#!/usr/bin/env python3 from flask import Flask, request, json, jsonify, abort, make_response import logging import argparse import time import Client CONFIG_FILE = 'config.json' PORT = 5000 TIMEOUT_CLIENT = 10 core = None # sensors NUM_VALUES = 1000 def setup(): # arguments parser = argparse.ArgumentParser(description='homecontrol') parser.add_argument('-p', '--port', dest='port', type=int, help='listening port') parser.add_argument('-c', '--config', dest='config', type=str, help='config file', default=CONFIG_FILE) parser.add_argument('-d', '--debug', dest='debug', action='store_true', help='debug mode') parser.add_argument('-D', '--debugflask', dest='debugflask', action='store_true', help='flask debug mode') # parse arguments args = parser.parse_args() # initialize config config = {} try: config_file = open(args.config, 'r') config = json.load(config_file) except Exception as ex: logger.error('Exception Type:%s, args:\n%s' % (type(ex).__name__, ex.args)) # fill new keys with defaults if not config.get('port'): config['port'] = PORT # overwrite with arguments if args.port: config['port'] = args.port # save to file with open(args.config, 'w') as config_file: json.dump(config, config_file) return args, config class Core: def __init__(self, debug): self.logger = logging.getLogger("Core") if args.debug: self.logger.setLevel(logging.DEBUG) else: self.logger.setLevel(logging.INFO) self.actors = {} self.sensors = {} def actors_get(self): ret = {} # remove inactive actors for a in list(self.actors): if time.time() - self.actors[a].ts > TIMEOUT_CLIENT: self.logger.info("removing inactive actor: %s" % a) self.actors.pop(a) for a in self.actors: ret[a] = self.actors[a].get_info() return ret def sensors_get(self): ret = {} # remove inactive sensors for s in list(self.sensors): if time.time() - self.sensors[s].ts > TIMEOUT_CLIENT: self.logger.info("removing inactive sensor: %s" % s) self.sensors.pop(s) for s in self.sensors: ret[s] = self.sensors[s].get_info() return ret def update(self): # TODO pass app = Flask(__name__) @app.route("/actors/get", methods=['GET']) def actors_get(): ret = core.actors_get() return make_response(jsonify(ret), 200) @app.route("/actors/update", methods=['POST']) def actors_update(): ret = {} try: content = request.json # logger.debug("/actors/update: %s" % content) id_a = content.get("id") level = content.get("level") if id_a not in core.actors: type_a = content.get("type") levels = content.get("levels") core.actors[id_a] = Client.Actor(id_a, type_a, levels) actor = core.actors[id_a] actor.update() actor.level = level ret = actor.get_queue() except Exception as ex: logger.error('Exception Type:%s, args:\n%s' % (type(ex).__name__, ex.args)) abort(400) return make_response(jsonify(ret), 200) @app.route("/actors/command", methods=['POST']) def actors_command(): ret = {} try: content = request.json # logger.debug("/actors/command: %s" % content) id_a = content.get("id") command = content.get("command") data = content.get("data") if id_a in core.actors: actor = core.actors[id_a] actor.add_queue(command, data) except Exception as ex: logger.error('Exception Type:%s, args:\n%s' % (type(ex).__name__, ex.args)) abort(400) return make_response(jsonify(ret), 200) @app.route("/actors/get_level/", methods=['GET']) def actors_get_level(id_a): ret = {} # logger.debug("actors/get_level/%s" % id_a) if id_a in core.actors: ret = core.actors[id_a].get_level() else: logger.debug("id_a: %s not in core.actors" % id_a) return make_response(jsonify(ret), 200) @app.route("/sensors/get", methods=['GET']) def sensors_get(): ret = core.sensors_get() return make_response(jsonify(ret), 200) @app.route("/sensors/get_values/", methods=['GET']) def sensors_get_values(id_s): ret = {} logger.debug("sensors/get_values/%s" % id_s) if id_s in core.sensors: ret = core.sensors[id_s].get_values() else: logger.debug("id_s: %s not in core.sensors" % id_s) return make_response(jsonify(ret), 200) @app.route("/sensors/update", methods=['POST']) def sensors_add_value(): ret = {} try: content = request.json # logger.info("sensors_update: %s" % (content)) id_s = content.get("id") value = content.get("value") if id_s not in core.sensors: type_s = content.get("type") core.sensors[id_s] = Client.Sensor(id_s, type_s, NUM_VALUES) logger.info("created sensor: %s" % (core.sensors[id_s].get_info())) sensor = core.sensors[id_s] sensor.update() ret = sensor.add_value(value) except Exception as ex: logger.error('Exception Type:%s, args:\n%s' % (type(ex).__name__, ex.args)) abort(400) return make_response(jsonify(ret), 200) if __name__ == "__main__": args, config = setup() core = Core(args.debug) FORMAT='%(asctime)-8s %(name)12s::%(levelname)-7s %(message)s' DATEFMT='%H:%M:%S' logging.basicConfig(level=logging.WARNING, format=FORMAT, datefmt=DATEFMT) logger = logging.getLogger("homecontrol") if args.debug: logger.setLevel(logging.DEBUG) else: logger.setLevel(logging.WARNING) app.run(host='0.0.0.0', port=config['port'], debug=args.debugflask)