From 96236756f1438a336c9bf13a65f49c5f79e6f948 Mon Sep 17 00:00:00 2001 From: Kellojo Date: Sun, 2 Oct 2022 14:41:14 +0200 Subject: [PATCH 1/3] Added resetAutoReleaseOnDetection property to sensors --- .../accessories/HttpWebHookSensorAccessory.js | 28 +++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/homekit/accessories/HttpWebHookSensorAccessory.js b/src/homekit/accessories/HttpWebHookSensorAccessory.js index fa18939..2bf92fe 100644 --- a/src/homekit/accessories/HttpWebHookSensorAccessory.js +++ b/src/homekit/accessories/HttpWebHookSensorAccessory.js @@ -85,28 +85,46 @@ HttpWebHookSensorAccessory.prototype.changeFromServer = function(urlParams) { if (this.type === "contact") { this.service.getCharacteristic(Characteristic.ContactSensorState).updateValue(urlValue ? Characteristic.ContactSensorState.CONTACT_DETECTED : Characteristic.ContactSensorState.CONTACT_NOT_DETECTED, undefined, Constants.CONTEXT_FROM_WEBHOOK); if (this.autoRelease) { - setTimeout(function() { - this.storage.setItemSync("http-webhook-" + this.id, true); - this.service.getCharacteristic(Characteristic.ContactSensorState).updateValue(Characteristic.ContactSensorState.CONTACT_DETECTED, undefined, Constants.CONTEXT_FROM_TIMEOUTCALL); + var timeoutStorageKey = "http-webhook-" + this.type + "-auto-release-timeout-" + this.id; + var timeout = this.storage.getItemSync(timeoutStorageKey); + if (this.resetAutoReleaseOnDetection) clearTimeout(timeout); + + timeout = setTimeout(function() { + this.storage.setItemSync("http-webhook-" + this.id, true); + this.service.getCharacteristic(Characteristic.ContactSensorState).updateValue(Characteristic.ContactSensorState.CONTACT_DETECTED, undefined, Constants.CONTEXT_FROM_TIMEOUTCALL); }.bind(this), this.autoReleaseTime); + + this.storage.setItemSync(timeoutStorageKey, timeout); } } else if (this.type === "motion") { this.service.getCharacteristic(Characteristic.MotionDetected).updateValue(urlValue, undefined, Constants.CONTEXT_FROM_WEBHOOK); if (this.autoRelease) { - setTimeout(function() { + var timeoutStorageKey = "http-webhook-" + this.type + "-auto-release-timeout-" + this.id; + var timeout = this.storage.getItemSync(timeoutStorageKey); + if (this.resetAutoReleaseOnDetection) clearTimeout(timeout); + + timeout = setTimeout(function () { this.storage.setItemSync("http-webhook-" + this.id, false); this.service.getCharacteristic(Characteristic.MotionDetected).updateValue(false, undefined, Constants.CONTEXT_FROM_TIMEOUTCALL); }.bind(this), this.autoReleaseTime); + + this.storage.setItemSync(timeoutStorageKey, timeout); } } else if (this.type === "occupancy") { this.service.getCharacteristic(Characteristic.OccupancyDetected).updateValue(urlValue ? Characteristic.OccupancyDetected.OCCUPANCY_DETECTED : Characteristic.OccupancyDetected.OCCUPANCY_NOT_DETECTED, undefined, Constants.CONTEXT_FROM_WEBHOOK); if (this.autoRelease) { - setTimeout(function() { + var timeoutStorageKey = "http-webhook-" + this.type + "-auto-release-timeout-" + this.id; + var timeout = this.storage.getItemSync(timeoutStorageKey); + if (this.resetAutoReleaseOnDetection) clearTimeout(timeout); + + timeout = setTimeout(function () { this.storage.setItemSync("http-webhook-" + this.id, false); this.service.getCharacteristic(Characteristic.OccupancyDetected).updateValue(Characteristic.OccupancyDetected.OCCUPANCY_NOT_DETECTED, undefined, Constants.CONTEXT_FROM_TIMEOUTCALL); }.bind(this), this.autoReleaseTime); + + this.storage.setItemSync(timeoutStorageKey, timeout); } } else if (this.type === "smoke") { From 8678e3215dd1dfec8565b1f93c7d65e5d544c01c Mon Sep 17 00:00:00 2001 From: Kellojo Date: Sun, 2 Oct 2022 15:51:09 +0200 Subject: [PATCH 2/3] Added missing config entries --- README.md | 3 ++- config.schema.json | 8 +++++++- src/homekit/accessories/HttpWebHookSensorAccessory.js | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a2bacff..3dd18ce 100755 --- a/README.md +++ b/README.md @@ -176,7 +176,8 @@ Example config.json: "name": "Sensor name 1", "type": "contact", "autoRelease": false, // (optional) - "autoReleaseTime": 7500 // (optional, in ms) + "autoReleaseTime": 7500, // (optional, in ms) + "resetAutoReleaseOnDetection": true // (optional) }, { "id": "sensor2", diff --git a/config.schema.json b/config.schema.json index 38e920f..01597d6 100644 --- a/config.schema.json +++ b/config.schema.json @@ -112,6 +112,11 @@ "type": "integer", "placeholder": "7500", "required": false + }, + "resetAutoReleaseOnDetection": { + "title": "Reset Auto Release on Detection", + "type": "boolean", + "required": false } } } @@ -1369,7 +1374,8 @@ "sensors[].name", "sensors[].type", "sensors[].autoRelease", - "sensors[].autoReleaseTime" + "sensors[].autoReleaseTime", + "sensors[].resetAutoReleaseOnDetection" ] } ] diff --git a/src/homekit/accessories/HttpWebHookSensorAccessory.js b/src/homekit/accessories/HttpWebHookSensorAccessory.js index 2bf92fe..bdb994b 100644 --- a/src/homekit/accessories/HttpWebHookSensorAccessory.js +++ b/src/homekit/accessories/HttpWebHookSensorAccessory.js @@ -13,6 +13,7 @@ function HttpWebHookSensorAccessory(ServiceParam, CharacteristicParam, platform, this.type = sensorConfig["type"]; this.autoRelease = sensorConfig["autoRelease"]; this.autoReleaseTime = sensorConfig["autoReleaseTime"] || Constants.DEFAULT_SENSOR_TIMEOUT; + this.resetAutoReleaseOnDetection = sensorConfig["resetAutoReleaseOnDetection"]; this.informationService = new Service.AccessoryInformation(); this.informationService.setCharacteristic(Characteristic.Manufacturer, "HttpWebHooksPlatform"); From c2cbdb80b26c3a893733f3fa3d5588cd5a8d7082 Mon Sep 17 00:00:00 2001 From: Kellojo Date: Sun, 2 Oct 2022 21:15:49 +0200 Subject: [PATCH 3/3] Cleaned up timeout handling --- .../accessories/HttpWebHookSensorAccessory.js | 64 ++++++++----------- 1 file changed, 28 insertions(+), 36 deletions(-) diff --git a/src/homekit/accessories/HttpWebHookSensorAccessory.js b/src/homekit/accessories/HttpWebHookSensorAccessory.js index bdb994b..0d958f4 100644 --- a/src/homekit/accessories/HttpWebHookSensorAccessory.js +++ b/src/homekit/accessories/HttpWebHookSensorAccessory.js @@ -80,53 +80,19 @@ HttpWebHookSensorAccessory.prototype.changeFromServer = function(urlParams) { this.storage.setItemSync("http-webhook-" + this.id, urlValue); this.log.debug("cached: "+ cached); this.log.debug("cached !== urlValue: "+ (cached !== urlValue)); + + if (cached !== urlValue) { this.log("Change HomeKit value for " + this.type + " sensor to '%s'.", urlValue); if (this.type === "contact") { this.service.getCharacteristic(Characteristic.ContactSensorState).updateValue(urlValue ? Characteristic.ContactSensorState.CONTACT_DETECTED : Characteristic.ContactSensorState.CONTACT_NOT_DETECTED, undefined, Constants.CONTEXT_FROM_WEBHOOK); - if (this.autoRelease) { - var timeoutStorageKey = "http-webhook-" + this.type + "-auto-release-timeout-" + this.id; - var timeout = this.storage.getItemSync(timeoutStorageKey); - if (this.resetAutoReleaseOnDetection) clearTimeout(timeout); - - timeout = setTimeout(function() { - this.storage.setItemSync("http-webhook-" + this.id, true); - this.service.getCharacteristic(Characteristic.ContactSensorState).updateValue(Characteristic.ContactSensorState.CONTACT_DETECTED, undefined, Constants.CONTEXT_FROM_TIMEOUTCALL); - }.bind(this), this.autoReleaseTime); - - this.storage.setItemSync(timeoutStorageKey, timeout); - } } else if (this.type === "motion") { this.service.getCharacteristic(Characteristic.MotionDetected).updateValue(urlValue, undefined, Constants.CONTEXT_FROM_WEBHOOK); - if (this.autoRelease) { - var timeoutStorageKey = "http-webhook-" + this.type + "-auto-release-timeout-" + this.id; - var timeout = this.storage.getItemSync(timeoutStorageKey); - if (this.resetAutoReleaseOnDetection) clearTimeout(timeout); - - timeout = setTimeout(function () { - this.storage.setItemSync("http-webhook-" + this.id, false); - this.service.getCharacteristic(Characteristic.MotionDetected).updateValue(false, undefined, Constants.CONTEXT_FROM_TIMEOUTCALL); - }.bind(this), this.autoReleaseTime); - - this.storage.setItemSync(timeoutStorageKey, timeout); - } } else if (this.type === "occupancy") { this.service.getCharacteristic(Characteristic.OccupancyDetected).updateValue(urlValue ? Characteristic.OccupancyDetected.OCCUPANCY_DETECTED : Characteristic.OccupancyDetected.OCCUPANCY_NOT_DETECTED, undefined, Constants.CONTEXT_FROM_WEBHOOK); - if (this.autoRelease) { - var timeoutStorageKey = "http-webhook-" + this.type + "-auto-release-timeout-" + this.id; - var timeout = this.storage.getItemSync(timeoutStorageKey); - if (this.resetAutoReleaseOnDetection) clearTimeout(timeout); - - timeout = setTimeout(function () { - this.storage.setItemSync("http-webhook-" + this.id, false); - this.service.getCharacteristic(Characteristic.OccupancyDetected).updateValue(Characteristic.OccupancyDetected.OCCUPANCY_NOT_DETECTED, undefined, Constants.CONTEXT_FROM_TIMEOUTCALL); - }.bind(this), this.autoReleaseTime); - - this.storage.setItemSync(timeoutStorageKey, timeout); - } } else if (this.type === "smoke") { this.service.getCharacteristic(Characteristic.SmokeDetected).updateValue(urlValue ? Characteristic.SmokeDetected.SMOKE_DETECTED : Characteristic.SmokeDetected.SMOKE_NOT_DETECTED, undefined, Constants.CONTEXT_FROM_WEBHOOK); @@ -149,6 +115,9 @@ HttpWebHookSensorAccessory.prototype.changeFromServer = function(urlParams) { } } + + this.setAutoReleaseTimeout(); + return { "success" : true }; @@ -182,4 +151,27 @@ HttpWebHookSensorAccessory.prototype.getServices = function() { return [ this.service, this.informationService ]; }; +HttpWebHookSensorAccessory.prototype.resetToInitialState = function () { + if (this.type === "contact") { + this.storage.setItemSync("http-webhook-" + this.id, true); + this.service.getCharacteristic(Characteristic.ContactSensorState).updateValue(Characteristic.ContactSensorState.CONTACT_DETECTED, undefined, Constants.CONTEXT_FROM_TIMEOUTCALL); + } else if (this.type === "motion") { + this.storage.setItemSync("http-webhook-" + this.id, false); + this.service.getCharacteristic(Characteristic.MotionDetected).updateValue(false, undefined, Constants.CONTEXT_FROM_TIMEOUTCALL); + } else if (this.type === "occupancy") { + this.storage.setItemSync("http-webhook-" + this.id, false); + this.service.getCharacteristic(Characteristic.OccupancyDetected).updateValue(Characteristic.OccupancyDetected.OCCUPANCY_NOT_DETECTED, undefined, Constants.CONTEXT_FROM_TIMEOUTCALL); + } +} + +HttpWebHookSensorAccessory.prototype.setAutoReleaseTimeout = function () { + if (!this.autoRelease || !this.resetAutoReleaseOnDetection) return; + clearTimeout(this[this.getTimeoutKey()]); + this[this.getTimeoutKey()] = setTimeout(this.resetToInitialState.bind(this), this.autoReleaseTime); +} + +HttpWebHookSensorAccessory.prototype.getTimeoutKey = function() { + return `autoReleaseTimeout-${this.type}-${this.id}`; +} + module.exports = HttpWebHookSensorAccessory;