Temporarily display value on esp8266 connected oled

I had a nice little idea for a esp device with a small oled display to show the current audio volume.

Got it working in a very simple setup, just printing a value with Lambda to the display.

Ideally I would like to only show a value on the display when the value changes.
I have not found something similar in Lambda to the “hass_state” function but then for a change of state. Does that exist?

Thought about other solutions like triggering an automation when audio volume changes, start script, get value from Sonos and write that to an entity or something. But this all seems a bit complex for what I want to do.

So my question is, is there a way to only print/render a value with Lambda when it changes and then stop after a timed interval?
Or maybe in another way with automation/script?

Because you can only really use the print function in the display component, you need to use pages.

Define a page that is blank and one that prints your value. Then in the sensor that has the volume have a block similar to the below:

on_value:
  - display.page.show: page1 # your page with the value displayed
  - delay 5s
  - display.page.show: page2 # your blank page
1 Like

I asked a very similar question here and did what zoogara suggested above. It works pretty well, but what if I want to display more than two pages and cycle through them without constantly seeing the page with the volume sensor?

  1. Create a script: that continually displays the other pages at whatever interval you like. You can create infinite loops using while:. Any delay: is non blocking so the ESP will happily do other stuff.
  2. Start the script on boot.
  3. Change the above example to:
    a) stop the running script
    b) display the volume value
    c) delay for appropriate time
    d) start the script again

That’s an idea, thanks! I am not that good with esphome or scripting for that matter. Mind sharing a sample of code?

Assuming you place the on boot script under esphome like below.

esphome:
    name: display
    friendly_name: my display
    ...
    on_boot:
        then: 
            - script here

sensor:
     - platform: homeassistant
       id: volume
       on_value:
            - display.page.show: page1 # your page with the 
               value displayed
            - delay 5s
            - script: my_script
script:
     - script_name: my_script
       # script directive 

esphome:
  name: display
  friendly_name: my display
  on_boot:
    then: 
      - script.execute: display_script

sensor:
  - platform: homeassistant
    id: volume
    on_value:
      - script.stop: display_script
      - display.page.show: page1 # your page with the value displayed
      - delay: 5s
      - script.execute: display_script

script:
  - id: display_script
      while:
        condition: # forever...
          lambda: |-
            return true;  
      then:
        - display.page.show: page2 # your page with the other stuff
        - delay: 5s
        - display.page.show: page3 # etc...
        - delay: 5s

@zoogara This worked like a charm. Really awesome!!

Tp share my code, for any other noobs like me wanting to learn:

i2c:
  sda: D2
  scl: D1
  frequency: 1600kHz

display:
  - platform: ssd1306_i2c
    model: "SH1106 128x64"
    address: 0x3C
    update_interval: 0.1s
    pages:
      - id: page1
        lambda: |-
          it.printf(it.get_width(), 0, id(roboto), TextAlign::TOP_RIGHT, "%s", id(sonos_volume).state.c_str());
      - id: page2
        lambda: |-
          it.print(0,0, id(roboto), "");

font:
  - file:
      type: gfonts
      family: Roboto
      weight: 500
    id: roboto
    size: 64

text_sensor:
  - platform: homeassistant
    id: sonos_volume
    entity_id: sensor.sonos_volume
    internal: true
    on_value:
      - display.page.show: page1
      - delay: 5s
      - display.page.show: page2

The delay seems a little bit odd, sometimes it is actually arround 5 seconds, sometimes less then 1 second before page 2 shown all of a sudden. Still going by trail and error to see how to fix that.

thanks @zoogara, I’ll play with the script later today, looks very promissing

Solved the delay that seemed odd. What was happening was, everytime I change the volume level a new delay timestamp is added. So if I change the level a few times quickly, wait for the first delay to finish (empty page/display), change level again and it will show the volume level briefly and then a old delay will finish and turn to the empty page.

Well, I found a simple solution with a script:

display:
  - platform: ssd1306_i2c
    model: "SH1106 128x64"
    address: 0x3C
    update_interval: 200ms
    pages:
      - id: page1
        lambda: |-
          it.printf(it.get_width(), 0, id(roboto), TextAlign::TOP_RIGHT, "%s", id(sonos_volume).state.c_str());
      - id: page2
        lambda: |-
          it.print(0,0, id(roboto), "");

font:
  - file:
      type: gfonts
      family: Roboto
      weight: 500
    id: roboto
    size: 64

text_sensor:
  - platform: homeassistant
    id: sonos_volume
    entity_id: sensor.sonos_volume
    on_value:
      - script.stop: display_script
      - script.execute: display_script

script:
  - id: display_script
    then:
      - display.page.show: page1
      - delay: 5s
      - display.page.show: page2

Now, after each button press for changing the volume level the delay is reset. It will only go to the empty page 5 seconds after the last button press/volume level change.

below script is working as expected, but I am seeing a warning in the logs:

[W][script:060]: Script 'display_script' is already running! (mode: single).
script:
  - id: display_script
    then:
      - while: 
          condition:
            lambda: |-
              return true;
          then:
            - display.page.show: page2
            - delay: 5s
            - display.page.show: page3
            - delay: 5s
            - display.page.show: page4
            - delay: 5s

In the script add mode: restart.

I missed that when I wrote it earlier - sorry.

script:
  - id: display_script
    mode: restart

Thank you! That makes sense, I need to invest more time into my coding skills :slight_smile: