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

Hello,

I just connected an MCP2515 Can-Bus component with ESP Wroom 32 to my Stiebel-Eltron WPF07 Cool heating pump.
Basically I followed the instructions on the ESP-Home page

Then I have received some good starting instructions, where Vincent82 posted me his configuration how to use the config and there was also a lot of information on the homepage of juerg5524 regarding this heating pump.

I hereby share my current config.
Since I was struggling a lot with this device - maybe it will help someone
I still didn’t achieve to get an answer for compressor timings from any CAN-ID.
But I can now easily read out the electrical power consumption of my pump.

captive_portal:

globals:
  - id: el_aufnahmeleistung_ww_tag_wh_float
    type: float
    restore_value: yes
  - id: el_aufnahmeleistung_ww_tag_wh_flag
    type: bool
    restore_value: yes
  - id: el_aufnahmeleistung_ww_tag_kwh
    type: float
    restore_value: yes
  - id: el_aufnahmeleistung_ww_tag_kwh_flag
    type: bool
    restore_value: yes
  - id: el_aufnahmeleistung_heiz_tag_wh_float
    type: float
    restore_value: yes
  - id: el_aufnahmeleistung_heiz_tag_wh_flag
    type: bool
    restore_value: yes
  - id: el_aufnahmeleistung_heiz_tag_kwh
    type: float
    restore_value: yes
  - id: el_aufnahmeleistung_heiz_tag_kwh_flag
    type: bool
    restore_value: yes 
  - id: el_aufnahmeleistung_ww_total_kWh_float
    type: float
    restore_value: yes
  - id: el_aufnahmeleistung_ww_total_kWh_flag
    type: bool
    restore_value: yes
  - id: el_aufnahmeleistung_ww_total_mWh
    type: float
    restore_value: yes
  - id: el_aufnahmeleistung_ww_total_mWh_flag
    type: bool
    restore_value: yes
  - id: el_aufnahmeleistung_heiz_total_kWh_float
    type: float
    restore_value: yes
  - id: el_aufnahmeleistung_heiz_total_kWh_flag
    type: bool
    restore_value: yes
  - id: el_aufnahmeleistung_heiz_total_mWh
    type: float
    restore_value: yes
  - id: el_aufnahmeleistung_heiz_total_mWh_flag
    type: bool
    restore_value: yes


  - id: waermemertrag_ww_tag_wh_float
    type: float
    restore_value: yes
  - id: waermemertrag_ww_tag_wh_flag
    type: bool
    restore_value: yes
  - id: waermemertrag_ww_tag_kwh
    type: float
    restore_value: yes
  - id: waermemertrag_ww_tag_kwh_flag
    type: bool
    
  - id: waermemertrag_electr_ww_tag_wh_float
    type: float
    restore_value: yes
  - id: waermemertrag_electr_ww_tag_wh_flag
    type: bool
    restore_value: yes
  - id: waermemertrag_electr_ww_tag_kwh
    type: float
    restore_value: yes
  - id: waermemertrag_electr_ww_tag_kwh_flag
    type: bool    
    restore_value: yes

  - id: waermemertrag_heiz_tag_wh_float
    type: float
    restore_value: yes
  - id: waermemertrag_heiz_tag_wh_flag
    type: bool
    restore_value: yes
  - id: waermemertrag_heiz_tag_kwh
    type: float
    restore_value: yes
  - id: waermemertrag_heiz_tag_kwh_flag
    type: bool
    restore_value: yes 

  - id: waermemertrag_electr_heiz_tag_wh_float
    type: float
    restore_value: yes
  - id: waermemertrag_electr_heiz_tag_wh_flag
    type: bool
    restore_value: yes
  - id: waermemertrag_electr_heiz_tag_kwh
    type: float
    restore_value: yes
  - id: waermemertrag_electr_heiz_tag_kwh_flag
    type: bool
    restore_value: yes 

  - id: waermemertrag_ww_total_kWh_float
    type: float
    restore_value: yes
  - id: waermemertrag_ww_total_kWh_flag
    type: bool
    restore_value: yes
  - id: waermemertrag_ww_total_mWh
    type: float
    restore_value: yes
  - id: waermemertrag_ww_total_mWh_flag
    type: bool
    restore_value: yes

  - id: waermemertrag_heiz_total_kWh_float
    type: float
    restore_value: yes
  - id: waermemertrag_heiz_total_kWh_flag
    type: bool
    restore_value: yes
  - id: waermemertrag_heiz_total_mWh
    type: float
    restore_value: yes
  - id: waermemertrag_heiz_total_mWh_flag
    type: bool
    restore_value: yes

  - id: waermemertrag_electr_heiz_total_kWh_float
    type: float
    restore_value: yes
  - id: waermemertrag_electr_heiz_total_kWh_flag
    type: bool
    restore_value: yes
  - id: waermemertrag_electr_heiz_total_mWh
    type: float
    restore_value: yes
  - id: waermemertrag_electr_heiz_total_mWh_flag
    type: bool
    restore_value: yes

  - id: waermemertrag_electr_ww_total_kWh_float
    type: float
    restore_value: yes
  - id: waermemertrag_electr_ww_total_kWh_flag
    type: bool
    restore_value: yes
  - id: waermemertrag_electr_ww_total_mWh
    type: float
    restore_value: yes
  - id: waermemertrag_electr_ww_total_mWh_flag
    type: bool
    restore_value: yes




