Communication with Fhem via websockets ?

Begonnen von AlxDmr, 03 November 2014, 19:58:17

Vorheriges Thema - Nächstes Thema

ntruchsess

here you find some information on how to install perl modules from cpan.

An alternative is to manually place the unzipped library files to fhem/FHEM/lib, 98_websocket.pm is able to load dependencies from there to. To do so locate Directory 'Protocol' in 'Protocol-WebSocket-0.18/lib' (from the unzipped archive) and move that (and all its subdirectories) to the target location.

regards,

Norbert
while (!asleep()) {sheep++};

AlxDmr

Hallo,
I finally succeeded to install dependencies (actually Protocol::Websocket but also JSON) so that fhem seems to be able to intitialize your websocket module.
However, when doing in the browser :
con = new WebSocket('ws://192.168.1.14:8080/fhem', ['json']);
I get the following error :
WebSocket connection to 'ws://192.168.1.14:8080/fhem' failed: Error during WebSocket handshake: Sent non-empty 'Sec-WebSocket-Protocol' header but no response was received


AlxDmr

The fhem logs are the followings :
2014.11.27 14:14:29 3: websocket websocket:192.168.1.24:62032 disconnect due to timeout
2014.11.27 14:14:29 1: PERL WARNING: Use of uninitialized value in ref-to-glob cast at ./FHEM/98_websocket.pm line 323.
2014.11.27 14:14:29 1: PERL WARNING: syswrite() on unopened filehandle at ./FHEM/98_websocket.pm line 323.
2014.11.27 14:14:59 3: websocket websocket:192.168.1.24:62032 disconnect due to timeout
2014.11.27 14:15:29 3: websocket websocket:192.168.1.24:62032 disconnect due to timeout

ntruchsess

while (!asleep()) {sheep++};

AlxDmr

#34
It's a Raspberry Pi model B+. I installed the Raspberrian distribution on it.

ntruchsess

and the javascript-code runs in which broser? Or is this on node.js?
while (!asleep()) {sheep++};

ntruchsess

while (!asleep()) {sheep++};

AlxDmr

#37
Thanks for the fix, I will test that as soon as possible.
I did the test from a browser (Opera, last version based on webkit) although the real usage I will have next will be to integrate the client socket inside NodeJS.

Best regards,
    Alex.

AlxDmr

#38
It works :)
well at least the connection is established, but now I'm struggling to understand the protocol you set up. I would like to subscribe to any event comming from Fhem, how should I do that ?

I am also trying to subscribe to a specific device (an EnOcean switch) with :

con.send( JSON.stringify({ "type" : "command"
            , "payload" : { "command" : "subscribe"
, "type" : ""
, "name" : "EnO_switch_002842C2"
, "changed" : "*"
, "arg" : "widget1"
}
  }) );


but I got no result when using the switch. I guess that payload object is not properly initialized but I do not know what is expected for attribute changed, type and arg.

ntruchsess

The parameters 'type', 'name' and 'changed' are being used as regular-expressions to filter the events on fhem-side. All three parameters are optional (if not specified it matches any 'TYPE', 'NAME' or 'CHANGED' internal of the event). '*' taken as a regular expression doesn't match anything ('' or '.*' would).

I suggest you use fhem.js to access the websocket-interface. fhem.js is able to process the messages returned by 'list'-command. It keeps a list of all devices in 'fhem.devices' and does update the devices readings with evey event received via event-message. You may register additional event-handlers with fhem.js. See websocket.html as example how to use the lib.

regards,

Norbert
while (!asleep()) {sheep++};

ntruchsess

I did some refactoring to the websocket-module:

split 98_websocket.pm into 00_websocket.pm, 10_websocket_json.pm and 10_websocket_fhem.pm (old 98_websocket.pm is removed)

00_websocket.pm is pure websocket-protocol-handler and acts as IODev for 10_websocket_xxx.pm
10_websocket_json.pm does handle the json-protocol (that was integrated into 98_websocket.pm before).
10_websocket_fhem.pm does handle plain-text fhem command protocol (similar to 98_telnet.pm, but over websocket).

As the core 00_websocket.pm module does handle the websocket-handshake only delegating all message-handling to it's clients, this refactoring enables the websocket-stack to be used by other frontend-specific modules more easily.

