Avoid service call in MQTT async_publish function (#58441)
* Avoid service call in MQTT async_publish function * Tweak * Fix integrations + tests
This commit is contained in:
parent
11cb04822e
commit
0456a896e3
26 changed files with 207 additions and 211 deletions
|
@ -452,6 +452,6 @@ class ManualMQTTAlarm(alarm.AlarmControlPanelEntity):
|
||||||
"""Publish state change to MQTT."""
|
"""Publish state change to MQTT."""
|
||||||
if (new_state := event.data.get("new_state")) is None:
|
if (new_state := event.data.get("new_state")) is None:
|
||||||
return
|
return
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass, self._state_topic, new_state.state, self._qos, True
|
self.hass, self._state_topic, new_state.state, self._qos, True
|
||||||
)
|
)
|
||||||
|
|
|
@ -245,39 +245,16 @@ def _build_publish_data(topic: Any, qos: int, retain: bool) -> ServiceDataType:
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
@bind_hass
|
def publish(hass: HomeAssistant, topic, payload, qos=0, retain=False) -> None:
|
||||||
def publish(hass: HomeAssistant, topic, payload, qos=None, retain=None) -> None:
|
|
||||||
"""Publish message to an MQTT topic."""
|
"""Publish message to an MQTT topic."""
|
||||||
hass.add_job(async_publish, hass, topic, payload, qos, retain)
|
hass.add_job(async_publish, hass, topic, payload, qos, retain)
|
||||||
|
|
||||||
|
|
||||||
@callback
|
async def async_publish(
|
||||||
@bind_hass
|
hass: HomeAssistant, topic: Any, payload, qos=0, retain=False
|
||||||
def async_publish(
|
|
||||||
hass: HomeAssistant, topic: Any, payload, qos=None, retain=None
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Publish message to an MQTT topic."""
|
"""Publish message to an MQTT topic."""
|
||||||
data = _build_publish_data(topic, qos, retain)
|
await hass.data[DATA_MQTT].async_publish(topic, str(payload), qos, retain)
|
||||||
data[ATTR_PAYLOAD] = payload
|
|
||||||
hass.async_create_task(hass.services.async_call(DOMAIN, SERVICE_PUBLISH, data))
|
|
||||||
|
|
||||||
|
|
||||||
@bind_hass
|
|
||||||
def publish_template(
|
|
||||||
hass: HomeAssistant, topic, payload_template, qos=None, retain=None
|
|
||||||
) -> None:
|
|
||||||
"""Publish message to an MQTT topic."""
|
|
||||||
hass.add_job(async_publish_template, hass, topic, payload_template, qos, retain)
|
|
||||||
|
|
||||||
|
|
||||||
@bind_hass
|
|
||||||
def async_publish_template(
|
|
||||||
hass: HomeAssistant, topic, payload_template, qos=None, retain=None
|
|
||||||
) -> None:
|
|
||||||
"""Publish message to an MQTT topic using a template payload."""
|
|
||||||
data = _build_publish_data(topic, qos, retain)
|
|
||||||
data[ATTR_PAYLOAD_TEMPLATE] = payload_template
|
|
||||||
hass.async_create_task(hass.services.async_call(DOMAIN, SERVICE_PUBLISH, data))
|
|
||||||
|
|
||||||
|
|
||||||
AsyncDeprecatedMessageCallbackType = Callable[
|
AsyncDeprecatedMessageCallbackType = Callable[
|
||||||
|
|
|
@ -228,7 +228,7 @@ class MqttAlarm(MqttEntity, alarm.AlarmControlPanelEntity):
|
||||||
if code_required and not self._validate_code(code, "disarming"):
|
if code_required and not self._validate_code(code, "disarming"):
|
||||||
return
|
return
|
||||||
payload = self._config[CONF_PAYLOAD_DISARM]
|
payload = self._config[CONF_PAYLOAD_DISARM]
|
||||||
self._publish(code, payload)
|
await self._publish(code, payload)
|
||||||
|
|
||||||
async def async_alarm_arm_home(self, code=None):
|
async def async_alarm_arm_home(self, code=None):
|
||||||
"""Send arm home command.
|
"""Send arm home command.
|
||||||
|
@ -239,7 +239,7 @@ class MqttAlarm(MqttEntity, alarm.AlarmControlPanelEntity):
|
||||||
if code_required and not self._validate_code(code, "arming home"):
|
if code_required and not self._validate_code(code, "arming home"):
|
||||||
return
|
return
|
||||||
action = self._config[CONF_PAYLOAD_ARM_HOME]
|
action = self._config[CONF_PAYLOAD_ARM_HOME]
|
||||||
self._publish(code, action)
|
await self._publish(code, action)
|
||||||
|
|
||||||
async def async_alarm_arm_away(self, code=None):
|
async def async_alarm_arm_away(self, code=None):
|
||||||
"""Send arm away command.
|
"""Send arm away command.
|
||||||
|
@ -250,7 +250,7 @@ class MqttAlarm(MqttEntity, alarm.AlarmControlPanelEntity):
|
||||||
if code_required and not self._validate_code(code, "arming away"):
|
if code_required and not self._validate_code(code, "arming away"):
|
||||||
return
|
return
|
||||||
action = self._config[CONF_PAYLOAD_ARM_AWAY]
|
action = self._config[CONF_PAYLOAD_ARM_AWAY]
|
||||||
self._publish(code, action)
|
await self._publish(code, action)
|
||||||
|
|
||||||
async def async_alarm_arm_night(self, code=None):
|
async def async_alarm_arm_night(self, code=None):
|
||||||
"""Send arm night command.
|
"""Send arm night command.
|
||||||
|
@ -261,7 +261,7 @@ class MqttAlarm(MqttEntity, alarm.AlarmControlPanelEntity):
|
||||||
if code_required and not self._validate_code(code, "arming night"):
|
if code_required and not self._validate_code(code, "arming night"):
|
||||||
return
|
return
|
||||||
action = self._config[CONF_PAYLOAD_ARM_NIGHT]
|
action = self._config[CONF_PAYLOAD_ARM_NIGHT]
|
||||||
self._publish(code, action)
|
await self._publish(code, action)
|
||||||
|
|
||||||
async def async_alarm_arm_vacation(self, code=None):
|
async def async_alarm_arm_vacation(self, code=None):
|
||||||
"""Send arm vacation command.
|
"""Send arm vacation command.
|
||||||
|
@ -272,7 +272,7 @@ class MqttAlarm(MqttEntity, alarm.AlarmControlPanelEntity):
|
||||||
if code_required and not self._validate_code(code, "arming vacation"):
|
if code_required and not self._validate_code(code, "arming vacation"):
|
||||||
return
|
return
|
||||||
action = self._config[CONF_PAYLOAD_ARM_VACATION]
|
action = self._config[CONF_PAYLOAD_ARM_VACATION]
|
||||||
self._publish(code, action)
|
await self._publish(code, action)
|
||||||
|
|
||||||
async def async_alarm_arm_custom_bypass(self, code=None):
|
async def async_alarm_arm_custom_bypass(self, code=None):
|
||||||
"""Send arm custom bypass command.
|
"""Send arm custom bypass command.
|
||||||
|
@ -283,14 +283,14 @@ class MqttAlarm(MqttEntity, alarm.AlarmControlPanelEntity):
|
||||||
if code_required and not self._validate_code(code, "arming custom bypass"):
|
if code_required and not self._validate_code(code, "arming custom bypass"):
|
||||||
return
|
return
|
||||||
action = self._config[CONF_PAYLOAD_ARM_CUSTOM_BYPASS]
|
action = self._config[CONF_PAYLOAD_ARM_CUSTOM_BYPASS]
|
||||||
self._publish(code, action)
|
await self._publish(code, action)
|
||||||
|
|
||||||
def _publish(self, code, action):
|
async def _publish(self, code, action):
|
||||||
"""Publish via mqtt."""
|
"""Publish via mqtt."""
|
||||||
command_template = self._config[CONF_COMMAND_TEMPLATE]
|
command_template = self._config[CONF_COMMAND_TEMPLATE]
|
||||||
values = {"action": action, "code": code}
|
values = {"action": action, "code": code}
|
||||||
payload = command_template.async_render(**values, parse_result=False)
|
payload = command_template.async_render(**values, parse_result=False)
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._config[CONF_COMMAND_TOPIC],
|
self._config[CONF_COMMAND_TOPIC],
|
||||||
payload,
|
payload,
|
||||||
|
|
|
@ -659,9 +659,9 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
||||||
"""Return the list of available fan modes."""
|
"""Return the list of available fan modes."""
|
||||||
return self._config[CONF_FAN_MODE_LIST]
|
return self._config[CONF_FAN_MODE_LIST]
|
||||||
|
|
||||||
def _publish(self, topic, payload):
|
async def _publish(self, topic, payload):
|
||||||
if self._topic[topic] is not None:
|
if self._topic[topic] is not None:
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._topic[topic],
|
self._topic[topic],
|
||||||
payload,
|
payload,
|
||||||
|
@ -669,7 +669,9 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
)
|
)
|
||||||
|
|
||||||
def _set_temperature(self, temp, cmnd_topic, cmnd_template, state_topic, attr):
|
async def _set_temperature(
|
||||||
|
self, temp, cmnd_topic, cmnd_template, state_topic, attr
|
||||||
|
):
|
||||||
if temp is not None:
|
if temp is not None:
|
||||||
if self._topic[state_topic] is None:
|
if self._topic[state_topic] is None:
|
||||||
# optimistic mode
|
# optimistic mode
|
||||||
|
@ -680,7 +682,7 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
||||||
or self._current_operation != HVAC_MODE_OFF
|
or self._current_operation != HVAC_MODE_OFF
|
||||||
):
|
):
|
||||||
payload = self._command_templates[cmnd_template](temp)
|
payload = self._command_templates[cmnd_template](temp)
|
||||||
self._publish(cmnd_topic, payload)
|
await self._publish(cmnd_topic, payload)
|
||||||
|
|
||||||
async def async_set_temperature(self, **kwargs):
|
async def async_set_temperature(self, **kwargs):
|
||||||
"""Set new target temperatures."""
|
"""Set new target temperatures."""
|
||||||
|
@ -688,7 +690,7 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
||||||
operation_mode = kwargs.get(ATTR_HVAC_MODE)
|
operation_mode = kwargs.get(ATTR_HVAC_MODE)
|
||||||
await self.async_set_hvac_mode(operation_mode)
|
await self.async_set_hvac_mode(operation_mode)
|
||||||
|
|
||||||
self._set_temperature(
|
await self._set_temperature(
|
||||||
kwargs.get(ATTR_TEMPERATURE),
|
kwargs.get(ATTR_TEMPERATURE),
|
||||||
CONF_TEMP_COMMAND_TOPIC,
|
CONF_TEMP_COMMAND_TOPIC,
|
||||||
CONF_TEMP_COMMAND_TEMPLATE,
|
CONF_TEMP_COMMAND_TEMPLATE,
|
||||||
|
@ -696,7 +698,7 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
||||||
"_target_temp",
|
"_target_temp",
|
||||||
)
|
)
|
||||||
|
|
||||||
self._set_temperature(
|
await self._set_temperature(
|
||||||
kwargs.get(ATTR_TARGET_TEMP_LOW),
|
kwargs.get(ATTR_TARGET_TEMP_LOW),
|
||||||
CONF_TEMP_LOW_COMMAND_TOPIC,
|
CONF_TEMP_LOW_COMMAND_TOPIC,
|
||||||
CONF_TEMP_LOW_COMMAND_TEMPLATE,
|
CONF_TEMP_LOW_COMMAND_TEMPLATE,
|
||||||
|
@ -704,7 +706,7 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
||||||
"_target_temp_low",
|
"_target_temp_low",
|
||||||
)
|
)
|
||||||
|
|
||||||
self._set_temperature(
|
await self._set_temperature(
|
||||||
kwargs.get(ATTR_TARGET_TEMP_HIGH),
|
kwargs.get(ATTR_TARGET_TEMP_HIGH),
|
||||||
CONF_TEMP_HIGH_COMMAND_TOPIC,
|
CONF_TEMP_HIGH_COMMAND_TOPIC,
|
||||||
CONF_TEMP_HIGH_COMMAND_TEMPLATE,
|
CONF_TEMP_HIGH_COMMAND_TEMPLATE,
|
||||||
|
@ -721,7 +723,7 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
||||||
payload = self._command_templates[CONF_SWING_MODE_COMMAND_TEMPLATE](
|
payload = self._command_templates[CONF_SWING_MODE_COMMAND_TEMPLATE](
|
||||||
swing_mode
|
swing_mode
|
||||||
)
|
)
|
||||||
self._publish(CONF_SWING_MODE_COMMAND_TOPIC, payload)
|
await self._publish(CONF_SWING_MODE_COMMAND_TOPIC, payload)
|
||||||
|
|
||||||
if self._topic[CONF_SWING_MODE_STATE_TOPIC] is None:
|
if self._topic[CONF_SWING_MODE_STATE_TOPIC] is None:
|
||||||
self._current_swing_mode = swing_mode
|
self._current_swing_mode = swing_mode
|
||||||
|
@ -731,7 +733,7 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
||||||
"""Set new target temperature."""
|
"""Set new target temperature."""
|
||||||
if self._config[CONF_SEND_IF_OFF] or self._current_operation != HVAC_MODE_OFF:
|
if self._config[CONF_SEND_IF_OFF] or self._current_operation != HVAC_MODE_OFF:
|
||||||
payload = self._command_templates[CONF_FAN_MODE_COMMAND_TEMPLATE](fan_mode)
|
payload = self._command_templates[CONF_FAN_MODE_COMMAND_TEMPLATE](fan_mode)
|
||||||
self._publish(CONF_FAN_MODE_COMMAND_TOPIC, payload)
|
await self._publish(CONF_FAN_MODE_COMMAND_TOPIC, payload)
|
||||||
|
|
||||||
if self._topic[CONF_FAN_MODE_STATE_TOPIC] is None:
|
if self._topic[CONF_FAN_MODE_STATE_TOPIC] is None:
|
||||||
self._current_fan_mode = fan_mode
|
self._current_fan_mode = fan_mode
|
||||||
|
@ -740,12 +742,14 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
||||||
async def async_set_hvac_mode(self, hvac_mode) -> None:
|
async def async_set_hvac_mode(self, hvac_mode) -> None:
|
||||||
"""Set new operation mode."""
|
"""Set new operation mode."""
|
||||||
if self._current_operation == HVAC_MODE_OFF and hvac_mode != HVAC_MODE_OFF:
|
if self._current_operation == HVAC_MODE_OFF and hvac_mode != HVAC_MODE_OFF:
|
||||||
self._publish(CONF_POWER_COMMAND_TOPIC, self._config[CONF_PAYLOAD_ON])
|
await self._publish(CONF_POWER_COMMAND_TOPIC, self._config[CONF_PAYLOAD_ON])
|
||||||
elif self._current_operation != HVAC_MODE_OFF and hvac_mode == HVAC_MODE_OFF:
|
elif self._current_operation != HVAC_MODE_OFF and hvac_mode == HVAC_MODE_OFF:
|
||||||
self._publish(CONF_POWER_COMMAND_TOPIC, self._config[CONF_PAYLOAD_OFF])
|
await self._publish(
|
||||||
|
CONF_POWER_COMMAND_TOPIC, self._config[CONF_PAYLOAD_OFF]
|
||||||
|
)
|
||||||
|
|
||||||
payload = self._command_templates[CONF_MODE_COMMAND_TEMPLATE](hvac_mode)
|
payload = self._command_templates[CONF_MODE_COMMAND_TEMPLATE](hvac_mode)
|
||||||
self._publish(CONF_MODE_COMMAND_TOPIC, payload)
|
await self._publish(CONF_MODE_COMMAND_TOPIC, payload)
|
||||||
|
|
||||||
if self._topic[CONF_MODE_STATE_TOPIC] is None:
|
if self._topic[CONF_MODE_STATE_TOPIC] is None:
|
||||||
self._current_operation = hvac_mode
|
self._current_operation = hvac_mode
|
||||||
|
@ -770,26 +774,28 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
||||||
optimistic_update = False
|
optimistic_update = False
|
||||||
|
|
||||||
if self._away:
|
if self._away:
|
||||||
optimistic_update = optimistic_update or self._set_away_mode(False)
|
optimistic_update = optimistic_update or await self._set_away_mode(False)
|
||||||
elif preset_mode == PRESET_AWAY:
|
elif preset_mode == PRESET_AWAY:
|
||||||
if self._hold:
|
if self._hold:
|
||||||
self._set_hold_mode(None)
|
await self._set_hold_mode(None)
|
||||||
optimistic_update = optimistic_update or self._set_away_mode(True)
|
optimistic_update = optimistic_update or await self._set_away_mode(True)
|
||||||
else:
|
else:
|
||||||
hold_mode = preset_mode
|
hold_mode = preset_mode
|
||||||
if preset_mode == PRESET_NONE:
|
if preset_mode == PRESET_NONE:
|
||||||
hold_mode = None
|
hold_mode = None
|
||||||
optimistic_update = optimistic_update or self._set_hold_mode(hold_mode)
|
optimistic_update = optimistic_update or await self._set_hold_mode(
|
||||||
|
hold_mode
|
||||||
|
)
|
||||||
|
|
||||||
if optimistic_update:
|
if optimistic_update:
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
def _set_away_mode(self, state):
|
async def _set_away_mode(self, state):
|
||||||
"""Set away mode.
|
"""Set away mode.
|
||||||
|
|
||||||
Returns if we should optimistically write the state.
|
Returns if we should optimistically write the state.
|
||||||
"""
|
"""
|
||||||
self._publish(
|
await self._publish(
|
||||||
CONF_AWAY_MODE_COMMAND_TOPIC,
|
CONF_AWAY_MODE_COMMAND_TOPIC,
|
||||||
self._config[CONF_PAYLOAD_ON] if state else self._config[CONF_PAYLOAD_OFF],
|
self._config[CONF_PAYLOAD_ON] if state else self._config[CONF_PAYLOAD_OFF],
|
||||||
)
|
)
|
||||||
|
@ -800,7 +806,7 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
||||||
self._away = state
|
self._away = state
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _set_hold_mode(self, hold_mode):
|
async def _set_hold_mode(self, hold_mode):
|
||||||
"""Set hold mode.
|
"""Set hold mode.
|
||||||
|
|
||||||
Returns if we should optimistically write the state.
|
Returns if we should optimistically write the state.
|
||||||
|
@ -808,7 +814,7 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
||||||
payload = self._command_templates[CONF_HOLD_COMMAND_TEMPLATE](
|
payload = self._command_templates[CONF_HOLD_COMMAND_TEMPLATE](
|
||||||
hold_mode or "off"
|
hold_mode or "off"
|
||||||
)
|
)
|
||||||
self._publish(CONF_HOLD_COMMAND_TOPIC, payload)
|
await self._publish(CONF_HOLD_COMMAND_TOPIC, payload)
|
||||||
|
|
||||||
if self._topic[CONF_HOLD_STATE_TOPIC] is not None:
|
if self._topic[CONF_HOLD_STATE_TOPIC] is not None:
|
||||||
return False
|
return False
|
||||||
|
@ -816,8 +822,8 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
||||||
self._hold = hold_mode
|
self._hold = hold_mode
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _set_aux_heat(self, state):
|
async def _set_aux_heat(self, state):
|
||||||
self._publish(
|
await self._publish(
|
||||||
CONF_AUX_COMMAND_TOPIC,
|
CONF_AUX_COMMAND_TOPIC,
|
||||||
self._config[CONF_PAYLOAD_ON] if state else self._config[CONF_PAYLOAD_OFF],
|
self._config[CONF_PAYLOAD_ON] if state else self._config[CONF_PAYLOAD_OFF],
|
||||||
)
|
)
|
||||||
|
@ -828,11 +834,11 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
||||||
|
|
||||||
async def async_turn_aux_heat_on(self):
|
async def async_turn_aux_heat_on(self):
|
||||||
"""Turn auxiliary heater on."""
|
"""Turn auxiliary heater on."""
|
||||||
self._set_aux_heat(True)
|
await self._set_aux_heat(True)
|
||||||
|
|
||||||
async def async_turn_aux_heat_off(self):
|
async def async_turn_aux_heat_off(self):
|
||||||
"""Turn auxiliary heater off."""
|
"""Turn auxiliary heater off."""
|
||||||
self._set_aux_heat(False)
|
await self._set_aux_heat(False)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def supported_features(self):
|
def supported_features(self):
|
||||||
|
|
|
@ -528,7 +528,7 @@ class MqttCover(MqttEntity, CoverEntity):
|
||||||
|
|
||||||
This method is a coroutine.
|
This method is a coroutine.
|
||||||
"""
|
"""
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._config.get(CONF_COMMAND_TOPIC),
|
self._config.get(CONF_COMMAND_TOPIC),
|
||||||
self._config[CONF_PAYLOAD_OPEN],
|
self._config[CONF_PAYLOAD_OPEN],
|
||||||
|
@ -549,7 +549,7 @@ class MqttCover(MqttEntity, CoverEntity):
|
||||||
|
|
||||||
This method is a coroutine.
|
This method is a coroutine.
|
||||||
"""
|
"""
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._config.get(CONF_COMMAND_TOPIC),
|
self._config.get(CONF_COMMAND_TOPIC),
|
||||||
self._config[CONF_PAYLOAD_CLOSE],
|
self._config[CONF_PAYLOAD_CLOSE],
|
||||||
|
@ -570,7 +570,7 @@ class MqttCover(MqttEntity, CoverEntity):
|
||||||
|
|
||||||
This method is a coroutine.
|
This method is a coroutine.
|
||||||
"""
|
"""
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._config.get(CONF_COMMAND_TOPIC),
|
self._config.get(CONF_COMMAND_TOPIC),
|
||||||
self._config[CONF_PAYLOAD_STOP],
|
self._config[CONF_PAYLOAD_STOP],
|
||||||
|
@ -580,7 +580,7 @@ class MqttCover(MqttEntity, CoverEntity):
|
||||||
|
|
||||||
async def async_open_cover_tilt(self, **kwargs):
|
async def async_open_cover_tilt(self, **kwargs):
|
||||||
"""Tilt the cover open."""
|
"""Tilt the cover open."""
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._config.get(CONF_TILT_COMMAND_TOPIC),
|
self._config.get(CONF_TILT_COMMAND_TOPIC),
|
||||||
self._config[CONF_TILT_OPEN_POSITION],
|
self._config[CONF_TILT_OPEN_POSITION],
|
||||||
|
@ -595,7 +595,7 @@ class MqttCover(MqttEntity, CoverEntity):
|
||||||
|
|
||||||
async def async_close_cover_tilt(self, **kwargs):
|
async def async_close_cover_tilt(self, **kwargs):
|
||||||
"""Tilt the cover closed."""
|
"""Tilt the cover closed."""
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._config.get(CONF_TILT_COMMAND_TOPIC),
|
self._config.get(CONF_TILT_COMMAND_TOPIC),
|
||||||
self._config[CONF_TILT_CLOSED_POSITION],
|
self._config[CONF_TILT_CLOSED_POSITION],
|
||||||
|
@ -626,7 +626,7 @@ class MqttCover(MqttEntity, CoverEntity):
|
||||||
}
|
}
|
||||||
tilt = template.async_render(parse_result=False, variables=variables)
|
tilt = template.async_render(parse_result=False, variables=variables)
|
||||||
|
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._config.get(CONF_TILT_COMMAND_TOPIC),
|
self._config.get(CONF_TILT_COMMAND_TOPIC),
|
||||||
tilt,
|
tilt,
|
||||||
|
@ -655,7 +655,7 @@ class MqttCover(MqttEntity, CoverEntity):
|
||||||
}
|
}
|
||||||
position = template.async_render(parse_result=False, variables=variables)
|
position = template.async_render(parse_result=False, variables=variables)
|
||||||
|
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._config.get(CONF_SET_POSITION_TOPIC),
|
self._config.get(CONF_SET_POSITION_TOPIC),
|
||||||
position,
|
position,
|
||||||
|
|
|
@ -520,7 +520,7 @@ class MqttFan(MqttEntity, FanEntity):
|
||||||
This method is a coroutine.
|
This method is a coroutine.
|
||||||
"""
|
"""
|
||||||
mqtt_payload = self._command_templates[CONF_STATE](self._payload["STATE_ON"])
|
mqtt_payload = self._command_templates[CONF_STATE](self._payload["STATE_ON"])
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._topic[CONF_COMMAND_TOPIC],
|
self._topic[CONF_COMMAND_TOPIC],
|
||||||
mqtt_payload,
|
mqtt_payload,
|
||||||
|
@ -541,7 +541,7 @@ class MqttFan(MqttEntity, FanEntity):
|
||||||
This method is a coroutine.
|
This method is a coroutine.
|
||||||
"""
|
"""
|
||||||
mqtt_payload = self._command_templates[CONF_STATE](self._payload["STATE_OFF"])
|
mqtt_payload = self._command_templates[CONF_STATE](self._payload["STATE_OFF"])
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._topic[CONF_COMMAND_TOPIC],
|
self._topic[CONF_COMMAND_TOPIC],
|
||||||
mqtt_payload,
|
mqtt_payload,
|
||||||
|
@ -561,7 +561,7 @@ class MqttFan(MqttEntity, FanEntity):
|
||||||
percentage_to_ranged_value(self._speed_range, percentage)
|
percentage_to_ranged_value(self._speed_range, percentage)
|
||||||
)
|
)
|
||||||
mqtt_payload = self._command_templates[ATTR_PERCENTAGE](percentage_payload)
|
mqtt_payload = self._command_templates[ATTR_PERCENTAGE](percentage_payload)
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._topic[CONF_PERCENTAGE_COMMAND_TOPIC],
|
self._topic[CONF_PERCENTAGE_COMMAND_TOPIC],
|
||||||
mqtt_payload,
|
mqtt_payload,
|
||||||
|
@ -584,7 +584,7 @@ class MqttFan(MqttEntity, FanEntity):
|
||||||
|
|
||||||
mqtt_payload = self._command_templates[ATTR_PRESET_MODE](preset_mode)
|
mqtt_payload = self._command_templates[ATTR_PRESET_MODE](preset_mode)
|
||||||
|
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._topic[CONF_PRESET_MODE_COMMAND_TOPIC],
|
self._topic[CONF_PRESET_MODE_COMMAND_TOPIC],
|
||||||
mqtt_payload,
|
mqtt_payload,
|
||||||
|
@ -610,7 +610,7 @@ class MqttFan(MqttEntity, FanEntity):
|
||||||
self._payload["OSCILLATE_OFF_PAYLOAD"]
|
self._payload["OSCILLATE_OFF_PAYLOAD"]
|
||||||
)
|
)
|
||||||
|
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._topic[CONF_OSCILLATION_COMMAND_TOPIC],
|
self._topic[CONF_OSCILLATION_COMMAND_TOPIC],
|
||||||
mqtt_payload,
|
mqtt_payload,
|
||||||
|
|
|
@ -385,7 +385,7 @@ class MqttHumidifier(MqttEntity, HumidifierEntity):
|
||||||
This method is a coroutine.
|
This method is a coroutine.
|
||||||
"""
|
"""
|
||||||
mqtt_payload = self._command_templates[CONF_STATE](self._payload["STATE_ON"])
|
mqtt_payload = self._command_templates[CONF_STATE](self._payload["STATE_ON"])
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._topic[CONF_COMMAND_TOPIC],
|
self._topic[CONF_COMMAND_TOPIC],
|
||||||
mqtt_payload,
|
mqtt_payload,
|
||||||
|
@ -402,7 +402,7 @@ class MqttHumidifier(MqttEntity, HumidifierEntity):
|
||||||
This method is a coroutine.
|
This method is a coroutine.
|
||||||
"""
|
"""
|
||||||
mqtt_payload = self._command_templates[CONF_STATE](self._payload["STATE_OFF"])
|
mqtt_payload = self._command_templates[CONF_STATE](self._payload["STATE_OFF"])
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._topic[CONF_COMMAND_TOPIC],
|
self._topic[CONF_COMMAND_TOPIC],
|
||||||
mqtt_payload,
|
mqtt_payload,
|
||||||
|
@ -419,7 +419,7 @@ class MqttHumidifier(MqttEntity, HumidifierEntity):
|
||||||
This method is a coroutine.
|
This method is a coroutine.
|
||||||
"""
|
"""
|
||||||
mqtt_payload = self._command_templates[ATTR_HUMIDITY](humidity)
|
mqtt_payload = self._command_templates[ATTR_HUMIDITY](humidity)
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._topic[CONF_TARGET_HUMIDITY_COMMAND_TOPIC],
|
self._topic[CONF_TARGET_HUMIDITY_COMMAND_TOPIC],
|
||||||
mqtt_payload,
|
mqtt_payload,
|
||||||
|
@ -442,7 +442,7 @@ class MqttHumidifier(MqttEntity, HumidifierEntity):
|
||||||
|
|
||||||
mqtt_payload = self._command_templates[ATTR_MODE](mode)
|
mqtt_payload = self._command_templates[ATTR_MODE](mode)
|
||||||
|
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._topic[CONF_MODE_COMMAND_TOPIC],
|
self._topic[CONF_MODE_COMMAND_TOPIC],
|
||||||
mqtt_payload,
|
mqtt_payload,
|
||||||
|
|
|
@ -811,9 +811,9 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
should_update = False
|
should_update = False
|
||||||
on_command_type = self._config[CONF_ON_COMMAND_TYPE]
|
on_command_type = self._config[CONF_ON_COMMAND_TYPE]
|
||||||
|
|
||||||
def publish(topic, payload):
|
async def publish(topic, payload):
|
||||||
"""Publish an MQTT message."""
|
"""Publish an MQTT message."""
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._topic[topic],
|
self._topic[topic],
|
||||||
payload,
|
payload,
|
||||||
|
@ -859,7 +859,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if on_command_type == "first":
|
if on_command_type == "first":
|
||||||
publish(CONF_COMMAND_TOPIC, self._payload["on"])
|
await publish(CONF_COMMAND_TOPIC, self._payload["on"])
|
||||||
should_update = True
|
should_update = True
|
||||||
|
|
||||||
# If brightness is being used instead of an on command, make sure
|
# If brightness is being used instead of an on command, make sure
|
||||||
|
@ -881,13 +881,13 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
# Legacy mode: Convert HS to RGB
|
# Legacy mode: Convert HS to RGB
|
||||||
rgb = scale_rgbx(color_util.color_hsv_to_RGB(*hs_color, 100))
|
rgb = scale_rgbx(color_util.color_hsv_to_RGB(*hs_color, 100))
|
||||||
rgb_s = render_rgbx(rgb, CONF_RGB_COMMAND_TEMPLATE, COLOR_MODE_RGB)
|
rgb_s = render_rgbx(rgb, CONF_RGB_COMMAND_TEMPLATE, COLOR_MODE_RGB)
|
||||||
publish(CONF_RGB_COMMAND_TOPIC, rgb_s)
|
await publish(CONF_RGB_COMMAND_TOPIC, rgb_s)
|
||||||
should_update |= set_optimistic(
|
should_update |= set_optimistic(
|
||||||
ATTR_HS_COLOR, hs_color, condition_attribute=ATTR_RGB_COLOR
|
ATTR_HS_COLOR, hs_color, condition_attribute=ATTR_RGB_COLOR
|
||||||
)
|
)
|
||||||
|
|
||||||
if hs_color and self._topic[CONF_HS_COMMAND_TOPIC] is not None:
|
if hs_color and self._topic[CONF_HS_COMMAND_TOPIC] is not None:
|
||||||
publish(CONF_HS_COMMAND_TOPIC, f"{hs_color[0]},{hs_color[1]}")
|
await publish(CONF_HS_COMMAND_TOPIC, f"{hs_color[0]},{hs_color[1]}")
|
||||||
should_update |= set_optimistic(ATTR_HS_COLOR, hs_color, COLOR_MODE_HS)
|
should_update |= set_optimistic(ATTR_HS_COLOR, hs_color, COLOR_MODE_HS)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -897,7 +897,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
):
|
):
|
||||||
# Legacy mode: Convert HS to XY
|
# Legacy mode: Convert HS to XY
|
||||||
xy_color = color_util.color_hs_to_xy(*hs_color)
|
xy_color = color_util.color_hs_to_xy(*hs_color)
|
||||||
publish(CONF_XY_COMMAND_TOPIC, f"{xy_color[0]},{xy_color[1]}")
|
await publish(CONF_XY_COMMAND_TOPIC, f"{xy_color[0]},{xy_color[1]}")
|
||||||
should_update |= set_optimistic(
|
should_update |= set_optimistic(
|
||||||
ATTR_HS_COLOR, hs_color, condition_attribute=ATTR_XY_COLOR
|
ATTR_HS_COLOR, hs_color, condition_attribute=ATTR_XY_COLOR
|
||||||
)
|
)
|
||||||
|
@ -909,7 +909,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
):
|
):
|
||||||
scaled = scale_rgbx(rgb)
|
scaled = scale_rgbx(rgb)
|
||||||
rgb_s = render_rgbx(scaled, CONF_RGB_COMMAND_TEMPLATE, COLOR_MODE_RGB)
|
rgb_s = render_rgbx(scaled, CONF_RGB_COMMAND_TEMPLATE, COLOR_MODE_RGB)
|
||||||
publish(CONF_RGB_COMMAND_TOPIC, rgb_s)
|
await publish(CONF_RGB_COMMAND_TOPIC, rgb_s)
|
||||||
should_update |= set_optimistic(ATTR_RGB_COLOR, rgb, COLOR_MODE_RGB)
|
should_update |= set_optimistic(ATTR_RGB_COLOR, rgb, COLOR_MODE_RGB)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -919,7 +919,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
):
|
):
|
||||||
scaled = scale_rgbx(rgbw)
|
scaled = scale_rgbx(rgbw)
|
||||||
rgbw_s = render_rgbx(scaled, CONF_RGBW_COMMAND_TEMPLATE, COLOR_MODE_RGBW)
|
rgbw_s = render_rgbx(scaled, CONF_RGBW_COMMAND_TEMPLATE, COLOR_MODE_RGBW)
|
||||||
publish(CONF_RGBW_COMMAND_TOPIC, rgbw_s)
|
await publish(CONF_RGBW_COMMAND_TOPIC, rgbw_s)
|
||||||
should_update |= set_optimistic(ATTR_RGBW_COLOR, rgbw, COLOR_MODE_RGBW)
|
should_update |= set_optimistic(ATTR_RGBW_COLOR, rgbw, COLOR_MODE_RGBW)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -929,7 +929,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
):
|
):
|
||||||
scaled = scale_rgbx(rgbww)
|
scaled = scale_rgbx(rgbww)
|
||||||
rgbww_s = render_rgbx(scaled, CONF_RGBWW_COMMAND_TEMPLATE, COLOR_MODE_RGBWW)
|
rgbww_s = render_rgbx(scaled, CONF_RGBWW_COMMAND_TEMPLATE, COLOR_MODE_RGBWW)
|
||||||
publish(CONF_RGBWW_COMMAND_TOPIC, rgbww_s)
|
await publish(CONF_RGBWW_COMMAND_TOPIC, rgbww_s)
|
||||||
should_update |= set_optimistic(ATTR_RGBWW_COLOR, rgbww, COLOR_MODE_RGBWW)
|
should_update |= set_optimistic(ATTR_RGBWW_COLOR, rgbww, COLOR_MODE_RGBWW)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -937,7 +937,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
and self._topic[CONF_XY_COMMAND_TOPIC] is not None
|
and self._topic[CONF_XY_COMMAND_TOPIC] is not None
|
||||||
and not self._legacy_mode
|
and not self._legacy_mode
|
||||||
):
|
):
|
||||||
publish(CONF_XY_COMMAND_TOPIC, f"{xy_color[0]},{xy_color[1]}")
|
await publish(CONF_XY_COMMAND_TOPIC, f"{xy_color[0]},{xy_color[1]}")
|
||||||
should_update |= set_optimistic(ATTR_XY_COLOR, xy_color, COLOR_MODE_XY)
|
should_update |= set_optimistic(ATTR_XY_COLOR, xy_color, COLOR_MODE_XY)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -951,7 +951,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
)
|
)
|
||||||
# Make sure the brightness is not rounded down to 0
|
# Make sure the brightness is not rounded down to 0
|
||||||
device_brightness = max(device_brightness, 1)
|
device_brightness = max(device_brightness, 1)
|
||||||
publish(CONF_BRIGHTNESS_COMMAND_TOPIC, device_brightness)
|
await publish(CONF_BRIGHTNESS_COMMAND_TOPIC, device_brightness)
|
||||||
should_update |= set_optimistic(ATTR_BRIGHTNESS, kwargs[ATTR_BRIGHTNESS])
|
should_update |= set_optimistic(ATTR_BRIGHTNESS, kwargs[ATTR_BRIGHTNESS])
|
||||||
elif (
|
elif (
|
||||||
ATTR_BRIGHTNESS in kwargs
|
ATTR_BRIGHTNESS in kwargs
|
||||||
|
@ -964,7 +964,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
brightness = kwargs[ATTR_BRIGHTNESS]
|
brightness = kwargs[ATTR_BRIGHTNESS]
|
||||||
rgb = scale_rgbx(color_util.color_hsv_to_RGB(*hs_color, 100), brightness)
|
rgb = scale_rgbx(color_util.color_hsv_to_RGB(*hs_color, 100), brightness)
|
||||||
rgb_s = render_rgbx(rgb, CONF_RGB_COMMAND_TEMPLATE, COLOR_MODE_RGB)
|
rgb_s = render_rgbx(rgb, CONF_RGB_COMMAND_TEMPLATE, COLOR_MODE_RGB)
|
||||||
publish(CONF_RGB_COMMAND_TOPIC, rgb_s)
|
await publish(CONF_RGB_COMMAND_TOPIC, rgb_s)
|
||||||
should_update |= set_optimistic(ATTR_BRIGHTNESS, kwargs[ATTR_BRIGHTNESS])
|
should_update |= set_optimistic(ATTR_BRIGHTNESS, kwargs[ATTR_BRIGHTNESS])
|
||||||
elif (
|
elif (
|
||||||
ATTR_BRIGHTNESS in kwargs
|
ATTR_BRIGHTNESS in kwargs
|
||||||
|
@ -975,7 +975,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
rgb_color = self._rgb_color if self._rgb_color is not None else (255,) * 3
|
rgb_color = self._rgb_color if self._rgb_color is not None else (255,) * 3
|
||||||
rgb = scale_rgbx(rgb_color, kwargs[ATTR_BRIGHTNESS])
|
rgb = scale_rgbx(rgb_color, kwargs[ATTR_BRIGHTNESS])
|
||||||
rgb_s = render_rgbx(rgb, CONF_RGB_COMMAND_TEMPLATE, COLOR_MODE_RGB)
|
rgb_s = render_rgbx(rgb, CONF_RGB_COMMAND_TEMPLATE, COLOR_MODE_RGB)
|
||||||
publish(CONF_RGB_COMMAND_TOPIC, rgb_s)
|
await publish(CONF_RGB_COMMAND_TOPIC, rgb_s)
|
||||||
should_update |= set_optimistic(ATTR_BRIGHTNESS, kwargs[ATTR_BRIGHTNESS])
|
should_update |= set_optimistic(ATTR_BRIGHTNESS, kwargs[ATTR_BRIGHTNESS])
|
||||||
elif (
|
elif (
|
||||||
ATTR_BRIGHTNESS in kwargs
|
ATTR_BRIGHTNESS in kwargs
|
||||||
|
@ -988,7 +988,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
)
|
)
|
||||||
rgbw = scale_rgbx(rgbw_color, kwargs[ATTR_BRIGHTNESS])
|
rgbw = scale_rgbx(rgbw_color, kwargs[ATTR_BRIGHTNESS])
|
||||||
rgbw_s = render_rgbx(rgbw, CONF_RGBW_COMMAND_TEMPLATE, COLOR_MODE_RGBW)
|
rgbw_s = render_rgbx(rgbw, CONF_RGBW_COMMAND_TEMPLATE, COLOR_MODE_RGBW)
|
||||||
publish(CONF_RGBW_COMMAND_TOPIC, rgbw_s)
|
await publish(CONF_RGBW_COMMAND_TOPIC, rgbw_s)
|
||||||
should_update |= set_optimistic(ATTR_BRIGHTNESS, kwargs[ATTR_BRIGHTNESS])
|
should_update |= set_optimistic(ATTR_BRIGHTNESS, kwargs[ATTR_BRIGHTNESS])
|
||||||
elif (
|
elif (
|
||||||
ATTR_BRIGHTNESS in kwargs
|
ATTR_BRIGHTNESS in kwargs
|
||||||
|
@ -1001,7 +1001,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
)
|
)
|
||||||
rgbww = scale_rgbx(rgbww_color, kwargs[ATTR_BRIGHTNESS])
|
rgbww = scale_rgbx(rgbww_color, kwargs[ATTR_BRIGHTNESS])
|
||||||
rgbww_s = render_rgbx(rgbww, CONF_RGBWW_COMMAND_TEMPLATE, COLOR_MODE_RGBWW)
|
rgbww_s = render_rgbx(rgbww, CONF_RGBWW_COMMAND_TEMPLATE, COLOR_MODE_RGBWW)
|
||||||
publish(CONF_RGBWW_COMMAND_TOPIC, rgbww_s)
|
await publish(CONF_RGBWW_COMMAND_TOPIC, rgbww_s)
|
||||||
should_update |= set_optimistic(ATTR_BRIGHTNESS, kwargs[ATTR_BRIGHTNESS])
|
should_update |= set_optimistic(ATTR_BRIGHTNESS, kwargs[ATTR_BRIGHTNESS])
|
||||||
if (
|
if (
|
||||||
ATTR_COLOR_TEMP in kwargs
|
ATTR_COLOR_TEMP in kwargs
|
||||||
|
@ -1012,7 +1012,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
if tpl:
|
if tpl:
|
||||||
color_temp = tpl({"value": color_temp})
|
color_temp = tpl({"value": color_temp})
|
||||||
|
|
||||||
publish(CONF_COLOR_TEMP_COMMAND_TOPIC, color_temp)
|
await publish(CONF_COLOR_TEMP_COMMAND_TOPIC, color_temp)
|
||||||
should_update |= set_optimistic(
|
should_update |= set_optimistic(
|
||||||
ATTR_COLOR_TEMP, kwargs[ATTR_COLOR_TEMP], COLOR_MODE_COLOR_TEMP
|
ATTR_COLOR_TEMP, kwargs[ATTR_COLOR_TEMP], COLOR_MODE_COLOR_TEMP
|
||||||
)
|
)
|
||||||
|
@ -1020,14 +1020,14 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
if ATTR_EFFECT in kwargs and self._topic[CONF_EFFECT_COMMAND_TOPIC] is not None:
|
if ATTR_EFFECT in kwargs and self._topic[CONF_EFFECT_COMMAND_TOPIC] is not None:
|
||||||
effect = kwargs[ATTR_EFFECT]
|
effect = kwargs[ATTR_EFFECT]
|
||||||
if effect in self._config.get(CONF_EFFECT_LIST):
|
if effect in self._config.get(CONF_EFFECT_LIST):
|
||||||
publish(CONF_EFFECT_COMMAND_TOPIC, effect)
|
await publish(CONF_EFFECT_COMMAND_TOPIC, effect)
|
||||||
should_update |= set_optimistic(ATTR_EFFECT, effect)
|
should_update |= set_optimistic(ATTR_EFFECT, effect)
|
||||||
|
|
||||||
if ATTR_WHITE in kwargs and self._topic[CONF_WHITE_COMMAND_TOPIC] is not None:
|
if ATTR_WHITE in kwargs and self._topic[CONF_WHITE_COMMAND_TOPIC] is not None:
|
||||||
percent_white = float(kwargs[ATTR_WHITE]) / 255
|
percent_white = float(kwargs[ATTR_WHITE]) / 255
|
||||||
white_scale = self._config[CONF_WHITE_SCALE]
|
white_scale = self._config[CONF_WHITE_SCALE]
|
||||||
device_white_value = min(round(percent_white * white_scale), white_scale)
|
device_white_value = min(round(percent_white * white_scale), white_scale)
|
||||||
publish(CONF_WHITE_COMMAND_TOPIC, device_white_value)
|
await publish(CONF_WHITE_COMMAND_TOPIC, device_white_value)
|
||||||
should_update |= set_optimistic(
|
should_update |= set_optimistic(
|
||||||
ATTR_BRIGHTNESS,
|
ATTR_BRIGHTNESS,
|
||||||
kwargs[ATTR_WHITE],
|
kwargs[ATTR_WHITE],
|
||||||
|
@ -1041,11 +1041,11 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
percent_white = float(kwargs[ATTR_WHITE_VALUE]) / 255
|
percent_white = float(kwargs[ATTR_WHITE_VALUE]) / 255
|
||||||
white_scale = self._config[CONF_WHITE_VALUE_SCALE]
|
white_scale = self._config[CONF_WHITE_VALUE_SCALE]
|
||||||
device_white_value = min(round(percent_white * white_scale), white_scale)
|
device_white_value = min(round(percent_white * white_scale), white_scale)
|
||||||
publish(CONF_WHITE_VALUE_COMMAND_TOPIC, device_white_value)
|
await publish(CONF_WHITE_VALUE_COMMAND_TOPIC, device_white_value)
|
||||||
should_update |= set_optimistic(ATTR_WHITE_VALUE, kwargs[ATTR_WHITE_VALUE])
|
should_update |= set_optimistic(ATTR_WHITE_VALUE, kwargs[ATTR_WHITE_VALUE])
|
||||||
|
|
||||||
if on_command_type == "last":
|
if on_command_type == "last":
|
||||||
publish(CONF_COMMAND_TOPIC, self._payload["on"])
|
await publish(CONF_COMMAND_TOPIC, self._payload["on"])
|
||||||
should_update = True
|
should_update = True
|
||||||
|
|
||||||
if self._optimistic:
|
if self._optimistic:
|
||||||
|
@ -1061,7 +1061,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
|
|
||||||
This method is a coroutine.
|
This method is a coroutine.
|
||||||
"""
|
"""
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._topic[CONF_COMMAND_TOPIC],
|
self._topic[CONF_COMMAND_TOPIC],
|
||||||
self._payload["off"],
|
self._payload["off"],
|
||||||
|
|
|
@ -621,7 +621,7 @@ class MqttLightJson(MqttEntity, LightEntity, RestoreEntity):
|
||||||
self._white_value = kwargs[ATTR_WHITE_VALUE]
|
self._white_value = kwargs[ATTR_WHITE_VALUE]
|
||||||
should_update = True
|
should_update = True
|
||||||
|
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._topic[CONF_COMMAND_TOPIC],
|
self._topic[CONF_COMMAND_TOPIC],
|
||||||
json.dumps(message),
|
json.dumps(message),
|
||||||
|
@ -646,7 +646,7 @@ class MqttLightJson(MqttEntity, LightEntity, RestoreEntity):
|
||||||
|
|
||||||
self._set_flash_and_transition(message, **kwargs)
|
self._set_flash_and_transition(message, **kwargs)
|
||||||
|
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._topic[CONF_COMMAND_TOPIC],
|
self._topic[CONF_COMMAND_TOPIC],
|
||||||
json.dumps(message),
|
json.dumps(message),
|
||||||
|
|
|
@ -374,7 +374,7 @@ class MqttLightTemplate(MqttEntity, LightEntity, RestoreEntity):
|
||||||
if ATTR_TRANSITION in kwargs:
|
if ATTR_TRANSITION in kwargs:
|
||||||
values["transition"] = kwargs[ATTR_TRANSITION]
|
values["transition"] = kwargs[ATTR_TRANSITION]
|
||||||
|
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._topics[CONF_COMMAND_TOPIC],
|
self._topics[CONF_COMMAND_TOPIC],
|
||||||
self._templates[CONF_COMMAND_ON_TEMPLATE].async_render(
|
self._templates[CONF_COMMAND_ON_TEMPLATE].async_render(
|
||||||
|
@ -399,7 +399,7 @@ class MqttLightTemplate(MqttEntity, LightEntity, RestoreEntity):
|
||||||
if ATTR_TRANSITION in kwargs:
|
if ATTR_TRANSITION in kwargs:
|
||||||
values["transition"] = kwargs[ATTR_TRANSITION]
|
values["transition"] = kwargs[ATTR_TRANSITION]
|
||||||
|
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._topics[CONF_COMMAND_TOPIC],
|
self._topics[CONF_COMMAND_TOPIC],
|
||||||
self._templates[CONF_COMMAND_OFF_TEMPLATE].async_render(
|
self._templates[CONF_COMMAND_OFF_TEMPLATE].async_render(
|
||||||
|
|
|
@ -149,7 +149,7 @@ class MqttLock(MqttEntity, LockEntity):
|
||||||
|
|
||||||
This method is a coroutine.
|
This method is a coroutine.
|
||||||
"""
|
"""
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._config[CONF_COMMAND_TOPIC],
|
self._config[CONF_COMMAND_TOPIC],
|
||||||
self._config[CONF_PAYLOAD_LOCK],
|
self._config[CONF_PAYLOAD_LOCK],
|
||||||
|
@ -166,7 +166,7 @@ class MqttLock(MqttEntity, LockEntity):
|
||||||
|
|
||||||
This method is a coroutine.
|
This method is a coroutine.
|
||||||
"""
|
"""
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._config[CONF_COMMAND_TOPIC],
|
self._config[CONF_COMMAND_TOPIC],
|
||||||
self._config[CONF_PAYLOAD_UNLOCK],
|
self._config[CONF_PAYLOAD_UNLOCK],
|
||||||
|
|
|
@ -231,7 +231,7 @@ class MqttNumber(MqttEntity, NumberEntity, RestoreEntity):
|
||||||
self._current_number = current_number
|
self._current_number = current_number
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._config[CONF_COMMAND_TOPIC],
|
self._config[CONF_COMMAND_TOPIC],
|
||||||
current_number,
|
current_number,
|
||||||
|
|
|
@ -121,7 +121,7 @@ class MqttScene(
|
||||||
|
|
||||||
This method is a coroutine.
|
This method is a coroutine.
|
||||||
"""
|
"""
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._config[CONF_COMMAND_TOPIC],
|
self._config[CONF_COMMAND_TOPIC],
|
||||||
self._config[CONF_PAYLOAD_ON],
|
self._config[CONF_PAYLOAD_ON],
|
||||||
|
|
|
@ -168,7 +168,7 @@ class MqttSelect(MqttEntity, SelectEntity, RestoreEntity):
|
||||||
self._attr_current_option = option
|
self._attr_current_option = option
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._config[CONF_COMMAND_TOPIC],
|
self._config[CONF_COMMAND_TOPIC],
|
||||||
option,
|
option,
|
||||||
|
|
|
@ -165,7 +165,7 @@ class MqttSwitch(MqttEntity, SwitchEntity, RestoreEntity):
|
||||||
|
|
||||||
This method is a coroutine.
|
This method is a coroutine.
|
||||||
"""
|
"""
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._config[CONF_COMMAND_TOPIC],
|
self._config[CONF_COMMAND_TOPIC],
|
||||||
self._config[CONF_PAYLOAD_ON],
|
self._config[CONF_PAYLOAD_ON],
|
||||||
|
@ -182,7 +182,7 @@ class MqttSwitch(MqttEntity, SwitchEntity, RestoreEntity):
|
||||||
|
|
||||||
This method is a coroutine.
|
This method is a coroutine.
|
||||||
"""
|
"""
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._config[CONF_COMMAND_TOPIC],
|
self._config[CONF_COMMAND_TOPIC],
|
||||||
self._config[CONF_PAYLOAD_OFF],
|
self._config[CONF_PAYLOAD_OFF],
|
||||||
|
|
|
@ -380,7 +380,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
||||||
if self.supported_features & SUPPORT_TURN_ON == 0:
|
if self.supported_features & SUPPORT_TURN_ON == 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._command_topic,
|
self._command_topic,
|
||||||
self._payloads[CONF_PAYLOAD_TURN_ON],
|
self._payloads[CONF_PAYLOAD_TURN_ON],
|
||||||
|
@ -395,7 +395,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
||||||
if self.supported_features & SUPPORT_TURN_OFF == 0:
|
if self.supported_features & SUPPORT_TURN_OFF == 0:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._command_topic,
|
self._command_topic,
|
||||||
self._payloads[CONF_PAYLOAD_TURN_OFF],
|
self._payloads[CONF_PAYLOAD_TURN_OFF],
|
||||||
|
@ -410,7 +410,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
||||||
if self.supported_features & SUPPORT_STOP == 0:
|
if self.supported_features & SUPPORT_STOP == 0:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._command_topic,
|
self._command_topic,
|
||||||
self._payloads[CONF_PAYLOAD_STOP],
|
self._payloads[CONF_PAYLOAD_STOP],
|
||||||
|
@ -425,7 +425,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
||||||
if self.supported_features & SUPPORT_CLEAN_SPOT == 0:
|
if self.supported_features & SUPPORT_CLEAN_SPOT == 0:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._command_topic,
|
self._command_topic,
|
||||||
self._payloads[CONF_PAYLOAD_CLEAN_SPOT],
|
self._payloads[CONF_PAYLOAD_CLEAN_SPOT],
|
||||||
|
@ -440,7 +440,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
||||||
if self.supported_features & SUPPORT_LOCATE == 0:
|
if self.supported_features & SUPPORT_LOCATE == 0:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._command_topic,
|
self._command_topic,
|
||||||
self._payloads[CONF_PAYLOAD_LOCATE],
|
self._payloads[CONF_PAYLOAD_LOCATE],
|
||||||
|
@ -455,7 +455,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
||||||
if self.supported_features & SUPPORT_PAUSE == 0:
|
if self.supported_features & SUPPORT_PAUSE == 0:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._command_topic,
|
self._command_topic,
|
||||||
self._payloads[CONF_PAYLOAD_START_PAUSE],
|
self._payloads[CONF_PAYLOAD_START_PAUSE],
|
||||||
|
@ -470,7 +470,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
||||||
if self.supported_features & SUPPORT_RETURN_HOME == 0:
|
if self.supported_features & SUPPORT_RETURN_HOME == 0:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._command_topic,
|
self._command_topic,
|
||||||
self._payloads[CONF_PAYLOAD_RETURN_TO_BASE],
|
self._payloads[CONF_PAYLOAD_RETURN_TO_BASE],
|
||||||
|
@ -487,7 +487,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
||||||
) or fan_speed not in self._fan_speed_list:
|
) or fan_speed not in self._fan_speed_list:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
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._status = f"Setting fan to {fan_speed}..."
|
self._status = f"Setting fan to {fan_speed}..."
|
||||||
|
@ -503,7 +503,7 @@ class MqttVacuum(MqttEntity, VacuumEntity):
|
||||||
message = json.dumps(message)
|
message = json.dumps(message)
|
||||||
else:
|
else:
|
||||||
message = command
|
message = command
|
||||||
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._status = f"Sending command {message}..."
|
self._status = f"Sending command {message}..."
|
||||||
|
|
|
@ -240,7 +240,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
|
||||||
"""Start the vacuum."""
|
"""Start the vacuum."""
|
||||||
if self.supported_features & SUPPORT_START == 0:
|
if self.supported_features & SUPPORT_START == 0:
|
||||||
return None
|
return None
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._command_topic,
|
self._command_topic,
|
||||||
self._config[CONF_PAYLOAD_START],
|
self._config[CONF_PAYLOAD_START],
|
||||||
|
@ -252,7 +252,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
|
||||||
"""Pause the vacuum."""
|
"""Pause the vacuum."""
|
||||||
if self.supported_features & SUPPORT_PAUSE == 0:
|
if self.supported_features & SUPPORT_PAUSE == 0:
|
||||||
return None
|
return None
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._command_topic,
|
self._command_topic,
|
||||||
self._config[CONF_PAYLOAD_PAUSE],
|
self._config[CONF_PAYLOAD_PAUSE],
|
||||||
|
@ -264,7 +264,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
|
||||||
"""Stop the vacuum."""
|
"""Stop the vacuum."""
|
||||||
if self.supported_features & SUPPORT_STOP == 0:
|
if self.supported_features & SUPPORT_STOP == 0:
|
||||||
return None
|
return None
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._command_topic,
|
self._command_topic,
|
||||||
self._config[CONF_PAYLOAD_STOP],
|
self._config[CONF_PAYLOAD_STOP],
|
||||||
|
@ -278,7 +278,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
|
||||||
fan_speed not in self._fan_speed_list
|
fan_speed not in self._fan_speed_list
|
||||||
):
|
):
|
||||||
return None
|
return None
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._set_fan_speed_topic,
|
self._set_fan_speed_topic,
|
||||||
fan_speed,
|
fan_speed,
|
||||||
|
@ -290,7 +290,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
|
||||||
"""Tell the vacuum to return to its dock."""
|
"""Tell the vacuum to return to its dock."""
|
||||||
if self.supported_features & SUPPORT_RETURN_HOME == 0:
|
if self.supported_features & SUPPORT_RETURN_HOME == 0:
|
||||||
return None
|
return None
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._command_topic,
|
self._command_topic,
|
||||||
self._config[CONF_PAYLOAD_RETURN_TO_BASE],
|
self._config[CONF_PAYLOAD_RETURN_TO_BASE],
|
||||||
|
@ -302,7 +302,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
|
||||||
"""Perform a spot clean-up."""
|
"""Perform a spot clean-up."""
|
||||||
if self.supported_features & SUPPORT_CLEAN_SPOT == 0:
|
if self.supported_features & SUPPORT_CLEAN_SPOT == 0:
|
||||||
return None
|
return None
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._command_topic,
|
self._command_topic,
|
||||||
self._config[CONF_PAYLOAD_CLEAN_SPOT],
|
self._config[CONF_PAYLOAD_CLEAN_SPOT],
|
||||||
|
@ -314,7 +314,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
|
||||||
"""Locate the vacuum (usually by playing a song)."""
|
"""Locate the vacuum (usually by playing a song)."""
|
||||||
if self.supported_features & SUPPORT_LOCATE == 0:
|
if self.supported_features & SUPPORT_LOCATE == 0:
|
||||||
return None
|
return None
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._command_topic,
|
self._command_topic,
|
||||||
self._config[CONF_PAYLOAD_LOCATE],
|
self._config[CONF_PAYLOAD_LOCATE],
|
||||||
|
@ -332,7 +332,7 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
|
||||||
message = json.dumps(message)
|
message = json.dumps(message)
|
||||||
else:
|
else:
|
||||||
message = command
|
message = command
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
self.hass,
|
self.hass,
|
||||||
self._send_command_topic,
|
self._send_command_topic,
|
||||||
message,
|
message,
|
||||||
|
|
|
@ -3,6 +3,7 @@ import json
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.components import mqtt
|
||||||
from homeassistant.components.mqtt import valid_publish_topic, valid_subscribe_topic
|
from homeassistant.components.mqtt import valid_publish_topic, valid_subscribe_topic
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_SERVICE_DATA,
|
ATTR_SERVICE_DATA,
|
||||||
|
@ -53,15 +54,13 @@ BLOCKED_EVENTS = [
|
||||||
|
|
||||||
async def async_setup(hass, config):
|
async def async_setup(hass, config):
|
||||||
"""Set up the MQTT eventstream component."""
|
"""Set up the MQTT eventstream component."""
|
||||||
mqtt = hass.components.mqtt
|
|
||||||
conf = config.get(DOMAIN, {})
|
conf = config.get(DOMAIN, {})
|
||||||
pub_topic = conf.get(CONF_PUBLISH_TOPIC)
|
pub_topic = conf.get(CONF_PUBLISH_TOPIC)
|
||||||
sub_topic = conf.get(CONF_SUBSCRIBE_TOPIC)
|
sub_topic = conf.get(CONF_SUBSCRIBE_TOPIC)
|
||||||
ignore_event = conf.get(CONF_IGNORE_EVENT)
|
ignore_event = conf.get(CONF_IGNORE_EVENT)
|
||||||
ignore_event.append(EVENT_TIME_CHANGED)
|
ignore_event.append(EVENT_TIME_CHANGED)
|
||||||
|
|
||||||
@callback
|
async def _event_publisher(event):
|
||||||
def _event_publisher(event):
|
|
||||||
"""Handle events by publishing them on the MQTT queue."""
|
"""Handle events by publishing them on the MQTT queue."""
|
||||||
if event.origin != EventOrigin.local:
|
if event.origin != EventOrigin.local:
|
||||||
return
|
return
|
||||||
|
@ -82,7 +81,7 @@ async def async_setup(hass, config):
|
||||||
|
|
||||||
event_info = {"event_type": event.event_type, "event_data": event.data}
|
event_info = {"event_type": event.event_type, "event_data": event.data}
|
||||||
msg = json.dumps(event_info, cls=JSONEncoder)
|
msg = json.dumps(event_info, cls=JSONEncoder)
|
||||||
mqtt.async_publish(pub_topic, msg)
|
await mqtt.async_publish(hass, pub_topic, msg)
|
||||||
|
|
||||||
# Only listen for local events if you are going to publish them.
|
# Only listen for local events if you are going to publish them.
|
||||||
if pub_topic:
|
if pub_topic:
|
||||||
|
@ -117,6 +116,6 @@ async def async_setup(hass, config):
|
||||||
|
|
||||||
# Only subscribe if you specified a topic.
|
# Only subscribe if you specified a topic.
|
||||||
if sub_topic:
|
if sub_topic:
|
||||||
await mqtt.async_subscribe(sub_topic, _event_receiver)
|
await mqtt.async_subscribe(hass, sub_topic, _event_receiver)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -3,9 +3,9 @@ import json
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.components import mqtt
|
||||||
from homeassistant.components.mqtt import valid_publish_topic
|
from homeassistant.components.mqtt import valid_publish_topic
|
||||||
from homeassistant.const import MATCH_ALL
|
from homeassistant.const import MATCH_ALL
|
||||||
from homeassistant.core import callback
|
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.helpers.entityfilter import (
|
from homeassistant.helpers.entityfilter import (
|
||||||
INCLUDE_EXCLUDE_BASE_FILTER_SCHEMA,
|
INCLUDE_EXCLUDE_BASE_FILTER_SCHEMA,
|
||||||
|
@ -44,8 +44,7 @@ async def async_setup(hass, config):
|
||||||
if not base_topic.endswith("/"):
|
if not base_topic.endswith("/"):
|
||||||
base_topic = f"{base_topic}/"
|
base_topic = f"{base_topic}/"
|
||||||
|
|
||||||
@callback
|
async def _state_publisher(entity_id, old_state, new_state):
|
||||||
def _state_publisher(entity_id, old_state, new_state):
|
|
||||||
if new_state is None:
|
if new_state is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -55,22 +54,30 @@ async def async_setup(hass, config):
|
||||||
payload = new_state.state
|
payload = new_state.state
|
||||||
|
|
||||||
mybase = f"{base_topic}{entity_id.replace('.', '/')}/"
|
mybase = f"{base_topic}{entity_id.replace('.', '/')}/"
|
||||||
hass.components.mqtt.async_publish(f"{mybase}state", payload, 1, True)
|
await mqtt.async_publish(hass, f"{mybase}state", payload, 1, True)
|
||||||
|
|
||||||
if publish_timestamps:
|
if publish_timestamps:
|
||||||
if new_state.last_updated:
|
if new_state.last_updated:
|
||||||
hass.components.mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
f"{mybase}last_updated", new_state.last_updated.isoformat(), 1, True
|
hass,
|
||||||
|
f"{mybase}last_updated",
|
||||||
|
new_state.last_updated.isoformat(),
|
||||||
|
1,
|
||||||
|
True,
|
||||||
)
|
)
|
||||||
if new_state.last_changed:
|
if new_state.last_changed:
|
||||||
hass.components.mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
f"{mybase}last_changed", new_state.last_changed.isoformat(), 1, True
|
hass,
|
||||||
|
f"{mybase}last_changed",
|
||||||
|
new_state.last_changed.isoformat(),
|
||||||
|
1,
|
||||||
|
True,
|
||||||
)
|
)
|
||||||
|
|
||||||
if publish_attributes:
|
if publish_attributes:
|
||||||
for key, val in new_state.attributes.items():
|
for key, val in new_state.attributes.items():
|
||||||
encoded_val = json.dumps(val, cls=JSONEncoder)
|
encoded_val = json.dumps(val, cls=JSONEncoder)
|
||||||
hass.components.mqtt.async_publish(mybase + key, encoded_val, 1, True)
|
await mqtt.async_publish(hass, mybase + key, encoded_val, 1, True)
|
||||||
|
|
||||||
async_track_state_change(hass, MATCH_ALL, _state_publisher)
|
async_track_state_change(hass, MATCH_ALL, _state_publisher)
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -185,7 +185,9 @@ async def _get_gateway(
|
||||||
|
|
||||||
def pub_callback(topic: str, payload: str, qos: int, retain: bool) -> None:
|
def pub_callback(topic: str, payload: str, qos: int, retain: bool) -> None:
|
||||||
"""Call MQTT publish function."""
|
"""Call MQTT publish function."""
|
||||||
mqtt.async_publish(topic, payload, qos, retain)
|
hass.async_create_task(
|
||||||
|
mqtt.async_publish(hass, topic, payload, qos, retain)
|
||||||
|
)
|
||||||
|
|
||||||
def sub_callback(
|
def sub_callback(
|
||||||
topic: str, sub_cb: Callable[[str, ReceivePayloadType, int], None], qos: int
|
topic: str, sub_cb: Callable[[str, ReceivePayloadType, int], None], qos: int
|
||||||
|
|
|
@ -106,7 +106,7 @@ async def async_setup_entry( # noqa: C901
|
||||||
_LOGGER.error("MQTT integration is not set up")
|
_LOGGER.error("MQTT integration is not set up")
|
||||||
return
|
return
|
||||||
|
|
||||||
mqtt.async_publish(hass, topic, json.dumps(payload))
|
hass.async_create_task(mqtt.async_publish(hass, topic, json.dumps(payload)))
|
||||||
|
|
||||||
manager_options["send_message"] = send_message
|
manager_options["send_message"] = send_message
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ import logging
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components import mqtt
|
from homeassistant.components import mqtt
|
||||||
from homeassistant.core import callback
|
|
||||||
from homeassistant.helpers import config_validation as cv, intent
|
from homeassistant.helpers import config_validation as cv, intent
|
||||||
|
|
||||||
DOMAIN = "snips"
|
DOMAIN = "snips"
|
||||||
|
@ -90,22 +89,17 @@ SERVICE_SCHEMA_FEEDBACK = vol.Schema(
|
||||||
async def async_setup(hass, config):
|
async def async_setup(hass, config):
|
||||||
"""Activate Snips component."""
|
"""Activate Snips component."""
|
||||||
|
|
||||||
@callback
|
async def async_set_feedback(site_ids, state):
|
||||||
def async_set_feedback(site_ids, state):
|
|
||||||
"""Set Feedback sound state."""
|
"""Set Feedback sound state."""
|
||||||
site_ids = site_ids if site_ids else config[DOMAIN].get(CONF_SITE_IDS)
|
site_ids = site_ids if site_ids else config[DOMAIN].get(CONF_SITE_IDS)
|
||||||
topic = FEEDBACK_ON_TOPIC if state else FEEDBACK_OFF_TOPIC
|
topic = FEEDBACK_ON_TOPIC if state else FEEDBACK_OFF_TOPIC
|
||||||
for site_id in site_ids:
|
for site_id in site_ids:
|
||||||
payload = json.dumps({"siteId": site_id})
|
payload = json.dumps({"siteId": site_id})
|
||||||
hass.components.mqtt.async_publish(
|
await mqtt.async_publish(hass, FEEDBACK_ON_TOPIC, "", qos=0, retain=False)
|
||||||
FEEDBACK_ON_TOPIC, "", qos=0, retain=False
|
await mqtt.async_publish(hass, topic, payload, qos=int(state), retain=state)
|
||||||
)
|
|
||||||
hass.components.mqtt.async_publish(
|
|
||||||
topic, payload, qos=int(state), retain=state
|
|
||||||
)
|
|
||||||
|
|
||||||
if CONF_FEEDBACK in config[DOMAIN]:
|
if CONF_FEEDBACK in config[DOMAIN]:
|
||||||
async_set_feedback(None, config[DOMAIN][CONF_FEEDBACK])
|
await async_set_feedback(None, config[DOMAIN][CONF_FEEDBACK])
|
||||||
|
|
||||||
async def message_received(msg):
|
async def message_received(msg):
|
||||||
"""Handle new messages on MQTT."""
|
"""Handle new messages on MQTT."""
|
||||||
|
@ -153,7 +147,7 @@ async def async_setup(hass, config):
|
||||||
notification["text"] = intent_response.speech["plain"]["speech"]
|
notification["text"] = intent_response.speech["plain"]["speech"]
|
||||||
|
|
||||||
_LOGGER.debug("send_response %s", json.dumps(notification))
|
_LOGGER.debug("send_response %s", json.dumps(notification))
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
hass, "hermes/dialogueManager/endSession", json.dumps(notification)
|
hass, "hermes/dialogueManager/endSession", json.dumps(notification)
|
||||||
)
|
)
|
||||||
except intent.UnknownIntent:
|
except intent.UnknownIntent:
|
||||||
|
@ -163,7 +157,7 @@ async def async_setup(hass, config):
|
||||||
except intent.IntentError:
|
except intent.IntentError:
|
||||||
_LOGGER.exception("Error while handling intent: %s", intent_type)
|
_LOGGER.exception("Error while handling intent: %s", intent_type)
|
||||||
|
|
||||||
await hass.components.mqtt.async_subscribe(INTENT_TOPIC, message_received)
|
await mqtt.async_subscribe(hass, INTENT_TOPIC, message_received)
|
||||||
|
|
||||||
async def snips_say(call):
|
async def snips_say(call):
|
||||||
"""Send a Snips notification message."""
|
"""Send a Snips notification message."""
|
||||||
|
@ -172,7 +166,7 @@ async def async_setup(hass, config):
|
||||||
"customData": call.data.get(ATTR_CUSTOM_DATA, ""),
|
"customData": call.data.get(ATTR_CUSTOM_DATA, ""),
|
||||||
"init": {"type": "notification", "text": call.data.get(ATTR_TEXT)},
|
"init": {"type": "notification", "text": call.data.get(ATTR_TEXT)},
|
||||||
}
|
}
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
hass, "hermes/dialogueManager/startSession", json.dumps(notification)
|
hass, "hermes/dialogueManager/startSession", json.dumps(notification)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
@ -189,18 +183,18 @@ async def async_setup(hass, config):
|
||||||
"intentFilter": call.data.get(ATTR_INTENT_FILTER, []),
|
"intentFilter": call.data.get(ATTR_INTENT_FILTER, []),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
mqtt.async_publish(
|
await mqtt.async_publish(
|
||||||
hass, "hermes/dialogueManager/startSession", json.dumps(notification)
|
hass, "hermes/dialogueManager/startSession", json.dumps(notification)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
async def feedback_on(call):
|
async def feedback_on(call):
|
||||||
"""Turn feedback sounds on."""
|
"""Turn feedback sounds on."""
|
||||||
async_set_feedback(call.data.get(ATTR_SITE_ID), True)
|
await async_set_feedback(call.data.get(ATTR_SITE_ID), True)
|
||||||
|
|
||||||
async def feedback_off(call):
|
async def feedback_off(call):
|
||||||
"""Turn feedback sounds off."""
|
"""Turn feedback sounds off."""
|
||||||
async_set_feedback(call.data.get(ATTR_SITE_ID), False)
|
await async_set_feedback(call.data.get(ATTR_SITE_ID), False)
|
||||||
|
|
||||||
hass.services.async_register(
|
hass.services.async_register(
|
||||||
DOMAIN, SERVICE_SAY, snips_say, schema=SERVICE_SCHEMA_SAY
|
DOMAIN, SERVICE_SAY, snips_say, schema=SERVICE_SCHEMA_SAY
|
||||||
|
|
|
@ -55,7 +55,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
qos: int | None = None,
|
qos: int | None = None,
|
||||||
retain: bool | None = None,
|
retain: bool | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
mqtt.async_publish(hass, topic, payload, qos, retain)
|
if qos is None:
|
||||||
|
qos = 0
|
||||||
|
if retain is None:
|
||||||
|
retain = False
|
||||||
|
hass.async_create_task(mqtt.async_publish(hass, topic, payload, qos, retain))
|
||||||
|
|
||||||
async def _subscribe_topics(sub_state: dict | None, topics: dict) -> dict:
|
async def _subscribe_topics(sub_state: dict | None, topics: dict) -> dict:
|
||||||
# Optionally mark message handlers as callback
|
# Optionally mark message handlers as callback
|
||||||
|
|
|
@ -12,7 +12,6 @@ from homeassistant.components import mqtt, websocket_api
|
||||||
from homeassistant.components.mqtt import debug_info
|
from homeassistant.components.mqtt import debug_info
|
||||||
from homeassistant.components.mqtt.mixins import MQTT_ENTITY_DEVICE_INFO_SCHEMA
|
from homeassistant.components.mqtt.mixins import MQTT_ENTITY_DEVICE_INFO_SCHEMA
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
EVENT_CALL_SERVICE,
|
|
||||||
EVENT_HOMEASSISTANT_STARTED,
|
EVENT_HOMEASSISTANT_STARTED,
|
||||||
EVENT_HOMEASSISTANT_STOP,
|
EVENT_HOMEASSISTANT_STOP,
|
||||||
TEMP_CELSIUS,
|
TEMP_CELSIUS,
|
||||||
|
@ -92,29 +91,51 @@ async def test_mqtt_disconnects_on_home_assistant_stop(hass, mqtt_mock):
|
||||||
assert mqtt_mock.async_disconnect.called
|
assert mqtt_mock.async_disconnect.called
|
||||||
|
|
||||||
|
|
||||||
async def test_publish_calls_service(hass, mqtt_mock, calls, record_calls):
|
async def test_publish_(hass, mqtt_mock):
|
||||||
"""Test the publishing of call to services."""
|
"""Test the publish function."""
|
||||||
hass.bus.async_listen_once(EVENT_CALL_SERVICE, record_calls)
|
await mqtt.async_publish(hass, "test-topic", "test-payload")
|
||||||
|
|
||||||
mqtt.async_publish(hass, "test-topic", "test-payload")
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
assert mqtt_mock.async_publish.called
|
||||||
|
assert mqtt_mock.async_publish.call_args[0] == (
|
||||||
|
"test-topic",
|
||||||
|
"test-payload",
|
||||||
|
0,
|
||||||
|
False,
|
||||||
|
)
|
||||||
|
mqtt_mock.reset_mock()
|
||||||
|
|
||||||
assert len(calls) == 1
|
await mqtt.async_publish(hass, "test-topic", "test-payload", 2, True)
|
||||||
assert calls[0][0].data["service_data"][mqtt.ATTR_TOPIC] == "test-topic"
|
|
||||||
assert calls[0][0].data["service_data"][mqtt.ATTR_PAYLOAD] == "test-payload"
|
|
||||||
assert mqtt.ATTR_QOS not in calls[0][0].data["service_data"]
|
|
||||||
assert mqtt.ATTR_RETAIN not in calls[0][0].data["service_data"]
|
|
||||||
|
|
||||||
hass.bus.async_listen_once(EVENT_CALL_SERVICE, record_calls)
|
|
||||||
|
|
||||||
mqtt.async_publish(hass, "test-topic", "test-payload", 2, True)
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
assert mqtt_mock.async_publish.called
|
||||||
|
assert mqtt_mock.async_publish.call_args[0] == (
|
||||||
|
"test-topic",
|
||||||
|
"test-payload",
|
||||||
|
2,
|
||||||
|
True,
|
||||||
|
)
|
||||||
|
mqtt_mock.reset_mock()
|
||||||
|
|
||||||
assert len(calls) == 2
|
mqtt.publish(hass, "test-topic2", "test-payload2")
|
||||||
assert calls[1][0].data["service_data"][mqtt.ATTR_TOPIC] == "test-topic"
|
await hass.async_block_till_done()
|
||||||
assert calls[1][0].data["service_data"][mqtt.ATTR_PAYLOAD] == "test-payload"
|
assert mqtt_mock.async_publish.called
|
||||||
assert calls[1][0].data["service_data"][mqtt.ATTR_QOS] == 2
|
assert mqtt_mock.async_publish.call_args[0] == (
|
||||||
assert calls[1][0].data["service_data"][mqtt.ATTR_RETAIN] is True
|
"test-topic2",
|
||||||
|
"test-payload2",
|
||||||
|
0,
|
||||||
|
False,
|
||||||
|
)
|
||||||
|
mqtt_mock.reset_mock()
|
||||||
|
|
||||||
|
mqtt.publish(hass, "test-topic2", "test-payload2", 2, True)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert mqtt_mock.async_publish.called
|
||||||
|
assert mqtt_mock.async_publish.call_args[0] == (
|
||||||
|
"test-topic2",
|
||||||
|
"test-payload2",
|
||||||
|
2,
|
||||||
|
True,
|
||||||
|
)
|
||||||
|
mqtt_mock.reset_mock()
|
||||||
|
|
||||||
|
|
||||||
async def test_service_call_without_topic_does_not_publish(hass, mqtt_mock):
|
async def test_service_call_without_topic_does_not_publish(hass, mqtt_mock):
|
||||||
|
@ -134,18 +155,6 @@ async def test_service_call_with_template_payload_renders_template(hass, mqtt_mo
|
||||||
|
|
||||||
If 'payload_template' is provided and 'payload' is not, then render it.
|
If 'payload_template' is provided and 'payload' is not, then render it.
|
||||||
"""
|
"""
|
||||||
mqtt.publish_template(hass, "test/topic", "{{ 1+1 }}")
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
assert mqtt_mock.async_publish.called
|
|
||||||
assert mqtt_mock.async_publish.call_args[0][1] == "2"
|
|
||||||
mqtt_mock.reset_mock()
|
|
||||||
|
|
||||||
mqtt.async_publish_template(hass, "test/topic", "{{ 2+2 }}")
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
assert mqtt_mock.async_publish.called
|
|
||||||
assert mqtt_mock.async_publish.call_args[0][1] == "4"
|
|
||||||
mqtt_mock.reset_mock()
|
|
||||||
|
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
mqtt.DOMAIN,
|
mqtt.DOMAIN,
|
||||||
mqtt.SERVICE_PUBLISH,
|
mqtt.SERVICE_PUBLISH,
|
||||||
|
|
|
@ -43,7 +43,7 @@ from homeassistant.components.websocket_api.const import (
|
||||||
from .common import MQTTMessage, setup_ozw
|
from .common import MQTTMessage, setup_ozw
|
||||||
|
|
||||||
|
|
||||||
async def test_websocket_api(hass, generic_data, hass_ws_client):
|
async def test_websocket_api(hass, generic_data, hass_ws_client, mqtt_mock):
|
||||||
"""Test the ozw websocket api."""
|
"""Test the ozw websocket api."""
|
||||||
await setup_ozw(hass, fixture=generic_data)
|
await setup_ozw(hass, fixture=generic_data)
|
||||||
client = await hass_ws_client(hass)
|
client = await hass_ws_client(hass)
|
||||||
|
@ -280,7 +280,7 @@ async def test_websocket_api(hass, generic_data, hass_ws_client):
|
||||||
assert result["code"] == ERR_NOT_FOUND
|
assert result["code"] == ERR_NOT_FOUND
|
||||||
|
|
||||||
|
|
||||||
async def test_ws_locks(hass, lock_data, hass_ws_client):
|
async def test_ws_locks(hass, lock_data, hass_ws_client, mqtt_mock):
|
||||||
"""Test lock websocket apis."""
|
"""Test lock websocket apis."""
|
||||||
await setup_ozw(hass, fixture=lock_data)
|
await setup_ozw(hass, fixture=lock_data)
|
||||||
client = await hass_ws_client(hass)
|
client = await hass_ws_client(hass)
|
||||||
|
@ -319,7 +319,9 @@ async def test_ws_locks(hass, lock_data, hass_ws_client):
|
||||||
assert msg["success"]
|
assert msg["success"]
|
||||||
|
|
||||||
|
|
||||||
async def test_refresh_node(hass, generic_data, sent_messages, hass_ws_client):
|
async def test_refresh_node(
|
||||||
|
hass, generic_data, sent_messages, hass_ws_client, mqtt_mock
|
||||||
|
):
|
||||||
"""Test the ozw refresh node api."""
|
"""Test the ozw refresh node api."""
|
||||||
receive_message = await setup_ozw(hass, fixture=generic_data)
|
receive_message = await setup_ozw(hass, fixture=generic_data)
|
||||||
client = await hass_ws_client(hass)
|
client = await hass_ws_client(hass)
|
||||||
|
@ -368,7 +370,7 @@ async def test_refresh_node(hass, generic_data, sent_messages, hass_ws_client):
|
||||||
assert result["node_query_stage"] == "versions"
|
assert result["node_query_stage"] == "versions"
|
||||||
|
|
||||||
|
|
||||||
async def test_refresh_node_unsubscribe(hass, generic_data, hass_ws_client):
|
async def test_refresh_node_unsubscribe(hass, generic_data, hass_ws_client, mqtt_mock):
|
||||||
"""Test unsubscribing the ozw refresh node api."""
|
"""Test unsubscribing the ozw refresh node api."""
|
||||||
await setup_ozw(hass, fixture=generic_data)
|
await setup_ozw(hass, fixture=generic_data)
|
||||||
client = await hass_ws_client(hass)
|
client = await hass_ws_client(hass)
|
||||||
|
|
|
@ -6,7 +6,6 @@ import pytest
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.bootstrap import async_setup_component
|
from homeassistant.bootstrap import async_setup_component
|
||||||
from homeassistant.components.mqtt import MQTT_PUBLISH_SCHEMA
|
|
||||||
import homeassistant.components.snips as snips
|
import homeassistant.components.snips as snips
|
||||||
from homeassistant.helpers.intent import ServiceIntentHandler, async_register
|
from homeassistant.helpers.intent import ServiceIntentHandler, async_register
|
||||||
|
|
||||||
|
@ -47,38 +46,36 @@ async def test_snips_bad_config(hass, mqtt_mock):
|
||||||
|
|
||||||
async def test_snips_config_feedback_on(hass, mqtt_mock):
|
async def test_snips_config_feedback_on(hass, mqtt_mock):
|
||||||
"""Test Snips Config."""
|
"""Test Snips Config."""
|
||||||
calls = async_mock_service(hass, "mqtt", "publish", MQTT_PUBLISH_SCHEMA)
|
|
||||||
result = await async_setup_component(
|
result = await async_setup_component(
|
||||||
hass, "snips", {"snips": {"feedback_sounds": True}}
|
hass, "snips", {"snips": {"feedback_sounds": True}}
|
||||||
)
|
)
|
||||||
assert result
|
assert result
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert len(calls) == 2
|
assert mqtt_mock.async_publish.call_count == 2
|
||||||
topic = calls[0].data["topic"]
|
topic = mqtt_mock.async_publish.call_args_list[0][0][0]
|
||||||
assert topic == "hermes/feedback/sound/toggleOn"
|
assert topic == "hermes/feedback/sound/toggleOn"
|
||||||
topic = calls[1].data["topic"]
|
topic = mqtt_mock.async_publish.call_args_list[1][0][0]
|
||||||
assert topic == "hermes/feedback/sound/toggleOn"
|
assert topic == "hermes/feedback/sound/toggleOn"
|
||||||
assert calls[1].data["qos"] == 1
|
assert mqtt_mock.async_publish.call_args_list[1][0][2] == 1
|
||||||
assert calls[1].data["retain"]
|
assert mqtt_mock.async_publish.call_args_list[1][0][3]
|
||||||
|
|
||||||
|
|
||||||
async def test_snips_config_feedback_off(hass, mqtt_mock):
|
async def test_snips_config_feedback_off(hass, mqtt_mock):
|
||||||
"""Test Snips Config."""
|
"""Test Snips Config."""
|
||||||
calls = async_mock_service(hass, "mqtt", "publish", MQTT_PUBLISH_SCHEMA)
|
|
||||||
result = await async_setup_component(
|
result = await async_setup_component(
|
||||||
hass, "snips", {"snips": {"feedback_sounds": False}}
|
hass, "snips", {"snips": {"feedback_sounds": False}}
|
||||||
)
|
)
|
||||||
assert result
|
assert result
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert len(calls) == 2
|
assert mqtt_mock.async_publish.call_count == 2
|
||||||
topic = calls[0].data["topic"]
|
topic = mqtt_mock.async_publish.call_args_list[0][0][0]
|
||||||
assert topic == "hermes/feedback/sound/toggleOn"
|
assert topic == "hermes/feedback/sound/toggleOn"
|
||||||
topic = calls[1].data["topic"]
|
topic = mqtt_mock.async_publish.call_args_list[1][0][0]
|
||||||
assert topic == "hermes/feedback/sound/toggleOff"
|
assert topic == "hermes/feedback/sound/toggleOff"
|
||||||
assert calls[1].data["qos"] == 0
|
assert mqtt_mock.async_publish.call_args_list[1][0][2] == 0
|
||||||
assert not calls[1].data["retain"]
|
assert not mqtt_mock.async_publish.call_args_list[1][0][3]
|
||||||
|
|
||||||
|
|
||||||
async def test_snips_config_no_feedback(hass, mqtt_mock):
|
async def test_snips_config_no_feedback(hass, mqtt_mock):
|
||||||
|
@ -232,7 +229,6 @@ async def test_snips_intent_with_duration(hass, mqtt_mock):
|
||||||
|
|
||||||
async def test_intent_speech_response(hass, mqtt_mock):
|
async def test_intent_speech_response(hass, mqtt_mock):
|
||||||
"""Test intent speech response via Snips."""
|
"""Test intent speech response via Snips."""
|
||||||
calls = async_mock_service(hass, "mqtt", "publish", MQTT_PUBLISH_SCHEMA)
|
|
||||||
result = await async_setup_component(hass, "snips", {"snips": {}})
|
result = await async_setup_component(hass, "snips", {"snips": {}})
|
||||||
assert result
|
assert result
|
||||||
result = await async_setup_component(
|
result = await async_setup_component(
|
||||||
|
@ -261,9 +257,9 @@ async def test_intent_speech_response(hass, mqtt_mock):
|
||||||
async_fire_mqtt_message(hass, "hermes/intent/spokenIntent", payload)
|
async_fire_mqtt_message(hass, "hermes/intent/spokenIntent", payload)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert len(calls) == 1
|
assert mqtt_mock.async_publish.call_count == 1
|
||||||
payload = json.loads(calls[0].data["payload"])
|
payload = json.loads(mqtt_mock.async_publish.call_args[0][1])
|
||||||
topic = calls[0].data["topic"]
|
topic = mqtt_mock.async_publish.call_args[0][0]
|
||||||
assert payload["sessionId"] == "abcdef0123456789"
|
assert payload["sessionId"] == "abcdef0123456789"
|
||||||
assert payload["text"] == "I am speaking to you"
|
assert payload["text"] == "I am speaking to you"
|
||||||
assert topic == "hermes/dialogueManager/endSession"
|
assert topic == "hermes/dialogueManager/endSession"
|
||||||
|
|
Loading…
Add table
Reference in a new issue