rubenbe / comfospottwin40

Control your Zehnder ComfoSpot Twin 40
MIT License
8 stars 0 forks source link

Protocol Information / Decoding of Bus info #11

Open FStelzer opened 4 days ago

FStelzer commented 4 days ago

Hi, first of all thanks very much for sharing your work on this. I own some getair smartfans and this was pretty much the only reference i could find that gives some details into the protocol used. I agree that the getair smartfan seems to be the oem vendor used by all the mentioned ones (i ordered pollen filters from getair and got kermi x-well branded ones :D ). But I'm not sure if they are all based on the same hardware revision since mine seem to not match the protocol you decoded. Can you share some more information on how you worked it out? I've sniffed some data on my rs485 bus and see a different preamble (0x00, 0x55, 0x59) and then what seems to be different packet types or a mix of packet type & identifier next (either 0x69, 0x67, 0x6b, 0xd1, 0xd3). these packets usually have a static fixed length but i cannot find any field / or part of it that would indicate this length. So looking at the packet data i'm guessing in my case it's more like "$PREAMBLE $TYPE/$IDENT $DATA $XOR/CHECKSUM". Also there's quite a bit of traffic on the bus (no big packets, but consistent small ones - like heartbeats?) which i did not expect.

So i thought i would ask if you could elaborate a bit more on your understading of the protocol you reverse engineered. Even if the details changed between hardware or oem partner i don't think they will be totally different

rubenbe commented 4 days ago

Hi,

Thanks for your confirmation on the OEM branding! Information on these things is really scarce. I cannot comment on why the protocol would be different. If you find version numbers on the controller, you could share them? Is it also exactly the comfospot40 style fans? (there are some lookalikes IIRC )

So the protocol effectively timeshares between the controller and the sensors/fans. The controller sends the desired fan speed for a zone (1 to 6). And then waits a bit to receive the sensor value. Then it does the same for the next zone. When it has looped over all the zones, it will redo this. forever.

Strictly seen this it not necessary, since the fan will remember its speed until it is powered off. It is only required to fetch the sensor values. The 6 zones are actually the 3 on the DIP switches, and the "counter" dip switch adds the other 3. So protocol wise you could have more zones than 6 zones or run the "counter" spinning fans as a real dedicated zone.

There is a known issue in my code with multiple sensors in one zone. Unfortunately I broke my second sensor so I can't really investigate & solve.

I never fully reverse engineered the checksum protocol. It is a super simple sum, but there is a weird thing when there is a zero byte (since the checksum would not change if you only have 00 bytes in a packet). In the end I chose to ignore the checksum, since it is fairly stable. Maybe I should ask an AI these days if it can find the pattern :D (If you find the packet boundaries, feel free to dump the data here, it might be interesting)

I might do more posts, since it's been a while since I did the original reverse engineering. (And update the README with more info)

If you go back more in history, you'll find more of the scripts that I used to check my understanding of the protocol while reverse engineering. https://github.com/rubenbe/comfospottwin40/blob/9afbad88644a78e66a681fb7ff265994885ad127/reverser.py You might also want to look at an old version of reader.py (I removed it since I'm no longer using it and was broken) Feel free to revive the thing and re-add it in a PR.

This test contains my understanding of the protocol on a packet level. https://github.com/rubenbe/comfospottwin40/blob/master/tests/packet_test.py

FStelzer commented 4 days ago

Thanks a lot. I'll take a look at the code and do some more analysis on the data. Actually i ran the hexdump through chatgpt & claude and it gave some pretty useful info (found the packet preambles, made some guesses about packet types & fields). Often it makes a wrong assumption (for example it took FF0055 for the preamble because packets often end in FF but not always) and follows an obviously wrong trail, but if you correct it it was quite useful. I also had it try most of the common xor/crc/adler checksums on the packet endings using various byte ranges of the packet and it concluded it's probably none of these only xor gave some results but not consistent. I'll post some more info / packet dumps when i have time to work on it in the next few days.