mirror of
https://github.com/home-assistant/core.git
synced 2025-07-18 10:47:10 +00:00
Allow MQTT discovery availability shortcut (#57479)
* replace base in availability topic * add tests for availability shortcuts - fix import * group constants * simplified loop * Moving constants to .const * rename value to topic * move CONF_TOPIC to .const * move CONF_AVAILABILITY to .const * remove check for string * Silently ignore if no config topic is found. * CONF_TOPIC should be required
This commit is contained in:
parent
13db867c1d
commit
a36a765352
@ -9,11 +9,13 @@ ATTR_QOS = "qos"
|
|||||||
ATTR_RETAIN = "retain"
|
ATTR_RETAIN = "retain"
|
||||||
ATTR_TOPIC = "topic"
|
ATTR_TOPIC = "topic"
|
||||||
|
|
||||||
|
CONF_AVAILABILITY = "availability"
|
||||||
CONF_BROKER = "broker"
|
CONF_BROKER = "broker"
|
||||||
CONF_BIRTH_MESSAGE = "birth_message"
|
CONF_BIRTH_MESSAGE = "birth_message"
|
||||||
CONF_QOS = ATTR_QOS
|
CONF_QOS = ATTR_QOS
|
||||||
CONF_RETAIN = ATTR_RETAIN
|
CONF_RETAIN = ATTR_RETAIN
|
||||||
CONF_STATE_TOPIC = "state_topic"
|
CONF_STATE_TOPIC = "state_topic"
|
||||||
|
CONF_TOPIC = "topic"
|
||||||
CONF_WILL_MESSAGE = "will_message"
|
CONF_WILL_MESSAGE = "will_message"
|
||||||
|
|
||||||
DATA_MQTT_CONFIG = "mqtt_config"
|
DATA_MQTT_CONFIG = "mqtt_config"
|
||||||
|
@ -22,6 +22,8 @@ from .const import (
|
|||||||
ATTR_DISCOVERY_HASH,
|
ATTR_DISCOVERY_HASH,
|
||||||
ATTR_DISCOVERY_PAYLOAD,
|
ATTR_DISCOVERY_PAYLOAD,
|
||||||
ATTR_DISCOVERY_TOPIC,
|
ATTR_DISCOVERY_TOPIC,
|
||||||
|
CONF_AVAILABILITY,
|
||||||
|
CONF_TOPIC,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -138,6 +140,14 @@ async def async_start( # noqa: C901
|
|||||||
payload[key] = f"{base}{value[1:]}"
|
payload[key] = f"{base}{value[1:]}"
|
||||||
if value[-1] == TOPIC_BASE and key.endswith("topic"):
|
if value[-1] == TOPIC_BASE and key.endswith("topic"):
|
||||||
payload[key] = f"{value[:-1]}{base}"
|
payload[key] = f"{value[:-1]}{base}"
|
||||||
|
if payload.get(CONF_AVAILABILITY):
|
||||||
|
for availability_conf in payload[CONF_AVAILABILITY]:
|
||||||
|
topic = availability_conf.get(CONF_TOPIC)
|
||||||
|
if topic:
|
||||||
|
if topic[0] == TOPIC_BASE:
|
||||||
|
availability_conf[CONF_TOPIC] = f"{base}{topic[1:]}"
|
||||||
|
if topic[-1] == TOPIC_BASE:
|
||||||
|
availability_conf[CONF_TOPIC] = f"{topic[:-1]}{base}"
|
||||||
|
|
||||||
# If present, the node_id will be included in the discovered object id
|
# If present, the node_id will be included in the discovered object id
|
||||||
discovery_id = " ".join((node_id, object_id)) if node_id else object_id
|
discovery_id = " ".join((node_id, object_id)) if node_id else object_id
|
||||||
|
@ -18,12 +18,14 @@ from homeassistant.helpers.dispatcher import (
|
|||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
|
|
||||||
from . import CONF_TOPIC, DATA_MQTT, debug_info, publish, subscription
|
from . import DATA_MQTT, debug_info, publish, subscription
|
||||||
from .const import (
|
from .const import (
|
||||||
ATTR_DISCOVERY_HASH,
|
ATTR_DISCOVERY_HASH,
|
||||||
ATTR_DISCOVERY_PAYLOAD,
|
ATTR_DISCOVERY_PAYLOAD,
|
||||||
ATTR_DISCOVERY_TOPIC,
|
ATTR_DISCOVERY_TOPIC,
|
||||||
|
CONF_AVAILABILITY,
|
||||||
CONF_QOS,
|
CONF_QOS,
|
||||||
|
CONF_TOPIC,
|
||||||
DEFAULT_PAYLOAD_AVAILABLE,
|
DEFAULT_PAYLOAD_AVAILABLE,
|
||||||
DEFAULT_PAYLOAD_NOT_AVAILABLE,
|
DEFAULT_PAYLOAD_NOT_AVAILABLE,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
@ -50,7 +52,6 @@ AVAILABILITY_LATEST = "latest"
|
|||||||
|
|
||||||
AVAILABILITY_MODES = [AVAILABILITY_ALL, AVAILABILITY_ANY, AVAILABILITY_LATEST]
|
AVAILABILITY_MODES = [AVAILABILITY_ALL, AVAILABILITY_ANY, AVAILABILITY_LATEST]
|
||||||
|
|
||||||
CONF_AVAILABILITY = "availability"
|
|
||||||
CONF_AVAILABILITY_MODE = "availability_mode"
|
CONF_AVAILABILITY_MODE = "availability_mode"
|
||||||
CONF_AVAILABILITY_TOPIC = "availability_topic"
|
CONF_AVAILABILITY_TOPIC = "availability_topic"
|
||||||
CONF_ENABLED_BY_DEFAULT = "enabled_by_default"
|
CONF_ENABLED_BY_DEFAULT = "enabled_by_default"
|
||||||
@ -108,7 +109,7 @@ MQTT_AVAILABILITY_LIST_SCHEMA = vol.Schema(
|
|||||||
cv.ensure_list,
|
cv.ensure_list,
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
vol.Optional(CONF_TOPIC): valid_subscribe_topic,
|
vol.Required(CONF_TOPIC): valid_subscribe_topic,
|
||||||
vol.Optional(
|
vol.Optional(
|
||||||
CONF_PAYLOAD_AVAILABLE, default=DEFAULT_PAYLOAD_AVAILABLE
|
CONF_PAYLOAD_AVAILABLE, default=DEFAULT_PAYLOAD_AVAILABLE
|
||||||
): cv.string,
|
): cv.string,
|
||||||
|
@ -12,7 +12,12 @@ from homeassistant.components.mqtt.abbreviations import (
|
|||||||
DEVICE_ABBREVIATIONS,
|
DEVICE_ABBREVIATIONS,
|
||||||
)
|
)
|
||||||
from homeassistant.components.mqtt.discovery import ALREADY_DISCOVERED, async_start
|
from homeassistant.components.mqtt.discovery import ALREADY_DISCOVERED, async_start
|
||||||
from homeassistant.const import EVENT_STATE_CHANGED, STATE_OFF, STATE_ON
|
from homeassistant.const import (
|
||||||
|
EVENT_STATE_CHANGED,
|
||||||
|
STATE_OFF,
|
||||||
|
STATE_ON,
|
||||||
|
STATE_UNAVAILABLE,
|
||||||
|
)
|
||||||
import homeassistant.core as ha
|
import homeassistant.core as ha
|
||||||
|
|
||||||
from tests.common import (
|
from tests.common import (
|
||||||
@ -449,6 +454,18 @@ async def test_discovery_expansion(hass, mqtt_mock, caplog):
|
|||||||
' "name": "DiscoveryExpansionTest1",'
|
' "name": "DiscoveryExpansionTest1",'
|
||||||
' "stat_t": "test_topic/~",'
|
' "stat_t": "test_topic/~",'
|
||||||
' "cmd_t": "~/test_topic",'
|
' "cmd_t": "~/test_topic",'
|
||||||
|
' "availability": ['
|
||||||
|
" {"
|
||||||
|
' "topic":"~/avail_item1",'
|
||||||
|
' "payload_available": "available",'
|
||||||
|
' "payload_not_available": "not_available"'
|
||||||
|
" },"
|
||||||
|
" {"
|
||||||
|
' "topic":"avail_item2/~",'
|
||||||
|
' "payload_available": "available",'
|
||||||
|
' "payload_not_available": "not_available"'
|
||||||
|
" }"
|
||||||
|
" ],"
|
||||||
' "dev":{'
|
' "dev":{'
|
||||||
' "ids":["5706DF"],'
|
' "ids":["5706DF"],'
|
||||||
' "name":"DiscoveryExpansionTest1 Device",'
|
' "name":"DiscoveryExpansionTest1 Device",'
|
||||||
@ -463,6 +480,12 @@ async def test_discovery_expansion(hass, mqtt_mock, caplog):
|
|||||||
async_fire_mqtt_message(hass, "homeassistant/switch/bla/config", data)
|
async_fire_mqtt_message(hass, "homeassistant/switch/bla/config", data)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get("switch.DiscoveryExpansionTest1")
|
||||||
|
assert state.state == STATE_UNAVAILABLE
|
||||||
|
|
||||||
|
async_fire_mqtt_message(hass, "avail_item2/some/base/topic", "available")
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
state = hass.states.get("switch.DiscoveryExpansionTest1")
|
state = hass.states.get("switch.DiscoveryExpansionTest1")
|
||||||
assert state is not None
|
assert state is not None
|
||||||
assert state.name == "DiscoveryExpansionTest1"
|
assert state.name == "DiscoveryExpansionTest1"
|
||||||
@ -474,6 +497,12 @@ async def test_discovery_expansion(hass, mqtt_mock, caplog):
|
|||||||
state = hass.states.get("switch.DiscoveryExpansionTest1")
|
state = hass.states.get("switch.DiscoveryExpansionTest1")
|
||||||
assert state.state == STATE_ON
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
async_fire_mqtt_message(hass, "some/base/topic/avail_item1", "not_available")
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get("switch.DiscoveryExpansionTest1")
|
||||||
|
assert state.state == STATE_UNAVAILABLE
|
||||||
|
|
||||||
|
|
||||||
ABBREVIATIONS_WHITE_LIST = [
|
ABBREVIATIONS_WHITE_LIST = [
|
||||||
# MQTT client/server/trigger settings
|
# MQTT client/server/trigger settings
|
||||||
|
Loading…
x
Reference in New Issue
Block a user