diff --git a/homeassistant/components/mqtt/alarm_control_panel.py b/homeassistant/components/mqtt/alarm_control_panel.py index e4614817790..9264c2c6d2a 100644 --- a/homeassistant/components/mqtt/alarm_control_panel.py +++ b/homeassistant/components/mqtt/alarm_control_panel.py @@ -42,12 +42,12 @@ from .const import ( ) from .debug_info import log_messages from .mixins import ( - MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entity_entry_helper, write_state_on_attr_change, ) from .models import MqttCommandTemplate, MqttValueTemplate, ReceiveMessage +from .schemas import MQTT_ENTITY_COMMON_SCHEMA from .util import valid_publish_topic, valid_subscribe_topic _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/mqtt/binary_sensor.py b/homeassistant/components/mqtt/binary_sensor.py index 6c678ee2b7c..cfc130377eb 100644 --- a/homeassistant/components/mqtt/binary_sensor.py +++ b/homeassistant/components/mqtt/binary_sensor.py @@ -39,13 +39,13 @@ from .config import MQTT_RO_SCHEMA from .const import CONF_ENCODING, CONF_QOS, CONF_STATE_TOPIC, PAYLOAD_NONE from .debug_info import log_messages from .mixins import ( - MQTT_ENTITY_COMMON_SCHEMA, MqttAvailability, MqttEntity, async_setup_entity_entry_helper, write_state_on_attr_change, ) from .models import MqttValueTemplate, ReceiveMessage +from .schemas import MQTT_ENTITY_COMMON_SCHEMA _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/mqtt/button.py b/homeassistant/components/mqtt/button.py index f6374aaa3cd..93fe0c4598e 100644 --- a/homeassistant/components/mqtt/button.py +++ b/homeassistant/components/mqtt/button.py @@ -21,12 +21,9 @@ from .const import ( CONF_QOS, CONF_RETAIN, ) -from .mixins import ( - MQTT_ENTITY_COMMON_SCHEMA, - MqttEntity, - async_setup_entity_entry_helper, -) +from .mixins import MqttEntity, async_setup_entity_entry_helper from .models import MqttCommandTemplate +from .schemas import MQTT_ENTITY_COMMON_SCHEMA from .util import valid_publish_topic CONF_PAYLOAD_PRESS = "payload_press" diff --git a/homeassistant/components/mqtt/camera.py b/homeassistant/components/mqtt/camera.py index 605d37834ec..23457c8d4fc 100644 --- a/homeassistant/components/mqtt/camera.py +++ b/homeassistant/components/mqtt/camera.py @@ -21,12 +21,9 @@ from . import subscription from .config import MQTT_BASE_SCHEMA from .const import CONF_QOS, CONF_TOPIC from .debug_info import log_messages -from .mixins import ( - MQTT_ENTITY_COMMON_SCHEMA, - MqttEntity, - async_setup_entity_entry_helper, -) +from .mixins import MqttEntity, async_setup_entity_entry_helper from .models import ReceiveMessage +from .schemas import MQTT_ENTITY_COMMON_SCHEMA from .util import valid_subscribe_topic _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/mqtt/climate.py b/homeassistant/components/mqtt/climate.py index 972bf02ecea..faf81528b20 100644 --- a/homeassistant/components/mqtt/climate.py +++ b/homeassistant/components/mqtt/climate.py @@ -81,7 +81,6 @@ from .const import ( ) from .debug_info import log_messages from .mixins import ( - MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entity_entry_helper, write_state_on_attr_change, @@ -93,6 +92,7 @@ from .models import ( ReceiveMessage, ReceivePayloadType, ) +from .schemas import MQTT_ENTITY_COMMON_SCHEMA from .util import valid_publish_topic, valid_subscribe_topic _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/mqtt/const.py b/homeassistant/components/mqtt/const.py index 17de3ab1e57..252ce4bb86a 100644 --- a/homeassistant/components/mqtt/const.py +++ b/homeassistant/components/mqtt/const.py @@ -14,13 +14,28 @@ ATTR_RETAIN = "retain" ATTR_SERIAL_NUMBER = "serial_number" ATTR_TOPIC = "topic" +AVAILABILITY_ALL = "all" +AVAILABILITY_ANY = "any" +AVAILABILITY_LATEST = "latest" + +AVAILABILITY_MODES = [AVAILABILITY_ALL, AVAILABILITY_ANY, AVAILABILITY_LATEST] + +CONF_PAYLOAD_AVAILABLE = "payload_available" +CONF_PAYLOAD_NOT_AVAILABLE = "payload_not_available" + CONF_AVAILABILITY = "availability" + +CONF_AVAILABILITY_MODE = "availability_mode" +CONF_AVAILABILITY_TEMPLATE = "availability_template" +CONF_AVAILABILITY_TOPIC = "availability_topic" CONF_BROKER = "broker" CONF_BIRTH_MESSAGE = "birth_message" CONF_COMMAND_TEMPLATE = "command_template" CONF_COMMAND_TOPIC = "command_topic" CONF_DISCOVERY_PREFIX = "discovery_prefix" CONF_ENCODING = "encoding" +CONF_JSON_ATTRS_TOPIC = "json_attributes_topic" +CONF_JSON_ATTRS_TEMPLATE = "json_attributes_template" CONF_KEEPALIVE = "keepalive" CONF_ORIGIN = "origin" CONF_QOS = ATTR_QOS @@ -42,6 +57,7 @@ CONF_CURRENT_HUMIDITY_TEMPLATE = "current_humidity_template" CONF_CURRENT_HUMIDITY_TOPIC = "current_humidity_topic" CONF_CURRENT_TEMP_TEMPLATE = "current_temperature_template" CONF_CURRENT_TEMP_TOPIC = "current_temperature_topic" +CONF_ENABLED_BY_DEFAULT = "enabled_by_default" CONF_MODE_COMMAND_TEMPLATE = "mode_command_template" CONF_MODE_COMMAND_TOPIC = "mode_command_topic" CONF_MODE_LIST = "modes" @@ -169,3 +185,34 @@ RELOADABLE_PLATFORMS = [ ] TEMPLATE_ERRORS = (jinja2.TemplateError, TemplateError, TypeError, ValueError) + +SUPPORTED_COMPONENTS = { + "alarm_control_panel", + "binary_sensor", + "button", + "camera", + "climate", + "cover", + "device_automation", + "device_tracker", + "event", + "fan", + "humidifier", + "image", + "lawn_mower", + "light", + "lock", + "notify", + "number", + "scene", + "siren", + "select", + "sensor", + "switch", + "tag", + "text", + "update", + "vacuum", + "valve", + "water_heater", +} diff --git a/homeassistant/components/mqtt/cover.py b/homeassistant/components/mqtt/cover.py index a659b1bb0c1..1d95c2326a8 100644 --- a/homeassistant/components/mqtt/cover.py +++ b/homeassistant/components/mqtt/cover.py @@ -64,12 +64,12 @@ from .const import ( ) from .debug_info import log_messages from .mixins import ( - MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entity_entry_helper, write_state_on_attr_change, ) from .models import MqttCommandTemplate, MqttValueTemplate, ReceiveMessage +from .schemas import MQTT_ENTITY_COMMON_SCHEMA from .util import valid_publish_topic, valid_subscribe_topic _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/mqtt/device_tracker.py b/homeassistant/components/mqtt/device_tracker.py index 417a636434f..84de7d3de52 100644 --- a/homeassistant/components/mqtt/device_tracker.py +++ b/homeassistant/components/mqtt/device_tracker.py @@ -34,12 +34,12 @@ from .const import CONF_PAYLOAD_RESET, CONF_QOS, CONF_STATE_TOPIC from .debug_info import log_messages from .mixins import ( CONF_JSON_ATTRS_TOPIC, - MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entity_entry_helper, write_state_on_attr_change, ) from .models import MqttValueTemplate, ReceiveMessage, ReceivePayloadType +from .schemas import MQTT_ENTITY_COMMON_SCHEMA from .util import valid_subscribe_topic CONF_PAYLOAD_HOME = "payload_home" diff --git a/homeassistant/components/mqtt/device_trigger.py b/homeassistant/components/mqtt/device_trigger.py index 0bf9c7697cc..7fbc228b3e9 100644 --- a/homeassistant/components/mqtt/device_trigger.py +++ b/homeassistant/components/mqtt/device_trigger.py @@ -36,13 +36,9 @@ from .const import ( DOMAIN, ) from .discovery import MQTTDiscoveryPayload, clear_discovery_hash -from .mixins import ( - MQTT_ENTITY_DEVICE_INFO_SCHEMA, - MqttDiscoveryDeviceUpdate, - send_discovery_done, - update_device, -) +from .mixins import MqttDiscoveryDeviceUpdate, send_discovery_done, update_device from .models import DATA_MQTT +from .schemas import MQTT_ENTITY_DEVICE_INFO_SCHEMA _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/mqtt/discovery.py b/homeassistant/components/mqtt/discovery.py index 1390c5ca8e3..b34141cc440 100644 --- a/homeassistant/components/mqtt/discovery.py +++ b/homeassistant/components/mqtt/discovery.py @@ -10,10 +10,8 @@ import re import time from typing import TYPE_CHECKING, Any -import voluptuous as vol - from homeassistant.config_entries import ConfigEntry -from homeassistant.const import CONF_DEVICE, CONF_NAME, CONF_PLATFORM +from homeassistant.const import CONF_DEVICE, CONF_PLATFORM from homeassistant.core import HomeAssistant, callback from homeassistant.data_entry_flow import FlowResultType import homeassistant.helpers.config_validation as cv @@ -35,12 +33,12 @@ from .const import ( ATTR_DISCOVERY_TOPIC, CONF_AVAILABILITY, CONF_ORIGIN, - CONF_SUPPORT_URL, - CONF_SW_VERSION, CONF_TOPIC, DOMAIN, + SUPPORTED_COMPONENTS, ) from .models import DATA_MQTT, MqttOriginInfo, ReceiveMessage +from .schemas import MQTT_ORIGIN_INFO_SCHEMA from .util import async_forward_entry_setup_and_setup_discovery _LOGGER = logging.getLogger(__name__) @@ -50,37 +48,6 @@ TOPIC_MATCHER = re.compile( r"?(?P[a-zA-Z0-9_-]+)/config" ) -SUPPORTED_COMPONENTS = { - "alarm_control_panel", - "binary_sensor", - "button", - "camera", - "climate", - "cover", - "device_automation", - "device_tracker", - "event", - "fan", - "humidifier", - "image", - "lawn_mower", - "light", - "lock", - "notify", - "number", - "scene", - "siren", - "select", - "sensor", - "switch", - "tag", - "text", - "update", - "vacuum", - "valve", - "water_heater", -} - MQTT_DISCOVERY_UPDATED: SignalTypeFormat[MQTTDiscoveryPayload] = SignalTypeFormat( "mqtt_discovery_updated_{}_{}" ) @@ -94,16 +61,6 @@ MQTT_DISCOVERY_DONE: SignalTypeFormat[Any] = SignalTypeFormat( TOPIC_BASE = "~" -MQTT_ORIGIN_INFO_SCHEMA = vol.All( - vol.Schema( - { - vol.Required(CONF_NAME): cv.string, - vol.Optional(CONF_SW_VERSION): cv.string, - vol.Optional(CONF_SUPPORT_URL): cv.configuration_url, - } - ), -) - class MQTTDiscoveryPayload(dict[str, Any]): """Class to hold and MQTT discovery payload and discovery data.""" diff --git a/homeassistant/components/mqtt/event.py b/homeassistant/components/mqtt/event.py index 6d3574b2d96..5c8ae7f7be1 100644 --- a/homeassistant/components/mqtt/event.py +++ b/homeassistant/components/mqtt/event.py @@ -32,11 +32,7 @@ from .const import ( PAYLOAD_NONE, ) from .debug_info import log_messages -from .mixins import ( - MQTT_ENTITY_COMMON_SCHEMA, - MqttEntity, - async_setup_entity_entry_helper, -) +from .mixins import MqttEntity, async_setup_entity_entry_helper from .models import ( DATA_MQTT, MqttValueTemplate, @@ -45,6 +41,7 @@ from .models import ( ReceiveMessage, ReceivePayloadType, ) +from .schemas import MQTT_ENTITY_COMMON_SCHEMA _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/mqtt/fan.py b/homeassistant/components/mqtt/fan.py index 0fed4ab666e..10571043fb8 100644 --- a/homeassistant/components/mqtt/fan.py +++ b/homeassistant/components/mqtt/fan.py @@ -51,7 +51,6 @@ from .const import ( ) from .debug_info import log_messages from .mixins import ( - MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entity_entry_helper, write_state_on_attr_change, @@ -64,6 +63,7 @@ from .models import ( ReceiveMessage, ReceivePayloadType, ) +from .schemas import MQTT_ENTITY_COMMON_SCHEMA from .util import valid_publish_topic, valid_subscribe_topic CONF_DIRECTION_STATE_TOPIC = "direction_state_topic" diff --git a/homeassistant/components/mqtt/humidifier.py b/homeassistant/components/mqtt/humidifier.py index 7c9ba26389c..b9f57dfe0ef 100644 --- a/homeassistant/components/mqtt/humidifier.py +++ b/homeassistant/components/mqtt/humidifier.py @@ -53,7 +53,6 @@ from .const import ( ) from .debug_info import log_messages from .mixins import ( - MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entity_entry_helper, write_state_on_attr_change, @@ -65,6 +64,7 @@ from .models import ( ReceiveMessage, ReceivePayloadType, ) +from .schemas import MQTT_ENTITY_COMMON_SCHEMA from .util import valid_publish_topic, valid_subscribe_topic CONF_AVAILABLE_MODES_LIST = "modes" diff --git a/homeassistant/components/mqtt/image.py b/homeassistant/components/mqtt/image.py index 1bcfeeb06ad..eec289aa464 100644 --- a/homeassistant/components/mqtt/image.py +++ b/homeassistant/components/mqtt/image.py @@ -27,11 +27,7 @@ from . import subscription from .config import MQTT_BASE_SCHEMA from .const import CONF_ENCODING, CONF_QOS from .debug_info import log_messages -from .mixins import ( - MQTT_ENTITY_COMMON_SCHEMA, - MqttEntity, - async_setup_entity_entry_helper, -) +from .mixins import MqttEntity, async_setup_entity_entry_helper from .models import ( DATA_MQTT, MessageCallbackType, @@ -39,6 +35,7 @@ from .models import ( MqttValueTemplateException, ReceiveMessage, ) +from .schemas import MQTT_ENTITY_COMMON_SCHEMA from .util import valid_subscribe_topic _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/mqtt/lawn_mower.py b/homeassistant/components/mqtt/lawn_mower.py index e6dc9125583..7380f478e2c 100644 --- a/homeassistant/components/mqtt/lawn_mower.py +++ b/homeassistant/components/mqtt/lawn_mower.py @@ -33,7 +33,6 @@ from .const import ( ) from .debug_info import log_messages from .mixins import ( - MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entity_entry_helper, write_state_on_attr_change, @@ -45,6 +44,7 @@ from .models import ( ReceiveMessage, ReceivePayloadType, ) +from .schemas import MQTT_ENTITY_COMMON_SCHEMA from .util import valid_publish_topic, valid_subscribe_topic _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/mqtt/light/schema_basic.py b/homeassistant/components/mqtt/light/schema_basic.py index bf0de319df0..904e45b3d2f 100644 --- a/homeassistant/components/mqtt/light/schema_basic.py +++ b/homeassistant/components/mqtt/light/schema_basic.py @@ -54,7 +54,7 @@ from ..const import ( PAYLOAD_NONE, ) from ..debug_info import log_messages -from ..mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, write_state_on_attr_change +from ..mixins import MqttEntity, write_state_on_attr_change from ..models import ( MessageCallbackType, MqttCommandTemplate, @@ -65,6 +65,7 @@ from ..models import ( ReceivePayloadType, TemplateVarsType, ) +from ..schemas import MQTT_ENTITY_COMMON_SCHEMA from ..util import valid_publish_topic, valid_subscribe_topic from .schema import MQTT_LIGHT_SCHEMA_SCHEMA diff --git a/homeassistant/components/mqtt/light/schema_json.py b/homeassistant/components/mqtt/light/schema_json.py index 6d3cd6328b8..52fbf3429b6 100644 --- a/homeassistant/components/mqtt/light/schema_json.py +++ b/homeassistant/components/mqtt/light/schema_json.py @@ -67,8 +67,9 @@ from ..const import ( DOMAIN as MQTT_DOMAIN, ) from ..debug_info import log_messages -from ..mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, write_state_on_attr_change +from ..mixins import MqttEntity, write_state_on_attr_change from ..models import ReceiveMessage +from ..schemas import MQTT_ENTITY_COMMON_SCHEMA from ..util import valid_subscribe_topic from .schema import MQTT_LIGHT_SCHEMA_SCHEMA from .schema_basic import ( diff --git a/homeassistant/components/mqtt/light/schema_template.py b/homeassistant/components/mqtt/light/schema_template.py index 95f97f0a736..651b691e28e 100644 --- a/homeassistant/components/mqtt/light/schema_template.py +++ b/homeassistant/components/mqtt/light/schema_template.py @@ -45,7 +45,7 @@ from ..const import ( PAYLOAD_NONE, ) from ..debug_info import log_messages -from ..mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, write_state_on_attr_change +from ..mixins import MqttEntity, write_state_on_attr_change from ..models import ( MqttCommandTemplate, MqttValueTemplate, @@ -53,6 +53,7 @@ from ..models import ( ReceiveMessage, ReceivePayloadType, ) +from ..schemas import MQTT_ENTITY_COMMON_SCHEMA from .schema import MQTT_LIGHT_SCHEMA_SCHEMA from .schema_basic import MQTT_LIGHT_ATTRIBUTES_BLOCKED diff --git a/homeassistant/components/mqtt/lock.py b/homeassistant/components/mqtt/lock.py index 00f61b5e224..940e1fd24a3 100644 --- a/homeassistant/components/mqtt/lock.py +++ b/homeassistant/components/mqtt/lock.py @@ -37,7 +37,6 @@ from .const import ( ) from .debug_info import log_messages from .mixins import ( - MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entity_entry_helper, write_state_on_attr_change, @@ -49,6 +48,7 @@ from .models import ( ReceiveMessage, ReceivePayloadType, ) +from .schemas import MQTT_ENTITY_COMMON_SCHEMA CONF_CODE_FORMAT = "code_format" diff --git a/homeassistant/components/mqtt/mixins.py b/homeassistant/components/mqtt/mixins.py index 2f37e33deca..56bbc7b19eb 100644 --- a/homeassistant/components/mqtt/mixins.py +++ b/homeassistant/components/mqtt/mixins.py @@ -31,11 +31,7 @@ from homeassistant.const import ( CONF_VALUE_TEMPLATE, ) from homeassistant.core import Event, HomeAssistant, callback -from homeassistant.helpers import ( - config_validation as cv, - device_registry as dr, - entity_registry as er, -) +from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers.device_registry import ( DeviceEntry, DeviceInfo, @@ -45,11 +41,7 @@ from homeassistant.helpers.dispatcher import ( async_dispatcher_connect, async_dispatcher_send, ) -from homeassistant.helpers.entity import ( - ENTITY_CATEGORIES_SCHEMA, - Entity, - async_generate_entity_id, -) +from homeassistant.helpers.entity import Entity, async_generate_entity_id from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.event import ( async_track_device_registry_updated_event, @@ -71,16 +63,24 @@ from .const import ( ATTR_DISCOVERY_HASH, ATTR_DISCOVERY_PAYLOAD, ATTR_DISCOVERY_TOPIC, + AVAILABILITY_ALL, + AVAILABILITY_ANY, CONF_AVAILABILITY, + CONF_AVAILABILITY_MODE, + CONF_AVAILABILITY_TEMPLATE, + CONF_AVAILABILITY_TOPIC, CONF_CONFIGURATION_URL, CONF_CONNECTIONS, - CONF_DEPRECATED_VIA_HUB, + CONF_ENABLED_BY_DEFAULT, CONF_ENCODING, CONF_HW_VERSION, CONF_IDENTIFIERS, + CONF_JSON_ATTRS_TEMPLATE, + CONF_JSON_ATTRS_TOPIC, CONF_MANUFACTURER, CONF_OBJECT_ID, - CONF_ORIGIN, + CONF_PAYLOAD_AVAILABLE, + CONF_PAYLOAD_NOT_AVAILABLE, CONF_QOS, CONF_SCHEMA, CONF_SERIAL_NUMBER, @@ -89,8 +89,6 @@ from .const import ( CONF_TOPIC, CONF_VIA_DEVICE, DEFAULT_ENCODING, - DEFAULT_PAYLOAD_AVAILABLE, - DEFAULT_PAYLOAD_NOT_AVAILABLE, DOMAIN, MQTT_CONNECTED, MQTT_DISCONNECTED, @@ -100,7 +98,6 @@ from .discovery import ( MQTT_DISCOVERY_DONE, MQTT_DISCOVERY_NEW, MQTT_DISCOVERY_UPDATED, - MQTT_ORIGIN_INFO_SCHEMA, MQTTDiscoveryPayload, clear_discovery_hash, set_discovery_hash, @@ -119,25 +116,10 @@ from .subscription import ( async_subscribe_topics, async_unsubscribe_topics, ) -from .util import mqtt_config_entry_enabled, valid_subscribe_topic +from .util import mqtt_config_entry_enabled _LOGGER = logging.getLogger(__name__) -AVAILABILITY_ALL = "all" -AVAILABILITY_ANY = "any" -AVAILABILITY_LATEST = "latest" - -AVAILABILITY_MODES = [AVAILABILITY_ALL, AVAILABILITY_ANY, AVAILABILITY_LATEST] - -CONF_AVAILABILITY_MODE = "availability_mode" -CONF_AVAILABILITY_TEMPLATE = "availability_template" -CONF_AVAILABILITY_TOPIC = "availability_topic" -CONF_ENABLED_BY_DEFAULT = "enabled_by_default" -CONF_PAYLOAD_AVAILABLE = "payload_available" -CONF_PAYLOAD_NOT_AVAILABLE = "payload_not_available" -CONF_JSON_ATTRS_TOPIC = "json_attributes_topic" -CONF_JSON_ATTRS_TEMPLATE = "json_attributes_template" - MQTT_ATTRIBUTES_BLOCKED = { "assumed_state", "available", @@ -157,96 +139,6 @@ MQTT_ATTRIBUTES_BLOCKED = { "unit_of_measurement", } -MQTT_AVAILABILITY_SINGLE_SCHEMA = vol.Schema( - { - vol.Exclusive(CONF_AVAILABILITY_TOPIC, "availability"): valid_subscribe_topic, - vol.Optional(CONF_AVAILABILITY_TEMPLATE): cv.template, - vol.Optional( - CONF_PAYLOAD_AVAILABLE, default=DEFAULT_PAYLOAD_AVAILABLE - ): cv.string, - vol.Optional( - CONF_PAYLOAD_NOT_AVAILABLE, default=DEFAULT_PAYLOAD_NOT_AVAILABLE - ): cv.string, - } -) - -MQTT_AVAILABILITY_LIST_SCHEMA = vol.Schema( - { - vol.Optional(CONF_AVAILABILITY_MODE, default=AVAILABILITY_LATEST): vol.All( - cv.string, vol.In(AVAILABILITY_MODES) - ), - vol.Exclusive(CONF_AVAILABILITY, "availability"): vol.All( - cv.ensure_list, - [ - { - vol.Required(CONF_TOPIC): valid_subscribe_topic, - vol.Optional( - CONF_PAYLOAD_AVAILABLE, default=DEFAULT_PAYLOAD_AVAILABLE - ): cv.string, - vol.Optional( - CONF_PAYLOAD_NOT_AVAILABLE, - default=DEFAULT_PAYLOAD_NOT_AVAILABLE, - ): cv.string, - vol.Optional(CONF_VALUE_TEMPLATE): cv.template, - } - ], - ), - } -) - -MQTT_AVAILABILITY_SCHEMA = MQTT_AVAILABILITY_SINGLE_SCHEMA.extend( - MQTT_AVAILABILITY_LIST_SCHEMA.schema -) - - -def validate_device_has_at_least_one_identifier(value: ConfigType) -> ConfigType: - """Validate that a device info entry has at least one identifying value.""" - if value.get(CONF_IDENTIFIERS) or value.get(CONF_CONNECTIONS): - return value - raise vol.Invalid( - "Device must have at least one identifying value in " - "'identifiers' and/or 'connections'" - ) - - -MQTT_ENTITY_DEVICE_INFO_SCHEMA = vol.All( - cv.deprecated(CONF_DEPRECATED_VIA_HUB, CONF_VIA_DEVICE), - vol.Schema( - { - vol.Optional(CONF_IDENTIFIERS, default=list): vol.All( - cv.ensure_list, [cv.string] - ), - vol.Optional(CONF_CONNECTIONS, default=list): vol.All( - cv.ensure_list, [vol.All(vol.Length(2), [cv.string])] - ), - vol.Optional(CONF_MANUFACTURER): cv.string, - vol.Optional(CONF_MODEL): cv.string, - vol.Optional(CONF_NAME): cv.string, - vol.Optional(CONF_HW_VERSION): cv.string, - vol.Optional(CONF_SERIAL_NUMBER): cv.string, - vol.Optional(CONF_SW_VERSION): cv.string, - vol.Optional(CONF_VIA_DEVICE): cv.string, - vol.Optional(CONF_SUGGESTED_AREA): cv.string, - vol.Optional(CONF_CONFIGURATION_URL): cv.configuration_url, - } - ), - validate_device_has_at_least_one_identifier, -) - -MQTT_ENTITY_COMMON_SCHEMA = MQTT_AVAILABILITY_SCHEMA.extend( - { - vol.Optional(CONF_DEVICE): MQTT_ENTITY_DEVICE_INFO_SCHEMA, - vol.Optional(CONF_ORIGIN): MQTT_ORIGIN_INFO_SCHEMA, - vol.Optional(CONF_ENABLED_BY_DEFAULT, default=True): cv.boolean, - vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA, - vol.Optional(CONF_ICON): cv.icon, - vol.Optional(CONF_JSON_ATTRS_TOPIC): valid_subscribe_topic, - vol.Optional(CONF_JSON_ATTRS_TEMPLATE): cv.template, - vol.Optional(CONF_OBJECT_ID): cv.string, - vol.Optional(CONF_UNIQUE_ID): cv.string, - } -) - class SetupEntity(Protocol): """Protocol type for async_setup_entities.""" diff --git a/homeassistant/components/mqtt/notify.py b/homeassistant/components/mqtt/notify.py index 07ab0050b45..57a213491a7 100644 --- a/homeassistant/components/mqtt/notify.py +++ b/homeassistant/components/mqtt/notify.py @@ -21,12 +21,9 @@ from .const import ( CONF_QOS, CONF_RETAIN, ) -from .mixins import ( - MQTT_ENTITY_COMMON_SCHEMA, - MqttEntity, - async_setup_entity_entry_helper, -) +from .mixins import MqttEntity, async_setup_entity_entry_helper from .models import MqttCommandTemplate +from .schemas import MQTT_ENTITY_COMMON_SCHEMA from .util import valid_publish_topic DEFAULT_NAME = "MQTT notify" diff --git a/homeassistant/components/mqtt/number.py b/homeassistant/components/mqtt/number.py index 88730d6e7a2..74d768ae598 100644 --- a/homeassistant/components/mqtt/number.py +++ b/homeassistant/components/mqtt/number.py @@ -43,7 +43,6 @@ from .const import ( ) from .debug_info import log_messages from .mixins import ( - MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entity_entry_helper, write_state_on_attr_change, @@ -55,6 +54,7 @@ from .models import ( ReceiveMessage, ReceivePayloadType, ) +from .schemas import MQTT_ENTITY_COMMON_SCHEMA _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/mqtt/scene.py b/homeassistant/components/mqtt/scene.py index a5ba2700e80..24b4415a4b2 100644 --- a/homeassistant/components/mqtt/scene.py +++ b/homeassistant/components/mqtt/scene.py @@ -17,11 +17,8 @@ from homeassistant.helpers.typing import ConfigType from .config import MQTT_BASE_SCHEMA from .const import CONF_COMMAND_TOPIC, CONF_ENCODING, CONF_QOS, CONF_RETAIN -from .mixins import ( - MQTT_ENTITY_COMMON_SCHEMA, - MqttEntity, - async_setup_entity_entry_helper, -) +from .mixins import MqttEntity, async_setup_entity_entry_helper +from .schemas import MQTT_ENTITY_COMMON_SCHEMA from .util import valid_publish_topic DEFAULT_NAME = "MQTT Scene" diff --git a/homeassistant/components/mqtt/schemas.py b/homeassistant/components/mqtt/schemas.py new file mode 100644 index 00000000000..bbc0194a1a5 --- /dev/null +++ b/homeassistant/components/mqtt/schemas.py @@ -0,0 +1,150 @@ +"""Shared schemas for MQTT discovery and YAML config items.""" + +from __future__ import annotations + +import voluptuous as vol + +from homeassistant.const import ( + CONF_DEVICE, + CONF_ENTITY_CATEGORY, + CONF_ICON, + CONF_MODEL, + CONF_NAME, + CONF_UNIQUE_ID, + CONF_VALUE_TEMPLATE, +) +from homeassistant.helpers import config_validation as cv +from homeassistant.helpers.entity import ENTITY_CATEGORIES_SCHEMA +from homeassistant.helpers.typing import ConfigType + +from .const import ( + AVAILABILITY_LATEST, + AVAILABILITY_MODES, + CONF_AVAILABILITY, + CONF_AVAILABILITY_MODE, + CONF_AVAILABILITY_TEMPLATE, + CONF_AVAILABILITY_TOPIC, + CONF_CONFIGURATION_URL, + CONF_CONNECTIONS, + CONF_DEPRECATED_VIA_HUB, + CONF_ENABLED_BY_DEFAULT, + CONF_HW_VERSION, + CONF_IDENTIFIERS, + CONF_JSON_ATTRS_TEMPLATE, + CONF_JSON_ATTRS_TOPIC, + CONF_MANUFACTURER, + CONF_OBJECT_ID, + CONF_ORIGIN, + CONF_PAYLOAD_AVAILABLE, + CONF_PAYLOAD_NOT_AVAILABLE, + CONF_SERIAL_NUMBER, + CONF_SUGGESTED_AREA, + CONF_SUPPORT_URL, + CONF_SW_VERSION, + CONF_TOPIC, + CONF_VIA_DEVICE, + DEFAULT_PAYLOAD_AVAILABLE, + DEFAULT_PAYLOAD_NOT_AVAILABLE, +) +from .util import valid_subscribe_topic + +MQTT_AVAILABILITY_SINGLE_SCHEMA = vol.Schema( + { + vol.Exclusive(CONF_AVAILABILITY_TOPIC, "availability"): valid_subscribe_topic, + vol.Optional(CONF_AVAILABILITY_TEMPLATE): cv.template, + vol.Optional( + CONF_PAYLOAD_AVAILABLE, default=DEFAULT_PAYLOAD_AVAILABLE + ): cv.string, + vol.Optional( + CONF_PAYLOAD_NOT_AVAILABLE, default=DEFAULT_PAYLOAD_NOT_AVAILABLE + ): cv.string, + } +) + +MQTT_AVAILABILITY_LIST_SCHEMA = vol.Schema( + { + vol.Optional(CONF_AVAILABILITY_MODE, default=AVAILABILITY_LATEST): vol.All( + cv.string, vol.In(AVAILABILITY_MODES) + ), + vol.Exclusive(CONF_AVAILABILITY, "availability"): vol.All( + cv.ensure_list, + [ + { + vol.Required(CONF_TOPIC): valid_subscribe_topic, + vol.Optional( + CONF_PAYLOAD_AVAILABLE, default=DEFAULT_PAYLOAD_AVAILABLE + ): cv.string, + vol.Optional( + CONF_PAYLOAD_NOT_AVAILABLE, + default=DEFAULT_PAYLOAD_NOT_AVAILABLE, + ): cv.string, + vol.Optional(CONF_VALUE_TEMPLATE): cv.template, + } + ], + ), + } +) + +MQTT_AVAILABILITY_SCHEMA = MQTT_AVAILABILITY_SINGLE_SCHEMA.extend( + MQTT_AVAILABILITY_LIST_SCHEMA.schema +) + + +def validate_device_has_at_least_one_identifier(value: ConfigType) -> ConfigType: + """Validate that a device info entry has at least one identifying value.""" + if value.get(CONF_IDENTIFIERS) or value.get(CONF_CONNECTIONS): + return value + raise vol.Invalid( + "Device must have at least one identifying value in " + "'identifiers' and/or 'connections'" + ) + + +MQTT_ENTITY_DEVICE_INFO_SCHEMA = vol.All( + cv.deprecated(CONF_DEPRECATED_VIA_HUB, CONF_VIA_DEVICE), + vol.Schema( + { + vol.Optional(CONF_IDENTIFIERS, default=list): vol.All( + cv.ensure_list, [cv.string] + ), + vol.Optional(CONF_CONNECTIONS, default=list): vol.All( + cv.ensure_list, [vol.All(vol.Length(2), [cv.string])] + ), + vol.Optional(CONF_MANUFACTURER): cv.string, + vol.Optional(CONF_MODEL): cv.string, + vol.Optional(CONF_NAME): cv.string, + vol.Optional(CONF_HW_VERSION): cv.string, + vol.Optional(CONF_SERIAL_NUMBER): cv.string, + vol.Optional(CONF_SW_VERSION): cv.string, + vol.Optional(CONF_VIA_DEVICE): cv.string, + vol.Optional(CONF_SUGGESTED_AREA): cv.string, + vol.Optional(CONF_CONFIGURATION_URL): cv.configuration_url, + } + ), + validate_device_has_at_least_one_identifier, +) + + +MQTT_ORIGIN_INFO_SCHEMA = vol.All( + vol.Schema( + { + vol.Required(CONF_NAME): cv.string, + vol.Optional(CONF_SW_VERSION): cv.string, + vol.Optional(CONF_SUPPORT_URL): cv.configuration_url, + } + ), +) + +MQTT_ENTITY_COMMON_SCHEMA = MQTT_AVAILABILITY_SCHEMA.extend( + { + vol.Optional(CONF_DEVICE): MQTT_ENTITY_DEVICE_INFO_SCHEMA, + vol.Optional(CONF_ORIGIN): MQTT_ORIGIN_INFO_SCHEMA, + vol.Optional(CONF_ENABLED_BY_DEFAULT, default=True): cv.boolean, + vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA, + vol.Optional(CONF_ICON): cv.icon, + vol.Optional(CONF_JSON_ATTRS_TOPIC): valid_subscribe_topic, + vol.Optional(CONF_JSON_ATTRS_TEMPLATE): cv.template, + vol.Optional(CONF_OBJECT_ID): cv.string, + vol.Optional(CONF_UNIQUE_ID): cv.string, + } +) diff --git a/homeassistant/components/mqtt/select.py b/homeassistant/components/mqtt/select.py index af09f5c0202..6619e7f6464 100644 --- a/homeassistant/components/mqtt/select.py +++ b/homeassistant/components/mqtt/select.py @@ -29,7 +29,6 @@ from .const import ( ) from .debug_info import log_messages from .mixins import ( - MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entity_entry_helper, write_state_on_attr_change, @@ -41,6 +40,7 @@ from .models import ( ReceiveMessage, ReceivePayloadType, ) +from .schemas import MQTT_ENTITY_COMMON_SCHEMA _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/mqtt/sensor.py b/homeassistant/components/mqtt/sensor.py index 5457011d122..744d7e0fdc9 100644 --- a/homeassistant/components/mqtt/sensor.py +++ b/homeassistant/components/mqtt/sensor.py @@ -42,7 +42,6 @@ from .config import MQTT_RO_SCHEMA from .const import CONF_ENCODING, CONF_QOS, CONF_STATE_TOPIC, PAYLOAD_NONE from .debug_info import log_messages from .mixins import ( - MQTT_ENTITY_COMMON_SCHEMA, MqttAvailability, MqttEntity, async_setup_entity_entry_helper, @@ -54,6 +53,7 @@ from .models import ( ReceiveMessage, ReceivePayloadType, ) +from .schemas import MQTT_ENTITY_COMMON_SCHEMA _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/mqtt/siren.py b/homeassistant/components/mqtt/siren.py index e360416db7c..9188e3d03ae 100644 --- a/homeassistant/components/mqtt/siren.py +++ b/homeassistant/components/mqtt/siren.py @@ -50,7 +50,6 @@ from .const import ( ) from .debug_info import log_messages from .mixins import ( - MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entity_entry_helper, write_state_on_attr_change, @@ -62,6 +61,7 @@ from .models import ( ReceiveMessage, ReceivePayloadType, ) +from .schemas import MQTT_ENTITY_COMMON_SCHEMA DEFAULT_NAME = "MQTT Siren" DEFAULT_PAYLOAD_ON = "ON" diff --git a/homeassistant/components/mqtt/switch.py b/homeassistant/components/mqtt/switch.py index 8be42a9ed19..5cbfefe0111 100644 --- a/homeassistant/components/mqtt/switch.py +++ b/homeassistant/components/mqtt/switch.py @@ -38,12 +38,12 @@ from .const import ( ) from .debug_info import log_messages from .mixins import ( - MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entity_entry_helper, write_state_on_attr_change, ) from .models import MqttValueTemplate, ReceiveMessage +from .schemas import MQTT_ENTITY_COMMON_SCHEMA DEFAULT_NAME = "MQTT Switch" DEFAULT_PAYLOAD_ON = "ON" diff --git a/homeassistant/components/mqtt/tag.py b/homeassistant/components/mqtt/tag.py index f593e6d428e..81db9295ea2 100644 --- a/homeassistant/components/mqtt/tag.py +++ b/homeassistant/components/mqtt/tag.py @@ -20,7 +20,6 @@ from .config import MQTT_BASE_SCHEMA from .const import ATTR_DISCOVERY_HASH, CONF_QOS, CONF_TOPIC from .discovery import MQTTDiscoveryPayload from .mixins import ( - MQTT_ENTITY_DEVICE_INFO_SCHEMA, MqttDiscoveryDeviceUpdate, async_handle_schema_error, async_setup_non_entity_entry_helper, @@ -34,6 +33,7 @@ from .models import ( ReceiveMessage, ReceivePayloadType, ) +from .schemas import MQTT_ENTITY_DEVICE_INFO_SCHEMA from .subscription import EntitySubscription from .util import valid_subscribe_topic diff --git a/homeassistant/components/mqtt/text.py b/homeassistant/components/mqtt/text.py index e5786dbe94d..8197eadd9be 100644 --- a/homeassistant/components/mqtt/text.py +++ b/homeassistant/components/mqtt/text.py @@ -36,7 +36,6 @@ from .const import ( ) from .debug_info import log_messages from .mixins import ( - MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entity_entry_helper, write_state_on_attr_change, @@ -49,6 +48,7 @@ from .models import ( ReceiveMessage, ReceivePayloadType, ) +from .schemas import MQTT_ENTITY_COMMON_SCHEMA _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/mqtt/update.py b/homeassistant/components/mqtt/update.py index 0171e8eee2d..25cc60155a0 100644 --- a/homeassistant/components/mqtt/update.py +++ b/homeassistant/components/mqtt/update.py @@ -34,12 +34,12 @@ from .const import ( ) from .debug_info import log_messages from .mixins import ( - MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entity_entry_helper, write_state_on_attr_change, ) from .models import MessageCallbackType, MqttValueTemplate, ReceiveMessage +from .schemas import MQTT_ENTITY_COMMON_SCHEMA from .util import valid_publish_topic, valid_subscribe_topic _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/mqtt/vacuum.py b/homeassistant/components/mqtt/vacuum.py index 96c0871e27b..57265008025 100644 --- a/homeassistant/components/mqtt/vacuum.py +++ b/homeassistant/components/mqtt/vacuum.py @@ -51,12 +51,12 @@ from .const import ( ) from .debug_info import log_messages from .mixins import ( - MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entity_entry_helper, write_state_on_attr_change, ) from .models import ReceiveMessage +from .schemas import MQTT_ENTITY_COMMON_SCHEMA from .util import valid_publish_topic LEGACY = "legacy" diff --git a/homeassistant/components/mqtt/valve.py b/homeassistant/components/mqtt/valve.py index 241d6748280..a491b1edfda 100644 --- a/homeassistant/components/mqtt/valve.py +++ b/homeassistant/components/mqtt/valve.py @@ -62,12 +62,12 @@ from .const import ( ) from .debug_info import log_messages from .mixins import ( - MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entity_entry_helper, write_state_on_attr_change, ) from .models import MqttCommandTemplate, MqttValueTemplate, ReceiveMessage +from .schemas import MQTT_ENTITY_COMMON_SCHEMA from .util import valid_publish_topic, valid_subscribe_topic _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/mqtt/water_heater.py b/homeassistant/components/mqtt/water_heater.py index 09db5fc33e7..ba1002038bb 100644 --- a/homeassistant/components/mqtt/water_heater.py +++ b/homeassistant/components/mqtt/water_heater.py @@ -65,12 +65,9 @@ from .const import ( DEFAULT_OPTIMISTIC, ) from .debug_info import log_messages -from .mixins import ( - MQTT_ENTITY_COMMON_SCHEMA, - async_setup_entity_entry_helper, - write_state_on_attr_change, -) +from .mixins import async_setup_entity_entry_helper, write_state_on_attr_change from .models import MqttCommandTemplate, MqttValueTemplate, ReceiveMessage +from .schemas import MQTT_ENTITY_COMMON_SCHEMA from .util import valid_publish_topic, valid_subscribe_topic _LOGGER = logging.getLogger(__name__) diff --git a/tests/components/mqtt/test_init.py b/tests/components/mqtt/test_init.py index d2b7f7021f4..b71a105b7bc 100644 --- a/tests/components/mqtt/test_init.py +++ b/tests/components/mqtt/test_init.py @@ -24,13 +24,13 @@ from homeassistant.components.mqtt.client import ( RECONNECT_INTERVAL_SECONDS, EnsureJobAfterCooldown, ) -from homeassistant.components.mqtt.mixins import MQTT_ENTITY_DEVICE_INFO_SCHEMA from homeassistant.components.mqtt.models import ( MessageCallbackType, MqttCommandTemplateException, MqttValueTemplateException, ReceiveMessage, ) +from homeassistant.components.mqtt.schemas import MQTT_ENTITY_DEVICE_INFO_SCHEMA from homeassistant.components.sensor import SensorDeviceClass from homeassistant.config_entries import ConfigEntryDisabler, ConfigEntryState from homeassistant.const import (