node-red-contrib-ble-scanner 0.0.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -22
- package/dist/ble/backend.d.ts +21 -30
- package/dist/ble/bluez.d.ts +1 -1
- package/dist/ble/bluez.js +150 -226
- package/dist/ble/bluez.js.map +1 -1
- package/dist/ble/noble.js +86 -247
- package/dist/ble/noble.js.map +1 -1
- package/dist/ble/utils.d.ts +3 -1
- package/dist/ble/utils.js +23 -0
- package/dist/ble/utils.js.map +1 -1
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +8 -27
- package/dist/cli.js.map +1 -1
- package/dist/constants.d.ts +0 -2
- package/dist/constants.js +0 -2
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/reader.d.ts +1 -9
- package/dist/reader.js +59 -88
- package/dist/reader.js.map +1 -1
- package/nodes/ble-reader-device.html +1 -6
- package/nodes/ble-reader-device.js +0 -1
- package/nodes/ble-reader-read.html +4 -4
- package/nodes/ble-reader-read.js +1 -4
- package/package.json +5 -4
package/dist/cli.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Command, Option } from 'commander';
|
|
2
2
|
import { setTimeout as delay } from 'node:timers/promises';
|
|
3
|
-
import { DEFAULTS,
|
|
3
|
+
import { DEFAULTS, discoverDevices, readDevices, shutdownBluetooth } from './index.js';
|
|
4
4
|
export async function main(argv = process.argv.slice(2)) {
|
|
5
5
|
installSignalCleanup();
|
|
6
6
|
const program = new Command();
|
|
7
7
|
program
|
|
8
8
|
.name('ble-reader')
|
|
9
|
-
.description('Discover BLE devices and read raw
|
|
9
|
+
.description('Discover BLE devices and read raw advertisement manufacturer data.')
|
|
10
10
|
.showHelpAfterError();
|
|
11
11
|
addSharedOptions(program);
|
|
12
12
|
addSharedOptions(program
|
|
@@ -24,9 +24,9 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
24
24
|
});
|
|
25
25
|
addSharedOptions(program
|
|
26
26
|
.command('read')
|
|
27
|
-
.description('Read raw
|
|
27
|
+
.description('Read raw advertisement manufacturer data from one exact advertised device name, or all matching devices.')
|
|
28
28
|
.argument('[deviceName]', 'exact advertised BLE device name')
|
|
29
|
-
.option('--interval <seconds>', 'read repeatedly every N seconds
|
|
29
|
+
.option('--interval <seconds>', 'read repeatedly every N seconds')).action(async (deviceName, options, command) => {
|
|
30
30
|
const globals = globalOptions(command, options);
|
|
31
31
|
const intervalMs = parseIntervalMs(options.interval);
|
|
32
32
|
if (intervalMs === null) {
|
|
@@ -62,7 +62,6 @@ export function toReadOptions(globals, deviceName) {
|
|
|
62
62
|
bluetooth: globals.bluetooth,
|
|
63
63
|
namePrefix: globals.namePrefix,
|
|
64
64
|
deviceName: deviceName || undefined,
|
|
65
|
-
notifyUuid: globals.notifyUuid,
|
|
66
65
|
listenMs: parseListenMs(globals.listenMs),
|
|
67
66
|
scanServiceUuid: globals.serviceUuid || null,
|
|
68
67
|
matchServiceUuid: globals.serviceUuid || null,
|
|
@@ -74,8 +73,7 @@ function addSharedOptions(command) {
|
|
|
74
73
|
.addOption(new Option('--bluetooth <backend>', 'Bluetooth backend').choices(['auto', 'bluez', 'noble']).default('auto'))
|
|
75
74
|
.option('--name-prefix <prefix>', 'BLE advertised name prefix; empty matches all devices', DEFAULTS.namePrefix)
|
|
76
75
|
.option('--service-uuid <uuid>', 'optional BLE service UUID used for discovery filtering')
|
|
77
|
-
.option('--
|
|
78
|
-
.option('--listen-ms <ms>', 'milliseconds to collect notifications per read', String(DEFAULTS.listenMs))
|
|
76
|
+
.option('--listen-ms <ms>', 'milliseconds to collect advertisements per read', String(DEFAULTS.listenMs))
|
|
79
77
|
.option('--debug', 'print Bluetooth diagnostics to stderr');
|
|
80
78
|
}
|
|
81
79
|
function globalOptions(command, options) {
|
|
@@ -83,7 +81,6 @@ function globalOptions(command, options) {
|
|
|
83
81
|
bluetooth: optionValue(command, options, 'bluetooth', 'auto'),
|
|
84
82
|
namePrefix: optionValue(command, options, 'namePrefix', DEFAULTS.namePrefix),
|
|
85
83
|
serviceUuid: optionValue(command, options, 'serviceUuid', ''),
|
|
86
|
-
notifyUuid: optionValue(command, options, 'notifyUuid', DEFAULTS.notifyUuid),
|
|
87
84
|
listenMs: optionValue(command, options, 'listenMs', String(DEFAULTS.listenMs)),
|
|
88
85
|
debug: optionValue(command, options, 'debug', false)
|
|
89
86
|
};
|
|
@@ -104,26 +101,10 @@ async function writeJson(value) {
|
|
|
104
101
|
});
|
|
105
102
|
}
|
|
106
103
|
async function readAtInterval(globals, deviceName, intervalMs) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
await
|
|
110
|
-
return;
|
|
104
|
+
while (true) {
|
|
105
|
+
await writeJson(await readDevices(toReadOptions(globals, deviceName)));
|
|
106
|
+
await delay(intervalMs);
|
|
111
107
|
}
|
|
112
|
-
try {
|
|
113
|
-
while (true) {
|
|
114
|
-
await writeJson(await readPersistentReaders(readers, globals));
|
|
115
|
-
await delay(intervalMs);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
finally {
|
|
119
|
-
await Promise.all(readers.map((reader) => reader.disconnect().catch(() => { })));
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
async function readPersistentReaders(readers, globals) {
|
|
123
|
-
const readings = [];
|
|
124
|
-
for (const reader of readers)
|
|
125
|
-
readings.push(await reader.read(toReadOptions(globals)));
|
|
126
|
-
return readings;
|
|
127
108
|
}
|
|
128
109
|
function installSignalCleanup() {
|
|
129
110
|
let shuttingDown = false;
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,UAAU,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,EAAE,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/constants.d.ts
CHANGED
package/dist/constants.js
CHANGED
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,QAAQ,EAAE,IAAI;IACd,SAAS,EAAE,KAAK;IAChB,
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,QAAQ,EAAE,IAAI;IACd,SAAS,EAAE,KAAK;IAChB,UAAU,EAAE,EAAE;CACN,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { DEFAULTS } from './constants.js';
|
|
2
|
-
export {
|
|
2
|
+
export { discoverDevices, readDevice, readDevices, shutdownBluetooth } from './reader.js';
|
|
3
3
|
export { matchesBleDevice } from './ble/utils.js';
|
|
4
|
-
export type { BleDiscoveredDevice,
|
|
4
|
+
export type { BleAdvertisement, BleDiscoveredDevice, BleManufacturerData, BleReading, BluetoothBackendName, DiscoverOptions, RawBleMessage, ReadOptions } from './ble/backend.js';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { DEFAULTS } from './constants.js';
|
|
2
|
-
export {
|
|
2
|
+
export { discoverDevices, readDevice, readDevices, shutdownBluetooth } from './reader.js';
|
|
3
3
|
export { matchesBleDevice } from './ble/utils.js';
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC1F,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/reader.d.ts
CHANGED
|
@@ -1,13 +1,5 @@
|
|
|
1
|
-
import type { BleDiscoveredDevice, BleReading,
|
|
2
|
-
export interface BleReader {
|
|
3
|
-
device: BleDiscoveredDevice;
|
|
4
|
-
read(options?: ReadOptions): Promise<BleReading>;
|
|
5
|
-
disconnect(): Promise<void>;
|
|
6
|
-
}
|
|
1
|
+
import type { BleDiscoveredDevice, BleReading, DiscoverOptions, ReadOptions } from './ble/backend.js';
|
|
7
2
|
export declare function discoverDevices(options?: DiscoverOptions): Promise<BleDiscoveredDevice[]>;
|
|
8
3
|
export declare function readDevices(options?: ReadOptions): Promise<BleReading[]>;
|
|
9
4
|
export declare function readDevice(device: BleDiscoveredDevice, options?: ReadOptions): Promise<BleReading>;
|
|
10
|
-
export declare function connectReaders(options?: ReadOptions): Promise<BleReader[]>;
|
|
11
|
-
export declare function connectDevice(device: BleDiscoveredDevice, options?: ReadOptions): Promise<BleReader>;
|
|
12
|
-
export declare function readSession(session: BleSession, options?: ReadOptions): Promise<BleReading>;
|
|
13
5
|
export declare function shutdownBluetooth(): Promise<void>;
|
package/dist/reader.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { setTimeout as delay } from 'node:timers/promises';
|
|
2
1
|
import { DEFAULTS } from './constants.js';
|
|
3
2
|
import { bluezBackend } from './ble/bluez.js';
|
|
4
3
|
import { nobleBackend } from './ble/noble.js';
|
|
5
|
-
import { displayDevice, normalizeUuid } from './ble/utils.js';
|
|
6
4
|
export async function discoverDevices(options = {}) {
|
|
7
5
|
const logger = options.logger || (() => { });
|
|
8
6
|
const bluetooth = options.bluetooth || 'auto';
|
|
@@ -27,95 +25,48 @@ export async function discoverDevices(options = {}) {
|
|
|
27
25
|
}
|
|
28
26
|
export async function readDevices(options = {}) {
|
|
29
27
|
const logger = options.logger || (() => { });
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
logger(`Reading raw BLE notifications from ${displayDevice(device)}.`);
|
|
34
|
-
readings.push(await readDevice(device, { ...options, logger }));
|
|
35
|
-
}
|
|
36
|
-
return readings;
|
|
37
|
-
}
|
|
38
|
-
export async function readDevice(device, options = {}) {
|
|
39
|
-
const reader = await connectDevice(device, options);
|
|
40
|
-
try {
|
|
41
|
-
return await reader.read(options);
|
|
42
|
-
}
|
|
43
|
-
finally {
|
|
44
|
-
await reader.disconnect().catch(() => { });
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
export async function connectReaders(options = {}) {
|
|
48
|
-
const logger = options.logger || (() => { });
|
|
49
|
-
const devices = await discoverDevices({ ...options, logger });
|
|
50
|
-
const readers = [];
|
|
28
|
+
const bluetooth = options.bluetooth || 'auto';
|
|
29
|
+
const backend = await selectBluetoothBackend(bluetooth, logger);
|
|
30
|
+
const byDevice = new Map();
|
|
51
31
|
try {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
32
|
+
await backend.scanAdvertisements({
|
|
33
|
+
namePrefix: options.namePrefix ?? DEFAULTS.namePrefix,
|
|
34
|
+
deviceName: options.deviceName || null,
|
|
35
|
+
timeoutMs: options.timeoutMs || DEFAULTS.timeoutMs,
|
|
36
|
+
listenMs: options.listenMs ?? DEFAULTS.listenMs,
|
|
37
|
+
scanServiceUuid: options.scanServiceUuid ?? null,
|
|
38
|
+
matchServiceUuid: options.matchServiceUuid ?? null,
|
|
39
|
+
logger,
|
|
40
|
+
onAdvertisement: (advertisement) => {
|
|
41
|
+
const reading = readingForAdvertisement(byDevice, advertisement);
|
|
42
|
+
reading.messages.push(advertisement.message);
|
|
43
|
+
logger(`BLE manufacturer data ${advertisement.message.companyIdHex}:${advertisement.message.hex} ` +
|
|
44
|
+
`(${advertisement.message.length} byte${advertisement.message.length === 1 ? '' : 's'}).`);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
57
47
|
}
|
|
58
48
|
catch (error) {
|
|
59
|
-
|
|
49
|
+
if (bluetooth === 'auto' && isBluetoothUnavailableError(error)) {
|
|
50
|
+
logger(`No usable Bluetooth backend found: ${error instanceof Error ? error.message : String(error)}.`);
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
60
53
|
throw error;
|
|
61
54
|
}
|
|
55
|
+
return [...byDevice.values()].sort((left, right) => displayReading(left).localeCompare(displayReading(right)));
|
|
62
56
|
}
|
|
63
|
-
export async function
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
device
|
|
69
|
-
timeoutMs: options.timeoutMs || DEFAULTS.timeoutMs,
|
|
70
|
-
connectTimeoutMs: options.connectTimeoutMs || DEFAULTS.connectTimeoutMs,
|
|
71
|
-
notifyUuid,
|
|
72
|
-
logger
|
|
57
|
+
export async function readDevice(device, options = {}) {
|
|
58
|
+
const readings = await readDevices({
|
|
59
|
+
...options,
|
|
60
|
+
bluetooth: device.backend,
|
|
61
|
+
namePrefix: '',
|
|
62
|
+
deviceName: device.name || undefined
|
|
73
63
|
});
|
|
74
|
-
|
|
75
|
-
return {
|
|
76
|
-
device
|
|
77
|
-
read: (readOptions) => readSession(session, { ...options, ...readOptions, notifyUuid, logger }),
|
|
78
|
-
disconnect: async () => {
|
|
79
|
-
if (disconnected)
|
|
80
|
-
return;
|
|
81
|
-
disconnected = true;
|
|
82
|
-
await session.disconnect();
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
export async function readSession(session, options = {}) {
|
|
87
|
-
const logger = options.logger || (() => { });
|
|
88
|
-
const listenMs = options.listenMs ?? DEFAULTS.listenMs;
|
|
89
|
-
const notifyUuid = normalizeUuid(options.notifyUuid || session.notify.uuid || DEFAULTS.notifyUuid);
|
|
90
|
-
const messages = [];
|
|
91
|
-
const onData = (data) => {
|
|
92
|
-
const raw = Buffer.from(data);
|
|
93
|
-
const message = {
|
|
94
|
-
timestamp: new Date().toISOString(),
|
|
95
|
-
uuid: session.notify.uuid,
|
|
96
|
-
length: raw.length,
|
|
97
|
-
data: raw,
|
|
98
|
-
hex: raw.toString('hex'),
|
|
99
|
-
base64: raw.toString('base64'),
|
|
100
|
-
bytes: [...raw]
|
|
101
|
-
};
|
|
102
|
-
logger(`BLE notification ${message.hex} (${message.length} byte${message.length === 1 ? '' : 's'}).`);
|
|
103
|
-
messages.push(message);
|
|
104
|
-
};
|
|
105
|
-
session.notify.onData(onData);
|
|
106
|
-
try {
|
|
107
|
-
logger(`Listening for ${listenMs}ms on characteristic ${notifyUuid}.`);
|
|
108
|
-
await delay(listenMs);
|
|
109
|
-
}
|
|
110
|
-
finally {
|
|
111
|
-
session.notify.removeDataListener(onData);
|
|
112
|
-
}
|
|
113
|
-
return {
|
|
114
|
-
device: session.device,
|
|
64
|
+
const match = readings.find((reading) => sameDevice(reading.device, device));
|
|
65
|
+
return (match || {
|
|
66
|
+
device,
|
|
115
67
|
timestamp: new Date().toISOString(),
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
};
|
|
68
|
+
messages: []
|
|
69
|
+
});
|
|
119
70
|
}
|
|
120
71
|
export async function shutdownBluetooth() {
|
|
121
72
|
await Promise.all([nobleBackend.shutdown(), bluezBackend.shutdown()]);
|
|
@@ -129,12 +80,32 @@ async function selectBluetoothBackend(bluetooth, logger) {
|
|
|
129
80
|
return bluezBackend;
|
|
130
81
|
return nobleBackend;
|
|
131
82
|
}
|
|
132
|
-
function
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
83
|
+
function readingForAdvertisement(readings, advertisement) {
|
|
84
|
+
const key = deviceKey(advertisement.device);
|
|
85
|
+
const existing = readings.get(key);
|
|
86
|
+
if (existing) {
|
|
87
|
+
existing.device = advertisement.device;
|
|
88
|
+
existing.timestamp = advertisement.message.timestamp;
|
|
89
|
+
return existing;
|
|
90
|
+
}
|
|
91
|
+
const reading = {
|
|
92
|
+
device: advertisement.device,
|
|
93
|
+
timestamp: advertisement.message.timestamp,
|
|
94
|
+
messages: []
|
|
136
95
|
};
|
|
137
|
-
|
|
96
|
+
readings.set(key, reading);
|
|
97
|
+
return reading;
|
|
98
|
+
}
|
|
99
|
+
function sameDevice(left, right) {
|
|
100
|
+
return (left.id === right.id ||
|
|
101
|
+
(!!left.address && !!right.address && left.address.toLowerCase() === right.address.toLowerCase()) ||
|
|
102
|
+
(!!left.name && !!right.name && left.name === right.name));
|
|
103
|
+
}
|
|
104
|
+
function deviceKey(device) {
|
|
105
|
+
return device.address?.toLowerCase() || device.name || `${device.backend}:${device.id}`;
|
|
106
|
+
}
|
|
107
|
+
function displayReading(reading) {
|
|
108
|
+
return reading.device.name || reading.device.address || reading.device.id;
|
|
138
109
|
}
|
|
139
110
|
function isBluetoothUnavailableError(error) {
|
|
140
111
|
const message = error instanceof Error ? error.message.toLowerCase() : String(error).toLowerCase();
|
package/dist/reader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reader.js","sourceRoot":"","sources":["../src/reader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"reader.js","sourceRoot":"","sources":["../src/reader.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
bluetooth: { value: 'auto' },
|
|
7
7
|
namePrefix: { value: '' },
|
|
8
8
|
serviceUuid: { value: '' },
|
|
9
|
-
notifyUuid: { value: 'fff1', required: true },
|
|
10
9
|
listenMs: { value: 5000, required: true, validate: RED.validators.number() },
|
|
11
10
|
targetMode: { value: 'all' },
|
|
12
11
|
deviceName: { value: '' }
|
|
@@ -107,10 +106,6 @@
|
|
|
107
106
|
<label for="node-config-input-serviceUuid"><i class="fa fa-filter"></i> Service UUID</label>
|
|
108
107
|
<input type="text" id="node-config-input-serviceUuid" placeholder="optional">
|
|
109
108
|
</div>
|
|
110
|
-
<div class="form-row">
|
|
111
|
-
<label for="node-config-input-notifyUuid"><i class="fa fa-bell"></i> Notify UUID</label>
|
|
112
|
-
<input type="text" id="node-config-input-notifyUuid" placeholder="fff1">
|
|
113
|
-
</div>
|
|
114
109
|
<div class="form-row">
|
|
115
110
|
<label for="node-config-input-listenMs"><i class="fa fa-clock-o"></i> Listen ms</label>
|
|
116
111
|
<input type="number" id="node-config-input-listenMs" min="0" step="100">
|
|
@@ -131,5 +126,5 @@
|
|
|
131
126
|
</script>
|
|
132
127
|
|
|
133
128
|
<script type="text/html" data-help-name="ble-reader-device">
|
|
134
|
-
<p>Configures BLE
|
|
129
|
+
<p>Configures BLE advertisement scanning and optional device filters used by the raw reader.</p>
|
|
135
130
|
</script>
|
|
@@ -11,7 +11,6 @@ module.exports = function registerBleReaderDeviceNode(RED) {
|
|
|
11
11
|
node.bluetooth = config.bluetooth || 'auto';
|
|
12
12
|
node.namePrefix = config.namePrefix || '';
|
|
13
13
|
node.serviceUuid = config.serviceUuid || '';
|
|
14
|
-
node.notifyUuid = config.notifyUuid || 'fff1';
|
|
15
14
|
node.listenMs = Number(config.listenMs || 5000);
|
|
16
15
|
node.targetMode = config.targetMode || 'all';
|
|
17
16
|
node.deviceName = config.deviceName || '';
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
outputs: 1,
|
|
12
12
|
icon: 'font-awesome/fa-bluetooth',
|
|
13
13
|
label: function () {
|
|
14
|
-
return this.name || 'BLE read';
|
|
14
|
+
return this.name || 'BLE advertisement read';
|
|
15
15
|
}
|
|
16
16
|
});
|
|
17
17
|
</script>
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
</script>
|
|
33
33
|
|
|
34
34
|
<script type="text/html" data-help-name="ble-reader-read">
|
|
35
|
-
<p>Collects raw BLE
|
|
36
|
-
<p>Each message contains <code>data</code> as a Buffer plus <code>hex</code>, <code>base64</code>, <code>bytes</code>, <code>length</code>, and <code>timestamp</code>.</p>
|
|
37
|
-
<p>Incoming <code>msg.payload</code> may contain <code>{ deviceName, listenMs, serviceUuid
|
|
35
|
+
<p>Collects raw BLE advertisement manufacturer data. Output <code>msg.payload</code> is an array with one entry per matching device.</p>
|
|
36
|
+
<p>Each message contains <code>companyId</code>, <code>companyIdHex</code>, <code>data</code> as a Buffer plus <code>hex</code>, <code>base64</code>, <code>bytes</code>, <code>length</code>, and <code>timestamp</code>.</p>
|
|
37
|
+
<p>Incoming <code>msg.payload</code> may contain <code>{ deviceName, listenMs, serviceUuid }</code> to override the configured values.</p>
|
|
38
38
|
</script>
|
package/nodes/ble-reader-read.js
CHANGED
|
@@ -16,16 +16,14 @@ module.exports = function registerBleReaderReadNode(RED) {
|
|
|
16
16
|
const deviceName = override.deviceName || (node.device.targetMode === 'name' ? node.device.deviceName : undefined);
|
|
17
17
|
const listenMs = override.listenMs ?? (node.listenMs || node.device.listenMs);
|
|
18
18
|
const serviceUuid = override.serviceUuid ?? node.device.serviceUuid;
|
|
19
|
-
const notifyUuid = override.notifyUuid ?? node.device.notifyUuid;
|
|
20
19
|
|
|
21
|
-
node.status({ fill: 'yellow', shape: 'ring', text: '
|
|
20
|
+
node.status({ fill: 'yellow', shape: 'ring', text: 'scanning' });
|
|
22
21
|
const result = await node.device.enqueue((ble) =>
|
|
23
22
|
ble.readDevices({
|
|
24
23
|
bluetooth: node.device.bluetooth,
|
|
25
24
|
namePrefix: node.device.namePrefix,
|
|
26
25
|
deviceName,
|
|
27
26
|
listenMs,
|
|
28
|
-
notifyUuid,
|
|
29
27
|
scanServiceUuid: serviceUuid || null,
|
|
30
28
|
matchServiceUuid: serviceUuid || null
|
|
31
29
|
})
|
|
@@ -50,7 +48,6 @@ function normalizePayload(payload) {
|
|
|
50
48
|
const result = {};
|
|
51
49
|
if (typeof payload.deviceName === 'string' && payload.deviceName) result.deviceName = payload.deviceName;
|
|
52
50
|
if (typeof payload.serviceUuid === 'string') result.serviceUuid = payload.serviceUuid;
|
|
53
|
-
if (typeof payload.notifyUuid === 'string' && payload.notifyUuid) result.notifyUuid = payload.notifyUuid;
|
|
54
51
|
if (payload.listenMs !== undefined) {
|
|
55
52
|
const listenMs = Number(payload.listenMs);
|
|
56
53
|
if (Number.isFinite(listenMs) && listenMs >= 0) result.listenMs = listenMs;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-red-contrib-ble-scanner",
|
|
3
|
-
"version": "0.0
|
|
4
|
-
"description": "Generic Node-RED BLE
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Generic Node-RED BLE scanner for raw advertisement manufacturer data.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"test": "npm run build --silent && node --test"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"commander": "^
|
|
49
|
+
"commander": "^15.0.0",
|
|
50
50
|
"dbus-next": "^0.10.2"
|
|
51
51
|
},
|
|
52
52
|
"optionalDependencies": {
|
|
@@ -67,7 +67,8 @@
|
|
|
67
67
|
"bluetooth",
|
|
68
68
|
"ble",
|
|
69
69
|
"scanner",
|
|
70
|
-
"
|
|
70
|
+
"advertisements",
|
|
71
|
+
"manufacturer-data"
|
|
71
72
|
],
|
|
72
73
|
"license": "MIT"
|
|
73
74
|
}
|