Servus Arno.
Ich friere noch! Wir sind über Weihnachten und Neujahr im Oberallgäu. Noch keinen genauen Plan ob Portugal ja oder nein diesen Winter.
Ja, aber während der Schulung gibt es auch etwas zu trinken, du hast noch jede Menge gut bei mir!!!
Servus Arno.
Ich friere noch! Wir sind über Weihnachten und Neujahr im Oberallgäu. Noch keinen genauen Plan ob Portugal ja oder nein diesen Winter.
Ja, aber während der Schulung gibt es auch etwas zu trinken, du hast noch jede Menge gut bei mir!!!
Quatsch
Aber mit dem trinken können wir ab Ende März mal überdenken
@ahtdf
Hey Arno, habe die Nodes etwas ergänzt und eine Seite zugefügt wo man die Spannungen eingeben kann. Musst die Seite nur in einen anderen Tab schieben, hier sind die jetzt im Info Tab. Viel Spas damit!
[ { "id": "40c35efeac98e425", "type": "function", "z": "a00d647c3d6e5e31", "name": "Berechnung Füllstand", "func": "const voltage = msg.payload; // Spannung in mV\n\n// Die Spannungswerte werden aus den globalen Variablen abgerufen\nconst points = [\n { voltage: global.get(\"voltage_0\"), level: 0 },\n { voltage: global.get(\"voltage_10\"), level: 10 },\n { voltage: global.get(\"voltage_20\"), level: 20 },\n { voltage: global.get(\"voltage_30\"), level: 30 },\n { voltage: global.get(\"voltage_40\"), level: 40 },\n { voltage: global.get(\"voltage_50\"), level: 50 },\n { voltage: global.get(\"voltage_60\"), level: 60 },\n { voltage: global.get(\"voltage_70\"), level: 70 },\n { voltage: global.get(\"voltage_80\"), level: 80 },\n { voltage: global.get(\"voltage_90\"), level: 90 },\n { voltage: global.get(\"voltage_100\"), level: 100 }\n];\n\n// Funktion zur linearen Interpolation\nfunction interpolate(value, x1, x2, y1, y2) {\n return y1 + ((value - x1) * (y2 - y1)) / (x2 - x1);\n}\n\nlet level = 0;\n\n// Finde die passenden Punkte für die Interpolation\nfor (let i = 0; i < points.length - 1; i++) {\n const p1 = points[i];\n const p2 = points[i + 1];\n\n if (voltage >= p1.voltage && voltage <= p2.voltage) {\n level = interpolate(voltage, p1.voltage, p2.voltage, p1.level, p2.level);\n break;\n }\n}\n\n// Sicherheitshalber Grenzen setzen\nlevel = Math.max(0, Math.min(100, level));\n\n// Runde den Wert und setze ihn als Payload\nmsg.payload = { level: Math.round(level), voltage };\n\nreturn msg;", "outputs": 1, "timeout": "", "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 760, "y": 360, "wires": [ [ "d19790332be670cd" ] ] }, { "id": "d19790332be670cd", "type": "function", "z": "a00d647c3d6e5e31", "name": "function 41", "func": "msg.payload = msg.payload.level;\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 1030, "y": 440, "wires": [ [ "535c1195b13647cd" ] ] }, { "id": "535c1195b13647cd", "type": "ui_gauge", "z": "a00d647c3d6e5e31", "name": "", "group": "9e7305cfb88bb726", "order": 2, "width": "3", "height": "3", "gtype": "gage", "title": "Gastank", "label": "%", "format": "{{msg.payload}} %", "min": 0, "max": "100", "colors": [ "#b30036", "#e6e600", "#3acb5e" ], "seg1": "20", "seg2": "50", "diff": false, "className": "", "x": 1340, "y": 460, "wires": [] }, { "id": "ecfdbdfe5a5e31a3", "type": "ui_form", "z": "a00d647c3d6e5e31", "name": "Eingabe Spannungen", "label": "Spannungswerte für Tankfüllstand", "group": "24c8410aa9b3f86e", "order": 1, "width": "6", "height": "6", "options": [ { "label": "0%", "value": "voltage_0", "type": "number", "required": true }, { "label": "10%", "value": "voltage_10", "type": "number", "required": true }, { "label": "20%", "value": "voltage_20", "type": "number", "required": true }, { "label": "30%", "value": "voltage_30", "type": "number", "required": true }, { "label": "40%", "value": "voltage_40", "type": "number", "required": true }, { "label": "50%", "value": "voltage_50", "type": "number", "required": true }, { "label": "60%", "value": "voltage_60", "type": "number", "required": true }, { "label": "70%", "value": "voltage_70", "type": "number", "required": true }, { "label": "80%", "value": "voltage_80", "type": "number", "required": true }, { "label": "90%", "value": "voltage_90", "type": "number", "required": true }, { "label": "100%", "value": "voltage_100", "type": "number", "required": true } ], "formValue": { "voltage_0": "", "voltage_10": "", "voltage_20": "", "voltage_30": "", "voltage_40": "", "voltage_50": "", "voltage_60": "", "voltage_70": "", "voltage_80": "", "voltage_90": "", "voltage_100": "" }, "payload": "", "topic": "", "x": 600, "y": 460, "wires": [ [ "b2291a91ecfdddb2" ] ] }, { "id": "b2291a91ecfdddb2", "type": "function", "z": "a00d647c3d6e5e31", "name": "Set Global Variables", "func": "global.set(\"voltage_0\", msg.payload.voltage_0);\nglobal.set(\"voltage_10\", msg.payload.voltage_10);\nglobal.set(\"voltage_20\", msg.payload.voltage_20);\nglobal.set(\"voltage_30\", msg.payload.voltage_30);\nglobal.set(\"voltage_40\", msg.payload.voltage_40);\nglobal.set(\"voltage_50\", msg.payload.voltage_50);\nglobal.set(\"voltage_60\", msg.payload.voltage_60);\nglobal.set(\"voltage_70\", msg.payload.voltage_70);\nglobal.set(\"voltage_80\", msg.payload.voltage_80);\nglobal.set(\"voltage_90\", msg.payload.voltage_90);\nglobal.set(\"voltage_100\", msg.payload.voltage_100);\nreturn msg;", "outputs": 1, "timeout": "", "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 850, "y": 460, "wires": [] }, { "id": "24c8410aa9b3f86e", "type": "ui_group", "name": "Tank2", "tab": "f3504f4de9eb46b5", "order": 1, "disp": true, "width": "6", "collapse": false, "className": "" }, { "id": "f3504f4de9eb46b5", "type": "ui_tab", "name": "Eingabe", "icon": "dashboard", "order": 2, "disabled": false, "hidden": false } ]
@ahtdf und weil ich grad dabei bin
Idee war wie beim Strom eine Art “Time to go” für das Gas zu erstellen. Die Node speichert über 10 Tage den Gasverbrauch und erstellt eine “Reichweite” des noch vorhandenen Gas. Daten älter 10 Tage werden gelöschte. Die Node einfach hinter “Berechnung Füllstand” hängen. Ob sie richtig funktioniert kann ich erst später sagen, ist ja gerade erst erstellt worden.
[ { "id": "32e57f98b85ae9c5", "type": "function", "z": "85d1ca8b7292bbe8", "name": "Reichweite berechnen", "func": "const dailyLevels = global.get('dailyLevels') || [];\n\n// Berechne Verbrauch\nif (dailyLevels.length < 2) {\n msg.payload = \"Nicht genug Daten für die Berechnung\";\n return msg;\n}\n\nlet totalConsumption = 0;\nfor (let i = 1; i < dailyLevels.length; i++) {\n totalConsumption += dailyLevels[i - 1].level - dailyLevels[i].level;\n}\nconst avgConsumption = totalConsumption / (dailyLevels.length - 1);\n\nconst currentLevel = dailyLevels[dailyLevels.length - 1].level;\nconst estimatedDaysLeft = avgConsumption > 0 ? currentLevel / avgConsumption : Infinity;\n\nmsg.payload = `Verbleibender Inhalt reicht für etwa ${Math.round(estimatedDaysLeft)} Tage.`;\nreturn msg;", "outputs": 1, "timeout": "", "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 980, "y": 440, "wires": [ [ "f509a33b93c72ad0" ] ] }, { "id": "f509a33b93c72ad0", "type": "ui_text", "z": "85d1ca8b7292bbe8", "group": "28bc464cc0904581", "order": 3, "width": "6", "height": "1", "name": "Reichweite anzeigen", "label": "Restreichweite:", "format": "{{msg.payload}}", "layout": "row-spread", "className": "", "style": false, "font": "", "fontSize": "", "color": "#000000", "x": 1220, "y": 440, "wires": [] }, { "id": "28bc464cc0904581", "type": "ui_group", "name": "Strom", "tab": "deee53a800de461d", "order": 2, "disp": true, "width": "6", "collapse": false, "className": "" }, { "id": "deee53a800de461d", "type": "ui_tab", "name": "Info", "icon": "mi-info", "order": 1, "disabled": false, "hidden": false } ]