Remove deprecated features from MQTT platforms (#32909)

* Remove deprecated features

* Lint
pull/32997/head
Erik Montnemery 2020-03-19 06:39:15 +01:00 committed by GitHub
parent 5c1dc60505
commit e0d2e5dcb0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 30 additions and 305 deletions

View File

@ -11,7 +11,7 @@ from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.helpers.typing import HomeAssistantType
from .abbreviations import ABBREVIATIONS, DEVICE_ABBREVIATIONS
from .const import ATTR_DISCOVERY_HASH, ATTR_DISCOVERY_TOPIC, CONF_STATE_TOPIC
from .const import ATTR_DISCOVERY_HASH, ATTR_DISCOVERY_TOPIC
_LOGGER = logging.getLogger(__name__)
@ -50,15 +50,6 @@ CONFIG_ENTRY_COMPONENTS = [
"vacuum",
]
DEPRECATED_PLATFORM_TO_SCHEMA = {
"light": {"mqtt_json": "json", "mqtt_template": "template"}
}
# These components require state_topic to be set.
# If not specified, infer state_topic from discovery topic.
IMPLICIT_STATE_TOPIC_COMPONENTS = ["alarm_control_panel", "binary_sensor", "sensor"]
ALREADY_DISCOVERED = "mqtt_discovered_components"
DATA_CONFIG_ENTRY_LOCK = "mqtt_config_entry_lock"
CONFIG_ENTRY_IS_SETUP = "mqtt_config_entry_is_setup"
@ -143,39 +134,8 @@ async def async_start(
}
setattr(payload, "discovery_data", discovery_data)
if CONF_PLATFORM in payload and "schema" not in payload:
platform = payload[CONF_PLATFORM]
if (
component in DEPRECATED_PLATFORM_TO_SCHEMA
and platform in DEPRECATED_PLATFORM_TO_SCHEMA[component]
):
schema = DEPRECATED_PLATFORM_TO_SCHEMA[component][platform]
payload["schema"] = schema
_LOGGER.warning(
'"platform": "%s" is deprecated, ' 'replace with "schema":"%s"',
platform,
schema,
)
payload[CONF_PLATFORM] = "mqtt"
if (
CONF_STATE_TOPIC not in payload
and component in IMPLICIT_STATE_TOPIC_COMPONENTS
):
# state_topic not specified, infer from discovery topic
fmt_node_id = f"{node_id}/" if node_id else ""
payload[
CONF_STATE_TOPIC
] = f"{discovery_topic}/{component}/{fmt_node_id}{object_id}/state"
_LOGGER.warning(
'implicit %s is deprecated, add "%s":"%s" to '
"%s discovery message",
CONF_STATE_TOPIC,
CONF_STATE_TOPIC,
payload[CONF_STATE_TOPIC],
topic,
)
if ALREADY_DISCOVERED not in hass.data:
hass.data[ALREADY_DISCOVERED] = {}
if discovery_hash in hass.data[ALREADY_DISCOVERED]:

View File

@ -1,6 +1,5 @@
"""Support for MQTT sensors."""
from datetime import timedelta
import json
import logging
from typing import Optional
@ -41,7 +40,6 @@ from .discovery import MQTT_DISCOVERY_NEW, clear_discovery_hash
_LOGGER = logging.getLogger(__name__)
CONF_EXPIRE_AFTER = "expire_after"
CONF_JSON_ATTRS = "json_attributes"
DEFAULT_NAME = "MQTT Sensor"
DEFAULT_FORCE_UPDATE = False
@ -53,7 +51,6 @@ PLATFORM_SCHEMA = (
vol.Optional(CONF_EXPIRE_AFTER): cv.positive_int,
vol.Optional(CONF_FORCE_UPDATE, default=DEFAULT_FORCE_UPDATE): cv.boolean,
vol.Optional(CONF_ICON): cv.icon,
vol.Optional(CONF_JSON_ATTRS, default=[]): cv.ensure_list_csv,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_UNIQUE_ID): cv.string,
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
@ -110,16 +107,9 @@ class MqttSensor(
self._state = None
self._sub_state = None
self._expiration_trigger = None
self._attributes = None
device_config = config.get(CONF_DEVICE)
if config.get(CONF_JSON_ATTRS):
_LOGGER.warning(
'configuration variable "json_attributes" is '
'deprecated, replace with "json_attributes_topic"'
)
MqttAttributes.__init__(self, config)
MqttAvailability.__init__(self, config)
MqttDiscoveryUpdate.__init__(self, discovery_data, self.discovery_update)
@ -165,22 +155,6 @@ class MqttSensor(
self.hass, self.value_is_expired, expiration_at
)
json_attributes = set(self._config[CONF_JSON_ATTRS])
if json_attributes:
self._attributes = {}
try:
json_dict = json.loads(payload)
if isinstance(json_dict, dict):
attrs = {
k: json_dict[k] for k in json_attributes & json_dict.keys()
}
self._attributes = attrs
else:
_LOGGER.warning("JSON result was not a dictionary")
except ValueError:
_LOGGER.warning("MQTT payload could not be parsed as JSON")
_LOGGER.debug("Erroneous JSON: %s", payload)
if template is not None:
payload = template.async_render_with_possible_json_value(
payload, self._state
@ -241,11 +215,6 @@ class MqttSensor(
"""Return the state of the entity."""
return self._state
@property
def device_state_attributes(self):
"""Return the state attributes."""
return self._attributes
@property
def unique_id(self):
"""Return a unique ID."""

View File

@ -117,7 +117,9 @@ async def test_correct_config_discovery(hass, mqtt_mock, caplog):
await async_start(hass, "homeassistant", {}, entry)
async_fire_mqtt_message(
hass, "homeassistant/binary_sensor/bla/config", '{ "name": "Beer" }'
hass,
"homeassistant/binary_sensor/bla/config",
'{ "name": "Beer", "state_topic": "test-topic" }',
)
await hass.async_block_till_done()
@ -199,7 +201,9 @@ async def test_discovery_incl_nodeid(hass, mqtt_mock, caplog):
await async_start(hass, "homeassistant", {}, entry)
async_fire_mqtt_message(
hass, "homeassistant/binary_sensor/my_node_id/bla/config", '{ "name": "Beer" }',
hass,
"homeassistant/binary_sensor/my_node_id/bla/config",
'{ "name": "Beer", "state_topic": "test-topic" }',
)
await hass.async_block_till_done()
@ -217,10 +221,14 @@ async def test_non_duplicate_discovery(hass, mqtt_mock, caplog):
await async_start(hass, "homeassistant", {}, entry)
async_fire_mqtt_message(
hass, "homeassistant/binary_sensor/bla/config", '{ "name": "Beer" }'
hass,
"homeassistant/binary_sensor/bla/config",
'{ "name": "Beer", "state_topic": "test-topic" }',
)
async_fire_mqtt_message(
hass, "homeassistant/binary_sensor/bla/config", '{ "name": "Beer" }'
hass,
"homeassistant/binary_sensor/bla/config",
'{ "name": "Beer", "state_topic": "test-topic" }',
)
await hass.async_block_till_done()
@ -240,7 +248,9 @@ async def test_removal(hass, mqtt_mock, caplog):
await async_start(hass, "homeassistant", {}, entry)
async_fire_mqtt_message(
hass, "homeassistant/binary_sensor/bla/config", '{ "name": "Beer" }'
hass,
"homeassistant/binary_sensor/bla/config",
'{ "name": "Beer", "state_topic": "test-topic" }',
)
await hass.async_block_till_done()
state = hass.states.get("binary_sensor.beer")
@ -259,7 +269,9 @@ async def test_rediscover(hass, mqtt_mock, caplog):
await async_start(hass, "homeassistant", {}, entry)
async_fire_mqtt_message(
hass, "homeassistant/binary_sensor/bla/config", '{ "name": "Beer" }'
hass,
"homeassistant/binary_sensor/bla/config",
'{ "name": "Beer", "state_topic": "test-topic" }',
)
await hass.async_block_till_done()
state = hass.states.get("binary_sensor.beer")
@ -271,7 +283,9 @@ async def test_rediscover(hass, mqtt_mock, caplog):
assert state is None
async_fire_mqtt_message(
hass, "homeassistant/binary_sensor/bla/config", '{ "name": "Beer" }'
hass,
"homeassistant/binary_sensor/bla/config",
'{ "name": "Beer", "state_topic": "test-topic" }',
)
await hass.async_block_till_done()
state = hass.states.get("binary_sensor.beer")
@ -285,7 +299,9 @@ async def test_duplicate_removal(hass, mqtt_mock, caplog):
await async_start(hass, "homeassistant", {}, entry)
async_fire_mqtt_message(
hass, "homeassistant/binary_sensor/bla/config", '{ "name": "Beer" }'
hass,
"homeassistant/binary_sensor/bla/config",
'{ "name": "Beer", "state_topic": "test-topic" }',
)
await hass.async_block_till_done()
async_fire_mqtt_message(hass, "homeassistant/binary_sensor/bla/config", "")
@ -431,93 +447,6 @@ async def test_missing_discover_abbreviations(hass, mqtt_mock, caplog):
assert not missing
async def test_implicit_state_topic_alarm(hass, mqtt_mock, caplog):
"""Test implicit state topic for alarm_control_panel."""
entry = MockConfigEntry(domain=mqtt.DOMAIN)
await async_start(hass, "homeassistant", {}, entry)
data = (
'{ "name": "Test1",'
' "command_topic": "homeassistant/alarm_control_panel/bla/cmnd"'
"}"
)
async_fire_mqtt_message(hass, "homeassistant/alarm_control_panel/bla/config", data)
await hass.async_block_till_done()
assert (
"implicit state_topic is deprecated, add "
'"state_topic":"homeassistant/alarm_control_panel/bla/state"' in caplog.text
)
state = hass.states.get("alarm_control_panel.Test1")
assert state is not None
assert state.name == "Test1"
assert ("alarm_control_panel", "bla") in hass.data[ALREADY_DISCOVERED]
assert state.state == "unknown"
async_fire_mqtt_message(
hass, "homeassistant/alarm_control_panel/bla/state", "armed_away"
)
state = hass.states.get("alarm_control_panel.Test1")
assert state.state == "armed_away"
async def test_implicit_state_topic_binary_sensor(hass, mqtt_mock, caplog):
"""Test implicit state topic for binary_sensor."""
entry = MockConfigEntry(domain=mqtt.DOMAIN)
await async_start(hass, "homeassistant", {}, entry)
data = '{ "name": "Test1"' "}"
async_fire_mqtt_message(hass, "homeassistant/binary_sensor/bla/config", data)
await hass.async_block_till_done()
assert (
"implicit state_topic is deprecated, add "
'"state_topic":"homeassistant/binary_sensor/bla/state"' in caplog.text
)
state = hass.states.get("binary_sensor.Test1")
assert state is not None
assert state.name == "Test1"
assert ("binary_sensor", "bla") in hass.data[ALREADY_DISCOVERED]
assert state.state == "off"
async_fire_mqtt_message(hass, "homeassistant/binary_sensor/bla/state", "ON")
state = hass.states.get("binary_sensor.Test1")
assert state.state == "on"
async def test_implicit_state_topic_sensor(hass, mqtt_mock, caplog):
"""Test implicit state topic for sensor."""
entry = MockConfigEntry(domain=mqtt.DOMAIN)
await async_start(hass, "homeassistant", {}, entry)
data = '{ "name": "Test1"' "}"
async_fire_mqtt_message(hass, "homeassistant/sensor/bla/config", data)
await hass.async_block_till_done()
assert (
"implicit state_topic is deprecated, add "
'"state_topic":"homeassistant/sensor/bla/state"' in caplog.text
)
state = hass.states.get("sensor.Test1")
assert state is not None
assert state.name == "Test1"
assert ("sensor", "bla") in hass.data[ALREADY_DISCOVERED]
assert state.state == "unknown"
async_fire_mqtt_message(hass, "homeassistant/sensor/bla/state", "1234")
state = hass.states.get("sensor.Test1")
assert state.state == "1234"
async def test_no_implicit_state_topic_switch(hass, mqtt_mock, caplog):
"""Test no implicit state topic for switch."""
entry = MockConfigEntry(domain=mqtt.DOMAIN)
@ -552,7 +481,7 @@ async def test_complex_discovery_topic_prefix(hass, mqtt_mock, caplog):
async_fire_mqtt_message(
hass,
("my_home/homeassistant/register/binary_sensor/node1/object1/config"),
'{ "name": "Beer" }',
'{ "name": "Beer", "state_topic": "test-topic" }',
)
await hass.async_block_till_done()

View File

@ -91,8 +91,7 @@ import json
from unittest import mock
from unittest.mock import patch
from homeassistant.components import light, mqtt
from homeassistant.components.mqtt.discovery import async_start
from homeassistant.components import light
from homeassistant.const import (
ATTR_ASSUMED_STATE,
ATTR_SUPPORTED_FEATURES,
@ -122,7 +121,7 @@ from .common import (
help_test_update_with_json_attrs_not_dict,
)
from tests.common import MockConfigEntry, async_fire_mqtt_message, mock_coro
from tests.common import async_fire_mqtt_message, mock_coro
from tests.components.light import common
DEFAULT_CONFIG = {
@ -1061,22 +1060,6 @@ async def test_discovery_removal(hass, mqtt_mock, caplog):
await help_test_discovery_removal(hass, mqtt_mock, caplog, light.DOMAIN, data)
async def test_discovery_deprecated(hass, mqtt_mock, caplog):
"""Test discovery of mqtt_json light with deprecated platform option."""
entry = MockConfigEntry(domain=mqtt.DOMAIN)
await async_start(hass, "homeassistant", {"mqtt": {}}, entry)
data = (
'{ "name": "Beer",'
' "platform": "mqtt_json",'
' "command_topic": "test_topic"}'
)
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data)
await hass.async_block_till_done()
state = hass.states.get("light.beer")
assert state is not None
assert state.name == "Beer"
async def test_discovery_update_light(hass, mqtt_mock, caplog):
"""Test update of discovered light."""
data1 = (

View File

@ -28,8 +28,7 @@ If your light doesn't support RGB feature, omit `(red|green|blue)_template`.
"""
from unittest.mock import patch
from homeassistant.components import light, mqtt
from homeassistant.components.mqtt.discovery import async_start
from homeassistant.components import light
from homeassistant.const import (
ATTR_ASSUMED_STATE,
ATTR_SUPPORTED_FEATURES,
@ -59,12 +58,7 @@ from .common import (
help_test_update_with_json_attrs_not_dict,
)
from tests.common import (
MockConfigEntry,
assert_setup_component,
async_fire_mqtt_message,
mock_coro,
)
from tests.common import assert_setup_component, async_fire_mqtt_message, mock_coro
from tests.components.light import common
DEFAULT_CONFIG = {
@ -883,24 +877,6 @@ async def test_discovery_removal(hass, mqtt_mock, caplog):
await help_test_discovery_removal(hass, mqtt_mock, caplog, light.DOMAIN, data)
async def test_discovery_deprecated(hass, mqtt_mock, caplog):
"""Test discovery of mqtt template light with deprecated option."""
entry = MockConfigEntry(domain=mqtt.DOMAIN)
await async_start(hass, "homeassistant", {"mqtt": {}}, entry)
data = (
'{ "name": "Beer",'
' "platform": "mqtt_template",'
' "command_topic": "test_topic",'
' "command_on_template": "on",'
' "command_off_template": "off"}'
)
async_fire_mqtt_message(hass, "homeassistant/light/bla/config", data)
await hass.async_block_till_done()
state = hass.states.get("light.beer")
assert state is not None
assert state.name == "Beer"
async def test_discovery_update_light(hass, mqtt_mock, caplog):
"""Test update of discovered light."""
data1 = (

View File

@ -240,98 +240,6 @@ async def test_custom_availability_payload(hass, mqtt_mock):
)
async def test_setting_sensor_attribute_via_legacy_mqtt_json_message(hass, mqtt_mock):
"""Test the setting of attribute via MQTT with JSON payload."""
assert await async_setup_component(
hass,
sensor.DOMAIN,
{
sensor.DOMAIN: {
"platform": "mqtt",
"name": "test",
"state_topic": "test-topic",
"unit_of_measurement": "fav unit",
"json_attributes_topic": "test-attributes-topic",
}
},
)
async_fire_mqtt_message(hass, "test-attributes-topic", '{ "val": "100" }')
state = hass.states.get("sensor.test")
assert state.attributes.get("val") == "100"
async def test_update_with_legacy_json_attrs_not_dict(hass, mqtt_mock, caplog):
"""Test attributes get extracted from a JSON result."""
assert await async_setup_component(
hass,
sensor.DOMAIN,
{
sensor.DOMAIN: {
"platform": "mqtt",
"name": "test",
"state_topic": "test-topic",
"unit_of_measurement": "fav unit",
"json_attributes_topic": "test-attributes-topic",
}
},
)
async_fire_mqtt_message(hass, "test-attributes-topic", '[ "list", "of", "things"]')
state = hass.states.get("sensor.test")
assert state.attributes.get("val") is None
assert "JSON result was not a dictionary" in caplog.text
async def test_update_with_legacy_json_attrs_bad_JSON(hass, mqtt_mock, caplog):
"""Test attributes get extracted from a JSON result."""
assert await async_setup_component(
hass,
sensor.DOMAIN,
{
sensor.DOMAIN: {
"platform": "mqtt",
"name": "test",
"state_topic": "test-topic",
"unit_of_measurement": "fav unit",
"json_attributes_topic": "test-attributes-topic",
}
},
)
async_fire_mqtt_message(hass, "test-attributes-topic", "This is not JSON")
state = hass.states.get("sensor.test")
assert state.attributes.get("val") is None
assert "Erroneous JSON: This is not JSON" in caplog.text
async def test_update_with_legacy_json_attrs_and_template(hass, mqtt_mock):
"""Test attributes get extracted from a JSON result."""
assert await async_setup_component(
hass,
sensor.DOMAIN,
{
sensor.DOMAIN: {
"platform": "mqtt",
"name": "test",
"state_topic": "test-topic",
"unit_of_measurement": "fav unit",
"value_template": "{{ value_json.val }}",
"json_attributes": "val",
}
},
)
async_fire_mqtt_message(hass, "test-topic", '{ "val": "100" }')
state = hass.states.get("sensor.test")
assert state.attributes.get("val") == "100"
assert state.state == "100"
async def test_invalid_device_class(hass, mqtt_mock):
"""Test device_class option with invalid value."""
assert await async_setup_component(