1 """Support for MQTT images."""
3 from __future__
import annotations
5 from base64
import b64decode
7 from collections.abc
import Callable
9 from typing
import TYPE_CHECKING, Any
12 import voluptuous
as vol
26 from .
import subscription
27 from .config
import MQTT_BASE_SCHEMA
28 from .entity
import MqttEntity, async_setup_entity_entry_helper
32 MqttValueTemplateException,
35 from .schemas
import MQTT_ENTITY_COMMON_SCHEMA
36 from .util
import valid_subscribe_topic
38 _LOGGER = logging.getLogger(__name__)
42 CONF_CONTENT_TYPE =
"content_type"
43 CONF_IMAGE_ENCODING =
"image_encoding"
44 CONF_IMAGE_TOPIC =
"image_topic"
45 CONF_URL_TEMPLATE =
"url_template"
46 CONF_URL_TOPIC =
"url_topic"
48 DEFAULT_NAME =
"MQTT Image"
50 GET_IMAGE_TIMEOUT = 10
54 """Ensure at least one subscribe topic is configured."""
55 if CONF_IMAGE_TOPIC
not in config
and CONF_URL_TOPIC
not in config:
56 raise vol.Invalid(
"Expected one of [`image_topic`, `url_topic`], got none")
57 if CONF_CONTENT_TYPE
in config
and CONF_URL_TOPIC
in config:
59 "Option `content_type` can not be used together with `url_topic`"
64 PLATFORM_SCHEMA_BASE = MQTT_BASE_SCHEMA.extend(
66 vol.Optional(CONF_CONTENT_TYPE): cv.string,
67 vol.Optional(CONF_NAME): vol.Any(cv.string,
None),
68 vol.Exclusive(CONF_URL_TOPIC,
"image_topic"): valid_subscribe_topic,
69 vol.Exclusive(CONF_IMAGE_TOPIC,
"image_topic"): valid_subscribe_topic,
70 vol.Optional(CONF_IMAGE_ENCODING):
"b64",
71 vol.Optional(CONF_URL_TEMPLATE): cv.template,
73 ).extend(MQTT_ENTITY_COMMON_SCHEMA.schema)
75 PLATFORM_SCHEMA_MODERN = vol.All(PLATFORM_SCHEMA_BASE.schema, validate_topic_required)
77 DISCOVERY_SCHEMA = vol.All(
78 PLATFORM_SCHEMA_BASE.extend({}, extra=vol.REMOVE_EXTRA), validate_topic_required
84 config_entry: ConfigEntry,
85 async_add_entities: AddEntitiesCallback,
87 """Set up MQTT image through YAML and through MQTT discovery."""
95 PLATFORM_SCHEMA_MODERN,
100 """representation of a MQTT image."""
102 _default_name = DEFAULT_NAME
103 _entity_id_format: str = image.ENTITY_ID_FORMAT
104 _last_image: bytes |
None =
None
105 _client: httpx.AsyncClient
106 _url_template: Callable[[ReceivePayloadType], ReceivePayloadType]
107 _topic: dict[str, Any]
113 config_entry: ConfigEntry,
114 discovery_data: DiscoveryInfoType |
None,
116 """Initialize the MQTT Image."""
118 ImageEntity.__init__(self, hass)
119 MqttEntity.__init__(self, hass, config, config_entry, discovery_data)
123 """Return the config schema."""
124 return DISCOVERY_SCHEMA
127 """(Re)Setup the entity."""
135 if CONF_IMAGE_TOPIC
in config:
137 CONF_CONTENT_TYPE, DEFAULT_CONTENT_TYPE
139 if CONF_URL_TOPIC
in config:
142 config.get(CONF_URL_TEMPLATE), entity=self
143 ).async_render_with_possible_json_value
147 """Handle new MQTT messages."""
149 if CONF_IMAGE_ENCODING
in self.
_config_config:
153 assert isinstance(msg.payload, bytes)
155 except (binascii.Error, ValueError, AssertionError)
as err:
157 "Error processing image data received at topic %s: %s",
163 self.
hasshasshass.data[DATA_MQTT].state_write_requests.write_state_request(self)
167 """Handle new MQTT messages."""
171 except MqttValueTemplateException
as exc:
176 "Invalid image URL '%s' received at topic %s",
182 self.
hasshasshass.data[DATA_MQTT].state_write_requests.write_state_request(self)
186 """(Re)Subscribe to topics."""
195 """(Re)Subscribe to topics."""
196 subscription.async_subscribe_topics_internal(self.
hasshasshass, self.
_sub_state_sub_state)
199 """Return bytes of image."""
200 if CONF_IMAGE_TOPIC
in self.
_config_config:
bool add_subscription(self, str state_topic_config_key, Callable[[ReceiveMessage], None] msg_callback, set[str]|None tracked_attributes, bool disable_encoding=False)
None __init__(self, HomeAssistant hass, ConfigType config, ConfigEntry config_entry, DiscoveryInfoType|None discovery_data)
None _prepare_subscribe_topics(self)
None _setup_from_config(self, ConfigType config)
None _image_data_received(self, ReceiveMessage msg)
None _image_from_url_request_received(self, ReceiveMessage msg)
bytes|None async_image(self)
VolSchemaType config_schema()
None _subscribe_topics(self)
None async_setup_entity_entry_helper(HomeAssistant hass, ConfigEntry entry, type[MqttEntity]|None entity_class, str domain, AddEntitiesCallback async_add_entities, VolSchemaType discovery_schema, VolSchemaType platform_schema_modern, dict[str, type[MqttEntity]]|None schema_class_mapping=None)
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
ConfigType validate_topic_required(ConfigType config)
httpx.AsyncClient get_async_client(HomeAssistant hass, bool verify_ssl=True)