#:########################################################################################:#
# Package: Pet Feeding and Jobs Timing
# File:    pet_feeding_and_jobs.yaml
# Version: v1.4.0
# Date:    2026-07-26
#
# Purpose:
#   Provides legacy MQTT pet activity sensors and Jobs-derived timing sensors for
#   the Lounge dog-feeding and depooping gauges.
#   v1.2.0: Added input_datetime helpers and automations so the View Road Events
#   home-feed-card shows correct X minutes ago after HA restart.
#
# Behaviour:
#   - Dog feeding reports the newest valid morning or evening completion time.
#   - Dog depooping reports the weekly Jobs completion time.
#   - Invalid or unrestored Jobs attributes make a timing sensor unavailable
#     instead of exposing a numeric sentinel value.
#
# Version History:
#   - v1.4.0 (2026-07-26): Announce four physical job completions on the Sony
#     lounge TV and both Pushover devices.
#   - v1.3.0 (2026-07-26): Restore retained dog-fed and jobs-done activity
#     feed publishing when physical completion events are received.
#   - v1.2.0 (2026-07-24): Added persistent input_datetime timestamps for
#     home-feed-card so time-ago survives HA restart.
#   - v1.1.0 (2026-07-21): Reject invalid Jobs timing attributes and remove the
#     999999-hour fallback from the dog-feeding gauge source.
#   - v1.0.0 (2026-07-21): Added Jobs-derived dog timing sensors for P010.
#:########################################################################################:#

#:######################################################################################:#
# LEGACY MQTT PET ACTIVITY AND TIMING SENSORS
#:######################################################################################:#
mqtt:
  sensor:
    - unique_id: dog_fed_activity
      name: "Dog Fed"
      state_topic: "viewroad-status/activityfeed/dogfed"
      icon: mdi:dog
    - unique_id: depooped_activity
      name: "DePooped"
      state_topic: "viewroad-status/activityfeed/depooped"
      icon: mdi:emoticon-poop
    - unique_id: jobs_done_activity
      name: "Jobs Done"
      state_topic: "viewroad-status/activityfeed/jobsdone"
      icon: mdi:notebook
    - unique_id: hours_since_jobs_done
      name: "Hours Since Jobs Done"
      state_topic: "viewroad-tele/petfeeding/hoursSinceJobsDone"
      unit_of_measurement: "Hours"
    - unique_id: hours_since_zorro_fed
      name: "Hours Since Zorro Fed"
      state_topic: "viewroad-tele/petfeeding/hoursSinceDogFed"
      unit_of_measurement: "Hours"
    - unique_id: hours_since_depooped
      name: "Hours Since DePooped"
      state_topic: "viewroad-tele/petfeeding/hoursSinceDePooped"
      unit_of_measurement: "Hours"

#:######################################################################################:#
# JOBS-DERIVED LOUNGE GAUGE SENSORS
#:######################################################################################:#
template:
  - sensor:
      - name: "Jobs Tracker Hours Since Dog Fed"
        unique_id: "jobs_tracker_hours_since_dog_fed"
        device_class: duration
        state_class: measurement
        unit_of_measurement: "h"
        icon: "mdi:dog-side"
        availability: >-
          {% set morning = state_attr('sensor.jobs_tracker_dog_feeding_morning', 'hours_since_completed') %}
          {% set evening = state_attr('sensor.jobs_tracker_dog_feeding_evening', 'hours_since_completed') %}
          {{ is_number(morning) or is_number(evening) }}
        state: >-
          {% set morning = state_attr('sensor.jobs_tracker_dog_feeding_morning', 'hours_since_completed') %}
          {% set evening = state_attr('sensor.jobs_tracker_dog_feeding_evening', 'hours_since_completed') %}
          {% if is_number(morning) and is_number(evening) %}
            {{ [morning | float(0), evening | float(0)] | min | round(0) }}
          {% elif is_number(morning) %}
            {{ morning | float(0) | round(0) }}
          {% elif is_number(evening) %}
            {{ evening | float(0) | round(0) }}
          {% else %}
            {{ none }}
          {% endif %}

      - name: "Jobs Tracker Hours Since Dog Depooped"
        unique_id: "jobs_tracker_hours_since_dog_depooped"
        device_class: duration
        state_class: measurement
        unit_of_measurement: "h"
        icon: "mdi:emoticon-poop"
        availability: >-
          {% set hours = state_attr('sensor.jobs_tracker_dog_depooping', 'hours_since_completed') %}
          {{ is_number(hours) }}
        state: >-
          {% set hours = state_attr('sensor.jobs_tracker_dog_depooping', 'hours_since_completed') %}
          {{ hours | float(0) if is_number(hours) else none }}

