Nespresso Expert machine has the Bluetooth ability which officially can be used only by Nespresso mobile app and it does not offer any API for 3rd party applications and services. Moreover, the Bluetooth services and characteristics are not documented and easy to use by the other Bluetooth libraries plus there is no documentation for the Bluetooth packets payload that need to be sent or received.
However, after searching a lot and sniffing the packets for a couple of days, I've been able to hack the machine and write the small nodejs application using noble and express to control and monitor the machine with Rest API exposed by express through Bluetooth connection. As I did this application for my ex-company and they are still using it for their demo I cannot share the code but I'm going to explain how it works.
Thanks to this repo: https://github.com/fsalomon/nespresso-expert-ble and also this nice medium post https://medium.com/@urish/reverse-engineering-a-bluetooth-lightbulb-56580fcb7546 that basically helped me to understand how I need to sniff the packets.
first I have installed the Nespresso app on my mobile and I connected to the machine and used the application. Then, using the post I mentioned above, I sniffed the packets and opened them in the Wireshark to analyze them.
I notice that everytime on the app we start communicating with the machine (brew or monitor or just oppening machine tab) it starts the conversation with a packet that has "8" at the start of its value and has 16 characters (mine was 85c55bc324a4170b) and it is writting on the 4th characteristic of the service 06aa1910f22a11e39daa0002a5d5c51b. note: only one mobile can connect to the expert machine and everytime that new mobile connects (which needs the device reset) the authentication packet will change.
I have used noble library for ble communication. I mention some hints ;)
Authentication will be done by writing to 4th characteristic of the first service Buffer.from("85c55bc324a4170b", "hex")
. after writing when you read the 5th characteristic, the data should be "2" which means authenticaton was successful.
I don't know why, and dont ask me please but before sending the brew command you need to write this Buffer.from("01100800000200c8000000", "hex")
on the 4th charac of the second service ("06aa1920f22a11e39daa0002a5d5c51b") and then inside the callback, you write this Buffer.from("03050704000000000101", "hex")
which is low temp espresso.
Now you machine should start brewing... yayyyy
below I leave all of my notes in case it can be useful
Here are my observations:
0305070400000000 00 00
medium ristretto0305070400000000 01 01
low espresso0305070400000000 02 02
high lungo0305070400000000 01 04
low hot water0305070400000000 01 05
low americano0305070400000000 01 07
low probably cleaning mode (all lights turning on together)03060102
would stop the brewing (not always)
On the second service, on 0th charac read normally is like 0:64 1:9 2:13 3:64 4:128 5:0 6:255 7:255
.
- 0: 64 is ok, 65: no water
- 1: 64 with 132 is brewing or busy , 64 with 2 ready , 64 with 66/67/7x :full disposal or no disposal
on second service, on 4th charac read normally is like:
0:129 1:16 2:1 3:32 4:0 5:0 6:0 7:0 8:0 9:0 10:0 11:0 12:0 13:0 14:0 15:0 16:0 17:0 18:0 19:0
For understanding slide error, read should be done after command of brew
- 1: 195 slider error, 129 ok, 131 busy brewing
Since
btsnooz.py
would always give me a pcap file with malformed/too short packets I took a look at the Nespresso android app and it was fairly easy to extract the pairing key code stuff, so I thought I'd share it here if someone else stumbles on this gist :)This is how it looks in Wireshark with malformed packets,
To get the current pairing code you'll need a rooted android device so you can access the Nespresso app database file. it will also work with an android device that has TWRP recovery mode, so you can mount the filesystem in recovery mode and get the database file. If you don't have access to a rooted android device you can factory reset the machine, generate a new pairing key and use that for pairing.
To get the current pairing key from a rooted android device:
The key needs to be transformed to a format that the Nespresso machine accepts, this can be done with this java program,
This java program can also generate a new pairing key, just save it as
pairing_key.java
and you can run it with#> java pairing_key.java 92d51b90e2bea6cd77f3fd7107907e2c New pairing key: d1e357a7c12f17615126e88445ef9c1b New pairing key hex: 8D1E357A7C12F176 Current key: 92d51b90e2bea6cd77f3fd7107907e2c Current key hex: 892D51B90E2BEA6C
Now good luck with hacking on your Nespresso machine :)