Home Assistant Script

I wanted a way to store up messages, such as “You have a new voicemail”, which could be read out easily when we get in and be used to flash the lights if we needed to read them. I found a very useful post by “123 Taras” and worked it up to a fairly easy solution.

  1. Add the template trigger to the Template: section of your Configuration.yaml
  2. Create a new script using the code below. It is fully prompted and can be tested easily in Dev tools.
  3. To add a message use call service to call the script and select “create message” with optional id
  4. Messages with id’s can be removed using “delete message” with the id
  5. All messages can be removed using “Delete All Messages”
  6. The macro can be used to list all the messages in a Markdown box or Template Card.

The core is a template sensor controlled by a trigger, which needs to be added to a package or to the configuration.yaml.

Template Trigger:

# ------------------------------------------------------------ Messaging System

- trigger:
    - platform: event
        - message_create
        - message_delete
        - message_delete_all
    - name: Messages
      state: "{{ now().timestamp() | timestamp_custom() }}"
        messages: >
          {% set msgs = this.attributes.get('messages', []) %}
          {% if trigger.event.event_type == 'message_create' %}
            {% set new = [{
                "id": trigger.event.data.id | default('TS' ~ now().timestamp()),
                "title": trigger.event.data.title | default(''),
                "message": trigger.event.data.message | default(''),
                "time": now().isoformat() }] %}
            {{ (msgs + new) }}
          {% elif trigger.event.event_type == 'message_delete' %}
            {% if trigger.event.data.id is defined %}
              {% set msgs = msgs | rejectattr('id', 'eq', trigger.event.data.id) | list %}
            {% elif trigger.event.data.index is defined and trigger.event.data.index | is_number %}
              {% set t = trigger.event.data.index | int(0) - 1 %}
              {% if 0 <= t < msgs|count %}
                {% set msgs = msgs | rejectattr('id', 'eq', msgs[t].id) | list %}
              {% endif %}
            {% endif %}
            {{ msgs }}
          {% else %}
            {{ [] }}
          {% endif %}

This can add messages and remove them by ID or all messages. In order to make it easy to remember the calls, I created a single Messages Update Script complete with parameters to allow messages to be added, removed etc.

Message update script:

alias: Messages Update
  - choose:
      - conditions:
          - condition: template
            value_template: "{{action == 'create_message'}}"
          - event: message_create
              id: "{{id | default('TS' ~ now().timestamp())}}"
              title: "{{title}}"
              message: "{{message}}"
      - conditions:
          - condition: template
            value_template: "{{action == 'delete_message'}}"
          - event: message_delete
              id: "{{id | default('TS' ~ now().timestamp())}}"
      - conditions:
          - condition: template
            value_template: "{{action == 'delete_all_messages'}}"
          - event: message_delete_all
            event_data: {}
mode: single
    name: Action
    description: Action to take,  title and message are only required for Create
          - label: Create
            value: create_message
          - label: Delete Message By ID
            value: delete_message
          - label: Delete All Messages
            value: delete_all_messages
    name: Message ID
    description: Optional for Create, mandatory for delete by id
      text: null
    name: Message Title
    description: title for message
      text: null
    name: Message
    description: Message Text, mandatory for Create only
      text: null

The script above can be called easily in the Script UI or from the Developers tools. Finally a quick Jinja macro to read the messages or tell you there are none, which can be called direct from an intent or via a script for Alexa.

Jinja Macro to read the messages:

{%- macro read_messages() -%}
{% from 'easy_time.jinja' import easy_time  %} 
{% set msgs = state_attr('sensor.messages', 'messages') %}
{% set count = msgs| count %}
{%- if count == 0 -%}
You have no messages.
{%- else -%}
{% for m in msgs %}
Message {{loop.index}} received {{easy_time(m.time) }} ago
{{ m.title }}, {{ m.message }}.
{%- endfor %}
{%- endif -%}
{%- endmacro -%}

Note: The above script uses Petro31’s easy_time macros available on HACS to read out how old the message is.