Problem in den Logs mit einer Netatmo-Kamera, obwohl die Bilder angezeigt werden

Hallo,

In den Logs habe ich einen Fehler mit einer Netatmo-Kamera, aber das Bild wird in Gladys angezeigt.

2026-07-21T11:37:18+0200  poll.js:14 (RtspCameraHandler.poll) Unable to poll camera
2026-07-21T11:37:20+0200  getImage.js:79 () Error: Command failed: ffmpeg -i http://192.168.*.*/a859f7810d059863a8e7f3b113b40ef5/live/index.m3u8 -f image2 -vframes 1 -qscale:v 15 -vf scale=1280:-1 /tmp/gladysassistant/camera-ec77fd13-5ac1-4edb-b340-d2b0447995d9-526-0-37-11.jpg
ffmpeg version 5.1.9-0+deb12u1 Copyright (c) 2000-2026 the FFmpeg developers
built with gcc 12 (Debian 12.2.0-14+deb12u1)
configuration: --prefix=/usr --extra-version=0+deb12u1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libglslang --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librabbitmq --enable-librist --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --disable-sndio --enable-libjxl --enable-pocketsphinx --enable-librsvg --enable-libmfx --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-libplacebo --enable-librav1e --enable-shared
libavutil      57. 28.100 / 57. 28.100
libavcodec     59. 37.100 / 59. 37.100
libavformat    59. 27.100 / 59. 27.100
libavdevice    59.  7.100 / 59.  7.100
libavfilter     8. 44.100 /  8. 44.100
libswscale      6.  7.100 /  6.  7.100
libswresample   4.  7.100 /  4.  7.100
libpostproc    56.  6.100 / 56.  6.100
\[hls @ 0x60877d48a880\] Skip ('#EXT-X-INDEPENDENT-SEGMENTS')
\[hls @ 0x60877d48a880\] Opening 'http://192.168.*.*/a859f7810d059863a8e7f3b113b40ef5/live/files/high/index.m3u8' for reading
\[hls @ 0x60877d48a880\] Skip ('#EXT-X-VERSION:7')
\[http @ 0x60877d498080\] Opening 'http://192.168.*.*/a859f7810d059863a8e7f3b113b40ef5/live/files/medium/index.m3u8' for reading
\[hls @ 0x60877d48a880\] Skip ('#EXT-X-VERSION:7')
\[http @ 0x60877d498080\] Opening 'http://192.168.*.*/a859f7810d059863a8e7f3b113b40ef5/live/files/low/index.m3u8' for reading
\[hls @ 0x60877d48a880\] Skip ('#EXT-X-VERSION:7')
\[http @ 0x60877d498080\] Opening 'http://192.168.*.*/a859f7810d059863a8e7f3b113b40ef5/live/files/poor/index.m3u8' for reading
\[hls @ 0x60877d48a880\] Skip ('#EXT-X-VERSION:7')
\[hls @ 0x60877d48a880\] Opening 'http://192.168.*.*/a859f7810d059863a8e7f3b113b40ef5/live/files/high/live0000036907.ts' for reading
\[hls @ 0x60877d48a880\] Opening 'http://192.168.*.*/a859f7810d059863a8e7f3b113b40ef5/live/files/high/live0000036908.ts' for reading
\[hls @ 0x60877d48a880\] Opening 'http://192.168.*.*/a859f7810d059863a8e7f3b113b40ef5/live/files/medium/live0000036907.ts' for reading
\[hls @ 0x60877d48a880\] Opening 'http://192.168.*.*/a859f7810d059863a8e7f3b113b40ef5/live/files/medium/live0000036908.ts' for reading
\[hls @ 0x60877d48a880\] Opening 'http://192.168.*.*/a859f7810d059863a8e7f3b113b40ef5/live/files/low/live0000036907.ts' for reading
\[hls @ 0x60877d48a880\] Opening 'http://192.168.*.*/a859f7810d059863a8e7f3b113b40ef5/live/files/low/live0000036908.ts' for reading
\[http @ 0x60877d498080\] Opening 'http://192.168.*.*/a859f7810d059863a8e7f3b113b40ef5/live/files/poor/index.m3u8' for reading
\[hls @ 0x60877d48a880\] Skip ('#EXT-X-VERSION:7')
\[hls @ 0x60877d48a880\] skipping 4 segments ahead, expired from playlists
\[hls @ 0x60877d48a880\] Opening 'http://192.168.*.*/a859f7810d059863a8e7f3b113b40ef5/live/files/poor/live0000036911.ts' for reading
\[hls @ 0x60877d48a880\] Opening 'http://192.168.*.*/a859f7810d059863a8e7f3b113b40ef5/live/files/poor/live0000036912.ts' for reading
\[http @ 0x60877d498080\] Opening 'http://192.168.*.*/a859f7810d059863a8e7f3b113b40ef5/live/files/high/index.m3u8' for reading
\[hls @ 0x60877d48a880\] Skip ('#EXT-X-VERSION:7')
\[hls @ 0x60877d48a880\] skipping 3 segments ahead, expired from playlists
\[http @ 0x60877d4c66c0\] Opening 'http://192.168.*.*/a859f7810d059863a8e7f3b113b40ef5/live/files/high/live0000036912.ts' for reading
\[mpegts @ 0x60877d49c5c0\] Packet corrupt (stream = 0, dts = 6643436250).
\[hls @ 0x60877d48a880\] Packet corrupt (stream = 0, dts = 6643432500)

Hallo,

Ich habe mir deine Logs angesehen und denke, dass es tatsächlich zwei verschiedene Probleme gibt, die sich gegenseitig verstärken, was erklärt, warum der Live-Stream funktioniert, aber nicht die Bildwiederherstellung.

Das erste Problem ist der Netatmo-Stream selbst. Der Token in der URL (der a859f78… in /live/index.m3u8) ist eine lokale Sitzung, die nicht dauerhaft ist: Er dreht sich, und der Stream ist nur verfügbar, wenn eine Streaming-Sitzung aktiv ist. Das sieht man deutlich in deinen Logs: Manchmal öffnet ffmpeg den Stream, holt einige Segmente, dann bekommt er in einer Schleife 404-Fehler bei den Playlists medium und low mit « Packet corrupt », und er wird schließlich beim Timeout getötet. Zu anderen Zeiten gibt es direkt einen 404-Fehler bei der Haupt-m3u8-Datei, dort ist der Token bereits ungültig. Wenn du also die Kamera manuell öffnest, wird ein frischer Stream gestartet und es funktioniert, aber der Hintergrund-Poll greift auf eine bereits abgelaufene URL zu.

Das zweite Problem, und ich denke, das ist das, was deine Eingabe blockiert, ist diese Zeile:

PayloadTooLargeError: request entity too large
expected: 103788, length: 103788, limit: 102400

Im Grunde genommen schafft es ffmpeg, das Bild auszugeben, aber es ist 103 KB groß und Gladys lehnt alles ab, was größer als 100 KB ist. Das Bild wird also tatsächlich erfasst, aber nie gespeichert. Und das passt zu deinem Problem: Deine Eingabe ist im Freien, die Szene ist detaillierter, daher ist das JPEG größer und überschreitet systematisch das Limit. Deine Innenkameras produzieren leichtere Bilder, sie kommen durch, wenn der Stream bereit ist zu antworten. Wahrscheinlich ist das der Grund, warum die Eingabe jedes Mal scheitert, während die anderen intermittierend funktionieren.

Beide Probleme ähneln eher Integrationsproblemen als einem Konfigurationsproblem deinerseits. Der PayloadTooLargeError vor allem: Das Limit von 100 KB ist etwas knapp für eine 1280px-Aufnahme im Freien, man müsste es entweder erhöhen oder die Auflösung oder die Qualität des Snapshots etwas verringern.

@Terdious, sagt dir das etwas?

Ja!! Das ist die Integration der PRs, die für die Integration der Netatmo-Kameras gemacht wurden, die dies lösen werden.

Aber der Port auf externes gladys-netatmo kann übernehmen.

Ich verheimliche nicht, dass dennoch einige Core-Bausteine erforderlich sein werden :face_with_peeking_eye:

Aber normalerweise existieren bereits abgekoppelte PRs :wink:

Ich bin einverstanden!

Ich fange morgen an :winking_face_with_tongue: das war geplant ^^

Danke @pierre-gilles und @Terdious :wink::+1:

Oh Mann, viel zu ungeduldig!!
Es ist unterwegs…



Mit der Ankunft der Kameras:

Dann die Integration der Bilder:


Kurz gesagt, es funktioniert schon… nun ja, fast. Fehlt nur noch der Videostream ^^ Aber ein Thema, das mit @pierre-gilles zu besprechen ist. Ich bereite einen Punkt mit Claude vor!!

Ah, der Stream funktioniert tatsächlich! Nur das Re-Encoding verursacht eine Verzögerung von 10/15 Sekunden!
Und kein Ton!! Aber das wird anscheinend separat auf Core-Seite behandelt werden müssen.

