Externe Integrationen in Gladys Assistant

Hier:

ghcr.io/gladysassistant/gladys-preview:claude-magical-turing-qhh7q2-arm64

@Will_71 Wird die Free Mobile-Integration nicht zu einer externen Integration? :slight_smile:

Ja, genau. Dann muss ich mir anschauen, wie das alles funktioniert. Ich hatte am Wochenende schon darüber nachgedacht, aber keine Zeit, mich näher damit zu beschäftigen.

Lance Claude dazu, das ist wirklich eine Geschichte von fünf Minuten meiner Meinung nach :grin:

Externe Integration von TP Link in Entwicklung/Test (ich muss mich um den Netzwerkentdeckungsteil kümmern)

Für den Netzwerk-Scan, das ist im SDK! Das ist Gladys, die den Scan durchführt und die Ergebnisse an die Integration übergibt.

Gib Claude einfach das SDK und er wird die Arbeit erledigen :sweat_smile:

Das ist auf der anderen Seite mit Claude zu einfach ^^

Hallo @pierre-gilles,

UX-Erfahrungsbericht nach dem Inbetriebnehmen des Transportmodells +
action auf gladys-tuya (übrigens: die Makronen lokal/cloud, der Toggle
GLADYS_PREFER_LOCAL, das Upsert der Parameter und die Aktion detect_protocol
funktionieren in der Praxis einwandfrei — Glückwunsch, das ändert alles).


Der schwierige Punkt bleibt die LESBARKEIT SEITENS GERÄT. Szenario, das ein
Standardnutzer erlebt: Zwei Geräte zeigen ein „Cloud“-Makron an, obwohl der
Lokalmodus aktiviert ist. Warum? Das eine wurde vom UDP-Scan nicht gefunden
(keine IP), das andere lehnt lokale Sitzungen ab. Es ist unmöglich, das aus
der Gerätekarte zu erfahren: Sie zeigt nur Name / Raum / Funktionen an
(DeviceBox.jsx rendert keine Parameter außerhalb des GLADYS_TRANSPORT-Badges).

Drei Anfragen, nach Priorität geordnet:

  1. Anzeige von „nützlichen“ Parametern auf der Gerätekarte einer externen Integration — mindestens zum Lesen (IP_ADDRESS, PROTOCOL_VERSION), idealerweise mit bearbeitbarer IP. Ohne das kann der Nutzer weder diagnostizieren noch handeln. Idee: eine Liste von Parametern, die angezeigt werden sollen, die im Manifest deklariert wird (z. B. « device_params_display »: [« IP_ADDRESS », « PROTOCOL_VERSION »]), mit einem « editable »-Flag pro Schlüssel — die Bearbeitung erfolgt über das bestehende Upsert von Parametern.

  2. Aktionen PRO GERÄT: Heute werden die Aktionen des Manifests nur im Konfigurationsbildschirm (ActionsCard.jsx) auf Integrationsebene angezeigt.
    Um das „lokale Protokoll erkennen“ zu lassen, ist der richtige Ort die Karte des betreffenden Geräts: ein Flag « scope »: « device » bei der Aktion, die als Button auf jeder Karte angezeigt wird, mit der external_id des Geräts, die in die an die Integration übertragenen Felder injiziert wird. Dadurch müsste der Nutzer keine Kennung kopieren.

  3. Alternativ (oder ergänzend) eine DYNAMISCHE QUELLE für die Select-Felder der Aktionen: Heute rendert ConfigSchemaForm.jsx nur statische Optionen aus dem Manifest. Ein Feld { "type": "select", "source": "devices" }, das die von der Integration erstellten Geräte auflistet (Label = Name, Wert = external_id), würde 90 % des Bedarfs mit minimalen Frontend-Änderungen lösen.

In der Zwischenzeit haben wir auf Integrationsebene eine Notlösung implementiert: Das Feld der Aktion akzeptiert den NAMEN des Geräts, wie er in Gladys angezeigt wird (oder die Tuya-ID). Das hilft, aber es bleibt eine freie Eingabe mit den Risiken von Homonymen.

Ergänzung zu den Transport-Makronen — ein „degradierter“ Zustand (orange)

Bei der Verwendung der lokal/cloud-Makronen in der Praxis stößt man auf einen Fall, den die drei aktuellen Zustände (lokal / cloud / unreachable) nicht ausdrücken können: Das Gerät FUNKTIONIERT, aber nicht wie es sollte.

Konkreter Fall: Ein Gerät wird vom lokalen UDP-Scan erkannt (IP und Protokollversion bekannt, lokaler Modus aktiviert), aber es gibt Fehler oder Timeouts bei den lokalen Abfragen. Unsere Integration wechselt dann in den Cloud-Fallback-Modus: Der Nutzer sieht ein blaues „Cloud“-Makron, das perfekt normal aussieht… obwohl in Wirklichkeit etwas nicht stimmt (Gerät lehnt lokale Sitzungen ab, lokales Token rotiert, anderes lokales Client hält die Verbindung, etc.). Nichts veranlasst ihn, nachzuforschen.

