Update xknx to 3.1.0 and fix climate read only mode (#123776)
This commit is contained in:
parent
71e23e7849
commit
b3d1d79a49
5 changed files with 109 additions and 10 deletions
|
@ -5,7 +5,11 @@ from __future__ import annotations
|
|||
from typing import Any
|
||||
|
||||
from xknx import XKNX
|
||||
from xknx.devices import Climate as XknxClimate, ClimateMode as XknxClimateMode
|
||||
from xknx.devices import (
|
||||
Climate as XknxClimate,
|
||||
ClimateMode as XknxClimateMode,
|
||||
Device as XknxDevice,
|
||||
)
|
||||
from xknx.dpt.dpt_20 import HVACControllerMode
|
||||
|
||||
from homeassistant import config_entries
|
||||
|
@ -241,12 +245,9 @@ class KNXClimate(KnxYamlEntity, ClimateEntity):
|
|||
if self._device.supports_on_off and not self._device.is_on:
|
||||
return HVACMode.OFF
|
||||
if self._device.mode is not None and self._device.mode.supports_controller_mode:
|
||||
hvac_mode = CONTROLLER_MODES.get(
|
||||
return CONTROLLER_MODES.get(
|
||||
self._device.mode.controller_mode, self.default_hvac_mode
|
||||
)
|
||||
if hvac_mode is not HVACMode.OFF:
|
||||
self._last_hvac_mode = hvac_mode
|
||||
return hvac_mode
|
||||
return self.default_hvac_mode
|
||||
|
||||
@property
|
||||
|
@ -261,11 +262,15 @@ class KNXClimate(KnxYamlEntity, ClimateEntity):
|
|||
|
||||
if self._device.supports_on_off:
|
||||
if not ha_controller_modes:
|
||||
ha_controller_modes.append(self.default_hvac_mode)
|
||||
ha_controller_modes.append(self._last_hvac_mode)
|
||||
ha_controller_modes.append(HVACMode.OFF)
|
||||
|
||||
hvac_modes = list(set(filter(None, ha_controller_modes)))
|
||||
return hvac_modes if hvac_modes else [self.default_hvac_mode]
|
||||
return (
|
||||
hvac_modes
|
||||
if hvac_modes
|
||||
else [self.hvac_mode] # mode read-only -> fall back to only current mode
|
||||
)
|
||||
|
||||
@property
|
||||
def hvac_action(self) -> HVACAction | None:
|
||||
|
@ -354,3 +359,13 @@ class KNXClimate(KnxYamlEntity, ClimateEntity):
|
|||
self._device.mode.unregister_device_updated_cb(self.after_update_callback)
|
||||
self._device.mode.xknx.devices.async_remove(self._device.mode)
|
||||
await super().async_will_remove_from_hass()
|
||||
|
||||
def after_update_callback(self, _device: XknxDevice) -> None:
|
||||
"""Call after device was updated."""
|
||||
if self._device.mode is not None and self._device.mode.supports_controller_mode:
|
||||
hvac_mode = CONTROLLER_MODES.get(
|
||||
self._device.mode.controller_mode, self.default_hvac_mode
|
||||
)
|
||||
if hvac_mode is not HVACMode.OFF:
|
||||
self._last_hvac_mode = hvac_mode
|
||||
super().after_update_callback(_device)
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
"loggers": ["xknx", "xknxproject"],
|
||||
"quality_scale": "platinum",
|
||||
"requirements": [
|
||||
"xknx==3.0.0",
|
||||
"xknx==3.1.0",
|
||||
"xknxproject==3.7.1",
|
||||
"knx-frontend==2024.8.9.225351"
|
||||
],
|
||||
|
|
|
@ -2930,7 +2930,7 @@ xbox-webapi==2.0.11
|
|||
xiaomi-ble==0.30.2
|
||||
|
||||
# homeassistant.components.knx
|
||||
xknx==3.0.0
|
||||
xknx==3.1.0
|
||||
|
||||
# homeassistant.components.knx
|
||||
xknxproject==3.7.1
|
||||
|
|
|
@ -2316,7 +2316,7 @@ xbox-webapi==2.0.11
|
|||
xiaomi-ble==0.30.2
|
||||
|
||||
# homeassistant.components.knx
|
||||
xknx==3.0.0
|
||||
xknx==3.1.0
|
||||
|
||||
# homeassistant.components.knx
|
||||
xknxproject==3.7.1
|
||||
|
|
|
@ -231,6 +231,90 @@ async def test_climate_hvac_mode(
|
|||
assert hass.states.get("climate.test").state == "cool"
|
||||
|
||||
|
||||
async def test_climate_heat_cool_read_only(
|
||||
hass: HomeAssistant, knx: KNXTestKit
|
||||
) -> None:
|
||||
"""Test KNX climate hvac mode."""
|
||||
heat_cool_state_ga = "3/3/3"
|
||||
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_HEAT_COOL_STATE_ADDRESS: heat_cool_state_ga,
|
||||
}
|
||||
}
|
||||
)
|
||||
# read states state updater
|
||||
# StateUpdater semaphore allows 2 concurrent requests
|
||||
await knx.assert_read("1/2/3")
|
||||
await knx.assert_read("1/2/5")
|
||||
# StateUpdater initialize state
|
||||
await knx.receive_response("1/2/3", RAW_FLOAT_20_0)
|
||||
await knx.receive_response("1/2/5", RAW_FLOAT_20_0)
|
||||
await knx.assert_read(heat_cool_state_ga)
|
||||
await knx.receive_response(heat_cool_state_ga, True) # heat
|
||||
|
||||
state = hass.states.get("climate.test")
|
||||
assert state.state == "heat"
|
||||
assert state.attributes["hvac_modes"] == ["heat"]
|
||||
assert state.attributes["hvac_action"] == "heating"
|
||||
|
||||
await knx.receive_write(heat_cool_state_ga, False) # cool
|
||||
state = hass.states.get("climate.test")
|
||||
assert state.state == "cool"
|
||||
assert state.attributes["hvac_modes"] == ["cool"]
|
||||
assert state.attributes["hvac_action"] == "cooling"
|
||||
|
||||
|
||||
async def test_climate_heat_cool_read_only_on_off(
|
||||
hass: HomeAssistant, knx: KNXTestKit
|
||||
) -> None:
|
||||
"""Test KNX climate hvac mode."""
|
||||
on_off_ga = "2/2/2"
|
||||
heat_cool_state_ga = "3/3/3"
|
||||
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_ON_OFF_ADDRESS: on_off_ga,
|
||||
ClimateSchema.CONF_HEAT_COOL_STATE_ADDRESS: heat_cool_state_ga,
|
||||
}
|
||||
}
|
||||
)
|
||||
# read states state updater
|
||||
# StateUpdater semaphore allows 2 concurrent requests
|
||||
await knx.assert_read("1/2/3")
|
||||
await knx.assert_read("1/2/5")
|
||||
# StateUpdater initialize state
|
||||
await knx.receive_response("1/2/3", RAW_FLOAT_20_0)
|
||||
await knx.receive_response("1/2/5", RAW_FLOAT_20_0)
|
||||
await knx.assert_read(heat_cool_state_ga)
|
||||
await knx.receive_response(heat_cool_state_ga, True) # heat
|
||||
|
||||
state = hass.states.get("climate.test")
|
||||
assert state.state == "off"
|
||||
assert set(state.attributes["hvac_modes"]) == {"off", "heat"}
|
||||
assert state.attributes["hvac_action"] == "off"
|
||||
|
||||
await knx.receive_write(heat_cool_state_ga, False) # cool
|
||||
state = hass.states.get("climate.test")
|
||||
assert state.state == "off"
|
||||
assert set(state.attributes["hvac_modes"]) == {"off", "cool"}
|
||||
assert state.attributes["hvac_action"] == "off"
|
||||
|
||||
await knx.receive_write(on_off_ga, True)
|
||||
state = hass.states.get("climate.test")
|
||||
assert state.state == "cool"
|
||||
assert set(state.attributes["hvac_modes"]) == {"off", "cool"}
|
||||
assert state.attributes["hvac_action"] == "cooling"
|
||||
|
||||
|
||||
async def test_climate_preset_mode(
|
||||
hass: HomeAssistant, knx: KNXTestKit, entity_registry: er.EntityRegistry
|
||||
) -> None:
|
||||
|
|
Loading…
Add table
Reference in a new issue