Air Quality Sensors + E-Ink Display using ESPHome

Hello I think there is a problem with the copy/paste but what is the symbol 
Thnaks

If you want to see what icon it is, check for it’s « mdi » name on https://materialdesignicons.com/
Then find it in the font and copy/past it to your code.

Hi,
I try to connect the same paper with esphome without success.
The screen have no react.
My first try :

...
substitutions:
  devicename: AQI Display
  gpio_led_status: GPIO5
  gpio_i2c_sda: GPIO21
  gpio_i2c_scl: GPIO22
  gpio_uart_rx_pin: GPIO14
  gpio_uart_tx_pin: GPIO13
  gpio_spi_clk_pin: GPIO25
  gpio_spi_mosi_pin: GPIO26
  gpio_cs_pin: GPIO32
  gpio_busy_pin: GPIO33
  gpio_reset_pin: GPIO27
  gpio_dc_pin: GPIO17
  gpio_buzzer: GPIO04
  gpio_led_red: GPIO19
  gpio_led_green: GPIO23
  gpio_led_blue: GPIO18
  
spi:
  clk_pin: GPIO12
  mosi_pin: GPIO13

display:
  - platform: waveshare_epaper
    id: epaper
    cs_pin: $gpio_cs_pin
    busy_pin: $gpio_busy_pin
    reset_pin: $gpio_reset_pin
    dc_pin: $gpio_dc_pin
    model: 4.20in # 300x400
    rotation: 270°
    update_interval: 60s
    lambda: |-
      it.print(0, 0, id(font_medium_20), "Hello World!");
      
font:
  - file: 'fonts/Kanit-Medium.ttf'
    id: font_medium_20
    size: 20
    glyphs:
      ['&', '@', '!', ',', '.', '"', '%', '+', '-', '_', ':', '°', '0',
       '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
       'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
       'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
       'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
       'u', 'v', 'w', 'x', 'y', 'z', '/', 'é']

I found a mistake in my substitutions. It’s works for me thx.

@makai
how have implement mdi font.
I download the ttf file. place in Esphom/fonts, but when a try to use it like you I don’t have icon on screen.

You may check this post: Display materialdesign icons on ESPHome attached to screen

If it does not solve your issue, please post your yaml.

1 Like

I use your code to understand how to do mine.

sensor:
  - platform: homeassistant
    name: "Outdoor Hum. from HA"
    entity_id: sensor.dark_sky_humidity
    id: outdoor_hum
    internal: true

display:
  - platform: waveshare_epaper
    id: epaper
    cs_pin: $gpio_cs_pin
    busy_pin: $gpio_busy_pin
    reset_pin: $gpio_reset_pin
    dc_pin: $gpio_dc_pin
    model: 4.20in # 300x400
    rotation: 270°
    update_interval: 60s
    lambda: |-
      ESP_LOGI("display", "Updating...");
      // OUTSIDE
      it.printf(7, 15, id(font_medium_20), TextAlign::BASELINE_LEFT, "Dehors");
      it.line(78, 14, 293, 14);
      it.printf(10, 84, id(icon_font_20), TextAlign::BASELINE_LEFT, ""); 
      if (id(outdoor_hum).has_state()) {
        it.printf(41, 82, id(font_regular_45), TextAlign::BASELINE_LEFT, "%2.0f", id(outdoor_hum).state);
        it.printf(95, 82, id(font_regular_30), TextAlign::BASELINE_LEFT, "%%");
      }
      
font:
  - file: 'fonts/Kanit-Medium.ttf'
    id: font_medium_20
    size: 20
    glyphs:
      ['&', '@', '!', ',', '.', '"', '%', '+', '-', '_', ':', '°', '0',
       '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
       'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
       'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
       'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
       'u', 'v', 'w', 'x', 'y', 'z', '/', 'é']
  - file: 'fonts/materialdesignicons-webfont.ttf'
    id: icon_font_20
    size: 20
    glyphs: [
     "", # mdi-water-percent
     ]

Did you copy/paste the “glyphs” from my code above?
If yes, you should try to open the font on your computer and copy/paste from it.

ok i try it

@makai Bien vu !
Font have change. Thx a lot.

2 Likes

@makai One more question.
How work weather print ?
I use our code without success.

The weather alert binary sensor is a templated binary sensor based on the Météo France integration (you need to add it using GUI):

Under binary_sensor:

- platform: template
  sensors:
    alerte_meteo:
      entity_id: sensor.81_weather_alert
      friendly_name: Alerte Météo
      device_class: safety
      value_template: >-
        {{ is_state('sensor.81_weather_alert', 'Jaune') 
           or is_state('sensor.81_weather_alert', 'Orange')
           or is_state('sensor.81_weather_alert', 'Rouge') }}

