mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 08:47:57 +00:00
Add swing support for KNX climate entities (#136752)
* added swing to knx climate * added tests for climate swing * removed type ignores * removed unreachable code
This commit is contained in:
parent
814e98f66a
commit
77d9309b81
@ -19,6 +19,8 @@ from homeassistant.components.climate import (
|
||||
FAN_LOW,
|
||||
FAN_MEDIUM,
|
||||
FAN_ON,
|
||||
SWING_OFF,
|
||||
SWING_ON,
|
||||
ClimateEntity,
|
||||
ClimateEntityFeature,
|
||||
HVACAction,
|
||||
@ -136,6 +138,14 @@ def _create_climate(xknx: XKNX, config: ConfigType) -> XknxClimate:
|
||||
ClimateSchema.CONF_FAN_SPEED_STATE_ADDRESS
|
||||
),
|
||||
fan_speed_mode=config[ClimateSchema.CONF_FAN_SPEED_MODE],
|
||||
group_address_swing=config.get(ClimateSchema.CONF_SWING_ADDRESS),
|
||||
group_address_swing_state=config.get(ClimateSchema.CONF_SWING_STATE_ADDRESS),
|
||||
group_address_horizontal_swing=config.get(
|
||||
ClimateSchema.CONF_SWING_HORIZONTAL_ADDRESS
|
||||
),
|
||||
group_address_horizontal_swing_state=config.get(
|
||||
ClimateSchema.CONF_SWING_HORIZONTAL_STATE_ADDRESS
|
||||
),
|
||||
group_address_humidity_state=config.get(
|
||||
ClimateSchema.CONF_HUMIDITY_STATE_ADDRESS
|
||||
),
|
||||
@ -207,6 +217,13 @@ class KNXClimate(KnxYamlEntity, ClimateEntity):
|
||||
self._attr_fan_modes = [self.fan_zero_mode] + [
|
||||
f"{percentage}%" for percentage in self._fan_modes_percentages[1:]
|
||||
]
|
||||
if self._device.swing.initialized:
|
||||
self._attr_supported_features |= ClimateEntityFeature.SWING_MODE
|
||||
self._attr_swing_modes = [SWING_ON, SWING_OFF]
|
||||
|
||||
if self._device.horizontal_swing.initialized:
|
||||
self._attr_supported_features |= ClimateEntityFeature.SWING_HORIZONTAL_MODE
|
||||
self._attr_swing_horizontal_modes = [SWING_ON, SWING_OFF]
|
||||
|
||||
self._attr_target_temperature_step = self._device.temperature_step
|
||||
self._attr_unique_id = (
|
||||
@ -399,6 +416,28 @@ class KNXClimate(KnxYamlEntity, ClimateEntity):
|
||||
|
||||
await self._device.set_fan_speed(self._fan_modes_percentages[fan_mode_index])
|
||||
|
||||
async def async_set_swing_mode(self, swing_mode: str) -> None:
|
||||
"""Set the swing setting."""
|
||||
await self._device.set_swing(swing_mode == SWING_ON)
|
||||
|
||||
async def async_set_swing_horizontal_mode(self, swing_horizontal_mode: str) -> None:
|
||||
"""Set the horizontal swing setting."""
|
||||
await self._device.set_horizontal_swing(swing_horizontal_mode == SWING_ON)
|
||||
|
||||
@property
|
||||
def swing_mode(self) -> str | None:
|
||||
"""Return the swing setting."""
|
||||
if self._device.swing.value is not None:
|
||||
return SWING_ON if self._device.swing.value else SWING_OFF
|
||||
return None
|
||||
|
||||
@property
|
||||
def swing_horizontal_mode(self) -> str | None:
|
||||
"""Return the horizontal swing setting."""
|
||||
if self._device.horizontal_swing.value is not None:
|
||||
return SWING_ON if self._device.horizontal_swing.value else SWING_OFF
|
||||
return None
|
||||
|
||||
@property
|
||||
def current_humidity(self) -> float | None:
|
||||
"""Return the current humidity."""
|
||||
|
@ -339,6 +339,10 @@ class ClimateSchema(KNXPlatformSchema):
|
||||
CONF_FAN_SPEED_MODE = "fan_speed_mode"
|
||||
CONF_FAN_ZERO_MODE = "fan_zero_mode"
|
||||
CONF_HUMIDITY_STATE_ADDRESS = "humidity_state_address"
|
||||
CONF_SWING_ADDRESS = "swing_address"
|
||||
CONF_SWING_STATE_ADDRESS = "swing_state_address"
|
||||
CONF_SWING_HORIZONTAL_ADDRESS = "swing_horizontal_address"
|
||||
CONF_SWING_HORIZONTAL_STATE_ADDRESS = "swing_horizontal_state_address"
|
||||
|
||||
DEFAULT_NAME = "KNX Climate"
|
||||
DEFAULT_SETPOINT_SHIFT_MODE = "DPT6010"
|
||||
@ -427,6 +431,10 @@ class ClimateSchema(KNXPlatformSchema):
|
||||
vol.Optional(CONF_FAN_ZERO_MODE, default=FAN_OFF): vol.Coerce(
|
||||
FanZeroMode
|
||||
),
|
||||
vol.Optional(CONF_SWING_ADDRESS): ga_list_validator,
|
||||
vol.Optional(CONF_SWING_STATE_ADDRESS): ga_list_validator,
|
||||
vol.Optional(CONF_SWING_HORIZONTAL_ADDRESS): ga_list_validator,
|
||||
vol.Optional(CONF_SWING_HORIZONTAL_STATE_ADDRESS): ga_list_validator,
|
||||
vol.Optional(CONF_HUMIDITY_STATE_ADDRESS): ga_list_validator,
|
||||
}
|
||||
),
|
||||
|
@ -850,3 +850,91 @@ async def test_climate_humidity(hass: HomeAssistant, knx: KNXTestKit) -> None:
|
||||
HVACMode.HEAT,
|
||||
current_humidity=45.6,
|
||||
)
|
||||
|
||||
|
||||
async def test_swing(hass: HomeAssistant, knx: KNXTestKit) -> None:
|
||||
"""Test KNX climate swing."""
|
||||
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_SWING_ADDRESS: "1/2/6",
|
||||
ClimateSchema.CONF_SWING_STATE_ADDRESS: "1/2/7",
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
# 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")
|
||||
await knx.receive_response("1/2/7", True)
|
||||
knx.assert_state(
|
||||
"climate.test",
|
||||
HVACMode.HEAT,
|
||||
swing_mode="on",
|
||||
swing_modes=["on", "off"],
|
||||
)
|
||||
|
||||
# turn off
|
||||
await hass.services.async_call(
|
||||
"climate",
|
||||
"set_swing_mode",
|
||||
{"entity_id": "climate.test", "swing_mode": "off"},
|
||||
blocking=True,
|
||||
)
|
||||
await knx.assert_write("1/2/6", False)
|
||||
knx.assert_state("climate.test", HVACMode.HEAT, swing_mode="off")
|
||||
|
||||
|
||||
async def test_horizontal_swing(hass: HomeAssistant, knx: KNXTestKit) -> None:
|
||||
"""Test KNX climate horizontal swing."""
|
||||
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_SWING_HORIZONTAL_ADDRESS: "1/2/6",
|
||||
ClimateSchema.CONF_SWING_HORIZONTAL_STATE_ADDRESS: "1/2/7",
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
# 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")
|
||||
await knx.receive_response("1/2/7", True)
|
||||
knx.assert_state(
|
||||
"climate.test",
|
||||
HVACMode.HEAT,
|
||||
swing_horizontal_mode="on",
|
||||
swing_horizontal_modes=["on", "off"],
|
||||
)
|
||||
|
||||
# turn off
|
||||
await hass.services.async_call(
|
||||
"climate",
|
||||
"set_swing_horizontal_mode",
|
||||
{"entity_id": "climate.test", "swing_horizontal_mode": "off"},
|
||||
blocking=True,
|
||||
)
|
||||
await knx.assert_write("1/2/6", False)
|
||||
knx.assert_state("climate.test", HVACMode.HEAT, swing_horizontal_mode="off")
|
||||
|
Loading…
x
Reference in New Issue
Block a user