Script Editor Kontext / Funktion Infos

Moin in die Runde,

ich hätte da auch einen kleinen Wunsch, ob das vielleicht unkompliziert zu integrieren ist.

(Fast) jeder hat sich ja auch die eine oder andere Weise eine eigene „kleine“ Funktionsbibliothek zugelegt und eingebunden.
Ob diese nun über die autoload integriert ist oder per include in jedem Script, sei ja erst mal egal.

Meine eigenen Funktionen fangen bei mir (zur Unterscheidung) alle mit dem Kürzel „FN_“ an, somit weis ich das es meine eigenen Funktionen sind und nicht IPS interne.

So langsam nehmen auch die Anzahl der Funktionen zu, so das ich immer öfters nachschauen muss, wie heißt die Funktion noch mal und was für Parameter muss ich mit angeben.

Was ich mir wünschen würde ist, das ich meine „Funktionsbiliothek“ mit in den Script Editor (Kontextmenü?) Vorschlagsliste mit einbinden kann.

Als bestes Beispiel die Funktion date();

grafik

Sowas würde ich gerne für meine eigene Funktionsbibliothek pflegen, in Form von:
FN_create… und ich bekomme die Liste was ich habe mit Erklärung was die Funktion macht. Das würde mir, kopier, nachschlage und Tipparbeit ersparen.

Wie macht sonst Ihr das so mit eigenen Funktionen?

Grüße
Thomas

2 „Gefällt mir“

1+, wünsche ich mir auch

Das wäre leider extrem aufwendig. Aktuell werden alle bekannten Funktionen (von Symcon und PHP direkt) konstant für die Funktionsliste verwendet. Wenn du mit include oder dergleichen arbeitest, dann müsste der Editor stattdessen den PHP-Code auswerten und auf dessen Basis bestimmen welche Funktionen zur Verfügung stehen. Das ist leider eine ganz andere Hausnummer.

Du könntest dir natürlich deine Hilfsfunktionen als Modul erstellen. Diese kann IP-Symcon dann ja auslesen und zur Autovervollständigung anbieten. Dann arbeitest du halt mit Symcon-Mitteln mit denen wir gut umgehen können.

Da bietet Symcon dann aber auch nur die Signatur der Funktion (ohne Rückgabewert!) an.
Die Doku der Funktion wird nicht angezeigt.
Dazu müsste die Konsole bzw Symcon dann eventuell vorhandene PHPDocs auslesen und anzeigen.
Michael

Mit „einem“ Testmodul habe ich auch schon etwas „rumgespielt“.
Gut ganz verstehen tue ich es (noch) nicht. Doch soviel wie ich verstanden habe brauch ein Modul ja immer die $InstanceID zur Abarbeitung.

Das führt zwar jetzt in die Modul Programmierung aber eben zum verstehen.

<?php

class TB_Bibliothek extends IPSModule
{
    public function Create()
    {
        parent::Create();
        // Initialisierungen hier hinzufügen, falls nötig
    }

    public function ApplyChanges()
    {
        parent::ApplyChanges();
        // Änderungen anwenden
    }

    // Gibt den letzten Aktualisierungszeitpunkt einer IPS-Variable zurück
    public function AktualisierungsZeitHolen(int $id)
    {
        #$this->$v = $this->GetValue($id);
        #$update = (int) $v['VariableUpdated'];
        $StatusvariableValue = $this->GetValue($id);
	return StatusvariableValue;
    }

    // Weitere Funktionen können hier hinzugefügt werden
}

Es gibt aber nicht immer dafür eine „Modul“ Instanz. Vieles sind auch einfach DummyModule wo Varablen und Scripte drinne liegen.

Falls mir da einer auf die Sprünge helfen könnte?

In der Endausbaustufe sollte zb. diese Funktion aus einem Script, welche da wunderbar arbeitet nun dann im Modul aufrufbar sein.

/**
 * Erzeugt eine Variable unterhalb {id} mit dem Namen {name} vom Typ {type}
 * Existiert die Variable schon wird diese zurückgeliefert.
 *
 * @param int $id ID unter welchem die Variable erzeugt werden soll.
 * @param string $ident Ident der zu erzeugenden Variable
 * @param string $name Name der zu erzeugenden Variable
 * @param int $type Typ der Variable (0 = Boolean, 1 = Integer, 2 = Float, 3 = String)
 * @param int $pos 0 gleich Standard, sonst neue Sortierreihenfolgenummer {pos}
 * @param string $icon Zuweisung eines Icons mit dem übergebenen Namen
 * @param string $profil Leer für kein Profil, sonst Profilnamen
 * @param int $action ID der benutzerdefinierten Aktion (Auslösung via Webfront)
 *
 * @return int ID der bestehenden oder neu angelegten Variable
 */
