Home Assistant: Displaying weather data on a reTerminal E1001 with ESPHome

5
(1)

In this tutorial, you will be guided step-by-step to display weather data from the Meteorologisk institutt integration, which comes built-in with Home Assistant, using the ESPHome framework on the Seeed Studio reTerminal E1001. You will learn how to fetch temperature readings, weather conditions, and forecasts from Home Assistant, and visually present this information directly on the e-paper display of the reTerminal.

To better understand the configuration of the reTerminal and the display of information from Home Assistant, I recommend reading my previous tutorial “Integrate a reTerminal E1002 into Home Assistant with ESPHome”.

Meteorologisk institutt (Met.no) integration

This weather integration is installed by default on Home Assistant, and provide weather forecast at your location. In its configuration you can select units, and find the entity id that we will use to retreive data: weather.forecast_home.

We will first check which information are provided by this integration, using States tab of developer tools. Enter weather as filter, you can see that this entity has weather condition as state (rainy) and several attributes (temperature, dew_point, temperature_unit, humidity…).

As we will see later, we do not see the weather forecast information. Indeed weather forecast are not attributes from weather.forecast_home sensor and must be requested by weather.get_forecasts action on the weather.forecast_home entity.

As we will see later, weather forecast information does not appear because forecasts are not stored as attributes of the weather.forecast_home sensor. To obtain the forecast data, you need to explicitly request it using the weather.get_forecasts action on the weather.forecast_home entity.

Display outdoor temperature

To display the current outdoor temperature, I use the temperature attribute from weather.forecast_home entity_id.

Outdoor temperature display

To access weather.forecast_home attributes, you need to create a template sensor “Outdoor temperature” in the Home Assistant configuration file (configuration.yaml).

Modifying this configuration file can be done with help of File Editor add-on. Here is the configuration to add to this file:

To access the attributes of the weather.forecast_home entity, you need to create a template sensor in the Home Assistant configuration file (configuration.yaml). You can edit this configuration file using the File Editor add-on (configuration.yaml) available from the Home Assistant add-ons store.
Below is the configuration snippet to add to your file:

YAML
template:
  - sensor:
      - name: "Outdoor temperature"
        unique_id: outdoor_temperature
        state: "{{ state_attr('weather.forecast_home','temperature') }}"    

A corresponding sensor must then be declared in ESPHome configuration file, immediately after the line captive_portal:

YAML
sensor:
  - platform: homeassistant
    id: outdoor_temperature_id
    entity_id: sensor.outdoor_temperature

So temperature can be displayed on the screen of reTerminal :

YAML
it.printf(0, 0, id(myFont), "%.1f °C", id(outdoor_temperature_id).state);         

Display indoor temperature and humidity

To display the indoor temperature and humidity, I use the internal STH40 sensor of the reTerminal.

Indoor temperature and humidity measured by internal sensor

The ESP32-S3 microcontroller in the reTerminal E1001 communicates with the STH40 sensor via an I2C bus. Its I2C address is 0x44, and the I2C bus uses the following pins:

  • Serial Data (SDA) : GPIO19
  • Serial Clock (SCL) : GPIO20

Here is the YAML configuration that allows you to retrieve the temperature and humidity from this sensor, to be copied immediately after the line captive_portal: in the ESPHome configuration file:

YAML
# define I2C interface
i2c:
  sda: GPIO19
  scl: GPIO20
  scan: false
# temperature and humidity sensor
sensor:
  # Internal SHT4x temperature/humidity sensor
  - platform: sht4x            # Sensor platform
    id: sht4x_component         # ID for the component
    temperature:                # Temperature sensor
      name: "Temperature"       # Sensor name
      id: sht4x_temperature     # ID for temperature sensor
    humidity:                   # Humidity sensor
      name: "Humidity"          # Sensor name
      id: sht4x_humidity        # ID for humidity sensor
    address: 0x44               # I2C address
    update_interval: 60s

You can display the value of this sensor on the reTerminal E1001 screen via the following ESPHome configuration:

YAML
it.printf(10, 10, id(myFont), "Temperature: %.1f°C", id(sht4x_temperature).state);  
it.printf(10, 40, id(myFont), "Humidity: %.1f%%", id(sht4x_humidity).state); 

