Problem mit IPS_SemaphoreEnter / Leave in eigenem Modul

Hi,

da Update ich mein eigenes RCT Modul im Store (nach diversen Tests), und nun schlägt das Ding quer… :frowning:

Mein Problem:

Ich habe eine Funktion UpdateData (per Timer), die regelmäßig Daten via Socket abfragt. Diese Methode setzt mittels IPS_SemphoreEnter eine Semphore.
In der ReceiveData Methode sammle ich dann über mehrere Calls hinweg die Antworten bis ich das Ende (der erwarteten Daten) habe. Anschließend verlasse ich dort (in der ReceiveData Methode) die Semaphore wieder. Nur: Die ist hier nicht bekannt!

Ergebnis


FlowHandler          | Kann Daten nicht zur Instanz #59352 weiterleiten: <br />
<b>Warning</b>:  Cannot find semaphore with name RCTPowerInverterUpdateData! in <b>/Library/Application Support/Symcon/modules/RCT-Power/RCT_POWER_INVERTER/module.php</b> on line <b>109</b><br />
RESULT:

ScriptEngine         | Semaphore RCTPowerInverterUpdateData für SkriptID 0 wurde nicht korrekt verlassen

Wieso? Und: War das schon immer so?

Ich habe mir auch mal parallel in einem Attribut gemerkt, ob ich die Semaphore gesetzt habe (bekommen habe) und wollte sie nur dann freigeben… gleiches Ergebnis. Ich bekomme die Semaphore im UpdateData zugeteilt, aber im ReceiveData ist sie nicht mehr bekannt (mein Attribut sagt aber, das ich sie haben sollte). Sollten Semaphoren nicht diverse Modulaufrufe überleben? Oder werden die irgendwie automatisch abgeräumt, sobald z.B. die Methode, welche die Semaphore bekommen hat, beendet ist?

Ja das war schon immer so.
Der Sinn ist, das nur der Thread der gerade läuft sich innerhalb Semaphore Enter und leave bewegen darf.
Und nur der Thread welches es gesetzt hat, muss sie auch verlassen.

Für deinen Anwendungsfall ist die auch nicht gedacht, sondern um zu verhindern das nicht auf geteilte Objekte (Buffer, IPS Variablen usw) parallel zugegriffen wird.

Wenn UpdateData nur die Datenabfrage startet, soll diese Funktion auf die empfangenen Daten warten, oder nicht?
Wenn ja, dann nach dem senden z.b. in einer Schleife auf einem Buffer prüfen und warten das dieser gefüllt ist.
Im ReceiveData, wenn der Datensatz komplett ist, diesen Buffer füllen.

Michael
PS: Ich habe dein Thema in den richtigen Bereich geschoben.

Hm. Soweit, so gut… so schlecht…

Mein Problem:
Solange es von meinem Modul nur eine Instanz gibt, ist alles ok. Funzt. Da brauche ich auch keine Semaphoren.

Wenn man aber mein Modul 2x verwendet (z.b. da 2 Wechselrichter), dann gibt es Probleme mit der Kommunikation, da die Wechselrichter leider nicht sonderlich „gesittet“ kommunizieren. Sprich: Sie plappern permanent durcheinander. Dies kann ich nur dadurch entwirren, das ich gezielt immer nur eine Instanz zur Zeit eine Abfrage senden lassen und diese erst ihre Daten erhalten haben muss, bevor die andere Instanz loslegen darf.

Also: Habt ihr eine geschickte Idee, wie man, ohne Semaphore, da die hier offensichtlich nicht funktionieren, die Instanzen untereinander Informieren kann, ob gerade eine andere Instanz kommuniziert? Gibt es da irgendein „geteiltes Element“ zwischen Instanzen desselben Moduls?

Das nennt sich Splitter.
Der wäre dann für den korrekten Zugriff auf den IO zuständig.

Theoretisch kannst du es auch mit dem Semaphore im Device lösen, aber dann nur in UpdateData. Diese Methode muss dann halt so lange warten bis alle Daten da sind und dann die Semaphore zurückgeben. (Blockiert dann natürlich einen PHP-Thread)
Außerdem sollte sich der Name von der Semaphore an den IO orientieren.
Wenn man mehrere Instanz an unterschiedlichen IOs hat, müssen die ja nicht unnötig warten.
Also doch besser gleich einen Splitter bauen :slight_smile:
Michael

Danke für den Gedankenanstoss. Werde das mal durchdenken und ausprobieren.

Gesendet von iPad mit Tapatalk Pro