HA-Automatisation des volets RTS (Version 2025)

Intro

Sur mon blog, je partage régulièrement mes projets domotiques pour rendre la maison plus confortable et intelligente. Aujourd’hui, je vous présente une de mes automatisations préférées : la gestion générale de mes volets roulants RTS. Ce script, conçu sous Home Assistant, adapte l’ouverture et la fermeture des volets selon les saisons (été/hiver) et mon statut (présent ou absent).

Objectif de l’automatisation

L’idée est simple : automatiser les volets pour qu’ils s’ouvrent et se ferment aux bons moments, en fonction de la luminosité (jour/nuit) et d’horaires prédéfinis pour l’été ou l’hiver. En bonus, un mode « Absent » sécurise la maison quand je ne suis pas là. Cette flexibilité est idéale pour économiser de l’énergie et optimiser le confort.

Les déclencheurs (Triggers)

Mon automatisme repose sur plusieurs déclencheurs pour couvrir tous les cas :

  1. Changement jour/nuit : Utilisation d’un input_boolean.nuit_jour qui bascule entre « on » (nuit) et « off » (jour). Par exemple, quand on passe de « on » à « off » (nuit vers jour), l’automatisation réagit immédiatement.
  2. Horaires saisonniers :
    • En été : des heures définies via input_datetime.horaire_ete_volet_ouv (ouverture) et input_datetime.horaire_ete_volet_ferm (fermeture).
    • En hiver : un horaire spécifique pour l’ouverture avec input_datetime.horaire_hiver_volet_ouv.

Les conditions et actions

Le cœur de l’automatisation repose sur un input_select.volets qui peut être réglé sur trois états : « Auto Hiv » (hiver), « Auto Ete » (été) ou « Absent ». Selon cet état et le déclencheur activé, différentes actions sont exécutées via des scripts :

  • Mode Auto Hiver :
    • Passage jour -> nuit : fermeture des volets (script).
    • Heure d’ouverture hiver : ouverture des volets (script).
  • Mode Auto Été :
    • Heure d’ouverture été : ouverture des volets (même script d’ouverture).
    • Heure de fermeture été : fermeture des volets (script).
  • Mode Absent :
    • Passage jour -> nuit : fermeture sécurisée (script).
    • Passage nuit -> jour : ouverture (script).

Si aucune condition n’est remplie, rien ne se passe (action par défaut vide).

Pourquoi ce système ?

Ce setup est super pratique pour plusieurs raisons :

  • Adaptabilité : Les horaires changent selon la saison, ce qui est parfait pour gérer la chaleur en été ou la lumière en hiver.
  • Sécurité : Le mode Absent simule une présence en ouvrant et fermant les volets, dissuadant les intrusions.
  • Simplicité : Une fois configuré, tout est automatique, et je peux ajuster les horaires via l’interface de Home Assistant.

Mesure de la luminosité : Une détection précise du jour et de la nuit

Pour que le passage jour/nuit soit vraiment intelligent, j’ai ajouté une automatisation dédiée au calcul de l’état input_boolean.nuit_jour. Elle repose sur un capteur de luminosité bh1750. et la position du soleil (sun.sun). Voici comment ça marche :

  • Déclencheurs :
    • Passage nuit -> jour : déclenché quand la luminosité dépasse un seuil haut (input_number.luminosite_seuil_haut) et que le soleil est au-dessus de l’horizon.
    • Passage jour -> nuit : activé quand la luminosité tombe sous un seuil bas (input_number.luminosite_seuil_bas) et que le soleil est sous l’horizon.
  • Actions :
    • Nuit -> Jour : met input_boolean.nuit_jour sur « on ».
    • Jour -> Nuit : met input_boolean.nuit_jour sur « off ».

Le code YAML de cette automatisation :

alias: Calcul Boolean Nuit/Jour
description: ""
triggers:
  - value_template: >-
      {{ states('sensor.bh1750_illuminance')|float(default=0) >
      states('input_number.luminosite_seuil_haut')|float(default=0) and
      is_state("sun.sun", "above_horizon") }}
    id: nuit->jour
    trigger: template
  - value_template: >-
      {{ states('sensor.bh1750_illuminance')|float(default=0) <
      states('input_number.luminosite_seuil_bas')|float(default=0) and
      is_state("sun.sun", "below_horizon") }}
    id: jour->nuit
    trigger: template
