Add Xiaomi Miio light config flow (#47161)

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
starkillerOG 2021-03-11 14:09:21 +01:00 committed by GitHub
parent b162c45e0a
commit cf4954fead
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 198 additions and 208 deletions

View File

@ -18,6 +18,7 @@ from .const import (
KEY_COORDINATOR, KEY_COORDINATOR,
MODELS_AIR_MONITOR, MODELS_AIR_MONITOR,
MODELS_FAN, MODELS_FAN,
MODELS_LIGHT,
MODELS_SWITCH, MODELS_SWITCH,
MODELS_VACUUM, MODELS_VACUUM,
) )
@ -28,6 +29,7 @@ _LOGGER = logging.getLogger(__name__)
GATEWAY_PLATFORMS = ["alarm_control_panel", "sensor", "switch", "light"] GATEWAY_PLATFORMS = ["alarm_control_panel", "sensor", "switch", "light"]
SWITCH_PLATFORMS = ["switch"] SWITCH_PLATFORMS = ["switch"]
FAN_PLATFORMS = ["fan"] FAN_PLATFORMS = ["fan"]
LIGHT_PLATFORMS = ["light"]
VACUUM_PLATFORMS = ["vacuum"] VACUUM_PLATFORMS = ["vacuum"]
AIR_MONITOR_PLATFORMS = ["air_quality", "sensor"] AIR_MONITOR_PLATFORMS = ["air_quality", "sensor"]
@ -128,6 +130,8 @@ async def async_setup_device_entry(
platforms = SWITCH_PLATFORMS platforms = SWITCH_PLATFORMS
elif model in MODELS_FAN: elif model in MODELS_FAN:
platforms = FAN_PLATFORMS platforms = FAN_PLATFORMS
elif model in MODELS_LIGHT:
platforms = LIGHT_PLATFORMS
for vacuum_model in MODELS_VACUUM: for vacuum_model in MODELS_VACUUM:
if model.startswith(vacuum_model): if model.startswith(vacuum_model):
platforms = VACUUM_PLATFORMS platforms = VACUUM_PLATFORMS

View File

@ -9,7 +9,7 @@ CONF_MAC = "mac"
KEY_COORDINATOR = "coordinator" KEY_COORDINATOR = "coordinator"
# Fam Models # Fan Models
MODEL_AIRPURIFIER_V1 = "zhimi.airpurifier.v1" MODEL_AIRPURIFIER_V1 = "zhimi.airpurifier.v1"
MODEL_AIRPURIFIER_V2 = "zhimi.airpurifier.v2" MODEL_AIRPURIFIER_V2 = "zhimi.airpurifier.v2"
MODEL_AIRPURIFIER_V3 = "zhimi.airpurifier.v3" MODEL_AIRPURIFIER_V3 = "zhimi.airpurifier.v3"
@ -60,6 +60,18 @@ MODEL_AIRQUALITYMONITOR_V1 = "zhimi.airmonitor.v1"
MODEL_AIRQUALITYMONITOR_B1 = "cgllc.airmonitor.b1" MODEL_AIRQUALITYMONITOR_B1 = "cgllc.airmonitor.b1"
MODEL_AIRQUALITYMONITOR_S1 = "cgllc.airmonitor.s1" MODEL_AIRQUALITYMONITOR_S1 = "cgllc.airmonitor.s1"
# Light Models
MODELS_LIGHT_EYECARE = ["philips.light.sread1"]
MODELS_LIGHT_CEILING = ["philips.light.ceiling", "philips.light.zyceiling"]
MODELS_LIGHT_MOON = ["philips.light.moonlight"]
MODELS_LIGHT_BULB = [
"philips.light.bulb",
"philips.light.candle",
"philips.light.candle2",
"philips.light.downlight",
]
MODELS_LIGHT_MONO = ["philips.light.mono1"]
# Model lists # Model lists
MODELS_GATEWAY = ["lumi.gateway", "lumi.acpartner"] MODELS_GATEWAY = ["lumi.gateway", "lumi.acpartner"]
MODELS_SWITCH = [ MODELS_SWITCH = [
@ -75,6 +87,13 @@ MODELS_SWITCH = [
"chuangmi.plug.hmi206", "chuangmi.plug.hmi206",
] ]
MODELS_FAN = MODELS_FAN_MIIO + MODELS_HUMIDIFIER_MIOT + MODELS_PURIFIER_MIOT MODELS_FAN = MODELS_FAN_MIIO + MODELS_HUMIDIFIER_MIOT + MODELS_PURIFIER_MIOT
MODELS_LIGHT = (
MODELS_LIGHT_EYECARE
+ MODELS_LIGHT_CEILING
+ MODELS_LIGHT_MOON
+ MODELS_LIGHT_BULB
+ MODELS_LIGHT_MONO
)
MODELS_VACUUM = ["roborock.vacuum", "rockrobo.vacuum"] MODELS_VACUUM = ["roborock.vacuum", "rockrobo.vacuum"]
MODELS_AIR_MONITOR = [ MODELS_AIR_MONITOR = [
MODEL_AIRQUALITYMONITOR_V1, MODEL_AIRQUALITYMONITOR_V1,
@ -82,7 +101,9 @@ MODELS_AIR_MONITOR = [
MODEL_AIRQUALITYMONITOR_S1, MODEL_AIRQUALITYMONITOR_S1,
] ]
MODELS_ALL_DEVICES = MODELS_SWITCH + MODELS_VACUUM + MODELS_AIR_MONITOR + MODELS_FAN MODELS_ALL_DEVICES = (
MODELS_SWITCH + MODELS_VACUUM + MODELS_AIR_MONITOR + MODELS_FAN + MODELS_LIGHT
)
MODELS_ALL = MODELS_ALL_DEVICES + MODELS_GATEWAY MODELS_ALL = MODELS_ALL_DEVICES + MODELS_GATEWAY
# Fan Services # Fan Services

View File

@ -6,14 +6,7 @@ from functools import partial
import logging import logging
from math import ceil from math import ceil
from miio import ( from miio import Ceil, DeviceException, PhilipsBulb, PhilipsEyecare, PhilipsMoonlight
Ceil,
Device,
DeviceException,
PhilipsBulb,
PhilipsEyecare,
PhilipsMoonlight,
)
from miio.gateway import ( from miio.gateway import (
GATEWAY_MODEL_AC_V1, GATEWAY_MODEL_AC_V1,
GATEWAY_MODEL_AC_V2, GATEWAY_MODEL_AC_V2,
@ -32,15 +25,23 @@ from homeassistant.components.light import (
SUPPORT_COLOR_TEMP, SUPPORT_COLOR_TEMP,
LightEntity, LightEntity,
) )
from homeassistant.config_entries import SOURCE_IMPORT
from homeassistant.const import ATTR_ENTITY_ID, CONF_HOST, CONF_NAME, CONF_TOKEN from homeassistant.const import ATTR_ENTITY_ID, CONF_HOST, CONF_NAME, CONF_TOKEN
from homeassistant.exceptions import PlatformNotReady
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.util import color, dt from homeassistant.util import color, dt
from .const import ( from .const import (
CONF_DEVICE,
CONF_FLOW_TYPE, CONF_FLOW_TYPE,
CONF_GATEWAY, CONF_GATEWAY,
CONF_MODEL,
DOMAIN, DOMAIN,
MODELS_LIGHT,
MODELS_LIGHT_BULB,
MODELS_LIGHT_CEILING,
MODELS_LIGHT_EYECARE,
MODELS_LIGHT_MONO,
MODELS_LIGHT_MOON,
SERVICE_EYECARE_MODE_OFF, SERVICE_EYECARE_MODE_OFF,
SERVICE_EYECARE_MODE_ON, SERVICE_EYECARE_MODE_ON,
SERVICE_NIGHT_LIGHT_MODE_OFF, SERVICE_NIGHT_LIGHT_MODE_OFF,
@ -50,32 +51,19 @@ from .const import (
SERVICE_SET_DELAYED_TURN_OFF, SERVICE_SET_DELAYED_TURN_OFF,
SERVICE_SET_SCENE, SERVICE_SET_SCENE,
) )
from .device import XiaomiMiioEntity
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
DEFAULT_NAME = "Xiaomi Philips Light" DEFAULT_NAME = "Xiaomi Philips Light"
DATA_KEY = "light.xiaomi_miio" DATA_KEY = "light.xiaomi_miio"
CONF_MODEL = "model"
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{ {
vol.Required(CONF_HOST): cv.string, vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_TOKEN): vol.All(cv.string, vol.Length(min=32, max=32)), vol.Required(CONF_TOKEN): vol.All(cv.string, vol.Length(min=32, max=32)),
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_MODEL): vol.In( vol.Optional(CONF_MODEL): vol.In(MODELS_LIGHT),
[
"philips.light.sread1",
"philips.light.ceiling",
"philips.light.zyceiling",
"philips.light.moonlight",
"philips.light.bulb",
"philips.light.candle",
"philips.light.candle2",
"philips.light.mono1",
"philips.light.downlight",
]
),
} }
) )
@ -87,7 +75,6 @@ DELAYED_TURN_OFF_MAX_DEVIATION_SECONDS = 4
DELAYED_TURN_OFF_MAX_DEVIATION_MINUTES = 1 DELAYED_TURN_OFF_MAX_DEVIATION_MINUTES = 1
SUCCESS = ["ok"] SUCCESS = ["ok"]
ATTR_MODEL = "model"
ATTR_SCENE = "scene" ATTR_SCENE = "scene"
ATTR_DELAYED_TURN_OFF = "delayed_turn_off" ATTR_DELAYED_TURN_OFF = "delayed_turn_off"
ATTR_TIME_PERIOD = "time_period" ATTR_TIME_PERIOD = "time_period"
@ -100,8 +87,8 @@ ATTR_EYECARE_MODE = "eyecare_mode"
ATTR_SLEEP_ASSISTANT = "sleep_assistant" ATTR_SLEEP_ASSISTANT = "sleep_assistant"
ATTR_SLEEP_OFF_TIME = "sleep_off_time" ATTR_SLEEP_OFF_TIME = "sleep_off_time"
ATTR_TOTAL_ASSISTANT_SLEEP_TIME = "total_assistant_sleep_time" ATTR_TOTAL_ASSISTANT_SLEEP_TIME = "total_assistant_sleep_time"
ATTR_BRAND_SLEEP = "brand_sleep" ATTR_BAND_SLEEP = "band_sleep"
ATTR_BRAND = "brand" ATTR_BAND = "band"
XIAOMI_MIIO_SERVICE_SCHEMA = vol.Schema({vol.Optional(ATTR_ENTITY_ID): cv.entity_ids}) XIAOMI_MIIO_SERVICE_SCHEMA = vol.Schema({vol.Optional(ATTR_ENTITY_ID): cv.entity_ids})
@ -131,6 +118,21 @@ SERVICE_TO_METHOD = {
} }
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Import Miio configuration from YAML."""
_LOGGER.warning(
"Loading Xiaomi Miio Light via platform setup is deprecated. "
"Please remove it from your configuration"
)
hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_IMPORT},
data=config,
)
)
async def async_setup_entry(hass, config_entry, async_add_entities): async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up the Xiaomi light from a config entry.""" """Set up the Xiaomi light from a config entry."""
entities = [] entities = []
@ -147,76 +149,51 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
XiaomiGatewayLight(gateway, config_entry.title, config_entry.unique_id) XiaomiGatewayLight(gateway, config_entry.title, config_entry.unique_id)
) )
async_add_entities(entities, update_before_add=True) if config_entry.data[CONF_FLOW_TYPE] == CONF_DEVICE:
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up the light from config."""
if DATA_KEY not in hass.data: if DATA_KEY not in hass.data:
hass.data[DATA_KEY] = {} hass.data[DATA_KEY] = {}
host = config[CONF_HOST] host = config_entry.data[CONF_HOST]
token = config[CONF_TOKEN] token = config_entry.data[CONF_TOKEN]
name = config[CONF_NAME] name = config_entry.title
model = config.get(CONF_MODEL) model = config_entry.data[CONF_MODEL]
unique_id = config_entry.unique_id
_LOGGER.info("Initializing with host %s (token %s...)", host, token[:5]) _LOGGER.debug("Initializing with host %s (token %s...)", host, token[:5])
devices = [] if model in MODELS_LIGHT_EYECARE:
unique_id = None
if model is None:
try:
miio_device = Device(host, token)
device_info = await hass.async_add_executor_job(miio_device.info)
model = device_info.model
unique_id = f"{model}-{device_info.mac_address}"
_LOGGER.info(
"%s %s %s detected",
model,
device_info.firmware_version,
device_info.hardware_version,
)
except DeviceException as ex:
raise PlatformNotReady from ex
if model == "philips.light.sread1":
light = PhilipsEyecare(host, token) light = PhilipsEyecare(host, token)
primary_device = XiaomiPhilipsEyecareLamp(name, light, model, unique_id) entity = XiaomiPhilipsEyecareLamp(name, light, config_entry, unique_id)
devices.append(primary_device) entities.append(entity)
hass.data[DATA_KEY][host] = primary_device hass.data[DATA_KEY][host] = entity
secondary_device = XiaomiPhilipsEyecareLampAmbientLight( entities.append(
name, light, model, unique_id XiaomiPhilipsEyecareLampAmbientLight(
name, light, config_entry, unique_id
)
) )
devices.append(secondary_device)
# The ambient light doesn't expose additional services. # The ambient light doesn't expose additional services.
# A hass.data[DATA_KEY] entry isn't needed. # A hass.data[DATA_KEY] entry isn't needed.
elif model in ["philips.light.ceiling", "philips.light.zyceiling"]: elif model in MODELS_LIGHT_CEILING:
light = Ceil(host, token) light = Ceil(host, token)
device = XiaomiPhilipsCeilingLamp(name, light, model, unique_id) entity = XiaomiPhilipsCeilingLamp(name, light, config_entry, unique_id)
devices.append(device) entities.append(entity)
hass.data[DATA_KEY][host] = device hass.data[DATA_KEY][host] = entity
elif model == "philips.light.moonlight": elif model in MODELS_LIGHT_MOON:
light = PhilipsMoonlight(host, token) light = PhilipsMoonlight(host, token)
device = XiaomiPhilipsMoonlightLamp(name, light, model, unique_id) entity = XiaomiPhilipsMoonlightLamp(name, light, config_entry, unique_id)
devices.append(device) entities.append(entity)
hass.data[DATA_KEY][host] = device hass.data[DATA_KEY][host] = entity
elif model in [ elif model in MODELS_LIGHT_BULB:
"philips.light.bulb",
"philips.light.candle",
"philips.light.candle2",
"philips.light.downlight",
]:
light = PhilipsBulb(host, token) light = PhilipsBulb(host, token)
device = XiaomiPhilipsBulb(name, light, model, unique_id) entity = XiaomiPhilipsBulb(name, light, config_entry, unique_id)
devices.append(device) entities.append(entity)
hass.data[DATA_KEY][host] = device hass.data[DATA_KEY][host] = entity
elif model == "philips.light.mono1": elif model in MODELS_LIGHT_MONO:
light = PhilipsBulb(host, token) light = PhilipsBulb(host, token)
device = XiaomiPhilipsGenericLight(name, light, model, unique_id) entity = XiaomiPhilipsGenericLight(name, light, config_entry, unique_id)
devices.append(device) entities.append(entity)
hass.data[DATA_KEY][host] = device hass.data[DATA_KEY][host] = entity
else: else:
_LOGGER.error( _LOGGER.error(
"Unsupported device found! Please create an issue at " "Unsupported device found! Please create an issue at "
@ -224,15 +201,15 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
"and provide the following data: %s", "and provide the following data: %s",
model, model,
) )
return False return
async_add_entities(devices, update_before_add=True)
async def async_service_handler(service): async def async_service_handler(service):
"""Map services to methods on Xiaomi Philips Lights.""" """Map services to methods on Xiaomi Philips Lights."""
method = SERVICE_TO_METHOD.get(service.service) method = SERVICE_TO_METHOD.get(service.service)
params = { params = {
key: value for key, value in service.data.items() if key != ATTR_ENTITY_ID key: value
for key, value in service.data.items()
if key != ATTR_ENTITY_ID
} }
entity_ids = service.data.get(ATTR_ENTITY_ID) entity_ids = service.data.get(ATTR_ENTITY_ID)
if entity_ids: if entity_ids:
@ -262,32 +239,20 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
DOMAIN, xiaomi_miio_service, async_service_handler, schema=schema DOMAIN, xiaomi_miio_service, async_service_handler, schema=schema
) )
async_add_entities(entities, update_before_add=True)
class XiaomiPhilipsAbstractLight(LightEntity):
class XiaomiPhilipsAbstractLight(XiaomiMiioEntity, LightEntity):
"""Representation of a Abstract Xiaomi Philips Light.""" """Representation of a Abstract Xiaomi Philips Light."""
def __init__(self, name, light, model, unique_id): def __init__(self, name, device, entry, unique_id):
"""Initialize the light device.""" """Initialize the light device."""
self._name = name super().__init__(name, device, entry, unique_id)
self._light = light
self._model = model
self._unique_id = unique_id
self._brightness = None self._brightness = None
self._available = False self._available = False
self._state = None self._state = None
self._state_attrs = {ATTR_MODEL: self._model} self._state_attrs = {}
@property
def unique_id(self):
"""Return an unique ID."""
return self._unique_id
@property
def name(self):
"""Return the name of the device if any."""
return self._name
@property @property
def available(self): def available(self):
@ -341,23 +306,23 @@ class XiaomiPhilipsAbstractLight(LightEntity):
result = await self._try_command( result = await self._try_command(
"Setting brightness failed: %s", "Setting brightness failed: %s",
self._light.set_brightness, self._device.set_brightness,
percent_brightness, percent_brightness,
) )
if result: if result:
self._brightness = brightness self._brightness = brightness
else: else:
await self._try_command("Turning the light on failed.", self._light.on) await self._try_command("Turning the light on failed.", self._device.on)
async def async_turn_off(self, **kwargs): async def async_turn_off(self, **kwargs):
"""Turn the light off.""" """Turn the light off."""
await self._try_command("Turning the light off failed.", self._light.off) await self._try_command("Turning the light off failed.", self._device.off)
async def async_update(self): async def async_update(self):
"""Fetch state from the device.""" """Fetch state from the device."""
try: try:
state = await self.hass.async_add_executor_job(self._light.status) state = await self.hass.async_add_executor_job(self._device.status)
except DeviceException as ex: except DeviceException as ex:
if self._available: if self._available:
self._available = False self._available = False
@ -374,16 +339,16 @@ class XiaomiPhilipsAbstractLight(LightEntity):
class XiaomiPhilipsGenericLight(XiaomiPhilipsAbstractLight): class XiaomiPhilipsGenericLight(XiaomiPhilipsAbstractLight):
"""Representation of a Generic Xiaomi Philips Light.""" """Representation of a Generic Xiaomi Philips Light."""
def __init__(self, name, light, model, unique_id): def __init__(self, name, device, entry, unique_id):
"""Initialize the light device.""" """Initialize the light device."""
super().__init__(name, light, model, unique_id) super().__init__(name, device, entry, unique_id)
self._state_attrs.update({ATTR_SCENE: None, ATTR_DELAYED_TURN_OFF: None}) self._state_attrs.update({ATTR_SCENE: None, ATTR_DELAYED_TURN_OFF: None})
async def async_update(self): async def async_update(self):
"""Fetch state from the device.""" """Fetch state from the device."""
try: try:
state = await self.hass.async_add_executor_job(self._light.status) state = await self.hass.async_add_executor_job(self._device.status)
except DeviceException as ex: except DeviceException as ex:
if self._available: if self._available:
self._available = False self._available = False
@ -409,14 +374,14 @@ class XiaomiPhilipsGenericLight(XiaomiPhilipsAbstractLight):
async def async_set_scene(self, scene: int = 1): async def async_set_scene(self, scene: int = 1):
"""Set the fixed scene.""" """Set the fixed scene."""
await self._try_command( await self._try_command(
"Setting a fixed scene failed.", self._light.set_scene, scene "Setting a fixed scene failed.", self._device.set_scene, scene
) )
async def async_set_delayed_turn_off(self, time_period: timedelta): async def async_set_delayed_turn_off(self, time_period: timedelta):
"""Set delayed turn off.""" """Set delayed turn off."""
await self._try_command( await self._try_command(
"Setting the turn off delay failed.", "Setting the turn off delay failed.",
self._light.delay_off, self._device.delay_off,
time_period.total_seconds(), time_period.total_seconds(),
) )
@ -445,9 +410,9 @@ class XiaomiPhilipsGenericLight(XiaomiPhilipsAbstractLight):
class XiaomiPhilipsBulb(XiaomiPhilipsGenericLight): class XiaomiPhilipsBulb(XiaomiPhilipsGenericLight):
"""Representation of a Xiaomi Philips Bulb.""" """Representation of a Xiaomi Philips Bulb."""
def __init__(self, name, light, model, unique_id): def __init__(self, name, device, entry, unique_id):
"""Initialize the light device.""" """Initialize the light device."""
super().__init__(name, light, model, unique_id) super().__init__(name, device, entry, unique_id)
self._color_temp = None self._color_temp = None
@ -495,7 +460,7 @@ class XiaomiPhilipsBulb(XiaomiPhilipsGenericLight):
result = await self._try_command( result = await self._try_command(
"Setting brightness and color temperature failed: %s bri, %s cct", "Setting brightness and color temperature failed: %s bri, %s cct",
self._light.set_brightness_and_color_temperature, self._device.set_brightness_and_color_temperature,
percent_brightness, percent_brightness,
percent_color_temp, percent_color_temp,
) )
@ -513,7 +478,7 @@ class XiaomiPhilipsBulb(XiaomiPhilipsGenericLight):
result = await self._try_command( result = await self._try_command(
"Setting color temperature failed: %s cct", "Setting color temperature failed: %s cct",
self._light.set_color_temperature, self._device.set_color_temperature,
percent_color_temp, percent_color_temp,
) )
@ -528,7 +493,7 @@ class XiaomiPhilipsBulb(XiaomiPhilipsGenericLight):
result = await self._try_command( result = await self._try_command(
"Setting brightness failed: %s", "Setting brightness failed: %s",
self._light.set_brightness, self._device.set_brightness,
percent_brightness, percent_brightness,
) )
@ -536,12 +501,12 @@ class XiaomiPhilipsBulb(XiaomiPhilipsGenericLight):
self._brightness = brightness self._brightness = brightness
else: else:
await self._try_command("Turning the light on failed.", self._light.on) await self._try_command("Turning the light on failed.", self._device.on)
async def async_update(self): async def async_update(self):
"""Fetch state from the device.""" """Fetch state from the device."""
try: try:
state = await self.hass.async_add_executor_job(self._light.status) state = await self.hass.async_add_executor_job(self._device.status)
except DeviceException as ex: except DeviceException as ex:
if self._available: if self._available:
self._available = False self._available = False
@ -579,9 +544,9 @@ class XiaomiPhilipsBulb(XiaomiPhilipsGenericLight):
class XiaomiPhilipsCeilingLamp(XiaomiPhilipsBulb): class XiaomiPhilipsCeilingLamp(XiaomiPhilipsBulb):
"""Representation of a Xiaomi Philips Ceiling Lamp.""" """Representation of a Xiaomi Philips Ceiling Lamp."""
def __init__(self, name, light, model, unique_id): def __init__(self, name, device, entry, unique_id):
"""Initialize the light device.""" """Initialize the light device."""
super().__init__(name, light, model, unique_id) super().__init__(name, device, entry, unique_id)
self._state_attrs.update( self._state_attrs.update(
{ATTR_NIGHT_LIGHT_MODE: None, ATTR_AUTOMATIC_COLOR_TEMPERATURE: None} {ATTR_NIGHT_LIGHT_MODE: None, ATTR_AUTOMATIC_COLOR_TEMPERATURE: None}
@ -600,7 +565,7 @@ class XiaomiPhilipsCeilingLamp(XiaomiPhilipsBulb):
async def async_update(self): async def async_update(self):
"""Fetch state from the device.""" """Fetch state from the device."""
try: try:
state = await self.hass.async_add_executor_job(self._light.status) state = await self.hass.async_add_executor_job(self._device.status)
except DeviceException as ex: except DeviceException as ex:
if self._available: if self._available:
self._available = False self._available = False
@ -635,9 +600,9 @@ class XiaomiPhilipsCeilingLamp(XiaomiPhilipsBulb):
class XiaomiPhilipsEyecareLamp(XiaomiPhilipsGenericLight): class XiaomiPhilipsEyecareLamp(XiaomiPhilipsGenericLight):
"""Representation of a Xiaomi Philips Eyecare Lamp 2.""" """Representation of a Xiaomi Philips Eyecare Lamp 2."""
def __init__(self, name, light, model, unique_id): def __init__(self, name, device, entry, unique_id):
"""Initialize the light device.""" """Initialize the light device."""
super().__init__(name, light, model, unique_id) super().__init__(name, device, entry, unique_id)
self._state_attrs.update( self._state_attrs.update(
{ATTR_REMINDER: None, ATTR_NIGHT_LIGHT_MODE: None, ATTR_EYECARE_MODE: None} {ATTR_REMINDER: None, ATTR_NIGHT_LIGHT_MODE: None, ATTR_EYECARE_MODE: None}
@ -646,7 +611,7 @@ class XiaomiPhilipsEyecareLamp(XiaomiPhilipsGenericLight):
async def async_update(self): async def async_update(self):
"""Fetch state from the device.""" """Fetch state from the device."""
try: try:
state = await self.hass.async_add_executor_job(self._light.status) state = await self.hass.async_add_executor_job(self._device.status)
except DeviceException as ex: except DeviceException as ex:
if self._available: if self._available:
self._available = False self._available = False
@ -679,46 +644,46 @@ class XiaomiPhilipsEyecareLamp(XiaomiPhilipsGenericLight):
"""Set delayed turn off.""" """Set delayed turn off."""
await self._try_command( await self._try_command(
"Setting the turn off delay failed.", "Setting the turn off delay failed.",
self._light.delay_off, self._device.delay_off,
round(time_period.total_seconds() / 60), round(time_period.total_seconds() / 60),
) )
async def async_reminder_on(self): async def async_reminder_on(self):
"""Enable the eye fatigue notification.""" """Enable the eye fatigue notification."""
await self._try_command( await self._try_command(
"Turning on the reminder failed.", self._light.reminder_on "Turning on the reminder failed.", self._device.reminder_on
) )
async def async_reminder_off(self): async def async_reminder_off(self):
"""Disable the eye fatigue notification.""" """Disable the eye fatigue notification."""
await self._try_command( await self._try_command(
"Turning off the reminder failed.", self._light.reminder_off "Turning off the reminder failed.", self._device.reminder_off
) )
async def async_night_light_mode_on(self): async def async_night_light_mode_on(self):
"""Turn the smart night light mode on.""" """Turn the smart night light mode on."""
await self._try_command( await self._try_command(
"Turning on the smart night light mode failed.", "Turning on the smart night light mode failed.",
self._light.smart_night_light_on, self._device.smart_night_light_on,
) )
async def async_night_light_mode_off(self): async def async_night_light_mode_off(self):
"""Turn the smart night light mode off.""" """Turn the smart night light mode off."""
await self._try_command( await self._try_command(
"Turning off the smart night light mode failed.", "Turning off the smart night light mode failed.",
self._light.smart_night_light_off, self._device.smart_night_light_off,
) )
async def async_eyecare_mode_on(self): async def async_eyecare_mode_on(self):
"""Turn the eyecare mode on.""" """Turn the eyecare mode on."""
await self._try_command( await self._try_command(
"Turning on the eyecare mode failed.", self._light.eyecare_on "Turning on the eyecare mode failed.", self._device.eyecare_on
) )
async def async_eyecare_mode_off(self): async def async_eyecare_mode_off(self):
"""Turn the eyecare mode off.""" """Turn the eyecare mode off."""
await self._try_command( await self._try_command(
"Turning off the eyecare mode failed.", self._light.eyecare_off "Turning off the eyecare mode failed.", self._device.eyecare_off
) )
@staticmethod @staticmethod
@ -748,12 +713,12 @@ class XiaomiPhilipsEyecareLamp(XiaomiPhilipsGenericLight):
class XiaomiPhilipsEyecareLampAmbientLight(XiaomiPhilipsAbstractLight): class XiaomiPhilipsEyecareLampAmbientLight(XiaomiPhilipsAbstractLight):
"""Representation of a Xiaomi Philips Eyecare Lamp Ambient Light.""" """Representation of a Xiaomi Philips Eyecare Lamp Ambient Light."""
def __init__(self, name, light, model, unique_id): def __init__(self, name, device, entry, unique_id):
"""Initialize the light device.""" """Initialize the light device."""
name = f"{name} Ambient Light" name = f"{name} Ambient Light"
if unique_id is not None: if unique_id is not None:
unique_id = f"{unique_id}-ambient" unique_id = f"{unique_id}-ambient"
super().__init__(name, light, model, unique_id) super().__init__(name, device, entry, unique_id)
async def async_turn_on(self, **kwargs): async def async_turn_on(self, **kwargs):
"""Turn the light on.""" """Turn the light on."""
@ -769,7 +734,7 @@ class XiaomiPhilipsEyecareLampAmbientLight(XiaomiPhilipsAbstractLight):
result = await self._try_command( result = await self._try_command(
"Setting brightness of the ambient failed: %s", "Setting brightness of the ambient failed: %s",
self._light.set_ambient_brightness, self._device.set_ambient_brightness,
percent_brightness, percent_brightness,
) )
@ -777,19 +742,19 @@ class XiaomiPhilipsEyecareLampAmbientLight(XiaomiPhilipsAbstractLight):
self._brightness = brightness self._brightness = brightness
else: else:
await self._try_command( await self._try_command(
"Turning the ambient light on failed.", self._light.ambient_on "Turning the ambient light on failed.", self._device.ambient_on
) )
async def async_turn_off(self, **kwargs): async def async_turn_off(self, **kwargs):
"""Turn the light off.""" """Turn the light off."""
await self._try_command( await self._try_command(
"Turning the ambient light off failed.", self._light.ambient_off "Turning the ambient light off failed.", self._device.ambient_off
) )
async def async_update(self): async def async_update(self):
"""Fetch state from the device.""" """Fetch state from the device."""
try: try:
state = await self.hass.async_add_executor_job(self._light.status) state = await self.hass.async_add_executor_job(self._device.status)
except DeviceException as ex: except DeviceException as ex:
if self._available: if self._available:
self._available = False self._available = False
@ -806,9 +771,9 @@ class XiaomiPhilipsEyecareLampAmbientLight(XiaomiPhilipsAbstractLight):
class XiaomiPhilipsMoonlightLamp(XiaomiPhilipsBulb): class XiaomiPhilipsMoonlightLamp(XiaomiPhilipsBulb):
"""Representation of a Xiaomi Philips Zhirui Bedside Lamp.""" """Representation of a Xiaomi Philips Zhirui Bedside Lamp."""
def __init__(self, name, light, model, unique_id): def __init__(self, name, device, entry, unique_id):
"""Initialize the light device.""" """Initialize the light device."""
super().__init__(name, light, model, unique_id) super().__init__(name, device, entry, unique_id)
self._hs_color = None self._hs_color = None
self._state_attrs.pop(ATTR_DELAYED_TURN_OFF) self._state_attrs.pop(ATTR_DELAYED_TURN_OFF)
@ -817,8 +782,8 @@ class XiaomiPhilipsMoonlightLamp(XiaomiPhilipsBulb):
ATTR_SLEEP_ASSISTANT: None, ATTR_SLEEP_ASSISTANT: None,
ATTR_SLEEP_OFF_TIME: None, ATTR_SLEEP_OFF_TIME: None,
ATTR_TOTAL_ASSISTANT_SLEEP_TIME: None, ATTR_TOTAL_ASSISTANT_SLEEP_TIME: None,
ATTR_BRAND_SLEEP: None, ATTR_BAND_SLEEP: None,
ATTR_BRAND: None, ATTR_BAND: None,
} }
) )
@ -868,7 +833,7 @@ class XiaomiPhilipsMoonlightLamp(XiaomiPhilipsBulb):
result = await self._try_command( result = await self._try_command(
"Setting brightness and color failed: %s bri, %s color", "Setting brightness and color failed: %s bri, %s color",
self._light.set_brightness_and_rgb, self._device.set_brightness_and_rgb,
percent_brightness, percent_brightness,
rgb, rgb,
) )
@ -889,7 +854,7 @@ class XiaomiPhilipsMoonlightLamp(XiaomiPhilipsBulb):
result = await self._try_command( result = await self._try_command(
"Setting brightness and color temperature failed: %s bri, %s cct", "Setting brightness and color temperature failed: %s bri, %s cct",
self._light.set_brightness_and_color_temperature, self._device.set_brightness_and_color_temperature,
percent_brightness, percent_brightness,
percent_color_temp, percent_color_temp,
) )
@ -902,7 +867,7 @@ class XiaomiPhilipsMoonlightLamp(XiaomiPhilipsBulb):
_LOGGER.debug("Setting color: %s", rgb) _LOGGER.debug("Setting color: %s", rgb)
result = await self._try_command( result = await self._try_command(
"Setting color failed: %s", self._light.set_rgb, rgb "Setting color failed: %s", self._device.set_rgb, rgb
) )
if result: if result:
@ -917,7 +882,7 @@ class XiaomiPhilipsMoonlightLamp(XiaomiPhilipsBulb):
result = await self._try_command( result = await self._try_command(
"Setting color temperature failed: %s cct", "Setting color temperature failed: %s cct",
self._light.set_color_temperature, self._device.set_color_temperature,
percent_color_temp, percent_color_temp,
) )
@ -932,7 +897,7 @@ class XiaomiPhilipsMoonlightLamp(XiaomiPhilipsBulb):
result = await self._try_command( result = await self._try_command(
"Setting brightness failed: %s", "Setting brightness failed: %s",
self._light.set_brightness, self._device.set_brightness,
percent_brightness, percent_brightness,
) )
@ -940,12 +905,12 @@ class XiaomiPhilipsMoonlightLamp(XiaomiPhilipsBulb):
self._brightness = brightness self._brightness = brightness
else: else:
await self._try_command("Turning the light on failed.", self._light.on) await self._try_command("Turning the light on failed.", self._device.on)
async def async_update(self): async def async_update(self):
"""Fetch state from the device.""" """Fetch state from the device."""
try: try:
state = await self.hass.async_add_executor_job(self._light.status) state = await self.hass.async_add_executor_job(self._device.status)
except DeviceException as ex: except DeviceException as ex:
if self._available: if self._available:
self._available = False self._available = False
@ -968,8 +933,8 @@ class XiaomiPhilipsMoonlightLamp(XiaomiPhilipsBulb):
ATTR_SLEEP_ASSISTANT: state.sleep_assistant, ATTR_SLEEP_ASSISTANT: state.sleep_assistant,
ATTR_SLEEP_OFF_TIME: state.sleep_off_time, ATTR_SLEEP_OFF_TIME: state.sleep_off_time,
ATTR_TOTAL_ASSISTANT_SLEEP_TIME: state.total_assistant_sleep_time, ATTR_TOTAL_ASSISTANT_SLEEP_TIME: state.total_assistant_sleep_time,
ATTR_BRAND_SLEEP: state.brand_sleep, ATTR_BAND_SLEEP: state.brand_sleep,
ATTR_BRAND: state.brand, ATTR_BAND: state.brand,
} }
) )