Mirroring a device property
Example module: helloindiwrite — a two-way mirror of GEOGRAPHIC_COORD.ELEV (a mount simulator, always available as soon as connected).
"mirror": {
"permission": 2,
"autoupdate": false,
"e": {
"elevation": {
"type": "float", "directedit": true, "autoupdate": false, "value": 0
}
}
}autoupdate:false at both levels (element and property) — see Reacting to a write and its logical-OR pitfall. Necessary here: the written value doesn’t really belong to the module’s datastore, it only makes sense once sent back to the device. Applying it automatically would be misleading — it would be displayed as acquired before the device had even confirmed anything.
Device → module
void HelloIndiWrite::onUpdateProperty(INDI::Property property)
{
if (QString(property.getDeviceName()) != getString("devices", "device")) return;
if (QString(property.getName()) != "GEOGRAPHIC_COORD") return;
INDI::PropertyNumber n = property;
for (unsigned int i = 0; i < n.count(); i++)
{
if (QString(n[i].name) == "ELEV")
{
getEltFloat("mirror", "elevation")->setValue(n[i].value, true);
}
}
}Same pattern as helloindi: filter on the device then on the INDI property name, here GEOGRAPHIC_COORD (a standard numeric vector).
Module → device
void HelloIndiWrite::onExternalEvent(OST::ExtEvent event)
{
if (event.ev != OST::ExtEvType::SV || event.prpkey != "mirror" || event.eltkey != "elevation") return;
QJsonObject o = event.data["m"].toObject()[getModuleName()].toObject();
double written = o["p"].toObject()["mirror"].toObject()["e"].toObject()["elevation"].toVariant().toDouble();
sendModNewNumber(getString("devices", "device"), "GEOGRAPHIC_COORD", "ELEV", written);
}Since nothing is auto-applied, the raw value written by the client must be extracted by hand from event.data — exactly the same mechanism as manualname in helloedit. sendModNewNumber(device, property, element, value) then sends it to the device over the INDI bus; it’s the actual update of the real GEOGRAPHIC_COORD.ELEV, coming back through onUpdateProperty() above, that closes the loop by confirming the value in mirror.elevation.