From 2fb37c5690b07c53c3a8fd4e49311312d4abc7ea Mon Sep 17 00:00:00 2001 From: Daniel Caspi Date: Mon, 28 Jun 2021 13:11:06 -0500 Subject: [PATCH] Polling of position_url #55 --- README.md | 3 +++ config.schema.json | 7 +++++++ index.js | 36 +++++++++++++++++++++++++++++++----- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 25a612d..1d3d8d5 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ Add the accessory in `config.json` in your home directory inside `.homebridge`. "up_url": "http://1.2.3.4/window/up", "down_url": "http://1.2.3.4/window/down", "position_url": "http://1.2.3.4/window/position", + "position_interval": 15000, "position_jsonata": "ShutterPosition1", "stop_url": "http://1.2.3.4/window/stop", "http_options": { @@ -182,6 +183,8 @@ This implementation does take into account whether or not the blinds are moving, If more robust handling of `position_url` responses in JSON format is needed, `position_jsonata` can be defined. This allows a [JSONata](https://jsonata.org/) expression to be set to parse the result. For example, considering the following JSON response: +`position_interval` is specified in ms, and defaults to 15000 ms (15 s). It can be used to set the polling frequency, particularly useful in cases where the blinds can also be controlled externally. + ```json { "example": { "value": 4 } diff --git a/config.schema.json b/config.schema.json index 055b1e1..babd9df 100644 --- a/config.schema.json +++ b/config.schema.json @@ -79,6 +79,13 @@ "placeholder": "http://1.2.3.4/window/position", "format": "uri" }, + "position_interval": { + "title": "Polling interval for Position URL", + "type": "integer", + "description": "Milliseconds between polling requests to position URL", + "minimum": 5000, + "placeholder": 15000 + }, "position_jsonata": { "title": "Jsonata for Position URL", "type": "string", diff --git a/index.js b/index.js index 7a9b0b9..feb3d42 100644 --- a/index.js +++ b/index.js @@ -45,6 +45,7 @@ function BlindsHTTPAccessory(log, config) { this.log.error(`Error parsing jsonata: ${err.message}`); } } + this.positionPollInterval = Math.max(parseInt(config.position_interval, 10) || 15000, 5000); this.stopURL = config.stop_url || false; this.httpOptions = config.http_options || config.http_method || { method: 'POST' }; this.successCodes = config.success_codes || [200]; @@ -93,13 +94,13 @@ function BlindsHTTPAccessory(log, config) { this.lastCommandMoveUp = this.currentTargetPosition % 100 > 0 ? null : this.currentTargetPosition === 100; if (this.positionURL) { - this.getCurrentPosition( + this.updatePositionByUrl(); + + this.pollInterval = setInterval( function () { - this.currentTargetPosition = this.lastPosition; - if (this.currentTargetPosition % 100 === 0) { - this.lastCommandMoveUp = this.currentTargetPosition === 100; - } + this.updatePositionByUrl(); }.bind(this), + this.positionPollInterval, ); } @@ -326,6 +327,31 @@ BlindsHTTPAccessory.prototype.setCurrentPositionByUrl = function (callback) { ); }; +BlindsHTTPAccessory.prototype.updatePositionByUrl = function () { + if (this.stopTimeout !== null || this.stepInterval !== null || this.lagTimeout !== null) { + if (this.verbose) { + this.log.info( + `Polling skipped (updatePositionByUrl); stopTimeout: ${this.stopTimeout}, stepInterval: ${this.stepInterval}, lagTimeout: ${this.lagTimeout}`, + ); + } + return; // blinds in motion by plugin + } + + if (this.verbose) { + this.log.info('Polling started (updatePositionByUrl)'); + } + + this.getCurrentPosition(function () { + this.currentTargetPosition = this.lastPosition; + if (this.currentTargetPosition % 100 === 0) { + this.lastCommandMoveUp = this.currentTargetPosition === 100; + } + if (this.verbose) { + this.log.info('Polling finished (updatePositionByUrl)'); + } + }).bind(this); +}; + BlindsHTTPAccessory.prototype.getTargetPosition = function (callback) { if (this.verbose) { this.log.info(`Requested TargetPosition: ${this.currentTargetPosition}%`);