|
| 1 | +--- |
| 2 | +tags: |
| 3 | + - package |
| 4 | + - automated |
| 5 | +version: 1.0.0 |
| 6 | +--- |
| 7 | + |
| 8 | +# Package: Washing Machine |
| 9 | + |
| 10 | +**Version:** 1.0.0 |
| 11 | +**Description:** Logic for Washing Machine state tracking, run time calculation, and smart notifications based on power usage. |
| 12 | + |
| 13 | +<!-- START_IMAGE --> |
| 14 | + |
| 15 | +<!-- END_IMAGE --> |
| 16 | + |
| 17 | +## Executive Summary |
| 18 | +<!-- START_SUMMARY --> |
| 19 | +The Washing Machine package provides intelligent state tracking for any washing machine connected to a smart plug with power monitoring. It uses power consumption data to automatically detect when a cycle starts and finishes. The system tracks the exact run time of each load and sends actionable notifications to users, ensuring laundry is never left forgotten in the machine. It abstracts complex power fluctuations into simple statuses like "Idle", "Running", and "Clean". |
| 20 | +<!-- END_SUMMARY --> |
| 21 | + |
| 22 | +## Process Description (Non-Technical) |
| 23 | +<!-- START_DETAILED --> |
| 24 | +### How It Works |
| 25 | +1. **Auto-Detection**: The system monitors the electricity usage of the washing machine smart plug. |
| 26 | +2. **Cycle Start**: When power usage exceeds **10W** for more than 1 minute, the system marks the machine as "Running" and records the start time. |
| 27 | +3. **Notifications**: |
| 28 | + * **Started**: A notification confirms the cycle has begun. |
| 29 | + * **Finished**: When power drops below **3W** for 2 minutes, the system marks the laundry as "Clean" and sends a notification including the total cycle duration (e.g., "1 hr 45 min"). |
| 30 | +4. **Continuous Status**: The system maintains a live "Run Time" sensor, so you can always see how long the current load has been washing. |
| 31 | +<!-- END_DETAILED --> |
| 32 | + |
| 33 | +## Integration Dependencies |
| 34 | +<!-- START_DEPENDENCIES --> |
| 35 | +* **Smart Plug**: Requires a smart plug with power metering (Entity: `sensor.washing_machine_plug_power`). |
| 36 | +* **Helpers**: Uses `input_select` for status and `input_datetime` for start time tracking. |
| 37 | +<!-- END_DEPENDENCIES --> |
| 38 | + |
| 39 | +## Dashboard Connections |
| 40 | +<!-- START_DASHBOARD --> |
| 41 | +This package powers the following dashboard views: |
| 42 | +* **[Bathroom](../dashboards/main/bathroom.md)** |
| 43 | +* **[Home](../dashboards/main/home.md)** |
| 44 | +<!-- END_DASHBOARD --> |
| 45 | + |
| 46 | +## Architecture Diagram |
| 47 | +<!-- START_MERMAID_DESC --> |
| 48 | +The architecture relies on a state machine driven by numeric state triggers from the power sensor. High power draw triggers the `Running` state and initializes the start timer. Low power draw triggers the `Clean` state and calculates the final duration. A generic reset mechanism or a subsequent high power event transitions the system back to `Idle` or directly to `Running` for the next load. |
| 49 | +<!-- END_MERMAID_DESC --> |
| 50 | + |
| 51 | +<!-- START_MERMAID --> |
| 52 | +```mermaid |
| 53 | +sequenceDiagram |
| 54 | + participant Machine as Smart Plug (Washing Machine) |
| 55 | + participant HA as Home Assistant |
| 56 | + participant User as User (Mobile) |
| 57 | +
|
| 58 | + Machine->>HA: Power > 10W (for 1 min) |
| 59 | + HA->>HA: Set Status 'Running' |
| 60 | + HA->>HA: Record Start Time |
| 61 | + HA->>User: Notify "Washing Machine Started" |
| 62 | +
|
| 63 | + loop Monitoring |
| 64 | + HA->>HA: Update Run Time Sensor |
| 65 | + end |
| 66 | +
|
| 67 | + Machine->>HA: Power < 3W (for 2 min) |
| 68 | + HA->>HA: Set Status 'Clean' |
| 69 | + HA->>HA: Calculate Total Duration |
| 70 | + HA->>User: Notify "Laundry is Ready" (Duration) |
| 71 | +
|
| 72 | + opt Reset |
| 73 | + HA->>HA: Auto-change to 'Idle' (if logic enabled) |
| 74 | + Note over HA: Ready for next load |
| 75 | + end |
| 76 | +``` |
| 77 | +<!-- END_MERMAID --> |
| 78 | + |
| 79 | +## Configuration (Source Code) |
| 80 | +```yaml |
| 81 | +# ------------------------------------------------------------------------------ |
| 82 | +# Package: Washing Machine |
| 83 | +# Version: 1.0.0 |
| 84 | +# Description: Logic for Washing Machine state tracking, run time calculation, and notifications. |
| 85 | +# Dependencies: |
| 86 | +# - Sensor: sensor.washing_machine_plug_power |
| 87 | +# - Script: script.notify_smart_master |
| 88 | +# ------------------------------------------------------------------------------ |
| 89 | + |
| 90 | +# ------------------------------------------------------------------------------ |
| 91 | +# 1. HELPERS |
| 92 | +# ------------------------------------------------------------------------------ |
| 93 | +input_select: |
| 94 | + washing_machine_status: |
| 95 | + name: "Washing Machine Status" |
| 96 | + icon: mdi:washing-machine |
| 97 | + options: |
| 98 | + - Idle |
| 99 | + - Running |
| 100 | + - Clean |
| 101 | + initial: Idle |
| 102 | + |
| 103 | +input_datetime: |
| 104 | + washing_machine_start_time: |
| 105 | + name: "Washing Machine Start Time" |
| 106 | + has_date: true |
| 107 | + has_time: true |
| 108 | + |
| 109 | +# ------------------------------------------------------------------------------ |
| 110 | +# 2. SENSORS |
| 111 | +# ------------------------------------------------------------------------------ |
| 112 | +template: |
| 113 | + - sensor: |
| 114 | + - name: "Washing Machine Run Time" |
| 115 | + unique_id: washing_machine_run_time |
| 116 | + icon: mdi:timer-outline |
| 117 | + state: > |
| 118 | + {% if is_state('input_select.washing_machine_status', 'Running') %} |
| 119 | + {% set start = states('input_datetime.washing_machine_start_time') | as_datetime %} |
| 120 | + {% if start %} |
| 121 | + {{ (now() - start).total_seconds() | timestamp_custom('%-H:%M', false) }} |
| 122 | + {% else %} |
| 123 | + 0:00 |
| 124 | + {% endif %} |
| 125 | + {% else %} |
| 126 | + 0:00 |
| 127 | + {% endif %} |
| 128 | +
|
| 129 | +# ------------------------------------------------------------------------------ |
| 130 | +# 3. AUTOMATIONS |
| 131 | +# ------------------------------------------------------------------------------ |
| 132 | +automation: |
| 133 | + # --- START DETECTED --- |
| 134 | + - alias: "Notify: Washing Machine Started" |
| 135 | + id: notify_washing_machine_started |
| 136 | + trigger: |
| 137 | + - platform: numeric_state |
| 138 | + entity_id: sensor.washing_machine_plug_power |
| 139 | + above: 10 |
| 140 | + for: "00:01:00" |
| 141 | + condition: |
| 142 | + - condition: state |
| 143 | + entity_id: input_select.washing_machine_status |
| 144 | + state: |
| 145 | + - "Idle" |
| 146 | + - "Clean" |
| 147 | + action: |
| 148 | + - service: input_select.select_option |
| 149 | + target: |
| 150 | + entity_id: input_select.washing_machine_status |
| 151 | + data: |
| 152 | + option: "Running" |
| 153 | + - service: input_datetime.set_datetime |
| 154 | + target: |
| 155 | + entity_id: input_datetime.washing_machine_start_time |
| 156 | + data: |
| 157 | + timestamp: "{{ now().timestamp() }}" |
| 158 | + - service: script.notify_smart_master |
| 159 | + data: |
| 160 | + category: info |
| 161 | + title: 🧺 Washing Machine Started |
| 162 | + message: "The cycle has started." |
| 163 | + tag: washing_machine |
| 164 | + clickAction: /lovelace/utility |
| 165 | + mode: single |
| 166 | + |
| 167 | + # --- FINISH DETECTED --- |
| 168 | + - alias: "Notify: Washing Machine Finished" |
| 169 | + id: notify_washing_machine_finished |
| 170 | + trigger: |
| 171 | + - platform: numeric_state |
| 172 | + entity_id: sensor.washing_machine_plug_power |
| 173 | + below: 3 |
| 174 | + for: "00:02:00" |
| 175 | + condition: |
| 176 | + - condition: state |
| 177 | + entity_id: input_select.washing_machine_status |
| 178 | + state: "Running" |
| 179 | + action: |
| 180 | + - service: input_select.select_option |
| 181 | + target: |
| 182 | + entity_id: input_select.washing_machine_status |
| 183 | + data: |
| 184 | + option: "Clean" |
| 185 | + |
| 186 | + # Calculate Final Duration |
| 187 | + - variables: |
| 188 | + start_time: "{{ states('input_datetime.washing_machine_start_time') | as_datetime }}" |
| 189 | + duration_str: >- |
| 190 | + {% if start_time %} |
| 191 | + {{ (now() - start_time).total_seconds() | timestamp_custom('%-H hr %-M min', false) }} |
| 192 | + {% else %} |
| 193 | + unknown time |
| 194 | + {% endif %} |
| 195 | +
|
| 196 | + - service: script.notify_smart_master |
| 197 | + data: |
| 198 | + category: info |
| 199 | + title: ✨ Laundry is Ready |
| 200 | + message: "Cycle finished. Duration: {{ duration_str }}." |
| 201 | + tag: washing_machine |
| 202 | + clickAction: /lovelace/utility |
| 203 | + mode: single |
| 204 | + |
| 205 | + # --- RESET TO IDLE --- |
| 206 | + - alias: "System: Washing Machine Reset" |
| 207 | + id: system_washing_machine_reset |
| 208 | + trigger: |
| 209 | + # If we want to automatically mark it as 'Idle' after some time |
| 210 | + - platform: state |
| 211 | + entity_id: input_select.washing_machine_status |
| 212 | + to: "Clean" |
| 213 | + for: "01:00:00" # Auto-reset after 1 hour if not unloaded |
| 214 | + action: |
| 215 | + - service: input_select.select_option |
| 216 | + target: |
| 217 | + entity_id: input_select.washing_machine_status |
| 218 | + data: |
| 219 | + option: "Idle" |
| 220 | + mode: single |
| 221 | +``` |
0 commit comments