sensor:
  - 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

  - platform: template
    name: "Quellentemperatur"
    id: temperature_source
    unit_of_measurement: "°C"
    icon: "mdi:thermometer-lines"
    device_class: "temperature"
    state_class: "measurement"
    accuracy_decimals: 1

  - platform: template
    name: "Warmwassertemperatur"
    id: temperature_water
    unit_of_measurement: "°C"
    icon: "mdi:thermometer-lines"
    device_class: "temperature"
    state_class: "measurement"
    accuracy_decimals: 1

  - platform: template
    name: "Vorlauftemperatur Heizung"
    id: temperature_forerun
    unit_of_measurement: "°C"
    icon: "mdi:waves-arrow-right"
    device_class: "temperature"
    state_class: "measurement"
    accuracy_decimals: 1
  - platform: template
    name: "Heizkreis Vorlauf"
    id: temperature_forerun_heating
    unit_of_measurement: "°C"
    icon: "mdi:waves-arrow-right"
    device_class: "temperature"
    state_class: "measurement"
    accuracy_decimals: 1


  - platform: template
    name: "RĂŒcklauftemperatur Heizung"
    id: temperature_return
    unit_of_measurement: "°C"
    icon: "mdi:waves-arrow-left"
    device_class: "temperature"
    state_class: "measurement"
    accuracy_decimals: 1

  - platform: template
    name: "Luftfeuchtigkeit Wohnraum"
    id: humidity_inside
    unit_of_measurement: "%rH"
    icon: "mdi:water-percent"
    device_class: "humidity"
    state_class: "measurement"
    accuracy_decimals: 1
  - platform: template
    name: "Temperatur Wohnraum"
    id: temperature_inside
    unit_of_measurement: "°C"
    icon: "mdi:thermometer-lines"
    device_class: "temperature"
    state_class: "measurement"
    accuracy_decimals: 1
  - platform: template
    name: "Stromverbrauch Warmwasser heute"
    id: daily_electric_energy_water
    unit_of_measurement: "kWh"
    device_class: "energy"
    state_class: "measurement"
    accuracy_decimals: 3
    icon: "mdi:transmission-tower"
  - platform: template
    name: "Stromverbrauch Heizung heute"
    id: daily_electric_energy_heating
    unit_of_measurement: "kWh"
    device_class: "energy"
    state_class: "measurement"
    icon: "mdi:transmission-tower"
    accuracy_decimals: 3   
  - platform: template
    name: "Stromverbrauch Warmwasser total"
    id: total_electric_energy_water
    unit_of_measurement: "MWh"
    device_class: "energy"
    state_class: "measurement"
    icon: "mdi:transmission-tower"
    accuracy_decimals: 3
  - platform: template
    name: "Stromverbrauch Heizung total"
    id: total_electric_energy_heating
    unit_of_measurement: "MWh"
    device_class: "energy"
    icon: "mdi:transmission-tower"
    state_class: "measurement"
    accuracy_decimals: 3

  - platform: template
    name: "WM Heizung heute"
    id: daily_heating_energy
    unit_of_measurement: "kWh"
    device_class: "energy"
    icon: "mdi:water-boiler"
    state_class: "measurement"
    accuracy_decimals: 3
   
  - platform: template
    name: "WM Heizen total"
    id: total_heating_energy
    unit_of_measurement: "MWh"
    device_class: "energy"
    icon: "mdi:water-boiler"
    state_class: "measurement"
    accuracy_decimals: 3

  - platform: template
    name: "WM Warmwasser heute"
    id: daily_heating_energy_water
    unit_of_measurement: "kWh"
    device_class: "energy"
    icon: "mdi:water-boiler"
    state_class: "measurement"
    accuracy_decimals: 3

  - platform: template
    name: "WM Warmwasser total"
    id: total_heating_energy_water
    unit_of_measurement: "MWh"
    device_class: "energy"
    icon: "mdi:water-boiler"
    state_class: "measurement"
    accuracy_decimals: 3

    
  - platform: template
    name: "WM elektr. Warmwasser total"
    id: total_electric_heating_energy_water
    unit_of_measurement: "kWh"
    device_class: "energy"
    icon: "mdi:water-boiler"
    state_class: "measurement"
    accuracy_decimals: 3


  - platform: template
    name: "WM elektr. heizen total"
    id: total_electric_heating_energy
    unit_of_measurement: "kWh"
    device_class: "energy"
    icon: "mdi:water-boiler"
    state_class: "measurement"
    accuracy_decimals: 3


binary_sensor:
  - platform: template
    name: "EVU Sperre"
    id: "evu_lock"



time:
  - platform: homeassistant
    id: homeassistant_time
    on_time:
     
      - seconds: /180
        then:


#WM NE WW Summe wh  - ok
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x09,0x22,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms
#WM NE WW Summe kwh  - ok
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x09,0x23,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms


#WM NE Heizen Summe wh - ok
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x09,0x26,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms
#WM NE Heizen Summe kwh - ok
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x09,0x27,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms


#WM WW Tag wh - ok
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x09,0x2a,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms

#WM WW Tag kwh - ok
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x09,0x2b,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms
#WM WW Summe kwh - ok
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x09,0x2c,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms

#WM WW Summe Mwh - ok
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x09,0x2d,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms

#WM Heizen Tag wh - ok
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x09,0x2e,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms

#WM Heizen Tag kwh - ok
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x09,0x2f,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms

#WM Heizen Summe kwh - ok
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x09,0x30,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms
#WM Heizen Summe Mwh - ok
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x09,0x31,0x00,0x00 ]
              can_id: 0x680
          - delay: 10s

          - lambda: |-
              if (id(waermemertrag_electr_ww_total_mWh_flag) and id(waermemertrag_electr_ww_total_kWh_flag)){
              id(waermemertrag_electr_ww_total_mWh) += id(waermemertrag_electr_ww_total_kWh_float);
              id(total_electric_heating_energy_water).publish_state(id(waermemertrag_electr_ww_total_mWh));
              };
              id(waermemertrag_electr_ww_total_mWh_flag)=false;
              id(waermemertrag_electr_ww_total_kWh_flag)=false;
          - lambda: |-
              if (id(waermemertrag_electr_heiz_total_kWh_flag) and id(waermemertrag_electr_heiz_total_mWh_flag)){
              id(waermemertrag_electr_heiz_total_mWh) += id(waermemertrag_electr_heiz_total_kWh_float);
              id(total_electric_heating_energy).publish_state(id(waermemertrag_electr_heiz_total_mWh));
              };
              id(waermemertrag_electr_heiz_total_kWh_flag)=false;
              id(waermemertrag_electr_heiz_total_mWh_flag)=false;       

          - lambda: |-
              if (id(waermemertrag_ww_total_mWh_flag) and id(waermemertrag_ww_total_kWh_flag)){
              id(waermemertrag_ww_total_mWh) += id(waermemertrag_ww_total_kWh_float);
              id(total_heating_energy_water).publish_state(id(waermemertrag_ww_total_mWh));
              };
              id(waermemertrag_ww_total_mWh_flag)=false;
              id(waermemertrag_ww_total_kWh_flag)=false;
          - lambda: |-
              if (id(waermemertrag_heiz_total_kWh_flag) and id(waermemertrag_heiz_total_mWh_flag)){
              id(waermemertrag_heiz_total_mWh) += id(waermemertrag_heiz_total_kWh_float);
              id(total_heating_energy).publish_state(id(waermemertrag_heiz_total_mWh));
              };
              id(waermemertrag_heiz_total_kWh_flag)=false;
              id(waermemertrag_heiz_total_mWh_flag)=false;       
          - lambda: |-
              if (id(waermemertrag_heiz_tag_kwh_flag) and id(waermemertrag_heiz_tag_wh_flag)){
              id(waermemertrag_heiz_tag_kwh) += id(waermemertrag_heiz_tag_wh_float);
              id(daily_heating_energy).publish_state(id(waermemertrag_heiz_tag_kwh));
              };
              id(waermemertrag_heiz_tag_kwh_flag)=false;
              id(waermemertrag_heiz_tag_wh_flag)=false;
          - lambda: |-
              if (id(waermemertrag_ww_tag_kwh_flag) and id(waermemertrag_ww_tag_wh_flag)){
              id(waermemertrag_ww_tag_kwh) += id(waermemertrag_ww_tag_wh_float);
              id(daily_heating_energy_water).publish_state(id(waermemertrag_ww_tag_kwh));
              };
              id(waermemertrag_ww_tag_kwh_flag)=false;
              id(waermemertrag_ww_tag_wh_flag)=false;










#el. Leistungsaufnahme WW Tag Wh -  ok
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x09,0x1a,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms
#el. Leistungsaufnahme WW Tag kWh -  ok
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x09,0x1b,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms


#el. Leistungsaufnahme WW Summe kwh - ok
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x09,0x1c,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms
#el. Leistungsaufnahme WW Summe Mwh - ok
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x09,0x1d,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms


#el. Leistungsaufnahme Heizen Tag Wh - ok
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x09,0x1e,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms
#el. Leistungsaufnahme Heizen Tag Wh - ok
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x09,0x1f,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms


#el. Leistungsaufnahme Heizen Summe kwh - ok
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x09,0x20,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms
#el. Leistungsaufnahme Heizen Summe Mwh - ok
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x09,0x21,0x00,0x00 ]
              can_id: 0x680
          - delay: 10s

          - lambda: |-
              if (id(el_aufnahmeleistung_ww_total_mWh_flag) and id(el_aufnahmeleistung_ww_total_kWh_flag)){
              id(el_aufnahmeleistung_ww_total_mWh) += id(el_aufnahmeleistung_ww_total_kWh_float);
              id(total_electric_energy_water).publish_state(id(el_aufnahmeleistung_ww_total_mWh));
              };
              id(el_aufnahmeleistung_ww_total_mWh_flag)=false;
              id(el_aufnahmeleistung_ww_total_kWh_flag)=false;
          - lambda: |-
              if (id(el_aufnahmeleistung_heiz_total_mWh_flag) and id(el_aufnahmeleistung_heiz_total_kWh_flag)){
              id(el_aufnahmeleistung_heiz_total_mWh) += id(el_aufnahmeleistung_heiz_total_kWh_float);
              id(total_electric_energy_heating).publish_state(id(el_aufnahmeleistung_heiz_total_mWh));
              };
              id(el_aufnahmeleistung_heiz_total_mWh_flag)=false;
              id(el_aufnahmeleistung_heiz_total_mWh_flag)=false;       
          - lambda: |-
              if (id(el_aufnahmeleistung_ww_tag_kwh_flag) and id(el_aufnahmeleistung_ww_tag_wh_flag)){
              id(el_aufnahmeleistung_ww_tag_kwh) += id(el_aufnahmeleistung_ww_tag_wh_float);
              id(daily_electric_energy_water).publish_state(id(el_aufnahmeleistung_ww_tag_kwh));
              };
              id(el_aufnahmeleistung_ww_tag_kwh_flag)=false;
              id(el_aufnahmeleistung_ww_tag_wh_flag)=false;
          - lambda: |-
              if (id(el_aufnahmeleistung_heiz_tag_kwh_flag) and id(el_aufnahmeleistung_heiz_tag_wh_flag)){
              id(el_aufnahmeleistung_heiz_tag_kwh) += id(el_aufnahmeleistung_heiz_tag_wh_float);
              id(daily_electric_energy_heating).publish_state(id(el_aufnahmeleistung_heiz_tag_kwh));
              };
              id(el_aufnahmeleistung_heiz_tag_kwh_flag)=false;
              id(el_aufnahmeleistung_heiz_tag_wh_flag)=false;
              
          - lambda: |-
              ESP_LOGD("main", "EVU Sperre requested");



#Außentemperatur 1/10 °C et dec value - ok /10
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x00,0x0c,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms

#Vorlauftemperatur  - ok 1/10
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x00,0x0d,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms 
#Vorlauftemperatur Hzg - ok 1/10
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x00,0x0f,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms 

#RĂŒcklauftemperatur Hzg - ok 1/10
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x00,0x16,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms 

#WW Temperatur - ok + offset
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x00,0x0e,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms 

#Quelle IST: - ok 1/10
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x01,0xd4,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms 





       
spi:
  id: McpSpi
  clk_pin: GPIO18
  mosi_pin: GPIO23
  miso_pin: GPIO19

canbus:
  - platform: mcp2515
    id: my_mcp2515
    spi_id: McpSpi
    cs_pin: GPIO15
    can_id: 680
    use_extended_id: false
    bit_rate: 20kbps
    on_frame:



#Warmwasser-Temperaturabfrage + Offset 3.9 °C
    - can_id: 0x180
      then:
        - lambda: |-
            if(x[0]==0xd2 and x[1]==0x00 and x[3]==0x00 and x[4] == 0x0e) {
              float temperature =float((float((int((x[6])+( (x[5])<<8))))/10)+3.9);
              id(temperature_water).publish_state(temperature);
              ESP_LOGD("main", "Temperature received over can is %f", temperature);
            }
#Quellen-Temperaturabfrage
    - can_id: 0x180
      then:
        - lambda: |-
            if(x[0]==0xd2 and x[1]==0x00 and x[3]==0x01 and x[4] == 0xd4) {
              float temperature =float(float((int((x[6])+( (x[5])<<8))))/10);
              id(temperature_source).publish_state(temperature);
              ESP_LOGD("main", "Temperature received over can is %f", temperature);
            }

#Vorlauftemperaturabfrage
    - can_id: 0x180
      then:
        - lambda: |-
            if(x[0]==0xd2 and x[1]==0x00 and x[3]==0x00 and x[4] == 0x0d) {
              float temperature =float(float((int((x[6])+( (x[5])<<8))))/1000);
              id(temperature_forerun).publish_state(temperature);
              ESP_LOGD("main", "Temperature received over can is %f", temperature);
            }
            
#Vorlauftemperaturabfrage Heizkreis
    - can_id: 0x180
      then:
        - lambda: |-
            if(x[0]==0xd2 and x[1]==0x00 and x[3]==0x00 and x[4] == 0x0f) {
              float temperature =float(float((int((x[6])+( (x[5])<<8))))/1000);
              id(temperature_forerun_heating).publish_state(temperature);
              ESP_LOGD("main", "Temperature received over can is %f", temperature);
            }
#RĂŒcklauftemperaturabfrage
    - can_id: 0x180
      then:
        - lambda: |-
            if(x[0]==0xd2 and x[1]==0x00 and x[3]==0x00 and x[4] == 0x16) {
              float temperature =float(float((int((x[6])+( (x[5])<<8))))/10);
              id(temperature_return).publish_state(temperature);
              ESP_LOGD("main", "Temperature received over can is %f", temperature);
            }


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

#Luftfeuchtigkeit FEK mitlesen
    - can_id: 0x301
      then:
        - lambda: |-
            if(x[0]==0xc0 and x[1]==0x01 and x[2]==0x75) {
              float humidity =float(float((int((x[4])+( (x[3])<<8))))/10);
              id(humidity_inside).publish_state(humidity);
              ESP_LOGD("main", "Humidity received over can is %f", humidity);
            }
#Raumtemperatur FEK mitlesen
    - can_id: 0x301
      then:
        - lambda: |-
            if(x[0]==0xc0 and x[1]==0x01 and x[2]==0x11) {
              float temperature =float(float((int((x[4])+( (x[3])<<8))))/10);
              id(temperature_inside).publish_state(temperature);
              ESP_LOGD("main", "Temperature received over can is %f", temperature);
            }



