Skip to content

Commit

Permalink
Climate: Added humidity support (#1586)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexkn authored Oct 20, 2024
1 parent 7f6bcfb commit 90dbacb
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 0 deletions.
4 changes: 4 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ nav_order: 2

# Changelog

### Devices

- Climate: Added humidity support

# 3.2.0 Climate Fan speed 2024-09-23

### Devices
Expand Down
2 changes: 2 additions & 0 deletions docs/climate.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Climate are representations of KNX HVAC/Climate controls.
- `on_off_invert` Invert on/off. Default: `False`
- `group_address_active_state` KNX address for reading if the climate device is currently active. *DPT 1*
- `group_address_command_value_state` KNX address for reading the current command value / valve position in %. *DPT 5.001*
- `group_address_humidity_state` KNX address of current room humidity. *DPT 9.007*
- `sync_state` defines if and how often the value should be actively read from the bus. If `False` no GroupValueRead telegrams will be sent to its group address. Defaults to `True`
- `max_temp` Maximum value for target temperature.
- `min_temp` Minimum value for target temperature.
Expand Down Expand Up @@ -94,6 +95,7 @@ climate = Climate(
mode=climate_mode,
device_updated_cb=None,
fan_speed_mode=FanSpeedMode.STEP,
group_address_humidity_state='',
)
xknx.devices.async_add(climate)
xknx.devices.async_add(climate_mode)
Expand Down
28 changes: 28 additions & 0 deletions test/devices_tests/climate_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
DPT2ByteFloat,
DPTArray,
DPTBinary,
DPTHumidity,
DPTHVACContrMode,
DPTHVACMode,
DPTHVACStatus,
Expand Down Expand Up @@ -84,13 +85,15 @@ def test_has_group_address(self):
group_address_setpoint_shift_state="1/2/4",
group_address_on_off="1/2/11",
group_address_on_off_state="1/2/12",
group_address_humidity_state="1/2/16",
)

assert climate.has_group_address(GroupAddress("1/2/1"))
assert climate.has_group_address(GroupAddress("1/2/2"))
assert climate.has_group_address(GroupAddress("1/2/4"))
assert climate.has_group_address(GroupAddress("1/2/11"))
assert climate.has_group_address(GroupAddress("1/2/12"))
assert climate.has_group_address(GroupAddress("1/2/16"))
assert not climate.has_group_address(GroupAddress("1/2/99"))

#
Expand Down Expand Up @@ -1073,6 +1076,15 @@ async def test_sync_mode_from_climate(self):
telegram1 = xknx.telegrams.get_nowait()
assert telegram1 == Telegram(GroupAddress("1/2/4"), payload=GroupValueRead())

async def test_sync_humidity(self):
"""Test sync function / sending group reads to KNX bus for humidity."""
xknx = XKNX()
climate = Climate(xknx, "TestClimate", group_address_humidity_state="1/2/16")
await climate.sync()
assert xknx.telegrams.qsize() == 1
telegram1 = xknx.telegrams.get_nowait()
assert telegram1 == Telegram(GroupAddress("1/2/16"), payload=GroupValueRead())

#
# TEST PROCESS
#
Expand Down Expand Up @@ -1258,6 +1270,22 @@ async def test_process_heat_cool(self):
climate_mode.process(telegram)
assert climate_mode.controller_mode == HVACControllerMode.HEAT

async def test_process_humidity(self):
"""Test process / reading telegrams from telegram queue. Test if humidity is processed correctly."""
xknx = XKNX()
climate = Climate(xknx, "TestClimate", group_address_humidity_state="1/2/16")
after_update_callback = Mock()
climate.register_device_updated_cb(after_update_callback)

telegram = Telegram(
destination_address=GroupAddress("1/2/16"),
payload=GroupValueWrite(DPTHumidity.to_knx(45.6)),
)
climate.process(telegram)

assert climate.humidity.value == 45.6
after_update_callback.assert_called_with(climate)

#
# SUPPORTED OPERATION MODES
#
Expand Down
13 changes: 13 additions & 0 deletions xknx/devices/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
GroupAddressesType,
RemoteValue,
RemoteValueDptValue1Ucount,
RemoteValueNumeric,
RemoteValueScaling,
RemoteValueSetpointShift,
RemoteValueSwitch,
Expand Down Expand Up @@ -68,6 +69,7 @@ def __init__(
group_address_fan_speed: GroupAddressesType = None,
group_address_fan_speed_state: GroupAddressesType = None,
fan_speed_mode: FanSpeedMode = FanSpeedMode.PERCENT,
group_address_humidity_state: GroupAddressesType = None,
):
"""Initialize Climate class."""
super().__init__(xknx, name, device_updated_cb)
Expand Down Expand Up @@ -168,6 +170,16 @@ def __init__(

self.mode = mode

self.humidity = RemoteValueNumeric(
xknx,
group_address_state=group_address_humidity_state,
sync_state=sync_state,
value_type="humidity",
device_name=self.name,
feature_name="Current humidity",
after_update_cb=self.after_update,
)

def _iter_remote_values(self) -> Iterator[RemoteValue[Any]]:
"""Iterate the devices RemoteValue classes."""
yield self.temperature
Expand All @@ -177,6 +189,7 @@ def _iter_remote_values(self) -> Iterator[RemoteValue[Any]]:
yield self.active
yield self.command_value
yield self.fan_speed
yield self.humidity

def has_group_address(self, group_address: DeviceGroupAddress) -> bool:
"""Test if device has given group address."""
Expand Down

0 comments on commit 90dbacb

Please sign in to comment.