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

I added the log to be printed at info level by default. This should enable you to match the Read/Write IDs to the CANMembers and adapt them if necessary. Also saw some strange values there that I need to investigate further.

Edit: nevermind … those big values for DAY, HOUR and so on are little endian :wink:

value of 0 usually means it is a read request

[23:51:14][I][Communication:079]: Message received: Read/Write ID 0xd0 0x3c for property 0x0176 with raw value: 257
[23:51:14][I][CallbackHandler:024]: Callback not found for Kessel 0x0176
[23:51:14][I][Communication:079]: Message received: Read/Write ID 0xd0 0x3c for property 0x0112 with raw value: 2816
[23:51:14][I][CallbackHandler:024]: Callback not found for Kessel 0x0112
[23:51:14][I][Communication:079]: Message received: Read/Write ID 0xd0 0x3c for property 0x0121 with raw value: 768
[23:51:14][I][Communication:079]: Message received: Read/Write ID 0xd0 0x3c for property 0x0122 with raw value: 3584
[23:51:14][I][Communication:079]: Message received: Read/Write ID 0xd0 0x3c for property 0x0123 with raw value: 768
[23:51:14][I][Communication:079]: Message received: Read/Write ID 0xd0 0x3c for property 0x0124 with raw value: 6144
[23:51:14][I][Communication:079]: Message received: Read/Write ID 0xd0 0x3c for property 0x0126 with raw value: 12800
[23:51:14][I][Communication:079]: Message received: Read/Write ID 0xd0 0x3c for property 0x0001 with raw value: 0
1 Like

Unfortunately still an error :frowning:

Linking .pioenvs/thz404/firmware.elf
/config/.esphome/platformio/packages/toolchain-xtensa-esp32/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: .pioenvs/thz404/src/main.cpp.o:(.literal._ZN6Mapper8instanceEv[Mapper::instance()]+0xc): undefined reference to `Mapper::Mapper()'
/config/.esphome/platformio/packages/toolchain-xtensa-esp32/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: .pioenvs/thz404/src/main.cpp.o:(.literal._Z17processCanMessageRKSt6vectorIhSaIhEE+0xc): undefined reference to `Mapper::getType(Property) const'
/config/.esphome/platformio/packages/toolchain-xtensa-esp32/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: .pioenvs/thz404/src/main.cpp.o:(.literal._Z17processCanMessageRKSt6vectorIhSaIhEE+0x10): undefined reference to `GetValueByType(unsigned short, Type)'
/config/.esphome/platformio/packages/toolchain-xtensa-esp32/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: .pioenvs/thz404/src/main.cpp.o:(.literal._ZNSt17_Function_handlerIFvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjEZ5setupvEUlS5_jE33_E9_M_invokeERKSt9_Any_dataOS5_Oj+0x0): undefined reference to `Mapper::getBetriebsartId(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const'
/config/.esphome/platformio/packages/toolchain-xtensa-esp32/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: .pioenvs/thz404/src/main.cpp.o: in function `Mapper::instance()':
/config/.esphome/build/thz404/src/mapper.h:52: undefined reference to `Mapper::Mapper()'
/config/.esphome/platformio/packages/toolchain-xtensa-esp32/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: .pioenvs/thz404/src/main.cpp.o: in function `processCanMessage(std::vector<unsigned char, std::allocator<unsigned char> > const&)':
/config/.esphome/build/thz404/src/communication.h:78: undefined reference to `Mapper::getType(Property) const'
/config/.esphome/platformio/packages/toolchain-xtensa-esp32/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /config/.esphome/build/thz404/src/communication.h:80: undefined reference to `GetValueByType(unsigned short, Type)'
/config/.esphome/platformio/packages/toolchain-xtensa-esp32/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: .pioenvs/thz404/src/main.cpp.o: in function `std::_Function_handler<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int), setup()::{lambda(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int)#35}>::_M_invoke(std::_Any_data const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, unsigned int&&)':
/config/thz/yaml/thz504_energy.yaml:30: undefined reference to `Mapper::getBetriebsartId(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const'
collect2: error: ld returned 1 exit status
*** [.pioenvs/thz404/firmware.elf] Error 1

Can you try to add mapper.cpp into the include section in the main yaml?

Can we track this as an issue in github? To not spam this thread here

@tomcat I’ve finally managed to replace the FEK with Home Assistant sensors <3
This commit adds the functionality:

image
As you can see, the values persist and are no longer overriden by the WP.
This enables me to set the RAUMEINFLUSS to 100% and no longer need to rely on weird settings for the HEIZKURVE in combination with AUßENTEMP, FUßPUNKT and all that crap. I’m using a HA helper that builds the average value of all temperature sensors in the house for this. On sunny days the heating should also turn off real quick now, because it will be reflected way faster than via the RÜCKLAUFIST temp.

Next thing in the line is to be able to set LEISTUNG_AUSLEGUNG_HEIZUNG, PUMPENDREHZAHL_HEIZEN and RAUMEINFLUSS along with VERDICHTER_STARTS to achieve better performance.
WIP Adds number entities by kr0ner · Pull Request #5 · kr0ner/OneESP32ToRuleThemAll · GitHub

So if I understand your code right you just send the roomtemp to the identifier 0x0011 to can member 0x401 and its accepting the write.
0x401 is inside your heat pump and you dont have a external fek installed under this id?
Seams like the wpm 4 has a different behaviour compared to wpm3 because this is not working for me :frowning:

Yes, but I use the same ready/write IDs as for 0x301. That seems to work :man_shrugging:t3: what could also work is this:

Die Luftfeuchtigkeit und Raumtemperatur brauche ich nicht aktiv von der FEK abzufragen - die kommt bei mir alle paar Minuten von der ID 301 und wird an ID 601 als Änderung gesendet.
(Paket C0 01 75 xx xx bzw. C0 01 11 xx xx)

[21:43:56] [R] Paket 6101fa00110000 | TX: 680 | RX: 301 | E-idx: 011   = Raumisttemp                              | Dir: [R] | Elster Type: et_dec_val           | Value converted:          | Value big: 0        | lit: 0        | Bits: 0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0 | Processed: [0]
[21:43:57] [R] Paket d200fa00118000 | TX: 301 | RX: 680 | E-idx: 011   = Raumisttemp                              | Dir: [A] | Elster Type: et_dec_val           | Value converted:          | Value big: -32768   | lit: -128     | Bits: 1|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0 | Processed: [0]

0x680 is an ISG. And its polling the roomtemp for HK1 too periodical. But its the same as I try it manually.
301/302 and also 601/602 both related to HK1/HK2 are not writeable or respond with meaningful values :frowning: 0x401/0x402 does not excist on my device.

How about this?
{ “RAUMTEMPERATUR_FEK” , 0x4ec7, et_dec_val},
{ “LUFTFEUCHTE_FEK” , 0x4ec8, et_dec_val},

Tbh I just tried all kinds of combinations until one worked :sweat_smile:

Not working.

Hello everyone, first of all a great project.

I’m also currently reading out my TECALOR TTF cool 8.6 over MCP and ESP8266.
This is a brine water heat pump which takes the energy from the earth from a depth of 150 meters.

I have a latest generation with a scroll compressor an WPM4 and FET1 at jear 2022.

While looking for CAN IDs today I came across the following which come from CAN ID 514.

0x514 - HEAT PUMP PROCESS DATA

HOT GAS TEMPERATURE
22 0 fa 2 65 1 25

COMPRESSOR ENTRY TEMPERATURE
22 0 fa 6 d9 1 1b

OIL SUMP TEMPERATURE
22 0 fa a 39 1 92

RETURN TEMPERATURE HEAT SOURCE
22 0 fa 4f a6 0 64

FLOW TEMPERATURE HEAT SOURCE
22 0 fa 4f a7 0 52

HEAT SOURCE PRESSURE
22 0 fa 4f a8 0 10

Heat source pump performance
22 0 fa 4f a9 0 0

ACTUAL SPEED OF COMPRESSOR
22 0 fa 6 eb 0 0

SET SPEED OF COMPRESSOR
22 0 fa 6 ec 0 0

CURRENT INVERTER
22 0 fa 6 b2 0 0

INVERTER VOLTAGE
22 0 fa 6 b1 0 99

WP WATER VOLUME FLOW
22 0 fa 2 e2 0 0

I simply query it via CAN ID 680 and only exchange the first digit to 0xa1 2.nd digit to 14 and leave digits 6 and 7 at 0x00

Exaple for WP WATER VOLUME FLOW:
a1 14 fa 2 e2 0 0

or INVERTER VOLTAGE
a1 14 fa 6 b1 0 0

The answer comes over CAN ID 514.

Have fun…

Since the Magpie table fits almost 0% for me, here are a few values ​​to read from the TTF 8.6 cool with WPM4 and FET.

Read time/date
Day: 91 0 fa 4f 32 0 0
Month: 91 0 fa 4f 31 0 0
Year: 91 0 fa 4f 30 0 0

Hour: 91 0 fa 4f 34 0 0
Minute: 91 0 fa 4f 33 0 0

Summer time start:
Tag: 91 0 fa 4f 3b 0 0
Month: 91 0 fa 4f 3c 0 0

Summer time end:
Tag: 91 0 fa 4f 3d 0 0
Month: 91 0 fa 4f 3e 0 0

SUMMER OPERATION yes/no)
31 0 fa 4f 1e 0 0 (0 or 1)

OUTDOOR TEMP SUMMER OPERATION 24H Medium
31 0 fa 1 bf 0 83

Building insulation
31 0 fa 4f 1f 0 2

Heating curve gradient
c1 1 fa 4f 2b 0 1b

Thanks to this project, i am able to read data from my WPL 17.
But i see an problem to receive “Hot water temperature target comfort” and “Hot water temperature target eco”. I send 0x31,0x00,0x03,0x00,0x00,0x00,0x00 and 0x31,0x00,0xfa,0x0a,0x06,0x00,0x00 but only receive the value of -3.276,8 °C. Does anyone has an idea how to fix it?

solved:

Thanks to the input of CLAM01 i was able to solve it:

send Request:

# temperature_water_target_eco - EINSTELL_SPEICHERSOLLTEMP2 - 0x0a06, et_dec_val
          - canbus.send:
              data: [ 0x41, 0x01, 0xfa,0x0a,0x06,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms
# temperature_water_target_comfort - EINSTELL_SPEICHERSOLLTEMP" - 0x0013, et_dec_val},
          - canbus.send:
              data: [ 0x41, 0x01, 0x13,0x00,0x00,0x00,0x00 ]
              can_id: 0x680
          - delay: 200ms

receive Value (Attention: different can_id, all other values are from 0x180)

    - can_id: 0x201
      then:
        - lambda: |-
            if(x[0]==0xd2 and x[1]==0x00 and x[3]==0xfa and x[4]==0x06) {
              float temperature =(float((int16_t((x[6])+( (x[5])<<8))))/10);
              id(temperature_water_target_eco).publish_state(temperature);
              ESP_LOGD("main", "temperature_water_target_eco Eco Soll empfangen over can is %f", temperature);
            }
            if(x[0]==0xd2 and x[1]==0x00 and x[2]==0x13) {
              float temperature =(float((int16_t((x[4])+( (x[3])<<8))))/10);
              id(temperature_water_target_comfort).publish_state(temperature);
              ESP_LOGD("main", "temperature_water_target_comfort Komfort Soll empfangen over can is %f", temperature);
            }

send new value to comfort button :

  - platform: template
    name: Send Temperature 37
    id: send_temperature_37
    on_press:
      then:
        - canbus.send:
            data: [ 0x40, 0x01, 0x13,0x01,0x72,0x00,0x00 ]
            can_id: 0x680

  - platform: template
    name: Send Temperature 47
    id: send_temperature_47
    on_press:
      then:
        - canbus.send:
            data: [ 0x40, 0x01, 0x13,0x01,0xd6,0x00,0x00 ]
            can_id: 0x680

try:
ECO temperature Target get
0x41,0x01,0xfa,0x0a,0x06,0x00,0x00

Komfort temperature target get
0x41,0x01,0x13,0x01,0x87,0x00,0x00

Or simply adjust the temperatures in the setting on the display and see what kind of packets come into the CAN bus with 0x30 or whatever. These are the messages to set a setting with a 0.

I then simply used the example 0x30 made a 0x31 and then sent the same rest of the CAN message and saw whether the value had changed in the setting

Example:
send 40 1 fa a 6 1 a4 sets the ECO hot water temperature for me

send 41 1 fa a 6 1 a4 reads the ECO hot water target temperature for me

Does anyone have a working ID for summer mode for a LWZ/THZ 404 eco? :slight_smile: Unfortunately I only get “unknown” for kSOMMERBETRIEB = 0xfdb4.

I could not find a working ID either, but recognized that the target temperature for the heating circuit drops to 5°C once Sommermode is active. On my WPL15 this temperature is on 0x01d7. My work around looks like this then:

 - platform: template
    name: "Sommerbetrieb"
    id: sommerbetrieb
    icon: "mdi:weather-sunny"
    lambda: |-
      id(sommerbetrieb).publish_state(id(t_hksoll).state == 5.0);
      return {};
1 Like

@StefanG84 check out this commit Adds BETRIEBS_STATUS_2 · kr0ner/OneESP32ToRuleThemAll@5c29ca5 · GitHub
according to the MODBUS spec the SOMMERBETRIEB flag is hidden in another BETRIEBSSTATUS message, together with OFEN/KAMIN STATUS. Should work now :slight_smile:

@tomcat: can you check Fixes RAUMISTTEMP · kr0ner/OneESP32ToRuleThemAll@4e20e6b · GitHub
if this also works for you? I’m able to set the room temperature reliably and it works nicely in combination with RAUMEINFLUSS.

The actual fix is this line
static const CanMember FEK {0x401, "FEK", {0x61, 0x01}, {0x60, 0x01}, {0x00, 0x00}};
in combination with
sendData(FEK, Property::kRAUMISTTEMP, static_cast<std::uint16_t>(room_temp * 10.0f));

I tested this some times ago. Wasnt working.
I was able to set Raumeinfluss and Raumfeuchte when send adress was 401 or 402 and reciver was 601/602 but when i wrote to Raumsolltemp 0x0012 or Raumisttemp 0x0011 i just got -40 as response.
When I send from 0x6a2 what I do for most other adresses not even Raumeinfluss and Raumfeuchte was working.
I guess 401 is the Adress of a FEK configured to heating circle 1 and 402 same for heating circle2 because 301/601 = heating circle 1 and 302/602 = heating circle 2

@xylone, @gagga, @b0bb0
Did you guys ever figure out the pump panel freeze, crashing etc issues?

I started implementing the minimal ESP32 + MCP2515 setup to my 2016 WPF07 and faced similar problems. I’m powering things with external USB PSU and have connected the grounds (ESP GND to pump CAN terminal GND). Using 20 kbps rate. Tried 50 but pump crashed instantly. Pump software:
WPM3i 391-10
FES 417-10
MFG 18

I witnessed these symptoms:

  • FES panel menus became slow. There was sometimes circular loading icon for some time before some info menu opened.
  • Pump refused to heat anything. No errors on screen / in history but hot water and heating temps fell below limits. Had to power cycle the pump controllers to fix it.
  • FES started showing errors in front page like “Error: to WPM”. Had to power cycle to fix this too.
  • Pump tried to start but instantly (within 2 seconds) stopped. On screen there were no errors but noticed in diag history some errors “to FES”. Pump kept retrying every 20 mins (sleeping period). Again had to power cycle to fix it.

I’m suspecting it was all due to poor connections with but would seem a bit weird that a CAN based system would act out like this because poor connectivity of one node that only requests parameters. I still have a flaky test setup with dupont wires but ditched the breadboard and things seem a bit more stable. If other stuff works out ok, I’ll mill a pcb for it and probably throw level shifter there and hope it helps things further.

Couple of other silly questions:

  1. I changed the can_id from 680 to 0x6a2 while trying to fix the issues. Not sure this had any effect but left it like that for now. I set this both to send messages and in MCP2515 settings in the same hex format 0x6a2. Does anyone know if the this can module settings matters at all or if only thing that matters is the id given when sending messages? According to ESPHome CAN manual the sending part overwrites the default so not sure why it’s used here, especially when it’s in decimal format in default config?

  2. @roberreiter checks the can-id of received messages and only parses ones with matching 680 id while the 2 other repos mentioned here (with some c++ helper modules) seem to ignore that and handle everything. With can-id 0x6a2 I of course receive messages starting d2 22 and have it as a filter and it works ok and I guess this is matter of choice but is there any other reason for this filtering?

  3. A bit of a side question, @roberreiter you mentioned somewhere that this 0x6a2 corresponds to CAN-ID 302. How so?

  4. Does someone have working scripts for switching the pump to “emergency mode” to utilize PV with resistors only? It was discussed earlier here but didn’t spot any example setups. I’d like to use this to avoid compressor trying to restart every 20 mins (sleep period) just to notice the temp still get too high for it and then shut down. Too bad the unit isn’t smarter and doesn’t handle this internally better. I’d also use an external 3-phase relay to enable heating elements according to available solar power and many times it would only allow one of them (=3kW) to be on so heating my 300L external reservoir to +60C or +65C would take quite some time and would end up with really unhealthy amount of compressor starts.

  5. Setting eco/comfort temperatures doesn’t work for me. For initial test I followed Rob’s example and commands seem to be getting through but the setpoint wont change on the unit. I’m receiving the current setpoint from CAN-ID 180. I then checked the logs when I adjusted the setpoint from panel and I noticed the sender ID being 100, but I guess the 180 is still the right destination? Any ideas what to try to make it work?

Example of received COMFORT temp:

[22:10:46][D][canbus:072]: received can message (#1) std can_id=0x180 size=7
[22:10:46][I][main:1328]: Antwort von 180 Hex: 22 0 13 1 e0 0 0
[22:10:46][I][main:1329]: Antwort von 180 Float: 0.000000
[22:10:46][I][main:1330]: Antwort von 180 Dez.: 0 0
[22:10:46][I][main:1331]: Antwort klein von 180 Float: 480.000000
[22:10:46][I][main:1332]: Antwort klein von 180 Dez.: 1 224

Example of received ECO temp when adjusting from the panel:

[22:10:45][D][canbus:072]: received can message (#1) std can_id=0x100 size=7
[22:10:45][I][main:1383]: Antwort von 100 Hex: 30 0 fa a 6 1 c4
[22:10:45][I][main:1384]: Antwort von 100 Float: 452.000000
[22:10:45][I][main:1385]: Antwort von 100 Dez.: 1 196

Example log when changing the value from HA:

[22:14:23][D][homeassistant.text_sensor:017]: 'input_text.ww_eco_temp': Got state '452'
[22:14:23][I][main:938]: eco changed!!!!!!!!!!!!!!!!!!
[22:14:23][D][text_sensor:064]: 'ww_eco_temp': Sending state '452'
[22:14:23][I][main:967]: eco sending!!!!!!!!!!!!!!!!!!
[22:14:23][D][binary_sensor:036]: 'update_sensor': Sending state ON
[22:14:23][D][canbus:035]: send standard id=0x6a2 rtr=FALSE size=7
[22:14:23][D][binary_sensor:036]: 'update_sensor': Sending state OFF 

To answer myself to some of them:

The system has been stable after removing the breadboard. Nothing else has changed so I guess the pump crashing was due to bad wiring and maybe ground potential differences.

1 ) Seems that everyone is just having unnecessary additional can-id in their send functions and these could be left out. Enough to specify it once in can-bus settings.
2 ) Haven’t noticed any issues when catching the IDs disregarding to whom the message was addressed.
5 ) Seems that sender id does matter and even if the pump does respond to value queries, it seems to ignore value change requests from some IDs. I switched back to 0x680 sender and changing temperature setpoints started working.