fhem.js - websocket connection to fhem via node.js proxy

Begonnen von Werner Schäffer, 13 Februar 2015, 21:53:55

Vorheriges Thema - Nächstes Thema

Werner Schäffer

Setze in params.js

exports.readDB = false;

Das ist auf true gesetzt. Die Fehlermeldung erscheint dann nicht mehr.

Dies ist auch ein neues Feature und ermöglicht Werte aus einer mySql DB zu lesen und dann an FHEM zu übergeben. Ich benutze das um die aktuelle Windgeschwindigkeit in FHEM zur Verfügung zu haben.

Um das zu nutzen muss das mysql-modul installiert werden mit

npm install -g mysql


HansDampfHH

#16
Hm, ne. Nach der letzten Version läuft das leider nicht mehr.
Auch das vorher funktionierende getAllValues läuft jetzt nicht mehr.
Die aufgerufene HTML Seite ist im pending...

Tut mir leid :-(
Wie kann man so etwas debuggen?
Würde ja auch gerne versuchen solchen Problemen auf die Spur zu kommen.
FHEM Docker, CUL868, Zigbee, CCU2, Jeelink

HansDampfHH

Konntest du das nachvollziehen oder liegt es an meinem Setup, dass das nicht mehr funktioniert?
FHEM Docker, CUL868, Zigbee, CCU2, Jeelink

Werner Schäffer

Ich habe gerade eine neue Version auf Github geladen. Schau mal in params.js dass dort

exports.debug = 1;

steht. Dies sorgt dafür dass mehr Meldungen auf der Server-Konsole ausgegeben werden.
Wenn es Probleme gibt dann poste mal was auf der Konsole ausgegeben wurde.

HansDampfHH

#19
Hm, also erst einmal gab es die Fehlermeldung über das fehlende modul socketio-auth.
Aber das habe ich jetzt nachinstalliert.

Nun ist der aktuelle Stand der gleich wie vorher.
Die aufgerufene Seite /test/nodetest.html ist pending.

Ich habe natürlich die URL in der HTML angepasst ;-)

Ausgabe auf der Konsole:
Server started: without SSL
initFinished
start connection to fhem server
connected to fhem server for listen on changed values

Nach dem Aufrufen der nodetest.html wird die aber nicht geladen, hängt im pending.

