Export Real Time data from home assistant to LCD display

Hello,

I am working on a project where I need to display real-time data from ‘‘Home Assistant’’ onto an ‘‘LCD screen’’. I am looking for an efficient and time-saving approach to achieve this.

Could someone suggest the best method to accomplish this with minimal delay and complexity?

You have a few options - these are just the ones that I have tried:

  • Fully Kiosk browser using an old Android tablet - just uses the standard HA dashboard: Fully Kiosk Browser - Home Assistant
  • ESPHome as detailed above. This tends to top out at 7 inch screen size, here’s an example: Waveshare ESP32-S3-Touch-LCD-7
  • Some also use a larger touchscreen display with a Raspberry Pi - like these from Amazon. Helps to have a Pi spare otherwise it gets expensive: Amazon.com

I’m not sure what you mean by the quotes on “Home Assistant” and “LCD screen.”

Hopefully the posts before me point you towards a high-level solution. If not, though, you need to be more specific about what “real-time data” and what “LCD screen,” and how, if at all, it’s connected to Home Assistant. Without that information, it’s hard to point you in a direction that’s specific to what you need.

Welcome to the forum. There are many people here who try very hard to help newcomers, and you should be able to find the assistance you need here.

Hi, thanks for following my question!

By real-time data, I mean the current status of the battery as displayed on Home Assistant, including battery power, voltage, wind, and current sensor readings. My project is to display this information on an LCD screen.

To do this, I am using a microcontroller that retrieves the data from Home Assistant and updates the LCD. Furhermore, I would like to tell you that access to Home Assistant is secured with some private credentials.

I want to make sure the LCD updates properly as the data changes in Home Assistant. Any advice on how to achieve this smoothly?

Thanks in advance

I’m using ESPHome to display the measurements of an outdoor sensor to display temperature and humidity on a TTGO-Display.

esphome:
  name: display-1

esp32:
  board: featheresp32

font:
  - file: 'slkscr.ttf'
    id: font_slkscr_8
    size: 8
#    glyphs: [!%()+,-/_.:°0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz]
  - file: 'slkscr.ttf'
    id: font_slkscr_16
    size: 16
#    glyphs: [!%()+,-/_.:°0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz]
  - file: 'BebasNeue-Regular.ttf'
    id: font_bebas_48
    size: 48
  - file: 'arial.ttf'
    id: font_arial_12
    size: 12


color:
  - id: color_white
    red: 1
    green: 1
    blue: 1
  - id: color_red
    red: 1
    green: 0
    blue: 0
  - id: color_green
    red: 0
    green: 1
    blue: 0
  - id: color_blue
    red: 0
    green: 0
    blue: 1
  - id: color_orange
    red: 1
    green: 0.6
    blue: 0
  - id: color_yellow
    hex: ffff00
  - id: color_dark_orange
    hex: ff8c00     
  - id: color_teal_blue
    red: 0
    green: 0.5
    blue: 0.45
  - id: color_tomato
    hex: FF6347
  - id: color_whiskey
    hex: d29062    
  - id: color_dark_pink
    hex: cb416b
  - id: color_grape
    hex: 5d1451
  - id: color_lavender
    hex: d5c9dd
  - id: color_arctic_blue
    hex: 95d6dc
  - id: color_sapphire
    hex: 09577B         
  - id: color_light_blue
    hex: add8e6

# Enable logging
logger:
  level: DEBUG

# Enable Home Assistant API
api:
  encryption:
    key: "kaLYjSYIg3WK91mgfgWlnjhtUq/KuUOB/L3fEhUA/8c="

ota:
  platform: esphome
  password: "eb0056095af6c6bdbe204b22bfb4adc3"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  domain: ".fritz.box"
  fast_connect: True
  
# Optional manual IP
  manual_ip:
    static_ip: 192.168.178.95
    gateway: 192.168.178.1
    subnet: 255.255.255.0
    dns1: 192.168.178.1

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Display-1 Fallback Hotspot"
    password: "xfoC8woX5yd9"

captive_portal:

web_server:
  port: 80

spi:
  clk_pin: GPIO18
  mosi_pin: GPIO19

time:
  - platform: homeassistant
    timezone: Europe/Berlin
    id: esptime

binary_sensor:
  - platform: template
    name: "Display Power State"
    lambda: |-
      if (id(vcc).state > 4.3) {
        // Power is On.
        return true;
      } else {
        // Power is Off.
        return false;
      }

sensor:
  - platform: homeassistant
    id: bthome_sensor_094e_temperature
    entity_id: sensor.bthome_sensor_b5a3_temperature
    unit_of_measurement: '°C'
  - platform: homeassistant
    id: bthome_sensor_094e_voltage
    unit_of_measurement: 'V'
    entity_id: sensor.bthome_sensor_b5a3_voltage
  - platform: homeassistant
    id: bthome_sensor_094e_humidity
    entity_id: sensor.bthome_sensor_b5a3_humidity
    unit_of_measurement: '%'

  - platform: adc
    pin: 34
    accuracy_decimals: 2
    attenuation: auto #11db
    name: VBatt
    id: vcc
    update_interval: 60s
    filters:
      - multiply: 2.0  # The voltage divider requires us to multiply by 2

  - platform: template
    name: batterylevel
    id: batterylevel
    unit_of_measurement: '%'
    update_interval: 60s
    lambda: |-
      // I know infering the battery from voltage only is misleading, but I'll take it. Considering linear decay (again, i'll take it), max=2.23, min=1.38
      // battery_percentage = 100 * (adc - BATTERY_MIN_ADC) / (BATTERY_MAX_ADC - BATTERY_MIN_ADC);
      if (id(vcc).state > 4.3) {return 101;} 
      else {return (100*(id(vcc).state-3.3)/(4.2-3.3));}
    on_value:
      then:
        - lambda: |-
            if (id(vcc).state < 4.3) {
              auto call = id(back_light).turn_on();
              call.set_brightness(id(batterylevel).state/100);
              call.perform();
              }
            else {
              auto call = id(back_light).turn_on();
              call.set_brightness(1.0);
              call.perform();            
              }
#            ESP_LOGI("display-1", "Value of batterylevel: %f", id(batterylevel).state);
#            ESP_LOGI("display-1", "Value of backlight: %f", id(back_light).current_values.get_brightness());
#        - light.dim_relative: 
#          id: gpio_04_backlight_pwm
#          level: batterylevel.state

# Define a PWM output on the ESP32
output:
  - platform: ledc
    pin: GPIO04
    id: gpio_04_backlight_pwm

# Define a monochromatic, dimmable light for the backlight
light:
  - platform: monochromatic
    output: gpio_04_backlight_pwm
    name: "Display Backlight"
    id: back_light
    restore_mode: RESTORE_AND_ON
          
# TODO brightness
display:
  - platform: ili9xxx
    model: st7789v
    #TTGO TDisplay 135x240
    dimensions:
      height: 240
      width: 135
      offset_height: 40
      offset_width: 52
    # Required or the colors are all inverted, and Black screen is White
    invert_colors: true
    cs_pin: GPIO5
    dc_pin: GPIO16
    reset_pin: GPIO23
    rotation: 90°
    update_interval: 15s
    lambda: |-
      // comment
      if (id(vcc).state < 4.3) {it.printf(4, 4, id(font_slkscr_16), id(color_teal_blue), "%.1f VBat (%.1f%%)", id(vcc).state, id(batterylevel).state);}
      else {it.printf(4, 4, id(font_slkscr_16), id(color_teal_blue), "%.1f VIn (Charging)", id(vcc).state);}

      it.strftime(180, 16, id(font_slkscr_16), id(color_teal_blue), TextAlign::BASELINE_LEFT, "%H:%M", id(esptime).now());
      it.printf(16, 18, id(font_bebas_48), id(color_white), "Temp");
      it.printf(120, 18, id(font_bebas_48), id(color_white), "Humi");

      if(id(bthome_sensor_094e_temperature).has_state()) {
        float temp = id(bthome_sensor_094e_temperature).state;
        if (temp > 24.0) {it.printf(16, 72, id(font_bebas_48), id(color_tomato), "%.1f°" ,id(bthome_sensor_094e_temperature).state);}
        else if (temp > 18.0) {it.printf(16, 72, id(font_bebas_48), id(color_whiskey), "%.1f°" ,id(bthome_sensor_094e_temperature).state);}    
        else if (temp > 12.0) {it.printf(16, 72, id(font_bebas_48), id(color_dark_orange), "%.1f°" ,id(bthome_sensor_094e_temperature).state);} 
        else if (temp > 6.0) {it.printf(16, 72, id(font_bebas_48), id(color_dark_pink), "%.1f°" ,id(bthome_sensor_094e_temperature).state);} 
        else if (temp = 0.0) {it.printf(16, 72, id(font_bebas_48), id(color_lavender), "%.1f°" ,id(bthome_sensor_094e_temperature).state);} 
        else if (temp > -5.0) {it.printf(16, 72, id(font_bebas_48), id(color_arctic_blue), "%.1f°" ,id(bthome_sensor_094e_temperature).state);} 
        else {it.printf(16, 72, id(font_bebas_48), id(color_sapphire), "%.1f°" ,id(bthome_sensor_094e_temperature).state);} 
      }  
      if (id(bthome_sensor_094e_humidity).has_state()) {
        float humi = id(bthome_sensor_094e_humidity).state;
        if (humi > 60.0) {it.printf(120, 72, id(font_bebas_48), id(color_light_blue), "%.1f%%", id(bthome_sensor_094e_humidity).state);} 
        else if (humi > 40) {it.printf(120, 72, id(font_bebas_48), id(color_green), "%.1f%%", id(bthome_sensor_094e_humidity).state);}        
        else {it.printf(120, 72, id(font_bebas_48), id(color_yellow), "%.1f%%", id(bthome_sensor_094e_humidity).state);}        
      }

text_sensor:
  - platform: version
    name: "ESPHome Version"     

number:
  - platform: template
    <<: *AnchorDelay
    id: "SwitchMainDelay"
    name: "Main Switch Delay"    
  - platform: template
    <<: *AnchorDelay
    id: "SwitchAuxDelay"
    name: "Aux Switch Delay"    

I have found most of the building blocks here in the forum, thank you to all contributors.

Hi there, i used your code and get:

INFO ESPHome 2025.3.3
INFO Reading configuration /config/esphome/esphome-web-f64b34.yaml…
ERROR Error while reading config: Invalid YAML syntax:

found undefined alias ‘AnchorDelay’
in “/config/esphome/esphome-web-f64b34.yaml”, line 243, column 9

any ideas, no worries if you don’t ))

I forgot to delete those lines. They are leftovers from some tests i did. Just delete all lines at the end after number: (incl.)

Thank you !