hn / bsh-home-appliances

BSH Bosch Siemens home appliances reverse engineering: D-Bus, washing machine, dryer electronics
32 stars 4 forks source link

Add support for Bosch Series 6 Dryer (WTW85490) #2

Closed freddiebd closed 1 week ago

freddiebd commented 6 months ago

Hello Hajo,

Thank you for the excellent project instructions :)

I have been successful in collecting lots of beautiful bus traffic! I'm not sure exactly where to begin with all of this so any help/tips would be appreciated. Let me know if more logs are required.

Door Opened: 04 | 21.10-00 | 29 03 | 33 fe (crc=ok) | 2a (ack=ok)

Door Closed: 04 | 21.10-00 | 29 06 | 63 5b (crc=ok) | 2a (ack=ok)

Low Heat On: 09 | 11.10-06 | 01 3c 03 68 0c 00 04 | c9 09 (crc=ok) | 1a (ack=ok) 05 | 21.10-04 | 05 32 64 | 63 81 (crc=ok) | 2a (ack=ok) 04 | 21.10-02 | 32 64 | 9e 56 (crc=ok) | 2a (ack=ok)

Low Heat Off: 09 | 11.10-06 | 01 3c 03 68 0c 00 00 | 89 8d (crc=ok) | 1a (ack=ok) 05 | 21.10-04 | 05 31 38 | ad ab (crc=ok) | 2a (ack=ok) 04 | 21.10-02 | 31 38 | 50 7c (crc=ok) | 2a (ack=ok)

Fine Adjust Off: 09 | 11.10-06 | 01 3c 03 68 06 00 00 | 4e 4c (crc=ok) | 1a (ack=ok) 05 | 21.10-04 | 05 2d 00 | 5c ee (crc=ok) | 2a (ack=ok) 04 | 21.10-02 | 2d 00 | a1 39 (crc=ok) | 2a (ack=ok)

Fine Adjust Low(+): 09 | 11.10-06 | 01 3c 03 68 08 00 00 | 55 4d (crc=ok) | 1a (ack=ok) 05 | 21.10-04 | 05 2e 68 | e4 13 (crc=ok) | 2a (ack=ok) 04 | 21.10-02 | 2e 68 | 19 c4 (crc=ok) | 2a (ack=ok)

Fine Adjust Medium(++): 09 | 11.10-06 | 01 3c 03 68 0a 00 00 | 3b 2d (crc=ok) | 1a (ack=ok) 05 | 21.10-04 | 05 2f d0 | f1 f1 (crc=ok) | 2a (ack=ok) 04 | 21.10-02 | 2f d0 | 0c 26 (crc=ok) | 2a (ack=ok)

Fine Adjust High(+++): 09 | 11.10-06 | 01 3c 03 68 0c 00 00 | 89 8d (crc=ok) | 1a (ack=ok) 05 | 21.10-04 | 05 31 38 | ad ab (crc=ok) | 2a (ack=ok) 04 | 21.10-02 | 31 38 | 50 7c (crc=ok) | 2a (ack=ok)

Select Program Cotton Cupboard Dry Plus: 04 | 11.10-01 | 03 00 | d1 6e (crc=ok) | 1a (ack=ok) 05 | 11.10-05 | 00 00 00 | 9e 9c (crc=ok) | 1a (ack=ok) 09 | 11.10-06 | 01 3c 03 68 0c 00 00 | 89 8d (crc=ok) | 1a (ack=ok) 05 | 11.10-05 | 06 01 00 | 1f 0d (crc=ok) | 1a (ack=ok) 09 | 11.10-06 | 01 3c 03 68 0c 00 00 | 89 8d (crc=ok) | 1a (ack=ok) 05 | 11.10-05 | 00 00 00 | 9e 9c (crc=ok) | 1a (ack=ok) 05 | 11.10-05 | 05 00 00 | 75 6c (crc=ok) | 1a (ack=ok) 05 | 21.10-04 | 05 31 38 | ad ab (crc=ok) | 2a (ack=ok) 04 | 21.10-02 | 31 38 | 50 7c (crc=ok) | 2a (ack=ok)

