Smart EV Load Manager with OCPP1.6j integration

Hi,
I planing to built an smart Load Manager for charging stations, whitch can handle grid load limitation (german §14a EnWG), PV optimized and can use dynamic grid pricing.
The Load Manager should use a OCPP integration to set the load profiles in the EVCS.

The use case is a charging station that can provide a charging point for guest with ad-hoc payment (over QR-code no APP) and provide me a uncharged port for private charging, by app or NFC autorization.

Used setup:

  • EV-ChargingStation: ABL eMH3(3W2263C)

  • EMS: CerboGX with NodeRED activated

  • OCPP-Integration: node-red-contrib-ocpp by argonne-vci

  • OCPP-Backend: bill.bo LITE (no fix costs)

Hint:

In ABL Web Configuration you have to add your URL with the specific Port and if you use standart port 80 for ws:// innode-red-contrib-ocpp the NodeRED crashes

Below you can find the sceme of my intention:

flowchart LR
 
        subgraph LPM[LoadProfilManager]
        direction TB
        LPN{{LoadProfil 0 A if GridPrice >= 35ct}}
        LPP{{if PV-Power > 5kW}}
        EU{{adapt LoadProfile if SurplusPower && isActiv LoadProfile}}

        LL([maxChargPower])
        M1{is lower}
        M2{is greater}
        M3{is greater}
        M4{is lower}
        LL --> M1
        M1 --> M2
        M2 --> M3
        M3 --> M4
        end


    subgraph DESS
    direction LR
        DAP[Day-Ahead-Grid-Price]
        PVP[PV-Forcast]
        P14[§14a EnWG LoadLimitation EEBUS]
        NM[GridMeasurement]
    NV[SteValue<br>GridPoint]    
        
    end
    CSMS[ChargeStationManager]
    CS[ChargeStation]
    DAP --> LPN
    PVP --> LPP
    P14 -->|ChargePowerLimit| M4
    EU --> |5min PV-optimization|M3
    NM --> |PV-Surplus >=5kW|EU
    LPP -->|LoadProfile: PV-Surplus|M2
    LPN -->|Loadprofile: PauseCharghing | M1
    M4 --> CSMS <==> |OCPP| CS
    Backend <=======> CSMS
    CSMS  --> NV

My OCPP-Proxy looks like this now and is prepared for interaction with EMS. But still with some uncached ecceptions:
Edit 16.06.2026: By working withn implementing Tags for identifying the source of the request, themassage routing is done nicely. By sending the responce only to the source of the request.
Edit 18.06.2026: Resolve the different massage input of the OCPP-Nodes, thad caused untransvered responses.

