Hello,
J’ai commencé il y a peu de temps aussi sur HA, et j’essaie de visualiser/piloter mon ipx800.
Mon retour d’expérience avec HA et IPX800 v3
Ce qui me semblait le plus intéressant, c’était d’utiliser le push de l’ipx évitant de scanner l’ipx selon un intervale régulier… mais l’utilisation de l’API HA n’est pas trop jouable avec une clé API sur l’ipx800 v3, en plus, avec l’utilisation de let’s encrypt, il faut un accès internet pour accéder à une machine local… je trouve cela un peu « bizarre »…
Nodered
J’ai donc commencé par utiliser Nodered, dont l’avantage est de pouvoir créer facilement un endpoint http et d’utiliser le push de l’IPX lorsque l’une des E/S est modifiée… donnant une très faible empreinte réseau. Je n’ai pas optimisé le flow… ça marche mais il faut jongler entre nodered et les entites créées sur HA.
API JSON
Du coup, je me suis lancé dans la config des fichiers yaml…
Je suis parti au départ sur l’utilisation de plusieurs sensor rest pour récupérer l’état des différentes E/S en passant par l’API retournant du json…
Car le problème de l’API json de l’IPX c’est d’utiliser une requête différente pour les entrées, les sorties, les compteurs… et les appels depuis HA sont fait à la suite vers l’IPX, et celui-ci n’a pas le temps de répondre à toutes les requêtes…; en jouant sur le paramètre scan_interval, cela évite dans la majorité des cas que les commandes ne soient pas lancé en même temps…et l’idéal, ce serait de pouvoir faire un délai entre les requêtes… mais bon, ça marche…
Voici un exemple de configuration:
#/config/sensors.yaml
# Récup état Entrées numeriques
- platform: rest
resource: 'http://ipx800.local/api/xdevices.json?cmd=10'
name: 'IPX800 entrees num'
value_template: '{{ value_json["product"] }}'
scan_interval: 30
json_attributes:
- IN1
- IN2
- IN3
- IN4
- IN5
- IN6
- IN7
- IN8
# Récup état Sorties numeriques
- platform: rest
resource: 'http://ipx800.local/api/xdevices.json?cmd=20'
#resource: 'http://{{ IP_ipx800 }}/api/xdevices.json?cmd=20'
name: 'IPX800 sorties num'
value_template: '{{ value_json["product"] }}'
scan_interval: 29
json_attributes:
- OUT1
- OUT2
- OUT3
- OUT4
- OUT5
- OUT6
- OUT7
API XML
Au final, pour éviter cela, il est possible de passer par l’API IPX800 XML, qui renvoie tous les états en 1 seul fois.
(bon, par contre attention a ne pas se faire avoir: la sortie 1, c’est out1 en json et led0 en xml… pas mieux pour les états en XML, 0,1 pour les sorties, up et dn pour les entrées…
#/config/sensors/sensor_ipx800.yaml
platform: rest
name: IPX800 global status
resource: 'http://ipx800.local/globalstatus.xml'
json_attributes_path: $.response
scan_interval: 15
value_template: OK
json_attributes:
- led0
- led1
- led2
- led3
- led4
- led5
- led6
- led7
- count0
- count1
- btn0
- btn1
- btn2
- btn3
- btn4
- btn5
- btn6
- btn7
- analog0
- analog1
L’état des différentes entrées (ou sorties, cpt…) se fait donc un seul sensor principal rest
Il suffit ensuite de créer des binary-sensors pour l’état des E/S,
#/config/binary_sensors/binary_sensor_ipx800.yaml
platform: template
sensors:
ipx800_e1:
friendly_name: IPX800 E1
value_template: '{{ is_state_attr("sensor.ipx800_global_status", "btn0","dn") }}'
ipx800_e2:
friendly_name: IPX800 E2
value_template: '{{ is_state_attr("sensor.ipx800_global_status", "btn1","dn") }}'
ipx800_e3:
friendly_name: IPX800 E3
value_template: '{{ is_state_attr("sensor.ipx800_global_status", "btn2","dn") }}'
ipx800_e4:
friendly_name: IPX800 E4
value_template: '{{ is_state_attr("sensor.ipx800_global_status", "btn3","dn") }}'
ipx800_e5:
friendly_name: IPX800 E5
value_template: '{{ is_state_attr("sensor.ipx800_global_status", "btn4","dn") }}'
ipx800_e6:
friendly_name: IPX800 E6
value_template: '{{ is_state_attr("sensor.ipx800_global_status", "btn5","dn") }}'
ipx800_e7:
friendly_name: IPX800 E7
value_template: '{{ is_state_attr("sensor.ipx800_global_status", "btn6","dn") }}'
ipx800_e8:
friendly_name: IPX800 E8
value_template: '{{ is_state_attr("sensor.ipx800_global_status", "btn7","dn") }}'
ipx800_s1:
friendly_name: IPX800 S1
value_template: '{{ state_attr("sensor.ipx800_global_status", "led0") }}'
ipx800_s2:
friendly_name: IPX800 S2
value_template: '{{ state_attr("sensor.ipx800_global_status", "led1") }}'
ipx800_s3:
friendly_name: IPX800 S3
value_template: '{{ state_attr("sensor.ipx800_global_status", "led2") }}'
ipx800_s4:
friendly_name: IPX800 S4
value_template: '{{ state_attr("sensor.ipx800_global_status", "led3") }}'
ipx800_s5:
friendly_name: IPX800 S5
value_template: '{{ state_attr("sensor.ipx800_global_status", "led4") }}'
ipx800_s6:
friendly_name: IPX800 S6
value_template: '{{ state_attr("sensor.ipx800_global_status", "led5") }}'
ipx800_s7:
friendly_name: IPX800 S7
value_template: '{{ state_attr("sensor.ipx800_global_status", "led6") }}'
ipx800_s8:
friendly_name: IPX800 S8
value_template: '{{ state_attr("sensor.ipx800_global_status", "led7") }}'
et des sensors pour l’état des compteurs et des analogiques qui se rapportent au sensor « principal »
#/config/sensors/sensor_ipx800.yaml
platform: template
sensors:
#Compteurs
ipx800_cpt1:
friendly_name: IPX compteur 1
value_template: '{{ state_attr("sensor.ipx800_global_status", "count0") }}'
unit_of_measurement: °F
ipx800_cpt2:
friendly_name: IPX compteur 2
value_template: '{{ state_attr("sensor.ipx800_global_status", "count1") }}'
unit_of_measurement: minutes
#Analogiques
ipx800_an1:
friendly_name: IPX800 ANA_1
device_class: power
value_template: '{{ state_attr("sensor.ipx800_global_status", "analog0") }}'
ipx800_an2:
friendly_name: IPX800 ANA_2
device_class: energy
value_template: '{{ state_attr("sensor.ipx800_global_status", "analog1") }}'
Tout cela permet déjà de remonter tous les états…
La commande
Pour la partie commande des E/S, utilisation de switch template
#/config/switches/switch_ipx800.yaml
platform: template
switches:
ipx800e1:
friendly_name: IPX800 E1
value_template: '{{ is_state_attr("sensor.ipx800_global_status", "btn0","dn") }}'
turn_on:
- service: rest_command.switch_ipx800_e
data:
led: 100
- service: homeassistant.update_entity
data:
entity_id:
- sensor.ipx800_global_status
- binary_sensor.ipx800_e1
turn_off:
- service: rest_command.switch_ipx800_e
data:
led: 100
- service: homeassistant.update_entity
data:
entity_id:
- sensor.ipx800_global_status
- binary_sensor.ipx800_e1
ipx800s7:
friendly_name: IPX800 S7
value_template: '{{ is_state_attr("sensor.ipx800_global_status", "led6","1") }}'
#value_template: '{{ state_attr("sensor.ipx800_global_status", "led6") | int >=1 }}'
turn_on:
- service: rest_command.set_ipx800_s
data:
num: set7
state: 1
- service: homeassistant.update_entity
data:
entity_id:
- sensor.ipx800_global_status
- binary_sensor.ipx800_s7
turn_off:
- service: rest_command.set_ipx800_s
data:
num: set7
state: 0
- service: homeassistant.update_entity
data:
entity_id:
- sensor.ipx800_global_status
- binary_sensor.ipx800_s7
(l’appel au service: homeassistant.update_entity permet de relancer une requête API et d’avoir un retour d’état immédiat)
avec une commande rest qui va avec:
- Fixe un état pour les sorties (on ne peut pas pour les entrées)
- Commutation pour les entrées (on peut utiliser aussi pour les sorties si on préfère avoir une seule commande. Avec le retour d’état, ça peut être jouable.
rest_command:
switch_ipx800_e:
url: http://ipx800.local/leds.cgi?led={{ led }}
set_ipx800_s:
url: http://ipx800.local/preset.htm?{{ num }}={{ state }}
Voici une carte rapide représentant l’état des différentes E/S et des actionneurs…
Changement d’état externe → une toute petite couche de nodered
Enfin dans le cas d’un changement d’un état de l’IPX800, pour éviter d’attendre le scan, si l’on veut un retour d’état rapide, utilisation d’un simple endpoint Nodered qui lorsqu’il recevra une requête, lancera un update du sensor « principal »… (il faudra faire éventuellement un update des différents sensors si besoin)
[{"id":"6d000be6.d538a4","type":"http in","z":"753e90f9.ed355","name":"","url":"/ipx800/refresh","method":"get","upload":false,"swaggerDoc":"","x":240,"y":480,"wires":[["16424523.6898bb","2bedb3eb.4b5dec"]]},{"id":"2bedb3eb.4b5dec","type":"http response","z":"753e90f9.ed355","name":"","statusCode":"200","headers":{},"x":660,"y":520,"wires":[]},{"id":"16424523.6898bb","type":"api-call-service","z":"753e90f9.ed355","name":"","server":"8b0f3c25.1116b","version":1,"debugenabled":false,"service_domain":"homeassistant","service":"update_entity","entityId":"sensor.ipx800_global_status","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":570,"y":460,"wires":[[]]},{"id":"8b0f3c25.1116b","type":"server","name":"Home Assistant","addon":true}]
Le push pourra se faire sur l’ipx soit au niveau général, soit au niveau de l’entrée/sortie concernée
Voilà, il y a surement encore des améliorations à faire, je n’ai que quelques semaines de HA, donc je ne capte pas toute les subtilités encore… mais bon, ça marche pour l’instant à peu près…
La prochaine étape, je verrai peut-être intégration si je trouve un peu de temps…
Avant je vais voir pour commander ma zibase qui est toujours opérationnelle !