Add mqtt encoding support for publishing (#62739)
* encoding support for mqtt publishing - todo tests * signature allows None values for qos and retain * common test for mqtt publishing encoding * better test with command templates * more tests * fix tests alarm control panel+tests light basic * tests light json and template * add tests vacuum and fix tests light_template
This commit is contained in:
parent
2cc4d9846b
commit
d0c4f0fec4
33 changed files with 1283 additions and 27 deletions
|
@ -338,18 +338,53 @@ def _build_publish_data(topic: Any, qos: int, retain: bool) -> ServiceDataType:
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def publish(hass: HomeAssistant, topic, payload, qos=0, retain=False) -> None:
|
def publish(
|
||||||
"""Publish message to an MQTT topic."""
|
hass: HomeAssistant,
|
||||||
hass.add_job(async_publish, hass, topic, payload, qos, retain)
|
topic: str,
|
||||||
|
payload: PublishPayloadType,
|
||||||
|
qos: int | None = 0,
|
||||||
|
retain: bool | None = False,
|
||||||
|
encoding: str | None = DEFAULT_ENCODING,
|
||||||
|
) -> None:
|
||||||
|
"""Publish message to a MQTT topic."""
|
||||||
|
hass.add_job(async_publish, hass, topic, payload, qos, retain, encoding)
|
||||||
|
|
||||||
|
|
||||||
async def async_publish(
|
async def async_publish(
|
||||||
hass: HomeAssistant, topic: Any, payload, qos=0, retain=False
|
hass: HomeAssistant,
|
||||||
|
topic: str,
|
||||||
|
payload: PublishPayloadType,
|
||||||
|
qos: int | None = 0,
|
||||||
|
retain: bool | None = False,
|
||||||
|
encoding: str | None = DEFAULT_ENCODING,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Publish message to an MQTT topic."""
|
"""Publish message to a MQTT topic."""
|
||||||
await hass.data[DATA_MQTT].async_publish(
|
|
||||||
topic, str(payload) if not isinstance(payload, bytes) else payload, qos, retain
|
outgoing_payload = payload
|
||||||
|
if not isinstance(payload, bytes):
|
||||||
|
if not encoding:
|
||||||
|
_LOGGER.error(
|
||||||
|
"Can't pass-through payload for publishing %s on %s with no encoding set, need 'bytes' got %s",
|
||||||
|
payload,
|
||||||
|
topic,
|
||||||
|
type(payload),
|
||||||
)
|
)
|
||||||
|
return
|
||||||
|
outgoing_payload = str(payload)
|
||||||
|
if encoding != DEFAULT_ENCODING:
|
||||||
|
# a string is encoded as utf-8 by default, other encoding requires bytes as payload
|
||||||
|
try:
|
||||||
|
outgoing_payload = outgoing_payload.encode(encoding)
|
||||||
|
except (AttributeError, LookupError, UnicodeEncodeError):
|
||||||
|
_LOGGER.error(
|
||||||
|
"Can't encode payload for publishing %s on %s with encoding %s",
|
||||||
|
payload,
|
||||||
|
topic,
|
||||||
|
encoding,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
await hass.data[DATA_MQTT].async_publish(topic, outgoing_payload, qos, retain)
|
||||||
|
|
||||||
|
|
||||||
AsyncDeprecatedMessageCallbackType = Callable[
|
AsyncDeprecatedMessageCallbackType = Callable[
|
||||||
|
|
|
@ -40,7 +40,14 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||||
|
|
||||||
from . import PLATFORMS, MqttCommandTemplate, subscription
|
from . import PLATFORMS, MqttCommandTemplate, subscription
|
||||||
from .. import mqtt
|
from .. import mqtt
|
||||||
from .const import CONF_COMMAND_TOPIC, CONF_QOS, CONF_RETAIN, CONF_STATE_TOPIC, DOMAIN
|
from .const import (
|
||||||
|
CONF_COMMAND_TOPIC,
|
||||||
|
CONF_ENCODING,
|
||||||
|
CONF_QOS,
|
||||||
|
CONF_RETAIN,
|
||||||
|
CONF_STATE_TOPIC,
|
||||||
|
DOMAIN,
|
||||||
|
)
|
||||||
from .debug_info import log_messages
|
from .debug_info import log_messages
|
||||||
from .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
from .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
||||||
|
|
||||||
|
@ -326,6 +333,7 @@ class MqttAlarm(MqttEntity, alarm.AlarmControlPanelEntity):
|
||||||
payload,
|
payload,
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
||||||
def _validate_code(self, code, state):
|
def _validate_code(self, code, state):
|
||||||
|
|
|
@ -17,7 +17,7 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||||
|
|
||||||
from . import PLATFORMS
|
from . import PLATFORMS
|
||||||
from .. import mqtt
|
from .. import mqtt
|
||||||
from .const import CONF_COMMAND_TOPIC, CONF_QOS, CONF_RETAIN, DOMAIN
|
from .const import CONF_COMMAND_TOPIC, CONF_ENCODING, CONF_QOS, CONF_RETAIN, DOMAIN
|
||||||
from .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
from .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
||||||
|
|
||||||
CONF_PAYLOAD_PRESS = "payload_press"
|
CONF_PAYLOAD_PRESS = "payload_press"
|
||||||
|
@ -100,4 +100,5 @@ class MqttButton(MqttEntity, ButtonEntity):
|
||||||
self._config[CONF_PAYLOAD_PRESS],
|
self._config[CONF_PAYLOAD_PRESS],
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
|
@ -58,7 +58,7 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||||
|
|
||||||
from . import MQTT_BASE_PLATFORM_SCHEMA, PLATFORMS, MqttCommandTemplate, subscription
|
from . import MQTT_BASE_PLATFORM_SCHEMA, PLATFORMS, MqttCommandTemplate, subscription
|
||||||
from .. import mqtt
|
from .. import mqtt
|
||||||
from .const import CONF_QOS, CONF_RETAIN, DOMAIN
|
from .const import CONF_ENCODING, CONF_QOS, CONF_RETAIN, DOMAIN
|
||||||
from .debug_info import log_messages
|
from .debug_info import log_messages
|
||||||
from .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
from .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
||||||
|
|
||||||
|
@ -685,6 +685,7 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
||||||
payload,
|
payload,
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _set_temperature(
|
async def _set_temperature(
|
||||||
|
|
|
@ -42,7 +42,14 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||||
|
|
||||||
from . import PLATFORMS, MqttCommandTemplate, subscription
|
from . import PLATFORMS, MqttCommandTemplate, subscription
|
||||||
from .. import mqtt
|
from .. import mqtt
|
||||||
from .const import CONF_COMMAND_TOPIC, CONF_QOS, CONF_RETAIN, CONF_STATE_TOPIC, DOMAIN
|
from .const import (
|
||||||
|
CONF_COMMAND_TOPIC,
|
||||||
|
CONF_ENCODING,
|
||||||
|
CONF_QOS,
|
||||||
|
CONF_RETAIN,
|
||||||
|
CONF_STATE_TOPIC,
|
||||||
|
DOMAIN,
|
||||||
|
)
|
||||||
from .debug_info import log_messages
|
from .debug_info import log_messages
|
||||||
from .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
from .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
||||||
|
|
||||||
|
@ -547,6 +554,7 @@ class MqttCover(MqttEntity, CoverEntity):
|
||||||
self._config[CONF_PAYLOAD_OPEN],
|
self._config[CONF_PAYLOAD_OPEN],
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
if self._optimistic:
|
if self._optimistic:
|
||||||
# Optimistically assume that cover has changed state.
|
# Optimistically assume that cover has changed state.
|
||||||
|
@ -568,6 +576,7 @@ class MqttCover(MqttEntity, CoverEntity):
|
||||||
self._config[CONF_PAYLOAD_CLOSE],
|
self._config[CONF_PAYLOAD_CLOSE],
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
if self._optimistic:
|
if self._optimistic:
|
||||||
# Optimistically assume that cover has changed state.
|
# Optimistically assume that cover has changed state.
|
||||||
|
@ -589,6 +598,7 @@ class MqttCover(MqttEntity, CoverEntity):
|
||||||
self._config[CONF_PAYLOAD_STOP],
|
self._config[CONF_PAYLOAD_STOP],
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
||||||
async def async_open_cover_tilt(self, **kwargs):
|
async def async_open_cover_tilt(self, **kwargs):
|
||||||
|
@ -599,6 +609,7 @@ class MqttCover(MqttEntity, CoverEntity):
|
||||||
self._config[CONF_TILT_OPEN_POSITION],
|
self._config[CONF_TILT_OPEN_POSITION],
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
if self._tilt_optimistic:
|
if self._tilt_optimistic:
|
||||||
self._tilt_value = self.find_percentage_in_range(
|
self._tilt_value = self.find_percentage_in_range(
|
||||||
|
@ -614,6 +625,7 @@ class MqttCover(MqttEntity, CoverEntity):
|
||||||
self._config[CONF_TILT_CLOSED_POSITION],
|
self._config[CONF_TILT_CLOSED_POSITION],
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
if self._tilt_optimistic:
|
if self._tilt_optimistic:
|
||||||
self._tilt_value = self.find_percentage_in_range(
|
self._tilt_value = self.find_percentage_in_range(
|
||||||
|
@ -643,6 +655,7 @@ class MqttCover(MqttEntity, CoverEntity):
|
||||||
tilt,
|
tilt,
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
if self._tilt_optimistic:
|
if self._tilt_optimistic:
|
||||||
_LOGGER.debug("Set tilt value optimistic")
|
_LOGGER.debug("Set tilt value optimistic")
|
||||||
|
@ -670,6 +683,7 @@ class MqttCover(MqttEntity, CoverEntity):
|
||||||
position,
|
position,
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
if self._optimistic:
|
if self._optimistic:
|
||||||
self._state = (
|
self._state = (
|
||||||
|
|
|
@ -42,7 +42,14 @@ from homeassistant.util.percentage import (
|
||||||
|
|
||||||
from . import PLATFORMS, MqttCommandTemplate, subscription
|
from . import PLATFORMS, MqttCommandTemplate, subscription
|
||||||
from .. import mqtt
|
from .. import mqtt
|
||||||
from .const import CONF_COMMAND_TOPIC, CONF_QOS, CONF_RETAIN, CONF_STATE_TOPIC, DOMAIN
|
from .const import (
|
||||||
|
CONF_COMMAND_TOPIC,
|
||||||
|
CONF_ENCODING,
|
||||||
|
CONF_QOS,
|
||||||
|
CONF_RETAIN,
|
||||||
|
CONF_STATE_TOPIC,
|
||||||
|
DOMAIN,
|
||||||
|
)
|
||||||
from .debug_info import log_messages
|
from .debug_info import log_messages
|
||||||
from .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
from .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
||||||
|
|
||||||
|
@ -542,6 +549,7 @@ class MqttFan(MqttEntity, FanEntity):
|
||||||
mqtt_payload,
|
mqtt_payload,
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
if percentage:
|
if percentage:
|
||||||
await self.async_set_percentage(percentage)
|
await self.async_set_percentage(percentage)
|
||||||
|
@ -563,6 +571,7 @@ class MqttFan(MqttEntity, FanEntity):
|
||||||
mqtt_payload,
|
mqtt_payload,
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
if self._optimistic:
|
if self._optimistic:
|
||||||
self._state = False
|
self._state = False
|
||||||
|
@ -583,6 +592,7 @@ class MqttFan(MqttEntity, FanEntity):
|
||||||
mqtt_payload,
|
mqtt_payload,
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
||||||
if self._optimistic_percentage:
|
if self._optimistic_percentage:
|
||||||
|
@ -606,6 +616,7 @@ class MqttFan(MqttEntity, FanEntity):
|
||||||
mqtt_payload,
|
mqtt_payload,
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
||||||
if self._optimistic_preset_mode:
|
if self._optimistic_preset_mode:
|
||||||
|
@ -632,6 +643,7 @@ class MqttFan(MqttEntity, FanEntity):
|
||||||
mqtt_payload,
|
mqtt_payload,
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
||||||
if self._optimistic_oscillation:
|
if self._optimistic_oscillation:
|
||||||
|
|
|
@ -32,7 +32,14 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||||
|
|
||||||
from . import PLATFORMS, MqttCommandTemplate, subscription
|
from . import PLATFORMS, MqttCommandTemplate, subscription
|
||||||
from .. import mqtt
|
from .. import mqtt
|
||||||
from .const import CONF_COMMAND_TOPIC, CONF_QOS, CONF_RETAIN, CONF_STATE_TOPIC, DOMAIN
|
from .const import (
|
||||||
|
CONF_COMMAND_TOPIC,
|
||||||
|
CONF_ENCODING,
|
||||||
|
CONF_QOS,
|
||||||
|
CONF_RETAIN,
|
||||||
|
CONF_STATE_TOPIC,
|
||||||
|
DOMAIN,
|
||||||
|
)
|
||||||
from .debug_info import log_messages
|
from .debug_info import log_messages
|
||||||
from .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
from .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
||||||
|
|
||||||
|
@ -408,6 +415,7 @@ class MqttHumidifier(MqttEntity, HumidifierEntity):
|
||||||
mqtt_payload,
|
mqtt_payload,
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
if self._optimistic:
|
if self._optimistic:
|
||||||
self._state = True
|
self._state = True
|
||||||
|
@ -425,6 +433,7 @@ class MqttHumidifier(MqttEntity, HumidifierEntity):
|
||||||
mqtt_payload,
|
mqtt_payload,
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
if self._optimistic:
|
if self._optimistic:
|
||||||
self._state = False
|
self._state = False
|
||||||
|
@ -442,6 +451,7 @@ class MqttHumidifier(MqttEntity, HumidifierEntity):
|
||||||
mqtt_payload,
|
mqtt_payload,
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
||||||
if self._optimistic_target_humidity:
|
if self._optimistic_target_humidity:
|
||||||
|
@ -465,6 +475,7 @@ class MqttHumidifier(MqttEntity, HumidifierEntity):
|
||||||
mqtt_payload,
|
mqtt_payload,
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
||||||
if self._optimistic_mode:
|
if self._optimistic_mode:
|
||||||
|
|
|
@ -53,7 +53,13 @@ import homeassistant.util.color as color_util
|
||||||
|
|
||||||
from .. import subscription
|
from .. import subscription
|
||||||
from ... import mqtt
|
from ... import mqtt
|
||||||
from ..const import CONF_COMMAND_TOPIC, CONF_QOS, CONF_RETAIN, CONF_STATE_TOPIC
|
from ..const import (
|
||||||
|
CONF_COMMAND_TOPIC,
|
||||||
|
CONF_ENCODING,
|
||||||
|
CONF_QOS,
|
||||||
|
CONF_RETAIN,
|
||||||
|
CONF_STATE_TOPIC,
|
||||||
|
)
|
||||||
from ..debug_info import log_messages
|
from ..debug_info import log_messages
|
||||||
from ..mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity
|
from ..mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity
|
||||||
from .schema import MQTT_LIGHT_SCHEMA_SCHEMA
|
from .schema import MQTT_LIGHT_SCHEMA_SCHEMA
|
||||||
|
@ -821,6 +827,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
payload,
|
payload,
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
||||||
def scale_rgbx(color, brightness=None):
|
def scale_rgbx(color, brightness=None):
|
||||||
|
@ -1069,6 +1076,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
self._payload["off"],
|
self._payload["off"],
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
||||||
if self._optimistic:
|
if self._optimistic:
|
||||||
|
|
|
@ -59,7 +59,13 @@ import homeassistant.util.color as color_util
|
||||||
|
|
||||||
from .. import subscription
|
from .. import subscription
|
||||||
from ... import mqtt
|
from ... import mqtt
|
||||||
from ..const import CONF_COMMAND_TOPIC, CONF_QOS, CONF_RETAIN, CONF_STATE_TOPIC
|
from ..const import (
|
||||||
|
CONF_COMMAND_TOPIC,
|
||||||
|
CONF_ENCODING,
|
||||||
|
CONF_QOS,
|
||||||
|
CONF_RETAIN,
|
||||||
|
CONF_STATE_TOPIC,
|
||||||
|
)
|
||||||
from ..debug_info import log_messages
|
from ..debug_info import log_messages
|
||||||
from ..mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity
|
from ..mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity
|
||||||
from .schema import MQTT_LIGHT_SCHEMA_SCHEMA
|
from .schema import MQTT_LIGHT_SCHEMA_SCHEMA
|
||||||
|
@ -629,6 +635,7 @@ class MqttLightJson(MqttEntity, LightEntity, RestoreEntity):
|
||||||
json.dumps(message),
|
json.dumps(message),
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
||||||
if self._optimistic:
|
if self._optimistic:
|
||||||
|
@ -654,6 +661,7 @@ class MqttLightJson(MqttEntity, LightEntity, RestoreEntity):
|
||||||
json.dumps(message),
|
json.dumps(message),
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
||||||
if self._optimistic:
|
if self._optimistic:
|
||||||
|
|
|
@ -35,7 +35,13 @@ import homeassistant.util.color as color_util
|
||||||
|
|
||||||
from .. import subscription
|
from .. import subscription
|
||||||
from ... import mqtt
|
from ... import mqtt
|
||||||
from ..const import CONF_COMMAND_TOPIC, CONF_QOS, CONF_RETAIN, CONF_STATE_TOPIC
|
from ..const import (
|
||||||
|
CONF_COMMAND_TOPIC,
|
||||||
|
CONF_ENCODING,
|
||||||
|
CONF_QOS,
|
||||||
|
CONF_RETAIN,
|
||||||
|
CONF_STATE_TOPIC,
|
||||||
|
)
|
||||||
from ..debug_info import log_messages
|
from ..debug_info import log_messages
|
||||||
from ..mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity
|
from ..mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity
|
||||||
from .schema import MQTT_LIGHT_SCHEMA_SCHEMA
|
from .schema import MQTT_LIGHT_SCHEMA_SCHEMA
|
||||||
|
@ -384,6 +390,7 @@ class MqttLightTemplate(MqttEntity, LightEntity, RestoreEntity):
|
||||||
),
|
),
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
||||||
if self._optimistic:
|
if self._optimistic:
|
||||||
|
@ -409,6 +416,7 @@ class MqttLightTemplate(MqttEntity, LightEntity, RestoreEntity):
|
||||||
),
|
),
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
||||||
if self._optimistic:
|
if self._optimistic:
|
||||||
|
|
|
@ -17,7 +17,14 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||||
|
|
||||||
from . import PLATFORMS, subscription
|
from . import PLATFORMS, subscription
|
||||||
from .. import mqtt
|
from .. import mqtt
|
||||||
from .const import CONF_COMMAND_TOPIC, CONF_QOS, CONF_RETAIN, CONF_STATE_TOPIC, DOMAIN
|
from .const import (
|
||||||
|
CONF_COMMAND_TOPIC,
|
||||||
|
CONF_ENCODING,
|
||||||
|
CONF_QOS,
|
||||||
|
CONF_RETAIN,
|
||||||
|
CONF_STATE_TOPIC,
|
||||||
|
DOMAIN,
|
||||||
|
)
|
||||||
from .debug_info import log_messages
|
from .debug_info import log_messages
|
||||||
from .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
from .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
||||||
|
|
||||||
|
@ -175,6 +182,7 @@ class MqttLock(MqttEntity, LockEntity):
|
||||||
self._config[CONF_PAYLOAD_LOCK],
|
self._config[CONF_PAYLOAD_LOCK],
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
if self._optimistic:
|
if self._optimistic:
|
||||||
# Optimistically assume that the lock has changed state.
|
# Optimistically assume that the lock has changed state.
|
||||||
|
@ -192,6 +200,7 @@ class MqttLock(MqttEntity, LockEntity):
|
||||||
self._config[CONF_PAYLOAD_UNLOCK],
|
self._config[CONF_PAYLOAD_UNLOCK],
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
if self._optimistic:
|
if self._optimistic:
|
||||||
# Optimistically assume that the lock has changed state.
|
# Optimistically assume that the lock has changed state.
|
||||||
|
@ -209,6 +218,7 @@ class MqttLock(MqttEntity, LockEntity):
|
||||||
self._config[CONF_PAYLOAD_OPEN],
|
self._config[CONF_PAYLOAD_OPEN],
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
if self._optimistic:
|
if self._optimistic:
|
||||||
# Optimistically assume that the lock unlocks when opened.
|
# Optimistically assume that the lock unlocks when opened.
|
||||||
|
|
|
@ -29,7 +29,14 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||||
|
|
||||||
from . import PLATFORMS, MqttCommandTemplate, subscription
|
from . import PLATFORMS, MqttCommandTemplate, subscription
|
||||||
from .. import mqtt
|
from .. import mqtt
|
||||||
from .const import CONF_COMMAND_TOPIC, CONF_QOS, CONF_RETAIN, CONF_STATE_TOPIC, DOMAIN
|
from .const import (
|
||||||
|
CONF_COMMAND_TOPIC,
|
||||||
|
CONF_ENCODING,
|
||||||
|
CONF_QOS,
|
||||||
|
CONF_RETAIN,
|
||||||
|
CONF_STATE_TOPIC,
|
||||||
|
DOMAIN,
|
||||||
|
)
|
||||||
from .debug_info import log_messages
|
from .debug_info import log_messages
|
||||||
from .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
from .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
||||||
|
|
||||||
|
@ -258,6 +265,7 @@ class MqttNumber(MqttEntity, NumberEntity, RestoreEntity):
|
||||||
payload,
|
payload,
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -17,7 +17,7 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||||
|
|
||||||
from . import PLATFORMS
|
from . import PLATFORMS
|
||||||
from .. import mqtt
|
from .. import mqtt
|
||||||
from .const import CONF_COMMAND_TOPIC, CONF_QOS, CONF_RETAIN, DOMAIN
|
from .const import CONF_COMMAND_TOPIC, CONF_ENCODING, CONF_QOS, CONF_RETAIN, DOMAIN
|
||||||
from .mixins import (
|
from .mixins import (
|
||||||
CONF_OBJECT_ID,
|
CONF_OBJECT_ID,
|
||||||
MQTT_AVAILABILITY_SCHEMA,
|
MQTT_AVAILABILITY_SCHEMA,
|
||||||
|
@ -153,4 +153,5 @@ class MqttScene(
|
||||||
self._config[CONF_PAYLOAD_ON],
|
self._config[CONF_PAYLOAD_ON],
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
|
@ -19,7 +19,14 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||||
|
|
||||||
from . import PLATFORMS, MqttCommandTemplate, subscription
|
from . import PLATFORMS, MqttCommandTemplate, subscription
|
||||||
from .. import mqtt
|
from .. import mqtt
|
||||||
from .const import CONF_COMMAND_TOPIC, CONF_QOS, CONF_RETAIN, CONF_STATE_TOPIC, DOMAIN
|
from .const import (
|
||||||
|
CONF_COMMAND_TOPIC,
|
||||||
|
CONF_ENCODING,
|
||||||
|
CONF_QOS,
|
||||||
|
CONF_RETAIN,
|
||||||
|
CONF_STATE_TOPIC,
|
||||||
|
DOMAIN,
|
||||||
|
)
|
||||||
from .debug_info import log_messages
|
from .debug_info import log_messages
|
||||||
from .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
from .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
||||||
|
|
||||||
|
@ -184,6 +191,7 @@ class MqttSelect(MqttEntity, SelectEntity, RestoreEntity):
|
||||||
payload,
|
payload,
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -26,7 +26,14 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||||
|
|
||||||
from . import PLATFORMS, subscription
|
from . import PLATFORMS, subscription
|
||||||
from .. import mqtt
|
from .. import mqtt
|
||||||
from .const import CONF_COMMAND_TOPIC, CONF_QOS, CONF_RETAIN, CONF_STATE_TOPIC, DOMAIN
|
from .const import (
|
||||||
|
CONF_COMMAND_TOPIC,
|
||||||
|
CONF_ENCODING,
|
||||||
|
CONF_QOS,
|
||||||
|
CONF_RETAIN,
|
||||||
|
CONF_STATE_TOPIC,
|
||||||
|
DOMAIN,
|
||||||
|
)
|
||||||
from .debug_info import log_messages
|
from .debug_info import log_messages
|
||||||
from .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
from .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
||||||
|
|
||||||
|
@ -188,6 +195,7 @@ class MqttSwitch(MqttEntity, SwitchEntity, RestoreEntity):
|
||||||
self._config[CONF_PAYLOAD_ON],
|
self._config[CONF_PAYLOAD_ON],
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
if self._optimistic:
|
if self._optimistic:
|
||||||
# Optimistically assume that switch has changed state.
|
# Optimistically assume that switch has changed state.
|
||||||
|
@ -205,6 +213,7 @@ class MqttSwitch(MqttEntity, SwitchEntity, RestoreEntity):
|
||||||
self._config[CONF_PAYLOAD_OFF],
|
self._config[CONF_PAYLOAD_OFF],
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
if self._optimistic:
|
if self._optimistic:
|
||||||
# Optimistically assume that switch has changed state.
|
# Optimistically assume that switch has changed state.
|
||||||
|
|
|
@ -26,7 +26,7 @@ from homeassistant.helpers.icon import icon_for_battery_level
|
||||||
|
|
||||||
from .. import subscription
|
from .. import subscription
|
||||||
from ... import mqtt
|
from ... import mqtt
|
||||||
from ..const import CONF_COMMAND_TOPIC, CONF_QOS, CONF_RETAIN
|
from ..const import CONF_COMMAND_TOPIC, CONF_ENCODING, CONF_QOS, CONF_RETAIN
|
||||||
from ..debug_info import log_messages
|
from ..debug_info import log_messages
|
||||||
from ..mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity
|
from ..mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity
|
||||||
from .const import MQTT_VACUUM_ATTRIBUTES_BLOCKED
|
from .const import MQTT_VACUUM_ATTRIBUTES_BLOCKED
|
||||||
|
@ -199,6 +199,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
||||||
self._fan_speed_list = config[CONF_FAN_SPEED_LIST]
|
self._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]
|
||||||
|
|
||||||
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)
|
||||||
|
@ -388,6 +389,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
||||||
self._payloads[CONF_PAYLOAD_TURN_ON],
|
self._payloads[CONF_PAYLOAD_TURN_ON],
|
||||||
self._qos,
|
self._qos,
|
||||||
self._retain,
|
self._retain,
|
||||||
|
self._encoding,
|
||||||
)
|
)
|
||||||
self._status = "Cleaning"
|
self._status = "Cleaning"
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
@ -403,6 +405,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
||||||
self._payloads[CONF_PAYLOAD_TURN_OFF],
|
self._payloads[CONF_PAYLOAD_TURN_OFF],
|
||||||
self._qos,
|
self._qos,
|
||||||
self._retain,
|
self._retain,
|
||||||
|
self._encoding,
|
||||||
)
|
)
|
||||||
self._status = "Turning Off"
|
self._status = "Turning Off"
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
@ -418,6 +421,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
||||||
self._payloads[CONF_PAYLOAD_STOP],
|
self._payloads[CONF_PAYLOAD_STOP],
|
||||||
self._qos,
|
self._qos,
|
||||||
self._retain,
|
self._retain,
|
||||||
|
self._encoding,
|
||||||
)
|
)
|
||||||
self._status = "Stopping the current task"
|
self._status = "Stopping the current task"
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
@ -433,6 +437,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
||||||
self._payloads[CONF_PAYLOAD_CLEAN_SPOT],
|
self._payloads[CONF_PAYLOAD_CLEAN_SPOT],
|
||||||
self._qos,
|
self._qos,
|
||||||
self._retain,
|
self._retain,
|
||||||
|
self._encoding,
|
||||||
)
|
)
|
||||||
self._status = "Cleaning spot"
|
self._status = "Cleaning spot"
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
@ -448,6 +453,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
||||||
self._payloads[CONF_PAYLOAD_LOCATE],
|
self._payloads[CONF_PAYLOAD_LOCATE],
|
||||||
self._qos,
|
self._qos,
|
||||||
self._retain,
|
self._retain,
|
||||||
|
self._encoding,
|
||||||
)
|
)
|
||||||
self._status = "Hi, I'm over here!"
|
self._status = "Hi, I'm over here!"
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
@ -463,6 +469,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
||||||
self._payloads[CONF_PAYLOAD_START_PAUSE],
|
self._payloads[CONF_PAYLOAD_START_PAUSE],
|
||||||
self._qos,
|
self._qos,
|
||||||
self._retain,
|
self._retain,
|
||||||
|
self._encoding,
|
||||||
)
|
)
|
||||||
self._status = "Pausing/Resuming cleaning..."
|
self._status = "Pausing/Resuming cleaning..."
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
@ -478,6 +485,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
||||||
self._payloads[CONF_PAYLOAD_RETURN_TO_BASE],
|
self._payloads[CONF_PAYLOAD_RETURN_TO_BASE],
|
||||||
self._qos,
|
self._qos,
|
||||||
self._retain,
|
self._retain,
|
||||||
|
self._encoding,
|
||||||
)
|
)
|
||||||
self._status = "Returning home..."
|
self._status = "Returning home..."
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
@ -490,7 +498,12 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
await mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass, self._set_fan_speed_topic, fan_speed, self._qos, self._retain
|
self.hass,
|
||||||
|
self._set_fan_speed_topic,
|
||||||
|
fan_speed,
|
||||||
|
self._qos,
|
||||||
|
self._retain,
|
||||||
|
self._encoding,
|
||||||
)
|
)
|
||||||
self._status = f"Setting fan to {fan_speed}..."
|
self._status = f"Setting fan to {fan_speed}..."
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
@ -506,7 +519,12 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
||||||
else:
|
else:
|
||||||
message = command
|
message = command
|
||||||
await mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass, self._send_command_topic, message, self._qos, self._retain
|
self.hass,
|
||||||
|
self._send_command_topic,
|
||||||
|
message,
|
||||||
|
self._qos,
|
||||||
|
self._retain,
|
||||||
|
self._encoding,
|
||||||
)
|
)
|
||||||
self._status = f"Sending command {message}..."
|
self._status = f"Sending command {message}..."
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
|
@ -29,7 +29,13 @@ import homeassistant.helpers.config_validation as cv
|
||||||
|
|
||||||
from .. import subscription
|
from .. import subscription
|
||||||
from ... import mqtt
|
from ... import mqtt
|
||||||
from ..const import CONF_COMMAND_TOPIC, CONF_QOS, CONF_RETAIN, CONF_STATE_TOPIC
|
from ..const import (
|
||||||
|
CONF_COMMAND_TOPIC,
|
||||||
|
CONF_ENCODING,
|
||||||
|
CONF_QOS,
|
||||||
|
CONF_RETAIN,
|
||||||
|
CONF_STATE_TOPIC,
|
||||||
|
)
|
||||||
from ..debug_info import log_messages
|
from ..debug_info import log_messages
|
||||||
from ..mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity
|
from ..mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity
|
||||||
from .const import MQTT_VACUUM_ATTRIBUTES_BLOCKED
|
from .const import MQTT_VACUUM_ATTRIBUTES_BLOCKED
|
||||||
|
@ -248,6 +254,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
|
||||||
self._config[CONF_PAYLOAD_START],
|
self._config[CONF_PAYLOAD_START],
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
||||||
async def async_pause(self):
|
async def async_pause(self):
|
||||||
|
@ -260,6 +267,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
|
||||||
self._config[CONF_PAYLOAD_PAUSE],
|
self._config[CONF_PAYLOAD_PAUSE],
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
||||||
async def async_stop(self, **kwargs):
|
async def async_stop(self, **kwargs):
|
||||||
|
@ -272,6 +280,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
|
||||||
self._config[CONF_PAYLOAD_STOP],
|
self._config[CONF_PAYLOAD_STOP],
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
||||||
async def async_set_fan_speed(self, fan_speed, **kwargs):
|
async def async_set_fan_speed(self, fan_speed, **kwargs):
|
||||||
|
@ -286,6 +295,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
|
||||||
fan_speed,
|
fan_speed,
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
||||||
async def async_return_to_base(self, **kwargs):
|
async def async_return_to_base(self, **kwargs):
|
||||||
|
@ -298,6 +308,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
|
||||||
self._config[CONF_PAYLOAD_RETURN_TO_BASE],
|
self._config[CONF_PAYLOAD_RETURN_TO_BASE],
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
||||||
async def async_clean_spot(self, **kwargs):
|
async def async_clean_spot(self, **kwargs):
|
||||||
|
@ -310,6 +321,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
|
||||||
self._config[CONF_PAYLOAD_CLEAN_SPOT],
|
self._config[CONF_PAYLOAD_CLEAN_SPOT],
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
||||||
async def async_locate(self, **kwargs):
|
async def async_locate(self, **kwargs):
|
||||||
|
@ -322,6 +334,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
|
||||||
self._config[CONF_PAYLOAD_LOCATE],
|
self._config[CONF_PAYLOAD_LOCATE],
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
||||||
async def async_send_command(self, command, params=None, **kwargs):
|
async def async_send_command(self, command, params=None, **kwargs):
|
||||||
|
@ -340,4 +353,5 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
|
||||||
message,
|
message,
|
||||||
self._config[CONF_QOS],
|
self._config[CONF_QOS],
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
|
self._config[CONF_ENCODING],
|
||||||
)
|
)
|
||||||
|
|
|
@ -50,6 +50,7 @@ from .test_common import (
|
||||||
help_test_entity_device_info_with_identifier,
|
help_test_entity_device_info_with_identifier,
|
||||||
help_test_entity_id_update_discovery_update,
|
help_test_entity_id_update_discovery_update,
|
||||||
help_test_entity_id_update_subscriptions,
|
help_test_entity_id_update_subscriptions,
|
||||||
|
help_test_publishing_with_custom_encoding,
|
||||||
help_test_setting_attribute_via_mqtt_json_message,
|
help_test_setting_attribute_via_mqtt_json_message,
|
||||||
help_test_setting_attribute_with_template,
|
help_test_setting_attribute_with_template,
|
||||||
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
||||||
|
@ -750,3 +751,58 @@ async def test_entity_debug_info_message(hass, mqtt_mock):
|
||||||
await help_test_entity_debug_info_message(
|
await help_test_entity_debug_info_message(
|
||||||
hass, mqtt_mock, alarm_control_panel.DOMAIN, DEFAULT_CONFIG
|
hass, mqtt_mock, alarm_control_panel.DOMAIN, DEFAULT_CONFIG
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"service,topic,parameters,payload,template,tpl_par,tpl_output",
|
||||||
|
[
|
||||||
|
(
|
||||||
|
alarm_control_panel.SERVICE_ALARM_ARM_AWAY,
|
||||||
|
"command_topic",
|
||||||
|
{"code": "secret"},
|
||||||
|
"ARM_AWAY",
|
||||||
|
"command_template",
|
||||||
|
"code",
|
||||||
|
b"s",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
alarm_control_panel.SERVICE_ALARM_DISARM,
|
||||||
|
"command_topic",
|
||||||
|
{"code": "secret"},
|
||||||
|
"DISARM",
|
||||||
|
"command_template",
|
||||||
|
"code",
|
||||||
|
b"s",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
tpl_par,
|
||||||
|
tpl_output,
|
||||||
|
):
|
||||||
|
"""Test publishing MQTT payload with different encoding."""
|
||||||
|
domain = alarm_control_panel.DOMAIN
|
||||||
|
config = DEFAULT_CONFIG[domain]
|
||||||
|
|
||||||
|
await help_test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
domain,
|
||||||
|
config,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
tpl_par=tpl_par,
|
||||||
|
tpl_output=tpl_output,
|
||||||
|
)
|
||||||
|
|
|
@ -23,6 +23,7 @@ from .test_common import (
|
||||||
help_test_entity_device_info_with_connection,
|
help_test_entity_device_info_with_connection,
|
||||||
help_test_entity_device_info_with_identifier,
|
help_test_entity_device_info_with_identifier,
|
||||||
help_test_entity_id_update_discovery_update,
|
help_test_entity_id_update_discovery_update,
|
||||||
|
help_test_publishing_with_custom_encoding,
|
||||||
help_test_setting_attribute_via_mqtt_json_message,
|
help_test_setting_attribute_via_mqtt_json_message,
|
||||||
help_test_setting_attribute_with_template,
|
help_test_setting_attribute_with_template,
|
||||||
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
||||||
|
@ -321,3 +322,30 @@ async def test_valid_device_class(hass, mqtt_mock):
|
||||||
assert state.attributes["device_class"] == button.ButtonDeviceClass.RESTART
|
assert state.attributes["device_class"] == button.ButtonDeviceClass.RESTART
|
||||||
state = hass.states.get("button.test_3")
|
state = hass.states.get("button.test_3")
|
||||||
assert "device_class" not in state.attributes
|
assert "device_class" not in state.attributes
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"service,topic,parameters,payload,template",
|
||||||
|
[
|
||||||
|
(button.SERVICE_PRESS, "command_topic", None, "PRESS", None),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_publishing_with_custom_encoding(
|
||||||
|
hass, mqtt_mock, caplog, service, topic, parameters, payload, template
|
||||||
|
):
|
||||||
|
"""Test publishing MQTT payload with different encoding."""
|
||||||
|
domain = button.DOMAIN
|
||||||
|
config = DEFAULT_CONFIG[domain]
|
||||||
|
|
||||||
|
await help_test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
domain,
|
||||||
|
config,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
)
|
||||||
|
|
|
@ -6,6 +6,7 @@ from unittest.mock import call, patch
|
||||||
import pytest
|
import pytest
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.components import climate
|
||||||
from homeassistant.components.climate import DEFAULT_MAX_TEMP, DEFAULT_MIN_TEMP
|
from homeassistant.components.climate import DEFAULT_MAX_TEMP, DEFAULT_MIN_TEMP
|
||||||
from homeassistant.components.climate.const import (
|
from homeassistant.components.climate.const import (
|
||||||
ATTR_HVAC_ACTION,
|
ATTR_HVAC_ACTION,
|
||||||
|
@ -46,6 +47,7 @@ from .test_common import (
|
||||||
help_test_entity_device_info_with_identifier,
|
help_test_entity_device_info_with_identifier,
|
||||||
help_test_entity_id_update_discovery_update,
|
help_test_entity_id_update_discovery_update,
|
||||||
help_test_entity_id_update_subscriptions,
|
help_test_entity_id_update_subscriptions,
|
||||||
|
help_test_publishing_with_custom_encoding,
|
||||||
help_test_setting_attribute_via_mqtt_json_message,
|
help_test_setting_attribute_via_mqtt_json_message,
|
||||||
help_test_setting_attribute_with_template,
|
help_test_setting_attribute_with_template,
|
||||||
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
||||||
|
@ -1133,3 +1135,121 @@ async def test_precision_whole(hass, mqtt_mock):
|
||||||
state = hass.states.get(ENTITY_CLIMATE)
|
state = hass.states.get(ENTITY_CLIMATE)
|
||||||
assert state.attributes.get("temperature") == 24.0
|
assert state.attributes.get("temperature") == 24.0
|
||||||
mqtt_mock.async_publish.reset_mock()
|
mqtt_mock.async_publish.reset_mock()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"service,topic,parameters,payload,template",
|
||||||
|
[
|
||||||
|
(
|
||||||
|
climate.SERVICE_TURN_ON,
|
||||||
|
"power_command_topic",
|
||||||
|
None,
|
||||||
|
"ON",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
climate.SERVICE_SET_HVAC_MODE,
|
||||||
|
"mode_command_topic",
|
||||||
|
{"hvac_mode": "cool"},
|
||||||
|
"cool",
|
||||||
|
"mode_command_template",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
climate.SERVICE_SET_PRESET_MODE,
|
||||||
|
"away_mode_command_topic",
|
||||||
|
{"preset_mode": "away"},
|
||||||
|
"ON",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
climate.SERVICE_SET_PRESET_MODE,
|
||||||
|
"hold_command_topic",
|
||||||
|
{"preset_mode": "eco"},
|
||||||
|
"eco",
|
||||||
|
"hold_command_template",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
climate.SERVICE_SET_PRESET_MODE,
|
||||||
|
"hold_command_topic",
|
||||||
|
{"preset_mode": "some_hold_mode"},
|
||||||
|
"some_hold_mode",
|
||||||
|
"hold_command_template",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
climate.SERVICE_SET_FAN_MODE,
|
||||||
|
"fan_mode_command_topic",
|
||||||
|
{"fan_mode": "medium"},
|
||||||
|
"medium",
|
||||||
|
"fan_mode_command_template",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
climate.SERVICE_SET_SWING_MODE,
|
||||||
|
"swing_mode_command_topic",
|
||||||
|
{"swing_mode": "on"},
|
||||||
|
"on",
|
||||||
|
"swing_mode_command_template",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
climate.SERVICE_SET_AUX_HEAT,
|
||||||
|
"aux_command_topic",
|
||||||
|
{"aux_heat": "on"},
|
||||||
|
"ON",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
climate.SERVICE_SET_TEMPERATURE,
|
||||||
|
"temperature_command_topic",
|
||||||
|
{"temperature": "20.1"},
|
||||||
|
20.1,
|
||||||
|
"temperature_command_template",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
climate.SERVICE_SET_TEMPERATURE,
|
||||||
|
"temperature_low_command_topic",
|
||||||
|
{
|
||||||
|
"temperature": "20.1",
|
||||||
|
"target_temp_low": "15.1",
|
||||||
|
"target_temp_high": "29.8",
|
||||||
|
},
|
||||||
|
15.1,
|
||||||
|
"temperature_low_command_template",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
climate.SERVICE_SET_TEMPERATURE,
|
||||||
|
"temperature_high_command_topic",
|
||||||
|
{
|
||||||
|
"temperature": "20.1",
|
||||||
|
"target_temp_low": "15.1",
|
||||||
|
"target_temp_high": "29.8",
|
||||||
|
},
|
||||||
|
29.8,
|
||||||
|
"temperature_high_command_template",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
):
|
||||||
|
"""Test publishing MQTT payload with different encoding."""
|
||||||
|
domain = climate.DOMAIN
|
||||||
|
config = DEFAULT_CONFIG[domain]
|
||||||
|
|
||||||
|
await help_test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
domain,
|
||||||
|
config,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
)
|
||||||
|
|
|
@ -8,7 +8,7 @@ from homeassistant.components import mqtt
|
||||||
from homeassistant.components.mqtt import debug_info
|
from homeassistant.components.mqtt import debug_info
|
||||||
from homeassistant.components.mqtt.const import MQTT_DISCONNECTED
|
from homeassistant.components.mqtt.const import MQTT_DISCONNECTED
|
||||||
from homeassistant.components.mqtt.mixins import MQTT_ATTRIBUTES_BLOCKED
|
from homeassistant.components.mqtt.mixins import MQTT_ATTRIBUTES_BLOCKED
|
||||||
from homeassistant.const import ATTR_ASSUMED_STATE, STATE_UNAVAILABLE
|
from homeassistant.const import ATTR_ASSUMED_STATE, ATTR_ENTITY_ID, STATE_UNAVAILABLE
|
||||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
@ -1266,3 +1266,120 @@ async def help_test_entity_category(hass, mqtt_mock, domain, config):
|
||||||
async_fire_mqtt_message(hass, f"homeassistant/{domain}/{unique_id}/config", data)
|
async_fire_mqtt_message(hass, f"homeassistant/{domain}/{unique_id}/config", data)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert not ent_registry.async_get_entity_id(domain, mqtt.DOMAIN, unique_id)
|
assert not ent_registry.async_get_entity_id(domain, mqtt.DOMAIN, unique_id)
|
||||||
|
|
||||||
|
|
||||||
|
async def help_test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
domain,
|
||||||
|
config,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
tpl_par="value",
|
||||||
|
tpl_output=None,
|
||||||
|
):
|
||||||
|
"""Test a service with publishing MQTT payload with different encoding."""
|
||||||
|
# prepare config for tests
|
||||||
|
test_config = {
|
||||||
|
"test1": {"encoding": None, "cmd_tpl": False},
|
||||||
|
"test2": {"encoding": "utf-16", "cmd_tpl": False},
|
||||||
|
"test3": {"encoding": "", "cmd_tpl": False},
|
||||||
|
"test4": {"encoding": "invalid", "cmd_tpl": False},
|
||||||
|
"test5": {"encoding": "", "cmd_tpl": True},
|
||||||
|
}
|
||||||
|
setup_config = []
|
||||||
|
service_data = {}
|
||||||
|
for test_id, test_data in test_config.items():
|
||||||
|
test_config_setup = copy.deepcopy(config)
|
||||||
|
test_config_setup.update(
|
||||||
|
{
|
||||||
|
topic: f"cmd/{test_id}",
|
||||||
|
"name": f"{test_id}",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if test_data["encoding"] is not None:
|
||||||
|
test_config_setup["encoding"] = test_data["encoding"]
|
||||||
|
if test_data["cmd_tpl"]:
|
||||||
|
test_config_setup[
|
||||||
|
template
|
||||||
|
] = f"{{{{ (('%.1f'|format({tpl_par}))[0] if is_number({tpl_par}) else {tpl_par}[0]) | ord | pack('b') }}}}"
|
||||||
|
setup_config.append(test_config_setup)
|
||||||
|
|
||||||
|
# setup service data
|
||||||
|
service_data[test_id] = {ATTR_ENTITY_ID: f"{domain}.{test_id}"}
|
||||||
|
if parameters:
|
||||||
|
service_data[test_id].update(parameters)
|
||||||
|
|
||||||
|
# setup test entities
|
||||||
|
assert await async_setup_component(
|
||||||
|
hass,
|
||||||
|
domain,
|
||||||
|
{domain: setup_config},
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
# 1) test with default encoding
|
||||||
|
await hass.services.async_call(
|
||||||
|
domain,
|
||||||
|
service,
|
||||||
|
service_data["test1"],
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
mqtt_mock.async_publish.assert_any_call("cmd/test1", str(payload), 0, False)
|
||||||
|
mqtt_mock.async_publish.reset_mock()
|
||||||
|
|
||||||
|
# 2) test with utf-16 encoding
|
||||||
|
await hass.services.async_call(
|
||||||
|
domain,
|
||||||
|
service,
|
||||||
|
service_data["test2"],
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
mqtt_mock.async_publish.assert_any_call(
|
||||||
|
"cmd/test2", str(payload).encode("utf-16"), 0, False
|
||||||
|
)
|
||||||
|
mqtt_mock.async_publish.reset_mock()
|
||||||
|
|
||||||
|
# 3) test with no encoding set should fail if payload is a string
|
||||||
|
await hass.services.async_call(
|
||||||
|
domain,
|
||||||
|
service,
|
||||||
|
service_data["test3"],
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
f"Can't pass-through payload for publishing {payload} on cmd/test3 with no encoding set, need 'bytes'"
|
||||||
|
in caplog.text
|
||||||
|
)
|
||||||
|
|
||||||
|
# 4) test with invalid encoding set should fail
|
||||||
|
await hass.services.async_call(
|
||||||
|
domain,
|
||||||
|
service,
|
||||||
|
service_data["test4"],
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
f"Can't encode payload for publishing {payload} on cmd/test4 with encoding invalid"
|
||||||
|
in caplog.text
|
||||||
|
)
|
||||||
|
|
||||||
|
# 5) test with command template and raw encoding if specified
|
||||||
|
if not template:
|
||||||
|
return
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
domain,
|
||||||
|
service,
|
||||||
|
service_data["test5"],
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
mqtt_mock.async_publish.assert_any_call(
|
||||||
|
"cmd/test5", tpl_output or str(payload)[0].encode("utf-8"), 0, False
|
||||||
|
)
|
||||||
|
mqtt_mock.async_publish.reset_mock()
|
||||||
|
|
|
@ -61,6 +61,7 @@ from .test_common import (
|
||||||
help_test_entity_device_info_with_identifier,
|
help_test_entity_device_info_with_identifier,
|
||||||
help_test_entity_id_update_discovery_update,
|
help_test_entity_id_update_discovery_update,
|
||||||
help_test_entity_id_update_subscriptions,
|
help_test_entity_id_update_subscriptions,
|
||||||
|
help_test_publishing_with_custom_encoding,
|
||||||
help_test_setting_attribute_via_mqtt_json_message,
|
help_test_setting_attribute_via_mqtt_json_message,
|
||||||
help_test_setting_attribute_with_template,
|
help_test_setting_attribute_with_template,
|
||||||
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
||||||
|
@ -3057,3 +3058,58 @@ async def test_tilt_status_template_without_tilt_status_topic_topic(
|
||||||
f"'{CONF_TILT_STATUS_TEMPLATE}' must be set together with '{CONF_TILT_STATUS_TOPIC}'."
|
f"'{CONF_TILT_STATUS_TEMPLATE}' must be set together with '{CONF_TILT_STATUS_TOPIC}'."
|
||||||
in caplog.text
|
in caplog.text
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"service,topic,parameters,payload,template",
|
||||||
|
[
|
||||||
|
(
|
||||||
|
SERVICE_OPEN_COVER,
|
||||||
|
"command_topic",
|
||||||
|
None,
|
||||||
|
"OPEN",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
SERVICE_SET_COVER_POSITION,
|
||||||
|
"set_position_topic",
|
||||||
|
{ATTR_POSITION: "50"},
|
||||||
|
50,
|
||||||
|
"set_position_template",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
SERVICE_SET_COVER_TILT_POSITION,
|
||||||
|
"tilt_command_topic",
|
||||||
|
{ATTR_TILT_POSITION: "45"},
|
||||||
|
45,
|
||||||
|
"tilt_command_template",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
):
|
||||||
|
"""Test publishing MQTT payload with different encoding."""
|
||||||
|
domain = cover.DOMAIN
|
||||||
|
config = DEFAULT_CONFIG[domain]
|
||||||
|
config["position_topic"] = "some-position-topic"
|
||||||
|
|
||||||
|
await help_test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
domain,
|
||||||
|
config,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
"""Test MQTT fans."""
|
"""Test MQTT fans."""
|
||||||
|
import copy
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -32,6 +33,7 @@ from .test_common import (
|
||||||
help_test_entity_device_info_with_identifier,
|
help_test_entity_device_info_with_identifier,
|
||||||
help_test_entity_id_update_discovery_update,
|
help_test_entity_id_update_discovery_update,
|
||||||
help_test_entity_id_update_subscriptions,
|
help_test_entity_id_update_subscriptions,
|
||||||
|
help_test_publishing_with_custom_encoding,
|
||||||
help_test_setting_attribute_via_mqtt_json_message,
|
help_test_setting_attribute_via_mqtt_json_message,
|
||||||
help_test_setting_attribute_with_template,
|
help_test_setting_attribute_with_template,
|
||||||
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
||||||
|
@ -1663,3 +1665,73 @@ async def test_entity_debug_info_message(hass, mqtt_mock):
|
||||||
await help_test_entity_debug_info_message(
|
await help_test_entity_debug_info_message(
|
||||||
hass, mqtt_mock, fan.DOMAIN, DEFAULT_CONFIG
|
hass, mqtt_mock, fan.DOMAIN, DEFAULT_CONFIG
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"service,topic,parameters,payload,template",
|
||||||
|
[
|
||||||
|
(
|
||||||
|
fan.SERVICE_TURN_ON,
|
||||||
|
"command_topic",
|
||||||
|
None,
|
||||||
|
"ON",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
fan.SERVICE_TURN_OFF,
|
||||||
|
"command_topic",
|
||||||
|
None,
|
||||||
|
"OFF",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
fan.SERVICE_SET_PRESET_MODE,
|
||||||
|
"preset_mode_command_topic",
|
||||||
|
{fan.ATTR_PRESET_MODE: "eco"},
|
||||||
|
"eco",
|
||||||
|
"preset_mode_command_template",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
fan.SERVICE_SET_PERCENTAGE,
|
||||||
|
"percentage_command_topic",
|
||||||
|
{fan.ATTR_PERCENTAGE: "45"},
|
||||||
|
45,
|
||||||
|
"percentage_command_template",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
fan.SERVICE_OSCILLATE,
|
||||||
|
"oscillation_command_topic",
|
||||||
|
{fan.ATTR_OSCILLATING: "on"},
|
||||||
|
"oscillate_on",
|
||||||
|
"oscillation_command_template",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
):
|
||||||
|
"""Test publishing MQTT payload with different encoding."""
|
||||||
|
domain = fan.DOMAIN
|
||||||
|
config = copy.deepcopy(DEFAULT_CONFIG[domain])
|
||||||
|
if topic == "preset_mode_command_topic":
|
||||||
|
config["preset_modes"] = ["auto", "eco"]
|
||||||
|
|
||||||
|
await help_test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
domain,
|
||||||
|
config,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
"""Test MQTT humidifiers."""
|
"""Test MQTT humidifiers."""
|
||||||
|
import copy
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -42,6 +43,7 @@ from .test_common import (
|
||||||
help_test_entity_device_info_with_identifier,
|
help_test_entity_device_info_with_identifier,
|
||||||
help_test_entity_id_update_discovery_update,
|
help_test_entity_id_update_discovery_update,
|
||||||
help_test_entity_id_update_subscriptions,
|
help_test_entity_id_update_subscriptions,
|
||||||
|
help_test_publishing_with_custom_encoding,
|
||||||
help_test_setting_attribute_via_mqtt_json_message,
|
help_test_setting_attribute_via_mqtt_json_message,
|
||||||
help_test_setting_attribute_with_template,
|
help_test_setting_attribute_with_template,
|
||||||
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
||||||
|
@ -1058,3 +1060,66 @@ async def test_entity_debug_info_message(hass, mqtt_mock):
|
||||||
await help_test_entity_debug_info_message(
|
await help_test_entity_debug_info_message(
|
||||||
hass, mqtt_mock, humidifier.DOMAIN, DEFAULT_CONFIG
|
hass, mqtt_mock, humidifier.DOMAIN, DEFAULT_CONFIG
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"service,topic,parameters,payload,template",
|
||||||
|
[
|
||||||
|
(
|
||||||
|
humidifier.SERVICE_TURN_ON,
|
||||||
|
"command_topic",
|
||||||
|
None,
|
||||||
|
"ON",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
humidifier.SERVICE_TURN_OFF,
|
||||||
|
"command_topic",
|
||||||
|
None,
|
||||||
|
"OFF",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
humidifier.SERVICE_SET_MODE,
|
||||||
|
"mode_command_topic",
|
||||||
|
{humidifier.ATTR_MODE: "eco"},
|
||||||
|
"eco",
|
||||||
|
"mode_command_template",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
humidifier.SERVICE_SET_HUMIDITY,
|
||||||
|
"target_humidity_command_topic",
|
||||||
|
{humidifier.ATTR_HUMIDITY: "45"},
|
||||||
|
45,
|
||||||
|
"target_humidity_command_template",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
):
|
||||||
|
"""Test publishing MQTT payload with different encoding."""
|
||||||
|
domain = humidifier.DOMAIN
|
||||||
|
config = copy.deepcopy(DEFAULT_CONFIG[domain])
|
||||||
|
if topic == "mode_command_topic":
|
||||||
|
config["modes"] = ["auto", "eco"]
|
||||||
|
|
||||||
|
await help_test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
domain,
|
||||||
|
config,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
)
|
||||||
|
|
|
@ -41,6 +41,7 @@ from .test_common import (
|
||||||
help_test_entity_device_info_with_identifier,
|
help_test_entity_device_info_with_identifier,
|
||||||
help_test_entity_id_update_discovery_update,
|
help_test_entity_id_update_discovery_update,
|
||||||
help_test_entity_id_update_subscriptions,
|
help_test_entity_id_update_subscriptions,
|
||||||
|
help_test_publishing_with_custom_encoding,
|
||||||
help_test_setting_attribute_via_mqtt_json_message,
|
help_test_setting_attribute_via_mqtt_json_message,
|
||||||
help_test_setting_attribute_with_template,
|
help_test_setting_attribute_with_template,
|
||||||
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
||||||
|
@ -746,3 +747,78 @@ async def test_entity_debug_info_message(hass, mqtt_mock):
|
||||||
await help_test_entity_debug_info_message(
|
await help_test_entity_debug_info_message(
|
||||||
hass, mqtt_mock, vacuum.DOMAIN, config, "test-topic"
|
hass, mqtt_mock, vacuum.DOMAIN, config, "test-topic"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"service,topic,parameters,payload,template",
|
||||||
|
[
|
||||||
|
(
|
||||||
|
vacuum.SERVICE_TURN_ON,
|
||||||
|
"command_topic",
|
||||||
|
None,
|
||||||
|
"turn_on",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
vacuum.SERVICE_CLEAN_SPOT,
|
||||||
|
"command_topic",
|
||||||
|
None,
|
||||||
|
"clean_spot",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
vacuum.SERVICE_SET_FAN_SPEED,
|
||||||
|
"set_fan_speed_topic",
|
||||||
|
{"fan_speed": "medium"},
|
||||||
|
"medium",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
vacuum.SERVICE_SEND_COMMAND,
|
||||||
|
"send_command_topic",
|
||||||
|
{"command": "custom command"},
|
||||||
|
"custom command",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
vacuum.SERVICE_TURN_OFF,
|
||||||
|
"command_topic",
|
||||||
|
None,
|
||||||
|
"turn_off",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
):
|
||||||
|
"""Test publishing MQTT payload with different encoding."""
|
||||||
|
domain = vacuum.DOMAIN
|
||||||
|
config = deepcopy(DEFAULT_CONFIG)
|
||||||
|
config["supported_features"] = [
|
||||||
|
"turn_on",
|
||||||
|
"turn_off",
|
||||||
|
"clean_spot",
|
||||||
|
"fan_speed",
|
||||||
|
"send_command",
|
||||||
|
]
|
||||||
|
|
||||||
|
await help_test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
domain,
|
||||||
|
config,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
)
|
||||||
|
|
|
@ -153,6 +153,7 @@ light:
|
||||||
payload_off: "off"
|
payload_off: "off"
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
import copy
|
||||||
from unittest.mock import call, patch
|
from unittest.mock import call, patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -189,6 +190,7 @@ from .test_common import (
|
||||||
help_test_entity_device_info_with_identifier,
|
help_test_entity_device_info_with_identifier,
|
||||||
help_test_entity_id_update_discovery_update,
|
help_test_entity_id_update_discovery_update,
|
||||||
help_test_entity_id_update_subscriptions,
|
help_test_entity_id_update_subscriptions,
|
||||||
|
help_test_publishing_with_custom_encoding,
|
||||||
help_test_setting_attribute_via_mqtt_json_message,
|
help_test_setting_attribute_via_mqtt_json_message,
|
||||||
help_test_setting_attribute_with_template,
|
help_test_setting_attribute_with_template,
|
||||||
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
||||||
|
@ -3407,3 +3409,125 @@ async def test_reloadable(hass, mqtt_mock):
|
||||||
|
|
||||||
assert hass.states.get("light.test") is None
|
assert hass.states.get("light.test") is None
|
||||||
assert hass.states.get("light.reload")
|
assert hass.states.get("light.reload")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"service,topic,parameters,payload,template,tpl_par,tpl_output",
|
||||||
|
[
|
||||||
|
(
|
||||||
|
light.SERVICE_TURN_ON,
|
||||||
|
"command_topic",
|
||||||
|
None,
|
||||||
|
"ON",
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
light.SERVICE_TURN_ON,
|
||||||
|
"white_command_topic",
|
||||||
|
{"white": "255"},
|
||||||
|
255,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
light.SERVICE_TURN_ON,
|
||||||
|
"brightness_command_topic",
|
||||||
|
{"color_temp": "200", "brightness": "50"},
|
||||||
|
50,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
light.SERVICE_TURN_ON,
|
||||||
|
"effect_command_topic",
|
||||||
|
{"rgb_color": [255, 128, 0], "effect": "color_loop"},
|
||||||
|
"color_loop",
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
light.SERVICE_TURN_ON,
|
||||||
|
"color_temp_command_topic",
|
||||||
|
{"color_temp": "200"},
|
||||||
|
200,
|
||||||
|
"color_temp_command_template",
|
||||||
|
"value",
|
||||||
|
b"2",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
light.SERVICE_TURN_ON,
|
||||||
|
"rgb_command_topic",
|
||||||
|
{"rgb_color": [255, 128, 0]},
|
||||||
|
"255,128,0",
|
||||||
|
"rgb_command_template",
|
||||||
|
"red",
|
||||||
|
b"2",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
light.SERVICE_TURN_ON,
|
||||||
|
"hs_command_topic",
|
||||||
|
{"rgb_color": [255, 128, 0]},
|
||||||
|
"30.118,100.0",
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
light.SERVICE_TURN_ON,
|
||||||
|
"xy_command_topic",
|
||||||
|
{"hs_color": [30.118, 100.0]},
|
||||||
|
"0.611,0.375",
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
light.SERVICE_TURN_OFF,
|
||||||
|
"command_topic",
|
||||||
|
None,
|
||||||
|
"OFF",
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
tpl_par,
|
||||||
|
tpl_output,
|
||||||
|
):
|
||||||
|
"""Test publishing MQTT payload with different encoding."""
|
||||||
|
domain = light.DOMAIN
|
||||||
|
config = copy.deepcopy(DEFAULT_CONFIG[domain])
|
||||||
|
if topic == "effect_command_topic":
|
||||||
|
config["effect_list"] = ["random", "color_loop"]
|
||||||
|
elif topic == "white_command_topic":
|
||||||
|
config["rgb_command_topic"] = "some-cmd-topic"
|
||||||
|
|
||||||
|
await help_test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
domain,
|
||||||
|
config,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
tpl_par=tpl_par,
|
||||||
|
tpl_output=tpl_output,
|
||||||
|
)
|
||||||
|
|
|
@ -87,6 +87,7 @@ light:
|
||||||
brightness: true
|
brightness: true
|
||||||
brightness_scale: 99
|
brightness_scale: 99
|
||||||
"""
|
"""
|
||||||
|
import copy
|
||||||
import json
|
import json
|
||||||
from unittest.mock import call, patch
|
from unittest.mock import call, patch
|
||||||
|
|
||||||
|
@ -122,6 +123,7 @@ from .test_common import (
|
||||||
help_test_entity_device_info_with_identifier,
|
help_test_entity_device_info_with_identifier,
|
||||||
help_test_entity_id_update_discovery_update,
|
help_test_entity_id_update_discovery_update,
|
||||||
help_test_entity_id_update_subscriptions,
|
help_test_entity_id_update_subscriptions,
|
||||||
|
help_test_publishing_with_custom_encoding,
|
||||||
help_test_setting_attribute_via_mqtt_json_message,
|
help_test_setting_attribute_via_mqtt_json_message,
|
||||||
help_test_setting_attribute_with_template,
|
help_test_setting_attribute_with_template,
|
||||||
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
||||||
|
@ -1902,3 +1904,62 @@ async def test_max_mireds(hass, mqtt_mock):
|
||||||
state = hass.states.get("light.test")
|
state = hass.states.get("light.test")
|
||||||
assert state.attributes.get("min_mireds") == 153
|
assert state.attributes.get("min_mireds") == 153
|
||||||
assert state.attributes.get("max_mireds") == 370
|
assert state.attributes.get("max_mireds") == 370
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"service,topic,parameters,payload,template,tpl_par,tpl_output",
|
||||||
|
[
|
||||||
|
(
|
||||||
|
light.SERVICE_TURN_ON,
|
||||||
|
"command_topic",
|
||||||
|
None,
|
||||||
|
'{"state": "ON"}',
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
light.SERVICE_TURN_OFF,
|
||||||
|
"command_topic",
|
||||||
|
None,
|
||||||
|
'{"state": "OFF"}',
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
tpl_par,
|
||||||
|
tpl_output,
|
||||||
|
):
|
||||||
|
"""Test publishing MQTT payload with different encoding."""
|
||||||
|
domain = light.DOMAIN
|
||||||
|
config = copy.deepcopy(DEFAULT_CONFIG[domain])
|
||||||
|
if topic == "effect_command_topic":
|
||||||
|
config["effect_list"] = ["random", "color_loop"]
|
||||||
|
elif topic == "white_command_topic":
|
||||||
|
config["rgb_command_topic"] = "some-cmd-topic"
|
||||||
|
|
||||||
|
await help_test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
domain,
|
||||||
|
config,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
tpl_par=tpl_par,
|
||||||
|
tpl_output=tpl_output,
|
||||||
|
)
|
||||||
|
|
|
@ -26,6 +26,7 @@ If your light doesn't support white value feature, omit `white_value_template`.
|
||||||
|
|
||||||
If your light doesn't support RGB feature, omit `(red|green|blue)_template`.
|
If your light doesn't support RGB feature, omit `(red|green|blue)_template`.
|
||||||
"""
|
"""
|
||||||
|
import copy
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -60,6 +61,7 @@ from .test_common import (
|
||||||
help_test_entity_device_info_with_identifier,
|
help_test_entity_device_info_with_identifier,
|
||||||
help_test_entity_id_update_discovery_update,
|
help_test_entity_id_update_discovery_update,
|
||||||
help_test_entity_id_update_subscriptions,
|
help_test_entity_id_update_subscriptions,
|
||||||
|
help_test_publishing_with_custom_encoding,
|
||||||
help_test_setting_attribute_via_mqtt_json_message,
|
help_test_setting_attribute_via_mqtt_json_message,
|
||||||
help_test_setting_attribute_with_template,
|
help_test_setting_attribute_with_template,
|
||||||
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
||||||
|
@ -1085,3 +1087,62 @@ async def test_max_mireds(hass, mqtt_mock):
|
||||||
state = hass.states.get("light.test")
|
state = hass.states.get("light.test")
|
||||||
assert state.attributes.get("min_mireds") == 153
|
assert state.attributes.get("min_mireds") == 153
|
||||||
assert state.attributes.get("max_mireds") == 370
|
assert state.attributes.get("max_mireds") == 370
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"service,topic,parameters,payload,template,tpl_par,tpl_output",
|
||||||
|
[
|
||||||
|
(
|
||||||
|
light.SERVICE_TURN_ON,
|
||||||
|
"command_topic",
|
||||||
|
None,
|
||||||
|
"on,",
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
light.SERVICE_TURN_OFF,
|
||||||
|
"command_topic",
|
||||||
|
None,
|
||||||
|
"off,",
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
tpl_par,
|
||||||
|
tpl_output,
|
||||||
|
):
|
||||||
|
"""Test publishing MQTT payload with different encoding."""
|
||||||
|
domain = light.DOMAIN
|
||||||
|
config = copy.deepcopy(DEFAULT_CONFIG[domain])
|
||||||
|
if topic == "effect_command_topic":
|
||||||
|
config["effect_list"] = ["random", "color_loop"]
|
||||||
|
elif topic == "white_command_topic":
|
||||||
|
config["rgb_command_topic"] = "some-cmd-topic"
|
||||||
|
|
||||||
|
await help_test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
domain,
|
||||||
|
config,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
tpl_par=tpl_par,
|
||||||
|
tpl_output=tpl_output,
|
||||||
|
)
|
||||||
|
|
|
@ -37,6 +37,7 @@ from .test_common import (
|
||||||
help_test_entity_device_info_with_identifier,
|
help_test_entity_device_info_with_identifier,
|
||||||
help_test_entity_id_update_discovery_update,
|
help_test_entity_id_update_discovery_update,
|
||||||
help_test_entity_id_update_subscriptions,
|
help_test_entity_id_update_subscriptions,
|
||||||
|
help_test_publishing_with_custom_encoding,
|
||||||
help_test_setting_attribute_via_mqtt_json_message,
|
help_test_setting_attribute_via_mqtt_json_message,
|
||||||
help_test_setting_attribute_with_template,
|
help_test_setting_attribute_with_template,
|
||||||
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
||||||
|
@ -589,3 +590,43 @@ async def test_entity_debug_info_message(hass, mqtt_mock):
|
||||||
await help_test_entity_debug_info_message(
|
await help_test_entity_debug_info_message(
|
||||||
hass, mqtt_mock, LOCK_DOMAIN, DEFAULT_CONFIG
|
hass, mqtt_mock, LOCK_DOMAIN, DEFAULT_CONFIG
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"service,topic,parameters,payload,template",
|
||||||
|
[
|
||||||
|
(
|
||||||
|
SERVICE_LOCK,
|
||||||
|
"command_topic",
|
||||||
|
None,
|
||||||
|
"LOCK",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
):
|
||||||
|
"""Test publishing MQTT payload with different encoding."""
|
||||||
|
domain = LOCK_DOMAIN
|
||||||
|
config = DEFAULT_CONFIG[domain]
|
||||||
|
|
||||||
|
await help_test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
domain,
|
||||||
|
config,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
)
|
||||||
|
|
|
@ -43,6 +43,7 @@ from .test_common import (
|
||||||
help_test_entity_device_info_with_identifier,
|
help_test_entity_device_info_with_identifier,
|
||||||
help_test_entity_id_update_discovery_update,
|
help_test_entity_id_update_discovery_update,
|
||||||
help_test_entity_id_update_subscriptions,
|
help_test_entity_id_update_subscriptions,
|
||||||
|
help_test_publishing_with_custom_encoding,
|
||||||
help_test_setting_attribute_via_mqtt_json_message,
|
help_test_setting_attribute_via_mqtt_json_message,
|
||||||
help_test_setting_attribute_with_template,
|
help_test_setting_attribute_with_template,
|
||||||
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
||||||
|
@ -640,3 +641,43 @@ async def test_mqtt_payload_out_of_range_error(hass, caplog, mqtt_mock):
|
||||||
assert (
|
assert (
|
||||||
"Invalid value for number.test_number: 115.5 (range 5.0 - 110.0)" in caplog.text
|
"Invalid value for number.test_number: 115.5 (range 5.0 - 110.0)" in caplog.text
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"service,topic,parameters,payload,template",
|
||||||
|
[
|
||||||
|
(
|
||||||
|
SERVICE_SET_VALUE,
|
||||||
|
"command_topic",
|
||||||
|
{ATTR_VALUE: "45"},
|
||||||
|
45,
|
||||||
|
"command_template",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
):
|
||||||
|
"""Test publishing MQTT payload with different encoding."""
|
||||||
|
domain = NUMBER_DOMAIN
|
||||||
|
config = DEFAULT_CONFIG[domain]
|
||||||
|
|
||||||
|
await help_test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
domain,
|
||||||
|
config,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
)
|
||||||
|
|
|
@ -33,6 +33,7 @@ from .test_common import (
|
||||||
help_test_entity_device_info_with_identifier,
|
help_test_entity_device_info_with_identifier,
|
||||||
help_test_entity_id_update_discovery_update,
|
help_test_entity_id_update_discovery_update,
|
||||||
help_test_entity_id_update_subscriptions,
|
help_test_entity_id_update_subscriptions,
|
||||||
|
help_test_publishing_with_custom_encoding,
|
||||||
help_test_setting_attribute_via_mqtt_json_message,
|
help_test_setting_attribute_via_mqtt_json_message,
|
||||||
help_test_setting_attribute_with_template,
|
help_test_setting_attribute_with_template,
|
||||||
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
||||||
|
@ -524,3 +525,37 @@ async def test_mqtt_payload_not_an_option_warning(hass, caplog, mqtt_mock):
|
||||||
"Invalid option for select.test_select: 'öl' (valid options: ['milk', 'beer'])"
|
"Invalid option for select.test_select: 'öl' (valid options: ['milk', 'beer'])"
|
||||||
in caplog.text
|
in caplog.text
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"service,topic,parameters,payload,template",
|
||||||
|
[
|
||||||
|
(
|
||||||
|
select.SERVICE_SELECT_OPTION,
|
||||||
|
"command_topic",
|
||||||
|
{"option": "beer"},
|
||||||
|
"beer",
|
||||||
|
"command_template",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_publishing_with_custom_encoding(
|
||||||
|
hass, mqtt_mock, caplog, service, topic, parameters, payload, template
|
||||||
|
):
|
||||||
|
"""Test publishing MQTT payload with different encoding."""
|
||||||
|
domain = select.DOMAIN
|
||||||
|
config = DEFAULT_CONFIG[domain]
|
||||||
|
config["options"] = ["milk", "beer"]
|
||||||
|
|
||||||
|
await help_test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
domain,
|
||||||
|
config,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
)
|
||||||
|
|
|
@ -51,6 +51,7 @@ from .test_common import (
|
||||||
help_test_entity_device_info_with_identifier,
|
help_test_entity_device_info_with_identifier,
|
||||||
help_test_entity_id_update_discovery_update,
|
help_test_entity_id_update_discovery_update,
|
||||||
help_test_entity_id_update_subscriptions,
|
help_test_entity_id_update_subscriptions,
|
||||||
|
help_test_publishing_with_custom_encoding,
|
||||||
help_test_setting_attribute_via_mqtt_json_message,
|
help_test_setting_attribute_via_mqtt_json_message,
|
||||||
help_test_setting_attribute_with_template,
|
help_test_setting_attribute_with_template,
|
||||||
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
||||||
|
@ -502,3 +503,83 @@ async def test_entity_debug_info_message(hass, mqtt_mock):
|
||||||
await help_test_entity_debug_info_message(
|
await help_test_entity_debug_info_message(
|
||||||
hass, mqtt_mock, vacuum.DOMAIN, DEFAULT_CONFIG_2, payload="{}"
|
hass, mqtt_mock, vacuum.DOMAIN, DEFAULT_CONFIG_2, payload="{}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"service,topic,parameters,payload,template",
|
||||||
|
[
|
||||||
|
(
|
||||||
|
vacuum.SERVICE_START,
|
||||||
|
"command_topic",
|
||||||
|
None,
|
||||||
|
"start",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
vacuum.SERVICE_CLEAN_SPOT,
|
||||||
|
"command_topic",
|
||||||
|
None,
|
||||||
|
"clean_spot",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
vacuum.SERVICE_SET_FAN_SPEED,
|
||||||
|
"set_fan_speed_topic",
|
||||||
|
{"fan_speed": "medium"},
|
||||||
|
"medium",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
vacuum.SERVICE_SEND_COMMAND,
|
||||||
|
"send_command_topic",
|
||||||
|
{"command": "custom command"},
|
||||||
|
"custom command",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
vacuum.SERVICE_STOP,
|
||||||
|
"command_topic",
|
||||||
|
None,
|
||||||
|
"stop",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
):
|
||||||
|
"""Test publishing MQTT payload with different encoding."""
|
||||||
|
domain = vacuum.DOMAIN
|
||||||
|
config = deepcopy(DEFAULT_CONFIG)
|
||||||
|
config["supported_features"] = [
|
||||||
|
"battery",
|
||||||
|
"clean_spot",
|
||||||
|
"fan_speed",
|
||||||
|
"locate",
|
||||||
|
"pause",
|
||||||
|
"return_home",
|
||||||
|
"send_command",
|
||||||
|
"start",
|
||||||
|
"status",
|
||||||
|
"stop",
|
||||||
|
]
|
||||||
|
|
||||||
|
await help_test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
domain,
|
||||||
|
config,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
)
|
||||||
|
|
|
@ -32,6 +32,7 @@ from .test_common import (
|
||||||
help_test_entity_device_info_with_identifier,
|
help_test_entity_device_info_with_identifier,
|
||||||
help_test_entity_id_update_discovery_update,
|
help_test_entity_id_update_discovery_update,
|
||||||
help_test_entity_id_update_subscriptions,
|
help_test_entity_id_update_subscriptions,
|
||||||
|
help_test_publishing_with_custom_encoding,
|
||||||
help_test_setting_attribute_via_mqtt_json_message,
|
help_test_setting_attribute_via_mqtt_json_message,
|
||||||
help_test_setting_attribute_with_template,
|
help_test_setting_attribute_with_template,
|
||||||
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
help_test_setting_blocked_attribute_via_mqtt_json_message,
|
||||||
|
@ -467,3 +468,50 @@ async def test_entity_debug_info_message(hass, mqtt_mock):
|
||||||
await help_test_entity_debug_info_message(
|
await help_test_entity_debug_info_message(
|
||||||
hass, mqtt_mock, switch.DOMAIN, DEFAULT_CONFIG
|
hass, mqtt_mock, switch.DOMAIN, DEFAULT_CONFIG
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"service,topic,parameters,payload,template",
|
||||||
|
[
|
||||||
|
(
|
||||||
|
switch.SERVICE_TURN_ON,
|
||||||
|
"command_topic",
|
||||||
|
None,
|
||||||
|
"ON",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
switch.SERVICE_TURN_OFF,
|
||||||
|
"command_topic",
|
||||||
|
None,
|
||||||
|
"OFF",
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
):
|
||||||
|
"""Test publishing MQTT payload with different encoding."""
|
||||||
|
domain = switch.DOMAIN
|
||||||
|
config = DEFAULT_CONFIG[domain]
|
||||||
|
|
||||||
|
await help_test_publishing_with_custom_encoding(
|
||||||
|
hass,
|
||||||
|
mqtt_mock,
|
||||||
|
caplog,
|
||||||
|
domain,
|
||||||
|
config,
|
||||||
|
service,
|
||||||
|
topic,
|
||||||
|
parameters,
|
||||||
|
payload,
|
||||||
|
template,
|
||||||
|
)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue