Lookig for importing forecast

Hi i am stucked importing forecast states in esphome.
Mi problem is:
If i import forecast homeassistant value i think that is an array:

  • platform: homeassistant
    id: forecast_test
    entity_id: weather.casa
    attribute: forecast

The imported sensor result “unavaible”.

My goal is splitting various states from forecast ex “Day 1 condition” “Day 1 max temperature” etc… without flooding homeassistant with template sensor.

There is a way to do this? Thanks in advice.

1 Like

Is this relevant to you?

I imported the whole code and adapted to my entities, but it cannot compile:
/config/esphome/aztouch.yaml: In lambda function:
/config/esphome/aztouch.yaml:649:7: error: ‘fivedays’ was not declared in this scope
fivedays = id(w_fivedays).state;
^
/config/esphome/aztouch.yaml:652:7: error: ‘five’ was not declared in this scope
five.clear();
^
/config/esphome/aztouch.yaml:657:7: error: ‘token’ was not declared in this scope
token = strtok (&fivedays[0],"#");
^
/config/esphome/aztouch.yaml:665:31: error: unable to deduce ‘auto&&’ from ‘five’
for ( std::string fiv : five ) {
^
/config/esphome/aztouch.yaml:669:9: error: ‘str’ was not declared in this scope
str = “”;
^
/config/esphome/aztouch.yaml:672:9: error: ‘v’ was not declared in this scope
v.clear();
^
/config/esphome/aztouch.yaml:681:31: error: unable to deduce ‘auto&&’ from ‘v’
for ( std::string s : v ) {
^
*** [/data/aztouch/.pioenvs/aztouch/src/main.cpp.o] Error 1

Sounds like you didn’t add the text sensor or the Home Assistant template sensor.

No no i have added all the sensor, in esphome:

  • platform: homeassistant
    id: w_fivedays
    entity_id: sensor.weather_fivedays

and in sensor.yaml in homeassistant (i have also verified that is working correctly)

sensors:
  weather_fivedays:
    friendly_name: "Five day weather"
    value_template: >-
         {% set weather = {
            "sunny": "",
            "clear-day": "", 
            "clear-night": "", 
            "cloudy": "", 
            "rainy": "", 
            "sleet": "", 
            "snow": "s", 
            "wind": "", 
            "fog": "", 
            "partlycloudy": "", 
          } %}
         {% set days = {'Mon':'Lun','Tue':'Mar','Wed':'Mer','Thu':'Gio','Fri':'Ven','Sat':'Sab','Sun':'Dom'} %}

            {% for state in states.weather.casa.attributes.forecast[1:6] -%}
           
            {{ days[as_timestamp(state.datetime)| timestamp_custom("%a")] }};{{state.templow}}-{{ state.temperature }}°C;{{ state.precipitation | replace('.', ',') }}mm;{{ weather[state.condition] }}#
            
            {%- endfor %}

It produce this state:
Mar;6.4-15.6°C;0,0mm;#Mer;5.5-13.1°C;0,5mm;#Gio;5.6-11.0°C;0,0mm;#Ven;5.3-12.4°C;0,0mm;#

Post the ESP-Home yaml you are running now.

esphome:
  name: aztouch
  platform: ESP32
  board: esp32dev

# Enable logging
logger:

# Enable Home Assistant API
api:
  services:
    - service: play_rtttl
      variables:
        song_str: string
      then:
        - rtttl.play:
            rtttl: !lambda 'return song_str;'

ota:

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
#  domain: !secret wifi_domain
  ap:
    ssid: "aztouch"
    password: !secret fallpass 

captive_portal:

spi:
 clk_pin: 18
 mosi_pin: 23
 miso_pin: 19

i2c:
  sda: 33
  scl: 25
  
xpt2046:
  id: touchscreen
  cs_pin: 14 
  irq_pin: 27 
  update_interval: 50ms
  report_interval: 1s
  dimension_x: 240
  dimension_y: 320
  calibration_x_min: 237
  calibration_x_max: 3873
  calibration_y_min: 3800
  calibration_y_max: 352
  swap_x_y: false
  on_state:
    - lambda: |-
        if (touched)
           ESP_LOGI("cal", "x=%d, y=%d, x_raw=%d, y_raw=%d",
              id(touchscreen).x,
              id(touchscreen).y,
              id(touchscreen).x_raw,
              id(touchscreen).y_raw
              );

globals:
   - id: x
     type: int
     restore_value: no
     initial_value: '0'
   - id: y
     type: int
     restore_value: no
     initial_value: '0'
   - id: xx
     type: int
     restore_value: no
     initial_value: '0'
   - id: yy
     type: int
     restore_value: no
     initial_value: '150'
substitutions:
  icon_xy: '80x80'

image:
#0-default.png
  - file: "images/0-default.png"
    id: wpng_0
    type: RGB24
    resize: ${icon_xy}
#1-clear-night.png
  - file: "images/1-clear-night.png"
    id: wpng_1
    type: RGB24
    resize: ${icon_xy}
#2-cloudy.png
  - file: "images/2-cloudy.png"
    id: wpng_2
    type: RGB24
    resize: ${icon_xy}
#3-fog.png
  - file: "images/3-fog.png"
    id: wpng_3
    type: RGB24
    resize: ${icon_xy}
#4-hail.png
  - file: "images/4-hail.png"
    id: wpng_4
    type: RGB24
    resize: ${icon_xy}
#5-lightning.png
  - file: "images/5-lightning.png"
    id: wpng_5
    type: RGB24
    resize: ${icon_xy}
#6-lightning-rainy.png
  - file: "images/6-lightning-rainy.png"
    id: wpng_6
    type: RGB24
    resize: ${icon_xy}
#7-partlycloudy.png
  - file: "images/7-partlycloudy.png"
    id: wpng_7
    type: RGB24
    resize: ${icon_xy}
#8-pouring.png // rgb565
  - file: "images/8-pouring.png"
    id: wpng_8
    type: RGB24
    resize: ${icon_xy}
#9-rainy.png
  - file: "images/9-rainy.png"
    id: wpng_9
    type: RGB24
    resize: ${icon_xy}
#10-snowy.png
  - file: "images/10-snowy.png"
    id: wpng_10
    type: RGB24
    resize: ${icon_xy}
#11-snowy-rainy.png // TODO: renable-when-RGB565-supported
  - file: "images/11-snowy-rainy.png"
    id: wpng_11
    type: RGB24
    resize: ${icon_xy}
#12-sunny.png
  - file: "images/12-sunny.png"
    id: wpng_12
    type: RGB24
    resize: ${icon_xy}
#13-windy.png
  - file: "images/13-windy.png"
    id: wpng_13
    type: RGB24
    resize: ${icon_xy}
#14-windy-variant.png // TODO: renable-when-RGB565-supported
  - file: "images/14-windy-variant.png"
    id: wpng_14
    type: RGB24
    resize: ${icon_xy}
#15-exceptional.png // TODO: renable-when-RGB565-supported
  - file: "images/15-exceptional.png"
    id: wpng_15
    type: RGB24
    resize: ${icon_xy}
  - file: "images/dany.png"
    id: dany
    type: RGB24
    resize: 110x100
  - file: "images/raffa.png"
    id: raffa
    type: RGB24
    resize: 110x100

color:
  - id: my_red
    red: 100%
    green: 0%
    blue: 0%
  - id: my_yellow
    red: 100%
    green: 100%
    blue: 0%
  - id: my_green
    red: 0%
    green: 100%
    blue: 0%
  - id: my_blue
    red: 0%
    green: 0%
    blue: 100%
  - id: my_gray
    red: 50%
    green: 50%
    blue: 50%  
    
    
font:
  - file: 'fonts/Arial-Black.ttf'
    id: font1
    size: 20
  - file: 'fonts/BebasNeue-Regular.ttf'
    id: font2
    size: 48
  - file: 'fonts/Arial-Black.ttf'
    id: font3
    size: 30
  - file: 'fonts/BebasNeue-Regular.ttf'
    id: font4
    size: 40
  - file: 'fonts/Arial-Black.ttf'
    id: font5
    size: 22
  - file: 'fonts/arial.ttf'
    id: font6
    size: 22
  - file: 'fonts/BebasNeue-Regular.ttf'
    id: font7
    size: 80
  - file: 'fonts/arial.ttf'
    id: font8
    size: 18
  - file: 'fonts/Arial-Black.ttf'
    id: my_font_small
    size: 20
  - file: 'fonts/materialdesignicons-webfont.ttf'
    id: casa_font
    size: 20
    glyphs:
      - "\U000F02DC" # A casa
      - "\U000F0F9B" # Fuori Casa
      - "\U000F059D" # Vento
      - "\U000F050F" # Temperatura
      - "\U000F04C5" # Pressione
      - "\U000F058E" # Umidita
  - file: 'fonts/materialdesignicons-webfont.ttf'
    id: weather_font
    size: 49
    glyphs: [
      # Weather
      "", # mdi-weather-sunny
      "", # mdi-weather-night
      "", # mdi-weather-cloudy
      "", # mdi-weather-pouring
      "", # mdi-weather-snowy-rainy
      "s", # mdi-weather-snowy-heavy
      "", # mdi-weather-windy-variant
      "", # mdi-weather-fog
      "n", # mdi-weather-night-partly-cloudy
      "", # mdi-weather-partly-cloudy
      ]

output:
  - platform: ledc
    pin: 15
    id: gpio_32_backlight_pwm
    inverted: true
  - platform: ledc
    pin: GPIO21
    id: rtttl_out

# Define a monochromatic, dimmable light for the backlight
light:
  - platform: monochromatic
    output: gpio_32_backlight_pwm
    name: "ILI9341 Display Backlight"
    id: back_light
    restore_mode: ALWAYS_ON

rtttl:
  output: rtttl_out

time:
  - platform: homeassistant
    id: esptime

binary_sensor:
  - platform: xpt2046
    xpt2046_id: touchscreen
    id: touch_key_next
    x_min: 196
    x_max: 240
    y_min: 245
    y_max: 318
    on_press:
      - display.page.show_next: tft_ha
  - platform: xpt2046
    xpt2046_id: touchscreen
    id: touch_key_previous
    x_min: 4
    x_max: 80
    y_min: 255
    y_max: 315
    on_press:
      - display.page.show_previous: tft_ha

sensor:
  - platform: homeassistant
    id: weather_temperature
    entity_id: sensor.esphome_current_weather_temperature
    internal: true
  - platform: homeassistant
    id: gradicasa
    entity_id: sensor.temperatura
    internal: true
  - platform: homeassistant
    id: vento
    entity_id: weather.casa
    attribute: wind_speed
    internal: true
  - platform: homeassistant
    id: vento_gradi
    entity_id: weather.casa
    attribute: wind_bearing
    internal: true

text_sensor:
  - platform: homeassistant
    id: weather_location
    entity_id: sensor.esphome_current_weather_location
    internal: true
  - platform: homeassistant
    id: forecast_test
    entity_id: weather.casa
    attribute: forecast
    name: Forecast test
    internal: no
  - platform: homeassistant
    id: forecast1
    name: Forecast1
    entity_id: sensor.forecast1_hass
    internal: true
  - platform: homeassistant
    id: forecast2
    name: Forecast2
    entity_id: sensor.forecast2_hass
    internal: true
  - platform: homeassistant
    id: forecast3
    name: Forecast3
    entity_id: sensor.forecast3_hass
    internal: true
  - platform: homeassistant
    id: weather_condition
    entity_id: sensor.esphome_current_weather_condition
    internal: true
    on_value:
     lambda: |-
       //Icon
       if (x == "clear-night")
       {
        id(tempo).publish_state("Notte serena");
       }
       else if (x == "cloudy")
       {
        id(tempo).publish_state("Nuvoloso");
       }
       else if (x == "fog")
       {
        id(tempo).publish_state("Nebbia");
       }
       else if (id(weather_condition).state == "hail")
       {
        id(tempo).publish_state("Grandine");
       }
       else if (id(weather_condition).state == "lightning")
       {
        id(tempo).publish_state("Fulmini");
       }
       else if (id(weather_condition).state == "lightning-rainy")
       {
        id(tempo).publish_state("Pioggia/Fulmini");
       }
       else if (id(weather_condition).state == "partlycloudy")
       {
        id(tempo).publish_state("Parz. nuvoloso");
       }
       else if (id(weather_condition).state == "pouring")
       {
        id(tempo).publish_state("Rovescio");
       }
       else if (id(weather_condition).state == "rainy")
       {
        id(tempo).publish_state("Pioggia");
       }
       else if (id(weather_condition).state == "snowy")
       {
        id(tempo).publish_state("Neve");
       }
       else if (id(weather_condition).state == "snowy-rainy")
       {
        id(tempo).publish_state("Neve/pioggia");
       }
       else if (id(weather_condition).state == "sunny")
       {
        id(tempo).publish_state("Soleggiato");;
       }
       else if (id(weather_condition).state == "windy")
       {
        id(tempo).publish_state("Vento");
       }
       else if (id(weather_condition).state == "windy-variant")
       {
        id(tempo).publish_state("Vento forte");
       } 
       else if (id(weather_condition).state == "exceptional")
       {
        id(tempo).publish_state("Eccezionale");
       }
       else
       {
        id(tempo).publish_state("Nessun dato");
       }
  - platform: homeassistant
    id: unit_of_measurement
    entity_id: sensor.esphome_current_weather_temperature_units
    internal: true

  - platform: homeassistant
    id: statod
    entity_id: person.daniele
    internal: true

  - platform: homeassistant
    id: stator
    entity_id: person.raffa
    internal: true
  - platform: template
    id: tempo
    internal: true

  - platform: homeassistant
    id: w_fivedays
    entity_id: sensor.weather_fivedays

display:
  - platform: ili9341
    model: TFT 2.4
    cs_pin: 5 
    dc_pin: 4 
    led_pin: 15 
    reset_pin: 22 
#    rotation: 90
    id: tft_ha      
    pages:
      - id: page1
        lambda: |-
          if (id(weather_condition).state == "clear-night")
          {
             it.image(id(x), id(y), id(wpng_1));
          }
          else if (id(weather_condition).state == "cloudy")
          {
             it.image(id(x), id(y), id(wpng_2));
          }
          else if (id(weather_condition).state == "fog")
          {
             it.image(id(x), id(y), id(wpng_3));
          }
          else if (id(weather_condition).state == "hail")
          {
             it.image(id(x), id(y), id(wpng_4));
          }
          else if (id(weather_condition).state == "lightning")
          {
             it.image(id(x), id(y), id(wpng_5));
          }
          else if (id(weather_condition).state == "lightning-rainy")
          {
             it.image(id(x), id(y), id(wpng_6));
          }
          else if (id(weather_condition).state == "partlycloudy")
          {
             it.image(id(x), id(y), id(wpng_7));
          }
          else if (id(weather_condition).state == "pouring")
          {
             it.image(id(x), id(y), id(wpng_8));
          }
          else if (id(weather_condition).state == "rainy")
          {
             it.image(id(x), id(y), id(wpng_9));
          }
          else if (id(weather_condition).state == "snowy")
          {
             it.image(id(x), id(y), id(wpng_10));
          }
          else if (id(weather_condition).state == "snowy-rainy")
          {
             it.image(id(x), id(y), id(wpng_11));
          }
          else if (id(weather_condition).state == "sunny")
          {
             it.image(id(x), id(y), id(wpng_12));
          }
          else if (id(weather_condition).state == "windy")
          {
             it.image(id(x), id(y), id(wpng_13));
          }
          else if (id(weather_condition).state == "windy-variant")
          {
             it.image(id(x), id(y), id(wpng_14));
          } 
          else if (id(weather_condition).state == "exceptional")
          {
             it.image(id(x), id(y), id(wpng_15));
          }
          else
          {
             it.image(id(x), id(y), id(wpng_0));
          }
          //Temperature
          if (id(weather_temperature).has_state())
          {
          //Tempo
            it.printf(0, (it.get_height()/3-15), id(font8), TextAlign::BASELINE_LEFT, "%s", id(tempo).state.c_str());
          //  it.printf(0, (it.get_height()/3-15), id(font8), TextAlign::BASELINE_LEFT, "%s", id(forecast_test)[1].state.c_str(), 'condition';
          //Gradi
            it.printf((it.get_width()/3+5), 10, id(font2),  id(my_blue), TextAlign::TOP_LEFT, "%.0f°", id(weather_temperature).state);
          }
          //Location
          if (id(weather_location).has_state())
          {
           it.printf((it.get_width()/3+5), 0, id(font8), TextAlign::TOP_LEFT, "%s", id(weather_location).state.c_str());
          }
          //Temperatura casa
          if (id(gradicasa).has_state()) 
          {
            it.printf((it.get_width()-10), 0, id(font8), TextAlign::TOP_RIGHT, "Casa");
            it.printf(it.get_width(), 10, id(font2),  id(my_red), TextAlign::TOP_RIGHT, "%.0f°", id(gradicasa).state);
          }
          //Vento
          if (id(vento).has_state())
          {
            it.printf((it.get_width()-60), (it.get_height()/3-15), id(casa_font), id(my_yellow), TextAlign::BASELINE_RIGHT, "\U000F059D");
            it.printf(it.get_width(), (it.get_height()/3-15), id(font8),  id(my_blue), TextAlign::BASELINE_RIGHT, "%.0f km/h", id(vento).state);
          }
          //Time
          it.strftime(0, it.get_height(), id(font1), TextAlign::BASELINE_LEFT, "%H:%M:%S", id(esptime).now());
          it.strftime(it.get_width(), it.get_height(), id(font1), TextAlign::BASELINE_RIGHT, "%d-%m-%Y", id(esptime).now());
          //lines
          it.line(0, (it.get_height()/3-5), it.get_width(), (it.get_height()/3-5));
          //Forecast 1
          if (id(forecast1).state == "clear-night")
          {
             it.image(id(xx), (it.get_height()/3), id(wpng_1));
          }
          else if (id(forecast1).state == "cloudy")
          {
             it.image(id(xx), (it.get_height()/3), id(wpng_2));
          }
          else if (id(forecast1).state == "fog")
          {
             it.image(id(xx), (it.get_height()/3), id(wpng_3));
          }
          else if (id(forecast1).state == "hail")
          {
             it.image(id(xx), (it.get_height()/3), id(wpng_4));
          }
          else if (id(forecast1).state == "lightning")
          {
             it.image(id(xx), (it.get_height()/3), id(wpng_5));
          }
          else if (id(forecast1).state == "lightning-rainy")
          {
             it.image(id(xx), (it.get_height()/3), id(wpng_6));
          }
          else if (id(forecast1).state == "partlycloudy")
          {
             it.image(id(xx), (it.get_height()/3), id(wpng_7));
          }
          else if (id(forecast1).state == "pouring")
          {
             it.image(id(xx), (it.get_height()/3), id(wpng_8));
          }
          else if (id(forecast1).state == "rainy")
          {
             it.image(id(xx), (it.get_height()/3), id(wpng_9));
          }
          else if (id(forecast1).state == "snowy")
          {
             it.image(id(xx), (it.get_height()/3), id(wpng_10));
          }
          else if (id(forecast1).state == "snowy-rainy")
          {
             it.image(id(xx), (it.get_height()/3), id(wpng_11));
          }
          else if (id(forecast1).state == "sunny")
          {
             it.image(id(xx), (it.get_height()/3), id(wpng_12));
          }
          else if (id(forecast1).state == "windy")
          {
             it.image(id(xx), (it.get_height()/3), id(wpng_13));
          }
          else if (id(forecast1).state == "windy-variant")
          {
             it.image(id(xx), (it.get_height()/3), id(wpng_14));
          } 
          else if (id(forecast1).state == "exceptional")
          {
             it.image(id(xx), (it.get_height()/3), id(wpng_15));
          }
          else
          {
             it.image(id(xx), (it.get_height()/3), id(wpng_0));
          }
      - id: page2
        lambda: |-
          it.strftime(50, 10, id(font7), "%H:%M", id(esptime).now());
          it.strftime(50, 80, id(font4), "%d/%m/%Y", id(esptime).now());
      - id: page3
        lambda: |-
          it.image(0, 0, id(dany));
          if (id(statod).state == "home")
          {
           it.printf(40, 100, id(casa_font), id(my_green), "\U000F02DC");
          }
          else
          {
            it.printf(40, 100, id(casa_font), id(my_red), "\U000F0F9B");
          }
          it.image(130, 0, id(raffa));
          if (id(stator).state == "home")
          {
           it.printf(165, 100, id(casa_font), id(my_green), "\U000F02DC");
          }
          else
          {
           it.printf(165, 100, id(casa_font), id(my_red), "\U000F0F9B");
           }
      - id: page4
        lambda: |-
          //Temp
          it.printf(0, 0, id(casa_font), id(my_red), "\U000F050F");
          it.printf(40, 0, id(font4), id(my_red), "Temperatura");
          //press
          it.printf(0, 32, id(casa_font), id(my_red), "\U000F04C5");
          it.printf(40, 32, id(font4), id(my_red), "Pressione");
          //Umidita
          it.printf(0, 64, id(casa_font), id(my_red), "\U000F058E");
          it.printf(40, 64, id(font4), id(my_red), "Umidita");
          //Vento
          it.printf(0, 96, id(casa_font), id(my_red), "\U000F059D");
          it.printf(40, 96, id(font4), id(my_red), "Vento");
      - id: page5
        lambda: |-
          it.printf(0, 0, id(font1), id(forecast1).state.c_str());
      - id: page6
        lambda: |-
          fivedays = id(w_fivedays).state;
          
          //ESP_LOGD("%s", fivedays.c_str());
          five.clear();
          
          int count = 0;
          int wx = 0; // start positio x
          int wy = 0; // start position y
          token = strtok (&fivedays[0],"#");
          // this while splits the string (I believe, I "found" the code)
          while (token != NULL)
          {
            five.push_back(token);
            token = strtok (NULL, "#");
          }
          // here we loop the days
          for ( std::string fiv : five ) {
            it.rectangle(0, wy, 128, 59);  // adds a border around the "day"
            it.rectangle(1, wy+1, 126, 57);
            
            str = "";
            str = fiv;
            //ESP_LOGD("test: ", "String to Vector: %s", str.c_str());
            v.clear();
            token = strtok (&str[0],";");
            while (token != NULL)
            {
              v.push_back(token);
              token = strtok (NULL, ";");
            }

            // this is the loop for each value in the "day"
            for ( std::string s : v ) {

              if(count == 0){
                // Day (Mon/Tue...)
                it.printf(wx +7, wy, id(my_font_small), "%s", s.c_str());
              }else if(count == 1){
                // Temperature 
                it.printf(wx +7, wy+18, id(my_font_small), "%s", s.c_str());
              }else if(count == 2){
                // Precipitation 
                it.printf(wx +7, wy+35, id(my_font_small), "%s", s.c_str());
              }else if(count == 3){
                // weather icon
                it.printf(123, wy+5, id(weather_font), TextAlign::TOP_RIGHT, "%s", s.c_str());
              }
               
              //ESP_LOGD("test: ", "String to Vector: %s", s.c_str());
              count += 1;
            }
            count = 0;
            wy += 59; // move down 59 pixels and output next day
          }

The relevant part is on page 6.

I have created new yaml for simplify the test:

esphome:
  name: aztouch
  platform: ESP32
  board: esp32dev

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
#  domain: !secret wifi_domain
  ap:
    ssid: "aztouch"
    password: !secret fallpass 

captive_portal:

spi:
 clk_pin: 18
 mosi_pin: 23
 miso_pin: 19

i2c:
  sda: 33
  scl: 25
font:  
  - file: 'fonts/Arial-Black.ttf'
    id: my_font_small
  - file: 'fonts/materialdesignicons-webfont.ttf'
    id: weather_font
    size: 49
    glyphs: [
      # Weather
      "", # mdi-weather-sunny
      "", # mdi-weather-night
      "", # mdi-weather-cloudy
      "", # mdi-weather-pouring
      "", # mdi-weather-snowy-rainy
      "s", # mdi-weather-snowy-heavy
      "", # mdi-weather-windy-variant
      "", # mdi-weather-fog
      "n", # mdi-weather-night-partly-cloudy
      "", # mdi-weather-partly-cloudy
      ]

text_sensor:
  - platform: homeassistant
    id: w_fivedays
    entity_id: sensor.weather_fivedays

    
display:
  - platform: ili9341
    model: TFT 2.4
    cs_pin: 5 
    dc_pin: 4 
    led_pin: 15 
    reset_pin: 22 
#    rotation: 90
    id: tft_ha
    lambda: |-
          fivedays = id(w_fivedays).state;
          
          //ESP_LOGD("%s", fivedays.c_str());
          five.clear();
          
          int count = 0;
          int wx = 0; // start positio x
          int wy = 0; // start position y
          token = strtok (&fivedays[0],"#");
          // this while splits the string (I believe, I "found" the code)
          while (token != NULL)
          {
            five.push_back(token);
            token = strtok (NULL, "#");
          }
          // here we loop the days
          for ( std::string fiv : five ) {
            it.rectangle(0, wy, 128, 59);  // adds a border around the "day"
            it.rectangle(1, wy+1, 126, 57);
            
            str = "";
            str = fiv;
            //ESP_LOGD("test: ", "String to Vector: %s", str.c_str());
            v.clear();
            token = strtok (&str[0],";");
            while (token != NULL)
            {
              v.push_back(token);
              token = strtok (NULL, ";");
            }

            // this is the loop for each value in the "day"
            for ( std::string s : v ) {

              if(count == 0){
                // Day (Mon/Tue...)
                it.printf(wx +7, wy, id(my_font_small), "%s", s.c_str());
              }else if(count == 1){
                // Temperature 
                it.printf(wx +7, wy+18, id(my_font_small), "%s", s.c_str());
              }else if(count == 2){
                // Precipitation 
                it.printf(wx +7, wy+35, id(my_font_small), "%s", s.c_str());
              }else if(count == 3){
                // weather icon
                it.printf(123, wy+5, id(weather_font), TextAlign::TOP_RIGHT, "%s", s.c_str());
              }
               
              //ESP_LOGD("test: ", "String to Vector: %s", s.c_str());
              count += 1;
            }
            count = 0;
            wy += 59; // move down 59 pixels and output next day
          }

When it complile it give me the same errors.

Have you registered the ESP-Home device in HA?
Can it output any entity from HA?

If you try a different sensor/entity and just output it’s state on screen, does it work?

I think it’s a connection error between device and HA.
Make sure it’s registered in the integrations page.

Yes I have the esphome entity for device registerd, his sensor work correctly. The problem is compile error, it seems inside lambda code and not after firmware update. It seems some problem in variable declaration

fivedays = id(w_fivedays).state

Not work it give me compilation error

But if I add std::string fivedays = id(w_fivedays).state

This work but compilation not run fine because it not recognise the variables “token” “v” etc… .
I think something is changed in lambda subsystem in the latest updates…
Today I have do some tests grabbed code around various project now the correct sytanx for declaring variables seems to be something like this:
std::string str = id(hatext).state;
std::vectorstd::string v;
char * token;
char seps[] = “,”;

Hi, finally i have adapted the code to my situation:

(id(w_1_2).has_state())
          {
            std::string fivedays = id(w_1_2).state;
            std::vector<std::string> five;
            it.rectangle(0, (it.get_height()/3), it.get_width(), 50);  // adds a border around the "day"
          
            //ESP_LOGD("%s", fivedays.c_str());
            five.clear();
          
            int count = 0;
            int wx = 0; // start positio x
            int wy = 108; // start position y
            char * token;
            token = strtok (&fivedays[0],"#");
            // this while splits the string (I believe, I "found" the code)
            while (token != NULL)
            {
              five.push_back(token);
              token = strtok (NULL, "#");
            }
            // here we loop the days
            for ( std::string fiv : five ) {
              //it.rectangle(wx, wy+1, wx+126, 57);
            
              std::string str = "";
              str = fiv;
              //ESP_LOGD("test: ", "String to Vector: %s", str.c_str());
              std::vector<std::string> v;
              v.clear();
              token = strtok (&str[0],";");
              while (token != NULL)
              {
                v.push_back(token);
                token = strtok (NULL, ";");
              }

              // this is the loop for each value in the "day"
              for ( std::string s : v ) {

                if(count == 0){
                  // Day (Mon/Tue...)
                  it.printf(wx +2, wy, id(my_font_small), "%s", s.c_str());
                }else if(count == 1){
                  // Temperature 
                  it.printf(wx +2, wy+16, id(my_font_small), "%s", s.c_str());
                }else if(count == 2){
                  // Precipitation 
                  it.printf(wx +2, wy+33, id(my_font_small), "%s", s.c_str());
                }else if(count == 3){
                  // weather icon
                  it.printf(wx +114, wy, id(weather_font), TextAlign::TOP_RIGHT, "%s", s.c_str());
                }
               
                //ESP_LOGD("test: ", "String to Vector: %s", s.c_str());
                count += 1;
              }
              count = 0;
              wx += 124; // move right 59 pixels and output next day            }
            }
          }

I have split 4 days in 2 sensor for have in esp 2 days upper and 2 days bottom inside a rectangle.
I had problems with webfont ttf the simple copy and paste not work for me, i obtain an empty square so i adapted wheter states in unicode:

{% set weather = {
                "sunny": "\U000F0599",
                "sunny-alert": "\U000F0F37",
                "sunny-off": "\U000F14E4",
                "clear-day": "\U000F0599", 

Everithing work as expected.
A last question please.

when you wrote the program, the sensor home assistant template text sensor was missing attribute import. Now it is possible to import all forecast data into a text sensor:

  • platform: homeassistant
    id: forecast_test
    entity_id: weather.casa
    attribute: forecast
    internal: true
    The sensor obtain value:
[{'condition': 'partlycloudy', 'precipitation': 0.0, 'temperature': 16.1, 'templow': 6.1, 'datetime': '2021-10-19T10:00:00+00:00', 'wind_bearing': 196.6, 'wind_speed': 7.6}, {'condition': 'rainy', 'precipitation': 0.4, 'temperature': 14.9, 'templow': 7.1, 'datetime': '2021-10-20T10:00:00+00:00', 'wind_bearing': 221.0, 'wind_speed': 17.3}, {'condition': 'rainy', 'precipitation': 5.3, 'temperature': 14.4, 'templow': 8.4, 'datetime': '2021-10-21T10:00:00+00:00', 'wind_bearing': 221.8, 'wind_speed': 15.5}, {'condition': 'partlycloudy', 'precipitation': 0.8, 'temperature': 16.4, 'templow': 9.8, 'datetime': '2021-10-22T10:00:00+00:00', 'wind_bearing': 175.2, 'wind_speed': 11.5}, {'condition': 'sunny', 'precipitation': 0.0, 'temperature': 13.3, 'templow': 7.6, 'datetime': '2021-10-23T10:00:00+00:00', 'wind_bearing': 26.3, 'wind_speed': 17.3}]"

I still can’t figure out how to adapt this code to transfer it directly to the esp, can you help me please?

      - id: page4
        lambda: |-
          std::string weather = {
                "sunny": "\U000F0599",
                "sunny-alert": "\U000F0F37",
                "sunny-off": "\U000F14E4",
                "clear-day": "\U000F0599", 
                "clear-night": "\U000F0594", 
                "cloudy": "\U000F0590", 
                "cloudy-alert": "\U000F0F2F",
                "partly-cloudy": "\U000F0595",
                "rainy": "\U000F0597",
                "partly-rainy": "\U000F0F33",
                "sleet": "\U000F067F",
                "hail": "\U000F0592",
                "snow": "\U000F0598",
                "snowy-rainy": "\U000F067F",
                "partly-snowy": "\U000F0F34",
                "partly-snowy-rainy": "\U000F0F35",
                "snowy-heavy": "\U000F0F36",
                "wind": "\U000F059D", 
                "fog": "\U000F0591", 
                "partlycloudy": "\U000F0595",
                "cloudy-arrow-right": "\U000F0E6E",
                "hazy": "\U000F0F30",
                "hurricane": "\U000F0898",
                "lightning": "\U000F0593",
                "lightning-rainy": "\U000F067E",
                "partly-lightning": "\U000F0F32",
                "night": "\U000F0594", 
                "night-partly-cloudy": "\U000F0F31",
                "pouring": "\U000F0596",
                "sunset": "\U000F059A",
                "sunset-down": "\U000F059B",
                "sunset-up": "\U000F059C",
                "tornado": "\U000F0F38",
                "windy": "\U000F059D",
                "windy-variant": "\U000F059E",
              }
            std::string days = {'Mon':'Lun','Tue':'Mar','Wed':'Mer','Thu':'Gio','Fri':'Ven','Sat':'Sab','Sun':'Dom'}

                 for state in states.forecast_test[0:2]
               
                {{ days[as_timestamp(state.datetime)| timestamp_custom("%a")] }};{{state.templow}}-{{ state.temperature }}°C;{{ state.precipitation | replace('.', ',') }}mm;{{ weather[state.condition] }}#

Thank you in advice.

So do I but it still works. I haven’t questioned why it works, that is probably the reason why it works :slight_smile:

Don’t know what you mean by this…

If you mean you added this to ESP-Home that will just give you a json in ESP-Home. Not sure if that is really helpful.

You have really messed it up.
The last code block is not supposed to be in ESP-Home. That is a template sensor in HA.
This template sensor is the one you should send to ESP-Home, not the weather entity.

Yes, maybe I haven’t explained myself well, I’m trying to remove the logic from Home assistant and move everything to esphome. So to do it all with a single weather sensor if that’s possible, what you see is just a test.
I grab the weather status from this:

  • platform: homeassistant
    id: weather_condition
    entity_id: weather.casa

And I would like to extract the forecast from this

  • platform: homeassistant
    id: forecast_test
    entity_id: weather.casa
    attribute: forecast

I meant if you think there is a way to take advantage of the second sensor called forecast_test which contains all the weekly weather codes without having to add other templates in homeassistant.

I would like to share the code here once I finish it, it would be much more useful for the end user to just use the esphome yaml without having to set up additional homeassistant templates.

I see. I’m not very good with ESP-Home lambda so I’m happy I managed to get it working the way it did.
Lambda is as far as I know c++ code so you could probably parse the json and use that directly but I’m not qualified to do that.

Same situation I know very little about C ++. I start studying well how vectors and strings work, I hope to find a way sooner or later. Thanks so much for the advice!

Finally after several days of studying c ++ and with the help of a friend and discord support I finally figured out how to take advantage of json weather forecast data.
With this method you do not need to make any template in homeassistant but esp will take care of the parse of the values using met.no integration already present in homeassistant just adapt the weather sensor weather. “your location name”
In the next few days I will post all the code and links of the entire project.

The new esphome versions can use json:
so in the file.yaml a line
json: is needed for the program work.

json:
text_sensor:
#5 Day forecast
  - platform: homeassistant
    id: forecast_5
    entity_id: weather.casa
    attribute: forecast
    internal: yes

And in the display section:

         //Forecast
         if (id(forecast_5).has_state())
         {
          int wx = 0; // start position x
          int wxx;
          int wyy;
         
          const size_t capacity = JSON_ARRAY_SIZE(5) + 5*JSON_OBJECT_SIZE(5) + 560;
          DynamicJsonBuffer jsonBuffer(capacity);
          JsonArray& root = jsonBuffer.parseArray(id(forecast_5).state.c_str());
          //for (int i=0; i<root.size(); i++)
          for (int i=0; i <= 4; ++i)
          {
           if (i == 0) {wxx = wx;}
           if (i == 0) {wyy = wy;}
           if (i == 0) {day = 1;}
           //Day 3-4 go down 
           if (i == 2) {wyy += 50;}
           if (i == 2) {wxx = 0;}
           JsonObject& root_0 = root[i];
           std::string root_0_condition = root_0["condition"]; // "sunny"
           float root_0_precipitation = root_0["precipitation"]; // 0.8
           float root_0_temperature = root_0["temperature"]; // 20.2
           float root_0_templow = root_0["templow"]; // 11.3
           //std::string root_0_datetime = root_0["datetime"]; // "2021-10-22T10:00:00+00:00"
           //int root_0_wind_bearing = root_0["wind_bearing"]; // 212
           //float root_0_wind_speed = root_0["wind_speed"]; // 9.4
           
           //Print to screen
           //Translated day
           it.printf(wxx +5, wyy, id(font_small), id(my_green), TextAlign::TOP_LEFT, "%s", dayDict[day]);
           //Icon condition
           it.printf(wxx +65, wyy, id(weather_font), TextAlign::TOP_LEFT, "%s", fonDict[root_0_condition.c_str()]);
           //Temp max
           it.printf(wxx +5, wyy+14, id(font_small_1), TextAlign::TOP_LEFT, "max %.0f°", root_0_temperature);
           //Temp min
           it.printf(wxx +5, wyy+25, id(font_small_1), TextAlign::TOP_LEFT, "min %.0f°", root_0_templow);
           //Rain in mm
           it.printf(wxx +5, wyy+36, id(font_small_1), TextAlign::TOP_LEFT, "%.0f mm", root_0_precipitation);
           wxx += 120;
           day += 1;
          }

Hey, great work! I want to adopt your project and use it on my ePaper display. Would you mind sharing the whole code? Thanks!

Hi, sorry for delay.
I have opened my first git project for hosting it.

I hope I was helpful

2 Likes

I have used your solution to read weather.home entity attributes. Good job :smiley: Thanks

Very cool, what display is?