EDIT: PRs integriert, Release 1.0.0 veröffentlicht => Package gladys-netatmo · GitHub

Hallo @pierre-gilles,

Offensichtlich, um es besser testen zu können, und logischerweise, sollte man einen der Parameter des Geräts anzeigen lassen können, um die Qualität des Streams « camera_quality » auswählen zu können:

[
    {
        "id": "6b193d78-1fab-4edd-87b2-37e3a46b5fd4",
        "device_id": "8f70c343-7642-47e1-883a-dabf6cc0694a",
        "name": "CAMERA_URL",
        "value": "http://10.6.0.23/token/live/files/high/index.m3u8",
        "created_at": "2026-07-21T22:04:32.684Z",
        "updated_at": "2026-07-21T22:04:32.684Z"
    },
    {
        "id": "c66dca61-b96b-431e-8894-db94ce1f9e42",
        "device_id": "8f70c343-7642-47e1-883a-dabf6cc0694a",
        "name": "camera_quality",
        "value": "high",
        "created_at": "2026-07-21T22:04:32.697Z",
        "updated_at": "2026-07-21T22:04:32.697Z"
    }
]

Ich habe bereits eine Anfrage in dieser Richtung an Tuya gestellt, um die IP- und Protokollversionsfelder in den Geräteeinträgen angeben zu können. Das geht in dieselbe Richtung.

Wir haben das vorerst mit einem globalen Parameter in der Konfiguration für alle Kameras der Integration umgangen

Für den Audio-Stream habe ich noch keine Lösung gefunden.

Und andererseits müssen wir wirklich eine Dokumentation mit Zugriff auf die Links der Entwicklerplattformen erstellen, denn hier haben wir keine Informationen mehr, um Konten zu erstellen usw., wie wir sie bei den Core-Integrationen hatten (oder einen Weg finden, um Einleitungskapitel in den Konfigurationen zu definieren, die externe Links enthalten können?)

EDIT:

  • Beim Ton scheint es meine Testkamera zu sein, die kaputt ist :sweat_smile: :face_with_peeking_eye: und keinen Ton mehr liefert… Entschuldigung
  • Ansonsten hat Claude einen Vorschlag für die Live-Verzögerung:

Erledigt!

Du hast recht! Die Lösung:

1. Feldtyp section — Einleitungsblöcke im Konfigurationsformular (Netatmo-Portierung erforderlich)

  • Manifestvalidierung: Neuer Typ section im config_schema (und in den fields der Aktionen, gleiche Engine) — label (Kapitelüberschrift, mehrsprachig), description als reiner Text ≤ 1000 Zeichen/Sprache, optionale links (1–5 Einträge {url, label}, url https erforderlich, unbekannte Felder werden abgelehnt). Rein präsentativ: required, default und placeholder auf einer Sektion → Manifest wird mit 422 abgelehnt. Das vendored-Schema spiegelt alles wider (enum + links + allOf-Regeln).
  • Kein Wert: validateConfigValue lehnt einen Sektionsschlüssel in jedem Konfigurationspayload ab (Frontend und Integration → 422 „Sektionsfelder haben keinen Wert“), nichts wird jemals in t_variable geschrieben, und getConfigForFront exponiert den Schlüssel nicht.
  • Frontend-Rendering (deklarativ, kein Markdown/HTML): Überschrift + Text + Links in einem neuen Tab geöffnet, mit der Zieladresse in Klammern neben dem Label angezeigt. Da das config_schema geordnet ist, unterteilen die Sektionen große Formulare natürlich — einschließlich der Mini-Formulare von Aktionen.

2. Permanenter „Dokumentation“-Link auf dem Konfigurationsbildschirm

  • Neues getDocsUrls auf Serverseite: Die Details GET /api/v1/external_integration/:selector exponieren nun docs (URLs, die pro Sprache neu gehostet werden, aus dem Cache des Store-Index, verknüpft über store_slug — null für eine Entwicklerinstallation, die keine neu gehostete Dokumentation hat).
  • Das Frontend zeigt einen „Dokumentation“-Button im Header der Konfigurationskarte an (Benutzersprache, Fallback en), für „Geräte“- und „Kommunikations“-Integrationen (geteilter Komponent).
  • Nebenbei, Korrektur eines bestehenden Lochs: getCatalog übertrug das Feld docs des Index nicht — der Dokumentationslink des Installationsbildschirms las ein Feld, das immer fehlte. Er funktioniert jetzt (docs: entry.docs || null), mit Assertion in den Store-Tests.

Verfügbar im SDK v0.8.0!