Jutta-Proto / protocol-bt-cpp

C++ JURA protocol implementation for controlling a Jura coffee maker over a Bluetooth connection.
GNU General Public License v3.0
45 stars 3 forks source link

Control Coffee Machine only with Bluetooth in Raspberry Pi #6

Open franfrancisco9 opened 1 year ago

franfrancisco9 commented 1 year ago

I am trying to implement a similar system to the one you have in another repository where we have a Raspbeery Pi and a RFID payment system. My question is if there is a way to not use UART and only use Bluetooth. Could the Barista mode help? I am yet to fully understand that mode and how to interact with it. I am able to brew coffee and detect when someone orders a new one, but I would need a way to make the coffee machine wait for the confirmation of payment from the Raspbeery Pi. I thought about just cancelling the coffe if possible and then order the coffee from the Pi but that does not show anything on the screen. Thank you in advance!

COM8 commented 1 year ago

The code in this repo only uses the BT connection. The JURA BT dongle then translates the BT commands to serial commands for interacting with the coffee maker. There is no way around this.

By now I also did not find a way to disable input send to the coffee maker. There is the "Debug mode on" when you send FN:89 via TX BT characteristic to the coffee maker. But to get out of it, you have to unplug the coffee maker from power and plug it in again. At one point I was able to get out of this mode by sending FN:90 to the coffee maker but it's not working reliably.

Barista mode would be an option, but sadly I also currently struggling to understand how it works in a model independent way.

Feel free to let me know when you find something out. Also we can include a link to your repo in the readme in case someone else has the same use case :)

franfrancisco9 commented 1 year ago

Thank you for the information, I have not really tried the TX characteristic, so I will take a better look and try a few things. What happens when you are in debug? If I find anything that works or about the Barista mode I will let you know! I will get a repo going in a few days when I clean everything and will send it here! Also if possible could you show me how you encoded the command "FN:89" to the TX characteristic?

COM8 commented 1 year ago

Once in debug mode, there are no button presses allowed any more. Once a button gets pressed, the coffee maker sends the button ID as serial output.

franfrancisco9 commented 1 year ago

Hello again, I have been trying to send a command to the RX characteristic and then read the response in the TX characteristic but I do not think I am doing it well since not even TY: is returning the expected result. Does the RX command also have to be encoded as it would have in UART? Or should I just do the normal encoding used in bluetooth? I tried to send f460bdcda610353c which is "TY:" (54 59 3a 5c 72 5c 6e) encoded with my key 6e. Could you show me how you sent the FN:89 as an example over bluetooth? Thank you in advance

COM8 commented 1 year ago

You mean, you are writing to TX and reading from RX. As far as I understand all commands get forwarded to the coffee maker directly so yes you have to obfuscate them as described here .

I will quickly try to send FN:89

franfrancisco9 commented 1 year ago

That makes sense, thank you. I will add the obfuscation process and see if I can get it to work.

COM8 commented 1 year ago

Jup, it's just following the obfuscated process.

franfrancisco9 commented 1 year ago

I was able to convert your obfuscation and de obfuscation to python and it works all well but I do not seem to be able to send it with bluetooth to TX. Just to confirm the TY:\r\n becomes:

5b5f5f5f 5f7b5f5f 7b7b7f5b 5f7f5b5b

Which I should send encoded with the bluetooth key seperatly with a 8ms delay? I get disconnected when I do that.

COM8 commented 1 year ago

I will send you an example next week once I'm back working on the coffee maker again.

You get disconnected since you probably are not sending a heat beat on a regular basis: https://github.com/Jutta-Proto/protocol-bt-cpp#heartbeat

franfrancisco9 commented 1 year ago

Alright thank you! I will create the repo today so I can also show you better where things go wrong, I have the heartbeat running well, and I have since been able to fix the disconnection it happened because right after I sent the TX command I tried to read from machine status. However, when I read from RX so far I have not gotten any reply but I think it might be due to the time I take to read.

franfrancisco9 commented 1 year ago

Also my repo https://github.com/franfrancisco9/Jura-Python-BT. Very messy for now

COM8 commented 1 year ago

Thanks for sharing your repo. Looks like sending is now somehow broken.

I can send data to the coffee maker via the tx characteristic, but I'm not sure whether it arrives at the coffee maker. I'd say the issue is, that the dongle applies the second level encryption to everything send via the tx characteristic. This results in the coffee maker not understanding all those basic commands detailed here.

This is the handshake done between coffee maker and dongle once connected. I'm currently looking into snooping the traffic between coffee maker and dongle but for this I had to order a new Raspberry Pi power supply.

Reading on the other hand works (if I do not read to fast via the rx characteristic). For this I just have to decode data as for all other encoded BT characteristics.

franfrancisco9 commented 1 year ago

Thank you for all the feedback. Reading is also working well for me now! Since the dongle might be applying the second level encryption, shouldn't we be able to just send letter by letter and let the dongle handle the encryption? I will do more tests regarding sending commands, if I am able to achieve any with success I will update here.

franfrancisco9 commented 1 year ago

Also, just to let you know in the README file I believe the Tx and Rxto be switched (the uuids).

franfrancisco9 commented 1 year ago

Have you tried to enter Incasso mode through bluetooth? The mode makes the machine wait for the Raspberry permission to do coffee, could it be done with bluetooth? If so, when someone clicked to get a coffee we would get that information in RX and be able to send the request from start product. I am not really sure what the code for that mode is though, from looking at the machine files so far I seem to be missing something.

COM8 commented 1 year ago

Found a far better way! You can lock and then unlock the screen and all buttons via BT. I documented my findings here: https://github.com/Jutta-Proto/protocol-bt-cpp#barista-mode

franfrancisco9 commented 1 year ago

Wow! That's amazing! That way the user just authenticates you unlock the machine the user makes the coffee, you can detect what coffee was made and then charge the user and relock the machine! I will certainly use that 👍

COM8 commented 1 year ago

Yes exactly!

The product then can be detected via a statistics change: https://github.com/Jutta-Proto/protocol-bt-cpp/pull/5 Better docs for it will follow.

franfrancisco9 commented 1 year ago

Works like a charm! I am yet to connect with the rfid reader, but I can lock the machine, order a coffee, see the statistics change and unlock easily. You can even detect with the alerts if the screen is locked or not.

COM8 commented 1 year ago

Yes, I also noticed the part with the alerts. This is really useful.

franfrancisco9 commented 1 year ago

After some tests I found that the characteristic of product progress is much more efficient than the statistics. With the product progress I can detect as soon as a product starts and the moment it ends: Example with key = "2a" after decoding that data from product progress in an hex array:

if data[1] not in [b"e1", b"ac"]:
    product_made = in_machine_products[int(as_hex[2])]
    print("Product made was: ", product_made)
    started =1
elif started == 1 and data[1] in [b"e1", b"ac"]:
    print("Product ended")

The in_machine_products is a dictionary with the numbers to products correspondence from the machine files. In my repo will be the full code. Like this you can easily lock the machine as soon as a product as started, detect the product, charge the user and relock the machine. And it is instanteous the detection. My problem with the statistics was that it took a few seconds to detect a change after the end allowing for a user to make more than one product.