Zehnder ComfoAir CA350 integration via serial connection (RS232) and MQTT

Hi everyone,

first of all, thank you all very much for all these projects :smiley:
I’ve successfully connected a ComfoAir 330, ComfoAir 350 Luxe, and a ComfoAir 550 using the esphome-comfoair project.
My setup is: HomeAssistant > ESPHome > Wemos D1 mini > TTL-to-RS232 module > RJ45 Plug (CA 350/550)/ direkt for CA 330

However, after carefully investigating the (“RS232”) ComfoAir interface, I realized, that it does not follow the “true” RS232 standard, but uses 0V and ~3V respectively (see image below). I guess this means, a TTL-to-RS232 module is not even needed. Would you agree with me?

Did anyone also measure these RX/TX voltage levels, or is something wrong in my setup?

Thank you very much!

Cheers
Jonas

My set up is more simple:
Home Assistant <-> MQTT Broker <-> Computer running the CA350 python script on TrueNAS (RS232 port) <-> RS232 cable <-> Comfoair (RS232 port)

It just works and I have never tested the voltages that it is using (and I don’t know if they are in line with a standard)…

Okay, thanks for the fast reply!
I’ve just realized that the voltage levels used by CA are for logic 0: ~0V (measured up to 0.5V), and for logic 1: ~2.7V.
If I’m not wrong, with direct TTL it’s for logic 0: ~3.3/5V, and for logic 1: ~0V.
This means the UART signal coming from the MCU needs to be inverted first.

I’ll keep you updated if I find anything more.

@jo-bru ,
Can you share how you managed the wiring?

I’m really interested to see where this project goes :wink:

Dario

Hi @bremby

Sure:

1. Approach: using the RS232-to-TTL Module (MAX3232)
3.3 V MCU <=> Vcc RS232-to-TTL Module
TX MCU <=> TX RS232-to-TTL Module <=> DB9 Pin 2 (RS232 RX)/ RJ45 Pin 2
RX MCU <=> RX RS232-to-TTL Module <=> DB9 Pin 3 (RS232 TX)/ RJ45 Pin 3
GND MCU <=> GND RS232-to-TTL Module <=> DB9 Pin 5 (RS232 GND)/ RJ45 Pin 8
(For the connection from RS232-to-TTL Module to CA RJ45 Plug I soldered a DB9-to-RJ45 with the pinout shown above)

2. Approach: direct connection without RS232 Module
TX MCU <=> RJ45 Pin 3 (not 100% sure)
RX MCU <=> RJ45 Pin 2 (not 100% sure)
GND MCU <=> RJ45 Pin 8

To invert the UART TX and RX I’ve used following syntax in my ESPHome yaml file:

    tx_pin: 
      number: GPIO1
      inverted: yes
    rx_pin: 
      number: GPIO3
      inverted: yes

Problem:
Sending seems to work properly also with approach 2.
Even in inverted mode the RX pin of the MCU has an idle voltage level of ~3V. If RX and TX of the MCU are connected directly it seems to be working and the voltage levels are as wanted: logic 0: 0V , logic 1: ~3V.
However, if the CA is connected directly (approach 2) the voltage levels for the RX Channel (MCU perspective) are logic 0: ~2,4V, logic 1: ~5V. And therefore cannot be read properly by the MCU.

Does anyone have an idea how to force/lower the RX voltage levels?

CA RJ45 Interface: (taken from this discussion)

P.s. The voltage levels and pin numbers might not be as described above, as I’m currently out of office and cannot check them again. But I’ll update any errors when I’m back.

Why don’t use a step down converter?

Set up this integration with my WHR930 basic, which has a RS232 port in RJ-45 form. Connected to my RPI, but the code doesn’t interpret the received byte arrays correctly.

I limited the code to just getting a ‘get_temp’ to debug, but it shows me a lot of empty bytes. So I also added a piece of code to strip the byte array of its ‘00’ values in order to get some readable data. Still the code fails to recognize the received bytes.

I thought I would post it here in order to see if anyone understands what is going on here:

12-09-2022 11:28:35 DEBUG: Executing function <function get_temp at 0xffffa5a314c0>
12-09-2022 11:28:37 DEBUG: hex data is: ['00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', 'f1', '32', '10', '1f', 'ff', '5b', 'ed', '5f', '53', '51', '51', '51', 'e1', '4b', '4b', '4b', '5f', 'f1', 'e1', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00']
12-09-2022 11:28:37 DEBUG: actual data = ['f1', '32', '10', '1f', 'ff', '5b', 'ed', '5f', '53', '51', '51', '51', 'e1', '4b', '4b', '4b', '5f', 'f1', 'e1']
12-09-2022 11:28:37 WARNING: Checksum doesn't match (222 vs 0). Message ignored
12-09-2022 11:28:37 DEBUG: serial_data is empty
12-09-2022 11:28:37 WARNING: get_temp function could not get serial data
12-09-2022 11:28:42 DEBUG: Executing function <function get_temp at 0xffffa5a314c0>
12-09-2022 11:28:44 DEBUG: hex data is: ['00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '7c', '06', 'e2', '1f', 'ff', '5b', 'ed', '5f', '98', '45', '45', '45', '41', 'de', 'a9', 'a9', '29', '5f', 'f1', 'e1', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00']
12-09-2022 11:28:44 DEBUG: actual data = ['7c', '06', 'e2', '1f', 'ff', '5b', 'ed', '5f', '98', '45', '45', '45', '41', 'de', 'a9', 'a9', '29', '5f', 'f1', 'e1']
12-09-2022 11:28:44 WARNING: Checksum doesn't match (8 vs 0). Message ignored
12-09-2022 11:28:44 DEBUG: serial_data is empty
12-09-2022 11:28:44 WARNING: get_temp function could not get serial data

So I’m following this thread with fascination. However we have a Zender Comfoair PRO 300.

If I google I don’t find much info on it except for:
Zehnder ComfoAir PRO 300 | Zehnder België (see Downloads for manual)
Zehnder pronkt met budgetmodel ComfoAir Pro 300

It seems to me like a stripped version of the 350Q but with a touch display on top.
Anyone have an idea what I can do to communicate with the device, and by that I mean don’t spend too much money on their overprized hubs.

You can find an installers manual (in dutch) here:

1 Like

Looks like you can control it via analog input (0-10V) or via 230V inputs. But there seems not to be any interface that would allow to read status or temperatures.

Yah, I was thinking that much (about reading value.

Are there any places where is explained how I can control the analog input and bathroom switch (BS)? 0-10V.
Is it possible to split the cables that e.g. connect to connector S44 (outside temperature) to “sniff” the value?

At the moment they hardwired
Niko draaischakelaar 3 standen 0-1-2 of 1-2-3 - Nikostore.nl to it
connected in 1-2-3 mode

I was thinking to use the L1,L2,L3 wires that are screwed to the ventilation system and connect them to a Shelly 2.5 (or another device? not sure about wiring, as I only connected a Shelly 1PM to some fuses to do some measurements before)

Does that make sense at all?

I would then remove the Niko dial switch and look for some smart device with 3 input buttons to set the fan speeds (any suggestions?). And probably mount it at a more central place in the home.

I was personally thinking at the Hue Remote since I have a Hue bridge and configure the 3 top buttons for the FAN and the bottom one for the BS function.

For the 0-10V input you could use a module with such output e.g. a dimmer (zigbee, zwave or wifi) either ready to use or a module connected to esp board.
For the 3 230V inputs you could use shelly 2.5 but it will cover only 2 speeds so you’ll need another one for the 3rd input. Or a board/relay module with required number of outputs (e.g. there are ready to use esp based relay boards, Sonoff 4CH Pro or similar)

Echoing some of the issues from above I can’t get any serial data - getting constant warnings “could not get serial data”. Sometimes it says “Expected return not found” as well, but sometimes it doesn’t. I’ve tried everything mentioned above I think - different usb/ftdi adaptors, swapping rx and tx lines, different network cables, leaving it running overnight, but nothing seems to work. It’s a CA350 with the RJ45 port and no other controls attached. RJ45 >FTDI RS232 adaptor > USB > Raspi 3. Both lights on the RS232 adaptor seem to flash. I don’t know what else to try.

I would once again check carefully this post:

Also make sure that you are configuring correct USB device name in the configuration file.
I’ve had problems with connecting to RJ45 socket if I remember correctly so I’ve connected mine to the RS232 port, which is inside of the device. You can also connect cables directly to the screw terminal on the unit (in my case the Ease controller was connected to it). So there are 3 options which you could check - they are all on the box on top of the unit, don’t connect to the one in front of it as I think there is RJ45 port as well.

If you are still interested there were some people reverse engineering the protocol for the Q models that work without the LAN module. Not sure if this is a fully working solution though:

Thank you for getting back to me, really appreciate it. Unfortunately mine only has one circuit board inside and no RS232 port or box on top. The empty connectors are for the front display, preheater etc none for serial apart from the RJ45. Out of interest does your machine constantly send data on serial or only when prompted? Just it would make it easier to test other lines if I’m expecting some data.

As far as I know it only sends data when you send the request for it. That’s also how the program is constructed. But I’ve never tried to sniff the traffic so maybe there is something going on.
Try to enable the debug mode in config and see if there are any meaningful messages.

Hey hif2k1,

I think my problem is similar to yours, as I get the same errors you mention and my circuit board looks exactly the same. See my post with my results here

My suspicion is that this board has the RJ45 only for debugging (or some other purpose) that uses a different protocol. As it doesnt even give correct acknoledgements back.

Would like to know for sure but I dont have the technical know how in order to determine if we can do anything else.

edit: as adorobis already mentions here I tested with a serial monitor and it really only gives of data when it receives a request first.

edit2: although another blog post has similar circuit and is able to talk to it succesfully

edit3: Looking at the PDF, what we have is the default circuit board only. There is an optional ‘connector board’, which is what adorabis’ picture shows as well. This has additional connectors, including the RS232 plug. The pdf is clear that you should be able to connect with the default board as well, so I am still stumped why the code is not running as it should…

1 Like

Yes I wonder if on later models (mine is new) they are disabling this somehow so people have to buy their controls. I’m afraid I’ve given up now and opted to use a small relay board to control the three speeds, but I’m sad to miss out on all the data about temperatures and efficiency. This approach is also not so safe as you are playing with grid voltages. Maybe one day I’ll have an oscilloscope and be able to figure it out properly. If anyone finds the trick then let me know.

Hi,

I just stumbled upon this integration. Right now I am only using loxone but I am considering to switch home assistant to controll all kinds of integrations which loxone can not (nano leaves, outdoor motion sensor (zigbee), etc).

I was looking @ integration possibilities for my ventilation unit and ended on this topic.
One thing I am missing though is to read the status of my ComfoFond L (heat exchanger / EWT). I Do see commands related to this in the reverse engineered command list though.

0x00 0xD1 Temperaturen abrufen
0x00 0xEB EWT / Nachheizung abrufen
0x00 0xED EWT / Nachheizung setzen

Would it be possible to add functionality to be able to read the “EWT” temperature and to be able to set the high and low temperature on which the EWT has to operate?