Die Anfrage: ein „degradierter“ Zustand (oranges Makron), orthogonal zum tatsächlichen Transport. Zwei Modellierungsmöglichkeiten, nach deiner Wahl:

  1. Ein separates Gesundheitsfeld in publishTransports, um die Semantik des Transports nicht zu verunreinigen:
   [{ "external_id": "...", 
      "transport": "cloud",
      "health": "degraded",
      "reason": {
                  "en": "LAN found but local polls fail — using cloud",
                  "fr": "Vu en LAN mais échecs de lecture locale — bascule cloud",
                  "de": "Im LAN beobachtet, aber lokale Lesefehler – Cloud-Umschaltung"
      }
    }]

→ Das Makron zeigt den Transport an, das Orange signalisiert die Degradierung, der
reason wird in der Tooltip / beim Klicken angezeigt. Das ist meine Favoritin: « degraded »
bleibt wahr, egal welcher Transport (ein langsamer Cloud oder ein lokaler, der Frames verliert, sind auch degradiert).

  1. Mindestens ein Wert « degraded », der zum Transport-Enum hinzugefügt wird — weniger reich (man verliert die Info über den tatsächlich verwendeten Transport), aber trivial hinzuzufügen.

Auf Integrationsebene haben wir bereits alles, um das sauber zu melden: Unser lokaler Circuit-Breaker weiß genau, wann ein LAN-fähiges Gerät nach N Fehlern auf die Cloud ausgelagert wird, mit dem Grund. Es fehlt uns nur der Kanal, um es dem Nutzer mitzuteilen.

Und darüber hinaus gibt es eine generische Sprache für alle „es funktioniert, aber schlecht“: Cloud-Token, das bald abläuft, Gerät, das nur einmal von zwei antwortet, Sub-Container im Crash-Loop, aber Fallback aktiv, etc.

Danke!

Ansonsten bleibt mir nur noch die Dokumentation zu schreiben, aber die ersten beiden externen Integrationen scheinen bereit zum Veröffentlichen zu sein ^^:

  • gladys-zendure in v1.1.0

Das Update funktioniert super!!^^

  • und gladys-tuya in v1.0.1:

Unglaublich, danke für dein Feedback und diese 2 Integrationen! Deine Rückmeldungen umzusetzen wird wahrscheinlich Donnerstag sein (heute und morgen bin ich freiberuflich :blush:)

Oui oui, ich weiß genau, deshalb haben wir es vorerst anders gelöst, es bleibt trotzdem funktionsfähig :heart_eyes: !!

Danke für alles :folded_hands:, diese große Weiterentwicklung ist ein Wendepunkt für Gladys, denke ich. Auch wenn, aber ich mache mir nicht allzu viele Illusionen, da ich dich jetzt kenne, was die Qualität angeht, wie @cicoub13 sehr richtig erwähnt hat, wird die Zukunft nicht unbedingt einfacher sein, um die Qualität und das hohe Image von Gladys zu erhalten!!

Also los!! Ich mach mich auch an die Arbeit ^^

Ja, das habe ich gemacht, aber der Vorschlag muss überarbeitet werden (IP muss vom Benutzer eingegeben werden und Fallback auf Netzwerk-Scan). Ich möchte, dass es einfacher wird und daher verstehen, was mit dem Scan wirklich möglich ist (ich werde die Dokumentation noch einmal lesen).

Wäre es nicht besser, wenn der Teil Supervision in einem eigenen Abschnitt (außerhalb der Konfiguration) wäre?

Wenn du ein Beispiel mit Fable generierst, kann ich es überprüfen.

Ich habe dir die Idee eines Validierungsservers für das SDK vorgestellt. Du wirst nicht validieren müssen, wenn das SDK alle Tests des Validierungsservers besteht. Der Entwickler kann dies auch lokal tun. Dadurch können auch mehrere externe SDKs unterstützt werden. Ich denke, dass offiziell unterstützte JS und Python 90% der Anforderungen und Entwickler abdecken. Zudem wird Python von HA verwendet und damit haben wir viele Integrationen, die wir leichter portieren können. Allerdings müssen wir auf die stabile Version der JS-Version warten. Lasst uns nicht zu schnell vorgehen :slight_smile:

Warum nicht, gute Idee!

Ja, ich bin einverstanden. Ich möchte erst eine erste Release in Produktion haben, die vollständig in JS ist, sowie ein ausreichend ausgereiftes JS-SDK, bevor ich ein Python-SDK vorschlage.

Andererseits, sobald das JS-SDK stabilisiert ist und weniger Entwicklung und Wartung von meiner Seite erfordert, wäre ich absolut bereit, es auf Python zu portieren.

Und hör mal, das scheint alles gut zu funktionieren ^^ OAuth hat auf Anhieb funktioniert.
Bilder und Video-Stream sind super!
Aber ich habe keinen Ton in den Video-Streams und der Stream ist um 10/15 Sekunden verzögert => Recherche morgen

Und ich denke, wir werden uns dem bald widmen ^^ Wahrscheinlich ein Wochenendprojekt!!^^

