Getting data from Huawei PV to VRM

My system:

Huawei 3KTL-M1 3 phase inverter with WIFI dongle

Victron Multiplus II on phase A

EM24 Smart Meter

My system works fine, battery is charging from production surplus (rare, because these days I have only 150-200W production), but I was missing solar data in vrm.

I now is only a cosmetic thing.

I was looking for this and I found 2 resources to inspire from:

HOUSEDOMOTICZ Youtube channel which shared his JSON files. I took a big chunk from here. Thank You Sir!

Schatten PV Youtube channel which gave me a basic notion about how things work. Thank You

Since I did not find an easy to use resource I will let this here, maybe will help.

Had to enable TCP modbus on Huawei.

Do not let your devices on DHCP. I had Huawei on DHCP and never bothered me until now :slight_smile:

Had to load node-red-contrib-modbus and node-red-contrib-modbus-tcp-ip palletes (I think only one is actually used, but if it works, why bother)

After import you have to modify ip address under the server setting on ModBus-Flex-Sequencer node.

I know there a lot of unused data, if that bothers you, delete the nodes.

[
    {
        "id": "d692c66251e2f6d7",
        "type": "tab",
        "label": "fotovoltaico",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "3fe9dcaa8874844f",
        "type": "inject",
        "z": "d692c66251e2f6d7",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "10",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 110,
        "y": 320,
        "wires": [
            [
                "a3946e97beb52c64"
            ]
        ]
    },
    {
        "id": "0a998d6eaf913c4a",
        "type": "function",
        "z": "d692c66251e2f6d7",
        "name": " AC Inverter Active Power",
        "func": "let rawData = new ArrayBuffer(4);\nlet intView = new Int16Array(rawData);\nlet fltView = new Int32Array(rawData);\n\nintView[0] = msg.payload[65]; //low\nintView[1] = msg.payload[64]; //high\n\nmsg.payload = parseFloat(fltView[0].toFixed(0));\nmsg.topic = \"Power\";\n\nnode.status({fill:\"blue\",shape:\"ring\",text:msg.topic + \":\" + msg.payload + \" W\"});    \n\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 670,
        "y": 400,
        "wires": [
            [
                "cf7b52018b6176e3"
            ]
        ]
    },
    {
        "id": "d585add44e8851ef",
        "type": "function",
        "z": "d692c66251e2f6d7",
        "name": "String 1 Voltage",
        "func": "let S1 = msg.payload[0]/10 \n\nmsg.topic = \"tensione\";\nmsg.payload = parseFloat((S1).toFixed(1));\nnode.status({fill:\"blue\",shape:\"ring\",text:msg.topic + \":\" + msg.payload + \" V\"});\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 640,
        "y": 100,
        "wires": [
            []
        ]
    },
    {
        "id": "b097e35699d5c0c4",
        "type": "function",
        "z": "d692c66251e2f6d7",
        "name": "String 1 Current ",
        "func": "let S1 = msg.payload[1]/100 \n\nmsg.topic = \"corrente\";\nmsg.payload = parseFloat((S1).toFixed(1));\nnode.status({fill:\"blue\",shape:\"ring\",text:msg.topic + \":\" + msg.payload + \" A\"});\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 640,
        "y": 160,
        "wires": [
            []
        ]
    },
    {
        "id": "c7668df6b50b6d95",
        "type": "function",
        "z": "d692c66251e2f6d7",
        "name": "Photovoltaic Power",
        "func": "let rawData = new ArrayBuffer(4);\nlet intView = new Int16Array(rawData);\nlet fltView = new Int32Array(rawData);\n\nintView[0] = msg.payload[49]; //low\nintView[1] = msg.payload[48]; //high\n\nmsg.payload = parseFloat(fltView[0].toFixed(0));\nmsg.topic = \"potenza\";\n\nnode.status({fill:\"blue\",shape:\"ring\",text:msg.topic + \":\" + msg.payload + \" W\"});    \n\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 650,
        "y": 220,
        "wires": [
            []
        ]
    },
    {
        "id": "7bf1d2b81d674de5",
        "type": "function",
        "z": "d692c66251e2f6d7",
        "name": " AC inverter Voltage",
        "func": "let S1 = msg.payload[50]/10 \n\nmsg.topic = \"Voltage\";\nmsg.payload = parseFloat((S1).toFixed(1));\nnode.status({fill:\"blue\",shape:\"ring\",text:msg.topic + \":\" + msg.payload + \" V\"});\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 650,
        "y": 280,
        "wires": [
            []
        ]
    },
    {
        "id": "a0cda5fbccbb0a4e",
        "type": "function",
        "z": "d692c66251e2f6d7",
        "name": " AC Inverter Reactive Power",
        "func": "let rawData = new ArrayBuffer(4);\nlet intView = new Int16Array(rawData);\nlet fltView = new Int32Array(rawData);\n\nintView[0] = msg.payload[67]; //low\nintView[1] = msg.payload[66]; //high\n\nmsg.payload = parseInt(fltView[0]);\nmsg.topic = \"potenza\";\n\nnode.status({fill:\"blue\",shape:\"ring\",text:msg.topic + \":\" + msg.payload + \" VAR\"});    \n\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 680,
        "y": 460,
        "wires": [
            []
        ]
    },
    {
        "id": "fbb25ea5b15740d4",
        "type": "function",
        "z": "d692c66251e2f6d7",
        "name": "Inverter cosfi",
        "func": "let S1 = msg.payload[68]/1000 \n\nmsg.topic = \"cosfi\";\nmsg.payload = parseFloat((S1).toFixed(2));\nnode.status({fill:\"blue\",shape:\"ring\",text:msg.topic + \":\" + msg.payload});\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 630,
        "y": 520,
        "wires": [
            []
        ]
    },
    {
        "id": "c5661fb640eeb543",
        "type": "function",
        "z": "d692c66251e2f6d7",
        "name": "Inverter frequency",
        "func": "let S1 = msg.payload[69]/100\n\nmsg.topic = \"frequenza\";\nmsg.payload = parseFloat((S1).toFixed(1));\nnode.status({fill:\"blue\",shape:\"ring\",text:msg.topic + \":\" + msg.payload + \" Hz\"});\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 650,
        "y": 580,
        "wires": [
            []
        ]
    },
    {
        "id": "c0bf0aa71990e706",
        "type": "function",
        "z": "d692c66251e2f6d7",
        "name": "Inverter temperature",
        "func": "let S1 = msg.payload[71]/10\n\nmsg.topic = \"temperatura\";\nmsg.payload = parseFloat((S1).toFixed(1));\nnode.status({fill:\"blue\",shape:\"ring\",text:msg.topic + \":\" + msg.payload + \" °C\"});\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 660,
        "y": 700,
        "wires": [
            []
        ]
    },
    {
        "id": "f5d4b0e91736fd46",
        "type": "function",
        "z": "d692c66251e2f6d7",
        "name": "AC inverter Current",
        "func": "let S1 = msg.payload[57]/1000 \n\nmsg.topic = \"Current\";\nmsg.payload = parseFloat((S1).toFixed(1));\nnode.status({fill:\"blue\",shape:\"ring\",text:msg.topic + \":\" + msg.payload + \" A\"});\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 650,
        "y": 340,
        "wires": [
            []
        ]
    },
    {
        "id": "2971dd2678ef3bcf",
        "type": "comment",
        "z": "d692c66251e2f6d7",
        "name": "INVERTER",
        "info": "",
        "x": 250,
        "y": 560,
        "wires": []
    },
    {
        "id": "f26e2ee653e94b5f",
        "type": "function",
        "z": "d692c66251e2f6d7",
        "name": "Inverter efficiency",
        "func": "let S1 = msg.payload[70]/100\n\nmsg.topic = \"efficienza\";\nmsg.payload = parseFloat((S1).toFixed(1));\nnode.status({fill:\"blue\",shape:\"ring\",text:msg.topic + \":\" + msg.payload + \" %\"});\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 650,
        "y": 640,
        "wires": [
            []
        ]
    },
    {
        "id": "a3946e97beb52c64",
        "type": "modbus-flex-sequencer",
        "z": "d692c66251e2f6d7",
        "name": "",
        "sequences": [
            {
                "name": "",
                "unitid": "1",
                "fc": "FC3",
                "address": "32016",
                "quantity": "100"
            }
        ],
        "server": "cabd9520437b6e88",
        "showStatusActivities": false,
        "showErrors": false,
        "showWarnings": true,
        "logIOActivities": false,
        "useIOFile": false,
        "ioFile": "",
        "useIOForPayload": false,
        "emptyMsgOnFail": false,
        "keepMsgProperties": false,
        "delayOnStart": false,
        "startDelayTime": "",
        "x": 240,
        "y": 620,
        "wires": [
            [
                "d585add44e8851ef",
                "b097e35699d5c0c4",
                "c7668df6b50b6d95",
                "0a998d6eaf913c4a",
                "7bf1d2b81d674de5",
                "a0cda5fbccbb0a4e",
                "fbb25ea5b15740d4",
                "c5661fb640eeb543",
                "c0bf0aa71990e706",
                "f5d4b0e91736fd46",
                "f26e2ee653e94b5f",
                "v_l1_extraction",
                "v_l2_extraction",
                "v_l3_extraction",
                "i_l1_fixed_v2",
                "i_l2_fixed_v2",
                "i_l3_fixed_v2",
                "p_l1_calc_node",
                "p_l2_calc_node",
                "p_l3_calc_node",
                "accumulated_yield_final_fixed"
            ],
            []
        ]
    },
    {
        "id": "a51fc1d02a3449c6",
        "type": "victron-virtual",
        "z": "d692c66251e2f6d7",
        "name": "SUN2000-3KTL-M1",
        "device": "pvinverter",
        "default_values": false,
        "battery_capacity": 25,
        "include_battery_temperature": false,
        "grid_nrofphases": 1,
        "include_motor_temp": false,
        "include_controller_temp": false,
        "include_coolant_temp": false,
        "include_motor_rpm": true,
        "include_motor_direction": true,
        "position": 0,
        "pvinverter_nrofphases": "3",
        "fluid_type": 0,
        "include_tank_battery": false,
        "include_tank_temperature": false,
        "tank_battery_voltage": 3.3,
        "tank_capacity": 0.2,
        "temperature_type": 2,
        "include_humidity": false,
        "include_pressure": false,
        "include_temp_battery": false,
        "temp_battery_voltage": 3.3,
        "x": 310,
        "y": 60,
        "wires": []
    },
    {
        "id": "cf7b52018b6176e3",
        "type": "victron-output-custom",
        "z": "d692c66251e2f6d7",
        "service": "com.victronenergy.pvinverter/100",
        "path": "/Ac/Power",
        "serviceObj": {
            "service": "com.victronenergy.pvinverter/100",
            "name": "SUN2000-3KTL-M1 (100)"
        },
        "pathObj": {
            "path": "/Ac/Power",
            "name": "/Ac/Power",
            "type": "object",
            "value": null
        },
        "name": "",
        "onlyChanges": false,
        "x": 950,
        "y": 400,
        "wires": []
    },
    {
        "id": "v_l1_extraction",
        "type": "function",
        "z": "d692c66251e2f6d7",
        "name": "L1 Voltage",
        "func": "let S1 = msg.payload[53] / 10; \nmsg.topic = \"L1_Voltage\";\nmsg.payload = parseFloat((S1).toFixed(1));\nnode.status({fill:\"blue\",shape:\"ring\",text:msg.topic + \":\" + msg.payload + \" V\"});    \nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 630,
        "y": 760,
        "wires": [
            [
                "412385a78bedbce6"
            ]
        ]
    },
    {
        "id": "v_l2_extraction",
        "type": "function",
        "z": "d692c66251e2f6d7",
        "name": "L2 Voltage",
        "func": "let S1 = msg.payload[54] / 10; \nmsg.topic = \"L2_Voltage\";\nmsg.payload = parseFloat((S1).toFixed(1));\nnode.status({fill:\"blue\",shape:\"ring\",text:msg.topic + \":\" + msg.payload + \" V\"});    \nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 630,
        "y": 820,
        "wires": [
            [
                "c3309162e70a9478"
            ]
        ]
    },
    {
        "id": "v_l3_extraction",
        "type": "function",
        "z": "d692c66251e2f6d7",
        "name": "L3 Voltage",
        "func": "let S1 = msg.payload[55] / 10; \nmsg.topic = \"L3_Voltage\";\nmsg.payload = parseFloat((S1).toFixed(1));\nnode.status({fill:\"blue\",shape:\"ring\",text:msg.topic + \":\" + msg.payload + \" V\"});    \nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 630,
        "y": 880,
        "wires": [
            [
                "09914adae4eeeb30"
            ]
        ]
    },
    {
        "id": "412385a78bedbce6",
        "type": "victron-output-custom",
        "z": "d692c66251e2f6d7",
        "service": "com.victronenergy.pvinverter/100",
        "path": "/Ac/L1/Voltage",
        "serviceObj": {
            "service": "com.victronenergy.pvinverter/100",
            "name": "SUN2000-3KTL-M1 (100)"
        },
        "pathObj": {
            "path": "/Ac/L1/Voltage",
            "name": "/Ac/L1/Voltage",
            "type": "number",
            "value": 0
        },
        "name": "",
        "onlyChanges": false,
        "x": 900,
        "y": 760,
        "wires": []
    },
    {
        "id": "c3309162e70a9478",
        "type": "victron-output-custom",
        "z": "d692c66251e2f6d7",
        "service": "com.victronenergy.pvinverter/100",
        "path": "/Ac/L2/Voltage",
        "serviceObj": {
            "service": "com.victronenergy.pvinverter/100",
            "name": "SUN2000-3KTL-M1 (100)"
        },
        "pathObj": {
            "path": "/Ac/L2/Voltage",
            "name": "/Ac/L2/Voltage",
            "type": "number",
            "value": 0
        },
        "name": "",
        "onlyChanges": false,
        "x": 900,
        "y": 820,
        "wires": []
    },
    {
        "id": "09914adae4eeeb30",
        "type": "victron-output-custom",
        "z": "d692c66251e2f6d7",
        "service": "com.victronenergy.pvinverter/100",
        "path": "/Ac/L3/Voltage",
        "serviceObj": {
            "service": "com.victronenergy.pvinverter/100",
            "name": "SUN2000-3KTL-M1 (100)"
        },
        "pathObj": {
            "path": "/Ac/L3/Voltage",
            "name": "/Ac/L3/Voltage",
            "type": "number",
            "value": 0
        },
        "name": "",
        "onlyChanges": false,
        "x": 900,
        "y": 880,
        "wires": []
    },
    {
        "id": "i_l1_fixed_v2",
        "type": "function",
        "z": "d692c66251e2f6d7",
        "name": "L1 Current",
        "func": "let buffer = new ArrayBuffer(4);\nlet view = new DataView(buffer);\n// Index 56 = High, Index 57 = Low\nview.setUint16(0, msg.payload[56], false);\nview.setUint16(2, msg.payload[57], false);\nlet rawVal = view.getInt32(0, false);\nmsg.payload = parseFloat((rawVal / 1000).toFixed(3));\nmsg.topic = \"L1_Current\";\nnode.status({fill:\"blue\",shape:\"ring\",text:msg.payload + \" A\"});\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 630,
        "y": 960,
        "wires": [
            [
                "21508df743b01882"
            ]
        ]
    },
    {
        "id": "i_l2_fixed_v2",
        "type": "function",
        "z": "d692c66251e2f6d7",
        "name": "L2 Current",
        "func": "let buffer = new ArrayBuffer(4);\nlet view = new DataView(buffer);\n// Index 58 = High, Index 59 = Low\nview.setUint16(0, msg.payload[58], false);\nview.setUint16(2, msg.payload[59], false);\nlet rawVal = view.getInt32(0, false);\nmsg.payload = parseFloat((rawVal / 1000).toFixed(3));\nmsg.topic = \"L2_Current\";\nnode.status({fill:\"blue\",shape:\"ring\",text:msg.payload + \" A\"});\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 630,
        "y": 1020,
        "wires": [
            [
                "d2f7cb78f0419653"
            ]
        ]
    },
    {
        "id": "i_l3_fixed_v2",
        "type": "function",
        "z": "d692c66251e2f6d7",
        "name": "L3 Current",
        "func": "let buffer = new ArrayBuffer(4);\nlet view = new DataView(buffer);\n// Index 60 = High, Index 61 = Low\nview.setUint16(0, msg.payload[60], false);\nview.setUint16(2, msg.payload[61], false);\nlet rawVal = view.getInt32(0, false);\nmsg.payload = parseFloat((rawVal / 1000).toFixed(3));\nmsg.topic = \"L3_Current\";\nnode.status({fill:\"blue\",shape:\"ring\",text:msg.payload + \" A\"});\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 630,
        "y": 1080,
        "wires": [
            [
                "2f7ed667e4549be6"
            ]
        ]
    },
    {
        "id": "p_l1_calc_node",
        "type": "function",
        "z": "d692c66251e2f6d7",
        "name": "L1 Power",
        "func": "let buf = new ArrayBuffer(4);\nlet view = new DataView(buf);\n\n// Extraction\nlet vol = msg.payload[53] / 10;\nview.setUint16(0, msg.payload[56], false);\nview.setUint16(2, msg.payload[57], false);\nlet amp = view.getInt32(0, false) / 1000;\nlet cos = msg.payload[68] / 1000;\n\n// Calculation\nmsg.payload = Math.round(vol * amp * cos);\nmsg.topic = \"L1_Power\";\nnode.status({fill:\"blue\",shape:\"ring\",text:msg.payload + \" W\"});\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 620,
        "y": 1160,
        "wires": [
            [
                "8c52687acb1e74b6"
            ]
        ]
    },
    {
        "id": "p_l2_calc_node",
        "type": "function",
        "z": "d692c66251e2f6d7",
        "name": "L2 Power",
        "func": "let buf = new ArrayBuffer(4);\nlet view = new DataView(buf);\n\n// Extraction\nlet vol = msg.payload[54] / 10;\nview.setUint16(0, msg.payload[58], false);\nview.setUint16(2, msg.payload[59], false);\nlet amp = view.getInt32(0, false) / 1000;\nlet cos = msg.payload[68] / 1000;\n\n// Calculation\nmsg.payload = Math.round(vol * amp * cos);\nmsg.topic = \"L2_Power\";\nnode.status({fill:\"blue\",shape:\"ring\",text:msg.payload + \" W\"});\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 620,
        "y": 1220,
        "wires": [
            [
                "42213deb5bd76e5c"
            ]
        ]
    },
    {
        "id": "p_l3_calc_node",
        "type": "function",
        "z": "d692c66251e2f6d7",
        "name": "L3 Power",
        "func": "let buf = new ArrayBuffer(4);\nlet view = new DataView(buf);\n\n// Extraction\nlet vol = msg.payload[55] / 10;\nview.setUint16(0, msg.payload[60], false);\nview.setUint16(2, msg.payload[61], false);\nlet amp = view.getInt32(0, false) / 1000;\nlet cos = msg.payload[68] / 1000;\n\n// Calculation\nmsg.payload = Math.round(vol * amp * cos);\nmsg.topic = \"L3_Power\";\nnode.status({fill:\"blue\",shape:\"ring\",text:msg.payload + \" W\"});\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 620,
        "y": 1280,
        "wires": [
            [
                "2156f33ef7097625"
            ]
        ]
    },
    {
        "id": "21508df743b01882",
        "type": "victron-output-custom",
        "z": "d692c66251e2f6d7",
        "service": "com.victronenergy.pvinverter/100",
        "path": "/Ac/L1/Current",
        "serviceObj": {
            "service": "com.victronenergy.pvinverter/100",
            "name": "SUN2000-3KTL-M1 (100)"
        },
        "pathObj": {
            "path": "/Ac/L1/Current",
            "name": "/Ac/L1/Current",
            "type": "number",
            "value": 0
        },
        "name": "",
        "onlyChanges": false,
        "x": 900,
        "y": 960,
        "wires": []
    },
    {
        "id": "d2f7cb78f0419653",
        "type": "victron-output-custom",
        "z": "d692c66251e2f6d7",
        "service": "com.victronenergy.pvinverter/100",
        "path": "/Ac/L2/Current",
        "serviceObj": {
            "service": "com.victronenergy.pvinverter/100",
            "name": "SUN2000-3KTL-M1 (100)"
        },
        "pathObj": {
            "path": "/Ac/L2/Current",
            "name": "/Ac/L2/Current",
            "type": "number",
            "value": 0
        },
        "name": "",
        "onlyChanges": false,
        "x": 900,
        "y": 1020,
        "wires": []
    },
    {
        "id": "2f7ed667e4549be6",
        "type": "victron-output-custom",
        "z": "d692c66251e2f6d7",
        "service": "com.victronenergy.pvinverter/100",
        "path": "/Ac/L3/Current",
        "serviceObj": {
            "service": "com.victronenergy.pvinverter/100",
            "name": "SUN2000-3KTL-M1 (100)"
        },
        "pathObj": {
            "path": "/Ac/L3/Current",
            "name": "/Ac/L3/Current",
            "type": "number",
            "value": 0
        },
        "name": "",
        "onlyChanges": false,
        "x": 900,
        "y": 1080,
        "wires": []
    },
    {
        "id": "8c52687acb1e74b6",
        "type": "victron-output-custom",
        "z": "d692c66251e2f6d7",
        "service": "com.victronenergy.pvinverter/100",
        "path": "/Ac/L1/Power",
        "serviceObj": {
            "service": "com.victronenergy.pvinverter/100",
            "name": "SUN2000-3KTL-M1 (100)"
        },
        "pathObj": {
            "path": "/Ac/L1/Power",
            "name": "/Ac/L1/Power",
            "type": "number",
            "value": 0
        },
        "name": "",
        "onlyChanges": false,
        "x": 900,
        "y": 1160,
        "wires": []
    },
    {
        "id": "42213deb5bd76e5c",
        "type": "victron-output-custom",
        "z": "d692c66251e2f6d7",
        "service": "com.victronenergy.pvinverter/100",
        "path": "/Ac/L2/Power",
        "serviceObj": {
            "service": "com.victronenergy.pvinverter/100",
            "name": "SUN2000-3KTL-M1 (100)"
        },
        "pathObj": {
            "path": "/Ac/L2/Power",
            "name": "/Ac/L2/Power",
            "type": "number",
            "value": 0
        },
        "name": "",
        "onlyChanges": false,
        "x": 900,
        "y": 1220,
        "wires": []
    },
    {
        "id": "2156f33ef7097625",
        "type": "victron-output-custom",
        "z": "d692c66251e2f6d7",
        "service": "com.victronenergy.pvinverter/100",
        "path": "/Ac/L3/Power",
        "serviceObj": {
            "service": "com.victronenergy.pvinverter/100",
            "name": "SUN2000-3KTL-M1 (100)"
        },
        "pathObj": {
            "path": "/Ac/L3/Power",
            "name": "/Ac/L3/Power",
            "type": "number",
            "value": 0
        },
        "name": "",
        "onlyChanges": false,
        "x": 900,
        "y": 1280,
        "wires": []
    },
    {
        "id": "accumulated_yield_final_fixed",
        "type": "function",
        "z": "d692c66251e2f6d7",
        "name": "Accumulated Yield (kWh)",
        "func": "if (!Array.isArray(msg.payload)) {\n    node.status({fill:\"red\", shape:\"ring\", text: \"Input not an array\"});\n    return null;\n}\n\n// Based on debug: Index 90 = 12 (High), Index 91 = 58513 (Low)\nlet high = msg.payload[90];\nlet low = msg.payload[91];\n\nif (high === undefined || low === undefined) {\n    node.status({fill:\"red\", shape:\"dot\", text: \"Indices 90/91 missing\"});\n    return null;\n}\n\n// Reconstruct 32-bit unsigned integer\n// Shift high word 16 bits left and combine with low word\nlet rawVal = ((high << 16) >>> 0) + (low >>> 0);\n\n// Huawei Scaling: 0.01 kWh\nmsg.payload = parseFloat((rawVal / 100).toFixed(2));\nmsg.topic = \"Accumulated_Yield\";\n\nnode.status({fill:\"blue\", shape:\"ring\", text: msg.payload + \" kWh\"});\n\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 590,
        "y": 1340,
        "wires": [
            [
                "5011fcd17c5beab6"
            ]
        ]
    },
    {
        "id": "5011fcd17c5beab6",
        "type": "victron-output-custom",
        "z": "d692c66251e2f6d7",
        "service": "com.victronenergy.pvinverter/100",
        "path": "/Ac/Energy/Forward",
        "serviceObj": {
            "service": "com.victronenergy.pvinverter/100",
            "name": "SUN2000-3KTL-M1 (100)"
        },
        "pathObj": {
            "path": "/Ac/Energy/Forward",
            "name": "/Ac/Energy/Forward",
            "type": "number",
            "value": 8449.45
        },
        "name": "",
        "onlyChanges": false,
        "x": 920,
        "y": 1340,
        "wires": []
    },
    {
        "id": "cabd9520437b6e88",
        "type": "modbus-client",
        "name": "HUAWEI SUN2000",
        "clienttype": "tcp",
        "bufferCommands": true,
        "stateLogEnabled": false,
        "queueLogEnabled": false,
        "failureLogEnabled": true,
        "tcpHost": "192.168.2.16",
        "tcpPort": "502",
        "tcpType": "DEFAULT",
        "serialPort": "/dev/ttyUSB",
        "serialType": "RTU-BUFFERD",
        "serialBaudrate": "9600",
        "serialDatabits": "8",
        "serialStopbits": "1",
        "serialParity": "none",
        "serialConnectionDelay": "100",
        "serialAsciiResponseStartDelimiter": "0x3A",
        "unit_id": 1,
        "commandDelay": 1,
        "clientTimeout": 3000,
        "reconnectOnTimeout": true,
        "reconnectTimeout": 5000,
        "parallelUnitIdsAllowed": true,
        "showErrors": false,
        "showWarnings": true,
        "showLogs": true
    }
]