Loxone Config – picoC Skripte lokal mit Loxmock ausführen

Entwicklungshilfe für individuelle Skripte

Wer sich mit picoC Entwicklung in der Loxone Welt befasst, winkt möglicherweise schnell ab. Zu fehleranfällig, kompliziert und undurchsichtig ist die Entwicklung oft. Zudem holt man sich sehr schnell Instabilitäten in sein System. Seien es Memoryleaks, vergessene sleep-Statements und damit Ressourcenverbräuche o.ä.. Ich habe mir mal die Mühe gemacht sämtliche angebotenen Loxone-Funktionen unter picoC zu Mocken. Das Ergebnis: Skript-Entwicklung weitestgehend unabhängig von der Loxone-Umgebung. Memory-Leaks können fortan lokal gefunden werden und belasten die Produktiv-Umgebung nicht mehr. Wie immer: Im Artikel gibts eine Beschreibung und den Loxmock zum Download (v01).

Loxone stellt für die individuelle Erweiterung seiner Umgebung picoC von Zik Saleeba zur Verfügung. Zwar in einer älteren Version, aber ausreichend für sämtliche Zwecke(zumindest für die meinen). Für die Loxone Umgebung wurden noch einige zusätzliche Funktionen implementiert, die spezifisch sind. Diese verhindern natürlich die lokale Ausführung, da sie eben nur in der Loxone-Umgebung verfügbar sind. Loxone stellt eine Dokumentation seiner Spezifika zur Verfügung. Diese Funktionen sind nun komplett lokal verfügbar – zumindest gemocked. Also: Kein Problem ohne eine Lösung. 🙂

Nachstehend erkläre ich, wie der Loxmock eingesetzt und konfiguriert werden kann, wie Testdaten eingesteuert und Memoryleaks erkannt werden können.

Zunächst aber: Was ist der Loxmock und was kann er?

Neben der Ermöglichung einer lokalen Ausführung der picoC Skripte, sind alle Funktionen funktional soweit möglich nachimplementiert. Klingt jetzt komplizierter als es ist, ist halt Fleißarbeit. Jede aufgerufene Funktion macht dabei eine Ausgabe und ermöglicht eine Unterstützung beim Debuggen. Ich habe mir meine Entwicklung damit jedenfalls deutlich erleichtert. Die Funktionen arbeiten wie in Loxone, nur mit dem Unterschied, dass Aufrufe zu externen Systemen mit hartcodierten, vorgegebenen Daten antworten. Das Ganze funktioniert so gut, dass ich auch die Bugs von getxmlvalue() implementiert habe, nachdem ich verstanden hatte, wie Loxone programmiert hat. Keine Angst, ist nur das Ignorieren eines Sonderfalls… 🙂

Für ein größeres Skript wie das blockweise Auslesen von Modbus-Werten, habe ich mal einen Screenshot gemacht. Eingaben und Ausgaben sind markiert, die byte-Rückgabewerte des Modbus sind entsprechend hinterlegt. Nur so als Eindruck, wie das Ganze funktioniert. Gerne darauf klicken…

Loxone picoC-Skript mit Loxmock lokal ausführen

Was ist zu tun, damit man seine Skripte lokal ausführen kann?

  1. Zunächst benötigt man picoC. Für Windows kann man eine compilierte Version von picoC aus dem Loxwiki herunterladen. Die Datei picoc.exe legt man in ein Verzeichnis.
  2. Die beiden Loxmock-Dateien, die unten zum Download angeboten werden, ebenfalls in das gleiche Verzeichnis ablegen.
  3. Das eigene Skript ebenfalls in das Verzeichnis ablegen. Nennen wir es mal myscript.c
  4. Am Anfang von myscript.c folgende Codezeile einfügen:     #include "loxmock.c"
    • Dies ist auch die einzige Zeile, die beim Kopieren von myscript.c auf den Loxone-Miniserver auskommentiert werden muss.
  5. In einer Windows Commandshell in das Verzeichnis wechseln.
  6. Ausführung mittels: picoc.exe -s myscript.c
  7. Läuft. Bis auf die Daten. Die kommen jetzt…

Dateninput und Konfiguration

Der Loxmock besteht aus zwei Teilen:

  1. Der eine Teil besteht aus den gemockten Funktionen und bleibt unangetastet.
  2. Im konfigurativen Teil werden Parameter und Testdaten eingestellt. Nicht verwendete Teile müssen auch nicht konfiguriert werden.

Allgemeine Parameter

Gleich zu Beginn der Datei loxmock.c können 4 allgemeine Parameter eingestellt werden.

Wer nicht sämtliche Aufrufe der Loxone-Erweiterungen sehen möchte kann dies über LOXMOCK_PRINTCALLS abschalten und erhält nur die Ausgaben aus den setoutput-Aufrufen.

