[
{
"id": "383cb2f7.2caede",
"type": "udp in",
"z": "e6fd3a1c.5e9548",
"name": "listener",
"iface": "",
"port": "18542",
"ipv": "udp4",
"multicast": "false",
"group": "",
"datatype": "buffer",
"x": 50,
"y": 40,
"wires": [
[
"1454f5c0.1322ca"
]
]
},
{
"id": "1454f5c0.1322ca",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "All Message Type numbers to Topic",
"func": "msg.Topic = (msg.payload[2].toString(16).toUpperCase() + msg.payload[1].toString(16).toUpperCase())\nreturn\tmsg;\t\t\n\t\t\t\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 280,
"y": 40,
"wires": [
[
"d1a55ffb.c877a",
"2af1bf8b.3e7b5"
]
]
},
{
"id": "d1a55ffb.c877a",
"type": "switch",
"z": "e6fd3a1c.5e9548",
"name": "Split the messages by type",
"property": "Topic",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "415A",
"vt": "str"
},
{
"t": "eq",
"v": "4232",
"vt": "str"
},
{
"t": "eq",
"v": "3E32",
"vt": "str"
},
{
"t": "eq",
"v": "3F33",
"vt": "str"
},
{
"t": "eq",
"v": "4732",
"vt": "str"
},
{
"t": "eq",
"v": "4932",
"vt": "str"
},
{
"t": "eq",
"v": "6131",
"vt": "str"
},
{
"t": "eq",
"v": "5732",
"vt": "str"
},
{
"t": "eq",
"v": "4032",
"vt": "str"
},
{
"t": "eq",
"v": "5432",
"vt": "str"
},
{
"t": "eq",
"v": "7857",
"vt": "str"
},
{
"t": "eq",
"v": "5632",
"vt": "str"
},
{
"t": "eq",
"v": "4A35",
"vt": "str"
},
{
"t": "eq",
"v": "4B35",
"vt": "str"
},
{
"t": "eq",
"v": "4C33",
"vt": "str"
},
{
"t": "eq",
"v": "4D33",
"vt": "str"
},
{
"t": "eq",
"v": "5334",
"vt": "str"
},
{
"t": "eq",
"v": "4F33",
"vt": "str"
},
{
"t": "eq",
"v": "5033",
"vt": "str"
},
{
"t": "eq",
"v": "5158",
"vt": "str"
},
{
"t": "eq",
"v": "5258",
"vt": "str"
},
{
"t": "eq",
"v": "4E58",
"vt": "str"
},
{
"t": "eq",
"v": "5831",
"vt": "str"
},
{
"t": "eq",
"v": "6831",
"vt": "str"
},
{
"t": "eq",
"v": "5431",
"vt": "str"
},
{
"t": "eq",
"v": "4732",
"vt": "str"
},
{
"t": "eq",
"v": "4d34",
"vt": "str"
},
{
"t": "eq",
"v": "6132",
"vt": "str"
}
],
"checkall": "true",
"repair": false,
"outputs": 28,
"x": 160,
"y": 320,
"wires": [
[
"9781b06a.53081"
],
[
"86897149.75de7"
],
[
"8f7d9f6b.5e7fa"
],
[
"7c28d81b.c0dd38"
],
[],
[
"d1133f4a.3ef44"
],
[
"d2fa3827.0fb158"
],
[
"40d3fdc.2a54504"
],
[
"6ba51319.a7a48c"
],
[
"1704d7ce.245b58"
],
[
"aeea1ecd.3c858"
],
[
"122c8b3f.160005"
],
[
"bc35aeeb.93ab7"
],
[
"31f8d71a.f97f68"
],
[
"6bbf2b60.9ce744"
],
[
"a7cdb5ee.7c66c8"
],
[
"bc74a308.cfe11"
],
[
"a3320528.870448"
],
[
"84398b42.b2f578"
],
[
"66113e17.06931"
],
[
"d0a120ad.f8edd"
],
[
"3f60dd09.a9d822"
],
[
"672f0abe.f9af24"
],
[
"fa326eca.690b8"
],
[
"15f71030.bd9eb"
],
[
"34dd4fa2.32065"
],
[
"17a67e5b.e13952"
],
[
"e69dec4b.f16a1"
]
]
},
{
"id": "ca12341f.fde6e8",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 1650,
"y": 640,
"wires": []
},
{
"id": "fbba11c0.1f358",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 390,
"y": 700,
"wires": []
},
{
"id": "bfddb91d.2b2a98",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 1650,
"y": 140,
"wires": []
},
{
"id": "5feebe37.b27b2",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 1650,
"y": 880,
"wires": []
},
{
"id": "49be9953.d21e48",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"d": true,
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 390,
"y": 1140,
"wires": []
},
{
"id": "22e7b26a.4c54ae",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 390,
"y": 740,
"wires": []
},
{
"id": "ea787f02.584ab",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"d": true,
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 390,
"y": 1100,
"wires": []
},
{
"id": "aeea1ecd.3c858",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Msg_7857_HwShuntMetrics",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n\t\t.skip(8)\n\t\t.uint8('ShuntSocCycles') \n\t\t.uint32le('RecentTimeAcculmSave') \t// Epoch\n\t\t.uint32le('RecentTimeSocLoRecal') \t// Epoch\n\t\t.uint32le('RecentTimeSocHiRecal') \t// Epoch\n\t\t.uint32le('RecentTimeSocCountLo') \t// Epoch\n\t\t.uint32le('RecentTimeSocCountHi') \t// Epoch\n\t\t.uint8( 'hasShuntSocCountLo') \t\t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'hasShuntSocCountHi') \t\t// boolean 0 = Off , 1 = On\n\t\t.int16le('EstDurationToFullmins') \n\t\t.int16le('EstDurationToEmptymins') \n\t\t.floatle('ShuntAcculmAvgCharge',\t{ formatter: (x) => {return x/1000;}})\t// Ah\n\t\t.floatle('ShuntAcculmAvgDischg',\t{ formatter: (x) => {return x/1000;}})\t// Ah\n\t\t.floatle('ShuntAcculmAvgNett',\t\t{ formatter: (x) => {return x/1000;}})\t// Ah\n\t\t.uint32le('ShuntSerialNo') \n\t\t.uint32le('ShuntManuCode') \n\t\t.int16le('ShuntPartNum')\n\t\t.int16le('ShuntVersCode')\n\t\t\n\n \nmsg.payload = typea.parse(buf);\n\n// convert date(s)\nmsg.payload.RecentTimeAcculmSave = new Date(msg.payload.RecentTimeAcculmSave*1000);\nmsg.payload.RecentTimeSocLoRecal = new Date(msg.payload.RecentTimeSocLoRecal*1000);\nmsg.payload.RecentTimeSocHiRecal = new Date(msg.payload.RecentTimeSocHiRecal*1000);\nmsg.payload.RecentTimeSocCountLo = new Date(msg.payload.RecentTimeSocCountLo*1000);\nmsg.payload.RecentTimeSocCountHi = new Date(msg.payload.RecentTimeSocCountHi*1000);\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 860,
"y": 840,
"wires": [
[
"90437fe0.fcd83"
]
]
},
{
"id": "df5c7d37.bd20b",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 1650,
"y": 840,
"wires": []
},
{
"id": "7c28d81b.c0dd38",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Msg_3f33_StatusFast",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n\t\t.skip(8)\n\t\t.uint8('CmuPollerMode') \t \n\t\t.uint8('CmuTxAckCount') // Cellmon TX Acknowledgement Count\n\t\t.uint8('CmuTxOpStatusNodeId') // Cellmon TX Operating Status Node ID\n\t\t.uint8('CmuTxOpStatusUSN') // Cellmon TX Operating Status Universal Serial Number\n\t\t.uint8('CmuTxOpParamNodeId') // Cellmon TX Parameter Node ID\n\t\t.int16le('GroupMinCellVolt',\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('GroupMaxCellVolt',\t\t{ formatter: (x) => {return x/1000;}})\t\t\n\t\t.uint8('GroupMinCellTemp',\t\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8('GroupMaxCellTemp',\t\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8('CmuRxOpStatusNodeId')\n\t\t.uint8('CmuRxOpStatusGroupAck')\n\t\t.uint8('CmuRxOpStatusUSN')\n\t\t.uint8('CmuRxOpParamNodeId')\n\t\t.uint8('SystemOpStatus') \n\t\t.uint8('SystemAuthMode') \n\t\t.int16le('SupplyVolt',\t\t\t\t{ formatter: (x) => {return x/100;}})\n\t\t.uint8('AmbientTemp',\t\t\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint32le('SystemTime') // Epoch\n\t\t.uint8('ShuntSOC', \t\t\t\t\t{ formatter: (x) => {return x/2-5;}}) // percent\n\t\t.uint8('ShuntTemp',\t\t\t\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.floatle('NomCapacityToFull',\t\t{ formatter: (x) => {return x/1000;}}) // Ah\n\t\t.floatle('NomCapacityToEmpty',\t\t{ formatter: (x) => {return x/1000;}}) // Ah\n\t\t.uint8('ShuntPollerMode') \n\t\t.uint8('ShuntStatus') /* Choices\n\t\t\t\tIdle Start = 0,\n\t\t\t\tIdle = 1,\n\t\t\t\tSync Start = 2,\n\t\t\t\tSync Running = 3,\n\t\t\t\tNormal = 4,\n\t\t\t\tShuntMon2 SetupStart = 5,\n\t\t\t\tShuntMon2 SetupRunning = 6,\n\t\t\t\tShuntMon2 Normal = 7, */\n\t\t.uint8('hasShuntLoSocRecal')\t\t// boolean 0 = Off , 1 = On\n\t\t.uint8('hasShuntHiSocRecal') \t\t// boolean 0 = Off , 1 = On\n\t\t// shunt.hasShuntOkSocRange = !(shunt.hasShuntLoSocRecal || shunt.hasShuntHiSocRecal);\n\t\t.uint8('ExpansionOutputFet5') \t\t// boolean 0 = Off , 1 = On\n\t\t.uint8('ExpansionOutputFet6') \t\t// boolean 0 = Off , 1 = On\n\t\t.uint8('ExpansionOutputFet7') \t\t// boolean 0 = Off , 1 = On\n\t\t.uint8('ExpansionOutputFet8') \t\t// boolean 0 = Off , 1 = On\n\t\t.uint8('ExpansionOutputRelay1') \t// boolean 0 = Off , 1 = On\n\t\t.uint8('ExpansionOutputRelay2') \t// boolean 0 = Off , 1 = On\n\t\t.uint8('ExpansionOutputRelay3') \t// boolean 0 = Off , 1 = On\n\t\t.uint8('ExpansionOutputRelay4') \t// boolean 0 = Off , 1 = On\n\t\t.int16le('ExpansionOutputPwm1') \n\t\t.int16le('ExpansionOutputPwm2') \n\t\t.uint8('ExpansionInput1') \t\t\t// boolean 0 = Off , 1 = On\n\t\t.uint8('ExpansionInput2') \t\t\t// boolean 0 = Off , 1 = On\n\t\t.uint8('ExpansionInput3') \t\t\t// boolean 0 = Off , 1 = On\n\t\t.uint8('ExpansionInput4') \t\t\t// boolean 0 = Off , 1 = On\n\t\t.uint8('ExpansionInput5') \n\t\t.int16le('ExpansionInputAIN1') \n\t\t.int16le('ExpansionInputAIN2') \n\t\t.floatle('MinBypassSession', \t\t{ formatter: (x) => {return x/1000;}}) // Ah\n\t\t.floatle('MaxBypassSession', \t\t{ formatter: (x) => {return x/1000;}}) // Ah\n\t\t.uint8('MinBypassSessionID')\n\t\t.uint8('MaxBypassSessionID')\n\t\t.uint8('RebalanceBypassExtra') \t// boolean 0 = Off , 1 = On\n\t\t.int16le('RepeatCellVoltCounter') \n\n \nmsg.payload = typea.parse(buf);\n\n// convert date(s)\nmsg.payload.SystemTime = new Date(msg.payload.SystemTime*1000);\n\n\nswitch(msg.payload.CmuPollerMode) {\n case 0:\n msg.payload.CmuPollerMode = \"Idle\";\n break;\n case 1:\n msg.payload.CmuPollerMode = \"Normal\";\n break;\n case 2:\n msg.payload.CmuPollerMode = \" Start collection\";\n break;\n case 3:\n msg.payload.CmuPollerMode = \"Collection running\";\n break;\n case 4:\n msg.payload.CmuPollerMode = \"Start synchronisation\";\n break;\n case 5:\n msg.payload.CmuPollerMode = \"Sync Running\";\n break;\n case 6:\n msg.payload.CmuPollerMode = \"Start NetworkTest\";\n break;\n case 7:\n msg.payload.CmuPollerMode = \"NetworkTest running\";\n break;\n case 8:\n msg.payload.CmuPollerMode = \"Start BypassTest\";\n break;\n case 9:\n msg.payload.CmuPollerMode = \"BypassTest running\";\n break;\n case 10:\n msg.payload.CmuPollerMode = \"Start Reboot All\";\n break;\n case 11:\n msg.payload.CmuPollerMode = \" Reboot All devices\";\n break;\n case 12:\n msg.payload.CmuPollerMode = \" Start Simulator\";\n break;\n case 13:\n msg.payload.CmuPollerMode = \"Simulator running\";\n break;\n default:\n msg.payload.CmuPollerMode = \"Buggered\";\n}\n\nswitch(msg.payload.SystemOpStatus) {\n case 0:\n msg.payload.SystemOpStatus = \"Timeout\";\n break;\n case 1:\n msg.payload.SystemOpStatus = \"Idle\";\n break;\n case 2:\n msg.payload.SystemOpStatus = \"Charging\";\n break;\n case 3:\n msg.payload.SystemOpStatus = \"Discharging\";\n break;\n case 4:\n msg.payload.SystemOpStatus = \"Full\";\n break;\n case 5:\n msg.payload.SystemOpStatus = \"Empty\";\n break;\n case 6:\n msg.payload.SystemOpStatus = \"Simulator\";\n break;\n case 7:\n msg.payload.SystemOpStatus = \"CriticalPending\";\n break;\n case 8:\n msg.payload.SystemOpStatus = \"CriticalOffline\";\n break;\n case 9:\n msg.payload.SystemOpStatus = \"MqttOffline\";\n break;\n case 10:\n msg.payload.SystemOpStatus = \"AuthSetup\";\n break;\n case 11:\n msg.payload.SystemOpStatus = \"Shunt Timeout\";\n break;\n default:\n msg.payload.SystemOpStatus = \"Buggered\";\n}\n\nswitch(msg.payload.SystemAuthMode) {\n case 0:\n msg.payload.SystemAuthMode = \"Default\";\n break;\n case 1:\n msg.payload.SystemAuthMode = \"Technician\";\n break;\n case 2:\n msg.payload.SystemAuthMode = \"Factory\";\n break;\n default:\n msg.payload.SystemAuthMode = \"Buggered\";\n}\n\nswitch(msg.payload.ShuntPollerMode) {\n case 0:\n msg.payload.ShuntPollerMode = \"Idle Start\";\n break;\n case 1:\n msg.payload.ShuntPollerMode = \"Idle\";\n break;\n case 2:\n msg.payload.ShuntPollerMode = \"Sync Start\";\n break;\n case 3:\n msg.payload.ShuntPollerMode = \"Sync Running\";\n break;\n case 4:\n msg.payload.ShuntPollerMode = \"Normal\";\n break;\n case 5:\n msg.payload.ShuntPollerMode = \"ShuntMon2 SetupStart\";\n break;\n case 6:\n msg.payload.ShuntPollerMode = \"ShuntMon2 SetupRunning\";\n break;\n case 7:\n msg.payload.ShuntPollerMode = \"ShuntMon2 Normal\";\n break;\n default:\n msg.payload.ShuntPollerMode = \"Buggered\";\n}\n\nswitch(msg.payload.ShuntStatus) {\n case 0:\n msg.payload.ShuntStatus = \"Timeout\";\n break;\n case 1:\n msg.payload.ShuntStatus = \"Discharging\";\n break;\n case 2:\n msg.payload.ShuntStatus = \"Idle\";\n break;\n case 4:\n msg.payload.ShuntStatus = \"Charging\";\n break;\n default:\n msg.payload.ShuntStatus = \"Buggered\";\n}\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 840,
"y": 640,
"wires": [
[
"ca12341f.fde6e8",
"8445ce7c.09028",
"b2ab7d4c.b3ddd",
"6476769.7ee5988",
"63dc95b5.2a2dcc",
"68635fb7.0529d"
]
]
},
{
"id": "9781b06a.53081",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Msg_415a_CellNodeStatus",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n\t\t.uint8('ID')\n .uint8('USN')\n .int16le('MinCellVolt', { formatter: (x) => {return x/1000;}})\n .int16le('MaxCellVolt', { formatter: (x) => {return x/1000;}})\n .uint8('MinCellTemp', { formatter: (x) => {return x-40;}}) // temperature ºC\n .uint8('BypassTemp', { formatter: (x) => {return x-40;}}) // temperature ºC\n .int16le('BypassAmp', { formatter: (x) => {return x/1000;}})\n .uint8('Status'); /* Choices NodeStatuses\n\t\t\t\t\t\tNone = 0,\n\t\t\t\t\t\tHighVolt = 1,\n\t\t\t\t\t\tHighTemp = 2,\n\t\t\t\t\t\tOk = 3,\n\t\t\t\t\t\tTimeout = 4,\n\t\t\t\t\t\tLowVolt = 5,\n\t\t\t\t\t\tDisabled = 6,\n\t\t\t\t\t\tInBypass = 7,\n\t\t\t\t\t\tInitialBypass = 8,\n\t\t\t\t\t\tFinalBypass = 9,\n\t\t\t\t\t\tMissingSetup = 10,\n\t\t\t\t\t\tNoConfig = 11,\n\t\t\t\t\t\tCellOutLimits = 12, */\n/*\n\t\tvar status = new Packet()\n\t\t.skip(8)\n\t\t.uint8('CmuRxOpStatusNodeID')\n\t\t.uint8('Records')\n\t\t.uint8('FirstNodeID')\n\t\t.uint8('LastNodeID')\n\t\t.array('nodes', {\n\t\t\ttype : Packet(),\n\t\t\tlength : 'Records'\n\t\t})\n*/\n \nmsg.payload = typea.parse(buf);\n\nswitch(msg.payload.Status) {\n case 0:\n msg.payload.Status = \"None\";\n break;\n case 1:\n msg.payload.Status = \"HighVolt\";\n break;\n case 2:\n msg.payload.Status = \"HighTemp\";\n break;\n case 3:\n msg.payload.Status = \"Ok\";\n break;\n case 4:\n msg.payload.Status = \"Timeout\";\n break;\n case 5:\n msg.payload.Status = \"LowVolt\";\n break;\n case 6:\n msg.payload.Status = \"Disabled\";\n break;\n case 7:\n msg.payload.Status = \"InBypass\";\n break;\n case 8:\n msg.payload.Status = \"InitialBypass\";\n break;\n case 9:\n msg.payload.Status = \"FinalBypass\";\n break;\n case 10:\n msg.payload.Status = \"MissingSetup\";\n break;\n case 11:\n msg.payload.Status = \"NoConfig\";\n break;\n case 12:\n msg.payload.Status = \"CellOutLimits\";\n break;\n default:\n msg.payload.Status = \"Buggered\";\n}\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 860,
"y": 880,
"wires": [
[
"5feebe37.b27b2"
]
]
},
{
"id": "ad8acc8c.9a174",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 1650,
"y": 960,
"wires": []
},
{
"id": "8f7d9f6b.5e7fa",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Msg_3e32_StatusRapid",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n\t\t.skip(8)\n\t\t.int16le('MinCellVolt',\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('MaxCellVolt',\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.uint8('MinCellVoltId')\n\t\t.uint8('MaxCellVoltId')\n\t\t.uint8('MinCellTemp',\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8('MaxCellTemp',\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8('MinCellTempId')\n\t\t.uint8('MaxCellTempId')\n\t\t.int16le('MinBypassAmp', \t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('MaxBypassAmp', \t{ formatter: (x) => {return x/1000;}})\n\t\t.uint8('MinBypassAmpId')\n\t\t.uint8('MaxBypassAmpId')\n\t\t.uint8('MinBypassTemp',\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8('MaxBypassTemp',\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8('MinBypassTempId',\t{ formatter: (x) => {return x-40;}})\n\t\t.uint8('MaxBypassTempId',\t{ formatter: (x) => {return x-40;}})\n\t\t.int16le('AvgCellVolt', \t{ formatter: (x) => {return x/1000;}})\n\t\t.uint8('AvgCellTemp', \t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8('NumOfCellsAboveInitialBypass')\n\t\t.uint8('NumOfCellsAboveFinalBypass')\n\t\t.uint8('NumOfCellsInBypass')\n\t\t.uint8('NumOfCellsOverdue')\n\t\t.uint8('NumOfCellsActive')\n\t\t.uint8('NumOfCellsInSystem')\n\t\t.uint8('CmuTxOpStatusId')\n\t\t.uint8('CmuRxOpStatusId')\n\t\t.uint8('CmuRxOpStatusUSN')\n\t\t.int16le('ShuntVoltage',\t{ formatter: (x) => {return x/100;}}) // voltage\n\t\t.floatle('ShuntCurrent',\t{ formatter: (x) => {return x/1000;}}) // amp\n\t\t.floatle('ShuntPowerVA',\t{ formatter: (x) => {return x/1000;}}) // kW \n\n \nmsg.payload = typea.parse(buf);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 850,
"y": 140,
"wires": [
[
"bfddb91d.2b2a98",
"b7222b59.93edf8",
"76bfaed9.eb6",
"8fce0a5e.09d718",
"ab145d35.a525d",
"739bdfbd.80809"
]
]
},
{
"id": "86897149.75de7",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Msg_4232_CellNodeFull",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n\t\t.skip(8)\n\t\t.uint8('ID')\n\t\t.uint8('USN')\n\t\t.int16le('MinCellVolt',\t\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('MaxCellVolt',\t\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.uint8('MinCellTemp',\t\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8('BypassTemp',\t\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.int16le('BypassAmp', \t\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.uint8('DataErrorCounter')\n\t\t.uint8('ResetCounter')\n\t\t.uint8('Status') /* Choices NodeStatuses\n\t\t\t\tNone = 0,\n\t\t\t\tHighVolt = 1,\n\t\t\t\tHighTemp = 2,\n\t\t\t\tOk = 3,\n\t\t\t\tTimeout = 4,\n\t\t\t\tLowVolt = 5,\n\t\t\t\tDisabled = 6,\n\t\t\t\tInBypass = 7,\n\t\t\t\tInitialBypass = 8,\n\t\t\t\tFinalBypass = 9,\n\t\t\t\tMissingSetup = 10,\n\t\t\t\tNoConfig = 11,\n\t\t\t\tCellOutLimits = 12, */\t\n\t\t.uint8('IsOverdue')\t\t\t\t// boolean 0 = Off , 1 = On\n\n\t\t.int16le('LoCellVoltAlert',\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('HiCellVoltAlert',\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('BypassVoltLevel',\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('BypassAmpLimit',\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.uint8('BypassTempLimit',\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8('HiCellTempAlert',\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8('RawVoltCalOffset')\n\t\t.int16le('FwVers')\n\t\t.int16le('HwVers')\n\t\t.int16le('BootVers')\n\t\t.uint32le('SerialNo')\t\n\t\t.uint32le('BypassInitialDate') \t// Epoch\n\t\t.floatle('BypassSessionAh',\t\t{ formatter: (x) => {return x/1000;}}) // Ah\n\t\t.uint8('RepeatCellV')\n\n \nmsg.payload = typea.parse(buf);\n\n// convert date(s)\nmsg.payload.BypassInitialDate = new Date(msg.payload.BypassInitialDate*1000);\n\n\nswitch(msg.payload.Status) {\n case 0:\n msg.payload.Status = \"None\";\n break;\n case 1:\n msg.payload.Status = \"HighVolt\";\n break;\n case 2:\n msg.payload.Status = \"HighTemp\";\n break;\n case 3:\n msg.payload.Status = \"Ok\";\n break;\n case 4:\n msg.payload.Status = \"Timeout\";\n break;\n case 5:\n msg.payload.Status = \"LowVolt\";\n break;\n case 6:\n msg.payload.Status = \"Disabled\";\n break;\n case 7:\n msg.payload.Status = \"InBypass\";\n break;\n case 8:\n msg.payload.Status = \"InitialBypass\";\n break;\n case 9:\n msg.payload.Status = \"FinalBypass\";\n break;\n case 10:\n msg.payload.Status = \"MissingSetup\";\n break;\n case 11:\n msg.payload.Status = \"NoConfig\";\n break;\n case 12:\n msg.payload.Status = \"CellOutLimits\";\n break;\n default:\n msg.payload.Status = \"Buggered\";\n}\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 850,
"y": 920,
"wires": [
[
"ad8acc8c.9a174",
"b56a71fb.69c95"
]
]
},
{
"id": "f29277f6.daa798",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 1650,
"y": 760,
"wires": []
},
{
"id": "d1133f4a.3ef44",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Msg_4932_ControlRemoteStatus",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n\t\t.skip(8)\n\t\t.uint8('CanbusRxStatusTicks') \n\t\t.uint8('CanbusRxUnknownTicks') \n\t\t.uint8('CanbusTxCmdTicks') \n\t\t.uint8( 'RemoteChargeActualCelcius', \t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.int16le('RemoteChargeTargetVolt')\n\t\t.int16le('RemoteChargeTargetAmp')\n\t\t.int16le('RemoteChargeTargetVA')\n\t\t.int16le('RemoteChargeActualVolt')\n\t\t.int16le('RemoteChargeActualAmp')\n\t\t.int16le('RemoteChargeActualVA')\n\t\t.uint32le('RemoteChargeActualFlag1')\n\t\t.uint32le('RemoteChargeActualFlag2')\n\t\t.uint32le('RemoteChargeActualRxTime') // Epoch\n\t\t.skip(1)\n\t\t.uint8( 'RemoteDishargeActualCelcius', \t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.int16le('RemoteDischargeTargetVolt')\n\t\t.int16le('RemoteDischargeTargetAmp')\n\t\t.int16le('RemoteDischargeTargetVA')\n\t\t.int16le('RemoteDischargeActualVolt')\n\t\t.int16le('RemoteDischargeActualAmp')\n\t\t.int16le('RemoteDischargeActualVA')\n\t\t.uint32le('RemoteDischargeActualFlag1')\n\t\t.uint32le('RemoteDischargeActualFlag2')\n\t\t.uint32le('RemoteDischargeActualRxTime') // Epoch\n \nmsg.payload = typea.parse(buf);\n\n// convert date(s)\nmsg.payload.RemoteChargeActualRxTime = new Date(msg.payload.RemoteChargeActualRxTime*1000);\nmsg.payload.RemoteDischargeActualRxTime = new Date(msg.payload.RemoteDischargeActualRxTime*1000);\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 880,
"y": 760,
"wires": [
[
"f29277f6.daa798"
]
]
},
{
"id": "10983267.223e1e",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 1650,
"y": 800,
"wires": []
},
{
"id": "d2fa3827.0fb158",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Msg_6131_StatusComms",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n\t\t.skip(8)\n\t\t.uint32le('SystemTime') // Epoch\n\t\t.uint8('SystemOpStatus') /* Choices\n\t\t\t\tSimulator = 0, \t // LED = rainbow pulse\n\t\t\t\tIdle = 1, \t // LED = green slow pulse\n\t\t\t\tDischarging = 2, \t // LED = green solid \n\t\t\t\tSoC Empty = 3, \t // LED = green double blink\n\t\t\t\tCharging = 4, \t // LED = blue slow pulse\n\t\t\t\tFull = 5, \t // LED = blue double blink\n\t\t\t\tTimeout = 6, \t // LED = red solid\n\t\t\t\tCritical Pending = 7, // LED = red fast pulse\n\t\t\t\tCritical Offline = 8, // LED = red slow pulse\n\t\t\t\tMqtt Offline = 9, // LED = white blink\n\t\t\t\tAuth Setup = 10, // LED = white solid\n\t\t\t\tShunt Timeout = 11, // LED = red solid \t*/\n\t\t.uint8('SystemAuthMode') /* Choices\n\t\t\t\tDefault = 0,\n\t\t\t\tTechnician = 1,\n\t\t\t\tFactory = 2, */\n\t\t.int16le('SystemAuthToken')\n\t\t.int16le('SystemAuthRejectTicks')\n\t\t.uint8('WifiState') /* Choices WifiOpStates\n\t\t\t\tBroadcast Start = 0,\n\t\t\t\tBroadcast Prep = 1,\n\t\t\t\tBroadcast TxSetup = 2,\n\t\t\t\tBroadcast Running = 3,\n\t\t\t\tUsbCmd Start = 4,\n\t\t\t\tUsbCmd Running = 5,\n\t\t\t\tUsbCmd PassThru = 6,\n\t\t\t\tUsbProg Start = 7,\n\t\t\t\tUsbProg Running = 8,\n\t\t\t\tUsbProg PassThru = 9,\n\t\t\t\tOffline Start = 10,\n\t\t\t\tOffline Running = 11,\n\t\t\t\tOffline Stop = 12,\n\t\t\t\tLimited Start = 13,\n\t\t\t\tLimited Prep = 14,\n\t\t\t\tLimited Running = 15,\n\t\t\t\tJoinAp Start = 16,\n\t\t\t\tJoinAp Running = 17,\t*/\t\t\n\t\t.uint8('WifiTxCmdTicks') \n\t\t.uint8('WifiRxCmdTicks') \n\t\t.uint8('WifiRxUnknownTicks') \n\t\t.uint8('CanbusOpStatus') /* Choices \n\t\t\t\t\n\t\t\t\t \t*/\t\t\n\t\t.uint8('CanbusRxStatusTicks')\n\t\t.uint8('CanbusRxUnknownTicks')\n\t\t.uint8('CanbusRxStatusTicks')\n\t\t.uint8('ShuntPollerMode') /* Choices ShuntPollerModes\n\t\t\t\tIdle Start = 0,\n\t\t\t\tIdle = 1,\n\t\t\t\tSync Start = 2,\n\t\t\t\tSync Running = 3,\n\t\t\t\tNormal = 4,\n\t\t\t\tShuntMon2 SetupStart = 5,\n\t\t\t\tShuntMon2 SetupRunning = 6,\n\t\t\t\tShuntMon2 Normal = 7, */\n\t\t.uint8('ShuntStatus') /* Choices ShuntStatuses\n\t\t\t\tTimeout = 0,\n\t\t\t\tDischarging = 1,\n\t\t\t\tIdle = 2,\n\t\t\t\tCharging = 4 */\n\t\t.uint8('ShuntRxAmpTicks')\n\t\t.uint8('ShuntTxAmpTicks')\n\t\t.uint8('CmuPollerMode') \t /* Choices\n\t\t\t\tIdle = 0,\n\t\t\t\tNormal = 1,\n\t\t\t\tCollection Start = 2,\n\t\t\t\tCollection Running = 3,\n\t\t\t\tSync Start = 4,\n\t\t\t\tSync Running = 5,\n\t\t\t\tNetworkTest Start = 6,\n\t\t\t\tNetworkTest Running = 9,\n\t\t\t\tBypassTest Start = 7,\n\t\t\t\tBypassTest Running = 8,\n\t\t\t\tRebootAll Start = 10,\n\t\t\t\tRebooting AllDevices = 11,\n\t\t\t\tSimulator Start = 12,\n\t\t\t\tSimulator Running = 13, */\n\t\t.uint8('CmuOpStatus') /* Choices */\n\t\t.uint8('CmuTxCmdTicks')\n\t\t\nmsg.payload = typea.parse(buf);\n\n\n// convert date(s)\nmsg.payload.SystemTime = new Date(msg.payload.SystemTime*1000);\n\nswitch(msg.payload.SystemOpStatus) {\n case 0:\n msg.payload.SystemOpStatus = \"Simulator\";\n break;\n case 1:\n msg.payload.SystemOpStatus = \"Idle\";\n break;\n case 2:\n msg.payload.SystemOpStatus = \"Discharging\";\n break;\n case 3:\n msg.payload.SystemOpStatus = \"SoC Empty\";\n break;\n case 4:\n msg.payload.SystemOpStatus = \"Charging\";\n break;\n case 5:\n msg.payload.SystemOpStatus = \"Full\";\n break;\n case 6:\n msg.payload.SystemOpStatus = \"Timeout\";\n break;\n case 7:\n msg.payload.SystemOpStatus = \"Critical Pending\";\n break;\n case 8:\n msg.payload.SystemOpStatus = \"Critical Offline\";\n break;\n case 9:\n msg.payload.SystemOpStatus = \"Mqtt Offline\";\n break;\n case 10:\n msg.payload.SystemOpStatus = \"Auth Setup\";\n break;\n case 11:\n msg.payload.SystemOpStatus = \"Shunt Timeout\";\n break;\n default:\n msg.payload.SystemOpStatus = \"Buggered\";\n}\n\nswitch(msg.payload.SystemAuthMode) {\n case 0:\n msg.payload.SystemAuthMode = \"Default\";\n break;\n case 1:\n msg.payload.SystemAuthMode = \"Technician\";\n break;\n case 2:\n msg.payload.SystemAuthMode = \"Factory\";\n break;\n default:\n msg.payload.SystemAuthMode = \"Buggered\";\n}\n\nswitch(msg.payload.WifiState) {\n case 0:\n msg.payload.WifiState = \"Broadcast Start\";\n break;\n case 1:\n msg.payload.WifiState = \"Broadcast Prep\";\n break;\n case 2:\n msg.payload.WifiState = \"Broadcast TxSetup\";\n break;\n case 3:\n msg.payload.WifiState = \"Broadcast Running\";\n break;\n case 4:\n msg.payload.WifiState = \"UsbCmd Start\";\n break;\n case 5:\n msg.payload.WifiState = \"UsbCmd Running\";\n break;\n case 6:\n msg.payload.WifiState = \"UsbCmd PassThru\";\n break;\n case 7:\n msg.payload.WifiState = \"UsbProg Start\";\n break;\n case 8:\n msg.payload.WifiState = \"UsbProg Running\";\n break;\n case 9:\n msg.payload.WifiState = \"UsbProg PassThru\";\n break;\n case 10:\n msg.payload.WifiState = \"Offline Start\";\n break;\n case 11:\n msg.payload.WifiState = \"Offline Running\";\n break;\n case 12:\n msg.payload.WifiState = \"Offline Stop\";\n break;\n case 13:\n msg.payload.WifiState = \"Limited Start\";\n break;\n case 14:\n msg.payload.WifiState = \"Limited Prep\";\n break;\n case 15:\n msg.payload.WifiState = \"Limited Running\";\n break;\n case 16:\n msg.payload.WifiState = \"JoinAp Start\";\n break;\n case 17:\n msg.payload.WifiState = \"JoinAp Running\";\n break;\n default:\n msg.payload.WifiState = \"Buggered\";\n}\n\nswitch(msg.payload.ShuntPollerMode) {\n case 0:\n msg.payload.ShuntPollerMode = \"Idle Start\";\n break;\n case 1:\n msg.payload.ShuntPollerMode = \"Idle\";\n break;\n case 2:\n msg.payload.ShuntPollerMode = \"Sync Start\";\n break;\n case 3:\n msg.payload.ShuntPollerMode = \"Sync Running\";\n break;\n case 4:\n msg.payload.ShuntPollerMode = \"Normal\";\n break;\n case 5:\n msg.payload.ShuntPollerMode = \"ShuntMon2 SetupStart\";\n break;\n case 6:\n msg.payload.ShuntPollerMode = \"ShuntMon2 SetupRunning\";\n break;\n case 7:\n msg.payload.ShuntPollerMode = \"ShuntMon2 Normal\";\n break;\n default:\n msg.payload.ShuntPollerMode = \"Buggered\";\n}\n\nswitch(msg.payload.ShuntStatus) {\n case 0:\n msg.payload.ShuntStatus = \"Timeout\";\n break;\n case 1:\n msg.payload.ShuntStatus = \"Discharging\";\n break;\n case 2:\n msg.payload.ShuntStatus = \"Idle\";\n break;\n case 4:\n msg.payload.ShuntStatus = \"Charging\";\n break;\n default:\n msg.payload.ShuntStatus = \"Buggered\";\n}\n\nswitch(msg.payload.CmuPollerMode) {\n case 0:\n msg.payload.CmuPollerMode = \"Idle\";\n break;\n case 1:\n msg.payload.CmuPollerMode = \"Normal\";\n break;\n case 2:\n msg.payload.CmuPollerMode = \"Collection Start\";\n break;\n case 3:\n msg.payload.CmuPollerMode = \"Collection Running\";\n break;\n case 4:\n msg.payload.CmuPollerMode = \"Sync Start\";\n break;\n case 5:\n msg.payload.CmuPollerMode = \"Sync Running\";\n break;\n case 6:\n msg.payload.CmuPollerMode = \"NetworkTest Start\";\n break;\n case 7:\n msg.payload.CmuPollerMode = \"NetworkTest Running\";\n break;\n case 8:\n msg.payload.CmuPollerMode = \"BypassTest Start\";\n break;\n case 9:\n msg.payload.CmuPollerMode = \"BypassTest Running\";\n break;\n case 10:\n msg.payload.CmuPollerMode = \"RebootAll Start\";\n break;\n case 11:\n msg.payload.CmuPollerMode = \"Rebooting AllDevices\";\n break;\n case 12:\n msg.payload.CmuPollerMode = \"Simulator Start\";\n break;\n case 13:\n msg.payload.CmuPollerMode = \"Simulator Running\";\n break;\n default:\n msg.payload.CmuPollerMode = \"Buggered\";\n}\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 850,
"y": 800,
"wires": [
[
"10983267.223e1e"
]
]
},
{
"id": "3b6043f2.c8f11c",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 1650,
"y": 380,
"wires": []
},
{
"id": "40d3fdc.2a54504",
"type": "function",
"z": "e6fd3a1c.5e9548",
"d": true,
"name": "Msg_5732_SystemDiscovery",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n\t\t.skip(8)\n\t\t.string('SystemCode', \t{ encoding: 'ascii', length: 8 })\n\t\t.int16le('SystemFirmwareVersion')\n\t\t.int16le('SystemHardwareVersion')\n\t\t.int32le('SystemTime') // Epoch\n\t\t.uint8('SystemOpStatus') /* Choices\n\t\t\t\tSimulator = 0, \t // LED = rainbow pulse\n\t\t\t\tIdle = 1, \t // LED = green slow pulse\n\t\t\t\tDischarging = 2, \t // LED = green solid \n\t\t\t\tSoC Empty = 3, \t // LED = green double blink\n\t\t\t\tCharging = 4, \t // LED = blue slow pulse\n\t\t\t\tFull = 5, \t // LED = blue double blink\n\t\t\t\tTimeout = 6, \t // LED = red solid\n\t\t\t\tCritical Pending = 7, // LED = red fast pulse\n\t\t\t\tCritical Offline = 8, // LED = red slow pulse\n\t\t\t\tMqtt Offline = 9, // LED = white blink\n\t\t\t\tAuth Setup = 10, // LED = white solid\n\t\t\t\tShunt Timeout = 11, // LED = red solid \t*/\n\t\t.uint8('SystemAuthMode') /* Choices\n\t\t\t\tDefault \t= 0,\n\t\t\t\tTechnician \t= 1,\n\t\t\t\tFactory \t= 2, */\n\t\t.uint8('CriticalBatOkState') // 0 = Off , 1 = On\n\t\t.uint8('ChargePowerRateState') /* Choices\n\t\t\t\tOff \t\t\t= 0,\n\t\t\t\tLimited Power \t= 2,\n\t\t\t\tNormal Power \t= 4, */\n\t\t.uint8('DischargePowerRateState') /* Choices\n\t\t\t\tOff \t\t\t= 0,\n\t\t\t\tLimited Power \t= 2,\n\t\t\t\tNormal Power \t= 4, */\n\t\t.uint8('HeatOnState') \t\t\t// 0 = Off , 1 = On\n\t\t.uint8('CoolOnState') \t\t\t// 0 = Off , 1 = On\n\t\t.int16le('MinCellVolt', \t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('MaxCellVolt', \t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('AvgCellVolt', \t{ formatter: (x) => {return x/1000;}})\n\t\t.uint8('MinCellTemp', \t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8('NumOfCellsActive')\n\t\t.uint8('CmuRxOpStatusUSN')\n\t\t.uint8('CmuPollerMode') /* Choices\n\t\t\t\tIdle = 0,\n\t\t\t\tNormal = 1,\n\t\t\t\tCollection Start = 2,\n\t\t\t\tCollection Running = 3,\n\t\t\t\tSync Start = 4,\n\t\t\t\tSync Running = 5,\n\t\t\t\tNetworkTest Start = 6,\n\t\t\t\tNetworkTest Running = 9,\n\t\t\t\tBypassTest Start = 7,\n\t\t\t\tBypassTest Running = 8,\n\t\t\t\tRebootAll Start = 10,\n\t\t\t\tRebooting AllDevices = 11,\n\t\t\t\tSimulator Start = 12,\n\t\t\t\tSimulator Running = 13, */\n\t\t.uint8('ShuntSOC',\t\t\t{ formatter: (x) => {return x/2-5;}}) // percent\n\t\t.int16le('ShuntVoltage',\t{ formatter: (x) => {return x/100;}})\n\t\t.floatle('ShuntCurrent',\t{ formatter: (x) => {return x/1000;}})\n\t\t.uint8('ShuntStatus') /* Choices\n\t\t\t\tTimeout = 0,\n\t\t\t\tDischarging = 1,\n\t\t\t\tIdle = 2,\n\t\t\t\tCharging = 4 */\n\t\t.uint8('ShuntRxAmpTicks')\n \nmsg.payload = typea.parse(buf);\n\n// convert date(s)\nmsg.payload.SystemTime = new Date(msg.payload.SystemTime*1000);\n\nswitch(msg.payload.SystemOpStatus) {\n case 0:\n msg.payload.SystemOpStatus = \"Timeout\";\n break;\n case 1:\n msg.payload.SystemOpStatus = \"Idle\";\n break;\n case 2:\n msg.payload.SystemOpStatus = \"Charging\";\n break;\n case 3:\n msg.payload.SystemOpStatus = \"Discharging\";\n break;\n case 4:\n msg.payload.SystemOpStatus = \"Full\";\n break;\n case 5:\n msg.payload.SystemOpStatus = \"Empty\";\n break;\n case 6:\n msg.payload.SystemOpStatus = \"Simulator\";\n break;\n case 7:\n msg.payload.SystemOpStatus = \"CriticalPending\";\n break;\n case 8:\n msg.payload.SystemOpStatus = \"CriticalOffline\";\n break;\n case 9:\n msg.payload.SystemOpStatus = \"MqttOffline\";\n break;\n case 10:\n msg.payload.SystemOpStatus = \"AuthSetup\";\n break;\n case 11:\n msg.payload.SystemOpStatus = \"Shunt Timeout\";\n break;\n default:\n msg.payload.SystemOpStatus = \"Buggered\";\n}\n\nswitch(msg.payload.SystemAuthMode) {\n case 0:\n msg.payload.SystemAuthMode = \"Default\";\n break;\n case 1:\n msg.payload.SystemAuthMode = \"Technician\";\n break;\n case 2:\n msg.payload.SystemAuthMode = \"Factory\";\n break;\n default:\n msg.payload.SystemAuthMode = \"Buggered\";\n}\n\nswitch(msg.payload.ChargePowerRateState) {\n case 0:\n msg.payload.ChargePowerRateState = \"Off\";\n break;\n case 2:\n msg.payload.ChargePowerRateState = \"Limited Power\";\n break;\n case 4:\n msg.payload.ChargePowerRateState = \"Normal Power\";\n break;\n default:\n msg.payload.ChargePowerRateState = \"Buggered\";\n}\n\nswitch(msg.payload.DischargePowerRateState) {\n case 0:\n msg.payload.DischargePowerRateState = \"Off\";\n break;\n case 2:\n msg.payload.DischargePowerRateState = \"Limited Power\";\n break;\n case 4:\n msg.payload.DischargePowerRateState = \"Normal Power\";\n break;\n default:\n msg.payload.DischargePowerRateState = \"Buggered\";\n}\n\nswitch(msg.payload.CmuPollerMode) {\n case 0:\n msg.payload.CmuPollerMode = \"Idle\";\n break;\n case 1:\n msg.payload.CmuPollerMode = \"Normal\";\n break;\n case 2:\n msg.payload.CmuPollerMode = \" Start collection\";\n break;\n case 3:\n msg.payload.CmuPollerMode = \"Collection running\";\n break;\n case 4:\n msg.payload.CmuPollerMode = \"Start synchronisation\";\n break;\n case 5:\n msg.payload.CmuPollerMode = \"Sync Running\";\n break;\n case 6:\n msg.payload.CmuPollerMode = \"Start NetworkTest\";\n break;\n case 7:\n msg.payload.CmuPollerMode = \"NetworkTest running\";\n break;\n case 8:\n msg.payload.CmuPollerMode = \"Start BypassTest\";\n break;\n case 9:\n msg.payload.CmuPollerMode = \"BypassTest running\";\n break;\n case 10:\n msg.payload.CmuPollerMode = \"Start Reboot All\";\n break;\n case 11:\n msg.payload.CmuPollerMode = \" Reboot All devices\";\n break;\n case 12:\n msg.payload.CmuPollerMode = \" Start Simulator\";\n break;\n case 13:\n msg.payload.CmuPollerMode = \"Simulator running\";\n break;\n default:\n msg.payload.CmuPollerMode = \"Buggered\";\n}\n\nswitch(msg.payload.ShuntStatus) {\n case 0:\n msg.payload.ShuntStatus = \"Timeout\";\n break;\n case 1:\n msg.payload.ShuntStatus = \"Discharging\";\n break;\n case 2:\n msg.payload.ShuntStatus = \"Idle\";\n break;\n case 4:\n msg.payload.ShuntStatus = \"Charging\";\n break;\n default:\n msg.payload.ShuntStatus = \"Buggered\";\n}\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 860,
"y": 380,
"wires": [
[
"3b6043f2.c8f11c"
]
]
},
{
"id": "e321fbb8.b60e48",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 1650,
"y": 420,
"wires": []
},
{
"id": "6ba51319.a7a48c",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Msg_4032_StatusSlow",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n \t\t.skip(8)\n\t\t.uint32le('SystemTime') \t\t\t// Epoch\n\t\t.uint8('IsProcessControl') \t\t\t// boolean 0 = Off , 1 = On\n\t\t.uint8('IsInitialStartup') \t\t\t// boolean 0 = Off , 1 = On\n\t\t.uint8('IgnoreWhenCellsOverdue') \t// boolean 0 = Off , 1 = On\n\t\t.uint8('IgnoreWhenShuntsOverdue') \t// boolean 0 = Off , 1 = On\n\t\t.uint8('MonitorDailySessionStats') \t// boolean 0 = Off , 1 = On\t\t\n\t\t.uint8('HwSystemSetupVers') \n\t\t.uint8('HwCellmonSetupVers') \n\t\t.uint8('HwShuntSetupVers') \n\t\t.uint8('HwExpansionSetupVers') \n\t\t.uint8('HwIntegrationSetupVers') \n\t\t.uint8('ControlCriticalSetupVers') \n\t\t.uint8('ControlChargeSetupVers') \n\t\t.uint8('ControlDischargeSetupVers') \t\t\n\t\t.uint8('ControlThermalSetupVers') \n\t\t.uint8('ControlRemoteSetupVers') \n\t\t.uint8('ControlSchedulerSetupVers') \t\t\t\n\t\t.int16le('EstDurationToFullmins') \n\t\t.int16le('EstDurationToEmptymins') \n\t\t.floatle('ShuntAcculmAvgCharge',\t{ formatter: (x) => {return x/1000;}}) // Ah\n\t\t.floatle('ShuntAcculmAvgDischg',\t{ formatter: (x) => {return x/1000;}}) // Ah\n\t\t.floatle('ShuntAcculmAvgNett',\t\t{ formatter: (x) => {return x/1000;}}) // Ah\n\t\t.uint8( 'hasShuntSocCountLo') \t\t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'hasShuntSocCountHi') \t\t// boolean 0 = Off , 1 = On\t\t\n\t\t.uint32le('QuickSessRecentTime') \t// EPOCH\n\t\t.int16le('QuickSessNumOfRecords')\n\t\t.int16le('QuickSessMaxNumOfRecords')\n\t\t.skip(8) // acculmNett ADC counter \n\t\t.floatle('NomCapacityToEmpty',\t\t{ formatter: (x) => {return x/1000;}}) // Ah\n\t\t\nmsg.payload = typea.parse(buf);\n// convert date(s)\nmsg.payload.SystemTime = new Date(msg.payload.SystemTime*1000);\nmsg.payload.QuickSessRecentTime = new Date(msg.payload.QuickSessRecentTime*1000);\n\n\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 840,
"y": 420,
"wires": [
[
"e321fbb8.b60e48",
"9a44bb7a.474bd8"
]
]
},
{
"id": "9a3c0c25.d705a",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 1650,
"y": 500,
"wires": []
},
{
"id": "1704d7ce.245b58",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Msg_5432_DailySession",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n\t\t.skip(8)\n\t\t.int16le('DailySessionMinCellVolt',\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('DailySessionMaxCellVolt',\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('DailySessionMinSupplyVolt',\t{ formatter: (x) => {return x/100;}})\n\t\t.int16le('DailySessionMaxSupplyVolt',\t{ formatter: (x) => {return x/100;}})\n\t\t.uint8('DailySessionMinReportTemp',\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8('DailySessionMaxReportTemp',\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.int16le('DailySessionMinShuntVolt',\t{ formatter: (x) => {return x/100;}})\n\t\t.int16le('DailySessionMaxShuntVolt',\t{ formatter: (x) => {return x/100;}})\n\t\t.uint8('DailySessionMinShuntSoc', \t\t{ formatter: (x) => {return (x-5)/2;}}) // percent\n\t\t.uint8('DailySessionMaxShuntSoc', \t\t{ formatter: (x) => {return (x-5)/2;}}) // percent\n\t\t.uint8('DailySessionThermalBandA',\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionThermalBandB',\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionThermalBandC',\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionThermalBandD',\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionThermalBandE',\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionThermalBandF',\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionThermalBandG',\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionThermalBandH',\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionSocBandA',\t\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionSocBandB',\t\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionSocBandC',\t\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionSocBandD',\t\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionSocBandE',\t\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionSocBandF',\t\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionSocBandG',\t\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionSocBandH',\t\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.int16le('DailySessionShuntPeakCharge',{ formatter: (x) => {return x/100;}}) // amps\n\t\t.int16le('DailySessionShuntPeakDischg',{ formatter: (x) => {return x/100;}}) // amps\n\t\t.uint8('DailySessionCriticalEvents')\n\t\t.int32le('DailySessionStartTime') \t// Epoch\n\t\t.int32le('DailySessionFinishTime') // Epoch\n\t\t.floatle('DailySessionCumulShuntAhCharge',{ formatter: (x) => {return x/1000;}}) // Ah\n\t\t.floatle('DailySessionCumulShuntAhDischg',{ formatter: (x) => {return x/1000;}}) // Ah\n\t\t.floatle('DailySessionCumulShuntkWhCharge',{ formatter: (x) => {return x/1000;}}) // kWh\n\t\t.floatle('DailySessionCumulShuntkWhDischg',{ formatter: (x) => {return x/1000;}}) // kWh\n\t\t\n \nmsg.payload = typea.parse(buf);\n\n// convert date(s)\nmsg.payload.DailySessionStartTime = new Date(msg.payload.DailySessionStartTime*1000);\nmsg.payload.DailySessionFinishTime = new Date(msg.payload.DailySessionFinishTime*1000);\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 850,
"y": 500,
"wires": [
[
"9a3c0c25.d705a",
"684ac7ee.c50fc8",
"7e92a896.171e58"
]
]
},
{
"id": "122c8b3f.160005",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Msg_5632_LifetimeMetrics",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n\t\t.skip(8)\n\t\t.uint32le('FirstSyncTime') \t\t\t// Epoch\n\t\t.uint32le('LifeCountStartup') \n\t\t.uint32le('LifeCountCriticalBattOk') \n\t\t.uint32le('LifeCountChargeOn') \n\t\t.uint32le('LifeCountChargeLimp') \n\t\t.uint32le('LifeCountDischgOn') \n\t\t.uint32le('LifeCountDischgLimp') \n\t\t.uint32le('LifeCountHeatOn') \n\t\t.uint32le('LifeCountCoolOn') \n\t\t.int16le( 'LifeCountDailySession') \n\t\t.uint32le('RecentTimeCriticalOn') \t// Epoch\n\t\t.uint32le('RecentTimeCriticalOff') \t// Epoch\n\t\t.uint32le('RecentTimeChargeOn') \t// Epoch\n\t\t.uint32le('RecentTimeChargeOff') \t// Epoch\n\t\t.uint32le('RecentTimeChargeLimp') \t// Epoch\n\t\t.uint32le('RecentTimeDischgOn') \t// Epoch\n\t\t.uint32le('RecentTimeDischgOff') \t// Epoch\n\t\t.uint32le('RecentTimeDischgLimp') \t// Epoch\n\t\t.uint32le('RecentTimeHeatOn') \t\t// Epoch\n\t\t.uint32le('RecentTimeHeatOff') \t\t// Epoch\n\t\t.uint32le('RecentTimeCoolOn') \t\t// Epoch\n\t\t.uint32le('RecentTimeCoolOff') \t\t// Epoch\n\t\t.uint32le('RecentTimeBypassInitial') // Epoch\n\t\t.uint32le('RecentTimeBypassComplete') // Epoch\n\t\t.uint32le('RecentTimeBypassTest') \t// Epoch\n\t\t.uint8('SystemBypassTestOutcome') /* Choices BypassTestOutcomes\n\t\t\tNotTested = 0,\n\t\t\tPreparing = 1,\n\t\t\tTesting = 2,\n\t\t\tPassOk = 3,\n\t\t\tFailed = 4, */\n\t\t.uint32le('RecentTimeWizardSetup') // Epoch\n\t\t.uint32le('RecentTimeBypassExtra') // Epoch\n\n \nmsg.payload = typea.parse(buf);\n\n// convert date(s)\nmsg.payload.FirstSyncTime = new Date(msg.payload.FirstSyncTime*1000);\nmsg.payload.RecentTimeCriticalOn = new Date(msg.payload.RecentTimeCriticalOn*1000);\nmsg.payload.RecentTimeCriticalOff = new Date(msg.payload.RecentTimeCriticalOff*1000);\nmsg.payload.RecentTimeChargeOn = new Date(msg.payload.RecentTimeChargeOn*1000);\nmsg.payload.RecentTimeChargeOff = new Date(msg.payload.RecentTimeChargeOff*1000);\nmsg.payload.RecentTimeChargeLimp = new Date(msg.payload.RecentTimeChargeLimp*1000);\nmsg.payload.RecentTimeDischgOn = new Date(msg.payload.RecentTimeDischgOn*1000);\nmsg.payload.RecentTimeDischgOff = new Date(msg.payload.RecentTimeDischgOff*1000);\nmsg.payload.RecentTimeDischgLimp = new Date(msg.payload.RecentTimeDischgLimp*1000);\nmsg.payload.RecentTimeHeatOn = new Date(msg.payload.RecentTimeHeatOn*1000);\nmsg.payload.RecentTimeHeatOff = new Date(msg.payload.RecentTimeHeatOff*1000);\nmsg.payload.RecentTimeCoolOn = new Date(msg.payload.RecentTimeCoolOn*1000);\nmsg.payload.RecentTimeCoolOff = new Date(msg.payload.RecentTimeCoolOff*1000);\nmsg.payload.RecentTimeBypassInitial = new Date(msg.payload.RecentTimeBypassInitial*1000);\nmsg.payload.RecentTimeBypassComplete = new Date(msg.payload.RecentTimeBypassComplete*1000);\nmsg.payload.RecentTimeBypassTest = new Date(msg.payload.RecentTimeBypassTest*1000);\nmsg.payload.RecentTimeWizardSetup = new Date(msg.payload.RecentTimeWizardSetup*1000);\nmsg.payload.RecentTimeBypassExtra = new Date(msg.payload.RecentTimeBypassExtra*1000);\n\nswitch(msg.payload.SystemBypassTestOutcome) {\n case 0:\n msg.payload.SystemBypassTestOutcome = \"NotTested\";\n break;\n case 1:\n msg.payload.SystemBypassTestOutcome = \"Preparing\";\n break;\n case 2:\n msg.payload.SystemBypassTestOutcome = \"Testing\";\n break;\n case 3:\n msg.payload.SystemBypassTestOutcome = \"PassOk\";\n break;\n case 4:\n msg.payload.SystemBypassTestOutcome = \"Failed\";\n break;\n default:\n msg.payload.SystemBypassTestOutcome = \"Buggered\";\n}\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 120,
"y": 620,
"wires": [
[
"dbbeb1bd.5221"
]
]
},
{
"id": "dbbeb1bd.5221",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 390,
"y": 620,
"wires": []
},
{
"id": "bc35aeeb.93ab7",
"type": "function",
"z": "e6fd3a1c.5e9548",
"d": true,
"name": "Msg_4a35_HwSystemSetup",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n\t\t.skip(8)\n\t\t.int16le('HwSystemSetupVers')\n\t\t.string('SystemCode', \t{ encoding: 'ascii', length: 8 })\n\t\t.string('SysName', \t\t{ encoding: 'ascii', length: 20 })\n\t\t.string('AssetCode', \t{ encoding: 'ascii', length: 20 })\n\t\t.uint8('AllowTechAuth') \t\t// boolean 0 = Off , 1 = On\n\t\t.uint8('AllowQuickSession') \t// boolean 0 = Off , 1 = On\n\t\t.uint32le('QuickSessionInterval', { formatter: (x) => {return x/1000;}}) // seconds\n\t\t.int16le('SystemPresetId')\n\t\t.int16le('SystemFirmwareVersion')\n\t\t.int16le('SystemHardwareVersion')\n\t\t.uint32le('SystemSerialNo')\n\t\t.uint8('ShowScheduler') \t\t// boolean 0 = Off , 1 = On\n\t\t.uint8('ShowStripCycle') \t\t// boolean 0 = Off , 1 = On\n\t\t\nmsg.payload = typea.parse(buf);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 120,
"y": 660,
"wires": [
[
"ecea2916.d52128"
]
]
},
{
"id": "ecea2916.d52128",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 390,
"y": 660,
"wires": []
},
{
"id": "a7cdb5ee.7c66c8",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Msg_4d33_HwExpansionSetup",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n\t\t.skip(8)\n\t\t.uint8('HwExpansionSetupVers') \n\t\t.uint8('HwExpansionTemplate') /* ExtensionTemplateOptions\n\t\t\t\tNone = 0,\n\t\t\t\tExpansionBoard 12v = 1,\n\t\t\t\tExpansionBoard 48v = 2,\n\t\t\t\tWatchMonCmC v2.0 = 3,\t*/\t\n\t\t.uint8('HwExpansionNeoPixelMode') /* NeoPixelExtStatusModes\n\t\t\t\tNone \t\t\t\t= 0,\n\t\t\t\tRepeat \t\t\t\t= 1,\n\t\t\t\tStatus + 7seg SoC% \t= 2,\n\t\t\t\tSolid SoC% 8seg \t= 3,\t*/\n\t\t.uint8('HwExpansionRelay1') /* ExpansionOutputAssignments\n\t\t\t\tNone = 0,\n\t\t\t\tManualOn = 1,\n\t\t\t\tCritical BattOk = 2,\n\t\t\t\tCharging On = 4,\n\t\t\t\tDischarging On = 5,\n\t\t\t\tHeating Required = 6,\n\t\t\t\tCooling Required = 7,\n\t\t\t\tRun / Idle input = 8,\n\t\t\t\tCharge / Normal input = 9,\n\t\t\t\tBypass Complete = 10,\n\t\t\t\tCharging Limited = 11,\n\t\t\t\tDischarging Limited = 12,\n\t\t\t\tCritical Recovery = 13,\n\t\t\t\tCritical PulseOn = 14,\n\t\t\t\tCritical PulseOff = 15,\n\t\t\t\tCritical Fault = 16,\n\t\t\t\tCritical PrechargeTimer = 17, */\n\t\t.uint8('HwExpansionRelay2') \t/* ExpansionOutputAssignments */\n\t\t.uint8('HwExpansionRelay3') \t/* ExpansionOutputAssignments */\n\t\t.uint8('HwExpansionRelay4')\t\t/* ExpansionOutputAssignments */\n\t\t.uint8('HwExpansionOutput5') \t/* ExpansionOutputAssignments */\n\t\t.uint8('HwExpansionOutput5') \t/* ExpansionOutputAssignments */\n\t\t.uint8('HwExpansionOutput7') \t/* ExpansionOutputAssignments */\n\t\t.uint8('HwExpansionOutput8') \t/* ExpansionOutputAssignments */\n\t\t.uint8('HwExpansionOutput9') \t/* ExpansionOutputAssignments */\n\t\t.uint8('HwExpansionOutput10') \t/* ExpansionOutputAssignments */\n\t\t.uint8('HwExpansionInput1') \t/* ExtensionInputOptions\n\t\t\t\tNone \t\t\t\t\t= 0,\n\t\t\t\tRun / Idle mode \t\t= 1,\n\t\t\t\tCharge / Normal mode \t= 2,\n\t\t\t\tCritical contact sensor - On = 3,\n\t\t\t\tCritical contact sensor - Fault = 4, */\n\t\t.uint8('HwExpansionInput2') \t/* ExtensionInputOptions */\n\t\t.uint8('HwExpansionInput3') \t/* ExtensionInputOptions */\n\t\t.uint8('HwExpansionInput4') \t/* ExtensionInputOptions */\n\t\t.uint8('HwExpansionInput5') \t/* ExtensionInputOptions */\n\t\t.uint8('HwExpansionInputAIN1') \n\t\t.uint8('HwExpansionInputAIN2') \n\t\t.int16le('HwExpansionCustomFeature1')\n\t\t.int16le('HwExpansionCustomFeature2')\n\n \nmsg.payload = typea.parse(buf);\n\n\nswitch(msg.payload.HwExpansionTemplate) {\n case 0:\n msg.payload.HwExpansionTemplate = \"None\";\n break;\n case 1:\n msg.payload.HwExpansionTemplate = \"ExpansionBoard 12v\";\n break;\n case 2:\n msg.payload.HwExpansionTemplate = \"ExpansionBoard 48v\";\n break;\n case 3:\n msg.payload.HwExpansionTemplate = \"WatchMonCmC v2.0\";\n break;\n default:\n msg.payload.HwExpansionTemplate = \"Buggered\";\n}\n\nswitch(msg.payload.HwExpansionNeoPixelMode) {\n case 0:\n msg.payload.HwExpansionNeoPixelMode = \"None\";\n break;\n case 1:\n msg.payload.HwExpansionNeoPixelMode = \"Repeat\";\n break;\n case 2:\n msg.payload.HwExpansionNeoPixelMode = \"Status + 7seg SoC%\";\n break;\n case 3:\n msg.payload.HwExpansionNeoPixelMode = \"Solid SoC% 8seg\";\n break;\n default:\n msg.payload.HwExpansionNeoPixelMode = \"Buggered\";\n}\n\nswitch(msg.payload.HwExpansionRelay1) {\n case 0:\n msg.payload.HwExpansionRelay1 = \"None\";\n break;\n case 1:\n msg.payload.HwExpansionRelay1 = \"ManualOn\";\n break;\n case 2:\n msg.payload.HwExpansionRelay1 = \"Critical BattOk\";\n break;\n case 3:\n msg.payload.HwExpansionRelay1 = \"Charging On\";\n break;\n case 4:\n msg.payload.HwExpansionRelay1 = \"Discharging On\";\n break;\n case 5:\n msg.payload.HwExpansionRelay1 = \"Heating Required\";\n break;\n case 6:\n msg.payload.HwExpansionRelay1 = \"Cooling Required\";\n break;\n case 7:\n msg.payload.HwExpansionRelay1 = \"Run / Idle input\";\n break;\n case 8:\n msg.payload.HwExpansionRelay1 = \"Charge / Normal input\";\n break;\n case 9:\n msg.payload.HwExpansionRelay1 = \"Bypass Complete\";\n break;\n case 10:\n msg.payload.HwExpansionRelay1 = \"Charging Limited\";\n break;\n case 11:\n msg.payload.HwExpansionRelay1 = \"Discharging Limited\";\n break;\n case 12:\n msg.payload.HwExpansionRelay1 = \"Critical Recovery\";\n break;\n case 13:\n msg.payload.HwExpansionRelay1 = \"Critical PulseOn\";\n break;\n case 14:\n msg.payload.HwExpansionRelay1 = \"Critical PulseOff\";\n break;\n case 105:\n msg.payload.HwExpansionRelay1 = \"Critical Fault\";\n break;\n case 16:\n msg.payload.HwExpansionRelay1 = \"Critical PrechargeTimer\";\n break;\n default:\n msg.payload.HwExpansionRelay1 = \"Buggered\";\n}\n\nswitch(msg.payload.HwExpansionInput1) {\n case 0:\n msg.payload.HwExpansionInput1 = \"None\";\n break;\n case 1:\n msg.payload.HwExpansionInput1 = \"Run / Idle mode\";\n break;\n case 2:\n msg.payload.HwExpansionInput1 = \"Charge / Normal mode\";\n break;\n case 3:\n msg.payload.HwExpansionInput1 = \"Critical contact sensor - On\";\n break;\n case 4:\n msg.payload.HwExpansionInput1 = \"Critical contact sensor - Fault\";\n break;\n default:\n msg.payload.HwExpansionInput1 = \"Buggered\";\n}\n\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 130,
"y": 780,
"wires": [
[
"1b2080a0.f3533f"
]
]
},
{
"id": "1b2080a0.f3533f",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 390,
"y": 780,
"wires": []
},
{
"id": "31f8d71a.f97f68",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Msg_4b35_HwCellGroupSetup",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n\t\t.skip(8)\n\t\t.uint8('HwCellmonSetupVers') \n\t\t.uint8('HwCellmonBattTypeID') /* BattTypes\n\t\t\t\tCustom \t\t\t\t= 0,\n\t\t\t\tLi-FePO4 Typical \t= 1,\n\t\t\t\tLi-Ion Performance \t= 2,\n\t\t\t\tLi-Ion LongLife \t= 3, \n\t\t\t\tLi-FePO4 Longlife \t= 4, */\n\t\t.uint8( 'HwCellmonFirstID') \n\t\t.uint8( 'HwCellmonLastID') \t\n\t\t.int16le('HwCellmonNomCellVolt', \t\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('HwCellmonLoCellVolt', \t\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('HwCellmonHiCellVolt',\t\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('HwCellmonBypassVoltLevel',\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('HwCellmonBypassAmpLimit', \t{ formatter: (x) => {return x/1000;}})\n\t\t.uint8( 'HwCellmonBypassTempLimit',\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8( 'HwCellmonLoCellTemp',\t\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8( 'HwCellmonHiCellTemp',\t\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8( 'HwCellmonDiffNomCellsInSeries') \t// Boolean 0 = Off , 1 = On\n\t\t.uint8( 'HwCellmonNomCellsInSeries') \n\t\t.uint8( 'HwCellmonAllowEntireRange') \t\t// Boolean 0 = Off , 1 = On\n\t\t.uint8( 'HwCellmonEntireFirstID') \n\t\t.uint8( 'HwCellmonEntireLastID') \n\t\t.uint8( 'HwCellmonBypassExtraMode') /* BypassExtraModes\n\t\t\t\tNone \t\t\t= 0,\n\t\t\t\tIdle Shunt \t\t= 1,\n\t\t\t\tSame CellVolt \t= 2,\n\t\t\t\tAutoLevel \t\t= 3, */\n\t\t.int16le('HwCellmonBypassExtraInterval',\t\t{ formatter: (x) => {return x/1000;}}) \t// seconds\n\t\t.uint8( 'HwCellmonCellMonTypeID') /* CellMonTypes\n\t\t\t\tCustom \t\t= 0,\n\t\t\t\tGenMon 2W \t= 1,\n\t\t\t\tGenMon 8W \t= 2,\n\t\t\t\tLongMon \t= 3,\n\t\t\t\tBlockMonM8 \t= 4,\n\t\t\t\tBlockMonM14 = 5,\n\t\t\t\tEndMon \t\t= 6,\n\t\t\t\tManyMon \t= 7, */\n\t\t.floatle('HwCellmonBypassImpedance', \t\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('HwCellmonBypassLoVoltCutout', \t\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('HwCellmonBypassShuntChargeLimit', \t{ formatter: (x) => {return x/100;}}) \t// amps\n\t\t.int16le('HwCellmonBypassShuntDischgLimit', \t{ formatter: (x) => {return x/100;}}) \t// amps\n\t\t.uint8( 'HwCellmonBypassShuntSocLo', \t\t\t{ formatter: (x) => {return (x-5)/2;}}) // percent\n\t\t.int16le('HwCellmonBypassCellVoltBanding', \t\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('HwCellmonBypassCellVoltDiff', \t\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('HwCellmonBypassStableInterval',\t\t{ formatter: (x) => {return x/1000;}}) // seconds\n\t\t.int16le('HwCellmonBypassExtraAmpLimit', \t\t{ formatter: (x) => {return x/1000;}}) // amps\n\n \nmsg.payload = typea.parse(buf);\n\nswitch(msg.payload.HwCellmonBattTypeID) {\n case 0:\n msg.payload.HwCellmonBattTypeID = \"Custom\";\n break;\n case 1:\n msg.payload.HwCellmonBattTypeID = \"Li-FePO4 Typical\";\n break;\n case 2:\n msg.payload.HwCellmonBattTypeID = \"Li-Ion Performance\";\n break;\n case 3:\n msg.payload.HwCellmonBattTypeID = \"Li-Ion LongLife\";\n break;\n case 4:\n msg.payload.HwCellmonBattTypeID = \"Li-FePO4 Longlife\";\n break;\n default:\n msg.payload.HwCellmonBattTypeID = \"Buggered\";\n}\n\nswitch(msg.payload.HwCellmonBypassExtraMode) {\n case 0:\n msg.payload.HwCellmonBypassExtraMode = \"None\";\n break;\n case 1:\n msg.payload.HwCellmonBypassExtraMode = \"Idle Shunt\";\n break;\n case 2:\n msg.payload.HwCellmonBypassExtraMode = \"Same CellVolt\";\n break;\n case 3:\n msg.payload.HwCellmonBypassExtraMode = \"AutoLevel\";\n break;\n default:\n msg.payload.HwCellmonBypassExtraMode = \"Buggered\";\n}\n\nswitch(msg.payload.HwCellmonCellMonTypeID) {\n case 0:\n msg.payload.HwCellmonCellMonTypeID = \"Custom\";\n break;\n case 1:\n msg.payload.HwCellmonCellMonTypeID = \"GenMon 2W\";\n break;\n case 2:\n msg.payload.HwCellmonCellMonTypeID = \"GenMon 8W\";\n break;\n case 3:\n msg.payload.HwCellmonCellMonTypeID = \"LongMon\";\n break;\n case 4:\n msg.payload.HwCellmonCellMonTypeID = \"BlockMonM8\";\n break;\n case 5:\n msg.payload.HwCellmonCellMonTypeID = \"BlockMonM14\";\n break;\n case 6:\n msg.payload.HwCellmonCellMonTypeID = \"EndMon\";\n break;\n case 7:\n msg.payload.HwCellmonCellMonTypeID = \"ManyMon\";\n break;\n default:\n msg.payload.HwCellmonCellMonTypeID = \"Buggered\";\n}\n\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 130,
"y": 700,
"wires": [
[
"fbba11c0.1f358"
]
]
},
{
"id": "6bbf2b60.9ce744",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Msg_4c33_HwShuntSetup",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n\t\t.skip(8)\n\t\t.uint8('HwShuntShuntType') /* ShuntTypes\n\t\t\t\tNone \t\t\t\t= 0,\n\t\t\t\tSFP102MOD 100uOhm 375A 150V \t= 1, \n\t\t\t\tSFP101EVB 72uOhm 500A 150V \t= 2,\n\t\t\t\tSFP101EVB 25uOhm 1500A 150V \t= 3,\n\t\t\t\tSFP102MOD (4k) 375A 750V \t\t= 4, \n\t\t\t\tSFP102MOD (3k) 375A 600V \t\t= 5, \n\t\t\t\tSFP102MOD Negative volt sense \t= 6,\n\t\t\t\tSFP102MOD 50uOhm 750A 150V \t\t= 7, \n\t\t\t\tShuntMon2 50uOhm 500A 650V \t\t= 16, */\n\t\t.int16le('HwShuntScale16volt')\n\t\t.int16le('HwShuntScale16amp')\n\t\t.int16le('HwShuntChargeIdle',\t{ formatter: (x) => {return x/100;}}) // amps\n\t\t.int16le('HwShuntDischgIdle',\t{ formatter: (x) => {return x/100;}})\t// amps\n\t\t.uint8( 'HwShuntSocCountLo', \t{ formatter: (x) => {return (x-5)/2;}}) // percent\n\t\t.uint8( 'HwShuntSocCountHi', \t{ formatter: (x) => {return (x-5)/2;}}) // percent\n\t\t.uint8( 'HwShuntSocLoRecal', \t{ formatter: (x) => {return (x-5)/2;}}) // percent\n\t\t.uint8( 'HwShuntSocHiRecal', \t{ formatter: (x) => {return (x-5)/2;}}) // percent\n\t\t.uint8( 'HwShuntMonitorSocLoRecal') \t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'HwShuntMonitorSocHiRecal') \t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'HwShuntMonitorInBypassRecal')\t// boolean 0 = Off , 1 = On\n\t\t.floatle('HwShuntNomCapacity',\t{ formatter: (x) => {return x/1000;}})\t// Ah\n\t\t.floatle('HwShuntGainVolt')\n\t\t.floatle('HwShuntGainAmp')\n\t\t.floatle('HwShuntGainAcculm')\t// mAh\n\t\t.floatle('HwShuntGainTemp') \t// temperature ºC\n\t\t.uint8( 'HwShuntReverseFlow') \t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'HwShuntSetupVers') \n\t\t.floatle('HwShuntGainVA')\n\t\t.floatle('HwShuntGainVAh')\t\n\t\t.int16le('HwShuntMax16volt')\n\t\t.int16le('HwShuntMax16charge')\n\t\t.int16le('HwShuntMax16dischg')\n\n \nmsg.payload = typea.parse(buf);\n\nswitch(msg.payload.HwShuntShuntType) {\n case 0:\n msg.payload.HwShuntShuntType = \"None\";\n break;\n case 1:\n msg.payload.HwShuntShuntType = \"SFP102MOD 100uOhm 375A 150V\";\n break;\n case 2:\n msg.payload.HwShuntShuntType = \"SFP101EVB 72uOhm 500A 150V\";\n break;\n case 3:\n msg.payload.HwShuntShuntType = \"SFP101EVB 25uOhm 1500A 150V\";\n break;\n case 4:\n msg.payload.HwShuntShuntType = \"SFP102MOD (4k) 375A 750V\";\n break;\n case 5:\n msg.payload.HwShuntShuntType = \"SFP102MOD (3k) 375A 600V\";\n break;\n case 6:\n msg.payload.HwShuntShuntType = \"SFP102MOD Negative volt sense\";\n break;\n case 7:\n msg.payload.HwShuntShuntType = \"SFP102MOD 50uOhm 750A 150V\";\n break;\n case 16:\n msg.payload.HwShuntShuntType = \"ShuntMon2 50uOhm 500A 650V\";\n break;\n default:\n msg.payload.HwShuntShuntType = \"Buggered\";\n}\n\n\n\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 120,
"y": 740,
"wires": [
[
"22e7b26a.4c54ae"
]
]
},
{
"id": "bc74a308.cfe11",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Msg_5334_HwIntegrationSetup",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n\t\t.skip(8)\n\t\t.uint8('HwIntegrationSetupVers') \n\t\t.uint8('HwIntegrationUsbTxBroadcast') \t\t// boolean 0 = Off , 1 = On\n\t\t.uint8('HwIntegrationWifiUdpTxBroadcast') \t// boolean 0 = Off , 1 = On\n\t\t.uint8('HwIntegrationWifiBroadcastMode') /* WifiBroadcastModes\n\t\t\t\tNone \t\t= 0,\n\t\t\t\tVerbose \t= 1,\n\t\t\t\tVerbose ReadOnly = 4,\n\t\t\t\tLimited \t= 2,\n\t\t\t\tDisabled \t= 3, */\n\t\t.uint8('HwIntegrationCanbusTxBroadcast') \t// boolean 0 = Off , 1 = On\n\t\t.uint8('HwIntegrationCanbusMode') /* CanbusModes\n\t\t\t\tNone \t\t= 0,\n\t\t\t\tNative \t\t= 1,\n\t\t\t\tElcon TCCharger = 2,\n\t\t\t\tEnPower Charger500k = 3,\n\t\t\t\tSolax PowerSK control = 4,\n\t\t\t\tSma SunnyIsland V31 = 5,\n\t\t\t\tBrusa NLG5 \t= 6,\n\t\t\t\tEnPower Charger 250k = 7,\n\t\t\t\tSolax PowerSK Limited = 8,\n\t\t\t\tBrusa NLG6 \t= 9,\n\t\t\t\tProject Lychee = 10,\n\t\t\t\tEltek FlatPack2 HE2000/48 = 11,\n\t\t\t\tProject42 \t= 42,\t*/\n\t\t.uint32le('HwIntegrationCanbusRemoteAddr')\n\t\t.uint32le('HwIntegrationCanbusBaseAddr')\n\t\t.uint32le('HwIntegrationCanbusGroupAddr')\n \nmsg.payload = typea.parse(buf);\n\nswitch(msg.payload.HwIntegrationWifiBroadcastMode) {\n case 0:\n msg.payload.HwIntegrationWifiBroadcastMode = \"None\";\n break;\n case 1:\n msg.payload.HwIntegrationWifiBroadcastMode = \"Verbose\";\n break;\n case 2:\n msg.payload.HwIntegrationWifiBroadcastMode = \"Limited\";\n break;\n case 3:\n msg.payload.HwIntegrationWifiBroadcastMode = \"Disabled\";\n break;\n case 4:\n msg.payload.HwIntegrationWifiBroadcastMode = \"Verbose ReadOnly\";\n break;\n default:\n msg.payload.HwIntegrationWifiBroadcastMode = \"Buggered\";\n}\n\nswitch(msg.payload.HwExpansionRelay1) {\n case 0:\n msg.payload.HwExpansionRelay1 = \"None\";\n break;\n case 1:\n msg.payload.HwExpansionRelay1 = \"Native\";\n break;\n case 2:\n msg.payload.HwExpansionRelay1 = \"Elcon TCCharger\";\n break;\n case 3:\n msg.payload.HwExpansionRelay1 = \"EnPower Charger500k\";\n break;\n case 4:\n msg.payload.HwExpansionRelay1 = \"Solax PowerSK control\";\n break;\n case 5:\n msg.payload.HwExpansionRelay1 = \"Sma SunnyIsland V31\";\n break;\n case 6:\n msg.payload.HwExpansionRelay1 = \"Brusa NLG5\";\n break;\n case 7:\n msg.payload.HwExpansionRelay1 = \"EnPower Charger 250k\";\n break;\n case 8:\n msg.payload.HwExpansionRelay1 = \"Solax PowerSK Limited\";\n break;\n case 9:\n msg.payload.HwExpansionRelay1 = \"Brusa NLG6\";\n break;\n case 10:\n msg.payload.HwExpansionRelay1 = \"Project Lychee\";\n break;\n case 11:\n msg.payload.HwExpansionRelay1 = \"Eltek FlatPack2 HE2000/48\";\n break;\n case 42:\n msg.payload.HwExpansionRelay1 = \"roject42\";\n break;\n default:\n msg.payload.HwExpansionRelay1 = \"Buggered\";\n}\n\n\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 130,
"y": 820,
"wires": [
[
"8b53a6b9.a53688"
]
]
},
{
"id": "8b53a6b9.a53688",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"d": true,
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 390,
"y": 820,
"wires": []
},
{
"id": "a3320528.870448",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Msg_4f33_ControlCriticalSetup",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n\t\t.skip(8)\n\t\t.uint8( 'ControlCriticalMode') /* Choices ControlCriticalModes\n\t\t\t\tAuto \t\t\t= 0,\n\t\t\t\tManually On \t= 1,\n\t\t\t\tManually Off \t= 2, */\t\n\t\t.uint8( 'ControlCriticalAutoRecovery') \t\t\t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'ControlCriticalIgnoreCellsOverdue') \t\t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'ControlCriticalMonitorCellVoltLo') \t\t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'ControlCriticalMonitorCellVoltHi') \t\t// boolean 0 = Off , 1 = On\n\t\t.int16le('ControlCriticalCellVoltLo',\t\t\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('ControlCriticalCellVoltHi',\t\t\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.uint8( 'ControlCriticalMonitorCellTempLo') \t\t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'ControlCriticalMonitorCellTempHi') \t\t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'ControlCriticalCellTempLo',\t\t\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8( 'ControlCriticalCellTempHi',\t\t\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8( 'ControlCriticalMonitorSupplyLo') \t\t\t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'ControlCriticalMonitorSupplyHi') \t\t\t// boolean 0 = Off , 1 = On\n\t\t.int16le('ControlCriticalSupplyVoltLo',\t\t\t\t{ formatter: (x) => {return x/100;}})\n\t\t.int16le('ControlCriticalSupplyVoltHi',\t\t\t\t{ formatter: (x) => {return x/100;}})\n\t\t.uint8( 'ControlCriticalMonitorAmbientLo') \t\t\t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'ControlCriticalMonitorAmbientHi') \t\t\t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'ControlCriticalAmbientTempLo',\t\t\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8( 'ControlCriticalAmbientTempHi',\t\t\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8( 'ControlCriticalMonitorShuntVoltLo') \t\t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'ControlCriticalMonitorShuntVoltHi') \t\t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'ControlCriticalMonitorShuntVoltLoIdle') \t// boolean 0 = Off , 1 = On\n\t\t.int16le('ControlCriticalShuntVoltLo',\t\t\t\t{ formatter: (x) => {return x/100;}})\n\t\t.int16le('ControlCriticalShuntVoltHi',\t\t\t\t{ formatter: (x) => {return x/100;}})\n\t\t.int16le('ControlCriticalShuntVoltLoIdle',\t\t\t{ formatter: (x) => {return x/100;}})\n\t\t.uint8( 'ControlCriticalMonitorShuntPeakCharge') \t// boolean 0 = Off , 1 = On\n\t\t.int16le('ControlCriticalShuntPeakCharge',\t\t\t{ formatter: (x) => {return x/100;}}) // amps\n\t\t.int16le('ControlCriticalShuntCrateCharge',\t\t\t{ formatter: (x) => {return x/100;}}) // ratio\n\t\t.uint8( 'ControlCriticalMonitorShuntPeakDischg') \t// boolean 0 = Off , 1 = On\n\t\t.int16le('ControlCriticalShuntPeakDischg',\t\t\t{ formatter: (x) => {return x/100;}}) // amps\n\t\t.int16le('ControlCriticalShuntCrateDischg',\t\t\t{ formatter: (x) => {return x/100;}}) // ratio\n\t\t.uint32le('ControlCriticalStopInterval',\t\t\t{ formatter: (x) => {return x/1000;}}) // seconds\n\t\t.uint32le('ControlCriticalStartInterval',\t\t\t{ formatter: (x) => {return x/1000;}}) // seconds\n\t\t.uint32le('ControlCriticalTimeoutManualOverride',\t{ formatter: (x) => {return x/1000;}}) // seconds\n\t\t.uint32le('ControlCriticalPrechargeTimeInterval',\t{ formatter: (x) => {return x/1000;}}) // seconds\n\t\t.uint8( 'ControlCriticalIgnoreShuntOverdue') \t\t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'ControlCriticalIgnoreRemoteOverdue') \t\t// boolean 0 = Off , 1 = On\n\t\t.int16le('ControlCriticalRecoverSupplyGapVolt',\t\t{ formatter: (x) => {return x/100;}})\n\t\t.int16le('ControlCriticalRecoverShuntChargeLimit',\t{ formatter: (x) => {return x/100;}}) // amps\n\t\t.int16le('ControlCriticalRecoverShuntDischgLimit',\t{ formatter: (x) => {return x/100;}}) // amps\n\t\t.uint8( 'ControlCriticalSetupVers') \n\n \nmsg.payload = typea.parse(buf);\n\nswitch(msg.payload.ControlCriticalMode) {\n case 0:\n msg.payload.ControlCriticalMode = \"Auto\";\n break;\n case 1:\n msg.payload.ControlCriticalMode = \"Manually On\";\n break;\n case 2:\n msg.payload.ControlCriticalMode = \"Manually Off\";\n break;\n default:\n msg.payload.ControlCriticalMode = \"Buggered\";\n}\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 130,
"y": 860,
"wires": [
[
"86100b5d.5d6998"
]
]
},
{
"id": "86100b5d.5d6998",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 390,
"y": 860,
"wires": []
},
{
"id": "84398b42.b2f578",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Msg_5033_ControlChargeSetup",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n\t\t.skip(8)\n\t\t.uint8( 'ControlChargeMode') /* Choices ControlChargeModes\n\t\t\t\tAuto\t\t \t = 0,\n\t\t\t\tManually On = 1,\n\t\t\t\tManually Off = 2,\n\t\t\t\tManually Limited = 3, */\t\n\t\t.uint8( 'ControlChargeAllowLimPowerStage') \t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'ControlChargeAllowBypassLimPower') \t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'ControlChargeAllowBypassComplete') \t// boolean 0 = Off , 1 = On\n\t\t.int16le('ControlChargeInitalBypassAmp',\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('ControlChargeFinalBypassAmp',\t\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.uint8( 'ControlChargeMonitorCellTempLo') \t\t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'ControlChargeMonitorCellTempHi') \t\t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'ControlChargeCellTempLo',\t\t\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8( 'ControlChargeCellTempHi',\t\t\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8( 'ControlChargeMonitorAmbientLo') \t\t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'ControlChargeMonitorAmbientHi') \t\t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'ControlChargeAmbientTempLo',\t\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8( 'ControlChargeAmbientTempHi',\t\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8( 'ControlChargeMonitorSupplyHi') \t\t// boolean 0 = Off , 1 = On\n\t\t.int16le('ControlChargeSupplyVoltHi',\t\t\t{ formatter: (x) => {return x/100;}})\n\t\t.int16le('ControlChargeSupplyVoltResume',\t\t{ formatter: (x) => {return x/100;}})\n\t\t.uint8( 'ControlChargeMonitorCellVoltHi') \t\t// boolean 0 = Off , 1 = On\n\t\t.int16le('ControlChargeCellVoltHi',\t\t\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('ControlChargeCellVoltResume',\t\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('ControlChargeCellVoltLimPower',\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.uint8( 'ControlChargeMonitorShuntVoltHi') \t// boolean 0 = Off , 1 = On\n\t\t.int16le('ControlChargeShuntVoltHi',\t\t\t{ formatter: (x) => {return x/100;}})\n\t\t.int16le('ControlChargeShuntVoltResume',\t\t{ formatter: (x) => {return x/100;}})\n\t\t.int16le('ControlChargeShuntVoltLimPower',\t\t{ formatter: (x) => {return x/100;}})\n\t\t.uint8( 'ControlChargeMonitorShuntSocHi') \t\t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'ControlChargeShuntSocHi', \t\t\t{ formatter: (x) => {return (x-5)/2;}}) // percent\n\t\t.uint8( 'ControlChargeShuntSocResume', \t\t{ formatter: (x) => {return (x-5)/2;}}) // percent\n\t\t.uint32le('ControlChargeStopInterval',\t\t\t{ formatter: (x) => {return x/1000;}}) // seconds\n\t\t.uint32le('ControlChargeStartInterval',\t\t\t{ formatter: (x) => {return x/1000;}}) // seconds\n\t\t.uint8( 'ControlChargeSetupVers') \n\t\t.floatle('ControlChargeBypassSessionLo',\t\t{ formatter: (x) => {return x/1000;}})\t// Ah\n\t\t.uint8( 'ControlChargeAllowBypassSession') \t// boolean 0 = Off , 1 = On\n\t\t\n \nmsg.payload = typea.parse(buf);\n\nswitch(msg.payload.ControlChargeMode) {\n case 0:\n msg.payload.ControlChargeMode = \"Auto\";\n break;\n case 1:\n msg.payload.ControlChargeMode = \"Manually On\";\n break;\n case 2:\n msg.payload.ControlChargeMode = \"Manually Off\";\n break;\n case 3:\n msg.payload.ControlChargeMode = \"Manually Limited\";\n break;\n default:\n msg.payload.ControlChargeMode = \"Buggered\";\n}\n\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 130,
"y": 900,
"wires": [
[
"e91ed1d6.85832"
]
]
},
{
"id": "e91ed1d6.85832",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"d": true,
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 390,
"y": 900,
"wires": []
},
{
"id": "66113e17.06931",
"type": "function",
"z": "e6fd3a1c.5e9548",
"d": true,
"name": "Msg_5158_ControlDischargeSetup",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n\t\t.skip(8)\n\t\t.uint8( 'ControlDischargeMode') /* Choices ControlDischgModes\n\t\t\t\tAuto\t\t \t = 0,\n\t\t\t\tManually On = 1,\n\t\t\t\tManually Off = 2,\n\t\t\t\tManually Limited = 3, */\t\n\t\t.uint8( 'ControlDischargeAllowLimPowerStage')\t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'ControlDischargeMonitorCellTempLo') \t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'ControlDischargeMonitorCellTempHi') \t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'ControlDischargeCellTempLo',\t\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8( 'ControlDischargeCellTempHi',\t\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8( 'ControlDischargeMonitorAmbientLo') \t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'ControlDischargeMonitorAmbientHi') \t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'ControlDischargeAmbientTempLo',\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8( 'ControlDischargeAmbientTempHi',\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8( 'ControlDischargeMonitorSupplyLo') \t// boolean 0 = Off , 1 = On\n\t\t.int16le( 'ControlDischargeSupplyVoltLo',\t\t{ formatter: (x) => {return x/100;}})\n\t\t.int16le( 'ControlDischargeSupplyVoltResume',\t{ formatter: (x) => {return x/100;}})\n\t\t.uint8( 'ControlDischargeMonitorCellVoltLo') \t// boolean 0 = Off , 1 = On\n\t\t.int16le( 'ControlDischargeCellVoltLo',\t\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le( 'ControlDischargeCellVoltResume',\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le( 'ControlDischargeCellVoltLimPower',\t{ formatter: (x) => {return x/1000;}})\n\t\t.uint8( 'ControlDischargeMonitorShuntVoltLo') // boolean 0 = Off , 1 = On\n\t\t.int16le( 'ControlDischargeShuntVoltLo',\t\t{ formatter: (x) => {return x/100;}})\n\t\t.int16le( 'ControlDischargeShuntVoltResume',\t{ formatter: (x) => {return x/100;}})\n\t\t.int16le( 'ControlDischargeShuntVoltLimPower',\t{ formatter: (x) => {return x/100;}})\n\t\t.uint8( 'ControlDischargeMonitorShuntSocLo') \t// boolean 0 = Off , 1 = On\n\t\t.uint8( 'ControlDischargeShuntSocLo', \t\t{ formatter: (x) => {return (x-5)/2;}}) // percent\n\t\t.uint8( 'ControlDischargeShuntSocResume', \t{ formatter: (x) => {return (x-5)/2;}}) // percent\n\t\t.uint32le('ControlDischargeStopInterval',\t\t{ formatter: (x) => {return x/1000;}}) // seconds\n\t\t.uint32le('ControlDischargeStartInterval',\t\t{ formatter: (x) => {return x/1000;}}) // seconds\n\t\t.uint8( 'ControlDischargeSetupVers') \n\t\n \nmsg.payload = typea.parse(buf);\n\nswitch(msg.payload.ControlDischargeMode) {\n case 0:\n msg.payload.ControlDischargeMode = \"Auto\";\n break;\n case 1:\n msg.payload.ControlDischargeMode = \"Manually On\";\n break;\n case 2:\n msg.payload.ControlDischargeMode = \"Manually Off\";\n break;\n case 3:\n msg.payload.ControlDischargeMode = \"Manually Limited\";\n break;\n default:\n msg.payload.ControlDischargeMode = \"Buggered\";\n}\n\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 140,
"y": 940,
"wires": [
[
"e0549ade.d61068"
]
]
},
{
"id": "e0549ade.d61068",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"d": true,
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 390,
"y": 940,
"wires": []
},
{
"id": "d0a120ad.f8edd",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Msg_5258_ControlThermalSetup",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n\t\t.skip(8)\n\t\t.uint8('ControlHeatMode') /* Choices ThermalControlModes\n\t\t\t\tAuto\t\t \t = 0,\n\t\t\t\tManually On = 1,\n\t\t\t\tManually Off = 2, */\t\n\t\t.uint8('ControlHeatMonitorLoCellTemp') \t// Boolean 0 = Off , 1 = On\n\t\t.uint8('ControlHeatMonitorLoAmbient') \t\t// Boolean 0 = Off , 1 = On\n\t\t.uint8('ControlHeatLoCellTemp', \t\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8('ControlHeatLoAmbient',\t \t\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint32le('ControlHeatStopInterval',\t\t{ formatter: (x) => {return x/1000;}}) // seconds\n\t\t.uint32le('ControlHeatStartInterval',\t\t{ formatter: (x) => {return x/1000;}}) // seconds\n\t\t.uint8('ControlCoolMode') \t\t\t\t\t/* Choices ThermalControlModes */\n\t\t.uint8('ControlCoolMonitorHiCellTemp') \t// Boolean 0 = Off , 1 = On\n\t\t.uint8('ControlCoolMonitorHiAmbient') \t// Boolean 0 = Off , 1 = On\n\t\t.uint8('ControlCoolMonitorInBypass') \t\t// Boolean 0 = Off , 1 = On\n\t\t.uint8('ControlCoolHiCellTemp', \t\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint8('ControlCoolHiAmbient',\t \t\t\t{ formatter: (x) => {return x-40;}}) // temperature ºC\n\t\t.uint32le('ControlCoolStopInterval',\t\t{ formatter: (x) => {return x/1000;}}) // seconds\n\t\t.uint32le('ControlCoolStartInterval',\t\t{ formatter: (x) => {return x/1000;}}) // seconds\n\t\t.uint8('ControlThermalSetupVers') \n\n \nmsg.payload = typea.parse(buf);\n\nswitch(msg.payload.ControlHeatMode) {\n case 0:\n msg.payload.ControlHeatMode = \"Auto\";\n break;\n case 1:\n msg.payload.ControlHeatMode = \"Manually On\";\n break;\n case 2:\n msg.payload.ControlHeatMode = \"Manually Off\";\n break;\n default:\n msg.payload.ControlHeatMode = \"Buggered\";\n}\n\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 140,
"y": 980,
"wires": [
[
"6bb53cb7.1587d4"
]
]
},
{
"id": "6bb53cb7.1587d4",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"d": true,
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 390,
"y": 980,
"wires": []
},
{
"id": "3f60dd09.a9d822",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Msg_4e58_ControlRemoteSetup",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n\t\t.skip(8)\n\t\t.int16le('ControlChargeTargetNormVolt')\n\t\t.int16le('ControlChargeTargetNormAmp')\n\t\t.int16le('ControlChargeTargetNormVA')\n\t\t.int16le('ControlChargeTargetLimpVolt')\n\t\t.int16le('ControlChargeTargetLimpAmp')\n\t\t.int16le('ControlChargeTargetLimpVA')\n\t\t.int16le('ControlChargeScale16volt')\n\t\t.int16le('ControlChargeScale16amp')\n\t\t.int16le('ControlChargeScale16va')\n\t\t.int16le('ControlDischargeTargetNormVolt')\n\t\t.int16le('ControlDischargeTargetNormAmp')\n\t\t.int16le('ControlDischargeTargetNormVA')\n\t\t.int16le('ControlDischargeTargetLimpVolt')\n\t\t.int16le('ControlDischargeTargetLimpAmp')\n\t\t.int16le('ControlDischargeTargetLimpVA')\n\t\t.int16le('ControlDischargeScale16volt')\n\t\t.int16le('ControlDischargeScale16amp')\n\t\t.int16le('ControlDischargeScale16va')\n\t\t.uint8('ControlRemoteSetupVers') \n\t\t\nmsg.payload = typea.parse(buf);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 140,
"y": 1020,
"wires": [
[
"77fa4a8.4d5f4b4"
]
]
},
{
"id": "77fa4a8.4d5f4b4",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"d": true,
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 390,
"y": 1020,
"wires": []
},
{
"id": "672f0abe.f9af24",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Msg_5831_DailySessionHist",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n\t\t.skip(8)\n\t\t.int16le('DailySessionHistId')\n\t\t.uint32le('DailySessionHistTime') \t\t// Epoch *** log key ***\n\t\t.uint8('DailySessionHistCriticalEvents')\n\t\t.skip(1)\n\t\t.uint8('DailySessionHistMinReportTemp',\t\t\t{ formatter: (x) => {return x-40;}})\t// temperature ºC\n\t\t.uint8('DailySessionHistMaxReportTemp',\t\t\t{ formatter: (x) => {return x-40;}})\t// temperature ºC\n\t\t.uint8('DailySessionHistMinShuntSoc', \t\t\t{ formatter: (x) => {return (x-5)/2;}}) // percent\n\t\t.uint8('DailySessionHistMaxShuntSoc', \t\t\t{ formatter: (x) => {return (x-5)/2;}}) // percent\n\t\t.int16le('DailySessionHistMinCellVolt',\t\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('DailySessionHistMaxCellVolt',\t\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('DailySessionHistMinSupplyVolt',\t\t{ formatter: (x) => {return x/100;}})\n\t\t.int16le('DailySessionHistMaxSupplyVolt',\t\t{ formatter: (x) => {return x/100;}})\n\t\t.int16le('DailySessionHistMinShuntVolt',\t\t{ formatter: (x) => {return x/100;}})\n\t\t.int16le('DailySessionHistMaxShuntVolt',\t\t{ formatter: (x) => {return x/100;}})\n\t\t.uint8('DailySessionHistThermalBandA',\t\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionHistThermalBandB',\t\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionHistThermalBandC',\t\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionHistThermalBandD',\t\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionHistThermalBandE',\t\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionHistThermalBandF',\t\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionHistThermalBandG',\t\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionHistThermalBandH',\t\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionHistSocBandA',\t\t\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionHistSocBandB',\t\t\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionHistSocBandC',\t\t\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionHistSocBandD',\t\t\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionHistSocBandE',\t\t\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionHistSocBandF',\t\t\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionHistSocBandG',\t\t\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.uint8('DailySessionHistSocBandH',\t\t\t\t{ formatter: (x) => {return x/10;}}) // hours\n\t\t.int16le('DailySessionHistShuntPeakCharge',\t\t{ formatter: (x) => {return x/100;}}) // amp\n\t\t.int16le('DailySessionHistShuntPeakDischg',\t\t{ formatter: (x) => {return x/100;}}) // amp\n\t\t.int16le('DailySessionHistCumulShuntAhCharge',\t{ formatter: (x) => {return x/1000;}}) // Ah\n\t\t.int16le('DailySessionHistCumulShuntAhDischg',\t{ formatter: (x) => {return x/1000;}}) // Ah\n\t\t\nmsg.payload = typea.parse(buf);\n\n// convert date(s)\nmsg.payload.DailySessionHistTime = new Date(msg.payload.DailySessionHistTime*1000);\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 120,
"y": 1060,
"wires": [
[
"f82cb531.002978"
]
]
},
{
"id": "f82cb531.002978",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"d": true,
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 390,
"y": 1060,
"wires": []
},
{
"id": "fa326eca.690b8",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Msg_6831_QuickSessionHist",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n\t\t.skip(8)\n\t\t.int16le('QuickSessionHistId')\n\t\t.uint32le('QuickSessionHistTime') \t\t// Epoch *** log key ***\n\t\t.uint8('QuickSessionHistSystemOpState') /* Choices\n\t\t\t\tSimulator = 0, \t // LED = rainbow pulse\n\t\t\t\tIdle = 1, \t // LED = green slow pulse\n\t\t\t\tDischarging = 2, \t // LED = green solid \n\t\t\t\tSoC Empty = 3, \t // LED = green double blink\n\t\t\t\tCharging = 4, \t // LED = blue slow pulse\n\t\t\t\tFull = 5, \t // LED = blue double blink\n\t\t\t\tTimeout = 6, \t // LED = red solid\n\t\t\t\tCritical Pending = 7, // LED = red fast pulse\n\t\t\t\tCritical Offline = 8, // LED = red slow pulse\n\t\t\t\tMqtt Offline = 9, // LED = white blink\n\t\t\t\tAuth Setup = 10, // LED = white solid\n\t\t\t\tShunt Timeout = 11, // LED = red solid \t*/\n\t\t.uint8( 'QuickSessionHistControlLogic') \n\t\t.int16le('QuickSessionHistMinCellVolt',\t\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('QuickSessionHistMaxCellVolt',\t\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.int16le('QuickSessionHistAvgCellVolt',\t\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.uint8( 'QuickSessionHistAvgCellTemp',\t\t\t{ formatter: (x) => {return x-40;}})\t// temperature ºC\n\t\t.int16le('QuickSessionHistSocHiRes',\t\t\t{ formatter: (x) => {return x/100;}})\t// percent\n\t\t.int16le('QuickSessionHistShuntVolt',\t\t\t{ formatter: (x) => {return x/100;}})\n\t\t.floatle('QuickSessionHistShuntAmp',\t\t\t{ formatter: (x) => {return x/1000;}}) // amp\n\t\t.uint8( 'QuickSessionHistNumOfCellsInBypass')\n\n\t\nmsg.payload = typea.parse(buf);\n\n// convert date(s)\nmsg.payload.QuickSessionHistTime = new Date(msg.payload.QuickSessionHistTime*1000);\n\nswitch(msg.payload.QuickSessionHistSystemOpState) {\n case 0:\n msg.payload.QuickSessionHistSystemOpState = \"Simulator\";\n break;\n case 1:\n msg.payload.QuickSessionHistSystemOpState = \"Idle\";\n break;\n case 2:\n msg.payload.QuickSessionHistSystemOpState = \"Discharging\";\n break;\n case 3:\n msg.payload.QuickSessionHistSystemOpState = \"SoC Empty\";\n break;\n case 4:\n msg.payload.QuickSessionHistSystemOpState = \"Charging\";\n break;\n case 5:\n msg.payload.QuickSessionHistSystemOpState = \"Full\";\n break;\n case 6:\n msg.payload.QuickSessionHistSystemOpState = \"Timeout\";\n break;\n case 7:\n msg.payload.QuickSessionHistSystemOpState = \"CriticalPending\";\n break;\n case 8:\n msg.payload.QuickSessionHistSystemOpState = \"CriticalOffline\";\n break;\n case 9:\n msg.payload.QuickSessionHistSystemOpState = \"MqttOffline\";\n break;\n case 10:\n msg.payload.QuickSessionHistSystemOpState = \"AuthSetup\";\n break;\n case 11:\n msg.payload.QuickSessionHistSystemOpState = \"Shunt Timeout\";\n break;\n default:\n msg.payload.QuickSessionHistSystemOpState = \"Buggered\";\n}\n\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 120,
"y": 1100,
"wires": [
[
"ea787f02.584ab"
]
]
},
{
"id": "15f71030.bd9eb",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Msg_5431_SessionMetrics",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n\t\t.skip(8)\n\t\t.uint32le('QuickSessRecentTime') \t\t// EPOCH\n\t\t.int16le('QuickSessNumOfRecords')\n\t\t.int16le('QuickSessMaxNumOfRecords')\n\t\t.uint32le('QuickSessionInterval',\t\t{ formatter: (x) => {return x/1000;}})\n\t\t.uint8('AllowQuickSession') \t\t\t// boolean 0 = Off , 1 = On\n\t\t.int16le('DailySessNumOfRecords')\n\t\t.int16le('DailySessMaxNumOfRecords')\n\n\nmsg.payload = typea.parse(buf);\n\n// convert date(s)\nmsg.payload.QuickSessRecentTime = new Date(msg.payload.QuickSessRecentTime*1000);\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 120,
"y": 1140,
"wires": [
[
"49be9953.d21e48"
]
]
},
{
"id": "2af1bf8b.3e7b5",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 570,
"y": 40,
"wires": []
},
{
"id": "6c1bb0a6.cde56",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Get the set of saved global variables",
"func": "\nvar ONE = global.get('ONE') || 0;\nvar TWO = global.get('TWO') || 0;\nvar THREE = global.get('THREE') || 0;\nvar FOUR = global.get('FOUR') || 0;\nvar FIVE = global.get('FIVE') || 0;\nvar SIX = global.get('SIX') || 0;\nvar SEVEN = global.get('SEVEN') || 0;\nvar EIGHT = global.get('EIGHT') || 0;\nvar NINE = global.get('NINE') || 0;\nvar TEN = global.get('TEN') || 0;\nvar ELEVEN = global.get('ELEVEN') || 0;\nvar TWELVE = global.get('TWELVE') || 0;\nvar THIRTEEN = global.get('THIRTEEN') || 0;\nvar FOURTEEN = global.get('FOURTEEN') || 0;\nvar FIFTEEN = global.get('FIFTEEN') || 0;\nvar SIXTEEN = global.get('SIXTEEN') || 0;\n\n\nvar m = {};\nm.labels = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16'];\nm.data = [[ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN,EIGHT, NINE, TEN, ELEVEN, TWELVE, THIRTEEN, FOURTEEN, FIFTEEN, SIXTEEN]];\nm.series = ['Cell'];\nreturn {payload:[m],topic:msg.topic};",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 890,
"y": 20,
"wires": [
[
"24fe7cc5.03a284",
"602b821a.72b6bc"
]
]
},
{
"id": "24fe7cc5.03a284",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 1650,
"y": 20,
"wires": []
},
{
"id": "b56a71fb.69c95",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Put cell voltage into globals",
"func": "var myLongmon;\n\nswitch(msg.payload.ID) {\n case 1:\n myLongmon=\"ONE\";\n break;\n case 2:\n myLongmon=\"TWO\";\n break;\n case 3:\n myLongmon=\"THREE\";\n break;\n case 4:\n myLongmon=\"FOUR\";\n break;\n case 5:\n myLongmon=\"FIVE\";\n break;\n case 6:\n myLongmon=\"SIX\";\n break;\n case 7:\n myLongmon=\"SEVEN\";\n break;\n case 8:\n myLongmon=\"EIGHT\";\n break;\n case 9:\n myLongmon=\"NINE\";\n break;\n case 10:\n myLongmon=\"TEN\";\n break;\n case 11:\n myLongmon=\"ELEVEN\";\n break;\n case 12:\n myLongmon=\"TWELVE\";\n break;\n case 13:\n myLongmon=\"THIRTEEN\";\n break;\n case 14:\n myLongmon=\"FOURTEEN\";\n break;\n case 15:\n myLongmon=\"FIFTEEN\";\n break;\n case 16:\n myLongmon=\"SIXTEEN\";\n break;\n}\n \nglobal.set(myLongmon,msg.payload.MaxCellVolt); \n \n//return msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 1440,
"y": 920,
"wires": [
[
"ee919253.daba5"
]
]
},
{
"id": "d9a8b490.a039d8",
"type": "inject",
"z": "e6fd3a1c.5e9548",
"name": "Update the chart every 1 second",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "5",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 520,
"y": 140,
"wires": [
[
"6c1bb0a6.cde56",
"7c2e474e.4fe348",
"d54ad04d.f5cb8"
]
]
},
{
"id": "602b821a.72b6bc",
"type": "ui_chart",
"z": "e6fd3a1c.5e9548",
"name": "Realtime cell voltages",
"group": "605bdeca.e6347",
"order": 5,
"width": "0",
"height": "0",
"label": "Cell voltages",
"chartType": "bar",
"legend": "false",
"xformat": "HH:mm:ss",
"interpolate": "linear",
"nodata": "No Data",
"dot": false,
"ymin": "3",
"ymax": "4.2",
"removeOlder": 1,
"removeOlderPoints": "",
"removeOlderUnit": "3600",
"cutout": 0,
"useOneColor": true,
"useUTC": false,
"colors": [
"#00aaff",
"#b3dfea",
"#ff7f0e",
"#2ca02c",
"#98df8a",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"outputs": 1,
"x": 1400,
"y": 60,
"wires": [
[
"43701535.84212c"
]
]
},
{
"id": "8445ce7c.09028",
"type": "ui_text",
"z": "e6fd3a1c.5e9548",
"group": "605bdeca.e6347",
"order": 1,
"width": "0",
"height": "0",
"name": "Shunt Status: ",
"label": "Shunt Status: ",
"format": "{{msg.payload.ShuntStatus}}",
"layout": "row-left",
"x": 820,
"y": 600,
"wires": []
},
{
"id": "34dd4fa2.32065",
"type": "function",
"z": "e6fd3a1c.5e9548",
"d": true,
"name": "Msg_4732_HwSystemSetup",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n .skip(8)\n .uint8('isCriticalBattOkState') // Boolean 0 = Off , 1 = On\n .uint8('isCriticalBattOkCalc') // Boolean 0 = Off , 1 = On\n .uint8('isCriticalTransition') // Boolean 0 = Off , 1 = On\n .uint8('hasCriticalCellOverdue') // Boolean 0 = Off , 1 = On\n .uint8('hasCriticalCellVoltLo') // Boolean 0 = Off , 1 = On\n .uint8('hasCriticalCellVoltHi') // Boolean 0 = Off , 1 = On\n .uint8('hasCriticalCellTempLo') // Boolean 0 = Off , 1 = On\n .uint8('hasCriticalCellTempHi') // Boolean 0 = Off , 1 = On\n .uint8('hasCriticalSupplyVoltLo') // Boolean 0 = Off , 1 = On\n .uint8('hasCriticalSupplyVoltHi') // Boolean 0 = Off , 1 = On\n .uint8('hasCriticalAmbientLo') // Boolean 0 = Off , 1 = On\n .uint8('hasCriticalAmbientHi') // Boolean 0 = Off , 1 = On\n .uint8('hasCriticalShuntVoltLo') // Boolean 0 = Off , 1 = On\n .uint8('hasCriticalShuntVoltHi') // Boolean 0 = Off , 1 = On\n .uint8('hasCriticalShuntVoltLoIdle') // Boolean 0 = Off , 1 = On\n .uint8('hasCriticalShuntPeakCharge') // Boolean 0 = Off , 1 = On\n .uint8('hasCriticalShuntPeakDischg') // Boolean 0 = Off , 1 = On\n .uint8('isChargeOnState') // Boolean 0 = Off , 1 = On\n .uint8('isChargeLimPower') // Boolean 0 = Off , 1 = On\n .uint8('isChargeTransition') // Boolean 0 = Off , 1 = On\n .uint8('isChargePowerRateState') /* Choices ChargeRateStates\n Off = 0,\n Limited Power = 2,\n Normal Power = 4, */\n .uint8('isChargePowerRateCalc') /* Choices ChargeRateStates */\n .uint8('hasChargeCellVoltHi ') // Boolean 0 = Off , 1 = On\n .uint8('hasChargeCellVoltPause ') // Boolean 0 = Off , 1 = On\n .uint8('hasChargeCellVoltLimPower ') // Boolean 0 = Off , 1 = On\n .uint8('hasChargeCellTempLo ') // Boolean 0 = Off , 1 = On\n .uint8('hasChargeCellTempHi ') // Boolean 0 = Off , 1 = On\n .uint8('hasChargeAmbientTempLo ') // Boolean 0 = Off , 1 = On\n .uint8('hasChargeAmbientTempHi ') // Boolean 0 = Off , 1 = On\n .uint8('hasChargeSupplyVoltHi ') // Boolean 0 = Off , 1 = On\n .uint8('hasChargeSupplyVoltPause ') // Boolean 0 = Off , 1 = On\n .uint8('hasChargeShuntVoltHi ') // Boolean 0 = Off , 1 = On\n .uint8('hasChargeShuntVoltPause ') // Boolean 0 = Off , 1 = On\n .uint8('hasChargeShuntVoltLimPower ') // Boolean 0 = Off , 1 = On\n .uint8('hasChargeShuntSocHi ') // Boolean 0 = Off , 1 = On\n .uint8('hasChargeShuntSocPause ') // Boolean 0 = Off , 1 = On\n .uint8('hasChargeAboveInitalBypass ') // Boolean 0 = Off , 1 = On\n .uint8('hasChargeAboveFinalBypass ') // Boolean 0 = Off , 1 = On\n .uint8('hasChargeInBypass ') // Boolean 0 = Off , 1 = On\n .uint8('hasChargeBypassComplete ') // Boolean 0 = Off , 1 = On\n .uint8('hasChargeBypassTempRelief ') // Boolean 0 = Off , 1 = On\n .uint8('isDischgOnState ') // Boolean 0 = Off , 1 = On\n .uint8('isDischgLimPower ') // Boolean 0 = Off , 1 = On\n .uint8('isDischgTransition ') // Boolean 0 = Off , 1 = On\n .uint8('isDischgPowerRateState ') /* Choices DischgRateStates\n Off = 0,\n Limited Power = 2,\n Normal Power = 4, */\n .uint8('isDischgPowerRateCalc ') /* Choices DischgRateStates */\n .uint8('hasDischgCellVoltLo ') // Boolean 0 = Off , 1 = On\n .uint8('hasDischgCellVoltPause ') // Boolean 0 = Off , 1 = On\n .uint8('hasDischgCellVoltLimPower ') // Boolean 0 = Off , 1 = On\n .uint8('hasDischgCellTempLo ') // Boolean 0 = Off , 1 = On\n .uint8('hasDischgCellTempHi ') // Boolean 0 = Off , 1 = On\n .uint8('hasDischgAmbientLo ') // Boolean 0 = Off , 1 = On\n .uint8('hasDischgAmbientHi ') // Boolean 0 = Off , 1 = On\n .uint8('hasDischgSupplyVoltLo ') // Boolean 0 = Off , 1 = On\n .uint8('hasDischgSupplyVoltPause ') // Boolean 0 = Off , 1 = On\n .uint8('hasDischgShuntVoltLo ') // Boolean 0 = Off , 1 = On\n .uint8('hasDischgShuntVoltPause ') // Boolean 0 = Off , 1 = On\n .uint8('hasDischgShuntVoltLimPower ') // Boolean 0 = Off , 1 = On\n .uint8('hasDischgShuntSocLo ') // Boolean 0 = Off , 1 = On\n .uint8('hasDischgShuntSocPause ') // Boolean 0 = Off , 1 = On\n .uint8('isHeatOnState ') // Boolean 0 = Off , 1 = On\n .uint8('isHeatOnCalc ') // Boolean 0 = Off , 1 = On\n .uint8('isHeatTransition ') // Boolean 0 = Off , 1 = On\n .uint8('hasHeatAmbientLo ') // Boolean 0 = Off , 1 = On\n .uint8('hasHeatCellTempLo ') // Boolean 0 = Off , 1 = On\n .uint8('isCoolOnState') // Boolean 0 = Off , 1 = On\n .uint8('isCoolOnCalc') // Boolean 0 = Off , 1 = On\n .uint8('isCoolTransition') // Boolean 0 = Off , 1 = On\n .uint8('hasCoolAmbientHi ') // Boolean 0 = Off , 1 = On\n .uint8('hasCoolCellTempHi ') // Boolean 0 = Off , 1 = On\n .uint8('hasChargeBypassSessionLo ') // Boolean 0 = Off , 1 = On\n\nmsg.payload = typea.parse(buf);\n\nswitch(msg.payload.isChargePowerRateState) {\n case 0:\n msg.payload.isChargePowerRateState = \"Off\";\n break;\n case 2:\n msg.payload.isChargePowerRateState = \"Limited Power\";\n break;\n case 4:\n msg.payload.isChargePowerRateState = \"Normal Power\";\n break;\n default:\n msg.payload.isChargePowerRateState = \"Buggered\";\n}\n\nswitch(msg.payload.isDischgPowerRateState) {\n case 0:\n msg.payload.isDischgPowerRateState = \"Off\";\n break;\n case 2:\n msg.payload.isDischgPowerRateState = \"Limited Power\";\n break;\n case 4:\n msg.payload.isDischgPowerRateState = \"Normal Power\";\n break;\n default:\n msg.payload.isDischgPowerRateState = \"Buggered\";\n}\n\n\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 120,
"y": 1180,
"wires": [
[
"e07437e.312e7c8"
]
]
},
{
"id": "e07437e.312e7c8",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"d": true,
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 390,
"y": 1180,
"wires": []
},
{
"id": "17a67e5b.e13952",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Msg_4d34_HwExpansionSetup",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n\t\t.skip(8)\n\t\t.uint8('HwExpansionSetupVers') \n\t\t.uint8('HwExpansionTemplate') /* ExtensionTemplateOptions\n\t\t\t\tNone = 0,\n\t\t\t\tExpansionBoard 12v = 1,\n\t\t\t\tExpansionBoard 48v = 2,\n\t\t\t\tWatchMonCmC v2.0 = 3,\t*/\t\n\t\t.uint8('HwExpansionNeoPixelMode') /* NeoPixelExtStatusModes\n\t\t\t\tNone \t\t\t\t= 0,\n\t\t\t\tRepeat \t\t\t\t= 1,\n\t\t\t\tStatus + 7seg SoC% \t= 2,\n\t\t\t\tSolid SoC% 8seg \t= 3,\t*/\n\t\t.uint8('HwExpansionRelay1') /* ExpansionOutputAssignments\n\t\t\t\tNone = 0,\n\t\t\t\tManualOn = 1,\n\t\t\t\tCritical BattOk = 2,\n\t\t\t\tCharging On = 4,\n\t\t\t\tDischarging On = 5,\n\t\t\t\tHeating Required = 6,\n\t\t\t\tCooling Required = 7,\n\t\t\t\tRun / Idle input = 8,\n\t\t\t\tCharge / Normal input = 9,\n\t\t\t\tBypass Complete = 10,\n\t\t\t\tCharging Limited = 11,\n\t\t\t\tDischarging Limited = 12,\n\t\t\t\tCritical Recovery = 13,\n\t\t\t\tCritical PulseOn = 14,\n\t\t\t\tCritical PulseOff = 15,\n\t\t\t\tCritical Fault = 16,\n\t\t\t\tCritical PrechargeTimer = 17, */\n\t\t.uint8('HwExpansionRelay2') \t/* ExpansionOutputAssignments */\n\t\t.uint8('HwExpansionRelay3') \t/* ExpansionOutputAssignments */\n\t\t.uint8('HwExpansionRelay4')\t\t/* ExpansionOutputAssignments */\n\t\t.uint8('HwExpansionOutput5') \t/* ExpansionOutputAssignments */\n\t\t.uint8('HwExpansionOutput5') \t/* ExpansionOutputAssignments */\n\t\t.uint8('HwExpansionOutput7') \t/* ExpansionOutputAssignments */\n\t\t.uint8('HwExpansionOutput8') \t/* ExpansionOutputAssignments */\n\t\t.uint8('HwExpansionOutput9') \t/* ExpansionOutputAssignments */\n\t\t.uint8('HwExpansionOutput10') \t/* ExpansionOutputAssignments */\n\t\t.uint8('HwExpansionInput1') \t/* ExtensionInputOptions\n\t\t\t\tNone \t\t\t\t\t= 0,\n\t\t\t\tRun / Idle mode \t\t= 1,\n\t\t\t\tCharge / Normal mode \t= 2,\n\t\t\t\tCritical contact sensor - On = 3,\n\t\t\t\tCritical contact sensor - Fault = 4, */\n\t\t.uint8('HwExpansionInput2') \t/* ExtensionInputOptions */\n\t\t.uint8('HwExpansionInput3') \t/* ExtensionInputOptions */\n\t\t.uint8('HwExpansionInput4') \t/* ExtensionInputOptions */\n\t\t.uint8('HwExpansionInput5') \t/* ExtensionInputOptions */\n\t\t.uint8('HwExpansionInputAIN1') \n\t\t.uint8('HwExpansionInputAIN2') \n\t\t.int16le('HwExpansionCustomFeature1')\n\t\t.int16le('HwExpansionCustomFeature2')\nmsg.payload = typea.parse(buf);\n\nswitch(msg.payload.HwExpansionTemplate) {\n case 0:\n msg.payload.HwExpansionTemplate = \"None\";\n break;\n case 1:\n msg.payload.HwExpansionTemplate = \"ExpansionBoard 12v\";\n break;\n case 2:\n msg.payload.HwExpansionTemplate = \"ExpansionBoard 48v\";\n break;\n case 3:\n msg.payload.HwExpansionTemplate = \"WatchMonCmC v2.0\";\n break;\n default:\n msg.payload.HwExpansionTemplate = \"Buggered\";\n}\n\nswitch(msg.payload.HwExpansionNeoPixelMode) {\n case 0:\n msg.payload.HwExpansionNeoPixelMode = \"None\";\n break;\n case 1:\n msg.payload.HwExpansionNeoPixelMode = \"Repeat\";\n break;\n case 2:\n msg.payload.HwExpansionNeoPixelMode = \"Status + 7seg SoC%\";\n break;\n case 3:\n msg.payload.HwExpansionNeoPixelMode = \"Solid SoC% 8seg\";\n break;\n default:\n msg.payload.HwExpansionNeoPixelMode = \"Buggered\";\n}\n\nswitch(msg.payload.HwExpansionRelay1) {\n case 0:\n msg.payload.HwExpansionRelay1 = \"None\";\n break;\n case 1:\n msg.payload.HwExpansionRelay1 = \"ManualOn\";\n break;\n case 2:\n msg.payload.HwExpansionRelay1 = \"Critical BattOk\";\n break;\n case 3:\n msg.payload.HwExpansionRelay1 = \"Charging On\";\n break;\n case 4:\n msg.payload.HwExpansionRelay1 = \"Discharging On\";\n break;\n case 5:\n msg.payload.HwExpansionRelay1 = \"Heating Required\";\n break;\n case 6:\n msg.payload.HwExpansionRelay1 = \"Cooling Required\";\n break;\n case 7:\n msg.payload.HwExpansionRelay1 = \"Run / Idle input\";\n break;\n case 8:\n msg.payload.HwExpansionRelay1 = \"Charge / Normal input\";\n break;\n case 9:\n msg.payload.HwExpansionRelay1 = \"Bypass Complete\";\n break;\n case 10:\n msg.payload.HwExpansionRelay1 = \"Charging Limited\";\n break;\n case 11:\n msg.payload.HwExpansionRelay1 = \"Discharging Limited\";\n break;\n case 12:\n msg.payload.HwExpansionRelay1 = \"Critical Recovery\";\n break;\n case 13:\n msg.payload.HwExpansionRelay1 = \"Critical PulseOn\";\n break;\n case 14:\n msg.payload.HwExpansionRelay1 = \"Critical PulseOff\";\n break;\n case 105:\n msg.payload.HwExpansionRelay1 = \"Critical Fault\";\n break;\n case 16:\n msg.payload.HwExpansionRelay1 = \"Critical PrechargeTimer\";\n break;\n default:\n msg.payload.HwExpansionRelay1 = \"Buggered\";\n}\n\nswitch(msg.payload.HwExpansionInput1) {\n case 0:\n msg.payload.HwExpansionInput1 = \"None\";\n break;\n case 1:\n msg.payload.HwExpansionInput1 = \"Run / Idle mode\";\n break;\n case 2:\n msg.payload.HwExpansionInput1 = \"Charge / Normal mode\";\n break;\n case 3:\n msg.payload.HwExpansionInput1 = \"Critical contact sensor - On\";\n break;\n case 4:\n msg.payload.HwExpansionInput1 = \"Critical contact sensor - Fault\";\n break;\n default:\n msg.payload.HwExpansionInput1 = \"Buggered\";\n}\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 130,
"y": 1220,
"wires": [
[
"d4d7f79b.18b4d8"
]
]
},
{
"id": "d4d7f79b.18b4d8",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"d": true,
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 390,
"y": 1220,
"wires": []
},
{
"id": "e69dec4b.f16a1",
"type": "function",
"z": "e6fd3a1c.5e9548",
"d": true,
"name": "Msg_6132_StatusComms",
"func": "var Packet = global.get('binary_parser');\nvar buf = msg.payload;\n\nvar typea = new Packet()\n\n\t\t.skip(8)\n\t\t.uint32le('SystemTime') // Epoch\n\t\t.uint8('SystemOpStatus') /* Choices\n\t\t\t\tSimulator = 0, \t // LED = rainbow pulse\n\t\t\t\tIdle = 1, \t // LED = green slow pulse\n\t\t\t\tDischarging = 2, \t // LED = green solid \n\t\t\t\tSoC Empty = 3, \t // LED = green double blink\n\t\t\t\tCharging = 4, \t // LED = blue slow pulse\n\t\t\t\tFull = 5, \t // LED = blue double blink\n\t\t\t\tTimeout = 6, \t // LED = red solid\n\t\t\t\tCritical Pending = 7, // LED = red fast pulse\n\t\t\t\tCritical Offline = 8, // LED = red slow pulse\n\t\t\t\tMqtt Offline = 9, // LED = white blink\n\t\t\t\tAuth Setup = 10, // LED = white solid\n\t\t\t\tShunt Timeout = 11, // LED = red solid \t*/\n\t\t.uint8('SystemAuthMode') /* Choices\n\t\t\t\tDefault = 0,\n\t\t\t\tTechnician = 1,\n\t\t\t\tFactory = 2, */\n\t\t.int16le('SystemAuthToken')\n\t\t.int16le('SystemAuthRejectTicks')\n\t\t.uint8('WifiState') /* Choices WifiOpStates\n\t\t\t\tBroadcast Start = 0,\n\t\t\t\tBroadcast Prep = 1,\n\t\t\t\tBroadcast TxSetup = 2,\n\t\t\t\tBroadcast Running = 3,\n\t\t\t\tUsbCmd Start = 4,\n\t\t\t\tUsbCmd Running = 5,\n\t\t\t\tUsbCmd PassThru = 6,\n\t\t\t\tUsbProg Start = 7,\n\t\t\t\tUsbProg Running = 8,\n\t\t\t\tUsbProg PassThru = 9,\n\t\t\t\tOffline Start = 10,\n\t\t\t\tOffline Running = 11,\n\t\t\t\tOffline Stop = 12,\n\t\t\t\tLimited Start = 13,\n\t\t\t\tLimited Prep = 14,\n\t\t\t\tLimited Running = 15,\n\t\t\t\tJoinAp Start = 16,\n\t\t\t\tJoinAp Running = 17,\t*/\t\t\n\t\t.uint8('WifiTxCmdTicks') \n\t\t.uint8('WifiRxCmdTicks') \n\t\t.uint8('WifiRxUnknownTicks') \n\t\t.uint8('CanbusOpStatus') /* Choices \n\n\t\t\t\t \t*/\t\t\n\t\t.uint8('CanbusRxStatusTicks')\n\t\t.uint8('CanbusRxUnknownTicks')\n\t\t.uint8('CanbusRxStatusTicks')\n\t\t.uint8('ShuntPollerMode') /* Choices ShuntPollerModes\n\t\t\t\tIdle Start = 0,\n\t\t\t\tIdle = 1,\n\t\t\t\tSync Start = 2,\n\t\t\t\tSync Running = 3,\n\t\t\t\tNormal = 4,\n\t\t\t\tShuntMon2 SetupStart = 5,\n\t\t\t\tShuntMon2 SetupRunning = 6,\n\t\t\t\tShuntMon2 Normal = 7, */\n\t\t.uint8('ShuntStatus') /* Choices ShuntStatuses\n\t\t\t\tTimeout = 0,\n\t\t\t\tDischarging = 1,\n\t\t\t\tIdle = 2,\n\t\t\t\tCharging = 4 */\n\t\t.uint8('ShuntRxAmpTicks')\n\t\t.uint8('ShuntTxAmpTicks')\n\t\t.uint8('CmuPollerMode') \t /* Choices\n\t\t\t\tIdle = 0,\n\t\t\t\tNormal = 1,\n\t\t\t\tCollection Start = 2,\n\t\t\t\tCollection Running = 3,\n\t\t\t\tSync Start = 4,\n\t\t\t\tSync Running = 5,\n\t\t\t\tNetworkTest Start = 6,\n\t\t\t\tNetworkTest Running = 9,\n\t\t\t\tBypassTest Start = 7,\n\t\t\t\tBypassTest Running = 8,\n\t\t\t\tRebootAll Start = 10,\n\t\t\t\tRebooting AllDevices = 11,\n\t\t\t\tSimulator Start = 12,\n\t\t\t\tSimulator Running = 13, */\n\t\t\t.uint8('CmuOpStatus') /* Choices */\n\t\t\t.uint8('CmuTxCmdTicks')\n\t\t\t.uint8('CmuRxCmdTicks')\n\nmsg.payload = typea.parse(buf);\n\n// convert date(s)\nmsg.payload.SystemTime = new Date(msg.payload.SystemTime*1000);\n\nswitch(msg.payload.SystemOpStatus) {\n case 0:\n msg.payload.SystemOpStatus = \"Simulator\";\n break;\n case 1:\n msg.payload.SystemOpStatus = \"Idle\";\n break;\n case 2:\n msg.payload.SystemOpStatus = \"Discharging\";\n break;\n case 3:\n msg.payload.SystemOpStatus = \"SoC Empty\";\n break;\n case 4:\n msg.payload.SystemOpStatus = \"Charging\";\n break;\n case 5:\n msg.payload.SystemOpStatus = \"Full\";\n break;\n case 6:\n msg.payload.SystemOpStatus = \"Timeout\";\n break;\n case 7:\n msg.payload.SystemOpStatus = \"Critical Pending\";\n break;\n case 8:\n msg.payload.SystemOpStatus = \"Critical Offline\";\n break;\n case 9:\n msg.payload.SystemOpStatus = \"Mqtt Offline\";\n break;\n case 10:\n msg.payload.SystemOpStatus = \"Auth Setup\";\n break;\n case 11:\n msg.payload.SystemOpStatus = \"Shunt Timeout\";\n break;\n default:\n msg.payload.SystemOpStatus = \"Buggered\";\n}\n\nswitch(msg.payload.SystemAuthMode) {\n case 0:\n msg.payload.SystemAuthMode = \"Default\";\n break;\n case 1:\n msg.payload.SystemAuthMode = \"Technician\";\n break;\n case 2:\n msg.payload.SystemAuthMode = \"Factory\";\n break;\n default:\n msg.payload.SystemAuthMode = \"Buggered\";\n}\n\nswitch(msg.payload.WifiState) {\n case 0:\n msg.payload.WifiState = \"Broadcast Start\";\n break;\n case 1:\n msg.payload.WifiState = \"Broadcast Prep\";\n break;\n case 2:\n msg.payload.WifiState = \"Broadcast TxSetup\";\n break;\n case 3:\n msg.payload.WifiState = \"Broadcast Running\";\n break;\n case 4:\n msg.payload.WifiState = \"UsbCmd Start\";\n break;\n case 5:\n msg.payload.WifiState = \"UsbCmd Running\";\n break;\n case 6:\n msg.payload.WifiState = \"UsbCmd PassThru\";\n break;\n case 7:\n msg.payload.WifiState = \"UsbProg Start\";\n break;\n case 8:\n msg.payload.WifiState = \"UsbProg Running\";\n break;\n case 9:\n msg.payload.WifiState = \"UsbProg PassThru\";\n break;\n case 10:\n msg.payload.WifiState = \"Offline Start\";\n break;\n case 11:\n msg.payload.WifiState = \"Offline Running\";\n break;\n case 12:\n msg.payload.WifiState = \"Offline Stop\";\n break;\n case 13:\n msg.payload.WifiState = \"Limited Start\";\n break;\n case 14:\n msg.payload.WifiState = \"Limited Prep\";\n break;\n case 15:\n msg.payload.WifiState = \"Limited Running\";\n break;\n case 16:\n msg.payload.WifiState = \"JoinAp Start\";\n break;\n case 17:\n msg.payload.WifiState = \"JoinAp Running\";\n break;\n default:\n msg.payload.WifiState = \"Buggered\";\n}\n\nswitch(msg.payload.ShuntPollerMode) {\n case 0:\n msg.payload.ShuntPollerMode = \"Idle Start\";\n break;\n case 1:\n msg.payload.ShuntPollerMode = \"Idle\";\n break;\n case 2:\n msg.payload.ShuntPollerMode = \"Sync Start\";\n break;\n case 3:\n msg.payload.ShuntPollerMode = \"Sync Running\";\n break;\n case 4:\n msg.payload.ShuntPollerMode = \"Normal\";\n break;\n case 5:\n msg.payload.ShuntPollerMode = \"ShuntMon2 SetupStart\";\n break;\n case 6:\n msg.payload.ShuntPollerMode = \"ShuntMon2 SetupRunning\";\n break;\n case 7:\n msg.payload.ShuntPollerMode = \"ShuntMon2 Normal\";\n break;\n default:\n msg.payload.ShuntPollerMode = \"Buggered\";\n}\n\nswitch(msg.payload.ShuntStatus) {\n case 0:\n msg.payload.ShuntStatus = \"Timeout\";\n break;\n case 1:\n msg.payload.ShuntStatus = \"Discharging\";\n break;\n case 2:\n msg.payload.ShuntStatus = \"Idle\";\n break;\n case 4:\n msg.payload.ShuntStatus = \"Charging\";\n break;\n default:\n msg.payload.ShuntStatus = \"Buggered\";\n}\n/*\nswitch(msg.payload.CmuPollerMode) {\n case 0:\n msg.payload.CmuPollerMode = \"Idle\";\n break;\n case 1:\n msg.payload.CmuPollerMode = \"Normal\";\n break;\n case 2:\n msg.payload.CmuPollerMode = \"Collection Start\";\n break;\n case 3:\n msg.payload.CmuPollerMode = \"Collection Running\";\n break;\n case 4:\n msg.payload.CmuPollerMode = \"Sync Start\";\n break;\n case 5:\n msg.payload.CmuPollerMode = \"Sync Running\";\n break;\n case 6:\n msg.payload.CmuPollerMode = \"NetworkTest Start\";\n break;\n case 7:\n msg.payload.CmuPollerMode = \"NetworkTest Running\";\n break;\n case 8:\n msg.payload.CmuPollerMode = \"BypassTest Start\";\n break;\n case 9:\n msg.payload.CmuPollerMode = \"BypassTest Running\";\n break;\n case 10:\n msg.payload.CmuPollerMode = \"RebootAll Start\";\n break;\n case 11:\n msg.payload.CmuPollerMode = \"Rebooting AllDevices\";\n break;\n case 12:\n msg.payload.CmuPollerMode = \"Simulator Start\";\n break;\n case 13:\n msg.payload.CmuPollerMode = \"Simulator Running\";\n break;\n default:\n msg.payload.CmuPollerMode = \"Buggered\";\n}\n*/\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 110,
"y": 1260,
"wires": [
[
"15668e4f.43b272"
]
]
},
{
"id": "15668e4f.43b272",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"d": true,
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 390,
"y": 1260,
"wires": []
},
{
"id": "1febde5.094d722",
"type": "comment",
"z": "e6fd3a1c.5e9548",
"name": "Based on Watchmon SW 1.0.30 UDP Outbound protocol",
"info": "All credit for the parsers to Daniel Römer\nBased on his grafpi project:\nhttp://diytechandrepairs.nu/raspberry-solar/\n\nBatrium WatchMon 4\n\nThe machine running node red must be able \nto acces port 18542 UDP IPv4\n\n",
"x": 690,
"y": 240,
"wires": []
},
{
"id": "b2ab7d4c.b3ddd",
"type": "ui_text",
"z": "e6fd3a1c.5e9548",
"group": "605bdeca.e6347",
"order": 0,
"width": "3",
"height": "2",
"name": "GroupMinCellVolt",
"label": "Min Cell Voltage",
"format": "{{msg.payload.GroupMinCellVolt}}v",
"layout": "col-center",
"x": 830,
"y": 680,
"wires": []
},
{
"id": "68635fb7.0529d",
"type": "ui_text",
"z": "e6fd3a1c.5e9548",
"group": "605bdeca.e6347",
"order": 0,
"width": "3",
"height": "2",
"name": "GroupMaxCellVolt",
"label": "Max Cell Voltage",
"format": "{{msg.payload.GroupMaxCellVolt}}v",
"layout": "col-center",
"x": 830,
"y": 560,
"wires": []
},
{
"id": "7c2e474e.4fe348",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Cells Global variables for influx",
"func": "var ONE = global.get('ONE') || 0;\nvar TWO = global.get('TWO') || 0;\nvar THREE = global.get('THREE') || 0;\nvar FOUR = global.get('FOUR') || 0;\nvar FIVE = global.get('FIVE') || 0;\nvar SIX = global.get('SIX') || 0;\nvar SEVEN = global.get('SEVEN') || 0;\nvar EIGHT = global.get('EIGHT') || 0;\nvar NINE = global.get('NINE') || 0;\nvar TEN = global.get('TEN') || 0;\nvar ELEVEN = global.get('ELEVEN') || 0;\nvar TWELVE = global.get('TWELVE') || 0;\nvar THIRTEEN = global.get('THIRTEEN') || 0;\nvar FOURTEEN = global.get('FOURTEEN') || 0;\nvar FIFTEEN = global.get('FIFTEEN') || 0;\nvar SIXTEEN = global.get('SIXTEEN') || 0;\n\nmsg.payload =\n{\n Cell1: ONE,\n Cell2: TWO,\n Cell3: THREE,\n Cell4: FOUR,\n Cell5: FIVE,\n Cell6: SIX,\n Cell7: SEVEN,\n Cell8: EIGHT,\n Cell9: NINE,\n Cell10: TEN,\n Cell11: ELEVEN,\n Cell12: TWELVE,\n CELL13: THIRTEEN,\n CELL14: FOURTEEN,\n CELL15: FIFTEEN,\n CELL16: SIXTEEN,\n}\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 870,
"y": 100,
"wires": [
[
"6d22e4f3.72c97c",
"f27ec1c6.f257"
]
]
},
{
"id": "6d22e4f3.72c97c",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 1650,
"y": 100,
"wires": []
},
{
"id": "f27ec1c6.f257",
"type": "influxdb out",
"z": "e6fd3a1c.5e9548",
"influxdb": "bafffa78.f7bbc8",
"name": "Cell_Voltage",
"measurement": "Cell_Voltage",
"precision": "",
"retentionPolicy": "",
"database": "",
"retentionPolicyV18Flux": "",
"org": "",
"bucket": "",
"x": 1430,
"y": 120,
"wires": []
},
{
"id": "684ac7ee.c50fc8",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "DailyCumulShuntAh_C_D Influx",
"func": "var CSAD = 0;\nvar CSAC = 0;\nCSAD = Number(msg.payload.DailySessionCumulShuntAhDischg);\nCSAC = Number(msg.payload.DailySessionCumulShuntAhCharge);\nmsg.payload =\n{\n CumulShuntAhDischg: CSAD,\n CumulShuntAhCharge: CSAC,\n}\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 1190,
"y": 540,
"wires": [
[
"b957de47.0dd2f",
"a2d070e7.f7336"
]
]
},
{
"id": "b957de47.0dd2f",
"type": "influxdb out",
"z": "e6fd3a1c.5e9548",
"influxdb": "bafffa78.f7bbc8",
"name": "CumulShuntAh_C_D",
"measurement": "CumulShuntAh_C_D",
"precision": "",
"retentionPolicy": "",
"x": 1460,
"y": 560,
"wires": []
},
{
"id": "a2d070e7.f7336",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"x": 1650,
"y": 540,
"wires": []
},
{
"id": "b7222b59.93edf8",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Cell_Min_Max_Avg Influx",
"func": "var MiCV = 0;\nvar MaCV = 0;\nvar AvCV = 0;\nMiCV = Number(msg.payload.MinCellVolt);\nMaCV = Number(msg.payload.MaxCellVolt);\nAvCV = Number(msg.payload.AvgCellVolt);\nmsg.payload =\n{\n MiCV: MiCV,\n MaCV: MaCV,\n AvCV: AvCV,\n}\nreturn msg;\n",
"outputs": 1,
"noerr": 0,
"x": 1170,
"y": 220,
"wires": [
[
"ad2c8772.107fa8",
"25fa4777.c5eb08"
]
]
},
{
"id": "ad2c8772.107fa8",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"x": 1650,
"y": 220,
"wires": []
},
{
"id": "76bfaed9.eb6",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Shunt_C_V_W Influx",
"func": "var ShuntV = 0;\nvar ShuntC = 0;\nvar myCurrent = 0;\nvar myVoltage = 0;\nvar Watts = 0;\nShuntV = Number(msg.payload.ShuntVoltage);\nShuntC = Number(msg.payload.ShuntCurrent);\nmyCurrent = Number(msg.payload.ShuntCurrent);\nmyVoltage = Number(msg.payload.ShuntVoltage);\nWatts=myVoltage*myCurrent;\nmsg.payload =\n{\n ShuntV: ShuntV,\n ShuntC: ShuntC,\n Watts: Watts,\n}\nreturn msg;\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 1160,
"y": 180,
"wires": [
[
"71217755.f344d8",
"c324df89.b0e6c"
]
]
},
{
"id": "71217755.f344d8",
"type": "influxdb out",
"z": "e6fd3a1c.5e9548",
"influxdb": "bafffa78.f7bbc8",
"name": "Shunt_C_V_W",
"measurement": "Shunt_C_V_W",
"precision": "",
"retentionPolicy": "",
"database": "",
"retentionPolicyV18Flux": "",
"org": "",
"bucket": "",
"x": 1440,
"y": 160,
"wires": []
},
{
"id": "c324df89.b0e6c",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"x": 1650,
"y": 180,
"wires": []
},
{
"id": "6476769.7ee5988",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Shunt_Cap_F_E_SOC Influx",
"func": "var CtoF = 0;\nvar CtoE = 0;\nvar SOC = 0;\nCtoF = Number(msg.payload.NomCapacityToFull);\nCtoE = Number(msg.payload.NomCapacityToEmpty);\nSOC = Number(msg.payload.ShuntSOC);\nmsg.payload =\n{\n CtoF: CtoF,\n CtoE: CtoE,\n SOC: SOC,\n}\nreturn msg;\n",
"outputs": 1,
"noerr": 0,
"x": 1180,
"y": 680,
"wires": [
[
"2ee7190.18693e8",
"9c618b31.f4dd78"
]
]
},
{
"id": "2ee7190.18693e8",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"x": 1650,
"y": 680,
"wires": []
},
{
"id": "9c618b31.f4dd78",
"type": "influxdb out",
"z": "e6fd3a1c.5e9548",
"influxdb": "bafffa78.f7bbc8",
"name": "Shunt_Cap_F_E_SOC",
"measurement": "Shunt_Cap_F_E_SOC",
"precision": "",
"retentionPolicy": "",
"x": 1460,
"y": 700,
"wires": []
},
{
"id": "25fa4777.c5eb08",
"type": "influxdb out",
"z": "e6fd3a1c.5e9548",
"influxdb": "bafffa78.f7bbc8",
"name": "Cell_Min_Max_Avg",
"measurement": "Cell_Min_Max_Avg",
"precision": "",
"retentionPolicy": "",
"x": 1450,
"y": 200,
"wires": []
},
{
"id": "63dc95b5.2a2dcc",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Shunt_Status Influx",
"func": "var SS;\nSS = (msg.payload.ShuntStatus);\nmsg.payload =\n{\n SS: SS,\n}\nreturn msg;\n",
"outputs": 1,
"noerr": 0,
"x": 1150,
"y": 720,
"wires": [
[
"b2e669b.0600398",
"3f760caf.ca21e4"
]
]
},
{
"id": "b2e669b.0600398",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"x": 1650,
"y": 720,
"wires": []
},
{
"id": "3f760caf.ca21e4",
"type": "influxdb out",
"z": "e6fd3a1c.5e9548",
"influxdb": "bafffa78.f7bbc8",
"name": "Shunt_Status",
"measurement": "Shunt_Status",
"precision": "",
"retentionPolicy": "",
"x": 1480,
"y": 740,
"wires": []
},
{
"id": "7e92a896.171e58",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "DailySessionShuntPeak_C_D Influx",
"func": "var DSSPD = 0;\nvar DSSPC = 0;\nDSSPC = Number(msg.payload.DailySessionShuntPeakCharge);\nDSSPD = Number(msg.payload.DailySessionShuntPeakDischg);\nmsg.payload =\n{\n ShuntPeakCharge: DSSPC,\n ShuntPeakDischg: DSSPD,\n}\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 1200,
"y": 580,
"wires": [
[
"f0f77762.36efe8",
"37822374.97f4ec"
]
]
},
{
"id": "f0f77762.36efe8",
"type": "influxdb out",
"z": "e6fd3a1c.5e9548",
"influxdb": "bafffa78.f7bbc8",
"name": "ShuntPeak_C_D",
"measurement": "ShuntPeak_C_D",
"precision": "",
"retentionPolicy": "",
"x": 1470,
"y": 620,
"wires": []
},
{
"id": "37822374.97f4ec",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"x": 1650,
"y": 580,
"wires": []
},
{
"id": "ee919253.daba5",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"x": 1650,
"y": 920,
"wires": []
},
{
"id": "43701535.84212c",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 1650,
"y": 60,
"wires": []
},
{
"id": "739bdfbd.80809",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "ShuntVoltage",
"func": "var myNumber = 0;\nmyNumber = Number(msg.payload.ShuntVoltage);\nreturn { payload : myNumber.toFixed(2) };",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 1130,
"y": 260,
"wires": [
[
"d29957c5.1270e8",
"869abefc.09573",
"51929c.16d05d64"
]
]
},
{
"id": "d29957c5.1270e8",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"d": true,
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 1650,
"y": 260,
"wires": []
},
{
"id": "8fce0a5e.09d718",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "ShuntCurrent",
"func": "var myNumber = 0;\nmyNumber = Number(msg.payload.ShuntCurrent);\nreturn { payload : myNumber.toFixed(2) };",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 1130,
"y": 300,
"wires": [
[
"8c0ce1a3.2b188",
"5049668e.8aca08",
"f3feb017.6f298"
]
]
},
{
"id": "8c0ce1a3.2b188",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"d": true,
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 1650,
"y": 300,
"wires": []
},
{
"id": "bdb0b97d.26f5c8",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"d": true,
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 1650,
"y": 340,
"wires": []
},
{
"id": "ab145d35.a525d",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "ShuntWatts",
"func": "var myCurrent = 0;\nvar myVoltage = 0;\nvar myWatts = 0;\n\nmyCurrent = Number(msg.payload.ShuntCurrent);\nmyVoltage = Number(msg.payload.ShuntVoltage);\n\nmyWatts=myVoltage*myCurrent;\n\nreturn { payload : myWatts.toFixed(2) };",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 1130,
"y": 340,
"wires": [
[
"bdb0b97d.26f5c8",
"f81ecab4.48ca38"
]
]
},
{
"id": "5049668e.8aca08",
"type": "ui_text",
"z": "e6fd3a1c.5e9548",
"group": "605bdeca.e6347",
"order": 3,
"width": "0",
"height": "0",
"name": "Shunt Amps: ",
"label": "Shunt Amps: ",
"format": "{{msg.payload}}A",
"layout": "col-center",
"x": 1430,
"y": 320,
"wires": []
},
{
"id": "869abefc.09573",
"type": "ui_text",
"z": "e6fd3a1c.5e9548",
"group": "605bdeca.e6347",
"order": 2,
"width": "0",
"height": "0",
"name": "Shunt Volts: ",
"label": "Shunt Volts: ",
"format": "{{msg.payload}}v",
"layout": "col-center",
"x": 1430,
"y": 280,
"wires": []
},
{
"id": "f81ecab4.48ca38",
"type": "ui_text",
"z": "e6fd3a1c.5e9548",
"group": "605bdeca.e6347",
"order": 4,
"width": "0",
"height": "0",
"name": "Shunt Watts: ",
"label": "Shunt Watts: ",
"format": "{{msg.payload}}W",
"layout": "col-center",
"x": 1430,
"y": 360,
"wires": []
},
{
"id": "51929c.16d05d64",
"type": "ui_gauge",
"z": "e6fd3a1c.5e9548",
"name": "Shunt V",
"group": "b37bd0d4.0bb66",
"order": 7,
"width": 0,
"height": 0,
"gtype": "gage",
"title": "Shunt V",
"label": "units",
"format": "{{value}}",
"min": "40",
"max": "60",
"colors": [
"#eb3d1e",
"#e6e600",
"#52cb3a"
],
"seg1": "",
"seg2": "",
"x": 1280,
"y": 280,
"wires": []
},
{
"id": "f3feb017.6f298",
"type": "ui_gauge",
"z": "e6fd3a1c.5e9548",
"name": "Shunt A",
"group": "e2c441d6.9e1ae",
"order": 0,
"width": 0,
"height": 0,
"gtype": "gage",
"title": "Shunt A",
"label": "units",
"format": "{{value}}",
"min": "-50",
"max": "50",
"colors": [
"#b31200",
"#e6e600",
"#54c00c"
],
"seg1": "",
"seg2": "",
"x": 1280,
"y": 320,
"wires": []
},
{
"id": "d54ad04d.f5cb8",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "16 Cell ",
"func": "var ONE = Number(global.get('ONE')) || 0;\nvar TWO = Number(global.get('TWO')) || 0;\nvar THREE = Number(global.get('THREE')) || 0;\nvar FOUR = Number(global.get('FOUR')) || 0;\nvar FIVE = Number(global.get('FIVE')) || 0;\nvar SIX = Number(global.get('SIX')) || 0;\nvar SEVEN = Number(global.get('SEVEN')) || 0;\nvar EIGHT = Number(global.get('EIGHT')) || 0;\nvar NINE = Number(global.get('NINE')) || 0;\nvar TEN = Number(global.get('TEN')) || 0;\nvar ELEVEN = Number(global.get('ELEVEN')) || 0;\nvar TWELVE = Number(global.get('TWELVE')) || 0;\nvar THIRTEEN = Number(global.get('THIRTEEN')) || 0;\nvar FOURTEEN = Number(global.get('FOURTEEN')) || 0;\nvar FIFTEEN = Number(global.get('FIFTEEN')) || 0;\nvar SIXTEEN = Number(global.get('SIXTEEN')) || 0;\n\nvar m = {};\nm.series = [\"B1\", \"B2\"];\nm.data = [ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, ELEVEN, TWELVE, THIRTEEN, FOURTEEN, FIFTEEN, SIXTEEN];\nm.labels = [\"\"];\nreturn {payload:[m],topic:msg.topic};",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 800,
"y": 60,
"wires": [
[
"5c74ba3e.11c214"
]
]
},
{
"id": "9a44bb7a.474bd8",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Est to full/empty min influx",
"func": "var EDF;\nvar EDE;\nEDF = (msg.payload.EstDurationToFullmins);\nEDE = (msg.payload.EstDurationToEmptymins);\nmsg.payload =\n{\n EDF: EDF,\n EDE: EDE,\n}\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 1170,
"y": 460,
"wires": [
[
"b2853dfb.645d9",
"d280fff4.b0597"
]
]
},
{
"id": "b2853dfb.645d9",
"type": "debug",
"z": "e6fd3a1c.5e9548",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"x": 1650,
"y": 460,
"wires": []
},
{
"id": "d280fff4.b0597",
"type": "influxdb out",
"z": "e6fd3a1c.5e9548",
"influxdb": "bafffa78.f7bbc8",
"name": "EST-Full_Empty_Min",
"measurement": "EST-Full_Empty_Min",
"precision": "",
"retentionPolicy": "",
"x": 1460,
"y": 480,
"wires": []
},
{
"id": "90437fe0.fcd83",
"type": "function",
"z": "e6fd3a1c.5e9548",
"name": "Test",
"func": "var EDTF;\nvar EDTE;\nEDTF = (msg.payload.EstDurationToFullmins);\nEDTE = (msg.payload.EstDurationToEmptymins);\nmsg.payload =\n{\n EDTF: EDTF,\n EDTE: EDTE,\n}\nreturn msg;\n",
"outputs": 1,
"noerr": 0,
"x": 1510,
"y": 840,
"wires": [
[
"df5c7d37.bd20b"
]
]
},
{
"id": "5c74ba3e.11c214",
"type": "ui_chart",
"z": "e6fd3a1c.5e9548",
"name": "",
"group": "b0f57fc2.e496c",
"order": 0,
"width": 0,
"height": 0,
"label": "chart",
"chartType": "bar",
"legend": "false",
"xformat": "HH:mm:ss",
"interpolate": "linear",
"nodata": "",
"dot": false,
"ymin": "3",
"ymax": "4.2",
"removeOlder": 1,
"removeOlderPoints": "",
"removeOlderUnit": "3600",
"cutout": 0,
"useOneColor": false,
"useUTC": false,
"colors": [
"#1f77b4",
"#aec7e8",
"#ff7f0e",
"#2ca02c",
"#98df8a",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"outputs": 1,
"x": 950,
"y": 60,
"wires": [
[]
]
},
{
"id": "605bdeca.e6347",
"type": "ui_group",
"name": "16 Cell",
"tab": "f3fb9943.a12128",
"order": 2,
"disp": true,
"width": "6",
"collapse": false
},
{
"id": "bafffa78.f7bbc8",
"type": "influxdb",
"hostname": "localhost",
"port": "8086",
"protocol": "http",
"database": "batrium",
"name": "",
"usetls": false,
"tls": "",
"influxdbVersion": "1.x",
"url": "",
"rejectUnauthorized": false
},
{
"id": "b37bd0d4.0bb66",
"type": "ui_group",
"name": "ShuntV",
"tab": "f3fb9943.a12128",
"order": 3,
"disp": true,
"width": "6",
"collapse": false
},
{
"id": "e2c441d6.9e1ae",
"type": "ui_group",
"name": "Shunt A",
"tab": "f3fb9943.a12128",
"order": 1,
"disp": true,
"width": "6",
"collapse": false
},
{
"id": "b0f57fc2.e496c",
"type": "ui_group",
"name": "7 Cell",
"tab": "f3fb9943.a12128",
"order": 4,
"disp": true,
"width": "6",
"collapse": false
},
{
"id": "f3fb9943.a12128",
"type": "ui_tab",
"name": "Watchmon",
"icon": "dashboard",
"order": 2,
"disabled": false,
"hidden": false
}
]