Skip to content

Commit

Permalink
Use fan mode when heat/cool is idle in homekit
Browse files Browse the repository at this point in the history
  • Loading branch information
Xeio committed Oct 18, 2024
1 parent 1a9c6de commit e611f46
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
17 changes: 16 additions & 1 deletion homeassistant/components/homekit_controller/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@
FAN_HIGH: ROTATION_SPEED_HIGH,
}

HOMEKIT_CURRENT_FAN_STATE_ACTIVE = 2


async def async_setup_entry(
hass: HomeAssistant,
Expand Down Expand Up @@ -484,6 +486,7 @@ def get_characteristic_types(self) -> list[str]:
CharacteristicsTypes.TEMPERATURE_TARGET,
CharacteristicsTypes.RELATIVE_HUMIDITY_CURRENT,
CharacteristicsTypes.RELATIVE_HUMIDITY_TARGET,
CharacteristicsTypes.FAN_STATE_CURRENT,
]

async def async_set_temperature(self, **kwargs: Any) -> None:
Expand Down Expand Up @@ -666,7 +669,19 @@ def hvac_action(self) -> HVACAction | None:
return HVACAction.IDLE

value = self.service.value(CharacteristicsTypes.HEATING_COOLING_CURRENT)
return CURRENT_MODE_HOMEKIT_TO_HASS.get(value)
current_hass_value = CURRENT_MODE_HOMEKIT_TO_HASS.get(value)

# If a device has a fan state (such as an Ecobee thermostat)
# show the Fan state when the device is otherwise idle.
if (
current_hass_value == HVACAction.IDLE
and self.service.has(CharacteristicsTypes.FAN_STATE_CURRENT)
and self.service.value(CharacteristicsTypes.FAN_STATE_CURRENT)
== HOMEKIT_CURRENT_FAN_STATE_ACTIVE
):
return HVACAction.FAN

return current_hass_value

@property
def hvac_mode(self) -> HVACMode:
Expand Down
15 changes: 15 additions & 0 deletions tests/components/homekit_controller/test_climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ def create_thermostat_service(accessory: Accessory) -> None:
char = service.add_char(CharacteristicsTypes.RELATIVE_HUMIDITY_CURRENT)
char.value = 0

char = service.add_char(CharacteristicsTypes.FAN_STATE_CURRENT)
char.value = 0


def create_thermostat_service_min_max(accessory: Accessory) -> None:
"""Define thermostat characteristics."""
Expand Down Expand Up @@ -648,6 +651,18 @@ async def test_hvac_mode_vs_hvac_action(
assert state.state == "heat"
assert state.attributes["hvac_action"] == "idle"

# Simulate the fan running while the heat/cool is idle
await helper.async_update(
ServicesTypes.THERMOSTAT,
{
CharacteristicsTypes.FAN_MODE_CURRENT: 2,

Check failure on line 658 in tests/components/homekit_controller/test_climate.py

View workflow job for this annotation

GitHub Actions / Run tests Python 3.12 (homekit_controller)

test_hvac_mode_vs_hvac_action AttributeError: type object 'CharacteristicsTypes' has no attribute 'FAN_MODE_CURRENT'. Did you mean: 'FAN_STATE_CURRENT'?
},
)

state = await helper.poll_and_get_state()
assert state.state == "heat"
assert state.attributes["hvac_action"] == "fan"

# Simulate that current temperature is below target temp
# Heating might be on and hvac_action currently 'heat'
await helper.async_update(
Expand Down

0 comments on commit e611f46

Please sign in to comment.