manchmal Dingen fehlen einem so die richtigen Ideen…
Ich möchte über ein Modul eine serielle Schnittstelle zur Verfügung stellen. Diese sollten - wenn sie dann eingebunden ist - vom IPS her möglichst so bedient und abgefragt werden wie eine „normale“ serielle Schnittstelle.
Ich grübele schon die ganze Zeit, wie man das wohl am Besten anstellt…
Wäre da die RegisterVariable da der richtige Ansatz?
Wenn ist so ist, wie binde ich diese überhaupt in mein Modul ein?
Schau dir mein WebSocket Modul, den ClientSplitter an.
Der stellt die übliche IPS interne IO zur Verfügung.
Oder meinst du, du möchtest eine serielle in deinem Modul ansprechen? Also andere Richtung?!
Michael
ich möchte die serielle Schnittstelle eines entfernten Raspberry Pi zur Nutzung durch ein Modul einbinden.
Durch eine einfache public function kann ich es relativ leicht realisieren, dass dort Daten hingesendet werden, nur was mache ich am Besten - um dieses Funktion auch möglichst universel nutzbar zu machen - mit den Daten die zurückkommen? Das könnte ja ziemlich „wilde“ Zeichenfolgen sein und der Nutzer muss diese in fast allen Fällen ja irgendwie weiterverarbeiten.
Wenn der Nutzer einen „echten“ SerialPort" im IPS installiert, wird er doch die ankommenden Daten in der Regel auf eine Registervariable schicken, die dann ein Skript zur Verarbeitung antriggert. In der Dokumentation steht, man soll die ankommenden Daten nicht auf eine „normale“ Stringvariable schreiben…
Verwendest Du auf dem Remote PI ser2net zur Umleitung serielle Schnittstelle IP-Socket und auf dem lokalen Pi einen normalen Clientsocket. Fertig. So mache ich es bei meinem Busware COC.
Du musst dann in deinem Modul den Virtual I/O als Interface für die Childs implementieren.
Außerdem musst du ja irgendwie die Daten vom RPi bekommen, auch dafür brauchst du ja bestimmt einen IO. Sprich ClientSocket o.ä.
Auch dafür musst du ein Interface in deinem Modul implementieren.
Daten Buffern musst du selbst ja gar nicht und kannst dich ‚transparent‘ verhalten.
Das ist dann die Aufgabe des Users mit Hilfe einer RegVar, welcher er hinter dein Modul hängt.
Michael
PS: ClientSocket und Serielle Schnittstelle bilden das gleiche Interface ab und sind in IPS untereinander austauschbar. Dafür braucht es kein Modul.
ofensichtlich muss ich jetzt doch noch mal etwas ausholen:
Selbstverständlich benutzt mein Modul eine ClientSocket und dabei auch die Wege die im Datenfluss beschrieben sind. Wenn man es genau nimmt, sind es sogar zwei: Eines für die Kommandos und eines für den Empfang „unangefragter Daten“. Die Kommunikation besteht darin, auf dem entfernten Pi GPIO, I²C, die serielle Schnittstelle und 1-Wire zu steuern und die Ergebnisse im IPS darzustellen. Alles so weit so gut - bis auf ein paar Details wie im anderen Thread beschrieben.
Auch die Kommunikation aus dem Splitter-Modul hin zum Pi wird über diese beiden ClientSockets laufen - intern. Wenn jemand etwas zur seriellen Schnittstelle senden möchte, macht er einen Funktionaufruf der dann aufbereitet und wie im Datenfluss beschrieben über den ClientSocket zum entfernten Pi gesendet wird. Neben vielen anderen Daten aus 1-Wire, I²C usw. kommen die Daten über den ClientSocket und über die im Datenfluss beschrieben Wege wieder zum Splitter und werden an die Instanzen verteilt.
Bei der seriellen Schnittstelle gibt es aber keine konkrete Funktion - anderes als bei I²C z.B. wo nur definierte Bausteine zugelassen sind. Die aus dem Pi kommenden Daten der seriellen Schnittstelle sollen nun aus dem Splitter an eine „universelle“ Schnittstelle gesendet werden, damit der Nutzer selbst diese Daten weiterverarbeiten kann - und da dachte ich eben daran, diese an einen RegisterVariable zu senden, wo der Nutzer eben das Skript definieren kann, was ihm die ankommenden Daten weiterverarbeitet…
Ist das so nachvollziehbar?
Im Moment habe ich das versuchsweise mal so realisiert:
Funktionsaufruf im Splitter mit dem zu sendenen Text „Test“
Die Daten werden aufbereitet und in diesem Fall über meinen „CommandClientSocket“ an den entfernten Pi gesendet
da ich RX und TX dort verbunden habe bekomme ich die Daten zurück
ich visualisiere sie und der Text ist „Test“
Ich könnte jetzt ja auch folgendes machen:
Ich gönne meinem Modul eine weitere Stringvariable und schreibe den empfangenen Text dort herein, der Nutzer überwacht diese Stringvariable auf Änderungen und verarbeitet diese dann - das sollte doch aber wohl so nicht sein, oder…
Es geht also lediglich um die regelkonforme Visualisierung bzw. die zur Verfügungstellung der ankommenden Daten…
Auch nicht machen.
Rohdaten haben in IPS-Variablen nichts zu suchen.
Du musst die Daten schon per SendDataToChildren weitersenden an einen Child (welche das ist, ist ja egal).
So dass der User dann dort eine RegVar hinter hängt und dann kann er im Script mit den Daten machen was er will.
Oder es schreibt jemand ein Modul und hängt es dort hinter, auch egal.
Zum senden von diesem Child über deinen Splitter musst du aber auf jeden Fall auch das ForwardData umsetzen, sonst kann weder die RegVar noch eine andere Instanz hinter deinem Splitter die Daten versenden.
Deine Public-Funktion ist ein Addon, was auch jede IPS-IO-Instanz hat; braucht man aber nicht wirklich.
Beispiel: (Ersetze serielle Schnittstelle + ZigBee-Module durch deine Splitter und IOs)
sieht nach außen damit nahzu identisch aus…(und klingt in beiden Fällen nach einer PublicFunction)
Ob diese dann im Splitter direkt hängt oder darunter noch ein Child ist dabei vielleicht erst einmal zweitrangig und im Zweifel schnell gemacht…
Aber wie realisiere ich den auch von Dir gezeigten Weg „So dass der User dann dort eine RegVar hinter hängt…“, also die Datenausgabe?
Joachim
Nachtrag: Die IPS-RegisterVariable kann ich meinen Splitter nicht als übergeordnete Instanz zuweisen. Mein (neu zu schaffendes) Child könnte also die Funktion der RegisterVariablen abbilden. Wie würde ich dem „Ziel-Skript“ die ankommenden Daten als $_IPS[‚VALUE‘] übergeben?
…das wird so nicht funktionieren befürchte ich…
Die IPS-RegVar akzeptiert meinen Splitter nicht als übergeordnete Instanz, müsste aber so sein, da die Daten noch vor dem Senden aufbereitet werden müssen, umgekehrt müssen die ankommendenDaten erst herausgefiltert werden und dann an „mein“ RegVar-Child übergeben werden.
Das heißt, ich erstelle etwas was aussieht wie ein IPS-RegVar und der User kann ein Zielskript wählen, dazu muss ich dem gestarteten Skript aber die Daten „mitgeben“…
Auch nicht machen.
Warum etwas neues erfinden, wenn IPS funktionierende Mittel hat.
Dann kann keine andere Instanz sich an deine Instanz als Child anhängen und alle Skripte welche für eine RegVar ausgelegt sind, funktionieren auch nicht.
Zusätzlich müsstest du dem User einen Buffer zur Verfügung stellen.
Alles Aufwand und Umwege welche du in Kauf nimmst.
Mach es so wie Tommi es schreib; vermutlich hast du in der Modul.json irgendeine falsche / fehlende GUID.
Michael
…wenn das so klappen würde, wäre das mit Sicherheit die beste Variante!
Bin jetzt aber (wieder) etwas am Schwimmen:
Wie sind denn die GUID für RX und TX?
Die RegVar wäre ja in diesem Fall das Device?
Und weiß die RegVar dass sie jetzt nicht I/O sondern Device ist? Ich kann dort doch nichts eintragen?
auch auf die Gefahr hin, dass ich hier gleich geschlagen werde - ich habe es noch nicht verstanden…:mad:
Derzeit ist die Struktur so:
Client Socket
Splitter
1 - n-Devices
Nun habe ich im Splitter die Code-Bestandteile, die für alle Devices die Kommunikation
von den Devices über den Splitter zum Client Socket und
vom Client Socket über den Splitter zu den Devices
abarbeiten
Jetzt zu dem was ich meine verstanden zu haben:
es soll eine virtuelle I/O hinzugefügt werden
an diese virtuelle I/O kann der Nutzer eine IPS-RegVar hängen
der Nutzer kann dann über REGVar_SendText Daten senden
und über das anzugebene Zielskript ankommenden Daten auswerten
Nur wo soll ich jetzt den Virtuellen I/O ranhängen? Kann ein Device oder ein Splitter denn zwei Parents haben?
DIE RX/TX GUID sind ja gleich den der schon verwendeten Client Socket. Muss dann beim Start zwei RequireParent in den Code?
Also wenn du einen zweiten IO zur Hardware brauchst, dann kommt das natürlich nicht in deinen Splitter sondern wird eine ganz neues eigenes Modul.
Wenn du jedoch einen I/O hast und dann dein Splitter… was hindert dich daran, außer die Verbindung zu deinen Devices, eine Verbindung zu anderen Devices (Virtual-IO Interface) umzusetzen.
Beispiel:
Mein WebSocketClient ist ein Splitter und hat einen Clientsocket als übergeordneten IO.
Ich sende dann die Daten einfach an mehrere Interfaces
Hier ist das sehr einfach da die Daten ja den gleichen Nutzen haben.
Bei den XBees ist es z.B. ganz anders.
Da wird mal ein serielles Datenpaket empfangen und muss an den Virtual-IO zum nächsten Splitter/RegVar.
Und mal eine Veränderung der A/D Pins übertragen welches ich dann an eine Geräte-Instanz senden muss.
Also ein Datenstrom rein… auseinanderdrösseln und weiter senden an verschieden Interfaces.
Funktioniert super (darum heißt das Ding ja auch Splitter )