1+ import { BleClient } from "@capacitor-community/bluetooth-le" ;
12import { AccelerometerData , AccelerometerDataEvent } from "./accelerometer.js" ;
23import { Service } from "./bluetooth-device-wrapper.js" ;
3- import { profile } from "./bluetooth-profile.js" ;
4- import { BackgroundErrorEvent , DeviceError } from "./device.js" ;
54import {
6- CharacteristicDataTarget ,
75 TypedServiceEvent ,
86 TypedServiceEventDispatcher ,
97} from "./service-events.js" ;
8+ import { profile } from "./bluetooth-profile.js" ;
109
1110export class AccelerometerService implements Service {
11+ static createService (
12+ deviceId : string ,
13+ dispatchTypedEvent : TypedServiceEventDispatcher ,
14+ ) : AccelerometerService {
15+ return new AccelerometerService ( deviceId , dispatchTypedEvent ) ;
16+ }
17+
1218 constructor (
13- private accelerometerDataCharacteristic : BluetoothRemoteGATTCharacteristic ,
14- private accelerometerPeriodCharacteristic : BluetoothRemoteGATTCharacteristic ,
19+ private deviceId : string ,
1520 private dispatchTypedEvent : TypedServiceEventDispatcher ,
16- private queueGattOperation : < R > ( action : ( ) => Promise < R > ) => Promise < R > ,
17- ) {
18- this . accelerometerDataCharacteristic . addEventListener (
19- "characteristicvaluechanged" ,
20- ( event : Event ) => {
21- const target = event . target as CharacteristicDataTarget ;
22- const data = this . dataViewToData ( target . value ) ;
23- this . dispatchTypedEvent (
24- "accelerometerdatachanged" ,
25- new AccelerometerDataEvent ( data ) ,
26- ) ;
27- } ,
28- ) ;
29- }
21+ ) { }
3022
31- static async createService (
32- gattServer : BluetoothRemoteGATTServer ,
33- dispatcher : TypedServiceEventDispatcher ,
34- queueGattOperation : < R > ( action : ( ) => Promise < R > ) => Promise < R > ,
35- listenerInit : boolean ,
36- ) : Promise < AccelerometerService | undefined > {
37- let accelerometerService : BluetoothRemoteGATTService ;
38- try {
39- accelerometerService = await gattServer . getPrimaryService (
40- profile . accelerometer . id ,
41- ) ;
42- } catch ( err ) {
43- if ( listenerInit ) {
44- dispatcher ( "backgrounderror" , new BackgroundErrorEvent ( err as string ) ) ;
45- return ;
46- } else {
47- throw new DeviceError ( {
48- code : "service-missing" ,
49- message : err as string ,
50- } ) ;
51- }
52- }
53- const accelerometerDataCharacteristic =
54- await accelerometerService . getCharacteristic (
55- profile . accelerometer . characteristics . data . id ,
56- ) ;
57- const accelerometerPeriodCharacteristic =
58- await accelerometerService . getCharacteristic (
59- profile . accelerometer . characteristics . period . id ,
60- ) ;
61- return new AccelerometerService (
62- accelerometerDataCharacteristic ,
63- accelerometerPeriodCharacteristic ,
64- dispatcher ,
65- queueGattOperation ,
66- ) ;
23+ getRelevantEvents ( ) : TypedServiceEvent [ ] {
24+ return [ "accelerometerdatachanged" ] ;
6725 }
6826
6927 private dataViewToData ( dataView : DataView ) : AccelerometerData {
@@ -75,15 +33,19 @@ export class AccelerometerService implements Service {
7533 }
7634
7735 async getData ( ) : Promise < AccelerometerData > {
78- const dataView = await this . queueGattOperation ( ( ) =>
79- this . accelerometerDataCharacteristic . readValue ( ) ,
36+ const dataView = await BleClient . read (
37+ this . deviceId ,
38+ profile . accelerometer . id ,
39+ profile . accelerometer . characteristics . data . id ,
8040 ) ;
8141 return this . dataViewToData ( dataView ) ;
8242 }
8343
8444 async getPeriod ( ) : Promise < number > {
85- const dataView = await this . queueGattOperation ( ( ) =>
86- this . accelerometerPeriodCharacteristic . readValue ( ) ,
45+ const dataView = await BleClient . read (
46+ this . deviceId ,
47+ profile . accelerometer . id ,
48+ profile . accelerometer . characteristics . period . id ,
8749 ) ;
8850 return dataView . getUint16 ( 0 , true ) ;
8951 }
@@ -99,23 +61,48 @@ export class AccelerometerService implements Service {
9961 // https://lancaster-university.github.io/microbit-docs/ble/profile/#about-the-accelerometer-service
10062 const dataView = new DataView ( new ArrayBuffer ( 2 ) ) ;
10163 dataView . setUint16 ( 0 , value , true ) ;
102- return this . queueGattOperation ( ( ) =>
103- this . accelerometerPeriodCharacteristic . writeValue ( dataView ) ,
64+ await BleClient . write (
65+ this . deviceId ,
66+ profile . accelerometer . id ,
67+ profile . accelerometer . characteristics . period . id ,
68+ dataView ,
10469 ) ;
10570 }
10671
10772 async startNotifications ( type : TypedServiceEvent ) : Promise < void > {
108- await this . characteristicForEvent ( type ) ?. startNotifications ( ) ;
73+ const result = this . characteristicForEvent ( type ) ;
74+ if ( result ) {
75+ const { service, characteristic } = result ;
76+ BleClient . startNotifications (
77+ this . deviceId ,
78+ service ,
79+ characteristic ,
80+ ( value ) => {
81+ const data = this . dataViewToData ( value ) ;
82+ this . dispatchTypedEvent (
83+ "accelerometerdatachanged" ,
84+ new AccelerometerDataEvent ( data ) ,
85+ ) ;
86+ } ,
87+ ) ;
88+ }
10989 }
11090
11191 async stopNotifications ( type : TypedServiceEvent ) : Promise < void > {
112- await this . characteristicForEvent ( type ) ?. stopNotifications ( ) ;
92+ const result = this . characteristicForEvent ( type ) ;
93+ if ( result ) {
94+ const { service, characteristic } = result ;
95+ BleClient . stopNotifications ( this . deviceId , service , characteristic ) ;
96+ }
11397 }
11498
11599 private characteristicForEvent ( type : TypedServiceEvent ) {
116100 switch ( type ) {
117101 case "accelerometerdatachanged" : {
118- return this . accelerometerDataCharacteristic ;
102+ return {
103+ service : profile . accelerometer . id ,
104+ characteristic : profile . accelerometer . characteristics . data . id ,
105+ } ;
119106 }
120107 default : {
121108 return undefined ;
0 commit comments