Home Assistant Git Exporter
This commit is contained in:
91
config/custom_components/pyscript/mqtt.py
Normal file
91
config/custom_components/pyscript/mqtt.py
Normal file
@@ -0,0 +1,91 @@
|
||||
"""Handles mqtt messages and notification."""
|
||||
|
||||
import json
|
||||
import logging
|
||||
|
||||
from homeassistant.components import mqtt
|
||||
|
||||
from .const import LOGGER_PATH
|
||||
|
||||
_LOGGER = logging.getLogger(LOGGER_PATH + ".mqtt")
|
||||
|
||||
|
||||
class Mqtt:
|
||||
"""Define mqtt functions."""
|
||||
|
||||
#
|
||||
# Global hass instance
|
||||
#
|
||||
hass = None
|
||||
|
||||
#
|
||||
# notify message queues by mqtt message topic
|
||||
#
|
||||
notify = {}
|
||||
notify_remove = {}
|
||||
|
||||
def __init__(self):
|
||||
"""Warn on Mqtt instantiation."""
|
||||
_LOGGER.error("Mqtt class is not meant to be instantiated")
|
||||
|
||||
@classmethod
|
||||
def init(cls, hass):
|
||||
"""Initialize Mqtt."""
|
||||
|
||||
cls.hass = hass
|
||||
|
||||
@classmethod
|
||||
def mqtt_message_handler_maker(cls, subscribed_topic):
|
||||
"""Closure for mqtt_message_handler."""
|
||||
|
||||
async def mqtt_message_handler(mqttmsg):
|
||||
"""Listen for MQTT messages."""
|
||||
func_args = {
|
||||
"trigger_type": "mqtt",
|
||||
"topic": mqttmsg.topic,
|
||||
"payload": mqttmsg.payload,
|
||||
"qos": mqttmsg.qos,
|
||||
}
|
||||
|
||||
try:
|
||||
func_args["payload_obj"] = json.loads(mqttmsg.payload)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
await cls.update(subscribed_topic, func_args)
|
||||
|
||||
return mqtt_message_handler
|
||||
|
||||
@classmethod
|
||||
async def notify_add(cls, topic, queue):
|
||||
"""Register to notify for mqtt messages of given topic to be sent to queue."""
|
||||
|
||||
if topic not in cls.notify:
|
||||
cls.notify[topic] = set()
|
||||
_LOGGER.debug("mqtt.notify_add(%s) -> adding mqtt subscription", topic)
|
||||
cls.notify_remove[topic] = await mqtt.async_subscribe(
|
||||
cls.hass, topic, cls.mqtt_message_handler_maker(topic), encoding="utf-8", qos=0
|
||||
)
|
||||
cls.notify[topic].add(queue)
|
||||
|
||||
@classmethod
|
||||
def notify_del(cls, topic, queue):
|
||||
"""Unregister to notify for mqtt messages of given topic for given queue."""
|
||||
|
||||
if topic not in cls.notify or queue not in cls.notify[topic]:
|
||||
return
|
||||
cls.notify[topic].discard(queue)
|
||||
if len(cls.notify[topic]) == 0:
|
||||
cls.notify_remove[topic]()
|
||||
_LOGGER.debug("mqtt.notify_del(%s) -> removing mqtt subscription", topic)
|
||||
del cls.notify[topic]
|
||||
del cls.notify_remove[topic]
|
||||
|
||||
@classmethod
|
||||
async def update(cls, topic, func_args):
|
||||
"""Deliver all notifications for an mqtt message on the given topic."""
|
||||
|
||||
_LOGGER.debug("mqtt.update(%s, %s, %s)", topic, vars, func_args)
|
||||
if topic in cls.notify:
|
||||
for queue in cls.notify[topic]:
|
||||
await queue.put(["mqtt", func_args.copy()])
|
||||
Reference in New Issue
Block a user