FHEM Forum

FHEM - Entwicklung => FHEM Development => Thema gestartet von: KernSani am 06 April 2020, 07:43:45

Titel: WebSocket via DevIO?
Beitrag von: KernSani am 06 April 2020, 07:43:45
Hallo zusammen,

Ich bastle gerade ein Modul, um die Daten meines Grünbeck-Wasserenthärters aus der Cloud zu lesen. Nun habe ich festgestellt, dass ein Teil der Daten (aktuelle Verbrauchdaten etc...) via Websocket kommt. Das ist „Neuland“ für mich. Bevor ich mich da im Detail einlese: Wäre das ein Fall für DevIO? Gibt es ein Modul, wo ich mir das mal ansehen kann?

Danke,

Grüße,

Oli


Gesendet von iPhone mit Tapatalk
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 06 April 2020, 08:56:05
Zitat
Wäre das ein Fall für DevIO?
Ich meine ja. Wenn Du einen Patch hast...

Zitat
Gibt es ein Modul, wo ich mir das mal ansehen kann?
FHEMWEB.pm implementiert eine unvollstaendige Version eines Websocket Servers.
Im Wesentlichen: HTTP-Aufruf, was per HTTP-Upgrade-Headerzeile zu websocket wird. Die gesendeten Daten werden jeweils mit einer Laengenangabe geprefixt.
Problematisch bei DevIO: Control-Pakete wie ping, wo keine Daten fliesen.
Ich wuerde es erst mal im Modul implementieren, und wenn es funktioniert, dann nach DevIO portieren.
Titel: Antw:WebSocket via DevIO?
Beitrag von: RichardCZ am 06 April 2020, 09:15:32
Ich meine ja. Wenn Du einen Patch hast...
FHEMWEB.pm implementiert eine unvollstaendige Version eines Websocket Servers.
Im Wesentlichen: HTTP-Aufruf, was per HTTP-Upgrade-Headerzeile zu websocket wird. Die gesendeten Daten werden jeweils mit einer Laengenangabe geprefixt.
Problematisch bei DevIO: Control-Pakete wie ping, wo keine Daten fliesen.
Ich wuerde es erst mal im Modul implementieren, und wenn es funktioniert, dann nach DevIO portieren.

Kann man in solchen Fällen heutzutage echt nicht "einfach mal" fertige Implementierungen nehmen?

https://metacpan.org/pod/release/VTI/Protocol-WebSocket-0.26/lib/Protocol/WebSocket.pm

Wenn einige Voraussetzungen erfüllt sind:

* Perl-Only (damit man das tatsächlich mit dem Source ausliefern kann)
* keine weiteren Abhängigkeiten, oder nur CORE, oder ebenfalls kleinere Perl-only
* stabil/funktional/gewartet

sehe ich keinen Grund warum man sich da nicht bedienen sollte.
Titel: Antw:WebSocket via DevIO?
Beitrag von: herrmannj am 06 April 2020, 09:18:04
@KernSani

ich würde Unterstützung anbieten.
Titel: Antw:WebSocket via DevIO?
Beitrag von: KernSani am 07 April 2020, 08:31:59
Danke erstmal. Ich werde mal modulspezifisch was basteln und mich melden, wenn ich nicht weiter komme.
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 07 April 2020, 08:52:21
Zitat
Im Wesentlichen: HTTP-Aufruf, was per HTTP-Upgrade-Headerzeile zu websocket wird. Die gesendeten Daten werden jeweils mit einer Laengenangabe geprefixt.
So ist es im SamsungAV realisiert.

Zitat
Kann man in solchen Fällen heutzutage echt nicht "einfach mal" fertige Implementierungen nehmen?
Wie heißt die Lib, die mit apt-get installiert werden kann ? Google brachte nicht die Erleuchtung.  :'(

Grüße Markus
Titel: Antw:WebSocket via DevIO?
Beitrag von: mahowi am 07 April 2020, 08:59:43
Als Debian Paket gibt's das Modul zur Zeit nur für Bullseye: https://packages.debian.org/bullseye/libprotocol-websocket-perl

Dazu muß man also die Bullseye Repositories apt hinzufügen und über "Pin-Priority" festlegen, daß nur libprotocol-websocket-perl daraus installiert wird. Ähnlich habe ich das auf einem anderen Pi für PiVPN mit Wireguard.
Titel: Antw:WebSocket via DevIO?
Beitrag von: herrmannj am 07 April 2020, 09:03:40
Moin,

die lib (CPAN) Protocol::WebSocket / und apt-get libprotocol-websocket-perl

Fertig oder cleanroom, wird ja hier immer mal wieder diskutiert. fhem bringt bereits eine Implementierung mit. (CPAN) Protocol::WebSocket ist, soweit ich auf die schnelle sehe, pure perl. Kann man also auch fix adaptieren.

edit: überschnitten. @mahowi, ich glaube debian (sid+) hat die auch so in den sources.
Titel: Antw:WebSocket via DevIO?
Beitrag von: mahowi am 07 April 2020, 09:10:15
edit: überschnitten. @mahowi, ich glaube debian (sid+) hat die auch so in den sources.
Ja, in sid ist sie auch drin. Aber das ist ja auch testing. In allen (stabilen) Versionen davor bis inklusive Buster ist sie leider nicht dabei.
Titel: Antw:WebSocket via DevIO?
Beitrag von: herrmannj am 07 April 2020, 09:22:52
dies Beispiel zeigt imho warum es doch schön ist, wenn fhem das ootb mitbringt
Titel: Antw:WebSocket via DevIO?
Beitrag von: mahowi am 07 April 2020, 09:42:15
Prinzipiell ist es schön, wenn FHEM alles mitbringt. Andererseits halte ich es für unnötig, das Rad ständig neu zu erfinden, wenn es bereits praktikable Lösungen gibt.

Und wenn bereits existierende Bibliotheken z.B. in FHEM/lib kopiert werden, führt das dazu, daß dort im Laufe der Zeit wahrscheinlich veraltete Versionen liegen, die keiner mit der ursprünglichen Version synchronisiert. Das ist dann wie bei vielen Windows-Programmen, die Standard-Bibliotheken mitbringen und im eigenen Verzeichnis ablegen. Man hat hinterher dieselben Dateien in unterschiedlichen Versionen überall im System verteilt.
Titel: Antw:WebSocket via DevIO?
Beitrag von: Beta-User am 07 April 2020, 10:05:41
Vielleicht verstehe ich von diesen ganzen Dingen zu wenig, will aber mal als Stichwort "perlbrew" in den Raum werfen, nachdem das jüngst in anderen Zusammenhängen hier in den Raum geworfen wurde...

Kurz zum Hintergrund:
Was die Perl-Basis angeht, hatte ich bisher immer versucht, nur das zu installieren, was das OS kannte (via apt-get), vor allem, damit alles auf einem zueinander passenden Stand ist. Mit cpan war ich immer sehr vorsichtig, und wenn, dann habe ich dh-make verwendet, um Debian-Pakete zu bauen, die man auch wieder deinstallieren kann.

Von perlbrew habe ich jetzt verstanden, dass man das nutzen kann, um
- neuere (oder ältere) Versionen von Perl-Paketen zu erhalten, und zwar alle auf demselben "Perl-Stand"
- darüber ggf. auch zusätzliche Pakete "in der richtigen Version" zu installieren.
Tendenziell würde ich jetzt dazu neigen, mir perlbrew etwas näher anzusehen, weil das ggf. Perl "aktueller" halten kann und dabei manche Probleme gar nicht entstehen würden, die ich seither über den dh-make Weg lösen wollte, ohne genau zu wissen, ob das wirklich klappt...

Frage: Wäre das nicht ein genereller Ansatzpunkt, um auf "Doppelungen" verzichten zu können, oder fürchten wir dadurch das Oberchaos, weil dann eben plötzlich "Fremdpakete" eine viel größere Rolle spielen könnten?

Es ist mir durchaus bewußt, dass der eine oder andere User dann möglicherweise völlig "verloren" bei der Frage ist, wo was zu finden und zu aktualisieren ist, wenn er jetzt noch eine "Ebene" zwischen dem OS und FHEM präsentiert bekommt. Aber evtl. ist das das kleinere Übel?
Titel: Antw:WebSocket via DevIO?
Beitrag von: herrmannj am 07 April 2020, 10:35:55
perlbrew https://perlbrew.pl/ hilft eigentlich erstmal unterschiedliche perl Versionen parallel zu betreiben (und /auch welche die es vom OS garnicht gibt)

CPAN braucht man trotzdem

Zitat
Frage: Wäre das nicht ein genereller Ansatzpunkt, um auf "Doppelungen" verzichten zu können, oder fürchten wir dadurch das Oberchaos, weil dann eben plötzlich "Fremdpakete" eine viel größere Rolle spielen könnten?
Ich mag die Diskussion gar nicht nicht führen. Fakt ist, fhem bringt mqtt. json, websocket, web mit, Abhängigkeiten im grossen und ganzen keine ausser core. Bedeutet, man kann sich das Paket vom fhem Server runterladen, starten  - läuft ohne "gefrickel" (CPAN, apt-get)

Auf der anderen Seite gibt's einige Module die setzen externe Bibliotheken vorraus. Guter Stil ist es das in deutlich in die Doku zu schreiben und dafür zu sorgen dass keine Abstürze durch nichtvorhandene Abhängigkeiten entsehen (bspw eval). Zusätzlich muss man als Autor dann sehr genau darauf achten dass keine blocking calls stattfinden (LWP zb, das muss einfach nicht sein -> httputils nonblocking get).
Titel: Antw:WebSocket via DevIO?
Beitrag von: Beta-User am 07 April 2020, 10:52:44
Dass man cpan braucht, war gar nicht die Frage, vermutlich ist das "Problem" auch, dass ich mich mit der Funktionsweise von cpan schlicht bisher nie beschäftigt habe bzw. was da ganau passiert, wenn man was darüber installiert (insbesondere: Welche Version bekommt man darüber eigentlich...?). War immer eher ein "großes dunkles Loch", das ich tunlichst gemieden hatte...

Wenn ich das hier https://opensource.com/article/18/7/perlbrew (ziemlich unten) richtig verstanden habe, gibts via Perlbrew jedenfalls Möglichkeiten, das so zu machen, dass man ggf. mehrere Versionen parallel hat. Wenn cpan das im Standard auch so gut macht, soll es mir recht sein ;D .

Ansonsten fand ich den bisherigen Angang auch sympatisch, für eine "normale Installation" möglichst auf "externes Gedöns" verzichten zu können und sich mit solchen Fragen gar nicht erst auseinandersetzen zu müssen. Aber meistens kommt eben irgendwann der Punkt, an dem man doch über irgendwas stolpert (und sei es nur, um es anzutesten), für das man eben weitere Pakete irgendwoher nehmen muß...

(Wollte euch also mit meiner Anmerkung keinesfalls davon abhalten, sinnvolle Erweiterungen vorzunehmen!)
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 07 April 2020, 10:53:53
Bei perlbrew ist das Einbinden von Perl-Modulen nicht immer trivial, wenn sie von Fremdbibliotheken wie OpenSSL abhaengen. Jenachdem, ob man erfahrener und/oder ausdauernder ist als der Maintainer der Distribution (dem perl mit seinen Modulen nicht die oberste Prio darstellt), kann man damit eine bessere Loesung haben oder nur Zeit verlieren. Fuer Support kann es auch ein Problem bedeuten, weil mit perlbrew so ziemlich sicher jeder eine einmalige Kombination von Modulversionen hat. Ich bin nicht prinzipiell gegen perlbrew (ich verwende es auch), das wird aber fuer Anfaenger nicht die Loesung sein.

Ob man fuer Websocket eine externe Bibliothek verwendet, oder ob man es selbst impementiert, sollte dem Entwickler ueberlassen werden: ich kann fuer beide Loesungen gute Argumente aufzaehlen. Mir ist nur wichtig, dass man Nonblocking beachtet.
Titel: Antw:WebSocket via DevIO?
Beitrag von: RichardCZ am 07 April 2020, 11:10:59
perlbrew https://perlbrew.pl/ hilft eigentlich erstmal unterschiedliche perl Versionen parallel zu betreiben (und /auch welche die es vom OS garnicht gibt)

CPAN braucht man trotzdem
Ich mag die Diskussion gar nicht nicht führen.

Ja, aber vielleicht mag sie jemand anders führen.

@Beta-User

Perlbrew ermöglicht all das was Hermann gesagt hat aber vor allem entkoppelt es OS Updates von "Perl Infrastruktur Updates". D.h. wenn man mal sein Stretch auf Jessie Buster oder sonstwas updated, bedeutet das, dass Deine Perlbrew-Perl Installation erstmal unangetastet bleibt. Allerdings bedeutet perlbrew auch: Man hat eine Compile-Infrastruktur auf der Maschine. Von daher sehe ich perlbrew derezit nur für Entwickler (da würde ich das schon in "Pflicht" Regionen sehen), bzw. für den ambitionierten User, der ggf. bei der Installation mehr Aufwand treiben will, dafür bei den Updates weniger.

Allgemein würde ich perlbrew dem Feld-Wald-Wiesen User nicht empfehlen.

Zitat
Fakt ist, fhem bringt mqtt. json, websocket, web mit, Abhängigkeiten im grossen und ganzen keine ausser core. Bedeutet, man kann sich das Paket vom fhem Server runterladen, starten  - läuft ohne "gefrickel" (CPAN, apt-get)

Naja ... das ist nicht komplett korrekt, FHEM bringt natürlich je nach Modul noch andere Abhängigkeiten mit sich, teilweise OS abhängig und nicht abgefangen im Code. So verlangen einige Module - 42_SMARTMON fällt mir da spontan ein - externe (Linux) Binaries, die man eh via apt-get oder irgendwie anzukarren hat.

