Add device to mqtt camera (#26238)

* Add device to mqtt camera

* Support discovery device info update and add tests
This commit is contained in:
zewelor 2019-09-04 16:15:40 +02:00 committed by Erik Montnemery
parent 2c65e02491
commit c4c21d3e99
2 changed files with 99 additions and 7 deletions

View file

@ -7,13 +7,19 @@ import voluptuous as vol
from homeassistant.components import camera, mqtt
from homeassistant.components.camera import PLATFORM_SCHEMA, Camera
from homeassistant.const import CONF_NAME
from homeassistant.const import CONF_NAME, CONF_DEVICE
from homeassistant.core import callback
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.typing import ConfigType, HomeAssistantType
from . import ATTR_DISCOVERY_HASH, CONF_UNIQUE_ID, MqttDiscoveryUpdate, subscription
from . import (
ATTR_DISCOVERY_HASH,
CONF_UNIQUE_ID,
MqttDiscoveryUpdate,
MqttEntityDeviceInfo,
subscription,
)
from .discovery import MQTT_DISCOVERY_NEW, clear_discovery_hash
_LOGGER = logging.getLogger(__name__)
@ -26,6 +32,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Required(CONF_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_UNIQUE_ID): cv.string,
vol.Optional(CONF_DEVICE): mqtt.MQTT_ENTITY_DEVICE_INFO_SCHEMA,
}
)
@ -45,7 +52,9 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
try:
discovery_hash = discovery_payload.pop(ATTR_DISCOVERY_HASH)
config = PLATFORM_SCHEMA(discovery_payload)
await _async_setup_entity(config, async_add_entities, discovery_hash)
await _async_setup_entity(
config, async_add_entities, config_entry, discovery_hash
)
except Exception:
if discovery_hash:
clear_discovery_hash(hass, discovery_hash)
@ -56,15 +65,17 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
)
async def _async_setup_entity(config, async_add_entities, discovery_hash=None):
async def _async_setup_entity(
config, async_add_entities, config_entry=None, discovery_hash=None
):
"""Set up the MQTT Camera."""
async_add_entities([MqttCamera(config, discovery_hash)])
async_add_entities([MqttCamera(config, config_entry, discovery_hash)])
class MqttCamera(MqttDiscoveryUpdate, Camera):
class MqttCamera(MqttDiscoveryUpdate, MqttEntityDeviceInfo, Camera):
"""representation of a MQTT camera."""
def __init__(self, config, discovery_hash):
def __init__(self, config, config_entry, discovery_hash):
"""Initialize the MQTT Camera."""
self._config = config
self._unique_id = config.get(CONF_UNIQUE_ID)
@ -73,8 +84,11 @@ class MqttCamera(MqttDiscoveryUpdate, Camera):
self._qos = 0
self._last_image = None
device_config = config.get(CONF_DEVICE)
Camera.__init__(self)
MqttDiscoveryUpdate.__init__(self, discovery_hash, self.discovery_update)
MqttEntityDeviceInfo.__init__(self, device_config, config_entry)
async def async_added_to_hass(self):
"""Subscribe MQTT events."""
@ -85,6 +99,7 @@ class MqttCamera(MqttDiscoveryUpdate, Camera):
"""Handle updated discovery message."""
config = PLATFORM_SCHEMA(discovery_payload)
self._config = config
await self.device_info_discovery_update(config)
await self._subscribe_topics()
self.async_write_ha_state()

View file

@ -1,5 +1,6 @@
"""The tests for mqtt camera component."""
from unittest.mock import ANY
import json
from homeassistant.components import camera, mqtt
from homeassistant.components.mqtt.discovery import async_start
@ -167,3 +168,79 @@ async def test_entity_id_update(hass, mqtt_mock):
assert state is not None
assert mock_mqtt.async_subscribe.call_count == 1
mock_mqtt.async_subscribe.assert_any_call("test-topic", ANY, 0, None)
async def test_entity_device_info_with_identifier(hass, mqtt_mock):
"""Test MQTT camera device registry integration."""
entry = MockConfigEntry(domain=mqtt.DOMAIN)
entry.add_to_hass(hass)
await async_start(hass, "homeassistant", {}, entry)
registry = await hass.helpers.device_registry.async_get_registry()
data = json.dumps(
{
"platform": "mqtt",
"name": "Test 1",
"topic": "test-topic",
"device": {
"identifiers": ["helloworld"],
"connections": [["mac", "02:5b:26:a8:dc:12"]],
"manufacturer": "Whatever",
"name": "Beer",
"model": "Glass",
"sw_version": "0.1-beta",
},
"unique_id": "veryunique",
}
)
async_fire_mqtt_message(hass, "homeassistant/camera/bla/config", data)
await hass.async_block_till_done()
device = registry.async_get_device({("mqtt", "helloworld")}, set())
assert device is not None
assert device.identifiers == {("mqtt", "helloworld")}
assert device.connections == {("mac", "02:5b:26:a8:dc:12")}
assert device.manufacturer == "Whatever"
assert device.name == "Beer"
assert device.model == "Glass"
assert device.sw_version == "0.1-beta"
async def test_entity_device_info_update(hass, mqtt_mock):
"""Test device registry update."""
entry = MockConfigEntry(domain=mqtt.DOMAIN)
entry.add_to_hass(hass)
await async_start(hass, "homeassistant", {}, entry)
registry = await hass.helpers.device_registry.async_get_registry()
config = {
"platform": "mqtt",
"name": "Test 1",
"topic": "test-topic",
"device": {
"identifiers": ["helloworld"],
"connections": [["mac", "02:5b:26:a8:dc:12"]],
"manufacturer": "Whatever",
"name": "Beer",
"model": "Glass",
"sw_version": "0.1-beta",
},
"unique_id": "veryunique",
}
data = json.dumps(config)
async_fire_mqtt_message(hass, "homeassistant/camera/bla/config", data)
await hass.async_block_till_done()
device = registry.async_get_device({("mqtt", "helloworld")}, set())
assert device is not None
assert device.name == "Beer"
config["device"]["name"] = "Milk"
data = json.dumps(config)
async_fire_mqtt_message(hass, "homeassistant/camera/bla/config", data)
await hass.async_block_till_done()
device = registry.async_get_device({("mqtt", "helloworld")}, set())
assert device is not None
assert device.name == "Milk"