Pass Message object to MQTT message callbacks (#21959)
* Pass Message object to MQTT message callbacks * Improve method of detecting deprecated msg callback * Fix mysensors * Fixup * Review comments * Fix merge error
This commit is contained in:
parent
50ec3d7de5
commit
5957e4b75b
19 changed files with 203 additions and 142 deletions
|
@ -5,6 +5,8 @@ For more details about this component, please refer to the documentation at
|
||||||
https://home-assistant.io/components/mqtt/
|
https://home-assistant.io/components/mqtt/
|
||||||
"""
|
"""
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import inspect
|
||||||
|
from functools import partial, wraps
|
||||||
from itertools import groupby
|
from itertools import groupby
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
@ -264,7 +266,19 @@ MQTT_PUBLISH_SCHEMA = vol.Schema({
|
||||||
# pylint: disable=invalid-name
|
# pylint: disable=invalid-name
|
||||||
PublishPayloadType = Union[str, bytes, int, float, None]
|
PublishPayloadType = Union[str, bytes, int, float, None]
|
||||||
SubscribePayloadType = Union[str, bytes] # Only bytes if encoding is None
|
SubscribePayloadType = Union[str, bytes] # Only bytes if encoding is None
|
||||||
MessageCallbackType = Callable[[str, SubscribePayloadType, int], None]
|
|
||||||
|
|
||||||
|
@attr.s(slots=True, frozen=True)
|
||||||
|
class Message:
|
||||||
|
"""MQTT Message."""
|
||||||
|
|
||||||
|
topic = attr.ib(type=str)
|
||||||
|
payload = attr.ib(type=PublishPayloadType)
|
||||||
|
qos = attr.ib(type=int)
|
||||||
|
retain = attr.ib(type=bool)
|
||||||
|
|
||||||
|
|
||||||
|
MessageCallbackType = Callable[[Message], None]
|
||||||
|
|
||||||
|
|
||||||
def _build_publish_data(topic: Any, qos: int, retain: bool) -> ServiceDataType:
|
def _build_publish_data(topic: Any, qos: int, retain: bool) -> ServiceDataType:
|
||||||
|
@ -304,6 +318,30 @@ def publish_template(hass: HomeAssistantType, topic, payload_template,
|
||||||
hass.services.call(DOMAIN, SERVICE_PUBLISH, data)
|
hass.services.call(DOMAIN, SERVICE_PUBLISH, data)
|
||||||
|
|
||||||
|
|
||||||
|
def wrap_msg_callback(
|
||||||
|
msg_callback: MessageCallbackType) -> MessageCallbackType:
|
||||||
|
"""Wrap an MQTT message callback to support deprecated signature."""
|
||||||
|
# Check for partials to properly determine if coroutine function
|
||||||
|
check_func = msg_callback
|
||||||
|
while isinstance(check_func, partial):
|
||||||
|
check_func = check_func.func
|
||||||
|
|
||||||
|
wrapper_func = None
|
||||||
|
if asyncio.iscoroutinefunction(check_func):
|
||||||
|
@wraps(msg_callback)
|
||||||
|
async def async_wrapper(msg: Any) -> None:
|
||||||
|
"""Catch and log exception."""
|
||||||
|
await msg_callback(msg.topic, msg.payload, msg.qos)
|
||||||
|
wrapper_func = async_wrapper
|
||||||
|
else:
|
||||||
|
@wraps(msg_callback)
|
||||||
|
def wrapper(msg: Any) -> None:
|
||||||
|
"""Catch and log exception."""
|
||||||
|
msg_callback(msg.topic, msg.payload, msg.qos)
|
||||||
|
wrapper_func = wrapper
|
||||||
|
return wrapper_func
|
||||||
|
|
||||||
|
|
||||||
@bind_hass
|
@bind_hass
|
||||||
async def async_subscribe(hass: HomeAssistantType, topic: str,
|
async def async_subscribe(hass: HomeAssistantType, topic: str,
|
||||||
msg_callback: MessageCallbackType,
|
msg_callback: MessageCallbackType,
|
||||||
|
@ -313,11 +351,25 @@ async def async_subscribe(hass: HomeAssistantType, topic: str,
|
||||||
|
|
||||||
Call the return value to unsubscribe.
|
Call the return value to unsubscribe.
|
||||||
"""
|
"""
|
||||||
|
# Count callback parameters which don't have a default value
|
||||||
|
non_default = 0
|
||||||
|
if msg_callback:
|
||||||
|
non_default = sum(p.default == inspect.Parameter.empty for _, p in
|
||||||
|
inspect.signature(msg_callback).parameters.items())
|
||||||
|
|
||||||
|
wrapped_msg_callback = msg_callback
|
||||||
|
# If we have 3 paramaters with no default value, wrap the callback
|
||||||
|
if non_default == 3:
|
||||||
|
_LOGGER.info(
|
||||||
|
"Signature of MQTT msg_callback '%s.%s' is deprecated",
|
||||||
|
inspect.getmodule(msg_callback).__name__, msg_callback.__name__)
|
||||||
|
wrapped_msg_callback = wrap_msg_callback(msg_callback)
|
||||||
|
|
||||||
async_remove = await hass.data[DATA_MQTT].async_subscribe(
|
async_remove = await hass.data[DATA_MQTT].async_subscribe(
|
||||||
topic, catch_log_exception(
|
topic, catch_log_exception(
|
||||||
msg_callback, lambda topic, msg, qos:
|
wrapped_msg_callback, lambda msg:
|
||||||
"Exception in {} when handling msg on '{}': '{}'".format(
|
"Exception in {} when handling msg on '{}': '{}'".format(
|
||||||
msg_callback.__name__, topic, msg)),
|
msg_callback.__name__, msg.topic, msg.payload)),
|
||||||
qos, encoding)
|
qos, encoding)
|
||||||
return async_remove
|
return async_remove
|
||||||
|
|
||||||
|
@ -575,16 +627,6 @@ class Subscription:
|
||||||
encoding = attr.ib(type=str, default='utf-8')
|
encoding = attr.ib(type=str, default='utf-8')
|
||||||
|
|
||||||
|
|
||||||
@attr.s(slots=True, frozen=True)
|
|
||||||
class Message:
|
|
||||||
"""MQTT Message."""
|
|
||||||
|
|
||||||
topic = attr.ib(type=str)
|
|
||||||
payload = attr.ib(type=PublishPayloadType)
|
|
||||||
qos = attr.ib(type=int, default=0)
|
|
||||||
retain = attr.ib(type=bool, default=False)
|
|
||||||
|
|
||||||
|
|
||||||
class MQTT:
|
class MQTT:
|
||||||
"""Home Assistant MQTT client."""
|
"""Home Assistant MQTT client."""
|
||||||
|
|
||||||
|
@ -770,7 +812,8 @@ class MQTT:
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def _mqtt_handle_message(self, msg) -> None:
|
def _mqtt_handle_message(self, msg) -> None:
|
||||||
_LOGGER.debug("Received message on %s: %s", msg.topic, msg.payload)
|
_LOGGER.debug("Received message on %s%s: %s", msg.topic,
|
||||||
|
" (retained)" if msg.retain else "", msg.payload)
|
||||||
|
|
||||||
for subscription in self.subscriptions:
|
for subscription in self.subscriptions:
|
||||||
if not _match_topic(subscription.topic, msg.topic):
|
if not _match_topic(subscription.topic, msg.topic):
|
||||||
|
@ -787,7 +830,8 @@ class MQTT:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.hass.async_run_job(
|
self.hass.async_run_job(
|
||||||
subscription.callback, msg.topic, payload, msg.qos)
|
subscription.callback, Message(msg.topic, payload, msg.qos,
|
||||||
|
msg.retain))
|
||||||
|
|
||||||
def _mqtt_on_disconnect(self, _mqttc, _userdata, result_code: int) -> None:
|
def _mqtt_on_disconnect(self, _mqttc, _userdata, result_code: int) -> None:
|
||||||
"""Disconnected callback."""
|
"""Disconnected callback."""
|
||||||
|
@ -865,11 +909,9 @@ class MqttAttributes(Entity):
|
||||||
from .subscription import async_subscribe_topics
|
from .subscription import async_subscribe_topics
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def attributes_message_received(topic: str,
|
def attributes_message_received(msg: Message) -> None:
|
||||||
payload: SubscribePayloadType,
|
|
||||||
qos: int) -> None:
|
|
||||||
try:
|
try:
|
||||||
json_dict = json.loads(payload)
|
json_dict = json.loads(msg.payload)
|
||||||
if isinstance(json_dict, dict):
|
if isinstance(json_dict, dict):
|
||||||
self._attributes = json_dict
|
self._attributes = json_dict
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
@ -877,7 +919,7 @@ class MqttAttributes(Entity):
|
||||||
_LOGGER.warning("JSON result was not a dictionary")
|
_LOGGER.warning("JSON result was not a dictionary")
|
||||||
self._attributes = None
|
self._attributes = None
|
||||||
except ValueError:
|
except ValueError:
|
||||||
_LOGGER.warning("Erroneous JSON: %s", payload)
|
_LOGGER.warning("Erroneous JSON: %s", msg.payload)
|
||||||
self._attributes = None
|
self._attributes = None
|
||||||
|
|
||||||
self._attributes_sub_state = await async_subscribe_topics(
|
self._attributes_sub_state = await async_subscribe_topics(
|
||||||
|
@ -927,13 +969,11 @@ class MqttAvailability(Entity):
|
||||||
from .subscription import async_subscribe_topics
|
from .subscription import async_subscribe_topics
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def availability_message_received(topic: str,
|
def availability_message_received(msg: Message) -> None:
|
||||||
payload: SubscribePayloadType,
|
|
||||||
qos: int) -> None:
|
|
||||||
"""Handle a new received MQTT availability message."""
|
"""Handle a new received MQTT availability message."""
|
||||||
if payload == self._avail_config[CONF_PAYLOAD_AVAILABLE]:
|
if msg.payload == self._avail_config[CONF_PAYLOAD_AVAILABLE]:
|
||||||
self._available = True
|
self._available = True
|
||||||
elif payload == self._avail_config[CONF_PAYLOAD_NOT_AVAILABLE]:
|
elif msg.payload == self._avail_config[CONF_PAYLOAD_NOT_AVAILABLE]:
|
||||||
self._available = False
|
self._available = False
|
||||||
|
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
@ -1064,12 +1104,13 @@ async def websocket_subscribe(hass, connection, msg):
|
||||||
if not connection.user.is_admin:
|
if not connection.user.is_admin:
|
||||||
raise Unauthorized
|
raise Unauthorized
|
||||||
|
|
||||||
async def forward_messages(topic: str, payload: str, qos: int):
|
async def forward_messages(mqttmsg: Message):
|
||||||
"""Forward events to websocket."""
|
"""Forward events to websocket."""
|
||||||
connection.send_message(websocket_api.event_message(msg['id'], {
|
connection.send_message(websocket_api.event_message(msg['id'], {
|
||||||
'topic': topic,
|
'topic': mqttmsg.topic,
|
||||||
'payload': payload,
|
'payload': mqttmsg.payload,
|
||||||
'qos': qos,
|
'qos': mqttmsg.qos,
|
||||||
|
'retain': mqttmsg.retain,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
connection.subscriptions[msg['id']] = await async_subscribe(
|
connection.subscriptions[msg['id']] = await async_subscribe(
|
||||||
|
|
|
@ -126,16 +126,17 @@ class MqttAlarm(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
async def _subscribe_topics(self):
|
async def _subscribe_topics(self):
|
||||||
"""(Re)Subscribe to topics."""
|
"""(Re)Subscribe to topics."""
|
||||||
@callback
|
@callback
|
||||||
def message_received(topic, payload, qos):
|
def message_received(msg):
|
||||||
"""Run when new MQTT message has been received."""
|
"""Run when new MQTT message has been received."""
|
||||||
if payload not in (STATE_ALARM_DISARMED, STATE_ALARM_ARMED_HOME,
|
if msg.payload not in (
|
||||||
|
STATE_ALARM_DISARMED, STATE_ALARM_ARMED_HOME,
|
||||||
STATE_ALARM_ARMED_AWAY,
|
STATE_ALARM_ARMED_AWAY,
|
||||||
STATE_ALARM_ARMED_NIGHT,
|
STATE_ALARM_ARMED_NIGHT,
|
||||||
STATE_ALARM_PENDING,
|
STATE_ALARM_PENDING,
|
||||||
STATE_ALARM_TRIGGERED):
|
STATE_ALARM_TRIGGERED):
|
||||||
_LOGGER.warning("Received unexpected payload: %s", payload)
|
_LOGGER.warning("Received unexpected payload: %s", msg.payload)
|
||||||
return
|
return
|
||||||
self._state = payload
|
self._state = msg.payload
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
self._sub_state = await subscription.async_subscribe_topics(
|
self._sub_state = await subscription.async_subscribe_topics(
|
||||||
|
|
|
@ -133,8 +133,9 @@ class MqttBinarySensor(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def state_message_received(_topic, payload, _qos):
|
def state_message_received(msg):
|
||||||
"""Handle a new received MQTT state message."""
|
"""Handle a new received MQTT state message."""
|
||||||
|
payload = msg.payload
|
||||||
value_template = self._config.get(CONF_VALUE_TEMPLATE)
|
value_template = self._config.get(CONF_VALUE_TEMPLATE)
|
||||||
if value_template is not None:
|
if value_template is not None:
|
||||||
payload = value_template.async_render_with_possible_json_value(
|
payload = value_template.async_render_with_possible_json_value(
|
||||||
|
|
|
@ -102,9 +102,9 @@ class MqttCamera(MqttDiscoveryUpdate, Camera):
|
||||||
async def _subscribe_topics(self):
|
async def _subscribe_topics(self):
|
||||||
"""(Re)Subscribe to topics."""
|
"""(Re)Subscribe to topics."""
|
||||||
@callback
|
@callback
|
||||||
def message_received(topic, payload, qos):
|
def message_received(msg):
|
||||||
"""Handle new MQTT messages."""
|
"""Handle new MQTT messages."""
|
||||||
self._last_image = payload
|
self._last_image = msg.payload
|
||||||
|
|
||||||
self._sub_state = await subscription.async_subscribe_topics(
|
self._sub_state = await subscription.async_subscribe_topics(
|
||||||
self.hass, self._sub_state,
|
self.hass, self._sub_state,
|
||||||
|
|
|
@ -288,8 +288,9 @@ class MqttClimate(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
qos = self._config.get(CONF_QOS)
|
qos = self._config.get(CONF_QOS)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def handle_current_temp_received(topic, payload, qos):
|
def handle_current_temp_received(msg):
|
||||||
"""Handle current temperature coming via MQTT."""
|
"""Handle current temperature coming via MQTT."""
|
||||||
|
payload = msg.payload
|
||||||
if CONF_CURRENT_TEMPERATURE_TEMPLATE in self._value_templates:
|
if CONF_CURRENT_TEMPERATURE_TEMPLATE in self._value_templates:
|
||||||
payload =\
|
payload =\
|
||||||
self._value_templates[CONF_CURRENT_TEMPERATURE_TEMPLATE].\
|
self._value_templates[CONF_CURRENT_TEMPERATURE_TEMPLATE].\
|
||||||
|
@ -308,8 +309,9 @@ class MqttClimate(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
'qos': qos}
|
'qos': qos}
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def handle_mode_received(topic, payload, qos):
|
def handle_mode_received(msg):
|
||||||
"""Handle receiving mode via MQTT."""
|
"""Handle receiving mode via MQTT."""
|
||||||
|
payload = msg.payload
|
||||||
if CONF_MODE_STATE_TEMPLATE in self._value_templates:
|
if CONF_MODE_STATE_TEMPLATE in self._value_templates:
|
||||||
payload = self._value_templates[CONF_MODE_STATE_TEMPLATE].\
|
payload = self._value_templates[CONF_MODE_STATE_TEMPLATE].\
|
||||||
async_render_with_possible_json_value(payload)
|
async_render_with_possible_json_value(payload)
|
||||||
|
@ -327,8 +329,9 @@ class MqttClimate(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
'qos': qos}
|
'qos': qos}
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def handle_temperature_received(topic, payload, qos):
|
def handle_temperature_received(msg):
|
||||||
"""Handle target temperature coming via MQTT."""
|
"""Handle target temperature coming via MQTT."""
|
||||||
|
payload = msg.payload
|
||||||
if CONF_TEMPERATURE_STATE_TEMPLATE in self._value_templates:
|
if CONF_TEMPERATURE_STATE_TEMPLATE in self._value_templates:
|
||||||
payload = \
|
payload = \
|
||||||
self._value_templates[CONF_TEMPERATURE_STATE_TEMPLATE].\
|
self._value_templates[CONF_TEMPERATURE_STATE_TEMPLATE].\
|
||||||
|
@ -347,8 +350,9 @@ class MqttClimate(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
'qos': qos}
|
'qos': qos}
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def handle_fan_mode_received(topic, payload, qos):
|
def handle_fan_mode_received(msg):
|
||||||
"""Handle receiving fan mode via MQTT."""
|
"""Handle receiving fan mode via MQTT."""
|
||||||
|
payload = msg.payload
|
||||||
if CONF_FAN_MODE_STATE_TEMPLATE in self._value_templates:
|
if CONF_FAN_MODE_STATE_TEMPLATE in self._value_templates:
|
||||||
payload = \
|
payload = \
|
||||||
self._value_templates[CONF_FAN_MODE_STATE_TEMPLATE].\
|
self._value_templates[CONF_FAN_MODE_STATE_TEMPLATE].\
|
||||||
|
@ -367,8 +371,9 @@ class MqttClimate(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
'qos': qos}
|
'qos': qos}
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def handle_swing_mode_received(topic, payload, qos):
|
def handle_swing_mode_received(msg):
|
||||||
"""Handle receiving swing mode via MQTT."""
|
"""Handle receiving swing mode via MQTT."""
|
||||||
|
payload = msg.payload
|
||||||
if CONF_SWING_MODE_STATE_TEMPLATE in self._value_templates:
|
if CONF_SWING_MODE_STATE_TEMPLATE in self._value_templates:
|
||||||
payload = \
|
payload = \
|
||||||
self._value_templates[CONF_SWING_MODE_STATE_TEMPLATE].\
|
self._value_templates[CONF_SWING_MODE_STATE_TEMPLATE].\
|
||||||
|
@ -387,8 +392,9 @@ class MqttClimate(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
'qos': qos}
|
'qos': qos}
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def handle_away_mode_received(topic, payload, qos):
|
def handle_away_mode_received(msg):
|
||||||
"""Handle receiving away mode via MQTT."""
|
"""Handle receiving away mode via MQTT."""
|
||||||
|
payload = msg.payload
|
||||||
payload_on = self._config.get(CONF_PAYLOAD_ON)
|
payload_on = self._config.get(CONF_PAYLOAD_ON)
|
||||||
payload_off = self._config.get(CONF_PAYLOAD_OFF)
|
payload_off = self._config.get(CONF_PAYLOAD_OFF)
|
||||||
if CONF_AWAY_MODE_STATE_TEMPLATE in self._value_templates:
|
if CONF_AWAY_MODE_STATE_TEMPLATE in self._value_templates:
|
||||||
|
@ -416,8 +422,9 @@ class MqttClimate(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
'qos': qos}
|
'qos': qos}
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def handle_aux_mode_received(topic, payload, qos):
|
def handle_aux_mode_received(msg):
|
||||||
"""Handle receiving aux mode via MQTT."""
|
"""Handle receiving aux mode via MQTT."""
|
||||||
|
payload = msg.payload
|
||||||
payload_on = self._config.get(CONF_PAYLOAD_ON)
|
payload_on = self._config.get(CONF_PAYLOAD_ON)
|
||||||
payload_off = self._config.get(CONF_PAYLOAD_OFF)
|
payload_off = self._config.get(CONF_PAYLOAD_OFF)
|
||||||
if CONF_AUX_STATE_TEMPLATE in self._value_templates:
|
if CONF_AUX_STATE_TEMPLATE in self._value_templates:
|
||||||
|
@ -444,8 +451,9 @@ class MqttClimate(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
'qos': qos}
|
'qos': qos}
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def handle_hold_mode_received(topic, payload, qos):
|
def handle_hold_mode_received(msg):
|
||||||
"""Handle receiving hold mode via MQTT."""
|
"""Handle receiving hold mode via MQTT."""
|
||||||
|
payload = msg.payload
|
||||||
if CONF_HOLD_STATE_TEMPLATE in self._value_templates:
|
if CONF_HOLD_STATE_TEMPLATE in self._value_templates:
|
||||||
payload = self._value_templates[CONF_HOLD_STATE_TEMPLATE].\
|
payload = self._value_templates[CONF_HOLD_STATE_TEMPLATE].\
|
||||||
async_render_with_possible_json_value(payload)
|
async_render_with_possible_json_value(payload)
|
||||||
|
|
|
@ -216,19 +216,20 @@ class MqttCover(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
topics = {}
|
topics = {}
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def tilt_updated(topic, payload, qos):
|
def tilt_updated(msg):
|
||||||
"""Handle tilt updates."""
|
"""Handle tilt updates."""
|
||||||
if (payload.isnumeric() and
|
if (msg.payload.isnumeric() and
|
||||||
(self._config.get(CONF_TILT_MIN) <= int(payload) <=
|
(self._config.get(CONF_TILT_MIN) <= int(msg.payload) <=
|
||||||
self._config.get(CONF_TILT_MAX))):
|
self._config.get(CONF_TILT_MAX))):
|
||||||
|
|
||||||
level = self.find_percentage_in_range(float(payload))
|
level = self.find_percentage_in_range(float(msg.payload))
|
||||||
self._tilt_value = level
|
self._tilt_value = level
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def state_message_received(topic, payload, qos):
|
def state_message_received(msg):
|
||||||
"""Handle new MQTT state messages."""
|
"""Handle new MQTT state messages."""
|
||||||
|
payload = msg.payload
|
||||||
if template is not None:
|
if template is not None:
|
||||||
payload = template.async_render_with_possible_json_value(
|
payload = template.async_render_with_possible_json_value(
|
||||||
payload)
|
payload)
|
||||||
|
@ -243,8 +244,9 @@ class MqttCover(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def position_message_received(topic, payload, qos):
|
def position_message_received(msg):
|
||||||
"""Handle new MQTT state messages."""
|
"""Handle new MQTT state messages."""
|
||||||
|
payload = msg.payload
|
||||||
if template is not None:
|
if template is not None:
|
||||||
payload = template.async_render_with_possible_json_value(
|
payload = template.async_render_with_possible_json_value(
|
||||||
payload)
|
payload)
|
||||||
|
|
|
@ -31,10 +31,10 @@ async def async_setup_scanner(hass, config, async_see, discovery_info=None):
|
||||||
|
|
||||||
for dev_id, topic in devices.items():
|
for dev_id, topic in devices.items():
|
||||||
@callback
|
@callback
|
||||||
def async_message_received(topic, payload, qos, dev_id=dev_id):
|
def async_message_received(msg, dev_id=dev_id):
|
||||||
"""Handle received MQTT message."""
|
"""Handle received MQTT message."""
|
||||||
hass.async_create_task(
|
hass.async_create_task(
|
||||||
async_see(dev_id=dev_id, location_name=payload))
|
async_see(dev_id=dev_id, location_name=msg.payload))
|
||||||
|
|
||||||
await mqtt.async_subscribe(
|
await mqtt.async_subscribe(
|
||||||
hass, topic, async_message_received, qos)
|
hass, topic, async_message_received, qos)
|
||||||
|
|
|
@ -200,8 +200,10 @@ def clear_discovery_hash(hass, discovery_hash):
|
||||||
async def async_start(hass: HomeAssistantType, discovery_topic, hass_config,
|
async def async_start(hass: HomeAssistantType, discovery_topic, hass_config,
|
||||||
config_entry=None) -> bool:
|
config_entry=None) -> bool:
|
||||||
"""Initialize of MQTT Discovery."""
|
"""Initialize of MQTT Discovery."""
|
||||||
async def async_device_message_received(topic, payload, qos):
|
async def async_device_message_received(msg):
|
||||||
"""Process the received message."""
|
"""Process the received message."""
|
||||||
|
payload = msg.payload
|
||||||
|
topic = msg.topic
|
||||||
match = TOPIC_MATCHER.match(topic)
|
match = TOPIC_MATCHER.match(topic)
|
||||||
|
|
||||||
if not match:
|
if not match:
|
||||||
|
|
|
@ -212,9 +212,9 @@ class MqttFan(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
templates[key] = tpl.async_render_with_possible_json_value
|
templates[key] = tpl.async_render_with_possible_json_value
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def state_received(topic, payload, qos):
|
def state_received(msg):
|
||||||
"""Handle new received MQTT message."""
|
"""Handle new received MQTT message."""
|
||||||
payload = templates[CONF_STATE](payload)
|
payload = templates[CONF_STATE](msg.payload)
|
||||||
if payload == self._payload[STATE_ON]:
|
if payload == self._payload[STATE_ON]:
|
||||||
self._state = True
|
self._state = True
|
||||||
elif payload == self._payload[STATE_OFF]:
|
elif payload == self._payload[STATE_OFF]:
|
||||||
|
@ -228,9 +228,9 @@ class MqttFan(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
'qos': self._config.get(CONF_QOS)}
|
'qos': self._config.get(CONF_QOS)}
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def speed_received(topic, payload, qos):
|
def speed_received(msg):
|
||||||
"""Handle new received MQTT message for the speed."""
|
"""Handle new received MQTT message for the speed."""
|
||||||
payload = templates[ATTR_SPEED](payload)
|
payload = templates[ATTR_SPEED](msg.payload)
|
||||||
if payload == self._payload[SPEED_LOW]:
|
if payload == self._payload[SPEED_LOW]:
|
||||||
self._speed = SPEED_LOW
|
self._speed = SPEED_LOW
|
||||||
elif payload == self._payload[SPEED_MEDIUM]:
|
elif payload == self._payload[SPEED_MEDIUM]:
|
||||||
|
@ -247,9 +247,9 @@ class MqttFan(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
self._speed = SPEED_OFF
|
self._speed = SPEED_OFF
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def oscillation_received(topic, payload, qos):
|
def oscillation_received(msg):
|
||||||
"""Handle new received MQTT message for the oscillation."""
|
"""Handle new received MQTT message for the oscillation."""
|
||||||
payload = templates[OSCILLATION](payload)
|
payload = templates[OSCILLATION](msg.payload)
|
||||||
if payload == self._payload[OSCILLATE_ON_PAYLOAD]:
|
if payload == self._payload[OSCILLATE_ON_PAYLOAD]:
|
||||||
self._oscillation = True
|
self._oscillation = True
|
||||||
elif payload == self._payload[OSCILLATE_OFF_PAYLOAD]:
|
elif payload == self._payload[OSCILLATE_OFF_PAYLOAD]:
|
||||||
|
|
|
@ -254,11 +254,12 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
last_state = await self.async_get_last_state()
|
last_state = await self.async_get_last_state()
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def state_received(topic, payload, qos):
|
def state_received(msg):
|
||||||
"""Handle new MQTT messages."""
|
"""Handle new MQTT messages."""
|
||||||
payload = templates[CONF_STATE](payload)
|
payload = templates[CONF_STATE](msg.payload)
|
||||||
if not payload:
|
if not payload:
|
||||||
_LOGGER.debug("Ignoring empty state message from '%s'", topic)
|
_LOGGER.debug("Ignoring empty state message from '%s'",
|
||||||
|
msg.topic)
|
||||||
return
|
return
|
||||||
|
|
||||||
if payload == self._payload['on']:
|
if payload == self._payload['on']:
|
||||||
|
@ -276,12 +277,12 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
self._state = last_state.state == STATE_ON
|
self._state = last_state.state == STATE_ON
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def brightness_received(topic, payload, qos):
|
def brightness_received(msg):
|
||||||
"""Handle new MQTT messages for the brightness."""
|
"""Handle new MQTT messages for the brightness."""
|
||||||
payload = templates[CONF_BRIGHTNESS](payload)
|
payload = templates[CONF_BRIGHTNESS](msg.payload)
|
||||||
if not payload:
|
if not payload:
|
||||||
_LOGGER.debug("Ignoring empty brightness message from '%s'",
|
_LOGGER.debug("Ignoring empty brightness message from '%s'",
|
||||||
topic)
|
msg.topic)
|
||||||
return
|
return
|
||||||
|
|
||||||
device_value = float(payload)
|
device_value = float(payload)
|
||||||
|
@ -305,11 +306,12 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
self._brightness = None
|
self._brightness = None
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def rgb_received(topic, payload, qos):
|
def rgb_received(msg):
|
||||||
"""Handle new MQTT messages for RGB."""
|
"""Handle new MQTT messages for RGB."""
|
||||||
payload = templates[CONF_RGB](payload)
|
payload = templates[CONF_RGB](msg.payload)
|
||||||
if not payload:
|
if not payload:
|
||||||
_LOGGER.debug("Ignoring empty rgb message from '%s'", topic)
|
_LOGGER.debug("Ignoring empty rgb message from '%s'",
|
||||||
|
msg.topic)
|
||||||
return
|
return
|
||||||
|
|
||||||
rgb = [int(val) for val in payload.split(',')]
|
rgb = [int(val) for val in payload.split(',')]
|
||||||
|
@ -333,12 +335,12 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
self._hs = (0, 0)
|
self._hs = (0, 0)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def color_temp_received(topic, payload, qos):
|
def color_temp_received(msg):
|
||||||
"""Handle new MQTT messages for color temperature."""
|
"""Handle new MQTT messages for color temperature."""
|
||||||
payload = templates[CONF_COLOR_TEMP](payload)
|
payload = templates[CONF_COLOR_TEMP](msg.payload)
|
||||||
if not payload:
|
if not payload:
|
||||||
_LOGGER.debug("Ignoring empty color temp message from '%s'",
|
_LOGGER.debug("Ignoring empty color temp message from '%s'",
|
||||||
topic)
|
msg.topic)
|
||||||
return
|
return
|
||||||
|
|
||||||
self._color_temp = int(payload)
|
self._color_temp = int(payload)
|
||||||
|
@ -359,11 +361,12 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
self._color_temp = None
|
self._color_temp = None
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def effect_received(topic, payload, qos):
|
def effect_received(msg):
|
||||||
"""Handle new MQTT messages for effect."""
|
"""Handle new MQTT messages for effect."""
|
||||||
payload = templates[CONF_EFFECT](payload)
|
payload = templates[CONF_EFFECT](msg.payload)
|
||||||
if not payload:
|
if not payload:
|
||||||
_LOGGER.debug("Ignoring empty effect message from '%s'", topic)
|
_LOGGER.debug("Ignoring empty effect message from '%s'",
|
||||||
|
msg.topic)
|
||||||
return
|
return
|
||||||
|
|
||||||
self._effect = payload
|
self._effect = payload
|
||||||
|
@ -384,11 +387,11 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
self._effect = None
|
self._effect = None
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def hs_received(topic, payload, qos):
|
def hs_received(msg):
|
||||||
"""Handle new MQTT messages for hs color."""
|
"""Handle new MQTT messages for hs color."""
|
||||||
payload = templates[CONF_HS](payload)
|
payload = templates[CONF_HS](msg.payload)
|
||||||
if not payload:
|
if not payload:
|
||||||
_LOGGER.debug("Ignoring empty hs message from '%s'", topic)
|
_LOGGER.debug("Ignoring empty hs message from '%s'", msg.topic)
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -412,12 +415,12 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
self._hs = (0, 0)
|
self._hs = (0, 0)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def white_value_received(topic, payload, qos):
|
def white_value_received(msg):
|
||||||
"""Handle new MQTT messages for white value."""
|
"""Handle new MQTT messages for white value."""
|
||||||
payload = templates[CONF_WHITE_VALUE](payload)
|
payload = templates[CONF_WHITE_VALUE](msg.payload)
|
||||||
if not payload:
|
if not payload:
|
||||||
_LOGGER.debug("Ignoring empty white value message from '%s'",
|
_LOGGER.debug("Ignoring empty white value message from '%s'",
|
||||||
topic)
|
msg.topic)
|
||||||
return
|
return
|
||||||
|
|
||||||
device_value = float(payload)
|
device_value = float(payload)
|
||||||
|
@ -441,12 +444,12 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
self._white_value = None
|
self._white_value = None
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def xy_received(topic, payload, qos):
|
def xy_received(msg):
|
||||||
"""Handle new MQTT messages for xy color."""
|
"""Handle new MQTT messages for xy color."""
|
||||||
payload = templates[CONF_XY](payload)
|
payload = templates[CONF_XY](msg.payload)
|
||||||
if not payload:
|
if not payload:
|
||||||
_LOGGER.debug("Ignoring empty xy-color message from '%s'",
|
_LOGGER.debug("Ignoring empty xy-color message from '%s'",
|
||||||
topic)
|
msg.topic)
|
||||||
return
|
return
|
||||||
|
|
||||||
xy_color = [float(val) for val in payload.split(',')]
|
xy_color = [float(val) for val in payload.split(',')]
|
||||||
|
|
|
@ -201,9 +201,9 @@ class MqttLightJson(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
last_state = await self.async_get_last_state()
|
last_state = await self.async_get_last_state()
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def state_received(topic, payload, qos):
|
def state_received(msg):
|
||||||
"""Handle new MQTT messages."""
|
"""Handle new MQTT messages."""
|
||||||
values = json.loads(payload)
|
values = json.loads(msg.payload)
|
||||||
|
|
||||||
if values['state'] == 'ON':
|
if values['state'] == 'ON':
|
||||||
self._state = True
|
self._state = True
|
||||||
|
|
|
@ -188,10 +188,10 @@ class MqttTemplate(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
last_state = await self.async_get_last_state()
|
last_state = await self.async_get_last_state()
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def state_received(topic, payload, qos):
|
def state_received(msg):
|
||||||
"""Handle new MQTT messages."""
|
"""Handle new MQTT messages."""
|
||||||
state = self._templates[CONF_STATE_TEMPLATE].\
|
state = self._templates[CONF_STATE_TEMPLATE].\
|
||||||
async_render_with_possible_json_value(payload)
|
async_render_with_possible_json_value(msg.payload)
|
||||||
if state == STATE_ON:
|
if state == STATE_ON:
|
||||||
self._state = True
|
self._state = True
|
||||||
elif state == STATE_OFF:
|
elif state == STATE_OFF:
|
||||||
|
@ -203,7 +203,7 @@ class MqttTemplate(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
try:
|
try:
|
||||||
self._brightness = int(
|
self._brightness = int(
|
||||||
self._templates[CONF_BRIGHTNESS_TEMPLATE].
|
self._templates[CONF_BRIGHTNESS_TEMPLATE].
|
||||||
async_render_with_possible_json_value(payload)
|
async_render_with_possible_json_value(msg.payload)
|
||||||
)
|
)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
_LOGGER.warning("Invalid brightness value received")
|
_LOGGER.warning("Invalid brightness value received")
|
||||||
|
@ -212,7 +212,7 @@ class MqttTemplate(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
try:
|
try:
|
||||||
self._color_temp = int(
|
self._color_temp = int(
|
||||||
self._templates[CONF_COLOR_TEMP_TEMPLATE].
|
self._templates[CONF_COLOR_TEMP_TEMPLATE].
|
||||||
async_render_with_possible_json_value(payload)
|
async_render_with_possible_json_value(msg.payload)
|
||||||
)
|
)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
_LOGGER.warning("Invalid color temperature value received")
|
_LOGGER.warning("Invalid color temperature value received")
|
||||||
|
@ -221,13 +221,13 @@ class MqttTemplate(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
try:
|
try:
|
||||||
red = int(
|
red = int(
|
||||||
self._templates[CONF_RED_TEMPLATE].
|
self._templates[CONF_RED_TEMPLATE].
|
||||||
async_render_with_possible_json_value(payload))
|
async_render_with_possible_json_value(msg.payload))
|
||||||
green = int(
|
green = int(
|
||||||
self._templates[CONF_GREEN_TEMPLATE].
|
self._templates[CONF_GREEN_TEMPLATE].
|
||||||
async_render_with_possible_json_value(payload))
|
async_render_with_possible_json_value(msg.payload))
|
||||||
blue = int(
|
blue = int(
|
||||||
self._templates[CONF_BLUE_TEMPLATE].
|
self._templates[CONF_BLUE_TEMPLATE].
|
||||||
async_render_with_possible_json_value(payload))
|
async_render_with_possible_json_value(msg.payload))
|
||||||
self._hs = color_util.color_RGB_to_hs(red, green, blue)
|
self._hs = color_util.color_RGB_to_hs(red, green, blue)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
_LOGGER.warning("Invalid color value received")
|
_LOGGER.warning("Invalid color value received")
|
||||||
|
@ -236,14 +236,14 @@ class MqttTemplate(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
try:
|
try:
|
||||||
self._white_value = int(
|
self._white_value = int(
|
||||||
self._templates[CONF_WHITE_VALUE_TEMPLATE].
|
self._templates[CONF_WHITE_VALUE_TEMPLATE].
|
||||||
async_render_with_possible_json_value(payload)
|
async_render_with_possible_json_value(msg.payload)
|
||||||
)
|
)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
_LOGGER.warning('Invalid white value received')
|
_LOGGER.warning('Invalid white value received')
|
||||||
|
|
||||||
if self._templates[CONF_EFFECT_TEMPLATE] is not None:
|
if self._templates[CONF_EFFECT_TEMPLATE] is not None:
|
||||||
effect = self._templates[CONF_EFFECT_TEMPLATE].\
|
effect = self._templates[CONF_EFFECT_TEMPLATE].\
|
||||||
async_render_with_possible_json_value(payload)
|
async_render_with_possible_json_value(msg.payload)
|
||||||
|
|
||||||
if effect in self._config.get(CONF_EFFECT_LIST):
|
if effect in self._config.get(CONF_EFFECT_LIST):
|
||||||
self._effect = effect
|
self._effect = effect
|
||||||
|
|
|
@ -120,8 +120,9 @@ class MqttLock(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
value_template.hass = self.hass
|
value_template.hass = self.hass
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def message_received(topic, payload, qos):
|
def message_received(msg):
|
||||||
"""Handle new MQTT messages."""
|
"""Handle new MQTT messages."""
|
||||||
|
payload = msg.payload
|
||||||
if value_template is not None:
|
if value_template is not None:
|
||||||
payload = value_template.async_render_with_possible_json_value(
|
payload = value_template.async_render_with_possible_json_value(
|
||||||
payload)
|
payload)
|
||||||
|
|
|
@ -133,8 +133,9 @@ class MqttSensor(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
template.hass = self.hass
|
template.hass = self.hass
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def message_received(topic, payload, qos):
|
def message_received(msg):
|
||||||
"""Handle new MQTT messages."""
|
"""Handle new MQTT messages."""
|
||||||
|
payload = msg.payload
|
||||||
# auto-expire enabled?
|
# auto-expire enabled?
|
||||||
expire_after = self._config.get(CONF_EXPIRE_AFTER)
|
expire_after = self._config.get(CONF_EXPIRE_AFTER)
|
||||||
if expire_after is not None and expire_after > 0:
|
if expire_after is not None and expire_after > 0:
|
||||||
|
|
|
@ -143,8 +143,9 @@ class MqttSwitch(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
template.hass = self.hass
|
template.hass = self.hass
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def state_message_received(topic, payload, qos):
|
def state_message_received(msg):
|
||||||
"""Handle new MQTT state messages."""
|
"""Handle new MQTT state messages."""
|
||||||
|
payload = msg.payload
|
||||||
if template is not None:
|
if template is not None:
|
||||||
payload = template.async_render_with_possible_json_value(
|
payload = template.async_render_with_possible_json_value(
|
||||||
payload)
|
payload)
|
||||||
|
|
|
@ -284,45 +284,45 @@ class MqttVacuum(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
tpl.hass = self.hass
|
tpl.hass = self.hass
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def message_received(topic, payload, qos):
|
def message_received(msg):
|
||||||
"""Handle new MQTT message."""
|
"""Handle new MQTT message."""
|
||||||
if topic == self._state_topics[CONF_BATTERY_LEVEL_TOPIC] and \
|
if msg.topic == self._state_topics[CONF_BATTERY_LEVEL_TOPIC] and \
|
||||||
self._templates[CONF_BATTERY_LEVEL_TEMPLATE]:
|
self._templates[CONF_BATTERY_LEVEL_TEMPLATE]:
|
||||||
battery_level = self._templates[CONF_BATTERY_LEVEL_TEMPLATE]\
|
battery_level = self._templates[CONF_BATTERY_LEVEL_TEMPLATE]\
|
||||||
.async_render_with_possible_json_value(
|
.async_render_with_possible_json_value(
|
||||||
payload, error_value=None)
|
msg.payload, error_value=None)
|
||||||
if battery_level is not None:
|
if battery_level is not None:
|
||||||
self._battery_level = int(battery_level)
|
self._battery_level = int(battery_level)
|
||||||
|
|
||||||
if topic == self._state_topics[CONF_CHARGING_TOPIC] and \
|
if msg.topic == self._state_topics[CONF_CHARGING_TOPIC] and \
|
||||||
self._templates[CONF_CHARGING_TEMPLATE]:
|
self._templates[CONF_CHARGING_TEMPLATE]:
|
||||||
charging = self._templates[CONF_CHARGING_TEMPLATE]\
|
charging = self._templates[CONF_CHARGING_TEMPLATE]\
|
||||||
.async_render_with_possible_json_value(
|
.async_render_with_possible_json_value(
|
||||||
payload, error_value=None)
|
msg.payload, error_value=None)
|
||||||
if charging is not None:
|
if charging is not None:
|
||||||
self._charging = cv.boolean(charging)
|
self._charging = cv.boolean(charging)
|
||||||
|
|
||||||
if topic == self._state_topics[CONF_CLEANING_TOPIC] and \
|
if msg.topic == self._state_topics[CONF_CLEANING_TOPIC] and \
|
||||||
self._templates[CONF_CLEANING_TEMPLATE]:
|
self._templates[CONF_CLEANING_TEMPLATE]:
|
||||||
cleaning = self._templates[CONF_CLEANING_TEMPLATE]\
|
cleaning = self._templates[CONF_CLEANING_TEMPLATE]\
|
||||||
.async_render_with_possible_json_value(
|
.async_render_with_possible_json_value(
|
||||||
payload, error_value=None)
|
msg.payload, error_value=None)
|
||||||
if cleaning is not None:
|
if cleaning is not None:
|
||||||
self._cleaning = cv.boolean(cleaning)
|
self._cleaning = cv.boolean(cleaning)
|
||||||
|
|
||||||
if topic == self._state_topics[CONF_DOCKED_TOPIC] and \
|
if msg.topic == self._state_topics[CONF_DOCKED_TOPIC] and \
|
||||||
self._templates[CONF_DOCKED_TEMPLATE]:
|
self._templates[CONF_DOCKED_TEMPLATE]:
|
||||||
docked = self._templates[CONF_DOCKED_TEMPLATE]\
|
docked = self._templates[CONF_DOCKED_TEMPLATE]\
|
||||||
.async_render_with_possible_json_value(
|
.async_render_with_possible_json_value(
|
||||||
payload, error_value=None)
|
msg.payload, error_value=None)
|
||||||
if docked is not None:
|
if docked is not None:
|
||||||
self._docked = cv.boolean(docked)
|
self._docked = cv.boolean(docked)
|
||||||
|
|
||||||
if topic == self._state_topics[CONF_ERROR_TOPIC] and \
|
if msg.topic == self._state_topics[CONF_ERROR_TOPIC] and \
|
||||||
self._templates[CONF_ERROR_TEMPLATE]:
|
self._templates[CONF_ERROR_TEMPLATE]:
|
||||||
error = self._templates[CONF_ERROR_TEMPLATE]\
|
error = self._templates[CONF_ERROR_TEMPLATE]\
|
||||||
.async_render_with_possible_json_value(
|
.async_render_with_possible_json_value(
|
||||||
payload, error_value=None)
|
msg.payload, error_value=None)
|
||||||
if error is not None:
|
if error is not None:
|
||||||
self._error = cv.string(error)
|
self._error = cv.string(error)
|
||||||
|
|
||||||
|
@ -338,11 +338,11 @@ class MqttVacuum(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
||||||
else:
|
else:
|
||||||
self._status = "Stopped"
|
self._status = "Stopped"
|
||||||
|
|
||||||
if topic == self._state_topics[CONF_FAN_SPEED_TOPIC] and \
|
if msg.topic == self._state_topics[CONF_FAN_SPEED_TOPIC] and \
|
||||||
self._templates[CONF_FAN_SPEED_TEMPLATE]:
|
self._templates[CONF_FAN_SPEED_TEMPLATE]:
|
||||||
fan_speed = self._templates[CONF_FAN_SPEED_TEMPLATE]\
|
fan_speed = self._templates[CONF_FAN_SPEED_TEMPLATE]\
|
||||||
.async_render_with_possible_json_value(
|
.async_render_with_possible_json_value(
|
||||||
payload, error_value=None)
|
msg.payload, error_value=None)
|
||||||
if fan_speed is not None:
|
if fan_speed is not None:
|
||||||
self._fan_speed = fan_speed
|
self._fan_speed = fan_speed
|
||||||
|
|
||||||
|
|
|
@ -98,9 +98,9 @@ async def _get_gateway(hass, config, gateway_conf, persistence_file):
|
||||||
def sub_callback(topic, sub_cb, qos):
|
def sub_callback(topic, sub_cb, qos):
|
||||||
"""Call MQTT subscribe function."""
|
"""Call MQTT subscribe function."""
|
||||||
@callback
|
@callback
|
||||||
def internal_callback(*args):
|
def internal_callback(msg):
|
||||||
"""Call callback."""
|
"""Call callback."""
|
||||||
sub_cb(*args)
|
sub_cb(msg.topic, msg.payload, msg.qos)
|
||||||
|
|
||||||
hass.async_create_task(
|
hass.async_create_task(
|
||||||
mqtt.async_subscribe(topic, internal_callback, qos))
|
mqtt.async_subscribe(topic, internal_callback, qos))
|
||||||
|
|
|
@ -316,8 +316,8 @@ class TestMQTTCallbacks(unittest.TestCase):
|
||||||
|
|
||||||
self.hass.block_till_done()
|
self.hass.block_till_done()
|
||||||
assert 1 == len(self.calls)
|
assert 1 == len(self.calls)
|
||||||
assert 'test-topic' == self.calls[0][0]
|
assert 'test-topic' == self.calls[0][0].topic
|
||||||
assert 'test-payload' == self.calls[0][1]
|
assert 'test-payload' == self.calls[0][0].payload
|
||||||
|
|
||||||
unsub()
|
unsub()
|
||||||
|
|
||||||
|
@ -343,8 +343,8 @@ class TestMQTTCallbacks(unittest.TestCase):
|
||||||
|
|
||||||
self.hass.block_till_done()
|
self.hass.block_till_done()
|
||||||
assert 1 == len(self.calls)
|
assert 1 == len(self.calls)
|
||||||
assert 'test-topic/bier/on' == self.calls[0][0]
|
assert 'test-topic/bier/on' == self.calls[0][0].topic
|
||||||
assert 'test-payload' == self.calls[0][1]
|
assert 'test-payload' == self.calls[0][0].payload
|
||||||
|
|
||||||
def test_subscribe_topic_level_wildcard_no_subtree_match(self):
|
def test_subscribe_topic_level_wildcard_no_subtree_match(self):
|
||||||
"""Test the subscription of wildcard topics."""
|
"""Test the subscription of wildcard topics."""
|
||||||
|
@ -372,8 +372,8 @@ class TestMQTTCallbacks(unittest.TestCase):
|
||||||
|
|
||||||
self.hass.block_till_done()
|
self.hass.block_till_done()
|
||||||
assert 1 == len(self.calls)
|
assert 1 == len(self.calls)
|
||||||
assert 'test-topic/bier/on' == self.calls[0][0]
|
assert 'test-topic/bier/on' == self.calls[0][0].topic
|
||||||
assert 'test-payload' == self.calls[0][1]
|
assert 'test-payload' == self.calls[0][0].payload
|
||||||
|
|
||||||
def test_subscribe_topic_subtree_wildcard_root_topic(self):
|
def test_subscribe_topic_subtree_wildcard_root_topic(self):
|
||||||
"""Test the subscription of wildcard topics."""
|
"""Test the subscription of wildcard topics."""
|
||||||
|
@ -383,8 +383,8 @@ class TestMQTTCallbacks(unittest.TestCase):
|
||||||
|
|
||||||
self.hass.block_till_done()
|
self.hass.block_till_done()
|
||||||
assert 1 == len(self.calls)
|
assert 1 == len(self.calls)
|
||||||
assert 'test-topic' == self.calls[0][0]
|
assert 'test-topic' == self.calls[0][0].topic
|
||||||
assert 'test-payload' == self.calls[0][1]
|
assert 'test-payload' == self.calls[0][0].payload
|
||||||
|
|
||||||
def test_subscribe_topic_subtree_wildcard_no_match(self):
|
def test_subscribe_topic_subtree_wildcard_no_match(self):
|
||||||
"""Test the subscription of wildcard topics."""
|
"""Test the subscription of wildcard topics."""
|
||||||
|
@ -403,8 +403,8 @@ class TestMQTTCallbacks(unittest.TestCase):
|
||||||
|
|
||||||
self.hass.block_till_done()
|
self.hass.block_till_done()
|
||||||
assert 1 == len(self.calls)
|
assert 1 == len(self.calls)
|
||||||
assert 'hi/test-topic' == self.calls[0][0]
|
assert 'hi/test-topic' == self.calls[0][0].topic
|
||||||
assert 'test-payload' == self.calls[0][1]
|
assert 'test-payload' == self.calls[0][0].payload
|
||||||
|
|
||||||
def test_subscribe_topic_level_wildcard_and_wildcard_subtree_topic(self):
|
def test_subscribe_topic_level_wildcard_and_wildcard_subtree_topic(self):
|
||||||
"""Test the subscription of wildcard topics."""
|
"""Test the subscription of wildcard topics."""
|
||||||
|
@ -414,8 +414,8 @@ class TestMQTTCallbacks(unittest.TestCase):
|
||||||
|
|
||||||
self.hass.block_till_done()
|
self.hass.block_till_done()
|
||||||
assert 1 == len(self.calls)
|
assert 1 == len(self.calls)
|
||||||
assert 'hi/test-topic/here-iam' == self.calls[0][0]
|
assert 'hi/test-topic/here-iam' == self.calls[0][0].topic
|
||||||
assert 'test-payload' == self.calls[0][1]
|
assert 'test-payload' == self.calls[0][0].payload
|
||||||
|
|
||||||
def test_subscribe_topic_level_wildcard_and_wildcard_level_no_match(self):
|
def test_subscribe_topic_level_wildcard_and_wildcard_level_no_match(self):
|
||||||
"""Test the subscription of wildcard topics."""
|
"""Test the subscription of wildcard topics."""
|
||||||
|
@ -443,8 +443,8 @@ class TestMQTTCallbacks(unittest.TestCase):
|
||||||
|
|
||||||
self.hass.block_till_done()
|
self.hass.block_till_done()
|
||||||
assert 1 == len(self.calls)
|
assert 1 == len(self.calls)
|
||||||
assert '$test-topic/subtree/on' == self.calls[0][0]
|
assert '$test-topic/subtree/on' == self.calls[0][0].topic
|
||||||
assert 'test-payload' == self.calls[0][1]
|
assert 'test-payload' == self.calls[0][0].payload
|
||||||
|
|
||||||
def test_subscribe_topic_sys_root_and_wildcard_topic(self):
|
def test_subscribe_topic_sys_root_and_wildcard_topic(self):
|
||||||
"""Test the subscription of $ root and wildcard topics."""
|
"""Test the subscription of $ root and wildcard topics."""
|
||||||
|
@ -454,8 +454,8 @@ class TestMQTTCallbacks(unittest.TestCase):
|
||||||
|
|
||||||
self.hass.block_till_done()
|
self.hass.block_till_done()
|
||||||
assert 1 == len(self.calls)
|
assert 1 == len(self.calls)
|
||||||
assert '$test-topic/some-topic' == self.calls[0][0]
|
assert '$test-topic/some-topic' == self.calls[0][0].topic
|
||||||
assert 'test-payload' == self.calls[0][1]
|
assert 'test-payload' == self.calls[0][0].payload
|
||||||
|
|
||||||
def test_subscribe_topic_sys_root_and_wildcard_subtree_topic(self):
|
def test_subscribe_topic_sys_root_and_wildcard_subtree_topic(self):
|
||||||
"""Test the subscription of $ root and wildcard subtree topics."""
|
"""Test the subscription of $ root and wildcard subtree topics."""
|
||||||
|
@ -466,8 +466,8 @@ class TestMQTTCallbacks(unittest.TestCase):
|
||||||
|
|
||||||
self.hass.block_till_done()
|
self.hass.block_till_done()
|
||||||
assert 1 == len(self.calls)
|
assert 1 == len(self.calls)
|
||||||
assert '$test-topic/subtree/some-topic' == self.calls[0][0]
|
assert '$test-topic/subtree/some-topic' == self.calls[0][0].topic
|
||||||
assert 'test-payload' == self.calls[0][1]
|
assert 'test-payload' == self.calls[0][0].payload
|
||||||
|
|
||||||
def test_subscribe_special_characters(self):
|
def test_subscribe_special_characters(self):
|
||||||
"""Test the subscription to topics with special characters."""
|
"""Test the subscription to topics with special characters."""
|
||||||
|
@ -479,8 +479,8 @@ class TestMQTTCallbacks(unittest.TestCase):
|
||||||
fire_mqtt_message(self.hass, topic, payload)
|
fire_mqtt_message(self.hass, topic, payload)
|
||||||
self.hass.block_till_done()
|
self.hass.block_till_done()
|
||||||
assert 1 == len(self.calls)
|
assert 1 == len(self.calls)
|
||||||
assert topic == self.calls[0][0]
|
assert topic == self.calls[0][0].topic
|
||||||
assert payload == self.calls[0][1]
|
assert payload == self.calls[0][0].payload
|
||||||
|
|
||||||
def test_mqtt_failed_connection_results_in_disconnect(self):
|
def test_mqtt_failed_connection_results_in_disconnect(self):
|
||||||
"""Test if connection failure leads to disconnect."""
|
"""Test if connection failure leads to disconnect."""
|
||||||
|
|
|
@ -35,8 +35,8 @@ async def test_subscribe_topics(hass, mqtt_mock, caplog):
|
||||||
async_fire_mqtt_message(hass, 'test-topic1', 'test-payload1')
|
async_fire_mqtt_message(hass, 'test-topic1', 'test-payload1')
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert 1 == len(calls1)
|
assert 1 == len(calls1)
|
||||||
assert 'test-topic1' == calls1[0][0]
|
assert 'test-topic1' == calls1[0][0].topic
|
||||||
assert 'test-payload1' == calls1[0][1]
|
assert 'test-payload1' == calls1[0][0].payload
|
||||||
assert 0 == len(calls2)
|
assert 0 == len(calls2)
|
||||||
|
|
||||||
async_fire_mqtt_message(hass, 'test-topic2', 'test-payload2')
|
async_fire_mqtt_message(hass, 'test-topic2', 'test-payload2')
|
||||||
|
@ -44,8 +44,8 @@ async def test_subscribe_topics(hass, mqtt_mock, caplog):
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert 1 == len(calls1)
|
assert 1 == len(calls1)
|
||||||
assert 1 == len(calls2)
|
assert 1 == len(calls2)
|
||||||
assert 'test-topic2' == calls2[0][0]
|
assert 'test-topic2' == calls2[0][0].topic
|
||||||
assert 'test-payload2' == calls2[0][1]
|
assert 'test-payload2' == calls2[0][0].payload
|
||||||
|
|
||||||
await async_unsubscribe_topics(hass, sub_state)
|
await async_unsubscribe_topics(hass, sub_state)
|
||||||
|
|
||||||
|
@ -108,8 +108,8 @@ async def test_modify_topics(hass, mqtt_mock, caplog):
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert 2 == len(calls1)
|
assert 2 == len(calls1)
|
||||||
assert 'test-topic1_1' == calls1[1][0]
|
assert 'test-topic1_1' == calls1[1][0].topic
|
||||||
assert 'test-payload' == calls1[1][1]
|
assert 'test-payload' == calls1[1][0].payload
|
||||||
assert 1 == len(calls2)
|
assert 1 == len(calls2)
|
||||||
|
|
||||||
await async_unsubscribe_topics(hass, sub_state)
|
await async_unsubscribe_topics(hass, sub_state)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue