HA – Monitoring de ma PAC Daikin Altherma avec ESPHome (esphome-altherma) : alternative à ESPAltherma

Intro

Comme pour mon article précédent basé sur ESPAltherma, mon objectif reste le même : remonter un maximum d’informations de ma PAC Daikin Altherma dans Home Assistant, sans cloud, avec une solution robuste et maintenable. Cette fois, je bascule sur une approche 100% ESPHome grâce au projet esphome-altherma de jjohnsen, qui “porte” la logique d’ESPAltherma dans un composant externe ESPHome.

En pratique, on obtient :

  • des entités Home Assistant natives via l’API ESPHome (pas besoin de MQTT/autodiscovery),
  • une configuration plus “propre” pour un environnement déjà très ESPHome,
  • une base de code inspirée d’ESPAltherma, mais intégrée à l’écosystème ESPHome.

Pour rappel mon installation est composée d’une unité extérieure Daikin Altherma (référence : ERLQ011CAV3) et d’une unité hydraulique (référence : EHBX11CB9W). Le système assure le chauffage par le sol sur un seul niveau, sans ballon d’eau chaude sanitaire.

Référence utile : mon précédent article “ESPAltherma” reste valable pour la partie “principe” (connexion au port série X10A/S21, précautions, etc.), mais ici je détaille la mise en œuvre avec esphome-altherma.

https://domo.rem81.com/index. hp/2025/06/15/ha-monitoring-et-controle-de-ma-pompe-a-chaleur-daikin-altherma-avec-espaltherma/


La solution retenue : esphome-altherma (jjohnsen)

Le dépôt jjohnsen/esphome-altherma https://github.com/jjohnsen/esphome-altherma fournit :

  • un composant externe ESPHome altherma_hub,
  • des fichiers “modèle” (mapping) par famille de PAC,
  • et même une méthode d’installation via navigateur (ESP Web Tools) pour flasher rapidement un firmware de base.

⚠️ Point important : à l’heure actuelle, le projet indique explicitement qu’un mapping est surtout disponible pour la série ERGA-D / EHV-EHB-EHVZ DA 04–08 kW (et contributions bienvenues pour d’autres modèles).
Dans mon cas, j’utilise un fichier de mapping dédié : pack_esp126/lt_da_04_08kw.yaml .


Matériel nécessaire

Côté matériel

  • 1 × ESP32 (dev board classique type esp32dev)
  • 1 × connecteur JST EH 2.5 mm 5 broches (ou fils Dupont, mais le JST est plus fiable)
  • Accès au connecteur série X10A (ou équivalent selon l’unité / câblage)

Rappel : câblage X10A ↔ ESP32

Le projet reprend le câblage standard popularisé par ESPAltherma :

  • X10A pin 1 (5V)5V/VIN de l’ESP32 (si l’alimentation 5V est suffisante, sinon alimentation USB externe)
  • X10A pin 2 (TX PAC)RX ESP32
  • X10A pin 3 (RX PAC)TX ESP32
  • X10A pin 5 (GND)GND ESP32

Dans ton YAML, tu es sur :

  • TX = GPIO17
  • RX = GPIO16
  • UART 9600 / 8 bits / parité EVEN / 1 stop bit

Ce choix correspond aux recommandations courantes (utiliser RX2/TX2 sur ESP32, souvent GPIO16/17).


Mise en œuvre avec ESPHome

Codes ESPHOME:

Le code principal fait appel à un fichier de configuration.

La version à jour du fichier principal est disponible ici:

https://github.com/remycrochon/home-assistant/blob/master/esphome/esp126-pac.yaml

# https://github.com/jjohnsen/esphome-altherma
substitutions:
  adress_ip: "192.168.0.126"
  device_name: "esp126-pac"
  friendly_name: "esp126-pac"
  time_timezone: "Europe/Paris"

esp32:
  board: esp32dev
  framework:
    type: esp-idf

packages:
  #altherma_sensors: !include pac/erga_eh_da_04_08.yaml
  altherma_sensors: !include pack_esp126/lt_da_04_08kw.yaml

