mirror of
https://github.com/home-assistant/core.git
synced 2026-09-26 09:23:17 -04:00
Guard KNX climate fan_mode against out-of-range step values (#182007)
This commit is contained in:
@@ -554,7 +554,7 @@ class _KnxClimate(ClimateEntity, _KnxEntityBase):
|
||||
|
||||
@property
|
||||
@override
|
||||
def fan_mode(self) -> str:
|
||||
def fan_mode(self) -> str | None:
|
||||
"""Return the fan setting."""
|
||||
|
||||
fan_speed = self._device.current_fan_speed
|
||||
@@ -563,6 +563,10 @@ class _KnxClimate(ClimateEntity, _KnxEntityBase):
|
||||
return self.fan_zero_mode
|
||||
|
||||
if self._device.fan_speed_mode is FanSpeedMode.STEP:
|
||||
# DPT 5.010 fits any 1-byte value (0-255), so a gateway may report
|
||||
# a step beyond the configured fan_max_step
|
||||
if fan_speed >= len(self._attr_fan_modes):
|
||||
return None
|
||||
return self._attr_fan_modes[fan_speed]
|
||||
|
||||
# Find the closest fan mode percentage
|
||||
|
||||
@@ -502,6 +502,45 @@ async def test_fan_speed_3_steps(hass: HomeAssistant, knx: KNXTestKit) -> None:
|
||||
knx.assert_state("climate.test", HVACMode.HEAT, fan_mode="off")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("raw_value", [0x04, 0xFF])
|
||||
async def test_fan_speed_step_out_of_range(
|
||||
hass: HomeAssistant, knx: KNXTestKit, raw_value: int
|
||||
) -> None:
|
||||
"""Test that fan step values beyond fan_max_step don't crash the entity."""
|
||||
await knx.setup_integration(
|
||||
{
|
||||
ClimateSchema.PLATFORM: {
|
||||
CONF_NAME: "test",
|
||||
ClimateSchema.CONF_TEMPERATURE_ADDRESS: "1/2/3",
|
||||
ClimateSchema.CONF_TARGET_TEMPERATURE_ADDRESS: "1/2/4",
|
||||
ClimateSchema.CONF_TARGET_TEMPERATURE_STATE_ADDRESS: "1/2/5",
|
||||
ClimateSchema.CONF_FAN_SPEED_ADDRESS: "1/2/6",
|
||||
ClimateSchema.CONF_FAN_SPEED_STATE_ADDRESS: "1/2/7",
|
||||
ClimateConf.FAN_SPEED_MODE: "step",
|
||||
ClimateConf.FAN_MAX_STEP: 3,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
# read states state updater
|
||||
await knx.assert_read("1/2/3")
|
||||
await knx.assert_read("1/2/5")
|
||||
|
||||
# StateUpdater initialize state
|
||||
await knx.receive_response("1/2/5", RAW_FLOAT_22_0)
|
||||
await knx.receive_response("1/2/3", RAW_FLOAT_21_0)
|
||||
|
||||
# Query status
|
||||
await knx.assert_read("1/2/7")
|
||||
|
||||
# a gateway may report a step value beyond the configured fan_max_step
|
||||
await knx.receive_write("1/2/7", (raw_value,))
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# the invalid telegram is published without breaking the state write
|
||||
knx.assert_state("climate.test", HVACMode.HEAT, fan_mode=None)
|
||||
|
||||
|
||||
async def test_fan_speed_2_steps(hass: HomeAssistant, knx: KNXTestKit) -> None:
|
||||
"""Test KNX climate fan speed 2 steps."""
|
||||
await knx.setup_integration(
|
||||
|
||||
Reference in New Issue
Block a user