Skip to content

Commit 27944b3

Browse files
committed
Use actual modulation for burner flame state
1 parent 09d4c0a commit 27944b3

2 files changed

Lines changed: 43 additions & 0 deletions

File tree

custom_components/bosch/pointtapi_entities.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2660,6 +2660,20 @@ def _resolve_on_off(raw: Any) -> bool | None:
26602660
return None
26612661

26622662

2663+
def _burner_flame_state(data: dict[str, Any]) -> bool | None:
2664+
"""Resolve burner flame state from current burner modulation.
2665+
2666+
POINTTAPI flameIndication can return multiple string dialects (off/ch/dhw),
2667+
which is not stable enough for a strict on/off parser. actualModulation is
2668+
a numeric signal and better reflects whether the burner is actively firing.
2669+
"""
2670+
raw = _val(data, "/heatSources/actualModulation")
2671+
try:
2672+
return float(raw) > 0.0
2673+
except (TypeError, ValueError):
2674+
return None
2675+
2676+
26632677
# ── Boost session: in-memory tracking of HA-triggered boost (v0.33.0) ──────
26642678

26652679

@@ -2780,6 +2794,7 @@ def available(self) -> bool:
27802794
key="/heatSources/flameIndication",
27812795
translation_key="burner_flame",
27822796
device_class=BinarySensorDeviceClass.RUNNING,
2797+
value_fn=_burner_flame_state,
27832798
),
27842799
BoschPoinTTAPIBinarySensorEntityDescription(
27852800
key="/heatSources/refillNeeded",

unittests/test_pointtapi_new_entities.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -812,6 +812,34 @@ def test_dhw_binary_sensor_off_maps_to_false(self):
812812
ent._handle_coordinator_update()
813813
assert ent.is_on is False
814814

815+
def test_burner_flame_uses_actual_modulation_positive_as_on(self):
816+
coord = _mock_coordinator(
817+
{
818+
"/heatSources/flameIndication": {"value": "dhw"},
819+
"/heatSources/actualModulation": {"value": 12.0},
820+
}
821+
)
822+
ent = _binary_sensor(coord, "/heatSources/flameIndication")
823+
ent._handle_coordinator_update()
824+
assert ent.is_on is True
825+
826+
def test_burner_flame_uses_actual_modulation_zero_as_off(self):
827+
coord = _mock_coordinator(
828+
{
829+
"/heatSources/flameIndication": {"value": "ch"},
830+
"/heatSources/actualModulation": {"value": 0.0},
831+
}
832+
)
833+
ent = _binary_sensor(coord, "/heatSources/flameIndication")
834+
ent._handle_coordinator_update()
835+
assert ent.is_on is False
836+
837+
def test_burner_flame_unknown_when_actual_modulation_missing(self):
838+
coord = _mock_coordinator({"/heatSources/flameIndication": {"value": "dhw"}})
839+
ent = _binary_sensor(coord, "/heatSources/flameIndication")
840+
ent._handle_coordinator_update()
841+
assert ent.is_on is None
842+
815843
def test_switch_unavailable_when_path_absent(self):
816844
coord = _mock_coordinator({})
817845
ent = _switch(coord, "/dhwCircuits/dhw1/extraDhw")

0 commit comments

Comments
 (0)