#Elektrische Leistungsaufnahme Wh /kWh
    - can_id: 0x180
      then:
        - lambda: |-
            if(x[0]==0xd2 and x[1]==0x00 and x[2]==0xfa and x[3]==0x09) {
              if (x[4]==0x1a){
                id(el_aufnahmeleistung_ww_tag_wh_float) = (float((int((x[6])+( (x[5])<<8))))/1000);
                id(el_aufnahmeleistung_ww_tag_wh_flag)=true;
                ESP_LOGD("main", "el_aufnahmeleistung_ww_tag_kwh received over can is %f", id(el_aufnahmeleistung_ww_tag_wh_float));}
              else if (x[4]==0x1e){
                id(el_aufnahmeleistung_heiz_tag_wh_float) = (float((int((x[6])+( (x[5])<<8))))/1000);
                id(el_aufnahmeleistung_heiz_tag_wh_flag) = true;
                ESP_LOGD("main", "el_aufnahmeleistung_heiz_tag_wh received over can is %f", id(el_aufnahmeleistung_heiz_tag_wh_float));}
              else if (x[4]==0x1c){
                id(el_aufnahmeleistung_ww_total_kWh_float) = (float((int((x[6])+( (x[5])<<8))))/1000);
                id(el_aufnahmeleistung_ww_total_kWh_flag)=true;
                ESP_LOGD("main", "el_aufnahmeleistung_ww_total_kkWh received over can is %f", id(el_aufnahmeleistung_ww_total_kWh_float));}
              else if (x[4]==0x20){
                id(el_aufnahmeleistung_heiz_total_kWh_float) = (float((int((x[6])+( (x[5])<<8))))/1000);
                id(el_aufnahmeleistung_heiz_total_kWh_flag) = true;
                ESP_LOGD("main", "el_aufnahmeleistung_heiz_total_kWh received over can is %f", id(el_aufnahmeleistung_heiz_total_kWh_float));}
              }
              if(x[0]==0xd2 and x[1]==0x00 and x[2]==0xfa and x[3]==0x00 and x[4]==0x74){
              if(x[5]==0x80 and x[6]==0x00){
                id(evu_lock).publish_state(false);
                }
              else{
                id(evu_lock).publish_state(true);
              };
            };

#Elektrische Leistungsaufnahme kWh / MWH
    - can_id: 0x180
      then:
        - lambda: |-
            if(x[0]==0xd2 and x[1]==0x00 and x[2]==0xfa and x[3]==0x09) {
              if(x[4]==0x1b){
              id(el_aufnahmeleistung_ww_tag_kwh) =float(int((x[6])+( (x[5])<<8)));
              id(el_aufnahmeleistung_ww_tag_kwh_flag)=true;
              ESP_LOGD("main", "el_aufnahmeleistung_ww_tag_kwh received over can is %f", id(el_aufnahmeleistung_ww_tag_kwh));}
              else if(x[4]==0x1f){
                id(el_aufnahmeleistung_heiz_tag_kwh) =float(int((x[6])+( (x[5])<<8)));
                id(el_aufnahmeleistung_heiz_tag_kwh_flag)=true;
                ESP_LOGD("main", "el_aufnahmeleistung_heiz_tag_kwh received over can is %f", id(el_aufnahmeleistung_heiz_tag_kwh));}
              else if(x[4]==0x1d){
              id(el_aufnahmeleistung_ww_total_mWh) =float(int((x[6])+( (x[5])<<8)));
              id(el_aufnahmeleistung_ww_total_mWh_flag)=true;
              ESP_LOGD("main", "el_aufnahmeleistung_ww_total_mWh received over can is %f", id(el_aufnahmeleistung_ww_total_mWh));}
              else if(x[4]==0x21){
                id(el_aufnahmeleistung_heiz_total_mWh) =float(int((x[6])+( (x[5])<<8)));
                id(el_aufnahmeleistung_heiz_total_mWh_flag)=true;
                ESP_LOGD("main", "el_aufnahmeleistung_heiz_total_mWh received over can is %f", id(el_aufnahmeleistung_heiz_total_mWh));}
            }


#WĂ€rmeertrag WW/Heizung MWh / kWH
    - can_id: 0x180
      then:
        - lambda: |-
            if(x[0]==0xd2 and x[1]==0x00 and x[2]==0xfa and x[3]==0x09) {
              if(x[4]==0x23){
                id(waermemertrag_electr_ww_total_mWh) =float(int((x[6])+( (x[5])<<8)));
                id(waermemertrag_electr_ww_total_mWh_flag)=true;
                ESP_LOGD("main", "waermemertrag_electr_ww_tag_kwh received over can is %f", id(waermemertrag_electr_ww_total_mWh));}
              else if(x[4]==0x27){
                id(waermemertrag_electr_heiz_total_mWh) =float(int((x[6])+( (x[5])<<8)));
                id(waermemertrag_electr_heiz_total_mWh_flag)=true;
                ESP_LOGD("main", "waermemertrag_electr_heiz_tag_kwh received over can is %f", id(waermemertrag_electr_heiz_total_mWh));}
              else if(x[4]==0x2b){
              id(waermemertrag_ww_tag_kwh) =float(int((x[6])+( (x[5])<<8)));
              id(waermemertrag_ww_tag_kwh_flag)=true;
              ESP_LOGD("main", "waermemertrag_ww_tag_kwh received over can is %f", id(waermemertrag_ww_tag_kwh));}
              else if(x[4]==0x2d){
              id(waermemertrag_ww_total_mWh) =float(int((x[6])+( (x[5])<<8)));
              id(waermemertrag_ww_total_mWh_flag)=true;
              ESP_LOGD("main", "waermemertrag_ww_total_mWh received over can is %f", id(waermemertrag_ww_total_mWh));}
              else if(x[4]==0x2f){
                id(waermemertrag_heiz_tag_kwh) =float(int((x[6])+( (x[5])<<8)));
                id(waermemertrag_heiz_tag_kwh_flag)=true;
                ESP_LOGD("main", "waermemertrag_heiz_tag_kwh received over can is %f", id(waermemertrag_heiz_tag_kwh));}
              else if(x[4]==0x31){
                id(waermemertrag_heiz_total_mWh) =float(int((x[6])+( (x[5])<<8)));
                id(waermemertrag_heiz_total_mWh_flag)=true;
                ESP_LOGD("main", "waermemertrag_heiz_total_kWh_float received over can is %f", id(waermemertrag_heiz_total_mWh));}
            }


#WĂ€rmeertrag WW/Heizung Wh / kWH
    - can_id: 0x180
      then:
        - lambda: |-
            if(x[0]==0xd2 and x[1]==0x00 and x[2]==0xfa and x[3]==0x09) {
              if(x[4]==0x22){
                id(waermemertrag_electr_ww_total_kWh_float) =float(int((x[6])+( (x[5])<<8)))/1000;
                id(waermemertrag_electr_ww_total_kWh_flag)=true;
                ESP_LOGD("main", "waermemertrag_electr_ww_tag_wh_float received over can is %f", id(waermemertrag_electr_ww_total_kWh_float));}
              else if(x[4]==0x26){
                id(waermemertrag_electr_heiz_total_kWh_float) =float(int((x[6])+( (x[5])<<8)))/1000;
                id(waermemertrag_electr_heiz_total_kWh_flag)=true;
                ESP_LOGD("main", "waermemertrag_electr_heiz_tag_wh_float received over can is %f", id(waermemertrag_electr_heiz_total_kWh_float));}
              else if(x[4]==0x2a){
              id(waermemertrag_ww_tag_wh_float) =float(int((x[6])+( (x[5])<<8)))/1000;
              id(waermemertrag_ww_tag_wh_flag)=true;
              ESP_LOGD("main", "waermemertrag_ww_tag_wh_float received over can is %f", id(waermemertrag_ww_tag_wh_float));}
              else if(x[4]==0x2c){
              id(waermemertrag_ww_total_kWh_float) =float(int((x[6])+( (x[5])<<8)))/1000;
              id(waermemertrag_ww_total_kWh_flag)=true;
              ESP_LOGD("main", "waermemertrag_ww_total_kWh_float received over can is %f", id(waermemertrag_ww_total_kWh_float));}
              else if(x[4]==0x2e){
                id(waermemertrag_heiz_tag_wh_float) =float(int((x[6])+( (x[5])<<8)))/1000;
                id(waermemertrag_heiz_tag_wh_flag)=true;
                ESP_LOGD("main", "waermemertrag_heiz_tag_wh_float received over can is %f", id(waermemertrag_heiz_tag_wh_float));}
              else if(x[4]==0x30){
                id(waermemertrag_heiz_total_kWh_float) =float(int((x[6])+( (x[5])<<8)))/1000;
                id(waermemertrag_heiz_total_kWh_flag)=true;
                ESP_LOGD("main", "waermemertrag_heiz_total_kWh_float received over can is %f", id(waermemertrag_heiz_total_kWh_float));}
            }


#Show data in raw form as hex-values
    - 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)));
              ESP_LOGD("main", "Antwort von 180 Hex: %x %x %x %x %x %x %x", wert0, wert1, wert2, wert3, wert4, wert5, wert6);
              ESP_LOGD("main", "Antwort von 180 Float: %f", wert7);
              ESP_LOGD("main", "Antwort von 180 Dez.: %i %i", wert5, wert6);




6 Likes

For explanation:

Stiebel Eltron uses CAN Bus for their communication with external devices like FEK remote control or ISG gateway. And CAN Bus is a standard that can be used with ESP32 too using an MCP 2515 can bus controller.
If you have a look at the heat pump’s manual in the section for electrical connections - for me it is section 12.2.3 and 12.8 you can read, how an ISG should be connected to the heat pump.
In the same way as the ISG, you can connect an MCP2515 CAN Bus component via an ESP32 microcontroller as set up in my thread. ESP32 is easily integrated in home assistant using ESP-Home.

To receive the corresponding signals from the heat pump, you send a hex command over the CAN Bus interface and the heat pump answers respectively. The needed command keys are located in the file “ElsterTable.inc” on the website juerg5524.ch.

Such a send command can look like this in ESP-Home.

          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x09,0x22,0x00,0x00 ]
              can_id: 0x680

The first and fourth digits are used to signal the request to the address of the heat pump - here it is the address ,3*8 + 0 =18 + 0 => 180.
Sencond digit “1” means request.
Digits 5 and 6 are usually “fa” with some certain exceptions, when the Elster Index is smaller than ff ff.
Digits 7 to 10 “09 22” is the Elster index key listed in the ElsterTable as “WAERMEERTRAG_2WE_WW_TAG_WH”.

As an answer you’ll get something like d2 00 fa 09 22 xx xx, meaning answer (digit 2 = 2) to can-id 680 (d*8 + 0) for request 09 22 and xx xx the value of the heat pump in double.

Thanks for your explanation!

I found the right connector and is indeed described in the sections you mentioned.
I was wondering: It is already used (probably by the FEK). Did you just added the extra wires?
And did you use the + also for the power to the board? Since you have a voltage regulator in the picture. :slight_smile:

And how does the ‘connector’ work? Are those ‘just’ clamps and did you just use a screwdriver to push them open?

And last: The code you published, it is all ESPHome code, right? Which then exposes the devices to HA.

I already ordered the parts and start soldering this weekend. :wink:

Yes, I just added the CAN-Controller to the same ports that are already used by the FEK.
Since this is a bus, you can just add additional devices that use different addresses.
I use address 680 for the MCP2515, as this was already used by others too and works.
In my case, FEK sends the room-temperature and humidity in intervals without dedicated call-outs from CAN-id 301 and my heat pump uses CAN-id 180. But the addresses can be different in other environments. Further you will see, that there are some more addresses used by different parts of the heat pump. I only listen for CAN id 301 and CAN id 180 currently.

You also don’t need a terminal resistor to connect the CAN-controller, since this should already be in the FEK. Just connect the two wires - in my case yellow and white. (P.S. The resistor showed in the picture IS needed :wink: )

The voltage regulator was a first shot trial. I thought I could use the power supply of the heat pump. But when I connected it, the display of the heat pump turned dark. So this probably doesn’t deliver sufficient power to supply the display and the ESP32 together.
Therefore I don’t use this voltage regulator anymore, but connected an external USB power supply.

I clamped the wires without a screw driver from the top. This seemed to fit enough for me. See picture attached.

The code I published is all ESPHome, right. The lambda-fucntions are used for C++ code segments.
Maybe try with a minimal configuration first, so it’s easier to troubleshoot e.g. if your device uses different CAN-ids.
A good troubleshooting advice from my learnings is, to use a codeblock like the one below, to see whats going on.
This sends a request every 60 seconds to the heat pump (assuming heat pump id is 180), to submit the outside temperature (canbus.send section) and listens actively for any response-package from CAN-id 180 as well as 301 and show the hex-content. You will also see, if a package was received from other IDs, but without the content, if you are not explicitly listening to them. I was struggling some days to find out how this works. Maybe you are more used to coding ESPHome than me and already knowed before.
Once you know the correct CAN-IDs of your heat pump and FEK it should be quite easy to go on with adapting my code above.

time:
  - platform: homeassistant
    id: homeassistant_time
    on_time:
     
      - seconds: /60
        then:
#temperature outside 1/10 °C et dec value
          - canbus.send:
              data: [ 0x31, 0x00, 0xfa,0x00,0x0c,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms
       
spi:
  id: McpSpi
  clk_pin: GPIO18
  mosi_pin: GPIO23
  miso_pin: GPIO19

canbus:
  - platform: mcp2515
    id: my_mcp2515
    spi_id: McpSpi
    cs_pin: GPIO15
    can_id: 680
    use_extended_id: false
    bit_rate: 20kbps
    on_frame:





#Show data in raw form as hex-values
    - 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)));
              ESP_LOGD("main", "Antwort von 301 Hex: %x %x %x %x %x %x %x", wert0, wert1, wert2, wert3, wert4, wert5, wert6);
              ESP_LOGD("main", "Antwort von 301 Float: %f", wert7);
              ESP_LOGD("main", "Antwort von 301 Dez.: %i %i", wert5, wert6);


#Show data in raw form as hex-values
    - 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)));
              ESP_LOGD("main", "Antwort von 180 Hex: %x %x %x %x %x %x %x", wert0, wert1, wert2, wert3, wert4, wert5, wert6);
              ESP_LOGD("main", "Antwort von 180 Float: %f", wert7);
              ESP_LOGD("main", "Antwort von 180 Dez.: %i %i", wert5, wert6);
1 Like

Thanks for all the info! Didn’t had time to solder, so hopefully some evening this week. :wink:
You did not connect the ground? To have a common ground? Or are you using the same outlet? (Probably also good I think)

I found in the list of juerg also the states, which I don’t see in your code. Didn’t these work, or are you just not interested in these? :wink:

I will start with your simplified code first to see if I have the same CAN-IDs and go from there. I will keep you updated!

Hello Justin,

I didn’t connect to common ground. I don’t know if it has any good or bad impact. Maybe I will try this.

Regarding states I didn’t think of logging them yet.
I will include the run time some day and will think of other stuff that makes sense.
But currently I’m quite happy while things that are already implemented work as expected.
I still have some issues with single entries that deliver strange values and need to be proofreaded.
The code becomes kind of crowded by the time.

Hi Rober,

I found some time to solder and test.
First attempt partly failed due to bad connection on the WPF.
After I inserted the wires correctly I got some data going.
Tried to figure out the addresses, but they are the exact same as yours, so all code can be used.

But
 After connecting and testing I found that my WPF did not work anymore. Well
 I worked partly.
The pump was on and off as usual, but it did not heat the water or the heating.
Also the menu on the WPF worked very slow.

I tried to power cycle both the WPF as the board but that did not help.

After removing the wires it all worked as before.

Did you also encounter this also?
I’m wondering
 should the end resistor be connected (just add the jumper on the mcp2515 board)

Or did I use a wrong wire? It’s quite a thick wire, but not very long, so I don’t that should cause any problem.
I also just use the usb connector with an adapter, so the mcp25215 is getting not exactly 5v, but more something like 4.95v.

Any help is appreciated!
Thanks!

Hello Justin,

I didn’t have any problems like the ones you mentioned
My connection-variant from the top side isn’t very professional. The right connection direction would be probably from the side-entry. I thinkt the top entry is actually to open the clamp.
If the wires are too thick, maybe the clamps of the WPF are opened and the connection to the FEK-wire is bad.

I do not use the jumper for the end resistor, as I was told by Vincent (from another thread) that this was already in the FEK and I don’t need it.

So my guess is, maybe check the wires.
I use a shielded data-cable as it is also used for KNX-devices.

Hi Rober,

Hmmm
 thats a pity

Was hoping you encountered the same problem.

I already used the side entry.
It’s a spring connector.
You can press it down from above with a small screwdriver.

You also have just the usb connection use, right?
Did you measured the voltage on the pin connected to the VCC of the mcp2515?

I do have used a NodeMCU ESP8266, so not an ESP32, but that should not be any problem.
I will try an other cable (have some shielded cables used for an alarm system) and also an external power supply with the voltage converter to have a solid 5v on the mcp2515.

No I didn’t measure the voltage on the pin.

Maybe check the configuration to use the correct clk_pin, mosi_pin, miso_pin and cs_pin.
But when it worked already, this seems to be the wrong place to look at.

Maybe a stupid question, but did you connect the ground? Because I didn’t.
WPF ground to the mcp2515 & nodemcu board ground that is.

No, I didn’t.
I just connected the Hi and Lo Pins of the heat pump to the mcp2515.
Maybe you could send a picture how you connected this.

Hmmm
I’m out of options then

I have no idea what I can change anymore.
The only thing could be that the mcp2515 board is broken I guess


Here some images from the first attempt (I have no image of the connection to the WPF, but I’m just using the ‘pin’ connector next to the FEK connection. There are two connectors for L and 2 for H) :



I do not see the 4k7 resistor for the miso pin.
Have another look at the wiring option section on this page

I think I just found the resistor. If the yellow wire is going to the miso-pin, the wiring looks ok to me.

Did you already test with a shielded wire?
Does your heat pump at least work as usual again?

Yes, I tried with a shielded cable. Also tried with the ground connected, since I read a lot of threads who were also connecting the ground. But nothing worked. Once I disconnect the wires the system is just working as expected.

I just ordered a new MCP2515 board and an ESP32 just to be sure none of the boards are broken.

Hopefully that does the trick.

Oh and yes I did use the resistor. :grin:

The guy that helped me with the ESP-configuration is working on a python-tool for Raspberry pi.
Could take some time until he is done with it, though.
He also had problems with connecting an ESP8266.
Using a Raspberry Pi for troubleshooting may be another option if it doesn’t work as expected, when you get the new board.

Ah, ok. Maybe it has something to do with the used libraries for the different boards or some timings. You’ll never know
 I receive them tomorrow, so tomorrow we will know! :slight_smile:

Already found some other project which are using pi’s, so yes, when the ESP does not work, I have some other options :wink: :

https://nocloud.info/en/attach-stiebel-eltron-lwz-504-using-usbtin-and-can-bus/

Also the ESP32 with a new MCP2515 board does not work
 I’m out of options now.
Well
 it works partly. I get some data, but not all and the WPF is not working correctly (slow menu etc)

Even tried different options with the software to test:

  • Empty ‘sketch’: All working
  • Sketch with initialising the can bus: All working
  • Sketch with only reading (on_frame): WPF starts struggling with the CAN info (slow menu etc)

Also tried with different addresses: (0x700, 0x780 and ofcourse 0x680)
And with different baudrates: 20kbps (partly working) and 50kbps (not working)

Hopefully someone else encountered the same problem and did found a solution.
Only thing I can think of, is the firmware of the WFP07COOL. Maybe there are some differences.

I think I will look into a pi option, just to test.
Or something like, to see if what is going on on the bus:

Oh, Rober, do you see you’re ESPHome in the Bus candidates in the menu of the WPF?

Hello,

trying with a Pi or alternative USB-Can adapter would be promissing, as it is easier then to send dedicated packages and listen what’s going on. The CAN adapter produces costs of course.

I see the following Bus candidates: WPM3i (Software 391-08), FES (Software 417-07), FEK (Software 416-02), MFG (Software 18).
So no, nothing regarding the ESPHome device in the menu of the WPF.
I don’t get answer for all of the sensors by the way.
E.g. I get no correct response for the forward temperature. Maybe I must look for an alternative Elster-table to receive more.

You guys just hooked up the 5V pins directly to the ESP? I don’t see any level shifting happening?