Bosch Junkers Control CT100

Begonnen von Mike_GKA, 21 Juli 2017, 11:10:45

Vorheriges Thema - Nächstes Thema

Mike_GKA

Meine Bosch Junkers Control CT100 habe ich mit den Modulen BDKM und KM200 nicht ansprechen können und ich habe sehr viel Zeit investiert.
Bei KM200 kommt die Fehlermeldung: No proper Communication with Gateway: write error: Connection reset by peer
und bei BDKM: communication ERROR in state reading ids ERROR - retrying every 60s: write error: Connection reset by peer

Bei meinen Recherchen fand ich den nefit-easy-server: https://github.com/robertklep/nefit-easy-http-server

Diesen habe ich erfolgreich installiert und mit FHEM angesprochen.
Wie man dies macht beschreibe ich nachfolgend für Raspberry Model 1 (sollte auch für neuere Raspberry Modell funktionieren, jedoch muss dort ein anderes node-Paket genommen werden)
Der nefit-easy-server braucht node (in neuerer Version), das zuerst installiert werden muss.

cd ~
wget https://nodejs.org/dist/v6.11.1/node-v6.11.1-linux-armv6l.tar.xz
tar -xvf node-v6.11.1-linux-armv6l.tar.xz
cd node-v6.11.1-linux-armv6l/
sudo cp -R * /usr/local/
node -v


Ich bekam dann einen Fehler wegen fehlender Abhängigkeiten, die ich noch installieren musste:
sudo apt-get install gcc-4.8 g++-4.8

Damit lief node und jetzt wird der nefit-easy-server installiert:
sudo npm i nefit-easy-http-server -g

Das dauert eine ganze Weile. Man kann den Erfolg dann prüfen mit:
easy-server -h

Um den easy-server zu starten und dann auch bei einem Restart vom Raspberry neu zu starten habe ich ein kleines Skript start_nefit-easy-http-server.sh  erstellt mit folgendem Inhalt:
#!/bin/bash
easy-server --serial=<serial> --access-key=<access-kex> --password=<password> --host=<host>


<serial>: ist der Name vom CT100, eine 9 stellige Nummer ohne die Lerrzeichen
<access-key>: steht hinten auf der CT100
<password>: ist das Passwort, das man selber vergeben hat bei der Inbetriebnahme vom CT100
--host=<host>: ist optional. Default ist 127.0.0.1 dann kann man nur innerhalb des Raspberry auf den easy-server zugreifen, sonst setzt man hier halt die IP-Adresse des Raspberry.

Damit nicht jeder diese Daten sehen kann:
sudo chmod 711 start_nefit-easy-http-server.sh

Zum Autostart verwende ich pm2 (könnte man auch anders machen):
sudo npm install pm2@latest –g
sudo pm2 start <path>/start_nefit-easy-http-server.sh
sudo pm2 save


<path> muss entsprechend angepasst werden.
Das dauert auch wieder eine ganze Weile, also Geduld!

Damit pm2 auch automatisch startet und damit dann auch der nefit-easy-http-server.

sudo pm2 startup


So jetzt müsste also eigentlich alles laufen und wir testen z.B. mit:
curl http://127.0.0.1:3000/api/status

Statt 127.0.0.1 muss hier die IP-Adresse des Raspberry stehen, falls man oben host gesetzt hat.
Die Antwort ist ein JSON-String, der z.B. die Temperatur im Haus, die Soll-Temperatur und die Außen-Temperatur enthält.
Mit:
curl -XPOST http:// 127.0.0.1:3000/bridge/heatingCircuits/hc1/temperatureRoomManual -d '{"value":20}' -H 'Content-Type: application/json'

kann man dann z.B. die Soll-Temperatur setzen.
Interessant ist auch:
curl http:// 127.0.0.1:3000/bridge/ecus/rrc/recordings/yearTotal

Damit bekommt den Verbrauch seit Jahresbeginn in kWh.

Weitere Infos zum easy-server und dem api findet man unter:
https://github.com/robertklep/nefit-easy-http-server
https://github.com/robertklep/nefit-easy-core/wiki/List-of-endpoints

Da wir jetzt den easy-server mit http ansprechen können, ist natürlich in FHEM das Modul HTTPMOD bestens geeignet. Also definieren wir in FHEM:
define CT100_Status HTTPMOD http://127.0.0.1:3000/api/status 900
attr CT100_Status userattr reading01JSON reading01Name reading02JSON reading02Name reading03JSON reading03Name
attr CT100_Status reading01JSON in house temp
attr CT100_Status reading01Name t_inhouse
attr CT100_Status reading02JSON temp setpoint
attr CT100_Status reading02Name t_setpoint
attr CT100_Status reading03JSON outdoor temp
attr CT100_Status reading03Name t_outdoor


Zum Lesen der Verbrauchsdaten definieren wir ein weiteres HTTPMOD-Device:
define CT100_yearTotal HTTPMOD http://127.0.0.1:3000/bridge/ecus/rrc/recordings/yearTotal 900
attr CT100_yearTotal userattr reading01JSON reading01Name reading02JSON reading02Name
attr CT100_yearTotal reading01JSON value
attr CT100_yearTotal reading01Name value
attr CT100_yearTotal reading02JSON unitOfMeasure
attr CT100_yearTotal reading02Name unit


Der Rest ist dann Standard, also bei Bedarf Logfiles und svg-Grafiken definieren.

Geht man in https://github.com/robertklep/nefit-easy-core/wiki/List-of-endpoints die ,,List of endpoints" durch, dann kann man da noch eine ganze Menge machen. Aber mir reichte das mal für den Anfang.

Es ist meiner Meinung nach auch suboptimal für jeden ,,Endpoint" ein HTTPMOD-Device zu definieren. Das kann man sicher geschickter machen, aber da reichen meine FHEM Kenntnisse nicht aus.
Vielleicht greift ja mal ein anderer diesen Ansatz auf.

PS: Das ist mein erster Beitrag hier im Forum. Nachdem ich so viel in den letzten Monaten von den unzähligen Beiträgen als FHEM-Anfänger profitiert habe, dachte ich es wäre vielleicht mal Zeit, selber etwas bei zu steuern.

chriz

Hi Mike,

klasse Arbeit, habe hier ebenfalls einen CT100 am Start und habe lange nach einer Einbindung in FHEM gesucht. Mittlerweile habe ich das HEATRONIC  Modul im Einsatz (via USB Adapter an der Junkers Therme). Damit kann ich aber leider nur den BUS lesen, also keine Werte setzen.

Kann man mit dem nefit-easy-server nicht sogar den Betriebsdruck der Therme auslesen? Hab das mal auf einigen Screenshots gesehen.



Grüße
Chris


FHEM auf Intel NUC D34010WYK Core i3, SSD, Ubuntu. HomeMatic mit HMLAN (Groundplane Antenne), Fritz DECT!200, FritzBox 7490, EnerGenie EG-PMS2-LAN, Yamaha RX-V475, Netatmo, Withings, Philips hue, Osram Lightify, Flukso Energy Meter, Harmony, RooWifi, Junkers ZSB 24-4 C Heizung via Heatronic HT-BUS

Mike_GKA

Hi Chris,

wie soeben probiert geht das auch:

curl http://127.0.0.1:3000/api/pressure
liefert
{"pressure":25.5,"unit":"bar"}

und alternativ

curl http://127.0.0.1:3000/bridge/system/appliance/systemPressure
liefert
{"id":"/system/appliance/systemPressure","type":"floatValue","recordable":0,"writeable":0,"value":25.5,"unitOfMeasure":"bar","minValue":0,"maxValue":25}

Die unzähligen "api-calls" und "endpoints" sind gelistet (aber nicht sonderlich dokumentiert) zu finden unter:
https://github.com/robertklep/nefit-easy-http-server
https://github.com/robertklep/nefit-easy-core/wiki/List-of-endpoints

Da ich da kein Spezialist in Sachen Heizung bin, ist das bei mir immer raten und probieren.

Gruß
Mike

Mike_GKA

