Weiter zum Inhalt
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Hell
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dunkel
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Skripten / Logik
  4. Node-Red
  5. ich brauche etwas Nachhilfe mit Node Red und RS232

NEWS

  • Monatsrückblick Juli / August 2026 ist online!
    BluefoxB
    Bluefox
    7
    1
    106

  • Der neue Monatsrückblick für Mai und Juni 2026 ist online!
    BluefoxB
    Bluefox
    8
    1
    1.3k

  • wichtiges UPDATE für controller 7.2.2 im stable
    HomoranH
    Homoran
    10
    1
    3.8k

ich brauche etwas Nachhilfe mit Node Red und RS232

Geplant Angeheftet Gesperrt Verschoben Node-Red
55 Beiträge 6 Kommentatoren 896 Aufrufe 4 Beobachtet
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • A andibr

    @OliverIO ich kopiere morgen mal die Meldungen die mir Node-Red auswirft. Es steht meistens, ....ist kein String....

    A Offline
    A Offline
    andibr
    schrieb am zuletzt editiert von
    #41

    Mein Flow sieht so aus:Bildschirmfoto vom 2026-08-14 19-32-46.png

    Manchmal funktioniert es richtig und manchmal eben nicht. Ich habe mir überlegt, ob evt. daran liegen könnte, dass der Port nach der Abfrage nicht geschlossen wird?
    Wenn ich im Minicom den Connect offen stehen lasse ist mir bis jetzt nicht aufgefallen, dass da keine Antwort kommen würde.

    Im Log sieht es dann so aus:
    Bildschirmfoto vom 2026-08-14 19-38-16.png

    Wenn ich dann den Flow verändere und neu deploye funktioniert es eine Weile ganz gut und plötzlich geht es wieder nicht mehr. Bis jetzt habe ich noch kein Muster gefunden.

    Ich habe da noch alte USR-TCP232-T2 Adapter rumliegen
    Bildschirmfoto vom 2026-08-14 19-43-18.png

    Allenfalls könnte man damit ja auch etwas machen und hätte dann einfach einen Netzwerk-Port zum abfragen, aber ich denke das Thema mit dem Timeout wird gleich bleiben. So wie ich es verstehe kommt der Timeout nicht vom Port sondern ist ein "nicht reagieren des BMS".

    OliverIOO 2 Antworten Letzte Antwort
    0
    • A andibr

      Mein Flow sieht so aus:Bildschirmfoto vom 2026-08-14 19-32-46.png

      Manchmal funktioniert es richtig und manchmal eben nicht. Ich habe mir überlegt, ob evt. daran liegen könnte, dass der Port nach der Abfrage nicht geschlossen wird?
      Wenn ich im Minicom den Connect offen stehen lasse ist mir bis jetzt nicht aufgefallen, dass da keine Antwort kommen würde.

      Im Log sieht es dann so aus:
      Bildschirmfoto vom 2026-08-14 19-38-16.png

      Wenn ich dann den Flow verändere und neu deploye funktioniert es eine Weile ganz gut und plötzlich geht es wieder nicht mehr. Bis jetzt habe ich noch kein Muster gefunden.

      Ich habe da noch alte USR-TCP232-T2 Adapter rumliegen
      Bildschirmfoto vom 2026-08-14 19-43-18.png

      Allenfalls könnte man damit ja auch etwas machen und hätte dann einfach einen Netzwerk-Port zum abfragen, aber ich denke das Thema mit dem Timeout wird gleich bleiben. So wie ich es verstehe kommt der Timeout nicht vom Port sondern ist ein "nicht reagieren des BMS".

      OliverIOO Offline
      OliverIOO Offline
      OliverIO
      schrieb am zuletzt editiert von OliverIO
      #42

      @andibr

      Als erstes muss man rausfinden an welcher Node der Fehler entsteht.
      Dann in dieser function node etwas debug code einbauen
      Damit man sieht was für ein datentyp da ankommt und was für Inhaltsangaben ankommt.
      Dann muss man bewerten wie man damit umgeht.
      Wenn es sonst funktioniert, dann kann man das einfach durch Code ausfiltern, also keine msg zurückgeben, so das die nachfolgenden nodes nicht getriggert werden.

      Nur mit einem Bild vom Flow kann niemand was anfangen.
      Mit mehr, kann ich erst Ende nächster woche weitermachen

      Meine Adapter und Widgets
      TVProgram, SqueezeboxRPC, OpenLiga, RSSFeed, MyTime,, pi-hole2, vis-json-template, skiinfo, vis-mapwidgets, vis-2-widgets-rssfeed
      Links im Profil

      A 1 Antwort Letzte Antwort
      0
      • OliverIOO OliverIO

        @andibr

        Als erstes muss man rausfinden an welcher Node der Fehler entsteht.
        Dann in dieser function node etwas debug code einbauen
        Damit man sieht was für ein datentyp da ankommt und was für Inhaltsangaben ankommt.
        Dann muss man bewerten wie man damit umgeht.
        Wenn es sonst funktioniert, dann kann man das einfach durch Code ausfiltern, also keine msg zurückgeben, so das die nachfolgenden nodes nicht getriggert werden.

        Nur mit einem Bild vom Flow kann niemand was anfangen.
        Mit mehr, kann ich erst Ende nächster woche weitermachen

        A Offline
        A Offline
        andibr
        schrieb am zuletzt editiert von
        #43

        @OliverIO ich versuche morgen noch etwas mehr raus zu holen. Eben es verwirrt mich das es manchmal durchläuft und dann plötzlich nicht mehr.
        Für mich als Laie sieht es irgendwie so aus, wie wenn das BMS irgendwie auf was warten würde und daher nicht mehr.

        1 Antwort Letzte Antwort
        0
        • P Offline
          P Offline
          peterfido
          schrieb am zuletzt editiert von
          #44

          Statt des Screenshots am besten den Node-Red-Export hier in Code-Tags posten. Dann kann man sehen, ob man helfen kann.

          Gruß

          Peterfido

          A 1 Antwort Letzte Antwort
          0
          • P peterfido

            Statt des Screenshots am besten den Node-Red-Export hier in Code-Tags posten. Dann kann man sehen, ob man helfen kann.

            A Offline
            A Offline
            andibr
            schrieb am zuletzt editiert von andibr
            #45

            @peterfido

            Hier ist der ganze Flow, den ich unterdessen zusammen habe:

            [
                {
                    "id": "26771494c726dd85",
                    "type": "tab",
                    "label": "Pytes",
                    "disabled": false,
                    "info": "",
                    "env": []
                },
                {
                    "id": "09a7088a7c52e930",
                    "type": "inject",
                    "z": "26771494c726dd85",
                    "name": "Start Impuls",
                    "props": [
                        {
                            "p": "payload"
                        }
                    ],
                    "repeat": "900",
                    "crontab": "",
                    "once": false,
                    "onceDelay": 0.1,
                    "topic": "",
                    "payload": "bat",
                    "payloadType": "str",
                    "x": 130,
                    "y": 60,
                    "wires": [
                        [
                            "f6f7978549817c9b",
                            "dd20c6bfc8c1643a",
                            "aae8b0af1ff64ae1",
                            "6df4f9bd092fdcd3",
                            "d81970d6d1e4cca6",
                            "c8cc5a91dbf6eb1a",
                            "09faeaa564e7d7ea",
                            "027109f5112c3c3e"
                        ]
                    ]
                },
                {
                    "id": "f6f7978549817c9b",
                    "type": "trigger",
                    "z": "26771494c726dd85",
                    "name": "bat 1",
                    "op1": "bat 1",
                    "op2": "",
                    "op1type": "str",
                    "op2type": "nul",
                    "duration": "250",
                    "extend": false,
                    "overrideDelay": false,
                    "units": "ms",
                    "reset": "",
                    "bytopic": "all",
                    "topic": "topic",
                    "outputs": 1,
                    "x": 690,
                    "y": 60,
                    "wires": [
                        [
                            "f1e94e531bb2b4f9"
                        ]
                    ]
                },
                {
                    "id": "f1e94e531bb2b4f9",
                    "type": "serial request",
                    "z": "26771494c726dd85",
                    "name": "BMSMaster",
                    "serial": "d031dd424e7b1ff2",
                    "x": 890,
                    "y": 60,
                    "wires": [
                        [
                            "79724f85531596e4",
                            "4b31f05c7b6c5425"
                        ]
                    ]
                },
                {
                    "id": "79724f85531596e4",
                    "type": "function",
                    "z": "26771494c726dd85",
                    "name": "convert to msgs",
                    "func": "const text = msg.payload;\n\nif (typeof text !== \"string\") {\n    node.error(\"msg.payload ist kein String\", msg);\n    return null;\n}\n\n// In einzelne Zeilen zerlegen\nconst lines = text\n    .split(/\\r?\\n/)\n    .map(line => line.trim())\n    .filter(line => line !== \"\");\n\n// Nur Zeilen berücksichtigen, die mit einer Batterienummer beginnen\nconst dataLines = lines.filter(line => /^\\d+\\s/.test(line));\n\nconst messages = [];\n\nfor (const line of dataLines) {\n\n    // Spalten sind durch mindestens 2 Leerzeichen getrennt\n    const columns = line.split(/\\s{2,}/);\n\n    if (columns.length < 9) {\n        node.warn(\"Zeile konnte nicht verarbeitet werden: \" + line);\n        continue;\n    }\n\n    const battery = {\n        battery: Number(columns[0]),\n        volt: Number(columns[1]),\n        tempr: Number(columns[2]),\n        baseState: columns[3],\n        voltState: columns[4],\n        currState: columns[5],\n        tempState: columns[6],\n        coulomb: Number(columns[7].replace(\"%\", \"\")),\n        capacity: Number(columns[8].replace(/[^\\d]/g, \"\"))\n    };\n\n    messages.push({\n        ...msg,\n        payload: battery\n    });\n}\n\n// Alle Nachrichten nacheinander über denselben Ausgang senden\nreturn [messages];",
                    "outputs": 1,
                    "timeout": 0,
                    "noerr": 0,
                    "initialize": "",
                    "finalize": "",
                    "libs": [],
                    "x": 1080,
                    "y": 60,
                    "wires": [
                        [
                            "4a8dcae7d0f7d8a8"
                        ]
                    ]
                },
                {
                    "id": "68c635b31d513d6d",
                    "type": "debug",
                    "z": "26771494c726dd85",
                    "name": "debug 4",
                    "active": false,
                    "tosidebar": true,
                    "console": false,
                    "tostatus": false,
                    "complete": "true",
                    "targetType": "full",
                    "statusVal": "",
                    "statusType": "auto",
                    "x": 1440,
                    "y": 120,
                    "wires": []
                },
                {
                    "id": "6a16c00e7b0e2997",
                    "type": "ioBroker out",
                    "z": "26771494c726dd85",
                    "name": "",
                    "topic": "",
                    "ack": "true",
                    "autoCreate": "true",
                    "stateName": "",
                    "role": "",
                    "payloadType": "",
                    "readonly": "",
                    "stateUnit": "",
                    "stateMin": "",
                    "stateMax": "",
                    "x": 1460,
                    "y": 60,
                    "wires": []
                },
                {
                    "id": "4a8dcae7d0f7d8a8",
                    "type": "function",
                    "z": "26771494c726dd85",
                    "name": "function 2",
                    "func": "const battery = msg.payload;\n\nif (!battery || battery.battery === undefined) {\n    node.error(\"Ungültiges Battery-Objekt\", msg);\n    return null;\n}\n\nconst batteryId = battery.battery;\n\nconst states = [\n    {\n        id: \"voltage\",\n        value: battery.volt,\n        name: \"Voltage\",\n        role: \"value.voltage\",\n        type: \"number\",\n        readonly: true,\n        unit: \"mV\",\n        min: 0\n    },\n    {\n        id: \"temperature\",\n        value: battery.tempr / 1000,\n        name: \"Temperature\",\n        role: \"value.temperature\",\n        type: \"number\",\n        readonly: true,\n        unit: \"°C\"\n    },\n    {\n        id: \"baseState\",\n        value: battery.baseState,\n        name: \"Base State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"voltageState\",\n        value: battery.voltState,\n        name: \"Voltage State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"currentState\",\n        value: battery.currState,\n        name: \"Current State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"temperatureState\",\n        value: battery.tempState,\n        name: \"Temperature State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"charge\",\n        value: battery.coulomb,\n        name: \"Charge\",\n        role: \"value.battery\",\n        type: \"number\",\n        readonly: true,\n        unit: \"%\",\n        min: 0,\n        max: 100\n    },\n    {\n        id: \"capacity\",\n        value: battery.capacity,\n        name: \"Capacity\",\n        role: \"value\",\n        type: \"number\",\n        readonly: true,\n        unit: \"mAh\",\n        min: 0\n    }\n];\n\nconst messages = [];\n\nfor (const state of states) {\n    const out = {\n        topic: `0_userdata.0.pytes.01.${batteryId}.${state.id}`,\n        payload: state.value,\n\n        stateName: state.name,\n        stateRole: state.role,\n        stateType: state.type,\n        stateReadonly: state.readonly\n    };\n\n    if (state.unit !== undefined) {\n        out.stateUnit = state.unit;\n    }\n\n    if (state.min !== undefined) {\n        out.stateMin = state.min;\n    }\n\n    if (state.max !== undefined) {\n        out.stateMax = state.max;\n    }\n\n    messages.push(out);\n}\n\nreturn [messages];",
                    "outputs": 1,
                    "timeout": 0,
                    "noerr": 0,
                    "initialize": "",
                    "finalize": "",
                    "libs": [],
                    "x": 1260,
                    "y": 60,
                    "wires": [
                        [
                            "6a16c00e7b0e2997",
                            "68c635b31d513d6d"
                        ]
                    ]
                },
                {
                    "id": "dd20c6bfc8c1643a",
                    "type": "delay",
                    "z": "26771494c726dd85",
                    "name": "",
                    "pauseType": "delay",
                    "timeout": "1",
                    "timeoutUnits": "minutes",
                    "rate": "1",
                    "nbRateUnits": "1",
                    "rateUnits": "second",
                    "randomFirst": "1",
                    "randomLast": "5",
                    "randomUnits": "seconds",
                    "drop": false,
                    "allowrate": false,
                    "outputs": 1,
                    "x": 520,
                    "y": 200,
                    "wires": [
                        [
                            "0dc431cc8e3444fa"
                        ]
                    ]
                },
                {
                    "id": "3cce03774442db86",
                    "type": "debug",
                    "z": "26771494c726dd85",
                    "name": "debug 2",
                    "active": false,
                    "tosidebar": true,
                    "console": false,
                    "tostatus": false,
                    "complete": "true",
                    "targetType": "full",
                    "statusVal": "",
                    "statusType": "auto",
                    "x": 1440,
                    "y": 260,
                    "wires": []
                },
                {
                    "id": "0dc431cc8e3444fa",
                    "type": "trigger",
                    "z": "26771494c726dd85",
                    "name": "bat 2",
                    "op1": "bat 2",
                    "op2": "",
                    "op1type": "str",
                    "op2type": "nul",
                    "duration": "250",
                    "extend": false,
                    "overrideDelay": false,
                    "units": "ms",
                    "reset": "",
                    "bytopic": "all",
                    "topic": "topic",
                    "outputs": 1,
                    "x": 730,
                    "y": 200,
                    "wires": [
                        [
                            "72209bb281ee39b7"
                        ]
                    ]
                },
                {
                    "id": "72209bb281ee39b7",
                    "type": "serial request",
                    "z": "26771494c726dd85",
                    "name": "BMSMaster",
                    "serial": "d031dd424e7b1ff2",
                    "x": 890,
                    "y": 200,
                    "wires": [
                        [
                            "9441d38d2c549fb8"
                        ]
                    ]
                },
                {
                    "id": "9441d38d2c549fb8",
                    "type": "function",
                    "z": "26771494c726dd85",
                    "name": "convert to msgs",
                    "func": "const text = msg.payload;\n\nif (typeof text !== \"string\") {\n    node.error(\"msg.payload ist kein String\", msg);\n    return null;\n}\n\n// In einzelne Zeilen zerlegen\nconst lines = text\n    .split(/\\r?\\n/)\n    .map(line => line.trim())\n    .filter(line => line !== \"\");\n\n// Nur Zeilen berücksichtigen, die mit einer Batterienummer beginnen\nconst dataLines = lines.filter(line => /^\\d+\\s/.test(line));\n\nconst messages = [];\n\nfor (const line of dataLines) {\n\n    // Spalten sind durch mindestens 2 Leerzeichen getrennt\n    const columns = line.split(/\\s{2,}/);\n\n    if (columns.length < 9) {\n        node.warn(\"Zeile konnte nicht verarbeitet werden: \" + line);\n        continue;\n    }\n\n    const battery = {\n        battery: Number(columns[0]),\n        volt: Number(columns[1]),\n        tempr: Number(columns[2]),\n        baseState: columns[3],\n        voltState: columns[4],\n        currState: columns[5],\n        tempState: columns[6],\n        coulomb: Number(columns[7].replace(\"%\", \"\")),\n        capacity: Number(columns[8].replace(/[^\\d]/g, \"\"))\n    };\n\n    messages.push({\n        ...msg,\n        payload: battery\n    });\n}\n\n// Alle Nachrichten nacheinander über denselben Ausgang senden\nreturn [messages];",
                    "outputs": 1,
                    "timeout": 0,
                    "noerr": 0,
                    "initialize": "",
                    "finalize": "",
                    "libs": [],
                    "x": 1080,
                    "y": 200,
                    "wires": [
                        [
                            "c7f18bb5735b986f"
                        ]
                    ]
                },
                {
                    "id": "5f5f0afbf22fe52b",
                    "type": "ioBroker out",
                    "z": "26771494c726dd85",
                    "name": "",
                    "topic": "",
                    "ack": "true",
                    "autoCreate": "true",
                    "stateName": "",
                    "role": "",
                    "payloadType": "",
                    "readonly": "",
                    "stateUnit": "",
                    "stateMin": "",
                    "stateMax": "",
                    "x": 1460,
                    "y": 200,
                    "wires": []
                },
                {
                    "id": "c7f18bb5735b986f",
                    "type": "function",
                    "z": "26771494c726dd85",
                    "name": "function 3",
                    "func": "const battery = msg.payload;\n\nif (!battery || battery.battery === undefined) {\n    node.error(\"Ungültiges Battery-Objekt\", msg);\n    return null;\n}\n\nconst batteryId = battery.battery;\n\nconst states = [\n    {\n        id: \"voltage\",\n        value: battery.volt,\n        name: \"Voltage\",\n        role: \"value.voltage\",\n        type: \"number\",\n        readonly: true,\n        unit: \"mV\",\n        min: 0\n    },\n    {\n        id: \"temperature\",\n        value: battery.tempr / 1000,\n        name: \"Temperature\",\n        role: \"value.temperature\",\n        type: \"number\",\n        readonly: true,\n        unit: \"°C\"\n    },\n    {\n        id: \"baseState\",\n        value: battery.baseState,\n        name: \"Base State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"voltageState\",\n        value: battery.voltState,\n        name: \"Voltage State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"currentState\",\n        value: battery.currState,\n        name: \"Current State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"temperatureState\",\n        value: battery.tempState,\n        name: \"Temperature State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"charge\",\n        value: battery.coulomb,\n        name: \"Charge\",\n        role: \"value.battery\",\n        type: \"number\",\n        readonly: true,\n        unit: \"%\",\n        min: 0,\n        max: 100\n    },\n    {\n        id: \"capacity\",\n        value: battery.capacity,\n        name: \"Capacity\",\n        role: \"value\",\n        type: \"number\",\n        readonly: true,\n        unit: \"mAh\",\n        min: 0\n    }\n];\n\nconst messages = [];\n\nfor (const state of states) {\n    const out = {\n        topic: `0_userdata.0.pytes.02.${batteryId}.${state.id}`,\n        payload: state.value,\n\n        stateName: state.name,\n        stateRole: state.role,\n        stateType: state.type,\n        stateReadonly: state.readonly\n    };\n\n    if (state.unit !== undefined) {\n        out.stateUnit = state.unit;\n    }\n\n    if (state.min !== undefined) {\n        out.stateMin = state.min;\n    }\n\n    if (state.max !== undefined) {\n        out.stateMax = state.max;\n    }\n\n    messages.push(out);\n}\n\nreturn [messages];",
                    "outputs": 1,
                    "timeout": 0,
                    "noerr": 0,
                    "initialize": "",
                    "finalize": "",
                    "libs": [],
                    "x": 1260,
                    "y": 200,
                    "wires": [
                        [
                            "5f5f0afbf22fe52b",
                            "3cce03774442db86"
                        ]
                    ]
                },
                {
                    "id": "aae8b0af1ff64ae1",
                    "type": "delay",
                    "z": "26771494c726dd85",
                    "name": "",
                    "pauseType": "delay",
                    "timeout": "2",
                    "timeoutUnits": "minutes",
                    "rate": "1",
                    "nbRateUnits": "1",
                    "rateUnits": "second",
                    "randomFirst": "1",
                    "randomLast": "5",
                    "randomUnits": "seconds",
                    "drop": false,
                    "allowrate": false,
                    "outputs": 1,
                    "x": 520,
                    "y": 340,
                    "wires": [
                        [
                            "085f008ec32136f1"
                        ]
                    ]
                },
                {
                    "id": "acfcfbc9dab48c55",
                    "type": "debug",
                    "z": "26771494c726dd85",
                    "name": "debug 5",
                    "active": false,
                    "tosidebar": true,
                    "console": false,
                    "tostatus": false,
                    "complete": "true",
                    "targetType": "full",
                    "statusVal": "",
                    "statusType": "auto",
                    "x": 1440,
                    "y": 400,
                    "wires": []
                },
                {
                    "id": "085f008ec32136f1",
                    "type": "trigger",
                    "z": "26771494c726dd85",
                    "name": "bat 3",
                    "op1": "bat 3",
                    "op2": "",
                    "op1type": "str",
                    "op2type": "nul",
                    "duration": "250",
                    "extend": false,
                    "overrideDelay": false,
                    "units": "ms",
                    "reset": "",
                    "bytopic": "all",
                    "topic": "topic",
                    "outputs": 1,
                    "x": 730,
                    "y": 340,
                    "wires": [
                        [
                            "7134518ae47c75db"
                        ]
                    ]
                },
                {
                    "id": "7134518ae47c75db",
                    "type": "serial request",
                    "z": "26771494c726dd85",
                    "name": "BMSMaster",
                    "serial": "d031dd424e7b1ff2",
                    "x": 890,
                    "y": 340,
                    "wires": [
                        [
                            "2819be0b93263306"
                        ]
                    ]
                },
                {
                    "id": "2819be0b93263306",
                    "type": "function",
                    "z": "26771494c726dd85",
                    "name": "convert to msgs",
                    "func": "const text = msg.payload;\n\nif (typeof text !== \"string\") {\n    node.error(\"msg.payload ist kein String\", msg);\n    return null;\n}\n\n// In einzelne Zeilen zerlegen\nconst lines = text\n    .split(/\\r?\\n/)\n    .map(line => line.trim())\n    .filter(line => line !== \"\");\n\n// Nur Zeilen berücksichtigen, die mit einer Batterienummer beginnen\nconst dataLines = lines.filter(line => /^\\d+\\s/.test(line));\n\nconst messages = [];\n\nfor (const line of dataLines) {\n\n    // Spalten sind durch mindestens 2 Leerzeichen getrennt\n    const columns = line.split(/\\s{2,}/);\n\n    if (columns.length < 9) {\n        node.warn(\"Zeile konnte nicht verarbeitet werden: \" + line);\n        continue;\n    }\n\n    const battery = {\n        battery: Number(columns[0]),\n        volt: Number(columns[1]),\n        tempr: Number(columns[2]),\n        baseState: columns[3],\n        voltState: columns[4],\n        currState: columns[5],\n        tempState: columns[6],\n        coulomb: Number(columns[7].replace(\"%\", \"\")),\n        capacity: Number(columns[8].replace(/[^\\d]/g, \"\"))\n    };\n\n    messages.push({\n        ...msg,\n        payload: battery\n    });\n}\n\n// Alle Nachrichten nacheinander über denselben Ausgang senden\nreturn [messages];",
                    "outputs": 1,
                    "timeout": 0,
                    "noerr": 0,
                    "initialize": "",
                    "finalize": "",
                    "libs": [],
                    "x": 1080,
                    "y": 340,
                    "wires": [
                        [
                            "ca02643445158e40"
                        ]
                    ]
                },
                {
                    "id": "ea0794a8642caf84",
                    "type": "ioBroker out",
                    "z": "26771494c726dd85",
                    "name": "",
                    "topic": "",
                    "ack": "true",
                    "autoCreate": "true",
                    "stateName": "",
                    "role": "",
                    "payloadType": "",
                    "readonly": "",
                    "stateUnit": "",
                    "stateMin": "",
                    "stateMax": "",
                    "x": 1460,
                    "y": 340,
                    "wires": []
                },
                {
                    "id": "ca02643445158e40",
                    "type": "function",
                    "z": "26771494c726dd85",
                    "name": "function 4",
                    "func": "const battery = msg.payload;\n\nif (!battery || battery.battery === undefined) {\n    node.error(\"Ungültiges Battery-Objekt\", msg);\n    return null;\n}\n\nconst batteryId = battery.battery;\n\nconst states = [\n    {\n        id: \"voltage\",\n        value: battery.volt,\n        name: \"Voltage\",\n        role: \"value.voltage\",\n        type: \"number\",\n        readonly: true,\n        unit: \"mV\",\n        min: 0\n    },\n    {\n        id: \"temperature\",\n        value: battery.tempr / 1000,\n        name: \"Temperature\",\n        role: \"value.temperature\",\n        type: \"number\",\n        readonly: true,\n        unit: \"°C\"\n    },\n    {\n        id: \"baseState\",\n        value: battery.baseState,\n        name: \"Base State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"voltageState\",\n        value: battery.voltState,\n        name: \"Voltage State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"currentState\",\n        value: battery.currState,\n        name: \"Current State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"temperatureState\",\n        value: battery.tempState,\n        name: \"Temperature State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"charge\",\n        value: battery.coulomb,\n        name: \"Charge\",\n        role: \"value.battery\",\n        type: \"number\",\n        readonly: true,\n        unit: \"%\",\n        min: 0,\n        max: 100\n    },\n    {\n        id: \"capacity\",\n        value: battery.capacity,\n        name: \"Capacity\",\n        role: \"value\",\n        type: \"number\",\n        readonly: true,\n        unit: \"mAh\",\n        min: 0\n    }\n];\n\nconst messages = [];\n\nfor (const state of states) {\n    const out = {\n        topic: `0_userdata.0.pytes.03.${batteryId}.${state.id}`,\n        payload: state.value,\n\n        stateName: state.name,\n        stateRole: state.role,\n        stateType: state.type,\n        stateReadonly: state.readonly\n    };\n\n    if (state.unit !== undefined) {\n        out.stateUnit = state.unit;\n    }\n\n    if (state.min !== undefined) {\n        out.stateMin = state.min;\n    }\n\n    if (state.max !== undefined) {\n        out.stateMax = state.max;\n    }\n\n    messages.push(out);\n}\n\nreturn [messages];",
                    "outputs": 1,
                    "timeout": 0,
                    "noerr": 0,
                    "initialize": "",
                    "finalize": "",
                    "libs": [],
                    "x": 1260,
                    "y": 340,
                    "wires": [
                        [
                            "ea0794a8642caf84",
                            "acfcfbc9dab48c55"
                        ]
                    ]
                },
                {
                    "id": "6df4f9bd092fdcd3",
                    "type": "delay",
                    "z": "26771494c726dd85",
                    "name": "",
                    "pauseType": "delay",
                    "timeout": "3",
                    "timeoutUnits": "minutes",
                    "rate": "1",
                    "nbRateUnits": "1",
                    "rateUnits": "second",
                    "randomFirst": "1",
                    "randomLast": "5",
                    "randomUnits": "seconds",
                    "drop": false,
                    "allowrate": false,
                    "outputs": 1,
                    "x": 520,
                    "y": 480,
                    "wires": [
                        [
                            "a832dedddd9504c7"
                        ]
                    ]
                },
                {
                    "id": "b7c07a571002ad06",
                    "type": "debug",
                    "z": "26771494c726dd85",
                    "name": "debug 6",
                    "active": false,
                    "tosidebar": true,
                    "console": false,
                    "tostatus": false,
                    "complete": "true",
                    "targetType": "full",
                    "statusVal": "",
                    "statusType": "auto",
                    "x": 1440,
                    "y": 540,
                    "wires": []
                },
                {
                    "id": "a832dedddd9504c7",
                    "type": "trigger",
                    "z": "26771494c726dd85",
                    "name": "bat 4",
                    "op1": "bat 4",
                    "op2": "",
                    "op1type": "str",
                    "op2type": "nul",
                    "duration": "250",
                    "extend": false,
                    "overrideDelay": false,
                    "units": "ms",
                    "reset": "",
                    "bytopic": "all",
                    "topic": "topic",
                    "outputs": 1,
                    "x": 730,
                    "y": 480,
                    "wires": [
                        [
                            "b82258c553850a68"
                        ]
                    ]
                },
                {
                    "id": "b82258c553850a68",
                    "type": "serial request",
                    "z": "26771494c726dd85",
                    "name": "BMSMaster",
                    "serial": "d031dd424e7b1ff2",
                    "x": 890,
                    "y": 480,
                    "wires": [
                        [
                            "4387216c1822cbcf"
                        ]
                    ]
                },
                {
                    "id": "4387216c1822cbcf",
                    "type": "function",
                    "z": "26771494c726dd85",
                    "name": "convert to msgs",
                    "func": "const text = msg.payload;\n\nif (typeof text !== \"string\") {\n    node.error(\"msg.payload ist kein String\", msg);\n    return null;\n}\n\n// In einzelne Zeilen zerlegen\nconst lines = text\n    .split(/\\r?\\n/)\n    .map(line => line.trim())\n    .filter(line => line !== \"\");\n\n// Nur Zeilen berücksichtigen, die mit einer Batterienummer beginnen\nconst dataLines = lines.filter(line => /^\\d+\\s/.test(line));\n\nconst messages = [];\n\nfor (const line of dataLines) {\n\n    // Spalten sind durch mindestens 2 Leerzeichen getrennt\n    const columns = line.split(/\\s{2,}/);\n\n    if (columns.length < 9) {\n        node.warn(\"Zeile konnte nicht verarbeitet werden: \" + line);\n        continue;\n    }\n\n    const battery = {\n        battery: Number(columns[0]),\n        volt: Number(columns[1]),\n        tempr: Number(columns[2]),\n        baseState: columns[3],\n        voltState: columns[4],\n        currState: columns[5],\n        tempState: columns[6],\n        coulomb: Number(columns[7].replace(\"%\", \"\")),\n        capacity: Number(columns[8].replace(/[^\\d]/g, \"\"))\n    };\n\n    messages.push({\n        ...msg,\n        payload: battery\n    });\n}\n\n// Alle Nachrichten nacheinander über denselben Ausgang senden\nreturn [messages];",
                    "outputs": 1,
                    "timeout": 0,
                    "noerr": 0,
                    "initialize": "",
                    "finalize": "",
                    "libs": [],
                    "x": 1080,
                    "y": 480,
                    "wires": [
                        [
                            "94e6b42f7309c443"
                        ]
                    ]
                },
                {
                    "id": "51c2e01cf0878450",
                    "type": "ioBroker out",
                    "z": "26771494c726dd85",
                    "name": "",
                    "topic": "",
                    "ack": "true",
                    "autoCreate": "true",
                    "stateName": "",
                    "role": "",
                    "payloadType": "",
                    "readonly": "",
                    "stateUnit": "",
                    "stateMin": "",
                    "stateMax": "",
                    "x": 1460,
                    "y": 480,
                    "wires": []
                },
                {
                    "id": "94e6b42f7309c443",
                    "type": "function",
                    "z": "26771494c726dd85",
                    "name": "function 5",
                    "func": "const battery = msg.payload;\n\nif (!battery || battery.battery === undefined) {\n    node.error(\"Ungültiges Battery-Objekt\", msg);\n    return null;\n}\n\nconst batteryId = battery.battery;\n\nconst states = [\n    {\n        id: \"voltage\",\n        value: battery.volt,\n        name: \"Voltage\",\n        role: \"value.voltage\",\n        type: \"number\",\n        readonly: true,\n        unit: \"mV\",\n        min: 0\n    },\n    {\n        id: \"temperature\",\n        value: battery.tempr / 1000,\n        name: \"Temperature\",\n        role: \"value.temperature\",\n        type: \"number\",\n        readonly: true,\n        unit: \"°C\"\n    },\n    {\n        id: \"baseState\",\n        value: battery.baseState,\n        name: \"Base State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"voltageState\",\n        value: battery.voltState,\n        name: \"Voltage State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"currentState\",\n        value: battery.currState,\n        name: \"Current State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"temperatureState\",\n        value: battery.tempState,\n        name: \"Temperature State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"charge\",\n        value: battery.coulomb,\n        name: \"Charge\",\n        role: \"value.battery\",\n        type: \"number\",\n        readonly: true,\n        unit: \"%\",\n        min: 0,\n        max: 100\n    },\n    {\n        id: \"capacity\",\n        value: battery.capacity,\n        name: \"Capacity\",\n        role: \"value\",\n        type: \"number\",\n        readonly: true,\n        unit: \"mAh\",\n        min: 0\n    }\n];\n\nconst messages = [];\n\nfor (const state of states) {\n    const out = {\n        topic: `0_userdata.0.pytes.04.${batteryId}.${state.id}`,\n        payload: state.value,\n\n        stateName: state.name,\n        stateRole: state.role,\n        stateType: state.type,\n        stateReadonly: state.readonly\n    };\n\n    if (state.unit !== undefined) {\n        out.stateUnit = state.unit;\n    }\n\n    if (state.min !== undefined) {\n        out.stateMin = state.min;\n    }\n\n    if (state.max !== undefined) {\n        out.stateMax = state.max;\n    }\n\n    messages.push(out);\n}\n\nreturn [messages];",
                    "outputs": 1,
                    "timeout": 0,
                    "noerr": 0,
                    "initialize": "",
                    "finalize": "",
                    "libs": [],
                    "x": 1260,
                    "y": 480,
                    "wires": [
                        [
                            "51c2e01cf0878450",
                            "b7c07a571002ad06"
                        ]
                    ]
                },
                {
                    "id": "d81970d6d1e4cca6",
                    "type": "delay",
                    "z": "26771494c726dd85",
                    "name": "",
                    "pauseType": "delay",
                    "timeout": "4",
                    "timeoutUnits": "minutes",
                    "rate": "1",
                    "nbRateUnits": "1",
                    "rateUnits": "second",
                    "randomFirst": "1",
                    "randomLast": "5",
                    "randomUnits": "seconds",
                    "drop": false,
                    "allowrate": false,
                    "outputs": 1,
                    "x": 520,
                    "y": 620,
                    "wires": [
                        [
                            "f1fd5ef8888380ad"
                        ]
                    ]
                },
                {
                    "id": "fb84ec681c169cd6",
                    "type": "debug",
                    "z": "26771494c726dd85",
                    "name": "debug 7",
                    "active": false,
                    "tosidebar": true,
                    "console": false,
                    "tostatus": false,
                    "complete": "true",
                    "targetType": "full",
                    "statusVal": "",
                    "statusType": "auto",
                    "x": 1440,
                    "y": 680,
                    "wires": []
                },
                {
                    "id": "f1fd5ef8888380ad",
                    "type": "trigger",
                    "z": "26771494c726dd85",
                    "name": "bat 5",
                    "op1": "bat 5",
                    "op2": "",
                    "op1type": "str",
                    "op2type": "nul",
                    "duration": "250",
                    "extend": false,
                    "overrideDelay": false,
                    "units": "ms",
                    "reset": "",
                    "bytopic": "all",
                    "topic": "topic",
                    "outputs": 1,
                    "x": 730,
                    "y": 620,
                    "wires": [
                        [
                            "75f9d95891961faf"
                        ]
                    ]
                },
                {
                    "id": "75f9d95891961faf",
                    "type": "serial request",
                    "z": "26771494c726dd85",
                    "name": "BMSMaster",
                    "serial": "d031dd424e7b1ff2",
                    "x": 890,
                    "y": 620,
                    "wires": [
                        [
                            "c4b473ff613b76e2"
                        ]
                    ]
                },
                {
                    "id": "c4b473ff613b76e2",
                    "type": "function",
                    "z": "26771494c726dd85",
                    "name": "convert to msgs",
                    "func": "const text = msg.payload;\n\nif (typeof text !== \"string\") {\n    node.error(\"msg.payload ist kein String\", msg);\n    return null;\n}\n\n// In einzelne Zeilen zerlegen\nconst lines = text\n    .split(/\\r?\\n/)\n    .map(line => line.trim())\n    .filter(line => line !== \"\");\n\n// Nur Zeilen berücksichtigen, die mit einer Batterienummer beginnen\nconst dataLines = lines.filter(line => /^\\d+\\s/.test(line));\n\nconst messages = [];\n\nfor (const line of dataLines) {\n\n    // Spalten sind durch mindestens 2 Leerzeichen getrennt\n    const columns = line.split(/\\s{2,}/);\n\n    if (columns.length < 9) {\n        node.warn(\"Zeile konnte nicht verarbeitet werden: \" + line);\n        continue;\n    }\n\n    const battery = {\n        battery: Number(columns[0]),\n        volt: Number(columns[1]),\n        tempr: Number(columns[2]),\n        baseState: columns[3],\n        voltState: columns[4],\n        currState: columns[5],\n        tempState: columns[6],\n        coulomb: Number(columns[7].replace(\"%\", \"\")),\n        capacity: Number(columns[8].replace(/[^\\d]/g, \"\"))\n    };\n\n    messages.push({\n        ...msg,\n        payload: battery\n    });\n}\n\n// Alle Nachrichten nacheinander über denselben Ausgang senden\nreturn [messages];",
                    "outputs": 1,
                    "timeout": 0,
                    "noerr": 0,
                    "initialize": "",
                    "finalize": "",
                    "libs": [],
                    "x": 1080,
                    "y": 620,
                    "wires": [
                        [
                            "4603fd0d509f8f04"
                        ]
                    ]
                },
                {
                    "id": "d35fbb5808f3ecae",
                    "type": "ioBroker out",
                    "z": "26771494c726dd85",
                    "name": "",
                    "topic": "",
                    "ack": "true",
                    "autoCreate": "true",
                    "stateName": "",
                    "role": "",
                    "payloadType": "",
                    "readonly": "",
                    "stateUnit": "",
                    "stateMin": "",
                    "stateMax": "",
                    "x": 1460,
                    "y": 620,
                    "wires": []
                },
                {
                    "id": "4603fd0d509f8f04",
                    "type": "function",
                    "z": "26771494c726dd85",
                    "name": "function 6",
                    "func": "const battery = msg.payload;\n\nif (!battery || battery.battery === undefined) {\n    node.error(\"Ungültiges Battery-Objekt\", msg);\n    return null;\n}\n\nconst batteryId = battery.battery;\n\nconst states = [\n    {\n        id: \"voltage\",\n        value: battery.volt,\n        name: \"Voltage\",\n        role: \"value.voltage\",\n        type: \"number\",\n        readonly: true,\n        unit: \"mV\",\n        min: 0\n    },\n    {\n        id: \"temperature\",\n        value: battery.tempr / 1000,\n        name: \"Temperature\",\n        role: \"value.temperature\",\n        type: \"number\",\n        readonly: true,\n        unit: \"°C\"\n    },\n    {\n        id: \"baseState\",\n        value: battery.baseState,\n        name: \"Base State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"voltageState\",\n        value: battery.voltState,\n        name: \"Voltage State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"currentState\",\n        value: battery.currState,\n        name: \"Current State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"temperatureState\",\n        value: battery.tempState,\n        name: \"Temperature State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"charge\",\n        value: battery.coulomb,\n        name: \"Charge\",\n        role: \"value.battery\",\n        type: \"number\",\n        readonly: true,\n        unit: \"%\",\n        min: 0,\n        max: 100\n    },\n    {\n        id: \"capacity\",\n        value: battery.capacity,\n        name: \"Capacity\",\n        role: \"value\",\n        type: \"number\",\n        readonly: true,\n        unit: \"mAh\",\n        min: 0\n    }\n];\n\nconst messages = [];\n\nfor (const state of states) {\n    const out = {\n        topic: `0_userdata.0.pytes.05.${batteryId}.${state.id}`,\n        payload: state.value,\n\n        stateName: state.name,\n        stateRole: state.role,\n        stateType: state.type,\n        stateReadonly: state.readonly\n    };\n\n    if (state.unit !== undefined) {\n        out.stateUnit = state.unit;\n    }\n\n    if (state.min !== undefined) {\n        out.stateMin = state.min;\n    }\n\n    if (state.max !== undefined) {\n        out.stateMax = state.max;\n    }\n\n    messages.push(out);\n}\n\nreturn [messages];",
                    "outputs": 1,
                    "timeout": 0,
                    "noerr": 0,
                    "initialize": "",
                    "finalize": "",
                    "libs": [],
                    "x": 1260,
                    "y": 620,
                    "wires": [
                        [
                            "d35fbb5808f3ecae",
                            "fb84ec681c169cd6"
                        ]
                    ]
                },
                {
                    "id": "c8cc5a91dbf6eb1a",
                    "type": "delay",
                    "z": "26771494c726dd85",
                    "name": "",
                    "pauseType": "delay",
                    "timeout": "5",
                    "timeoutUnits": "minutes",
                    "rate": "1",
                    "nbRateUnits": "1",
                    "rateUnits": "second",
                    "randomFirst": "1",
                    "randomLast": "5",
                    "randomUnits": "seconds",
                    "drop": false,
                    "allowrate": false,
                    "outputs": 1,
                    "x": 520,
                    "y": 760,
                    "wires": [
                        [
                            "188d8b0ef9b1ec1c"
                        ]
                    ]
                },
                {
                    "id": "810cc1a467a83b14",
                    "type": "debug",
                    "z": "26771494c726dd85",
                    "name": "debug 8",
                    "active": false,
                    "tosidebar": true,
                    "console": false,
                    "tostatus": false,
                    "complete": "true",
                    "targetType": "full",
                    "statusVal": "",
                    "statusType": "auto",
                    "x": 1440,
                    "y": 820,
                    "wires": []
                },
                {
                    "id": "188d8b0ef9b1ec1c",
                    "type": "trigger",
                    "z": "26771494c726dd85",
                    "name": "bat 6",
                    "op1": "bat 6",
                    "op2": "",
                    "op1type": "str",
                    "op2type": "nul",
                    "duration": "250",
                    "extend": false,
                    "overrideDelay": false,
                    "units": "ms",
                    "reset": "",
                    "bytopic": "all",
                    "topic": "topic",
                    "outputs": 1,
                    "x": 730,
                    "y": 760,
                    "wires": [
                        [
                            "2fd087fa4da3841b"
                        ]
                    ]
                },
                {
                    "id": "2fd087fa4da3841b",
                    "type": "serial request",
                    "z": "26771494c726dd85",
                    "name": "BMSMaster",
                    "serial": "d031dd424e7b1ff2",
                    "x": 890,
                    "y": 760,
                    "wires": [
                        [
                            "59e325c588ae2c94"
                        ]
                    ]
                },
                {
                    "id": "59e325c588ae2c94",
                    "type": "function",
                    "z": "26771494c726dd85",
                    "name": "convert to msgs",
                    "func": "const text = msg.payload;\n\nif (typeof text !== \"string\") {\n    node.error(\"msg.payload ist kein String\", msg);\n    return null;\n}\n\n// In einzelne Zeilen zerlegen\nconst lines = text\n    .split(/\\r?\\n/)\n    .map(line => line.trim())\n    .filter(line => line !== \"\");\n\n// Nur Zeilen berücksichtigen, die mit einer Batterienummer beginnen\nconst dataLines = lines.filter(line => /^\\d+\\s/.test(line));\n\nconst messages = [];\n\nfor (const line of dataLines) {\n\n    // Spalten sind durch mindestens 2 Leerzeichen getrennt\n    const columns = line.split(/\\s{2,}/);\n\n    if (columns.length < 9) {\n        node.warn(\"Zeile konnte nicht verarbeitet werden: \" + line);\n        continue;\n    }\n\n    const battery = {\n        battery: Number(columns[0]),\n        volt: Number(columns[1]),\n        tempr: Number(columns[2]),\n        baseState: columns[3],\n        voltState: columns[4],\n        currState: columns[5],\n        tempState: columns[6],\n        coulomb: Number(columns[7].replace(\"%\", \"\")),\n        capacity: Number(columns[8].replace(/[^\\d]/g, \"\"))\n    };\n\n    messages.push({\n        ...msg,\n        payload: battery\n    });\n}\n\n// Alle Nachrichten nacheinander über denselben Ausgang senden\nreturn [messages];",
                    "outputs": 1,
                    "timeout": 0,
                    "noerr": 0,
                    "initialize": "",
                    "finalize": "",
                    "libs": [],
                    "x": 1080,
                    "y": 760,
                    "wires": [
                        [
                            "5d321ccd3cdb9ce7"
                        ]
                    ]
                },
                {
                    "id": "b60baba38d523d1e",
                    "type": "ioBroker out",
                    "z": "26771494c726dd85",
                    "name": "",
                    "topic": "",
                    "ack": "true",
                    "autoCreate": "true",
                    "stateName": "",
                    "role": "",
                    "payloadType": "",
                    "readonly": "",
                    "stateUnit": "",
                    "stateMin": "",
                    "stateMax": "",
                    "x": 1460,
                    "y": 760,
                    "wires": []
                },
                {
                    "id": "5d321ccd3cdb9ce7",
                    "type": "function",
                    "z": "26771494c726dd85",
                    "name": "function 7",
                    "func": "const battery = msg.payload;\n\nif (!battery || battery.battery === undefined) {\n    node.error(\"Ungültiges Battery-Objekt\", msg);\n    return null;\n}\n\nconst batteryId = battery.battery;\n\nconst states = [\n    {\n        id: \"voltage\",\n        value: battery.volt,\n        name: \"Voltage\",\n        role: \"value.voltage\",\n        type: \"number\",\n        readonly: true,\n        unit: \"mV\",\n        min: 0\n    },\n    {\n        id: \"temperature\",\n        value: battery.tempr / 1000,\n        name: \"Temperature\",\n        role: \"value.temperature\",\n        type: \"number\",\n        readonly: true,\n        unit: \"°C\"\n    },\n    {\n        id: \"baseState\",\n        value: battery.baseState,\n        name: \"Base State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"voltageState\",\n        value: battery.voltState,\n        name: \"Voltage State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"currentState\",\n        value: battery.currState,\n        name: \"Current State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"temperatureState\",\n        value: battery.tempState,\n        name: \"Temperature State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"charge\",\n        value: battery.coulomb,\n        name: \"Charge\",\n        role: \"value.battery\",\n        type: \"number\",\n        readonly: true,\n        unit: \"%\",\n        min: 0,\n        max: 100\n    },\n    {\n        id: \"capacity\",\n        value: battery.capacity,\n        name: \"Capacity\",\n        role: \"value\",\n        type: \"number\",\n        readonly: true,\n        unit: \"mAh\",\n        min: 0\n    }\n];\n\nconst messages = [];\n\nfor (const state of states) {\n    const out = {\n        topic: `0_userdata.0.pytes.06.${batteryId}.${state.id}`,\n        payload: state.value,\n\n        stateName: state.name,\n        stateRole: state.role,\n        stateType: state.type,\n        stateReadonly: state.readonly\n    };\n\n    if (state.unit !== undefined) {\n        out.stateUnit = state.unit;\n    }\n\n    if (state.min !== undefined) {\n        out.stateMin = state.min;\n    }\n\n    if (state.max !== undefined) {\n        out.stateMax = state.max;\n    }\n\n    messages.push(out);\n}\n\nreturn [messages];",
                    "outputs": 1,
                    "timeout": 0,
                    "noerr": 0,
                    "initialize": "",
                    "finalize": "",
                    "libs": [],
                    "x": 1260,
                    "y": 760,
                    "wires": [
                        [
                            "b60baba38d523d1e",
                            "810cc1a467a83b14"
                        ]
                    ]
                },
                {
                    "id": "09faeaa564e7d7ea",
                    "type": "delay",
                    "z": "26771494c726dd85",
                    "name": "",
                    "pauseType": "delay",
                    "timeout": "6",
                    "timeoutUnits": "minutes",
                    "rate": "1",
                    "nbRateUnits": "1",
                    "rateUnits": "second",
                    "randomFirst": "1",
                    "randomLast": "5",
                    "randomUnits": "seconds",
                    "drop": false,
                    "allowrate": false,
                    "outputs": 1,
                    "x": 520,
                    "y": 900,
                    "wires": [
                        [
                            "c0c69b8e170813f8"
                        ]
                    ]
                },
                {
                    "id": "0e613121bc95e046",
                    "type": "debug",
                    "z": "26771494c726dd85",
                    "name": "debug 9",
                    "active": false,
                    "tosidebar": true,
                    "console": false,
                    "tostatus": false,
                    "complete": "true",
                    "targetType": "full",
                    "statusVal": "",
                    "statusType": "auto",
                    "x": 1440,
                    "y": 960,
                    "wires": []
                },
                {
                    "id": "c0c69b8e170813f8",
                    "type": "trigger",
                    "z": "26771494c726dd85",
                    "name": "bat 7",
                    "op1": "bat 7",
                    "op2": "",
                    "op1type": "str",
                    "op2type": "nul",
                    "duration": "250",
                    "extend": false,
                    "overrideDelay": false,
                    "units": "ms",
                    "reset": "",
                    "bytopic": "all",
                    "topic": "topic",
                    "outputs": 1,
                    "x": 730,
                    "y": 900,
                    "wires": [
                        [
                            "5e45ba1558c0e2c5"
                        ]
                    ]
                },
                {
                    "id": "5e45ba1558c0e2c5",
                    "type": "serial request",
                    "z": "26771494c726dd85",
                    "name": "BMSMaster",
                    "serial": "d031dd424e7b1ff2",
                    "x": 890,
                    "y": 900,
                    "wires": [
                        [
                            "56d333a3d08a8b60"
                        ]
                    ]
                },
                {
                    "id": "56d333a3d08a8b60",
                    "type": "function",
                    "z": "26771494c726dd85",
                    "name": "convert to msgs",
                    "func": "const text = msg.payload;\n\nif (typeof text !== \"string\") {\n    node.error(\"msg.payload ist kein String\", msg);\n    return null;\n}\n\n// In einzelne Zeilen zerlegen\nconst lines = text\n    .split(/\\r?\\n/)\n    .map(line => line.trim())\n    .filter(line => line !== \"\");\n\n// Nur Zeilen berücksichtigen, die mit einer Batterienummer beginnen\nconst dataLines = lines.filter(line => /^\\d+\\s/.test(line));\n\nconst messages = [];\n\nfor (const line of dataLines) {\n\n    // Spalten sind durch mindestens 2 Leerzeichen getrennt\n    const columns = line.split(/\\s{2,}/);\n\n    if (columns.length < 9) {\n        node.warn(\"Zeile konnte nicht verarbeitet werden: \" + line);\n        continue;\n    }\n\n    const battery = {\n        battery: Number(columns[0]),\n        volt: Number(columns[1]),\n        tempr: Number(columns[2]),\n        baseState: columns[3],\n        voltState: columns[4],\n        currState: columns[5],\n        tempState: columns[6],\n        coulomb: Number(columns[7].replace(\"%\", \"\")),\n        capacity: Number(columns[8].replace(/[^\\d]/g, \"\"))\n    };\n\n    messages.push({\n        ...msg,\n        payload: battery\n    });\n}\n\n// Alle Nachrichten nacheinander über denselben Ausgang senden\nreturn [messages];",
                    "outputs": 1,
                    "timeout": 0,
                    "noerr": 0,
                    "initialize": "",
                    "finalize": "",
                    "libs": [],
                    "x": 1080,
                    "y": 900,
                    "wires": [
                        [
                            "8dc1347bba1166d9"
                        ]
                    ]
                },
                {
                    "id": "a2f16c5161ec9254",
                    "type": "ioBroker out",
                    "z": "26771494c726dd85",
                    "name": "",
                    "topic": "",
                    "ack": "true",
                    "autoCreate": "true",
                    "stateName": "",
                    "role": "",
                    "payloadType": "",
                    "readonly": "",
                    "stateUnit": "",
                    "stateMin": "",
                    "stateMax": "",
                    "x": 1460,
                    "y": 900,
                    "wires": []
                },
                {
                    "id": "8dc1347bba1166d9",
                    "type": "function",
                    "z": "26771494c726dd85",
                    "name": "function 8",
                    "func": "const battery = msg.payload;\n\nif (!battery || battery.battery === undefined) {\n    node.error(\"Ungültiges Battery-Objekt\", msg);\n    return null;\n}\n\nconst batteryId = battery.battery;\n\nconst states = [\n    {\n        id: \"voltage\",\n        value: battery.volt,\n        name: \"Voltage\",\n        role: \"value.voltage\",\n        type: \"number\",\n        readonly: true,\n        unit: \"mV\",\n        min: 0\n    },\n    {\n        id: \"temperature\",\n        value: battery.tempr / 1000,\n        name: \"Temperature\",\n        role: \"value.temperature\",\n        type: \"number\",\n        readonly: true,\n        unit: \"°C\"\n    },\n    {\n        id: \"baseState\",\n        value: battery.baseState,\n        name: \"Base State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"voltageState\",\n        value: battery.voltState,\n        name: \"Voltage State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"currentState\",\n        value: battery.currState,\n        name: \"Current State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"temperatureState\",\n        value: battery.tempState,\n        name: \"Temperature State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"charge\",\n        value: battery.coulomb,\n        name: \"Charge\",\n        role: \"value.battery\",\n        type: \"number\",\n        readonly: true,\n        unit: \"%\",\n        min: 0,\n        max: 100\n    },\n    {\n        id: \"capacity\",\n        value: battery.capacity,\n        name: \"Capacity\",\n        role: \"value\",\n        type: \"number\",\n        readonly: true,\n        unit: \"mAh\",\n        min: 0\n    }\n];\n\nconst messages = [];\n\nfor (const state of states) {\n    const out = {\n        topic: `0_userdata.0.pytes.07.${batteryId}.${state.id}`,\n        payload: state.value,\n\n        stateName: state.name,\n        stateRole: state.role,\n        stateType: state.type,\n        stateReadonly: state.readonly\n    };\n\n    if (state.unit !== undefined) {\n        out.stateUnit = state.unit;\n    }\n\n    if (state.min !== undefined) {\n        out.stateMin = state.min;\n    }\n\n    if (state.max !== undefined) {\n        out.stateMax = state.max;\n    }\n\n    messages.push(out);\n}\n\nreturn [messages];",
                    "outputs": 1,
                    "timeout": 0,
                    "noerr": 0,
                    "initialize": "",
                    "finalize": "",
                    "libs": [],
                    "x": 1260,
                    "y": 900,
                    "wires": [
                        [
                            "a2f16c5161ec9254",
                            "0e613121bc95e046"
                        ]
                    ]
                },
                {
                    "id": "027109f5112c3c3e",
                    "type": "delay",
                    "z": "26771494c726dd85",
                    "name": "",
                    "pauseType": "delay",
                    "timeout": "7",
                    "timeoutUnits": "minutes",
                    "rate": "1",
                    "nbRateUnits": "1",
                    "rateUnits": "second",
                    "randomFirst": "1",
                    "randomLast": "5",
                    "randomUnits": "seconds",
                    "drop": false,
                    "allowrate": false,
                    "outputs": 1,
                    "x": 520,
                    "y": 1040,
                    "wires": [
                        [
                            "98d31a678f60f56d"
                        ]
                    ]
                },
                {
                    "id": "8ed399995f0adf29",
                    "type": "debug",
                    "z": "26771494c726dd85",
                    "name": "debug 10",
                    "active": false,
                    "tosidebar": true,
                    "console": false,
                    "tostatus": false,
                    "complete": "true",
                    "targetType": "full",
                    "statusVal": "",
                    "statusType": "auto",
                    "x": 1440,
                    "y": 1100,
                    "wires": []
                },
                {
                    "id": "98d31a678f60f56d",
                    "type": "trigger",
                    "z": "26771494c726dd85",
                    "name": "bat 8",
                    "op1": "bat 8",
                    "op2": "",
                    "op1type": "str",
                    "op2type": "nul",
                    "duration": "250",
                    "extend": false,
                    "overrideDelay": false,
                    "units": "ms",
                    "reset": "",
                    "bytopic": "all",
                    "topic": "topic",
                    "outputs": 1,
                    "x": 730,
                    "y": 1040,
                    "wires": [
                        [
                            "abed25adf4a19908"
                        ]
                    ]
                },
                {
                    "id": "abed25adf4a19908",
                    "type": "serial request",
                    "z": "26771494c726dd85",
                    "name": "BMSMaster",
                    "serial": "d031dd424e7b1ff2",
                    "x": 890,
                    "y": 1040,
                    "wires": [
                        [
                            "dfa2e714a883320c"
                        ]
                    ]
                },
                {
                    "id": "dfa2e714a883320c",
                    "type": "function",
                    "z": "26771494c726dd85",
                    "name": "convert to msgs",
                    "func": "const text = msg.payload;\n\nif (typeof text !== \"string\") {\n    node.error(\"msg.payload ist kein String\", msg);\n    return null;\n}\n\n// In einzelne Zeilen zerlegen\nconst lines = text\n    .split(/\\r?\\n/)\n    .map(line => line.trim())\n    .filter(line => line !== \"\");\n\n// Nur Zeilen berücksichtigen, die mit einer Batterienummer beginnen\nconst dataLines = lines.filter(line => /^\\d+\\s/.test(line));\n\nconst messages = [];\n\nfor (const line of dataLines) {\n\n    // Spalten sind durch mindestens 2 Leerzeichen getrennt\n    const columns = line.split(/\\s{2,}/);\n\n    if (columns.length < 9) {\n        node.warn(\"Zeile konnte nicht verarbeitet werden: \" + line);\n        continue;\n    }\n\n    const battery = {\n        battery: Number(columns[0]),\n        volt: Number(columns[1]),\n        tempr: Number(columns[2]),\n        baseState: columns[3],\n        voltState: columns[4],\n        currState: columns[5],\n        tempState: columns[6],\n        coulomb: Number(columns[7].replace(\"%\", \"\")),\n        capacity: Number(columns[8].replace(/[^\\d]/g, \"\"))\n    };\n\n    messages.push({\n        ...msg,\n        payload: battery\n    });\n}\n\n// Alle Nachrichten nacheinander über denselben Ausgang senden\nreturn [messages];",
                    "outputs": 1,
                    "timeout": 0,
                    "noerr": 0,
                    "initialize": "",
                    "finalize": "",
                    "libs": [],
                    "x": 1080,
                    "y": 1040,
                    "wires": [
                        [
                            "4127ce3ea3ebf45b"
                        ]
                    ]
                },
                {
                    "id": "9d3e816f7aae72a8",
                    "type": "ioBroker out",
                    "z": "26771494c726dd85",
                    "name": "",
                    "topic": "",
                    "ack": "true",
                    "autoCreate": "true",
                    "stateName": "",
                    "role": "",
                    "payloadType": "",
                    "readonly": "",
                    "stateUnit": "",
                    "stateMin": "",
                    "stateMax": "",
                    "x": 1460,
                    "y": 1040,
                    "wires": []
                },
                {
                    "id": "4127ce3ea3ebf45b",
                    "type": "function",
                    "z": "26771494c726dd85",
                    "name": "function 9",
                    "func": "const battery = msg.payload;\n\nif (!battery || battery.battery === undefined) {\n    node.error(\"Ungültiges Battery-Objekt\", msg);\n    return null;\n}\n\nconst batteryId = battery.battery;\n\nconst states = [\n    {\n        id: \"voltage\",\n        value: battery.volt,\n        name: \"Voltage\",\n        role: \"value.voltage\",\n        type: \"number\",\n        readonly: true,\n        unit: \"mV\",\n        min: 0\n    },\n    {\n        id: \"temperature\",\n        value: battery.tempr / 1000,\n        name: \"Temperature\",\n        role: \"value.temperature\",\n        type: \"number\",\n        readonly: true,\n        unit: \"°C\"\n    },\n    {\n        id: \"baseState\",\n        value: battery.baseState,\n        name: \"Base State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"voltageState\",\n        value: battery.voltState,\n        name: \"Voltage State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"currentState\",\n        value: battery.currState,\n        name: \"Current State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"temperatureState\",\n        value: battery.tempState,\n        name: \"Temperature State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"charge\",\n        value: battery.coulomb,\n        name: \"Charge\",\n        role: \"value.battery\",\n        type: \"number\",\n        readonly: true,\n        unit: \"%\",\n        min: 0,\n        max: 100\n    },\n    {\n        id: \"capacity\",\n        value: battery.capacity,\n        name: \"Capacity\",\n        role: \"value\",\n        type: \"number\",\n        readonly: true,\n        unit: \"mAh\",\n        min: 0\n    }\n];\n\nconst messages = [];\n\nfor (const state of states) {\n    const out = {\n        topic: `0_userdata.0.pytes.08.${batteryId}.${state.id}`,\n        payload: state.value,\n\n        stateName: state.name,\n        stateRole: state.role,\n        stateType: state.type,\n        stateReadonly: state.readonly\n    };\n\n    if (state.unit !== undefined) {\n        out.stateUnit = state.unit;\n    }\n\n    if (state.min !== undefined) {\n        out.stateMin = state.min;\n    }\n\n    if (state.max !== undefined) {\n        out.stateMax = state.max;\n    }\n\n    messages.push(out);\n}\n\nreturn [messages];",
                    "outputs": 1,
                    "timeout": 0,
                    "noerr": 0,
                    "initialize": "",
                    "finalize": "",
                    "libs": [],
                    "x": 1260,
                    "y": 1040,
                    "wires": [
                        [
                            "9d3e816f7aae72a8",
                            "8ed399995f0adf29"
                        ]
                    ]
                },
                {
                    "id": "4b31f05c7b6c5425",
                    "type": "debug",
                    "z": "26771494c726dd85",
                    "name": "debug 11",
                    "active": false,
                    "tosidebar": true,
                    "console": false,
                    "tostatus": false,
                    "complete": "false",
                    "statusVal": "",
                    "statusType": "auto",
                    "x": 1060,
                    "y": 120,
                    "wires": []
                },
                {
                    "id": "d031dd424e7b1ff2",
                    "type": "serial-port",
                    "name": "Pytes",
                    "serialport": "/dev/serial/by-id/usb-FTDI_USB_Serial_Converter_FTFS8I5L-if00-port0",
                    "serialbaud": "115200",
                    "databits": 8,
                    "parity": "none",
                    "stopbits": 1,
                    "waitfor": "@",
                    "dtr": "none",
                    "rts": "none",
                    "cts": "none",
                    "dsr": "none",
                    "newline": "250",
                    "bin": "false",
                    "out": "time",
                    "addchar": "\\r\\n",
                    "responsetimeout": "250"
                },
                {
                    "id": "655fb8e61b544b29",
                    "type": "global-config",
                    "env": [],
                    "modules": {
                        "node-red-node-serialport": "2.0.3"
                    }
                }
            ]
            

            Es ist äusserst interessant, ich habe heute mal die Schnittstellen durchreichung in den Iobroker Proxmox LXC neu, mit den offiziellen Proxmox Werkzeugen neu gemacht. Dabei ist mir aufgefallen, das der Flow mehrere male sauber läuft, plötzlich kommt die Meldung:

            node-red.0
            	2026-08-15 16:54:00.757	error	Node-RED: 15 Aug 16:54:00 - [error] [function:convert to msgs] msg.payload ist kein String
            

            und auch im Flow wird dann beim entsprechenden Node aus einem "verbunden" ein "Timeout". Nach einem deaktivieren des ganzen Flow und deploy und anschliessendem aktivieren und deploy läuft er wieder ein paar Stunden ohne irgendwelche Probleme. Beim Fehler kommt scheinbar einfach keine Antwort mehr und der "function-Node" wirft dann den Fehler raus. Ist ja richtig und auch verständlich.

            Kann es sein, dass es mit meiner vervielfachung auch quasi mehrere offenen Schnittstellen Task gibt?

            Ich habe mich gefragt ob es allenfalls besser wäre trigger-Node so umzubauen das er eben nicht einfach nur den Text sendet, sondern das er quasi eine Liste mit den Texten abarbeitet. Oder das nach dem function Node ein zusätzlicher Node angestossen würde der die Schnittstelle schliesst? Nur da habe ich bis jetzt keinerlei Hinweise gefunden wie man eine solche serielle Schnittstelle schliessen kann.

            1 Antwort Letzte Antwort
            0
            • P Offline
              P Offline
              peterfido
              schrieb am zuletzt editiert von
              #46

              Ich habe das mangels Batterie nicht testen können.

              Das Skript geht die Batterien nach und nach durch und startet automatisch wieder, wenn ich die Verbindung unterbreche.

              Den Comport musste ich natürlich umbiegen.

              [
                  {
                      "id": "26771494c726dd85",
                      "type": "tab",
                      "label": "Pytes",
                      "disabled": false,
                      "info": "",
                      "env": []
                  },
                  {
                      "id": "fe3238beacae91ad",
                      "type": "junction",
                      "z": "26771494c726dd85",
                      "x": 340,
                      "y": 180,
                      "wires": [
                          [
                              "b28980471e986893",
                              "fdaee2e16d78cc87"
                          ]
                      ]
                  },
                  {
                      "id": "665e7ef72b226bc2",
                      "type": "junction",
                      "z": "26771494c726dd85",
                      "x": 780,
                      "y": 260,
                      "wires": [
                          [
                              "65a7b88c58ac941a"
                          ]
                      ]
                  },
                  {
                      "id": "65a7b88c58ac941a",
                      "type": "junction",
                      "z": "26771494c726dd85",
                      "x": 60,
                      "y": 260,
                      "wires": [
                          [
                              "6d9a8c4540741cbf"
                          ]
                      ]
                  },
                  {
                      "id": "79724f85531596e4",
                      "type": "function",
                      "z": "26771494c726dd85",
                      "name": "convert to msgs",
                      "func": "const text = msg.payload;\n\nif (typeof text !== \"string\") {\n    node.error(\"msg.payload ist kein String\", msg);\n    return null;\n}\n\n// In einzelne Zeilen zerlegen\nconst lines = text\n    .split(/\\r?\\n/)\n    .map(line => line.trim())\n    .filter(line => line !== \"\");\n\n// Nur Zeilen berücksichtigen, die mit einer Batterienummer beginnen\nconst dataLines = lines.filter(line => /^\\d+\\s/.test(line));\n\nconst messages = [];\n\nfor (const line of dataLines) {\n\n    // Spalten sind durch mindestens 2 Leerzeichen getrennt\n    const columns = line.split(/\\s{2,}/);\n\n    if (columns.length < 9) {\n        node.warn(\"Zeile konnte nicht verarbeitet werden: \" + line);\n        continue;\n    }\n\n    const battery = {\n        battery: Number(columns[0]),\n        volt: Number(columns[1]),\n        tempr: Number(columns[2]),\n        baseState: columns[3],\n        voltState: columns[4],\n        currState: columns[5],\n        tempState: columns[6],\n        coulomb: Number(columns[7].replace(\"%\", \"\")),\n        capacity: Number(columns[8].replace(/[^\\d]/g, \"\"))\n    };\n\n    messages.push({\n        ...msg,\n        payload: battery\n    });\n}\n\n// Alle Nachrichten nacheinander über denselben Ausgang senden\nreturn [messages];",
                      "outputs": 1,
                      "timeout": 0,
                      "noerr": 0,
                      "initialize": "",
                      "finalize": "",
                      "libs": [],
                      "x": 940,
                      "y": 80,
                      "wires": [
                          [
                              "4a8dcae7d0f7d8a8"
                          ]
                      ]
                  },
                  {
                      "id": "68c635b31d513d6d",
                      "type": "debug",
                      "z": "26771494c726dd85",
                      "name": "debug 4",
                      "active": true,
                      "tosidebar": true,
                      "console": false,
                      "tostatus": false,
                      "complete": "true",
                      "targetType": "full",
                      "statusVal": "",
                      "statusType": "auto",
                      "x": 1260,
                      "y": 160,
                      "wires": []
                  },
                  {
                      "id": "6a16c00e7b0e2997",
                      "type": "ioBroker out",
                      "z": "26771494c726dd85",
                      "name": "",
                      "topic": "",
                      "ack": "true",
                      "autoCreate": "true",
                      "stateName": "",
                      "role": "",
                      "payloadType": "",
                      "readonly": "",
                      "stateUnit": "",
                      "stateMin": "",
                      "stateMax": "",
                      "x": 1280,
                      "y": 80,
                      "wires": []
                  },
                  {
                      "id": "4a8dcae7d0f7d8a8",
                      "type": "function",
                      "z": "26771494c726dd85",
                      "name": "function 2",
                      "func": "const battery = msg.payload;\n\nif (!battery || battery.battery === undefined) {\n    node.error(\"Ungültiges Battery-Objekt\", msg);\n    return null;\n}\n\nconst batteryId = battery.battery;\n\nconst states = [\n    {\n        id: \"voltage\",\n        value: battery.volt,\n        name: \"Voltage\",\n        role: \"value.voltage\",\n        type: \"number\",\n        readonly: true,\n        unit: \"mV\",\n        min: 0\n    },\n    {\n        id: \"temperature\",\n        value: battery.tempr / 1000,\n        name: \"Temperature\",\n        role: \"value.temperature\",\n        type: \"number\",\n        readonly: true,\n        unit: \"°C\"\n    },\n    {\n        id: \"baseState\",\n        value: battery.baseState,\n        name: \"Base State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"voltageState\",\n        value: battery.voltState,\n        name: \"Voltage State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"currentState\",\n        value: battery.currState,\n        name: \"Current State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"temperatureState\",\n        value: battery.tempState,\n        name: \"Temperature State\",\n        role: \"text\",\n        type: \"string\",\n        readonly: true\n    },\n    {\n        id: \"charge\",\n        value: battery.coulomb,\n        name: \"Charge\",\n        role: \"value.battery\",\n        type: \"number\",\n        readonly: true,\n        unit: \"%\",\n        min: 0,\n        max: 100\n    },\n    {\n        id: \"capacity\",\n        value: battery.capacity,\n        name: \"Capacity\",\n        role: \"value\",\n        type: \"number\",\n        readonly: true,\n        unit: \"mAh\",\n        min: 0\n    }\n];\n\nconst messages = [];\n\nfor (const state of states) {\n    const out = {\n        topic: `0_userdata.0.pytes.01.${batteryId}.${state.id}`,\n        payload: state.value,\n\n        stateName: state.name,\n        stateRole: state.role,\n        stateType: state.type,\n        stateReadonly: state.readonly\n    };\n\n    if (state.unit !== undefined) {\n        out.stateUnit = state.unit;\n    }\n\n    if (state.min !== undefined) {\n        out.stateMin = state.min;\n    }\n\n    if (state.max !== undefined) {\n        out.stateMax = state.max;\n    }\n\n    messages.push(out);\n}\n\nreturn [messages];",
                      "outputs": 1,
                      "timeout": 0,
                      "noerr": 0,
                      "initialize": "",
                      "finalize": "",
                      "libs": [],
                      "x": 1100,
                      "y": 80,
                      "wires": [
                          [
                              "6a16c00e7b0e2997",
                              "68c635b31d513d6d"
                          ]
                      ]
                  },
                  {
                      "id": "c0f1afd033e9efcf",
                      "type": "inject",
                      "z": "26771494c726dd85",
                      "name": "",
                      "props": [
                          {
                              "p": "payload"
                          },
                          {
                              "p": "topic",
                              "vt": "str"
                          }
                      ],
                      "repeat": "",
                      "crontab": "",
                      "once": true,
                      "onceDelay": "0.1",
                      "topic": "",
                      "payload": "true",
                      "payloadType": "bool",
                      "x": 110,
                      "y": 40,
                      "wires": [
                          [
                              "6d9a8c4540741cbf"
                          ]
                      ]
                  },
                  {
                      "id": "478993d3b5047088",
                      "type": "serial control",
                      "z": "26771494c726dd85",
                      "name": "",
                      "serial": "a78922aa38d9e450",
                      "x": 840,
                      "y": 180,
                      "wires": [
                          []
                      ]
                  },
                  {
                      "id": "c0ff5d2e0b5d2616",
                      "type": "debug",
                      "z": "26771494c726dd85",
                      "name": "debug 14",
                      "active": false,
                      "tosidebar": true,
                      "console": false,
                      "tostatus": false,
                      "complete": "true",
                      "targetType": "full",
                      "statusVal": "",
                      "statusType": "auto",
                      "x": 800,
                      "y": 40,
                      "wires": []
                  },
                  {
                      "id": "723e5a9cad6671c7",
                      "type": "comment",
                      "z": "26771494c726dd85",
                      "name": "Serial-Ports",
                      "info": "/dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller-if00-port0\n\n/dev/serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0",
                      "x": 90,
                      "y": 100,
                      "wires": []
                  },
                  {
                      "id": "69611b30df398dd3",
                      "type": "serial request",
                      "z": "26771494c726dd85",
                      "name": "",
                      "serial": "a78922aa38d9e450",
                      "x": 600,
                      "y": 80,
                      "wires": [
                          [
                              "c0ff5d2e0b5d2616",
                              "598d93854bab5014"
                          ]
                      ]
                  },
                  {
                      "id": "6d9a8c4540741cbf",
                      "type": "delay",
                      "z": "26771494c726dd85",
                      "name": "",
                      "pauseType": "delay",
                      "timeout": "2",
                      "timeoutUnits": "seconds",
                      "rate": "1",
                      "nbRateUnits": "1",
                      "rateUnits": "second",
                      "randomFirst": "1",
                      "randomLast": "5",
                      "randomUnits": "seconds",
                      "drop": false,
                      "allowrate": false,
                      "outputs": 1,
                      "x": 300,
                      "y": 80,
                      "wires": [
                          [
                              "8979945491174ae1"
                          ]
                      ]
                  },
                  {
                      "id": "8979945491174ae1",
                      "type": "function",
                      "z": "26771494c726dd85",
                      "name": "naechster",
                      "func": "const batts =[\"bat 1\", \"bat 2\", \"bat 3\", \"bat 4\", \"bat 5\", \"bat 6\", \"bat 7\",\"bat 8\"];\n\nflow.set(\"batts\", batts);\n\nvar pos = parseInt(flow.get(\"pos\"));\npos++;\nif(pos > batts.length -1){pos=0}\nmsg.payload = batts[pos];\nflow.set (\"pos\", pos);\n\nreturn msg;",
                      "outputs": 1,
                      "timeout": 0,
                      "noerr": 0,
                      "initialize": "// Der Code hier wird ausgeführt,\n// wenn der Node gestartet wird\nflow.set(\"pos\", 0);\n",
                      "finalize": "",
                      "libs": [],
                      "x": 460,
                      "y": 80,
                      "wires": [
                          [
                              "69611b30df398dd3"
                          ]
                      ]
                  },
                  {
                      "id": "a418a9b4681de96b",
                      "type": "catch",
                      "z": "26771494c726dd85",
                      "name": "",
                      "scope": null,
                      "uncaught": false,
                      "x": 220,
                      "y": 180,
                      "wires": [
                          [
                              "fe3238beacae91ad"
                          ]
                      ]
                  },
                  {
                      "id": "598d93854bab5014",
                      "type": "switch",
                      "z": "26771494c726dd85",
                      "name": "",
                      "property": "payload",
                      "propertyType": "msg",
                      "rules": [
                          {
                              "t": "istype",
                              "v": "string",
                              "vt": "string"
                          },
                          {
                              "t": "else"
                          }
                      ],
                      "checkall": "true",
                      "repair": false,
                      "outputs": 2,
                      "x": 750,
                      "y": 80,
                      "wires": [
                          [
                              "79724f85531596e4",
                              "6d9a8c4540741cbf"
                          ],
                          [
                              "fe3238beacae91ad"
                          ]
                      ]
                  },
                  {
                      "id": "5a79550b570ff05d",
                      "type": "change",
                      "z": "26771494c726dd85",
                      "name": "Öffne Verbindung",
                      "rules": [
                          {
                              "t": "set",
                              "p": "payload",
                              "pt": "msg",
                              "to": "{\"enabled\":true}",
                              "tot": "json"
                          }
                      ],
                      "action": "",
                      "property": "",
                      "from": "",
                      "to": "",
                      "reg": false,
                      "x": 630,
                      "y": 220,
                      "wires": [
                          [
                              "478993d3b5047088",
                              "665e7ef72b226bc2"
                          ]
                      ]
                  },
                  {
                      "id": "b28980471e986893",
                      "type": "change",
                      "z": "26771494c726dd85",
                      "name": "Schließe Verbindung",
                      "rules": [
                          {
                              "t": "set",
                              "p": "payload",
                              "pt": "msg",
                              "to": "{\"enabled\":false}",
                              "tot": "json"
                          }
                      ],
                      "action": "",
                      "property": "",
                      "from": "",
                      "to": "",
                      "reg": false,
                      "x": 640,
                      "y": 180,
                      "wires": [
                          [
                              "478993d3b5047088"
                          ]
                      ]
                  },
                  {
                      "id": "fdaee2e16d78cc87",
                      "type": "delay",
                      "z": "26771494c726dd85",
                      "name": "",
                      "pauseType": "delay",
                      "timeout": "4",
                      "timeoutUnits": "seconds",
                      "rate": "1",
                      "nbRateUnits": "1",
                      "rateUnits": "second",
                      "randomFirst": "1",
                      "randomLast": "5",
                      "randomUnits": "seconds",
                      "drop": false,
                      "allowrate": false,
                      "outputs": 1,
                      "x": 440,
                      "y": 220,
                      "wires": [
                          [
                              "5a79550b570ff05d"
                          ]
                      ]
                  },
                  {
                      "id": "ecfde46ecc908741",
                      "type": "inject",
                      "z": "26771494c726dd85",
                      "name": "Test",
                      "props": [
                          {
                              "p": "payload"
                          },
                          {
                              "p": "topic",
                              "vt": "str"
                          }
                      ],
                      "repeat": "",
                      "crontab": "",
                      "once": false,
                      "onceDelay": 0.1,
                      "topic": "",
                      "payload": "true",
                      "payloadType": "bool",
                      "x": 230,
                      "y": 240,
                      "wires": [
                          [
                              "fe3238beacae91ad"
                          ]
                      ]
                  },
                  {
                      "id": "a78922aa38d9e450",
                      "type": "serial-port",
                      "name": "SerialPort",
                      "serialport": "/dev/serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0",
                      "serialbaud": "115200",
                      "databits": "8",
                      "parity": "none",
                      "stopbits": "1",
                      "waitfor": "",
                      "dtr": "none",
                      "rts": "none",
                      "cts": "none",
                      "dsr": "none",
                      "newline": "250",
                      "bin": "false",
                      "out": "time",
                      "addchar": "\\r\\n",
                      "responsetimeout": "10000"
                  }
              ]
              

              Gruß

              Peterfido

              1 Antwort Letzte Antwort
              0
              • A andibr

                Mein Flow sieht so aus:Bildschirmfoto vom 2026-08-14 19-32-46.png

                Manchmal funktioniert es richtig und manchmal eben nicht. Ich habe mir überlegt, ob evt. daran liegen könnte, dass der Port nach der Abfrage nicht geschlossen wird?
                Wenn ich im Minicom den Connect offen stehen lasse ist mir bis jetzt nicht aufgefallen, dass da keine Antwort kommen würde.

                Im Log sieht es dann so aus:
                Bildschirmfoto vom 2026-08-14 19-38-16.png

                Wenn ich dann den Flow verändere und neu deploye funktioniert es eine Weile ganz gut und plötzlich geht es wieder nicht mehr. Bis jetzt habe ich noch kein Muster gefunden.

                Ich habe da noch alte USR-TCP232-T2 Adapter rumliegen
                Bildschirmfoto vom 2026-08-14 19-43-18.png

                Allenfalls könnte man damit ja auch etwas machen und hätte dann einfach einen Netzwerk-Port zum abfragen, aber ich denke das Thema mit dem Timeout wird gleich bleiben. So wie ich es verstehe kommt der Timeout nicht vom Port sondern ist ein "nicht reagieren des BMS".

                OliverIOO Offline
                OliverIOO Offline
                OliverIO
                schrieb am zuletzt editiert von
                #47

                @andibr

                Ich habe mir nochmal das Bild mit dem Node Flow und dem debug Screen rechts angeschaut.
                Da gibt die debug node undefined aus.
                Das ist natürlich kein String.
                Dann müsste an den Anfang der function node sowas rein

                if (msg.payload == undefined) return;
                

                Das sorgt dafür das keine neue msg generiert wird, wenn keine auswertbare Information kommt.
                Das filtert dann das aus.

                Kann das leider nicht testen, da aktuell kein Node red verfügbar

                Meine Adapter und Widgets
                TVProgram, SqueezeboxRPC, OpenLiga, RSSFeed, MyTime,, pi-hole2, vis-json-template, skiinfo, vis-mapwidgets, vis-2-widgets-rssfeed
                Links im Profil

                A mickymM 2 Antworten Letzte Antwort
                0
                • OliverIOO OliverIO

                  @andibr

                  Ich habe mir nochmal das Bild mit dem Node Flow und dem debug Screen rechts angeschaut.
                  Da gibt die debug node undefined aus.
                  Das ist natürlich kein String.
                  Dann müsste an den Anfang der function node sowas rein

                  if (msg.payload == undefined) return;
                  

                  Das sorgt dafür das keine neue msg generiert wird, wenn keine auswertbare Information kommt.
                  Das filtert dann das aus.

                  Kann das leider nicht testen, da aktuell kein Node red verfügbar

                  A Offline
                  A Offline
                  andibr
                  schrieb am zuletzt editiert von
                  #48

                  @OliverIO
                  Danke für die Analyse und der grundsätzlichen Bestätigung, dass es eigentlich richtig ist und auch funktionieren sollte.
                  Unterdessen ist es so, dass ich den wiederholzykluss auf 20min gestellt habe und zwischen jeder Anfrage 1 Minute warte. Zusätzlich habe ich ja die udev-Regel entfernt und das Portweiterleiten mit den Proxmox eigenen Mitteln gemacht. Es läuft nun seit 25h so, und Fehler mit keinem String ist noch 2x aufgetreten, hat sich unterdessen aber sogar selber gefixt und läuft seither ohne erkennbar Fehlermeldungen durch.
                  Weil es ja so merkwürdig reagiert hat, habe ich den Pylontechadapter nochmals installiert und die neue Schnittstelle eingerichtet. Nach sehr langem warten wurde der Adapter sogar grün und er hat tatsächlich die BMS Infos rausgelesen, aber die Zelleninfos kamm nicht.

                  Ich habe zwar keine Ahnung wie das Pytes BMS Tool das wirklich macht, aber ich habe den Eindruck, dass der Abfragezyklus nicht mehr als 1x pro Minute gestartet werden darf. Das Pytes Tool bringt alle infis eigentlich recht schnell.
                  Bei meinem 12V System mit den DALI ist es so beschrieben, dass man nur 1x pro Minute Abfragen, kann weil der Prozessor sonst seine Aufgabe nicht machen kann.

                  Aktuell läuft es und ich beobachte das sehr intensiv, weil ich der Sache noch nicht ganz traue.

                  1 Antwort Letzte Antwort
                  0
                  • OliverIOO OliverIO

                    @andibr

                    Ich habe mir nochmal das Bild mit dem Node Flow und dem debug Screen rechts angeschaut.
                    Da gibt die debug node undefined aus.
                    Das ist natürlich kein String.
                    Dann müsste an den Anfang der function node sowas rein

                    if (msg.payload == undefined) return;
                    

                    Das sorgt dafür das keine neue msg generiert wird, wenn keine auswertbare Information kommt.
                    Das filtert dann das aus.

                    Kann das leider nicht testen, da aktuell kein Node red verfügbar

                    mickymM Offline
                    mickymM Offline
                    mickym
                    Most Active
                    schrieb am zuletzt editiert von
                    #49

                    @OliverIO Wie meist, kann man das aber auch mit einer switch Node filtern und braucht dazu kein Javascript.

                    a2e9a403-3763-473b-abfe-25e73ac31c57-image.jpeg

                    Jeder Flow bzw. jedes Script, das ich hier poste implementiert jeder auf eigene Gefahr. Flows und Scripts können Fehler aufweisen und weder der Seitenbetreiber noch ich persönlich können hierfür haftbar gemacht werden. Das gleiche gilt für Empfehlungen aller Art.

                    OliverIOO 1 Antwort Letzte Antwort
                    0
                    • mickymM mickym

                      @OliverIO Wie meist, kann man das aber auch mit einer switch Node filtern und braucht dazu kein Javascript.

                      a2e9a403-3763-473b-abfe-25e73ac31c57-image.jpeg

                      OliverIOO Offline
                      OliverIOO Offline
                      OliverIO
                      schrieb am zuletzt editiert von OliverIO
                      #50

                      @mickym

                      Theoretisch schon
                      Bin gerade nicht am Rechner
                      Weiß nicht was man da auswählen kann
                      Irgend was mit

                      Ist
                      Oder
                      Ist nicht
                      Oder
                      Ist vom typ

                      Und bei Typ
                      Undefined

                      Dann einen Ausgang entsprechend der Logik verdrahten so das die undefined Message ins Leere läuft

                      Meine Adapter und Widgets
                      TVProgram, SqueezeboxRPC, OpenLiga, RSSFeed, MyTime,, pi-hole2, vis-json-template, skiinfo, vis-mapwidgets, vis-2-widgets-rssfeed
                      Links im Profil

                      mickymM 1 Antwort Letzte Antwort
                      0
                      • OliverIOO OliverIO

                        @mickym

                        Theoretisch schon
                        Bin gerade nicht am Rechner
                        Weiß nicht was man da auswählen kann
                        Irgend was mit

                        Ist
                        Oder
                        Ist nicht
                        Oder
                        Ist vom typ

                        Und bei Typ
                        Undefined

                        Dann einen Ausgang entsprechend der Logik verdrahten so das die undefined Message ins Leere läuft

                        mickymM Offline
                        mickymM Offline
                        mickym
                        Most Active
                        schrieb am zuletzt editiert von mickym
                        #51

                        @OliverIO Ich habe doch einen Screenshot gemacht. So kommen nur Strings durch. Kein undefined, Numbers etc., aber ich will mich da nicht in Eure Diskussion einmischen. Das ist ja nur ein Nebenschauplatz

                        Jeder Flow bzw. jedes Script, das ich hier poste implementiert jeder auf eigene Gefahr. Flows und Scripts können Fehler aufweisen und weder der Seitenbetreiber noch ich persönlich können hierfür haftbar gemacht werden. Das gleiche gilt für Empfehlungen aller Art.

                        OliverIOO 1 Antwort Letzte Antwort
                        0
                        • mickymM mickym

                          @OliverIO Ich habe doch einen Screenshot gemacht. So kommen nur Strings durch. Kein undefined, Numbers etc., aber ich will mich da nicht in Eure Diskussion einmischen. Das ist ja nur ein Nebenschauplatz

                          OliverIOO Offline
                          OliverIOO Offline
                          OliverIO
                          schrieb am zuletzt editiert von
                          #52

                          @mickym
                          Wenn es String ist
                          Könnte auch
                          buffer
                          Sein
                          Kann mich nicht mehr erinnern

                          Meine Adapter und Widgets
                          TVProgram, SqueezeboxRPC, OpenLiga, RSSFeed, MyTime,, pi-hole2, vis-json-template, skiinfo, vis-mapwidgets, vis-2-widgets-rssfeed
                          Links im Profil

                          mickymM 1 Antwort Letzte Antwort
                          0
                          • OliverIOO OliverIO

                            @mickym
                            Wenn es String ist
                            Könnte auch
                            buffer
                            Sein
                            Kann mich nicht mehr erinnern

                            mickymM Offline
                            mickymM Offline
                            mickym
                            Most Active
                            schrieb am zuletzt editiert von
                            #53

                            @OliverIO Man kann auch undefined an Ausgang 1 schicken und ins Leere laufen lassen und den Rest weiterverarbeiten:

                            ace69e52-9d5f-4f1c-8a52-7a7cf080908e-image.jpeg

                            Jeder Flow bzw. jedes Script, das ich hier poste implementiert jeder auf eigene Gefahr. Flows und Scripts können Fehler aufweisen und weder der Seitenbetreiber noch ich persönlich können hierfür haftbar gemacht werden. Das gleiche gilt für Empfehlungen aller Art.

                            1 Antwort Letzte Antwort
                            0
                            • P Offline
                              P Offline
                              peterfido
                              schrieb am zuletzt editiert von
                              #54

                              So wie @mickym schreibt, ist es doch in meinem Beispiel-Code weiter oben.

                              Gruß

                              Peterfido

                              A 1 Antwort Letzte Antwort
                              0
                              • P peterfido

                                So wie @mickym schreibt, ist es doch in meinem Beispiel-Code weiter oben.

                                A Offline
                                A Offline
                                andibr
                                schrieb am zuletzt editiert von andibr
                                #55

                                Soweit ich das bis jetzt begriffen habe, gibt es mehrere Probleme mit meinem Flow:

                                1. Das BMS sendet irgendwann plötzlich nicht mehr korrekte Daten.
                                2. Der Flow verliert bei mir nach ca.36h Betrieb irgendwie die Synchronisation und blockiert bei mir irgendwie den ganzen Iobroker. Es entstehen hunderte Fehlermeldungen mit Bezug zum Node Red.
                                3. Scheinbar gibt es da auch ein Problem beim so Datenschreiben in die Datenpunkte. Weil zu viele Daten angeblich im Node Red im Cash hängenbleiben und nicht gelöscht werden ( zumindest behauptet ein KI das).
                                  Ich habe irgendwie kapituliert, weil ich nicht begreife wie das zu machen ist

                                Ich habe mir auch überlegt, ob man allenfalls mit der msg.payload gleich eine Globale Variable schreiben könnte und danach diesen Inhalt im Node der die einzelne Listen Einträge erstellt, im Topic einsetzen. Konkret stelle ich mir das so vor: beim payload "bat 1" soll die Varaible auf den Wert "1" gesetzt. Und dann als Block 1 in die Topic eingesetzt werden. Bei "bat 2" dann eine "2" etc. Damit könnte man alle abfragen eben über den gleichen RS232 Node machen und hätte auch da nicht 8stk.

                                1 Antwort Letzte Antwort
                                0

                                Hey! Du scheinst an dieser Unterhaltung interessiert zu sein, hast aber noch kein Konto.

                                Hast du es satt, bei jedem Besuch durch die gleichen Beiträge zu scrollen? Wenn du dich für ein Konto anmeldest, kommst du immer genau dorthin zurück, wo du zuvor warst, und kannst dich über neue Antworten benachrichtigen lassen (entweder per E-Mail oder Push-Benachrichtigung). Du kannst auch Lesezeichen speichern und Beiträge positiv bewerten, um anderen Community-Mitgliedern deine Wertschätzung zu zeigen.

                                Mit deinem Input könnte dieser Beitrag noch besser werden 💗

                                Registrieren Anmelden
                                Antworten
                                • In einem neuen Thema antworten
                                Anmelden zum Antworten
                                • Älteste zuerst
                                • Neuste zuerst
                                • Meiste Stimmen


                                Support us

                                ioBroker
                                Community Adapters
                                Donate

                                340

                                Online

                                33.0k

                                Benutzer

                                83.7k

                                Themen

                                1.3m

                                Beiträge
                                Community
                                Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
                                ioBroker Community 2014-2026
                                logo
                                • Anmelden

                                • Du hast noch kein Konto? Registrieren

                                • Anmelden oder registrieren, um zu suchen
                                • Erster Beitrag
                                  Letzter Beitrag
                                0
                                • Home
                                • Aktuell
                                • Tags
                                • Ungelesen 0
                                • Kategorien
                                • Unreplied
                                • Beliebt
                                • GitHub
                                • Docu
                                • Hilfe