Wie Registervariable und Seriellen Port in Modulen korrekt verwenden?

Hallo Zusammen,

ich möchte gerne mein Skript zum Empfang von wireless M-Bus Daten in Module umbauen. Hierzu soll es ein Gateway-Modul geben, das die Daten des USB-Sticks (Serieller Port) empfängt und an die entsprechenden Geräte Module weitergibt.

Momentan werden die Daten so verarbeitet: Serial Port --> Registervariable --> Script (Aufruf durch RegVar).
Da häufig die Daten von Serial Port nicht vollständig sind, verwende ich die Registervariable als Puffer, bis ich ein vollständiges Telegramm erhalte.

Wie bilde ich dies nun am sinnvollsten in Modulen ab? Ich könnnte zwar im Gateway-Modul ein Parent festlegen (müsste nach der bisherigen Prozedur die Registervariable sein), aber wie kann ich dann sicherstellen, dass die Registervariable ihrerseits wieder mit dem richtigen Parent (Serial Port) verbunden ist?
Oder kann ich die RegisterVariable auch übergehen, und die Pufferung in einer Variablen im Gateway-Modul durchführen?

Letzteres, kannst du ja mal meine Module ansehen.
Teilweise etwas ‚schwierig‘ nachzuvollziehen.
Empfehlenswert ist das XBee-Modul und dort das Gateway.
Es empfängt Daten und setzte diese wieder zusammen. Buffer ist aktuell leider noch eine IPS-String variable.
Michael

Schau dir mal dieses Thema an: Datenfluss — IP-Symcon :: Automatisierungssoftware

So wie du es dir vorstellest, ist es genau richtig. I/O (1) <-> WM-Bus Gateway (1) <-> WM-Bus Geräte (n Instanzen)

Und der Puffer würde in das Gateway kommen. Zur Zeit ist es noch etwas doof, da du eine String Variable als Puffer nutzen musst, aber in Zukunft wird dein PHP Modul einen eingebauten Puffer bekommen, oder die String-Variable eine Option zum flüchtiger Speicher bekommen.

Schau dir gerne dazu auch mal die Module im SymconTest Repository von mir an.

Übrigens brauchst du in keinem Fall mehr eine RegisterVariable :wink:

paresy

Hallo zusammen,

hänge momentan auch an diesem Thema fest:
Bastle aktuell ein PHP-Modul zum Auslesen einer Heizungssteuerung Buderus Logamatic 4000.

hermanthegerman2/BuderusLogamatic4000 · GitHub

Das Modul ist noch in der Entwicklung, sollte sich aber schon installieren lassen. Datenfluss wie folgt:

Auswahl GatewayMode 0
Client Socket {3CFF0FD9-E306-41DB-9B5A-9D06D38576C3} -> LogamaticSplitter -> RegisterVariable

Auswahl GatewayMode 1
Serial Socket {6DC3D946-0D31-450F-A8C6-C42DB8D7D4F1} -> LogamaticSplitter -> RegisterVariable

Die Instanzen werden angelegt, jedoch bekommt meine Splitter-Instanz keine übergeordnete Instanz zugewiesen.
Wer kann mir hier helfen ?

Danke und Gruß,
Hermann

Du kannst im Create leider noch kein ReadProperty nutzen. Das kann frühstens im ApplyChanges passieren. :slight_smile:

Außerdem: Kannst du den ClientSocket manuell erstellen? (Die Frage testet, ob deine GUIDs korrekt sind)

paresy

Hallo Paresy,

vielen Dank schon mal. Habe meine „Baustelle“ nun umgebaut und den Datenfluß ohne RegisterVariable realisiert.
Der Datenfluss funktioniert schon mal, allerdings nicht 1:1, wenn ich mit dem ClientSocket vergleiche (siehe Anhang!)
Hier das Modul: hermanthegerman2/Logamatic4000 · GitHub

Folgende Probleme gibt es noch:

[ul]
[li]Daten werden nicht 1:1 vom IO zum Device gesendet
[/li][li]Status der Instanzen ist 101
[/li][/ul]

Ich steh momentan etwas auf dem Schlauch … wer kann mir bitte weiterhelfen ?

Danke und Gruß,
Hermann

Heizung_auslesen.txt (3.1 KB)

Du musst den Buffer mit utf8decode wieder in das Binäre Format bringen.
IPS muss die Daten so senden, sonst funktioniert das nicht mit json.
Auch wenn du Daten weiter runter oder auch hoch sendest, musst du selber deine Daten wieder erst mit utf8encode verpacken und dann in den json String wandeln.

