Display / dynamic path to image?

Hy all from Germany :slight_smile:

I have a little Display and have a problem…
On the Display, i show the zodiacsigns… therefor, i have a sensor, that takes the sign from HA

text_sensor:
  - platform: homeassistant
    name: "sternzeichen"
    id: sternzeichen
    entity_id: sensor.zodiac
    internal: True

The value is for example “taurus”

Then i defined the image:

- file: "images/sternzeichen/taurus.png"
    id: taurus
    resize: 150x150
    type: RGB24

Last i check the state and show the image:

if (id(sternzeichen).state == "taurus") {
            it.image(37, 2, id(taurus));

That all works… but because there are 12 different zodiacsigns, i have to make 12 checks for the sign… thats a lot of code and i am wondering, if there is a shorter way…?

So the state of the sensor is “taurus”, the id of the image is “taurus” and the name of the image is “taurus.png”…

Is there a way to make it dynamic ? like

it.image(37, 2, id($zodiacsign));

Hope for help :slight_smile:

Greetz
Günni

I was just trying to do something similar yesterday - I had a ESPHome service defined - and I planned to pass the id of a display page to it.

Could not get it to work, the closest I came was:

        - display.page.show: !lambda |-
            return id("${page}");

Which gave the compile error:

/config/esphome/weather.yaml: In lambda function:
/config/esphome/weather.yaml:26:16: error: invalid conversion from 'char' to 'esphome::display::DisplayPage*' [-fpermissive]
             return id("${page}");
              ~~^~~~~~~~~~~

So it looks like you need to be able to somehow cast a string or char to an id. If you get it to work I will be interested.

I tried to work with substitions…

When i define on the top of the esp-file

substitutions:
  zodiacsign: !include zodiacsign.yaml

(inside the zodiacsign.yaml is just the name of the zodiacsign, now “taurus”)
i can use $zodiacsign in the path…

it.image(37, 2, id($zodiacsign));

The problem is, i have found no way to read in the zodiacsign.yaml, when the zodiac changes…
i have to flash the esp32 to re-read the zodiacsign.yaml with !include…

I didn’t try it myself, but would something like this work:

- file: "images/sternzeichen/"+sternzeichen+".png"
    id: sternzeichenpicture
    resize: 150x150
    type: RGB24

it.image(37, 2, id(sternzeichenpicture));

No, it doesn’t work… :frowning:

- file: "images/sternzeichen/"+sternzeichen+".png"

marks the file with red dots with text “while parsing a block mapping”

- file: "images/sternzeichen/"+id(sternzeichen)+".png"

same

- file: "images/sternzeichen/"+id(sensor.zodiac)+".png"

same

:frowning:

Does anyone has another idea…?

I did have a quick search about this, and as I understand it now the ESPHome Display component currently only supports static images that are downloaded on the device during flashing.
Please correct me when this is incorrect.

However, it looks like there is an dynamic image support in the making.
See this Pull request: Add runtime online image support #4710
So may be in the near future there will be a dynamic image option for ESPHome?

I know this is a bit of a necro but I found this post while attempting to solve the same problem. I finally got it working, the solution is pass the image pointer to the function - the function needs to be defined to accept esphome::image::Image*. Below is a simplified version of my code.

I haven’t touched C++ since freshmen college so apologies if any of my terminology is off.

image:
  - file: mdi:microphone-off
    id: img_microphone_off
    resize: 60x60

  - file: mdi:microphone
    id: img_microphone_on
    resize: 60x60

  - file: mdi:phone-classic
    id: img_meeting_on
    resize: 60x60


# 1.14 inch, 135*240 Colorful TFT LCD, ST7789v2
display:
  - platform: st7789v
    model: TTGO TDisplay 135x240
    cs_pin: GPIO5
    dc_pin: GPIO14
    reset_pin: GPIO12
    lambda: |-
      int current_offset = 20;      
      int image_offset = 75; // height + buffer
      float horizontal_offset = 37.5;

      // Retrieve state of devices
      bool b_audio_on = id(audio_on).state;
      bool b_video_on = id(camera_on).state;
      bool b_meeting_on = id(in_meeting).state;

      // Helper function to draw an image at the next position
      auto drawImage = [&](int &current_offset, esphome::image::Image* image) {
        it.image(horizontal_offset, current_offset, image);
        current_offset += image_offset; // Increase offset after drawing
      };

      drawImage(current_offset, id(img_meeting_on));
      drawImage(current_offset, b_audio_on ? id(img_microphone_on) : id(img_microphone_off));
3 Likes