Controlling Delonghi Primadonna Elite through ST

Hey guys,

As mentioned earlier in this thread, here are the service and characteristic that you need to scan and read from:

const SERVICE = "00035b03-58e6-07dd-021a-08123a000300";
const CHARACTERISTIC = "00035b03-58e6-07dd-021a-08123a000301";

Note that you need to enable both notifications and indications for the characteristic, before writing to it.

Here are the commands I managed to intercept so far (I am using a JSON format as an example):

{
  "turn_on":                                ["0d 07 84 0f 02 01 55 12",
                                             "0d 07 84 0f 02 01 55 12",
                                             "0d 07 84 0f 02 01 55 12",
                                             "0d 07 84 0f 02 01 55 12",
                                             "0d 07 84 0f 02 01 55 12",
                                             "0d 07 84 0f 02 01 55 12"],
  "health_check":                           ["0d 05 75 0f da 25"],
  "machine_status":                         ["0d 08 95 0f 00 32 01 5d df", "0d 08 95 0f 00 3f 01 2b 83"],


  "settings_cup_lighting_on":               ["0d 0b 90 0f 00 3f 00 00 00 99 39 22"],
  "settings_cup_lighting_off":              ["0d 0b 90 0f 00 3f 00 00 00 91 b8 2a"],
  "settings_cup_warmer_on":                 ["0d 0b 90 0f 00 3f 00 00 00 b1 9c 48"],
  "settings_cup_warmer_off":                ["0d 0b 90 0f 00 3f 00 00 00 91 b8 2a"],
  "settings_energy_saving_on":              ["0d 0b 90 0f 00 3f 00 00 00 91 b8 2a"],
  "settings_energy_saving_off":             ["0d 0b 90 0f 00 3f 00 00 00 81 aa 1b"],
  "settings_beep_sound_on":                 ["0d 0b 90 0f 00 3f 00 00 00 91 b8 2a"],
  "settings_beep_sound_off":                ["0d 0b 90 0f 00 3f 00 00 00 95 f8 ae"],
  "settings_show_time":                     ["0d 08 95 0f 00 5f 03 00 eb"],
  "settings_water_hardness_1":              ["0d 0b 90 0f 00 32 00 00 00 00 0a c8"],
  "settings_water_hardness_2":              ["0d 0b 90 0f 00 32 00 00 00 02 2a 8a"],
  "settings_water_hardness_3":              ["0d 0b 90 0f 00 32 00 00 00 02 2a 8a"],
  "settings_water_hardness_4":              ["0d 0b 90 0f 00 32 00 00 00 03 3a ab"],

  "beverages_setting_a1_q20_t1":            ["0d 11 83 f0 01 00 01 00 14 02 01 08 00 00 00 05 bb fd"],
  "beverages_setting_a2_q20_t1":            ["0d 11 83 f0 01 00 01 00 14 02 02 08 00 00 00 05 75 1d"],
  "beverages_setting_a3_q20_t1":            ["0d 11 83 f0 01 00 01 00 14 02 03 08 00 00 00 05 30 bd"],
  "beverages_setting_a4_q20_t1":            ["0d 11 83 f0 01 00 01 00 14 02 04 08 00 00 00 05 f8 fc"],
  "beverages_setting_a5_q20_t1":            ["0d 11 83 f0 01 00 01 00 14 02 05 08 00 00 00 05 bd 5c"],
  
  "beverages_setting_a2_q40_t2":            ["0d 11 83 f0 01 00 01 00 28 02 02 08 00 00 00 05 22 76"],
  
  "beverage_espresso_1_a1_q20_t1":          ["0d 11 83 f0 01 01 01 00 14 02 01 08 00 00 00 06 53 d7",     "0d 08 83 f0 01 02 06 9d e1"],

  "beverage_espresso_1_a2_q40_t2":          ["0d 11 83 f0 01 01 01 00 28 02 02 08 00 00 00 06 ca 5c",     "0d 08 83 f0 01 02 06 9d e1"],
  "beverage_espresso_1_a3_q40_t2":          ["0d 11 83 f0 01 01 01 00 28 02 03 08 00 00 00 06 8f fc",     "0d 08 83 f0 01 02 06 9d e1"],
  "beverage_espresso_2":                    ["0d 11 83 f0 01 01 01 00 28 02 03 08 01 00 00 06 f9 48",     "0d 08 83 f0 01 02 06 9d e1"],
  "beverage_coffee":                        ["0d 0f 83 f0 02 01 01 00 67 02 02 00 00 06 77 ff",           "0d 08 83 f0 02 02 06 c4 b1"],
  "beverage_doppio_plus":                   ["0d 0d 83 f0 05 01 01 00 78 00 00 06 c4 7e",                 "0d 08 83 f0 05 02 06 41 21"],
  "beverage_steam":                         ["0d 0d 83 f0 11 01 09 03 84 1c 01 06 c0 7b",                 "0d 08 83 f0 11 02 06 de 82"],
  "beverage_hot_water":                     ["0d 0d 83 f0 10 01 0f 00 fa 1c 01 06 04 b4",                 "0d 08 83 f0 10 02 06 e9 b2"],
  "beverage_2_espressos":                   ["0d 0f 83 f0 04 01 01 00 28 02 02 00 00 06 ab 53",           "0d 08 83 f0 04 02 06 76 11"],
  "beverage_americano":                     ["0d 12 83 f0 06 01 01 00 28 02 03 0f 00 6e 00 00 06 47 8b",  "0d 08 83 f0 06 02 06 18 71"],
  "beverage_coffee_long":                   ["0d 0f 83 f0 03 01 01 00 a0 02 03 00 00 06 18 7f",           "0d 08 83 f0 03 02 06 f3 81"],
}

NOTES:
The packets are sent by chunks (each entry in the arrays above corresponds to one chunck). For example, the turn_on commands need to send 6 times the following packet: “0d 07 84 0f 02 01 55 12”.

For the machine_status, we need to send “0d 08 95 0f 00 32 01 5d df” followed by “0d 08 95 0f 00 3f 01 2b 83”.

Explanation about the arbitrary beverage naming I am using above (ie. beverage_espresso_1_a3_q40_t2):

  • a is for Aroma: 5 levels
  • q is for quantity: from 20 to 120ml
  • t is for temperature: 4 levels
  • espresso_1 is one cup of espresso
  • espresso_2 is two cups of espresso

I still need to figure all the other combinations! I am just short on time :sweat_smile:

Also, sending commands to the machine should be easy to do now. However, I am still figuring out the correct protocol that the machine is using. I am looking into decoding the responses coming from the machine. But it’s a little bit challenging, since De’longhi seems to be using a proprietary protocol. But I am working on it :slight_smile:

I will keep you updated here once I have more news!

Cheers.

1 Like

@manekinekko

wow that’s a neat work. thanks.

I have a few questions:

  1. what is health check ? is it useful ?
  2. what is “machine_status” ? can we get statistics with this command ?
  3. about power on ; I just use "0d07840f02015512 " once and it works all the time.
    but you say we need to send it 6 times. why do you think so ?
  4. is there a correlation between t1-t4 and the hex codes ? so for example how can we change beverages_setting_a1_q20_t1 to beverages_setting_a1_q20_t2 ?
  5. I understand that 9th byte is for quantity (q) , is that correct ?
  6. I also see that 11th byte is for aroma level (a) , is it ?
  7. is the 13th byte for setting 2 cups ? (00 means 1 cup, 01 means 2 cups ) ?
  8. how the beverage_2_espressos and beverage_espresso_2 differs ?

Hi. Here are my assumptions (I am still trying to figure out the protocol)…

  1. the health check ping is done by the mobile app to maintain a connection with the machine, and disconnect the app if the machine is not reachable anymore. These packets are sent every 5 seconds. This is also used to monitor the status of the machine. After each ping, the machine responds with 19 bytes packets which look like this: d0 12 75 0f 01 05 00 08 00 07 00 00 00 00 00 00 00 d7 2a

De’Longhi seems to use a proprietary protocol to decode these packets. I managed to extract this information (half decoded) from the assembly code:

    MonitorDataV2:
      - AccessoryPresent      = 1
      - ActiveAlarms          = 3
      - BeverageType          = undefined
      - CoffeeInfuserPos      = 0
      - CoffeePowderQty       = -1
      - CoffeeWasteCounter    = undefined
      - DispensingPercentage  = 0
      - FunctionOngoing       = 7
      - HeaterTemp            = undefined
      - MachineModelId        = -1
      - MainBoardSwRelease    = 0
      - OnLoads               = 
      - OnSwitches            = 0,2
      - OnSwitchesToShowUser  = 
      - PressedKeys           = 
      - RequestedWaterQty     = -1
      - SteamerTemp           = undefined
      - Timestamp             = undefined
      - Type                  = 2
      - WaterFlowQty          = 10752
  1. The machine status packets are used to retrieve Parameters from the machine, which the app would use to trigger other commands (like reading the serial number, model, etc…). I guess these values are also used for the settings. I managed to decode some parts of these Parameter. The 12 bytes packets sent by the machines look like this: d0 0b 95 0f 00 3f 00 00 00 9d bb 9b
    Parameter:
      - Index             = 63
      - Value             = 0,0,0,-99
      - CountryType       = -1
      - SelectedLanguage  = -1
      - AutoOffOn         = false
      - AutoStartOn       = false
      - BuzzerOn          = true
      - CupLightOn        = true
      - CupWarmerOn       = true
      - EnergySaving      = true
      - FilterOn          = true
      - FirstStartEnabled = false
      - LanguageSet       = false
      - TimeSet24hFormat  = true
      - WriteDone         = true
  1. The mobile app does send 6 times the tun on packet. I suspect it’s because to make sure the machine receives the turn on command (BLE is not really reliable).

  2. I am still in the process of mapping all the different combinations for beverages (aroma, qty, temperature, water, milk). After which I would be able to figure the correct packets. But for the beverages_setting_aXX_qYY_t1, it seems that the 11th byte controls the aroma level and the 9th controls the quantity: 0d 11 83 f0 01 00 01 00 YY 02 XX 08 00 00 00 05 bb fd

  3. Yes

  4. Yes

  5. I need to finish the mapping and figure this out.

  6. In the ECAM65075MS machine menu, these are two different beverage IDs. beverage_2_espressos will automatically serves 2 espresso cups (in one command). beverage_espresso_2_XXYY would split 1 espresso across 2 different cups. I think that is why they have different commands.

Cheers.

1 Like

please also let us know if you find how to read stats from the machine (how many beverages made so far etc.)

Sure buddy :wink:

Hey,

If you guys want to contribute to the project, I pushed my work in progress code on my GitHub: https://github.com/manekinekko/cafy

Join me and let’s try to decode the protocol together :wink: