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)