esphome:
  name: ${device_name}
  friendly_name: ${device_name}
  # Automatically add the mac address to the name
  # so you can use a single firmware for all devices
  # name_add_mac_suffix: true
  # Uncomment below for using mock uart during development:
  #platformio_options:
  #  build_flags:
  #    - -DUSE_MOCK_UART


# Enable logging
logger:
  level: DEBUG

# Enable Home Assistant API
api:

ota:
  platform: esphome

web_server:
  port: 80

wifi:
  networks:
    - ssid: !secret wifi_esp
      password: !secret mdpwifi_esp
  reboot_timeout: 5min
  min_auth_mode: WPA2

  manual_ip:
    static_ip: ${adress_ip}
    gateway: 192.168.0.254
    subnet: 255.255.255.0
    dns1: !secret dns1
    dns2: !secret dns2    
    
external_components:
  - source: github://jjohnsen/esphome-altherma@main
    components: [altherma_hub]

#external_components:
#  - source:
#      type: local
#      path: components

uart:
  id: uart_bus
  tx_pin: GPIO17
  rx_pin: GPIO16
  baud_rate: 9600
  data_bits: 8
  parity: EVEN
  stop_bits: 1

altherma_hub:
  id: altherma_hub_1
  uart_id: uart_bus
  update_interval: 30s

binary_sensor:
#Etat de la connection
  - platform: status
    name: "Status"
sensor:
  - platform: homeassistant
    id: pu_pac
    entity_id: sensor.ecocompteur_pac
    internal: true

  - platform: template
    id: temp_dep_calculee
    name: "temp_dep_calculee"
    unit_of_measurement: "°C"
    device_class: temperature
    state_class: measurement
    accuracy_decimals: 2
    update_interval: 30s
    lambda: |-
      // Paramètres (identiques à votre template HA)
      const float p102 = 37.0f;
      const float p103 = 25.0f;
      const float p100 = -10.0f;
      const float p101 = 20.0f;

      // Température extérieure
      float t = id(temp_r1t).state;
      if (isnan(t)) return NAN;

      // Coefficients de la droite
      const float a = (p102 - p103) / (p100 - p101);
      const float b = p103 - a * p101;

      // Clamp + calcul
      if (t <= p100) return p100;
      if (t >= p101) return p101;

      return (a * t) + b;

  - platform: template
    id: cop
    name: "cop"
    unit_of_measurement: ""
    state_class: measurement
    accuracy_decimals: 2
    update_interval: 30s
    lambda: |-
      // Lecture des entrées
      float debit = id(debit_pac).state;            // L/min
      float rt1   = id(temp_r1t).state;         // °C
      float rt4   = id(temp_rt4).state;         // °C
      float i     = id(int_primaire).state; // A
      float pu    = id(pu_pac).state;            // W

      // Garde-fous NaN
      if (isnan(debit) || isnan(rt1) || isnan(rt4) || isnan(i) || isnan(pu)) {
        return NAN;
      }

      // Mode chauffage (text_sensor)
      if (strcmp(id(mode_fonctionnement).state.c_str(), "Heating") != 0) {
        return 0.0f;
      }

      // Courant > 0 obligatoire
      if (i <= 0.0f || pu <= 0.0f) {
        return 0.0f;
      }

      // Calcul COP
      // (debit * 0.06 * 1.16) * (rt1 - rt4) / (pu / 1000)
      float cop = (debit * 0.06f * 1.16f) * (rt1 - rt4) / (pu / 1000.0f);

      // Filtrage identique à HA
      if (cop >= 0.0f && cop < 10.0f) {
        return cop;
      }

      return 0.0f;

Mon fichier de mapping « lt_da_04_08kw.yaml »:

La version à jour du fichier de configuration est disponible ici:

https://github.com/remycrochon/home-assistant/blob/master/esphome/pack_esp126/lt_da_04_08kw.yaml

# =========================================================
# Conversion labeldef.h -> ESPHome (format identique au 1er)
# Plateforme: altherma_hub
# =========================================================

# anchors
.altherma_base: &altherma_base
  platform: altherma_hub
  altherma_hub_id: altherma_hub_1

.temp: &temp
  <<: *altherma_base
  device_class: temperature
  unit_of_measurement: °C
  state_class: measurement
  accuracy_decimals: 1

