homebridge-adt-pulse 2.2.0 → 3.0.0-beta.10
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/LICENSE +1 -1
- package/README.md +150 -111
- package/build/config.schema.json +320 -0
- package/build/src/index.js +6 -0
- package/build/src/index.js.map +1 -0
- package/build/src/lib/accessory.js +239 -0
- package/build/src/lib/accessory.js.map +1 -0
- package/build/src/lib/api.js +1876 -0
- package/build/src/lib/api.js.map +1 -0
- package/build/src/lib/detect.js +595 -0
- package/build/src/lib/detect.js.map +1 -0
- package/build/src/lib/platform.js +446 -0
- package/build/src/lib/platform.js.map +1 -0
- package/build/src/lib/regex.js +25 -0
- package/build/src/lib/regex.js.map +1 -0
- package/build/src/lib/schema.js +40 -0
- package/build/src/lib/schema.js.map +1 -0
- package/build/src/lib/utility.js +458 -0
- package/build/src/lib/utility.js.map +1 -0
- package/build/src/scripts/repl.js +173 -0
- package/build/src/scripts/repl.js.map +1 -0
- package/build/src/scripts/test-api.js +171 -0
- package/build/src/scripts/test-api.js.map +1 -0
- package/config.schema.json +301 -218
- package/package.json +42 -17
- package/api-test.js +0 -280
- package/api.js +0 -878
- package/index.js +0 -1312
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import _ from 'lodash';
|
|
3
|
+
import { readFileSync } from 'node:fs';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import { exit, stdin, stdout } from 'node:process';
|
|
6
|
+
import readline from 'node:readline';
|
|
7
|
+
import util from 'node:util';
|
|
8
|
+
import { ADTPulse } from '../lib/api.js';
|
|
9
|
+
import { platformConfig } from '../lib/schema.js';
|
|
10
|
+
import { debugLog, isForwardSlashOS } from '../lib/utility.js';
|
|
11
|
+
class ADTPulseTest {
|
|
12
|
+
#selectedConfigLocation;
|
|
13
|
+
#selectedPlatform;
|
|
14
|
+
async startTest() {
|
|
15
|
+
try {
|
|
16
|
+
const userAcceptedDisclaimer = await ADTPulseTest.askQuestion('disclaimer');
|
|
17
|
+
if (!userAcceptedDisclaimer) {
|
|
18
|
+
exit(0);
|
|
19
|
+
}
|
|
20
|
+
console.info('\r');
|
|
21
|
+
const configFoundAndSet = this.findConfig();
|
|
22
|
+
if (!configFoundAndSet || this.#selectedPlatform === undefined) {
|
|
23
|
+
ADTPulseTest.printTestOutput(false);
|
|
24
|
+
exit(1);
|
|
25
|
+
}
|
|
26
|
+
const instance = new ADTPulse(this.#selectedPlatform, {
|
|
27
|
+
debug: true,
|
|
28
|
+
testMode: {
|
|
29
|
+
enabled: true,
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
const instanceFunctions = [
|
|
33
|
+
instance.login.bind(instance),
|
|
34
|
+
instance.getGatewayInformation.bind(instance),
|
|
35
|
+
instance.getPanelInformation.bind(instance),
|
|
36
|
+
instance.getPanelStatus.bind(instance),
|
|
37
|
+
instance.setPanelStatus.bind(instance, 'away'),
|
|
38
|
+
instance.setPanelStatus.bind(instance, 'stay'),
|
|
39
|
+
instance.setPanelStatus.bind(instance, 'night'),
|
|
40
|
+
instance.setPanelStatus.bind(instance, 'off'),
|
|
41
|
+
instance.getSensorsInformation.bind(instance),
|
|
42
|
+
instance.getSensorsStatus.bind(instance),
|
|
43
|
+
instance.performSyncCheck.bind(instance),
|
|
44
|
+
instance.performKeepAlive.bind(instance),
|
|
45
|
+
instance.logout.bind(instance),
|
|
46
|
+
];
|
|
47
|
+
for (let i = 0; i < instanceFunctions.length; i += 1) {
|
|
48
|
+
const response = await instanceFunctions[i]();
|
|
49
|
+
if (!response.success) {
|
|
50
|
+
ADTPulseTest.printTestOutput(false);
|
|
51
|
+
exit(1);
|
|
52
|
+
}
|
|
53
|
+
console.info(util.inspect(response, {
|
|
54
|
+
showHidden: false,
|
|
55
|
+
depth: Infinity,
|
|
56
|
+
colors: true,
|
|
57
|
+
}));
|
|
58
|
+
}
|
|
59
|
+
ADTPulseTest.printTestOutput(true);
|
|
60
|
+
exit(0);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
ADTPulseTest.printTestOutput(false);
|
|
64
|
+
exit(1);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
findConfig() {
|
|
68
|
+
const possibleLocations = [
|
|
69
|
+
...(isForwardSlashOS()) ? [
|
|
70
|
+
'/homebridge/config.json',
|
|
71
|
+
'/var/lib/homebridge/config.json',
|
|
72
|
+
`${os.homedir()}/.homebridge/config.json`,
|
|
73
|
+
] : [],
|
|
74
|
+
...(!isForwardSlashOS()) ? [
|
|
75
|
+
`${os.homedir()}\\.homebridge\\config.json`,
|
|
76
|
+
] : [],
|
|
77
|
+
];
|
|
78
|
+
for (let i = 0; i < possibleLocations.length; i += 1) {
|
|
79
|
+
if (this.#selectedConfigLocation !== undefined && this.#selectedPlatform !== undefined) {
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
debugLog(null, 'test-api.ts', 'info', `Attempt ${i + 1}: Finding the Homebridge config file in "${possibleLocations[i]}"`);
|
|
83
|
+
try {
|
|
84
|
+
const rawFile = readFileSync(possibleLocations[i], 'utf-8');
|
|
85
|
+
const parsedFile = JSON.parse(rawFile);
|
|
86
|
+
const platforms = _.get(parsedFile, ['platforms']);
|
|
87
|
+
const adtPlatform = _.find(platforms, (platform) => _.get(platform, ['platform']) === 'ADTPulse');
|
|
88
|
+
if (adtPlatform !== undefined) {
|
|
89
|
+
const validAdtPlatform = platformConfig.safeParse(adtPlatform);
|
|
90
|
+
if (validAdtPlatform.success) {
|
|
91
|
+
this.#selectedConfigLocation = possibleLocations[i];
|
|
92
|
+
this.#selectedPlatform = validAdtPlatform.data;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
this.#selectedConfigLocation = undefined;
|
|
98
|
+
this.#selectedPlatform = undefined;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (this.#selectedConfigLocation === undefined || this.#selectedPlatform === undefined) {
|
|
102
|
+
debugLog(null, 'test-api.ts', 'error', 'Unable to find a parsable Homebridge config file with a validated "ADTPulse" platform');
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
debugLog(null, 'test-api.ts', 'success', `Found valid Homebridge config in "${this.#selectedConfigLocation}"`);
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
static async askQuestion(mode) {
|
|
109
|
+
const rlInterface = readline.createInterface({
|
|
110
|
+
input: stdin,
|
|
111
|
+
output: stdout,
|
|
112
|
+
});
|
|
113
|
+
const questions = {
|
|
114
|
+
disclaimer: [
|
|
115
|
+
chalk.cyanBright('##############################################################'),
|
|
116
|
+
chalk.cyanBright('#### ADT Pulse for Homebridge Plugin Test ####'),
|
|
117
|
+
chalk.cyanBright('#### https://github.com/mrjackyliang/homebridge-adt-pulse ####'),
|
|
118
|
+
chalk.cyanBright('#### ####'),
|
|
119
|
+
chalk.cyanBright('#### Copyright (c) 2023 Jacky Liang. ISC License. ####'),
|
|
120
|
+
chalk.cyanBright('##############################################################'),
|
|
121
|
+
'Before you begin, please make sure of the following:',
|
|
122
|
+
'',
|
|
123
|
+
'1. You have the proper authorization to carry out system testing.',
|
|
124
|
+
'2. You are currently ON THE PROPERTY where the test is being conducted.',
|
|
125
|
+
'3. You have disarmed the system and have >= 1 door/window open.',
|
|
126
|
+
'4. You have access to MyADT and have placed the system in test mode.',
|
|
127
|
+
'',
|
|
128
|
+
`${chalk.redBright('WARNING')}: If you DO NOT have access to MyADT or CANNOT place the system into`,
|
|
129
|
+
'test mode, please DO NOT PROCEED. The author is NOT RESPONSIBLE if the test causes',
|
|
130
|
+
'an accidental trigger or if ADT agents/local authorities become involved.',
|
|
131
|
+
'',
|
|
132
|
+
`${chalk.bold.yellowBright('NOTICE')}: The API gathers anonymous analytics to detect potential bugs or issues.`,
|
|
133
|
+
' All personally identifiable information redacted. You will see exactly what will be sent out.',
|
|
134
|
+
'',
|
|
135
|
+
chalk.yellowBright('Type "I Agree" (without quotes) to fully acknowledge that you have read through'),
|
|
136
|
+
chalk.yellowBright('and understood the instructions, and agree to the disclaimer above ...'),
|
|
137
|
+
'➜ ',
|
|
138
|
+
].join('\n'),
|
|
139
|
+
};
|
|
140
|
+
return new Promise((resolve) => {
|
|
141
|
+
rlInterface.question(questions[mode], (input) => {
|
|
142
|
+
if (input !== 'I Agree') {
|
|
143
|
+
resolve(false);
|
|
144
|
+
}
|
|
145
|
+
resolve(true);
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
static printTestOutput(isSuccess) {
|
|
150
|
+
if (!isSuccess) {
|
|
151
|
+
console.info([
|
|
152
|
+
'',
|
|
153
|
+
chalk.redBright('########################################################################'),
|
|
154
|
+
chalk.redBright('##### Test has failed! Please check the error response #####'),
|
|
155
|
+
chalk.redBright('##### above, attempt to resolve them, then run this tester again #####'),
|
|
156
|
+
chalk.redBright('########################################################################'),
|
|
157
|
+
].join('\n'));
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
console.info([
|
|
161
|
+
'',
|
|
162
|
+
chalk.greenBright('########################################################################'),
|
|
163
|
+
chalk.greenBright('##### Test has completed! If you find my plugin useful #####'),
|
|
164
|
+
chalk.greenBright('##### please consider donating to my efforts via GitHub Sponsors #####'),
|
|
165
|
+
chalk.greenBright('########################################################################'),
|
|
166
|
+
].join('\n'));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const instance = new ADTPulseTest();
|
|
170
|
+
await instance.startTest();
|
|
171
|
+
//# sourceMappingURL=test-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-api.js","sourceRoot":"","sources":["../../../src/scripts/test-api.ts"],"names":[],"mappings":"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"}
|