Print Sensor to LCD Screen

So I have one of those 16x2 LCD Displays. It’s connected to a nodemcu and it’s working and I can print simple text to it no problems.

What I want to be able to do is print a state from a sensor from Home Assistant.

My yaml looks like this:

esphome:
  name: node_lcd
  platform: ESP8266
  board: nodemcuv2

wifi:
  ssid: "MY-SSID"
  password: "MY-PASS"

  # Optional manual IP
  manual_ip:
    static_ip: 10.90.11.57
    gateway: 10.90.11.1
    subnet: 255.255.255.0
    
# Enable logging
logger:

# Enable Home Assistant API
api:

ota:

i2c:
  sda: D2
  scl: D1

display:
  - platform: lcd_pcf8574
    dimensions: 16x2
    address: 0x27
    lambda: |-
      it.print("Weather: %s", id(weather).state.c_str());
      it.print(1, 0, "Sun: %s", id(sun).state.c_str());

web_server:
  port: 80

text_sensor:
  - platform: homeassistant
    id: weather
    name: weather
    entity_id: weather.home
    internal: true
  - platform: homeassistant
    id: sun
    name: sun
    entity_id: sun.sun
    internal: true

My errors on compilation are:

src/main.cpp: In lambda function:
src/main.cpp:167:53: error: no matching function for call to 'esphome::lcd_base::LCDDisplay::print(const char [12], const char*)'
it.print("Weather: %s", weather->state.c_str());
^
src/main.cpp:167:53: note: candidates are:
In file included from src/esphome.h:16:0,
from src/main.cpp:3:
src/esphome/components/lcd_base/lcd_display.h:31:8: note: void esphome::lcd_base::LCDDisplay::print(uint8_t, uint8_t, const char*)
void print(uint8_t column, uint8_t row, const char *str);
^
src/esphome/components/lcd_base/lcd_display.h:31:8: note:   candidate expects 3 arguments, 2 provided
src/esphome/components/lcd_base/lcd_display.h:33:8: note: void esphome::lcd_base::LCDDisplay::print(uint8_t, uint8_t, const string&)
void print(uint8_t column, uint8_t row, const std::string &str);
^
src/esphome/components/lcd_base/lcd_display.h:33:8: note:   candidate expects 3 arguments, 2 provided
src/esphome/components/lcd_base/lcd_display.h:35:8: note: void esphome::lcd_base::LCDDisplay::print(const char*)
void print(const char *str);
^
src/esphome/components/lcd_base/lcd_display.h:35:8: note:   candidate expects 1 argument, 2 provided
src/esphome/components/lcd_base/lcd_display.h:37:8: note: void esphome::lcd_base::LCDDisplay::print(const string&)
void print(const std::string &str);
^
src/esphome/components/lcd_base/lcd_display.h:37:8: note:   candidate expects 1 argument, 2 provided
src/main.cpp:168:51: error: no matching function for call to 'esphome::lcd_base::LCDDisplay::print(int, int, const char [8], const char*)'
it.print(1, 0, "Sun: %s", sun->state.c_str());
^
src/main.cpp:168:51: note: candidates are:
In file included from src/esphome.h:16:0,
from src/main.cpp:3:
src/esphome/components/lcd_base/lcd_display.h:31:8: note: void esphome::lcd_base::LCDDisplay::print(uint8_t, uint8_t, const char*)
void print(uint8_t column, uint8_t row, const char *str);
^
src/esphome/components/lcd_base/lcd_display.h:31:8: note:   candidate expects 3 arguments, 4 provided
src/esphome/components/lcd_base/lcd_display.h:33:8: note: void esphome::lcd_base::LCDDisplay::print(uint8_t, uint8_t, const string&)
void print(uint8_t column, uint8_t row, const std::string &str);
^
src/esphome/components/lcd_base/lcd_display.h:33:8: note:   candidate expects 3 arguments, 4 provided
src/esphome/components/lcd_base/lcd_display.h:35:8: note: void esphome::lcd_base::LCDDisplay::print(const char*)
void print(const char *str);
^
src/esphome/components/lcd_base/lcd_display.h:35:8: note:   candidate expects 1 argument, 4 provided
src/esphome/components/lcd_base/lcd_display.h:37:8: note: void esphome::lcd_base::LCDDisplay::print(const string&)
void print(const std::string &str);
^
src/esphome/components/lcd_base/lcd_display.h:37:8: note:   candidate expects 1 argument, 4 provided
*** [/data/nick_lcd/.pioenvs/nick_lcd/src/main.cpp.o] Error 1

