hm2mqtt 3.6.1 → 3.6.2

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 +31 -4
  2. package/package.json +1 -1
package/lib/rpc.js CHANGED
@@ -22,6 +22,8 @@ export const METHODS = [
22
22
  ];
23
23
 
24
24
  const TX_METHODS = new Set(['setValue', 'putParamset', 'activateLinkParamset']);
25
+ /** a failed init is retried after 2, 4, 8, 16 s, then every INIT_RETRY_MS (the cap) */
26
+ const INIT_BACKOFF_MS = [2000, 4000, 8000, 16000];
25
27
  const INIT_RETRY_MS = 30000;
26
28
  const DEINIT_TIMEOUT_MS = 1500;
27
29
  const CALL_TIMEOUT_MS = 30000;
@@ -48,6 +50,15 @@ export function batchHints(events) {
48
50
  return hints;
49
51
  }
50
52
 
53
+ /**
54
+ * The delay before the next init attempt.
55
+ * @param {number} failures failed attempts in a row (1 after the first failure)
56
+ * @returns {number} ms
57
+ */
58
+ export function initRetryDelay(failures) {
59
+ return failures >= 1 && failures <= INIT_BACKOFF_MS.length ? INIT_BACKOFF_MS[failures - 1] : INIT_RETRY_MS;
60
+ }
61
+
51
62
  /**
52
63
  * The callback servers the CCU talks to. One http (xmlrpc) and/or one binrpc server, started on
53
64
  * demand; calls are routed by their init id to the registered RpcConnection.
@@ -288,6 +299,7 @@ export class RpcConnection extends EventEmitter {
288
299
  this.initTimer = null;
289
300
  this.pingTimer = null;
290
301
  this.lastInitError = null;
302
+ this.initFailures = 0;
291
303
  }
292
304
 
293
305
  createClient() {
@@ -343,7 +355,7 @@ export class RpcConnection extends EventEmitter {
343
355
  });
344
356
  }
345
357
 
346
- /** Connects: init subscription (retried every 30 s while it fails), ping supervision. */
358
+ /** Connects: init subscription (retried with backoff from 2 s while it fails), ping supervision. */
347
359
  async start() {
348
360
  this.stopped = false;
349
361
  if (!this.wantInit) {
@@ -372,18 +384,33 @@ export class RpcConnection extends EventEmitter {
372
384
  this.log.info('rpc', this.name, '> init', url, this.initId);
373
385
  await this.methodCall('init', [url, this.initId]);
374
386
  this.initialized = true;
387
+ if (this.initFailures > 0) {
388
+ this.log.info('rpc', this.name, 'init succeeded after', this.initFailures + 1, 'attempts');
389
+ }
390
+ this.initFailures = 0;
375
391
  this.lastInitError = null;
376
392
  this.setConnected(true);
377
393
  } catch (err) {
394
+ if (this.stopped) {
395
+ return;
396
+ }
378
397
  const msg = err.message || String(err);
398
+ this.initFailures += 1;
399
+ const delay = initRetryDelay(this.initFailures);
379
400
  if (msg !== this.lastInitError) {
380
- this.log.warn('rpc', this.name, 'init failed:', msg, `- retrying every ${INIT_RETRY_MS / 1000} s`);
401
+ this.log.warn(
402
+ 'rpc',
403
+ this.name,
404
+ 'init failed:',
405
+ msg,
406
+ `- retrying in ${delay / 1000} s (then up to every ${INIT_RETRY_MS / 1000} s)`,
407
+ );
381
408
  this.lastInitError = msg;
382
409
  } else {
383
- this.log.debug('rpc', this.name, 'init failed:', msg);
410
+ this.log.debug('rpc', this.name, 'init failed:', msg, `- next attempt in ${delay / 1000} s`);
384
411
  }
385
412
  this.setConnected(false);
386
- this.initTimer = this.timers.setTimeout(() => this.init(), INIT_RETRY_MS);
413
+ this.initTimer = this.timers.setTimeout(() => this.init(), delay);
387
414
  return;
388
415
  }
389
416
  if (this.wantPing) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hm2mqtt",
3
- "version": "3.6.1",
3
+ "version": "3.6.2",
4
4
  "description": "Interface between Homematic CCU and MQTT",
5
5
  "type": "module",
6
6
  "main": "index.js",