Select Program Cupboard Dry: 04 | 11.10-01 | 03 00 | d1 6e (crc=ok) | 1a (ack=ok) 05 | 11.10-05 | 00 00 00 | 9e 9c (crc=ok) | 1a (ack=ok) 09 | 11.10-06 | 02 3c 02 68 0c 00 00 | fb 5e (crc=ok) | 1a (ack=ok) 05 | 11.10-05 | 06 02 00 | 4a 5e (crc=ok) | 1a (ack=ok) 09 | 11.10-06 | 02 3c 02 68 0c 00 00 | fb 5e (crc=ok) | 1a (ack=ok) 05 | 11.10-05 | 00 00 00 | 9e 9c (crc=ok) | 1a (ack=ok) 05 | 11.10-05 | 05 00 00 | 75 6c (crc=ok) | 1a (ack=ok) 05 | 21.10-04 | 05 2a e4 | 78 d3 (crc=ok) | 2a (ack=ok) 04 | 21.10-02 | 2a e4 | 85 04 (crc=ok) | 2a (ack=ok)

Select Program “Timed Dry Warm” (20 Minutes Default): 04 | 11.10-01 | 03 00 | d1 6e (crc=ok) | 1a (ack=ok) 05 | 11.10-05 | 00 00 00 | 9e 9c (crc=ok) | 1a (ack=ok) 09 | 11.10-06 | 07 3c 05 68 06 00 00 | 22 ec (crc=ok) | 1a (ack=ok) 05 | 11.10-05 | 00 00 00 | 9e 9c (crc=ok) | 1a (ack=ok) 09 | 11.10-06 | 07 3c 05 68 06 00 00 | 22 ec (crc=ok) | 1a (ack=ok) 05 | 11.10-05 | 05 04 b0 | 1e 73 (crc=ok) | 1a (ack=ok) 04 | 21.10-02 | 04 b0 | ba 9c (crc=ok) | 2a (ack=ok) 05 | 11.10-05 | 00 00 00 | 9e 9c (crc=ok) | 1a (ack=ok) 05 | 11.10-05 | 06 07 00 | b5 ab (crc=ok) | 1a (ack=ok) 05 | 21.10-04 | 05 03 c0 | a0 4b (crc=ok) | 2a (ack=ok)

Increased “Timed Dry” to 30 Minutes: 05 | 11.10-05 | 00 0a 00 | 71 57 (crc=ok) | 1a (ack=ok) 05 | 11.10-05 | 05 07 08 | 6d f3 (crc=ok) | 1a (ack=ok) 04 | 21.10-02 | 07 08 | c9 1c (crc=ok) | 2a (ack=ok) 05 | 11.10-05 | 00 00 00 | 9e 9c (crc=ok) | 1a (ack=ok) 05 | 21.10-04 | 05 03 c0 | a0 4b (crc=ok) | 2a (ack=ok)

Increased “Timed Dry” to 40 Minutes: 05 | 11.10-05 | 00 0a 00 | 71 57 (crc=ok) | 1a (ack=ok) 05 | 11.10-05 | 05 09 60 | a3 52 (crc=ok) | 1a (ack=ok) 04 | 21.10-02 | 09 60 | 07 bd (crc=ok) | 2a (ack=ok) 05 | 11.10-05 | 00 00 00 | 9e 9c (crc=ok) | 1a (ack=ok) 05 | 21.10-04 | 05 03 c0 | a0 4b (crc=ok) | 2a (ack=ok)

Select Program “Wool Finish”: 04 | 11.10-01 | 03 00 | d1 6e (crc=ok) | 1a (ack=ok) 05 | 11.10-05 | 00 00 00 | 9e 9c (crc=ok) | 1a (ack=ok) 09 | 11.10-06 | 09 3c 05 68 06 00 00 | 10 64 (crc=ok) | 1a (ack=ok) 05 | 11.10-05 | 00 00 00 | 9e 9c (crc=ok) | 1a (ack=ok) 09 | 11.10-06 | 09 3c 05 68 06 00 00 | 10 64 (crc=ok) | 1a (ack=ok) 05 | 11.10-05 | 05 01 68 | ab f3 (crc=ok) | 1a (ack=ok) 04 | 21.10-02 | 01 68 | 0f 1c (crc=ok) | 2a (ack=ok) 05 | 11.10-05 | 00 00 00 | 9e 9c (crc=ok) | 1a (ack=ok) 05 | 11.10-05 | 06 09 00 | 96 a4 (crc=ok) | 1a (ack=ok) 05 | 21.10-04 | 05 01 68 | f2 cb (crc=ok) | 2a (ack=ok)

