From bc29d29a5fad5f3289cedb5b6f66d0091eecb961 Mon Sep 17 00:00:00 2001 From: Christian Elberfeld <elberfeld@web.de> Date: Sun, 8 Jan 2023 22:07:35 +0100 Subject: [PATCH] Removed MQTT dependency, implemented http Update --- Dockerfile | 1 - docker-compose.yml | 2 + mqtt/publish_zoneclosed.bat | 1 - mqtt/publish_zoneopen.bat | 1 - mqtt/subscribe.bat | 2 - warpapi/warpapi.py | 107 ++++++++++++++++++++++++------------ 6 files changed, 75 insertions(+), 39 deletions(-) delete mode 100644 mqtt/publish_zoneclosed.bat delete mode 100644 mqtt/publish_zoneopen.bat delete mode 100644 mqtt/subscribe.bat diff --git a/Dockerfile b/Dockerfile index 5e38869..074c48c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,6 @@ RUN pip3 install --upgrade pip # pip Packages RUN pip3 install \ flask==1.0.2 \ - flask_mqtt \ gunicorn \ --upgrade diff --git a/docker-compose.yml b/docker-compose.yml index b69f2af..874e262 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,3 +9,5 @@ services: - 0.0.0.0:5000:5000 volumes: - ./warpapi/:/opt/warpapi + environment: + - UPDATE_KEY=somesecretkey diff --git a/mqtt/publish_zoneclosed.bat b/mqtt/publish_zoneclosed.bat deleted file mode 100644 index 47ad7d3..0000000 --- a/mqtt/publish_zoneclosed.bat +++ /dev/null @@ -1 +0,0 @@ - docker run --rm -it ruimarinho/mosquitto mosquitto_pub -h 192.168.0.201 -t warpzone/door/status -m "CLOSED" --retain diff --git a/mqtt/publish_zoneopen.bat b/mqtt/publish_zoneopen.bat deleted file mode 100644 index b2be594..0000000 --- a/mqtt/publish_zoneopen.bat +++ /dev/null @@ -1 +0,0 @@ - docker run --rm -it ruimarinho/mosquitto mosquitto_pub -h 192.168.0.201 -t warpzone/door/status -m "OPEN" --retain diff --git a/mqtt/subscribe.bat b/mqtt/subscribe.bat deleted file mode 100644 index a07b68e..0000000 --- a/mqtt/subscribe.bat +++ /dev/null @@ -1,2 +0,0 @@ - docker run --rm -it ruimarinho/mosquitto mosquitto_sub -h 192.168.0.201 -t warpzone/door/status - \ No newline at end of file diff --git a/warpapi/warpapi.py b/warpapi/warpapi.py index 4209936..abb17b6 100644 --- a/warpapi/warpapi.py +++ b/warpapi/warpapi.py @@ -1,11 +1,27 @@ +from datetime import datetime from flask import Flask from flask import request from flask import redirect from flask import render_template from flask import send_from_directory from flask import json -from flask_mqtt import Mqtt from logging.config import dictConfig +import os + +# Erlaubte Werte für zone_door_status +zone_door_status_values = ['OPEN', 'CLOSED', 'UNKNOWN'] + +# Aktueller Status +zone_door_status = 'UNKNOWN' + +# Letztes Update des Status +zone_door_lastupdate = datetime.min + +# Maximales ALter (in Minuten) für den Status +zone_door_maxage = 15 + +# Update Key für Updates +setstatus_update_key = os.getenv("UPDATE_KEY", "development_key") dictConfig({ 'version': 1, @@ -24,35 +40,25 @@ dictConfig({ }) app = Flask(__name__, static_url_path='') -app.config['MQTT_BROKER_URL'] = '192.168.0.201' -app.config['MQTT_BROKER_PORT'] = 1883 -app.config['MQTT_USERNAME'] = '' -app.config['MQTT_PASSWORD'] = '' -app.config['MQTT_KEEPALIVE'] = 5 -app.config['MQTT_TLS_ENABLED'] = False -zone_door_status = "UNKNOWN" -mqtt = Mqtt(app) if __name__ == "__main__": app.run() -@mqtt.on_connect() -def handle_connect(client, userdata, flags, rc): - app.logger.info("mqtt connected") - mqtt.subscribe("warpzone/door/status") - app.logger.info("mqtt subscribed: warpzone/door/status") +# Effektiver Status +# Wenn der letzte Status zu alt ist wird UNKNOWN zurückgegeben +def effective_zone_door_status(app): + global zone_door_status + global zone_door_lastupdate -@mqtt.on_message() -def handle_mqtt_message(client, userdata, message): - global zone_door_status - data = dict( - topic=message.topic, - payload=message.payload.decode() - ) - app.logger.info("mqtt message") - app.logger.info(data) - zone_door_status = message.payload.decode() - app.logger.info("zone_door_status = " + zone_door_status) + zone_door_alter = (datetime.now() - zone_door_lastupdate).total_seconds() / 60 + zone_door_alter_str = str(round(zone_door_alter,2)) + + app.logger.info("Current Zone Status = " + zone_door_status + " / Age = " + zone_door_alter_str + " Minutes / MaxAge = " + str(zone_door_maxage)) + + if zone_door_alter > zone_door_maxage: + return 'UNKNOWN' + else: + return zone_door_status # CORS Header setzen @app.after_request @@ -64,29 +70,63 @@ def after_request(response): # Startseite @app.route('/') def view_index(): - global zone_door_status - return 'Warpzone API, current status = ' + zone_door_status + ', see: https://gitlab.warpzone.ms/infrastruktur/warpapi/blob/master/README.md' + global zone_door_lastupdate + zone_door_status = effective_zone_door_status(app) + zone_door_alter = (datetime.now() - zone_door_lastupdate).total_seconds() / 60 + zone_door_alter_str = str(round(zone_door_alter,2)) + return 'Warpzone API, Status = ' + zone_door_status + ', letztes Update vor ' + zone_door_alter_str + ' Minuten, see: https://gitlab.warpzone.ms/infrastruktur/warpapi/blob/master/README.md' # Statische Dateien @app.route('/files/<path:path>') -def send_file(path): +def file(path): return send_from_directory('files', path) +# Statische Dateien +@app.route('/setstatus') +def setstatus(): + global zone_door_status + global zone_door_status_values + global zone_door_lastupdate + global setstatus_update_key + + if not 'newstatus' in request.args: + return "Error: Parameter 'newstatus' is missing", 500 + + if not 'update_key' in request.args: + return "Error: Parameter 'update_key' is missing", 500 + + newstatus = request.args['newstatus'] + update_key = request.args['update_key'] + + app.logger.info("Update Request, newstatus = " + newstatus + " / update_key = " + update_key) + + if newstatus not in zone_door_status_values: + app.logger.error("Update Request, newstatus is invalid") + return "Error: Parameter 'newstatus' is invalid", 500 + + if update_key != setstatus_update_key: + app.logger.error("Update Request, update_key is invalid, expected = " + setstatus_update_key) + return "Error: 'update_key' is invalid", 500 + + app.logger.info("Update Request is valid, Update Zone Status to " + newstatus) + + zone_door_status = newstatus + zone_door_lastupdate = datetime.now(); + return "OK, Status is set to: " + zone_door_status + # Statusanzeige auf der Webseite @app.route('/static') def view_static(): - global zone_door_status spaceopen = False - if zone_door_status == "OPEN": + if effective_zone_door_status(app) == "OPEN": spaceopen = True return render_template('static.html', open = spaceopen) # Statusanzeige auf der Webseite @app.route('/status') def data_status(): - global zone_door_status spaceopen = 0 - if zone_door_status == "OPEN": + if effective_zone_door_status(app) == "OPEN": spaceopen = 1 data = { "tuerOffen": spaceopen, @@ -116,9 +156,8 @@ def data_spaceapiphp(): # Implementierung der SpaceAPI @app.route('/spaceapi') def data_spaceapi(): - global zone_door_status spaceopen = False - if zone_door_status == "OPEN": + if effective_zone_door_status(app) == "OPEN": spaceopen = True data = { "api": "0.13", -- GitLab