-
-
Notifications
You must be signed in to change notification settings - Fork 38.2k
Implement base for MQTT device registry integration #16943
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
bba7a24
0c61e18
74f7df1
1489a92
2f717ed
1644b29
2ad6291
c1fea49
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,10 +21,11 @@ | |
| from homeassistant import config_entries | ||
| from homeassistant.const import ( | ||
| CONF_PASSWORD, CONF_PAYLOAD, CONF_PORT, CONF_PROTOCOL, CONF_USERNAME, | ||
| CONF_VALUE_TEMPLATE, EVENT_HOMEASSISTANT_STOP) | ||
| CONF_VALUE_TEMPLATE, EVENT_HOMEASSISTANT_STOP, CONF_TYPE, CONF_NAME, | ||
| CONF_DEVICE) | ||
| from homeassistant.core import Event, ServiceCall, callback | ||
| from homeassistant.exceptions import HomeAssistantError | ||
| from homeassistant.helpers import config_validation as cv | ||
| from homeassistant.helpers import config_validation as cv, device_registry | ||
| from homeassistant.helpers import template | ||
| from homeassistant.helpers.entity import Entity | ||
| from homeassistant.helpers.typing import ( | ||
|
|
@@ -73,6 +74,13 @@ | |
| CONF_QOS = 'qos' | ||
| CONF_RETAIN = 'retain' | ||
|
|
||
| CONF_IDENTIFIERS = 'identifiers' | ||
| CONF_CONNECTIONS = 'connections' | ||
| CONF_IDENTIFIER = 'identifier' | ||
| CONF_MANUFACTURER = 'manufacturer' | ||
| CONF_MODEL = 'model' | ||
| CONF_SW_VERSION = 'sw_version' | ||
|
|
||
| PROTOCOL_31 = '3.1' | ||
| PROTOCOL_311 = '3.1.1' | ||
|
|
||
|
|
@@ -144,6 +152,15 @@ def valid_publish_topic(value: Any) -> str: | |
| return value | ||
|
|
||
|
|
||
| def validate_device_has_at_least_one_identifier(value: ConfigType) -> \ | ||
| ConfigType: | ||
| """Validate that a device info entry has at least one identifying value.""" | ||
| if not value.get(CONF_IDENTIFIERS) and not value.get(CONF_CONNECTIONS): | ||
| raise vol.Invalid("Device must has at least one identifying value in" | ||
| "'identifiers' and/or 'connections'") | ||
| return value | ||
|
|
||
|
|
||
| _VALID_QOS_SCHEMA = vol.All(vol.Coerce(int), vol.In([0, 1, 2])) | ||
|
|
||
| CLIENT_KEY_AUTH_MSG = 'client_key and client_cert must both be present in ' \ | ||
|
|
@@ -198,6 +215,20 @@ def valid_publish_topic(value: Any) -> str: | |
| default=DEFAULT_PAYLOAD_NOT_AVAILABLE): cv.string, | ||
| }) | ||
|
|
||
| MQTT_ENTITY_DEVICE_INFO_SCHEMA = vol.All(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.Schema({ | ||
| vol.Required(CONF_TYPE): vol.Any(*device_registry.CONNECTION_KEYS), | ||
| vol.Required(CONF_IDENTIFIER): cv.string, | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't really like the name of this option (
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this a dict to begin with?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well primarily to make it more consistent with the device registry naming. One option would be: {
...
"device": {
"connections": {
"mac": "F7:19:18:29:93:1A",
"other": "connection_id"
}
}
}but that would for example not support devices with multiple MAC addresses (probably doesn't come up too often, but I think it's good to support it from the start to prevent breaking changes). The other option would be: {
...
"device": {
"connections": [
{"mac": "F7:19:18:29:93:1A"},
{"mac": "E8:2A:29:3A:A4:2B"}
]
}
}or: {
...
"device": {
"connections": [
["mac", "F7:19:18:29:93:1A"],
["mac", "E8:2A:29:3A:A4:2B"]
]
}
}
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like the last one. That is also how we store it internally.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, updated to that. |
||
| })]), | ||
| vol.Optional(CONF_MANUFACTURER): cv.string, | ||
| vol.Optional(CONF_MODEL): cv.string, | ||
| vol.Optional(CONF_NAME): cv.string, | ||
| vol.Optional(CONF_SW_VERSION): cv.string, | ||
| }), validate_device_has_at_least_one_identifier) | ||
|
MartinHjelmare marked this conversation as resolved.
|
||
|
|
||
| MQTT_BASE_PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend(SCHEMA_BASE) | ||
|
|
||
| # Sensor type platforms subscribe to MQTT events | ||
|
|
@@ -868,3 +899,32 @@ def discovery_callback(payload): | |
| self.hass, | ||
| MQTT_DISCOVERY_UPDATED.format(self._discovery_hash), | ||
| discovery_callback) | ||
|
|
||
|
|
||
| class MqttEntityDeviceInfo(Entity): | ||
| """Mixin used for mqtt platforms that support the device registry.""" | ||
|
|
||
| def __init__(self, device_config: Optional[ConfigType]) -> None: | ||
| """Initialize the device mixin.""" | ||
| self._device_config = device_config | ||
|
|
||
| @property | ||
| def device_info(self): | ||
| """Return a device description for device registry.""" | ||
| if not self._device_config: | ||
| return None | ||
|
|
||
| return { | ||
| 'identifiers': { | ||
| (DOMAIN, id_) | ||
|
OttoWinter marked this conversation as resolved.
|
||
| for id_ in self._device_config[CONF_IDENTIFIERS] | ||
| }, | ||
| 'connections': { | ||
| (connection[CONF_TYPE], connection[CONF_IDENTIFIER]) | ||
| for connection in self._device_config[CONF_CONNECTIONS] | ||
| }, | ||
| 'manufacturer': self._device_config.get(CONF_MANUFACTURER), | ||
| 'model': self._device_config.get(CONF_MODEL), | ||
| 'name': self._device_config.get(CONF_NAME), | ||
| 'sw_version': self._device_config.get(CONF_SW_VERSION), | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'homeassistant.helpers.device_registry' imported but unused