Ma gestion de chauffage

EN COURS DE REDACTION, j’ajouterais le contenue au fil de l’eau dans le topics initial :slight_smile:

Hello,

Je profite de ce post pour share ma configuration de chauffage en fils pilotes.

Dans les grandes lignes je reprend ce qui est expliqué sur le dépot de simple_thermostat avec quelques adaptation NodeRED.

Page générale

Mode de chauffage
Ceci me permet de définir des templates de scheduling en fonction des jours de la semaines pour adapter au moins le type de chauffe que j’ai besoin en fonction des jours.

Rez de chaussée / Chambres
Bouton pour forcer une consigne à plusieurs zones en même temps

Thermostat
Permet de piloter rapidement tt les thermostat sans chargement

Calendrier
Permet de définir le templates de scheduling en fonction des jours de la semaines.

Page pour la programmation

C’est ici qu’on retrouve mes différents templates de programmation.

Page par zone

C’est ici que je configure les consignes de chaqu’un de mes presets du thermostat en question.

HACS Intégration nécéssaire

HACS Frontend nécéssaire

Création d’un thermostat sur HA

A dupliquer en fonction du nombre de zone.

- platform: simple_thermostat
  name: sejour
  heater: switch.action_chauffage_sejour
  target_sensor: sensor.temp_sejour
  min_temp: 7
  max_temp: 26
  ac_mode: false
  cold_tolerance: 0.3
  hot_tolerance: 0
  min_cycle_duration:
    seconds: 5
  keep_alive:
    minutes: 3
  initial_hvac_mode: "heat"
  precision: 0.1

Les input select pour la selection des template par jours :

climate_agenda_lundi:
  name: Lundi
  options:
   - Absent
   - Matin
   - Soir
   - Confort
   - Congés
   - Télé-Travail
climate_agenda_mardi:
  name: Mardi
  options:
   - Absent
   - Matin
   - Soir
   - Confort
   - Congés
   - Télé-Travail
climate_agenda_mercredi:
  name: Mercredi
  options:
   - Absent
   - Matin
   - Soir
   - Confort
   - Congés
   - Télé-Travail
climate_agenda_jeudi:
  name: Jeudi
  options:
   - Absent
   - Matin
   - Soir
   - Confort
   - Congés
   - Télé-Travail
climate_agenda_vendredi:
  name: Vendredi
  options:
   - Absent
   - Matin
   - Soir
   - Confort
   - Congés
   - Télé-Travail
climate_agenda_samedi:
  name: Samedi
  options:
   - Absent
   - Matin
   - Soir
   - Confort
   - Congés
   - Télé-Travail
climate_agenda_dimanche:
  name: Dimanche
  options:
   - Absent
   - Matin
   - Soir
   - Confort
   - Congés
   - Télé-Travail

Les input_number pour les consignes de chaques presets (a dupliquer par zone) :

climate_consigne_sleep_rdc_sejour:
  name: Hors-Gel
  min: 7
  max: 26
  step: 0.5
  unit_of_measurement: °C
climate_consigne_away_rdc_sejour:
  name: Absent
  min: 7
  max: 26
  step: 0.5
  unit_of_measurement: °C
climate_consigne_eco_rdc_sejour:
  name: Eco
  min: 7
  max: 26
  step: 0.5
  unit_of_measurement: °C
climate_consigne_home_rdc_sejour:
  name: Normal
  min: 7
  max: 26
  step: 0.5
  unit_of_measurement: °C
climate_consigne_comfort_rdc_sejour:
  name: Confort
  min: 7
  max: 26
  step: 0.5
  unit_of_measurement: °C

Ma page lovelace générale (il y les 8 thermostat dans mon cas donc un peu lourde) :

