Home Assistant custom integration for DeLonghi PrimaDonna Soul and other Ayla-based DeLonghi coffee machines, controlled through the Coffee Link cloud.
Any DeLonghi coffee machine exposed by the Coffee Link mobile app through Ayla Networks IoT. Confirmed working:
- PrimaDonna Soul ECAM610.xx, ECAM612.xx, ECAM613.xx (
oem_model = DL-millcore) - works out of the box. - Eletta Explore ECAM45x.xx (
oem_model = DL-striker-cb) - beverages and power-on confirmed working; needs a one-time "teach from the app" step per drink (see Eletta Explore below). - Other Coffee Link Wi-Fi machines may work; the same teach-from-app mechanism applies.
- 21 beverage buttons (Espresso, Cappuccino, Latte Macchiato, Hot Water, Tea, etc.)
- Wake and Standby buttons (power the machine on / off remotely)
- Counters sensors (total beverages, per-drink counters, descale status)
- Machine Status (standby, ready, rinsing, dispensing...) and Connection Status sensors, plus Last Connected - when the machine established its current cloud connection
- Generic Stop button
- Services for raw binary command injection (advanced use)
The cloud accepts a command for a machine that is offline and answers 200 OK;
the machine simply never receives it. So when the cloud reports your machine as
offline, commands are refused with a clear error instead of being written
into the void - check that the machine is powered at the mains and joined to
Wi-Fi. Connection Status tells you how the cloud sees it right now, and Last
Connected when it last established that connection. A machine merely in standby
stays online and can still be woken, and send_raw_command is never blocked so
you can always poke a machine by hand.
The PrimaDonna Soul this integration was built on uses a fixed beverage command. The Eletta Explore (oem_model = DL-striker-cb) - and likely other non-Soul models - uses a different, variable-length command (the recipe, quantity, intensity and milk are all encoded in the bytes, and the frame carries a per-device signature). Rather than guess those bytes, the integration learns the exact command your machine's official app sends and replays it - which is reliable by construction.
So on an Eletta Explore there is a one-time teach step, after which everything works from Home Assistant (and is remembered across restarts):
Beverages
- Make sure Home Assistant is running and the machine is online.
- Start each drink once from the official Coffee Link app. Home Assistant captures the exact bytes (you can confirm on the Last Captured Command diagnostic sensor:
style: eletta,crc_valid: true). - From then on, the matching Home Assistant button (or
start_beverageservice) brews that drink.
Power-on (Wake)
- With Home Assistant running, power the machine on once from the official app.
- From then on the Wake button powers it from standby.
Power-off (Standby)
The official app has no power-off control, so this frame is always synthesized
(84 0f, params 01 01 - validated live on the reference Soul). On Eletta-style
models it needs the per-device signature, which is taken from any frame already
learned (e.g. the wake frame) - so once the Wake teach step above is done, the
Standby button works too.
If you change a drink's settings in the app (e.g. quantity), start it once more from the app so Home Assistant re-learns the new bytes.
Why the teach step also unlocks the cloud session. ECAM machines only obey commands sent inside a cloud session registered with their own 4-byte device signature - the one they append to every frame. That signature is read from the first frame you teach, so before any teach step the machine may accept a command (HTTP 200, valid CRC,
machine_status: ready) and simply do nothing. TheCloud Session app_iddiagnostic sensor shows which id is in use through itssession_id_sourceattribute (device_signatureonce taught,default_constantbefore). See issue #15.
A read-only Dump Recipe Datapoints diagnostic button is also provided; it logs the recipe definitions the machine stores (it sends nothing to the machine). See issue #1 for the reverse-engineering details.
The machine prioritizes LAN connections over cloud. As long as the Coffee Link mobile app is running on a phone on the same Wi-Fi network, it holds a LAN session (30s keep-alive) and the machine ignores cloud commands.
Close the Coffee Link app completely (swipe from recents) before using Home Assistant. If you want to regain control from the app, just reopen it.
A future version of this integration will include a local LAN server to bypass this limitation.
One-click install - click the badge below (requires HACS already installed in your HA) :
Or manually :
- In HACS, click the 3-dots menu > Custom repositories
- Add
https://github.com/actabi/delonghi_coffeelinkas category Integration - Install "De'Longhi Coffee Link"
- Restart Home Assistant
- Click this badge to add the integration :
- Enter your Coffee Link email and password (same as the mobile app)
- Copy
custom_components/delonghi_coffeelink/to your HAconfig/custom_components/ - Restart Home Assistant
- Add integration via Settings > Devices & Services
# Start a beverage
service: delonghi_coffeelink.start_beverage
data:
beverage: hot_water # espresso, cappuccino, latte_macchiato, etc.
# Stop a beverage
service: delonghi_coffeelink.stop_beverage
data:
beverage: hot_water
# Send a raw binary command (advanced)
service: delonghi_coffeelink.send_raw_command
data:
value_base64: DQ2D8BABDwD6GwEGgSRp6MygThis integration implements the Coffee Link authentication and command protocol:
- Authenticate to Gigya (SAP Customer Data Cloud) identity service
- Request a signed JWT (HMAC-SHA1 over the Gigya session)
- Exchange the JWT for an Ayla Networks SSO token
- Poll Ayla Networks IoT cloud for 312 device properties
- Send binary commands via the
data_requestproperty (base64-encoded)
Beverage command format - PrimaDonna Soul (fixed 18 bytes):
byte 0-1 : 0x0d 0x0d prefix + length
byte 2-3 : 0x83 0xf0 command family: beverage
byte 4 : beverage_id 0x01 = espresso, 0x10 = hot water, etc.
byte 5 : action 0x01 = start, 0x02 = stop
byte 6-11 : recipe params temperature, quantity, aroma
byte 12-13 : CRC16 AUG-CCITT over bytes 0..11
byte 14-17 : Unix timestamp (big-endian)
Eletta Explore (DL-striker-cb) uses a variable-length frame: the same 0x83 0xf0 <bev> <action> header, then a variable recipe block (quantity in ml, intensity and milk encoded inline), the same CRC16 AUG-CCITT (over the whole frame before the CRC), the timestamp, and a 4-byte per-device signature. Because the recipe layout varies, the integration does not synthesize this frame; it replays the exact frame captured from the official app (see Eletta Explore). The power-on frame uses family 0x84 0x0f and is handled the same way.
If commands are accepted by the cloud (no error) but your machine does nothing
- common on models other than the PrimaDonna Soul this was built on - the integration can capture the exact bytes the official Coffee Link app sends, so they can be compared to what it generates.
Each device has a diagnostic sensor Last Captured Command
(sensor.<machine>_last_captured_command). To use it:
- Make sure the integration is running and the device is online.
- Open the official Coffee Link app and start a beverage (e.g. an espresso).
- Within one polling cycle (~30 s), open Developer Tools -> States and look
at
sensor.<machine>_last_captured_command.- State = the app's raw base64 command.
- Attributes decode it:
origin(appvsintegration),beverage_name,params,crc_valid, andmatches_integration.
matches_integration: truemeans the integration generates the same bytes as the app (so any "machine ignores it" issue is environmental - e.g. the app holding the local session, see the note above).matches_integration: falsemeans the app uses different bytes - paste this sensor's attributes into a GitHub issue and the command builder can be corrected for your model.
App-originated captures are also logged (enable debug logging for
custom_components.delonghi_coffeelink) as CAPTURED app->machine command ....
Your machine isn't a PrimaDonna Soul or an Eletta Explore? It very likely already works. Unknown models default to the learn-and-replay path: trigger each drink (and power-on) once from the official Coffee Link app, Home Assistant captures the exact bytes and replays them (see Eletta Explore for the procedure). That works on any Coffee Link machine without any code change.
If you'd like first-class support for your model (so it's recognised by name, and so we can document/optimise it), open an issue with the data below. Everything needed is already exposed by the integration's diagnostics - no network sniffing, no rooting, just copy/paste.
1. Identify the machine
- Commercial name + full reference under the machine (e.g.
Maestosa ECAM650.85.MS). - Coffee Link account region (EU / US).
- The
oem_modelandsw_version: enable debug logging forcustom_components.delonghi_coffeelink, restart, and copy theDiscovered DeLonghi device:log line.
2. What the official app sends (the ground truth we replay)
For each drink you care about, start it from the official app with Home Assistant running, then copy the Attributes of the ...Last Captured Command sensor (Developer Tools → States). Do the same for power-on. Each block shows style, beverage_id, the full recipe/hex, crc_valid, and the device signature - exactly what's needed.
3. The recipes the machine stores (for the optional "zero-touch" path) Press the Dump Recipe Datapoints diagnostic button and paste the logged block (it's read-only - it sends nothing to the machine).
4. Does it work after teaching? Tell us whether the Home Assistant buttons brew/power the machine after you've triggered them once from the app (yes/no per drink, and whether the machine was already on or in standby).
With that, adding first-class support is usually just a new ModelProfile subclass in model_profiles.py (detection rule + whether it learns from the app) - nothing else in the integration needs to change. The Eletta Explore reverse-engineering, captured frame-by-frame this way, is tracked in issue #1 as a worked example.
- Reverse engineering of Coffee Link auth & protocol: @actabi (2026)
- Based on the Ayla Networks LAN protocol research from jakecrowley/AylaLocalAPI
- DeLonghi BLE protocol research from Arbuzov/home_assistant_delonghi_primadonna
This is an unofficial integration. De'Longhi and Ayla Networks may change the protocol at any time. Use at your own risk.
MIT