Zitat
Auf der anderen Seite gibt's einige Module die setzen externe Bibliotheken vorraus. Guter Stil ist es das in deutlich in die Doku zu schreiben und dafür zu sorgen dass keine Abstürze durch nichtvorhandene Abhängigkeiten entsehen (bspw eval). Zusätzlich muss man als Autor dann sehr genau darauf achten dass keine blocking calls stattfinden (LWP zb, das muss einfach nicht sein -> httputils nonblocking get).

Nuja. LWP sind schon schwere Kanonen, aber die Doku https://metacpan.org/pod/LWP#The-User-Agent spricht relativ deutlich einen timeout Parameter an.

Ich befürworte den Ansatz "möglichst wenig Gefrickel" bei der Installation und "noch weniger Gefrickel" beim Update. Da geht aber IMHO mehr, als man bei FHEM derzeit zu tun bereit ist. Und irgendwie passt es nicht für mich zusammen auf der einen Seite zu sagen "wir haben so wenig Entwicklerkapazität/Zeit/Lust was neu zu machen" und dann "wir machen lieber unsere eigene Implementierung".

Würde ich das jetzt malevolent interpretieren wollen, würde ich sagen "Not Invented Here"-Syndrom Terminalstadium.
Aber ich interpretiere ja stets benevolent.
Titel: Antw:WebSocket via DevIO?
Beitrag von: mahowi am 07 April 2020, 11:17:19
Dass man cpan braucht, war gar nicht die Frage, vermutlich ist das "Problem" auch, dass ich mich mit der Funktionsweise von cpan schlicht bisher nie beschäftigt habe bzw. was da ganau passiert, wenn man was darüber installiert (insbesondere: Welche Version bekommt man darüber eigentlich...?). War immer eher ein "großes dunkles Loch", das ich tunlichst gemieden hatte...
Über CPAN bekommst Du die jeweils aktuellste Version. Die Module werden unter /usr/local installiert, so daß keine unter /usr installierten Dateien überschrieben werden. Auch deinstallieren geht mit cpanm --uninstall.

Die einzigen Module, dich ich bisher nur über CPAN und nicht als Debian-Paket gefunden habe, waren Net::MQTT::... Die werden (zumindest laut Wiki (http://)) für MQTT benötigt.
Titel: Antw:WebSocket via DevIO?
Beitrag von: Beta-User am 07 April 2020, 11:28:33
Allgemein würde ich perlbrew dem Feld-Wald-Wiesen User nicht empfehlen.
Diese Schlußfolgerung lag nach Rudi's Anmerkung schon nahe.

Und ja: perlbrew wird seinen Weg auf mein Laptop finden... Viele Dinge waren halt bisher nicht notwendig, und bitte entschuldigt, wenn meine Anmerkung hier kurz vom eigentlichen Thema des Threads abgelenkt haben sollten ::) .

@mahowi: Thx für die näheren Hintergründe. MQTT (alt bzw. Generic Bridge) war auch der Anwendungsfall, bei dem ich über dh-make gegangen war (die betreffenden Hinweise im Wiki zu dem Tool stammen von mir...). Ansonsten hast du recht, das ist selten, dass man cpan überhaupt bemühen muss.
Btw: Mit dh-make kann man afaik auch rausfinden, ob es ein verfügbares Debian-Paket gibt: " dh-make-perl locate xyz"
Titel: Antw:WebSocket via DevIO?
Beitrag von: RichardCZ am 07 April 2020, 11:47:45
Diese Schlußfolgerung lag nach Rudi's Anmerkung schon nahe.

Es ist auch distributionsabhängig. Ok, wenn jemand Gentoo verwendet ist er vermutlich eh kein FWW-User, k.A. ob sich "Arch Linux" User auch in dieser Kategorie sehen. Prinzipiell gilt: Man spart sich viel Leid wenn man bei einer "Versionless Linux Distri" perlbrew benutzt.

Oder auch eine Distri wie Ubuntu, die automatisch Updates fährt (wobei wer sowas bei seiner Haussteuerung macht, der hat auch in jedem Zimmer ein Damoklesschwert hängen)
Titel: Antw:WebSocket via DevIO?
Beitrag von: Beta-User am 07 April 2020, 12:12:02
Es ist auch distributionsabhängig. Ok, wenn jemand Gentoo verwendet ist er vermutlich eh kein FWW-User, k.A. ob sich "Arch Linux" User auch in dieser Kategorie sehen. Prinzipiell gilt: Man spart sich viel Leid wenn man bei einer "Versionless Linux Distri" perlbrew benutzt.

Oder auch eine Distri wie Ubuntu, die automatisch Updates fährt (wobei wer sowas bei seiner Haussteuerung macht, der hat auch in jedem Zimmer ein Damoklesschwert hängen)
Klar ist die Welt ziemlich bunt, aber vielleicht dazu noch ein paar OT-Anmerkungen (bewußt plakativ, ist nicht böse gemeint): "gefühlte" 98% der Linux-"User" hier nutzen eine Himbeere und sind dabei ganz überwiegend schon froh, wenn sie "sudo" fehlerfrei getippt bekommen und sich nicht damit auseinandersetzen müssen, was der Unterschied zwischen einem Befehl mit und ohne diese 4 letters ist.

Schon die Empfehlung, doch bitte keine GUI zu installieren, sondern "headless" zu fahren, finden die als unangemessene Gängelung (teils auch, weil ein beliebter Videoblogger, dessen "Kenntnisse" teils als das Maß der Dinge angesehen werden, das mal mit GUI vorgemacht hat...).

Ergo:
Bitte im Hinterkopf behalten, dass das "Damoklesschwert" in Form von raspbian über den meisten der Köpfe hier hängt, und zwar zu allem Überfluß noch zu 100% über genau all denen, die keinen Plan haben, wie sie sich notfalls selbst helfen können...
Dann gibt es noch einige Minderheiten, wobei Debian und Ubuntu auch da weit dominierend sein dürften.

(Btw.: ich bin ca. Mitte 2014 von der Fritte (AVM Fritzbox) auf debian-basierte Serversysteme (neben der Himbeere im Lauf der Zeit alles mögliche) umgestiegen, kann mich aber an kein (FHEM betreffendes) Problem erinnern, das auf ein OS-update zurückzuführen gewesen wäre - und ich mache regelmäßig updates. Von daher: Ja, das ist ein Thema, aber man sollte es nicht überbewerten! Besser ein aktuelles OS und Restrisiken beim updaten als nicht geschlossene, aber bekannte Sicherheitslücken...
Aber auch das legt nahe: möglichst wenig externes "Zeug" (Abhängigkeiten, Zusatzpakete usw.), denn da kommt zumindest bei mir schnell das Gefühl auf, dass es "schwammig" wird, wenn es mal Probleme gibt.)
Titel: Antw:WebSocket via DevIO?
Beitrag von: RichardCZ am 07 April 2020, 12:32:38
Schon die Empfehlung, doch bitte keine GUI zu installieren, sondern "headless" zu fahren, finden die als unangemessene Gängelung (teils auch, weil ein beliebter Videoblogger, dessen "Kenntnisse" teils als das Maß der Dinge angesehen werden, das mal mit GUI vorgemacht hat...).

Ja aber Gängelung der User ist doch die einzige Entlohnung die man bekommt wenn man die Software schon kostenlos abgibt! Oder nicht?  ;)

Will sagen: Ich stimme ja prinzipiell zu.

* kein perlbrew für Normalsterbliche
* Code muss robust geschrieben sein, dass er bei fehlenden Abhängigkeiten nicht alles in den Abgrund reisst

Ich stimme nicht zu:

* Wir liefern unter keinen Umständen CPAN code mit

Ich mache das in Hobo, z.B. für Export::Attrs. Das sind 12KB reiner distri- & architekturunabhängiger Perl Code, der wohl auch die nächsten 10 Jahre ohne Updates tun wird.
Kein Gefrickel für den User, extreme Erleichterung für den modulbewussten Entwickler. Und solche non-CORE Module gibt es einige. Die würde ich nicht dogmatisch ausschliessen.
Titel: Antw:WebSocket via DevIO?
Beitrag von: betateilchen am 07 April 2020, 13:48:37
In allen (stabilen) Versionen davor bis inklusive Buster ist sie leider nicht dabei.

wget http://ftp.de.debian.org/debian/pool/main/libp/libprotocol-websocket-perl/libprotocol-websocket-perl_0.26-2_all.deb
dpkg -i libprotocol-websocket-perl_0.26-2_all.deb

Geht auch mit Buster.
Titel: Antw:WebSocket via DevIO?
Beitrag von: CoolTux am 07 April 2020, 13:56:03
Debian ist die einzige Distribution welche ich kenne die eine Unmenge an zusätzlicher Perlmodule mitliefert. Versuch mal bei OpenSuse was zu finden. Kannste knicken.
Titel: Antw:WebSocket via DevIO?
Beitrag von: mahowi am 07 April 2020, 13:56:57
wget http://ftp.de.debian.org/debian/pool/main/libp/libprotocol-websocket-perl/libprotocol-websocket-perl_0.26-2_all.deb
dpkg -i libprotocol-websocket-perl_0.26-2_all.deb

Geht auch mit Buster.

Natürlich kann ich mir jedes Debian Package auch irgendwo runterladen und mit dpkg installieren. Sauberer finde ich aber den Weg, die Sourcen einzubinden.

/etc/apt/sources.list.d/bullseye.list:
deb https://mirror.netcologne.de/raspbian/raspbian/ bullseye main
/etc/apt/preferences.d/limit-bullseye:
Package: *
Pin: release n=bullseye
Pin-Priority: -1

Package: libprotocol-websocket-perl
Pin: release n=bullseye
Pin-Priority: 100

So bekomme ich auch Updates, falls es welche gibt.
Titel: Antw:WebSocket via DevIO?
Beitrag von: CoolTux am 07 April 2020, 13:59:27
Natürlich kann ich mir jedes Debian Package auch irgendwo runterladen und mit dpkg installieren. Sauberer finde ich aber den Weg, die Sourcen einzubinden.

/etc/apt/sources.list.d/bullseye.list:
deb https://mirror.netcologne.de/raspbian/raspbian/ bullseye main
/etc/apt/preferences.d/limit-bullseye:
Package: *
Pin: release n=bullseye
Pin-Priority: -1

Package: libprotocol-websocket-perl
Pin: release n=bullseye
Pin-Priority: 100

So bekomme ich auch Updates, falls es welche gibt.

Na hoffentlich nimmt das jetzt kein User zum testen. Sonst ist seine buster Installation gleich im Eimer  ;D
Titel: Antw:WebSocket via DevIO?
Beitrag von: mahowi am 07 April 2020, 14:26:04
Na hoffentlich nimmt das jetzt kein User zum testen. Sonst ist seine buster Installation gleich im Eimer  ;D
Eigentlich sollte man sich damit nichts zerschiessen können.

Zitat von: man apt_preferences
       100 <= P < 500
           veranlasst, dass eine Version installiert wird, außer wenn eine Version verfügbar ist, die zu einer
           anderen Distribution gehört oder die installierte Version neuer ist

       0 < P < 100
           veranlasst, dass eine Version nur dann installiert wird, wenn es keine installierte Version des Pakets
           gibt

       P < 0
           verhindert das Installieren der Version

Da ich für alle Pakete (*) Pin-Priority: -1 gesetzt habe, wird auch außer den explizit aufgeführten nichts aus Bullseye installiert.

Mutwillig kaputt machen geht natürlich immer noch.  ;D

Im Übrigen installiert PiVPN auf die Art auch wireguard inkl. Kernel-Modulen auf einem Debian Buster.
Titel: Antw:WebSocket via DevIO?
Beitrag von: betateilchen am 07 April 2020, 14:39:45
Natürlich kann ich mir jedes Debian Package auch irgendwo runterladen und mit dpkg installieren.

Den von mir genannten FTP Server von Debian würde ich jetzt nicht zwingend als "irgendwo" einstufen. Und man muss das auch nicht für jedes Paket so machen, sondern nur für die Pakete, die im Standard nicht in den Quellen vorhanden sind - wofür es meistens gute Gründe gibt.
Titel: Antw:WebSocket via DevIO?
Beitrag von: KernSani am 01 Mai 2020, 00:48:30
Zurück zum Ursprungsthema. Ich habe das jetzt mal hier umgesetzt: https://forum.fhem.de/index.php/topic,110323.0.html
Nutzt DevIO und Protocol::WebSocket::Client. Kann man sicher schöner machen, aber funktioniert erstmal. Im BOTVAC Modul gibt es übrigens eine WebSocket-Implementierung mit DevIo, die ohne Protocol::WebSocket::Client auskommt. Vielleicht kann man sich auch daran orientieren.
Titel: Antw:WebSocket via DevIO?
Beitrag von: RichardCZ am 01 Mai 2020, 19:10:36
die lib (CPAN) Protocol::WebSocket / und apt-get libprotocol-websocket-perl

Fertig oder cleanroom, wird ja hier immer mal wieder diskutiert. fhem bringt bereits eine Implementierung mit. (CPAN) Protocol::WebSocket ist, soweit ich auf die schnelle sehe, pure perl. Kann man also auch fix adaptieren.

Ist pure-Perl, gerade gründlich getestet.
Und gleich assimiliert: https://gl.petatech.eu/root/HomeBot/-/commit/1d37880dbca37f4f92079548842acde1b492288c
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 23 Mai 2020, 17:45:18
Hi Oli,
ich hab mir Dein Kunstwerk mal angesehen, weil ich gerade auch für ein neues Modul mit websocket arbeiten muss u. gerne die SelectLoop nutzen möchte.