.binary: &binary
  <<: *altherma_base

.current: &current
  <<: *altherma_base
  device_class: current
  unit_of_measurement: A
  icon: mdi:current-ac
  state_class: measurement
  accuracy_decimals: 1

.voltage: &voltage
  <<: *altherma_base
  device_class: voltage
  unit_of_measurement: V
  state_class: measurement

.rps: &rps
  <<: *altherma_base
  unit_of_measurement: rps
  state_class: measurement

.rpm: &rpm
  <<: *altherma_base
  unit_of_measurement: rpm
  state_class: measurement

.text: &text
  <<: *altherma_base


# =========================
# SENSORS (numériques)
# =========================
sensor:
  # {0x20,0,105,2,1,"Temp. d air extérieur(R1T)"}
  - <<: *temp
    name: "Temp. d air extérieur (R1T)"
    register: 0x20
    offset: 0
    convid: 105
    datasize: 2
    id: temp_r1t

  # {0x20,10,105,2,1,"Temp. tuyau de liquide (R6T)"}
  - <<: *temp
    name: "Temp. tuyau de liquide (R6T)"
    register: 0x20
    offset: 10
    convid: 105
    datasize: 2

  # {0x20,12,105,2,1,"Temp. de dissipateur de chaleur"}
  - <<: *temp
    name: "Temp. de dissipateur de chaleur"
    register: 0x20
    offset: 12
    convid: 105
    datasize: 2

  # {0x20,14,105,2,2,"Capteur de pression"}
  - <<: *altherma_base
    name: "Capteur de pression"
    register: 0x20
    offset: 14
    convid: 105
    datasize: 2
    device_class: pressure
    unit_of_measurement: bar
    state_class: measurement
    accuracy_decimals: 2

  # {0x21,0,105,2,-1,"Courant primaire INV (A)"}
  - <<: *current
    name: "Courant primaire INV (A)"
    register: 0x21
    offset: 0
    convid: 105
    datasize: 2
    id: int_primaire

  # {0x21,2,105,2,-1,"Courant secondaire INV (A)"}
  - <<: *current
    name: "Courant secondaire INV (A)"
    register: 0x21
    offset: 2
    convid: 105
    datasize: 2

  # {0x30,0,152,1,-1,"Fréquence INV (rps)"}
  - <<: *rps
    name: "Fréquence INV (rps)"
    register: 0x30
    offset: 0
    convid: 152
    datasize: 1

  # {0x30,1,152,1,-1,"Fréquence INV 2 (rps)"}
  - <<: *rps
    name: "Fréquence INV 2 (rps)"
    register: 0x30
    offset: 1
    convid: 152
    datasize: 1

  # {0x30,0,211,1,-1,"Ventilateur 1 (10 rpm)"}
  - <<: *rpm
    name: "Ventilateur 1 (rpm)"
    register: 0x30
    offset: 0
    convid: 211
    datasize: 1
    filters:
      - multiply: 10

  # {0x30,1,211,1,-1,"Ventilateur 2 (palier)"}
  - <<: *rpm
    name: "Ventilateur 2 (palier)"
    register: 0x30
    offset: 1
    convid: 211
    datasize: 1

  # {0x60,9,105,2,1,"Consigne LW (principal)"}
  - <<: *temp
    name: "Consigne LW (principal)"
    register: 0x60
    offset: 9
    convid: 105
    datasize: 2

  # {0x61,2,105,2,1,"Laisser temp. eau avant BUH (R1T)"}
  - <<: *temp
    name: "Leaving water temp. avant BUH (R1T)"
    register: 0x61
    offset: 2
    convid: 105
    datasize: 2

  # {0x61,4,105,2,1,"Laisser temp. eau après BUH (R2T)"}
  - <<: *temp
    name: "Leaving water temp. après BUH (R2T)"
    register: 0x61
    offset: 4
    convid: 105
    datasize: 2
    
  # {0x61,6,105,2,1,"Temp. réfrig. côté liquide (R3T)"}
  - <<: *temp
    name: "Temp. réfrig. côté liquide (R3T)"
    register: 0x61
    offset: 6
    convid: 105
    datasize: 2

  # {0x61,8,105,2,1,"Temp. d eau d entrée (R4T)"}
  - <<: *temp
    name: "Temp. d eau d entrée (R4T)"
    register: 0x61
    offset: 8
    convid: 105
    datasize: 2
    id: temp_rt4
    
  # {0x61,12,105,2,1,"Temp. ambiante intérieure (R1T)"}
  - <<: *temp
    name: "Temp. ambiante intérieure (R1T)"
    register: 0x61
    offset: 12
    convid: 105
    datasize: 2
    
  # {0x61,14,105,2,1,"Capteur ext. de temp. ambiante intérieure (R6T)"}
  - <<: *temp
    name: "Capteur ext. temp. ambiante intérieure (R6T)"
    register: 0x61
    offset: 14
    convid: 105
    datasize: 2
    
  # {0x62,5,105,2,1,"Consigne Thermostat int"}
  - <<: *temp
    name: "Consigne Thermostat int"
    register: 0x62
    offset: 5
    convid: 105
    datasize: 2

  # {0x62,9,105,2,-1,"Capteur de débit (l/min)"}
  - <<: *altherma_base
    name: "Capteur de débit (l/min)"
    register: 0x62
    offset: 9
    convid: 105
    datasize: 2
    unit_of_measurement: l/min
    state_class: measurement
    accuracy_decimals: 1
    id: debit

  # {0x62,11,105,1,2,"Pression d eau"}
  - <<: *altherma_base
    name: "Pression d eau"
    register: 0x62
    offset: 11
    convid: 105
    datasize: 1
    device_class: pressure
    unit_of_measurement: bar
    state_class: measurement
    accuracy_decimals: 2

  # {0x62,12,152,1,-1,"Signal de pompe à eau (0:max-100:arrêt)"}
  - <<: *altherma_base
    name: "Signal pompe à eau (0-100)"
    register: 0x62
    offset: 12
    convid: 152
    datasize: 1
    state_class: measurement
    accuracy_decimals: 0
    filters:
      - lambda: return x -100;


