import flask import logging import json import threading from spejsiot.manager import SpejsiotManager from spejsiot.rendering import render_endpoint logging.basicConfig(level=logging.DEBUG, format='[%(asctime)-15s] %(name)-10s %(levelname)7s: %(message)s') app = flask.Flask(__name__) app.config['DISABLE_GUI'] = True app.config['PORT'] = 5100 app.config['BROKER'] = ('mqtt.waw.hackerspace.pl', 1883) app.config['PREFIX'] = 'iot/' app.config['TEMPLATES_AUTO_RELOAD'] = True manager = SpejsiotManager(app) @app.context_processor def utility_processor(): return { 'render_endpoint': render_endpoint, } @app.route('/') def index(): if app.config.get('DISABLE_GUI'): return flask.redirect(flask.url_for( 'static', filename='apidocs/index.html')) return flask.render_template('index.html', devices=manager.devices) def prometheus_sanitize(v): return v.encode('unicode_escape').decode('utf-8') def prometheus_value(v): return float(v) @app.route('/metrics') def metrics(): proplist = [] for _, dev in manager.devices.items(): if not dev.online: continue for endpoint_id, props in dev.endpoints.items(): for property_id, value in props.items(): if property_id.startswith('$'): continue try: proplist.append('spejsiot{node_id="%s", name="%s", ' \ 'endpoint="%s", property="%s"} %s' % ( prometheus_sanitize(dev.node_id), prometheus_sanitize(dev.name), prometheus_sanitize(endpoint_id), prometheus_sanitize(property_id), prometheus_value(value), )) except ValueError: # This is most probably just a string value continue return '\n'.join(proplist), 200, { 'Content-Type': 'text/plain; version=0.0.4', } @app.route('/api/1/devices/') def api_devices(): """Lists all known devices. :status 200: list of all devices :>json object [device_id]: listed device info object """ return flask.jsonify({k: v.dictify() for k, v in manager.devices.items()}) @app.route('/api/1/devices//') def api_device_info(node_id): """Returns specified device info object. :param node_id: device ID or device name :status 200: device found :status 404: no device found :>json string $name: human-readable device name :>json boolean $online: device is currently online :>json object [endpoint_name]: endpoint object :>json [endpoint_name].[prop_name]: last endpoint property value """ node = manager.find_node(node_id) if not node: flask.abort(404) return flask.jsonify(node.dictify()) # @app.route('/api/1/device////') @app.route('/api/1/devices////') def device_write(node_id, endpoint, prop, value): """Sets specified value to device endpoint and prop. :param node_id: device ID or device name :param endpoint: endpoint name :param prop: endpoint property name :param value: value to set :status 200: device found :status 404: no device found """ return flask.jsonify({ "result": manager.handle_request(node_id, endpoint, prop, value) }) @app.route('/api/1/devices///', methods=['PUT']) def device_put(node_id, endpoint, prop): """Sets specified value to device endpoint and prop. :param node_id: device ID or device name :param endpoint: endpoint name :param prop: endpoint property name :