Skip to content

Commit e1b408b

Browse files
committed
Initial commit
0 parents  commit e1b408b

File tree

10 files changed

+2181
-0
lines changed

10 files changed

+2181
-0
lines changed

.editorconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
root = true
2+
3+
[*]
4+
end_of_line = lf
5+
insert_final_newline = true
6+
indent_size = 4
7+
indent_style = space
8+
9+
[*.js]
10+
trim_trailing_whitespace = true

.github/ISSUE_TEMPLATE/Bug_Report.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
### Describe the Bug
2+
<!-- Describe the issue in full detail. -->
3+
4+
### Reproducing the Bug
5+
<!-- Using the provided list below, what did you do to get this bug. -->
6+
1.
7+
2.
8+
3.
9+
4.
10+
5.
11+
12+
### Expected Behavior
13+
<!-- What did you expect, and what happened. -->
14+
15+
### System Information
16+
Include with your bug report Node and Homebridge version info:
17+
1. Get access to a console (e.g. Terminal) on where the plugin resides.
18+
2. Paste this command: `node --version`.
19+
3. Replace the response `[Paste Node version here]` with the answer.
20+
4. Paste this command: `homebridge --version`.
21+
5. Replace the response `[Paste Homebridge version here]` with the answer.
22+
6. That's it!
23+
24+
```text
25+
Node version: [Paste Node version here]
26+
Homebridge version: [Paste Homebridge version here]
27+
```
28+
29+
### Debug Log Output
30+
To get the debug information, set the `debug` setting to `true`. Re-run the plugin, reproduce the issue, then paste the logs below where marked.
31+
32+
Remember to omit any usernames, passwords, and logs from other plugins. Thanks!
33+
34+
```sh
35+
Replace ONLY this line. DO NOT replace the line above or below me!
36+
```
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
### Describe the Feature
2+
<!-- Is the feature related to a problem? Explain the frustration here! -->
3+
4+
### Describe the Solution
5+
<!-- A clear and concise description of what you want to happen. -->
6+
7+
### Describe the Alternatives
8+
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
9+
10+
### Additional Context
11+
<!-- Add any other context or screenshots about the feature request here. -->

.gitignore

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
### macOS ###
2+
*.DS_Store
3+
.AppleDouble
4+
.LSOverride
5+
._*
6+
.DocumentRevisions-V100
7+
.fseventsd
8+
.Spotlight-V100
9+
.TemporaryItems
10+
.Trashes
11+
.VolumeIcon.icns
12+
.com.apple.timemachine.donotpresent
13+
.AppleDB
14+
.AppleDesktop
15+
Network Trash Folder
16+
Temporary Items
17+
.apdisk
18+
19+
### Linux ###
20+
*~
21+
.fuse_hidden*
22+
.directory
23+
.Trash-*
24+
.nfs*
25+
26+
### Windows ###
27+
Thumbs.db
28+
ehthumbs.db
29+
ehthumbs_vista.db
30+
Desktop.ini
31+
$RECYCLE.BIN/
32+
*.lnk
33+
34+
### Node Stack ###
35+
node_modules/
36+
package-lock.json
37+
38+
### WebStorm+all Patch ###
39+
.idea/
40+
*.iml
41+
modules.xml
42+
.idea/misc.xml
43+
*.ipr

LICENSE

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
ISC License
2+
3+
Copyright (c) 2019, Jacky Liang
4+
5+
Permission to use, copy, modify, and/or distribute this software for any
6+
purpose with or without fee is hereby granted, provided that the above
7+
copyright notice and this permission notice appear in all copies.
8+
9+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

