From bf941ae7018580f9f456937e78fc7163aa3deaa0 Mon Sep 17 00:00:00 2001 From: Konstantin Koslowski Date: Sun, 3 Nov 2019 13:57:14 +0100 Subject: [PATCH] homecontrol: add queue for actors, formatting, lots of things --- Client.py | 45 ++++++++++++++++-------- homecontrol.py | 92 ++++++++++++++++++++++++++++++-------------------- 2 files changed, 86 insertions(+), 51 deletions(-) diff --git a/Client.py b/Client.py index a882ba4..b8554f0 100644 --- a/Client.py +++ b/Client.py @@ -1,19 +1,24 @@ #!/usr/bin/env python3 +import queue import time class Client: - def __init__(self, clientid, clienttype="default"): - self.clienttype = clienttype - self.clientid = clientid + def __init__(self, id_c, type_c="default"): + self.type_c = type_c + self.id_c = id_c + self.ts = time.time() + + def update(self): + self.ts = time.time() def get_info(self): - return "clientid: %s, clienttype: %s" % (self.clientid, self.clienttype) + return "id: %s, type: %s, ts: %s" % (self.id_c, self.type_c, self.ts) class Sensor(Client): - def __init__(self, sensorid, sensortype, num_values): + def __init__(self, id_s, type_s, num_values): self.num_values = num_values self.values = {} - super().__init__(sensorid, sensortype) + super().__init__(id_s, type_s) def get_values(self): return self.values @@ -28,15 +33,27 @@ class Sensor(Client): return len(self.values) class Actor(Client): - def __init__(self, actorid, actortype, levels): + def __init__(self, id_a, type_a, levels): + self.id_a = id_a + self.type_a = type_a self.levels = levels - self.level = 0 - super().__init__(actorid, actortype) + self.queue = queue.Queue() + super().__init__(id_a, type_a) + + + def get_info(self): + return "id: %s, type: %s, ts: %s, levels: 0x%x, level: 0x%06x" % ( + self.id_a, self.type_a, self.ts, self.levels, self.level) + + def add_queue(self, command, data): + print("add_queue: {\"command\": %s, \"data\": %s}" % (command, data)) + self.queue.put({"command": command, "data": data}) + + def get_queue(self): + ret = {} + if not self.queue.empty(): + ret = self.queue.get() + return ret def get_level(self): return(self.level) - - def set_level(self, level): - if level < self.levels: - self.level = level - return(self.level) diff --git a/homecontrol.py b/homecontrol.py index 63a0bb9..34582fa 100755 --- a/homecontrol.py +++ b/homecontrol.py @@ -2,10 +2,12 @@ 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 @@ -20,6 +22,8 @@ def setup(): 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() @@ -60,12 +64,24 @@ class Core: 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 @@ -89,52 +105,52 @@ def actors_update(): ret = {} try: content = request.json - id_a = content.get("id_a") - type_a = content.get("type_a") - levels = content.get("levels") + # 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.type_a = type_a - actor.levels = levels + 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) - for a in core.actors: - logger.debug("actor: %s" % a) 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): - logger.debug("actors/get_level/%s" % id_a) + ret = {} + # logger.debug("actors/get_level/%s" % id_a) if id_a in core.actors: ret = core.actors[id_a].get_level() - return make_response(jsonify(ret), 200) else: logger.debug("id_a: %s not in core.actors" % id_a) - for a in core.actors: - logger.debug("actor: %s" % a) - abort(400) - - -@app.route("/actors/set_level", methods=['POST']) -def actors_set_level(): - ret = {} - try: - content = request.json - logger.info("actors/set_level: %s" % (content)) - id_a = content.get("id_a") - level = content.get("level") - if id_a in core.actors: - ret = core.actors[id_a].set_level(level) - 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) @@ -146,28 +162,29 @@ def sensors_get(): @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() - return make_response(jsonify(ret), 200) else: logger.debug("id_s: %s not in core.sensors" % id_s) - abort(400) + return make_response(jsonify(ret), 200) -@app.route("/sensors/add_value", methods=['POST']) +@app.route("/sensors/update", methods=['POST']) def sensors_add_value(): ret = {} try: content = request.json - logger.info("sensors_add_value: %s" % (content)) - id_s = content.get("id_s") + # 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("sensortype") + 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)) @@ -178,12 +195,13 @@ def sensors_add_value(): if __name__ == "__main__": args, config = setup() core = Core(args.debug) - print("main") - logging.basicConfig(level=logging.INFO) + 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.INFO) + logger.setLevel(logging.WARNING) - app.run(host='0.0.0.0', port=config['port'], debug=args.debug) + app.run(host='0.0.0.0', port=config['port'], debug=args.debugflask)