Pass an object to script?

Is it possible to pass an object (e.g. the ‘it’ display buffer obj) to an ESPHome script?

The goal is to factor-out some common logic in display pages’ lambdas so that the same block of code doesn’t have to be repeated in each page’s lambda. But that logic depends on having access to ‘it’.

First thought was to have ‘it’ get stored in a ‘globals:’ variable, but of what type, and is that even allowed?

I was experimenting with this a few days ago. I found out that you can assign an id to your display. For example id: my_display. Then you can use that id as a pointer in the lambda of a script. For example my_display->print("Hello");. You can try that.

Works great - Thanks!

Have a look at how I factored out common logic for pages in my ESPHome air quality monitor:

I have something like this in the lambda for each page:

display:
  - platform: st7789v
    id: ttgo_tdisplay
    backlight_pin: GPIO4
    cs_pin: GPIO5
    dc_pin: GPIO16
    reset_pin: GPIO23
    rotation: 270
    pages:
      - id: page1
        lambda: |-
          drawHeader(it, id(color_blue));
          showCalibration(it, id(roboto_12), id(color_yellow), id(color_red), id(co2_calibrate), id(co2_calibrated));
          showStatus(it, id(roboto_12), id(color_green), id(color_red), id(system_status));
          it.printf((240 / 2), (110 / 3) * 1 + 5, id(roboto_24), id(color_gray), TextAlign::CENTER, "CO2: %.0f ppm", id(co2_value).state);
          it.graph(0, 60, id(co2_graph));

I include the helper functions in a header file:


esphome:
  includes:
    - include/display_utilities.h

And then the header file looks like this:

#include "esphome.h"

// Draw header and frame
void drawHeader(esphome::display::DisplayBuffer& it, esphome::Color color) {
    it.rectangle(0,  0, it.get_width(), it.get_height(), color);
    it.rectangle(0, 20, it.get_width(), it.get_height(), color);
}

// Show calibration state at the left
void showCalibration(esphome::display::DisplayBuffer& it, esphome::display::Font* font, esphome::Color color_info, esphome::Color color_nok, esphome::switch_::Switch* co2_calibrate, esphome::binary_sensor::BinarySensor* co2_calibrated) {
    if ((*co2_calibrate).state) {
        it.print(5, 5, font, color_info, esphome::display::TextAlign::TOP_LEFT, "Calibrating...");
    }
    else if (!(*co2_calibrated).state) {
        it.print(5, 5, font, color_nok, esphome::display::TextAlign::TOP_LEFT, "Calibrate");
    }
}

// Show connection state at the right
void showStatus(esphome::display::DisplayBuffer& it, esphome::display::Font* font, esphome::Color color_ok, esphome::Color color_nok, esphome::binary_sensor::BinarySensor* system_status) {
    if ((*system_status).state) {
        it.print(it.get_width() - 5, 5, font, color_ok, esphome::display::TextAlign::TOP_RIGHT, "Online");
    }
    else {
        it.print(it.get_width() - 5, 5, font, color_nok, esphome::display::TextAlign::TOP_RIGHT, "Offline");
    }
}

You can find the right types of the objects to refer to in your functions in the ESPHome API reference.

2 Likes