path: home
title: Home
type: custom:grid-layout
cards:
  - type: custom:layout-card
    layout_type: custom:grid-layout
    layout:
      grid-template-columns: 25% 25% 25% 25%
      grid-template-rows: auto
      grid-template-areas: |
        "title1 title1 title2 title3"
        "mode1 mode1 mode2 mode3"
        "line1 line2 line3 line4"
        "line5 line6 line7 line8"
      mediaquery:
        "(max-width: 600px)":
          grid-template-columns: 100%
          grid-template-areas: |
            "title1"
            "mode1"
            "title2"
            "mode2"
            "title3"
            "mode3"
            "line1"
            "line2"
            "line3"
            "line4"
            "line5"
            "line6"
            "line7"
            "line8"
        "(max-width: 1065px)":
          grid-template-columns: 50% 50%
          grid-template-areas: |
            "title1 mode1"
            "title2 mode2"
            "title3 mode3"
            "line1 line2"
            "line3 line4"
            "line5 line6"
            "line7 line8"
    cards:
      - type: horizontal-stack
        view_layout:
          grid-area: title1
        cards:
          - type: markdown
            content: "# Mode de chauffage"
            style: >
                  ha-card {
                    box-shadow: none;
                    font-size: 9px;
                    background: none;
                    padding-top: 8px;
                  }
                  ha-markdown.no-header {
                      padding-top: 0px !important;
                  }
          - type: markdown
            content: "{{ states('input_select.mode_chauffage') }}"
            style: >
                  ha-card {
                    font-size: 16px;
                    text-align: right;
                    font-style: italic;
                    padding-top: 8px;
                    background: none;
                    box-shadow: none;
                  }
                  ha-markdown.no-header {
                      padding-top: 0px !important;
                  }
      - type: horizontal-stack
        view_layout:
          grid-area: mode1
        cards:
          - type: custom:button-card
            entity: input_select.mode_chauffage
            icon: mdi:exit-run
            size: 70px
            show_state: false
            show_name: false
            color: 'var(--paper-item-icon-color)'
            state:
              - value: Absent
                color: "rgb(180,94,224)"
            tap_action:
              action: call-service
              service: input_select.select_option
              service_data:
                entity_id: input_select.mode_chauffage
                option: Absent
            styles:
              state:
                - font-size: 14px
                - padding-top: 5px
          - type: custom:button-card
            entity: input_select.mode_chauffage
            icon: mdi:weather-sunset-up
            size: 70px
            show_state: false
            show_name: false
            color: 'var(--paper-item-icon-color)'
            state:
              - value: Matin
                color: "#F2FC18"
            tap_action:
              action: call-service
              service: input_select.select_option
              service_data:
                entity_id: input_select.mode_chauffage
                option: Matin
            styles:
              state:
                - font-size: 14px
                - padding-top: 5px
          - type: custom:button-card
            entity: input_select.mode_chauffage
            icon: mdi:weather-sunset-down
            size: 70px
            show_state: false
            show_name: false
            color: 'var(--paper-item-icon-color)'
            state:
              - value: Soir
                color: "#FC9118"
            tap_action:
              action: call-service
              service: input_select.select_option
              service_data:
                entity_id: input_select.mode_chauffage
                option: Soir
            styles:
              state:
                - font-size: 14px
                - padding-top: 5px
          - type: custom:button-card
            entity: input_select.mode_chauffage
            icon: mdi:sofa
            size: 70px
            show_state: false
            show_name: false
            color: 'var(--paper-item-icon-color)'
            state:
              - value: Confort
                color: "rgb(223,94,94)"
            tap_action:
              action: call-service
              service: input_select.select_option
              service_data:
                entity_id: input_select.mode_chauffage
                option: Confort
            styles:
              state:
                - font-size: 14px
                - padding-top: 5px
          - type: custom:button-card
            entity: input_select.mode_chauffage
            icon: mdi:home-account
            size: 70px
            show_state: false
            show_name: false
            color: 'var(--paper-item-icon-color)'
            state:
              - value: Congés
                color: "rgb(223,94,94)"
            tap_action:
              action: call-service
              service: input_select.select_option
              service_data:
                entity_id: input_select.mode_chauffage
                option: Congés
            styles:
              state:
                - font-size: 14px
                - padding-top: 5px
          - type: custom:button-card
            entity: input_select.mode_chauffage
            icon: mdi:briefcase-variant-outline
            size: 70px
            show_state: false
            show_name: false
            color: 'var(--paper-item-icon-color)'
            state:
              - value: Télé-Travail
                color: "rgb(94,223,111)"
            tap_action:
              action: call-service
              service: input_select.select_option
              service_data:
                entity_id: input_select.mode_chauffage
                option: Télé-Travail
            styles:
              state:
                - font-size: 14px
                - padding-top: 5px
      - type: horizontal-stack
        view_layout:
          grid-area: title2
        cards:
          - type: markdown
            content: "# Rez de chaussée"
            style: >
                  ha-card {
                    box-shadow: none;
                    font-size: 9px;
                    background: none;
                    padding-top: 8px;
                  }
                  ha-markdown.no-header {
                      padding-top: 0px !important;
                  }
      - type: horizontal-stack
        view_layout:
          grid-area: mode2
        cards:
          - type: custom:button-card
            icon: mdi:snowflake
            size: 70px
            style: >
              ha-card {
                height: 100%;
              }
            show_state: false
            show_name: false
            color: 'rgb(130,223,223)'
            state:
              - value: sleep
                color: "rgb(130,223,223)"
            tap_action:
              action: call-service
              service: mqtt.publish
              service_data:
                topic: nodered/climate/zone/rdc
                payload: sleep
          - type: custom:button-card
            icon: mdi:exit-run
            size: 70px
            style: >
              ha-card {
                height: 100%;
              }
            show_state: false
            show_name: false
            color: 'rgb(180,94,224)'
            state:
              - value: away
                color: "rgb(180,94,224)"
            tap_action:
              action: call-service
              service: mqtt.publish
              service_data:
                topic: nodered/climate/zone/rdc
                payload: away
          - type: custom:button-card
            icon: mdi:leaf
            size: 70px
            style: >
              ha-card {
                height: 100%;
              }
            show_state: false
            show_name: false
            color: 'rgb(94,223,111)'
            state:
              - value: eco
                color: "rgb(94,223,111)"
            tap_action:
              action: call-service
              service: mqtt.publish
              service_data:
                topic: nodered/climate/zone/rdc
                payload: eco
          - type: custom:button-card
            icon: mdi:fire
            size: 70px
            style: >
              ha-card {
                height: 100%;
              }
            show_state: false
            show_name: false
            color: 'rgb(223,223,94)'
            state:
              - value: home
                color: "rgb(223,223,94)"
            tap_action:
              action: call-service
              service: mqtt.publish
              service_data:
                topic: nodered/climate/zone/rdc
                payload: home
          - type: custom:button-card
            icon: mdi:sofa
            size: 70px
            style: >
              ha-card {
                height: 100%;
              }
            show_state: false
            show_name: false
            color: 'rgb(223,94,94)'
            state:
              - value: comfort
                color: "rgb(223,94,94)"
            tap_action:
              action: call-service
              service: mqtt.publish
              service_data:
                topic: nodered/climate/zone/rdc
                payload: comfort
      - type: horizontal-stack
        view_layout:
          grid-area: title3
        cards:
          - type: markdown
            content: "# Chambres"
            style: >
                  ha-card {
                    box-shadow: none;
                    font-size: 9px;
                    background: none;
                    padding-top: 8px;
                  }
                  ha-markdown.no-header {
                      padding-top: 0px !important;
                  }
      - type: horizontal-stack
        view_layout:
          grid-area: mode3
        cards:
          - type: custom:button-card
            icon: mdi:snowflake
            size: 70px
            style: >
              ha-card {
                height: 100%;
              }
            show_state: false
            show_name: false
            color: 'rgb(130,223,223)'
            state:
              - value: sleep
                color: "rgb(130,223,223)"
            tap_action:
              action: call-service
              service: mqtt.publish
              service_data:
                topic: nodered/climate/zone/chambres
                payload: sleep
          - type: custom:button-card
            icon: mdi:exit-run
            size: 70px
            style: >
              ha-card {
                height: 100%;
              }
            show_state: false
            show_name: false
            color: 'rgb(180,94,224)'
            state:
              - value: away
                color: "rgb(180,94,224)"
            tap_action:
              action: call-service
              service: mqtt.publish
              service_data:
                topic: nodered/climate/zone/chambres
                payload: away
          - type: custom:button-card
            icon: mdi:leaf
            size: 70px
            style: >
              ha-card {
                height: 100%;
              }
            show_state: false
            show_name: false
            color: 'rgb(94,223,111)'
            state:
              - value: eco
                color: "rgb(94,223,111)"
            tap_action:
              action: call-service
              service: mqtt.publish
              service_data:
                topic: nodered/climate/zone/chambres
                payload: eco
          - type: custom:button-card
            icon: mdi:fire
            size: 70px
            style: >
              ha-card {
                height: 100%;
              }
            show_state: false
            show_name: false
            color: 'rgb(223,223,94)'
            state:
              - value: home
                color: "rgb(223,223,94)"
            tap_action:
              action: call-service
              service: mqtt.publish
              service_data:
                topic: nodered/climate/zone/chambres
                payload: home
          - type: custom:button-card
            icon: mdi:sofa
            size: 70px
            style: >
              ha-card {
                height: 100%;
              }
            show_state: false
            show_name: false
            color: 'rgb(223,94,94)'
            state:
              - value: comfort
                color: "rgb(223,94,94)"
            tap_action:
              action: call-service
              service: mqtt.publish
              service_data:
                topic: nodered/climate/zone/chambres
                payload: comfort
      - type: custom:stack-in-card
        view_layout:
          grid-area: line1
        mode: vertical
        cards:
          - type: 'custom:simple-thermostat'
            entity: climate.sejour
            version: 3
            header:
              name: Séjour
            style: |
              ha-card.heating .current--value,
              ha-card.heating ha-icon.header__icon {
                color: red;
              }
              .mode {
                margin-top: 0px
                padding: 15px;
              }
              .mode-icon {
                min-height: 50px;
              --mdc-icon-size: 50px;
              }
              .mode-item {
                background: none !important;
                color: var(--state-icon-color) !important;
              }
              .mode-item.active.sleep {
                background: none;
                color: rgb(130,223,223) !important;
              }
              .mode-item.active.away {
                background: none;
                color: rgb(180,94,224) !important;
              }
              .mode-item.active.eco {
                background: none;
                color: rgb(94,223,111) !important;
              }
              .mode-item.active.home {
                background: none;
                color: rgb(223,223,94) !important;
              }
              .mode-item.active.comfort {
                background: none;
                color: rgb(223,94,94) !important;
              }
            step_size: 0.5
            sensors:
              - id: state
                label: Etat
                template: '{{hvac_action|translate(''state_attributes.climate.hvac_action.'')}}'
              - id: temperature
                label: 'Température'
                template: '{{current_temperature|formatNumber}}°C'
              - label: Minimun
                template: '{{min_temp}}°C'
              - label: Maximun
                template: '{{max_temp}}°C'
              - entity: sensor.hum_sejour
                template: '{{state.text}}%'
                label: 'Humidité'
            layout:
              mode:
                headings: false
            control:
              preset:
                none: false
                activity: false
                boost: false
                "sleep":
                  name: ""
                  icon: mdi:snowflake
                "away":
                  name: ""
                  icon: mdi:exit-run
                "eco":
                  name: ""
                  icon: mdi:leaf
                "home":
                  name: ""
                  icon: mdi:fire
                "comfort":
                  name: ""
                  icon: mdi:sofa
  - type: custom:layout-card
    layout_type: custom:grid-layout
    layout:
      grid-template-columns: auto auto auto
      grid-template-rows: auto
      grid-template-areas: |
        "footer1 footer2 footer3 footer4 footer5 footer6 footer7"
      mediaquery:
        "(max-width: 600px)":
          grid-template-columns: 100%
          grid-template-areas: |
            "footer1"
            "footer2"
            "footer3"
            "footer4"
            "footer5"
            "footer6"
            "footer7"
        "(max-width: 1065px)":
          grid-template-columns: auto auto
          grid-template-areas: |
            "footer1 footer2"
            "footer3 footer4"
            "footer5 footer6"
            "footer7 footer8"
        "(max-width: 1550px)":
          grid-template-columns: auto auto auto auto
          grid-template-areas: |
            "footer1 footer2 footer3 footer4"
            "footer5 footer6 footer7 footer8"
    cards:
      - type: entities
        view_layout:
          grid-area: footer1
        entities:
          - entity: input_select.climate_agenda_lundi
      - type: entities
        view_layout:
          grid-area: footer2
        entities:
          - entity: input_select.climate_agenda_mardi
      - type: entities
        view_layout:
          grid-area: footer3
        entities:
          - entity: input_select.climate_agenda_mercredi
      - type: entities
        view_layout:
          grid-area: footer4
        entities:
          - entity: input_select.climate_agenda_jeudi
      - type: entities
        view_layout:
          grid-area: footer5
        entities:
          - entity: input_select.climate_agenda_vendredi
      - type: entities
        view_layout:
          grid-area: footer6
        entities:
          - entity: input_select.climate_agenda_samedi
      - type: entities
        view_layout:
          grid-area: footer7
        entities:
          - entity: input_select.climate_agenda_dimanche

Ma page de scheduling :

path: climate_sheduler
title: Programmation
type: custom:grid-layout
cards:

  - type: custom:stack-in-card
    mode: horizontal
    cards:
      - type: custom:layout-card
        layout_type: custom:grid-layout
        layout:
          grid-template-columns: 33% 34% 33%
          grid-template-rows: auto
          grid-template-areas: |
            "absent confort matin"
            "soir conges teletravail"
          mediaquery:
            "(max-width: 600px)":
              grid-template-columns: 100%
              grid-template-areas: |
                "absent"
                "confort"
                "matin"
                "soir"
                "conges"
                "teletravail"
            "(max-width: 1550px)":
              grid-template-columns: 50% 50%
              grid-template-areas: |
                "absent confort"
                "matin soir"
                "conges teletravail"
        cards:
          - type: custom:scheduler-card
            style: |
              ha-card {
                border: 0px;
                background: none;
                box-shadow: none;
              }
              .card-actions {
                border-top: 0px !important
              }
              .card-header {
              {% set mode_chauffage = states('input_select.mode_chauffage') %}
              {% if mode_chauffage == "Absent" %}
                color: var(--accent-color) !important;
              {% endif %}              }
            view_layout:
              grid-area: absent
            show_header_toggle: false
            display_options:
              primary_info:
                - "{name}"
                - "{action}"
            include:
              - climate
              - input_select.mode_chauffage
            title: Absent
            discover_existing: false
            time_step: 5
            tags:
              - absent
          - type: custom:scheduler-card
            style: |
              ha-card {
                border: 0px;
                background: none;
                box-shadow: none;
              }
              .card-actions {
                border-top: 0px !important
              }
              .card-header {
              {% set mode_chauffage = states('input_select.mode_chauffage') %}
              {% if mode_chauffage == "Matin" %}
                color: var(--accent-color) !important;
              {% endif %}              }
            view_layout:
              grid-area: matin
            show_header_toggle: false
            display_options:
              primary_info:
                - "{name}"
                - "{action}"
            include:
              - climate
              - input_select.mode_chauffage
            title: Matin
            discover_existing: false
            time_step: 5
            tags:
              - matin
          - type: custom:scheduler-card
            style: |
              ha-card {
                border: 0px;
                background: none;
                box-shadow: none;
              }
              .card-actions {
                border-top: 0px !important
              }
              .card-header {
              {% set mode_chauffage = states('input_select.mode_chauffage') %}
              {% if mode_chauffage == "Soir" %}
                color: var(--accent-color) !important;
              {% endif %}              }
            view_layout:
              grid-area: soir
            show_header_toggle: false
            display_options:
              primary_info:
                - "{name}"
                - "{action}"
            include:
              - climate
              - input_select.mode_chauffage
            title: Soir
            discover_existing: false
            time_step: 5
            tags:
              - soir
          - type: custom:scheduler-card
            style: |
              ha-card {
                border: 0px;
                background: none;
                box-shadow: none;
              }
              .card-actions {
                border-top: 0px !important
              }
              .card-header {
              {% set mode_chauffage = states('input_select.mode_chauffage') %}
              {% if mode_chauffage == "Confort" %}
                color: var(--accent-color) !important;
              {% endif %}              }
            view_layout:
              grid-area: confort
            show_header_toggle: false
            display_options:
              primary_info:
                - "{name}"
                - "{action}"
            include:
              - climate
              - input_select.mode_chauffage
            title: Confort
            discover_existing: false
            time_step: 5
            tags:
              - confort
          - type: custom:scheduler-card
            style: |
              ha-card {
                border: 0px;
                background: none;
                box-shadow: none;
              }
              .card-actions {
                border-top: 0px !important
              }
              .card-header {
              {% set mode_chauffage = states('input_select.mode_chauffage') %}
              {% if mode_chauffage == "Congés" %}
                color: var(--accent-color) !important;
              {% endif %}              }
            view_layout:
              grid-area: conges
            show_header_toggle: false
            display_options:
              primary_info:
                - "{name}"
                - "{action}"
            include:
              - climate
              - input_select.mode_chauffage
            title: Congés
            discover_existing: false
            time_step: 5
            tags:
              - conges
          - type: custom:scheduler-card
            style: |
              ha-card {
                border: 0px;
                background: none;
                box-shadow: none;
              }
              .card-actions {
                border-top: 0px !important
              }
              .card-header {
              {% set mode_chauffage = states('input_select.mode_chauffage') %}
              {% if mode_chauffage == "Télé-Travail" %}
                color: var(--accent-color) !important;
              {% endif %}              }
            view_layout:
              grid-area: teletravail
            show_header_toggle: false
            display_options:
              primary_info:
                - "{name}"
                - "{action}"
            include:
              - climate
              - input_select.mode_chauffage
            title: Télé-Travail
            discover_existing: false
            time_step: 5
            tags:
              - teletravail

