Détection d'une panne de courant

Salut à tous,

J’ai créé une scène qui pourrait en intéresser quelques un : la détection d’une coupure de courant à la maison et l’alerte via Telegram.

Niveau du scénario : Avancé

Ce scénario utilise des fonctionnalités pas encore présentes dans Gladys. Pour passer outre, j’ai utilisé Node-Red, installé sur le même Raspberry Pi.

:arrow_forward: Documentation officielle de Gladys sur le sujet : Intégrer Node-RED avec Gladys Assistant en MQTT | Gladys Assistant

Prérequis

J’utilise chez moi 100% du Zigbee. Pour cette scène, j’utilise deux composants dont un n’est pas connecté :

Voici un schéma qui représente (dans l’ordre) : la prise connectée, l’onduleur, la multiprise (pour la box fibre) et le raspberry pi avec Gladys et Node Red.

Pourquoi un onduleur ?

Cela permet, en cas de coupure de courant dans la maison, de continuer à alimenter Gladys en électricité.

Comment détecter une panne de courant ?

L’idée est très simple, il y a une panne de courant si :

  • ma prise connectée ne consomme plus d’énergie (attention, si elle est éteinte cela sera aussi détecté)
  • ma prise n’envoie plus de données pendant plus d’une minute

C’est ce second point qui n’est pas encore géré (à ma connaissance) par Gladys à l’heure où j’écris ces lignes.

Configuration de Node Red

Il faut installer Node Red et configurer l’interconnexion avec Zigbee2MQTT (couvert déjà par un grand nombre de tutos).

Schéma général

Comment faire ?

  1. Dans un premier temps, stocker la dernière valeur renvoyée par la prise connectée dans un fichier.




    J’ajoute la brique « Get Complete State » pour m’assurer d’avoir toutes les données de la prise. Ensuite « Add timestamp » me permet d’ajouter la date de la réception des données que je stocke enfin dans un fichier appelé arbitrairement « prise_nous2_last_data.txt ».

    image

    image

  2. Ensuite je lis ce fichier toutes les minutes et je compare la date qu’il contient avec l’heure actuelle moins une minute.



    image

    La brique « Parse JSON » est nécessaire pour pouvoir utiliser les données stockée dans le fichier correctement.
    image

    Puis avec un bloc de fonction, je calcule l’heure en cours, moins une minute :
    image

    Enfin, je procède à deux tests avec les deux briques « switch mode » : si la prise consomme moins de 5W ou si la date a dépassé 1 minute :
    image

    image

    Pour terminer, je créé un message à envoyer dans Telegra avec le dernier bloc « JSON » :
    image

Export JSON Node Red
[
    {
        "id": "877e6dde4f64094e",
        "type": "tab",
        "label": "Panne de courant",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "2d047039d3727cc5",
        "type": "zigbee2mqtt-in",
        "z": "877e6dde4f64094e",
        "name": "PriseNous2 (Onduleur)",
        "server": "6dda341ee7a029cb",
        "friendly_name": "PriseNous2",
        "device_id": "REDACTED",
        "state": "0",
        "outputAtStartup": true,
        "x": 140,
        "y": 160,
        "wires": [
            [
                "9cc8b65f8ce767af"
            ]
        ]
    },
    {
        "id": "c57fa22873f8262e",
        "type": "file",
        "z": "877e6dde4f64094e",
        "name": "Write file",
        "filename": "prise_nous2_last_data.txt",
        "filenameType": "str",
        "appendNewline": false,
        "createDir": false,
        "overwriteFile": "true",
        "encoding": "none",
        "x": 740,
        "y": 160,
        "wires": [
            []
        ]
    },
    {
        "id": "3c9969810f1b7d9c",
        "type": "file in",
        "z": "877e6dde4f64094e",
        "name": "Read file",
        "filename": "prise_nous2_last_data.txt",
        "filenameType": "str",
        "format": "utf8",
        "chunk": false,
        "sendError": false,
        "encoding": "none",
        "allProps": false,
        "x": 300,
        "y": 320,
        "wires": [
            [
                "393212bfa20c5210"
            ]
        ]
    },
    {
        "id": "4f2d7369b4194a31",
        "type": "inject",
        "z": "877e6dde4f64094e",
        "name": "Every minutes",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "10",
        "crontab": "",
        "once": false,
        "onceDelay": "60",
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 140,
        "y": 320,
        "wires": [
            [
                "3c9969810f1b7d9c"
            ]
        ]
    },
    {
        "id": "21bca9ada5443cb1",
        "type": "change",
        "z": "877e6dde4f64094e",
        "name": "Add timestamp",
        "rules": [
            {
                "t": "set",
                "p": "payload.timestamp",
                "pt": "msg",
                "to": "",
                "tot": "date"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 580,
        "y": 160,
        "wires": [
            [
                "c57fa22873f8262e"
            ]
        ]
    },
    {
        "id": "d32f71ec6761bdda",
        "type": "switch",
        "z": "877e6dde4f64094e",
        "name": "Test timestamp",
        "property": "payload.timestamp",
        "propertyType": "msg",
        "rules": [
            {
                "t": "lt",
                "v": "payload.lastminutetimestamp",
                "vt": "msg"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 880,
        "y": 320,
        "wires": [
            [
                "cabbc5db0e4652b6",
                "e803e70cdfe1f77a"
            ]
        ]
    },
    {
        "id": "09bee4816c7b6a4b",
        "type": "function",
        "z": "877e6dde4f64094e",
        "name": "Get last 1 minute timestamp",
        "func": "var oneMinInMs = 60000;\nvar lastminute = Date.now() - oneMinInMs;\nmsg.payload.lastminutetimestamp = lastminute;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 660,
        "y": 320,
        "wires": [
            [
                "d32f71ec6761bdda"
            ]
        ]
    },
    {
        "id": "cabbc5db0e4652b6",
        "type": "debug",
        "z": "877e6dde4f64094e",
        "name": "PANNE DE COURANT",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 910,
        "y": 280,
        "wires": []
    },
    {
        "id": "393212bfa20c5210",
        "type": "json",
        "z": "877e6dde4f64094e",
        "name": "Parse JSON",
        "property": "payload",
        "action": "",
        "pretty": false,
        "x": 450,
        "y": 320,
        "wires": [
            [
                "09bee4816c7b6a4b",
                "af16ab7a64e96d55"
            ]
        ]
    },
    {
        "id": "1868c1c355f975cf",
        "type": "telegram sender",
        "z": "877e6dde4f64094e",
        "name": "Telegram",
        "bot": "REDACTED",
        "haserroroutput": false,
        "outputs": 1,
        "x": 1500,
        "y": 320,
        "wires": [
            []
        ]
    },
    {
        "id": "dfaa974da87838fe",
        "type": "function",
        "z": "877e6dde4f64094e",
        "name": "JSON TELEGRAM",
        "func": "msg.payload = {\n    chatId: REDACTED,\n    type: 'message',\n    content: '⚡‼️ Panne de courant détectée à la maison'\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1330,
        "y": 320,
        "wires": [
            [
                "1868c1c355f975cf"
            ]
        ]
    },
    {
        "id": "e803e70cdfe1f77a",
        "type": "switch",
        "z": "877e6dde4f64094e",
        "name": "Test Power > 5W",
        "property": "payload.power",
        "propertyType": "msg",
        "rules": [
            {
                "t": "lt",
                "v": "5",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 1110,
        "y": 320,
        "wires": [
            [
                "dfaa974da87838fe"
            ]
        ]
    },
    {
        "id": "af16ab7a64e96d55",
        "type": "debug",
        "z": "877e6dde4f64094e",
        "name": "READ FILE",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 450,
        "y": 360,
        "wires": []
    },
    {
        "id": "9cc8b65f8ce767af",
        "type": "zigbee2mqtt-get",
        "z": "877e6dde4f64094e",
        "name": "Get Complete State",
        "server": "6dda341ee7a029cb",
        "friendly_name": "PriseNous2",
        "device_id": "REDACTED",
        "state": "0",
        "x": 370,
        "y": 160,
        "wires": [
            [
                "21bca9ada5443cb1"
            ]
        ]
    },
    {
        "id": "6dda341ee7a029cb",
        "type": "zigbee2mqtt-server",
        "name": "Zigbee2MQTT",
        "host": "127.0.0.1",
        "mqtt_port": "1884",
        "mqtt_username": "z2m",
        "mqtt_password": "REDACTED",
        "tls": "",
        "usetls": false,
        "base_topic": "zigbee2mqtt"
    },
    {
        "id": "1008fcc5ae346779",
        "type": "telegram bot",
        "botname": "Node Red Gladys Ermont",
        "usernames": "",
        "chatids": "REDACTED",
        "baseapiurl": "",
        "updatemode": "polling",
        "pollinterval": "300",
        "usesocks": false,
        "sockshost": "",
        "socksport": "6667",
        "socksusername": "anonymous",
        "sockspassword": "",
        "bothost": "",
        "botpath": "",
        "localbotport": "8443",
        "publicbotport": "8443",
        "privatekey": "",
        "certificate": "",
        "useselfsignedcertificate": false,
        "sslterminated": false,
        "verboselogging": false
    }
]

Conclusion

Si mon onduleur ne consomme plus de courant, c’est qu’il n’y a plus d’électricité à la maison. Dans ce cas, la prise connectée sur laquelle l’onduleur est connecté ne consommera plus de courant ou n’enverra plus de données.
Node Red me permet de réaliser cela assez facilement en réalité.

N’hésitez pas à me faire vos retours s’il faut expliciter encore plus certaines parties !

7 Likes

Super le tuto !

Je vais peut être le mettre en place chez moi car je suis déjà équipé en onduleur et prise connectée.
Jusqu’ici je me base sur les notifications de mon NAS qui m’indique lorsqu’il est passé sur l’onduleur… Maia une solution intégrée à Gladys serait top !

D’ailleurs à terme je pense que je vais utiliser / créer un onduleur dédié à Gladys sur mon Pi, comme ça je pourrais avoir une TRÈS longue autonomie en cas de panne, et ne perdrai pas mes scènes de surveillance / alarme de la maison :+1:

2 Likes

Merci pour ce tutoriel super complet @lmilcent ! J’ai édité le lien Domadoo avec un lien affilié comme demandé :wink:

2 Likes

Merci :blush:
Et oui, autant faire profiter tous le monde (tuto et lien affilié !).

Je trouve ça intéressant d’avoir ce genre de présentation de scènes, ça peut donner des idées.

1 Like