Actuar sobre el device
Módulo de ejemplo: helloindiactions.
En Crear propiedades dinámicamente, el botón de acción modificaba el estado interno del módulo (hellodyn). Aquí, la acción modifica realmente algo en el device — el propio device lo persiste, no el módulo.
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() construye la propiedad actions (vacía al principio); addElt() le añade el elemento saveconfig, en C++, como en Crear propiedades dinámicamente — este capítulo no cambia nada en la forma de construir una propiedad, solo en lo que ocurre cuando se activa.
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 es un switch INDI estándar, presente en todo driver (guardar la configuración actual) — lo que hace que este ejemplo sea comprobable contra cualquier device conectado, sin depender de una funcionalidad propia de un simulador en particular.
Estos helpers solo escriben un solo elemento a la vez: recuperan la propiedad tal como se conoce actualmente del lado del cliente, modifican el valor del elemento señalado, y luego devuelven el vector completo — los demás elementos se van con su último valor conocido, no necesariamente 0, no necesariamente el que el driver espera.
Ejemplo concreto: enviar un pulso de guiado a una montura. TELESCOPE_TIMED_GUIDE_NS tiene dos elementos, TIMED_GUIDE_N y TIMED_GUIDE_S — nunca se pulsa más que en un solo sentido a la vez, así que el driver espera recibir los dos valores en cada envío, uno de ellos valiendo explícitamente 0. Al limitarse a escribir TIMED_GUIDE_N mediante sendModNewNumber(), TIMED_GUIDE_S se va con su último valor conocido — potencialmente no nulo, lo que el driver puede simplemente ignorar o interpretar mal.
En este tipo de casos, es mejor bajar directamente al nivel INDI::BaseClient (ver la vista de conjunto: un IndiModule es un verdadero cliente INDI): construir uno mismo el INDI::PropertyNumber completo, fijar explícitamente cada elemento, y luego llamar directamente a sendNewNumber() — en lugar de confiar en un helper pensado para el caso simple de una propiedad con un solo elemento relevante.