# =========================
# BINARY SENSORS (ON/OFF)
# =========================
binary_sensor:
  # {0x10,1,304,1,-1,"Dégivrage"}
  - <<: *binary
    name: "Dégivrage"
    register: 0x10
    offset: 1
    convid: 304
    datasize: 1
    device_class: running

  # {0x10,1,307,1,-1,"Thermostat ON/OFF Ext"}
  #- <<: *binary
  #  name: "Thermostat ON/OFF Ext"
  #  register: 0x10
  #  offset: 1
  #  convid: 307
  #  datasize: 1
  #  device_class: running

  # {0x60,2,303,1,-1,"Thermostat ON/OFF Int"}
  - <<: *binary
    name: "Thermostat ON/OFF Int"
    register: 0x60
    offset: 2
    convid: 303
    datasize: 1
    device_class: running

  # {0x60,2,302,1,-1,"Protection antigel"}
  - <<: *binary
    name: "Protection antigel"
    register: 0x60
    offset: 2
    convid: 302
    datasize: 1
    device_class: cold

  # {0x60,12,304,1,-1,"Palier1 BUH"}
  - <<: *binary
    name: "Palier1 BUH"
    register: 0x60
    offset: 12
    convid: 304
    datasize: 1

  # {0x60,12,303,1,-1,"Palier2 BUH"}
  - <<: *binary
    name: "Palier2 BUH"
    register: 0x60
    offset: 12
    convid: 303
    datasize: 1

  # {0x62,8,302,1,-1,"Fonctionnement de pompe de circulation"}
  - <<: *binary
    name: "Pompe de circulation (ON/OFF)"
    register: 0x62
    offset: 8
    convid: 302
    datasize: 1
    device_class: running

