From f7d04829ea49eea0ba80a7a17ca81497d37dcab8 Mon Sep 17 00:00:00 2001 From: Eduard Iten Date: Mon, 29 Jun 2026 11:33:41 +0000 Subject: [PATCH] Erster Commit --- flows.json | 815 +++++++++++++++++++++++++++++++++++++++++++++++- flows_cred.json | 7 +- 2 files changed, 820 insertions(+), 2 deletions(-) diff --git a/flows.json b/flows.json index 0637a08..451ce01 100644 --- a/flows.json +++ b/flows.json @@ -1 +1,814 @@ -[] \ No newline at end of file +[ + { + "id": "0e938b2c7d519455", + "type": "tab", + "label": "Flow 1", + "disabled": false, + "info": "", + "env": [ + { + "name": "in_port", + "value": "20000", + "type": "str" + }, + { + "name": "out_port", + "value": "20000", + "type": "str" + } + ] + }, + { + "id": "b9502e7d5adbd1fc", + "type": "subflow", + "name": "Pump Command", + "info": "", + "category": "", + "in": [ + { + "x": 140, + "y": 100, + "wires": [ + { + "id": "26952e484ee2bdd1" + } + ] + } + ], + "out": [ + { + "x": 380, + "y": 100, + "wires": [ + { + "id": "26952e484ee2bdd1", + "port": 0 + } + ] + } + ], + "env": [ + { + "name": "TARGET_NODE", + "type": "num", + "value": "" + }, + { + "name": "PUMP_ID", + "type": "num", + "value": "" + } + ], + "meta": {}, + "color": "#DDAA99" + }, + { + "id": "1a6e91b7110fc591", + "type": "subflow", + "name": "Druck", + "info": "", + "category": "", + "in": [ + { + "x": 60, + "y": 40, + "wires": [ + { + "id": "6e8a2a39a56ae270" + } + ] + } + ], + "out": [ + { + "x": 340, + "y": 40, + "wires": [ + { + "id": "6e8a2a39a56ae270", + "port": 0 + } + ] + } + ], + "env": [], + "meta": {}, + "color": "#DDAA99" + }, + { + "id": "d9f42b9039b25aff", + "type": "server", + "name": "Home Assistant", + "version": 6, + "addon": false, + "rejectUnauthorizedCerts": false, + "ha_boolean": [ + "y", + "yes", + "true", + "on", + "home", + "open" + ], + "connectionDelay": true, + "cacheJson": true, + "heartbeat": true, + "heartbeatInterval": 30, + "areaSelector": "friendlyName", + "deviceSelector": "friendlyName", + "entitySelector": "friendlyName", + "statusSeparator": ": ", + "statusYear": "hidden", + "statusMonth": "short", + "statusDay": "numeric", + "statusHourCycle": "default", + "statusTimeFormat": "h:m", + "enableGlobalContextStore": false + }, + { + "id": "0a17864de5505a20", + "type": "ha-device-config", + "name": "Regenwasser", + "hwVersion": "", + "manufacturer": "Node-RED", + "model": "", + "swVersion": "" + }, + { + "id": "79cd4bcaeefb790a", + "type": "ha-entity-config", + "server": "d9f42b9039b25aff", + "deviceConfig": "0a17864de5505a20", + "name": "Systemdruck", + "version": 6, + "entityType": "sensor", + "haConfig": [ + { + "property": "name", + "value": "Systemdruck" + }, + { + "property": "icon", + "value": "" + }, + { + "property": "entity_picture", + "value": "" + }, + { + "property": "entity_category", + "value": "" + }, + { + "property": "device_class", + "value": "pressure" + }, + { + "property": "unit_of_measurement", + "value": "Pa" + }, + { + "property": "state_class", + "value": "" + } + ], + "resend": false, + "debugEnabled": false + }, + { + "id": "11087cbf4f9379d1", + "type": "ha-entity-config", + "server": "d9f42b9039b25aff", + "deviceConfig": "0a17864de5505a20", + "name": "Wasserstand", + "version": 6, + "entityType": "sensor", + "haConfig": [ + { + "property": "name", + "value": "Wasserstand" + }, + { + "property": "icon", + "value": "" + }, + { + "property": "entity_picture", + "value": "" + }, + { + "property": "entity_category", + "value": "" + }, + { + "property": "device_class", + "value": "pressure" + }, + { + "property": "unit_of_measurement", + "value": "Pa" + }, + { + "property": "state_class", + "value": "" + } + ], + "resend": false, + "debugEnabled": false + }, + { + "id": "9cba2b96af7846f4", + "type": "ha-entity-config", + "server": "d9f42b9039b25aff", + "deviceConfig": "0a17864de5505a20", + "name": "Pumpe", + "version": 6, + "entityType": "binary_sensor", + "haConfig": [ + { + "property": "name", + "value": "Pumpe" + }, + { + "property": "icon", + "value": "" + }, + { + "property": "entity_picture", + "value": "" + }, + { + "property": "entity_category", + "value": "" + }, + { + "property": "device_class", + "value": "" + } + ], + "resend": false, + "debugEnabled": false + }, + { + "id": "92579cd9fdb0eda1", + "type": "ha-entity-config", + "server": "d9f42b9039b25aff", + "deviceConfig": "0a17864de5505a20", + "name": "Quittierung Pumpenstörung", + "version": 6, + "entityType": "button", + "haConfig": [ + { + "property": "name", + "value": "Quittierunf Pumpenstörung" + }, + { + "property": "icon", + "value": "" + }, + { + "property": "entity_picture", + "value": "" + }, + { + "property": "entity_category", + "value": "config" + }, + { + "property": "device_class", + "value": "restart" + } + ], + "resend": false, + "debugEnabled": true + }, + { + "id": "bcc6944e1ff6c6e7", + "type": "ha-entity-config", + "server": "d9f42b9039b25aff", + "deviceConfig": "0a17864de5505a20", + "name": "Pumpenfehler", + "version": 6, + "entityType": "binary_sensor", + "haConfig": [ + { + "property": "name", + "value": "Pumpenfehler" + }, + { + "property": "icon", + "value": "" + }, + { + "property": "entity_picture", + "value": "" + }, + { + "property": "entity_category", + "value": "" + }, + { + "property": "device_class", + "value": "problem" + } + ], + "resend": false, + "debugEnabled": false + }, + { + "id": "fd41de37db3bcf9f", + "type": "ha-entity-config", + "server": "d9f42b9039b25aff", + "deviceConfig": "0a17864de5505a20", + "name": "Verlorene Frames", + "version": 6, + "entityType": "sensor", + "haConfig": [ + { + "property": "name", + "value": "Verlorene Frames" + }, + { + "property": "icon", + "value": "mdi:alert" + }, + { + "property": "entity_picture", + "value": "" + }, + { + "property": "entity_category", + "value": "diagnostic" + }, + { + "property": "device_class", + "value": "" + }, + { + "property": "unit_of_measurement", + "value": "" + }, + { + "property": "state_class", + "value": "measurement" + } + ], + "resend": false, + "debugEnabled": false + }, + { + "id": "26952e484ee2bdd1", + "type": "function", + "z": "b9502e7d5adbd1fc", + "name": "function 1", + "func": "let targetNode = env.get(\"TARGET_NODE\");\nlet pumpId = env.get(\"PUMP_ID\");\nlet pumpCmd = msg.payload; \n\nif (typeof pumpCmd !== \"number\") {\n node.warn(\"Befehl muss eine Zahl sein!\");\n return null;\n}\n\n// Wir bauen NUR den Payload (die 3 Bytes Nutzdaten)\nmsg.payload = Buffer.from([ targetNode, pumpId, pumpCmd ]);\n\n// 1. Das komplette Objekt mit allen IDs aus dem globalen Speicher holen\nlet CAN = global.get(\"CAN\");\n\n// 2. Wir hängen dem Paket als \"Post-It\" an, auf welcher CAN-ID es später reisen soll.\n// CAN.CMD_PUMP holt genau die 0x020 aus deiner globalen Liste.\nmsg.canId = CAN.CMD_PUMP; \n\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 260, + "y": 100, + "wires": [ + [] + ] + }, + { + "id": "6e8a2a39a56ae270", + "type": "function", + "z": "1a6e91b7110fc591", + "name": "Druck vom CAN", + "func": "let buf = msg.payload;\n\n// Sicherheitscheck: 6 Bytes erwartet\nif (buf.length !== 6) return null;\n\n// Bytes auslesen\nlet sourceNode = buf.readUInt8(0);\nlet sensorId = buf.readUInt8(1);\nlet pressurePa = buf.readUInt32BE(2); // Die 300.000 auslesen\n\n// Für Home Assistant rechnen wir Pascal wieder in Bar um\nlet pressureBar = pressurePa / 100000.0;\n\n// Payload überschreiben (HA will nur den reinen Wert)\nmsg.payload = pressurePa;\nmsg.sensorId = sensorId;\nmsg.nodeId = sourceNode;\n\n// Grüne LED am Knoten für direktes Feedback\nnode.status({fill:\"green\", shape:\"dot\", text: pressureBar.toFixed(2) + \" Bar\"});\n\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 200, + "y": 40, + "wires": [ + [] + ] + }, + { + "id": "d5928c3e9f080926", + "type": "udp in", + "z": "0e938b2c7d519455", + "name": "Garten CAN UDP In", + "iface": "", + "port": "${in_port}", + "ipv": "udp4", + "multicast": "false", + "group": "", + "datatype": "buffer", + "x": 110, + "y": 160, + "wires": [ + [ + "59119f4834036e0f" + ] + ] + }, + { + "id": "59119f4834036e0f", + "type": "function", + "z": "0e938b2c7d519455", + "name": "Input Decoder", + "func": "// sender IP merken für spätere Antworten\nflow.set(\"last_gateway_ip\", msg.ip);\n\n// msg.payload enthält den rohen Byte-Buffer vom ESP32/STM32\nlet buf = msg.payload;\n\n// Sicherheitscheck 1: Ist das Paket überhaupt groß genug für den Header?\nif (buf.length < 8) return null;\n\n// Header auslesen (Offsets korrigiert)\nlet canId = buf.readUInt32BE(0);\nlet flags = buf.readUInt8(4);\nlet dlc = buf.readUInt8(5);\nlet seqNo = buf.readUInt16BE(6);\n\n// Sicherheitscheck 2: Stimmen DLC und Puffergrösse überein?\nif (buf.length !== dlc + 8) {\n node.status({ fill: \"red\", shape: \"dot\", text: \"Size mismatch\" });\n return null;\n}\n\n// 1. CAN-ID als sauberen Hex-String formatieren\nlet canIdHex = canId.toString(16).toUpperCase();\n\n// 2. Die echten CAN-Nutzdaten aus dem Buffer herausschneiden (ab Byte 8)\nlet canData = buf.slice(8, 8 + dlc);\n\n// 3. Nachricht für die Weiche und die Decoder vorbereiten\nmsg.canId = canId; // Für den switch-Knoten\nmsg.payload = canData; // Ab hier liegen nur noch die echten Daten im Payload\nmsg.seqNo = seqNo; // Falls ein späterer Node die Sequenznummer braucht\n\n// Grüne LED mit Hex-ID anzeigen\nnode.status({ fill: \"green\", shape: \"dot\", text: \"ID: 0x\" + canIdHex + \" | Seq: \" + seqNo + \" | DLC: \" + dlc });\n\n// --- SEQUENZPRÜFUNG ---\n// Holt die Werte aus dem flüchtigen RAM-Kontext der Node\nlet oldSeq = context.get('oldSeq');\nlet errorCounter = context.get('errorCounter') || 0;\n\nif (oldSeq === undefined) {\n context.set('oldSeq', seqNo);\n context.set('errorCounter', errorCounter);\n msg.errorCounter = errorCounter;\n return msg;\n}\n\n// Delta berechnen (16-Bit Maske wegen readUInt16BE)\nlet delta = (seqNo - oldSeq) & 0xFFFF;\n\nif (delta > 1) {\n // Da du oben 10000 statt 100 gewählt hast: absolut okay für 16-Bit-Zähler bei schnellen Telegrammen\n if (delta < 10000) {\n let lostFrames = delta - 1;\n errorCounter += lostFrames;\n // FIX: Variable auf errorCounter korrigiert\n node.warn(`${lostFrames} Frame(s) verloren! Zähler steht auf: ${errorCounter}`);\n } else {\n // FIX: Variable auf seqNo korrigiert\n node.log(`Sensor-Reset erkannt (Sprung von ${oldSeq} auf ${seqNo}).`);\n }\n}\n\n// Werte für das nächste Paket im RAM merken\ncontext.set('oldSeq', seqNo);\ncontext.set('errorCounter', errorCounter);\n\n// Fehlerzähler an die Nachricht hängen\nmsg.errorCounter = errorCounter;\n\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 360, + "y": 160, + "wires": [ + [ + "1be1fe0ccdfb3d67", + "d2f4efb6f0a3199d" + ] + ] + }, + { + "id": "f8eb45ba33d70b65", + "type": "ha-button", + "z": "0e938b2c7d519455", + "name": "Quittierung Pumpenstörung", + "version": 0, + "debugenabled": false, + "outputs": 1, + "entityConfig": "92579cd9fdb0eda1", + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "0x05", + "valueType": "num" + } + ], + "x": 140, + "y": 480, + "wires": [ + [ + "a947a45468017733" + ] + ] + }, + { + "id": "a0a226dd400461d8", + "type": "comment", + "z": "0e938b2c7d519455", + "name": "", + "info": "### Funktionale CAN-Map (11-Bit)\n\n| Hex-ID | Dezimal | Kategorie | Beschreibung |\n| :--- | :--- | :--- | :--- |\n| **`0x000`** | 0 | **NMT** | Network Management (Alle Halt/Start) |\n| **`0x010`** | 16 | **Alarm** | Emergency (Saugrohr trocken, Druck kritisch) |\n| **`0x020`** | 32 | **Befehl** | Pumpensteuerung (Auto/Aus/Reset) |\n| **`0x030`** | 48 | **Befehl** | Ventil setzen (Pos in %) |\n| **`0x100`** | 256 | **Wert** | Systemdruck (Pascal) |\n| **`0x110`** | 272 | **Wert** | Füllstand (Tank / Einperlverfahren) |\n| **`0x200`** | 512 | **Zähler** | Durchflusszähler (Ticks) |\n| **`0x220`** | 544 | **Status** | Pumpenstatus |\n| **`0x230`** | 560 | **Status** | Ventilstatus |\n| **`0x7E0`** | 2016| **System**| Firmware Update (bis 0x7EF) |\n| **`0x7F0`** | 2032| **System**| Debug & Logging (bis 0x7FF) |", + "x": 80, + "y": 60, + "wires": [] + }, + { + "id": "1be1fe0ccdfb3d67", + "type": "switch", + "z": "0e938b2c7d519455", + "name": "", + "property": "canId", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "CAN.STAT_PUMP", + "vt": "global" + }, + { + "t": "eq", + "v": "CAN.VAL_PRESSURE", + "vt": "global" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 550, + "y": 160, + "wires": [ + [ + "0c60399fc4327d06" + ], + [ + "5538f815301a6ace" + ] + ] + }, + { + "id": "0c60399fc4327d06", + "type": "function", + "z": "0e938b2c7d519455", + "name": "Pumpenstatus", + "func": "let buf = msg.payload;\n\n// Sicherheitscheck: Wir wollen 3 Bytes lesen (Index 0, 1, 2)\nif (buf.length !== 3) return null;\n\nlet nodeId = buf.readUInt8(0);\nlet pumpId = buf.readUInt8(1);\nlet pumpState = buf.readUInt8(2);\n\nlet runState = false;\nlet errorState = false;\n\nswitch (pumpState) {\n case 0:\n runState = false;\n errorState = false;\n break;\n case 1:\n runState = true;\n errorState = false;\n break;\n case 2:\n default:\n runState = false;\n errorState = true;\n break;\n}\n\n// Nachricht 1 (Ausgang Oben) vorbereiten\nmsg.payload = runState;\nmsg.pumpId = pumpId;\nmsg.disabled = errorState;\nmsg.nodeId = nodeId;\n\n// Nachricht 2 (Ausgang Unten) vorbereiten\n// Wichtig: Wir müssen das Objekt erst erschaffen!\nlet msg_error = {\n payload: errorState,\n pumpId: pumpId,\n nodeId: nodeId\n};\n\n// Grüne LED anzeigen (wir nutzen msg.canId, falls du das vorher übergeben hast)\nnode.status({ fill: \"green\", shape: \"dot\", text: \"Pumpe \" + pumpId + \" | Status: \" + pumpState });\n\n// Ausgang 1 bekommt msg, Ausgang 2 bekommt msg_error\nreturn [msg, msg_error];", + "outputs": 2, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 800, + "y": 120, + "wires": [ + [ + "2f788ae7d216ce09" + ], + [ + "63466986c3d2f412" + ] + ] + }, + { + "id": "2f788ae7d216ce09", + "type": "ha-binary-sensor", + "z": "0e938b2c7d519455", + "name": "Pumpe", + "entityConfig": "9cba2b96af7846f4", + "version": 0, + "state": "payload", + "stateType": "msg", + "attributes": [ + { + "property": "disable", + "value": "disabled", + "valueType": "msg" + } + ], + "inputOverride": "allow", + "outputProperties": [], + "x": 1020, + "y": 100, + "wires": [ + [] + ] + }, + { + "id": "63466986c3d2f412", + "type": "ha-binary-sensor", + "z": "0e938b2c7d519455", + "name": "Pumpenfehler", + "entityConfig": "bcc6944e1ff6c6e7", + "version": 0, + "state": "payload", + "stateType": "msg", + "attributes": [], + "inputOverride": "block", + "outputProperties": [], + "x": 1040, + "y": 160, + "wires": [ + [] + ] + }, + { + "id": "a947a45468017733", + "type": "subflow:b9502e7d5adbd1fc", + "z": "0e938b2c7d519455", + "name": "", + "env": [ + { + "name": "TARGET_NODE", + "value": "1", + "type": "num" + }, + { + "name": "PUMP_ID", + "value": "1", + "type": "num" + } + ], + "x": 400, + "y": 480, + "wires": [ + [ + "259a6eb05825188b" + ] + ] + }, + { + "id": "36e2dae7fa76fa4f", + "type": "debug", + "z": "0e938b2c7d519455", + "name": "Systemdruck", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 1330, + "y": 240, + "wires": [] + }, + { + "id": "efce4aea184f149f", + "type": "inject", + "z": "0e938b2c7d519455", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": true, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 330, + "y": 60, + "wires": [ + [ + "14566063729419a9" + ] + ] + }, + { + "id": "14566063729419a9", + "type": "function", + "z": "0e938b2c7d519455", + "name": "Globals", + "func": "// Wir nutzen jetzt echte Hex-Zahlen (ohne Anführungszeichen!)\nconst CAN_IDS = {\n // Alarme\n ALARM: 0x010, \n \n // Befehle\n CMD_PUMP: 0x020, \n CMD_VALVE: 0x030, \n \n // Werte\n VAL_PRESSURE: 0x100,\n\n // Status\n STAT_PUMP: 0x220,\n};\n\nglobal.set(\"CAN\", CAN_IDS);\n\nnode.status({fill:\"green\", shape:\"dot\", text:\"Globale CAN-IDs geladen\"});\nreturn null;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 540, + "y": 60, + "wires": [ + [] + ] + }, + { + "id": "259a6eb05825188b", + "type": "function", + "z": "0e938b2c7d519455", + "name": "Output Encoder", + "func": "let targetIp = flow.get(\"last_gateway_ip\");\n\nif (!targetIp) {\n node.warn(\"Verworfen: Noch keine Gateway-IP gelernt. Warte auf erstes Paket vom ESP...\");\n return null;\n}\n\n// 2. Daten vom vorgeschalteten Knoten holen\nlet canData = msg.payload; // Die 3 Bytes aus dem Subflow\nlet canIdHex = msg.canId; // Die gewünschte CAN-ID (\"20\")\n\n// Sequenznummer global hochzählen\nlet seqNo = global.get(\"txSeqNo\") || 0;\nglobal.set(\"txSeqNo\", (seqNo + 1) % 65536);\n\n// 3. Den rohen UDP-Buffer bauen: 8 Bytes Header + X Bytes Daten\n// Das geniale: canData.length macht die DLC absolut dynamisch!\nlet buf = Buffer.alloc(8 + canData.length);\n\n// --- HEADER ---\nbuf.writeUInt32BE(parseInt(canIdHex, 16), 0); // CAN-ID umwandeln\nbuf.writeUInt8(0, 4); // Flags\nbuf.writeUInt8(canData.length, 5); // DLC (berechnet sich von selbst)\nbuf.writeUInt16BE(seqNo, 6); // Sequenznummer\n\n// --- PAYLOAD ---\n// Kopiert unsere 3 Nutzdaten-Bytes exakt an Position 8 in den großen Buffer\ncanData.copy(buf, 8);\n\n// 4. Feuer frei für den udp-out Knoten\nmsg.payload = buf;\nmsg.ip = targetIp;\n\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 600, + "y": 480, + "wires": [ + [ + "97252b8dc7a55b3e" + ] + ] + }, + { + "id": "97252b8dc7a55b3e", + "type": "udp out", + "z": "0e938b2c7d519455", + "name": "", + "addr": "", + "iface": "", + "port": "${out_port}", + "ipv": "udp4", + "outport": "", + "base64": false, + "multicast": "false", + "x": 840, + "y": 480, + "wires": [] + }, + { + "id": "5538f815301a6ace", + "type": "subflow:1a6e91b7110fc591", + "z": "0e938b2c7d519455", + "name": "", + "x": 770, + "y": 280, + "wires": [ + [ + "d7b39d46bdc6d1c8" + ] + ] + }, + { + "id": "c43b3701443a6dfe", + "type": "ha-sensor", + "z": "0e938b2c7d519455", + "name": "Systemdruck", + "entityConfig": "79cd4bcaeefb790a", + "version": 0, + "state": "payload", + "stateType": "msg", + "attributes": [], + "inputOverride": "allow", + "outputProperties": [], + "x": 1130, + "y": 240, + "wires": [ + [ + "36e2dae7fa76fa4f" + ] + ] + }, + { + "id": "d7b39d46bdc6d1c8", + "type": "switch", + "z": "0e938b2c7d519455", + "name": "", + "property": "sensorId", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "1", + "vt": "num" + }, + { + "t": "eq", + "v": "2", + "vt": "num" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 910, + "y": 280, + "wires": [ + [ + "c43b3701443a6dfe" + ], + [ + "aaedd1ee4c078969" + ] + ] + }, + { + "id": "aaedd1ee4c078969", + "type": "ha-sensor", + "z": "0e938b2c7d519455", + "name": "Wasserstand", + "entityConfig": "11087cbf4f9379d1", + "version": 0, + "state": "payload", + "stateType": "msg", + "attributes": [], + "inputOverride": "allow", + "outputProperties": [], + "x": 1130, + "y": 300, + "wires": [ + [ + "d547519394f23d1a" + ] + ] + }, + { + "id": "d547519394f23d1a", + "type": "debug", + "z": "0e938b2c7d519455", + "name": "Wasserstand", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "statusVal": "", + "statusType": "auto", + "x": 1330, + "y": 300, + "wires": [] + }, + { + "id": "d2f4efb6f0a3199d", + "type": "ha-sensor", + "z": "0e938b2c7d519455", + "name": "Verlorene Frames", + "entityConfig": "fd41de37db3bcf9f", + "version": 0, + "state": "errorCounter", + "stateType": "msg", + "attributes": [], + "inputOverride": "allow", + "outputProperties": [], + "x": 550, + "y": 260, + "wires": [ + [] + ] + } +] \ No newline at end of file diff --git a/flows_cred.json b/flows_cred.json index 9e26dfe..865aae8 100644 --- a/flows_cred.json +++ b/flows_cred.json @@ -1 +1,6 @@ -{} \ No newline at end of file +{ + "d9f42b9039b25aff": { + "host": "http://10.0.10.110:8123", + "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIwZjhiOGY1MzMwODE0Y2U4OTU5ZGZiYTBiYzM0ZjM4NCIsImlhdCI6MTc4MjYyODQxNSwiZXhwIjoyMDk3OTg4NDE1fQ.9wDgo9cqe8JcQPvlF5iRt-o2QmPVp0XPGEv9xkmJRDw" + } +} \ No newline at end of file