#:######################################################################################:#
# PERSISTENT EVENT TIMESTAMPS (survive HA restart)
#:######################################################################################:#
# These input_datetime entities store the actual wall-clock time of the most recent
# event. The home-feed-card uses last_changed for "X minutes ago".
# Since input_datetime state is restored from the database after restart,
# last_changed reflects the actual event time, not the restart time.

# input_datetime entities created via HA API (not in YAML)

#:######################################################################################:#
# AUTOMATIONS: Update timestamps on event
#:######################################################################################:#
automation:
  - id: timestamp_dog_fed
    alias: "Timestamp - Dog Fed"
    mode: single
    triggers:
      - trigger: state
        entity_id: event.jobs_dog_fed_button_x14bt_action
    conditions:
      - condition: template
        value_template: >-
          {{ trigger.to_state.state not in ['unknown', 'unavailable'] }}
    actions:
      - action: input_datetime.set_datetime
        target:
          entity_id: input_datetime.dog_last_fed
        data:
          timestamp: "{{ as_timestamp(now()) }}"
      - action: mqtt.publish
        data:
          topic: "viewroad-status/activityfeed/dogfed"
          payload: "{{ now().strftime('%H:%M') }}"
          qos: 0
          retain: true

  - id: timestamp_dog_depooped
    alias: "Timestamp - Dog Depooped"
    mode: single
    triggers:
      - trigger: state
        entity_id: event.jobs_dog_depooped_button_x15bt_action
    conditions:
      - condition: template
        value_template: >-
          {{ trigger.to_state.state not in ['unknown', 'unavailable'] }}
    actions:
      - action: input_datetime.set_datetime
        target:
          entity_id: input_datetime.dog_last_depooped
        data:
          timestamp: "{{ as_timestamp(now()) }}"

  - id: timestamp_jobs_done
    alias: "Timestamp - Any Job Completed"
    description: >-
      Updates the jobs-done timestamp whenever any tracked job completion
      event fires. This keeps the "Jobs Done" entry in the home-feed-card
      showing the time of the most recent job completion.
    mode: single
    triggers:
      - trigger: state
        entity_id:
          - event.jobs_dog_fed_button_x14bt_action
          - event.jobs_dog_depooped_button_x15bt_action
          - event.kitchen_jobs_kitchen_completed_buttons_button_1
          - event.kitchen_jobs_kitchen_completed_buttons_button_2
    conditions:
      - condition: template
        value_template: >-
          {{ trigger.to_state.state not in ['unknown', 'unavailable'] }}
    actions:
      - action: input_datetime.set_datetime
        target:
          entity_id: input_datetime.last_jobs_done
        data:
          timestamp: "{{ as_timestamp(now()) }}"
      - action: mqtt.publish
        data:
          topic: "viewroad-status/activityfeed/jobsdone"
          payload: "{{ now().strftime('%-I:%M %p') }}"
          qos: 0
          retain: true

  - id: jobs_completion_announcements
    alias: "Jobs - Completion Announcements"
    description: >-
      Announces physical dog feeding, dog depooping, dishwasher and rubbish
      completion events on the lounge Sony TV and both Pushover devices.
    mode: queued
    max: 10
    triggers:
      - trigger: state
        entity_id:
          - event.jobs_dog_fed_button_x14bt_action
          - event.jobs_dog_depooped_button_x15bt_action
          - event.kitchen_jobs_kitchen_completed_buttons_button_1
          - event.kitchen_jobs_kitchen_completed_buttons_button_2
    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_ts = as_timestamp(trigger.to_state.state, 0)
            if valid_state else 0 %}
          {% set event_age = as_timestamp(now()) - event_ts %}
          {{ valid_state and event_ts > 0 and event_age >= 0 and event_age <= 30 }}
    actions:
      - variables:
          completion_message: >-
            {% if trigger.entity_id == 'event.jobs_dog_fed_button_x14bt_action' %}
              Zorro has been fed
            {% elif trigger.entity_id == 'event.jobs_dog_depooped_button_x15bt_action' %}
              Zorro has been depooped
            {% elif trigger.entity_id == 'event.kitchen_jobs_kitchen_completed_buttons_button_1' %}
              Dishwasher has been emptied
            {% elif trigger.entity_id == 'event.kitchen_jobs_kitchen_completed_buttons_button_2' %}
              Rubbish has been removed
            {% else %}
              Job has been completed
            {% endif %}
      - action: script.view_road_announcement
        data:
          channels: "sony_tv_lounge, pushover_zorruno, pushover_kim"
          title: "Jobs Announcement"
          short_announcement: "{{ completion_message }}"
          long_announcement: "{{ completion_message }}"
