Timer Entities with Home Assistant Voice

So one of my biggest gripes with the Home Assistant Voice was that I couldn’t have timer entities in home assistant to use with my dashboard and to be able to set timers on different satellites (or different rooms in my case).

I fixed this now with a rather simple automation and some help from LLM.

Here is how it works:

You need to set up a timer for each area under helpers. So I set up timer.kitchen, timer.living_room and so on.

Here is the automation that is triggered by custom sentences. I have to specify {room} and {duration}. I am using an LLM to have it format the spoken duration into a timedelta string.

Automation:
alias: VA Set Timer to Duration
description: ""
triggers:
  - trigger: conversation
    command:
      - Set {room} timer to {duration}
      - Start {duration} timer on {room}
conditions: []
actions:
  - choose:
      - conditions:
          - condition: template
            value_template: >-
              {{ trigger.slots.room == "kitchen" or trigger.slots.room ==
              "Kitchen" }}
        sequence:
          - alias: Send the request to the LLM
            action: conversation.process
            data:
              text: >-
                You are an AI process that transforms a timer command into a
                structured timedelta string.


                This is the voice command query provided by the user: "{{
                trigger.sentence }}"


                Here is an example of a structured timedelta string that I
                expect in response: 00:30:00 The timedelta string works like
                this: the first two numbers represent the hours,  the second two
                numbers the minutes and the last two numbers the second. So the
                example shows 30 Minutes. 

                This is the duration provided by the voice command: "{{
                trigger.slots.duration }}"

                Please format this into a timedelta string using the provided
                explanation. 

                IMPORTANT: You must reply with only the timedelta string,
                nothing before nor after because your response will be processed
                by a action component of a smart home service.  So also no code
                tags. Only the timedelta string!
              agent_id: conversation.chatgpt
            response_variable: timedelta
          - action: timer.start
            metadata: {}
            data:
              duration: "{{ timedelta.response.speech.plain.speech }}"
            target:
              entity_id: timer.kitchen
          - set_conversation_response: "{{ trigger.slots.room }} timer set to {{ trigger.slots.duration }}"
      - conditions:
          - condition: template
            value_template: >-
              {{ trigger.slots.room == "bathroom" or trigger.slots.room ==
              "Bathroom" }}
        sequence:
          - alias: Send the request to the LLM
            action: conversation.process
            data:
              text: >-
                You are an AI process that transforms a timer command into a
                structured timedelta string.


                This is the voice command query provided by the user: "{{
                trigger.sentence }}"


                Here is an example of a structured timedelta string that I
                expect in response: 00:30:00 The timedelta string works like
                this: the first two numbers represent the hours,  the second two
                numbers the minutes and the last two numbers the second. So the
                example shows 30 Minutes. 

                This is the duration provided by the voice command: "{{
                trigger.slots.duration }}"

                Please format this into a timedelta string using the provided
                explanation. 

                IMPORTANT: You must reply with only the timedelta string,
                nothing before nor after because your response will be processed
                by a action component of a smart home service.  So also no code
                tags. Only the timedelta string!
              agent_id: conversation.chatgpt
            response_variable: timedelta
          - action: timer.start
            metadata: {}
            data:
              duration: "{{ timedelta.response.speech.plain.speech }}"
            target:
              entity_id: timer.bathroom
          - set_conversation_response: "{{ trigger.slots.room }} timer set to {{ trigger.slots.duration }}"
      - conditions:
          - condition: template
            value_template: >-
              {{ trigger.slots.room == "living room" or trigger.slots.room ==
              "Living Room" }}
        sequence:
          - alias: Send the request to the LLM
            action: conversation.process
            data:
              text: >-
                You are an AI process that transforms a timer command into a
                structured timedelta string.


                This is the voice command query provided by the user: "{{
                trigger.sentence }}"


                Here is an example of a structured timedelta string that I
                expect in response: 00:30:00 The timedelta string works like
                this: the first two numbers represent the hours,  the second two
                numbers the minutes and the last two numbers the second. So the
                example shows 30 Minutes. 

                This is the duration provided by the voice command: "{{
                trigger.slots.duration }}"

                Please format this into a timedelta string using the provided
                explanation. 

                IMPORTANT: You must reply with only the timedelta string,
                nothing before nor after because your response will be processed
                by a action component of a smart home service.  So also no code
                tags. Only the timedelta string!
              agent_id: conversation.chatgpt
            response_variable: timedelta
          - action: timer.start
            metadata: {}
            data:
              duration: "{{ timedelta.response.speech.plain.speech }}"
            target:
              entity_id: timer.living_room
          - set_conversation_response: "{{ trigger.slots.room }} timer set to {{ trigger.slots.duration }}"
      - conditions:
          - condition: template
            value_template: >-
              {{ trigger.slots.room == "Office" or trigger.slots.room ==
              "office" }}
        sequence:
          - alias: Send the request to the LLM
            action: conversation.process
            data:
              text: >-
                You are an AI process that transforms a timer command into a
                structured timedelta string.


                This is the voice command query provided by the user: "{{
                trigger.sentence }}"


                Here is an example of a structured timedelta string that I
                expect in response: 00:30:00 The timedelta string works like
                this: the first two numbers represent the hours,  the second two
                numbers the minutes and the last two numbers the second. So the
                example shows 30 Minutes. 

                This is the duration provided by the voice command: "{{
                trigger.slots.duration }}"

                Please format this into a timedelta string using the provided
                explanation. 

                IMPORTANT: You must reply with only the timedelta string,
                nothing before nor after because your response will be processed
                by a action component of a smart home service.  So also no code
                tags. Only the timedelta string!
              agent_id: conversation.chatgpt
            response_variable: timedelta
          - action: timer.start
            metadata: {}
            data:
              duration: "{{ timedelta.response.speech.plain.speech }}"
            target:
              entity_id: timer.office
          - set_conversation_response: "{{ trigger.slots.room }} timer set to {{ trigger.slots.duration }}"
      - conditions:
          - condition: template
            value_template: >-
              {{ trigger.slots.room == "bedroom" or trigger.slots.room ==
              "Bedroom" }}
        sequence:
          - alias: Send the request to the LLM
            action: conversation.process
            data:
              text: >-
                You are an AI process that transforms a timer command into a
                structured timedelta string.


                This is the voice command query provided by the user: "{{
                trigger.sentence }}"


                Here is an example of a structured timedelta string that I
                expect in response: 00:30:00 The timedelta string works like
                this: the first two numbers represent the hours,  the second two
                numbers the minutes and the last two numbers the second. So the
                example shows 30 Minutes. 

                This is the duration provided by the voice command: "{{
                trigger.slots.duration }}"

                Please format this into a timedelta string using the provided
                explanation. 

                IMPORTANT: You must reply with only the timedelta string,
                nothing before nor after because your response will be processed
                by a action component of a smart home service.  So also no code
                tags. Only the timedelta string!
              agent_id: conversation.chatgpt
            response_variable: timedelta
          - action: timer.start
            metadata: {}
            data:
              duration: "{{ timedelta.response.speech.plain.speech }}"
            target:
              entity_id: timer.bedroom
          - set_conversation_response: "{{ trigger.slots.room }} timer set to {{ trigger.slots.duration }}"
      - conditions:
          - condition: template
            value_template: >-
              {{ trigger.slots.room == "guest room" or trigger.slots.room ==
              "Guest Room" }}
        sequence:
          - alias: Send the request to the LLM
            action: conversation.process
            data:
              text: >-
                You are an AI process that transforms a timer command into a
                structured timedelta string.


                This is the voice command query provided by the user: "{{
                trigger.sentence }}"


                Here is an example of a structured timedelta string that I
                expect in response: 00:30:00 The timedelta string works like
                this: the first two numbers represent the hours,  the second two
                numbers the minutes and the last two numbers the second. So the
                example shows 30 Minutes. 

                This is the duration provided by the voice command: "{{
                trigger.slots.duration }}"

                Please format this into a timedelta string using the provided
                explanation. 

                IMPORTANT: You must reply with only the timedelta string,
                nothing before nor after because your response will be processed
                by a action component of a smart home service.  So also no code
                tags. Only the timedelta string!
              agent_id: conversation.chatgpt
            response_variable: timedelta
          - action: timer.start
            metadata: {}
            data:
              duration: "{{ timedelta.response.speech.plain.speech }}"
            target:
              entity_id: timer.guest_room
          - set_conversation_response: "{{ trigger.slots.room }} timer set to {{ trigger.slots.duration }}"
    default:
      - set_conversation_response: "{{ trigger.slots.room }} is not a valid area. "
