Communication with Fhem via websockets ?

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

Vorheriges Thema - Nächstes Thema

svenson08

Hello,

i have only defined
define wsPort websocket 8080 global
define wsPort_fhem websocket_json


and set verbose to 5

when i send an command i found in the fhemlogfile
websocket_json: Undefined subroutine &websocket_json::AnalyzeCommandChain called

i fix this bug in the 10_websocket_json.pm, restart fhem and the send out of the websocket.html now works.
i attach the fixed version of the 10_websocket_json.pm.

In my case send and receive over websocket works. now i can make further tests.

svenson


ntruchsess

Hi Svenson,

thank you for reporting (and fixing) this bug. Will include your patch soon (didn't see your post more early as I was away from my computer during winter-hollidays...)

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

svenson08

Hi Norbert,

That's OK. It's running for me yet (successfully) as an test with my front end. And on the other side, it is not as if I can not manage myself.

I still have some ideas for improvement that I wanted to watch in the modules-code before, but have not gotten to it.

for example:

  • It should be possible to terminate all existing connections of websocketserver (disconnect all / restart, or similar).
  • Could disable the Websocketserver (disable 0/1).
  • All active connections should be displayed (as reading)

Then I noticed if you sent over the websocket a "invalid" command is sent an erroranswer ("Error" feedback from FHEM) to the client, but there I have not "see" on the client side. I wanted to see detail. I think with such a "fault" should somehow be returned as an error.

svenson

AlxDmr

Hello Norbert,
I get a handshake error with your new code :
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

Using Chrome under with windows 8.1, latest versions.

Regards,
    Alex.

AKNOT

Hey there,

I tried to use your websocket module, but I don't get it to work. I installed JSON and Websocket from metacpan.org into /etc/perl/ (Im using a Raspberry with wheezy).
After restart the fhem log tells me:


2015.01.18 20:20:51 1: PERL WARNING: Use of uninitialized value in ref-to-glob cast at ./FHEM/00_websocket.pm line 310.
2015.01.18 20:20:51 1: PERL WARNING: syswrite() on unopened filehandle at ./FHEM/00_websocket.pm line 310.


As client I'm using a nodeJs Server. The connection is established successfuly (also the counter in the fhem ws device counts up), but when I do


fhem.sendCommand({
command: 'set KuecheLED off',
});


in the Connection Callback nothing happens.

What could be wrong?

Thanks in advance!
AKNOT

AlxDmr

#50
Hello Norbert,
sorry to bother you again about that but I still encounter the same problem when establishing the websocket connection using the JSON subprotocol. I use your code for connection :
https://raw.githubusercontent.com/ntruchsess/fhem-mirror/websockets/fhem/www/fhem_websocket.js

However there is an error, here is what happen :
The HTTP request from client to server is well formatted, it indicates that the client wnat to change protocole to websocket and use the subprotocol json.
The server handle the request and send back a HTTP answer specifying that it is OK to switch protocol to websocket BUT it does not specify that subprotocol is now json. As a consequence the web-browser throw an error saying that webserver does not properly handle the communication protocol.
WebSocket connection to 'ws://192.168.1.14:8080/' failed: Error during WebSocket handshake: Sent non-empty 'Sec-WebSocket-Protocol' header but no response was received
GET ws://192.168.1.14:8080/ HTTP/1.1
Host: 192.168.1.14:8080
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: http://www.clubic.com
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36 OPR/27.0.1689.76
Accept-Encoding: gzip, deflate, lzma, sdch
Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Sec-WebSocket-Key: J9gkEgJR38c7Ks4NFADLHA==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Protocol: json

HTTP/1.1 101 WebSocket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Accept: ZgItETgg6fXcea/Yzl/I/4AtvQ8=


I identified the code responsible for setting the subprotocol in 00_websocket.pm :
    if ($hash = $main::defs{$sname}) {
      foreach my $arg (keys %{$hash->{onopen}}) {
        my $protocol = eval {
          return &{$hash->{onopen}->{$arg}->{fn}}($cl,$hash->{onopen}->{$arg}->{arg},$cl->{resource},@{$cl->{protocols}});
        };
        Log3 ($sname,4,"websocket: ".GP_Catch($@)) if $@;
        if (defined $protocol) {
          Log3 ($sname,4,"websocket: protocol chosen '$protocol'");
          $cl->{hs}->res->subprotocol($protocol);
          $cl->{protocol} = $protocol;
          last;
        }
      }
    }


Unfortuntly I am unable to program in PERL language so I cannot even add some traces (using Log3 properly). could anyone help?

AlxDmr

I added HTTP request and answer to my previous post, hope it can help.

AlxDmr

#52
The struggle continue...
I managed to add some traces using Log3 function, it appears that %{$hash->{onopen}} is "empty", meaning that no one subscribed to onopen.
So I think that 10_websocket_json.pm is not loaded. Looking back at the post of svenson08 I added the very same line of code in fhem?cfg :
define wsPort websocket 8080 global
define wsPort_fhem websocket_json


But when I save the file, it displays an error 0 Cannot load module websocket_json.

So... I think I am progressing although it is quite difficult for a newbies like me! What should I configure in order to load this module properly ? Of course I checked that the file 10_websocket_json.pm is present in /opt/fhem/FHEM

Regards,
    Alex.

AlxDmr

#53
Here I am!
I "just" forgot to install the JSON library...
so, in case it could be useful for someone, if you want to test the great work done by Norbert :
1) Download the files from his repository (00_websocket.pm, 10_websocket_json.pm, ...) as mentionned in a previous post of Norbert
2) Install library using cpan
sudo cpan App::cpanminus
sudo cpanm Protocol::WebSocket
sudo cpanm JSON
3) in fhem.cfg, add :
define wsPort websocket 8080 global
define wsPort_json websocket_json


