« Heizung, Lüftung, Klima  |

DIY Alternative zu Nibe Modbus Modul

Teilen: facebook    whatsapp    email
 
 1  2 ... 3 ... 6  7  8  9 ... 10 ... 49  50  51 
  •  chrismo
  •   Gold-Award
29.1.2019 - 25.4.2024
1.009 Antworten | 62 Autoren 1009
127
1136
Weil es hier immer wieder zu Diskussionen zum Thema Modbus-Anbindung der Nibe kommt, wollte ich hier mal kurz meine Erfahrungen mit dem Nachbau einer DiY Lösung, auf Basis von im Netz vorhandener Infos, teilen. Für mich war es eine Spielerei und Zeitvertreib der letzten Tage. Der Post dient vor allem als Speicherort für meine gesammelten Infos und evt. dem Austausch von Leuten, die das so oder so ähnlich bei sich installiert haben. Ich kann und will hier keine Empfehlung abgeben, sowas selbst zu machen!

Die Lösung basiert im Wesentlichen auf den Nibe Bindings von openHAB (https://www.openhab.org/addons/bindings/nibeheatpump/), das eine Umsetzung Modbus auf UDP macht. Infos zur Funktionsweise findet man auf der openHAB Seite bzw. dem entsprechenden github Repo.

Die grobe Vorgangsweise war folgend:
1) Auf einen Arduino mit Ethernet Shield und RS485 Adapter die NibeGW Software (Teil des Bindings) installieren. Der Ardunio Code muss dabei an die eigenen Netzwerkeinstellungen angepasst werden. 

2) Den Arduino an die Wärmepumpe und ans LAN anschließen.

3) Die Nibe Modbus Manager Software auf einem Rechner installieren und bis zu 20 Register auswählen, die periodisch von der Wärmepumpe exportiert werden sollen. Diese Konfig muss gespeichert und per USB-Stick auf die WPWP [Wärmepumpe] übertragen werden.

4) Das Modbus Modul in der WPWP [Wärmepumpe] aktivieren. Wenn alles geklappt hat, bleibt die Wärmepumpe im Normalbetrieb. Falls irgendwas bei der Kommunikation mit dem Arduino schief geht, wird eine Fehlermeldung am Display ausgegeben und die WPWP [Wärmepumpe] geht in einen Alarmmodus.

5) Das nibeopenhab Binding in openHAB installieren und konfigurieren.

zu 1) Man könnte dazu auch einen Raspberry Pi mit RS485 Adapter verwenden, auf dem dann auch openHAB selbst läuft. Das finde ich aber nicht optimal. Ein Pi wäre mir da nicht robust genug. Selbst ein einfacher Neustart des Pis würde zu einem Fehler der WPWP [Wärmepumpe] führen und ein SD-Kartenfehler wäre sowieso ungemütlich.

zu 5) Da ich derzeit noch nicht weiß ob es openHAB oder was anderes wird - über Erfahrungen bzw. Empfehlungen würde ich mich freuen(!) - habe ich das Binding so adaptiert, das es ohne openHAB läuft. Derzeit verwende ich die Log-Dateien dieses "Stand-Alone Bindings" zur Speicherung der Werte. Eine Erweiterung für "richtige" Ausgabeformate bzw. Kanäle (Umsetzung auf KNX wurde hier mal in einem anderen Thread diskutiert) wäre aber von hier weg leicht machbar.

von energiesparhaus

  •  SMiak
  •   Bronze-Award
