# ============================================================================= # Template Sensors for Timer Remaining Time # ============================================================================= # Add to configuration.yaml: template: !include templates.yaml # Or merge into your existing template configuration. # # Each area gets a sensor that calculates: # - Remaining seconds (state) # - Original duration in seconds (attribute) # - Timer state: idle, active, paused (attribute) # - Progress percentage (attribute) # # Naming convention: sensor._timer_remaining_seconds # # To add a new area, copy the template block and replace the area name. # ============================================================================= # Triggered sensors update every second when timers are active - trigger: # Update every second for active timers - platform: time_pattern seconds: "/1" # Also update when any timer state changes - platform: state entity_id: - timer.kitchen - timer.bedroom - timer.playroom # Add more timer entities here as needed sensor: # ========================================================================= # Kitchen Timer Sensor # ========================================================================= - name: "Kitchen Timer Remaining Seconds" unique_id: kitchen_timer_remaining_seconds unit_of_measurement: "s" device_class: duration state: > {% set timer = states.timer.kitchen %} {% if timer is none or timer.state == 'unavailable' %} 0 {% elif timer.state == 'active' and timer.attributes.finishes_at is defined %} {% set finish = as_datetime(timer.attributes.finishes_at) %} {% set remaining = (finish - now()).total_seconds() | int %} {{ [remaining, 0] | max }} {% elif timer.state == 'paused' and timer.attributes.remaining is defined %} {% set parts = timer.attributes.remaining.split(':') %} {% if parts | length == 3 %} {{ (parts[0] | int) * 3600 + (parts[1] | int) * 60 + (parts[2] | float) | int }} {% else %} 0 {% endif %} {% else %} 0 {% endif %} attributes: duration_seconds: > {% set timer = states.timer.kitchen %} {% if timer is none or timer.state == 'unavailable' %} 0 {% elif timer.attributes.duration is defined %} {% set parts = timer.attributes.duration.split(':') %} {% if parts | length == 3 %} {{ (parts[0] | int) * 3600 + (parts[1] | int) * 60 + (parts[2] | float) | int }} {% else %} 0 {% endif %} {% else %} 0 {% endif %} timer_state: "{{ states('timer.kitchen') }}" progress_percent: > {% set timer = states.timer.kitchen %} {% if timer is none or timer.state in ['unavailable', 'idle'] %} 0 {% else %} {% set remaining = this.state | int(0) %} {% set duration = this.attributes.get('duration_seconds', 0) | int(1) %} {% if duration > 0 %} {{ ((duration - remaining) / duration * 100) | round(0) | int }} {% else %} 0 {% endif %} {% endif %} # ========================================================================= # Bedroom Timer Sensor # ========================================================================= - name: "Bedroom Timer Remaining Seconds" unique_id: bedroom_timer_remaining_seconds unit_of_measurement: "s" device_class: duration state: > {% set timer = states.timer.bedroom %} {% if timer is none or timer.state == 'unavailable' %} 0 {% elif timer.state == 'active' and timer.attributes.finishes_at is defined %} {% set finish = as_datetime(timer.attributes.finishes_at) %} {% set remaining = (finish - now()).total_seconds() | int %} {{ [remaining, 0] | max }} {% elif timer.state == 'paused' and timer.attributes.remaining is defined %} {% set parts = timer.attributes.remaining.split(':') %} {% if parts | length == 3 %} {{ (parts[0] | int) * 3600 + (parts[1] | int) * 60 + (parts[2] | float) | int }} {% else %} 0 {% endif %} {% else %} 0 {% endif %} attributes: duration_seconds: > {% set timer = states.timer.bedroom %} {% if timer is none or timer.state == 'unavailable' %} 0 {% elif timer.attributes.duration is defined %} {% set parts = timer.attributes.duration.split(':') %} {% if parts | length == 3 %} {{ (parts[0] | int) * 3600 + (parts[1] | int) * 60 + (parts[2] | float) | int }} {% else %} 0 {% endif %} {% else %} 0 {% endif %} timer_state: "{{ states('timer.bedroom') }}" progress_percent: > {% set timer = states.timer.bedroom %} {% if timer is none or timer.state in ['unavailable', 'idle'] %} 0 {% else %} {% set remaining = this.state | int(0) %} {% set duration = this.attributes.get('duration_seconds', 0) | int(1) %} {% if duration > 0 %} {{ ((duration - remaining) / duration * 100) | round(0) | int }} {% else %} 0 {% endif %} {% endif %} # ========================================================================= # Playroom Timer Sensor # ========================================================================= - name: "Playroom Timer Remaining Seconds" unique_id: playroom_timer_remaining_seconds unit_of_measurement: "s" device_class: duration state: > {% set timer = states.timer.playroom %} {% if timer is none or timer.state == 'unavailable' %} 0 {% elif timer.state == 'active' and timer.attributes.finishes_at is defined %} {% set finish = as_datetime(timer.attributes.finishes_at) %} {% set remaining = (finish - now()).total_seconds() | int %} {{ [remaining, 0] | max }} {% elif timer.state == 'paused' and timer.attributes.remaining is defined %} {% set parts = timer.attributes.remaining.split(':') %} {% if parts | length == 3 %} {{ (parts[0] | int) * 3600 + (parts[1] | int) * 60 + (parts[2] | float) | int }} {% else %} 0 {% endif %} {% else %} 0 {% endif %} attributes: duration_seconds: > {% set timer = states.timer.playroom %} {% if timer is none or timer.state == 'unavailable' %} 0 {% elif timer.attributes.duration is defined %} {% set parts = timer.attributes.duration.split(':') %} {% if parts | length == 3 %} {{ (parts[0] | int) * 3600 + (parts[1] | int) * 60 + (parts[2] | float) | int }} {% else %} 0 {% endif %} {% else %} 0 {% endif %} timer_state: "{{ states('timer.playroom') }}" progress_percent: > {% set timer = states.timer.playroom %} {% if timer is none or timer.state in ['unavailable', 'idle'] %} 0 {% else %} {% set remaining = this.state | int(0) %} {% set duration = this.attributes.get('duration_seconds', 0) | int(1) %} {% if duration > 0 %} {{ ((duration - remaining) / duration * 100) | round(0) | int }} {% else %} 0 {% endif %} {% endif %} # ========================================================================= # Timer Progress Sensors (percentage for visual indicators) # ========================================================================= - sensor: - name: "Kitchen Timer Progress" unique_id: kitchen_timer_progress unit_of_measurement: "%" state: > {{ state_attr('sensor.kitchen_timer_remaining_seconds', 'progress_percent') | int(0) }} availability: "{{ has_value('sensor.kitchen_timer_remaining_seconds') }}" - name: "Bedroom Timer Progress" unique_id: bedroom_timer_progress unit_of_measurement: "%" state: > {{ state_attr('sensor.bedroom_timer_remaining_seconds', 'progress_percent') | int(0) }} availability: "{{ has_value('sensor.bedroom_timer_remaining_seconds') }}" - name: "Playroom Timer Progress" unique_id: playroom_timer_progress unit_of_measurement: "%" state: > {{ state_attr('sensor.playroom_timer_remaining_seconds', 'progress_percent') | int(0) }} availability: "{{ has_value('sensor.playroom_timer_remaining_seconds') }}" # ========================================================================= # Timer Active Binary Sensors # ========================================================================= - binary_sensor: - name: "Kitchen Timer Active" unique_id: kitchen_timer_active device_class: running state: > {{ states('timer.kitchen') in ['active', 'paused'] or is_state('switch.kitchen_voice_assistant_timer_ringing', 'on') }} - name: "Bedroom Timer Active" unique_id: bedroom_timer_active device_class: running state: > {{ states('timer.bedroom') in ['active', 'paused'] or is_state('switch.bedroom_voice_assistant_timer_ringing', 'on') }} - name: "Playroom Timer Active" unique_id: playroom_timer_active device_class: running state: > {{ states('timer.playroom') in ['active', 'paused'] or is_state('switch.playroom_voice_assistant_timer_ringing', 'on') }} # ========================================================================= # Timer Ringing Binary Sensors # Wrap switch entities to handle unavailable/unknown states gracefully # ========================================================================= - name: "Kitchen Timer Ringing" unique_id: kitchen_timer_ringing_binary state: "{{ is_state('switch.kitchen_voice_assistant_timer_ringing', 'on') }}" - name: "Bedroom Timer Ringing" unique_id: bedroom_timer_ringing_binary state: "{{ is_state('switch.bedroom_voice_assistant_timer_ringing', 'on') }}" - name: "Playroom Timer Ringing" unique_id: playroom_timer_ringing_binary state: "{{ is_state('switch.playroom_voice_assistant_timer_ringing', 'on') }}"