homebridge-gpio-electic-rim-lock 2.1.1 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/config.schema.json +1 -0
- package/index.js +115 -86
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -51,3 +51,8 @@ Fields:
|
|
|
51
51
|
* name - The door name visible in HomeKit, can be anything (required).
|
|
52
52
|
* pin - The physical GPIO pin number that controls the relay (required).
|
|
53
53
|
* duratin - Number of milliseconds to trigger the relay. Defaults to 500 millseconds (0,5 second) if not specified.
|
|
54
|
+
|
|
55
|
+
## Compatibility
|
|
56
|
+
|
|
57
|
+
This plugin is designed to run **only on Raspberry Pi** hardware because it uses the `rpio` library for GPIO access.
|
|
58
|
+
It **will not work on other Linux systems** or in Docker containers without GPIO support.
|
package/config.schema.json
CHANGED
package/index.js
CHANGED
|
@@ -1,99 +1,128 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
|
|
2
3
|
var Service, Characteristic;
|
|
3
4
|
var rpio = require('rpio');
|
|
5
|
+
var os = require('os');
|
|
4
6
|
|
|
5
7
|
module.exports = function(homebridge) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
Service = homebridge.hap.Service;
|
|
9
|
+
Characteristic = homebridge.hap.Characteristic;
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
homebridge.registerAccessory(
|
|
12
|
+
'homebridge-gpio-electic-rim-lock',
|
|
13
|
+
'Tiro',
|
|
14
|
+
ElecticRimLockAccessory
|
|
15
|
+
);
|
|
16
|
+
};
|
|
11
17
|
|
|
12
|
-
function getSerial(){
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
function getSerial() {
|
|
19
|
+
var fs = require('fs');
|
|
20
|
+
var cpuinfo = fs.readFileSync('/proc/cpuinfo', 'utf8');
|
|
21
|
+
var match = cpuinfo.match(/Serial\s*:\s*([a-f0-9]+)/i);
|
|
22
|
+
return match ? match[1] : null;
|
|
17
23
|
}
|
|
18
24
|
|
|
19
25
|
function ElecticRimLockAccessory(log, config) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
26
|
+
this.log = log;
|
|
27
|
+
this.name = config['name'];
|
|
28
|
+
this.pin = config['pin'];
|
|
29
|
+
this.duration = config['duration'];
|
|
30
|
+
this.version = require('./package.json').version;
|
|
31
|
+
this.lastLockTargetState = 1;
|
|
32
|
+
|
|
33
|
+
// Check configuration
|
|
34
|
+
if (!this.name || !this.pin) {
|
|
35
|
+
this.log.warn("⚠ RimLock not configured correctly: name or pin missing. Plugin is disabled.");
|
|
36
|
+
this.disabled = true;
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Warn if not running on Raspberry Pi
|
|
41
|
+
if (os.arch() !== 'arm') {
|
|
42
|
+
this.log.warn("⚠ This plugin is intended to run only on Raspberry Pi. Some features may not work.");
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (this.duration == null || this.duration % 1 !== 0) this.duration = 500;
|
|
46
|
+
|
|
47
|
+
this.log("Tiro GPIO version: " + this.version);
|
|
48
|
+
this.log("Switch pin: " + this.pin);
|
|
49
|
+
this.log("Active time: " + this.duration + " ms");
|
|
36
50
|
}
|
|
37
51
|
|
|
38
52
|
ElecticRimLockAccessory.prototype = {
|
|
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
|
-
|
|
53
|
+
|
|
54
|
+
getServices: function() {
|
|
55
|
+
if (this.disabled) {
|
|
56
|
+
this.log.warn("Plugin disabled, no services will be registered.");
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let informationService = new Service.AccessoryInformation();
|
|
61
|
+
informationService
|
|
62
|
+
.setCharacteristic(Characteristic.Manufacturer, "Roberto Montanari")
|
|
63
|
+
.setCharacteristic(Characteristic.Model, "Tiro GPIO")
|
|
64
|
+
.setCharacteristic(Characteristic.SerialNumber, getSerial() + this.pin)
|
|
65
|
+
.setCharacteristic(Characteristic.FirmwareRevision, this.version);
|
|
66
|
+
|
|
67
|
+
let lockMechanismService = new Service.LockMechanism(this.name);
|
|
68
|
+
lockMechanismService
|
|
69
|
+
.getCharacteristic(Characteristic.LockCurrentState)
|
|
70
|
+
.on('get', this.getLockCurrentState.bind(this));
|
|
71
|
+
lockMechanismService
|
|
72
|
+
.getCharacteristic(Characteristic.LockTargetState)
|
|
73
|
+
.on('get', this.getLockTargetState.bind(this))
|
|
74
|
+
.on('set', this.setLockTargetState.bind(this));
|
|
75
|
+
|
|
76
|
+
this.informationService = informationService;
|
|
77
|
+
this.lockMechanismService = lockMechanismService;
|
|
78
|
+
|
|
79
|
+
return [informationService, lockMechanismService];
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
getLockCurrentState: function(callback) {
|
|
83
|
+
if (this.lastLockTargetState === 0) {
|
|
84
|
+
this.lastLockTargetState = 1;
|
|
85
|
+
callback(null, 0);
|
|
86
|
+
} else {
|
|
87
|
+
callback(null, 1);
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
getLockTargetState: function(callback) {
|
|
92
|
+
this.lastLockTargetState = 1;
|
|
93
|
+
callback(null, 1);
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
setLockTargetState: function(state, callback) {
|
|
97
|
+
if (this.disabled) {
|
|
98
|
+
this.log.warn("Plugin disabled, command ignored.");
|
|
99
|
+
return callback(null);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (state === 0) { // Unlock
|
|
103
|
+
this.writePin(1);
|
|
104
|
+
this.log("Waiting for " + this.duration + " ms");
|
|
105
|
+
setTimeout(() => this.writePin(0), this.duration);
|
|
106
|
+
this.log("Lock state set to OPEN");
|
|
107
|
+
this.lastLockTargetState = 0;
|
|
108
|
+
callback(null);
|
|
109
|
+
} else { // Lock
|
|
110
|
+
this.writePin(0);
|
|
111
|
+
this.log("Lock state set to CLOSED");
|
|
112
|
+
this.lastLockTargetState = 1;
|
|
113
|
+
callback(null);
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
writePin: function(val) {
|
|
118
|
+
if (this.disabled) return;
|
|
119
|
+
|
|
120
|
+
try {
|
|
121
|
+
rpio.open(this.pin, rpio.OUTPUT, rpio.LOW);
|
|
122
|
+
rpio.write(this.pin, val);
|
|
123
|
+
this.log("GPIO pin " + this.pin + " set " + (val === 0 ? "OFF" : "ON"));
|
|
124
|
+
} catch (err) {
|
|
125
|
+
this.log.error("GPIO error on pin " + this.pin + ": " + err.message);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-gpio-electic-rim-lock",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "Homebridge plugin to open electric rim locks via Raspberry Pi GPIO pins",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
},
|
|
13
13
|
"keywords": [
|
|
14
14
|
"homebridge-plugin",
|
|
15
|
+
"homebridge-gpio",
|
|
16
|
+
"raspberry-pi-only",
|
|
15
17
|
"homebridge",
|
|
16
18
|
"homekit",
|
|
17
19
|
"smart home",
|