function CreateVariableByIdent($id, $ident, $name, $type, $pos = 0, $icon = '', $profile = '', $action = null)
{
    $ident = CreateIdent($ident);
    $vid = GetObjectByIdent($id, $ident);
    if ($vid === false) {
        $vid = IPS_CreateVariable($type);
        IPS_SetParent($vid, $id);
        IPS_SetName($vid, $name);
        IPS_SetIdent($vid, $ident);
        IPS_SetPosition($vid, $pos);
        IPS_SetIcon($vid, $icon);
        if ($profile !== '') {
            IPS_SetVariableCustomProfile($vid, $profile);
        }
        if ($action != null) {
            IPS_SetVariableCustomAction($vid, $action);
        }
    }
    return $vid;
}



Also man möchte irgendwas berechnen. DummyModul erstellt. Leeres Script erstellt.


define('ID_ARCHIV',     17032);  // Archiv
define('ID_JSON_API',   CreateVariableByName($_IPS['SELF'], 'JSON API Daten', 3, 0, '', '')); // JSON API String

define('ID_AKTUELL',    CreateVariableByName(IPS_GetParent($_IPS['SELF']), 'aktuell', 2, 0, '', '~Electricity') );
define('ID_HEUTE',      CreateVariableByName(IPS_GetParent($_IPS['SELF']), 'heute', 2, 1, '', '~Electricity') ); // TODO: Archivierung aktivieren (Typ: Zähler));
define('ID_MORGEN',     CreateVariableByName(IPS_GetParent($_IPS['SELF']), 'morgen', 2, 3, '', '~Electricity'));
define('ID_LEISTUNG',   CreateVariableByName(IPS_GetParent($_IPS['SELF']), 'Aktuelle Leistung', 3, 4, 'EnergyProduction', '~HTMLBox'));
define('ID_VORHERSAGE', CreateVariableByName(IPS_GetParent($_IPS['SELF']), 'Vorhersage', 3, 0, 'Graph', '~HTMLBox'));

Und einfach dann damit arbeiten im Script.

Du müsstest dein Testmodul halt einmal als Instanz erstellen. Das würde dann ähnlich wie beim Archiv funktionieren. Bei allen AC_-Funktionen ist der erste Parameter die ID des Archivs, egal wo die Variable liegt. Bei dir würdest du dann halt als ersten Parameter immer die ID deiner Instanz nehmen.

Deine Funktion AktualisierungsZeitHolen würdest du dann also beispielsweise als

FN_AktualisierungsZeitHolen(12345, $variablenID);

aufrufen, wobei 12345 die ID deiner einmalig erstellen Helferinstanz ist, egal wo diese jetzt liegt.

Ok, das funktioniert ja so schon (erstaunlich) gut! :wink:

Mein Fehler war es ich habe natürlich kein (/mein) Modul gar nicht erstellt, deswegen hatte ich ja auch kein $InstanceID, und die DummyModule haben ja quasi nicht meine Funktionen beinhaltet.

Dann werde ich wohl mal so nach und nach die Funktionen umbauen und in ein Modul gießen.

Wenn es nun noch eine Möglichkeit der „Textmäßigen Beschreibung“ der Funktion gibt, so wie in der Date Funktion, dann wäre das schon fast perfekt!

Die Idee an sich finde ich absolut genial und sowas finde ich ein absolutes muss.

Was ich mir gerade vorstelle ist, wie verhalten sich dann die Funktionen die man aus der Instanz verwendet wenn aus zwei unterschiedlichen Scripten die ein und selbe Funktion aufgerufen wird ?

Besteht hier nicht die Gefahr das wenn diese Instanzfunktion in der Abarbeitung lange an Laufzeit benötigt das ein anderer Aufrufer Inhalte überschreibt ?

Anders gefragt, müsste ich dann nicht die Funktionen mit einem Semaphore absichern und somit den Aufrufer blockieren ?

Es wird zweimal gestartet.

