spejsiot-api/spejsiot/manager.py

92 lines
2.6 KiB
Python

import paho.mqtt.client as mqtt
from collections import defaultdict
import logging
class SpejsiotDevice(object):
node_id = None
properties = None
endpoints = None
manager = None
def __init__(self, node_id, manager=None):
self.node_id = node_id
self.manager = manager
self.properties = {}
self.endpoints = defaultdict(dict)
def dictify(self):
return dict(self.properties, **self.endpoints)
def set(self, endpoint, prop, value):
self.manager.publish('%s%s/%s/%s/set' % (
self.manager.app.config['PREFIX'],
self.node_id,
endpoint,
prop,
), value, retain=True)
return True
class SpejsiotManager(mqtt.Client):
devices = dict()
logger = logging.getLogger('manager')
def __init__(self, app):
super(SpejsiotManager, self).__init__()
self.app = app
def on_connect(self, client, userdata, flags, rc):
self.logger.info('Connected, rc: %d', rc)
self.subscribe(self.app.config['PREFIX'] + '+/+')
self.subscribe(self.app.config['PREFIX'] + '+/+/+')
def run(self, broker, port):
self.connect(broker, port, 60)
self.loop_start()
def on_message(self, client, userdata, msg):
try:
self.logger.info('Message received %s: %s', msg.topic, msg.payload)
topic = msg.topic[len(self.app.config['PREFIX']):]
node_id, topic = topic.split('/', 1)
if node_id not in self.devices.keys():
self.devices[node_id] = SpejsiotDevice(node_id, self)
if msg.payload == b'true':
value = True
elif msg.payload == b'false':
value = False
else:
value = msg.payload.decode('utf-8')
if topic.startswith('$'):
self.devices[node_id].properties[topic] = value
else:
endpoint, prop = topic.split('/', 1)
self.devices[node_id].endpoints[endpoint][prop] = value
except:
self.logger.exception('fuckup')
def find_node(self, node_id):
if node_id in self.devices:
return self.devices[node_id]
for n in self.devices.values():
if n.properties.get('$name', None) == node_id:
return n
return None
def handle_request(self, node_id, endpoint, prop, value):
node = self.find_node(node_id)
if not node:
return False
if value == True:
value = 'true'
elif value == False:
value = 'false'
return node.set(endpoint, prop, value)