isy-nodejs 1.0.1-alpha.6 → 1.0.1-alpha.9

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.
Files changed (158) hide show
  1. package/dist/cjs/Converters.js +66 -30
  2. package/dist/cjs/Converters.js.map +1 -1
  3. package/dist/cjs/Definitions/Global/Drivers.js +10 -3
  4. package/dist/cjs/Definitions/Global/Drivers.js.map +1 -1
  5. package/dist/cjs/Definitions/Global/Events.js +1 -2
  6. package/dist/cjs/Definitions/Global/Events.js.map +1 -1
  7. package/dist/cjs/Devices/Elk/ElkAlarmPanelDevice.js +3 -3
  8. package/dist/cjs/Devices/Elk/ElkAlarmSensorDevice.js +9 -6
  9. package/dist/cjs/Devices/Elk/ElkAlarmSensorDevice.js.map +1 -1
  10. package/dist/cjs/Devices/Insteon/InsteonBaseDevice.js +1 -1
  11. package/dist/cjs/Devices/Insteon/InsteonBaseDevice.js.map +1 -1
  12. package/dist/cjs/Devices/Insteon/InsteonFanDevice.js +4 -2
  13. package/dist/cjs/Devices/Insteon/InsteonFanDevice.js.map +1 -1
  14. package/dist/cjs/Devices/Insteon/InsteonMotionSensorDevice.js +5 -5
  15. package/dist/cjs/ISY.js +29 -20
  16. package/dist/cjs/ISY.js.map +1 -1
  17. package/dist/cjs/ISYNode.js +11 -8
  18. package/dist/cjs/ISYNode.js.map +1 -1
  19. package/dist/cjs/ISYScene.js +2 -2
  20. package/dist/cjs/Matter/Behaviors/ISYBridgedDeviceBehavior.js +11 -4
  21. package/dist/cjs/Matter/Behaviors/ISYBridgedDeviceBehavior.js.map +1 -1
  22. package/dist/cjs/Matter/Behaviors/ISYClusterBehavior.js +26 -7
  23. package/dist/cjs/Matter/Behaviors/ISYClusterBehavior.js.map +1 -1
  24. package/dist/cjs/Matter/Behaviors/ISYOnOffBehavior.js +9 -7
  25. package/dist/cjs/Matter/Behaviors/ISYOnOffBehavior.js.map +1 -1
  26. package/dist/cjs/Matter/{Server → Bridge}/Server.js +31 -45
  27. package/dist/cjs/Matter/Bridge/Server.js.map +1 -0
  28. package/dist/cjs/Matter/Mappings/Insteon.js +19 -15
  29. package/dist/cjs/Matter/Mappings/Insteon.js.map +1 -1
  30. package/dist/cjs/Matter/Mappings/register.js +1 -0
  31. package/dist/cjs/Matter/Mappings/register.js.map +1 -0
  32. package/dist/cjs/Model/ClusterMap.js +12 -9
  33. package/dist/cjs/Model/ClusterMap.js.map +1 -1
  34. package/dist/cjs/Utils.js +0 -9
  35. package/dist/cjs/Utils.js.map +1 -1
  36. package/dist/cjs/types/Converters.d.ts +28 -8
  37. package/dist/cjs/types/Converters.d.ts.map +1 -1
  38. package/dist/cjs/types/Definitions/Global/Drivers.d.ts +4 -3
  39. package/dist/cjs/types/Definitions/Global/Drivers.d.ts.map +1 -1
  40. package/dist/cjs/types/Definitions/Global/Events.d.ts.map +1 -1
  41. package/dist/cjs/types/Devices/Elk/ElkAlarmSensorDevice.d.ts.map +1 -1
  42. package/dist/cjs/types/Devices/EndpointFor.d.ts +2 -2
  43. package/dist/cjs/types/Devices/Insteon/InsteonDevice.d.ts +4 -4
  44. package/dist/cjs/types/Devices/Insteon/InsteonFanDevice.d.ts.map +1 -1
  45. package/dist/cjs/types/ISY.d.ts +21 -18
  46. package/dist/cjs/types/ISY.d.ts.map +1 -1
  47. package/dist/cjs/types/ISYNode.d.ts +4 -4
  48. package/dist/cjs/types/ISYNode.d.ts.map +1 -1
  49. package/dist/cjs/types/Matter/Behaviors/ISYBridgedDeviceBehavior.d.ts +16 -6
  50. package/dist/cjs/types/Matter/Behaviors/ISYBridgedDeviceBehavior.d.ts.map +1 -1
  51. package/dist/cjs/types/Matter/Behaviors/ISYClusterBehavior.d.ts +13 -11
  52. package/dist/cjs/types/Matter/Behaviors/ISYClusterBehavior.d.ts.map +1 -1
  53. package/dist/cjs/types/Matter/Behaviors/ISYOnOffBehavior.d.ts +4 -4
  54. package/dist/cjs/types/Matter/Behaviors/ISYOnOffBehavior.d.ts.map +1 -1
  55. package/dist/cjs/types/Matter/Bridge/Server.d.ts +17 -0
  56. package/dist/cjs/types/Matter/Bridge/Server.d.ts.map +1 -0
  57. package/dist/cjs/types/Matter/Mappings/register.d.ts +1 -0
  58. package/dist/cjs/types/Matter/Mappings/register.d.ts.map +1 -0
  59. package/dist/cjs/types/Model/ClusterMap.d.ts +19 -11
  60. package/dist/cjs/types/Model/ClusterMap.d.ts.map +1 -1
  61. package/dist/cjs/types/Utils.d.ts +0 -5
  62. package/dist/cjs/types/Utils.d.ts.map +1 -1
  63. package/dist/esm/Converters.js +63 -28
  64. package/dist/esm/Converters.js.map +1 -1
  65. package/dist/esm/Definitions/Global/Drivers.js +10 -3
  66. package/dist/esm/Definitions/Global/Drivers.js.map +1 -1
  67. package/dist/esm/Definitions/Global/Events.js +1 -2
  68. package/dist/esm/Definitions/Global/Events.js.map +1 -1
  69. package/dist/esm/Devices/Elk/ElkAlarmPanelDevice.js +3 -3
  70. package/dist/esm/Devices/Elk/ElkAlarmSensorDevice.js +9 -6
  71. package/dist/esm/Devices/Elk/ElkAlarmSensorDevice.js.map +1 -1
  72. package/dist/esm/Devices/Insteon/InsteonBaseDevice.js +2 -2
  73. package/dist/esm/Devices/Insteon/InsteonBaseDevice.js.map +1 -1
  74. package/dist/esm/Devices/Insteon/InsteonFanDevice.js +4 -2
  75. package/dist/esm/Devices/Insteon/InsteonFanDevice.js.map +1 -1
  76. package/dist/esm/Devices/Insteon/InsteonMotionSensorDevice.js +5 -5
  77. package/dist/esm/ISY.js +28 -19
  78. package/dist/esm/ISY.js.map +1 -1
  79. package/dist/esm/ISYNode.js +12 -9
  80. package/dist/esm/ISYNode.js.map +1 -1
  81. package/dist/esm/ISYScene.js +2 -2
  82. package/dist/esm/Matter/Behaviors/ISYBridgedDeviceBehavior.js +11 -4
  83. package/dist/esm/Matter/Behaviors/ISYBridgedDeviceBehavior.js.map +1 -1
  84. package/dist/esm/Matter/Behaviors/ISYClusterBehavior.js +26 -7
  85. package/dist/esm/Matter/Behaviors/ISYClusterBehavior.js.map +1 -1
  86. package/dist/esm/Matter/Behaviors/ISYOnOffBehavior.js +10 -8
  87. package/dist/esm/Matter/Behaviors/ISYOnOffBehavior.js.map +1 -1
  88. package/dist/esm/Matter/{Server → Bridge}/Server.js +29 -44
  89. package/dist/esm/Matter/Bridge/Server.js.map +1 -0
  90. package/dist/esm/Matter/Mappings/Insteon.js +22 -18
  91. package/dist/esm/Matter/Mappings/Insteon.js.map +1 -1
  92. package/dist/esm/Matter/Mappings/register.js +2 -0
  93. package/dist/esm/Matter/Mappings/register.js.map +1 -0
  94. package/dist/esm/Model/ClusterMap.js +12 -9
  95. package/dist/esm/Model/ClusterMap.js.map +1 -1
  96. package/dist/esm/Utils.js +0 -8
  97. package/dist/esm/Utils.js.map +1 -1
  98. package/dist/esm/types/Converters.d.ts +28 -8
  99. package/dist/esm/types/Converters.d.ts.map +1 -1
  100. package/dist/esm/types/Definitions/Global/Drivers.d.ts +4 -3
  101. package/dist/esm/types/Definitions/Global/Drivers.d.ts.map +1 -1
  102. package/dist/esm/types/Definitions/Global/Events.d.ts.map +1 -1
  103. package/dist/esm/types/Devices/Elk/ElkAlarmSensorDevice.d.ts.map +1 -1
  104. package/dist/esm/types/Devices/EndpointFor.d.ts +3 -3
  105. package/dist/esm/types/Devices/Insteon/InsteonDevice.d.ts +6 -6
  106. package/dist/esm/types/Devices/Insteon/InsteonFanDevice.d.ts.map +1 -1
  107. package/dist/esm/types/ISY.d.ts +21 -18
  108. package/dist/esm/types/ISY.d.ts.map +1 -1
  109. package/dist/esm/types/ISYNode.d.ts +5 -5
  110. package/dist/esm/types/ISYNode.d.ts.map +1 -1
  111. package/dist/esm/types/Matter/Behaviors/ISYBridgedDeviceBehavior.d.ts +16 -6
  112. package/dist/esm/types/Matter/Behaviors/ISYBridgedDeviceBehavior.d.ts.map +1 -1
  113. package/dist/esm/types/Matter/Behaviors/ISYClusterBehavior.d.ts +13 -11
  114. package/dist/esm/types/Matter/Behaviors/ISYClusterBehavior.d.ts.map +1 -1
  115. package/dist/esm/types/Matter/Behaviors/ISYOnOffBehavior.d.ts +4 -4
  116. package/dist/esm/types/Matter/Behaviors/ISYOnOffBehavior.d.ts.map +1 -1
  117. package/dist/esm/types/Matter/Bridge/Server.d.ts +17 -0
  118. package/dist/esm/types/Matter/Bridge/Server.d.ts.map +1 -0
  119. package/dist/esm/types/Matter/Mappings/register.d.ts +2 -0
  120. package/dist/esm/types/Matter/Mappings/register.d.ts.map +1 -0
  121. package/dist/esm/types/Model/ClusterMap.d.ts +19 -11
  122. package/dist/esm/types/Model/ClusterMap.d.ts.map +1 -1
  123. package/dist/esm/types/Utils.d.ts +0 -5
  124. package/dist/esm/types/Utils.d.ts.map +1 -1
  125. package/package.json +2 -7
  126. package/src/Converters.ts +137 -69
  127. package/src/Definitions/Global/Drivers.ts +16 -7
  128. package/src/Definitions/Global/Events.ts +4 -3
  129. package/src/Devices/Elk/ElkAlarmPanelDevice.ts +3 -3
  130. package/src/Devices/Elk/ElkAlarmSensorDevice.ts +15 -21
  131. package/src/Devices/Insteon/Generated/RelayLamp.ts +8 -7
  132. package/src/Devices/Insteon/InsteonBaseDevice.ts +2 -2
  133. package/src/Devices/Insteon/InsteonFanDevice.ts +11 -9
  134. package/src/Devices/Insteon/InsteonMotionSensorDevice.ts +5 -5
  135. package/src/ISY.ts +53 -38
  136. package/src/ISYNode.ts +13 -10
  137. package/src/ISYScene.ts +2 -2
  138. package/src/Matter/Behaviors/ISYBridgedDeviceBehavior.ts +28 -10
  139. package/src/Matter/Behaviors/ISYClusterBehavior.ts +46 -28
  140. package/src/Matter/Behaviors/ISYOnOffBehavior.ts +49 -60
  141. package/src/Matter/{Server → Bridge}/Server.ts +49 -53
  142. package/src/Matter/Mappings/Insteon.ts +53 -60
  143. package/src/Matter/Mappings/register.ts +0 -0
  144. package/src/Model/ClusterMap.ts +31 -22
  145. package/src/Utils.ts +1 -19
  146. package/LICENSE +0 -22
  147. package/dist/cjs/Matter/Server/Server.js.map +0 -1
  148. package/dist/cjs/types/Matter/Server/Server.d.ts +0 -4
  149. package/dist/cjs/types/Matter/Server/Server.d.ts.map +0 -1
  150. package/dist/esm/Devices/Insteon/Generated/RelayLampSwitch.js +0 -68
  151. package/dist/esm/Devices/Insteon/Generated/RelayLampSwitch.js.map +0 -1
  152. package/dist/esm/Matter/Server/Server.js.map +0 -1
  153. package/dist/esm/types/Devices/Insteon/Generated/RelayLampSwitch.d.ts +0 -93
  154. package/dist/esm/types/Devices/Insteon/Generated/RelayLampSwitch.d.ts.map +0 -1
  155. package/dist/esm/types/Matter/Server/Server.d.ts +0 -4
  156. package/dist/esm/types/Matter/Server/Server.d.ts.map +0 -1
  157. package/dist/tsconfig.cjs.tsbuildinfo +0 -1
  158. package/dist/tsconfig.esm.tsbuildinfo +0 -1
package/src/ISY.ts CHANGED
@@ -10,7 +10,6 @@ import { EventEmitter } from 'events';
10
10
  import winston, { format, Logger, loggers, type LeveledLogMethod } from 'winston';
11
11
  import { Category } from './Definitions/Global/Categories.js';
12
12
  import { Family } from './Definitions/Global/Families.js';
13
- import type { NodeInfo } from './Model/NodeInfo.js';
14
13
  import { DeviceFactory } from './Devices/DeviceFactory.js';
15
14
  import { ELKAlarmPanelDevice } from './Devices/Elk/ElkAlarmPanelDevice.js';
16
15
  import { ElkAlarmSensorDevice } from './Devices/Elk/ElkAlarmSensorDevice.js';
@@ -31,13 +30,14 @@ import { InsteonOnOffOutletDevice } from './Devices/Insteon/InsteonOnOffOutletDe
31
30
  import { InsteonRelayDevice } from './Devices/Insteon/InsteonRelayDevice.js';
32
31
  import { InsteonSmokeSensorDevice } from './Devices/Insteon/InsteonSmokeSensorDevice.js';
33
32
  import { InsteonThermostatDevice } from './Devices/Insteon/InsteonThermostatDevice.js';
33
+ import { ISYDeviceNode } from './Devices/ISYDeviceNode.js';
34
34
  import { EventType } from './Events/EventType.js';
35
35
  import { NodeType, Props, States, VariableType } from './ISYConstants.js';
36
- import { ISYNode } from './ISYNode.js';
37
- import { ISYDeviceNode } from './Devices/ISYDeviceNode.js';
38
36
  import { type ISYDevice } from './ISYDevice.js';
37
+ import { ISYNode } from './ISYNode.js';
39
38
  import { ISYScene } from './ISYScene.js';
40
39
  import { ISYVariable } from './ISYVariable.js';
40
+ import type { NodeInfo } from './Model/NodeInfo.js';
41
41
 
42
42
  import * as Utils from './Utils.js';
43
43
 
@@ -118,6 +118,21 @@ const parser = new Parser(defaultParserOptions);
118
118
 
119
119
  export let Controls = {};
120
120
 
121
+ interface ISYConfig {
122
+ // #region Properties (8)
123
+
124
+ displayNameFormat?: string;
125
+ elkEnabled?: boolean;
126
+ enableWebSocket?: boolean;
127
+ host: string;
128
+ password: string;
129
+ port: number;
130
+ protocol: 'http' | 'https';
131
+ username: string;
132
+
133
+ // #endregion Properties (8)
134
+ }
135
+
121
136
  export class ISY extends EventEmitter implements Disposable {
122
137
  // #region Properties (30)
123
138
 
@@ -158,20 +173,7 @@ export class ISY extends EventEmitter implements Disposable {
158
173
 
159
174
  // #region Constructors (1)
160
175
 
161
- constructor(
162
- config: {
163
- host: string;
164
- port: number;
165
- protocol: 'http' | 'https';
166
- username: string;
167
- password: string;
168
- enableWebSocket?: boolean;
169
- displayNameFormat?: string;
170
- elkEnabled?: boolean;
171
- },
172
- logger: Logger = new Logger(),
173
- storagePath?: string
174
- ) {
176
+ constructor(config: ISYConfig, logger: Logger = new Logger(), storagePath?: string) {
175
177
  super();
176
178
  this.enableWebSocket = config.enableWebSocket ?? true;
177
179
  this.storagePath = storagePath ?? './';
@@ -218,7 +220,15 @@ export class ISY extends EventEmitter implements Disposable {
218
220
 
219
221
  // #endregion Public Getters And Setters (2)
220
222
 
221
- // #region Public Methods (22)
223
+ // #region Public Methods (24)
224
+
225
+ [Symbol.dispose](): void {
226
+ try {
227
+ this.webSocket?.close();
228
+ } catch (e) {
229
+ this.logger.error(`Error closing websocket: ${e.message}`);
230
+ }
231
+ }
222
232
 
223
233
  public override emit(event: 'InitializeCompleted' | 'NodeAdded' | 'NodeRemoved' | 'NodeChanged', node?: ISYNode<any, any, any, any>): boolean {
224
234
  return super.emit(event, node);
@@ -239,6 +249,10 @@ export class ISY extends EventEmitter implements Disposable {
239
249
  return s as T;
240
250
  }
241
251
 
252
+ public getElkAlarmPanel() {
253
+ return this.elkAlarmPanel;
254
+ }
255
+
242
256
  public getNode<T extends ISYNode<any, any, any, any> = ISYNode<any, any, any, any>>(address: string, parentsOnly = false): T {
243
257
  let s = this.nodeMap.get(address);
244
258
  if (!parentsOnly) {
@@ -254,10 +268,6 @@ export class ISY extends EventEmitter implements Disposable {
254
268
  return s as T;
255
269
  }
256
270
 
257
- public getElkAlarmPanel() {
258
- return this.elkAlarmPanel;
259
- }
260
-
261
271
  public getScene(address: string) {
262
272
  return this.sceneList.get(address);
263
273
  }
@@ -569,6 +579,7 @@ export class ISY extends EventEmitter implements Disposable {
569
579
  trailingSlash: boolean;
570
580
  requestLogLevel?: any;
571
581
  responseLogLevel?: any;
582
+ errorLogLevel?: any;
572
583
  } = { trailingSlash: true }
573
584
  ): Promise<any> {
574
585
  const requestLogLevel = options.requestLogLevel ?? 'debug';
@@ -585,19 +596,22 @@ export class ISY extends EventEmitter implements Disposable {
585
596
  if (options.parserOptions) curParser = new Parser({ ...defaultParserOptions, ...options.parserOptions });
586
597
  var altParser = new XMLParser(defaultXMLParserOptions);
587
598
  var s = altParser.parse(response.data);
588
- this.logger.log(requestLogLevel ?? 'debug',`Response: ${JSON.stringify(s)}`);
599
+ this.logger.log(requestLogLevel ?? 'debug', `Response: ${JSON.stringify(s)}`);
589
600
  return s;
590
601
  } else if (response.headers['content-type'].toString().includes('json')) {
591
602
  this.logger.log(responseLogLevel ?? 'debug', `Response: ${JSON.stringify(response.data)}`);
592
603
  return JSON.parse(response.data);
593
604
  } else {
594
- this.logger.log(responseLogLevel ?? 'debug',`Response Header: ${JSON.stringify(response.headers)} Response: ${JSON.stringify(response.data)}`);
605
+ this.logger.log(responseLogLevel ?? 'debug', `Response Header: ${JSON.stringify(response.headers)} Response: ${JSON.stringify(response.data)}`);
595
606
  return response.data;
596
607
  }
597
608
  }
598
609
  } catch (error) {
599
- this.logger.error(`Error sending request to ISY: ${error?.message}`);
600
- throw new Error(`Error sending request to ISY: ${JSON.stringify(error)}`);
610
+ if (options.errorLogLevel) {
611
+ this.logger.log(options.errorLogLevel, `Error sending request to ISY: ${error?.message}`);
612
+ } else {
613
+ this.logger.error(`Error sending request to ISY: ${error?.message}`);
614
+ }
601
615
  }
602
616
  }
603
617
 
@@ -608,11 +622,15 @@ export class ISY extends EventEmitter implements Disposable {
608
622
  return this.sendRequest(uriToUse);
609
623
  }
610
624
 
611
- public variableChangedHandler(variable: { id: string; type: string }) {
625
+ #variableChangedHandler(variable: { id: string; type: string }) {
612
626
  this.logger.info(`Variable: ${variable.id} (${variable.type}) changed`);
613
627
  }
614
628
 
615
- // #endregion Public Methods (22)
629
+ public close() {
630
+ if (this.webSocket) this.webSocket.close();
631
+ }
632
+
633
+ // #endregion Public Methods (24)
616
634
 
617
635
  // #region Private Methods (11)
618
636
 
@@ -649,12 +667,13 @@ export class ISY extends EventEmitter implements Disposable {
649
667
  }
650
668
  }
651
669
 
652
- #guardian() {
670
+ async #guardian() {
653
671
  const timeNow = new Date();
654
672
 
655
673
  if (Number(timeNow) - Number(this.lastActivity) > 60000) {
656
674
  this.logger.info('Guardian: Detected no activity in more then 60 seconds. Reinitializing web sockets');
657
- this.initializeWebSocket();
675
+ await this.refreshStatuses();
676
+ await this.initializeWebSocket();
658
677
  }
659
678
  }
660
679
 
@@ -802,13 +821,9 @@ export class ISY extends EventEmitter implements Disposable {
802
821
  }
803
822
  }
804
823
 
805
- [Symbol.dispose](): void {
806
- try {
807
- this.webSocket.close();
808
- } catch (e) {
809
- this.logger.error(`Error closing websocket: ${e.message}`);
810
- }
811
- }
812
-
813
824
  // #endregion Private Methods (11)
814
825
  }
826
+
827
+ export namespace ISY {
828
+ export interface Config extends ISYConfig {}
829
+ }
package/src/ISYNode.ts CHANGED
@@ -6,7 +6,7 @@ import { UnitOfMeasure } from './Definitions/Global/UOM.js';
6
6
  import { ISY, NodeType, type ISYScene } from './ISY.js';
7
7
 
8
8
  import { CliConfigSetLevels } from 'winston/lib/winston/config/index.js';
9
- import { Converters } from './Converters.js';
9
+ import { Converter } from './Converters.js';
10
10
  import type { Command } from './Definitions/Global/Commands.js';
11
11
  import { Event } from './Definitions/Global/Events.js';
12
12
  import type { Constructor } from './Devices/Constructor.js';
@@ -168,7 +168,7 @@ export class ISYNode<
168
168
  if (from === to) return value;
169
169
  else {
170
170
  try {
171
- return Converters.Standard[from][to].from(value);
171
+ return Converter.Standard[from][to].from(value);
172
172
  } catch {
173
173
  this.isy.logger.error(`Conversion from ${UnitOfMeasure[from]} to ${UnitOfMeasure[to]} not supported.`);
174
174
  } finally {
@@ -191,7 +191,7 @@ export class ISYNode<
191
191
  }
192
192
  }
193
193
 
194
- public emit(event: 'PropertyChanged' | 'ControlTriggered', propertyName?: string, newValue?: any, oldValue?: any, formattedValue?: string, controlName?: string) {
194
+ public emit(event: 'propertyChanged' | 'controlTriggered', propertyName?: string, newValue?: any, oldValue?: any, formattedValue?: string, controlName?: string) {
195
195
  //if ('PropertyChanged') return super.emit(event, propertyName, newValue, oldValue, formattedValue);
196
196
  //else if ('ControlTriggered') return super.emit(event, controlName);
197
197
  }
@@ -232,7 +232,7 @@ export class ISYNode<
232
232
 
233
233
  public handleControlTrigger(controlName: keyof E & keyof C): boolean {
234
234
  //this.lastChanged = new Date();
235
- this.events.emit('ControlTriggered', controlName);
235
+ this.events.emit('controlTriggered', controlName);
236
236
  return true;
237
237
  }
238
238
 
@@ -255,20 +255,23 @@ export class ISYNode<
255
255
  const e = event.control;
256
256
  const dispName = this.commands[e]?.name;
257
257
  if (dispName !== undefined && dispName !== null) {
258
- this.logger(`Command ${dispName} (${e}) triggered.`);
258
+ this.logger(`Command ${dispName} (${e}) event sent.`);
259
259
  } else {
260
- this.logger(`Command ${e} triggered.`);
260
+ this.logger(`Command ${e} event sent.`);
261
261
  }
262
262
  this.handleControlTrigger(e);
263
263
  return true;
264
264
  }
265
265
  }
