Skip to content

Commit 1ede9f8

Browse files
authored
Merge pull request #37 from 3dg1luk43/copilot/sub-pr-36
Fix code quality issues from PR #36 review
2 parents 042f91d + fee55ff commit 1ede9f8

5 files changed

Lines changed: 18 additions & 18 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
A Home Assistant custom component to monitor washing machines via smart sockets, learn power profiles, and estimate completion time using shape-correlation matching.
1010

1111
> [!CAUTION]
12-
> **ELECTRICAL SAFETY WARNING**: Using smart plugs such as Shelly or Sonoff with high-amperage appliances (washing machines, dryers, dishwriters) carries significant risk.
12+
> **ELECTRICAL SAFETY WARNING**: Using smart plugs such as Shelly or Sonoff with high-amperage appliances (washing machines, dryers, dishwashers) carries significant risk.
1313
>
1414
> * **Fire Hazard**: Cheap or low-rated smart plugs may overheat, melt, or catch fire under sustained high loads (heating/drying phases).
1515
> * **Rating Check**: Ensure your smart plug is rated for the **maximum peak power** of your appliance (often >2500W). Standard 10A plugs may fail; 16A+ or hardwired modules are recommended.

custom_components/ha_washdata/cycle_detector.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ def reset(self) -> None:
7373
self._ma_buffer = []
7474
self._cycle_status = None
7575
self._last_power = None
76+
self._abrupt_drop = False
7677
self._potential_start_time = None
7778
self._end_condition_count = 0
7879
self._extension_count = 0

custom_components/ha_washdata/manager.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,13 @@ async def _attempt_state_restoration(self) -> None:
301301
current_power = float(state.state)
302302
power_is_valid = True
303303
except (ValueError, TypeError):
304-
pass
304+
# Power sensor state is not numeric during restoration; treat as 0W
305+
_LOGGER.debug(
306+
"Power sensor %s state %r is not numeric during restoration; "
307+
"treating as 0W and not restoring by power",
308+
self.power_sensor_entity_id,
309+
getattr(state, "state", None),
310+
)
305311

306312
should_restore = False
307313
active_snapshot_to_restore = active_snapshot
@@ -374,9 +380,15 @@ def is_viable_restore(last_save_time: datetime) -> bool:
374380
# Restore manual program flag if present
375381
self._manual_program_active = active_snapshot_to_restore.get("manual_program", False)
376382

377-
# If we restored into a low-power state, ensure we don't immediately quit
383+
# If we restored into a low-power state, ensure we don't immediately quit.
384+
# For now we just log this; the cycle detector's off_delay will handle actual shutdown.
378385
if power_is_valid and current_power < self._config.min_power:
379-
pass
386+
_LOGGER.debug(
387+
"Restored active cycle in low-power state (power=%.2fW < min_power=%.2fW); "
388+
"waiting for detector off_delay before marking as finished",
389+
current_power,
390+
self._config.min_power,
391+
)
380392

381393
if self.detector.matched_profile:
382394
self._current_program = self.detector.matched_profile
@@ -819,16 +831,6 @@ def _run_final_profile_match(self) -> None:
819831
f"No confident match in final attempt (best: {profile_name}, conf={confidence:.3f})"
820832
)
821833

822-
def _check_state_save(self, now: datetime) -> None:
823-
"""Periodically save active state."""
824-
last_save = getattr(self, "_last_state_save", None)
825-
if not last_save or (now - last_save).total_seconds() > 60:
826-
# Fire and forget save task
827-
self.hass.async_create_task(
828-
self.profile_store.async_save_active_cycle(self.detector.get_state_snapshot())
829-
)
830-
self._last_state_save = now
831-
832834
def _start_watchdog(self) -> None:
833835
"""Start the watchdog timer when a cycle begins."""
834836
if self._remove_watchdog:

custom_components/ha_washdata/profile_store.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -611,8 +611,6 @@ def rebuild_envelope(self, profile_name: str) -> bool:
611611
"cycle_count": len(resampled),
612612
"target_duration": float(target_duration),
613613
"sampling_rates": list(sampling_rates),
614-
"target_duration": float(target_duration),
615-
"sampling_rates": list(sampling_rates),
616614
"updated_at": datetime.now().isoformat(),
617615
}
618616

@@ -654,8 +652,6 @@ def rebuild_envelope(self, profile_name: str) -> bool:
654652

655653
return True
656654

657-
return True
658-
659655
def generate_profile_svg(self, profile_name: str) -> str | None:
660656
"""Generate an SVG string for the profile's power envelope."""
661657
envelope = self.get_envelope(profile_name)

run_tests.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#!/bin/bash
2+
# If you encounter "Permission denied", run: chmod +x run_tests.sh
23
set -e
34

45
# Define path to venv python

0 commit comments

Comments
 (0)