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

How have you installed the program? In any case just try to restart it and see if it helps. Otherwise check logs to see if there is any indication of an error.

Thank you very my for your quick feedback, adorobis.
Puh, it`s quite a long time ago…

I installed it according your guideline here (hope there was just one :wink: ).
How can I restart this instead of restarting the whole system?
Rebooting the system didn`t help.

Thank you and have a nice evening.

Anyway, why don’t you check what entities you have in HA. Go to Settings->Devices&Services->MQTT and select your device (default name is CA350). You should see something like that:


and a pretty long list of sensors:

Which one are you missing?

Thank you very much for your support.
I didn`t had in mind to check entities in MQTT.
The entity “binary_sensor.comfoair350_wohnraumluftung_filter_status” was not shown in my dashboard. I have updated it now.

Now it`s visible again, but not in the visualized view:

There is just a grey sand clock visible and the entity is not listed in the MQTT-List.
I have in mind, that this was different before.

If the filter time has exceeded, I was normally able to reset this by pushing the “Filter Reset-Button”.

But here also nothing happens anymore.

Sorry for so many questions. Have a nice day.

Yes, it should look like that (or red in case filter requires replacement):


Could you go to yaml mode of the card config and check if you have proper entity id defined there:

Make sure it is the same as the one you can see in your device:

I have been fixing it recently and should now work reliably. You can get the latest version of the program from here:

or if you are using docker, the image has been also updated.

Thank you Adoboris.
I have checked all entities-they seem to be right.

Maybe the problem ist, that I don`t use the repaired version until now.
I have replaced thoe code you have posted in this file:

/homeassistant/custom_components/ca350/ca350.py

After doing so and restarting the system CA350 Items don`t work anymore.
Seems to be a failure in the configuration.

Maybe you can give some more hints.

Thank you so much.

I’d start with checking the logs. Don’t know how old was your program. Could you share your config file? You can remove mqtt password from it if you have one.
And if it was working before just restore to your previous code. In this case I’d check what’s wrong with the dashboard card - maybe simple browser cache clearing will solve it?

Hello Adorobis,

I`m using this program version (should be the latest version):

Clearing the Browser Cach didn`t help, this problem also remains on my mobile device.

The LOG-File shows, that I have pushed the Button “Reset Filter” several times, but the red Icon still remains.

Thank you.

Can you double check that you have the latest ca350.py program? E.g. latest update was to have the reset filter function to look like that:

def reset_filter_timer():
    data = send_command(b'\x00\x37', b'\x00\x80\x00\x00\x00\x00\x02', expect_reply=False)
    data = send_command(b'\x00\x37', b'\x00\xC0\x00\x00\x00\x00\x03', expect_reply=False)

    if data is None:
        warning_msg('reset_filter_timer function could not get serial data')
    else:
        get_filter_weeks()
        get_filter_hours()
        get_filter_status()

Regarding the log, not sure how it behaves in your installation type, but the program is generating its own log file, maybe check if it is in the same place as where your program sits?

@adorobis
If you don’t have CC Ease connected, you might want to reset the ms value of the button to 0 at the end (as CC Ease cyclically sends all buttons 0 when no button is pressed):

data = send_command(b'\x00\x37', b'\x00\x80\x00\x00\x00\x00\x02', expect_reply=False)
data = send_command(b'\x00\x37', b'\x00\xC0\x00\x00\x00\x00\x03', expect_reply=False)
data = send_command(b'\x00\x37', b'\x00\x00\x00\x00\x00\x00\x02', expect_reply=False)

It will probably have a timeout and work anyway, but who knows.

Alternatively, you could try using this command to reset the filter hours (though I haven’t tested it myself yet):

Interestingly non of the options work for me anymore. Maybe because I’ve reset the filter a few weeks ago successfully sending the two button press commands - at that time filter was past the timer. But now the status of the filter is OK and hours ~670h. Can’t reset it at this stage - maybe this is standard behavior?

Reset from the CC Ease (with long button press) is probably only possible, if filter warning is active.
Did you also try with the 0xDB commad?
My guess is, that this should always work.

Yes, I’ve tried this one as well. No effect.I’ll check again once in ~12 weeks :slight_smile:

Hello Adorobis,

I have replaced my old ca350.py File with the new file you mentioned.
If I do so, after restart all Entities are unavailable.

I have not found any line to change/customize in this file.
Did I miss something?
Is it just abou to replace this oine file “ca350.py” wih the new code?

Thank you very much.

Depending how old your version was you might need to update the config.ini file as well. There were some new options added but that was already somewhere a year ago.
Instead of guessing I’d suggest that you try to run the program from command line - this way you’ll see what error the program is facing and we can resolve it. From the HAOS command line run: source /config/custom_components/ca350/python3venv/bin/activate && python3 /config/custom_components/ca350/ca350.py

I have exactly the same problem with “unknown.” Can you help me? How did you solve the problem?

Hi @adorobis ,

I have a CA300 as well and I’m seeing the same issue. The incorrect exhaust RPM readings mostly appear at lower fan speeds. At medium/high everything looks stable.

After digging into it, it doesn’t seem like a serial issue but more like a parsing issue. get_fan_status() sometimes returns 6 bytes when values are correct, but 7 (or even 8) bytes when they go wrong.

Some examples:

High (OK, 6 bytes)
47 42 04 10 04 84 → ~1800 / 1600 rpm

Medium (OK, 6 bytes)
35 30 05 62 05 B4 → ~1360 / 1280 rpm

Low (OK, 6 bytes)
32 2D 05 8E 06 0E → ~1318 / 1209 rpm

Absent (problematic; mostly 7 bytes, sometimes 8)

23 1E 07 07 98 08 6C
• 2:4 = 07 07 → 1042 rpm
3:5 = 07 98 → 964 rpm
• 4:6 = 98 08 → 48 rpm
5:7 = 08 6C → 869 rpm

25 20 07 07 5E 07 07 E2
3:5 = 07 5E → 994 rpm
6:8 = 07 E2 → 929 rpm

In these cases, the valid RPM values are still present, but appear shifted.

My current assumption is:
• 6-byte case:

[speed1][speed2][rpm1_hi][rpm1_lo][rpm2_hi][rpm2_lo]

• 7/8-byte case:

[speed1][speed2][opt_flag][rpm1_hi][rpm1_lo][opt_flag][rpm2_hi][rpm2_lo]

So it looks like extra 0x07 flag bytes may be inserted (possibly at lower fan speeds), which shift the RPM fields. When the parser assumes a fixed 6-byte layout, the second RPM gets misaligned and can decode to very low values.

Not 100% sure, but this seems to explain why the exhaust RPM in particular drops to unrealistic values.

I think the code doesn’t account for bit stuffing:
If a 0x07 value appears in the data section, another 0x07 is inserted, but it is not included in the length specification or the checksum.

I’m using the MQTT integration from @pepo83. My “High” status currently maxes out at 60%/65% fan speed. Is there the possibility to change the fan speeds for each group (low/mid/high) using your integration or is this still something that needs to be altered manually in the comfosense module? Thanks!