# =========================
# TEXT SENSORS (états / codes)
# =========================
text_sensor:
  # {0x10,0,217,1,-1,"Mode de fonctionnement"}
  - <<: *text
    name: "Mode de fonctionnement"
    icon: mdi:state-machine
    register: 0x10
    offset: 0
    convid: 217
    datasize: 1
    id: mode_fonctionnement

  # {0x10,4,203,1,-1,"Type de dysfonctionnement"}
  - <<: *text
    name: "Type de dysfonctionnement"
    register: 0x10
    offset: 4
    convid: 203
    datasize: 1
    entity_category: diagnostic

  # {0x10,5,204,1,-1,"Code de dysfonctionnement"}
  - <<: *text
    name: "Code de dysfonctionnement"
    register: 0x10
    offset: 5
    convid: 204
    datasize: 1
    entity_category: diagnostic

  # {0x60,3,204,1,-1,"Code de dysfonctionnement"}
  - <<: *text
    name: "Code de dysfonctionnement (IU)"
    register: 0x60
    offset: 3
    convid: 204
    datasize: 1
    entity_category: diagnostic

  # {0x60,4,152,1,-1,"Code d erreur détaillé"}
  - <<: *text
    name: "Code d erreur détaillé"
    register: 0x60
    offset: 4
    convid: 152
    datasize: 1
    entity_category: diagnostic

  # {0x60,5,203,1,-1,"Type de dysfonctionnement"}
  - <<: *text
    name: "Type de dysfonctionnement (IU)"
    register: 0x60
    offset: 5
    convid: 203
    datasize: 1
    entity_category: diagnostic

Avantages de cette approche

  • ESP-IDF : très stable sur ESP32, particulièrement quand on a des projets “série” un peu sensibles.
  • update_interval: 30s : bon compromis (et facile à ajuster).
  • logger: DEBUG : indispensable pour valider la communication UART au début.

Installation : 2 méthodes possibles

Option A – Flash “facile” via navigateur (ESP Web Tools)

Le dépôt propose une installation via ESP Web Tools : on connecte l’ESP32 en USB, on flashe depuis le navigateur, puis on configure le Wi-Fi, et Home Assistant découvre le device.
C’est pratique pour valider rapidement un premier flash “fonctionnel”.

Option B – Méthode “propre” (celle que tu utilises) : ESPHome + external_components

C’est ce que fait ton YAML : tu déclares external_components en pointant sur github://jjohnsen/esphome-altherma@main.
Avantage : tu restes dans ton pipeline ESPHome habituel (packages, secrets, IP fixe, etc.).


Zoom sur le calcul du COP

Le Coefficient de Performance (COP) est un indicateur clé pour mesurer l’efficacité de ma PAC : il représente le rapport entre l’énergie thermique produite (en kWh) et l’énergie électrique consommée (en kWh). Un COP élevé signifie une PAC performante.

Dans mon fichier pac.yaml, j’ai implémenté un capteur qui calcule le COP en temps réel. Voici comment cela fonctionne :

  1. Données utilisées :
  • Débit d’eau : mesuré par la PAC.
  • Température de l’eau départ : température de l’eau sortant de l’échangeur.
  • Température de l’eau retour : température de l’eau revenant dans la PAC.
  • Puissance électrique : mesurée via un compteur externe (Linky ou équivalent).
  • Mode de fonctionnement : pour s’assurer que la PAC est en mode chauffage.
  1. Formule :
    La formule utilisée est basée sur la chaleur produite par l’eau chauffée :
  • 0.06 convertit le débit de l/min en m³/h.
  • 1.16 est la chaleur spécifique de l’eau (kWh/m³·°C).
  • La puissance consommée est divisée par 1000 pour passer de W à kWh.
  1. Garde-fous :
  • Le calcul n’est effectué que si la PAC est en mode « Heating » et que le courant primaire est supérieur à 0 (pour éviter des valeurs aberrantes).
  • Si le COP calculé est négatif ou supérieur à 10 (peu réaliste), il est ramené à 0 pour garantir la fiabilité des données.
  1. Utilisation :
    Ce capteur me permet de suivre l’efficacité de ma PAC en temps réel. Par exemple, un COP de 4 signifie que pour 1 kWh d’électricité consommée, la PAC produit 4 kWh de chaleur. En analysant ces données, j’ai pu ajuster les consignes de température pour maximiser le COP, surtout par temps doux.

Zoom sur le calcul de la température de départ:

