Present the heater as a climate entity #121
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/heater-climate"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The heater endpoint now gets a climate entity (off/heat, target temperature, heating/idle action) driven by
CMD_HEATER, instead of a switch. The run state and coolant temperature sensors stay.Behaviour change: the heater switch from #119 is gone; the climate entity takes its
unique_id(60-00) and the switch platform gives the endpoint up. No automations to protect, as the switch landed today.STATE_HEATER's measured field is the coolant and is not used.Ticket: CCS-HA-56
Three things to fix, two smaller ones below. I did not run the suite or ruff: the worktree has no python on PATH.
@ -0,0 +26,4 @@from .protocol.enums import HeaterRunStatefrom .protocol.presentation import PresentationKind, SemanticClass, kind_ofUNKNOWN_SETPOINT = 0x7FFFUNKNOWN_SETPOINTduplicatesSIGNED_SENTINELS[Sentinel.UNKNOWN]in protocol/units.py. Reuse that. The test file also redefines it asUNKNOWN_TEMPERATUREand again as the0x7FFFdefault inheater_reports.@ -0,0 +47,4 @@class CampervanHeater(CampervanCommandEntity, ClimateEntity):_attr_temperature_unit = UnitOfTemperature.CELSIUS_attr_supported_features = (ClimateEntityFeature.TARGET_TEMPERATURE_cabinand the module docstring say room or cabin temperature. Per the spec's heater table the lowest-index temperature on NODE_HEATER is index 1, the heat exchanger hot sensor. It is not a room reading. The owner's rule is fine, but the naming and the docstring claim something false. Rename (e.g._temperature_endpoint) and fix the docstring. CLAUDE.md's wording is accurate ("lowest-index temperature readout").@ -0,0 +85,4 @@def max_temp(self) -> float:return self._limit(self.endpoint.maximum, DEFAULT_MAX_TEMP)@propertyis_onis true for any non-zero mode, so mode 2 (fixed power) or 3 (ventilate) shows as HEAT with HEATING or IDLE. Spec 8.3: the node honours modes 0 and 1 only. Unlikely on the bus today, but the entity claims heat when the mode is not heat. Either accept this on purpose or map mode 1 only.@ -0,0 +140,4 @@self.endpoint.index,heat,UNKNOWN_SETPOINT if setpoint is None else setpoint,),Only 0x7FFF is treated as no setpoint. 0x7FFE (fault), 0x7FFD (over range) and 0x8000 (under range) would show as 3276.6, 3276.5 or -3276.8 degrees. Spec section 6.1 says sentinels are real values. Use the existing sentinel handling (
units.TEMPERATURE/measurement_of) instead of a hand-rolled check.@ -0,0 +141,4 @@heat,UNKNOWN_SETPOINT if setpoint is None else setpoint,),on=heat,set_temperaturewhile off or unknown sendsmode=0(spec: off sends shutdown) to an already-off heater. Unknown state counts as off. A setpoint change should not carry a shutdown. Confirm with the spec owner what the node does with mode 0 plus a setpoint, and say so in a test.Fixed 1-3 in the latest commit: all reserved setpoint patterns read as unknown, the constant comes from
units.SIGNED_SENTINELS, and_cabinis now_temperature_readoutwith a docstring that says what it is.4: left.
is_ontreating any non-zero mode as on is the existing, tested rule, and the spec says NODE_HEATER reports 0 or 1 only.5: left. Set-temperature sends the current mode as designed. Off plus a setpoint to an already-off heater is the same request the node sees from any other remote.
e28e70405cc4f0ecd320