################################################################################ # PACKAGE: Appliances Status Monitoring ################################################################################ # # Version: 1.4 # Date: 2026-06-09 # # Purpose: # Appliance status monitoring package for multiple appliances. # # This package defines a central appliance registry and one automation that: # # 1. Publishes MQTT discovery config for each appliance monitor sensor. # 2. Samples appliance power sensors once per minute. # 3. Calls script.appliance_monitor_process_sample. # # Processor package required: # appliance_monitor_processor.yaml # # Announcement router required: # view_road_announcement_router.yaml # # MQTT: # MQTT is used only as retained state storage for appliance monitor sensors. # Sensor entities are created using MQTT discovery. # # Adding another appliance: # Add one entry to the am_appliances list. # # Version 1.4: # Added min_cycle_notify_seconds support. # Default is 300 seconds, so cycles shorter than 5 minutes are recorded but # do not send finished notifications. # Per-appliance overrides can be set in the am_appliances list. # # Version 1.3: # Removed the is_number gate before calling the processor. The processor is # now always called once per appliance per sample, and power is safely converted # to 0 if the source sensor is unavailable or non-numeric. # ################################################################################ automation: - id: appliances_status_monitoring_process_samples alias: Appliances Status Monitoring - Process Samples description: Publish MQTT discovery, sample appliance power sensors, and process appliance status/cycle data. mode: queued max: 20 trigger: - platform: homeassistant event: start id: ha_start - platform: time_pattern minutes: "/1" id: periodic_sample variables: ########################################################################## # MQTT LOCAL CONTROLS ########################################################################## mqtt_device_name: "appliance_monitor" mqtt_local_status_topic: !secret mqtt_status_main_topic mqtt_discovery_prefix: "homeassistant" ########################################################################## # DEFAULTS ########################################################################## am_default_debug_flow: false am_default_resolution: 2 am_default_standby_power: 2 am_default_operating_power_min: 12 am_default_min_cycle_notify_seconds: 300 #am_default_announcement_channels: "pushover_zorruno, sony_tv_lounge, lounge_google_home_voice, led_matrix_1" am_default_announcement_channels: "pushover_zorruno" # Optional appliance-specific overrides available: # resolution: 4 # The number of samples for the average, with one sample per minute. # # standby_power: 3 # Below this value, the appliance will show "Off". # Between this value and operating_power_min, it will show "Standby". # # operating_power_min: 20 # The minimum average power needed for the appliance to show "Operating". # # min_cycle_notify_seconds: 600 # Finished cycles shorter than this are recorded, but no notification # is sent. Default is 300 seconds. # # announcement_channels: "pushover_zorruno" # Announcement channels for this appliance. # # long_announcement: "The device has finished. Please empty it when convenient." # Override the long announcement. # # min_cycle_notify_seconds: 600 # Minimum time for an appliance to be operating before a completion announcement generated. ########################################################################## # APPLIANCE REGISTRY ########################################################################## am_appliances: - appliance_id: washing_machine appliance_name: "Washing Machine" appliance_action: "washing2" power_entity: "sensor.esp_laundrywashpow_load_power" icon: "mdi:washing-machine" short_announcement: "/s/sWashing complete" # long_announcement: # Created by the processor matrix_indicator: "wash,1,15,10,6,5,1,0" # Optional washing-machine-specific overrides resolution: 5 standby_power: 3 operating_power_min: 10 announcement_channels: "pushover_zorruno" - appliance_id: dryer appliance_name: "Dryer" appliance_action: "drying2" power_entity: "sensor.esp_laundrydrypow_load_power" icon: "mdi:tumble-dryer" short_announcement: "/s/sDryer complete" # long_announcement: # Created by the processor matrix_indicator: "dry,1,15,10,6,5,1,0" # Optional dryer-specific overrides resolution: 4 standby_power: 3 operating_power_min: 10 announcement_channels: "pushover_zorruno" - appliance_id: main_dishwasher appliance_name: "Main Dishwasher" appliance_action: "dishwashing2" power_entity: "sensor.esp_maindishwasherpower_power" icon: "mdi:dishwasher" short_announcement: "/sDishwasher complete" # long_announcement: # Created by the processor matrix_indicator: "dish,1,15,10,6,5,1,0" - appliance_id: evcharger_32a appliance_name: "EV Charger (32A)" appliance_action: "EV charging (32A)" power_entity: "sensor.main_house_3_phase_power_monitor_32a_wallcharger_power" monitor_sensor: "sensor.appliance_monitor_ev_charger_32a_monitor" icon: "mdi:ev-plug-type2" short_announcement: "/s/s32A EV Charging complete" # long_announcement: # Created by the processor matrix_indicator: "ev32a,1,15,10,6,5,1,0" resolution: 6 standby_power: 3 operating_power_min: 50 announcement_channels: "pushover_zorruno" action: ########################################################################## # PUBLISH / REFRESH MQTT DISCOVERY CONFIG ########################################################################## - repeat: for_each: "{{ am_appliances }}" sequence: - variables: am_state_topic: >- {{ mqtt_local_status_topic }}/{{ mqtt_device_name }}/{{ repeat.item.appliance_id }}/state am_discovery_topic: >- {{ mqtt_discovery_prefix }}/sensor/{{ mqtt_device_name }}_{{ repeat.item.appliance_id }}/config am_unique_id: >- {{ repeat.item.appliance_id }}_monitor am_object_id: >- {{ mqtt_device_name }}_{{ repeat.item.appliance_id }}_monitor - action: mqtt.publish data: topic: "{{ am_discovery_topic }}" retain: true qos: 0 payload: >- {{ dict( name=repeat.item.appliance_name ~ ' Monitor', unique_id=am_unique_id, object_id=am_object_id, icon=repeat.item.icon | default('mdi:power-plug'), state_topic=am_state_topic, value_template='{{ value_json.state | default("Off") }}', json_attributes_topic=am_state_topic, device=dict( identifiers=[mqtt_device_name], name='Appliance Monitor', manufacturer='View Road Home Assistant', model='Shared appliance power monitor' ) ) | to_json }} ########################################################################## # PROCESS SAMPLES ########################################################################## # # Always process every appliance. The processor receives power_w as a safe # float value, so unavailable/non-numeric sensors become 0 W. # ########################################################################## - repeat: for_each: "{{ am_appliances }}" sequence: - variables: am_state_topic: >- {{ mqtt_local_status_topic }}/{{ mqtt_device_name }}/{{ repeat.item.appliance_id }}/state am_monitor_sensor: >- {{ repeat.item.monitor_sensor | default('sensor.' ~ mqtt_device_name ~ '_' ~ repeat.item.appliance_id ~ '_monitor', true) }} am_title: >- {{ repeat.item.title | default(repeat.item.appliance_name ~ ' Notification', true) }} am_announcement_channels: >- {{ repeat.item.announcement_channels | default(am_default_announcement_channels, true) }} am_debug_flow: >- {{ repeat.item.debug_flow | default(am_default_debug_flow, true) }} am_resolution: >- {{ repeat.item.resolution | default(am_default_resolution, true) }} am_standby_power: >- {{ repeat.item.standby_power | default(am_default_standby_power, true) }} am_operating_power_min: >- {{ repeat.item.operating_power_min | default(am_default_operating_power_min, true) }} am_min_cycle_notify_seconds: >- {{ repeat.item.min_cycle_notify_seconds | default(am_default_min_cycle_notify_seconds, true) }} am_power_w: >- {{ states(repeat.item.power_entity) | float(0) }} am_long_announcement: >- {{ repeat.item.long_announcement | default('', true) }} - action: script.appliance_monitor_process_sample data: appliance_id: "{{ repeat.item.appliance_id }}" appliance_name: "{{ repeat.item.appliance_name }}" appliance_action: "{{ repeat.item.appliance_action }}" power_w: "{{ am_power_w }}" monitor_sensor: "{{ am_monitor_sensor }}" state_topic: "{{ am_state_topic }}" debug_flow: "{{ am_debug_flow }}" resolution: "{{ am_resolution }}" standby_power: "{{ am_standby_power }}" operating_power_min: "{{ am_operating_power_min }}" min_cycle_notify_seconds: "{{ am_min_cycle_notify_seconds }}" announcement_channels: "{{ am_announcement_channels }}" short_announcement: "{{ repeat.item.short_announcement }}" long_announcement: "{{ am_long_announcement }}" title: "{{ am_title }}" matrix_indicator: "{{ repeat.item.matrix_indicator }}"