Create MQTTMatcher once per subscription instead of each message (#40345)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>pull/40794/head
parent
4c157f65ea
commit
a11fd08d20
|
@ -630,6 +630,7 @@ class Subscription:
|
|||
"""Class to hold data about an active subscription."""
|
||||
|
||||
topic: str = attr.ib()
|
||||
matcher: Any = attr.ib()
|
||||
callback: MessageCallbackType = attr.ib()
|
||||
qos: int = attr.ib(default=0)
|
||||
encoding: str = attr.ib(default="utf-8")
|
||||
|
@ -838,7 +839,9 @@ class MQTT:
|
|||
if not isinstance(topic, str):
|
||||
raise HomeAssistantError("Topic needs to be a string!")
|
||||
|
||||
subscription = Subscription(topic, msg_callback, qos, encoding)
|
||||
subscription = Subscription(
|
||||
topic, _matcher_for_topic(topic), msg_callback, qos, encoding
|
||||
)
|
||||
self.subscriptions.append(subscription)
|
||||
|
||||
# Only subscribe if currently connected.
|
||||
|
@ -953,7 +956,7 @@ class MQTT:
|
|||
timestamp = dt_util.utcnow()
|
||||
|
||||
for subscription in self.subscriptions:
|
||||
if not _match_topic(subscription.topic, msg.topic):
|
||||
if not subscription.matcher(msg.topic):
|
||||
continue
|
||||
|
||||
payload: SubscribePayloadType = msg.payload
|
||||
|
@ -1050,18 +1053,14 @@ def _raise_on_error(result_code: int) -> None:
|
|||
)
|
||||
|
||||
|
||||
def _match_topic(subscription: str, topic: str) -> bool:
|
||||
"""Test if topic matches subscription."""
|
||||
def _matcher_for_topic(subscription: str) -> Any:
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from paho.mqtt.matcher import MQTTMatcher
|
||||
|
||||
matcher = MQTTMatcher()
|
||||
matcher[subscription] = True
|
||||
try:
|
||||
next(matcher.iter_match(topic))
|
||||
return True
|
||||
except StopIteration:
|
||||
return False
|
||||
|
||||
return lambda topic: next(matcher.iter_match(topic), False)
|
||||
|
||||
|
||||
class MqttAttributes(Entity):
|
||||
|
|
Loading…
Reference in New Issue