Un E1002 de openELAB pour afficher un dashboard Home Assistant

maxresdefault

Créer un affichage Home Assistant autonome sur un écran à encre électronique

L’affichage continu d’un tableau de bord domotique implique généralement l’utilisation d’une tablette tactile allumée en permanence, ce qui consomme de l’énergie et nécessite un branchement secteur constant. Dans cet article, nous allons apprendre à exploiter un écran à encre électronique (e-ink) de manière totalement autonome pour afficher les données de votre domotique. En utilisant une méthode de rendu par capture d’écran automatisée, vous découvrirez comment allier supervision, esthétique et très faible consommation énergétique.

🛠️ Configurer Home Assistant : Utilisateur et Tableau de bord

On commence par la base. L’idée, c’est de ne pas s’embêter à coder l’interface visuelle directement dans le microcontrôleur de l’écran (c’est très long et la moindre modification devient un enfer). On va plutôt utiliser l’interface graphique de Home Assistant, et notre système ira la photographier tout seul. On va y aller étape par étape, c’est pas sorcier.

  1. Allez dans les paramètres de Home Assistant, puis dans Personnes.
  2. Créez un nouvel utilisateur spécifique (appelez-le eink par exemple).
  3. Dans l’onglet sécurité de cet utilisateur, générez un Jeton d’accès longue durée (token). Copiez ce code dans un coin de votre ordinateur, on va s’en servir juste après.
  4. Créez ensuite un nouveau tableau de bord (dashboard) dédié à ce que vous souhaitez afficher sur l’écran.
Petite astuce : Si votre écran gère 6 couleurs, limitez-vous à ces teintes franches (noir, blanc, rouge, bleu, vert, jaune) dans votre design. Vous éviterez les effets de tramage un peu baveux et le contraste sera net !

🐳 Déployer l’outil de capture avec Docker

C’est là qu’on fait un peu de magie. On va utiliser un petit conteneur Docker appelé ha-puppet (hass-screenshot). Son seul boulot ? Se connecter à votre Home Assistant en arrière-plan, prendre une photo du tableau de bord que vous venez de créer, et la servir sur une page web pour votre écran. C’est moins compliqué qu’il n’y paraît.

Voici le bloc de configuration à ajouter à votre fichier docker-compose.yml :

YAML
 
  hass-screenshot:
    container_name: ha-puppet
    image: balloob_ha_puppet
    build:
      context: https://github.com/balloob/home-assistant-addons.git#main:puppet
    pull_policy: never
    restart: always
    ports:
      - "10000:10000"
    environment:
      - TZ=Europe/Paris
    volumes:
      - /srv/dev-disk-by-uuid-6e4d03aa-5335-4581-9aae-edd258c3dc46/config/puppet/puppet_config.json:/data/options.json:ro
    deploy:
      resources:
        limits:
          memory: 1G
Attention : Avant de lancer le conteneur, n’oubliez pas de créer le fichier puppet_config.json dans votre dossier /srv/.../config/puppet/ et d’y coller le fameux jeton (token) de l’étape précédente. Démarrez tout ça, et boum, votre outil de capture est opérationnel sur le port 10000.

🚀 Flasher le microcontrôleur avec ESPHome

Maintenant que notre belle image est générée en réseau, il faut dire à notre écran (dans ce cas, un Seeed reTerminal E1002) d’aller la chercher. Pour ça, on utilise ESPHome. Pas de panique si vous n’avez jamais codé en C++, le fichier YAML fait absolument tout le travail à votre place.

Le principe est super simple : l’écran se réveille, allume le Wi-Fi, télécharge l’image générée par Puppet, rafraîchit l’affichage, puis repart hiberner (deep sleep) pendant 5 minutes pour économiser la batterie.

Créez un nouveau projet dans ESPHome, et collez-y ce code tout prêt (pensez juste à vérifier vos identifiants Wi-Fi) :

YAML
 
esphome:
  name: reterminal-e1002
  friendly_name: reTerminal E1002
  on_boot:
    - priority: 600
      then:
        - output.turn_on: bsp_battery_enable
        - delay: 200ms
        - component.update: battery_voltage
        - component.update: battery_level
        - component.update: sht4x_hub
    - then:
        - wait_until:
            condition:
              wifi.connected:
            timeout: 90s
        - component.update: dashboard_image

