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)

thanks!

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

sensor:

  - platform: template
    id: icon_state
    icon: "mdi:apps"
    lambda: |-
      id(send_state)[0]=id(PumpCANread_id)[0];id(send_state)[1]=id(PumpCANread_id)[1];id(send_state)[2]=0xfa;id(send_state)[3]=0x01;id(send_state)[4]=0x76;id(send_state)[5]=0x00;id(send_state)[6]=0x00;
      id(update_sensor).publish_state(true);
      id(update_sensor).publish_state(false);
      return {};
    update_interval: 5min

binary_sensor:

  - 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"

canbus:

#Icons
        - 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);
              id(icon_state).publish_state(state);
              // ESP_LOGI("main", "Icons empfangen over can is %i, %i", int(x[5]), int(x[6]));
            }

Hi,

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.

Hi,

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.
So
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.

No sorry, never got it stable. Eventually just ordered the ISG for way to much money, but it works and keeps working and I’m able to control my WPF with everything I want (change modes, control heating/cooling/ hot water etc etc). And of course also monitor every detail of the system. So I’m happy :wink:

It’s been working solid for me after I connected grounds and removed the breadboard. Still running the test setup with dupont wires only.

I’ve been successfully controlling my WPF7 based on available solar power by setting the pump to emergency mode (to disable compressor) and comfort temp to max 65C. I have disabled the 2 phases of electric heaters for now as 1 phase is able to heat the water to 65C just fine during the day. I’ll add a 3 phase shelly there tho to automate it.

I’d like to still be able to read source pump status and other pump statuses to know more reliably whether it’s about to start a compressor cycle. Just so that I wont ever cancel that with the emergency mode. For now I’m using the power measurement of the control phase of the pump as I can see from that when source pump is running.

I tried to find out this by listening CAN bus when switching source pump using relay test and got some readings but those same ones are not there when pump is switching the source pump on during regular cycle. Also none of the pump statuses listed in Elster file worked (all returned static 128 value).

Pump, compressor mixer states and so on are bitcoded values.
Read 0x4e5e for that.
Compressor = Bit 1
Buffer charge pump = Bit 8
Source pump = Bit 9
NHZ2 = Bit 10
NHZ1 = Bit 11
Mixer closed = Bit 12
Mixer open = B13
Mixer pump = Bit 14
Heating circuit pump = Bit 15
If the bit is 0 state is off
1 is on…
Meaning of each bit might be different on your device…

Good day to everyone!
I kindly ask those who have FEK to send the log of which messages pass through the bus, both from it and to it.
I am also interested in which telegrams go from it to WPM, for example, humidity recording or heating curve correction. Also, what does FEK respond every 420 seconds (if it responds at all)?
Thank you in advance.

Hello guys,

This being said I want to discuss with you what are the usefull informations to monitor on the Warmpump ?

As I’m using Water Law I don’t have indoor thermometer.
I’m thinking of :
Curve
Outside temperature
Water temperature (but wich one ?)
When the Warmpump is working ? (what is the id ?)
When the boiller is working ? (what is the id ? and how to prevent this)
may be checking if mode is Eco…

What do you think is usefull ?

My heat pump dashboard for reference

1 Like

Hey guys,

I’m new to to CAN BUS and I would like to implement my Stiebel Eltron WPL 25 AC.
I have connected my ESP32 via ESPHome and MCP2515 and the CAN signals are comming in already.
Unfortunately, the messages can’t be matched with the parameter. I think it is because the CAN id of my heat pump is different? I tried to get the right ones but I have no idea where to find and how to interpret the incomming CAN bus messages. Maybe you have a little hint how I can continue.

Hi Tom,

I have a Stiebel Eltron WPL 25 AC myself and used the code line of GitHub - bullitt186/ha-stiebel-control: An ESPhome / Home Assistant configuration to monitor & configure Stiebel Eltron Heating Pumps via a CAN Interface. However not all messages work for me. I didn’t have the time yet to fix the issues.

1 Like

Hi, can you share your esp32 yaml file, please? I have HSBC 200 too and can bus does not communicate. Thnak you very much.

Hi everyone,
Here is my working code.
Maybe helpful for someone in future.

  • Wemos D1 mini ESP8266
  • Stiebel Eltron LWZ 8 CS Trend
  • incl. ventilation control with buttons
esphome:
  name: esp-lwz8
  friendly_name: ESP-LWZ8

esp8266:
  board: d1_mini

# Enable logging
logger:
  
# Example configuration entry
web_server:
  port: 80
  version: 1

# Enable Home Assistant API
api:
  encryption:
    key: "FVGTR/akQ+w/YscGSJGIFAekix5YajPirlvpMiXXNnM="


ota:
  - platform: esphome
    password: "5a6aaa8ea05d76c937dc2e744857d8cc"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp-Lwz8 Fallback Hotspot"
    password: "dEnIcOhe17ya"

captive_portal:


globals:
#Array zum Senden von Can-Bus Befehl aus Programmcode
  - id: send_state
    type: int[7]
    initial_value: '{0x00,0x00,0x00,0x00,0x00,0x00,0x00}'
    restore_value: no




#Abfrage des Sensorstatus durch Ausführen des Lambda-Befehls. send_state wird auf das request-Paket gesetzt. Anschließend wird Update_sensor aktiviert, der den Befehl via CAN absetzt und wieder deaktiviert
sensor:

#LĂźfterstufe Tag
  - platform: template
    name: "LĂźfterstufe Tag"
    id: luefter_tag
    unit_of_measurement: ""
    icon: "mdi:fan"
    device_class: "power_factor"
    state_class: "measurement"
    accuracy_decimals: 1
    lambda: |-
      id(send_state)[0]=0x31;id(send_state)[1]=0x00;id(send_state)[2]=0xfa;id(send_state)[3]=0x05;id(send_state)[4]=0x6c;id(send_state)[5]=0x00;id(send_state)[6]=0x00;
      id(update_sensor).publish_state(true);
      id(update_sensor).publish_state(false);
      return {};
    update_interval: 15min

#LĂźfterstufe Tag
  - platform: template
    name: "LĂźfterstufe Nacht"
    id: luefter_nacht
    unit_of_measurement: ""
    icon: "mdi:fan"
    device_class: "power_factor"
    state_class: "measurement"
    accuracy_decimals: 1
    lambda: |-
      id(send_state)[0]=0x31;id(send_state)[1]=0x00;id(send_state)[2]=0xfa;id(send_state)[3]=0x05;id(send_state)[4]=0x6d;id(send_state)[5]=0x00;id(send_state)[6]=0x00;
      id(update_sensor).publish_state(true);
      id(update_sensor).publish_state(false);
      return {};
    update_interval: 15min

#Außentemperatur
  - platform: template
    name: "Außentemperatur"
    id: temperature_outside
    unit_of_measurement: "°C"
    icon: "mdi:thermometer-lines"
    device_class: "temperature"
    state_class: "measurement"
    accuracy_decimals: 1
    lambda: |-
      id(send_state)[0]=0x31;id(send_state)[1]=0x00;id(send_state)[2]=0xfa;id(send_state)[3]=0x00;id(send_state)[4]=0x0c;id(send_state)[5]=0x00;id(send_state)[6]=0x00;
      id(update_sensor).publish_state(true);
      id(update_sensor).publish_state(false);
      return {};
    update_interval: 10min



#Raumtemperatur
  - platform: template
    name: "Raumtemperatur Ist"
    id: t_raumtemp_ist
    unit_of_measurement: "°C"
    icon: "mdi:home-thermometer-outline"
    device_class: "temperature"
    state_class: "measurement"
    accuracy_decimals: 1
    lambda: |-
      id(send_state)[0]=0x61;id(send_state)[1]=0x02;id(send_state)[2]=0xfa;id(send_state)[3]=0x00;id(send_state)[4]=0x11;id(send_state)[5]=0x00;id(send_state)[6]=0x00;
      id(update_sensor).publish_state(true);
      id(update_sensor).publish_state(false);
      return {};
    update_interval: 5min

  - platform: template
    name: "Raumtemperatur Soll"
    id: t_raumtemp_soll
    unit_of_measurement: "°C"
    icon: "mdi:waves-arrow-left"
    device_class: "temperature"
    state_class: "measurement"
    accuracy_decimals: 1
    lambda: |-
      id(send_state)[0]=0x61;id(send_state)[1]=0x02;id(send_state)[2]=0xfa;id(send_state)[3]=0x00;id(send_state)[4]=0x12;id(send_state)[5]=0x00;id(send_state)[6]=0x00;
      id(update_sensor).publish_state(true);
      id(update_sensor).publish_state(false);
      return {};
    update_interval: 15min