README.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
ADT Pulse for Homebridge
2+
=========================
3+
4+
This is a Homebridge plugin for ADT Pulse users that allows homeowners to control their security systems and view sensor status through HomeKit. The API relies mostly on the ADT Pulse Portal (powered by Icontrol One).
5+
6+
To use this plugin, here are two simple steps you need to follow:
7+
1. Run `npm install homebridge-adt-pulse`
8+
1. You can also search `adt-pulse` using Onzu's Homebridge user interface.
9+
2. Configure the plugin using the example below.
10+
11+
## Configuration
12+
When configuring this plugin, simply add the platform to your existing `config.json` file. Mind that the `platform` name must always be `ADTPulse`.
13+
```json
14+
{
15+
"platforms": [
16+
{
17+
"platform": "ADTPulse",
18+
"name": "ADT-Pulse",
19+
"username": "email@email.com",
20+
"password": "1234567890",
21+
"debug": false,
22+
"refreshInterval": 15,
23+
"syncInterval": 30
24+
},
25+
{
26+
"platform": "...",
27+
"name": "..."
28+
}
29+
]
30+
}
31+
```
32+
33+
## Plugin Limitations
34+
Even though the name is stated as "ADT Pulse for Homebridge", this Homebridge plugin is limited in the hardware it may support. This plugin is not a complete replacement to the [official ADT Pulse app](https://www.adt.com/help/faq/adt-pulse/adt-pulse-mobile-app).
35+
36+
The supported hardware configurations are listed below:
37+
1. ADT Security Panel (`system`)
38+
2. ADT Door/Window Sensors (`doorWindow`)
39+
3. ADT Glass Break Detectors (`glass`)
40+
4. ADT Motion Sensors (`motion`)
41+
5. ADT Carbon Monoxide Detector (`co`)
42+
6. ADT Fire (Smoke/Heat) Detector (`fire`)
43+
44+
If you have a sensor that is unsupported by this plugin, [request a feature](https://github.com/mrjackyliang/homebridge-adt-pulse/issues/new?template=Feature_Request.md) so I can add support for it into the plugin.
45+
46+
Please mind that I DO NOT have plans to support smart devices or cameras connected to the ADT Pulse service. I recommend using another `homebridge-plugin` for that.
47+
48+
## Test Script
49+
There is a test script included in the package that performs specific actions used by the plugin. Feel free to test it out, and report any bugs you see.
50+
51+
This script requires your username, password, and an action type.
52+
```shell script
53+
node adt-pulse-test.js --username email@email.com --password 12345667890 --action [device-status,zone-status,sync,disarm,arm-away,arm-stay] --debug [true,false]
54+
```
55+
56+
## Developer Information
57+
The script provides an active connection to the ADT Pulse portal. Here are a list of must knows, just in case you might want to debug (or improve) the plugin:
58+
59+
1. Sync codes are polled every 30 seconds (by default). Only thing stopping it is if there are more than 2 login failures.
60+
2. Device updates are also polled every 15 seconds (by default) and retrieved from the cached data created through the sync code changes above so to not pound the external servers.
61+
3. Current version is `16.0.0-131`. If Web Portal version is changed or updated, a warning will appear in the logs. Please [create a bug report](https://github.com/mrjackyliang/homebridge-adt-pulse/issues/new?template=Bug_Report.md) to let me know!
62+
63+
## Credits and Appreciation
64+
If you would like to show your appreciation for its continued development, you can optionally make a small donation to my company, [CBN Ventures](https://cbnventures.io), through [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=L59Y27M66FG26&source=url).
65+
66+
Also, giving HUGE thanks to [@kevinmkickey](https://github.com/kevinmhickey/adt-pulse) for providing the ADT Pulse script. This plugin (or any other unofficial ADT Pulse plugin) would not have happened without this script.

adt-pulse-test.js

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
/**
2+
* ADT Pulse Test.
3+
*
4+
* Test the ADT Pulse API responses using this script.
5+
*
6+
* Arguments:
7+
* --username email@email.com
8+
* --password 1234567890
9+
* --action [device-status,zone-status,sync,disarm,arm-away,arm-stay]
10+
* --debug [true,false]
11+
*
12+
* Usage:
13+
* node adt-pulse-test.js --username ! --password % --action @ --debug #
14+
*
15+
* Replace:
16+
* ! - Account username
17+
* % - Account password
18+
* @ - Action type
19+
* # - Debug value
20+
*
21+
* @type {(function(Object): void)|*}
22+
*
23+
* @since 1.0.0
24+
*/
25+
const Pulse = require("./adt-pulse");
26+
27+
/**
28+
* Setup script arguments.
29+
*
30+
* @since 1.0.0
31+
*/
32+
const username = process.argv.indexOf("--username");
33+
const password = process.argv.indexOf("--password");
34+
const action = process.argv.indexOf("--action");
35+
const debug = process.argv.indexOf("--debug");
36+
let usernameValue = (username > -1) ? process.argv[username + 1] : "";
37+
let passwordValue = (password > -1) ? process.argv[password + 1] : "";
38+
let actionValue = (action > -1) ? process.argv[action + 1] : "";
39+
let debugValue = (debug > -1) ? process.argv[debug + 1] : "false";
40+
41+
/**
42+
* Sanitize arguments.
43+
*
44+
* @since 1.0.0
45+
*/
46+
if (!usernameValue) {
47+
console.error("ADT Pulse Test: Username is empty.");
48+
return;
49+
}
50+
if (!passwordValue) {
51+
console.error("ADT Pulse Test: Password is empty.");
52+
return;
53+
}
54+
if (!actionValue) {
55+
console.error("ADT Pulse Test: Action is empty.");
56+
return;
57+
}
58+
if (debugValue === "true") {
59+
debugValue = true;
60+
console.log("ADT Pulse Test: Debug mode on.");
61+
} else {
62+
debugValue = false;
63+
console.log("ADT Pulse Test: Debug mode off.");
64+
}
65+
66+
/**
67+
* Initialize ADT Pulse function.
68+
*
69+
* @type {pulse}
70+
*
71+
* @since 1.0.0
72+
*/
73+
let myAlarm = new Pulse({
74+
"username": usernameValue,
75+
"password": passwordValue,
76+
"debug": debugValue,
77+
});
78+
79+
/**
80+
* ADT Pulse actions.
81+
*
82+
* @since 1.0.0
83+
*/
84+
switch (actionValue) {
85+
case "device-status":
86+
console.log("ADT Pulse Test: Getting device status...");
87+
88+
myAlarm
89+
.login()
90+
.then(() => myAlarm.getDeviceStatus())
91+
.then((status) => {
92+
console.log("==============================");
93+
console.log(status);
94+
console.log("==============================");
95+
})
96+
.then(() => myAlarm.logout());
97+
break;
98+
case "zone-status":
99+
console.log("ADT Pulse Test: Getting zone status...");
100+
101+
myAlarm
102+
.login()
103+
.then(() => myAlarm.getZoneStatus())
104+
.then((statuses) => {
105+
console.log("==============================");
106+
console.log(statuses);
107+
console.log("==============================");
108+
})
109+
.then(() => myAlarm.logout());
110+
break;
111+
case "sync":
112+
console.log("ADT Pulse Test: Performing portal sync...");
113+
114+
myAlarm
115+
.login()
116+
.then(() => myAlarm.performPortalSync())
117+
.then((syncCode) => {
118+
console.log("==============================");
119+
console.log(syncCode);
120+
console.log("==============================");
121+
})
122+
.then(() => myAlarm.logout());
123+
break;
124+
case "disarm":
125+
console.log("ADT Pulse Test: Disarming...");
126+
127+
myAlarm
128+
.login()
129+
.then(() => myAlarm.getDeviceStatus())
130+
.then((status) => {
131+
console.log("==============================");
132+
console.log(status);
133+
console.log("==============================");
134+
})
135+
.then(async () => {
136+
// setDeviceStatus function may fail because a wrong armState was set.
137+
await myAlarm.setDeviceStatus("away", "off");
138+
})
139+
.then(() => {
140+
setTimeout(() => {
141+
myAlarm
142+
.getDeviceStatus()
143+
.then((status) => {
144+
console.log("==============================");
145+
console.log(status);
146+
console.log("==============================");
147+
})
148+
.then(() => myAlarm.logout());
149+
}, 1000);
150+
});
151+
break;
152+
case "arm-away":
153+
console.log("ADT Pulse Test: Arming away...");
154+
155+
myAlarm
156+
.login()
157+
.then(() => myAlarm.getDeviceStatus())
158+
.then((status) => {
159+
console.log("==============================");
160+
console.log(status);
161+
console.log("==============================");
162+
})
163+
.then(async () => {
164+
// setDeviceStatus function may fail because a wrong armState was set.
165+
await myAlarm.setDeviceStatus("disarmed", "away");
166+
})
167+
.then(() => {
168+
setTimeout(() => {
169+
myAlarm
170+
.getDeviceStatus()
171+
.then((status) => {
172+
console.log("==============================");
173+
console.log(status);
174+
console.log("==============================");
175+
})
176+
.then(() => myAlarm.logout());
177+
}, 1000);
178+
});
179+
break;
180+
case "arm-stay":
181+
console.log("ADT Pulse Test: Arming stay...");
182+
183+
myAlarm
184+
.login()
185+
.then(() => myAlarm.getDeviceStatus())
186+
.then((status) => {
187+
console.log("==============================");
188+
console.log(status);
189+
console.log("==============================");
190+
})
191+
.then(async () => {
192+
// setDeviceStatus function may fail because a wrong armState was set.
193+
await myAlarm.setDeviceStatus("disarmed", "stay");
194+
})
195+
.then(() => {
196+
setTimeout(() => {
197+
myAlarm
198+
.getDeviceStatus()
199+
.then((status) => {
200+
console.log("==============================");
201+
console.log(status);
202+
console.log("==============================");
203+
})
204+
.then(() => myAlarm.logout());
205+
}, 1000);
206+
});
207+
break;
208+
default:
209+
console.error(`ADT Pulse Test: Unknown action type ${actionValue}.`);
210+
break;
211+
}

0 commit comments

Comments
 (0)