Hoe ik mijn Nefit Easy thermostaat bedien met Home Assistant

Door balk op dinsdag 25 september 2018 20:29 - Reacties (3)
Categorie: -, Views: 2.541

Zie deze post.

Ik wilde onze Nefit Easy kunnen besturen met Home Assistant. Maar ik kon geen component vinden die dat mogelijk kon maken. (er is er intussen wel een).
Globale stappen
1) Ik heb de python Nefit Easy HTTP Server draaien. Die opent een http server die je kan aanspreken met
2) Node Red om elke zoveel seconden te informeren wat de status is van de Nefit Easy thermostaat: ingestelde temperatuur, operatie modus en nog wat zaken. De Node Red flow stopt dat in een MQTT topic dat door HASS wordt uitgelezen
3) Door middel van de Hass Climate MQTT HVAC component heb ik een thermostaat in HASS die de status uitleest van bovenstaande MQTT topics
4) Ik heb een AppDaemon script dat reageert op een MQTT topic om de temperatuur in te stellen. Dit script roept 3 endpoints van de Nefit Easy HTTP server aan om de temperatuur in te stellen. Vervolgens pollt Node Red weer de HTTP server en wordt de nieuwe ingestelde temperatuur weer aan HASS doorgegeven.
Nefit Easy Server
Dit pakket praat met de Nefit cloud, waarmee ook de app op mijn telefoon en natuurlijk de thermostaat zelf communiceert.
Node Red flow:
Vanuit Node Red wordt elke zoveel seconden de status opgevraagd aan het pyhton script hierboven. De resultaten worden in enkele MQTT telegrammen gestopt voor verdere verwerking.