Bei der Entwicklung oder Memoryleak Nachstellung sind sleep-Statements unter Umständen unerwünscht. Mit LOXMOCK_EXECUTE_SLEEP kann man das steuern. Per Default wird bei sleep-Statements nicht gewartet.

Wer mit Datumsangaben hantiert kann das entsprechend einstellen. Die beiden Parameter LOXMOCK_LOCAL_TZDIFF_TO_UTC und LOXMOCK_LOCAL_IS_SUMMERTIME sind denke ich selbsterklärend.

Testdaten

  • Inputkanäle: Diese Konfiguration Bedarf denke ich keiner Worte. Das Bild spricht für sich.

Interessanter wird es bei Daten von externen Systemen:

  • httpget()-Aufruf: Der Rückgabewert dieses Aufrufs ist inklusive des http-headers anzugeben. Das Vorgehen von der Datenabfrage bis zum Einfügen in die Konfiguration sieht dann wie folgt aus.
  • localwebservice()-Aufruf: Der Rückgabewert dieses Aufrufs ist ein reines XML ohne Protokollheader. Das Vorgehen von der Datenabfrage bis zum Einfügen in die Konfiguration sieht dann hier wie folgt aus.
  • Arbeiten mit STREAM

Wie mit allen Testdaten erfordert auch das Arbeiten mit Streams zunächst Vorarbeit. Sprich: Am besten mit einem Modbus-TCP Tool o.ä. Daten Abfragen und dann hinterlegen. Das nachstehende Bild zeigt die Konfiguration einmal mit der Arbeit auf byte-Ebene und einmal mit der Arbeit auf ascii-Ebene. Die hex-Eingaben werden intern in die entsprechenden byte-Werte umgewandelt.

  • Virtuelle Ein- und Ausgänge

Wer mit Funktionen wie getio()/setio() arbeitet, kann diese ebenfalls verwenden. Die initialen Werte können vorgegeben werden. Eigene Änderungen sind zur Laufzeit auch verfügbar.

  • Inputevents

Zu guter Letzt kann man auch mit Inputevents arbeitet. Zur einfacheren Konfiguration kann man numerische Vorgaben machen, die intern dann zur entsprechenden Bitmap umgewandelt werden.

Memoryleaks

Das Verhalten des loxmock ist bzgl. der Speicherallokation wie die Loxonefunktionen. Bei Aufrufen von z.B. getinputtext() oder anderen Funktionen mit entsprechenden Rückgabezeigern werden Werte zurückgeliefert, die mittels free() auch wieder freigegeben werden müssen. Erfolgt das nicht, folgt irgendwann die Quittung. Selbst verschuldete Leaks haben natürlich den gleichen Effekt. Wird alles nur oft genug wiederholt, steigt das Programm irgendwann eben aus. Man sieht das unter Windows recht schön im Taskmanager. Startet man das picoC Skript und wartet auch nicht bei den sleep-Statements, werden viele Iterationen in kurzer Zeit durchgeführt. Steigt der Ressourcenverbrauch kontinuierlich, so empfehle ich von einem Produktionsdeployment abzusehen… 😉

Achtung bei Windows: Das ausführende picoc-Programm wird wirklich als picoc.exe angezeigt und ist nicht zu verwecheln mit der „Windows-Befehlsprozessor“ oder „cmd.exe“ o.ä. Anzeige.

Entsprechende Anzeigen gibts unter den anderen Betriebssystemen natürlich auch.

Zum Testen einfach mal 10 Minuten laufen lassen und beobachten. Ein zurückgegebener Leerstring "" enthält 1 Byte. Dauert also, aber irgendwann…

#include "loxmock.c"
while (TRUE) {
    char *cleverInput = getinputtext(0);
    // Ooops, forgot to free(cleverInput);
}

Fazit

Loxmock kann zwar nicht alles abdecken, insbesondere nicht die echte Kommunikation mit Drittsystemen. Funktionale Entwicklung, Fehlerfälle, Stabilisierung, deutlich weniger Miniserver-Deployments etc. lassen sich jedoch meines Erachtens sehr gut damit umsetzen. Final sagt natürlich der Miniserver, was Sache ist. Gerade mit dynamischer Speicherallokation verhalten sich in bestimmten Fällen Miniserver und Konsole unterschiedlich. Das wird aber vermutlich die Wenigsten betreffen.

Wer mag – die Sourcen

Hier der Loxmock zum Download. Die Dateien sollten nach dem Download in loxmock.c und loxmock_func_v01.c umbenannt werden.


Wie immer gilt: Fortschritt, nicht Perfektion… Feedback ist also jederzeit willkommen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert