# Dynamic WeatherBoard - trigger: - platform: time_pattern minutes: /5 variables: # USE ONE Weather entity_id (check Developer Tools > States) # Open-Meteo likely uses "weather.home" and Openweather likely uses "weather.openweathermap" but yours may be different weather_entity: "weather.home" hourlytimes: > {# Edit and order the schedule from midnight 00:00 to 23:00 as needed - 1st handles from midnight to a certain AM time and the last will handle all others not in the if/elif's #} {# You MUST use leading zeros on all time comparisons for 9am and earlier - results will be unpredictable if you forget to do this #} {# Because of the way Home Assistant updates sensors, it can take up to 2 time pattern cycles to fully update #} {# Be sure all of your hourlytimes end in :00 unless you live in a "weird" time zone that uses +/- 30 minutes then you probably have to end all hourlytimes with :30 #} {# Do a service call in Home Assistant Developer tools with weather.get_forecasts (hourly) and you can see why this is important #} {%- set hourlytimes = [] %} {%- if now().strftime('%H.%M') < '06.10' %} {# for waketime 06:05 #} {%- set hourlytimes = hourlytimes + ["09:00"] %} {%- set hourlytimes = hourlytimes + ["12:00"] %} {%- set hourlytimes = hourlytimes + ["15:00"] %} {%- set hourlytimes = hourlytimes + ["18:00"] %} {%- elif now().strftime('%H.%M') < '08.10' %} {# for waketime 08:05 #} {%- set hourlytimes = hourlytimes + ["10:00"] %} {%- set hourlytimes = hourlytimes + ["14:00"] %} {%- set hourlytimes = hourlytimes + ["16:00"] %} {%- set hourlytimes = hourlytimes + ["20:00"] %} {%- elif now().strftime('%H.%M') < '10.10' %} {# for waketime 10:05 #} {%- set hourlytimes = hourlytimes + ["12:00"] %} {%- set hourlytimes = hourlytimes + ["15:00"] %} {%- set hourlytimes = hourlytimes + ["18:00"] %} {%- set hourlytimes = hourlytimes + ["21:00"] %} {%- elif now().strftime('%H.%M') < '12.10' %} {# for waketime 12:05 #} {%- set hourlytimes = hourlytimes + ["14:00"] %} {%- set hourlytimes = hourlytimes + ["16:00"] %} {%- set hourlytimes = hourlytimes + ["19:00"] %} {%- set hourlytimes = hourlytimes + ["22:00"] %} {%- elif now().strftime('%H.%M') < '14.10' %} {# for waketime 14:05 #} {%- set hourlytimes = hourlytimes + ["16:00"] %} {%- set hourlytimes = hourlytimes + ["18:00"] %} {%- set hourlytimes = hourlytimes + ["20:00"] %} {%- set hourlytimes = hourlytimes + ["22:00"] %} {%- elif now().strftime('%H.%M') < '16.10' %} {# for waketime 16:05 #} {%- set hourlytimes = hourlytimes + ["18:00"] %} {%- set hourlytimes = hourlytimes + ["20:00"] %} {%- set hourlytimes = hourlytimes + ["22:00"] %} {%- set hourlytimes = hourlytimes + ["00:00"] %} {%- elif now().strftime('%H.%M') < '18.10' %} {# for waketime 18:05 #} {%- set hourlytimes = hourlytimes + ["20:00"] %} {%- set hourlytimes = hourlytimes + ["21:00"] %} {%- set hourlytimes = hourlytimes + ["22:00"] %} {%- set hourlytimes = hourlytimes + ["00:00"] %} {%- else %} {# for waketimes after 19:00, will show next day's forecast #} {%- set hourlytimes = hourlytimes + ["08:00"] %} {%- set hourlytimes = hourlytimes + ["12:00"] %} {%- set hourlytimes = hourlytimes + ["16:00"] %} {%- set hourlytimes = hourlytimes + ["20:00"] %} {%- endif %} {{hourlytimes}} # Here you can edit the fallback intervals in case the above fails default_0: "2" default_1: "4" default_2: "6" default_3: "8" titles: > {# Similar as above but basically make sure it handles the hourly report shows a different title #} {# Handle it in the order of the 3 titles (WEATHER, TODAY, OUTLOOK are defaults #} {# Be sure the font in your ESPHome YAML can handle the characters! ie. "WEATHR" for font_title and "TODAY MRWULK" for the font_small_title #} {%- set titles = [] %} {%- set titles = titles + ["WEATHER"] %} {%- if now().strftime('%H.%M') < '00.10' %} {# for waketime 00:05 (it's TOMORROW until the sun rises #} {%- set titles = titles + ["TOMORROW"] %} {%- elif now().strftime('%H.%M') < '18.10' %} {# for waketimes 06:05 to 18:05 #} {%- set titles = titles + ["TODAY"] %} {%- else %} {# for waketimes after 18:10, will show next day's forecast #} {%- set titles = titles + ["TOMORROW"] %} {%- endif %} {%- set titles = titles + ["OUTLOOK"] %} {{titles}} dailydays: > {# Similar as above but handles the daily forecast/outlook (it doesn't need to show tomorrow when that's handled by the hourly #} {%- set dailydays = [] %} {%- if now().strftime('%H.%M') < '00.10' %} {# for waketime 00:05 (kludge fix: service still contains this day's daily forecast as tomorrow's) #} {%- set dailydays = [2,3,4,5] %} {%- elif now().strftime('%H.%M') < '18.10' %} {# for waketimes 06:05 to 18:05 #} {%- set dailydays = [1,2,3,4] %} {%- else %} {# for waketimes after 18:10, will skip showing tomorrow's forecast #} {%- set dailydays = [2,3,4,5] %} {%- endif %} {{dailydays}} daily_0: "{{ dailydays[0]|int }}" daily_1: "{{ dailydays[1]|int }}" daily_2: "{{ dailydays[2]|int }}" daily_3: "{{ dailydays[3]|int }}" # Edit how timestamps are shown time_format: "%I:00%p" # %H:00 = 24hrs (13:00) / %I:00%p = 12hrs + AM/PM (01:00PM) strip_zero: "0" # 0 to strip leading zero (1:00PM), empty quotes if not action: - service: weather.get_forecasts data: type: hourly target: entity_id: "{{ weather_entity }}" response_variable: hourly - service: weather.get_forecasts data: type: daily target: entity_id: "{{ weather_entity }}" response_variable: daily sensor: - name: eInk WeatherBoard Data unique_id: eink_weatherboard_data state: "OK" attributes: hourly_times: "{{hourlytimes}}" hourly_intervals: > {%- set thishourly = 3 %} {# should match what variable is the max #} {%- set count = namespace(this = 0) %} {%- set counter = namespace(this = 0) %} {%- set hours = namespace(this = []) -%} {%- for hourlycheck in hourly[weather_entity].forecast %} {%- if (hourlytimes[count.this]|string + ":00") in (as_datetime(hourlycheck.datetime).astimezone()|string) %} {%- set count.this = count.this + 1 %} {%- set hours.this = hours.this + [counter.this] %} {%- if count.this == 1 + thishourly %} {%- break %} {%- endif %} {%- endif %} {%- set counter.this = counter.this + 1 %} {%- endfor %} {{hours.this}} weather_now_title: "{{ titles[0] }}" weather_now_temperature: > {{ hourly[weather_entity].forecast[0].temperature | round }} weather_now_condition: > {%- set cond_now = hourly[weather_entity].forecast[0].condition %} {%- if states('sun.sun') == 'below_horizon' %} {%- if cond_now == 'sunny' %} night {% elif cond_now == 'partlycloudy' %} night-partly-cloudy {% else %} {{ cond_now }} {% endif %} {%- else %} {{ cond_now }} {%- endif %} weather_hourly_title: "{{ titles[1] }}" weather_hourly_condition_0: > {%- if 'hourly_intervals' not in this.attributes %} {%- set hourlytime = (default_0 | int) %} {%- else %} {%- set hourlytime = ((this.attributes.hourly_intervals[0] | default(default_0)) | int) %} {%- endif %} {%- set cond0 = hourly[weather_entity].forecast[hourlytime].condition %} {%- set next_setting = as_timestamp(state_attr('sun.sun', 'next_setting')) %} {%- set next_rising = as_timestamp(state_attr('sun.sun', 'next_rising')) %} {%- set cond0_time = as_timestamp(hourly[weather_entity].forecast[hourlytime].datetime) %} {%- if cond0_time > next_setting and cond0_time < next_rising %} {%- if cond0 == 'sunny' %} night {% elif cond0 == 'partlycloudy' %} night-partly-cloudy {% else %} {{ cond0 }} {% endif %} {%- else %} {{ cond0 }} {%- endif %} weather_hourly_temperature_0: > {%- if 'hourly_intervals' not in this.attributes %} {%- set hourlytime = (default_0 | int) %} {%- else %} {%- set hourlytime = ((this.attributes.hourly_intervals[0] | default(default_0)) | int) %} {%- endif %} {{ hourly[weather_entity].forecast[hourlytime].temperature | round }} weather_hourly_timestamp_0: > {%- if 'hourly_intervals' not in this.attributes %} {%- set hourlytime = (default_0 | int) %} {%- else %} {%- set hourlytime = ((this.attributes.hourly_intervals[0] | default(default_0)) | int) %} {%- endif %} {%- set timestamp = as_timestamp(hourly[weather_entity].forecast[hourlytime].datetime) | timestamp_custom(time_format) %} {{ timestamp.lstrip(strip_zero) }} weather_hourly_condition_1: > {%- if 'hourly_intervals' not in this.attributes %} {%- set hourlytime = (default_1 | int) %} {%- else %} {%- set hourlytime = ((this.attributes.hourly_intervals[1] | default(default_1)) | int) %} {%- endif %} {%- set cond0 = hourly[weather_entity].forecast[hourlytime].condition %} {%- set next_setting = as_timestamp(state_attr('sun.sun', 'next_setting')) %} {%- set next_rising = as_timestamp(state_attr('sun.sun', 'next_rising')) %} {%- set cond0_time = as_timestamp(hourly[weather_entity].forecast[hourlytime].datetime) %} {%- if cond0_time > next_setting and cond0_time < next_rising %} {%- if cond0 == 'sunny' %} night {% elif cond0 == 'partlycloudy' %} night-partly-cloudy {% else %} {{ cond0 }} {% endif %} {%- else %} {{ cond0 }} {%- endif %} weather_hourly_temperature_1: > {%- if 'hourly_intervals' not in this.attributes %} {%- set hourlytime = (default_1 | int) %} {%- else %} {%- set hourlytime = ((this.attributes.hourly_intervals[1] | default(default_1)) | int) %} {%- endif %} {{ hourly[weather_entity].forecast[hourlytime].temperature | round }} weather_hourly_timestamp_1: > {%- if 'hourly_intervals' not in this.attributes %} {%- set hourlytime = (default_1 | int) %} {%- else %} {%- set hourlytime = ((this.attributes.hourly_intervals[1] | default(default_1)) | int) %} {%- endif %} {%- set timestamp = as_timestamp(hourly[weather_entity].forecast[hourlytime].datetime) | timestamp_custom(time_format) %} {{ timestamp.lstrip(strip_zero) }} weather_hourly_condition_2: > {%- if 'hourly_intervals' not in this.attributes %} {%- set hourlytime = (default_2 | int) %} {%- else %} {%- set hourlytime = ((this.attributes.hourly_intervals[2] | default(default_2)) | int) %} {%- endif %} {%- set cond0 = hourly[weather_entity].forecast[hourlytime].condition %} {%- set next_setting = as_timestamp(state_attr('sun.sun', 'next_setting')) %} {%- set next_rising = as_timestamp(state_attr('sun.sun', 'next_rising')) %} {%- set cond0_time = as_timestamp(hourly[weather_entity].forecast[hourlytime].datetime) %} {%- if cond0_time > next_setting and cond0_time < next_rising %} {%- if cond0 == 'sunny' %} night {% elif cond0 == 'partlycloudy' %} night-partly-cloudy {% else %} {{ cond0 }} {% endif %} {%- else %} {{ cond0 }} {%- endif %} weather_hourly_temperature_2: > {%- if 'hourly_intervals' not in this.attributes %} {%- set hourlytime = (default_2 | int) %} {%- else %} {%- set hourlytime = ((this.attributes.hourly_intervals[2] | default(default_2)) | int) %} {%- endif %} {{ hourly[weather_entity].forecast[hourlytime].temperature | round }} weather_hourly_timestamp_2: > {%- if 'hourly_intervals' not in this.attributes %} {%- set hourlytime = (default_2 | int) %} {%- else %} {%- set hourlytime = ((this.attributes.hourly_intervals[2] | default(default_2)) | int) %} {%- endif %} {%- set timestamp = as_timestamp(hourly[weather_entity].forecast[hourlytime].datetime) | timestamp_custom(time_format) %} {{ timestamp.lstrip(strip_zero) }} weather_hourly_condition_3: > {%- if 'hourly_intervals' not in this.attributes %} {%- set hourlytime = (default_3 | int) %} {%- else %} {%- set hourlytime = ((this.attributes.hourly_intervals[3] | default(default_3)) | int) %} {%- endif %} {%- set cond0 = hourly[weather_entity].forecast[hourlytime].condition %} {%- set next_setting = as_timestamp(state_attr('sun.sun', 'next_setting')) %} {%- set next_rising = as_timestamp(state_attr('sun.sun', 'next_rising')) %} {%- set cond0_time = as_timestamp(hourly[weather_entity].forecast[hourlytime].datetime) %} {%- if cond0_time > next_setting and cond0_time < next_rising %} {%- if cond0 == 'sunny' %} night {% elif cond0 == 'partlycloudy' %} night-partly-cloudy {% else %} {{ cond0 }} {% endif %} {%- else %} {{ cond0 }} {%- endif %} weather_hourly_temperature_3: > {%- if 'hourly_intervals' not in this.attributes %} {%- set hourlytime = (default_3 | int) %} {%- else %} {%- set hourlytime = ((this.attributes.hourly_intervals[3] | default(default_3)) | int) %} {%- endif %} {{ hourly[weather_entity].forecast[hourlytime].temperature | round }} weather_hourly_timestamp_3: > {%- if 'hourly_intervals' not in this.attributes %} {%- set hourlytime = (default_3 | int) %} {%- else %} {%- set hourlytime = ((this.attributes.hourly_intervals[3] | default(default_3)) | int) %} {%- endif %} {%- set timestamp = as_timestamp(hourly[weather_entity].forecast[hourlytime].datetime) | timestamp_custom(time_format) %} {{ timestamp.lstrip(strip_zero) }} weather_daily_title: "{{ titles[2] }}" weather_daily_condition_0: > {{ daily[weather_entity].forecast[daily_0].condition }} weather_daily_temperature_0: > {{ daily[weather_entity].forecast[daily_0].temperature | round }} weather_daily_timestamp_0: > {{ as_timestamp(daily[weather_entity].forecast[daily_0].datetime) | timestamp_custom('%a') }} weather_daily_condition_1: > {{ daily[weather_entity].forecast[daily_1].condition }} weather_daily_temperature_1: > {{ daily[weather_entity].forecast[daily_1].temperature | round }} weather_daily_timestamp_1: > {{ as_timestamp(daily[weather_entity].forecast[daily_1].datetime) | timestamp_custom('%a') }} weather_daily_condition_2: > {{ daily[weather_entity].forecast[daily_2].condition }} weather_daily_temperature_2: > {{ daily[weather_entity].forecast[daily_2].temperature | round }} weather_daily_timestamp_2: > {{ as_timestamp(daily[weather_entity].forecast[daily_2].datetime) | timestamp_custom('%a') }} weather_daily_condition_3: > {{ daily[weather_entity].forecast[daily_3].condition }} weather_daily_temperature_3: > {{ daily[weather_entity].forecast[daily_3].temperature | round }} weather_daily_timestamp_3: > {{ as_timestamp(daily[weather_entity].forecast[daily_3].datetime) | timestamp_custom('%a') }} - trigger: - platform: time_pattern minutes: /1 variables: waketime: > {# Edit and order the schedule from midnight 00:00 to 23:59 as needed #} {%- set waketimes = [] %} {%- set waketimes = waketimes + ["00:05"] %} {%- set waketimes = waketimes + ["06:05"] %} {%- set waketimes = waketimes + ["08:05"] %} {%- set waketimes = waketimes + ["10:05"] %} {%- set waketimes = waketimes + ["12:05"] %} {%- set waketimes = waketimes + ["14:05"] %} {%- set waketimes = waketimes + ["16:05"] %} {%- set waketimes = waketimes + ["18:05"] %} {%- set waketimes = waketimes + ["21:05"] %} {%- set waketime = namespace(next = "") %} {%- set waketime_all = [] %} {%- for test in waketimes %} {%- set waketime.next = (now().strftime('%Y-%m-%d')|string) + " " + (test|string) %} {%- if (now().strftime('%Y-%m-%d %H:%M:%S')|string|as_datetime) < (waketime.next|as_datetime) %} {%- break %} {%- endif %} {%- endfor %} {%- if (now().strftime('%Y-%m-%d %H:%M:%S')|string|as_datetime) > (waketime.next|as_datetime) %} {%- set waketime.next = (now().strftime('%Y-%m-%d')|string) + " " + (waketimes[0]|string) %} {%- set waketime_helper = ((as_timestamp(waketime.next|as_datetime + timedelta(days=1)) - as_timestamp(now()|as_datetime))|int(0)) %} {%- else %} {%- set waketime_helper = ((as_timestamp(waketime.next|as_datetime) - as_timestamp(now()|as_datetime))|int(0)) %} {%- endif %} {%- set waketime_all = [waketime.next] + [waketime_helper] + [waketimes] %} {{waketime_all}} sensor: - name: eInk WeatherBoard Wake Times unique_id: eink_weatherboard_wake_times state: "{{ this.attributes.next_wake_time | default('Not Available') }}" attributes: wake_times: "{{ waketime[2] | default('Not Available') }}" next_wake_time: "{{ waketime[0] | default(999999) }}" wake_time_helper: "{{ waketime[1] | default('Not Available') }}"