You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/Bluetooth_MI32.md
+66-26Lines changed: 66 additions & 26 deletions
Original file line number
Diff line number
Diff line change
@@ -142,7 +142,7 @@ The naming conventions in the product range of bluetooth sensors in XIAOMI-unive
142
142
</tr>
143
143
</table>
144
144
passive: data is received via BLE advertisements
145
-
active: data is received via bidrectional connection to the sensor
145
+
active: data is received via bidirectional connection to the sensor
146
146
147
147
#### Devices with payload encryption
148
148
@@ -324,8 +324,23 @@ We have the following methods, which are chosen to be able to replace the old co
324
324
For generic BLE access we import the module:
325
325
`import BLE`
326
326
327
-
To simplify BLE access this works in the form of state machine, where you have to set some properties of a context and then finally launch an operation. Besides we have three callback mechanisms for listening to advertisements, active sensor connections with Tasmota as a client and providing a server including advertising. All need a byte buffer in Berry for data exchange and a Berry function as the callback.
327
+
BLE Function|Parameters and details
328
+
:---|:---
329
+
adv_cb|`(callback function:function, buffer:bytes)`<br>Will start listening to advertisements or stop it by providing `nil` as function.<br>The callback function will have arguments `service data` and `manufacturer data` as integer values, that are indices pointing to these kinds of data in the buffer or have a value of 0 if there is no such data in the advertisement.
330
+
adv_watch|`(MAC:bytes[, type:int])`<br>Watch BLE address exclusively, is added to a list (MAC is a 6-byte-buffer, type is optional 0-3, default is 0).
331
+
adv_block|`(MAC:bytes[, type:int])`<br>Block BLE address, is added to a list (MAC is a 6-byte-buffer, type is optional 0-3, default is 0).
332
+
conn_cb|`(callback function:function, buffer:bytes)`<br>Will init Tasmota as a peripheral device, that can connect to a central device.<br>The callback function will have arguments `error`,`op code`,`16-bit uuid` and `handle`. If an UUID with more than 16 bit is accessed, the automatic conversion to 16-bit will probably give no usable result, thus the handle should be used in these cases.
333
+
serv_cb|`(callback function:function, buffer:bytes)`<br>Will init Tasmota as a central device (aka server) or stop it by providing `nil` as function.<br>The callback function will have arguments `error`,`op code`,`16-bit uuid` and `handle`. If an UUID with more than 16 bit is accessed, the automatic conversion to 16-bit will probably give no usable result, thus the handle should be used in these cases.
334
+
set_MAC|`(MAC:bytes[, type:int]) -> handled:bool`<br>Set MAC for for use as peripheral or central device as a 6-byte-buffer, type is optional 0-3, default is 0.
335
+
set_svc|`(UUID:string[, discoverAttributes:bool]) -> handled:bool`<br>Set service UUID for for use as peripheral or central device as a 16-Bit or 128-Bit service uuid, the latter must include the dashes. Optional: Let the BLE stack discover all attributes of the service, which takes time and battery. Default is `false`.
336
+
set_chr|`(UUID:string) -> handled:bool`<br>Set characteristic UUID for for use as peripheral or central device as a 16-Bit or 128-Bit service uuid, the latter must include the dashes.
337
+
run|`(operation:int[, response:bool])`<br>Start a Bluetooth operation, where `operation` is a proprietary code - see sections below. `Response` is optional and defaults to `false`.
338
+
loop|`()`<br>Triggers a synchronization between Bluetooth stack and Berry, thus firing callbacks, if there is new data. Will typically be called from Berrys [Fast Loop](Berry.md#fast-loop).
339
+
340
+
341
+
To simplify BLE access this works in the form of state machine, where you have to set some properties of a context and then finally launch an operation. Besides we have three callback mechanisms for listening to advertisements, active sensor connections with Tasmota as a client and providing a server including advertising. All you need is a byte buffer in Berry for data exchange and a Berry function as the callback.
328
342
The byte buffer is always organized in the format `length-data bytes`, where the first byte represents the length of the following data bytes, which results in a maximum of 255 data bytes.
343
+
Because Bluetooth is inherently very asynchronous, almost every status, result or error condition is reported via callbacks.
329
344
330
345
#### Observer (aka Advertisement listener)
331
346
To listen to advertisements inside a class (that could be a driver) we could initialize like that:
@@ -380,13 +395,10 @@ The payload is always provided completely, so every possibles AD type can be par
380
395
381
396
The payload can be parsed according to the BLE GAP standard. It consists of AD elements of variable size in the format length-type-data, where the length byte describes the length of the two following components in bytes, the type byte is defined in the GAP and the data parts of 'length-1' bytes is interpreted according to the type.
382
397
383
-
Two methods for filtering of advertisements are provided:
384
-
`BLE.adv_watch(MAC,type)`: watch BLE address exclusively, is added to a list (MAC is a 6-byte-buffer, type is optional 0-3, default is 0)
385
-
`BLE.adv_block(MAC,type)`: block BLE address, is added to a list(MAC is a 6-byte-buffer, type is optional 0-3, default is 0)
386
-
398
+
387
399
!!! tip
388
400
389
-
The watchlist is more effective to avoid missing packets, than the blocklist in environments with high BLE traffic. Both methods work for the internal Xiaomi driver and the post processing with Berry.
401
+
The watchlist is more effective to avoid missing packets than the blocklist in environments with high BLE traffic. Both methods work for the internal Xiaomi driver and the post processing with Berry, because they set properties of the underlying Bluetooth framework.
390
402
391
403
#### Peripheral role (aka client)
392
404
@@ -739,13 +751,13 @@ Here is an implementation of the "old" MI32 commands:
739
751
740
752
```berry
741
753
# Simple Berry driver for the BPR2S Air mouse (a cheap BLE HID controller)
742
-
# TODO: handle mouse mode
743
754
744
755
import BLE
745
756
746
757
class BLE_BPR2S : Driver
747
758
var buf
748
-
var connecting, connected
759
+
var connecting, connected, new_position
760
+
var x,y
749
761
750
762
def init(MAC,addr_type)
751
763
var cbp = tasmota.gen_cb(/e,o,u,h->self.cb(e,o,u,h))
@@ -754,12 +766,15 @@ Here is an implementation of the "old" MI32 commands:
754
766
BLE.set_MAC(bytes(MAC),addr_type)
755
767
print("BLE: will try to connect to BPR2S with MAC:",MAC)
756
768
self.connect()
757
-
tasmota.add_fast_loop(/-> BLE.loop())
769
+
tasmota.add_fast_loop(/-> BLE.loop()) # needed for mouse position
758
770
end
759
771
760
772
def connect()
761
-
self.connecting = true;
762
-
self.connected = false;
773
+
self.connecting = true
774
+
self.connected = false
775
+
self.new_position = false
776
+
self.x = 128
777
+
self.y = 128
763
778
BLE.set_svc("1812")
764
779
BLE.set_chr("2a4a") # the first characteristic we have to read
765
780
BLE.run(1) # read
@@ -772,22 +787,53 @@ Here is an implementation of the "old" MI32 commands:
0 commit comments