# Companion to esphome/resin-curing-timer.yaml. # Keep the outlet and controller IDs in sync with that file's substitutions. # The timer helper is defined in helpers/timer.yaml. template: - sensor: - name: Resin Curing Deadline default_entity_id: sensor.resin_curing_deadline unique_id: resin_curing_deadline icon: mdi:timer-sand # The ESPHome display expects Unix epoch seconds, rather than an ISO date. state: >- {{ as_timestamp(state_attr('timer.resin_curing', 'finishes_at'), 0) | int if is_state('timer.resin_curing', 'active') else 0 }} automation: - id: resin_curing_timer_control alias: Resin Curing Timer - Control UV Light description: >- Handle the CYD presets and STOP button, turn off the UV outlet when the timer ends, and reconcile the timer and outlet after restart or recovery. triggers: - trigger: event event_type: esphome.resin_curing_timer event_data: controller: resin-curing-timer id: command - trigger: state entity_id: timer.resin_curing to: - idle - paused id: timer_stopped - trigger: event event_type: timer.finished event_data: entity_id: timer.resin_curing id: timer_finished - trigger: state entity_id: switch.resin_uv_light to: - "on" - "off" id: outlet_changed - trigger: homeassistant event: start id: startup - trigger: event event_type: automation_reloaded id: reload # Retry a missed shutoff once the outlet recovers, including after downtime. - trigger: time_pattern seconds: "/30" id: reconcile actions: - choose: - conditions: - condition: template value_template: >- {{ trigger.id == 'command' and trigger.event.data.get('command') == 'start' and trigger.event.data.get('minutes') | string in ['30', '45', '60', '90'] and states('switch.resin_uv_light') in ['on', 'off'] }} sequence: # Arm the shutoff before requesting power. Each preset replaces # the remaining time, matching the duration shown on the CYD. - action: timer.start target: entity_id: timer.resin_curing data: duration: "{{ (trigger.event.data.minutes | int) * 60 }}" - action: switch.turn_on target: entity_id: switch.resin_uv_light - conditions: - condition: template value_template: >- {{ trigger.id == 'command' and trigger.event.data.get('command') == 'stop' }} sequence: - action: switch.turn_off continue_on_error: true target: entity_id: switch.resin_uv_light - action: timer.cancel target: entity_id: timer.resin_curing default: # Ignore malformed commands. Recheck current state when a queued # event runs so an old expiry cannot stop a newly started session. - condition: template value_template: "{{ trigger.id != 'command' }}" - choose: - conditions: - condition: template value_template: >- {{ not is_state('timer.resin_curing', 'active') and not is_state('switch.resin_uv_light', 'off') }} sequence: - action: switch.turn_off continue_on_error: true target: entity_id: switch.resin_uv_light - conditions: - condition: state entity_id: timer.resin_curing state: active - condition: state entity_id: switch.resin_uv_light state: "off" sequence: # A physical/HA outlet shutoff ends the displayed countdown. - action: timer.cancel target: entity_id: timer.resin_curing mode: queued max: 20