Add MQTT base entity (#44971)

This commit is contained in:
Erik Montnemery 2021-01-09 17:46:53 +01:00 committed by GitHub
parent eabe757e20
commit 248802efd5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 190 additions and 865 deletions

View file

@ -48,10 +48,7 @@ from .mixins import (
MQTT_AVAILABILITY_SCHEMA, MQTT_AVAILABILITY_SCHEMA,
MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA,
MQTT_JSON_ATTRS_SCHEMA, MQTT_JSON_ATTRS_SCHEMA,
MqttAttributes, MqttEntity,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
async_setup_entry_helper, async_setup_entry_helper,
) )
@ -127,46 +124,19 @@ async def _async_setup_entity(
async_add_entities([MqttAlarm(hass, config, config_entry, discovery_data)]) async_add_entities([MqttAlarm(hass, config, config_entry, discovery_data)])
class MqttAlarm( class MqttAlarm(MqttEntity, alarm.AlarmControlPanelEntity):
MqttAttributes,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
alarm.AlarmControlPanelEntity,
):
"""Representation of a MQTT alarm status.""" """Representation of a MQTT alarm status."""
def __init__(self, hass, config, config_entry, discovery_data): def __init__(self, hass, config, config_entry, discovery_data):
"""Init the MQTT Alarm Control Panel.""" """Init the MQTT Alarm Control Panel."""
self.hass = hass
self._state = None self._state = None
self._unique_id = config.get(CONF_UNIQUE_ID)
self._sub_state = None
# Load config MqttEntity.__init__(self, hass, config, config_entry, discovery_data)
self._setup_from_config(config)
device_config = config.get(CONF_DEVICE) @staticmethod
def config_schema():
MqttAttributes.__init__(self, config) """Return the config schema."""
MqttAvailability.__init__(self, config) return PLATFORM_SCHEMA
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()
def _setup_from_config(self, config): def _setup_from_config(self, config):
self._config = 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 @property
def name(self): def name(self):
"""Return the name of the device.""" """Return the name of the device."""
return self._config[CONF_NAME] return self._config[CONF_NAME]
@property
def unique_id(self):
"""Return a unique ID."""
return self._unique_id
@property @property
def state(self): def state(self):
"""Return the state of the device.""" """Return the state of the device."""

View file

@ -35,10 +35,8 @@ from .mixins import (
MQTT_AVAILABILITY_SCHEMA, MQTT_AVAILABILITY_SCHEMA,
MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA,
MQTT_JSON_ATTRS_SCHEMA, MQTT_JSON_ATTRS_SCHEMA,
MqttAttributes,
MqttAvailability, MqttAvailability,
MqttDiscoveryUpdate, MqttEntity,
MqttEntityDeviceInfo,
async_setup_entry_helper, async_setup_entry_helper,
) )
@ -94,21 +92,12 @@ async def _async_setup_entity(
async_add_entities([MqttBinarySensor(hass, config, config_entry, discovery_data)]) async_add_entities([MqttBinarySensor(hass, config, config_entry, discovery_data)])
class MqttBinarySensor( class MqttBinarySensor(MqttEntity, BinarySensorEntity):
MqttAttributes,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
BinarySensorEntity,
):
"""Representation a binary sensor that is updated by MQTT.""" """Representation a binary sensor that is updated by MQTT."""
def __init__(self, hass, config, config_entry, discovery_data): def __init__(self, hass, config, config_entry, discovery_data):
"""Initialize the MQTT binary sensor.""" """Initialize the MQTT binary sensor."""
self.hass = hass
self._unique_id = config.get(CONF_UNIQUE_ID)
self._state = None self._state = None
self._sub_state = None
self._expiration_trigger = None self._expiration_trigger = None
self._delay_listener = None self._delay_listener = None
expire_after = config.get(CONF_EXPIRE_AFTER) expire_after = config.get(CONF_EXPIRE_AFTER)
@ -117,30 +106,12 @@ class MqttBinarySensor(
else: else:
self._expired = None self._expired = None
# Load config MqttEntity.__init__(self, hass, config, config_entry, discovery_data)
self._setup_from_config(config)
device_config = config.get(CONF_DEVICE) @staticmethod
def config_schema():
MqttAttributes.__init__(self, config) """Return the config schema."""
MqttAvailability.__init__(self, config) return PLATFORM_SCHEMA
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()
def _setup_from_config(self, config): def _setup_from_config(self, config):
self._config = 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 @callback
def _value_is_expired(self, *_): def _value_is_expired(self, *_):
"""Triggered when value is expired.""" """Triggered when value is expired."""
@ -258,11 +220,6 @@ class MqttBinarySensor(
self.async_write_ha_state() self.async_write_ha_state()
@property
def should_poll(self):
"""Return the polling state."""
return False
@property @property
def name(self): def name(self):
"""Return the name of the binary sensor.""" """Return the name of the binary sensor."""
@ -283,11 +240,6 @@ class MqttBinarySensor(
"""Force update.""" """Force update."""
return self._config[CONF_FORCE_UPDATE] return self._config[CONF_FORCE_UPDATE]
@property
def unique_id(self):
"""Return a unique ID."""
return self._unique_id
@property @property
def available(self) -> bool: def available(self) -> bool:
"""Return true if the device is available and value has not expired.""" """Return true if the device is available and value has not expired."""

View file

@ -19,10 +19,7 @@ from .mixins import (
MQTT_AVAILABILITY_SCHEMA, MQTT_AVAILABILITY_SCHEMA,
MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA,
MQTT_JSON_ATTRS_SCHEMA, MQTT_JSON_ATTRS_SCHEMA,
MqttAttributes, MqttEntity,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
async_setup_entry_helper, async_setup_entry_helper,
) )
@ -69,41 +66,23 @@ async def _async_setup_entity(
async_add_entities([MqttCamera(config, config_entry, discovery_data)]) async_add_entities([MqttCamera(config, config_entry, discovery_data)])
class MqttCamera( class MqttCamera(MqttEntity, Camera):
MqttAttributes, MqttAvailability, MqttDiscoveryUpdate, MqttEntityDeviceInfo, Camera
):
"""representation of a MQTT camera.""" """representation of a MQTT camera."""
def __init__(self, config, config_entry, discovery_data): def __init__(self, config, config_entry, discovery_data):
"""Initialize the MQTT Camera.""" """Initialize the MQTT Camera."""
self._config = config
self._unique_id = config.get(CONF_UNIQUE_ID)
self._sub_state = None
self._last_image = None self._last_image = None
device_config = config.get(CONF_DEVICE)
Camera.__init__(self) Camera.__init__(self)
MqttAttributes.__init__(self, config) MqttEntity.__init__(self, None, config, config_entry, discovery_data)
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): @staticmethod
"""Subscribe MQTT events.""" def config_schema():
await super().async_added_to_hass() """Return the config schema."""
await self._subscribe_topics() return PLATFORM_SCHEMA
async def discovery_update(self, discovery_payload): def _setup_from_config(self, config):
"""Handle updated discovery message."""
config = PLATFORM_SCHEMA(discovery_payload)
self._config = 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): async def _subscribe_topics(self):
"""(Re)Subscribe to topics.""" """(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): async def async_camera_image(self):
"""Return image response.""" """Return image response."""
return self._last_image return self._last_image
@ -144,8 +114,3 @@ class MqttCamera(
def name(self): def name(self):
"""Return the name of this camera.""" """Return the name of this camera."""
return self._config[CONF_NAME] return self._config[CONF_NAME]
@property
def unique_id(self):
"""Return a unique ID."""
return self._unique_id

View file

@ -65,10 +65,7 @@ from .mixins import (
MQTT_AVAILABILITY_SCHEMA, MQTT_AVAILABILITY_SCHEMA,
MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA,
MQTT_JSON_ATTRS_SCHEMA, MQTT_JSON_ATTRS_SCHEMA,
MqttAttributes, MqttEntity,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
async_setup_entry_helper, async_setup_entry_helper,
) )
@ -267,22 +264,11 @@ async def _async_setup_entity(
async_add_entities([MqttClimate(hass, config, config_entry, discovery_data)]) async_add_entities([MqttClimate(hass, config, config_entry, discovery_data)])
class MqttClimate( class MqttClimate(MqttEntity, ClimateEntity):
MqttAttributes,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
ClimateEntity,
):
"""Representation of an MQTT climate device.""" """Representation of an MQTT climate device."""
def __init__(self, hass, config, config_entry, discovery_data): def __init__(self, hass, config, config_entry, discovery_data):
"""Initialize the climate device.""" """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._action = None
self._aux = False self._aux = False
self._away = False self._away = False
@ -297,33 +283,21 @@ class MqttClimate(
self._topic = None self._topic = None
self._value_templates = 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) @staticmethod
def config_schema():
MqttAttributes.__init__(self, config) """Return the config schema."""
MqttAvailability.__init__(self, config) return PLATFORM_SCHEMA
MqttDiscoveryUpdate.__init__(self, discovery_data, self.discovery_update)
MqttEntityDeviceInfo.__init__(self, device_config, config_entry)
async def async_added_to_hass(self): async def async_added_to_hass(self):
"""Handle being added to Home Assistant.""" """Handle being added to Home Assistant."""
await super().async_added_to_hass() await super().async_added_to_hass()
await self._subscribe_topics() 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): def _setup_from_config(self, config):
"""(Re)Setup the entity.""" """(Re)Setup the entity."""
self._config = config
self._topic = {key: config.get(key) for key in TOPIC_KEYS} self._topic = {key: config.get(key) for key in TOPIC_KEYS}
# set to None in non-optimistic mode # set to None in non-optimistic mode
@ -556,30 +530,11 @@ class MqttClimate(
self.hass, self._sub_state, topics 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 @property
def name(self): def name(self):
"""Return the name of the climate device.""" """Return the name of the climate device."""
return self._config[CONF_NAME] return self._config[CONF_NAME]
@property
def unique_id(self):
"""Return a unique ID."""
return self._unique_id
@property @property
def temperature_unit(self): def temperature_unit(self):
"""Return the unit of measurement.""" """Return the unit of measurement."""

View file

@ -52,10 +52,7 @@ from .mixins import (
MQTT_AVAILABILITY_SCHEMA, MQTT_AVAILABILITY_SCHEMA,
MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA,
MQTT_JSON_ATTRS_SCHEMA, MQTT_JSON_ATTRS_SCHEMA,
MqttAttributes, MqttEntity,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
async_setup_entry_helper, async_setup_entry_helper,
) )
@ -198,51 +195,24 @@ async def _async_setup_entity(
async_add_entities([MqttCover(hass, config, config_entry, discovery_data)]) async_add_entities([MqttCover(hass, config, config_entry, discovery_data)])
class MqttCover( class MqttCover(MqttEntity, CoverEntity):
MqttAttributes,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
CoverEntity,
):
"""Representation of a cover that can be controlled using MQTT.""" """Representation of a cover that can be controlled using MQTT."""
def __init__(self, hass, config, config_entry, discovery_data): def __init__(self, hass, config, config_entry, discovery_data):
"""Initialize the cover.""" """Initialize the cover."""
self.hass = hass
self._unique_id = config.get(CONF_UNIQUE_ID)
self._position = None self._position = None
self._state = None self._state = None
self._sub_state = None
self._optimistic = None self._optimistic = None
self._tilt_value = None self._tilt_value = None
self._tilt_optimistic = None self._tilt_optimistic = None
# Load config MqttEntity.__init__(self, hass, config, config_entry, discovery_data)
self._setup_from_config(config)
device_config = config.get(CONF_DEVICE) @staticmethod
def config_schema():
MqttAttributes.__init__(self, config) """Return the config schema."""
MqttAvailability.__init__(self, config) return PLATFORM_SCHEMA
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()
def _setup_from_config(self, config): def _setup_from_config(self, config):
self._config = config self._config = config
@ -367,20 +337,6 @@ class MqttCover(
self.hass, self._sub_state, topics 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 @property
def assumed_state(self): def assumed_state(self):
"""Return true if we do optimistic updates.""" """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]: if range_type == TILT_PAYLOAD and self._config[CONF_TILT_INVERT_STATE]:
position = max_range - position + offset position = max_range - position + offset
return position return position
@property
def unique_id(self):
"""Return a unique ID."""
return self._unique_id

View file

@ -30,10 +30,7 @@ from ..mixins import (
MQTT_AVAILABILITY_SCHEMA, MQTT_AVAILABILITY_SCHEMA,
MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA,
MQTT_JSON_ATTRS_SCHEMA, MQTT_JSON_ATTRS_SCHEMA,
MqttAttributes, MqttEntity,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
async_setup_entry_helper, async_setup_entry_helper,
) )
@ -78,46 +75,19 @@ async def _async_setup_entity(
async_add_entities([MqttDeviceTracker(hass, config, config_entry, discovery_data)]) async_add_entities([MqttDeviceTracker(hass, config, config_entry, discovery_data)])
class MqttDeviceTracker( class MqttDeviceTracker(MqttEntity, TrackerEntity):
MqttAttributes,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
TrackerEntity,
):
"""Representation of a device tracker using MQTT.""" """Representation of a device tracker using MQTT."""
def __init__(self, hass, config, config_entry, discovery_data): def __init__(self, hass, config, config_entry, discovery_data):
"""Initialize the tracker.""" """Initialize the tracker."""
self.hass = hass
self._location_name = None self._location_name = None
self._sub_state = None
self._unique_id = config.get(CONF_UNIQUE_ID)
# Load config MqttEntity.__init__(self, hass, config, config_entry, discovery_data)
self._setup_from_config(config)
device_config = config.get(CONF_DEVICE) @staticmethod
def config_schema():
MqttAttributes.__init__(self, config) """Return the config schema."""
MqttAvailability.__init__(self, config) return PLATFORM_SCHEMA_DISCOVERY
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()
def _setup_from_config(self, config): def _setup_from_config(self, config):
"""(Re)Setup the entity.""" """(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 @property
def icon(self): def icon(self):
"""Return the icon of the device.""" """Return the icon of the device."""
@ -213,11 +174,6 @@ class MqttDeviceTracker(
"""Return the name of the device tracker.""" """Return the name of the device tracker."""
return self._config.get(CONF_NAME) return self._config.get(CONF_NAME)
@property
def unique_id(self):
"""Return a unique ID."""
return self._unique_id
@property @property
def source_type(self): def source_type(self):
"""Return the source type, eg gps or router, of the device.""" """Return the source type, eg gps or router, of the device."""

View file

@ -44,10 +44,7 @@ from .mixins import (
MQTT_AVAILABILITY_SCHEMA, MQTT_AVAILABILITY_SCHEMA,
MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA,
MQTT_JSON_ATTRS_SCHEMA, MQTT_JSON_ATTRS_SCHEMA,
MqttAttributes, MqttEntity,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
async_setup_entry_helper, async_setup_entry_helper,
) )
@ -139,24 +136,15 @@ async def _async_setup_entity(
async_add_entities([MqttFan(hass, config, config_entry, discovery_data)]) async_add_entities([MqttFan(hass, config, config_entry, discovery_data)])
class MqttFan( class MqttFan(MqttEntity, FanEntity):
MqttAttributes,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
FanEntity,
):
"""A MQTT fan component.""" """A MQTT fan component."""
def __init__(self, hass, config, config_entry, discovery_data): def __init__(self, hass, config, config_entry, discovery_data):
"""Initialize the MQTT fan.""" """Initialize the MQTT fan."""
self.hass = hass
self._unique_id = config.get(CONF_UNIQUE_ID)
self._state = False self._state = False
self._speed = None self._speed = None
self._oscillation = None self._oscillation = None
self._supported_features = 0 self._supported_features = 0
self._sub_state = None
self._topic = None self._topic = None
self._payload = None self._payload = None
@ -165,30 +153,12 @@ class MqttFan(
self._optimistic_oscillation = None self._optimistic_oscillation = None
self._optimistic_speed = None self._optimistic_speed = None
# Load config MqttEntity.__init__(self, hass, config, config_entry, discovery_data)
self._setup_from_config(config)
device_config = config.get(CONF_DEVICE) @staticmethod
def config_schema():
MqttAttributes.__init__(self, config) """Return the config schema."""
MqttAvailability.__init__(self, config) return PLATFORM_SCHEMA
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()
def _setup_from_config(self, config): def _setup_from_config(self, config):
"""(Re)Setup the entity.""" """(Re)Setup the entity."""
@ -312,20 +282,6 @@ class MqttFan(
self.hass, self._sub_state, topics 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 @property
def assumed_state(self): def assumed_state(self):
"""Return true if we do optimistic updates.""" """Return true if we do optimistic updates."""
@ -444,8 +400,3 @@ class MqttFan(
if self._optimistic_oscillation: if self._optimistic_oscillation:
self._oscillation = oscillating self._oscillation = oscillating
self.async_write_ha_state() self.async_write_ha_state()
@property
def unique_id(self):
"""Return a unique ID."""
return self._unique_id

View file

@ -38,10 +38,7 @@ from ..mixins import (
MQTT_AVAILABILITY_SCHEMA, MQTT_AVAILABILITY_SCHEMA,
MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA,
MQTT_JSON_ATTRS_SCHEMA, MQTT_JSON_ATTRS_SCHEMA,
MqttAttributes, MqttEntity,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
) )
from .schema import MQTT_LIGHT_SCHEMA_SCHEMA 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)]) async_add_entities([MqttLight(hass, config, config_entry, discovery_data)])
class MqttLight( class MqttLight(MqttEntity, LightEntity, RestoreEntity):
MqttAttributes,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
LightEntity,
RestoreEntity,
):
"""Representation of a MQTT light.""" """Representation of a MQTT light."""
def __init__(self, hass, config, config_entry, discovery_data): def __init__(self, hass, config, config_entry, discovery_data):
"""Initialize MQTT light.""" """Initialize MQTT light."""
self.hass = hass
self._state = False self._state = False
self._sub_state = None
self._brightness = None self._brightness = None
self._hs = None self._hs = None
self._color_temp = None self._color_temp = None
@ -196,32 +184,13 @@ class MqttLight(
self._optimistic_hs = False self._optimistic_hs = False
self._optimistic_white_value = False self._optimistic_white_value = False
self._optimistic_xy = False self._optimistic_xy = False
self._unique_id = config.get(CONF_UNIQUE_ID)
# Load config MqttEntity.__init__(self, hass, config, config_entry, discovery_data)
self._setup_from_config(config)
device_config = config.get(CONF_DEVICE) @staticmethod
def config_schema():
MqttAttributes.__init__(self, config) """Return the config schema."""
MqttAvailability.__init__(self, config) return PLATFORM_SCHEMA_BASIC
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()
def _setup_from_config(self, config): def _setup_from_config(self, config):
"""(Re)Setup the entity.""" """(Re)Setup the entity."""
@ -525,15 +494,6 @@ class MqttLight(
self.hass, self._sub_state, topics 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 @property
def brightness(self): def brightness(self):
"""Return the brightness of this light between 0..255.""" """Return the brightness of this light between 0..255."""
@ -580,21 +540,11 @@ class MqttLight(
return white_value return white_value
return None return None
@property
def should_poll(self):
"""No polling needed for a MQTT light."""
return False
@property @property
def name(self): def name(self):
"""Return the name of the device if any.""" """Return the name of the device if any."""
return self._config[CONF_NAME] return self._config[CONF_NAME]
@property
def unique_id(self):
"""Return a unique ID."""
return self._unique_id
@property @property
def is_on(self): def is_on(self):
"""Return true if device is on.""" """Return true if device is on."""

View file

@ -49,10 +49,7 @@ from ..mixins import (
MQTT_AVAILABILITY_SCHEMA, MQTT_AVAILABILITY_SCHEMA,
MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA,
MQTT_JSON_ATTRS_SCHEMA, MQTT_JSON_ATTRS_SCHEMA,
MqttAttributes, MqttEntity,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
) )
from .schema import MQTT_LIGHT_SCHEMA_SCHEMA from .schema import MQTT_LIGHT_SCHEMA_SCHEMA
from .schema_basic import CONF_BRIGHTNESS_SCALE 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)]) async_add_entities([MqttLightJson(config, config_entry, discovery_data)])
class MqttLightJson( class MqttLightJson(MqttEntity, LightEntity, RestoreEntity):
MqttAttributes,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
LightEntity,
RestoreEntity,
):
"""Representation of a MQTT JSON light.""" """Representation of a MQTT JSON light."""
def __init__(self, config, config_entry, discovery_data): def __init__(self, config, config_entry, discovery_data):
"""Initialize MQTT JSON light.""" """Initialize MQTT JSON light."""
self._state = False self._state = False
self._sub_state = None
self._supported_features = 0 self._supported_features = 0
self._topic = None self._topic = None
@ -154,32 +143,13 @@ class MqttLightJson(
self._hs = None self._hs = None
self._white_value = None self._white_value = None
self._flash_times = None self._flash_times = None
self._unique_id = config.get(CONF_UNIQUE_ID)
# Load config MqttEntity.__init__(self, None, config, config_entry, discovery_data)
self._setup_from_config(config)
device_config = config.get(CONF_DEVICE) @staticmethod
def config_schema():
MqttAttributes.__init__(self, config) """Return the config schema."""
MqttAvailability.__init__(self, config) return PLATFORM_SCHEMA_JSON
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()
def _setup_from_config(self, config): def _setup_from_config(self, config):
"""(Re)Setup the entity.""" """(Re)Setup the entity."""
@ -314,15 +284,6 @@ class MqttLightJson(
if last_state.attributes.get(ATTR_WHITE_VALUE): if last_state.attributes.get(ATTR_WHITE_VALUE):
self._white_value = 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 @property
def brightness(self): def brightness(self):
"""Return the brightness of this light between 0..255.""" """Return the brightness of this light between 0..255."""
@ -363,21 +324,11 @@ class MqttLightJson(
"""Return the white property.""" """Return the white property."""
return self._white_value return self._white_value
@property
def should_poll(self):
"""No polling needed for a MQTT light."""
return False
@property @property
def name(self): def name(self):
"""Return the name of the device if any.""" """Return the name of the device if any."""
return self._config[CONF_NAME] return self._config[CONF_NAME]
@property
def unique_id(self):
"""Return a unique ID."""
return self._unique_id
@property @property
def is_on(self): def is_on(self):
"""Return true if device is on.""" """Return true if device is on."""

View file

@ -40,10 +40,7 @@ from ..mixins import (
MQTT_AVAILABILITY_SCHEMA, MQTT_AVAILABILITY_SCHEMA,
MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA,
MQTT_JSON_ATTRS_SCHEMA, MQTT_JSON_ATTRS_SCHEMA,
MqttAttributes, MqttEntity,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
) )
from .schema import MQTT_LIGHT_SCHEMA_SCHEMA 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)]) async_add_entities([MqttLightTemplate(config, config_entry, discovery_data)])
class MqttLightTemplate( class MqttLightTemplate(MqttEntity, LightEntity, RestoreEntity):
MqttAttributes,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
LightEntity,
RestoreEntity,
):
"""Representation of a MQTT Template light.""" """Representation of a MQTT Template light."""
def __init__(self, config, config_entry, discovery_data): def __init__(self, config, config_entry, discovery_data):
"""Initialize a MQTT Template light.""" """Initialize a MQTT Template light."""
self._state = False self._state = False
self._sub_state = None
self._topics = None self._topics = None
self._templates = None self._templates = None
@ -128,32 +117,13 @@ class MqttLightTemplate(
self._white_value = None self._white_value = None
self._hs = None self._hs = None
self._effect = None self._effect = None
self._unique_id = config.get(CONF_UNIQUE_ID)
# Load config MqttEntity.__init__(self, None, config, config_entry, discovery_data)
self._setup_from_config(config)
device_config = config.get(CONF_DEVICE) @staticmethod
def config_schema():
MqttAttributes.__init__(self, config) """Return the config schema."""
MqttAvailability.__init__(self, config) return PLATFORM_SCHEMA_TEMPLATE
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()
def _setup_from_config(self, config): def _setup_from_config(self, config):
"""(Re)Setup the entity.""" """(Re)Setup the entity."""
@ -299,15 +269,6 @@ class MqttLightTemplate(
if last_state.attributes.get(ATTR_WHITE_VALUE): if last_state.attributes.get(ATTR_WHITE_VALUE):
self._white_value = 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 @property
def brightness(self): def brightness(self):
"""Return the brightness of this light between 0..255.""" """Return the brightness of this light between 0..255."""
@ -338,24 +299,11 @@ class MqttLightTemplate(
"""Return the white property.""" """Return the white property."""
return self._white_value 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 @property
def name(self): def name(self):
"""Return the name of the entity.""" """Return the name of the entity."""
return self._config[CONF_NAME] return self._config[CONF_NAME]
@property
def unique_id(self):
"""Return a unique ID."""
return self._unique_id
@property @property
def is_on(self): def is_on(self):
"""Return True if entity is on.""" """Return True if entity is on."""

View file

@ -33,10 +33,7 @@ from .mixins import (
MQTT_AVAILABILITY_SCHEMA, MQTT_AVAILABILITY_SCHEMA,
MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA,
MQTT_JSON_ATTRS_SCHEMA, MQTT_JSON_ATTRS_SCHEMA,
MqttAttributes, MqttEntity,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
async_setup_entry_helper, async_setup_entry_helper,
) )
@ -101,47 +98,20 @@ async def _async_setup_entity(
async_add_entities([MqttLock(hass, config, config_entry, discovery_data)]) async_add_entities([MqttLock(hass, config, config_entry, discovery_data)])
class MqttLock( class MqttLock(MqttEntity, LockEntity):
MqttAttributes,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
LockEntity,
):
"""Representation of a lock that can be toggled using MQTT.""" """Representation of a lock that can be toggled using MQTT."""
def __init__(self, hass, config, config_entry, discovery_data): def __init__(self, hass, config, config_entry, discovery_data):
"""Initialize the lock.""" """Initialize the lock."""
self.hass = hass
self._unique_id = config.get(CONF_UNIQUE_ID)
self._state = False self._state = False
self._sub_state = None
self._optimistic = False self._optimistic = False
# Load config MqttEntity.__init__(self, hass, config, config_entry, discovery_data)
self._setup_from_config(config)
device_config = config.get(CONF_DEVICE) @staticmethod
def config_schema():
MqttAttributes.__init__(self, config) """Return the config schema."""
MqttAvailability.__init__(self, config) return PLATFORM_SCHEMA
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()
def _setup_from_config(self, config): def _setup_from_config(self, config):
"""(Re)Setup the entity.""" """(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 @property
def name(self): def name(self):
"""Return the name of the lock.""" """Return the name of the lock."""
return self._config[CONF_NAME] return self._config[CONF_NAME]
@property
def unique_id(self):
"""Return a unique ID."""
return self._unique_id
@property @property
def is_locked(self): def is_locked(self):
"""Return true if lock is locked.""" """Return true if lock is locked."""

View file

@ -1,11 +1,12 @@
"""MQTT component mixins and helpers.""" """MQTT component mixins and helpers."""
from abc import abstractmethod
import json import json
import logging import logging
from typing import Optional from typing import Optional
import voluptuous as vol 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.core import callback
from homeassistant.helpers import config_validation as cv from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.dispatcher import ( from homeassistant.helpers.dispatcher import (
@ -15,7 +16,7 @@ from homeassistant.helpers.dispatcher import (
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.helpers.typing import ConfigType 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 ( from .const import (
ATTR_DISCOVERY_HASH, ATTR_DISCOVERY_HASH,
ATTR_DISCOVERY_PAYLOAD, ATTR_DISCOVERY_PAYLOAD,
@ -493,3 +494,73 @@ class MqttEntityDeviceInfo(Entity):
def device_info(self): def device_info(self):
"""Return a device description for device registry.""" """Return a device description for device registry."""
return device_info_from_config(self._device_config) 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

View file

@ -33,10 +33,7 @@ from .mixins import (
MQTT_AVAILABILITY_SCHEMA, MQTT_AVAILABILITY_SCHEMA,
MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA,
MQTT_JSON_ATTRS_SCHEMA, MQTT_JSON_ATTRS_SCHEMA,
MqttAttributes, MqttEntity,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
async_setup_entry_helper, async_setup_entry_helper,
) )
@ -84,47 +81,27 @@ async def _async_setup_entity(
async_add_entities([MqttNumber(config, config_entry, discovery_data)]) async_add_entities([MqttNumber(config, config_entry, discovery_data)])
class MqttNumber( class MqttNumber(MqttEntity, NumberEntity, RestoreEntity):
MqttAttributes,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
NumberEntity,
RestoreEntity,
):
"""representation of an MQTT number.""" """representation of an MQTT number."""
def __init__(self, config, config_entry, discovery_data): def __init__(self, config, config_entry, discovery_data):
"""Initialize the MQTT Number.""" """Initialize the MQTT Number."""
self._config = config
self._sub_state = None self._sub_state = None
self._current_number = None self._current_number = None
self._optimistic = config.get(CONF_OPTIMISTIC) self._optimistic = config.get(CONF_OPTIMISTIC)
self._unique_id = config.get(CONF_UNIQUE_ID) self._unique_id = config.get(CONF_UNIQUE_ID)
device_config = config.get(CONF_DEVICE)
NumberEntity.__init__(self) NumberEntity.__init__(self)
MqttAttributes.__init__(self, config) MqttEntity.__init__(self, None, config, config_entry, discovery_data)
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): @staticmethod
"""Subscribe MQTT events.""" def config_schema():
await super().async_added_to_hass() """Return the config schema."""
await self._subscribe_topics() return PLATFORM_SCHEMA
async def discovery_update(self, discovery_payload): def _setup_from_config(self, config):
"""Handle updated discovery message."""
config = PLATFORM_SCHEMA(discovery_payload)
self._config = 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): async def _subscribe_topics(self):
"""(Re)Subscribe to topics.""" """(Re)Subscribe to topics."""
@ -165,15 +142,6 @@ class MqttNumber(
if last_state: if last_state:
self._current_number = last_state.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 @property
def value(self): def value(self):
"""Return the current value.""" """Return the current value."""
@ -203,16 +171,6 @@ class MqttNumber(
"""Return the name of this number.""" """Return the name of this number."""
return self._config[CONF_NAME] 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 @property
def assumed_state(self): def assumed_state(self):
"""Return true if we do optimistic updates.""" """Return true if we do optimistic updates."""

View file

@ -33,10 +33,8 @@ from .mixins import (
MQTT_AVAILABILITY_SCHEMA, MQTT_AVAILABILITY_SCHEMA,
MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA,
MQTT_JSON_ATTRS_SCHEMA, MQTT_JSON_ATTRS_SCHEMA,
MqttAttributes,
MqttAvailability, MqttAvailability,
MqttDiscoveryUpdate, MqttEntity,
MqttEntityDeviceInfo,
async_setup_entry_helper, async_setup_entry_helper,
) )
@ -88,17 +86,12 @@ async def _async_setup_entity(
async_add_entities([MqttSensor(hass, config, config_entry, discovery_data)]) async_add_entities([MqttSensor(hass, config, config_entry, discovery_data)])
class MqttSensor( class MqttSensor(MqttEntity, Entity):
MqttAttributes, MqttAvailability, MqttDiscoveryUpdate, MqttEntityDeviceInfo, Entity
):
"""Representation of a sensor that can be updated using MQTT.""" """Representation of a sensor that can be updated using MQTT."""
def __init__(self, hass, config, config_entry, discovery_data): def __init__(self, hass, config, config_entry, discovery_data):
"""Initialize the sensor.""" """Initialize the sensor."""
self.hass = hass
self._unique_id = config.get(CONF_UNIQUE_ID)
self._state = None self._state = None
self._sub_state = None
self._expiration_trigger = None self._expiration_trigger = None
expire_after = config.get(CONF_EXPIRE_AFTER) expire_after = config.get(CONF_EXPIRE_AFTER)
@ -107,30 +100,12 @@ class MqttSensor(
else: else:
self._expired = None self._expired = None
# Load config MqttEntity.__init__(self, hass, config, config_entry, discovery_data)
self._setup_from_config(config)
device_config = config.get(CONF_DEVICE) @staticmethod
def config_schema():
MqttAttributes.__init__(self, config) """Return the config schema."""
MqttAvailability.__init__(self, config) return PLATFORM_SCHEMA
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()
def _setup_from_config(self, config): def _setup_from_config(self, config):
"""(Re)Setup the entity.""" """(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 @callback
def _value_is_expired(self, *_): def _value_is_expired(self, *_):
"""Triggered when value is expired.""" """Triggered when value is expired."""
@ -201,11 +167,6 @@ class MqttSensor(
self._expired = True self._expired = True
self.async_write_ha_state() self.async_write_ha_state()
@property
def should_poll(self):
"""No polling needed."""
return False
@property @property
def name(self): def name(self):
"""Return the name of the sensor.""" """Return the name of the sensor."""
@ -226,11 +187,6 @@ class MqttSensor(
"""Return the state of the entity.""" """Return the state of the entity."""
return self._state return self._state
@property
def unique_id(self):
"""Return a unique ID."""
return self._unique_id
@property @property
def icon(self): def icon(self):
"""Return the icon.""" """Return the icon."""

View file

@ -38,10 +38,7 @@ from .mixins import (
MQTT_AVAILABILITY_SCHEMA, MQTT_AVAILABILITY_SCHEMA,
MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA,
MQTT_JSON_ATTRS_SCHEMA, MQTT_JSON_ATTRS_SCHEMA,
MqttAttributes, MqttEntity,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
async_setup_entry_helper, async_setup_entry_helper,
) )
@ -97,51 +94,23 @@ async def _async_setup_entity(
async_add_entities([MqttSwitch(hass, config, config_entry, discovery_data)]) async_add_entities([MqttSwitch(hass, config, config_entry, discovery_data)])
class MqttSwitch( class MqttSwitch(MqttEntity, SwitchEntity, RestoreEntity):
MqttAttributes,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
SwitchEntity,
RestoreEntity,
):
"""Representation of a switch that can be toggled using MQTT.""" """Representation of a switch that can be toggled using MQTT."""
def __init__(self, hass, config, config_entry, discovery_data): def __init__(self, hass, config, config_entry, discovery_data):
"""Initialize the MQTT switch.""" """Initialize the MQTT switch."""
self.hass = hass
self._state = False self._state = False
self._sub_state = None
self._state_on = None self._state_on = None
self._state_off = None self._state_off = None
self._optimistic = None self._optimistic = None
self._unique_id = config.get(CONF_UNIQUE_ID)
# Load config MqttEntity.__init__(self, hass, config, config_entry, discovery_data)
self._setup_from_config(config)
device_config = config.get(CONF_DEVICE) @staticmethod
def config_schema():
MqttAttributes.__init__(self, config) """Return the config schema."""
MqttAvailability.__init__(self, config) return PLATFORM_SCHEMA
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()
def _setup_from_config(self, config): def _setup_from_config(self, config):
"""(Re)Setup the entity.""" """(Re)Setup the entity."""
@ -198,20 +167,6 @@ class MqttSwitch(
if last_state: if last_state:
self._state = last_state.state == STATE_ON 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 @property
def name(self): def name(self):
"""Return the name of the switch.""" """Return the name of the switch."""
@ -227,11 +182,6 @@ class MqttSwitch(
"""Return true if we do optimistic updates.""" """Return true if we do optimistic updates."""
return self._optimistic return self._optimistic
@property
def unique_id(self):
"""Return a unique ID."""
return self._unique_id
@property @property
def icon(self): def icon(self):
"""Return the icon.""" """Return the icon."""

View file

@ -35,10 +35,7 @@ from ..mixins import (
MQTT_AVAILABILITY_SCHEMA, MQTT_AVAILABILITY_SCHEMA,
MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA,
MQTT_JSON_ATTRS_SCHEMA, MQTT_JSON_ATTRS_SCHEMA,
MqttAttributes, MqttEntity,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
) )
from .schema import MQTT_VACUUM_SCHEMA, services_to_strings, strings_to_services 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)]) async_add_entities([MqttVacuum(config, config_entry, discovery_data)])
class MqttVacuum( class MqttVacuum(MqttEntity, VacuumEntity):
MqttAttributes,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
VacuumEntity,
):
"""Representation of a MQTT-controlled legacy vacuum.""" """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.""" """Initialize the vacuum."""
self._cleaning = False self._cleaning = False
self._charging = False self._charging = False
@ -195,18 +186,13 @@ class MqttVacuum(
self._battery_level = 0 self._battery_level = 0
self._fan_speed = "unknown" self._fan_speed = "unknown"
self._fan_speed_list = [] self._fan_speed_list = []
self._sub_state = None
self._unique_id = config.get(CONF_UNIQUE_ID)
# Load config MqttEntity.__init__(self, None, config, config_entry, discovery_data)
self._setup_from_config(config)
device_config = config.get(CONF_DEVICE) @staticmethod
def config_schema():
MqttAttributes.__init__(self, config) """Return the config schema."""
MqttAvailability.__init__(self, config) return PLATFORM_SCHEMA_LEGACY
MqttDiscoveryUpdate.__init__(self, discovery_info, self.discovery_update)
MqttEntityDeviceInfo.__init__(self, device_config, config_entry)
def _setup_from_config(self, config): def _setup_from_config(self, config):
self._name = config[CONF_NAME] 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): async def _subscribe_topics(self):
"""(Re)Subscribe to topics.""" """(Re)Subscribe to topics."""
for tpl in self._templates.values(): for tpl in self._templates.values():
@ -384,21 +346,11 @@ class MqttVacuum(
"""Return the name of the vacuum.""" """Return the name of the vacuum."""
return self._name return self._name
@property
def should_poll(self):
"""No polling needed for an MQTT vacuum."""
return False
@property @property
def is_on(self): def is_on(self):
"""Return true if vacuum is on.""" """Return true if vacuum is on."""
return self._cleaning return self._cleaning
@property
def unique_id(self):
"""Return a unique ID."""
return self._unique_id
@property @property
def status(self): def status(self):
"""Return a status string for the vacuum.""" """Return a status string for the vacuum."""

View file

@ -39,10 +39,7 @@ from ..mixins import (
MQTT_AVAILABILITY_SCHEMA, MQTT_AVAILABILITY_SCHEMA,
MQTT_ENTITY_DEVICE_INFO_SCHEMA, MQTT_ENTITY_DEVICE_INFO_SCHEMA,
MQTT_JSON_ATTRS_SCHEMA, MQTT_JSON_ATTRS_SCHEMA,
MqttAttributes, MqttEntity,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
) )
from .schema import MQTT_VACUUM_SCHEMA, services_to_strings, strings_to_services 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)]) async_add_entities([MqttStateVacuum(config, config_entry, discovery_data)])
class MqttStateVacuum( class MqttStateVacuum(MqttEntity, StateVacuumEntity):
MqttAttributes,
MqttAvailability,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
StateVacuumEntity,
):
"""Representation of a MQTT-controlled state vacuum.""" """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.""" """Initialize the vacuum."""
self._state = None self._state = None
self._state_attrs = {} self._state_attrs = {}
self._fan_speed_list = [] self._fan_speed_list = []
self._sub_state = None
self._unique_id = config.get(CONF_UNIQUE_ID)
# Load config MqttEntity.__init__(self, None, config, config_entry, discovery_data)
self._setup_from_config(config)
device_config = config.get(CONF_DEVICE) @staticmethod
def config_schema():
MqttAttributes.__init__(self, config) """Return the config schema."""
MqttAvailability.__init__(self, config) return PLATFORM_SCHEMA_STATE
MqttDiscoveryUpdate.__init__(self, discovery_info, self.discovery_update)
MqttEntityDeviceInfo.__init__(self, device_config, config_entry)
def _setup_from_config(self, config): def _setup_from_config(self, config):
self._config = 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): async def _subscribe_topics(self):
"""(Re)Subscribe to topics.""" """(Re)Subscribe to topics."""
topics = {} topics = {}
@ -270,11 +232,6 @@ class MqttStateVacuum(
"""Return state of vacuum.""" """Return state of vacuum."""
return self._state return self._state
@property
def unique_id(self):
"""Return a unique ID."""
return self._unique_id
@property @property
def fan_speed(self): def fan_speed(self):
"""Return fan speed of the vacuum.""" """Return fan speed of the vacuum."""