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
|
||||
|
||||
|
||||
def publish(hass: HomeAssistant, topic, payload, qos=0, retain=False) -> None:
|
||||
"""Publish message to an MQTT topic."""
|
||||
hass.add_job(async_publish, hass, topic, payload, qos, retain)
|
||||
def publish(
|
||||
hass: HomeAssistant,
|
||||
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(
|
||||
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:
|
||||
"""Publish message to an MQTT topic."""
|
||||
await hass.data[DATA_MQTT].async_publish(
|
||||
topic, str(payload) if not isinstance(payload, bytes) else payload, qos, retain
|
||||
"""Publish message to a MQTT topic."""
|
||||
|
||||
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[
|
||||
|
|
|
@ -40,7 +40,14 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
|||
|
||||
from . import PLATFORMS, MqttCommandTemplate, subscription
|
||||
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 .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
||||
|
||||
|
@ -326,6 +333,7 @@ class MqttAlarm(MqttEntity, alarm.AlarmControlPanelEntity):
|
|||
payload,
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
|
||||
def _validate_code(self, code, state):
|
||||
|
|
|
@ -17,7 +17,7 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
|||
|
||||
from . import PLATFORMS
|
||||
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
|
||||
|
||||
CONF_PAYLOAD_PRESS = "payload_press"
|
||||
|
@ -100,4 +100,5 @@ class MqttButton(MqttEntity, ButtonEntity):
|
|||
self._config[CONF_PAYLOAD_PRESS],
|
||||
self._config[CONF_QOS],
|
||||
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
|
||||
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 .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
||||
|
||||
|
@ -685,6 +685,7 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
|||
payload,
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
|
||||
async def _set_temperature(
|
||||
|
|
|
@ -42,7 +42,14 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
|||
|
||||
from . import PLATFORMS, MqttCommandTemplate, subscription
|
||||
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 .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_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
if self._optimistic:
|
||||
# Optimistically assume that cover has changed state.
|
||||
|
@ -568,6 +576,7 @@ class MqttCover(MqttEntity, CoverEntity):
|
|||
self._config[CONF_PAYLOAD_CLOSE],
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
if self._optimistic:
|
||||
# Optimistically assume that cover has changed state.
|
||||
|
@ -589,6 +598,7 @@ class MqttCover(MqttEntity, CoverEntity):
|
|||
self._config[CONF_PAYLOAD_STOP],
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
|
||||
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_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
if self._tilt_optimistic:
|
||||
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_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
if self._tilt_optimistic:
|
||||
self._tilt_value = self.find_percentage_in_range(
|
||||
|
@ -643,6 +655,7 @@ class MqttCover(MqttEntity, CoverEntity):
|
|||
tilt,
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
if self._tilt_optimistic:
|
||||
_LOGGER.debug("Set tilt value optimistic")
|
||||
|
@ -670,6 +683,7 @@ class MqttCover(MqttEntity, CoverEntity):
|
|||
position,
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
if self._optimistic:
|
||||
self._state = (
|
||||
|
|
|
@ -42,7 +42,14 @@ from homeassistant.util.percentage import (
|
|||
|
||||
from . import PLATFORMS, MqttCommandTemplate, subscription
|
||||
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 .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
||||
|
||||
|
@ -542,6 +549,7 @@ class MqttFan(MqttEntity, FanEntity):
|
|||
mqtt_payload,
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
if percentage:
|
||||
await self.async_set_percentage(percentage)
|
||||
|
@ -563,6 +571,7 @@ class MqttFan(MqttEntity, FanEntity):
|
|||
mqtt_payload,
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
if self._optimistic:
|
||||
self._state = False
|
||||
|
@ -583,6 +592,7 @@ class MqttFan(MqttEntity, FanEntity):
|
|||
mqtt_payload,
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
|
||||
if self._optimistic_percentage:
|
||||
|
@ -606,6 +616,7 @@ class MqttFan(MqttEntity, FanEntity):
|
|||
mqtt_payload,
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
|
||||
if self._optimistic_preset_mode:
|
||||
|
@ -632,6 +643,7 @@ class MqttFan(MqttEntity, FanEntity):
|
|||
mqtt_payload,
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
|
||||
if self._optimistic_oscillation:
|
||||
|
|
|
@ -32,7 +32,14 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
|||
|
||||
from . import PLATFORMS, MqttCommandTemplate, subscription
|
||||
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 .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
||||
|
||||
|
@ -408,6 +415,7 @@ class MqttHumidifier(MqttEntity, HumidifierEntity):
|
|||
mqtt_payload,
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
if self._optimistic:
|
||||
self._state = True
|
||||
|
@ -425,6 +433,7 @@ class MqttHumidifier(MqttEntity, HumidifierEntity):
|
|||
mqtt_payload,
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
if self._optimistic:
|
||||
self._state = False
|
||||
|
@ -442,6 +451,7 @@ class MqttHumidifier(MqttEntity, HumidifierEntity):
|
|||
mqtt_payload,
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
|
||||
if self._optimistic_target_humidity:
|
||||
|
@ -465,6 +475,7 @@ class MqttHumidifier(MqttEntity, HumidifierEntity):
|
|||
mqtt_payload,
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
|
||||
if self._optimistic_mode:
|
||||
|
|
|
@ -53,7 +53,13 @@ import homeassistant.util.color as color_util
|
|||
|
||||
from .. import subscription
|
||||
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 ..mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity
|
||||
from .schema import MQTT_LIGHT_SCHEMA_SCHEMA
|
||||
|
@ -821,6 +827,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
|||
payload,
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
|
||||
def scale_rgbx(color, brightness=None):
|
||||
|
@ -1069,6 +1076,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
|||
self._payload["off"],
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
|
||||
if self._optimistic:
|
||||
|
|
|
@ -59,7 +59,13 @@ import homeassistant.util.color as color_util
|
|||
|
||||
from .. import subscription
|
||||
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 ..mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity
|
||||
from .schema import MQTT_LIGHT_SCHEMA_SCHEMA
|
||||
|
@ -629,6 +635,7 @@ class MqttLightJson(MqttEntity, LightEntity, RestoreEntity):
|
|||
json.dumps(message),
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
|
||||
if self._optimistic:
|
||||
|
@ -654,6 +661,7 @@ class MqttLightJson(MqttEntity, LightEntity, RestoreEntity):
|
|||
json.dumps(message),
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
|
||||
if self._optimistic:
|
||||
|
|
|
@ -35,7 +35,13 @@ import homeassistant.util.color as color_util
|
|||
|
||||
from .. import subscription
|
||||
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 ..mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity
|
||||
from .schema import MQTT_LIGHT_SCHEMA_SCHEMA
|
||||
|
@ -384,6 +390,7 @@ class MqttLightTemplate(MqttEntity, LightEntity, RestoreEntity):
|
|||
),
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
|
||||
if self._optimistic:
|
||||
|
@ -409,6 +416,7 @@ class MqttLightTemplate(MqttEntity, LightEntity, RestoreEntity):
|
|||
),
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
|
||||
if self._optimistic:
|
||||
|
|
|
@ -17,7 +17,14 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
|||
|
||||
from . import PLATFORMS, subscription
|
||||
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 .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_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
if self._optimistic:
|
||||
# Optimistically assume that the lock has changed state.
|
||||
|
@ -192,6 +200,7 @@ class MqttLock(MqttEntity, LockEntity):
|
|||
self._config[CONF_PAYLOAD_UNLOCK],
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
if self._optimistic:
|
||||
# Optimistically assume that the lock has changed state.
|
||||
|
@ -209,6 +218,7 @@ class MqttLock(MqttEntity, LockEntity):
|
|||
self._config[CONF_PAYLOAD_OPEN],
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
if self._optimistic:
|
||||
# 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 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 .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
||||
|
||||
|
@ -258,6 +265,7 @@ class MqttNumber(MqttEntity, NumberEntity, RestoreEntity):
|
|||
payload,
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
|
||||
@property
|
||||
|
|
|
@ -17,7 +17,7 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
|||
|
||||
from . import PLATFORMS
|
||||
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 (
|
||||
CONF_OBJECT_ID,
|
||||
MQTT_AVAILABILITY_SCHEMA,
|
||||
|
@ -153,4 +153,5 @@ class MqttScene(
|
|||
self._config[CONF_PAYLOAD_ON],
|
||||
self._config[CONF_QOS],
|
||||
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 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 .mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper
|
||||
|
||||
|
@ -184,6 +191,7 @@ class MqttSelect(MqttEntity, SelectEntity, RestoreEntity):
|
|||
payload,
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
|
||||
@property
|
||||
|
|
|
@ -26,7 +26,14 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
|||
|
||||
from . import PLATFORMS, subscription
|
||||
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 .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_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
if self._optimistic:
|
||||
# Optimistically assume that switch has changed state.
|
||||
|
@ -205,6 +213,7 @@ class MqttSwitch(MqttEntity, SwitchEntity, RestoreEntity):
|
|||
self._config[CONF_PAYLOAD_OFF],
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
if self._optimistic:
|
||||
# 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 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 ..mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity
|
||||
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._qos = config[CONF_QOS]
|
||||
self._retain = config[CONF_RETAIN]
|
||||
self._encoding = config[CONF_ENCODING]
|
||||
|
||||
self._command_topic = config.get(CONF_COMMAND_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._qos,
|
||||
self._retain,
|
||||
self._encoding,
|
||||
)
|
||||
self._status = "Cleaning"
|
||||
self.async_write_ha_state()
|
||||
|
@ -403,6 +405,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
|||
self._payloads[CONF_PAYLOAD_TURN_OFF],
|
||||
self._qos,
|
||||
self._retain,
|
||||
self._encoding,
|
||||
)
|
||||
self._status = "Turning Off"
|
||||
self.async_write_ha_state()
|
||||
|
@ -418,6 +421,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
|||
self._payloads[CONF_PAYLOAD_STOP],
|
||||
self._qos,
|
||||
self._retain,
|
||||
self._encoding,
|
||||
)
|
||||
self._status = "Stopping the current task"
|
||||
self.async_write_ha_state()
|
||||
|
@ -433,6 +437,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
|||
self._payloads[CONF_PAYLOAD_CLEAN_SPOT],
|
||||
self._qos,
|
||||
self._retain,
|
||||
self._encoding,
|
||||
)
|
||||
self._status = "Cleaning spot"
|
||||
self.async_write_ha_state()
|
||||
|
@ -448,6 +453,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
|||
self._payloads[CONF_PAYLOAD_LOCATE],
|
||||
self._qos,
|
||||
self._retain,
|
||||
self._encoding,
|
||||
)
|
||||
self._status = "Hi, I'm over here!"
|
||||
self.async_write_ha_state()
|
||||
|
@ -463,6 +469,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
|||
self._payloads[CONF_PAYLOAD_START_PAUSE],
|
||||
self._qos,
|
||||
self._retain,
|
||||
self._encoding,
|
||||
)
|
||||
self._status = "Pausing/Resuming cleaning..."
|
||||
self.async_write_ha_state()
|
||||
|
@ -478,6 +485,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
|||
self._payloads[CONF_PAYLOAD_RETURN_TO_BASE],
|
||||
self._qos,
|
||||
self._retain,
|
||||
self._encoding,
|
||||
)
|
||||
self._status = "Returning home..."
|
||||
self.async_write_ha_state()
|
||||
|
@ -490,7 +498,12 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
|||
return None
|
||||
|
||||
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.async_write_ha_state()
|
||||
|
@ -506,7 +519,12 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
|||
else:
|
||||
message = command
|
||||
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.async_write_ha_state()
|
||||
|
|
|
@ -29,7 +29,13 @@ import homeassistant.helpers.config_validation as cv
|
|||
|
||||
from .. import subscription
|
||||
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 ..mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity
|
||||
from .const import MQTT_VACUUM_ATTRIBUTES_BLOCKED
|
||||
|
@ -248,6 +254,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
|
|||
self._config[CONF_PAYLOAD_START],
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
|
||||
async def async_pause(self):
|
||||
|
@ -260,6 +267,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
|
|||
self._config[CONF_PAYLOAD_PAUSE],
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
|
||||
async def async_stop(self, **kwargs):
|
||||
|
@ -272,6 +280,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
|
|||
self._config[CONF_PAYLOAD_STOP],
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
|
||||
async def async_set_fan_speed(self, fan_speed, **kwargs):
|
||||
|
@ -286,6 +295,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
|
|||
fan_speed,
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
|
||||
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_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
|
||||
async def async_clean_spot(self, **kwargs):
|
||||
|
@ -310,6 +321,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
|
|||
self._config[CONF_PAYLOAD_CLEAN_SPOT],
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
|
||||
async def async_locate(self, **kwargs):
|
||||
|
@ -322,6 +334,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
|
|||
self._config[CONF_PAYLOAD_LOCATE],
|
||||
self._config[CONF_QOS],
|
||||
self._config[CONF_RETAIN],
|
||||
self._config[CONF_ENCODING],
|
||||
)
|
||||
|
||||
async def async_send_command(self, command, params=None, **kwargs):
|
||||
|
@ -340,4 +353,5 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
|
|||
message,
|
||||
self._config[CONF_QOS],
|
||||
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_id_update_discovery_update,
|
||||
help_test_entity_id_update_subscriptions,
|
||||
help_test_publishing_with_custom_encoding,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_setting_attribute_with_template,
|
||||
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(
|
||||
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_identifier,
|
||||
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_with_template,
|
||||
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
|
||||
state = hass.states.get("button.test_3")
|
||||
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 voluptuous as vol
|
||||
|
||||
from homeassistant.components import climate
|
||||
from homeassistant.components.climate import DEFAULT_MAX_TEMP, DEFAULT_MIN_TEMP
|
||||
from homeassistant.components.climate.const import (
|
||||
ATTR_HVAC_ACTION,
|
||||
|
@ -46,6 +47,7 @@ from .test_common import (
|
|||
help_test_entity_device_info_with_identifier,
|
||||
help_test_entity_id_update_discovery_update,
|
||||
help_test_entity_id_update_subscriptions,
|
||||
help_test_publishing_with_custom_encoding,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_setting_attribute_with_template,
|
||||
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)
|
||||
assert state.attributes.get("temperature") == 24.0
|
||||
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.const import MQTT_DISCONNECTED
|
||||
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.dispatcher import async_dispatcher_send
|
||||
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)
|
||||
await hass.async_block_till_done()
|
||||
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_id_update_discovery_update,
|
||||
help_test_entity_id_update_subscriptions,
|
||||
help_test_publishing_with_custom_encoding,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_setting_attribute_with_template,
|
||||
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}'."
|
||||
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."""
|
||||
import copy
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
@ -32,6 +33,7 @@ from .test_common import (
|
|||
help_test_entity_device_info_with_identifier,
|
||||
help_test_entity_id_update_discovery_update,
|
||||
help_test_entity_id_update_subscriptions,
|
||||
help_test_publishing_with_custom_encoding,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_setting_attribute_with_template,
|
||||
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(
|
||||
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."""
|
||||
import copy
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
@ -42,6 +43,7 @@ from .test_common import (
|
|||
help_test_entity_device_info_with_identifier,
|
||||
help_test_entity_id_update_discovery_update,
|
||||
help_test_entity_id_update_subscriptions,
|
||||
help_test_publishing_with_custom_encoding,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_setting_attribute_with_template,
|
||||
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(
|
||||
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_id_update_discovery_update,
|
||||
help_test_entity_id_update_subscriptions,
|
||||
help_test_publishing_with_custom_encoding,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_setting_attribute_with_template,
|
||||
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(
|
||||
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"
|
||||
|
||||
"""
|
||||
import copy
|
||||
from unittest.mock import call, patch
|
||||
|
||||
import pytest
|
||||
|
@ -189,6 +190,7 @@ from .test_common import (
|
|||
help_test_entity_device_info_with_identifier,
|
||||
help_test_entity_id_update_discovery_update,
|
||||
help_test_entity_id_update_subscriptions,
|
||||
help_test_publishing_with_custom_encoding,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_setting_attribute_with_template,
|
||||
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.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_scale: 99
|
||||
"""
|
||||
import copy
|
||||
import json
|
||||
from unittest.mock import call, patch
|
||||
|
||||
|
@ -122,6 +123,7 @@ from .test_common import (
|
|||
help_test_entity_device_info_with_identifier,
|
||||
help_test_entity_id_update_discovery_update,
|
||||
help_test_entity_id_update_subscriptions,
|
||||
help_test_publishing_with_custom_encoding,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_setting_attribute_with_template,
|
||||
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")
|
||||
assert state.attributes.get("min_mireds") == 153
|
||||
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`.
|
||||
"""
|
||||
import copy
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
@ -60,6 +61,7 @@ from .test_common import (
|
|||
help_test_entity_device_info_with_identifier,
|
||||
help_test_entity_id_update_discovery_update,
|
||||
help_test_entity_id_update_subscriptions,
|
||||
help_test_publishing_with_custom_encoding,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_setting_attribute_with_template,
|
||||
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")
|
||||
assert state.attributes.get("min_mireds") == 153
|
||||
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_id_update_discovery_update,
|
||||
help_test_entity_id_update_subscriptions,
|
||||
help_test_publishing_with_custom_encoding,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_setting_attribute_with_template,
|
||||
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(
|
||||
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_id_update_discovery_update,
|
||||
help_test_entity_id_update_subscriptions,
|
||||
help_test_publishing_with_custom_encoding,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_setting_attribute_with_template,
|
||||
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 (
|
||||
"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_id_update_discovery_update,
|
||||
help_test_entity_id_update_subscriptions,
|
||||
help_test_publishing_with_custom_encoding,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_setting_attribute_with_template,
|
||||
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'])"
|
||||
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_id_update_discovery_update,
|
||||
help_test_entity_id_update_subscriptions,
|
||||
help_test_publishing_with_custom_encoding,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_setting_attribute_with_template,
|
||||
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(
|
||||
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_id_update_discovery_update,
|
||||
help_test_entity_id_update_subscriptions,
|
||||
help_test_publishing_with_custom_encoding,
|
||||
help_test_setting_attribute_via_mqtt_json_message,
|
||||
help_test_setting_attribute_with_template,
|
||||
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(
|
||||
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