92 lines
2.7 KiB
Python
92 lines
2.7 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()
|
|
print(self.on_connect)
|
|
|
|
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
|
|
|
|
return node.set(endpoint, prop, value)
|
|
|
|
def on_log(self, client, userdata, level, buf):
|
|
self.logger.debug('[%r] %r', level, buf)
|
|
|