Skip to content

Commit 01113f2

Browse files
authored
Merge pull request #9 from rsporny/issue-6-reed-switch
Issue 6 reed switch
2 parents 7be261e + c39e7d1 commit 01113f2

3 files changed

Lines changed: 51 additions & 13 deletions

File tree

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ Sample accessory:
2222
"pinDown": 11,
2323
"durationUp": 13000,
2424
"durationDown": 13000,
25+
"pinClosed": 17,
26+
"pinOpen": 18,
2527
"activeLow": false
2628
}
2729
]
@@ -35,7 +37,10 @@ Fields:
3537
- `pinDown` pin for moving down
3638
- `durationUp` milliseconds to open blinds completely
3739
- `durationDown` milliseconds to close blinds completely
38-
- `activeLow` set to false if your relay is activated by high state (default: *true*)
40+
- `pinClosed` [optional] pin connected to reed switch which is active when blind is closed, see *reedActiveLow*
41+
- `pinOpen` [optional] pin connected to reed switch which is active when blind is open, see *reedActiveLow*
42+
- `activeLow` [optional, default: *true*] true: relay activated by low state (0), false: relay activated by high state (1), affects *pinUp*, *pinDown*
43+
- `reedSwitchActiveLow` [optional, default: *true*] true: reed switch activated by low state (0), false: reed switch activated by high state (1), affects *pinClosed*, *pinOpen*
3944

4045
## Raspberry Pi setup
4146
- Raspberry Pi 3 (should work with all versions)

config-sample.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
"pinDown": 3,
2424
"durationUp": 27000,
2525
"durationDown": 25000,
26+
"pinClosed":17,
27+
"pinOpen":18,
2628
"activeLow": false
2729
}
2830
]

index.js

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
var _ = require("underscore");
2-
var rpio = require("rpio");
1+
var _ = require('underscore');
2+
var rpio = require('rpio');
33
var Service, Characteristic;
44

55
const STATE_DECREASING = 0;
@@ -10,20 +10,23 @@ module.exports = function(homebridge) {
1010
Service = homebridge.hap.Service;
1111
Characteristic = homebridge.hap.Characteristic;
1212

13-
homebridge.registerAccessory("homebridge-gpio-blinds", "Blinds", BlindsAccessory);
13+
homebridge.registerAccessory('homebridge-gpio-blinds', 'Blinds', BlindsAccessory);
1414
}
1515

1616
function BlindsAccessory(log, config) {
17-
_.defaults(config, {activeLow: true});
17+
_.defaults(config, {activeLow: true, reedSwitchActiveLow: true});
1818

1919
this.log = log;
2020
this.name = config['name'];
21-
this.pinUp = config["pinUp"];
22-
this.pinDown = config["pinDown"];
21+
this.pinUp = config['pinUp'];
22+
this.pinDown = config['pinDown'];
2323
this.durationUp = config['durationUp'];
2424
this.durationDown = config['durationDown'];
25+
this.pinClosed = config['pinClosed'];
26+
this.pinOpen = config['pinOpen'];
2527
this.initialState = config['activeLow'] ? rpio.HIGH : rpio.LOW;
2628
this.activeState = config['activeLow'] ? rpio.LOW : rpio.HIGH;
29+
this.reedSwitchActiveState = config['reedSwitchActiveLow'] ? rpio.LOW : rpio.HIGH;
2730

2831
this.currentPosition = 0; // down by default
2932
this.targetPosition = 0; // down by default
@@ -33,16 +36,18 @@ function BlindsAccessory(log, config) {
3336

3437
this.infoService = new Service.AccessoryInformation();
3538
this.infoService
36-
.setCharacteristic(Characteristic.Manufacturer, "Radoslaw Sporny")
37-
.setCharacteristic(Characteristic.Model, "RaspberryPi GPIO Blinds")
38-
.setCharacteristic(Characteristic.SerialNumber, "Version 1.0.0");
39+
.setCharacteristic(Characteristic.Manufacturer, 'Radoslaw Sporny')
40+
.setCharacteristic(Characteristic.Model, 'RaspberryPi GPIO Blinds')
41+
.setCharacteristic(Characteristic.SerialNumber, 'Version 1.0.1');
3942

4043
// use gpio pin numbering
4144
rpio.init({
4245
mapping: 'gpio'
4346
});
4447
rpio.open(this.pinUp, rpio.OUTPUT, this.initialState);
4548
rpio.open(this.pinDown, rpio.OUTPUT, this.initialState);
49+
if (this.pinClosed) rpio.open(this.pinClosed, rpio.INPUT, rpio.PULL_UP);
50+
if (this.pinOpen) rpio.open(this.pinOpen, rpio.INPUT, rpio.PULL_UP);
4651

4752
this.service
4853
.getCharacteristic(Characteristic.CurrentPosition)
@@ -69,6 +74,19 @@ BlindsAccessory.prototype.getCurrentPosition = function(callback) {
6974
}
7075

7176
BlindsAccessory.prototype.getTargetPosition = function(callback) {
77+
if (this.closedAndOutOfSync()) {
78+
this.log("Current position is out of sync, setting to 0");
79+
this.currentPosition = 0;
80+
this.targetPosition = 0;
81+
} else if (this.openAndOutOfSync()) {
82+
this.log("Current position is out of sync, setting to 100");
83+
this.currentPosition = 100;
84+
this.targetPosition = 100;
85+
} else if (this.partiallyOpenAndOutOfSync()) {
86+
this.log("Current position is out of sync, setting to 50");
87+
this.currentPosition = 50;
88+
this.targetPosition = 50;
89+
}
7290
this.log("Target position: %s", this.targetPosition);
7391
callback(null, this.targetPosition);
7492
}
@@ -77,13 +95,13 @@ BlindsAccessory.prototype.setTargetPosition = function(position, callback) {
7795
this.log("Setting target position to %s", position);
7896

7997
if (this.positionState != STATE_STOPPED) {
80-
this.log("Blinds are moving. You need to wait. I will do nothing.");
98+
this.log('Blinds are moving. You need to wait. I will do nothing.');
8199
callback();
82100
return false;
83101
}
84102

85103
if (this.currentPosition == position) {
86-
this.log("Current position already matches target position. There is nothing to do.");
104+
this.log('Current position already matches target position. There is nothing to do.');
87105
callback();
88106
return true;
89107
}
@@ -98,7 +116,7 @@ BlindsAccessory.prototype.setTargetPosition = function(position, callback) {
98116
}
99117

100118
this.log("Duration: %s ms", duration);
101-
this.log(moveUp ? "Moving up" : "Moving down");
119+
this.log(moveUp ? 'Moving up' : 'Moving down');
102120

103121
this.service.setCharacteristic(Characteristic.PositionState, (moveUp ? STATE_INCREASING : STATE_DECREASING));
104122
this.positionState = (moveUp ? STATE_INCREASING : STATE_DECREASING);
@@ -125,6 +143,19 @@ BlindsAccessory.prototype.setFinalBlindsState = function() {
125143
this.log("Successfully moved to target position: %s", this.targetPosition);
126144
}
127145

146+
BlindsAccessory.prototype.closedAndOutOfSync = function() {
147+
return this.currentPosition != 0 && this.pinClosed && (rpio.read(this.pinClosed) == this.reedSwitchActiveState);
148+
}
149+
150+
BlindsAccessory.prototype.openAndOutOfSync = function() {
151+
return this.currentPosition != 100 && this.pinOpen && (rpio.read(this.pinOpen) == this.reedSwitchActiveState);
152+
}
153+
154+
BlindsAccessory.prototype.partiallyOpenAndOutOfSync = function() {
155+
return (this.currentPosition == 0 && this.pinClosed && (rpio.read(this.pinClosed) != this.reedSwitchActiveState)) ||
156+
(this.currentPosition == 100 && this.pinOpen && (rpio.read(this.pinOpen) != this.reedSwitchActiveState));
157+
}
158+
128159
BlindsAccessory.prototype.getServices = function() {
129160
return [this.infoService, this.service];
130161
}

0 commit comments

Comments
 (0)