Initial commit - copied workspace after database cleanup

This commit is contained in:
RobbStarkAustria
2025-10-10 15:20:14 +00:00
commit 1efe40a03b
142 changed files with 23625 additions and 0 deletions

4
listener/.dockerignore Normal file
View File

@@ -0,0 +1,4 @@
__pycache__/
*.pyc
*.pyo
*.log

16
listener/Dockerfile Normal file
View File

@@ -0,0 +1,16 @@
# Listener Dockerfile
FROM python:3.13-slim
WORKDIR /app
COPY listener/requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
# Mosquitto-Tools für MQTT-Tests installieren
RUN apt-get update && apt-get install -y --no-install-recommends mosquitto-clients && rm -rf /var/lib/apt/lists/*
COPY listener/ ./listener
COPY models/ ./models
ENV PYTHONPATH=/app
CMD ["python", "listener/listener.py"]

102
listener/listener.py Normal file
View File

@@ -0,0 +1,102 @@
import os
import json
import logging
import datetime
import paho.mqtt.client as mqtt
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from models.models import Client
if os.getenv("ENV", "development") == "development":
from dotenv import load_dotenv
load_dotenv(".env")
# ENV-abhängige Konfiguration
ENV = os.getenv("ENV", "development")
LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO" if ENV == "production" else "DEBUG")
DB_URL = os.environ.get(
"DB_CONN", "mysql+pymysql://user:password@db/infoscreen")
# Logging
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s [%(levelname)s] %(message)s')
# DB-Konfiguration
engine = create_engine(DB_URL)
Session = sessionmaker(bind=engine)
def on_message(client, userdata, msg):
topic = msg.topic
logging.debug(f"Empfangene Nachricht auf Topic: {topic}")
try:
# Heartbeat-Handling
if topic.startswith("infoscreen/") and topic.endswith("/heartbeat"):
uuid = topic.split("/")[1]
session = Session()
client_obj = session.query(Client).filter_by(uuid=uuid).first()
if client_obj:
client_obj.last_alive = datetime.datetime.now(datetime.UTC)
session.commit()
logging.info(
f"Heartbeat von {uuid} empfangen, last_alive (UTC) aktualisiert.")
session.close()
return
# Discovery-Handling
if topic == "infoscreen/discovery":
payload = json.loads(msg.payload.decode())
logging.info(f"Discovery empfangen: {payload}")
if "uuid" in payload:
uuid = payload["uuid"]
session = Session()
existing = session.query(Client).filter_by(uuid=uuid).first()
if not existing:
new_client = Client(
uuid=uuid,
hardware_token=payload.get("hardware_token"),
ip=payload.get("ip"),
type=payload.get("type"),
hostname=payload.get("hostname"),
os_version=payload.get("os_version"),
software_version=payload.get("software_version"),
macs=",".join(payload.get("macs", [])),
model=payload.get("model"),
registration_time=datetime.datetime.now(datetime.UTC),
)
session.add(new_client)
session.commit()
logging.info(f"Neuer Client registriert: {uuid}")
else:
logging.info(f"Client bereits bekannt: {uuid}")
session.close()
# Discovery-ACK senden
ack_topic = f"infoscreen/{uuid}/discovery_ack"
client.publish(ack_topic, json.dumps({"status": "ok"}))
logging.info(f"Discovery-ACK gesendet an {ack_topic}")
else:
logging.warning("Discovery ohne UUID empfangen, ignoriert.")
except Exception as e:
logging.error(f"Fehler bei Verarbeitung: {e}")
def main():
mqtt_client = mqtt.Client(protocol=mqtt.MQTTv311, callback_api_version=2)
mqtt_client.on_message = on_message
mqtt_client.connect("mqtt", 1883)
mqtt_client.subscribe("infoscreen/discovery")
mqtt_client.subscribe("infoscreen/+/heartbeat")
logging.info(
"Listener gestartet und abonniert auf infoscreen/discovery und infoscreen/+/heartbeat")
mqtt_client.loop_forever()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,4 @@
paho-mqtt>=2.0
SQLAlchemy>=2.0
pymysql
python-dotenv