Fix emulated_hue brightness off by one (#34185)
* Fix emulated_hue brightness off by one
Hue uses a max brightness of 254, Home Assistant
uses a max brightness of 255. Values > 127 were
off by one.
* use constant
* fix test
* add debug
* Revert "add debug"
This reverts commit 242220a02e
.
pull/33082/head
parent
813f8dd63f
commit
23f278e090
|
@ -367,7 +367,7 @@ class HueOneLightChangeView(HomeAssistantView):
|
|||
cover.DOMAIN,
|
||||
climate.DOMAIN,
|
||||
]:
|
||||
# Convert 0-255 to 0-100
|
||||
# Convert 0-254 to 0-100
|
||||
level = (parsed[STATE_BRIGHTNESS] / HUE_API_STATE_BRI_MAX) * 100
|
||||
parsed[STATE_BRIGHTNESS] = round(level)
|
||||
parsed[STATE_ON] = True
|
||||
|
@ -390,7 +390,9 @@ class HueOneLightChangeView(HomeAssistantView):
|
|||
if parsed[STATE_ON]:
|
||||
if entity_features & SUPPORT_BRIGHTNESS:
|
||||
if parsed[STATE_BRIGHTNESS] is not None:
|
||||
data[ATTR_BRIGHTNESS] = parsed[STATE_BRIGHTNESS]
|
||||
data[ATTR_BRIGHTNESS] = hue_brightness_to_hass(
|
||||
parsed[STATE_BRIGHTNESS]
|
||||
)
|
||||
|
||||
if entity_features & SUPPORT_COLOR:
|
||||
if any((parsed[STATE_HUE], parsed[STATE_SATURATION])):
|
||||
|
@ -536,7 +538,9 @@ def get_entity_state(config, entity):
|
|||
data[STATE_ON] = entity.state != STATE_OFF
|
||||
|
||||
if data[STATE_ON]:
|
||||
data[STATE_BRIGHTNESS] = entity.attributes.get(ATTR_BRIGHTNESS, 0)
|
||||
data[STATE_BRIGHTNESS] = hass_to_hue_brightness(
|
||||
entity.attributes.get(ATTR_BRIGHTNESS, 0)
|
||||
)
|
||||
hue_sat = entity.attributes.get(ATTR_HS_COLOR)
|
||||
if hue_sat is not None:
|
||||
hue = hue_sat[0]
|
||||
|
@ -563,32 +567,32 @@ def get_entity_state(config, entity):
|
|||
pass
|
||||
elif entity.domain == climate.DOMAIN:
|
||||
temperature = entity.attributes.get(ATTR_TEMPERATURE, 0)
|
||||
# Convert 0-100 to 0-255
|
||||
data[STATE_BRIGHTNESS] = round(temperature * 255 / 100)
|
||||
# Convert 0-100 to 0-254
|
||||
data[STATE_BRIGHTNESS] = round(temperature * HUE_API_STATE_BRI_MAX / 100)
|
||||
elif entity.domain == media_player.DOMAIN:
|
||||
level = entity.attributes.get(
|
||||
ATTR_MEDIA_VOLUME_LEVEL, 1.0 if data[STATE_ON] else 0.0
|
||||
)
|
||||
# Convert 0.0-1.0 to 0-255
|
||||
data[STATE_BRIGHTNESS] = round(min(1.0, level) * 255)
|
||||
# Convert 0.0-1.0 to 0-254
|
||||
data[STATE_BRIGHTNESS] = round(min(1.0, level) * HUE_API_STATE_BRI_MAX)
|
||||
elif entity.domain == fan.DOMAIN:
|
||||
speed = entity.attributes.get(ATTR_SPEED, 0)
|
||||
# Convert 0.0-1.0 to 0-255
|
||||
# Convert 0.0-1.0 to 0-254
|
||||
data[STATE_BRIGHTNESS] = 0
|
||||
if speed == SPEED_LOW:
|
||||
data[STATE_BRIGHTNESS] = 85
|
||||
elif speed == SPEED_MEDIUM:
|
||||
data[STATE_BRIGHTNESS] = 170
|
||||
elif speed == SPEED_HIGH:
|
||||
data[STATE_BRIGHTNESS] = 255
|
||||
data[STATE_BRIGHTNESS] = HUE_API_STATE_BRI_MAX
|
||||
elif entity.domain == cover.DOMAIN:
|
||||
level = entity.attributes.get(ATTR_CURRENT_POSITION, 0)
|
||||
data[STATE_BRIGHTNESS] = round(level / 100 * 255)
|
||||
data[STATE_BRIGHTNESS] = round(level / 100 * HUE_API_STATE_BRI_MAX)
|
||||
else:
|
||||
data = cached_state
|
||||
# Make sure brightness is valid
|
||||
if data[STATE_BRIGHTNESS] is None:
|
||||
data[STATE_BRIGHTNESS] = 255 if data[STATE_ON] else 0
|
||||
data[STATE_BRIGHTNESS] = HUE_API_STATE_BRI_MAX if data[STATE_ON] else 0
|
||||
|
||||
# Make sure hue/saturation are valid
|
||||
if (data[STATE_HUE] is None) or (data[STATE_SATURATION] is None):
|
||||
|
@ -723,3 +727,13 @@ def create_list_of_entities(config, request):
|
|||
json_response[number] = entity_to_json(config, entity)
|
||||
|
||||
return json_response
|
||||
|
||||
|
||||
def hue_brightness_to_hass(value):
|
||||
"""Convert hue brightness 1..254 to hass format 0..255."""
|
||||
return min(255, round((value / HUE_API_STATE_BRI_MAX) * 255))
|
||||
|
||||
|
||||
def hass_to_hue_brightness(value):
|
||||
"""Convert hass brightness 0..255 to hue 1..254 scale."""
|
||||
return max(1, round((value / 255) * HUE_API_STATE_BRI_MAX))
|
||||
|
|
|
@ -384,7 +384,7 @@ async def test_get_light_state(hass_hue, hue_client):
|
|||
await perform_get_light_state(hue_client, "light.kitchen_lights", 401)
|
||||
|
||||
|
||||
async def test_put_light_state(hass_hue, hue_client):
|
||||
async def test_put_light_state(hass, hass_hue, hue_client):
|
||||
"""Test the setting of light states."""
|
||||
await perform_put_test_on_ceiling_lights(hass_hue, hue_client)
|
||||
|
||||
|
@ -400,6 +400,21 @@ async def test_put_light_state(hass_hue, hue_client):
|
|||
assert ceiling_lights.state == STATE_ON
|
||||
assert ceiling_lights.attributes[light.ATTR_BRIGHTNESS] == 153
|
||||
|
||||
# update light state through api
|
||||
await perform_put_light_state(
|
||||
hass_hue,
|
||||
hue_client,
|
||||
"light.ceiling_lights",
|
||||
True,
|
||||
hue=4369,
|
||||
saturation=127,
|
||||
brightness=128,
|
||||
)
|
||||
|
||||
assert (
|
||||
hass.states.get("light.ceiling_lights").attributes[light.ATTR_BRIGHTNESS] == 129
|
||||
)
|
||||
|
||||
# update light state through api
|
||||
await perform_put_light_state(
|
||||
hass_hue,
|
||||
|
@ -411,6 +426,10 @@ async def test_put_light_state(hass_hue, hue_client):
|
|||
brightness=123,
|
||||
)
|
||||
|
||||
assert (
|
||||
hass.states.get("light.ceiling_lights").attributes[light.ATTR_BRIGHTNESS] == 123
|
||||
)
|
||||
|
||||
# go through api to get the state back
|
||||
ceiling_json = await perform_get_light_state(
|
||||
hue_client, "light.ceiling_lights", 200
|
||||
|
@ -419,6 +438,25 @@ async def test_put_light_state(hass_hue, hue_client):
|
|||
assert ceiling_json["state"][HUE_API_STATE_HUE] == 4369
|
||||
assert ceiling_json["state"][HUE_API_STATE_SAT] == 127
|
||||
|
||||
# update light state through api
|
||||
await perform_put_light_state(
|
||||
hass_hue,
|
||||
hue_client,
|
||||
"light.ceiling_lights",
|
||||
True,
|
||||
hue=4369,
|
||||
saturation=127,
|
||||
brightness=255,
|
||||
)
|
||||
|
||||
# go through api to get the state back
|
||||
ceiling_json = await perform_get_light_state(
|
||||
hue_client, "light.ceiling_lights", 200
|
||||
)
|
||||
assert ceiling_json["state"][HUE_API_STATE_BRI] == 254
|
||||
assert ceiling_json["state"][HUE_API_STATE_HUE] == 4369
|
||||
assert ceiling_json["state"][HUE_API_STATE_SAT] == 127
|
||||
|
||||
# Go through the API to turn it off
|
||||
ceiling_result = await perform_put_light_state(
|
||||
hass_hue, hue_client, "light.ceiling_lights", False
|
||||
|
@ -454,7 +492,7 @@ async def test_put_light_state(hass_hue, hue_client):
|
|||
assert kitchen_result.status == HTTP_NOT_FOUND
|
||||
|
||||
|
||||
async def test_put_light_state_script(hass_hue, hue_client):
|
||||
async def test_put_light_state_script(hass, hass_hue, hue_client):
|
||||
"""Test the setting of script variables."""
|
||||
# Turn the kitchen light off first
|
||||
await hass_hue.services.async_call(
|
||||
|
@ -464,9 +502,9 @@ async def test_put_light_state_script(hass_hue, hue_client):
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
# Emulated hue converts 0-100% to 0-255.
|
||||
# Emulated hue converts 0-100% to 0-254.
|
||||
level = 23
|
||||
brightness = round(level * 255 / 100)
|
||||
brightness = round(level * 254 / 100)
|
||||
|
||||
script_result = await perform_put_light_state(
|
||||
hass_hue, hue_client, "script.set_kitchen_light", True, brightness
|
||||
|
@ -481,11 +519,15 @@ async def test_put_light_state_script(hass_hue, hue_client):
|
|||
assert kitchen_light.state == "on"
|
||||
assert kitchen_light.attributes[light.ATTR_BRIGHTNESS] == level
|
||||
|
||||
assert (
|
||||
hass.states.get("light.kitchen_lights").attributes[light.ATTR_BRIGHTNESS] == 23
|
||||
)
|
||||
|
||||
|
||||
async def test_put_light_state_climate_set_temperature(hass_hue, hue_client):
|
||||
"""Test setting climate temperature."""
|
||||
brightness = 19
|
||||
temperature = round(brightness / 255 * 100)
|
||||
temperature = round(brightness / 254 * 100)
|
||||
|
||||
hvac_result = await perform_put_light_state(
|
||||
hass_hue, hue_client, "climate.hvac", True, brightness
|
||||
|
@ -517,9 +559,9 @@ async def test_put_light_state_media_player(hass_hue, hue_client):
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
# Emulated hue converts 0.0-1.0 to 0-255.
|
||||
# Emulated hue converts 0.0-1.0 to 0-254.
|
||||
level = 0.25
|
||||
brightness = round(level * 255)
|
||||
brightness = round(level * 254)
|
||||
|
||||
mp_result = await perform_put_light_state(
|
||||
hass_hue, hue_client, "media_player.walkman", True, brightness
|
||||
|
@ -602,7 +644,7 @@ async def test_set_position_cover(hass_hue, hue_client):
|
|||
assert cover_test.state == "closed"
|
||||
|
||||
level = 20
|
||||
brightness = round(level / 100 * 255)
|
||||
brightness = round(level / 100 * 254)
|
||||
|
||||
# Go through the API to open
|
||||
cover_result = await perform_put_light_state(
|
||||
|
@ -644,9 +686,9 @@ async def test_put_light_state_fan(hass_hue, hue_client):
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
# Emulated hue converts 0-100% to 0-255.
|
||||
# Emulated hue converts 0-100% to 0-254.
|
||||
level = 43
|
||||
brightness = round(level * 255 / 100)
|
||||
brightness = round(level * 254 / 100)
|
||||
|
||||
fan_result = await perform_put_light_state(
|
||||
hass_hue, hue_client, "fan.living_room_fan", True, brightness
|
||||
|
|
Loading…
Reference in New Issue