mirror of
https://github.com/home-assistant/core.git
synced 2025-06-03 12:47:06 +00:00
Add MQTT binary_sensor as entity platform on MQTT subentries (#144142)
Add MQTT binary_sensor subentry support
This commit is contained in:
parent
60846434d3
commit
46df29b390
@ -35,7 +35,7 @@ from homeassistant.util import dt as dt_util
|
||||
|
||||
from . import subscription
|
||||
from .config import MQTT_RO_SCHEMA
|
||||
from .const import CONF_STATE_TOPIC, PAYLOAD_NONE
|
||||
from .const import CONF_OFF_DELAY, CONF_STATE_TOPIC, PAYLOAD_NONE
|
||||
from .entity import MqttAvailabilityMixin, MqttEntity, async_setup_entity_entry_helper
|
||||
from .models import MqttValueTemplate, ReceiveMessage
|
||||
from .schemas import MQTT_ENTITY_COMMON_SCHEMA
|
||||
@ -45,7 +45,6 @@ _LOGGER = logging.getLogger(__name__)
|
||||
PARALLEL_UPDATES = 0
|
||||
|
||||
DEFAULT_NAME = "MQTT Binary sensor"
|
||||
CONF_OFF_DELAY = "off_delay"
|
||||
DEFAULT_PAYLOAD_OFF = "OFF"
|
||||
DEFAULT_PAYLOAD_ON = "ON"
|
||||
DEFAULT_FORCE_UPDATE = False
|
||||
|
@ -25,6 +25,7 @@ from cryptography.hazmat.primitives.serialization import (
|
||||
from cryptography.x509 import load_der_x509_certificate, load_pem_x509_certificate
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.binary_sensor import BinarySensorDeviceClass
|
||||
from homeassistant.components.file_upload import process_uploaded_file
|
||||
from homeassistant.components.hassio import AddonError, AddonManager, AddonState
|
||||
from homeassistant.components.light import (
|
||||
@ -157,6 +158,7 @@ from .const import (
|
||||
CONF_LAST_RESET_VALUE_TEMPLATE,
|
||||
CONF_MAX_KELVIN,
|
||||
CONF_MIN_KELVIN,
|
||||
CONF_OFF_DELAY,
|
||||
CONF_ON_COMMAND_TYPE,
|
||||
CONF_OPTIONS,
|
||||
CONF_PAYLOAD_AVAILABLE,
|
||||
@ -305,7 +307,13 @@ KEY_UPLOAD_SELECTOR = FileSelector(
|
||||
)
|
||||
|
||||
# Subentry selectors
|
||||
SUBENTRY_PLATFORMS = [Platform.LIGHT, Platform.NOTIFY, Platform.SENSOR, Platform.SWITCH]
|
||||
SUBENTRY_PLATFORMS = [
|
||||
Platform.BINARY_SENSOR,
|
||||
Platform.LIGHT,
|
||||
Platform.NOTIFY,
|
||||
Platform.SENSOR,
|
||||
Platform.SWITCH,
|
||||
]
|
||||
SUBENTRY_PLATFORM_SELECTOR = SelectSelector(
|
||||
SelectSelectorConfig(
|
||||
options=[platform.value for platform in SUBENTRY_PLATFORMS],
|
||||
@ -337,6 +345,14 @@ SENSOR_DEVICE_CLASS_SELECTOR = SelectSelector(
|
||||
sort=True,
|
||||
)
|
||||
)
|
||||
BINARY_SENSOR_DEVICE_CLASS_SELECTOR = SelectSelector(
|
||||
SelectSelectorConfig(
|
||||
options=[device_class.value for device_class in BinarySensorDeviceClass],
|
||||
mode=SelectSelectorMode.DROPDOWN,
|
||||
translation_key="device_class_binary_sensor",
|
||||
sort=True,
|
||||
)
|
||||
)
|
||||
SENSOR_STATE_CLASS_SELECTOR = SelectSelector(
|
||||
SelectSelectorConfig(
|
||||
options=[device_class.value for device_class in SensorStateClass],
|
||||
@ -354,7 +370,7 @@ OPTIONS_SELECTOR = SelectSelector(
|
||||
SUGGESTED_DISPLAY_PRECISION_SELECTOR = NumberSelector(
|
||||
NumberSelectorConfig(mode=NumberSelectorMode.BOX, min=0, max=9)
|
||||
)
|
||||
EXPIRE_AFTER_SELECTOR = NumberSelector(
|
||||
TIMEOUT_SELECTOR = NumberSelector(
|
||||
NumberSelectorConfig(mode=NumberSelectorMode.BOX, min=0)
|
||||
)
|
||||
|
||||
@ -523,6 +539,13 @@ COMMON_ENTITY_FIELDS = {
|
||||
}
|
||||
|
||||
PLATFORM_ENTITY_FIELDS = {
|
||||
Platform.BINARY_SENSOR.value: {
|
||||
CONF_DEVICE_CLASS: PlatformField(
|
||||
selector=BINARY_SENSOR_DEVICE_CLASS_SELECTOR,
|
||||
required=False,
|
||||
validator=str,
|
||||
),
|
||||
},
|
||||
Platform.NOTIFY.value: {},
|
||||
Platform.SENSOR.value: {
|
||||
CONF_DEVICE_CLASS: PlatformField(
|
||||
@ -573,6 +596,44 @@ PLATFORM_ENTITY_FIELDS = {
|
||||
},
|
||||
}
|
||||
PLATFORM_MQTT_FIELDS = {
|
||||
Platform.BINARY_SENSOR.value: {
|
||||
CONF_STATE_TOPIC: PlatformField(
|
||||
selector=TEXT_SELECTOR,
|
||||
required=True,
|
||||
validator=valid_subscribe_topic,
|
||||
error="invalid_subscribe_topic",
|
||||
),
|
||||
CONF_VALUE_TEMPLATE: PlatformField(
|
||||
selector=TEMPLATE_SELECTOR,
|
||||
required=False,
|
||||
validator=cv.template,
|
||||
error="invalid_template",
|
||||
),
|
||||
CONF_PAYLOAD_OFF: PlatformField(
|
||||
selector=TEXT_SELECTOR,
|
||||
required=False,
|
||||
validator=str,
|
||||
default=DEFAULT_PAYLOAD_OFF,
|
||||
),
|
||||
CONF_PAYLOAD_ON: PlatformField(
|
||||
selector=TEXT_SELECTOR,
|
||||
required=False,
|
||||
validator=str,
|
||||
default=DEFAULT_PAYLOAD_ON,
|
||||
),
|
||||
CONF_EXPIRE_AFTER: PlatformField(
|
||||
selector=TIMEOUT_SELECTOR,
|
||||
required=False,
|
||||
validator=cv.positive_int,
|
||||
section="advanced_settings",
|
||||
),
|
||||
CONF_OFF_DELAY: PlatformField(
|
||||
selector=TIMEOUT_SELECTOR,
|
||||
required=False,
|
||||
validator=cv.positive_int,
|
||||
section="advanced_settings",
|
||||
),
|
||||
},
|
||||
Platform.NOTIFY.value: {
|
||||
CONF_COMMAND_TOPIC: PlatformField(
|
||||
selector=TEXT_SELECTOR,
|
||||
@ -611,7 +672,7 @@ PLATFORM_MQTT_FIELDS = {
|
||||
conditions=({CONF_STATE_CLASS: "total"},),
|
||||
),
|
||||
CONF_EXPIRE_AFTER: PlatformField(
|
||||
selector=EXPIRE_AFTER_SELECTOR,
|
||||
selector=TIMEOUT_SELECTOR,
|
||||
required=False,
|
||||
validator=cv.positive_int,
|
||||
section="advanced_settings",
|
||||
@ -1144,6 +1205,7 @@ ENTITY_CONFIG_VALIDATOR: dict[
|
||||
str,
|
||||
Callable[[dict[str, Any]], dict[str, str]] | None,
|
||||
] = {
|
||||
Platform.BINARY_SENSOR.value: None,
|
||||
Platform.LIGHT.value: validate_light_platform_config,
|
||||
Platform.NOTIFY.value: None,
|
||||
Platform.SENSOR.value: validate_sensor_platform_config,
|
||||
|
@ -105,6 +105,7 @@ CONF_MODE_COMMAND_TOPIC = "mode_command_topic"
|
||||
CONF_MODE_LIST = "modes"
|
||||
CONF_MODE_STATE_TEMPLATE = "mode_state_template"
|
||||
CONF_MODE_STATE_TOPIC = "mode_state_topic"
|
||||
CONF_OFF_DELAY = "off_delay"
|
||||
CONF_ON_COMMAND_TYPE = "on_command_type"
|
||||
CONF_PAYLOAD_CLOSE = "payload_close"
|
||||
CONF_PAYLOAD_OPEN = "payload_open"
|
||||
|
@ -300,6 +300,7 @@
|
||||
"flash_time_short": "Flash time short",
|
||||
"max_kelvin": "Max Kelvin",
|
||||
"min_kelvin": "Min Kelvin",
|
||||
"off_delay": "OFF delay",
|
||||
"transition": "Transition support"
|
||||
},
|
||||
"data_description": {
|
||||
@ -309,6 +310,7 @@
|
||||
"flash_time_short": "The duration, in seconds, of a \"short\" flash.",
|
||||
"max_kelvin": "The maximum color temperature in Kelvin.",
|
||||
"min_kelvin": "The minimum color temperature in Kelvin.",
|
||||
"off_delay": "For sensors that only send \"on\" state updates (like PIRs), this variable sets a delay in seconds after which the sensor’s state will be updated back to \"off\".",
|
||||
"transition": "Enable the transition feature for this light"
|
||||
}
|
||||
},
|
||||
@ -600,6 +602,38 @@
|
||||
}
|
||||
},
|
||||
"selector": {
|
||||
"device_class_binary_sensor": {
|
||||
"options": {
|
||||
"battery": "[%key:component::binary_sensor::entity_component::battery::name%]",
|
||||
"battery_charging": "[%key:component::binary_sensor::entity_component::battery_charging::name%]",
|
||||
"carbon_monoxide": "[%key:component::binary_sensor::entity_component::carbon_monoxide::name%]",
|
||||
"cold": "[%key:component::binary_sensor::entity_component::cold::name%]",
|
||||
"connectivity": "[%key:component::binary_sensor::entity_component::connectivity::name%]",
|
||||
"door": "[%key:component::binary_sensor::entity_component::door::name%]",
|
||||
"garage_door": "[%key:component::binary_sensor::entity_component::garage_door::name%]",
|
||||
"gas": "[%key:component::binary_sensor::entity_component::gas::name%]",
|
||||
"heat": "[%key:component::binary_sensor::entity_component::heat::name%]",
|
||||
"light": "[%key:component::binary_sensor::entity_component::light::name%]",
|
||||
"lock": "[%key:component::binary_sensor::entity_component::lock::name%]",
|
||||
"moisture": "[%key:component::binary_sensor::entity_component::moisture::name%]",
|
||||
"motion": "[%key:component::binary_sensor::entity_component::motion::name%]",
|
||||
"moving": "[%key:component::binary_sensor::entity_component::moving::name%]",
|
||||
"occupancy": "[%key:component::binary_sensor::entity_component::occupancy::name%]",
|
||||
"opening": "[%key:component::binary_sensor::entity_component::opening::name%]",
|
||||
"plug": "[%key:component::binary_sensor::entity_component::plug::name%]",
|
||||
"power": "[%key:component::binary_sensor::entity_component::power::name%]",
|
||||
"presence": "[%key:component::binary_sensor::entity_component::presence::name%]",
|
||||
"problem": "[%key:component::binary_sensor::entity_component::problem::name%]",
|
||||
"running": "[%key:component::binary_sensor::entity_component::running::name%]",
|
||||
"safety": "[%key:component::binary_sensor::entity_component::safety::name%]",
|
||||
"smoke": "[%key:component::binary_sensor::entity_component::smoke::name%]",
|
||||
"sound": "[%key:component::binary_sensor::entity_component::sound::name%]",
|
||||
"tamper": "[%key:component::binary_sensor::entity_component::tamper::name%]",
|
||||
"update": "[%key:component::binary_sensor::entity_component::update::name%]",
|
||||
"vibration": "[%key:component::binary_sensor::entity_component::vibration::name%]",
|
||||
"window": "[%key:component::binary_sensor::entity_component::window::name%]"
|
||||
}
|
||||
},
|
||||
"device_class_sensor": {
|
||||
"options": {
|
||||
"apparent_power": "[%key:component::sensor::entity_component::apparent_power::name%]",
|
||||
@ -682,6 +716,7 @@
|
||||
},
|
||||
"platform": {
|
||||
"options": {
|
||||
"binary_sensor": "[%key:component::binary_sensor::title%]",
|
||||
"light": "[%key:component::light::title%]",
|
||||
"notify": "[%key:component::notify::title%]",
|
||||
"sensor": "[%key:component::sensor::title%]",
|
||||
|
@ -66,6 +66,20 @@ DEFAULT_CONFIG_DEVICE_INFO_MAC = {
|
||||
"configuration_url": "http://example.com",
|
||||
}
|
||||
|
||||
MOCK_SUBENTRY_BINARY_SENSOR_COMPONENT = {
|
||||
"5b06357ef8654e8d9c54cee5bb0e939b": {
|
||||
"platform": "binary_sensor",
|
||||
"name": "Hatch",
|
||||
"device_class": "door",
|
||||
"state_topic": "test-topic",
|
||||
"payload_on": "ON",
|
||||
"payload_off": "OFF",
|
||||
"expire_after": 1200,
|
||||
"off_delay": 5,
|
||||
"value_template": "{{ value_json.value }}",
|
||||
"entity_picture": "https://example.com/5b06357ef8654e8d9c54cee5bb0e939b",
|
||||
},
|
||||
}
|
||||
MOCK_SUBENTRY_NOTIFY_COMPONENT1 = {
|
||||
"363a7ecad6be4a19b939a016ea93e994": {
|
||||
"platform": "notify",
|
||||
@ -187,6 +201,10 @@ MOCK_NOTIFY_SUBENTRY_DATA_MULTI = {
|
||||
"components": MOCK_SUBENTRY_NOTIFY_COMPONENT1 | MOCK_SUBENTRY_NOTIFY_COMPONENT2,
|
||||
} | MOCK_SUBENTRY_AVAILABILITY_DATA
|
||||
|
||||
MOCK_BINARY_SENSOR_SUBENTRY_DATA_SINGLE = {
|
||||
"device": MOCK_SUBENTRY_DEVICE_DATA | {"mqtt_settings": {"qos": 2}},
|
||||
"components": MOCK_SUBENTRY_BINARY_SENSOR_COMPONENT,
|
||||
}
|
||||
MOCK_NOTIFY_SUBENTRY_DATA_SINGLE = {
|
||||
"device": MOCK_SUBENTRY_DEVICE_DATA | {"mqtt_settings": {"qos": 1}},
|
||||
"components": MOCK_SUBENTRY_NOTIFY_COMPONENT1,
|
||||
|
@ -33,6 +33,7 @@ from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
from homeassistant.helpers.service_info.hassio import HassioServiceInfo
|
||||
|
||||
from .common import (
|
||||
MOCK_BINARY_SENSOR_SUBENTRY_DATA_SINGLE,
|
||||
MOCK_LIGHT_BASIC_KELVIN_SUBENTRY_DATA_SINGLE,
|
||||
MOCK_NOTIFY_SUBENTRY_DATA_MULTI,
|
||||
MOCK_NOTIFY_SUBENTRY_DATA_NO_NAME,
|
||||
@ -2657,6 +2658,25 @@ async def test_migrate_of_incompatible_config_entry(
|
||||
"entity_name",
|
||||
),
|
||||
[
|
||||
(
|
||||
MOCK_BINARY_SENSOR_SUBENTRY_DATA_SINGLE,
|
||||
{"name": "Milk notifier", "mqtt_settings": {"qos": 2}},
|
||||
{"name": "Hatch"},
|
||||
{"device_class": "door"},
|
||||
(),
|
||||
{
|
||||
"state_topic": "test-topic",
|
||||
"value_template": "{{ value_json.value }}",
|
||||
"advanced_settings": {"expire_after": 1200, "off_delay": 5},
|
||||
},
|
||||
(
|
||||
(
|
||||
{"state_topic": "test-topic#invalid"},
|
||||
{"state_topic": "invalid_subscribe_topic"},
|
||||
),
|
||||
),
|
||||
"Milk notifier Hatch",
|
||||
),
|
||||
(
|
||||
MOCK_NOTIFY_SUBENTRY_DATA_SINGLE,
|
||||
{"name": "Milk notifier", "mqtt_settings": {"qos": 1}},
|
||||
@ -2832,6 +2852,7 @@ async def test_migrate_of_incompatible_config_entry(
|
||||
),
|
||||
],
|
||||
ids=[
|
||||
"binary_sensor",
|
||||
"notify_with_entity_name",
|
||||
"notify_no_entity_name",
|
||||
"sensor_options",
|
||||
|
Loading…
x
Reference in New Issue
Block a user