Enhanced Bluetooth LE support

I see you've started to incorporate BLE support. Wondering if you can add basic Bluetooth LE support for actual interactions. Shouldn't be too hard.

Basically you would scan for bluetooth devices, then ask it which characteristics you can get notifications from, let the user choose, then do something with it. You could extend things further letting them actually inspect the written values for devices that support it.

For instance, the Griffin Wireless PowerMate Bluetooth uses Bluetooth LE to send one of six things to the computer... rotate left/right, press, press-and-hold, press-and-hold-and-rotate left/right. By pairing to, then tracking those BLE notifications, you would implicitly support that device 'natively'.

Same could be done for any BLE device. This would also let people make custom BTT controllers with things like Arduinos and such.

Even better, if we let people create BLE device definitions, like for that aforementioned Griffin, then people could share the devices and get automatic understanding of the specific device (i.e. instead of characteristic 241-t316va-521-bla bla... they get 'rotate right'.

Going a step further, you could also let it send BLE messages to control external devices. This too can be done quite easily. For instance, the PunchThrough LightBlue app lets you 'interrogate' a device, which it can then emulate simply by publishing the same values as the original. So... you could clone in a BLE remote, then trigger BLE signals from BTT.

That latter part--going back out--would just be a nice-to-have but may be out of scope for this. Still, it's so close to what the first part of this is, it may be a freebie.

For that matter, I'd be more than happy to chip in and code the BLE portions if you could then integrate them into your app. Definitely something I'd use and happy to help out. LMK.

Anyway, something to consider. Thanks!

M

I totally second this. Here is actually a log from BlueSee that is connected to a PowerMate

User initiated device connection.
20:42:43.6300: connected in underlying BLE layer.
20:42:43.6340: discovered services: (
"25598CF7-4240-40A6-9910-080F19F91EBC",
"F000FFC0-0451-4000-B000-000000000000",
"Device Information"
)
20:42:43.8530: discovered characteristics for service 180A: (
"System ID",
"Model Number String",
"Serial Number String",
"Firmware Revision String",
"Hardware Revision String",
"Software Revision String",
"Manufacturer Name String",
"IEEE Regulatory Certification",
"PnP ID"
)
20:42:44.0030: discovered characteristics for service 25598CF7-4240-40A6-9910-080F19F91EBC: (
"50F09CC9-FE1D-4C79-A962-B3A7CD3E5584",
"847D189E-86EE-4BD2-966F-800832B1259D",
"9CF53570-DDD9-47F3-BA63-09ACEFC60415",
"C5CF8AE4-6988-409F-9EC4-F9DAA9147D15"
)
20:42:44.1370: discovered characteristics for service F000FFC0-0451-4000-B000-000000000000: (
"F000FFC1-0451-4000-B000-000000000000",
"F000FFC2-0451-4000-B000-000000000000"
)
20:42:44.1370: state changed to 'Connected'.
20:42:44.4530: received update from characteristic 2A23___180A: <13150800 00921200>
20:42:44.4820: received update from characteristic 2A24___180A: <50524a30 37363330 00>
20:42:44.5120: received update from characteristic 2A25___180A: <30783030 31323932 30383135 31330000>
20:42:44.5420: received update from characteristic 2A26___180A: <312e302e 3100>
20:42:44.5720: received update from characteristic 2A27___180A: <312e302e 3000>
20:42:44.6020: received update from characteristic 2A28___180A: <2000>
20:42:44.6330: received update from characteristic 2A29___180A: <47726966 66696e20 54656368 6e6f6c6f 677900>
20:42:44.6620: received update from characteristic 2A2A___180A:
20:42:44.6940: received update from characteristic 2A50___180A: <010d0000 001001>
20:42:44.7220: received update from characteristic 2A23___180A: <13150800 00921200>
20:42:44.7670: received update from characteristic 2A24___180A: <50524a30 37363330 00>
20:42:44.7970: received update from characteristic 2A25___180A: <30783030 31323932 30383135 31330000>
20:42:44.8270: received update from characteristic 2A26___180A: <312e302e 3100>
20:42:44.8570: received update from characteristic 2A27___180A: <312e302e 3000>
20:42:44.8870: received update from characteristic 2A28___180A: <2000>
20:42:44.9180: received update from characteristic 2A29___180A: <47726966 66696e20 54656368 6e6f6c6f 677900>
20:42:44.9470: received update from characteristic 2A2A___180A:
20:42:44.9770: received update from characteristic 2A50___180A: <010d0000 001001>
20:42:45.0080: received update from characteristic C5CF8AE4-6988-409F-9EC4-F9DAA9147D15___25598CF7-4240-40A6-9910-080F19F91EBC: <ff130000 00000000 00000000 00000000 000000>
20:42:45.0380: received update from characteristic C5CF8AE4-6988-409F-9EC4-F9DAA9147D15___25598CF7-4240-40A6-9910-080F19F91EBC: <506f7765 724d6174 6520426c 7565746f 6f7468>
20:42:45.0670: received update from characteristic 2A23___180A: <13150800 00921200>
20:42:45.0970: received update from characteristic 2A24___180A: <50524a30 37363330 00>
20:42:45.1270: received update from characteristic 2A25___180A: <30783030 31323932 30383135 31330000>
20:42:45.1570: received update from characteristic 2A26___180A: <312e302e 3100>
20:42:45.1870: received update from characteristic 2A27___180A: <312e302e 3000>
20:42:45.2170: received update from characteristic 2A28___180A: <2000>
20:42:45.2480: received update from characteristic 2A29___180A: <47726966 66696e20 54656368 6e6f6c6f 677900>
20:42:45.2770: received update from characteristic 2A2A___180A:
20:42:45.3070: received update from characteristic 2A50___180A: <010d0000 001001>
20:42:45.3370: received update from characteristic 2A23___180A: <13150800 00921200>
20:42:45.3670: received update from characteristic 2A24___180A: <50524a30 37363330 00>
20:42:45.3970: received update from characteristic 2A25___180A: <30783030 31323932 30383135 31330000>
20:42:45.4270: received update from characteristic 2A26___180A: <312e302e 3100>
20:42:45.4560: received update from characteristic 2A27___180A: <312e302e 3000>
20:42:45.4870: received update from characteristic 2A28___180A: <2000>
20:42:45.5180: received update from characteristic 2A29___180A: <47726966 66696e20 54656368 6e6f6c6f 677900>
20:42:45.5620: received update from characteristic 2A2A___180A:
20:42:45.5920: received update from characteristic 2A50___180A: <010d0000 001001>
20:42:45.6230: received update from characteristic C5CF8AE4-6988-409F-9EC4-F9DAA9147D15___25598CF7-4240-40A6-9910-080F19F91EBC:
20:42:45.6530: received update from characteristic C5CF8AE4-6988-409F-9EC4-F9DAA9147D15___25598CF7-4240-40A6-9910-080F19F91EBC: <ff130000 00000000 00000000 00000000 000000>
20:42:51.8880: updated subscription state for characteristic 50F09CC9-FE1D-4C79-A962-B3A7CD3E5584___25598CF7-4240-40A6-9910-080F19F91EBC: subscribed
20:42:53.1260: updated subscription state for characteristic 9CF53570-DDD9-47F3-BA63-09ACEFC60415___25598CF7-4240-40A6-9910-080F19F91EBC: subscribed
20:42:56.5760: updated subscription state for characteristic F000FFC1-0451-4000-B000-000000000000___F000FFC0-0451-4000-B000-000000000000: subscribed
20:42:57.8500: updated subscription state for characteristic F000FFC2-0451-4000-B000-000000000000___F000FFC0-0451-4000-B000-000000000000: subscribed
20:43:00.2150: received update from characteristic 9CF53570-DDD9-47F3-BA63-09ACEFC60415___25598CF7-4240-40A6-9910-080F19F91EBC: <68>
20:43:00.4380: received update from characteristic 9CF53570-DDD9-47F3-BA63-09ACEFC60415___25598CF7-4240-40A6-9910-080F19F91EBC: <68>
20:43:01.9010: received update from characteristic 9CF53570-DDD9-47F3-BA63-09ACEFC60415___25598CF7-4240-40A6-9910-080F19F91EBC: <67>
20:43:02.1500: received update from characteristic 9CF53570-DDD9-47F3-BA63-09ACEFC60415___25598CF7-4240-40A6-9910-080F19F91EBC: <67>
20:43:02.3890: received update from characteristic 9CF53570-DDD9-47F3-BA63-09ACEFC60415___25598CF7-4240-40A6-9910-080F19F91EBC: <67>
20:43:03.7380: received update from characteristic 50F09CC9-FE1D-4C79-A962-B3A7CD3E5584___25598CF7-4240-40A6-9910-080F19F91EBC: <64>
20:43:03.7760: received update from characteristic 9CF53570-DDD9-47F3-BA63-09ACEFC60415___25598CF7-4240-40A6-9910-080F19F91EBC: <65>
20:43:05.0880: received update from characteristic 9CF53570-DDD9-47F3-BA63-09ACEFC60415___25598CF7-4240-40A6-9910-080F19F91EBC: <65>
20:43:06.8130: received update from characteristic 9CF53570-DDD9-47F3-BA63-09ACEFC60415___25598CF7-4240-40A6-9910-080F19F91EBC: <65>
20:43:08.1260: received update from characteristic 9CF53570-DDD9-47F3-BA63-09ACEFC60415___25598CF7-4240-40A6-9910-080F19F91EBC: <65>
20:43:08.6510: received update from characteristic 9CF53570-DDD9-47F3-BA63-09ACEFC60415___25598CF7-4240-40A6-9910-080F19F91EBC: <72>
20:43:09.1760: received update from characteristic 9CF53570-DDD9-47F3-BA63-09ACEFC60415___25598CF7-4240-40A6-9910-080F19F91EBC: <73>
20:43:09.2510: received update from characteristic 9CF53570-DDD9-47F3-BA63-09ACEFC60415___25598CF7-4240-40A6-9910-080F19F91EBC: <66>
20:43:09.2520: received update from characteristic 9CF53570-DDD9-47F3-BA63-09ACEFC60415___25598CF7-4240-40A6-9910-080F19F91EBC: <66>
20:43:11.2760: received update from characteristic 9CF53570-DDD9-47F3-BA63-09ACEFC60415___25598CF7-4240-40A6-9910-080F19F91EBC: <68>
20:43:11.5760: received update from characteristic 9CF53570-DDD9-47F3-BA63-09ACEFC60415___25598CF7-4240-40A6-9910-080F19F91EBC: <68>
20:43:11.9510: received update from characteristic 9CF53570-DDD9-47F3-BA63-09ACEFC60415___25598CF7-4240-40A6-9910-080F19F91EBC: <68>
20:43:12.2130: received update from characteristic 9CF53570-DDD9-47F3-BA63-09ACEFC60415___25598CF7-4240-40A6-9910-080F19F91EBC: <67>
20:43:13.3760: received update from characteristic 9CF53570-DDD9-47F3-BA63-09ACEFC60415___25598CF7-4240-40A6-9910-080F19F91EBC: <65>
20:43:13.6010: received update from characteristic 9CF53570-DDD9-47F3-BA63-09ACEFC60415___25598CF7-4240-40A6-9910-080F19F91EBC: <69>
20:43:13.7890: received update from characteristic 9CF53570-DDD9-47F3-BA63-09ACEFC60415___25598CF7-4240-40A6-9910-080F19F91EBC: <69>
20:43:14.0130: received update from characteristic 9CF53570-DDD9-47F3-BA63-09ACEFC60415___25598CF7-4240-40A6-9910-080F19F91EBC: <70>

Being able to subscribe to characteristics and assign values to events would be great.
The log contains turn left, right, click, long-click,...

Cheers, karsten

Good idea. I have been working a lot with BTLE lately, so it should be easy to add such things. However creating the UI that allows listening to and possibly parsing complex btle data could be quite complicated. Maybe I can leverage BTT's new JavaScript functionality for that (I have recently create a complex BTLE app in JavaScript and it's surprisingly easy to handle raw data in JS)

