{"id":3552,"date":"2025-02-01T20:54:08","date_gmt":"2025-02-01T19:54:08","guid":{"rendered":"https:\/\/domo.rem81.com\/?p=3552"},"modified":"2025-04-13T09:39:46","modified_gmt":"2025-04-13T07:39:46","slug":"ha-afficher-les-couleurs-de-loffre-tempo-dedf-avec-esphome","status":"publish","type":"post","link":"https:\/\/domo.rem81.com\/index.php\/2025\/02\/01\/ha-afficher-les-couleurs-de-loffre-tempo-dedf-avec-esphome\/","title":{"rendered":"HA-Afficher les couleurs de l\u2019offre Tempo d\u2019EDF avec ESPHome"},"content":{"rendered":"\n\n\n\n<h1 class=\"wp-block-heading\">Intro<\/h1>\n\n\n\n<p>Dans cet article, je vous pr\u00e9sente un projet qui me tient \u00e0 c\u0153ur : un affichage visuel des couleurs de l\u2019offre Tempo d\u2019EDF (pour le jour actuel et le lendemain) \u00e0 l\u2019aide d\u2019un ESP8266 (Wemos D1 Mini), d\u2019une bande LED RGB WS2812, et d\u2019ESPHome. Ce syst\u00e8me me permet de savoir d\u2019un coup d\u2019\u0153il si la journ\u00e9e est en tarif Bleu, Blanc ou Rouge, et d\u2019anticiper celle du lendemain. Les donn\u00e9es sont r\u00e9cup\u00e9r\u00e9es depuis Home Assistant et affich\u00e9es via des LED color\u00e9es. Voici comment j\u2019ai r\u00e9alis\u00e9 ce projet, avec le code complet et des explications pour vous inspirer !<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Pourquoi ce projet ?<\/h1>\n\n\n\n<p>L\u2019offre Tempo d\u2019EDF propose des tarifs variables selon les jours : Bleu (tarif avantageux), Blanc (interm\u00e9diaire), ou Rouge (plus cher). Conna\u00eetre la couleur du jour et celle du lendemain est essentiel pour optimiser ma consommation \u00e9lectrique, par exemple en d\u00e9calant l\u2019utilisation d\u2019appareils \u00e9nergivores. Plut\u00f4t que de v\u00e9rifier manuellement sur Home Assistant, j\u2019ai voulu un affichage visuel simple et intuitif gr\u00e2ce \u00e0 une bande LED RGB. Ce projet allie domotique, programmation, et un c\u00f4t\u00e9 pratique au quotidien !<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Le mat\u00e9riel utilis\u00e9<\/h1>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>ESP8266 Wemos D1 Mini<\/strong> : Une carte compacte et \u00e9conomique, id\u00e9ale pour les projets IoT.<\/li>\n\n\n\n<li><strong>Bande LED RGB WS2812<\/strong> : J\u2019utilise 8 LED (mais seules 5 sont actives dans ce projet : 3 pour le jour actuel, 2 pour le lendemain).<\/li>\n\n\n\n<li><strong>Quelques c\u00e2bles<\/strong> pour connecter la bande LED \u00e0 la carte.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"768\" height=\"1024\" data-id=\"3560\" src=\"https:\/\/domo.rem81.com\/wp-content\/uploads\/2025\/04\/IMG_0645-768x1024.jpeg\" alt=\"\" class=\"wp-image-3560\" srcset=\"https:\/\/domo.rem81.com\/wp-content\/uploads\/2025\/04\/IMG_0645-768x1024.jpeg 768w, https:\/\/domo.rem81.com\/wp-content\/uploads\/2025\/04\/IMG_0645-225x300.jpeg 225w, https:\/\/domo.rem81.com\/wp-content\/uploads\/2025\/04\/IMG_0645-1152x1536.jpeg 1152w, https:\/\/domo.rem81.com\/wp-content\/uploads\/2025\/04\/IMG_0645.jpeg 1536w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"383\" height=\"199\" data-id=\"3558\" src=\"https:\/\/domo.rem81.com\/wp-content\/uploads\/2025\/04\/image-1.png\" alt=\"\" class=\"wp-image-3558\" srcset=\"https:\/\/domo.rem81.com\/wp-content\/uploads\/2025\/04\/image-1.png 383w, https:\/\/domo.rem81.com\/wp-content\/uploads\/2025\/04\/image-1-300x156.png 300w\" sizes=\"auto, (max-width: 383px) 100vw, 383px\" \/><\/figure>\n<\/figure>\n\n\n\n<h1 class=\"wp-block-heading\">Le code ESPHome<\/h1>\n\n\n\n<p>Voici le programme complet que j\u2019ai utilis\u00e9 pour configurer mon ESP8266 avec ESPHome. Ce code r\u00e9cup\u00e8re les donn\u00e9es Tempo depuis Home Assistant et contr\u00f4le les LED en fonction des couleurs.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>substitutions:\n  device_name: esp141-affichage-pv\n  adress_ip: \"192.168.0.141\"\n  friendly_name: esp141\n  time_timezone: \"Europe\/Paris\"\n  \nesphome:\n  name: ${device_name}\n  project:\n    name: \"rem81.Affichage_Pv\"\n    version: \"1.0.0\"\n  platformio_options:\n    lib_deps: NeoPixelBus@2.6.0\n  on_boot:\n    then:\n      - light.control:\n          id: rgb_led\n          brightness: 0.25\n          state: on  \n\nesp8266:\n  board: d1_mini\n  framework:\n    version: recommended\n\n\nwifi:\n  networks:\n    - ssid: !secret wifi_esp\n      password: !secret mdpwifi_esp\n      priority: 1\n      \n    - ssid: !secret wifi\n      password: !secret mdpwifi\n      priority: 0\n      \n  reboot_timeout: 5min\n  #use_address: ${device_name}\n  \n  manual_ip:\n    static_ip: ${adress_ip}\n    gateway: 192.168.0.254\n    subnet: 255.255.255.0\n\nlogger:\napi:\nota:\n    platform: esphome\nweb_server:\n  port: 80\n\ntime:\n  - platform: homeassistant\n    timezone:  ${time_timezone} \n\n# Led WS2812 RGB  \nlight:\n\n  - platform: neopixelbus\n    method:\n      type: esp8266_dma\n    num_leds: 8 #1\n    pin: GPIO3\n    name: \"RGB strip\"\n    variant: ws2812\n    id: rgb_led\nglobals:\n  # Niveau intensit\u00e9 lumineuse\n   - id: intlum\n     type: float\n     restore_value: no\n     initial_value: '10'\n  # Niveau intensit\u00e9 lumineuse\n   - id: intlum1\n     type: float\n     restore_value: no\n     initial_value: '0.25'\n#Etat de la connection\nbinary_sensor:\n  - platform: gpio\n    pin:\n      number: GPIO16\n      inverted: True\n    name: bp_raz\n\n  - platform: status\n    name: \"${friendly_name} Status\"\n\ntext_sensor:\n  - platform: homeassistant\n    name: \"Tempo Jour\"\n    entity_id: sensor.rte_tempo_couleur_actuelle\n    id: tempo_jour\n\n  - platform: homeassistant\n    name: \"Tempo j+1\"\n    entity_id: sensor.rte_tempo_prochaine_couleur\n    id: tempo_jour1\n\nswitch:\n  - platform: restart\n    name: \"${friendly_name} Restart\" \n\ninterval:\n  - interval: 1s\n    then:\n      - script.execute: calcul_led_jour\n      - script.execute: calcul_led_jour1\n\n# ------------------------  Scripts\nscript:\n# \n# Couleur du Jour en cours\n# Si indisponible alors Led Eteinte\n  - id: calcul_led_jour\n    mode: single\n    then:\n      - if:\n          condition:\n            and:\n              - lambda: |-\n                  return strcmp(id(tempo_jour).state.c_str(),\"Bleu\") != 0;\n              - lambda: |-\n                  return strcmp(id(tempo_jour).state.c_str(),\"Blanc\") != 0;\n              - lambda: |-\n                  return strcmp(id(tempo_jour).state.c_str(),\"Rouge\") != 0;\n          then:\n            - light.addressable_set:\n                  id: rgb_led\n                  range_from: 0\n                  range_to: 1\n                  red: 0%\n                  green: 0%\n                  blue: 0%\n\n            - light.addressable_set:\n                  id: rgb_led\n                  range_from: 2\n                  range_to: 4\n                  red: 0%\n                  green: 0%\n                  blue: 0%          \n      - if: \n          condition:\n            - lambda: |-\n                return strcmp(id(tempo_jour).state.c_str(),\"Bleu\") == 0;\n          then:\n            - light.addressable_set:\n                  id: rgb_led\n                  range_from: 0\n                  range_to: 1\n                  red: 0%\n                  green: 0%\n                  blue: !lambda |-\n                    return id(intlum1);\n\n            - light.addressable_set:\n                  id: rgb_led\n                  range_from: 2\n                  range_to: 4\n                  red: 0%\n                  green: 0%\n                  blue: 0%\n\n      - if: \n          condition:\n            - lambda: |-\n                return strcmp(id(tempo_jour).state.c_str(),\"Blanc\") == 0;\n          then:\n            - light.addressable_set:\n                  id: rgb_led\n                  range_from: 0\n                  range_to: 1\n                  red: !lambda |-\n                    return id(intlum1);\n                  green: !lambda |-\n                    return id(intlum1);\n                  blue: !lambda |-\n                    return id(intlum1);\n                  \n            - light.addressable_set:\n                  id: rgb_led\n                  range_from: 2\n                  range_to: 4\n                  red: 0%\n                  green: 0%\n                  blue: 0%\n\n          \n      - if: \n          condition:\n            - lambda: |-\n                return strcmp(id(tempo_jour).state.c_str(),\"Rouge\") == 0;\n          then:\n            - light.addressable_set:\n                  id: rgb_led\n                  range_from: 0\n                  range_to: 1\n                  red: !lambda |-\n                    return id(intlum1);\n                  green: 0%\n                  blue: 0%\n                  \n            - light.addressable_set:\n                  id: rgb_led\n                  range_from: 2\n                  range_to: 4\n                  red: 0%\n                  green: 0%\n                  blue: 0%\n\n# Couleur du lendemain\n  - id: calcul_led_jour1\n    mode: single\n    then:\n      # Si \n      - if: \n          condition:\n            and:\n              - lambda: |-\n                  return strcmp(id(tempo_jour1).state.c_str(),\"Bleu\") != 0;\n              - lambda: |-\n                  return strcmp(id(tempo_jour1).state.c_str(),\"Blanc\") != 0;\n              - lambda: |-\n                  return strcmp(id(tempo_jour1).state.c_str(),\"Rouge\") != 0;\n          then:\n            - light.addressable_set:\n                  id: rgb_led\n                  range_from: 5\n                  range_to: 7\n                  red: 0%\n                  green: 0%\n                  blue: 0%\n\n            - light.addressable_set:\n                  id: rgb_led\n                  range_from: 2\n                  range_to: 4\n                  red: 0%\n                  green: 0%\n                  blue: 0%      \n      - if: \n          condition:\n            - lambda: |-\n                return strcmp(id(tempo_jour1).state.c_str(),\"Bleu\") == 0;\n          then:\n            - light.addressable_set:\n                  id: rgb_led\n                  range_from: 5\n                  range_to: 7\n                  red: 0%\n                  green: 0%\n                  blue: !lambda |-\n                    return id(intlum1);\n\n            - light.addressable_set:\n                  id: rgb_led\n                  range_from: 2\n                  range_to: 4\n                  red: 0%\n                  green: 0%\n                  blue: 0%\n\n      - if: \n          condition:\n            - lambda: |-\n                return strcmp(id(tempo_jour1).state.c_str(),\"Blanc\") == 0;\n          then:\n            - light.addressable_set:\n                  id: rgb_led\n                  range_from: 5\n                  range_to: 7\n                  red: !lambda |-\n                    return id(intlum1);\n                  green:  !lambda |-\n                    return id(intlum1);\n                  blue:  !lambda |-\n                    return id(intlum1);\n                  \n            - light.addressable_set:\n                  id: rgb_led\n                  range_from: 2\n                  range_to: 4\n                  red: 0%\n                  green: 0%\n                  blue: 0%\n          \n      - if: \n          condition:\n            - lambda: |-\n                return strcmp(id(tempo_jour1).state.c_str(),\"Rouge\") == 0;\n          then:\n            - light.addressable_set:\n                  id: rgb_led\n                  range_from: 5\n                  range_to: 7\n                  red:  !lambda |-\n                    return id(intlum1);\n                  green: 00%\n                  blue: 0%\n\n            - light.addressable_set:\n                  id: rgb_led\n                  range_from: 2\n                  range_to: 4\n                  red: 0%\n                  green: 0%\n                  blue: 0%\n\n <\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">Explications du code<\/h1>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Substitutions<\/strong> : J\u2019ai d\u00e9fini des variables comme le nom de l\u2019appareil (esp141-affichage-pv), son adresse IP statique (192.168.0.141), et un nom convivial (esp141). Le fuseau horaire est r\u00e9gl\u00e9 sur Europe\/Paris.<\/li>\n\n\n\n<li><strong>Configuration de l\u2019ESP8266<\/strong> : J\u2019utilise une Wemos D1 Mini (board: d1_mini) avec la version recommand\u00e9e du framework ESPHome. La biblioth\u00e8que NeoPixelBus est incluse pour g\u00e9rer la bande LED WS2812.<\/li>\n\n\n\n<li><strong>Connexion Wi-Fi<\/strong> : Le module se connecte \u00e0 deux r\u00e9seaux Wi-Fi possibles (avec des priorit\u00e9s), et utilise une IP statique pour une int\u00e9gration stable dans mon r\u00e9seau.<\/li>\n\n\n\n<li><strong>Bande LED RGB<\/strong> :\n<ul class=\"wp-block-list\">\n<li>J\u2019utilise une bande WS2812 avec 8 LED, connect\u00e9e \u00e0 la broche GPIO3 (D1 sur la Wemos D1 Mini).<\/li>\n\n\n\n<li>Les LED 0 \u00e0 1 affichent la couleur du jour actuel, et les LED 5 \u00e0 7 celle du lendemain. Les LED 2 \u00e0 4 sont \u00e9teintes pour s\u00e9parer visuellement les deux groupes.<\/li>\n\n\n\n<li>L\u2019intensit\u00e9 lumineuse est contr\u00f4l\u00e9e par une variable globale intlum1 (initialement \u00e0 0.25 pour \u00e9viter un \u00e9clairage trop intense).<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>R\u00e9cup\u00e9ration des donn\u00e9es Tempo<\/strong> :\n<ul class=\"wp-block-list\">\n<li>Deux text_sensor r\u00e9cup\u00e8rent les donn\u00e9es depuis Home Assistant : sensor.rte_tempo_couleur_actuelle (couleur du jour) et sensor.rte_tempo_prochaine_couleur (couleur du lendemain).<\/li>\n\n\n\n<li>Ces capteurs doivent \u00eatre configur\u00e9s dans Home Assistant au pr\u00e9alable (par exemple, via l\u2019int\u00e9gration officielle RTE Tempo).<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Scripts pour les LED<\/strong> :\n<ul class=\"wp-block-list\">\n<li>Le script calcul_led_jour g\u00e8re la couleur du jour actuel :\n<ul class=\"wp-block-list\">\n<li>Si la couleur est \u00ab\u00a0Bleu\u00a0\u00bb, les LED 0-1 s\u2019allument en bleu.<\/li>\n\n\n\n<li>Si \u00ab\u00a0Blanc\u00a0\u00bb, elles s\u2019allument en blanc (R+G+B).<\/li>\n\n\n\n<li>Si \u00ab\u00a0Rouge\u00a0\u00bb, elles s\u2019allument en rouge.<\/li>\n\n\n\n<li>Si la couleur est indisponible, les LED s\u2019\u00e9teignent.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Le script calcul_led_jour1 fait de m\u00eame pour le lendemain, en contr\u00f4lant les LED 5-7.<\/li>\n\n\n\n<li>Les scripts sont ex\u00e9cut\u00e9s toutes les secondes (interval: 1s) pour une mise \u00e0 jour rapide.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Autres fonctionnalit\u00e9s<\/strong> :\n<ul class=\"wp-block-list\">\n<li>Un binary_sensor (status) v\u00e9rifie l\u2019\u00e9tat de la connexion.<\/li>\n\n\n\n<li>Un switch (restart) permet de red\u00e9marrer l\u2019ESP \u00e0 distance.<\/li>\n\n\n\n<li>Un bouton physique (bp_raz) est connect\u00e9 \u00e0 GPIO16, mais il n\u2019est pas utilis\u00e9 dans ce code.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h1 class=\"wp-block-heading\">Int\u00e9gration dans Home Assistant<\/h1>\n\n\n\n<p>Pour que ce projet fonctionne, il faut d\u2019abord configurer l\u2019int\u00e9gration Tempo dans Home Assistant (via <a href=\"https:\/\/github.com\/hekmon\/rtetempo\/blob\/v1.3.2\/README.md\" data-type=\"link\" data-id=\"https:\/\/github.com\/hekmon\/rtetempo\/blob\/v1.3.2\/README.md\" target=\"_blank\" rel=\"noreferrer noopener\">l\u2019int\u00e9gration officielle RTE<\/a>). Une fois les capteurs sensor.rte_tempo_couleur_actuelle et sensor.rte_tempo_prochaine_couleur disponibles, l\u2019ESP les r\u00e9cup\u00e8re automatiquement gr\u00e2ce au composant text_sensor. L\u2019appareil est d\u00e9tect\u00e9 via l\u2019API ESPHome, et je peux aussi ajuster l\u2019intensit\u00e9 des LED ou red\u00e9marrer l\u2019ESP depuis Home Assistant.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">A Venir<\/h1>\n\n\n\n<p>Int\u00e9gration de l&rsquo;ensemble dans un boitier comme celui ci par exemple.<\/p>\n\n\n\n<div class=\"wp-block-media-text is-stacked-on-mobile\"><figure class=\"wp-block-media-text__media\"><img loading=\"lazy\" decoding=\"async\" width=\"371\" height=\"374\" src=\"https:\/\/domo.rem81.com\/wp-content\/uploads\/2025\/02\/image.png\" alt=\"\" class=\"wp-image-3818 size-full\" srcset=\"https:\/\/domo.rem81.com\/wp-content\/uploads\/2025\/02\/image.png 371w, https:\/\/domo.rem81.com\/wp-content\/uploads\/2025\/02\/image-298x300.png 298w, https:\/\/domo.rem81.com\/wp-content\/uploads\/2025\/02\/image-150x150.png 150w\" sizes=\"auto, (max-width: 371px) 100vw, 371px\" \/><\/figure><div class=\"wp-block-media-text__content\">\n<p><a href=\"https:\/\/fr.aliexpress.com\/item\/4000589488923.html?spm=a2g0o.order_list.order_list_main.17.cfed5e5bvLcini&amp;gatewayAdapt=glo2fra\">https:\/\/fr.aliexpress.com\/item\/4000589488923.html?spm=a2g0o.order_list.order_list_main.17.cfed5e5bvLcini&amp;gatewayAdapt=glo2fra<\/a><\/p>\n<\/div><\/div>\n\n\n\n<h1 class=\"wp-block-heading\">Conclusion<\/h1>\n\n\n\n<p>Ce syst\u00e8me est un vrai gain de temps au quotidien : un simple coup d\u2019\u0153il sur la bande LED me permet de savoir si je dois limiter ma consommation (jour Rouge) ou en profiter (jour Bleu). La couleur du lendemain me permet aussi de planifier mes t\u00e2ches, comme lancer une machine \u00e0 laver ou charger un appareil. C\u2019est un projet \u00e0 la fois pratique et esth\u00e9tique, qui ajoute une touche de domotique maligne \u00e0 mon int\u00e9rieur !<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Intro Dans cet article, je vous pr\u00e9sente un projet qui me tient \u00e0 c\u0153ur : un affichage visuel des couleurs de l\u2019offre Tempo d\u2019EDF (pour le jour actuel et le &hellip; <\/p>\n","protected":false},"author":1,"featured_media":3558,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[17,22],"class_list":["post-3552","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-homeassistant","tag-esphome","tag-linky"],"_links":{"self":[{"href":"https:\/\/domo.rem81.com\/index.php\/wp-json\/wp\/v2\/posts\/3552","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/domo.rem81.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/domo.rem81.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/domo.rem81.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/domo.rem81.com\/index.php\/wp-json\/wp\/v2\/comments?post=3552"}],"version-history":[{"count":10,"href":"https:\/\/domo.rem81.com\/index.php\/wp-json\/wp\/v2\/posts\/3552\/revisions"}],"predecessor-version":[{"id":3821,"href":"https:\/\/domo.rem81.com\/index.php\/wp-json\/wp\/v2\/posts\/3552\/revisions\/3821"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/domo.rem81.com\/index.php\/wp-json\/wp\/v2\/media\/3558"}],"wp:attachment":[{"href":"https:\/\/domo.rem81.com\/index.php\/wp-json\/wp\/v2\/media?parent=3552"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/domo.rem81.com\/index.php\/wp-json\/wp\/v2\/categories?post=3552"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/domo.rem81.com\/index.php\/wp-json\/wp\/v2\/tags?post=3552"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}