Press Start/Stop Button (Double beep didn’t start, dryer sometimes does that!…): 04 | 11.10-01 | 23 00 | d7 88 (crc=ok) | 1a (ack=ok) 04 | 11.10-01 | 24 00 | 4e 1f (crc=ok) | 1a (ack=ok) 04 | 21.10-00 | 39 00 | 00 ee (crc=ok) | 2a (ack=ok)

Press Start/Stop Button (Started. Now running): 04 | 11.10-01 | 23 00 | d7 88 (crc=ok) | 1a (ack=ok) 04 | 11.10-01 | 24 00 | 4e 1f (crc=ok) | 1a (ack=ok) 04 | 21.10-00 | 2e 00 | 9a 0a (crc=ok) | 2a (ack=ok) 04 | 11.10-01 | 01 00 | b7 0c (crc=ok) | 1a (ack=ok) 05 | 11.10-05 | 00 00 00 | 9e 9c (crc=ok) | 1a (ack=ok) 04 | 21.10-00 | 16 00 | 16 36 (crc=ok) | 2a (ack=ok)

Dryer Running Time changed from 6 mins to 5 mins remaining: 04 | 21.10-02 | 01 2c | 07 5c (crc=ok) | 2a (ack=ok) 04 | 21.10-00 | 0c 00 | fa 8e (crc=ok) | 2a (ack=ok) 03 | 21.10-03 | 0b | 08 73 (crc=ok) | 2a (ack=ok)

4 mins remaining to END: 04 | 21.10-02 | 00 f0 | 3e 9c (crc=ok) | 2a (ack=ok) 04 | 21.10-00 | 0c 00 | fa 8e (crc=ok) | 2a (ack=ok)

Figured this out - Hexadecimal 00f0 = 240 seconds

3 mins remaining to END: 04 | 21.10-02 | 00 b4 | 36 dc (crc=ok) | 2a (ack=ok) 04 | 21.10-00 | 0c 00 | fa 8e (crc=ok) | 2a (ack=ok)

Figured this out - Hexadecimal 00b4 = 180 seconds

Paused: 04 | 21.10-00 | 0c 00 | fa 8e (crc=ok) | 2a (ack=ok) 04 | 11.10-01 | 03 00 | d1 6e (crc=ok) | 1a (ack=ok) 05 | 11.10-05 | 00 00 00 | 9e 9c (crc=ok) | 1a (ack=ok) 05 | 11.10-05 | 05 00 78 | 8a f3 (crc=ok) | 1a (ack=ok) 04 | 21.10-02 | 00 78 | 2e 1c (crc=ok) | 2a (ack=ok)

Resumed: 04 | 11.10-01 | 23 00 | d7 88 (crc=ok) | 1a (ack=ok) 04 | 11.10-01 | 24 00 | 4e 1f (crc=ok) | 1a (ack=ok) 04 | 21.10-00 | 2e 00 | 9a 0a (crc=ok) | 2a (ack=ok) 05 | 11.10-05 | 00 04 00 | 52 58 (crc=ok) | 1a (ack=ok) 04 | 11.10-01 | 01 00 | b7 0c (crc=ok) | 1a (ack=ok) 04 | 21.10-00 | 16 00 | 16 36 (crc=ok) | 2a (ack=ok) 03 | 21.10-03 | 0b | 08 73 (crc=ok) | 2a (ack=ok) 05 | 21.10-04 | 05 01 68 | f2 cb (crc=ok) | 2a (ack=ok)

Program “END” (shown on machine display): 03 | 21.10-03 | 05 | e9 bd (crc=ok) | 2a (ack=ok) 04 | 21.10-00 | 17 00 | 25 07 (crc=ok) | 2a (ack=ok) 03 | 21.10-03 | 05 | e9 bd (crc=ok) | 2a (ack=ok) 05 | 21.10-04 | 05 00 00 | 2c 54 (crc=ok) | 2a (ack=ok)