[

    {
        "id": "17b017b2265d4eef",
        "type": "tab",
        "label": "CSMS",
        "disabled": false,
        "info": "",
        "env": [
            {
                "name": "HeartbeatInterval",
                "value": "10",
                "type": "num"
            }
        ]
    },
    {
        "id": "b352eadf12178be2",
        "type": "switch",
        "z": "17b017b2265d4eef",
        "d": true,
        "name": "OCPP CS Command Switch",
        "property": "payload.command",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "BootNotification",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "Authorize",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "Heartbeat",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "StatusNotification",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "MeterValues",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "StartTransaction",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "StopTransaction",
                "vt": "str"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 8,
        "x": 820,
        "y": 540,
        "wires": [
            [
                "ac9cb8a8468ddc1a"
            ],
            [
                "b4194f31fe89a932"
            ],
            [
                "f3500ade9ca34666"
            ],
            [
                "82e4927dbcad7eb4"
            ],
            [
                "82e4927dbcad7eb4",
                "4c7791b26456419c"
            ],
            [
                "74dc3d5bb9fdb379"
            ],
            [
                "b4194f31fe89a932",
                "e7a35d84afd408e3"
            ],
            []
        ]
    },
    {
        "id": "ac9cb8a8468ddc1a",
        "type": "function",
        "z": "17b017b2265d4eef",
        "d": true,
        "name": "BootNotification",
        "func": "msg.payload = {\n    interval: 120,\n    currentTime: new Date().toISOString(),\n    status: \"Accepted\"\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 1080,
        "y": 421,
        "wires": [
            [
                "19faa1904fd4d362",
                "1002fb0a2ee1197f"
            ]
        ]
    },
    {
        "id": "74dc3d5bb9fdb379",
        "type": "function",
        "z": "17b017b2265d4eef",
        "d": true,
        "name": "Start Transaction",
        "func": "msg.payload = {\n    idTagInfo: {\n        status: \"Accepted\",\n    },\n    transactionId: getRndInteger(0,100000)\n}\nreturn msg;\n\nfunction getRndInteger(min, max) {\n    return Math.floor(Math.random() * (max - min + 1) ) + min;\n}\n",
        "outputs": 1,
        "noerr": 0,
        "x": 1090,
        "y": 601,
        "wires": [
            []
        ]
    },
    {
        "id": "e7a35d84afd408e3",
        "type": "function",
        "z": "17b017b2265d4eef",
        "d": true,
        "name": "Stop Transaction",
        "func": "msg.payload = { idTagInfo: { status: \"Accepted\"} };\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 1290,
        "y": 621,
        "wires": [
            []
        ]
    },
    {
        "id": "f3500ade9ca34666",
        "type": "change",
        "z": "17b017b2265d4eef",
        "d": true,
        "name": "Heartbeat",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "{}",
                "tot": "json"
            },
            {
                "t": "set",
                "p": "payload.currentTime",
                "pt": "msg",
                "to": "$now()",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1060,
        "y": 499,
        "wires": [
            [
                "19faa1904fd4d362"
            ]
        ]
    },
    {
        "id": "b4194f31fe89a932",
        "type": "change",
        "z": "17b017b2265d4eef",
        "d": true,
        "name": "Generic Status=Accepted",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "{\"idTagInfo\":{\"status\":\"Accepted\"}}",
                "tot": "json"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1110,
        "y": 461,
        "wires": [
            [
                "d680f9d5fe35cdc5"
            ]
        ]
    },
    {
        "id": "82e4927dbcad7eb4",
        "type": "change",
        "z": "17b017b2265d4eef",
        "d": true,
        "name": "Generic Return",
        "rules": [
            {
                "t": "set",
                "p": "ocpp.data",
                "pt": "msg",
                "to": "payload.data",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "{}",
                "tot": "json"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1080,
        "y": 541,
        "wires": [
            []
        ]
    },
    {
        "id": "d680f9d5fe35cdc5",
        "type": "debug",
        "z": "17b017b2265d4eef",
        "d": true,
        "name": "Accept",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1310,
        "y": 441,
        "wires": []
    },
    {
        "id": "4c7791b26456419c",
        "type": "debug",
        "z": "17b017b2265d4eef",
        "d": true,
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload.data.meterValue[0]",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1130,
        "y": 660,
        "wires": []
    },
    {
        "id": "19faa1904fd4d362",
        "type": "debug",
        "z": "17b017b2265d4eef",
        "d": true,
        "name": "bootN",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1390,
        "y": 480,
        "wires": []
    },
    {
        "id": "a80a4115ba81f248",
        "type": "link in",
        "z": "17b017b2265d4eef",
        "d": true,
        "name": "Command Switch in",
        "links": [
            "537fd9734c5e4e03",
            "aff46675fec074f0"
        ],
        "x": 635,
        "y": 560,
        "wires": [
            [
                "b352eadf12178be2"
            ]
        ]
    },
    {
        "id": "832f5e0119acc621",
        "type": "inject",
        "z": "17b017b2265d4eef",
        "d": true,
        "name": "StopTransaction",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"ocpp\":{\"ocppVersion\":\"1.6j\",\"MessageId\":\"d7e4b786-5540-4588-b712-92b7fd9bb3fb\",\"msgType\":2,\"command\":\"RemoteStopTransaction\"},\"payload\":{\"command\":\"RemoteStopTransaction\",\"data\":{\"transactionId\":123456789}},\"msgId\":\"a6252592-0d99-49ff-987a-1dc86f1e610d\",\"_msgid\":\"db384751d7fc8d8b\"}",
        "payloadType": "json",
        "x": 460,
        "y": 560,
        "wires": [
            []
        ]
    },
    {
        "id": "6136f6304fcaa278",
        "type": "inject",
        "z": "17b017b2265d4eef",
        "name": "BootNotification",
        "props": [
            {
                "p": "ocpp",
                "v": "{\"msgType\":2,\"command\":\"BootNotification\",\"data\":{\"chargePointVendor\":\"ABL\",\"chargePointModel\":\"3W2263\",\"chargePointSerialNumber\":\"chargePointSerialNumber\",\"chargeBoxSerialNumber\":\"chargeBoxSerialNumber\",\"firmwareVersion\":\"1.8p4\"}}",
                "vt": "json"
            },
            {
                "p": "ocpp.MessageId",
                "v": "$floor($random()*899999 + 1000000)",
                "vt": "jsonata"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 140,
        "y": 700,
        "wires": [
            [
                "f03815ae9c3523ba"
            ]
        ]
    },
    {
        "id": "5ccbda76a0f5c624",
        "type": "inject",
        "z": "17b017b2265d4eef",
        "name": "Trigger MeterValues",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "payload.MessageId",
                "v": "06bd3eff-6c0d-5424-8214-b96ecc2ccf74",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"msgType\":2,\"command\":\"TriggerMessage\",\"data\":{\"requestedMessage\":\"MeterValues\",\"connectorId\":1}}",
        "payloadType": "json",
        "x": 150,
        "y": 540,
        "wires": [
            [
                "cde258b40613cc08"
            ]
        ]
    },
    {
        "id": "370f02afbe26096a",
        "type": "inject",
        "z": "17b017b2265d4eef",
        "name": "SendLocalList",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"msgType\":2,\"command\":\"SendLocalList\",\"data\":{\"localAuthorizationList\":[{\"idTag\":\"Tag_Identifier_01\",\"idTagInfo\":{\"status\":\"Accepted\"}},{\"idTag\":\"Tag_Identifier_02\",\"idTagInfo\":{\"status\":\"Accepted\"}}],\"updateType\":\"Full\"}}",
        "payloadType": "json",
        "x": 130,
        "y": 660,
        "wires": [
            [
                "2a43e0e79e62b90f"
            ]
        ]
    },
    {
        "id": "2a43e0e79e62b90f",
        "type": "function",
        "z": "17b017b2265d4eef",
        "name": "parse LocalList",
        "func": "context.data = context.data || {};\n\nif ((msg.ocpp?.msgType == 2 || msg.payload?.msgType == 2) &&\n    msg.payload?.command == \"SendLocalList\" ) {\n    context.data = msg.payload.data;\n    msg.payload = {\"msgType\": 2,\"command\":\"GetLocalListVersion\",\"data\":{}};\n    return msg;\n} else if((msg.ocpp?.msgType == 3 || msg.payload?.msgType == 3) &&\n     (msg.ocpp?.command == \"GetLocalListVersion\" || msg.payload?.command == \"GetLocalListVersion\")){\n    var listVersion = msg.payload.data.listVersion +1;\n    msg = {};\n    msg.payload = {\"msgType\": 2,\"command\":\"SendLocalList\"};\n    msg.payload.data = context.data;\n    msg.payload.data.listVersion = listVersion;\n\n    // msg.payload.msgType = 3;\n    // msg.payload.command = context.msg.ocpp.command;\n    //msg.payload = context.msg.payload.data;\n    return msg;\n    }\n    \nreturn null;\n\n",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 180,
        "y": 600,
        "wires": [
            [
                "cde258b40613cc08"
            ]
        ]
    },
    {
        "id": "47336589637de3ab",
        "type": "link in",
        "z": "17b017b2265d4eef",
        "name": "CSMS feedback",
        "links": [
            "537fd9734c5e4e03"
        ],
        "x": 55,
        "y": 620,
        "wires": [
            [
                "2a43e0e79e62b90f"
            ]
        ]
    },
    {
        "id": "537fd9734c5e4e03",
        "type": "link out",
        "z": "17b017b2265d4eef",
        "name": "CSMS out",
        "mode": "link",
        "links": [
            "47336589637de3ab",
            "a80a4115ba81f248"
        ],
        "x": 925,
        "y": 260,
        "wires": []
    },
    {
        "id": "1002fb0a2ee1197f",
        "type": "debug",
        "z": "17b017b2265d4eef",
        "d": true,
        "name": "BootNotification",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1320,
        "y": 400,
        "wires": []
    },
    {
        "id": "5f62be1caad50bf3",
        "type": "debug",
        "z": "17b017b2265d4eef",
        "name": "request EVSE",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1100,
        "y": 220,
        "wires": []
    },
    {
        "id": "a42b1bdbb37a9685",
        "type": "CP client JSON",
        "z": "17b017b2265d4eef",
        "name": "Backend",
        "cbId": "CP_Identifier",
        "remotecs": "92124697.6658f",
        "ocppver": "1.6j",
        "command": "",
        "cmddata": "",
        "log": false,
        "pathlog": "/data/home/nodered/logs/OCPP.log",
        "wsdelayconnect": false,
        "wstomin": 5,
        "wstomax": 360,
        "wstoinc": 5,
        "x": 160,
        "y": 200,
        "wires": [
            [
                "f03815ae9c3523ba"
            ]
        ]
    },
    {
        "id": "531856ac3c6f1dd0",
        "type": "CS server",
        "z": "17b017b2265d4eef",
        "name": "OCPP listener",
        "port": "8020",
        "portType": "num",
        "enabled15": false,
        "path15": "",
        "enabled16": false,
        "path16": "",
        "enabled16j": true,
        "path16j": "/ocpp",
        "log": false,
        "pathlog": "/data/home/nodered/logs/OCPP.log",
        "x": 130,
        "y": 80,
        "wires": [
            [
                "520557f93aeb084c"
            ],
            []
        ]
    },
    {
        "id": "65bda55ae3be526a",
        "type": "server response",
        "z": "17b017b2265d4eef",
        "name": "CP response",
        "x": 990,
        "y": 100,
        "wires": []
    },
    {
        "id": "54ddaee06b0f6efb",
        "type": "debug",
        "z": "17b017b2265d4eef",
        "name": "incommimg",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 750,
        "y": 320,
        "wires": []
    },
    {
        "id": "8c192aa61e841a7f",
        "type": "comment",
        "z": "17b017b2265d4eef",
        "name": "In-Out for EVSE requests",
        "info": "",
        "x": 150,
        "y": 280,
        "wires": []
    },
    {
        "id": "f116c88dcc1f08fa",
        "type": "CS request JSON",
        "z": "17b017b2265d4eef",
        "name": "request EVSE",
        "remotecb": "2b6ab4fbb3f5ac80",
        "command": "",
        "cmddata": "",
        "log": true,
        "pathlog": "",
        "x": 180,
        "y": 320,
        "wires": [
            [
                "aba7ba9e6ee29983"
            ]
        ]
    },
    {
        "id": "a9cbb64e364ff830",
        "type": "link in",
        "z": "17b017b2265d4eef",
        "name": "request EVSE in",
        "links": [
            "aff46675fec074f0"
        ],
        "x": 55,
        "y": 320,
        "wires": [
            [
                "f116c88dcc1f08fa"
            ]
        ]
    },
    {
        "id": "e19d2a2910aeba60",
        "type": "link in",
        "z": "17b017b2265d4eef",
        "name": "Backend in",
        "links": [
            "f77e3549f2df1b32"
        ],
        "x": 55,
        "y": 200,
        "wires": [
            [
                "a42b1bdbb37a9685"
            ]
        ]
    },
    {
        "id": "f77e3549f2df1b32",
        "type": "link out",
        "z": "17b017b2265d4eef",
        "name": "Backend out",
        "mode": "link",
        "links": [
            "e19d2a2910aeba60"
        ],
        "x": 925,
        "y": 180,
        "wires": []
    },
    {
        "id": "96b24119440bc0c5",
        "type": "debug",
        "z": "17b017b2265d4eef",
        "name": "EVSE",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1070,
        "y": 140,
        "wires": []
    },
    {
        "id": "885699d55bd9c62d",
        "type": "debug",
        "z": "17b017b2265d4eef",
        "name": "Backend",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1080,
        "y": 180,
        "wires": []
    },
    {
        "id": "aff46675fec074f0",
        "type": "link out",
        "z": "17b017b2265d4eef",
        "name": "request EVSE out",
        "mode": "link",
        "links": [
            "a9cbb64e364ff830",
            "a80a4115ba81f248"
        ],
        "x": 925,
        "y": 220,
        "wires": []
    },
    {
        "id": "97e14c469f86df22",
        "type": "comment",
        "z": "17b017b2265d4eef",
        "name": "Catches EVSE Massages",
        "info": "",
        "x": 150,
        "y": 40,
        "wires": []
    },
    {
        "id": "b6e5d3102f24c1c5",
        "type": "comment",
        "z": "17b017b2265d4eef",
        "name": "In-Out for Backend requests",
        "info": "",
        "x": 160,
        "y": 160,
        "wires": []
    },
    {
        "id": "b734d6abbc29f736",
        "type": "debug",
        "z": "17b017b2265d4eef",
        "name": "responce to CSMS",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1110,
        "y": 260,
        "wires": []
    },
    {
        "id": "21eb298303e5d3dc",
        "type": "function",
        "z": "17b017b2265d4eef",
        "name": "massage routing",
        "func": "// Source - https://stackoverflow.com/a/30031152\n// Posted by user2314737\n// Retrieved 2026-06-17, License - CC BY-SA 3.0\n//fruits.filter(function(x){return x !== 'undefined'}).length\n\nif (msg.ocpp?.websocket != undefined && msg.ocpp?.command === undefined){\n    // msg.payload = msg.ocpp;\n    //delete(msg.ocpp);\n    return [null, null, null, msg]};\nif (msg.ocpp?.msgType == undefined || msg.ocpp?.command == undefined){node.warn('Inpropper OCPP-Massage!'); return null;}\n\n\n// msg.payload = { ...msg?.ocpp , ... msg.payload};\n//delete(msg.ocpp);\n\nif (msg.ocpp?.msgType == 2) {\n    if(msg.msgTag?.origin === undefined){\n        node.warn('No MassageTag is set! Define a Massage Tag like: msg.msgTag = {\"origin\":\"source\",\"uTimestamp\":Date.now(),\"MessageId\":\"ocpp_ID\",\"msgId\":\"msgID\"}');\n    } else {\n       let msgTag = [];\n       msgTag = flow.get(\"msgTag\");\n//add Tag element to storage\n        msgTag.push(msg.msgTag);\n//remove obsolete elements >min\n        while (msgTag[0].uTimestamp <= (Date.now() - (2*60*1000)) ){ \n            msgTag.splice(0,1); \n        }\n        for (const item of msgTag){\n//find matching source\n            if (item.MessageId == (msg.ocpp?.MessageId)){  \n            \n\n            flow.set(\"msgTag\",msgTag);\n    // node.warn(flow.get(\"msgTag\"));\n            msg.payload.MessageId = msg.ocpp.MessageId;\n            msg.payload.msgType  = msg.ocpp.msgType ;\n            msg.payload.command = msg.ocpp.command;\n\n            switch (item.origin) {\n                case \"EVSE\":\n                    return [null, msg, null, null];\n                case \"Backend\":\n                    if (msg.ocpp.msgId){msg.payload.msgId  = msg.ocpp.msgId;}\n                    if (msg.ocpp.chargeBoxIdentity){msg.payload.cbId  = msg.ocpp.chargeBoxIdentity;}\n                    return [null, null, msg, null];\n                case \"reqEVSE\":\n                    return [null, msg, null, null];\n                case \"CSMS\":\n                    if (msg.ocpp.msgId){msg.payload.msgId  = msg.ocpp.msgId;}\n                    if (msg.ocpp.chargeBoxIdentity){msg.payload.cbId  = msg.ocpp.chargeBoxIdentity;}\n                    return [null, null, msg, null];\n                default:\n                    return [null, null, null, msg];\n                \n                }\n            }\n        }\n    }\n\n} else if(msg.ocpp?.msgType == 3) {\n    // msg.payload = msg.payload.data;\n    let msgTag = flow.get(\"msgTag\");\n    \n    for (let item = msgTag.length -1; item >=0; item-- ){\n//find matching source\n        if (msgTag[item].MessageId == (msg.ocpp?.MessageId)){  \n        msg.msgId  = msgTag[item].msgId;\n        const origin = msgTag[item].origin;\n        msgTag.splice(item,1);\n        flow.set(\"msgTag\",msgTag);\n        // node.warn(msgTag.length);\n        msg.payload.MessageId = msg.ocpp.MessageId;\n        msg.payload.msgType  = msg.ocpp.msgType ;\n        msg.payload.command = msg.ocpp.command;\n       \n        switch (origin) {\n            case \"EVSE\":\n                msg.payload = msg.payload.data;\n                return [msg, null, null, null];\n            case \"Backend\":\n                return [null, msg, null, null];\n            case \"reqEVSE\":\n                if (msg.ocpp.msgId){msg.payload.msgId  = msg.ocpp.msgId;}\n                if (msg.ocpp.chargeBoxIdentity){msg.payload.cbId  = msg.ocpp.chargeBoxIdentity;}\n                return [null, null, msg, null];\n            default:\n                return [null, null, null, msg];\n            }\n        }\n    }\n}\n\nreturn [null, null, null, msg];\n\n",
        "outputs": 4,
        "timeout": "",
        "noerr": 0,
        "initialize": "// Der Code hier wird ausgeführt,\n// wenn der Node gestartet wird\n\n//initiallize msgMarker\nlet newArray = [];\nflow.set(\"msgTag\",newArray);",
        "finalize": "",
        "libs": [],
        "x": 740,
        "y": 200,
        "wires": [
            [
                "65bda55ae3be526a",
                "96b24119440bc0c5"
            ],
            [
                "885699d55bd9c62d",
                "f77e3549f2df1b32"
            ],
            [
                "5f62be1caad50bf3",
                "aff46675fec074f0"
            ],
            [
                "b734d6abbc29f736",
                "537fd9734c5e4e03"
            ]
        ]
    },
    {
        "id": "520557f93aeb084c",
        "type": "function",
        "z": "17b017b2265d4eef",
        "name": "Tag EVSE",
        "func": "if(msg.ocpp?.msgType == 2 &&\n    msg.ocpp?.command != undefined ) {\n    msg.msgTag = {\"origin\" : \"EVSE\"};\n    msg.msgTag.msgId = msg.msgId || msg.ocpp.MessageId;\n    msg.msgTag.MessageId = msg.ocpp.MessageId;\n    msg.msgTag.uTimestamp = Date.now();\n    }\nreturn msg;\n\n",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 370,
        "y": 80,
        "wires": [
            [
                "21eb298303e5d3dc",
                "54ddaee06b0f6efb"
            ]
        ]
    },
    {
        "id": "f03815ae9c3523ba",
        "type": "function",
        "z": "17b017b2265d4eef",
        "name": "Tag Backend",
        "func": "if(msg.ocpp?.msgType == 2 &&\n    msg.ocpp?.command != undefined ) {\n    msg.msgTag = {\"origin\" : \"Backend\"};\n    msg.msgTag.msgId = msg.msgId || msg.ocpp.MessageId;\n    msg.msgTag.MessageId = msg.ocpp.MessageId;\n    msg.msgTag.uTimestamp = Date.now();\n    }\nreturn msg;\n\n",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 370,
        "y": 200,
        "wires": [
            [
                "21eb298303e5d3dc",
                "54ddaee06b0f6efb"
            ]
        ]
    },
    {
        "id": "aba7ba9e6ee29983",
        "type": "function",
        "z": "17b017b2265d4eef",
        "name": "Tag reqEVSE",
        "func": "if(msg.ocpp?.msgType == 2 &&\n    msg.ocpp?.command != undefined ) {\n    msg.msgTag = {\"origin\" : \"reqEVSE\"};\n    msg.msgTag.msgId = msg.msgId || msg.ocpp.MessageId;\n    msg.msgTag.MessageId = msg.ocpp.MessageId;\n    msg.msgTag.uTimestamp = Date.now();\n    \n    }\nreturn msg;\n",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 360,
        "y": 320,
        "wires": [
            [
                "21eb298303e5d3dc",
                "54ddaee06b0f6efb"
            ]
        ]
    },
    {
        "id": "cde258b40613cc08",
        "type": "function",
        "z": "17b017b2265d4eef",
        "name": "Tag CSMS",
        "func": "\nif (msg?.ocpp == undefined){msg.ocpp ={};}\nmsg.ocpp.msgType = msg.ocpp.msgType || msg.payload.msgType;\nmsg.ocpp.command = msg.ocpp.command || msg.payload.command;\n\nmsg.ocpp.MessageId = msg.ocpp.MessageId ||msg.payload?.MessageId|| crypto.randomUUID();\n\nif(msg.payload?.msgType == 2 || msg.ocpp?.msgType == 2) {\n    msg.msgTag = msg.msgTag || {\"origin\" : \"CSMS\"};\n    msg.msgTag.msgId = msg.msgId || msg.payload.MessageId;\n    msg.msgTag.MessageId = msg.payload.MessageId;\n    msg.msgTag.uTimestamp = Date.now();\n    }\nreturn msg;\n\n",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [
            {
                "var": "crypto",
                "module": "crypto"
            }
        ],
        "x": 370,
        "y": 440,
        "wires": [
            [
                "21eb298303e5d3dc",
                "54ddaee06b0f6efb"
            ]
        ]
    },
    {
        "id": "1657738134829b0a",
        "type": "comment",
        "z": "17b017b2265d4eef",
        "name": "Input CSMS interface ",
        "info": "",
        "x": 240,
        "y": 400,
        "wires": []
    },
    {
        "id": "7522209452c9493c",
        "type": "comment",
        "z": "17b017b2265d4eef",
        "name": "Output sortet by Device",
        "info": "",
        "x": 1020,
        "y": 40,
        "wires": []
    },
    {
        "id": "6b6e272bc4b18cbe",
        "type": "comment",
        "z": "17b017b2265d4eef",
        "name": "some example Massages",
        "info": "",
        "x": 150,
        "y": 500,
        "wires": []
    },
    {
        "id": "236903c37579d28b",
        "type": "inject",
        "z": "17b017b2265d4eef",
        "d": true,
        "name": "GetCompositeSchedule",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"ocpp\":{\"ocppVersion\":\"1.6j\",\"MessageId\":\"417b0428-d8a3-46cb-809d-831075c100aa\",\"msgType\":2,\"command\":\"GetCompositeSchedule\"},\"payload\":{\"command\":\"GetCompositeSchedule\",\"data\":{\"connectorId\":1,\"duration\":15,\"chargingRateUnit\":\"W\"},\"MessageId\":\"417b0428-d8a3-46cb-809d-831075c100aa\",\"msgType\":2},\"msgId\":\"5e4b3036-6086-4450-ace0-0431e60a460d\",\"_msgid\":\"6b965bb876743508\"}",
        "payloadType": "json",
        "x": 480,
        "y": 600,
        "wires": [
            []
        ]
    },
    {
        "id": "c1db1eb9d8259bde",
        "type": "inject",
        "z": "17b017b2265d4eef",
        "d": true,
        "name": "responce GetCompositeSchedule",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"ocpp\":{\"ocppVersion\":\"1.6j\",\"MessageId\":\"417b0428-d8a3-46cb-809d-831075c100aa\",\"msgType\":2,\"command\":\"GetCompositeSchedule\"},\"payload\":{\"command\":\"GetCompositeSchedule\",\"data\":{\"connectorId\":1,\"duration\":15,\"chargingRateUnit\":\"W\"},\"MessageId\":\"417b0428-d8a3-46cb-809d-831075c100aa\",\"msgType\":2},\"msgId\":\"5e4b3036-6086-4450-ace0-0431e60a460d\",\"_msgid\":\"6b965bb876743508\"}",
        "payloadType": "json",
        "x": 510,
        "y": 640,
        "wires": [
            []
        ]
    },
    {
        "id": "92124697.6658f",
        "type": "ocpp-remote-cs",
        "name": "bill.bo",
        "url": "wss://CP_Identifier:Backend_PW@ocpp.chargeiq.de"
    },
    {
        "id": "2b6ab4fbb3f5ac80",
        "type": "ocpp-remotej-cp",
        "name": "",
        "cbId": "CP_Identifier",
        "ocppver": "1.6j"
    },
    {
        "id": "4612095b16107d53",
        "type": "global-config",
        "env": [],
        "modules": {
            "node-red-contrib-ocpp": "1.3.10"
        }
    }

]

With this Thread I just whant to share my work and open a platform to discous thoughts, solutions and other related stuff.

Now I have completed my smart charging system by setting charging profiles dependent on grid price and PV surplus, also battery capacity is used if the SoC forecast does not drop below a certain value.
The big aim of this control is, one can us a WallBox with backend for billed charging and still have the full control of the charging point. And can even manage the local RFID access.
Please drop a comment if it was a helpful start for you own project.

[
    {
        "id": "17b017b2265d4eef",
        "type": "tab",
        "label": "Smart Charge",
        "disabled": false,
        "info": "",
        "env": [
            {
                "name": "HeartbeatInterval",
                "value": "10",
                "type": "num"
            }
        ]
    },
    {
        "id": "59f8897d78fd047c",
        "type": "group",
        "z": "17b017b2265d4eef",
        "name": "Regelung Netzanschlusspunkt",
        "style": {
            "label": true
        },
        "nodes": [
            "a2191ef8c7f30edc",
            "226cce0fdd4abc0a",
            "8939894fe6a45b98",
            "016f62610b6768ca",
            "d7ddcba25f10b458",
            "0688cc021dcbe159",
            "927f1aba4218e035",
            "d271589acd162dd8",
            "53d6230003810363",
            "f32a2c3539951257",
            "71a74a28de11279c",
            "f76c95ea96f848cd",
            "fbe7a6b2bc91ba3d",
            "1cbbe490c95c37cb",
            "7ccb4444844f0ce1",
            "156faa677fc271bf",
            "196fd778a13d7812",
            "5dc322c7e1993517",
            "e4e36e1547ec24eb",
            "cbfcbce8aec902aa",
            "4dc444a6ef60ae4a",
            "88f5b39aa0f025d6",
            "63807e6edc499d8a"
        ],
        "x": 14,
        "y": 1139,
        "w": 1312,
        "h": 442
    },
    {
        "id": "a71924f761669a5d",
        "type": "group",
        "z": "17b017b2265d4eef",
        "name": "Set Carger Power Limit",
        "style": {
            "label": true
        },
        "nodes": [
            "290da2eb2dc3479e",
            "b63058b521f27d5c",
            "2c7bae975694e7a2",
            "8ebf6d92c05143f2",
            "6bdb11631a17a7f9",
            "3a9ee99528aebbb6",
            "640eef9320f44225",
            "9ec157cdf763fb36",
            "83d348c4bba99711",
            "b6ef33d841b43f61",
            "5f6edab6a877da69",
            "03af6795e5707fee",
            "228b28f0a7956493"
        ],
        "x": 14,
        "y": 819,
        "w": 1152,
        "h": 302
    },
    {
        "id": "389e6b39b85cf801",
        "type": "group",
        "z": "17b017b2265d4eef",
        "name": "Opperator Commands",
        "style": {
            "label": true
        },
        "nodes": [
            "832f5e0119acc621",
            "6136f6304fcaa278",
            "5ccbda76a0f5c624",
            "370f02afbe26096a",
            "2a43e0e79e62b90f",
            "47336589637de3ab",
            "6b6e272bc4b18cbe",
            "236903c37579d28b",
            "c1db1eb9d8259bde",
            "e498cb5fd423feaa",
            "2d316cee30d6fbcc",
            "6211ee624730dd62",
            "63f4a317c92b54aa"
        ],
        "x": 14,
        "y": 519,
        "w": 1232,
        "h": 282
    },
    {
        "id": "44ac6bf510980216",
        "type": "group",
        "z": "17b017b2265d4eef",
        "name": "OCPP Interface",
        "style": {
            "label": true
        },
        "nodes": [
            "537fd9734c5e4e03",
            "5f62be1caad50bf3",
            "a42b1bdbb37a9685",
            "531856ac3c6f1dd0",
            "65bda55ae3be526a",
            "54ddaee06b0f6efb",
            "8c192aa61e841a7f",
            "f116c88dcc1f08fa",
            "a9cbb64e364ff830",
            "e19d2a2910aeba60",
            "f77e3549f2df1b32",
            "96b24119440bc0c5",
            "885699d55bd9c62d",
            "aff46675fec074f0",
            "97e14c469f86df22",
            "b6e5d3102f24c1c5",
            "b734d6abbc29f736",
            "21eb298303e5d3dc",
            "520557f93aeb084c",
            "f03815ae9c3523ba",
            "aba7ba9e6ee29983",
            "cde258b40613cc08",
            "1657738134829b0a",
            "7522209452c9493c",
            "e70f1dd07148cc5a",
            "0e87eb14c089b953",
            "761a0f55f4626b21"
        ],
        "x": 14,
        "y": 19,
        "w": 1232,
        "h": 482
    },
    {
        "id": "832f5e0119acc621",
        "type": "inject",
        "z": "17b017b2265d4eef",
        "d": true,
        "g": "389e6b39b85cf801",
        "name": "StopTransaction",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"ocpp\":{\"ocppVersion\":\"1.6j\",\"MessageId\":\"d7e4b786-5540-4588-b712-92b7fd9bb3fb\",\"msgType\":2,\"command\":\"RemoteStopTransaction\"},\"payload\":{\"command\":\"RemoteStopTransaction\",\"data\":{\"transactionId\":123456789}},\"msgId\":\"a6252592-0d99-49ff-987a-1dc86f1e610d\",\"_msgid\":\"db384751d7fc8d8b\"}",
        "payloadType": "json",
        "x": 540,
        "y": 680,
        "wires": [
            []
        ]
    },
    {
        "id": "6136f6304fcaa278",
        "type": "inject",
        "z": "17b017b2265d4eef",
        "g": "389e6b39b85cf801",
        "name": "BootNotification",
        "props": [
            {
                "p": "ocpp",
                "v": "{\"msgType\":2,\"command\":\"BootNotification\",\"data\":{\"chargePointVendor\":\"ABL\",\"chargePointModel\":\"3W2263\",\"chargePointSerialNumber\":\"chargePointSerialNumber\",\"chargeBoxSerialNumber\":\"chargeBoxSerialNumber\",\"firmwareVersion\":\"1.8p4\"}}",
                "vt": "json"
            },
            {
                "p": "msgTag.origin",
                "v": "EVCS",
                "vt": "str"
            },
            {
                "p": "msgTag.uTimestamp",
                "v": "",
                "vt": "date"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 140,
        "y": 720,
        "wires": [
            [
                "63f4a317c92b54aa"
            ]
        ]
    },
    {
        "id": "5ccbda76a0f5c624",
        "type": "inject",
        "z": "17b017b2265d4eef",
        "g": "389e6b39b85cf801",
        "name": "Trigger MeterValues",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"msgType\":2,\"command\":\"TriggerMessage\",\"data\":{\"requestedMessage\":\"MeterValues\",\"connectorId\":1}}",
        "payloadType": "json",
        "x": 150,
        "y": 600,
        "wires": [
            [
                "63f4a317c92b54aa"
            ]
        ]
    },
    {
        "id": "370f02afbe26096a",
        "type": "inject",
        "z": "17b017b2265d4eef",
        "g": "389e6b39b85cf801",
        "name": "SendLocalList",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"msgType\":2,\"command\":\"SendLocalList\",\"data\":{\"localAuthorizationList\":[{\"idTag\":\"Tag_Identifier_01\",\"idTagInfo\":{\"status\":\"Accepted\"}},{\"idTag\":\"Tag_Identifier_01\",\"idTagInfo\":{\"status\":\"Accepted\"}}],\"updateType\":\"Full\"}}",
        "payloadType": "json",
        "x": 130,
        "y": 640,
        "wires": [
            [
                "2a43e0e79e62b90f"
            ]
        ]
    },
    {
        "id": "2a43e0e79e62b90f",
        "type": "function",
        "z": "17b017b2265d4eef",
        "g": "389e6b39b85cf801",
        "name": "parse LocalList",
        "func": "context.data = context.data || {};\n\nif ((msg.ocpp?.msgType == 2 || msg.payload?.msgType == 2) &&\n    msg.payload?.command == \"SendLocalList\" ) {\n    context.data = msg.payload.data;\n    msg.payload = {\"msgType\": 2,\"command\":\"GetLocalListVersion\",\"data\":{}};\n    return msg;\n} else if((msg.ocpp?.msgType == 3 || msg.payload?.msgType == 3) &&\n     (msg.ocpp?.command == \"GetLocalListVersion\" || msg.payload?.command == \"GetLocalListVersion\")){\n    var listVersion = msg.payload.data.listVersion +1;\n    msg = {};\n    msg.payload = {\"msgType\": 2,\"command\":\"SendLocalList\"};\n    msg.payload.data = context.data;\n    msg.payload.data.listVersion = listVersion;\n\n    // msg.payload.msgType = 3;\n    // msg.payload.command = context.msg.ocpp.command;\n    //msg.payload = context.msg.payload.data;\n    return msg;\n    }\n    \nreturn null;\n\n",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 180,
        "y": 680,
        "wires": [
            [
                "63f4a317c92b54aa"
            ]
        ]
    },
    {
        "id": "47336589637de3ab",
        "type": "link in",
        "z": "17b017b2265d4eef",
        "g": "389e6b39b85cf801",
        "name": "CSMS feedback",
        "links": [
            "537fd9734c5e4e03"
        ],
        "x": 55,
        "y": 680,
        "wires": [
            [
                "2a43e0e79e62b90f"
            ]
        ]
    },
    {
        "id": "537fd9734c5e4e03",
        "type": "link out",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "CSMS out",
        "mode": "link",
        "links": [
            "47336589637de3ab"
        ],
        "x": 995,
        "y": 320,
        "wires": []
    },
    {
        "id": "5f62be1caad50bf3",
        "type": "debug",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "request EVCS",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1100,
        "y": 260,
        "wires": []
    },
    {
        "id": "a42b1bdbb37a9685",
        "type": "CP client JSON",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "Backend",
        "cbId": "CP_Identifier",
        "remotecs": "92124697.6658f",
        "ocppver": "1.6j",
        "command": "",
        "cmddata": "",
        "log": false,
        "pathlog": "/data/home/nodered/logs/OCPP.log",
        "wsdelayconnect": false,
        "wstomin": 5,
        "wstomax": 360,
        "wstoinc": 5,
        "x": 160,
        "y": 220,
        "wires": [
            [
                "f03815ae9c3523ba"
            ]
        ]
    },
    {
        "id": "531856ac3c6f1dd0",
        "type": "CS server",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "OCPP listener",
        "port": "8020",
        "portType": "num",
        "enabled15": false,
        "path15": "",
        "enabled16": false,
        "path16": "",
        "enabled16j": true,
        "path16j": "/ocpp",
        "log": false,
        "pathlog": "/data/home/nodered/logs/OCPP.log",
        "x": 130,
        "y": 100,
        "wires": [
            [
                "520557f93aeb084c"
            ],
            []
        ]
    },
    {
        "id": "65bda55ae3be526a",
        "type": "server response",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "CP response",
        "x": 990,
        "y": 120,
        "wires": []
    },
    {
        "id": "54ddaee06b0f6efb",
        "type": "debug",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "incommimg",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 710,
        "y": 340,
        "wires": []
    },
    {
        "id": "8c192aa61e841a7f",
        "type": "comment",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "In-Out for EVSE requests",
        "info": "",
        "x": 150,
        "y": 300,
        "wires": []
    },
    {
        "id": "f116c88dcc1f08fa",
        "type": "CS request JSON",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "request EVCS",
        "remotecb": "2b6ab4fbb3f5ac80",
        "command": "",
        "cmddata": "",
        "log": true,
        "pathlog": "",
        "x": 180,
        "y": 340,
        "wires": [
            [
                "aba7ba9e6ee29983"
            ]
        ]
    },
    {
        "id": "a9cbb64e364ff830",
        "type": "link in",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "request EVSE in",
        "links": [
            "aff46675fec074f0"
        ],
        "x": 55,
        "y": 340,
        "wires": [
            [
                "f116c88dcc1f08fa"
            ]
        ]
    },
    {
        "id": "e19d2a2910aeba60",
        "type": "link in",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "Backend in",
        "links": [
            "f77e3549f2df1b32"
        ],
        "x": 55,
        "y": 220,
        "wires": [
            [
                "a42b1bdbb37a9685"
            ]
        ]
    },
    {
        "id": "f77e3549f2df1b32",
        "type": "link out",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "Backend out",
        "mode": "link",
        "links": [
            "e19d2a2910aeba60"
        ],
        "x": 965,
        "y": 180,
        "wires": []
    },
    {
        "id": "96b24119440bc0c5",
        "type": "debug",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "EVCS",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1070,
        "y": 160,
        "wires": []
    },
    {
        "id": "885699d55bd9c62d",
        "type": "debug",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "Backend",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1120,
        "y": 220,
        "wires": []
    },
    {
        "id": "aff46675fec074f0",
        "type": "link out",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "request EVSE out",
        "mode": "link",
        "links": [
            "a9cbb64e364ff830"
        ],
        "x": 995,
        "y": 260,
        "wires": []
    },
    {
        "id": "97e14c469f86df22",
        "type": "comment",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "Catches EVCS Massages",
        "info": "",
        "x": 150,
        "y": 60,
        "wires": []
    },
    {
        "id": "b6e5d3102f24c1c5",
        "type": "comment",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "In-Out for Backend requests",
        "info": "",
        "x": 160,
        "y": 180,
        "wires": []
    },
    {
        "id": "b734d6abbc29f736",
        "type": "debug",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "responce to CSMS",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1110,
        "y": 320,
        "wires": []
    },
    {
        "id": "21eb298303e5d3dc",
        "type": "function",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "massage routing",
        "func": "//breake if command is undefined\nif (msg.ocpp?.websocket != undefined && msg.ocpp?.command === undefined){\n    return [null, null, null, msg]};\n//breake if command has inpropper structure    \nif (msg.ocpp?.msgType == undefined || msg.ocpp?.command == undefined){node.warn('Inpropper OCPP-Massage!'); return null;}\n\n//route ocpp requests\nif (msg.ocpp?.msgType == 2) {\n    if(msg.msgTag?.origin === undefined){\n        node.warn('No MassageTag is set! Define a Massage Tag like: msg.msgTag = {\"origin\":\"source\",\"uTimestamp\":Date.now(),\"MessageId\":\"ocpp_ID\",\"msgId\":\"msgID\"}');\n    } else {\n       let msgTag = [];\n       msgTag = flow.get(\"msgTag\");\n//add Tag element to storage\n        msgTag.push(msg.msgTag);\n//remove obsolete elements >min\n        while (msgTag[0].uTimestamp <= (Date.now() - (2*60*1000)) ){ \n            msgTag.splice(0,1); \n        }\n        for (const item of msgTag){\n//find matching source\n            if (item.MessageId == (msg.ocpp?.MessageId)){  \n                flow.set(\"msgTag\",msgTag);\n                msg.payload.MessageId = msg.ocpp.MessageId;\n                msg.payload.msgType  = msg.ocpp.msgType ;\n                msg.payload.command = msg.ocpp.command;\n    \n                switch (item.origin) {\n                    case \"EVCS\":\n                        return [null, msg, null, null];\n                    case \"Backend\":\n                        if (msg.ocpp.msgId){msg.payload.msgId  = msg.ocpp.msgId;}\n                        if (msg.ocpp.chargeBoxIdentity){msg.payload.cbId  = msg.ocpp.chargeBoxIdentity;}\n                        return [null, null, msg, null];\n                    case \"reqEVCS\":\n                        return [null, msg, null, null];\n                    case \"CSMS\":\n                        if (msg.ocpp.msgId){msg.payload.msgId  = msg.ocpp.msgId;}\n                        if (msg.ocpp.chargeBoxIdentity){msg.payload.cbId  = msg.ocpp.chargeBoxIdentity;}\n                        return [null, null, msg, null];\n                    default:\n                        return [null, null, null, msg];\n                }\n            }\n        }\n    }\n//route ocpp response\n} else if(msg.ocpp?.msgType == 3) {\n    let msgTag = flow.get(\"msgTag\");\n    \n    for (let item = msgTag.length -1; item >=0; item-- ){\n//find matching source\n        if (msgTag[item].MessageId == (msg.ocpp?.MessageId)){  \n        msg.msgId  = msgTag[item].msgId;\n        const origin = msgTag[item].origin;\n        msgTag.splice(item,1);\n        flow.set(\"msgTag\",msgTag);\n        msg.payload.MessageId = msg.ocpp.MessageId;\n        msg.payload.msgType  = msg.ocpp.msgType ;\n        msg.payload.command = msg.ocpp.command;\n//route to the response to massage origin        \n        switch (origin) {\n            case \"EVCS\":\n                msg.payload = msg.payload.data;\n                return [msg, null, null, null];\n            case \"Backend\":\n                return [null, msg, null, null];\n            case \"reqEVCS\":\n                if (msg.ocpp.msgId){msg.payload.msgId  = msg.ocpp.msgId;}\n                if (msg.ocpp.chargeBoxIdentity){msg.payload.cbId  = msg.ocpp.chargeBoxIdentity;}\n                return [null, null, msg, null];\n            default:\n                return [null, null, null, msg];\n            }\n        }\n    }\n}\n//send unhandled massages to CSMS\nreturn [null, null, null, msg];\n\n",
        "outputs": 4,
        "timeout": "",
        "noerr": 0,
        "initialize": "\n//initiallize msgTag\nlet newArray = [];\nflow.set(\"msgTag\",newArray);",
        "finalize": "",
        "libs": [],
        "x": 600,
        "y": 220,
        "wires": [
            [
                "65bda55ae3be526a",
                "96b24119440bc0c5"
            ],
            [
                "885699d55bd9c62d",
                "e70f1dd07148cc5a"
            ],
            [
                "5f62be1caad50bf3",
                "aff46675fec074f0"
            ],
            [
                "b734d6abbc29f736",
                "537fd9734c5e4e03"
            ]
        ]
    },
    {
        "id": "520557f93aeb084c",
        "type": "function",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "Tag EVCS",
        "func": "if(msg.ocpp?.msgType == 2 &&\n    msg.ocpp?.command != undefined ) {\n    msg.msgTag = {\"origin\" : \"EVCS\"};\n    msg.msgTag.msgId = msg.msgId || msg.ocpp.MessageId;\n    msg.msgTag.MessageId = msg.ocpp.MessageId;\n    msg.msgTag.uTimestamp = Date.now();\n    }\nreturn msg;\n\n",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 370,
        "y": 100,
        "wires": [
            [
                "21eb298303e5d3dc",
                "54ddaee06b0f6efb"
            ]
        ]
    },
    {
        "id": "f03815ae9c3523ba",
        "type": "function",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "Tag Backend",
        "func": "if(msg.ocpp?.msgType == 2 &&\n    msg.ocpp?.command != undefined ) {\n    msg.msgTag = {\"origin\" : \"Backend\"};\n    msg.msgTag.msgId = msg.msgId || msg.ocpp.MessageId;\n    msg.msgTag.MessageId = msg.ocpp.MessageId;\n    msg.msgTag.uTimestamp = Date.now();\n    }\nreturn msg;\n\n",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 370,
        "y": 220,
        "wires": [
            [
                "21eb298303e5d3dc",
                "54ddaee06b0f6efb"
            ]
        ]
    },
    {
        "id": "aba7ba9e6ee29983",
        "type": "function",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "Tag reqEVCS",
        "func": "if(msg.ocpp?.msgType == 2 &&\n    msg.ocpp?.command != undefined ) {\n    msg.msgTag = {\"origin\" : \"reqEVCS\"};\n    msg.msgTag.msgId = msg.msgId || msg.ocpp.MessageId;\n    msg.msgTag.MessageId = msg.ocpp.MessageId;\n    msg.msgTag.uTimestamp = Date.now();\n    \n    }\nreturn msg;\n",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 360,
        "y": 340,
        "wires": [
            [
                "21eb298303e5d3dc",
                "54ddaee06b0f6efb"
            ]
        ]
    },
    {
        "id": "cde258b40613cc08",
        "type": "function",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "Tag CSMS",
        "func": "\nif (msg?.ocpp == undefined){msg.ocpp ={};}\nif (msg?.payload == undefined){msg.payload ={};}\nmsg.ocpp.msgType = msg.ocpp.msgType || msg.payload.msgType;\nmsg.ocpp.command = msg.ocpp.command || msg.payload.command;\n\nmsg.ocpp.MessageId = msg.ocpp?.MessageId ||msg.payload?.MessageId|| crypto.randomUUID();\nmsg.payload.MessageId = msg.payload?.MessageId || msg.ocpp.MessageId;\nif(msg.payload?.msgType == 2 || msg.ocpp?.msgType == 2) {\n    msg.msgTag = msg.msgTag || {\"origin\" : \"CSMS\"};\n    msg.msgTag.msgId = msg.msgId || msg.payload.MessageId;\n    msg.msgTag.MessageId = msg.payload.MessageId;\n    msg.msgTag.uTimestamp = msg.msgTag.uTimestamp || Date.now();\n    }\nreturn msg;\n\n",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [
            {
                "var": "crypto",
                "module": "crypto"
            }
        ],
        "x": 370,
        "y": 460,
        "wires": [
            [
                "21eb298303e5d3dc",
                "54ddaee06b0f6efb"
            ]
        ]
    },
    {
        "id": "1657738134829b0a",
        "type": "comment",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "Input CSMS interface ",
        "info": "",
        "x": 240,
        "y": 420,
        "wires": []
    },
    {
        "id": "7522209452c9493c",
        "type": "comment",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "Output sortet by Device",
        "info": "",
        "x": 1020,
        "y": 60,
        "wires": []
    },
    {
        "id": "6b6e272bc4b18cbe",
        "type": "comment",
        "z": "17b017b2265d4eef",
        "g": "389e6b39b85cf801",
        "name": "some example Massages",
        "info": "",
        "x": 150,
        "y": 560,
        "wires": []
    },
    {
        "id": "236903c37579d28b",
        "type": "inject",
        "z": "17b017b2265d4eef",
        "d": true,
        "g": "389e6b39b85cf801",
        "name": "GetCompositeSchedule",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"ocpp\":{\"ocppVersion\":\"1.6j\",\"MessageId\":\"417b0428-d8a3-46cb-809d-831075c100aa\",\"msgType\":2,\"command\":\"GetCompositeSchedule\"},\"payload\":{\"command\":\"GetCompositeSchedule\",\"data\":{\"connectorId\":1,\"duration\":15,\"chargingRateUnit\":\"W\"},\"MessageId\":\"417b0428-d8a3-46cb-809d-831075c100aa\",\"msgType\":2},\"msgId\":\"5e4b3036-6086-4450-ace0-0431e60a460d\",\"_msgid\":\"6b965bb876743508\"}",
        "payloadType": "json",
        "x": 560,
        "y": 720,
        "wires": [
            []
        ]
    },
    {
        "id": "c1db1eb9d8259bde",
        "type": "inject",
        "z": "17b017b2265d4eef",
        "d": true,
        "g": "389e6b39b85cf801",
        "name": "responce GetCompositeSchedule",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"ocpp\":{\"ocppVersion\":\"1.6j\",\"MessageId\":\"417b0428-d8a3-46cb-809d-831075c100aa\",\"msgType\":2,\"command\":\"GetCompositeSchedule\"},\"payload\":{\"command\":\"GetCompositeSchedule\",\"data\":{\"connectorId\":1,\"duration\":15,\"chargingRateUnit\":\"W\"},\"MessageId\":\"417b0428-d8a3-46cb-809d-831075c100aa\",\"msgType\":2},\"msgId\":\"5e4b3036-6086-4450-ace0-0431e60a460d\",\"_msgid\":\"6b965bb876743508\"}",
        "payloadType": "json",
        "x": 590,
        "y": 760,
        "wires": [
            []
        ]
    },
    {
        "id": "a2191ef8c7f30edc",
        "type": "victron-output-custom",
        "z": "17b017b2265d4eef",
        "g": "59f8897d78fd047c",
        "service": "com.victronenergy.hub4/0",
        "path": "/Overrides/Setpoint",
        "serviceObj": {
            "service": "com.victronenergy.hub4/0",
            "name": "ESS (0)"
        },
        "pathObj": {
            "path": "/Overrides/Setpoint",
            "name": "/Overrides/Setpoint",
            "type": "object",
            "value": null
        },
        "name": "",
        "onlyChanges": false,
        "roundValues": "no",
        "rateLimit": 0,
        "conditionalMode": false,
        "condition1Operator": ">",
        "condition1HysteresisEnabled": false,
        "condition1HysteresisThreshold": "",
        "condition2Enabled": false,
        "condition2Service": "",
        "condition2Path": "",
        "condition2Operator": ">",
        "logicOperator": "AND",
        "outputTrue": "true",
        "outputFalse": "false",
        "outputOnChange": false,
        "debounce": 2000,
        "x": 900,
        "y": 1520,
        "wires": []
    },
    {
        "id": "290da2eb2dc3479e",
        "type": "vrm-api",
        "z": "17b017b2265d4eef",
        "g": "a71924f761669a5d",
        "vrm": "fa90d7a11bfc6ddb",
        "name": "Get SolarForcast and GridPrice",
        "api_type": "installations",
        "idUser": "",
        "usersQuery": "installations",
        "idSite": "vrmSiteId",
        "installations": "stats",
        "attribute": "dynamic_ess",
        "stats_interval": "15mins",
        "show_instance": false,
        "stats_start": "0",
        "stats_end": "86400",
        "use_utc": true,
        "gps_start": "",
        "gps_end": "",
        "widgets": "PVInverterStatus",
        "instance": "",
        "store_in_global_context": false,
        "verbose": false,
        "transform_price_schedule": false,
        "outputs": 1,
        "x": 470,
        "y": 960,
        "wires": [
            [
                "8ebf6d92c05143f2",
                "b63058b521f27d5c"
            ]
        ]
    },
    {
        "id": "b63058b521f27d5c",
        "type": "debug",
        "z": "17b017b2265d4eef",
        "g": "a71924f761669a5d",
        "name": "incommimg",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 990,
        "y": 1020,
        "wires": []
    },
    {
        "id": "2c7bae975694e7a2",
        "type": "inject",
        "z": "17b017b2265d4eef",
        "g": "a71924f761669a5d",
        "name": "SetChargingProfile",
        "props": [],
        "repeat": "3600",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 160,
        "y": 960,
        "wires": [
            [
                "290da2eb2dc3479e"
            ]
        ]
    },
    {
        "id": "8ebf6d92c05143f2",
        "type": "function",
        "z": "17b017b2265d4eef",
        "g": "a71924f761669a5d",
        "name": "currentLimitProfile",
        "func": "const priceLimit = flow.get(\"gridPriceLimit\") || 0.35;\nconst maxChargeLimit = flow.get(\"EVCSLimit\") || flow.get(\"maxChargeLoad\");\nconst minLoad = flow.minChargeLoad;\nvar iPV = 0;\nvar iCL = 0;\nvar chargeLimit = [];\nvar pvForcast = 0;\nvar cL = 0;\n\n// msg.payload.records.deGb[ideGb][0]\n// msg.payload.records.solar_yield_forecast[iPV][0]\nfor (var ideGb = 0; ideGb < msg.payload.records.deGb.length; ideGb++){\n    if( msg.payload.records.solar_yield_forecast.length <= ideGb){break;}\n    while (msg.payload.records.deGb[ideGb][0] >= msg.payload.records.solar_yield_forecast[iPV+1][0]){\n        iPV++;\n    }\n        // node.warn(msg.payload.records.deGb[ideGb][0] - msg.payload.records.solar_yield_forecast[iPV][0]);\n    pvForcast = msg.payload.records.solar_yield_forecast[iPV][1]\n    if(msg.payload.records.deGb[ideGb][1] > priceLimit){\n        cL = (pvForcast > (minLoad - 500) ? pvForcast : 0);\n    }else {cL = maxChargeLimit;}\n\n    chargeLimit[ideGb] = [msg.payload.records.deGb[ideGb][0],cL];\n\n}\n// msg = {};\n// msg.payload = chargeLimit\n\nvar start = chargeLimit[0][0];\nvar end = chargeLimit.at(-1)[0];\nvar chargeProfile  = [];\nvar iCP = 0;\n\nfor (var itemCL of chargeLimit){\n    if(iCP ==0 || chargeProfile[iCP-1].limit != parseInt(itemCL[1])){\n        chargeProfile[iCP] = {\n            \"limit\": parseInt(itemCL[1]),\n            \"startPeriod\": parseInt((itemCL[0] - start)/1000)\n        };\n        iCP++;\n    }\n\n}\nmsg = {};\n\nmsg.payload = {\n    \"data\": {\n        \"connectorId\": 0,\n        \"csChargingProfiles\": {\n            // \"chargingProfileId\": flow.get(\"dailyCP\"),\n            \"chargingProfileKind\": \"Absolute\",\n            \"chargingProfilePurpose\": \"TxDefaultProfile\",\n            \"chargingSchedule\": {\n                \"chargingRateUnit\": \"W\",\n                \"chargingSchedulePeriod\": chargeProfile,\n                // \"duration\": 86400,\n                \"startSchedule\": new Date(start).toISOString()\n            },\n//            \"transactionId\": 123456,\n            // \"validFrom\": new Date(start).toISOString(),\n            // \"validTo\": new Date(stop).toISOString(),\n            \"stackLevel\": 1\n        }\n    }\n}\nmsg.payload.command = \"SetChargingProfile\";\nmsg.payload.msgType= 2;\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "// Der Code hier wird ausgeführt,\n// wenn der Node gestartet wird\nflow.set(\"SoCForcast\",[]);",
        "finalize": "",
        "libs": [],
        "x": 750,
        "y": 960,
        "wires": [
            [
                "b6ef33d841b43f61"
            ]
        ]
    },
    {
        "id": "6bdb11631a17a7f9",
        "type": "inject",
        "z": "17b017b2265d4eef",
        "g": "a71924f761669a5d",
        "name": "ClearChargingProfile",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"msgType\":2,\"command\":\"ClearChargingProfile\",\"data\":{}}",
        "payloadType": "json",
        "x": 670,
        "y": 900,
        "wires": [
            [
                "b6ef33d841b43f61"
            ]
        ]
    },
    {
        "id": "3a9ee99528aebbb6",
        "type": "inject",
        "z": "17b017b2265d4eef",
        "d": true,
        "g": "a71924f761669a5d",
        "name": "GetVirtualDeviceLimit",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"msgType\":2,\"command\":\"GetVirtualDeviceLimit\",\"data\":{}}",
        "payloadType": "json",
        "x": 680,
        "y": 860,
        "wires": [
            [
                "b6ef33d841b43f61"
            ]
        ]
    },
    {
        "id": "640eef9320f44225",
        "type": "function",
        "z": "17b017b2265d4eef",
        "g": "a71924f761669a5d",
        "name": "TxProfile",
        "func": "\nconst limit = msg.payload.limit;\nconst duration = msg.payload.duration;\nmsg ={};\nmsg.payload = {\n    \"data\": {\n        \"connectorId\": 1,\n        \"csChargingProfiles\": {\n            // \"chargingProfileId\": flow.get(\"dailyCP\"),\n            \"chargingProfileKind\": \"Relative\",\n            \"chargingProfilePurpose\": \"TxProfile\",\n            \"chargingSchedule\": {\n                \"chargingRateUnit\": \"W\",\n                \"chargingSchedulePeriod\": {\n                    // \"startPeriod\": 0,\n                    \"limit\": limit\n        },\n                \"duration\": duration,\n                // \"startSchedule\": new Date(start).toISOString()\n            },\n//            \"transactionId\": 123456,\n            // \"validFrom\": new Date(start).toISOString(),\n            // \"validTo\": new Date(stop).toISOString(),\n            \"stackLevel\": 2\n        }\n    }\n}\nmsg.payload.command = \"SetChargingProfile\";\nmsg.payload.msgType= 2;\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 720,
        "y": 1080,
        "wires": [
            [
                "b63058b521f27d5c",
                "b6ef33d841b43f61"
            ]
        ]
    },
    {
        "id": "9ec157cdf763fb36",
        "type": "inject",
        "z": "17b017b2265d4eef",
        "g": "a71924f761669a5d",
        "name": "Set 15min Limit",
        "props": [
            {
                "p": "payload.limit",
                "v": "1500",
                "vt": "str"
            },
            {
                "p": "payload.duration",
                "v": "900",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 140,
        "y": 1080,
        "wires": [
            [
                "83d348c4bba99711"
            ]
        ]
    },
    {
        "id": "226cce0fdd4abc0a",
        "type": "victron-virtual",
        "z": "17b017b2265d4eef",
        "g": "59f8897d78fd047c",
        "name": "EM EVCS 1",
        "outputs": 1,
        "device": "energymeter",
        "default_values": false,
        "acload_nrofphases": "3",
        "enable_s2support": false,
        "s2_measurement_type": "3_PHASE_SYMMETRIC",
        "battery_capacity": 25,
        "include_battery_temperature": false,
        "battery_voltage_preset": "24",
        "battery_voltage_custom": 24,
        "generator_type": "ac",
        "generator_nrofphases": 1,
        "include_engine_hours": false,
        "include_starter_voltage": false,
        "include_history_energy": false,
        "grid_nrofphases": 1,
        "energymeter_nrofphases": "3",
        "energymeter_role": "evcharger",
        "include_motor_temp": false,
        "include_controller_temp": false,
        "include_coolant_temp": false,
        "include_motor_rpm": true,
        "include_motor_direction": true,
        "position": 0,
        "pvinverter_nrofphases": 1,
        "switch_1_type": 1,
        "switch_1_min": 0,
        "switch_1_max": "",
        "switch_1_initial": 0,
        "switch_1_label": "",
        "switch_1_unit": "",
        "switch_1_step": 1,
        "switch_1_customname": "",
        "switch_1_group": "",
        "switch_1_include_measurement": false,
        "switch_1_rgb_color_wheel": false,
        "switch_1_cct_wheel": false,
        "switch_1_rgb_white_dimmer": false,
        "switch_1_passthrough_mode": "auto_only",
        "fluid_type": 0,
        "include_tank_battery": false,
        "include_tank_temperature": false,
        "tank_battery_voltage": 3.3,
        "tank_capacity": 0.2,
        "auto_aggregate": false,
        "pulsemeter_multiplier": 0.001,
        "ev_vin": "",
        "ev_battery_capacity": "",
        "temperature_type": 2,
        "include_humidity": false,
        "include_pressure": false,
        "include_temp_battery": false,
        "temp_battery_voltage": 3.3,
        "start_disconnected": true,
        "x": 830,
        "y": 1300,
        "wires": [
            [
                "d7ddcba25f10b458"
            ]
        ]
    },
    {
        "id": "8939894fe6a45b98",
        "type": "victron-virtual",
        "z": "17b017b2265d4eef",
        "g": "59f8897d78fd047c",
        "name": "EM EVCS 2",
        "outputs": 1,
        "device": "energymeter",
        "default_values": false,
        "acload_nrofphases": "3",
        "enable_s2support": false,
        "s2_measurement_type": "3_PHASE_SYMMETRIC",
        "battery_capacity": 25,
        "include_battery_temperature": false,
        "battery_voltage_preset": "24",
        "battery_voltage_custom": 24,
        "generator_type": "ac",
        "generator_nrofphases": 1,
        "include_engine_hours": false,
        "include_starter_voltage": false,
        "include_history_energy": false,
        "grid_nrofphases": 1,
        "energymeter_nrofphases": "3",
        "energymeter_role": "evcharger",
        "include_motor_temp": false,
        "include_controller_temp": false,
        "include_coolant_temp": false,
        "include_motor_rpm": true,
        "include_motor_direction": true,
        "position": 0,
        "pvinverter_nrofphases": 1,
        "switch_1_type": 1,
        "switch_1_min": 0,
        "switch_1_max": "",
        "switch_1_initial": 0,
        "switch_1_label": "",
        "switch_1_unit": "",
        "switch_1_step": 1,
        "switch_1_customname": "",
        "switch_1_group": "",
        "switch_1_include_measurement": false,
        "switch_1_rgb_color_wheel": false,
        "switch_1_cct_wheel": false,
        "switch_1_rgb_white_dimmer": false,
        "switch_1_passthrough_mode": "auto_only",
        "fluid_type": 0,
        "include_tank_battery": false,
        "include_tank_temperature": false,
        "tank_battery_voltage": 3.3,
        "tank_capacity": 0.2,
        "auto_aggregate": false,
        "pulsemeter_multiplier": 0.001,
        "ev_vin": "",
        "ev_battery_capacity": "",
        "temperature_type": 2,
        "include_humidity": false,
        "include_pressure": false,
        "include_temp_battery": false,
        "temp_battery_voltage": 3.3,
        "start_disconnected": true,
        "x": 830,
        "y": 1360,
        "wires": [
            [
                "d7ddcba25f10b458"
            ]
        ]
    },
    {
        "id": "016f62610b6768ca",
        "type": "function",
        "z": "17b017b2265d4eef",
        "g": "59f8897d78fd047c",
        "name": "Calculate GridSetPoint",
        "func": "//initialisation variables\nconst stdGridSetPoint = flow.get(\"stdGridSetPoint\");\nconst SoCTreshold = flow.get(\"minChargingSoC\");\nvar GridSetPoint;\n\n//find minimal SoC of the next 18 hours\nlet minSoC = 0;\n\nif (msg.payload.records?.vrm_soc_plan) {\n    let SoCForcast = msg.payload.records.vrm_soc_plan;\n    minSoC = 100;\n\n    for (let item = SoCForcast.length -1; item >=0; item--){\n        if (Date.now() + (18*60*60*1000) >= SoCForcast[item][0]){ //only check for the next 18 houres\n            minSoC = parseInt(Math.min(minSoC,SoCForcast[item][1]));\n        }\n        flow.set(\"minSoC\",minSoC);\n        if (Date.now() >= SoCForcast[item][0]){ //end if actual time is reached\n            break;\n        }\n    }\n}\n\n//process new EVCS load values\nlet loadEVCS = flow.get(\"LoadEVCS\");\nif (msg.topic == \"CGMeter-1\" && msg?.payload[\"/Ac/Power\"] != undefined) {\n    loadEVCS[1] = msg.payload[\"/Ac/Power\"];\n}else if (msg.topic == \"CGMeter-2\" && msg?.payload[\"/Ac/Power\"] != undefined) {\n    loadEVCS[2] = msg.payload[\"/Ac/Power\"];\n}\nloadEVCS[0] = loadEVCS[1] + loadEVCS[2];\nflow.set(\"LoadEVCS\",loadEVCS);\n\n//claculate new Grid setpoint\nif(flow.get(\"minSoC\") > SoCTreshold){\n    GridSetPoint = stdGridSetPoint;\n} else{\n    GridSetPoint = loadEVCS[0] - 500;\n}\n\n//calculate new EVCS limit based on the main fuse limitation and store it in the flow variable\nif (msg.topic == \"Gid Load\") {\n    const deviation = parseInt((flow.get(\"maxGridLoad\") - msg.payload) / 1000)*1000;\n    flow.set(\"EVCSLimit\", flow.get(\"EVCSLimit\") || 0);\n    if (deviation < 0 || (deviation > flow.get(\"EVCSLimit\") && flow.get(\"EVCSLimit\") < flow.get(\"maxChargeLoad\"))){\n        flow.set(\"EVCSLimit\", Math.max(flow.get(\"minChargeLoad\"), Math.min(flow.get(\"maxChargeLoad\"),flow.get(\"EVCSLimit\") + deviation)));\n        return [{\"payload\": (GridSetPoint <= stdGridSetPoint ? stdGridSetPoint : GridSetPoint)}, {\"payload\": flow.get(\"EVCSLimit\")}]\n    }\n}\n\nreturn [{\"payload\": (GridSetPoint <= stdGridSetPoint ? stdGridSetPoint : GridSetPoint)},null];\n",
        "outputs": 2,
        "timeout": 0,
        "noerr": 0,
        "initialize": "flow.set(\"LoadEVCS\", [0,0,0]);\nflow.set(\"minSoC\", 0);\n",
        "finalize": "",
        "libs": [],
        "x": 420,
        "y": 1520,
        "wires": [
            [
                "a2191ef8c7f30edc",
                "e4e36e1547ec24eb"
            ],
            [
                "71a74a28de11279c"
            ]
        ]
    },
    {
        "id": "e70f1dd07148cc5a",
        "type": "function",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "Catch n Manipulate",
        "func": "\nif (msg.payload.tagList?.length > 0){context.tagList = msg.payload.tagList; return null;}\n\n// Catch Authorisation request for knowen idTag\nif(msg.payload?.command == \"Authorize\"){\n    for (let item of context.tagList){\n        node.warn(msg.payload.data.idTag);\n        if (msg.payload.data?.idTag == item.idTag) {\n            node.warn(item);\n            msg.ocpp.msgType = 3;\n            delete(msg.ocpp.data);\n            msg.payload = {};\n            msg.payload.data = {\"idTagInfo\":{\"status\":\"Accepted\"}};\n            return [null, msg] ;\n        }\n    }\n}\nreturn [msg, null];\n\n",
        "outputs": 2,
        "timeout": "",
        "noerr": 0,
        "initialize": "// Der Code hier wird ausgeführt,\n// wenn der Node gestartet wird\ncontext.tagList = [];",
        "finalize": "",
        "libs": [],
        "x": 830,
        "y": 200,
        "wires": [
            [
                "f77e3549f2df1b32"
            ],
            [
                "537fd9734c5e4e03"
            ]
        ]
    },
    {
        "id": "d7ddcba25f10b458",
        "type": "switch",
        "z": "17b017b2265d4eef",
        "g": "59f8897d78fd047c",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "hask",
                "v": "/Ac/Power",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 1010,
        "y": 1320,
        "wires": [
            [
                "f32a2c3539951257",
                "927f1aba4218e035"
            ]
        ]
    },
    {
        "id": "0e87eb14c089b953",
        "type": "inject",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "Allowed Tag List",
        "props": [
            {
                "p": "payload.tagList",
                "v": "[{\"idTag\":\"Tag_Identifier_01\",\"user\":\"Installer\"},{\"idTag\":\"000000A3D0FB12\",\"user\":\"Ulfilas\"}]",
                "vt": "json"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": "1",
        "topic": "",
        "x": 660,
        "y": 120,
        "wires": [
            [
                "e70f1dd07148cc5a"
            ]
        ]
    },
    {
        "id": "e498cb5fd423feaa",
        "type": "inject",
        "z": "17b017b2265d4eef",
        "g": "389e6b39b85cf801",
        "name": "test Authorisation",
        "props": [
            {
                "p": "ocpp",
                "v": "{\"msgType\":2,\"command\":\"Authorize\",\"data\":{\"idTag\":\"Tag_Identifier_01\"}}",
                "vt": "json"
            },
            {
                "p": "msgTag.origin",
                "v": "EVCS",
                "vt": "str"
            },
            {
                "p": "msgTag.uTimestamp",
                "v": "",
                "vt": "date"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 140,
        "y": 760,
        "wires": [
            [
                "63f4a317c92b54aa"
            ]
        ]
    },
    {
        "id": "0688cc021dcbe159",
        "type": "modbus-flex-getter",
        "z": "17b017b2265d4eef",
        "g": "59f8897d78fd047c",
        "name": "EVCS GW",
        "showStatusActivities": false,
        "showErrors": false,
        "showWarnings": true,
        "logIOActivities": false,
        "server": "8156c135951d2377",
        "useIOFile": false,
        "ioFile": "",
        "useIOForPayload": false,
        "emptyMsgOnFail": false,
        "keepMsgProperties": false,
        "delayOnStart": false,
        "enableDeformedMessages": false,
        "startDelayTime": "",
        "x": 230,
        "y": 1300,
        "wires": [
            [
                "1cbbe490c95c37cb"
            ],
            []
        ]
    },
    {
        "id": "927f1aba4218e035",
        "type": "debug",
        "z": "17b017b2265d4eef",
        "g": "59f8897d78fd047c",
        "name": "debug 8",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1220,
        "y": 1320,
        "wires": []
    },
    {
        "id": "83d348c4bba99711",
        "type": "change",
        "z": "17b017b2265d4eef",
        "g": "a71924f761669a5d",
        "name": "",
        "rules": [
            {
                "t": "move",
                "p": "payload",
                "pt": "msg",
                "to": "payload.limit",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "payload.duration",
                "pt": "msg",
                "to": "500",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 430,
        "y": 1080,
        "wires": [
            [
                "640eef9320f44225"
            ]
        ]
    },
    {
        "id": "d271589acd162dd8",
        "type": "victron-input-gridmeter",
        "z": "17b017b2265d4eef",
        "g": "59f8897d78fd047c",
        "service": "com.victronenergy.grid/33",
        "path": "/Ac/Power",
        "serviceObj": {
            "service": "com.victronenergy.grid/33",
            "name": "Haus Zähler",
            "communityTag": "gridmeter"
        },
        "pathObj": {
            "path": "/Ac/Power",
            "type": "float",
            "name": "Power (W)"
        },
        "name": "Gid Load",
        "onlyChanges": false,
        "roundValues": "0",
        "rateLimit": "0.2",
        "conditionalMode": false,
        "condition1HysteresisEnabled": false,
        "condition1HysteresisThreshold": "",
        "outputTrue": "true",
        "outputFalse": "false",
        "debounce": "2000",
        "x": 160,
        "y": 1540,
        "wires": [
            [
                "016f62610b6768ca"
            ]
        ]
    },
    {
        "id": "2d316cee30d6fbcc",
        "type": "inject",
        "z": "17b017b2265d4eef",
        "g": "389e6b39b85cf801",
        "name": "SmartCharge const",
        "props": [
            {
                "p": "payload.maxChargeLoad",
                "v": "22000",
                "vt": "num"
            },
            {
                "p": "payload.minChargeLoad",
                "v": "4200",
                "vt": "num"
            },
            {
                "p": "payload.maxGridLoad",
                "v": "50000",
                "vt": "num"
            },
            {
                "p": "payload.stdGridSetPoint",
                "v": "-50",
                "vt": "num"
            },
            {
                "p": "payload.gridPriceLimit",
                "v": "35",
                "vt": "num"
            },
            {
                "p": "payload.minChargingSoC",
                "v": "25",
                "vt": "num"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": "0.001",
        "topic": "",
        "x": 950,
        "y": 600,
        "wires": [
            [
                "6211ee624730dd62"
            ]
        ]
    },
    {
        "id": "6211ee624730dd62",
        "type": "change",
        "z": "17b017b2265d4eef",
        "g": "389e6b39b85cf801",
        "name": "Set flow const",
        "rules": [
            {
                "t": "set",
                "p": "maxChargeLoad",
                "pt": "flow",
                "to": "payload.maxChargeLoad",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "minChargeLoad",
                "pt": "flow",
                "to": "payload.minChargeLoad",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "maxGridLoad",
                "pt": "flow",
                "to": "payload.maxGridLoad",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "stdGridSetPoint",
                "pt": "flow",
                "to": "payload.stdGridSetPoint",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "gridPriceLimit",
                "pt": "flow",
                "to": "payload.gridPriceLimit",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "minChargingSoC",
                "pt": "flow",
                "to": "payload.minChargingSoC",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1140,
        "y": 600,
        "wires": [
            []
        ]
    },
    {
        "id": "53d6230003810363",
        "type": "link in",
        "z": "17b017b2265d4eef",
        "g": "59f8897d78fd047c",
        "name": "EVCSPower in",
        "links": [
            "f32a2c3539951257"
        ],
        "x": 205,
        "y": 1500,
        "wires": [
            [
                "016f62610b6768ca"
            ]
        ]
    },
    {
        "id": "f32a2c3539951257",
        "type": "link out",
        "z": "17b017b2265d4eef",
        "g": "59f8897d78fd047c",
        "name": "EVCS Power out",
        "mode": "link",
        "links": [
            "53d6230003810363"
        ],
        "x": 1135,
        "y": 1320,
        "wires": []
    },
    {
        "id": "761a0f55f4626b21",
        "type": "link in",
        "z": "17b017b2265d4eef",
        "g": "44ac6bf510980216",
        "name": "CSMS in",
        "links": [
            "63f4a317c92b54aa",
            "b6ef33d841b43f61"
        ],
        "x": 235,
        "y": 460,
        "wires": [
            [
                "cde258b40613cc08"
            ]
        ]
    },
    {
        "id": "63f4a317c92b54aa",
        "type": "link out",
        "z": "17b017b2265d4eef",
        "g": "389e6b39b85cf801",
        "name": "CSMS Command out",
        "mode": "link",
        "links": [
            "761a0f55f4626b21"
        ],
        "x": 375,
        "y": 700,
        "wires": []
    },
    {
        "id": "b6ef33d841b43f61",
        "type": "link out",
        "z": "17b017b2265d4eef",
        "g": "a71924f761669a5d",
        "name": "CSMS Command out",
        "mode": "link",
        "links": [
            "761a0f55f4626b21"
        ],
        "x": 1040,
        "y": 960,
        "wires": [],
        "l": true
    },
    {
        "id": "5f6edab6a877da69",
        "type": "link in",
        "z": "17b017b2265d4eef",
        "g": "a71924f761669a5d",
        "name": "EVCS Limit in",
        "links": [
            "71a74a28de11279c"
        ],
        "x": 305,
        "y": 940,
        "wires": [
            [
                "290da2eb2dc3479e"
            ]
        ]
    },
    {
        "id": "71a74a28de11279c",
        "type": "link out",
        "z": "17b017b2265d4eef",
        "g": "59f8897d78fd047c",
        "name": "EVCS Limit out",
        "mode": "link",
        "links": [
            "5f6edab6a877da69"
        ],
        "x": 595,
        "y": 1540,
        "wires": []
    },
    {
        "id": "f76c95ea96f848cd",
        "type": "inject",
        "z": "17b017b2265d4eef",
        "g": "59f8897d78fd047c",
        "name": "getSerialNo",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "900",
        "crontab": "",
        "once": true,
        "onceDelay": "20",
        "topic": "Serial CGMeter-1",
        "payload": "{\"value\":\"msg.payload\",\"fc\":3,\"address\":20480,\"unitid\":1,\"quantity\":7}",
        "payloadType": "json",
        "x": 130,
        "y": 1240,
        "wires": [
            [
                "fbe7a6b2bc91ba3d"
            ]
        ]
    },
    {
        "id": "fbe7a6b2bc91ba3d",
        "type": "delay",
        "z": "17b017b2265d4eef",
        "g": "59f8897d78fd047c",
        "name": "",
        "pauseType": "rate",
        "timeout": "5",
        "timeoutUnits": "seconds",
        "rate": "2",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 440,
        "y": 1240,
        "wires": [
            [
                "156faa677fc271bf",
                "0688cc021dcbe159"
            ]
        ]
    },
    {
        "id": "1cbbe490c95c37cb",
        "type": "function",
        "z": "17b017b2265d4eef",
        "g": "59f8897d78fd047c",
        "name": "Parse Modbus Massage",
        "func": "//initialisation variables\nvar data = msg.payload;\nlet Bytes2Int32 = global.get(\"Bytes2Int32\");\nlet Byte2Int16 = global.get(\"Byte2Int16\");\n\nvar msgMeter = {};\nlet msgArray =[copy(context.commands[0]),null,null];\nmsgArray[0].payload.unitid = context.devices[0].unitId;\nmsgArray[0].topic = context.commands[0].topic.slice() + \" CGMeter-\" + context.devices[0].unitId;\nvar commandIndex = 0;\n//get device index from topic ID\nlet deviceIndex = context.devices.findIndex(p => p.unitId === parseInt(msg.topic.substring(msg.topic.indexOf(\"CGMeter\")+8)));\n\n//check for valid device index\nif (deviceIndex == -1) {return msgArray;}\n\n//selector for modbus response massage\n//the outgoing massage on port 0 contains the next modbus read command\nswitch (msg.topic.substring(0,msg.topic.indexOf(\"CGMeter\")-1)){\n//parse serial number and set state connected\n    case \"Serial\":\n        if (msg.modbusRequest.quantity == context.commands[commandIndex].payload.quantity){\n            if (!context.devices[deviceIndex].connected){\n                context.devices[deviceIndex].connected = true;\n                msgArray[deviceIndex+1] = {\"connected\": true};\n                msgArray[0] = copy(context.commands[commandIndex]);\n                msgArray[0].payload.unitid = context.devices[deviceIndex].unitId;\n                msgArray[0].topic = msgArray[0].topic + \" CGMeter-\" + context.devices[deviceIndex].unitId;\n                return msgArray;\n            }\n            msgMeter = { \"payload\": {\"/Serial\": String(msg.responseBuffer.buffer).replace(/\\0/g, '')}};\n            msgArray[deviceIndex+1] = msgMeter;\n\n            if (deviceIndex < context.devices.length -1 ) {\n                deviceIndex += 1;\n                msgArray[0] = copy(context.commands[commandIndex]);\n            } else { //if massage error the readcommand will be repeted\n                deviceIndex = 0;\n                msgArray[0] = copy(context.commands[commandIndex + 1]);\n            }\n            msgArray[0].payload.unitid = context.devices[deviceIndex].unitId;\n            msgArray[0].topic = msgArray[0].topic + \" CGMeter-\" + context.devices[deviceIndex].unitId;\n            return msgArray;\n        }else {\n            msgArray[0] = copy(context.commands[commandIndex]);\n            msgArray[0].payload.unitid = context.devices[deviceIndex].unitId;\n            msgArray[0].topic = msgArray[0].topic + \" CGMeter-\" + context.devices[deviceIndex].unitId;\n            return msgArray;\n        }\n        break;\n//block one set line voltages and basic parameters    \n    case \"blck1\":\n        commandIndex = 1;\n        if (msg.modbusRequest.quantity == context.commands[commandIndex].payload.quantity){\n            msgMeter = { payload: {\n                    \"/Ac/L1/Voltage\": Bytes2Int32(data[0],data[1])/10,\n                    \"/Ac/L2/Voltage\": Bytes2Int32(data[2],data[3])/10,\n                    \"/Ac/L3/Voltage\": Bytes2Int32(data[4],data[5])/10,\n                    // \"/Ac/Frequency\": AcFrequency,\n                    \"/DeviceType\": 71,\n                    \"/Position\": 1, //       <-- 0=AC Output, 1=AC Input\n                    \"/IsGenericEnergyMeter\": 1,\n                    // \"/ProductName\":,\n                    // \"/CustomName\":,\n                    // \"/Mgmt/Connection\":,\n                    // \"/Mgmt/ProcessName\":,\n                    // \"/Mgmt/ProcessVersion\":,\n                    \"/Connected\": true,\n                    // \"/DeviceInstance\":,\n                    // \"/ProductId\": \"EM340\",\n                    // \"/HardwareVersion\":,\n                    // \"/FirmwareVersion\":,\n                    \"/ErrorCode\": 0}};\n            msgArray[deviceIndex+1] = msgMeter;\n            if (deviceIndex < context.devices.length -1 ) {\n                deviceIndex += 1;\n                msgArray[0] = copy(context.commands[commandIndex]);\n            } else {\n                deviceIndex = 0;\n                msgArray[0] = copy(context.commands[commandIndex + 1]);\n            }\n            msgArray[0].payload.unitid = context.devices[deviceIndex].unitId;\n            msgArray[0].topic = msgArray[0].topic + \" CGMeter-\" + context.devices[deviceIndex].unitId;\n                // node.warn(msgArray);\n            return msgArray;\n    \n        }else {\n            msgArray[0] = copy(context.commands[commandIndex]);\n            msgArray[0].payload.unitid = context.devices[deviceIndex].unitId;\n            msgArray[0].topic = msgArray[0].topic + \" CGMeter-\" + context.devices[deviceIndex].unitId;\n            return msgArray;\n        }\n        break;\n//Block two set line current and power\n    case \"blck2\":\n        commandIndex = 2;\n        if (msg.modbusRequest.quantity == context.commands[commandIndex].payload.quantity){\n            msgMeter = { payload: {\n                \"/Ac/L1/Current\": Bytes2Int32(data[0],data[1])/1000, \n                \"/Ac/L2/Current\": Bytes2Int32(data[2],data[3])/1000, \n                \"/Ac/L3/Current\": Bytes2Int32(data[4],data[5])/1000,\n                \"/Ac/L1/Power\": Bytes2Int32(data[6],data[7])/10,\n                \"/Ac/L2/Power\": Bytes2Int32(data[8],data[9])/10,\n                \"/Ac/L3/Power\": Bytes2Int32(data[10],data[11])/10}}; \n            msgArray[deviceIndex+1] = msgMeter;\n            if (deviceIndex < context.devices.length -1 ) {\n                deviceIndex += 1;\n                msgArray[0] = copy(context.commands[commandIndex]);\n            } else {\n                deviceIndex = 0;\n                msgArray[0] = copy(context.commands[commandIndex + 1]);\n            }\n            msgArray[0].payload.unitid = context.devices[deviceIndex].unitId;\n            msgArray[0].topic = msgArray[0].topic + \" CGMeter-\" + context.devices[deviceIndex].unitId;\n                // node.warn(msgArray);\n            return msgArray;\n    \n        }else {\n            msgArray[0] = copy(context.commands[commandIndex]);\n            msgArray[0].payload.unitid = context.devices[deviceIndex].unitId;\n            msgArray[0].topic = msgArray[0].topic + \" CGMeter-\" + context.devices[deviceIndex].unitId;\n            return msgArray;\n        }\n        break;\n//Block three set power, power factor and forward energy\n    case \"blck3\":\n        commandIndex = 3;\n        if (msg.modbusRequest.quantity == context.commands[commandIndex].payload.quantity){\n            msgMeter = { payload: {\"/Ac/Power\": Bytes2Int32(data[0],data[1])/10, \n                \"/Ac/L1/PowerFactor\": Byte2Int16(data[6])/1000,\n                \"/Ac/L2/PowerFactor\": Byte2Int16(data[7])/1000,\n                \"/Ac/L3/PowerFactor\": Byte2Int16(data[8])/1000,\n                \"/Ac/PowerFactor\": Byte2Int16(data[9])/1000}};\n            if (Bytes2Int32(data[12],data[13]) > 0){\n                msgMeter.payload = {...msgMeter.payload,  \"/Ac/Energy/Forward\": Bytes2Int32(data[12],data[13])/10};}\n\n            msgArray[deviceIndex+1] = msgMeter;\n            if (deviceIndex < context.devices.length -1 ) {\n                deviceIndex += 1;\n                msgArray[0] = copy(context.commands[commandIndex]);\n            } else {\n                deviceIndex = 0;\n                msgArray[0] = copy(context.commands[commandIndex + 1]);\n            }\n            msgArray[0].payload.unitid = context.devices[deviceIndex].unitId;\n            msgArray[0].topic = msgArray[0].topic + \" CGMeter-\" + context.devices[deviceIndex].unitId;\n                // node.warn(msgArray);\n            return msgArray;\n    \n        }else {\n            msgArray[0] = copy(context.commands[commandIndex]);\n            msgArray[0].payload.unitid = context.devices[deviceIndex].unitId;\n            msgArray[0].topic = msgArray[0].topic + \" CGMeter-\" + context.devices[deviceIndex].unitId;\n            return msgArray;\n        }\n        break;\n//Block four set line energy and reverse energy\n    case \"blck4\":\n        commandIndex = 4;\n        if (msg.modbusRequest.quantity == context.commands[commandIndex].payload.quantity ){\n            if (Bytes2Int32(data[14],data[15]) > 0){\n                msgMeter.payload = {...msgMeter.payload,  \"/Ac/Energy/Reverse\": Bytes2Int32(data[14],data[15])/10};}\n                \n            if (Bytes2Int32(data[0],data[1]) > 0){\n                msgMeter.payload = {...msgMeter.payload,  \"/Ac/L1/Energy/Forward\": Bytes2Int32(data[0],data[1])/10};}\n                \n            if (Bytes2Int32(data[2],data[3]) > 0){\n                msgMeter.payload = {...msgMeter.payload,  \"/Ac/L2/Energy/Forward\": Bytes2Int32(data[2],data[3])/10};}\n                \n            if (Bytes2Int32(data[4],data[5]) > 0){\n                msgMeter.payload = {...msgMeter.payload,  \"/Ac/L3/Energy/Forward\": Bytes2Int32(data[4],data[5])/10};}\n                \n            msgArray[deviceIndex+1] = msgMeter;\n            if (deviceIndex < context.devices.length -1 ) {\n                deviceIndex += 1;\n                msgArray[0] = copy(context.commands[commandIndex]);\n            } else {\n                deviceIndex = 0;\n                msgArray[0] = copy(context.commands[1]);\n            }\n            msgArray[0].payload.unitid = context.devices[deviceIndex].unitId;\n            msgArray[0].topic = msgArray[0].topic + \" CGMeter-\" + context.devices[deviceIndex].unitId;\n                // node.warn(msgArray);\n            return msgArray;\n    \n        }else {\n            msgArray[0] = copy(context.commands[commandIndex]);\n            msgArray[0].payload.unitid = context.devices[deviceIndex].unitId;\n            msgArray[0].topic = msgArray[0].topic + \" CGMeter-\" + context.devices[deviceIndex].unitId;\n            return msgArray;\n        }\n        break;\n}\nreturn msgArray;\n\n//define local deep copy function for objects\nfunction copy(aObject) {\n  // Prevent undefined objects\n  // if (!aObject) return aObject;\n\n  let bObject = Array.isArray(aObject) ? [] : {};\n\n  let value;\n  for (const key in aObject) {\n\n    // Prevent self-references to parent object\n    // if (Object.is(aObject[key], aObject)) continue;\n    \n    value = aObject[key];\n\n    bObject[key] = (typeof value === \"object\") ? copy(value) : value;\n  }\n\n  return bObject;\n}",
        "outputs": 3,
        "timeout": 0,
        "noerr": 0,
        "initialize": "//Modbus parser for int16 and int32\nfunction Bytes2Int32(lowByte,highByte){\n    return (highByte >= 32768) ? ((highByte-65536) * 65536) + lowByte : (highByte * 65536) + lowByte;\n}\nfunction Byte2Int16(Byte){\n    return (Byte >= 32768) ? Byte-65536 : Byte;\n}\nglobal.set(\"Bytes2Int32\",Bytes2Int32)\nglobal.set(\"Byte2Int16\",Byte2Int16)\n\n//Initialize Modbus units\ncontext.devices = [{\"unitId\": 1, \"connected\": false},\n                {\"unitId\": 2, \"connected\": false}];\n\n//initialize modbus read blocks\ncontext.commands = [{\"topic\":'Serial',\n    \"payload\":{\"value\": \"msg.payload\",\"fc\": 3,\"address\": 20480,\"unitid\": 1,\"quantity\": 7}},\n    {\"topic\":'blck1',\n    \"payload\":{\"value\": \"msg.payload\",\"fc\": 3,\"address\": 0,\"unitid\": 1,\"quantity\": 6}},\n    {\"topic\":'blck2',\n    \"payload\":{\"value\": \"msg.payload\",\"fc\": 3,\"address\": 12,\"unitid\": 1,\"quantity\": 12}},\n    {\"topic\":'blck3',\n    \"payload\":{\"value\": \"msg.payload\",\"fc\": 3,\"address\": 40,\"unitid\": 1,\"quantity\": 14}},\n    {\"topic\":'blck4',\n    \"payload\":{\"value\": \"msg.payload\",\"fc\": 3,\"address\": 64,\"unitid\": 1,\"quantity\": 16}},\n    ]\n",
        "finalize": "",
        "libs": [],
        "x": 450,
        "y": 1300,
        "wires": [
            [
                "196fd778a13d7812",
                "5dc322c7e1993517"
            ],
            [
                "226cce0fdd4abc0a"
            ],
            [
                "8939894fe6a45b98"
            ]
        ]
    },
    {
        "id": "7ccb4444844f0ce1",
        "type": "link in",
        "z": "17b017b2265d4eef",
        "g": "59f8897d78fd047c",
        "name": "ModBus in",
        "links": [
            "196fd778a13d7812"
        ],
        "x": 295,
        "y": 1220,
        "wires": [
            [
                "fbe7a6b2bc91ba3d"
            ]
        ]
    },
    {
        "id": "156faa677fc271bf",
        "type": "trigger",
        "z": "17b017b2265d4eef",
        "g": "59f8897d78fd047c",
        "name": "whatchdog",
        "op1": "",
        "op2": "",
        "op1type": "nul",
        "op2type": "pay",
        "duration": "1000",
        "extend": true,
        "overrideDelay": false,
        "units": "ms",
        "reset": "reset",
        "bytopic": "all",
        "topic": "topic",
        "outputs": 1,
        "x": 830,
        "y": 1240,
        "wires": [
            [
                "196fd778a13d7812"
            ]
        ]
    },
    {
        "id": "196fd778a13d7812",
        "type": "link out",
        "z": "17b017b2265d4eef",
        "g": "59f8897d78fd047c",
        "name": "ModBus out",
        "mode": "link",
        "links": [
            "7ccb4444844f0ce1"
        ],
        "x": 1135,
        "y": 1260,
        "wires": []
    },
    {
        "id": "5dc322c7e1993517",
        "type": "change",
        "z": "17b017b2265d4eef",
        "g": "59f8897d78fd047c",
        "name": "reset",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "reset",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 670,
        "y": 1260,
        "wires": [
            [
                "156faa677fc271bf"
            ]
        ]
    },
    {
        "id": "e4e36e1547ec24eb",
        "type": "debug",
        "z": "17b017b2265d4eef",
        "g": "59f8897d78fd047c",
        "name": "debug 2",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1120,
        "y": 1520,
        "wires": []
    },
    {
        "id": "cbfcbce8aec902aa",
        "type": "vrm-api",
        "z": "17b017b2265d4eef",
        "g": "59f8897d78fd047c",
        "vrm": "fa90d7a11bfc6ddb",
        "name": "GetSoC",
        "api_type": "installations",
        "idUser": "",
        "usersQuery": "installations",
        "idSite": "vrmSiteId",
        "installations": "stats",
        "attribute": "dynamic_ess",
        "stats_interval": "15mins",
        "show_instance": false,
        "stats_start": "0",
        "stats_end": "86400",
        "use_utc": true,
        "gps_start": "",
        "gps_end": "",
        "widgets": "PVInverterStatus",
        "instance": "",
        "store_in_global_context": false,
        "verbose": false,
        "transform_price_schedule": false,
        "outputs": 1,
        "x": 240,
        "y": 1440,
        "wires": [
            [
                "016f62610b6768ca"
            ]
        ]
    },
    {
        "id": "4dc444a6ef60ae4a",
        "type": "inject",
        "z": "17b017b2265d4eef",
        "g": "59f8897d78fd047c",
        "name": "5min",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "300",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "SoC",
        "payloadType": "str",
        "x": 110,
        "y": 1440,
        "wires": [
            [
                "cbfcbce8aec902aa"
            ]
        ]
    },
    {
        "id": "0ef75b29ed9253ea",
        "type": "comment",
        "z": "17b017b2265d4eef",
        "name": "General constants for SmartChargeLogic",
        "info": "",
        "x": 1022,
        "y": 558,
        "wires": []
    },
    {
        "id": "03af6795e5707fee",
        "type": "comment",
        "z": "17b017b2265d4eef",
        "g": "a71924f761669a5d",
        "name": "Setting general ChargingProfile respect to GridPrice and SolarForcarst",
        "info": "",
        "x": 290,
        "y": 860,
        "wires": []
    },
    {
        "id": "228b28f0a7956493",
        "type": "comment",
        "z": "17b017b2265d4eef",
        "g": "a71924f761669a5d",
        "name": "overwrite ChargingProfile",
        "info": "",
        "x": 150,
        "y": 1040,
        "wires": []
    },
    {
        "id": "88f5b39aa0f025d6",
        "type": "comment",
        "z": "17b017b2265d4eef",
        "g": "59f8897d78fd047c",
        "name": "Read EVCS MeterValues via Modbus",
        "info": "",
        "x": 210,
        "y": 1180,
        "wires": []
    },
    {
        "id": "63807e6edc499d8a",
        "type": "comment",
        "z": "17b017b2265d4eef",
        "g": "59f8897d78fd047c",
        "name": "recalculate GridSetPoint to prevent discharging the Battery below minSoC  by EV-Charger  ",
        "info": "",
        "x": 370,
        "y": 1400,
        "wires": []
    },
    {
        "id": "92124697.6658f",
        "type": "ocpp-remote-cs",
        "name": "bill.bo",
        "url": "wss://CP_Identifier:Backend_PW@Backend_Server:Backend_Port"
    },
    {
        "id": "2b6ab4fbb3f5ac80",
        "type": "ocpp-remotej-cp",
        "name": "",
        "cbId": "CP_Identifier",
        "ocppver": "1.6j"
    },
    {
        "id": "fa90d7a11bfc6ddb",
        "type": "config-vrm-api",
        "name": "VRM-api-Strompreis",
        "forceIpv4": false
    },
    {
        "id": "8156c135951d2377",
        "type": "modbus-client",
        "name": "WS-GW-WallBox",
        "clienttype": "tcp",
        "bufferCommands": true,
        "stateLogEnabled": false,
        "queueLogEnabled": false,
        "failureLogEnabled": true,
        "tcpHost": "192.168.13.141",
        "tcpPort": 502,
        "tcpType": "DEFAULT",
        "serialPort": "/dev/ttyUSB",
        "serialType": "RTU-BUFFERD",
        "serialBaudrate": 9600,
        "serialDatabits": 8,
        "serialStopbits": 1,
        "serialParity": "none",
        "serialConnectionDelay": 100,
        "serialAsciiResponseStartDelimiter": "0x3A",
        "unit_id": 2,
        "commandDelay": 1,
        "clientTimeout": 1000,
        "reconnectOnTimeout": true,
        "reconnectTimeout": 2000,
        "parallelUnitIdsAllowed": true,
        "showErrors": false,
        "showWarnings": true,
        "showLogs": true
    },
    {
        "id": "91f58ca0c4fb1388",
        "type": "global-config",
        "env": [],
        "modules": {
            "node-red-contrib-ocpp": "1.3.10",
            "@victronenergy/node-red-contrib-victron": "1.7.20",
            "victron-vrm-api": "0.4.3",
            "node-red-contrib-modbus": "5.45.2"
        }
    }
]