node-red-contrib-victron-ble
Version:
node-red node to parse Instant Readout advertisement data from Victron BLE devices
75 lines (74 loc) • 2.62 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Scanner = void 0;
const get_ble_adapter_1 = require("./ble/get-ble-adapter");
const devices_1 = require("./devices");
const events_1 = require("events");
class Scanner extends events_1.EventEmitter {
ble = null;
deviceKeys = {};
knownDevices = {};
discovered = new Map();
constructor() {
super();
}
async start() {
this.ble = await (0, get_ble_adapter_1.getBleAdapter)();
if (!this.ble)
return;
this.ble.on('raw', (packet) => this.handleRawPacket(packet));
await this.ble.startScan();
}
async stop() {
if (this.ble)
await this.ble.stopScan();
}
setKey(address, key) {
this.deviceKeys[address.toLowerCase()] = key;
delete this.knownDevices[address.toLowerCase()];
}
getDiscoveredDevices() {
return Array.from(this.discovered.values());
}
handleRawPacket(packet) {
const now = Date.now();
const address = packet.address.toLowerCase();
let dev = this.discovered.get(address);
if (!dev) {
dev = { address, name: packet.name || '', rssi: packet.rssi };
this.discovered.set(address, dev);
}
else {
dev.name = packet.name || '';
dev.rssi = packet.rssi;
}
// Try to parse if we have a key
if (this.deviceKeys[address]) {
let emitRaw = true;
try {
if (packet.rawData.length > 0 && packet.rawData[0] == 0x10) {
const deviceClass = (0, devices_1.detectDeviceType)(packet.rawData);
if (!deviceClass)
throw new Error(`Could not identify device type for ${address}`);
let device = this.knownDevices[address];
if (!device) {
device = new deviceClass(this.deviceKeys[address]);
this.knownDevices[address] = device;
}
device.parse(packet.rawData);
const payload = device.toJson();
const parsedPacket = { ...packet, payload };
delete parsedPacket.rawData;
this.emit('parsed', parsedPacket);
emitRaw = false;
}
}
catch (error) {
// Parsing failed, emit as raw only
}
if (emitRaw)
this.emit('raw', packet);
}
}
}
exports.Scanner = Scanner;