Crease Guard Spin triggered?(not sure this one is correct identification by me): 04 | 21.10-00 | 0c 00 | fa 8e (crc=ok) | 2a (ack=ok)

Door Opened at “END” of program (time now reset on display ready to start new program): 04 | 21.10-00 | 29 03 | 33 fe (crc=ok) | 2a (ack=ok) 04 | 11.10-01 | 03 00 | d1 6e (crc=ok) | 1a (ack=ok) 05 | 11.10-05 | 00 05 00 | 61 69 (crc=ok) | 1a (ack=ok) 09 | 11.10-06 | 09 3c 05 68 06 00 00 | 10 64 (crc=ok) | 1a (ack=ok) 05 | 11.10-05 | 05 01 68 | ab f3 (crc=ok) | 1a (ack=ok) 04 | 21.10-02 | 01 68 | 0f 1c (crc=ok) | 2a (ack=ok) 05 | 11.10-05 | 00 00 00 | 9e 9c (crc=ok) | 1a (ack=ok) 05 | 21.10-04 | 05 01 68 | f2 cb (crc=ok) | 2a (ack=ok)

. . Small thing… When Idle(Program selected, not started) is repeated this on ‘Serial Monitor’: 03 | 0f.e0-00 | 05 | ca a8 (crc=ok) | (ack=err, re-evaluate byte) 1a | (read=timout) Is that normal/correct?

hn commented 6 months ago

Thanks for sharing!

It‘s important to understand the „TC“ byte (the number before the dot, C seems to be always 1 for the dryer and T is the target of the frame). So if you have e.g. „ | 21.10-02 | 00 f0 |“ then something (likely the dryer control unit) sends to the user control panel (T=2) the command 10-02 which makes it display the remaining time of 240s.

And if you press a button on the control panel it usually send one or more frames to the dryer control unit (T=1) to set/start things there.

For the ack=err you mentioned in the last paragraph, I‘ve seen that before. the BSH guys seem to have special ack logic for network (T=0) targets, but that seems to depend on specific models.

I‘ll take a deeper look in some days. Happy hacking :)

freddiebd commented 6 months ago

Starting to understand and I think I have correctly identified each event but will need to test properly when in ESPHome.

Drying Program: 11.10-06 | 01 —> Cotton Cupboard Dry Plus 11.10-06 | 02 —> Cotton Cupboard Dry 11.10-06 | 03 —> Cotton Iron Dry 11.10-06 | 04 —> Sportswear 11.10-06 | 05 —> Towels 11.10-06 | 06 —> Mixed Load 11.10-06 | 07 —> Timed Dry Warm 11.10-06 | 08 —> Timed Dry Cold 11.10-06 | 09 —> Wool Finish 11.10-06 | 10 —> Down Wear 11.10-06 | 11 —> Super Quick 40’ 11.10-06 | 12 —> Shirts 11.10-06 | 13 —> Easy Care Iron Dry 11.10-06 | 14 —> Easy Care Cupboard Dry 11.10-06 | 15 —> Easy Care Cupboard Dry Plus

Play/Pause Button Pressed: 11.10-01 | 23 00 —> Play 11.10-01 | 03 00 —> Pause

Dryer Status Running/Paused/Finished: 21.10-00 | 2e 00 —> Running ? Need to log ?? —> Paused -P- , via Door opened or pause button pressed mid-cycle. Maybe 21.10-02 | 00 78 21.10-00 | 17 00 —> Finished/‘End’

Door Status: 21.10-00 | 29 03 —> Door Open 21.10-00 | 29 06 —> Door Closed

