A simple serial port with a baud rate of 4800 8E2.
Vitosoft is searching for Wireless Access Point VIESSMANN-12345678
. 12345678
is the password to the WLAN Access Point. After connecting to the access point, it creates a TCP Connection to 10.45.161.1:45317
(10.x.x.x is a private Class-A network), which is treated very similar to the serial port, except sync is not necessary – it seems to be managed on the device side. Besides that it seems identical to the VS2 protocol.
Communication is a package based serial communication. In pseudo-code it works like this:
sendPackage()
for retry=0 to RETRYCOUNT
if hasReply() then
receiveReplyPackage()
return
sleep(RETRYDELAY)
In the following section I write RETRYCOUNT x RETRYDELAY ms
, e.g. 10x50ms
to define the delays.
The GWG protocol is only used for old "Gas Wand Geräte" (Gas Wall Units). It is detected, but no longer supported by the Vitosoft 300 application. It only supports 8-bit addresses with several function codes, allowing a slightly larger address space.
The detection works as follows: wait up to 10x50ms for an ENQ
(0x05). Then send 0xC7,0xF8,0x04
(Virtual Read 0xF8, 4 bytes). The reply should be 0x20,0x53
or 0x20,0x54
to detect the GWG hardware. 0x20
is the "Gruppenidentifikation" (group identification) and 0x53
or 0x54
are the "Regleridentifikation" (controller unit identification)
Version 1 of the Vitotronic protocol, supported by the KW units from Viessmann. It supports 16-bit addresses plus several function codes.
Because the whole communication is timing based, a timer is called every 50ms to check the current state of the connection and does the following:
- after opening the serial port or in case of an error, a connection is created by waiting for up to 30x100ms for an
ENQ
(0x05). It then immediately is confirmed by sending a0x01
. In case anVS2_ACK
(0x06
) orVS2_NACK
(0x15
) was received, the VS2 protocol is also supported. - If there is a pending message to be send, the message is written out and for up to 20x50ms serial data is read. Once the number of expected bytes have been received, the data is then processed. If within the giving time, not enough data was received, a connection reset it triggered (see step #1)
- If nothing needs to be send to the unit, every 500ms the connection is kept alive, by sending a check connection message (Virtual Read: 0xF8, 2 bytes), which expects a 2-byte reply within 20x50ms.
The message is a simply list of bytes:
- Command/Function Code (
Virtuell_Write
=0xF4
,Virtuell_Read
=0xF7
,GFA_Read
=0x6B
,GFA_Write
=0x68
,PROZESS_WRITE
=0x78
,PROZESS_READ
=0x7B
) - Address High Byte
- Address Low Byte
- Block Length
- For write functions: Block Length additional bytes
Read functions send a reply containing of the number of bytes in the block. All write functions send a single byte vs1_data
, which is 0x00
in case the write was successful, any other value is undefined and is a failure.
Version 2 of the Vitotronic protocol. It is supported by all modern Viessmann units. These modern units also seem to be backward compatible with the VS1 protocol. It is an extension of the VS1 protocol, mostly to be faster and more reliable – thanks to checksums. But it is also more complex, because of hand-shaking requirements.
To initiate the connection, after the serial port read buffer is emptied, then an EOT
(0x04
) is send and for 30x100ms waited for an ENQ
(0x05
), after which a VS2_START_VS2, 0, 0
(0x16,0x00,0x00
) is send and within 30x100ms an VS2_ACK
(0x06
) is expected. If an VS2_ACK
(0x06
) is received, before the start was sent, the start is resent (and the timeout is reset). In case a VS2_NACK
(0x15
) is received, it also resents the start and resets the timeout.
After message is send, for up 30x100ms serial data is read. An VS2_ACK
(0x06
) or VS2_NACK
(0x15
) is expected first. If more than one is received, the oldest ones are removed from the receive buffer. If it is not received as the first byte, the message was not send successfully. Further bytes are collected till a full message is received. If the checksum is valid, an VS2_ACK
is send out to confirm the successful transmission. A VS2_NACK
is never send!
If no message was send within 5s, the connection is restarted, the serial port read buffer is emptied and then sending a VS2_START_VS2, 0, 0
(0x16,0x00,0x00
) and within 30x100ms expecting an VS2_ACK
(0x06
).
In case a UNACKD Message was send, only a single VS2_ACK
or VS2_NACK
is expected.
The message requires a simple checksum.
VS2_DAP_STANDARD
(0x41)- Package length for the CRC
- Protocol Identifier (0x00 = LDAP, 0x10 = RDAP, unused) | Message Identifier (0 = Request Message, 1 = Response Message, 2 = UNACKD Message, 3 = Error Message)
- Message Sequenz Number (top 3 bits in the byte) | Function Code
- Address High Byte
- Address Low Byte
- Block Length
- Block Length additional bytes
- CRC, a modulo-256 addition of bytes from Block Length and the additional bytes. CRC is technically the wrong name, it is more a checksum. But that is what Viessmann calls it.
There are many commands defined, but only very few are actually used by Vitosoft, which seems to be Virtual_READ
, Virtual_WRITE
, Remote_Procedure_Call
, PROZESS_READ
, PROZESS_WRITE
, GFA_READ
, GFA_WRITE
.
Here is the complete list:
undefined
= 0Virtual_READ
= 1Virtual_WRITE
= 2Physical_READ
= 3Physical_WRITE
= 4EEPROM_READ
= 5EEPROM_WRITE
= 6Remote_Procedure_Call
= 7Virtual_MBUS
= 33Virtual_MarktManager_READ
= 34Virtual_MarktManager_WRITE
= 35Virtual_WILO_READ
= 36Virtual_WILO_WRITE
= 37XRAM_READ
= 49XRAM_WRITE
= 50Port_READ
= 51Port_WRITE
= 52BE_READ
= 53BE_WRITE
= 54KMBUS_RAM_READ
= 65KMBUS_EEPROM_READ
= 67KBUS_DATAELEMENT_READ
= 81KBUS_DATAELEMENT_WRITE
= 82KBUS_DATABLOCK_READ
= 83KBUS_DATABLOCK_WRITE
= 84KBUS_TRANSPARENT_READ
= 85KBUS_TRANSPARENT_WRITE
= 86KBUS_INITIALISATION_READ
= 87KBUS_INITIALISATION_WRITE
= 88KBUS_EEPROM_LT_READ
= 89KBUS_EEPROM_LT_WRITE
= 90KBUS_CONTROL_WRITE
= 91KBUS_MEMBERLIST_READ
= 93KBUS_MEMBERLIST_WRITE
= 94KBUS_VIRTUAL_READ
= 95KBUS_VIRTUAL_WRITE
= 96KBUS_DIRECT_READ
= 97KBUS_DIRECT_WRITE
= 98KBUS_INDIRECT_READ
= 99KBUS_INDIRECT_WRITE
= 100KBUS_GATEWAY_READ
= 101KBUS_GATEWAY_WRITE
= 102PROZESS_WRITE
= 120PROZESS_READ
= 123OT_Physical_Read
= 180OT_Virtual_Read
= 181OT_Physical_Write
= 182OT_Virtual_Write
= 183GFA_READ
= 201GFA_WRITE
= 202