Grundsätzliche Fragen zur Modulerstellung

So! Wieder ein Stück weiter - Dank für die Tipps!:slight_smile:

Jetzt jängt es glaube ich daran, dass weder der Name der vergeben soll gesetzt wird, noch die Instanz an der vorgesehene Stelle im Hierarchiebaum einsortiert wird!

Woran könnte das liegen?

Joachim

Module.json den Typ und den Alias-Namen angepasst?
Wenn der Typ 3 ist wird sie im Baum dort einsortiert wo du die Instanz erstellst, bei allen anderen wird es automatisch in Kern, IO oder Splitter erstellt.
Michael

…das funktioniert so weit, jedoch wird der in Feld „Name“ angegebene Text nicht übernommen (bleibt leer) als auch der Ort (wird als neue Instanz unter der Hauptkategorie angelegt).

Joachim

Name ist ja immer die PHP-Klasse.
Im Objektbaum wird der nur als Name übernommen, Wenn beim Erzeugen kein Fehler geworfen wird.
Tritt ein Fehler auf, bleibt der Name leer im Baum.
Könnte auf den Ort auch zutreffen.
Weil erst erzeugt IPS mit Create die Instanz und dann setzt IPS den Ort und den Namen.
Michael

Hallo Michael,

magst Du hierbitte noch mal einen Blick drauf werfen?

Ich habe jetzt eigentlich alles gelöscht was m.E. nicht erforderlich ist.

Aber vielleicht liegt es ja nach den vielen Fehlversuchen ja auch am IPS. Mir ist aufgefallen das nach einem Restart das oberste Objekte im Verzeichnisbaum immer wieder von „IP-Symcon“ auf „unnamed“ geändert wird und auch immer wieder ein „Virtual I/O“ angelegt wird…:eek:

Joachim

Ich verwende das Parent-Schild-Muster in meinen Modulen recht intensiv.
-Das ws300pc-Modul ist z.B. ein Splitter, das Daten vom SerialPort-Modul bekommt und N WetterDevice befüllt.
-Das NUT-Modul bekommt seine Daten über das ClientSocket-Modul und verteilt an EnergyDevices, die dann jeweils eine USV repräsentieren.
-Die AVMAHA und XS1 Module holen sich ihre Daten selber via http und verteilen dann pro Sensor/Aktor an Wetter-, Energy- und SwitchDevices. Die SwitchDevices können ihrerseits wieder Befehle über die Splitter an die Aktoren senden.

HTH
Tommi

Also wenn ich einen Dimmer hinzufüge bekomme ich diverse Fehler, welche sowohl das platzieren im Baum als auch die korrekte Benennung verhindern:


IP-Symcon Management Console [127.0.0.1]

<br />
<b>Warning</b>:
in <b>C:\IP-Symcon\scripts__ipsmodule.inc.php</b> on line <b>308</b><br />
<br />
<b>Warning</b>: Instanz #0 existiert nicht in <b>C:\IP-Symcon\scripts__ipsmodule.inc.php</b> on line <b>309</b><br />
<br />
<b>Warning</b>: Datenfluss für Instanz #0 existiert nicht in <b>C:\IP-Symcon\scripts__ipsmodule.inc.php</b> on line <b>311</b><br />


OK

Ursachen:

Du hast diverse Leerzeilen außerhalb der PHP-Tags, das wird als Fehler angesehen und verhindert somit die korrekte Abarbeitung innerhalb von IPS.

Die anderen Fehler sollten dann verschwinden (Folgefehler).
Außer dass jedesmal ein neuer Parent angelegt wird, dass liegt an deinem ForceParent.
ConnectParent wäre da die bessere Wahl.

Hier mal ein Fork:
GitHub - Nall-chan/SymconModules

Soll das Modul nachher auch unter meinem Windows-IPS laufen um die GPIOs eines entfernen PIs anzusprechen ?

Michael

SUPER!!!

Kaum macht man es richtig, funktioniert es!!!:):slight_smile:

Vielen, vielen Dank!!

Joachim

Bitte, häufig ist der Rechner nicht zur Hand zum helfen. :wink:
Michael

