HSL2.0 - Kommunikation zwischen Logikbaustein-Instanzen
Inhalt
1.
Einleitung
2.
Beispiel

## 1.Einleitung

Das HSL 2.0-Framework bietet die Möglichkeit, dass Logikbausteine auf Instanzen anderer Bausteine zugreifen können.
Dies ermöglicht die Kommunikation von Logikbaustein-Instanzen untereinander.
Im Framework sind zwei Methoden vorhanden, um eine Instanz zu erhalten:

- get_instance_by_id(instance_id)
- get_instance_from_module_by_id(module_context, instance_id)

Beide Methoden liefern als Ergebnis die zu instance_id zugehörige Logikbaustein-Instanz zurück (oder `None` wenn die instance_id ungültig ist). Der Unterschied zwischen den beiden Methoden liegt darin, dass get_instance_by_id(instance_id) nur auf Instanzen aus dem gleichen Modulkontext zugreifen kann. Die Methode get_instance_from_module_by_id(module_context, instance_id) liefert unter Angabe des entsprechenden Modulkontexts auch eine Instanz aus einem anderen Modulkontext.
Die instance_id ist eine vom Framework zur Laufzeit des HomeServers eindeutig vergebene ID für die jeweilige Instanz eines Bausteins. Sie stimmt nicht mit der fünfstelligen Baustein-ID (z.B. 19042) überein. Die instance_id (auch Laufzeit-ID genannt) kann über die Methode _get_module_id() (des BaseModule) ermittelt werden. Folgender Beispielcode würde die eigene Instanz (also self) zurückliefern:

`self.FRAMEWORK.get_instance_by_id(self._get_module_id())`

Die Laufzeit-ID kann einfach über die Verdrahtung von Ein- und Ausgängen zwischen Logikbausteinen ausgetauscht und bekannt gemacht werden.

## 2.Beispiel

Folgendes Beispiel zeigt die Kommunikation zwischen Logikbaustein-Instanzen. Dazu wurden 2 Logikbausteine entworfen. Diese 2 Bausteine werden zur Konfiguration von 3 Lautsprechern (Player) in 3 Räumen, die sich innerhalb eines Haushalts (Büro) befinden, genutzt.
Die Demo-Bausteine finden Sie auch im Beispiel-Ordner unter "`\communication_between_instances`"
Achtung
Die hier verwendeten Bausteine enthalten zum großen Teil nur Dummy-Code und dienen allein als anschauliches Beispiel. Sie sollten auf keinen Fall produktiv eingesetzt werden!

### 2.1.Übersicht der Konfiguration im grafischen Logikeditor

### 2.2.Beschreibung der Bausteine

#### 2.2.1.Household Baustein

Dieser Baustein enthält den spezifischen Programmcode und regelt zentral die Kommunikation mit der (fiktiven) SpeakerSystem-API. Ein Household (=Haushalt) bündelt logisch alle im Büro befindlichen SpeakerSystem Devices.
Der Baustein sendet nach Initialisierung der Logik seine Laufzeit-ID auf Ausgang 1 und macht diese damit den Player Bausteinen bekannt.

#### 2.2.2.Player Baustein

Dieser Baustein repräsentiert jeweils einen Player (PLAY:1, PLAY:3, usw.). In diesem Beispiel befindet sich jeder Player in einem eigenen Raum im Büro. Jeder Player Baustein (bzw. jede Instanz des Bausteins) erhält die Laufzeit-ID des Household Bausteins über Eingang 1. Damit kann er auf die Methoden des Household Bausteins zugreifen und muss nicht direkt mit der SpeakerSystem-API kommunizieren.

### 2.3.Ablauf der Kommunikation

Um den Ablauf der Kommunikation zwischen den Bausteinen im Detail zu zeigen, wird im Folgenden jeweils auf die Stellen im Quellcode verwiesen. Jeder Codezeile wird zur besseren Übersicht die entsprechende Zeile im jeweiligen Quellcode des Bausteins vorangestellt. Der Quellcode des Household Bausteins befindet sich in der Datei 10705_SpeakerSystem Household.py. Der Quellcode des Player Bausteins befindet sich in der Datei 10706_SpeakerSystem Player.py.

#### 2.3.1.Nach Start des HS

1. Household Baustein ermittelt seine Laufzeit-ID:

   `20 module_id = self._get_module_id()`

2. Household Baustein sendet seine Laufzeit-ID auf den Ausgang:

   `21 self._set_output_value(self.PIN_O_SPEAKERSYSTEM_PLAYER, module_id)`

3. Player Baustein ruft die Instanz des Household Bausteins mit Hilfe der Laufzeit-ID (value) ab und merkt sich diese:

   `25 self.household_instance = self.FRAMEWORK.get_instance_by_id(value)`

   (Dies passiert jeweils einmal pro Instanz des Player Bausteins. Also insgesamt drei mal.)
4. Player Baustein registriert eine Callback-Methode (self.on_trackinfo_event) beim Household Baustein. Diese wird vom Household Baustein aufgerufen, sobald das aktuell gespielte Lied geändert wird:

   `28 self.household_instance.register_for_trackinfo_update(self._get_input_value(self.PIN_I_DEVICE_ID), self.on_trackinfo_event)`

   (Dies passiert jeweils einmal pro Instanz des Player Baustein. Also insgesamt drei mal.)

#### 2.3.2.Player Baustein zur Laufzeit

Zur Laufzeit trifft auf Eingang 3 des Player Bausteins ein Wert ein

1. Der Player Baustein ruft die Methode do_play_or_pause(device_id) des Household Bausteins auf:

   `33 self.household_instance.do_play_or_pause(self._get_input_value(self.PIN_I_DEVICE_ID))`

#### 2.3.3.Household Baustein zur Laufzeit

Zur Laufzeit erhält der Household Baustein eine Änderung des aktuell gespielten Liedes

1. Der Household Baustein sucht anhand der mitgelieferten Client ID das entsprechende Callback und führt (wenn vorhanden) dieses aus:

   `55 if device_id in self.registered_devices.keys(): 56 self.registered_devices[device_id](args["info"])`