Mini-tuto Piloter dans Gladys un appareil Zigbee2Mqtt qui n'est pas encore reconnu par Gladys via Node-red

Ce mini-tuto propose de connecter un appareil reconnu dans zigbee2mqtt mais dont l’intégration n’existerais pas encore dans Gladys en utilisant node-red comme intermédiaire ! Plus d’excuse :slight_smile: pour ne pas utiliser Gladys !

Pour cela on va créer un appareil virtuel (ou virtual device) dans l’intégration MQTT de Gladys et un flow Node-red qu’il suffit d’importer et il faudra juste paramétrer en fonction de l’appareil à controler et de vos paramètres (IP de votre instance Gladys, mot de passe de Mqtt, mot de passe de Zigbee2Mqtt)

On commence :

Allez dans le menu « Intégrations »

Cliquez sur l’icône de l’intégration « MQTT »

image

Dans appareil cliquez sur le bouton « Nouveau + »

créez un appareil virtuel comme suit

vous aurez ensuite un appareil qui devrait être celui-ci

image

La partie création de l’appareil est terminée, il ne restera plus qu’a afficher cet appareil avec ces 2 features dans le dashboard de Gladys

Il y a 3 paramètres que l’on va réutiliser plus tard ce sont les topic de « Topic Mqtt pour publier » et « Topic Mqtt à écouter »

Allez dans node-red et cliquez sur « Importer »

image

Copiez le flux suivant ci-dessous et collez le puis cliquez sur « Importer »

Code du flow
[
    {
        "id": "064a844a10f278d0",
        "type": "tab",
        "label": "Gladys <=> Z2M",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "2bee4d2d30957c22",
        "type": "group",
        "z": "064a844a10f278d0",
        "style": {
            "stroke": "#999999",
            "stroke-opacity": "1",
            "fill": "none",
            "fill-opacity": "1",
            "label": true,
            "label-position": "nw",
            "color": "#a4a4a4"
        },
        "nodes": [
            "55b5362bb2f1081f",
            "e5974b74c4f0523d",
            "896b379f92909116",
            "267f8ce1755e49ee",
            "79f42f08d633eba1",
            "86df5045936db7d1",
            "350d4cab9b6ddfc6",
            "eba51d83ac887a1c",
            "3ad8cd81b2da503b",
            "1908d429c1d0cf06",
            "9b850e5047f189e9",
            "5faacded48aa4cc7"
        ],
        "x": 74,
        "y": 99,
        "w": 1112,
        "h": 222
    },
    {
        "id": "0cf88844315f110d",
        "type": "group",
        "z": "064a844a10f278d0",
        "style": {
            "stroke": "#999999",
            "stroke-opacity": "1",
            "fill": "none",
            "fill-opacity": "1",
            "label": true,
            "label-position": "nw",
            "color": "#a4a4a4"
        },
        "nodes": [
            "07dec9a2ad2f07cd",
            "780c7da37c4cc4bf",
            "7e369026c5674540",
            "f17aadce56f60a2f",
            "73cdf2a53b73da8f",
            "79365e2791c55807",
            "a7ad027dd87ce30b",
            "32c7a028d4dba351",
            "b0717d9927c1b6d8",
            "fceca8e194e04524"
        ],
        "x": 74,
        "y": 399,
        "w": 1062,
        "h": 182
    },
    {
        "id": "e5974b74c4f0523d",
        "type": "mqtt in",
        "z": "064a844a10f278d0",
        "g": "2bee4d2d30957c22",
        "name": "IP Gladys:1883",
        "topic": "#",
        "qos": "2",
        "datatype": "auto",
        "broker": "f4ab211ed11dc81c",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 180,
        "y": 180,
        "wires": [
            [
                "896b379f92909116",
                "55b5362bb2f1081f"
            ]
        ]
    },
    {
        "id": "896b379f92909116",
        "type": "debug",
        "z": "064a844a10f278d0",
        "g": "2bee4d2d30957c22",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 370,
        "y": 220,
        "wires": []
    },
    {
        "id": "267f8ce1755e49ee",
        "type": "debug",
        "z": "064a844a10f278d0",
        "g": "2bee4d2d30957c22",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1050,
        "y": 280,
        "wires": []
    },
    {
        "id": "79f42f08d633eba1",
        "type": "change",
        "z": "064a844a10f278d0",
        "g": "2bee4d2d30957c22",
        "name": "Test OFF",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "zigbee2mqtt/NOUS-5/set/state",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "OFF",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 800,
        "y": 240,
        "wires": [
            [
                "267f8ce1755e49ee",
                "350d4cab9b6ddfc6"
            ]
        ]
    },
    {
        "id": "86df5045936db7d1",
        "type": "inject",
        "z": "064a844a10f278d0",
        "g": "2bee4d2d30957c22",
        "name": "OFF",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "OFF",
        "payload": "gladys/device/mqtt:Z2M-NOUS-5/feature/mqtt:Z2M-NOUS-5-state/state",
        "payloadType": "str",
        "x": 550,
        "y": 240,
        "wires": [
            [
                "79f42f08d633eba1"
            ]
        ]
    },
    {
        "id": "07dec9a2ad2f07cd",
        "type": "mqtt in",
        "z": "064a844a10f278d0",
        "g": "0cf88844315f110d",
        "name": "IP Zigbee2Mqtt:1884",
        "topic": "zigbee2mqtt/NOUS-5",
        "qos": "2",
        "datatype": "auto",
        "broker": "16ae73273064273e",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 190,
        "y": 480,
        "wires": [
            [
                "780c7da37c4cc4bf",
                "b0717d9927c1b6d8"
            ]
        ]
    },
    {
        "id": "780c7da37c4cc4bf",
        "type": "debug",
        "z": "064a844a10f278d0",
        "g": "0cf88844315f110d",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 370,
        "y": 540,
        "wires": []
    },
    {
        "id": "350d4cab9b6ddfc6",
        "type": "mqtt out",
        "z": "064a844a10f278d0",
        "g": "2bee4d2d30957c22",
        "name": "IP Zigbee2Mqtt:1884",
        "topic": "",
        "qos": "",
        "retain": "",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "16ae73273064273e",
        "x": 1060,
        "y": 180,
        "wires": []
    },
    {
        "id": "eba51d83ac887a1c",
        "type": "inject",
        "z": "064a844a10f278d0",
        "g": "2bee4d2d30957c22",
        "name": "ON",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "ON",
        "payload": "gladys/device/mqtt:Z2M-NOUS-5/feature/mqtt:Z2M-NOUS-5-state/state",
        "payloadType": "str",
        "x": 550,
        "y": 280,
        "wires": [
            [
                "3ad8cd81b2da503b"
            ]
        ]
    },
    {
        "id": "3ad8cd81b2da503b",
        "type": "change",
        "z": "064a844a10f278d0",
        "g": "2bee4d2d30957c22",
        "name": "Test ON",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "zigbee2mqtt/NOUS-5/set/state",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "ON",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 800,
        "y": 280,
        "wires": [
            [
                "350d4cab9b6ddfc6",
                "267f8ce1755e49ee"
            ]
        ]
    },
    {
        "id": "1908d429c1d0cf06",
        "type": "debug",
        "z": "064a844a10f278d0",
        "g": "2bee4d2d30957c22",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 790,
        "y": 140,
        "wires": []
    },
    {
        "id": "7e369026c5674540",
        "type": "mqtt out",
        "z": "064a844a10f278d0",
        "g": "0cf88844315f110d",
        "name": "IP Gladys:1883",
        "topic": "",
        "qos": "",
        "retain": "",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "f4ab211ed11dc81c",
        "x": 1030,
        "y": 480,
        "wires": []
    },
    {
        "id": "f17aadce56f60a2f",
        "type": "inject",
        "z": "064a844a10f278d0",
        "g": "0cf88844315f110d",
        "name": "ON",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "ON",
        "payload": "gladys/master/device/mqtt:Heiman-On/feature/mqtt:Heiman-On/state",
        "payloadType": "str",
        "x": 540,
        "y": 540,
        "wires": [
            [
                "73cdf2a53b73da8f"
            ]
        ]
    },
    {
        "id": "73cdf2a53b73da8f",
        "type": "change",
        "z": "064a844a10f278d0",
        "g": "0cf88844315f110d",
        "name": "Test valeur 66",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "gladys/master/device/mqtt:Z2M-NOUS-5/feature/mqtt:Z2M-NOUS-5-power/text",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "66",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 810,
        "y": 540,
        "wires": [
            [
                "7e369026c5674540",
                "79365e2791c55807"
            ]
        ]
    },
    {
        "id": "79365e2791c55807",
        "type": "debug",
        "z": "064a844a10f278d0",
        "g": "0cf88844315f110d",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 1000,
        "y": 540,
        "wires": []
    },
    {
        "id": "a7ad027dd87ce30b",
        "type": "comment",
        "z": "064a844a10f278d0",
        "g": "0cf88844315f110d",
        "name": "Reception de Zigbee2Mqtt",
        "info": "",
        "x": 210,
        "y": 440,
        "wires": []
    },
    {
        "id": "32c7a028d4dba351",
        "type": "comment",
        "z": "064a844a10f278d0",
        "g": "0cf88844315f110d",
        "name": "Envoi à Gladys",
        "info": "",
        "x": 1030,
        "y": 440,
        "wires": []
    },
    {
        "id": "9b850e5047f189e9",
        "type": "comment",
        "z": "064a844a10f278d0",
        "g": "2bee4d2d30957c22",
        "name": "Reception de Gladys",
        "info": "",
        "x": 200,
        "y": 140,
        "wires": []
    },
    {
        "id": "5faacded48aa4cc7",
        "type": "comment",
        "z": "064a844a10f278d0",
        "g": "2bee4d2d30957c22",
        "name": "Envoi à Zigbee2Mqtt",
        "info": "",
        "x": 1050,
        "y": 140,
        "wires": []
    },
    {
        "id": "55b5362bb2f1081f",
        "type": "function",
        "z": "064a844a10f278d0",
        "g": "2bee4d2d30957c22",
        "name": "Gladys => zigbee2mqtt",
        "func": "var inputTopic = msg.topic;\nvar inputPayload = msg.payload;\n\n// Logique pour changer le topic et le payload en fonction à la fois du topic et du payload en entrée\n\nif (inputTopic === \"gladys/device/mqtt:Z2M-NOUS-5/feature/mqtt:Z2M-NOUS-5-state/state\" && inputPayload === \"0\") {\n  // adaption du topic et du payload de Gladys à zigbee2mqtt \n  msg.topic = \"zigbee2mqtt/NOUS-5/set/state\"; msg.payload = \"OFF\";\n} \n\nif (inputTopic === \"gladys/device/mqtt:Z2M-NOUS-5/feature/mqtt:Z2M-NOUS-5-state/state\" && inputPayload === \"1\") {\n  // adaption du topic et du payload de Gladys à zigbee2mqtt \n  msg.topic = \"zigbee2mqtt/NOUS-5/set/state\"; msg.payload = \"ON\";\n}\n\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 590,
        "y": 180,
        "wires": [
            [
                "1908d429c1d0cf06",
                "350d4cab9b6ddfc6"
            ]
        ]
    },
    {
        "id": "b0717d9927c1b6d8",
        "type": "function",
        "z": "064a844a10f278d0",
        "g": "0cf88844315f110d",
        "name": " zigbee2mqtt => Gladys",
        "func": "var inputTopic = msg.topic;\nvar inputPayload = JSON.parse(msg.payload);\n\n// Logique pour changer le topic et le payload en fonction à la fois du topic et du payload en entrée\nif (msg.topic === \"zigbee2mqtt/NOUS-5\") {\n    \n    \n    // si il ya la valeur \"state\" dans le json envoyé dans l payload de zigbee2mqtt\n    if (inputPayload.hasOwnProperty('state')) {\n        // adaption du topic de Gladys à zigbee2mqtt \n        msg.topic = \"gladys/device/mqtt:Z2M-NOUS-5/feature/mqtt:Z2M-NOUS-5-state/state\";\n        // adaption du payload de zigbee2mqtt à Gladys \n        var payloadValue = inputPayload.state;\n        msg.payload = payloadValue;\n    } else {\n        // Si la clé 'power' n'est pas présente, définit la sortie sur \"defaut\"\n        msg.payload = \"defaut\";\n    }\n    \n    // si il ya la valeur \"power\" dans le json envoyé dans l payload de zigbee2mqtt\n    if (inputPayload.hasOwnProperty('power')) {\n        // adaption du topic de Gladys à zigbee2mqtt \n        msg.topic = \"gladys/master/device/mqtt:Z2M-NOUS-5/feature/mqtt:Z2M-NOUS-5-power/text\";\n        // adaption du payload de zigbee2mqtt à Gladys \n        var payloadValue = inputPayload.power;\n        msg.payload = payloadValue;\n    } else {\n        // Si la clé 'power' n'est pas présente, définit la sortie sur \"defaut\"\n        msg.payload = \"defaut\";\n    }\n}\n\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 580,
        "y": 480,
        "wires": [
            [
                "7e369026c5674540",
                "fceca8e194e04524"
            ]
        ]
    },
    {
        "id": "fceca8e194e04524",
        "type": "debug",
        "z": "064a844a10f278d0",
        "g": "0cf88844315f110d",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 780,
        "y": 440,
        "wires": []
    },
    {
        "id": "f4ab211ed11dc81c",
        "type": "mqtt-broker",
        "name": "192.168.0.125:1883",
        "broker": "192.168.0.125",
        "port": "1883",
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "autoUnsubscribe": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": ""
    },
    {
        "id": "16ae73273064273e",
        "type": "mqtt-broker",
        "name": "",
        "broker": "192.168.0.125",
        "port": "1884",
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "autoUnsubscribe": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthRetain": "false",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closeRetain": "false",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willRetain": "false",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": ""
    }
]

PS : code mis à jour 07/11/2023

Vous obtiendrez un flux comme celui-ci

Connectez-vous sur l’url de la page zigbee2mqtt du docker

Vous arriverez sur la page du broker Zigbee2Mqtt

Sélectionnez le device zigbee2mqtt à contrôler, dans l’exemple c’est une prise NOUS A1Z (device déjà contrôlé par Gladys mais c’est pour l’exemple :wink:) elle porte le nom « NOUS-5 »

Quand vous êtes dans la page paramètre, allez sur l’onglet état, il donne le json échangé entre zigbee2mqtt et l’extérieur, ici on va utiliser 2 valeurs pour l’exemple

  • une (in-out) qui sert a contrôler l’allumage ou l’extinction de la prise : state
  • une autre (out) qui envoie la puissance consommée de la prise : power

    C’est ce json qui faudra copier dans le code du flow en cas d’adaptation pour un autre matériel

Maintenant on retourne dans node-red, on retrouve 2 zones de code

La 1ère concerne la translation entre le topic et le payload issu de Gladys vers le topic et le payload attendu par Zigbee2Mqtt

image

La 2de concerne la translation entre le topic et le payload issu de Zigbee2Mqtt vers le topic et le payload attendu par Gladys

image

Dans les 2 cas les valeurs à changer en fonction de l’appareil virtuel mqtt et du matériel Zigbee2Mqtt à controler sont en rouge

