Node-RED/flow: Wärmemelder

Node-RED als CCU3/RaspberryMatic Addon, WebApp, HomeKit, ...

Moderator: Co-Administratoren

Antworten
Benutzeravatar
Henke
Beiträge: 1500
Registriert: 27.06.2022, 20:51
System: CCU
Hat sich bedankt: 133 Mal
Danksagung erhalten: 303 Mal

Node-RED/flow: Wärmemelder

Beitrag von Henke » 22.12.2022, 17:44

Aufgrund dieses Beitrags viewtopic.php?f=79&t=77035&start=20 habe ich meine zusätzliche Feuerwarnung etwas optimiert.
Die Grundidee war die vielen vorhandenen Temperatursensoren mit in eine Feuerwarnung einzubinden. Dabei möchte ich explizit darauf hinweisen, das dies auf keinen Fall die Rauchmelder ersetzen kann. Jedoch habe ich persönlich nicht in jedem Raum bzw. Außen eine Rauchmelder und die Erweiterung kostet schließlich nix.
Test mit den Wandthermostaten vs. Feuer im Kamin haben gezeigt das durch die Auswertung der zeitlichen Differenz viel schneller ein sicherer Alarm ausgelöst werden kann. Beim Starten des Feuers kam die Meldung schon unter 45 Grad, runtergebrannt dagegen kam nichts. Test mit Shellys, die in Unterputzdosen verbaut sind, lösten jedoch beim Einschalten der Verbraucher zu früh aus. Bei denen klappt die Differenzberechnung nicht.

Testet es bitte, wenn dadurch auch nur ein Brand schneller erkannt wird, hat es sich gelohnt.
Screenshot 2022-12-22 172507.jpg

Code: Alles auswählen

