isy-nodejs 1.0.3-alpha.3 → 1.0.3-y.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/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "isy-nodejs",
|
|
3
3
|
"description": "Node.js wrapper for ISY interface including websockets for change notifications. Fork of isy-js by Rod Toll. Designed to be used in a node.js application.",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "1.0.3-
|
|
5
|
+
"version": "1.0.3-y.0",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Pradeep Mouli"
|
|
8
8
|
},
|
|
@@ -73,5 +73,5 @@
|
|
|
73
73
|
"publishConfig": {
|
|
74
74
|
"access": "public"
|
|
75
75
|
},
|
|
76
|
-
"gitHead": "
|
|
76
|
+
"gitHead": "e28859e01d805f420d064c9c56e5e2f481cf5514"
|
|
77
77
|
}
|
package/src/ISY.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
|
|
2
1
|
import { writeFile } from 'fs';
|
|
3
2
|
|
|
4
|
-
import { Parser, type ParserOptions } from 'xml2js';
|
|
5
|
-
import { parseBooleans, parseNumbers } from 'xml2js/lib/processors.js';
|
|
6
|
-
import WebSocket from 'ws';
|
|
7
3
|
import axios, { type AxiosRequestConfig } from 'axios';
|
|
8
4
|
import { EventEmitter } from 'events';
|
|
9
5
|
import { format, Logger, loggers, type LeveledLogMethod } from 'winston';
|
|
6
|
+
import WebSocket from 'ws';
|
|
7
|
+
import { Parser, type ParserOptions } from 'xml2js';
|
|
8
|
+
import { parseBooleans, parseNumbers } from 'xml2js/lib/processors.js';
|
|
10
9
|
import { DeviceFactory } from './Devices/DeviceFactory.js';
|
|
11
10
|
import { ELKAlarmPanelDevice } from './Devices/Elk/ElkAlarmPanelDevice.js';
|
|
12
11
|
import { ElkAlarmSensorDevice } from './Devices/Elk/ElkAlarmSensorDevice.js';
|
|
@@ -22,16 +21,14 @@ import type { NodeInfo } from './Model/NodeInfo.js';
|
|
|
22
21
|
import * as Utils from './Utils.js';
|
|
23
22
|
|
|
24
23
|
import { X2jOptions, XMLParser } from 'fast-xml-parser';
|
|
24
|
+
import type { ClientRequestArgs } from 'http';
|
|
25
25
|
import path from 'path';
|
|
26
|
+
import { textChangeRangeIsUnchanged } from 'typescript';
|
|
27
|
+
import { promisify } from 'util';
|
|
26
28
|
import { NodeFactory } from './Devices/NodeFactory.js';
|
|
27
29
|
import { ISYError } from './ISYError.js';
|
|
28
30
|
import type { Config } from './Model/Config.js';
|
|
29
31
|
import { findPackageJson } from './Utils.js';
|
|
30
|
-
import { textChangeRangeIsUnchanged } from 'typescript';
|
|
31
|
-
import type { ClientRequestArgs } from 'http';
|
|
32
|
-
import { promisify } from 'util';
|
|
33
|
-
|
|
34
|
-
|
|
35
32
|
|
|
36
33
|
type InitStep = 'config' | 'loadNodes' | 'readFolders' | 'readDevices' | 'readScenes' | 'variables' | 'websocket' | 'refreshStatuses' | 'initialize';
|
|
37
34
|
|
|
@@ -180,13 +177,11 @@ export class ISY extends EventEmitter implements Disposable {
|
|
|
180
177
|
this.webSocketOptions = { origin: 'com.universal-devices.websockets.isy' };
|
|
181
178
|
|
|
182
179
|
if (this.socketPath) {
|
|
183
|
-
|
|
184
180
|
this.webSocketOptions.socketPath = this.socketPath;
|
|
185
181
|
} else {
|
|
186
182
|
this.webSocketOptions.auth = `${this.credentials.username}:${this.credentials.password}`;
|
|
187
183
|
}
|
|
188
184
|
|
|
189
|
-
|
|
190
185
|
//this.elkEnabled = config.elkEnabled ?? false;
|
|
191
186
|
|
|
192
187
|
this.nodesLoaded = false;
|
|
@@ -375,10 +370,9 @@ export class ISY extends EventEmitter implements Disposable {
|
|
|
375
370
|
return true;
|
|
376
371
|
} catch (e) {
|
|
377
372
|
if (e instanceof ISYInitializationError) {
|
|
378
|
-
if(e.step === 'variables')
|
|
379
|
-
{
|
|
373
|
+
if (e.step === 'variables') {
|
|
380
374
|
this.logger.warn(`Error loading variables: ${e.message}`);
|
|
381
|
-
|
|
375
|
+
await this.#finishInitialize(true);
|
|
382
376
|
return true;
|
|
383
377
|
}
|
|
384
378
|
this.logger.error(`Error initializing ISY during (${e.step}): ${e.message}`);
|
|
@@ -387,7 +381,6 @@ export class ISY extends EventEmitter implements Disposable {
|
|
|
387
381
|
this.logger.error(`Error initializing ISY: ${e.message}`);
|
|
388
382
|
return false;
|
|
389
383
|
}
|
|
390
|
-
throw e;
|
|
391
384
|
} finally {
|
|
392
385
|
if (this.nodesLoaded !== true) {
|
|
393
386
|
await that.#finishInitialize(false);
|
|
@@ -402,10 +395,9 @@ export class ISY extends EventEmitter implements Disposable {
|
|
|
402
395
|
const that = this;
|
|
403
396
|
|
|
404
397
|
//const auth = `Basic ${Buffer.from(`${this.credentials.username}:${this.credentials.password}`).toString('base64')}`;
|
|
405
|
-
let address = `${this.wsprotocol}://${this.address}/rest/subscribe
|
|
406
|
-
if(this.socketPath)
|
|
407
|
-
|
|
408
|
-
address = `ws+unix://${this.socketPath}:rest/subscribe`;
|
|
398
|
+
let address = `${this.wsprotocol}://${this.address}/rest/subscribe`;
|
|
399
|
+
if (this.socketPath) {
|
|
400
|
+
address = `ws+unix:${this.socketPath}:/rest/subscribe`;
|
|
409
401
|
}
|
|
410
402
|
this.logger.info(`Opening webSocket: ${address}`);
|
|
411
403
|
this.logger.info('Using the following websocket options: ' + JSON.stringify(this.webSocketOptions));
|
|
@@ -417,42 +409,42 @@ export class ISY extends EventEmitter implements Disposable {
|
|
|
417
409
|
}
|
|
418
410
|
}
|
|
419
411
|
|
|
420
|
-
|
|
412
|
+
/*headers: {
|
|
421
413
|
Origin: 'com.universal-devices.websockets.isy',
|
|
422
414
|
auth
|
|
423
415
|
},
|
|
424
416
|
|
|
425
417
|
ping: 10*/
|
|
426
|
-
let p
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
418
|
+
let p = new Promise<void>((resolve, reject) => {
|
|
419
|
+
this.webSocket = new WebSocket(`${address}`, ['ISYSUB'], this.webSocketOptions);
|
|
420
|
+
this.lastActivity = new Date();
|
|
421
|
+
//this.webSocket.onmessage = (event) => {this.handleWebSocketMessage()
|
|
422
|
+
this.webSocket
|
|
423
|
+
.on('open', () => {
|
|
424
|
+
this.logger.info('Websocket connection open');
|
|
425
|
+
resolve();
|
|
426
|
+
})
|
|
427
|
+
.on('message', (data, b) => {
|
|
428
|
+
that.logger.silly(`Received message: ${Utils.logStringify(data, 1)}`);
|
|
429
|
+
that.handleWebSocketMessage({ data: data });
|
|
430
|
+
})
|
|
431
|
+
.on('error', (err: any, response: any) => {
|
|
432
|
+
that.logger.warn(`Websocket subscription error: ${err}`);
|
|
433
|
+
return reject(new ISYInitializationError('Websocket subscription error', 'websocket'));
|
|
434
|
+
})
|
|
435
|
+
.on('fail', (data: string, response: any) => {
|
|
436
|
+
that.logger.warn(`Websocket subscription failure: ${data}`);
|
|
437
|
+
return reject(new Error('Websocket subscription failure'));
|
|
438
|
+
})
|
|
439
|
+
.on('abort', () => {
|
|
440
|
+
that.logger.warn('Websocket subscription aborted.');
|
|
441
|
+
throw new Error('Websocket subscription aborted.');
|
|
442
|
+
})
|
|
443
|
+
.on('timeout', (ms: string) => {
|
|
444
|
+
that.logger.warn(`Websocket subscription timed out after ${ms} milliseconds.`);
|
|
445
|
+
return reject(new Error('Timeout contacting ISY'));
|
|
446
|
+
//throw new Error('Timeout contacting ISY');
|
|
447
|
+
});
|
|
456
448
|
});
|
|
457
449
|
return p;
|
|
458
450
|
} catch (e) {
|
|
@@ -509,16 +501,14 @@ export class ISY extends EventEmitter implements Disposable {
|
|
|
509
501
|
}
|
|
510
502
|
|
|
511
503
|
public async loadVariables(type: VariableType): Promise<any> {
|
|
512
|
-
try
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
}
|
|
521
|
-
catch{
|
|
504
|
+
try {
|
|
505
|
+
const that = this;
|
|
506
|
+
this.logger.info(`Loading ISY Variables of type: ${type}`);
|
|
507
|
+
return this.sendRequest(`vars/definitions/${type}`)
|
|
508
|
+
.then((result) => that.#createVariables(type, result))
|
|
509
|
+
.then(() => that.sendRequest(`vars/get/${type}`))
|
|
510
|
+
.then(that.#setVariableValues.bind(that));
|
|
511
|
+
} catch {
|
|
522
512
|
this.logger.warn('error loading variables');
|
|
523
513
|
}
|
|
524
514
|
}
|
|
@@ -580,8 +570,7 @@ export class ISY extends EventEmitter implements Disposable {
|
|
|
580
570
|
if (paramName === 'value' || paramName === 'default') {
|
|
581
571
|
uriToUse += `/${q[paramName]}`;
|
|
582
572
|
continue;
|
|
583
|
-
}
|
|
584
|
-
else if (typeof q[paramName] === 'string' || typeof q[paramName] === 'number') uriToUse += `/${paramName}/${q[paramName]}`;
|
|
573
|
+
} else if (typeof q[paramName] === 'string' || typeof q[paramName] === 'number') uriToUse += `/${paramName}/${q[paramName]}`;
|
|
585
574
|
}
|
|
586
575
|
|
|
587
576
|
//uriToUse += `/${q[((p : Record<string,number|number>) => `${p[]}/${p.paramValue}` ).join('/')}`;
|
|
@@ -699,7 +688,6 @@ export class ISY extends EventEmitter implements Disposable {
|
|
|
699
688
|
}
|
|
700
689
|
}
|
|
701
690
|
}
|
|
702
|
-
|
|
703
691
|
}
|
|
704
692
|
|
|
705
693
|
async #guardian() {
|
|
@@ -784,13 +772,10 @@ export class ISY extends EventEmitter implements Disposable {
|
|
|
784
772
|
return acc;
|
|
785
773
|
}, {});
|
|
786
774
|
|
|
787
|
-
if(cls)
|
|
788
|
-
{
|
|
775
|
+
if (cls) {
|
|
789
776
|
try {
|
|
790
777
|
newDevice = new cls(this, nodeInfo) as ISYDeviceNode<any, any, any, any>;
|
|
791
|
-
}
|
|
792
|
-
catch(e)
|
|
793
|
-
{
|
|
778
|
+
} catch (e) {
|
|
794
779
|
this.logger.error(`Error creating device ${nodeInfo.name} with type ${nodeInfo.type} and nodedef ${nodeInfo.nodeDefId}: ${e.message}`);
|
|
795
780
|
continue;
|
|
796
781
|
}
|