Nein, da jedes Script (wozu auch die PHP-Module gehören) in einem eigenen Kontext gestartet werden. Die wissen nix voneinander.

Nein.
Aber, und das gilt aber auch für normale Scripte, Ablaufpläne, Ereignisse usw., man muss beachten was dort eigentlich passiert und nicht das auch zwei Ereignisse in die Quere kommen. Also einer will einschalten und der andere ausschalten, oder wartet auf das ausschalten und blockiert das einschalten usw…
Michael

1 „Gefällt mir“

Das heißt, obwohl es nur eine Instanz ist, wird im Hintergrund so zu sagen immer ein zweiter Thread eröffnet, kann man das so sagen ?

Aber, alles was außerhalb von diesem Script beschrieben wird, z.B. Buffer oder Aktorik etc. was für alle zugänglich ist, weil es nun mal global ist, dann werden doch diese globalen Eigenschaften, egal was es wäre von dem zweiten Aufruf beeinflusst.

Alles was innerhalb der Funktion lokal als Variabel beinhaltet ist Thread safe, alles andere dann nicht.

Das heißt aber wiederum, das man um Semaphoren nicht drum herum kommt wenn man sicher sein will.
Wenn eine andere Logik z.B. einen Aktor direkt wieder ausschaltet, dann wäre es ein Fehler von der anderen Logik. Sonst würde man nie auf den Fehler kommen das ein gleichzeitiger Zugriff auf einen Aktor von einem anderen Script überschrieben wird und somit z.B. nie ausgeschalten wird.

Ja, oder halt jedes Mal wenn du eine Funktion der Instanz startest.
Darum sollen Scripte ja auch nicht so lange laufen, weil es nur eine endliche Anzahl von PHP Threads gibt.

Ja, das gilt aber für alles in Symcon.
Also auch deine eigenen Scripte oder Ereignisse, Ablaufpläne, Wochenpläne usw…

Ja, wobei Module auch z.b. eigene Buffer nutzen können. Die sind nicht Threadsafe, da muss man sich selber drum kümmern.

Wie gesagt, das kann auch jederzeit jetzt schon passieren und hat nix mit Modulen per se zu tun.

Aber ich glaube wir schweifen hier ab :laughing:
Michael

1 „Gefällt mir“

Ok, also dann wäre mein Fazit, damit man sich grundlegend nichts einfängt, immer Threadsafe seine Funktionen aufsetzen. Schadet ja nicht.

Danke …

Moin,

das ganze geht nun so langsam in die richtige Richtung.
Ich hätte da aber gerne noch etwas Doku / Bescheibung mit in dem ToolTip.

Für die Hardcore Programmierer und für das Symcon Team, die kennen die Doku sicherlich auswendig :wink: … und die Typen, Optionen, …

@Dr.Niels gibt es noch eine Möglichkeit den Tooltip mit Inhalt zu befüllen?
Es ist ja auch bei IPS Internen Funktionen so das „nur die Parameter“ angegeben / vorgeschlagen werden. Ihr habt doch in eurer Doku auch die ganzen Optionen sauber aufgeführt? Wäre es nicht möglich und Sinnvoll eure schon geschriebene Doku mit in dem Tooltip anzuzeigen? Ich habe leider meistens noch ein zusätzlichen Browser Fenster mit der Doku offen, Klick hier, suche da. Was für ein Typ war den noch mal ein String Element? Ah: also doch die 3 …

VariablenTyp
Wert Beschreibung
0 Legt eine Variable vom Typ Boolean an
1 Legt eine Variable vom Typ Integer an
2 Legt eine Variable vom Typ Float an
3 Legt eine Variable vom Typ String an

Bei mir sieht es momentan so aus, halt IPS „Standard“:
grafik

Ich könnte mir auch vorstellen die Funktion Pararmeter etwas „sprechender“ darzustellen?:

Aber so „richtig“ Schick - sieht das auch nicht aus?
Gibt es bessere Ideen?

Thomas

Für euch von außen gibt es keine Möglichkeit die Tooltips zu befüllen. Ich merke aber, hier ist reges Interesse. Wir schauen also mal, was man da machen kann.

5 „Gefällt mir“

:+1:

Super - darauf freue ich mich schon!

1 „Gefällt mir“

kann ? eher ein schönes und wundervolles muss :grin:

2 „Gefällt mir“