les paramètrage des node « mqqt » (port 1883 pour Mqtt, 1884 pour Zigbee2Mqtt), il faut impérativement l’adresse IP de votre Gladys dans les nodes mqtt pour que les trames sortent vers l’extérieur des containers !

image

image

image

image

Pour ce qui concernes le port 1883 le nom d’utisateur et le mot de passe se trouves dans Gladys

Pour ce qui concernes le port 1884 (Zigbee2Mqtt) le nom d’utisateur et le mot de passe se trouves dans le fichier « configuration.yaml » qui se trouves dans le repertoire « var/lib/gladysassistant/zigbee2mqtt/z2m » dans la section « mqtt: »
(ce serait bien de pouvoir le visualiser dans l’intégration Zigbee2Mqtt :woozy_face: comme on le voit pour Mqtt et Node-red :blush:)

Si les valeurs sont correctes, les nodes « mqtt » apparaitront « connecté » en vert

image

image

Voila c’est fini, dans le dashboard de Gladys vous pouvez commuter la prise « Nous-5 » en utilisant la prise virtuel « Z2M-NOUS-5 »

image

et voir sa consommation

image

Voila s’il y a des suggestions ou améliorations ou des erreurs n’hésitez pas… :wink:

PS: C’est grace à des infos trouvées sur le forum notamment pour le mot de passe zigbee2mqtt (@vonox dans une discussion] (@_Will_71 pour le virtual device de son tuto somfy) que j’ai pu faire ce mini-tuto

7 « J'aime »