Time Remaining: 21.10-02 | xxxx —> Remaining time in seconds xxxx - (Condition needed? dryer ‘Running’… else show '0' or 'Idle’)

Low Heat/Temperature Feature: 21.10-02 | 32 64 —> Enabled 21.10-02 | 31 38 —> Disabled

Fine Adjust (Dryness) Feature: 21.10-02 | 2d 00 —> Off 21.10-02 | 2e 68 —> Low(+) 21.10-02 | 2f d0 —> Med(++) 21.10-02 | 31 38 —> High(+++)

Now just need to work out the ESPHome YAML somehow...! PS, on my unit the D-Bus traffic goes completely quiet when the rotary dial is set to 'Off', do you see the same?

EDIT: Changed a few identified events in the draft YAML below

freddiebd commented 6 months ago

Here's what I've got so far, need to give it a try to see if anything works! I'm not so confident...

https://github.com/freddiebd/bsh-home-appliances/blob/master/bsh-dbus-wtw85490-draft.yaml

freddiebd commented 5 months ago

I can't get your yaml or even my yaml code to compile due to the error below. Something about 'byte' not being a standard ESPHome component. Do I need an "external_components" here to help?

EDIT: I think this is due to ESPHome not being ready for ESP32-C6. I will pick up a normal ESP32 to try. EDIT2: switching to **uint8_t** worked. Still using ESP32-C6 :) . . /config/esphome/tumble-dryer.yaml: In lambda function: /config/esphome/tumble-dryer.yaml:47:9: error: 'byte' was not declared in this scope; did you mean 'std::byte'? 47 | byte framedata = bytes.data() + i; | ^
| std::byte In file included from /data/cache/platformio/packages/toolchain-riscv32-esp/riscv32-esp-elf/include/c++/12.2.0/bits/stl_algobase.h:61,

hn commented 5 months ago

Try uint8_t instead of byte type.

Analyse the frame data more bit-wise and not byte-wise.

I‘m busy this week, more details next week.

freddiebd commented 5 months ago

Got it to compile and function "perfectly" but the yaml seems a bit over complicated compared to yours. I prefer your method of putting the sensor mappings in the HA sensor filters -map section but I couldn't get that to compile for some reason. It works though! Just need to simplify/optimise before opening pull request...

image

hn commented 5 months ago

Nice :)

Use binary_sensor for boolean states (door, low heat …)

for text sensor maps to work you need to sprintf to buf and publish that buf, see my yaml „case 0x261200“

hn commented 5 months ago

I just pushed https://github.com/hn/bsh-home-appliances/commit/2f9a4f5ea5cbc1a1213bbce4ba3b30346f187e65 which adds an ESPHome BSHDBus external component for better/easier integration.

I suggest to analyze the frames more bit-wise, e.g. for the Low Heat binary_sensor: lambda: return (x[6] >> 2) & 0x01;.

With the new external components, x points to the message data. So if you had framedata[y] in the old poc code, you have to change this to x[y-4].

freddiebd commented 5 months ago

Thanks, will give that a try this weekend.

freddiebd commented 5 months ago

Got a bit stuck trying to use the new external component. How can I publish 3 different cases/data to one sensor?

For example I am currently publishing 'Ready to Start', 'Running' & 'Finished' to sensor 'id: bsh_dryer_status'.

But these messages come from case 0x211000, case 0x111001 & case 0x211004.

hn commented 5 months ago

I suggest to keep the bshdbus sensors as simple as possible, e.g. make them only to reflect the state you see in the frames (binary infos to binary_sensor, numbers to sensor, ...). If you look at the WM14S750 example you see that the lambdas are more or less trivial -- just extracting bits and bytes.

If you need some 'higher level' interpretation you might want to use template sensors and merge all infos according to your needs there.

rlagerweij commented 3 months ago

Did you try sending commands? I would love to be able to start/pause the dying cycle based on current power production from my solar PV

hn commented 3 months ago

@rlagerweij In principle, you can send commands with bsh-dbus-logger.ino.

It is difficult to say whether you can really control the home appliance properly with it. My impression is that the D-Bus was added to BSH devices later as an evolution, most of the control and status in the device is done internally by the 'traditional' system parts. If you send control commands via the bus, it is possible that the traditional parts may end up in an inconsistent status (example: if you send the command to set the temperature to the control unit, the user control panel will likely not realize this and will not display the correct temperature). But this is all pure guesswork.

hn commented 1 week ago

Please see https://github.com/hn/bsh-home-appliances/blob/master/contrib/bsh-dbus-wt47r440.yaml, contributed by @stefanhirt