From 2e0c514a37a600c69b744fa858437f679a7a9cdb Mon Sep 17 00:00:00 2001 From: Daniel Caspi Date: Fri, 8 Jul 2022 10:16:53 -0500 Subject: [PATCH] Add favorite buttons for specific blind positions --- README.md | 2 ++ config.schema.json | 18 ++++++++++++++++++ index.js | 37 +++++++++++++++++++++++++++++++++++-- package.json | 2 +- 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index fb29b10..16a781d 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,7 @@ Add the accessory in `config.json` in your home directory inside `.homebridge`. "unique_serial": false, "show_toggle_button": false, "show_stop_button": false, + "show_favorite_buttons": [1, 50], "use_same_url_for_stop": false, "trigger_stop_at_boundaries": false, "webhook_port": 51828, @@ -170,6 +171,7 @@ For cases where `motion_time` varies based on the direction of shutter movement, | ---------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `show_stop_button` | `false` | Expose a HomeKit button for the stop command. | | `show_toggle_button` | `false` | Expose a HomeKit button that allows the blinds position to be toggled based on the last command sent. For example, if the last command sent to the blinds was `up`, it will send the command `down`. Note that on startup, `toggle` will have no effect unless either 1) the initial blinds position on start up is either 0 or 100, or, 2) at least one command (`up` or `down`) is sent. | +| `show_favorite_buttons` | `[]` | Expose HomeKit buttons for favorite positions, which are provided as an array of integers. | | `unique_serial` | `false` | Use a uuid-based serial/model number instead of the default `BlindsHTTPAccessory`. This should only be required for specific external integrations (such as Eve) that may have problems with identical serial numbers for multiple devices. | | `use_same_url_for_stop` | `false` | Send the previously sent url (either, `up_url` or `down_url`) again. This is for specific blind types that don't use a standard stop URL. | | `trigger_stop_at_boundaries` | `false` | Send an additional stop command when moving the blinds to position 0 or 100. Most blinds don't require this command and will stop by themselves. | diff --git a/config.schema.json b/config.schema.json index 5944b36..67ad28d 100644 --- a/config.schema.json +++ b/config.schema.json @@ -98,6 +98,20 @@ "minimum": 1 } }, + "show_favorite_buttons": { + "type": "array", + "notitle": true, + "uniqueItems": true, + "displayFlex": true, + "flex-direction": "row", + "items": { + "type": "integer", + "title": "Position (0 = closed, 100 = open)", + "placeholder": 50, + "minimum": 0, + "maximum": 100 + } + }, "webhook_port": { "title": "Port", "type": "integer", @@ -517,6 +531,10 @@ } } ] + }, + { + "type": "array", + "items": ["show_favorite_buttons[]"] } ] }, diff --git a/index.js b/index.js index 9e5aab0..f18b953 100644 --- a/index.js +++ b/index.js @@ -104,6 +104,10 @@ function BlindsHTTPAccessory(log, config) { // expose additional button vars this.showStopButton = config.show_stop_button === true; this.showToggleButton = config.show_toggle_button === true; + this.showFavoriteButtons = config.show_favorite_buttons || []; + this.showFavoriteButtons = new Set( + this.showFavoriteButtons.filter((val) => Number.isInteger(val) && val >= 0 && val <= 100), + ); // motion time vars const motionTimeConfig = parseInt(config.motion_time, 10) || 10000; @@ -839,6 +843,26 @@ BlindsHTTPAccessory.prototype.sendToggleRequest = function (targetService, on, c } }; +BlindsHTTPAccessory.prototype.sendFavoriteRequest = function (targetService, favoritePos, on, callback) { + if (on) { + if (targetService) { + this.log.info(`Requesting favorite position: ${favoritePos}`); + this.service.setCharacteristic(Characteristic.TargetPosition, favoritePos); + + setTimeout( + function () { + targetService.getCharacteristic(Characteristic.On).updateValue(false); + }.bind(this), + 1000, + ); + } + } + + if (targetService) { + return callback(null); + } +}; + BlindsHTTPAccessory.prototype.httpRequest = function (url, methods, callback) { if (!url) { return callback(null, null); @@ -964,18 +988,27 @@ BlindsHTTPAccessory.prototype.getServices = function () { this.services.push(this.service); if (this.showStopButton && (this.stopURL || this.useSameUrlForStop)) { - const stopService = new Service.Switch(this.name + ' Stop', 'stop'); + const stopService = new Service.Switch(`${this.name} Stop`, 'stop'); stopService.getCharacteristic(Characteristic.On).on('set', this.sendStopRequest.bind(this, stopService)); this.services.push(stopService); } if (this.showToggleButton) { - const toggleService = new Service.Switch(this.name + ' Toggle', 'toggle'); + const toggleService = new Service.Switch(`${this.name} Toggle`, 'toggle'); toggleService.getCharacteristic(Characteristic.On).on('set', this.sendToggleRequest.bind(this, toggleService)); this.services.push(toggleService); } + for (const favoritePos of this.showFavoriteButtons) { + const favoriteService = new Service.Switch(`${this.name} ${favoritePos}% Shortcut`, `favorite_${favoritePos}`); + favoriteService + .getCharacteristic(Characteristic.On) + .on('set', this.sendFavoriteRequest.bind(this, favoriteService, favoritePos)); + + this.services.push(favoriteService); + } + return this.services; }; diff --git a/package.json b/package.json index 0d5c6e4..24272d1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "homebridge-blinds", - "version": "2.0.0", + "version": "2.0.1", "description": "A homebridge plugin to control my blinds", "main": "index.js", "scripts": {