Skip to content

Instantly share code, notes, and snippets.

@nalditopr
Last active April 12, 2025 04:42
Show Gist options
  • Save nalditopr/493af377e9928b88c2639a9e1607f127 to your computer and use it in GitHub Desktop.
Save nalditopr/493af377e9928b88c2639a9e1607f127 to your computer and use it in GitHub Desktop.
Eco Flow Delta 3 + Node-Red + Homeassistant
[
{
"id": "5c3a7efbb734c312",
"type": "tab",
"label": "Ecoflow MQTT",
"disabled": false,
"info": "",
"env": []
},
{
"id": "773fab09ddaa9e53",
"type": "inject",
"z": "5c3a7efbb734c312",
"name": "connect",
"props": [
{
"p": "action",
"v": "connect",
"vt": "str"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"x": 350,
"y": 520,
"wires": [
[
"d5d7e8960ba14429"
]
]
},
{
"id": "d5d7e8960ba14429",
"type": "mqtt out",
"z": "5c3a7efbb734c312",
"name": "ef-mqtt",
"topic": "",
"qos": "",
"retain": "",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "4a025f91e9595714",
"x": 540,
"y": 540,
"wires": []
},
{
"id": "6d38c1d92d6c19eb",
"type": "mqtt in",
"z": "5c3a7efbb734c312",
"name": "",
"topic": "/app/[[APPID]]/[[SN]]/thing/property/get",
"qos": "2",
"datatype": "base64",
"broker": "4a025f91e9595714",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 970,
"y": 340,
"wires": [
[
"0cf29e3992e7bfdc"
]
]
},
{
"id": "c8d401ac3c0d530b",
"type": "debug",
"z": "5c3a7efbb734c312",
"name": "debug 2",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 1180,
"y": 220,
"wires": []
},
{
"id": "0cf29e3992e7bfdc",
"type": "debug",
"z": "5c3a7efbb734c312",
"name": "debug 3",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 1420,
"y": 340,
"wires": []
},
{
"id": "d9ecc011d0be04ea",
"type": "mqtt in",
"z": "5c3a7efbb734c312",
"name": "",
"topic": "/app/[[APPID]]/[[SN]]/thing/property/get_reply",
"qos": "2",
"datatype": "base64",
"broker": "4a025f91e9595714",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 990,
"y": 460,
"wires": [
[
"5dc759c3914d8893"
]
]
},
{
"id": "34495fd19ce3c931",
"type": "mqtt in",
"z": "5c3a7efbb734c312",
"name": "",
"topic": "/app/[[APPID]]/[[SN]]/thing/property/set",
"qos": "2",
"datatype": "base64",
"broker": "4a025f91e9595714",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 970,
"y": 580,
"wires": [
[
"1b07cbc9319439e6"
]
]
},
{
"id": "196e8e1147aa9c70",
"type": "mqtt in",
"z": "5c3a7efbb734c312",
"name": "",
"topic": "/app/[[APPID]]/[[SN]]/thing/property/set_reply",
"qos": "2",
"datatype": "base64",
"broker": "4a025f91e9595714",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 980,
"y": 700,
"wires": [
[
"222174cf92b067ba"
]
]
},
{
"id": "5dc759c3914d8893",
"type": "debug",
"z": "5c3a7efbb734c312",
"name": "debug 4",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 1420,
"y": 460,
"wires": []
},
{
"id": "1b07cbc9319439e6",
"type": "debug",
"z": "5c3a7efbb734c312",
"name": "debug 5",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 1420,
"y": 580,
"wires": []
},
{
"id": "222174cf92b067ba",
"type": "debug",
"z": "5c3a7efbb734c312",
"name": "debug 6",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 1420,
"y": 700,
"wires": []
},
{
"id": "2ea889238290350b",
"type": "mqtt out",
"z": "5c3a7efbb734c312",
"name": "",
"topic": "/app/[[APPID]]/[[SN]]/thing/property/set",
"qos": "0",
"retain": "",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "4a025f91e9595714",
"x": 990,
"y": 980,
"wires": []
},
{
"id": "3507d66f640759d3",
"type": "inject",
"z": "5c3a7efbb734c312",
"name": "beep_on",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_9\":1},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":2,\"int_11\":1,\"int_14\":128301330,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"payloadType": "json",
"x": 340,
"y": 1080,
"wires": [
[
"1879d2c74d981f0a"
]
]
},
{
"id": "2126c09b8693f86a",
"type": "mqtt in",
"z": "5c3a7efbb734c312",
"name": "",
"topic": "/app/[[APPID]]/[[SN]]/thing/property/set",
"qos": "2",
"datatype": "auto-detect",
"broker": "4a025f91e9595714",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 990,
"y": 640,
"wires": [
[
"1b07cbc9319439e6"
]
]
},
{
"id": "1771f8034a515b9c",
"type": "mqtt in",
"z": "5c3a7efbb734c312",
"name": "",
"topic": "/app/[[APPID]]/[[SN]]/thing/property/get",
"qos": "2",
"datatype": "auto-detect",
"broker": "4a025f91e9595714",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 990,
"y": 400,
"wires": [
[
"0cf29e3992e7bfdc"
]
]
},
{
"id": "6bd61b7f744cd6dd",
"type": "mqtt in",
"z": "5c3a7efbb734c312",
"name": "",
"topic": "/app/[[APPID]]/[[SN]]/thing/property/get_reply",
"qos": "2",
"datatype": "auto-detect",
"broker": "4a025f91e9595714",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 1010,
"y": 520,
"wires": [
[
"5dc759c3914d8893",
"15622328ecef2318"
]
]
},
{
"id": "2aa01b5bcbc04c2d",
"type": "mqtt in",
"z": "5c3a7efbb734c312",
"name": "",
"topic": "/app/[[APPID]]/[[SN]]/thing/property/set_reply",
"qos": "2",
"datatype": "auto-detect",
"broker": "4a025f91e9595714",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 1000,
"y": 760,
"wires": [
[
"222174cf92b067ba"
]
]
},
{
"id": "af84a2f4c0da27f2",
"type": "mqtt in",
"z": "5c3a7efbb734c312",
"name": "",
"topic": "/app/device/status/[[SN]]",
"qos": "2",
"datatype": "auto-detect",
"broker": "4a025f91e9595714",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 900,
"y": 280,
"wires": [
[
"c8d401ac3c0d530b"
]
]
},
{
"id": "1879d2c74d981f0a",
"type": "encode",
"z": "5c3a7efbb734c312",
"name": "",
"protofile": "fd04eecb52341faa",
"protoType": "MessageFromJson",
"x": 620,
"y": 980,
"wires": [
[
"2ea889238290350b"
]
]
},
{
"id": "c41e867bd65c48cc",
"type": "inject",
"z": "5c3a7efbb734c312",
"name": "beep_off",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_9\":0},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":2,\"int_11\":1,\"int_14\":128301330,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"payloadType": "json",
"x": 340,
"y": 1200,
"wires": [
[
"1879d2c74d981f0a"
]
]
},
{
"id": "4ec8c1c4e51da6e7",
"type": "inject",
"z": "5c3a7efbb734c312",
"name": "get",
"props": [
{
"p": "payload"
}
],
"repeat": "15",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_14\":128301330,\"bytes_23\":\"Android\"}}}",
"payloadType": "json",
"x": 350,
"y": 660,
"wires": [
[
"d0662aaa5ced35c4"
]
]
},
{
"id": "1050b450dc646a9f",
"type": "mqtt out",
"z": "5c3a7efbb734c312",
"name": "",
"topic": "/app/[[APPID]]/[[SN]]/thing/property/get",
"qos": "2",
"retain": "",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "4a025f91e9595714",
"x": 990,
"y": 860,
"wires": []
},
{
"id": "d0662aaa5ced35c4",
"type": "encode",
"z": "5c3a7efbb734c312",
"name": "",
"protofile": "fd04eecb52341faa",
"protoType": "MessageFromJson",
"x": 620,
"y": 860,
"wires": [
[
"1050b450dc646a9f"
]
]
},
{
"id": "1981b4272caec0f1",
"type": "debug",
"z": "5c3a7efbb734c312",
"name": "debug 7",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 2240,
"y": 520,
"wires": []
},
{
"id": "668e876f10fa3918",
"type": "inject",
"z": "5c3a7efbb734c312",
"name": "charge_15",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_102\":15},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":3,\"int_11\":1,\"int_14\":148771586,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"payloadType": "json",
"x": 340,
"y": 1000,
"wires": [
[
"1879d2c74d981f0a"
]
]
},
{
"id": "fab3e8f819aca276",
"type": "inject",
"z": "5c3a7efbb734c312",
"name": "charge_90",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_102\":90},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":3,\"int_11\":1,\"int_14\":148771586,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"payloadType": "json",
"x": 340,
"y": 920,
"wires": [
[
"1879d2c74d981f0a"
]
]
},
{
"id": "15622328ecef2318",
"type": "decode",
"z": "5c3a7efbb734c312",
"name": "",
"protofile": "09526bce7b477f38",
"protoType": "MessageFromJson",
"x": 1560,
"y": 520,
"wires": [
[
"86e09c3f6d07938c"
]
]
},
{
"id": "86e09c3f6d07938c",
"type": "function",
"z": "5c3a7efbb734c312",
"name": "parser",
"func": "// Array of variables to convert (define the path to each variable as a string, excluding the array index)\nlet variablesToConvert = [\n \"NestedsubMesssage_1.batteryLevel\",\n \"NestedsubMesssage_1.acPower\",\n \"NestedsubMesssage_1.acOut\"\n];\n\n// Helper function to access and modify nested properties\nfunction convertFixed32ToFloat(obj, path) {\n let keys = path.split(\".\");\n let lastKey = keys.pop();\n let target = keys.reduce((o, k) => (o && o[k] ? o[k] : undefined), obj);\n\n if (target && target[lastKey] !== undefined) {\n let fixed32Value = target[lastKey];\n let buffer = Buffer.alloc(4);\n buffer.writeUInt32LE(fixed32Value); // Write as little-endian\n let dataView = new DataView(buffer.buffer);\n let floatValue = dataView.getFloat32(0, true); // Convert to float (little-endian)\n target[lastKey] = Math.round(floatValue * 100) / 100; // Round to 2 decimals\n }\n}\n\n// Validate that the array exists\nif (\n msg.payload.subMesssage_1 &&\n Array.isArray(msg.payload.subMesssage_1)\n) {\n // Automatically find the element with the largest NestedsubMesssage_1 (by number of keys)\n let selectedElement = msg.payload.subMesssage_1.reduce((largest, current) => {\n const currentSize = current?.NestedsubMesssage_1 ? Object.keys(current.NestedsubMesssage_1).length : 0;\n const largestSize = largest?.NestedsubMesssage_1 ? Object.keys(largest.NestedsubMesssage_1).length : 0;\n return currentSize > largestSize ? current : largest;\n }, null);\n\n if (selectedElement) {\n // Loop through the variables and convert them for the selected element\n variablesToConvert.forEach(path => {\n convertFixed32ToFloat(selectedElement, path);\n });\n\n // Flatten the selected element for output\n msg.payload = {\n ...selectedElement.NestedsubMesssage_1\n };\n } else {\n msg.payload = { error: \"No valid element found in subMesssage_1.\" };\n }\n} else {\n // Handle the case where the array is invalid\n msg.payload = {\n error: \"subMesssage_1 is not a valid array.\"\n };\n}\n\n// Return the flattened object as the payload\nreturn msg;\n",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1710,
"y": 520,
"wires": [
[
"1981b4272caec0f1",
"16d905301a29dbdf",
"4df43232664f45b5",
"2177e930db19a389",
"5adb6177ab992ca0"
]
]
},
{
"id": "ab9e1d2599c501f9",
"type": "inject",
"z": "5c3a7efbb734c312",
"name": "self-powered off",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"selfpowered_106\":{}},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":3,\"int_11\":1,\"int_14\":148771586,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"payloadType": "json",
"x": 320,
"y": 860,
"wires": [
[
"1879d2c74d981f0a"
]
]
},
{
"id": "2b4391ab6cfa2082",
"type": "inject",
"z": "5c3a7efbb734c312",
"name": "self-powered on",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_26\":0,\"selfpowered_106\":{\"int_1\":1},\"int_138\":0},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":11,\"int_11\":1,\"int_14\":357051739,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"payloadType": "json",
"x": 320,
"y": 740,
"wires": [
[
"1879d2c74d981f0a"
]
]
},
{
"id": "16d905301a29dbdf",
"type": "ha-sensor",
"z": "5c3a7efbb734c312",
"name": "device_a_Battery Level",
"entityConfig": "49b4f2bfd1956a24",
"version": 0,
"state": "payload.batteryLevel",
"stateType": "msg",
"attributes": [],
"inputOverride": "allow",
"outputProperties": [],
"x": 1950,
"y": 700,
"wires": [
[
"1981b4272caec0f1"
]
]
},
{
"id": "4df43232664f45b5",
"type": "ha-sensor",
"z": "5c3a7efbb734c312",
"name": "device_a_Charge Target",
"entityConfig": "87a97985e13b1458",
"version": 0,
"state": "payload.target",
"stateType": "msg",
"attributes": [],
"inputOverride": "allow",
"outputProperties": [],
"x": 1960,
"y": 760,
"wires": [
[
"1981b4272caec0f1"
]
]
},
{
"id": "dfcac4c65259021a",
"type": "ha-switch",
"z": "5c3a7efbb734c312",
"name": "device_a_self-powered",
"version": 0,
"debugenabled": false,
"inputs": 0,
"outputs": 2,
"entityConfig": "20ef2d5be7415ccd",
"enableInput": false,
"outputOnStateChange": true,
"outputProperties": [
{
"property": "payload",
"propertyType": "msg",
"value": "",
"valueType": "str"
}
],
"x": 90,
"y": 800,
"wires": [
[
"14cf1dbdc9323cf5"
],
[
"168a92bf365a0769"
]
]
},
{
"id": "14cf1dbdc9323cf5",
"type": "change",
"z": "5c3a7efbb734c312",
"name": "self-powered on",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_26\":0,\"selfpowered_106\":{\"int_1\":1},\"int_138\":0},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":11,\"int_11\":1,\"int_14\":357051739,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"tot": "json"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 320,
"y": 780,
"wires": [
[
"1879d2c74d981f0a"
]
]
},
{
"id": "168a92bf365a0769",
"type": "change",
"z": "5c3a7efbb734c312",
"name": "self-powered off",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"selfpowered_106\":{}},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":3,\"int_11\":1,\"int_14\":148771586,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"tot": "json"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 320,
"y": 820,
"wires": [
[
"1879d2c74d981f0a"
]
]
},
{
"id": "2177e930db19a389",
"type": "ha-sensor",
"z": "5c3a7efbb734c312",
"name": "device_a_AC Power",
"entityConfig": "6670dfa7e6a8c02e",
"version": 0,
"state": "payload.acPower",
"stateType": "msg",
"attributes": [],
"inputOverride": "allow",
"outputProperties": [],
"x": 1940,
"y": 640,
"wires": [
[
"1981b4272caec0f1"
]
]
},
{
"id": "18c73ca84e0549a8",
"type": "ha-number",
"z": "5c3a7efbb734c312",
"name": "device_a_charge-target",
"version": 1,
"debugenabled": false,
"inputs": 0,
"outputs": 1,
"entityConfig": "a0136659e84650bb",
"exposeAsEntityConfig": "",
"mode": "listen",
"value": "payload",
"valueType": "msg",
"outputProperties": [
{
"property": "payload",
"propertyType": "msg",
"value": "",
"valueType": "value"
},
{
"property": "previousValue",
"propertyType": "msg",
"value": "",
"valueType": "previousValue"
}
],
"x": 90,
"y": 960,
"wires": [
[
"06a42ae752c09211"
]
]
},
{
"id": "06a42ae752c09211",
"type": "function",
"z": "5c3a7efbb734c312",
"name": "charge-target",
"func": "// Get the input number from the msg payload\nlet inputNumber = msg.payload;\n\n// Validate the input number and clamp it between 15 and 90\nif (inputNumber < 15) {\n inputNumber = 15;\n} else if (inputNumber > 90) {\n inputNumber = 90;\n}\n\n// Define the JSON structure\nconst jsonResponse = {\n \"subMesssage_1\": {\n \"NestedsubMesssage_1\": {\n \"int_102\": inputNumber // Use the validated input number here\n },\n \"int_2\": 32,\n \"int_3\": 2,\n \"int_4\": 1,\n \"int_5\": 1,\n \"int_8\": 254,\n \"int_9\": 17,\n \"int_10\": 3,\n \"int_11\": 1,\n \"int_14\": 148771586,\n \"int_15\": 1,\n \"int_16\": 19,\n \"int_17\": 1\n }\n};\n\n// Assign the JSON to msg.payload\nmsg.payload = jsonResponse;\n\n// Return the modified msg object\nreturn msg;\n",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 330,
"y": 960,
"wires": [
[
"1879d2c74d981f0a"
]
]
},
{
"id": "20d9b6e2c35b70fc",
"type": "ha-switch",
"z": "5c3a7efbb734c312",
"name": "device_a_beep",
"version": 0,
"debugenabled": false,
"inputs": 0,
"outputs": 2,
"entityConfig": "43ab0950c992e96d",
"enableInput": false,
"outputOnStateChange": true,
"outputProperties": [
{
"property": "payload",
"propertyType": "msg",
"value": "",
"valueType": "str"
}
],
"x": 120,
"y": 1140,
"wires": [
[
"8d0c4baed56b9bfe"
],
[
"f591f651b4d2153a"
]
]
},
{
"id": "8d0c4baed56b9bfe",
"type": "change",
"z": "5c3a7efbb734c312",
"name": "beep-on",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_9\":1},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":2,\"int_11\":1,\"int_14\":128301330,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"tot": "json"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 340,
"y": 1120,
"wires": [
[
"1879d2c74d981f0a"
]
]
},
{
"id": "f591f651b4d2153a",
"type": "change",
"z": "5c3a7efbb734c312",
"name": "beep-off",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_9\":0},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":2,\"int_11\":1,\"int_14\":128301330,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"tot": "json"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 340,
"y": 1160,
"wires": [
[
"1879d2c74d981f0a"
]
]
},
{
"id": "5adb6177ab992ca0",
"type": "ha-sensor",
"z": "5c3a7efbb734c312",
"name": "device_a_AC Out",
"entityConfig": "9531e396809c4293",
"version": 0,
"state": "payload.acOut",
"stateType": "msg",
"attributes": [],
"inputOverride": "allow",
"outputProperties": [],
"x": 1930,
"y": 580,
"wires": [
[
"1981b4272caec0f1"
]
]
},
{
"id": "61291127c9a9b736",
"type": "debug",
"z": "5c3a7efbb734c312",
"name": "debug 10",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 1420,
"y": 1440,
"wires": []
},
{
"id": "78bcd84f0434c885",
"type": "mqtt out",
"z": "5c3a7efbb734c312",
"name": "",
"topic": "/app/[[APPID]]/[[SN]]/thing/property/set",
"qos": "0",
"retain": "",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "4a025f91e9595714",
"x": 990,
"y": 1960,
"wires": []
},
{
"id": "cbc2dd792fc76a03",
"type": "inject",
"z": "5c3a7efbb734c312",
"name": "beep_on",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_9\":1},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":2,\"int_11\":1,\"int_14\":128301330,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"payloadType": "json",
"x": 340,
"y": 2060,
"wires": [
[
"4afdedfb126c3adb"
]
]
},
{
"id": "79a047ea301467c3",
"type": "mqtt in",
"z": "5c3a7efbb734c312",
"name": "",
"topic": "/app/[[APPID]]/[[SN]]/thing/property/get_reply",
"qos": "2",
"datatype": "auto-detect",
"broker": "4a025f91e9595714",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 1010,
"y": 1500,
"wires": [
[
"61291127c9a9b736",
"a3ddcd10a21dabe5"
]
]
},
{
"id": "4afdedfb126c3adb",
"type": "encode",
"z": "5c3a7efbb734c312",
"name": "",
"protofile": "fd04eecb52341faa",
"protoType": "MessageFromJson",
"x": 620,
"y": 1960,
"wires": [
[
"78bcd84f0434c885"
]
]
},
{
"id": "d2c67cfa36b8eddd",
"type": "inject",
"z": "5c3a7efbb734c312",
"name": "beep_off",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_9\":0},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":2,\"int_11\":1,\"int_14\":128301330,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"payloadType": "json",
"x": 340,
"y": 2180,
"wires": [
[
"4afdedfb126c3adb"
]
]
},
{
"id": "4c886e6bc42a159d",
"type": "inject",
"z": "5c3a7efbb734c312",
"name": "get",
"props": [
{
"p": "payload"
}
],
"repeat": "15",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_14\":128301340,\"bytes_23\":\"Android\"}}}",
"payloadType": "json",
"x": 350,
"y": 1640,
"wires": [
[
"a866568cee5cc41b"
]
]
},
{
"id": "53e91d153c751f3b",
"type": "mqtt out",
"z": "5c3a7efbb734c312",
"name": "",
"topic": "/app/[[APPID]]/[[SN]]/thing/property/get",
"qos": "2",
"retain": "",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "4a025f91e9595714",
"x": 990,
"y": 1840,
"wires": []
},
{
"id": "a866568cee5cc41b",
"type": "encode",
"z": "5c3a7efbb734c312",
"name": "",
"protofile": "fd04eecb52341faa",
"protoType": "MessageFromJson",
"x": 620,
"y": 1840,
"wires": [
[
"53e91d153c751f3b"
]
]
},
{
"id": "14915a090ac399a6",
"type": "debug",
"z": "5c3a7efbb734c312",
"name": "debug 13",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 2240,
"y": 1500,
"wires": []
},
{
"id": "3117402a17b4b898",
"type": "inject",
"z": "5c3a7efbb734c312",
"name": "charge_15",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_102\":15},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":3,\"int_11\":1,\"int_14\":148771586,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"payloadType": "json",
"x": 340,
"y": 1980,
"wires": [
[
"4afdedfb126c3adb"
]
]
},
{
"id": "78ab8f746a16080b",
"type": "inject",
"z": "5c3a7efbb734c312",
"name": "charge_90",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_102\":90},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":3,\"int_11\":1,\"int_14\":148771586,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"payloadType": "json",
"x": 340,
"y": 1900,
"wires": [
[
"4afdedfb126c3adb"
]
]
},
{
"id": "a3ddcd10a21dabe5",
"type": "decode",
"z": "5c3a7efbb734c312",
"name": "",
"protofile": "09526bce7b477f38",
"protoType": "MessageFromJson",
"x": 1560,
"y": 1500,
"wires": [
[
"2ccc9eebdc8b1c6d"
]
]
},
{
"id": "2ccc9eebdc8b1c6d",
"type": "function",
"z": "5c3a7efbb734c312",
"name": "parser",
"func": "// Array of variables to convert (define the path to each variable as a string, excluding the array index)\nlet variablesToConvert = [\n \"NestedsubMesssage_1.batteryLevel\",\n \"NestedsubMesssage_1.acPower\",\n \"NestedsubMesssage_1.acOut\"\n];\n\n// Helper function to access and modify nested properties\nfunction convertFixed32ToFloat(obj, path) {\n let keys = path.split(\".\");\n let lastKey = keys.pop();\n let target = keys.reduce((o, k) => (o && o[k] ? o[k] : undefined), obj);\n\n if (target && target[lastKey] !== undefined) {\n let fixed32Value = target[lastKey];\n let buffer = Buffer.alloc(4);\n buffer.writeUInt32LE(fixed32Value); // Write as little-endian\n let dataView = new DataView(buffer.buffer);\n let floatValue = dataView.getFloat32(0, true); // Convert to float (little-endian)\n target[lastKey] = Math.round(floatValue * 100) / 100; // Round to 2 decimals\n }\n}\n\n// Validate that the array exists\nif (\n msg.payload.subMesssage_1 &&\n Array.isArray(msg.payload.subMesssage_1)\n) {\n // Automatically find the element with the largest NestedsubMesssage_1 (by number of keys)\n let selectedElement = msg.payload.subMesssage_1.reduce((largest, current) => {\n const currentSize = current?.NestedsubMesssage_1 ? Object.keys(current.NestedsubMesssage_1).length : 0;\n const largestSize = largest?.NestedsubMesssage_1 ? Object.keys(largest.NestedsubMesssage_1).length : 0;\n return currentSize > largestSize ? current : largest;\n }, null);\n\n if (selectedElement) {\n // Loop through the variables and convert them for the selected element\n variablesToConvert.forEach(path => {\n convertFixed32ToFloat(selectedElement, path);\n });\n\n // Flatten the selected element for output\n msg.payload = {\n ...selectedElement.NestedsubMesssage_1\n };\n } else {\n msg.payload = { error: \"No valid element found in subMesssage_1.\" };\n }\n} else {\n // Handle the case where the array is invalid\n msg.payload = {\n error: \"subMesssage_1 is not a valid array.\"\n };\n}\n\n// Return the flattened object as the payload\nreturn msg;\n",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1710,
"y": 1500,
"wires": [
[
"14915a090ac399a6",
"9cee10300a29e6a9",
"1b4d1659ea3a926c",
"bada8f8ece2635aa",
"43c3e714cd35d499"
]
]
},
{
"id": "b48fdb9a8c3cc648",
"type": "inject",
"z": "5c3a7efbb734c312",
"name": "self-powered off",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"selfpowered_106\":{}},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":3,\"int_11\":1,\"int_14\":148771586,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"payloadType": "json",
"x": 320,
"y": 1840,
"wires": [
[
"4afdedfb126c3adb"
]
]
},
{
"id": "cdb9de6cfa82de2f",
"type": "inject",
"z": "5c3a7efbb734c312",
"name": "self-powered on",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_26\":0,\"selfpowered_106\":{\"int_1\":1},\"int_138\":0},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":11,\"int_11\":1,\"int_14\":357051739,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"payloadType": "json",
"x": 320,
"y": 1720,
"wires": [
[
"4afdedfb126c3adb"
]
]
},
{
"id": "9cee10300a29e6a9",
"type": "ha-sensor",
"z": "5c3a7efbb734c312",
"name": "device_b_Battery Level",
"entityConfig": "dde3390b2670ecca",
"version": 0,
"state": "payload.batteryLevel",
"stateType": "msg",
"attributes": [],
"inputOverride": "allow",
"outputProperties": [],
"x": 1950,
"y": 1680,
"wires": [
[
"14915a090ac399a6"
]
]
},
{
"id": "1b4d1659ea3a926c",
"type": "ha-sensor",
"z": "5c3a7efbb734c312",
"name": "device_b_Charge Target",
"entityConfig": "8a7f89d5a9fa7c02",
"version": 0,
"state": "payload.target",
"stateType": "msg",
"attributes": [],
"inputOverride": "allow",
"outputProperties": [],
"x": 1950,
"y": 1740,
"wires": [
[
"14915a090ac399a6"
]
]
},
{
"id": "99b6426401998b0e",
"type": "ha-switch",
"z": "5c3a7efbb734c312",
"name": "device_b_self-powered",
"version": 0,
"debugenabled": false,
"inputs": 0,
"outputs": 2,
"entityConfig": "0ed3beaf87d1c18b",
"enableInput": false,
"outputOnStateChange": true,
"outputProperties": [
{
"property": "payload",
"propertyType": "msg",
"value": "",
"valueType": "str"
}
],
"x": 90,
"y": 1780,
"wires": [
[
"63aceac7ccac0171"
],
[
"d832c92ebdc1011f"
]
]
},
{
"id": "63aceac7ccac0171",
"type": "change",
"z": "5c3a7efbb734c312",
"name": "self-powered on",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_26\":0,\"selfpowered_106\":{\"int_1\":1},\"int_138\":0},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":11,\"int_11\":1,\"int_14\":357051739,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"tot": "json"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 320,
"y": 1760,
"wires": [
[
"4afdedfb126c3adb"
]
]
},
{
"id": "d832c92ebdc1011f",
"type": "change",
"z": "5c3a7efbb734c312",
"name": "self-powered off",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"selfpowered_106\":{}},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":3,\"int_11\":1,\"int_14\":148771586,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"tot": "json"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 320,
"y": 1800,
"wires": [
[
"4afdedfb126c3adb"
]
]
},
{
"id": "bada8f8ece2635aa",
"type": "ha-sensor",
"z": "5c3a7efbb734c312",
"name": "device_b_AC Power",
"entityConfig": "026a8517f7533933",
"version": 0,
"state": "payload.acPower",
"stateType": "msg",
"attributes": [],
"inputOverride": "allow",
"outputProperties": [],
"x": 1940,
"y": 1620,
"wires": [
[
"14915a090ac399a6"
]
]
},
{
"id": "2ebdec0e9dfb2275",
"type": "ha-number",
"z": "5c3a7efbb734c312",
"name": "device_b_charge-target",
"version": 1,
"debugenabled": false,
"inputs": 0,
"outputs": 1,
"entityConfig": "3c4b70a170c5034c",
"exposeAsEntityConfig": "",
"mode": "listen",
"value": "payload",
"valueType": "msg",
"outputProperties": [
{
"property": "payload",
"propertyType": "msg",
"value": "",
"valueType": "value"
},
{
"property": "previousValue",
"propertyType": "msg",
"value": "",
"valueType": "previousValue"
}
],
"x": 90,
"y": 1940,
"wires": [
[
"154a232e234fcd68"
]
]
},
{
"id": "154a232e234fcd68",
"type": "function",
"z": "5c3a7efbb734c312",
"name": "charge-target",
"func": "// Get the input number from the msg payload\nlet inputNumber = msg.payload;\n\n// Validate the input number and clamp it between 15 and 90\nif (inputNumber < 15) {\n inputNumber = 15;\n} else if (inputNumber > 90) {\n inputNumber = 90;\n}\n\n// Define the JSON structure\nconst jsonResponse = {\n \"subMesssage_1\": {\n \"NestedsubMesssage_1\": {\n \"int_102\": inputNumber // Use the validated input number here\n },\n \"int_2\": 32,\n \"int_3\": 2,\n \"int_4\": 1,\n \"int_5\": 1,\n \"int_8\": 254,\n \"int_9\": 17,\n \"int_10\": 3,\n \"int_11\": 1,\n \"int_14\": 148771586,\n \"int_15\": 1,\n \"int_16\": 19,\n \"int_17\": 1\n }\n};\n\n// Assign the JSON to msg.payload\nmsg.payload = jsonResponse;\n\n// Return the modified msg object\nreturn msg;\n",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 330,
"y": 1940,
"wires": [
[
"4afdedfb126c3adb"
]
]
},
{
"id": "e01d4a7f5c8794e8",
"type": "ha-switch",
"z": "5c3a7efbb734c312",
"name": "device_b_beep",
"version": 0,
"debugenabled": false,
"inputs": 0,
"outputs": 2,
"entityConfig": "3631ea3e83d0c784",
"enableInput": false,
"outputOnStateChange": true,
"outputProperties": [
{
"property": "payload",
"propertyType": "msg",
"value": "",
"valueType": "str"
}
],
"x": 120,
"y": 2120,
"wires": [
[
"da187d62e67d4740"
],
[
"0db6d726d44ba972"
]
]
},
{
"id": "da187d62e67d4740",
"type": "change",
"z": "5c3a7efbb734c312",
"name": "beep-on",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_9\":1},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":2,\"int_11\":1,\"int_14\":128301330,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"tot": "json"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 340,
"y": 2100,
"wires": [
[
"4afdedfb126c3adb"
]
]
},
{
"id": "0db6d726d44ba972",
"type": "change",
"z": "5c3a7efbb734c312",
"name": "beep-off",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_9\":0},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":2,\"int_11\":1,\"int_14\":128301330,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"tot": "json"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 340,
"y": 2140,
"wires": [
[
"4afdedfb126c3adb"
]
]
},
{
"id": "43c3e714cd35d499",
"type": "ha-sensor",
"z": "5c3a7efbb734c312",
"name": "device_b_AC Out",
"entityConfig": "2a388ed5ce9b5e60",
"version": 0,
"state": "payload.acOut",
"stateType": "msg",
"attributes": [],
"inputOverride": "allow",
"outputProperties": [],
"x": 1930,
"y": 1560,
"wires": [
[
"14915a090ac399a6"
]
]
},
{
"id": "2c1452e5064f0d52",
"type": "mqtt in",
"z": "5c3a7efbb734c312",
"name": "",
"topic": "/app/[[APPID]]/[[SN]]/thing/property/get_reply",
"qos": "2",
"datatype": "base64",
"broker": "4a025f91e9595714",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 1010,
"y": 1440,
"wires": [
[
"61291127c9a9b736"
]
]
},
{
"id": "40899d5bf070eb87",
"type": "mqtt out",
"z": "5c3a7efbb734c312",
"name": "",
"topic": "/app/[[APPID]]/[[SN]]/thing/property/set",
"qos": "0",
"retain": "",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "4a025f91e9595714",
"x": 990,
"y": 2640,
"wires": []
},
{
"id": "e7b270e459122203",
"type": "inject",
"z": "5c3a7efbb734c312",
"name": "beep_on",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_9\":1},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":2,\"int_11\":1,\"int_14\":128301330,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"payloadType": "json",
"x": 340,
"y": 2740,
"wires": [
[
"0df3e8fca92c4338"
]
]
},
{
"id": "0df3e8fca92c4338",
"type": "encode",
"z": "5c3a7efbb734c312",
"name": "",
"protofile": "fd04eecb52341faa",
"protoType": "MessageFromJson",
"x": 620,
"y": 2640,
"wires": [
[
"40899d5bf070eb87"
]
]
},
{
"id": "da568bf8284dcb21",
"type": "inject",
"z": "5c3a7efbb734c312",
"name": "beep_off",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_9\":0},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":2,\"int_11\":1,\"int_14\":128301330,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"payloadType": "json",
"x": 340,
"y": 2860,
"wires": [
[
"0df3e8fca92c4338"
]
]
},
{
"id": "206aee2b11b63f84",
"type": "inject",
"z": "5c3a7efbb734c312",
"name": "get",
"props": [
{
"p": "payload"
}
],
"repeat": "15",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_14\":128301340,\"bytes_23\":\"Android\"}}}",
"payloadType": "json",
"x": 350,
"y": 2320,
"wires": [
[
"e48d93fa9bd1dede"
]
]
},
{
"id": "c041d0230aae2212",
"type": "mqtt out",
"z": "5c3a7efbb734c312",
"name": "",
"topic": "/app/[[APPID]]/[[SN]]/thing/property/get",
"qos": "2",
"retain": "",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "4a025f91e9595714",
"x": 990,
"y": 2520,
"wires": []
},
{
"id": "e48d93fa9bd1dede",
"type": "encode",
"z": "5c3a7efbb734c312",
"name": "",
"protofile": "fd04eecb52341faa",
"protoType": "MessageFromJson",
"x": 620,
"y": 2520,
"wires": [
[
"c041d0230aae2212"
]
]
},
{
"id": "9d19d00006660558",
"type": "inject",
"z": "5c3a7efbb734c312",
"name": "charge_15",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_102\":15},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":3,\"int_11\":1,\"int_14\":148771586,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"payloadType": "json",
"x": 340,
"y": 2660,
"wires": [
[
"0df3e8fca92c4338"
]
]
},
{
"id": "9c7d06381f17ec47",
"type": "inject",
"z": "5c3a7efbb734c312",
"name": "charge_90",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_102\":90},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":3,\"int_11\":1,\"int_14\":148771586,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"payloadType": "json",
"x": 340,
"y": 2580,
"wires": [
[
"0df3e8fca92c4338"
]
]
},
{
"id": "606d09cff852da57",
"type": "inject",
"z": "5c3a7efbb734c312",
"name": "self-powered off",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"selfpowered_106\":{}},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":3,\"int_11\":1,\"int_14\":148771586,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"payloadType": "json",
"x": 320,
"y": 2520,
"wires": [
[
"0df3e8fca92c4338"
]
]
},
{
"id": "0c965edcfaee92e2",
"type": "inject",
"z": "5c3a7efbb734c312",
"name": "self-powered on",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_26\":0,\"selfpowered_106\":{\"int_1\":1},\"int_138\":0},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":11,\"int_11\":1,\"int_14\":357051739,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"payloadType": "json",
"x": 320,
"y": 2400,
"wires": [
[
"0df3e8fca92c4338"
]
]
},
{
"id": "2a75e18e8370d8dc",
"type": "ha-switch",
"z": "5c3a7efbb734c312",
"name": "game-room_self-powered",
"version": 0,
"debugenabled": false,
"inputs": 0,
"outputs": 2,
"entityConfig": "0ed3beaf87d1c18b",
"enableInput": false,
"outputOnStateChange": true,
"outputProperties": [
{
"property": "payload",
"propertyType": "msg",
"value": "",
"valueType": "str"
}
],
"x": 110,
"y": 2460,
"wires": [
[
"d58f942610d15d41"
],
[
"36b8aa2e46921246"
]
]
},
{
"id": "d58f942610d15d41",
"type": "change",
"z": "5c3a7efbb734c312",
"name": "self-powered on",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_26\":0,\"selfpowered_106\":{\"int_1\":1},\"int_138\":0},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":11,\"int_11\":1,\"int_14\":357051739,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"tot": "json"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 320,
"y": 2440,
"wires": [
[
"0df3e8fca92c4338"
]
]
},
{
"id": "36b8aa2e46921246",
"type": "change",
"z": "5c3a7efbb734c312",
"name": "self-powered off",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"selfpowered_106\":{}},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":3,\"int_11\":1,\"int_14\":148771586,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"tot": "json"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 320,
"y": 2480,
"wires": [
[
"0df3e8fca92c4338"
]
]
},
{
"id": "a8889aac5fe8adba",
"type": "ha-number",
"z": "5c3a7efbb734c312",
"name": "game_room_charge-target",
"version": 1,
"debugenabled": false,
"inputs": 0,
"outputs": 1,
"entityConfig": "6d6efedc5ce72e03",
"exposeAsEntityConfig": "",
"mode": "listen",
"value": "payload",
"valueType": "msg",
"outputProperties": [
{
"property": "payload",
"propertyType": "msg",
"value": "",
"valueType": "value"
},
{
"property": "previousValue",
"propertyType": "msg",
"value": "",
"valueType": "previousValue"
}
],
"x": 110,
"y": 2620,
"wires": [
[
"a0e3545c22e94120"
]
]
},
{
"id": "a0e3545c22e94120",
"type": "function",
"z": "5c3a7efbb734c312",
"name": "charge-target",
"func": "// Get the input number from the msg payload\nlet inputNumber = msg.payload;\n\n// Validate the input number and clamp it between 15 and 90\nif (inputNumber < 15) {\n inputNumber = 15;\n} else if (inputNumber > 90) {\n inputNumber = 90;\n}\n\n// Define the JSON structure\nconst jsonResponse = {\n \"subMesssage_1\": {\n \"NestedsubMesssage_1\": {\n \"int_102\": inputNumber // Use the validated input number here\n },\n \"int_2\": 32,\n \"int_3\": 2,\n \"int_4\": 1,\n \"int_5\": 1,\n \"int_8\": 254,\n \"int_9\": 17,\n \"int_10\": 3,\n \"int_11\": 1,\n \"int_14\": 148771586,\n \"int_15\": 1,\n \"int_16\": 19,\n \"int_17\": 1\n }\n};\n\n// Assign the JSON to msg.payload\nmsg.payload = jsonResponse;\n\n// Return the modified msg object\nreturn msg;\n",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 330,
"y": 2620,
"wires": [
[
"0df3e8fca92c4338"
]
]
},
{
"id": "c87da4bdf1d50ee0",
"type": "ha-switch",
"z": "5c3a7efbb734c312",
"name": "game_romm_beep",
"version": 0,
"debugenabled": false,
"inputs": 0,
"outputs": 2,
"entityConfig": "7780b0daa4506eb3",
"enableInput": false,
"outputOnStateChange": true,
"outputProperties": [
{
"property": "payload",
"propertyType": "msg",
"value": "",
"valueType": "str"
}
],
"x": 150,
"y": 2800,
"wires": [
[
"84ef3666b4918b11"
],
[
"7797631b8793f548"
]
]
},
{
"id": "84ef3666b4918b11",
"type": "change",
"z": "5c3a7efbb734c312",
"name": "beep-on",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_9\":1},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":2,\"int_11\":1,\"int_14\":128301330,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"tot": "json"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 340,
"y": 2780,
"wires": [
[
"0df3e8fca92c4338"
]
]
},
{
"id": "7797631b8793f548",
"type": "change",
"z": "5c3a7efbb734c312",
"name": "beep-off",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "{\"subMesssage_1\":{\"NestedsubMesssage_1\":{\"int_9\":0},\"int_2\":32,\"int_3\":2,\"int_4\":1,\"int_5\":1,\"int_8\":254,\"int_9\":17,\"int_10\":2,\"int_11\":1,\"int_14\":128301330,\"int_15\":1,\"int_16\":19,\"int_17\":1}}",
"tot": "json"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 340,
"y": 2820,
"wires": [
[
"0df3e8fca92c4338"
]
]
},
{
"id": "86fd2954650666b0",
"type": "debug",
"z": "5c3a7efbb734c312",
"name": "debug 14",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 1380,
"y": 2380,
"wires": []
},
{
"id": "384d158b61792940",
"type": "mqtt in",
"z": "5c3a7efbb734c312",
"name": "",
"topic": "/app/[[APPID]]/[[SN]]/thing/property/get_reply",
"qos": "2",
"datatype": "auto-detect",
"broker": "4a025f91e9595714",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 970,
"y": 2440,
"wires": [
[
"86fd2954650666b0",
"26d30e88ae82ce2e"
]
]
},
{
"id": "d0116386713bae5c",
"type": "debug",
"z": "5c3a7efbb734c312",
"name": "debug 15",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 2260,
"y": 2440,
"wires": []
},
{
"id": "26d30e88ae82ce2e",
"type": "decode",
"z": "5c3a7efbb734c312",
"name": "",
"protofile": "09526bce7b477f38",
"protoType": "MessageFromJson",
"x": 1520,
"y": 2440,
"wires": [
[
"549457785dda7568",
"d0116386713bae5c"
]
]
},
{
"id": "549457785dda7568",
"type": "function",
"z": "5c3a7efbb734c312",
"name": "parser",
"func": "// Array of variables to convert (define the path to each variable as a string, excluding the array index)\nlet variablesToConvert = [\n \"NestedsubMesssage_1.batteryLevel\",\n \"NestedsubMesssage_1.acPower\",\n \"NestedsubMesssage_1.acOut\"\n];\n\n// Helper function to access and modify nested properties\nfunction convertFixed32ToFloat(obj, path) {\n let keys = path.split(\".\");\n let lastKey = keys.pop();\n let target = keys.reduce((o, k) => (o && o[k] ? o[k] : undefined), obj);\n\n if (target && target[lastKey] !== undefined) {\n let fixed32Value = target[lastKey];\n let buffer = Buffer.alloc(4);\n buffer.writeUInt32LE(fixed32Value); // Write as little-endian\n let dataView = new DataView(buffer.buffer);\n let floatValue = dataView.getFloat32(0, true); // Convert to float (little-endian)\n target[lastKey] = Math.round(floatValue * 100) / 100; // Round to 2 decimals\n }\n}\n\n// Validate that the array exists\nif (\n msg.payload.subMesssage_1 &&\n Array.isArray(msg.payload.subMesssage_1)\n) {\n // Automatically find the element with the largest NestedsubMesssage_1 (by number of keys)\n let selectedElement = msg.payload.subMesssage_1.reduce((largest, current) => {\n const currentSize = current?.NestedsubMesssage_1 ? Object.keys(current.NestedsubMesssage_1).length : 0;\n const largestSize = largest?.NestedsubMesssage_1 ? Object.keys(largest.NestedsubMesssage_1).length : 0;\n return currentSize > largestSize ? current : largest;\n }, null);\n\n if (selectedElement) {\n // Loop through the variables and convert them for the selected element\n variablesToConvert.forEach(path => {\n convertFixed32ToFloat(selectedElement, path);\n });\n\n // Flatten the selected element for output\n msg.payload = {\n ...selectedElement.NestedsubMesssage_1\n };\n } else {\n msg.payload = { error: \"No valid element found in subMesssage_1.\" };\n }\n} else {\n // Handle the case where the array is invalid\n msg.payload = {\n error: \"subMesssage_1 is not a valid array.\"\n };\n}\n\n// Return the flattened object as the payload\nreturn msg;\n",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1670,
"y": 2440,
"wires": [
[
"d0116386713bae5c",
"0c4901bd2280a3d7",
"45baf5736570e2ad",
"329113f3c0c5de18",
"e0919f7e1a368afa"
]
]
},
{
"id": "0c4901bd2280a3d7",
"type": "ha-sensor",
"z": "5c3a7efbb734c312",
"name": "game_room_Battery Level",
"entityConfig": "7151f98c7353537a",
"version": 0,
"state": "payload.batteryLevel",
"stateType": "msg",
"attributes": [],
"inputOverride": "allow",
"outputProperties": [],
"x": 1940,
"y": 2620,
"wires": [
[
"d0116386713bae5c"
]
]
},
{
"id": "45baf5736570e2ad",
"type": "ha-sensor",
"z": "5c3a7efbb734c312",
"name": "game_room_Charge Target",
"entityConfig": "441b901f84dcda6f",
"version": 0,
"state": "payload.target",
"stateType": "msg",
"attributes": [],
"inputOverride": "allow",
"outputProperties": [],
"x": 1940,
"y": 2680,
"wires": [
[
"d0116386713bae5c"
]
]
},
{
"id": "329113f3c0c5de18",
"type": "ha-sensor",
"z": "5c3a7efbb734c312",
"name": "game_room_AC Power",
"entityConfig": "0f0fe1c43b8f4534",
"version": 0,
"state": "payload.acPower",
"stateType": "msg",
"attributes": [],
"inputOverride": "allow",
"outputProperties": [],
"x": 1930,
"y": 2560,
"wires": [
[
"d0116386713bae5c"
]
]
},
{
"id": "e0919f7e1a368afa",
"type": "ha-sensor",
"z": "5c3a7efbb734c312",
"name": "game_room_AC Out",
"entityConfig": "859ef31dd27d08ad",
"version": 0,
"state": "payload.acOut",
"stateType": "msg",
"attributes": [],
"inputOverride": "allow",
"outputProperties": [],
"x": 1920,
"y": 2500,
"wires": [
[
"d0116386713bae5c"
]
]
},
{
"id": "fd881a468a285660",
"type": "mqtt in",
"z": "5c3a7efbb734c312",
"name": "",
"topic": "/app/[[APPID]]/[[SN]]/thing/property/get_reply",
"qos": "2",
"datatype": "base64",
"broker": "4a025f91e9595714",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 970,
"y": 2380,
"wires": [
[
"86fd2954650666b0"
]
]
},
{
"id": "671e0ceff575862c",
"type": "inject",
"z": "5c3a7efbb734c312",
"name": "disconnect",
"props": [
{
"p": "action",
"v": "disconnect",
"vt": "str"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"x": 340,
"y": 580,
"wires": [
[
"d5d7e8960ba14429"
]
]
},
{
"id": "5b6c19b0a776f928",
"type": "mqtt in",
"z": "5c3a7efbb734c312",
"name": "",
"topic": "/app/device/status/[[SN]]",
"qos": "2",
"datatype": "base64",
"broker": "4a025f91e9595714",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 900,
"y": 220,
"wires": [
[
"c8d401ac3c0d530b"
]
]
},
{
"id": "4a025f91e9595714",
"type": "mqtt-broker",
"name": "ecoflow",
"broker": "mqtts://mqtt.ecoflow.com:8883",
"port": "8883",
"clientid": "ANDROID_58AC938C-00B3-4635-8D83-D0575E20C8B7_[[APPID]]",
"autoConnect": false,
"usetls": false,
"protocolVersion": "4",
"keepalive": "60",
"cleansession": true,
"autoUnsubscribe": true,
"birthTopic": "",
"birthQos": "0",
"birthRetain": "false",
"birthPayload": "",
"birthMsg": {},
"closeTopic": "",
"closeQos": "0",
"closeRetain": "false",
"closePayload": "",
"closeMsg": {},
"willTopic": "",
"willQos": "0",
"willRetain": "false",
"willPayload": "",
"willMsg": {},
"userProps": "",
"sessionExpiry": ""
},
{
"id": "fd04eecb52341faa",
"type": "protobuf-file",
"protopath": "/homeassistant/www/get-delta3.proto",
"watchFile": true,
"keepCase": false
},
{
"id": "09526bce7b477f38",
"type": "protobuf-file",
"protopath": "/homeassistant/www/decodev2-delta3.proto",
"watchFile": true,
"keepCase": false
},
{
"id": "49b4f2bfd1956a24",
"type": "ha-entity-config",
"server": "399b9507.fdb0ea",
"deviceConfig": "5953bb61763c4552",
"name": "device_a_Battery Level",
"version": "6",
"entityType": "sensor",
"haConfig": [
{
"property": "name",
"value": "Battery Level"
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_picture",
"value": ""
},
{
"property": "entity_category",
"value": "diagnostic"
},
{
"property": "device_class",
"value": "battery"
},
{
"property": "unit_of_measurement",
"value": "%"
},
{
"property": "state_class",
"value": "measurement"
}
],
"resend": false,
"debugEnabled": false
},
{
"id": "87a97985e13b1458",
"type": "ha-entity-config",
"server": "399b9507.fdb0ea",
"deviceConfig": "5953bb61763c4552",
"name": "device_a_Charge Target",
"version": "6",
"entityType": "sensor",
"haConfig": [
{
"property": "name",
"value": "Charge Target"
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_picture",
"value": ""
},
{
"property": "entity_category",
"value": "diagnostic"
},
{
"property": "device_class",
"value": ""
},
{
"property": "unit_of_measurement",
"value": "%"
},
{
"property": "state_class",
"value": ""
}
],
"resend": false,
"debugEnabled": false
},
{
"id": "20ef2d5be7415ccd",
"type": "ha-entity-config",
"server": "399b9507.fdb0ea",
"deviceConfig": "5953bb61763c4552",
"name": "device_a_self-powered",
"version": "6",
"entityType": "switch",
"haConfig": [
{
"property": "name",
"value": "self-powered"
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_picture",
"value": ""
},
{
"property": "entity_category",
"value": "config"
},
{
"property": "device_class",
"value": ""
}
],
"resend": false,
"debugEnabled": false
},
{
"id": "6670dfa7e6a8c02e",
"type": "ha-entity-config",
"server": "399b9507.fdb0ea",
"deviceConfig": "5953bb61763c4552",
"name": "device_a_AC Power",
"version": "6",
"entityType": "sensor",
"haConfig": [
{
"property": "name",
"value": "AC Power"
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_picture",
"value": ""
},
{
"property": "entity_category",
"value": "diagnostic"
},
{
"property": "device_class",
"value": "energy"
},
{
"property": "unit_of_measurement",
"value": "Wh"
},
{
"property": "state_class",
"value": "measurement"
}
],
"resend": false,
"debugEnabled": false
},
{
"id": "a0136659e84650bb",
"type": "ha-entity-config",
"server": "399b9507.fdb0ea",
"deviceConfig": "5953bb61763c4552",
"name": "device_a_charge-target",
"version": "6",
"entityType": "number",
"haConfig": [
{
"property": "name",
"value": "charge-target"
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_picture",
"value": ""
},
{
"property": "entity_category",
"value": "config"
},
{
"property": "device_class",
"value": ""
},
{
"property": "unit_of_measurement",
"value": "%"
},
{
"property": "min_value",
"value": 15
},
{
"property": "max_value",
"value": 90
},
{
"property": "step_value",
"value": 1
},
{
"property": "mode",
"value": "auto"
}
],
"resend": false,
"debugEnabled": false
},
{
"id": "43ab0950c992e96d",
"type": "ha-entity-config",
"server": "399b9507.fdb0ea",
"deviceConfig": "5953bb61763c4552",
"name": "device_a_beep",
"version": "6",
"entityType": "switch",
"haConfig": [
{
"property": "name",
"value": "Beep"
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_picture",
"value": ""
},
{
"property": "entity_category",
"value": "config"
},
{
"property": "device_class",
"value": ""
}
],
"resend": false,
"debugEnabled": false
},
{
"id": "9531e396809c4293",
"type": "ha-entity-config",
"server": "399b9507.fdb0ea",
"deviceConfig": "5953bb61763c4552",
"name": "device_a_AC Out",
"version": "6",
"entityType": "sensor",
"haConfig": [
{
"property": "name",
"value": "AC Out"
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_picture",
"value": ""
},
{
"property": "entity_category",
"value": "diagnostic"
},
{
"property": "device_class",
"value": "energy"
},
{
"property": "unit_of_measurement",
"value": "Wh"
},
{
"property": "state_class",
"value": "measurement"
}
],
"resend": false,
"debugEnabled": false
},
{
"id": "dde3390b2670ecca",
"type": "ha-entity-config",
"server": "399b9507.fdb0ea",
"deviceConfig": "65845f97489716d9",
"name": "device_b_Battery Level",
"version": "6",
"entityType": "sensor",
"haConfig": [
{
"property": "name",
"value": "Battery Level"
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_picture",
"value": ""
},
{
"property": "entity_category",
"value": "diagnostic"
},
{
"property": "device_class",
"value": "battery"
},
{
"property": "unit_of_measurement",
"value": "%"
},
{
"property": "state_class",
"value": "measurement"
}
],
"resend": false,
"debugEnabled": false
},
{
"id": "8a7f89d5a9fa7c02",
"type": "ha-entity-config",
"server": "399b9507.fdb0ea",
"deviceConfig": "65845f97489716d9",
"name": "device_b_Charge Target",
"version": "6",
"entityType": "sensor",
"haConfig": [
{
"property": "name",
"value": "Charge Target"
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_picture",
"value": ""
},
{
"property": "entity_category",
"value": "diagnostic"
},
{
"property": "device_class",
"value": ""
},
{
"property": "unit_of_measurement",
"value": "%"
},
{
"property": "state_class",
"value": ""
}
],
"resend": false,
"debugEnabled": false
},
{
"id": "0ed3beaf87d1c18b",
"type": "ha-entity-config",
"server": "399b9507.fdb0ea",
"deviceConfig": "295aed1158103b7f",
"name": "game-room_self-powered",
"version": "6",
"entityType": "switch",
"haConfig": [
{
"property": "name",
"value": "self-powered"
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_picture",
"value": ""
},
{
"property": "entity_category",
"value": ""
},
{
"property": "device_class",
"value": "switch"
}
],
"resend": false,
"debugEnabled": false
},
{
"id": "026a8517f7533933",
"type": "ha-entity-config",
"server": "399b9507.fdb0ea",
"deviceConfig": "65845f97489716d9",
"name": "device_b_AC Power",
"version": "6",
"entityType": "sensor",
"haConfig": [
{
"property": "name",
"value": "AC Power"
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_picture",
"value": ""
},
{
"property": "entity_category",
"value": "diagnostic"
},
{
"property": "device_class",
"value": "energy"
},
{
"property": "unit_of_measurement",
"value": "Wh"
},
{
"property": "state_class",
"value": "measurement"
}
],
"resend": false,
"debugEnabled": false
},
{
"id": "3c4b70a170c5034c",
"type": "ha-entity-config",
"server": "399b9507.fdb0ea",
"deviceConfig": "65845f97489716d9",
"name": "device_b_charge-target",
"version": "6",
"entityType": "number",
"haConfig": [
{
"property": "name",
"value": "charge-target"
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_picture",
"value": ""
},
{
"property": "entity_category",
"value": "config"
},
{
"property": "device_class",
"value": ""
},
{
"property": "unit_of_measurement",
"value": "%"
},
{
"property": "min_value",
"value": 15
},
{
"property": "max_value",
"value": 90
},
{
"property": "step_value",
"value": 1
},
{
"property": "mode",
"value": "slider"
}
],
"resend": false,
"debugEnabled": false
},
{
"id": "3631ea3e83d0c784",
"type": "ha-entity-config",
"server": "399b9507.fdb0ea",
"deviceConfig": "65845f97489716d9",
"name": "device_b_beep",
"version": "6",
"entityType": "switch",
"haConfig": [
{
"property": "name",
"value": "Beep"
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_picture",
"value": ""
},
{
"property": "entity_category",
"value": "config"
},
{
"property": "device_class",
"value": "switch"
}
],
"resend": false,
"debugEnabled": false
},
{
"id": "2a388ed5ce9b5e60",
"type": "ha-entity-config",
"server": "399b9507.fdb0ea",
"deviceConfig": "65845f97489716d9",
"name": "device_b_AC Out",
"version": "6",
"entityType": "sensor",
"haConfig": [
{
"property": "name",
"value": "AC Out"
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_picture",
"value": ""
},
{
"property": "entity_category",
"value": "diagnostic"
},
{
"property": "device_class",
"value": "energy"
},
{
"property": "unit_of_measurement",
"value": "Wh"
},
{
"property": "state_class",
"value": "measurement"
}
],
"resend": false,
"debugEnabled": false
},
{
"id": "6d6efedc5ce72e03",
"type": "ha-entity-config",
"server": "399b9507.fdb0ea",
"deviceConfig": "295aed1158103b7f",
"name": "game_room_charge-target",
"version": "6",
"entityType": "number",
"haConfig": [
{
"property": "name",
"value": ""
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_picture",
"value": ""
},
{
"property": "entity_category",
"value": "config"
},
{
"property": "device_class",
"value": ""
},
{
"property": "unit_of_measurement",
"value": "%"
},
{
"property": "min_value",
"value": 15
},
{
"property": "max_value",
"value": 90
},
{
"property": "step_value",
"value": 1
},
{
"property": "mode",
"value": "slider"
}
],
"resend": false,
"debugEnabled": false
},
{
"id": "7780b0daa4506eb3",
"type": "ha-entity-config",
"server": "399b9507.fdb0ea",
"deviceConfig": "295aed1158103b7f",
"name": "game_room_beep",
"version": "6",
"entityType": "switch",
"haConfig": [
{
"property": "name",
"value": "Beep"
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_picture",
"value": ""
},
{
"property": "entity_category",
"value": "config"
},
{
"property": "device_class",
"value": "switch"
}
],
"resend": false,
"debugEnabled": false
},
{
"id": "7151f98c7353537a",
"type": "ha-entity-config",
"server": "399b9507.fdb0ea",
"deviceConfig": "295aed1158103b7f",
"name": "game_room_Battery_Level",
"version": "6",
"entityType": "sensor",
"haConfig": [
{
"property": "name",
"value": "Battery Level"
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_picture",
"value": ""
},
{
"property": "entity_category",
"value": "diagnostic"
},
{
"property": "device_class",
"value": "battery"
},
{
"property": "unit_of_measurement",
"value": "%"
},
{
"property": "state_class",
"value": "measurement"
}
],
"resend": false,
"debugEnabled": false
},
{
"id": "441b901f84dcda6f",
"type": "ha-entity-config",
"server": "399b9507.fdb0ea",
"deviceConfig": "295aed1158103b7f",
"name": "game_room_charge_target",
"version": "6",
"entityType": "sensor",
"haConfig": [
{
"property": "name",
"value": "Charge Target"
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_picture",
"value": ""
},
{
"property": "entity_category",
"value": "diagnostic"
},
{
"property": "device_class",
"value": ""
},
{
"property": "unit_of_measurement",
"value": "%"
},
{
"property": "state_class",
"value": ""
}
],
"resend": false,
"debugEnabled": false
},
{
"id": "0f0fe1c43b8f4534",
"type": "ha-entity-config",
"server": "399b9507.fdb0ea",
"deviceConfig": "295aed1158103b7f",
"name": "game_room_AC_Power",
"version": "6",
"entityType": "sensor",
"haConfig": [
{
"property": "name",
"value": "AC Power"
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_picture",
"value": ""
},
{
"property": "entity_category",
"value": "diagnostic"
},
{
"property": "device_class",
"value": "energy"
},
{
"property": "unit_of_measurement",
"value": "Wh"
},
{
"property": "state_class",
"value": "measurement"
}
],
"resend": false,
"debugEnabled": false
},
{
"id": "859ef31dd27d08ad",
"type": "ha-entity-config",
"server": "399b9507.fdb0ea",
"deviceConfig": "295aed1158103b7f",
"name": "game_room_AC Out",
"version": "6",
"entityType": "sensor",
"haConfig": [
{
"property": "name",
"value": "AC Out"
},
{
"property": "icon",
"value": ""
},
{
"property": "entity_picture",
"value": ""
},
{
"property": "entity_category",
"value": "diagnostic"
},
{
"property": "device_class",
"value": "energy"
},
{
"property": "unit_of_measurement",
"value": "Wh"
},
{
"property": "state_class",
"value": "measurement"
}
],
"resend": false,
"debugEnabled": false
},
{
"id": "399b9507.fdb0ea",
"type": "server",
"name": "Home Assistant",
"addon": true
},
{
"id": "5953bb61763c4552",
"type": "ha-device-config",
"name": "device_a D3+",
"hwVersion": "",
"manufacturer": "EcoFlow",
"model": "Delta 3+",
"swVersion": ""
},
{
"id": "65845f97489716d9",
"type": "ha-device-config",
"name": "device_b D3+",
"hwVersion": "",
"manufacturer": "EcoFlow",
"model": "Delta 3+",
"swVersion": ""
},
{
"id": "295aed1158103b7f",
"type": "ha-device-config",
"name": "Game Room D3+",
"hwVersion": "",
"manufacturer": "EcoFlow",
"model": "Delta 3+",
"swVersion": ""
}
]
@nalditopr
Copy link
Author

@phoniclynx you might need to split the positive and negatives values with helper entities, there is a writeup about it here. https://community.home-assistant.io/t/rewritten-tesla-style-solar-power-card/294466/22?page=2
home-assistant/core#124671

"To extract the positive value from grid_power I wound up using {{ [ states('sensor.my_home_grid_power')|float(0), 0.0 ] | max }}, which because I am not fluent in the language used, I had to adapt from a search result. The method to convert a negative value into a positive value I wound up using was {{ [ ( -1 * states('sensor.my_home_grid_power')|float(0)), 0.0 ] | max }}."

@phoniclynx
Copy link

phoniclynx commented Apr 10, 2025

That might not be such a major issue as these other two in 3 and 4 seem to be the values I want.. however I can't confirm because there is too much sun. But as you said you have the values it should be a pretty good guess.

I am still having those same problems with the protobuf saying it's invalid which it shouldn't be :\

syntax = "proto3";

message MessageFromJson {

    repeated subMessage_1SubMsg subMessage_1 = 1;

    message NestedsubMessage_1SubMsg {

            fixed32 battery_level = 262;
            int32 target = 8;
            selfpowered_nested selfpowered_106 = 106;
            fixed32 ac_power = 54;
            fixed32 ac_out = 368;
            fixed32 batt_in = 3;
            fixed32 batt_out = 4;
            fixed32 dcone_in = 361;
            fixed32 dctwo_in = 70;

    }

    message subMessage_1SubMsg {

        NestedsubMessage_1SubMsg NestedsubMessage_1 = 1;

    }

    message selfpowered_nested {
        int32 int_1 = 1;
    }
}

Javascript:

  // Array of variables to convert (define the path to each variable as a string, excluding the array index)
  let variablesToConvert = [
    "NestedsubMessage_1.batteryLevel",
    "NestedsubMessage_1.acPower",
    "NestedsubMessage_1.acOut",
    "NestedsubMessage_1.battIn",
    "NestedsubMessage_1.battOut",
    "NestedsubMessage_1.dcOneIn",
    "NestedsubMessage_1.dcTwoIn"
];

Can you see my mistake at all?

@phoniclynx
Copy link

I'm stumped. I've been at this for a few hours and not getting any closer
image

@phoniclynx
Copy link

I changed it ever so slightly and have dcOneIn working but the others to me look the same yet they cause the error above if I uncomment them

syntax = "proto3";

message MessageFromJson {

    repeated subMessage_1SubMsg subMessage_1 = 1;

    message NestedsubMessage_1SubMsg {

            fixed32 battery_level = 262;
            int32 target = 8;
            selfpowered_nested selfpowered_106 = 106;
            fixed32 ac_power = 54;
            fixed32 ac_out = 368;
//            fixed32 battIn = 3;
//            fixed32 battOut = 4;
            fixed32 dcOneIn = 361;
//            fixed32 dcTwoIn = 70;

    }

    message subMessage_1SubMsg {

        NestedsubMessage_1SubMsg NestedsubMessage_1 = 1;

    }

    message selfpowered_nested {
        int32 int_1 = 1;
    }
}

@phoniclynx
Copy link

phoniclynx commented Apr 10, 2025

"fixed32 dcTwoIn = 70;" gives an error: Wire format is invalid: RangeError: index out of range: 1261 + 10 > 1261

110-116	70	fixed32	
As int: 0
As float: 0

"fixed32 dcOneIn = 361;" seems to work fine

373-379	361	fixed32	
As int: 0
As float: 0

They both look the same "fixed32" but for some reason, it can't decode it

"fixed32 battIn = 3;" gives an error: Wire format is invalid: Error: invalid wire type 4 at offset 548

2-7	3	fixed32	
As int: 0
As float: 0

"fixed32 battOut = 4;" seems to work fine. However, interestingly, it wasn't working when I started this post, but now it's working fine (I hope it stays that way)........... having said that.. sometimes it works and then it stops for a few mins then starts working again: Wire format is invalid: RangeError: index out of range: 1257 + 10 > 1257

7-12	4	fixed32	
As int: 1124597760
As float: 136

@nalditopr
Copy link
Author

I connected a 12v power supply and was able to decode dc_in_02 , 01 does not work, still checking.

    syntax = "proto3";
    
    message MessageFromJson {
    
        repeated subMessage_1SubMsg sub_message_1 = 1;
    
        message NestedsubMessage_1SubMsg {
    
            optional fixed32 battery_level = 262;
            optional int32 target = 8;
            optional fixed32 ac_power = 54;
            optional fixed32 ac_out = 368;
            //optional fixed32 dc_in_01 = 70;
            optional fixed32 dc_in_02 = 361;
    
        }
    
        message subMessage_1SubMsg {
    
            NestedsubMessage_1SubMsg Nestedsub_message_1 = 1;
    
        }
    }

@nalditopr
Copy link
Author

nalditopr commented Apr 10, 2025

@phoniclynx The root cause is that the message coming from ecoflow has some nesting in the protobuf structure that I have not been able to parse.

for example, dc_input 1 is located at position 70 as fixed 32, but on the next value of the array, position 70 has a string message, this causes it to fail decoding.

the other values do not have this problem and parse just fine.

fwiw, value 3 is combined dc input, 70 is dc_01 and 361 is dc_02.

@phoniclynx
Copy link

phoniclynx commented Apr 11, 2025

Did you mean 70 is dc_02 and 361 is dc_01? That's what I worked out on mine.

I'm guessing you need to parse the protobuf file differently?

I've also noticed a small error in the way you've set up the sensors. Category and Last Reset should be blank: (According to this: HA Forum Link - but I could be wrong)
image

However, Last Reset should be filled out here: (If not, you are not able to use it in the energy pages)
image

I'm not too sure if the actual date means anything or if it needs to be calculated elsewhere for some reason. But it does stop the Energy pages from throwing up an error message.

The final step is to get that protobuf nesting solved; then, it should work quite nicely. Until we find a different error LOL

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment