/
button.js
91 lines (79 loc) · 2.32 KB
/
button.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
const noble = require('@abandonware/noble');
const buttonService = 'feff';
const buttonCharacteristic = 'fe01';
const ledCharacteristic = 'fe02';
const buttonName = 't-rex-btn';
function scanButton() {
console.log('Scanning...');
noble.startScanning([buttonService], true);
}
function init(clickListener, connectionListener = () => 0) {
noble.on('stateChange', (state) => {
if (state === 'poweredOn') {
scanButton();
} else {
noble.stopScanning();
}
});
noble.on('discover', (peripheral) => {
if (peripheral.advertisement.localName === buttonName) {
noble.stopScanning();
peripheral.connect((error) => {
if (error) {
connectionListener(false);
scanButton();
console.error(error);
return;
}
console.log('Connected to', peripheral.id);
peripheral.discoverSomeServicesAndCharacteristics(
[buttonService],
[buttonCharacteristic, ledCharacteristic],
onServicesAndCharacteristicsDiscovered
);
});
function onServicesAndCharacteristicsDiscovered(
error,
services,
[buttonNotifications, ledState]
) {
if (error) {
console.error(error);
peripheral.disconnect();
return;
}
ledState.write(Buffer.from([1]));
setTimeout(() => {
ledState.write(Buffer.from([0]));
}, 500);
// data callback receives notifications
buttonNotifications.on('data', (buf) => {
const pressed = buf[0] === 1;
if (pressed) {
clickListener(pressed);
}
});
// subscribe to be notified whenever the peripheral update the characteristic
buttonNotifications.subscribe((error) => {
if (error) {
console.error('Error subscribing to echoCharacteristic');
peripheral.disconnect();
} else {
connectionListener(true);
console.log('Subscribed for echoCharacteristic notifications');
}
});
}
peripheral.once('disconnect', () => {
console.log('disconnected');
// Clean noble's peripheral cache
noble._peripherals = {};
connectionListener(false);
scanButton();
});
}
});
}
module.exports = {
init
};