Access to weather forecast data

To access weather forecasts in Home Assistant, you need to execute the weather.get_forecasts action on the weather.forecast_home entity, specifying the type as daily or hourly.

To check if everything is properly configured, you can use the Actions tab of developer tools and enter the following configuration:

YAML
action: weather.get_forecasts
entity_id: weather.forecast_home
data:
  type: daily
target:
  entity_id: weather.forecast_home

You should get the daily weather forecast for today and the next 5 days in the Response field:

To get hourly weather forecast for the next 48h you can use this configuration:

YAML
action: weather.get_forecasts
entity_id: weather.forecast_home
data:
  type: hourly
target:
  entity_id: weather.forecast_home

Display daily weather forecast

I want to display the daily weather forecast, including the day, condition (icon), maximum and minimum temperature for today and the next four days.

Daily weather forecast (condition icon, maximum and minimum temperatures)

Displaying daily forecasst requires modifying the Home Assistant configuration file (configuration.yaml) to create an automation that executes the weather.get_forecasts action, as well as a custom sensor template to retrieve the weather forecast data.

Here is an example of how to configure daily_weather_forecast_sensor template sensor and its automation, which retrieves the weather forecast (day, min/max temperature and condition) for today and the next 3 days:

YAML
template:
  - trigger:
      - platform: time_pattern
        hours: /1
      - platform: homeassistant
        event: start
    action:
      - service: weather.get_forecasts
        data:
          type: daily
        target:
          entity_id: weather.forecast_home
        response_variable: daily_data      
    sensor:
      - name: "Weather forecast"
        unique_id: weather_forecast
        state: "{{ daily_data['weather.forecast_home'].forecast[0] }}"
        attributes:
          daily_forecast: "{{ daily_data['weather.forecast_home'].forecast }}"
        availability: "{{ states('weather.forecast_home') not in ['unknown', 'unavailable', 'none'] }}"
  - sensor:
      - name: "Daily weather forecast sensor"
        unique_id: daily_weather_forecast_sensor
        state: "{{ state_attr('sensor.weather_forecast','daily_forecast')[0] }}"
        attributes:  
          condition0: "{{ state_attr('sensor.weather_forecast','daily_forecast')[0].condition }}"
          day0: "{{ as_timestamp(state_attr('sensor.weather_forecast','daily_forecast')[0].datetime) | timestamp_custom('%a', True) }}"
          temperature0: "{{ state_attr('sensor.weather_forecast','daily_forecast')[0].temperature | float }}"
          templow0: "{{ state_attr('sensor.weather_forecast','daily_forecast')[0].templow | float }}"
          condition1: "{{ state_attr('sensor.weather_forecast','daily_forecast')[1].condition }}"
          day1: "{{ as_timestamp(state_attr('sensor.weather_forecast','daily_forecast')[1].datetime) | timestamp_custom('%a', True) }}"          
          temperature1: "{{ state_attr('sensor.weather_forecast','daily_forecast')[1].temperature | float }}"
          templow1: "{{ state_attr('sensor.weather_forecast','daily_forecast')[1].templow | float }}"
          condition2: "{{ state_attr('sensor.weather_forecast','daily_forecast')[2].condition }}"
          day2: "{{ as_timestamp(state_attr('sensor.weather_forecast','daily_forecast')[2].datetime) | timestamp_custom('%a', True) }}"          
          temperature2: "{{ state_attr('sensor.weather_forecast','daily_forecast')[2].temperature | float }}"
          templow2: "{{ state_attr('sensor.weather_forecast','daily_forecast')[2].templow | float }}"
          condition3: "{{ state_attr('sensor.weather_forecast','daily_forecast')[3].condition }}"
          day3: "{{ as_timestamp(state_attr('sensor.weather_forecast','daily_forecast')[3].datetime) | timestamp_custom('%a', True) }}"          
          temperature3: "{{ state_attr('sensor.weather_forecast','daily_forecast')[3].temperature | float }}"
          templow3: "{{ state_attr('sensor.weather_forecast','daily_forecast')[3].templow | float }}"          
          condition4: "{{ state_attr('sensor.weather_forecast','daily_forecast')[4].condition }}"
          day4: "{{ as_timestamp(state_attr('sensor.weather_forecast','daily_forecast')[4].datetime) | timestamp_custom('%a', True) }}"          
          temperature4: "{{ state_attr('sensor.weather_forecast','daily_forecast')[4].temperature | float }}"
          templow4: "{{ state_attr('sensor.weather_forecast','daily_forecast')[4].templow | float }}"     