- Norbert

while (!asleep()) {sheep++};

ntruchsess

#41
- just added support for SSL (just specify attribute 'SSL' on websocket-device). Then connect using wss:// as protocol of websocket. For ssl to work a certificate has to be installed in fhem 'cert' directory. If you are using a self-signed certificate make sure your browser does trust this certificate. To import the certificate into the browser you may try to open the websocket-port in browser (by using a https://<hostname>:<port> type url and then accepting the security warning).

- js-library fhem.js has been renamed to fhem_websocket.js

- when using fhem_websocket.js you may enable ssl by setting 'secure'-property of fhem-object.

- support for a 'resource-path' in websocket-url for module websocket_json is implemented. Use 'define <name> websocket_json /path_to_resource' in definition and then ws://<ip:port>/path_to_resource when opening the websocket. Defaults to '/'. A resource-path may be used to share a single websocket-port for different websocket_client-modules serving different purposes.

regards,
Norbert
while (!asleep()) {sheep++};

svenson08

hello norbert,

I have websocket and websocket_json defined. In your sample html relevant info from FHEM come back. The sending of commands (set Office on) but does not seem to be working. from the logfile

Zitat
2014.12.11 06:17:52 5: websocket text {"type":"command","payload":{"command":"set Office off"}}
2014.12.11 06:17:52 5: websocket jsonmessage: $VAR1 = {
          'payload' => {
                         'command' => 'set Office off'
                       },
          'type' => 'command'
        };

2014.12.11 06:17:52 4: websocket_json: Undefined subroutine &websocket_json::AnalyzeCommandChain called

websocket_fhem also needs to be defined? in my case i have following errors in the log.

Zitat2014.12.11 06:24:04 5: Loading ./FHEM/10_websocket_fhem.pm
2014.12.11 06:24:04 1: reload: Error:Modul 10_websocket_fhem deactivated:
Global symbol "%inform" requires explicit package name at ./FHEM/10_websocket_fhem.pm line 96.
Global symbol "%defs" requires explicit package name at ./FHEM/10_websocket_fhem.pm line 97.
Global symbol "%inform" requires explicit package name at ./FHEM/10_websocket_fhem.pm line 98.

the last thing. some garbage data seen in the log, like this

Zitat2014.12.11 06:17:00 5: Š€ðÃÔ'
2014.12.11 06:17:00 5: websocket pong
2014.12.11 06:17:30 5: $VAR1 = {
          'type' => 'ping'
        };

2014.12.11 06:17:30 5: Š€þGz·
2014.12.11 06:17:30 5: websocket pong
2014.12.11 06:17:52 5: ¹X¨i #ŠÙ(ÍKšzËÍ5ÉÄz,,KÐ9ÑÏ9ÌKš#Š

svenson

AlxDmr

#43
Hello Norbert,
I downloaded the latest files from your git and there is a handshake problem :
in the javascript console of Chrome (latest version, windows 8 ) :
WebSocket connection to 'ws://192.168.1.12:8080/' failed: Error during WebSocket handshake: Sent non-empty 'Sec-WebSocket-Protocol' header but no response was received
I think you fixed the problem but there might have been a regression when you refactored the code.

Regards,
    Alex.

CaliHo

Hello Norbert,
I loaded the three pm files 00_websocket, 10_websocket_fhem and 10_websocket_json into my Fhem server and installed the necessary perl modules (protocol::websocket..) via cpan. I then defined "websocket websocket 8080 global" in the fhem.cfg and uploaded the websocket.html and the fhem_websocket.js onto the server. The button "open" seems to work: I get a debug output:  "Connection opened to fhem server!" But entering a command like "set Rolladen1 up" or "list Rolladen1"  does not work. When reloading the 10_websocket_fhem I get the same messages as svenson08 in his post "...Global symbol "%inform" requires explicit package name at ./FHEM/10_websocket_fhem.pm line 96...". Do I have to define anything else? Is ist wrong to load all three pm files. If i want to replace a telnet communication I suppose the 10_websocket_fhem ist what I need to get working? I hope you can help me. Thank you for your work so far.

regards,
Carsten