Den Status kannst du mit SetStatus beeinflussen.
Michael

Vielen Dank schon mal nall-chan.

Problem mit SetStatus ist gelöst !

Die Daten denke ich habe ich genauso verarbeitet
json_decode -> utf8_decode für ReceiveData
bzw.
utf8_encode -> json encode für SendData.

Hast Du DIr mal die Log´s von mir angesehen ?

Anbei ein markiertes Beispiel, damit man den Wald vor lauter Bäumen auch sehen kann :wink:

BG,
Hermann

log_bsp.PNG

Also wo das C2 jetzt am Anfang herkommt, sehe ich so auf die Schnelle auch nicht.

Der Rest ist ja korrekt, weil deine Funktion str2hex in der buderus4000.php nutzt die Funktion dechex.
Diese erzeugt nur so viele ‚Stellen‘ wie nötig. Darum steht da statt 00, 01 oder 09 halt nur 0, 1 oder 9.

Ich konvertiere in meinen Modulen die Daten nach Möglichkeit gar nicht.
Ist halt nur ‚blöd‘ für das Logfile… und eine andere Möglichkeit (wie die Debug-Ausgabe, welche mit Rohdaten umgehen kann) haben wir ja leider aktuell nicht.

Michael

Du hast in Deinen Modulen den Empfangsbuffer mit lock bzw. delock „verriegelt“ … könnte es damit zusammenhängen ?

Mhhh… ich clone nachher mal dein Modul, vielleicht sehe ich dann mehr.
Den Lock nutze ich, damit nicht mehrere Aufrufe einer Instanz gleichzeitig senden können.

Beim Empfang ist es halt so, dass IPS die Daten an die Instanz sendet.
Je nachdem wie (Hardware) oder wie viel (Menge) die Daten eintreffen, kann es sein dass es noch kein ganzes Datenpaket ist.
Darum nutze ich eine IPS-Variable als Buffer und verriegel diese mit Lock. Vielleicht ist dies beim Empfang inzwischen auch unnötig, ich habe weis nicht ob die IO-Instanzen die Daten in einem sep. Thread übergeben und sich somit überschneiden könnten.
Michael

Super Sache, danke !

Habe Dir eine PN gesendet mit dem freigeschalteten Port, dann bekommst Du die Daten ebenfalls.

Melde Dich falls die Portweiterleitung nicht funktionieren sollte.

Hermann

Hallo Nall-chan,

ich denke ich hab´s jetzt lösen können. Weiß nur nicht warum und wieso … bedarf noch einiger Recherche.
Ich melde mich ggf. nochmal …
Danke Dir für die Unterstützung.

By the way …

lässt sich mit PHP ein Protocol-Umsetzer (3964R) als Modul basteln ?
Momentan macht diesen Part noch das ProtocolControlModul von der Fa. LeaOil. Leider nur auf einer Windoof-Kiste.

BG,
Hermann

Schön zu hören… ich fange jetzt gerade erst an :smiley:

Allerdings habe ich deinen Fehler bezüglich der übergeordneten Instanzen gefunden.
Du darfst nicht bei childRequirements die GUID von dem Modul angeben, sondern musst die GUID deinen Datentyps eintragen.
Also was der Child bei implemented stehen hat.
Ebenso muss bei parentRequirements des Child die GUID des Datentyps eingetragen werden, welche im Parent (Splitter) bei implemented eingetragen wurde (zusätzlich zu den Datentyps welche der Parent des Splitters nutzt).


{
    "id": "{24F1DF95-D340-48DB-B0CC-ABB40B12BCAA}",
    "name": "LogamaticGateway",
    "type": 2,    
    "vendor": "Buderus",
    "aliases": ["Logamatic Gateway"],
    "parentRequirements": ["{79827379-F36E-4ADA-8A95-5F8D1DC92FA9}"],
    "childRequirements": ["{FDAAB689-6162-47D3-A05D-F342430AF8C2}"],
    "implemented": ["{018EF6B5-AB94-40C6-AA53-46943E824ACF}","{0D923A14-D3B4-4F44-A4AB-D2B534693C35}"],
    "prefix": "Gateway"
}


{
    "id": "{9888202F-A490-4785-BDA7-DBB817B163B2}",
    "name": "Logamatic4311",
    "type": 3,
    "vendor": "Buderus",
    "aliases": ["Logamatic 4311"],
    "parentRequirements": ["{0D923A14-D3B4-4F44-A4AB-D2B534693C35}"],
    "childRequirements": [],
    "implemented": ["{FDAAB689-6162-47D3-A05D-F342430AF8C2}"],
    "prefix": "Logamatic"
}


