Messaggi Server → Client
Formato dei messaggi
Ogni messaggio è un oggetto JSON con una sola chiave di primo livello. Questa chiave codifica il tipo di evento e può includere una descrizione leggibile separata da un trattino:
"aa-dump all data" → tipo evento = primi 2 caratteri = "aa"
"ea" → tipo evento = "ea"
"d" → tipo evento = "d" (carattere unico)I client devono confrontare i primi 1 o 2 caratteri della chiave, non l’intera stringa, poiché la parte descrittiva può cambiare.
Tutte le chiavi degli eventi inviate dal server sono in minuscolo (es. d, ea, ap, gc).
Indice dei tipi di evento
| Chiave | Descrizione |
|---|---|
d | Dump iniziale completo (risposta a DU) |
aa | Dump completo di un modulo (modulo caricato/ricaricato) |
ap | Sostituzione completa di una proprietà |
ea | Aggiornamento di tutti i valori degli elementi di una proprietà |
ee | Aggiornamento di un singolo valore di elemento |
ev | Aggiornamento di un valore di elemento con i suoi vincoli |
el | LOV locale dell’elemento modificata |
ps | Aggiornamento dello stato e dell’abilitazione di una proprietà |
dm | Modulo eliminato |
dp | Proprietà eliminata |
gc | Riga di griglia creata |
gu | Riga di griglia aggiornata |
gd | Riga di griglia eliminata |
gr | Reset della griglia (tutte le righe eliminate) |
lc | LOV creato o fuso |
lu | LOV sostituito |
ld | LOV eliminato |
fs | Profilo salvato |
fl | Profilo caricato |
fc | Profilo modificato (modifiche non salvate) |
l | Voce di log |
uc | Aggiornamento dei dati del controller |
af | File aggiunto |
df | File eliminato |
ad | Cartella aggiunta |
dd | Cartella eliminata |
qa | Risposta a una richiesta di modulo (meccanismo inter-modulo, non destinato al client) |
xx | Pong keepalive |
d — Dump iniziale completo
Inviato in risposta a una richiesta DU. Contiene tutto: tutti i moduli, i log, gli elenchi di file e i dati del controller. Il dettaglio delle chiavi di controllerdata e di files è in Controller, GlobalDatastore e file; l’esempio seguente ne mostra solo alcune.
{
"d": {
"grant-client": "1",
"grant-server": "0",
"serverlng": "en",
"m": {
"Focus": {
"infos": { "modulelabel": "Focus", "description": "..." },
"f": { "name": "default", "changed": false },
"l": {
"myLov": { "label": "My LOV", "type": "string", "values": { "a": "Option A" } }
},
"p": {
"parameters": {
"label": "Parameters",
"order": "10",
"level1": "Focus",
"level2": "Config",
"status": 0,
"permission": 2,
"enabled": true,
"showElts": true,
"hasGrid": false,
"hasGraph": false,
"rule": 0,
"badge": false,
"preicon1": "", "preicon2": "", "posticon1": "", "posticon2": "",
"hasprofile": true,
"freevalue": "",
"e": {
"iterations": {
"type": "int",
"label": "Iterations",
"order": "10",
"hint": "",
"autoupdate": false,
"badge": false,
"directedit": false,
"value": 5,
"min": 1,
"max": 20,
"step": 1,
"format": "",
"slider": 0
}
}
}
}
}
},
"files": {
"folders": ["", "/Allsky", "/Allsky/archives"],
"files": ["/image.jpeg"],
"selectedfolder": "/home/user/ostmedia"
},
"logs": [
{ "d": "2024-01-01T12:00:00.000", "c": "Focus", "t": "Module loaded", "l": 1 }
],
"controllerdata": {
"profiles": {
"Focus": ["default", "test"]
},
"currentconf": "default"
},
"lovs": {
"sharedLov": { "label": "Shared LOV", "type": "string", "values": {} }
}
}
}m = modules, p = properties, e = elements, l = globallovs, f = profile.
Normalizzare queste abbreviazioni ai loro nomi completi durante la memorizzazione interna.
aa — Dump completo di un modulo (modulo caricato/ricaricato)
Inviato quando un modulo viene caricato o ricaricato a runtime. Contiene lo stato completo del modulo. La chiave inizia con "aa".
{
"aa-dump all data": {
"Guider": {
"infos": { "modulelabel": "Guider", "description": "..." },
"f": { "name": "default", "changed": false },
"l": {},
"p": {
"status": { ... }
}
}
}
}ap — Sostituzione completa di una proprietà
Sostituisce interamente una o più proprietà. La chiave inizia con "ap".
{
"ap-dump all property data": {
"Focus": {
"p": {
"parameters": {
"label": "Parameters",
"status": 0,
"permission": 2,
"enabled": true,
"showElts": true,
"hasGrid": false,
"hasGraph": false,
"rule": 0,
"e": {
"iterations": {
"type": "int",
"value": 7,
"min": 1, "max": 20, "step": 1,
"label": "Iterations", "order": "10", "hint": "",
"autoupdate": false, "badge": false, "directedit": false,
"format": "", "slider": 0
}
}
}
}
}
}
}ea — Aggiornamento di tutti i valori degli elementi (livello proprietà)
Il messaggio di aggiornamento più comune. Invia i valori correnti di tutti gli elementi di una proprietà. Contiene solo i valori — senza metadati. La chiave è esattamente "ea".
{
"ea": {
"Allsky": {
"p": {
"coming": {
"e": {
"sunrise": { "hh": 7, "mm": 6, "ss": 51 },
"sunset": { "hh": 21, "mm": 15, "ss": 1 }
}
}
}
}
}
}Per i tipi semplici (int, float, bool, string, light), il valore è uno scalare:
{
"ea": {
"Focus": {
"p": {
"parameters": {
"e": {
"iterations": 5,
"exposure": 3.5,
"active": true
}
}
}
}
}
}ee — Aggiornamento di un singolo valore di elemento
Aggiorna il valore di un singolo elemento. Stesso formato di ea ma per un solo elemento. La chiave è esattamente "ee".
{
"ee": {
"Focus": {
"p": {
"parameters": {
"e": {
"iterations": 7
}
}
}
}
}
}ee è solo di origine backendee viene inviato solo per iniziativa del backend stesso (es. un cambio di valore proveniente da un device, un polling interno) — mai come risposta diretta a una scrittura del client. Qualsiasi risposta a un SV o SA avviato dal client è sempre un ea dell’intera proprietà, indipendentemente dal numero di elementi effettivamente cambiati.
ev — Aggiornamento di un elemento con metadati
Aggiorna il valore di un elemento e i suoi vincoli (min, max, format). La chiave inizia con "ev".
{
"ev-set one element value/min/max/format ": {
"Focus": {
"p": {
"parameters": {
"e": {
"temperature": {
"value": 12.5,
"min": -40.0,
"max": 80.0,
"format": "%.1f"
}
}
}
}
}
}
}el — LOV locale modificata
Inviato quando la lista di valori locale (listOfValues) di un elemento viene aggiunta, aggiornata o svuotata per iniziativa del server stesso — ad es. i nomi degli slot di una ruota portafiltri (ri)letti dal device. La chiave inizia con "el". Stesso formato di payload di ev (valore corrente, vincoli e listOfValues sono tutti inclusi), ma a differenza di ev questo evento non marca mai come modificato il profilo di una proprietà hasprofile (fc): una LOV locale è decorativa, non un valore di profilo memorizzato.
{
"el-element's own local lov changed": {
"Sequencer": {
"p": {
"sequence": {
"e": {
"filter": {
"value": 1,
"listOfValues": { "1": "Luminance", "2": "Red", "3": "Green", "4": "Blue" }
}
}
}
}
}
}
}ps — Aggiornamento dello stato di una proprietà
Aggiorna solo i campi status e enabled di una proprietà. La chiave inizia con "ps".
{
"ps-only property state": {
"Focus": {
"p": {
"autofocus": {
"status": 2,
"enabled": true
}
}
}
}
}Valori di stato: 0 Standby · 1 OK · 2 Occupato · 3 Errore
dm — Modulo eliminato
Inviato quando un modulo viene scaricato. Il client deve eliminare tutti i dati di questo modulo. La chiave inizia con "dm".
{
"dm-delete/remove module": {
"Focus": {}
}
}dp — Proprietà eliminata
Inviato quando una proprietà viene rimossa da un modulo. La chiave inizia con "dp".
{
"dp-delete/remove property": {
"Focus": {
"p": {
"oldProperty": ""
}
}
}
}gc — Riga di griglia creata
Inviato dopo l’aggiunta di una nuova riga in una proprietà di tipo griglia. La chiave inizia con "gc".
{
"gc-grid new line ": {
"Sequencer": {
"p": {
"sequence": {
"i": 3,
"values": {
"target": "M31",
"exposure": 120,
"count": 10
}
}
}
}
}
}i è l’indice della riga appena creata. values è un oggetto indicizzato per nome elemento.
gu — Riga di griglia aggiornata
Inviato quando una riga esistente della griglia viene modificata. La chiave inizia con "gu".
{
"gu-grid update line": {
"Sequencer": {
"p": {
"sequence": {
"i": 1,
"values": {
"target": "M42",
"exposure": 60,
"count": 20
}
}
}
}
}
}gd — Riga di griglia eliminata
Inviato quando una riga della griglia viene rimossa. La chiave inizia con "gd".
{
"gd-grid delete line": {
"Sequencer": {
"p": {
"sequence": {
"i": 0
}
}
}
}
}i è l’indice (base zero) della riga eliminata. Le righe successive si spostano di una posizione verso l’alto.
gr — Reset della griglia
Elimina l’intera griglia di una proprietà. La chiave inizia con "gr".
{
"gr-grid reset": {
"Sequencer": {
"p": {
"sequence": {}
}
}
}
}lc / lu / ld — Eventi LOV
lc — LOV creato/fuso (chiave inizia con "lc"):
LOV di modulo:
{
"lc-lov create": {
"Focus": {
"l": {
"myLov": {
"label": "My LOV",
"type": "string",
"values": { "a": "Option A", "b": "Option B" }
}
}
}
}
}LOV del controller (senza involucro modulo, usa la chiave lovs):
{
"lc-lov create": {
"lovs": {
"sharedLov": {
"label": "Shared LOV",
"type": "string",
"values": { "x": "Value X" }
}
}
}
}lu — LOV sostituito (stesso formato di lc, sostituzione completa).
ld — LOV eliminato (chiave inizia con "ld"):
{
"ld-lov delete": {
"lovs": {
"sharedLov": {}
}
}
}fs / fl / fc — Eventi di profilo
Inviati quando un profilo viene salvato, caricato o modificato.
{
"fs-profile saved": {
"Focus": {
"f": { "name": "myProfile", "changed": false }
}
}
}| Prefisso chiave | Evento |
|---|---|
fs | Profilo salvato |
fl | Profilo caricato |
fc | Profilo con modifiche non salvate |
l — Voce di log
Inviato per ogni messaggio di log generato dal server. La chiave è esattamente "l".
{
"l": {
"d": "2024-01-01T12:00:00.000",
"c": "Focus",
"t": "Autofocus completed successfully",
"l": 1
}
}| Campo | Descrizione |
|---|---|
d | Data/ora ISO 8601 con millisecondi |
c | Contesto/fonte (nome del modulo o "WS") |
t | Testo del messaggio (tradotto nella lingua del client) |
l | Livello: 0 Debug · 1 Info · 2 Avviso · 3 Errore · 4 Critico |
uc — Aggiornamento dei dati del controller
Inviato quando i dati globali del controller cambiano: profili, configurazioni, driver INDI attivi, elenchi di file (files, folders), carico del sistema (systemwatcher, ogni 10 s per impostazione predefinita). La chiave inizia con "uc". Le chiavi possibili sono descritte in Controller, GlobalDatastore e file.
{
"uc-update controller data": {
"profiles": {
"Focus": ["default", "highres"],
"Guider": ["default"]
}
}
}Il payload è {"chiave": valore} dove valore può essere una stringa, un array o un oggetto. Ogni messaggio porta una sola chiave e il suo valore sostituisce interamente quello precedente.
af / df / ad / dd — Eventi di file e cartella
Inviato a tutti i client quando il contenuto della cartella di file sorvegliata cambia (vedi File system). A differenza degli altri messaggi, il valore è una stringa nuda: il percorso interessato, non racchiuso in un oggetto o array — il server segnala sempre un solo percorso per messaggio.
{ "af": "/Allsky/image_001.jpeg" }
{ "df": "/Allsky/old_image.jpeg" }| Chiave | Significato |
|---|---|
af | File aggiunto alla cartella selezionata |
df | File eliminato dalla cartella selezionata |
ad | Sottocartella aggiunta ovunque nel webroot |
dd | Sottocartella eliminata ovunque nel webroot |
af/df riguardano solo la cartella attualmente selezionata tramite FS — non viene segnalato nulla per il contenuto delle altre cartelle. ad/dd sono globali: si attivano per l’intero albero del webroot, indipendentemente da cosa è attualmente selezionato. Vedi File system per il quadro completo.
qa — Risposta a una richiesta di modulo
Vedi la nota su QY: questo meccanismo esiste principalmente perché un modulo ne interroghi un altro internamente. Documentato qui per completezza, non come funzionalità destinata al client.
Risposta a una richiesta QY. QY/qa è un meccanismo generico di richiesta/risposta specifico per modulo: un client (o un altro modulo, internamente) pone a un modulo una domanda nominata con parametri, e riceve indietro una risposta nominata. Quali nomi di richiesta un modulo comprenda realmente, e la forma della sua risposta, dipende interamente da quel modulo — il protocollo definisce solo l’involucro, non il contenuto.
{
"qa-query answer": {
"Sequencer": {
"q": {
"query": "profileduration",
"result": { "seconds": 3600 }
}
}
}
}result è ciò che il modulo ha restituito per quella richiesta — la sua forma dipende interamente da query. Un modulo senza un caso corrispondente al nome query richiesto restituisce silenziosamente un result vuoto.
Oggi solo il modulo Sequencer implementa una vera risposta (profileduration), usata internamente dal modulo Planner piuttosto che da un qualsiasi flusso client documentato. Nessun altro modulo distribuito risponde in modo significativo a nessun nome di richiesta per ora — il meccanismo esiste ed è completamente cablato, ma c’è ancora poco da interrogare in pratica.
xx — Pong keepalive
Inviato dal server in risposta a un heartbeat client (XX). Nessun payload utile; i client possono ignorarlo.
{ "xx": {} }