Building a Daily Briefing

Building a Daily Briefing

If you saw my recent video on building a Daily Briefing in Home Assistant and you are here for some code, thanks for checking out my videos. If you haven’t seen the video you might wan to check it out first:

Building a Daily Briefing has the potential to get crazy real fast, but using macros can help simply things. For example you could have a macro for each domain of information you want to include, say weather or the status of the home security system. If you want to see what I use for my daily briefing you can find it on my github.

If you want to build your own I suggest you start with this basic framework.

{# Daily Briefing #}
{%- macro getGreeting() -%}
  I am sorry, I cannot do that, Dave.
{%- endmacro -%}

{{ getGreeting() }}

This will print out whatever you include in the macro called getGreeting. And if doesn’t have to be static text like this. If you could wrapped in if statements like this:

{# Daily Briefing #}
{%- macro getGreeting() -%}
  {% if now().strftime('%H')|int < 12 %}
    Good morning.
  {% elif now().strftime('%H')|int >= 12 and now().strftime('%H')|int < 17 %}
    Good afternoon.
  {% else %}
    Good evening.
  {% endif %}
Dave
{%- endmacro -%}

{{ getGreeting() }}

This allows you to get really complex with your briefing. And you could continue adding logic and macros for as much of this until you end up with something like:

{# Daily Briefing #}
{%- macro getGreeting() -%}
  {% if now().strftime('%H')|int < 12 %}
    Good morning.
  {% elif now().strftime('%H')|int >= 12 and now().strftime('%H')|int < 17 %}
    Good afternoon.
  {% else %}
    Good evening.
  {% endif %}

  {% if is_state('binary_sensor.morning','on') %} 
      Today is {{states.sensor.today_is.state }}, {{ as_timestamp(now()) | timestamp_custom('%B %d %Y') }}.
  {% else %}
      It is {{ now().strftime("%I:%M %p") }}
  {% endif %}

  Dave.
{%- endmacro -%}

{%- macro getDoorStatus() -%}
  The Pod Bay Doors are Closed.
{%- endmacro -%}

{# a macro that removes all newline characters, empty spaces, and returns formatted text #}
{%- macro cleanup(data) -%}
  {%- for item in data.split("\n")  if item | trim != "" -%}
    {{ item | trim }} {% endfor -%}
{%- endmacro -%}

{# a macro to call all macros :)  #}
{%- macro mother_of_all_macros() -%}
  {{ getGreeting() }}
  {{ getDoorStatus() }}
{%- endmacro -%}
  
  {# Call the macro  #}
{{- cleanup(mother_of_all_macros()) -}}

This now includes some macros to help clean up your message which isn’t needed unless you want to print that message on your lovelace dashboard or send it in a text. The above code outputs a message that looks like:

I hope that shows some of the power in macros, and gives you some ideas on how to build on that idea. Of course the advance stuff is going to require some jinja magic in both if/else statements to help you format a universal briefing, but you could just as easily build it printing the state of current sensors.

It could be as simple as built a macro that prints the current inside temperature using your thermostat:

The temperature inside is {{ state_attr('climate.home','current_temperature') }} degrees.

The reality is you can make this as simple or crazy as you want. The key parts are the code above and storing it somewhere.

In my setup I typically include it in it’s own YAML file like this example one. And I forgot to include in the video that in this file we need a “>” at the start of the file or you will get an error:

But feel free to take that example file and build on it. Once you have it ready you can use it in an automation like this:

- id: 1d8f396a-f6ec-460d-97e3-d11900418f95
    alias: Good Morning Report
    initial_state: true
    trigger:
      - platform: state
        entity_id: binary_sensor.kitchen_occupancy
        to: 'on'
    condition:
      - condition: time
        after: '06:45:00'
        before: '08:30:00'
      - condition: state
        entity_id: input_boolean.good_morning_report
        state: 'off'
    action:
    - service: tts.cloud_say
        data:
          entity_id: media_player.kitchen_display
          message: !include ../templates/speech/daily_briefing.yaml
          cache: true
          language: en-GB
          options: 
            gender: male

Or in a script like this:

morning_briefing:
    sequence:
    - service: tts.cloud_say
        data:
          entity_id: media_player.kitchen_display
          message: !include ../templates/speech/daily_briefing.yaml
          cache: true
          language: en-GB
          options: 
            gender: male

Using the include with a path to the YAML file you created allows you to replace the message contents with whatever your macros output. And keeping them separated could make it easier to maintain.

With any of my my content, if you have questions hit me up here or over on YouTube.

Mastodon