Calcul de la température de départ selon la loi d’eau

Ma PAC Daikin Altherma utilise une loi d’eau pour réguler la température de départ de l’eau (T° Dpt R2T) en fonction de la température extérieure (T° Ext R6T). La loi d’eau est une relation linéaire qui ajuste la température de départ pour maintenir un confort intérieur tout en optimisant l’efficacité énergétique. Pour vérifier et comprendre cette température de départ calculée par la PAC, j’ai implémenté un capteur dans Home Assistant : espaltherma_temp_dep_calculee.

Principe de la loi d’eau

La loi d’eau est définie par une relation linéaire entre la température extérieure ((T_{ext})) et la température de départ ((T_{dep})) :

Calcul de la pente et de l’ordonnée

Limites et application

Intégration dans Home Assistant

Une fois flashé et connecté au Wi-Fi :

  1. Home Assistant découvre l’ESP via l’intégration ESPHome (API native).
  2. Les entités exposées dépendent directement de ton fichier lt_da_04_08kw.yaml (capteurs, nombres, selects…).

En termes d’usage, tu obtiens généralement :

  • températures (départ/retour, ECS si présent, ext…),
  • états / modes,
  • informations de fonctionnement (compresseur, cycles, etc. selon mapping),
  • potentiellement courants/tensions/mesures internes selon ce que le mapping expose.

Tableau de Bord:

aspect_ratio: 50%
elements:
  - entity: sensor.esp126_pac_mode_de_fonctionnement
    prefix: "Fct= "
    style:
      background: "#000000"
      color: white
      font-size: 110%
      left: 1%
      top: 5%
      transform: none
    type: state-label
  - entity: binary_sensor.esp126_pac_thermostat_on_off_int
    prefix: "Th Int= "
    style:
      background: "#000000"
      color: white
      font-size: 110%
      left: 1%
      top: 10%
      transform: none
    type: state-label
  - entity: sensor.ecocompteur_pac
    prefix: "P= "
    style:
      background: "#000000"
      color: white
      font-size: 110%
      left: 1%
      top: 40%
      transform: none
    type: state-label
  - entity: sensor.compteur_energie_pac_jour_hp_hc
    prefix: "EJ= "
    style:
      background: "#000000"
      color: white
      font-size: 110%
      left: 1%
      top: 60%
      transform: none
    type: state-label
  - entity: sensor.esp126_pac_leaving_water_temp_apres_buh_r2t
    prefix: "T°Dpt R2T= "
    style:
      background: "#000000"
      color: white
      font-size: 110%
      left: 1%
      top: 23%
      transform: none
    type: state-label
  - entity: sensor.esp126_pac_temp_dep_calculee
    prefix: "T°Dpt Calculée= "
    style:
      background: "#000000"
      color: white
      font-size: 110%
      left: 1%
      top: 33%
      transform: none
    type: state-label
  - entity: binary_sensor.esp126_pac_palier1_buh
    prefix: "Resist. 1= "
    style:
      background: "#000000"
      color: white
      font-size: 110%
      left: 50%
      top: 10%
    type: state-label
  - entity: binary_sensor.esp126_pac_palier2_buh
    prefix: "Resist. 2= "
    style:
      background: "#000000"
      color: white
      font-size: 110%
      left: 50%
      top: 15%
    type: state-label
  - entity: sensor.esp126_pac_leaving_water_temp_avant_buh_r1t
    prefix: "T°Avant BUH= "
    style:
      background: "#000000"
      color: white
      font-size: 110%
      left: 57%
      top: 30%
    type: state-label
  - entity: sensor.esp126_pac_signal_pompe_a_eau_0_100
    prefix: "Circ= "
    style:
      background: "#000000"
      color: white
      font-size: 110%
      left: 62%
      top: 85%
    type: state-label
  - entity: sensor.esp126_pac_capteur_de_debit_l_min
    prefix: "Débit= "
    style:
      background: "#000000"
      color: white
      font-size: 110%
      left: 68.5%
      top: 25%
    type: state-label
  - entity: sensor.esp126_pac_temp_d_eau_d_entree_r4t
    prefix: "T° Retour R4T= "
    style:
      background: "#000000"
      color: white
      font-size: 110%
      left: 1%
      top: 75%
      transform: none
    type: state-label
  - entity: sensor.esp126_pac_temp_refrig_cote_liquide_r3t
    prefix: "T°R3T= "
    style:
      background: "#000000"
      color: white
      font-size: 110%
      left: 80%
      top: 78%
      transform: none
    type: state-label
  - entity: sensor.esp126_pac_consigne_thermostat_int
    prefix: "T°Cons= "
    style:
      background: "#000000"
      color: yellow
      font-size: 110%
      left: 25%
      top: 40%
      transform: none
    type: state-label
  - entity: sensor.esp126_pac_temp_ambiante_interieure_r1t
    prefix: "T°Int= "
    style:
      background: "#000000"
      color: white
      font-size: 110%
      left: 25%
      top: 45%
      transform: none
    type: state-label
  - entity: sensor.esp126_pac_temp_d_air_exterieur_r1t
    prefix: "T°Ext R1T= "
    style:
      background: "#000000"
      color: white
      font-size: 110%
      left: 80%
      top: 8%
      transform: none
    type: state-label
  - entity: sensor.esp126_pac_temp_tuyau_de_liquide_r6t
    prefix: "T°R6T= "
    style:
      background: "#000000"
      color: white
      font-size: 110%
      left: 80%
      top: 15%
      transform: none
    type: state-label
  - entity: sensor.esp126_pac_ventilateur_1_rpm
    prefix: "Vent1= "
    style:
      background: "#000000"
      color: white
      font-size: 110%
      left: 80%
      top: 40%
      transform: none
    type: state-label
  - entity: sensor.esp126_pac_ventilateur_2_palier
    prefix: "Vent2= "
    style:
      background: "#000000"
      color: white
      font-size: 110%
      left: 80%
      top: 50%
      transform: none
    type: state-label
  - entity: binary_sensor.esp126_pac_degivrage
    prefix: "Degivrage= "
    style:
      background: "#000000"
      color: white
      font-size: 110%
      left: 80%
      top: 60%
      transform: none
    type: state-label
  - entity: sensor.esp126_pac_cop
    prefix: "COP= "
    style:
      background: "#000000"
      color: white
      font-size: 110%
      left: 25%
      top: 60%
      transform: none
    type: state-label
  - entity: sensor.esp126_pac_courant_primaire_inv_a
    prefix: "I= "
    style:
      background: "#000000"
      color: white
      font-size: 110%
      left: 10%
      top: 40%
      transform: none
    type: state-label
  - entity: sensor.esp126_pac_pression_d_eau
    prefix: "P= "
    style:
      background: "#000000"
      color: white
      font-size: 110%
      left: 59%
      top: 67%
    type: state-label
  - entity: binary_sensor.esp126_pac_status
    prefix: "Status= "
    style:
      background: "#000000"
      color: white
      font-size: 110%
      left: 1%
      top: 90%
      transform: none
    type: state-label
image: /local/images/pac5.png
type: picture-elements

Dépannage (les 3 points qui font gagner du temps)

1) Rien ne remonte : vérifier le câblage et la masse

Le point critique : GND commun entre la PAC et l’ESP32. Même si tu alimentes l’ESP en USB, il faut garder le GND lié au GND du X10A.

2) UART : bon port / bons paramètres

Ton UART est cohérent avec la doc (9600, 8E1, TX17/RX16).
Si tu vois des trames incohérentes, la parité est un suspect classique : certains retours de communauté mentionnent des variations (8N1/8O1) selon modèles/implémentations, mais dans le cadre Altherma/ESPAltherma on est très souvent en EVEN.

3) Trop d’entités / polling trop fréquent

Si ton mapping expose énormément de points, monte l’intervalle (60s par exemple) le temps de stabiliser, puis réduis ensuite.


Conclusion

Avec esphome-altherma, tu gardes l’approche “DIY série sur X10A”, mais tu passes sur une intégration native ESPHome → Home Assistant, ce qui est particulièrement cohérent quand ton infra est déjà centrée sur ESPHome (packages, OTA, API, logs, secrets…).

Laisser un commentaire

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