esp32:
  board: esp32-s3-devkitc-1
  framework:
    type: esp-idf

# UART0 et non USB_SERIAL_JTAG : sur le reTerminal E1002, l'I2C (capteur SHT4x
# interne) est câblé sur GPIO19/20, les mêmes broches que l'USB natif de
# l'ESP32-S3. Les deux ne peuvent pas fonctionner en même temps : la config
# officielle Seeed pour ce modèle utilise UART0 pour cette raison.
logger:
  hardware_uart: UART0

api:

ota:
  - platform: esphome

wifi:
  ssid: "Prof"
  password: "test8000"

deep_sleep:
  id: sommeil
  run_duration: 6min
  sleep_duration: 5min
  wakeup_pin:
    number: GPIO3
    inverted: true
    mode:
      input: true
      pullup: true

psram:
  mode: octal
  speed: 80MHz

http_request:
  verify_ssl: false
  timeout: 20s
  watchdog_timeout: 25s

spi:
  clk_pin: GPIO7
  mosi_pin: GPIO9

i2c:
  scl: GPIO20
  sda: GPIO19

output:
  - platform: gpio
    pin: GPIO21
    id: bsp_battery_enable

font:
  - file: "gfonts://Inter@700"
    id: small_font
    size: 24

sensor:
  - platform: sht4x
    id: sht4x_hub
    temperature:
      name: "Temperature"
      id: temp_sensor
    humidity:
      name: "Humidite"
      id: hum_sensor
  - platform: adc
    pin: GPIO1
    name: "Battery Voltage"
    id: battery_voltage
    update_interval: 60s
    attenuation: 12db
    filters:
      - multiply: 2.0
  - platform: template
    name: "Battery Level"
    id: battery_level
    unit_of_measurement: "%"
    icon: "mdi:battery"
    device_class: battery
    lambda: 'return id(battery_voltage).state;'
    update_interval: 60s
    filters:
      - calibrate_linear:
          - 4.15 -> 100.0
          - 3.96 -> 90.0
          - 3.91 -> 80.0
          - 3.85 -> 70.0
          - 3.80 -> 60.0
          - 3.75 -> 50.0
          - 3.68 -> 40.0
          - 3.58 -> 30.0
          - 3.49 -> 20.0
          - 3.41 -> 10.0
          - 3.30 -> 5.0
          - 3.27 -> 0.0
      - clamp:
          min_value: 0
          max_value: 100

image:
  - platform: online_image
    id: dashboard_image
    format: PNG
    type: RGB565
    buffer_size: 65536
    url: "http://176.189.153.211:10000/dashboard-elink?device=seeed-reterminal-e1002&dithering=none&lang=fr"
    # Essentiel : empêche le re-téléchargement pendant que l'écran se dessine
    update_interval: never 
    on_download_finished:
      - component.update: epaper_display
      - delay: 40s
      - deep_sleep.enter: sommeil

display:
  - platform: epaper_spi
    id: epaper_display
    model: Seeed-reTerminal-E1002
    # "never" : on ne rafraîchit l'écran que sur commande explicite (ci-dessus,
    # au retour du téléchargement de l'image). Un e-paper couleur met jusqu'à
    # ~30s à se rafraîchir : inutile de le déclencher aussi toutes les 30s.
    update_interval: never
    lambda: |-
      it.image(0, 0, id(dashboard_image));
      const auto WHITE = Color(255, 255, 255, 0);
      const auto RED = Color(255, 0, 0, 0);
      if (id(temp_sensor).has_state() && id(battery_level).has_state()) {
        it.printf(450, 440, id(small_font), RED, TextAlign::TOP_RIGHT,
                  "%.1f°C  %.0f%%", id(temp_sensor).state, id(battery_level).state);
      }
Compilez et flashez. C’est normal de voir l’écran clignoter plusieurs fois au redémarrage, c’est le fonctionnement classique de l’encre électronique couleur.

En externalisant le rendu graphique vers Home Assistant par le biais de Docker, cette méthode offre une flexibilité totale tout en préservant l’autonomie de la batterie. Vous pouvez désormais modifier entièrement le design, les couleurs et les entités de votre interface domotique sans jamais avoir besoin de reconnecter ou de reflasher votre écran e-ink.
Retour en haut