J'ai souvent parlé d'alarme ici, de télécommandes, de claviers et de sirènes. Je pense cette fois être parvenu à quelque chose de fonctionnel et je vais vous en parler. Pour faire face aux différentes contraintes, notamment la gestion bizarre des télécommandes sous ZHA, il va falloir un peu ruser. Avant que vous me demandiez pourquoi je m'obstine sous ZHA alors que ces mêmes télécommandes sont bien gérées sous Z2M, je vous répondrait que mon objectif est la simplification et donc d'éviter le plus possible les adons qui complexifient une installation, pas forcément pour moi ou je dispose de toutes les passerelles possibles, mais sur des installations que je gère à distance ou je me dois de faire simple et fiable.
Attention : on parle ici d'un système de sécurité DIY, donc non agrée par les assurances et autres... Ca ne veut pas dire que ça ne fonctionne pas, juste que ça ne répond pas aux normes NF en vigueur dans ce domaine
Afin de gérer toutes les contraintes, je vais principalement m'appuyer sur deux automations:
, quelques scripts:
et un alarm_control_panel:
virtuel.
L'objectif est de gérer :
- Un mode absent (away) (avec une variable pour simuler un peu de présence).
- Un mode présent/nuit armé (home) (plus ou moins utile mais mais ça fait partie de tout système d'alarme face au home jacking.
- Un mode alerte (emergency) qui va permettre de déclencher une action d'urgence en appuyant sur un bouton de télécommande ou médaillon (je pense à mes vieux jours).
De l'armement / désarmement vont également découler :
- La fermeture complète ou partielle des volets roulants, leur réouverture cohérente avec la programmation en cours et éventuellement le passage en manuel des volets des chambres des enfants / invités s'ils sont présents.
- La gestion du climatiseur et des convecteurs avec passage en mode éco ou absent en fonction du type d'armement).
- La gestion du chauffe eau en cas d'absence de longue durée.
- La gestion des éclairages et la mise en veille des écrans et ordinateurs.
- ...
Etant donné que j'ai deux systèmes d'alarme qui fonctionnent en parallèle (Alarmo et Visonic), j'ai commencé par créer une alarme virtuelle et je me servirait d'elle pour les différentes actions.
alarm_control_panel:
- platform: manual
name: Home Alarm Command
code: 1234
code_arm_required: false
disarm_after_trigger: false
arming_time: 0
delay_time: 0
trigger_time: 600
disarmed:
trigger_time: 0
armed_home:
arming_time: 0
delay_time: 0
L'Armement / Désarmement
L'armement / désarmement va pouvoir se faire de plusieurs façons :
- Clavier à code
- Télécommande dédiée
- Application mobile
- Tag RFID (pour désarmer dans mon cas)
J'ai volontairement écarté les télécommandes radio en 433 Mhz dont j'avais parlé ici, d'une part parce qu'elles sont facilement piratables, et d'autre part parce qu'elles ne permettent pas de savoir qui a désarmé le système.
Je vais utiliser deux automations et les découper ce dessous/
- La première pour gérer les armements / désarmements
- La seconde pour gérer le désarmement des télécommandes, claviers à code afin d'intégrer les particularités ZHA (en attendant une amélioration de la part des développeurs de Home Assistant qui pour l'instant font la sourde oreille, parfois plus concentrés sur les nouveautés que l'affinage de l'existant).
Gestion de l'armement / désarmement et des boutons d'urgence
Les déclencheurs : Ici on va empiler nos déclencheurs d'armement, qu'ils soient gérés par ZHA, Z2M ou toute autre source. 3 par fonction, armed_away, armed_home, triggered
, mais cela peut également être un bouton virtuel pour Lovelace, voire n'importe quelle télécommande ou bouton poussoir.
- id: 078fsdg412-3545-4f37-ba02-bccsfds5646sf
alias: "Alarm : Global ON/OFF"
mode: restart
trigger:
- platform: device
device_id: c036b6547a0347878dcc6d06152267ab
domain: alarm_control_panel
entity_id: alarm_control_panel.lk_zb_keypad
type: armed_away
id: "KeyPad Away"
- platform: device
device_id: c036b6547a0347878dcc6d06152267ab
domain: alarm_control_panel
entity_id: alarm_control_panel.lk_zb_keypad
type: armed_home
id: "KeyPad Home"
- platform: device
device_id: c036b6547a0347878dcc6d06152267ab
domain: alarm_control_panel
entity_id: alarm_control_panel.lk_zb_keypad
type: triggered
id: "KeyPad Triggered"
- platform: state
entity_id: input_button.arm_alarm_away
id: "Push Button Away"
Et un déclencheur de désarmement activé par une seconde automation que l'on verra plus loin :
- platform: state
entity_id:
- alarm_control_panel.home_alarm_command
to: disarmed
id: "Remote or Keypad"
Les conditions : Dans mon cas je n'en ai pas utilisé. Chacun adaptera.
condition:
Les actions :
Je commence par arrêter les éventuels scripts en cours. Cela est principalement utile quand on a fermé la porte, armé le système et que l'on doit rapidement désarmer car on a oublié quelque chose dans la maison.
action:
- service: homeassistant.turn_off
target:
entity_id:
- script.privacy_on
- script.privacy_off
- script.alarmo_after_arm
- script.alarmo_after_disarm
- script.alarm_actions_on_leave_common_tasks
- script.alarm_actions_on_return_common_tasks
Ensuite on va utiliser chose:
pour exécuter les différentes actions en fonction de la source et de l'état.
On commence par l'armement en mode absent :
- On envoie les bips d'armement sur la sirène. En MQTT pour l'instant car elle aussi est très mal gérée sous ZHA
- On arme Alarmo
- On arme Visonic (en mode Home sans les PIR qui déraillent).
- On arme notre panneau d'alarme virtuel qui nous servira au désarmement
- On arme également le clavier, ça ne change rien à l'usage mais quand on se présentera pour désarmé il apparaitra comme étant armé. Dans la pratique ça relance de fait l'automation avec la même automation, et donc ça fausse le message, j'ai donc retiré cette option pour l'instant. (D'ailleurs si vous êtes sous Z2M il le développeur d'Alarmo a fait un joli travail pour ce clavier).
- On inscrit un message texte dans un
input_text:
que l'on affiche dans Lovelace et qui nous permet de savoir qui fait quoi. A terme je remplacerait les id:
par le prénom de l'utilisateur pour plus de lisibilité.
- choose:
- conditions: "{{ trigger.id in ['KeyPad Away', 'Heiman RC1 Away', 'Heiman RC2 Away', 'Woox RC1 Away'] }}"
sequence:
- service: mqtt.publish
data:
topic: zigbee2mqtt/Sirène SMaBiT/set
payload: >-
{"squawk": {"state": "system_is_armed", "level": "veryhigh", "strobe": "true"}}
- service: alarm_control_panel.alarm_arm_away # ALARMO Away
data:
code: !secret alarm_code
entity_id: alarm_control_panel.alarmo
- service: alarm_control_panel.alarm_arm_home # VISONIC Home (ne jamais armer AWAY à cause des détecteurs HS)
data:
code: !secret alarm_code_visonic
entity_id: alarm_control_panel.visonic_alarm
- service: script.alarm_actions_on_leave_common_tasks
- service: alarm_control_panel.alarm_arm_away # FAKE ALARM PANEL Away
target:
entity_id: alarm_control_panel.home_alarm_command
- service: alarm_control_panel.alarm_arm_away # On arme le clavier afin qu'il apparaisse armé
data:
code: !secret alarm_code_zha
target:
entity_id:
- alarm_control_panel.lk_zb_keypad
- service: input_text.set_value
target:
entity_id: input_text.last_arm
data:
value: "{{now().strftime('%d/%m/%Y, %H:%M:%S')}} > Arm Away by : {{ trigger.id }}"
On fait la même chose pour le mode home. Je fais l'impasse sur Visonic, par contre j'émet un son de confirmation sur un buzzer (on verra plus loin l'utilisation possible d'un TTS sur une enceinte.
- conditions: "{{ trigger.id in ['KeyPad Home', 'Heiman RC1 Home', 'Heiman RC2 Home', 'Woox RC1 Home'] }}"
sequence:
- service: alarm_control_panel.alarm_arm_home # ALARMO Home
data:
code: !secret alarm_code
entity_id: alarm_control_panel.alarmo
- service: alarm_control_panel.alarm_arm_home # FAKE ALARM PANEL Home
target:
entity_id: alarm_control_panel.home_alarm_command
- service: alarm_control_panel.alarm_arm_home # On arme le clavier afin qu'il apparaisse armé
data:
code: !secret alarm_code_zha
target:
entity_id:
- alarm_control_panel.lk_zb_keypad
- service: button.press
target:
entity_id: button.up_chime_play_buzzer
- service: input_text.set_value
target:
entity_id: input_text.last_arm
data:
value: "{{now().strftime('%d/%m/%Y, %H:%M:%S')}} > Arm Home by : {{ trigger.id }}"
Ensuite on passe au désarmement du mode absent. On remarque que l'on écrit pas d'input_text:
car ici on ne sait pas qui a fait quoi car l'ordre vient de la seconde automation que l'on verra plus loi. C'est donc elle qui écrira. Par contre on émet le son de désarmement sur la sirène.
- conditions: "{{ trigger.id in ['Remote or Keypad'] and is_state('alarm_control_panel.alarmo', 'armed_away') }}"
sequence:
- service: alarm_control_panel.alarm_disarm
data:
code: !secret alarm_code
entity_id:
- alarm_control_panel.alarmo
- alarm_control_panel.visonic_alarm
- service: mqtt.publish
data:
topic: zigbee2mqtt/Sirène SMaBiT/set
payload: >-
{"squawk": {"state": "system_is_disarmed", "level": "veryhigh", "strobe": "true"}}
Pareil pour le mode Home. Ici on joue un son sur le buzzer.
- conditions:
- "{{ trigger.id in ['Push Button'] }}"
- "{{ is_state('alarm_control_panel.alarmo', 'armed_home') }}"
sequence:
- service: alarm_control_panel.alarm_disarm
data:
code: !secret alarm_code
entity_id:
- alarm_control_panel.alarmo
- service: button.press
target:
entity_id: button.up_chime_play_buzzer
On continue avec la gestion du bouton d'urgence :
- On joue un son pour confirmer
- On arme notre panneau d'alarme virtuel dans un mode inutilisé (Nuit) pour ensuite pouvoir désarmer.
- On envoie un SMS d'Au Secours, ou toute autre action à imaginer.
- On écrit un
input_text:
pour avoir une trace.
- conditions: "{{ trigger.id in ['KeyPad Triggered', 'Heiman RC1 Triggered', 'Heiman RC2 Triggered', 'Woox RC1 Triggered'] and is_state('alarm_control_panel.alarmo', 'disarmed') }}"
sequence:
- service: button.press
target:
entity_id: button.up_chime_play_chime
- service: alarm_control_panel.alarm_arm_night # FAKE ALARM PANEL Night pour pouvoir désarmer
target:
entity_id: alarm_control_panel.home_alarm_command
- service: notify.free_mobile_andre
data:
message: "{{ states.sensor.date_time.state}} > TEST Alerte au secours par télécommande TEST"
- service: input_text.set_value
target:
entity_id: input_text.last_arm
data:
value: "{{now().strftime('%d/%m/%Y, %H:%M:%S')}} > Triggered by : {{ trigger.id }}"
Enfin, on désarme cette alerte. A ce stade on peut aussi envoyer un SMS pour dire que c'était une fausse alerte... Je vais me contenter de jouer du buzzer...
- conditions:
- "{{ trigger.id in ['Remote or Keypad'] and is_state('alarm_control_panel.alarmo', 'disarmed') }}"
sequence:
- service: button.press
target:
entity_id: button.up_chime_play_buzzer
Le cas des tag RFID
Les tags RFID c'est sympa, mais hormis en coller deux cote à cote on ne pourra basiquement gérer qu'un seule information : tag_scanned
Hors, l'idée est de se servir d'un même tag collé à la porte pour armer ou désarmer. S'il s'agissait d'un switch on ferait un switch.toggle
, mais pas pour une alarme. Il va falloir ruser.
Bien sur on pourrait mettre une condition pour savoir connaitre l'état de l'alarme, mais je ne veux pas utiliser de condition et uniquement un trigger
avec son id:
. J'ai passé des heures à essayer de faire un trigger template pour combiner le scan du tag + l'état de alarm_control_panel
, mais sans succès car le tag n'est pas un device
ou un entity
ou l'on peut facilement lire l'état.
La solution consiste à créer un binary_sensor:
temporisé :
template:
- trigger:
- platform: event
event_type: tag_scanned
event_data:
tag_id: bf5018c7-c1a9-4220-a01a-66f885176795
# name: Tag Green
# device_id: 1d3ddfgy45805354ce090774e3f22510
binary_sensor:
name: Tag Green
state: "{{ trigger.platform == 'event' }}"
auto_off:
seconds: 1
A noter que name:
peut être utilisé à la place de tag_id:
et que l'on peut jouer avec les autres informations que l'on trouve dans l'event afin par exemple de savoir quel appareil a scanné le tag et ainsi savoir qui a armé ou désarmé...
Et ensuite il sera facile de créer un trigger basé sur un petit template et se servir de son id:
pour action dans le chose:
- platform: template
value_template: "{{ is_state('binary_sensor.tag_green', 'on') and is_state('alarm_control_panel.alarmo', 'armed_home') }}"
id: tag_to_disarm
Gestion des commandes de désarmement
Au risque de me répéter, cette partie aurait pu être intégrée à la première automation, si ZHA ne posait pas problème... Je le ferait probablement, mais pour l'exemple on va pour l'instant scinder cette partie.
Donc, pour les télécommandes d'alarme sous ZHA on va devoir écouter un event:
, s'en servir pour désarmer nos système d'alarme mais également pour la désarmer et désarmer ses copines ainsi que le clavier. Simple ! J'avais exploré dans un précédent article plusieurs pistes afin de ne prendre en compte qu'un seul de ses "events" (en + elle en envoie 3 ou 4 identiques selon l'humeur et le modèle). J'ai un peu avancé et on ne va pas les écouter dans l'automation, mais se servir de l'état temporaire d'un binary_sensor:
que l'on va pouvoir temporiser et ainsi ne prendre en compte qu'un seul event:
template:
- trigger:
- platform: event
event_type: zha_event
event_data:
device_ieee: a4:c1:38:96:0b:cf:c9:61 # Woox RC1
command: 'arm'
args:
arm_mode: 0
arm_mode_description: 'Disarm'
code: ''
zone_id: 0
binary_sensor:
name: Woox RC1 to Disarmed
icon: "{{ (trigger.platform == 'event') | iif('mdi:remote-off', 'mdi:remote') }}"
state: "{{ trigger.platform == 'event' }}"
auto_off:
seconds: 5
Les déclencheurs : Ici on va écouter des actions de désarmement, que cela provienne d'un clavier, une télécommande (via leur binary_sensor:
), ou en direct pour une source classique (tag RFID, MQTT, ...).
- id: '2bd0ertyyf-43fa-45f98f-aed0-disarm'
alias: "Alarm @ Remote Disarm"
description: 'Disarm Remote Control panel'
mode: single
trigger:
- platform: state
entity_id: binary_sensor.heiman_rc1_to_disarmed
to: "on"
id: "Heiman RC 1"
- platform: tag
tag_id: 2b855225-c999-4b5558123-6c7d12345641
id: "TAG Jaune"
- platform: device
domain: mqtt
device_id: 139eb4ce27246465b0d5aa7560a953601
type: action
subtype: disarm
discovery_id: 0x84fd27fffe915905 action_disarm
id: "Heiman RC2"
Les conditions : Aucune, mais on pourrait imagine un flag de blocage activé à distance après une alerte...
condition:
Les actions : On utilise un chose: et on commence par :
- Désarmer le panneau d'alarme virtuel, ce qui déclenchera l'action idoine dans la première automation.
- Désarmer les télécommandes et claviers qui sont également des panneaux d'alarme, avec cette particularité ZHA qui fait qu'il faut un code pour désarmer une télécommande...
- Ecrire un
input_text:
afin de savoir qui a désarmé.
- J'envoie un message dans Slack qui me sert de log. Ca va également m'informer à distance que quelqu'un est arrivé et a désarmé
action:
- choose: # DISARM
- conditions: "{{ trigger.id in ['Push Button', 'KeyPad', 'Linkind RC', 'Heiman RC 1', 'Woox RC 1', 'TAG Porte', 'TAG Jaune', 'TAG Clé', 'TAG Carte', 'Heiman RC2' ] }}"
sequence:
- service: alarm_control_panel.alarm_disarm # FAKE ALARM PANEL to Command
data:
code: "1234"
target:
entity_id: alarm_control_panel.home_alarm_command
- service: alarm_control_panel.alarm_disarm
data:
code: !secret alarm_code_zha
target:
entity_id:
- alarm_control_panel.lk_zb_keypad
- alarm_control_panel.lk_zb_remote
- alarm_control_panel.heiman_remote
- alarm_control_panel.woox_01
- service: input_text.set_value
target:
entity_id: input_text.last_disarm
data:
value: "{{now().strftime('%d/%m/%Y, %H:%M:%S')}} > Disarm by : {{ trigger.id }}"
- service: notify.slack_hass_canaletto
data:
message: "{{now().strftime('%d/%m/%Y, %H:%M:%S')}} > Disarmed by : {{ trigger.id }}"
On peut également faire une place à une fonctionnalité détournée du clavier. En effet au delà de l'amenée Home, Away et Emergency, on peut également lui faire avaler n'importe quel code et effectuer une action précise en fonction de celui ci. Ici si je saisit 33 et valide je vais allumer les projecteurs.
- choose:
- conditions: "{{ trigger.id in ['KeyPad 33'] }}"
sequence:
- service: light.turn_off
target:
entity_id:
- light.groupe_de_projecteurs
Enfin j'ai quelques actions par défaut, comme éteindre les sirènes au cas ou... (ça sent le debug...).
- service: mqtt.publish
data:
topic: zigbee2mqtt/Sirène SMaBiT/set
payload: >-
{"warning": {"mode": "stop"}}
- service: siren.turn_off
target:
entity_id:
- siren.heiman_sirene_1
- siren.heiman_sirene_2
- siren.sirene_terrasse
Et surtout on ajoute un délai car ces télécommandes ont la fâcheuse idée d'envoyer 3 ou 4 event:
identique pour chaque appui. Donc combiné au mode: single
de cette automation, on va en capturer qu'un seul. Ce délais est bien sur à ajuster plus ou moins au pif... Maintenant que je passe par des binary_sensor:
temporisés, je pense que ce délai est devenu inutile.
- delay : '00:00:08'
Les actions POST Armement / Désarmement
On va utiliser deux scripts qui seront exécutés par Alarmo après l'armement et après le désarmement. Chez moi ils vont servir à :
- Jouer une annonce vocale en TTS sur une enceinte extérieure pour annoncer l'état armé ou désarmé.
- Activer ou désactiver la vidéo surveillance.
- Passer les volets en mode manuel et automatique au retour (voir l'automatisation des volets).
- Gérer le mode ECO/Absent du climatiseur et des convecteurs.
- Gérer les éclairages et le mode veille de mon PC.
- Et plus encore selon votre imagination....
Les notifications d'alarme et sirènes
- Notifications SMS pour l'intrusion, la détection incendie ou fuite d'eau. (notifications gérées par Alarmo).
- Sirènes et projecteurs en cas d'intrusion :
- la législation autorise au maximum 3 minutes pour chaque lancement de sirène.
- Pas de limite pour les projecteurs. Et éclairer comme en plein jour peut également faire fuir et permettra d'avoir des images bien nettes sur les caméras.
- Si vous avez un système audio multi room bien puissant, vous pouvez également envoyer une bonne salve d'AC-DC, ça peu perturber... ou inciter les voisins à appeler la maréchaussée.
- Les armes, explosifs et autres gaz toxiques sont à proscrire.
Pour cela on va utiliser des scripts: qui seront lancés par Alarmo selon les conditions choisies (voir ici).
Etant donné que j'ai des détecteurs d'ouverture sur mes volets roulants, je peux également imaginer l'éclairage extérieur avant de déclencher l'alarme si un de ces volets est touché. Il faut être prévenant et éclairer l'intrus. Cela peut se gréer dans une partition secondaire d'Alarmo, ou simple une automation. Les caméras Unifi Protect (G4) font également de la détection de personne qui remonte dans Home Assistant.
Voilà, ce n'est pas exhaustif, vos idées son les bienvenues, ici ou sur HACF.