Initial commit
commit
ec584a804b
|
@ -0,0 +1,73 @@
|
|||
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()
|
|
@ -0,0 +1,2 @@
|
|||
Flask==0.11.1
|
||||
paho-mqtt==1.2
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Bootswatch: Flatly</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="https://bootswatch.com/flatly/bootstrap.css" media="screen">
|
||||
<style type="text/css" media="screen">
|
||||
.panel-body h1, .panel-body h2, .panel-body h3 {
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
{% for name, dev in devices.items() %}
|
||||
{% for name, obj in dev.endpoints.items() %}
|
||||
{% if obj['type'] != 'control' %}
|
||||
<div class="col-md-3">
|
||||
<div class="panel {% if dev.online %}panel-primary{% else %}panel-default{% endif %}">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title"><small>{{ dev.node_id }} / {{ dev.metadata['device_type'] }}</small> {{ name }}</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<h1>{{ obj['value'] }}<small>unit</small></h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue