Relazione master/slave

Moduli di esempio: hellomaster (il master) e helloslave (lo slave).

Un modulo può comandarne un altro, scelto per istanza (il suo nome, non la sua classe). Questo meccanismo non richiede alcun hardware INDI — è per questo che è trattato qui piuttosto che nel capitolo successivo.

Lato slave: dichiararsi disponibile

HelloSlave::HelloSlave(...)
    : Basemodule(...)
{
    giveMeAState();                       // propriété "signals" : état + description
    setStateEvent(OST::Idle, "idle", "", "");
    declareFamily("hello");               // famille arbitraire pour cette paire
}
  • giveMeAState() crea, su richiesta (come tutti i giveMeA*()), la proprietà signals (stato + descrizione) — nulla di automatico, un Basemodule nudo non ha questa proprietà per default.
  • setStateEvent(stato, descrizione, evento, descrizione-evento, ...) la aggiorna in un colpo.
  • declareFamily(nome) iscrive il modulo in una famiglia — il che alimenta automaticamente una lista di valori controller loadedFamilies-<nome>, che qualsiasi master può referenziare per lasciare che l’utente scelga un’istanza. Nessun legame con INDI: declareFamily() vive su Basemodule stesso.
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", "");
    }
}

Lato master: scegliere un’istanza e comandare

"slaves": {
  "permission": 2,
  "hasprofile": true,
  "e": {
    "slavemodule": {
      "type": "string",
      "directedit": true, "autoupdate": true,
      "value": "helloslave",
      "listOfValues": "loadedFamilies-hello",
      "listOfValuesIsExternal": true
    }
  }
}
Buona pratica: la proprietà slaves è hasprofile:true

Quale slave comandare è una scelta dell’utente che deve sopravvivere ai riavvii — un master che la dimenticasse richiederebbe il suo slave a ogni ricaricamento del modulo.

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

otherModuleSetValue(istanza, proprietà, elemento, valore) invia, per nome di istanza.

Osservare ciò che lo slave riporta

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);
}
Un evento diffuso a tutti, filtrato da ciascuno

Il controller diffonde l’evento di qualsiasi modulo a tutti i moduli caricati — non esiste alcuna sottoscrizione esplicita da fare. Sta a onOtherModuleEvent() filtrare da solo su mod (il nome dell’istanza di interesse), come sopra.