You can check the correct configuration of sensor.daily_weather_forecast_sensor from developper tools:

Note that the day attribute is displayed as abbreviated weekday name thanks to %a argument in timestamp_custom() function. See the Time component documention for details.

Once the sensors are configured in Home Assistant, they must be declared in the ESPHome configuration. Because day and condition are provided as text (for example, “Monday”, “sunny”), they should be defined as text_sensor entities. Temperature (max temperature) and Templow (min temperature) are floating-point values, they should be defined as sensor entities

YAML

text_sensor:
  # Daily text sensors
  - platform: homeassistant
    entity_id: sensor.daily_weather_forecast_sensor 
    attribute: day0
    id: day_d0
  - platform: homeassistant
    entity_id: sensor.daily_weather_forecast_sensor
    attribute: condition0
    id: condition_d0
  - platform: homeassistant
    entity_id: sensor.daily_weather_forecast_sensor 
    attribute: day1
    id: day_d1
  - platform: homeassistant
    entity_id: sensor.daily_weather_forecast_sensor
    attribute: condition1
    id: condition_d1
  - platform: homeassistant
    entity_id: sensor.daily_weather_forecast_sensor 
    attribute: day2
    id: day_d2
  - platform: homeassistant
    entity_id: sensor.daily_weather_forecast_sensor
    attribute: condition2
    id: condition_d2
  - platform: homeassistant
    entity_id: sensor.daily_weather_forecast_sensor 
    attribute: day3
    id: day_d3
  - platform: homeassistant
    entity_id: sensor.daily_weather_forecast_sensor
    attribute: condition3
    id: condition_d3
  - platform: homeassistant
    entity_id: sensor.daily_weather_forecast_sensor 
    attribute: day4
    id: day_d4
  - platform: homeassistant
    entity_id: sensor.daily_weather_forecast_sensor
    attribute: condition4
    id: condition_d4        

sensor:
    # Daily sensors
  - platform: homeassistant
    id: temperature_d0
    entity_id: sensor.daily_weather_forecast_sensor
    attribute: temperature0  
  - platform: homeassistant
    id: templow_d0
    entity_id: sensor.daily_weather_forecast_sensor
    attribute: templow0    
  - platform: homeassistant
    id: temperature_d1
    entity_id: sensor.daily_weather_forecast_sensor
    attribute: temperature1 
  - platform: homeassistant
    id: templow_d1
    entity_id: sensor.daily_weather_forecast_sensor
    attribute: templow1
  - platform: homeassistant
    id: temperature_d2
    entity_id: sensor.daily_weather_forecast_sensor
    attribute: temperature2 
  - platform: homeassistant
    id: templow_d2
    entity_id: sensor.daily_weather_forecast_sensor
    attribute: templow2
  - platform: homeassistant
    id: temperature_d3
    entity_id: sensor.daily_weather_forecast_sensor
    attribute: temperature3 
  - platform: homeassistant
    id: templow_d3
    entity_id: sensor.daily_weather_forecast_sensor
    attribute: templow3
  - platform: homeassistant
    id: temperature_d4
    entity_id: sensor.daily_weather_forecast_sensor
    attribute: temperature4 
  - platform: homeassistant
    id: templow_d4
    entity_id: sensor.daily_weather_forecast_sensor
    attribute: templow4       

Display hourly weather forecast

We want to display hourly weather condition, temperature and precipitation for the next 12hours.

Hourly weather foreacast for the next 12 hours

Similar to daily forecasts, displaying hourly forecasts requires modifying the Home Assistant configuration file (configuration.yaml) to create hourly_weather_forecast_sensor template sensor:

