matterbridge 1.6.6-dev.7 → 1.6.6

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 (102) hide show
  1. package/CHANGELOG.md +22 -10
  2. package/README-DEV.md +3 -3
  3. package/README.md +4 -0
  4. package/dist/cli.d.ts +25 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +26 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/cluster/export.d.ts +2 -0
  9. package/dist/cluster/export.d.ts.map +1 -0
  10. package/dist/cluster/export.js +2 -0
  11. package/dist/cluster/export.js.map +1 -0
  12. package/dist/defaultConfigSchema.d.ts +27 -0
  13. package/dist/defaultConfigSchema.d.ts.map +1 -0
  14. package/dist/defaultConfigSchema.js +23 -0
  15. package/dist/defaultConfigSchema.js.map +1 -0
  16. package/dist/deviceManager.d.ts +46 -0
  17. package/dist/deviceManager.d.ts.map +1 -0
  18. package/dist/deviceManager.js +26 -1
  19. package/dist/deviceManager.js.map +1 -0
  20. package/dist/index.d.ts +40 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +30 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/logger/export.d.ts +2 -0
  25. package/dist/logger/export.d.ts.map +1 -0
  26. package/dist/logger/export.js +1 -0
  27. package/dist/logger/export.js.map +1 -0
  28. package/dist/matter/export.d.ts +5 -0
  29. package/dist/matter/export.d.ts.map +1 -0
  30. package/dist/matter/export.js +1 -0
  31. package/dist/matter/export.js.map +1 -0
  32. package/dist/matterbridge.d.ts +466 -0
  33. package/dist/matterbridge.d.ts.map +1 -0
  34. package/dist/matterbridge.js +712 -65
  35. package/dist/matterbridge.js.map +1 -0
  36. package/dist/matterbridgeAccessoryPlatform.d.ts +39 -0
  37. package/dist/matterbridgeAccessoryPlatform.d.ts.map +1 -0
  38. package/dist/matterbridgeAccessoryPlatform.js +33 -0
  39. package/dist/matterbridgeAccessoryPlatform.js.map +1 -0
  40. package/dist/matterbridgeBehaviors.d.ts +942 -0
  41. package/dist/matterbridgeBehaviors.d.ts.map +1 -0
  42. package/dist/matterbridgeBehaviors.js +38 -1
  43. package/dist/matterbridgeBehaviors.js.map +1 -0
  44. package/dist/matterbridgeDevice.d.ts +6674 -0
  45. package/dist/matterbridgeDevice.d.ts.map +1 -0
  46. package/dist/matterbridgeDevice.js +1001 -26
  47. package/dist/matterbridgeDevice.js.map +1 -0
  48. package/dist/matterbridgeDeviceTypes.d.ts +82 -0
  49. package/dist/matterbridgeDeviceTypes.d.ts.map +1 -0
  50. package/dist/matterbridgeDeviceTypes.js +59 -13
  51. package/dist/matterbridgeDeviceTypes.js.map +1 -0
  52. package/dist/matterbridgeDynamicPlatform.d.ts +39 -0
  53. package/dist/matterbridgeDynamicPlatform.d.ts.map +1 -0
  54. package/dist/matterbridgeDynamicPlatform.js +33 -0
  55. package/dist/matterbridgeDynamicPlatform.js.map +1 -0
  56. package/dist/matterbridgeEdge.d.ts +89 -0
  57. package/dist/matterbridgeEdge.d.ts.map +1 -0
  58. package/dist/matterbridgeEdge.js +529 -4
  59. package/dist/matterbridgeEdge.js.map +1 -0
  60. package/dist/matterbridgeEndpoint.d.ts +9774 -0
  61. package/dist/matterbridgeEndpoint.d.ts.map +1 -0
  62. package/dist/matterbridgeEndpoint.js +1113 -94
  63. package/dist/matterbridgeEndpoint.js.map +1 -0
  64. package/dist/matterbridgePlatform.d.ts +114 -0
  65. package/dist/matterbridgePlatform.d.ts.map +1 -0
  66. package/dist/matterbridgePlatform.js +122 -13
  67. package/dist/matterbridgePlatform.js.map +1 -0
  68. package/dist/matterbridgeTypes.d.ts +161 -0
  69. package/dist/matterbridgeTypes.d.ts.map +1 -0
  70. package/dist/matterbridgeTypes.js +24 -0
  71. package/dist/matterbridgeTypes.js.map +1 -0
  72. package/dist/matterbridgeWebsocket.d.ts +49 -0
  73. package/dist/matterbridgeWebsocket.d.ts.map +1 -0
  74. package/dist/matterbridgeWebsocket.js +50 -0
  75. package/dist/matterbridgeWebsocket.js.map +1 -0
  76. package/dist/pluginManager.d.ts +238 -0
  77. package/dist/pluginManager.d.ts.map +1 -0
  78. package/dist/pluginManager.js +238 -3
  79. package/dist/pluginManager.js.map +1 -0
  80. package/dist/storage/export.d.ts +2 -0
  81. package/dist/storage/export.d.ts.map +1 -0
  82. package/dist/storage/export.js +1 -0
  83. package/dist/storage/export.js.map +1 -0
  84. package/dist/utils/colorUtils.d.ts +61 -0
  85. package/dist/utils/colorUtils.d.ts.map +1 -0
  86. package/dist/utils/colorUtils.js +236 -89
  87. package/dist/utils/colorUtils.js.map +1 -0
  88. package/dist/utils/export.d.ts +3 -0
  89. package/dist/utils/export.d.ts.map +1 -0
  90. package/dist/utils/export.js +1 -0
  91. package/dist/utils/export.js.map +1 -0
  92. package/dist/utils/utils.d.ts +221 -0
  93. package/dist/utils/utils.d.ts.map +1 -0
  94. package/dist/utils/utils.js +252 -7
  95. package/dist/utils/utils.js.map +1 -0
  96. package/frontend/build/asset-manifest.json +3 -3
  97. package/frontend/build/index.html +1 -1
  98. package/frontend/build/static/js/{main.cb537856.js → main.a742de4e.js} +9 -9
  99. package/frontend/build/static/js/{main.cb537856.js.map → main.a742de4e.js.map} +1 -1
  100. package/npm-shrinkwrap.json +165 -84
  101. package/package.json +4 -4
  102. /package/frontend/build/static/js/{main.cb537856.js.LICENSE.txt → main.a742de4e.js.LICENSE.txt} +0 -0
@@ -1,8 +1,35 @@
1
+ /**
2
+ * This file contains the class MatterbridgeEndpoint that extends the Endpoint class from the Matter.js library.
3
+ *
4
+ * @file matterbridgeEndpoint.ts
5
+ * @author Luca Liguori
6
+ * @date 2024-10-01
7
+ * @version 1.0.0
8
+ *
9
+ * Copyright 2024, 2025, 2026 Luca Liguori.
10
+ *
11
+ * Licensed under the Apache License, Version 2.0 (the "License");
12
+ * you may not use this file except in compliance with the License.
13
+ * You may obtain a copy of the License at
14
+ *
15
+ * http://www.apache.org/licenses/LICENSE-2.0
16
+ *
17
+ * Unless required by applicable law or agreed to in writing, software
18
+ * distributed under the License is distributed on an "AS IS" BASIS,
19
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
+ * See the License for the specific language governing permissions and
21
+ * limitations under the License. *
22
+ */
23
+ /* eslint-disable @typescript-eslint/no-unused-vars */
24
+ // Node.js modules
1
25
  import { createHash } from 'crypto';
26
+ // AnsiLogger module
2
27
  import { AnsiLogger, BLUE, CYAN, YELLOW, db, debugStringify, er, hk, or, rs, zb } from 'node-ansi-logger';
28
+ // Matterbridge
3
29
  import { MatterbridgeBehavior, MatterbridgeBehaviorDevice, MatterbridgeBooleanStateConfigurationServer, MatterbridgeColorControlServer, MatterbridgeDoorLockServer, MatterbridgeFanControlServer, MatterbridgeIdentifyServer, MatterbridgeLevelControlServer, MatterbridgeOnOffServer, MatterbridgeThermostatServer, MatterbridgeWindowCoveringServer, } from './matterbridgeBehaviors.js';
4
30
  import { bridgedNode } from './matterbridgeDeviceTypes.js';
5
31
  import { deepCopy, isValidNumber } from './utils/utils.js';
32
+ // @matter
6
33
  import { Endpoint, MutableEndpoint, SupportedBehaviors, NamedHandler, Lifecycle } from '@matter/main';
7
34
  import { EndpointNumber, VendorId } from '@matter/main';
8
35
  import { AirQuality, AirQualityCluster, BasicInformation, BasicInformationCluster, BooleanState, BooleanStateCluster, BooleanStateConfiguration, BooleanStateConfigurationCluster, BridgedDeviceBasicInformation, BridgedDeviceBasicInformationCluster, CarbonDioxideConcentrationMeasurement, CarbonDioxideConcentrationMeasurementCluster, CarbonMonoxideConcentrationMeasurement, CarbonMonoxideConcentrationMeasurementCluster, ColorControl, ColorControlCluster, ConcentrationMeasurement, Descriptor, DoorLock, DoorLockCluster, ElectricalEnergyMeasurement, ElectricalEnergyMeasurementCluster, ElectricalPowerMeasurement, ElectricalPowerMeasurementCluster, FanControl, FanControlCluster, FixedLabel, FixedLabelCluster, FlowMeasurement, FlowMeasurementCluster, FormaldehydeConcentrationMeasurement, FormaldehydeConcentrationMeasurementCluster, Groups, GroupsCluster, Identify, IdentifyCluster, IlluminanceMeasurement, IlluminanceMeasurementCluster, LevelControl, LevelControlCluster, ModeSelect, ModeSelectCluster, NitrogenDioxideConcentrationMeasurement, NitrogenDioxideConcentrationMeasurementCluster, OccupancySensing, OccupancySensingCluster, OnOff, OnOffCluster, OzoneConcentrationMeasurement, OzoneConcentrationMeasurementCluster, Pm10ConcentrationMeasurement, Pm10ConcentrationMeasurementCluster, Pm1ConcentrationMeasurement, Pm1ConcentrationMeasurementCluster, Pm25ConcentrationMeasurement, Pm25ConcentrationMeasurementCluster, PowerSource, PowerSourceCluster, PowerSourceConfigurationCluster, PowerTopology, PowerTopologyCluster, PressureMeasurement, PressureMeasurementCluster, RadonConcentrationMeasurement, RadonConcentrationMeasurementCluster, RelativeHumidityMeasurement, RelativeHumidityMeasurementCluster, SmokeCoAlarm, SmokeCoAlarmCluster, Switch, SwitchCluster, TemperatureMeasurement, TemperatureMeasurementCluster, Thermostat, ThermostatCluster, TotalVolatileOrganicCompoundsConcentrationMeasurement, TotalVolatileOrganicCompoundsConcentrationMeasurementCluster, UserLabel, UserLabelCluster, WindowCovering, WindowCoveringCluster, } from '@matter/main/clusters';