Nachtrag:
Gerade habe ich das Ganze auch auf PI Modell 3 installiert:
Dies gelang völlig analog. Die Annahme, dass node auf dem Modell 3 anders installiert werden muss, stimmte nicht.
Es musste aber nicht die fehlende Abhängigkeit `GLIBCXX_3.4.18' insatlliert werden.

Noch etwas war extrem augenscheinlich: Die Installation erfolgte um ein vielfaches schneller  ;)

Dabei ist mir noch folgendes aufgefallen:
Der PI3 auf dem ich gerade installiert habe läuft in einem völlig anderen Netz, trotzdem funktionierte der Zugriff auf die CT100 einwandfrei.

Das kann für den ein oder anderen ein Vorteil sehe; ich sehe das aber eher etwas kritisch:
Zumindest der Kommunikationsaufbau vom easy-server zur CT100 erfolgt immer über einen Dritten (Bosch, Junkers). Das wollte ich eigentlich vermeiden.
Aber ich hatte das zuvor schon vermutet, da beim Starten des easy-servers keine IP-Adresse angeben werden muss.


SouzA

Moin,

danke für deine Arbeit.
Mir ist noch nicht ganz klar, wir der nefit Server an die Daten kommt. Auch beim zweiten durchschauen habe ich keine URL im Github gefunden, die auf den Bosch-Server deuten könnte.

Ansonsten könnte ich mir vorstellen, dass das HTTPMOD auch ohne den Server hinbekommen könnte. Es fehlt halt die URL...
Da muss ich mich aber auch noch einlesen.

Bis denn
SouzA
Raspi 4, EnOcean TCM310 USB, HM-MOD-UART-USB, Jeelink, hue, AMAD, fully, FRITZBOX, Signalbot, VIERA, Presence BT/Mac, TPLink, Gassistant, Shelly, fhempy, ZigBee

Mike_GKA

Hi SouzA,

die URL ist in nefit-easy-core (https://github.com/robertklep/nefit-easy-core/blob/master/lib/index.js) definiert:

[...]
   host : 'wa2-mz36-qrmzh6.bosch.de'
[...]

und dahinter steckt anscheinend ein XMPP-Server.

So wie ich das verstehe (was jetzt nicht unbedingt stimmen muss) ist netfit-easy-core ein XMPP-Client, der fest mit dem Bosch XMPP-Server verbunden ist. Mit der Installation von nefit-easy-http-server werden natürlich auch alle Abhängigkeiten installiert, und darunter ist dann auch netfit-easy-core. In netfit-easy-core findet auch einiges an Ver-/Entschlüsselung statt.

Wenn man alles so wie beschrieben installiert hat, findet man die Abhängigkeiten unter /usr/local/lib/node_modules/nefit-easy-http-server/node_modules/. Und das ist eine ganze Menge!


Gruß
Mike

SouzA

Hi,

hatte da auch nochmal geschaut.
Das es ein XMPP ist, hatte ich auch schon rausgelesen. Die URL hatte ich nicht gefunden ;)
Da fällt der HTTPMOD eigentlich ja schon raus...

Für FHEM gibt es ja auch ein XMPP-Modul. Inwieweit das damit zu realisieren ist, hab ich aus zeitlichen Gründen noch nicht prüfen können.

Btw.:
In deinen aufgeführten Links werden ja auch Diskussionen über den Nefit-Server geführt. Da ist von einer nicht Erreichbarkeit bzw. Netzwerktrennung des CT100 die Rede, wenn der Nefit-Server zum Einsatz kommt. Hast du diese Erfahrungen auch gemacht?

Bis denn
SouzA
Raspi 4, EnOcean TCM310 USB, HM-MOD-UART-USB, Jeelink, hue, AMAD, fully, FRITZBOX, Signalbot, VIERA, Presence BT/Mac, TPLink, Gassistant, Shelly, fhempy, ZigBee

Mike_GKA

Hi SouzA,

das mit dem XMPP-Modul in fhem hatte ich noch gar nicht auf dem Schirm. Ich schätze aber, dass das schwierig wird. Im nefit-core wird viel verschlüsselt. Und eine Lösung ist das dann auch nicht, da der XMPP-Server bei Bosch steht. Man müsste direkt auf die CT-100 kommen ohne den Bosch-Server, die IP-Adresse hat man ja. Ich hoffe mal, dass der XMPP-Server lediglich für den Kommunikationsaufbau ist und die eigentliche Kommunikation dann direkt zwischen CT-100 und Client erfolgt. Wenn dem nicht so sein sollte, dann hat man eh keine Chance.

Netzwerk-Trennungen hatte ich häufiger (subjektiv mehrmals am Tag) am Anfang nach der CT-100-Inbetriebnahme, aber da lief noch kein Nefit-Server. Irgendwann hat sich das ohne mein Zutun stabilisiert.
Seit Juli läuft bei mir der Nefit-Server auf 3 Raspberrys (Produktiv, Test, Development) und ich hatte noch keinerlei Ausfall.

Mittlerweile habe ich übrigens ein kleines php-Skript geschrieben, das alle von mir gewünschten Daten vom Nefit-Server holt und als JSON zurückgibt. In fhem brauche ich dann nur noch ein HTTPMOD um alles zu bekommen. Das macht die Sache einfacher, schlanker und leichter pflegbar.

Gruß
Mike

SouzA

Zitat von: Mike_GKA am 06 Oktober 2017, 17:36:35
Und eine Lösung ist das dann auch nicht, da der XMPP-Server bei Bosch steht. Man müsste direkt auf die CT-100 kommen ohne den Bosch-Server, die IP-Adresse hat man ja.

DAS wir schwierig, da ich denke, dass die URL von Bosch in der FW des CT100 steckt. Das CT100 wird auf nix anderes "hören"... Ganz genau weiß man das nicht ;)

Werde mir da auch mal nen Test Raspi aufbauen. Würdest du das Script zur Verfügung stellen?

Bis denn
SouzA
Raspi 4, EnOcean TCM310 USB, HM-MOD-UART-USB, Jeelink, hue, AMAD, fully, FRITZBOX, Signalbot, VIERA, Presence BT/Mac, TPLink, Gassistant, Shelly, fhempy, ZigBee

SouzA

Hi,

hab den Server wohl soweit am laufen... ABER ich bekomme keine vernünftige Meldung raus.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Error: Invalid character in statusMessage.<br> &nbsp; &nbsp;at ServerResponse.writeHead (_http_server.js:195:11)<br> &nbsp; &nbsp;at ServerResponse.writeHead (/usr/local/lib/node_modules/nefit-easy-http-server/node_modules/on-headers/index.js:55:19)<br> &nbsp; &nbsp;at ServerResponse._implicitHeader (_http_server.js:157:8)<br> &nbsp; &nbsp;at ServerResponse.OutgoingMessage.end (_http_outgoing.js:574:10)<br> &nbsp; &nbs.....................................................
Raspi 4, EnOcean TCM310 USB, HM-MOD-UART-USB, Jeelink, hue, AMAD, fully, FRITZBOX, Signalbot, VIERA, Presence BT/Mac, TPLink, Gassistant, Shelly, fhempy, ZigBee

Mike_GKA

Das Skript kann ich auch gerne öffentlich machen. Es ist eigentlich recht simpel.


<?php

$basicurl "http://192.168.1.88:3000";
$result = array();

$json json_decode(file_get_contents($basicurl "/api/status"), true);
$result['t_inhouse'] = $json['in house temp'];
$result['t_setpoint'] = $json['temp setpoint'];
$result['t_outdoor'] = $json['outdoor temp'];
if ($json['boiler indicator'] == "off") {
$result['boiler'] = 0;
} else {
$result['boiler'] = 1;
}

$json json_decode(file_get_contents($basicurl "/api/pressure"), true);
$result['pressure'] = $json['pressure'];

$json json_decode(file_get_contents($basicurl "/bridge/ecus/rrc/recordings/yearTotal"), true);
$result['yearTotal'] = $json['value'];

$json json_decode(file_get_contents($basicurl "/bridge/heatingCircuits/hc1/actualSupplyTemperature"), true);
$result['actualSupplyTemperature'] = $json['value'];

header('Content-Type: application/json');
Echo json_encode($result);

?>


Mike_GKA

Hi SouzA,

auf welche Anfrage bekommst Du diese "Error-Seite"?

Welche Antwort bekommst Du, wenn Du auf dem Raspberry mit dem Nefit-Server in einer Terminalsitzung folgenden Befehl absetzt:

curl http://127.0.0.1:3000/api/status

?

Gruß
Mike

SouzA

Hi,

Danke für die Antwort und das Script.
Ich bekomme bei dem von dir genannten Befehl im Terminal den von mir beschriebenen Fehler.
Keine Ahnung, was da nicht stimmt.

Bis denn SouzA
Raspi 4, EnOcean TCM310 USB, HM-MOD-UART-USB, Jeelink, hue, AMAD, fully, FRITZBOX, Signalbot, VIERA, Presence BT/Mac, TPLink, Gassistant, Shelly, fhempy, ZigBee

Mike_GKA

#13
Hallo SouzA,

sehr eigentümlich, ich hatte zwar bei der Entwicklung dieser Lösung eine ganze Menge von Fehlern zu lösen, diese lagen aber immer alle in node.js selber, bzw. wie ich das installiert habe. Als ich dann node.js am Laufen hatte gabe es mit dem Nefit-Server absolut keinerlei Probleme.

Was gibt der PM2 Status zurück?

sudo pm2 status


Schau Dir mal den Log vom Nefit-server an, diesen erhälst Du z.B. mit:

sudo pm2 logs start_nefit-easy-http-server

Dann machst Du in einem zweiten Terminal

curl http://127.0.0.1:3000/api/status


Dann müsste im Log was kommen. Bei mir ist es:

0|start_ne | 127.0.0.1 - - [10/Oct/2017:09:02:49 +0000] "GET /api/status HTTP/1.1" 200 571 "-" "curl/7.38.0"


Vielleicht sagt uns das dann etwas??

Noch was: Welche Rasbian-Version hast Du installiert? Mit dem neuen Debian-Stretch habe ich es noch nicht getestet. Ich hoffe bis Ende nächster Woche das auch ausprobiert zu haben.

Gruß
Mike

[Nachtrag:
Auf Debian Stretch habe ich es auch ausprobiert (allerdings noch ohne Einbindung in fhem):
node.js Installation funktionierte völlig identisch,
ebenso die Installation vom Nefit-Server und PM2.
Die Abfrage des CT100-Status mit curl funktionierte ebenso fehlerfrei.
Also auf Stretch läuft das auch]

SouzA

Hi,

Danke, dass du helfen willst.
Zur Zeit ist bei mir echt voll und ich bin noch nicht dazu gekommen mal weiter zu testen.
Wenn wieder Luft ist, werde ich die Ergebnisse schreiben.

Bis denn
SouzA
Raspi 4, EnOcean TCM310 USB, HM-MOD-UART-USB, Jeelink, hue, AMAD, fully, FRITZBOX, Signalbot, VIERA, Presence BT/Mac, TPLink, Gassistant, Shelly, fhempy, ZigBee

SouzA

Hi,

sooo:

Zitat von: Mike_GKA am 10 Oktober 2017, 11:27:06

Was gibt der PM2 Status zurück?

sudo pm2 status





sudo pm2 status
┌──────────────────────────────┬──────┬────────┬───┬─────┬──────────┐
│ Name                         │ mode │ status │ ↺ │ cpu │ memory   │
├──────────────────────────────┼──────┼────────┼───┼─────┼──────────┤
│ start_nefit-easy-http-server │ fork │ online │ 0 │ 0%  │ 2.5 MB   │


Zitat von: Mike_GKA am 10 Oktober 2017, 11:27:06
Schau Dir mal den Log vom Nefit-server an, diesen erhälst Du z.B. mit:

sudo pm2 logs start_nefit-easy-http-server




pi@raspberrypi:~ $ sudo pm2 logs start_nefit-easy-http-server
[TAILING] Tailing last 15 lines for [start_nefit-easy-http-server] process (change the value with --lines option)
/root/.pm2/logs/start-nefit-easy-http-server-out-0.log last 15 lines:
0|start_ne | SyntaxError: Unexpected token � in JSON at position 0
0|start_ne |     at Object.parse (native)
0|start_ne |     at pending.(anonymous function).send.then.e (/usr/lib/node_modules/nefit-easy-http-server/node_modules/nefit-easy-core/lib/index.js:222:28)
0|start_ne |     at tryCatcher (/usr/lib/node_modules/nefit-easy-http-server/node_modules/bluebird/js/release/util.js:16:23)
0|start_ne |     at Promise._settlePromiseFromHandler (/usr/lib/node_modules/nefit-easy-http-server/node_modules/bluebird/js/release/promise.js:512:31)
0|start_ne |     at Promise._settlePromise (/usr/lib/node_modules/nefit-easy-http-server/node_modules/bluebird/js/release/promise.js:569:18)
0|start_ne |     at Promise._settlePromise0 (/usr/lib/node_modules/nefit-easy-http-server/node_modules/bluebird/js/release/promise.js:614:10)
0|start_ne |     at Promise._settlePromises (/usr/lib/node_modules/nefit-easy-http-server/node_modules/bluebird/js/release/promise.js:693:18)
0|start_ne |     at Async._drainQueue (/usr/lib/node_modules/nefit-easy-http-server/node_modules/bluebird/js/release/async.js:133:16)
0|start_ne |     at Async._drainQueues (/usr/lib/node_modules/nefit-easy-http-server/node_modules/bluebird/js/release/async.js:143:10)
0|start_ne |     at Immediate.Async.drainQueues (/usr/lib/node_modules/nefit-easy-http-server/node_modules/bluebird/js/release/async.js:17:14)
0|start_ne |     at runCallback (timers.js:672:20)
0|start_ne |     at tryOnImmediate (timers.js:645:5)
0|start_ne |     at processImmediate [as _immediateCallback] (timers.js:617:5)
0|start_ne | 127.0.0.1 - - [15/Oct/2017:09:18:48 +0000] "GET /api/status HTTP/1.1" 500 1723 "-" "curl/7.52.1"

/root/.pm2/logs/start-nefit-easy-http-server-error-0.log last 15 lines:
0|start_ne |     at ServerResponse.writeHead (_http_server.js:195:11)
0|start_ne |     at ServerResponse.writeHead (/usr/lib/node_modules/nefit-easy-http-server/node_modules/on-headers/index.js:55:19)
0|start_ne |     at ServerResponse._implicitHeader (_http_server.js:157:8)
0|start_ne |     at ServerResponse.OutgoingMessage.end (_http_outgoing.js:573:10)
0|start_ne |     at ServerResponse.send (/usr/lib/node_modules/nefit-easy-http-server/node_modules/express/lib/response.js:221:10)
0|start_ne |     at app.use (/usr/lib/node_modules/nefit-easy-http-server/lib/cli/server.js:46:18)
0|start_ne |     at Layer.handle_error (/usr/lib/node_modules/nefit-easy-http-server/node_modules/express/lib/router/layer.js:71:5)
0|start_ne |     at trim_prefix (/usr/lib/node_modules/nefit-easy-http-server/node_modules/express/lib/router/index.js:315:13)
0|start_ne |     at /usr/lib/node_modules/nefit-easy-http-server/node_modules/express/lib/router/index.js:284:7
0|start_ne |     at Function.process_params (/usr/lib/node_modules/nefit-easy-http-server/node_modules/express/lib/router/index.js:335:12)
0|start_ne |     at Immediate.next (/usr/lib/node_modules/nefit-easy-http-server/node_modules/express/lib/router/index.js:275:10)
0|start_ne |     at Immediate.<anonymous> (/usr/lib/node_modules/nefit-easy-http-server/node_modules/express/lib/router/index.js:635:15)
0|start_ne |     at runCallback (timers.js:674:20)
0|start_ne |     at tryOnImmediate (timers.js:645:5)
0|start_ne |     at processImmediate [as _immediateCallback] (timers.js:617:5)




Zitat von: Mike_GKA am 10 Oktober 2017, 11:27:06
Dann machst Du in einem zweiten Terminal

curl http://127.0.0.1:3000/api/status


Dann müsste im Log was kommen. Bei mir ist es:

0|start_ne | 127.0.0.1 - - [10/Oct/2017:09:02:49 +0000] "GET /api/status HTTP/1.1" 200 571 "-" "curl/7.38.0"



0|start_ne | 127.0.0.1 - - [15/Oct/2017:09:35:47 +0000] "GET /api/status HTTP/1.1" 500 1723 "-" "curl/7.52.1"
0|start_ne | Error: Invalid character in statusMessage.
0|start_ne |     at ServerResponse.writeHead (_http_server.js:195:11)
0|start_ne |     at ServerResponse.writeHead (/usr/lib/node_modules/nefit-easy-http-server/node_modules/on-headers/index.js:55:19)
0|start_ne |     at ServerResponse._implicitHeader (_http_server.js:157:8)
0|start_ne |     at ServerResponse.OutgoingMessage.end (_http_outgoing.js:573:10)
0|start_ne |     at ServerResponse.send (/usr/lib/node_modules/nefit-easy-http-server/node_modules/express/lib/response.js:221:10)
0|start_ne |     at app.use (/usr/lib/node_modules/nefit-easy-http-server/lib/cli/server.js:46:18)
0|start_ne |     at Layer.handle_error (/usr/lib/node_modules/nefit-easy-http-server/node_modules/express/lib/router/layer.js:71:5)
0|start_ne |     at trim_prefix (/usr/lib/node_modules/nefit-easy-http-server/node_modules/express/lib/router/index.js:315:13)
0|start_ne |     at /usr/lib/node_modules/nefit-easy-http-server/node_modules/express/lib/router/index.js:284:7
0|start_ne |     at Function.process_params (/usr/lib/node_modules/nefit-easy-http-server/node_modules/express/lib/router/index.js:335:12)
0|start_ne |     at Immediate.next (/usr/lib/node_modules/nefit-easy-http-server/node_modules/express/lib/router/index.js:275:10)
0|start_ne |     at Immediate.<anonymous> (/usr/lib/node_modules/nefit-easy-http-server/node_modules/express/lib/router/index.js:635:15)
0|start_ne |     at runCallback (timers.js:674:20)
0|start_ne |     at tryOnImmediate (timers.js:645:5)
0|start_ne |     at processImmediate [as _immediateCallback] (timers.js:617:5)



Zitat von: Mike_GKA am 10 Oktober 2017, 11:27:06
Vielleicht sagt uns das dann etwas??

Noch was: Welche Rasbian-Version hast Du installiert? Mit dem neuen Debian-Stretch habe ich es noch nicht getestet. Ich hoffe bis Ende nächster Woche das auch ausprobiert zu haben.

[Nachtrag:
Auf Debian Stretch habe ich es auch ausprobiert (allerdings noch ohne Einbindung in fhem):
node.js Installation funktionierte völlig identisch,
ebenso die Installation vom Nefit-Server und PM2.
Die Abfrage des CT100-Status mit curl funktionierte ebenso fehlerfrei.
Also auf Stretch läuft das auch]


Ich habe auch Stretch drauf. Hab den Raspi komplett neu aufgesetzt zum testen.

Bis denn
SouzA
Raspi 4, EnOcean TCM310 USB, HM-MOD-UART-USB, Jeelink, hue, AMAD, fully, FRITZBOX, Signalbot, VIERA, Presence BT/Mac, TPLink, Gassistant, Shelly, fhempy, ZigBee

SouzA

#16
Hat sich erledigt... kriege nun was zurück.

Mein erstes Passwort war länger als 10 Zeichen! Dann funzt das nicht!!

Jetzt habe ich ein anderes Problem...
Der PM2 startet den Server nicht bei reboot.
Obwohl mit sudo installiert und mit sudo gesaved...


hab s nun in die rc.local geklatscht...
Funzt.

Nächste Frage:
Wie und wo führst du jetzt dein Script aus, damit fhem darauf zugriff hat?


Bis denn
SouzA
Raspi 4, EnOcean TCM310 USB, HM-MOD-UART-USB, Jeelink, hue, AMAD, fully, FRITZBOX, Signalbot, VIERA, Presence BT/Mac, TPLink, Gassistant, Shelly, fhempy, ZigBee

Mike_GKA

Hallo SouzA,

erstmal sorry für die späte Reaktion, aber die letzten Wochen waren beruflich und privat schon recht "ausgefüllt".

Aus den Fehlermeldungen bin ich nicht so richtig schlau geworden. Ich hätte eher eine Vermutung Richtung Zeichensatz (UTF8, Ansi) geäußert. Aber dass es an der Länge des Passworts liegt, da wäre ich nie drauf gekommen. Da bin ich auch echt froh, dass mein Passwort exakt 10 Stellen lang ist.

Mit dem Autostart über pm2 hatte ich auch nie Probleme. Das verwende ich auch für einige andere Dinge, aber mit rc.local funktioniert das natürlich auch und ist eigentlich einfacher.

Das Skript in fhem zu nutzen, ist es eigentlich sehr simpel. Bei mir heißt es heizung.php, und in fhem steht dann

# Heizung über nefit-easy-http-server, CT100 und heizung.php

define H_Summary HTTPMOD http://127.0.0.1/heizung.php 300
attr H_Summary userattr reading01JSON reading01Name reading02JSON reading02Name reading03JSON reading03Name reading04JSON reading04Name reading05JSON reading05Name reading06JSON reading06Name reading07JSON reading07Name
attr H_Summary enableControlSet 1
attr H_Summary reading01JSON t_inhouse
attr H_Summary reading01Name t_inhouse
attr H_Summary reading02JSON t_setpoint
attr H_Summary reading02Name t_setpoint
attr H_Summary reading03JSON t_outdoor
attr H_Summary reading03Name t_outdoor
attr H_Summary reading04JSON boiler
attr H_Summary reading04Name boiler
attr H_Summary reading05JSON pressure
attr H_Summary reading05Name pressure
attr H_Summary reading06JSON yearTotal
attr H_Summary reading06Name yearTotal
attr H_Summary reading07JSON actualSupplyTemperature
attr H_Summary reading07Name actualSupplyTemperature
attr H_Summary room Heizung



Gruß
Mike

SouzA

Hi,

Bei mir ist es auch immer recht voll, zeitlich gesehen. Also alles kein Problem.  ;)

Gehe ich recht in der Annahme, dass das Script dann im www Ordner des Raspis liegt auf dem fhem installiert ist? Hast du dazu apache installiert?

Bis denn
SouzA
Raspi 4, EnOcean TCM310 USB, HM-MOD-UART-USB, Jeelink, hue, AMAD, fully, FRITZBOX, Signalbot, VIERA, Presence BT/Mac, TPLink, Gassistant, Shelly, fhempy, ZigBee

Mike_GKA

Hallo,

hatte ich nicht aufgeführt, aber klar, ein http-Server wie Aapche muss installiert sein. Eventuell geht es auch ohne, wenn man das Skript aus fhem direkt ausführt, aber wie, da bin ich überfragt. Es steckt ja auch nicht allzu viel hinter dem Skript, das lässt sich sicher auch in js oder perl nachstricken.
Ich habe eh immer LAMP auf dem Raspberry auch für einige andere Aufgaben.
Und das Skript steht dann natürlich unter /var/www/html.

Noch zu dem automatischem Start mit pm2.

sudo pm2 startup

sollte das Problem lösen. Habe ich jetzt auch Eingangs korrigiert.
Das hatte ich vergessen, da ich eh pm2 noch für andere Aufgaben nutze.

Gruß
Mike

SouzA

#20
Habs nun erstmal zum laufen bekommen.

Rennt jetzt zunächst auf einem anderen Raspi testweise, bevor ich das auf den fhem Raspi ziehe.
Mal gucken, was einem dazu noch alles einfällt :)
Vielen Dank bis hierher ;D

Was nicht funktioniert ist, eine neue Solltemp zu setzen.
Weder vom fhem Raspi noch vom "Junkers" Raspi.
Das Mobil-Symbol auf dem CT100 erscheint zwar. Aber ändern tut sich nix.

Was ich noch sehr spannend finde:
t_inhouse ist nicht die Aktuelle Raumtemperatur in der APP, gleicht sich aber mit der Temperatur, die auf dem CT100 angezeigt wird...

Außerdem tue ich mich gerade ein wenig schwer mit den endpoints.
Irgendwie ist für mich nun nicht wirklich ersichtlich, welches davon Vorlauf Temp und welches Wasser Temp ist.
Hast du das schonmal rausgefunden?

Nach Internetrecherche gehe ich nun davon aus, dass actualSupplyTemperature die Vorlauf Temp ist.
Raspi 4, EnOcean TCM310 USB, HM-MOD-UART-USB, Jeelink, hue, AMAD, fully, FRITZBOX, Signalbot, VIERA, Presence BT/Mac, TPLink, Gassistant, Shelly, fhempy, ZigBee

Mike_GKA

Es ist tatsächlich ein großes Handicap, dass die endpoints so gut wie gar nicht beschrieben sind.
Da bleibt häufig nur raten und probieren. Gute Hinweise wie es eventuell gehen könnte findet man bei den anderen Heizungssteuerungen KM200 und BDKM, da ja letztendlich darunter eine sehr ähnliche Logik stecken muss. Auch das Studium der Quellen von nefit-easy-commands gibt manchmal Hinweise.
Es gibt starke Indizien dafür, dass letztendlich die CT100-App für Smartphone auch die Quellen von nefit-easy-core nutzt. nefit-easy-commands ist letztendlich wohl ein API für nefit-easy-core und der nefit-easy-http-server setzt über alles dann einen http-Server.

Was ich bisher herausgefunden habe und zumindest bei mir anstandlos funktioniert:

1. Temperatur manuell setzen:
Hierzu muss man auf den manuellen Modus umschalten und die Soll-Temperatur übergeben:

curl -XPOST http://127.0.0.1:3000/bridge/heatingCircuits/hc1/usermode -d '{"value":"manual"}' -H 'Content-Type: application/json'
curl -XPOST http://127.0.0.1:3000/bridge/heatingCircuits/hc1/temperatureRoomManual -d '{"value":23}' -H 'Content-Type: application/json'

So wird die Soll-Temperatur auf 23° gesetzt.

Um wieder in den automatischen Modus zu gelangen:

curl -XPOST http://127.0.0.1:3000/bridge/heatingCircuits/hc1/usermode -d '{"value":"clock"}' -H 'Content-Type: application/json'


2. Vorlauftemperatur:
Das ist in der Tat "actualSupplyTemperature".
Da ich das Ganze schon eine Weile am Laufen habe und die Daten protokolliere, kann ich sehr gut sehen ,wie "actualSupplyTemperature" beim Einschalten des Brenners steigt und beim Abschalten wieder sinkt. Auch die maximale Vorlauftemperatur, die ich am Brenner direkt einstellen kann, wird dabei nicht überschritten.

3. t_inhouse:
deckt sich bei mir mit der Anzeige auf der CT100 und der CT100-App auf dem Smartphone. Lediglich wird nur unterschiedlich gerundet.
Es wird auch der Kalibrierungswert aus der CT100-App berücksichtigt.

mondface

#22
ich benutze "easy set temperature 20" als shell script und rufe dies über die ha-bridge als execute command auf:
Alexa schalte Heizung ein -> 20 Grad
Alexa dimme Heizung 20,5 Grad
Alexa schalte Heizung aus: 15 Grad

Das funktioniert im automatischen Modus!

Leider kann ich nicht sagen, erhöhe um 1 Grad, da ich den easy Befehl dafür nicht kenne ....

pyrlix

Servus, bin auch am experimentieren mit meinem CT100 Regler und dem EASY-Server.
Kann man die Raumwunschtemperatur nicht irgendwie über HTTPMOD setzen? Ich habe jetzt versucht das Thermostat über folgende Definition zu steuern

defmod Thermostat_Wohn HTTPMOD http://192.168.2.105:3000/bridge/heatingCircuits/hc1/temperatureRoomManual 60
attr Thermostat_Wohn userattr set1Name set1Replacement01Value
attr Thermostat_Wohn set1Name WohnTemp
attr Thermostat_Wohn set1Replacement01Value replaceJSON("value", 22)


Jedoch passiert beim setzen der Temperatur nichts, die Temperatur die am Regler sowie in der API angezeigt wird bleibt da angetackert wo sie ist.

Mike_GKA

Hallo pyrlix,
so kann es eigentlich nicht funktionieren, da dies ein http-get wäre und der EASY-Server ein http-post braucht.
Ich kenne mich jetzt mit HTTPMOD nicht so besonders aus, aber laut Wiki https://wiki.fhem.de/wiki/HTTPMOD müsste man das doch mit attr requestData hinbekommen.
Eventuell musst Du auch noch den Header anpassen. Dazu gibt es attr requestHeader...

Im Wiki ist ein Beispiel für einen  Poolmanager, da steht unter anderem

attr PM requestData {"get" :["34.4001.value" ,"34.4008.value" ,"34.4033.value", "14.16601.value", "14.16602.value"]}
attr PM requestHeader1 Content-Type: application/json


Das könntest Du doch mal "abkupfern". Müsste dann wohl ähnlich  ...requestData {"value":22} heißen.
Mit fehlt aktuell die Zeit, das selbst auszuprobieren.
Wenn Du es hinbekommst, wäre es auch schön die Lösung hier zu finden.

pyrlix

Danke Mike!

Habs  nach viel experimentieren hinbekommen!


defmod Thermostat_Wohn HTTPMOD http://192.168.2.105:3000/bridge/heatingCircuits/hc1/temperatureRoomManual 15
attr Thermostat_Wohn userattr set1Data set1Header set1Name
attr Thermostat_Wohn set1Data {"value":$val}
attr Thermostat_Wohn set1Header Content-Type: application/json
attr Thermostat_Wohn set1Name WohnTemp

setstate Thermostat_Wohn 2017-11-25 14:39:37 value 18


Beim setten von "WohnTemp" passt sich der Para in der "Control"-App sowie dem Thermostat an - kurzum, es funktioniert.

Mike_GKA

Prima und Danke! Und wenn man es weiß, eigentlich gar nicht so schwer.
Eines würde ich noch ändern

defmod Thermostat_Wohn HTTPMOD http://192.168.2.105:3000/bridge/heatingCircuits/hc1/temperatureRoomManual 15

Die "15" am Ende besagt ja jetzt, dass dies alle 15 Sek. aufgerufen wird.
Mit:

defmod Thermostat_Wohn HTTPMOD http://192.168.2.105:3000/bridge/heatingCircuits/hc1/temperatureRoomManual 0

wird es nur noch einmal bei "setstate" aufgerufen.

Dann noch eine Frage:
Hast Du "heatingCircuits/hc1/usermode" immer auf "manual" sitzen? Bei mir funktioniert es nur wenn ich es auf "manual" setze, da ich ja im Normalbetrieb die Heizung über "clock" steuer.

pyrlix

Danke Mike, werde ich so umsetzen! Macht sogar Sinn, weniger polling.

Ich habs Thermostat generell immer auf manuell stehen, den Raum muss ich sowieso heizen, wenn ich nachts auf 16 runter gehe und tags wieder auf 18 oder 20 hoch muss braucht das (finde ich) mehr Gas, als wenn ich konstant auf 18-20°C halten lasse. Zumal ich Witterungsgeführt mit mittlerem Raumanteil fahre, laut der Gasverbrauchsanzeige ist das bisher das ökonomischste.

Jetzt muss ich nurnoch die Temperatureinstellung vom Thermostat an der Heizung weiterleiten ans CT100, den Wert in FHem hab ich ja schon (CCU2 mit dem HmIP TRV) - wobei ich debattiere den dort rauszuschmeißen und einfach ne Kappe auf das Ventil stecke.

Mike_GKA

Seit gestern bekomme ich bei jeder Abfrage die Fehlermeldung: XMPP authentication failure
Zusätzlich fiel mir auf, dass die Grundlast des Raspberry (CPU) signifikant angestiegen íst.

Zum Glück hat der Autor der nefit-easy SW Robert Klep sehr schnell darauf reagiert. Gefunden auf https://www.domoticz.com/forum/viewtopic.php?f=34&p=181905.

Nach
sudo npm update nefit-easy-http-server -g
läuft alles wieder normal.

SouzA

Hi,

ich habe neuerdings das Problem, dass der nefit sich nach der Zwangstrennung zum ISP, bzw. nach dem Zuvorkommen der FritzBox, nicht mehr mit dem Server verbindet.
Dementsprechend habe ich Fehlermeldungen im log:
2018.06.21 05:10:02 3: Therme: Read callback: Error: read from http://127.0.0.1:80 timed out
2018.06.21 05:15:02 3: Therme: Read callback: Error: read from http://127.0.0.1:80 timed out
2018.06.21 05:20:02 3: Therme: Read callback: Error: read from http://127.0.0.1:80 timed out
2018.06.21 05:25:02 3: Therme: Read callback: Error: read from http://127.0.0.1:80 timed out
2018.06.21 05:30:02 3: Therme: Read callback: Error: read from http://127.0.0.1:80 timed out
2018.06.21 05:35:02 3: Therme: Read callback: Error: read from http://127.0.0.1:80 timed out
2018.06.21 05:40:02 3: Therme: Read callback: Error: read from http://127.0.0.1:80 timed out
2018.06.21 05:45:02 3: Therme: Read callback: Error: read from http://127.0.0.1:80 timed out
2018.06.21 05:50:02 3: Therme: Read callback: Error: read from http://127.0.0.1:80 timed out
2018.06.21 05:55:02 3: Therme: Read callback: Error: read from http://127.0.0.1:80 timed out
2018.06.21 06:00:02 3: Therme: Read callback: Error: read from http://127.0.0.1:80 timed out
2018.06.21 06:05:02 3: Therme: Read callback: Error: read from http://127.0.0.1:80 timed out
2018.06.21 06:10:02 3: Therme: Read callback: Error: read from http://127.0.0.1:80 timed out
2018.06.21 06:15:02 3: Therme: Read callback: Error: read from http://127.0.0.1:80 timed out
2018.06.21 06:20:02 3: Therme: Read callback: Error: read from http://127.0.0.1:80 timed out
2018.06.21 06:25:02 3: Therme: Read callback: Error: read from http://127.0.0.1:80 timed out
2018.06.21 06:30:02 3: Therme: Read callback: Error: read from http://127.0.0.1:80 timed out


Bis dato hilft mir nur der Raspi-Neustart.
Kriegt man den reconnect des Nefit auch über FHEM, bzw. automatisch wieder hin?

Vielen Dank und bis denn
SouzA
Raspi 4, EnOcean TCM310 USB, HM-MOD-UART-USB, Jeelink, hue, AMAD, fully, FRITZBOX, Signalbot, VIERA, Presence BT/Mac, TPLink, Gassistant, Shelly, fhempy, ZigBee

Mike_GKA

Hi,
Dieser Fehler taucht bei mir auch immer wieder auf, wobei der Timeout ein Folgefehler sein muss. Ursprünglich hatte ich angenommen, dass dieser Fehler "nur" bei mir auftaucht, da ich einiges an meinem Raspberry "herumgeschraubt" hatte.
Ich habe den Log von nefit durchforstet. Er steht bei mir unter /root/.pm2/logs/start-nefit-easy-http-server-out-1.log. Den Pfad bekommt man heraus über:

sudo pm2 show start_nefit-easy-http-server

Hier finde ich dann als Ursache "Error: MAX_RETRIES_REACHED"
Dieser Fehler wurde auch schon an Robert Klep gemeldet: https://github.com/robertklep/nefit-easy-http-server/issues/15
Der letzte Eintrag: 11.6.18: "I'm still working on trying to find a fix."

Den Zusammenhang mit "Zwangstrennung" bzw. "Neuverbindung" habe ich nicht erkannt. Aber da scheint was dran zu sein. In meinem Logfile (2 MB) finde ich lediglich 3 Ausnahmen, wobei ich nicht analysieren kann, ob da wegen Provider Störungen nicht auch eine Neuverbindung stattfand.

Als recht unsaubere Umgehungslösung habe ich jetzt folgendes gemacht:
Ich habe ein Skript angelegt mit:


#!/bin/bash
sudo pm2 stop start_nefit-easy-http-server
sudo pm2 start start_nefit-easy-http-server


Und starte dieses per Cron stündlich.

Ich hoffe, Robert Klep findet bald eine Lösung.
Es gibt wohl die Vermutung, dass dieser Fehler mit einem anderen Problem zusammenhängt: https://github.com/robertklep/nefit-easy-core/issues/14
Und hier gibt es Hoffnung.
Robert Klep Gestern: Let's keep it running for a day or so, if no other issues emerge I'm going to declare this a win (at least for you and me) and push a new version :D


SouzA

Moin!
Mit Antworten bist du ja immer schnell... ;D ;)
Auf der Github-Seite habe ich mittlerweile auch die Aussage gefunden, dass er an etwas bastelt. Wir warten...

Frage zu
Zitat von: Mike_GKA am 21 Juni 2018, 11:22:24
Als recht unsaubere Umgehungslösung habe ich jetzt folgendes gemacht:
Ich habe ein Skript angelegt mit:


#!/bin/bash
sudo pm2 stop start_nefit-easy-http-server
sudo pm2 start start_nefit-easy-http-server


Und starte dieses per Cron stündlich.

Kann man dieses Script nicht starten und stoppen, wenn im Log die Fehlermeldungen auftauchen?
So etwa:

define di_nefit_restart DOIF
dev:
([":^Read callback: Error: read from http://127.0.0.1:80 timed out"])
({system(STOP);;return 0})
({system(START);;return 0})
attr wait 0,30
attr do always


Wobei ich nicht weiß, wie in einem DOIF die Ausführungen heißen müssen?!
Weißt du das?

Bis denn
SouzA
Raspi 4, EnOcean TCM310 USB, HM-MOD-UART-USB, Jeelink, hue, AMAD, fully, FRITZBOX, Signalbot, VIERA, Presence BT/Mac, TPLink, Gassistant, Shelly, fhempy, ZigBee

Mike_GKA

Hi,

gute Idee, aber so richtig kenne ich mich an dieser Ecke auch nicht aus.
Meiner Meinung müsste es wie folgt heißen:
({system(sudo <Pfad-Name zum Restart-Skript>);;return 0})
und ein "else" braucht man nicht.

Funktioniert das mit "([":^Read callback: Error: read from http://127.0.0.1:80 timed out"])", ist mir nämlich auch unbekannt.

Folgende Alternative ist vielleicht einfacher. Man erweitert das Skript zum Restart.
Folgendes kann vielleicht funktionieren:

#!/bin/bash
if curl http://127.0.0.1:3000/api/status | grep -q "timeout"
then
sudo pm2 stop start_nefit-easy-http-server
sudo pm2 start start_nefit-easy-http-server
fi


Ich habe das jetzt nicht ausprobiert!

SouzA

Zitat von: Mike_GKA am 21 Juni 2018, 14:28:41
Funktioniert das mit "([":^Read callback: Error: read from http://127.0.0.1:80 timed out"])", ist mir nämlich auch unbekannt.

Aus der commandref von DOIF:
([":^temp"]) triggert auf beliebige Devices, die im Event mit "temp" beginnen

ich denke schon.
Raspi 4, EnOcean TCM310 USB, HM-MOD-UART-USB, Jeelink, hue, AMAD, fully, FRITZBOX, Signalbot, VIERA, Presence BT/Mac, TPLink, Gassistant, Shelly, fhempy, ZigBee

Mike_GKA


Automatischer Restart nefit-easy


Das war gar nicht so leicht, wie zuerst angenommen.
Wenn man auf die Fehlermeldung von netfit-easy triggert und ein Restart macht, dann kommt es in aller Regel vor, dass dieser Restart ein zweites und evtl. noch weitere Male ausgelöst wird, bevor der erste Restart ordnungsgemäß beendet wurde. Das muss man vermeiden.
Ich habe deshalb ein Skript geschrieben, das überprüft ob es bereits läuft.
Um etwas Übersicht zu haben, habe ich unter /home/pi ein Subdirectory angelegt: /home/pi/Progs.
Dort habe ich das Skript "php_shell.sh" angelegt mit dem Inhalt

#!/bin/bash

lockdir=/home/pi/Progs/LogDirToAvoidProcessStartWhenAlreadyRunning
mkdir $lockdir  || {
sudo date >> /home/pi/Progs/restart_nefit.log
sudo echo "Process already running" >> /home/pi/Progs/restart_nefit.log
sudo echo ------------------- >> /home/pi/Progs/restart_nefit.log
exit 1
}

# take pains to remove lock directory when script terminates
trap "rmdir $lockdir" EXIT INT KILL TERM


sudo date >> /home/pi/Progs/restart_nefit.log
sudo echo Restart nefit-easy-http-server >> /home/pi/Progs/restart_nefit.log

sudo pm2 stop start_nefit-easy-http-server
sudo pm2 start start_nefit-easy-http-server

sleep 10

sudo echo Restart finished >> /home/pi/Progs/restart_nefit.log
sudo date >> /home/pi/Progs/restart_nefit.log
sudo echo ------------------- >> /home/pi/Progs/restart_nefit.log


Der Name "php_shell.sh" mag hier etwas irritieren (man kann es ja auch anders nennen), aber ich selbst verwende das ausschließlich aus php heraus (s.u.).

Jetzt sollte man aus fhem heraus dieses Skript im Fehlerfall aufrufen:

{system(sudo /home/pi/Progs/php_shell.sh);;return 0}

Dies habe ich nicht ausprobiert, da ich das Skript anderweitig verwende.
Die Logdatei findet man unter /home/pi/Progs/restart_nefit.log.

Ich rufe nefit-easy auch aus anderen Anwendungen heraus auf. Dazu habe ich eine kleine php-Anwendung, die alle Aufrufe kapselt. In dieser php-Anwendung prüfe ich jetzt ob das Ergebnis von nefit-easy korrekt ist, bzw, ob ein Fehler gemeldet wurde. Im Falle eines Fehlers rufe ich obiges Skript auf.
ABER, aus php heraus kann man i.A. kein "sudo" machen. Das wäre ja sicherheitstechnisch irgendwo worstcase. Deshalb habe ich einen kleinen Wrapper geschrieben, der sich root Rechte holt und damit das Skript ausführt.

Das ist dann ein kleines C-Programm (wrapper.c), das ich auch auf /home/pi/Progs anlege:


#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>

int
main (int argc, char **argv)
{
setuid (0);
if (argc == 2) {
char str[255];
strcpy(str, "/bin/sh /home/pi/Progs/");
strcat(str , argv[1]);
system (str);
} else {
system ("/bin/sh /home/pi/Progs/php_shell.sh");
}

return 0;
}


Das muss man dann natürlich übersetzen und die Eigenschaften entsprechend setzen.

gcc wrapper.c -o php_root
sudo chown root php_root
sudo chmod u=rwx,go=xr,+s php_root


Das aufrufbare Programm heißt jetzt also: /home/pi/Progs/php_root

Die kleine php-Anwendung, die alle Aufrufe kapselt, heißt bei mir nefit.php und steht natürlich im www-Verzeichnis (/var/www/html)

<?php

$basicurl "http://127.0.0.1:3000";
$defaultapicall "/api/status";

$_GET_lower array_change_key_case($_GETCASE_LOWER);
$apicall $_GET_lower['api'] ;
if(empty($apicall)) {
$apicall $defaultapicall;


$data file_get_contents($basicurl $apicall);


$pos strpos($data '{"'); //check if the result is possible a json-string
if ($pos === false) {
     exec('/home/pi/Progs/php_root'); //result cannot be a json, restart nefit-easy

else {
if ($pos != 0) {
     exec('/home/pi/Progs/php_root'); //result cannot be a json, restart nefit-easy
}
}

ob_end_clean();
header("Connection: close\r\n");
header('Content-Type: application/json');
ob_start();
Echo $data;
$size ob_get_length();
header("Content-Length: $size");
ob_end_flush();
flush();

?>



Mittels file_get_contents wird also nefit-easy abgefragt. Das Ergebnis wird analysiert. Wenn es nicht korrekt als JSON aufgebaut ist, gehe ich von einem Fehler aus und starte nefit-easy neu exec('/home/pi/Progs/php_root')
Im korrekten Fall wird einfach das Ergebnis weitergereicht.

nefit.php versteht einen Parameter "api" in der URL. Damit wird gezielt der api-Aufruf von nefit-easy gesteuert.
Also z.B.:
http://127.0.0.1/nefit.php?api=/api/status
http://127.0.0.1/nefit.php?api=/bridge/heatingCircuits/hc1/actualSupplyTemperature
usw.

Für fhem habe ich eine php-Anwendung (heizung.php), die viele Werte aus nefit-easy abfragt und als JSON an fhem gibt:

<?php

$basicurl "http://127.0.0.1/nefit.php";
$result = array();

$json json_decode(file_get_contents($basicurl "?api=/api/status"), true);
$result['t_inhouse'] = $json['in house temp'];
$result['t_setpoint'] = $json['temp setpoint'];
$result['t_outdoor'] = $json['outdoor temp'];
if ($json['boiler indicator'] == "off") {
$result['boiler'] = 0;
} else {
$result['boiler'] = 1;
}

$json json_decode(file_get_contents($basicurl "?api=/api/pressure"), true);
$result['pressure'] = $json['pressure'];

$json json_decode(file_get_contents($basicurl "?api=/bridge/ecus/rrc/recordings/yearTotal"), true);
$result['yearTotal'] = $json['value'];

$json json_decode(file_get_contents($basicurl "?api=/bridge/heatingCircuits/hc1/actualSupplyTemperature"), true);
$result['actualSupplyTemperature'] = $json['value'];

header('Content-Type: application/json');
Echo json_encode($result);
?>



Dies hole ich mit HTTPMOD in fhem ab und parse die JSON Felder.

defmod heizung HTTPMOD http://127.0.0.1/heizung.php 300
attr heizung userattr reading01JSON reading01Name reading02JSON reading02Name reading03JSON reading03Name reading04JSON reading04Name reading05JSON reading05Name reading06JSON reading06Name reading07JSON reading07Name
attr heizung enableControlSet 1
attr heizung reading01JSON t_inhouse
attr heizung reading01Name t_inhouse
attr heizung reading02JSON t_setpoint
attr heizung reading02Name t_setpoint
attr heizung reading03JSON t_outdoor
attr heizung reading03Name t_outdoor
attr heizung reading04JSON boiler
attr heizung reading04Name boiler
attr heizung reading05JSON pressure
attr heizung reading05Name pressure
attr heizung reading06JSON yearTotal
attr heizung reading06Name yearTotal
attr heizung reading07JSON actualSupplyTemperature
attr heizung reading07Name actualSupplyTemperature


Dies läuft jetzt bei mir seit 3 Tagen fehlerfrei.

SouzA

#35
Hi,
Da hat aber jemand gebastelt. Respekt dafür.

Ich musste das für mich einfacher Regeln.
Ich hatte beobachtet, dass die Readings aus dem JSON nicht mehr aktualisiert werden, wenn der nefit weg ist. Auch die Zeitstempel werden nicht mehr aktualisiert.

define restart_nefit-easy-http-server DOIF
(
[Therme:actualSupplyTemperature]
)
({system('sudo pm2 restart /home/pi/start_nefit-easy-http-server.sh');;return 0})

attr do resetwait
attr wait 950


Wenn jetzt innerhalb 950 Sekunden das Reading aktualisiert wird, dann wird das Wait zurück gesetzt und beginnt von vorne.

Btw. Das funktioniert dann natürlich nur mit pm2. Dementsprechend ist mein Startscript aus dem rc.local geflogen und wird jetzt von pm2 gestartet und gestopt.
Ja, ich hab pm2 doch noch installiert bekommen... ;)

Bis denn
SouzA

Raspi 4, EnOcean TCM310 USB, HM-MOD-UART-USB, Jeelink, hue, AMAD, fully, FRITZBOX, Signalbot, VIERA, Presence BT/Mac, TPLink, Gassistant, Shelly, fhempy, ZigBee

Mike_GKA

echt raffiniert und um Längen einfacher als meine Lösung.
Ich musste erst im fhem-wiki nachlesen, wie das funktioniert: resetwait und wait kannte ich bei DOIF noch gar nicht.

Leider löst das bei mir aber "nur" gut 90 % der Probleme, da ich nefit-easy auch aus nicht-fhem-Applikaitonen vielfach nutze.

SouzA

Naja, eben. Hatte schon erkannt, dass deine Ausarbeitung für größeres bestimmt ist.
Nur deshalb habe ich die vereinfachte Version hier gebracht, falls jemand den Nefit, so wie ich, nur aus fhem benutzt.

Bis denn
SouzA
Raspi 4, EnOcean TCM310 USB, HM-MOD-UART-USB, Jeelink, hue, AMAD, fully, FRITZBOX, Signalbot, VIERA, Presence BT/Mac, TPLink, Gassistant, Shelly, fhempy, ZigBee

SouzA

#38
Hi, ich hätte da gerne mal wieder ein Problem...

Hab nach einer kleinen Havarie den Raspi neu aufgesetzt.
Was ich mir damals nicht notiert hatte war, dass ich dem User fhem Root-Rechte verpasst hatte. Is soweit auch nicht schlimm, wenn der Pi nicht von außen erreichbar ist. Allerdings hat sich bei mir die Nutzung der Sprachsteuerung eingeschlichen und der pi ist von außen erreichbar.
Dementsprechend will ich dem User fhem nicht alle Rechte zusprechen.
Allerdings nun die Frage, wie kann ich pm2 jetzt den restart-Befehl geben?

Hat da jemand einen Tipp?

Vielen Dank
Bis denn
SouzA

EDIT: Gelöst!
Meine Doku enthält nun folgendes:
ZitatUm ein Restart des nefit-servers durchführen zu können und zusätzlich den User fhem keine root-Rechte verpassen zu müssen erstellen wir ein zusätzliches script:
→ sudo nano /home/pi/restart_nefit.sh
Dieses script mit
#!/bin/sh
sudo pm2 restart /home/pi/start_nefit-easy-http-server.sh
füllen.
Um dem User fhem die Rechte zum ausführen zu geben, bearbeiten wir die sudoers Datei:
   → sudo nano /etc/sudoers
Am Ende folgende Zeile anfügen:
   → fhem ALL=NOPASSWD: /home/pi/restart_nefit.sh, /home/pi/next.sh
Damit hat fhem die root-Rechte nur zum ausführen des Scripts.
Raspi 4, EnOcean TCM310 USB, HM-MOD-UART-USB, Jeelink, hue, AMAD, fully, FRITZBOX, Signalbot, VIERA, Presence BT/Mac, TPLink, Gassistant, Shelly, fhempy, ZigBee

Mike_GKA

Das ist ja das gleiche Problem wie ich mit dem Aufruf aus php hatte.
In https://forum.fhem.de/index.php?topic=74483.msg814386#msg814386 ist das ja beschrieben.

Hier der wesentliche Auszug:
Deshalb habe ich einen kleinen Wrapper geschrieben, der sich root Rechte holt und damit das Skript ausführt.

Das ist dann ein kleines C-Programm (wrapper.c), das ich auch auf /home/pi/Progs anlege:


#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>

int
main (int argc, char **argv)
{
setuid (0);
if (argc == 2) {
char str[255];
strcpy(str, "/bin/sh /home/pi/Progs/");
strcat(str , argv[1]);
system (str);
} else {
system ("/bin/sh /home/pi/Progs/php_shell.sh");
}

return 0;
}


Das muss man dann natürlich übersetzen und die Eigenschaften entsprechend setzen.

gcc wrapper.c -o php_root
sudo chown root php_root
sudo chmod u=rwx,go=xr,+s php_root


Das aufrufbare Programm heißt jetzt also: /home/pi/Progs/php_root

php_root besorgt sich jetzt die root-Rechte (sudo) und führt damit das Skript aus.

Die Namen php_root und php_shell.sh sind jetzt in Deinem Kontext natürlich nicht besonders sinnvoll, und solltest Du bei Bedarf entsprechend anpassen.

Übrigens: Es gibt ein Update vom nefit-easy, das das ursächliche Problem beseitigen sollte.
Ich habe bei mir letzte Woche dieses Update eingespielt. Allerdings taucht das Problem weiterhin auf, wenn auch wesentlich seltener und im Kontext etwas anders. Ich habe aber den Eindruck, dass das schlicht und einfach daran liegt, dass Server temporär immer mal wieder überhaupt nicht erreichbar ist. Da kann man dann softwaremäßig eh nichts mehr machen.

grappa24

#40
hat schon mal jemand von Euch ein CT200 mit dem netfit-easy-server angesprochen?

Ich kann zwar meine Heizung via CT200 und der Bosch EasyControl app (Android) steuern, bekomme aber keinen Zugriff via netfit-easy-server (XMPP authentication failure).
FHEM 6.3, 2 x RasPi 3B+, Debian Buster; KNX, FS20, HM, HUE, Tradfri, Shellies, KLF200
Rollo-/Lichtsteuerung/-szenarien, T-Sensoren, Fensterkontakte, Heizungssteuerung, HEOS, Sprachsteuerung mit Alexa-FHEM, Netatmo, Nuki, ...

Mike_GKA

Dieses Problem wurde auch schon an Robert Klep gemeldet: https://github.com/robertklep/nefit-easy-http-server/issues/30
Aber Robert Klep hat keinen Zugriff auf eine CT200, d.h. ich befürchte, da wird es so schnell keine Lösung geben.
Auch ich habe keine CT200, kann also reineweg nichts machen, sorry.
Wie es scheint wurde die Authentifizierung geändert.
Da Bosch das nicht transparent macht und alles verschlüsselt abläuft, ist es sehr schwer bis unmöglich, das zu "knacken". Da müsste man mit "man in the middle attack" ran, und das wäre eh nichts für meine eher bescheidenen Fähigkeiten.

grappa24

Danke Mike, dann kann ich mich ja jetzt entspannen  ;)  ... und ggf abwarten  :(
FHEM 6.3, 2 x RasPi 3B+, Debian Buster; KNX, FS20, HM, HUE, Tradfri, Shellies, KLF200
Rollo-/Lichtsteuerung/-szenarien, T-Sensoren, Fensterkontakte, Heizungssteuerung, HEOS, Sprachsteuerung mit Alexa-FHEM, Netatmo, Nuki, ...

grappa24

"Wenn der Berg nicht zum Propheten kommt .... "   ;)

Ich hab mir jetzt einen gebrauchten CT100 zum Testen bestellt, brauche den ganzen Schnickschnack des CT200 eh nicht ...  8)
(keine Anwesenheitserkennung, kein Näherungssensor, keine Thermostatsteuerung, ...) Hauptsache FHEM-Anbindung
FHEM 6.3, 2 x RasPi 3B+, Debian Buster; KNX, FS20, HM, HUE, Tradfri, Shellies, KLF200
Rollo-/Lichtsteuerung/-szenarien, T-Sensoren, Fensterkontakte, Heizungssteuerung, HEOS, Sprachsteuerung mit Alexa-FHEM, Netatmo, Nuki, ...

grappa24

CT100 angekommen, funktioniert perfekt wie hier beschrieben mit dem netfit-easy-server. Würde ihn aber gern wieder verkaufen, da ich auf CW400/MB LAN2/Heatronic-Modul umsteigen werde. Bei Interesse gerne PN.


FHEM 6.3, 2 x RasPi 3B+, Debian Buster; KNX, FS20, HM, HUE, Tradfri, Shellies, KLF200
Rollo-/Lichtsteuerung/-szenarien, T-Sensoren, Fensterkontakte, Heizungssteuerung, HEOS, Sprachsteuerung mit Alexa-FHEM, Netatmo, Nuki, ...

SouzA

Moin,

es gibt eine neue Art das CT100 und andere nefit-Devices auzulesen und zu steuern.
Das funktioniert mit fhempy.
https://github.com/dominikkarall/fhempy

Dominik hat da bereits ganze Arbeit geleistet und auf meinen Wunsch hin nun auch das nefit mit aufgenommen.
https://github.com/dominikkarall/fhempy/blob/master/FHEM/bindings/python/fhempy/lib/nefit/README.md

Ist noch in der Erprobungsphase, Werte auslesen funktioniert aber schon. Mode-Umschaltung auch. Mit den Temps haben wir noch kleine Probleme. Aber da bin ich zuversichtlich.
Ich denke, wenn sich noch Tester finden würden, wäre das ganz hilfreich.
Anbei ein Screenshot der Readings.

Bis denn
SouzA
Raspi 4, EnOcean TCM310 USB, HM-MOD-UART-USB, Jeelink, hue, AMAD, fully, FRITZBOX, Signalbot, VIERA, Presence BT/Mac, TPLink, Gassistant, Shelly, fhempy, ZigBee