YAML

template:
  - trigger:
      - platform: time_pattern
        hours: /1
      - platform: homeassistant
        event: start
    action:
      - service: weather.get_forecasts
        data:
          type: daily
        target:
          entity_id: weather.forecast_home
        response_variable: daily_data
      - service: weather.get_forecasts
        data:
          type: hourly
        target:
          entity_id: weather.forecast_home
        response_variable: hourly_data        
    sensor:
      - name: "Weather forecast"
        unique_id: weather_forecast
        state: "{{ daily_data['weather.forecast_home'].forecast[0] }}"
        attributes:
          daily_forecast: "{{ daily_data['weather.forecast_home'].forecast }}"
          hourly_forecast: "{{ hourly_data['weather.forecast_home'].forecast }}"
        availability: "{{ states('weather.forecast_home') not in ['unknown', 'unavailable', 'none'] }}"
  - sensor:
      - name: "Daily weather forecast sensor"
        unique_id: daily_weather_forecast_sensor
        state: "{{ state_attr('sensor.weather_forecast','daily_forecast')[0] }}"
        attributes:  
          condition0: "{{ state_attr('sensor.weather_forecast','daily_forecast')[0].condition }}"
          day0: "{{ as_timestamp(state_attr('sensor.weather_forecast','daily_forecast')[0].datetime) | timestamp_custom('%a', True) }}"
          temperature0: "{{ state_attr('sensor.weather_forecast','daily_forecast')[0].temperature | float }}"
          templow0: "{{ state_attr('sensor.weather_forecast','daily_forecast')[0].templow | float }}"
          condition1: "{{ state_attr('sensor.weather_forecast','daily_forecast')[1].condition }}"
          day1: "{{ as_timestamp(state_attr('sensor.weather_forecast','daily_forecast')[1].datetime) | timestamp_custom('%a', True) }}"          
          temperature1: "{{ state_attr('sensor.weather_forecast','daily_forecast')[1].temperature | float }}"
          templow1: "{{ state_attr('sensor.weather_forecast','daily_forecast')[1].templow | float }}"
          condition2: "{{ state_attr('sensor.weather_forecast','daily_forecast')[2].condition }}"
          day2: "{{ as_timestamp(state_attr('sensor.weather_forecast','daily_forecast')[2].datetime) | timestamp_custom('%a', True) }}"          
          temperature2: "{{ state_attr('sensor.weather_forecast','daily_forecast')[2].temperature | float }}"
          templow2: "{{ state_attr('sensor.weather_forecast','daily_forecast')[2].templow | float }}"
          condition3: "{{ state_attr('sensor.weather_forecast','daily_forecast')[3].condition }}"
          day3: "{{ as_timestamp(state_attr('sensor.weather_forecast','daily_forecast')[3].datetime) | timestamp_custom('%a', True) }}"          
          temperature3: "{{ state_attr('sensor.weather_forecast','daily_forecast')[3].temperature | float }}"
          templow3: "{{ state_attr('sensor.weather_forecast','daily_forecast')[3].templow | float }}"          
          condition4: "{{ state_attr('sensor.weather_forecast','daily_forecast')[4].condition }}"
          day4: "{{ as_timestamp(state_attr('sensor.weather_forecast','daily_forecast')[4].datetime) | timestamp_custom('%a', True) }}"          
          temperature4: "{{ state_attr('sensor.weather_forecast','daily_forecast')[4].temperature | float }}"
          templow4: "{{ state_attr('sensor.weather_forecast','daily_forecast')[4].templow | float }}"     
  - sensor:
      - name: "Hourly weather forecast sensor"
        unique_id: hourly_weather_forecast_sensor
        state: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[0] }}"
        attributes:
          # Heure_0
          condition0: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[0].condition | default(0) }}"
          time0: "{{ as_timestamp(state_attr('sensor.weather_forecast','hourly_forecast')[0].datetime) | int(0) | timestamp_custom('%H:%M', true) }}"
          temperature0: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[0].temperature | float(0) }}"
          precipitation0: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[0].precipitation | float(0) }}"
          # time_1
          condition1: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[1].condition | default(0) }}"
          time1: "{{ as_timestamp(state_attr('sensor.weather_forecast','hourly_forecast')[1].datetime) | int(0) | timestamp_custom('%H:%M', true) }}"
          temperature1: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[1].temperature | float(0) }}"
          precipitation1: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[1].precipitation | float(0) }}"
          # time_2
          condition2: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[2].condition | default(0) }}"
          time2: "{{ as_timestamp(state_attr('sensor.weather_forecast','hourly_forecast')[2].datetime) | int(0) | timestamp_custom('%H:%M', true) }}"
          temperature2: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[2].temperature | float(0) }}"
          precipitation2: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[2].precipitation | float(0) }}"
          # time_3
          condition3: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[3].condition | default(0) }}"
          time3: "{{ as_timestamp(state_attr('sensor.weather_forecast','hourly_forecast')[3].datetime) | int(0) | timestamp_custom('%H:%M', true) }}"
          temperature3: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[3].temperature | float(0) }}"
          precipitation3: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[3].precipitation | float(0) }}"
          # time_4
          condition4: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[4].condition | default(0) }}"
          time4: "{{ as_timestamp(state_attr('sensor.weather_forecast','hourly_forecast')[4].datetime) | int(0) | timestamp_custom('%H:%M', true) }}"
          temperature4: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[4].temperature | float(0) }}"
          precipitation4: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[4].precipitation | float(0) }}"
          # time_5
          condition5: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[5].condition | default(0) }}"
          time5: "{{ as_timestamp(state_attr('sensor.weather_forecast','hourly_forecast')[5].datetime) | int(0) | timestamp_custom('%H:%M', true) }}"
          temperature5: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[5].temperature | float(0) }}"
          precipitation5: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[5].precipitation | float(0) }}"
          # time_6
          condition6: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[6].condition | default(0) }}"
          time6: "{{ as_timestamp(state_attr('sensor.weather_forecast','hourly_forecast')[6].datetime) | int(0) | timestamp_custom('%H:%M', true) }}"
          temperature6: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[6].temperature | float(0) }}"
          precipitation6: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[6].precipitation | float(0) }}"
          # time_7
          condition7: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[7].condition | default(0) }}"
          time7: "{{ as_timestamp(state_attr('sensor.weather_forecast','hourly_forecast')[7].datetime) | int(0) | timestamp_custom('%H:%M', true) }}"
          temperature7: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[7].temperature | float(0) }}"
          precipitation7: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[7].precipitation | float(0) }}"
          # time_8
          condition8: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[8].condition | default(0) }}"
          time8: "{{ as_timestamp(state_attr('sensor.weather_forecast','hourly_forecast')[8].datetime) | int(0) | timestamp_custom('%H:%M', true) }}"
          temperature8: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[8].temperature | float(0) }}"
          precipitation8: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[8].precipitation | float(0) }}"
          # time_9
          condition9: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[9].condition | default(0) }}"
          time9: "{{ as_timestamp(state_attr('sensor.weather_forecast','hourly_forecast')[9].datetime) | int(0) | timestamp_custom('%H:%M', true) }}"
          temperature9: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[9].temperature | float(0) }}"
          precipitation9: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[9].precipitation | float(0) }}"
          # time_10
          condition10: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[10].condition | default(0) }}"
          time10: "{{ as_timestamp(state_attr('sensor.weather_forecast','hourly_forecast')[10].datetime) | int(0) | timestamp_custom('%H:%M', true) }}"
          temperature10: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[10].temperature | float(0) }}"
          precipitation10: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[10].precipitation | float(0) }}"
          # time_11
          condition11: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[11].condition | default(0) }}"
          time11: "{{ as_timestamp(state_attr('sensor.weather_forecast','hourly_forecast')[11].datetime) | int(0) | timestamp_custom('%H:%M', true) }}"
          temperature11: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[11].temperature | float(0) }}"
          precipitation11: "{{ state_attr('sensor.weather_forecast','hourly_forecast')[11].precipitation | float(0) }}"          

