make listener robust to bad data
This commit is contained in:
1546
dashboard/package-lock.json
generated
1546
dashboard/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -31,6 +31,13 @@
|
||||
"commitId": "a1b2c3d4e5f6"
|
||||
},
|
||||
"changelog": [
|
||||
{
|
||||
"version": "2025.1.0-alpha.4",
|
||||
"date": "2025-09-01",
|
||||
"changes": [
|
||||
"Grundstruktur für Deployment getestet und optimiert."
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "2025.1.0-alpha.3",
|
||||
"date": "2025-08-30",
|
||||
|
||||
@@ -123,21 +123,18 @@ services:
|
||||
- infoscreen-net
|
||||
|
||||
scheduler:
|
||||
image: ghcr.io/robbstarkaustria/infoscreen-scheduler:latest # Oder wo auch immer Ihre Images liegen
|
||||
image: ghcr.io/robbstarkaustria/infoscreen-scheduler:latest
|
||||
container_name: infoscreen-scheduler
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
# HINZUGEFÜGT: Stellt sicher, dass die DB vor dem Scheduler startet
|
||||
db:
|
||||
condition: service_healthy
|
||||
mqtt:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
# HINZUGEFÜGT: Datenbank-Verbindungsstring
|
||||
DB_CONN: "mysql+pymysql://${DB_USER}:${DB_PASSWORD}@db/${DB_NAME}"
|
||||
DB_USER: ${DB_USER}
|
||||
DB_PASSWORD: ${DB_PASSWORD}
|
||||
DB_NAME: ${DB_NAME}
|
||||
DB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
|
||||
MQTT_BROKER_URL: mqtt
|
||||
MQTT_PORT: 1883
|
||||
networks:
|
||||
- infoscreen-net
|
||||
|
||||
@@ -5,8 +5,8 @@ networks:
|
||||
services:
|
||||
listener:
|
||||
build:
|
||||
context: ./listener
|
||||
dockerfile: Dockerfile
|
||||
context: .
|
||||
dockerfile: listener/Dockerfile
|
||||
image: infoscreen-listener:latest
|
||||
container_name: infoscreen-listener
|
||||
restart: unless-stopped
|
||||
@@ -16,6 +16,7 @@ services:
|
||||
mqtt:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
- DB_CONN=mysql+pymysql://${DB_USER}:${DB_PASSWORD}@db/${DB_NAME}
|
||||
- DB_URL=mysql+pymysql://${DB_USER}:${DB_PASSWORD}@db/${DB_NAME}
|
||||
# 🔧 ENTFERNT: Volume-Mount ist nur für die Entwicklung
|
||||
networks:
|
||||
@@ -80,8 +81,8 @@ services:
|
||||
|
||||
server:
|
||||
build:
|
||||
context: ./server
|
||||
dockerfile: Dockerfile
|
||||
context: .
|
||||
dockerfile: server/Dockerfile
|
||||
image: infoscreen-api:latest
|
||||
container_name: infoscreen-api
|
||||
restart: unless-stopped
|
||||
@@ -111,8 +112,8 @@ services:
|
||||
# ✅ GEÄNDERT: Dashboard jetzt mit Node.js/React statt Python/Dash
|
||||
dashboard:
|
||||
build:
|
||||
context: ./dashboard
|
||||
dockerfile: Dockerfile
|
||||
context: .
|
||||
dockerfile: dashboard/Dockerfile
|
||||
# 🔧 VEREINFACHT: Build-Args werden durch Umgebungsvariablen gesetzt
|
||||
args:
|
||||
- VITE_API_URL=${API_URL}
|
||||
@@ -140,22 +141,23 @@ services:
|
||||
|
||||
scheduler:
|
||||
build:
|
||||
context: ./scheduler
|
||||
dockerfile: Dockerfile
|
||||
dockerfile: scheduler/Dockerfile
|
||||
image: infoscreen-scheduler:latest
|
||||
container_name: infoscreen-scheduler
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
# HINZUGEFÜGT: Stellt sicher, dass die DB vor dem Scheduler startet
|
||||
db:
|
||||
condition: service_healthy
|
||||
mqtt:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
DB_CONN: "mysql+pymysql://${DB_USER}:${DB_PASSWORD}@db/${DB_NAME}"
|
||||
MQTT_BROKER_URL: mqtt
|
||||
MQTT_PORT: 1883
|
||||
# HINZUGEFÜGT: Datenbank-Verbindungsstring
|
||||
- DB_CONN=mysql+pymysql://${DB_USER}:${DB_PASSWORD}@db/${DB_NAME}
|
||||
- MQTT_PORT=1883
|
||||
networks:
|
||||
- infoscreen-net
|
||||
|
||||
volumes:
|
||||
db-data:
|
||||
server-pip-cache:
|
||||
db-data:
|
||||
|
||||
@@ -50,32 +50,35 @@ def on_message(client, userdata, msg):
|
||||
# Discovery-Handling
|
||||
payload = json.loads(msg.payload.decode())
|
||||
logging.info(f"Discovery empfangen: {payload}")
|
||||
session = Session()
|
||||
existing = session.query(Client).filter_by(
|
||||
uuid=payload["uuid"]).first()
|
||||
if not existing:
|
||||
new_client = Client(
|
||||
uuid=payload.get("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: {payload['uuid']}")
|
||||
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.info(f"Client bereits bekannt: {payload['uuid']}")
|
||||
session.close()
|
||||
# Discovery-ACK senden
|
||||
ack_topic = f"infoscreen/{payload['uuid']}/discovery_ack"
|
||||
client.publish(ack_topic, json.dumps({"status": "ok"}))
|
||||
logging.info(f"Discovery-ACK gesendet an {ack_topic}")
|
||||
logging.warning("Discovery ohne UUID empfangen, ignoriert.")
|
||||
except Exception as e:
|
||||
logging.error(f"Fehler bei Verarbeitung: {e}")
|
||||
|
||||
|
||||
@@ -5,4 +5,4 @@ RUN pip install --no-cache-dir -r requirements.txt
|
||||
COPY scheduler/ ./scheduler
|
||||
COPY models/ ./models
|
||||
ENV PYTHONPATH=/app
|
||||
CMD ["python", "scheduler/scheduler.py"]
|
||||
CMD ["python", "-m", "scheduler.scheduler"]
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import os
|
||||
import logging
|
||||
from db_utils import get_active_events
|
||||
from .db_utils import get_active_events
|
||||
import paho.mqtt.client as mqtt
|
||||
import json
|
||||
import datetime
|
||||
|
||||
@@ -20,16 +20,16 @@ ENV LANG=de_DE.UTF-8 \
|
||||
LC_ALL=de_DE.UTF-8
|
||||
|
||||
# Setze das Arbeitsverzeichnis auf den Workspace-Root, passend zu den Mounts.
|
||||
WORKDIR /workspace
|
||||
WORKDIR /app
|
||||
|
||||
# Kopiere die Anforderungsdateien in das korrekte Unterverzeichnis.
|
||||
# ✅ KORRIGIERT: Pfade sind jetzt relativ zum Build-Kontext (dem 'server'-Verzeichnis)
|
||||
COPY requirements.txt requirements-dev.txt ./
|
||||
COPY server/requirements.txt server/requirements-dev.txt ./server/
|
||||
|
||||
# Installiere die Python-Abhängigkeiten
|
||||
RUN pip install --upgrade pip \
|
||||
&& pip install --no-cache-dir -r requirements.txt \
|
||||
&& pip install --no-cache-dir -r requirements-dev.txt
|
||||
&& pip install --no-cache-dir -r server/requirements.txt \
|
||||
&& pip install --no-cache-dir -r server/requirements-dev.txt
|
||||
|
||||
# Das Kopieren des Codes ist nicht nötig, da das Verzeichnis gemountet wird.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user