From b8012de934b466a57debcc74a4c7cdbc4215b846 Mon Sep 17 00:00:00 2001 From: Pino Date: Wed, 10 Jun 2026 21:30:25 +0200 Subject: [PATCH] BUG-003: HeatingRule auf heizungsrelevante Sensoren begrenzen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - matches(): nur climate oder sensor mit device_class in {temperature, humidity, occupancy, presence, heating} - Tests: ergänzt für relevante und nicht-relevante Sensoren - Verhindert falsche Empfehlungen bei Strom-/Tür-/Wetter-Sensoren --- app/rules/heating.py | 16 +++++++++++++++- tests/rules/test_heating.py | 21 ++++++++++++++++++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/app/rules/heating.py b/app/rules/heating.py index 994711a..bfe1a81 100644 --- a/app/rules/heating.py +++ b/app/rules/heating.py @@ -9,7 +9,21 @@ from app.rules.recommender import Rule class HeatingRule(Rule): def matches(self, entities: Sequence[HaEntitySummary]) -> bool: domains = {item.domain for item in entities} - return "climate" in domains or "sensor" in domains + if "climate" in domains: + return True + if "sensor" in domains: + # Nur Sensoren mit Heizungs-/Klimarelevanz + relevant_device_classes = { + "temperature", + "humidity", + "occupancy", + "presence", + "heating", + } + for entity in entities: + if entity.domain == "sensor" and entity.device_class in relevant_device_classes: + return True + return False def recommendation(self, entities: Sequence[HaEntitySummary]) -> str: return "Prüfe Heizungsregelung: Aktiviere energiesparenden Modus bei Abwesenheit." \ No newline at end of file diff --git a/tests/rules/test_heating.py b/tests/rules/test_heating.py index da4d753..34bf5c9 100644 --- a/tests/rules/test_heating.py +++ b/tests/rules/test_heating.py @@ -5,8 +5,8 @@ from app.rules.heating import HeatingRule from app.rules.recommender import Recommender -def _sensor(entity_id: str) -> HaEntitySummary: - return HaEntitySummary(entity_id=entity_id, domain="sensor") +def _sensor(entity_id: str, device_class: str | None = None) -> HaEntitySummary: + return HaEntitySummary(entity_id=entity_id, domain="sensor", device_class=device_class) def _climate(entity_id: str) -> HaEntitySummary: @@ -16,7 +16,22 @@ def _climate(entity_id: str) -> HaEntitySummary: def test_heating_rule_triggers() -> None: rule = HeatingRule() assert rule.matches([_climate("climate.living_room")]) - assert rule.matches([_sensor("sensor.temperature_living")]) + # Relevante Sensoren + assert rule.matches([_sensor("sensor.temperature_living", device_class="temperature")]) + assert rule.matches([_sensor("sensor.humidity_bath", device_class="humidity")]) + assert rule.matches([_sensor("sensor.occupancy_living", device_class="occupancy")]) + assert rule.matches([_sensor("sensor.presence_entry", device_class="presence")]) + assert rule.matches([_sensor("sensor.heating_status", device_class="heating")]) + + +def test_heating_rule_ignores_non_relevant_sensors() -> None: + rule = HeatingRule() + # Nicht-relevante Sensoren + assert not rule.matches([_sensor("sensor.power", device_class="power")]) + assert not rule.matches([_sensor("sensor.voltage", device_class="voltage")]) + assert not rule.matches([_sensor("sensor.door", device_class="door")]) + assert not rule.matches([_sensor("sensor.window", device_class="window")]) + assert not rule.matches([_sensor("sensor.light", device_class="illuminance")]) def test_recommender_uses_rule() -> None: -- 2.47.3