Problem beim Erstellen von Modulen

Hallo zusammen,

ich habe mich jetzt durch die Dokumentation und das Forum gewurschtelt und mir diverse Module angeschaut aber ich komme für mein Modul nicht auf einen grünen Zweig.

Ich muss hier einen Webdienst ansprechen. Im ersten Schritt meldet man sich mit Benutzername und Passwort an und bekommt einen 8h gültigen Authentication Token zurück.

Danach kann man mit dem Token eine Liste der Verbundenen Geräte abfragen.

Im letzen Schritt soll der Benutzer dann eines der Geräte auswählen können.

Konkret scheitere ich an zwei Dingen:

1.) Das dynamische Füllen der Liste.

Wenn der Benutzer das Modul-Form öffnet sind ja noch keine Daten drin. Er gibt dann seine Benutzerdaten ein. Ich bekomme aber die Select-Liste nicht dynamisch erweitert. GetConfigurationForm() wird nur beim Öffnen aufgerufen und wenn ich es im Code erneut aufrufe wird das Formular trotzdem nicht neu geladen. Mit der statischen form.json geht es ja eh nicht, zumindest habe ich nichts gefunden, wie man per Code ein bestehendes Element erweitern kann.

Im Endeffekt bleibt im Moment nur: Daten eingeben, Token generieren, Formular schließen, Formular wieder öffnen, jetzt ist die List befüllt und man kann das Gerät auswählen und alles erneut speichern.

Gibt es da keinen Weg, dass schöner hinzubekommen?

2.) Properties überschreiben:

Ich würde gerne im Code den Wert von Properties im Nachhinein ändern. Z.b. würde ich den Authentication Token gerne speichern und eine Property hat hier den Vorteil, dass das nicht im Variablenbaum auftaucht. Immerhin könnte man da den Token auch für andere Dinge abgreifen und das möchte ich vermeiden.

Es gibt aber nur RegisterProperty, da kann man dann einen Wert vergeben, und ReadProperty zum Lesen. Aber im Code selbst kann man Properties nicht schreiben.

Gibt es da einen Trick?

IP-Symcon läuft in Version 4.1, der letzte Update war vor ca. 2 Wochen.

Viele Grüße und danke für die Hilfe.

Gustl

Die Console ruft diese Funktion auf, und aus den zurückgegeben JSON stellt sie dann die Form dar.
Deswegen ist es sinnlos diese Funktion selbst aufzurufen.
Und wenn man in der Console auf ‚Übernehmen‘ klickt, dann ruft die Konsole wieder diese Funktion auf und stellt die Form neu dar.
(Habe ich selber noch nie probiert, soll aber inzwischen gehen)

Die Datei in GetConfigurationForm laden, das JSON in ein Array / Objekt konvertieren, anpassen und dann wieder als JSON-String zurückgeben.

Beispiel ohne Liste nur um zu zeigen wie es gemacht werden kann:

    public function GetConfigurationForm()
    {
        $data = json_decode(file_get_contents(__DIR__ . "/form.json"));
        if ((float) IPS_GetKernelVersion() < 4.2)
        {
            $data->elements[8]->type = "ValidationTextBox";
            $data->elements[8]->caption = "Path to certificate";
            unset($data->elements[8]->extensions);
            $data->elements[9]->type = "ValidationTextBox";
            $data->elements[9]->caption = "Path to private key";
            unset($data->elements[9]->extensions);
        }
        return json_encode($data);
    }

Der Trick heißt; nicht machen !
du kannst immer mit IPS_SetProperty darauf schreiben, aber laut Paresy wird es dann irgendwann ‚knallen‘.
Weil du ja danach wieder IPS_Applychanges aufrufen must und dann mit Pech außerem noch eine Endlosschleife gebaut hast.

Der Token ist ja flüchtig, du mußt ihn ja eh alle 8h neu holen.

Also einfach einen Buffer nutzen.


$this->SetBuffer('Token', $Token); // schreiben
$Token = $this->GetBuffer('Token'); // lesen

Michael

Hallo Michael,

vielen lieben Dank für Deine Hilfe. Das sieht soweit ganz gut aus. Die Liste kommt sauber durch und ich kann danach sauber die APIs ansprechen.

Die Kinder schlafen schon, darum kann ich heute keinen Testlauf mehr machen, aber wenn morgen alles funktioniert kann ich mein Staubsaugermodul online stellen.
Aber es gibt halt doch ca. 28 Zustandsübergänge und da sollten schon alle Aktionsskripte sauber zusammenspielen.

Immerhin kann ich dann heute den ganzen Debug-Code wieder ausbauen.

Viele Grüße

Gustl

Was für Aktionsskripte?
So etwas haben Module nicht.
Michael

PS: immer mehr Debug einbauen als man meint. Ist immer zu wenig :wink:
Aber bitte nur mit $this->SendDebug. Niemals in das Log. Da gehören wenn nur Fehlermeldungen rein.

Hallo Michael,

mein Modul legt ja Variablen an, z.B. den Zustand des Roboters (ein/Aus).
Diesen Variablen muss ich ja entweder Aktionsskripte zuweisen, oder Trigger-Events definieren.

Das Modul selbst hat keine solchen Skripte, da geb ich Dir Recht.

Ich scheitere aber jetzt gerade noch an einem ganz konfusen Thema. Wenn ich einen Button definiere, der wiederum eine Aktion in meiner module.php aufruft muss ich ja die Instanz-ID als Parameter übergeben.

In meiner form.json sieht das so aus:

{ "type": "Button", "label": "Fetch robot information", "onClick": "BOTVAC_FetchRobotList($id);" },

Wenn ich das Formular aber direkt in der module.php generiere klappt das nicht. Dort ist die Variable $id nicht vordefiniert. Und auch aus $_IPS kann ich sie nicht holen, da sind nur SELF, THREAD und SENDER definiert.

Ich finde gerade kein einziges Modul als Beispiel, das GetConfigurationForm() in Verbindung mit Buttons nutzt. Und auch in der Doku ist kein passendes Beispiel gelistet.

Wie komme ich denn an die ID?

Viele Grüße

Gustl

Nein es gibt keine Actionskripte in Modulen hier ist Request Action zu nutzten.

GetIDForIdent
oder was meinst Du jetzt genau?

Muss sie auch nicht, das macht die Konsole.
Du musst also den Text mit $id übergeben und verhindern dass dein Modul dort einen Wert einsetzen will.
Ist kein Problem wenn man =’$id’ anstatt ="$id" schreibt.
Das sind aber PHP Grundlagen…
Michael

Nein er meint Actions-Buttons in der Form.
Diese können PHP enthalten (ja ganze Scripte, aber nur in einer Zeile).
Michael

Hallo Michael,

Danke für den Tip. Klar sind das Grundlagen, dass bei Single Quotes der String selbst nicht geparst wird. Aber nach mehreren Stunden probieren kommt man oft nicht auf so simple Lösungen.

In der SDK-Dokumentation steht lediglich, dass man diese Variable automatisch bereitgestellt wird. Ich dachte eben, dass IPS diese analog zu $_IPS für die module.php beim Laden bereitstellt.
Wenn da natürlich irgendwo stehen würde, dass diese Variable von der Konsole initialisiert wird und nicht vom IPS-Server-Part wäre das klarer, glaube ich.

Ich denke mal, dass ich ein paar Beispiele zusammenstelle und diese dann als Feedback zur Doku einreiche.

Viele Grüße

Gustl