I am simply wanting to print the weather state and the sun state…
ie Weather: sunny
sun: above_horizon
image

This code:

display:
  - platform: lcd_pcf8574
    dimensions: 16x2
    address: 0x27
    lambda: |-
      it.print("Weather");
      it.print(0, 1, "Sun");

Just prints 2 lines without the state but it works…

ok… this seems to work:

it.printf(0, 0, "Sun: %s", id(sun).state.c_str());

So now I can talk to it, I want to use a sensor state in Home Assistant (say the state will be On or Off) to trigger a countdown timer… say 60 seconds and then for the display to show that timer value.

I think that’s probably not too hard… has anyone done anything like that?

I haven’t done it but I would imagine it should be easy enough. Do you want to have that countdown timer value adjustable? That could complicate things a little but maybe try the below as a start

I’d imagine you can use theHome Assistant binary_sensor to retrieve the on/off from HA and use that to trigger an ESPhome automation to count down a global variable. You would then use code similar to what you have already to display the value of that global variable.

Not immediately obvious how to trigger the countdown…

Could potentially use a HA automation to trigger a switch on the nodemcu as well maybe? Not sure how to add the switch to esphome though either…

I think you would use this, but replace platform: gpio with platform: homeassistant and then specify your HA entity that was to be switching to ‘on’

Alternative method is to de-couple the nodeMCU and have it simply be a reporter of an MQTT topic you send it.

Then you can use automations in HASS to update the “print on my MCU” MQTT topic to whatever you want.

Keeps the logic in HASS with the MCU simply always showing what it is told.

This is what I did (in the olden days of arduino coding) here

Thanks Phil… while I love MQTT, this particular project doesn’t use it - only esphome.

It doesn’t appear like it’s that hard to do this in esphome but it’s a bit of a foreign language in there and not that intuitive to me.

Actually I’m not even 100% sure how I would do a countdown timer in Home Assistant anyway…

I’m quite interested in this little project of yours so you have me hooked now… (and I’m away from home so can’t tinker :smirk: )

You could probably use the timer component in HA and then read that with the ESP HA sensor. From there you would use your existing code to display the variable (the timer value) and the idea I had above to use that value to trigger an ESPhome automation

I don’t think the timer will do it. I want to run a pump for 60 seconds and have the screen display if the pump is on or off and if On I want it to count down from 60 seconds until it turns off. There’s actually 2 pumps - so one line for each pump…

There are counters and delays in Esphome - I just can’t figure out how to put all the pieces together mainly because I don’t get the logic of esphome really - this is the first thing I have tried to do with it other than toying with it for some basic switches a while ago which had me heading back to Tasmota again after I couldn’t do some pretty simple things in a logical manner…

Just in case you hadn’t seen it, there is a whole section on time here https://esphome.io/components/time.html

Forgive me if it is unhelpful, or already mentioned. I am in the middle of cooking dinner, and the water has just gone off. Hard to cook rice…

If I get some time in the next day or so I’ll try and right up some code to test

1 Like

Appreciate any help. Thanks.

Hey David…

I would start creating int globals, one for each pump
In your switch (I believe I would use a template switch optimistic) the on turn on action would set this global variable to e.g. 60

then there will be an interval: setup, to run every second, in this interval I check the value of the global and decremented by 1 if it is bigger than 1.

Let us know if you need more specific info. Try to put together these ideas in code so we can start working on there.