-
-
Notifications
You must be signed in to change notification settings - Fork 31.8k
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
Support abbreviations in discovery topic #16635
Support abbreviations in discovery topic #16635
Conversation
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.
A change like this would also require a test.
@fabaff Thanks for review! |
|
||
def expand(matchobj): | ||
"""Helper to expand a possibly abbreviated word.""" | ||
abbreviation = matchobj.group(0) |
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.
unexpected indentation
pattern = r'(?:(?<=^)|(?<=_))[^\W_]+(?=_|$)' | ||
|
||
def expand(matchobj): | ||
"""Helper to expand a possibly abbreviated word.""" |
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.
expected an indented block
IndentationError: expected an indented block
8e1bb40
to
c287260
Compare
c287260
to
1d39883
Compare
Btw, I didn't add words relevant for Alarm control panel, HVAC and Lock (home-assistant/home-assistant.io#6295). I'll add those and and push a new commit. |
We should wait with this PR until we finalized our discussion in the architecture repo? |
@balloob Definitely, I added WIP tag |
|
||
from tests.common import async_fire_mqtt_message, mock_coro | ||
|
||
from tests.common import ( |
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.
'tests.common.mock_mqtt_component' imported but unused
'tests.common.fire_mqtt_message' imported but unused
'tests.common.get_test_home_assistant' imported but unused
@@ -1,12 +1,15 @@ | |||
"""The tests for the MQTT discovery.""" | |||
import asyncio | |||
import unittest |
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.
'unittest' imported but unused
b757c07
to
eed9472
Compare
@fabaff Please have a look at the updated version:
|
if TOPIC_PREFIX in payload: | ||
prefix = payload[TOPIC_PREFIX] | ||
for key in payload.keys(): | ||
payload[key] = payload[key].replace(TOPIC_PREFIX, prefix) |
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 shouldn't do the replace like this, as it would also replace something like hello/~paulus
. Instead, do this:
for key, value in payload.items():
if key[0] == TOPIC_PREFIX:
payload[key] = "{}{}".format(TOPIC_PREFIX, value[1:])
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, and that limits the topic prefix to the very beginning, maybe that's a reasonable limitation?
Perhaps it also makes sense to only do the replacement if the configuration variable ends with _topic, so something like:
for key, value in payload.items():
if value[0] == TOPIC_PREFIX and key.endswith('_topic'):
payload[key] = "{}{}".format(TOPIC_PREFIX, value[1:])
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 in latest commit.
@@ -62,6 +142,31 @@ | |||
return | |||
|
|||
payload = dict(payload) | |||
|
|||
for key in list(payload.keys()): |
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.
Wait, how does this work, I was under the impression that we had a fixed list of abbreviation -> full key, which would not require a regex. If we can, let's avoid regex.
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 a (long) fixed list of abbreviated words, the purpose of the regex was to split the configuration variable name in words and attempt to expand word by word.
Regex replaced with string.split()
if TOPIC_PREFIX in payload: | ||
prefix = payload[TOPIC_PREFIX] | ||
for key, value in payload.items(): | ||
if value.startswith(TOPIC_PREFIX) and key.endswith('_topic'): |
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.
value[0]
will be faster.
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.
for key, value in payload.items(): | ||
if value.startswith(TOPIC_PREFIX) and key.endswith('_topic'): | ||
payload[key] = "{}{}".format(prefix, | ||
value[len(TOPIC_PREFIX):]) |
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 think we'll ever change the prefix, I think just using 1:
would be more readable.
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.
ded3945
to
8fc9c96
Compare
@balloob Yes, exactly. I'm not sure what the rationale for the "backwards" default topic scheme is, maybe to make it easier to subscribe to all state updates as you suggest. |
Why can't we have nice things 😢 Looks like in Tasmota the topics can be configured to have the tasmota "prefix" be last: https://github.com/arendst/Sonoff-Tasmota/wiki/MQTT-Features#mqtt-topic-definition |
@balloob Yes, exactly, and "prefix" last is even the default setting. Hence, can I update the PR by replacing: # Replace TOPIC_PREFIX at the start of configuration value
if TOPIC_PREFIX in payload:
prefix = payload[TOPIC_PREFIX]
for key, value in payload.items():
if value[0] == TOPIC_PREFIX and key.endswith('_topic'):
payload[key] = "{}{}".format(prefix, value[1:]) with: # Replace BASE_TOPIC in configuration value
if BASE_TOPIC in payload:
base_topic = payload[BASE_TOPIC]
for key in payload.keys():
if key.endswith('_topic'):
payload = payload.split('/')
payload = [x if x != BASE_TOPIC else base_topic for x in payload]
payload[key] = '/'.join(payload) |
Add missing docstring.
be57bcb
to
7a2d892
Compare
But if default prefix is last, then why would we have to update to support the base topic in every slot? Couldn't we get the user to just configure it properly? |
@balloob OK, how about supporting base topic either first (this makes most sense) or last (since it's Tasmota defualt) then? |
Let's do it. I don't like it though 😢 |
@balloob Done! |
Description:
Support abbreviations in MQTT discovery messages. Purpose is to avoid out-of-memory situations on memory constrained devices when sending discovery topic.
Note: This is item 4 from home-assistant/architecture#70
Pull request in home-assistant.github.io with documentation (if applicable): home-assistant/home-assistant.io#6294
Checklist:
tox
.