Datenmodell

Überblick

Alle Daten sind in einer dreistufigen Hierarchie organisiert:

Module
  └─ Property (eine oder mehrere pro Modul)
       └─ Element (eines oder mehrere pro Property)

Verbindung und Anfangszustand

Den Server finden

Ein Web-Client wird vom OST-Server selbst ausgeliefert und kennt daher bereits seinen Host — die WebSocket-URL sollte von der URL der Seite selbst abgeleitet werden, nicht vom Benutzer erfragt:

Seiten-URLWebSocket-URL
http://<host>/ws://<host>:9624 (direkt, fester Port)
https://<host>/wss://<host>/ws/ (impliziter Port 443, über einen Reverse-Proxy-Pfad — SSL-Setups legen Port 9624 nicht direkt offen)

Das ist eine Konvention, keine vom Protokoll erzwungene Regel — aber jeder existierende Client folgt ihr, und ein Client, der stattdessen den Benutzer bittet, eine WebSocket-URL manuell einzugeben, löst ein Problem, das im Web-Fall gar nicht existiert.

Ein Nicht-Web-Client (Mobile, Desktop) hat keine Seiten-URL, von der er etwas ableiten könnte, und braucht den Host auf andere Weise:

  • mDNS/Zeroconf: der Server meldet sich im lokalen Netzwerk als Diensttyp _ostserver_ws._tcp in der Domäne local, mit einem TXT-Eintrag OstServer=Observatoire Sans Tete. Der angekündigte Port ist immer 9624. Das erlaubt einem Client, verfügbare Server im Netzwerk zu scannen, statt vom Benutzer eine IP-Adresse zu verlangen — nützlich für eine erste Verbindung, oder wann immer mehr als ein OST-Server in der Nähe sein könnte.
  • Manuelle Eingabe, gemerkt: ob entdeckt oder eingegeben, ein Client sollte eine kleine Historie bereits genutzter Server (Host/Port/sicher) führen, damit eine spätere Wiederverbindung nicht die Erkennung oder Eingabe wiederholen muss. Das ist ein clientseitiger Komfort, kein Teil des Protokolls.