Ma page dédiée pour chaque thermostat (a dupliquer en fonction du nombre de thermostat également) :

path: sejour
title: Séjour
type: custom:grid-layout
cards:

  - type: picture
    image: /local/piece/sejour.png
  - type: custom:layout-card
    layout_type: custom:grid-layout
    layout:
      grid-template-columns: auto auto
      grid-template-rows: auto
      grid-template-areas: |
        "climate config"
      mediaquery:
        "(max-width: 1065px)":
          grid-template-columns: 100%
          grid-template-areas: |
            "climate"
            "config"
    cards:
      - type: custom:stack-in-card
        mode: vertical
        cards:
          - type: 'custom:simple-thermostat'
            entity: climate.sejour
            version: 3
            header:
              name: Séjour
            style: |
              ha-card.heating .current--value,
              ha-card.heating ha-icon.header__icon {
                color: red;
              }
              .mode {
                margin-top: 0px
                padding: 15px;
              }
              .mode-icon {
                min-height: 50px;
              --mdc-icon-size: 50px;
              }
              .mode-item {
                background: none !important;
                color: var(--state-icon-color) !important;
              }
              .mode-item.active.sleep {
                background: none;
                color: rgb(130,223,223) !important;
              }
              .mode-item.active.away {
                background: none;
                color: rgb(180,94,224) !important;
              }
              .mode-item.active.eco {
                background: none;
                color: rgb(94,223,111) !important;
              }
              .mode-item.active.home {
                background: none;
                color: rgb(223,223,94) !important;
              }
              .mode-item.active.comfort {
                background: none;
                color: rgb(223,94,94) !important;
              }
            step_size: 0.5
            sensors:
              - id: state
                label: Etat
                template: '{{hvac_action|translate(''state_attributes.climate.hvac_action.'')}}'
              - id: temperature
                label: 'Température'
                template: '{{current_temperature|formatNumber}}°C'
              - label: Minimun
                template: '{{min_temp}}°C'
              - label: Maximun
                template: '{{max_temp}}°C'
              - entity: sensor.hum_sejour
                template: '{{state.text}}%'
                label: 'Humidité'
            layout:
              mode:
                headings: false
            control:
              preset:
                none: false
                activity: false
                boost: false
                "sleep":
                  name: ""
                  icon: mdi:snowflake
                "away":
                  name: ""
                  icon: mdi:exit-run
                "eco":
                  name: ""
                  icon: mdi:leaf
                "home":
                  name: ""
                  icon: mdi:fire
                "comfort":
                  name: ""
                  icon: mdi:sofa

      - type: custom:vertical-stack-in-card
        view_layout:
          grid-area: config
        style: |
          ha-card {
            height: 295px;
          }
        cards:
          - type: entities
            entities:
              - entity: input_number.climate_consigne_sleep_rdc_sejour
                name: Hors-Gel
                icon: mdi:fire
              - entity: input_number.climate_consigne_away_rdc_sejour
                name: Absent
                icon: mdi:fire
              - entity: input_number.climate_consigne_eco_rdc_sejour
                name: Eco
                icon: mdi:fire
              - entity: input_number.climate_consigne_home_rdc_sejour
                name: Normal
                icon: mdi:fire
              - entity: input_number.climate_consigne_comfort_rdc_sejour
                name: Confort
                icon: mdi:fire
  - type: custom:layout-card
    layout_type: custom:grid-layout
    layout:
      grid-template-columns: 100%
      grid-template-rows: auto
      grid-template-areas: |
        "graph"
    cards:
      - type: horizontal-stack
        view_layout:
          grid-area: graph
        cards:
          - type: custom:mini-graph-card
            name: Séjour
            icon: mdi:temperature-celsius
            animate: false
            font_size: 100
            font_size_header: 10
            points_per_hour: 60
            line_width: 1
            hours_to_show: 48
            show:
              extrema: false
              labels: false
              labels_secondary: false
            entities:
              - entity: sensor.temp_sejour
                name: Température
                smoothing: true
                color: "#C13618"
                font_size: 75
                unit: "°C"
                show_points: false
                show_fill: false
                show_legend: true
                show_indicator: false
              - entity: sensor.cible_chauffage_sejour
                name: Cible
                color: "#DFAA5E"
                font_size: 75
                smoothing: false
                unit: "°C"
                show_fill: false
                show_line: true
                show_points: false
                show_legend: true
                show_indicator: false
              - entity: sensor.status_chauffage_sejour
                name: Etat
                color: "#5EDADF"
                font_size: 75
                smoothing: false
                unit: "°C"
                y_axis: secondary
                show_fill: false
                show_line: true
                show_points: false
                show_legend: true
                show_indicator: false
              - entity: sensor.night
                name: Nuit
                color: "#717171"
                font_size: 75
                smoothing: false
                unit: "°C"
                y_axis: secondary
                show_line: false
                show_points: false
                show_legend: true
                show_indicator: false
              - entity: sensor.hum_sejour
                name: Humidité
                unit: "%"
                color: "#1871C1"
                font_size: 75
                smoothing: false
                y_axis: secondary
                show_line: false
                show_points: false
                show_legend: true
                show_indicator: false

Mon Flow Node-RED :

