Grundsätzliche Fragen zur Modulerstellung

…m.E. steht mein Modul-Grundgerüst jetzt. Vielen Dank noch mal für die unermüdliche Unterstützung!

Einige Punkte sind für mich noch Verbesserungswürdig:

  • Wie schon oben angesprochen, benötigt man den Client Socket eigentlich nur als Funktion, nicht zwangsläufig als eigene Instanz.
  • An die Daten zu kommen - oder sie zu setzen - gelingt nach meinem Kenntnisstand nur so:
$ParentID = (IPS_GetInstance($this->InstanceID)['ConnectionID']);

Mit der InstanzID habe ich dann einige Möglichkeiten die IPS-Funktionen zu nutzen.

  • Ich kann die interne Datenkommunikation zwischen dem Client Socket und dem untergeordneten Splitter nur bedingt beeinflussen

Jetzt wird es - hoffentlich - mehr um die inhaltliche Fragestellungen des Moduls gehen.

Verbesserungspotential ist noch vorhanden, aber die Module sind eine extreme Bereicherung und bieten phantastische Möglichkeiten!:loveips:

Joachim

Das kommt auf die Verwendung an. Wenn du nur etwas sendest und die Antwort empfangen möchtest, brauchst du keinen und sendest deine Anfrage direkt über einen PHP-Socket.

Wenn du aber jederzeit auch Daten empfangen willst (also wenn der Server periodisch Daten sendet), dann brauchst du zwingend den ClientSocket.

So kannst du prüfen ob du einen Parent hast, und ihn auch mit SetProperty konfigurieren, aber versenden von Daten wird nicht über die $ParentID gelöst.

Was willst du dort beeinflussen?
Das ist eine interne 1:1 Verbindung vom ClientSocket zu deinem Splitter.
Aber wenn du die Daten eh per Pull abholen must, dann brauchst du keinen und kannst den ganzen Datenaustausch vom Splitter zu einem IO wegwerfen.

Michael

…noch mal eine Frage:

Wie kann ich den Nutzer über eine Message Box darüber informieren, wenn etwas falsch läuft?
Der Eintrag ins Log kommt sowieso, aber wenn z.B. die genannte IP nicht erreichbar ist oder ähnliches?
Ich meine so etwas irgendwo schon gelesen zu haben, finde es aber nicht mehr…

Joachim

Einfach Echo?
Oder was war die Frage?
Sonst gibt es noch SetStatus.
Michael

…die „Echo“ hatte ich alle rausgenommen. Das sah dann sehr „komisch“ aus.
Ich meine so eine Messagebox mit Meldungstext, Ausrufezeichen oder ähnlichem und einem OK-Button…

Joachim

Sinnvoll ist eigentlich nur der Ansatz im Modul, der Anwender hat die Konsole ja nicht immer offen und du kannst ein PopUp nicht erneut schicken, wenn er sie startet.
Fehlercodes/-meldungen kannst du in der forms.json definieren.

Ich gebe das zusätzlich im Log aus. Kann ja sein, das das Modul noch läuft, aber Teile nicht passen.

Hallo Leute,

noch mal eine Frage:

Wenn man wie ich eine Splitter Instanz mit n-Devices habe, wie verhält es sich dann mit den jeweiligen Device RX/TX?
Sollte die in allen Devices jeweils unterschiedlich sein? Oder sollten alle Devices zu diesem Splitter die gleiche Device RX und TX haben?
Wozu dient diese GUID/DataID denn im Speziellen? „SendToChildren“ sagt ja eigentlich schon aus, wohin die (Daten-)Reise gehen soll…

Joachim

SendToChildren sagt nicht aus wohin die Daten gehen. Es wird pauschal an alle Child’s gesendet.
Die GUID sollte für die Pakete mit gleichen Aufbau identisch sein. Auch wenn die Instanzen unterschiedlich sind.
Michael

Hallo Leute,

noch mal eine Frage zur „korrekten“ Kommunikation mit den ClientSocket-Parent:
So etwas wie

$this->SendDataToParent(json_encode(Array("DataID" => "{79827379-F36E-4ADA-8A95-5F8D1DC92FA9}", "Port" => "192.168.178.53", "Host"=> 8888)));

Gibt es nicht, oder?

Hier ist dann eine „Konstruktion“ wie

$ParentID = (IPS_GetInstance($this->InstanceID)['ConnectionID']); 
IPS_SetProperty($ParentID, "Port", 8888);

ich sage mal „zulässig“?

Joachim

Ja, gibt es nicht.

Ja, kann man machen :smiley:

Zumindest noch Stand der Dinge…
Wobei ich nicht gnadenlos immer SetProperty und Applychanges aufrufen würde.
Sondern nur in deinem eigenen Applychanges und dann auch nur wenn beide Instanzen unterschiedliche Einstellungen haben.