Ohne jetzt die physikalischen Eigenschaften zu kennen… rein vom Protokoll bestimmt.
Nur wie viel ‚Last‘ erzeugt das Protokoll nachher ? Wie viele und wie häufig werden Daten übertragen.
Dies ist auch ein Punkt welchen ich bisher kritisch betrachte, Erfahrungswerte fehlen da einfach noch …

Aktuell wird ja jedesmal wenn du Daten über einen IO empfängst, ein PHP-Thread erzeugt, deine Modul-Datei geladen, daraus eine neue Klasse erzeugt und dann erst kommen die Daten an die Receive-Funktion.
Dies ist doch ‚relativ‘ viel Overhead.

Also einen eBus-Koverter werde ich z.B. nicht in PHP umsetzen.
Nur das nachgelagerte Auserten der Nutzdaten irgendwann.
Aber auf keinen Fall das direkte lesen und senden auf den Bus. Dazu ist mir das Timing mit den Sync einfach zu zeitkritisch.

Michael

So nächstes Problem(chen):

Kann ich in Modulen mit mehrdimensionalen Arrays arbeiten ?

<?php
require_once(__DIR__ . "/../buderus4000.php");  // diverse Klassen

class Logamatic4311 extends IPSModule
{
    private $Buderus[128][-1] = array ("Heizkreis 1", "17");
    private $Buderus[128][0] = array ("Betriebswerte", "Bit", "Ausschaltoptimierung", "Einschaltoptimierung", "Automatik");
    private $Buderus[128][1] = array ("Betriebswerte 2", "Bit", "Sommer", "Tag", "keine Kommunikation mit FB", "FB fehlerhaft");

Bekomme leider einen Syntax-Fehler von IPS. Das Array in einem Skript funktioniert tadellos …

Habt Ihr eine Idee ?

Hermann

Hat sich erledigt … habe eine function draus gemacht !

Hallo zusammen,

kann ich in Modulen mit thread´s arbeiten ? Hat jemand ein Bespielskript in php ?

Gruß,
Hermann

Hatte ich auch schon mal überlegt… die Erweiterung ist aber nicht installiert. Es bringt dir aber auch nichts.
Du bist bei jeder Aktion welche IPS mit deinem Modul startet, an die 30sek Scriptlaufzeit gebunden.
Also permanent die Instanz ‚leben‘ zu lassen, geht nicht.
Michael

Hallo Nall-chan,

danke für die umgehende Einschätzung … machst Du das Forum hauptberuflich ? Ich meine nur, weil Du immer gleich antwortest :wink:

Mein aktuelles Probem ist, daß ich bei meinem Buderus Logamatic 4000 Modul gelegentlich (zumindest initial) in den sogenannten Monitormodus gehe und dabei >1kB an Daten (ist eine Art Speicherabbild) von ihr bekomme. Diese müssen erst gepuffert und dann verarbeitet werden. Ist im Prinzip nicht zeitkritisch, allerdings lässt sich die Datenmenge wahrscheinlich nicht in den 30sek, welche Du beschrieben hast komplett verarbeiten.

Ich muß mir also was überlegen, daß ich mit einer gesetzten Variable beim Abruf der Monitordaten und damit verbundenem Timer bei Instanzaufruf die Zeit nutze und jedes mal einen Teil des Puffers abarbeite.

Welche Alternativen hätte ich noch ?

Danke und Gruß,
Hermann

Nee… aber ich habe diesen Bereich abonniert und bekomme somit immer die Infos :slight_smile:

Wenn du die Daten über einen IO bekommst, wird dir dieser nicht alles auf einmal senden. Sondern Stück für Stück.
Du musst also jedes mal die Daten auf Vollständigkeit prüfen und sonst immer ein einen Buffer schieben.
Hier hast du dann auch kein Problem mit der max. Laufzeit.
Macht mein SqueezeBox-Modul auch (und auch fast alle anderen meiner Module welche einen IO benötigen).
Dann wird deine Instanz zwar 20-30 mal gestartet bis du deinen Datensatz hast, aber es geht.
Wichtig ist, dass du irgendwie erkennen kannst, dass deine Daten komplett sind.
Also Start/Endzeichen, Längenangabe, Checksumme oder ähnliches.

Auch mit großen Playlisten hatte ich noch keine Probleme, den dann 600kB großen Datensatz innerhalb der 30sek zu verarbeiten.
Michael