30.11.2019  (#141)
Live-AZ fetzt emoji

Wie erfasst du eigentlich den Pumpenstrom?

Halte uns am Laufen!

Vg Maik 

1
  •  JanRi
  •   Gold-Award
30.11.2019  (#142)
Hi,

die WPWP [Wärmepumpe] hängt an zwei BG-etech-Modbuszählern, einmal dreiphasig für Kompressor und ZH und einmal einphasig für die Steuerung. Die wiederum lese ich seit Januar per Modbus mit meinem Haupt-Pi aus. Der loggt das dann. Bislang musste ich das mühsam per Hand mit den USB-Logs der Nibe synchronisieren (siehe WW WW [Warmwasser]-Thread).

Jetzt habe ich das Skript so umgebaut, dass es jetzt auch per MQTT seine Messwerte veröffentlicht. Der Logger subskribiert sich da auch und kann schon alles fein zusammen loggen und die AZ recht gut ausrechnen.

Das ganze ist natürlich fehlerbehaftet... alleine beim Schwanken der Spreizung um 0,1K ändert sich die AZ bei Leistungen um 3 KW um 0,3 Punkte. Dessen ungeachtet liege ich jetzt bei 48 Hz, 3400W und 27,2C VL VL [Vorlauf] bei knapp 6 in der AZ inkl. allem.

Viele Grüße,

Jan

1
  •  JanRi
  •   Gold-Award
1.12.2019  (#143)
Hi,

english again because I found something for NibePi...

At night we again got two alarms. Therefore, alarm count decreases by not requesting messages at all (just favorites) and by isolating heatpump.js on a dedicated processor core.

However, two alarms are two alarms too much. In order to figure out if this is caused by my hardware I now test nibegw.c.

Approach: nibegw runs on a Pi (with nibepi image without anything) isolated on core 3 with nice value -20. It sends out everything it got using UDP to my server.

There, a small UDP client running on node.js (I start to like that) gets the message and decodes it. My decoder is based on the ideas from heatpump.js but is very limited because it can only decode messages from favorites (these have to be known in advance, so not adapted automatically like NibePi), nothing else. These messages are then published using MQTT to a mosquitto running on my server. This way, I retain compatibility with the nibepi solution with respect to my client (I only had to change the address of the MQTT server). 

This was rather simple... the whole UDP->MQTT translator is just 126 LOC with some debug stuff included. However, this is obvious, because I can only decode know messages (and only message type 0x68). But, it is just for hardware testing, so this should be sufficient.

NibePi: While doing that I guess I figured out why 1.0.6 does not get the value of the register 43514: The reason is that the register before that is type u16 and your decodeMessage has a bug here: While decoding U16, it increases the pointer by 5. u16 is 2 byte only, so i = i + 3 should do (not yet tested in heatpump.js since now nibegw is tested).

The hard core test comes in 45 minutes: Then, hot water starts. Here, NibePi 1.0.6 failed in more than one try. If nibegw also fails, I have to improve my hardware, otherwise, 1.1 will hopefully be the solution.

Chrismo: My small UDP->MQTT should also work with plan C, Arduino connected to heat pump because the interface of nibegw should be the same.

Greetings,

Jan

1
  •  SMiak
  •   Bronze-Award
1.12.2019  (#144)

zitat..
JanRi schrieb: Chrismo: My small UDP->MQTT should also work with plan C, Arduino connected to heat pump because the interface of nibegw should be the same.

that should be plan A emoji

Thanks for testing! I hope that I can test it too at Christmas.

Greetings, 
Maik


1
  •  chrismo
  •   Gold-Award
1.12.2019  (#145)

zitat..
JanRi schrieb: There, a small UDP client running on node.js (I start to like that) gets the message and decodes it.


You may also have a look into the Java code of the openHAB Nibe binding. It contains info about all the registers (e.g., data type, scaling factor) and also the parsing functions. I guess based on that information, it should be rather easy to enhance the C decoder. You can find the source code here: https://github.com/openhab/openhab2-addons/tree/master/bundles/org.openhab.binding.nibeheatpump/src/main/java/org/openhab/binding/nibeheatpump/internal

zitat..
SMiak schrieb: that should be plan A

I guess there are some different opinions about that emoji I also prefer the Arduino but actually it would even be better, if more options would be around and everyone can choose based on his/her preferences.

Use NibePi, Modbus comm handled by a node.js script
Use NibePi, but Modbus comm is handled by nibeGW (C program)
Use NibePi+Arduino ("ArduNibePi"), Arduino handles the Modbus stuff and communicates with NibePi using UDP (or serial).

1
  •  JanRi
  •   Gold-Award
1.12.2019  (#146)
Hi,

zitat..
SMiak schrieb: that should be plan A

Actually, I also start to think in that direction, although the Pi does the job really good (but this is obvious because I dropped everything else and nibegw has a dedicated CPU core).

nibegw runs since 9:30 with no alarm and no restart of nibegw necessary (and with USB stick plugged in and logging, Uplink is still removed). In the meantime I continued with my simple UDP<->MQTT program. It is now able to read other registers (beside the favorites) and to write values. The interface for writing is equal to nibepi, the interface for single shot reading is compatible to the one nibepi plans implement in 1.1 (nibe/modbus/<regnr>/get). Adding/removing registers to a set that is periodic requested is not implemented because I do not need that (and I see this as a test, not a clone of nibepi). Furthermore, all the automatic functions are also not present as they are also not needed for testing purpose. 

Since two hours I read 10 additional registers in a way that I make one read every 20 seconds so every register is read after 200 seconds. This is more than enough for registers such as heat meter etc. The important registers are read as favorites.

The interface of nibegw is really simple: It acks the message and sends the payload using UDP. In parallel, it listens on two UDP sockets in order to get read and write commands. I just parse the incoming data stream and use the other two ports for the other direction.

With respect to nibepi, I have a feature request for 1.2 (or even 1.1.1?): It would be really great to have a second optional backend that can use the UDP interface by nibegw. This should be really simple to include because on the incoming way, instead of reading from serial port, reading is now required from UDP. Acks are not necessary because nibegw takes care of this. On the outgoing way, instead of writing to serial, writing to UDP is necessary. Everything else, especially all the parsing, configuration etc. remains the same. I guess with the modular approach of nibepi 1.1 this should be really simple to implement.

The advantage is: Many users already have home servers of different type, not all of them RPi and not all of them near the heat pump. In this case, the very simple Arduino-UDP-nibegw can be attached to the heat pump while nibepi runs an the server some else.

Current functionality: I log 39 registers, 30 coming from heatpump (20 favorite, 10 requested) and 9 coming from my Smartmeter-Pi, everythings goes into CSV file. The interface now looks like this:

AT: 0.4 IT: 22.0 AT_48h: 2.1
VL: 26.9 RL RL [Rücklauf]: 24.0 exVL: 26.9 VLsoll: 26.9
Kond.VL: 26.8 Heissgas: 48.1 Sauggas: 6.6
SoleEin: 4.0 SoleAus: 0.2
BWoben: 45.1 BWunten: 44.7
WQ: 12 % WT: 49 % WT: 14.7 l/min
Kompr. 43.0 Hz Relais: 7 Starts: 187
-426.5 GM
Spreizung: 2.9 P_th: 2975 W
P_ko: 474.4 W P_pu: 31.8 P_el 506.2 AZ: 5.877
EZ Kompressor: 2261.9 KWh EZ Pumpen: 387.7 KWh
WMZ Heizung: 13071.4 KWh WMZ WW WW [Warmwasser]: 632.8 KWh WMZ Kuehl: 0.0 KWh

The update rate is slightly more than once a second and the accuracy is equal to the display on the heat pump but I can show whatever I want together.  And we still have real-time COP emoji

Greetings,

Jan


1
  •  JanRi
  •   Gold-Award
1.12.2019  (#147)
Hi again,

chrismos posting was written while I was writing my posting...

zitat..
chrismo schrieb: It contains info about all the registers (e.g., data type, scaling factor)

 
The F1155.json file of nibepi does exactly that and nibepi has similar files for some other nibe machines.


zitat..
chrismo schrieb: I also prefer the Arduino but actually it would even be better, if more options would be around and everyone can choose based on his/her preferences.

Exactly.


zitat..
chrismo schrieb: Use NibePi, but Modbus comm is handled by nibeGW (C program)


My current setting is similar... but instead of NibePi my own node.js program and this not on the Pi but on a server. The Pi just does nibegw and UDP. 

Furthermore, I figured out something interesting: While making hot water (this was no problem with nibegw!) my decoder ran into some problems. This was due to the fact that it assumed "correct" messages and did not include any error handling, but this way I figured out that the heat pump sent some garbage or partly incorrect messages. Nibegw has acked them, so checksum was correct but the format was slightly changed. My current guess is that there is something that we do not know about the protocol. The fact is that due to that the decoder seemed to decode a register with some impossible number and the content "23644". This happened two or three times on different fields and with some time inbetween. Although the "impossible register" was caused by the non-existing error checking of the decoder, the numder 23644 is interesting: This is 0x5c5c, so twice the starting code. According to nibegw.c, the nibe-protocol seems to avoid 5c as checksum (replaced by c5) so it might be possible that there is some "escaping" of special sequences also on other places that we are not aware of. These sequences seem to happen at the beginning of hot water production because here a variety of different values (with increasing temperatures) is produced (or because of a higher load on the nibe CPU?). I do not have a log of the raw data but this cannot be random: NibePi runs into 2-3 alarms in the first minutes of HW. NibeGW does not have any problem at all (but it does not look at the data) but my (simple!) decoder also fails two or three times here. 

Therefore, my current guess is: We do not know everything on the protocol and its specialities. There seem to be some "spikes" - maybe due to unknown protocol features such as escpaping or maybe just due to problems in the heat pump software or whatever - that are problematic for our decoders. NibePi is forced into error handling which might lead to problems with acking on time while my decoder just produces nonsense for one message.

This is a strong argument for separating the "ACK-part" and the decoder as good as possible in order to avoid that decoder problems (or whatever) can influence the real-time part. So this is both an argument for nibepi 1.1 (if the separation is strong enough) or the physical separation into to programs running on two computers or microcontrollers connected by UDP.

The really good thing with UDP is that it is "fire and forget" so whatever happens after sending, is not relevant anymore for the sender.

Greetings,

Jan


1
  •  nibepi
1.12.2019  (#148)

zitat..
JanRi schrieb: So this is both an argument for nibepi 1.1 (if the separation is strong enough) or the physical separation into to programs running on two computers or microcontrollers connected by UDP.

So I invite you to test the beta of 1.1. I've just uploaded the library to NPM.
In your nodejs project folder you can just "npm install nibepi". Se an example.js here.

zitat..
var nibe = require('nibepi');
const serialPort = "/dev/ttyAMA0";
const mqtt_host = "127.0.0.1";
const mqtt_port = "1883"

nibe.initiateCore(serialPort, function(err,core) {
    if(err) return console.log(err);
    console.log('Core is started.')
})
console.log('Waiting for the core to initiate...')

nibe.handleMQTT(true,mqtt_host,mqtt_port,function(err,result) {
    if(err) return console.log(err);
    if(result===true) {
        console.log('MQTT broker is connected')
    } else {
        console.log('MQTT broker is disconnected')
    }
})
console.log('Waiting for MQTT')

nibe.data.on('data',data => {
    console.log(`${data.register}, ${data.titel}: ${data.data} ${data.unit}`)
})

This is just a preview beta for you to test out, the above script will launch the NibePi core on the specified serialport. For now the core resets the heatpump red error code regulary, it does'nt check for error, it just resets always.


zitat..
node example.js
Waiting for the core to initiate...
Waiting for MQTT
MQTT broker is connected
Core is started.
Nibe F750
Firmware 9086
Register is set. Length: 639
40083, EB100-BE1 Current: 6 A
40081, EB100-BE2 Current: 1.7 A
40079, EB100-BE3 Current: 2.5 A
43144, Compr. energy total: 24185.49 kWh

It should look something like above.
The MQTT will start and all data will be availible on nibe/modbus/*register*

The MQTT functions are nibe/modbus/*register*/get , set, add, remove

I have read all your comments and all I can say about your discoveries about the nibegw and error handling is that nibepi is handling errors and only outputs valid data and sends valid data.

zitat..
JanRi schrieb: NibePi: While doing that I guess I figured out why 1.0.6 does not get the value of the register 43514: The reason is that the register before that is type u16 and your decodeMessage has a bug here: While decoding U16, it increases the pointer by 5. u16 is 2 byte only, so i = i + 3 should do (not yet tested in heatpump.js since now nibegw is tested).

Thank you for noticing this, sounds reasonable, I have adjusted that in the code.
U32 and S32 now works also.

zitat..
JanRi schrieb: With respect to nibepi, I have a feature request for 1.2 (or even 1.1.1?): It would be really great to have a second optional backend that can use the UDP interface by nibegw.

I have no plans to make nibepi compatible with nibegw. Nibegw has some issues and it seems depreceated. In my opinion nibegw does what nibepi does but nibepi is better at it.
I will however add possibilites to support other "backends" like the new S models are real modbus TCP, so a Modbus TCP and RTU core will be added in the future to support all heatpumps with modbus. 

If someone is interested making and arduino code out of the backend.js please be my guest and i will add UDP/TCP possibilities to communicate with such a solution.

My goal is to have NibePi as the total solution in one hardware, easy to install and to use.


1
  •  JanRi
  •   Gold-Award
2.12.2019  (#149)
Hi,

zitat..
nibepi schrieb: This is just a preview beta for you to test out, the above script will launch the NibePi core on the specified serialport. For now the core resets the heatpump red error code regulary, it does'nt check for error, it just resets always.

 
Thank you!

Do you still see problems in using an external MQTT (i.e., mosquitto running on the server and not on the Pi)? This would simplify testing for me because this way, it would be a drop-in replacement for my UDP<->MQTT adapter. If there are still problems with that, I have to adapt the client to access two brokers instead of one (the second is for smart meter logging that I do not want to put on the test Pi to keep load comparable).

With respect to resetting alarms, I will disable that for testing because it is done at client side (by subscribing to nibe/modbus/45001) enabling easier alarm logging and counting.

I can test this today evening at home (hopefully).


zitat..
nibepi schrieb: all I can say about your discoveries about the nibegw and error handling is that nibepi is handling errors and only outputs valid data and sends valid data.


That was not the point. I guess that this error handling is the problem in 1.0.6 that leads to alarms. NibeGW just sends out everything it gets so there is no alarm (errors should be handled at the other side of UDP connection). If the separation of real-time and the other part works better in 1.1, this should be no longer a problem.


zitat..
nibepi schrieb: Nibegw has some issues and it seems depreceated.


What kind of issues are related to nibegw (and not the rest of openhab)?

With respect do "deprecated": What do you want to improve on a RS485<->UDP translator? It does what it should do in a very simple manner.


zitat..
nibepi schrieb: If someone is interested making and arduino code out of the backend.js please be my guest and i will add UDP/TCP possibilities to communicate with such a solution.


The UDP interface of nibegw and the Arduino solution is equal.

I have not yet looked into your new code: Is the serial communication encapsulated in a way that there is an object that handles the low level serial communication and offers "read" and "write" to the rest of the backend/other code? If yes, the UDP adapter is a question of some lines of code. 

serial read: read data from tty, send ACK
serial write: write data to tty

UDP read: read data from socket
UDP write: write data to socket

The payload is exactly the same.

I already tried to incorporate that into 1.0.6 but at the end it was easier (mainly due to my JS skills...) to implement my own gateway with significantly reduced functionality.


zitat..
nibepi schrieb: My goal is to have NibePi as the total solution in one hardware, easy to install and to use.

I do not see a contradiction here. It is just the question of interfacing the heat pump. You always need a RS485 converter. The only question is how this is connected to the Pi. Your solution is the RS485<->RS232 adapter (RS485 hat on pi zero). Another solution would be RS485<->USB that I wanted to use but actually, I now have a RS485 shield. For the software, these two solutions are equal (except the interface to use, ttyAMA0 vs. ttyUSB0) because they both offer a serial interface The third solution is RS485<->UDP. This can be realized by a Pi running NibeGW or by the Arduino solution. For the user, this is just another adapter attached by network.

Greetings,

Jan


1
  •  nibepi
2.12.2019  (#150)

zitat..
JanRi schrieb: Do you still see problems in using an external MQTT (i.e., mosquitto running on the server and not on the Pi)

 That's not a issue anymore. There is only one broker connection now. In this beta you can just type another ip. But only brokers with no user password for now. 

zitat..
JanRi schrieb: With respect do "deprecated": What do you want to improve on a RS485<->UDP translator? It does what it should do in a very simple manner

Well on that point you are right. I just want some more filtrering on the first level. The application Im building only needs the real data. 
I dont see nibepi as a translator. Nibepi backend.js sends out the real data as buffers. Not all the acking com with the heatpump.
It's probably no bigger issue to make my worker compatible with nibegw. But my goal has always been to have an own solution which fits my needs for the project. 
If you want the raw data nibegw is the way to go. 

zitat..
JanRi schrieb: Another solution would be RS485<->USB that I wanted to use but actually,

For me it doesn't matter if it is a usb or hat. Still the same hardware attached. 
Since my application has built in automations I want them to run on a hardware wired to the heatpump. The automations should not be dependent on your network.
For weather data as an example. If you loose communication with the weather server the automations need to adapt back and reset the values to default. 
Nibegw on a arduino cant do that by its own. 
But a raspberry pi with nibepi can. 




1
  •  JanRi
  •   Gold-Award
2.12.2019  (#151)
Hi,

zitat..
nibepi schrieb: But only brokers with no user password for now. 


It has no password emoji Fine, then I test that way as a simple drop in replacement. I will just remove the periodic alarm resetting in order to enable my alarm counter.

zitat..
nibepi schrieb: The automations should not be dependent on your network.


Here I agree. If you control something on heat pump, it has to be reliable not depending on external components in its base functionality. Here, your approach fits best.

For logging, this is not a big problem if we accept losing some log data in case of network problems (we have to accept this anyway because we do not want to have a R/W filesystem on the pi connected to the heat pump).

With respect to controling, I actually stopped any work on that until I have a clear answer (hopefully from Nibe but maybe from one of the insider) on the question of storage durability. I guess your weather automation can run into the same problem depending on the number of parameter changes. 

But first, lets see how the beta is running (test has to wait until I'm home after work).

Greetings,

Jan

1
  •  nibepi
2.12.2019  (#152)

zitat..
JanRi schrieb: With respect to controling, I actually stopped any work on that until I have a clear answer (hopefully from Nibe but maybe from one of the insider) on the question of storage durability. I guess your weather automation can run into the same problem depending on the number of parameter changes. 

But first, lets see how the beta is running (test has to wait until I'm home after work).

Im interested in that answer. My plugins change registers several Times a day. Register 47011 mostly to simulate another outdoor temperature. 

Looking forward to hear from your testing!
In my opinion it should run 100% stable without any adjustments to the cpu cores. 

1
  •  JanRi
  •   Gold-Award
2.12.2019  (#153)
Hi,

zitat..
nibepi schrieb: Looking forward to hear from your testing!

I delayed testing because I found the problem I mentioned yesterday - it affects your code as well (and I have the solution).

Furthermore, "npm install nibepi" failed with some error I have yet to solve (looks like local problems). However, I downloaded the sources from the repository in order to scan through your code - it is affected by the problem I discovered.

Yesterday I assumed that there is something we do not know about the protocol. Today, while making hot water, I saw this problem (strange values) again. Then, I added a raw data logger to my UDP<->MQTT adapter in order to see whats going on. By accident, I was sucessful quite soon.

A usual type 0x68 packet looks like this:

5c00206850449c2500489c06014c9cec004e9cc3014d9cc5014f9c2500509c0100519c0601529cdb01569c4400879c0601619cdb00889c940001a80601fda7f9ef80a88601faa90700ada93100afa90800c9af00009a8c

This is logged from what I got from UDP so it is equal to what you get from serial. I looked at the code of nibegw.c - this is NOT added by nibegw but originates from heat pump. Look at the bold values. The first one is packet size 0x50 - 80 byte. The other two are register numbers 40018 and 40022. Obviously, there are two bytes inbetween (the data).

Now, the problematic package:

5c00206851449c2100489c08014c9cec004e9cc3014d9cc5014f9c1b00509c0200519c0601529c5c5c02569c2600879c0001619cdc00889c930001a8f600fda743f080a85301faa90700ada93100afa91500c9af00008c7e

It is 0x51 long, so 81 byte. Furthermore, the two register names have THREE bytes in between. This is caused - as I guessed yesterday - by escaping the 0x5c (start byte) in a way that the data 0x5c is encoded as 0x5c5c.

The same applies to 0x6a (read answer) packets:

Standard package:

5c00206a0614ad630002009401

That's 6 data bytes. Register is 44308 (heatmeter) with 32 bit value.

and:

5c00206a0714ad5c5c000200f64c

again: 5c as part of the regular payload is escaped so we have one byte more (7). 

This problem occurs every time we have 0x5c as part of the data field. This happens rarely but has a higher probability when producing hot water because we have values that change fast and often. The same applies to heatmeter... it has to run through values that contain 5c.

The solution is very simple: We have to scan through the data and replace every occurence of 0x5c5c by 0x5c before further dealing with the message.

I have not yet seen data packets with twice that problem but I guess nibe deals with it in the same manner. However, my logger remains enabled and will log all raw data I get from the heatpump (only types 0x68 and 0x6a). If you are interested, I can give you that log in order to give you more data to test your decoder.

With respect to testing, I will wait for the fix because I guess that these messages will lead at least to some problems and maybe even an alarm (I have not looked at your code completely to figure this out). With respect to 1.0.6, I'm now sure that this was the cause of the alarms because they were heavily related to hw production this happens quite often.

Thats for my findings...

Greetings,

Jan

1
  •  chrismo
  •   Gold-Award
2.12.2019  (#154)

zitat..
JanRi schrieb: It is 0x51 long, so 81 byte. Furthermore, the two register names have THREE bytes in between. This is caused - as I guessed yesterday - by escaping the 0x5c (start byte) in a way that the data 0x5c is encoded as 0x5c5c.

Yes, 5c is escaped and must be removed from the data.

zitat..
chrismo schrieb: You may also have a look into the Java code of the openHAB Nibe binding. It contains info about all the registers (e.g., data type, scaling factor) and also the parsing functions.


As I already suggested, have a look at the Nibe binding in openHAB. They already solved this kind of issues, i.e.:  https://github.com/openhab/openhab2-addons/blob/master/bundles/org.openhab.binding.nibeheatpump/src/main/java/org/openhab/binding/nibeheatpump/internal/protocol/NibeHeatPumpProtocol.java

removes duplicate "5c" bytes.

1
  •  nibepi
2.12.2019  (#155)

zitat..
JanRi schrieb: 5c00206851449c2100489c08014c9cec004e9cc3014d9cc5014f9c1b00509c0200519c0601529c5c5c02569c2600879c0001619cdc00889c930001a8f600fda743f080a85301faa90700ada93100afa91500c9af00008c7e

It is 0x51 long, so 81 byte. Furthermore, the two register names have THREE bytes in between. This is caused - as I guessed yesterday - by escaping the 0x5c (start byte) in a way that the data 0x5c is encoded as 0x5c5c.

 In 1.0.6 I got a lot of these 81 bytes, sometimes when counting them there are just 79 or maybe 80 bytes.
On the other hand I dont think its related to 5c being sent in the middle of the message. Because as soon as nibegw or my nibepi receives 5C it checks for the next 00, and then 20. If that all checks we know we have a message for us. Then in the next buffer we get the type and in the next, the length. if it says 50 (80 bytes) then we read 80 buffers ahead and start decoding them. It doesnt matter if it's 5C in the data. The start is found and we dont look for another start until we finished the 80 bytes.
But the last byte being sent is the checksum. That cant be 5C. (Not sure why but that how it is).

The problem I think we have here in nibegw and nibepi 1.0.6 is timing. When the cpu is busy it piles up buffers and seems to rearrange the order of them. In 1.0.6 i got special function to filter out these "unknown" byte lengths. Like 81 bytes, 7 bytes and so on. Sometimes it says 80 bytes but the data received is only 79 bytes, and it takes the checksum as the last databyte. And everything gets messed up.
You can search in heatpump.js and find "ERR SHORT". I handle that error with a NACK and a new message come.

This is why i rebuilt the core and made backend.js
All these problem with strange byte lengths have dissappered when using the new core.
So I'm pretty sure it's a timing issue or other communication related problem when the cpu is busy.

1
  •  nibepi
2.12.2019  (#156)

zitat..
chrismo schrieb:
__________________
Im Beitrag zitiert von JanRi: It is 0x51 long, so 81 byte. Furthermore, the two register names have THREE bytes in between. This is caused - as I guessed yesterday - by escaping the 0x5c (start byte) in a way that the data 0x5c is encoded as 0x5c5c.

Yes, 5c is escaped and must be removed from the data.
__________________
Im Beitrag zitiert von chrismo: You may also have a look into the Java code of the openHAB Nibe binding. It contains info about all the registers (e.g., data type, scaling factor) and also the parsing functions.

As I already suggested, have a look at the Nibe binding in openHAB. They already solved this kind of issues, i.e.:  https://github.com/openhab/openhab2-addons/blob/master/bundles/org.openhab.binding.nibeheatpump/src/main/java/org/openhab/binding/nibeheatpump/internal/protocol/NibeHeatPumpProtocol.java

removes duplicate "5c" bytes.

Now when I read this, this might also be true. Well it probably is so Im gonna investigate it further.

1
  •  JanRi
  •   Gold-Award
2.12.2019  (#157)
Hi,

zitat..
nibepi schrieb: Because as soon as nibegw or my nibepi receives 5C it checks for the next 00, and then 20.


No, at least not for nibegw. It considers 5c as start of message and uses the rest as messages. This can contain 5c5c and it contains 5c5c as my log shows. This is a classical case of "escaping" (similar to escape "\" on a shell as \\).

zitat..
nibepi schrieb: It doesnt matter if it's 5C in the data


It does matter as nibe never puts 5c into the message, only in escaped format as 5c5c. See the answer of chrismo with the pointer to the openhab code.

Look at the example messages I posted. If you decode them by hand you will get the right result if you replace 5c5c by just 5c.

Furthermore, the messages regarding heat meter belong to a series of values (obviously increasing). In this series, the value is perfectly correct when replacing 5c5c by just 5c. The same applies to hot gas temperature. It went down after hw and the value in question perfectly matched the ones before and after.

zitat..
nibepi schrieb: That cant be 5C. (Not sure why but that how it is).


That is simple. The rule of the protocol is: There is only ONE position a single 5c is allowed - that is start. In checksum, a 5c (which might be the result) is replaced by c5. See nibegw.c:

" // check special case, if checksum is 0x5C (start character),
// heat pump seems to send 0xC5 checksum"

zitat..
nibepi schrieb: The problem I think we have here in nibegw and nibepi 1.0.6 is timing.


No, at least not for nibegw. Nibegw does NOT produce an alarm here. It perfectly acks the messages and perfectly streams to UDP. With the rule mentioned above, you can perfectly decode these messages.

I just found the next prove in my log. Register 0xfda7 -> 43005 -> degree minutes 16 bit stayed for 8 minutes in the area -400,5 to -400,4. The latter is encoded as -4004 which is s16 and therefore 61532 = 5cf0 in coding.

From the log two entries one after the other:

2019-12-02;14:09:12 5c00206851449c2500489c04014c9ced004e9cc2014d9cc5014f9c2800509c0800519c0201529cd701569c4800879c0301619cdb00889c940001a80401fda75c5cf080a85401faa90700ada93100afa90600c9af0000a47e
2019-12-02;14:09:14 5c00206850449c2500489c04014c9ced004e9cc2014d9cc5014f9c2800509c0800519c0201529cd701569c4800879c0301619cdc00889c940001a80401fda75bf080a85401faa90700ada93100afa90600c9af0000f9a4

In both cases, register fda7 which is 43005 is marked bold. The data in the second case is obvious: 5bf0. This is 61531, in s16 this is -4005 so -400,5 GM. The message before has data 5c5cf0 - you see that the next register (as in second message) is 80a8 starting afterwards. We remove escaping and end up with 5cf0 -> -400,4. So, this is NOT an error, this is just regular escaping of data. We cannot just drop this data - just imagine the heatmeter contains "5c" for a very long time.

zitat..
nibepi schrieb: Sometimes it says 80 bytes but the data received is only 79 bytes, and it takes the checksum as the last databyte.


This so far never happened with nibegw and UDP. Message length was always correct but I will add a check for this and log that too.

zitat..
nibepi schrieb: All these problem with strange byte lengths have dissappered when using the new core.


I don't believe that. Maybe you just drop such frames but this way you also drop data. I can easily test that... it should be enough to set the circulation pump to 92 (0x5c). Your code will drop that message (because nibe escapes this message) or produce an error.

Hmm... lets test that right away with nibegw and my decoder that does not yet de-escape:

mosquitto_pub -h localhost -t "nibe/modbus/47414/set" -m "92"

Setting seems to work... but this results in "23644%" as pump speed (pump is running at 92% as requested). 91% and 93% show right values. Thats obvious because 92 is 5c and this is encoded as 5c5c which is 23644 and my decoder does not de-escape yet.

Now, ALL my messages are 81 bytes long as long as the pump is at 92%. You would drop them all (or give alarm - I have not tested with your new version because I'm still at work).

So... this is NOT an error, it is just part of the protocol.

Please try to set some register to 92 (5c) and read it again.

Greetings,

Jan

2
  •  nibepi
2.12.2019  (#158)

zitat..
In both cases, register fda7 which is 43005 is marked bold. The data in the second case is obvious: 5bf0. This is 61531, in s16 this is -4005 so -400,5 GM. The message before has data 5c5cf0 - you see that the next register (as in second message) is 80a8 starting afterwards. We remove escaping and end up with 5cf0 -> -400,4. So, this is NOT an error, this is just regular escaping of data. We cannot just drop this data - just imagine the heatmeter contains "5c" for a very long time.
__________________
Im Beitrag zitiert von nibepi: Sometimes it says 80 bytes but the data received is only 79 bytes, and it takes the checksum as the last databyte.

This so far never happened with nibegw and UDP. Message length was always correct but I will add a check for this and log that too.
__________________
Im Beitrag zitiert von nibepi: All these problem with strange byte lengths have dissappered when using the new core.

I don't believe that. Maybe you just drop such frames but this way you also drop data. I can easily test that... it should be enough to set the circulation pump to 92 (0x5c). Your code will drop that message (because nibe escapes this message) or produce an error.

Hmm... lets test that right away with nibegw and my decoder that does not yet de-escape:

mosquitto_pub -h localhost -t "nibe/modbus/47414/set" -m "92"

Setting seems to work... but this results in "23644%" as pump speed (pump is running at 92% as requested). 91% and 93% show right values. Thats obvious because 92 is 5c and this is encoded as 5c5c which is 23644 and my decoder does not de-escape yet.

Now, ALL my messages are 81 bytes long as long as the pump is at 92%. You would drop them all (or give alarm - I have not tested with your new version because I'm still at work).

So... this is NOT an error, it is just part of the protocol.

Please try to set some register to 92 (5c) and read it again.

Greetings,

Jan

Thanks for all the info, chrismo too. 
Here I was wrong and my code is faulty. Seems like my code have just discarded those messages and sent no error code.
Now I can easily solve that with this new information.
I probably had two issues with heatpump.js. Timing and this 5c5c info.
This has bugged me for a long time and I was on the wrong track!

I will change it as soon as I can and publish a new package.

zitat..
Faulty message type: 92,0,32,106,7,84,156,92,92,0,139,1,15
ERROR: Corrupt payload (2364.4) from register 40020

 Thanks for putting me at the right track!
I wonder what happens if I publish value 92 to a 16 bit register. Or 192 (C0) which is the write register char. I probably need to adjust that too.


1
  •  JanRi
  •   Gold-Award
2.12.2019  (#159)
Hi,

zitat..
nibepi schrieb: wonder what happens if I publish value 92 to a 16 bit register.

 This will probably work. For me, it looks like 0x5c is no problem in packages that WE sent but I will test that again once my decoder can de-escape. Your example above (as well as mine) is already a prove because setting the register worked as we see in this answer packet. "Sending" (publishing) always contains 4 bytes for the value we want to write no matter of data type. I guess the heatpump "knows" how many bytes are relevant for the register and only uses that many bytes.


zitat..
nibepi schrieb: Or 192 (C0) which is the write register char. I probably need to adjust that too.


That we can easily test by publishing something that contains 0xc0. 

With respect to message length, I added a check to my UDP<->MQTT converter that tags packages in the log data[4]+7 != data.length. Lets see how often this happens. My guess is: Only very, very rarely.

So... now I implement a de-escaper emoji

Greetings,

Jan


1
  •  JanRi
  •   Gold-Award
2.12.2019  (#160)
Hi again,

so... 0xc0 in sending is no problem.

Just set the hot water stop temp to 19,2C -> 192.

mosquitto_pub -h localhost -t "nibe/modbus/47044/set" -m "192"

(here my interface for setting differs from yours - I set the value without taking the factor into account but I will change that sometimes that it becomes compatible with nibepi).

Second, a test for 0x5c in 16bit data:

mosquitto_pub -h localhost -t "nibe/modbus/47044/set" -m "348"

34,8C is 384 == 0x015c, so coded as 5c5c01.

Reading these registers works perfect with my new de-escaper:

// de-escape
for (i = 5; i < buf.length - 2; i = i + 1) {
if (buf==92 && buf[i+1]==92){
removed=buf.splice(i,1);
console.log("De-escaped message");
}

Greetings,

Jan

1
  •  chrismo
  •   Gold-Award
2.12.2019  (#161)

zitat..
nibepi schrieb: That cant be 5C. (Not sure why but that how it is).

That was apparently a design choice. I guess the Nibe designers wanted to keep complexity of the parser low. And ensuring that there is no single 5c helps here. You have to keep in mind that the only intended parser is part of the Modbus40 module.


1


Beitrag schreiben oder Werbung ausblenden?
Einloggen

 Kostenlos registrieren [Mehr Infos]


next