platypush/platypush/backend/adafruit/io/__init__.py

97 lines
3 KiB
Python

from typing import Optional
from platypush.backend import Backend
from platypush.context import get_plugin
from platypush.message.event.adafruit import ConnectedEvent, DisconnectedEvent, \
FeedUpdateEvent
class AdafruitIoBackend(Backend):
"""
Backend that listens to messages received over the Adafruit IO message queue
Triggers:
* :class:`platypush.message.event.adafruit.ConnectedEvent` when the
backend connects to the Adafruit queue
* :class:`platypush.message.event.adafruit.DisconnectedEvent` when the
backend disconnects from the Adafruit queue
* :class:`platypush.message.event.adafruit.FeedUpdateEvent` when an
update event is received on a monitored feed
Requires:
* The :class:`platypush.plugins.adafruit.io.AdafruitIoPlugin` plugin to
be active and configured.
"""
def __init__(self, feeds, *args, **kwargs):
"""
:param feeds: List of feed IDs to monitor
:type feeds: list[str]
"""
super().__init__(*args, **kwargs)
from Adafruit_IO import MQTTClient
self.feeds = feeds
self._client: Optional[MQTTClient] = None
def _init_client(self):
if self._client:
return
from Adafruit_IO import MQTTClient
plugin = get_plugin('adafruit.io')
if not plugin:
raise RuntimeError('Adafruit IO plugin not configured')
# noinspection PyProtectedMember
self._client = MQTTClient(plugin._username, plugin._key)
self._client.on_connect = self.on_connect()
self._client.on_disconnect = self.on_disconnect()
self._client.on_message = self.on_message()
def on_connect(self):
def _handler(client):
for feed in self.feeds:
client.subscribe(feed)
self.bus.post(ConnectedEvent())
return _handler
def on_disconnect(self):
def _handler(*_, **__):
self.bus.post(DisconnectedEvent())
return _handler
def on_message(self, *_, **__):
# noinspection PyUnusedLocal
def _handler(client, feed, data):
try:
data = float(data)
except Exception as e:
self.logger.debug('Not a number: {}: {}'.format(data, e))
self.bus.post(FeedUpdateEvent(feed=feed, data=data))
return _handler
def run(self):
super().run()
self.logger.info(('Initialized Adafruit IO backend, listening on ' +
'feeds {}').format(self.feeds))
while not self.should_stop():
try:
self._init_client()
# noinspection PyUnresolvedReferences
self._client.connect()
# noinspection PyUnresolvedReferences
self._client.loop_blocking()
except Exception as e:
self.logger.exception(e)
self._client = None
# vim:sw=4:ts=4:et: