spejsiot-api/main.py

74 lines
2.1 KiB
Python

import flask
import paho.mqtt.client as mqtt
import logging
import json
logging.basicConfig(level=logging.DEBUG, format='[%(asctime)-15s] %(name)-10s %(levelname)7s: %(message)s')
class SpejsiotDevice(object):
metadata = None
online = False
node_id = None
def __init__(self, node_id):
self.node_id = node_id
class SpejsiotManager(mqtt.Client):
devices = dict()
logger = logging.getLogger('manager')
def __init__(self):
super(SpejsiotManager, self).__init__()
def run(self, broker, port):
self.connect(broker, port, 60)
self.loop_start()
def on_connect(self, client, userdata, flags, rc):
self.logger.info('Connected, rc: %d', rc)
self.subscribe('iot/+/state')
self.subscribe('iot/+/metadata')
def on_message(self, client, userdata, msg):
self.logger.info('Message received %s: %s', msg.topic, msg.payload)
_, node_id, topic = msg.topic.split('/', 2)
if node_id not in self.devices.keys():
self.devices[node_id] = SpejsiotDevice(node_id)
if topic == 'state':
self.devices[node_id].online = msg.payload == 'online'
elif topic == 'metadata':
metadata = json.loads(msg.payload)
self.devices[node_id].metadata = metadata
self.devices[node_id].endpoints = {
e['name']: {'type': e['type'], 'value': None}
for e in metadata['endpoints']
}
for e in self.devices[node_id].endpoints.keys():
self.subscribe('iot/%s/%s' % (node_id, e))
elif topic in self.devices[node_id].endpoints:
self.devices[node_id].endpoints[topic]['value'] = msg.payload
manager = SpejsiotManager()
app = flask.Flask(__name__)
app.config['TEMPLATES_AUTO_RELOAD'] = True
@app.route('/')
def index():
return flask.render_template('index.html', devices=manager.devices)
@app.route('/api/1/devices')
def api_devices():
return flask.jsonify({k: v.metadata for k, v in manager.devices.items()})
if __name__ == "__main__":
manager.run('127.0.0.1', 1883)
app.run()