hm2mqtt 3.8.1 → 3.8.3

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.
Files changed (2) hide show
  1. package/lib/rpc.js +41 -1
  2. package/package.json +1 -1
package/lib/rpc.js CHANGED
@@ -26,6 +26,12 @@ const TX_METHODS = new Set(['setValue', 'putParamset', 'activateLinkParamset']);
26
26
  const INIT_BACKOFF_MS = [1000, 2000, 4000, 8000];
27
27
  export const INIT_RETRY_MS = 15000;
28
28
  const DEINIT_TIMEOUT_MS = 1500;
29
+ /**
30
+ * How long after an init the interface process's listDevices/newDevices still belong to it: hmipserver answers the
31
+ * init at once and calls listDevices and newDevices afterwards. Such a call later than this is the process calling on
32
+ * its own - it restarted and kept the subscription (B-5).
33
+ */
34
+ export const INIT_GRACE_MS = 30000;
29
35
  const CALL_TIMEOUT_MS = 30000;
30
36
 
31
37
  /**
@@ -185,11 +191,13 @@ export class RpcServers {
185
191
  const answer = connection.listDevices();
186
192
  this.log.debug('rpc >', connection.name, 'listDevices', answer.length, 'devices');
187
193
  done(answer);
194
+ connection.unsolicited(method);
188
195
  break;
189
196
  }
190
197
  case 'newDevices':
191
198
  connection.newDevices(Array.isArray(params[1]) ? params[1] : []);
192
199
  done('');
200
+ connection.unsolicited(method);
193
201
  break;
194
202
  case 'deleteDevices':
195
203
  connection.deleteDevices(Array.isArray(params[1]) ? params[1] : []);
@@ -319,6 +327,8 @@ export class RpcConnection extends EventEmitter {
319
327
  this.lastInitError = null;
320
328
  this.initFailures = 0;
321
329
  this.everInitialized = false;
330
+ this.initInFlight = false;
331
+ this.lastInitAt = 0;
322
332
  }
323
333
 
324
334
  /** Closes the client (binrpc: its socket and reconnect timer); the next call creates a new one. */
@@ -412,7 +422,13 @@ export class RpcConnection extends EventEmitter {
412
422
  this.servers.register(this.initId, this);
413
423
  this.lastEvent = this.timers.now();
414
424
  this.log.info('rpc', this.name, '> init', url, this.initId);
415
- await this.methodCall('init', [url, this.initId]);
425
+ this.initInFlight = true;
426
+ try {
427
+ await this.methodCall('init', [url, this.initId]);
428
+ } finally {
429
+ this.initInFlight = false;
430
+ }
431
+ this.lastInitAt = this.timers.now();
416
432
  this.initialized = true;
417
433
  this.everInitialized = true;
418
434
  if (this.initFailures > 0) {
@@ -501,6 +517,30 @@ export class RpcConnection extends EventEmitter {
501
517
  return this.listDevicesAnswer();
502
518
  }
503
519
 
520
+ /**
521
+ * The interface process called listDevices or newDevices. Outside our own init it restarted and kept the
522
+ * subscription: hmipserver restores its subscribers from its handlers file, calls listDevices and newDevices on
523
+ * them and answers their pings (the PONG arrives), but delivers no event to such a kept subscription until a fresh
524
+ * init (B-5; openccu-lite B-286, measured). So init again at once instead of waiting for the ping watchdog, which
525
+ * the PONGs keep satisfied. A newDevices for a device paired just now costs one init the same way.
526
+ * @param {string} method
527
+ */
528
+ unsolicited(method) {
529
+ if (!this.wantInit || this.stopped || !this.initialized || this.initInFlight || this.initTimer) {
530
+ return;
531
+ }
532
+ if (this.timers.now() - this.lastInitAt < INIT_GRACE_MS) {
533
+ return;
534
+ }
535
+ this.log.info(
536
+ 'rpc',
537
+ this.name,
538
+ method,
539
+ 'outside our init: the interface process restarted and kept the subscription - subscribing afresh',
540
+ );
541
+ this.initTimer = this.timers.setTimeout(() => this.init(), 0);
542
+ }
543
+
504
544
  newDevices(devices) {
505
545
  this.log.debug('rpc <', this.name, 'newDevices', devices.length);
506
546
  this.emit('newDevices', devices);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hm2mqtt",
3
- "version": "3.8.1",
3
+ "version": "3.8.3",
4
4
  "description": "Interface between Homematic CCU and MQTT",
5
5
  "type": "module",
6
6
  "main": "index.js",