From 096bf367aa50b7af83494db7ed197fde16d30a91 Mon Sep 17 00:00:00 2001 From: Peter Siegmund Date: Thu, 15 Jan 2026 23:05:37 +0100 Subject: [PATCH] code cleanup Signed-off-by: Peter Siegmund --- .gitea/workflows/deploy.yml | 11 ++++++++- .gitea/workflows/version_env.sh | 11 +++++++++ Dockerfile | 32 ++++++++++++++++++++---- bambu.py | 44 +++++++++++++++++---------------- requirements.txt | 2 ++ 5 files changed, 73 insertions(+), 27 deletions(-) create mode 100644 .gitea/workflows/version_env.sh create mode 100644 requirements.txt diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 46a589a..077ed6a 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -17,6 +17,7 @@ jobs: uses: docker/setup-buildx-action@v2 - name: Set Registry Domain + # Extracts the registry domain from the server URL run: | REGISTRY_DOMAIN=$(echo "${{ github.server_url }}" | sed 's|https://||' | sed 's|http://||') echo "REGISTRY_DOMAIN=$REGISTRY_DOMAIN" >> $GITHUB_ENV @@ -28,6 +29,10 @@ jobs: username: ${{ secrets.REGISTRY_USER }} password: ${{ secrets.REGISTRY_PASSWORD }} + - name: Set version tags from Dockerfile + # Reads version from Dockerfile and sets MAJOR, MAJOR_MINOR, VERSION + run: ./.gitea/workflows/version_env.sh + - name: Build and push Docker image (multi-arch) uses: docker/build-push-action@v5 with: @@ -35,4 +40,8 @@ jobs: file: ./Dockerfile push: true platforms: linux/amd64,linux/arm64 - tags: ${{ env.REGISTRY_DOMAIN }}/${{ github.repository }}:latest + tags: | + ${{ env.REGISTRY_DOMAIN }}/${{ github.repository }}:latest + ${{ env.REGISTRY_DOMAIN }}/${{ github.repository }}:${{ env.MAJOR }} + ${{ env.REGISTRY_DOMAIN }}/${{ github.repository }}:${{ env.MAJOR_MINOR }} + ${{ env.REGISTRY_DOMAIN }}/${{ github.repository }}:${{ env.VERSION }} diff --git a/.gitea/workflows/version_env.sh b/.gitea/workflows/version_env.sh new file mode 100644 index 0000000..ae25a61 --- /dev/null +++ b/.gitea/workflows/version_env.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +# version_env.sh: Reads the version from the Dockerfile and sets MAJOR, MAJOR_MINOR, VERSION as environment variables + +VERSION=$(grep 'org.opencontainers.image.version' Dockerfile | cut -d'=' -f2 | tr -d '"') +MAJOR=$(echo "$VERSION" | cut -d. -f1) +MAJOR_MINOR=$(echo "$VERSION" | awk -F. '{print $1 "." $2}') + +echo "VERSION=$VERSION" >> $GITHUB_ENV +echo "MAJOR=$MAJOR" >> $GITHUB_ENV +echo "MAJOR_MINOR=$MAJOR_MINOR" >> $GITHUB_ENV diff --git a/Dockerfile b/Dockerfile index b1b9b3e..f311210 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,33 @@ -# Dockerfile für bambu.py -FROM python:3.11-slim +## Dockerfile for bambu.py +FROM python:3.11.7-alpine + +LABEL maintainer="Peter Siegmund " +LABEL org.opencontainers.image.source="https://git.mars3142.dev/mars3142/bambu_mqtt" +LABEL org.opencontainers.image.description="MQTT-Bridge für BambuLab Drucker" +LABEL org.opencontainers.image.version="0.1.0" WORKDIR /app +## Copy only requirements.txt first for better caching +COPY requirements.txt /app/requirements.txt +RUN apk add --no-cache build-base libffi-dev openssl-dev \ + && python -m venv /app/.venv \ + && /app/.venv/bin/pip install --no-cache-dir -r /app/requirements.txt \ + && apk del build-base libffi-dev openssl-dev + +## Now copy the actual code COPY bambu.py /app/bambu.py -# Optional: requirements.txt falls weitere Pakete benötigt werden -RUN pip install --no-cache-dir paho-mqtt dotenv +## Create non-root user +RUN adduser -D -h /app appuser \ + && chown -R appuser:appuser /app +USER appuser -CMD ["python", "-u", "bambu.py"] +ENV PATH="/app/.venv/bin:$PATH" + +## Healthcheck: checks if the process is running (simple example) +HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ + CMD pgrep -f "python -u bambu.py" || exit 1 + +## ENTRYPOINT for better extensibility +ENTRYPOINT ["python", "-u", "bambu.py"] diff --git a/bambu.py b/bambu.py index 56fc572..474ede2 100644 --- a/bambu.py +++ b/bambu.py @@ -1,4 +1,4 @@ -# video url +# Video URL example # ffplay -rtsp_transport tcp -tls_verify 0 "rtsps://bblp:@:322/streaming/live/1" import ssl @@ -8,7 +8,7 @@ from dotenv import load_dotenv load_dotenv() -# --- KONFIGURATION aus .env --- +# --- CONFIGURATION from .env --- PRINTER_IP = os.getenv("PRINTER_IP") PRINTER_ACCESS_CODE = os.getenv("PRINTER_ACCESS_CODE") PRINTER_SERIAL = os.getenv("PRINTER_SERIAL") @@ -19,38 +19,40 @@ TARGET_USERNAME = os.getenv("TARGET_USERNAME") TARGET_PASSWORD = os.getenv("TARGET_PASSWORD") TARGET_PREFIX = os.getenv("TARGET_PREFIX", "bambulab/") -# --- ZIEL-CLIENT (SINK) --- + +# --- TARGET CLIENT (SINK) --- def setup_target(): client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2) - # TLS-Konfiguration für Ziel-Broker (Zertifikate werden geprüft) + # TLS configuration for target broker (certificates are verified) client.tls_set(cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1_2) - # Authentifizierung + # Authentication client.username_pw_set(TARGET_USERNAME, TARGET_PASSWORD) try: client.connect(TARGET_BROKER_IP, TARGET_PORT, 60) - client.loop_start() # Läuft im Hintergrund-Thread - print(f"[Target] Verbunden mit {TARGET_BROKER_IP}") + client.loop_start() # Runs in background thread + print(f"[Target] Connected to {TARGET_BROKER_IP}") return client except Exception as e: - print(f"[Target] Fehler: {e}") + print(f"[Target] Error: {e}") exit(1) target_client = setup_target() -# --- QUELL-CLIENT (SOURCE - BAMBULAB) --- + +# --- SOURCE CLIENT (BAMBULAB) --- def on_connect_source(client, userdata, flags, rc, properties=None): if rc == 0: - # Abonniere Haupt-Report Topic + # Subscribe to main report topic topic = f"device/{PRINTER_SERIAL}/report" client.subscribe(topic) else: - print(f"[Source] Verbindung fehlgeschlagen. Code: {rc}") + print(f"[Source] Connection failed. Code: {rc}") def on_message_source(client, userdata, msg): import datetime - # Füge Prefix hinzu, z.B. bambu/device/SERIAL/report + # Add prefix, e.g. bambu/device/SERIAL/report mirror_topic = f"{TARGET_PREFIX}{msg.topic}" - # Prüfe, ob sich die Daten geändert haben + # Check if the data has changed if not hasattr(on_message_source, "last_payloads"): on_message_source.last_payloads = {} last_payload = on_message_source.last_payloads.get(mirror_topic) @@ -58,31 +60,31 @@ def on_message_source(client, userdata, msg): target_client.publish(mirror_topic, msg.payload, qos=0, retain=False) on_message_source.last_payloads[mirror_topic] = msg.payload now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') - print(f"[{now}] Empfangen & weitergeleitet: Topic={mirror_topic}, Bytes={len(msg.payload)}") + print(f"[{now}] Received & forwarded: Topic={mirror_topic}, Bytes={len(msg.payload)}") else: now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') - print(f"[{now}] Empfangen, aber nicht weitergeleitet (keine Änderung): Topic={mirror_topic}") + print(f"[{now}] Received, but not forwarded (no change): Topic={mirror_topic}") def main(): - # BambuLab benötigt SSL/TLS, akzeptiert aber oft nur unsichere Zertifikate + # BambuLab requires SSL/TLS, but often only accepts insecure certificates source_client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2) - # TLS Konfiguration für Self-Signed Certs + # TLS configuration for self-signed certs source_client.tls_set(cert_reqs=ssl.CERT_NONE, tls_version=ssl.PROTOCOL_TLSv1_2) source_client.tls_insecure_set(True) - # Auth: User ist IMMER 'bblp', Passwort ist der Access Code + # Auth: User is ALWAYS 'bblp', password is the access code source_client.username_pw_set("bblp", PRINTER_ACCESS_CODE) source_client.on_connect = on_connect_source source_client.on_message = on_message_source try: - # Port 8883 ist Standard für BambuLab MQTTS + # Port 8883 is default for BambuLab MQTTS source_client.connect(PRINTER_IP, 8883, 60) - source_client.loop_forever() # Blockiert hier und hält das Script am Leben + source_client.loop_forever() # Blocks here and keeps the script alive except KeyboardInterrupt: - print("\nBeende...") + print("\nExiting...") target_client.loop_stop() source_client.disconnect() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..56b7bdc --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +paho-mqtt +python-dotenv