[
    {
        "id": "2066ed3659d168e5",
        "type": "subflow",
        "name": "diff payload",
        "info": "Berechnung der Differenz pro Zeit, aufgeteilt nach Topic und Datenpunkt.\r\nAusgabe von msg.diff",
        "category": "",
        "in": [
            {
                "x": 40,
                "y": 80,
                "wires": [
                    {
                        "id": "38433d81cca8bfc6"
                    }
                ]
            }
        ],
        "out": [
            {
                "x": 340,
                "y": 80,
                "wires": [
                    {
                        "id": "38433d81cca8bfc6",
                        "port": 0
                    }
                ]
            }
        ],
        "env": [
            {
                "name": "msg",
                "type": "str",
                "value": "payload",
                "ui": {
                    "icon": "font-awesome/fa-angle-left",
                    "label": {
                        "de": "Datenpunkt msg."
                    },
                    "type": "input",
                    "opts": {
                        "types": [
                            "str",
                            "env"
                        ]
                    }
                }
            }
        ],
        "meta": {},
        "color": "#FDD0A2",
        "icon": "node-red/function.svg",
        "status": {
            "x": 340,
            "y": 140,
            "wires": [
                {
                    "id": "1a2b3d68e0c03267",
                    "port": 0
                }
            ]
        }
    },
    {
        "id": "38433d81cca8bfc6",
        "type": "function",
        "z": "2066ed3659d168e5",
        "name": "diff payload",
        "func": "// V 1.0 Copyleft M. Henke\n\nvar name = \"diffTime\";\nvar lastFL = context.get(name) || {};\n\nconst msgName = env.get(\"msg\") || {};\nvar pp = RED.util.getObjectProperty(msg, msgName);\nif (!pp) {\n    node.error(\"unbekannt: msg.\" + msgName, msg);\n    return;\n}\n\nif (!msg.ts) {\n    node.warn(\"msg.ts fehlt\");\n    return;\n}\nif (!msg.topic) {\n    node.warn(\"msg.topic fehlt\");\n    return;\n}\nif (typeof pp != 'number') {\n    node.warn(\"msg.\" + msgName + \" keine Zahl \" + pp);\n    return;\n}\nvar nSet = {};\nnSet.payload = pp;\nnSet.time = new Date(msg.ts);\nlet sDP = msg.topic + \".\" + msgName;\n\nvar nFlow = {};\nnFlow.Akt = nSet;\n\nvar last = lastFL[sDP];\nif (last) {\n    //    newMsg.ssss = last.Start.payload;\n    nFlow.Start = last.Start;\n}\nelse {\n    nFlow.Start = nSet;\n    lastFL[sDP] = nFlow;\n    context.set(name, lastFL);\n    return;\n}\n\nvar tDiff = (nSet.time.getTime() - last.Akt.time.getTime());\nif (tDiff < 1000)\n    return;\nlastFL[sDP] = nFlow;\ncontext.set(name, lastFL);\n\nvar newMsg = msg;\nnewMsg.diff = {};\n\nvar out = {};\nvar diff = nSet.payload - last.Akt.payload;\n\nout.plLast = last.Akt.payload;\nout.pl = diff;\nout.time = tDiff;\nif (tDiff) {\n    out.Sec = diff * 1000 / tDiff;\n    out.Min = diff * 60 * 1000 / tDiff;\n    out.h = diff * 60 * 60 * 1000 / tDiff;\n}\nnewMsg.diff.Akt = out;\n\nvar out2 = {};\ndiff = pp - last.Start.payload;\ntDiff = (nSet.time.getTime() - last.Start.time.getTime());\nout2.plLast = last.Start.payload;\nout2.pl = diff;\nout2.time = tDiff;\nif (tDiff) {\n    out2.Sec = diff * 1000 / tDiff;\n    out2.Min = diff * 60 * 1000 / tDiff;\n    out2.h = diff * 60 * 60 * 1000 / tDiff;\n}\nnewMsg.diff.Start = out2;\n\nconst text = sDP + \" \" + pp + \" diff: \" + (Math.round(msg.diff.Akt.Min * 1000) / 1000);\nnode.status({ fill: \"blue\", shape: \"dot\", text: text });\nreturn newMsg;\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 190,
        "y": 80,
        "wires": [
            []
        ]
    },
    {
        "id": "1a2b3d68e0c03267",
        "type": "status",
        "z": "2066ed3659d168e5",
        "name": "",
        "scope": [
            "38433d81cca8bfc6"
        ],
        "x": 180,
        "y": 140,
        "wires": [
            []
        ]
    },
    {
        "id": "a76412665ae32774",
        "type": "subflow:2066ed3659d168e5",
        "z": "d85b59ff755cd0af",
        "name": "",
        "x": 490,
        "y": 1460,
        "wires": [
            [
                "3040f728f81e7dc0"
            ]
        ]
    },
    {
        "id": "a9ea5444b9af1635",
        "type": "switch",
        "z": "d85b59ff755cd0af",
        "name": ">= 21",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "gte",
                "v": "21",
                "vt": "num"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 470,
        "y": 1420,
        "wires": [
            [
                "a76412665ae32774"
            ]
        ]
    },
    {
        "id": "3040f728f81e7dc0",
        "type": "switch",
        "z": "d85b59ff755cd0af",
        "name": ">= 3.5 Grad pro Minute",
        "property": "diff.Akt.Min",
        "propertyType": "msg",
        "rules": [
            {
                "t": "gte",
                "v": "3.5",
                "vt": "num"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 690,
        "y": 1460,
        "wires": [
            [
                "bc45b4ac007dc6db"
            ]
        ]
    },
    {
        "id": "bc45b4ac007dc6db",
        "type": "debug",
        "z": "d85b59ff755cd0af",
        "name": "Feuer Diff",
        "active": true,
        "tosidebar": true,
        "console": true,
        "tostatus": false,
        "complete": "channelName & \": \" & payload",
        "targetType": "jsonata",
        "statusVal": "",
        "statusType": "auto",
        "x": 910,
        "y": 1460,
        "wires": []
    },
    {
        "id": "9ab0c56a62e6650f",
        "type": "switch",
        "z": "d85b59ff755cd0af",
        "name": ">= 54",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "gte",
                "v": "54",
                "vt": "num"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 470,
        "y": 1380,
        "wires": [
            [
                "e8a03ae7d3c3ad28"
            ]
        ]
    },
    {
        "id": "e8a03ae7d3c3ad28",
        "type": "debug",
        "z": "d85b59ff755cd0af",
        "name": "Feuer > 54 Grad",
        "active": true,
        "tosidebar": true,
        "console": true,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 930,
        "y": 1380,
        "wires": []
    },
    {
        "id": "b3dbdd5f7937246b",
        "type": "ccu-rpc-event",
        "z": "d85b59ff755cd0af",
        "name": "",
        "iface": "",
        "ccuConfig": "89acb508b5dc9002",
        "rooms": "",
        "roomsRx": "str",
        "functions": "",
        "functionsRx": "str",
        "device": "",
        "deviceRx": "str",
        "deviceName": "",
        "deviceNameRx": "str",
        "deviceType": "",
        "deviceTypeRx": "str",
        "channel": "",
        "channelRx": "str",
        "channelName": "",
        "channelNameRx": "str",
        "channelType": "",
        "channelTypeRx": "str",
        "channelIndex": "",
        "channelIndexRx": "str",
        "datapoint": "ACTUAL_TEMPERATURE",
        "datapointRx": "str",
        "change": false,
        "working": true,
        "cache": true,
        "topic": "${CCU}/${Interface}/${channelName}/${datapoint}",
        "x": 220,
        "y": 1380,
        "wires": [
            [
                "a9ea5444b9af1635",
                "7b59d7ec7f5b9135",
                "9ab0c56a62e6650f"
            ]
        ]
    },
    {
        "id": "7b59d7ec7f5b9135",
        "type": "debug",
        "z": "d85b59ff755cd0af",
        "name": "debug 3",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "counter",
        "x": 220,
        "y": 1440,
        "wires": []
    },
    {
        "id": "ecb068e08784b823",
        "type": "comment",
        "z": "d85b59ff755cd0af",
        "name": "Die beiden Ausgänge dann weiterleiten an die Rauchmelder oder Handy",
        "info": "",
        "x": 1090,
        "y": 1420,
        "wires": []
    },
    {
        "id": "89acb508b5dc9002",
        "type": "ccu-connection",
        "name": "CCU Export - durch eigene ersetzen",
        "host": "192.168.0.0",
        "regaEnabled": true,
        "bcrfEnabled": true,
        "iprfEnabled": true,
        "virtEnabled": true,
        "bcwiEnabled": false,
        "jackEnabled": false,
        "cuxdEnabled": false,
        "regaPoll": true,
        "regaInterval": "30",
        "rpcPingTimeout": "60",
        "rpcInitAddress": "",
        "rpcServerHost": "0.0.0.0",
        "rpcBinPort": "2085",
        "rpcXmlPort": "2086",
        "tls": false,
        "inSecure": false,
        "authentication": false,
        "username": "",
        "password": "",
        "queueTimeout": "5000",
        "queuePause": "250",
        "contextStore": ""
    }
]
LG
Michael
Zuletzt geändert von Henke am 22.12.2022, 19:57, insgesamt 1-mal geändert.

Benutzeravatar
Baxxy
Beiträge: 10647
Registriert: 18.12.2018, 15:45
System: Alternative CCU (auf Basis OCCU)
Hat sich bedankt: 597 Mal
Danksagung erhalten: 2180 Mal

Re: Node-RED/flow: Wärmemelder

Beitrag von Baxxy » 22.12.2022, 19:00

Welche "ccu-connection-node" hole ich mir denn da beim Import mit rein?
Original oder ptweety?

Bei mir gab's "CodeRed" nach dem deploy und NodeRed (als AddOn unter HA) ließ sich auch nicht mehr starten.
(Konnte das aber über den Safe-Mode und Entfernen der importierten "ccu-connection-node" beheben)

Benutzeravatar
Henke
Beiträge: 1500
Registriert: 27.06.2022, 20:51
System: CCU
Hat sich bedankt: 133 Mal
Danksagung erhalten: 303 Mal

Re: Node-RED/flow: Wärmemelder

Beitrag von Henke » 22.12.2022, 19:53

Eine "ccu-connection-node" bei der ich die Werte von Hand lösche. Ich gebe ungern Benutzername und Passwort raus. 8)
Die muss immer bei solchen Sachen durch die eigene ersetzt werden.

Ich habe zum Testen ptweety unter Windows installiert aber es muss auch unter dem original laufen.

Im Zweifel die "rpc_event" node löschen und durch eigene ersetzen:
Screenshot 2022-12-22 194949.jpg
Ich ändere den Flow oben mal auf eine saubere ohne User/Passwort. Dann sollte "CodeRed" wenigstens weg sein.

Antworten

Zurück zu „RedMatic“