@@ -23,9 +50,10 @@ import { AirQualityServer, BasicInformationServer, CarbonDioxideConcentrationMea
23
50
  import { ClusterServer, GroupsClusterHandler } from '@project-chip/matter.js/cluster';
24
51
  export class MatterbridgeEndpoint extends Endpoint {
25
52
  static bridgeMode = '';
26
- static logLevel = "info";
53
+ static logLevel = "info" /* LogLevel.INFO */;
27
54
  log;
28
55
  plugin = undefined;
56
+ configUrl = undefined;
29
57
  deviceName = undefined;
30
58
  serialNumber = undefined;
31
59
  uniqueId = undefined;
@@ -42,12 +70,20 @@ export class MatterbridgeEndpoint extends Endpoint {
42
70
  uniqueStorageKey = undefined;
43
71
  tagList = undefined;
44
72
  subType = '';
73
+ // Maps matter deviceTypes and endpoints
45
74
  deviceTypes = new Map();
46
75
  clusterServers = new Map();
47
76
  clusterClients = new Map();
48
77
  commandHandler = new NamedHandler();
78
+ /**
79
+ * Represents a MatterbridgeEndpoint.
80
+ * @constructor
81
+ * @param {DeviceTypeDefinition | AtLeastOne<DeviceTypeDefinition>} definition - The DeviceTypeDefinition(s) of the endpoint.
82
+ * @param {MatterbridgeEndpointOptions} [options={}] - The options for the device.
83
+ */
49
84
  constructor(definition, options = {}, debug = false) {
50
85
  let deviceTypeList = [];
86
+ // Get the first DeviceTypeDefinition
51
87
  let firstDefinition;
52
88
  if (Array.isArray(definition)) {
53
89
  firstDefinition = definition[0];
@@ -60,6 +96,7 @@ export class MatterbridgeEndpoint extends Endpoint {
60
96
  firstDefinition = definition;
61
97
  deviceTypeList = [{ deviceType: firstDefinition.code, revision: firstDefinition.revision }];
62
98
  }
99
+ // Convert the first DeviceTypeDefinition to an EndpointType.Options
63
100
  const deviceTypeDefinitionV8 = {
64
101
  name: firstDefinition.name.replace('-', '_'),
65
102
  deviceType: firstDefinition.code,
@@ -78,6 +115,7 @@ export class MatterbridgeEndpoint extends Endpoint {
78
115
  behaviors: options.tagList ? SupportedBehaviors(DescriptorServer.with(Descriptor.Feature.TagList)) : {},
79
116
  };
80
117
  const endpointV8 = MutableEndpoint(deviceTypeDefinitionV8);
118
+ // Convert the options to an Endpoint.Options
81
119
  const optionsV8 = {
82
120
  id: options.uniqueStorageKey?.replace(/[ .]/g, ''),
83
121
  number: options.endpointId,
@@ -95,15 +133,27 @@ export class MatterbridgeEndpoint extends Endpoint {
95
133
  }
96
134
  else
97
135
  this.deviceTypes.set(firstDefinition.code, firstDefinition);
98
- this.log = new AnsiLogger({ logName: 'MatterbridgeEndpoint', logTimestampFormat: 4, logLevel: debug === true ? "debug" : MatterbridgeEndpoint.logLevel });
136
+ // console.log('MatterbridgeEndpoint.option', options);
137
+ // console.log('MatterbridgeEndpoint.endpointV8', endpointV8);
138
+ // console.log('MatterbridgeEndpoint.optionsV8', optionsV8);
139
+ // Create the logger
140
+ this.log = new AnsiLogger({ logName: 'MatterbridgeEndpoint', logTimestampFormat: 4 /* TimestampFormat.TIME_MILLIS */, logLevel: debug === true ? "debug" /* LogLevel.DEBUG */ : MatterbridgeEndpoint.logLevel });
99
141
  this.log.debug(`${YELLOW}new${db} MatterbridgeEndpoint: ${zb}${'0x' + firstDefinition.code.toString(16).padStart(4, '0')}${db}-${zb}${firstDefinition.name}${db} ` +
100
142
  `id: ${CYAN}${options.uniqueStorageKey}${db} number: ${CYAN}${options.endpointId}${db} taglist: ${CYAN}${options.tagList ? debugStringify(options.tagList) : 'undefined'}${db}`);
143
+ // Add MatterbridgeBehavior with MatterbridgeBehaviorDevice
101
144
  this.behaviors.require(MatterbridgeBehavior, { deviceCommand: new MatterbridgeBehaviorDevice(this.log, this.commandHandler, undefined) });
102
145
  }
146
+ /**
147
+ * Loads an instance of the MatterbridgeDevice class.
148
+ *
149
+ * @param {DeviceTypeDefinition | AtLeastOne<DeviceTypeDefinition>} definition - The DeviceTypeDefinition(s) of the device.
150
+ * @returns MatterbridgeDevice instance.
151
+ */
103
152
  static async loadInstance(definition, options = {}, debug = false) {
104
153
  return new MatterbridgeEndpoint(definition, options, debug);
105
154
  }
106
155
  static getBehaviourTypesFromClusterServerIds(clusterServerList) {
156
+ // Map Server ClusterId to Behavior.Type
107
157
  const behaviorTypes = [];
108
158
  clusterServerList.forEach((clusterId) => {
109
159
  behaviorTypes.push(MatterbridgeEndpoint.getBehaviourTypeFromClusterServerId(clusterId));
@@ -111,12 +161,15 @@ export class MatterbridgeEndpoint extends Endpoint {
111
161
  return behaviorTypes;
112
162
  }
113
163
  static getBehaviourTypesFromClusterClientIds(clusterClientList) {
164
+ // Map Client ClusterId to Behavior.Type
114
165
  const behaviorTypes = [];
115
166
  clusterClientList.forEach((clusterId) => {
167
+ // behaviorTypes.push(MatterbridgeEndpoint.getBehaviourTypeFromClusterClientId(clusterId));
116
168
  });
117
169
  return behaviorTypes;
118
170
  }
119
171
  static getBehaviourTypeFromClusterServerId(clusterId, subType) {
172
+ // Map ClusterId to Behavior.Type
120
173
  if (clusterId === Identify.Cluster.id)
121
174
  return MatterbridgeIdentifyServer;
122
175
  if (clusterId === Groups.Cluster.id)
@@ -124,15 +177,15 @@ export class MatterbridgeEndpoint extends Endpoint {
124
177
  if (clusterId === OnOff.Cluster.id)
125
178
  return MatterbridgeOnOffServer.with('Lighting');
126
179
  if (clusterId === LevelControl.Cluster.id)
127
- return MatterbridgeLevelControlServer;
180
+ return MatterbridgeLevelControlServer.with('OnOff', 'Lighting');
128
181
  if (clusterId === ColorControl.Cluster.id && subType === undefined)
129
182
  return MatterbridgeColorControlServer;
130
183
  if (clusterId === ColorControl.Cluster.id && subType === 'CompleteColorControl')
131
184
  return MatterbridgeColorControlServer;
132
185
  if (clusterId === ColorControl.Cluster.id && subType === 'XyColorControl')
133
- return MatterbridgeColorControlServer.with('Xy');
186
+ return MatterbridgeColorControlServer.with('Xy', 'ColorTemperature');
134
187
  if (clusterId === ColorControl.Cluster.id && subType === 'HueSaturationColorControl')
135
- return MatterbridgeColorControlServer.with('HueSaturation');
188
+ return MatterbridgeColorControlServer.with('HueSaturation', 'ColorTemperature');
136
189
  if (clusterId === ColorControl.Cluster.id && subType === 'ColorTemperatureColorControl')
137
190
  return MatterbridgeColorControlServer.with('ColorTemperature');
138
191
  if (clusterId === DoorLock.Cluster.id)
@@ -222,12 +275,21 @@ export class MatterbridgeEndpoint extends Endpoint {
222
275
  return MatterbridgeIdentifyServer;
223
276
  }
224
277
  static getBehaviourTypeFromClusterClientId(clusterId) {
278
+ // Map ClusterId to Behavior.Type
225
279
  return IdentifyBehavior;
226
280
  }
281
+ /**
282
+ * Adds a device type to the list of device types.
283
+ * If the device type is not already present in the list, it will be added.
284
+ *
285
+ * @param {DeviceTypeDefinition} deviceType - The device type to add.
286
+ */
227
287
  addDeviceType(deviceType) {
228
288
  if (!this.deviceTypes.has(deviceType.code)) {
289
+ // Keep the Matterbridge internal map
229
290
  this.log.debug(`addDeviceType: ${zb}${'0x' + deviceType.code.toString(16).padStart(4, '0')}${db}-${zb}${deviceType.name}${db}`);
230
291
  this.deviceTypes.set(deviceType.code, deviceType);
292
+ // Add the device types to the descriptor server
231
293
  const deviceTypeList = Array.from(this.deviceTypes.values()).map((dt) => ({
232
294
  deviceType: dt.code,
233
295
  revision: dt.revision,
@@ -245,6 +307,12 @@ export class MatterbridgeEndpoint extends Endpoint {
245
307
  }
246
308
  }
247
309
  }
310
+ /**
311
+ * Adds one or more device types with the required cluster servers and the specified cluster servers.
312
+ *
313
+ * @param {AtLeastOne<DeviceTypeDefinition>} deviceTypes - The device types to add.
314
+ * @param {ClusterId[]} includeServerList - The list of cluster IDs to include.
315
+ */
248
316
  addDeviceTypeWithClusterServer(deviceTypes, includeServerList) {
249
317
  this.log.debug('addDeviceTypeWithClusterServer:');
250
318
  deviceTypes.forEach((deviceType) => {
@@ -267,6 +335,12 @@ export class MatterbridgeEndpoint extends Endpoint {
267
335
  });
268
336
  this.addClusterServerFromList(this, includeServerList);
269
337
  }
338
+ /**
339
+ * Adds the required cluster servers (only if they are not present) for the device types of the specified endpoint.
340
+ *
341
+ * @param {MatterbridgeEndpoint} endpoint - The endpoint to add the required cluster servers to.
342
+ * @returns {MatterbridgeEndpoint} The updated endpoint with the required cluster servers added.
343
+ */
270
344
  addRequiredClusterServers(endpoint) {
271
345
  const requiredServerList = [];
272
346
  this.log.debug(`addRequiredClusterServer for ${CYAN}${endpoint.id}${db}`);
@@ -283,6 +357,12 @@ export class MatterbridgeEndpoint extends Endpoint {
283
357
  this.addClusterServerFromList(endpoint, requiredServerList);
284
358
  return endpoint;
285
359
  }
360
+ /**
361
+ * Adds the optional cluster servers (only if they are not present) for the device types of the specified endpoint.
362
+ *
363
+ * @param {MatterbridgeEndpoint} endpoint - The endpoint to add the required cluster servers to.
364
+ * @returns {MatterbridgeEndpoint} The updated endpoint with the required cluster servers added.
365
+ */
286
366
  addOptionalClusterServers(endpoint) {
287
367
  const optionalServerList = [];
288
368
  this.log.debug(`addRequiredClusterServer for ${CYAN}${endpoint.id}${db}`);
@@ -299,6 +379,17 @@ export class MatterbridgeEndpoint extends Endpoint {
299
379
  this.addClusterServerFromList(endpoint, optionalServerList);
300
380
  return endpoint;
301
381
  }
382
+ /**
383
+ * Adds a child endpoint with the specified device types and options.
384
+ * If the child endpoint is not already present, it will be created and added.
385
+ * If the child endpoint is already present, the device types will be added to the existing child endpoint.
386
+ *
387
+ * @param {string} endpointName - The name of the new endpoint to add.
388
+ * @param {AtLeastOne<DeviceTypeDefinition>} deviceTypes - The device types to add.
389
+ * @param {MatterbridgeEndpointOptions} [options={}] - The options for the endpoint.
390
+ * @param {boolean} [debug=false] - Whether to enable debug logging.
391
+ * @returns {MatterbridgeEndpoint} - The child endpoint that was found or added.
392
+ */
302
393
  addChildDeviceType(endpointName, deviceTypes, options = {}, debug = false) {
303
394
  this.log.debug(`addChildDeviceType: ${CYAN}${endpointName}${db}`);
304
395
  let child = this.getChildEndpointByName(endpointName);
@@ -329,6 +420,18 @@ export class MatterbridgeEndpoint extends Endpoint {
329
420
  }
330
421
  return child;
331
422
  }
423
+ /**
424
+ * Adds a child endpoint with one or more device types with the required cluster servers and the specified cluster servers.
425
+ * If the child endpoint is not already present in the childEndpoints, it will be added.
426
+ * If the child endpoint is already present in the childEndpoints, the device types and cluster servers will be added to the existing child endpoint.
427
+ *
428
+ * @param {string} endpointName - The name of the new enpoint to add.
429
+ * @param {AtLeastOne<DeviceTypeDefinition>} deviceTypes - The device types to add.
430
+ * @param {ClusterId[]} [includeServerList=[]] - The list of cluster IDs to include.
431
+ * @param {MatterbridgeEndpointOptions} [options={}] - The options for the device.
432
+ * @param {boolean} [debug=false] - Whether to enable debug logging.
433
+ * @returns {MatterbridgeEndpoint} - The child endpoint that was found or added.
434
+ */
332
435
  addChildDeviceTypeWithClusterServer(endpointName, deviceTypes, includeServerList = [], options = {}, debug = false) {
333
436
  this.log.debug(`addChildDeviceTypeWithClusterServer: ${CYAN}${endpointName}${db}`);
334
437
  let child = this.getChildEndpointByName(endpointName);
@@ -372,6 +475,12 @@ export class MatterbridgeEndpoint extends Endpoint {
372
475
  }
373
476
  return child;
374
477
  }
478
+ /**
479
+ * Retrieves a child endpoint by its name.
480
+ *
481
+ * @param {string} endpointName - The name of the endpoint to retrieve.
482
+ * @returns {Endpoint | undefined} The child endpoint with the specified name, or undefined if not found.
483
+ */
375
484
  getChildEndpointByName(endpointName) {
376
485
  return this.parts.find((part) => part.id === endpointName);
377
486
  }
@@ -390,6 +499,8 @@ export class MatterbridgeEndpoint extends Endpoint {
390
499
  });
391
500
  }
392
501
  async setBridgedDeviceReachability(reachable) {
502
+ // await this.setAttribute(BridgedDeviceBasicInformationCluster.id, 'reachable', reachable, this.log);
503
+ // await this.triggerEvent(BridgedDeviceBasicInformationCluster.id, 'reachableChanged', { reachableNewValue: reachable }, this.log);
393
504
  }
394
505
  hasClusterServer(cluster) {
395
506
  return this.clusterServers.has(cluster.id);
@@ -407,11 +518,16 @@ export class MatterbridgeEndpoint extends Endpoint {
407
518
  return this.clusterServers.get(clusterId);
408
519
  }
409
520
  addTagList(endpoint, mfgCode, namespaceId, tag, label) {
521
+ // Do nothing here only for old api compatibility
410
522
  }
411
523
  addClusterServer(cluster) {
524
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
412
525
  const options = {};
413
526
  for (const attribute of Object.values(cluster.attributes)) {
527
+ // console.error('Attribute:', (attribute as any).id, (attribute as any).name, (attribute as any).value);
528
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
414
529
  if (attribute.id < 0xfff0) {
530
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
415
531
  options[attribute.name] = attribute.value;
416
532
  }
417
533
  }
@@ -420,9 +536,9 @@ export class MatterbridgeEndpoint extends Endpoint {
420
536
  this.log.debug(`****cluster ${hk}${'0x' + cluster.id.toString(16).padStart(4, '0')}${db}-${hk}${getClusterNameById(cluster.id)}${db} already added`);
421
537
  }
422
538
  this.subType = '';
423
- if (cluster.id === ColorControl.Cluster.id && cluster.isAttributeSupportedByName('currentX') && !cluster.isAttributeSupportedByName('currentHue') && !cluster.isAttributeSupportedByName('colorTemperatureMireds'))
539
+ if (cluster.id === ColorControl.Cluster.id && cluster.isAttributeSupportedByName('currentX') && !cluster.isAttributeSupportedByName('currentHue'))
424
540
  this.subType = 'XyColorControl';
425
- else if (cluster.id === ColorControl.Cluster.id && cluster.isAttributeSupportedByName('currentHue') && !cluster.isAttributeSupportedByName('currentX') && !cluster.isAttributeSupportedByName('colorTemperatureMireds'))
541
+ else if (cluster.id === ColorControl.Cluster.id && cluster.isAttributeSupportedByName('currentHue') && !cluster.isAttributeSupportedByName('currentX'))
426
542
  this.subType = 'HueSaturationColorControl';
427
543
  else if (cluster.id === ColorControl.Cluster.id && cluster.isAttributeSupportedByName('colorTemperatureMireds') && !cluster.isAttributeSupportedByName('currentHue') && !cluster.isAttributeSupportedByName('currentX'))
428
544
  this.subType = 'ColorTemperatureColorControl';
@@ -445,11 +561,24 @@ export class MatterbridgeEndpoint extends Endpoint {
445
561
  if (cluster.id === ThermostatCluster.id && cluster.isAttributeSupportedByName('minSetpointDeadBand'))
446
562
  this.subType = 'AutoModeThermostat';
447
563
  const behavior = MatterbridgeEndpoint.getBehaviourTypeFromClusterServerId(cluster.id, this.subType);
564
+ /*
565
+ if (cluster.id === PowerTopologyCluster.id && this.clusterServers.has(cluster.id)) return; // TODO remove this workaround
566
+ if (cluster.id === ElectricalPowerMeasurementCluster.id && this.clusterServers.has(cluster.id)) return; // TODO remove this workaround
567
+ if (cluster.id === ElectricalEnergyMeasurementCluster.id && this.clusterServers.has(cluster.id)) return; // TODO remove this workaround
568
+ if (cluster.id === ThermostatCluster.id && this.clusterServers.has(cluster.id)) return; // TODO remove this workaround
569
+ */
448
570
  this.clusterServers.set(cluster.id, cluster);
449
571
  if (cluster.id === BasicInformationCluster.id)
450
- return;
572
+ return; // Not used in Matterbridge edge for devices. Only on server node.
451
573
  this.behaviors.require(behavior, options);
452
574
  }
575
+ /**
576
+ * Adds cluster servers to the specified endpoint based on the provided server list.
577
+ *
578
+ * @param {Endpoint} endpoint - The endpoint to add cluster servers to.
579
+ * @param {ClusterId[]} includeServerList - The list of cluster IDs to include.
580
+ * @returns void
581
+ */
453
582
  addClusterServerFromList(endpoint, includeServerList) {
454
583
  if (includeServerList.includes(Identify.Cluster.id))
455
584
  endpoint.addClusterServer(this.getDefaultIdentifyClusterServer());
@@ -519,6 +648,8 @@ export class MatterbridgeEndpoint extends Endpoint {
519
648
  endpoint.addClusterServer(this.getDefaultRadonConcentrationMeasurementClusterServer());
520
649
  if (includeServerList.includes(TotalVolatileOrganicCompoundsConcentrationMeasurement.Cluster.id))
521
650
  endpoint.addClusterServer(this.getDefaultTvocMeasurementClusterServer());
651
+ // if (includeServerList.includes(DeviceEnergyManagement.Cluster.id)) endpoint.addClusterServer(this.getDefaultDeviceEnergyManagementClusterServer());
652
+ // if (includeServerList.includes(DeviceEnergyManagementMode.Cluster.id)) endpoint.addClusterServer(this.getDefaultDeviceEnergyManagementModeClusterServer());
522
653
  }
523
654
  async addFixedLabel(label, value) {
524
655
  if (!this.clusterServers.get(FixedLabelCluster.id)) {
@@ -529,6 +660,7 @@ export class MatterbridgeEndpoint extends Endpoint {
529
660
  return;
530
661
  }
531
662
  this.log.debug(`addFixedLabel: add label ${CYAN}${label}${db} value ${CYAN}${value}${db}`);
663
+ // if (this.construction.status !== Lifecycle.Status.Active) await this.construction.ready;
532
664
  const labelList = (this.getAttribute(FixedLabelCluster.id, 'labelList', this.log) ?? []).filter((entryLabel) => entryLabel.label !== label);
533
665
  labelList.push({ label, value });
534
666
  await this.setAttribute(FixedLabelCluster.id, 'labelList', labelList, this.log);
@@ -542,6 +674,7 @@ export class MatterbridgeEndpoint extends Endpoint {
542
674
  return;
543
675
  }
544
676
  this.log.debug(`addUserLabel: add label ${CYAN}${label}${db} value ${CYAN}${value}${db}`);
677
+ // if (this.construction.status !== Lifecycle.Status.Active) await this.construction.ready;
545
678
  const labelList = (this.getAttribute(UserLabelCluster.id, 'labelList', this.log) ?? []).filter((entryLabel) => entryLabel.label !== label);
546
679
  labelList.push({ label, value });
547
680
  await this.setAttribute(UserLabelCluster.id, 'labelList', labelList, this.log);
@@ -556,6 +689,16 @@ export class MatterbridgeEndpoint extends Endpoint {
556
689
  return name;
557
690
  return name.charAt(0).toLowerCase() + name.slice(1);
558
691
  }
692
+ /**
693
+ * Retrieves the value of the specified attribute from the given endpoint and cluster.
694
+ *
695
+ * @param {ClusterId} clusterId - The ID of the cluster to retrieve the attribute from.
696
+ * @param {string} attribute - The name of the attribute to retrieve.
697
+ * @param {AnsiLogger} [log] - Optional logger for error and info messages.
698
+ * @param {MatterbridgeEndpoint} [endpoint] - Optional the child endpoint to retrieve the attribute from.
699
+ * @returns {any} The value of the attribute, or undefined if the attribute is not found.
700
+ */
701
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
559
702
  getAttribute(clusterId, attribute, log, endpoint) {
560
703
  if (!endpoint)
561
704
  endpoint = this;
@@ -564,6 +707,7 @@ export class MatterbridgeEndpoint extends Endpoint {
564
707
  this.log.error(`getAttribute ${hk}${clusterName}.${attribute}${er} error: Endpoint ${or}${endpoint.id}${er} is in the ${BLUE}${endpoint.construction.status}${er} state`);
565
708
  return undefined;
566
709
  }
710
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
567
711
  const state = endpoint.state;
568
712
  if (!(clusterName in state)) {
569
713
  this.log.error(`getAttribute error: Cluster ${'0x' + clusterId.toString(16).padStart(4, '0')}:${clusterName} not found on endpoint ${or}${endpoint.id}${er}:${or}${endpoint.number}${er}`);
@@ -578,14 +722,27 @@ export class MatterbridgeEndpoint extends Endpoint {
578
722
  log?.info(`${db}Get endpoint ${or}${endpoint.id}${db}:${or}${endpoint.number}${db} attribute ${hk}${this.capitalizeFirstLetter(clusterName)}${db}.${hk}${attribute}${db} value ${YELLOW}${typeof value === 'object' ? debugStringify(value) : value}${db}`);
579
723
  return value;
580
724
  }
725
+ /**
726
+ * Sets the value of an attribute on a cluster server endpoint.
727
+ *
728
+ * @param {ClusterId} clusterId - The ID of the cluster.
729
+ * @param {string} attribute - The name of the attribute.
730
+ * @param {any} value - The value to set for the attribute.
731
+ * @param {AnsiLogger} [log] - (Optional) The logger to use for logging errors and information.
732
+ * @param {MatterbridgeEndpoint} [endpoint] - (Optional) The endpoint to set the attribute on. If not provided, the attribute will be set on the current endpoint.
733
+ * @returns {Promise<boolean>} - A promise that resolves to a boolean indicating whether the attribute was successfully set.
734
+ */
735
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
581
736
  async setAttribute(clusterId, attribute, value, log, endpoint) {
582
737
  if (!endpoint)
583
738
  endpoint = this;
584
739
  const clusterName = this.lowercaseFirstLetter(getClusterNameById(clusterId));
585
740
  if (endpoint.construction.status !== Lifecycle.Status.Active) {
586
741
  this.log.error(`setAttribute ${hk}${clusterName}.${attribute}${er} error: Endpoint ${or}${endpoint.id}${er} is in the ${BLUE}${endpoint.construction.status}${er} state`);
742
+ // await endpoint.construction.ready;
587
743
  return false;
588
744
  }
745
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
589
746
  const state = endpoint.state;
590
747
  if (!(clusterName in state)) {
591
748
  this.log.error(`setAttribute ${hk}${attribute}${er} error: Cluster ${'0x' + clusterId.toString(16).padStart(4, '0')}:${clusterName} not found on endpoint ${or}${endpoint.id}${er}:${or}${endpoint.number}${er}`);
@@ -600,18 +757,32 @@ export class MatterbridgeEndpoint extends Endpoint {
600
757
  if (typeof oldValue === 'object')
601
758
  oldValue = deepCopy(oldValue);
602
759
  await endpoint.setStateOf(endpoint.behaviors.supported[clusterName], { [attribute]: value });
760
+ // await endpoint.set({ [clusterName]: { [attribute]: value } });
603
761
  log?.info(`${db}Set endpoint ${or}${endpoint.id}${db}:${or}${endpoint.number}${db} attribute ${hk}${this.capitalizeFirstLetter(clusterName)}${db}.${hk}${attribute}${db} ` +
604
762
  `from ${YELLOW}${typeof oldValue === 'object' ? debugStringify(oldValue) : oldValue}${db} ` +
605
763
  `to ${YELLOW}${typeof value === 'object' ? debugStringify(value) : value}${db}`);
606
764
  return true;
607
765
  }
766
+ /**
767
+ * Subscribes to an attribute on a cluster.
768
+ *
769
+ * @param {ClusterId} clusterId - The ID of the cluster.
770
+ * @param {string} attribute - The name of the attribute to subscribe to.
771
+ * @param {(newValue: any, oldValue: any) => void} listener - A callback function that will be called when the attribute value changes.
772
+ * @param {AnsiLogger} [log] - Optional logger for logging errors and information.
773
+ * @param {MatterbridgeEndpoint} [endpoint] - Optional endpoint to subscribe the attribute on. Defaults to the current endpoint.
774
+ * @returns {boolean} - A boolean indicating whether the subscription was successful.
775
+ */
776
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
608
777
  async subscribeAttribute(clusterId, attribute, listener, log, endpoint) {
609
778
  if (!endpoint)
610
779
  endpoint = this;
611
780
  const clusterName = this.lowercaseFirstLetter(getClusterNameById(clusterId));
612
781
  if (endpoint.construction.status !== Lifecycle.Status.Active) {
782
+ // this.log.error(`subscribeAttribute ${hk}${clusterName}.${attribute}${er} error: Endpoint ${or}${endpoint.id}${er} is in the ${BLUE}${endpoint.construction.status}${er} state`);
613
783
  await endpoint.construction.ready;
614
784
  }
785
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
615
786
  const events = endpoint.events;
616
787
  if (!(clusterName in events)) {
617
788
  this.log.error(`subscribeAttribute ${hk}${attribute}${er} error: Cluster ${'0x' + clusterId.toString(16).padStart(4, '0')}:${clusterName} not found on endpoint ${or}${endpoint.id}${er}:${or}${endpoint.number}${er}`);
@@ -626,31 +797,120 @@ export class MatterbridgeEndpoint extends Endpoint {
626
797
  log?.info(`${db}Subscribe endpoint ${or}${endpoint.id}${db}:${or}${endpoint.number}${db} attribute ${hk}${this.capitalizeFirstLetter(clusterName)}${db}.${hk}${attribute}${db}`);
627
798
  return true;
628
799
  }
800
+ /**
801
+ * Triggers an event on the specified cluster.
802
+ *
803
+ * @param {ClusterId} clusterId - The ID of the cluster.
804
+ * @param {string} event - The name of the event to trigger.
805
+ * @param {Record<string, boolean | number | bigint | string | object | undefined | null>} payload - The payload to pass to the event.
806
+ * @param {AnsiLogger} [log] - Optional logger for logging information.
807
+ * @param {MatterbridgeEndpoint} [endpoint] - Optional endpoint to trigger the event on. Defaults to the current endpoint.
808
+ * @returns {Promise<boolean>} - A promise that resolves to a boolean indicating whether the event was successfully triggered.
809
+ */
629
810
  async triggerEvent(clusterId, event, payload, log, endpoint) {
630
811
  if (!endpoint)
631
812
  endpoint = this;
632
813
  const clusterName = this.lowercaseFirstLetter(getClusterNameById(clusterId));
633
814
  if (endpoint.construction.status !== Lifecycle.Status.Active) {
815
+ // this.log.error(`triggerEvent ${hk}${clusterName}.${event}${er} error: Endpoint ${or}${endpoint.id}${er} is in the ${BLUE}${endpoint.construction.status}${er} state`);
634
816
  await endpoint.construction.ready;
817
+ // return false;
635
818
  }
819
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
636
820
  const events = endpoint.events;
637
821
  if (!(clusterName in events) || !(event in events[clusterName])) {
638
822
  this.log.error(`triggerEvent ${hk}${event}${er} error: Cluster ${'0x' + clusterId.toString(16).padStart(4, '0')}:${clusterName} not found on endpoint ${or}${endpoint.id}${er}:${or}${endpoint.number}${er}`);
639
823
  return false;
640
824
  }
825
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
826
+ // @ts-ignore
641
827
  await endpoint.act((agent) => agent[clusterName].events[event].emit(payload, agent.context));
642
828
  log?.info(`${db}Trigger event ${hk}${this.capitalizeFirstLetter(clusterName)}${db}.${hk}${event}${db} with ${debugStringify(payload)}${db} on endpoint ${or}${endpoint.id}${db}:${or}${endpoint.number}${db} `);
643
829
  return true;
644
830
  }
831
+ /**
832
+ * Adds a command handler for the specified command.
833
+ *
834
+ * @param {keyof MatterbridgeEndpointCommands} command - The command to add the handler for.
835
+ * @param {(data: any) => void} handler - The handler function to execute when the command is received.
836
+ * @returns {void}
837
+ */
838
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
645
839
  addCommandHandler(command, handler) {
646
840
  this.commandHandler.addHandler(command, handler);
647
841
  }
842
+ /**
843
+ * Serializes the Matterbridge device into a serialized object.
844
+ *
845
+ * @param pluginName - The name of the plugin.
846
+ * @returns The serialized Matterbridge device object.
847
+ */
648
848
  serialize() {
649
849
  return undefined;
650
- }
850
+ /*
851
+ if (!this.serialNumber || !this.deviceName || !this.uniqueId) return;
852
+ const cluster = this.getClusterServer(BasicInformationCluster) ?? this.getClusterServer(BridgedDeviceBasicInformationCluster);
853
+ if (!cluster) return;
854
+ const serialized: SerializedMatterbridgeDevice = {
855
+ pluginName: this.plugin ?? 'Unknown',
856
+ serialNumber: this.serialNumber,
857
+ deviceName: this.deviceName,
858
+ uniqueId: this.uniqueId,
859
+ productName: cluster.attributes.productName?.getLocal(),
860
+ vendorId: cluster.attributes.vendorId?.getLocal(),
861
+ vendorName: cluster.attributes.vendorName?.getLocal(),
862
+ deviceTypes: Array.from(this.deviceTypes.values()),
863
+ endpoint: this.number,
864
+ endpointName: this.id,
865
+ clusterServersId: [],
866
+ };
867
+ this.getAllClusterServers().forEach((clusterServer) => {
868
+ serialized.clusterServersId.push(clusterServer.id);
869
+ });
870
+ return serialized;
871
+ */
872
+ }
873
+ /**
874
+ * Deserializes the device into a serialized object.
875
+ *
876
+ * @returns The deserialized MatterbridgeDevice.
877
+ */
651
878
  static deserialize(serializedDevice) {
652
879
  return undefined;
653
- }
880
+ /*
881
+ const device = new MatterbridgeDevice(serializedDevice.deviceTypes);
882
+ device.serialNumber = serializedDevice.serialNumber;
883
+ device.deviceName = serializedDevice.deviceName;
884
+ device.uniqueId = serializedDevice.uniqueId;
885
+ for (const clusterId of serializedDevice.clusterServersId) {
886
+ if (clusterId === BasicInformationCluster.id)
887
+ device.createDefaultBasicInformationClusterServer(
888
+ serializedDevice.deviceName,
889
+ serializedDevice.serialNumber,
890
+ serializedDevice.vendorId ?? 0xfff1,
891
+ serializedDevice.vendorName ?? 'Matterbridge',
892
+ serializedDevice.productId ?? 0x8000,
893
+ serializedDevice.productName ?? 'Matterbridge device',
894
+ );
895
+ else if (clusterId === BridgedDeviceBasicInformationCluster.id)
896
+ device.createDefaultBridgedDeviceBasicInformationClusterServer(
897
+ serializedDevice.deviceName,
898
+ serializedDevice.serialNumber,
899
+ serializedDevice.vendorId ?? 0xfff1,
900
+ serializedDevice.vendorName ?? 'Matterbridge',
901
+ serializedDevice.productName ?? 'Matterbridge device',
902
+ );
903
+ else device.addClusterServerFromList(device, [clusterId]);
904
+ }
905
+ return device;
906
+ */
907
+ }
908
+ /**
909
+ * From here copy paste from MatterbridgeDevice
910
+ */
911
+ /**
912
+ * Get a default IdentifyCluster server.
913
+ */
654
914
  getDefaultIdentifyClusterServer(identifyTime = 0, identifyType = Identify.IdentifyType.None) {
655
915
  return ClusterServer(IdentifyCluster, {
656
916
  identifyTime,
@@ -666,28 +926,88 @@ export class MatterbridgeEndpoint extends Endpoint {
666
926
  },
667
927
  });
668
928
  }
929
+ /**
930
+ * Creates a default IdentifyCluster server.
931
+ */
669
932
  createDefaultIdentifyClusterServer(identifyTime = 0, identifyType = Identify.IdentifyType.None) {
670
933
  this.addClusterServer(this.getDefaultIdentifyClusterServer(identifyTime, identifyType));
671
934
  }
935
+ /**
936
+ * Get a default IdentifyCluster server.
937
+ */
672
938
  getDefaultGroupsClusterServer() {
673
939
  return ClusterServer(GroupsCluster, {
674
940
  nameSupport: {
675
941
  nameSupport: true,
676
942
  },
677
943
  }, GroupsClusterHandler());
944
+ // return createDefaultGroupsClusterServer();
678
945
  }
946
+ /**
947
+ * Creates a default groups cluster server and adds it to the device.
948
+ */
679
949
  createDefaultGroupsClusterServer() {
680
950
  this.addClusterServer(this.getDefaultGroupsClusterServer());
681
951
  }
952
+ /**
953
+ * Get a default scenes cluster server and adds it to the current instance.
954
+ * @deprecated This method is deprecated.
955
+ *
956
+ */
682
957
  getDefaultScenesClusterServer() {
683
- }
958
+ /*
959
+ return ClusterServer(
960
+ ScenesCluster,
961
+ {
962
+ sceneCount: 0,
963
+ currentScene: 0,
964
+ currentGroup: GroupId(0),
965
+ sceneValid: false,
966
+ nameSupport: {
967
+ nameSupport: true,
968
+ },
969
+ lastConfiguredBy: null,
970
+ },
971
+ {},
972
+ );
973
+ */
974
+ }
975
+ /**
976
+ * Creates a default scenes cluster server and adds it to the current instance.
977
+ * @deprecated This method is deprecated.
978
+ */
684
979
  createDefaultScenesClusterServer() {
685
- }
980
+ /*
981
+ this.addClusterServer(this.getDefaultScenesClusterServer());
982
+ */
983
+ }
984
+ /**
985
+ * Creates a unique identifier based on the provided parameters.
986
+ * @param param1 - The first parameter.
987
+ * @param param2 - The second parameter.
988
+ * @param param3 - The third parameter.
989
+ * @param param4 - The fourth parameter.
990
+ * @returns A unique identifier generated using the MD5 hash algorithm.
991
+ */
686
992
  createUniqueId(param1, param2, param3, param4) {
687
993
  const hash = createHash('md5');
688
994
  hash.update(param1 + param2 + param3 + param4);
689
995
  return hash.digest('hex');
690
996
  }
997
+ /**
998
+ * Get a default Basic Information Cluster Server.
999
+ *
1000
+ * @param deviceName - The name of the device.
1001
+ * @param serialNumber - The serial number of the device.
1002
+ * @param vendorId - The vendor ID of the device.
1003
+ * @param vendorName - The vendor name of the device.
1004
+ * @param productId - The product ID of the device.
1005
+ * @param productName - The product name of the device.
1006
+ * @param softwareVersion - The software version of the device. Default is 1.
1007
+ * @param softwareVersionString - The software version string of the device. Default is 'v.1.0.0'.
1008
+ * @param hardwareVersion - The hardware version of the device. Default is 1.
1009
+ * @param hardwareVersionString - The hardware version string of the device. Default is 'v.1.0.0'.
1010
+ */
691
1011
  getDefaultBasicInformationClusterServer(deviceName, serialNumber, vendorId, vendorName, productId, productName, softwareVersion = 1, softwareVersionString = '1.0.0', hardwareVersion = 1, hardwareVersionString = '1.0.0') {
692
1012
  this.log.logName = deviceName;
693
1013
  this.deviceName = deviceName;
@@ -708,6 +1028,7 @@ export class MatterbridgeEndpoint extends Endpoint {
708
1028
  vendorName: vendorName.slice(0, 32),
709
1029
  productId: productId,
710
1030
  productName: productName.slice(0, 32),
1031
+ productUrl: 'https://www.npmjs.com/package/matterbridge',
711
1032
  productLabel: deviceName.slice(0, 64),
712
1033
  nodeLabel: deviceName.slice(0, 32),
713
1034
  serialNumber: serialNumber.slice(0, 32),
@@ -727,6 +1048,20 @@ export class MatterbridgeEndpoint extends Endpoint {
727
1048
  reachableChanged: true,
728
1049
  });
729
1050
  }
1051
+ /**
1052
+ * Creates a default Basic Information Cluster Server.
1053
+ *
1054
+ * @param deviceName - The name of the device.
1055
+ * @param serialNumber - The serial number of the device.
1056
+ * @param vendorId - The vendor ID of the device.
1057
+ * @param vendorName - The vendor name of the device.
1058
+ * @param productId - The product ID of the device.
1059
+ * @param productName - The product name of the device.
1060
+ * @param softwareVersion - The software version of the device. Default is 1.
1061
+ * @param softwareVersionString - The software version string of the device. Default is 'v.1.0.0'.
1062
+ * @param hardwareVersion - The hardware version of the device. Default is 1.
1063
+ * @param hardwareVersionString - The hardware version string of the device. Default is 'v.1.0.0'.
1064
+ */
730
1065
  createDefaultBasicInformationClusterServer(deviceName, serialNumber, vendorId, vendorName, productId, productName, softwareVersion = 1, softwareVersionString = '1.0.0', hardwareVersion = 1, hardwareVersionString = '1.0.0') {
731
1066
  if (MatterbridgeEndpoint.bridgeMode === 'bridge') {
732
1067
  this.addDeviceType(bridgedNode);
@@ -735,6 +1070,19 @@ export class MatterbridgeEndpoint extends Endpoint {
735
1070
  }
736
1071
  this.addClusterServer(this.getDefaultBasicInformationClusterServer(deviceName, serialNumber, vendorId, vendorName, productId, productName, softwareVersion, softwareVersionString, hardwareVersion, hardwareVersionString));
737
1072
  }
1073
+ /**
1074
+ * Get a default BridgedDeviceBasicInformationClusterServer.
1075
+ *
1076
+ * @param deviceName - The name of the device.
1077
+ * @param serialNumber - The serial number of the device.
1078
+ * @param vendorId - The vendor ID of the device.
1079
+ * @param vendorName - The name of the vendor.
1080
+ * @param productName - The name of the product.
1081
+ * @param softwareVersion - The software version of the device. Default is 1.
1082
+ * @param softwareVersionString - The software version string of the device. Default is 'v.1.0.0'.
1083
+ * @param hardwareVersion - The hardware version of the device. Default is 1.
1084
+ * @param hardwareVersionString - The hardware version string of the device. Default is 'v.1.0.0'.
1085
+ */
738
1086
  getDefaultBridgedDeviceBasicInformationClusterServer(deviceName, serialNumber, vendorId, vendorName, productName, softwareVersion = 1, softwareVersionString = '1.0.0', hardwareVersion = 1, hardwareVersionString = '1.0.0') {
739
1087
  this.log.logName = deviceName;
740
1088
  this.deviceName = deviceName;
@@ -749,9 +1097,10 @@ export class MatterbridgeEndpoint extends Endpoint {
749
1097
  this.hardwareVersion = hardwareVersion;
750
1098
  this.hardwareVersionString = hardwareVersionString;
751
1099
  return ClusterServer(BridgedDeviceBasicInformationCluster, {
752
- vendorId: vendorId !== undefined ? VendorId(vendorId) : undefined,
1100
+ vendorId: vendorId !== undefined ? VendorId(vendorId) : undefined, // 4874
753
1101
  vendorName: vendorName.slice(0, 32),
754
1102
  productName: productName.slice(0, 32),
1103
+ productUrl: 'https://www.npmjs.com/package/matterbridge',
755
1104
  productLabel: deviceName.slice(0, 64),
756
1105
  nodeLabel: deviceName.slice(0, 32),
757
1106
  serialNumber: serialNumber.slice(0, 32),
@@ -768,12 +1117,36 @@ export class MatterbridgeEndpoint extends Endpoint {
768
1117
  reachableChanged: true,
769
1118
  });
770
1119
  }
1120
+ /**
1121
+ * Creates a default BridgedDeviceBasicInformationClusterServer.
1122
+ *
1123
+ * @param deviceName - The name of the device.
1124
+ * @param serialNumber - The serial number of the device.
1125
+ * @param vendorId - The vendor ID of the device.
1126
+ * @param vendorName - The name of the vendor.
1127
+ * @param productName - The name of the product.
1128
+ * @param softwareVersion - The software version of the device. Default is 1.
1129
+ * @param softwareVersionString - The software version string of the device. Default is 'v.1.0.0'.
1130
+ * @param hardwareVersion - The hardware version of the device. Default is 1.
1131
+ * @param hardwareVersionString - The hardware version string of the device. Default is 'v.1.0.0'.
1132
+ */
771
1133
  createDefaultBridgedDeviceBasicInformationClusterServer(deviceName, serialNumber, vendorId, vendorName, productName, softwareVersion = 1, softwareVersionString = '1.0.0', hardwareVersion = 1, hardwareVersionString = '1.0.0') {
772
1134
  this.addClusterServer(this.getDefaultBridgedDeviceBasicInformationClusterServer(deviceName, serialNumber, vendorId, vendorName, productName, softwareVersion, softwareVersionString, hardwareVersion, hardwareVersionString));
773
1135
  }
1136
+ /**
1137
+ * Get a default Power Topology Cluster Server. Only needed for an electricalSensor device type.
1138
+ *
1139
+ * @returns {ClusterServer} - The configured Power Topology Cluster Server.
1140
+ */
774
1141
  getDefaultPowerTopologyClusterServer() {
775
1142
  return ClusterServer(PowerTopologyCluster.with(PowerTopology.Feature.TreeTopology), {}, {}, {});
776
1143
  }
1144
+ /**
1145
+ * Get a default Electrical Energy Measurement Cluster Server.
1146
+ *
1147
+ * @param {number} energy - The total consumption value in mW/h.
1148
+ * @returns {ClusterServer} - The configured Electrical Energy Measurement Cluster Server.
1149
+ */
777
1150
  getDefaultElectricalEnergyMeasurementClusterServer(energy = null) {
778
1151
  return ClusterServer(ElectricalEnergyMeasurementCluster.with(ElectricalEnergyMeasurement.Feature.ImportedEnergy, ElectricalEnergyMeasurement.Feature.ExportedEnergy, ElectricalEnergyMeasurement.Feature.CumulativeEnergy), {
779
1152
  accuracy: {
@@ -790,6 +1163,15 @@ export class MatterbridgeEndpoint extends Endpoint {
790
1163
  cumulativeEnergyMeasured: true,
791
1164
  });
792
1165
  }
1166
+ /**
1167
+ * Get a default Electrical Power Measurement Cluster Server.
1168
+ *
1169
+ * @param {number} voltage - The voltage value in millivolts.
1170
+ * @param {number} current - The current value in milliamperes.
1171
+ * @param {number} power - The power value in milliwatts.
1172
+ * @param {number} frequency - The frequency value in millihertz.
1173
+ * @returns {ClusterServer} - The configured Electrical Power Measurement Cluster Server.
1174
+ */
793
1175
  getDefaultElectricalPowerMeasurementClusterServer(voltage = null, current = null, power = null, frequency = null) {
794
1176
  return ClusterServer(ElectricalPowerMeasurementCluster.with(ElectricalPowerMeasurement.Feature.AlternatingCurrent), {
795
1177
  powerMode: ElectricalPowerMeasurement.PowerMode.Ac,
@@ -830,6 +1212,16 @@ export class MatterbridgeEndpoint extends Endpoint {
830
1212
  frequency: frequency,
831
1213
  }, {}, {});
832
1214
  }
1215
+ /**
1216
+ * Get a default OnOff cluster server.
1217
+ *
1218
+ * @param {boolean} [onOff=false] - The initial state of the OnOff cluster.
1219
+ * @param {boolean} [globalSceneControl=false] - The global scene control state.
1220
+ * @param {number} [onTime=0] - The on time value.
1221
+ * @param {number} [offWaitTime=0] - The off wait time value.
1222
+ * @param {OnOff.StartUpOnOff | null} [startUpOnOff=null] - The start-up OnOff state. Null means previous state.
1223
+ * @returns {ClusterServer} - The configured OnOff cluster server.
1224
+ */
833
1225
  getDefaultOnOffClusterServer(onOff = false, globalSceneControl = false, onTime = 0, offWaitTime = 0, startUpOnOff = null) {
834
1226
  return ClusterServer(OnOffCluster.with(OnOff.Feature.Lighting), {
835
1227
  onOff,
@@ -839,64 +1231,109 @@ export class MatterbridgeEndpoint extends Endpoint {
839
1231
  startUpOnOff,
840
1232
  }, {
841
1233
  on: async (data) => {
1234
+ // Never called in edge
842
1235
  },
843
1236
  off: async (data) => {
1237
+ // Never called in edge
844
1238
  },
845
1239
  toggle: async (data) => {
1240
+ // Never called in edge
846
1241
  },
847
1242
  offWithEffect: async () => {
1243
+ // Never called in edge
848
1244
  },
849
1245
  onWithRecallGlobalScene: async () => {
1246
+ // Never called in edge
850
1247
  },
851
1248
  onWithTimedOff: async () => {
1249
+ // Never called in edge
852
1250
  },
853
1251
  }, {});
854
1252
  }
1253
+ /**
1254
+ * Creates a default OnOff cluster server.
1255
+ *
1256
+ * @param {boolean} [onOff=false] - The initial state of the OnOff cluster.
1257
+ * @param {boolean} [globalSceneControl=false] - The global scene control state.
1258
+ * @param {number} [onTime=0] - The on time value.
1259
+ * @param {number} [offWaitTime=0] - The off wait time value.
1260
+ * @param {OnOff.StartUpOnOff | null} [startUpOnOff=null] - The start-up OnOff state. Null means previous state.
1261
+ * @returns {void}
1262
+ */
855
1263
  createDefaultOnOffClusterServer(onOff = false, globalSceneControl = false, onTime = 0, offWaitTime = 0, startUpOnOff = null) {
856
1264
  this.addClusterServer(this.getDefaultOnOffClusterServer(onOff, globalSceneControl, onTime, offWaitTime, startUpOnOff));
857
1265
  }
858
- getDefaultLevelControlClusterServer(currentLevel = 254, minLevel = 0, maxLevel = 254, onLevel = 254) {
859
- return ClusterServer(LevelControlCluster.with(LevelControl.Feature.OnOff), {
1266
+ /**
1267
+ * Get a default level control cluster server.
1268
+ *
1269
+ * @param currentLevel - The current level (default: 254).
1270
+ * @param minLevel - The minimum level (default: 1).
1271
+ * @param maxLevel - The maximum level (default: 254).
1272
+ * @param onLevel - The on level (default: null).
1273
+ * @param startUpCurrentLevel - The startUp on level (default: null).
1274
+ */
1275
+ getDefaultLevelControlClusterServer(currentLevel = 254, minLevel = 1, maxLevel = 254, onLevel = null, startUpCurrentLevel = null) {
1276
+ return ClusterServer(LevelControlCluster.with(LevelControl.Feature.OnOff, LevelControl.Feature.Lighting), {
860
1277
  currentLevel,
861
1278
  minLevel,
862
1279
  maxLevel,
863
1280
  onLevel,
1281
+ remainingTime: 0,
1282
+ startUpCurrentLevel,
864
1283
  options: {
865
1284
  executeIfOff: false,
866
1285
  coupleColorTempToLevel: false,
867
1286
  },
868
1287
  }, {
869
1288
  moveToLevel: async (data) => {
870
- this.log.debug('Matter command: moveToLevel request:', data.request, 'attributes.currentLevel:', data.attributes.currentLevel.getLocal());
871
- await this.commandHandler.executeHandler('moveToLevel', data);
1289
+ // Never called in edge
872
1290
  },
873
1291
  move: async () => {
874
- this.log.error('Matter command: move not implemented');
1292
+ // Never called in edge
875
1293
  },
876
1294
  step: async () => {
877
- this.log.error('Matter command: step not implemented');
1295
+ // Never called in edge
878
1296
  },
879
1297
  stop: async () => {
880
- this.log.error('Matter command: stop not implemented');
1298
+ // Never called in edge
881
1299
  },
882
1300
  moveToLevelWithOnOff: async (data) => {
883
- this.log.debug('Matter command: moveToLevelWithOnOff request:', data.request, 'attributes.currentLevel:', data.attributes.currentLevel.getLocal());
884
- await this.commandHandler.executeHandler('moveToLevelWithOnOff', data);
1301
+ // Never called in edge
885
1302
  },
886
1303
  moveWithOnOff: async () => {
887
- this.log.error('Matter command: moveWithOnOff not implemented');
1304
+ // Never called in edge
888
1305
  },
889
1306
  stepWithOnOff: async () => {
890
- this.log.error('Matter command: stepWithOnOff not implemented');
1307
+ // Never called in edge
891
1308
  },
892
1309
  stopWithOnOff: async () => {
893
- this.log.error('Matter command: stopWithOnOff not implemented');
1310
+ // Never called in edge
894
1311
  },
895
1312
  });
896
1313
  }
897
- createDefaultLevelControlClusterServer(currentLevel = 254, minLevel = 0, maxLevel = 254, onLevel = 254) {
898
- this.addClusterServer(this.getDefaultLevelControlClusterServer(currentLevel, minLevel, maxLevel, onLevel));
899
- }
1314
+ /**
1315
+ * Creates a default level control cluster server.
1316
+ *
1317
+ * @param currentLevel - The current level (default: 254).
1318
+ * @param minLevel - The minimum level (default: 1).
1319
+ * @param maxLevel - The maximum level (default: 254).
1320
+ * @param onLevel - The on level (default: null).
1321
+ * @param startUpCurrentLevel - The startUp on level (default: null).
1322
+ */
1323
+ createDefaultLevelControlClusterServer(currentLevel = 254, minLevel = 1, maxLevel = 254, onLevel = null, startUpCurrentLevel = null) {
1324
+ this.addClusterServer(this.getDefaultLevelControlClusterServer(currentLevel, minLevel, maxLevel, onLevel, startUpCurrentLevel));
1325
+ }
1326
+ /**
1327
+ * Get a default color control cluster server with Xy, HueSaturation and ColorTemperature.
1328
+ *
1329
+ * @param currentX - The current X value.
1330
+ * @param currentY - The current Y value.
1331
+ * @param currentHue - The current hue value.
1332
+ * @param currentSaturation - The current saturation value.
1333
+ * @param colorTemperatureMireds - The color temperature in mireds.
1334
+ * @param colorTempPhysicalMinMireds - The physical minimum color temperature in mireds.
1335
+ * @param colorTempPhysicalMaxMireds - The physical maximum color temperature in mireds.
1336
+ */
900
1337
  getDefaultColorControlClusterServer(currentX = 0, currentY = 0, currentHue = 0, currentSaturation = 0, colorTemperatureMireds = 500, colorTempPhysicalMinMireds = 147, colorTempPhysicalMaxMireds = 500) {
901
1338
  return ClusterServer(ColorControlCluster.with(ColorControl.Feature.Xy, ColorControl.Feature.HueSaturation, ColorControl.Feature.ColorTemperature), {
902
1339
  colorMode: ColorControl.ColorMode.CurrentHueAndCurrentSaturation,
@@ -914,118 +1351,210 @@ export class MatterbridgeEndpoint extends Endpoint {
914
1351
  colorTempPhysicalMinMireds,
915
1352
  colorTempPhysicalMaxMireds,
916
1353
  coupleColorTempToLevelMinMireds: colorTempPhysicalMinMireds,
1354
+ remainingTime: 0,
917
1355
  startUpColorTemperatureMireds: null,
918
1356
  }, {
919
1357
  moveToColor: async (data) => {
920
- this.log.debug('Matter command: moveToColor request:', data.request, 'attributes.currentX:', data.attributes.currentX.getLocal(), 'attributes.currentY:', data.attributes.currentY.getLocal());
921
- this.commandHandler.executeHandler('moveToColor', data);
1358
+ // Never called in edge
922
1359
  },
923
1360
  moveColor: async () => {
924
- this.log.error('Matter command: moveColor not implemented');
1361
+ // Never called in edge
925
1362
  },
926
1363
  stepColor: async () => {
927
- this.log.error('Matter command: stepColor not implemented');
1364
+ // Never called in edge
928
1365
  },
929
1366
  moveToHue: async (data) => {
930
- this.log.debug('Matter command: moveToHue request:', data.request, 'attributes.currentHue:', data.attributes.currentHue.getLocal());
931
- this.commandHandler.executeHandler('moveToHue', data);
1367
+ // Never called in edge
932
1368
  },
933
1369
  moveHue: async () => {
934
- this.log.error('Matter command: moveHue not implemented');
1370
+ // Never called in edge
935
1371
  },
936
1372
  stepHue: async () => {
937
- this.log.error('Matter command: stepHue not implemented');
1373
+ // Never called in edge
938
1374
  },
939
1375
  moveToSaturation: async (data) => {
940
- this.log.debug('Matter command: moveToSaturation request:', data.request, 'attributes.currentSaturation:', data.attributes.currentSaturation.getLocal());
941
- this.commandHandler.executeHandler('moveToSaturation', data);
1376
+ // Never called in edge
942
1377
  },
943
1378
  moveSaturation: async () => {
944
- this.log.error('Matter command: moveSaturation not implemented');
1379
+ // Never called in edge
945
1380
  },
946
1381
  stepSaturation: async () => {
947
- this.log.error('Matter command: stepSaturation not implemented');
1382
+ // Never called in edge
948
1383
  },
949
1384
  moveToHueAndSaturation: async (data) => {
950
- this.log.debug('Matter command: moveToHueAndSaturation request:', data.request, 'attributes.currentHue:', data.attributes.currentHue.getLocal(), 'attributes.currentSaturation:', data.attributes.currentSaturation.getLocal());
951
- this.commandHandler.executeHandler('moveToHueAndSaturation', data);
1385
+ // Never called in edge
952
1386
  },
953
1387
  stopMoveStep: async () => {
954
- this.log.error('Matter command: stopMoveStep not implemented');
1388
+ // Never called in edge
955
1389
  },
956
1390
  moveToColorTemperature: async (data) => {
957
- this.log.debug('Matter command: moveToColorTemperature request:', data.request, 'attributes.colorTemperatureMireds:', data.attributes.colorTemperatureMireds.getLocal());
958
- this.commandHandler.executeHandler('moveToColorTemperature', data);
1391
+ // Never called in edge
959
1392
  },
960
1393
  moveColorTemperature: async () => {
961
- this.log.error('Matter command: moveColorTemperature not implemented');
1394
+ // Never called in edge
962
1395
  },
963
1396
  stepColorTemperature: async () => {
964
- this.log.error('Matter command: stepColorTemperature not implemented');
1397
+ // Never called in edge
965
1398
  },
966
1399
  }, {});
967
1400
  }
1401
+ /**
1402
+ * Creates a default color control cluster server with Xy, HueSaturation and ColorTemperature.
1403
+ *
1404
+ * @param currentX - The current X value.
1405
+ * @param currentY - The current Y value.
1406
+ * @param currentHue - The current hue value.
1407
+ * @param currentSaturation - The current saturation value.
1408
+ * @param colorTemperatureMireds - The color temperature in mireds.
1409
+ * @param colorTempPhysicalMinMireds - The physical minimum color temperature in mireds.
1410
+ * @param colorTempPhysicalMaxMireds - The physical maximum color temperature in mireds.
1411
+ */
968
1412
  createDefaultColorControlClusterServer(currentX = 0, currentY = 0, currentHue = 0, currentSaturation = 0, colorTemperatureMireds = 500, colorTempPhysicalMinMireds = 147, colorTempPhysicalMaxMireds = 500) {
969
1413
  this.addClusterServer(this.getDefaultColorControlClusterServer(currentX, currentY, currentHue, currentSaturation, colorTemperatureMireds, colorTempPhysicalMinMireds, colorTempPhysicalMaxMireds));
970
1414
  }
971
- getXyColorControlClusterServer(currentX = 0, currentY = 0) {
972
- return ClusterServer(ColorControlCluster.with(ColorControl.Feature.Xy), {
1415
+ /**
1416
+ * Get a Xy color control cluster server with Xy and ColorTemperature.
1417
+ *
1418
+ * @param currentX - The current X value.
1419
+ * @param currentY - The current Y value.
1420
+ * @param colorTemperatureMireds - The color temperature in mireds.
1421
+ * @param colorTempPhysicalMinMireds - The physical minimum color temperature in mireds.
1422
+ * @param colorTempPhysicalMaxMireds - The physical maximum color temperature in mireds.
1423
+ */
1424
+ getXyColorControlClusterServer(currentX = 0, currentY = 0, colorTemperatureMireds = 500, colorTempPhysicalMinMireds = 147, colorTempPhysicalMaxMireds = 500) {
1425
+ return ClusterServer(ColorControlCluster.with(ColorControl.Feature.Xy, ColorControl.Feature.ColorTemperature), {
973
1426
  colorMode: ColorControl.ColorMode.CurrentXAndCurrentY,
974
1427
  enhancedColorMode: ColorControl.EnhancedColorMode.CurrentXAndCurrentY,
975
- colorCapabilities: { xy: true, hueSaturation: false, colorLoop: false, enhancedHue: false, colorTemperature: false },
1428
+ colorCapabilities: { xy: true, hueSaturation: false, colorLoop: false, enhancedHue: false, colorTemperature: true },
976
1429
  options: {
977
1430
  executeIfOff: false,
978
1431
  },
979
1432
  numberOfPrimaries: null,
980
1433
  currentX,
981
1434
  currentY,
1435
+ colorTemperatureMireds,
1436
+ colorTempPhysicalMinMireds,
1437
+ colorTempPhysicalMaxMireds,
1438
+ coupleColorTempToLevelMinMireds: colorTempPhysicalMinMireds,
1439
+ startUpColorTemperatureMireds: null,
1440
+ remainingTime: 0,
982
1441
  }, {
983
1442
  moveToColor: async () => {
1443
+ // Never called in edge
984
1444
  },
985
1445
  moveColor: async () => {
1446
+ // Never called in edge
986
1447
  },
987
1448
  stepColor: async () => {
1449
+ // Never called in edge
988
1450
  },
989
1451
  stopMoveStep: async () => {
1452
+ // Never called in edge
1453
+ },
1454
+ moveToColorTemperature: async () => {
1455
+ // Never called in edge
1456
+ },
1457
+ moveColorTemperature: async () => {
1458
+ // Never called in edge
1459
+ },
1460
+ stepColorTemperature: async () => {
1461
+ // Never called in edge
990
1462
  },
991
1463
  }, {});
992
1464
  }
993
- createXyColorControlClusterServer(currentX = 0, currentY = 0) {
994
- this.addClusterServer(this.getXyColorControlClusterServer(currentX, currentY));
995
- }
996
- getHsColorControlClusterServer(currentHue = 0, currentSaturation = 0) {
997
- return ClusterServer(ColorControlCluster.with(ColorControl.Feature.HueSaturation), {
1465
+ /**
1466
+ * Creates a Xy color control cluster server with Xy and ColorTemperature.
1467
+ *
1468
+ * @param currentX - The current X value.
1469
+ * @param currentY - The current Y value.
1470
+ * @param colorTemperatureMireds - The color temperature in mireds.
1471
+ * @param colorTempPhysicalMinMireds - The physical minimum color temperature in mireds.
1472
+ * @param colorTempPhysicalMaxMireds - The physical maximum color temperature in mireds.
1473
+ */
1474
+ createXyColorControlClusterServer(currentX = 0, currentY = 0, colorTemperatureMireds = 500, colorTempPhysicalMinMireds = 147, colorTempPhysicalMaxMireds = 500) {
1475
+ this.addClusterServer(this.getXyColorControlClusterServer(currentX, currentY, colorTemperatureMireds, colorTempPhysicalMinMireds, colorTempPhysicalMaxMireds));
1476
+ }
1477
+ /**
1478
+ * Get a default hue and saturation control cluster server with HueSaturation and ColorTemperature.
1479
+ *
1480
+ * @param currentHue - The current hue value.
1481
+ * @param currentSaturation - The current saturation value.
1482
+ * @param colorTemperatureMireds - The color temperature in mireds.
1483
+ * @param colorTempPhysicalMinMireds - The physical minimum color temperature in mireds.
1484
+ * @param colorTempPhysicalMaxMireds - The physical maximum color temperature in mireds.
1485
+ */
1486
+ getHsColorControlClusterServer(currentHue = 0, currentSaturation = 0, colorTemperatureMireds = 500, colorTempPhysicalMinMireds = 147, colorTempPhysicalMaxMireds = 500) {
1487
+ return ClusterServer(ColorControlCluster.with(ColorControl.Feature.HueSaturation, ColorControl.Feature.ColorTemperature), {
998
1488
  colorMode: ColorControl.ColorMode.CurrentHueAndCurrentSaturation,
999
1489
  enhancedColorMode: ColorControl.EnhancedColorMode.CurrentHueAndCurrentSaturation,
1000
- colorCapabilities: { xy: false, hueSaturation: true, colorLoop: false, enhancedHue: false, colorTemperature: false },
1490
+ colorCapabilities: { xy: false, hueSaturation: true, colorLoop: false, enhancedHue: false, colorTemperature: true },
1001
1491
  options: {
1002
1492
  executeIfOff: false,
1003
1493
  },
1004
1494
  numberOfPrimaries: null,
1005
1495
  currentHue,
1006
1496
  currentSaturation,
1497
+ colorTemperatureMireds,
1498
+ colorTempPhysicalMinMireds,
1499
+ colorTempPhysicalMaxMireds,
1500
+ coupleColorTempToLevelMinMireds: colorTempPhysicalMinMireds,
1501
+ startUpColorTemperatureMireds: null,
1502
+ remainingTime: 0,
1007
1503
  }, {
1008
- moveToHue: async ({ request, attributes, endpoint }) => {
1504
+ moveToHue: async () => {
1505
+ // Never called in edge
1009
1506
  },
1010
1507
  moveHue: async () => {
1508
+ // Never called in edge
1011
1509
  },
1012
1510
  stepHue: async () => {
1511
+ // Never called in edge
1013
1512
  },
1014
- moveToSaturation: async ({ request, attributes, endpoint }) => {
1513
+ moveToSaturation: async () => {
1514
+ // Never called in edge
1015
1515
  },
1016
1516
  moveSaturation: async () => {
1517
+ // Never called in edge
1017
1518
  },
1018
1519
  stepSaturation: async () => {
1520
+ // Never called in edge
1019
1521
  },
1020
- moveToHueAndSaturation: async ({ request, attributes, endpoint }) => {
1522
+ moveToHueAndSaturation: async () => {
1523
+ // Never called in edge
1021
1524
  },
1022
1525
  stopMoveStep: async () => {
1526
+ // Never called in edge
1527
+ },
1528
+ moveToColorTemperature: async () => {
1529
+ // Never called in edge
1530
+ },
1531
+ moveColorTemperature: async () => {
1532
+ // Never called in edge
1533
+ },
1534
+ stepColorTemperature: async () => {
1535
+ // Never called in edge
1023
1536
  },
1024
1537
  }, {});
1025
1538
  }
1026
- createHsColorControlClusterServer(currentHue = 0, currentSaturation = 0) {
1027
- this.addClusterServer(this.getHsColorControlClusterServer(currentHue, currentSaturation));
1028
- }
1539
+ /**
1540
+ * Creates a hue and saturation color control cluster server with HueSaturation and ColorTemperature.
1541
+ *
1542
+ * @param currentHue - The current hue value.
1543
+ * @param currentSaturation - The current saturation value.
1544
+ * @param colorTemperatureMireds - The color temperature in mireds.
1545
+ * @param colorTempPhysicalMinMireds - The physical minimum color temperature in mireds.
1546
+ * @param colorTempPhysicalMaxMireds - The physical maximum color temperature in mireds.
1547
+ */
1548
+ createHsColorControlClusterServer(currentHue = 0, currentSaturation = 0, colorTemperatureMireds = 500, colorTempPhysicalMinMireds = 147, colorTempPhysicalMaxMireds = 500) {
1549
+ this.addClusterServer(this.getHsColorControlClusterServer(currentHue, currentSaturation, colorTemperatureMireds, colorTempPhysicalMinMireds, colorTempPhysicalMaxMireds));
1550
+ }
1551
+ /**
1552
+ * Get a color temperature color control cluster server.
1553
+ *
1554
+ * @param colorTemperatureMireds - The color temperature in mireds.
1555
+ * @param colorTempPhysicalMinMireds - The physical minimum color temperature in mireds.
1556
+ * @param colorTempPhysicalMaxMireds - The physical maximum color temperature in mireds.
1557
+ */
1029
1558
  getCtColorControlClusterServer(colorTemperatureMireds = 500, colorTempPhysicalMinMireds = 147, colorTempPhysicalMaxMireds = 500) {
1030
1559
  return ClusterServer(ColorControlCluster.with(ColorControl.Feature.ColorTemperature), {
1031
1560
  colorMode: ColorControl.ColorMode.ColorTemperatureMireds,
@@ -1039,22 +1568,48 @@ export class MatterbridgeEndpoint extends Endpoint {
1039
1568
  colorTempPhysicalMinMireds,
1040
1569
  colorTempPhysicalMaxMireds,
1041
1570
  coupleColorTempToLevelMinMireds: colorTempPhysicalMinMireds,
1571
+ remainingTime: 0,
1042
1572
  startUpColorTemperatureMireds: null,
1043
1573
  }, {
1044
1574
  stopMoveStep: async () => {
1575
+ // Never called in edge
1045
1576
  },
1046
- moveToColorTemperature: async ({ request, attributes, endpoint }) => {
1577
+ moveToColorTemperature: async () => {
1578
+ // Never called in edge
1047
1579
  },
1048
1580
  moveColorTemperature: async () => {
1581
+ // Never called in edge
1049
1582
  },
1050
1583
  stepColorTemperature: async () => {
1584
+ // Never called in edge
1051
1585
  },
1052
1586
  }, {});
1053
1587
  }
1588
+ /**
1589
+ * Creates a color temperature color control cluster server.
1590
+ *
1591
+ * @param colorTemperatureMireds - The color temperature in mireds.
1592
+ * @param colorTempPhysicalMinMireds - The physical minimum color temperature in mireds.
1593
+ * @param colorTempPhysicalMaxMireds - The physical maximum color temperature in mireds.
1594
+ */
1054
1595
  createCtColorControlClusterServer(colorTemperatureMireds = 500, colorTempPhysicalMinMireds = 147, colorTempPhysicalMaxMireds = 500) {
1055
1596
  this.addClusterServer(this.getCtColorControlClusterServer(colorTemperatureMireds, colorTempPhysicalMinMireds, colorTempPhysicalMaxMireds));
1056
1597
  }
1057
1598
  isColorControlConfigured = false;
1599
+ /**
1600
+ * Configures the color control cluster for a device.
1601
+ *
1602
+ * @remark This method must be called only after creating the cluster with getDefaultColorControlClusterServer or createDefaultColorControlClusterServer
1603
+ * and before starting the matter node.
1604
+ *
1605
+ * @deprecated Use configureColorControlMode instead.
1606
+ *
1607
+ * @param {boolean} hueSaturation - A boolean indicating whether the device supports hue and saturation control.
1608
+ * @param {boolean} xy - A boolean indicating whether the device supports XY control.
1609
+ * @param {boolean} colorTemperature - A boolean indicating whether the device supports color temperature control.
1610
+ * @param {ColorControl.ColorMode} colorMode - An optional parameter specifying the color mode of the device.
1611
+ * @param {Endpoint} endpoint - An optional parameter specifying the endpoint to configure. If not provided, the device endpoint will be used.
1612
+ */
1058
1613
  async configureColorControlCluster(hueSaturation, xy, colorTemperature, colorMode, endpoint) {
1059
1614
  if (!endpoint)
1060
1615
  endpoint = this;
@@ -1077,6 +1632,12 @@ export class MatterbridgeEndpoint extends Endpoint {
1077
1632
  }
1078
1633
  this.isColorControlConfigured = true;
1079
1634
  }
1635
+ /**
1636
+ * Configures the color control mode for the device.
1637
+ *
1638
+ * @param {ColorControl.ColorMode} colorMode - The color mode to set.
1639
+ * @param {Endpoint} endpoint - The optional endpoint to configure. If not provided, the method will configure the current endpoint.
1640
+ */
1080
1641
  async configureColorControlMode(colorMode, endpoint) {
1081
1642
  if (!endpoint)
1082
1643
  endpoint = this;
@@ -1085,6 +1646,11 @@ export class MatterbridgeEndpoint extends Endpoint {
1085
1646
  await endpoint.setAttribute(ColorControlCluster.id, 'enhancedColorMode', colorMode, this.log, endpoint);
1086
1647
  }
1087
1648
  }
1649
+ /**
1650
+ * Get a default window covering cluster server.
1651
+ *
1652
+ * @param positionPercent100ths - The position percentage in 100ths (0-10000). Defaults to 0. Matter uses 10000 = fully closed 0 = fully opened.
1653
+ */
1088
1654
  getDefaultWindowCoveringClusterServer(positionPercent100ths) {
1089
1655
  return ClusterServer(WindowCoveringCluster.with(WindowCovering.Feature.Lift, WindowCovering.Feature.PositionAwareLift), {
1090
1656
  type: WindowCovering.WindowCoveringType.Rollershade,
@@ -1100,35 +1666,39 @@ export class MatterbridgeEndpoint extends Endpoint {
1100
1666
  operationalStatus: { global: WindowCovering.MovementStatus.Stopped, lift: WindowCovering.MovementStatus.Stopped, tilt: WindowCovering.MovementStatus.Stopped },
1101
1667
  endProductType: WindowCovering.EndProductType.RollerShade,
1102
1668
  mode: { motorDirectionReversed: false, calibrationMode: false, maintenanceMode: false, ledFeedback: false },
1103
- targetPositionLiftPercent100ths: positionPercent100ths ?? 0,
1104
- currentPositionLiftPercent100ths: positionPercent100ths ?? 0,
1669
+ targetPositionLiftPercent100ths: positionPercent100ths ?? 0, // 0 Fully open 10000 fully closed
1670
+ currentPositionLiftPercent100ths: positionPercent100ths ?? 0, // 0 Fully open 10000 fully closed
1105
1671
  }, {
1106
1672
  upOrOpen: async (data) => {
1107
- this.log.debug('Matter command: upOrOpen');
1108
- await this.commandHandler.executeHandler('upOrOpen', data);
1673
+ // Never called in edge
1109
1674
  },
1110
1675
  downOrClose: async (data) => {
1111
- this.log.debug('Matter command: downOrClose');
1112
- await this.commandHandler.executeHandler('downOrClose', data);
1676
+ // Never called in edge
1113
1677
  },
1114
1678
  stopMotion: async (data) => {
1115
- this.log.debug('Matter command: stopMotion');
1116
- await this.commandHandler.executeHandler('stopMotion', data);
1679
+ // Never called in edge
1117
1680
  },
1118
1681
  goToLiftPercentage: async (data) => {
1119
- this.log.debug(`Matter command: goToLiftPercentage: ${data.request.liftPercent100thsValue} current: ${data.attributes.currentPositionLiftPercent100ths?.getLocal()} ` +
1120
- `target: ${data.attributes.targetPositionLiftPercent100ths?.getLocal()} status: ${data.attributes.operationalStatus.getLocal().lift}`);
1121
- await this.commandHandler.executeHandler('goToLiftPercentage', data);
1682
+ // Never called in edge
1122
1683
  },
1123
1684
  }, {});
1124
1685
  }
1686
+ /**
1687
+ * Creates a default window covering cluster server.
1688
+ *
1689
+ * @param positionPercent100ths - The position percentage in 100ths (0-10000). Defaults to 0. Matter uses 10000 = fully closed 0 = fully opened.
1690
+ */
1125
1691
  createDefaultWindowCoveringClusterServer(positionPercent100ths) {
1126
1692
  this.addClusterServer(this.getDefaultWindowCoveringClusterServer(positionPercent100ths));
1127
1693
  }
1694
+ /**
1695
+ * Sets the window covering target position as the current position and stops the movement.
1696
+ * @param {Endpoint} endpoint - The endpoint on which to set the window covering (default the device endpoint).
1697
+ */
1128
1698
  async setWindowCoveringTargetAsCurrentAndStopped(endpoint) {
1129
1699
  if (!endpoint)
1130
1700
  endpoint = this;
1131
- const position = endpoint.getAttribute(WindowCoveringCluster.id, 'currentPositionLiftPercent100ths', this.log, endpoint);
1701
+ const position = endpoint.getAttribute(WindowCoveringCluster.id, 'currentPositionLiftPercent100ths', this.log, endpoint); // windowCoveringCluster.getCurrentPositionLiftPercent100thsAttribute();
1132
1702
  if (position !== null) {
1133
1703
  await endpoint.setAttribute(WindowCoveringCluster.id, 'targetPositionLiftPercent100ths', position, this.log, endpoint);
1134
1704
  await endpoint.setAttribute(WindowCoveringCluster.id, 'operationalStatus', {
@@ -1139,6 +1709,13 @@ export class MatterbridgeEndpoint extends Endpoint {
1139
1709
  }
1140
1710
  this.log.debug(`Set WindowCovering currentPositionLiftPercent100ths and targetPositionLiftPercent100ths to ${position} and operationalStatus to Stopped.`);
1141
1711
  }
1712
+ /**
1713
+ * Sets the current and target status of a window covering.
1714
+ * @param {number} current - The current position of the window covering.
1715
+ * @param {number} target - The target position of the window covering.
1716
+ * @param {WindowCovering.MovementStatus} status - The movement status of the window covering.
1717
+ * @param {Endpoint} endpoint - The endpoint on which to set the window covering (default the device endpoint).
1718
+ */
1142
1719
  async setWindowCoveringCurrentTargetStatus(current, target, status, endpoint) {
1143
1720
  if (!endpoint)
1144
1721
  endpoint = this;
@@ -1151,6 +1728,11 @@ export class MatterbridgeEndpoint extends Endpoint {
1151
1728
  }, this.log, endpoint);
1152
1729
  this.log.debug(`Set WindowCovering currentPositionLiftPercent100ths: ${current}, targetPositionLiftPercent100ths: ${target} and operationalStatus: ${status}.`);
1153
1730
  }
1731
+ /**
1732
+ * Sets the status of the window covering.
1733
+ * @param {WindowCovering.MovementStatus} status - The movement status to set.
1734
+ * @param {Endpoint} endpoint - The endpoint on which to set the window covering (default the device endpoint).
1735
+ */
1154
1736
  async setWindowCoveringStatus(status, endpoint) {
1155
1737
  if (!endpoint)
1156
1738
  endpoint = this;
@@ -1161,6 +1743,12 @@ export class MatterbridgeEndpoint extends Endpoint {
1161
1743
  }, this.log, endpoint);
1162
1744
  this.log.debug(`Set WindowCovering operationalStatus: ${status}`);
1163
1745
  }
1746
+ /**
1747
+ * Retrieves the status of the window covering.
1748
+ * @param {Endpoint} endpoint - The endpoint on which to get the window covering (default the device endpoint).
1749
+ *
1750
+ * @returns The global operational status of the window covering.
1751
+ */
1164
1752
  getWindowCoveringStatus(endpoint) {
1165
1753
  if (!endpoint)
1166
1754
  endpoint = this;
@@ -1168,6 +1756,12 @@ export class MatterbridgeEndpoint extends Endpoint {
1168
1756
  this.log.debug(`Get WindowCovering operationalStatus: ${status.global}`);
1169
1757
  return status.global;
1170
1758
  }
1759
+ /**
1760
+ * Sets the target and current position of the window covering.
1761
+ *
1762
+ * @param position - The position to set, specified as a number.
1763
+ * @param {Endpoint} endpoint - The endpoint on which to set the window covering (default the device endpoint).
1764
+ */
1171
1765
  async setWindowCoveringTargetAndCurrentPosition(position, endpoint) {
1172
1766
  if (!endpoint)
1173
1767
  endpoint = this;
@@ -1175,6 +1769,13 @@ export class MatterbridgeEndpoint extends Endpoint {
1175
1769
  await endpoint.setAttribute(WindowCoveringCluster.id, 'targetPositionLiftPercent100ths', position, this.log, endpoint);
1176
1770
  this.log.debug(`Set WindowCovering currentPositionLiftPercent100ths: ${position} and targetPositionLiftPercent100ths: ${position}.`);
1177
1771
  }
1772
+ /**
1773
+ * Get a default door lock cluster server.
1774
+ *
1775
+ * @remarks
1776
+ * This method adds a cluster server for a door lock cluster with default settings.
1777
+ *
1778
+ */
1178
1779
  getDefaultDoorLockClusterServer(lockState = DoorLock.LockState.Locked, lockType = DoorLock.LockType.DeadBolt) {
1179
1780
  return ClusterServer(DoorLockCluster, {
1180
1781
  operatingMode: DoorLock.OperatingMode.Normal,
@@ -1184,12 +1785,10 @@ export class MatterbridgeEndpoint extends Endpoint {
1184
1785
  supportedOperatingModes: { normal: true, vacation: false, privacy: false, noRemoteLockUnlock: false, passage: false },
1185
1786
  }, {
1186
1787
  lockDoor: async (data) => {
1187
- this.log.debug('Matter command: lockDoor', data.request);
1188
- await this.commandHandler.executeHandler('lockDoor', data);
1788
+ // Never called in edge
1189
1789
  },
1190
1790
  unlockDoor: async (data) => {
1191
- this.log.debug('Matter command: unlockDoor', data.request);
1192
- await this.commandHandler.executeHandler('unlockDoor', data);
1791
+ // Never called in edge
1193
1792
  },
1194
1793
  }, {
1195
1794
  doorLockAlarm: true,
@@ -1197,9 +1796,22 @@ export class MatterbridgeEndpoint extends Endpoint {
1197
1796
  lockOperationError: true,
1198
1797
  });
1199
1798
  }
1799
+ /**
1800
+ * Creates a default door lock cluster server.
1801
+ *
1802
+ * @remarks
1803
+ * This method adds a cluster server for a door lock cluster with default settings.
1804
+ *
1805
+ */
1200
1806
  createDefaultDoorLockClusterServer(lockState = DoorLock.LockState.Locked, lockType = DoorLock.LockType.DeadBolt) {
1201
1807
  this.addClusterServer(this.getDefaultDoorLockClusterServer(lockState, lockType));
1202
1808
  }
1809
+ /**
1810
+ * Get a default momentary switch cluster server.
1811
+ *
1812
+ * @remarks
1813
+ * This method adds a cluster server with default momentary switch features and configurations suitable for (AppleHome) Single Double Long automations.
1814
+ */
1203
1815
  getDefaultSwitchClusterServer() {
1204
1816
  return ClusterServer(SwitchCluster.with(Switch.Feature.MomentarySwitch, Switch.Feature.MomentarySwitchRelease, Switch.Feature.MomentarySwitchLongPress, Switch.Feature.MomentarySwitchMultiPress), {
1205
1817
  numberOfPositions: 2,
@@ -1214,9 +1826,21 @@ export class MatterbridgeEndpoint extends Endpoint {
1214
1826
  multiPressComplete: true,
1215
1827
  });
1216
1828
  }
1829
+ /**
1830
+ * Creates a default momentary switch cluster server.
1831
+ *
1832
+ * @remarks
1833
+ * This method adds a cluster server with default momentary switch features and configurations.
1834
+ */
1217
1835
  createDefaultSwitchClusterServer() {
1218
1836
  this.addClusterServer(this.getDefaultSwitchClusterServer());
1219
1837
  }
1838
+ /**
1839
+ * Get a default latching switch cluster server.
1840
+ *
1841
+ * @remarks
1842
+ * This method adds a cluster server with default latching switch features and configuration.
1843
+ */
1220
1844
  getDefaultLatchingSwitchClusterServer() {
1221
1845
  return ClusterServer(SwitchCluster.with(Switch.Feature.LatchingSwitch), {
1222
1846
  numberOfPositions: 2,
@@ -1225,9 +1849,22 @@ export class MatterbridgeEndpoint extends Endpoint {
1225
1849
  switchLatched: true,
1226
1850
  });
1227
1851
  }
1852
+ /**
1853
+ * Creates a default latching switch cluster server.
1854
+ *
1855
+ * @remarks
1856
+ * This method adds a cluster server with default latching switch features and configuration.
1857
+ */
1228
1858
  createDefaultLatchingSwitchClusterServer() {
1229
1859
  this.addClusterServer(this.getDefaultLatchingSwitchClusterServer());
1230
1860
  }
1861
+ /**
1862
+ * Triggers a switch event on the specified endpoint.
1863
+ *
1864
+ * @param {string} event - The type of event to trigger. Possible values are 'Single', 'Double', 'Long' for momentarySwitch and 'Press', 'Release' for latchingSwitch.
1865
+ * @param {Endpoint} endpoint - The endpoint on which to trigger the event (default the device endpoint).
1866
+ * @returns {void}
1867
+ */
1231
1868
  async triggerSwitchEvent(event, log, endpoint) {
1232
1869
  if (!endpoint)
1233
1870
  endpoint = this;
@@ -1295,6 +1932,15 @@ export class MatterbridgeEndpoint extends Endpoint {
1295
1932
  }
1296
1933
  return true;
1297
1934
  }
1935
+ /**
1936
+ * Retrieves the default mode select cluster server.
1937
+ *
1938
+ * @param description - The description of the cluster server.
1939
+ * @param supportedModes - The supported modes for the cluster server.
1940
+ * @param currentMode - The current mode of the cluster server. Defaults to 0.
1941
+ * @param startUpMode - The startup mode of the cluster server. Defaults to 0.
1942
+ * @returns The default mode select cluster server.
1943
+ */
1298
1944
  getDefaultModeSelectClusterServer(description, supportedModes, currentMode = 0, startUpMode = 0) {
1299
1945
  return ClusterServer(ModeSelectCluster, {
1300
1946
  description: description,
@@ -1304,16 +1950,30 @@ export class MatterbridgeEndpoint extends Endpoint {
1304
1950
  startUpMode: startUpMode,
1305
1951
  }, {
1306
1952
  changeToMode: async (data) => {
1307
- this.log.debug('Matter command: ModeSelectCluster.changeToMode', data.request);
1308
- await this.commandHandler.executeHandler('changeToMode', data);
1953
+ // Never called in edge
1309
1954
  },
1310
1955
  });
1311
1956
  }
1957
+ /**
1958
+ * Creates a default mode select cluster server.
1959
+ *
1960
+ * @param description - The description of the cluster server.
1961
+ * @param supportedModes - The supported modes for the cluster server.
1962
+ * @param currentMode - The current mode of the cluster server. Defaults to 0.
1963
+ * @param startUpMode - The startup mode of the cluster server. Defaults to 0.
1964
+ * @param endpoint - The endpoint to add the cluster server to. Defaults to `this` if not provided.
1965
+ *
1966
+ */
1312
1967
  createDefaultModeSelectClusterServer(description, supportedModes, currentMode = 0, startUpMode = 0, endpoint) {
1313
1968
  if (!endpoint)
1314
1969
  endpoint = this;
1315
1970
  endpoint.addClusterServer(this.getDefaultModeSelectClusterServer(description, supportedModes, currentMode, startUpMode));
1316
1971
  }
1972
+ /**
1973
+ * Get a default occupancy sensing cluster server.
1974
+ *
1975
+ * @param occupied - A boolean indicating whether the occupancy is occupied or not. Default is false.
1976
+ */
1317
1977
  getDefaultOccupancySensingClusterServer(occupied = false) {
1318
1978
  return ClusterServer(OccupancySensingCluster, {
1319
1979
  occupancy: { occupied },
@@ -1322,9 +1982,19 @@ export class MatterbridgeEndpoint extends Endpoint {
1322
1982
  pirOccupiedToUnoccupiedDelay: 30,
1323
1983
  }, {});
1324
1984
  }
1985
+ /**
1986
+ * Creates a default occupancy sensing cluster server.
1987
+ *
1988
+ * @param occupied - A boolean indicating whether the occupancy is occupied or not. Default is false.
1989
+ */
1325
1990
  createDefaultOccupancySensingClusterServer(occupied = false) {
1326
1991
  this.addClusterServer(this.getDefaultOccupancySensingClusterServer(occupied));
1327
1992
  }
1993
+ /**
1994
+ * Get a default Illuminance Measurement Cluster Server.
1995
+ *
1996
+ * @param measuredValue - The measured value of illuminance.
1997
+ */
1328
1998
  getDefaultIlluminanceMeasurementClusterServer(measuredValue = 0) {
1329
1999
  return ClusterServer(IlluminanceMeasurementCluster, {
1330
2000
  measuredValue,
@@ -1333,9 +2003,19 @@ export class MatterbridgeEndpoint extends Endpoint {
1333
2003
  tolerance: 0,
1334
2004
  }, {}, {});
1335
2005
  }
2006
+ /**
2007
+ * Creates a default Illuminance Measurement Cluster Server.
2008
+ *
2009
+ * @param measuredValue - The measured value of illuminance.
2010
+ */
1336
2011
  createDefaultIlluminanceMeasurementClusterServer(measuredValue = 0) {
1337
2012
  this.addClusterServer(this.getDefaultIlluminanceMeasurementClusterServer(measuredValue));
1338
2013
  }
2014
+ /**
2015
+ * Get a default flow measurement cluster server.
2016
+ *
2017
+ * @param measuredValue - The measured value of the flow in 10 x m/h.
2018
+ */
1339
2019
  getDefaultFlowMeasurementClusterServer(measuredValue = 0) {
1340
2020
  return ClusterServer(FlowMeasurementCluster, {
1341
2021
  measuredValue,
@@ -1344,9 +2024,19 @@ export class MatterbridgeEndpoint extends Endpoint {
1344
2024
  tolerance: 0,
1345
2025
  }, {}, {});
1346
2026
  }
2027
+ /**
2028
+ * Creates a default flow measurement cluster server.
2029
+ *
2030
+ * @param measuredValue - The measured value of the flow in 10 x m/h.
2031
+ */
1347
2032
  createDefaultFlowMeasurementClusterServer(measuredValue = 0) {
1348
2033
  this.addClusterServer(this.getDefaultFlowMeasurementClusterServer(measuredValue));
1349
2034
  }
2035
+ /**
2036
+ * Get a default temperature measurement cluster server.
2037
+ *
2038
+ * @param measuredValue - The measured value of the temperature x 100.
2039
+ */
1350
2040
  getDefaultTemperatureMeasurementClusterServer(measuredValue = 0) {
1351
2041
  return ClusterServer(TemperatureMeasurementCluster, {
1352
2042
  measuredValue,
@@ -1355,9 +2045,19 @@ export class MatterbridgeEndpoint extends Endpoint {
1355
2045
  tolerance: 0,
1356
2046
  }, {}, {});
1357
2047
  }
2048
+ /**
2049
+ * Creates a default temperature measurement cluster server.
2050
+ *
2051
+ * @param measuredValue - The measured value of the temperature x 100.
2052
+ */
1358
2053
  createDefaultTemperatureMeasurementClusterServer(measuredValue = 0) {
1359
2054
  this.addClusterServer(this.getDefaultTemperatureMeasurementClusterServer(measuredValue));
1360
2055
  }
2056
+ /**
2057
+ * Get a default RelativeHumidityMeasurementCluster server.
2058
+ *
2059
+ * @param measuredValue - The measured value of the relative humidity x 100.
2060
+ */
1361
2061
  getDefaultRelativeHumidityMeasurementClusterServer(measuredValue = 0) {
1362
2062
  return ClusterServer(RelativeHumidityMeasurementCluster, {
1363
2063
  measuredValue,
@@ -1366,9 +2066,19 @@ export class MatterbridgeEndpoint extends Endpoint {
1366
2066
  tolerance: 0,
1367
2067
  }, {}, {});
1368
2068
  }
2069
+ /**
2070
+ * Creates a default RelativeHumidityMeasurementCluster server.
2071
+ *
2072
+ * @param measuredValue - The measured value of the relative humidity x 100.
2073
+ */
1369
2074
  createDefaultRelativeHumidityMeasurementClusterServer(measuredValue = 0) {
1370
2075
  this.addClusterServer(this.getDefaultRelativeHumidityMeasurementClusterServer(measuredValue));
1371
2076
  }
2077
+ /**
2078
+ * Get a default Pressure Measurement Cluster Server.
2079
+ *
2080
+ * @param measuredValue - The measured value for the pressure.
2081
+ */
1372
2082
  getDefaultPressureMeasurementClusterServer(measuredValue = 1000) {
1373
2083
  return ClusterServer(PressureMeasurementCluster, {
1374
2084
  measuredValue,
@@ -1377,19 +2087,39 @@ export class MatterbridgeEndpoint extends Endpoint {
1377
2087
  tolerance: 0,
1378
2088
  }, {}, {});
1379
2089
  }
2090
+ /**
2091
+ * Creates a default Pressure Measurement Cluster Server.
2092
+ *
2093
+ * @param measuredValue - The measured value for the pressure.
2094
+ */
1380
2095
  createDefaultPressureMeasurementClusterServer(measuredValue = 1000) {
1381
2096
  this.addClusterServer(this.getDefaultPressureMeasurementClusterServer(measuredValue));
1382
2097
  }
2098
+ /**
2099
+ * Get a default boolean state cluster server.
2100
+ *
2101
+ * @param contact - Optional boolean value indicating the contact state. Defaults to `true` if not provided.
2102
+ */
1383
2103
  getDefaultBooleanStateClusterServer(contact) {
1384
2104
  return ClusterServer(BooleanStateCluster, {
1385
- stateValue: contact ?? true,
2105
+ stateValue: contact ?? true, // true=contact false=no_contact
1386
2106
  }, {}, {
1387
2107
  stateChange: true,
1388
2108
  });
1389
2109
  }
2110
+ /**
2111
+ * Creates a default boolean state configuration cluster server.
2112
+ *
2113
+ * @param contact - Optional boolean value indicating the contact state. Defaults to `true` if not provided.
2114
+ */
1390
2115
  createDefaultBooleanStateClusterServer(contact) {
1391
2116
  this.addClusterServer(this.getDefaultBooleanStateClusterServer(contact));
1392
2117
  }
2118
+ /**
2119
+ * Get a default boolean state configuration cluster server.
2120
+ *
2121
+ * @param contact - Optional boolean value indicating the sensor fault state. Defaults to `false` if not provided.
2122
+ */
1393
2123
  getDefaultBooleanStateConfigurationClusterServer(sensorFault = false) {
1394
2124
  return ClusterServer(BooleanStateConfigurationCluster.with(BooleanStateConfiguration.Feature.Visual, BooleanStateConfiguration.Feature.Audible, BooleanStateConfiguration.Feature.SensitivityLevel), {
1395
2125
  currentSensitivityLevel: 0,
@@ -1398,20 +2128,34 @@ export class MatterbridgeEndpoint extends Endpoint {
1398
2128
  alarmsActive: { visual: false, audible: false },
1399
2129
  alarmsEnabled: { visual: false, audible: false },
1400
2130
  alarmsSupported: { visual: true, audible: true },
2131
+ // alarmsSuppressed: { visual: false, audible: false },
1401
2132
  sensorFault: { generalFault: sensorFault },
1402
2133
  }, {
1403
2134
  enableDisableAlarm: async (data) => {
1404
- this.log.debug('Matter command: enableDisableAlarm', data.request);
1405
- await this.commandHandler.executeHandler('enableDisableAlarm', data);
2135
+ // Never called in edge
1406
2136
  },
1407
2137
  }, {
1408
2138
  alarmsStateChanged: true,
1409
2139
  sensorFault: true,
1410
2140
  });
1411
2141
  }
2142
+ /**
2143
+ * Creates a default boolean state configuration cluster server.
2144
+ *
2145
+ * @param contact - Optional boolean value indicating the sensor fault state. Defaults to `false` if not provided.
2146
+ */
1412
2147
  createDefaultBooleanStateConfigurationClusterServer(sensorFault = false) {
1413
2148
  this.addClusterServer(this.getDefaultBooleanStateConfigurationClusterServer(sensorFault));
1414
2149
  }
2150
+ /**
2151
+ * Get a default power source replaceable battery cluster server.
2152
+ *
2153
+ * @param batPercentRemaining - The remaining battery percentage (default: 100).
2154
+ * @param batChargeLevel - The battery charge level (default: PowerSource.BatChargeLevel.Ok).
2155
+ * @param batVoltage - The battery voltage (default: 1500).
2156
+ * @param batReplacementDescription - The battery replacement description (default: 'Battery type').
2157
+ * @param batQuantity - The battery quantity (default: 1).
2158
+ */
1415
2159
  getDefaultPowerSourceReplaceableBatteryClusterServer(batPercentRemaining = 100, batChargeLevel = PowerSource.BatChargeLevel.Ok, batVoltage = 1500, batReplacementDescription = 'Battery type', batQuantity = 1) {
1416
2160
  return ClusterServer(PowerSourceCluster.with(PowerSource.Feature.Battery, PowerSource.Feature.Replaceable), {
1417
2161
  status: PowerSource.PowerSourceStatus.Active,
@@ -1428,9 +2172,25 @@ export class MatterbridgeEndpoint extends Endpoint {
1428
2172
  endpointList: [],
1429
2173
  }, {}, {});
1430
2174
  }
2175
+ /**
2176
+ * Creates a default power source replaceable battery cluster server.
2177
+ *
2178
+ * @param batPercentRemaining - The remaining battery percentage (default: 100).
2179
+ * @param batChargeLevel - The battery charge level (default: PowerSource.BatChargeLevel.Ok).
2180
+ * @param batVoltage - The battery voltage (default: 1500).
2181
+ * @param batReplacementDescription - The battery replacement description (default: 'Battery type').
2182
+ * @param batQuantity - The battery quantity (default: 1).
2183
+ */
1431
2184
  createDefaultPowerSourceReplaceableBatteryClusterServer(batPercentRemaining = 100, batChargeLevel = PowerSource.BatChargeLevel.Ok, batVoltage = 1500, batReplacementDescription = 'Battery type', batQuantity = 1) {
1432
2185
  this.addClusterServer(this.getDefaultPowerSourceReplaceableBatteryClusterServer(batPercentRemaining, batChargeLevel, batVoltage, batReplacementDescription, batQuantity));
1433
2186
  }
2187
+ /**
2188
+ * Get a default power source rechargeable battery cluster server.
2189
+ *
2190
+ * @param batPercentRemaining - The remaining battery percentage (default: 100).
2191
+ * @param batChargeLevel - The battery charge level (default: PowerSource.BatChargeLevel.Ok).
2192
+ * @param batVoltage - The battery voltage (default: 1500).
2193
+ */
1434
2194
  getDefaultPowerSourceRechargeableBatteryClusterServer(batPercentRemaining = 100, batChargeLevel = PowerSource.BatChargeLevel.Ok, batVoltage = 1500) {
1435
2195
  return ClusterServer(PowerSourceCluster.with(PowerSource.Feature.Battery, PowerSource.Feature.Rechargeable), {
1436
2196
  status: PowerSource.PowerSourceStatus.Active,
@@ -1448,9 +2208,21 @@ export class MatterbridgeEndpoint extends Endpoint {
1448
2208
  endpointList: [],
1449
2209
  }, {}, {});
1450
2210
  }
2211
+ /**
2212
+ * Creates a default power source rechargeable battery cluster server.
2213
+ *
2214
+ * @param batPercentRemaining - The remaining battery percentage (default: 100).
2215
+ * @param batChargeLevel - The battery charge level (default: PowerSource.BatChargeLevel.Ok).
2216
+ * @param batVoltage - The battery voltage (default: 1500).
2217
+ */
1451
2218
  createDefaultPowerSourceRechargeableBatteryClusterServer(batPercentRemaining = 100, batChargeLevel = PowerSource.BatChargeLevel.Ok, batVoltage = 1500) {
1452
2219
  this.addClusterServer(this.getDefaultPowerSourceRechargeableBatteryClusterServer(batPercentRemaining, batChargeLevel, batVoltage));
1453
2220
  }
2221
+ /**
2222
+ * Get a default power source wired cluster server.
2223
+ *
2224
+ * @param wiredCurrentType - The type of wired current (default: PowerSource.WiredCurrentType.Ac)
2225
+ */
1454
2226
  getDefaultPowerSourceWiredClusterServer(wiredCurrentType = PowerSource.WiredCurrentType.Ac) {
1455
2227
  return ClusterServer(PowerSourceCluster.with(PowerSource.Feature.Wired), {
1456
2228
  wiredCurrentType,
@@ -1460,22 +2232,45 @@ export class MatterbridgeEndpoint extends Endpoint {
1460
2232
  endpointList: [],
1461
2233
  }, {}, {});
1462
2234
  }
2235
+ /**
2236
+ * Creates a default power source wired cluster server.
2237
+ *
2238
+ * @param wiredCurrentType - The type of wired current (default: PowerSource.WiredCurrentType.Ac)
2239
+ */
1463
2240
  createDefaultPowerSourceWiredClusterServer(wiredCurrentType = PowerSource.WiredCurrentType.Ac) {
1464
2241
  this.addClusterServer(this.getDefaultPowerSourceWiredClusterServer(wiredCurrentType));
1465
2242
  }
2243
+ /**
2244
+ * @deprecated This function is deprecated by Matter 1.3 spec and will be removed in a future version.
2245
+ */
1466
2246
  createDefaultPowerSourceConfigurationClusterServer(endpointNumber) {
1467
2247
  this.addClusterServer(ClusterServer(PowerSourceConfigurationCluster, {
1468
2248
  sources: endpointNumber ? [EndpointNumber(endpointNumber)] : [],
1469
2249
  }, {}, {}));
1470
2250
  }
2251
+ /**
2252
+ * Get a default air quality cluster server.
2253
+ *
2254
+ * @param airQuality The air quality type. Defaults to `AirQuality.AirQualityType.Unknown`.
2255
+ */
1471
2256
  getDefaultAirQualityClusterServer(airQuality = AirQuality.AirQualityEnum.Unknown) {
1472
2257
  return ClusterServer(AirQualityCluster.with(AirQuality.Feature.Fair, AirQuality.Feature.Moderate, AirQuality.Feature.VeryPoor, AirQuality.Feature.ExtremelyPoor), {
1473
2258
  airQuality,
1474
2259
  }, {}, {});
1475
2260
  }
2261
+ /**
2262
+ * Creates a default air quality cluster server.
2263
+ *
2264
+ * @param airQuality The air quality type. Defaults to `AirQuality.AirQualityType.Unknown`.
2265
+ */
1476
2266
  createDefaultAirQualityClusterServer(airQuality = AirQuality.AirQualityEnum.Unknown) {
1477
2267
  this.addClusterServer(this.getDefaultAirQualityClusterServer(airQuality));
1478
2268
  }
2269
+ /**
2270
+ * Get a default TVOC measurement cluster server.
2271
+ *
2272
+ * @param measuredValue - The measured value for TVOC.
2273
+ */
1479
2274
  getDefaultTvocMeasurementClusterServer(measuredValue = 0, measurementUnit = ConcentrationMeasurement.MeasurementUnit.Ppm, measurementMedium = ConcentrationMeasurement.MeasurementMedium.Air) {
1480
2275
  return ClusterServer(TotalVolatileOrganicCompoundsConcentrationMeasurementCluster.with('NumericMeasurement'), {
1481
2276
  measuredValue,
@@ -1486,14 +2281,28 @@ export class MatterbridgeEndpoint extends Endpoint {
1486
2281
  measurementMedium,
1487
2282
  }, {}, {});
1488
2283
  }
2284
+ /**
2285
+ * Creates a default TVOC measurement cluster server.
2286
+ *
2287
+ * @param measuredValue - The measured value for TVOC.
2288
+ */
1489
2289
  createDefaultTvocMeasurementClusterServer(measuredValue = 0, measurementUnit = ConcentrationMeasurement.MeasurementUnit.Ppm, measurementMedium = ConcentrationMeasurement.MeasurementMedium.Air) {
1490
2290
  this.addClusterServer(this.getDefaultTvocMeasurementClusterServer(measuredValue, measurementUnit, measurementMedium));
1491
2291
  }
2292
+ /**
2293
+ * Get a default heating thermostat cluster server with the specified parameters.
2294
+ * @param {number} [localTemperature] - The local temperature value in degrees Celsius. Defaults to 23°.
2295
+ * @param {number} [occupiedHeatingSetpoint] - The occupied heating setpoint value in degrees Celsius. Defaults to 21°.
2296
+ * @param {number} [minHeatSetpointLimit] - The minimum heat setpoint limit value. Defaults to 0°.
2297
+ * @param {number} [maxHeatSetpointLimit] - The maximum heat setpoint limit value. Defaults to 50°.
2298
+ * @returns {ThermostatClusterServer} A default thermostat cluster server configured with the specified parameters.
2299
+ */
1492
2300
  getDefaultHeatingThermostatClusterServer(localTemperature = 23, occupiedHeatingSetpoint = 21, minHeatSetpointLimit = 0, maxHeatSetpointLimit = 50) {
1493
2301
  return ClusterServer(ThermostatCluster.with(Thermostat.Feature.Heating), {
1494
2302
  localTemperature: localTemperature * 100,
1495
2303
  systemMode: Thermostat.SystemMode.Heat,
1496
2304
  controlSequenceOfOperation: Thermostat.ControlSequenceOfOperation.HeatingOnly,
2305
+ // Thermostat.Feature.Heating
1497
2306
  occupiedHeatingSetpoint: occupiedHeatingSetpoint * 100,
1498
2307
  minHeatSetpointLimit: minHeatSetpointLimit * 100,
1499
2308
  maxHeatSetpointLimit: maxHeatSetpointLimit * 100,
@@ -1501,19 +2310,35 @@ export class MatterbridgeEndpoint extends Endpoint {
1501
2310
  absMaxHeatSetpointLimit: maxHeatSetpointLimit * 100,
1502
2311
  }, {
1503
2312
  setpointRaiseLower: async (data) => {
1504
- this.log.debug('Matter command: setpointRaiseLower', data.request);
1505
- await this.commandHandler.executeHandler('setpointRaiseLower', data);
2313
+ // Never called in edge
1506
2314
  },
1507
2315
  }, {});
1508
2316
  }
2317
+ /**
2318
+ * Creates and adds a default heating thermostat cluster server to the device.
2319
+ *
2320
+ * @param {number} [localTemperature] - The local temperature value in degrees Celsius. Defaults to 23°.
2321
+ * @param {number} [occupiedHeatingSetpoint] - The occupied heating setpoint value in degrees Celsius. Defaults to 21°.
2322
+ * @param {number} [minHeatSetpointLimit] - The minimum heat setpoint limit value. Defaults to 0°.
2323
+ * @param {number} [maxHeatSetpointLimit] - The maximum heat setpoint limit value. Defaults to 50°.
2324
+ */
1509
2325
  createDefaultHeatingThermostatClusterServer(localTemperature = 23, occupiedHeatingSetpoint = 25, minHeatSetpointLimit = 0, maxHeatSetpointLimit = 50) {
1510
2326
  this.addClusterServer(this.getDefaultHeatingThermostatClusterServer(localTemperature, occupiedHeatingSetpoint, minHeatSetpointLimit, maxHeatSetpointLimit));
1511
2327
  }
2328
+ /**
2329
+ * Get a default cooling thermostat cluster server with the specified parameters.
2330
+ * @param {number} [localTemperature] - The local temperature value in degrees Celsius. Defaults to 23°.
2331
+ * @param {number} [occupiedCoolingSetpoint] - The occupied cooling setpoint value in degrees Celsius. Defaults to 25°.
2332
+ * @param {number} [minCoolSetpointLimit] - The minimum cool setpoint limit value. Defaults to 0°.
2333
+ * @param {number} [maxCoolSetpointLimit] - The maximum cool setpoint limit value. Defaults to 50°.
2334
+ * @returns {ThermostatClusterServer} A default thermostat cluster server configured with the specified parameters.
2335
+ */
1512
2336
  getDefaultCoolingThermostatClusterServer(localTemperature = 23, occupiedCoolingSetpoint = 25, minCoolSetpointLimit = 0, maxCoolSetpointLimit = 50) {
1513
2337
  return ClusterServer(ThermostatCluster.with(Thermostat.Feature.Cooling), {
1514
2338
  localTemperature: localTemperature * 100,
1515
2339
  systemMode: Thermostat.SystemMode.Cool,
1516
2340
  controlSequenceOfOperation: Thermostat.ControlSequenceOfOperation.CoolingOnly,
2341
+ // Thermostat.Feature.Cooling
1517
2342
  occupiedCoolingSetpoint: occupiedCoolingSetpoint * 100,
1518
2343
  minCoolSetpointLimit: minCoolSetpointLimit * 100,
1519
2344
  maxCoolSetpointLimit: maxCoolSetpointLimit * 100,
@@ -1521,41 +2346,82 @@ export class MatterbridgeEndpoint extends Endpoint {
1521
2346
  absMaxCoolSetpointLimit: maxCoolSetpointLimit * 100,
1522
2347
  }, {
1523
2348
  setpointRaiseLower: async (data) => {
1524
- this.log.debug('Matter command: setpointRaiseLower', data.request);
1525
- await this.commandHandler.executeHandler('setpointRaiseLower', data);
2349
+ // Never called in edge
1526
2350
  },
1527
2351
  }, {});
1528
2352
  }
2353
+ /**
2354
+ * Creates and adds a default cooling thermostat cluster server to the device.
2355
+ *
2356
+ * @param {number} [localTemperature] - The local temperature value in degrees Celsius. Defaults to 23°.
2357
+ * @param {number} [occupiedCoolingSetpoint] - The occupied cooling setpoint value in degrees Celsius. Defaults to 25°.
2358
+ * @param {number} [minCoolSetpointLimit] - The minimum cool setpoint limit value. Defaults to 0°.
2359
+ * @param {number} [maxCoolSetpointLimit] - The maximum cool setpoint limit value. Defaults to 50°.
2360
+ */
1529
2361
  createDefaultCoolingThermostatClusterServer(localTemperature = 23, occupiedCoolingSetpoint = 25, minCoolSetpointLimit = 0, maxCoolSetpointLimit = 50) {
1530
2362
  this.addClusterServer(this.getDefaultCoolingThermostatClusterServer(localTemperature, occupiedCoolingSetpoint, minCoolSetpointLimit, maxCoolSetpointLimit));
1531
2363
  }
2364
+ /**
2365
+ * Get a default thermostat cluster server with the specified parameters.
2366
+ *
2367
+ * @param {number} [localTemperature=23] - The local temperature value in degrees Celsius. Defaults to 23°.
2368
+ * @param {number} [occupiedHeatingSetpoint=21] - The occupied heating setpoint value in degrees Celsius. Defaults to 21°.
2369
+ * @param {number} [occupiedCoolingSetpoint=25] - The occupied cooling setpoint value in degrees Celsius. Defaults to 25°.
2370
+ * @param {number} [minSetpointDeadBand=1] - The minimum setpoint dead band value. Defaults to 1°.
2371
+ * @param {number} [minHeatSetpointLimit=0] - The minimum heat setpoint limit value. Defaults to 0°.
2372
+ * @param {number} [maxHeatSetpointLimit=50] - The maximum heat setpoint limit value. Defaults to 50°.
2373
+ * @param {number} [minCoolSetpointLimit=0] - The minimum cool setpoint limit value. Defaults to 0°.
2374
+ * @param {number} [maxCoolSetpointLimit=50] - The maximum cool setpoint limit value. Defaults to 50°.
2375
+ * @returns {ThermostatClusterServer} A default thermostat cluster server configured with the specified parameters.
2376
+ */
1532
2377
  getDefaultThermostatClusterServer(localTemperature = 23, occupiedHeatingSetpoint = 21, occupiedCoolingSetpoint = 25, minSetpointDeadBand = 1, minHeatSetpointLimit = 0, maxHeatSetpointLimit = 50, minCoolSetpointLimit = 0, maxCoolSetpointLimit = 50) {
1533
2378
  return ClusterServer(ThermostatCluster.with(Thermostat.Feature.Heating, Thermostat.Feature.Cooling, Thermostat.Feature.AutoMode), {
1534
2379
  localTemperature: localTemperature * 100,
1535
2380
  systemMode: Thermostat.SystemMode.Auto,
1536
2381
  controlSequenceOfOperation: Thermostat.ControlSequenceOfOperation.CoolingAndHeating,
2382
+ // Thermostat.Feature.Heating
1537
2383
  occupiedHeatingSetpoint: occupiedHeatingSetpoint * 100,
1538
2384
  minHeatSetpointLimit: minHeatSetpointLimit * 100,
1539
2385
  maxHeatSetpointLimit: maxHeatSetpointLimit * 100,
1540
2386
  absMinHeatSetpointLimit: minHeatSetpointLimit * 100,
1541
2387
  absMaxHeatSetpointLimit: maxHeatSetpointLimit * 100,
2388
+ // Thermostat.Feature.Cooling
1542
2389
  occupiedCoolingSetpoint: occupiedCoolingSetpoint * 100,
1543
2390
  minCoolSetpointLimit: minCoolSetpointLimit * 100,
1544
2391
  maxCoolSetpointLimit: maxCoolSetpointLimit * 100,
1545
2392
  absMinCoolSetpointLimit: minCoolSetpointLimit * 100,
1546
2393
  absMaxCoolSetpointLimit: maxCoolSetpointLimit * 100,
2394
+ // Thermostat.Feature.AutoMode
1547
2395
  minSetpointDeadBand: minSetpointDeadBand * 100,
1548
2396
  thermostatRunningMode: Thermostat.ThermostatRunningMode.Off,
1549
2397
  }, {
1550
2398
  setpointRaiseLower: async (data) => {
1551
- this.log.debug('Matter command: setpointRaiseLower', data.request);
1552
- await this.commandHandler.executeHandler('setpointRaiseLower', data);
2399
+ // Never called in edge
1553
2400
  },
1554
2401
  }, {});
1555
2402
  }
2403
+ /**
2404
+ * Creates and adds a default thermostat cluster server to the device.
2405
+ *
2406
+ * @param {number} [localTemperature=23] - The local temperature value in degrees Celsius. Defaults to 23°.
2407
+ * @param {number} [occupiedHeatingSetpoint=21] - The occupied heating setpoint value in degrees Celsius. Defaults to 21°.
2408
+ * @param {number} [occupiedCoolingSetpoint=25] - The occupied cooling setpoint value in degrees Celsius. Defaults to 25°.
2409
+ * @param {number} [minSetpointDeadBand=1] - The minimum setpoint dead band value. Defaults to 1°.
2410
+ * @param {number} [minHeatSetpointLimit=0] - The minimum heat setpoint limit value. Defaults to 0°.
2411
+ * @param {number} [maxHeatSetpointLimit=50] - The maximum heat setpoint limit value. Defaults to 50°.
2412
+ * @param {number} [minCoolSetpointLimit=0] - The minimum cool setpoint limit value. Defaults to 0°.
2413
+ * @param {number} [maxCoolSetpointLimit=50] - The maximum cool setpoint limit value. Defaults to 50°.
2414
+ */
1556
2415
  createDefaultThermostatClusterServer(localTemperature = 23, occupiedHeatingSetpoint = 21, occupiedCoolingSetpoint = 25, minSetpointDeadBand = 1, minHeatSetpointLimit = 0, maxHeatSetpointLimit = 50, minCoolSetpointLimit = 0, maxCoolSetpointLimit = 50) {
1557
2416
  this.addClusterServer(this.getDefaultThermostatClusterServer(localTemperature, occupiedHeatingSetpoint, occupiedCoolingSetpoint, minSetpointDeadBand, minHeatSetpointLimit, maxHeatSetpointLimit, minCoolSetpointLimit, maxCoolSetpointLimit));
1558
2417
  }
2418
+ /**
2419
+ * Returns the default SmokeCOAlarm Cluster Server.
2420
+ *
2421
+ * @param smokeState - The state of the smoke alarm. Defaults to SmokeCoAlarm.AlarmState.Normal.
2422
+ * @param coState - The state of the CO alarm. Defaults to SmokeCoAlarm.AlarmState.Normal.
2423
+ * @returns The default SmokeCOAlarmClusterServer.
2424
+ */
1559
2425
  getDefaultSmokeCOAlarmClusterServer(smokeState = SmokeCoAlarm.AlarmState.Normal, coState = SmokeCoAlarm.AlarmState.Normal) {
1560
2426
  return ClusterServer(SmokeCoAlarmCluster.with(SmokeCoAlarm.Feature.SmokeAlarm, SmokeCoAlarm.Feature.CoAlarm), {
1561
2427
  smokeState,
@@ -1570,8 +2436,7 @@ export class MatterbridgeEndpoint extends Endpoint {
1570
2436
  interconnectCoAlarm: SmokeCoAlarm.AlarmState.Normal,
1571
2437
  }, {
1572
2438
  selfTestRequest: async (data) => {
1573
- this.log.debug('Matter command: selfTestRequest');
1574
- await this.commandHandler.executeHandler('selfTestRequest', data);
2439
+ // Never called in edge
1575
2440
  },
1576
2441
  }, {
1577
2442
  smokeAlarm: true,
@@ -1587,9 +2452,24 @@ export class MatterbridgeEndpoint extends Endpoint {
1587
2452
  allClear: true,
1588
2453
  });
1589
2454
  }
2455
+ /**
2456
+ * Create the default SmokeCOAlarm Cluster Server.
2457
+ *
2458
+ * @param smokeState - The state of the smoke alarm. Defaults to SmokeCoAlarm.AlarmState.Normal.
2459
+ * @param coState - The state of the CO alarm. Defaults to SmokeCoAlarm.AlarmState.Normal.
2460
+ * @returns The default SmokeCOAlarmClusterServer.
2461
+ */
1590
2462
  createDefaultSmokeCOAlarmClusterServer(smokeState = SmokeCoAlarm.AlarmState.Normal, coState = SmokeCoAlarm.AlarmState.Normal) {
1591
2463
  this.addClusterServer(this.getDefaultSmokeCOAlarmClusterServer(smokeState, coState));
1592
2464
  }
2465
+ /**
2466
+ * Returns the default Carbon Monoxide Concentration Measurement Cluster Server.
2467
+ *
2468
+ * @param {number} measuredValue - The measured value of the concentration.
2469
+ * @param {ConcentrationMeasurement.MeasurementUnit} measurementUnit - The unit of measurement.
2470
+ * @param {ConcentrationMeasurement.MeasurementMedium} measurementMedium - The medium of measurement.
2471
+ * @returns {ClusterServer} - The default Carbon Monoxide Concentration Measurement Cluster Server.
2472
+ */
1593
2473
  getDefaultCarbonMonoxideConcentrationMeasurementClusterServer(measuredValue = 0, measurementUnit = ConcentrationMeasurement.MeasurementUnit.Ppm, measurementMedium = ConcentrationMeasurement.MeasurementMedium.Air) {
1594
2474
  return ClusterServer(CarbonMonoxideConcentrationMeasurementCluster.with('NumericMeasurement'), {
1595
2475
  measuredValue,
@@ -1600,9 +2480,24 @@ export class MatterbridgeEndpoint extends Endpoint {
1600
2480
  measurementMedium,
1601
2481
  }, {}, {});
1602
2482
  }
2483
+ /**
2484
+ * Create the default Carbon Monoxide Concentration Measurement Cluster Server.
2485
+ *
2486
+ * @param {number} measuredValue - The measured value of the concentration.
2487
+ * @param {ConcentrationMeasurement.MeasurementUnit} measurementUnit - The unit of measurement.
2488
+ * @param {ConcentrationMeasurement.MeasurementMedium} measurementMedium - The medium of measurement.
2489
+ */
1603
2490
  createDefaultCarbonMonoxideConcentrationMeasurementClusterServer(measuredValue = 0, measurementUnit = ConcentrationMeasurement.MeasurementUnit.Ppm, measurementMedium = ConcentrationMeasurement.MeasurementMedium.Air) {
1604
2491
  this.addClusterServer(this.getDefaultCarbonMonoxideConcentrationMeasurementClusterServer(measuredValue, measurementUnit, measurementMedium));
1605
2492
  }
2493
+ /**
2494
+ * Returns the default Carbon Dioxide Concentration Measurement Cluster Server.
2495
+ *
2496
+ * @param {number} measuredValue - The measured value of the concentration.
2497
+ * @param {ConcentrationMeasurement.MeasurementUnit} measurementUnit - The unit of measurement.
2498
+ * @param {ConcentrationMeasurement.MeasurementMedium} measurementMedium - The medium of measurement.
2499
+ * @returns {ClusterServer} - The default Carbon Monoxide Concentration Measurement Cluster Server.
2500
+ */
1606
2501
  getDefaultCarbonDioxideConcentrationMeasurementClusterServer(measuredValue = 0, measurementUnit = ConcentrationMeasurement.MeasurementUnit.Ppm, measurementMedium = ConcentrationMeasurement.MeasurementMedium.Air) {
1607
2502
  return ClusterServer(CarbonDioxideConcentrationMeasurementCluster.with('NumericMeasurement'), {
1608
2503
  measuredValue,
@@ -1613,9 +2508,24 @@ export class MatterbridgeEndpoint extends Endpoint {
1613
2508
  measurementMedium,
1614
2509
  }, {}, {});
1615
2510
  }
2511
+ /**
2512
+ * Create the default Carbon Dioxide Concentration Measurement Cluster Server.
2513
+ *
2514
+ * @param {number} measuredValue - The measured value of the concentration.
2515
+ * @param {ConcentrationMeasurement.MeasurementUnit} measurementUnit - The unit of measurement.
2516
+ * @param {ConcentrationMeasurement.MeasurementMedium} measurementMedium - The medium of measurement.
2517
+ */
1616
2518
  createDefaultCarbonDioxideConcentrationMeasurementClusterServer(measuredValue = 0, measurementUnit = ConcentrationMeasurement.MeasurementUnit.Ppm, measurementMedium = ConcentrationMeasurement.MeasurementMedium.Air) {
1617
2519
  this.addClusterServer(this.getDefaultCarbonDioxideConcentrationMeasurementClusterServer(measuredValue, measurementUnit, measurementMedium));
1618
2520
  }
2521
+ /**
2522
+ * Returns the default Formaldehyde Concentration Measurement Cluster Server.
2523
+ *
2524
+ * @param {number} measuredValue - The measured value of the concentration.
2525
+ * @param {ConcentrationMeasurement.MeasurementUnit} measurementUnit - The unit of measurement.
2526
+ * @param {ConcentrationMeasurement.MeasurementMedium} measurementMedium - The medium of measurement.
2527
+ * @returns {ClusterServer} - The default Carbon Monoxide Concentration Measurement Cluster Server.
2528
+ */
1619
2529
  getDefaultFormaldehydeConcentrationMeasurementClusterServer(measuredValue = 0, measurementUnit = ConcentrationMeasurement.MeasurementUnit.Ppm, measurementMedium = ConcentrationMeasurement.MeasurementMedium.Air) {
1620
2530
  return ClusterServer(FormaldehydeConcentrationMeasurementCluster.with('NumericMeasurement'), {
1621
2531
  measuredValue,
@@ -1626,9 +2536,24 @@ export class MatterbridgeEndpoint extends Endpoint {
1626
2536
  measurementMedium,
1627
2537
  }, {}, {});
1628
2538
  }
2539
+ /**
2540
+ * Create the default Formaldehyde Concentration Measurement Cluster Server.
2541
+ *
2542
+ * @param {number} measuredValue - The measured value of the concentration.
2543
+ * @param {ConcentrationMeasurement.MeasurementUnit} measurementUnit - The unit of measurement.
2544
+ * @param {ConcentrationMeasurement.MeasurementMedium} measurementMedium - The medium of measurement.
2545
+ */
1629
2546
  createDefaultFormaldehydeConcentrationMeasurementClusterServer(measuredValue = 0, measurementUnit = ConcentrationMeasurement.MeasurementUnit.Ppm, measurementMedium = ConcentrationMeasurement.MeasurementMedium.Air) {
1630
2547
  this.addClusterServer(this.getDefaultFormaldehydeConcentrationMeasurementClusterServer(measuredValue, measurementUnit, measurementMedium));
1631
2548
  }
2549
+ /**
2550
+ * Returns the default Pm1 Concentration Measurement Cluster Server.
2551
+ *
2552
+ * @param {number} measuredValue - The measured value of the concentration.
2553
+ * @param {ConcentrationMeasurement.MeasurementUnit} measurementUnit - The unit of measurement.
2554
+ * @param {ConcentrationMeasurement.MeasurementMedium} measurementMedium - The medium of measurement.
2555
+ * @returns {ClusterServer} - The default Carbon Monoxide Concentration Measurement Cluster Server.
2556
+ */
1632
2557
  getDefaultPm1ConcentrationMeasurementClusterServer(measuredValue = 0, measurementUnit = ConcentrationMeasurement.MeasurementUnit.Ppm, measurementMedium = ConcentrationMeasurement.MeasurementMedium.Air) {
1633
2558
  return ClusterServer(Pm1ConcentrationMeasurementCluster.with('NumericMeasurement'), {
1634
2559
  measuredValue,
@@ -1639,9 +2564,24 @@ export class MatterbridgeEndpoint extends Endpoint {
1639
2564
  measurementMedium,
1640
2565
  }, {}, {});
1641
2566
  }
2567
+ /**
2568
+ * Create the default Pm1 Concentration Measurement Cluster Server.
2569
+ *
2570
+ * @param {number} measuredValue - The measured value of the concentration.
2571
+ * @param {ConcentrationMeasurement.MeasurementUnit} measurementUnit - The unit of measurement.
2572
+ * @param {ConcentrationMeasurement.MeasurementMedium} measurementMedium - The medium of measurement.
2573
+ */
1642
2574
  createDefaultPm1ConcentrationMeasurementClusterServer(measuredValue = 0, measurementUnit = ConcentrationMeasurement.MeasurementUnit.Ppm, measurementMedium = ConcentrationMeasurement.MeasurementMedium.Air) {
1643
2575
  this.addClusterServer(this.getDefaultPm1ConcentrationMeasurementClusterServer(measuredValue, measurementUnit, measurementMedium));
1644
2576
  }
2577
+ /**
2578
+ * Returns the default Pm25 Concentration Measurement Cluster Server.
2579
+ *
2580
+ * @param {number} measuredValue - The measured value of the concentration.
2581
+ * @param {ConcentrationMeasurement.MeasurementUnit} measurementUnit - The unit of measurement.
2582
+ * @param {ConcentrationMeasurement.MeasurementMedium} measurementMedium - The medium of measurement.
2583
+ * @returns {ClusterServer} - The default Carbon Monoxide Concentration Measurement Cluster Server.
2584
+ */
1645
2585
  getDefaultPm25ConcentrationMeasurementClusterServer(measuredValue = 0, measurementUnit = ConcentrationMeasurement.MeasurementUnit.Ppm, measurementMedium = ConcentrationMeasurement.MeasurementMedium.Air) {
1646
2586
  return ClusterServer(Pm25ConcentrationMeasurementCluster.with('NumericMeasurement'), {
1647
2587
  measuredValue,
@@ -1652,9 +2592,24 @@ export class MatterbridgeEndpoint extends Endpoint {
1652
2592
  measurementMedium,
1653
2593
  }, {}, {});
1654
2594
  }
2595
+ /**
2596
+ * Create the default Pm25 Concentration Measurement Cluster Server.
2597
+ *
2598
+ * @param {number} measuredValue - The measured value of the concentration.
2599
+ * @param {ConcentrationMeasurement.MeasurementUnit} measurementUnit - The unit of measurement.
2600
+ * @param {ConcentrationMeasurement.MeasurementMedium} measurementMedium - The medium of measurement.
2601
+ */
1655
2602
  createDefaultPm25ConcentrationMeasurementClusterServer(measuredValue = 0, measurementUnit = ConcentrationMeasurement.MeasurementUnit.Ppm, measurementMedium = ConcentrationMeasurement.MeasurementMedium.Air) {
1656
2603
  this.addClusterServer(this.getDefaultPm25ConcentrationMeasurementClusterServer(measuredValue, measurementUnit, measurementMedium));
1657
2604
  }
2605
+ /**
2606
+ * Returns the default Pm10 Concentration Measurement Cluster Server.
2607
+ *
2608
+ * @param {number} measuredValue - The measured value of the concentration.
2609
+ * @param {ConcentrationMeasurement.MeasurementUnit} measurementUnit - The unit of measurement.
2610
+ * @param {ConcentrationMeasurement.MeasurementMedium} measurementMedium - The medium of measurement.
2611
+ * @returns {ClusterServer} - The default Carbon Monoxide Concentration Measurement Cluster Server.
2612
+ */
1658
2613
  getDefaultPm10ConcentrationMeasurementClusterServer(measuredValue = 0, measurementUnit = ConcentrationMeasurement.MeasurementUnit.Ppm, measurementMedium = ConcentrationMeasurement.MeasurementMedium.Air) {
1659
2614
  return ClusterServer(Pm10ConcentrationMeasurementCluster.with('NumericMeasurement'), {
1660
2615
  measuredValue,
@@ -1665,9 +2620,24 @@ export class MatterbridgeEndpoint extends Endpoint {
1665
2620
  measurementMedium,
1666
2621
  }, {}, {});
1667
2622
  }
2623
+ /**
2624
+ * Create the default Pm10 Concentration Measurement Cluster Server.
2625
+ *
2626
+ * @param {number} measuredValue - The measured value of the concentration.
2627
+ * @param {ConcentrationMeasurement.MeasurementUnit} measurementUnit - The unit of measurement.
2628
+ * @param {ConcentrationMeasurement.MeasurementMedium} measurementMedium - The medium of measurement.
2629
+ */
1668
2630
  createDefaultPm10ConcentrationMeasurementClusterServer(measuredValue = 0, measurementUnit = ConcentrationMeasurement.MeasurementUnit.Ppm, measurementMedium = ConcentrationMeasurement.MeasurementMedium.Air) {
1669
2631
  this.addClusterServer(this.getDefaultPm10ConcentrationMeasurementClusterServer(measuredValue, measurementUnit, measurementMedium));
1670
2632
  }
2633
+ /**
2634
+ * Returns the default Ozone Concentration Measurement Cluster Server.
2635
+ *
2636
+ * @param {number} measuredValue - The measured value of the concentration.
2637
+ * @param {ConcentrationMeasurement.MeasurementUnit} measurementUnit - The unit of measurement.
2638
+ * @param {ConcentrationMeasurement.MeasurementMedium} measurementMedium - The medium of measurement.
2639
+ * @returns {ClusterServer} - The default Carbon Monoxide Concentration Measurement Cluster Server.
2640
+ */
1671
2641
  getDefaultOzoneConcentrationMeasurementClusterServer(measuredValue = 0, measurementUnit = ConcentrationMeasurement.MeasurementUnit.Ugm3, measurementMedium = ConcentrationMeasurement.MeasurementMedium.Air) {
1672
2642
  return ClusterServer(OzoneConcentrationMeasurementCluster.with('NumericMeasurement'), {
1673
2643
  measuredValue,
@@ -1678,9 +2648,24 @@ export class MatterbridgeEndpoint extends Endpoint {
1678
2648
  measurementMedium,
1679
2649
  }, {}, {});
1680
2650
  }
2651
+ /**
2652
+ * Create the default Ozone Concentration Measurement Cluster Server.
2653
+ *
2654
+ * @param {number} measuredValue - The measured value of the concentration.
2655
+ * @param {ConcentrationMeasurement.MeasurementUnit} measurementUnit - The unit of measurement.
2656
+ * @param {ConcentrationMeasurement.MeasurementMedium} measurementMedium - The medium of measurement.
2657
+ */
1681
2658
  createDefaultOzoneConcentrationMeasurementClusterServer(measuredValue = 0, measurementUnit = ConcentrationMeasurement.MeasurementUnit.Ugm3, measurementMedium = ConcentrationMeasurement.MeasurementMedium.Air) {
1682
2659
  this.addClusterServer(this.getDefaultOzoneConcentrationMeasurementClusterServer(measuredValue, measurementUnit, measurementMedium));
1683
2660
  }
2661
+ /**
2662
+ * Returns the default Radon Concentration Measurement Cluster Server.
2663
+ *
2664
+ * @param {number} measuredValue - The measured value of the concentration.
2665
+ * @param {ConcentrationMeasurement.MeasurementUnit} measurementUnit - The unit of measurement.
2666
+ * @param {ConcentrationMeasurement.MeasurementMedium} measurementMedium - The medium of measurement.
2667
+ * @returns {ClusterServer} - The default Carbon Monoxide Concentration Measurement Cluster Server.
2668
+ */
1684
2669
  getDefaultRadonConcentrationMeasurementClusterServer(measuredValue = 0, measurementUnit = ConcentrationMeasurement.MeasurementUnit.Ppm, measurementMedium = ConcentrationMeasurement.MeasurementMedium.Air) {
1685
2670
  return ClusterServer(RadonConcentrationMeasurementCluster.with('NumericMeasurement'), {
1686
2671
  measuredValue,
@@ -1691,9 +2676,24 @@ export class MatterbridgeEndpoint extends Endpoint {
1691
2676
  measurementMedium,
1692
2677
  }, {}, {});
1693
2678
  }
2679
+ /**
2680
+ * Create the default Radon Concentration Measurement Cluster Server.
2681
+ *
2682
+ * @param {number} measuredValue - The measured value of the concentration.
2683
+ * @param {ConcentrationMeasurement.MeasurementUnit} measurementUnit - The unit of measurement.
2684
+ * @param {ConcentrationMeasurement.MeasurementMedium} measurementMedium - The medium of measurement.
2685
+ */
1694
2686
  createDefaultRadonConcentrationMeasurementClusterServer(measuredValue = 0, measurementUnit = ConcentrationMeasurement.MeasurementUnit.Ppm, measurementMedium = ConcentrationMeasurement.MeasurementMedium.Air) {
1695
2687
  this.addClusterServer(this.getDefaultRadonConcentrationMeasurementClusterServer(measuredValue, measurementUnit, measurementMedium));
1696
2688
  }
2689
+ /**
2690
+ * Returns the default Nitrogen Dioxide Concentration Measurement Cluster Server.
2691
+ *
2692
+ * @param {number} measuredValue - The measured value of the concentration.
2693
+ * @param {ConcentrationMeasurement.MeasurementUnit} measurementUnit - The unit of measurement.
2694
+ * @param {ConcentrationMeasurement.MeasurementMedium} measurementMedium - The medium of measurement.
2695
+ * @returns {ClusterServer} - The default Carbon Monoxide Concentration Measurement Cluster Server.
2696
+ */
1697
2697
  getDefaultNitrogenDioxideConcentrationMeasurementClusterServer(measuredValue = 0, measurementUnit = ConcentrationMeasurement.MeasurementUnit.Ugm3, measurementMedium = ConcentrationMeasurement.MeasurementMedium.Air) {
1698
2698
  return ClusterServer(NitrogenDioxideConcentrationMeasurementCluster.with('NumericMeasurement'), {
1699
2699
  measuredValue,
@@ -1704,9 +2704,22 @@ export class MatterbridgeEndpoint extends Endpoint {
1704
2704
  measurementMedium,
1705
2705
  }, {}, {});
1706
2706
  }
2707
+ /**
2708
+ * Create the default Nitrogen Dioxide Concentration Measurement Cluster Server.
2709
+ *
2710
+ * @param {number} measuredValue - The measured value of the concentration.
2711
+ * @param {ConcentrationMeasurement.MeasurementUnit} measurementUnit - The unit of measurement.
2712
+ * @param {ConcentrationMeasurement.MeasurementMedium} measurementMedium - The medium of measurement.
2713
+ */
1707
2714
  createDefaultNitrogenDioxideConcentrationMeasurementClusterServer(measuredValue = 0, measurementUnit = ConcentrationMeasurement.MeasurementUnit.Ugm3, measurementMedium = ConcentrationMeasurement.MeasurementMedium.Air) {
1708
2715
  this.addClusterServer(this.getDefaultNitrogenDioxideConcentrationMeasurementClusterServer(measuredValue, measurementUnit, measurementMedium));
1709
2716
  }
2717
+ /**
2718
+ * Returns the default fan control cluster server rev 2.
2719
+ *
2720
+ * @param fanMode The fan mode to set. Defaults to `FanControl.FanMode.Off`.
2721
+ * @returns The default fan control cluster server.
2722
+ */
1710
2723
  getDefaultFanControlClusterServer(fanMode = FanControl.FanMode.Off) {
1711
2724
  return ClusterServer(FanControlCluster.with(FanControl.Feature.MultiSpeed, FanControl.Feature.Auto, FanControl.Feature.Step), {
1712
2725
  fanMode,
@@ -1718,12 +2731,18 @@ export class MatterbridgeEndpoint extends Endpoint {
1718
2731
  speedCurrent: 0,
1719
2732
  }, {
1720
2733
  step: async (data) => {
1721
- this.log.debug('Matter command: step', data.request);
1722
- await this.commandHandler.executeHandler('step', data);
2734
+ // Never called in edge
1723
2735
  },
1724
2736
  }, {});
1725
2737
  }
2738
+ /**
2739
+ * Create the default fan control cluster server rev 2.
2740
+ *
2741
+ * @param fanMode The fan mode to set. Defaults to `FanControl.FanMode.Off`.
2742
+ * @returns The default fan control cluster server.
2743
+ */
1726
2744
  createDefaultFanControlClusterServer(fanMode = FanControl.FanMode.Off) {
1727
2745
  this.addClusterServer(this.getDefaultFanControlClusterServer(fanMode));
1728
2746
  }
1729
2747
  }
2748
+ //# sourceMappingURL=matterbridgeEndpoint.js.map