-
-
Notifications
You must be signed in to change notification settings - Fork 31.7k
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
Reconfigure MQTT binary_sensor component if discovery info is changed #18169
Reconfigure MQTT binary_sensor component if discovery info is changed #18169
Conversation
@@ -864,9 +864,14 @@ def available(self) -> bool: | |||
class MqttDiscoveryUpdate(Entity): | |||
"""Mixin used to handle updated discovery message.""" | |||
|
|||
def __init__(self, discovery_hash) -> None: | |||
def __init__(self, discovery_hash, discovery_payload=None, | |||
async_discover=None) -> None: |
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.
I don't like this that much. Passing this async_discover
callback will become quite a mess once we start implementing MQTT config entry unloading. For now it's probably ok though
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.
Fixed (I think?)
@OttoWinter Thanks a lot for the comments! Some questions:
|
aa53d67
to
ac19a0b
Compare
b357dce
to
61541a0
Compare
61541a0
to
0542b2d
Compare
self._unique_id = config.get(CONF_UNIQUE_ID) | ||
|
||
# TODO: Handle changed device? | ||
# config.get(CONF_DEVICE), |
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.
@OttoWinter What do you suggest to do if device info is changed, just update the MqttEntityDeviceInfo?
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.
Why not the same as availability_discovery_update
, just called device_info_discovery_update
- this method would set the internal self._device_info
object to the latest values.
(It might be the case though that the device_info
is only read when the device is initially added to hass, then I guess we ignore the update to this attribute, as it's probably not used too often)
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.
It might be the case though that the device_info is only read when the device is initially added to hass
Yes, this seems to be the cased based on some quick testing.
Either just ignore this case as you suggest, or delete + re-add the component.
self._unique_id = config.get(CONF_UNIQUE_ID) | ||
|
||
# TODO: Handle changed device? | ||
# config.get(CONF_DEVICE), |
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.
Why not the same as availability_discovery_update
, just called device_info_discovery_update
- this method would set the internal self._device_info
object to the latest values.
(It might be the case though that the device_info
is only read when the device is initially added to hass, then I guess we ignore the update to this attribute, as it's probably not used too often)
@bind_hass | ||
async def async_subscribe_topics(hass: HomeAssistantType, sub_state: dict, | ||
new_topics: dict, | ||
msg_callback: MessageCallbackType, |
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.
We should not have a generic msg callback for all topics. For example, this won't work for the MQTT light, as it has a different callback for brightness and state.
I would expect new_topics
to be called topics
(as there might nothing be new about it) and be defined like this:
{
'/home/light/kitchen/state': {
'qos': 2,
'encoding': 'utf-8',
'msg_callback': state_received
}
}
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.
Fixed.
State is kept in sub_state. | ||
""" | ||
if sub_state is None: | ||
sub_state = {'topics': {}} |
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.
No reason to wrap it in a dictionary. It's an opaque object to the outside world, inside this method we always know the implementation.
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.
OK, fixed.
for key, topic in new_topics.items(): | ||
if key not in old_topics and topic is not None: | ||
unsub = await mqtt.async_subscribe(hass, topic, msg_callback, qos) | ||
old_topics[key] = (topic, unsub) |
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.
it's kinda confusing that we have an object called old_topics
that we're writing to. That's also why we need to wrap the for-loop with a list
around values.
We should rename old_topic
to cur_topics
and create a new state
dictionary. Then just while iterating over the new_topics
param, we pop keys from cur_topics
. When done with the for-loop, anything that's left in cur_topics
can be unsubscribed.
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.
Ok, rewritten as you suggest.
@balloob Thanks a lot for the review! subscription.py rewritten as you suggest, and tests added. |
@balloob Do you consider this ready for merge now, or are additional changes needed? |
Looks good! Delayed because I was taking a week off GitHub :) |
Description:
Reconfigure component if discovery info is changed.
This is bullet 2 in home-assistant/architecture#70
PRs for other platforms will be opened separately.
Checklist:
tox
.