:-(
FHEM Docker, CUL868, Zigbee, CCU2, Jeelink

Werner Schäffer

Stimmen die Ports überein?

Bitte prüfen
1. exports.nodePort in params.js
2. in der URL im beim Aufruf im Browser
3. im Javascriptteil beim Aufruf io.connect

alle drei müssen gleich sein.
-------

Nach dem Start von node server.js mit



netstat -pona|grep deinport

prüfen ob node.js auf deinport hört.

-------

Zeigt in params.js der Paramater exports.pathHTML auf das richtige Verzeichnis?

------

Wird nach dem Aufruf der Website auf der node.js Konsole irgendetwas ausgegeben?

------

HansDampfHH

Also die Ports sind an allen Stellen gleich.
Ursprünglich hatte ich in der params.js den Value exports.PathHTML auf false, da ich dachte, dass keine Web files zurück gegeben werden.

exports.pathHTML = '/var/www/fhem.js/test';
exports.indexHTML = 'nodetest.html';

Das habe ich jetzt umgestellt und im Browser nachfolgende URL aufgerufen:
http://192.168.178.30:8086/fhem.js/test/nodetest.html

Nun spuckt die Konsole folgendes aus:
http request: /fhem.js/test/nodetest.html

Der Befehl netstat -pona|grep 8086 gibt folgendes zurück:
tcp        0      0 0.0.0.0:8086            0.0.0.0:*               LISTEN      19991/nodejs     off (0.00/0/0)

Aber die aufgerufene HTML Seite lädt weiterhin scheinbar unendlich...und bei einer Änderung eines Devices unter FHEM tut sich nichts.
FHEM Docker, CUL868, Zigbee, CCU2, Jeelink

Werner Schäffer

exports.pathHTML = '/var/www/fhem.js/test';

legt das Verzeichnis /var/www/fhem.js/test als Root-Verzeichnis des Webservers fest. Im Browser ist somit alles relative zu diesem Pfad zu sehen.

Also versuchs mal mit:

http://192.168.178.30:8086/nodetest.html

Außerdem:
exports.indexHTML = 'nodetest.html';
ist nicht so schön - besser bei
exports.indexHTML = 'index.html';
belassen. Dies legt die default Datei fest die geladen wird wenn im Browser keine Datei angeben wurde. Dies ist der allgemeine Standard (index.html) auch z.B. im Apache. 




rretsiem

Hallo,

sehr interessante Geschichte, die ich direkt mal ausprobiere und schon in ein Problem laufe.

bei einem emit mit einem command wird der callback bei mir nicht ausgeführt, das command selbst wird aber abgesetzt.


function buttonClicked(val) {
      console.log("1. klicked!!");
      // body...
      socket.emit('command', 'set testDummy on', function(data) {
         console.log("2. emit function callback");
         console.log(data);
         for (rsp in data) {
            console.log(rsp);
            // var value = rsp;
         }

      });
   }


Der erste log kommt im Browser noch an, ist ja auch vor dem emit. aber die function(data) {} scheint nicht ausgeführt zu werden.

Wo liegt der Fehler?

Werner Schäffer

Zitat von: rretsiem am 24 April 2015, 15:12:51
...
bei einem emit mit einem command wird der callback bei mir nicht ausgeführt, das command selbst wird aber abgesetzt.


function buttonClicked(val) {
      console.log("1. klicked!!");
      // body...
      socket.emit('command', 'set testDummy on', function(data) {
         console.log("2. emit function callback");
         console.log(data);
         for (rsp in data) {
            console.log(rsp);
            // var value = rsp;
         }

      });
   }


Der erste log kommt im Browser noch an, ist ja auch vor dem emit. aber die function(data) {} scheint nicht ausgeführt zu werden.


set xyz on ist kein gutes Beispiel, weil fhem.pl bei diesem Befehl keine Antwort sendet, sondern den Befehl nur ausführt. Kann man ganz einfach auf dem Server testen mit

telnet localhost 7072
set xyz on


... und es kommt keine Meldung zurück und der node.js Server schickt deshalb auch keine Antwort.

Andere Frage: wurde der Befehl wengistens ausgeführt?
Ansonsten mal den Output der node.js Konsole posten.

Kleiner Tipp zum Testen:
einfach mal den Befehl "list" absetzen - der liefert viele Zeilen Antwort.
 

rretsiem

Danke, das ist natürlich klar das bei einem "set xyz on" nix zurück kommt.
Der "list" klappt und führt das callback aus...

Um also zu prüfen ob ein "set xyz on" ausgeführt wird müsste ich im Client einen emit() auf getValueOnChange auf das Device zusätzlich machen, korrekt?
Aber wie gehe ich bei mehreren verschiedenen Devices auf einer Seite dann vor, muss ich für jedes Command dann ein eigenen emit() implementieren?

Werner Schäffer

Zitat von: rretsiem am 24 April 2015, 15:42:58
Danke, das ist natürlich klar das bei einem "set xyz on" nix zurück kommt.
Der "list" klappt und führt das callback aus...

Um also zu prüfen ob ein "set xyz on" ausgeführt wird müsste ich im Client einen emit() auf getValueOnChange auf das Device zusätzlich machen, korrekt?
Aber wie gehe ich bei mehreren verschiedenen Devices auf einer Seite dann vor, muss ich für jedes Command dann ein eigenen emit() implementieren?

Auf jede Einheit muss ein seperates emit('getValueOnChange','name') ausgeführt werden oder man setzt einen emit('getAllValuesOnChange') ab. Dann bekommt man aber alles.
Ich benutze in einer Android App erstere Lösung um den Traffic so klein wie möglich zu halten.

Aber egal wie man es macht man braucht nur einen Listener: socket.on('value', ....)

rretsiem

Danke, da benötige ich denke ich noch etwas Praxis wie man das am besten nutzt.
Noch eine weitere Frage, ich bekomme egal was ich aufrufe, "lediglich" die States eines Devices. Planst du evtl auch etwas um evtl alle Readings eines Devices via Json zu erhalten. Also quasi ein Jsonlist2 vom FhemServer?

Werner Schäffer

Zitat von: rretsiem am 24 April 2015, 17:17:41
...
Planst du evtl auch etwas um evtl alle Readings eines Devices via Json zu erhalten. Also quasi ein Jsonlist2 vom FhemServer?

du kannst jetzt auch emit('command','jsonList2 device',...) aufrufen.
Ich habe es noch nicht ausprobiert, aber das wird nicht ganz problemlos funktionieren, da bei die zurückgegeben Daten zeilenweise kommen. Mit irgendwelchen Javascript commands würde man daraus auch wieder eine JSON-Struktur hinbekommen. Aber je länger ich hier schreibe desto klarer wird dass ich da noch einen speziellen Request einbauen werde. Das ist kein großer Aufwand - aber heute nicht mehr!

rretsiem

Ich hatte mir die Server.js schon angesehen wie du das normale list implementiert hattest aber hatte auch noch keinen Zeit da was zu tun.
Ich denke aber auch das das spezielle Commando besser in beim Server aufgehoben ist, dann kann der das parsen und aufbereiten und nur noch das Json zurückschicken. Wenn ich das via command baue dann muss der Client ja alles tun?