[ { "id": "f96eea4d4a3a345d", "type": "tab", "label": "Meters", "disabled": false, "info": "", "env": [] }, { "id": "79ff2bd4c3604f42", "type": "inject", "z": "f96eea4d4a3a345d", "name": "Poll every 3 sec", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "3", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 180, "y": 400, "wires": [ [ "5c5702e7ebd71a77", "ccf9f0980f83375d", "e2571df80f480199", "165c27082bf35d11", "71afb139032cfee2", "972360a051abdf88", "21e06b0168fdee41", "e107fc40d203f46a", "7586c0c0ec778dad" ] ] }, { "id": "63e9e27d8597ced3", "type": "http in", "z": "f96eea4d4a3a345d", "name": "", "url": "/meters", "method": "get", "upload": false, "swaggerDoc": "", "x": 120, "y": 880, "wires": [ [ "c61fcb67b3a33b47" ] ] }, { "id": "fbe8cca3419d8161", "type": "change", "z": "f96eea4d4a3a345d", "name": "set http header", "rules": [ { "t": "set", "p": "headers", "pt": "msg", "to": "{}", "tot": "json" }, { "t": "set", "p": "headers.content-type", "pt": "msg", "to": "application/json", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1150, "y": 880, "wires": [ [ "83f39f5649b78b86" ] ] }, { "id": "83f39f5649b78b86", "type": "http response", "z": "f96eea4d4a3a345d", "name": "serve as http api", "statusCode": "", "headers": {}, "x": 1420, "y": 880, "wires": [] }, { "id": "c61fcb67b3a33b47", "type": "function", "z": "f96eea4d4a3a345d", "name": "Create java objects", "func": "var grid_total_power = parseFloat(global.get(\"grid_total_power\"))\n\nvar grid_l1_voltage = parseFloat(global.get(\"grid_l1_voltage\"))\nvar grid_l2_voltage = parseFloat(global.get(\"grid_l2_voltage\"))\nvar grid_l3_voltage = parseFloat(global.get(\"grid_l3_voltage\"))\n\nvar grid_l1_current = parseFloat(global.get(\"grid_l1_current\"))\nvar grid_l2_current = parseFloat(global.get(\"grid_l2_current\"))\nvar grid_l3_current = parseFloat(global.get(\"grid_l3_current\"))\n\nvar grid_l1_power = parseFloat(global.get(\"grid_l1_power\"))\nvar grid_l2_power = parseFloat(global.get(\"grid_l2_power\"))\nvar grid_l3_power = parseFloat(global.get(\"grid_l3_power\"))\n\nvar grid_l1_import = parseFloat(global.get(\"grid_l1_import\"))\nvar grid_l2_import = parseFloat(global.get(\"grid_l2_import\"))\nvar grid_l3_import = parseFloat(global.get(\"grid_l3_import\"))\n\nvar grid_l1_export = parseFloat(global.get(\"grid_l1_export\"))\nvar grid_l2_export = parseFloat(global.get(\"grid_l2_export\"))\nvar grid_l3_export = parseFloat(global.get(\"grid_l3_export\"))\n\n//Totals\nvar grid_total_current = grid_l1_current + grid_l2_current + grid_l3_current\nvar grid_total_import = parseFloat(global.get(\"grid_total_import\"))\nvar grid_total_export = parseFloat(global.get(\"grid_total_export\"))\n\nmsg.payload.grid = {total_power:grid_total_power, total_current:grid_total_current, total_import:grid_total_import, total_export:grid_total_export, l1_voltage:grid_l1_voltage, l2_voltage:grid_l2_voltage, l3_voltage:grid_l3_voltage, l1_current:grid_l1_current, l2_current:grid_l2_current, l3_current:grid_l3_current, l1_power:grid_l1_power, l2_power:grid_l2_power, l3_power:grid_l3_power, l1_import:grid_l1_import, l2_import:grid_l2_import, l3_import:grid_l3_import, l1_export:grid_l1_export, l2_export:grid_l2_export, l3_export:grid_l3_export};\n\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 510, "y": 880, "wires": [ [ "307db2619dcf6228" ] ] }, { "id": "307db2619dcf6228", "type": "json", "z": "f96eea4d4a3a345d", "name": "build json object", "property": "payload", "action": "", "pretty": false, "x": 910, "y": 880, "wires": [ [ "fbe8cca3419d8161" ] ] }, { "id": "5c5702e7ebd71a77", "type": "http request", "z": "f96eea4d4a3a345d", "name": "Voltage L1", "method": "GET", "ret": "txt", "paytoqs": "ignore", "url": "http://10.1.0.5/cgi-bin/readVal.exe?PDP,%20R100,d", "tls": "", "persist": false, "proxy": "", "authType": "", "senderr": false, "x": 560, "y": 140, "wires": [ [ "f5853a536891d509" ] ] }, { "id": "f5853a536891d509", "type": "function", "z": "f96eea4d4a3a345d", "name": "format and save to global var", "func": "temp = parseFloat(msg.payload * 0.1).toFixed(1);\nglobal.set(\"grid_l1_voltage\", temp)\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 940, "y": 140, "wires": [ [] ] }, { "id": "ccf9f0980f83375d", "type": "http request", "z": "f96eea4d4a3a345d", "name": "Voltage L2", "method": "GET", "ret": "txt", "paytoqs": "ignore", "url": "http://10.1.0.5/cgi-bin/readVal.exe?PDP,%20R101,d", "tls": "", "persist": false, "proxy": "", "authType": "", "senderr": false, "x": 560, "y": 180, "wires": [ [ "a3b33ef1225b85e7" ] ] }, { "id": "a3b33ef1225b85e7", "type": "function", "z": "f96eea4d4a3a345d", "name": "format and save to global var", "func": "temp = parseFloat(msg.payload * 0.1).toFixed(1);\nglobal.set(\"grid_l2_voltage\", temp)\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 940, "y": 180, "wires": [ [] ] }, { "id": "e2571df80f480199", "type": "http request", "z": "f96eea4d4a3a345d", "name": "Voltage L3", "method": "GET", "ret": "txt", "paytoqs": "ignore", "url": "http://10.1.0.5/cgi-bin/readVal.exe?PDP,%20R102,d", "tls": "", "persist": false, "proxy": "", "authType": "", "senderr": false, "x": 560, "y": 220, "wires": [ [ "b284d02cb539994f" ] ] }, { "id": "b284d02cb539994f", "type": "function", "z": "f96eea4d4a3a345d", "name": "format and save to global var", "func": "temp = parseFloat(msg.payload * 0.1).toFixed(1);\nglobal.set(\"grid_l3_voltage\", temp)\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 940, "y": 220, "wires": [ [] ] }, { "id": "165c27082bf35d11", "type": "http request", "z": "f96eea4d4a3a345d", "name": "Current L1", "method": "GET", "ret": "txt", "paytoqs": "ignore", "url": "http://10.1.0.5/cgi-bin/readVal.exe?PDP,%20R103,d", "tls": "", "persist": false, "proxy": "", "authType": "", "senderr": false, "x": 560, "y": 260, "wires": [ [ "1da7740caa290264" ] ] }, { "id": "1da7740caa290264", "type": "function", "z": "f96eea4d4a3a345d", "name": "format and save to global var", "func": "temp = parseFloat(msg.payload * 0.001).toFixed(1);\nglobal.set(\"grid_l1_current\", temp)\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 940, "y": 260, "wires": [ [] ] }, { "id": "71afb139032cfee2", "type": "http request", "z": "f96eea4d4a3a345d", "name": "Current L2", "method": "GET", "ret": "txt", "paytoqs": "ignore", "url": "http://10.1.0.5/cgi-bin/readVal.exe?PDP,%20R104,d", "tls": "", "persist": false, "proxy": "", "authType": "", "senderr": false, "x": 560, "y": 300, "wires": [ [ "6c9ebd253a3c3b0d" ] ] }, { "id": "6c9ebd253a3c3b0d", "type": "function", "z": "f96eea4d4a3a345d", "name": "format and save to global var", "func": "temp = parseFloat(msg.payload * 0.001).toFixed(1);\nglobal.set(\"grid_l2_current\", temp)\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 940, "y": 300, "wires": [ [] ] }, { "id": "972360a051abdf88", "type": "http request", "z": "f96eea4d4a3a345d", "name": "Current L3", "method": "GET", "ret": "txt", "paytoqs": "ignore", "url": "http://10.1.0.5/cgi-bin/readVal.exe?PDP,%20R105,d", "tls": "", "persist": false, "proxy": "", "authType": "", "senderr": false, "x": 560, "y": 340, "wires": [ [ "d848102461062b3f" ] ] }, { "id": "d848102461062b3f", "type": "function", "z": "f96eea4d4a3a345d", "name": "format and save to global var", "func": "temp = parseFloat(msg.payload * 0.001).toFixed(1);\nglobal.set(\"grid_l3_current\", temp)\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 940, "y": 340, "wires": [ [] ] }, { "id": "21e06b0168fdee41", "type": "http request", "z": "f96eea4d4a3a345d", "name": "Power L1", "method": "GET", "ret": "txt", "paytoqs": "ignore", "url": "http://10.1.0.5/cgi-bin/readVal.exe?PDP,%20R106,d", "tls": "", "persist": false, "proxy": "", "authType": "", "senderr": false, "x": 550, "y": 380, "wires": [ [ "3e88cef8b8b508ac" ] ] }, { "id": "3e88cef8b8b508ac", "type": "function", "z": "f96eea4d4a3a345d", "name": "format and save to global var", "func": "temp = parseFloat(msg.payload * 0.1).toFixed(1);\nglobal.set(\"grid_l1_power\", temp);\nmsg.payload = parseFloat(temp);\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 940, "y": 380, "wires": [ [ "1cdb84780936c696" ] ] }, { "id": "e107fc40d203f46a", "type": "http request", "z": "f96eea4d4a3a345d", "name": "Power L2", "method": "GET", "ret": "txt", "paytoqs": "ignore", "url": "http://10.1.0.5/cgi-bin/readVal.exe?PDP,%20R107,d", "tls": "", "persist": false, "proxy": "", "authType": "", "senderr": false, "x": 550, "y": 420, "wires": [ [ "466e66a05eddb62f" ] ] }, { "id": "466e66a05eddb62f", "type": "function", "z": "f96eea4d4a3a345d", "name": "format and save to global var", "func": "temp = parseFloat(msg.payload * 0.1).toFixed(1);\nglobal.set(\"grid_l2_power\", temp);\nmsg.payload = parseFloat(temp);\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 940, "y": 420, "wires": [ [ "074a7fdb9ba59d27" ] ] }, { "id": "7586c0c0ec778dad", "type": "http request", "z": "f96eea4d4a3a345d", "name": "Power L3", "method": "GET", "ret": "txt", "paytoqs": "ignore", "url": "http://10.1.0.5/cgi-bin/readVal.exe?PDP,%20R108,d", "tls": "", "persist": false, "proxy": "", "authType": "", "senderr": false, "x": 550, "y": 460, "wires": [ [ "a0e6a154bfb85c09" ] ] }, { "id": "a0e6a154bfb85c09", "type": "function", "z": "f96eea4d4a3a345d", "name": "format and save to global var", "func": "temp = parseFloat(msg.payload * 0.1).toFixed(1);\nglobal.set(\"grid_l3_power\", temp);\nmsg.payload = parseFloat(temp);\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 940, "y": 460, "wires": [ [ "6ff639af913d0a4d" ] ] }, { "id": "baf1934f370ed4fd", "type": "http request", "z": "f96eea4d4a3a345d", "name": "Total Power", "method": "GET", "ret": "txt", "paytoqs": "ignore", "url": "http://10.1.0.5/cgi-bin/readVal.exe?PDP,%20R112,d", "tls": "", "persist": false, "proxy": "", "authType": "", "senderr": false, "x": 560, "y": 40, "wires": [ [ "c86839ef84dcc35d" ] ] }, { "id": "c86839ef84dcc35d", "type": "function", "z": "f96eea4d4a3a345d", "name": "format and save to global var", "func": "temp = parseFloat(msg.payload * 0.1).toFixed(1);\nglobal.set(\"grid_total_power\", temp);\nmsg.payload = parseFloat(temp);\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 940, "y": 40, "wires": [ [ "1504cb346fc652fd" ] ] }, { "id": "58942376d9fbdd07", "type": "inject", "z": "f96eea4d4a3a345d", "name": "Poll every two sec", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "2", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 200, "y": 40, "wires": [ [ "baf1934f370ed4fd" ] ] }, { "id": "983943d318a0ef33", "type": "function", "z": "f96eea4d4a3a345d", "name": "Calculate kWh of sum power", "func": "//init counters if not defined\nif (global.get(\"grid_total_import\") === undefined) {\n global.set(\"grid_total_import\", 0);\n}\nif (global.get(\"grid_total_export\") === undefined) {\n global.set(\"grid_total_export\", 0);\n}\n//get counters from global variable\nvar total_import = global.get(\"grid_total_import\");\nvar total_export = global.get(\"grid_total_export\");\nvar check = \"Nothing\";\n\n//check if usage (payload) is positive=import or negative=export\n//add diff to import or export counters\nif (msg.payload < 0) {\n total_export += Math.abs(msg.payload);\n check = \"Export: \" + Math.abs(msg.payload) + \" kWh\";\n}\nif (msg.payload > 0) {\n total_import += Math.abs(msg.payload);\n check = \"Import: \" + Math.abs(msg.payload) + \" kWh\";\n}\n\n//write result back to global vars and send a msg for debug\nglobal.set(\"grid_total_import\", total_import);\nglobal.set(\"grid_total_export\", total_export);\nmsg.payload = {total_import: total_import, total_export: total_export, check: check}\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 1530, "y": 40, "wires": [ [] ] }, { "id": "1504cb346fc652fd", "type": "watt2kwh", "z": "f96eea4d4a3a345d", "format": "kwh", "maximum": "10", "maximumunit": "mins", "name": "", "x": 1250, "y": 40, "wires": [ [ "983943d318a0ef33" ] ] }, { "id": "e621c16c10a5eb1d", "type": "function", "z": "f96eea4d4a3a345d", "name": "Init variables", "func": "global.set(\"grid_total_import\", 0);\nglobal.set(\"grid_total_export\", 0);\nglobal.set(\"grid_l1_import\", 0);\nglobal.set(\"grid_l2_import\", 0);\nglobal.set(\"grid_l3_import\", 0);\nglobal.set(\"grid_l1_export\", 0);\nglobal.set(\"grid_l2_export\", 0);\nglobal.set(\"grid_l3_export\", 0);\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 880, "y": 580, "wires": [ [] ] }, { "id": "d905c25120cfdfd3", "type": "inject", "z": "f96eea4d4a3a345d", "name": "Reset or init all counters (Set to Zero)", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 260, "y": 580, "wires": [ [ "e621c16c10a5eb1d" ] ] }, { "id": "1cdb84780936c696", "type": "watt2kwh", "z": "f96eea4d4a3a345d", "format": "kwh", "maximum": "10", "maximumunit": "mins", "name": "", "x": 1230, "y": 380, "wires": [ [ "0b9537e05d7149d3" ] ] }, { "id": "074a7fdb9ba59d27", "type": "watt2kwh", "z": "f96eea4d4a3a345d", "format": "kwh", "maximum": "10", "maximumunit": "mins", "name": "", "x": 1230, "y": 420, "wires": [ [ "59bf60635bd06584" ] ] }, { "id": "6ff639af913d0a4d", "type": "watt2kwh", "z": "f96eea4d4a3a345d", "format": "kwh", "maximum": "10", "maximumunit": "mins", "name": "", "x": 1230, "y": 460, "wires": [ [ "87d6bf141ff90325" ] ] }, { "id": "0b9537e05d7149d3", "type": "function", "z": "f96eea4d4a3a345d", "name": "Calculate kWh of phase 1 power", "func": "//init counters if not defined\nif (global.get(\"grid_l1_import\") === undefined) {\n global.set(\"grid_l1_import\", 0);\n}\nif (global.get(\"grid_l1_export\") === undefined) {\n global.set(\"grid_l1_export\", 0);\n}\n//get counters from global variable\nvar total_import = global.get(\"grid_l1_import\");\nvar total_export = global.get(\"grid_l1_export\");\nvar check = \"Nothing\";\n\n//check if usage (payload) is positive=import or negative=export\n//add diff to import or export counters\nif (msg.payload < 0) {\n total_export += Math.abs(msg.payload);\n check = \"Export: \" + Math.abs(msg.payload) + \" kWh\";\n}\nif (msg.payload > 0) {\n total_import += Math.abs(msg.payload);\n check = \"Import: \" + Math.abs(msg.payload) + \" kWh\";\n}\n//write result back to global vars and send a msg for debug\nglobal.set(\"grid_l1_import\", total_import);\nglobal.set(\"grid_l1_export\", total_export);\nmsg.payload = {total_import: total_import, total_export: total_export, check: check}\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 1500, "y": 380, "wires": [ [] ] }, { "id": "59bf60635bd06584", "type": "function", "z": "f96eea4d4a3a345d", "name": "Calculate kWh of phase 2 power", "func": "//init counters if not defined\nif (global.get(\"grid_l2_import\") === undefined) {\n global.set(\"grid_l2_import\", 0);\n}\nif (global.get(\"grid_l2_export\") === undefined) {\n global.set(\"grid_l2_export\", 0);\n}\n//get counters from global variable\nvar total_import = global.get(\"grid_l2_import\");\nvar total_export = global.get(\"grid_l2_export\");\nvar check = \"Nothing\";\n\n//check if usage (payload) is positive=import or negative=export\n//add diff to import or export counters\nif (msg.payload < 0) {\n total_export += Math.abs(msg.payload);\n check = \"Export: \" + Math.abs(msg.payload) + \" kWh\";\n}\nif (msg.payload > 0) {\n total_import += Math.abs(msg.payload);\n check = \"Import: \" + Math.abs(msg.payload) + \" kWh\";\n}\n\n//write result back to global vars and send a msg for debug\nglobal.set(\"grid_l2_import\", total_import);\nglobal.set(\"grid_l2_export\", total_export);\nmsg.payload = {total_import: total_import, total_export: total_export, check: check}\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 1500, "y": 420, "wires": [ [] ] }, { "id": "87d6bf141ff90325", "type": "function", "z": "f96eea4d4a3a345d", "name": "Calculate kWh of phase 3 power", "func": "//init counters if not defined\nif (global.get(\"grid_l3_import\") === undefined) {\n global.set(\"grid_l3_import\", 0);\n}\nif (global.get(\"grid_l3_export\") === undefined) {\n global.set(\"grid_l3_export\", 0);\n}\n//get counters from global variable\nvar total_import = global.get(\"grid_l3_import\");\nvar total_export = global.get(\"grid_l3_export\");\nvar check = \"Nothing\";\n\n//check if usage (payload) is positive=import or negative=export\n//add diff to import or export counters\nif (msg.payload < 0) {\n total_export += Math.abs(msg.payload);\n check = \"Export: \" + Math.abs(msg.payload) + \" kWh\";\n}\nif (msg.payload > 0) {\n total_import += Math.abs(msg.payload);\n check = \"Import: \" + Math.abs(msg.payload) + \" kWh\";\n}\n\n//write result back to global vars and send a msg for debug\nglobal.set(\"grid_l3_import\", total_import);\nglobal.set(\"grid_l3_export\", total_export);\nmsg.payload = {total_import: total_import, total_export: total_export, check: check}\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 1500, "y": 460, "wires": [ [] ] }, { "id": "8fe908e8e4e30699", "type": "comment", "z": "f96eea4d4a3a345d", "name": "Write all values into global vars, to export them via a JSON-HTTP-API", "info": "Write all values into global vars,\nto export them via a JSON-HTTP-API", "x": 790, "y": 80, "wires": [] }, { "id": "c648f182292dd923", "type": "comment", "z": "f96eea4d4a3a345d", "name": "Read all global vars an create a JObject so we can poll it via HTTP", "info": "Read all global vars an create a JObject so we can poll it via HTTP", "x": 700, "y": 820, "wires": [] }, { "id": "b38818b5fb6846af", "type": "comment", "z": "f96eea4d4a3a345d", "name": "You can save global vars to a context file, if you enable \"Context storage\" in your Node-RED settings.json", "info": "You can save global vars to a context file, if you enable \"Context storage\" in your Node-RED settings.json", "x": 850, "y": 720, "wires": [] }, { "id": "2413b4c69ccefdfb", "type": "comment", "z": "f96eea4d4a3a345d", "name": "With Context storage all global vars are persisted bedween Node RED restarts", "info": "With Context storage all global vars are persisted bedween Node RED restarts", "x": 740, "y": 760, "wires": [] } ]