homecontrol: add queue for actors, formatting, lots of things

This commit is contained in:
Konstantin Koslowski 2019-11-03 13:57:14 +01:00
parent 246bf7e1de
commit bf941ae701
2 changed files with 86 additions and 51 deletions

View file

@ -1,19 +1,24 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import queue
import time import time
class Client: class Client:
def __init__(self, clientid, clienttype="default"): def __init__(self, id_c, type_c="default"):
self.clienttype = clienttype self.type_c = type_c
self.clientid = clientid self.id_c = id_c
self.ts = time.time()
def update(self):
self.ts = time.time()
def get_info(self): 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): 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.num_values = num_values
self.values = {} self.values = {}
super().__init__(sensorid, sensortype) super().__init__(id_s, type_s)
def get_values(self): def get_values(self):
return self.values return self.values
@ -28,15 +33,27 @@ class Sensor(Client):
return len(self.values) return len(self.values)
class Actor(Client): 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.levels = levels
self.level = 0 self.queue = queue.Queue()
super().__init__(actorid, actortype) 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): def get_level(self):
return(self.level) return(self.level)
def set_level(self, level):
if level < self.levels:
self.level = level
return(self.level)

View file

@ -2,10 +2,12 @@
from flask import Flask, request, json, jsonify, abort, make_response from flask import Flask, request, json, jsonify, abort, make_response
import logging import logging
import argparse import argparse
import time
import Client import Client
CONFIG_FILE = 'config.json' CONFIG_FILE = 'config.json'
PORT = 5000 PORT = 5000
TIMEOUT_CLIENT = 10
core = None core = None
# sensors # sensors
@ -20,6 +22,8 @@ def setup():
help='config file', default=CONFIG_FILE) help='config file', default=CONFIG_FILE)
parser.add_argument('-d', '--debug', dest='debug', action='store_true', parser.add_argument('-d', '--debug', dest='debug', action='store_true',
help='debug mode') help='debug mode')
parser.add_argument('-D', '--debugflask', dest='debugflask', action='store_true',
help='flask debug mode')
# parse arguments # parse arguments
args = parser.parse_args() args = parser.parse_args()
@ -60,12 +64,24 @@ class Core:
def actors_get(self): def actors_get(self):
ret = {} 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: for a in self.actors:
ret[a] = self.actors[a].get_info() ret[a] = self.actors[a].get_info()
return ret return ret
def sensors_get(self): def sensors_get(self):
ret = {} 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: for s in self.sensors:
ret[s] = self.sensors[s].get_info() ret[s] = self.sensors[s].get_info()
return ret return ret
@ -89,52 +105,52 @@ def actors_update():
ret = {} ret = {}
try: try:
content = request.json content = request.json
id_a = content.get("id_a") # logger.debug("/actors/update: %s" % content)
type_a = content.get("type_a") id_a = content.get("id")
levels = content.get("levels")
level = content.get("level") level = content.get("level")
if id_a not in core.actors: 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) core.actors[id_a] = Client.Actor(id_a, type_a, levels)
actor = core.actors[id_a] actor = core.actors[id_a]
actor.type_a = type_a actor.update()
actor.levels = levels
actor.level = level actor.level = level
ret = actor.get_queue()
except Exception as ex: except Exception as ex:
logger.error('Exception Type:%s, args:\n%s' % (type(ex).__name__, ex.args)) logger.error('Exception Type:%s, args:\n%s' % (type(ex).__name__, ex.args))
abort(400) abort(400)
for a in core.actors:
logger.debug("actor: %s" % a)
return make_response(jsonify(ret), 200) 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/<id_a>", methods=['GET']) @app.route("/actors/get_level/<id_a>", methods=['GET'])
def actors_get_level(id_a): 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: if id_a in core.actors:
ret = core.actors[id_a].get_level() ret = core.actors[id_a].get_level()
return make_response(jsonify(ret), 200)
else: else:
logger.debug("id_a: %s not in core.actors" % id_a) 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) return make_response(jsonify(ret), 200)
@ -146,28 +162,29 @@ def sensors_get():
@app.route("/sensors/get_values/<id_s>", methods=['GET']) @app.route("/sensors/get_values/<id_s>", methods=['GET'])
def sensors_get_values(id_s): def sensors_get_values(id_s):
ret = {}
logger.debug("sensors/get_values/%s" % id_s) logger.debug("sensors/get_values/%s" % id_s)
if id_s in core.sensors: if id_s in core.sensors:
ret = core.sensors[id_s].get_values() ret = core.sensors[id_s].get_values()
return make_response(jsonify(ret), 200)
else: else:
logger.debug("id_s: %s not in core.sensors" % id_s) 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(): def sensors_add_value():
ret = {} ret = {}
try: try:
content = request.json content = request.json
logger.info("sensors_add_value: %s" % (content)) # logger.info("sensors_update: %s" % (content))
id_s = content.get("id_s") id_s = content.get("id")
value = content.get("value") value = content.get("value")
if id_s not in core.sensors: 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) core.sensors[id_s] = Client.Sensor(id_s, type_s, NUM_VALUES)
logger.info("created sensor: %s" % (core.sensors[id_s].get_info())) logger.info("created sensor: %s" % (core.sensors[id_s].get_info()))
sensor = core.sensors[id_s] sensor = core.sensors[id_s]
sensor.update()
ret = sensor.add_value(value) ret = sensor.add_value(value)
except Exception as ex: except Exception as ex:
logger.error('Exception Type:%s, args:\n%s' % (type(ex).__name__, ex.args)) logger.error('Exception Type:%s, args:\n%s' % (type(ex).__name__, ex.args))
@ -178,12 +195,13 @@ def sensors_add_value():
if __name__ == "__main__": if __name__ == "__main__":
args, config = setup() args, config = setup()
core = Core(args.debug) core = Core(args.debug)
print("main") FORMAT='%(asctime)-8s %(name)12s::%(levelname)-7s %(message)s'
logging.basicConfig(level=logging.INFO) DATEFMT='%H:%M:%S'
logging.basicConfig(level=logging.WARNING, format=FORMAT, datefmt=DATEFMT)
logger = logging.getLogger("homecontrol") logger = logging.getLogger("homecontrol")
if args.debug: if args.debug:
logger.setLevel(logging.DEBUG) logger.setLevel(logging.DEBUG)
else: 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)