-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathindex.js
117 lines (97 loc) · 3.9 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
var Service, Characteristic, TargetDoorState, CurrentDoorState;
var rpio = require('rpio');
module.exports = function (homebridge) {
Service = homebridge.hap.Service;
Characteristic = homebridge.hap.Characteristic;
TargetDoorState = Characteristic.TargetDoorState;
CurrentDoorState = Characteristic.CurrentDoorState;
DoorState = homebridge.hap.Characteristic.CurrentDoorState;
homebridge.registerAccessory('homebridge-garage-door-wsensor', 'Garage Door Opener', GarageDoorOpener);
}
function GarageDoorOpener(log, config) {
this.log = log;
this.name = config.name;
this.doorRelayPin = config.doorRelayPin;
this.doorSensorPin = config.doorSensorPin;
this.currentDoorState = CurrentDoorState.CLOSED;
this.targetDoorState = TargetDoorState.CLOSED;
this.invertDoorState = defaultVal(config["invertDoorState"], false);
this.invertSensorState = defaultVal(config['invertSensorState'], false);
this.default = defaultVal(config["default_state"], false);
this.duration = defaultVal(config["duration_ms"], 0);
this.doorState = 0;
this.sensorChange = 0;
this.service = null;
if (!this.doorRelayPin) throw new Error("You must provide a config value for 'doorRelayPin'.");
if (!this.doorSensorPin) throw new Error("You must provide a config value for 'doorSensorPin'.");
if (!is_int(this.duration)) throw new Error("The config value 'duration' must be an integer number of milliseconds.");
this.log("Creating a garage door relay named '%s', initial state: %s", this.name, (this.invertDoorState ? "OPEN" : "CLOSED"));
rpio.open(this.doorRelayPin, rpio.OUTPUT, this.gpioDoorVal(this.invertDoorState));
rpio.open(this.doorSensorPin, rpio.OUTPUT, this.gpioSensorVal(this.invertSensorState));
this.checkSensor(e => {});
}
GarageDoorOpener.prototype.getServices = function () {
this.service = new Service.GarageDoorOpener(this.name, this.name);
this.service.setCharacteristic(TargetDoorState, TargetDoorState.CLOSED);
this.service.setCharacteristic(CurrentDoorState, CurrentDoorState.CLOSED);
this.service.getCharacteristic(CurrentDoorState)
.on('get', this.getSensorStatus.bind(this))
this.service.getCharacteristic(TargetDoorState)
.on('get', this.getSensorStatus.bind(this))
.on('set', this.setDoorOpen.bind(this));
return [this.service];
}
GarageDoorOpener.prototype.getSensorStatus = function (callback) {
callback(null, this.readSensorState());
}
GarageDoorOpener.prototype.checkSensor = function (callback) {
setTimeout(e => {
this.doorState = this.readSensorState();
if (this.doorState !== this.sensorChange){
this.service.getCharacteristic(TargetDoorState).updateValue(this.doorState);
this.service.getCharacteristic(CurrentDoorState).updateValue(this.doorState);
this.sensorChange = this.doorState;
}
this.checkSensor(callback);
}, 500);
callback(null);
}
GarageDoorOpener.prototype.readSensorState = function () {
var val = this.gpioSensorVal(rpio.read(this.doorSensorPin));
return val == rpio.HIGH;
}
GarageDoorOpener.prototype.setState = function (val) {
rpio.write(this.doorRelayPin, this.gpioDoorVal(val));
}
GarageDoorOpener.prototype.setDoorOpen = function (newState, callback) {
if (this.timerid !== -1) {
clearTimeout(this.timerid);
this.timerid = -1;
}
this.setState(newState);
if (this.duration > 0) {
this.timerid = setTimeout(this.timeOutCB, this.duration, this);
}
callback(null);
}
GarageDoorOpener.prototype.timeOutCB = function (o) {
o.setState(0);
o.timerid = -1;
}
GarageDoorOpener.prototype.gpioSensorVal = function (val) {
if (!this.invertSensorState) val = !val;
return val ? rpio.HIGH : rpio.LOW;
}
GarageDoorOpener.prototype.gpioDoorVal = function (val) {
if (this.invertDoorState) val = !val;
return val ? rpio.HIGH : rpio.LOW;
}
var is_int = function (n) {
return n % 1 === 0;
}
var is_defined = function (v) {
return typeof v !== 'undefined';
}
var defaultVal = function (v, dflt) {
return is_defined(v) ? v : dflt;
}