…nun, derzeit kämpfe ich mit Zeitmangel, Leerzeilen an der falschen Stelle, zufällig ausgewählten aber dennoch „falschen“ Dateinamen…
Vieles ist für mich absolutes Neuland in diesem Projekt.
Der erste Schritt soll aber der Raspberry Pi als IPS-Basis sein. Ob ich das dann alles so weit hinbekomme ist ja aktuell schon fraglich, wenn aber doch, dann sollte es irgendwann auch auf Windows laufen - so wie ich bisher vorangekommen bin ist das aber offensichtlich noch ein weiter Weg…:wink:

Joachim

Hallo Leute,

Dank Eurer Unterstützung und der Beispiele geht es kontinuierlich weiter - mühsam ernährt sich das Eichhörnchen!:wink:

Es gibt aber noch Fragen die mich beschäftigen:

Wie macht man die Einträge in dem „Select“-Formularfeld der Konfigurationsformulare „dynamisch“?

Hintergrund: Je nach Auswahl des Raspberry Pi-Typs sind ja verschiedene Anzahl und GPIO-Pin-Nummern verfügbar. Zum einen sollten im Grundsatz also nur die Pin-Nummern zur Auswahl stehen, die überhaupt verfügbar sind, zum anderen sollten die GPIO-Pin nicht mehr angeboten werden, die schon in einer der Funktionen genutzt werden.

Gibt es irgendwo ein Beispiel, wo das Drop-Down-Formularfeld seine Einträge aus einem Array einliest?

Joachim

Aktuell gar nicht. Es soll aber wiederkommen, im Delphi-SDK ging es auch.
Michael

…Okay, dann „Plan B“…:wink:

In dem Modul gibt es folgende Funktion:

	public function ReceiveData($JSONString) 
	{
    	// Empfangene Daten vom Gateway/Splitter
    	$data = json_decode($JSONString);
    	IPS_LogMessage("ReceiveData", utf8_decode($data->Buffer));
 
    	}

Diese hatte ich - soweit ich die Dokumentation verstanden habe - eingerichtet, um Daten aus dem Python-Skript zu empfangen. Hier wird per JSON-RPC mit Variablen ID = ID der Modul Instanz ein Wert gesendet, dieses sollte nach dem Skript einen Log-Eintrag zur Folge haben. Funktioniert so aber aus mir unbekannten Gründen nicht. Habe ich die Funktion an sich falsch verstanden?

Zum anderen: Wie sollten man Werte (Variablen) in den Modulen erstellen/ablegen, die erhalten bleiben solange IPS läuft und die von außen weder sichtbar noch manipulierbar sind?

Joachim

ReceiveData empfängt die Daten die vom Parent durchgereicht werden. Vom Parent müssen die Daten über SendDataToChildren
SendDataToChildren — IP-Symcon :: Automatisierungssoftware
weitergeleitet werden. Da bei Dir im Parent aber nix per senddatatochildren gesendet wird kann bei den Children auch nix über ReceiveData ankommen. Wenn Du die Daten von dem Python Script nach IPS bringen willst kannst Du entweder über einen Webhook gehen oder eine Variable in IPS per JSON RPC ändern und das Modul zur Laufzeit prüfen lassen ob sich die Variable geändert hat. Oder aber Du nutzt doch einen Clientsocket und schickst die Daten mit dem Pythonscript an den Clientsocket. Wahrscheinlich ist es das einfachste Vorgehen eine Variable in IP-Symcon entweder per Webhook oder über die JSON RPC von Python aus zu beschreiben. Dort liegt ein Ereignis drauf bei Variablenaktualisierung. Das Ereignis triggert dann eine Funktion im Modul die die Variable ausliest und an die Children durchreicht. Das bastelst Du Dir alles in den I/O und schickst die Daten dann per senddatatochildren an die Children. Dann kommt auch was bei ReceiveData an. Du must aber, wenn dies selektiv ausgewertet werden soll, bei senddatatochildren noch mitgeben an wen das eigentlich gedacht ist. Dazu baust Du den Buffer von SendDataToChildren als Array auf der aus den eigentlich zu sendenden Daten und einen Key besteht, der bezeichnet für welchen Typ von Children das Datenpaket gedacht ist. Bei ReceiveData liest Du dann den Buffer aus und prüfst im Array ob das Datenpaktet auch wirklich für den Children bestimmt ist. Wenn ja, kannst Du dann den Wert aus dem Buffer Array auslesen und diesen weiterverarbeiten. Da ja mehrere Children unterhalb des Parents hast und senddatatochildren die Daten an alle Children weiterreicht kommen die Daten auch bei allen Children an.