actions:
  - choose:
      - conditions:
          - condition: trigger
            id: nuit->jour
        sequence:
          - action: input_boolean.turn_on
            target:
              entity_id: input_boolean.nuit_jour
      - conditions:
          - condition: trigger
            id: jour->nuit
        sequence:
          - action: input_boolean.turn_off
            target:
              entity_id: input_boolean.nuit_jour
    default: []
mode: single

Cette approche combine la mesure réelle de la luminosité avec les données astronomiques, rendant la détection hyper fiable, même par temps nuageux ou pluvieux.

Piloter les volets Somfy RTS avec ESPSomfy-RTS

Pour contrôler mes volets Somfy RTS, j’ai opté pour la solution open-source ESPSomfy-RTS, que j’ai découverte sur GitHub (voir ici). Ce projet utilise un ESP32 couplé à un module CC1101 pour envoyer et recevoir des commandes RTS sur la fréquence 433 MHz. Voici pourquoi et comment je l’utilise :

  • Matériel abordable : Pour environ 12 €, j’ai assemblé un ESP32 et un CC1101 avec des connecteurs Dupont, sans soudure. C’est simple et accessible.
  • Configuration : Après avoir flashé le firmware (disponible dans les releases GitHub), je connecte l’ESP32 à mon réseau Wi-Fi via son interface web (http://192.168.4.1 en mode AP initial). Ensuite, je configure les volets en les associant au système, un peu comme on programme une télécommande Somfy.
  • Intégration avec Home Assistant : ESPSomfy-RTS s’intègre nativement à Home Assistant via une découverte automatique ou MQTT. Mes scripts (comme ceux ci-dessus) appellent ensuite les commandes via les entités créées (ex. cover.volet_salon).
  • Avantages : Contrairement à une télécommande classique, ESPSomfy-RTS suit la position des volets même quand je les pilote manuellement, et il supporte jusqu’à 32 volets individuels ou 16 groupes. Un vrai plus pour une maison connectée !

Pour plus de détails sur la configuration, consultez le wiki officiel. Avec cette solution, mes volets sont non seulement automatisés, mais aussi accessibles depuis n’importe où via Home Assistant.

Montage de l’ESP32

Afin de fiabiliser mon montage, j’ai opté pour la conception avec EasyEda et la réalisation dun circuit imprimé confié à JLCPCB (5 ex pour une poignée d’€).

Integration dans HA

Le code de l’automatisation principale

Pour les curieux, voici le YAML de l’automatisation des volets:

alias: Volet Automatisme Général RTS
description: "Ete/Hiver/Absent "
triggers:
  - entity_id:
      - input_boolean.nuit_jour
    from: "on"
    to: "off"
    id: jour->nuit
    for:
      hours: 0
      minutes: 0
      seconds: 0
    trigger: state
  - at: input_datetime.horaire_ete_volet_ouv
    id: heure_ouv
    trigger: time
  - at: input_datetime.horaire_ete_volet_ferm
    id: heure_ferm
    trigger: time
  - entity_id:
      - input_boolean.nuit_jour
    id: nuit->jour
    from: "off"
    to: "on"
    for:
      hours: 0
      minutes: 0
      seconds: 0
    trigger: state
  - at: input_datetime.horaire_hiver_volet_ouv
    id: ouv_hiv
    trigger: time
conditions: []
actions:
  - choose:
      - conditions:
          - condition: state
            entity_id: input_select.volets
            state: Auto Hiv
          - condition: trigger
            id: jour->nuit
        sequence:
          - data: {}
            action: script.1706464871250
      - conditions:
          - condition: state
            entity_id: input_select.volets
            state: Auto Hiv
          - condition: trigger
            id:
              - ouv_hiv
        sequence:
          - data: {}
            action: script.0_0_1_ouverture_volets_rts
      - conditions:
          - condition: state
            entity_id: input_select.volets
            state: Auto Ete
          - condition: trigger
            id: heure_ouv
        sequence:
          - data: {}
            action: script.0_0_1_ouverture_volets_rts
      - conditions:
          - condition: state
            entity_id: input_select.volets
            state: Auto Ete
          - condition: trigger
            id: heure_ferm
        sequence:
          - data: {}
            action: script.1706464871250
      - conditions:
          - condition: state
            entity_id: input_select.volets
            state: Absent
          - condition: trigger
            id: jour->nuit
        sequence:
          - data: {}
            action: script.0_1_0_fermeture_volets_mode_absent_rts
      - conditions:
          - condition: state
            entity_id: input_select.volets
            state: Absent
          - condition: trigger
            id: nuit->jour
        sequence:
          - data: {}
            action: script.0_1_1_ouverture_volets_mode_absent_rts
    default: []
mode: single

Interface Lovelace

type: vertical-stack
cards:
  - cards:
      - cards:
          - entity: cover.porte_garage
            label: Garage
            operator: default
            show_icon: true
            show_label: true
            show_name: false
            size: 70%
            state:
              - color: green
                icon: mdi:garage
                operator: template
                value: >
                  [[[ return
                  states['cover.porte_garage'].attributes.current_position < 1
                  ]]]
              - color: red
                icon: mdi:garage-open
                operator: template
                value: >
                  [[[ return
                  states['cover.porte_garage'].attributes.current_position > 99
                  ]]]
              - color: orange
                icon: mdi:garage-alert
                operator: default
            tap_action:
              action: more-info
            theme: Mushroom
            type: custom:button-card
          - icon: mdi:arrow-up-bold
            name: Ouvrir
            show_icon: true
            show_name: false
            tap_action:
              action: call-service
              service: cover.open_cover
              service_data: {}
              target:
                entity_id:
                  - cover.porte_garage
            type: button
          - icon: mdi:pause
            name: Stop
            show_name: false
            tap_action:
              action: call-service
              service: cover.stop_cover
              service_data: {}
              target:
                entity_id:
                  - cover.porte_garage
            type: button
          - icon: mdi:arrow-down-bold
            name: Fermer
            show_name: false
            tap_action:
              action: call-service
              service: cover.close_cover
              service_data: {}
              target:
                entity_id:
                  - cover.porte_garage
            type: button
          - icon: mdi:weather-sunset-up
            name: Soleil
            show_name: false
            tap_action:
              action: call-service
              service: cover.set_cover_position
              service_data:
                position: 50
              target:
                entity_id:
                  - cover.porte_garage
            type: button
          - elements:
              - attribute: current_position
                entity: cover.porte_garage
                style:
                  color: "#44739E"
                  font-size: 16px
                  font-weight: bold
                  left: 50%
                  top: 50%
                suffix: "%"
                tap_action:
                  action: more-info
                type: state-label
            image: /local/images/carre_orange.png
            type: picture-elements
            view_layout:
              position: sidebar
        columns: 6
        square: true
        type: grid
      - cards:
          - entity: cover.porte_sous_sol
            label: Sous Sol
            show_icon: true
            show_label: true
            show_name: false
            size: 70%
            state:
              - color: green
                icon: mdi:garage
                operator: template
                value: >
                  [[[ return
                  states['cover.porte_sous_sol'].attributes.current_position < 1
                  ]]]
              - color: red
                icon: mdi:garage-open
                operator: template
                value: >
                  [[[ return
                  states['cover.porte_sous_sol'].attributes.current_position >
                  99 ]]]
              - color: orange
                icon: mdi:garage-alert
                operator: default
            tap_action:
              action: more-info
            theme: Mushroom
            type: custom:button-card
          - icon: mdi:arrow-up-bold
            name: Ouvrir
            show_icon: true
            show_name: false
            tap_action:
              action: call-service
              service: cover.open_cover
              service_data: {}
              target:
                entity_id:
                  - cover.porte_sous_sol
            type: button
          - icon: mdi:pause
            name: Stop
            show_name: false
            tap_action:
              action: call-service
              service: cover.stop_cover
              service_data: {}
              target:
                entity_id:
                  - cover.porte_sous_sol
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:arrow-down-bold
            name: Fermer
            tap_action:
              action: call-service
              service: cover.close_cover
              target:
                entity_id: cover.porte_sous_sol
              data: {}
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:weather-sunset-up
            name: Soleil
            tap_action:
              action: call-service
              service: cover.set_cover_position
              target:
                entity_id:
                  - cover.porte_sous_sol
              data:
                position: 15
            type: button
          - elements:
              - attribute: current_position
                entity: cover.porte_sous_sol
                style:
                  color: "#44739E"
                  font-size: 16px
                  font-weight: bold
                  left: 50%
                  top: 50%
                suffix: "%"
                tap_action:
                  action: more-info
                type: state-label
            image: /local/images/carre_orange.png
            type: picture-elements
            view_layout:
              position: sidebar
        columns: 6
        square: true
        type: grid
      - cards:
          - entity: cover.volet_bureau_rts
            hold_action:
              action: none
            icon: mdi:desk-lamp
            name: Bureau
            show_icon: true
            show_name: true
            show_state: false
            tap_action:
              action: more-info
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:arrow-up-bold
            name: Ouvrir
            tap_action:
              action: call-service
              service: cover.open_cover
              target:
                entity_id:
                  - cover.volet_bureau_rts
              data: {}
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:pause
            name: Stop
            tap_action:
              action: call-service
              service: cover.stop_cover
              target:
                entity_id:
                  - cover.volet_bureau_rts
              data: {}
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:arrow-down-bold
            name: Fermer
            tap_action:
              action: call-service
              service: cover.close_cover
              target:
                entity_id:
                  - cover.volet_bureau_rts
              data: {}
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:weather-sunset-up
            name: Soleil
            tap_action:
              action: call-service
              service: cover.set_cover_position
              target:
                entity_id:
                  - cover.volet_bureau_rts
              data:
                position: 50
            type: button
          - elements:
              - attribute: current_position
                entity: cover.volet_bureau_rts
                style:
                  color: "#44739E"
                  font-size: 16px
                  font-weight: bold
                  left: 50%
                  top: 50%
                suffix: "%"
                tap_action:
                  action: more-info
                type: state-label
            image: /local/images/carre_orange.png
            type: picture-elements
            view_layout:
              position: sidebar
        columns: 6
        square: true
        type: grid
      - cards:
          - show_name: true
            show_icon: true
            entity: cover.volets_salon_rts
            hold_action:
              action: none
            icon: mdi:sofa
            name: Salon
            show_state: false
            tap_action:
              action: more-info
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:arrow-up-bold
            name: Ouvrir
            tap_action:
              action: call-service
              service: cover.open_cover
              target:
                entity_id:
                  - cover.volets_salon_rts
              data: {}
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:pause
            name: Stop
            tap_action:
              action: call-service
              service: cover.stop_cover
              target:
                entity_id:
                  - cover.volets_salon_rts
              data: {}
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:arrow-down-bold
            name: Fermer
            tap_action:
              action: call-service
              service: cover.close_cover
              target:
                entity_id:
                  - cover.volets_salon_rts
              data: {}
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:weather-sunset-up
            name: Soleil
            tap_action:
              action: call-service
              service: cover.set_cover_position
              target:
                entity_id:
                  - cover.volets_salon_rts
              data:
                position: 50
            type: button
          - elements:
              - attribute: current_position
                entity: cover.volets_salon_rts
                style:
                  color: "#44739E"
                  font-size: 16px
                  font-weight: bold
                  left: 50%
                  top: 50%
                suffix: "%"
                tap_action:
                  action: more-info
                type: state-label
            image: /local/images/carre_orange.png
            type: picture-elements
            view_layout:
              position: sidebar
        columns: 6
        square: true
        type: grid
      - cards:
          - show_name: true
            show_icon: true
            entity: cover.volet_sdb_rts
            hold_action:
              action: none
            icon: mdi:bathtub
            name: SdB
            show_state: false
            tap_action:
              action: more-info
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:arrow-up-bold
            name: Ouvrir
            tap_action:
              action: call-service
              service: cover.open_cover
              target:
                entity_id:
                  - cover.volet_sdb_rts
              data: {}
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:pause
            name: Stop
            tap_action:
              action: call-service
              service: cover.stop_cover
              target:
                entity_id:
                  - cover.volet_sdb_rts
              data: {}
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:arrow-down-bold
            name: Fermer
            tap_action:
              action: call-service
              service: cover.close_cover
              target:
                entity_id:
                  - cover.volet_sdb_rts
              data: {}
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:weather-sunset-up
            name: Soleil
            tap_action:
              action: call-service
              service: cover.set_cover_position
              target:
                entity_id:
                  - cover.volet_sdb_rts
              data:
                position: 50
            type: button
          - elements:
              - attribute: current_position
                entity: cover.volet_sdb_rts
                style:
                  color: "#44739E"
                  font-size: 16px
                  font-weight: bold
                  left: 50%
                  top: 50%
                suffix: "%"
                tap_action:
                  action: more-info
                type: state-label
            image: /local/images/carre_orange.png
            type: picture-elements
            view_layout:
              position: sidebar
        columns: 6
        square: true
        type: grid
      - cards:
          - show_name: true
            show_icon: true
            entity: cover.volet_ch_nord
            hold_action:
              action: none
            icon: mdi:bed
            name: A Nord
            show_state: false
            tap_action:
              action: more-info
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:arrow-up-bold
            name: Ouvrir
            tap_action:
              action: call-service
              service: cover.open_cover
              target:
                entity_id:
                  - cover.volet_ch_nord
              data: {}
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:pause
            name: Stop
            tap_action:
              action: call-service
              service: cover.stop_cover
              target:
                entity_id:
                  - cover.volet_ch_nord
              data: {}
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:arrow-down-bold
            name: Fermer
            tap_action:
              action: call-service
              service: cover.close_cover
              target:
                entity_id:
                  - cover.volet_ch_nord
              data: {}
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:weather-sunset-up
            name: Soleil
            tap_action:
              action: call-service
              service: cover.set_cover_position
              target:
                entity_id:
                  - cover.volet_ch_nord
              data:
                position: 50
            type: button
          - elements:
              - attribute: current_position
                entity: cover.volet_ch_nord
                style:
                  color: "#44739E"
                  font-size: 16px
                  font-weight: bold
                  left: 50%
                  top: 50%
                suffix: "%"
                tap_action:
                  action: more-info
                type: state-label
            image: /local/images/carre_orange.png
            type: picture-elements
            view_layout:
              position: sidebar
        columns: 6
        square: true
        type: grid
      - cards:
          - show_name: true
            show_icon: true
            entity: cover.volets_ch_parents_rts
            hold_action:
              action: none
            icon: mdi:bed
            name: Parents
            show_state: false
            tap_action:
              action: more-info
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:arrow-up-bold
            name: Ouvrir
            tap_action:
              action: call-service
              service: cover.open_cover
              target:
                entity_id:
                  - cover.volets_ch_parents_rts
              data: {}
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:pause
            name: Stop
            tap_action:
              action: call-service
              service: cover.stop_cover
              target:
                entity_id:
                  - cover.volets_ch_parents_rts
              data: {}
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:arrow-down-bold
            name: Fermer
            tap_action:
              action: call-service
              service: cover.close_cover
              target:
                entity_id:
                  - cover.volets_ch_parents_rts
              data: {}
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:weather-sunset-up
            name: Soleil
            tap_action:
              action: call-service
              service: cover.set_cover_position
              target:
                entity_id:
                  - cover.volets_ch_parents_rts
              data:
                position: 50
            type: button
          - elements:
              - attribute: current_position
                entity: cover.volets_ch_parents_rts
                style:
                  color: "#44739E"
                  font-size: 16px
                  font-weight: bold
                  left: 50%
                  top: 50%
                suffix: "%"
                tap_action:
                  action: more-info
                type: state-label
            image: /local/images/carre_orange.png
            type: picture-elements
            view_layout:
              position: sidebar
        columns: 6
        square: true
        type: grid
      - cards:
          - show_name: true
            show_icon: true
            entity: cover.volets_ch_sud_rts
            hold_action:
              action: none
            icon: mdi:bed
            name: A Sud
            show_state: false
            tap_action:
              action: more-info
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:arrow-up-bold
            name: Ouvrir
            tap_action:
              action: call-service
              service: cover.open_cover
              target:
                entity_id:
                  - cover.volets_ch_sud_rts
              data: {}
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:pause
            name: Stop
            tap_action:
              action: call-service
              service: cover.stop_cover
              target:
                entity_id:
                  - cover.volets_ch_sud_rts
              data: {}
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:arrow-down-bold
            name: Fermer
            tap_action:
              action: call-service
              service: cover.close_cover
              target:
                entity_id:
                  - cover.volets_ch_sud_rts
              data: {}
            type: button
          - show_name: false
            show_icon: true
            icon: mdi:weather-sunset-up
            name: Soleil
            tap_action:
              action: call-service
              service: cover.set_cover_position
              target:
                entity_id:
                  - cover.volets_ch_sud_rts
              data:
                position: 50
            type: button
          - elements:
              - attribute: current_position
                entity: cover.volets_ch_sud_rts
                style:
                  color: "#44739E"
                  font-size: 16px
                  font-weight: bold
                  left: 50%
                  top: 50%
                suffix: "%"
                tap_action:
                  action: more-info
                type: state-label
            image: /local/images/carre_orange.png
            type: picture-elements
            view_layout:
              position: sidebar
        columns: 6
        square: true
        type: grid
    type: vertical-stack

Conclusion

Avec cette automatisation, mes volets RTS sont devenus de vrais alliés au quotidien. Que ce soit pour garder la fraîcheur en été, profiter du soleil d’hiver ou sécuriser la maison en mon absence, tout est géré sans effort. La mesure de luminosité ajoute une précision redoutable, et ESPSomfy-RTS apporte une solution robuste et économique pour piloter mes volets Somfy. Si vous avez des volets compatibles RTS et Home Assistant, je vous encourage à tester cette configuration. Vous avez des idées pour l’améliorer ? Laissez un commentaire sur domo.rem81.com !

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *