Esphome check if sun is below horizon in lambda function

Hi,

I’m trying to set icons for the night on my display. I need to check if the sun is below horizon to display night icons. I’m using the sun component, but get errors compiling

The error I get

ha-panel.yaml: In lambda function:
ha-panel.yaml:1154:19: error: 'class esphome::sun::Sun' has no member named 'is_below_horizon'

Here the config

sun:
  latitude: 51.521159
  longitude: 4.271538
  id: my_sun

  - platform: template
    id: weather_condition_icon
    lambda: |-
      std::string state = id(ha_weather_cond).state.c_str();

      if (id(my_sun).is_below_horizon()) {
        if (state == "SUNNY") {
          return std::string("$night");
        } else if (state == "PARTLYCLOUDY") {
          return std::string("$nightpartlycloudy");
        }
      }

      if (state == "RAINY") { return std::string("$rainy"); }
      else if (state == "CLOUDY") { return std::string("$cloudy"); }
      else if (state == "PARTLYCLOUDY") { return std::string("$partlycloudy"); }
      else if (state == "SUNNY") { return std::string("$sunny"); }
      else if (state == "FOG") { return std::string("$fog"); }
      else if (state == "HAIL") { return std::string("$hail"); }
      else if (state == "HAZY") { return std::string("$hazy"); }
      else if (state == "LIGHTNING") { return std::string("$lightning"); }
      else if (state == "LIGHTNINGRAINY") { return std::string("$lightningrainy"); }
      else if (state == "NIGHT") { return std::string("$night"); }
      else if (state == "NIGHTPARTLYCLOUDY") { return std::string("$nightpartlycloudy"); }
      else if (state == "PARTLYRAINY") { return std::string("$partlyrainy"); }
      else if (state == "PARTLYLIGHTNING") { return std::string("$partlylightning"); }
      else if (state == "PARTLYSNOWY") { return std::string("$partlysnowy"); }
      else if (state == "PARTLYSNOWYRAINY") { return std::string("$partlysnowyrainy"); }
      else if (state == "POURING") { return std::string("$pouring"); }
      else if (state == "SNOWY") { return std::string("$snowy"); }
      else if (state == "SNOWYHEAVY") { return std::string("$snowyheavy"); }
      else if (state == "SUNSET") { return std::string("$sunset"); }
      else if (state == "TORNADO") { return std::string("$tornado"); }
      else if (state == "WINDY") { return std::string("$windy"); }
      else if (state == "HURRICANE") { return std::string("$hurricane"); }
      return std::string("$happyface");
    on_value:
      then:
        - logger.log: id(weather_condition_icon).state.c_str()
        - lvgl.label.update:
            id: display_weather_icon
            text: !lambda return id(weather_condition_icon).state.c_str();

What is your time configuration?

Also I think you need a sun sensor.

Maybe I’m misunderstanding, but in the docs, it says the .is_below_horizon is a conditional. Idk if you can access an instance of the sun condition.

I would recommend to use the conditional trigger to set a global variable when the sun goes below or above the horizon. Then use that global variable in your lambda to check it.

I got it working with this, with elevation. I need to check tomorrow after sunrise if the day icons are back

  - platform: template
    id: weather_condition_icon
    lambda: |-
      std::string state = id(ha_weather_cond).state.c_str();

      // Controleer de elevation om te bepalen of het nacht is
      if (id(my_sun).elevation() < 0) {  // Haakjes toegevoegd
        if (state == "SUNNY") {
          return std::string("$night");
        } else if (state == "PARTLYCLOUDY") {
          return std::string("$nightpartlycloudy");
        }
      }

      if (state == "RAINY") { return std::string("$rainy"); }
      else if (state == "CLOUDY") { return std::string("$cloudy"); }
      else if (state == "PARTLYCLOUDY") { return std::string("$partlycloudy"); }
      else if (state == "SUNNY") { return std::string("$sunny"); }
      else if (state == "FOG") { return std::string("$fog"); }
      else if (state == "HAIL") { return std::string("$hail"); }
      else if (state == "HAZY") { return std::string("$hazy"); }
      else if (state == "LIGHTNING") { return std::string("$lightning"); }
      else if (state == "LIGHTNINGRAINY") { return std::string("$lightningrainy"); }
      else if (state == "NIGHT") { return std::string("$night"); }
      else if (state == "NIGHTPARTLYCLOUDY") { return std::string("$nightpartlycloudy"); }
      else if (state == "PARTLYRAINY") { return std::string("$partlyrainy"); }
      else if (state == "PARTLYLIGHTNING") { return std::string("$partlylightning"); }
      else if (state == "PARTLYSNOWY") { return std::string("$partlysnowy"); }
      else if (state == "PARTLYSNOWYRAINY") { return std::string("$partlysnowyrainy"); }
      else if (state == "POURING") { return std::string("$pouring"); }
      else if (state == "SNOWY") { return std::string("$snowy"); }
      else if (state == "SNOWYHEAVY") { return std::string("$snowyheavy"); }
      else if (state == "SUNSET") { return std::string("$sunset"); }
      else if (state == "TORNADO") { return std::string("$tornado"); }
      else if (state == "WINDY") { return std::string("$windy"); }
      else if (state == "HURRICANE") { return std::string("$hurricane"); }
      return std::string("$happyface");
    on_value:
      then:
        - logger.log: id(weather_condition_icon).state.c_str()
        - lvgl.label.update:
            id: display_weather_icon
            text: !lambda return id(weather_condition_icon).state.c_str();