From 50b5fc486082d101f0c40ca06bdc0522716af2c3 Mon Sep 17 00:00:00 2001 From: starkillerOG Date: Sun, 14 Mar 2021 12:32:19 +0100 Subject: [PATCH] Add Xiaomi Miio subdevice lightbulb support (#46660) * Xiaomi Miio: add subdevice lightbulb support * fix tests * process revieuw comments * bump python-miio to 0.5.5 * bump python-miio to 0.5.5 * fix imports --- .../components/xiaomi_miio/__init__.py | 2 +- homeassistant/components/xiaomi_miio/light.py | 66 ++++++++++++++++++- .../components/xiaomi_miio/manifest.json | 2 +- .../components/xiaomi_miio/sensor.py | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 6 files changed, 70 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/xiaomi_miio/__init__.py b/homeassistant/components/xiaomi_miio/__init__.py index 069520ada7d..e426322e5dc 100644 --- a/homeassistant/components/xiaomi_miio/__init__.py +++ b/homeassistant/components/xiaomi_miio/__init__.py @@ -2,7 +2,7 @@ from datetime import timedelta import logging -from miio.gateway import GatewayException +from miio.gateway.gateway import GatewayException from homeassistant import config_entries, core from homeassistant.const import CONF_HOST, CONF_TOKEN diff --git a/homeassistant/components/xiaomi_miio/light.py b/homeassistant/components/xiaomi_miio/light.py index c6d8b67bb07..f6cd468ad00 100644 --- a/homeassistant/components/xiaomi_miio/light.py +++ b/homeassistant/components/xiaomi_miio/light.py @@ -7,7 +7,7 @@ import logging from math import ceil from miio import Ceil, DeviceException, PhilipsBulb, PhilipsEyecare, PhilipsMoonlight -from miio.gateway import ( +from miio.gateway.gateway import ( GATEWAY_MODEL_AC_V1, GATEWAY_MODEL_AC_V2, GATEWAY_MODEL_AC_V3, @@ -36,6 +36,7 @@ from .const import ( CONF_GATEWAY, CONF_MODEL, DOMAIN, + KEY_COORDINATOR, MODELS_LIGHT, MODELS_LIGHT_BULB, MODELS_LIGHT_CEILING, @@ -52,6 +53,7 @@ from .const import ( SERVICE_SET_SCENE, ) from .device import XiaomiMiioEntity +from .gateway import XiaomiGatewayDevice _LOGGER = logging.getLogger(__name__) @@ -148,6 +150,14 @@ async def async_setup_entry(hass, config_entry, async_add_entities): entities.append( XiaomiGatewayLight(gateway, config_entry.title, config_entry.unique_id) ) + # Gateway sub devices + sub_devices = gateway.devices + coordinator = hass.data[DOMAIN][config_entry.entry_id][KEY_COORDINATOR] + for sub_device in sub_devices.values(): + if sub_device.device_type == "LightBulb": + entities.append( + XiaomiGatewayBulb(coordinator, sub_device, config_entry) + ) if config_entry.data[CONF_FLOW_TYPE] == CONF_DEVICE: if DATA_KEY not in hass.data: @@ -1042,3 +1052,57 @@ class XiaomiGatewayLight(LightEntity): self._brightness_pct = state_dict["brightness"] self._rgb = state_dict["rgb"] self._hs = color.color_RGB_to_hs(*self._rgb) + + +class XiaomiGatewayBulb(XiaomiGatewayDevice, LightEntity): + """Representation of Xiaomi Gateway Bulb.""" + + @property + def brightness(self): + """Return the brightness of the light.""" + return round((self._sub_device.status["brightness"] * 255) / 100) + + @property + def color_temp(self): + """Return current color temperature.""" + return self._sub_device.status["color_temp"] + + @property + def is_on(self): + """Return true if light is on.""" + return self._sub_device.status["status"] == "on" + + @property + def min_mireds(self): + """Return min cct.""" + return self._sub_device.status["cct_min"] + + @property + def max_mireds(self): + """Return max cct.""" + return self._sub_device.status["cct_max"] + + @property + def supported_features(self): + """Return the supported features.""" + return SUPPORT_BRIGHTNESS | SUPPORT_COLOR_TEMP + + async def async_turn_on(self, **kwargs): + """Instruct the light to turn on.""" + await self.hass.async_add_executor_job(self._sub_device.on) + + if ATTR_COLOR_TEMP in kwargs: + color_temp = kwargs[ATTR_COLOR_TEMP] + await self.hass.async_add_executor_job( + self._sub_device.set_color_temp, color_temp + ) + + if ATTR_BRIGHTNESS in kwargs: + brightness = round((kwargs[ATTR_BRIGHTNESS] * 100) / 255) + await self.hass.async_add_executor_job( + self._sub_device.set_brightness, brightness + ) + + async def async_turn_off(self, **kwargsf): + """Instruct the light to turn off.""" + await self.hass.async_add_executor_job(self._sub_device.off) diff --git a/homeassistant/components/xiaomi_miio/manifest.json b/homeassistant/components/xiaomi_miio/manifest.json index 2536b0e0aa7..6f8069be681 100644 --- a/homeassistant/components/xiaomi_miio/manifest.json +++ b/homeassistant/components/xiaomi_miio/manifest.json @@ -3,7 +3,7 @@ "name": "Xiaomi Miio", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/xiaomi_miio", - "requirements": ["construct==2.10.56", "python-miio==0.5.4"], + "requirements": ["construct==2.10.56", "python-miio==0.5.5"], "codeowners": ["@rytilahti", "@syssi", "@starkillerOG"], "zeroconf": ["_miio._udp.local."] } diff --git a/homeassistant/components/xiaomi_miio/sensor.py b/homeassistant/components/xiaomi_miio/sensor.py index 5769c1fb475..cdb38ba9515 100644 --- a/homeassistant/components/xiaomi_miio/sensor.py +++ b/homeassistant/components/xiaomi_miio/sensor.py @@ -3,7 +3,7 @@ from dataclasses import dataclass import logging from miio import AirQualityMonitor, DeviceException -from miio.gateway import ( +from miio.gateway.gateway import ( GATEWAY_MODEL_AC_V1, GATEWAY_MODEL_AC_V2, GATEWAY_MODEL_AC_V3, diff --git a/requirements_all.txt b/requirements_all.txt index 9840e88a1ca..d37eb5571fc 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1795,7 +1795,7 @@ python-juicenet==1.0.1 # python-lirc==1.2.3 # homeassistant.components.xiaomi_miio -python-miio==0.5.4 +python-miio==0.5.5 # homeassistant.components.mpd python-mpd2==3.0.4 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 60a62290db7..564a3b49e09 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -935,7 +935,7 @@ python-izone==1.1.4 python-juicenet==1.0.1 # homeassistant.components.xiaomi_miio -python-miio==0.5.4 +python-miio==0.5.5 # homeassistant.components.nest python-nest==4.1.0