[ { "id": "e5a14b97656525b2", "type": "tab", "label": "Flow 1", "disabled": false, "info": "// nrlint no-loops:off, function-eslint:off\n", "env": [] }, { "id": "6dcc47acdd010392", "type": "serial-port", "serialport": "/dev/ttyUSB0", "serialbaud": "250000", "databits": "8", "parity": "none", "stopbits": "1", "waitfor": "", "dtr": "none", "rts": "none", "cts": "none", "dsr": "none", "newline": "\\r", "bin": "false", "out": "char", "addchar": "\\n", "responsetimeout": "10000" }, { "id": "2d58ef73b13e77b5", "type": "ui_base", "theme": { "name": "theme-light", "lightTheme": { "default": "#0094CE", "baseColor": "#0094CE", "baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif", "edited": true, "reset": false }, "darkTheme": { "default": "#097479", "baseColor": "#097479", "baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif", "edited": false }, "customTheme": { "name": "Untitled Theme 1", "default": "#4B7930", "baseColor": "#4B7930", "baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif" }, "themeState": { "base-color": { "default": "#0094CE", "value": "#0094CE", "edited": false }, "page-titlebar-backgroundColor": { "value": "#0094CE", "edited": false }, "page-backgroundColor": { "value": "#fafafa", "edited": false }, "page-sidebar-backgroundColor": { "value": "#ffffff", "edited": false }, "group-textColor": { "value": "#1bbfff", "edited": false }, "group-borderColor": { "value": "#ffffff", "edited": false }, "group-backgroundColor": { "value": "#ffffff", "edited": false }, "widget-textColor": { "value": "#111111", "edited": false }, "widget-backgroundColor": { "value": "#0094ce", "edited": false }, "widget-borderColor": { "value": "#ffffff", "edited": false }, "base-font": { "value": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif" } }, "angularTheme": { "primary": "indigo", "accents": "blue", "warn": "red", "background": "grey", "palette": "light" } }, "site": { "name": "Node-RED Dashboard", "hideToolbar": "false", "allowSwipe": "false", "lockMenu": "false", "allowTempTheme": "true", "dateFormat": "DD/MM/YYYY", "sizes": { "sx": 48, "sy": 48, "gx": 6, "gy": 6, "cx": 6, "cy": 6, "px": 0, "py": 0 } } }, { "id": "13226a88cd3dcc52", "type": "ui_group", "name": "Battery status", "tab": "e2b1d23efc58d519", "order": 2, "disp": false, "width": "7", "collapse": false, "className": "" }, { "id": "e2b1d23efc58d519", "type": "ui_tab", "name": "Battery", "icon": "dashboard", "disabled": false, "hidden": false }, { "id": "e81b8c03483fddb9", "type": "ui_group", "name": "", "tab": "e2b1d23efc58d519", "order": 1, "disp": true, "width": "6", "collapse": false, "className": "" }, { "id": "9bd690c74714e0c2", "type": "serial out", "z": "e5a14b97656525b2", "name": "manual commands out", "serial": "6dcc47acdd010392", "x": 680, "y": 320, "wires": [] }, { "id": "31d085d59b856ba3", "type": "serial in", "z": "e5a14b97656525b2", "name": "", "serial": "6dcc47acdd010392", "x": 310, "y": 200, "wires": [ [ "0e454fe28c6921d7", "bbdc972684e5bce6", "977e5dbd93dc0213" ] ] }, { "id": "15a3bb2d132af445", "type": "inject", "z": "e5a14b97656525b2", "name": "", "props": [ { "p": "payload" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "V", "payloadType": "str", "x": 290, "y": 320, "wires": [ [ "9bd690c74714e0c2", "81f40af8f862b13a" ] ] }, { "id": "81f40af8f862b13a", "type": "debug", "z": "e5a14b97656525b2", "name": "manual commands", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 670, "y": 380, "wires": [] }, { "id": "0e454fe28c6921d7", "type": "debug", "z": "e5a14b97656525b2", "name": "monitor of serial input", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 600, "y": 200, "wires": [] }, { "id": "15493eef3a243cef", "type": "inject", "z": "e5a14b97656525b2", "name": "", "props": [ { "p": "payload" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "C", "payloadType": "str", "x": 290, "y": 360, "wires": [ [ "9bd690c74714e0c2", "81f40af8f862b13a" ] ] }, { "id": "50a373d5725f19c4", "type": "inject", "z": "e5a14b97656525b2", "name": "", "props": [ { "p": "payload" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "S5", "payloadType": "str", "x": 290, "y": 400, "wires": [ [ "9bd690c74714e0c2", "81f40af8f862b13a" ] ] }, { "id": "84d7fc64b0e2e44e", "type": "inject", "z": "e5a14b97656525b2", "name": "", "props": [ { "p": "payload" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "O", "payloadType": "str", "x": 290, "y": 440, "wires": [ [ "9bd690c74714e0c2", "81f40af8f862b13a" ] ] }, { "id": "d0555e9d66f17a12", "type": "serial request", "z": "e5a14b97656525b2", "name": "CAN serial request", "serial": "6dcc47acdd010392", "x": 790, "y": 500, "wires": [ [ "73e61269a2b9dcdb" ] ] }, { "id": "73e61269a2b9dcdb", "type": "function", "z": "e5a14b97656525b2", "name": "Auto-Start CAN Messaging", "func": "\nif (msg.payload == \"S5\") {\n return msg;\n}\nif (msg.request_payload == \"S5\") {\n msg.payload = \"O\";\n return msg;\n}", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 540, "y": 500, "wires": [ [ "d0555e9d66f17a12" ] ] }, { "id": "85d95944eb21e7f3", "type": "inject", "z": "e5a14b97656525b2", "name": "Start auto", "props": [ { "p": "payload" } ], "repeat": "", "crontab": "", "once": true, "onceDelay": 0.1, "topic": "", "payload": "S5", "payloadType": "str", "x": 280, "y": 500, "wires": [ [ "73e61269a2b9dcdb" ] ] }, { "id": "bbdc972684e5bce6", "type": "ui_text", "z": "e5a14b97656525b2", "group": "13226a88cd3dcc52", "order": 0, "width": 0, "height": 0, "name": "", "label": "Full CANbus telegram", "format": "{{msg.payload}}", "layout": "col-center", "className": "", "style": false, "font": "", "fontSize": 16, "color": "#000000", "x": 600, "y": 240, "wires": [] }, { "id": "977e5dbd93dc0213", "type": "function", "z": "e5a14b97656525b2", "name": "Decode BMS telegrams", "func": "// Create decode messages\nmsg.decode = {};\nmsg.result = {};\n// Parse message id\nmsg.decode.id = msg.payload.slice(1, 9);\n// Parse message length\nmsg.decode.length = msg.payload[9];\n// Remove parsed data\nmsg.payload = msg.payload.slice(10, (msg.payload.length) * 2 + 1);\n switch (msg.decode.id) { \n case \"18FEEB46\":\n node.warn(\"ProductIDstring\");\n let ProductIDstring = msg.payload.slice(0, 16); \n msg.result.idstring = ProductIDstring;\n node.warn(\"ProductIDresult\");\n let PIDel0 = String.fromCharCode(parseInt(msg.payload.slice(0, 2), 16));\n let PIDel1 = String.fromCharCode(parseInt(msg.payload.slice(2, 4), 16));\n let PIDel2 = String.fromCharCode(parseInt(msg.payload.slice(4, 6), 16));\n let PIDel3 = String.fromCharCode(parseInt(msg.payload.slice(6, 8), 16));\n let PIDel4 = String.fromCharCode(parseInt(msg.payload.slice(8, 10), 16));\n let PIDel5 = String.fromCharCode(parseInt(msg.payload.slice(10, 12), 16));\n let PIDel6 = String.fromCharCode(parseInt(msg.payload.slice(12, 14), 16));\n let PIDel7 = String.fromCharCode(parseInt(msg.payload.slice(14, 16), 16));\n let CurrentProdID = String(PIDel0 + PIDel1 + PIDel2 + PIDel3 + PIDel4 + PIDel5 + PIDel6 + PIDel7);\n msg.result.ProdID = CurrentProdID;\n global.set(\"resultID\", CurrentProdID);\n break;\n case \"19FFFD46\":\n node.warn(\"Voltage\");\n let VoltageHexHB = msg.payload.slice(4, 6);\n let VoltageHexLB = msg.payload.slice(6, 8);\n let VoltageINT = parseInt(VoltageHexLB + VoltageHexHB, 16) / 20;\n msg.result.voltage = VoltageINT;\n global.set(\"resultvoltage\", VoltageINT);\n node.warn(\"Current\");\n let CurrentHexLBL = msg.payload.slice(8, 10);\n let CurrentHexLBH = msg.payload.slice(10, 12);\n let CurrentHexHBL = msg.payload.slice(12, 14);\n let CurrentHexHBH = msg.payload.slice(14, 16);\n let CurrentINT = (parseInt(CurrentHexHBH + CurrentHexHBL + CurrentHexLBH + CurrentHexLBL, 16) - 2000000000) * 0.001;\n msg.result.current = CurrentINT;\n global.set(\"resultcurrent\", CurrentINT);\n break; \n case \"19FECA46\":\n node.warn(\"PowerON/OFF\");\n let Power = msg.payload.slice(1, 2);\n let powerStat = parseInt(Power, 16);\n if (powerStat === 1) {\n msg.result.powerstat = \"Power is OFF\"\n }\n if (powerStat === 5) {\n msg.result.powerstat = \"Power is ON\"\n } \n global.set(\"resultpower\", msg.result.powerstat); \n break; \n case \"19FFFC46\":\n node.warn(\"Temperature\");\n let TempertureHexHB = msg.payload.slice(4, 6);\n let TempertureHexLB = msg.payload.slice(6, 8);\n let TempertureINT = (parseInt(TempertureHexLB + TempertureHexHB, 16) - 8736) * 0.03125;\n msg.result.temperature_C = TempertureINT;\n msg.result.temperature_F = (TempertureINT * 9) / 5 + 32;\n global.set(\"resulttempC\", TempertureINT);\n global.set(\"resulttempF\", msg.result.temperature_F);\n node.warn(\"State Of Charge\");\n let SOCHex = msg.payload.slice(8, 10);\n let SOCINT = parseInt(SOCHex, 16) / 2;\n msg.result.SOC = SOCINT;\n global.set(\"resultSOC\", SOCINT);\n node.warn(\"Remaining Discharge Time\");\n let RDTHexHB = msg.payload.slice(10, 12);\n let RDTHexLB = msg.payload.slice(12, 14);\n let RDTINT = parseInt(RDTHexLB + RDTHexHB, 16);\n msg.result.RDT = RDTINT;\n global.set(\"resultRDT\", RDTINT);\n break;\n case \"19FFFB46\":\n node.warn(\"Remaining Discharge Capacity\");\n let RDCHexHB = msg.payload.slice(6, 8);\n let RDCHexLB = msg.payload.slice(8, 10);\n let RDCINT = parseInt(RDCHexLB + RDCHexHB, 16);\n msg.result.RDC = RDCINT;\n global.set(\"resultRDC\", RDCINT);\n break; \n} \nmsg.ProductID = global.get(\"resultID\");\nmsg.actvoltvalue = global.get(\"resultvoltage\");\nmsg.actcurrentvalue = global.get(\"resultcurrent\");\nmsg.actpowerstatus = global.get(\"resultpower\");\nmsg.acttempCvalue = global.get(\"resulttempC\");\nmsg.acttempFvalue = global.get(\"resulttempF\");\nmsg.actSOCvalue = global.get(\"resultSOC\");\nmsg.actRDTvalue = global.get(\"resultRDT\");\nmsg.actRDCvalue = global.get(\"resultRDC\"); \nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 610, "y": 160, "wires": [ [ "e0e95772250aed21", "680f31a15fd3963b", "7fdaaaf73f0f65b1", "f9cb9946bf5cfd82", "8cb2cc8e121cbe1a", "c6a73f345dcca1b8", "3f8e630694019655", "7ad1cf0c6928ff1b", "d398ef35b26cf868" ] ] }, { "id": "e0e95772250aed21", "type": "ui_text", "z": "e5a14b97656525b2", "group": "13226a88cd3dcc52", "order": 1, "width": 0, "height": 0, "name": "", "label": "Product ID", "format": "{{msg.ProductID}}", "layout": "row-spread", "className": "", "style": false, "font": "", "fontSize": 16, "color": "#000000", "x": 1070, "y": 200, "wires": [] }, { "id": "680f31a15fd3963b", "type": "ui_text", "z": "e5a14b97656525b2", "group": "13226a88cd3dcc52", "order": 2, "width": 0, "height": 0, "name": "", "label": "Actual Voltage", "format": "{{msg.actvoltvalue}} Volt", "layout": "row-spread", "className": "", "style": false, "font": "", "fontSize": 16, "color": "#000000", "x": 1080, "y": 240, "wires": [] }, { "id": "7fdaaaf73f0f65b1", "type": "ui_text", "z": "e5a14b97656525b2", "group": "13226a88cd3dcc52", "order": 3, "width": 0, "height": 0, "name": "", "label": "Actual Current", "format": "{{msg.actcurrentvalue}} Amp", "layout": "row-spread", "className": "", "style": false, "font": "", "fontSize": 16, "color": "#000000", "x": 1080, "y": 280, "wires": [] }, { "id": "f9cb9946bf5cfd82", "type": "debug", "z": "e5a14b97656525b2", "name": "results", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "result", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 1030, "y": 160, "wires": [] }, { "id": "01ddc31dd9175cc0", "type": "inject", "z": "e5a14b97656525b2", "name": "PowerOFF", "props": [ { "p": "payload" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "X19FEA44680100000000000000", "payloadType": "str", "x": 120, "y": 280, "wires": [ [ "9bd690c74714e0c2", "81f40af8f862b13a" ] ] }, { "id": "195842610f8448c7", "type": "ui_button", "z": "e5a14b97656525b2", "name": "PowerOff", "group": "13226a88cd3dcc52", "order": 8, "width": "4", "height": "1", "passthru": false, "label": "PowerOFF", "tooltip": "", "color": "", "bgcolor": "green", "className": "", "icon": "", "payload": "X19FEA44680100000000000000", "payloadType": "str", "topic": "topic", "topicType": "msg", "x": 120, "y": 240, "wires": [ [ "81f40af8f862b13a", "9bd690c74714e0c2" ] ] }, { "id": "e80c6da86f83812e", "type": "ui_button", "z": "e5a14b97656525b2", "name": "PowerOn", "group": "13226a88cd3dcc52", "order": 9, "width": "3", "height": "1", "passthru": false, "label": "PowerON", "tooltip": "", "color": "", "bgcolor": "red", "className": "", "icon": "", "payload": "X19FEA44680101000000000000", "payloadType": "str", "topic": "topic", "topicType": "msg", "x": 120, "y": 200, "wires": [ [ "9bd690c74714e0c2", "81f40af8f862b13a" ] ] }, { "id": "8cb2cc8e121cbe1a", "type": "ui_gauge", "z": "e5a14b97656525b2", "name": "", "group": "e81b8c03483fddb9", "order": 1, "width": 6, "height": 3, "gtype": "gage", "title": "State of charge (%)", "label": "%", "format": "{{msg.actSOCvalue}}", "min": 0, "max": "100", "colors": [ "#c80000", "#e6e600", "#00c800" ], "seg1": "40", "seg2": "75", "diff": false, "className": "", "x": 1090, "y": 360, "wires": [] }, { "id": "c6a73f345dcca1b8", "type": "ui_text", "z": "e5a14b97656525b2", "group": "13226a88cd3dcc52", "order": 4, "width": 0, "height": 0, "name": "", "label": "Temperature", "format": "{{msg.acttempFvalue}} deg F", "layout": "row-spread", "className": "", "style": false, "font": "", "fontSize": 16, "color": "#000000", "x": 1070, "y": 400, "wires": [] }, { "id": "3f8e630694019655", "type": "ui_text", "z": "e5a14b97656525b2", "group": "13226a88cd3dcc52", "order": 5, "width": 0, "height": 0, "name": "", "label": "Remaining Discharge Capacity", "format": "{{msg.actRDCvalue}} Ah", "layout": "row-spread", "className": "", "style": false, "font": "", "fontSize": 16, "color": "#000000", "x": 1070, "y": 440, "wires": [] }, { "id": "7ad1cf0c6928ff1b", "type": "ui_text", "z": "e5a14b97656525b2", "group": "13226a88cd3dcc52", "order": 6, "width": 0, "height": 0, "name": "", "label": "Remaining Discharge Time", "format": "{{msg.actRDTvalue}} min", "layout": "row-spread", "className": "", "style": false, "font": "", "fontSize": 16, "color": "#000000", "x": 1060, "y": 480, "wires": [] }, { "id": "d398ef35b26cf868", "type": "ui_text", "z": "e5a14b97656525b2", "group": "13226a88cd3dcc52", "order": 7, "width": 0, "height": 0, "name": "", "label": "Power Status", "format": "{{msg.actpowerstatus}}", "layout": "row-spread", "className": "", "style": false, "font": "", "fontSize": 16, "color": "#000000", "x": 1070, "y": 320, "wires": [] } ]