then reboot and it should be done!
I got an "error" when loading fhem.cfg :
ERROR:

0 0

but modules are loaded and I am able to communicate

Für Norbert :Entschuldigung, ich bin ein bisschen dumm... Danke schöne für ihren werk, sehr nützlich !

AlxDmr

Hello,
I get all the events now (plus the list of devices) but I cannot apply a "get DEVICE ..." command.
Well in fact it does not returns anything not does it trace something in the logs...
I checked via telnet that the command is working :
get EnO_UTE_008785CE measurement input energy
it emits an events to an update in the readings
However, when I try to apply the same command via websocket (using the websocket.html), I get nothing. I tried several syntax :
{"command":"get EnO_UTE_008785CE measurement input energy"}
{"command":"get", "device":"EnO_UTE_008785CE", "property":"measurement input energy"}
or directly in the javascript console :
fhem.sendCommand( {command:"get EnO_UTE_008785CE measurement input energy"} );
fhem.sendCommand( {command:"get", device:"EnO_UTE_008785CE", property:"measurement input energy"} );
fhem.sendCommand( {command:"get", arg:"EnO_UTE_008785CE measurement input energy"} );

What is the right way to send a "get" command ? looking at the 00_websocket.pm file I would have suspect at least one of them to work fine :(

     Alex.

AlxDmr

I red the code of the file 10_websocket_json.pm (https://raw.githubusercontent.com/ntruchsess/fhem-mirror/websockets/fhem/FHEM/10_websocket_json.pm), there is one typo when processing the websocket command message :
AnylyzeCommand as to be AnalyzeCommand  (well, I guess)

Anyway, the code just after also fails for an unknown reason for me :
my $ret = AnalyzeCommandChain($cl, $command);
I added a Log3 just before and just after and the second one is never displayed in the logs. Every command seems to fails when processed by AnalyzeCommandChain, I tried to change AnalyzeCommandChain into AnalyzeCommand but there is no improvment.

I looked at 98_telnet.pm and this function is also used (AnalyzeCommandChain), maybe the first argument is not the right one?

Don't know what to do now :(