master
vuko 2020-11-27 17:26:39 +01:00
parent ae1e54b37c
commit 24464bb63c
2 changed files with 98 additions and 103 deletions

View File

@ -6,10 +6,7 @@ pkgs.python3Packages.buildPythonPackage {
src = ./.;
propagatedBuildInputs = with pkgs; [
python3Packages.gunicorn
python3Packages.flask
python3Packages.paho-mqtt
python3Packages.pyyaml
propagatedBuildInputs = with pkgs.python3Packages; [
gunicorn flask paho-mqtt pyyaml setuptools
];
}

View File

@ -16,107 +16,105 @@ import atexit
# remove temporary files created by resource_filename
atexit.register(cleanup_resources, force=True)
secrets_path = Path(os.environ.get("LIGHTS_WEB_SECRETS", 'secrets.yaml'))
config_path = Path(os.environ.get("LIGHTS_WEB_CONFIG", 'config.yaml'))
config = yaml.safe_load(config_path.read_text())
config.update(yaml.safe_load(secrets_path.read_text()))
c = threading.Condition()
application = flask.Flask(__name__)
application.msg="ab"
application.lights = { lid: False for lid in config['lights'] }
application.logger.removeHandler(flask.logging.default_handler)
logging.basicConfig(level=logging.DEBUG)
def on_message(client,userdata,message):
c.acquire()
for lid, cfg in config['lights'].items():
if cfg['mqtt_path'] == message.topic:
if message.payload == b'true':
application.lights[lid] = True
elif message.payload == b'false':
application.lights[lid] = False
c.release()
def on_connect(client, userdata, rc, l):
logging.info(f"connected")
for lid, cfg in config['lights'].items():
logging.info(f"subscribing: {cfg}")
client.subscribe(cfg['mqtt_path'])
mc = mqtt.client.Client()
mc.username_pw_set(config['mqtt_rw_username'], config['mqtt_rw_password'])
mc.on_connect = on_connect
mc.on_message = on_message
mc.connect_async(config["mqtt_server"])
mc.enable_logger()
mc.loop_start()
@application.route("/")
def main():
return flask.send_file(resource_filename(__name__, 'static/index.html'))
@application.route("/status")
def status():
print("Main Thread: " + str(threading.current_thread()))
c.acquire()
st = {"lights" : application.lights}
c.release()
return json.dumps(st)
@application.route("/config")
def get_config():
return flask.jsonify({
"mqtt_server": config["mqtt_server"],
"mqtt_port": config["mqtt_port"],
"mqtt_username": config["mqtt_ro_username"],
"mqtt_password": config["mqtt_ro_password"],
"lights": config['lights']
})
def publish(path, payload):
mc.publish(path, payload, qos=1)
@application.route('/light/<lid>/on/set', methods=['POST'])
def set_light(lid):
try:
path = config["lights"][lid]["mqtt_path"]
except KeyError:
return flask.jsonify({"ok": False})
publish(path + '/set', "true")
return flask.jsonify({"ok": True})
@application.route('/light/<lid>/on/toggle', methods=['POST'])
def toggle_light(lid):
try:
cfg = config["lights"][lid]
toggle = cfg.get('toggle', False)
path = cfg["mqtt_path"]
except KeyError:
print(config["lights"])
logging.exception("toggle exception")
return flask.jsonify({"ok": False})
if toggle:
publish(path + '/toggle', "true")
elif application.lights[lid]:
publish(path + '/set', "false")
else:
def app():
secrets_path = Path(os.environ.get("LIGHTS_WEB_SECRETS", 'secrets.yaml'))
config_path = Path(os.environ.get("LIGHTS_WEB_CONFIG", 'config.yaml'))
config = yaml.safe_load(config_path.read_text())
config.update(yaml.safe_load(secrets_path.read_text()))
c = threading.Condition()
application = flask.Flask(__name__)
application.msg="ab"
application.lights = { lid: False for lid in config['lights'] }
def on_message(client,userdata,message):
c.acquire()
for lid, cfg in config['lights'].items():
if cfg['mqtt_path'] == message.topic:
if message.payload == b'true':
application.lights[lid] = True
elif message.payload == b'false':
application.lights[lid] = False
c.release()
def on_connect(client, userdata, rc, l):
logging.info(f"connected")
for lid, cfg in config['lights'].items():
logging.info(f"subscribing: {cfg}")
client.subscribe(cfg['mqtt_path'])
mc = mqtt.client.Client()
mc.username_pw_set(config['mqtt_rw_username'], config['mqtt_rw_password'])
mc.on_connect = on_connect
mc.on_message = on_message
mc.connect_async(config["mqtt_server"])
mc.enable_logger()
mc.loop_start()
@application.route("/")
def main():
return flask.send_file(resource_filename(__name__, 'static/index.html'))
@application.route("/status")
def status():
print("Main Thread: " + str(threading.current_thread()))
c.acquire()
st = {"lights" : application.lights}
c.release()
return json.dumps(st)
@application.route("/config")
def get_config():
return flask.jsonify({
"mqtt_server": config["mqtt_server"],
"mqtt_port": config["mqtt_ws_port"],
"mqtt_username": config["mqtt_ro_username"],
"mqtt_password": config["mqtt_ro_password"],
"lights": config['lights']
})
def publish(path, payload):
mc.publish(path, payload, qos=1)
@application.route('/light/<lid>/on/set', methods=['POST'])
def set_light(lid):
try:
path = config["lights"][lid]["mqtt_path"]
except KeyError:
return flask.jsonify({"ok": False})
publish(path + '/set', "true")
return flask.jsonify({"ok": True})
return flask.jsonify({"ok": True})
@application.route('/light/<lid>/on/toggle', methods=['POST'])
def toggle_light(lid):
try:
cfg = config["lights"][lid]
toggle = cfg.get('toggle', False)
path = cfg["mqtt_path"]
except KeyError:
print(config["lights"])
logging.exception("toggle exception")
return flask.jsonify({"ok": False})
if toggle:
publish(path + '/toggle', "true")
elif application.lights[lid]:
publish(path + '/set', "false")
else:
publish(path + '/set', "true")
return flask.jsonify({"ok": True})
return application
def run_development():
application.run(host='127.0.0.1',port=8000,debug=True)
app().run(host='127.0.0.1',port=8000,debug=True)
if __name__ == "__main__":
run_development()