From 688b9f156536b47c05887352f4a0a3448927bdcd Mon Sep 17 00:00:00 2001 From: Radoslaw Sporny Date: Fri, 18 May 2018 15:50:51 +0200 Subject: [PATCH] issue #7: fix set position by slider This reverts commit b3f3b67342d2b398d0c0793c4e672f14bc870c4e. --- README.md | 3 ++- config-sample.json | 10 +++++----- index.js | 45 +++++++++++++++++++++++++++++++-------------- package.json | 5 +++-- 4 files changed, 41 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 9d7561d..b7f3d03 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,8 @@ Sample accessory: "durationDown": 13000, "pinClosed": 17, "pinOpen": 18, - "activeLow": false + "activeLow": false, + "reedSwitchActiveLow": false } ] ``` diff --git a/config-sample.json b/config-sample.json index 64f1744..999210b 100644 --- a/config-sample.json +++ b/config-sample.json @@ -13,8 +13,7 @@ "pinUp": 5, "pinDown": 11, "durationUp": 13000, - "durationDown": 13000, - "activeLow": false + "durationDown": 13000 }, { "accessory": "Blinds", @@ -23,9 +22,10 @@ "pinDown": 3, "durationUp": 27000, "durationDown": 25000, - "pinClosed":17, - "pinOpen":18, - "activeLow": false + "pinClosed": 17, + "pinOpen": 18, + "activeLow": false, + "reedSwitchActiveLow": false } ] } diff --git a/index.js b/index.js index 92af1ff..d9918bb 100644 --- a/index.js +++ b/index.js @@ -38,7 +38,13 @@ function BlindsAccessory(log, config) { this.infoService .setCharacteristic(Characteristic.Manufacturer, 'Radoslaw Sporny') .setCharacteristic(Characteristic.Model, 'RaspberryPi GPIO Blinds') - .setCharacteristic(Characteristic.SerialNumber, 'Version 1.1.0'); + .setCharacteristic(Characteristic.SerialNumber, 'Version 1.1.1'); + + this.finalBlindsStateTimeout; + this.togglePinTimeout; + this.intervalUp = this.durationUp / 100; + this.intervalDown = this.durationDown / 100; + this.currentPositionInterval; // use gpio pin numbering rpio.init({ @@ -93,11 +99,19 @@ BlindsAccessory.prototype.getTargetPosition = function(callback) { BlindsAccessory.prototype.setTargetPosition = function(position, callback) { this.log("Setting target position to %s", position); + this.targetPosition = position; + var moveUp = (this.targetPosition >= this.currentPosition); + var duration; if (this.positionState != STATE_STOPPED) { - this.log('Blinds are moving. You need to wait. I will do nothing.'); - callback(); - return false; + this.log("Blind is moving, current position %s", this.currentPosition); + if (this.oppositeDirection(moveUp)) { + this.log('Stopping the blind because of opposite direction'); + rpio.write((moveUp ? this.pinDown : this.pinUp), this.initialState); + } + clearInterval(this.currentPositionInterval); + clearTimeout(this.finalBlindsStateTimeout); + clearTimeout(this.togglePinTimeout); } if (this.currentPosition == position) { @@ -106,22 +120,20 @@ BlindsAccessory.prototype.setTargetPosition = function(position, callback) { return true; } - this.targetPosition = position; - var moveUp = (this.targetPosition >= this.currentPosition); - var duration; if (moveUp) { - duration = (this.targetPosition - this.currentPosition) / 100 * this.durationUp; + duration = Math.round((this.targetPosition - this.currentPosition) / 100 * this.durationUp); + this.currentPositionInterval = setInterval(function(){ this.currentPosition++; }.bind(this), this.intervalUp); } else { - duration = (this.currentPosition - this.targetPosition) / 100 * this.durationDown; + duration = Math.round((this.currentPosition - this.targetPosition) / 100 * this.durationDown); + this.currentPositionInterval = setInterval(function(){ this.currentPosition--; }.bind(this), this.intervalDown); } - this.log("Duration: %s ms", duration); - this.log(moveUp ? 'Moving up' : 'Moving down'); + this.log((moveUp ? 'Moving up' : 'Moving down') + ". Duration: %s ms.", duration); this.service.setCharacteristic(Characteristic.PositionState, (moveUp ? STATE_INCREASING : STATE_DECREASING)); this.positionState = (moveUp ? STATE_INCREASING : STATE_DECREASING); - setTimeout(this.setFinalBlindsState.bind(this), duration); + this.finalBlindsStateTimeout = setTimeout(this.setFinalBlindsState.bind(this), duration); this.togglePin((moveUp ? this.pinUp : this.pinDown), duration); callback(); @@ -129,13 +141,14 @@ BlindsAccessory.prototype.setTargetPosition = function(position, callback) { } BlindsAccessory.prototype.togglePin = function(pin, duration) { - rpio.write(pin, this.activeState); - setTimeout(function() { + if (rpio.read(pin) != this.activeState) rpio.write(pin, this.activeState); + this.togglePinTimeout = setTimeout(function() { rpio.write(pin, this.initialState); }.bind(this), duration); } BlindsAccessory.prototype.setFinalBlindsState = function() { + clearInterval(this.currentPositionInterval); this.positionState = STATE_STOPPED; this.service.setCharacteristic(Characteristic.PositionState, STATE_STOPPED); this.service.setCharacteristic(Characteristic.CurrentPosition, this.targetPosition); @@ -156,6 +169,10 @@ BlindsAccessory.prototype.partiallyOpenAndOutOfSync = function() { (this.currentPosition == 100 && this.pinOpen && (rpio.read(this.pinOpen) != this.reedSwitchActiveState)); } +BlindsAccessory.prototype.oppositeDirection = function(moveUp) { + return (this.positionState == STATE_INCREASING && !moveUp) || (this.positionState == STATE_DECREASING && moveUp); +} + BlindsAccessory.prototype.getServices = function() { return [this.infoService, this.service]; } diff --git a/package.json b/package.json index 664e36e..fbbb695 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "homebridge-gpio-blinds", - "version": "1.1.0", + "version": "1.1.1", "description": "Homebridge plugin to control blinds via Raspberry Pi GPIO pins", "license": "MIT", "keywords": [ @@ -9,7 +9,8 @@ "raspberry", "gpio", "blinds", - "window-blinds" + "window-blinds", + "homekit" ], "repository": { "type": "git",