@paresy Ich glaube Du hast mein Anliegen nicht verstanden.
Modbus ist ja jetzt keine Raketenwissenschaft wofür es ein NDA geben könnte?
Ich habe in der offiziellen Dokumentation keinen Hinweis gefunden, wie bei den Modulen die Anbindung an das ModBus Gateway funktioniert.
Ein paar Hinweise in der offiziellen Doku über den Datenfluss des ModBus Gateway analog wie für (Client Socket, HID, HTTP Client, …) ist ja jetzt keine große Sache.
Eine Referenz auf einen Beispielcode mit ein paar zusätzlichen Hinweisen im Code hätten mir auch gereicht.
Mein Ergebnis aus „Jugend forscht“ sieht wie folgt aus. Vielleicht kann das jemand anderes gebrauchen.
Falls ich falsche Rückschlüsse gezogen habe bitte berichtigen.
class MODBUS extends IPSModule {
public function Create()
{
//Never delete this line!
parent::Create();
// verbinde ein ModBus Gateway
$this->ConnectParent("{A5F663AB-C400-4FE5-B207-4D67CC030564}");
}
public function Destroy()
{
//Never delete this line!
parent::Destroy();
}
public function ApplyChanges()
{
//Never delete this line!
parent::ApplyChanges();
}
public function ModBusRequest()
{
// $DataID ist die [Implemented] GUID des ModBus Gateway.
// Lässt sich mit folgendem Befehl ermitteln: IPS_GetModule("{A5F663AB-C400-4FE5-B207-4D67CC030564}")
$DataID = "{E310B701-4AE7-458E-B618-EC13A1A6F6A8}";
// ModBus Adresse des Gerätes. Die ModBus Geräte ID wird direkt im Modbus Gateway konfiguriert.
$Address = 0x0000;
// ModBus FunctionCode zur Abfrage bzw. Senden von Parameter. (Siehe https://de.wikipedia.org/wiki/Modbus)
$Function = 4;
// Anzahl der Datenregister
$Quantity = 2;
// Datenbyte String, zum Schreiben an ModBus (Bei FunctionCodes 5,15,6,16)
$Data = "";
$response = $this->SendDataToParent(json_encode(Array("DataID" => $DataID, "Function" => $Function, "Address" => $Address , "Quantity" => $Quantity, "Data" => $Data)));
// $response[0] => gesendeter Function Code
// $response[1] => Anzahl der folgenden Werte Bytes (angefordert mit $Quantity)
// $response[2] bis
// $response[x] => Werte Bytes. Die Reihenfolge ist unabhängig von der Einstellung von "Swap LSW/MSW" im Modbus Gateway !!
$this->SendDebug("ModBus Response", $response, 1);
}
}
Ich klinke mich hier mal ein. Ich bin auch grade dabei ein Modul zu schreiben für eine EOS Saunasteuerung die über ModBus angebunden ist.
Leider bekomme ich es nicht hin, die Parent Instanz in der Create Funktion einzubinden. Wenn ich den Code wie ich hier erfahren habe verwende:
class EOSModBus extends IPSModule
public function Create()
{
//Never delete this line!
parent::Create();
$this->ConnectParent('{A5F663AB-C400-4FE5-B207-4D67CC030564}');
$this->CreateVariableProfiles();
$this->RegisterPropertyInteger("Vaporizer", 1);
$this->RegisterPropertyInteger('Interval', 0);
$this->RegisterTimer('UpdateTimer', 0, 'EOS_RequestRead($_IPS["TARGET"]);');
}
bekomme ich die Meldung:
Warning: Datenfluss ist inkompatibel in C:\ProgramData\Symcon\modules\EOSModBus\EOSModBus\module.php</b> on line 34
(Code: -32603)
Edit:
Ich hab es grade selbst gefunden, man muss die Datei modul.json entsprechend anpassen, dann läuft es zumindest schon mal durch.
So ich bekomme meine Steuerung schon mal ausgelesen. Das geht mal super fix und mal dauert es ewig kein Ahnung warum. Ich bekomme aber fast immer am Ende der Schleife in der ich alle Daten hole einen Fehler „Zeitüberschreitung beim Warten auf Antwort“ aber die Daten werden meistens trotzdem gelesen und angezeigt. Und ab und zu auch die Meldung „ILLEGAL_DATA_ADDRESS“ was aber scheinbar nur passiert wenn ich versuche ein Register auszulesen, dass in meinem Fall zwar vorhanden ist, das aber keine Daten enthält. Dann hab ich noch den Fall, dass teilweise bei einem Lauf keine Daten geliefert werden.
Und dann kommt auch ab und an nur „UNKNOWN_ERROR“.
Das Verhalten ist irgendwie nicht vorher zu sehen.
Fragen:
Kann ich das Verhalten irgendwie analysieren?
Und wie kann ich die Meldung unterdrücken? Mit try / catch scheint es nicht zu gehen.
Das ist ein sehr schönes und anschauliches Beispiel vielen Dank dafür.
Ich hab das jetzt mal auf eine eigene Entwicklungsmaschine geschoben und auch nur noch die Steuerung am Modbus hängen und jetzt sieht es ganz gut aus. Allerdings bekomme ich immer bei der letzten Adresse die ich lese zwar den Wert aber danach den Fehler „ILLEGAL_DATA_ADDRESS“.
Jetzt befasse ich mich grade mit dem Schreiben von Werten. Das scheint auch noch nicht so einfach zu sein. Ich würde das gerne so machen, dass durch die Änderung der Variablen das Schreiben ausgelöst wird. Das passiert in RequestAction richtig? Aber wie müssen die Daten aussehen die gesendet werden? Ein einfacher String scheint es nicht zu sein wenn ich da z.B. 80 Als Wert übergebe zeigt mir das System später 48 an. Ich gehe mal davon aus, dass da was umgewandelt werden muss da das wohl Hex Werte sein müssen?.
Das funktioniert nicht. Zumindest nie über die Änderung des Wertes der Variable.
Es gibt aber die Anforderung einen Wert zu setzen, welches durch die Visualisierungen bzw. im Script durch RequestAction ausgelöst wird.
Diese Anforderungen landet dann, wie schon korrekt erkannt, im Modul in der Methode RequestAction.
Das ist die sogenannte Standardaktion einer Variable, welche du aber erst mit EnableAction auf deine Variable aktivieren musst.
Wie die Werte beim Schreiben genau sind, kann ich dir nicht sagen. Auf jeden Fall ist String (Datentyp) der Inhalt dürfte aber binary sein.
Michael
Zum Thema schreiben: Ich wandle einen Integer Wert in einen String und den übergebe ich. Kann es sein, dass da ein anderes Datenformat benötigt wird? Ich bekomme dabei keinen Fehler aber schalten tut das Gerät auch nicht.
Kann ich irgendwo den Code für das ModBus Devide finden? Da wird das doch auch gemacht und funktioniert.
Was heißt wandeln?
Nur die Zahl als Datentyp String versenden oder die Zahl in ihre binären Entsprechung?
Zeig doch einmal dein Code.
Irgendwo hatten wir das Thema im Forum schon einmal. Bin aber gerade auf den Sprung und kann somit nicht suchen.
Michael
Ich glaube es hat sich erledigt. Natürlich muss ich pack verwenden um aus dem Int den richtigen String zu bauen. Sorry für die Verwirrung!
Was ich jetzt noch brauche ist die Info, wie ich diese Action aufrufe wenn ich den Wert im Webfront ändere. Sprich wie kann ich die Standardaktion setzen wie z.B. das eigene Profil?
Ach ja und drei Fragen hab ich noch,
wie kann ich mein Modul aus einem Skript heraus aufrufen?
wie macht man es am geschicktesten diese Funktion „Status emulieren“ mit einzubauen (auch im Form) und zu verwenden?
wie kann ich meine Switches anwenden? Genau wie alle anderen auch?
Public Methoden werde als Instanz-Funktionen von Symcon verstanden. Dazu kommt davor das Präfix aus der module.json. Das steht auch in der Doku
Beispiel:
Zuerst im Abschnitt Konfigurationsformular der SDK Doku einmal die benötigten Elemente (CheckBox) raussuchen. Und wie man Eigenschaft einer Instanz registriert und liest: RegisterPropertyBoolean — IP-Symcon :: Automatisierungssoftware
Dann kannst du vor dem Senden prüfen ob die Eigenschaften aktiv ist oder nicht.
OK hab ich gemacht aber das läuft noch nicht, werde ich mir aber noch mal näher ansehen.
Auf jeden Fall hab ich mir das Ganze jetzt im Webfront angeschaut und wenn ich da irgendetwas einstelle kommt es sauber an der Steuerung an. Ich bin sehr begeistert.
Wenn ich jetzt noch raus bekomme wie ich die ab und an kommenden Meldungen über Zeitüberschreitung raus bekomme ist das Teil für mich perfekt nutzbar.
Der Beitrag hier oben, genauer das verlinkte TestModule ist genau das.
Eine Variable ‚TestVariable‘ mit Standardaktion und dann in RequestAction die Verarbeitung der Aktion. In diesem TestModule wird einfach nur die Variable gesetzt. Du müsstest dann deine Schreibfunktion ausführen.
Ja genau das mache ich. Beim Schalten über das Webfront funktioniert es auch. Beim Ändern des Wertes über den Objektbaum nicht. Ist aber egal, da es mir darauf ankommt das Element sauber über die Oberfläche bzw. ein Skript setzen zu können.
Ahhhh dann kann ich ja lange suchen. Dann bin ich also mit dem Teil fertig.
Vielen Dank für de geduldige Antworten! Ist auch nicht überall selbstverständlich.
Schönes Wochenende!