1
mirror of https://github.com/home-assistant/core synced 2024-08-02 23:40:32 +02:00

Fix MQTT camera encoding (#76124)

* Fix MQTT camera encoding

* Reduce code

* Add test for using image_encoding parameter

* Move deprecation check to validation

* Dependency

* Set correct strings and log warning

* Rename constant

* Use better issue string identifier

* Revert unwanted change to hassio test

* Avoid term `deprecated` in issue description

* Revert changes using the repairs API

* Add a notice when work-a-round will be removed

* Update homeassistant/components/mqtt/camera.py

Co-authored-by: Erik Montnemery <erik@montnemery.com>

Co-authored-by: Erik Montnemery <erik@montnemery.com>
This commit is contained in:
Jan Bouwhuis 2022-08-15 08:26:17 +02:00 committed by GitHub
parent 4f9e6d2407
commit f72cfef7be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 109 additions and 8 deletions

View File

@ -80,6 +80,7 @@ ABBREVIATIONS = {
"hs_stat_t": "hs_state_topic",
"hs_val_tpl": "hs_value_template",
"ic": "icon",
"img_e": "image_encoding",
"init": "initial",
"hum_cmd_t": "target_humidity_command_topic",
"hum_cmd_tpl": "target_humidity_command_template",

View File

@ -3,6 +3,7 @@ from __future__ import annotations
from base64 import b64decode
import functools
import logging
import voluptuous as vol
@ -17,7 +18,7 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from . import subscription
from .config import MQTT_BASE_SCHEMA
from .const import CONF_ENCODING, CONF_QOS, CONF_TOPIC
from .const import CONF_ENCODING, CONF_QOS, CONF_TOPIC, DEFAULT_ENCODING
from .debug_info import log_messages
from .mixins import (
MQTT_ENTITY_COMMON_SCHEMA,
@ -29,6 +30,10 @@ from .mixins import (
)
from .util import valid_subscribe_topic
_LOGGER = logging.getLogger(__name__)
CONF_IMAGE_ENCODING = "image_encoding"
DEFAULT_NAME = "MQTT Camera"
MQTT_CAMERA_ATTRIBUTES_BLOCKED = frozenset(
@ -40,20 +45,41 @@ MQTT_CAMERA_ATTRIBUTES_BLOCKED = frozenset(
}
)
PLATFORM_SCHEMA_MODERN = MQTT_BASE_SCHEMA.extend(
# Using CONF_ENCODING to set b64 encoding for images is deprecated as of Home Assistant 2022.9
# use CONF_IMAGE_ENCODING instead, support for the work-a-round will be removed with Home Assistant 2022.11
def repair_legacy_encoding(config: ConfigType) -> ConfigType:
"""Check incorrect deprecated config of image encoding."""
if config[CONF_ENCODING] == "b64":
config[CONF_IMAGE_ENCODING] = "b64"
config[CONF_ENCODING] = DEFAULT_ENCODING
_LOGGER.warning(
"Using the `encoding` parameter to set image encoding has been deprecated, use `image_encoding` instead"
)
return config
PLATFORM_SCHEMA_BASE = MQTT_BASE_SCHEMA.extend(
{
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Required(CONF_TOPIC): valid_subscribe_topic,
vol.Optional(CONF_IMAGE_ENCODING): "b64",
}
).extend(MQTT_ENTITY_COMMON_SCHEMA.schema)
# Configuring MQTT Camera under the camera platform key is deprecated in HA Core 2022.6
PLATFORM_SCHEMA = vol.All(
cv.PLATFORM_SCHEMA.extend(PLATFORM_SCHEMA_MODERN.schema),
warn_for_legacy_schema(camera.DOMAIN),
PLATFORM_SCHEMA_MODERN = vol.All(
PLATFORM_SCHEMA_BASE.schema,
repair_legacy_encoding,
)
DISCOVERY_SCHEMA = PLATFORM_SCHEMA_MODERN.extend({}, extra=vol.REMOVE_EXTRA)
# Configuring MQTT Camera under the camera platform key is deprecated in HA Core 2022.6
PLATFORM_SCHEMA = vol.All(
cv.PLATFORM_SCHEMA.extend(PLATFORM_SCHEMA_BASE.schema),
warn_for_legacy_schema(camera.DOMAIN),
repair_legacy_encoding,
)
DISCOVERY_SCHEMA = PLATFORM_SCHEMA_BASE.extend({}, extra=vol.REMOVE_EXTRA)
async def async_setup_platform(
@ -124,7 +150,7 @@ class MqttCamera(MqttEntity, Camera):
@log_messages(self.hass, self.entity_id)
def message_received(msg):
"""Handle new MQTT messages."""
if self._config[CONF_ENCODING] == "b64":
if CONF_IMAGE_ENCODING in self._config:
self._last_image = b64decode(msg.payload)
else:
self._last_image = msg.payload

View File

@ -110,6 +110,80 @@ async def test_run_camera_b64_encoded(
assert body == "grass"
# Using CONF_ENCODING to set b64 encoding for images is deprecated Home Assistant 2022.9, use CONF_IMAGE_ENCODING instead
async def test_legacy_camera_b64_encoded_with_availability(
hass, hass_client_no_auth, mqtt_mock_entry_with_yaml_config
):
"""Test availability works if b64 encoding (legacy mode) is turned on."""
topic = "test/camera"
topic_availability = "test/camera_availability"
await async_setup_component(
hass,
"camera",
{
"camera": {
"platform": "mqtt",
"topic": topic,
"name": "Test Camera",
"encoding": "b64",
"availability": {"topic": topic_availability},
}
},
)
await hass.async_block_till_done()
await mqtt_mock_entry_with_yaml_config()
# Make sure we are available
async_fire_mqtt_message(hass, topic_availability, "online")
url = hass.states.get("camera.test_camera").attributes["entity_picture"]
async_fire_mqtt_message(hass, topic, b64encode(b"grass"))
client = await hass_client_no_auth()
resp = await client.get(url)
assert resp.status == HTTPStatus.OK
body = await resp.text()
assert body == "grass"
async def test_camera_b64_encoded_with_availability(
hass, hass_client_no_auth, mqtt_mock_entry_with_yaml_config
):
"""Test availability works if b64 encoding is turned on."""
topic = "test/camera"
topic_availability = "test/camera_availability"
await async_setup_component(
hass,
"camera",
{
"camera": {
"platform": "mqtt",
"topic": topic,
"name": "Test Camera",
"encoding": "utf-8",
"image_encoding": "b64",
"availability": {"topic": topic_availability},
}
},
)
await hass.async_block_till_done()
await mqtt_mock_entry_with_yaml_config()
# Make sure we are available
async_fire_mqtt_message(hass, topic_availability, "online")
url = hass.states.get("camera.test_camera").attributes["entity_picture"]
async_fire_mqtt_message(hass, topic, b64encode(b"grass"))
client = await hass_client_no_auth()
resp = await client.get(url)
assert resp.status == HTTPStatus.OK
body = await resp.text()
assert body == "grass"
async def test_availability_when_connection_lost(
hass, mqtt_mock_entry_with_yaml_config
):