MPI10K SEC Commands Protocol Nodes

Use this nodes to easily communicate with an Infisolar, MPPSolar, Voltronic (...) PV Inverter.

Type: MPI10K MPI15K

[{"id":"8c74e2302d140724","type":"subflow","name":" SEC - Commands","info":"Used to generate SEC-Commands for InfiniSolar Protocol\r\n\r\nMPI10K\r\n\r\n**command**\r\nThe string command with starting ^ and without `<CR>`.\r\n`msg.command` can be used to set this from an incomming message.\r\n\r\n**parameters**\r\nThe parameters for specific commands as `object`. These are all commands with lower case letters in it.\r\nPlease see the specification for its documentation.\r\n`msg.parameters` can be used to set this from an incomming message.\r\n\r\n**checksum_str**\r\nThe string part to be replaced for the checksum, e.g. `nnn`. See examples for a better understanding.\r\nThe checksum will be generated and the characters specified in `checksum_str` will be replaced.\r\n`msg.checksum_str` can be used to set this from an incomming message.\r\n\r\n# Example - Query power status (^P003PS)\r\n```\r\nmsg.command = '^P003PS';\r\n```\r\n\r\n# Example - Query generated energy of year (^P010EYyyyynnn)\r\n```\r\nmsg.command = '^P010EYyyyynnn';\r\nmsg.parameters = { yyyy: '2024'};\r\nmsg.checksum_str = 'nnn';\r\n\r\n// msg.payload will be \"^P010EY2024165\"\r\n```","category":"","in":[{"x":50,"y":30,"wires":[{"id":"68d2f8d03648856a"}]}],"out":[{"x":700,"y":40,"wires":[{"id":"68d2f8d03648856a","port":0}]},{"x":700,"y":100,"wires":[{"id":"552b73b20e971be4","port":0}]}],"env":[{"name":"command","type":"str","value":"^P010EYyyyynnn","ui":{"icon":"font-awesome/fa-commenting-o","type":"select","opts":{"opts":[{"l":{"de":"(^P002T) - Query current time"},"v":"^P002T"},{"l":{"de":"(^P003DI) - Query default value of changeable parameter"},"v":"^P003DI"},{"l":{"de":"(^P003DM) - Query machine model"},"v":"^P003DM"},{"l":{"de":"(^P003ET) - Query total generated energy"},"v":"^P003ET"},{"l":{"de":"(^P003ET) - Query total generated energy"},"v":"^P003ET"},{"l":{"de":"(^P003FT) - Query wait time for feed power"},"v":"^P003FT"},{"l":{"de":"(^P003GS) - Query general status"},"v":"^P003GS"},{"l":{"de":"(^P003ID) - Query series number"},"v":"^P003ID"},{"l":{"de":"(^P003MD) - Query device model"},"v":"^P003MD"},{"l":{"de":"(^P003PI) - Query protocol ID"},"v":"^P003PI"},{"l":{"de":"(^P003PS) - Query power status"},"v":"^P003PS"},{"l":{"de":"(^P003SV) - Query Solar input voltage acceptable range"},"v":"^P003SV"},{"l":{"de":"(^P003WS) - Query warning status"},"v":"^P003WS"},{"l":{"de":"(^P004CFS) - Query current fault status"},"v":"^P004CFS"},{"l":{"de":"(^P004FET) - Query first generated energy saved time"},"v":"^P004FET"},{"l":{"de":"(^P004GOF) - Query AC input frequency acceptable range of feed power"},"v":"^P004GOF"},{"l":{"de":"(^P004GOV) - Query AC input voltage acceptable range for feed power"},"v":"^P004GOV"},{"l":{"de":"(^P004LST) - Query LCD sleep wait time"},"v":"^P004LST"},{"l":{"de":"(^P004MAR) - Query machine ajustable range"},"v":"^P004MAR"},{"l":{"de":"(^P004MOD) - Query working mode"},"v":"^P004MOD"},{"l":{"de":"(^P004VFW) - Query CPU version"},"v":"^P004VFW"},{"l":{"de":"(^P005ACCT) - Query AC charge time bucket"},"v":"^P005ACCT"},{"l":{"de":"(^P005ACLT) - Query AC supply load time bucket"},"v":"^P005ACLT"},{"l":{"de":"(^P005BATS) - Query battery setting"},"v":"^P005BATS"},{"l":{"de":"(^P005FLAG) - Query enable/disable flag status"},"v":"^P005FLAG"},{"l":{"de":"(^P005GPMP) - Query the maximum output power for feeding grid"},"v":"^P005GPMP"},{"l":{"de":"(^P005HECS) - Query energy control status"},"v":"^P005HECS"},{"l":{"de":"(^P005INGS) - ?"},"v":"^P005INGS"},{"l":{"de":"(^P005PIRI) - Query rated information"},"v":"^P005PIRI"},{"l":{"de":"(^P005RTCP) - ?"},"v":"^P005RTCP"},{"l":{"de":"(^P005VFW2) - Query secondary CPU version"},"v":"^P005VFW2"},{"l":{"de":"(^P005VFWT)"},"v":"^P005VFWT"},{"l":{"de":"(^P006GLTHV) - Query AC input long-lime highest average voltage"},"v":"^P006GLTHV"},{"l":{"de":"(^P006HFSnn) - Query history fault parameter"},"v":"^P006HFSnn"},{"l":{"de":"(^P006MPPTV) - Query Solar input MPPT acceptable range"},"v":"^P006MPPTV"},{"l":{"de":"(^P007EMINFO) - ?"},"v":"^P007EMINFO"},{"l":{"de":"(^P010EYyyyynnn) - Query generated energy of year"},"v":"^P010EYyyyynnn"},{"l":{"de":"(^P012EMyyyymmnnn) - Query generated energy of month"},"v":"^P012EMyyyymmnnn"},{"l":{"de":"(^P014EDyyyymmddnnn) - Query generated energy of day"},"v":"^P014EDyyyymmddnnn"},{"l":{"de":"(^P016EHyyyymmddhhnnn) - Query generated energy of hour"},"v":"^P016EHyyyymmddhhnnn"},{"l":{"de":"(^S003PF) - Set changeable parameter restore to default value"},"v":"^S003PF"},{"l":{"de":"(^S004BTn) - Set battery type"},"v":"^S004BTn"},{"l":{"de":"(^S004F50) - Set AC output frequency to be 50Hz"},"v":"^S004F50"},{"l":{"de":"(^S004F60) - Set AC output frequency to be 60Hz"},"v":"^S004F60"},{"l":{"de":"(^S004Pmn) - Set enable/disable status"},"v":"^S004Pmn"},{"l":{"de":"(^S005EDmn) - Set energy distribution"},"v":"^S005EDmn"},{"l":{"de":"(^S005LONn) - Set enable/disable machine supply power to the loads"},"v":"^S005LONn"},{"l":{"de":"(^S006DMnnn) - Set machine model"},"v":"^S006DMnnn"},{"l":{"de":"(^S006FTnnn) - Set wait time for feed power"},"v":"^S006FTnnn"},{"l":{"de":"(^S006LSTnn) - Set LCD sleep wait time"},"v":"^S006LSTnn"},{"l":{"de":"(^S006SEPnn) - Set Solar energy distribution of priority"},"v":"^S006SEPnn"},{"l":{"de":"(^S006Vnnnn) - Set AC output rated voltage"},"v":"^S006Vnnnn"},{"l":{"de":"(^S007BTSnnn) (RED) - Battery temperature sensor compensation"},"v":"^S007BTSnnn"},{"l":{"de":"(^S009BDCMnnnn) (RED) - Battery discharge max current in hybrid mode"},"v":"^S009BDCMnnnn"},{"l":{"de":"(^S009BST) - Li-Fe battery self-test by charged at a time"},"v":"^S009BST"},{"l":{"de":"(^S009GOHFnnnn) - Set AC input highest frequency for feeding power"},"v":"^S009GOHFnnnn"},{"l":{"de":"(^S009GOHVnnnn) - Set AC input highest voltage for feeding power"},"v":"^S009GOHVnnnn"},{"l":{"de":"(^S009GOLFnnnn) - Set AC input lowest frequency for feeding power"},"v":"^S009GOLFnnnn"},{"l":{"de":"(^S009GOLVnnnn) - Set AC input lowest voltage for feeding power"},"v":"^S009GOLVnnnn"},{"l":{"de":"(^S009SIHVnnnn) - Set Solar input highest voltage"},"v":"^S009SIHVnnnn"},{"l":{"de":"(^S009SILVnnnn) - Set Solar input lowest voltage"},"v":"^S009SILVnnnn"},{"l":{"de":"(^S010GLTHVnnnn) - Set AC input long-time highest average voltage"},"v":"^S010GLTHVnnnn"},{"l":{"de":"(^S010MCHGCnnnn) - Set battery maximum charge current"},"v":"^S010MCHGCnnnn"},{"l":{"de":"(^S011GPMPnnnnnn) - Set max power of feeding grid"},"v":"^S011GPMPnnnnnn"},{"l":{"de":"(^S011MPPTHVnnnn) - Set Solar input highest MPPT voltage"},"v":"^S011MPPTHVnnnn"},{"l":{"de":"(^S011MPPTLVnnnn) - Set Solar input lowest MPPT voltage"},"v":"^S011MPPTLVnnnn"},{"l":{"de":"(^S011MUCHGCnnnn) (RED) - Max. AC charging current from AC"},"v":"^S011MUCHGCnnnn"},{"l":{"de":"(^S012FPADJm,nnnn) (RED) - Feeding grid power calibration (^S012FPADJm,nnnn)"},"v":"^S012FPADJm,nnnn"},{"l":{"de":"(^S014ACCTaaaa,bbbb) - Set AC charge time bucket"},"v":"^S014ACCTaaaa,bbbb"},{"l":{"de":"(^S014ACLTaaaa,bbbb) - Set AC supply load time bucket"},"v":"^S014ACLTaaaa,bbbb"},{"l":{"de":"(^S015MCHGVmmmm,nnnn) - Set battery maximum charge voltage"},"v":"^S015MCHGVmmmm,nnnn"},{"l":{"de":"(^S016ACCBa,bbbb) (RED) - AC charger keep battery voltage setting"},"v":"^S016ACCBa,bbbb"},{"l":{"de":"(^S016BITyymmddhhffss) - Set battery install time"},"v":"^S016BITyymmddhhffss"},{"l":{"de":"(^S016DATyymmddhhffss) - Set date time"},"v":"^S016DATyymmddhhffss"},{"l":{"de":"(^S017BCAaaaa,bbb,cccc) - Set battery charger application in floating charging"},"v":"^S017BCAaaaa,bbb,cccc"},{"l":{"de":"(^S025BATDVaaaa,bbbb,cccc,dddd) - Set battery discharge voltage"},"v":"^S025BATDVaaaa,bbbb,cccc,dddd"},{"l":{"de":"(RED) - Query feeding grid power calibration (^P006FPADJ)"},"v":"^P006FPADJ"}]}}},{"name":"parameters","type":"json","value":"{}","ui":{"icon":"font-awesome/fa-paragraph","label":{"de":"Parameters as Object"}}},{"name":"checksum_str","type":"str","value":"","ui":{"icon":"font-awesome/fa-check-circle-o","label":{"de":"Checksum String"},"type":"input","opts":{"types":["str"]}}}],"meta":{},"color":"#DDAA99"},{"id":"68d2f8d03648856a","type":"function","z":"8c74e2302d140724","name":"Replace parameters, calculate checksum","func":"const crc = env.get('crc');\nlet command = msg.command || env.get('command');\nlet parameters = msg.parameters || env.get('parameters');\nlet checksum_str = msg.checksum_str || env.get('checksum_str');\n\n\nif (parameters) {\n        // replace parameters\n        for (const [key, value] of Object.entries(parameters)) {\n                command = command.replace(key, value);\n        }\n}\n\nif (checksum_str) {\n        const str = command.replace(checksum_str, '');\n        msg.payload = str + (\"000\" + (str.split('').reduce((partialSum, a) => partialSum + a.charCodeAt(0), 0) % 256)).slice(-3);\n}\nelse {\n        msg.payload = command;\n}\n\nmsg.command = msg.payload;\nreturn msg;\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":320,"y":40,"wires":[["552b73b20e971be4"]]},{"id":"552b73b20e971be4","type":"function","z":"8c74e2302d140724","name":"Encode","func":"msg.payload = Buffer.from(msg.payload + '\\r');\nmsg.command = msg.command;\nreturn msg;\n\n","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":580,"y":100,"wires":[[]]},{"id":"792aaa46907b7c2e","type":"subflow","name":"SEC Code - Response Parser","info":"","category":"","in":[{"x":40,"y":40,"wires":[{"id":"13e9d247b430f5da"}]}],"out":[{"x":1100,"y":40,"wires":[{"id":"b31f3fd89e19f731","port":0}]},{"x":1100,"y":100,"wires":[{"id":"2c69abb5e5834703","port":0}]},{"x":580,"y":40,"wires":[{"id":"13e9d247b430f5da","port":0}]}],"env":[],"meta":{},"color":"#DDAA99"},{"id":"13e9d247b430f5da","type":"function","z":"792aaa46907b7c2e","name":"parse Response","func":"const str = msg.payload.toString();\n\nconst length = parseInt(str.substr(2, 3));\n\nconst data = str.substr(5, length - 3).split(',');\n\n\nconst faultCodes = {\n    \"01\": \"BUS exceed the upper limit\",\n    \"02\": \"BUS dropp to the lower limit\",\n    \"03\": \"BUS soft start circuit timeout\",\n    \"04\": \"Inverter voltage soft start timeout\",\n    \"05\": \"Inverter current exceed the upper limit\",\n    \"06\": \"Temperature over\",\n    \"07\": \"Inverter relay work abnormal\",\n    \"08\": \"Current sample abnormal when inverter doesn't work\",\n    \"09\": \"Solar input voltage exceed upper limit\",\n    \"10\": \"SPS power voltage abnormal\",\n    \"11\": \"Solar input current exceed upper limit\",\n    \"12\": \"Leakage current exceed permit range\",\n    \"13\": \"Solar insulation resistance too low\",\n    \"14\": \"Inverter DC current exceed permit range when feed power\",\n    \"15\": \"The AC input voltage or frequency has been detected different between master CPU and slave CPU\",\n    \"16\": \"Leakage current detect circuit abnormal when inverter doesn't work\",\n    \"17\": \"Comminication loss between master CPU and slave CPU\",\n    \"18\": \"Comminicate data discordant between master CPU and slave CPU\",\n    \"19\": \"AC input ground wire loss\",\n    \"22\": \"Battery voltage exceed upper limit\",\n    \"23\": \"Over load\",\n    \"24\": \"Battery disconnected\",\n    \"26\": \"AC output short\",\n    \"27\": \"Fan lock\",\n    \"32\": \"Battery DC-DC current over\",\n    \"33\": \"AC output voltage too low\",\n    \"34\": \"AC output voltage too high\",\n    \"35\": \"Control board wiring error\",\n    \"36\": \"AC circuit voltage sample error\",\n};\n\n\nconst command = msg.command;\nlet obj = {};\nlet a = 0; // autoIndex;\nif (command.startsWith(\"^P010EY\")) {\n    obj = {\n        \"Generated energy\": {\n            value: parseInt(data[0]),\n            unit: 'Wh'\n        }\n    };\n}\n\nelse if (command.startsWith(\"^P003PI\")) {\n    obj = parseInt(data[0]);\n}\n\nelse if (command.startsWith(\"^P003ID\")) {\n    obj = data[0];\n}\n\nelse if (command.startsWith(\"^P004VFW\")) {\n    obj = data[0];\n}\n\nelse if (command.startsWith(\"^P005VFW2<\")) {\n    obj = data[0];\n}\n\nelse if (command.startsWith(\"^P003MD\")) {\n    enumVal(\"Machine number\", { \"000\": 'MPI Hybrid 10KW/3P', });\n    val(\"Output rated VA\", 1, \"VA\");\n    val(\"Output power factor\", 1);\n    val(\"AC input phase number\", 1);\n    val(\"AC output phase number\", 1);\n    val(\"Norminal AC output voltage\", 0.1, \"V\");\n    val(\"Norminal AC input voltage\", 0.1, \"V\");\n    val(\"Battery piece number\", 1);\n    val(\"Battery standard voltage per unit\", 0.1, \"V\");\n}\n\nelse if (command.startsWith(\"^P005PIRI\")) {\n    val(\"AC input rated voltage\", 0.1, 'V');\n    val(\"AC input rated frequency\", 0.1, 'Hz');\n    val(\"AC input rated current\", 0.1, 'A');\n    val(\"AC output rated voltage\", 0.1, 'V');\n    val(\"AC output rated current\", 0.1, 'A');\n    val(\"MPPT rated current per string\", 0.1, 'A');\n    val(\"Battery rated voltage\", 0.1, 'V');\n    val(\"MPPT track number\", 1);\n    enumVal(\"Machine type\", { \"00\": 'Grid type', \"01\": \"Off-grid type\", \"10\": 'Hybrid type' });\n    enumVal(\"Topology\", { \"0\": 'transformerless', \"1\": \"transformer\" });\n\n}\n\n\nelse if (command.startsWith(\"^P003GS\")) {\n    val(\"Solar input voltage 1\", 0.1, 'V');\n    val(\"Solar input voltage 2\", 0.1, 'V');\n    val(\"Solar input current 1\", 0.1, 'A');\n    val(\"Solar input current 2\", 0.1, 'A');\n\n    val(\"Battery voltage\", 0.1, 'V');\n    val(\"Battery capacity\", 1, '%');\n    val(\"Battery current\", 0.1, 'V');\n    obj[\"Battery current\"].charge = (parseInt(data[6]) * 0.1 || 0) > 0;\n    obj[\"Battery current\"].discharge = (parseInt(data[6]) * 0.1 || 0) < 0;\n\n    val(\"AC input voltage R\", 0.1, 'V');\n    val(\"AC input voltage S\", 0.1, 'V');\n    val(\"AC input voltage T\", 0.1, 'V');\n    val(\"AC input frequency\", 0.01, 'Hz');\n    val(\"AC input current R\", 0.1, 'A');\n    val(\"AC input current S\", 0.1, 'A');\n    val(\"AC input current T\", 0.1, 'A');\n\n    val(\"AC output voltage R\", 0.1, 'V');\n    val(\"AC output voltage S\", 0.1, 'V');\n    val(\"AC output voltage T\", 0.1, 'V');\n    val(\"AC output frequency\", 0.01, 'Hz');\n    val(\"AC output current R\", 0.1, 'A');\n    val(\"AC output current S\", 0.1, 'A');\n    val(\"AC output current T\", 0.1, 'A');\n\n    val(\"Inner temperature\", 1, '°C');\n    val(\"Component max temperature\", 1, '°C');\n    val(\"External battery temperature\", 1, '°C');\n}\n\nelse if (command.startsWith(\"^P003PS\")) {\n    val(\"Solar input power 1\", 1, 'W');\n    val(\"Solar input power 2\", 1, 'W');\n    val(\"Battery power\", 0.1, 'W');\n    obj[\"Battery power\"].charge = (parseInt(data[3]) || 0) > 0;\n    obj[\"Battery power\"].discharge = (parseInt(data[3]) || 0) < 0;\n\n    val(\"AC input active power R\", 1, 'W');\n    obj[\"AC input active power R\"].input = (parseInt(data[4]) || 0) > 0;\n    obj[\"AC input active power R\"].output = (parseInt(data[4]) || 0) < 0;\n    val(\"AC input active power S\", 1, 'W');\n    obj[\"AC input active power S\"].input = (parseInt(data[5]) || 0) > 0;\n    obj[\"AC input active power S\"].output = (parseInt(data[5]) || 0) < 0;\n    val(\"AC input active power T\", 1, 'W');\n    obj[\"AC input active power T\"].input = (parseInt(data[6]) || 0) > 0;\n    obj[\"AC input active power T\"].output = (parseInt(data[6]) || 0) < 0;\n    val(\"AC input total active power\", 1, 'W');\n    obj[\"AC input total active power\"].input = (parseInt(data[7]) || 0) > 0;\n    obj[\"AC input total active power\"].output = (parseInt(data[7]) || 0) < 0;\n\n\n    val(\"AC output active power R\", 1, 'W');\n    val(\"AC output active power S\", 1, 'W');\n    val(\"AC output active power T\", 1, 'W');\n    val(\"AC output total active power\", 1, 'W');\n\n    val(\"AC output apperent power R\", 1, 'VA');\n    val(\"AC output apperent power S\", 1, 'VA');\n    val(\"AC output apperent power T\", 1, 'VA');\n    val(\"AC output total apperent power\", 1, 'VA');\n\n    val(\"AC output power percentage\", 1, '%');\n    enumVal(\"AC output connect status\", { \"0\": 'disconnect', \"1\": \"connect\" });\n    enumVal(\"Solar input 1 work status\", { \"0\": 'idle', \"1\": \"work\" });\n    enumVal(\"Solar input 2 work status\", { \"0\": 'idle', \"1\": \"work\" });\n    enumVal(\"Battery power direction\", { \"0\": 'donothing', \"1\": \"charge\", \"2\": \"discharge\" });\n    enumVal(\"DC/AC power direction\", { \"0\": 'donothing', \"1\": \"AC-DC\", \"2\": \"DC-AC\" });\n    enumVal(\"Line power direction\", { \"0\": 'donothing', \"1\": \"charge\", \"2\": \"discharge\" });\n}\n\nelse if (command.startsWith(\"^P004MOD\")) {\n    obj = asEnum({\n        \"00\": \"Power on mode\",\n        \"01\": \"Standby mode\",\n        \"02\": \"Bypass mode\",\n        \"03\": \"Battery mode\",\n        \"04\": \"Fault mode\",\n        \"05\": \"Hybrid mode(Line mode, Grid mode)\",\n        \"06\": \"Charge mode\",\n    });\n}\n\nelse if (command.startsWith(\"^P003WS\")) {\n    bool(\"Solar input 1 loss\", \"Solar input 1 voltage exceed the acceptable range\");\n    bool(\"Solar input 2 loss\", \"Solar input 2 voltage exceed the acceptable range\");\n    bool(\"Solar input 1 voltage too higher\", \"\");\n    bool(\"Solar input 2 voltage too higher\", \"\");\n    bool(\"Battery under\", \"Battery voltage drop to unacceptable level\");\n    bool(\"Battery low\", \"Battery voltage near to unacceptable level\");\n    bool(\"Battery open\", \"Battery disconnected\");\n    bool(\"Battery voltage too high\", \"Battery voltage exceed the highest level\");\n    bool(\"Battery low in hybrid mode\", \"Battery voltage drop to unacceptable level of hybrid mode\");\n    bool(\"Grid voltage high loss\", \"AC input voltage higher than the highest level of AC feeding voltage\");\n    bool(\"Grid voltage low loss\", \"AC input voltage lower than the lowest level of AC feeding voltage\");\n    bool(\"Grid frequency high loss\", \"AC input frequency higher than the highest level of AC feeding frequency\");\n    bool(\"Grid frequency low loss\", \"AC input voltage lower than the lowest level of AC feeding frequency\");\n    bool(\"AC input long-time average voltage over\", \"AC input long-time average voltage exceed the highest level\");\n    bool(\"AC input voltage loss\", \"AC input voltage out of acceptable range\");\n    bool(\"AC input frequency loss\", \"AC input frequency out of acceptable range\");\n    bool(\"AC input island\", \"AC input has been detected for the island\");\n    bool(\"AC input phase dislocation\", \"AC input three phase dislocation\");\n    bool(\"Over temperature\", \"Machine temperature near to unacceptable level\");\n    bool(\"Over load\", \"The loads connect to machine exceed abnormal level\");\n    bool(\"EPO active\", \"Emergent power off active\");\n    bool(\"AC input wave loss\", \"AC input wave terrible\");\n\n}\nelse if (command.startsWith(\"^P005FLAG\")) {\n    bool(\"Mute buzzer beep\");\n    bool(\"Mute buzzer beep in standby mode\");\n    bool(\"Mute buzzer beep only on battery discharged status\");\n    bool(\"Generator as AC input\");\n    bool(\"Wide AC input range\");\n}\nelse if (command.startsWith(\"^P002T\")) {\n    const year = parseInt(data[0].substr(0, 4));\n    const month = parseInt(data[0].substr(4, 2));\n    const day = parseInt(data[0].substr(6, 2));\n    const hour = parseInt(data[0].substr(8, 2));\n    const minute = parseInt(data[0].substr(10, 2));\n    const second = parseInt(data[0].substr(12, 2));\n    obj = { date: new Date(year - 1, month - 1, day, hour, minute, second, 0), raw: data[0], year, day, month, hour, minute, second };\n}\n\nelse if (command.startsWith(\"^P003ET\")) {\n    obj = {\n        \"Generated energy\": {\n            value: parseInt(data[0].length > 0 ? data[0] : 0),\n            unit: 'KWh'\n        }\n    };\n}\nelse if (command.startsWith(\"^P010EY\")) {\n    obj = {\n        \"Generated energy\": {\n            value: parseInt(data[0].length > 0 ? data[0] : 0),\n            unit: 'Wh'\n        }\n    };\n}\nelse if (command.startsWith(\"^P012EM\")) {\n    obj = {\n        \"Generated energy\": {\n            value: parseInt(data[0].length > 0 ? data[0] : 0),\n            unit: 'Wh'\n        }\n    };\n}\nelse if (command.startsWith(\"^P014ED\")) {\n    obj = {\n        \"Generated energy\": {\n            value: parseInt(data[0].length > 0 ? data[0] : 0),\n            unit: 'Wh'\n        }\n    };\n}\nelse if (command.startsWith(\"^P016EH\")) {\n    obj = {\n        \"Generated energy\": {\n            value: parseInt(data[0].length > 0 ? data[0] : 0),\n            unit: 'Wh'\n        }\n    };\n}\nelse if (command.startsWith(\"^P004GOV\")) {\n    val(\"The highest voltage\", 0.1, 'V');\n    val(\"The lowest voltage\", 0.1, 'V');\n}\nelse if (command.startsWith(\"^P004GOF\")) {\n    val(\"The highest frequency\", 0.01, 'Hz');\n    val(\"The lowest frequency\", 0.01, 'Hz');\n}\nelse if (command.startsWith(\"^P005GPMP\")) {\n    val(\"The maximum power\", 1, 'W');\n}\nelse if (command.startsWith(\"^P006MPPTV\")) {\n    val(\"The highest voltage\", 0.1, 'V');\n    val(\"The lowest voltage\", 0.1, 'V');\n}\nelse if (command.startsWith(\"^P003SV\")) {\n    val(\"The highest voltage\", 0.1, 'V');\n    val(\"The lowest voltage\", 0.1, 'V');\n}\nelse if (command.startsWith(\"^P004LST\")) {\n    obj = asEnum({\n        \"00\": \"always on\",\n        \"01\": \"30s\",\n        \"02\": \"1m\",\n        \"03\": \"5m\",\n        \"04\": \"10m\",\n    });\n}\nelse if (command.startsWith(\"^P003DI\")) {\n    val(\"AC input highest voltage for feed power\", 0.1, 'V');\n    val(\"AC input lowest voltage for feed power\", 0.1, 'V');\n\n    val(\"AC input highest frequency for feed power\", 0.01, 'Hz');\n    val(\"AC input lowest frequency for feed power\", 0.01, 'Hz');\n\n    val(\"Solar input highest MPPT voltage\", 0.1, 'V');\n    val(\"Solar input lowest MPPT voltage\", 0.1, 'V');\n    val(\"Solar input highest voltager\", 0.1, 'V');\n    val(\"Solar input lowest voltage\", 0.1, 'V');\n    val(\"AC input long-time highest average voltage\", 0.1, 'V');\n\n    enumVal(\"LCD sleep wait time\", {\n        \"00\": \"always on\",\n        \"01\": \"30s\",\n        \"02\": \"1m\",\n        \"03\": \"5m\",\n        \"04\": \"10m\",\n    });\n    val(\"Battery maximum charge current\", 0.1, 'A');\n    val(\"Battery constant charge voltage(C.V.)\", 0.1, 'V');\n    val(\"Battery float charge voltage\", 0.1, 'V');\n    val(\"The wait time for feed power\", 1, 'Second');\n    strVal(\"Start time for support loads\", \"HHMM\", \"example: 1230 meas 12:30\");\n    strVal(\"Ending time for support loads\", \"HHMM\", \"example: 1230 meas 12:30\");\n    strVal(\"Start time for AC charger\", \"HHMM\", \"example: 1230 meas 12:30\");\n    strVal(\"Ending time for AC charger\", \"HHMM\", \"example: 1230 meas 12:30\");\n    val(\"Battery under voltage\", 0.1, 'V');\n    val(\"Battery under back voltage\", 0.1, 'V');\n    val(\"Battery weak voltage in hybrid mode\", 0.1, 'V');\n    val(\"Battery weak back voltage in hybrid mode\", 0.1, 'V');\n    val(\"Battery stop charger current level in floating charging\", 0.1, 'A');\n    val(\"Keep charged time of battery catch stop charger current level\", 1, 'Minute');\n    val(\"Battery voltage of recover to charge when battery stop charger in floating charging\", 0.1, 'A');\n}\nelse if (command.startsWith(\"^P005BATS\")) {\n    val(\"Battery maximum charge current\", 0.1, 'A');\n    val(\"Battery constant charge voltage(C.V.)\", 0.1, 'V');\n    val(\"Battery floating charge voltage\", 0.1, 'V');\n    val(\"Battery stop charger current level in floating charging\", 0.1, 'A');\n    val(\"Keep charged time of battery catch stopped charging current level\", 1, 'Minute');\n\n\n    val(\"Battery voltage of recover to charge when battery stop charger in floating charging\", 0.1, 'V');\n    val(\"Battery under voltage\", 0.1, 'V');\n    val(\"Battery under back voltage\", 0.1, 'V');\n    val(\"Battery weak voltage in hybrid mode\", 0.1, 'V');\n    val(\"Battery weak back voltage in hybrid mode\", 0.1, 'V');\n    enumVal(\"Battery type\", {\n        \"0\": \"Ordinary\",\n        \"1\": \"Li-Fe\",\n    });\n    val(\"Battery Max.discharge current in hybrid mode\", 0.1, 'VA');\n    strVal(\"Battery install time\", \"YY-MM-DD, HH:MM:SS\");\n    bool(\"AC charger keep battery voltage function enable/diable\")\n\n    val(\"AC charger keep battery voltage\", 0.1, 'V');\n    val(\"Battery temperature sensor compensation\", 0.1, 'mV');\n    val(\"Max.AC charging current\", 0.1, 'A');\n    val(\"Battery discharge max current in hybrid mode\", 1, 'A');\n}\n\nelse if (command.startsWith(\"^D006AAA\")) {\n    obj = asEnum({\n        \"050\": \"Hybrid type VDE certification\",\n        \"051\": \"Hybrid type AS4777 certification\",\n        \"052\": \"Hybrid type DK certification\",\n        \"053\": \"Hybrid type RD1663 certification\",\n        \"054\": \"Hybrid type G83 certification\",\n        \"055\": \"Hybrid type Taiwan certification\",\n        \"056\": \"Hybrid type USH certification\",\n        \"057\": \"Hybrid type USL certification\",\n        \"058\": \"Hybrid type VDE4105 certification\",\n        \"059\": \"Hybrid type Korea certification\",\n        \"060\": \"Hybrid type HongSun certification\",\n        \"061\": \"Hybrid type Sweden certification\",\n        \"100\": \"Grid type VDE certification\",\n        \"101\": \"Grid type AS4777 certification\",\n        \"102\": \"Grid type DK certification\",\n        \"103\": \"Grid type RD1663 certification\",\n        \"104\": \"Grid type G83 certification\",\n        \"105\": \"Grid type Taiwan certification\",\n        \"106\": \"Grid type USH certification\",\n        \"107\": \"Grid type USL certification\",\n        \"108\": \"Grid type VDE4105 certification\",\n        \"109\": \"Grid type Korea certification\",\n        \"110\": \"Grid type HongSun certification\",\n        \"111\": \"Grid type Sweden certification\",\n        \"150\": \"Off Grid type\",\n        \"151\": \"Off Grid 3 type\",\n    });\n}\nelse if (command.startsWith(\"^P004MAR\")) {\n    val(\"The upper limit of AC input highest voltage for feed power\", 0.1, 'V');\n    val(\"The lower limit of AC input highest voltage for feed power\", 0.1, 'V');\n    val(\"The upper limit of AC input lowest voltage for feed power\", 0.1, 'V');\n    val(\"The lower limit of AC input lowest voltage for feed power\", 0.1, 'V');\n    val(\"The upper limit of AC input highest frequency for feed power\", 0.01, 'Hz');\n    val(\"The lower limit of AC input highest frequency for feed power\", 0.01, 'Hz');\n    val(\"The upper limit of AC input lowest frequency for feed power\", 0.01, 'Hz');\n    val(\"The lower limit of AC input lowest frequency for feed power\", 0.01, 'Hz');\n    val(\"The upper limit of wait time for feed power\", 1, 'Second');\n    val(\"The lower limit of wait time for feed power\", 1, 'Second');\n    val(\"The upper limit of solar maximum input voltage\", 0.1, 'V');\n    val(\"The lower limit of solar maximum input voltage\", 0.1, 'V');\n    val(\"The upper limit of solar minimum input voltage\", 0.1, 'V');\n    val(\"The lower limit of solar minimum input voltage\", 0.1, 'V');\n    val(\"The upper limit of solar maximum MPPT voltage\", 0.1, 'V');\n    val(\"The lower limit of solar maximum MPPT voltage\", 0.1, 'V');\n    val(\"The upper limit of solar minimum MPPT voltage\", 0.1, 'V');\n    val(\"The lower limit of solar minimum MPPT voltage\", 0.1, 'V');\n    val(\"The upper limit of battery charged voltage\", 0.1, 'V');\n    val(\"The lower limit of battery charged voltage\", 0.1, 'V');\n    val(\"The upper limit of battery Max. charged current\", 0.1, 'A');\n    val(\"The lower limit of battery Max. charged current\", 0.1, 'A');\n    val(\"The upper limit of maximum feeding power\", 1, 'W');\n    val(\"The lower limit of maximum feeding power\", 1, 'W');\n}\nelse if (command.startsWith(\"^P004CFS\")) {\n    enumVal(\"The latest fault code\", faultCodes);\n    val(\"The latest fault code ID stored in flash\", 1);\n}\nelse if (command.startsWith(\"^P006HFS\")) {\n    val(\"The fault code ID stored in flash\", 1);\n    enumVal(\"Fault code\", faultCodes);\n    strVal(\"Time\", 'YY-MM-DD, HH:MM:SS');\n    val(\"Work mode\", 1,);\n    val(\"Solar input voltage 1\", 0.1, 'V');\n    val(\"Solar input voltage 2\", 0.1, 'V');\n    val(\"Solar input power 1\", 1, 'W');\n    val(\"Solar input power 2\", 1, 'W');\n    val(\"AC input voltage R\", 0.1, 'V');\n    val(\"AC input voltage S\", 0.1, 'V');\n    val(\"AC input voltage T\", 0.1, 'V');\n    val(\"AC input frequency\", 0.01, 'Hz');\n    val(\"Battery voltage\", 0.1, 'V');\n    val(\"Battery current\", 0.1, 'V');\n    obj[\"Battery current\"].charge = (parseInt(data[14]) * 0.1 || 0) > 0;\n    obj[\"Battery current\"].discharge = (parseInt(data[15]) * 0.1 || 0) < 0;\n\n    val(\"AC output voltage R\", 0.1, 'V');\n    val(\"AC output voltage S\", 0.1, 'V');\n    val(\"AC output voltage T\", 0.1, 'V');\n    val(\"AC output frequency\", 0.01, 'Hz');\n    val(\"AC output apperent power R\", 1, 'VA');\n    val(\"AC output apperent power S\", 1, 'VA');\n    val(\"AC output apperent power T\", 1, 'VA');\n    val(\"AC output percentage\", 1, '%');\n    val(\"Inner temperature\", 1, '°C');\n    val(\"Component Max. temperature\", 1, '°C');\n    val(\"External battery temperature\", 1, '°C');\n}\nelse if (command.startsWith(\"^P005HECS\")) {\n    enumVal(\"Solar energy distribution of priority\", {\n        \"00\": \"Battery-Load-Grid\",\n        \"01\": \"Load-Battery-Grid\",\n        \"02\": \"Load-Grid-Battery\",\n    });\n    bool(\"Enable / disable solar charge battery\");\n    bool(\"Enable / disable AC charge battery\");\n    bool(\"Enable / disable feed power to utility\");\n    bool(\"Enable / disable battery discharge to loads when solar input normal\");\n    bool(\"Enable / disable battery discharge to loads when solar input loss\");\n    bool(\"Enable / disable battery discharge to feed power to utility when solar input normal\");\n    bool(\"Enable / disable battery discharge to feed power to utility when solar input loss\");\n    bool(\"Enable / disable auto adjust PF according to Feed power\");\n}\nelse if (command.startsWith(\"^P006GLTHV\")) {\n    val(\"AC input long-lime highest average voltage\", 0.1, 'V');\n}\nelse if (command.startsWith(\"^P004FET\")) {\n    const year = parseInt(data[0].substr(0, 4));\n    const month = parseInt(data[0].substr(4, 2));\n    const day = parseInt(data[0].substr(6, 2));\n    const hour = parseInt(data[0].substr(8, 2));\n    obj = { date: new Date(year - 1, month - 1, day, hour, 0, 0, 0), raw: data[0], year, day, month, hour };\n}\nelse if (command.startsWith(\"^P003FT\")) {\n    val(\"Wait time\", 1, 'Second');\n}\n\nelse if (command.startsWith(\"^P005ACCT\")) {\n    strVal(\"Start time for enable AC charger working\", \"HH:MM(hour : minute)\");\n    strVal(\"Ending time for enable AC charger working\", \"HH:MM(hour : minute)\");\n}\nelse if (command.startsWith(\"^P005ACCT\")) {\n    strVal(\"Start time for enable AC supply the load\", \"HH:MM(hour : minute)\");\n    strVal(\"Ending time for enable AC supply the load\", \"HH:MM(hour : minute)\");\n}\nelse if (command.startsWith(\"^P005ACCT\")) { //RED\n    enumVal(\"Feeding grid derection\", {\n        \"0\": \"-\",\n        \"1\": \"+\"\n    });\n    val(\"Feeding grid calibration power\", 1, 'W');\n}\n\n\n// SET COMMAND RESPONSES:\n\nif (str.startsWith(\"^1\")) { \n    obj = true; // accepted\n}\nif (str.startsWith(\"^0\")) { \n    obj = false; // refused\n}\n\n\n\n\n\n\nmsg.payload = { raw: msg.payload, str: msg.payload.toString(), type: str.substr(1, 1), length, data, obj, crc: str.substr(length + 2, 2) };\nmsg.command = command;\n\n\n\nreturn msg;\n\nfunction val(name, factor, unit, remark) {\n    let value = parseInt(data[a]);\n    if (Number.isNaN(value)) {\n        value = 0;\n    }\n    if (factor) {\n        value = value * factor;\n    }\n    obj[name] = { value };\n    if (unit) {\n        obj[name].unit = unit;\n    }\n    if (remark) {\n        obj[name].remark = remark;\n    }\n    a++;\n}\n\nfunction enumVal(name, enumObj) {\n    obj[name] = { text: enumObj?.[data[a]] || '', value: data[a] }\n    a++;\n}\n\nfunction asEnum(enumObj) {\n    return { text: enumObj?.[data[a]] || '', value: data[a] }\n}\n\nfunction bool(name, remark) {\n    obj[name] = { value: Boolean(parseInt(data[a])) };\n    if (remark) {\n        obj[name].remark = remark;\n    }\n    a++;\n}\n\nfunction strVal(name, format, remark) {\n    obj[name] = { value: data[a] };\n    if (format) {\n        obj[name].format = format;\n    }\n    if (remark) {\n        obj[name].remark = remark;\n    }\n    a++;\n}","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":280,"y":40,"wires":[["b31f3fd89e19f731","2c69abb5e5834703"]]},{"id":"b31f3fd89e19f731","type":"function","z":"792aaa46907b7c2e","name":"only parsed obj as Payload","func":"msg.payload = msg.payload.obj;\nmsg.command = msg.command;\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":680,"y":100,"wires":[[]]},{"id":"2c69abb5e5834703","type":"function","z":"792aaa46907b7c2e","name":"only data array as Payload","func":"msg.payload = msg.payload.data;\nmsg.command = msg.command;\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":680,"y":160,"wires":[[]]},{"id":"af500419e30b1df5","type":"inject","z":"517fb8d3d2591875","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"^P004VFW","payloadType":"str","x":140,"y":320,"wires":[["d0a14df7eb9e09b3"]]},{"id":"6ca65cb7c5a9b5f2","type":"inject","z":"517fb8d3d2591875","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"^P003ID","payloadType":"str","x":140,"y":260,"wires":[["d0a14df7eb9e09b3"]]},{"id":"61db83904fa3274f","type":"inject","z":"517fb8d3d2591875","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"^P003PI","payloadType":"str","x":140,"y":200,"wires":[["d0a14df7eb9e09b3"]]},{"id":"aebeb85759303b24","type":"inject","z":"517fb8d3d2591875","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"^P003MD","payloadType":"str","x":140,"y":380,"wires":[["d0a14df7eb9e09b3"]]},{"id":"f88a3cc1e5ecd783","type":"inject","z":"517fb8d3d2591875","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"^P002T","payloadType":"str","x":150,"y":440,"wires":[["d0a14df7eb9e09b3"]]},{"id":"40a03bb8d8a61297","type":"inject","z":"517fb8d3d2591875","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"^P004MOD","payloadType":"str","x":130,"y":500,"wires":[["d0a14df7eb9e09b3"]]},{"id":"7767f635542a4fd3","type":"inject","z":"517fb8d3d2591875","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"^P003GS","payloadType":"str","x":140,"y":560,"wires":[["d0a14df7eb9e09b3"]]},{"id":"d68211018ed8feb7","type":"inject","z":"517fb8d3d2591875","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"^P003PS","payloadType":"str","x":140,"y":140,"wires":[["d0a14df7eb9e09b3"]]},{"id":"876e76e5930b0710","type":"inject","z":"517fb8d3d2591875","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"^P005INGS","payloadType":"str","x":130,"y":620,"wires":[["d0a14df7eb9e09b3"]]},{"id":"566f09865c9336a0","type":"inject","z":"517fb8d3d2591875","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"^P007EMINFO","payloadType":"str","x":120,"y":680,"wires":[["d0a14df7eb9e09b3"]]},{"id":"7eb9ddf7d8f84d22","type":"tcp request","z":"517fb8d3d2591875","name":"TCP-RS232-MPI10K","server":"192.168.1.163","port":"8223","out":"sit","ret":"buffer","splitc":" ","newline":"","trim":false,"tls":"","x":780,"y":380,"wires":[["bae6df7cb3001223"]]},{"id":"1c82ae41a91a3087","type":"inject","z":"517fb8d3d2591875","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":800,"wires":[["911cbb8b126d8bc5"]]},{"id":"926eabae98ec3ce2","type":"debug","z":"517fb8d3d2591875","name":"Show Response","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1340,"y":380,"wires":[]},{"id":"bae6df7cb3001223","type":"subflow:792aaa46907b7c2e","z":"517fb8d3d2591875","name":"","x":1060,"y":380,"wires":[["926eabae98ec3ce2"],[],["926eabae98ec3ce2"]]},{"id":"911cbb8b126d8bc5","type":"subflow:8c74e2302d140724","z":"517fb8d3d2591875","name":"Set AC charge time bucket","env":[{"name":"command","value":"^S014ACCTaaaa,bbbb","type":"str"},{"name":"parameters","value":"{\"aaaa\":\"0300\",\"bbbb\":\"0555\"}","type":"json"},{"name":"checkstum_str","value":"nnn","type":"str"}],"x":460,"y":800,"wires":[[],["7eb9ddf7d8f84d22"]]},{"id":"599be87dcdab5778","type":"subflow:8c74e2302d140724","z":"517fb8d3d2591875","name":"Query AC","env":[{"name":"command","value":"^P005ACCT","type":"str"},{"name":"checkstum_str","value":"nnn","type":"str"}],"x":400,"y":860,"wires":[[],["7eb9ddf7d8f84d22"]]},{"id":"7305d6d5cb73df7a","type":"inject","z":"517fb8d3d2591875","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":860,"wires":[["599be87dcdab5778"]]},{"id":"d0a14df7eb9e09b3","type":"function","z":"517fb8d3d2591875","name":"payload to command","func":"msg.command = msg.payload;\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":420,"y":380,"wires":[["df325cabbeef4730"]]},{"id":"df325cabbeef4730","type":"subflow:8c74e2302d140724","z":"517fb8d3d2591875","name":"","env":[{"name":"command","value":"^S014ACCTaaaa,bbbb","type":"str"},{"name":"parameters","value":"{\"aaaa\":\"0300\",\"bbbb\":\"0555\"}","type":"json"},{"name":"checkstum_str","value":"nnn","type":"str"}],"x":550,"y":140,"wires":[[],["7eb9ddf7d8f84d22"]]},{"id":"4e3ce7bbcc1924c7","type":"comment","z":"517fb8d3d2591875","name":"Use a TCP Connection to an TCP to RS232 Adapter. You could use a direct serial connection here alternatively...","info":"Use a TCP Connection to an TCP to RS232 Adapter.\nYou could use a direct serial connection here alternatively...","x":1060,"y":320,"wires":[]}]

Flow Info

Created 1 year ago
Rating: 5 1

Owner

Actions

Rate:

Node Types

Core
  • comment (x1)
  • debug (x1)
  • function (x6)
  • inject (x12)
  • tcp request (x1)
Other
  • subflow (x2)
  • subflow:792aaa46907b7c2e (x1)
  • subflow:8c74e2302d140724 (x3)

Tags

  • MPI10K
  • MPI15K
  • Voltronic
  • MPPSolar
  • InfiniSolar
  • Inverter
  • PV
  • Protocol
  • SEC
Copy this flow JSON to your clipboard and then import into Node-RED using the Import From > Clipboard (Ctrl-I) menu option