diff --git a/cleaning_logs.db b/cleaning_logs.db
new file mode 100644
index 0000000..99a8d6c
Binary files /dev/null and b/cleaning_logs.db differ
diff --git a/dashboard.py b/dashboard.py
new file mode 100644
index 0000000..04cbd3f
--- /dev/null
+++ b/dashboard.py
@@ -0,0 +1,323 @@
+import sqlite3
+from flask import Flask, render_template_string, jsonify
+from datetime import datetime, date
+
+app = Flask(__name__)
+DB_FILE = "cleaning_logs.db"
+
+# Room definitions
+BUILDINGS = {
+ "Haus A-C": [
+ list(range(101, 131)),
+ list(range(201, 231)),
+ list(range(301, 331))
+ ],
+ "Haus D-F": [
+ list(range(131, 151)),
+ list(range(231, 251)),
+ list(range(331, 351))
+ ],
+ "Haus O": [
+ list(range(401, 413)),
+ list(range(420, 436)),
+ list(range(440, 457))
+ ]
+}
+
+def get_all_defined_rooms():
+ """Get a set of all room numbers defined in buildings"""
+ rooms = set()
+ for floors in BUILDINGS.values():
+ for floor in floors:
+ rooms.update(str(r) for r in floor)
+ return rooms
+
+def get_room_statuses():
+ """Returns dict: {room_number: (last_cleaned_time, is_today)}"""
+ today = date.today().strftime("%Y-%m-%d")
+
+ with sqlite3.connect(DB_FILE) as conn:
+ cursor = conn.execute("""
+ SELECT room_number, MAX(cleaned_at) as last_cleaned
+ FROM cleaning_events
+ GROUP BY room_number
+ """)
+ rows = cursor.fetchall()
+
+ statuses = {}
+ for room, last_cleaned in rows:
+ is_today = last_cleaned.startswith(today) if last_cleaned else False
+ statuses[room] = {
+ "is_today": is_today,
+ "last_cleaned": last_cleaned
+ }
+
+ return statuses
+
+def get_special_rooms(statuses):
+ """Get rooms that aren't in any defined building"""
+ defined_rooms = get_all_defined_rooms()
+ special_rooms = []
+
+ for room_number in statuses.keys():
+ if room_number not in defined_rooms:
+ special_rooms.append(room_number)
+
+ return sorted(special_rooms)
+
+@app.route('/')
+def dashboard():
+ statuses = get_room_statuses()
+ special_rooms = get_special_rooms(statuses)
+ return render_template_string(
+ TEMPLATE,
+ buildings=BUILDINGS,
+ statuses=statuses,
+ special_rooms=special_rooms
+ )
+
+@app.route('/api/status')
+def api_status():
+ """API endpoint for live updates"""
+ statuses = get_room_statuses()
+ special_rooms = get_special_rooms(statuses)
+ return jsonify({
+ "statuses": statuses,
+ "special_rooms": special_rooms
+ })
+
+TEMPLATE = '''
+
+
+
+ Room Cleaning Dashboard
+
+
+
+ đŸ§¹ Room Cleaning Status
+
+
+
+
+
+ {% for building_name, floors in buildings.items() %}
+
+
{{ building_name }}
+ {% for floor in floors %}
+
+
Etage {{ loop.index }}
+
+ {% for room in floor %}
+ {% set room_str = room|string %}
+ {% set status = statuses.get(room_str, {"is_today": False, "last_cleaned": None}) %}
+
+ {{ room }}
+
+ {% if status.last_cleaned %}
+ {{ status.last_cleaned[5:10] }}
{{ status.last_cleaned[11:16] }}
+ {% else %}Never{% endif %}
+
+
+ {% endfor %}
+
+
+ {% endfor %}
+
+ {% endfor %}
+
+ {% if special_rooms %}
+
+
Sonderräume
+
+
+ {% for room in special_rooms %}
+ {% set status = statuses.get(room, {"is_today": False, "last_cleaned": None}) %}
+
+ {{ room }}
+
+ {% if status.last_cleaned %}
+ {{ status.last_cleaned[5:10] }}
{{ status.last_cleaned[11:16] }}
+ {% else %}Never{% endif %}
+
+
+ {% endfor %}
+
+
+
+ {% endif %}
+
+
+
+
+'''
+
+if __name__ == '__main__':
+ app.run(host='0.0.0.0', port=5001, debug=True)
diff --git a/flake.lock b/flake.lock
new file mode 100644
index 0000000..6f6bfa6
--- /dev/null
+++ b/flake.lock
@@ -0,0 +1,27 @@
+{
+ "nodes": {
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1769461804,
+ "narHash": "sha256-msG8SU5WsBUfVVa/9RPLaymvi5bI8edTavbIq3vRlhI=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "bfc1b8a4574108ceef22f02bafcf6611380c100d",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "nixpkgs": "nixpkgs"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/test.py b/test.py
index 7f5d4ea..eee6bce 100644
--- a/test.py
+++ b/test.py
@@ -3,37 +3,42 @@ from flask import Flask, request
from datetime import datetime
app = Flask(__name__)
-DB_FILE = "logs.db"
+DB_FILE = "cleaning_logs.db"
def init_db():
with sqlite3.connect(DB_FILE) as conn:
conn.execute('''
- CREATE TABLE IF NOT EXISTS post_logs (
+ CREATE TABLE IF NOT EXISTS cleaning_events (
id INTEGER PRIMARY KEY AUTOINCREMENT,
- timestamp TEXT,
- content_type TEXT,
- body TEXT
+ room_number TEXT,
+ cleaned_at TEXT
)
''')
@app.route('/', methods=['POST'])
def handle_post():
- content_type = request.headers.get('Content-Type')
- body = request.get_data(as_text=True)
- timestamp = datetime.now().isoformat()
+ # Extract the room number from the POST body
+ # .strip('"') removes extra quotes if the sender includes them
+ room_number = request.get_data(as_text=True).strip().strip('"')
+
+ if not room_number:
+ return "Missing room number", 400
- # Log to Console
- print(f"[{timestamp}] Logging POST: {body[:50]}...")
+ timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
- # Log to SQLite
+ # Log to Console for your visibility
+ print(f"Room {room_number} marked as cleaned at {timestamp}")
+
+ # Save to SQLite
with sqlite3.connect(DB_FILE) as conn:
conn.execute(
- "INSERT INTO post_logs (timestamp, content_type, body) VALUES (?, ?, ?)",
- (timestamp, content_type, body)
+ "INSERT INTO cleaning_events (room_number, cleaned_at) VALUES (?, ?)",
+ (room_number, timestamp)
)
- return "Logged successfully", 200
+ return f"Room {room_number} logged.", 200
if __name__ == '__main__':
init_db()
- app.run(host='0.0.0.0', port=5000, debug=True)
+ # Binding to 0.0.0.0 so devices on your network can reach it
+ app.run(host='0.0.0.0', port=5000)