So in der Art mache ich es.
Fehlen zwar einige Funktionen & Konstanten, aber die Namen sollten es aussagen:


    public function ApplyChanges()
    {
        parent::ApplyChanges();
        $Open = $this->ReadPropertyBoolean('Open');
        $NewState = IS_ACTIVE;

        if (!$Open)  //Alles Egal, Splitter steht auf geschlossen
        {
            $NewState = IS_INACTIVE;
        }
        else // Prüfen ob Konfig sinnvoll, sonst $Open auf false setzen.
        {
            if ($this->ReadPropertyString('Host') == '')
            {
                $NewState = IS_EBASE + 2;
                $Open = false;
                trigger_error('Host is empty', E_USER_NOTICE);
            }
            if ($this->ReadPropertyInteger('Port') == 0)
            {
                $NewState = IS_EBASE + 2;
                $Open = false;
                trigger_error('Port is empty', E_USER_NOTICE);
            }
            if ($this->ReadPropertyInteger('Webport') == 0)
            {
                $NewState = IS_EBASE + 2;
                $Open = false;
                trigger_error('Webport is empty', E_USER_NOTICE);
            }            
        }

        $ParentID = $this->GetParent();

        if ($ParentID > 0)
        {

            if (IPS_GetProperty($ParentID, 'Host') <> $this->ReadPropertyString('Host'))
                IPS_SetProperty($ParentID, 'Host', $this->ReadPropertyString('Host'));

            if (IPS_GetProperty($ParentID, 'Port') <> $this->ReadPropertyInteger('Port'))
                IPS_SetProperty($ParentID, 'Port', $this->ReadPropertyInteger('Port'));

            // Keine Verbindung erzwingen wenn Host offline ist
            if ($Open)
            {
                $Open = @Sys_Ping($this->ReadPropertyString('Host'), 500);
                if (!$Open)
                    $NewState = IS_INACTIVE;
            }
            if (IPS_GetProperty($ParentID, 'Open') <> $Open)
                IPS_SetProperty($ParentID, 'Open', $Open);

            if (IPS_HasChanges($ParentID))
                @IPS_ApplyChanges($ParentID);
        }
        else
        {
            if ($Open)
            {
                $NewState = IS_INACTIVE;
                $Open = false;
            }
        }

        if ($Open)
        {
          // Hier irgendwas machen wie z.B. an einem Event-Server anmelden....
        }

        $this->SetStatus($NewState);
    }

Michael

Hallo Michael,

vielen Dank für Deine „Zeilen“…habe einiges davon „zitiert“…:wink:

Ich habe aber jetzt so eine komische Fehlermeldung:
Warning: Only active, inactive or error codes are allowed in … __ipsmodule.inc.php on line 355…

Wo soll ich nach dem Fehler suchen?

Zum anderen:
Ich habe ja jetzt wie von Dir geschrieben überall die __construct-Funktion gelöscht. Ich meine, dass seit dem ich bei jedem Update ich alle Probertys neu setzen muss… (letzteres ist leider Fakt, das davor eine Annahme…:wink:

Joachim

Der Fehler kann durchaus sein, je nachdem welche möglichen Stati du in der Form.json deklariert hast.
Statusmeldung — IP-Symcon :: Automatisierungssoftware
Michael

…habe das ja so gemacht:

    "status":
    [
        { "code": 101, "icon": "inactive", "caption": "Instanz wird erstellt" },
        { "code": 102, "icon": "active", "caption": "Instanz ist aktiv" },
        { "code": 104, "icon": "inactive", "caption": "Instanz ist inaktiv" },
        { "code": 200, "icon": "error", "caption": "Pin wird doppelt genutzt!" },
        { "code": 201, "icon": "error", "caption": "Pin wird an diesem Raspberry Pi Modell nicht vorhanden!" }
],

Vom Syntax selbst gibt es offenbar keinen Fehler, ist die Definition der Fehlercodes >=200 vielleicht das Problem?

Joachim

Wenn du die Zeile bei meinem Copy&Paste nicht angepasst hast, fehlt 202 für Port oder Host leer.
Michael

…die Fehlermeldung habe ich aktuell noch nicht integriert.
Vielleicht kann Paresy etwas zum Ursprung dieser Fehlermeldung sagen?

Joachim

Die Fehlermeldung kommt von SetStatus. Die Werte müssen mit den aus der form.json übereinstimmen.
Michael

…das sollten sie, schaue aber noch mal…

Kann es sein, das innerhalb der „Create-Funktion“ kein SetStatus möglich ist?:confused:

Joachim

Da steht sie Automatisch wohl auf 101.
Und kann sein das es somit nicht geht. Aber warum willst du das im Create aufrufen?
IPS führt nach dem Create auch Appylchanges aus und dann ist die Instanz ja schon erstellt.
Michael

…so, irgendwie kommt es nicht gut, wenn "SetStatus-Anweisungen in der Create-Funktion und in der „frühen“ ApplyChange-Funktion verwendet werden. Habe sie jetzt entfernt und alles ist wieder gut!

Auf meiner To-Do-Liste steht jetzt noch die Testfunktion (da muss ich noch mal nach Beispielen suchen) und falls mir noch etwas zur Performance-Verbesserung einfällt…

Ansonsten ist zumindest erst einmal eine Funktion gegeben und alle mir eingefallenen möglichen Fehler sind so weit abgefangen - Verbesserungspotential wird es ja aber immer wieder mal geben,

In der Dokumentation zu den Modulen sind ja schon einige neue Features zur Version 4.1 nachgetragen worden!
Davon kann ich das eine oder andere sicherlich auch gebrauchen…

Wenn ich die Testfunktionen fertiggestellt habe, dann werde ich das Modul dann gerne mal in der „Public-Beta“ vorstellen.

Vielen Dank an der Stelle schon mal an Michael (Nall chan), Ernst, Fonzo und Paresy!

Als nächstes steht die Erweiterung dann für den Ultraschall-Entfernungsmesser an…

Joachim

…ich hätte da gerne noch so ein Problem!:slight_smile:

Ich versuche folgendes:

$Value = min(100, max(0, $Value));
$Message = "dims=".$Value."\xFF\xFF\xFF"; 
$this->SendDataToParent(json_encode(Array("DataID"=> "{A0DAAF26-4A2D-4350-963E-CC02E74BD414}", "Function" => "write_bytes_serial", "Handle" => GetValueInteger($this->GetIDForIdent("Handle")), "Message" => $Message)));

Wenn ich die Funktion ausführe bekomme ich ein zärtliches:

Warning:  JSON Parser-Fehler in /usr/share/symcon/scripts/__ipsmodule.inc.php on line 290

Liegt das an der $Message?

Joachim