Die letzten sechs Beiträge:

Über mich

Wie viele ....

Random Post
Search
  • Home
  • Tag Archives:  ZigBee
Search
  • Window- Doorsensor Monitoring with ZigBee2MQTT, Node-RED on a Raspi

    Overview

    This Node-RED flow is designed to monitor a ZigBee-based WC (restroom) window sensor. It detects the window status (open/closed) and monitors the sensor’s battery level. Relevant state changes trigger Pushover notifications. Now a new Version is online V1.1 with little improvements in the Dashboard when the flow starts.

    Features

    • Window Status Detection: Identifies whether the window is open or closed.
    • Battery Status Monitoring: Keeps track of the sensor’s battery level.
    • Notification System: Sends Pushover notifications when the sensor contact is open for a adjustable time, when the sensor will be closed or the battery level is low.

    Requirements

    • Node-RED installed
    • ZigBee sensor compatible with Node-RED (i have used the Aquara MCCGQ11LM)
    • Pushover credentials to use the notification feature

    Installation

    1. Install Node-RED your desired system.
    2. Required Nodes: Dashboard, Pushover, ZigBee2MQTT, node-red-contrib-ui-led
    3. Import the flow into Node-RED.
    4. Create an Pushover Account if you don´t have
    5. Configure the required Pushover Api Node with your credentials.
    6. Activate and test the flow.

    Usage

    • The flow runs automatically in the background and monitors the sensor.
    • A push notification is sent if the window is opened for an adjustable time, when it ist closed or the battery is low.

    License

    This project is licensed under the MIT License.

    Contact

    For questions or improvements, feel free to open an issue on GitHub or submit a pull request. Or write me an via the Contact Page: https://edi.teppert.com/contact

    Node-Red Flow

    The flow (Download here) is available as a JSON file in the project and can be downloaded or the JSON code can be copied

     


    Here you will find the GitHub Repositroy:

    https://github.com/EdiTep/ZigBee2MQTT-Aquara-Sensor

    The Flow V 1.1 of the Project (Downlod here):

    [
        {
            "id": "d6070f5350480dbb",
            "type": "zigbee2mqtt-in",
            "z": "4e6fdb9451843a3d",
            "g": "59e1941a3b68e077",
            "name": "WC Fenster Sensor",
            "server": "1bfcccb11dd30d19",
            "friendly_name": "WCFensterSensor (MCCGQ11LM)",
            "device_id": "0x00158d008b117102",
            "state": "contact",
            "outputAtStartup": false,
            "filterChanges": true,
            "enableMultiple": false,
            "x": 144,
            "y": 100,
            "wires": [
                [
                    "2e1f096ac9e37b56",
                    "dea796bef74cd015",
                    "b968904d4861c3ab"
                ]
            ]
        },
        {
            "id": "cf468edabe628d0d",
            "type": "pushover api",
            "z": "4e6fdb9451843a3d",
            "g": "59e1941a3b68e077",
            "keys": "d24db8d2d165ad26",
            "title": "WC Fenster Meldung",
            "name": "WC Fenster Meldung",
            "x": 1074,
            "y": 280,
            "wires": []
        },
        {
            "id": "382888c4c7c1315e",
            "type": "zigbee2mqtt-in",
            "z": "4e6fdb9451843a3d",
            "g": "59e1941a3b68e077",
            "name": "WC Fenster Sensor Akku",
            "server": "1bfcccb11dd30d19",
            "friendly_name": "WCFensterSensor (MCCGQ11LM)",
            "device_id": "0x00158d008b117102",
            "state": "battery",
            "outputAtStartup": true,
            "filterChanges": false,
            "enableMultiple": false,
            "x": 164,
            "y": 340,
            "wires": [
                [
                    "8d8e2ed54aaa2a81",
                    "2abbd3a4ad5102dd"
                ]
            ]
        },
        {
            "id": "2e1f096ac9e37b56",
            "type": "function",
            "z": "4e6fdb9451843a3d",
            "g": "59e1941a3b68e077",
            "name": "Fenster Zustand auswerten",
            "func": "if (msg.payload === true || msg.payload === 'true') {\n    return [null, msg]; // Open (true) -> second output\n} else if (msg.payload === false || msg.payload === 'false') {\n    return [msg, null]; // Closed (false) -> first output\n} else {\n    return null; // Ignore other values\n}",
            "outputs": 2,
            "timeout": "",
            "noerr": 0,
            "initialize": "",
            "finalize": "",
            "libs": [],
            "x": 214,
            "y": 240,
            "wires": [
                [
                    "6ca24693b4fd377e",
                    "2ceabb5369c7d016",
                    "434f42e55bd0d9f9"
                ],
                [
                    "6ca24693b4fd377e",
                    "ec487efa4e8c2ecf",
                    "434f42e55bd0d9f9"
                ]
            ]
        },
        {
            "id": "66cdc35624062665",
            "type": "comment",
            "z": "4e6fdb9451843a3d",
            "g": "59e1941a3b68e077",
            "name": "ZigBee Fenster im WC Sensor überwachen. Wenn Fenster 3 min. oder weitere 5 min. offen eine Pushover Nachricht schicken. Wenn Akku unter 5% ebenfalls",
            "info": "",
            "x": 574,
            "y": 60,
            "wires": []
        },
        {
            "id": "8d8e2ed54aaa2a81",
            "type": "function",
            "z": "4e6fdb9451843a3d",
            "g": "59e1941a3b68e077",
            "name": "Batteriestand überwachen",
            "func": "let batteryLevel = msg.payload;\n\n// Prüfe, ob der Batteriestand definiert ist und ≤ 5%\nif (batteryLevel !== undefined && batteryLevel <= 5) {\n    msg.payload = `Warnung: Der Batteriestand des WC-Fenster Sensors ist kritisch: ${batteryLevel}%`;\n    return msg;\n} else {\n    // Keine Nachricht senden, wenn der Batteriestand über 5% liegt\n    return null;\n}",
            "outputs": 1,
            "timeout": "",
            "noerr": 0,
            "initialize": "",
            "finalize": "",
            "libs": [],
            "x": 514,
            "y": 340,
            "wires": [
                [
                    "cf468edabe628d0d"
                ]
            ]
        },
        {
            "id": "b968904d4861c3ab",
            "type": "function",
            "z": "4e6fdb9451843a3d",
            "g": "59e1941a3b68e077",
            "name": "Fenster offen / zu Timer",
            "func": "const firstInterval = 3 * 60 * 1000; // 3 Minuten in Millisekunden\nconst secondInterval = 5 * 60 * 1000; // 5 Minuten in Millisekunden\n\n// Lade den letzten Zustand aus dem Kontext (Standard: null)\nconst lastState = context.get('lastState') || null;\n\n// Timer-Objekte initialisieren\nif (!context.firstInterval) context.firstInterval = null;\nif (!context.secondInterval) context.secondInterval = null;\n\nif (msg.payload === false) { // Fenster geöffnet\n    // Nur bei einer Zustandsänderung von geschlossen nach offen ausführen\n    if (lastState !== false) {\n        // Aktualisiere den letzten Zustand\n        context.set('lastState', false);\n\n        // Wenn kein Timer aktiv ist, erstelle einen\n        if (!context.firstInterval && !context.secondInterval) {\n            // Starte den einmaligen Verzögerungstimer für die erste Meldung\n            context.firstInterval = setTimeout(() => {\n                node.send({ payload: 'WC Fenster ist offen!' }); // Erste Nachricht nach 3 Minuten senden\n\n                // Starte wiederholten Timer nach der ersten Meldung\n                context.secondInterval = setInterval(() => {\n                    node.send({ payload: 'WC Fenster ist immer noch offen!' });\n                }, secondInterval);\n            }, firstInterval);\n        }\n    }\n} else if (msg.payload === true) { // Fenster geschlossen\n    // Nur bei einer Zustandsänderung von offen nach geschlossen ausführen\n    if (lastState !== true) {\n        // Aktualisiere den letzten Zustand\n        context.set('lastState', true);\n\n        // Lösche den ersten Verzögerungstimer, falls er noch läuft\n        if (context.firstInterval) {\n            clearTimeout(context.firstInterval);\n            context.firstInterval = null;\n        }\n\n        // Lösche den wiederholten Timer\n        if (context.secondInterval) {\n            clearInterval(context.secondInterval);\n            context.secondInterval = null;\n        }\n\n        // Nachricht senden, dass das Fenster geschlossen wurde\n        node.send({ payload: 'WC Fenster wurde geschlossen' });\n    }\n}\n\nreturn null;\n",
            "outputs": 1,
            "timeout": "",
            "noerr": 0,
            "initialize": "",
            "finalize": "",
            "libs": [],
            "x": 504,
            "y": 100,
            "wires": [
                [
                    "d76908ac9eaae204",
                    "cf468edabe628d0d"
                ]
            ],
            "info": "const firstInterval = 3 * 60 * 1000; // 3 Minuten in Millisekunden\nconst secondInterval = 5 * 60 * 1000; // 5 Minuten in Millisekunden\n\n// Timer-Objekte initialisieren\nif (!context.firstInterval) {\n    context.firstInterval = null;\n}\nif (!context.secondInterval) {\n    context.secondInterval = null;\n}\n\nif (msg.payload === false) { // Fenster geöffnet\n    // Wenn kein Timer aktiv ist, erstelle einen\n    if (!context.firstInterval && !context.secondInterval) {\n        // Starte den einmaligen Verzögerungstimer für die erste Meldung\n        context.firstInterval = setTimeout(() => {\n            node.send({ payload: 'Fenster ist offen!' }); // Erste Nachricht nach 3 Minuten senden\n\n            // Starte wiederholten Timer nach der ersten Meldung\n            context.secondInterval = setInterval(() => {\n                node.send({ payload: 'Fenster ist immer noch offen!' });\n            }, secondInterval);\n        }, firstInterval);\n    }\n} else if (msg.payload === true) { // Fenster geschlossen\n    // Lösche den ersten Verzögerungstimer, falls er noch läuft\n    if (context.firstInterval) {\n        clearTimeout(context.firstInterval);\n        context.firstInterval = null;\n    }\n\n    // Lösche den wiederholten Timer\n    if (context.secondInterval) {\n        clearInterval(context.secondInterval);\n        context.secondInterval = null;\n    }\n\n    node.send({ payload: 'Fenster wurde geschlossen' }); // Nachricht für Schließen\n}\n\nreturn null;\n"
        },
        {
            "id": "d76908ac9eaae204",
            "type": "debug",
            "z": "4e6fdb9451843a3d",
            "g": "59e1941a3b68e077",
            "name": "Fenster auf / zu Meldungen",
            "active": true,
            "tosidebar": true,
            "console": false,
            "tostatus": true,
            "complete": "payload",
            "targetType": "msg",
            "statusVal": "payload",
            "statusType": "auto",
            "x": 1054,
            "y": 100,
            "wires": []
        },
        {
            "id": "6ca24693b4fd377e",
            "type": "debug",
            "z": "4e6fdb9451843a3d",
            "g": "59e1941a3b68e077",
            "name": "Fenster Zustand",
            "active": true,
            "tosidebar": true,
            "console": false,
            "tostatus": true,
            "complete": "payload",
            "targetType": "msg",
            "statusVal": "payload",
            "statusType": "auto",
            "x": 654,
            "y": 215,
            "wires": []
        },
        {
            "id": "80479bbf8f11d3f4",
            "type": "ui_text",
            "z": "4e6fdb9451843a3d",
            "g": "59e1941a3b68e077",
            "group": "507542867a7bb60c",
            "order": 1,
            "width": 6,
            "height": 2,
            "name": "WC Fenster Zustand",
            "label": "",
            "format": "{{msg.payload}}",
            "layout": "col-center",
            "className": "",
            "style": true,
            "font": "Arial Black,Arial Black,Gadget,sans-serif",
            "fontSize": "18",
            "color": "#000000",
            "x": 1074,
            "y": 200,
            "wires": []
        },
        {
            "id": "2abbd3a4ad5102dd",
            "type": "ui_gauge",
            "z": "4e6fdb9451843a3d",
            "g": "59e1941a3b68e077",
            "name": "",
            "group": "507542867a7bb60c",
            "order": 3,
            "width": 3,
            "height": 3,
            "gtype": "gage",
            "title": "Akku Sensor Kapazität",
            "label": "%",
            "format": "{{value}} %",
            "min": 0,
            "max": "100",
            "colors": [
                "#ab3f38",
                "#e6e600",
                "#50b232"
            ],
            "seg1": "",
            "seg2": "",
            "diff": false,
            "className": "",
            "x": 1074,
            "y": 320,
            "wires": []
        },
        {
            "id": "434f42e55bd0d9f9",
            "type": "ui_led2",
            "z": "4e6fdb9451843a3d",
            "g": "59e1941a3b68e077",
            "order": 2,
            "group": "507542867a7bb60c",
            "width": 3,
            "height": 3,
            "label": "",
            "property": "payload",
            "labelPlacement": "left",
            "labelAlignment": "left",
            "colorForValue": [
                {
                    "color": "#ff0000",
                    "value": "false",
                    "valueType": "bool"
                },
                {
                    "color": "#008000",
                    "value": "true",
                    "valueType": "bool"
                }
            ],
            "allowColorForValueInMessage": false,
            "shape": "circle",
            "showGlow": true,
            "name": "WC Fenster LED",
            "x": 1064,
            "y": 240,
            "wires": []
        },
        {
            "id": "ec487efa4e8c2ecf",
            "type": "change",
            "z": "4e6fdb9451843a3d",
            "g": "59e1941a3b68e077",
            "name": "true = GESCHLOSSEN",
            "rules": [
                {
                    "t": "set",
                    "p": "payload",
                    "pt": "msg",
                    "to": "WC Fenster geschlossen",
                    "tot": "str"
                }
            ],
            "action": "",
            "property": "",
            "from": "",
            "to": "",
            "reg": false,
            "x": 504,
            "y": 140,
            "wires": [
                [
                    "80479bbf8f11d3f4"
                ]
            ]
        },
        {
            "id": "2ceabb5369c7d016",
            "type": "change",
            "z": "4e6fdb9451843a3d",
            "g": "59e1941a3b68e077",
            "name": "false = OFFEN",
            "rules": [
                {
                    "t": "set",
                    "p": "payload",
                    "pt": "msg",
                    "to": "WC Fenster OFFEN",
                    "tot": "str"
                }
            ],
            "action": "",
            "property": "",
            "from": "",
            "to": "",
            "reg": false,
            "x": 474,
            "y": 180,
            "wires": [
                [
                    "80479bbf8f11d3f4"
                ]
            ]
        },
        {
            "id": "dea796bef74cd015",
            "type": "debug",
            "z": "4e6fdb9451843a3d",
            "g": "59e1941a3b68e077",
            "name": "true / false",
            "active": true,
            "tosidebar": true,
            "console": false,
            "tostatus": true,
            "complete": "payload",
            "targetType": "msg",
            "statusVal": "payload",
            "statusType": "auto",
            "x": 204,
            "y": 180,
            "wires": []
        },
        {
            "id": "50d078fac87374bc",
            "type": "inject",
            "z": "4e6fdb9451843a3d",
            "g": "59e1941a3b68e077",
            "name": "Zustand auslesen",
            "props": [
                {
                    "p": "payload"
                }
            ],
            "repeat": "",
            "crontab": "",
            "once": true,
            "onceDelay": 0.1,
            "topic": "",
            "payload": "",
            "payloadType": "date",
            "x": 164,
            "y": 287,
            "wires": [
                [
                    "9dbc4a01fcccd9e5"
                ]
            ]
        },
        {
            "id": "9dbc4a01fcccd9e5",
            "type": "zigbee2mqtt-get",
            "z": "4e6fdb9451843a3d",
            "g": "59e1941a3b68e077",
            "name": "Zustand WC Fenster",
            "server": "1bfcccb11dd30d19",
            "friendly_name": "WCFensterSensor (MCCGQ11LM)",
            "device_id": "0x00158d008b117102",
            "state": "contact",
            "enableMultiple": false,
            "x": 394,
            "y": 287,
            "wires": [
                [
                    "edd7a5bdcb67cbea",
                    "2e1f096ac9e37b56"
                ]
            ]
        },
        {
            "id": "edd7a5bdcb67cbea",
            "type": "debug",
            "z": "4e6fdb9451843a3d",
            "g": "59e1941a3b68e077",
            "name": "Zustand",
            "active": true,
            "tosidebar": true,
            "console": false,
            "tostatus": true,
            "complete": "payload",
            "targetType": "msg",
            "statusVal": "payload",
            "statusType": "auto",
            "x": 634,
            "y": 287,
            "wires": []
        },
        {
            "id": "1bfcccb11dd30d19",
            "type": "zigbee2mqtt-server",
            "name": "Sonoff ZigBee Raspi",
            "host": "Raspi",
            "mqtt_port": "1883",
            "mqtt_username": "raspi",
            "mqtt_password": "Password",
            "mqtt_qos": "2",
            "tls": "",
            "usetls": false,
            "base_topic": "zigbee2mqtt"
        },
        {
            "id": "d24db8d2d165ad26",
            "type": "pushover-keys",
            "name": "Fenster Alarm Pushover (Gruppe)"
        },
        {
            "id": "507542867a7bb60c",
            "type": "ui_group",
            "name": "WC Fenster Überwachung",
            "tab": "b1a7800aebadd728",
            "order": 3,
            "disp": true,
            "width": "6",
            "collapse": false,
            "className": ""
        },
        {
            "id": "b1a7800aebadd728",
            "type": "ui_tab",
            "name": "ZigBee Geräte Überwachung",
            "icon": "bug_report",
            "order": 6,
            "disabled": false,
            "hidden": false
        }
    ]

     

  • Heim Automation – IoT mit Raspi, Node-Red, MQTT, iOBroker uvm.

    Seit dem Einzug ins eigene Heim hat sich bei dem Thema Heim Automation bei mir vieles entwickelt, liegt wohl auch daran, dass ich beruflich in der IT arbeite und es unglaublich viel Spaß macht wenn man beim Programmieren oder Elektronik basteln, löten, messen ein Ergebnis sieht, das auch etwas bewegt oder steuert und nicht nur einfach ein Programm abläuft.

    # Programm zur Raspberry Pi GPIO Steuerung mit Python 
    
    import RPi.GPIO as GPIO
    import time
    import sys
    
    # GPIO PIN Nummer
    SwitchNummer = 27
    
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(SwitchNummer, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    
    def read_gpio(pin):
    stable_value = GPIO.input(pin)
    start_time = time.time()
    while time.time() - start_time < 0.05: # 50ms debounce time
    if GPIO.input(pin) != stable_value:
    start_time = time.time()
    stable_value = GPIO.input(pin)
    return stable_value
    
    # Variable zum Verfolgen des anfaenglichen Schalterzustands
    schalter_zustand = GPIO.input(SwitchNummer)
    
    print('GPIO PIN 27 Zustand anzeigen')
    schalter_zustand = GPIO.input(SwitchNummer)
    
    if schalter_zustand == 0:
    print("Schalter geöffnet")
    sys.exit(0) # GPIO is HIGH
    else:
    print("Schalter GESCHLOSSEN")
    sys.exit(1) # GPIO is LOW
    
    # (c) ETe 2024-10
    

    Angefangen hat es mit dem Raspiberry Pi, den ich zur Überwachung und Steuerung meines Garagentors genutzt habe. Zu Beginn hab ich Python Scripte geschrieben, die nach eingehendem Funktionstest als Dienst auf dem Raspi laufen und ihre Aufgabe erfüllen. Da die Benachrichtigung per SMS vom Raspi aus schwierig und  vermutlich auch kostenpflichtig gewesen wäre, habe ich  andere Lösungen gesucht und auch gefunden. Pushover ist ein Dienst, der bis zu einem Aufkommen von 10000 Nachrichten / Monat kostenlos ist. In Python hab ich das für mich programmiert, es ist auch gut möglich in Node-Red oder im iOBroker. Alle anderen HA Plattformen unterstützen es bestimmt auch.

    Inzwischen habe ich so einiges an IoT Geräten im Einsatz, die unter anderem zum Steuern von Steckdosen oder dem Warmwasserspeicher zum Einsatz kommen. Mit den ermittelten Werten aus der PV Anlage mit Akku kann so der erzeugte Strom effizient genutzt werden in dem Zeiten wo überschüssige Energie vorhanden ist.

    Zum Einsatz kommt dazu unter Anderem sehr intensiv Node-Red. Grundlage vieler Algorithmen ist der MQTT-Broker Mosquito, der wie auch Node-Red auf dem Raspi laufen. iOBroker ist auch im Einsatz, für den gibt es unzählige Adapter, die so ziemlich alles steuern können. Ich habe ihn im Einsatz um mit der Visualisierung iQontrol meine Rollläden zu steuern.

    Ein Gebiet für das es jeden Tag neue Ideen und Herausforderungen gibt. Es wird nie langweilig (zumindest mir nicht). Mit jedem Projekt wächst man mehr in die verschiedenen Programme hinein und kann besser damit umgehen. Beim Programmieren bleibt auch der Geist aktiv und wach, das ist für die Gesundheit hilfreich, sofern man es nicht übertreibt und andere Dinge auf der Strecke bleiben.

    Mal sehen was ich hier so alles zusammentragen werde.

    Gruß

    Edi