You can check the correct configuration of sensor.hourly_weather_forecast_sensor en developper tools:

Note that the time attribute is displayed in local time using the HH:MM format, while datetime is returned in UTC. Local time conversion is performed by setting the second argument of timestamp_custom() to true.

Once the sensors are configured in Home Assistant, they must be declared in the ESPHome configuration:

Because time and condition are provided as text (for example, “11:00”, “sunny”), they should be defined as text_sensor entities. Temperature and precipition floating-point values should be defined as sensor entities:

YAML

text_sensor: 
    # hourly text sensors
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: time0
    id: time_h0    
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: condition0
    id: condition_h0
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: time1
    id: time_h1    
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: condition1
    id: condition_h1
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: time2
    id: time_h2    
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: condition2
    id: condition_h2
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: time3
    id: time_h3    
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: condition3
    id: condition_h3
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: time4
    id: time_h4    
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: condition4
    id: condition_h4
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: time5
    id: time_h5    
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: condition5
    id: condition_h5
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: time6
    id: time_h6    
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: condition6
    id: condition_h6
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: time7
    id: time_h7    
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: condition7
    id: condition_h7
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: time8
    id: time_h8    
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: condition8
    id: condition_h8
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: time9
    id: time_h9    
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: condition9
    id: condition_h9
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: time10
    id: time_h10    
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: condition10
    id: condition_h10
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: time11
    id: time_h11    
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: condition11
    id: condition_h11

