mirror of
https://github.com/home-assistant/core.git
synced 2025-07-10 06:47:09 +00:00
Add humidifier support to emulated_hue (#37110)
* Add humidifier support to emulated_hue * add humidifier dependency * move dependency to after_dependency * move dependency to hassfest
This commit is contained in:
parent
95d980da4a
commit
5ba38e5053
@ -8,6 +8,7 @@ from homeassistant.components import (
|
|||||||
climate,
|
climate,
|
||||||
cover,
|
cover,
|
||||||
fan,
|
fan,
|
||||||
|
humidifier,
|
||||||
light,
|
light,
|
||||||
media_player,
|
media_player,
|
||||||
scene,
|
scene,
|
||||||
@ -33,6 +34,10 @@ from homeassistant.components.fan import (
|
|||||||
)
|
)
|
||||||
from homeassistant.components.http import HomeAssistantView
|
from homeassistant.components.http import HomeAssistantView
|
||||||
from homeassistant.components.http.const import KEY_REAL_IP
|
from homeassistant.components.http.const import KEY_REAL_IP
|
||||||
|
from homeassistant.components.humidifier.const import (
|
||||||
|
ATTR_HUMIDITY,
|
||||||
|
SERVICE_SET_HUMIDITY,
|
||||||
|
)
|
||||||
from homeassistant.components.light import (
|
from homeassistant.components.light import (
|
||||||
ATTR_BRIGHTNESS,
|
ATTR_BRIGHTNESS,
|
||||||
ATTR_COLOR_TEMP,
|
ATTR_COLOR_TEMP,
|
||||||
@ -386,6 +391,7 @@ class HueOneLightChangeView(HomeAssistantView):
|
|||||||
fan.DOMAIN,
|
fan.DOMAIN,
|
||||||
cover.DOMAIN,
|
cover.DOMAIN,
|
||||||
climate.DOMAIN,
|
climate.DOMAIN,
|
||||||
|
humidifier.DOMAIN,
|
||||||
]:
|
]:
|
||||||
# Convert 0-254 to 0-100
|
# Convert 0-254 to 0-100
|
||||||
level = (parsed[STATE_BRIGHTNESS] / HUE_API_STATE_BRI_MAX) * 100
|
level = (parsed[STATE_BRIGHTNESS] / HUE_API_STATE_BRI_MAX) * 100
|
||||||
@ -457,6 +463,14 @@ class HueOneLightChangeView(HomeAssistantView):
|
|||||||
service = SERVICE_SET_TEMPERATURE
|
service = SERVICE_SET_TEMPERATURE
|
||||||
data[ATTR_TEMPERATURE] = parsed[STATE_BRIGHTNESS]
|
data[ATTR_TEMPERATURE] = parsed[STATE_BRIGHTNESS]
|
||||||
|
|
||||||
|
# If the requested entity is a humidifier, set the humidity
|
||||||
|
elif entity.domain == humidifier.DOMAIN:
|
||||||
|
if parsed[STATE_BRIGHTNESS] is not None:
|
||||||
|
turn_on_needed = True
|
||||||
|
domain = entity.domain
|
||||||
|
service = SERVICE_SET_HUMIDITY
|
||||||
|
data[ATTR_HUMIDITY] = parsed[STATE_BRIGHTNESS]
|
||||||
|
|
||||||
# If the requested entity is a media player, convert to volume
|
# If the requested entity is a media player, convert to volume
|
||||||
elif entity.domain == media_player.DOMAIN:
|
elif entity.domain == media_player.DOMAIN:
|
||||||
if entity_features & SUPPORT_VOLUME_SET:
|
if entity_features & SUPPORT_VOLUME_SET:
|
||||||
@ -595,6 +609,10 @@ def get_entity_state(config, entity):
|
|||||||
temperature = entity.attributes.get(ATTR_TEMPERATURE, 0)
|
temperature = entity.attributes.get(ATTR_TEMPERATURE, 0)
|
||||||
# Convert 0-100 to 0-254
|
# Convert 0-100 to 0-254
|
||||||
data[STATE_BRIGHTNESS] = round(temperature * HUE_API_STATE_BRI_MAX / 100)
|
data[STATE_BRIGHTNESS] = round(temperature * HUE_API_STATE_BRI_MAX / 100)
|
||||||
|
elif entity.domain == humidifier.DOMAIN:
|
||||||
|
humidity = entity.attributes.get(ATTR_HUMIDITY, 0)
|
||||||
|
# Convert 0-100 to 0-254
|
||||||
|
data[STATE_BRIGHTNESS] = round(humidity * HUE_API_STATE_BRI_MAX / 100)
|
||||||
elif entity.domain == media_player.DOMAIN:
|
elif entity.domain == media_player.DOMAIN:
|
||||||
level = entity.attributes.get(
|
level = entity.attributes.get(
|
||||||
ATTR_MEDIA_VOLUME_LEVEL, 1.0 if data[STATE_ON] else 0.0
|
ATTR_MEDIA_VOLUME_LEVEL, 1.0 if data[STATE_ON] else 0.0
|
||||||
|
@ -13,6 +13,7 @@ from homeassistant.components import (
|
|||||||
emulated_hue,
|
emulated_hue,
|
||||||
fan,
|
fan,
|
||||||
http,
|
http,
|
||||||
|
humidifier,
|
||||||
light,
|
light,
|
||||||
media_player,
|
media_player,
|
||||||
script,
|
script,
|
||||||
@ -73,6 +74,9 @@ ENTITY_IDS_BY_NUMBER = {
|
|||||||
"13": "climate.heatpump",
|
"13": "climate.heatpump",
|
||||||
"14": "climate.ecobee",
|
"14": "climate.ecobee",
|
||||||
"15": "light.no_brightness",
|
"15": "light.no_brightness",
|
||||||
|
"16": "humidifier.humidifier",
|
||||||
|
"17": "humidifier.dehumidifier",
|
||||||
|
"18": "humidifier.hygrostat",
|
||||||
}
|
}
|
||||||
|
|
||||||
ENTITY_NUMBERS_BY_ID = {v: k for k, v in ENTITY_IDS_BY_NUMBER.items()}
|
ENTITY_NUMBERS_BY_ID = {v: k for k, v in ENTITY_IDS_BY_NUMBER.items()}
|
||||||
@ -138,6 +142,12 @@ def hass_hue(loop, hass):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
loop.run_until_complete(
|
||||||
|
setup.async_setup_component(
|
||||||
|
hass, humidifier.DOMAIN, {"humidifier": [{"platform": "demo"}]}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
loop.run_until_complete(
|
loop.run_until_complete(
|
||||||
setup.async_setup_component(
|
setup.async_setup_component(
|
||||||
hass, media_player.DOMAIN, {"media_player": [{"platform": "demo"}]}
|
hass, media_player.DOMAIN, {"media_player": [{"platform": "demo"}]}
|
||||||
@ -181,6 +191,10 @@ def hue_client(loop, hass_hue, aiohttp_client):
|
|||||||
"climate.hvac": {emulated_hue.CONF_ENTITY_HIDDEN: False},
|
"climate.hvac": {emulated_hue.CONF_ENTITY_HIDDEN: False},
|
||||||
# Expose HeatPump
|
# Expose HeatPump
|
||||||
"climate.heatpump": {emulated_hue.CONF_ENTITY_HIDDEN: False},
|
"climate.heatpump": {emulated_hue.CONF_ENTITY_HIDDEN: False},
|
||||||
|
# Expose Humidifier
|
||||||
|
"humidifier.humidifier": {emulated_hue.CONF_ENTITY_HIDDEN: False},
|
||||||
|
# Expose Dehumidifier
|
||||||
|
"humidifier.dehumidifier": {emulated_hue.CONF_ENTITY_HIDDEN: False},
|
||||||
# No expose setting (use default of not exposed)
|
# No expose setting (use default of not exposed)
|
||||||
"climate.nosetting": {},
|
"climate.nosetting": {},
|
||||||
},
|
},
|
||||||
@ -225,6 +239,10 @@ async def test_discover_lights(hue_client):
|
|||||||
assert "00:42:03:fe:97:58:2d:b1-50" in devices # climate.hvac
|
assert "00:42:03:fe:97:58:2d:b1-50" in devices # climate.hvac
|
||||||
assert "00:7b:2a:c7:08:d6:66:bf-80" in devices # climate.heatpump
|
assert "00:7b:2a:c7:08:d6:66:bf-80" in devices # climate.heatpump
|
||||||
assert "00:57:77:a1:6a:8e:ef:b3-6c" not in devices # climate.ecobee
|
assert "00:57:77:a1:6a:8e:ef:b3-6c" not in devices # climate.ecobee
|
||||||
|
assert "00:18:7c:7e:78:0e:cd:86-ae" in devices # light.no_brightness
|
||||||
|
assert "00:78:eb:f8:d5:0c:14:85-e7" in devices # humidifier.humidifier
|
||||||
|
assert "00:67:19:bd:ea:e4:2d:ef-22" in devices # humidifier.dehumidifier
|
||||||
|
assert "00:61:bf:ab:08:b1:a6:18-43" not in devices # humidifier.hygrostat
|
||||||
|
|
||||||
|
|
||||||
async def test_light_without_brightness_supported(hass_hue, hue_client):
|
async def test_light_without_brightness_supported(hass_hue, hue_client):
|
||||||
@ -631,6 +649,39 @@ async def test_put_light_state_climate_set_temperature(hass_hue, hue_client):
|
|||||||
assert ecobee_result.status == HTTP_UNAUTHORIZED
|
assert ecobee_result.status == HTTP_UNAUTHORIZED
|
||||||
|
|
||||||
|
|
||||||
|
async def test_put_light_state_humidifier_set_humidity(hass_hue, hue_client):
|
||||||
|
"""Test setting humidifier target humidity."""
|
||||||
|
# Turn the humidifier off first
|
||||||
|
await hass_hue.services.async_call(
|
||||||
|
humidifier.DOMAIN,
|
||||||
|
const.SERVICE_TURN_OFF,
|
||||||
|
{const.ATTR_ENTITY_ID: "humidifier.humidifier"},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
brightness = 19
|
||||||
|
humidity = round(brightness / 254 * 100)
|
||||||
|
|
||||||
|
humidifier_result = await perform_put_light_state(
|
||||||
|
hass_hue, hue_client, "humidifier.humidifier", True, brightness
|
||||||
|
)
|
||||||
|
|
||||||
|
humidifier_result_json = await humidifier_result.json()
|
||||||
|
|
||||||
|
assert humidifier_result.status == HTTP_OK
|
||||||
|
assert len(humidifier_result_json) == 2
|
||||||
|
|
||||||
|
hvac = hass_hue.states.get("humidifier.humidifier")
|
||||||
|
assert hvac.state == "on"
|
||||||
|
assert hvac.attributes[humidifier.ATTR_HUMIDITY] == humidity
|
||||||
|
|
||||||
|
# Make sure we can't change the hygrostat humidity since it's not exposed
|
||||||
|
hygrostat_result = await perform_put_light_state(
|
||||||
|
hass_hue, hue_client, "humidifier.hygrostat", True
|
||||||
|
)
|
||||||
|
assert hygrostat_result.status == HTTP_UNAUTHORIZED
|
||||||
|
|
||||||
|
|
||||||
async def test_put_light_state_media_player(hass_hue, hue_client):
|
async def test_put_light_state_media_player(hass_hue, hue_client):
|
||||||
"""Test turning on media player and setting volume."""
|
"""Test turning on media player and setting volume."""
|
||||||
# Turn the music player off first
|
# Turn the music player off first
|
||||||
|
Loading…
x
Reference in New Issue
Block a user