Master/slave relationship

Example modules: hellomaster (the master) and helloslave (the slave).

A module can command another one, chosen by instance (its name, not its class). This mechanism requires no INDI hardware at all — which is why it’s covered here rather than in the next chapter.

On the slave side: declaring itself available

HelloSlave::HelloSlave(...)
    : Basemodule(...)
{
    giveMeAState();                       // propriété "signals" : état + description
    setStateEvent(OST::Idle, "idle", "", "");
    declareFamily("hello");               // famille arbitraire pour cette paire
}
  • giveMeAState() creates, on demand (like all giveMeA*() helpers), the signals property (state + description) — nothing automatic, a bare Basemodule doesn’t have this property by default.
  • setStateEvent(state, description, event, event-description, ...) updates it all at once.
  • declareFamily(name) registers the module in a family — which automatically feeds a controller list of values loadedFamilies-<name>, which any master can reference to let the user choose an instance. No connection to INDI: declareFamily() lives on Basemodule itself.
void HelloSlave::onExternalEvent(OST::ExtEvent event)
{
    if (event.eltkey == "dowork")
    {
        setStateEvent(OST::Busy, "working", "dowork", "");
        getEltBool("actions", "dowork")->setValue(false, true);
        // ... travail réel ...
        setStateEvent(OST::Ok, "ready", "dowork", "");
    }
}

On the master side: choosing an instance and commanding it

"slaves": {
  "permission": 2,
  "hasprofile": true,
  "e": {
    "slavemodule": {
      "type": "string",
      "directedit": true, "autoupdate": true,
      "value": "helloslave",
      "listOfValues": "loadedFamilies-hello",
      "listOfValuesIsExternal": true
    }
  }
}
Good practice: the slaves property is hasprofile:true

Which slave to command is a user choice that must survive restarts — a master that forgot it would have to ask for its slave again on every module reload.

otherModuleSetValue(getString("slaves", "slavemodule"), "actions", "dowork", true);

otherModuleSetValue(instance, property, element, value) sends it, by instance name.

Observing what the slave reports

void HelloMaster::onOtherModuleEvent(OST::EvType ev, QString mod, QString prp, QString elt, QVariant data, int line)
{
    if (mod != getString("slaves", "slavemodule")) return;
    if (ev != OST::EvType::ea || prp != "signals") return;

    QJsonObject o = data.toJsonValue().toObject()["e"].toObject();
    getEltLight("etat", "etat")->setValue(OST::IntToState(o["state"].toInt()), true);
}
An event broadcast to everyone, filtered by each

The controller broadcasts the event of any module to all loaded modules — there is no explicit subscription to set up. It’s up to onOtherModuleEvent() to filter itself on mod (the name of the instance it cares about), as above.