Unglaublich, diese externen Integrationen sind echt der Hammer :blush:

Okay, halt mich auf dem Laufenden wegen der Latenz-Geschichte!

Nach Diskussion mit Fable:

Die drei Rückmeldungen betreffen echte Bedürfnisse, aber ich würde sie nicht alle so übernehmen. Meine Meinung Punkt für Punkt:

1. Aktionen pro Gerät (scope: "device") — ich würde das verschieben. Der Bedarf ist legitim (dem Benutzer nicht das Kopieren einer external_id zumuten), aber die vorgeschlagene Lösung öffnet eine UI-Pandora-Büchse: Buttons, die durch das Manifest deklariert werden und sich in die Gerätekarten injizieren, genau die Art von Oberfläche, die wir vermeiden wollten (Anforderung Nr. 3 des Rahmens: kohärente UI, kein Rendering, das durch Integrationen gesteuert wird, über generierte Formulare hinaus). Und es wirft Fragen ohne gute Antwort in v1 auf: auf welcher Karte? Nur der Gerätebildschirm der Integration oder das Dashboard? Was tun, wenn eine Integration 5 Geräteaktionen × 40 Geräte deklariert? Der Entwickler sagt es selbst: die dynamische Quelle deckt 90 % des Bedarfs ab. Die restlichen 10 % (ein Klick weniger im Vergleich zu einem Select) rechtfertigen diese Komplexität jetzt nicht. Kandidat für Phase 2, wenn der Bedarf dies erfordert, nicht v1.

2. Dynamische Quelle für Selects ("source": "devices") — ja, ehrlich gesagt. Das ist die richtige Lösung für dasselbe Problem: klein, generisch, konsistent mit dem bestehenden config_schema, und das Rendering bleibt zu 100 % durch den Core kontrolliert (label = Gerätename, value = external_id, gefiltert nach service_id der Integration — null Leckage zwischen Mandanten). Zwei Schutzmechanismen, die in die Spezifikation aufgenommen werden müssen: source ist ein reserviertes Enum, das durch den Core definiert wird (v1: nur devices), keine URL oder ein Ausdruck — wir öffnen keinen Mechanismus zur Injektion beliebiger Daten; und source ist exklusiv mit statischen options. Es funktioniert für die Felder der actions[] und, kostenlos, auch für das config_schema der Installation.

3. „Degradierter“ Zustand — der Bedarf ist real, aber nicht als 4. Wert des Enums. Der beschriebene Fall (das Gerät funktioniert in der Cloud, obwohl es lokal sein sollte) ist generisch, nicht tuya-spezifisch, und der blaue Aufkleber „alles in Ordnung“, der ein Problem maskiert, ist ein echtes Observability-Loch. Allerdings würde das Hinzufügen von degraded zu GLADYS_TRANSPORT zwei orthogonale Achsen vermischen: welcher Transport wird verwendet und ist es der nominale Zustand. Mit einem Enum mit 4 Werten verliert der Benutzer, der „Degradiert“ sieht, die Information „es ist gerade in der Cloud“ — genau das, was ihm hilft, es zu verstehen. Mein Vorschlag: local|cloud|unreachable als Transportwert beibehalten und denselben Endpunkt POST /device/transport mit zwei optionalen Feldern pro Eintrag erweitern: degraded: true und eine mehrsprachige message (z. B. „Lokal erkannt, aber Sitzungen abgelehnt, Wechsel zur Cloud“). Darstellung: Der Aufkleber behält seine Transportfarbe/-beschriftung mit einem orangefarbenen Rand oder Punkt, Tooltip = die Nachricht; der globale Zähler des Gerätebildschirms erhält eine Zeile „n degradiert(e)“. Wir behalten beide Informationen, anstatt eine zu überschreiben.

Zusammenfassend: Ich nehme den Punkt 2 so wie er ist (mit reserviertem Enum), den Punkt 3 umgestaltet in ein orthogonales Flag degraded + Nachricht statt als 4. Zustand, und verschiebe den Punkt 1 in die Phase 2, da der Punkt 2 den größten Teil des Bedarfs abdeckt. Wenn das für dich in Ordnung ist, schreibe ich diese beiden Ergänzungen in die Spezifikation.

Ich bin eher seiner Meinung!

Dediziertes Supervision-Registerkarte (Danke @cicoub13)

Möglichkeit, die params anzuzeigen:


Ich bin voll und ganz damit einverstanden, und wie für Punkt 1 erwähnt, funktioniert es auch ohne, es ist nur eine mögliche Verbesserung, die besprochen und Zeit braucht :smiling_face_with_three_hearts:

Das ist viel besser :wink:

Neue Version des SDK, die v0.7.0 mit neuen Funktionen für @Terdious und @cicoub13:

  • feat: verschlechterter Transportzustand und dynamische Auswahl der Quelle « Geräte » (Spezifikationsupdate) von @Pierre-Gilles in #11
  • feat: aktives Broadcast-Netzwerk-Scan udp-active-broadcast (Spezifikationsupdate B.16) von @Pierre-Gilles in #12