Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. painless

    NEWS

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    • Monatsrückblick - April 2025

    P
    • Profile
    • Following 0
    • Followers 0
    • Topics 0
    • Posts 9
    • Best 0
    • Groups 1

    painless

    @painless

    0
    Reputation
    14
    Profile views
    9
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    painless Follow
    Starter

    Latest posts made by painless

    • RE: Bosswerk MI600 Adapter

      @rene55
      Warte noch ein paar Minuten. Da kommt noch mehr..
      Ja, ich hab auch BMI 600.

      Mach mal Deinen Chat für mich auf. Da tauschen wir ein paar pers. Daten aus um besser zu kommunizieren...

      posted in Entwicklung
      P
      painless
    • RE: Bosswerk MI600 Adapter

      @rene55
      Der Code geht im Spoiler kaputt.

      Versuche es mal über Dateianhang.

      bosswerk.json

      posted in Entwicklung
      P
      painless
    • RE: Bosswerk MI600 Adapter

      @rene55
      Stimmt, die Fehlermeldung bekomme ich auch, wenn ich meinen eigenen Flow importieren will. Sorry, da muss beim Export etwas schief gegangen sein.

      Versuche es bitte damit nochmal:


      [
      {
      "id": "6e802f1553b18149",
      "type": "subflow",
      "name": "JSON or Obj to IOBroker",
      "info": "# Creates an IOBroker tree\n\nThis node creates an IOBroker tree out of an Java-Object or JSON String.\n\nThe object tree will be created under 0_userdata.0\nIn addition to the JSON-String or Java Object as msg.payload it is necessary to specify a msg.top properity in addition to the msg-Object.\n\nThe object tree will be created under 0_userdata.0\n\nExisting msg.topic entries will be deleted.\nAn iobroker-out node has to be appended to this subflow node. It is not part of the subflow itself. No topic should be specified in the iobroker out node.\n\nIs msg.top property isn't defined, the top property of the subflow-node is used. \n\nIn the properties of the subflow node a new property keepTopic has been added. Default is false to keep the current behaviour. If set to true then the originial topic will be placed between the top property of the subflow node and the property of the analyzed JSON object.\n\nAttention:\nIf msg.top and top is empty, all msg.topics (msg.topic) will be directly prefixed with 0_userdata.0. . \n\nUpdate 13.09.2022:\nSpaces in topics of objects are no longer replaced with underscores in objects. No differences between all data types.\n\n# Erstellt einen Objektbaum im ioBroker\n\nDiese Node erstellt einen Objektbaum im ioBroker aus einem JAVA Objekt bzw. einem JSON String. \n\nDer Baum wird in jedem Fall unter 0_userdata.0 erstellt und zwar unter dem Topic der in msg.top mitgegeben wurde. In der msg.payload befindet sich dann der JSON String oder das entsprechende Objekt.\n\nExistierende msg.topic Einträge werden gelöscht.\nEin entsprechende iobroker-out Node muss an den Flow angehängt werden. Sie ist nicht Bestandteil des Subflows. In dieser iobroker-out Node darf kein Topic angegeben werden. \n\nFalls msg.top nicht definiert wurde, wird der top-Wert der Subflow-Node verwendet.\n\nIn den Eigenschaften der Subflow-Node wurde ein neuer Parameter keepTopic hinzugefügt. Standardwert ist false, um das bisherige Verhalten beizubehalten. Setzt man die Eigenschaft auf true, dann wird das originale Topic zwischen der top Eigenschaft der Subflow-Node und Eigenschaft des analysierten JSON Objektes eingefügt.\n\nAchtung:\nWenn top und msg.top leer ist, werden alle msg.topics (msg.topic) direkt unter dem Präfix 0_userdata.0., angelegt bzw. ausgegeben. \n\nUpdate 13.09.2022:\nLeerzeichen werden in Topics von Objekten nicht mehr durch Unterstriche ersetzt. Es gibt keine Unterschiede mehr zwischen den Datentypen.",
      "category": "",
      "in": [
      {
      "x": 60,
      "y": 160,
      "wires": [
      {
      "id": "554b8c663bcb46c2"
      }
      ]
      }
      ],
      "out": [
      {
      "x": 2620,
      "y": 280,
      "wires": [
      {
      "id": "0962842ebd23e0d7",
      "port": 0
      }
      ]
      }
      ],
      "env": [
      {
      "name": "top",
      "type": "str",
      "value": "objRoot"
      },
      {
      "name": "keepTopic",
      "type": "bool",
      "value": "false"
      }
      ],
      "meta": {},
      "color": "#E2D96E",
      "icon": "node-red/batch.svg"
      },
      {
      "id": "3e11e8338f694832",
      "type": "split",
      "z": "6e802f1553b18149",
      "name": "split object",
      "splt": "\n",
      "spltType": "str",
      "arraySplt": 1,
      "arraySpltType": "len",
      "stream": false,
      "addname": "key",
      "x": 1370,
      "y": 160,
      "wires": [
      [
      "0562a4249c8b856b"
      ]
      ]
      },
      {
      "id": "0562a4249c8b856b",
      "type": "change",
      "z": "6e802f1553b18149",
      "name": "add key to topic",
      "rules": [
      {
      "t": "set",
      "p": "stateName",
      "pt": "msg",
      "to": "key",
      "tot": "msg"
      },
      {
      "t": "set",
      "p": "topic",
      "pt": "msg",
      "to": "topic & '.' & key",
      "tot": "jsonata"
      }
      ],
      "action": "",
      "property": "",
      "from": "",
      "to": "",
      "reg": false,
      "x": 1560,
      "y": 160,
      "wires": [
      [
      "ddc90985bef0fafa"
      ]
      ]
      },
      {
      "id": "ddc90985bef0fafa",
      "type": "switch",
      "z": "6e802f1553b18149",
      "name": "is type?",
      "property": "payload",
      "propertyType": "msg",
      "rules": [
      {
      "t": "istype",
      "v": "array",
      "vt": "array"
      },
      {
      "t": "istype",
      "v": "object",
      "vt": "object"
      },
      {
      "t": "else"
      }
      ],
      "checkall": "true",
      "repair": false,
      "outputs": 3,
      "x": 1740,
      "y": 160,
      "wires": [
      [
      "bfce19b206660fbe"
      ],
      [
      "3e11e8338f694832"
      ],
      [
      "1a8c03d866b85b12"
      ]
      ]
      },
      {
      "id": "bfce19b206660fbe",
      "type": "split",
      "z": "6e802f1553b18149",
      "name": "split array",
      "splt": "\n",
      "spltType": "str",
      "arraySplt": 1,
      "arraySpltType": "len",
      "stream": false,
      "addname": "",
      "x": 780,
      "y": 280,
      "wires": [
      [
      "e89927810c6d75ec"
      ]
      ]
      },
      {
      "id": "e89927810c6d75ec",
      "type": "change",
      "z": "6e802f1553b18149",
      "name": "add index to topic",
      "rules": [
      {
      "t": "set",
      "p": "topic",
      "pt": "msg",
      "to": "topic & '.' & parts.index",
      "tot": "jsonata"
      }
      ],
      "action": "",
      "property": "",
      "from": "",
      "to": "",
      "reg": false,
      "x": 970,
      "y": 280,
      "wires": [
      [
      "a4d1a5d04564dc77"
      ]
      ]
      },
      {
      "id": "f5d52c6a57d08904",
      "type": "change",
      "z": "6e802f1553b18149",
      "name": "finalize msg.topic",
      "rules": [
      {
      "t": "set",
      "p": "top",
      "pt": "msg",
      "to": "'0_userdata.0.' & top",
      "tot": "jsonata"
      },
      {
      "t": "set",
      "p": "topic",
      "pt": "msg",
      "to": "top & '.' & topic",
      "tot": "jsonata"
      }
      ],
      "action": "",
      "property": "",
      "from": "",
      "to": "",
      "reg": false,
      "x": 2170,
      "y": 240,
      "wires": [
      [
      "0962842ebd23e0d7"
      ]
      ]
      },
      {
      "id": "c863dd7d651b2272",
      "type": "switch",
      "z": "6e802f1553b18149",
      "name": "is type?",
      "property": "payload",
      "propertyType": "msg",
      "rules": [
      {
      "t": "istype",
      "v": "json",
      "vt": "json"
      },
      {
      "t": "istype",
      "v": "object",
      "vt": "object"
      },
      {
      "t": "istype",
      "v": "array",
      "vt": "array"
      },
      {
      "t": "else"
      }
      ],
      "checkall": "true",
      "repair": false,
      "outputs": 4,
      "x": 580,
      "y": 160,
      "wires": [
      [
      "158930afddd0780b"
      ],
      [
      "3e11e8338f694832"
      ],
      [
      "bfce19b206660fbe"
      ],
      [
      "a4d1a5d04564dc77"
      ]
      ]
      },
      {
      "id": "158930afddd0780b",
      "type": "json",
      "z": "6e802f1553b18149",
      "name": "",
      "property": "payload",
      "action": "",
      "pretty": false,
      "x": 770,
      "y": 120,
      "wires": [
      [
      "3649300b4c233b10"
      ]
      ]
      },
      {
      "id": "1a8c03d866b85b12",
      "type": "switch",
      "z": "6e802f1553b18149",
      "name": "is msg.top != null",
      "property": "top",
      "propertyType": "msg",
      "rules": [
      {
      "t": "nnull"
      },
      {
      "t": "null"
      }
      ],
      "checkall": "true",
      "repair": false,
      "outputs": 2,
      "x": 1950,
      "y": 280,
      "wires": [
      [
      "f5d52c6a57d08904"
      ],
      [
      "74c895ce724750de"
      ]
      ]
      },
      {
      "id": "e023fe88445ce43e",
      "type": "change",
      "z": "6e802f1553b18149",
      "name": "",
      "rules": [
      {
      "t": "delete",
      "p": "topic",
      "pt": "msg"
      }
      ],
      "action": "",
      "property": "",
      "from": "",
      "to": "",
      "reg": false,
      "x": 350,
      "y": 200,
      "wires": [
      [
      "c863dd7d651b2272"
      ]
      ]
      },
      {
      "id": "3649300b4c233b10",
      "type": "switch",
      "z": "6e802f1553b18149",
      "name": "is array?",
      "property": "payload",
      "propertyType": "msg",
      "rules": [
      {
      "t": "istype",
      "v": "array",
      "vt": "array"
      },
      {
      "t": "else"
      }
      ],
      "checkall": "true",
      "repair": false,
      "outputs": 2,
      "x": 900,
      "y": 120,
      "wires": [
      [
      "bfce19b206660fbe"
      ],
      [
      "3e11e8338f694832"
      ]
      ]
      },
      {
      "id": "1b8480cd2df7ba3f",
      "type": "comment",
      "z": "6e802f1553b18149",
      "name": "Array",
      "info": "",
      "x": 600,
      "y": 280,
      "wires": []
      },
      {
      "id": "b3541807672be040",
      "type": "comment",
      "z": "6e802f1553b18149",
      "name": "object",
      "info": "",
      "x": 1340,
      "y": 100,
      "wires": []
      },
      {
      "id": "a4d1a5d04564dc77",
      "type": "switch",
      "z": "6e802f1553b18149",
      "name": "is type?",
      "property": "payload",
      "propertyType": "msg",
      "rules": [
      {
      "t": "istype",
      "v": "object",
      "vt": "object"
      },
      {
      "t": "istype",
      "v": "array",
      "vt": "array"
      },
      {
      "t": "else"
      }
      ],
      "checkall": "true",
      "repair": false,
      "outputs": 3,
      "x": 1160,
      "y": 280,
      "wires": [
      [
      "3e11e8338f694832"
      ],
      [
      "bfce19b206660fbe"
      ],
      [
      "1a8c03d866b85b12"
      ]
      ]
      },
      {
      "id": "74c895ce724750de",
      "type": "change",
      "z": "6e802f1553b18149",
      "name": "finalize msg.topic",
      "rules": [
      {
      "t": "set",
      "p": "top",
      "pt": "msg",
      "to": "top",
      "tot": "env"
      },
      {
      "t": "set",
      "p": "top",
      "pt": "msg",
      "to": "'0_userdata.0.' & top",
      "tot": "jsonata"
      },
      {
      "t": "set",
      "p": "topic",
      "pt": "msg",
      "to": "top & '.' & topic",
      "tot": "jsonata"
      }
      ],
      "action": "",
      "property": "",
      "from": "",
      "to": "",
      "reg": false,
      "x": 2170,
      "y": 320,
      "wires": [
      [
      "0962842ebd23e0d7"
      ]
      ]
      },
      {
      "id": "554b8c663bcb46c2",
      "type": "switch",
      "z": "6e802f1553b18149",
      "name": "",
      "property": "keepTopic",
      "propertyType": "env",
      "rules": [
      {
      "t": "true"
      },
      {
      "t": "false"
      }
      ],
      "checkall": "true",
      "repair": false,
      "outputs": 2,
      "x": 170,
      "y": 160,
      "wires": [
      [
      "e30ba9f0483285e4"
      ],
      [
      "e023fe88445ce43e"
      ]
      ]
      },
      {
      "id": "e30ba9f0483285e4",
      "type": "change",
      "z": "6e802f1553b18149",
      "name": "",
      "rules": [
      {
      "t": "change",
      "p": "topic",
      "pt": "msg",
      "from": "/",
      "fromt": "str",
      "to": ".",
      "tot": "str"
      }
      ],
      "action": "",
      "property": "",
      "from": "",
      "to": "",
      "reg": false,
      "x": 350,
      "y": 120,
      "wires": [
      [
      "c863dd7d651b2272"
      ]
      ]
      },
      {
      "id": "0962842ebd23e0d7",
      "type": "change",
      "z": "6e802f1553b18149",
      "name": "translate invalid chars in topic",
      "rules": [
      {
      "t": "change",
      "p": "topic",
      "pt": "msg",
      "from": "..",
      "fromt": "str",
      "to": ".",
      "tot": "str"
      },
      {
      "t": "change",
      "p": "topic",
      "pt": "msg",
      "from": "€",
      "fromt": "str",
      "to": "EUR",
      "tot": "str"
      }
      ],
      "action": "",
      "property": "",
      "from": "",
      "to": "",
      "reg": false,
      "x": 2430,
      "y": 280,
      "wires": [
      []
      ]
      },
      {
      "id": "16c33b1e099682e0",
      "type": "subflow",
      "name": "solar inverter",
      "info": "TCP server for LSW3 wifi logger \r\nused with Sofar inverters\r\n\r\n## Supported inverters\r\n\r\nSofar KTL-X \r\nSofar ME3000SP \r\nSofar HYD6000-ES \r\n\r\n### Outputs\r\n1. JSON data\r\n: payload (object) : parsed data object.\r\n: topic (string) : frame data type.\r\n\r\n2. debug\r\n: payload (buffer) : raw data from inverter.\r\n: topic (string) : message origin.\r\n: frameType (string) : frame data type.\r\n\r\n### Details\r\n\r\nDefault local server port: \r\n10000\r\n\r\nDefault host IP: \r\n47.88.8.200 (data1.solarmanpv.com) \r\nor \r\n115.29.186.234 (data2.solarmanpv.com) \r\n\r\nDefault port nr: \r\n10000\r\n\r\n### References\r\n\r\n - GitHub - the node github repository\r\n",
      "category": "",
      "in": [],
      "out": [
      {
      "x": 630,
      "y": 260,
      "wires": [
      {
      "id": "5d0553bafc1e3bf7",
      "port": 0
      }
      ]
      },
      {
      "x": 1150,
      "y": 260,
      "wires": [
      {
      "id": "a92085a4d10f12e6",
      "port": 0
      }
      ]
      }
      ],
      "env": [
      {
      "name": "localPort",
      "type": "num",
      "value": "10000",
      "ui": {
      "icon": "font-awesome/fa-plug",
      "label": {
      "en-US": "local port"
      },
      "type": "input",
      "opts": {
      "types": [
      "num",
      "env"
      ]
      }
      }
      },
      {
      "name": "resend",
      "type": "bool",
      "value": "false",
      "ui": {
      "label": {
      "en-US": "forward data to remote server"
      },
      "type": "checkbox"
      }
      },
      {
      "name": "remoteHostIp",
      "type": "str",
      "value": "47.102.152.71",
      "ui": {
      "icon": "font-awesome/fa-cloud-upload",
      "label": {
      "en-US": "remote ip"
      },
      "type": "input",
      "opts": {
      "types": [
      "str",
      "env"
      ]
      }
      }
      },
      {
      "name": "remoteHostPort",
      "type": "num",
      "value": "10000",
      "ui": {
      "icon": "font-awesome/fa-plug",
      "label": {
      "en-US": "remote port"
      },
      "type": "input",
      "opts": {
      "types": [
      "num",
      "env"
      ]
      }
      }
      }
      ],
      "meta": {
      "version": "1.2.0",
      "author": "serek4",
      "desc": "sofar inverter with LSW3 wifi logger",
      "license": "MIT"
      },
      "color": "#20c800",
      "outputLabels": [
      "JSON data",
      "debug"
      ],
      "icon": "node-red/bridge-dash.svg"
      },
      {
      "id": "f0ad23cb42522771",
      "type": "tcp in",
      "z": "16c33b1e099682e0",
      "name": "Inverter stick out",
      "server": "server",
      "host": "",
      "port": "${localPort}",
      "datamode": "stream",
      "datatype": "buffer",
      "newline": "",
      "topic": "inverter",
      "trim": false,
      "base64": false,
      "tls": "",
      "x": 140,
      "y": 120,
      "wires": [
      [
      "88b9df11c34f72ea",
      "a92085a4d10f12e6",
      "5d0553bafc1e3bf7"
      ]
      ]
      },
      {
      "id": "164f421ec73701f9",
      "type": "tcp request",
      "z": "16c33b1e099682e0",
      "name": "Solarmanpv.com",
      "server": "",
      "port": "",
      "out": "time",
      "ret": "buffer",
      "splitc": "1000",
      "newline": "",
      "trim": false,
      "tls": "",
      "x": 810,
      "y": 160,
      "wires": [
      [
      "a92085a4d10f12e6"
      ]
      ]
      },
      {
      "id": "c511e8c8f7ced576",
      "type": "function",
      "z": "16c33b1e099682e0",
      "name": "generate response",
      "func": "const request = msg.payload;\n\nconst timestamp = Math.floor(Date.now() / 1000);\nconst timestampStr = timestamp.toString(16);\nconst timestampBuff = Buffer.from(timestamp.toString(16), 'hex');\n\nconst response = Buffer.alloc(23);\nresponse.writeUInt8(0xA5, 0x00); // msg begin\n\nresponse.writeUInt8(0x0A, 0x01); // msg length\nresponse.writeUInt8(0x00, 0x02);\n\nresponse.writeUInt8(0x10, 0x03);\nresponse.writeUInt8(responseType(request.readUInt8(0x04)), 0x04); // match req type\n\nresponse.writeUInt8(request.readUInt8(0x05) >= 0xFF ? 0x00 : request.readUInt8(0x05) + 0x01, 0x05); // get from req + 1\nresponse.writeUInt8(request.readUInt8(0x06), 0x06); // get from req\n\nresponse.writeUInt32LE(request.readUInt32LE(0x07), 0x07); // wifi SN - get from req\n\nresponse.writeUInt8(request.readUInt8(0x0B), 0x0B); // get from req\nresponse.writeUInt8(0x01, 0x0C);\n\nresponse.writeUInt32LE(timestampBuff.readUInt32BE(0x00), 0x0D); // timestamp\n\nresponse.writeUInt8(0x78, 0x11);\nresponse.writeUInt8(0x00, 0x12);\nresponse.writeUInt8(0x00, 0x13);\nresponse.writeUInt8(0x00, 0x14);\n\nresponse.writeUInt8(calculateChecksum(response), 0x15); //checksum\nresponse.writeUInt8(0x15, 0x16); // msg end\n\nmsg.payload = response;\nmsg.topic = 'local_server';\nreturn msg;\n\nfunction responseType(requestTypeByte) {\n // node.warn(req code: 0x${requestTypeByte.toString(16)});\n let responseTypeByte = requestTypeByte - (0x30);\n responseTypeByte = Math.min(Math.max(responseTypeByte, 0x00), 0xFF); //min 0x00 max 255\n // switch(requestTypeByte) {\n // case 0x41:\n // responseTypeByte = 0x11;\n // break;\n // case 0x42:\n // responseTypeByte = 0x12;\n // break;\n // case 0x43:\n // responseTypeByte = 0x13;\n // break;\n // case 0x47:\n // responseTypeByte = 0x17;\n // break;\n // case 0x48:\n // responseTypeByte = 0x18;\n // break;\n // default:\n // responseTypeByte = 0xFF;\n // }\n // node.warn(res code: 0x${responseTypeByte.toString(16)});\n return responseTypeByte;\n}\nfunction calculateChecksum(message) {\n message = message.slice(1, -2);\n let sum = 0x0;\n for (const key of message.keys()) {\n sum += message[key];\n }\n sum = sum % 256;\n // node.warn( sum.toString(16));\n return sum;\n}",
      "outputs": 1,
      "noerr": 0,
      "initialize": "",
      "finalize": "",
      "libs": [],
      "x": 810,
      "y": 120,
      "wires": [
      [
      "95b6eef2f2bbf823",
      "a92085a4d10f12e6"
      ]
      ],
      "inputLabels": [
      "data from wifi stick"
      ],
      "outputLabels": [
      "response out"
      ]
      },
      {
      "id": "95b6eef2f2bbf823",
      "type": "tcp out",
      "z": "16c33b1e099682e0",
      "name": "Inverter stick response in",
      "host": "",
      "port": "10000",
      "beserver": "reply",
      "base64": false,
      "end": true,
      "tls": "",
      "x": 1090,
      "y": 120,
      "wires": []
      },
      {
      "id": "5d0553bafc1e3bf7",
      "type": "function",
      "z": "16c33b1e099682e0",
      "name": "decode msg",
      "func": "let buffer = msg.payload;\nlet data = {};\nswitch (buffer.length) {\n case 547: // data - BMI-600 & SUN600G3-EU-230\n data.loggerSN = buffer.readUInt32LE(0x07);\n\n data.inverterSN = (buffer.toString('utf8', 0x20, 0x29)).trimEnd();\n \n data.dailyGenerationkWh = buffer.readUInt32LE(0x2C) / 100;\n data.generationTotalkWh = buffer.readUInt32LE(0x30) / 10;\n\n data.powerGridVoltageV = buffer.readUInt16LE(0x38) / 10;\n data.powerGridCurrentA = buffer.readUInt16LE(0x3E) / 10;\n\n data.ACFrequencyHz = buffer.readUInt16LE(0x44) / 100;\n data.ACOutputTotalPowerW = buffer.readUInt16LE(0x46);\n data.tempHeatSink = buffer.readInt16LE(0x4A) / 100;\n \n\n data.DCPV1VoltageV = buffer.readUInt16LE(0x60) / 10;\n data.DCPV1CurrentA = buffer.readUInt16LE(0x62) / 10;\n data.DCPV2VoltageV = buffer.readUInt16LE(0x64) / 10;\n data.DCPV2CurrentA = buffer.readUInt16LE(0x66) / 10;\n \n data.ComProtVer = (buffer.toString('utf8', 0x70, 0x77)).trimEnd();\n data.ContrBoardVer = (buffer.toString('utf8', 0x78, 0x7F)).trimEnd();\n data.ComBoardVer = (buffer.toString('utf8', 0x80, 0x87)).trimEnd();\n\n data.RatedPowerW = buffer.readUInt16BE(0x8C) / 10;\n \n data.Modul1SN = (buffer.toString('utf8', 0xAA, 0xB9)).trimEnd();\n data.Modul2SN = (buffer.toString('utf8', 0xBA, 0xC9)).trimEnd();\n data.Modul3SN = (buffer.toString('utf8', 0xCA, 0xD9)).trimEnd();\n data.Modul4SN = (buffer.toString('utf8', 0xDA, 0xE9)).trimEnd();\n \n data.overfreqHz = buffer.readUInt16BE(0xEA) / 100;\n data.overfreqPerc = buffer.readUInt16BE(0xEC);\n data.gridVoltageUpLim = buffer.readUInt16BE(0xF6) / 10 ;\n data.gridVoltageLowLim = buffer.readUInt16BE(0xF8) / 10;\n data.gridFreqUpLim = buffer.readUInt16BE(0xFA) / 100;\n data.gridFreqLowLim = buffer.readUInt16BE(0xFC) / 100;\n data.selfcheckTimeSec = buffer.readUInt16BE(0xFE);\n \n data.year = buffer.readUInt8(0x100);\n data.month = buffer.readUInt8(0x101);\n data.day = buffer.readUInt8(0x102);\n data.hour = buffer.readUInt8(0x103);\n data.minute = buffer.readUInt8(0x104);\n data.second = buffer.readUInt8(0x105); \n \n /*\n data.DCPV2PowerW = buffer.readUInt16LE(0x68) * 10;\n data.ACPVoltageV = buffer.readUInt16LE(0x3C) / 10;\n data.ACCurrentA = buffer.readUInt16LE(0x3E) / 100;\n data.ACFrequencyHz = buffer.readUInt16LE(0x40) / 100;\n data.battPowerW = buffer.readInt16LE(0x42) * 10;\n data.battVoltageV = buffer.readUInt16LE(0x44) / 10;\n data.battCurrentA = buffer.readInt16LE(0x46) / 100;\n data.battSoCPct = buffer.readUInt16LE(0x48);\n data.battTempC = buffer.readUInt16LE(0x4A);\n data.consumptionTotalW = buffer.readUInt16LE(0x4E) * 10;\n data.ACOutputTotalPowerW = buffer.readUInt16LE(0x52);\n data.emergencyOutputVoltageV = buffer.readUInt16LE(0x54) / 10;\n data.emergencyOutputPowerW = buffer.readUInt16LE(0x56) * 10;\n data.dailyGenerationkWh = buffer.readUInt16LE(0x58) / 100;\n data.dailyOnGridEnergykWh = buffer.readUInt16LE(0x5A) / 100;\n data.dailyEnergyPurchasedkWh = buffer.readUInt16LE(0x5C) / 100;\n data.dailyEnergyUsedkWh = buffer.readUInt16LE(0x5E) / 100;\n data.generationTotalkWh = buffer.readUInt32LE(0x60);\n data.totalOnGridGenerationkWh = buffer.readUInt32LE(0x64);\n data.totalEnergyPurchasedkWh = buffer.readUInt32LE(0x68);\n data.totalEnergyConsumptionkWh = buffer.readUInt32LE(0x6C);\n data.battDailyEnergyDischargedkWh = buffer.readUInt16LE(0x70) / 100;\n data.battDailyEnergyChargedkWh = buffer.readUInt16LE(0x72) / 100;\n data.battTotalEnergyChargedkWh = buffer.readUInt32LE(0x74);\n data.battTotalEnergyDischargedkWh = buffer.readUInt32LE(0x78);\n data.battTotalChargingDischargingTimesNum = buffer.readUInt16LE(0x80);\n data.busVoltageV = buffer.readUInt16LE(0x82) / 10;\n data.LLCbusVoltageV = buffer.readUInt16LE(0x84) / 10;\n data.buckCurrentA = buffer.readUInt16LE(0x86) / 100;\n data.powerGridVoltageV = buffer.readUInt16LE(0x88) / 10;\n data.powerGridCurrentA = buffer.readUInt16LE(0x8A) / 100;\n data.inverterTempC = buffer.readUInt16LE(0x8E);\n data.radiatorTempC = buffer.readUInt16LE(0x90);\n data.currentDCComponentA = buffer.readInt16LE(0x94);\n data.voltageDCComponentV = buffer.readInt16LE(0x96);\n data.dailyGeneratingHours = buffer.readUInt8(0xA4);\n data.totalGeneratingHours = buffer.readUInt32LE(0xA6);\n data.insulationImpedanceToTheGround = buffer.readUInt16LE(0xAA);\n data.insulationImpedancePVToGround = buffer.readUInt16LE(0xAC);\n data.insulationImpedanceCathodeToGround = buffer.readUInt16LE(0xAE);\n \n data.year = buffer.readUInt8(0xC8);\n data.month = buffer.readUInt8(0xC9);\n data.day = buffer.readUInt8(0xCA);\n data.hour = buffer.readUInt8(0xCB);\n data.minute = buffer.readUInt8(0xCC);\n data.second = buffer.readUInt8(0xCD);\n */\n return {\n payload: data,\n topic: "Solar " + data.loggerSN\n };\n break;\n case 208: // data - HYD6000ES\n data.loggerSN = buffer.readUInt32LE(0x07);\n data.inverterSN = (buffer.toString('utf8', 0x20, 0x30)).trimEnd();\n data.DCPV1VoltageV = buffer.readUInt16LE(0x30) / 10;\n data.DCPV1CurrentA = buffer.readUInt16LE(0x32) / 100;\n data.DCPV1PowerW = buffer.readUInt16LE(0x34) * 10;\n data.DCPV2VoltageV = buffer.readUInt16LE(0x36) / 10;\n data.DCPV2CurrentA = buffer.readUInt16LE(0x38) / 100;\n data.DCPV2PowerW = buffer.readUInt16LE(0x3A) * 10;\n data.ACPVoltageV = buffer.readUInt16LE(0x3C) / 10;\n data.ACCurrentA = buffer.readUInt16LE(0x3E) / 100;\n data.ACFrequencyHz = buffer.readUInt16LE(0x40) / 100;\n data.battPowerW = buffer.readInt16LE(0x42) * 10;\n data.battVoltageV = buffer.readUInt16LE(0x44) / 10;\n data.battCurrentA = buffer.readInt16LE(0x46) / 100;\n data.battSoCPct = buffer.readUInt16LE(0x48);\n data.battTempC = buffer.readUInt16LE(0x4A);\n data.consumptionTotalW = buffer.readUInt16LE(0x4E) * 10;\n data.ACOutputTotalPowerW = buffer.readUInt16LE(0x52);\n data.emergencyOutputVoltageV = buffer.readUInt16LE(0x54) / 10;\n data.emergencyOutputPowerW = buffer.readUInt16LE(0x56) * 10;\n data.dailyGenerationkWh = buffer.readUInt16LE(0x58) / 100;\n data.dailyOnGridEnergykWh = buffer.readUInt16LE(0x5A) / 100;\n data.dailyEnergyPurchasedkWh = buffer.readUInt16LE(0x5C) / 100;\n data.dailyEnergyUsedkWh = buffer.readUInt16LE(0x5E) / 100;\n data.generationTotalkWh = buffer.readUInt32LE(0x60);\n data.totalOnGridGenerationkWh = buffer.readUInt32LE(0x64);\n data.totalEnergyPurchasedkWh = buffer.readUInt32LE(0x68);\n data.totalEnergyConsumptionkWh = buffer.readUInt32LE(0x6C);\n data.battDailyEnergyDischargedkWh = buffer.readUInt16LE(0x70) / 100;\n data.battDailyEnergyChargedkWh = buffer.readUInt16LE(0x72) / 100;\n data.battTotalEnergyChargedkWh = buffer.readUInt32LE(0x74);\n data.battTotalEnergyDischargedkWh = buffer.readUInt32LE(0x78);\n data.battTotalChargingDischargingTimesNum = buffer.readUInt16LE(0x80);\n data.busVoltageV = buffer.readUInt16LE(0x82) / 10;\n data.LLCbusVoltageV = buffer.readUInt16LE(0x84) / 10;\n data.buckCurrentA = buffer.readUInt16LE(0x86) / 100;\n data.powerGridVoltageV = buffer.readUInt16LE(0x88) / 10;\n data.powerGridCurrentA = buffer.readUInt16LE(0x8A) / 100;\n data.inverterTempC = buffer.readUInt16LE(0x8E);\n data.radiatorTempC = buffer.readUInt16LE(0x90);\n data.currentDCComponentA = buffer.readInt16LE(0x94);\n data.voltageDCComponentV = buffer.readInt16LE(0x96);\n data.dailyGeneratingHours = buffer.readUInt8(0xA4);\n data.totalGeneratingHours = buffer.readUInt32LE(0xA6);\n data.insulationImpedanceToTheGround = buffer.readUInt16LE(0xAA);\n data.insulationImpedancePVToGround = buffer.readUInt16LE(0xAC);\n data.insulationImpedanceCathodeToGround = buffer.readUInt16LE(0xAE);\n data.year = buffer.readUInt8(0xC8);\n data.month = buffer.readUInt8(0xC9);\n data.day = buffer.readUInt8(0xCA);\n data.hour = buffer.readUInt8(0xCB);\n data.minute = buffer.readUInt8(0xCC);\n data.second = buffer.readUInt8(0xCD);\n return {\n payload: data,\n topic: 'data'\n };\n break;\n case 232: // data - ME3000SP\n data.loggerSN = buffer.readUInt32LE(0x07);\n data.tempLogger = buffer.readInt16LE(0x70) / 100;\n data.tempBattery = buffer.readInt16LE(0x30) / 10;\n data.tempInverter = buffer.readInt16LE(0xA6);\n data.tempHeatSink = buffer.readInt16LE(0xA8);\n data.sensorTypeList = readSensorTypeList(buffer.slice(0x0C, 0x0E));\n data.tOperationTime = buffer.readUInt32LE(0x0E);\n data.inverterSN = (buffer.toString('utf8', 0x20, 0x30)).trimEnd();\n data.VAC1 = buffer.readUInt16LE(0x40) / 10;\n data.VAC2 = buffer.readUInt16LE(0x42) / 10;\n data.VAC3 = buffer.readUInt16LE(0x44) / 10;\n data.frequencyPowerGrid = buffer.readUInt16LE(0x46) / 100;\n data.currentPower = buffer.readUInt32LE(0x48);\n data.inverterStatus = decodeInverterStatus(buffer.readUInt8(0x58));\n data.Vbus = buffer.readUInt16LE(0x72) / 10;\n data.VCPU1 = buffer.readUInt16LE(0x74) / 10;\n data.cathode_groundInsulationImpedance = buffer.readUInt16LE(0x80);\n data.countryCode = buffer.readUInt16LE(0x82);\n data.A_phaseDCdistribution = buffer.readUInt16LE(0x8A);\n data.B_phaseDCdistribution = buffer.readUInt16LE(0x8C);\n data.C_phaseDCdistribution = buffer.readUInt16LE(0x8E);\n data.consumptionDailyEnergyPurchase = buffer.readUInt16LE(0x76);\n data.consumptionDailyEnergyUsed = buffer.readUInt16LE(0x78);\n data.consumptionTotal = buffer.readUInt16LE(0x86);\n data.generationTotal = buffer.readUInt16LE(0x7A);\n data.generationTotalOnGrid = buffer.readUInt16LE(0x7E);\n data.battChargeLevel = buffer.readUInt16LE(0x6A);\n data.battChargeDischargePower = buffer.readInt16LE(0x64) * 10;\n data.battCurrent = buffer.readInt16LE(0x68) / 100;\n data.battDailyGenerationPV = buffer.readUInt32LE(0x4C) / 100;\n data.battDailyEnergyCharged = buffer.readUInt16LE(0xc4) / 100;\n data.battDailyEnergyDischarged = buffer.readUInt16LE(0xC6) / 100;\n data.battGenerationCurrent = buffer.readInt16LE(0xA2) / 100;\n data.battTotalEnergyCharged = buffer.readUInt32LE(0xC8);\n data.battTotalEnergyDischarged = buffer.readUInt32LE(0xCC);\n data.battPower = buffer.readInt16LE(0xc2) * 10;\n data.battVoltage = buffer.readUInt16LE(0x66) / 100;\n\n data.busVoltage = buffer.readUInt16LE(0x90) / 10;\n data.busVoltageLlc = buffer.readUInt16LE(0x92) / 10;\n data.buckCurrent = buffer.readInt16LE(0x94) / 100;\n data.voltageDCComponent = buffer.readInt16LE(0xAE) / 10;\n data.epsOutVoltage = buffer.readInt16LE(0x96) / 10;\n data.productionCurrentR = buffer.readUInt16LE(0x98) / 100;\n data.productionCurrentS = buffer.readUInt16LE(0x9E) / 100;\n data.productionCurrentT = buffer.readUInt16LE(0xA0) / 100;\n data.year = buffer.readUInt8(0xE0);\n data.month = buffer.readUInt8(0xE1);\n data.day = buffer.readUInt8(0xE2);\n data.hour = buffer.readUInt8(0xE3);\n data.minute = buffer.readUInt8(0xE4);\n data.second = buffer.readUInt8(0xE5);\n let dateFormat = '20' + String(data.year).padStart(2, '0') + '-' + String(data.month).padStart(2, '0') + '-' + String(data.day).padStart(2, '0') + 'T' + String(data.hour).padStart(2, '0') + ':' + String(data.minute).padStart(2, '0') + ':' + String(data.second).padStart(2, '0')\n data.timestamp = new Date(dateFormat)\n //node.warn(data);\n return {\n payload: data,\n topic: 'data'\n };\n break;\n\n case 164: // data - KTL-X\n data.loggerSN = buffer.readUInt32LE(0x07);\n data.sensorTypeList = readSensorTypeList(buffer.slice(0x0C, 0x0E));\n data.tOperationTime = buffer.readUInt32LE(0x0E);\n data.inverterSN = (buffer.toString('utf8', 0x20, 0x30)).trimEnd();\n data.inverterTemp = buffer.readInt16LE(0x30) / 10;\n data.VDC1 = buffer.readUInt16LE(0x32) / 10;\n data.VDC2 = buffer.readUInt16LE(0x34) / 10;\n data.IDC1 = buffer.readUInt16LE(0x36) / 10;\n data.IDC2 = buffer.readUInt16LE(0x38) / 10;\n data.IAC1 = buffer.readUInt16LE(0x3A) / 10;\n data.IAC2 = buffer.readUInt16LE(0x3C) / 10;\n data.IAC3 = buffer.readUInt16LE(0x3E) / 10;\n data.VAC1 = buffer.readUInt16LE(0x40) / 10;\n data.VAC2 = buffer.readUInt16LE(0x42) / 10;\n data.VAC3 = buffer.readUInt16LE(0x44) / 10;\n data.fAC = buffer.readUInt16LE(0x46) / 100;\n\n data.currentPower = buffer.readUInt32LE(0x48);\n\n data.eToday = buffer.readUInt32LE(0x4C) / 100;\n data.eTotal = buffer.readUInt32LE(0x50) / 10;\n\n data.hTotal = buffer.readUInt32LE(0x54);\n\n data.inverterStatus = decodeInverterStatus(buffer.readUInt8(0x58));\n\n data.loggerTemp = buffer.readInt16LE(0x70);\n data.Vbus = buffer.readUInt16LE(0x72) / 10;\n data.VCPU1 = buffer.readUInt16LE(0x74) / 10;\n data.countdownTime = buffer.readUInt16LE(0x78);\n data.PV1insulationResistance = buffer.readUInt16LE(0x7C);\n data.PV2insulationResistance = buffer.readUInt16LE(0x7E);\n data.cathode_groundInsulationImpedance = buffer.readUInt16LE(0x80);\n data.countryCode = buffer.readUInt16LE(0x82);\n data.A_phaseDCdistribution = buffer.readUInt16LE(0x8A);\n data.B_phaseDCdistribution = buffer.readUInt16LE(0x8C);\n data.C_phaseDCdistribution = buffer.readUInt16LE(0x8E);\n\n data.firmware = buffer.toString('utf8', 0x90, 0x94);\n\n data.year = buffer.readUInt8(0x98);\n data.month = buffer.readUInt8(0x99);\n data.day = buffer.readUInt8(0x9A);\n data.hour = buffer.readUInt8(0x9B);\n data.minute = buffer.readUInt8(0x9C);\n data.second = buffer.readUInt8(0x9D);\n\n // node.warn(data);\n return {\n payload: data,\n topic: 'data'\n };\n break;\n case 99: // hello message\n data.loggerSN = buffer.readUInt32LE(0x07);\n data.tOperationTime = buffer.readUInt32LE(0x0C);\n data.uploadingFrequency = buffer.readUInt8(0x18);\n data.dataLoggingFrequency = buffer.readUInt8(0x19);\n data.heartbeatFrequency = buffer.readUInt8(0x1A);\n data.commandType = buffer.readUInt8(0x1B);\n data.signalQuality = buffer.readUInt8(0x1C);\n data.sensorTypeNr = buffer.readUInt8(0x1D);\n data.moduleVersion = buffer.toString('utf8', 0x1E, 0x46);\n data.macAddress = readMacAddress(buffer.slice(0x46, 0x4C));\n data.localIP = buffer.toString('utf8', 0x4C, 0x5B);\n data.sensorTypeList = readSensorTypeList(buffer.slice(0x5F, 0x61));\n\n // node.warn(data);\n return {\n payload: data,\n topic: 'hello'\n };\n break;\n case 41: // hello_cd message\n data.loggerSN = buffer.readUInt32LE(0x07);\n data.totalOperationTime = buffer.readUInt32LE(0x0C);\n\n // node.warn(data);\n return {\n payload: data,\n topic: 'hello_cd'\n };\n break;\n case 73: // hello_end message\n data.loggerSN = buffer.readUInt32LE(0x07);\n data.totalOperationTime = buffer.readUInt32LE(0x0C);\n\n // node.warn(data);\n return {\n payload: data,\n topic: 'hello_end'\n };\n break;\n\n default:\n // node.warn(buffer.length);\n return null\n break;\n}\n\nfunction readMacAddress(buffer) {\n let macAddressStr = '';\n for (let buff of buffer) {\n // node.warn(buff.toString(16));\n macAddressStr += ${0${(buff.toString(16))}.slice(-2)}:;\n }\n return macAddressStr.substring(0, 17);\n}\nfunction readSensorTypeList(buffer) {\n let SensorTypeListStr = ${0${(buffer[1].toString(16))}.slice(-2)};\n SensorTypeListStr += ${0${(buffer[0].toString(16))}.slice(-2)};\n return SensorTypeListStr;\n}\n\nfunction decodeInverterStatus(status) {\n switch (status) {\n case 0x00:\n return standby;\n case 0x02:\n return normal;\n case 0x03:\n return fault;\n case 0x04:\n return permanent;\n default:\n return 0x${0${(status.toString(16))}.slice(-2)};\n }\n}\n",
      "outputs": 1,
      "noerr": 0,
      "initialize": "",
      "finalize": "",
      "libs": [],
      "x": 450,
      "y": 260,
      "wires": [
      []
      ],
      "inputLabels": [
      "wifi stick buffer in"
      ],
      "outputLabels": [
      "decoded message object"
      ]
      },
      {
      "id": "28fb73099b82097a",
      "type": "change",
      "z": "16c33b1e099682e0",
      "name": "set host and port",
      "rules": [
      {
      "t": "set",
      "p": "host",
      "pt": "msg",
      "to": "remoteHostIp",
      "tot": "env"
      },
      {
      "t": "set",
      "p": "port",
      "pt": "msg",
      "to": "remoteHostPort",
      "tot": "env"
      },
      {
      "t": "set",
      "p": "topic",
      "pt": "msg",
      "to": "remote_server",
      "tot": "str"
      }
      ],
      "action": "",
      "property": "",
      "from": "",
      "to": "",
      "reg": false,
      "x": 610,
      "y": 160,
      "wires": [
      [
      "164f421ec73701f9"
      ]
      ]
      },
      {
      "id": "88b9df11c34f72ea",
      "type": "switch",
      "z": "16c33b1e099682e0",
      "name": "",
      "property": "resend",
      "propertyType": "env",
      "rules": [
      {
      "t": "istype",
      "v": "boolean",
      "vt": "boolean"
      },
      {
      "t": "true"
      }
      ],
      "checkall": "true",
      "repair": false,
      "outputs": 2,
      "x": 430,
      "y": 120,
      "wires": [
      [
      "c511e8c8f7ced576"
      ],
      [
      "28fb73099b82097a"
      ]
      ],
      "inputLabels": [
      "inverter data"
      ],
      "outputLabels": [
      "local server only",
      "remote server"
      ]
      },
      {
      "id": "7113cbe45845bb03",
      "type": "status",
      "z": "16c33b1e099682e0",
      "name": "",
      "scope": [],
      "x": 120,
      "y": 40,
      "wires": [
      []
      ]
      },
      {
      "id": "a92085a4d10f12e6",
      "type": "function",
      "z": "16c33b1e099682e0",
      "name": "add msg.frameType",
      "func": "let frameType = '';\nswitch (msg.payload.length) {\n case 99:\n frameType = 'hello(99)';\n break;\n case 23:\n frameType = 'srv_res(23)';\n break;\n case 164: // KTL-X\n case 208: // HYD6000ES\n case 232: // ME3000SP\n case 547: // BMI-600 & SUN600G3-EU-230\n frameType = data(${msg.payload.length});\n break;\n case 14:\n frameType = 'heartbeat(14)';\n break;\n case 41:\n frameType = 'hello_cd(41)';\n break;\n case 73:\n frameType = 'hello_end(73)';\n break;\n default:\n frameType = unknown(${msg.payload.length});\n break;\n}\nmsg.frameType = frameType;\n// delete TCP nodes properties\ndelete msg.ip;\ndelete msg.host;\ndelete msg.port;\ndelete msg._session;\n\nreturn msg;",
      "outputs": 1,
      "noerr": 0,
      "initialize": "",
      "finalize": "",
      "libs": [],
      "x": 960,
      "y": 260,
      "wires": [
      []
      ]
      },
      {
      "id": "f5a0b9593db8e99f",
      "type": "file in",
      "z": "16c33b1e099682e0",
      "name": "",
      "filename": "/opt/iobroker/test.bin",
      "filenameType": "str",
      "format": "stream",
      "chunk": false,
      "sendError": false,
      "encoding": "none",
      "allProps": false,
      "x": 340,
      "y": 360,
      "wires": [
      []
      ]
      },
      {
      "id": "d8a0e2dceb7262ee",
      "type": "inject",
      "z": "16c33b1e099682e0",
      "name": "",
      "props": [
      {
      "p": "payload"
      },
      {
      "p": "topic",
      "vt": "str"
      }
      ],
      "repeat": "10",
      "crontab": "",
      "once": false,
      "onceDelay": 0.1,
      "topic": "",
      "payload": "",
      "payloadType": "date",
      "x": 120,
      "y": 360,
      "wires": [
      []
      ]
      },
      {
      "id": "a3d422ba2bba844c",
      "type": "comment",
      "z": "16c33b1e099682e0",
      "name": "Hinweise zum solar Node",
      "info": "https://github.com/serek4/node-red-sofar-inverter\nhttp://192.168.99.90/config_hide.html\nhttp://192.168.99.91/config_hide.html\nhttp://192.168.99.92/config_hide.html\nhttps://github.com/0xb1ff/solarman-dissector\nresent disabled in Eigenschaften",
      "x": 170,
      "y": 240,
      "wires": []
      },
      {
      "id": "63d79ea54fec0a3b",
      "type": "subflow:16c33b1e099682e0",
      "z": "c6d3f0d.558371",
      "name": "Solar inverter",
      "x": 130,
      "y": 500,
      "wires": [
      [
      "f301baaf83223c8e"
      ],
      [
      "378a1d9b2360b7a0"
      ]
      ]
      },
      {
      "id": "f301baaf83223c8e",
      "type": "json",
      "z": "c6d3f0d.558371",
      "name": "",
      "property": "payload",
      "action": "",
      "pretty": false,
      "x": 330,
      "y": 500,
      "wires": [
      [
      "df544262fde22aca"
      ]
      ]
      },
      {
      "id": "255e0e6a6050f427",
      "type": "comment",
      "z": "c6d3f0d.558371",
      "name": "Hinweise zum solar Node",
      "info": "https://github.com/serek4/node-red-sofar-inverter\nhttp://192.168.99.90/config_hide.html\nhttp://192.168.99.91/config_hide.html\nhttp://192.168.99.92/config_hide.html\nhttps://github.com/0xb1ff/solarman-dissector",
      "x": 130,
      "y": 560,
      "wires": []
      },
      {
      "id": "df544262fde22aca",
      "type": "subflow:6e802f1553b18149",
      "z": "c6d3f0d.558371",
      "name": "",
      "env": [
      {
      "name": "keepTopic",
      "value": "true",
      "type": "bool"
      }
      ],
      "x": 570,
      "y": 500,
      "wires": [
      [
      "5b2b626a187f8453"
      ]
      ]
      },
      {
      "id": "5b2b626a187f8453",
      "type": "ioBroker out",
      "z": "c6d3f0d.558371",
      "name": "",
      "topic": "",
      "ack": "true",
      "autoCreate": "true",
      "stateName": "",
      "role": "",
      "payloadType": "",
      "readonly": "",
      "stateUnit": "",
      "stateMin": "",
      "stateMax": "",
      "x": 820,
      "y": 500,
      "wires": []
      },
      {
      "id": "378a1d9b2360b7a0",
      "type": "debug",
      "z": "c6d3f0d.558371",
      "name": "debug 1",
      "active": true,
      "tosidebar": true,
      "console": false,
      "tostatus": false,
      "complete": "false",
      "statusVal": "",
      "statusType": "auto",
      "x": 340,
      "y": 560,
      "wires": []
      }
      ]

      posted in Entwicklung
      P
      painless
    • RE: Bosswerk MI600 Adapter

      @rene55
      Diese Pakete kommen schon mal vom Bosswerk, da alle Pakete im Data 5 Protokoll mit 165 beginnen. Messages mit einer Länge von 143 sind mir allerdings unbekannt.
      Mindest die Heartbeat-Msg mit der Länge von 14 sollte alle 5 Minuten ankommen.

      Hast Du im config_hide Menü Server A auf deinen node-red umgebogen ? Beim optionalen Server kommt zumindestens bei mir nix an.

      Ist der tcp Input-node im Ausgang auf "Strom von" "Buffer" gestellt ?

      Nimm meinen Flow, da sparst Du ne Menge Zeit und kannst bei der weiteren Decodierung helfen. Im Flow selbst kannst Du das forwarding der Nachrichten zum Solarman Server ein/ausschalten. Damit funktioniert dann auch noch die Solarman App.

      posted in Entwicklung
      P
      painless
    • RE: Bosswerk MI600 Adapter

      @rene55

      Gerne. Voraussetzung - node red adapter.

      Du musst in den Node-Red Einstellungen "Erstellung von Fremdobjekten zulassen" aktivieren, damit die Datenpunkte erstellt werden.

      Alle bosswerk relevanten pv Daten sind in der 547-msg length drin. Screen mal die 60ér und 73ér msg. Da wird Deine ip und Wifi Adresse übertragen...


      [
      {
      "id": "6e802f1553b18149",
      "type": "subflow",
      "name": "JSON or Obj to IOBroker",
      "info": "# Creates an IOBroker tree\n\nThis node creates an IOBroker tree out of an Java-Object or JSON String.\n\nThe object tree will be created under 0_userdata.0\nIn addition to the JSON-String or Java Object as msg.payload it is necessary to specify a msg.top properity in addition to the msg-Object.\n\nThe object tree will be created under 0_userdata.0\n\nExisting msg.topic entries will be deleted.\nAn iobroker-out node has to be appended to this subflow node. It is not part of the subflow itself. No topic should be specified in the iobroker out node.\n\nIs msg.top property isn't defined, the top property of the subflow-node is used. \n\nIn the properties of the subflow node a new property keepTopic has been added. Default is false to keep the current behaviour. If set to true then the originial topic will be placed between the top property of the subflow node and the property of the analyzed JSON object.\n\nAttention:\nIf msg.top and top is empty, all msg.topics (msg.topic) will be directly prefixed with 0_userdata.0. . \n\nUpdate 13.09.2022:\nSpaces in topics of objects are no longer replaced with underscores in objects. No differences between all data types.\n\n# Erstellt einen Objektbaum im ioBroker\n\nDiese Node erstellt einen Objektbaum im ioBroker aus einem JAVA Objekt bzw. einem JSON String. \n\nDer Baum wird in jedem Fall unter 0_userdata.0 erstellt und zwar unter dem Topic der in msg.top mitgegeben wurde. In der msg.payload befindet sich dann der JSON String oder das entsprechende Objekt.\n\nExistierende msg.topic Einträge werden gelöscht.\nEin entsprechende iobroker-out Node muss an den Flow angehängt werden. Sie ist nicht Bestandteil des Subflows. In dieser iobroker-out Node darf kein Topic angegeben werden. \n\nFalls msg.top nicht definiert wurde, wird der top-Wert der Subflow-Node verwendet.\n\nIn den Eigenschaften der Subflow-Node wurde ein neuer Parameter keepTopic hinzugefügt. Standardwert ist false, um das bisherige Verhalten beizubehalten. Setzt man die Eigenschaft auf true, dann wird das originale Topic zwischen der top Eigenschaft der Subflow-Node und Eigenschaft des analysierten JSON Objektes eingefügt.\n\nAchtung:\nWenn top und msg.top leer ist, werden alle msg.topics (msg.topic) direkt unter dem Präfix 0_userdata.0., angelegt bzw. ausgegeben. \n\nUpdate 13.09.2022:\nLeerzeichen werden in Topics von Objekten nicht mehr durch Unterstriche ersetzt. Es gibt keine Unterschiede mehr zwischen den Datentypen.",
      "category": "",
      "in": [
      {
      "x": 60,
      "y": 160,
      "wires": [
      {
      "id": "554b8c663bcb46c2"
      }
      ]
      }
      ],
      "out": [
      {
      "x": 2620,
      "y": 280,
      "wires": [
      {
      "id": "0962842ebd23e0d7",
      "port": 0
      }
      ]
      }
      ],
      "env": [
      {
      "name": "top",
      "type": "str",
      "value": "objRoot"
      },
      {
      "name": "keepTopic",
      "type": "bool",
      "value": "false"
      }
      ],
      "meta": {},
      "color": "#E2D96E",
      "icon": "node-red/batch.svg"
      },
      {
      "id": "3e11e8338f694832",
      "type": "split",
      "z": "6e802f1553b18149",
      "name": "split object",
      "splt": "\n",
      "spltType": "str",
      "arraySplt": 1,
      "arraySpltType": "len",
      "stream": false,
      "addname": "key",
      "x": 1370,
      "y": 160,
      "wires": [
      [
      "0562a4249c8b856b"
      ]
      ]
      },
      {
      "id": "0562a4249c8b856b",
      "type": "change",
      "z": "6e802f1553b18149",
      "name": "add key to topic",
      "rules": [
      {
      "t": "set",
      "p": "stateName",
      "pt": "msg",
      "to": "key",
      "tot": "msg"
      },
      {
      "t": "set",
      "p": "topic",
      "pt": "msg",
      "to": "topic & '.' & key",
      "tot": "jsonata"
      }
      ],
      "action": "",
      "property": "",
      "from": "",
      "to": "",
      "reg": false,
      "x": 1560,
      "y": 160,
      "wires": [
      [
      "ddc90985bef0fafa"
      ]
      ]
      },
      {
      "id": "ddc90985bef0fafa",
      "type": "switch",
      "z": "6e802f1553b18149",
      "name": "is type?",
      "property": "payload",
      "propertyType": "msg",
      "rules": [
      {
      "t": "istype",
      "v": "array",
      "vt": "array"
      },
      {
      "t": "istype",
      "v": "object",
      "vt": "object"
      },
      {
      "t": "else"
      }
      ],
      "checkall": "true",
      "repair": false,
      "outputs": 3,
      "x": 1740,
      "y": 160,
      "wires": [
      [
      "bfce19b206660fbe"
      ],
      [
      "3e11e8338f694832"
      ],
      [
      "1a8c03d866b85b12"
      ]
      ]
      },
      {
      "id": "bfce19b206660fbe",
      "type": "split",
      "z": "6e802f1553b18149",
      "name": "split array",
      "splt": "\n",
      "spltType": "str",
      "arraySplt": 1,
      "arraySpltType": "len",
      "stream": false,
      "addname": "",
      "x": 780,
      "y": 280,
      "wires": [
      [
      "e89927810c6d75ec"
      ]
      ]
      },
      {
      "id": "e89927810c6d75ec",
      "type": "change",
      "z": "6e802f1553b18149",
      "name": "add index to topic",
      "rules": [
      {
      "t": "set",
      "p": "topic",
      "pt": "msg",
      "to": "topic & '.' & parts.index",
      "tot": "jsonata"
      }
      ],
      "action": "",
      "property": "",
      "from": "",
      "to": "",
      "reg": false,
      "x": 970,
      "y": 280,
      "wires": [
      [
      "a4d1a5d04564dc77"
      ]
      ]
      },
      {
      "id": "f5d52c6a57d08904",
      "type": "change",
      "z": "6e802f1553b18149",
      "name": "finalize msg.topic",
      "rules": [
      {
      "t": "set",
      "p": "top",
      "pt": "msg",
      "to": "'0_userdata.0.' & top",
      "tot": "jsonata"
      },
      {
      "t": "set",
      "p": "topic",
      "pt": "msg",
      "to": "top & '.' & topic",
      "tot": "jsonata"
      }
      ],
      "action": "",
      "property": "",
      "from": "",
      "to": "",
      "reg": false,
      "x": 2170,
      "y": 240,
      "wires": [
      [
      "0962842ebd23e0d7"
      ]
      ]
      },
      {
      "id": "c863dd7d651b2272",
      "type": "switch",
      "z": "6e802f1553b18149",
      "name": "is type?",
      "property": "payload",
      "propertyType": "msg",
      "rules": [
      {
      "t": "istype",
      "v": "json",
      "vt": "json"
      },
      {
      "t": "istype",
      "v": "object",
      "vt": "object"
      },
      {
      "t": "istype",
      "v": "array",
      "vt": "array"
      },
      {
      "t": "else"
      }
      ],
      "checkall": "true",
      "repair": false,
      "outputs": 4,
      "x": 580,
      "y": 160,
      "wires": [
      [
      "158930afddd0780b"
      ],
      [
      "3e11e8338f694832"
      ],
      [
      "bfce19b206660fbe"
      ],
      [
      "a4d1a5d04564dc77"
      ]
      ]
      },
      {
      "id": "158930afddd0780b",
      "type": "json",
      "z": "6e802f1553b18149",
      "name": "",
      "property": "payload",
      "action": "",
      "pretty": false,
      "x": 770,
      "y": 120,
      "wires": [
      [
      "3649300b4c233b10"
      ]
      ]
      },
      {
      "id": "1a8c03d866b85b12",
      "type": "switch",
      "z": "6e802f1553b18149",
      "name": "is msg.top != null",
      "property": "top",
      "propertyType": "msg",
      "rules": [
      {
      "t": "nnull"
      },
      {
      "t": "null"
      }
      ],
      "checkall": "true",
      "repair": false,
      "outputs": 2,
      "x": 1950,
      "y": 280,
      "wires": [
      [
      "f5d52c6a57d08904"
      ],
      [
      "74c895ce724750de"
      ]
      ]
      },
      {
      "id": "e023fe88445ce43e",
      "type": "change",
      "z": "6e802f1553b18149",
      "name": "",
      "rules": [
      {
      "t": "delete",
      "p": "topic",
      "pt": "msg"
      }
      ],
      "action": "",
      "property": "",
      "from": "",
      "to": "",
      "reg": false,
      "x": 350,
      "y": 200,
      "wires": [
      [
      "c863dd7d651b2272"
      ]
      ]
      },
      {
      "id": "3649300b4c233b10",
      "type": "switch",
      "z": "6e802f1553b18149",
      "name": "is array?",
      "property": "payload",
      "propertyType": "msg",
      "rules": [
      {
      "t": "istype",
      "v": "array",
      "vt": "array"
      },
      {
      "t": "else"
      }
      ],
      "checkall": "true",
      "repair": false,
      "outputs": 2,
      "x": 900,
      "y": 120,
      "wires": [
      [
      "bfce19b206660fbe"
      ],
      [
      "3e11e8338f694832"
      ]
      ]
      },
      {
      "id": "1b8480cd2df7ba3f",
      "type": "comment",
      "z": "6e802f1553b18149",
      "name": "Array",
      "info": "",
      "x": 600,
      "y": 280,
      "wires": []
      },
      {
      "id": "b3541807672be040",
      "type": "comment",
      "z": "6e802f1553b18149",
      "name": "object",
      "info": "",
      "x": 1340,
      "y": 100,
      "wires": []
      },
      {
      "id": "a4d1a5d04564dc77",
      "type": "switch",
      "z": "6e802f1553b18149",
      "name": "is type?",
      "property": "payload",
      "propertyType": "msg",
      "rules": [
      {
      "t": "istype",
      "v": "object",
      "vt": "object"
      },
      {
      "t": "istype",
      "v": "array",
      "vt": "array"
      },
      {
      "t": "else"
      }
      ],
      "checkall": "true",
      "repair": false,
      "outputs": 3,
      "x": 1160,
      "y": 280,
      "wires": [
      [
      "3e11e8338f694832"
      ],
      [
      "bfce19b206660fbe"
      ],
      [
      "1a8c03d866b85b12"
      ]
      ]
      },
      {
      "id": "74c895ce724750de",
      "type": "change",
      "z": "6e802f1553b18149",
      "name": "finalize msg.topic",
      "rules": [
      {
      "t": "set",
      "p": "top",
      "pt": "msg",
      "to": "top",
      "tot": "env"
      },
      {
      "t": "set",
      "p": "top",
      "pt": "msg",
      "to": "'0_userdata.0.' & top",
      "tot": "jsonata"
      },
      {
      "t": "set",
      "p": "topic",
      "pt": "msg",
      "to": "top & '.' & topic",
      "tot": "jsonata"
      }
      ],
      "action": "",
      "property": "",
      "from": "",
      "to": "",
      "reg": false,
      "x": 2170,
      "y": 320,
      "wires": [
      [
      "0962842ebd23e0d7"
      ]
      ]
      },
      {
      "id": "554b8c663bcb46c2",
      "type": "switch",
      "z": "6e802f1553b18149",
      "name": "",
      "property": "keepTopic",
      "propertyType": "env",
      "rules": [
      {
      "t": "true"
      },
      {
      "t": "false"
      }
      ],
      "checkall": "true",
      "repair": false,
      "outputs": 2,
      "x": 170,
      "y": 160,
      "wires": [
      [
      "e30ba9f0483285e4"
      ],
      [
      "e023fe88445ce43e"
      ]
      ]
      },
      {
      "id": "e30ba9f0483285e4",
      "type": "change",
      "z": "6e802f1553b18149",
      "name": "",
      "rules": [
      {
      "t": "change",
      "p": "topic",
      "pt": "msg",
      "from": "/",
      "fromt": "str",
      "to": ".",
      "tot": "str"
      }
      ],
      "action": "",
      "property": "",
      "from": "",
      "to": "",
      "reg": false,
      "x": 350,
      "y": 120,
      "wires": [
      [
      "c863dd7d651b2272"
      ]
      ]
      },
      {
      "id": "0962842ebd23e0d7",
      "type": "change",
      "z": "6e802f1553b18149",
      "name": "translate invalid chars in topic",
      "rules": [
      {
      "t": "change",
      "p": "topic",
      "pt": "msg",
      "from": "..",
      "fromt": "str",
      "to": ".",
      "tot": "str"
      },
      {
      "t": "change",
      "p": "topic",
      "pt": "msg",
      "from": "€",
      "fromt": "str",
      "to": "EUR",
      "tot": "str"
      }
      ],
      "action": "",
      "property": "",
      "from": "",
      "to": "",
      "reg": false,
      "x": 2430,
      "y": 280,
      "wires": [
      []
      ]
      },
      {
      "id": "16c33b1e099682e0",
      "type": "subflow",
      "name": "solar inverter",
      "info": "TCP server for LSW3 wifi logger \r\nused with Sofar inverters\r\n\r\n## Supported inverters\r\n\r\nSofar KTL-X \r\nSofar ME3000SP \r\nSofar HYD6000-ES \r\n\r\n### Outputs\r\n1. JSON data\r\n: payload (object) : parsed data object.\r\n: topic (string) : frame data type.\r\n\r\n2. debug\r\n: payload (buffer) : raw data from inverter.\r\n: topic (string) : message origin.\r\n: frameType (string) : frame data type.\r\n\r\n### Details\r\n\r\nDefault local server port: \r\n10000\r\n\r\nDefault host IP: \r\n47.88.8.200 (data1.solarmanpv.com) \r\nor \r\n115.29.186.234 (data2.solarmanpv.com) \r\n\r\nDefault port nr: \r\n10000\r\n\r\n### References\r\n\r\n - GitHub - the node github repository\r\n",
      "category": "",
      "in": [],
      "out": [
      {
      "x": 630,
      "y": 260,
      "wires": [
      {
      "id": "5d0553bafc1e3bf7",
      "port": 0
      }
      ]
      },
      {
      "x": 1150,
      "y": 260,
      "wires": [
      {
      "id": "a92085a4d10f12e6",
      "port": 0
      }
      ]
      }
      ],
      "env": [
      {
      "name": "localPort",
      "type": "num",
      "value": "10000",
      "ui": {
      "icon": "font-awesome/fa-plug",
      "label": {
      "en-US": "local port"
      },
      "type": "input",
      "opts": {
      "types": [
      "num",
      "env"
      ]
      }
      }
      },
      {
      "name": "resend",
      "type": "bool",
      "value": "false",
      "ui": {
      "label": {
      "en-US": "forward data to remote server"
      },
      "type": "checkbox"
      }
      },
      {
      "name": "remoteHostIp",
      "type": "str",
      "value": "47.102.152.71",
      "ui": {
      "icon": "font-awesome/fa-cloud-upload",
      "label": {
      "en-US": "remote ip"
      },
      "type": "input",
      "opts": {
      "types": [
      "str",
      "env"
      ]
      }
      }
      },
      {
      "name": "remoteHostPort",
      "type": "num",
      "value": "10000",
      "ui": {
      "icon": "font-awesome/fa-plug",
      "label": {
      "en-US": "remote port"
      },
      "type": "input",
      "opts": {
      "types": [
      "num",
      "env"
      ]
      }
      }
      }
      ],
      "meta": {
      "version": "1.2.0",
      "author": "serek4",
      "desc": "sofar inverter with LSW3 wifi logger",
      "license": "MIT"
      },
      "color": "#20c800",
      "outputLabels": [
      "JSON data",
      "debug"
      ],
      "icon": "node-red/bridge-dash.svg"
      },
      {
      "id": "f0ad23cb42522771",
      "type": "tcp in",
      "z": "16c33b1e099682e0",
      "name": "Inverter stick out",
      "server": "server",
      "host": "",
      "port": "${localPort}",
      "datamode": "stream",
      "datatype": "buffer",
      "newline": "",
      "topic": "inverter",
      "trim": false,
      "base64": false,
      "tls": "",
      "x": 140,
      "y": 120,
      "wires": [
      [
      "88b9df11c34f72ea",
      "a92085a4d10f12e6",
      "5d0553bafc1e3bf7",
      "cd050871c5e7245c"
      ]
      ]
      },
      {
      "id": "164f421ec73701f9",
      "type": "tcp request",
      "z": "16c33b1e099682e0",
      "name": "Solarmanpv.com",
      "server": "",
      "port": "",
      "out": "time",
      "ret": "buffer",
      "splitc": "1000",
      "newline": "",
      "trim": false,
      "tls": "",
      "x": 810,
      "y": 160,
      "wires": [
      [
      "a92085a4d10f12e6"
      ]
      ]
      },
      {
      "id": "c511e8c8f7ced576",
      "type": "function",
      "z": "16c33b1e099682e0",
      "name": "generate response",
      "func": "const request = msg.payload;\n\nconst timestamp = Math.floor(Date.now() / 1000);\nconst timestampStr = timestamp.toString(16);\nconst timestampBuff = Buffer.from(timestamp.toString(16), 'hex');\n\nconst response = Buffer.alloc(23);\nresponse.writeUInt8(0xA5, 0x00); // msg begin\n\nresponse.writeUInt8(0x0A, 0x01); // msg length\nresponse.writeUInt8(0x00, 0x02);\n\nresponse.writeUInt8(0x10, 0x03);\nresponse.writeUInt8(responseType(request.readUInt8(0x04)), 0x04); // match req type\n\nresponse.writeUInt8(request.readUInt8(0x05) >= 0xFF ? 0x00 : request.readUInt8(0x05) + 0x01, 0x05); // get from req + 1\nresponse.writeUInt8(request.readUInt8(0x06), 0x06); // get from req\n\nresponse.writeUInt32LE(request.readUInt32LE(0x07), 0x07); // wifi SN - get from req\n\nresponse.writeUInt8(request.readUInt8(0x0B), 0x0B); // get from req\nresponse.writeUInt8(0x01, 0x0C);\n\nresponse.writeUInt32LE(timestampBuff.readUInt32BE(0x00), 0x0D); // timestamp\n\nresponse.writeUInt8(0x78, 0x11);\nresponse.writeUInt8(0x00, 0x12);\nresponse.writeUInt8(0x00, 0x13);\nresponse.writeUInt8(0x00, 0x14);\n\nresponse.writeUInt8(calculateChecksum(response), 0x15); //checksum\nresponse.writeUInt8(0x15, 0x16); // msg end\n\nmsg.payload = response;\nmsg.topic = 'local_server';\nreturn msg;\n\nfunction responseType(requestTypeByte) {\n // node.warn(req code: 0x${requestTypeByte.toString(16)});\n let responseTypeByte = requestTypeByte - (0x30);\n responseTypeByte = Math.min(Math.max(responseTypeByte, 0x00), 0xFF); //min 0x00 max 255\n // switch(requestTypeByte) {\n // case 0x41:\n // responseTypeByte = 0x11;\n // break;\n // case 0x42:\n // responseTypeByte = 0x12;\n // break;\n // case 0x43:\n // responseTypeByte = 0x13;\n // break;\n // case 0x47:\n // responseTypeByte = 0x17;\n // break;\n // case 0x48:\n // responseTypeByte = 0x18;\n // break;\n // default:\n // responseTypeByte = 0xFF;\n // }\n // node.warn(res code: 0x${responseTypeByte.toString(16)});\n return responseTypeByte;\n}\nfunction calculateChecksum(message) {\n message = message.slice(1, -2);\n let sum = 0x0;\n for (const key of message.keys()) {\n sum += message[key];\n }\n sum = sum % 256;\n // node.warn( sum.toString(16));\n return sum;\n}",
      "outputs": 1,
      "noerr": 0,
      "initialize": "",
      "finalize": "",
      "libs": [],
      "x": 810,
      "y": 120,
      "wires": [
      [
      "95b6eef2f2bbf823",
      "a92085a4d10f12e6"
      ]
      ],
      "inputLabels": [
      "data from wifi stick"
      ],
      "outputLabels": [
      "response out"
      ]
      },
      {
      "id": "95b6eef2f2bbf823",
      "type": "tcp out",
      "z": "16c33b1e099682e0",
      "name": "Inverter stick response in",
      "host": "",
      "port": "10000",
      "beserver": "reply",
      "base64": false,
      "end": true,
      "tls": "",
      "x": 1090,
      "y": 120,
      "wires": []
      },
      {
      "id": "5d0553bafc1e3bf7",
      "type": "function",
      "z": "16c33b1e099682e0",
      "name": "decode msg",
      "func": "let buffer = msg.payload;\nlet data = {};\nswitch (buffer.length) {\n case 547: // data - BMI-600 & SUN600G3-EU-230\n data.loggerSN = buffer.readUInt32LE(0x07);\n\n data.inverterSN = (buffer.toString('utf8', 0x20, 0x29)).trimEnd();\n \n data.dailyGenerationkWh = buffer.readUInt32LE(0x2C) / 100;\n data.generationTotalkWh = buffer.readUInt32LE(0x30) / 10;\n\n data.powerGridVoltageV = buffer.readUInt16LE(0x38) / 10;\n data.powerGridCurrentA = buffer.readUInt16LE(0x3E) / 10;\n\n data.ACFrequencyHz = buffer.readUInt16LE(0x44) / 100;\n data.ACOutputTotalPowerW = buffer.readUInt16LE(0x46);\n data.tempHeatSink = buffer.readInt16LE(0x4A) / 100;\n \n\n data.DCPV1VoltageV = buffer.readUInt16LE(0x60) / 10;\n data.DCPV1CurrentA = buffer.readUInt16LE(0x62) / 10;\n data.DCPV2VoltageV = buffer.readUInt16LE(0x64) / 10;\n data.DCPV2CurrentA = buffer.readUInt16LE(0x66) / 10;\n \n data.ComProtVer = (buffer.toString('utf8', 0x70, 0x77)).trimEnd();\n data.ContrBoardVer = (buffer.toString('utf8', 0x78, 0x7F)).trimEnd();\n data.ComBoardVer = (buffer.toString('utf8', 0x80, 0x87)).trimEnd();\n\n data.RatedPowerW = buffer.readUInt16BE(0x8C) / 10;\n \n data.Modul1SN = (buffer.toString('utf8', 0xAA, 0xB9)).trimEnd();\n data.Modul2SN = (buffer.toString('utf8', 0xBA, 0xC9)).trimEnd();\n data.Modul3SN = (buffer.toString('utf8', 0xCA, 0xD9)).trimEnd();\n data.Modul4SN = (buffer.toString('utf8', 0xDA, 0xE9)).trimEnd();\n \n data.overfreqHz = buffer.readUInt16BE(0xEA) / 100;\n data.overfreqPerc = buffer.readUInt16BE(0xEC);\n data.gridVoltageUpLim = buffer.readUInt16BE(0xF6) / 10 ;\n data.gridVoltageLowLim = buffer.readUInt16BE(0xF8) / 10;\n data.gridFreqUpLim = buffer.readUInt16BE(0xFA) / 100;\n data.gridFreqLowLim = buffer.readUInt16BE(0xFC) / 100;\n data.selfcheckTimeSec = buffer.readUInt16BE(0xFE);\n \n data.year = buffer.readUInt8(0x100);\n data.month = buffer.readUInt8(0x101);\n data.day = buffer.readUInt8(0x102);\n data.hour = buffer.readUInt8(0x103);\n data.minute = buffer.readUInt8(0x104);\n data.second = buffer.readUInt8(0x105); \n \n /*\n data.DCPV2PowerW = buffer.readUInt16LE(0x68) * 10;\n data.ACPVoltageV = buffer.readUInt16LE(0x3C) / 10;\n data.ACCurrentA = buffer.readUInt16LE(0x3E) / 100;\n data.ACFrequencyHz = buffer.readUInt16LE(0x40) / 100;\n data.battPowerW = buffer.readInt16LE(0x42) * 10;\n data.battVoltageV = buffer.readUInt16LE(0x44) / 10;\n data.battCurrentA = buffer.readInt16LE(0x46) / 100;\n data.battSoCPct = buffer.readUInt16LE(0x48);\n data.battTempC = buffer.readUInt16LE(0x4A);\n data.consumptionTotalW = buffer.readUInt16LE(0x4E) * 10;\n data.ACOutputTotalPowerW = buffer.readUInt16LE(0x52);\n data.emergencyOutputVoltageV = buffer.readUInt16LE(0x54) / 10;\n data.emergencyOutputPowerW = buffer.readUInt16LE(0x56) * 10;\n data.dailyGenerationkWh = buffer.readUInt16LE(0x58) / 100;\n data.dailyOnGridEnergykWh = buffer.readUInt16LE(0x5A) / 100;\n data.dailyEnergyPurchasedkWh = buffer.readUInt16LE(0x5C) / 100;\n data.dailyEnergyUsedkWh = buffer.readUInt16LE(0x5E) / 100;\n data.generationTotalkWh = buffer.readUInt32LE(0x60);\n data.totalOnGridGenerationkWh = buffer.readUInt32LE(0x64);\n data.totalEnergyPurchasedkWh = buffer.readUInt32LE(0x68);\n data.totalEnergyConsumptionkWh = buffer.readUInt32LE(0x6C);\n data.battDailyEnergyDischargedkWh = buffer.readUInt16LE(0x70) / 100;\n data.battDailyEnergyChargedkWh = buffer.readUInt16LE(0x72) / 100;\n data.battTotalEnergyChargedkWh = buffer.readUInt32LE(0x74);\n data.battTotalEnergyDischargedkWh = buffer.readUInt32LE(0x78);\n data.battTotalChargingDischargingTimesNum = buffer.readUInt16LE(0x80);\n data.busVoltageV = buffer.readUInt16LE(0x82) / 10;\n data.LLCbusVoltageV = buffer.readUInt16LE(0x84) / 10;\n data.buckCurrentA = buffer.readUInt16LE(0x86) / 100;\n data.powerGridVoltageV = buffer.readUInt16LE(0x88) / 10;\n data.powerGridCurrentA = buffer.readUInt16LE(0x8A) / 100;\n data.inverterTempC = buffer.readUInt16LE(0x8E);\n data.radiatorTempC = buffer.readUInt16LE(0x90);\n data.currentDCComponentA = buffer.readInt16LE(0x94);\n data.voltageDCComponentV = buffer.readInt16LE(0x96);\n data.dailyGeneratingHours = buffer.readUInt8(0xA4);\n data.totalGeneratingHours = buffer.readUInt32LE(0xA6);\n data.insulationImpedanceToTheGround = buffer.readUInt16LE(0xAA);\n data.insulationImpedancePVToGround = buffer.readUInt16LE(0xAC);\n data.insulationImpedanceCathodeToGround = buffer.readUInt16LE(0xAE);\n \n data.year = buffer.readUInt8(0xC8);\n data.month = buffer.readUInt8(0xC9);\n data.day = buffer.readUInt8(0xCA);\n data.hour = buffer.readUInt8(0xCB);\n data.minute = buffer.readUInt8(0xCC);\n data.second = buffer.readUInt8(0xCD);\n */\n return {\n payload: data,\n topic: "Solar " + data.loggerSN\n };\n break;\n case 208: // data - HYD6000ES\n data.loggerSN = buffer.readUInt32LE(0x07);\n data.inverterSN = (buffer.toString('utf8', 0x20, 0x30)).trimEnd();\n data.DCPV1VoltageV = buffer.readUInt16LE(0x30) / 10;\n data.DCPV1CurrentA = buffer.readUInt16LE(0x32) / 100;\n data.DCPV1PowerW = buffer.readUInt16LE(0x34) * 10;\n data.DCPV2VoltageV = buffer.readUInt16LE(0x36) / 10;\n data.DCPV2CurrentA = buffer.readUInt16LE(0x38) / 100;\n data.DCPV2PowerW = buffer.readUInt16LE(0x3A) * 10;\n data.ACPVoltageV = buffer.readUInt16LE(0x3C) / 10;\n data.ACCurrentA = buffer.readUInt16LE(0x3E) / 100;\n data.ACFrequencyHz = buffer.readUInt16LE(0x40) / 100;\n data.battPowerW = buffer.readInt16LE(0x42) * 10;\n data.battVoltageV = buffer.readUInt16LE(0x44) / 10;\n data.battCurrentA = buffer.readInt16LE(0x46) / 100;\n data.battSoCPct = buffer.readUInt16LE(0x48);\n data.battTempC = buffer.readUInt16LE(0x4A);\n data.consumptionTotalW = buffer.readUInt16LE(0x4E) * 10;\n data.ACOutputTotalPowerW = buffer.readUInt16LE(0x52);\n data.emergencyOutputVoltageV = buffer.readUInt16LE(0x54) / 10;\n data.emergencyOutputPowerW = buffer.readUInt16LE(0x56) * 10;\n data.dailyGenerationkWh = buffer.readUInt16LE(0x58) / 100;\n data.dailyOnGridEnergykWh = buffer.readUInt16LE(0x5A) / 100;\n data.dailyEnergyPurchasedkWh = buffer.readUInt16LE(0x5C) / 100;\n data.dailyEnergyUsedkWh = buffer.readUInt16LE(0x5E) / 100;\n data.generationTotalkWh = buffer.readUInt32LE(0x60);\n data.totalOnGridGenerationkWh = buffer.readUInt32LE(0x64);\n data.totalEnergyPurchasedkWh = buffer.readUInt32LE(0x68);\n data.totalEnergyConsumptionkWh = buffer.readUInt32LE(0x6C);\n data.battDailyEnergyDischargedkWh = buffer.readUInt16LE(0x70) / 100;\n data.battDailyEnergyChargedkWh = buffer.readUInt16LE(0x72) / 100;\n data.battTotalEnergyChargedkWh = buffer.readUInt32LE(0x74);\n data.battTotalEnergyDischargedkWh = buffer.readUInt32LE(0x78);\n data.battTotalChargingDischargingTimesNum = buffer.readUInt16LE(0x80);\n data.busVoltageV = buffer.readUInt16LE(0x82) / 10;\n data.LLCbusVoltageV = buffer.readUInt16LE(0x84) / 10;\n data.buckCurrentA = buffer.readUInt16LE(0x86) / 100;\n data.powerGridVoltageV = buffer.readUInt16LE(0x88) / 10;\n data.powerGridCurrentA = buffer.readUInt16LE(0x8A) / 100;\n data.inverterTempC = buffer.readUInt16LE(0x8E);\n data.radiatorTempC = buffer.readUInt16LE(0x90);\n data.currentDCComponentA = buffer.readInt16LE(0x94);\n data.voltageDCComponentV = buffer.readInt16LE(0x96);\n data.dailyGeneratingHours = buffer.readUInt8(0xA4);\n data.totalGeneratingHours = buffer.readUInt32LE(0xA6);\n data.insulationImpedanceToTheGround = buffer.readUInt16LE(0xAA);\n data.insulationImpedancePVToGround = buffer.readUInt16LE(0xAC);\n data.insulationImpedanceCathodeToGround = buffer.readUInt16LE(0xAE);\n data.year = buffer.readUInt8(0xC8);\n data.month = buffer.readUInt8(0xC9);\n data.day = buffer.readUInt8(0xCA);\n data.hour = buffer.readUInt8(0xCB);\n data.minute = buffer.readUInt8(0xCC);\n data.second = buffer.readUInt8(0xCD);\n return {\n payload: data,\n topic: 'data'\n };\n break;\n case 232: // data - ME3000SP\n data.loggerSN = buffer.readUInt32LE(0x07);\n data.tempLogger = buffer.readInt16LE(0x70) / 100;\n data.tempBattery = buffer.readInt16LE(0x30) / 10;\n data.tempInverter = buffer.readInt16LE(0xA6);\n data.tempHeatSink = buffer.readInt16LE(0xA8);\n data.sensorTypeList = readSensorTypeList(buffer.slice(0x0C, 0x0E));\n data.tOperationTime = buffer.readUInt32LE(0x0E);\n data.inverterSN = (buffer.toString('utf8', 0x20, 0x30)).trimEnd();\n data.VAC1 = buffer.readUInt16LE(0x40) / 10;\n data.VAC2 = buffer.readUInt16LE(0x42) / 10;\n data.VAC3 = buffer.readUInt16LE(0x44) / 10;\n data.frequencyPowerGrid = buffer.readUInt16LE(0x46) / 100;\n data.currentPower = buffer.readUInt32LE(0x48);\n data.inverterStatus = decodeInverterStatus(buffer.readUInt8(0x58));\n data.Vbus = buffer.readUInt16LE(0x72) / 10;\n data.VCPU1 = buffer.readUInt16LE(0x74) / 10;\n data.cathode_groundInsulationImpedance = buffer.readUInt16LE(0x80);\n data.countryCode = buffer.readUInt16LE(0x82);\n data.A_phaseDCdistribution = buffer.readUInt16LE(0x8A);\n data.B_phaseDCdistribution = buffer.readUInt16LE(0x8C);\n data.C_phaseDCdistribution = buffer.readUInt16LE(0x8E);\n data.consumptionDailyEnergyPurchase = buffer.readUInt16LE(0x76);\n data.consumptionDailyEnergyUsed = buffer.readUInt16LE(0x78);\n data.consumptionTotal = buffer.readUInt16LE(0x86);\n data.generationTotal = buffer.readUInt16LE(0x7A);\n data.generationTotalOnGrid = buffer.readUInt16LE(0x7E);\n data.battChargeLevel = buffer.readUInt16LE(0x6A);\n data.battChargeDischargePower = buffer.readInt16LE(0x64) * 10;\n data.battCurrent = buffer.readInt16LE(0x68) / 100;\n data.battDailyGenerationPV = buffer.readUInt32LE(0x4C) / 100;\n data.battDailyEnergyCharged = buffer.readUInt16LE(0xc4) / 100;\n data.battDailyEnergyDischarged = buffer.readUInt16LE(0xC6) / 100;\n data.battGenerationCurrent = buffer.readInt16LE(0xA2) / 100;\n data.battTotalEnergyCharged = buffer.readUInt32LE(0xC8);\n data.battTotalEnergyDischarged = buffer.readUInt32LE(0xCC);\n data.battPower = buffer.readInt16LE(0xc2) * 10;\n data.battVoltage = buffer.readUInt16LE(0x66) / 100;\n\n data.busVoltage = buffer.readUInt16LE(0x90) / 10;\n data.busVoltageLlc = buffer.readUInt16LE(0x92) / 10;\n data.buckCurrent = buffer.readInt16LE(0x94) / 100;\n data.voltageDCComponent = buffer.readInt16LE(0xAE) / 10;\n data.epsOutVoltage = buffer.readInt16LE(0x96) / 10;\n data.productionCurrentR = buffer.readUInt16LE(0x98) / 100;\n data.productionCurrentS = buffer.readUInt16LE(0x9E) / 100;\n data.productionCurrentT = buffer.readUInt16LE(0xA0) / 100;\n data.year = buffer.readUInt8(0xE0);\n data.month = buffer.readUInt8(0xE1);\n data.day = buffer.readUInt8(0xE2);\n data.hour = buffer.readUInt8(0xE3);\n data.minute = buffer.readUInt8(0xE4);\n data.second = buffer.readUInt8(0xE5);\n let dateFormat = '20' + String(data.year).padStart(2, '0') + '-' + String(data.month).padStart(2, '0') + '-' + String(data.day).padStart(2, '0') + 'T' + String(data.hour).padStart(2, '0') + ':' + String(data.minute).padStart(2, '0') + ':' + String(data.second).padStart(2, '0')\n data.timestamp = new Date(dateFormat)\n //node.warn(data);\n return {\n payload: data,\n topic: 'data'\n };\n break;\n\n case 164: // data - KTL-X\n data.loggerSN = buffer.readUInt32LE(0x07);\n data.sensorTypeList = readSensorTypeList(buffer.slice(0x0C, 0x0E));\n data.tOperationTime = buffer.readUInt32LE(0x0E);\n data.inverterSN = (buffer.toString('utf8', 0x20, 0x30)).trimEnd();\n data.inverterTemp = buffer.readInt16LE(0x30) / 10;\n data.VDC1 = buffer.readUInt16LE(0x32) / 10;\n data.VDC2 = buffer.readUInt16LE(0x34) / 10;\n data.IDC1 = buffer.readUInt16LE(0x36) / 10;\n data.IDC2 = buffer.readUInt16LE(0x38) / 10;\n data.IAC1 = buffer.readUInt16LE(0x3A) / 10;\n data.IAC2 = buffer.readUInt16LE(0x3C) / 10;\n data.IAC3 = buffer.readUInt16LE(0x3E) / 10;\n data.VAC1 = buffer.readUInt16LE(0x40) / 10;\n data.VAC2 = buffer.readUInt16LE(0x42) / 10;\n data.VAC3 = buffer.readUInt16LE(0x44) / 10;\n data.fAC = buffer.readUInt16LE(0x46) / 100;\n\n data.currentPower = buffer.readUInt32LE(0x48);\n\n data.eToday = buffer.readUInt32LE(0x4C) / 100;\n data.eTotal = buffer.readUInt32LE(0x50) / 10;\n\n data.hTotal = buffer.readUInt32LE(0x54);\n\n data.inverterStatus = decodeInverterStatus(buffer.readUInt8(0x58));\n\n data.loggerTemp = buffer.readInt16LE(0x70);\n data.Vbus = buffer.readUInt16LE(0x72) / 10;\n data.VCPU1 = buffer.readUInt16LE(0x74) / 10;\n data.countdownTime = buffer.readUInt16LE(0x78);\n data.PV1insulationResistance = buffer.readUInt16LE(0x7C);\n data.PV2insulationResistance = buffer.readUInt16LE(0x7E);\n data.cathode_groundInsulationImpedance = buffer.readUInt16LE(0x80);\n data.countryCode = buffer.readUInt16LE(0x82);\n data.A_phaseDCdistribution = buffer.readUInt16LE(0x8A);\n data.B_phaseDCdistribution = buffer.readUInt16LE(0x8C);\n data.C_phaseDCdistribution = buffer.readUInt16LE(0x8E);\n\n data.firmware = buffer.toString('utf8', 0x90, 0x94);\n\n data.year = buffer.readUInt8(0x98);\n data.month = buffer.readUInt8(0x99);\n data.day = buffer.readUInt8(0x9A);\n data.hour = buffer.readUInt8(0x9B);\n data.minute = buffer.readUInt8(0x9C);\n data.second = buffer.readUInt8(0x9D);\n\n // node.warn(data);\n return {\n payload: data,\n topic: 'data'\n };\n break;\n case 99: // hello message\n data.loggerSN = buffer.readUInt32LE(0x07);\n data.tOperationTime = buffer.readUInt32LE(0x0C);\n data.uploadingFrequency = buffer.readUInt8(0x18);\n data.dataLoggingFrequency = buffer.readUInt8(0x19);\n data.heartbeatFrequency = buffer.readUInt8(0x1A);\n data.commandType = buffer.readUInt8(0x1B);\n data.signalQuality = buffer.readUInt8(0x1C);\n data.sensorTypeNr = buffer.readUInt8(0x1D);\n data.moduleVersion = buffer.toString('utf8', 0x1E, 0x46);\n data.macAddress = readMacAddress(buffer.slice(0x46, 0x4C));\n data.localIP = buffer.toString('utf8', 0x4C, 0x5B);\n data.sensorTypeList = readSensorTypeList(buffer.slice(0x5F, 0x61));\n\n // node.warn(data);\n return {\n payload: data,\n topic: 'hello'\n };\n break;\n case 41: // hello_cd message\n data.loggerSN = buffer.readUInt32LE(0x07);\n data.totalOperationTime = buffer.readUInt32LE(0x0C);\n\n // node.warn(data);\n return {\n payload: data,\n topic: 'hello_cd'\n };\n break;\n case 73: // hello_end message\n data.loggerSN = buffer.readUInt32LE(0x07);\n data.totalOperationTime = buffer.readUInt32LE(0x0C);\n\n // node.warn(data);\n return {\n payload: data,\n topic: 'hello_end'\n };\n break;\n\n default:\n // node.warn(buffer.length);\n return null\n break;\n}\n\nfunction readMacAddress(buffer) {\n let macAddressStr = '';\n for (let buff of buffer) {\n // node.warn(buff.toString(16));\n macAddressStr += ${0${(buff.toString(16))}.slice(-2)}:;\n }\n return macAddressStr.substring(0, 17);\n}\nfunction readSensorTypeList(buffer) {\n let SensorTypeListStr = ${0${(buffer[1].toString(16))}.slice(-2)};\n SensorTypeListStr += ${0${(buffer[0].toString(16))}.slice(-2)};\n return SensorTypeListStr;\n}\n\nfunction decodeInverterStatus(status) {\n switch (status) {\n case 0x00:\n return standby;\n case 0x02:\n return normal;\n case 0x03:\n return fault;\n case 0x04:\n return permanent;\n default:\n return 0x${0${(status.toString(16))}.slice(-2)};\n }\n}\n",
      "outputs": 1,
      "noerr": 0,
      "initialize": "",
      "finalize": "",
      "libs": [],
      "x": 450,
      "y": 260,
      "wires": [
      []
      ],
      "inputLabels": [
      "wifi stick buffer in"
      ],
      "outputLabels": [
      "decoded message object"
      ]
      },
      {
      "id": "28fb73099b82097a",
      "type": "change",
      "z": "16c33b1e099682e0",
      "name": "set host and port",
      "rules": [
      {
      "t": "set",
      "p": "host",
      "pt": "msg",
      "to": "remoteHostIp",
      "tot": "env"
      },
      {
      "t": "set",
      "p": "port",
      "pt": "msg",
      "to": "remoteHostPort",
      "tot": "env"
      },
      {
      "t": "set",
      "p": "topic",
      "pt": "msg",
      "to": "remote_server",
      "tot": "str"
      }
      ],
      "action": "",
      "property": "",
      "from": "",
      "to": "",
      "reg": false,
      "x": 610,
      "y": 160,
      "wires": [
      [
      "164f421ec73701f9"
      ]
      ]
      },
      {
      "id": "88b9df11c34f72ea",
      "type": "switch",
      "z": "16c33b1e099682e0",
      "name": "",
      "property": "resend",
      "propertyType": "env",
      "rules": [
      {
      "t": "istype",
      "v": "boolean",
      "vt": "boolean"
      },
      {
      "t": "true"
      }
      ],
      "checkall": "true",
      "repair": false,
      "outputs": 2,
      "x": 430,
      "y": 120,
      "wires": [
      [
      "c511e8c8f7ced576"
      ],
      [
      "28fb73099b82097a"
      ]
      ],
      "inputLabels": [
      "inverter data"
      ],
      "outputLabels": [
      "local server only",
      "remote server"
      ]
      },
      {
      "id": "7113cbe45845bb03",
      "type": "status",
      "z": "16c33b1e099682e0",
      "name": "",
      "scope": [],
      "x": 120,
      "y": 40,
      "wires": [
      []
      ]
      },
      {
      "id": "a92085a4d10f12e6",
      "type": "function",
      "z": "16c33b1e099682e0",
      "name": "add msg.frameType",
      "func": "let frameType = '';\nswitch (msg.payload.length) {\n case 99:\n frameType = 'hello(99)';\n break;\n case 23:\n frameType = 'srv_res(23)';\n break;\n case 164: // KTL-X\n case 208: // HYD6000ES\n case 232: // ME3000SP\n case 547: // BMI-600 & SUN600G3-EU-230\n frameType = data(${msg.payload.length});\n break;\n case 14:\n frameType = 'heartbeat(14)';\n break;\n case 41:\n frameType = 'hello_cd(41)';\n break;\n case 73:\n frameType = 'hello_end(73)';\n break;\n default:\n frameType = unknown(${msg.payload.length});\n break;\n}\nmsg.frameType = frameType;\n// delete TCP nodes properties\ndelete msg.ip;\ndelete msg.host;\ndelete msg.port;\ndelete msg._session;\n\nreturn msg;",
      "outputs": 1,
      "noerr": 0,
      "initialize": "",
      "finalize": "",
      "libs": [],
      "x": 960,
      "y": 260,
      "wires": [
      []
      ]
      },
      {
      "id": "f5a0b9593db8e99f",
      "type": "file in",
      "z": "16c33b1e099682e0",
      "name": "",
      "filename": "/opt/iobroker/test.bin",
      "filenameType": "str",
      "format": "stream",
      "chunk": false,
      "sendError": false,
      "encoding": "none",
      "allProps": false,
      "x": 340,
      "y": 360,
      "wires": [
      []
      ]
      },
      {
      "id": "d8a0e2dceb7262ee",
      "type": "inject",
      "z": "16c33b1e099682e0",
      "name": "",
      "props": [
      {
      "p": "payload"
      },
      {
      "p": "topic",
      "vt": "str"
      }
      ],
      "repeat": "10",
      "crontab": "",
      "once": false,
      "onceDelay": 0.1,
      "topic": "",
      "payload": "",
      "payloadType": "date",
      "x": 120,
      "y": 360,
      "wires": [
      []
      ]
      },
      {
      "id": "a3d422ba2bba844c",
      "type": "comment",
      "z": "16c33b1e099682e0",
      "name": "Hinweise zum solar Node",
      "info": "https://github.com/serek4/node-red-sofar-inverter\nhttp://192.168.1.90/config_hide.html\nhttp://192.168.1.91/config_hide.html\nhttp://192.168.1.92/config_hide.html\nhttps://github.com/0xb1ff/solarman-dissector\nresent disabled in Eigenschaften",
      "x": 610,
      "y": 520,
      "wires": []
      },
      {
      "id": "cd050871c5e7245c",
      "type": "debug",
      "z": "16c33b1e099682e0",
      "name": "debug 3",
      "active": true,
      "tosidebar": true,
      "console": false,
      "tostatus": false,
      "complete": "false",
      "statusVal": "",
      "statusType": "auto",
      "x": 460,
      "y": 40,
      "wires": []
      },
      {
      "id": "63d79ea54fec0a3b",
      "type": "subflow:16c33b1e099682e0",
      "z": "c6d3f0d.558371",
      "name": "Solar inverter",
      "x": 130,
      "y": 500,
      "wires": [
      [
      "f301baaf83223c8e"
      ],
      [
      "487a65aaad85458b"
      ]
      ]
      },
      {
      "id": "f301baaf83223c8e",
      "type": "json",
      "z": "c6d3f0d.558371",
      "name": "",
      "property": "payload",
      "action": "",
      "pretty": false,
      "x": 330,
      "y": 500,
      "wires": [
      [
      "df544262fde22aca"
      ]
      ]
      },
      {
      "id": "255e0e6a6050f427",
      "type": "comment",
      "z": "c6d3f0d.558371",
      "name": "Hinweise zum solar Node",
      "info": "https://github.com/serek4/node-red-sofar-inverter\nhttp://192.168.1.90/config_hide.html\nhttp://192.168.1.91/config_hide.html\nhttp://192.168.1.92/config_hide.html\nhttps://github.com/0xb1ff/solarman-dissector",
      "x": 130,
      "y": 560,
      "wires": []
      },
      {
      "id": "df544262fde22aca",
      "type": "subflow:6e802f1553b18149",
      "z": "c6d3f0d.558371",
      "name": "",
      "env": [
      {
      "name": "keepTopic",
      "value": "true",
      "type": "bool"
      }
      ],
      "x": 570,
      "y": 500,
      "wires": [
      [
      "5b2b626a187f8453"
      ]
      ]
      },
      {
      "id": "5b2b626a187f8453",
      "type": "ioBroker out",
      "z": "c6d3f0d.558371",
      "name": "",
      "topic": "",
      "ack": "true",
      "autoCreate": "true",
      "stateName": "",
      "role": "",
      "payloadType": "",
      "readonly": "",
      "stateUnit": "",
      "stateMin": "",
      "stateMax": "",
      "x": 820,
      "y": 500,
      "wires": []
      },
      {
      "id": "487a65aaad85458b",
      "type": "debug",
      "z": "c6d3f0d.558371",
      "name": "debug 2",
      "active": true,
      "tosidebar": true,
      "console": false,
      "tostatus": false,
      "complete": "false",
      "statusVal": "",
      "statusType": "auto",
      "x": 340,
      "y": 560,
      "wires": []
      }
      ]

      posted in Entwicklung
      P
      painless
    • RE: Bosswerk MI600 Adapter

      @sborg
      Hallo, das ist ein interessanter Ansatz aber unnötig: Du kannst die Bosswerk Solarman Server -Adresse direkt im Inverter über ein verstecktes Menü ändern:

      http://<lokale IP des Bosswerk Inverters>/config_hide.html

      Hier habe ich dann die IP-Adresse auf einen eigenen Node-red input verbogen und dann damit die eingehenden Datenpakete analysiert. Ich kann zwar (noch) nicht alles entschlüsseln, komme aber an alle relevanten PV Daten ran und habe daraus eigene Datenpunkte gezogen.

      Dabei kam die große Überraschung: Die Bosswerk Inverter und damit alle baugleichen Geräte übertragen die eigene lokale IP-Adresse und die WIFI SSID an die Solarman-Server. Ob auch das WIFI Password dabei ist, kann ich nicht sagen, da ich nicht alles dechiffriert bekomme. Aber die Vermutung liegt nahe..

      Ich habe jetzt jedenfalls die komplette Kommunikation an die Solarman-Server unterbrochen. Das ist mir zu unheimlich...

      Im Klartext heißt das, dass alle die die SOLARMAN-App nutzen und ihre Inverter entsprechend eingerichtet haben, gleichzeitig auch sensible Daten weiterleiten. Und wenn man dann auch noch seine GEO-Daten in der App eingibt... Na Ihr könnt es Euch denken.

      posted in Entwicklung
      P
      painless
    • RE: Alexa Anbindung ohne Cloud und Skill

      Hi,

      ja, damit funktioniert es. Dann aber mit Cloud und Skill, was ich eigentlich nicht möchte. Keine Flat, Daten außer Haus etc.

      Gibt es irgendwo noch Debug oder Protokoll-Funktionen die ich mit ALexa local prüfen kann ?

      Danke !

      Kai

      posted in Cloud Dienste
      P
      painless
    • RE: Alexa Anbindung ohne Cloud und Skill

      @Blackeye:

      Hi,

      eine Trick gibt es da eigentlich nicht, aber welchen der InputAdapter benutzt du denn?

      @painless:

      Hallo,

      ich verzweifle… Nach 2 Tagen hab ich es immer noch nicht geschafft, irgendwelche Objekte mit der Alexa App suche zu finden. Es ist wie bei meinen Vorrednern. Das Device geht auf discovery, wird aber nicht entdeckt.

      Hab die node js 8.12.0 mit der 4.6.1 NPM in einer ioBroker Installation 3.4.7 und dem 1.6.0 node-red Adapter im Einsatz.

      Das ganze läuft auf eine RPI 3B+ Linux jessie lite 4.14.69-V7+ aus dem piVCCU-Image 2.35.16-36.

      Vielleicht kann mir jemand helfen. Mit den diversen Cloud-Lösungen werden die Objekte gefunden aber ich finde diese Lösung einfach zu gut und würde sie gerne weiter testen.

      Die Log´s sind unauffällig soweit ich das beurteilen kann.

      Danke !

      painless

      Hallo Blackeye

      danke für Deine schnelle Antwort! Welchen Input Adapter meinst Du ?

      Ich hab die Alexa App auf einem Fire und einen Echo 2. Gen und da hab ich gelesen, dass dort die Device suche (noch) nicht funktioniert. Aber vom Fire muss es doch klappen, oder ?

      Im ioBroker hab ich den o.g. node-red Adapter 1.6.0 und das node-red-contrib-alexa-local über die node-red Oberfläche installiert.

      Weiter laufen die Homematic hmrega und hmrpc, discovery und admin Adapter. Sonst nix weiter.

      Keine weiteren Cloud oder aktivierten Skills, wie Du es hier auch so beschreibst.

      Mein Flow startet mit dem Input der Alexa-local. Ich hab es so verstanden, dass der Name dieses Inputs der Rufname in Alexa ist. Dann noch einen Switch, da ich damit ein Licht schalten möchte und dann die Verzweigung auf das entsprechende Homematic Objekt.

      Hab ich da irgendetwas überlesen ?

      Danke !

      painless

      posted in Cloud Dienste
      P
      painless
    • RE: Alexa Anbindung ohne Cloud und Skill

      Hallo,

      ich verzweifle… Nach 2 Tagen hab ich es immer noch nicht geschafft, irgendwelche Objekte mit der Alexa App suche zu finden. Es ist wie bei meinen Vorrednern. Das Device geht auf discovery, wird aber nicht entdeckt.

      Hab die node js 8.12.0 mit der 4.6.1 NPM in einer ioBroker Installation 3.4.7 und dem 1.6.0 node-red Adapter im Einsatz.

      Das ganze läuft auf eine RPI 3B+ Linux jessie lite 4.14.69-V7+ aus dem piVCCU-Image 2.35.16-36.

      Vielleicht kann mir jemand helfen. Mit den diversen Cloud-Lösungen werden die Objekte gefunden aber ich finde diese Lösung einfach zu gut und würde sie gerne weiter testen.

      Die Log´s sind unauffällig soweit ich das beurteilen kann.

      Danke !

      painless

      posted in Cloud Dienste
      P
      painless
    Community
    Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
    The ioBroker Community 2014-2023
    logo