commit 62e72d9713a029839a634678c664643ba1ae5c12 Author: Stuart Lamont Date: Tue May 30 13:27:15 2023 +1000 First Commit diff --git a/DadJoke.png b/DadJoke.png new file mode 100644 index 0000000..a552b5c Binary files /dev/null and b/DadJoke.png differ diff --git a/QuoteSensor.png b/QuoteSensor.png new file mode 100644 index 0000000..b68ccd1 Binary files /dev/null and b/QuoteSensor.png differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/RandomFact.png b/RandomFact.png new file mode 100644 index 0000000..a546420 Binary files /dev/null and b/RandomFact.png differ diff --git a/automations.yaml b/automations.yaml new file mode 100644 index 0000000..0bd818a --- /dev/null +++ b/automations.yaml @@ -0,0 +1,26 @@ +- id: `daily_briefing + alias: BRIEFING - Daily Briefing + description: '' + trigger: + - platform: state + entity_id: + - input_button.daily_briefing + condition: [] + action: + - service: script.announce_time + data: {} + - service: script.announce_weather_details + data: {} + - service: script.announce_inside_temperatures + data: {} + - service: script.announce_internal_temperatures + data: {} + - service: script.announce_dad_joke + data: {} + - service: script.announce_random_fact + data: {} + - service: script.announce_dad_joke_of_the_day + data: {} + - service: script.announce_end_of_briefing + data: {} + mode: single \ No newline at end of file diff --git a/briefing notes.md b/briefing notes.md new file mode 100644 index 0000000..3448f1d --- /dev/null +++ b/briefing notes.md @@ -0,0 +1,271 @@ +# Notes for creating a morning briefing from my smart home. + +## Determining the data points that we want + +__Current Temperature:__ `{{ state_attr ('weather.home','temperature') }}` +__Temperature Unit:__ `{{ state_attr ('weather.home','temperature_unit') }}` +__Wind-Speed:__ `{{ state_attr ('weather.home','wind_speed') }}` +__Wind-Speed-Unit:__ `{{ state_attr ('weather.home','wind_speed_unit') }}` +__Wind-Bearing:__ `{{ state_attr ('weather.home','temperature') }}` + +__Current State:__ `{{ states('weather.home') }}` + +__Wind-Cardinal:__ if Statement to determine Cardinal Direction of wind + +``` +{% set wind_bearing = state_attr('weather.home', 'wind_bearing') | float %} + +{% set directions = { + (0.0, 11.25): 'North', + (11.25, 33.75): 'North North East', + (33.75, 56.25): 'North East', + (56.25, 78.75): 'East North East', + (78.75, 101.25): 'East', + (101.25, 123.75): 'East South East', + (123.75, 146.25): 'South Eeast', + (146.25, 168.75): 'South South East', + (168.75, 191.25): 'South', + (191.25, 213.75): 'South South West', + (213.75, 236.25): 'South West', + (236.25, 258.75): 'West South West', + (258.75, 281.25): 'West', + (281.25, 303.75): 'West North West', + (303.75, 326.25): 'North West', + (326.25, 348.75): 'North Nort West', + (348.75, 360.0): 'North' +} %} + +{% for rng, direction in directions.items() %} + {% if wind_bearing >= rng[0] and wind_bearing < rng[1] %} + The wind is blowing from the {{ direction }} direction. + {% endif %} +{% endfor %} +``` + +__Forecast Conditions__: + +``` + +{% for forecast_item in state_attr('weather.home', 'forecast' ) %} + {{ forecast_item.datetime }} + {% if forecast_item.condition == 'rainy'%} + It looks like there's rain expected at around {{ forecast_item.datetime.split('T')[1][:2] }} o'clock. You might want to take an umbrella if you're leaving the house. + {% else %} + {% endif %} +{% endfor %} +``` +__Most Common Condition:__ +``` +{% set conditions = [] %} +{% for item in forecast %} + {% set _ = conditions.append(item.condition) %} +{% endfor %} + +{% set most_common_condition = conditions|groupby('self')|map('list')|max(attribute='|length')|first %} + +Most common condition: {{ most_common_condition }} + + +``` +__Forecast High/Low Temp__ +``` +{% set weather = state_attr('weather.home', 'forecast') %} +{% set high_temp = weather[0].temperature %} +{% set low_temp = weather[0].templow %} + +{% for entry in weather %} + {% if entry.temperature > high_temp %} + {% set high_temp = entry.temperature %} + {% endif %} + {% if entry.templow < low_temp %} + {% set low_temp = entry.templow %} + {% endif %} + {% if entry.condition == 'rainy'%} + It looks like there's rain expected at around {{ entry.datetime.split('T')[1][:2] }} o'clock. You might want to take an umbrella if you're leaving the house. + {% endif %} +{% endfor %} + +The forecast high is {{ high_temp }} °C +With a Low of {{ low_temp }} °C +``` + +__Dining Room Temperature__: + + +__Service Call__: + +``` +service: notify.alexa_media_office_echo_dot +data: + message: " + +{% set current_temp = state_attr ('weather.home','temperature') | float %} +{% set wind_bearing = state_attr('weather.home', 'wind_bearing') | float %} +{% set wind_speed = state_attr('weather.home','wind_speed') | float %} +{% set current_condition = states('weather.home') %} +{% set current_time = states('sensor.time') %} + +{% if current_condition == 'partlycloudy' %} + {% set current_condition = 'Partly Cloudy' %} +{% endif %} + +{% set directions = { + (0.0, 11.25): 'North', + (11.25, 33.75): 'North North East', + (33.75, 56.25): 'North East', + (56.25, 78.75): 'East North East', + (78.75, 101.25): 'East', + (101.25, 123.75): 'East South East', + (123.75, 146.25): 'South Eeast', + (146.25, 168.75): 'South South East', + (168.75, 191.25): 'South', + (191.25, 213.75): 'South South West', + (213.75, 236.25): 'South West', + (236.25, 258.75): 'West South West', + (258.75, 281.25): 'West', + (281.25, 303.75): 'West North West', + (303.75, 326.25): 'North West', + (326.25, 348.75): 'North Nort West', + (348.75, 360.0): 'North' +} %} + +{% set hour = current_time.split(':')[0] | int %} +{% set minute = current_time.split(':')[1] %} + + + + +{% if hour >= 6 and hour < 12 %} + Good morning! +{% elif hour >= 12 and hour < 18 %} + Good afternoon! +{% elif hour >= 18 or hour < 6 %} + Good evening! +{% endif %} + +{% set suffix = 'AM' if hour < 12 else 'PM' %} +{% set hour_12 = hour if hour <= 12 else hour - 12 %} + + +It's currently {{ hour_12 }}:{{ minute }} {{ suffix }}. + +Outside, It's {{ current_condition }} and {{ current_temp }} degrees Celsius. + +{% set weather = state_attr('weather.home', 'forecast') %} +{% set high_temp = weather[0].temperature %} +{% set low_temp = weather[0].templow %} + +{% for entry in weather %} + {% if entry.temperature > high_temp %} + {% set high_temp = entry.temperature %} + {% endif %} + {% if entry.templow < low_temp %} + {% set low_temp = entry.templow %} + {% endif %} + {% if entry.condition == 'rainy'%} + It looks like there's rain expected at around {{ entry.datetime.split('T')[1][:2] }} o'clock. You might want to take an umbrella if you're leaving the house. + {% endif %} +{% endfor %} + +{% if high_temp > 30 %} + It's going to be a hot one +{% elif 20 < high_temp < 30 %} + It should be a warm day +{% elif 15 < high_temp < 20 %} + It's going to be a pretty mild temperature today +{% elif 10 < high_temp < 15 %} + It seems like it'll be a bit chilly today +{% elif 0 < high_temp < 10 %} + It's going to be a cold day +{% else %} + It's going to be freezing today +{% endif %} + +The forecast high is {{ high_temp }} °C. + +With a Low of {{ low_temp }} °C . +{% if low_temp > 30 %} + Wow. That's hot! +{% elif 20 < low_temp < 30 %} + it's not going to go below 20 degrees today. +{% elif 10 < low_temp < 20 %} + it might get a little bit chilly. +{% elif 0 < low_temp < 10 %} + That's cold. +{% else %} + Absolutely freezing! +{% endif %} + + + +{% if wind_speed > 50 %} + Its very windy outside. +{% endif %} +{% for rng, direction in directions.items() %} + {% if wind_bearing >= rng[0] and wind_bearing < rng[1] %} + The wind is currently blowing from the {{ direction }} direction, at {{ wind_speed }} kilometres per hour + {% endif %} + +{% endfor %} + +Inside it's currently {{ states('sensor.temperature_dining') }} °C in the Dining Room, +{{ states('sensor.lounge_ac_inside_temperature') }} °C in the Lounge, +{{ states('sensor.temperature_office')}} °C in the office, +and {{ states('sensor.master_bedroom_purifier_temperature') }} °C in the Master Bedroom. + +The {{ state_attr( 'sensor.quote_sensor', 'category' ) }} Quote of the day is by {{ state_attr( 'sensor.quote_sensor', 'author' ) }}. +They said. {{ states('sensor.quote_sensor') }} + +Here is a Dad Joke.. {{ states('sensor.dad_joke_of_the_hour') }} + +And a random fact.. {{ states('sensor.random_fact') }} + +{% if states('update.home_assistant_operating_system_update') == 'off' %} +There's a Home Assistant O S Update pending. +The Installed version is {{ state_attr('update.home_assistant_operating_system_update', 'installed_version') }} +The Available version is {{ state_attr('update.home_assistant_operating_system_update', 'latest_version') }} +{% endif %} + +{% if states('update.home_assistant_core_update') == 'off' %} +There's a Home Assistant Core Update pending. +The Installed version is {{ state_attr('update.home_assistant_core_update', 'installed_version') }} +The Available version is {{ state_attr('update.home_assistant_core_update', 'latest_version') }} +{% endif %} + +{% if states('update.esphome_update') == 'off' %} +There's an E S P Home Update pending. +The Installed version is {{ state_attr('update.esphome_update', 'installed_version') }} +The Available version is {{ state_attr('update.esphome_update', 'latest_version') }} +{% endif %} + +``` + +__Abstract it all:__ + +Break it all into Scripts and trigger them in sequence with the Automation. + + + +``` +service: notify.alexa_media_office_echo_dot +data: + message: " + +{% set current_time = states('sensor.time') %} +{% set hour = current_time.split(':')[0] | int %} +{% set minute = current_time.split(':')[1] %} + +{% if hour >= 6 and hour < 12 %} + Good morning! +{% elif hour >= 12 and hour < 18 %} + Good afternoon! +{% elif hour >= 18 or hour < 6 %} + Good evening! +{% endif %} + +{% set suffix = 'AM' if hour < 12 else 'PM' %} +{% set hour_12 = hour if hour <= 12 else hour - 12 %} + +It's currently {{ hour_12 }}:{{ minute }} {{ suffix }}. +" +``` \ No newline at end of file diff --git a/final call.md b/final call.md new file mode 100644 index 0000000..60703df --- /dev/null +++ b/final call.md @@ -0,0 +1,148 @@ +__Service Call__: + +``` +service: notify.alexa_media_office_echo_dot +data: + message: " + +{% set current_temp = state_attr ('weather.home','temperature') | float %} +{% set wind_bearing = state_attr('weather.home', 'wind_bearing') | float %} +{% set wind_speed = state_attr('weather.home','wind_speed') | float %} +{% set current_condition = states('weather.home') %} + + +{% if current_condition == 'partlycloudy' %} + {% set current_condition = 'Partly Cloudy' %} +{% endif %} + +{% set directions = { + (0.0, 11.25): 'North', + (11.25, 33.75): 'North North East', + (33.75, 56.25): 'North East', + (56.25, 78.75): 'East North East', + (78.75, 101.25): 'East', + (101.25, 123.75): 'East South East', + (123.75, 146.25): 'South Eeast', + (146.25, 168.75): 'South South East', + (168.75, 191.25): 'South', + (191.25, 213.75): 'South South West', + (213.75, 236.25): 'South West', + (236.25, 258.75): 'West South West', + (258.75, 281.25): 'West', + (281.25, 303.75): 'West North West', + (303.75, 326.25): 'North West', + (326.25, 348.75): 'North Nort West', + (348.75, 360.0): 'North' +} %} + +# get Current Time from Home Assistant +{% set current_time = states('sensor.time') %} +# Split time into hour +{% set hour = current_time.split(':')[0] | int %} +# and Minute +{% set minute = current_time.split(':')[1] %} + +# Say a time appropriate greeting +{% if hour >= 6 and hour < 12 %} + Good morning! +{% elif hour >= 12 and hour < 18 %} + Good afternoon! +{% elif hour >= 18 or hour < 6 %} + Good evening! +{% endif %} + +# Add AM or PM Suffix +{% set suffix = 'AM' if hour < 12 else 'PM' %} +{% set hour_12 = hour if hour <= 12 else hour - 12 %} + +# Announce the current Time +It's currently {{ hour_12 }}:{{ minute }} {{ suffix }}. + +Outside, It's {{ current_condition }} and {{ current_temp }} degrees Celsius. + +{% set weather = state_attr('weather.home', 'forecast') %} +{% set high_temp = weather[0].temperature %} +{% set low_temp = weather[0].templow %} + +{% for entry in weather %} + {% if entry.temperature > high_temp %} + {% set high_temp = entry.temperature %} + {% endif %} + {% if entry.templow < low_temp %} + {% set low_temp = entry.templow %} + {% endif %} + {% if entry.condition == 'rainy'%} + It looks like there's rain expected at around {{ entry.datetime.split('T')[1][:2] }} o'clock. You might want to take an umbrella if you're leaving the house. + {% endif %} +{% endfor %} + +{% if high_temp > 30 %} + It's going to be a hot one +{% elif 20 < high_temp < 30 %} + It should be a warm day +{% elif 15 < high_temp < 20 %} + It's going to be a pretty mild temperature today +{% elif 10 < high_temp < 15 %} + It seems like it'll be a bit chilly today +{% elif 0 < high_temp < 10 %} + It's going to be a cold day +{% else %} + It's going to be freezing today +{% endif %} + +The forecast high is {{ high_temp }} °C. + +With a Low of {{ low_temp }} °C . +{% if low_temp > 30 %} + Wow. That's hot! +{% elif 20 < low_temp < 30 %} + it's not going to go below 20 degrees today. +{% elif 10 < low_temp < 20 %} + it might get a little bit chilly. +{% elif 0 < low_temp < 10 %} + That's cold. +{% else %} + Absolutely freezing! +{% endif %} + +{% if wind_speed > 50 %} + Its very windy outside. +{% endif %} +{% for rng, direction in directions.items() %} + {% if wind_bearing >= rng[0] and wind_bearing < rng[1] %} + The wind is currently blowing from the {{ direction }} direction, at {{ wind_speed }} kilometres per hour + {% endif %} + +{% endfor %} + +Inside it's currently {{ states('sensor.temperature_dining') }} °C in the Dining Room, +{{ states('sensor.lounge_ac_inside_temperature') }} °C in the Lounge, +{{ states('sensor.temperature_office')}} °C in the office, +and {{ states('sensor.master_bedroom_purifier_temperature') }} °C in the Master Bedroom. + +The {{ state_attr( 'sensor.quote_sensor', 'category' ) }} Quote of the day is by {{ state_attr( 'sensor.quote_sensor', 'author' ) }}. +They said. {{ states('sensor.quote_sensor') }} + +Here is a Dad Joke.. {{ states('sensor.dad_joke_of_the_hour') }} + +And a random fact.. {{ states('sensor.random_fact') }} + +{% if states('update.home_assistant_operating_system_update') == 'off' %} +There's a Home Assistant O S Update pending. +The Installed version is {{ state_attr('update.home_assistant_operating_system_update', 'installed_version') }} +The Available version is {{ state_attr('update.home_assistant_operating_system_update', 'latest_version') }} +{% endif %} + +{% if states('update.home_assistant_core_update') == 'off' %} +There's a Home Assistant Core Update pending. +The Installed version is {{ state_attr('update.home_assistant_core_update', 'installed_version') }} +The Available version is {{ state_attr('update.home_assistant_core_update', 'latest_version') }} +{% endif %} + +{% if states('update.esphome_update') == 'off' %} +There's an E S P Home Update pending. +The Installed version is {{ state_attr('update.esphome_update', 'installed_version') }} +The Available version is {{ state_attr('update.esphome_update', 'latest_version') }} +{% endif %} + +``` \ No newline at end of file diff --git a/fun.md b/fun.md new file mode 100644 index 0000000..9093296 --- /dev/null +++ b/fun.md @@ -0,0 +1,144 @@ +# Home Assistant Templating and integrations to have some fun with your briefing +I wanted to add some fun things to the Announcement, So I went in search of different ways to do that. +I landed on adding: + +- A random quote +- a random fact +and +- a random Dad Joke + +The first hurdle is getting the data into Home Assistant to then be able to use it in the templates. + +Thankfully, I found a good source of all 3 available via REST API's, all from [API Ninjas](https://api-ninjas.com) +The API documentations are: +- [Dad Jokes](https://api-ninjas.com/api/dadjokes) +- [Random Facts](https://api-ninjas.com/api/facts) +- [Random Quotes](https://api-ninjas.com/api/quotes) + +There's plenty more API's that might be useful so I recommend checking out API Ninjas. You'll need to sign up for an API Key, but it's free. + +## Restful Sensor integration +So to get the data into Home Assistant, we're going to use the RESTful Sensor integration, this involves modifying your `configuration.yaml` file. + +I also make use of the `secrets.yaml` file to store the APINinjas API key. + +your secrets.yaml file entry should look like this: +``` +ninjas_api: +``` +obviously substituting `` for the API Key you were issued by API Ninjas. +### Pro-Tip +After Logging into API Ninjas website, you'll find your API Key at: +### My Account, +### API Statistics +and +### Show API Key + +## The Home Assistant RestFul API Setups + + + +### __Quote "sensor"__ + +The `configuration.yaml` entry I came up with for the Quote Sensor looks like this + +``` +sensor: + - platform: rest + name: Quote Sensor + unique_id: quote_sensor + resource: https://api.api-ninjas.com/v1/quotes? + method: GET + scan_interval: 7200 + headers: + X-Api-Key: !secret ninjas_api + value_template: "{{ value_json[0].quote }}" + json_attributes_path: "$.[0]" + json_attributes: + - "author" + - "category" +``` + +This creates a Sensor entity in Home Assistant with the "State" being the Quote, and attributes with the Author and the category. +![Quote Sensor Screenshot](QuoteSensor.png) + +This becomes important when we get to the Announcement + +### __Dad Joke__ + +For the Dad Joke, we don't really need any other attributes, so the code is a bit simpler + + +``` +sensor: + - platform: rest + name: Dad Joke Of the Hour + unique_id: dad_joke + resource: https://api.api-ninjas.com/v1/dadjokes?limit=1 + method: GET + scan_interval: 7200 + headers: + X-Api-Key: !secret ninjas_api + value_template: "{{ value_json[0].joke }}" +``` +Which creates a Sensor entity with the Dad Joke as it's State +![Dad Joke Sensor](DadJoke.png) + +### __Random Fact__ + +And again, very simple for the Random Fact + +``` +sensor: + - platform: rest + name: Random Fact + unique_id: random_fact + resource: https://api.api-ninjas.com/v1/facts?limit=1 + method: GET + scan_interval: 7200 + headers: + X-Api-Key: !secret ninjas_api + value_template: "{{ value_json.articles[0].title }}" +``` + +![Random Fact Sensor](RandomFact.png) + +## Announcing Jokes, facts, and quotes + +So for the quote, I want to know the "Category" of quote. +There's a list of categories in the [API Documentation](https://api-ninjas.com/api/quotes). +Expect results like: +- `marriage` +- `government` +- `age` +- `movies` + +so that line of code looks like this: +``` +The {{ state_attr( 'sensor.quote_sensor', 'category' ) }} Quote of the day is +``` +I also want to know who said it: +``` +by {{ state_attr( 'sensor.quote_sensor', 'author' ) }}. +``` +And lastly, obviously, the quote: +``` +They said. {{ states('sensor.quote_sensor') }} +``` + +``` +The {{ state_attr( 'sensor.quote_sensor', 'category' ) }} Quote of the day is by {{ state_attr( 'sensor.quote_sensor', 'author' ) }}. +They said. {{ states('sensor.quote_sensor') }} +``` + + + +### Put All Together +``` +The {{ state_attr( 'sensor.quote_sensor', 'category' ) }} Quote of the day is by {{ state_attr( 'sensor.quote_sensor', 'author' ) }}. +They said. {{ states('sensor.quote_sensor') }} + +Here is a Dad Joke.. {{ states('sensor.dad_joke_of_the_hour') }} + +And a random fact.. {{ states('sensor.random_fact') }} +``` \ No newline at end of file diff --git a/inside temps.md b/inside temps.md new file mode 100644 index 0000000..e69de29 diff --git a/scripts.yaml b/scripts.yaml new file mode 100755 index 0000000..d1e5bbc --- /dev/null +++ b/scripts.yaml @@ -0,0 +1,161 @@ +announce_weather_details: + alias: Announce Weather Details + sequence: + - service: notify.alexa_media + data: + message: "\n{% set current_temp = state_attr ('weather.home','temperature') + | float %} {% set wind_bearing = state_attr('weather.home', 'wind_bearing') + | float %} {% set wind_speed = state_attr('weather.home','wind_speed') | float + %} {% set current_condition = states('weather.home') %}\n\n{% if current_condition + == 'partlycloudy' %} \n {% set current_condition = 'Partly Cloudy' %}\n{% + endif %}\n{% set directions = { (0.0, 11.25): 'North', (11.25, 33.75): 'North + North East', (33.75, 56.25): 'North East', (56.25, 78.75): 'East North East', + (78.75, 101.25): 'East', (101.25, 123.75): 'East South East', (123.75, 146.25): + 'South Eeast', (146.25, 168.75): 'South South East', (168.75, 191.25): 'South', + (191.25, 213.75): 'South South West', (213.75, 236.25): 'South West', (236.25, + 258.75): 'West South West', (258.75, 281.25): 'West', (281.25, 303.75): 'West + North West', (303.75, 326.25): 'North West', (326.25, 348.75): 'North Nort + West', (348.75, 360.0): 'North' } %}\nOutside, It's {{ current_condition }} + and {{ current_temp }} °C.\n{% set weather = state_attr('weather.home', 'forecast') + %} {% set high_temp = weather[0].temperature %} {% set low_temp = weather[0].templow + %}\n{% for entry in weather %}\n {% if entry.temperature > high_temp %}\n + \ {% set high_temp = entry.temperature %}\n {% endif %}\n {% if entry.templow + < low_temp %}\n {% set low_temp = entry.templow %}\n {% endif %}\n {% + if entry.condition == 'rainy'%} \n It looks like there's rain expected + at around {{ entry.datetime.split('T')[1][:2] }} o'clock. \n You might + want to take an umbrella if you're planning on leaving the house.\n {% endif + %}\n{% endfor %}\n{% if high_temp > 30 %} \n It's going to be a hot one \n{% + elif 20 < high_temp < 30 %} \n It should be a warm day \n{% elif 15 < high_temp + < 20 %} \n It's going to be a pretty mild temperature today \n{% elif 10 + < high_temp < 15 %} \n It seems like it'll be a bit chilly today\n{% elif + 0 < high_temp < 10 %} \n It's going to be a cold day \n{% else %} \n It's + going to be freezing today \n{% endif %}\nThe forecast high is {{ high_temp + }} °C.\nWith a Low of {{ low_temp }} °C . {% if low_temp > 30 %} \n Wow. + That's hot! \n{% elif 20 < low_temp < 30 %}\n it's not going to go below + 20 degrees today. \n{% elif 10 < low_temp < 20 %} \n it might get a little + bit chilly. \n{% elif 0 < low_temp < 10 %} \n That's cold. \n{% else %} \n + \ Absolutely freezing! \n{% endif %}\n{% if wind_speed > 50 %}\n Its very + windy outside.\n{% elif 40 < wind_speed < 50 %}\n It's pretty windy at the + moment\n{% elif 30 < wind_speed < 40 %}\n Theres a strong breeze right now\n{% + elif 20 < wind_speed < 30 %}\n It's a bit breezy outside\n{% elif 10 < wind_speed + < 20 %}\n There's a light breeze\n{% else %}\n it's quite still\n{% endif + %} {% for rng, direction in directions.items() %} \n {% if wind_bearing >= + rng[0] and wind_bearing < rng[1] %} \n The wind is currently blowing from + the {{ direction }} direction, at {{ wind_speed }} kilometres per hour \n + \ {% endif %}\n{% endfor %} " + target: + - media_player.dining_room_echo_plus + mode: single +announce_time: + alias: Announce Time + sequence: + - service: notify.alexa_media + data: + message: '" {% set current_time = states(''sensor.time'') %} {% set hour = current_time.split('':'')[0] + | int %} {% set minute = current_time.split('':'')[1] %} + + {% if hour >= 6 and hour < 12 %} Good morning! {% elif hour >= 12 and hour + < 18 %} Good afternoon! {% elif hour >= 18 or hour < 6 %} Good evening! {% + endif %} + + {% set suffix = ''AM'' if hour < 12 else ''PM'' %} {% set hour_12 = hour if + hour <= 12 else hour - 12 %} + + It''s currently {{ hour_12 }}:{{ minute }} {{ suffix }}." + + ' + target: + - media_player.dining_room_echo_plus + mode: single +announce_internal_temperatures: + alias: Announce Quote of the Day + sequence: + - service: notify.alexa_media + data: + message: ' The {{ state_attr( ''sensor.quote_sensor'', ''category'' ) }} Quote + of the day is by {{ state_attr( ''sensor.quote_sensor'', ''author'' ) }}. They + said. {{ states(''sensor.quote_sensor'') }} ' + target: + - media_player.dining_room_echo_plus + mode: single + icon: mdi:comment-quote +announce_dad_joke_of_the_day: + alias: Announce Pending Updates + sequence: + - service: notify.alexa_media + data: + message: '{% if states(''update.home_assistant_operating_system_update'') == + ''on'' %} There''s a Home Assistant O S Update pending. The Installed version + is {{ state_attr(''update.home_assistant_operating_system_update'', ''installed_version'') + }}. The Available version is {{ state_attr(''update.home_assistant_operating_system_update'', + ''latest_version'') }}. {% endif %} {% if states(''update.home_assistant_core_update'') + == ''on'' %} There''s a Home Assistant Core Update pending. The Installed + version is {{ state_attr(''update.home_assistant_core_update'', ''installed_version'') + }}. The Available version is {{ state_attr(''update.home_assistant_core_update'', + ''latest_version'') }}. {% endif %} + + {% if states(''update.esphome_update'') == ''on'' %} There''s an E S P Home + Update pending. The Installed version is {{ state_attr(''update.esphome_update'', + ''installed_version'') }}. The Available version is {{ state_attr(''update.esphome_update'', + ''latest_version'') }}. {% endif %} ' + target: + - media_player.dining_room_echo_plus + mode: single + icon: mdi:update +announce_dad_joke: + alias: Announce Dad Joke + sequence: + - service: notify.alexa_media + data: + message: Here is a Dad Joke.. {{ states('sensor.dad_joke_of_the_hour') }} + target: + - media_player.dining_room_echo_plus + mode: single + icon: mdi:party-popper +announce_random_fact: + alias: Announce Random Fact + sequence: + - service: notify.alexa_media + data: + message: And a random fact.. {{ states('sensor.random_fact') }} + target: + - media_player.dining_room_echo_plus + mode: single +announce_end_of_briefing: + alias: Announce end of briefing + sequence: + - service: notify.alexa_media + data: + message: That's All I've got right now + target: + - media_player.dining_room_echo_plus + mode: single +test_everywhere_announcement: + alias: Test Everywhere Announcement + sequence: + - service: notify.alexa_media + data: + data: + type: tts + message: '" This is a Test "' + target: + - media_player.dining_room_echo_plus + - media_player.bedroom_echo_dot + - media_player.office_echo_dot + - media_player.spare_room_echo_dot + mode: single +announce_inside_temperatures: + alias: Announce Inside Temperatures + sequence: + - service: notify.alexa_media + data: + data: + type: tts + message: ' Inside it''s currently {{ states(''sensor.temperature_dining'') }} + °C in the Dining Room, {{ states(''sensor.lounge_ac_inside_temperature'') + }} °C in the Lounge, {{ states(''sensor.temperature_office'')}} °C in the + office, and {{ states(''sensor.master_bedroom_purifier_temperature'') }} °C + in the Master Bedroom. ' + target: + - media_player.dining_room_echo_plus + mode: single diff --git a/time.md b/time.md new file mode 100644 index 0000000..4e5c8af --- /dev/null +++ b/time.md @@ -0,0 +1,62 @@ +# Jinja template for Home Assistant for Time + +## get Current Time from Home Assistant +``` +{% set current_time = states('sensor.time') %} +``` +### extract the current hour +``` +{% set hour = current_time.split(':')[0] | int %} +``` +### and Minute +``` +{% set minute = current_time.split(':')[1] %} +``` + +## Say a time appropriate greeting +``` +{% if hour >= 6 and hour < 12 %} + Good morning! +{% elif hour >= 12 and hour < 18 %} + Good afternoon! +{% elif hour >= 18 or hour < 6 %} + Good evening! +{% endif %} +``` + +## Add AM or PM Suffix for announcement +``` +{% set suffix = 'AM' if hour < 12 else 'PM' %} +``` +## convert 24 hour time to 12 hour time +``` +{% set hour_12 = hour if hour <= 12 else hour - 12 %} +``` +## Announce the current Time +It's currently {{ hour_12 }}:{{ minute }} {{ suffix }}. + +## Put it all together: +``` +# get Current Time from Home Assistant +{% set current_time = states('sensor.time') %} +# Split time into hour +{% set hour = current_time.split(':')[0] | int %} +# and Minute +{% set minute = current_time.split(':')[1] %} + +# Say a time appropriate greeting +{% if hour >= 6 and hour < 12 %} + Good morning! +{% elif hour >= 12 and hour < 18 %} + Good afternoon! +{% elif hour >= 18 or hour < 6 %} + Good evening! +{% endif %} + +# Add AM or PM Suffix +{% set suffix = 'AM' if hour < 12 else 'PM' %} +{% set hour_12 = hour if hour <= 12 else hour - 12 %} + +# Announce the current Time +It's currently {{ hour_12 }}:{{ minute }} {{ suffix }}. +``` \ No newline at end of file diff --git a/weather temperature.md b/weather temperature.md new file mode 100644 index 0000000..fce0230 --- /dev/null +++ b/weather temperature.md @@ -0,0 +1,188 @@ +# Home Assistant Jinja 2 Templates for Weather Temperatures + +## Step-by-step + +### Get the current Temperature from Home Assistant +We're casting this as a float, probably no need, but I'd rather be safe. +``` +{% set current_temp = state_attr ('weather.home','temperature') | float %} +``` + +### Get the current weather condition from Home Assistant as well +``` +{% set current_condition = states('weather.home') %} +``` +### Fix the current Condition +When the Current weather condition is "Partly Cloudy" the default weather integration returns `partlycloudy` and it sounds odd when read out by a Text to Speech engine. +To fix it I added: +``` +{% if current_condition == 'partlycloudy' %} + {% set current_condition = 'Partly Cloudy' %} +{% endif %} +``` + +## Announce the current condition and Temperature +``` +Outside, It's {{ current_condition }} and {{ current_temp }} degrees Celsius. +``` + +## Figure out the Highs and Lows from the forecast +For weather information, I want to know the High and Low temp. This data is strangely not included by default in the default weather integration, so we have to figure it out ourselves. + +### Start by Extracting the `forecast` array data into a variable +``` +{% set weather = state_attr('weather.home', 'forecast') %} +``` + +### Instantiate a `high_temp` and `low_temp` variable +We're assigning the temperature from the 0th record in the array to get started. + +``` +{% set high_temp = weather[0].temperature %} +{% set low_temp = weather[0].templow %} +``` + +### Iterate through the array and set the `high_temp` or `low_temp` variables accordingly. +I've also added an `if` statement in here to announce if any of the forecast conditions are `rainy` and the `hour` that the rain is forecast for and to tell us to take an umbrella. +I've surrounded that code block with `###########` for clarity + +``` +{% for entry in weather %} + {% if entry.temperature > high_temp %} + {% set high_temp = entry.temperature %} + {% endif %} + {% if entry.templow < low_temp %} + {% set low_temp = entry.templow %} + {% endif %} + + ########### + # While we're here, if the condition for this hour is `rainy` let's announce that + {% if entry.condition == 'rainy'%} + It looks like there's rain expected at around {{ entry.datetime.split('T')[1][:2] }} o'clock. + You might want to take an umbrella if you're leaving the house. + {% endif %} + ########### + +{% endfor %} +``` + +### Some Qualitative statements about the `high_temp` +This code block looks at the `high_temp` variable and runs the if statement below to make a qualitative statement about it. +These have been built for °C and I pulled the qualitative statements out of my head. +Change them as you need to + +`Above 30°C` say "It's going to be a hot one" +`between 20°C and 30°C` say "It should be a warm day" +`between 15°C and 20°C` say "It's going to be a pretty mild temperature today" +`between 10°C and 15°C` say "It seems like it'll be a bit chilly today" +`between 0°C and 10°C` say "It's going to be a cold day" +else: the `high_temp` variable must be < 0°C +`< 0°C` say "It's going to be freezing today" + +``` +{% if high_temp > 30 %} + It's going to be a hot one +{% elif 20 < high_temp < 30 %} + It should be a warm day +{% elif 15 < high_temp < 20 %} + It's going to be a pretty mild temperature today +{% elif 10 < high_temp < 15 %} + It seems like it'll be a bit chilly today +{% elif 0 < high_temp < 10 %} + It's going to be a cold day +{% else %} + It's going to be freezing today +{% endif %} +``` + +### Announce the `high_temp` and `low_temp` values +Again, built for °C + +``` +The forecast high is {{ high_temp }} °C. +With a Low of {{ low_temp }} °C . +``` + +### Some qualitative statements about the `low_temp` +Again we're looking at °C and the statements and ranges are arbitrary, and can be adjusted to your tastes + +Remember these are for the `low_temp` variable, so it's not going to get colder than these + +`Above 30°C` say "Wow. That's hot!" +`between 20°C and 30°C` say "it's not going to get below 20°C toda.y" +`between 10°C and 20°C` say "it might get a little bit chilly." +`between 0°C and 10°C` say "That's cold." +`< 0°C` say "Absolutely freezing!" + +Puntuation like `.`, `!`, `?` and `,` is important in the text to speech statments so the timing sounds "natural" + +``` +{% if low_temp > 30 %} + Wow. That's hot! +{% elif 20 < low_temp < 30 %} + it's not going to go below 20°C today. +{% elif 10 < low_temp < 20 %} + it might get a little bit chilly. +{% elif 0 < low_temp < 10 %} + That's cold. +{% else %} + Absolutely freezing! +{% endif %} +``` + +## Now we can put it all together: +``` +{% set current_temp = state_attr ('weather.home','temperature') | float %} +{% set current_condition = states('weather.home') %} + +{% if current_condition == 'partlycloudy' %} + {% set current_condition = 'Partly Cloudy' %} +{% endif %} + +Outside, It's {{ current_condition }} and {{ current_temp }} degrees Celsius. + +{% set weather = state_attr('weather.home', 'forecast') %} +{% set high_temp = weather[0].temperature %} +{% set low_temp = weather[0].templow %} + +{% for entry in weather %} + {% if entry.temperature > high_temp %} + {% set high_temp = entry.temperature %} + {% endif %} + {% if entry.templow < low_temp %} + {% set low_temp = entry.templow %} + {% endif %} + {% if entry.condition == 'rainy'%} + It looks like there's rain expected at around {{ entry.datetime.split('T')[1][:2] }} o'clock. You might want to take an umbrella if you're leaving the house. + {% endif %} +{% endfor %} + +{% if high_temp > 30 %} + It's going to be a hot one +{% elif 20 < high_temp < 30 %} + It should be a warm day +{% elif 15 < high_temp < 20 %} + It's going to be a pretty mild temperature today +{% elif 10 < high_temp < 15 %} + It seems like it'll be a bit chilly today +{% elif 0 < high_temp < 10 %} + It's going to be a cold day +{% else %} + It's going to be freezing today +{% endif %} + +The forecast high is {{ high_temp }} °C. + +With a Low of {{ low_temp }} °C . +{% if low_temp > 30 %} + Wow. That's hot! +{% elif 20 < low_temp < 30 %} + it's not going to go below 20 degrees today. +{% elif 10 < low_temp < 20 %} + it might get a little bit chilly. +{% elif 0 < low_temp < 10 %} + That's cold. +{% else %} + Absolutely freezing! +{% endif %} +``` \ No newline at end of file diff --git a/weather wind.md b/weather wind.md new file mode 100644 index 0000000..1ccfeff --- /dev/null +++ b/weather wind.md @@ -0,0 +1,56 @@ +# Home Assistant Jinja Templating to anmnounce Wind Details + +## get the current wind speed and wind bearing in degrees from Home Assistant +``` +{% set wind_bearing = state_attr('weather.home', 'wind_bearing') | float %} +{% set wind_speed = state_attr('weather.home','wind_speed') | float %} +``` + +## This array is a list of Cardinal Directions allowing us to convert the +``` +{% set directions = { + (0.0, 11.25): 'North', + (11.25, 33.75): 'North North East', + (33.75, 56.25): 'North East', + (56.25, 78.75): 'East North East', + (78.75, 101.25): 'East', + (101.25, 123.75): 'East South East', + (123.75, 146.25): 'South Eeast', + (146.25, 168.75): 'South South East', + (168.75, 191.25): 'South', + (191.25, 213.75): 'South South West', + (213.75, 236.25): 'South West', + (236.25, 258.75): 'West South West', + (258.75, 281.25): 'West', + (281.25, 303.75): 'West North West', + (303.75, 326.25): 'North West', + (326.25, 348.75): 'North Nort West', + (348.75, 360.0): 'North' +} %} +``` + +## Announce a qualitative description of wind speed +``` +{% if wind_speed > 50 %} + Its very windy outside. +{% elif 40 < wind_speed < 50 %} + It's pretty windy at the moment +{% elif 30 < wind_speed < 40 %} + Theres a strong breeze right now +{% elif 20 < wind_speed < 30 %} + It's a bit breezy outside +{% elif 10 < wind_speed < 20 %} + There's a light breeze +{% else %} + it's quite still +{% endif %} +``` + +### +``` +{% for rng, direction in directions.items() %} + {% if wind_bearing >= rng[0] and wind_bearing < rng[1] %} + The wind is currently blowing from the {{ direction }} direction, at {{ wind_speed }} kilometres per hour + {% endif %} +{% endfor %} +``` \ No newline at end of file