In jedem Fall folgt die Basis-URL der Medien (für Bilder/Videos, siehe die Notiz „Media-URLs" weiter unten) demselben Host, mit dem üblichen HTTP(S)-Port (80/443) statt 9624 — ein Nicht-Web-Client braucht diesen Host ebenfalls, aus genau demselben Grund wie den WebSocket-Host.

Bei der Verbindung eine DU-Anfrage senden (siehe Client → Server).
Der Server antwortet mit einer vollständigen Dump-Nachricht (d), die alle Module, die Controller-Daten und die Dateilisten enthält.

Controller-spezifische Daten (Serverlast, Modulkonfigurationen, INDI-Treiber, Dateisystem) sind nicht Teil des auf dieser Seite beschriebenen Modul-Modells — siehe Controller, GlobalDatastore und Dateien.


Module

Ein Modul repräsentiert ein funktionales Subsystem (Fokussierung, Guiding, Allsky-Kamera usw.).
Seine Kennung ist sein interner Name (ohne Leerzeichen).

FeldTypBeschreibung
infos.modulelabelstringAngezeigter Name des Moduls
infos.descriptionstringBeschreibung des Moduls
infos.templatestringAnzeige-Hinweis für das Frontend (welche Darstellung verwendet werden soll), z. B. "focus", "guider" — rein kosmetisch, kann fehlen
infos.librarystringTyp des Moduls, kleingeschrieben (die Bibliothek, aus der es geladen wurde, z. B. "focus")
infos.classnamestringTyp des Moduls, exakte Schreibweise (z. B. "Focus")
infos.familiesArray von stringFähigkeiten, die diese Modulinstanz deklariert (z. B. ["guiding"]) — keine, eine oder mehrere
propertiesobjectMap von Property-Name → Property-Objekt
globallovsobjectMap von LOV-Schlüssel → LOV-Objekt (Wertelisten auf Modulebene)
profile.namestringName des aktiven Profils
profile.changedboolZeigt an, ob das Profil nicht gespeicherte Änderungen hat
Wire-Format

Im JSON-Format über das Netzwerk wird properties zu p, globallovs zu l und profile zu f abgekürzt. Clients müssen diese abgekürzten Schlüssel verarbeiten können.

Typ, Template und Familie sind drei verschiedene Dinge

Es ist verlockend, infos.template als Identität des Moduls zu behandeln — nicht tun. Es handelt sich um drei unabhängige Konzepte:

  • Typ (infos.library/infos.classname) ist die eigentliche Identität des Moduls — die Bibliothek, aus der es geladen wurde. Zwei Instanzen desselben Typs (z. B. zwei Focus-Module) haben immer denselben Typ.
  • Template (infos.template) ist nur ein Anzeige-Hinweis für das Frontend, rein kosmetisch und völlig optional. Zwei unterschiedliche Typen können sich dasselbe generische Template teilen (z. B. alles, was mit "default" gerendert wird).
  • Familie (infos.families) ist eine Fähigkeit, die ein Modul über sich selbst deklariert, unabhängig von Typ und Template. Ein Modul kann keine, eine oder mehrere Familien deklarieren — das existiert, damit ein Client “jedes Modul, das guiden kann” ansprechen kann, ohne sich darum zu kümmern, ob der tatsächliche Typ Guider ist oder eine andere Implementierung derselben Fähigkeit.

loadedModules-<type> und loadedFamilies-<family> (weiter unten) verwenden das kleingeschriebene infos.library/infos.families als Schlüssel; profiles-<Type> dagegen das exakt geschriebene infos.classname. Immer das passende Feld direkt verwenden — niemals eines aus dem anderen durch clientseitige Groß-/Kleinschreibungs-Transformation ableiten.

Interne Felder

infos enthält außerdem mehrere interne Build-/Versionsfelder (baseGithash, thisversion, startdatetime und andere) — Implementierungsdetail, nicht Teil des stabilen Client-Vertrags, hier nicht einzeln dokumentiert.


Properties

Eine Property gruppiert zusammengehörige Elemente. Properties werden hierarchisch über level1 und level2 angezeigt.

FeldTypBeschreibung
labelstringAngezeigte Bezeichnung
orderstringSortierreihenfolge innerhalb derselben Ebene
level1stringErste Hierarchieebene (z. B. Tab-Name)
level2stringZweite Hierarchieebene (z. B. Gruppenname)
statusint0 Ruhe · 1 OK (grün) · 2 Beschäftigt (gelb) · 3 Fehler (rot)
permissionint0 Nur Lesen · 1 Nur Schreiben · 2 Lesen-Schreiben
enabledboolZeigt an, ob mit der Property interagiert werden kann
badgeboolZeigt an, ob die Property in der Favoritenliste steht
preicon1stringIcon vor der Bezeichnung (Name eines Google-Fonts-Icons)
preicon2stringZweites Icon vor der Bezeichnung
posticon1stringIcon nach der Bezeichnung
posticon2stringZweites Icon nach der Bezeichnung
showEltsboolZeigt an, ob die Elementwerte inline angezeigt werden sollen
hasprofileboolZeigt an, ob die Property in Profilen gespeichert wird
freevaluestringBeliebiges Freitextfeld
ruleintGruppierungsregel für bool-Elemente: 0 GenauEines (Radio) · 1 HöchstensEines · 2 Beliebig
elementsobjectMap von Elementname → Element-Objekt
preicon/posticon: klickbare Aktionen, keine Dekoration

Ein nicht-leerer Wert von preicon1/preicon2/posticon1/posticon2 ist der Name des zu rendernden Google-Fonts-Icons (Material Icons) — und er ist klickbar: ein Klick darauf sendet I1/I2/I3/I4 ohne Wert oder Parameter, nur ein leeres Payload, das die Property adressiert. Ein leerer String bedeutet, dass an dieser Stelle kein Icon vorhanden ist — nichts zu rendern, nichts zu klicken, nichts zu senden. Die elementbezogenen preicon/posticon weiter unten funktionieren genauso, über J1/J2. Siehe Icon-Aktionen für die vollständige Nachrichtenreferenz.

permission steuert editierbare Elemente, nicht ob der Wert angezeigt wird

permission: 1 (“nur schreibend”) bedeutet nicht „aktuellen Wert verstecken" — es bedeutet, dass die Property nichts Sinnvolles besitzt, das sich als übermittelbarer Eingabewert zurücklesen ließe (eine Fire-and-forget-Aktion). Eine Property, deren einziges Element ein reiner Anzeige-Typ ist (img, video, light, prg, message), kann durchaus permission: 1 haben — eine Live-Kamera-Vorschau ist ein reales Beispiel — und muss trotzdem anhand ihres Werts gerendert werden, unabhängig von permission. Interaktivität (ein Eingabefeld anzeigen, einen Submit aktivieren) an permission koppeln, das Rendering dagegen an den Element-Typ, nicht an permission.

rule hat nur Bedeutung, wenn alle Elemente vom Typ bool sind

rule ist bei jeder Property vorhanden (Standardwert 0), hat aber nur dann Bedeutung — und sollte nur dann berücksichtigt werden —, wenn alle Elemente der Property vom Typ bool sind. Es taucht auch, wirkungslos, bei Properties auf, deren Elemente eine Mischung anderer Typen sind (z. B. ein Koordinatenpaar aus zwei float-Elementen) — ein Client sollte es dort ignorieren, statt zu versuchen, etwa zwei Floats als Radiogruppe darzustellen.

badge wird vom Modulautor gesetzt, nicht zur Laufzeit von einem Client

Es gibt keine Client-Nachricht, die badge umschaltet — es ist pro Property/pro Element fest in der eigenen Definition des Moduls verdrahtet, kein benutzer- oder sitzungsspezifischer Favorit, den ein Client setzen könnte. Ein Favoriten-Bildschirm kann anzeigen und aggregieren, was bereits markiert ist, hat aber keine Möglichkeit, einen Benutzer selbst etwas als Favorit markieren zu lassen.

level1/level2/order sind informativ, kein Vertrag

Diese Felder sind rein informativ — das Backend erzwingt sie nie, und ein Client kann sie teilweise oder gar nicht befolgen. Sie drücken nur aus, wie sich der Entwickler eines Moduls die Organisation seiner eigenen Properties vorgestellt hat. Genau das ermöglicht generischen Clients (Rooster, ostnoctua), sich an jedes Modul anzupassen, ohne modulspezifische UI.

Der Referenz-Client (Rooster) gruppiert Properties so, für einen Client, der ein ähnliches generisches Layout anstrebt:

  1. level1 leer → Property außerhalb jedes Tabs angezeigt (direkt gerendert, nach order sortiert).
  2. level1 gesetzt → in einem Tab namens level1 gruppiert. Darin: level2 leer → direkt unter dem Tab angezeigt; level2 gesetzt → in einer einklappbaren Gruppe namens level2.
  3. Die Reihenfolge der Tabs (und der Gruppen innerhalb eines Tabs) ist kein eigenes Feld — sie ergibt sich aus dem kleinsten order-Wert unter den Properties dieser Gruppe.
  4. Innerhalb einer Gruppe werden Properties nach ihrem eigenen order sortiert.

Zwei Dinge, die man kennen sollte, wenn man etwas Ähnliches baut:

  • level1/level2 bilden bewusst eine “unechte Hierarchie”, keine garantierte zweistufige Struktur — nichts hindert ein Modul daran, level1 leer zu lassen und trotzdem level2 zu setzen (Rooster behandelt diese Kombination nicht einmal gesondert; die Property landet einfach im “kein level1”-Topf, level2 wird ignoriert).
  • level1/level2 sind übersetzte Bezeichnungen, die denselben Mechanismus wie label/hint durchlaufen. Den rohen String-Wert als UI-Zustandsschlüssel zu verwenden (z. B. für ein auf-/zugeklapptes Panel) ist über Sprachwechsel des Clients hinweg brüchig — kein Bug, nur etwas, das man vermeiden sollte.

Properties mit Grid (wenn hasGrid: true):

FeldTypBeschreibung
hasGridboolDie Property enthält tabellarische Daten
showGridboolDie Grid soll standardmäßig angezeigt werden
gridLimitintMaximale Anzahl an Zeilen in der Grid
gridheadersstring[]Spaltenreihenfolge (Elementnamen)
gridArray von ArraysZeilen der Grid; jede Zeile ist ein Array von Werten in der Reihenfolge von gridheaders

Properties mit Graph (wenn hasGraph: true):

FeldTypBeschreibung
hasGraphboolDie Property enthält einen Graph — immer vorhanden, auch wenn false
graphTypestring"XY" · "DY" · "SXY" · "SDY" · "PHD" — siehe unten
graphParamsobjectWelches Element welche Rolle im Graph liefert — siehe unten

Eine Property mit Graph ist immer auch eine Grid-Property (hasGrid: true, siehe oben): jede Grid-Zeile ist ein Datenpunkt, und graphParams ordnet einer abstrakten Graph-Rolle den Element-Schlüssel zu (einer aus gridheaders), dessen Wert in dieser Zeile die Rolle liefert.

graphTypeFormRollen in graphParams
XYEine Streudiagramm-Serie, feste AchsengrenzenX, Y, Xmin, Xmax, Ymin, Ymax, optional zusätzlich graphColor (unten)
DYEine Serie, Datum/Zeit auf XD (Datum/Zeit-Element), Y, optional zusätzlich graphColor (unten)
SXYMehrere Streudiagramm-Serien, gruppiert nach einem SerienschlüsselS (Serienname-Element), X, Y, optional zusätzlich graphColors/axis/mapping (unten)
SDYMehrere Serien, Datum/Zeit auf X, gruppiert nach einem SerienschlüsselS, D, Y, optional zusätzlich graphColors/axis/mapping
PHDEigener PHD2-artiger Guiding-Graph (Drift + SNR + RMS)D, RA, DE, pRA, pDE, RSB, RMS — feste, zweckgebundene Rollen

Optionale Felder in graphParams:

FeldVerwendet vonBeschreibung
graphColorXY, DY{"R": int, "G": int, "B": int} — Farbe der einzelnen Serie
graphColorsSXY, SDY{"<Serie>": {"R": int, "G": int, "B": int}} — Farbe pro Serie
axisSXY, SDY{"<Name>": {"min": number, "max": number, "pos": "left"|"right", "text": string}} — eine oder mehrere Y-Achsen
mappingSXY, SDY{"<Serie>": "<Achsenname>"} — gegen welchen Eintrag von axis jede Serie geplottet wird
PHD ist kein generischer Graph-Typ

Anders als XY/DY/SXY/SDY, deren Rollen generisch genug sind, um eine einzige wiederverwendbare Graph-Komponente zu steuern, hat PHD feste, zweckgebundene Rollen für einen PHD2-artigen Guiding-Graphen (verwendet vom guider-Modul). Ein Client, der eine generische Graph-Komponente für die anderen vier Typen baut, braucht für PHD wahrscheinlich eine eigene Implementierung — oder lässt es weg. Rooster tut Letzteres (nur SXY/SDY/XY/DY, PHD nicht behandelt).

Graphen als lebendige Komponenten rendern, nicht als erzeugte Bilder

Die Grid-Daten einer Graph-Property ändern sich mit der Zeit (gc/gu/gd/gr, oder ein frischer uc/ap/aa) — also wie jedes andere lebendige UI-Element behandeln: mit einer Diagramm-/Canvas-Komponente zeichnen, die sich bei jedem Update neu aufbaut, so wie Rooster es mit Chart.js macht. Nicht server- oder clientseitig in ein statisches Bild rendern (PNG-Schnappschuss, serverseitig gerendertes Diagramm) und dann nur das <img> austauschen — das sieht merklich schlechter aus als ein echtes Diagramm (keine flüssigen Updates, keine Interaktivität, sichtbares Flackern/Neuladen bei jedem Punkt), und es verschenkt den ganzen Sinn, Grid-Daten überhaupt live über die Leitung zu bekommen.

Wire-Format

Im JSON-Format über das Netzwerk wird elements zu e abgekürzt.


Elemente

Ein Element enthält einen einzigen typisierten Wert. Es gibt 11 Elementtypen.

Gemeinsame Felder (alle Elemente, im vollständigen Dump)

FeldTypBeschreibung
typestringTyp des Elements (siehe Liste unten)
labelstringAngezeigte Bezeichnung
orderstringSortierreihenfolge innerhalb der Property
hintstringHilfetext / Tooltip
autoupdateboolInterner Backend-Indikator; von Clients ignoriert
badgeboolZeigt an, ob das Element in der Favoritenliste steht
directeditboolZeigt an, ob dieses Element allein per SV geschrieben werden kann — siehe unten
preiconstringIcon vor dem Element — klickbare Aktion, siehe Hinweis oben (optional)
posticonstringIcon nach dem Element — klickbare Aktion, siehe Hinweis oben (optional)
Teilweise Updates

In den Update-Nachrichten ee und ea enthalten Elemente nur ihren Wert — ohne die Metadatenfelder. Clients müssen die Metadaten des letzten vollständigen Dumps behalten.

Feldauslassung

directedit kann bei Elementen, auf die es nicht zutrifft, ganz fehlen — ein fehlendes directedit als false behandeln. Das hält die Dumps von Properties, die es nicht brauchen, schlanker.

Bedeutung von directedit

true bedeutet, dieses Element kann für sich allein aktualisiert werden, unabhängig von den anderen Elementen der Property — dafür SV senden (SA funktioniert auch). false bedeutet, der Client muss alle Elemente der Property zusammen übermitteln — dafür immer SA verwenden, nie SV für dieses einzelne Element. Ein anschauliches Beispiel: RA/Dec-Koordinaten, bei denen beide Werte zusammen angegeben werden müssen.

Das Backend erzwingt dies: Ein SV auf ein Element mit directedit: false wird mit einem Fehler im Modul-Log abgelehnt, und nichts wird angewendet. SA wird immer akzeptiert.

Den Wert nach dem Verhalten des Elements wählen, nicht danach, ob es sich mit seinen Nachbarn „zusammengehörig anfühlt“:

  • true für ein unabhängiges Element — ein bool, das unabhängig von seinen Geschwistern wahr sein kann (Aktions-Button wie start/abort/loop, Schalter), muss directedit: true haben. Ein solcher Wert spiegelt oft eine laufende Aktivität wider, und mehrere können gleichzeitig wahr sein (z. B. eine laufende Aufnahmeschleife, während ein Focus-out angefordert wird). false zu setzen würde fälschlich behaupten, die Elemente müssten als Gruppe übermittelt werden, und ein Client, der dieser Seite folgt, würde SA senden und Module umgehen, die nur SV verarbeiten.
  • false nur für eine echte Gruppe — Elemente, die nur zusammen sinnvoll sind: RA/Dec-Koordinaten oder ein 1:1 gespiegelter INDI-Switch-Vektor.

Bei einer false-Gruppe aus bool-Elementen mit exklusiver Regel (OneOfMany oder AtMostOne) bedeutet die Auswahl eines Elements, ihm true und allen Geschwistern false im selben SA zu senden — niemals die aktuellen Werte der Geschwister erneut senden, sonst sind zwei Elemente true.


Typ: int

FeldTypBeschreibung
valueintAktueller Ganzzahlwert
minintMinimal erlaubter Wert
maxintMaximal erlaubter Wert
stepintSchrittweite
formatstringAnzeige-Formatierungsstring
sliderint0 kein Slider · 1 nur Slider · 2 Slider + Werteingabe
listOfValuesobjectOptional: Map {"Schlüssel": "Bezeichnung"} der erlaubten Werte
globallovstringOptional: Schlüssel, der auf eine Modul- oder Controller-LOV verweist
lovScopestring"module" oder "controller" — wo die globallov definiert ist
lovConstrainedboolZeigt an, ob der Wert zur LOV gehören muss
nullableboolZeigt an, ob das Element leer bleiben darf (Frontend sollte eine “keine”-Option anbieten)

Typ: float

Gleiche Felder wie int, mit value, min, max, step als Gleitkommazahl.

Typ: bool

FeldTypBeschreibung
valuebooltrue oder false

Typ: string

FeldTypBeschreibung
valuestringTextwert
listOfValuesobjectOptional: Map {"Schlüssel": "Bezeichnung"} der erlaubten Werte
globallovstringOptional: Schlüssel, der auf eine LOV verweist
lovScopestring"module" oder "controller"
lovConstrainedboolZeigt an, ob der Wert zur LOV gehören muss
nullableboolZeigt an, ob das Element leer bleiben darf (Frontend sollte eine “keine”-Option anbieten)

Typ: date

FeldTypBeschreibung
valueobject{"year": int, "month": int (1-12), "day": int (1-31)}

Typ: time

FeldTypBeschreibung
valueobject{"hh": int, "mm": int, "ss": int, "ms": int}
usemsboolZeigt an, ob Millisekunden angezeigt werden sollen

Typ: datetime

FeldTypBeschreibung
valueobject{"year": int, "month": int, "day": int, "hh": int, "mm": int, "ss": int, "ms": int}

Typ: img

Das Feld value ist ein Objekt mit den Bild-Metadaten:

FeldTypBeschreibung
urljpegstringRelativer Pfad zum JPEG-Bild (mit der Basis-URL /ostmedia/ zu verwenden)
urlfitsstringRelativer Pfad zur FITS-Datei
urlthumbnailstringRelativer Pfad zum Thumbnail
urloverlaystringRelativer Pfad zum Overlay-Bild
channelsintAnzahl der Farbkanäle
width / heightintBildabmessungen in Pixeln
snrfloatSignal-Rausch-Verhältnis
hfravgfloatDurchschnittlicher HFR (Half-Flux-Radius) der erkannten Sterne
hfravgdevfloatStandardabweichung von hfravg
starsintAnzahl der erkannten Sterne
issolvedboolZeigt an, ob die Plate-Solving-Auflösung erfolgreich war
solverra / solverdefloatAufgelöste RA/Dec-Koordinaten
solverorientationfloatRotationswinkel des aufgelösten Feldes: von Norden zur Bildoberkante (Grad), nur relevant wenn issolved
solverpixscalefloatAufgelöste Pixelskala (Bogensekunden/Pixel), nur relevant wenn issolved
solverfieldwidth / solverfieldheightfloatAufgelöste Feldgröße (Bogenminuten), nur relevant wenn issolved
samplingfloatNominale Pixelskala (Bogensekunden/Pixel), berechnet aus der Brennweite/dem Reducer der Optik und der Pixelgröße der Kamera des Moduls — immer verfügbar, sobald Kamera und Optik konfiguriert sind, unabhängig von einer Auflösung (im Gegensatz zu den obigen solver*-Feldern)
min / max / mean / median / stddevfloat[]Statistiken pro Kanal (siehe unten)
histogramarrayHistogrammdaten pro Kanal (siehe unten)
alternatesstring[]Optional: alternative Versionen des Bildes
showstatsboolVom Modulentwickler festgelegt: ob die obigen Statistikfelder für dieses Bild aussagekräftig sind und angezeigt werden sollen (ein Modul kann dies auf false setzen, wenn es sie nicht berechnet oder sie nicht zutreffen)

Statistiken pro Kanal: min/max/mean/median/stddev sind Arrays mit 3 festen Plätzen, unabhängig von der tatsächlichen Kanalzahl — Index 0 = einzelner Kanal (Mono-Bild) oder Rot (R), 1 = Grün (G), 2 = Blau (B). Nur die ersten channels Plätze sind aussagekräftig; darüber hinaus sind die Werte null und bedeutungslos (ein Mono-Bild hat nur Index 0 befüllt).

Histogramm: Bin-Struktur

histogram folgt derselben Kanal-Logik (ein Array pro Kanal, nur die ersten channels verwendet), hat aber zwei Besonderheiten, die man vor der Nutzung kennen sollte:

  • Jeder Bin ist selbst in ein Array mit einem Element verpackt: histogram[Kanal][Bin] ist [Häufigkeit], nicht direkt Häufigkeit — ein Artefakt der aktuellen Backend-Serialisierung, kein Lesefehler auf Client-Seite.
  • Der Pixelwert, den jeder Bin repräsentiert, wird nicht direkt übertragen, nur die Häufigkeit. Die Anzahl der Bins variiert je Bild (histogram[Kanal].length); der Pixelwert von Bin i wird aus min/max desselben Kanals neu berechnet:
    bin_breite = (max[Kanal] - min[Kanal]) / (bin_anzahl - 1)
    wert(i)    = min[Kanal] + i × bin_breite
Media-URLs

Alle Bild-/Video-Pfade sind relativ. Mit http(s)://hostname/ostmedia/ voranstellen, um die vollständige URL zu erhalten.
Beispiel: "urljpeg": "Focus/frame.jpeg" → http://hostname/ostmedia/Focus/frame.jpeg

Medien werden getrennt vom WebSocket-Port bereitgestellt

Dieser hostname ist nicht aus dem Protokoll ableitbar — kein Feld im Dump liefert ihn, und es ist nicht der Host der gerade aufgebauten WebSocket-Verbindung. In der Referenz-Installation (siehe Neuinstallation) werden Medien von einem separaten Webserver bereitgestellt (nginx, standardmäßig Port 80, 443 hinter SSL) — ein völlig anderer Port als der WebSocket-Server (9624). Ein Client muss den Hostname des OST-Servers bereits kennen, oder ihn vom Nutzer konfigurieren lassen, unabhängig von der WebSocket-URL, und Medien-URLs gegen den HTTP-Port dieses Hostnamens aufbauen — nicht gegen den eigenen Ursprung der Seite und nicht gegen den WebSocket-Port. Ein Client, der einfach einen nackten /ostmedia/-Pfad voranstellt (aufgelöst relativ zu seinem eigenen Serving-Ursprung), bekommt kaputte Bilder.

Typ: video

FeldTypBeschreibung
valueobject{"url": "relativer/pfad/zum/video.mp4"}

In Nachrichten mit teilweisem Update (ea) kann das Video-Element url direkt auf Elementebene enthalten, statt in value verschachtelt.

Typ: light

FeldTypBeschreibung
valueint0 Ruhe · 1 OK · 2 Warnung · 3 Fehler

Typ: prg

FeldTypBeschreibung
valueobject{"value": float (0–100), "dynlabel": string}
prgtypestring"bar" oder "spinner"

Typ: message (im aktuellen Backend noch nicht implementiert)

Reserviert für die Anzeige von Nachrichten/Logs.


Wertelisten (LOV)

LOVs stellen eine Menge erlaubter Werte für Elemente vom Typ int, float und string bereit.

Lokale LOV — direkt im Element eingebettet:

"listOfValues": {
  "1": "Option Un",
  "2": "Option Deux"
}

Globale LOV — per Schlüssel referenziert:

"globallov": "myCameraModels",
"lovScope": "module"

Die LOV selbst wird auf Modulebene (globallovs) oder Controller-Ebene (lovs) definiert:

"myCameraModels": {
  "label": "Modèles de caméra",
  "type": "string",
  "values": {
    "ASI294MC": "ZWO ASI 294 MC",
    "ASI533MC": "ZWO ASI 533 MC"
  }
}

Eingebaute Controller-LOVs:

SchlüsselInhaltVerfügbar
loadedModulesAlle geladenen Module: {Modulname: Bezeichnung}Immer
loadedModules-<type>Module eines bestimmten Typs, passend zu infos.library (z. B. loadedModules-focus)Sobald ein Modul dieses Typs geladen ist
loadedFamilies-<family>Module, die eine bestimmte Familie deklarieren, passend zu infos.families (z. B. listet loadedFamilies-guiding jedes geladene Modul auf, das guiden kann, unabhängig von seinem tatsächlichen Typ)Sobald ein Modul, das diese Familie deklariert, geladen ist
profiles-<Type>Verfügbare Profile für einen Modultyp, passend zu infos.classname exakt — Achtung auf die Großschreibung, z. B. profiles-FocusSobald ein Profil dieses Typs gespeichert wurde

Zugriffskontrolle

Die Dump-Antwort enthält die Werte grant-server und grant-client.

grant-server ist die feste Zugriffsrichtlinie des Servers selbst (beim Serverstart festgelegt, für jeden Client gleich):

WertBedeutung
"0"Vollständiger Lese-Schreib-Zugriff, kein Login nötig — grant-client ist immer "1"
"1"Vollständiger Lesezugriff, kein Login nötig; der Schreibzugriff hängt von den Rechten des angemeldeten Benutzers ab — grant-client ist "0" oder "1"
"2"Ohne Login kein Zugriff; Lese- und Schreibzugriff hängen von den Rechten des angemeldeten Benutzers ab — grant-client ist "-1", "0" oder "1"

grant-client ist der aktuelle Grant dieser Verbindung, der sich nach einem erfolgreichen LO (Login) ändern kann:

WertBedeutung
"1"Vollständiger Lese-Schreib-Zugriff
"0"Nur Lesen
"-1"Zugriff verweigert (Authentifizierung erforderlich)

Ist grant-client gleich "-1", werden keine Moduldaten gesendet. Die LO-Nachricht (Login) zur Authentifizierung verwenden.