node-alarm-dot-com 2.1.1 → 2.3.0-beta.0
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/dist/_models/AuthOpts.js +1 -0
- package/dist/_models/AuthOpts.js.map +1 -0
- package/dist/_models/DeviceStates.d.ts +1 -1
- package/dist/_models/DeviceStates.js +1 -0
- package/dist/_models/DeviceStates.js.map +1 -0
- package/dist/_models/IdentityResponse.js +1 -0
- package/dist/_models/IdentityResponse.js.map +1 -0
- package/dist/_models/PartitionActionOptions.js +1 -0
- package/dist/_models/PartitionActionOptions.js.map +1 -0
- package/dist/_models/RequestOptions.d.ts +2 -3
- package/dist/_models/RequestOptions.js +1 -0
- package/dist/_models/RequestOptions.js.map +1 -0
- package/dist/_models/SensorType.js +1 -1
- package/dist/_models/SensorType.js.map +1 -0
- package/dist/_models/States.js +1 -1
- package/dist/_models/States.js.map +1 -0
- package/dist/_models/SystemState.js +1 -0
- package/dist/_models/SystemState.js.map +1 -0
- package/dist/_utils.d.ts +34 -0
- package/dist/_utils.js +147 -0
- package/dist/_utils.js.map +1 -0
- package/dist/core.d.ts +29 -0
- package/dist/core.js +163 -0
- package/dist/core.js.map +1 -0
- package/dist/garages.d.ts +17 -0
- package/dist/garages.js +38 -0
- package/dist/garages.js.map +1 -0
- package/dist/index.d.ts +8 -171
- package/dist/index.js +13 -629
- package/dist/index.js.map +1 -0
- package/dist/lights.d.ts +23 -0
- package/dist/lights.js +76 -0
- package/dist/lights.js.map +1 -0
- package/dist/locks.d.ts +19 -0
- package/dist/locks.js +44 -0
- package/dist/locks.js.map +1 -0
- package/dist/partitions.d.ts +40 -0
- package/dist/partitions.js +83 -0
- package/dist/partitions.js.map +1 -0
- package/dist/thermostats.d.ts +29 -0
- package/dist/thermostats.js +61 -0
- package/dist/thermostats.js.map +1 -0
- package/package.json +19 -14
package/dist/index.js
CHANGED
|
@@ -16,639 +16,23 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
|
|
|
16
16
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
17
17
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
18
18
|
};
|
|
19
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
20
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
21
|
-
};
|
|
22
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
-
exports.
|
|
24
|
-
exports.getIdentitiesState = getIdentitiesState;
|
|
25
|
-
exports.getCurrentState = getCurrentState;
|
|
26
|
-
exports.getComponents = getComponents;
|
|
27
|
-
exports.armStay = armStay;
|
|
28
|
-
exports.armAway = armAway;
|
|
29
|
-
exports.disarm = disarm;
|
|
30
|
-
exports.setLightOn = setLightOn;
|
|
31
|
-
exports.setLightOff = setLightOff;
|
|
32
|
-
exports.setLockSecure = setLockSecure;
|
|
33
|
-
exports.setLockUnsecure = setLockUnsecure;
|
|
34
|
-
exports.closeGarage = closeGarage;
|
|
35
|
-
exports.openGarage = openGarage;
|
|
36
|
-
exports.setThermostatState = setThermostatState;
|
|
37
|
-
exports.setThermostatTargetHeatTemperature = setThermostatTargetHeatTemperature;
|
|
38
|
-
exports.setThermostatTargetCoolTemperature = setThermostatTargetCoolTemperature;
|
|
39
|
-
exports.authenticatedGet = authenticatedGet;
|
|
40
|
-
exports.authenticatedPost = authenticatedPost;
|
|
41
|
-
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
20
|
+
exports.getComponents = exports.authenticatedPost = exports.authenticatedGet = void 0;
|
|
42
21
|
__exportStar(require("./_models/AuthOpts"), exports);
|
|
43
22
|
__exportStar(require("./_models/DeviceStates"), exports);
|
|
44
23
|
__exportStar(require("./_models/IdentityResponse"), exports);
|
|
45
24
|
__exportStar(require("./_models/PartitionActionOptions"), exports);
|
|
46
25
|
__exportStar(require("./_models/RequestOptions"), exports);
|
|
47
|
-
__exportStar(require("./_models/SystemState"), exports);
|
|
48
26
|
__exportStar(require("./_models/SensorType"), exports);
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const UA = `node-alarm-dot-com/${require('../package.json').version}`;
|
|
62
|
-
// Exported methods ////////////////////////////////////////////////////////////
|
|
63
|
-
/**
|
|
64
|
-
* Authenticate with alarm.com.
|
|
65
|
-
* Returns an authentication object that can be passed to other methods.
|
|
66
|
-
*
|
|
67
|
-
* @param {string} username Alarm.com username.
|
|
68
|
-
* @param {string} password Alarm.com password.
|
|
69
|
-
* @param {string} existingMfaToken MFA token from browser used to bypass MFA.
|
|
70
|
-
* @returns {Promise}
|
|
71
|
-
*/
|
|
72
|
-
async function login(username, password, existingMfaToken) {
|
|
73
|
-
let loginCookies;
|
|
74
|
-
let ajaxKey;
|
|
75
|
-
let loginFormBody;
|
|
76
|
-
let identities;
|
|
77
|
-
let systems;
|
|
78
|
-
// load initial alarm.com page to gather required hidden form fields
|
|
79
|
-
await get(ADCLOGIN_URL)
|
|
80
|
-
.then((res) => {
|
|
81
|
-
/* eslint-disable @typescript-eslint/naming-convention */
|
|
82
|
-
const loginObj = {
|
|
83
|
-
__EVENTTARGET: null,
|
|
84
|
-
__EVENTARGUMENT: null,
|
|
85
|
-
__VIEWSTATEENCRYPTED: null,
|
|
86
|
-
__EVENTVALIDATION: res.body.match(/name="__EVENTVALIDATION".*?value="([^"]*)"/)[1],
|
|
87
|
-
__VIEWSTATE: res.body.match(/name="__VIEWSTATE".*?value="([^"]*)"/)[1],
|
|
88
|
-
__VIEWSTATEGENERATOR: res.body.match(/name="__VIEWSTATEGENERATOR".*?value="([^"]*)"/)[1],
|
|
89
|
-
__PREVIOUSPAGE: res.body.match(/name="__PREVIOUSPAGE".*?value="([^"]*)"/)[1],
|
|
90
|
-
IsFromNewSite: '1',
|
|
91
|
-
ctl00$ContentPlaceHolder1$loginform$txtUserName: username,
|
|
92
|
-
txtPassword: password
|
|
93
|
-
};
|
|
94
|
-
/* eslint-enable @typescript-eslint/naming-convention */
|
|
95
|
-
// build login form body
|
|
96
|
-
loginFormBody = Object.keys(loginObj)
|
|
97
|
-
.map((k) => encodeURIComponent(k) + '=' + encodeURIComponent(loginObj[k]))
|
|
98
|
-
.join('&');
|
|
99
|
-
})
|
|
100
|
-
.catch((err) => {
|
|
101
|
-
throw new Error(`GET ${ADCLOGIN_URL} failed: ${err.message || err}`);
|
|
102
|
-
});
|
|
103
|
-
await (0, node_fetch_1.default)(ADCFORMLOGIN_URL, {
|
|
104
|
-
method: 'POST',
|
|
105
|
-
/* eslint-disable @typescript-eslint/naming-convention */
|
|
106
|
-
headers: {
|
|
107
|
-
'Content-Type': 'application/x-www-form-urlencoded',
|
|
108
|
-
'User-Agent': UA,
|
|
109
|
-
Cookie: `twoFactorAuthenticationId=${existingMfaToken};`
|
|
110
|
-
},
|
|
111
|
-
/* eslint-enable @typescript-eslint/naming-convention */
|
|
112
|
-
body: loginFormBody,
|
|
113
|
-
redirect: 'manual'
|
|
114
|
-
})
|
|
115
|
-
.then((res) => {
|
|
116
|
-
loginCookies = res.headers
|
|
117
|
-
.raw()['set-cookie'].map((c) => c.split(';')[0])
|
|
118
|
-
.join('; ');
|
|
119
|
-
// gather ajaxkey for session headers
|
|
120
|
-
const re = /afg=([^;]+);/.exec(loginCookies);
|
|
121
|
-
if (!re) {
|
|
122
|
-
throw new Error(`No afg cookie: ${loginCookies}`);
|
|
123
|
-
}
|
|
124
|
-
ajaxKey = re[1];
|
|
125
|
-
})
|
|
126
|
-
.catch((err) => {
|
|
127
|
-
throw new Error(`POST ${ADCFORMLOGIN_URL} failed: ${err.message || err}`);
|
|
128
|
-
});
|
|
129
|
-
await getIdentitiesState(loginCookies, ajaxKey)
|
|
130
|
-
.then((res) => {
|
|
131
|
-
systems = (res.data || []).map((d) => {
|
|
132
|
-
return d.relationships.selectedSystem.data.id;
|
|
133
|
-
});
|
|
134
|
-
})
|
|
135
|
-
.catch((err) => {
|
|
136
|
-
throw new Error(`GET ${IDENTITIES_URL} failed: ${err.message || err}`);
|
|
137
|
-
});
|
|
138
|
-
return {
|
|
139
|
-
cookie: loginCookies,
|
|
140
|
-
ajaxKey: ajaxKey,
|
|
141
|
-
systems: systems,
|
|
142
|
-
identities: identities
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* This function returns the alarm.com system identity for the currently logged in system.
|
|
147
|
-
* The information returned is useful for finding current systems and global config.
|
|
148
|
-
*/
|
|
149
|
-
async function getIdentitiesState(loginCookies, ajaxKey) {
|
|
150
|
-
return await get(IDENTITIES_URL, {
|
|
151
|
-
/* eslint-disable @typescript-eslint/naming-convention */
|
|
152
|
-
headers: {
|
|
153
|
-
Accept: 'application/vnd.api+json',
|
|
154
|
-
Cookie: loginCookies,
|
|
155
|
-
ajaxrequestuniquekey: ajaxKey,
|
|
156
|
-
Referer: 'https://www.alarm.com/web/system/home',
|
|
157
|
-
'User-Agent': UA
|
|
158
|
-
}
|
|
159
|
-
/* eslint-enable @typescript-eslint/naming-convention */
|
|
160
|
-
})
|
|
161
|
-
.then((res) => {
|
|
162
|
-
// gather identities and systems
|
|
163
|
-
return res.body;
|
|
164
|
-
})
|
|
165
|
-
.catch((err) => {
|
|
166
|
-
throw new Error(`GET ${IDENTITIES_URL} failed: ${err.message || err}`);
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Retrieve information about the current state of a security system including
|
|
171
|
-
* attributes, partitions, accessory components and relationships.
|
|
172
|
-
*
|
|
173
|
-
* @param {string} systemID ID of the system to query. The Authentication
|
|
174
|
-
* object returned from the `login` method contains a `systems` property which
|
|
175
|
-
* is an array of system IDs.
|
|
176
|
-
* @param {Object} authOpts Authentication object returned from the login.
|
|
177
|
-
* @returns {Promise}
|
|
178
|
-
*/
|
|
179
|
-
async function getCurrentState(systemID, authOpts) {
|
|
180
|
-
// This call to the systems endpoint retrieves an overview of all devices in a system
|
|
181
|
-
const res = await authenticatedGet(SYSTEM_URL + systemID, authOpts);
|
|
182
|
-
const rels = res.data.relationships;
|
|
183
|
-
const components = new Map();
|
|
184
|
-
// push the results of getComponents into the components
|
|
185
|
-
// Now we go through and get detailed information about all devices
|
|
186
|
-
const partitionIDs = rels.partitions.data.map((partition) => partition.id);
|
|
187
|
-
if (typeof partitionIDs[0] !== 'undefined') {
|
|
188
|
-
components.set('partitions', await getComponents(PARTITIONS_URL, partitionIDs, authOpts));
|
|
189
|
-
}
|
|
190
|
-
const sensorIDs = rels.sensors.data.map((sensor) => sensor.id);
|
|
191
|
-
if (typeof sensorIDs[0] !== 'undefined') {
|
|
192
|
-
components.set('sensors', await getComponents(SENSORS_URL, sensorIDs, authOpts));
|
|
193
|
-
}
|
|
194
|
-
const lightIDs = rels.lights.data.map((light) => light.id);
|
|
195
|
-
if (typeof lightIDs[0] !== 'undefined') {
|
|
196
|
-
components.set('lights', await getComponents(LIGHTS_URL, lightIDs, authOpts));
|
|
197
|
-
}
|
|
198
|
-
const lockIDs = rels.locks.data.map((lock) => lock.id);
|
|
199
|
-
if (typeof lockIDs[0] !== 'undefined') {
|
|
200
|
-
components.set('locks', await getComponents(LOCKS_URL, lockIDs, authOpts));
|
|
201
|
-
}
|
|
202
|
-
const garageIDs = rels.garageDoors.data.map((garage) => garage.id);
|
|
203
|
-
if (typeof garageIDs[0] !== 'undefined') {
|
|
204
|
-
components.set('garages', await getComponents(GARAGE_URL, garageIDs, authOpts));
|
|
205
|
-
}
|
|
206
|
-
const thermostatIDs = rels.thermostats.data.map((thermostat) => thermostat.id);
|
|
207
|
-
if (typeof thermostatIDs[0] !== 'undefined') {
|
|
208
|
-
components.set('thermostats', await getComponents(THERMOSTAT_URL, thermostatIDs, authOpts));
|
|
209
|
-
}
|
|
210
|
-
return {
|
|
211
|
-
id: res.data.id,
|
|
212
|
-
attributes: res.data.attributes,
|
|
213
|
-
partitions: components.has('partitions') ? components.get('partitions').data : [],
|
|
214
|
-
sensors: components.has('sensors') ? components.get('sensors').data : [],
|
|
215
|
-
lights: components.has('lights') ? components.get('lights').data : [],
|
|
216
|
-
locks: components.has('locks') ? components.get('locks').data : [],
|
|
217
|
-
garages: components.has('garages') ? components.get('garages').data : [],
|
|
218
|
-
thermostats: components.has('thermostats') ? components.get('thermostats').data : [],
|
|
219
|
-
relationships: rels
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
/**
|
|
223
|
-
* Get information about groups of components e.g., sensors, lights, locks, garages, etc.
|
|
224
|
-
*
|
|
225
|
-
* @param {string} url Base request url.
|
|
226
|
-
* @param {string} componentIDs Array of ID to retrieve.
|
|
227
|
-
* @param {Object} authOpts Authentication object returned from the login.
|
|
228
|
-
* @returns {Promise}
|
|
229
|
-
*/
|
|
230
|
-
async function getComponents(url, componentIDs, authOpts) {
|
|
231
|
-
const IDs = Array.isArray(componentIDs) ? componentIDs : [componentIDs];
|
|
232
|
-
let requests = [];
|
|
233
|
-
if (IDs.length <= 50) {
|
|
234
|
-
const getUrl = `${url}?${IDs.map((id) => `ids%5B%5D=${id}`).join('&')}`;
|
|
235
|
-
requests.push(authenticatedGet(getUrl, authOpts));
|
|
236
|
-
}
|
|
237
|
-
else {
|
|
238
|
-
// We have found that the Alarm.com API will return a 404 error when there is an excessive number of query parameters.
|
|
239
|
-
// We get around this by breaking up our GET calls into shorter URIs.
|
|
240
|
-
const shortenedUrls = [];
|
|
241
|
-
while (IDs.length > 50) {
|
|
242
|
-
const currentArray = IDs.splice(0, 50);
|
|
243
|
-
shortenedUrls.push(`${url}?${currentArray.map((id) => `ids%5B%5D=${id}`).join('&')}`);
|
|
244
|
-
}
|
|
245
|
-
shortenedUrls.push(`${url}?${IDs.map((id) => `ids%5B%5D=${id}`).join('&')}`);
|
|
246
|
-
requests = shortenedUrls.map((u) => authenticatedGet(u, authOpts));
|
|
247
|
-
}
|
|
248
|
-
return await combineAPIDeviceAPICalls(requests);
|
|
249
|
-
}
|
|
250
|
-
async function combineAPIDeviceAPICalls(apiCalls) {
|
|
251
|
-
const apiStateCalls = await Promise.all(apiCalls);
|
|
252
|
-
const stateToReturn = {
|
|
253
|
-
data: [],
|
|
254
|
-
included: []
|
|
255
|
-
};
|
|
256
|
-
for (const apiCall of apiStateCalls) {
|
|
257
|
-
for (const apiData of apiCall.data) {
|
|
258
|
-
stateToReturn.data.push(apiData);
|
|
259
|
-
}
|
|
260
|
-
for (const apiInclude of apiCall.included) {
|
|
261
|
-
stateToReturn.included.push(apiInclude);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
stateToReturn.meta = apiStateCalls[0].meta;
|
|
265
|
-
return stateToReturn;
|
|
266
|
-
}
|
|
267
|
-
// Partition methods ///////////////////////////////////////////////////////////
|
|
268
|
-
/**
|
|
269
|
-
* Perform partition actions, e.g., armAway, armStay, disarm.
|
|
270
|
-
*
|
|
271
|
-
* @param {string} partitionID Partition ID to perform action on.
|
|
272
|
-
* @param {string} action Action (verb) to perform on partition.
|
|
273
|
-
* @param {Object} authOpts Authentication object returned from the login.
|
|
274
|
-
* @param {Object} opts Additional options for the action.
|
|
275
|
-
*/
|
|
276
|
-
function partitionAction(partitionID, action, authOpts, opts) {
|
|
277
|
-
opts = opts || {
|
|
278
|
-
noEntryDelay: false,
|
|
279
|
-
silentArming: false,
|
|
280
|
-
nightArming: false,
|
|
281
|
-
forceBypass: false
|
|
282
|
-
};
|
|
283
|
-
const url = `${PARTITIONS_URL}${partitionID}/${action}`;
|
|
284
|
-
const body = {
|
|
285
|
-
noEntryDelay: action === 'disarm' ? undefined : Boolean(opts.noEntryDelay),
|
|
286
|
-
silentArming: action === 'disarm' ? undefined : Boolean(opts.silentArming),
|
|
287
|
-
statePollOnly: false
|
|
288
|
-
};
|
|
289
|
-
// We only want to set nightArming when told to do so
|
|
290
|
-
//This is because calling nightArm when not supported will break the action
|
|
291
|
-
if (opts.nightArming === true) {
|
|
292
|
-
body['nightArming'] = true;
|
|
293
|
-
}
|
|
294
|
-
if (opts.forceBypass === true) {
|
|
295
|
-
body['forceBypass'] = true;
|
|
296
|
-
}
|
|
297
|
-
const postOpts = Object.assign({}, authOpts, { body });
|
|
298
|
-
return authenticatedPost(url, postOpts);
|
|
299
|
-
}
|
|
300
|
-
/**
|
|
301
|
-
* Convenience Method:
|
|
302
|
-
* Arm a security system panel in "stay" mode. NOTE: This call generally takes
|
|
303
|
-
* 20-30 seconds to complete.
|
|
304
|
-
*
|
|
305
|
-
* @param {string} partitionID Partition ID to arm.
|
|
306
|
-
* @param {Object} authOpts Authentication object returned from the login.
|
|
307
|
-
* @param {Object} opts Optional arguments for arming the system.
|
|
308
|
-
* @param {boolean} opts.noEntryDelay Disable the 30-second entry delay.
|
|
309
|
-
* @param {boolean} opts.silentArming Disable audible beeps and double the exit
|
|
310
|
-
* delay.
|
|
311
|
-
* @returns {Promise}
|
|
312
|
-
*/
|
|
313
|
-
function armStay(partitionID, authOpts, opts) {
|
|
314
|
-
return partitionAction(partitionID, 'armStay', authOpts, opts);
|
|
315
|
-
}
|
|
316
|
-
/**
|
|
317
|
-
* Convenience Method:
|
|
318
|
-
* Arm a security system panel in "away" mode. NOTE: This call generally takes
|
|
319
|
-
* 20-30 seconds to complete.
|
|
320
|
-
*
|
|
321
|
-
* @param {string} partitionID Partition ID to arm.
|
|
322
|
-
* @param {Object} authOpts Authentication object returned from the login.
|
|
323
|
-
* @param {Object} opts Optional arguments for arming the system.
|
|
324
|
-
* @param {boolean} opts.noEntryDelay Disable the 30-second entry delay.
|
|
325
|
-
* @param {boolean} opts.silentArming Disable audible beeps and double the exit
|
|
326
|
-
* delay.
|
|
327
|
-
* @returns {Promise}
|
|
328
|
-
*/
|
|
329
|
-
function armAway(partitionID, authOpts, opts) {
|
|
330
|
-
return partitionAction(partitionID, 'armAway', authOpts, opts);
|
|
331
|
-
}
|
|
332
|
-
/**
|
|
333
|
-
* Convenience Method:
|
|
334
|
-
* Disarm a security system panel. NOTE: This call generally takes 20-30 seconds
|
|
335
|
-
* to complete.
|
|
336
|
-
*
|
|
337
|
-
* @param {string} partitionID Partition ID to disarm.
|
|
338
|
-
* @param {Object} authOpts Authentication object returned from the login.
|
|
339
|
-
* @returns {Promise}
|
|
340
|
-
*/
|
|
341
|
-
function disarm(partitionID, authOpts) {
|
|
342
|
-
return partitionAction(partitionID, 'disarm', authOpts);
|
|
343
|
-
}
|
|
344
|
-
// Sensor methods //////////////////////////////////////////////////////////////
|
|
345
|
-
// Sensors don't do anything, but they report state when we get information
|
|
346
|
-
// about any of the components, sensors included.
|
|
347
|
-
// Light methods ///////////////////////////////////////////////////////////////
|
|
348
|
-
/**
|
|
349
|
-
* Perform non-dimmable light actions, i.e. turn on, turn off
|
|
350
|
-
*
|
|
351
|
-
* @param {string} lightID Light ID string.
|
|
352
|
-
* @param {string} action Action (verb) to perform on the light.
|
|
353
|
-
* @param {Object} authOpts Authentication object returned from the login.
|
|
354
|
-
*/
|
|
355
|
-
function lightAction(lightID, authOpts, action) {
|
|
356
|
-
const url = `${LIGHTS_URL}${lightID}/${action}`;
|
|
357
|
-
const postOpts = Object.assign({}, authOpts, {
|
|
358
|
-
body: {
|
|
359
|
-
statePollOnly: false
|
|
360
|
-
}
|
|
361
|
-
});
|
|
362
|
-
return authenticatedPost(url, postOpts);
|
|
363
|
-
}
|
|
364
|
-
/**
|
|
365
|
-
* Perform dimmable light actions, e.g., turn on, turn off, change brightness level.
|
|
366
|
-
*
|
|
367
|
-
* @param {string} lightID Light ID string.
|
|
368
|
-
* @param {string} action Action (verb) to perform on the light.
|
|
369
|
-
* @param {Object} authOpts Authentication object returned from the login.
|
|
370
|
-
* @param {number} brightness An integer, 1-100, indicating brightness.
|
|
371
|
-
*/
|
|
372
|
-
function dimmerAction(lightID, authOpts, brightness, action) {
|
|
373
|
-
const url = `${LIGHTS_URL}${lightID}/${action}`;
|
|
374
|
-
const postOpts = Object.assign({}, authOpts, {
|
|
375
|
-
body: {
|
|
376
|
-
dimmerLevel: brightness,
|
|
377
|
-
statePollOnly: false
|
|
378
|
-
}
|
|
379
|
-
});
|
|
380
|
-
return authenticatedPost(url, postOpts);
|
|
381
|
-
}
|
|
382
|
-
/**
|
|
383
|
-
* Convenience Method:
|
|
384
|
-
* Sets a light to ON and adjusts brightness level (1-100) of dimmable lights.
|
|
385
|
-
*
|
|
386
|
-
* @param {string} lightID Light ID string.
|
|
387
|
-
* @param {number} brightness An integer, 1-100, indicating brightness.
|
|
388
|
-
* @param {Object} authOpts Authentication object returned from the login.
|
|
389
|
-
* @param {boolean} isDimmer Indicates whether or not light is dimmable.
|
|
390
|
-
* @returns {Promise}
|
|
391
|
-
*/
|
|
392
|
-
function setLightOn(lightID, authOpts, brightness, isDimmer) {
|
|
393
|
-
if (isDimmer) {
|
|
394
|
-
return dimmerAction(lightID, authOpts, brightness, 'turnOn');
|
|
395
|
-
}
|
|
396
|
-
else {
|
|
397
|
-
return lightAction(lightID, authOpts, 'turnOn');
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
/**
|
|
401
|
-
* Convenience Method:
|
|
402
|
-
* Sets a light to OFF. The brightness level is ignored.
|
|
403
|
-
*
|
|
404
|
-
* @param {string} lightID Light ID string.
|
|
405
|
-
* @param {number} brightness An integer, 1-100, indicating brightness. Ignored.
|
|
406
|
-
* @param {Object} authOpts Authentication object returned from the login.
|
|
407
|
-
* @param {boolean} isDimmer Indicates whether or not light is dimmable.
|
|
408
|
-
* @returns {Promise}
|
|
409
|
-
*/
|
|
410
|
-
function setLightOff(lightID, authOpts, brightness, isDimmer) {
|
|
411
|
-
if (isDimmer) {
|
|
412
|
-
return dimmerAction(lightID, authOpts, brightness, 'turnOff');
|
|
413
|
-
}
|
|
414
|
-
else {
|
|
415
|
-
return lightAction(lightID, authOpts, 'turnOff');
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
// Lock methods ////////////////////////////////////////////////////////////////
|
|
419
|
-
/**
|
|
420
|
-
* Perform lock actions, e.g., lock, unlock.
|
|
421
|
-
*
|
|
422
|
-
* @param {string} lockID Lock ID string.
|
|
423
|
-
* @param {string} action Action (verb) to perform on the lock.
|
|
424
|
-
* @param {Object} authOpts Authentication object returned from the login.
|
|
425
|
-
*/
|
|
426
|
-
function lockAction(lockID, authOpts, action) {
|
|
427
|
-
const url = `${LOCKS_URL}${lockID}/${action}`;
|
|
428
|
-
const postOpts = Object.assign({}, authOpts, {
|
|
429
|
-
body: {
|
|
430
|
-
statePollOnly: false
|
|
431
|
-
}
|
|
432
|
-
});
|
|
433
|
-
return authenticatedPost(url, postOpts);
|
|
434
|
-
}
|
|
435
|
-
/**
|
|
436
|
-
* Convenience Method:
|
|
437
|
-
* Sets a lock to "locked" (SECURED).
|
|
438
|
-
*
|
|
439
|
-
* @param {string} lockID Lock ID string.
|
|
440
|
-
* @param {Object} authOpts Authentication object returned from the login.
|
|
441
|
-
* @returns {Promise}
|
|
442
|
-
*/
|
|
443
|
-
function setLockSecure(lockID, authOpts) {
|
|
444
|
-
return lockAction(lockID, authOpts, 'lock');
|
|
445
|
-
}
|
|
446
|
-
/**
|
|
447
|
-
* Convenience Method:
|
|
448
|
-
* Sets a lock to "unlocked" (UNSECURED).
|
|
449
|
-
*
|
|
450
|
-
* @param {string} lockID Lock ID string.
|
|
451
|
-
* @param {Object} authOpts Authentication object returned from the login.
|
|
452
|
-
* @returns {Promise}
|
|
453
|
-
*/
|
|
454
|
-
function setLockUnsecure(lockID, authOpts) {
|
|
455
|
-
return lockAction(lockID, authOpts, 'unlock');
|
|
456
|
-
}
|
|
457
|
-
// Garage methods ////////////////////////////////////////////////////////////////
|
|
458
|
-
/**
|
|
459
|
-
* Get information for one or more garages.
|
|
460
|
-
*
|
|
461
|
-
* @param {string[]} garageIDs Array of Garage ID strings.
|
|
462
|
-
* @param {Object} authOpts Authentication object returned from the `login`
|
|
463
|
-
* method.
|
|
464
|
-
* @returns {Promise}
|
|
465
|
-
*/
|
|
466
|
-
function getGarages(garageIDs, authOpts) {
|
|
467
|
-
if (!Array.isArray(garageIDs)) {
|
|
468
|
-
garageIDs = [garageIDs];
|
|
469
|
-
}
|
|
470
|
-
const query = garageIDs.map((id) => `ids%5B%5D=${id}`).join('&');
|
|
471
|
-
const url = `${GARAGE_URL}?${query}`;
|
|
472
|
-
return authenticatedGet(url, authOpts);
|
|
473
|
-
}
|
|
474
|
-
/**
|
|
475
|
-
* Sets a garage to CLOSED.
|
|
476
|
-
*
|
|
477
|
-
*
|
|
478
|
-
* @param {string} garageID Lock ID string.
|
|
479
|
-
* @param {Object} authOpts Authentication object returned from the `login`
|
|
480
|
-
* method.
|
|
481
|
-
* @returns {Promise}
|
|
482
|
-
*/
|
|
483
|
-
function closeGarage(garageID, authOpts) {
|
|
484
|
-
const url = `${GARAGE_URL}${garageID}/close`;
|
|
485
|
-
const postOpts = Object.assign({}, authOpts, {
|
|
486
|
-
body: {
|
|
487
|
-
statePollOnly: false
|
|
488
|
-
}
|
|
489
|
-
});
|
|
490
|
-
return authenticatedPost(url, postOpts);
|
|
491
|
-
}
|
|
492
|
-
/**
|
|
493
|
-
* Sets a garage to OPEN.
|
|
494
|
-
*
|
|
495
|
-
* @param {string} garageID Lock ID string.
|
|
496
|
-
* @param {Object} authOpts Authentication object returned from the `login`
|
|
497
|
-
* method.
|
|
498
|
-
* @returns {Promise}
|
|
499
|
-
*/
|
|
500
|
-
function openGarage(garageID, authOpts) {
|
|
501
|
-
const url = `${GARAGE_URL}${garageID}/open`;
|
|
502
|
-
const postOpts = Object.assign({}, authOpts, {
|
|
503
|
-
body: {
|
|
504
|
-
statePollOnly: false
|
|
505
|
-
}
|
|
506
|
-
});
|
|
507
|
-
return authenticatedPost(url, postOpts);
|
|
508
|
-
}
|
|
509
|
-
// Thermostat methods ////////////////////////////////////////////////////////////////
|
|
510
|
-
/**
|
|
511
|
-
* Update thermostat state
|
|
512
|
-
*
|
|
513
|
-
* @param {string} thermostatID Thermostat ID string.
|
|
514
|
-
* @param {Object} newState New desired state
|
|
515
|
-
* @param {Object} authOpts Authentication object returned from the `login`
|
|
516
|
-
* method.
|
|
517
|
-
* @returns {Promise}
|
|
518
|
-
*/
|
|
519
|
-
function setThermostatState(thermostatID, newState, authOpts) {
|
|
520
|
-
const url = `${THERMOSTAT_URL}${thermostatID}/setState`;
|
|
521
|
-
const postOpts = Object.assign({}, authOpts, {
|
|
522
|
-
body: {
|
|
523
|
-
desiredState: newState,
|
|
524
|
-
statePollOnly: false
|
|
525
|
-
}
|
|
526
|
-
});
|
|
527
|
-
return authenticatedPost(url, postOpts);
|
|
528
|
-
}
|
|
529
|
-
/**
|
|
530
|
-
* Sets a thermostat target heat temperature.
|
|
531
|
-
*
|
|
532
|
-
* @param {string} thermostatID ThermostatID ID string.
|
|
533
|
-
* @param {number} newTemp New target temperature
|
|
534
|
-
* @param {Object} authOpts Authentication object returned from the `login`
|
|
535
|
-
* method.
|
|
536
|
-
* @returns {Promise}
|
|
537
|
-
*/
|
|
538
|
-
function setThermostatTargetHeatTemperature(thermostatID, newTemp, authOpts) {
|
|
539
|
-
const url = `${THERMOSTAT_URL}${thermostatID}/setState`;
|
|
540
|
-
const postOpts = Object.assign({}, authOpts, {
|
|
541
|
-
body: {
|
|
542
|
-
desiredHeatSetpoint: newTemp,
|
|
543
|
-
statePollOnly: false
|
|
544
|
-
}
|
|
545
|
-
});
|
|
546
|
-
return authenticatedPost(url, postOpts);
|
|
547
|
-
}
|
|
548
|
-
/**
|
|
549
|
-
* Sets a thermostat target cool temperature.
|
|
550
|
-
*
|
|
551
|
-
* @param {string} thermostatID ThermostatID ID string.
|
|
552
|
-
* @param {number} newTemp New target temperature
|
|
553
|
-
* @param {Object} authOpts Authentication object returned from the `login`
|
|
554
|
-
* method.
|
|
555
|
-
* @returns {Promise}
|
|
556
|
-
*/
|
|
557
|
-
function setThermostatTargetCoolTemperature(thermostatID, newTemp, authOpts) {
|
|
558
|
-
const url = `${THERMOSTAT_URL}${thermostatID}/setState`;
|
|
559
|
-
const postOpts = Object.assign({}, authOpts, {
|
|
560
|
-
body: {
|
|
561
|
-
desiredCoolSetpoint: newTemp,
|
|
562
|
-
statePollOnly: false
|
|
563
|
-
}
|
|
564
|
-
});
|
|
565
|
-
return authenticatedPost(url, postOpts);
|
|
566
|
-
}
|
|
567
|
-
// Helper methods //////////////////////////////////////////////////////////////
|
|
568
|
-
function getValue(data, path) {
|
|
569
|
-
if (typeof path === 'string') {
|
|
570
|
-
path = path.split('.');
|
|
571
|
-
}
|
|
572
|
-
for (let i = 0; typeof data === 'object' && i < path.length; i++) {
|
|
573
|
-
data = data[path[i]];
|
|
574
|
-
}
|
|
575
|
-
return data;
|
|
576
|
-
}
|
|
577
|
-
async function authenticatedGet(url, opts) {
|
|
578
|
-
opts = opts || {};
|
|
579
|
-
opts.headers = opts.headers || {};
|
|
580
|
-
opts.headers.Accept = 'application/vnd.api+json';
|
|
581
|
-
opts.headers.ajaxrequestuniquekey = opts.ajaxKey;
|
|
582
|
-
opts.headers.Cookie = opts.cookie;
|
|
583
|
-
opts.headers.Referer = HOME_URL;
|
|
584
|
-
opts.headers['User-Agent'] = UA;
|
|
585
|
-
const res = await get(url, opts);
|
|
586
|
-
return res.body;
|
|
587
|
-
}
|
|
588
|
-
async function authenticatedPost(url, opts) {
|
|
589
|
-
opts = opts || {};
|
|
590
|
-
opts.headers = opts.headers || {};
|
|
591
|
-
opts.headers.Accept = 'application/vnd.api+json';
|
|
592
|
-
opts.headers.ajaxrequestuniquekey = opts.ajaxKey;
|
|
593
|
-
opts.headers.Cookie = opts.cookie;
|
|
594
|
-
opts.headers.Referer = HOME_URL;
|
|
595
|
-
opts.headers['User-Agent'] = UA;
|
|
596
|
-
opts.headers['Content-Type'] = 'application/json; charset=UTF-8';
|
|
597
|
-
const res = await post(url, opts);
|
|
598
|
-
return res.body;
|
|
599
|
-
}
|
|
600
|
-
async function get(url, opts) {
|
|
601
|
-
opts = opts || {};
|
|
602
|
-
let status;
|
|
603
|
-
let resHeaders;
|
|
604
|
-
try {
|
|
605
|
-
const res = await (0, node_fetch_1.default)(url, {
|
|
606
|
-
method: 'GET',
|
|
607
|
-
redirect: 'manual',
|
|
608
|
-
headers: opts.headers
|
|
609
|
-
});
|
|
610
|
-
status = res.status;
|
|
611
|
-
resHeaders = res.headers;
|
|
612
|
-
const type = res.headers.get('content-type') || '';
|
|
613
|
-
const body = await (type.indexOf('json') !== -1 ? (res.status === 204 ? {} : res.json()) : res.text());
|
|
614
|
-
if (status === 409) {
|
|
615
|
-
throw new Error('Two factor is enabled on this account but not setup in the plugin.' + ' See the wiki for details');
|
|
616
|
-
}
|
|
617
|
-
if (status >= 400) {
|
|
618
|
-
throw new Error(body.Message || body || status);
|
|
619
|
-
}
|
|
620
|
-
return {
|
|
621
|
-
headers: resHeaders,
|
|
622
|
-
body: body
|
|
623
|
-
};
|
|
624
|
-
}
|
|
625
|
-
catch (err) {
|
|
626
|
-
throw new Error(`GET ${url} failed: ${err.message || err}`);
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
async function post(url, opts) {
|
|
630
|
-
opts = opts || {};
|
|
631
|
-
let status;
|
|
632
|
-
let resHeaders;
|
|
633
|
-
try {
|
|
634
|
-
const res = await (0, node_fetch_1.default)(url, {
|
|
635
|
-
method: 'POST',
|
|
636
|
-
redirect: 'manual',
|
|
637
|
-
body: opts.body ? JSON.stringify(opts.body) : undefined,
|
|
638
|
-
headers: opts.headers
|
|
639
|
-
});
|
|
640
|
-
status = res.status;
|
|
641
|
-
resHeaders = res.headers;
|
|
642
|
-
const json = await (res.status === 204 ? {} : res.json());
|
|
643
|
-
if (status !== 200) {
|
|
644
|
-
throw new Error(json.Message || status);
|
|
645
|
-
}
|
|
646
|
-
return {
|
|
647
|
-
headers: resHeaders,
|
|
648
|
-
body: json
|
|
649
|
-
};
|
|
650
|
-
}
|
|
651
|
-
catch (err) {
|
|
652
|
-
throw new Error(`POST ${url} failed: ${err.message || err}`);
|
|
653
|
-
}
|
|
654
|
-
}
|
|
27
|
+
__exportStar(require("./_models/SystemState"), exports);
|
|
28
|
+
var _utils_1 = require("./_utils");
|
|
29
|
+
Object.defineProperty(exports, "authenticatedGet", { enumerable: true, get: function () { return _utils_1.authenticatedGet; } });
|
|
30
|
+
Object.defineProperty(exports, "authenticatedPost", { enumerable: true, get: function () { return _utils_1.authenticatedPost; } });
|
|
31
|
+
Object.defineProperty(exports, "getComponents", { enumerable: true, get: function () { return _utils_1.getComponents; } });
|
|
32
|
+
__exportStar(require("./core"), exports);
|
|
33
|
+
__exportStar(require("./partitions"), exports);
|
|
34
|
+
__exportStar(require("./lights"), exports);
|
|
35
|
+
__exportStar(require("./locks"), exports);
|
|
36
|
+
__exportStar(require("./garages"), exports);
|
|
37
|
+
__exportStar(require("./thermostats"), exports);
|
|
38
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;;AAEH,qDAAmC;AACnC,yDAAuC;AACvC,6DAA2C;AAC3C,mEAAiD;AACjD,2DAAyC;AACzC,uDAAqC;AACrC,wDAAsC;AAEtC,mCAA8E;AAArE,0GAAA,gBAAgB,OAAA;AAAE,2GAAA,iBAAiB,OAAA;AAAE,uGAAA,aAAa,OAAA;AAC3D,yCAAuB;AACvB,+CAA6B;AAC7B,2CAAyB;AACzB,0CAAwB;AACxB,4CAA0B;AAC1B,gDAA8B"}
|
package/dist/lights.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { AuthOpts } from './_models/AuthOpts';
|
|
2
|
+
/**
|
|
3
|
+
* Convenience Method:
|
|
4
|
+
* Sets a light to ON and adjusts brightness level (1-100) of dimmable lights.
|
|
5
|
+
*
|
|
6
|
+
* @param {string} lightID Light ID string.
|
|
7
|
+
* @param {number} brightness An integer, 1-100, indicating brightness.
|
|
8
|
+
* @param {Object} authOpts Authentication object returned from the login.
|
|
9
|
+
* @param {boolean} isDimmer Indicates whether or not light is dimmable.
|
|
10
|
+
* @returns {Promise}
|
|
11
|
+
*/
|
|
12
|
+
export declare function setLightOn(lightID: string, authOpts: AuthOpts, brightness: number, isDimmer: boolean): Promise<any>;
|
|
13
|
+
/**
|
|
14
|
+
* Convenience Method:
|
|
15
|
+
* Sets a light to OFF. The brightness level is ignored.
|
|
16
|
+
*
|
|
17
|
+
* @param {string} lightID Light ID string.
|
|
18
|
+
* @param {number} brightness An integer, 1-100, indicating brightness. Ignored.
|
|
19
|
+
* @param {Object} authOpts Authentication object returned from the login.
|
|
20
|
+
* @param {boolean} isDimmer Indicates whether or not light is dimmable.
|
|
21
|
+
* @returns {Promise}
|
|
22
|
+
*/
|
|
23
|
+
export declare function setLightOff(lightID: string, authOpts: AuthOpts, brightness: number, isDimmer: boolean): Promise<any>;
|