sensor:
    # Hourly sensors         
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: temperature0
    id: temperature_h0
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: precipitation0
    id: precipitation_h0
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: temperature1
    id: temperature_h1
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: precipitation1
    id: precipitation_h1
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: temperature2
    id: temperature_h2
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: precipitation2
    id: precipitation_h2
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: temperature3
    id: temperature_h3
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: precipitation3
    id: precipitation_h3
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: temperature4
    id: temperature_h4
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: precipitation4
    id: precipitation_h4
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: temperature5
    id: temperature_h5
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: precipitation5
    id: precipitation_h5
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: temperature6
    id: temperature_h6
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: precipitation6
    id: precipitation_h6
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: temperature7
    id: temperature_h7
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: precipitation7
    id: precipitation_h7
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: temperature8
    id: temperature_h8
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: precipitation8
    id: precipitation_h8
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: temperature9
    id: temperature_h9
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: precipitation9
    id: precipitation_h9
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: temperature10
    id: temperature_h10
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: precipitation10
    id: precipitation_h10
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: temperature11
    id: temperature_h11
  - platform: homeassistant
    entity_id: sensor.hourly_weather_forecast_sensor
    attribute: precipitation11
    id: precipitation_h11

Display battery charge

To retrieve the reTerminal’s battery level, you must enable battery voltage measurement by configuring GPIO21 (VBAT ENABLE) during reTerminal boot. The reading is then taken from GPIO1 (VBAT ADC), which is internally connected to the battery via a measurement circuit.

YAML
esphome:
  name: reterminal
  friendly_name: reTerminal
  on_boot:
    priority: 600
    then:
      - output.turn_on: bsp_battery_enable
      - delay: 500ms   
      
captive_portal:

output:
  - platform: gpio
    pin: GPIO21
    id: bsp_battery_enable
    
sensor:
  # ADC for battery voltage measurement
  - platform: adc
    pin: GPIO1
    name: "Battery Voltage"
    id: battery_voltage
    update_interval: 600s      
    attenuation: 12db
    filters:
      - multiply: 2.0  # Voltage divider compensation

By reading the analog value on GPIO1, we retrieve the internal battery voltage. The technical documentation of the reTerminal E1001 shows that the voltage is measured using a voltage divider, so a filter must be applied to compensate for the halving of the voltage caused by this divider, which consists of two 10kΩ resistors.

The voltage across the internal battery indicates its charge level. A lithium battery is considered discharged if its voltage is below 3.3 V. A battery is fully charged when its voltage is above 4.0 V.

Internal battery voltage display

Displaying icons

I chose to display the icons using the materialdesignicons-webfont.ttf font instead of images. You’ll need to download this font and place it in the ESPHome fonts directory using a File Editor add-on, for example. To choose your own icons, you can use the pictogrammers.com website and note the reference number of the desired icon.

