Création d'un pont Jeedom vers HA

Hello

malgré mon switch quasi total, j’ai encore des choses non migré et surtout des choses qui ne pourront être migré (comme ma gestion d’alarme Protexiom Somfy).
Pourriez vous me guider sur la meilleure façon de faire un pont entre Jeedom et HA?

Prenons l’exemple de mon alarme Somfy
Dans mon équipement Jeedom j’ai :

  • 5 commandes action : Marche ABC, Arrêt ABC, Marche A, Marche B, Marche C
  • 4 commandes infos: Etat Alarme, Etat Zone A, Etat Zone B, Etat Zone C

Pour lancer une action sur Jeedom, j’avais dans la tête de créé un switch avec l’intégration command_line. Ce qui me permet de faire un appel vers l’API de la commande action.
Mais par contre, cela ne va pas géré le retour d’état. mon switch va rester sur On

Pour les commandes infos, j’ai publié l’état dans MQTT grâce au plugin JMQTT.
Mais par contre, les entités ne sont pas créés dans l’intégration MQTT…
pourtant je vois bien mon topic homeassistant/switch/Alarm_Somfy_ZoneA/sensor/ avec set = 0

Est ce que vous auriez des conseils pour moi?

Merci

Est-ce que tu as regardé l’API dans l’autre sens : Jeedom qui attaque lAPI de Home Assistant ?

Même si la solution la plus pérenne serait effectivement tout dans le serveur MQTT…

Dans le sens HA -> Jeedom et pour déclencher une action, tu peux faire des appels vers l’API jeedom en curl, par exemple avec l’intégration shell_command.

Pour ce qui est de récupérer des états, tu peux utiliser l’intégration rest:

sensor
  - platform: rest
      resource: "http://192.168.1.245/core/api/jeeApi.php?apikey=apitype=cmd&id=36"
      name: temperature_consigne
      unit_of_measurement: '°C'

Ca va créer un sensor qui va récupérer la valeur de l’id 36 du côté jeedom.

Et ensuite, sur tu as des capteurs du côté jeedom que tu veux envoyer vers HA, tu as l’« url de push global » voir https://community.jeedom.com/t/jeedom-vs-homeassistant/23687/10 pour les explications.

Avec ces trois points, j’arrive à avoir jeedom synchronisé avec HA (et réciproquement)
Mon réseau zwave est du côté jeedom et tourne sans interruption depuis 18 mois :slight_smile:
Tout les changements d’état des capteurs sont envoyés vers HA comme ça.
Ca marche tellement bien que je n’ai pas basculé le zwave en HA « natif ».

3 J'aime

