Agire sul device
Modulo di esempio: helloindiactions.
In Creare proprietà dinamicamente, il pulsante d’azione modificava lo stato interno del modulo (hellodyn). Qui, l’azione modifica realmente qualcosa sul device — il device stesso la persiste, non il modulo.
HelloIndiActions::HelloIndiActions(...)
: IndiModule(...)
{
giveMeADevice("device", "Device", INDI::BaseDevice::GENERAL_INTERFACE);
giveMeAnActions();
OST::ElementBool *saveconfig = new OST::ElementBool("saveconfig", "Save device config", "1", "");
saveconfig->setDirectEdit(true);
getProperty("actions")->addElt(saveconfig);
}giveMeAnActions() costruisce la proprietà actions (vuota all’inizio); addElt() vi aggiunge l’elemento saveconfig, in C++, come in Creare proprietà dinamicamente — questo capitolo non cambia nulla al modo di costruire una proprietà, solo a ciò che accade quando viene azionata.
void HelloIndiActions::onExternalEvent(OST::ExtEvent event)
{
if (event.ev != OST::ExtEvType::SV || event.prpkey != "actions" || event.eltkey != "saveconfig") return;
sendModNewSwitch(getString("devices", "device"), "CONFIG_PROCESS", "CONFIG_SAVE", ISS_ON);
getEltBool("actions", "saveconfig")->setValue(false, true);
}CONFIG_PROCESS/CONFIG_SAVE è uno switch INDI standard, presente su ogni driver (salvare la configurazione corrente) — il che rende questo esempio testabile contro qualsiasi device connesso, senza dipendere da una funzionalità propria a un particolare simulatore.
Questi helper scrivono solo un unico elemento alla volta: recuperano la proprietà come attualmente conosciuta lato client, modificano il valore dell’elemento preso di mira, poi rinviano il vettore completo — gli altri elementi partono con il loro ultimo valore conosciuto, non necessariamente 0, non necessariamente quello che il driver si aspetta.
Esempio concreto: inviare un impulso di guida a una montatura. TELESCOPE_TIMED_GUIDE_NS ha due elementi, TIMED_GUIDE_N e TIMED_GUIDE_S — non si pulsa mai che in un solo senso alla volta, quindi il driver si aspetta di ricevere entrambi i valori a ogni invio, uno dei due valendo esplicitamente 0. Limitandosi a scrivere TIMED_GUIDE_N tramite sendModNewNumber(), TIMED_GUIDE_S riparte con il suo ultimo valore conosciuto — potenzialmente non nullo, cosa che il driver può semplicemente ignorare o interpretare male.
In questo genere di casi, è meglio scendere direttamente al livello INDI::BaseClient (vedi la panoramica: un IndiModule è un vero client INDI): costruire da soli l’INDI::PropertyNumber completo, fissare esplicitamente ogni elemento, poi chiamare direttamente sendNewNumber() — piuttosto che fidarsi di un helper pensato per il caso semplice di una proprietà con un solo elemento rilevante.