code:
1
[{"id":"41151e3f.3383e","type":"tab","label":"Nefit"},{"id":"c03c0e01.75cb3","type":"http request","z":"41151e3f.3383e","name":"","method":"GET","ret":"txt","url":"http://192.168.0.9:8124/bridge/ecus/rrc/uiStatus","tls":"","x":538.5,"y":146,"wires":[["cdb1fbde.fd35d8","5d90adf3.160804","28ec33bd.11d44c","feecaa72.399178","d6366363.501d","ae42c889.77b0c8","15cc82c4.7d3c8d"]]},{"id":"85019b50.4bca78","type":"inject","z":"41151e3f.3383e","name":"","topic":"","payload":"","payloadType":"date","repeat":"10","crontab":"","once":false,"onceDelay":"","x":310,"y":140,"wires":[["c03c0e01.75cb3"]]},{"id":"cdb1fbde.fd35d8","type":"function","z":"41151e3f.3383e","name":"BAI","func":"var data = JSON.parse(msg.payload);\nmsg.payload = data.value.BAI;\n\n//if (msg === \"No\" or msg === \"CH\" or msg === \"HW\") {\n    return msg;\n//}","outputs":1,"noerr":0,"x":742.5,"y":146,"wires":[["b8c9c4e2.56d2b8","db7e1433.7a2d98"]]},{"id":"b8c9c4e2.56d2b8","type":"debug","z":"41151e3f.3383e","name":"","active":false,"console":"false","complete":"false","x":1099.8332824707031,"y":116.00000667572021,"wires":[]},{"id":"15cc82c4.7d3c8d","type":"debug","z":"41151e3f.3383e","name":"","active":false,"console":"false","complete":"false","x":871.5,"y":107,"wires":[]},{"id":"5d90adf3.160804","type":"json","z":"41151e3f.3383e","name":"","x":712.5,"y":108,"wires":[["15cc82c4.7d3c8d"]]},{"id":"28ec33bd.11d44c","type":"function","z":"41151e3f.3383e","name":"IHT (measured Temp)","func":"var data = JSON.parse(msg.payload);\nmsg.payload = data.value.IHT;\n\nreturn msg;","outputs":1,"noerr":0,"x":792.5,"y":376,"wires":[["e912d7a.8d6a428"]]},{"id":"ebe95643.b53498","type":"mqtt out","z":"41151e3f.3383e","name":"","topic":"woonkamer/woonkamer/thermostaat/gemetentemperatuur","qos":"","retain":"true","broker":"716d90a0.a6a12","x":1300,"y":380,"wires":[]},{"id":"dd1ecb0a.adafd8","type":"mqtt out","z":"41151e3f.3383e","name":"","topic":"woonkamer/woonkamer/thermostaat/boilerstatus","qos":"","retain":"true","broker":"716d90a0.a6a12","x":1113.5,"y":154,"wires":[]},{"id":"bbb2fc01.b582d","type":"http request","z":"41151e3f.3383e","name":"","method":"GET","ret":"txt","url":"http://192.168.0.9:8124/bridge/heatingCircuits/hc1/actualSupplyTemperature","tls":"","x":538,"y":771.6666259765625,"wires":[["a17b3b28.bec538","811e023b.a9537"]]},{"id":"95de828.7c3578","type":"inject","z":"41151e3f.3383e","name":"","topic":"","payload":"","payloadType":"date","repeat":"60","crontab":"","once":false,"onceDelay":"","x":329.6666603088379,"y":770.3333015441895,"wires":[["bbb2fc01.b582d"]]},{"id":"a17b3b28.bec538","type":"function","z":"41151e3f.3383e","name":"supplytemp","func":"var data = JSON.parse(msg.payload);\nmsg.payload = data.value;\n\nreturn msg;","outputs":1,"noerr":0,"x":762,"y":771.6666259765625,"wires":[["47cbd323.b8a28c","bb7239da.99e638"]]},{"id":"47cbd323.b8a28c","type":"debug","z":"41151e3f.3383e","name":"","active":false,"console":"false","complete":"false","x":791,"y":871.6666259765625,"wires":[]},{"id":"811e023b.a9537","type":"debug","z":"41151e3f.3383e","name":"","active":false,"console":"false","complete":"false","x":910,"y":640,"wires":[]},{"id":"2320da2a.17c066","type":"json","z":"41151e3f.3383e","name":"","x":712,"y":733.6666259765625,"wires":[[]]},{"id":"85524341.08a56","type":"mqtt out","z":"41151e3f.3383e","name":"","topic":"woonkamer/woonkamer/thermostaat/supplytemp","qos":"","retain":"true","broker":"716d90a0.a6a12","x":1350,"y":780,"wires":[]},{"id":"feecaa72.399178","type":"function","z":"41151e3f.3383e","name":"TSP (Temp Setpoint)","func":"var data = JSON.parse(msg.payload);\nmsg.payload = data.value.TSP;\n\nreturn msg;","outputs":1,"noerr":0,"x":623.75,"y":471.25,"wires":[["d0484361.073b2","480a92c5.6b298c"]]},{"id":"d27d50d0.31f34","type":"mqtt out","z":"41151e3f.3383e","name":"","topic":"woonkamer/woonkamer/thermostaat/tempsetpoint","qos":"","retain":"true","broker":"716d90a0.a6a12","x":1170,"y":460,"wires":[]},{"id":"d6366363.501d","type":"function","z":"41151e3f.3383e","name":"CPM (Clock Program)","func":"var data = JSON.parse(msg.payload);\nmsg.payload = data.value.CPM;\n\nreturn msg;","outputs":1,"noerr":0,"x":624.4443969726562,"y":555.5555419921875,"wires":[["f87a3188.ba761"]]},{"id":"358c21bc.ffdfbe","type":"mqtt out","z":"41151e3f.3383e","name":"","topic":"woonkamer/woonkamer/thermostaat/clockprogram","qos":"","retain":"true","broker":"716d90a0.a6a12","x":1190,"y":560,"wires":[]},{"id":"5d6fee11.49984","type":"http request","z":"41151e3f.3383e","name":"","method":"GET","ret":"txt","url":"http://192.168.0.9:8124/api/program","tls":"","x":406.6666564941406,"y":1009.9999389648438,"wires":[["c70461a6.4a46a","3b923a34.936356"]]},{"id":"4bb1ea37.1d2924","type":"inject","z":"41151e3f.3383e","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":"","x":188.33331680297852,"y":1008.6666145324707,"wires":[["5d6fee11.49984"]]},{"id":"c70461a6.4a46a","type":"function","z":"41151e3f.3383e","name":"Active Program","func":"var data = JSON.parse(msg.payload);\nmsg.payload = data.active;\n\nreturn msg;","outputs":1,"noerr":0,"x":640.6666564941406,"y":1009.9999389648438,"wires":[["a842484d.822288","8cf65bdb.a0a548"]]},{"id":"a842484d.822288","type":"debug","z":"41151e3f.3383e","name":"","active":false,"console":"false","complete":"false","x":659.6666564941406,"y":1109.9999389648438,"wires":[]},{"id":"3b923a34.936356","type":"debug","z":"41151e3f.3383e","name":"","active":false,"console":"false","complete":"false","x":730,"y":920,"wires":[]},{"id":"3a9e078d.00b1c8","type":"json","z":"41151e3f.3383e","name":"","x":580.6666564941406,"y":971.9999389648438,"wires":[[]]},{"id":"8cf65bdb.a0a548","type":"mqtt out","z":"41151e3f.3383e","name":"","topic":"woonkamer/woonkamer/thermostaat/activeprogram","qos":"","retain":"true","broker":"716d90a0.a6a12","x":991.6666564941406,"y":1017.9999389648438,"wires":[]},{"id":"ae42c889.77b0c8","type":"function","z":"41151e3f.3383e","name":"BAI","func":"var data = JSON.parse(msg.payload);\nmsg.payload = data.value.BAI;\nif (data.value.BAI === \"No\") {\n    msg.payload = 0;\n} else if (data.value.BAI === \"CH\") {\n    msg.payload = 1;\n} else if (data.value.BAI === \"HW\") {\n    msg.payload = 2;\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":758,"y":257,"wires":[["af3e35bd.9c8f58"]]},{"id":"af3e35bd.9c8f58","type":"mqtt out","z":"41151e3f.3383e","name":"","topic":"woonkamer/woonkamer/thermostaat/boilerstatus_num","qos":"","retain":"true","broker":"716d90a0.a6a12","x":1200,"y":260,"wires":[]},{"id":"d0484361.073b2","type":"debug","z":"41151e3f.3383e","name":"","active":false,"console":"false","complete":"false","x":1115.3332824707031,"y":227.00000667572021,"wires":[]},{"id":"db7e1433.7a2d98","type":"filter","z":"41151e3f.3383e","name":"","property":"payload","propertyType":"msg","asArray":false,"itemProperty":"payload","itemPropertyType":"item","rules":[{"t":"eq","v":"CH","vt":"str","output":1},{"t":"eq","v":"No","vt":"str","output":1},{"t":"eq","v":"HW","vt":"str","output":1}],"checkall":"true","outputs":1,"x":850,"y":200,"wires":[["dd1ecb0a.adafd8"]]},{"id":"abbc08dd.ddc508","type":"filter","z":"41151e3f.3383e","name":"","property":"payload","propertyType":"msg","asArray":false,"itemProperty":"payload","itemPropertyType":"item","rules":[{"t":"eq","v":"CH","vt":"str","output":1},{"t":"eq","v":"No","vt":"str","output":1},{"t":"eq","v":"HW","vt":"str","output":1}],"checkall":"true","outputs":1,"x":880,"y":260,"wires":[[]]},{"id":"e912d7a.8d6a428","type":"filter","z":"41151e3f.3383e","name":"","property":"payload","propertyType":"msg","asArray":false,"itemProperty":"payload","itemPropertyType":"item","rules":[{"t":"nnull","output":1}],"checkall":"true","outputs":1,"x":980,"y":380,"wires":[["ebe95643.b53498"]]},{"id":"480a92c5.6b298c","type":"filter","z":"41151e3f.3383e","name":"","property":"payload","propertyType":"msg","asArray":false,"itemProperty":"payload","itemPropertyType":"item","rules":[{"t":"nnull","output":1}],"checkall":"true","outputs":1,"x":840,"y":480,"wires":[["d27d50d0.31f34"]]},{"id":"f87a3188.ba761","type":"filter","z":"41151e3f.3383e","name":"","property":"payload","propertyType":"msg","asArray":false,"itemProperty":"payload","itemPropertyType":"item","rules":[{"t":"nnull","output":1}],"checkall":"true","outputs":1,"x":860,"y":560,"wires":[["358c21bc.ffdfbe"]]},{"id":"bb7239da.99e638","type":"filter","z":"41151e3f.3383e","name":"","property":"payload","propertyType":"msg","asArray":false,"itemProperty":"payload","itemPropertyType":"item","rules":[{"t":"nnull","output":1}],"checkall":"true","outputs":1,"x":1000,"y":780,"wires":[["85524341.08a56"]]},{"id":"716d90a0.a6a12","type":"mqtt-broker","z":"","name":"","broker":"192.168.0.9","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]

Home Assistant code:
In Home Assistant heb ik een MQTT Climate Component geactiveerd. Die ontvangt de MQTT topics die Node Red produceert, en verstuurt ook het nieuwe set point voor de thermostaat.
https://tweakers.net/ext/f/u8TmJ16qvOf1eGjX1RAF4rhT/full.png

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
climate:
- platform: mqtt
  name: Woonkamer
  current_temperature_topic: "woonkamer/woonkamer/thermostaat/gemetentemperatuur"
  temperature_command_topic: "woonkamer/woonkamer/thermostaat/temperature/set"
  temperature_state_topic: "woonkamer/woonkamer/thermostaat/tempsetpoint2"
  mode_state_topic: "woonkamer/woonkamer/thermostaat/boilerstatus"
  modes:
    - "No"
    - "HW"
    - "CH"
  min_temp: 10
  max_temp: 25
  intial: 15
  retain: True


Ik heb ook een paar sensoren aangemaakt om met de volgende stap te praten.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
sensors:
- platform: mqtt
  name: 'wk_boilerstatus'
  state_topic: "woonkamer/woonkamer/thermostaat/boilerstatus"
- platform: mqtt
  name: 'wk_thermostaat_pv'
  unit_of_measurement: '°C'
  state_topic: "woonkamer/woonkamer/thermostaat/gemetentemperatuur"
- platform: mqtt
  name: 'wk_thermostaat_hass_sp'
  unit_of_measurement: '°C'
  state_topic: "woonkamer/woonkamer/thermostaat/temperature/set"
- platform: mqtt
  name: 'thermostaat_activeprogram'
  state_topic: "woonkamer/woonkamer/thermostaat/activeprogram"
- platform: mqtt
  name: 'thermostaat_tempsetpoint_raw'
  state_topic: "woonkamer/woonkamer/thermostaat/tempsetpoint"

Appdaemon script 1
De Nefit Easy Server spuugt soms een 'undefined' uit en die moet ik er uit filteren. Dat gebeurt met dit AppDaemon script:

Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import appdaemon.plugins.hass.hassapi as hass

class thermostaat_raw(hass.Hass):
    def initialize(self):

        self.listen_state(self.inputhandler, "sensor.thermostaat_tempsetpoint_raw")


    def inputhandler(self, entity, attribute, old, new, kwargs):
        reading = self.get_state("sensor.thermostaat_tempsetpoint_raw")
        #self.log(reading)
        if reading != "undefined":
            try:
                temp_sp_thermostaat = float(reading)
                self.log("float: " + reading )
                
                self.call_service("mqtt/publish", topic="woonkamer/woonkamer/thermostaat/tempsetpoint2", payload=temp_sp_thermostaat, retain=True)
                

            except:
                self.log("error in: reading" + reading)

Appdaemon Script 2
Dit script zet een nieuw (in hass ingesteld) set point door naar de thermostaat. Het roept drie endpoints aan, zoals beschreven in dit bericht op github.

Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import appdaemon.plugins.hass.hassapi as hass

import requests

class thermostaat_mqtt(hass.Hass):
    def initialize(self):
        self.listen_state(self.program_enable, "input_boolean.nefit_programma",new="on")
        self.listen_state(self.inputhandler, "sensor.wk_thermostaat_hass_sp")


    def inputhandler(self, entity, attribute, old, new, kwargs):
        temp_sp_hass = float(self.get_state("sensor.wk_thermostaat_hass_sp"))

        headers = {'Content-type': 'application/json'}
        myurl = "http://192.168.0.9:8124"
        command1 = "/bridge/heatingCircuits/hc1/temperatureRoomManual"
        command2 = "/bridge/heatingCircuits/hc1/manualTempOverride/status"
        command3 = "/bridge/heatingCircuits/hc1/manualTempOverride/temperature"

        body1 = temp_sp_hass
        body2 = "on"
        body3 = temp_sp_hass
        self.log("new setpoint & command:")
        self.log(body1)
        self.log(body2)


        r1 = requests.post(myurl+command1, verify=False, json={"value": body1}, headers = headers)
        self.log(r1.status_code)
        self.log(r1.text)

        r2 = requests.post(myurl+command2, verify=False, json={"value": body2}, headers = headers)
        self.log(r2.status_code)
        self.log(r2.text)

        r3 = requests.post(myurl+command3, verify=False, json={"value": body3}, headers = headers)
        self.log(r3.status_code)
        self.log(r3.text)

        self.call_service("input_boolean/turn_off", entity_id="input_boolean.nefit_programma")





    def program_enable(self, entity, attribute, old, new, kwargs):

        headers = {'Content-type': 'application/json'}
        myurl = "http://192.168.0.9:8124"
        command2 = "/bridge/heatingCircuits/hc1/manualTempOverride/status"

        body2 = "off"


        r2 = requests.post(myurl+command2, verify=False, json={"value": body2}, headers = headers)
        self.log(r2.status_code)
        self.log(r2.text)

Volgende: CO2 Meter met MH-Z19 04-'17 CO2 Meter met MH-Z19

Reacties


Door Tweakers user ThaStealth, woensdag 26 september 2018 08:24

Je kan ook dit python scriptje pakken: https://github.com/marconfus/ha-nefit en de nefit-client installeren met pip, is denk ik wat makkelijker.

[Reactie gewijzigd op woensdag 26 september 2018 08:24]


Door Tweakers user Hkuit, vrijdag 28 september 2018 13:04

Mooi verhaal, maar werkt het ook fijn in de praktijk? En wat is je reden om het zo aan te pakken; heb je dit geļntegreerd in een groter domotica-systeem?

Door Tweakers user balk, vrijdag 28 september 2018 16:09

Hkuit schreef op vrijdag 28 september 2018 @ 13:04:
Mooi verhaal, maar werkt het ook fijn in de praktijk? En wat is je reden om het zo aan te pakken; heb je dit geļntegreerd in een groter domotica-systeem?
Yep, Ik gebruik Home Assistant. Dat pakket laat allerlei protocollen met elkaar praten. Zo heb ik een Z-wave knop die via MQTT een zelfbouw lamp aanstuurt. In de praktijk werkt het 95% van de tijd. Dat ligt meer aan de Nefit cloud dan aan mijn implementatie. Niet zo lang geleden heeft Nefit ook wat in de API veranderd waardoor dit niet meer werkt. De code was snel weer bijgewerkt.

Een van de dingen waar ik de Nefit Easy connectie voor gebruik is
a) Ventilatie in douch aan als er warm water getapt wordt voor meer dan een minuut
b) Verwarming pas uit wanneer alle lichten in de woonkamer uit zijn

Ik zal nog wat context geven aan deze posting.

Reactie formulier
(verplicht)
(verplicht, maar wordt niet getoond)
(optioneel)