678 lines
35 KiB
YAML
678 lines
35 KiB
YAML
blueprint:
|
||
name: "AWTRIX Weather ⛈️ + Forecast + \U0001F315️"
|
||
description: "\nThis is somewhat of a mega-weather blueprint with moon phase support.
|
||
However for it work correctly you will need a variety of different things setup.
|
||
It was initially designed to use in partnership with a personal weather station
|
||
however it seems to work fine with OpenWeather as well or any other provider that
|
||
offers an hourly forecast.\n\n\n![](https://raw.githubusercontent.com/jeeftor/HomeAssistant/master/docs/weather.gif)\n\n![](https://raw.githubusercontent.com/jeeftor/HomeAssistant/master/docs/sunset.gif)\nThis
|
||
blueprint will publish to two separate topics. `jeef_weather` for the weather
|
||
report and `jeef_weather_sun` if its near sunrise/set\n## ⚠️ REQUIREMENTS ⚠️\nFor
|
||
this blueprint to work you MUST have a few things pre-setup. \n### Moon Integration
|
||
\U0001F315️\n .------.\n ( I MOON ) ..\n `------' .' /\n O
|
||
\ / ;\n o i OO\n C `-. Make sure you've\n |
|
||
\ <-' enabled\n ( ,--. the MOON Sensor\n V
|
||
\ \\_)\n \\ :\n `._\\. \n\n\nThe moon integration
|
||
is required. You can add it via the [moon](https://www.home-assistant.io/integrations/moon/)
|
||
page or just by [clicking here](https://my.home-assistant.io/redirect/config_flow_start?domain=moon)\n###
|
||
Moon Rise/Set Sensor \U0001F315️ ⏲️\n\n M\n (X)\n // \\\\
|
||
\ Lets use a GeoLocation to find\n // \\\\ out the Moon Rise / Set\n
|
||
\ // \\\\ TIMES\n // \\\\\n / \\\n\nAs Home
|
||
Assistant doesn't _currently_ provide moon rise/set times you will need to get
|
||
this from some api. You can use the [ipgeolocation](https://app.ipgeolocation.io)
|
||
API.\nTo do so you will need to create an account and extract your `API_KEY`.
|
||
Additionally you need your `LAT` and `LON`.\nThen you can add a [REST](https://www.home-assistant.io/integrations/sensor.rest/)
|
||
sensor to your `configuraiton.yaml` file like the one here:\n\n resource: https://api.ipgeolocation.io/astronomy?lat=<LAT>&long=<LON>&apiKey=<API_KEY>\n
|
||
\ name: ip_geo_location\n scan_interval: 300\n value_template: \"OK\"\n
|
||
\ json_attributes:\n - moonrise\n - moonset\n - moon_altitude\n\n###
|
||
Icons\nYou can call my custom script which will prompt you for an Awtrix device
|
||
and then upload the required icons:\n \n (If you have windows I don't know if
|
||
this will work)\n\n bash -c \"$(curl -fsSL https://raw.githubusercontent.com/jeeftor/HomeAssistant/master/icons/upload_icon.sh)\"\n\n_This
|
||
blueprint ~will~ may be updated as new features_\n![](https://www.gravatar.com/avatar/3b9968835eb719e5d78a04ba7a2bafbd?s=64)
|
||
https://raw.githubusercontent.com/jeeftor/HomeAssistant/master/blueprints/automation/awtrix_weatherflow.yaml\n"
|
||
domain: automation
|
||
input:
|
||
awtrix:
|
||
name: AWTRIX Device
|
||
description: Select the Awtrix light
|
||
selector:
|
||
device:
|
||
integration: mqtt
|
||
manufacturer: Blueforcer
|
||
model: AWTRIX Light
|
||
multiple: true
|
||
forecast_var:
|
||
name: Hourly Forecast
|
||
description: "Select a sensor that provides an Hourly forecast (not a daily
|
||
one)\nThis integration has been tested with:\n\n - HACS [Weatherflow](https://github.com/briis/hass-weatherflow)
|
||
integration \n \n - HomeAssistant [Openweather](https://www.home-assistant.io/integrations/openweathermap/)\n"
|
||
selector:
|
||
entity:
|
||
filter:
|
||
- domain:
|
||
- weather
|
||
multiple: false
|
||
hours_to_show:
|
||
name: Forecast Hours to Show
|
||
description: 'How many hours of forecast do you wish to show along the bottom
|
||
of the display
|
||
|
||
'
|
||
selector:
|
||
number:
|
||
max: 24.0
|
||
min: 0.0
|
||
unit_of_measurement: hours
|
||
mode: box
|
||
step: 1.0
|
||
default: 12
|
||
forecast_temp_field:
|
||
name: Temperature Attributes
|
||
description: "Once you've selected your hourly forecast you will need to identify
|
||
which attributes in the forecast provides a temperature value. \n\n - If
|
||
you are using [Weatherflow](https://github.com/briis/hass-weatherflow) you
|
||
may be able to select from either `feels_like` or `temperature`\n\n - In
|
||
[Openweather](https://www.home-assistant.io/integrations/openweathermap/)
|
||
you only have access to `temperature`\n"
|
||
selector:
|
||
text: {}
|
||
default: feels_like
|
||
temp_digits:
|
||
name: Temp Digits
|
||
description: 'By default we will round the temp to the nearest whole-number.
|
||
If you want percisions you can change this to 1 or 2 in order to see more
|
||
decimalm places.
|
||
|
||
'
|
||
selector:
|
||
number:
|
||
min: 0.0
|
||
max: 2.0
|
||
step: 1.0
|
||
mode: box
|
||
unit_of_measurement: Decimal places
|
||
default: 0
|
||
temp_suffix:
|
||
name: Temperature suffix
|
||
description: "How do you want to display the temperature\nIf you live in a country
|
||
with the following flags:\n\U0001F1FA\U0001F1F8️\U0001F1F5\U0001F1F7️\U0001F1F5\U0001F1FC️\U0001F1E7\U0001F1FF️\U0001F1F0\U0001F1FE️\U0001F1EB\U0001F1F2️\U0001F1F2\U0001F1ED️\U0001F1FB\U0001F1EE️\U0001F1EC\U0001F1FA️\nYou
|
||
probbaly use Farenheit.\nEverybody else in the \U0001F5FA️ seems to rock the
|
||
Metric System"
|
||
selector:
|
||
select:
|
||
options:
|
||
- label: None
|
||
value: ''
|
||
- label: °
|
||
value: °
|
||
- label: °F
|
||
value: °F
|
||
- label: °C
|
||
value: °C
|
||
- label: F
|
||
value: F
|
||
- label: C
|
||
value: C
|
||
sort: false
|
||
custom_value: false
|
||
multiple: false
|
||
default: °
|
||
current_temp_var:
|
||
name: The current outside temperature
|
||
description: "Select a sensor either from a PWS or a forecast that provides
|
||
the current outside temperature you wish to display:\n\n - `sensor.openweathermap_feels_like_temperature`\n"
|
||
selector:
|
||
entity:
|
||
domain:
|
||
- sensor
|
||
multiple: false
|
||
default: sensor.weatherflow_air_temperature
|
||
color_matrix_json:
|
||
name: Color Matrix
|
||
description: "The `Color Matrix` will control colors map to temperature ranges
|
||
on the display. The format of this map is **JSON** \nHere you can enter a
|
||
temperature to color mapping. \n> Please note the format is *JSON*,\n \n\nSome
|
||
possible mappings are:\n#### USA: Farenheit 0-100 (Based on NOAA scale from
|
||
0-100)\n\n\n {\"0\": \"#FEC4FF\",\"10\": \"#D977DF\",\"20\": \"#9545BC\",\"30\":
|
||
\"#4B379C\",\"40\": \"#31B8DB\",\"50\": \"#31DB8B\",\"60\": \"#6ED228\",\"70\":
|
||
\"#FFFF28\",\"80\": \"#F87E27\",\"90\": \"#CF3927\",\"100\": \"#A12527\"}\n\n\n####
|
||
EURO: -12°c to -38°c based on USA NOAA Colors \n\n {\"-12\": \"#D977DF\",\"-6\":
|
||
\"#9545BC\",\"-1\": \"#4B379C\",\"0\": \"#FEC4FF\",\"4\": \"#31B8DB\",\"10\":
|
||
\"#31DB8B\",\"15\": \"#6ED228\",\"21\": \"#FFFF28\",\"27\": \"#F87E27\",\"32\":
|
||
\"#CF3927\",\"38\": \"#A12527\"}\n"
|
||
selector:
|
||
text:
|
||
multiline: true
|
||
default: "{\n \"0\": \"#FEC4FF\",\n \"10\": \"#D977DF\",\n \"20\": \"#9545BC\",\n
|
||
\ \"30\": \"#4B379C\",\n \"40\": \"#31B8DB\",\n \"50\": \"#31DB8B\",\n \"60\":
|
||
\"#6ED228\",\n \"70\": \"#FFFF28\",\n \"80\": \"#F87E27\",\n \"90\": \"#CF3927\",\n
|
||
\ \"100\": \"#A12527\"\n}\n"
|
||
moon:
|
||
name: Moon Phase Sensor
|
||
description: "\U0001F311️\U0001F312️\U0001F313️\U0001F314️\U0001F316️\U0001F317️\U0001F318️\nTo
|
||
setup a moon sensor see here: https://www.home-assistant.io/integrations/moon/\nor
|
||
just [clicking here](https://my.home-assistant.io/redirect/config_flow_start?domain=moon)\n"
|
||
selector:
|
||
entity:
|
||
multiple: false
|
||
filter:
|
||
- integration: moon
|
||
moon_rise_set:
|
||
name: Moon Riese/Set Sensor
|
||
description: "As Home Assistant doesn't provide moon rise/set times you will
|
||
need to get this from some api. In my personal setup I use [ipgeolocation](https://app.ipgeolocation.io)
|
||
as my api.\nYou can create a custom REST sensor as follows:\n``` sensor: -
|
||
platform: rest\n resource: https://api.ipgeolocation.io/astronomy?lat=<LAT>&long=-<LON>&apiKey=<API_KEY>\n
|
||
\ name: ip_geo_location\n scan_interval: 300\n value_template: \"OK\"\n
|
||
\ json_attributes:\n - moonrise\n - moonset\n - moon_altitude\n```\n"
|
||
selector:
|
||
entity:
|
||
multiple: false
|
||
filter:
|
||
- integration: rest
|
||
when_show_moon:
|
||
name: When should the moon be displayed
|
||
description: "Some people are really into the moon \U0001F43A️ and they are
|
||
called Wearwolves or maybe Astronomers. \n\nPlease select how and when you
|
||
want the moon displayed\n\nBy selecting `Always show moon` the moon will always
|
||
be drawn to the right of the display. Otherwise the moon will only be drawn
|
||
if its risen depending on the option selected.\n### NOTE:\n\n At Brightness
|
||
values less than 29 the greys of the moon will render green on the clock.\n"
|
||
selector:
|
||
select:
|
||
options:
|
||
- label: Never show moon
|
||
value: never
|
||
- label: Always show moon
|
||
value: always
|
||
- label: Only show moon if its risen
|
||
value: risen
|
||
- label: Only show moon if risen + night
|
||
value: night
|
||
sort: false
|
||
custom_value: false
|
||
multiple: false
|
||
default: night
|
||
use_moon_clear_night:
|
||
name: Swap Clear Night for Moon
|
||
description: '
|
||
|
||
The default case is for the moon to be drawn to the right-side of the clock,
|
||
however, you have the option if this is selected to repalce the `clear_night`
|
||
icon with the moon icon. This will only swap icons if the moon is currently
|
||
being displayed.
|
||
|
||
- ![](https://developer.lametric.com/content/apps/icon_thumbs/2314_icon_thumb.png?v=1)
|
||
- `full_moon`
|
||
|
||
- ![](https://developer.lametric.com/content/apps/icon_thumbs/2315_icon_thumb.png?v=1)
|
||
- `waning_gibbous`
|
||
|
||
- ![](https://developer.lametric.com/content/apps/icon_thumbs/2316_icon_thumb.png?v=1)
|
||
- `last_quarter`
|
||
|
||
- ![](https://developer.lametric.com/content/apps/icon_thumbs/2317_icon_thumb.png?v=1)
|
||
- `waning_crescent`
|
||
|
||
- ![](https://developer.lametric.com/content/apps/icon_thumbs/2318_icon_thumb.png?v=1)
|
||
- `new_moon`
|
||
|
||
- ![](https://developer.lametric.com/content/apps/icon_thumbs/2319_icon_thumb.png?v=1)
|
||
- `waxing_crescent`
|
||
|
||
- ![](https://developer.lametric.com/content/apps/icon_thumbs/2320_icon_thumb.png?v=1)
|
||
- `first_quarter`
|
||
|
||
- ![](https://developer.lametric.com/content/apps/icon_thumbs/2321_icon_thumb.png?v=1)
|
||
- `waxing_gibbous`
|
||
|
||
If you wish to use a different icon please enter its text in the box to the
|
||
right'
|
||
selector:
|
||
boolean: {}
|
||
default: true
|
||
use_moon_sunny_night:
|
||
name: Swap Sunny + Night for the Moon
|
||
description: Some weather integrations may not correctly implement the `clear-night`
|
||
weather state. In that case you can use this option to automatically swap
|
||
out the moon for if you have night + sunny
|
||
selector:
|
||
boolean: {}
|
||
default: true
|
||
show_sun_rise_set:
|
||
name: ☀️ Show Sunrise/Sunset
|
||
description: "Prior to both sunrise and sunset times offer a message about pending
|
||
sun transitional state.\n\n :\n `. ; .'\n
|
||
\ `. .-'''-. .'\n ;' __ _;'\n / '_ _`\\
|
||
\ TURN ME ON!\n | _( a ( a |\n ''''| (_) > |``````\n
|
||
\ \\ \\ / /\n `. `--'.'\n .' `-,,,-' `.\n
|
||
\ .' : `.\n :\n\n\n_You can change the icons
|
||
for sun rise/set way down below._\n"
|
||
selector:
|
||
boolean: {}
|
||
default: true
|
||
sun_event_minute_threshold:
|
||
name: "Sun Time Prior \U0001F570️"
|
||
description: "This value controls when to show sunrise/set notifications. \n\nIf
|
||
the sunrise will occur in `50` minutes and this value is set to `60` it will
|
||
show, however if this value is only `30` it won't show."
|
||
selector:
|
||
number:
|
||
min: 5.0
|
||
max: 1440.0
|
||
unit_of_measurement: min
|
||
step: 1.0
|
||
mode: slider
|
||
default: 30
|
||
sun_time_type:
|
||
name: Sun Time Type
|
||
description: "When showing a notification about sun rise/set it can offer 3
|
||
different time formats:\n\n - Relative Time: `12 min`\n - Actual Time:
|
||
\ `8:31 pm` or `22:31`\n"
|
||
selector:
|
||
select:
|
||
options:
|
||
- Relative
|
||
- Actual
|
||
sort: false
|
||
custom_value: false
|
||
multiple: false
|
||
default: Actual
|
||
sun_time_format:
|
||
name: Actual Time Format
|
||
description: "If you are using actual time you can enter a STRFTIME format string
|
||
here for the time. Some options would be:\n\n - `%H%M` which would render
|
||
`0529`\n \n - `%-I%M%p` which woudl render `529AM`\n - `%-I%:M%p` which
|
||
woudl render `5:29AM`\n\n\n\n For details see https://strftime.org/\n"
|
||
selector:
|
||
text:
|
||
type: text
|
||
multiline: false
|
||
default: '%-I%M%p'
|
||
message_duration_forecast:
|
||
name: Forecast Duration ⏱️
|
||
description: How long should the forecast message remain on the screen(in seconds). *If
|
||
you select `0` it will use the Global App Time*
|
||
selector:
|
||
number:
|
||
min: 0.0
|
||
max: 300.0
|
||
unit_of_measurement: sec
|
||
step: 1.0
|
||
mode: slider
|
||
default: 30
|
||
message_duration_riseset:
|
||
name: Sun Rise/Set Duration ⏱️
|
||
description: How long should the sunrise sunset message remain on the screen(in
|
||
seconds). *If you select `0` it will use the Global App Time*
|
||
selector:
|
||
number:
|
||
min: 0.0
|
||
max: 300.0
|
||
unit_of_measurement: sec
|
||
step: 1.0
|
||
mode: slider
|
||
default: 30
|
||
icon_clear_night:
|
||
name: Icon for clear-night
|
||
description: "\nThe default clear_night icon is: \n\n ![](https://developer.lametric.com/content/apps/icon_thumbs/53383_icon_thumb.gif?v=2)
|
||
- `53383`\n"
|
||
selector:
|
||
text: {}
|
||
default: w-clear-night
|
||
icon_cloudy:
|
||
name: Icon for cloudy
|
||
description: 'This is the icon ID which maps to the weather state: `cloudy`
|
||
|
||
![](https://developer.lametric.com/content/apps/icon_thumbs/53384_icon_thumb.gif?v=1)
|
||
|
||
'
|
||
selector:
|
||
text: {}
|
||
default: w-cloudy
|
||
icon_exceptional:
|
||
name: Icon for exceptional
|
||
description: 'This is the icon ID which maps to the weather state: `exceptional`
|
||
|
||
|
||
![](https://developer.lametric.com/content/apps/icon_thumbs/36637_icon_thumb.gif?v=1)
|
||
|
||
'
|
||
selector:
|
||
text: {}
|
||
default: w-exceptional
|
||
icon_fog:
|
||
name: Icon for fog
|
||
description: 'This is the icon ID which maps to the weather state: `fog`
|
||
|
||
![](https://developer.lametric.com/content/apps/icon_thumbs/17055_icon_thumb.gif?v=1)
|
||
|
||
'
|
||
selector:
|
||
text: {}
|
||
default: w-fog
|
||
icon_hail:
|
||
name: Icon for hail
|
||
description: 'This is the icon ID which maps to the weather state: `hail` (IF
|
||
YOU HAVE A BETTER ONE PLEASE LET ME KNOW)
|
||
|
||
![](https://developer.lametric.com/content/apps/icon_thumbs/53385_icon_thumb.gif?v=1)
|
||
|
||
'
|
||
selector:
|
||
text: {}
|
||
default: w-hail
|
||
icon_lightning:
|
||
name: Icon for lightning
|
||
description: 'This is the icon ID which maps to the weather state: `lightning`
|
||
|
||
![](https://developer.lametric.com/content/apps/icon_thumbs/29839_icon_thumb.gif?v=1)
|
||
|
||
'
|
||
selector:
|
||
text: {}
|
||
default: w-lightning
|
||
icon_lightning_rainy:
|
||
name: Icon for lightning-rainy
|
||
description: 'This is the icon ID which maps to the weather state: `lightning-rainy`
|
||
|
||
![](https://developer.lametric.com/content/apps/icon_thumbs/49299_icon_thumb.gif?v=4)
|
||
|
||
'
|
||
selector:
|
||
text: {}
|
||
default: w-lightning-rainy
|
||
icon_partlycloudy:
|
||
name: Icon for partlycloudy
|
||
description: "This is the icon ID which maps to the weather state: `partlycloudy`\n
|
||
\n![](https://developer.lametric.com/content/apps/icon_thumbs/2286_icon_thumb.gif?v=1)\n"
|
||
selector:
|
||
text: {}
|
||
default: w-partlycloudy
|
||
icon_pouring:
|
||
name: Icon for pouring
|
||
description: 'This is the default icon which maps to the weather state: `pouring`
|
||
|
||
![](https://developer.lametric.com/content/apps/icon_thumbs/49300_icon_thumb.gif?v=1)
|
||
|
||
'
|
||
selector:
|
||
text: {}
|
||
default: w-pouring
|
||
icon_rainy:
|
||
name: Icon for rainy
|
||
description: 'This is the default icon which maps to the weather state: `rainy`
|
||
|
||
![](https://developer.lametric.com/content/apps/icon_thumbs/2720_icon_thumb.gif?v=1)
|
||
|
||
'
|
||
selector:
|
||
text: {}
|
||
default: w-rainy
|
||
icon_snowy:
|
||
name: Icon for snowy
|
||
description: 'This is the icon ID which maps to the weather state: `snowy`
|
||
|
||
![](https://developer.lametric.com/content/apps/icon_thumbs/2289_icon_thumb.gif?v=1)
|
||
|
||
'
|
||
selector:
|
||
text: {}
|
||
default: w-snowy
|
||
icon_snowy_rainy:
|
||
name: Icon for snowy-rainy
|
||
description: 'This is the icon ID which maps to the weather state: `snowy-rainy`
|
||
|
||
![](https://developer.lametric.com/content/apps/icon_thumbs/49301_icon_thumb.gif?v=2)
|
||
|
||
'
|
||
selector:
|
||
text: {}
|
||
default: w-snowy-rainy
|
||
icon_sunny:
|
||
name: Icon for sunny
|
||
description: 'This is the icon ID which maps to the weather state: `sunny`
|
||
|
||
![](https://developer.lametric.com/content/apps/icon_thumbs/53386_icon_thumb.gif?v=1)
|
||
|
||
'
|
||
selector:
|
||
text: {}
|
||
default: w-sunny
|
||
icon_windy:
|
||
name: Icon for windy
|
||
description: 'This is the icon ID which maps to the weather state: `windy`
|
||
|
||
![](https://developer.lametric.com/content/apps/icon_thumbs/3363_icon_thumb.gif?v=1)
|
||
|
||
'
|
||
selector:
|
||
text: {}
|
||
default: w-windy
|
||
icon_windy_variant:
|
||
name: Icon for windy-variant
|
||
description: 'This is the icon ID which maps to the weather state: `windy-variant`
|
||
|
||
![](https://developer.lametric.com/content/apps/icon_thumbs/3363_icon_thumb.gif?v=1)
|
||
|
||
'
|
||
selector:
|
||
text: {}
|
||
default: w-windy-variant
|
||
icon_sunrise:
|
||
name: Icon for sunrise
|
||
description: 'This is the icon ID which maps to the `sunrise`
|
||
|
||
![](https://developer.lametric.com/content/apps/icon_thumbs/53418_icon_thumb.gif?v=1)
|
||
|
||
'
|
||
selector:
|
||
text: {}
|
||
default: w-sunrise
|
||
icon_sunset:
|
||
name: Icon for sunset
|
||
description: 'This is the icon ID which maps to the `sunset`
|
||
|
||
![](https://developer.lametric.com/content/apps/icon_thumbs/53417_icon_thumb.gif?v=1)
|
||
|
||
'
|
||
selector:
|
||
text: {}
|
||
default: w-sunset
|
||
source_url: https://raw.githubusercontent.com/jeeftor/HomeAssistant/master/blueprints/automation/awtrix_weatherflow.yaml
|
||
mode: restart
|
||
variables:
|
||
device_ids: !input awtrix
|
||
app_topic: jeef_weather
|
||
devices_topics: "{%- macro get_device_topic(device_id) %} {{ states((device_entities(device_id)
|
||
| select('search','device_topic') | list)[0]) }} {%- endmacro %}\n{%- set ns =
|
||
namespace(devices=[]) %} {%- for device_id in device_ids %}\n {%- set device=get_device_topic(device_id)|replace('
|
||
','') %}\n {% set ns.devices = ns.devices + [ device ~ '/custom/' ~ app_topic]
|
||
%}\n{%- endfor %} {{ ns.devices | reject('match','unavailable') | list}}"
|
||
forecast_var: !input forecast_var
|
||
forecast: '{{state_attr(forecast_var,''forecast'')}}'
|
||
weather: '{{states(forecast_var)}}'
|
||
hours_to_show: !input hours_to_show
|
||
moon: !input moon
|
||
moon_phase: '{{states(moon)}}'
|
||
moon_times: !input moon_rise_set
|
||
moon_rise: '{{state_attr(moon_times,''moonrise'')}}'
|
||
moon_set: '{{state_attr(moon_times,''moonset'')}}'
|
||
moon_alt: '{{state_attr(moon_times,''moon_altitude'')}}'
|
||
moon_risen: '{{moon_alt > 0}}'
|
||
when_show_moon: !input when_show_moon
|
||
show_moon: '{%- if when_show_moon == ''always'' %} True {%- elif when_show_moon
|
||
== ''never'' %} False {%- elif when_show_moon == ''risen'' %} {{moon_risen}} {%-
|
||
else %} {{state_attr(''sun.sun'', ''elevation'') < 0 and moon_risen}} {%- endif
|
||
%}'
|
||
message_duration: !input message_duration_forecast
|
||
message_duration_riseset: !input message_duration_riseset
|
||
current_temp_var: !input current_temp_var
|
||
temp_digits: !input temp_digits
|
||
temp_suffix: !input temp_suffix
|
||
current_temp: '{{states(current_temp_var)}}'
|
||
temp_text: "{%- macro round_and_set_temp(temp_var, temp_suffix, digits=0) -%} {%-
|
||
if has_value(temp_var) -%}\n {{ states(temp_var) | round(digits) ~ temp_suffix}}
|
||
\n{%- else -%} ?? {%- endif -%} {%- endmacro -%} {{ round_and_set_temp(current_temp_var,
|
||
temp_suffix, temp_digits)}}"
|
||
forecast_temp_field: !input forecast_temp_field
|
||
text_available_width: '{%- if show_moon %}16{%- else %}24{%- endif %}
|
||
|
||
'
|
||
text_len: "{%- macro get_text_len(string) %} {%- set length = namespace(value=0)
|
||
%} {%- for char in string %}\n {%- if char.isdigit() %}\n {%- set length.value
|
||
= length.value + 3 %}\n {%- elif char == '°' %}\n {%- set length.value = length.value
|
||
+ 2 %}\n {%- elif char == '.' %}\n {%- set length.value = length.value + 1
|
||
%}\n {%- elif char in ['-','C','F'] %}\n {%- set length.value = length.value
|
||
+ 3 %}\n {%- else %}\n {%- set length.value = length.value + 1 %}\n {%- endif
|
||
%}\n {%- if not loop.last %}\n {%- set length.value = length.value + 1 %}{%-
|
||
endif -%}\n{%- endfor -%} {{ length.value }} {%- endmacro %}\n{{get_text_len(temp_text)}}"
|
||
text_x: '{{8 + ((text_available_width - text_len)/2)}}'
|
||
sun_event_minute_threshold: !input sun_event_minute_threshold
|
||
sun_time_type: !input sun_time_type
|
||
sun_time_format: !input sun_time_format
|
||
icon_sunrise: !input icon_sunrise
|
||
icon_sunset: !input icon_sunset
|
||
show_sun_rise_set: !input show_sun_rise_set
|
||
sun_next_event: '{%- set rise = state_attr(''sun.sun'',''next_rising'') %} {%- set
|
||
set = state_attr(''sun.sun'',''next_setting'') %} {%- set ts_rise = rise |as_timestamp
|
||
%} {%- set ts_set = set |as_timestamp %} {{ iif(ts_set < ts_rise,''sunset'',''sunrise'')
|
||
}}'
|
||
sun_min_until_next_event: '{%- set rise = state_attr(''sun.sun'',''next_rising'')
|
||
%} {%- set set = state_attr(''sun.sun'',''next_setting'') %} {%- set ts_rise =
|
||
rise |as_timestamp %} {%- set ts_set = set |as_timestamp %} {{ iif(sun_next_event
|
||
== ''sunrise'',(ts_rise - utcnow()|as_timestamp) / 60,(ts_set - utcnow()|as_timestamp)
|
||
/ 60) | round(0) }}'
|
||
sun_next_str: "{%- set rise = state_attr('sun.sun','next_rising') %} {%- set set
|
||
= state_attr('sun.sun','next_setting') %} {%- set ts_rise = rise |as_timestamp
|
||
%} {%- set ts_set = set |as_timestamp %} {%- if sun_time_type == 'Actual' %}\n
|
||
\ {{ iif(sun_next_event == 'sunrise',(ts_rise | as_datetime | as_local).strftime(sun_time_format),
|
||
\ (ts_set | as_datetime | as_local).strftime(sun_time_format)) }}\n{%- else %}
|
||
{#- relative time #}\n {% set hours = sun_min_until_next_event // 60 %}\n {%
|
||
set remaining_minutes = sun_min_until_next_event % 60 %}\n\n {% if hours == 0
|
||
%}\n {{ remaining_minutes }} min\n {% else %}\n [\n {\"t\":\"{{hours}}\",
|
||
\"c\":\"#ffffff\"},\n {\"t\":\"h\", \"c\":\"#9c9d97\"},\n {\"t\":\"{{remaining_minutes}}\",
|
||
\"c\":\"#ffffff\"},\n {\"t\":\"m\", \"c\":\"#9c9d97\"}\n ]\n {% endif
|
||
%}\n \n{%- endif %}"
|
||
sun_event_icon: '{{ iif(sun_next_event == ''sunrise'', icon_sunrise, icon_sunset)
|
||
}}'
|
||
sun_event_payload: '{"icon":"{{sun_event_icon}}", "text":"{{sun_next_str}}", "duration":
|
||
{{message_duration_riseset}}}'
|
||
sun_payload: '{%- if show_sun_rise_set %} {{ iif(sun_event_minute_threshold >= sun_min_until_next_event,
|
||
sun_event_payload, "{}") }} {%- else %} {} {%- endif %}'
|
||
icon_clear_night: !input icon_clear_night
|
||
use_moon_clear_night: !input use_moon_clear_night
|
||
use_moon_sunny_night: !input use_moon_sunny_night
|
||
icon_cloudy: !input icon_cloudy
|
||
icon_exceptional: !input icon_exceptional
|
||
icon_fog: !input icon_fog
|
||
icon_hail: !input icon_hail
|
||
icon_lightning: !input icon_lightning
|
||
icon_lightning_rainy: !input icon_lightning_rainy
|
||
icon_partlycloudy: !input icon_partlycloudy
|
||
icon_pouring: !input icon_pouring
|
||
icon_rainy: !input icon_rainy
|
||
icon_snowy: !input icon_snowy
|
||
icon_snowy_rainy: !input icon_snowy_rainy
|
||
icon_sunny: !input icon_sunny
|
||
icon_windy: !input icon_windy
|
||
icon_windy_variant: !input icon_windy_variant
|
||
clear_night_dict: "{{ dict({\n 'full_moon': '2314',\n 'waning_gibbous': '2315',\n
|
||
\ 'last_quarter': '2316',\n 'waning_crescent': '2317',\n 'new_moon': '2318',\n
|
||
\ 'waxing_crescent': '2319',\n 'first_quarter': '2320',\n 'waxing_gibbous':
|
||
'2321'}) }}"
|
||
color_matrix_json: !input color_matrix_json
|
||
color_dict: "{% set b = color_matrix_json | from_json %} {%- set ns = namespace(tuples=[])
|
||
%} {%- for k,v in b | items -%}\n {%- set key = k|float -%}\n {%- set ns.tuples
|
||
= ns.tuples + [(key,v)] %} \n{% endfor %} {{ dict.from_keys(ns.tuples) }}"
|
||
icon_dict: '{{ dict({''clear-night'': icon_clear_night, ''cloudy'': icon_cloudy,
|
||
''exceptional'': icon_exceptional, ''fog'': icon_fog, ''hail'': icon_hail, ''lightning'':
|
||
icon_lightning, ''lightning-rainy'': icon_lightning_rainy, ''partlycloudy'': icon_partlycloudy,
|
||
''pouring'': icon_pouring, ''rainy'': icon_rainy, ''snowy'': icon_snowy, ''snowy-rainy'':
|
||
icon_snowy_rainy, ''sunny'': icon_sunny, ''windy'': icon_windy, ''windy-variant'':
|
||
icon_windy_variant})}}'
|
||
icon: "{%- if ((weather == 'clear_night') and use_moon_clear_night) %}\n {{clear_night_dict[moon_phase]}}\n{%-
|
||
elif (sun_next_event == 'sunrise') and use_moon_sunny_night and (weather == 'sunny')
|
||
-%}\n \n{%- else %}\n {{ icon_dict[weather] }}\n{%- endif %}\n"
|
||
moon_data: "{%- macro draw_moon(phase,x=22,y=0) %}\n {%- if phase == 'first_quarter'
|
||
\ %}\n {\"db\":[{{x}},{{y}},8,8,[0,0,3355443,3355443,14079702,14079702,0,0,0,3355443,3355443,3355443,15790320,14079702,14079702,0,3355443,3355443,3355443,3355443,13355979,13355979,14079702,14079702,3355443,3355443,1644825,3355443,13355979,15790320,15790320,14079702,3355443,3355443,1644825,3355443,15790320,15790320,15790320,14079702,3355443,3355443,3355443,3355443,15790320,13355979,14079702,14079702,0,3355443,3355443,3355443,15790320,14079702,14079702,0,0,0,3355443,3355443,14079702,14079702,0,0]]}\n
|
||
\ {%- endif %}\n {%- if phase == 'full_moon' %}\n {\"db\":[{{x}},{{y}},8,8,[0,0,14079702,14079702,14079702,14079702,0,0,0,14079702,14079702,15790320,15790320,14079702,14079702,0,14079702,14079702,15790320,15790320,11974326,11974326,14079702,14079702,14079702,15790320,11974326,15790320,11974326,15790320,15790320,14079702,14079702,15790320,11974326,15790320,15790320,15790320,15790320,14079702,14079702,14079702,15790320,15790320,15790320,11974326,14079702,14079702,0,14079702,14079702,11974326,15790320,14079702,14079702,0,0,0,14079702,14079702,14079702,14079702,0,0]]}\n
|
||
\ {%- endif %}\n {%- if phase == 'last_quarter' %}\n {\"db\":[{{x}},{{y}},8,8,[0,0,14079702,14079702,3487029,3487029,0,0,0,14079702,14079702,15790320,3487029,3487029,3487029,0,14079702,14079702,15790320,15790320,1907997,1907997,3487029,3487029,14079702,15790320,13553358,15790320,1907997,3487029,3487029,3487029,14079702,15790320,13553358,15790320,3487029,3487029,3487029,3487029,14079702,14079702,15790320,15790320,3487029,1907997,3487029,3487029,0,14079702,14079702,13553358,3487029,3487029,3487029,0,0,0,14079702,14079702,3487029,3487029,0,0]]}\n
|
||
\ {%- endif %}\n {%- if phase == 'new_moon' %}\n {\"db\":[{{x}},{{y}},8,8,[0,0,2763306,2763306,2763306,2763306,0,0,0,2763306,2763306,2763306,2763306,2763306,2763306,0,2763306,2763306,2763306,2763306,1842204,1842204,2763306,2763306,2763306,2763306,1842204,2763306,1842204,2763306,2763306,2763306,2763306,2763306,1842204,2763306,2763306,2763306,2763306,2763306,2763306,2763306,2763306,2763306,2763306,1842204,2763306,2763306,0,2763306,2763306,1842204,2763306,2763306,2763306,0,0,0,2763306,2763306,2763306,2763306,0,0]]}\n
|
||
\ {%- endif %}\n {%- if phase == 'waning_crescent' %}\n {\"db\":[{{x}},{{y}},8,8,[0,0,14079702,14079702,2763306,2763306,0,0,0,14079702,14079702,2763306,2763306,2763306,2763306,0,14079702,14079702,2763306,2763306,1842204,1842204,2763306,2763306,14079702,15790320,1842204,2763306,1842204,2763306,2763306,2763306,14079702,15790320,1842204,2763306,2763306,2763306,2763306,2763306,14079702,14079702,2763306,2763306,2763306,1842204,2763306,2763306,0,14079702,14079702,1842204,2763306,2763306,2763306,0,0,0,14079702,14079702,2763306,2763306,0,0]]}\n
|
||
\ {%- endif %}\n {%- if phase == 'waning_gibbous' %}\n {\"db\":[{{x}},{{y}},8,8,[0,0,14079702,14079702,3552822,3552822,0,0,0,14079702,14079702,15790320,15790320,3552822,3552822,0,14079702,14079702,15790320,15790320,13421772,13421772,3552822,3552822,14079702,15790320,13421772,15790320,13421772,15790320,3552822,3552822,14079702,15790320,13421772,15790320,15790320,15790320,3552822,3552822,14079702,14079702,15790320,15790320,15790320,13421772,3552822,3552822,0,14079702,14079702,13421772,15790320,3552822,3552822,0,0,0,14079702,14079702,3552822,3552822,0,0]]}\n
|
||
\ {%- endif %}\n {%- if phase == 'waxing_crescent' %}\n {\"db\":[{{x}},{{y}},8,8,[0,0,3355443,3355443,14079702,14079702,0,0,0,3355443,3355443,3355443,3355443,14079702,14079702,0,3355443,3355443,3355443,3355443,1644825,1644825,14079702,14079702,3355443,3355443,1644825,3355443,1644825,3355443,15790320,14079702,3355443,3355443,1644825,3355443,3355443,3355443,15790320,14079702,3355443,3355443,3355443,3355443,3355443,1644825,14079702,14079702,0,3355443,3355443,3355443,3355443,14079702,14079702,0,0,0,3355443,3355443,14079702,14079702,0,0]]}\n
|
||
\ {%- endif %}\n {%- if phase == 'waxing_gibbous' %}\n {\"db\":[{{x}},{{y}},8,8,[0,0,3355443,3355443,14079702,14079702,0,0,0,3355443,3355443,14079702,15790320,14079702,14079702,0,3355443,3355443,15790320,15790320,12763842,12763842,14079702,14079702,3355443,3355443,12763842,15790320,12763842,15790320,15790320,14079702,3355443,3355443,12763842,15790320,15790320,15790320,15790320,14079702,3355443,3355443,15790320,15790320,15790320,12763842,14079702,14079702,0,3355443,3355443,12763842,15790320,14079702,14079702,0,0,0,3355443,3355443,14079702,14079702,0,0]]}\n
|
||
\ {%- endif %}\n{%- endmacro %}\n{%- if weather == 'clear-night' and use_moon_clear_night
|
||
-%} {{draw_moon(moon_phase,0,0)}} {%- elif(sun_next_event == 'sunrise') and use_moon_sunny_night
|
||
and (weather == 'sunny') -%} {{draw_moon(moon_phase,0,0)}} {%- else -%} {{draw_moon(moon_phase,23,0)}}
|
||
{%- endif -%}\n"
|
||
payload: "{%- macro interpolate(dictionary, x) -%}\n \n {%- set sorted_keys =
|
||
dictionary|dictsort -%}\n {%- set above = sorted_keys|selectattr('0', 'gt', x)|map(attribute='0')|list|first
|
||
-%}\n {%- set below = sorted_keys|selectattr('0', 'lt', x)|map(attribute='0')|list|last
|
||
-%}\n\n {#- Key matches x exactly -#}\n {%- if above is defined and dictionary[above]
|
||
== x -%}\n {%- set value = dictionary[above] -%}\n {{ value }}\n {%- elif
|
||
below is defined and dictionary[below] == x -%}\n {%- set value = dictionary[below]
|
||
-%}\n {{ value }}\n {#- Interpolation between two values -#}\n {%- elif below
|
||
is defined and above is defined -%}\n {%- set lower_value = dictionary[below]
|
||
-%}\n {%- set upper_value = dictionary[above] -%}\n {%- set lower_rgb =
|
||
lower_value[1:] -%}\n {%- set upper_rgb = upper_value[1:] -%}\n\n {%- set
|
||
lower_r = lower_rgb[0:2]|int(base=16) -%}\n {%- set lower_g = lower_rgb[2:4]|int(base=16)
|
||
-%}\n {%- set lower_b = lower_rgb[4:6]|int(base=16) -%}\n\n {%- set upper_r
|
||
= upper_rgb[0:2]|int(base=16) -%}\n {%- set upper_g = upper_rgb[2:4]|int(base=16)
|
||
-%}\n {%- set upper_b = upper_rgb[4:6]|int(base=16) -%}\n\n {%- set interpolation_factor
|
||
= (x - below) / (above - below) -%}\n {%- set interpolated_r = ((1 - interpolation_factor)
|
||
* lower_r + interpolation_factor * upper_r)|int -%}\n {%- set interpolated_g
|
||
= ((1 - interpolation_factor) * lower_g + interpolation_factor * upper_g)|int
|
||
-%}\n {%- set interpolated_b = ((1 - interpolation_factor) * lower_b + interpolation_factor
|
||
* upper_b)|int -%}\n\n {%- set interpolated_hex = '#' ~ '%02X' % interpolated_r
|
||
~ '%02X' % interpolated_g ~ '%02X' % interpolated_b -%}\n {{ interpolated_hex
|
||
}}\n {#- Only below key available -#}\n {%- elif below is defined -%}\n {%-
|
||
set value = dictionary[below] -%}\n {{ value }}\n {#- Only above key available
|
||
-#}\n {%- elif above is defined -%}\n {%- set value = dictionary[above] -%}\n
|
||
\ {{ value }}\n {#- No matching keys available -#}\n {%- else -%}\n No
|
||
matching key found.\n {%- endif -%}\n{%- endmacro -%}\n{#- Define macro to get
|
||
length of the forecast} {%- macro str_len(str) %} {%- if '.' in str %} {%- set
|
||
char_count = (str | length) -1 %}{{char_count * 3 + 1 + char_count}} {%- else
|
||
%} {%- set char_count = (str | length) %}{{char_count * 3 + (char_count - 1)}}
|
||
{%- endif %} {%- endmacro %}\n{#- Define a macro to draw out the forecast lines#}
|
||
{%- macro draw_forecast_lines(x,hours,height) %}\n {%- for hour in range(hours)
|
||
%}\n {%- if height == 0 %}\n {\"dp\": [{{x+hour}},7,\"{{interpolate(color_dict,
|
||
forecast[hour][forecast_temp_field]) }}\"]}\n {%- else %}\n {\"dl\": [{{x+hour}},7,{{x+hour}},{{7
|
||
- height}},\"{{interpolate(color_dict, forecast[hour][forecast_temp_field]) }}\"]}\n
|
||
\ {%- endif %}\n {%- if hour+1 != hours %},{%endif%}\n {%- endfor %}\n{%-
|
||
endmacro %}\n\n{# Define the color mapping dictionary #} { \"draw\": [\n {%-
|
||
if hours_to_show > 0 %}\n {{draw_forecast_lines(8,hours_to_show,0)}}\n {%- endif
|
||
%}\n {%- if current_temp != 'unavailable' -%}\n ,{\"dt\":[{{text_x}},1,\"{{temp_text}}\",\"{{interpolate(color_dict,
|
||
current_temp | float)}}\"]}\n {%- else -%}\n {\"dt\":\"err\"}\n {%- endif -%}\n
|
||
\n {% if show_moon %}\n ,{{moon_data}}\n {% endif %}\n], \"icon\": \"{{icon}}\",
|
||
\"duration\": {{message_duration}}, \"pushIcon\": 2, \"lifetime\": 120, \"lifetimeMode\":1,
|
||
\"weather\": \"{{weather}}\" }\n"
|
||
trigger:
|
||
- platform: time_pattern
|
||
seconds: /5
|
||
- platform: state
|
||
entity_id: !input forecast_var
|
||
id: Changes
|
||
enabled: true
|
||
condition: []
|
||
action:
|
||
- repeat:
|
||
for_each: '{{ devices_topics }}'
|
||
sequence:
|
||
- service: mqtt.publish
|
||
data:
|
||
qos: 0
|
||
retain: false
|
||
topic: '{{ repeat.item }}'
|
||
payload: '{{payload}}
|
||
|
||
'
|
||
- service: mqtt.publish
|
||
data:
|
||
qos: 0
|
||
retain: false
|
||
topic: '{{ repeat.item ~ ''_sun''}} '
|
||
payload: '{{sun_payload}}
|
||
|
||
'
|