From 248802efd546a87c2323d15c6aa48f88ff4e6a8d Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Sat, 9 Jan 2021 17:46:53 +0100 Subject: [PATCH] Add MQTT base entity (#44971) --- .../components/mqtt/alarm_control_panel.py | 63 ++-------------- .../components/mqtt/binary_sensor.py | 62 ++------------- homeassistant/components/mqtt/camera.py | 51 ++----------- homeassistant/components/mqtt/climate.py | 61 ++------------- homeassistant/components/mqtt/cover.py | 63 ++-------------- .../mqtt/device_tracker/schema_discovery.py | 58 ++------------ homeassistant/components/mqtt/fan.py | 63 ++-------------- .../components/mqtt/light/schema_basic.py | 64 ++-------------- .../components/mqtt/light/schema_json.py | 63 ++-------------- .../components/mqtt/light/schema_template.py | 66 ++-------------- homeassistant/components/mqtt/lock.py | 63 ++-------------- homeassistant/components/mqtt/mixins.py | 75 ++++++++++++++++++- homeassistant/components/mqtt/number.py | 58 ++------------ homeassistant/components/mqtt/sensor.py | 58 ++------------ homeassistant/components/mqtt/switch.py | 64 ++-------------- .../components/mqtt/vacuum/schema_legacy.py | 64 ++-------------- .../components/mqtt/vacuum/schema_state.py | 59 ++------------- 17 files changed, 190 insertions(+), 865 deletions(-) diff --git a/homeassistant/components/mqtt/alarm_control_panel.py b/homeassistant/components/mqtt/alarm_control_panel.py index 4c06f6af7c3..38fec57607e 100644 --- a/homeassistant/components/mqtt/alarm_control_panel.py +++ b/homeassistant/components/mqtt/alarm_control_panel.py @@ -48,10 +48,7 @@ from .mixins import ( MQTT_AVAILABILITY_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_JSON_ATTRS_SCHEMA, - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, + MqttEntity, async_setup_entry_helper, ) @@ -127,46 +124,19 @@ async def _async_setup_entity( async_add_entities([MqttAlarm(hass, config, config_entry, discovery_data)]) -class MqttAlarm( - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, - alarm.AlarmControlPanelEntity, -): +class MqttAlarm(MqttEntity, alarm.AlarmControlPanelEntity): """Representation of a MQTT alarm status.""" def __init__(self, hass, config, config_entry, discovery_data): """Init the MQTT Alarm Control Panel.""" - self.hass = hass self._state = None - self._unique_id = config.get(CONF_UNIQUE_ID) - self._sub_state = None - # Load config - self._setup_from_config(config) + MqttEntity.__init__(self, hass, config, config_entry, discovery_data) - device_config = config.get(CONF_DEVICE) - - MqttAttributes.__init__(self, config) - MqttAvailability.__init__(self, config) - MqttDiscoveryUpdate.__init__(self, discovery_data, self.discovery_update) - MqttEntityDeviceInfo.__init__(self, device_config, config_entry) - - async def async_added_to_hass(self): - """Subscribe mqtt events.""" - await super().async_added_to_hass() - await self._subscribe_topics() - - async def discovery_update(self, discovery_payload): - """Handle updated discovery message.""" - config = PLATFORM_SCHEMA(discovery_payload) - self._setup_from_config(config) - await self.attributes_discovery_update(config) - await self.availability_discovery_update(config) - await self.device_info_discovery_update(config) - await self._subscribe_topics() - self.async_write_ha_state() + @staticmethod + def config_schema(): + """Return the config schema.""" + return PLATFORM_SCHEMA def _setup_from_config(self, config): self._config = config @@ -217,30 +187,11 @@ class MqttAlarm( }, ) - async def async_will_remove_from_hass(self): - """Unsubscribe when removed.""" - self._sub_state = await subscription.async_unsubscribe_topics( - self.hass, self._sub_state - ) - await MqttAttributes.async_will_remove_from_hass(self) - await MqttAvailability.async_will_remove_from_hass(self) - await MqttDiscoveryUpdate.async_will_remove_from_hass(self) - - @property - def should_poll(self): - """No polling needed.""" - return False - @property def name(self): """Return the name of the device.""" return self._config[CONF_NAME] - @property - def unique_id(self): - """Return a unique ID.""" - return self._unique_id - @property def state(self): """Return the state of the device.""" diff --git a/homeassistant/components/mqtt/binary_sensor.py b/homeassistant/components/mqtt/binary_sensor.py index 21d7740442c..d965401cef4 100644 --- a/homeassistant/components/mqtt/binary_sensor.py +++ b/homeassistant/components/mqtt/binary_sensor.py @@ -35,10 +35,8 @@ from .mixins import ( MQTT_AVAILABILITY_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_JSON_ATTRS_SCHEMA, - MqttAttributes, MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, + MqttEntity, async_setup_entry_helper, ) @@ -94,21 +92,12 @@ async def _async_setup_entity( async_add_entities([MqttBinarySensor(hass, config, config_entry, discovery_data)]) -class MqttBinarySensor( - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, - BinarySensorEntity, -): +class MqttBinarySensor(MqttEntity, BinarySensorEntity): """Representation a binary sensor that is updated by MQTT.""" def __init__(self, hass, config, config_entry, discovery_data): """Initialize the MQTT binary sensor.""" - self.hass = hass - self._unique_id = config.get(CONF_UNIQUE_ID) self._state = None - self._sub_state = None self._expiration_trigger = None self._delay_listener = None expire_after = config.get(CONF_EXPIRE_AFTER) @@ -117,30 +106,12 @@ class MqttBinarySensor( else: self._expired = None - # Load config - self._setup_from_config(config) + MqttEntity.__init__(self, hass, config, config_entry, discovery_data) - device_config = config.get(CONF_DEVICE) - - MqttAttributes.__init__(self, config) - MqttAvailability.__init__(self, config) - MqttDiscoveryUpdate.__init__(self, discovery_data, self.discovery_update) - MqttEntityDeviceInfo.__init__(self, device_config, config_entry) - - async def async_added_to_hass(self): - """Subscribe mqtt events.""" - await super().async_added_to_hass() - await self._subscribe_topics() - - async def discovery_update(self, discovery_payload): - """Handle updated discovery message.""" - config = PLATFORM_SCHEMA(discovery_payload) - self._setup_from_config(config) - await self.attributes_discovery_update(config) - await self.availability_discovery_update(config) - await self.device_info_discovery_update(config) - await self._subscribe_topics() - self.async_write_ha_state() + @staticmethod + def config_schema(): + """Return the config schema.""" + return PLATFORM_SCHEMA def _setup_from_config(self, config): self._config = config @@ -240,15 +211,6 @@ class MqttBinarySensor( }, ) - async def async_will_remove_from_hass(self): - """Unsubscribe when removed.""" - self._sub_state = await subscription.async_unsubscribe_topics( - self.hass, self._sub_state - ) - await MqttAttributes.async_will_remove_from_hass(self) - await MqttAvailability.async_will_remove_from_hass(self) - await MqttDiscoveryUpdate.async_will_remove_from_hass(self) - @callback def _value_is_expired(self, *_): """Triggered when value is expired.""" @@ -258,11 +220,6 @@ class MqttBinarySensor( self.async_write_ha_state() - @property - def should_poll(self): - """Return the polling state.""" - return False - @property def name(self): """Return the name of the binary sensor.""" @@ -283,11 +240,6 @@ class MqttBinarySensor( """Force update.""" return self._config[CONF_FORCE_UPDATE] - @property - def unique_id(self): - """Return a unique ID.""" - return self._unique_id - @property def available(self) -> bool: """Return true if the device is available and value has not expired.""" diff --git a/homeassistant/components/mqtt/camera.py b/homeassistant/components/mqtt/camera.py index 5600dd8a1e3..21fcb9276dd 100644 --- a/homeassistant/components/mqtt/camera.py +++ b/homeassistant/components/mqtt/camera.py @@ -19,10 +19,7 @@ from .mixins import ( MQTT_AVAILABILITY_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_JSON_ATTRS_SCHEMA, - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, + MqttEntity, async_setup_entry_helper, ) @@ -69,41 +66,23 @@ async def _async_setup_entity( async_add_entities([MqttCamera(config, config_entry, discovery_data)]) -class MqttCamera( - MqttAttributes, MqttAvailability, MqttDiscoveryUpdate, MqttEntityDeviceInfo, Camera -): +class MqttCamera(MqttEntity, Camera): """representation of a MQTT camera.""" def __init__(self, config, config_entry, discovery_data): """Initialize the MQTT Camera.""" - self._config = config - self._unique_id = config.get(CONF_UNIQUE_ID) - self._sub_state = None - self._last_image = None - device_config = config.get(CONF_DEVICE) - Camera.__init__(self) - MqttAttributes.__init__(self, config) - MqttAvailability.__init__(self, config) - MqttDiscoveryUpdate.__init__(self, discovery_data, self.discovery_update) - MqttEntityDeviceInfo.__init__(self, device_config, config_entry) + MqttEntity.__init__(self, None, config, config_entry, discovery_data) - async def async_added_to_hass(self): - """Subscribe MQTT events.""" - await super().async_added_to_hass() - await self._subscribe_topics() + @staticmethod + def config_schema(): + """Return the config schema.""" + return PLATFORM_SCHEMA - async def discovery_update(self, discovery_payload): - """Handle updated discovery message.""" - config = PLATFORM_SCHEMA(discovery_payload) + def _setup_from_config(self, config): self._config = config - await self.attributes_discovery_update(config) - await self.availability_discovery_update(config) - await self.device_info_discovery_update(config) - await self._subscribe_topics() - self.async_write_ha_state() async def _subscribe_topics(self): """(Re)Subscribe to topics.""" @@ -127,15 +106,6 @@ class MqttCamera( }, ) - async def async_will_remove_from_hass(self): - """Unsubscribe when removed.""" - self._sub_state = await subscription.async_unsubscribe_topics( - self.hass, self._sub_state - ) - await MqttAttributes.async_will_remove_from_hass(self) - await MqttAvailability.async_will_remove_from_hass(self) - await MqttDiscoveryUpdate.async_will_remove_from_hass(self) - async def async_camera_image(self): """Return image response.""" return self._last_image @@ -144,8 +114,3 @@ class MqttCamera( def name(self): """Return the name of this camera.""" return self._config[CONF_NAME] - - @property - def unique_id(self): - """Return a unique ID.""" - return self._unique_id diff --git a/homeassistant/components/mqtt/climate.py b/homeassistant/components/mqtt/climate.py index 1c9bbd74bfb..b0d9ebd6ffa 100644 --- a/homeassistant/components/mqtt/climate.py +++ b/homeassistant/components/mqtt/climate.py @@ -65,10 +65,7 @@ from .mixins import ( MQTT_AVAILABILITY_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_JSON_ATTRS_SCHEMA, - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, + MqttEntity, async_setup_entry_helper, ) @@ -267,22 +264,11 @@ async def _async_setup_entity( async_add_entities([MqttClimate(hass, config, config_entry, discovery_data)]) -class MqttClimate( - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, - ClimateEntity, -): +class MqttClimate(MqttEntity, ClimateEntity): """Representation of an MQTT climate device.""" def __init__(self, hass, config, config_entry, discovery_data): """Initialize the climate device.""" - self._config = config - self._unique_id = config.get(CONF_UNIQUE_ID) - self._sub_state = None - - self.hass = hass self._action = None self._aux = False self._away = False @@ -297,33 +283,21 @@ class MqttClimate( self._topic = None self._value_templates = None - self._setup_from_config(config) + MqttEntity.__init__(self, hass, config, config_entry, discovery_data) - device_config = config.get(CONF_DEVICE) - - MqttAttributes.__init__(self, config) - MqttAvailability.__init__(self, config) - MqttDiscoveryUpdate.__init__(self, discovery_data, self.discovery_update) - MqttEntityDeviceInfo.__init__(self, device_config, config_entry) + @staticmethod + def config_schema(): + """Return the config schema.""" + return PLATFORM_SCHEMA async def async_added_to_hass(self): """Handle being added to Home Assistant.""" await super().async_added_to_hass() await self._subscribe_topics() - async def discovery_update(self, discovery_payload): - """Handle updated discovery message.""" - config = PLATFORM_SCHEMA(discovery_payload) - self._config = config - self._setup_from_config(config) - await self.attributes_discovery_update(config) - await self.availability_discovery_update(config) - await self.device_info_discovery_update(config) - await self._subscribe_topics() - self.async_write_ha_state() - def _setup_from_config(self, config): """(Re)Setup the entity.""" + self._config = config self._topic = {key: config.get(key) for key in TOPIC_KEYS} # set to None in non-optimistic mode @@ -556,30 +530,11 @@ class MqttClimate( self.hass, self._sub_state, topics ) - async def async_will_remove_from_hass(self): - """Unsubscribe when removed.""" - self._sub_state = await subscription.async_unsubscribe_topics( - self.hass, self._sub_state - ) - await MqttAttributes.async_will_remove_from_hass(self) - await MqttAvailability.async_will_remove_from_hass(self) - await MqttDiscoveryUpdate.async_will_remove_from_hass(self) - - @property - def should_poll(self): - """Return the polling state.""" - return False - @property def name(self): """Return the name of the climate device.""" return self._config[CONF_NAME] - @property - def unique_id(self): - """Return a unique ID.""" - return self._unique_id - @property def temperature_unit(self): """Return the unit of measurement.""" diff --git a/homeassistant/components/mqtt/cover.py b/homeassistant/components/mqtt/cover.py index 498d6ffc8af..dc2cba0efab 100644 --- a/homeassistant/components/mqtt/cover.py +++ b/homeassistant/components/mqtt/cover.py @@ -52,10 +52,7 @@ from .mixins import ( MQTT_AVAILABILITY_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_JSON_ATTRS_SCHEMA, - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, + MqttEntity, async_setup_entry_helper, ) @@ -198,51 +195,24 @@ async def _async_setup_entity( async_add_entities([MqttCover(hass, config, config_entry, discovery_data)]) -class MqttCover( - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, - CoverEntity, -): +class MqttCover(MqttEntity, CoverEntity): """Representation of a cover that can be controlled using MQTT.""" def __init__(self, hass, config, config_entry, discovery_data): """Initialize the cover.""" - self.hass = hass - self._unique_id = config.get(CONF_UNIQUE_ID) self._position = None self._state = None - self._sub_state = None self._optimistic = None self._tilt_value = None self._tilt_optimistic = None - # Load config - self._setup_from_config(config) + MqttEntity.__init__(self, hass, config, config_entry, discovery_data) - device_config = config.get(CONF_DEVICE) - - MqttAttributes.__init__(self, config) - MqttAvailability.__init__(self, config) - MqttDiscoveryUpdate.__init__(self, discovery_data, self.discovery_update) - MqttEntityDeviceInfo.__init__(self, device_config, config_entry) - - async def async_added_to_hass(self): - """Subscribe MQTT events.""" - await super().async_added_to_hass() - await self._subscribe_topics() - - async def discovery_update(self, discovery_payload): - """Handle updated discovery message.""" - config = PLATFORM_SCHEMA(discovery_payload) - self._setup_from_config(config) - await self.attributes_discovery_update(config) - await self.availability_discovery_update(config) - await self.device_info_discovery_update(config) - await self._subscribe_topics() - self.async_write_ha_state() + @staticmethod + def config_schema(): + """Return the config schema.""" + return PLATFORM_SCHEMA def _setup_from_config(self, config): self._config = config @@ -367,20 +337,6 @@ class MqttCover( self.hass, self._sub_state, topics ) - async def async_will_remove_from_hass(self): - """Unsubscribe when removed.""" - self._sub_state = await subscription.async_unsubscribe_topics( - self.hass, self._sub_state - ) - await MqttAttributes.async_will_remove_from_hass(self) - await MqttAvailability.async_will_remove_from_hass(self) - await MqttDiscoveryUpdate.async_will_remove_from_hass(self) - - @property - def should_poll(self): - """No polling needed.""" - return False - @property def assumed_state(self): """Return true if we do optimistic updates.""" @@ -628,8 +584,3 @@ class MqttCover( if range_type == TILT_PAYLOAD and self._config[CONF_TILT_INVERT_STATE]: position = max_range - position + offset return position - - @property - def unique_id(self): - """Return a unique ID.""" - return self._unique_id diff --git a/homeassistant/components/mqtt/device_tracker/schema_discovery.py b/homeassistant/components/mqtt/device_tracker/schema_discovery.py index 8e6019eefd7..8b51b9fac0e 100644 --- a/homeassistant/components/mqtt/device_tracker/schema_discovery.py +++ b/homeassistant/components/mqtt/device_tracker/schema_discovery.py @@ -30,10 +30,7 @@ from ..mixins import ( MQTT_AVAILABILITY_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_JSON_ATTRS_SCHEMA, - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, + MqttEntity, async_setup_entry_helper, ) @@ -78,46 +75,19 @@ async def _async_setup_entity( async_add_entities([MqttDeviceTracker(hass, config, config_entry, discovery_data)]) -class MqttDeviceTracker( - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, - TrackerEntity, -): +class MqttDeviceTracker(MqttEntity, TrackerEntity): """Representation of a device tracker using MQTT.""" def __init__(self, hass, config, config_entry, discovery_data): """Initialize the tracker.""" - self.hass = hass self._location_name = None - self._sub_state = None - self._unique_id = config.get(CONF_UNIQUE_ID) - # Load config - self._setup_from_config(config) + MqttEntity.__init__(self, hass, config, config_entry, discovery_data) - device_config = config.get(CONF_DEVICE) - - MqttAttributes.__init__(self, config) - MqttAvailability.__init__(self, config) - MqttDiscoveryUpdate.__init__(self, discovery_data, self.discovery_update) - MqttEntityDeviceInfo.__init__(self, device_config, config_entry) - - async def async_added_to_hass(self): - """Subscribe to MQTT events.""" - await super().async_added_to_hass() - await self._subscribe_topics() - - async def discovery_update(self, discovery_payload): - """Handle updated discovery message.""" - config = PLATFORM_SCHEMA_DISCOVERY(discovery_payload) - self._setup_from_config(config) - await self.attributes_discovery_update(config) - await self.availability_discovery_update(config) - await self.device_info_discovery_update(config) - await self._subscribe_topics() - self.async_write_ha_state() + @staticmethod + def config_schema(): + """Return the config schema.""" + return PLATFORM_SCHEMA_DISCOVERY def _setup_from_config(self, config): """(Re)Setup the entity.""" @@ -159,15 +129,6 @@ class MqttDeviceTracker( }, ) - async def async_will_remove_from_hass(self): - """Unsubscribe when removed.""" - self._sub_state = await subscription.async_unsubscribe_topics( - self.hass, self._sub_state - ) - await MqttAttributes.async_will_remove_from_hass(self) - await MqttAvailability.async_will_remove_from_hass(self) - await MqttDiscoveryUpdate.async_will_remove_from_hass(self) - @property def icon(self): """Return the icon of the device.""" @@ -213,11 +174,6 @@ class MqttDeviceTracker( """Return the name of the device tracker.""" return self._config.get(CONF_NAME) - @property - def unique_id(self): - """Return a unique ID.""" - return self._unique_id - @property def source_type(self): """Return the source type, eg gps or router, of the device.""" diff --git a/homeassistant/components/mqtt/fan.py b/homeassistant/components/mqtt/fan.py index 5d3abd7b793..5d69fb87b91 100644 --- a/homeassistant/components/mqtt/fan.py +++ b/homeassistant/components/mqtt/fan.py @@ -44,10 +44,7 @@ from .mixins import ( MQTT_AVAILABILITY_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_JSON_ATTRS_SCHEMA, - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, + MqttEntity, async_setup_entry_helper, ) @@ -139,24 +136,15 @@ async def _async_setup_entity( async_add_entities([MqttFan(hass, config, config_entry, discovery_data)]) -class MqttFan( - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, - FanEntity, -): +class MqttFan(MqttEntity, FanEntity): """A MQTT fan component.""" def __init__(self, hass, config, config_entry, discovery_data): """Initialize the MQTT fan.""" - self.hass = hass - self._unique_id = config.get(CONF_UNIQUE_ID) self._state = False self._speed = None self._oscillation = None self._supported_features = 0 - self._sub_state = None self._topic = None self._payload = None @@ -165,30 +153,12 @@ class MqttFan( self._optimistic_oscillation = None self._optimistic_speed = None - # Load config - self._setup_from_config(config) + MqttEntity.__init__(self, hass, config, config_entry, discovery_data) - device_config = config.get(CONF_DEVICE) - - MqttAttributes.__init__(self, config) - MqttAvailability.__init__(self, config) - MqttDiscoveryUpdate.__init__(self, discovery_data, self.discovery_update) - MqttEntityDeviceInfo.__init__(self, device_config, config_entry) - - async def async_added_to_hass(self): - """Subscribe to MQTT events.""" - await super().async_added_to_hass() - await self._subscribe_topics() - - async def discovery_update(self, discovery_payload): - """Handle updated discovery message.""" - config = PLATFORM_SCHEMA(discovery_payload) - self._setup_from_config(config) - await self.attributes_discovery_update(config) - await self.availability_discovery_update(config) - await self.device_info_discovery_update(config) - await self._subscribe_topics() - self.async_write_ha_state() + @staticmethod + def config_schema(): + """Return the config schema.""" + return PLATFORM_SCHEMA def _setup_from_config(self, config): """(Re)Setup the entity.""" @@ -312,20 +282,6 @@ class MqttFan( self.hass, self._sub_state, topics ) - async def async_will_remove_from_hass(self): - """Unsubscribe when removed.""" - self._sub_state = await subscription.async_unsubscribe_topics( - self.hass, self._sub_state - ) - await MqttAttributes.async_will_remove_from_hass(self) - await MqttAvailability.async_will_remove_from_hass(self) - await MqttDiscoveryUpdate.async_will_remove_from_hass(self) - - @property - def should_poll(self): - """No polling needed for a MQTT fan.""" - return False - @property def assumed_state(self): """Return true if we do optimistic updates.""" @@ -444,8 +400,3 @@ class MqttFan( if self._optimistic_oscillation: self._oscillation = oscillating self.async_write_ha_state() - - @property - def unique_id(self): - """Return a unique ID.""" - return self._unique_id diff --git a/homeassistant/components/mqtt/light/schema_basic.py b/homeassistant/components/mqtt/light/schema_basic.py index 230efa5e60a..04f01ea0d3a 100644 --- a/homeassistant/components/mqtt/light/schema_basic.py +++ b/homeassistant/components/mqtt/light/schema_basic.py @@ -38,10 +38,7 @@ from ..mixins import ( MQTT_AVAILABILITY_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_JSON_ATTRS_SCHEMA, - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, + MqttEntity, ) from .schema import MQTT_LIGHT_SCHEMA_SCHEMA @@ -163,21 +160,12 @@ async def async_setup_entity_basic( async_add_entities([MqttLight(hass, config, config_entry, discovery_data)]) -class MqttLight( - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, - LightEntity, - RestoreEntity, -): +class MqttLight(MqttEntity, LightEntity, RestoreEntity): """Representation of a MQTT light.""" def __init__(self, hass, config, config_entry, discovery_data): """Initialize MQTT light.""" - self.hass = hass self._state = False - self._sub_state = None self._brightness = None self._hs = None self._color_temp = None @@ -196,32 +184,13 @@ class MqttLight( self._optimistic_hs = False self._optimistic_white_value = False self._optimistic_xy = False - self._unique_id = config.get(CONF_UNIQUE_ID) - # Load config - self._setup_from_config(config) + MqttEntity.__init__(self, hass, config, config_entry, discovery_data) - device_config = config.get(CONF_DEVICE) - - MqttAttributes.__init__(self, config) - MqttAvailability.__init__(self, config) - MqttDiscoveryUpdate.__init__(self, discovery_data, self.discovery_update) - MqttEntityDeviceInfo.__init__(self, device_config, config_entry) - - async def async_added_to_hass(self): - """Subscribe to MQTT events.""" - await super().async_added_to_hass() - await self._subscribe_topics() - - async def discovery_update(self, discovery_payload): - """Handle updated discovery message.""" - config = PLATFORM_SCHEMA_BASIC(discovery_payload) - self._setup_from_config(config) - await self.attributes_discovery_update(config) - await self.availability_discovery_update(config) - await self.device_info_discovery_update(config) - await self._subscribe_topics() - self.async_write_ha_state() + @staticmethod + def config_schema(): + """Return the config schema.""" + return PLATFORM_SCHEMA_BASIC def _setup_from_config(self, config): """(Re)Setup the entity.""" @@ -525,15 +494,6 @@ class MqttLight( self.hass, self._sub_state, topics ) - async def async_will_remove_from_hass(self): - """Unsubscribe when removed.""" - self._sub_state = await subscription.async_unsubscribe_topics( - self.hass, self._sub_state - ) - await MqttAttributes.async_will_remove_from_hass(self) - await MqttAvailability.async_will_remove_from_hass(self) - await MqttDiscoveryUpdate.async_will_remove_from_hass(self) - @property def brightness(self): """Return the brightness of this light between 0..255.""" @@ -580,21 +540,11 @@ class MqttLight( return white_value return None - @property - def should_poll(self): - """No polling needed for a MQTT light.""" - return False - @property def name(self): """Return the name of the device if any.""" return self._config[CONF_NAME] - @property - def unique_id(self): - """Return a unique ID.""" - return self._unique_id - @property def is_on(self): """Return true if device is on.""" diff --git a/homeassistant/components/mqtt/light/schema_json.py b/homeassistant/components/mqtt/light/schema_json.py index 16281da4169..c6622578a6f 100644 --- a/homeassistant/components/mqtt/light/schema_json.py +++ b/homeassistant/components/mqtt/light/schema_json.py @@ -49,10 +49,7 @@ from ..mixins import ( MQTT_AVAILABILITY_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_JSON_ATTRS_SCHEMA, - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, + MqttEntity, ) from .schema import MQTT_LIGHT_SCHEMA_SCHEMA from .schema_basic import CONF_BRIGHTNESS_SCALE @@ -130,20 +127,12 @@ async def async_setup_entity_json( async_add_entities([MqttLightJson(config, config_entry, discovery_data)]) -class MqttLightJson( - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, - LightEntity, - RestoreEntity, -): +class MqttLightJson(MqttEntity, LightEntity, RestoreEntity): """Representation of a MQTT JSON light.""" def __init__(self, config, config_entry, discovery_data): """Initialize MQTT JSON light.""" self._state = False - self._sub_state = None self._supported_features = 0 self._topic = None @@ -154,32 +143,13 @@ class MqttLightJson( self._hs = None self._white_value = None self._flash_times = None - self._unique_id = config.get(CONF_UNIQUE_ID) - # Load config - self._setup_from_config(config) + MqttEntity.__init__(self, None, config, config_entry, discovery_data) - device_config = config.get(CONF_DEVICE) - - MqttAttributes.__init__(self, config) - MqttAvailability.__init__(self, config) - MqttDiscoveryUpdate.__init__(self, discovery_data, self.discovery_update) - MqttEntityDeviceInfo.__init__(self, device_config, config_entry) - - async def async_added_to_hass(self): - """Subscribe to MQTT events.""" - await super().async_added_to_hass() - await self._subscribe_topics() - - async def discovery_update(self, discovery_payload): - """Handle updated discovery message.""" - config = PLATFORM_SCHEMA_JSON(discovery_payload) - self._setup_from_config(config) - await self.attributes_discovery_update(config) - await self.availability_discovery_update(config) - await self.device_info_discovery_update(config) - await self._subscribe_topics() - self.async_write_ha_state() + @staticmethod + def config_schema(): + """Return the config schema.""" + return PLATFORM_SCHEMA_JSON def _setup_from_config(self, config): """(Re)Setup the entity.""" @@ -314,15 +284,6 @@ class MqttLightJson( if last_state.attributes.get(ATTR_WHITE_VALUE): self._white_value = last_state.attributes.get(ATTR_WHITE_VALUE) - async def async_will_remove_from_hass(self): - """Unsubscribe when removed.""" - self._sub_state = await subscription.async_unsubscribe_topics( - self.hass, self._sub_state - ) - await MqttAttributes.async_will_remove_from_hass(self) - await MqttAvailability.async_will_remove_from_hass(self) - await MqttDiscoveryUpdate.async_will_remove_from_hass(self) - @property def brightness(self): """Return the brightness of this light between 0..255.""" @@ -363,21 +324,11 @@ class MqttLightJson( """Return the white property.""" return self._white_value - @property - def should_poll(self): - """No polling needed for a MQTT light.""" - return False - @property def name(self): """Return the name of the device if any.""" return self._config[CONF_NAME] - @property - def unique_id(self): - """Return a unique ID.""" - return self._unique_id - @property def is_on(self): """Return true if device is on.""" diff --git a/homeassistant/components/mqtt/light/schema_template.py b/homeassistant/components/mqtt/light/schema_template.py index e33d169e47a..e696e99552e 100644 --- a/homeassistant/components/mqtt/light/schema_template.py +++ b/homeassistant/components/mqtt/light/schema_template.py @@ -40,10 +40,7 @@ from ..mixins import ( MQTT_AVAILABILITY_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_JSON_ATTRS_SCHEMA, - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, + MqttEntity, ) from .schema import MQTT_LIGHT_SCHEMA_SCHEMA @@ -103,20 +100,12 @@ async def async_setup_entity_template( async_add_entities([MqttLightTemplate(config, config_entry, discovery_data)]) -class MqttLightTemplate( - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, - LightEntity, - RestoreEntity, -): +class MqttLightTemplate(MqttEntity, LightEntity, RestoreEntity): """Representation of a MQTT Template light.""" def __init__(self, config, config_entry, discovery_data): """Initialize a MQTT Template light.""" self._state = False - self._sub_state = None self._topics = None self._templates = None @@ -128,32 +117,13 @@ class MqttLightTemplate( self._white_value = None self._hs = None self._effect = None - self._unique_id = config.get(CONF_UNIQUE_ID) - # Load config - self._setup_from_config(config) + MqttEntity.__init__(self, None, config, config_entry, discovery_data) - device_config = config.get(CONF_DEVICE) - - MqttAttributes.__init__(self, config) - MqttAvailability.__init__(self, config) - MqttDiscoveryUpdate.__init__(self, discovery_data, self.discovery_update) - MqttEntityDeviceInfo.__init__(self, device_config, config_entry) - - async def async_added_to_hass(self): - """Subscribe to MQTT events.""" - await super().async_added_to_hass() - await self._subscribe_topics() - - async def discovery_update(self, discovery_payload): - """Handle updated discovery message.""" - config = PLATFORM_SCHEMA_TEMPLATE(discovery_payload) - self._setup_from_config(config) - await self.attributes_discovery_update(config) - await self.availability_discovery_update(config) - await self.device_info_discovery_update(config) - await self._subscribe_topics() - self.async_write_ha_state() + @staticmethod + def config_schema(): + """Return the config schema.""" + return PLATFORM_SCHEMA_TEMPLATE def _setup_from_config(self, config): """(Re)Setup the entity.""" @@ -299,15 +269,6 @@ class MqttLightTemplate( if last_state.attributes.get(ATTR_WHITE_VALUE): self._white_value = last_state.attributes.get(ATTR_WHITE_VALUE) - async def async_will_remove_from_hass(self): - """Unsubscribe when removed.""" - self._sub_state = await subscription.async_unsubscribe_topics( - self.hass, self._sub_state - ) - await MqttAttributes.async_will_remove_from_hass(self) - await MqttAvailability.async_will_remove_from_hass(self) - await MqttDiscoveryUpdate.async_will_remove_from_hass(self) - @property def brightness(self): """Return the brightness of this light between 0..255.""" @@ -338,24 +299,11 @@ class MqttLightTemplate( """Return the white property.""" return self._white_value - @property - def should_poll(self): - """Return True if entity has to be polled for state. - - False if entity pushes its state to HA. - """ - return False - @property def name(self): """Return the name of the entity.""" return self._config[CONF_NAME] - @property - def unique_id(self): - """Return a unique ID.""" - return self._unique_id - @property def is_on(self): """Return True if entity is on.""" diff --git a/homeassistant/components/mqtt/lock.py b/homeassistant/components/mqtt/lock.py index ef3ad6bb8eb..b08f8f8bb43 100644 --- a/homeassistant/components/mqtt/lock.py +++ b/homeassistant/components/mqtt/lock.py @@ -33,10 +33,7 @@ from .mixins import ( MQTT_AVAILABILITY_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_JSON_ATTRS_SCHEMA, - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, + MqttEntity, async_setup_entry_helper, ) @@ -101,47 +98,20 @@ async def _async_setup_entity( async_add_entities([MqttLock(hass, config, config_entry, discovery_data)]) -class MqttLock( - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, - LockEntity, -): +class MqttLock(MqttEntity, LockEntity): """Representation of a lock that can be toggled using MQTT.""" def __init__(self, hass, config, config_entry, discovery_data): """Initialize the lock.""" - self.hass = hass - self._unique_id = config.get(CONF_UNIQUE_ID) self._state = False - self._sub_state = None self._optimistic = False - # Load config - self._setup_from_config(config) + MqttEntity.__init__(self, hass, config, config_entry, discovery_data) - device_config = config.get(CONF_DEVICE) - - MqttAttributes.__init__(self, config) - MqttAvailability.__init__(self, config) - MqttDiscoveryUpdate.__init__(self, discovery_data, self.discovery_update) - MqttEntityDeviceInfo.__init__(self, device_config, config_entry) - - async def async_added_to_hass(self): - """Subscribe to MQTT events.""" - await super().async_added_to_hass() - await self._subscribe_topics() - - async def discovery_update(self, discovery_payload): - """Handle updated discovery message.""" - config = PLATFORM_SCHEMA(discovery_payload) - self._setup_from_config(config) - await self.attributes_discovery_update(config) - await self.availability_discovery_update(config) - await self.device_info_discovery_update(config) - await self._subscribe_topics() - self.async_write_ha_state() + @staticmethod + def config_schema(): + """Return the config schema.""" + return PLATFORM_SCHEMA def _setup_from_config(self, config): """(Re)Setup the entity.""" @@ -187,30 +157,11 @@ class MqttLock( }, ) - async def async_will_remove_from_hass(self): - """Unsubscribe when removed.""" - self._sub_state = await subscription.async_unsubscribe_topics( - self.hass, self._sub_state - ) - await MqttAttributes.async_will_remove_from_hass(self) - await MqttAvailability.async_will_remove_from_hass(self) - await MqttDiscoveryUpdate.async_will_remove_from_hass(self) - - @property - def should_poll(self): - """No polling needed.""" - return False - @property def name(self): """Return the name of the lock.""" return self._config[CONF_NAME] - @property - def unique_id(self): - """Return a unique ID.""" - return self._unique_id - @property def is_locked(self): """Return true if lock is locked.""" diff --git a/homeassistant/components/mqtt/mixins.py b/homeassistant/components/mqtt/mixins.py index 42171ef4e34..e4fa7e15526 100644 --- a/homeassistant/components/mqtt/mixins.py +++ b/homeassistant/components/mqtt/mixins.py @@ -1,11 +1,12 @@ """MQTT component mixins and helpers.""" +from abc import abstractmethod import json import logging from typing import Optional import voluptuous as vol -from homeassistant.const import CONF_DEVICE, CONF_NAME +from homeassistant.const import CONF_DEVICE, CONF_NAME, CONF_UNIQUE_ID from homeassistant.core import callback from homeassistant.helpers import config_validation as cv from homeassistant.helpers.dispatcher import ( @@ -15,7 +16,7 @@ from homeassistant.helpers.dispatcher import ( from homeassistant.helpers.entity import Entity from homeassistant.helpers.typing import ConfigType -from . import CONF_TOPIC, DATA_MQTT, debug_info, publish +from . import CONF_TOPIC, DATA_MQTT, debug_info, publish, subscription from .const import ( ATTR_DISCOVERY_HASH, ATTR_DISCOVERY_PAYLOAD, @@ -493,3 +494,73 @@ class MqttEntityDeviceInfo(Entity): def device_info(self): """Return a device description for device registry.""" return device_info_from_config(self._device_config) + + +class MqttEntity( + MqttAttributes, + MqttAvailability, + MqttDiscoveryUpdate, + MqttEntityDeviceInfo, +): + """Representation of an MQTT entity.""" + + def __init__(self, hass, config, config_entry, discovery_data): + """Init the MQTT Entity.""" + self.hass = hass + self._unique_id = config.get(CONF_UNIQUE_ID) + self._sub_state = None + + # Load config + self._setup_from_config(config) + + # Initialize mixin classes + MqttAttributes.__init__(self, config) + MqttAvailability.__init__(self, config) + MqttDiscoveryUpdate.__init__(self, discovery_data, self.discovery_update) + MqttEntityDeviceInfo.__init__(self, config.get(CONF_DEVICE), config_entry) + + async def async_added_to_hass(self): + """Subscribe mqtt events.""" + await super().async_added_to_hass() + await self._subscribe_topics() + + async def discovery_update(self, discovery_payload): + """Handle updated discovery message.""" + config = self.config_schema()(discovery_payload) + self._setup_from_config(config) + await self.attributes_discovery_update(config) + await self.availability_discovery_update(config) + await self.device_info_discovery_update(config) + await self._subscribe_topics() + self.async_write_ha_state() + + async def async_will_remove_from_hass(self): + """Unsubscribe when removed.""" + self._sub_state = await subscription.async_unsubscribe_topics( + self.hass, self._sub_state + ) + await MqttAttributes.async_will_remove_from_hass(self) + await MqttAvailability.async_will_remove_from_hass(self) + await MqttDiscoveryUpdate.async_will_remove_from_hass(self) + + @staticmethod + @abstractmethod + def config_schema(): + """Return the config schema.""" + + def _setup_from_config(self, config): + """(Re)Setup the entity.""" + + @abstractmethod + async def _subscribe_topics(self): + """(Re)Subscribe to topics.""" + + @property + def should_poll(self): + """No polling needed.""" + return False + + @property + def unique_id(self): + """Return a unique ID.""" + return self._unique_id diff --git a/homeassistant/components/mqtt/number.py b/homeassistant/components/mqtt/number.py index c844d888efe..159f466f7ae 100644 --- a/homeassistant/components/mqtt/number.py +++ b/homeassistant/components/mqtt/number.py @@ -33,10 +33,7 @@ from .mixins import ( MQTT_AVAILABILITY_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_JSON_ATTRS_SCHEMA, - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, + MqttEntity, async_setup_entry_helper, ) @@ -84,47 +81,27 @@ async def _async_setup_entity( async_add_entities([MqttNumber(config, config_entry, discovery_data)]) -class MqttNumber( - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, - NumberEntity, - RestoreEntity, -): +class MqttNumber(MqttEntity, NumberEntity, RestoreEntity): """representation of an MQTT number.""" def __init__(self, config, config_entry, discovery_data): """Initialize the MQTT Number.""" - self._config = config self._sub_state = None self._current_number = None self._optimistic = config.get(CONF_OPTIMISTIC) self._unique_id = config.get(CONF_UNIQUE_ID) - device_config = config.get(CONF_DEVICE) - NumberEntity.__init__(self) - MqttAttributes.__init__(self, config) - MqttAvailability.__init__(self, config) - MqttDiscoveryUpdate.__init__(self, discovery_data, self.discovery_update) - MqttEntityDeviceInfo.__init__(self, device_config, config_entry) + MqttEntity.__init__(self, None, config, config_entry, discovery_data) - async def async_added_to_hass(self): - """Subscribe MQTT events.""" - await super().async_added_to_hass() - await self._subscribe_topics() + @staticmethod + def config_schema(): + """Return the config schema.""" + return PLATFORM_SCHEMA - async def discovery_update(self, discovery_payload): - """Handle updated discovery message.""" - config = PLATFORM_SCHEMA(discovery_payload) + def _setup_from_config(self, config): self._config = config - await self.attributes_discovery_update(config) - await self.availability_discovery_update(config) - await self.device_info_discovery_update(config) - await self._subscribe_topics() - self.async_write_ha_state() async def _subscribe_topics(self): """(Re)Subscribe to topics.""" @@ -165,15 +142,6 @@ class MqttNumber( if last_state: self._current_number = last_state.state - async def async_will_remove_from_hass(self): - """Unsubscribe when removed.""" - self._sub_state = await subscription.async_unsubscribe_topics( - self.hass, self._sub_state - ) - await MqttAttributes.async_will_remove_from_hass(self) - await MqttAvailability.async_will_remove_from_hass(self) - await MqttDiscoveryUpdate.async_will_remove_from_hass(self) - @property def value(self): """Return the current value.""" @@ -203,16 +171,6 @@ class MqttNumber( """Return the name of this number.""" return self._config[CONF_NAME] - @property - def unique_id(self): - """Return a unique ID.""" - return self._unique_id - - @property - def should_poll(self): - """Return the polling state.""" - return False - @property def assumed_state(self): """Return true if we do optimistic updates.""" diff --git a/homeassistant/components/mqtt/sensor.py b/homeassistant/components/mqtt/sensor.py index 159c4b1d118..3f79ab1bafe 100644 --- a/homeassistant/components/mqtt/sensor.py +++ b/homeassistant/components/mqtt/sensor.py @@ -33,10 +33,8 @@ from .mixins import ( MQTT_AVAILABILITY_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_JSON_ATTRS_SCHEMA, - MqttAttributes, MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, + MqttEntity, async_setup_entry_helper, ) @@ -88,17 +86,12 @@ async def _async_setup_entity( async_add_entities([MqttSensor(hass, config, config_entry, discovery_data)]) -class MqttSensor( - MqttAttributes, MqttAvailability, MqttDiscoveryUpdate, MqttEntityDeviceInfo, Entity -): +class MqttSensor(MqttEntity, Entity): """Representation of a sensor that can be updated using MQTT.""" def __init__(self, hass, config, config_entry, discovery_data): """Initialize the sensor.""" - self.hass = hass - self._unique_id = config.get(CONF_UNIQUE_ID) self._state = None - self._sub_state = None self._expiration_trigger = None expire_after = config.get(CONF_EXPIRE_AFTER) @@ -107,30 +100,12 @@ class MqttSensor( else: self._expired = None - # Load config - self._setup_from_config(config) + MqttEntity.__init__(self, hass, config, config_entry, discovery_data) - device_config = config.get(CONF_DEVICE) - - MqttAttributes.__init__(self, config) - MqttAvailability.__init__(self, config) - MqttDiscoveryUpdate.__init__(self, discovery_data, self.discovery_update) - MqttEntityDeviceInfo.__init__(self, device_config, config_entry) - - async def async_added_to_hass(self): - """Subscribe to MQTT events.""" - await super().async_added_to_hass() - await self._subscribe_topics() - - async def discovery_update(self, discovery_payload): - """Handle updated discovery message.""" - config = PLATFORM_SCHEMA(discovery_payload) - self._setup_from_config(config) - await self.attributes_discovery_update(config) - await self.availability_discovery_update(config) - await self.device_info_discovery_update(config) - await self._subscribe_topics() - self.async_write_ha_state() + @staticmethod + def config_schema(): + """Return the config schema.""" + return PLATFORM_SCHEMA def _setup_from_config(self, config): """(Re)Setup the entity.""" @@ -185,15 +160,6 @@ class MqttSensor( }, ) - async def async_will_remove_from_hass(self): - """Unsubscribe when removed.""" - self._sub_state = await subscription.async_unsubscribe_topics( - self.hass, self._sub_state - ) - await MqttAttributes.async_will_remove_from_hass(self) - await MqttAvailability.async_will_remove_from_hass(self) - await MqttDiscoveryUpdate.async_will_remove_from_hass(self) - @callback def _value_is_expired(self, *_): """Triggered when value is expired.""" @@ -201,11 +167,6 @@ class MqttSensor( self._expired = True self.async_write_ha_state() - @property - def should_poll(self): - """No polling needed.""" - return False - @property def name(self): """Return the name of the sensor.""" @@ -226,11 +187,6 @@ class MqttSensor( """Return the state of the entity.""" return self._state - @property - def unique_id(self): - """Return a unique ID.""" - return self._unique_id - @property def icon(self): """Return the icon.""" diff --git a/homeassistant/components/mqtt/switch.py b/homeassistant/components/mqtt/switch.py index a4e65354594..d6d476b680d 100644 --- a/homeassistant/components/mqtt/switch.py +++ b/homeassistant/components/mqtt/switch.py @@ -38,10 +38,7 @@ from .mixins import ( MQTT_AVAILABILITY_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_JSON_ATTRS_SCHEMA, - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, + MqttEntity, async_setup_entry_helper, ) @@ -97,51 +94,23 @@ async def _async_setup_entity( async_add_entities([MqttSwitch(hass, config, config_entry, discovery_data)]) -class MqttSwitch( - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, - SwitchEntity, - RestoreEntity, -): +class MqttSwitch(MqttEntity, SwitchEntity, RestoreEntity): """Representation of a switch that can be toggled using MQTT.""" def __init__(self, hass, config, config_entry, discovery_data): """Initialize the MQTT switch.""" - self.hass = hass self._state = False - self._sub_state = None self._state_on = None self._state_off = None self._optimistic = None - self._unique_id = config.get(CONF_UNIQUE_ID) - # Load config - self._setup_from_config(config) + MqttEntity.__init__(self, hass, config, config_entry, discovery_data) - device_config = config.get(CONF_DEVICE) - - MqttAttributes.__init__(self, config) - MqttAvailability.__init__(self, config) - MqttDiscoveryUpdate.__init__(self, discovery_data, self.discovery_update) - MqttEntityDeviceInfo.__init__(self, device_config, config_entry) - - async def async_added_to_hass(self): - """Subscribe to MQTT events.""" - await super().async_added_to_hass() - await self._subscribe_topics() - - async def discovery_update(self, discovery_payload): - """Handle updated discovery message.""" - config = PLATFORM_SCHEMA(discovery_payload) - self._setup_from_config(config) - await self.attributes_discovery_update(config) - await self.availability_discovery_update(config) - await self.device_info_discovery_update(config) - await self._subscribe_topics() - self.async_write_ha_state() + @staticmethod + def config_schema(): + """Return the config schema.""" + return PLATFORM_SCHEMA def _setup_from_config(self, config): """(Re)Setup the entity.""" @@ -198,20 +167,6 @@ class MqttSwitch( if last_state: self._state = last_state.state == STATE_ON - async def async_will_remove_from_hass(self): - """Unsubscribe when removed.""" - self._sub_state = await subscription.async_unsubscribe_topics( - self.hass, self._sub_state - ) - await MqttAttributes.async_will_remove_from_hass(self) - await MqttAvailability.async_will_remove_from_hass(self) - await MqttDiscoveryUpdate.async_will_remove_from_hass(self) - - @property - def should_poll(self): - """Return the polling state.""" - return False - @property def name(self): """Return the name of the switch.""" @@ -227,11 +182,6 @@ class MqttSwitch( """Return true if we do optimistic updates.""" return self._optimistic - @property - def unique_id(self): - """Return a unique ID.""" - return self._unique_id - @property def icon(self): """Return the icon.""" diff --git a/homeassistant/components/mqtt/vacuum/schema_legacy.py b/homeassistant/components/mqtt/vacuum/schema_legacy.py index dd156720a01..e7be64be6ae 100644 --- a/homeassistant/components/mqtt/vacuum/schema_legacy.py +++ b/homeassistant/components/mqtt/vacuum/schema_legacy.py @@ -35,10 +35,7 @@ from ..mixins import ( MQTT_AVAILABILITY_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_JSON_ATTRS_SCHEMA, - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, + MqttEntity, ) from .schema import MQTT_VACUUM_SCHEMA, services_to_strings, strings_to_services @@ -176,16 +173,10 @@ async def async_setup_entity_legacy( async_add_entities([MqttVacuum(config, config_entry, discovery_data)]) -class MqttVacuum( - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, - VacuumEntity, -): +class MqttVacuum(MqttEntity, VacuumEntity): """Representation of a MQTT-controlled legacy vacuum.""" - def __init__(self, config, config_entry, discovery_info): + def __init__(self, config, config_entry, discovery_data): """Initialize the vacuum.""" self._cleaning = False self._charging = False @@ -195,18 +186,13 @@ class MqttVacuum( self._battery_level = 0 self._fan_speed = "unknown" self._fan_speed_list = [] - self._sub_state = None - self._unique_id = config.get(CONF_UNIQUE_ID) - # Load config - self._setup_from_config(config) + MqttEntity.__init__(self, None, config, config_entry, discovery_data) - device_config = config.get(CONF_DEVICE) - - MqttAttributes.__init__(self, config) - MqttAvailability.__init__(self, config) - MqttDiscoveryUpdate.__init__(self, discovery_info, self.discovery_update) - MqttEntityDeviceInfo.__init__(self, device_config, config_entry) + @staticmethod + def config_schema(): + """Return the config schema.""" + return PLATFORM_SCHEMA_LEGACY def _setup_from_config(self, config): self._name = config[CONF_NAME] @@ -257,30 +243,6 @@ class MqttVacuum( ) } - async def discovery_update(self, discovery_payload): - """Handle updated discovery message.""" - config = PLATFORM_SCHEMA_LEGACY(discovery_payload) - self._setup_from_config(config) - await self.attributes_discovery_update(config) - await self.availability_discovery_update(config) - await self.device_info_discovery_update(config) - await self._subscribe_topics() - self.async_write_ha_state() - - async def async_added_to_hass(self): - """Subscribe MQTT events.""" - await super().async_added_to_hass() - await self._subscribe_topics() - - async def async_will_remove_from_hass(self): - """Unsubscribe when removed.""" - self._sub_state = await subscription.async_unsubscribe_topics( - self.hass, self._sub_state - ) - await MqttAttributes.async_will_remove_from_hass(self) - await MqttAvailability.async_will_remove_from_hass(self) - await MqttDiscoveryUpdate.async_will_remove_from_hass(self) - async def _subscribe_topics(self): """(Re)Subscribe to topics.""" for tpl in self._templates.values(): @@ -384,21 +346,11 @@ class MqttVacuum( """Return the name of the vacuum.""" return self._name - @property - def should_poll(self): - """No polling needed for an MQTT vacuum.""" - return False - @property def is_on(self): """Return true if vacuum is on.""" return self._cleaning - @property - def unique_id(self): - """Return a unique ID.""" - return self._unique_id - @property def status(self): """Return a status string for the vacuum.""" diff --git a/homeassistant/components/mqtt/vacuum/schema_state.py b/homeassistant/components/mqtt/vacuum/schema_state.py index 536dd89b0fe..c754ba1604a 100644 --- a/homeassistant/components/mqtt/vacuum/schema_state.py +++ b/homeassistant/components/mqtt/vacuum/schema_state.py @@ -39,10 +39,7 @@ from ..mixins import ( MQTT_AVAILABILITY_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_JSON_ATTRS_SCHEMA, - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, + MqttEntity, ) from .schema import MQTT_VACUUM_SCHEMA, services_to_strings, strings_to_services @@ -160,32 +157,21 @@ async def async_setup_entity_state( async_add_entities([MqttStateVacuum(config, config_entry, discovery_data)]) -class MqttStateVacuum( - MqttAttributes, - MqttAvailability, - MqttDiscoveryUpdate, - MqttEntityDeviceInfo, - StateVacuumEntity, -): +class MqttStateVacuum(MqttEntity, StateVacuumEntity): """Representation of a MQTT-controlled state vacuum.""" - def __init__(self, config, config_entry, discovery_info): + def __init__(self, config, config_entry, discovery_data): """Initialize the vacuum.""" self._state = None self._state_attrs = {} self._fan_speed_list = [] - self._sub_state = None - self._unique_id = config.get(CONF_UNIQUE_ID) - # Load config - self._setup_from_config(config) + MqttEntity.__init__(self, None, config, config_entry, discovery_data) - device_config = config.get(CONF_DEVICE) - - MqttAttributes.__init__(self, config) - MqttAvailability.__init__(self, config) - MqttDiscoveryUpdate.__init__(self, discovery_info, self.discovery_update) - MqttEntityDeviceInfo.__init__(self, device_config, config_entry) + @staticmethod + def config_schema(): + """Return the config schema.""" + return PLATFORM_SCHEMA_STATE def _setup_from_config(self, config): self._config = config @@ -211,30 +197,6 @@ class MqttStateVacuum( ) } - async def discovery_update(self, discovery_payload): - """Handle updated discovery message.""" - config = PLATFORM_SCHEMA_STATE(discovery_payload) - self._setup_from_config(config) - await self.attributes_discovery_update(config) - await self.availability_discovery_update(config) - await self.device_info_discovery_update(config) - await self._subscribe_topics() - self.async_write_ha_state() - - async def async_added_to_hass(self): - """Subscribe MQTT events.""" - await super().async_added_to_hass() - await self._subscribe_topics() - - async def async_will_remove_from_hass(self): - """Unsubscribe when removed.""" - self._sub_state = await subscription.async_unsubscribe_topics( - self.hass, self._sub_state - ) - await MqttAttributes.async_will_remove_from_hass(self) - await MqttAvailability.async_will_remove_from_hass(self) - await MqttDiscoveryUpdate.async_will_remove_from_hass(self) - async def _subscribe_topics(self): """(Re)Subscribe to topics.""" topics = {} @@ -270,11 +232,6 @@ class MqttStateVacuum( """Return state of vacuum.""" return self._state - @property - def unique_id(self): - """Return a unique ID.""" - return self._unique_id - @property def fan_speed(self): """Return fan speed of the vacuum."""