For the forecast I use the Darksky integration and a templated sensor (under sensor: in my conf):

  - platform: template
    sensors:
      forecast_0:
        entity_id:
          - sensor.dark_sky_daytime_high_temperature_0d
          - sensor.dark_sky_overnight_low_temperature_0d
          - sensor.dark_sky_precip_probability_0d
          - sensor.dark_sky_icon_0d
          - sensor.dark_sky_uv_index_0d
        friendly_name: "Météo de la journée"
        value_template: 
          "{{ states('sensor.dark_sky_overnight_low_temperature_0d')|round(0) }}°/\
           {{ states('sensor.dark_sky_daytime_high_temperature_0d')|round(0) }}°/\
           {{ states('sensor.dark_sky_precip_probability_0d')|round(0) }}%/\
           {{ states('sensor.dark_sky_uv_index_0d') }}UV"
        icon_template: >-
          {% if is_state("sensor.dark_sky_icon_0d", "clear-day") %}
            mdi:weather-sunny
          {% elif is_state("sensor.dark_sky_icon_0d", "clear-night") %}
            mdi:weather-night
          {% elif is_state("sensor.dark_sky_icon_0d", "cloudy") %}
            mdi:weather-cloudy
          {% elif is_state("sensor.dark_sky_icon_0d", "rain") %}
            mdi:weather-pouring
          {% elif is_state("sensor.dark_sky_icon_0d", "sleet") %}
            mdi:weather-snowy-rainy
          {% elif is_state("sensor.dark_sky_icon_0d", "snow") %}
            mdi:weather-snowy
          {% elif is_state("sensor.dark_sky_icon_0d", "wind") %}
            mdi:weather-windy
          {% elif is_state("sensor.dark_sky_icon_0d", "fog") %}
            mdi:weather-fog
          {% elif is_state("sensor.dark_sky_icon_0d", "partly-cloudy-day") %}
            mdi:weather-partly-cloudy
          {% elif is_state("sensor.dark_sky_icon_0d", "partly-cloudy-night") %}
            mdi:weather-night-partly-cloudy
          {% else %}
            error
          {% endif %}

      forecast_1:
        entity_id:
          - sensor.dark_sky_daytime_high_temperature_1d
          - sensor.dark_sky_overnight_low_temperature_1d
          - sensor.dark_sky_precip_probability_1d
          - sensor.dark_sky_icon_1d
          - sensor.dark_sky_uv_index_1d
        friendly_name_template: '{{ (as_timestamp(now()) + (86400))|timestamp_custom("%A", True) }}'
        value_template:
          "{{ states('sensor.dark_sky_overnight_low_temperature_1d')|round(0) }}°/\
           {{ states('sensor.dark_sky_daytime_high_temperature_1d')|round(0) }}°/\
           {{ states('sensor.dark_sky_precip_probability_1d')|round(0) }}%/\
           {{ states('sensor.dark_sky_uv_index_1d') }}UV"
        icon_template: >-
          {% if is_state("sensor.dark_sky_icon_1d", "clear-day") %}
            mdi:weather-sunny
          {% elif is_state("sensor.dark_sky_icon_1d", "clear-night") %}
            mdi:weather-night
          {% elif is_state("sensor.dark_sky_icon_1d", "cloudy") %}
            mdi:weather-cloudy   
          {% elif is_state("sensor.dark_sky_icon_1d", "rain") %}
            mdi:weather-pouring        
          {% elif is_state("sensor.dark_sky_icon_1d", "sleet") %}
            mdi:weather-snowy-rainy
          {% elif is_state("sensor.dark_sky_icon_1d", "snow") %}
            mdi:weather-snowy
          {% elif is_state("sensor.dark_sky_icon_1d", "wind") %}
            mdi:weather-windy
          {% elif is_state("sensor.dark_sky_icon_1d", "fog") %}
            mdi:weather-fog
          {% elif is_state("sensor.dark_sky_icon_1d", "partly-cloudy-day") %}
            mdi:weather-partly-cloudy
          {% elif is_state("sensor.dark_sky_icon_1d", "partly-cloudy-night") %}
            mdi:weather-night-partly-cloudy            
          {% else %}
            error
          {% endif %}

It’s work ! Are you on the French discord ?

Hi @makai,
Thanks for sharing the project.
Can I use waveshare 7,5” e-ink display that uses red color along with black and white?
https://www.waveshare.com/7.5inch-hd-e-paper-b.htm

I would like to use red color to accent high values.

I have other question regarding 3D printed case, the finish on the 3D printed materials always feels cheap and not smooth at all, do you have some method where it would turn out like a molded plastic?

ESPHome does not currently support color for displays. So only the “black and white” 7.5" display is supported and the red one won’t work at all.

Regarding the case, I have no idea :man_shrugging:

Thanks @makai!
Is the 7,5” Display with 880x528 resolution supported, or just the one with 800x480?

Supported model are in the documentation:

That is true, but there are more than one 4.2 inch version sold by WaveShare.

This thread seems to indicate that the higher res version of the 7.5 in is not supported by esphome, I think the same would apply to the higher res 4.2 in. Waveshare e-ink paper 7.5 HD display support

Hey, did anyone with this project managed to trigger only partial updates in the 4.2 inches screen?

I seem to have a full update every 60s (my update interval). Which means that 1) I only see the temperature updates every minute 2) the update is ugly (I hate the going to black, white and render). The second point is what is killing me.

I was hoping to be able to only do full refresh every 30 min or so.

I have seen this guy on youtube that manages to do partial updates using the same hardware (min 9:30 of the video). He does it directly using arduino IDE.

Thanks!