API Connection state in lambda

Hi!
I’m trying to implement a display with infos regarding the api state. It should display something like online/offline. For this i’m using a lambda. But I’m unable to get it to work as I can not find the correct command. This is what I have:

display:
  - platform: ssd1306_i2c
    model: "SSD1306 128x64"
    address: 0x3C
    update_interval: 2s
    lambda: |-
      if (api.connected()) {
      it.printf(127, 0, id(font3), TextAlign::TOP_RIGHT, "online");
      }
      else {
      it.printf(127, 0, id(font3), TextAlign::TOP_RIGHT, "offline");
      }

which produces this compilation error

src/main.cpp: In lambda function:
src/main.cpp:678:14: error: expected primary-expression before '.' token
       if (api.connected()) {
              ^

So api.connected() is not correct. Can anyone give me a tip how to correct this?

Cheers
James

Try just:

   if(api.connected){
     ...
   }

I would use the status binary_sensor with a lambda, doesn’t that work?

@jocnnor
No that does not work unfortunately.

@truglodite
Yes thank you that seems to work!

binary_sensor:
  - platform: status
    name: "Statussensor"
    id: statussensor
[...]
display:
  - platform: ssd1306_i2c
    model: "SSD1306 128x64"
    address: 0x3C
    update_interval: 2s
    lambda: |-
      if (id(statussensor).state) {
      it.printf(127, 0, id(font3), TextAlign::TOP_RIGHT, "online");
      }
      else {
      it.printf(127, 0, id(font3), TextAlign::TOP_RIGHT, "offline");
      }
4 Likes

HOW is that a solution if you don’t reference api.connected in your configuration?
All you’re doing here is getting the value of your binary sensor “statussensor” which has nothing to do with api.connected or the api state.
This is a false solution.
I have duplicated it. Because it seems to report along the lines what you would expect, it fools you into thinking it works.

I figured out a real solution, outside of lambda, outside of display:

      - if:
          condition:
            api.connected:
          then:
            - lambda: 'id(displaytext2).publish_state("api on");'     # to my oled display
          else:
            - lambda: 'id(displaytext2).publish_state("api off");' 

REMEMBER that logger: log output counts as api client as well as your Home Assistant instance, so kill log output when testing for negative, and disconnect your connection externally to your hassio or that will count as a client too. I just unplug ethernet and/or rename wifi temporarily to prevent logger.
Display, for reference:

display:                                 
  - platform: ssd1306_i2c                 
    model: "SSD1306 128x64"
#    reset_pin: D0
    address: 0x3C      
    lambda: |-
      it.printf(0, 40, id(myfont14), "State: %s", id(displaytext2).state.c_str());   

The same can be used for the wifi.connected: state.

3 Likes

Okay, the real solution I just picked from esphome source code is: global_api_server->is_connected()

Important notice: it returns false if there are no connected API clients. Possible clients are Home Assistant and esphome logs (can be more). So if you watch esphome’s logs from your local machine and your Home Assistant gets disconnected, you still see that global_api_server->is_connected() == true (and api.connected condition is true).

3 Likes