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 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 »
Dans appareil cliquez sur le bouton « Nouveau + »
créez un appareil virtuel comme suit
vous aurez ensuite un appareil qui devrait être celui-ci
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 »
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 ) 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
La 2de concerne la translation entre le topic et le payload issu de Zigbee2Mqtt vers le topic et le payload attendu par Gladys
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 !
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 comme on le voit pour Mqtt et Node-red )
Si les valeurs sont correctes, les nodes « mqtt » apparaitront « connecté » en vert
Voila c’est fini, dans le dashboard de Gladys vous pouvez commuter la prise « Nous-5 » en utilisant la prise virtuel « Z2M-NOUS-5 »
et voir sa consommation
Voila s’il y a des suggestions ou améliorations ou des erreurs n’hésitez pas…
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