Dishwasher - Candy simply FI - CDI 6015 WiFi

I’ve found the way to retrieve the KEY and decode all request and response! as soon as possible I will share the list of requests for all washer-dryer programs

2 Likes

Good job Paolinho! I am waiting for the good news!

These 404 errors are coming from an invalid link. Check api/v1//api/v1.
It has to be /api/v1/ only once…

I´ve got a used Hoover-Candy Washer, which is already registered in any account, so I cannot register it on the herokuapp-Server anymore. However, it is a machine with wifi-initial-setup. I sniffed the communication between app an washer during the setup. It is encrypted already with an initial-key like: http://192.168.1.x/http-config.json?encrypted=1&data=xxxxxxxxxxxxx (many hexadedimal bytes). I decoded these bytes using a known plaintext attack (knowing that ssid an password had to be in there). Now I have the new encryption key. More tests later…

This is what I got:
statusLavatrice":{
“WiFiStatus”:“1”,
“Err”:“255”,
“MachMd”:“1”,
“Pr”:“9”,
“PrPh”:“0”,
“SLevel”:“2”,
“Temp”:“90”,
“SpinSp”:“4”,
“Opt1”:“0”,
“Opt2”:“0”,
“Opt3”:“0”,
“Opt4”:“0”,
“Opt5”:“0”,
“Opt6”:“0”,
“Opt7”:“0”,
“Opt8”:“0”,
“Steam”:“0”,
“DryT”:“0”,
“DelVal”:“255”,
“RemTime”:“136”,
“RecipeId”:“0”,
“CheckUpState”:“0”
}
Should be enough to find a key :wink:

Hi guys. Amazing job. I do not yet own a Candy branded device but the progress here would heavily influence my purchase decision (dishwasher + washing machine)
Also I wonder if they’re any good :sweat_smile: beyond the wifi part.

Anyway hoping to see if there was any updates since the last post in June. Thanks!

1 Like

Hi, could you tell me step by step the process for getting this data, please?

Thanks.

Is your machine already registered in the app? Do you know your IP-Adress? If it is, first of all do;

http://ip_of_the_machine/http-read.json?encrypted=1
then you will get the encrypted data. With this you can search in it with any tool for known-plaintext-attacks for any word I posted (“CheckUpState” / “WiFiStatus” / …), knowing that the key-length is 16. If you dont find a tool, you can post the encrypted data here, I can try to help.

Ok, thanks!!
I will try later. If I have any problem I will ask you again.

ok. I used a python script called xorknown.py on my linux machine. And remember: your encrypted data is hexadecimal, you have to convert it to ascii first, then use the tool. You will get the complete output and the key to decrypt it easier next time :wink:

Here’s what I did:

  • Download the decrypt script: curl -SLO https://raw.githubusercontent.com/Alamot/code-snippets/master/crypto/xorknown.py
  • Make it executable: chmod +x ./xorknown.py
  • Get encrypted data and convert to ascii: curl -s http://[APPLIANCE-IP]/http-read.json?encrypted=1 | xxd -r -p > ./crypted.txt
  • Decrypt data: ./xorknown.py ./crypted.txt '{"status' 16

The script will return partially decrypted data, go on adding known text to improve it.
Problem is that the API returns its data localized. Because of this you can not always use the same string.
I had to use '{"statusHob":{"S as complete string since I own an induction hob and the first field of the object was not WiFiStatus but StatoWiFi.

The complete result is:

{
  "statusHob": {
    "StatoWiFi": "1",
    "Z1status": "0",
    "Z1pan": "0",
    "Z1hot": "0",
    "Z1combi": "0",
    "Z1low": "0",
    "Z1power": "0",
    "Z1error": "00",
    "Z1timeh": "0",
    "Z1timem": "0",
    "Z2status": "0",
    "Z2pan": "0",
    "Z2hot": "0",
    "Z2combi": "0",
    "Z2low": "0",
    "Z2power": "0",
    "Z2error": "00",
    "Z2timeh": "0",
    "Z2timem": "0",
    "Z3status": "0",
    "Z3pan": "0",
    "Z3hot": "0",
    "Z3combi": "0",
    "Z3low": "0",
    "Z3power": "0",
    "Z3error": "00",
    "Z3timeh": "0",
    "Z3timem": "0",
    "Z4status": "1",
    "Z4pan": "1",
    "Z4hot": "0",
    "Z4combi": "0",
    "Z4low": "0",
    "Z4power": "1",
    "Z4error": "00",
    "Z4timeh": "7",
    "Z4timem": "59",
    "lock": "0",
    "alarmh": "0",
    "alarmm": "0"
  }
}
3 Likes

Ok, here are the strings to use for each appliance:

  • '{"statusHob":{"StatoWiFi' for hob
  • '{"statusDWash":{"StatoWiFi' for dishwasher
  • '{"statusLavatrice":{"WiFiStatus' for washing mashine
  • '{"statusTD":{"StatoWiFi' for tumble dryer
  • '{"statusRefrigerator":{"WiFi' for fridge
  • '{"StatusHood":{"WiFiStatus' for hood
  • '{"statusForno":{"StatoWiFi' for hoven
1 Like

This is awesome. How would I get this info in to HA? Could I use some plugin to pull the info in?

No, there’s no plugin at the moment. I ended up using a command line sensor to fetch and decrypt the information and then a bunch of template sensors to split the values into some entities

Do you own a washing machine too? Since I can`t register my machine to the server, I cannot use the app. It would be nice to know, what we can do with the machine over wifi (start / stop …), but without the app I cannot sniff the communication…

No, I’m sorry

could you share the command line sensor and the template sensors? I have a dishwasher and i would like to know only when it is working

Once you’ve found the key the sensor is quite simple:

  - platform: command_line
    name: Induzione
    scan_interval: 30
    command: 'xortool-xor -h $(curl -sf http://PianoInduzione/http-read.json?encrypted=1") -s [KEY] | jq -cerM .statusHob'
    value_template: "{% if value_json.StatoWiFi | int == 1 -%}on{%- else -%}off{% endif %}"

In the command I read the encrypted JSON value from the hob and pass it to xortool-xor to have a plain JSON.
Then it’s just a matter of mapping the available fields to the sensor json_attributes and use them via template sensors.

2 Likes

I have a Hoover whashing dryer
I’ve got as far as here. I have the KEY and the phrase but I cannot get to work your example code on HA on Raspberry Pi4.
Should I first somehow install xortool or it is already present within HA?
What are the parts to be changed (IP, [KEY], .statusHob’) ?
Thanks in advance for your help

xortool-xor is not part of Home Assistant and needs to be installed on the system. Obviously .statusHob is specific to my case since I own an hob. Remove the jq part, check your json output and filter it accordingly using jq. It’s just a way to avoid extra parsing in the sensor