homebridge-ismartgate-sensor 1.4.3
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/.gitattributes +2 -0
- package/CHANGELOG.md +8 -0
- package/LICENSE +21 -0
- package/README.md +13 -0
- package/config.schema.json +76 -0
- package/index.js +212 -0
- package/package.json +38 -0
package/.gitattributes
ADDED
package/CHANGELOG.md
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2019 codyc1515
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# homebridge-ismartgate
|
|
2
|
+
Forked from [homebridge-ismartgate](https://github.com/codyc1515/homebridge-ismartgate) which is no longer support and has been archived.
|
|
3
|
+
|
|
4
|
+
[Homebridge](https://github.com/nfarina/homebridge) plug-in for iSmartGate HomeKit devices to expose their Temperature & Battery services, which would otherwise be hidden.
|
|
5
|
+
|
|
6
|
+
## Things to know
|
|
7
|
+
* Supports only a single garage door / gate
|
|
8
|
+
* Only exposes the Temperature & Battery services, as the device already has HomeKit support for the Garage Door service. If you need a Garage Door service as well, take a look at the plug-in [homebridge-gogogate2](https://www.npmjs.com/package/homebridge-gogogate2).
|
|
9
|
+
* Only the iSmartGate Gate Lite is supported. While no other devices have been tested, I see no reason that they should not work.
|
|
10
|
+
|
|
11
|
+
### Legal
|
|
12
|
+
* Licensed under [MIT](LICENSE)
|
|
13
|
+
* This is not an official plug-in and is not affiliated with iSmartGate in any way
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"pluginAlias":"iSmartGate",
|
|
3
|
+
"headerDisplay":null,
|
|
4
|
+
"pluginType":"accessory",
|
|
5
|
+
"singular":true,
|
|
6
|
+
"schema":{
|
|
7
|
+
"type":"object",
|
|
8
|
+
"properties":{
|
|
9
|
+
"name":{
|
|
10
|
+
"title":"Accessory Name",
|
|
11
|
+
"type":"string",
|
|
12
|
+
"format":"string",
|
|
13
|
+
"default":"iSmartGate Sensor",
|
|
14
|
+
"description":"The name of your device to show in the Home app",
|
|
15
|
+
"minLength": 1,
|
|
16
|
+
"required": true
|
|
17
|
+
},
|
|
18
|
+
"username":{
|
|
19
|
+
"title":"Username",
|
|
20
|
+
"type":"string",
|
|
21
|
+
"format":"string",
|
|
22
|
+
"placeholder":"admin",
|
|
23
|
+
"description": "Default: admin",
|
|
24
|
+
"minLength": 1,
|
|
25
|
+
"required": true
|
|
26
|
+
},
|
|
27
|
+
"password":{
|
|
28
|
+
"title":"Password",
|
|
29
|
+
"type":"string",
|
|
30
|
+
"format":"password",
|
|
31
|
+
"description": "Configured during device setup",
|
|
32
|
+
"minLength": 1,
|
|
33
|
+
"required": true
|
|
34
|
+
},
|
|
35
|
+
"hostname":{
|
|
36
|
+
"title":"Hostname or IP address",
|
|
37
|
+
"type":"string",
|
|
38
|
+
"format":"string",
|
|
39
|
+
"default":"ismartgate.local",
|
|
40
|
+
"description": "Host name or local IP address",
|
|
41
|
+
"minLength": 1,
|
|
42
|
+
"required": true
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"layout":[
|
|
47
|
+
{
|
|
48
|
+
"type":"flex",
|
|
49
|
+
"flex-flow":"row wrap",
|
|
50
|
+
"items":[
|
|
51
|
+
{
|
|
52
|
+
"key":"name",
|
|
53
|
+
"type":"string"
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"type":"flex",
|
|
59
|
+
"flex-flow":"row wrap",
|
|
60
|
+
"items":[
|
|
61
|
+
{
|
|
62
|
+
"key":"username",
|
|
63
|
+
"type":"string"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"key":"password",
|
|
67
|
+
"type":"password"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"key":"hostname",
|
|
71
|
+
"type":"string"
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
}
|
package/index.js
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
let axios = require("axios")
|
|
2
|
+
//mdns = require('mdns-js'); ///"mdns-js": "^1.0.3",
|
|
3
|
+
|
|
4
|
+
var API,
|
|
5
|
+
Accessory,
|
|
6
|
+
Characteristic,
|
|
7
|
+
Service;
|
|
8
|
+
|
|
9
|
+
module.exports = function(homebridge) {
|
|
10
|
+
API = homebridge;
|
|
11
|
+
Accessory = homebridge.hap.Accessory;
|
|
12
|
+
Characteristic = homebridge.hap.Characteristic;
|
|
13
|
+
Service = homebridge.hap.Service;
|
|
14
|
+
|
|
15
|
+
homebridge.registerAccessory("homebridge-ismartgate-sensor", "iSmartGate", iSmartGate);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
function iSmartGate(log, config) {
|
|
19
|
+
this.log = log;
|
|
20
|
+
this.name = config["name"] || "iSmartGate Temperature";
|
|
21
|
+
this.username = config["username"];
|
|
22
|
+
this.password = config["password"];
|
|
23
|
+
this.hostname = config["hostname"];
|
|
24
|
+
this.response = null;
|
|
25
|
+
this.cookie = null
|
|
26
|
+
|
|
27
|
+
this.CurrentTemperature = null;
|
|
28
|
+
this.BatteryLevel = null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
iSmartGate.prototype = {
|
|
32
|
+
|
|
33
|
+
identify: function(callback) {
|
|
34
|
+
this.log.info("identify");
|
|
35
|
+
callback();
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
getServices: function() {
|
|
39
|
+
|
|
40
|
+
// Temperature Sensor service
|
|
41
|
+
this.TemperatureSensor = new Service.TemperatureSensor(this.name);
|
|
42
|
+
|
|
43
|
+
// Battery service
|
|
44
|
+
this.BatteryService = new Service.Battery(this.name);
|
|
45
|
+
|
|
46
|
+
// Accessory Information service
|
|
47
|
+
this.AccessoryInformation = new Service.AccessoryInformation();
|
|
48
|
+
this.AccessoryInformation
|
|
49
|
+
.setCharacteristic(Characteristic.Name, this.name)
|
|
50
|
+
.setCharacteristic(Characteristic.Manufacturer, "iSmartGate")
|
|
51
|
+
.setCharacteristic(Characteristic.Model, "Temperature")
|
|
52
|
+
.setCharacteristic(Characteristic.FirmwareRevision, "1.4.2")
|
|
53
|
+
.setCharacteristic(Characteristic.SerialNumber, this.username);
|
|
54
|
+
|
|
55
|
+
/*
|
|
56
|
+
// Start searching for the iSmartGate using mDNS
|
|
57
|
+
var browser = mdns.createBrowser("_hap._tcp");
|
|
58
|
+
browser.on('ready', function() { browser.discover(); });
|
|
59
|
+
browser.on('update', function(data) {
|
|
60
|
+
if(data['txt']) {
|
|
61
|
+
data['txt'].forEach(txt => {
|
|
62
|
+
txt = txt.split("=");
|
|
63
|
+
if(txt[0] == "md" && txt[1] == "iSmartGate" && data.addresses[0] != this.hostname) {
|
|
64
|
+
// Set the new hostname obtained from mDNS
|
|
65
|
+
this.hostname = data.addresses[0];
|
|
66
|
+
this.log.info("Found an iSmartGate at", this.hostname);
|
|
67
|
+
|
|
68
|
+
// Login to the iSmartGate for the first time and refresh
|
|
69
|
+
setTimeout(function() {
|
|
70
|
+
this._login();
|
|
71
|
+
}.bind(this), 2500);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}.bind(this));
|
|
76
|
+
*/
|
|
77
|
+
|
|
78
|
+
// Login to the iSmartGate for the first time and refresh
|
|
79
|
+
setTimeout(function() {
|
|
80
|
+
this.response=this._login();
|
|
81
|
+
}.bind(this), 2500);
|
|
82
|
+
|
|
83
|
+
setTimeout(function() {
|
|
84
|
+
this._refresh();
|
|
85
|
+
}.bind(this), 5000);
|
|
86
|
+
|
|
87
|
+
// Set a timer to refresh the data every 10 minutes
|
|
88
|
+
setInterval(function() {
|
|
89
|
+
this._refresh();
|
|
90
|
+
}.bind(this), 600000);
|
|
91
|
+
|
|
92
|
+
// Set a timer to refresh the login token every 3 hours
|
|
93
|
+
setInterval(function() {
|
|
94
|
+
this.response=this._login();
|
|
95
|
+
}.bind(this), 10800000);
|
|
96
|
+
|
|
97
|
+
// Return the Accessory
|
|
98
|
+
return [
|
|
99
|
+
this.AccessoryInformation,
|
|
100
|
+
this.TemperatureSensor,
|
|
101
|
+
this.BatteryService
|
|
102
|
+
];
|
|
103
|
+
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
_login: async function() {
|
|
107
|
+
try {
|
|
108
|
+
this.log.info('Retrieving token')
|
|
109
|
+
let response = await axios({
|
|
110
|
+
withCredentials: true,
|
|
111
|
+
method: 'post',
|
|
112
|
+
url: `http://${this.hostname}/index.php`,
|
|
113
|
+
headers: {
|
|
114
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
115
|
+
'Accept-Encoding': 'gzip,deflate,compress',
|
|
116
|
+
},
|
|
117
|
+
data: {
|
|
118
|
+
"MIME Type": "application/x-www-form-urlencoded",
|
|
119
|
+
"login": this.username,
|
|
120
|
+
"pass": this.password,
|
|
121
|
+
"send-login": "Sign in"
|
|
122
|
+
},
|
|
123
|
+
responseType: 'text'
|
|
124
|
+
}).catch(err => {
|
|
125
|
+
this.log.debug(JSON.stringify(err, null, 2))
|
|
126
|
+
this.log.error('Error signing in and getting token %s', err.message)
|
|
127
|
+
if (err.response) { this.log.warn(JSON.stringify(err.response.data, null, 2))}
|
|
128
|
+
return err.response
|
|
129
|
+
})
|
|
130
|
+
if (response.status == 200) {
|
|
131
|
+
this.log.info("Logged into iSmartGate succesfully");
|
|
132
|
+
this.log.debug('signin response', response.headers)
|
|
133
|
+
this.cookie=response.headers['set-cookie']
|
|
134
|
+
return response
|
|
135
|
+
}
|
|
136
|
+
} catch (err) { this.log.error('Error retrieving token \n%s', err)}
|
|
137
|
+
},
|
|
138
|
+
|
|
139
|
+
_refresh: async function() {
|
|
140
|
+
try {
|
|
141
|
+
this.log.debug("Start refreshing temperature & battery");
|
|
142
|
+
let response = await axios({
|
|
143
|
+
withCredentials: true,
|
|
144
|
+
method: 'get',
|
|
145
|
+
url: `http://${this.hostname}/isg/temperature.php`,
|
|
146
|
+
headers: {
|
|
147
|
+
'Cookie': this.cookie
|
|
148
|
+
},
|
|
149
|
+
params: {
|
|
150
|
+
door: 1
|
|
151
|
+
},
|
|
152
|
+
responseType: 'json'
|
|
153
|
+
}).catch(err => {
|
|
154
|
+
this.log.debug(JSON.stringify(err, null, 2))
|
|
155
|
+
this.log.error('Error fetching temperature & battery %s', err.message)
|
|
156
|
+
if (err.response) { this.log.warn(JSON.stringify(err.response.data, null, 2))}
|
|
157
|
+
return err.response
|
|
158
|
+
})
|
|
159
|
+
if (response.status == 200 && Array.isArray(response.data)) {
|
|
160
|
+
this.log.debug("Obtained status.", response.data);
|
|
161
|
+
|
|
162
|
+
// Find the CurrentTemperature
|
|
163
|
+
this.CurrentTemperature = response.data[0] / 1000;
|
|
164
|
+
|
|
165
|
+
// Find the BatteryLevel
|
|
166
|
+
switch (response.data[1]) {
|
|
167
|
+
case "full": this.BatteryLevel = 100; break;
|
|
168
|
+
case "80": this.BatteryLevel = 80; break;
|
|
169
|
+
case "60": this.BatteryLevel = 60; break;
|
|
170
|
+
case "40": this.BatteryLevel = 40; break;
|
|
171
|
+
case "20": this.BatteryLevel = 20; break;
|
|
172
|
+
case "low": this.BatteryLevel = 10; break;
|
|
173
|
+
|
|
174
|
+
default:
|
|
175
|
+
this.log.warn("Unexpected BatteryLevel detected.", response.data);
|
|
176
|
+
this.BatteryLevel = 0;
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Set the Current Temperature
|
|
181
|
+
this.TemperatureSensor.getCharacteristic(Characteristic.CurrentTemperature).updateValue(this.CurrentTemperature);
|
|
182
|
+
|
|
183
|
+
// Set the Battery Level
|
|
184
|
+
this.BatteryService.setCharacteristic(Characteristic.BatteryLevel, this.BatteryLevel);
|
|
185
|
+
|
|
186
|
+
// Set the Status Low Battery
|
|
187
|
+
if(this.BatteryLevel <= 10) {this.BatteryService.setCharacteristic(Characteristic.StatusLowBattery, Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW);}
|
|
188
|
+
else {this.BatteryService.setCharacteristic(Characteristic.StatusLowBattery, Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL);}
|
|
189
|
+
return response
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
if(response.data == "Restricted Access") {this.log.error("Restricted Access", response.data);}
|
|
193
|
+
else if(response.data == "Login Token Expired") {this.log.error("Login Token Expired", response.data);}
|
|
194
|
+
else {
|
|
195
|
+
this.log.error("Could not connect.", "Check http://" + this.hostname + " to make sure the device is still reachable & no captcha is showing.");
|
|
196
|
+
this.log.error(response.data);}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
} catch (err) { this.log.error('Error retrieving temperature & battery \n%s', err)}
|
|
200
|
+
},
|
|
201
|
+
|
|
202
|
+
_getValue: function(CharacteristicName, callback) {
|
|
203
|
+
this.log.debug("GET", CharacteristicName);
|
|
204
|
+
callback(null);
|
|
205
|
+
},
|
|
206
|
+
|
|
207
|
+
_setValue: function(CharacteristicName, value, callback) {
|
|
208
|
+
this.log.debug("SET", CharacteristicName, value);
|
|
209
|
+
callback();
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "homebridge-ismartgate-sensor",
|
|
3
|
+
"displayName": "ismartgate sensor",
|
|
4
|
+
"version": "1.4.3",
|
|
5
|
+
"author": "John Valiquette",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"axios": "^1.7.7"
|
|
8
|
+
},
|
|
9
|
+
"deprecated": false,
|
|
10
|
+
"description": "Homebridge plug-in for iSmartGate HomeKit devices to expose their Temperature & Battery sensor, which would otherwise be hidden.",
|
|
11
|
+
"engines": {
|
|
12
|
+
"homebridge": "^1.8.0 || ^2.0.0-beta.0",
|
|
13
|
+
"node": "^18.20.0 || ^20.17.0 || ^22.9.0"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"homebridge-plugin",
|
|
17
|
+
"homekit",
|
|
18
|
+
"ismartgate",
|
|
19
|
+
"gogogate",
|
|
20
|
+
"garage",
|
|
21
|
+
"door",
|
|
22
|
+
"temperature",
|
|
23
|
+
"battery"
|
|
24
|
+
],
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"main": "index.js",
|
|
27
|
+
"homepage": "https://github.com/valiquette/homebridge-ismartgate-sensor/blob/master/README.md",
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "git+https://github.com/valiquette/homebridge-ismartgate-sensor"
|
|
31
|
+
},
|
|
32
|
+
"bugs": {
|
|
33
|
+
"url": "https://github.com/codyc1515/homebridge-ismartgate/issues"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
37
|
+
}
|
|
38
|
+
}
|