Use _attr_ for MQTT vacuum (#81534)

* Use `_attr_` for MQTT vacuum

* Remove unneeded properties

* Follow-up comment

* Remove default value
This commit is contained in:
Jan Bouwhuis 2022-11-08 18:48:08 +01:00 committed by GitHub
parent 3cc9ecf1dc
commit b364ef98a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 95 deletions

View File

@ -173,14 +173,13 @@ class MqttVacuum(MqttEntity, VacuumEntity):
def __init__(self, hass, config, config_entry, discovery_data): def __init__(self, hass, config, config_entry, discovery_data):
"""Initialize the vacuum.""" """Initialize the vacuum."""
self._cleaning = False self._attr_battery_level = 0
self._attr_is_on = False
self._attr_fan_speed = "unknown"
self._charging = False self._charging = False
self._docked = False self._docked = False
self._error = None self._error = None
self._status = "Unknown"
self._battery_level = 0
self._fan_speed = "unknown"
self._fan_speed_list = []
MqttEntity.__init__(self, hass, config, config_entry, discovery_data) MqttEntity.__init__(self, hass, config, config_entry, discovery_data)
@ -190,11 +189,12 @@ class MqttVacuum(MqttEntity, VacuumEntity):
return DISCOVERY_SCHEMA_LEGACY return DISCOVERY_SCHEMA_LEGACY
def _setup_from_config(self, config): def _setup_from_config(self, config):
"""(Re)Setup the entity."""
supported_feature_strings = config[CONF_SUPPORTED_FEATURES] supported_feature_strings = config[CONF_SUPPORTED_FEATURES]
self._supported_features = strings_to_services( self._attr_supported_features = strings_to_services(
supported_feature_strings, STRING_TO_SERVICE supported_feature_strings, STRING_TO_SERVICE
) )
self._fan_speed_list = config[CONF_FAN_SPEED_LIST] self._attr_fan_speed_list = config[CONF_FAN_SPEED_LIST]
self._qos = config[CONF_QOS] self._qos = config[CONF_QOS]
self._retain = config[CONF_RETAIN] self._retain = config[CONF_RETAIN]
self._encoding = config[CONF_ENCODING] or None self._encoding = config[CONF_ENCODING] or None
@ -258,7 +258,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
msg.payload, PayloadSentinel.DEFAULT msg.payload, PayloadSentinel.DEFAULT
) )
if battery_level and battery_level is not PayloadSentinel.DEFAULT: if battery_level and battery_level is not PayloadSentinel.DEFAULT:
self._battery_level = int(battery_level) self._attr_battery_level = max(0, min(100, int(battery_level)))
if ( if (
msg.topic == self._state_topics[CONF_CHARGING_TOPIC] msg.topic == self._state_topics[CONF_CHARGING_TOPIC]
@ -282,7 +282,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
msg.payload, PayloadSentinel.DEFAULT msg.payload, PayloadSentinel.DEFAULT
) )
if cleaning and cleaning is not PayloadSentinel.DEFAULT: if cleaning and cleaning is not PayloadSentinel.DEFAULT:
self._cleaning = cv.boolean(cleaning) self._attr_is_on = cv.boolean(cleaning)
if ( if (
msg.topic == self._state_topics[CONF_DOCKED_TOPIC] msg.topic == self._state_topics[CONF_DOCKED_TOPIC]
@ -310,15 +310,15 @@ class MqttVacuum(MqttEntity, VacuumEntity):
if self._docked: if self._docked:
if self._charging: if self._charging:
self._status = "Docked & Charging" self._attr_status = "Docked & Charging"
else: else:
self._status = "Docked" self._attr_status = "Docked"
elif self._cleaning: elif self.is_on:
self._status = "Cleaning" self._attr_status = "Cleaning"
elif self._error: elif self._error:
self._status = f"Error: {self._error}" self._attr_status = f"Error: {self._error}"
else: else:
self._status = "Stopped" self._attr_status = "Stopped"
if ( if (
msg.topic == self._state_topics[CONF_FAN_SPEED_TOPIC] msg.topic == self._state_topics[CONF_FAN_SPEED_TOPIC]
@ -330,7 +330,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
msg.payload, PayloadSentinel.DEFAULT msg.payload, PayloadSentinel.DEFAULT
) )
if fan_speed and fan_speed is not PayloadSentinel.DEFAULT: if fan_speed and fan_speed is not PayloadSentinel.DEFAULT:
self._fan_speed = fan_speed self._attr_fan_speed = fan_speed
get_mqtt_data(self.hass).state_write_requests.write_state_request(self) get_mqtt_data(self.hass).state_write_requests.write_state_request(self)
@ -353,31 +353,6 @@ class MqttVacuum(MqttEntity, VacuumEntity):
"""(Re)Subscribe to topics.""" """(Re)Subscribe to topics."""
await subscription.async_subscribe_topics(self.hass, self._sub_state) await subscription.async_subscribe_topics(self.hass, self._sub_state)
@property
def is_on(self):
"""Return true if vacuum is on."""
return self._cleaning
@property
def status(self):
"""Return a status string for the vacuum."""
return self._status
@property
def fan_speed(self):
"""Return the status of the vacuum."""
return self._fan_speed
@property
def fan_speed_list(self):
"""Return the status of the vacuum."""
return self._fan_speed_list
@property
def battery_level(self):
"""Return the status of the vacuum."""
return max(0, min(100, self._battery_level))
@property @property
def battery_icon(self): def battery_icon(self):
"""Return the battery icon for the vacuum cleaner. """Return the battery icon for the vacuum cleaner.
@ -388,11 +363,6 @@ class MqttVacuum(MqttEntity, VacuumEntity):
battery_level=self.battery_level, charging=self._charging battery_level=self.battery_level, charging=self._charging
) )
@property
def supported_features(self):
"""Flag supported features."""
return self._supported_features
async def async_turn_on(self, **kwargs): async def async_turn_on(self, **kwargs):
"""Turn the vacuum on.""" """Turn the vacuum on."""
if self.supported_features & VacuumEntityFeature.TURN_ON == 0: if self.supported_features & VacuumEntityFeature.TURN_ON == 0:
@ -405,7 +375,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
self._retain, self._retain,
self._encoding, self._encoding,
) )
self._status = "Cleaning" self._attr_status = "Cleaning"
self.async_write_ha_state() self.async_write_ha_state()
async def async_turn_off(self, **kwargs): async def async_turn_off(self, **kwargs):
@ -420,7 +390,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
self._retain, self._retain,
self._encoding, self._encoding,
) )
self._status = "Turning Off" self._attr_status = "Turning Off"
self.async_write_ha_state() self.async_write_ha_state()
async def async_stop(self, **kwargs): async def async_stop(self, **kwargs):
@ -435,7 +405,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
self._retain, self._retain,
self._encoding, self._encoding,
) )
self._status = "Stopping the current task" self._attr_status = "Stopping the current task"
self.async_write_ha_state() self.async_write_ha_state()
async def async_clean_spot(self, **kwargs): async def async_clean_spot(self, **kwargs):
@ -450,7 +420,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
self._retain, self._retain,
self._encoding, self._encoding,
) )
self._status = "Cleaning spot" self._attr_status = "Cleaning spot"
self.async_write_ha_state() self.async_write_ha_state()
async def async_locate(self, **kwargs): async def async_locate(self, **kwargs):
@ -465,7 +435,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
self._retain, self._retain,
self._encoding, self._encoding,
) )
self._status = "Hi, I'm over here!" self._attr_status = "Hi, I'm over here!"
self.async_write_ha_state() self.async_write_ha_state()
async def async_start_pause(self, **kwargs): async def async_start_pause(self, **kwargs):
@ -480,7 +450,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
self._retain, self._retain,
self._encoding, self._encoding,
) )
self._status = "Pausing/Resuming cleaning..." self._attr_status = "Pausing/Resuming cleaning..."
self.async_write_ha_state() self.async_write_ha_state()
async def async_return_to_base(self, **kwargs): async def async_return_to_base(self, **kwargs):
@ -495,14 +465,14 @@ class MqttVacuum(MqttEntity, VacuumEntity):
self._retain, self._retain,
self._encoding, self._encoding,
) )
self._status = "Returning home..." self._attr_status = "Returning home..."
self.async_write_ha_state() self.async_write_ha_state()
async def async_set_fan_speed(self, fan_speed, **kwargs): async def async_set_fan_speed(self, fan_speed, **kwargs):
"""Set fan speed.""" """Set fan speed."""
if ( if (
self.supported_features & VacuumEntityFeature.FAN_SPEED == 0 self.supported_features & VacuumEntityFeature.FAN_SPEED == 0
) or fan_speed not in self._fan_speed_list: ) or fan_speed not in self.fan_speed_list:
return None return None
await self.async_publish( await self.async_publish(
@ -512,7 +482,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
self._retain, self._retain,
self._encoding, self._encoding,
) )
self._status = f"Setting fan to {fan_speed}..." self._attr_status = f"Setting fan to {fan_speed}..."
self.async_write_ha_state() self.async_write_ha_state()
async def async_send_command(self, command, params=None, **kwargs): async def async_send_command(self, command, params=None, **kwargs):
@ -532,5 +502,5 @@ class MqttVacuum(MqttEntity, VacuumEntity):
self._retain, self._retain,
self._encoding, self._encoding,
) )
self._status = f"Sending command {message}..." self._attr_status = f"Sending command {message}..."
self.async_write_ha_state() self.async_write_ha_state()

View File

@ -161,9 +161,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
def __init__(self, hass, config, config_entry, discovery_data): def __init__(self, hass, config, config_entry, discovery_data):
"""Initialize the vacuum.""" """Initialize the vacuum."""
self._state = None
self._state_attrs = {} self._state_attrs = {}
self._fan_speed_list = []
MqttEntity.__init__(self, hass, config, config_entry, discovery_data) MqttEntity.__init__(self, hass, config, config_entry, discovery_data)
@ -173,11 +171,12 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
return DISCOVERY_SCHEMA_STATE return DISCOVERY_SCHEMA_STATE
def _setup_from_config(self, config): def _setup_from_config(self, config):
"""(Re)Setup the entity."""
supported_feature_strings = config[CONF_SUPPORTED_FEATURES] supported_feature_strings = config[CONF_SUPPORTED_FEATURES]
self._supported_features = strings_to_services( self._attr_supported_features = strings_to_services(
supported_feature_strings, STRING_TO_SERVICE supported_feature_strings, STRING_TO_SERVICE
) )
self._fan_speed_list = config[CONF_FAN_SPEED_LIST] self._attr_fan_speed_list = config[CONF_FAN_SPEED_LIST]
self._command_topic = config.get(CONF_COMMAND_TOPIC) self._command_topic = config.get(CONF_COMMAND_TOPIC)
self._set_fan_speed_topic = config.get(CONF_SET_FAN_SPEED_TOPIC) self._set_fan_speed_topic = config.get(CONF_SET_FAN_SPEED_TOPIC)
self._send_command_topic = config.get(CONF_SEND_COMMAND_TOPIC) self._send_command_topic = config.get(CONF_SEND_COMMAND_TOPIC)
@ -194,6 +193,12 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
) )
} }
def _update_state_attributes(self, payload):
"""Update the entity state attributes."""
self._state_attrs.update(payload)
self._attr_fan_speed = self._state_attrs.get(FAN_SPEED, 0)
self._attr_battery_level = max(0, min(100, self._state_attrs.get(BATTERY, 0)))
def _prepare_subscribe_topics(self): def _prepare_subscribe_topics(self):
"""(Re)Subscribe to topics.""" """(Re)Subscribe to topics."""
topics = {} topics = {}
@ -206,11 +211,11 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
if STATE in payload and ( if STATE in payload and (
payload[STATE] in POSSIBLE_STATES or payload[STATE] is None payload[STATE] in POSSIBLE_STATES or payload[STATE] is None
): ):
self._state = ( self._attr_state = (
POSSIBLE_STATES[payload[STATE]] if payload[STATE] else None POSSIBLE_STATES[payload[STATE]] if payload[STATE] else None
) )
del payload[STATE] del payload[STATE]
self._state_attrs.update(payload) self._update_state_attributes(payload)
get_mqtt_data(self.hass).state_write_requests.write_state_request(self) get_mqtt_data(self.hass).state_write_requests.write_state_request(self)
if self._config.get(CONF_STATE_TOPIC): if self._config.get(CONF_STATE_TOPIC):
@ -228,31 +233,6 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
"""(Re)Subscribe to topics.""" """(Re)Subscribe to topics."""
await subscription.async_subscribe_topics(self.hass, self._sub_state) await subscription.async_subscribe_topics(self.hass, self._sub_state)
@property
def state(self):
"""Return state of vacuum."""
return self._state
@property
def fan_speed(self):
"""Return fan speed of the vacuum."""
return self._state_attrs.get(FAN_SPEED, 0)
@property
def fan_speed_list(self):
"""Return fan speed list of the vacuum."""
return self._fan_speed_list
@property
def battery_level(self):
"""Return battery level of the vacuum."""
return max(0, min(100, self._state_attrs.get(BATTERY, 0)))
@property
def supported_features(self):
"""Flag supported features."""
return self._supported_features
async def async_start(self): async def async_start(self):
"""Start the vacuum.""" """Start the vacuum."""
if self.supported_features & VacuumEntityFeature.START == 0: if self.supported_features & VacuumEntityFeature.START == 0:
@ -268,7 +248,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
async def async_pause(self): async def async_pause(self):
"""Pause the vacuum.""" """Pause the vacuum."""
if self.supported_features & VacuumEntityFeature.PAUSE == 0: if self.supported_features & VacuumEntityFeature.PAUSE == 0:
return None return
await self.async_publish( await self.async_publish(
self._command_topic, self._command_topic,
self._config[CONF_PAYLOAD_PAUSE], self._config[CONF_PAYLOAD_PAUSE],
@ -280,7 +260,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
async def async_stop(self, **kwargs): async def async_stop(self, **kwargs):
"""Stop the vacuum.""" """Stop the vacuum."""
if self.supported_features & VacuumEntityFeature.STOP == 0: if self.supported_features & VacuumEntityFeature.STOP == 0:
return None return
await self.async_publish( await self.async_publish(
self._command_topic, self._command_topic,
self._config[CONF_PAYLOAD_STOP], self._config[CONF_PAYLOAD_STOP],
@ -292,9 +272,9 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
async def async_set_fan_speed(self, fan_speed, **kwargs): async def async_set_fan_speed(self, fan_speed, **kwargs):
"""Set fan speed.""" """Set fan speed."""
if (self.supported_features & VacuumEntityFeature.FAN_SPEED == 0) or ( if (self.supported_features & VacuumEntityFeature.FAN_SPEED == 0) or (
fan_speed not in self._fan_speed_list fan_speed not in self.fan_speed_list
): ):
return None return
await self.async_publish( await self.async_publish(
self._set_fan_speed_topic, self._set_fan_speed_topic,
fan_speed, fan_speed,
@ -306,7 +286,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
async def async_return_to_base(self, **kwargs): async def async_return_to_base(self, **kwargs):
"""Tell the vacuum to return to its dock.""" """Tell the vacuum to return to its dock."""
if self.supported_features & VacuumEntityFeature.RETURN_HOME == 0: if self.supported_features & VacuumEntityFeature.RETURN_HOME == 0:
return None return
await self.async_publish( await self.async_publish(
self._command_topic, self._command_topic,
self._config[CONF_PAYLOAD_RETURN_TO_BASE], self._config[CONF_PAYLOAD_RETURN_TO_BASE],
@ -318,7 +298,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
async def async_clean_spot(self, **kwargs): async def async_clean_spot(self, **kwargs):
"""Perform a spot clean-up.""" """Perform a spot clean-up."""
if self.supported_features & VacuumEntityFeature.CLEAN_SPOT == 0: if self.supported_features & VacuumEntityFeature.CLEAN_SPOT == 0:
return None return
await self.async_publish( await self.async_publish(
self._command_topic, self._command_topic,
self._config[CONF_PAYLOAD_CLEAN_SPOT], self._config[CONF_PAYLOAD_CLEAN_SPOT],
@ -330,7 +310,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
async def async_locate(self, **kwargs): async def async_locate(self, **kwargs):
"""Locate the vacuum (usually by playing a song).""" """Locate the vacuum (usually by playing a song)."""
if self.supported_features & VacuumEntityFeature.LOCATE == 0: if self.supported_features & VacuumEntityFeature.LOCATE == 0:
return None return
await self.async_publish( await self.async_publish(
self._command_topic, self._command_topic,
self._config[CONF_PAYLOAD_LOCATE], self._config[CONF_PAYLOAD_LOCATE],
@ -342,7 +322,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
async def async_send_command(self, command, params=None, **kwargs): async def async_send_command(self, command, params=None, **kwargs):
"""Send a command to a vacuum cleaner.""" """Send a command to a vacuum cleaner."""
if self.supported_features & VacuumEntityFeature.SEND_COMMAND == 0: if self.supported_features & VacuumEntityFeature.SEND_COMMAND == 0:
return None return
if params: if params:
message = {"command": command} message = {"command": command}
message.update(params) message.update(params)