#Heizkreis 
  - platform: template
    name: "Heizkreis Ist"
    id: t_hk2_ist
    unit_of_measurement: "°C"
    icon: "mdi:thermometer"
    device_class: "temperature"
    state_class: "measurement"
    accuracy_decimals: 1
    lambda: |-
      id(send_state)[0]=0x61;id(send_state)[1]=0x02;id(send_state)[2]=0xfa;id(send_state)[3]=0x00;id(send_state)[4]=0x0f;id(send_state)[5]=0x00;id(send_state)[6]=0x00;
      id(update_sensor).publish_state(true);
      id(update_sensor).publish_state(false);
      return {};
    update_interval: 5min


  - platform: template
    name: "Heizkreis Soll"
    id: t_hk2_soll
    unit_of_measurement: "°C"
    icon: "mdi:thermometer-high"
    device_class: "temperature"
    state_class: "measurement"
    accuracy_decimals: 1
    lambda: |-
      id(send_state)[0]=0x61;id(send_state)[1]=0x02;id(send_state)[2]=0xfa;id(send_state)[3]=0x00;id(send_state)[4]=0x04;id(send_state)[5]=0x00;id(send_state)[6]=0x00;
      id(update_sensor).publish_state(true);
      id(update_sensor).publish_state(false);
      return {};
    update_interval: 15min


#RĂźcklauftemperatur
  - platform: template
    name: "RĂźcklauftemperatur Ist"
    id: temperature_return
    unit_of_measurement: "°C"
    icon: "mdi:waves-arrow-left"
    device_class: "temperature"
    state_class: "measurement"
    accuracy_decimals: 1
    lambda: |-
      id(send_state)[0]=0x31;id(send_state)[1]=0x00;id(send_state)[2]=0xfa;id(send_state)[3]=0x00;id(send_state)[4]=0x16;id(send_state)[5]=0x00;id(send_state)[6]=0x00;
      id(update_sensor).publish_state(true);
      id(update_sensor).publish_state(false);
      return {};
    update_interval: 5min


#WW-Temperatur Ist
  - platform: template
    name: "WW-Temperatur Ist"
    id: ww_temp_ist
    unit_of_measurement: "°C"
    icon: "mdi:water-thermometer"
    device_class: "temperature"
    state_class: "measurement"
    accuracy_decimals: 1
    lambda: |-
      id(send_state)[0]=0x31;id(send_state)[1]=0x00;id(send_state)[2]=0xfa;id(send_state)[3]=0x00;id(send_state)[4]=0x0e;id(send_state)[5]=0x00;id(send_state)[6]=0x00;
      id(update_sensor).publish_state(true);
      id(update_sensor).publish_state(false);
      return {};
    update_interval: 5min

#WW-Temperatur Soll
  - platform: template
    name: "WW-Temperatur Soll"
    id: ww_temp_soll
    unit_of_measurement: "°C"
    icon: "mdi:water-thermometer-outline"
    device_class: "temperature"
    state_class: "measurement"
    accuracy_decimals: 1
    lambda: |-
      id(send_state)[0]=0x31;id(send_state)[1]=0x00;id(send_state)[2]=0xfa;id(send_state)[3]=0x00;id(send_state)[4]=0x03;id(send_state)[5]=0x00;id(send_state)[6]=0x00;
      id(update_sensor).publish_state(true);
      id(update_sensor).publish_state(false);
      return {};
    update_interval: 15min


