-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.old.js
121 lines (99 loc) · 3.25 KB
/
index.old.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import dotenv from 'dotenv';
import mqtt from 'mqtt';
import * as nobleModule from '@abandonware/noble';
import * as MiParser from './parsers/mi_parser.js';
import * as QPParser from './parsers/qingping_parser.js';
import _ from 'lodash';
const noble = nobleModule.default;
const parsers = [MiParser, QPParser];
dotenv.config();
const topic = process.env.MQTT_TOPIC || 'ble_sensors';
const machineName = process.env.MACHINE_NAME || 'needsNameInConfig';
const mqttClient = mqtt.connect(`mqtt://${process.env.MQTT_HOSTNAME}`, {
username: process.env.MQTT_USERNAME,
password: process.env.MQTT_PASSWORD
});
function decodeData(peripheral) {
if (!peripheral.advertisement.serviceData) return;
//console.log(peripheral.advertisement.serviceUuids)
const { advertisement: { serviceData } = {}, id, address } = peripheral || {};
serviceData.forEach((iter) => {
if (!iter) return;
try {
let result = parsers.reduce((a, rootParser) => {
if (_.includes(rootParser.SERVICE_DATA_UUIDS, iter.uuid.toLowerCase())) {
return new rootParser.Parser(iter.data).parse();
}
return a;
}, null);
if (!result) return;
let wrappedResult = {
macAddress: result.macAddress,
rssi: peripheral.rssi,
receivedFrom: machineName,
parser: result.parser,
result: result.info
};
console.info('PUB:', wrappedResult.macAddress, result.info);
mqttClient.publish(topic, JSON.stringify(wrappedResult));
} catch (error) {
console.error(error);
}
});
}
function onDiscovery(peripheral) {
// peripheral.rssi - signal strength
// peripheral.address - MAC address
// peripheral.advertisement.localName - device's name
// peripheral.advertisement.manufacturerData - manufacturer-specific data
// peripheral.advertisement.serviceData - normal advertisement service data
// ignore devices with no manufacturer data
if (!peripheral.advertisement.serviceData) return;
// output what we have
decodeData(peripheral);
if (process.env.BLE_DEBUG == 'true') {
console.debug(
peripheral.address || 'no-address-yet',
JSON.stringify(peripheral.advertisement.localName || peripheral.address || 'no-name'),
peripheral.rssi,
signalStrengthPercentage(peripheral.rssi)
);
}
}
noble.on('warning', (warning) => console.warn(warning));
noble.on('discover', onDiscovery);
noble.on('stateChange', function (state) {
if (state != 'poweredOn') return;
console.log('🚀 Starting BLE scan...');
noble.startScanning([], true);
});
// bluetooth lib start / stop events
noble.on('scanStart', function () {
console.log('BLE Scanning started.');
});
noble.on('scanStop', function () {
console.log('BLE Scanning stopped.');
mqttClient.end();
});
function signalStrengthBars(rssi) {
let bars = '▂▄▆█';
if (rssi >= -65) {
// strong
return bars;
}
if (rssi >= -73) {
// good
return bars.substr(0, 3);
}
if (rssi >= -80) {
return bars.substr(0, 2);
}
if (rssi >= -94) {
return bars.substr(0, 1);
}
return '─';
}
function signalStrengthPercentage(rssi) {
// Quality as percentage max -40 min -110
return (((rssi + 110) * 10) / 7).toFixed(0) + '%';
}