@carfnann petite question: c’est quoi comme alarme Somfy ? J’en ai une aussi, mais je ne semble pas pouvoir la piloter via une box domotique :(.

Super idée d’utiliser le push global !
Tu peux partager ton flow Nodered, stp ? Il me reste quelques plugins et mon rfxcom qui tourne encore dessus …

Merci !

Et voilà…

[{"id":"6273e9a6.0704e8","type":"http in","z":"3ed32b34.880364","name":"Jeedom In","url":"/jeedom","method":"get","upload":false,"swaggerDoc":"","x":330,"y":350,"wires":[["5be0819d.013f2","82ae502a.84c94","3c3b2c34.7b2924","a173ab89.c1f568"]]},{"id":"5be0819d.013f2","type":"http response","z":"3ed32b34.880364","name":"","statusCode":"","headers":{},"x":520,"y":330,"wires":[]},{"id":"3c3b2c34.7b2924","type":"function","z":"3ed32b34.880364","name":"J2ssio","func":"var host = global.get(\"host\");\nvar token = global.get(\"token\");\n\nvar value = Number(msg.payload.value);\nvar objet_id = Number(msg.payload.id);\nvar entity_id = \"\";\n\nids = global.get(\"ids\");\nnames = global.get(\"names\");\nis_binary = global.get(\"binary\");\n\nentity_id = names[ids.indexOf(objet_id)];\nentity_binary = is_binary[ids.indexOf(objet_id)];\n\nif ( Boolean(entity_binary) ) {\n    if ( value === 1 ) { value = \"On\"; }\n    else { value = \"Off\" }\n}\n\nif ( entity_id === undefined ) {\n    msg.url = \"\";\n    msg.method = \"\";\n    msg.payload = \"\";\n    msg.headers = \"\";\n}\nelse {\n    msg.url = host + \"/api/states/\" + entity_id;\n    msg.method = \"POST\";\n    msg.payload = {\n       'state': value\n    }; \n    msg.headers = {\n        'Authorization': 'Bearer ' + token,\n        'content-type': 'application/json',\n    } ;\n}\nreturn msg;\n","outputs":1,"noerr":0,"x":520,"y":410,"wires":[["27ece8de.b09948"]]},{"id":"27ece8de.b09948","type":"switch","z":"3ed32b34.880364","name":"","property":"payload","propertyType":"msg","rules":[{"t":"nempty"},{"t":"else"}],"checkall":"false","repair":false,"outputs":2,"x":660,"y":410,"wires":[["76c583a2.063fcc"],[]]},{"id":"76c583a2.063fcc","type":"https-node","z":"3ed32b34.880364","name":"Hassio Out","method":"use","ret":"txt","url":"","authorized":false,"agent":true,"x":810,"y":410,"wires":[[]]},{"id":"1d321a0d.73bf76","type":"inject","z":"3ed32b34.880364","name":"","topic":"","payload":"","payloadType":"date","repeat":"900","crontab":"","once":true,"onceDelay":"2","x":360,"y":480,"wires":[["409aeef2.d2993"]]},{"id":"409aeef2.d2993","type":"file in","z":"3ed32b34.880364","name":"Sensors","filename":"/config/resources/jeedom/sensors.yaml","format":"utf8","chunk":false,"sendError":false,"encoding":"none","x":530,"y":480,"wires":[["dfdd3eb6.4b15e"]]},{"id":"dfdd3eb6.4b15e","type":"yaml","z":"3ed32b34.880364","property":"payload","name":"","x":680,"y":480,"wires":[["322c70df.d7297","eb15bf94.2e284"]]},{"id":"322c70df.d7297","type":"function","z":"3ed32b34.880364","name":"Charge","func":"var array_id = [];\nvar array_name = [];\nvar array_binary = [];\nglobal.set(\"ids\",\"\");\nglobal.set(\"names\",\"\");\nglobal.set(\"binary\",\"\");\nfor (var i=0; i<msg.payload.sensors.length;i++) {\n  array_id.push(msg.payload.sensors[i].id);\n  array_name.push(msg.payload.sensors[i].name);\n  array_binary.push(msg.payload.sensors[i].binary);\n}\nglobal.set(\"ids\", array_id);\nglobal.set(\"names\", array_name);\nglobal.set(\"binary\", array_binary);\nreturn msg;\n","outputs":1,"noerr":0,"x":830,"y":480,"wires":[[]]}]

Il faut créer un fichier des « sensors » que jeedom publie et que tu veux connaitre dans HA.

sensors:
- name: sensor.oeil_salon_presence
  binary: true
  id: 35
- name: sensor.oeil_salon_temperature
  binary: false
  id: 36 

Les id sont ceux de Jeedom.

Il faut également créer les variables qui sont utilisées.

[{"id":"65ed6d48.d79604","type":"inject","z":"3ed32b34.880364","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":"1","x":430,"y":170,"wires":[["47249f9b.aa531"]]},{"id":"47249f9b.aa531","type":"change","z":"3ed32b34.880364","name":"Parameters","rules":[{"t":"set","p":"host","pt":"global","to":"https://@IP_HA:8123","tot":"str"},{"t":"set","p":"token","pt":"global","to":"Le_Token","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":610,"y":170,"wires":[[]]}]

Il y a sûrement des trucs à améliorer la dedans. A l’époque mes connaissances en javascript étaient nulles ou presque. Deux ans après, je n’ai pas vraiment progressé. Je ne me suis donc pas replongé dans le code.

1 J'aime

C’est top ! Merci !!!
Je vais sans doute l’adapter pour pusher en mqtt !

1 J'aime

J’y ai pensé. Mais, la méthode de fonctionnement du plugin mqtt ou jmqtt rend ça, à mon avis, plus compliqué à gérer et maintenir.
Dans mon idée, je mets en place la configuration une fois sur jeedom (et ça marche pour tout) et je garde l’« intelligence » du côte Nodered/HA.
Si tu pars sur du MQTT, ça va être du 50/50 en terme de gestion (ou presque). C’est pour ça que je n’ai pas fait ce choix là.
Mais, bon, ça se discute!

Je comprends pas tout a fait ta remarque, je veux juste modifier ton noeud pour pusher dans mqtt plutôt que dans ha directement, et je garde la configuration côté jeedom.

Ca ajoute un étage d’abstraction mais ça reste conforme a l’utilisation que j’en fait avec mes autres devices (Zigbee2mqtt et zwave2mqtt)

Ah, ok. Je croyais que tu voulais pousser en MQTT depuis jeedom. En gros du jeedom2mqtt :slight_smile:

non non ce sera du jeedom2NR2mqtt :wink:

Ca commence à marcher !!!
image

Par contre jeedom ne doit pas renvoyer les informations si la case ‹ ne pas repeter › est cochée, du coup ca va mettre un peu de temps à tout remonter :wink: A moins qu’il y ai une astuce pour force le premier push avec toutees les valeurs courantes ?

Il me reste à ajouter une valeur last_update par topic et je partagerai mon flow NR !

Je ne pense pas… Dans mon cas, je relaie des capteurs zwave qui envoient « régulièrement » une info.
Et en tout cas, dès qu’il y a un changement, donc, ça me va.

Et voila c’est fonctionnel pour ma part !

Merci @golfvert pour la bonne base de travail !!!

Il faut tout d’abord configurer le push de jeedom avec l’url du serveur NR:
http://IP_SRV_NODERED:1880/jeedom?value=#value#&id=#cmd_id#

Voici le flow NR

[
    {
        "id": "6987201a.3de69",
        "type": "tab",
        "label": "Jeedom2Mqtt",
        "disabled": false,
        "info": ""
    },
    {
        "id": "6273e9a6.0704e8",
        "type": "http in",
        "z": "6987201a.3de69",
        "name": "Jeedom In",
        "url": "/jeedom",
        "method": "get",
        "upload": false,
        "swaggerDoc": "",
        "x": 200,
        "y": 160,
        "wires": [
            [
                "5be0819d.013f2",
                "3c3b2c34.7b2924"
            ]
        ]
    },
    {
        "id": "5be0819d.013f2",
        "type": "http response",
        "z": "6987201a.3de69",
        "name": "",
        "statusCode": "",
        "headers": {},
        "x": 390,
        "y": 140,
        "wires": []
    },
    {
        "id": "3c3b2c34.7b2924",
        "type": "function",
        "z": "6987201a.3de69",
        "name": "jeedom2mqtt",
        "func": "id2topic = flow.get(\"id2topic\");\nlast_seen = null;\n\nvar device = id2topic[msg.payload.id];\n\nif ( device === undefined ) {\n    return null;\n}\nelse {\n    msg.topic = device.topic;\n    msg.retain = true;\n    msg.payload = msg.payload.value;\n    \n    if(device.last_seen)\n    {\n        last_seen = {};\n        last_seen.retain = device.retain;\n        last_seen.topic = device.topic.substring(0,device.topic.lastIndexOf('/')+1)+\"last_seen\";\n        last_seen.payload = new Date();\n    }\n}\n\nreturn [msg,last_seen];\n",
        "outputs": 2,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 410,
        "y": 180,
        "wires": [
            [
                "3608f8ec.aa1218"
            ],
            [
                "bdceb078.0b19d"
            ]
        ]
    },
    {
        "id": "1d321a0d.73bf76",
        "type": "inject",
        "z": "6987201a.3de69",
        "name": "",
        "repeat": "900",
        "crontab": "",
        "once": true,
        "onceDelay": "2",
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 230,
        "y": 60,
        "wires": [
            [
                "409aeef2.d2993"
            ]
        ]
    },
    {
        "id": "409aeef2.d2993",
        "type": "file in",
        "z": "6987201a.3de69",
        "name": "jeedom2mqtt",
        "filename": "/data/external-data/jeedom2mqtt.yaml",
        "format": "utf8",
        "chunk": false,
        "sendError": false,
        "encoding": "none",
        "x": 410,
        "y": 60,
        "wires": [
            [
                "dfdd3eb6.4b15e"
            ]
        ]
    },
    {
        "id": "dfdd3eb6.4b15e",
        "type": "yaml",
        "z": "6987201a.3de69",
        "property": "payload",
        "name": "",
        "x": 570,
        "y": 60,
        "wires": [
            [
                "322c70df.d7297"
            ]
        ]
    },
    {
        "id": "322c70df.d7297",
        "type": "function",
        "z": "6987201a.3de69",
        "name": "Charge",
        "func": "let id2topic = {};\n\nfor (var i=0; i<msg.payload.sensors.length;i++) {\n    baseTopic=msg.payload.topicbase+\"/\"+msg.payload.sensors[i].name+\"/\";\n    retain = msg.payload.sensors[i].retain || true;\n    last_seen = msg.payload.sensors[i].retain || false;\n    for (var j=0; j<msg.payload.sensors[i].sensors.length;j++) {\n      topic = baseTopic+msg.payload.sensors[i].sensors[j].topic;\n      id2topic[\"\"+msg.payload.sensors[i].sensors[j].id] = {topic:topic, retain:retain, last_seen:last_seen};\n    }\n}\n\nflow.set(\"id2topic\", id2topic);\n\nreturn msg;\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 720,
        "y": 60,
        "wires": [
            []
        ]
    },
    {
        "id": "3608f8ec.aa1218",
        "type": "mqtt out",
        "z": "6987201a.3de69",
        "name": "",
        "topic": "",
        "qos": "0",
        "retain": "true",
        "broker": "9b372184.f0e1a",
        "x": 630,
        "y": 140,
        "wires": []
    },
    {
        "id": "bdceb078.0b19d",
        "type": "mqtt out",
        "z": "6987201a.3de69",
        "name": "",
        "topic": "",
        "qos": "0",
        "retain": "true",
        "broker": "9b372184.f0e1a",
        "x": 630,
        "y": 220,
        "wires": []
    },
    {
        "id": "9b372184.f0e1a",
        "type": "mqtt-broker",
        "name": "mqttIoull",
        "broker": "192.168.10.9",
        "port": "1883",
        "clientid": "",
        "usetls": false,
        "compatmode": true,
        "keepalive": "60",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "willTopic": "",
        "willQos": "0",
        "willPayload": ""
    }
]

Ca prends en entrée un fichier yaml que j’ai mis dans /data/external_data/jeedom2mqtt.yaml

topicbase: jeedom2mqtt
sensors:
  - name: CDL_TMP
    last_seen: true
    retain: true
    sensors:
    - id: 91
      topic: temperature
    - id: 92
      topic: humidity
    - id: 93
      topic: battery
    - id: 94
      topic: signal
  - name: CDM_TMP
    last_seen: true
    retain: true
    sensors:
    - id: 9
      topic: temperature
    - id: 10
      topic: humidity
    - id: 11
      topic: battery
    - id: 12
      topic: signal
  - name: CDT_TMP
    last_seen: true
    retain: true
    sensors:
    - id: 83
      topic: temperature
    - id: 84
      topic: humidity
    - id: 85
      topic: battery
    - id: 86
      topic: signal

les couples (id, topic) permettent de faire le lien entre l’id de la ‹ commande › jeedom avec le topic MQTT.

Et ca rempli le mqtt :
image

N’hesitez pas si vous avez des commentaires !

1 J'aime

c’est une alarme Protexiom (idem que la protexial)

@golfvert @Ioull merci pour ces infos.
je commence à me plonger dessus.

j’aime bien ton idée @Ioull j’ai repris ton NR.
par contre, ou as tu positionné ton fichier /data/external_data/jeedom2mqtt.yaml ?
a la racine de config? ou dans www? ou dans le répertoire nodered?
car j’ai tenté mais j’ai une erreur quand je lance le timestamp.

Ok j’suis intrigué :o. Niveau Jeedom, ils utilisent quoi pour contrôler l’alarme ?

le plugin Somfy alarm

ce plugin se connecte sur l’interface web de l’alarm puis scrap toutes les infos

Ah oui ok, c’est pour ça qu’il n’y a rien sur HA pour faire ça : HA interdit le fait de scraper des sites :(.

J’ai une installation sous docker donc j’ai créé un répertoire external_data dans le répertoire data de nodered. Il faut le mettre dans un répertoire que vois nodered, je ne connais pas les bonnes pratiques pour ça …
Pour le mqtt il faut que tu configuré le noeud pour le faire pointer vers une configuration mqtt a toi pour qu’il s’y connecte