Configured my ESPHome with MCP2515 CAN-Bus for Stiebel Eltron heating pump

Thanks for the effort! Unfortunately, this does not work with my THZ 404. I have also tested a different index (+/-1). The status is always OFF

Can you go to the WP and navigate to:
Diagnose → Anlagenstatus and check, if you get the correct value there? If yes, check the logs for the correct Id :wink:

Hi @roberreiter , were you able to figure out how to read the current mode of the stiebel?
I’d like to see if/when it switches to cooling mode but i’m not able to find that specific entry in the Elster table (partially because my german is terrible)


My code is based on an older version, but maybe that helps:


  - platform: template
    id: icon_state
    icon: "mdi:apps"
    lambda: |-
      return {};
    update_interval: 5min


  - platform: template
    name: "Icon Schaltprogramm"
    id: icon_schaltprogramm
    icon: "mdi:timer-sand-complete"
  - platform: template
    name: "Icon Verdichter"
    id: icon_verdichter
    icon: "mdi:tennis-ball-outline"
  - platform: template
    name: "Icon Heizen"
    id: icon_heizen
    icon: "mdi:heating-coil"
  - platform: template
    name: "Icon Kühlen"
    id: icon_kuehlen
    icon: "mdi:snowflake"
  - platform: template
    name: "Icon Warmwasser"
    id: icon_warmwasser
    icon: "mdi:water-pump"
  - platform: template
    name: "Icon Notheizung"
    id: icon_notheizung
    icon: "mdi:radiator"
  - platform: template
    name: "Icon Service"
    id: icon_service
    icon: "mdi:wrench-outline"
  - platform: template
    name: "Icon Fernwartung"
    id: icon_fernwartung
    icon: "mdi:connection"
  - platform: template
    name: "Icon Filter oben und unten"
    id: icon_filter_oben_unten
    icon: "mdi:arrow-up-down-bold"
  - platform: template
    name: "Icon Lüftungsstufe"
    id: icon_lueftungsstufe
    icon: "mdi:fan"
  - platform: template
    name: "Icon Heizkreispumpe"
    id: icon_heizkreispumpe
    icon: "mdi:play-circle-outline"
  - platform: template
    name: "Icon Abtauen Verdampfer"
    id: icon_abtauen_verdampfer
    icon: "mdi:snowflake-melt"
  - platform: template
    name: "Icon Filter oben"
    id: icon_filter_oben
    icon: "mdi:arrow-up-bold"
  - platform: template
    name: "Icon Filter unten"
    id: icon_filter_unten
    icon: "mdi:arrow-down-bold"
  - platform: template
    name: "Icon Aufheizen"
    id: icon_aufheizen
    icon: "mdi:thermometer-chevron-up"
  - platform: template
    name: "Icon Achtung"
    id: icon_achtung
    icon: "mdi:alert"


        - lambda: |-
            if(x[0]==${can_x0} and x[1]==${can_x1} and x[2]==0xfa and x[3]==0x01 and x[4] == 0x76) {
              float state = float(int((x[6])+((x[5])<<8)));
              id(icon_schaltprogramm).publish_state((x[6] & 0x01) != 0);
              id(icon_verdichter).publish_state((x[6] & 0x02) != 0);
              id(icon_heizen).publish_state((x[6] & 0x04) != 0);
              id(icon_kuehlen).publish_state((x[6] & 0x08) != 0);
              id(icon_warmwasser).publish_state((x[6] & 0x10) != 0);
              id(icon_notheizung).publish_state((x[6] & 0x20) != 0);
              id(icon_service).publish_state((x[6] & 0x40) != 0);
              id(icon_fernwartung).publish_state((x[6] & 0x80) != 0);
              id(icon_filter_oben_unten).publish_state((x[5] & 0x01) != 0);
              id(icon_lueftungsstufe).publish_state((x[5] & 0x02) != 0);
              id(icon_heizkreispumpe).publish_state((x[5] & 0x04) != 0);
              id(icon_abtauen_verdampfer).publish_state((x[5] & 0x08) != 0);
              id(icon_filter_oben).publish_state((x[5] & 0x10) != 0);
              id(icon_filter_unten).publish_state((x[5] & 0x20) != 0);
              id(icon_aufheizen).publish_state((x[5] & 0x40) != 0);
              id(icon_achtung).publish_state((x[5] & 0x80) != 0);
              // ESP_LOGI("main", "Icons empfangen over can is %i, %i", int(x[5]), int(x[6]));


I tried it out somehow last year. But I didn’t make it to a full implementation.

I think I found how to set/read cooling-function activated.
But this doesn’t help for automations.

I decided to do an alternative workout to switch my KNX-heat actors to cooling/heating state using homeassistant:
Acc. To the Stiebel-manual the pump switches to summer(cooling) or winter(heating) mode in order to to time of the outer mean-temperature over/below a set limit.
Depending of the damping-value of the house there are 3 limit-times: 24h/48h/72h

So currently I’m doing this stupid workaround:
Measure the mean-temperature outside of the last 24h.
Temperature above limit-temperature - set KNX-actor to summer, else winter mode.

If you can figure out the correct CAN-IDs, that may help.


so after the question of Radiotechniman, I made some additional trys.

To my answer before - I just found the temperature-value to set, to switch the heat pump from summer to winter / viceversa.

If you change the temperature to a lower value (below 24/48/72h mean outside temperature) the pump switches to cooling.
If you set it high, cooling turns off.

This is the CAN hex-package for setting the idx 01bf to 15 degrees celsius:
30 0 fa 1 bf 0 96

With this, you set it to 21.5 degrees.
30 0 fa 1 bf 0 d7

idx 01bf is listed as “SW_AUSSENTEMP” in the elster table.

After switching from one temperature to the other, I received two different signals from address 480, which I would guess is heating or cooling-mode:

20 0 fa 4e 6a 0 1 (at 15 °C)
20 0 fa 4e 6a 0 0 (at 21.5 °C)
So I would guess, this could be returns that you receive from the pump, if it changes from one mode to the other.
But it was neither possible to set this value from my own CAN-device, nor did I get a valid response of the current value from 2100fa4e6a0000.
Additionally 4e6a is not listed in the elster-table. So I absolutely don’t know what they are exactly.
I assume the current state of cooling / heating mode can be read from any other idx, but I don’t know which one.

Correction - think I got it:
If I ask the same addres that sends the message 4e6a (heat pump manager, 9100 = id 480) I get an answer of the current state.
Query: 91 00 fa 4e 6a 00 00
=> response
d2 0 fa 4e 6a 0 0, when cooling mode is off
d2 0 fa 4e 6a 0 1, when cooling mode is on

Be aware - I’m not 100% sure, what exactly is delivered in 4e6a, as the idx isn’t listed in the elster-table.
But it looks promissing to be the cooling mode.