Du kannst einfach eine Eigenschaft der Klasse nutzten. Diese gibst Du nicht im Formular an. Vorhanden ist diese ja trotzdem nur für den User im ersten Moment nicht sichtbar. Also einfach im Create eine weitere Eigenschaft definieren. Manipulieren läst sich diese dennoch von außen auch vom User wenn er den Namen der Eigenschaft kennt mit
IPS_SetProperty — IP-Symcon :: Automatisierungssoftware
Du kannst auch innerhalb einer Funktion halt Variablen nutzten das geht aber halt auch nur zur Laufzeit.

Hallo Fonzo,

vielen Dank erst einmal für Deine ausführliche Antwort.

Ich habe nun im „Create-Bereich“ per RegisterPropertyString die zusätzliche benötigten Variablen angelegt. Ich veruche sie nun per Skript bei der Initialisierung zu füllen, jedoch bekomme ich immer wieder Fehlermeldungen, dass die neuen Variablen noch vorhanden sind.

Wo müsste die „Befüllung“ korrekterweise erfolgen?

Joachim

Vergiss es, Dafür sind die Property’s nicht gedacht.
Zumal diese immer ein Appylchanges benötigen was schnell zu einer Endlosschleife führen kann.
Nimm erstmal IPS-Variablen und Versteck diese. Irgendwann kommt da eine Lösung von Paresy um Daten persistent in einer Instanz zu halten.
Michael

Wie Nall Chan schon geschrieben hat hängt das davon ab was genau passieren soll. Wenn Du einmalig einen Wert ablegen willst der keine IP-Symcon Variable verbraucht, für den User zunächst nicht sichtbar ist, der sich aber auch nicht ändert kannst Du eine Eigenschaft nutzten. Die setzt Du mit
IPS_SetProperty — IP-Symcon :: Automatisierungssoftware
Und anschließend
IPS_ApplyChanges — IP-Symcon :: Automatisierungssoftware

Wenn sich der Wert aber öfter ändert kann dies wie Nall Chan schon schrieb zu Problemen führen. Dann nimm statt dessen eine IP-Symcon Variable und setzt die Hidden.

…da ich ja heute auch beim User-Treffen in Hamburg gelernt habe, dass das aktuell noch nicht so funktioniert - Besserung wurde zugesagt;) - habe ich im der übergeordneten Instanz Variablen angelegt, die nun auch in der Konsole sichtbar sind.

Aber wie greife ich von den untergeodneten Instanzen korrekterweise darauf zu?

Joachim

Gar nicht :smiley:

Du sendest vom Child mit $antwort= $this->SendDataToParent($JSONString) eine Anfrage an den Parent und dieser kann direkt mit return dir $antwort zurückgeben.

Klar kannst du auch anders auf diese Variablen zugreifen, dies wäre aber eher ‚geschummelt‘ und mit Pech geht das irgendwann nicht mehr.
Dazu dann im Child den eigenen Parent abfragen und dann unterhalb dessen Instanz die Variable suchen… ist aber so nicht gedacht.

Michael

Hallo Michael,

ich möchte ja im Children wissen, was im Parent mit

GetValue($this->GetIDForIdent("User"))

abrufbar wäre.

Weist Du wo ich ein Beispiel dafür finden könnte?

Joachim

Nachtrag: An andere Stelle habe ich es so gemacht:

IPS_GetProperty((IPS_GetInstance($this->InstanceID)['ConnectionID']), "IPAddress")

Das funktioniert zwar, ist dann aber wohl nicht im Sinne des Erfinders?