various tidyups

This commit is contained in:
zorruno
2026-07-22 22:15:25 +12:00
parent b9e9c98f7e
commit 8fdcb128a3
15 changed files with 778 additions and 2030 deletions
@@ -9,7 +9,7 @@
# jobs_tracker_jobs.yaml
#
# VERSION:
# V2.3 2026-07-20
# V2.4 2026-07-21
#
# PURPOSE:
# Defines the job registry, MQTT Discovery entities, completion triggers and
@@ -41,6 +41,12 @@
# Complete
#
# VERSION HISTORY:
# V2.4 2026-07-21
# - Startup now waits for every retained job timestamp before refreshing.
# - Minute refreshes skip while retained MQTT state is not ready.
# - Restored stale event timestamps are no longer accepted as completions.
# - Discovery device firmware version updated to 2.4.
#
# V2.3 2026-07-20
# - All completion methods now obey the configured completion window.
# - Physical completion entities, Home Assistant discovery buttons and direct
@@ -360,7 +366,7 @@ script:
device_name: "Jobs Tracker"
device_manufacturer: "View Road Home Assistant"
device_model: "Shared household jobs tracker"
device_sw_version: "2.3"
device_sw_version: "2.4"
value_template_state: >-
{% raw %}{{ value_json.state | default('unknown') }}{% endraw %}
@@ -697,10 +703,23 @@ automation:
actions:
- action: script.jobs_tracker_publish_discovery
# Give Home Assistant a moment to process MQTT Discovery.
- delay: "00:00:10"
- variables:
jobs_tracker_jobs: *jobs_tracker_jobs
# Force retained state payloads onto each job topic.
# Do not refresh until every retained timestamp has returned from MQTT.
# Aborting on timeout protects valid retained data from being replaced by 0.
- wait_template: >-
{% set ns = namespace(ready=true) %}
{% for job in jobs_tracker_jobs %}
{% if not is_number(state_attr(job.state_entity, 'last_completed_ts')) %}
{% set ns.ready = false %}
{% endif %}
{% endfor %}
{{ ns.ready }}
timeout: "00:01:30"
continue_on_timeout: false
# Recalculate each job only after retained state is confirmed ready.
- action: script.jobs_tracker_dispatch
data:
update_all: true
@@ -711,25 +730,26 @@ automation:
mode: single
triggers:
- trigger: homeassistant
event: start
id: ha_start
- trigger: time_pattern
minutes: "/1"
id: tick
variables:
jobs_tracker_jobs: *jobs_tracker_jobs
conditions:
# Skip the minute tick until every retained timestamp is available.
- condition: template
value_template: >-
{% set ns = namespace(ready=true) %}
{% for job in jobs_tracker_jobs %}
{% if not is_number(state_attr(job.state_entity, 'last_completed_ts')) %}
{% set ns.ready = false %}
{% endif %}
{% endfor %}
{{ ns.ready }}
actions:
- if:
- condition: template
value_template: "{{ trigger.id == 'ha_start' }}"
then:
- action: script.jobs_tracker_publish_discovery
# Let retained MQTT Discovery and job state messages restore before
# the first refresh.
- delay: "00:01:30"
- action: script.jobs_tracker_dispatch
data:
update_all: true
@@ -747,9 +767,18 @@ automation:
conditions:
- condition: template
value_template: >-
{% set valid_state = trigger.to_state is not none
and trigger.to_state.state not in ['unknown', 'unavailable'] %}
{% set event_entity = trigger.entity_id.startswith('event.') %}
{% set event_ts = as_timestamp(trigger.to_state.state, 0)
if valid_state and event_entity else 0 %}
{% set event_age = as_timestamp(now()) - event_ts %}
{{
trigger.to_state is not none
and trigger.to_state.state not in ['unknown', 'unavailable']
valid_state
and (
not event_entity
or (event_ts > 0 and event_age >= 0 and event_age <= 30)
)
}}
actions: