homecontrol/homecontrol.py

207 lines
5.9 KiB
Python
Executable file

#!/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/<id_a>", 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/<id_s>", 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)