mirror of
https://github.com/home-assistant/core.git
synced 2025-07-26 06:37:52 +00:00
Add ability for MQTT device tracker to map non-default topic payloads to zones/states (#27143)
* add ability for MQTT device tracker to map nondefault topic payloads to zones * update new parameter name and add abbreviation * support for payload_home, payload_not_home, and payload_custom * use constants STATE_NOT_HOME and STATE_HOME as defaults * reference state constants directly * add empty dict as default for payload_custom * change parameter name for custom mapping of payloads to non-home zones to be more descriptive * removed 'payload_other_zones' per ballobs review * remove abbreviation for 'payload_other_zones' * add tests for feature
This commit is contained in:
parent
489340160b
commit
4e25807b7d
@ -88,11 +88,13 @@ ABBREVIATIONS = {
|
|||||||
"pl_cls": "payload_close",
|
"pl_cls": "payload_close",
|
||||||
"pl_disarm": "payload_disarm",
|
"pl_disarm": "payload_disarm",
|
||||||
"pl_hi_spd": "payload_high_speed",
|
"pl_hi_spd": "payload_high_speed",
|
||||||
|
"pl_home": "payload_home",
|
||||||
"pl_lock": "payload_lock",
|
"pl_lock": "payload_lock",
|
||||||
"pl_loc": "payload_locate",
|
"pl_loc": "payload_locate",
|
||||||
"pl_lo_spd": "payload_low_speed",
|
"pl_lo_spd": "payload_low_speed",
|
||||||
"pl_med_spd": "payload_medium_speed",
|
"pl_med_spd": "payload_medium_speed",
|
||||||
"pl_not_avail": "payload_not_available",
|
"pl_not_avail": "payload_not_available",
|
||||||
|
"pl_not_home": "payload_not_home",
|
||||||
"pl_off": "payload_off",
|
"pl_off": "payload_off",
|
||||||
"pl_off_spd": "payload_off_speed",
|
"pl_off_spd": "payload_off_speed",
|
||||||
"pl_on": "payload_on",
|
"pl_on": "payload_on",
|
||||||
|
@ -5,16 +5,23 @@ import voluptuous as vol
|
|||||||
|
|
||||||
from homeassistant.components import mqtt
|
from homeassistant.components import mqtt
|
||||||
from homeassistant.components.device_tracker import PLATFORM_SCHEMA
|
from homeassistant.components.device_tracker import PLATFORM_SCHEMA
|
||||||
from homeassistant.const import CONF_DEVICES
|
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
from homeassistant.const import CONF_DEVICES, STATE_NOT_HOME, STATE_HOME
|
||||||
|
|
||||||
from . import CONF_QOS
|
from . import CONF_QOS
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
CONF_PAYLOAD_HOME = "payload_home"
|
||||||
|
CONF_PAYLOAD_NOT_HOME = "payload_not_home"
|
||||||
|
|
||||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(mqtt.SCHEMA_BASE).extend(
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(mqtt.SCHEMA_BASE).extend(
|
||||||
{vol.Required(CONF_DEVICES): {cv.string: mqtt.valid_subscribe_topic}}
|
{
|
||||||
|
vol.Required(CONF_DEVICES): {cv.string: mqtt.valid_subscribe_topic},
|
||||||
|
vol.Optional(CONF_PAYLOAD_HOME, default=STATE_HOME): cv.string,
|
||||||
|
vol.Optional(CONF_PAYLOAD_NOT_HOME, default=STATE_NOT_HOME): cv.string,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -22,13 +29,24 @@ async def async_setup_scanner(hass, config, async_see, discovery_info=None):
|
|||||||
"""Set up the MQTT tracker."""
|
"""Set up the MQTT tracker."""
|
||||||
devices = config[CONF_DEVICES]
|
devices = config[CONF_DEVICES]
|
||||||
qos = config[CONF_QOS]
|
qos = config[CONF_QOS]
|
||||||
|
payload_home = config[CONF_PAYLOAD_HOME]
|
||||||
|
payload_not_home = config[CONF_PAYLOAD_NOT_HOME]
|
||||||
|
|
||||||
for dev_id, topic in devices.items():
|
for dev_id, topic in devices.items():
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def async_message_received(msg, dev_id=dev_id):
|
def async_message_received(msg, dev_id=dev_id):
|
||||||
"""Handle received MQTT message."""
|
"""Handle received MQTT message."""
|
||||||
hass.async_create_task(async_see(dev_id=dev_id, location_name=msg.payload))
|
if msg.payload == payload_home:
|
||||||
|
location_name = STATE_HOME
|
||||||
|
elif msg.payload == payload_not_home:
|
||||||
|
location_name = STATE_NOT_HOME
|
||||||
|
else:
|
||||||
|
location_name = msg.payload
|
||||||
|
|
||||||
|
hass.async_create_task(
|
||||||
|
async_see(dev_id=dev_id, location_name=location_name)
|
||||||
|
)
|
||||||
|
|
||||||
await mqtt.async_subscribe(hass, topic, async_message_received, qos)
|
await mqtt.async_subscribe(hass, topic, async_message_received, qos)
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import pytest
|
|||||||
|
|
||||||
from homeassistant.components import device_tracker
|
from homeassistant.components import device_tracker
|
||||||
from homeassistant.components.device_tracker.const import ENTITY_ID_FORMAT
|
from homeassistant.components.device_tracker.const import ENTITY_ID_FORMAT
|
||||||
from homeassistant.const import CONF_PLATFORM
|
from homeassistant.const import CONF_PLATFORM, STATE_HOME, STATE_NOT_HOME
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
from tests.common import async_fire_mqtt_message
|
from tests.common import async_fire_mqtt_message
|
||||||
@ -156,3 +156,65 @@ async def test_multi_level_wildcard_topic_not_matching(hass, mock_device_tracker
|
|||||||
async_fire_mqtt_message(hass, topic, location)
|
async_fire_mqtt_message(hass, topic, location)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert hass.states.get(entity_id) is None
|
assert hass.states.get(entity_id) is None
|
||||||
|
|
||||||
|
|
||||||
|
async def test_matching_custom_payload_for_home_and_not_home(
|
||||||
|
hass, mock_device_tracker_conf
|
||||||
|
):
|
||||||
|
"""Test custom payload_home sets state to home and custom payload_not_home sets state to not_home."""
|
||||||
|
dev_id = "paulus"
|
||||||
|
entity_id = ENTITY_ID_FORMAT.format(dev_id)
|
||||||
|
topic = "/location/paulus"
|
||||||
|
payload_home = "present"
|
||||||
|
payload_not_home = "not present"
|
||||||
|
|
||||||
|
hass.config.components = set(["mqtt", "zone"])
|
||||||
|
assert await async_setup_component(
|
||||||
|
hass,
|
||||||
|
device_tracker.DOMAIN,
|
||||||
|
{
|
||||||
|
device_tracker.DOMAIN: {
|
||||||
|
CONF_PLATFORM: "mqtt",
|
||||||
|
"devices": {dev_id: topic},
|
||||||
|
"payload_home": payload_home,
|
||||||
|
"payload_not_home": payload_not_home,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
async_fire_mqtt_message(hass, topic, payload_home)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert hass.states.get(entity_id).state == STATE_HOME
|
||||||
|
|
||||||
|
async_fire_mqtt_message(hass, topic, payload_not_home)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert hass.states.get(entity_id).state == STATE_NOT_HOME
|
||||||
|
|
||||||
|
|
||||||
|
async def test_not_matching_custom_payload_for_home_and_not_home(
|
||||||
|
hass, mock_device_tracker_conf
|
||||||
|
):
|
||||||
|
"""Test not matching payload does not set state to home or not_home."""
|
||||||
|
dev_id = "paulus"
|
||||||
|
entity_id = ENTITY_ID_FORMAT.format(dev_id)
|
||||||
|
topic = "/location/paulus"
|
||||||
|
payload_home = "present"
|
||||||
|
payload_not_home = "not present"
|
||||||
|
payload_not_matching = "test"
|
||||||
|
|
||||||
|
hass.config.components = set(["mqtt", "zone"])
|
||||||
|
assert await async_setup_component(
|
||||||
|
hass,
|
||||||
|
device_tracker.DOMAIN,
|
||||||
|
{
|
||||||
|
device_tracker.DOMAIN: {
|
||||||
|
CONF_PLATFORM: "mqtt",
|
||||||
|
"devices": {dev_id: topic},
|
||||||
|
"payload_home": payload_home,
|
||||||
|
"payload_not_home": payload_not_home,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
async_fire_mqtt_message(hass, topic, payload_not_matching)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert hass.states.get(entity_id).state != STATE_HOME
|
||||||
|
assert hass.states.get(entity_id).state != STATE_NOT_HOME
|
||||||
|
Loading…
x
Reference in New Issue
Block a user