Using local variables (globals)

I can’t find any useable information about using local variables in esphome.
What i’m trying to achieve is this:
I have sonoff D1 dimmer. I’d like to use local INT variable to store current dimm position (as value 1, 2 or 3): i intend to dimm only to 3 predefined values with a button (1%, 25% and 100%).

My local variable (global) is “dim_vrednost” and it’s INT type.

For that i would very much like to know:

  • how to check if a variable has a certain value in IF sentence? I wrote like this:
  - if:
      condition: 
        lambda: 'return (id(dim_vrednost) == 0);'
    then:

  • how to set a value to variable?
    i did it like this:
- lambda: |-
    id(dim_vrednost) = (1);

Of course it doesn’t work…

  • third thing:
    HOW to send a local variable in to logger.log?

Ok, after extensive search (and try-and-error) i found “kinda” solution which works. I used multiple boolean variables (dim_1. dim_25 and dim_100), so i used this as condition

if:
  condition: #if dimm value is at 1% then global dim_1 is set
    lambda: |-
        ESP_LOGD("Stanje", "Bool1: %d", id(dim_1));
        return id(dim_1);
  then:
    ...

where “dim_1” is my variable, i set that one when i have my light at 1%, i succesfully set a value with this command:

- lambda: |-
     id(dim_1)=(0);

I also can send those boolean globals to logger with

lambda: |-
   ESP_LOGD("Stanje", "Bool1: %d", id(dim_1));

But, i still don’t know

  • how to set a value to integer global
  • how to correctly write an “IF” sentence with INT global.
  • how to send INT global to logger.

So, any advice would still be very welcome! And i apologize - i’m sure that these things are pure basics for you, skilled guys…but they are pretty unfamiliar to me - i’m programming Bascom only…, C, yaml and similar… that i’m still learning…

The docs:

Your if condition looks like it should work, although the documentation omits the brackets. Your first post’s indentation was off between condition and then, which should be aligned:

- if:
    condition: 
      lambda: 'return id(dim_vrednost) == 0;'
    then:

If you’re trying to set it to 1, don’t include the brackets.

- lambda: |-
    id(dim_vrednost) = 1;

For the logger:

Here’s the (long) code that’s running my room temperature sensor and display, that includes an example of everything you’re asking about:

captive_portal:

time:
  - platform: homeassistant
    id: the_time
    on_time:
      seconds: /3
      then:
        - script.execute: line2_cycle

# Enable logging
logger:

# Enable Home Assistant API
api:
  password: "xyzzy"
  reboot_timeout: 
    minutes: 4

ota:
  password: "xyzzy"

globals:
  - id: temp_bar
    type: int
    restore_value: no
    initial_value: '0'
  - id: over_temp
    type: bool
    restore_value: no
    initial_value: 'false'
  - id: under_temp
    type: bool
    restore_value: no
    initial_value: 'false'
  - id: line2
    type: int
    restore_value: no
    initial_value: '0'

switch:
  - platform: gpio
    pin:
      number: D4
      inverted: yes
    name: "Hall sensor onboard LED"
    id: "onboard_led"
    internal: true

  - platform: restart
    name: "Hall sensor restart"

dallas:
  pin: D5
  update_interval: 30s

sensor:
  - platform: dallas
    address: 0xf40316813883ff28
    name: "Hall temperature"
    unit_of_measurement: "°C"
    icon: "mdi:thermometer"
    id: the_temp
    filters:
      sliding_window_moving_average:
        window_size: 4
        send_every: 1
    on_value:
      then:
        - script.execute: bar_script

  - platform: homeassistant
    name: "Target CH temperature"
    entity_id: sensor.central_heating_target_temperature
    id: target_temp
    internal: true
    on_value:
      then:
        - script.execute: bar_script

  - platform: homeassistant
    name: "Outside temperature"
    entity_id: sensor.outside_temperature
    id: external_temp
    internal: true

  - platform: homeassistant
    name: "Outside humidity"
    entity_id: sensor.outside_humidity
    id: external_hum
    internal: true

  - platform: homeassistant
    name: "LEAF battery"
    entity_id: sensor.leaf_battery_percentage
    id: leaf_batt
    internal: true

  - platform: homeassistant
    name: "LEAF GOM"
    entity_id: sensor.leaf_gom
    id: leaf_gom
    internal: true

  - platform: homeassistant
    name: "Screen brightness"
    entity_id: sensor.hall_screen_brightness
    id: screen_bright
    internal: true
    on_value:
      then:
        - lambda: |-
            id(the_display).set_brightness(id(screen_bright).state);
            // id(the_display).setup();
        - logger.log:
            format: "Setting display brightness to %.2f."
            args: ['id(screen_bright).state']

  - platform: wifi_signal
    name: "Hall sensor wifi signal"
    update_interval: 60s

binary_sensor:
  - platform: homeassistant
    name: "Day Night CH setting from HA"
    entity_id: binary_sensor.heating_daytime
    id: ch_day
    internal: true
        
  - platform: homeassistant
    name: "CH Run from HA"
    entity_id: switch.chc_central_heating_relay
    id: ch_run
    internal: true

  - platform: homeassistant
    name: "HW Run from HA"
    entity_id: switch.chc_gas_water_heating_relay
    id: hw_run
    internal: true
    
  - platform: homeassistant
    name: "LEAF connected"
    entity_id: binary_sensor.leaf_connected
    id: leaf_conn
    internal: true

  - platform: status
    name: "Hall sensor status"

text_sensor:
  - platform: homeassistant
    name: "CH mode"
    entity_id: climate.central_heating
    id: ch_mode
    internal: true

script:
  - id: line2_cycle
    then:
      - lambda: |-
          id(line2) += 1;
          if (id(line2) == 3) {
            id(line2) = 0;
          }

  - id: bar_script
    then:
      # calculates the width of the thermometer bar
      - lambda: |-
          id(over_temp) = false;
          id(under_temp) = false;
          id(temp_bar) = int(60 - (120.0 * (id(target_temp).state - id(the_temp).state)));
          if(id(temp_bar) > 120) {
            id(temp_bar) = 120;
            id(over_temp) = true;
          }
          if(id(temp_bar) < 0) {
            id(temp_bar) = 0;
            id(under_temp) = true;
          }
      - logger.log:
          format: "Setting temp bar width to %d. (%.2f, %.2f)"
          args: ['id(temp_bar)', 'id(the_temp).state', 'id(target_temp).state']

font:
  - file: "UbuntuMono-R.ttf"
    id: big_font
    size: 36
    glyphs: "0123456789.°C"
  - file: "UbuntuMono-R.ttf"
    id: med_font
    size: 24 
# custom from Fontello. A fire B sun C moon D off E drop
  - file: "hall-display.ttf"
    id: icon_font
    size: 16
    glyphs: "ABCDE "

i2c:
  sda: D2
  scl: D1
  scan: false

display:
  - platform: ssd1306_i2c
    model: "SH1106 128x64"
    address: 0x3C
    id: the_display
    brightness: 0.5
    update_interval: 3s
    lambda: |-
      if (id(screen_bright).state == 0.0) {
        it.fill(COLOR_OFF);
      } else {
        // print the temperature
        it.printf(0, 0, id(big_font), "%.1f°C", id(the_temp).state);
  
        // cycle between the time and the external temperature. line2 variable
        // is cycled as a time automation above.
        if (id(line2) == 0) {
          it.strftime(0, 32, id(med_font), "%H:%M", id(the_time).now());
        } else {
          if (id(line2) == 1 ) {
            it.printf(0, 32, id(med_font), "%.1f°C %.0f%%", id(external_temp).state, id(external_hum).state);
          } else {
            it.printf(0, 32, id(med_font), "%.0f%% %.0fmi", id(leaf_batt).state, id(leaf_gom).state);
          }
        }
  
        // also on line 2 with clock, the mode icons drop/blank, flame/blank and sun/moon; or an off icon. A fire B sun C moon D off E drop
        if (id(line2) == 0) { 
          if (id(ch_mode).state == "heat") {
            it.printf(122, 36, id(icon_font), TextAlign::TOP_RIGHT, "%s%s%s", id(hw_run).state ? "E" : " ", id(ch_run).state ? "A" : " ", id(ch_day).state ? "B" : "C");
          } else {
            it.printf(122, 36, id(icon_font), TextAlign::TOP_RIGHT, "%s D", id(hw_run).state ? "E" : " ");
          }
        }
  
        // temperature "scale" ranging from target +/- 0.5°C across 120px.
        // target at 60px (unmarked), 12px = 0.1°C
        // tolerance / hysteresis arrows are from hot_tolerance and cold_tolerance
        //   settings in HA, which are not exposed to ESPHome :(
  
        // low-end arrow, 0.1°C below target
        it.line(48,59,48,63);
        it.line(48,59,52,63);
        it.line(48,63,52,63);
  
        // high-end arrow, 0.1°C above target
        it.line(72,59,72,63);
        it.line(72,59,68,63);
        it.line(72,63,68,63);
  
        // the line: length is a global set in a script above
        it.line(1,61,id(temp_bar),61);
  
        // if we're off the scale high, draw an arrow pointing right; similar if off-low
        // otherwise, draw a small blob at current temperature
        if(id(over_temp)) {
          it.line(118,59,120,61);
          it.line(118,63,120,61);
        } else if (id(under_temp)) {
          it.line(2,59,0,61);
          it.line(0,61,3,61);
          it.line(2,63,0,61);
        } else {
          it.filled_circle(id(temp_bar),61,2);
        }
      } 
3 Likes

@Troon : thanks a lot for this! It’s very educational and indeed it contains pretty much all i need, even more (for the future).
I did try with logger.log and args declaration, but i’m not sure why i’ve got errors when compiling, so i gave up (too soon…). I’ll try again in the evening, when i’ll have some time. If i found correct info those arguments (%f…) are taken from python, right?
Now picture is slowly getting more clear… i like to understand what i’m doing, not just blindly copy/paste stuff, that’s why i’m asking. But it’s pretty hard, since there’s tons of stuff to remember and learn.