From b2efcb3c22c55770ed2c8cd032d30ea3c1822e88 Mon Sep 17 00:00:00 2001 From: starkillerOG Date: Mon, 15 Mar 2021 12:15:34 +0100 Subject: [PATCH] Support all Xiaomi Miio gateway switches (#46657) * Support all gateway switches * fix checks * process revieuw * Update homeassistant/components/xiaomi_miio/switch.py Co-authored-by: Martin Hjelmare * generilize variable matching * fix styling Co-authored-by: Martin Hjelmare --- .../components/xiaomi_miio/__init__.py | 2 +- .../components/xiaomi_miio/sensor.py | 5 ++ .../components/xiaomi_miio/switch.py | 68 ++++++++++++++++++- 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/xiaomi_miio/__init__.py b/homeassistant/components/xiaomi_miio/__init__.py index e426322e5dc..e194225409a 100644 --- a/homeassistant/components/xiaomi_miio/__init__.py +++ b/homeassistant/components/xiaomi_miio/__init__.py @@ -26,7 +26,7 @@ from .gateway import ConnectXiaomiGateway _LOGGER = logging.getLogger(__name__) -GATEWAY_PLATFORMS = ["alarm_control_panel", "sensor", "switch", "light"] +GATEWAY_PLATFORMS = ["alarm_control_panel", "light", "sensor", "switch"] SWITCH_PLATFORMS = ["switch"] FAN_PLATFORMS = ["fan"] LIGHT_PLATFORMS = ["light"] diff --git a/homeassistant/components/xiaomi_miio/sensor.py b/homeassistant/components/xiaomi_miio/sensor.py index cdb38ba9515..e2b645a10ea 100644 --- a/homeassistant/components/xiaomi_miio/sensor.py +++ b/homeassistant/components/xiaomi_miio/sensor.py @@ -21,9 +21,11 @@ from homeassistant.const import ( CONF_TOKEN, DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_ILLUMINANCE, + DEVICE_CLASS_POWER, DEVICE_CLASS_PRESSURE, DEVICE_CLASS_TEMPERATURE, PERCENTAGE, + POWER_WATT, PRESSURE_HPA, TEMP_CELSIUS, ) @@ -77,6 +79,9 @@ GATEWAY_SENSOR_TYPES = { "pressure": SensorType( unit=PRESSURE_HPA, icon=None, device_class=DEVICE_CLASS_PRESSURE ), + "load_power": SensorType( + unit=POWER_WATT, icon=None, device_class=DEVICE_CLASS_POWER + ), } diff --git a/homeassistant/components/xiaomi_miio/switch.py b/homeassistant/components/xiaomi_miio/switch.py index fd75e9f0088..adb18b0de5a 100644 --- a/homeassistant/components/xiaomi_miio/switch.py +++ b/homeassistant/components/xiaomi_miio/switch.py @@ -7,7 +7,11 @@ from miio import AirConditioningCompanionV3, ChuangmiPlug, DeviceException, Powe from miio.powerstrip import PowerMode import voluptuous as vol -from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchEntity +from homeassistant.components.switch import ( + DEVICE_CLASS_SWITCH, + PLATFORM_SCHEMA, + SwitchEntity, +) from homeassistant.config_entries import SOURCE_IMPORT from homeassistant.const import ( ATTR_ENTITY_ID, @@ -25,12 +29,14 @@ from .const import ( CONF_GATEWAY, CONF_MODEL, DOMAIN, + KEY_COORDINATOR, SERVICE_SET_POWER_MODE, SERVICE_SET_POWER_PRICE, SERVICE_SET_WIFI_LED_OFF, SERVICE_SET_WIFI_LED_ON, ) from .device import XiaomiMiioEntity +from .gateway import XiaomiGatewayDevice _LOGGER = logging.getLogger(__name__) @@ -40,6 +46,13 @@ DATA_KEY = "switch.xiaomi_miio" MODEL_POWER_STRIP_V2 = "zimi.powerstrip.v2" MODEL_PLUG_V3 = "chuangmi.plug.v3" +KEY_CHANNEL = "channel" +GATEWAY_SWITCH_VARS = { + "status_ch0": {KEY_CHANNEL: 0}, + "status_ch1": {KEY_CHANNEL: 1}, + "status_ch2": {KEY_CHANNEL: 2}, +} + PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { vol.Required(CONF_HOST): cv.string, @@ -135,6 +148,25 @@ async def async_setup_entry(hass, config_entry, async_add_entities): model = config_entry.data[CONF_MODEL] unique_id = config_entry.unique_id + if config_entry.data[CONF_FLOW_TYPE] == CONF_GATEWAY: + gateway = hass.data[DOMAIN][config_entry.entry_id][CONF_GATEWAY] + # 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 != "Switch": + continue + switch_variables = set(sub_device.status) & set(GATEWAY_SWITCH_VARS) + if switch_variables: + entities.extend( + [ + XiaomiGatewaySwitch( + coordinator, sub_device, config_entry, variable + ) + for variable in switch_variables + ] + ) + if config_entry.data[CONF_FLOW_TYPE] == CONF_DEVICE or ( config_entry.data[CONF_FLOW_TYPE] == CONF_GATEWAY and model == "lumi.acpartner.v3" @@ -227,6 +259,40 @@ async def async_setup_entry(hass, config_entry, async_add_entities): async_add_entities(entities, update_before_add=True) +class XiaomiGatewaySwitch(XiaomiGatewayDevice, SwitchEntity): + """Representation of a XiaomiGatewaySwitch.""" + + def __init__(self, coordinator, sub_device, entry, variable): + """Initialize the XiaomiSensor.""" + super().__init__(coordinator, sub_device, entry) + self._channel = GATEWAY_SWITCH_VARS[variable][KEY_CHANNEL] + self._data_key = f"status_ch{self._channel}" + self._unique_id = f"{sub_device.sid}-ch{self._channel}" + self._name = f"{sub_device.name} ch{self._channel} ({sub_device.sid})" + + @property + def device_class(self): + """Return the device class of this entity.""" + return DEVICE_CLASS_SWITCH + + @property + def is_on(self): + """Return true if switch is on.""" + return self._sub_device.status[self._data_key] == "on" + + async def async_turn_on(self, **kwargs): + """Turn the switch on.""" + await self.hass.async_add_executor_job(self._sub_device.on, self._channel) + + async def async_turn_off(self, **kwargs): + """Turn the switch off.""" + await self.hass.async_add_executor_job(self._sub_device.off, self._channel) + + async def async_toggle(self, **kwargs): + """Toggle the switch.""" + await self.hass.async_add_executor_job(self._sub_device.toggle, self._channel) + + class XiaomiPlugGenericSwitch(XiaomiMiioEntity, SwitchEntity): """Representation of a Xiaomi Plug Generic."""