Next, you need to declare the glyphs corresponding to the icons in the font. Here, for example, on a font size of 20, we want to use the icons representing a battery, a water droplet, a thermometer, and a clock.

YAML
  - file: "fonts/materialdesignicons-webfont.ttf"
    id: icon_font_20
    size: 20
    glyphs:
      - "\U000F12A3" # battery
      - "\U000F058C" # water
      - "\U000F050F" # thermometer
      - "\U000F1442" # clock

Then you can display the icon from its code like this:

YAML
      it.printf(0, 0+85, id(icon_font_20), "\U000F050F");  // thermometer

Deep sleep

The reTerminal E1001 is configured to remain in deep sleep for 30 minutes. After these 30 minutes, it wakes up for 30 seconds to retrieve weather information and update its screen. It then returns to deep sleep for another 30 minutes.

This deep sleep mode is configured as follows in the ESPHome YAML configuration file:

YAML
# Deep sleep configuration to save power
deep_sleep:
  id: deep_sleep_1              # ID for deep sleep component
  run_duration: 30s             # Time to stay awake after wake-up
  sleep_duration: 30min         # Time to sleep between wake-ups
  wakeup_pin: GPIO3             # GPIO pin to wake up device
  wakeup_pin_mode: INVERT_WAKEUP # Inverted wake-up logic

Display refresh

When reTerminal wakes from deep sleep, it behaves the same way as during startup. Therefore, a precise sequence of events must be maintained. The reTerminal screen should only be refreshed once the data from the internal sensor and Home Assistant has been retrieved (Wi-Fi takes time to activate, and therefore Home Assistant data is not immediately available at boot).

Update the battery voltage measurement and the internal temperature and humidity sensor measurement at boot time:

YAML
esphome:
  name: reterminal-e1001
  friendly_name: reTerminal-e1001
  on_boot:
    priority: 600
    then:
      # Turn on the GPIO output that powers the battery measurement circuit
      - output.turn_on: bsp_battery_enable
      # Wait a short delay to allow power stabilization
      - delay: 500ms
      # Manually update battery sensors (voltage and percentage)
      - component.update: battery_voltage
      # Manually read the internal temperature/humidity sensor
      - component.update: sht4x_component  

Disable automatic updates (update_interval: never) for the ST4X internal sensor:

YAML
  # Internal SHT4x temperature/humidity sensor
  - platform: sht4x            # Sensor platform
    id: sht4x_component         # ID for the component
    temperature:                # Temperature sensor
      name: "Temperature"       # Sensor name
      id: sht4x_temperature     # ID for temperature sensor
    humidity:                   # Humidity sensor
      name: "Humidity"          # Sensor name
      id: sht4x_humidity        # ID for humidity sensor
    address: 0x44               # I2C address
    update_interval: never      # Disable automatic updates (manual read only)

Disable automatic screen refresh (update_interval: never):

YAML
display:
  - platform: waveshare_epaper
    id: epaper_display
    model: 7.50inv2
    cs_pin: GPIO10
    dc_pin: GPIO11
    reset_pin:
      number: GPIO12
      inverted: false
    busy_pin:
      number: GPIO13
      inverted: true
    update_interval: never

And finally, refresh the screen once Home Assistant data is received (for example on temperature0 update):

YAML
    # Daily sensors
  - platform: homeassistant
    id: temperature_d0
    entity_id: sensor.daily_weather_forecast_sensor
    attribute: temperature0
    on_value:
      then:
        # Refresh the e-paper display whenever this sensor updates
        - component.update: epaper_display           

Conclusion

Thanks to the reTerminal E1001 and its integration with Home Assistant, I finally have the perfect weather station to meet my needs. The ESPHome framework requires a short learning curve to grasp its principles, but once you’ve mastered them, it proves remarkably powerful and flexible.

The complete Home Assistant and ESPHome configuration used in this tutorial is available on my GitHub.

I hope you found this tutorial helpful. Feel free to share your feedback by clicking on the stars below or leaving a comment.

How useful was this post?

Click on a star to rate it!

Average rating 5 / 5. Vote count: 1

No votes so far! Be the first to rate this post.

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?