266
266
 
267
- public handlePropertyChange(propertyName: StringKeys<D>, value: any, uom: UnitOfMeasure, formattedValue: string, prec?: number): boolean {
267
+ public handlePropertyChange(propertyName: StringKeys<D>, value: any, uom: UnitOfMeasure, prec?: number, formattedValue?: string): boolean {
268
268
  this.lastChanged = new Date();
269
- const oldValue = this.drivers[propertyName].value;
270
- if (this.drivers[propertyName].patch(value, formattedValue, uom, prec)) {
271
- this.emit('PropertyChanged', propertyName, value, oldValue, formattedValue);
269
+ let driver = this.drivers[propertyName];
270
+ this.logger(`Driver ${propertyName} (${driver?.label} value update ${value} (${formattedValue}) uom: ${UnitOfMeasure[uom]} event received.`);
271
+ const oldValue = driver?.value;
272
+ if (driver?.patch(value, formattedValue, uom, prec)) {
273
+ this.logger(`Driver ${driver.label} updated from ${oldValue} to ${value} (${formattedValue})`);
274
+ this.emit('propertyChanged', propertyName, value, oldValue, formattedValue);
272
275
  this.scenes?.forEach((element) => {
273
276
  this.logger(`Recalulating ${element.deviceFriendlyName}`);
274
277
  element.recalculateState();
package/src/ISYScene.ts CHANGED
@@ -110,10 +110,10 @@ export class ISYScene extends ISYNode<Family.Scene, Driver.Signatures<'ST'>,Comm
110
110
  }
111
111
  public markAsChanged() {
112
112
  this.lastChanged = new Date();
113
- this.emit('PropertyChanged', 'isOn', this.isOn, this.isOn, this.isOn ? 'on' : 'off');
113
+ this.emit('propertyChanged', 'isOn', this.isOn, this.isOn, this.isOn ? 'on' : 'off');
114
114
 
115
115
  if (this.isDimmable) {
116
- this.emit('PropertyChanged', 'brightnesslevel', this.brightnessLevel, this.brightnessLevel, this.brightnessLevel + '%');
116
+ this.emit('propertyChanged', 'brightnesslevel', this.brightnessLevel, this.brightnessLevel, this.brightnessLevel + '%');
117
117
 
118
118
  }
119
119
  }
@@ -11,11 +11,11 @@ import internal from 'stream';
11
11
  import type { Driver } from '../../Definitions/Global/Drivers.js';
12
12
  import { ISY, type Family, type ISYNode } from '../../ISY.js';
13
13
  import type { ISYDevice } from '../../ISYDevice.js';
14
- import { DeviceToClusterMap, MappingRegistry, type ClusterMapping } from '../../Model/ClusterMap.js';
14
+ import { DeviceToClusterMap, MappingRegistry, type ClusterMapping, type BehaviorMapping } from '../../Model/ClusterMap.js';
15
15
 
16
16
 
17
17
  type ClusterForBehavior<B extends ClusterBehavior> = B extends ClusterBehavior.Type<infer C> ? C : never;
18
- export class ISYBridgedDeviceBehavior extends Behavior {
18
+ export class ISYBridgedDeviceBehavior<N extends ISYNode<any, D, any, any>, D extends ISYNode.DriverSignatures = ISYNode.DriverSignatures> extends Behavior {
19
19
  static override readonly id = 'isyNode';
20
20
 
21
21
  static override readonly early = true;
@@ -23,16 +23,24 @@ export class ISYBridgedDeviceBehavior extends Behavior {
23
23
  declare internal: ISYBridgedDeviceBehavior.Internal;
24
24
  declare state: ISYBridgedDeviceBehavior.State;
25
25
 
26
- declare events: ISYBridgedDeviceBehavior.Events;
26
+ declare events: ISYBridgedDeviceBehavior.Events & ISYBridgedDeviceBehavior.EventsFor<N["drivers"]>;
27
27
 
28
28
  override async initialize(_options?: {}) {
29
29
  await super.initialize(_options);
30
30
  var address = this.state.address;
31
- this.internal.device = ISY.instance.nodeMap.get(this.state.address);
32
- this.internal.map = MappingRegistry.getMapping(this.internal.device as unknown as ISYDevice<Family, any, any, any>);
31
+ const d = ISY.instance.nodeMap.get(this.state.address);
32
+ this.internal.device = d;
33
+ this.internal.map = MappingRegistry.getMapping(this.internal.device as unknown as ISYNode<Family, any, any, any>);
33
34
  ISY.instance.logger.debug(`Initializing ${this.constructor.name} for ${this.internal.device.constructor.name} ${this.internal.device.name} with address ${address}`);
34
- if (this.internal.device) {
35
- this.internal.device.events.on('PropertyChanged', this.handlePropertyChange.bind(this));
35
+ if (d) {
36
+ d.events.on('PropertyChanged', this.handlePropertyChange.bind(this));
37
+ for(const f in d.drivers)
38
+ {
39
+ let evt = `${d.drivers[f].name}Changed`;
40
+ this.events[evt] = Observable<[{ driver: string; newValue: any; oldValue: any; formattedValue: string }]>();
41
+ //@ts-ignore
42
+ d.events.on(evt, (driver: string, newValue: any, oldValue: any, formattedValue: string) => this.events.emit(evt, { driver, newValue, oldValue, formattedValue } as unknown as any));
43
+ }
36
44
  }
37
45
  }
38
46
 
@@ -44,8 +52,8 @@ export class ISYBridgedDeviceBehavior extends Behavior {
44
52
  return this.internal.map;
45
53
  }
46
54
 
47
- mapForBehavior<B extends { cluster: unknown }>(behavior: B): ClusterMapping<B['cluster'], typeof this.internal.device> {
48
- return this.map[behavior.cluster['name']];
55
+ mapForBehavior<B extends ClusterBehavior>(behavior: B): BehaviorMapping<B, typeof this.internal.device> {
56
+ return this.map.mapping[behavior.cluster['name']];
49
57
  }
50
58
 
51
59
  handlePropertyChange(driver: string, newValue: any, oldValue: any, formattedValue: string) {
@@ -64,8 +72,18 @@ export namespace ISYBridgedDeviceBehavior {
64
72
  map?: DeviceToClusterMap<typeof this.device, any>;
65
73
  }
66
74
 
67
- export class Events extends EventEmitter {
75
+ export type EventsFor<D extends {[x: string]: Driver<any,any,any>}> = {
76
+ [s in keyof D as `${D[s]["name"]}Changed`] : Observable<[{ driver: s; newValue: any; oldValue: any; formattedValue: string }]>;
77
+ }
78
+
79
+
80
+
81
+
82
+ export class Events extends EventEmitter{
68
83
  propertyChanged = Observable<[{ driver: string; newValue: any; oldValue: any; formattedValue: string }]>();
84
+
85
+
86
+
69
87
  }
70
88
 
71
89
  export class State {
@@ -1,38 +1,50 @@
1
- import type { ClusterBehavior, ClusterInterface } from '@project-chip/matter.js/behavior/cluster';
2
-
3
- import type { DriversOf, ISYNode } from '../../ISYNode.js';
4
-
5
1
  import type { Behavior } from '@project-chip/matter.js/behavior';
2
+ import type { ClusterBehavior, ClusterInterface } from '@project-chip/matter.js/behavior/cluster';
6
3
  import { BridgedDeviceBasicInformationServer } from '@project-chip/matter.js/behaviors/bridged-device-basic-information';
7
4
  import type { LevelControlBehavior } from '@project-chip/matter.js/behaviors/level-control';
8
5
  import type { OnOffBehavior, OnOffServer } from '@project-chip/matter.js/behaviors/on-off';
9
6
  import type { Cluster, ClusterServerHandlers, ClusterType as CT } from '@project-chip/matter.js/cluster';
10
7
  import '@project-chip/matter.js/device';
11
8
  import { OnOffLightRequirements } from '@project-chip/matter.js/devices/OnOffLightDevice';
12
- import { DriverType } from '../../Definitions/Global/Drivers.js';
9
+ import { Converter } from '../../Converters.js';
10
+ import { Driver, DriverType } from '../../Definitions/Global/Drivers.js';
13
11
  import type { Constructor } from '../../Devices/Constructor.js';
14
12
  import type { RelaxTypes } from '../../Devices/MapsTo.js';
15
13
  import { ISY, type ISYDevice } from '../../ISY.js';
16
- import { MappingRegistry, type ClusterMapping, type DeviceToClusterMap } from '../../Model/ClusterMap.js';
17
-
14
+ import type { DriversOf, ISYNode } from '../../ISYNode.js';
15
+ import { BehaviorMapping, MappingRegistry, type ClusterMapping, type DeviceToClusterMap } from '../../Model/ClusterMap.js';
18
16
  import { ISYBridgedDeviceBehavior } from './ISYBridgedDeviceBehavior.js';
19
17
 
20
- type NotUnknown<T extends ClusterBehavior> = T extends { cluster: { name: 'Unknown' } } ? never : T;
18
+ // #region Type aliases (6)
21
19
 
20
+ export type ClusterForBehavior<B> = B extends ClusterBehavior.Type<infer C, infer D, infer E> ? C : never;
22
21
  export type ConstructedType<B extends Constructor<any>> = B extends Constructor<infer C> ? C : never;
22
+ // <reference path="MatterDevice.js" />
23
+ // @ts-ignore
24
+ export type DeviceBehavior<P extends ISYNode, T extends { cluster? }> = {
25
+ device: P;
23
26
 
24
- export type ClusterForBehavior<B> = B extends ClusterBehavior.Type<infer C, infer D, infer E> ? C : never;
27
+ bridgedDeviceBehavior: ISYBridgedDeviceBehavior<P>;
25
28
 
26
- type t = ClusterForBehavior<LevelControlBehavior>;
29
+ //ts-ignore
30
+ map: BehaviorMapping<T, P>;
27
31
 
32
+ handlePropertyChange(chg: PropertyChange<P>): void;
33
+ };
34
+ type NotUnknown<T extends ClusterBehavior> = T extends { cluster: { name: 'Unknown' } } ? never : T;
28
35
  export type PropertyChange<P extends ISYNode<any, any, any, any>> = {
29
36
  driver: keyof DriversOf<P>;
30
37
  newValue: any;
31
38
  oldValue: any;
32
39
  formattedValue: string;
33
40
  };
41
+ type t = ClusterForBehavior<LevelControlBehavior>;
42
+
43
+ // #endregion Type aliases (6)
34
44
 
35
- export function ISYClusterBehavior<T extends Constructor<ClusterBehavior> & { cluster: unknown }, P extends ISYNode<any, any, any, any>>(
45
+ // #region Functions (1)
46
+
47
+ export function ISYClusterBehavior<T extends Constructor<ClusterBehavior> & { cluster }, P extends ISYNode<any, any, any, any>>(
36
48
  base: T,
37
49
  p: Constructor<P>
38
50
  ): typeof base & { new (...args: any[]): DeviceBehavior<P, T> } {
@@ -41,30 +53,44 @@ export function ISYClusterBehavior<T extends Constructor<ClusterBehavior> & { cl
41
53
 
42
54
  handlers: { [x in keyof DriversOf<P>]: (newValue, oldValue, formattedValue) => void } = {} as any;
43
55
 
56
+ bridgedDeviceBehavior: ISYBridgedDeviceBehavior<P>;
44
57
  ///public map: ClusterMapping<ToClusterTypeByName<ClusterForBehavior<ConstructedType<typeof base>>["name"]>,ISYDeviceNode<any, any, any>>;
45
58
 
46
- map: ClusterMapping<T['cluster'], P>;
59
+ map: BehaviorMapping<T, P>;
47
60
 
48
61
  override async initialize(_options?: {}) {
49
62
  await super.initialize(_options);
50
- var behavior = await this.agent.load(ISYBridgedDeviceBehavior);
63
+ var behavior = (await this.agent.load(ISYBridgedDeviceBehavior)) as ISYBridgedDeviceBehavior<P>;
64
+ this.bridgedDeviceBehavior = behavior;
51
65
  //var behavior = this.agent.get(ISYBridgedDeviceBehavior);
52
66
  this._device = behavior.device as P;
67
+ //@ts-ignore
53
68
  this.map = behavior.mapForBehavior<T>(this as unknown as T);
54
69
  for (const key2 in this.map.attributes) {
55
- if (typeof this.map.attributes[key2] === 'string') {
56
- this.handlers[this.map.attributes[key2]] = (newValue, oldValue, formattedValue) => {
70
+ let val = this.map.attributes[key2];
71
+ let driverObj = null;
72
+ if (typeof val === 'string' || typeof val === 'symbol' || typeof val === 'number') {
73
+ driverObj = this._device.drivers[val];
74
+ this.handlers[val] = (newValue, oldValue, formattedValue) => {
57
75
  this.state[key2 as string] = newValue;
58
76
  };
59
- } else if (this.map.attributes[key2].driver) {
60
- let { driver, converter } = this.map.attributes[key2];
77
+ } else if (val.driver as DriversOf<P>) {
78
+ driverObj = this._device.drivers[val.driver as string];
79
+
80
+ let { driver, converter } = val;
81
+ const convFunc = Converter.get(converter)?.from;
61
82
  this.handlers[driver] = (newValue, oldValue, formattedValue) => {
62
- this.state[key2 as string] = converter(newValue);
83
+ if (convFunc) this.state[key2 as string] = convFunc(newValue);
84
+ else this.state[key2 as string] = newValue;
63
85
  };
64
86
  }
87
+ if (driverObj) {
88
+ let evt = `${driverObj.name}Changed`;
89
+ this.reactTo(behavior.events[evt], this.handlePropertyChange.bind(this), { lock: false });
90
+ }
65
91
  }
66
92
 
67
- this.reactTo(behavior.events.propertyChanged, this.handlePropertyChange, { lock: false });
93
+ //this.reactTo(behavior.events.propertyChanged, this.handlePropertyChange, { lock: false });
68
94
 
69
95
  //this._device.on("PropertyChanged", this.handlePropertyChange.bind(this));
70
96
  }
@@ -95,13 +121,5 @@ export function ISYClusterBehavior<T extends Constructor<ClusterBehavior> & { cl
95
121
  }
96
122
  };
97
123
  }
98
- // <reference path="MatterDevice.js" />
99
- // @ts-ignore
100
-
101
- export type DeviceBehavior<P extends ISYNode, T extends { cluster }> = {
102
- device: P;
103
124
 
104
- map: ClusterMapping<T['cluster'], P>;
105
-
106
- handlePropertyChange(chg: PropertyChange<P>): void;
107
- };
125
+ // #endregion Functions (1)
@@ -1,80 +1,69 @@
1
- import { InsteonRelayDevice } from "../../Devices/Insteon/InsteonRelayDevice.js"
2
- import { OnOffLightRequirements } from "@project-chip/matter.js/devices/OnOffLightDevice";
3
- import { ISYClusterBehavior, ClusterForBehavior, type PropertyChange } from "./ISYClusterBehavior.js";
1
+ import type { LevelControlInterface, LevelControlServer } from '@project-chip/matter.js/behaviors/level-control';
2
+ import type { OnOffBehavior, OnOffServer } from '@project-chip/matter.js/behaviors/on-off';
3
+ import type { MutableCluster, OnOffCluster } from '@project-chip/matter.js/cluster';
4
+ import { DimmableLightRequirements } from '@project-chip/matter.js/devices/DimmableLightDevice';
5
+ import { OnOffLightRequirements } from '@project-chip/matter.js/devices/OnOffLightDevice';
4
6
  import { OnOffLightSwitchDevice } from '@project-chip/matter.js/devices/OnOffLightSwitchDevice';
5
7
  import type { MaybePromise } from '@project-chip/matter.js/util';
6
- import { MappingRegistry } from '../../Model/ClusterMap.js';
7
- import type { MutableCluster, OnOffCluster } from '@project-chip/matter.js/cluster';
8
- import type { OnOffBehavior, OnOffServer } from '@project-chip/matter.js/behaviors/on-off';
9
- import type { LevelControlServer, LevelControlInterface } from '@project-chip/matter.js/behaviors/level-control';
10
8
  import { DriverType } from '../../Definitions/Global/Drivers.js';
11
- import { DimmableLightRequirements } from '@project-chip/matter.js/devices/DimmableLightDevice';
12
9
  import { InsteonDimmableDevice } from '../../Devices/Insteon/InsteonDimmableDevice.js';
10
+ import { InsteonRelayDevice } from '../../Devices/Insteon/InsteonRelayDevice.js';
11
+ import { MappingRegistry } from '../../Model/ClusterMap.js';
12
+ import { ClusterForBehavior, ISYClusterBehavior, type PropertyChange } from './ISYClusterBehavior.js';
13
13
 
14
- import {Converters} from '../../Converters.js';
15
-
16
-
17
-
18
-
19
-
20
- export class ISYOnOffBehavior extends ISYClusterBehavior(OnOffLightRequirements.OnOffServer, InsteonRelayDevice)
21
- {
22
-
23
- override async initialize(_options?: {}) {
24
- await super.initialize(_options);
25
- //this.state.onOff = await this.device.state;
26
-
27
-
14
+ import { Converter } from '../../Converters.js';
28
15
 
29
- }
16
+ export class ISYOnOffBehavior extends ISYClusterBehavior(OnOffLightRequirements.OnOffServer, InsteonRelayDevice) {
17
+ override async initialize(_options?: {}) {
18
+ await super.initialize(_options);
19
+ //this.state.onOff = await this.device.state;
20
+ }
30
21
 
22
+ override on = async () => {
23
+ await super.on();
24
+ await this.device.on();
31
25
 
32
- override on = async () => {
33
- await super.on();
26
+ //this.device.commands.DON = true;
27
+ };
34
28
 
29
+ override async off() {
30
+ await super.off();
31
+ await this.device.off();
35
32
 
36
- //this.device.commands.DON = true;
37
- }
38
33
 
39
- override async off() {
40
- //await super.off();
41
- // this.device.drivers = false;
42
- }
43
34
 
44
- override toggle = async () => {
45
- //this.device.state = !(await this.device.state);
46
- }
35
+ // this.device.drivers = false;
36
+ }
47
37
 
48
- override async handlePropertyChange({driver, newValue, oldValue, formattedValue}: PropertyChange<InsteonRelayDevice>) {
49
- if (driver === "ST") {
50
- this.state.onOff = newValue;
38
+ override toggle = async () => {
51
39
 
52
- }
40
+ //this.device.state = !(await this.device.state);
41
+ };
53
42
 
54
- return super.handlePropertyChange({driver, newValue, oldValue, formattedValue});
55
- }
43
+ override async handlePropertyChange({ driver, newValue, oldValue, formattedValue }: PropertyChange<InsteonRelayDevice>) {
44
+ /*if (driver === 'ST') {
45
+ this.state.onOff = newValue;
46
+ }*/
56
47
 
57
48
 
49
+ return super.handlePropertyChange({ driver, newValue, oldValue, formattedValue });
50
+ }
58
51
  }
59
52
 
60
-
61
53
  export class ISYDimmableBehavior extends ISYClusterBehavior(DimmableLightRequirements.LevelControlServer, InsteonDimmableDevice) {
62
- override async initialize(_options?: {}) {
63
- await super.initialize(_options);
64
- this.state.currentLevel = this.device.drivers.ST.value;
65
- //this.state.onLevel = this.device.drivers.OL;
66
-
67
- }
68
-
69
- override setLevel(level: number): MaybePromise<void> {
70
- level = Converters.Matter.LevelFrom0To255.LightingLevel.to(level);
71
- if(level > 0)
72
- {
73
- return this.device.sendCommand('DON',level);
74
- }
75
- else
76
- {
77
- return this.device.sendCommand('DOF');
78
- }
79
- }
80
- }
54
+ override async initialize(_options?: {}) {
55
+ await super.initialize(_options);
56
+ this.state.currentLevel = this.device.drivers.ST.value;
57
+
58
+ //this.state.onLevel = this.device.drivers.OL;
59
+ }
60
+
61
+ override setLevel(level: number): MaybePromise<void> {
62
+ level = Converter.Matter.LevelFrom0To255.LightingLevel.from(level);
63
+ if (level > 0) {
64
+ return this.device.sendCommand('DON', level);
65
+ } else {
66
+ return this.device.sendCommand('DOF');
67
+ }
68
+ }
69
+ }