@rhizomatics/signalk-bluetti-plugin 1.1.1-alpha → 1.1.2-alpha

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/index.js CHANGED
@@ -214,16 +214,18 @@ module.exports = function (app) {
214
214
  scanner.startScan(30000);
215
215
  };
216
216
 
217
- // Search $HOME for a file named <bleName>.csv (case-insensitive).
217
+ // Search $HOME for an encryption CSV for bleName.
218
+ // Priority: 1) <bleName>.csv 2) bluetti_device_licence.csv
218
219
  function findEncryptionCsvInHome(bleName) {
219
220
  const homeDir = os.homedir();
220
- const target = `${bleName.toLowerCase()}.csv`;
221
221
  try {
222
- const match = fs.readdirSync(homeDir).find(f => f.toLowerCase() === target);
223
- return match ? path.join(homeDir, match) : null;
224
- } catch (_) {
225
- return null;
226
- }
222
+ const files = fs.readdirSync(homeDir);
223
+ const specific = files.find(f => f.toLowerCase() === `${bleName.toLowerCase()}.csv`);
224
+ if (specific) return path.join(homeDir, specific);
225
+ const generic = files.find(f => f.toLowerCase() === 'bluetti_device_licence.csv');
226
+ if (generic) return path.join(homeDir, generic);
227
+ } catch (_) {}
228
+ return null;
227
229
  }
228
230
 
229
231
  function validateEncryptionCsvPath(csvPath, deviceName) {
package/lib/device.js CHANGED
@@ -12,8 +12,9 @@ const WRITE_UUID = 'ff02';
12
12
  const ALT_SERVICE_UUID = 'ffe0';
13
13
  const ALT_CHAR_UUID = 'ffe1';
14
14
 
15
- const RECONNECT_DELAYS = [5000, 10000, 20000, 30000, 60000]; // ms, capped at last value
16
- const CONNECT_TIMEOUT_MS = 30000;
15
+ const RECONNECT_DELAYS = [5000, 10000, 20000, 30000, 60000]; // ms, capped at last value
16
+ const CONNECT_TIMEOUT_MS = 30000;
17
+ const DISCOVER_TIMEOUT_MS = 20000;
17
18
 
18
19
  class BluettiDevice extends EventEmitter {
19
20
  constructor({ address, name, device, fields, pollIntervalMs = 10000, xorKey = null, log }) {
@@ -115,16 +116,26 @@ class BluettiDevice extends EventEmitter {
115
116
  };
116
117
  this._device.once('disconnect', this._disconnectHandler);
117
118
 
118
- await this._discoverServices();
119
+ let discoverSettled = false;
120
+ const discoverTimer = setTimeout(() => {
121
+ if (discoverSettled) return;
122
+ discoverSettled = true;
123
+ this._log(`[${this._name}] Service discovery timed out — will retry`);
124
+ this._scheduleReconnect();
125
+ }, DISCOVER_TIMEOUT_MS);
126
+
127
+ await this._discoverServices(() => !discoverSettled);
128
+ discoverSettled = true;
129
+ clearTimeout(discoverTimer);
119
130
  }
120
131
 
121
- async _discoverServices() {
132
+ async _discoverServices(isActive) {
122
133
  let gatt;
123
134
  try {
124
135
  gatt = await this._device.gatt();
125
136
  } catch (err) {
126
137
  this._log(`[${this._name}] GATT error: ${err.message}`);
127
- this._scheduleReconnect();
138
+ if (isActive()) this._scheduleReconnect();
128
139
  return;
129
140
  }
130
141
 
@@ -137,7 +148,7 @@ class BluettiDevice extends EventEmitter {
137
148
  }
138
149
  if (!service) {
139
150
  this._log(`[${this._name}] Could not find BLE service (tried ${SERVICE_UUID}, ${ALT_SERVICE_UUID})`);
140
- this._scheduleReconnect();
151
+ if (isActive()) this._scheduleReconnect();
141
152
  return;
142
153
  }
143
154
 
@@ -153,7 +164,7 @@ class BluettiDevice extends EventEmitter {
153
164
 
154
165
  if (!notifyChar || !writeChar) {
155
166
  this._log(`[${this._name}] Could not find required GATT characteristics`);
156
- this._scheduleReconnect();
167
+ if (isActive()) this._scheduleReconnect();
157
168
  return;
158
169
  }
159
170
 
@@ -161,7 +172,7 @@ class BluettiDevice extends EventEmitter {
161
172
  await notifyChar.startNotifications();
162
173
  } catch (err) {
163
174
  this._log(`[${this._name}] Subscribe error: ${err.message}`);
164
- this._scheduleReconnect();
175
+ if (isActive()) this._scheduleReconnect();
165
176
  return;
166
177
  }
167
178
 
package/lib/scanner.js CHANGED
@@ -97,8 +97,9 @@ class Scanner extends EventEmitter {
97
97
  this._scanning = false;
98
98
  // Decrement BlueZ discovery reference count — other plugins' sessions keep scanning.
99
99
  if (this._adapter) this._adapter.stopDiscovery().catch(() => {});
100
- this._log(`Scan complete. Found ${this._found.size} Bluetti device(s).`);
101
- this.emit('scanComplete', [...this._found.values()].map(({ address, name }) => ({ address, name })));
100
+ const found = [...this._found.values()].filter(v => v !== null);
101
+ this._log(`Scan complete. Found ${found.length} Bluetti device(s).`);
102
+ this.emit('scanComplete', found.map(({ address, name }) => ({ address, name })));
102
103
  }
103
104
 
104
105
  stopAll() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rhizomatics/signalk-bluetti-plugin",
3
- "version": "1.1.1-alpha",
3
+ "version": "1.1.2-alpha",
4
4
  "signalk": {
5
5
  "displayName": "Bluetti Monitoring"
6
6
  },