mode: single

The automation checks which room is specified and set with the help of the llm the duration of the timer and starts it.

I have another automation which runs when the timer finishes. I have set up an automation for each timer. Here is the automation for the kitchen timer as an example:

Kitchen timer Finished:
alias: VA Kitchen timer finished
description: ""
triggers:
  - event_type: timer.finished
    event_data:
      entity_id: timer.kitchen
    trigger: event
conditions: []
actions:
  - repeat:
      sequence:
        - parallel:
            - action: assist_satellite.announce
              metadata: {}
              data:
                message: Kitchen timer is finished
              target:
                entity_id: assist_satellite.home_assistant_voice_kitchen_assist_satellite
            - data:
                entity_id: media_player.home_assistant_voice_kitchen_media_player
                media_content_id: /local/sounds/alarm-digital-clock-beep.wav
                media_content_type: audio/mp3
              action: media_player.play_media
        - delay:
            hours: 0
            minutes: 0
            seconds: 2
            milliseconds: 0
      until:
        - condition: state
          entity_id: assist_satellite.home_assistant_voice_kitchen_assist_satellite
          state: listening
mode: single

The automation announces that the timer is finished and plays a mp3 from my local folder. It does this until the satellite changes to listen, so I just have to say “ok nabu” to make it stop, just like with the regular timer.

This actually works really well and I am quite happy with the functionality.

Maybe someone here wants to help me make this into a blueprint?

1 Like