hardware:vaillantvrt340f_protocol
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende ÜberarbeitungNächste ÜberarbeitungBeide Seiten der Revision | ||
hardware:vaillantvrt340f_protocol [2017/05/03 19:08] – reinhold | hardware:vaillantvrt340f_protocol [2017/05/05 11:28] – reinhold | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
====== Vaillant CalorMatic 340f (868MHz) PART 2: Decoding the wireless protocol of the heating control | ====== Vaillant CalorMatic 340f (868MHz) PART 2: Decoding the wireless protocol of the heating control | ||
+ | - [[hardware: | ||
+ | - [[hardware: | ||
+ | - **[[hardware: | ||
After we investigated the wireless signal that was sent by the Vaillant CalorMatic 340f over the 868MHz frequency and extracted the binary contents [[hardware: | After we investigated the wireless signal that was sent by the Vaillant CalorMatic 340f over the 868MHz frequency and extracted the binary contents [[hardware: | ||
+ | {{: | ||
+ | |||
+ | As a quick recap of the first part, the signal from the wireless control is sent at **868.275MHz** with **OOK** modulation. The underlying encoding is **differential Manchester encoding** (with a signal **bitrate of 606Hz**, where a transition in the middle of the period indicates a 1 and no transition indicates 0; a transition after each bit period is guaranteed for clock synchronization and does not hold any information). In addition, the bit sequence (except for the final to 0xFF 00 bytes!) is **bit-stuffed**, | ||
Zeile 31: | Zeile 37: | ||
^Description | ^Description | ||
- | |Heating\ ON,\ Water\ OFF || '' | + | |Heating\ ON,\ Water\ OFF || '' |
- | |Heating\ ON,\ Water\ OFF\ (Rep.) | + | |Heating\ ON,\ Water\ OFF\ (Rep.) |
- | |Heating\ OFF,\ Water\ OFF || '' | + | |Heating\ OFF,\ Water\ OFF || '' |
- | |Heating\ OFF,\ Water\ OFF\ (Rep.) | + | |Heating\ OFF,\ Water\ OFF\ (Rep.) |
- | |Heating\ ON,\ Water\ ON || '' | + | |Heating\ ON,\ Water\ ON || '' |
- | |Heating\ ON,\ Water\ ON\ (Rep.) | + | |Heating\ ON,\ Water\ ON\ (Rep.) |
- | |Heating\ OFF,\ Water\ ON || '' | + | |Heating\ OFF,\ Water\ ON || '' |
- | |Heating\ OFF,\ Water\ ON\ (Rep.) | + | |Heating\ OFF,\ Water\ ON\ (Rep.) |
- | |Heat.\ ON,\ Water\ OFF,\ Batt.\ LOW || '' | + | |Heat.\ ON,\ Water\ OFF,\ Batt.\ LOW || '' |
- | |Heat.\ ON,\ W.\ OFF,\ Batt.\ LOW\ (Rep.) || '' | + | |Heat.\ ON,\ W.\ OFF,\ Batt.\ LOW\ (Rep.) || '' |
- | |Heat.\ OFF,\ W.\ OFF,\ Batt.\ LOW || '' | + | |Heat.\ OFF,\ W.\ OFF,\ Batt.\ LOW || '' |
- | |Heat.\ OFF,\ W.\ OFF,\ Batt.\ LOW\ (Rep.)|| '' | + | |Heat.\ OFF,\ W.\ OFF,\ Batt.\ LOW\ (Rep.)|| '' |
- | |Heat.\ ON,\ W.\ ON,\ Batt.\ LOW || '' | + | |Heat.\ ON,\ W.\ ON,\ Batt.\ LOW || '' |
- | |Heat.\ ON,\ W.\ ON,\ Batt.\ LOW\ (Rep) || '' | + | |Heat.\ ON,\ W.\ ON,\ Batt.\ LOW\ (Rep) || '' |
- | |Heat.\ OFF,\ W.\ ON,\ Batt.\ LOW || '' | + | |Heat.\ OFF,\ W.\ ON,\ Batt.\ LOW || '' |
- | |Heat.\ OFF,\ W.\ ON,\ Batt.\ LOW\ (Rep.) || '' | + | |Heat.\ OFF,\ W.\ ON,\ Batt.\ LOW\ (Rep.) || '' |
- | In this table, I already split the binary signal into octets, i.e. bytes. | + | In this table, I already split the binary signal into octets, i.e. bytes. |
- | + | ||
- | Somehow that is strange... As my reasoning below shows, that extra byte must be before the final three bytes, but after the fourth-to-last one. So we have the 9-bit sequence 101111101 that we must make sense of. After some googling, I stumbled upon the [[https:// | + | |
===== The individual parts of the signal ===== | ===== The individual parts of the signal ===== | ||
Zeile 68: | Zeile 72: | ||
The next byte 12 has one bit set if battery is LOW and is zero otherwise. | The next byte 12 has one bit set if battery is LOW and is zero otherwise. | ||
- | The next byte 13 is always the same, then one additional 1 bit appears. | + | The next byte 13 is always the same. |
The next byte 14 is the most interesting, | The next byte 14 is the most interesting, | ||
- | The two final bytes 15-16 are constant and always have the value 0xFF 00, which makes again sense considering the physical encoding, i.e. 0xFF will be a quickly oscillating square ware, and the final 0x00 byte will be a slowly oscillating square wave. | + | The two final bytes 15-16 are constant and always have the value 0xFF 00, which makes again sense considering the physical encoding, i.e. 0xFF will be a quickly oscillating square ware, and the final 0x00 byte will be a slowly oscillating square wave and not contain any information any more. |
===== Re-writing the signal as HEX bytes ===== | ===== Re-writing the signal as HEX bytes ===== | ||
Zeile 82: | Zeile 86: | ||
Our sixteen base signals from above now become: | Our sixteen base signals from above now become: | ||
- | ^Heat.^Wat.^Rep.^Bat.| '' | + | ^Heat.^Wat.^Rep.^Bat.| '' |
- | | Heating ON | Water OFF | | OK | '' | + | | Heating ON | Water OFF | | OK | '' |
- | | Heating ON | Water OFF | X | OK | '' | + | | Heating ON | Water OFF | X | OK | '' |
- | | Heating OFF | Water OFF | | OK | '' | + | | Heating OFF | Water OFF | | OK | '' |
- | | Heating OFF | Water OFF | X | OK | '' | + | | Heating OFF | Water OFF | X | OK | '' |
- | | Heating ON | Water ON | | OK | '' | + | | Heating ON | Water ON | | OK | '' |
- | | Heating ON | Water ON | X | OK | '' | + | | Heating ON | Water ON | X | OK | '' |
- | | Heating OFF | Water ON | | OK | '' | + | | Heating OFF | Water ON | | OK | '' |
- | | Heating OFF | Water ON | X | OK | '' | + | | Heating OFF | Water ON | X | OK | '' |
- | | Heating ON | Water OFF | | LOW | '' | + | | Heating ON | Water OFF | | LOW | '' |
- | | Heating ON | Water OFF | X | LOW | '' | + | | Heating ON | Water OFF | X | LOW | '' |
- | | Heating OFF | Water OFF | | LOW | '' | + | | Heating OFF | Water OFF | | LOW | '' |
- | | Heating OFF | Water OFF | X | LOW | '' | + | | Heating OFF | Water OFF | X | LOW | '' |
- | | Heating ON | Water ON | | LOW | '' | + | | Heating ON | Water ON | | LOW | '' |
- | | Heating ON | Water ON | X | LOW | '' | + | | Heating ON | Water ON | X | LOW | '' |
- | | Heating OFF | Water ON | | LOW | '' | + | | Heating OFF | Water ON | | LOW | '' |
- | | Heating OFF | Water ON | X | LOW | '' | + | | Heating OFF | Water ON | X | LOW | '' |
Summarizing our interpretation of the individual bytes of the signal: | Summarizing our interpretation of the individual bytes of the signal: | ||
Zeile 110: | Zeile 114: | ||
^11 | ^11 | ||
^12 | 0x00 | Battery: 0x00 for OK, 0x01 for LOW (bit 1) || | ^12 | 0x00 | Battery: 0x00 for OK, 0x01 for LOW (bit 1) || | ||
- | ^13 | + | ^13 |
- | ^Bit | 1 | Unknown, single 1 bit || | + | |
^14 | ^14 | ||
^15-16| 0xFF 00 | End of Signal || | ^15-16| 0xFF 00 | End of Signal || | ||
Zeile 144: | Zeile 147: | ||
So, the checksum seems to be simple complement of the sum of all bytes. After a few trials, one notices that bytes 4-12 and the checksum byte 14 always sum up to 0x300, i.e. 0x00! So the checksum is simply the complement of bytes 4-12 summed up. | So, the checksum seems to be simple complement of the sum of all bytes. After a few trials, one notices that bytes 4-12 and the checksum byte 14 always sum up to 0x300, i.e. 0x00! So the checksum is simply the complement of bytes 4-12 summed up. | ||
- | Also, this result clearly shows that the checksum | + | Bytes 3, 13 and 15 seem to be special and not included in the checksum, but this just confirms our suspicion |
+ | |||
+ | ==== UPDATE: Making sense of the 0xFD byte 13 ==== | ||
+ | The byte 13 with unknown constant value 0xFD kept bothering me, and a few days after I understood the checksum byte I figured out its meaning too: As I mentioned, bytes 4-12 together with the checksum byte 14 summed up always yielded 0x0300. It seemed strange to me that the 0x03 byte of the sum was somehow ignored, until I realized that 0xFD is actually the binary complement of 0x03, i.e. the checksum is actually just byte 14, but the two-byte value of bytes 13 and 14. So, our assumption that bytes 13 with a value of 0xFD is some kind of End-Of-Data or separator byte was simply wrong, and it being constant is just a coincidence. | ||
+ | |||
+ | In short, bytes 13 and 14 are simply | ||
+ | |||
===== The heating byte ===== | ===== The heating byte ===== | ||
We saw that turning on the heating always meant for byte 11 to be set to 0xB4, while turning off the heating set byte 11 to 0x00 (which is what we would expect). But why 0xB4? | We saw that turning on the heating always meant for byte 11 to be set to 0xB4, while turning off the heating set byte 11 to 0x00 (which is what we would expect). But why 0xB4? | ||
+ | Looking at the manual of the Vaillant calorMatic 340f heating control system, one can learn that the control also has an expert mode for the following settings: | ||
+ | * Default ECO temperature => no effect on signal | ||
+ | * Room temperature adjustment (if the temperature where the control is placed does not reflect the real room temperature) => no effect on signal | ||
+ | * 2-point-mode / Analogue mode: In two-point mode, the heating will turn on if the temperature falls below a given threshold and turn off once it reaches a given threshold (=target temperature). In analogue mode, the heating will be different depending on how far the current temperature is from the target temperature. Enabling analogue mode has a large influence on the signal, as the heating ON/OFF signal is no longer sufficient, but a heating percentage needs to be sent: | ||
+ | * if current temp is more than 1 degree below target, heating will be fully on; | ||
+ | * if current temp is more than 1 degree above target, heating will be off; | ||
+ | * Between target temp +- 1 degree, heating will be linear between off and fully on | ||
+ | * Control mode (sensitivity/ | ||
+ | * day / month / year => no effect on signal | ||
+ | |||
+ | If we switch to analogue mode, we can observe various different values for the heating byte, depending on the current room temperature. Here are a few examples of the heating byte: | ||
+ | |||
+ | ^ Target temp. ^ Room temp ^ Heating byte ^ Comment ^ | ||
+ | ^ 21.5 ^ 22.5 | 0x15 | Heating byte increases with increasing target temperature | | ||
+ | ^ 22 ^ 22.5 | 0x26 | ::: | | ||
+ | ^ 22.5 ^ 22.5 | 0x31 | ::: | | ||
+ | ^ 23.5 ^ 22.5 | 0x4B | ::: | | ||
+ | ^ 24 ^ 22.5 | 0x5A | ::: | | ||
+ | ^ ^^^^ | ||
+ | ^ 24 ^ 23.5 | 0x3B | Absolute value of target temp is irrelevant => Difference of room and target temperature is relevant | | ||
+ | ^ 22.5 ^ 22 | 0x3B | ::: | | ||
+ | ^ ^^^^ | ||
+ | ^ 22.5 ^ 22.5 | 0x2C | Same displayed room + target temperature (0.5 C steps!) can lead to different heating bytes (but only within limited range) => Internally, the sensor has a higher accuracy than 0.5°C. | | ||
+ | ^ 22.5 ^ 22.5 | 0x34 | ::: | | ||
+ | ^ 22.5 ^ 22.5 | 0x31 | ::: | | ||
+ | ^ 22.5 ^ 22.5 | 0x2F | ::: | | ||
+ | ^ 22.5 ^ 22.5 | 0x2C | ::: | | ||
+ | ^ ^^^^ | ||
+ | |||
+ | What we also observe is that the heating will still be turned on for target temperatures up to 1°C below the current room temperatur (i.e. no need to heat up the room, because it's already warm enough!), but with a low value of the heating byte. And for target temperatures above current temperature + 1°C, the heating byte will not change any more (0x5A = 90 decimal), indicating that the maximum heating intensity is already reached for target temperature of room temperature plus 1°C. | ||
+ | |||
+ | The final indication that we need can be found in the diagnosis mode of the control: The manual states that when diagnosis mode is initiated, the boiler will be instructed to heat the water for the heating to exactly 50° C. When enabling diagnosis mode (pressing the " | ||
+ | |||
+ | '' | ||
+ | 0x00 00 7E 6D F6 00 20 00 01 80 32 00 FD CA FF 00'' | ||
+ | |||
+ | So, the heating byte 0x32 corresponds to a heating water temperature of 50°C. If you are used to hex numbers, you probably already saw it. If not, let's just write the heating bit in decimal: 0x32 = 50. | ||
+ | This can't be a coincidence! The heating byte must be the target temperature of the heating water. | ||
+ | |||
+ | This makes perfect sense: The values observed (for " | ||
+ | |||
+ | If 2-point mode is enabled, bit 8 is set and bits 1-7 carry a value of 52°C, in analogue mode bit 8 is never set and bits 1-7 carry the target heating water temperature. | ||
+ | So, | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ====== The Full Data Frame Specification ====== | ||
+ | |||
+ | The data is sent in frames of 16 bytes, where the actual data is contained in bytes 4-12, and bytes 13-14 are a 2-byte checksum. | ||
+ | |||
+ | Summarizing our interpretation of the individual bytes of the signal: | ||
+ | ^Byte ^^ Value ^Description ^ | ||
+ | ^1-2 || 0x00 00 | Preamble (square wave to synchronize clocks with the receiver) | | ||
+ | ^3 || 0x7E | Begin of frame/data (Constant) | | ||
+ | ^ 4-14 || Data content of the frame with 2-byte checksum attached || | ||
+ | | ^4-5 | 0x6D F6 | Device ID (Constant for each device) | | ||
+ | |::: ^6-8 | 0x00 20 00 | Unknown (constant, bit 6 of byte 7 always set) | | ||
+ | |::: ^9 | 0x00/01 | Repeat: 0x00 for original signal, 0x01 for repeat signal (bit 1) | | ||
+ | |::: ^10 | 0x80/88 | Pre-heated Water: 0x80 for ON, 0x88 for OFF (bit 8 always set, bit 4 indicates water) | | ||
+ | |::: ^11 | 0xB4/00/... | Heating: 0x00 for OFF, 0xB4 for ON, Target heating water temperatur for analogue mode | | ||
+ | |::: ^12 | 0x00 | Battery: 0x00 for OK, 0x01 for LOW (bit 1) | | ||
+ | |::: ^13-14 | 0xFD .. | 2-byte Checksum (signed integer): negative of the sum of bytes 4-12 | | ||
+ | ^15 || 0xFF | End of Signal indicator | | ||
+ | ^16 || 0x00 | Epilogue (no data any more) | | ||
+ | |||
+ | All bytes are converted to a bit sequence with least-significant bit first. | ||
+ | |||
+ | For transmission over the 868,275MHz frequency, the data contents (bytes 4-14, but NOT bytes 3 and 15) are bit-stuffed (i.e. after five consecutive one bits, one extra zero bit is inserted). The resulting bit sequence is then encoded using differential Manchester encoding (1 is encoded as a transition, 0 as no transition) based on an underlying square wave of frequency 303Hz. Each bit period will be a half-wavelength, | ||
+ | Each signal is first sent with byte 9 set to 0x00 and shortly afterwards repeated with byte 9 set to 0x01 (and the checksum updated correspondingly). | ||
- | ===== The spurious extra bit between | + | ====== Implementing support for the device in rtl_433, rflink and/or OpenHAB ====== |
+ | Now that we understand both the physical layer of the signal, as well as the structure of the protocol, we can go on to [[hardware: |
hardware/vaillantvrt340f_protocol.txt · Zuletzt geändert: 2017/05/11 19:28 von reinhold