node-red-contrib-victron-ble
Version:
node-red node to parse Instant Readout advertisement data from Victron BLE devices
64 lines (63 loc) • 2.55 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.NobleBleAdapter = void 0;
const events_1 = require("events");
const noble_1 = __importDefault(require("@abandonware/noble"));
class NobleBleAdapter extends events_1.EventEmitter {
scanning = false;
discovered = new Map();
async startScan() {
return new Promise((resolve, reject) => {
noble_1.default.on('stateChange', (state) => {
if (state === 'poweredOn') {
noble_1.default.startScanning([], true, (err) => {
if (err)
return reject(err);
this.scanning = true;
noble_1.default.on('discover', (peripheral) => {
const adv = peripheral.advertisement;
const address = peripheral.address || peripheral.uuid;
const device = {
address,
name: adv.localName,
rssi: peripheral.rssi,
};
this.discovered.set(device.address, device);
if (adv.manufacturerData) {
const packet = {
...device,
rssi: peripheral.rssi,
rawData: normalizeManufacturerData(adv.manufacturerData),
};
this.emit('raw', packet);
}
});
resolve();
});
}
else if (state === 'unauthorized') {
reject(new Error('noble warning: adapter state unauthorized, please run as root or with sudo'));
}
});
});
}
async stopScan() {
if (this.scanning) {
await noble_1.default.stopScanning();
this.scanning = false;
}
}
getDiscoveredDevices() {
return Array.from(this.discovered.values());
}
}
exports.NobleBleAdapter = NobleBleAdapter;
function normalizeManufacturerData(data) {
if (data.length > 2 && data.readUInt16LE(0) === 0x02e1) {
return data.subarray(2);
}
return data;
}