Du hast ja noch ne Menge httputils-Zugriffe im Modul, aber ich interpretiere das mal als zusätzliche Zugriffe bei get-/set-Befehlen ?(Machen es nicht gerade übersichtlich für mich  :()

Will heißen, Deine Logik bildet tatsächlich websocket-Zugriff für/mit DevIO und den Vorteilen von ...Read u. ...Ready sowie disconnect ab ?
Möchte halt sichergehen bevor ich den Aufwand betreibe u. Dein Konstrukt noch nicht vollständig verstanden habe.

Und TLS hast Du ja auch problemlos genutzt, richtig ?

Schönes We
Markus
PS: Wär ja schon schön es in DevIO zu haben. ;)
Ich meine ja. Wenn Du einen Patch hast...
.
.
Ich wuerde es erst mal im Modul implementieren, und wenn es funktioniert, dann nach DevIO portieren.
Titel: Antw:WebSocket via DevIO?
Beitrag von: KernSani am 23 Mai 2020, 18:34:41
Hi Markus,

mein Werk ist sicher nichts was man so nach DevIO portieren könnte :-D Korrekt, ich habe eine Menge "normale" Abfragen. Über Websocket kommen beim Entkalker nur so Daten wie aktuelle Durchflussmenge etc...

Was du brauchst (und gerne schöner lösen kannst) sind die Sub wsConnect und ales was danach kommt.

Grüße,

Oli
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 23 Mai 2020, 18:42:23
Danke Dir
Zitat
Sub wsConnect und ales was danach kommt.
So sah ich das und meine verstanden zu haben, dass du "vorher"(negotiate) nur einen "Schlüssel" holst.
Zitat
und gerne schöner lösen kannst
Wohl kaum.  ;) Bin froh, wenn ich das per cut&paste hinbekomme. Vielleicht erbarmt sich Rudi mal. ;) Kommen ja immer mehr devices hinzu.

Grüße Markus

Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 24 Mai 2020, 11:18:39
Hi Oli,
ich glaub Du hast mich ganz schön durch Deine Namensgebung aufs Glatteis geführt. wsfail hab ich gelesen u. nicht weiter über DevIo nachgedacht. Und      Log3 $name, LOG_ERROR, qq ([$name] - error while connecting to Websocket: $error);hat mich noch im Gedanken bestätigt. Ich hab mir das Hirn zermartert, was da bei mir schief läuft. Aber bei DevIo ist es ja gar keine fail-Funktion(wie bei blockingcall), sondern der callback für die non-blocking-variante. Danach erfolgt dann erst die init-func. Will heißen, Namensgebung verwirrend u. es fehlt noch ein if auf $error.

Ich hab aber noch 2 andere Probleme, dazu per edit später mehr.....

Grüße Markus