[
    {
        "id": "fffb452a.5a3458",
        "type": "server-state-changed",
        "z": "12ac70ec.f1d30f",
        "name": "input_number.climate_consigne_",
        "server": "7f33d7bb.9361a8",
        "version": 3,
        "exposeToHomeAssistant": false,
        "haConfig": [
            {
                "property": "name",
                "value": ""
            },
            {
                "property": "icon",
                "value": ""
            }
        ],
        "entityidfilter": "input_number.climate_consigne_.*",
        "entityidfiltertype": "regex",
        "outputinitially": false,
        "state_type": "num",
        "haltifstate": "NaN",
        "halt_if_type": "str",
        "halt_if_compare": "is_not",
        "outputs": 2,
        "output_only_on_state_change": true,
        "for": "0",
        "forType": "num",
        "forUnits": "minutes",
        "ignorePrevStateNull": false,
        "ignorePrevStateUnknown": false,
        "ignorePrevStateUnavailable": false,
        "ignoreCurrentStateUnknown": true,
        "ignoreCurrentStateUnavailable": true,
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "data",
                "propertyType": "msg",
                "value": "",
                "valueType": "eventData"
            },
            {
                "property": "topic",
                "propertyType": "msg",
                "value": "",
                "valueType": "triggerId"
            }
        ],
        "x": 150,
        "y": 210,
        "wires": [
            [
                "21c76a6d.e2c756"
            ],
            []
        ]
    },
    {
        "id": "21c76a6d.e2c756",
        "type": "function",
        "z": "12ac70ec.f1d30f",
        "name": "Save Consigne",
        "func": "msg.switch = 2;\n\nvar topic = msg.topic.replace('input_number.climate_consigne_',\"\");\nmsg.mode = topic.split('_')[0];\nmsg.zone = topic.split('_')[1];\nmsg.name = topic.split('_')[2];\nif ( ! isNaN(msg.payload) && msg.payload != undefined) {\n    flow.set(\"climate.\"+msg.name+\".target.\"+msg.mode, msg.payload);\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 420,
        "y": 210,
        "wires": [
            [
                "19cedccf.367543"
            ]
        ]
    },
    {
        "id": "8db6d27e.3238a",
        "type": "api-call-service",
        "z": "12ac70ec.f1d30f",
        "name": "set_temperature",
        "server": "7f33d7bb.9361a8",
        "version": 3,
        "debugenabled": false,
        "service_domain": "climate",
        "service": "set_temperature",
        "entityId": "climate.{{name}}",
        "data": "{\"entity_id\":\"climate.{{name}}\",\"temperature\":\"{{target}}\"}",
        "dataType": "json",
        "mergecontext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "x": 1210,
        "y": 240,
        "wires": [
            []
        ]
    },
    {
        "id": "e2c02571.d33478",
        "type": "function",
        "z": "12ac70ec.f1d30f",
        "name": "Set température",
        "func": "var name = msg.name;\nvar zone = msg.zone;\nmsg.current_mode = flow.get(\"climate.\"+name+\".thermostat_current\");\nreturn msg;   ",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 830,
        "y": 210,
        "wires": [
            [
                "b3f742aed0643ada"
            ]
        ]
    },
    {
        "id": "19cedccf.367543",
        "type": "string",
        "z": "12ac70ec.f1d30f",
        "name": "",
        "methods": [
            {
                "name": "toLowerCase",
                "params": []
            },
            {
                "name": "replaceAll",
                "params": [
                    {
                        "type": "str",
                        "value": "-"
                    },
                    {
                        "type": "str",
                        "value": " "
                    }
                ]
            }
        ],
        "prop": "mode",
        "propout": "mode",
        "object": "msg",
        "objectout": "msg",
        "x": 650,
        "y": 210,
        "wires": [
            [
                "e2c02571.d33478"
            ]
        ]
    },
    {
        "id": "b3f742aed0643ada",
        "type": "switch",
        "z": "12ac70ec.f1d30f",
        "name": "",
        "property": "current_mode",
        "propertyType": "msg",
        "rules": [
            {
                "t": "neq",
                "v": "mode",
                "vt": "str"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 990,
        "y": 210,
        "wires": [
            [
                "dfa177e9cfde19e7"
            ],
            [
                "8db6d27e.3238a"
            ]
        ]
    },
    {
        "id": "1ed548078e1d2154",
        "type": "function",
        "z": "12ac70ec.f1d30f",
        "name": "Save Consigne",
        "func": "msg.switch = 1;\n\nfunction RemoveAccents(str) {\n  var accents    = 'ÀÁÂÃÄÅàáâãäåÒÓÔÕÕÖØòóôõöøÈÉÊËèéêëðÇçÐÌÍÎÏìíîïÙÚÛÜùúûüÑñŠšŸÿýŽž';\n  var accentsOut = \"AAAAAAaaaaaaOOOOOOOooooooEEEEeeeeeCcDIIIIiiiiUUUUuuuuNnSsYyyZz\";\n  str = str.split('');\n  var strLen = str.length;\n  var i, x;\n  for (i = 0; i < strLen; i++) {\n    if ((x = accents.indexOf(str[i])) != -1) {\n      str[i] = accentsOut[x];\n    }\n  }\n  return str.join('');\n}\n\nvar preset_mode = msg.data.new_state.attributes.preset_mode\nvar topic = msg.topic.replace('climate.',\"\");\nmsg.name = topic.split('_')[0];\nmsg.mode = preset_mode\n\nvar thermostat_current = flow.get(\"climate.\"+msg.name+\".thermostat_current\");\n\n// flow.set(\"climate.\"+msg.name+\".mode\", preset_mode);\n\nmsg.debug = {\n    \"thermostat_current\": thermostat_current,\n    \"preset_mode\": preset_mode\n}\n\nif (thermostat_current != preset_mode) {\n    // Only preset filter\n    flow.set(\"climate.\"+msg.name+\".thermostat_current\", preset_mode);\n    return msg;\n}",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 420,
        "y": 140,
        "wires": [
            [
                "1c25177782ed17f1"
            ]
        ]
    },
    {
        "id": "1c25177782ed17f1",
        "type": "string",
        "z": "12ac70ec.f1d30f",
        "name": "",
        "methods": [
            {
                "name": "toLowerCase",
                "params": []
            },
            {
                "name": "replaceAll",
                "params": [
                    {
                        "type": "str",
                        "value": "-"
                    },
                    {
                        "type": "str",
                        "value": " "
                    }
                ]
            }
        ],
        "prop": "mode",
        "propout": "mode",
        "object": "msg",
        "objectout": "msg",
        "x": 650,
        "y": 140,
        "wires": [
            [
                "954841f0f31a6be0"
            ]
        ]
    },
    {
        "id": "954841f0f31a6be0",
        "type": "function",
        "z": "12ac70ec.f1d30f",
        "name": "Get température",
        "func": "var name = msg.name;\nvar mode = msg.mode;\nvar target = flow.get(\"climate.\"+name+\".target.\"+mode);\nvar preset = mode;\n\nvar zones = flow.get(\"climate_zone\")\nmsg.debug = zones;\n\nfor (let id_zone in zones) {\n    list_zone = zones[id_zone];\n    for (let id_name in list_zone) {\n        check_name = list_zone[id_name];\n        if (name == check_name) {\n            zone = id_zone;\n        }\n    }\n}\n\nmsg.payload = {\n    \"name\": name,\n    \"zone\": zone,\n    \"preset\": preset\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 810,
        "y": 140,
        "wires": [
            [
                "d542e49e2f121404"
            ]
        ]
    },
    {
        "id": "1879e08.e359f2",
        "type": "server-state-changed",
        "z": "12ac70ec.f1d30f",
        "name": "",
        "server": "7f33d7bb.9361a8",
        "version": 3,
        "exposeToHomeAssistant": false,
        "haConfig": [
            {
                "property": "name",
                "value": ""
            },
            {
                "property": "icon",
                "value": ""
            }
        ],
        "entityidfilter": "^climate\\.+",
        "entityidfiltertype": "regex",
        "outputinitially": false,
        "state_type": "str",
        "haltifstate": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "outputs": 1,
        "output_only_on_state_change": false,
        "for": "0",
        "forType": "num",
        "forUnits": "minutes",
        "ignorePrevStateNull": false,
        "ignorePrevStateUnknown": false,
        "ignorePrevStateUnavailable": false,
        "ignoreCurrentStateUnknown": true,
        "ignoreCurrentStateUnavailable": true,
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "data",
                "propertyType": "msg",
                "value": "",
                "valueType": "eventData"
            },
            {
                "property": "topic",
                "propertyType": "msg",
                "value": "",
                "valueType": "triggerId"
            }
        ],
        "x": 170,
        "y": 140,
        "wires": [
            [
                "1ed548078e1d2154"
            ]
        ]
    },
    {
        "id": "dfa177e9cfde19e7",
        "type": "api-call-service",
        "z": "12ac70ec.f1d30f",
        "name": "Change Preset",
        "server": "7f33d7bb.9361a8",
        "version": 3,
        "debugenabled": false,
        "service_domain": "climate",
        "service": "set_preset_mode",
        "entityId": "climate.{{name}}",
        "data": "{\"preset_mode\":\"{{mode}}\"}",
        "dataType": "json",
        "mergecontext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "x": 1210,
        "y": 190,
        "wires": [
            [
                "04d5275241eb763c"
            ]
        ]
    },
    {
        "id": "04d5275241eb763c",
        "type": "api-call-service",
        "z": "12ac70ec.f1d30f",
        "name": "set_temperature",
        "server": "7f33d7bb.9361a8",
        "version": 3,
        "debugenabled": false,
        "service_domain": "climate",
        "service": "set_temperature",
        "entityId": "climate.{{name}}",
        "data": "{\"entity_id\":\"climate.{{name}}\",\"temperature\":\"{{payload}}\"}",
        "dataType": "json",
        "mergecontext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "x": 1430,
        "y": 150,
        "wires": [
            [
                "21023ea120e0c425"
            ]
        ]
    },
    {
        "id": "21023ea120e0c425",
        "type": "api-call-service",
        "z": "12ac70ec.f1d30f",
        "name": "Restore Preset",
        "server": "7f33d7bb.9361a8",
        "version": 3,
        "debugenabled": false,
        "service_domain": "climate",
        "service": "set_preset_mode",
        "entityId": "climate.{{name}}",
        "data": "{\"preset_mode\":\"{{current_mode}}\"}",
        "dataType": "json",
        "mergecontext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "x": 1680,
        "y": 110,
        "wires": [
            []
        ]
    },
    {
        "id": "4c6cc3e74cdba2a6",
        "type": "inject",
        "z": "12ac70ec.f1d30f",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "60",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payloadType": "date",
        "x": 210,
        "y": 50,
        "wires": [
            [
                "b5fe1570a79b9518"
            ]
        ]
    },
    {
        "id": "b5fe1570a79b9518",
        "type": "function",
        "z": "12ac70ec.f1d30f",
        "name": "Configuration",
        "func": "var climate_zone = {\n    \"rdc\": [\"sejour\", \"hall\", \"cuisine\", \"bureau\", \"chambrerdc\"],\n    \"chambres\": [\"parents\", \"chloe\", \"simon\"]\n}\nflow.set(\"climate_zone\",climate_zone)",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 410,
        "y": 50,
        "wires": [
            []
        ]
    },
    {
        "id": "e04b8eb419385665",
        "type": "server-state-changed",
        "z": "12ac70ec.f1d30f",
        "name": "input_select.mode_chauffage",
        "server": "7f33d7bb.9361a8",
        "version": 3,
        "exposeToHomeAssistant": false,
        "haConfig": [
            {
                "property": "name",
                "value": ""
            },
            {
                "property": "icon",
                "value": ""
            }
        ],
        "entityidfilter": "input_select.mode_chauffage",
        "entityidfiltertype": "regex",
        "outputinitially": false,
        "state_type": "str",
        "haltifstate": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "outputs": 1,
        "output_only_on_state_change": true,
        "for": "0",
        "forType": "num",
        "forUnits": "minutes",
        "ignorePrevStateNull": false,
        "ignorePrevStateUnknown": false,
        "ignorePrevStateUnavailable": false,
        "ignoreCurrentStateUnknown": false,
        "ignoreCurrentStateUnavailable": false,
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "data",
                "propertyType": "msg",
                "value": "",
                "valueType": "eventData"
            },
            {
                "property": "topic",
                "propertyType": "msg",
                "value": "",
                "valueType": "triggerId"
            }
        ],
        "x": 160,
        "y": 350,
        "wires": [
            [
                "90ff61b0ddb09293"
            ]
        ]
    },
    {
        "id": "90ff61b0ddb09293",
        "type": "function",
        "z": "12ac70ec.f1d30f",
        "name": "Switch Ambiance Mode",
        "func": "function transform2ha(str) {\n  var accents    = 'ÀÁÂÃÄÅàáâãäåÒÓÔÕÕÖØòóôõöøÈÉÊËèéêëðÇçÐÌÍÎÏìíîïÙÚÛÜùúûüÑñŠšŸÿýŽž';\n  var accentsOut = \"AAAAAAaaaaaaOOOOOOOooooooEEEEeeeeeCcDIIIIiiiiUUUUuuuuNnSsYyyZz\";\n  str = str.replace(\"-\",\"\").toLowerCase();\n  str = str.split('');\n  var strLen = str.length;\n  var i, x;\n  for (i = 0; i < strLen; i++) {\n    if ((x = accents.indexOf(str[i])) != -1) {\n      str[i] = accentsOut[x];\n    }\n  }\n  return str.join('');\n}\n\nvar new_mode = transform2ha(msg.payload)\nvar old_mode = transform2ha(msg.data.old_state.state)\n\nflow.set(\"thermostats.ambiance\",new_mode);\n\n// Sheduler management\nmsg.payload = []\nvar shedulers = flow.get(\"sheduler\")\nfor (let id_shedulers in shedulers){\n    var mode = id_shedulers;\n    var sheduler = shedulers[id_shedulers];\n    \n    for(let id_sheduler in sheduler) {\n\n        // Disable old mode\n        if (mode == old_mode) {\n            msg.payload.push({\n                \"topic\": \"switch.\"+id_sheduler,\n                \"service\": \"turn_off\"\n            })\n        }\n        \n        //Enable new mode\n        if (mode == new_mode) {\n            msg.payload.push({\n                \"topic\": \"switch.\"+id_sheduler,\n                \"service\": \"turn_on\"\n            })\n        }        \n        node.log(id_sheduler)\n    }\n}\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 450,
        "y": 350,
        "wires": [
            [
                "4c35911265b9674f"
            ]
        ]
    },
    {
        "id": "d542e49e2f121404",
        "type": "api-call-service",
        "z": "12ac70ec.f1d30f",
        "name": "Change Input Select",
        "server": "7f33d7bb.9361a8",
        "version": 3,
        "debugenabled": false,
        "service_domain": "input_select",
        "service": "select_option",
        "entityId": "input_select.climate_selection_{{payload.zone}}_{{payload.name}}",
        "data": "{\"option\":\"{{payload.preset}}\"}",
        "dataType": "json",
        "mergecontext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "x": 1020,
        "y": 140,
        "wires": [
            []
        ]
    },
    {
        "id": "a3df28c9500eb3b3",
        "type": "inject",
        "z": "12ac70ec.f1d30f",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "00 00 * * *",
        "once": false,
        "onceDelay": 0.1,
        "topic": "cron",
        "payloadType": "date",
        "x": 200,
        "y": 410,
        "wires": [
            [
                "1af2d481928e938a"
            ]
        ]
    },
    {
        "id": "cbfb163e64af99bd",
        "type": "server-state-changed",
        "z": "12ac70ec.f1d30f",
        "name": "input_select.climate_agenda_",
        "server": "7f33d7bb.9361a8",
        "version": 3,
        "exposeToHomeAssistant": false,
        "haConfig": [
            {
                "property": "name",
                "value": ""
            },
            {
                "property": "icon",
                "value": ""
            }
        ],
        "entityidfilter": "input_select.climate_agenda_.*",
        "entityidfiltertype": "regex",
        "outputinitially": true,
        "state_type": "str",
        "haltifstate": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "outputs": 1,
        "output_only_on_state_change": false,
        "for": "0",
        "forType": "num",
        "forUnits": "minutes",
        "ignorePrevStateNull": true,
        "ignorePrevStateUnknown": false,
        "ignorePrevStateUnavailable": false,
        "ignoreCurrentStateUnknown": false,
        "ignoreCurrentStateUnavailable": false,
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "data",
                "propertyType": "msg",
                "value": "",
                "valueType": "eventData"
            },
            {
                "property": "topic",
                "propertyType": "msg",
                "value": "",
                "valueType": "triggerId"
            }
        ],
        "x": 160,
        "y": 280,
        "wires": [
            [
                "8333991bae3aca3c"
            ]
        ]
    },
    {
        "id": "8333991bae3aca3c",
        "type": "function",
        "z": "12ac70ec.f1d30f",
        "name": "Agenda",
        "func": "msg.switch = 6;\nvar topic = msg.topic.replace('input_select.climate_agenda_',\"\");\nmsg.day = topic.split('_')[0];\nflow.set(\"calendrier.\"+msg.day+\".mode\", msg.payload);\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 400,
        "y": 280,
        "wires": [
            []
        ]
    },
    {
        "id": "1af2d481928e938a",
        "type": "function",
        "z": "12ac70ec.f1d30f",
        "name": "Change Ambiance Mode",
        "func": "msg.switch = 7;\nvar days = ['dimanche','lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'];\nvar day = new Date();\nday = days[day.getDay()];\n\nmsg.day = day;\n\nmsg.mode = flow.get(\"calendrier.\"+day+\".mode\")\n\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 450,
        "y": 410,
        "wires": [
            [
                "871de269358e2af4"
            ]
        ]
    },
    {
        "id": "871de269358e2af4",
        "type": "api-call-service",
        "z": "12ac70ec.f1d30f",
        "name": "Change Input Select",
        "server": "7f33d7bb.9361a8",
        "version": 3,
        "debugenabled": true,
        "service_domain": "input_select",
        "service": "select_option",
        "entityId": "input_select.mode_chauffage",
        "data": "{\"option\":\"{{mode}}\"}",
        "dataType": "json",
        "mergecontext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "x": 790,
        "y": 410,
        "wires": [
            []
        ]
    },
    {
        "id": "f2e952e8ddd141d7",
        "type": "mqtt in",
        "z": "12ac70ec.f1d30f",
        "name": "",
        "topic": "nodered/climate/zone/rdc",
        "qos": "0",
        "datatype": "auto",
        "broker": "94fffe91.c7ff7",
        "nl": false,
        "rap": false,
        "rh": "2",
        "inputs": 0,
        "x": 200,
        "y": 480,
        "wires": [
            [
                "0755af5e251b9e89"
            ]
        ]
    },
    {
        "id": "261dbf0bf20550e7",
        "type": "mqtt in",
        "z": "12ac70ec.f1d30f",
        "name": "",
        "topic": "nodered/climate/zone/chambres",
        "qos": "0",
        "datatype": "auto",
        "broker": "94fffe91.c7ff7",
        "nl": false,
        "rap": false,
        "rh": "2",
        "inputs": 0,
        "x": 180,
        "y": 540,
        "wires": [
            [
                "0755af5e251b9e89"
            ]
        ]
    },
    {
        "id": "0755af5e251b9e89",
        "type": "function",
        "z": "12ac70ec.f1d30f",
        "name": "Get Climate",
        "func": "var value = msg.payload;\nvar topics = msg.topic;\nvar current_zone = topics.split(\"/\")[3]\nvar zones = flow.get(\"climate_zone.\"+current_zone)\n\nmsg.payload = [];\nfor (let id in zones) {\n    name = zones[id];\n    target = flow.get(\"climate.\"+name+\".target.\"+value);\n    msg.payload.push({\n        \"name\": name,\n        \"target\": target,\n        \"zone\": current_zone,\n        \"preset\": value\n    })     \n}\n\n\nreturn [msg];",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 440,
        "y": 510,
        "wires": [
            [
                "fa713664a70e4bdc"
            ]
        ]
    },
    {
        "id": "fa713664a70e4bdc",
        "type": "split",
        "z": "12ac70ec.f1d30f",
        "name": "",
        "splt": "\\n",
        "spltType": "str",
        "arraySplt": 1,
        "arraySpltType": "len",
        "stream": false,
        "addname": "",
        "x": 580,
        "y": 510,
        "wires": [
            [
                "1fd4657fe9469312"
            ]
        ]
    },
    {
        "id": "1fd4657fe9469312",
        "type": "api-call-service",
        "z": "12ac70ec.f1d30f",
        "name": "Change Preset",
        "server": "7f33d7bb.9361a8",
        "version": 3,
        "debugenabled": false,
        "service_domain": "climate",
        "service": "set_preset_mode",
        "entityId": "climate.{{payload.name}}",
        "data": "{\"preset_mode\":\"{{payload.preset}}\"}",
        "dataType": "json",
        "mergecontext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "x": 810,
        "y": 510,
        "wires": [
            []
        ]
    },
    {
        "id": "bce7ac021be8430a",
        "type": "debug",
        "z": "12ac70ec.f1d30f",
        "name": "out",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 770,
        "y": 610,
        "wires": []
    },
    {
        "id": "2c2abe8fb8b72f29",
        "type": "function",
        "z": "12ac70ec.f1d30f",
        "name": "Check Tags",
        "func": "tags_needed = [\"climate\"]\nvar list_tags = msg.data.new_state.attributes.tags;\n\nvar now = Date.now()\n\nfor (let id_tag_needed in tags_needed) {\n    tag_needed = tags_needed[id_tag_needed];\n    if (list_tags.includes(tag_needed)) {\n        for (let id_tag in list_tags) {\n            tag = list_tags[id_tag];\n            if (tag != tag_needed) {\n                flow.set(\"sheduler.\"+tag+\".\"+msg.topic.replace('switch.',''),now)   \n                // msg.switch = msg.topic;\n                return msg;       \n            }\n        }\n    \n    }\n}",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 440,
        "y": 610,
        "wires": [
            [
                "bce7ac021be8430a"
            ]
        ]
    },
    {
        "id": "3443e4e757652f05",
        "type": "server-state-changed",
        "z": "12ac70ec.f1d30f",
        "name": "",
        "server": "7f33d7bb.9361a8",
        "version": 3,
        "exposeToHomeAssistant": false,
        "haConfig": [
            {
                "property": "name",
                "value": ""
            },
            {
                "property": "icon",
                "value": ""
            }
        ],
        "entityidfilter": "^switch\\.schedule_+",
        "entityidfiltertype": "regex",
        "outputinitially": true,
        "state_type": "str",
        "haltifstate": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "outputs": 1,
        "output_only_on_state_change": false,
        "for": "0",
        "forType": "num",
        "forUnits": "minutes",
        "ignorePrevStateNull": false,
        "ignorePrevStateUnknown": false,
        "ignorePrevStateUnavailable": false,
        "ignoreCurrentStateUnknown": true,
        "ignoreCurrentStateUnavailable": true,
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "data",
                "propertyType": "msg",
                "value": "",
                "valueType": "eventData"
            },
            {
                "property": "topic",
                "propertyType": "msg",
                "value": "",
                "valueType": "triggerId"
            }
        ],
        "x": 170,
        "y": 610,
        "wires": [
            [
                "2c2abe8fb8b72f29"
            ]
        ]
    },
    {
        "id": "4c35911265b9674f",
        "type": "split",
        "z": "12ac70ec.f1d30f",
        "name": "",
        "splt": "\\n",
        "spltType": "str",
        "arraySplt": 1,
        "arraySpltType": "len",
        "stream": false,
        "addname": "",
        "x": 640,
        "y": 350,
        "wires": [
            [
                "b49f301104df4f24"
            ]
        ]
    },
    {
        "id": "180fb7c256f788b6",
        "type": "api-call-service",
        "z": "12ac70ec.f1d30f",
        "name": "Change Switch",
        "server": "7f33d7bb.9361a8",
        "version": 3,
        "debugenabled": true,
        "service_domain": "switch",
        "service": "{{payload.service}}",
        "entityId": "{{payload.topic}}",
        "data": "",
        "dataType": "json",
        "mergecontext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "x": 970,
        "y": 350,
        "wires": [
            []
        ]
    },
    {
        "id": "b49f301104df4f24",
        "type": "delay",
        "z": "12ac70ec.f1d30f",
        "name": "",
        "pauseType": "rate",
        "timeout": "5",
        "timeoutUnits": "seconds",
        "rate": "2",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 790,
        "y": 350,
        "wires": [
            [
                "180fb7c256f788b6"
            ]
        ]
    },
    {
        "id": "7f33d7bb.9361a8",
        "type": "server",
        "name": "Home Assistant",
        "version": 2,
        "addon": false,
        "rejectUnauthorizedCerts": false,
        "ha_boolean": "y|yes|true|on|home|open",
        "connectionDelay": true,
        "cacheJson": true,
        "heartbeat": false,
        "heartbeatInterval": "30"
    },
    {
        "id": "94fffe91.c7ff7",
        "type": "mqtt-broker",
        "name": "Mosquitto",
        "broker": "mosquitto.mosquitto",
        "port": "1883",
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "5",
        "keepalive": "60",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "sessionExpiry": ""
    }
]
8 « J'aime »

WOW!
On peut poser des questions ici même ?
Je n’ai pas encore commencé, toutes les modifications sont dans /config/configuration.yaml ?

Il y a du nodered également

Concernant la partie lovelace, je ne sais pas trop ou le copier… Quand je fais le copier coller sur une carte « manuel » rien ne s’affiche…

edit: j’ai trouvé mon erreur j’avais mis un espace en moins dans le code yaml.

Juste une question du coup, dans la page dédié à la pièce, tu as crée un sensor « night » et un sensor « état » ?

Yep, je passe par un flow nodered qui publie dans MQTT l’état.

Tu te bases sur l’état on/off du radiateur ?

Concernant node-red où dois-je coller le code ?

En tout cas merci beaucoup de ton aide !

Je comprend pas ta question :smiley:

Via l’outils d’importation

Ma question est sur quoi est basé le sensor état ? (Je sais pas si c’est mieux formulé :slightly_smiling_face:

bah c’est juste l’état on/off du radiateur simplement. que je récupère via MQTT (je suis en zwavejs2mqtt)

D’accord merci !

Je viens d’importer le flow node-red voici l’erreur que j’obtiens :

Il te manque juste la palette en question node-red-contrib-string

Je regarde ça demain, merci beaucoup pour tes réponses rapides !

J’ai ajouté la palette sur node-red mais avant d’importer le flow, y’a t’il des variables à changer ou je le copie comme ça ? (j’ai juste changé l’adresse du broker)

Chouette projet !
J’ai moi aussi fait un truc dans le genre mais pas aussi abouti.
Si j’avais su, je me serai inspiré
Encore bravo

Bravo pour ton sujet; quel boitier est branché sur tes chauffages ?

D’accord j’utilise Heatzy pour le moment mais prochainement je voudrait piloter et réguler la température de mes pièces grâce à une sonde de T° et non plus avec le thermostat du chauffage.

Actuellement j’ai une sonde de température dans chaque pièces et un thermostat Home Assistant par pièce.
Du coup je pilote tt les pièces de façon indépendante.