One possibility is at least for an initial stab at it, don't worry about parsing any of the data. Just use the notifications on the characteristics/attributes as triggers, at least initially. You could then dig into the actual values later.

That said, aren't the values just basically numbers or strings? Not really following what the 'complex data' you're referring to is. Maybe you're talking at a much lower level than the APIs I'm referring to (CoreBluetooth, etc.) Still, something would be pretty cool for sure.

One thing you could do is use JSON for the definition of the devices. More than happy to brainstorm with you on this. Let us know if we can help at all.

Adding more, almost every BLE example on the web shows how to do a basic BLE browser. You first scan for peripherals and show them in a list. You then pick one and interrogate it for it's characteristics. Then the characteristics for the attributes, etc. Shouldn't be a difficult UI to do at all.

If it would help, I can share the UI I did in iOS for this. Not a 1-to-1 with Mac, but the basics are there. LMK.

jup that part is easy, however I don’t know any app that lets you execute different actions depending on what data has been received through the various characteristics. There are many complex protocols used over BTLE, if I add something like this it needs to be generic enough to support such.

It’s not just numbers and strings that are transferred over BTLE - it can be any byte sequence. Actually I have never worked with a BTLE device which didn’t require at least some parsing of the data or some small data exchange to start specific functionality (but I’m sure there are lots of consumer devices that are pretty simple)

I’m looking into this and I think I have some good ideas.

Just adding something here. Yes, you are correct about the data being something specific, but it usually is just a number or a string. Take a look at Punch Through's LightBlue app for iOS. (https://apps.apple.com/us/app/lightblue/id557428110). It's a generic browser that works as both a central and peripheral. It even has a cool feature that lets you act as the central, connect to a peripheral, clone it, then you can virtually emulate it as if you were that peripheral. For instance, I used it to connect to a BLE camera light, I cloned the light, then I made LightBlue pretend it was a light so the light's app connected to my virtual device and I could see all traffic going to/from it.

Also, a lot of devices deal with standard BLE protocols so there are known characteristics and values for them. And even for those that aren't known but are explored, let the user say what they're looking for... value 'x' on characteristic 'y' kinda thing.

But something else to consider... sometimes you don't even need to know what the value is! A notification on a characteristic itself may very well be enough to trigger the action. Say for 'any' change to the value, do 'X'

Again, check out that app and others like it and you'll see you can get a lot of info with a simple BLE browser.