Edit: so, jetzt sehe ich klarer
1. Warum $client->read($recv_data);in while von wsHandshake ? Das ist doch die http-connect-message ?
2. $hash->{helper}{wsClient} wird für mich noch nicht nachvollziehbar nicht befüllt. Sicherlich ein indiv. Problem. >:(
3. Ich denke der Server macht nach einer Zeit einen close, weil ich keine Authentication(wg. 2.) mache.
    Aber wieso kommen (vermeintliche) frame-Header-Fragmente an ?  :o
    Ich dachte das löst nun Protocol::Websocket für mich(im Gegensatz zur "manuellen" Variante, wo ich mich selber drum kümmern muss)?
Zitat
2020.05.24 11:40:21 5: [EET] solmate Received from socket: 52fd080b
2020.05.24 11:40:41 5: [EET] solmate Received from socket: 03fd
2020.05.24 11:41:04 5: [EET] solmate Received from socket: fd27fdfd
2020.05.24 11:41:24 5: [EET] solmate Received from socket: 03fd
2020.05.24 11:41:47 5: [EET] solmate Received from socket: 33e3fd
Und wenn nicht, wo hast Du das abgefangen ? ??? :-\ :-[
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 24 Mai 2020, 11:56:21
Zitat
Vielleicht erbarmt sich Rudi mal. ;) Kommen ja immer mehr devices hinzu.
Wie kann man sowas einfach testen, ausser mit FHEMEB?
Titel: Antw:WebSocket via DevIO?
Beitrag von: KernSani am 24 Mai 2020, 12:00:17
Hi Oli,
ich glaub Du hast mich ganz schön durch Deine Namensgebung aufs Glatteis geführt. wsfail hab ich gelesen u. nicht weiter über DevIo nachgedacht. Und      Log3 $name, LOG_ERROR, qq ([$name] - error while connecting to Websocket: $error);hat mich noch im Gedanken bestätigt. Ich hab mir das Hirn zermartert, was da bei mir schief läuft. Aber bei DevIo ist es ja gar keine fail-Funktion(wie bei blockingcall), sondern der callback für die non-blocking-variante. Danach erfolgt dann erst die init-func. Will heißen, Namensgebung verwirrend u. es fehlt noch ein if auf $error.

Ich hab aber noch 2 andere Probleme, dazu per edit später mehr.....

Grüße Markus
Das erklärt dann vielleicht auch das komische Verhalten, das ich gelegentlich beobachte :-D Schaue ich mir nochmal an...


Kurz, weil mobil....
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 24 Mai 2020, 12:21:43
dann bitte auch ein Blick auf das edit meines Posts...

Zitat
Wie kann man sowas einfach testen, ausser mit FHEMEB?
Bin mir nicht sicher, ob ich Dich richtig verstanden hab: Man kann es meines Erachtens nur über die Modulentwicklung wie bei Oli u. mir(inet-Server !)
Wenn ich so weit wäre, würd ich SamsungAV(derzeit mit http, upgrade ws, frame-handling) umbauen.
Titel: Antw:WebSocket via DevIO?
Beitrag von: herrmannj am 24 Mai 2020, 12:34:34
Zum Test reicht ein Echo Server
https://www.websocket.org/echo.html
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 24 Mai 2020, 12:43:09
Oh Mann. Der ist ja klasse.  :-* Hätte mir Stunden, Nächte, wscat... gespart.... >:(
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 24 Mai 2020, 19:51:09
Hi Oli,
ich kann mir mittlerweile nicht mehr vorstellen, dass bei Dir das write funktioniert. Ein read nur deshalb, weil Du die framing bytes irgendwie eliminierst.

 Nach diversen Abstürzen, Zusatzlogging ....habe ich mal write mit simple_write gemacht. Kein Absturz. Beim anschließenden read bekomme ich nur framing bytes. Letzteres kenne ich aber schon, da ich das bei der "manuellen" Variante(also http, upgrade websocket...). auch hatte. Es ist einfach ein finales frame ohne payload mit opcode 0x08(close) vom Server, weil ihm der payload nicht gefiel.

Ich schätze neben dem o.g. die Situation nun so ein:
- websocketaufbau (mit TLS) funktioniert bestens(das Modul macht nichts anderes als das bekannte http-get, upgrade)
- Nutzung von DevIo funktioniert mit seinen Funktionen open, read, write, is_open. Read_Fn u. Ready_Fn auch.
- für read muss das frame um die framing bytes gestripped werden; vor dem write um die framing bytes ergänzt; und schließlich brauchen wir die Inhalte der framing bytes, da z.B. manchmal der Server ohne payload antwortet, aber z.B. der opcode(z.B. close) für die Weiterverarbeitung nötig ist.

@Rudi: prüft DevIo eigentlich in irgendeiner Form(z.B. ping)zyklisch , ob die Verbindung noch steht ?
Wenn ja, würde das zu einem close der Verbindung führen.

Grüße Markus
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 24 Mai 2020, 20:23:06
Zitat
@Rudi: prüft DevIo eigentlich in irgendeiner Form(z.B. ping)zyklisch , ob die Verbindung noch steht ?
Natuerlich nicht.

Websocket koennte so in DevIo eingebaut werden:
- DevIo_OpenDev uebernimmt HTTP connect und upgrade
- DevIo_SimpleRead packt die Daten aus, und beantwortet Ping & co. ReadFn (wo SimpleRead aufgerufen wird) muss mit "" als Rueckgabewert klarkommen, und dabei nichts tun. undef bedeutet Ende der Verbindung.
- DevIo_SimpleWrite packt die Daten vorm Schreiben ein. Ist noch unklar, ob dabei direkt geschrieben wird, oder die Daten ins WriteBuffer gesteckt werden.
Titel: Antw:WebSocket via DevIO?
Beitrag von: herrmannj am 24 Mai 2020, 20:32:08
Für die frames würde es cpan Module geben. Die machen auch gleich binary, verschiedene Standards usw. Vielleicht doch Überlegenswert ? siehe KernSanis Beitrag unten  ;)
Titel: Antw:WebSocket via DevIO?
Beitrag von: KernSani am 24 Mai 2020, 22:43:56
@Markus:

Hi Oli,
ich glaub Du hast mich ganz schön durch Deine Namensgebung aufs Glatteis geführt. wsfail hab ich gelesen u. nicht weiter über DevIo nachgedacht. Und      Log3 $name, LOG_ERROR, qq ([$name] - error while connecting to Websocket: $error);hat mich noch im Gedanken bestätigt. Ich hab mir das Hirn zermartert, was da bei mir schief läuft. Aber bei DevIo ist es ja gar keine fail-Funktion(wie bei blockingcall), sondern der callback für die non-blocking-variante. Danach erfolgt dann erst die init-func. Will heißen, Namensgebung verwirrend u. es fehlt noch ein if auf $error.
Ich habe jetzt extra nochmal nachgelesen. Die initFn (in meinem Fall wsHandshake) wird bei erfolgreichem Verbindungsaufbau aufgerufen, die callBackFn (in meinem Fall wsFail) wird aufgerufen, wenn die Verbindung nicht hergestellt werden kann. Die CallbackFn führt zusätzlich dazu, dass die Verbindung nonBlocking aufgebaut wird.

In wsHandshake wird dann eine Instanz von Protocol::WebSocket::Client erzeugt. Diese kümmert sich um das Ganze framing Gedöns.
Write brauche ich in meinem Szenario nicht und habe ich nicht getestet, aber bei read passiert folgendes:
Über die ReadFn (wsReadDevIo) bzw. darin Simple_Read kommen Daten. Diese übergebe ich an den zuvor definierten client (Protocol::WebSocket::Client) der sich um das framing kümmert und ich kann in parseWebsocketRead die Inhalte auswerten. Kurz tcpsocket-Aufbau und "Raw"-Kommunikation erfolgt über DevIo, Protocol::WebSocket::Client kümmert sich um die Websocket-Spezifika.

Was mir noch unklar ist: Ich habe gelegentlich Einträge im Log:
Strange call for nonexistent : ReadFnDiese stehen in keinem zeitlichem Zusammenhang zu den Websocket-Verbindungen, ich habe aber den Verdacht, dass da noch irgendwo DevIo-Leichen herumschwirren, die ich noch nicht näher aufspüren konnte.



Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 25 Mai 2020, 08:54:32
Hi Oli,
Zitat
die callBackFn (in meinem Fall wsFail) wird aufgerufen, wenn die Verbindung nicht hergestellt werden kann.
Das stimmt so nicht.
Zitat
Der Rückgabewert enthält im Fehlerfall eine entsprechende Fehlermeldung. Im Erfolgsfall wird undef zurückgegeben.
Sie wird immer aufgerufen und in Deinem Fall fehlt im Erfolgsfall dann eben ein kleines if auf undef, um die Logmeldung dann nicht abzusetzen.

Zitat
Diese kümmert sich um das Ganze framing Gedöns.
Das glaube ich auch nicht. Sonst bekäme ich ja nicht die framing bytes. Und beim write setzt Du ja nirgends opcode, FIN-bit....
Ich bin aber leider auch mal wieder zu blöd OOP-Perl so richtig zu verstehen.  :-[ Und kriege es deshalb auch nicht besser hin.
Beispiel: Du machst die Zuweisung des Objekts/Socket
    $hash->{helper}{wsClient} = $client; um es Dir zwischenzuspeichern. Das wird aber gar nicht befüllt(zumindest bei mir nicht, steht da bei Dir etwa was drin ?). Und weil das(zumindest bei mir) nicht klappt, habe ich ja im nächsten Aufruf überhaupt keinen Bezug mehr zum Objekt ?!?!? Deshalb meine Abstürze. Mache ich es mit simple_write, dann klappt es im Prinzip, weil devIo ja den fileDesriptor hat.

@Rudi: das klingt gut.
@Jörg: Das wäre ja dann z.B. Protocol::Websocket:Frame (https://metacpan.org/pod/Protocol%3A%3AWebSocket%3A%3AFrame)
Daran habe ich mich auch schon versucht. Aber ich bin zu doof für OOP.

Das
Protocol::WebSocket::Frame->new('data');   verstehe ich ja noch. Und dass die framing bits default FIN=0x01, opcode=0x01.... sind auch. Aber wie bekomme ich nun das zu sendende frame ?
Bei my $frame = Protocol::WebSocket::Frame->new('data');klappt DevIo($hash, $frame->to_bytes,2);irgendwie nicht.
Und was ich auch nicht verstehe: Ist das Objekt dann nach dem Modulaufruf noch im Nirwana des Speichers und muss ich es vorher irgendwie "löschen" oder mir irgendwie eine Referenz in einem helper "mitschleppen", um es beim nächsten Modulaufruf zu nutzen ?

Grüße Markus
Titel: Antw:WebSocket via DevIO?
Beitrag von: KernSani am 25 Mai 2020, 10:21:23
Hi Oli,Das stimmt so nicht.Sie wird immer aufgerufen und in Deinem Fall fehlt im Erfolgsfall dann eben ein kleines if auf undef, um die Logmeldung dann nicht abzusetzen.
Da hast du recht. Bei mir lokal läuft schon länger eine Version, die das berücksichtigt... Hatte ich nur noch nicht hochgeladen...

Zitat
Beispiel: Du machst die Zuweisung des Objekts/Socket
    $hash->{helper}{wsClient} = $client; um es Dir zwischenzuspeichern. Das wird aber gar nicht befüllt(zumindest bei mir nicht, steht da bei Dir etwa was drin ?). Und weil das(zumindest bei mir) nicht klappt, habe ich ja im nächsten Aufruf überhaupt keinen Bezug mehr zum Objekt ?!?!?
Bei mir klappt das... Auch wenn die Lösung äußerst unschön ist. Eigentlich sollte das eine globale Variable o.ä. sein.

Zitat
Und was ich auch nicht verstehe: Ist das Objekt dann nach dem Modulaufruf noch im Nirwana des Speichers und muss ich es vorher irgendwie "löschen" oder mir irgendwie eine Referenz in einem helper "mitschleppen", um es beim nächsten Modulaufruf zu nutzen ?
Das ist genau die obige hässliche Zuweisung.

Ich hatte das Ganze ursprünglich ohne DevIo umgesetzt (auf Basis des in den Kommentaren verlinkten Artikels) und nachträglich DevIo mit rein gefummelt. Der Artikel erklärt ganz gut, wie das funktioniert.

Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 25 Mai 2020, 11:15:36
Habe in DevIo.pm websocket Unterstuetzung eingebaut und kurz getestet mit echo.websocket.org und FHEMWEB.

Beispielmodul:
use strict;
use warnings;
use DevIo;

sub
wstest_Initialize($)
{
  my ($hash) = @_;
  $hash->{DefFn}     = "wstest_Define";
  $hash->{ReadFn}    = "wstest_ReadFn";
}

sub
wstest_Define($$)
{
  my ($hash, $def) = @_;
  $hash->{DeviceName} = "ws:echo.websocket.org:443";
  $hash->{SSL} = 1;
  DevIo_OpenDev($hash, 0, undef, sub(){
    DevIo_SimpleWrite($hash, "list", 2);
  });
}

sub
wstest_ReadFn($)
{
  my ($hash) = @_;

  my $buf = DevIo_SimpleRead($hash);
  if(!defined($buf)) {
    DevIo_CloseDev($hash);
    return;
  }
  Log 1, "GOT via websocket: >$buf<";
}

1;
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 25 Mai 2020, 11:42:48
Danke Rudi. Ich probier es mal aus.

Trotzdem würde ich gerne verstehen(zu meiner Weiterbildung  ;D), warum das bei mir nicht klappte.
Zitat
auf Basis des in den Kommentaren verlinkten Artikels
Genau den suche ich immer wieder vergebens. Ich weiß, dass ich einen Link irgendwo gesehen hatte....Weißt Du noch wo bzw. wie der lautet ?

Zitat
Bei mir klappt das... Auch wenn die Lösung äußerst unschön ist. Eigentlich sollte das eine globale Variable o.ä. sein.
Wenn ich aber ein list device mache, gibt es bei mir keine helper-Variable. Bei Dir ?!?!?!?! Oder "versteckt" list den Eintrag u. führt mich in die Irre ?

Titel: Antw:WebSocket via DevIO?
Beitrag von: RichardCZ am 25 Mai 2020, 18:00:42
Perltidy krächzt.

419: return $doCb("websocket is only supported with callback") if(!$c ...
            -----^
found ( where operator expected (previous token underlined)

Do you mean '$doCb->(' ?
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 25 Mai 2020, 18:47:14
Danke fuer den Hinweis, habs gefixt.
Titel: Antw:WebSocket via DevIO?
Beitrag von: KernSani am 31 Mai 2020, 23:48:38
Hallo Rudi,

danke für den Einbau. Leider scheitere ich in meinem Anwendungsfall schon beim Verbindungsaufbau. Der Websocket-Server ist in meinem Fall erreichbar unter einer URL der Form wss://host:port/irgendwas?undmehr=1&bla. Devio reduziert leider erstmal auf host:port (das passt ja auch für den tcpsocket) und hängt dann ein http/https für den nonBlocking-Connect vorne dran, dadurch ergibt sich https://host:port und die Websocketverbindung kommt natürlich nicht zu Stande.
Meine aktuelle Implementierung (auch vor Anpassung von DevIo) läuft vereinfacht gesagt wie folgt:
* DevIo baut tscpsocket auf (host:port)
* Basierend auf tcpsocket ($hash->{TCPDev}) wird Protocol::WebSocket::Client instantiiert (mit kompletter URL)
* Protocol::WebSocket::Client macht Handshake (upgrade etc...)
* ReadFn leitet $buf an Protocol::WebSocket::Client weiter, um Rückgabe zu bearbeiten.

Welchen Input benötigst du um das auf DevIO-Seite zu optimieren?

Danke,

Oli

Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 01 Juni 2020, 00:58:35
Meines Wissens sollte das Beschriebene ohne "Optimierung" funktionieren.
wss:XX ist als ws:XX + $hash->{SSL}=1 zu spezifizieren, analog zu TCP, siehe mein Beispiel.
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 01 Juni 2020, 06:19:02
Hi Rudi,
auch ich habe mich mühevoll versucht. Die Definition ist ja eigentlich einfach. Ich dachte, dass es an TLS liegt, aber scheinbar ist es etwas anderes beim handshake, das die Verbindung nicht zustande kommen lässt. Mit wscat u. der Test-Website, die Jörg genannt hatte, funktioniert alles bestens.

Ich hab nun die Möglichkeit das Ganze ohne TLS auszuprobieren. Ich guck mir das im Laufe des Tages mit tcpdump/Wireshark mal an.

Wunsch: Den opcode des frames zurückliefern. Insbesondere beim Test fänd ich es hilfreich, wenn die Info ankommt, dass der Server die Verbindung "geclosed" hat. Ich guck aber selber mal, ob man das einfach in DevIo unterbringen kann.

Grüße Markus
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 01 Juni 2020, 09:55:05
Lt. Wireshark antwortet der Server auf den upgrade websocket request
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: t4n9guUpD/ZNPtfze+r3aUVqTo0=
Date: Mon, 01 Jun 2020 07:32:51 GMT
Server: Python/3.5 websockets/7.0

dann noch ein TCP-Ack des FHEM-Servers an den websocket-Server, aber dann wartet FHEM den timeout(3s) ab.... :'(

Und so sieht das im FHEM-Log aus
2020.06.01 09:32:51 3: [EE2] sol_local EE2_Ready(connection seems to be lost) retrying wsconnect for DeviceName: ws:xxxip.de:9124
2020.06.01 09:32:51 5: HttpUtils url=http://xxxip.de:9124/
2020.06.01 09:32:51 4: IP: xxxip.de -> Ipdeshosts
2020.06.01 09:32:51 5: HttpUtils request header:
GET / HTTP/1.1
Host: xxxip.de:9124
User-Agent: fhem
Accept-Encoding: gzip,deflate
Sec-WebSocket-Key: sXh1fxWrbbVHEyfLPyO77Q==
Connection: Upgrade
Sec-WebSocket-Version: 13
Upgrade: websocket

2020.06.01 09:32:54 4: [EE2] sol_local - error while connecting to Websocket: read from http://xxxip.de:9124 timed out from DevIO
2020.06.01 09:32:54 4: [EE2] sol_local - callback called

Auf was wartet httputils bzw. DevIo da noch ?!?!?!?

Wenn Du mehr brauchst, melde Dich gerne
Grüße Markus

Correction: additional new line added
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 01 Juni 2020, 11:07:50
Zitat
Auf was wartet httputils bzw. DevIo da noch ?!?!?!?
Falls Du die Daten vollstaendig kopiert hast: auf einem zweiten NL nach dem Header.
Ich fuerchte mit dieser Methode kommen wir nur muehsam weiter: gibt es eine Moeglichkeit, dass ich mich direkt mit deinem Server verbinde?

Ich habe DevIo.pm erweitert: mit verbose 5 wird jedes websocket Frame geloggt, und wss: ist equivalent zu ws: + $hash->{SSL}=1;
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 01 Juni 2020, 11:36:08
Mit TLS kannst Du es auf sol.eet.energy:9124 testen.

Was ist ein NL ?  :-[

Danke fürs logging. Ich hol mir mal die aktuelle Version...

Allerdings genügt das Logging vermutlich nicht  :'( Ich konnte verfolgen, dass der Server alle 20s einen ping sendet, womit dann mit einem pong geantwortet wird(ansonsten schließt der Server die websocket-Verbindung). Ein websocket-frame ohne Daten kommt aber nicht im Modul über die ReadFn an, oder ? Oder ist das etwas, was in DevIo rein müsste ?
Ich glaube im konkreten Fall kommt kein Ping mehr, wenn man die ersten Daten(Logindaten)) geschickt hat...

Für ein anderes Modul überlege ich mir, ob ich auch auf DevIo umbaue. Allerdings ist das ein device, das nicht regelmäßig verfügbar ist. Du schreibst ja hier u. da, dass DevIo dann eher keinen Sinn macht. Was hältst Du von einer Lösung, wo die Verfügbarkeit des devices mit einem anderen Mechanismus überwacht wird und nur für die Dauer der Verfügbarkeit eine websocket-Verbindung aufgebaut bleibt, also Aufbau, wenn verfügbar und ein close(und damit auch kein ReadyFn/ReadFn ), wenn nicht mehr verfügbar.

Grüße Markus
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 01 Juni 2020, 12:30:18
Zitat
Mit TLS kannst Du es auf sol.eet.energy:9124 testen.
Habs gemacht.
Eine websocket Verbindung wird zwar hergestellt, aber von der anderen Seite sofort geschlossen (mit OP:8 == Close), vermutlich weil das von mir gesendete "list" ohne Weiteres dem Server nicht passt.

NL steht fuer NewLine: ein HTTP Header wird mit zwei Newlines abgeschlossen, und in deinem Beitrag sieht man nur eins.
Ein Websocket Frame wird mit DevIO nie beim Modul ankommen, da das Prinzip von DevIo ist, vom Transportschicht-Eigenheiten zu abstrahieren.
Abgesehen davon wuesste ich nicht, warum Ping/etc das Modul interessieren sollte.

Zitat
Du schreibst ja hier u. da, dass DevIo dann eher keinen Sinn macht.
Das ist vermutlich falsch interpretiert, kannst Du mir diesen Zitat zeigen?
Websocket ist (im Gegensatz zu HTTP) fuer eine laenger geoeffnete Verbindung ausgelegt.
Man kann es (wie alles) missbrauchen, und ob man das mit DevIo oder ohne macht, ist mir egal.

Zitat
Was hältst Du von einer Lösung, wo die Verfügbarkeit des devices mit einem anderen Mechanismus überwacht wird und nur für die Dauer der Verfügbarkeit eine websocket-Verbindung aufgebaut bleibt,
Wenig, wenn beide Verfahren das gleiche Medium (Netzwerk) nutzen.
Wenn die andere Seite nicht da ist, dann kriegt man das auch per websocket mit: ob jetzt ping oder der TCP Connect-Versuch keine Antwort kriegt, ist  egal. Es kommt dazu, dass man fuer ping entweder spezielle Rechte (root), oder unangemessen viel Ressourcen (fork+exec) braucht.
Heisst nicht, dass ich die, die sowas programmieren, aktiv verfolge, ich aussere nur meine Meinung, wenn ich danach gefragt werde :)
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 01 Juni 2020, 12:53:31
Hi Rudi,
Zitat
Eine websocket Verbindung wird zwar hergestellt, aber von der anderen Seite sofort geschlossen (mit OP:8 == Close), vermutlich weil das von mir gesendete "list" ohne Weiteres dem Server nicht passt.
Ja, das macht er, wenn ihm was nicht passt.  ;) Wie hast Du das denn jetzt mit dem "fehlenden" 2. NL gelöst ? Geänderte  DevIo sehe ich nicht.  :-[

Zitat
Abgesehen davon wuesste ich nicht, warum Ping/etc das Modul interessieren sollte.
Das sehe ich dann, wenn es mal mit dem Modul klappt.... ;)
Zitat
Das ist vermutlich falsch interpretiert, kannst Du mir diesen Zitat zeigen?
Finde ich bestimmt nicht mehr, aber Du hast ja jetzt ausführlich aufgeklärt.

Danke&Grüße Markus
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 01 Juni 2020, 13:58:54
Hm,
mein lokales device gibt auch nur ein NL zurück.  Das war wohl Quatsch. Du meintest ja die response. :( Trotzdem selbes Problem mit meinem lokalen device.

2020.06.01 13:50:57 5: HttpUtils url=https://localIP:8002/
2020.06.01 13:50:57 4: IP: localIP -> localIP
2020.06.01 13:50:57 5: HttpUtils request header:
GET / HTTP/1.1
Host: localIP:8002
User-Agent: fhem
Accept-Encoding: gzip,deflate
Sec-WebSocket-Key: 9nXYHmyxKMPCKREAHTn2Ng==
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Version: 13

2020.06.01 13:51:00 5: [SamsungAV] Fernseher - callback after connecting to Websocket by DevIO
2020.06.01 13:51:00 2: [SamsungAV] Fernseher - error while connecting to Websocket: read from https://localIP:8002 timed out from DevIO

Edit: Das mit dem NL ist es wohl nicht. Hab nochmal in Wireshark geguckt. Die response endet mit \r\n\r\n. Ich passdie obigen Posts mal an.
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 01 Juni 2020, 20:20:33
Zitat
mein lokales device gibt auch nur ein NL zurück.
Du verwirrst mich.
Im Code-Stueck sind zwei zu sehen: einmal nach "Sec-WebSocket-Version: 13" und danach die leere Zeile.
Der Zugriff auf "sol.eet.energy:9124" klappte ohne Aenderung, der schickt schon 2 NLs.
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 01 Juni 2020, 20:44:54
Ich mich auch. Hab jetzt erst gemerkt, dass Du ja die response meintest. Ja, da kommt die 2. NL. Hatte ich nur nicht mitkopiert. :o

Aber dann sind wir so weit wie heute Morgen: Was führt zu dem timeout ? Und viel schlimmer: wieso klappt das bei Dir ? ??? Da kann man doch eigentlich nichts falsch machen.  :-[

    $hash->{DeviceName} = "ws:".$hash->{Host} . ":" . $hash->{Port}; 
#    $hash->{SSL}         = 1;  # TLS only used for remote access; set by attribute   
#    $hash->{WEBSOCKET}   = 1;  set by Dev
    DevIo_OpenDev( $hash, 0, "wsHandshake", "wsCb" );
sub wsCb ($){
    my ($hash, $error)  = @_;

    my $name  = $hash->{NAME};

    if (defined($error)) {Log3 $name, 4, "[EE2] $name - error while connecting to Websocket: $error from DevIO" };
    Log3 $name, 4, "[EE2] $name - callback called";
    return $error;
}
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 02 Juni 2020, 09:03:31
Hi Rudi,
nachdem es also nicht am NL liegt, wird für mich die Sache immer ominöser. Was mich in meinem Log so blind gemacht hatte ist, dass es überflutet wurde. Das liegt daran, dass permanent die ReadyFN aufgerufen und ein Neuaufbau versucht wird. Es ist doch richtig, dass die ReadyFn eigentlich gar nicht aufgerufen werden dürfte oder zumindest der STATE auf connected stehen müsste, oder ?

Außerdem hadere ich mit dem reopen-Flag. Ich hab jetzt noch einmal ein wenig umgebaut und bekomme folgendes Logging
2020.06.01 23:17:38 3: [EE2] sol_local defined with host: localDomain port: 9124
...Versatz von 20s ist korrekt, weil der Aufbau über einen internaltimmer 20s nach dem define gestartet wird
2020.06.01 23:17:58 4: [EE2] sol_local  Attempting to open websocket by DevIo
2020.06.01 23:17:58 3: Opening sol_local device ws:localDomain:9124
2020.06.01 23:17:58 5: HttpUtils url=http://localDomain:9124/
2020.06.01 23:17:58 4: IP: localDomain -> localIP
2020.06.01 23:17:58 5: HttpUtils request header:
GET / HTTP/1.1
Host: localDomain:9124
User-Agent: fhem
Accept-Encoding: gzip,deflate
Upgrade: websocket
Sec-WebSocket-Version: 13
Connection: Upgrade
Sec-WebSocket-Key: 7i8DGRzM9v3nc2QrBABKIw==

2020.06.01 23:18:01 1: sol_local: Can't connect to localDomain:9124: No such file or directory
2020.06.01 23:18:01 1: sol_local: Can't connect to localDomain:9124: read from http://localDomain:9124 timed out
2020.06.01 23:18:01 4: [EE2] sol_local - error while connecting to Websocket: read from http://localDomain:9124 timed out from DevIO
2020.06.01 23:18:01 3: [EE2] sol_local EE2_Ready(connection seems to be lost) retrying wsconnect for DeviceName: ws:localDomain:9124
2020.06.01 23:18:01 3: Opening sol_local device ws:localDomain:9124
2020.06.01 23:18:01 4: [EE2] sol_local - connecting to Websocket successful
2020.06.01 23:18:01 3: [EE2] sol_local EE2_Ready(connection seems to be lost) retrying wsconnect for DeviceName: ws:localDomain:9124
2020.06.01 23:18:01 4: [EE2] sol_local - connecting to Websocket successful
2020.06.01 23:18:02 3: [EE2] sol_local EE2_Ready(connection seems to be lost) retrying wsconnect for DeviceName: ws:localDomain:9124
2020.06.01 23:18:02 4: [EE2] sol_local - connecting to Websocket successful
.
.
.
bei diesem coding.
.
Initial-websocket-connect
    $hash->{helper}{wsconnect} = 0;
    Log3 $name, 4, "[EE2] $name  Attempting to open websocket by DevIo";
    $hash->{DeviceName} = "ws:".$hash->{Host} . ":" . $hash->{Port}; 
    DevIo_OpenDev( $hash, 0, "wsHandshake", "wsCb" );
.
.
ReadyFN
   Log3 $hash->{NAME}, 3, "[EE2] $hash->{NAME} EE2_Ready(connection seems to be lost) retrying wsconnect for DeviceName: $hash->{DeviceName}";
  return DevIo_OpenDev( $hash, $hash->{helper}{wsconnect}, "wsHandshake", "wsCb" )
                if($hash->{STATE} eq "disconnected");     

wsCb
    if (defined($error)) {Log3 $name, 4, "[EE2] $name - error while connecting to Websocket: $error from DevIO" }
    else {
       Log3 $name, 4, "[EE2] $name - connecting to Websocket successful";
       $hash->{helper}{wsconnect} = 1;
    }
Auf ein write habe ich komplett verzichtet, da ggfs. der Server mit einem disconnect reagiert.

Aber wieso gibt es erst diese "Can't connect" Meldung mit 3s timeout, dann der identische Aufruf von DevIo(reopen=1), der nun scheinbar erfolgreich ist, aber nicht zu einem "connected" führt bzw. die ReadyFn aufgerufen wird, wo dann erneut ein erfolgreicher ws-connect(reopen=1) erfolgt, der aber wieder in die ReadyFN läuft. Und das dann permanent.

Soll ich das nochmal genau mit Wireshark analysieren ?

Grüße Markus
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 02 Juni 2020, 11:44:02
Oh Mann, Rudi.

Und wenn man nicht mehr weiter weiß, macht man ein update u. shutdown/restart.

Und dann klappts auch. Ich spekuliere: die httputils wurde auch erneuert. Ich hatte aber immer nur DevIo aus dem SVN manuell geladen.  :-\

Ich kann Dir aber schon einmal
Zitat
Zitat
Zitat

Abgesehen davon wuesste ich nicht, warum Ping/etc das Modul interessieren sollte.

Das sehe ich dann, wenn es mal mit dem Modul klappt.... ;)
beantworten: nach 20s sendet der Server einen ping. Ohne ein pong des FHEM-client schließt er die Verbindung. FHEM schickt zwar den Pong, die Verbindung wird aber trotzdem vom Server geschlossen. (möglicherweise, weil es nicht "masked" gesendet wurde ?

Trotz richtiger Daten, löst das simple_write auch ein disconnect aus. Mit Wireshark konnte ich feststellen, dass der Unterschied darin liegt, dass wir "unmasked" senden. Hier (https://softwareengineering.stackexchange.com/questions/226343/is-masking-really-necessary-when-sending-from-websocket-client) hab ich was gefunden, dass es zwingend erforderlich wäre.

Grüße Markus
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 02 Juni 2020, 11:48:48
Zitat
Ich spekuliere: die httputils wurde auch erneuert.
Ja, die Aenderung ist fuer websocket relevant.
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 02 Juni 2020, 21:03:50
Während Du geantwortet hast, hatte ich getestet, den Post editiert... Ich wiederhol dann mal meine unschöne Feststellung als trigger für einen change im Thread,

Trotz richtiger Daten, löst das simple_write auch ein disconnect aus. Mit Wireshark konnte ich feststellen, dass der Unterschied darin liegt, dass wir "unmasked" senden. Hier (https://softwareengineering.stackexchange.com/questions/226343/is-masking-really-necessary-when-sending-from-websocket-client) hab ich was gefunden, dass es zwingend erforderlich wäre. Gar nicht gut . >:(

Grüße Markus
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 03 Juni 2020, 14:28:59
Danke fuer die Recherche. Ich habe die Begruendung gelesen: entweder waren das Anfaenger, oder sie haben was in der Begruendung nicht erwaehnt.

Wie auch immer, ich habe jetzt die DevIo Routinen so umgestellt, dass alles maskiert gesendet wird.
FHEM und echows kommt damit zurecht, sol.eet.energy ist immerhin nicht sofort beleidigt, und wartet auf mehr Daten.
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 03 Juni 2020, 19:44:08
Danke für die Implementierung. Ich hatte mit größeren Schwierigkeiten gerechnet, weil wohl auch die in Perl enthaltene "rand" nicht den Anforderungen genügen soll.(Stichwort füge ich später aus dem RFC hinzu)Nicht im RFc, sondern in CPAN steht zum in Protocol::Websocket verwendeten Modul:
Zitat
cryptographically-secure replacement for Perl's built-in rand function

Mittlerweile hatte ich auch noch weiter recherchiert: In der RFC6455 (https://tools.ietf.org/html/rfc6455#section-5.3)(Ich editier hier gleich noch den Link rein) steht auch, dass der Client IMMER maskiert senden muss. Der Server nicht. Die Begründung steht dort auch genau beschrieben.

Und funktionieren tut es leider auch nicht.  :'( Aber nachdem ich Deinen Fehler korrigiert habe, klappt es. Dass ich das noch erleben darf. 8)
Spaß beiseite. Bei der Längenberechnung ist noch etwas faul. Bei der Länge > 125 u. < 65536 muss das erste byte chr(0xFE) lauten(ich guck da auch nochmal im RFC warum).

Einen Wunsch habe ich noch: Nachdem ich gestern überfliegend im RFCxxx geblättert habe, ist mir auch untergekommen, dass bei einem close immer ein Statuscode (https://tools.ietf.org/html/rfc6455#section-7.4.1) mitgegeben wird. Das Log zeigt auch die payload von 2 bytes an
2020.06.03 18:39:19 5: Websocket msg: OP:8 LEN:2 MASK:0 FIN:1Wireshark zeigt den sogar anStatus code: Invalid frame payload data (1007) Wenn wir den Statuscode noch mitprotokollieren könnten ?

Danke&Grüße
Markus

Edit: das pong geht auch noch in die Hose. Nach 20s Nichtstun closed der Server die Verbindung wg. des "unzulässigen" pongs.

Edit2:
Zitat
frame-payload-length    = ( %x00-7D )
                            / ( %x7E frame-payload-length-16 )
                            / ( %x7F frame-payload-length-63 )
                            ; 7, 7+16, or 7+64 bits in length,
                            ; respectively
also doch bei Maskierung:
0x80-FD  f. < 125    (richtig implementiert)
0xFE       f. > 125 u. < 65536 (noch falsch)
0xFF       f. > 65536 (noch falsch)
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 03 Juni 2020, 20:14:44
Zitat
In der RFCxxx(Ich editier hier gleich noch den Link rein)
Der Link zu rfc6455 steht in DevIo.pm/DevIo_DecodeWS() als Kommentar.
Meine Bemerkung von vorhin bezog sich auf deren Begruendung fuer die Notwendigkeit der Mask bei Clients.

Zitat
Bei der Länge > 125 u. < 65536 muss das erste byte chr(0xFE) lauten(ich guck da auch nochmal im RFC warum).
Brauchst Du nicht, liegt daran, dass mein Kopfrechnen mich bei 0x7e|0x80 im Stich gelassen hat.
Danke fuer den Hinweis, habs korrigiert.

Zitat
Wenn wir den Statuscode noch mitprotokollieren könnten ?
Habs gemacht, jetzt sagt sol.eet.energy, wenn ich ihm "list" schicke:
2020.06.03 20:07:01.300 5: Websocket msg: OP:8 LEN:35 MASK:0 FIN:1
2020.06.03 20:07:01.300 5: Websocket close, reason: 1000 (normal) Error: Please provide valid JSON.
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 03 Juni 2020, 20:21:27
Zitat
Edit: das pong geht auch noch in die Hose. Nach 20s Nichtstun closed der Server die Verbindung wg. des "unzulässigen" pongs.
wsecho hat nix gegen meinen pongs. Was passt denn deinem Server nicht?
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 03 Juni 2020, 20:34:33
Mann bist Du fix....

Zitat
A Pong frame sent in response to a Ping frame must have identical
   "Application data" as found in the message body of the Ping frame
   being replied to.
steige noch nicht ganz hinter Dein .WSBUF  :-[
Ich gucke Wireshark....
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 03 Juni 2020, 20:50:37
Zitat
steige noch nicht ganz hinter Dein .WSBUF  :-[
Das sollst Du auch nicht.

Habe DevIo_Ping() hinzugefuegt (tut nur bei websocket was), und ich gebe die Ping/Pong Application-Data jetzt auch aus.
Pong hat auch vorher Application Data brav zurueckgeschickt.
Gibt es einen Hinweis, dass Ping Application Data enthaelt (siehe LEN: bei OP:9)?
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 03 Juni 2020, 21:00:40
Wireshark sagt. 1. ping -> korrekter pong; 2. ping -> nichts passiert; nach 20s dann das close m. 1011(internal server  :-\)

FHEM.WSBUS: connected:empty, 1. ping:irgendwas, wird nach dem pong nicht gelöscht

Kannst Du damit was anfangen ? Oder soll ich was in Devio loggen, um dem Fehlerchen auf die Schliche zu kommen ?

edit:Und schon wieder warst Du zu schnell für mich. Hole mir die aktuelle DevIo........
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 03 Juni 2020, 21:18:53
2020.06.03 21:09:42 3: [EE2] sol_local defined with host: Domain port: 9124
2020.06.03 21:10:02 4: [EE2] sol_local  Attempting to open websocket by DevIo
2020.06.03 21:10:02 3: Opening sol_local device ws:Domain:9124
2020.06.03 21:10:02 5: HttpUtils url=http://Domain:9124/
2020.06.03 21:10:02 4: [EE2] sol_local  what happens after opendevio ?
2020.06.03 21:10:02 4: IP: Domain -> IPofDomain
2020.06.03 21:10:02 5: HttpUtils request header:
GET / HTTP/1.1
Host: Domain:9124
User-Agent: fhem
Accept-Encoding: gzip,deflate
Sec-WebSocket-Key: AhWXoKfADXSTAplbMuBq6g==
Upgrade: websocket
Sec-WebSocket-Version: 13
Connection: Upgrade

2020.06.03 21:10:02 4: http://Domain:9124/: HTTP response code 101
2020.06.03 21:10:02 5: HttpUtils http://Domain:9124/: Got data, length: 0
2020.06.03 21:10:02 5: HttpUtils response header:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: A5/ORmKJaBb+JjARcWiGFZQ/D9E=
Date: Wed, 03 Jun 2020 19:10:02 GMT
Server: Python/3.5 websockets/7.0
2020.06.03 21:10:02 5: [EE2] sol_local InitFn called from websocket DevIo
2020.06.03 21:10:02 3: sol_local device opened
2020.06.03 21:10:02 4: [EE2] sol_local - connecting to Websocket successful
2020.06.03 21:10:22 5: Websocket msg: OP:9 LEN:4 MASK:0 FIN:1
2020.06.03 21:10:22 5: Websocket ping: ‡…Oë
2020.06.03 21:10:22 4: [EE2] sol_local received websocket data: ><
2020.06.03 21:10:42 4: [EE2] sol_local received websocket data: ><
2020.06.03 21:11:02 4: [EE2] sol_local received websocket data: ><
2020.06.03 21:11:02 1: ws:Domain:9124 disconnected, waiting to reappear (sol_local)
2020.06.03 21:11:02 4: [EE2] sol_local websocket-connection seems to be closed
Ich seh da jetzt nix. Nach 20s der 1.ping(der pong erfolgt wohl korrekt). Nach weiteren 20s wird der ping nicht erkannt, was weitere 20s später zum close führt.
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 03 Juni 2020, 21:32:14
Da war noch eine Zeile vor dem Umbau uebrig, hat Aerger verursacht, falls ping Daten enthaelt.
Sollte jetzt behoben sein.
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 03 Juni 2020, 22:41:28
Prima, jetzt klappts auch mit dem pong.

Und mein Modul liefert zyklisch readings.  8)

 :-* :-* :-*

Die Tage knöpfe ich mir dann das SamsungAV vor...
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 03 Juni 2020, 23:10:51
So ganz konnte ich doch noch nicht abschalten.  ::)

Im SamsungAV gebe ich beim websocket-upgrade-request einen Pfad und Parameter im header mit. Wie mach ich das denn bei DevIo_OpenDev()-websocket ?  :-\
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 04 Juni 2020, 14:23:12
Habe DevIo erweitert:
- Pfad wird ab sofort weitergegeben:
  $hash->{DeviceName} = "wss:echo.websocket.org:443/hello";- header kann man uebergeben:
  $hash->{header} = { "User-Agent", "FHEM!" };
Titel: Antw:WebSocket via DevIO?
Beitrag von: Dr. Boris Neubert am 04 Juni 2020, 21:41:32
Schalte mich mal ein mit Verweis auf https://forum.fhem.de/index.php?topic=111718.new#new (https://forum.fhem.de/index.php?topic=111718.new#new)

Die Änderung an HttpUtils.pm in Revision 22027 vom 25.05.2020 führt dazu, dass Kalender von Nextcloud nicht mehr abgerufen werden können. Dreht man HttpUtils.pm auf Revision 21529 zurück, ist alles wieder gut (bei sonst aktuellem FHEM).

Soll ich auf einen Patch warten, der sich aus diesem Thema hier wohl noch ergeben wird, oder soll ich mit ins Debugging einsteigen?

Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 04 Juni 2020, 22:49:20
Websocket funktioniert mit der vorgeschlagenen Änderung  (https://forum.fhem.de/index.php/topic,111718.msg1060891.html#msg1060891)noch..

@Rudi: Danke für Deine Erweiterungen. Ich nimmersatt hab dann noch ein weiteres Problem. Der TLS-Aufbau macht Probleme. Das hatte ich vorher durch den SSL-Parameter SSL_verify_mode=>0 umgangen. Da wir uns ja im lokalen Netz bewegen, fand ich das iO. Würde das automatisch berücksichtigt, wenn es ein attr SSLargs im device gäbe ?  :-\ Hatten wir das nicht bei irgendeinem Modul ? Ich finds aber nicht, sonst würde ich es mal ausprobieren...
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 04 Juni 2020, 23:51:47
@Boris: ich wuerde gerne ein Response-Header sehen.
@KölnSolar: per Voreinstellung ist SSL_verify_mode 0. DevIo.pm reicht aber ab sofort $hash->{sslargs} weiter, damit kann man es ueberschreiben und weitere SSL Parameter setzen.
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 05 Juni 2020, 09:57:34
Bin zwar nicht Boris, aber hab dann versucht zu unterstützen. Im Header findet sich ein Connection: Upgrade, Keep-Alive (https://forum.fhem.de/index.php/topic,111718.msg1060970.html#msg1060970)
Also meinen Vorschlag
Zitat
Scheinbar ist im Fehlerfall Connection:\s*Upgrade im Header enthalten. Für den Zweck der Änderung(für DevIo mit websocket), müsste stattdessen Upgrade:\s*websocket in Zeile 698 geändert werden und den Fehler verhindern.
umsetzen ? :-\
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 05 Juni 2020, 10:43:07
Danke fuer den Link, habe HttpUtils.pm geaendert.
Ich wollte dein Vorschlag nicht ignorieren, sondern vorher den Problemfall selbst verstehen.
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 05 Juni 2020, 12:39:11
Mit dem SamsungAV komme ich noch nicht so richtig weiter. Tw. liegt es an mir  ::), das gucke ich mir heute Abend in Ruhe mal über Wireshark an. Mir fehlt aber auch eine Info, die der TV im Rahmen des websocket-Aufbaus schickt. Nach der websocket-Bestätigungsresponse schickt er sofort eine weitere response, die das wichtige UserToken enthält. Das wird mir aber nicht über die ReadFn angeboten. Ich spekuliere, dass das möglicherweise im response-frame mitgeschickt wird. Zum Verständnis, was ich früher gemacht habe

Zitat
$socket = IO::Socket::SSL->new(PeerAddr=>"$dev:$port", SSL_verify_mode=>0,Timeout=>2, Blocking=>1, ReuseAddr=>1);
.
.
wenn erfolgreich, Aufbau des Headers mit zwischengespeichertem UserToken(ohne lehnt der TV die Verbindung ab)
.
.
syswrite $socket, $webclient_header;
.
.
sysread $socket, my $buf, 10240;
(bei Erfolg, wird die "first" response eingelesen)
.
.
.
sysread $socket, $buf, 10240;
(hier bekam ich mit der "second" response per JSON das UserToken
.
.
websocket Aufbau erfolgreich u. es kann der Befehl an den TV gesendet werden

im Log sah das dann so aus
Zitat
2020.06.05 11:37:32 5: [SamsungAV] Fernseher send to TV: GET /api/v2/channels/samsung.remote.control?name=unwichtig==&token=UserToken HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: localIP:8002
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13


2020.06.05 11:37:32 5: [SamsungAV] Fernseher first websocket response: HTTP/1.1 101 Switching Protocols
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=


2020.06.05 11:37:32 5: [SamsungAV] Fernseher Statusbytes of second websocket response: 817e0115
2020.06.05 11:37:32 5: [SamsungAV] Fernseher data of second websocket response: {"data":{"clients":[{"attributes":{"name":"unwichtig","token":"UserToken"},"..."}

2020.06.05 11:37:32 4: [SamsungAV] Fernseher sending 1
2020.06.05 11:37:32 5: [SamsungAV] Fernseher send payload: {"method":"ms.remote.control","params":{"TypeOfRemote":"SendRemoteKey","DataOfCmd":"KEY_1","Option":"false","Cmd":"Click"}}
Wobei das damals wider besseren Wissens "Statusbytes of second websocket response" genannte, nach heutigem Kenntnisstand die framing bytes der response sind, also FIN=0x01,Opcode=0x01,nicht maskiert,Länge > 125, 16bit-payloadlength. Aber dann hätte ich die doch per ReadFn angeboten bekommen müssen ?
Ne Idee, wo es hängt ?

Grüße Markus
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 05 Juni 2020, 13:46:21
Zitat
Aber dann hätte ich die doch per ReadFn angeboten bekommen müssen ?
Ne Idee, wo es hängt ?
Ja.
Nein. :/
Titel: Antw:WebSocket via DevIO?
Beitrag von: Dr. Boris Neubert am 05 Juni 2020, 13:47:31
Danke fuer den Link, habe HttpUtils.pm geaendert.
Ich wollte dein Vorschlag nicht ignorieren, sondern vorher den Problemfall selbst verstehen.

Gerade wurde bestätigt, dass das Calendar-Modul nun wieder auf Nextcloud-Kalender zugreifen kann.

Danke für die Anpassung, Rudi.

Ich melde mich aus diesem Thema ab.

Viele Grüße
Boris
Titel: Antw:WebSocket via DevIO?
Beitrag von: HomeAuto_User am 05 Juni 2020, 22:37:22
@Rudi  8)
Danke fuer den Link, habe HttpUtils.pm geaendert.
Ich wollte dein Vorschlag nicht ignorieren, sondern vorher den Problemfall selbst verstehen.

Hallo,
seit der Änderung habe ich ein sehr eigenartiges Verhalten.

Meine SIGNALduino Devices welche bis gestern mit
/dev/serial/by-path/platform-3f980000.usb-usb-0:1.1.3:1.0-port0@57600definiert waren bringen seit dem Update heute einen FHEM Crash hervor.

Wenn ich diese nun auf die DEF
/dev/ttyUSB0@57600ändere geht dies vorübergehend aber 2 Devices bei mir haben die selbe ID. (daher DEF bei path)

 >:( LANGE suchte ich die URSACHE und ich habe nun auch im SVN gesehen die HttpUtils.pm wurde geändert und seit dem heutigen Update ist das Verhalten.
Bis gestern ging es.

Nun versuchte ich die DEF auf
/dev/serial/by-path/platform-3f980000.usb-usb-0:1.1.3:1.0-port0@57600zurück zu ändern aber ich erhalte nun einen RETURN aus dem HttpUtils.pm Modul  :o :'( :'(

    return "$hash->{displayurl}: malformed or unsupported URL";
Kurzum
  if($hash->{url} !~ /
      ^(http|https):\/\/                # $1: proto
       (([^:\/]+):([^:\/]+)@)?          # $2: auth, $3:user, $4:password
       ([^:\/]+|\[[0-9a-f:]+\])         # $5: host or IPv6 address
       (:\d+)?                          # $6: port
       (\/.*)$                          # $7: path
    /xi) {
    return "$hash->{displayurl}: malformed or unsupported URL";
  }

akzeptiert nicht die Eingabe
/dev/serial/by-path/platform-3f980000.usb-usb-0:1.1.3:1.0-port0@57600.

Ich erbitte einen Blick darüber.

MfG

EDIT: Sorry, fand auch nun https://forum.fhem.de/index.php/topic,111832.msg1061157.html#msg1061157
Titel: Antw:WebSocket via DevIO?
Beitrag von: CoolTux am 05 Juni 2020, 22:46:59
@Rudi  8)
Hallo,
seit der Änderung habe ich ein sehr eigenartiges Verhalten.

Meine SIGNALduino Devices welche bis gestern mit
/dev/serial/by-path/platform-3f980000.usb-usb-0:1.1.3:1.0-port0@57600definiert waren bringen seit dem Update heute einen FHEM Crash hervor.

Wenn ich diese nun auf die DEF
/dev/ttyUSB0@57600ändere geht dies vorübergehend aber 2 Devices bei mir haben die selbe ID. (daher DEF bei path)

 >:( LANGE suchte ich die URSACHE und ich habe nun auch im SVN gesehen die HttpUtils.pm wurde geändert und seit dem heutigen Update ist das Verhalten.
Bis gestern ging es.

Nun versuchte ich die DEF auf
/dev/serial/by-path/platform-3f980000.usb-usb-0:1.1.3:1.0-port0@57600zurück zu ändern aber ich erhalte nun einen RETURN aus dem HttpUtils.pm Modul  :o :'( :'(

    return "$hash->{displayurl}: malformed or unsupported URL";
Kurzum
  if($hash->{url} !~ /
      ^(http|https):\/\/                # $1: proto
       (([^:\/]+):([^:\/]+)@)?          # $2: auth, $3:user, $4:password
       ([^:\/]+|\[[0-9a-f:]+\])         # $5: host or IPv6 address
       (:\d+)?                          # $6: port
       (\/.*)$                          # $7: path
    /xi) {
    return "$hash->{displayurl}: malformed or unsupported URL";
  }

akzeptiert nicht die Eingabe
/dev/serial/by-path/platform-3f980000.usb-usb-0:1.1.3:1.0-port0@57600.

Ich erbitte einen Blick darüber.

MfG

Das sollte mit der Version von DevIO von heute Mittag Rum behoben sein. Teste mal aus dem SVN

https://forum.fhem.de/index.php/topic,111832.0.html
Titel: Antw:WebSocket via DevIO?
Beitrag von: HomeAuto_User am 05 Juni 2020, 22:56:59
Das sollte mit der Version von DevIO von heute Mittag Rum behoben sein. Teste mal aus dem SVN

https://forum.fhem.de/index.php/topic,111832.0.html

Danke für den Hinweis.
Nach dem manuellem laden aus dem SVN geht es erstmal wieder. Diese Datei kommt dann mit Sicherheit erst morgen mit dem SVN update.
Titel: Antw:WebSocket via DevIO?
Beitrag von: KernSani am 08 Juni 2020, 00:23:40
Hallo Rudi & Markus,
hatte leider vergangene Woche wenig Zeit mich dem Thema zu widmen, aber ihr habt ganze Arbeit geleistet. Funktioniert bei mir jetzt problemlos :-) Vielen Dank und *Daumen hoch*!
Einen kleinen Schönheitsfehler habe ich noch. Die Regex in folgender Zeile:
elsif($dev =~ m,^(ws:|wss:)?([^/:]+):([0-9]+)(.*?)$,) {# TCP or websocket
verlangt zwingend, dass ein port mitgegeben wird. In meinem Fall kommt die Websocket-URL aus einer vorhergehenden Abfrage (ohne Port), was dazu führt, dass ich die URL erst zerlegen und wieder zusammenbauen muss (damit kann ich Leben, aber schöner wär's, wenn der Port aus dem Protokoll abgeleitet würde, wenn nicht mitgegeben).
Protokoll ist bei mir "wss". DevIO macht daraus "https" -> funktioniert trotzdem, ich bin mir aber nicht sicher, ob das in allen Fällen so ist, aber so lange niemand meckert ;-)
Grüße,
Oli
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 08 Juni 2020, 08:45:06
Standard-Ports sind ja meines Wissens wie bei http/https 80/443.

Mein Fehler war, dass ich in einem bestehenden Modul einen kompletten URL(also DeviceName mit  wss://....) hatte und daher das Ganze ziemlich daneben lief.
Ob man die beiden slash noch mit reinnehmen sollte ?  :-\ Zumindest ich schreib die immer aus Gewohnheit. Und im Fehlerfall guckt man auf alles Mögliche, aber dem Kopf fallen die "überzähligen" // nicht auf.

Ansonsten klappt das bei mir nun auch mit dem SamsungAV. Ich habe einen gefühlten Performance-Gewinn.  ;) (Verbindung ist nun dauerhaft offen u. wird nicht mehr bei jedem Modul-Aufruf neu aufgebaut)
Ich kämpfe noch mit dem Problem, dass der TV beim ausschalten kein close schickt. DevIo "merkt" also nicht, dass die Verbindung flöten gegangen ist(das selbe passiert natürlich, wenn hart per Funksteckdose abgeschaltet wird). Da alle 6s ein Ping vom TV kommt, hab ich mir einen workaround über einen internaltimer in der ReadFn geschrieben. Der setzt ein beliebiges write ab u. dann reagiert DevIo. Den internaltimer setze ich zeitlich so, dass er in der Regel(online) nicht ausgeführt, sondern über die ReadFN vorher gelöscht u. erneuert wird.

Gibt es dazu eine bessere Lösung, wenn das System/DevIo selber nicht merkt, dass die Verbindung geschlossen wurde ? isOpen funktioniert ja dann auch nicht als Prüfung.

Grüße Markus
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 08 Juni 2020, 09:41:10
Es gibt DevIO_Ping, die prueft aber nicht, ob die andere Seite rechtzeitig Pong geliefert hat.
Bei einem ausgeschalteten Geraet muesste aber das OS dadurch merken, dass die Verbindung zu ist, und das per ReadFn/DevIo_SimpleRead auch an FHEM mitteilen.
=> Ein regelmaessiges, aus dem Modul aufgerufenes DevIO_Ping ist vmtl. eine bessere Loesung.
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 08 Juni 2020, 10:05:55
Danke, probier ich aus....
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 19 Juni 2020, 09:32:18
Hi Rudi,
ich kämpfe immer noch mit den websockets by DevIo.

Seit Tagen versuche ich zu verstehen, was ich beim Open falsch machen könnte. Da ich es auch noch an verschiedenen Stellen des Moduls ausführe, war es nicht leicht bei einem geht/geht_nicht Verhalten dem Ganzen auf die Spur zu kommen. Nun habe ich aber endlich herausgefunden, dass ein "seltsamer" ReadFn-Aufruf zum disconnect führt. Warum auch immer wird die ReadFn aufgerufen. Das DevIoSimpleRead führt dann zum disconnect, weil gar keine Daten bereitstehen. Mit ein paar Zusatzloggings das Verhalten, welches im 2. Logauszug dadurch vermieden wird, dass ich einfach den ersten Aufruf der ReadFn OHNE  DevIoSimpleRead  ausführe.

Fehlverhalten:
2020.06.19 08:57:17 4: [EE2] sol  Attempting to open websocket by DevIo
2020.06.19 08:57:17 3: Opening sol device ws:wsServer:wsPort
2020.06.19 08:57:17 5: HttpUtils url=http://wsServer:wsPort/
2020.06.19 08:57:17 4: IP: wsServer -> IPwsServer
2020.06.19 08:57:17 5: HttpUtils request header:
GET / HTTP/1.1
Host: wsServer:wsPort
User-Agent: fhem
Accept-Encoding: gzip,deflate
Connection: Upgrade
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: /u+SyWye/hh3qEBt8GNb8A==
Upgrade: websocket

2020.06.19 08:57:17 4: http://wsServer:wsPort/: HTTP response code 101
2020.06.19 08:57:17 5: HttpUtils http://wsServer:wsPort/: Got data, length: 0
2020.06.19 08:57:17 5: HttpUtils response header:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: Mx0apO9tUi3QpxSZXUgeBL6RNBM=
Date: Fri, 19 Jun 2020 06:57:17 GMT
Server: Python/3.5 websockets/7.0
2020.06.19 08:57:17 4: [EE2] sol wsInitFn called by DevIo. Try to login
2020.06.19 08:57:17 3: sol device opened
2020.06.19 08:57:17 5: [EE2] sol - wsCallbackFn called without error by DevIo
2020.06.19 08:57:17 4: [EE2] sol ReadFn called; maybe too early ? First Read Flag: 1
2020.06.19 08:57:17 1: [DevIo] sol: empty read buffer after first read ? SimpleReadWithTimeout called
2020.06.19 08:57:17 1: [DevIo] sol: disconnected because of empty read buffer
2020.06.19 08:57:17 1: ws:wsServer:wsPort disconnected, waiting to reappear (sol)
2020.06.19 08:57:17 4: [EE2] sol connection seems to be closed. OpenDev for DeviceName: ws:wsServer:wsPort
2020.06.19 08:57:17 5: [EE2] sol - wsCallbackFn called without error by DevIo

Ignoriere ich den 1. Aufruf der ReadFn funktioniert es bestens. Die erste Aktion ist dann nach 20s ein Ping des Servers
2020.06.19 09:01:03 4: [EE2] sol  Attempting to open websocket by DevIo
2020.06.19 09:01:03 3: Opening sol device ws:wsServer:wsPort
2020.06.19 09:01:03 5: HttpUtils url=http://wsServer:wsPort/
2020.06.19 09:01:03 4: IP: wsServer:wsPort -> IPwsServer
2020.06.19 09:01:03 5: HttpUtils request header:
GET / HTTP/1.1
Host: wsServer:wsPort
User-Agent: fhem
Accept-Encoding: gzip,deflate
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: zdZLA7J4sTs+aOsOmj7COQ==
Connection: Upgrade
Upgrade: websocket

2020.06.19 09:01:03 4: http://wsServer:wsPort/: HTTP response code 101
2020.06.19 09:01:03 5: HttpUtils http://wsServer:wsPort/: Got data, length: 0
2020.06.19 09:01:03 5: HttpUtils response header:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: IILT5oOQKLm8DyRhsDStpMgP+wo=
Date: Fri, 19 Jun 2020 07:01:03 GMT
Server: Python/3.5 websockets/7.0
2020.06.19 09:01:03 4: [EE2] sol wsInitFn called by DevIo. Try to login
2020.06.19 09:01:03 3: sol device opened
2020.06.19 09:01:03 5: [EE2] sol - wsCallbackFn called without error by DevIo
2020.06.19 09:01:03 4: [EE2] sol ReadFn called; maybe too early ? First Read Flag: 1
2020.06.19 09:01:23 4: [EE2] sol ReadFn called; maybe too early ? First Read Flag: 0
2020.06.19 09:01:23 5: Websocket msg: OP:9 LEN:4 MASK:0 FIN:1
2020.06.19 09:01:23 5: Websocket ping: »;8X
2020.06.19 09:01:23 4: [EE2] sol received websocket data: ><

Läuft da noch was schief, dass die ReadFn "fälschlicherweise" aufgerufen wird ? Und wie gesagt, manchmal klappt der Verbindungsaufbau auch. Allerdings konnte ich das mit dem aktuellen Modulstand nicht reproduzieren.

Danke&Grüße
Markus
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 19 Juni 2020, 09:42:51
Ich fuerchte ich kann (trotz deinen fantasiereichen Debug-Texte) nichts dazu sagen, ohne es selbst testen zu koennen.
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 19 Juni 2020, 10:33:01
;D ;D ;D
Das ist die, die Du auch damals schon getestet hattest. Da ich ja gar keine Daten gesendet hatte, liegt das Problem entweder im websocket-Aufbau oder einem möglicherweise sofort vom Server folgenden Ping.
Mit TLS kannst Du es auf sol.eet.energy:9124 testen.
Danke vorab
Markus
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 19 Juni 2020, 18:19:59
Zitat
Mit TLS kannst Du es auf sol.eet.energy:9124 testen.
Ich wuesste nicht wie. Wenn ich was sende, kriege ich eine Fehlermeldung (dass es kein JSON ist, oder dass ich per JSON Unsinn schicke), und wenn ich nichts sende, kriege ich alle 20 Sekunden ein ping request (was FHEM brav bantwortet), und meine Pings werden von sol.eet beantwortet. Sonst passiert: nix.
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 19 Juni 2020, 18:49:38
Genau so.  ;) Ich hab ja das Problem, dass nach dem erfolgreichen Verbindungsaufbau die ReadFn aufgerufen wird. Das dortige SimpleRead führt dann zum disconnect, weil keine Daten gelesen werden. Zu einem SimpleWrite für einen Login..... komme ich ja schon gar nicht.

Die InitFn u. CallbackFn, die ich dem Open-Call mitgebe machen außer logging nichts.

Hast Du innerhalb einer FHEM-Instanz mit select/ready getestet ?

Ich probiere es nochmal. Nicht, dass das gerade wieder ohne überlesen des ersten ReadFn-Aufrufs funktioniert. Wenn nicht stell ich mal ein reduziertes Modul ein, dass die Symptome liefert.
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 19 Juni 2020, 20:09:04
Ich habe mit folgendem 98_wstest.pm getestet:
use strict;
use strict;
use warnings;
use DevIo;
sub wstest_ping($);
sub wstest_connect($);

sub
wstest_Initialize($)
{
  my ($hash) = @_;
  $hash->{DefFn}     = "wstest_Define";
  $hash->{ReadFn}    = "wstest_ReadFn";
  $hash->{ReadyFn}   = "wstest_connect";
}

sub
wstest_Define($$)
{
  my ($hash, $def) = @_;
  my @a = split(" ", $def);
  $hash->{DeviceName} = $a[2];
  wstest_connect($hash);
}

sub
wstest_ping($)
{
  my ($hash) = @_;
  return if(!$hash->{WEBSOCKET});
  DevIo_Ping($hash, "Hello");
  InternalTimer(time()+10, \&wstest_ping, $hash);
}

sub
wstest_ReadFn($)
{
  my ($hash) = @_;
  my $buf = DevIo_SimpleRead($hash);
  return if(!defined($buf)); # Disconnected, dont close, wait for reconnect
  Log 1, "GOT via websocket: >$buf<";
}

sub
wstest_connect($)
{
  my ($hash) = @_;
  my $disco = (ReadingsVal($hash->{NAME}, "state", "") eq "disconnected");
  DevIo_OpenDev($hash, $disco, undef, sub(){
    return if(!$hash->{WEBSOCKET});
    DevIo_SimpleWrite($hash, 'list', 2);
    wstest_ping($hash);
  });
}

1;


Aufgerufen habe ich es mit
define ws wstest wss:sol.eet.energy:9124
attr ws verbose 5
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 19 Juni 2020, 20:09:54
So hier der Minimalcode##############################################################################
#
# 70_EE3.pm
#
# a module to request data from a EET-solmate-device
#
# written 2020 by KoelnSolar
#
# Version = 0.1
#
##############################################################################

package main;
use strict;
use warnings;

sub EE3_Initialize($)
{
  my ($hash) = @_;
  $hash->{DefFn}    = "EE3_Define";
  $hash->{UndefFn}  = "EE3_Undefine";
  $hash->{ReadFn}   = "EE3_Read"; 
  $hash->{ReadyFn}  = "EE3_Ready";
}

sub EE3_Define($$)
{
  my ($hash, $def) = @_;
  my @args = split("[ \t]+", $def);

  if (int(@args) != 4)
  {
    return "[EE3] Define: faulty number of arguments. Usage:\n" .
         "define <name> EE3 <host> <port>";
  }

  $hash->{Host} = $args[2];
  $hash->{Port} = $args[3];

  if ( $hash->{Port} ne "9124" ){
  return "[EE3] Port is not supported";
  }

  DevIo_CloseDev( $hash) if (defined($hash->{FD}));

 EE3_Init($hash);

  return undef;
}

sub EE3_Undefine($$)
{
  my ($hash,$arg) = @_;
  DevIo_CloseDev( $hash) ;
  return undef;
}

sub EE3_Init($)
{
    my ($hash) = @_;

    return if ( DevIo_IsOpen($hash) );

    $hash->{DeviceName} = "wss:".$hash->{Host} . ":" . $hash->{Port};

   DevIo_OpenDev( $hash, 0, "wsInit", "wsCb" );

}

sub EE3_Ready($)
{
  my ($hash) = @_;

  DevIo_OpenDev( $hash, $hash->{helper}{wsconnect}, "wsInit", "wsCb" );

  return;
}

sub EE3_Read($)
{
  my ($hash) = @_;
  my $name = $hash->{NAME};

#if ($hash->{First_Read} == 1) {
#$hash->{First_Read} = 0;
#return;
#}
  my $buf = DevIo_SimpleRead($hash);
  return "" if ( !defined($buf) );

    Log3 $name, 4, "[EE3] $name received websocket data: >$buf<";
  return;
}

sub wsInit ($){
    my ($hash)     = @_;

$hash->{First_Read} = 1;

    return undef;

}

sub wsCb ($){
    my ($hash, $error)  = @_;

    return;
}


1;

=pod
=item summary device to communicate with an Samsung Television
=begin html

<a name="EE3"></a>

<h3>EE3</h3>
<ul><p>
This module supports EET solmate devices .<br>

</p>
 <b>Define</b><br>
  <code>define &lt;name&gt; EE3 &lt;host&gt; &lt;port&gt;</code><br>
  <p>
 use port 9124<br>                         


  Example:<br>
  define Television EE3 192.168.178.20 9124 <br>

  </p>
 <b>Set</b><br>
  - no set commands supported -

   <b>Get</b><br>
   <ul>N/A</ul><br>
  <br>
   <b>Attributes</b><br>
    <ul>
<li>SSL:  set to 1 supports secure connections</li>
  <br>
</ul>
  </ul>


</ul>
   
=end html
=cut


ohne überlesen des 1. Read
2020.06.19 19:57:38 3: Opening test device wss:sol.eet.energy:9124
2020.06.19 19:57:39 3: test device opened
2020.06.19 19:57:39 1: wss:sol.eet.energy:9124 disconnected, waiting to reappear (test)
kommentiert(also 1. ReadFn-Aufruf ignorieren):
2020.06.19 20:05:29 3: Opening test device wss:sol.eet.energy:9124
2020.06.19 20:05:29 3: test device opened
2020.06.19 20:05:49 5: Websocket msg: OP:9 LEN:4 MASK:0 FIN:1
2020.06.19 20:05:49 5: Websocket ping: \¦ÑN
2020.06.19 20:05:49 4: [EE3] test received websocket data: ><
.
.

Siehst Du etwas unsinniges als Ursache in dem Code ?

Edit: da haben wir gerade gleichzeitig gepostet. Ich vergleiche Deinen Code.....
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 19 Juni 2020, 20:31:46
Mit deinem Code sehe ich:
2020.06.19 20:28:53 3: ee3 device opened
2020.06.19 20:29:13 5: Websocket msg: OP:9 LEN:4 MASK:0 FIN:1
2020.06.19 20:29:13 5: Websocket ping: ©¼^}
2020.06.19 20:29:13 4: [EE3] ee3 received websocket data: ><
2020.06.19 20:29:33 5: Websocket msg: OP:9 LEN:4 MASK:0 FIN:1
2020.06.19 20:29:33 5: Websocket ping: jë
2020.06.19 20:29:33 4: [EE3] ee3 received websocket data: ><
was normal ist.
Leere Strings musst man ignorieren, da DevIo bei Kontrolpaketen wie Ping die Daten komplett verdaut.


Falls DevIo_SimpleRead undefined zurueckliefert, dann ist Zeit die Verbindung zu schliessen, das muesste man in deinem Modul aendern.
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 19 Juni 2020, 21:12:52
Oh Rudi....
Du hast mir die Augen geöffnet. Anfängerfehler.  :-[ :-[ :-[ Dieses Perl killt mich noch. :(

Am Ablauf des Codes muss ich nichts ändern(denke ich), das passt schon. Hab meinen Fehler gerade korrigiert und funktioniert. Es waren die Benennungen der subs für die InitFn u. CallbackFn.  :o Ich vermute, dass Du als Profi das vermeidest, indem Du gerne die Subs im "laufenden" coding definierst. Ich find das nur immer wieder, weil auch anders gewohnt, fürchterlich zum lesen.

Vielen, vielen lieben Dank.
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 20 Juni 2020, 21:50:30
Hi Rudi,
erst einmal nur zur Info: das war es doch nicht.  :'( Wie ich schon sagte: geht/geht_nicht  :'(

Es muss irgendwie mit etwas gepuffertem zusammenhängen, denn wenn ich das initiale open beim define oder nach einem enable_device(also nach vorherigem disable) mache, klappt es. Da aber die Verbindung immer mal nach ein paar Stunden abbricht(ohne, dass FHEM es merkt  :(), habe ich ein reopen eingebaut. Nix besonderes, ein DevIo_Close und dann ein open hinterher, aber da tritt das Symptom dann auf.

Ich such mal weiter.....

Grüße Markus
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 20 Juni 2020, 22:31:56
Der Client kann (wie in meinem Beispiel) auch ein regelmaessiges Ping absenden, damit muesste ein Verbindungsabbruch auffallen. Wenn das nicht reicht, koennten wir die Antwort per Timer ueberwachen.
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 20 Juni 2020, 23:13:39
Zitat
Der Client kann (wie in meinem Beispiel) auch ein regelmaessiges Ping absenden
Ich schreibe(get data) bereits mit einem 60s-timer. Nur bekomme ich irgendwann keine Antwort mehr.
Zitat
Wenn das nicht reicht, koennten wir die Antwort per Timer ueberwachen.
Genau das mache ich(bzw. ähnlich).

Das reopen-Flag dürfte keine Rolle spielen, oder ? :-\ Ich mache ja einen close der abgebrochenen Verbindung und das (re-)open dann mit reopenflag=0. Und dass ich eine InitFn(im Gegensatz zu Deinem Bsp.) im open übergebe, doch sicherlich auch nicht.
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 22 Juni 2020, 17:49:59
Hi Rudi,
ich glaube(mal wieder  ::)) ich bin dem Fehler näher auf die Spur gekommen. Ich habe mir mal %readyfnlist zur Brust genommen. Und da sah ich zufällig ZWEI Einträge mit unterschiedlichen keys
2020.06.22 16:09:05 3: [EE2] - readyFn-entry - devicename: sol, DeviceName: ws:localDomain.de:9124, Key: sol.localDomain.de:9124
2020.06.22 16:09:05 3: [EE2] - readyFn-entry - devicename: sol, DeviceName: ws:localDomain.de:9124, Key: sol.ws:localDomain.de:9124
Ich spekuliere mal, dass das hier in DevIo_Open falsch läuft:

Zitat
DevIo_OpenDev
.
.
  } elsif($dev =~ m,^(ws:|wss:)?([^/:]+):([0-9]+)(.*?)$,) {# TCP or websocket
    my ($proto, $host, $port, $path) = ($1 ? $1 : "", $2, $3, $4);
    $dev = "$host:$port";
    if($proto eq "wss:")  {
      $hash->{SSL} = 1;
      $proto = "ws:";
    }
    if($proto eq "ws:")  {
      require MIME::Base64;
      return &$doCb('websocket is only supported with callback') if(!$callback);
    }
    $path = "/" if(!defined($path) || $path eq "");

    # This part is called every time the timeout (5sec) is expired _OR_
    # somebody is communicating over another TCP connection. As the connect
    # for non-existent devices has a delay of 3 sec, we are sitting all the
    # time in this connect. NEXT_OPEN tries to avoid this problem.
    if($hash->{NEXT_OPEN} && time() < $hash->{NEXT_OPEN}) {
      return &$doCb(undef); # Forum 53309
    }

    delete($readyfnlist{"$name.$dev"});

    my $timeout = $hash->{TIMEOUT} ? $hash->{TIMEOUT} : 3;

    # Do common TCP/IP "afterwork":
    # if connected: set keepalive, fill selectlist, FD, TCPDev.
    # if not: report the error and schedule reconnect
    my $doTcpTail = sub($) {
      my ($conn) = @_;
      if($conn) {
        delete($hash->{NEXT_OPEN});
        $conn->setsockopt(SOL_SOCKET, SO_KEEPALIVE, 1) if(defined($conn));

      } else {
        Log3 $name, 1, "$name: Can't connect to $dev: $!" if(!$reopen && $!);
        $readyfnlist{"$name.$dev"} = $hash;
        DevIo_setStates($hash, "disconnected");
        DoTrigger($name, "DISCONNECTED") if(!$reopen);
        $hash->{NEXT_OPEN} = time() + $nextOpenDelay;
        return 0;
      }

      $hash->{WEBSOCKET} = 1 if($proto eq "ws:");
      $hash->{TCPDev} = $conn;
      $hash->{FD} = $conn->fileno();
      $hash->{CD} = $conn;
      $selectlist{"$name.$dev"} = $hash;
      return 1;
    };
in DevIo_Close u. DevIo_Disconnected wird mit $hash->{DeviceName} auf die readyfnlist zugegriffen.

Grüße Markus

Edit: Die  Zeile für die selectlist hab ich noch ergänzt. Bei mir läuft eine Version, in der ich $dev durch $hash->{DeviceName} ersetzt habe. Bei EE2 warte ich auf den nächsten disconnect(spätestens um 3 Uhr, wenn meine IP neu zugewiesen wird). Das SamsungAV wirkt auf den ersten Blick "gefälliger".
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 23 Juni 2020, 10:34:19
Danke fuer den Hinweis, $dev bei wss zu "fixen" war in der Tat ein Fehler.

Ich habe DevIo.pm geaendert und eingecheckt. Ich habe mein wstest.pm im alten Posting auch aktualisiert, und damit und mit dem geaenderten DevIo.pm das reconnect erfolgreich getestet, gegen eine zweite FHEM-Instanz.
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 24 Juni 2020, 07:15:05
Hi Rudi,
da bin ich ja jetzt froh, dass mein Gesülze der letzten Tage dann doch einen Fehlerhintergrund hatte.  ;)

Heute Nacht hatte ich disconnects u. die wurden auch brav durch reopen gelöst. Da ich den logelevel niedrig hatte, konnte ich nicht sehen, ob "das System" den Verbindungsabbruch bemerkt hat oder meine eigene Funktion(zyklische Prüfung, ob der Server noch pingt). Das checke ich noch. Das SamsungAV macht noch Probleme, aber vermutlich hab ich da noch einen Bug drin. :'(

Danke&Grüße Markus

btw., was passiert eigentlich technisch genau beim nonblocking-get ? Wird da auch ein Child-Prozess wie beim Blocking-Call eröffnet ?
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 24 Juni 2020, 09:46:12
HttpUtils_NonblockingGet erzeugt keinen weiteren Prozess, sondern traegt sich in die globale select Liste ein, sowohl fuers Schreiben, wie auch fuers Lesen. Bei gesetzten dnsServer wird auch die DNS-Aufloesung per eigene Routine (wieder ueber den globalen select) nicht blockierend abgewickelt. D.h. es wird nirgendwo gewartet/geschlafen, und der Ressourcenverbrauch ist minimal.

Kein Regel ohne Ausnahme: Zertifikataustausch/Cryptoverfahren Aushandlung am Anfang einer TLS/HTTPS Verbindung.
Aber da gibt es auch ein Timeout, insofern ist es nicht sehr tragisch.
Titel: Antw:WebSocket via DevIO?
Beitrag von: dominik am 19 Juli 2020, 22:04:59
Ich habe gerade festgestellt, dass bei Websockets
SimpleRead und SimpleReadWithTimeout
unterschiedliche Ergebnisse liefern.

Ich denke es muss noch ein DevIo_DecodeWS($hash, $buf) if($hash->{WEBSOCKET})
hier mit rein:
https://github.com/mhop/fhem-mirror/blob/master/fhem/FHEM/DevIo.pm#L99

Einen Nachteil hat die WithTimeout Funktion noch, es wird nie ein disconnect erkannt, wobei ich da jetzt keine Idee hätte wie man das korrigiert.

//EDIT..damit funktionierts:
sub
DevIo_SimpleReadWithTimeout($$)
{
  my ($hash, $timeout) = @_;

  my $rin = "";
  vec($rin, $hash->{FD}, 1) = 1;
  my $nfound = select($rin, undef, undef, $timeout);
  if ($nfound > 0) {
    my $buf = DevIo_DoSimpleRead($hash);
    $buf = DevIo_DecodeWS($hash, $buf) if($hash->{WEBSOCKET});
    return $buf;
  }
  return undef;
}
Titel: Antw:WebSocket via DevIO?
Beitrag von: rudolfkoenig am 20 Juli 2020, 15:31:04
Ich will eine "nicht erwuenschte" Funktion wie DevIo_TimeoutRead (steht im Kommentar drueber: DO NOT USE IT!) nicht erweitern.
Lieber wuerde ich sie entfernen, leider gibt es noch ein paar Module, die sie verwenden.
Titel: Antw:WebSocket via DevIO?
Beitrag von: KölnSolar am 20 Juli 2020, 18:35:59
Zitat
Lieber wuerde ich sie entfernen, leider gibt es noch ein paar Module, die sie verwenden.
Ein erster Schritt wäre vielleicht die Beschreibung aus dem Wiki zu entfernen.  :-\

Grüße Markus
Titel: Antw:WebSocket via DevIO?
Beitrag von: dominik am 20 Juli 2020, 18:42:08
Ok, wenn die Funktion nicht weiter verwendet werden soll, ist das natuerlich ein Argument.
Titel: Antw:WebSocket via DevIO?
Beitrag von: krikan am 20 Juli 2020, 18:53:14
Ein erster Schritt wäre vielleicht die Beschreibung aus dem Wiki zu entfernen.  :-\
Meiner Meinung nach ergab sich "nihct nutzen" schon aus dem Wiki und der jeweils vorhandenen Warnung; habe jetzt noch jeweils "NICHT NUTZEN" in der Warnungs-Box ergänzt. "Entfernen" gefiel mir nicht. Wer es anders möchte, kann gerne zur Tat schreiten.  ;)

Gruß, Christian