#Sonstiges
  - platform: template
    name: "Verdichterstarts"
    id: VD_starts
    unit_of_measurement: "a.u."
    icon: "mdi:counter"
    device_class: "power_factor"
    state_class: "measurement"
    lambda: |-
      id(send_state)[0]=0x31;id(send_state)[1]=0x00;id(send_state)[2]=0xfa;id(send_state)[3]=0xc0;id(send_state)[4]=0xf4;id(send_state)[5]=0x00;id(send_state)[6]=0x00;
      id(update_sensor).publish_state(true);
      id(update_sensor).publish_state(false);
      return {};
    update_interval: 5h
    accuracy_decimals: 0



  - platform: template
    name: "Volumenstrom"
    id: volumenstrom_log
    unit_of_measurement: "l/min"
    icon: "mdi:air-filter"
    state_class: "measurement"
    accuracy_decimals: 2
    lambda: |-
      id(send_state)[0]=0x31;id(send_state)[1]=0x00;id(send_state)[2]=0xfa;id(send_state)[3]=0x01;id(send_state)[4]=0xda;id(send_state)[5]=0x00;id(send_state)[6]=0x00;
      id(update_sensor).publish_state(true);
      id(update_sensor).publish_state(false);
      return {};
    update_interval: 1min


  - platform: template
    name: "Druck Heizkreis"
    id: heizungsdruck_log
    unit_of_measurement: "bar"
    icon: "mdi:gauge"
    device_class: "pressure"
    state_class: "measurement"
    accuracy_decimals: 2
    lambda: |-
      id(send_state)[0]=0x31;id(send_state)[1]=0x00;id(send_state)[2]=0xfa;id(send_state)[3]=0x06;id(send_state)[4]=0x4a;id(send_state)[5]=0x00;id(send_state)[6]=0x00;
      id(update_sensor).publish_state(true);
      id(update_sensor).publish_state(false);
      return {};
    update_interval: 7min





binary_sensor:

#Sensor zum Senden von CAN-Befehlen aus Lambda-Routinen
  - platform: template
    id: update_sensor
    on_press:
      then:
        - canbus.send: 
            data: !lambda
              return {(uint8_t) id(send_state)[0],(uint8_t) id(send_state)[1],(uint8_t) id(send_state)[2],(uint8_t) id(send_state)[3], (uint8_t) id(send_state)[4],(uint8_t) id(send_state)[5],(uint8_t) id(send_state)[6]};
            can_id: 0x6a2
            



button:
#Button zum automatisierten reset des ESP-Device
  - platform: restart
    name: "ESP restart"
    id: esp_heizraum_restart_bt
    on_press:
      - logger.log: "Button pressed"


  - platform: template
    name: LĂźftung Tag 0
    id: btn_lueftung_tag_0
    icon: "mdi:fan-remove"
    on_press:
      then:
        - canbus.send: 
            data: [ 0x30, 0x00, 0xfa,0x05,0x6c,0x00,0x00 ]
            can_id: 0x6a2
        - delay: 500ms
        - canbus.send: 
            data: [ 0x31, 0x00, 0xfa,0x05,0x6c,0x00,0x00 ]
            can_id: 0x6a2

  - platform: template
    name: LĂźftung Tag 1
    id: btn_lueftung_tag_1
    icon: "mdi:fan-speed-1"
    on_press:
      then:
        - canbus.send: 
            data: [ 0x30, 0x00, 0xfa,0x05,0x6c,0x00,0x01 ]
            can_id: 0x6a2
        - delay: 500ms
        - canbus.send: 
            data: [ 0x31, 0x00, 0xfa,0x05,0x6c,0x00,0x00 ]
            can_id: 0x6a2

  - platform: template
    name: LĂźftung Tag 2
    id: btn_lueftung_tag_2
    icon: "mdi:fan-speed-2"
    on_press:
      then:
        - canbus.send: 
            data: [ 0x30, 0x00, 0xfa,0x05,0x6c,0x00,0x02 ]
            can_id: 0x6a2
        - delay: 500ms
        - canbus.send: 
            data: [ 0x31, 0x00, 0xfa,0x05,0x6c,0x00,0x00 ]
            can_id: 0x6a2

  - platform: template
    name: LĂźftung Tag 3
    id: btn_lueftung_tag_3
    icon: "mdi:fan-speed-3"
    on_press:
      then:
        - canbus.send: 
            data: [ 0x30, 0x00, 0xfa,0x05,0x6c,0x00,0x03 ]
            can_id: 0x6a2
        - delay: 500ms
        - canbus.send: 
            data: [ 0x31, 0x00, 0xfa,0x05,0x6c,0x00,0x00 ]
            can_id: 0x6a2

  - platform: template
    name: LĂźftung Nacht 0
    id: btn_lueftung_nacht_0
    icon: "mdi:fan-remove"
    on_press:
      then:
        - canbus.send: 
            data: [ 0x30, 0x00, 0xfa,0x05,0x6d,0x00,0x00 ]
            can_id: 0x6a2
        - delay: 500ms
        - canbus.send: 
            data: [ 0x31, 0x00, 0xfa,0x05,0x6d,0x00,0x00 ]
            can_id: 0x6a2

  - platform: template
    name: LĂźftung Nacht 1
    id: btn_lueftung_nacht_1
    icon: "mdi:fan-speed-1"
    on_press:
      then:
        - canbus.send: 
            data: [ 0x30, 0x00, 0xfa,0x05,0x6d,0x00,0x01 ]
            can_id: 0x6a2
        - delay: 500ms
        - canbus.send: 
            data: [ 0x31, 0x00, 0xfa,0x05,0x6d,0x00,0x00 ]
            can_id: 0x6a2

  - platform: template
    name: LĂźftung Nacht 2
    id: btn_lueftung_nacht_2
    icon: "mdi:fan-speed-2"
    on_press:
      then:
        - canbus.send: 
            data: [ 0x30, 0x00, 0xfa,0x05,0x6d,0x00,0x02 ]
            can_id: 0x6a2
        - delay: 500ms
        - canbus.send: 
            data: [ 0x31, 0x00, 0xfa,0x05,0x6d,0x00,0x00 ]
            can_id: 0x6a2

  - platform: template
    name: LĂźftung Nacht 3
    id: btn_lueftung_nacht_3
    icon: "mdi:fan-speed-3"
    on_press:
      then:
        - canbus.send: 
            data: [ 0x30, 0x00, 0xfa,0x05,0x6d,0x00,0x03 ]
            can_id: 0x6a2
        - delay: 500ms
        - canbus.send: 
            data: [ 0x31, 0x00, 0xfa,0x05,0x6d,0x00,0x00 ]
            can_id: 0x6a2
spi:
  id: McpSpi
  clk_pin: GPIO16
  mosi_pin: GPIO5
  miso_pin: GPIO4

canbus:
  - platform: mcp2515
    id: my_mcp2515
    spi_id: McpSpi
    cs_pin: GPIO14
    can_id: 0x6a2
    use_extended_id: false
    bit_rate: 20kbps
    on_frame:

#LĂźfterstufe Tag
    - can_id: 0x180
      then:
        - lambda: |-
            if(   x[0]==  0xd2 
              and x[1]==  0x22 
              and x[2]==  0xfa 
              and x[3]==  0x05 
              and x[4]==  0x6c    ) {
              float stufe =float((int16_t((x[6])+( (x[5])<<8))));

              /*auto call = id(lueftungsstufe_tag_num).make_call();
              call.set_value(stufe);
              call.perform();*/

              id(luefter_tag).publish_state(stufe);
              ESP_LOGD("main", "Luefter Tag received over can is %f", stufe);
            }

#LĂźfterstufe Nacht
    - can_id: 0x180
      then:
        - lambda: |-
            if(   x[0]==  0xd2 
              and x[1]==  0x22 
              and x[2]==  0xfa 
              and x[3]==  0x05 
              and x[4]==  0x6d    ) {
              float stufe =float((int16_t((x[6])+( (x[5])<<8))));
              
              /*auto call = id(lueftungsstufe_nacht_num).make_call();
              call.set_value(stufe);
              call.perform();*/

              id(luefter_nacht).publish_state(stufe);
              ESP_LOGD("main", "Luefter Nacht received over can is %f", stufe);
            }

#Außentemperatur
#float temperature =float(float((int((x[6])+( (x[5])<<8))))/10);
    - can_id: 0x180
      then:
        - lambda: |-
            if(   x[0]==  0xd2 
              and x[1]==  0x22 
              and x[2]==  0xfa 
              and x[3]==  0x00 
              and x[4]==  0x0c    ) {
              float temperature =float((int16_t((x[6])+( (x[5])<<8))))/10;
              id(temperature_outside).publish_state(temperature);
              ESP_LOGD("main", "Aussen-Temperature received over can is %f", temperature);
            }


#Raumtemperatur Ist
    - can_id: 0x302
      then:
        - lambda: |-
            if( x[0]==    0xd2 
              and x[1]==  0x22 
              and x[2]==  0xfa 
              and x[3]==  0x00 
              and x[4]==  0x11    ) {
              float temperature =(float((int16_t((x[6])+( (x[5])<<8))))/10);
              id(t_raumtemp_soll).publish_state(temperature);
              ESP_LOGD("main", "Raumtemperatur Ist empfangen over can is %f", temperature);
            }

#Raumtemperatur Soll
    - can_id: 0x302
      then:
        - lambda: |-
            if( x[0]==    0xd2 
              and x[1]==  0x22 
              and x[2]==  0xfa 
              and x[3]==  0x00 
              and x[4]==  0x12    ) {
              float temperature =(float((int16_t((x[6])+( (x[5])<<8))))/10);
              id(t_raumtemp_soll).publish_state(temperature);
              ESP_LOGD("main", "Raumtemperatur Soll empfangen over can is %f", temperature);
            }
 

#Heizkreis Ist
    - can_id: 0x302
      then:
        - lambda: |-
            if( x[0]==    0xd2 
              and x[1]==  0x22 
              and x[2]==  0xfa 
              and x[3]==  0x00 
              and x[4]==  0x0f    ) {
              float temperature =(float((int16_t((x[6])+( (x[5])<<8))))/10);
              id(t_hk2_ist).publish_state(temperature);
              ESP_LOGD("main", "Heizkreis Ist empfangen over can is %f", temperature);
            }

#Heizkreis Soll
    - can_id: 0x302
      then:
        - lambda: |-
            if( x[0]==    0xd2 
              and x[1]==  0x22 
              and x[2]==  0xfa 
              and x[3]==  0x00 
              and x[4]==  0x04    ) {
              float temperature =(float((int16_t((x[6])+( (x[5])<<8))))/10);
              id(t_hk2_soll).publish_state(temperature);
              ESP_LOGD("main", "Heizkreis Soll empfangen over can is %f", temperature);
            }

#RĂźcklauftemperatur Ist
    - can_id: 0x180
      then:
        - lambda: |-
            if(   x[0]==  0xd2 
              and x[1]==  0x22 
              and x[2]==  0xfa 
              and x[3]==  0x00 
              and x[4]==  0x16    ) {
              float temperature =float((int16_t((x[6])+( (x[5])<<8))))/10;
              id(temperature_return).publish_state(temperature);
              ESP_LOGD("main", "RĂźcklauftemperatur Ist received over can is %f", temperature);
            }
            
#WW-Temperatur Ist
    - can_id: 0x180
      then:
        - lambda: |-
            if(   x[0]==  0xd2 
              and x[1]==  0x22 
              and x[2]==  0xfa 
              and x[3]==  0x00 
              and x[4]==  0x0e    ) {
              float temperature =float((int16_t((x[6])+( (x[5])<<8))))/10;
              id(ww_temp_ist).publish_state(temperature);
              ESP_LOGD("main", "WW-Temperatur Ist received over can is %f", temperature);
            }
            
#WW-Temperatur Soll
    - can_id: 0x180
      then:
        - lambda: |-
            if(   x[0]==  0xd2 
              and x[1]==  0x22 
              and x[2]==  0xfa 
              and x[3]==  0x00 
              and x[4]==  0x03    ) {
              float temperature =float((int16_t((x[6])+( (x[5])<<8))))/10;
              id(ww_temp_soll).publish_state(temperature);
              ESP_LOGD("main", "WW-Temperatur Soll received over can is %f", temperature);
            }

            
#Verdichterstarts
    - can_id: 0x180
      then:
        - lambda: |-
            if(   x[0]==  0xd2 
              and x[1]==  0x22 
              and x[2]==  0xfa 
              and x[3]==  0xc0 
              and x[4]==  0xf4    ) {
              float VD_x =float((int16_t((x[6])+( (x[5])<<8))));
              id(VD_starts).publish_state(VD_x);
              ESP_LOGD("main", "Verdichterstarts received over can is %f", VD_x);
            }

#Volumenstrom (l/min)
    - can_id: 0x180
      then:
        - lambda: |-
            if(   x[0]==  0xd2 
              and x[1]==  0x22 
              and x[2]==  0xfa 
              and x[3]==  0x01 
              and x[4]==  0xda    ) {
              float current =(float((int16_t((x[6])+( (x[5])<<8))))/100);
              id(volumenstrom_log).publish_state(current);
              ESP_LOGD("main", "l/min Volumenstrom empfangen over can is %f", current);
            }


#Heizungsdruck (bar)
    - can_id: 0x180
      then:
        - lambda: |-
            if(   x[0]==  0xd2 
              and x[1]==  0x22 
              and x[2]==  0xfa 
              and x[3]==  0x06 
              and x[4]==  0x4a    ) {
              float pressure =(float((int16_t((x[6])+( (x[5])<<8))))/10);
              id(heizungsdruck_log).publish_state(pressure);
              ESP_LOGD("main", "Heizungsdruck empfangen over can is %f", pressure);
            }





    - can_id: 0x180
      then:
        - lambda: |-
              int wert0 = int(x[0]);
              int wert1 =int(x[1]);
              int wert2 =int(x[2]);
              int wert3 =int(x[3]);
              int wert4 =int(x[4]);
              int wert5 =int(x[5]);
              int wert6 =int(x[6]);
              float wert7 = float(int((x[6])+( (x[5])<<8)));
              float wert8 = float(int((x[4])+( (x[3])<<8)));
              ESP_LOGI("main", "Antwort von 180 Hex: %x %x %x %x %x %x %x", wert0, wert1, wert2, wert3, wert4, wert5, wert6);
              ESP_LOGI("main", "Antwort von 180 Float: %f", wert7);
              ESP_LOGI("main", "Antwort von 180 Dez.: %i %i", wert5, wert6);
              
    - can_id: 0x700
      then:
        - lambda: |-
              int wert0 = int(x[0]);
              int wert1 =int(x[1]);
              int wert2 =int(x[2]);
              int wert3 =int(x[3]);
              int wert4 =int(x[4]);
              int wert5 =int(x[5]);
              int wert6 =int(x[6]);
              float wert7 = float(int((x[6])+( (x[5])<<8)));
              float wert8 = float(int((x[4])+( (x[3])<<8)));
              ESP_LOGI("main", "Antwort von 700 Hex: %x %x %x %x %x %x %x", wert0, wert1, wert2, wert3, wert4, wert5, wert6);
              ESP_LOGI("main", "Antwort von 700 Float: %f", wert7);
              ESP_LOGI("main", "Antwort von 700 Dez.: %i %i", wert5, wert6);

    - can_id: 0x480
      then:
        - lambda: |-
              int wert0 = int(x[0]);
              int wert1 =int(x[1]);
              int wert2 =int(x[2]);
              int wert3 =int(x[3]);
              int wert4 =int(x[4]);
              int wert5 =int(x[5]);
              int wert6 =int(x[6]);
              float wert7 = float(int((x[6])+( (x[5])<<8)));
              float wert8 = float(int((x[4])+( (x[3])<<8)));
              ESP_LOGI("main", "Antwort von 480 Hex: %x %x %x %x %x %x %x", wert0, wert1, wert2, wert3, wert4, wert5, wert6);
              ESP_LOGI("main", "Antwort von 480 Float: %f", wert7);
              ESP_LOGI("main", "Antwort von 480 Dez.: %i %i", wert5, wert6);

    - can_id: 0x100
      then:
        - lambda: |-
              int wert0 = int(x[0]);
              int wert1 =int(x[1]);
              int wert2 =int(x[2]);
              int wert3 =int(x[3]);
              int wert4 =int(x[4]);
              int wert5 =int(x[5]);
              int wert6 =int(x[6]);
              float wert7 = float(int((x[6])+( (x[5])<<8)));
              float wert8 = float(int((x[4])+( (x[3])<<8)));
              ESP_LOGI("main", "Antwort von 100 Hex: %x %x %x %x %x %x %x", wert0, wert1, wert2, wert3, wert4, wert5, wert6);
              ESP_LOGI("main", "Antwort von 100 Float: %f", wert7);
              ESP_LOGI("main", "Antwort von 100 Dez.: %i %i", wert5, wert6);

    - can_id: 0x301
      then:
        - lambda: |-
              int wert0 = int(x[0]);
              int wert1 =int(x[1]);
              int wert2 =int(x[2]);
              int wert3 =int(x[3]);
              int wert4 =int(x[4]);
              int wert5 =int(x[5]);
              int wert6 =int(x[6]);
              float wert7 = float(int((x[6])+( (x[5])<<8)));
              float wert8 = float(int((x[4])+( (x[3])<<8)));
              ESP_LOGI("main", "Antwort von 301 Hex: %x %x %x %x %x %x %x", wert0, wert1, wert2, wert3, wert4, wert5, wert6);
              ESP_LOGI("main", "Antwort von 301 Float: %f", wert7);
              ESP_LOGI("main", "Antwort von 301 Dez.: %i %i", wert5, wert6);
    - can_id: 0x302
      then:
        - lambda: |-
              int wert0 = int(x[0]);
              int wert1 =int(x[1]);
              int wert2 =int(x[2]);
              int wert3 =int(x[3]);
              int wert4 =int(x[4]);
              int wert5 =int(x[5]);
              int wert6 =int(x[6]);
              float wert7 = float(int((x[6])+( (x[5])<<8)));
              float wert8 = float(int((x[4])+( (x[3])<<8)));
              ESP_LOGI("main", "Antwort von 302 Hex: %x %x %x %x %x %x %x", wert0, wert1, wert2, wert3, wert4, wert5, wert6);
              ESP_LOGI("main", "Antwort von 302 Float: %f", wert7);
              ESP_LOGI("main", "Antwort von 302 Dez.: %i %i", wert5, wert6);
    - can_id: 0x6A1
      then:
        - lambda: |-
              int wert0 = int(x[0]);
              int wert1 =int(x[1]);
              int wert2 =int(x[2]);
              int wert3 =int(x[3]);
              int wert4 =int(x[4]);
              int wert5 =int(x[5]);
              int wert6 =int(x[6]);
              float wert7 = float(int((x[6])+( (x[5])<<8)));
              float wert8 = float(int((x[4])+( (x[3])<<8)));
              ESP_LOGI("main", "Antwort von 6A1 Hex: %x %x %x %x %x %x %x", wert0, wert1, wert2, wert3, wert4, wert5, wert6);
              ESP_LOGI("main", "Antwort von 6A1 Float: %f", wert7);
              ESP_LOGI("main", "Antwort von 6A1 Dez.: %i %i", wert5, wert6);

Hi, thank you for sharing this great project. I was able to read some of the values - however, I’m not too sure how to go about reading these following values:

My pump is hpa-o 8 cs plus

[09:28:04][D][canbus:072]: received can message (#1) std can_id=0x100 size=7
[09:28:04][D][canbus:072]: received can message (#1) std can_id=0x180 size=7
[09:28:05][D][canbus:072]: received can message (#1) std can_id=0x100 size=7
[09:28:05][D][canbus:072]: received can message (#2) std can_id=0x180 size=7
[09:28:06][D][canbus:072]: received can message (#1) std can_id=0x100 size=7
[09:28:06][D][canbus:072]: received can message (#2) std can_id=0x201 size=7
[09:28:07][D][canbus:072]: received can message (#1) std can_id=0x500 size=7
[09:28:07][D][canbus:072]: received can message (#2) std can_id=0x700 size=7
[09:28:07][D][canbus:072]: received can message (#1) std can_id=0x100 size=7
[09:28:07][D][canbus:072]: received can message (#2) std can_id=0x180 size=7
[09:28:09][D][canbus:072]: received can message (#1) std can_id=0x100 size=7
[09:28:09][D][canbus:072]: received can message (#2) std can_id=0x180 size=7
[09:28:10][D][canbus:035]: send standard id=0x680 rtr=FALSE size=7
[09:28:10][D][canbus:072]: received can message (#1) std can_id=0x514 size=7

Hi calm01,

I have a Tecalor TTF 05 cool and an existing working connection to the CAN BUS.
Can you share your configuration? Because I can’t assign many values.

Thank you!

Maybe this is of interest for you

Hi,
I have the same error:

Linking .pioenvs/heatingpump/firmware.elf
[…]
collect2: error: ld returned 1 exit status
*** [.pioenvs/heatingpump/firmware.elf] Error 1

while compiling for an esp8266. Is there any solution for that?
Greetings
Robert