Skip to content

Commit

Permalink
Merge pull request #212 from kongo09/198-represent-humidifiers-by-hum…
Browse files Browse the repository at this point in the history
…idifier-entity-instead-of-fan-entity

represent humidifiers by humidifier entity instead of fan entity
  • Loading branch information
kongo09 authored Nov 30, 2024
2 parents 4c64159 + 7cd6309 commit 574c4be
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 27 deletions.
1 change: 1 addition & 0 deletions custom_components/philips_airpurifier_coap/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ class FanAttributes(StrEnum):
FILTER_NANOPROTECT = "nanoprotect_filter"
FILTER_NANOPROTECT_CLEAN = "pre_filter"
FUNCTION = "function"
PURIFICATION = "purification"
HUMIDITY = "humidity"
HUMIDIFICATION = "humidification"
HUMIDIFIER = "humidifier"
Expand Down
4 changes: 3 additions & 1 deletion custom_components/philips_airpurifier_coap/fan.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,6 @@ async def async_setup_entry(
_LOGGER.error("Unsupported model: %s", model)
return

async_add_entities([fan_entity])
# some humidifiers don't need a fan entity
if fan_entity.CREATE_FAN:
async_add_entities([fan_entity])
78 changes: 52 additions & 26 deletions custom_components/philips_airpurifier_coap/humidifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,16 +107,23 @@ def __init__(
self._description[FanAttributes.HUMIDITY]
)

# not all humidifiers can set a mode
# 2-in-1 devices have a switch to select humidification vs purification
if self._switch:
self._attr_supported_features = HumidifierEntityFeature.MODES
self._attr_available_modes = {FanAttributes.IDLE, FanAttributes.HUMIDIFYING}
self._attr_available_modes = {
FanAttributes.PURIFICATION,
FanAttributes.HUMIDIFICATION,
}

# pure humidification devices are identified by the function being the power and have the fan modes as modes
elif self._function_key == self._power_key:
self._attr_supported_features = HumidifierEntityFeature.MODES
self._attr_available_modes = list(self._available_preset_modes.keys())

@property
def action(self) -> str:
"""Return the current action."""
function_status = self._device_status.get(self._function_key)
_LOGGER.debug("function_status: %s", function_status)

if function_status == self._description[FanAttributes.HUMIDIFYING]:
return HumidifierAction.HUMIDIFYING
Expand All @@ -137,35 +144,54 @@ def target_humidity(self) -> int | None:
def mode(self) -> str | None:
"""Return the current mode."""

# not all humidifiers can set a mode
if not self._switch:
return None

function_status = self._device_status.get(self._function_key)
if function_status == self._description[FanAttributes.HUMIDIFYING]:
return FanAttributes.HUMIDIFYING

return FanAttributes.IDLE
# first we treat 2-in-1 devices
if self._switch:
function_status = self._device_status.get(self._function_key)
if function_status == self._description[FanAttributes.HUMIDIFYING]:
return FanAttributes.HUMIDIFICATION
return FanAttributes.PURIFICATION

# then we treat pure humidification devices
if self._function_key == self._power_key:
for preset_mode, status_pattern in self._available_preset_modes.items():
for k, v in status_pattern.items():
status = self._device_status.get(k)
if status != v:
break
else:
return preset_mode

# no mode found
return None

async def async_set_mode(self, mode: str) -> None:
"""Set the mode of the humidifier."""
if mode not in self._attr_available_modes:
return

if mode == FanAttributes.IDLE:
function_value = self._description[FanAttributes.IDLE]
else:
function_value = self._description[FanAttributes.HUMIDIFYING]
# first we treat the 2-in-1 devices
if self._switch:
if mode == FanAttributes.PURIFICATION:
function_value = self._description[FanAttributes.IDLE]
else:
function_value = self._description[FanAttributes.HUMIDIFYING]

await self.coordinator.client.set_control_values(
data={
self._power_key: self._description[FanAttributes.ON],
self._function_key: function_value,
}
)
self._device_status[self._power_key] = self._description[FanAttributes.ON]
self._device_status[self._function_key] = function_value
self._handle_coordinator_update()

await self.coordinator.client.set_control_values(
data={
self._power_key: self._description[FanAttributes.ON],
self._function_key: function_value,
}
)
self._device_status[self._power_key] = self._description[FanAttributes.ON]
self._device_status[self._function_key] = function_value
self._handle_coordinator_update()
# then we treat pure humidification devices
elif self._function_key == self._power_key:
status_pattern = self._available_preset_modes.get(mode)
await self.coordinator.client.set_control_values(data=status_pattern)
self._device_status.update(status_pattern)
self._handle_coordinator_update()

@property
def is_on(self) -> bool | None:
Expand Down Expand Up @@ -195,7 +221,7 @@ async def async_turn_off(self, **kwargs: Any) -> None:
self._power_key: self._description[FanAttributes.OFF],
}
)
self._device_status[self._power_key] = self._description[FanAttributes.ON]
self._device_status[self._power_key] = self._description[FanAttributes.OFF]
self._handle_coordinator_update()

async def async_set_humidity(self, humidity: str) -> None:
Expand Down
6 changes: 6 additions & 0 deletions custom_components/philips_airpurifier_coap/philips.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ def append(
class PhilipsGenericFanBase(PhilipsGenericControlBase, FanEntity):
"""Class as basis to manage a generic Philips fan."""

CREATE_FAN = True

AVAILABLE_SPEEDS = {}
REPLACE_SPEED = None
AVAILABLE_SWITCHES = []
Expand Down Expand Up @@ -1915,6 +1917,8 @@ class PhilipsCX3550(PhilipsNew2GenericFan):
class PhilipsHU1509(PhilipsNew2GenericFan):
"""HU1509."""

CREATE_FAN = False

AVAILABLE_PRESET_MODES = {
PresetMode.AUTO: {
PhilipsApi.NEW2_POWER: 1,
Expand Down Expand Up @@ -1951,6 +1955,8 @@ class PhilipsHU1510(PhilipsHU1509):
class PhilipsHU5710(PhilipsNew2GenericFan):
"""HU5710."""

CREATE_FAN = False

AVAILABLE_PRESET_MODES = {
PresetMode.AUTO: {
PhilipsApi.NEW2_POWER: 1,
Expand Down

0 comments on commit 574c4be

Please sign in to comment.