Master/Slave-Beziehung

Beispielmodule: hellomaster (der Master) und helloslave (der Slave).

Ein Modul kann ein anderes steuern, ausgewählt nach Instanz (seinem Namen, nicht seiner Klasse). Dieser Mechanismus erfordert keine INDI-Hardware — deshalb wird er hier behandelt und nicht im nächsten Kapitel.

Auf der Slave-Seite: sich als verfügbar deklarieren

HelloSlave::HelloSlave(...)
    : Basemodule(...)
{
    giveMeAState();                       // propriété "signals" : état + description
    setStateEvent(OST::Idle, "idle", "", "");
    declareFamily("hello");               // famille arbitraire pour cette paire
}
  • giveMeAState() erzeugt, auf Anfrage (wie alle giveMeA*()), die Property signals (Zustand + Beschreibung) — nichts Automatisches, ein nacktes Basemodule hat diese Property nicht standardmäßig.
  • setStateEvent(état, description, événement, description-événement, ...) aktualisiert sie in einem Zug.
  • declareFamily(nom) trägt das Modul in eine Familie ein — was automatisch eine Controller-Werteliste loadedFamilies-<nom> befüllt, auf die jeder beliebige Master verweisen kann, um dem Benutzer die Wahl einer Instanz zu ermöglichen. Keine Verbindung zu INDI: declareFamily() lebt auf Basemodule selbst.
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", "");
    }
}

Auf der Master-Seite: eine Instanz wählen und steuern

"slaves": {
  "permission": 2,
  "hasprofile": true,
  "e": {
    "slavemodule": {
      "type": "string",
      "directedit": true, "autoupdate": true,
      "value": "helloslave",
      "listOfValues": "loadedFamilies-hello",
      "listOfValuesIsExternal": true
    }
  }
}
Best Practice: die Property slaves ist hasprofile:true

Welcher Slave gesteuert werden soll, ist eine Benutzerentscheidung, die Neustarts überleben muss — ein Master, der das vergäße, würde seinen Slave bei jedem Neuladen des Moduls erneut abfragen müssen.

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

otherModuleSetValue(instance, propriété, élément, valeur) sendet, anhand des Instanznamens.

Beobachten, was der Slave zurückmeldet

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);
}
Ein Ereignis, an alle verteilt, von jedem gefiltert

Der Controller verteilt das Ereignis jedes beliebigen Moduls an alle geladenen Module — es gibt kein explizites Abonnement zu setzen. Es ist Aufgabe von onOtherModuleEvent(), selbst nach mod (dem Namen der interessierenden Instanz) zu filtern, wie oben.