docstrings in ki qualität, weil ki sie geschrieben hat
This commit is contained in:
@@ -43,6 +43,7 @@ def get_coffees():
|
|||||||
return coffees
|
return coffees
|
||||||
|
|
||||||
def create_toggle_machine():
|
def create_toggle_machine():
|
||||||
|
"""Create a command to toggle the coffee machine."""
|
||||||
randID = random.randint(1000, 9999)
|
randID = random.randint(1000, 9999)
|
||||||
fullCommand = {'command': 'toggle_machine', 'status': 'pending', 'command_id': randID}
|
fullCommand = {'command': 'toggle_machine', 'status': 'pending', 'command_id': randID}
|
||||||
conn = sqlite3.connect(DB_PATH)
|
conn = sqlite3.connect(DB_PATH)
|
||||||
@@ -60,6 +61,7 @@ def create_toggle_machine():
|
|||||||
return fullCommand
|
return fullCommand
|
||||||
|
|
||||||
def create_make_coffee():
|
def create_make_coffee():
|
||||||
|
"""Create a command to make coffee."""
|
||||||
randID = random.randint(1000, 9999)
|
randID = random.randint(1000, 9999)
|
||||||
fullCommand = {'command': 'make_coffee', 'status': 'pending', 'command_id': randID}
|
fullCommand = {'command': 'make_coffee', 'status': 'pending', 'command_id': randID}
|
||||||
conn = sqlite3.connect(DB_PATH)
|
conn = sqlite3.connect(DB_PATH)
|
||||||
@@ -75,6 +77,7 @@ def create_make_coffee():
|
|||||||
return fullCommand
|
return fullCommand
|
||||||
|
|
||||||
def create_coffee_entry():
|
def create_coffee_entry():
|
||||||
|
"""Create a coffee entry in the coffee database."""
|
||||||
conn = sqlite3.connect(DB_PATH_COFFEE)
|
conn = sqlite3.connect(DB_PATH_COFFEE)
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
cursor.execute("""
|
cursor.execute("""
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ from modules.socketio import resend_static_data
|
|||||||
from modules.db import create_coffee_entry
|
from modules.db import create_coffee_entry
|
||||||
|
|
||||||
def track_coffee_made(data, flanksUp, flanksDown):
|
def track_coffee_made(data, flanksUp, flanksDown):
|
||||||
|
"""Track if coffee has been made based on the ESP data."""
|
||||||
coffee_made = False
|
coffee_made = False
|
||||||
#logic for tracking coffee made
|
#logic for tracking coffee made
|
||||||
|
|
||||||
@@ -34,18 +35,21 @@ def track_coffee_made(data, flanksUp, flanksDown):
|
|||||||
return
|
return
|
||||||
|
|
||||||
def track_error_water(data, flanksUp, flanksDown):
|
def track_error_water(data, flanksUp, flanksDown):
|
||||||
|
"""Track if there could be an error with water."""
|
||||||
water = load_dict("water")
|
water = load_dict("water")
|
||||||
if water["fill"] <= 7:
|
if water["fill"] <= 7:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def track_error_beans(data, flanksUp, flanksDown):
|
def track_error_beans(data, flanksUp, flanksDown):
|
||||||
|
"""Track if there could be an error with beans."""
|
||||||
beans = load_dict("beans")
|
beans = load_dict("beans")
|
||||||
if beans["fill"] <= 7:
|
if beans["fill"] <= 7:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def track_error(data, flanksUp, flanksDown):
|
def track_error(data, flanksUp, flanksDown):
|
||||||
|
"""Backrrack an Coffee machine error."""
|
||||||
if track_error_water(data, flanksUp, flanksDown):
|
if track_error_water(data, flanksUp, flanksDown):
|
||||||
return "Wasser Leer"
|
return "Wasser Leer"
|
||||||
elif track_error_beans(data, flanksUp, flanksDown):
|
elif track_error_beans(data, flanksUp, flanksDown):
|
||||||
@@ -53,6 +57,8 @@ def track_error(data, flanksUp, flanksDown):
|
|||||||
return "Unbekannter Fehler"
|
return "Unbekannter Fehler"
|
||||||
|
|
||||||
def refactor_and_use_esp_data(data):
|
def refactor_and_use_esp_data(data):
|
||||||
|
"""Refactor and use the ESP data to update the machine state.
|
||||||
|
Calls track_coffee_made() and track_error functions()."""
|
||||||
# global oldDataSet
|
# global oldDataSet
|
||||||
if 'oldDataSet' not in globals() or oldDataSet is None:
|
if 'oldDataSet' not in globals() or oldDataSet is None:
|
||||||
oldDataSet = data # Initialize oldDataSet with default values
|
oldDataSet = data # Initialize oldDataSet with default values
|
||||||
|
|||||||
@@ -7,12 +7,15 @@ BASE_PATH = os.path.abspath(BASE_PATH)
|
|||||||
|
|
||||||
|
|
||||||
def save_dict(name, data):
|
def save_dict(name, data):
|
||||||
|
"""Saves a dictionary to a JSON file."""
|
||||||
path = os.path.join(BASE_PATH, f"{name}.json")
|
path = os.path.join(BASE_PATH, f"{name}.json")
|
||||||
os.makedirs(BASE_PATH, exist_ok=True)
|
os.makedirs(BASE_PATH, exist_ok=True)
|
||||||
with open(path, "w") as f:
|
with open(path, "w") as f:
|
||||||
json.dump(data, f, default=str, indent=2)
|
json.dump(data, f, default=str, indent=2)
|
||||||
|
|
||||||
def load_dict(name):
|
def load_dict(name):
|
||||||
|
"""Loads a dictionary from a JSON file.
|
||||||
|
returns the data or an empty dict if the file does not exist."""
|
||||||
path = os.path.join(BASE_PATH, f"{name}.json")
|
path = os.path.join(BASE_PATH, f"{name}.json")
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
with open(path, "r") as f:
|
with open(path, "r") as f:
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ socketio = SocketIO(cors_allowed_origins="*", async_mode='threading')
|
|||||||
|
|
||||||
# function to change the datetime format to isoformat because json does not support datetime
|
# function to change the datetime format to isoformat because json does not support datetime
|
||||||
def convert_datetimes(obj):
|
def convert_datetimes(obj):
|
||||||
|
"""Convert datetime objects in a dict or list to a specific string format."""
|
||||||
if isinstance(obj, dict):
|
if isinstance(obj, dict):
|
||||||
return {k: convert_datetimes(v) for k, v in obj.items()}
|
return {k: convert_datetimes(v) for k, v in obj.items()}
|
||||||
elif isinstance(obj, list):
|
elif isinstance(obj, list):
|
||||||
@@ -19,6 +20,7 @@ def convert_datetimes(obj):
|
|||||||
|
|
||||||
|
|
||||||
def resend_static_data():
|
def resend_static_data():
|
||||||
|
"""Resend static data to the frontend via SocketIO."""
|
||||||
water = load_dict("water")
|
water = load_dict("water")
|
||||||
beans = load_dict("beans")
|
beans = load_dict("beans")
|
||||||
machine = load_dict("machine")
|
machine = load_dict("machine")
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ class User:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def validate_user(username, userid):
|
def validate_user(username, userid):
|
||||||
"""Prüft, ob ein Benutzer mit E-Mail + Passwort existiert"""
|
"""Prüft, ob ein Benutzer mit E-Mail + ID existiert"""
|
||||||
db_path = os.path.join("db", "user.db")
|
db_path = os.path.join("db", "user.db")
|
||||||
with sqlite3.connect(db_path) as conn:
|
with sqlite3.connect(db_path) as conn:
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ MQTT_TOPIC = "coffee/command"
|
|||||||
|
|
||||||
@esp.route('/online', methods=['POST'])
|
@esp.route('/online', methods=['POST'])
|
||||||
def esp_online():
|
def esp_online():
|
||||||
|
"""Endpoint to mark the ESP as online and update its connection info."""
|
||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
sender_ip = request.headers.get('X-Forwarded-For', request.remote_addr)
|
sender_ip = request.headers.get('X-Forwarded-For', request.remote_addr)
|
||||||
esp_ip = data.get("ip", "unknown")
|
esp_ip = data.get("ip", "unknown")
|
||||||
@@ -32,6 +33,7 @@ def esp_online():
|
|||||||
|
|
||||||
@esp.route('/toggle-machine', methods=['POST'])
|
@esp.route('/toggle-machine', methods=['POST'])
|
||||||
def toggle_machine():
|
def toggle_machine():
|
||||||
|
"""Endpoint to toggle the coffee machine state."""
|
||||||
fullCommand = create_toggle_machine()
|
fullCommand = create_toggle_machine()
|
||||||
|
|
||||||
new_status = load_dict("machine")
|
new_status = load_dict("machine")
|
||||||
@@ -48,6 +50,7 @@ def toggle_machine():
|
|||||||
|
|
||||||
@esp.route('/make_coffee', methods=['POST'])
|
@esp.route('/make_coffee', methods=['POST'])
|
||||||
def make_coffee():
|
def make_coffee():
|
||||||
|
"""Endpoint to create a command to make coffee."""
|
||||||
fullCommand = create_make_coffee()
|
fullCommand = create_make_coffee()
|
||||||
|
|
||||||
client = mqtt.Client()
|
client = mqtt.Client()
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import random
|
|||||||
|
|
||||||
@unsecure.route('/')
|
@unsecure.route('/')
|
||||||
def index():
|
def index():
|
||||||
|
"""Render the main page with user validation."""
|
||||||
username = request.args.get('username')
|
username = request.args.get('username')
|
||||||
userid = request.args.get('userid')
|
userid = request.args.get('userid')
|
||||||
|
|
||||||
@@ -32,6 +33,7 @@ def index():
|
|||||||
|
|
||||||
@unsecure.route('/verify', methods=['POST'])
|
@unsecure.route('/verify', methods=['POST'])
|
||||||
def verify():
|
def verify():
|
||||||
|
"""Verify user credentials and redirect accordingly."""
|
||||||
username = request.args.get('username')
|
username = request.args.get('username')
|
||||||
password = request.args.get('pass')
|
password = request.args.get('pass')
|
||||||
|
|
||||||
@@ -48,6 +50,7 @@ def verify():
|
|||||||
|
|
||||||
@unsecure.route('/register', methods=['POST'])
|
@unsecure.route('/register', methods=['POST'])
|
||||||
def register():
|
def register():
|
||||||
|
"""Register a new user and redirect to the login page."""
|
||||||
username = request.args.get('username')
|
username = request.args.get('username')
|
||||||
password = request.args.get('pass')
|
password = request.args.get('pass')
|
||||||
userid = random.randint(10000, 99999)
|
userid = random.randint(10000, 99999)
|
||||||
@@ -61,10 +64,12 @@ def register():
|
|||||||
|
|
||||||
@unsecure.route('/login')
|
@unsecure.route('/login')
|
||||||
def login():
|
def login():
|
||||||
|
"""Render the login page."""
|
||||||
return render_template('login.html')
|
return render_template('login.html')
|
||||||
|
|
||||||
@unsecure.route('/refill-water', methods=['POST'])
|
@unsecure.route('/refill-water', methods=['POST'])
|
||||||
def update_water():
|
def update_water():
|
||||||
|
"""Refill the water tank and update the water status."""
|
||||||
water = load_dict("water")
|
water = load_dict("water")
|
||||||
water["lastFilled"] = datetime.now()
|
water["lastFilled"] = datetime.now()
|
||||||
water["fill"] = 100
|
water["fill"] = 100
|
||||||
@@ -76,6 +81,7 @@ def update_water():
|
|||||||
|
|
||||||
@unsecure.route('/refill-beans', methods=['POST'])
|
@unsecure.route('/refill-beans', methods=['POST'])
|
||||||
def update_beans():
|
def update_beans():
|
||||||
|
"""Refill the beans container and update the beans status."""
|
||||||
beans = load_dict("beans")
|
beans = load_dict("beans")
|
||||||
beans["lastFilled"] = datetime.now()
|
beans["lastFilled"] = datetime.now()
|
||||||
beans["fill"] = 100
|
beans["fill"] = 100
|
||||||
@@ -87,14 +93,17 @@ def update_beans():
|
|||||||
|
|
||||||
@unsecure.route('/coffees-made')
|
@unsecure.route('/coffees-made')
|
||||||
def coffees_made():
|
def coffees_made():
|
||||||
|
"""Render the coffees made page with a list of coffees."""
|
||||||
coffees = get_coffees()
|
coffees = get_coffees()
|
||||||
return render_template('coffees.html', title='gimmiCoffee', coffees=coffees)
|
return render_template('coffees.html', title='gimmiCoffee', coffees=coffees)
|
||||||
|
|
||||||
@unsecure.route('/water')
|
@unsecure.route('/water')
|
||||||
def water():
|
def water():
|
||||||
|
"""Render the water status page."""
|
||||||
water = load_dict("water")
|
water = load_dict("water")
|
||||||
return render_template('water.html', title='gimmiCoffee', last_filled=datetime.strptime(water["lastFilled"], "%Y-%m-%d %H:%M:%S.%f"), current_level=water["fill"], total_refills=water["refilled"], coffees_made=water["coffeesOnFill"])
|
return render_template('water.html', title='gimmiCoffee', last_filled=datetime.strptime(water["lastFilled"], "%Y-%m-%d %H:%M:%S.%f"), current_level=water["fill"], total_refills=water["refilled"], coffees_made=water["coffeesOnFill"])
|
||||||
@unsecure.route('/beans')
|
@unsecure.route('/beans')
|
||||||
def beans():
|
def beans():
|
||||||
|
"""Render the beans status page."""
|
||||||
beans = load_dict("beans")
|
beans = load_dict("beans")
|
||||||
return render_template('beans.html', title='gimmiCoffee', last_filled=datetime.strptime(beans["lastFilled"], "%Y-%m-%d %H:%M:%S.%f"), current_level=beans["fill"], total_refills=beans["refilled"], coffees_made=beans["coffeesOnFill"])
|
return render_template('beans.html', title='gimmiCoffee', last_filled=datetime.strptime(beans["lastFilled"], "%Y-%m-%d %H:%M:%S.%f"), current_level=beans["fill"], total_refills=beans["refilled"], coffees_made=beans["coffeesOnFill"])
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ app.register_blueprint(esp)
|
|||||||
|
|
||||||
# MQTT Callback-Funktionen
|
# MQTT Callback-Funktionen
|
||||||
def on_connect(client, userdata, flags, rc):
|
def on_connect(client, userdata, flags, rc):
|
||||||
|
"""Callback-Funktion, die aufgerufen wird, wenn der Client sich mit dem Broker verbindet."""
|
||||||
print(f"[MQTT] Verbunden mit Code {rc}")
|
print(f"[MQTT] Verbunden mit Code {rc}")
|
||||||
client.subscribe(MQTT_TOPIC_SUB)
|
client.subscribe(MQTT_TOPIC_SUB)
|
||||||
client.subscribe(MQTT_TOPIC_RETURN)
|
client.subscribe(MQTT_TOPIC_RETURN)
|
||||||
@@ -39,6 +40,7 @@ def on_connect(client, userdata, flags, rc):
|
|||||||
print(f"[MQTT] Subscribed to topic: {MQTT_TOPIC_SUB}")
|
print(f"[MQTT] Subscribed to topic: {MQTT_TOPIC_SUB}")
|
||||||
|
|
||||||
def on_message(client, userdata, msg):
|
def on_message(client, userdata, msg):
|
||||||
|
"""Callback-Funktion, die aufgerufen wird, wenn eine Nachricht empfangen wird."""
|
||||||
if msg.topic == MQTT_TOPIC_SUB:
|
if msg.topic == MQTT_TOPIC_SUB:
|
||||||
print(f"[MQTT] Nachricht empfangen: {msg.topic} -> {msg.payload.decode()}")
|
print(f"[MQTT] Nachricht empfangen: {msg.topic} -> {msg.payload.decode()}")
|
||||||
esp_conn_infos["last_seen"] = datetime.now()
|
esp_conn_infos["last_seen"] = datetime.now()
|
||||||
@@ -60,6 +62,7 @@ def on_message(client, userdata, msg):
|
|||||||
|
|
||||||
# MQTT-Thread
|
# MQTT-Thread
|
||||||
def mqtt_thread():
|
def mqtt_thread():
|
||||||
|
"""Thread, der die MQTT-Verbindung aufbaut und Nachrichten verarbeitet."""
|
||||||
client = mqtt.Client()
|
client = mqtt.Client()
|
||||||
client.on_connect = on_connect
|
client.on_connect = on_connect
|
||||||
client.on_message = on_message
|
client.on_message = on_message
|
||||||
@@ -68,7 +71,7 @@ def mqtt_thread():
|
|||||||
|
|
||||||
# DB-Cleanup-Thread
|
# DB-Cleanup-Thread
|
||||||
def cleanup_old_commands():
|
def cleanup_old_commands():
|
||||||
|
"""Thread, der alle 5 Minuten die Datenbank nach 'pending' Befehlen durchsucht und diese auf 'failed' setzt, wenn sie älter als 5 Minuten sind."""
|
||||||
db_path = os.path.join(os.path.dirname(__file__), "db", "commands.db")
|
db_path = os.path.join(os.path.dirname(__file__), "db", "commands.db")
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
@@ -97,6 +100,7 @@ def cleanup_old_commands():
|
|||||||
|
|
||||||
# Clear commands DB
|
# Clear commands DB
|
||||||
def clear_commands_db():
|
def clear_commands_db():
|
||||||
|
"""Löscht alle Einträge in der commands- und coffee-Tabelle der Datenbank."""
|
||||||
import os
|
import os
|
||||||
import sqlite3
|
import sqlite3
|
||||||
|
|
||||||
@@ -121,6 +125,7 @@ def clear_commands_db():
|
|||||||
|
|
||||||
# Motitior ESP-Connection
|
# Motitior ESP-Connection
|
||||||
def monitor_esp_connection():
|
def monitor_esp_connection():
|
||||||
|
"""Überwacht die Verbindung zum ESP und setzt die Verbindung auf ungültig, wenn der ESP länger als 3 Minuten nicht gesehen wurde."""
|
||||||
while True:
|
while True:
|
||||||
if esp_conn_infos["last_seen"]:
|
if esp_conn_infos["last_seen"]:
|
||||||
time_diff = datetime.now() - esp_conn_infos["last_seen"]
|
time_diff = datetime.now() - esp_conn_infos["last_seen"]
|
||||||
|
|||||||
Reference in New Issue
Block a user