Skip to content

Commit

Permalink
emulated_hue: Use correct state for covers
Browse files Browse the repository at this point in the history
  • Loading branch information
Tho85 committed Dec 27, 2023
1 parent 178e4f9 commit e4a559c
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 4 deletions.
16 changes: 12 additions & 4 deletions homeassistant/components/emulated_hue/hue_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
SERVICE_VOLUME_SET,
STATE_CLOSED,
STATE_OFF,
STATE_ON,
STATE_UNAVAILABLE,
Expand Down Expand Up @@ -394,7 +395,7 @@ async def put( # noqa: C901
return self.json_message("Bad request", HTTPStatus.BAD_REQUEST)
parsed[STATE_ON] = request_json[HUE_API_STATE_ON]
else:
parsed[STATE_ON] = entity.state != STATE_OFF
parsed[STATE_ON] = _hass_to_hue_state(entity)

for key, attr in (
(HUE_API_STATE_BRI, STATE_BRIGHTNESS),
Expand Down Expand Up @@ -585,7 +586,7 @@ async def put( # noqa: C901
)

if service is not None:
state_will_change = parsed[STATE_ON] != (entity.state != STATE_OFF)
state_will_change = parsed[STATE_ON] != _hass_to_hue_state(entity)

hass.async_create_task(
hass.services.async_call(domain, service, data, blocking=True)
Expand Down Expand Up @@ -643,7 +644,7 @@ def get_entity_state_dict(config: Config, entity: State) -> dict[str, Any]:
cached_state = entry_state
elif time.time() - entry_time < STATE_CACHED_TIMEOUT and entry_state[
STATE_ON
] == (entity.state != STATE_OFF):
] == _hass_to_hue_state(entity):
# We only want to use the cache if the actual state of the entity
# is in sync so that it can be detected as an error by Alexa.
cached_state = entry_state
Expand Down Expand Up @@ -676,7 +677,7 @@ def get_entity_state_dict(config: Config, entity: State) -> dict[str, Any]:
@lru_cache(maxsize=512)
def _build_entity_state_dict(entity: State) -> dict[str, Any]:
"""Build a state dict for an entity."""
is_on = entity.state != STATE_OFF
is_on = _hass_to_hue_state(entity)
data: dict[str, Any] = {
STATE_ON: is_on,
STATE_BRIGHTNESS: None,
Expand Down Expand Up @@ -729,6 +730,13 @@ def _build_entity_state_dict(entity: State) -> dict[str, Any]:
return data


def _hass_to_hue_state(entity: State) -> bool:
if entity.domain == cover.DOMAIN:
return entity.state != STATE_CLOSED

return entity.state != STATE_OFF


def _clamp_values(data: dict[str, Any]) -> None:
"""Clamp brightness, hue, saturation, and color temp to valid values."""
for key, v_min, v_max in (
Expand Down
27 changes: 27 additions & 0 deletions tests/components/emulated_hue/test_hue_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -1019,6 +1019,12 @@ async def test_set_position_cover(hass_hue, hue_client) -> None:
cover_test = hass_hue.states.get(cover_id)
assert cover_test.state == "closed"

cover_json = await perform_get_light_state(
hue_client, "cover.living_room_window", HTTPStatus.OK
)
assert cover_json["state"][HUE_API_STATE_ON] is False
assert cover_json["state"][HUE_API_STATE_BRI] == 1

level = 20
brightness = round(level / 100 * 254)

Expand Down Expand Up @@ -1095,6 +1101,7 @@ async def test_put_light_state_fan(hass_hue, hue_client) -> None:
fan_json = await perform_get_light_state(
hue_client, "fan.living_room_fan", HTTPStatus.OK
)
assert fan_json["state"][HUE_API_STATE_ON] is True
assert round(fan_json["state"][HUE_API_STATE_BRI] * 100 / 254) == 33

await perform_put_light_state(
Expand All @@ -1112,6 +1119,7 @@ async def test_put_light_state_fan(hass_hue, hue_client) -> None:
fan_json = await perform_get_light_state(
hue_client, "fan.living_room_fan", HTTPStatus.OK
)
assert fan_json["state"][HUE_API_STATE_ON] is True
assert (
round(fan_json["state"][HUE_API_STATE_BRI] * 100 / 254) == 66
) # small rounding error in inverse operation
Expand All @@ -1132,8 +1140,27 @@ async def test_put_light_state_fan(hass_hue, hue_client) -> None:
fan_json = await perform_get_light_state(
hue_client, "fan.living_room_fan", HTTPStatus.OK
)
assert fan_json["state"][HUE_API_STATE_ON] is True
assert round(fan_json["state"][HUE_API_STATE_BRI] * 100 / 254) == 100

await perform_put_light_state(
hass_hue,
hue_client,
"fan.living_room_fan",
False,
brightness=0,
)
assert (
hass_hue.states.get("fan.living_room_fan").attributes[fan.ATTR_PERCENTAGE] == 0
)
with patch.object(hue_api, "STATE_CACHED_TIMEOUT", 0.000001):
await asyncio.sleep(0.000001)
fan_json = await perform_get_light_state(
hue_client, "fan.living_room_fan", HTTPStatus.OK
)
assert fan_json["state"][HUE_API_STATE_ON] is False
assert fan_json["state"][HUE_API_STATE_BRI] == 1


async def test_put_with_form_urlencoded_content_type(hass_hue, hue_client) -> None:
"""Test the form with urlencoded content."""
Expand Down

0 comments on commit e4a559c

Please sign in to comment.