matterbridge-example-dynamic-platform 1.1.8 → 1.2.0-edge.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/platform.js CHANGED
@@ -1,9 +1,13 @@
1
- import { MatterbridgeEndpoint, MatterbridgeDynamicPlatform, airConditioner, airQualitySensor, bridgedNode, colorTemperatureLight, coverDevice, dimmableLight, doorLockDevice, fanDevice, flowSensor, humiditySensor, onOffLight, onOffOutlet, onOffSwitch, powerSource, rainSensor, smokeCoAlarm, temperatureSensor, thermostatDevice, waterFreezeDetector, waterLeakDetector, airPurifier, pumpDevice, waterValve, genericSwitch, } from 'matterbridge';
1
+ import { MatterbridgeEndpoint, MatterbridgeDynamicPlatform, airQualitySensor, bridgedNode, colorTemperatureLight, coverDevice, dimmableLight, doorLockDevice, fanDevice, flowSensor, humiditySensor, onOffLight, onOffOutlet, onOffSwitch, powerSource, rainSensor, smokeCoAlarm, temperatureSensor, thermostatDevice, waterFreezeDetector, waterLeakDetector, airPurifier, pumpDevice, waterValve, genericSwitch, airConditioner, laundryWasher, cooktop, extractorHood, microwaveOven, oven, refrigerator, dishwasher, laundryDryer, onOffMountedSwitch, dimmableMountedSwitch, extendedColorLight, } from 'matterbridge';
2
2
  import { isValidBoolean, isValidNumber } from 'matterbridge/utils';
3
3
  import { LocationTag } from 'matterbridge/matter';
4
4
  import { PowerSource, BooleanState, OnOff, LevelControl, AirQuality, CarbonDioxideConcentrationMeasurement, CarbonMonoxideConcentrationMeasurement, FlowMeasurement, ColorControl, DoorLock, FanControl, FormaldehydeConcentrationMeasurement, NitrogenDioxideConcentrationMeasurement, OzoneConcentrationMeasurement, Pm10ConcentrationMeasurement, Pm1ConcentrationMeasurement, Pm25ConcentrationMeasurement, RadonConcentrationMeasurement, RelativeHumidityMeasurement, RelativeHumidityMeasurementCluster, SmokeCoAlarm, TemperatureMeasurement, Thermostat, ThermostatCluster, TotalVolatileOrganicCompoundsConcentrationMeasurement, WindowCovering, } from 'matterbridge/matter/clusters';
5
+ import { Appliances } from './appliances.js';
6
+ import { Robot } from './robot.js';
5
7
  export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatform {
6
8
  switch;
9
+ mountedOnOffSwitch;
10
+ mountedDimmerSwitch;
7
11
  lightOnOff;
8
12
  dimmer;
9
13
  light;
@@ -20,7 +24,9 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
20
24
  waterLeak;
21
25
  waterFreeze;
22
26
  rain;
23
- smoke;
27
+ smokeCo;
28
+ smokeOnly;
29
+ coOnly;
24
30
  airQuality;
25
31
  airConditioner;
26
32
  airPurifier;
@@ -28,6 +34,7 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
28
34
  valve;
29
35
  momentarySwitch;
30
36
  latchingSwitch;
37
+ vacuum;
31
38
  switchInterval;
32
39
  lightInterval;
33
40
  outletInterval;
@@ -43,320 +50,448 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
43
50
  airConditionerInterval;
44
51
  genericSwitchInterval;
45
52
  genericSwitchLastEvent = 'Release';
53
+ intervalOnOff = false;
54
+ intervalLevel = 0;
55
+ intervalColorTemperature = 147;
46
56
  bridgedDevices = new Map();
47
57
  fanModeLookup = ['Off', 'Low', 'Medium', 'High', 'On', 'Auto', 'Smart'];
48
58
  constructor(matterbridge, log, config) {
49
59
  super(matterbridge, log, config);
50
- if (this.verifyMatterbridgeVersion === undefined || typeof this.verifyMatterbridgeVersion !== 'function' || !this.verifyMatterbridgeVersion('2.2.0')) {
51
- throw new Error(`This plugin requires Matterbridge version >= "2.2.0". Please update Matterbridge from ${this.matterbridge.matterbridgeVersion} to the latest version in the frontend.`);
60
+ if (this.verifyMatterbridgeVersion === undefined || typeof this.verifyMatterbridgeVersion !== 'function' || !this.verifyMatterbridgeVersion('2.2.7')) {
61
+ throw new Error(`This plugin requires Matterbridge version >= "2.2.7". Please update Matterbridge from ${this.matterbridge.matterbridgeVersion} to the latest version in the frontend.`);
52
62
  }
53
63
  this.log.info('Initializing platform:', this.config.name);
64
+ if (config.whiteList === undefined)
65
+ config.whiteList = [];
66
+ if (config.blackList === undefined)
67
+ config.blackList = [];
54
68
  }
55
69
  async onStart(reason) {
56
70
  this.log.info('onStart called with reason:', reason ?? 'none');
57
- this.switch = new MatterbridgeEndpoint([onOffSwitch, bridgedNode, powerSource], { uniqueStorageKey: 'Switch' }, this.config.debug).createDefaultIdentifyClusterServer();
58
- this.switch
71
+ await this.ready;
72
+ await this.clearSelect();
73
+ this.switch = new MatterbridgeEndpoint([onOffSwitch, bridgedNode, powerSource], { uniqueStorageKey: 'Switch' }, this.config.debug)
74
+ .createDefaultIdentifyClusterServer()
59
75
  .createDefaultGroupsClusterServer()
60
76
  .createDefaultBridgedDeviceBasicInformationClusterServer('Switch', '0x23452164', 0xfff1, 'Matterbridge', 'Matterbridge Switch', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
61
77
  .createDefaultOnOffClusterServer()
62
78
  .createDefaultPowerSourceRechargeableBatteryClusterServer(70);
63
- await this.registerDevice(this.switch);
64
- this.bridgedDevices.set(this.switch.deviceName ?? '', this.switch);
65
- this.switch.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
79
+ this.setSelectDevice(this.switch.serialNumber ?? '', this.switch.deviceName ?? '', undefined, 'hub');
80
+ if (this.validateDevice(this.switch.deviceName ?? '')) {
81
+ await this.registerDevice(this.switch);
82
+ this.bridgedDevices.set(this.switch.deviceName ?? '', this.switch);
83
+ }
84
+ else {
85
+ this.switch = undefined;
86
+ }
87
+ this.switch?.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
66
88
  this.log.info(`Command identify called identifyTime:${identifyTime}`);
67
89
  });
68
- this.switch.addCommandHandler('on', async () => {
90
+ this.switch?.addCommandHandler('on', async () => {
69
91
  await this.switch?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.switch.log);
70
92
  this.switch?.log.info('Command on called');
71
93
  });
72
- this.switch.addCommandHandler('off', async () => {
94
+ this.switch?.addCommandHandler('off', async () => {
73
95
  await this.switch?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.switch.log);
74
96
  this.switch?.log.info('Command off called');
75
97
  });
98
+ this.mountedOnOffSwitch = new MatterbridgeEndpoint([onOffMountedSwitch, bridgedNode, powerSource], { uniqueStorageKey: 'OnOffMountedSwitch' }, this.config.debug)
99
+ .createDefaultIdentifyClusterServer()
100
+ .createDefaultGroupsClusterServer()
101
+ .createDefaultBridgedDeviceBasicInformationClusterServer('OnOff Mounted Switch', '0x298242164', 0xfff1, 'Matterbridge', 'Matterbridge OnOff Mounted Switch', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
102
+ .createDefaultOnOffClusterServer()
103
+ .createDefaultPowerSourceRechargeableBatteryClusterServer(70);
104
+ this.setSelectDevice(this.mountedOnOffSwitch.serialNumber ?? '', this.mountedOnOffSwitch.deviceName ?? '', undefined, 'hub');
105
+ if (this.validateDevice(this.mountedOnOffSwitch.deviceName ?? '')) {
106
+ await this.registerDevice(this.mountedOnOffSwitch);
107
+ this.bridgedDevices.set(this.mountedOnOffSwitch.deviceName ?? '', this.mountedOnOffSwitch);
108
+ }
109
+ else {
110
+ this.mountedOnOffSwitch = undefined;
111
+ }
112
+ this.mountedOnOffSwitch?.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
113
+ this.mountedOnOffSwitch?.log.info(`Command identify called identifyTime:${identifyTime}`);
114
+ });
115
+ this.mountedOnOffSwitch?.addCommandHandler('on', async () => {
116
+ await this.mountedOnOffSwitch?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.mountedOnOffSwitch.log);
117
+ this.mountedOnOffSwitch?.log.info('Command on called');
118
+ });
119
+ this.mountedOnOffSwitch?.addCommandHandler('off', async () => {
120
+ await this.mountedOnOffSwitch?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.mountedOnOffSwitch.log);
121
+ this.mountedOnOffSwitch?.log.info('Command off called');
122
+ });
123
+ this.mountedDimmerSwitch = new MatterbridgeEndpoint([dimmableMountedSwitch, bridgedNode, powerSource], { uniqueStorageKey: 'DimmerMountedSwitch' }, this.config.debug)
124
+ .createDefaultIdentifyClusterServer()
125
+ .createDefaultGroupsClusterServer()
126
+ .createDefaultBridgedDeviceBasicInformationClusterServer('Dimmer Mounted Switch', '0x22145578864', 0xfff1, 'Matterbridge', 'Matterbridge Dimmer Mounted Switch', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
127
+ .createDefaultOnOffClusterServer()
128
+ .createDefaultLevelControlClusterServer()
129
+ .createDefaultPowerSourceRechargeableBatteryClusterServer(70);
130
+ this.setSelectDevice(this.mountedDimmerSwitch.serialNumber ?? '', this.mountedDimmerSwitch.deviceName ?? '', undefined, 'hub');
131
+ if (this.validateDevice(this.mountedDimmerSwitch.deviceName ?? '')) {
132
+ await this.registerDevice(this.mountedDimmerSwitch);
133
+ this.bridgedDevices.set(this.mountedDimmerSwitch.deviceName ?? '', this.mountedDimmerSwitch);
134
+ }
135
+ else {
136
+ this.mountedDimmerSwitch = undefined;
137
+ }
138
+ this.mountedDimmerSwitch?.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
139
+ this.mountedDimmerSwitch?.log.info(`Command identify called identifyTime:${identifyTime}`);
140
+ });
141
+ this.mountedDimmerSwitch?.addCommandHandler('on', async () => {
142
+ await this.mountedDimmerSwitch?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.mountedDimmerSwitch.log);
143
+ this.mountedDimmerSwitch?.log.info('Command on called');
144
+ });
145
+ this.mountedDimmerSwitch?.addCommandHandler('off', async () => {
146
+ await this.mountedDimmerSwitch?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.mountedDimmerSwitch.log);
147
+ this.mountedDimmerSwitch?.log.info('Command off called');
148
+ });
149
+ this.mountedDimmerSwitch?.addCommandHandler('moveToLevel', async ({ request: { level } }) => {
150
+ await this.mountedDimmerSwitch?.setAttribute(LevelControl.Cluster.id, 'currentLevel', level, this.mountedDimmerSwitch.log);
151
+ this.mountedDimmerSwitch?.log.debug(`Command moveToLevel called request: ${level}`);
152
+ });
153
+ this.mountedDimmerSwitch?.addCommandHandler('moveToLevelWithOnOff', async ({ request: { level } }) => {
154
+ await this.mountedDimmerSwitch?.setAttribute(LevelControl.Cluster.id, 'currentLevel', level, this.mountedDimmerSwitch.log);
155
+ this.mountedDimmerSwitch?.log.debug(`Command moveToLevelWithOnOff called request: ${level}`);
156
+ });
76
157
  this.lightOnOff = new MatterbridgeEndpoint([onOffLight, bridgedNode, powerSource], { uniqueStorageKey: 'Light (on/off)' }, this.config.debug)
77
158
  .createDefaultIdentifyClusterServer()
78
159
  .createDefaultGroupsClusterServer()
79
160
  .createDefaultBridgedDeviceBasicInformationClusterServer('Light (on/off)', '0x2342375564', 0xfff1, 'Matterbridge', 'Matterbridge Light on/off', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
80
161
  .createDefaultOnOffClusterServer()
81
162
  .createDefaultPowerSourceWiredClusterServer();
82
- await this.registerDevice(this.lightOnOff);
83
- this.bridgedDevices.set(this.lightOnOff.deviceName ?? '', this.lightOnOff);
84
- this.lightOnOff.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
163
+ this.setSelectDevice(this.lightOnOff.serialNumber ?? '', this.lightOnOff.deviceName ?? '', undefined, 'hub');
164
+ if (this.validateDevice(this.lightOnOff.deviceName ?? '')) {
165
+ await this.registerDevice(this.lightOnOff);
166
+ this.bridgedDevices.set(this.lightOnOff.deviceName ?? '', this.lightOnOff);
167
+ }
168
+ else {
169
+ this.lightOnOff = undefined;
170
+ }
171
+ this.lightOnOff?.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
85
172
  this.lightOnOff?.log.info(`Command identify called identifyTime:${identifyTime}`);
86
173
  });
87
- this.lightOnOff.addCommandHandler('on', async () => {
174
+ this.lightOnOff?.addCommandHandler('on', async () => {
88
175
  await this.lightOnOff?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.lightOnOff?.log);
89
176
  this.lightOnOff?.log.info('Command on called');
90
177
  });
91
- this.lightOnOff.addCommandHandler('off', async () => {
178
+ this.lightOnOff?.addCommandHandler('off', async () => {
92
179
  await this.lightOnOff?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.lightOnOff?.log);
93
180
  this.lightOnOff?.log.info('Command off called');
94
181
  });
95
- this.dimmer = new MatterbridgeEndpoint([dimmableLight, bridgedNode, powerSource], { uniqueStorageKey: 'Dimmer' }, this.config.debug).createDefaultIdentifyClusterServer();
96
- this.dimmer
182
+ this.dimmer = new MatterbridgeEndpoint([dimmableLight, bridgedNode, powerSource], { uniqueStorageKey: 'Dimmer' }, this.config.debug)
183
+ .createDefaultIdentifyClusterServer()
97
184
  .createDefaultGroupsClusterServer()
98
185
  .createDefaultBridgedDeviceBasicInformationClusterServer('Dimmer', '0x234554564', 0xfff1, 'Matterbridge', 'Matterbridge Dimmer', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
99
186
  .createDefaultOnOffClusterServer()
100
187
  .createDefaultLevelControlClusterServer()
101
- .createDefaultPowerSourceReplaceableBatteryClusterServer(70);
102
- await this.registerDevice(this.dimmer);
103
- this.bridgedDevices.set(this.dimmer.deviceName ?? '', this.dimmer);
104
- this.dimmer.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
188
+ .createDefaultPowerSourceReplaceableBatteryClusterServer(70, PowerSource.BatChargeLevel.Ok, 2990, '2 x AA', 2);
189
+ this.setSelectDevice(this.dimmer.serialNumber ?? '', this.dimmer.deviceName ?? '', undefined, 'hub');
190
+ if (this.validateDevice(this.dimmer.deviceName ?? '')) {
191
+ await this.registerDevice(this.dimmer);
192
+ this.bridgedDevices.set(this.dimmer.deviceName ?? '', this.dimmer);
193
+ }
194
+ else {
195
+ this.dimmer = undefined;
196
+ }
197
+ this.dimmer?.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
105
198
  this.dimmer?.log.info(`Command identify called identifyTime:${identifyTime}`);
106
199
  });
107
- this.dimmer.addCommandHandler('on', async () => {
200
+ this.dimmer?.addCommandHandler('on', async () => {
108
201
  await this.dimmer?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.dimmer.log);
109
202
  this.dimmer?.log.info('Command on called');
110
203
  });
111
- this.dimmer.addCommandHandler('off', async () => {
204
+ this.dimmer?.addCommandHandler('off', async () => {
112
205
  await this.dimmer?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.dimmer.log);
113
206
  this.dimmer?.log.info('Command off called');
114
207
  });
115
- this.dimmer.addCommandHandler('moveToLevel', async ({ request: { level } }) => {
208
+ this.dimmer?.addCommandHandler('moveToLevel', async ({ request: { level } }) => {
116
209
  await this.dimmer?.setAttribute(LevelControl.Cluster.id, 'currentLevel', level, this.dimmer.log);
117
210
  this.dimmer?.log.debug(`Command moveToLevel called request: ${level}`);
118
211
  });
119
- this.dimmer.addCommandHandler('moveToLevelWithOnOff', async ({ request: { level } }) => {
212
+ this.dimmer?.addCommandHandler('moveToLevelWithOnOff', async ({ request: { level } }) => {
120
213
  await this.dimmer?.setAttribute(LevelControl.Cluster.id, 'currentLevel', level, this.dimmer.log);
121
214
  this.dimmer?.log.debug(`Command moveToLevelWithOnOff called request: ${level}`);
122
215
  });
123
- this.light = new MatterbridgeEndpoint([colorTemperatureLight, bridgedNode, powerSource], { uniqueStorageKey: 'Light (XY, HS and CT)' }, this.config.debug).createDefaultIdentifyClusterServer();
124
- this.light
216
+ this.light = new MatterbridgeEndpoint([extendedColorLight, bridgedNode, powerSource], { uniqueStorageKey: 'Light (XY, HS and CT)' }, this.config.debug)
217
+ .createDefaultIdentifyClusterServer()
125
218
  .createDefaultGroupsClusterServer()
126
219
  .createDefaultBridgedDeviceBasicInformationClusterServer('Light (XY, HS and CT)', '0x23480564', 0xfff1, 'Matterbridge', 'Matterbridge Light', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
127
220
  .createDefaultOnOffClusterServer()
128
221
  .createDefaultLevelControlClusterServer()
129
222
  .createDefaultColorControlClusterServer()
130
223
  .createDefaultPowerSourceReplaceableBatteryClusterServer(70);
131
- await this.registerDevice(this.light);
132
- this.bridgedDevices.set(this.light.deviceName ?? '', this.light);
133
- this.light.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
224
+ this.setSelectDevice(this.light.serialNumber ?? '', this.light.deviceName ?? '', undefined, 'hub');
225
+ if (this.validateDevice(this.light.deviceName ?? '')) {
226
+ await this.registerDevice(this.light);
227
+ this.bridgedDevices.set(this.light.deviceName ?? '', this.light);
228
+ }
229
+ else {
230
+ this.light = undefined;
231
+ }
232
+ this.light?.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
134
233
  this.light?.log.info(`Command identify called identifyTime:${identifyTime}`);
135
234
  });
136
- this.light.addCommandHandler('on', async () => {
235
+ this.light?.addCommandHandler('on', async () => {
137
236
  await this.light?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.light?.log);
138
237
  this.light?.log.info('Command on called');
139
238
  });
140
- this.light.addCommandHandler('off', async () => {
239
+ this.light?.addCommandHandler('off', async () => {
141
240
  await this.light?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.light?.log);
142
241
  this.light?.log.info('Command off called');
143
242
  });
144
- this.light.addCommandHandler('moveToLevel', async ({ request: { level } }) => {
243
+ this.light?.addCommandHandler('moveToLevel', async ({ request: { level } }) => {
145
244
  await this.light?.setAttribute(LevelControl.Cluster.id, 'currentLevel', level, this.light?.log);
146
245
  this.light?.log.debug(`Command moveToLevel called request: ${level}`);
147
246
  });
148
- this.light.addCommandHandler('moveToLevelWithOnOff', async ({ request: { level } }) => {
247
+ this.light?.addCommandHandler('moveToLevelWithOnOff', async ({ request: { level } }) => {
149
248
  await this.light?.setAttribute(LevelControl.Cluster.id, 'currentLevel', level, this.light?.log);
150
249
  this.light?.log.debug(`Command moveToLevelWithOnOff called request: ${level}`);
151
250
  });
152
- this.light.addCommandHandler('moveToColor', async ({ request: { colorX, colorY } }) => {
251
+ this.light?.addCommandHandler('moveToColor', async ({ request: { colorX, colorY } }) => {
153
252
  await this.light?.setAttribute(ColorControl.Cluster.id, 'currentX', colorX, this.light?.log);
154
253
  await this.light?.setAttribute(ColorControl.Cluster.id, 'currentY', colorY, this.light?.log);
155
254
  this.light?.log.debug(`Command moveToColor called request: X ${colorX / 65536} Y ${colorY / 65536}`);
156
255
  });
157
- this.light.addCommandHandler('moveToHueAndSaturation', async ({ request: { hue, saturation } }) => {
256
+ this.light?.addCommandHandler('moveToHueAndSaturation', async ({ request: { hue, saturation } }) => {
158
257
  await this.light?.setAttribute(ColorControl.Cluster.id, 'currentHue', hue, this.light?.log);
159
258
  await this.light?.setAttribute(ColorControl.Cluster.id, 'currentSaturation', saturation, this.light?.log);
160
259
  this.light?.log.debug(`Command moveToHueAndSaturation called request: hue ${hue} saturation ${saturation}`);
161
260
  });
162
- this.light.addCommandHandler('moveToHue', async ({ request: { hue } }) => {
261
+ this.light?.addCommandHandler('moveToHue', async ({ request: { hue } }) => {
163
262
  await this.light?.setAttribute(ColorControl.Cluster.id, 'currentHue', hue, this.light?.log);
164
263
  this.light?.log.debug(`Command moveToHue called request: hue ${hue}`);
165
264
  });
166
- this.light.addCommandHandler('moveToSaturation', async ({ request: { saturation } }) => {
265
+ this.light?.addCommandHandler('moveToSaturation', async ({ request: { saturation } }) => {
167
266
  await this.light?.setAttribute(ColorControl.Cluster.id, 'currentSaturation', saturation, this.light?.log);
168
267
  this.light?.log.debug(`Command moveToSaturation called request: saturation ${saturation}}`);
169
268
  });
170
- this.light.addCommandHandler('moveToColorTemperature', async ({ request: { colorTemperatureMireds } }) => {
269
+ this.light?.addCommandHandler('moveToColorTemperature', async ({ request: { colorTemperatureMireds } }) => {
171
270
  await this.light?.setAttribute(ColorControl.Cluster.id, 'colorTemperatureMireds', colorTemperatureMireds, this.light?.log);
172
271
  this.light?.log.debug(`Command moveToColorTemperature called request: ${colorTemperatureMireds}`);
173
272
  });
174
- this.lightHS = new MatterbridgeEndpoint([colorTemperatureLight, bridgedNode, powerSource], { uniqueStorageKey: 'Light (HS, CT)' }, this.config.debug).createDefaultIdentifyClusterServer();
175
- this.lightHS
273
+ this.lightHS = new MatterbridgeEndpoint([colorTemperatureLight, bridgedNode, powerSource], { uniqueStorageKey: 'Light (HS, CT)' }, this.config.debug)
274
+ .createDefaultIdentifyClusterServer()
176
275
  .createDefaultGroupsClusterServer()
177
276
  .createDefaultBridgedDeviceBasicInformationClusterServer('Light (HS, CT)', '0x25097564', 0xfff1, 'Matterbridge', 'Matterbridge Light', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
178
277
  .createDefaultOnOffClusterServer()
179
278
  .createDefaultLevelControlClusterServer()
180
279
  .createHsColorControlClusterServer()
181
280
  .createDefaultPowerSourceWiredClusterServer();
182
- await this.registerDevice(this.lightHS);
183
- this.bridgedDevices.set(this.lightHS.deviceName ?? '', this.lightHS);
184
- this.lightHS.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
281
+ this.setSelectDevice(this.lightHS.serialNumber ?? '', this.lightHS.deviceName ?? '', undefined, 'hub');
282
+ if (this.validateDevice(this.lightHS.deviceName ?? '')) {
283
+ await this.registerDevice(this.lightHS);
284
+ this.bridgedDevices.set(this.lightHS.deviceName ?? '', this.lightHS);
285
+ }
286
+ else {
287
+ this.lightHS = undefined;
288
+ }
289
+ this.lightHS?.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
185
290
  this.lightHS?.log.info(`Command identify called identifyTime:${identifyTime}`);
186
291
  });
187
- this.lightHS.addCommandHandler('on', async () => {
292
+ this.lightHS?.addCommandHandler('on', async () => {
188
293
  await this.lightHS?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.lightHS?.log);
189
294
  this.lightHS?.log.info('Command on called');
190
295
  });
191
- this.lightHS.addCommandHandler('off', async () => {
296
+ this.lightHS?.addCommandHandler('off', async () => {
192
297
  await this.lightHS?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.lightHS?.log);
193
298
  this.lightHS?.log.info('Command off called');
194
299
  });
195
- this.lightHS.addCommandHandler('moveToLevel', async ({ request: { level } }) => {
300
+ this.lightHS?.addCommandHandler('moveToLevel', async ({ request: { level } }) => {
196
301
  await this.lightHS?.setAttribute(LevelControl.Cluster.id, 'currentLevel', level, this.lightHS?.log);
197
302
  this.lightHS?.log.debug(`Command moveToLevel called request: ${level}`);
198
303
  });
199
- this.lightHS.addCommandHandler('moveToLevelWithOnOff', async ({ request: { level } }) => {
304
+ this.lightHS?.addCommandHandler('moveToLevelWithOnOff', async ({ request: { level } }) => {
200
305
  await this.lightHS?.setAttribute(LevelControl.Cluster.id, 'currentLevel', level, this.lightHS?.log);
201
306
  this.lightHS?.log.debug(`Command moveToLevelWithOnOff called request: ${level}`);
202
307
  });
203
- this.lightHS.addCommandHandler('moveToHueAndSaturation', async ({ request: { hue, saturation } }) => {
308
+ this.lightHS?.addCommandHandler('moveToHueAndSaturation', async ({ request: { hue, saturation } }) => {
204
309
  await this.lightHS?.setAttribute(ColorControl.Cluster.id, 'currentHue', hue, this.lightHS?.log);
205
310
  await this.lightHS?.setAttribute(ColorControl.Cluster.id, 'currentSaturation', saturation, this.lightHS?.log);
206
311
  this.lightHS?.log.debug(`Command moveToHueAndSaturation called request: hue ${hue} saturation ${saturation}}`);
207
312
  });
208
- this.lightHS.addCommandHandler('moveToHue', async ({ request: { hue } }) => {
313
+ this.lightHS?.addCommandHandler('moveToHue', async ({ request: { hue } }) => {
209
314
  await this.lightHS?.setAttribute(ColorControl.Cluster.id, 'currentHue', hue, this.lightHS?.log);
210
315
  this.lightHS?.log.debug(`Command moveToHue called request: hue ${hue}`);
211
316
  });
212
- this.lightHS.addCommandHandler('moveToSaturation', async ({ request: { saturation } }) => {
317
+ this.lightHS?.addCommandHandler('moveToSaturation', async ({ request: { saturation } }) => {
213
318
  await this.lightHS?.setAttribute(ColorControl.Cluster.id, 'currentSaturation', saturation, this.lightHS?.log);
214
319
  this.lightHS?.log.debug(`Command moveToSaturation called request: saturation ${saturation}`);
215
320
  });
216
- this.lightHS.addCommandHandler('moveToColorTemperature', async ({ request: colorTemperatureMireds }) => {
321
+ this.lightHS?.addCommandHandler('moveToColorTemperature', async ({ request: { colorTemperatureMireds } }) => {
322
+ await this.lightHS?.setAttribute(ColorControl.Cluster.id, 'colorTemperatureMireds', colorTemperatureMireds, this.lightHS?.log);
217
323
  this.lightHS?.log.debug(`Command moveToColorTemperature called request: ${colorTemperatureMireds}`);
218
324
  });
219
- this.lightXY = new MatterbridgeEndpoint([colorTemperatureLight, bridgedNode, powerSource], { uniqueStorageKey: 'Light (XY, CT)' }, this.config.debug).createDefaultIdentifyClusterServer();
220
- this.lightXY
325
+ this.lightXY = new MatterbridgeEndpoint([extendedColorLight, bridgedNode, powerSource], { uniqueStorageKey: 'Light (XY, CT)' }, this.config.debug)
326
+ .createDefaultIdentifyClusterServer()
221
327
  .createDefaultGroupsClusterServer()
222
328
  .createDefaultBridgedDeviceBasicInformationClusterServer('Light (XY, CT)', '0x23497564', 0xfff1, 'Matterbridge', 'Matterbridge Light', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
223
329
  .createDefaultOnOffClusterServer()
224
330
  .createDefaultLevelControlClusterServer()
225
331
  .createXyColorControlClusterServer()
226
332
  .createDefaultPowerSourceWiredClusterServer();
227
- await this.registerDevice(this.lightXY);
228
- this.bridgedDevices.set(this.lightXY.deviceName ?? '', this.lightXY);
229
- this.lightXY.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
333
+ this.setSelectDevice(this.lightXY.serialNumber ?? '', this.lightXY.deviceName ?? '', undefined, 'hub');
334
+ if (this.validateDevice(this.lightXY.deviceName ?? '')) {
335
+ await this.registerDevice(this.lightXY);
336
+ this.bridgedDevices.set(this.lightXY.deviceName ?? '', this.lightXY);
337
+ }
338
+ else {
339
+ this.lightXY = undefined;
340
+ }
341
+ this.lightXY?.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
230
342
  this.lightXY?.log.info(`Command identify called identifyTime:${identifyTime}`);
231
343
  });
232
- this.lightXY.addCommandHandler('on', async () => {
344
+ this.lightXY?.addCommandHandler('on', async () => {
233
345
  await this.lightXY?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.lightXY?.log);
234
346
  this.lightXY?.log.info('Command on called');
235
347
  });
236
- this.lightXY.addCommandHandler('off', async () => {
348
+ this.lightXY?.addCommandHandler('off', async () => {
237
349
  await this.lightXY?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.lightXY?.log);
238
350
  this.lightXY?.log.info('Command off called');
239
351
  });
240
- this.lightXY.addCommandHandler('moveToLevel', async ({ request: { level } }) => {
352
+ this.lightXY?.addCommandHandler('moveToLevel', async ({ request: { level } }) => {
241
353
  await this.lightXY?.setAttribute(LevelControl.Cluster.id, 'currentLevel', level, this.lightXY?.log);
242
354
  this.lightXY?.log.debug(`Command moveToLevel called request: ${level}`);
243
355
  });
244
- this.lightXY.addCommandHandler('moveToLevelWithOnOff', async ({ request: { level } }) => {
356
+ this.lightXY?.addCommandHandler('moveToLevelWithOnOff', async ({ request: { level } }) => {
245
357
  await this.lightXY?.setAttribute(LevelControl.Cluster.id, 'currentLevel', level, this.lightXY?.log);
246
358
  this.lightXY?.log.debug(`Command moveToLevelWithOnOff called request: ${level}`);
247
359
  });
248
- this.lightXY.addCommandHandler('moveToColor', async ({ request: { colorX, colorY } }) => {
360
+ this.lightXY?.addCommandHandler('moveToColor', async ({ request: { colorX, colorY } }) => {
249
361
  await this.lightXY?.setAttribute(ColorControl.Cluster.id, 'currentX', colorX, this.lightXY?.log);
250
362
  await this.lightXY?.setAttribute(ColorControl.Cluster.id, 'currentY', colorY, this.lightXY?.log);
251
363
  this.lightXY?.log.debug(`Command moveToColor called request: X ${colorX / 65536} Y ${colorY / 65536}`);
252
364
  });
253
- this.lightXY.addCommandHandler('moveToColorTemperature', async ({ request: { colorTemperatureMireds } }) => {
365
+ this.lightXY?.addCommandHandler('moveToColorTemperature', async ({ request: { colorTemperatureMireds } }) => {
254
366
  await this.lightXY?.setAttribute(ColorControl.Cluster.id, 'colorTemperatureMireds', colorTemperatureMireds, this.lightXY?.log);
255
367
  this.lightXY?.log.debug(`Command moveToColorTemperature called request: ${colorTemperatureMireds}`);
256
368
  });
257
- this.lightCT = new MatterbridgeEndpoint([colorTemperatureLight, bridgedNode, powerSource], { uniqueStorageKey: 'Light (CT)' }, this.config.debug).createDefaultIdentifyClusterServer();
258
- this.lightCT
369
+ this.lightCT = new MatterbridgeEndpoint([colorTemperatureLight, bridgedNode, powerSource], { uniqueStorageKey: 'Light (CT)' }, this.config.debug)
370
+ .createDefaultIdentifyClusterServer()
259
371
  .createDefaultGroupsClusterServer()
260
372
  .createDefaultBridgedDeviceBasicInformationClusterServer('Light (CT)', '0x23480749', 0xfff1, 'Matterbridge', 'Matterbridge Light', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
261
373
  .createDefaultOnOffClusterServer()
262
374
  .createDefaultLevelControlClusterServer()
263
375
  .createCtColorControlClusterServer()
264
376
  .createDefaultPowerSourceReplaceableBatteryClusterServer(70);
265
- await this.registerDevice(this.lightCT);
266
- this.bridgedDevices.set(this.lightCT.deviceName ?? '', this.lightCT);
267
- this.lightCT.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
377
+ this.setSelectDevice(this.lightCT.serialNumber ?? '', this.lightCT.deviceName ?? '', undefined, 'hub');
378
+ if (this.validateDevice(this.lightCT.deviceName ?? '')) {
379
+ await this.registerDevice(this.lightCT);
380
+ this.bridgedDevices.set(this.lightCT.deviceName ?? '', this.lightCT);
381
+ }
382
+ else {
383
+ this.lightCT = undefined;
384
+ }
385
+ this.lightCT?.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
268
386
  this.lightCT?.log.info(`Command identify called identifyTime:${identifyTime}`);
269
387
  });
270
- this.lightCT.addCommandHandler('on', async () => {
388
+ this.lightCT?.addCommandHandler('on', async () => {
271
389
  await this.lightCT?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.lightCT?.log);
272
390
  this.lightCT?.log.info('Command on called');
273
391
  });
274
- this.lightCT.addCommandHandler('off', async () => {
392
+ this.lightCT?.addCommandHandler('off', async () => {
275
393
  await this.lightCT?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.lightCT?.log);
276
394
  this.lightCT?.log.info('Command off called');
277
395
  });
278
- this.lightCT.addCommandHandler('moveToLevel', async ({ request: { level } }) => {
396
+ this.lightCT?.addCommandHandler('moveToLevel', async ({ request: { level } }) => {
279
397
  await this.lightCT?.setAttribute(LevelControl.Cluster.id, 'currentLevel', level, this.lightCT?.log);
280
398
  this.lightCT?.log.debug(`Command moveToLevel called request: ${level}`);
281
399
  });
282
- this.lightCT.addCommandHandler('moveToLevelWithOnOff', async ({ request: { level } }) => {
400
+ this.lightCT?.addCommandHandler('moveToLevelWithOnOff', async ({ request: { level } }) => {
283
401
  await this.lightCT?.setAttribute(LevelControl.Cluster.id, 'currentLevel', level, this.lightCT?.log);
284
402
  this.lightCT?.log.debug(`Command moveToLevelWithOnOff called request: ${level}`);
285
403
  });
286
- this.lightCT.addCommandHandler('moveToColorTemperature', async ({ request: { colorTemperatureMireds } }) => {
404
+ this.lightCT?.addCommandHandler('moveToColorTemperature', async ({ request: { colorTemperatureMireds } }) => {
287
405
  await this.lightCT?.setAttribute(ColorControl.Cluster.id, 'colorTemperatureMireds', colorTemperatureMireds, this.lightCT?.log);
288
406
  this.lightCT?.log.debug(`Command moveToColorTemperature called request: ${colorTemperatureMireds}`);
289
407
  });
290
- this.outlet = new MatterbridgeEndpoint([onOffOutlet, bridgedNode, powerSource], { uniqueStorageKey: 'Outlet' }, this.config.debug).createDefaultIdentifyClusterServer();
291
- this.outlet
408
+ this.outlet = new MatterbridgeEndpoint([onOffOutlet, bridgedNode, powerSource], { uniqueStorageKey: 'Outlet' }, this.config.debug)
409
+ .createDefaultIdentifyClusterServer()
292
410
  .createDefaultGroupsClusterServer()
293
411
  .createDefaultBridgedDeviceBasicInformationClusterServer('Outlet', '0x29252164', 0xfff1, 'Matterbridge', 'Matterbridge Outlet', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
294
412
  .createDefaultOnOffClusterServer()
295
413
  .createDefaultPowerSourceWiredClusterServer();
296
- await this.registerDevice(this.outlet);
297
- this.bridgedDevices.set(this.outlet.deviceName ?? '', this.outlet);
298
- this.outlet.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
414
+ this.setSelectDevice(this.outlet.serialNumber ?? '', this.outlet.deviceName ?? '', undefined, 'hub');
415
+ if (this.validateDevice(this.outlet.deviceName ?? '')) {
416
+ await this.registerDevice(this.outlet);
417
+ this.bridgedDevices.set(this.outlet.deviceName ?? '', this.outlet);
418
+ }
419
+ else {
420
+ this.outlet = undefined;
421
+ }
422
+ this.outlet?.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
299
423
  this.outlet?.log.info(`Command identify called identifyTime:${identifyTime}`);
300
424
  });
301
- this.outlet.addCommandHandler('on', async () => {
425
+ this.outlet?.addCommandHandler('on', async () => {
302
426
  await this.outlet?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.outlet?.log);
303
427
  this.outlet?.log.info('Command on called');
304
428
  });
305
- this.outlet.addCommandHandler('off', async () => {
429
+ this.outlet?.addCommandHandler('off', async () => {
306
430
  await this.outlet?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.outlet?.log);
307
431
  this.outlet?.log.info('Command off called');
308
432
  });
309
- this.cover = new MatterbridgeEndpoint([coverDevice, bridgedNode, powerSource], { uniqueStorageKey: 'Cover' }, this.config.debug);
310
- this.cover.log.logName = 'Cover';
311
- this.cover.createDefaultIdentifyClusterServer();
312
- this.cover.createDefaultGroupsClusterServer();
313
- this.cover.createDefaultBridgedDeviceBasicInformationClusterServer('Cover', '0x01020564', 0xfff1, 'Matterbridge', 'Matterbridge Cover', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion);
314
- this.cover.createDefaultWindowCoveringClusterServer();
315
- this.cover.createDefaultPowerSourceRechargeableBatteryClusterServer(86);
316
- await this.registerDevice(this.cover);
317
- this.bridgedDevices.set(this.cover.deviceName ?? '', this.cover);
318
- this.cover.subscribeAttribute(WindowCovering.Cluster.id, 'mode', (newValue, oldValue) => {
433
+ this.cover = new MatterbridgeEndpoint([coverDevice, bridgedNode, powerSource], { uniqueStorageKey: 'Cover' }, this.config.debug)
434
+ .createDefaultIdentifyClusterServer()
435
+ .createDefaultGroupsClusterServer()
436
+ .createDefaultBridgedDeviceBasicInformationClusterServer('Cover', '0x01020564', 0xfff1, 'Matterbridge', 'Matterbridge Cover', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
437
+ .createDefaultWindowCoveringClusterServer()
438
+ .createDefaultPowerSourceRechargeableBatteryClusterServer(86);
439
+ this.setSelectDevice(this.cover.serialNumber ?? '', this.cover.deviceName ?? '', undefined, 'hub');
440
+ if (this.validateDevice(this.cover.deviceName ?? '')) {
441
+ await this.registerDevice(this.cover);
442
+ this.bridgedDevices.set(this.cover.deviceName ?? '', this.cover);
443
+ }
444
+ else {
445
+ this.cover = undefined;
446
+ }
447
+ this.cover?.subscribeAttribute(WindowCovering.Cluster.id, 'mode', (newValue, oldValue) => {
319
448
  this.cover?.log.info(`Attribute mode changed from ${oldValue} to ${newValue}. Reverse: ${newValue.motorDirectionReversed}. Calibration: ${newValue.calibrationMode}. Maintenance: ${newValue.maintenanceMode}. LED: ${newValue.ledFeedback}`);
320
449
  }, this.cover.log);
321
- this.cover.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
450
+ this.cover?.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
322
451
  this.cover?.log.info(`Command identify called identifyTime:${identifyTime}`);
323
452
  });
324
- this.cover.addCommandHandler('stopMotion', async () => {
453
+ this.cover?.addCommandHandler('stopMotion', async () => {
325
454
  await this.cover?.setWindowCoveringTargetAsCurrentAndStopped();
326
455
  this.cover?.log.info(`Command stopMotion called`);
327
456
  });
328
- this.cover.addCommandHandler('downOrClose', async () => {
457
+ this.cover?.addCommandHandler('downOrClose', async () => {
329
458
  await this.cover?.setWindowCoveringCurrentTargetStatus(10000, 10000, WindowCovering.MovementStatus.Stopped);
330
459
  this.cover?.log.info(`Command downOrClose called`);
331
460
  });
332
- this.cover.addCommandHandler('upOrOpen', async () => {
461
+ this.cover?.addCommandHandler('upOrOpen', async () => {
333
462
  await this.cover?.setWindowCoveringCurrentTargetStatus(0, 0, WindowCovering.MovementStatus.Stopped);
334
463
  this.cover?.log.info(`Command upOrOpen called`);
335
464
  });
336
- this.cover.addCommandHandler('goToLiftPercentage', async ({ request: { liftPercent100thsValue } }) => {
465
+ this.cover?.addCommandHandler('goToLiftPercentage', async ({ request: { liftPercent100thsValue } }) => {
337
466
  await this.cover?.setWindowCoveringCurrentTargetStatus(liftPercent100thsValue, liftPercent100thsValue, WindowCovering.MovementStatus.Stopped);
338
467
  this.cover?.log.info(`Command goToLiftPercentage ${liftPercent100thsValue} called`);
339
468
  });
340
- this.lock = new MatterbridgeEndpoint([doorLockDevice, bridgedNode, powerSource], { uniqueStorageKey: 'Lock' }, this.config.debug).createDefaultIdentifyClusterServer();
341
- this.lock
469
+ this.lock = new MatterbridgeEndpoint([doorLockDevice, bridgedNode, powerSource], { uniqueStorageKey: 'Lock' }, this.config.debug)
470
+ .createDefaultIdentifyClusterServer()
342
471
  .createDefaultBridgedDeviceBasicInformationClusterServer('Lock', '0x96352164', 0xfff1, 'Matterbridge', 'Matterbridge Lock', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
343
472
  .createDefaultDoorLockClusterServer()
344
473
  .createDefaultPowerSourceRechargeableBatteryClusterServer(30);
345
- await this.registerDevice(this.lock);
346
- this.bridgedDevices.set(this.lock.deviceName ?? '', this.lock);
347
- this.lock.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
474
+ this.setSelectDevice(this.lock.serialNumber ?? '', this.lock.deviceName ?? '', undefined, 'hub');
475
+ if (this.validateDevice(this.lock.deviceName ?? '')) {
476
+ await this.registerDevice(this.lock);
477
+ this.bridgedDevices.set(this.lock.deviceName ?? '', this.lock);
478
+ }
479
+ else {
480
+ this.lock = undefined;
481
+ }
482
+ this.lock?.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
348
483
  this.lock?.log.info(`Command identify called identifyTime:${identifyTime}`);
349
484
  });
350
- this.lock.addCommandHandler('lockDoor', async () => {
485
+ this.lock?.addCommandHandler('lockDoor', async () => {
351
486
  await this.lock?.setAttribute(DoorLock.Cluster.id, 'lockState', DoorLock.LockState.Locked, this.lock?.log);
352
487
  this.lock?.log.info('Command lockDoor called');
353
488
  });
354
- this.lock.addCommandHandler('unlockDoor', async () => {
489
+ this.lock?.addCommandHandler('unlockDoor', async () => {
355
490
  await this.lock?.setAttribute(DoorLock.Cluster.id, 'lockState', DoorLock.LockState.Unlocked, this.lock?.log);
356
491
  this.lock?.log.info('Command unlockDoor called');
357
492
  });
358
- this.thermoAuto = new MatterbridgeEndpoint([thermostatDevice, bridgedNode, powerSource], { uniqueStorageKey: 'Thermostat (AutoMode)' }, this.config.debug).createDefaultIdentifyClusterServer();
359
- this.thermoAuto
493
+ this.thermoAuto = new MatterbridgeEndpoint([thermostatDevice, bridgedNode, powerSource], { uniqueStorageKey: 'Thermostat (AutoMode)' }, this.config.debug)
494
+ .createDefaultIdentifyClusterServer()
360
495
  .createDefaultGroupsClusterServer()
361
496
  .createDefaultBridgedDeviceBasicInformationClusterServer('Thermostat (AutoMode)', '0x96382164A', 0xfff1, 'Matterbridge', 'Matterbridge Thermostat', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
362
497
  .createDefaultThermostatClusterServer(20, 18, 22)
@@ -373,15 +508,21 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
373
508
  .addChildDeviceType('Humidity', humiditySensor)
374
509
  .createDefaultRelativeHumidityMeasurementClusterServer(50 * 100)
375
510
  .addRequiredClusterServers();
376
- await this.registerDevice(this.thermoAuto);
377
- this.bridgedDevices.set(this.thermoAuto.deviceName ?? '', this.thermoAuto);
378
- this.thermoAuto.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
511
+ this.setSelectDevice(this.thermoAuto.serialNumber ?? '', this.thermoAuto.deviceName ?? '', undefined, 'hub');
512
+ if (this.validateDevice(this.thermoAuto.deviceName ?? '')) {
513
+ await this.registerDevice(this.thermoAuto);
514
+ this.bridgedDevices.set(this.thermoAuto.deviceName ?? '', this.thermoAuto);
515
+ }
516
+ else {
517
+ this.thermoAuto = undefined;
518
+ }
519
+ this.thermoAuto?.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
379
520
  this.thermoAuto?.log.info(`Command identify called identifyTime ${identifyTime}`);
380
521
  });
381
- this.thermoAuto.addCommandHandler('triggerEffect', async ({ request: { effectIdentifier, effectVariant } }) => {
522
+ this.thermoAuto?.addCommandHandler('triggerEffect', async ({ request: { effectIdentifier, effectVariant } }) => {
382
523
  this.thermoAuto?.log.info(`Command identify called effectIdentifier ${effectIdentifier} effectVariant ${effectVariant}`);
383
524
  });
384
- this.thermoAuto.addCommandHandler('setpointRaiseLower', async ({ request: { mode, amount } }) => {
525
+ this.thermoAuto?.addCommandHandler('setpointRaiseLower', async ({ request: { mode, amount } }) => {
385
526
  const lookupSetpointAdjustMode = ['Heat', 'Cool', 'Both'];
386
527
  this.thermoAuto?.log.info(`Command setpointRaiseLower called with mode: ${lookupSetpointAdjustMode[mode]} amount: ${amount / 10}`);
387
528
  if (mode === Thermostat.SetpointRaiseLowerMode.Heat || mode === Thermostat.SetpointRaiseLowerMode.Both) {
@@ -395,18 +536,18 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
395
536
  this.thermoAuto?.log.info('Set occupiedCoolingSetpoint:', setpoint);
396
537
  }
397
538
  });
398
- this.thermoAuto.subscribeAttribute(ThermostatCluster.id, 'systemMode', async (value) => {
539
+ this.thermoAuto?.subscribeAttribute(ThermostatCluster.id, 'systemMode', async (value) => {
399
540
  const lookupSystemMode = ['Off', 'Auto', '', 'Cool', 'Heat', 'EmergencyHeat', 'Precooling', 'FanOnly', 'Dry', 'Sleep'];
400
541
  this.thermoAuto?.log.info('Subscribe systemMode called with:', lookupSystemMode[value]);
401
542
  }, this.thermoAuto.log);
402
- this.thermoAuto.subscribeAttribute(ThermostatCluster.id, 'occupiedHeatingSetpoint', async (value) => {
543
+ this.thermoAuto?.subscribeAttribute(ThermostatCluster.id, 'occupiedHeatingSetpoint', async (value) => {
403
544
  this.thermoAuto?.log.info('Subscribe occupiedHeatingSetpoint called with:', value / 100);
404
545
  }, this.thermoAuto.log);
405
- this.thermoAuto.subscribeAttribute(ThermostatCluster.id, 'occupiedCoolingSetpoint', async (value) => {
546
+ this.thermoAuto?.subscribeAttribute(ThermostatCluster.id, 'occupiedCoolingSetpoint', async (value) => {
406
547
  this.thermoAuto?.log.info('Subscribe occupiedCoolingSetpoint called with:', value / 100);
407
548
  }, this.thermoAuto.log);
408
- this.thermoHeat = new MatterbridgeEndpoint([thermostatDevice, bridgedNode, powerSource], { uniqueStorageKey: 'Thermostat (Heat)' }, this.config.debug).createDefaultIdentifyClusterServer();
409
- this.thermoHeat
549
+ this.thermoHeat = new MatterbridgeEndpoint([thermostatDevice, bridgedNode, powerSource], { uniqueStorageKey: 'Thermostat (Heat)' }, this.config.debug)
550
+ .createDefaultIdentifyClusterServer()
410
551
  .createDefaultGroupsClusterServer()
411
552
  .createDefaultBridgedDeviceBasicInformationClusterServer('Thermostat (Heat)', '0x96382164H', 0xfff1, 'Matterbridge', 'Matterbridge Thermostat', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
412
553
  .createDefaultHeatingThermostatClusterServer(20, 18, 5, 35)
@@ -423,19 +564,25 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
423
564
  })
424
565
  .createDefaultIdentifyClusterServer()
425
566
  .createDefaultTemperatureMeasurementClusterServer(15 * 100);
426
- await this.registerDevice(this.thermoHeat);
427
- this.bridgedDevices.set(this.thermoHeat.deviceName ?? '', this.thermoHeat);
428
- this.thermoHeat.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
567
+ this.setSelectDevice(this.thermoHeat.serialNumber ?? '', this.thermoHeat.deviceName ?? '', undefined, 'hub');
568
+ if (this.validateDevice(this.thermoHeat.deviceName ?? '')) {
569
+ await this.registerDevice(this.thermoHeat);
570
+ this.bridgedDevices.set(this.thermoHeat.deviceName ?? '', this.thermoHeat);
571
+ }
572
+ else {
573
+ this.thermoHeat = undefined;
574
+ }
575
+ this.thermoHeat?.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
429
576
  this.thermoHeat?.log.info(`Command identify called identifyTime ${identifyTime}`);
430
577
  });
431
- this.thermoHeat.addCommandHandler('triggerEffect', async ({ request: { effectIdentifier, effectVariant } }) => {
578
+ this.thermoHeat?.addCommandHandler('triggerEffect', async ({ request: { effectIdentifier, effectVariant } }) => {
432
579
  this.thermoHeat?.log.info(`Command identify called effectIdentifier ${effectIdentifier} effectVariant ${effectVariant}`);
433
580
  });
434
- this.thermoHeat.subscribeAttribute(ThermostatCluster.id, 'systemMode', async (value) => {
581
+ this.thermoHeat?.subscribeAttribute(ThermostatCluster.id, 'systemMode', async (value) => {
435
582
  const lookupSystemMode = ['Off', 'Auto', '', 'Cool', 'Heat', 'EmergencyHeat', 'Precooling', 'FanOnly', 'Dry', 'Sleep'];
436
583
  this.thermoHeat?.log.info('Subscribe systemMode called with:', lookupSystemMode[value]);
437
584
  }, this.thermoHeat.log);
438
- this.thermoHeat.subscribeAttribute(ThermostatCluster.id, 'occupiedHeatingSetpoint', async (value) => {
585
+ this.thermoHeat?.subscribeAttribute(ThermostatCluster.id, 'occupiedHeatingSetpoint', async (value) => {
439
586
  this.thermoHeat?.log.info('Subscribe occupiedHeatingSetpoint called with:', value / 100);
440
587
  }, this.thermoHeat.log);
441
588
  this.thermoCool = new MatterbridgeEndpoint([thermostatDevice, bridgedNode, powerSource], { uniqueStorageKey: 'Thermostat (Cool)' }, this.config.debug)
@@ -444,36 +591,48 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
444
591
  .createDefaultBridgedDeviceBasicInformationClusterServer('Thermostat (Cool)', '0x96382164C', 0xfff1, 'Matterbridge', 'Matterbridge Thermostat', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
445
592
  .createDefaultCoolingThermostatClusterServer(20, 18, 5, 35)
446
593
  .createDefaultPowerSourceReplaceableBatteryClusterServer(40, PowerSource.BatChargeLevel.Ok, 5080, 'AA 1.5V', 4);
447
- await this.registerDevice(this.thermoCool);
448
- this.bridgedDevices.set(this.thermoCool.deviceName ?? '', this.thermoCool);
449
- this.thermoCool.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
594
+ this.setSelectDevice(this.thermoCool.serialNumber ?? '', this.thermoCool.deviceName ?? '', undefined, 'hub');
595
+ if (this.validateDevice(this.thermoCool.deviceName ?? '')) {
596
+ await this.registerDevice(this.thermoCool);
597
+ this.bridgedDevices.set(this.thermoCool.deviceName ?? '', this.thermoCool);
598
+ }
599
+ else {
600
+ this.thermoCool = undefined;
601
+ }
602
+ this.thermoCool?.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
450
603
  this.thermoCool?.log.info(`Command identify called identifyTime ${identifyTime}`);
451
604
  });
452
- this.thermoCool.addCommandHandler('triggerEffect', async ({ request: { effectIdentifier, effectVariant } }) => {
605
+ this.thermoCool?.addCommandHandler('triggerEffect', async ({ request: { effectIdentifier, effectVariant } }) => {
453
606
  this.thermoCool?.log.info(`Command identify called effectIdentifier ${effectIdentifier} effectVariant ${effectVariant}`);
454
607
  });
455
- this.thermoCool.subscribeAttribute(ThermostatCluster.id, 'systemMode', async (value) => {
608
+ this.thermoCool?.subscribeAttribute(ThermostatCluster.id, 'systemMode', async (value) => {
456
609
  const lookupSystemMode = ['Off', 'Auto', '', 'Cool', 'Heat', 'EmergencyHeat', 'Precooling', 'FanOnly', 'Dry', 'Sleep'];
457
610
  this.thermoCool?.log.info('Subscribe systemMode called with:', lookupSystemMode[value]);
458
611
  }, this.thermoCool.log);
459
- this.thermoCool.subscribeAttribute(ThermostatCluster.id, 'occupiedCoolingSetpoint', async (value) => {
612
+ this.thermoCool?.subscribeAttribute(ThermostatCluster.id, 'occupiedCoolingSetpoint', async (value) => {
460
613
  this.thermoCool?.log.info('Subscribe occupiedCoolingSetpoint called with:', value / 100);
461
614
  }, this.thermoCool.log);
462
- this.airPurifier = new MatterbridgeEndpoint([airPurifier, temperatureSensor, humiditySensor, bridgedNode, powerSource], { uniqueStorageKey: 'Air purifier' }, this.config.debug);
463
- this.airPurifier.log.logName = 'Air purifier';
464
- this.airPurifier
615
+ this.airPurifier = new MatterbridgeEndpoint([airPurifier, temperatureSensor, humiditySensor, bridgedNode, powerSource], { uniqueStorageKey: 'Air purifier' }, this.config.debug)
465
616
  .createDefaultBridgedDeviceBasicInformationClusterServer('Air purifier', '0x96584864AP', 0xfff1, 'Matterbridge', 'Matterbridge Air purifier', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
466
617
  .createDefaultIdentifyClusterServer()
467
618
  .createDefaultFanControlClusterServer()
468
619
  .createDefaultTemperatureMeasurementClusterServer(20 * 100)
469
620
  .createDefaultRelativeHumidityMeasurementClusterServer(50 * 100)
470
- .createDefaultPowerSourceWiredClusterServer();
471
- await this.registerDevice(this.airPurifier);
472
- this.bridgedDevices.set(this.airPurifier.deviceName ?? '', this.airPurifier);
473
- this.airPurifier.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
621
+ .createDefaultPowerSourceWiredClusterServer()
622
+ .createDefaultActivatedCarbonFilterMonitoringClusterServer()
623
+ .createDefaultHepaFilterMonitoringClusterServer();
624
+ this.setSelectDevice(this.airPurifier.serialNumber ?? '', this.airPurifier.deviceName ?? '', undefined, 'hub');
625
+ if (this.validateDevice(this.airPurifier.deviceName ?? '')) {
626
+ await this.registerDevice(this.airPurifier);
627
+ this.bridgedDevices.set(this.airPurifier.deviceName ?? '', this.airPurifier);
628
+ }
629
+ else {
630
+ this.airPurifier = undefined;
631
+ }
632
+ this.airPurifier?.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
474
633
  this.airPurifier?.log.info(`Command identify called identifyTime:${identifyTime}`);
475
634
  });
476
- this.airPurifier.subscribeAttribute(FanControl.Cluster.id, 'fanMode', async (newValue, oldValue) => {
635
+ this.airPurifier?.subscribeAttribute(FanControl.Cluster.id, 'fanMode', async (newValue, oldValue) => {
477
636
  this.fan?.log.info(`Fan mode changed from ${this.fanModeLookup[oldValue]} to ${this.fanModeLookup[newValue]}`);
478
637
  if (newValue === FanControl.FanMode.Off) {
479
638
  await this.airPurifier?.setAttribute(FanControl.Cluster.id, 'percentCurrent', 0, this.airPurifier?.log);
@@ -494,39 +653,43 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
494
653
  await this.airPurifier?.setAttribute(FanControl.Cluster.id, 'percentCurrent', 50, this.airPurifier?.log);
495
654
  }
496
655
  }, this.airPurifier.log);
497
- this.airPurifier.subscribeAttribute(FanControl.Cluster.id, 'percentSetting', async (newValue, oldValue) => {
656
+ this.airPurifier?.subscribeAttribute(FanControl.Cluster.id, 'percentSetting', async (newValue, oldValue) => {
498
657
  this.fan?.log.info(`Percent setting changed from ${oldValue} to ${newValue}`);
499
658
  if (isValidNumber(newValue, 0, 100))
500
659
  await this.airPurifier?.setAttribute(FanControl.Cluster.id, 'percentCurrent', newValue, this.airPurifier?.log);
501
660
  }, this.airPurifier.log);
502
- this.airConditioner = new MatterbridgeEndpoint([airConditioner, bridgedNode, powerSource], { uniqueStorageKey: 'Air conditioner' }, this.config.debug)
503
- .createDefaultBridgedDeviceBasicInformationClusterServer('Air conditioner', '0x96382864AC', 0xfff1, 'Matterbridge', 'Matterbridge Air conditioner', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
661
+ this.airConditioner = new MatterbridgeEndpoint([airConditioner, bridgedNode, powerSource], { uniqueStorageKey: 'Air Conditioner' }, this.config.debug)
662
+ .createDefaultBridgedDeviceBasicInformationClusterServer('Air Conditioner', '0x96382864AC', 0xfff1, 'Matterbridge', 'Matterbridge Air Conditioner', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
504
663
  .createDefaultIdentifyClusterServer()
505
664
  .createDeadFrontOnOffClusterServer(true)
506
665
  .createDefaultThermostatClusterServer(20, 18, 22)
666
+ .createDefaultThermostatUserInterfaceConfigurationClusterServer()
507
667
  .createDefaultFanControlClusterServer(FanControl.FanMode.Auto)
508
668
  .createDefaultTemperatureMeasurementClusterServer(20 * 100)
509
669
  .createDefaultRelativeHumidityMeasurementClusterServer(50 * 100)
510
670
  .createDefaultPowerSourceWiredClusterServer()
511
671
  .addRequiredClusterServers();
512
- await this.registerDevice(this.airConditioner);
513
- this.bridgedDevices.set(this.airConditioner.deviceName ?? '', this.airConditioner);
514
- this.airConditioner.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
672
+ this.setSelectDevice(this.airConditioner.serialNumber ?? '', this.airConditioner.deviceName ?? '', undefined, 'hub');
673
+ if (this.validateDevice(this.airConditioner.deviceName ?? '')) {
674
+ await this.registerDevice(this.airConditioner);
675
+ this.bridgedDevices.set(this.airConditioner.deviceName ?? '', this.airConditioner);
676
+ }
677
+ else {
678
+ this.airConditioner = undefined;
679
+ }
680
+ this.airConditioner?.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
515
681
  this.airConditioner?.log.info(`Command identify called identifyTime:${identifyTime}`);
516
682
  });
517
- this.airConditioner.addCommandHandler('on', async () => {
683
+ this.airConditioner?.addCommandHandler('on', async () => {
518
684
  this.airConditioner?.log.info('Command on called');
519
- await this.airConditioner?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.airConditioner?.log);
520
- await this.airConditioner?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.airConditioner?.log);
521
685
  await this.airConditioner?.setAttribute(ThermostatCluster.id, 'localTemperature', 20 * 100, this.airConditioner?.log);
522
686
  await this.airConditioner?.setAttribute(TemperatureMeasurement.Cluster.id, 'measuredValue', 20 * 100, this.airConditioner?.log);
523
687
  await this.airConditioner?.setAttribute(RelativeHumidityMeasurementCluster.id, 'measuredValue', 50 * 100, this.airConditioner?.log);
524
688
  await this.airConditioner?.setAttribute(FanControl.Cluster.id, 'speedSetting', 50, this.airConditioner?.log);
525
689
  await this.airConditioner?.setAttribute(FanControl.Cluster.id, 'percentSetting', 50, this.airConditioner?.log);
526
690
  });
527
- this.airConditioner.addCommandHandler('off', async () => {
691
+ this.airConditioner?.addCommandHandler('off', async () => {
528
692
  this.airConditioner?.log.info('Command off called');
529
- await this.airConditioner?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.airConditioner?.log);
530
693
  await this.airConditioner?.setAttribute(ThermostatCluster.id, 'localTemperature', null, this.airConditioner?.log);
531
694
  await this.airConditioner?.setAttribute(TemperatureMeasurement.Cluster.id, 'measuredValue', null, this.airConditioner?.log);
532
695
  await this.airConditioner?.setAttribute(RelativeHumidityMeasurementCluster.id, 'measuredValue', null, this.airConditioner?.log);
@@ -536,19 +699,26 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
536
699
  this.pump = new MatterbridgeEndpoint([pumpDevice, bridgedNode, powerSource], { uniqueStorageKey: 'Pump' }, this.config.debug)
537
700
  .createDefaultBridgedDeviceBasicInformationClusterServer('Pump', '0x96382864PUMP', 0xfff1, 'Matterbridge', 'Matterbridge Pump', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
538
701
  .createDefaultIdentifyClusterServer()
539
- .createDefaultOnOffClusterServer(true)
702
+ .createOnOffClusterServer()
703
+ .createLevelControlClusterServer()
540
704
  .createDefaultPumpConfigurationAndControlClusterServer()
541
705
  .createDefaultPowerSourceWiredClusterServer();
542
- await this.registerDevice(this.pump);
543
- this.bridgedDevices.set(this.pump.deviceName ?? '', this.pump);
544
- this.pump.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
706
+ this.setSelectDevice(this.pump.serialNumber ?? '', this.pump.deviceName ?? '', undefined, 'hub');
707
+ if (this.validateDevice(this.pump.deviceName ?? '')) {
708
+ await this.registerDevice(this.pump);
709
+ this.bridgedDevices.set(this.pump.deviceName ?? '', this.pump);
710
+ }
711
+ else {
712
+ this.pump = undefined;
713
+ }
714
+ this.pump?.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
545
715
  this.pump?.log.info(`Command identify called identifyTime:${identifyTime}`);
546
716
  });
547
- this.pump.addCommandHandler('on', async () => {
717
+ this.pump?.addCommandHandler('on', async () => {
548
718
  this.pump?.log.info('Command on called');
549
719
  await this.pump?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.pump?.log);
550
720
  });
551
- this.pump.addCommandHandler('off', async () => {
721
+ this.pump?.addCommandHandler('off', async () => {
552
722
  this.pump?.log.info('Command off called');
553
723
  await this.pump?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.pump?.log);
554
724
  });
@@ -557,17 +727,29 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
557
727
  .createDefaultIdentifyClusterServer()
558
728
  .createDefaultValveConfigurationAndControlClusterServer()
559
729
  .createDefaultPowerSourceWiredClusterServer();
560
- await this.registerDevice(this.valve);
561
- this.bridgedDevices.set(this.valve.deviceName ?? '', this.valve);
562
- this.valve.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
730
+ this.setSelectDevice(this.valve.serialNumber ?? '', this.valve.deviceName ?? '', undefined, 'hub');
731
+ if (this.validateDevice(this.valve.deviceName ?? '')) {
732
+ await this.registerDevice(this.valve);
733
+ this.bridgedDevices.set(this.valve.deviceName ?? '', this.valve);
734
+ }
735
+ else {
736
+ this.valve = undefined;
737
+ }
738
+ this.valve?.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
563
739
  this.valve?.log.info(`Command identify called identifyTime:${identifyTime}`);
564
740
  });
565
741
  this.fan = new MatterbridgeEndpoint([fanDevice, bridgedNode], { uniqueStorageKey: 'Fan' }, this.config.debug)
566
742
  .createDefaultBridgedDeviceBasicInformationClusterServer('Fan', 'serial_980545631228', 0xfff1, 'Matterbridge', 'Matterbridge Fan', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
567
743
  .addRequiredClusterServers();
568
- await this.registerDevice(this.fan);
569
- this.bridgedDevices.set(this.fan.deviceName ?? '', this.fan);
570
- this.fan.subscribeAttribute(FanControl.Cluster.id, 'fanMode', async (newValue, oldValue) => {
744
+ this.setSelectDevice(this.fan.serialNumber ?? '', this.fan.deviceName ?? '', undefined, 'hub');
745
+ if (this.validateDevice(this.fan.deviceName ?? '')) {
746
+ await this.registerDevice(this.fan);
747
+ this.bridgedDevices.set(this.fan.deviceName ?? '', this.fan);
748
+ }
749
+ else {
750
+ this.fan = undefined;
751
+ }
752
+ this.fan?.subscribeAttribute(FanControl.Cluster.id, 'fanMode', async (newValue, oldValue) => {
571
753
  this.fan?.log.info(`Fan mode changed from ${this.fanModeLookup[oldValue]} to ${this.fanModeLookup[newValue]}`);
572
754
  if (newValue === FanControl.FanMode.Off) {
573
755
  await this.fan?.setAttribute(FanControl.Cluster.id, 'percentSetting', 0, this.fan?.log);
@@ -594,12 +776,12 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
594
776
  await this.fan?.setAttribute(FanControl.Cluster.id, 'percentCurrent', 50, this.fan?.log);
595
777
  }
596
778
  }, this.fan.log);
597
- this.fan.subscribeAttribute(FanControl.Cluster.id, 'percentSetting', async (newValue, oldValue) => {
779
+ this.fan?.subscribeAttribute(FanControl.Cluster.id, 'percentSetting', async (newValue, oldValue) => {
598
780
  this.fan?.log.info(`Percent setting changed from ${oldValue} to ${newValue}`);
599
781
  if (isValidNumber(newValue, 0, 100))
600
782
  await this.fan?.setAttribute(FanControl.Cluster.id, 'percentCurrent', newValue, this.fan?.log);
601
783
  }, this.fan.log);
602
- this.fan.subscribeAttribute(FanControl.Cluster.id, 'speedSetting', async (newValue, oldValue) => {
784
+ this.fan?.subscribeAttribute(FanControl.Cluster.id, 'speedSetting', async (newValue, oldValue) => {
603
785
  this.fan?.log.info(`Speed setting changed from ${oldValue} to ${newValue}`);
604
786
  if (isValidNumber(newValue, 0, 100))
605
787
  await this.fan?.setAttribute(FanControl.Cluster.id, 'speedCurrent', newValue, this.fan?.log);
@@ -609,81 +791,206 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
609
791
  .createDefaultBooleanStateClusterServer(false)
610
792
  .addRequiredClusterServers()
611
793
  .addOptionalClusterServers();
612
- this.registerDevice(this.waterLeak);
613
- this.bridgedDevices.set(this.waterLeak.deviceName ?? '', this.waterLeak);
794
+ this.setSelectDevice(this.waterLeak.serialNumber ?? '', this.waterLeak.deviceName ?? '', undefined, 'hub');
795
+ if (this.validateDevice(this.waterLeak.deviceName ?? '')) {
796
+ await this.registerDevice(this.waterLeak);
797
+ this.bridgedDevices.set(this.waterLeak.deviceName ?? '', this.waterLeak);
798
+ }
799
+ else {
800
+ this.waterLeak = undefined;
801
+ }
614
802
  this.waterFreeze = new MatterbridgeEndpoint([waterFreezeDetector, bridgedNode], { uniqueStorageKey: 'Water freeze detector' }, this.config.debug)
615
803
  .createDefaultBridgedDeviceBasicInformationClusterServer('Water freeze detector', 'serial_98745631223', 0xfff1, 'Matterbridge', 'Matterbridge WaterFreezeDetector', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
616
804
  .createDefaultBooleanStateClusterServer(false)
617
805
  .addRequiredClusterServers()
618
806
  .addOptionalClusterServers();
619
- await this.registerDevice(this.waterFreeze);
620
- this.bridgedDevices.set(this.waterFreeze.deviceName ?? '', this.waterFreeze);
807
+ this.setSelectDevice(this.waterFreeze.serialNumber ?? '', this.waterFreeze.deviceName ?? '', undefined, 'hub');
808
+ if (this.validateDevice(this.waterFreeze.deviceName ?? '')) {
809
+ await this.registerDevice(this.waterFreeze);
810
+ this.bridgedDevices.set(this.waterFreeze.deviceName ?? '', this.waterFreeze);
811
+ }
812
+ else {
813
+ this.waterFreeze = undefined;
814
+ }
621
815
  this.rain = new MatterbridgeEndpoint([rainSensor, bridgedNode], { uniqueStorageKey: 'Rain sensor' }, this.config.debug)
622
816
  .createDefaultBridgedDeviceBasicInformationClusterServer('Rain sensor', 'serial_98745631224', 0xfff1, 'Matterbridge', 'Matterbridge RainSensor', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
623
817
  .createDefaultIdentifyClusterServer()
624
818
  .createDefaultBooleanStateClusterServer(false)
625
819
  .createDefaultBooleanStateConfigurationClusterServer();
626
- await this.registerDevice(this.rain);
627
- this.bridgedDevices.set(this.rain.deviceName ?? '', this.rain);
628
- this.smoke = new MatterbridgeEndpoint([smokeCoAlarm, bridgedNode], { uniqueStorageKey: 'Smoke alarm sensor' }, this.config.debug)
629
- .createDefaultBridgedDeviceBasicInformationClusterServer('Smoke alarm sensor', 'serial_94745631225', 0xfff1, 'Matterbridge', 'Matterbridge SmokeCoAlarm', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
820
+ this.setSelectDevice(this.rain.serialNumber ?? '', this.rain.deviceName ?? '', undefined, 'hub');
821
+ if (this.validateDevice(this.rain.deviceName ?? '')) {
822
+ await this.registerDevice(this.rain);
823
+ this.bridgedDevices.set(this.rain.deviceName ?? '', this.rain);
824
+ }
825
+ else {
826
+ this.rain = undefined;
827
+ }
828
+ this.smokeCo = new MatterbridgeEndpoint([smokeCoAlarm, bridgedNode], { uniqueStorageKey: 'SmokeCo alarm sensor' }, this.config.debug)
829
+ .createDefaultBridgedDeviceBasicInformationClusterServer('SmokeCo alarm sensor', 'serial_94745631225', 0xfff1, 'Matterbridge', 'Matterbridge SmokeCoAlarm', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
830
+ .createDefaultIdentifyClusterServer()
831
+ .createDefaultSmokeCOAlarmClusterServer(SmokeCoAlarm.AlarmState.Normal, SmokeCoAlarm.AlarmState.Normal);
832
+ if (this.config.enableConcentrationMeasurements === true)
833
+ this.smokeCo.createDefaultCarbonMonoxideConcentrationMeasurementClusterServer(100);
834
+ this.setSelectDevice(this.smokeCo.serialNumber ?? '', this.smokeCo.deviceName ?? '', undefined, 'hub');
835
+ if (this.validateDevice(this.smokeCo.deviceName ?? '')) {
836
+ await this.registerDevice(this.smokeCo);
837
+ this.bridgedDevices.set(this.smokeCo.deviceName ?? '', this.smokeCo);
838
+ }
839
+ else {
840
+ this.smokeCo = undefined;
841
+ }
842
+ this.smokeOnly = new MatterbridgeEndpoint([smokeCoAlarm, bridgedNode], { uniqueStorageKey: 'Smoke only SmokeCo alarm sensor' }, this.config.debug)
843
+ .createDefaultBridgedDeviceBasicInformationClusterServer('Smoke only SmokeCo alarm sensor', 'serial_94755661225', 0xfff1, 'Matterbridge', 'Matterbridge SmokeCoAlarm', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
630
844
  .createDefaultIdentifyClusterServer()
631
- .createDefaultSmokeCOAlarmClusterServer(SmokeCoAlarm.AlarmState.Normal, SmokeCoAlarm.AlarmState.Normal)
632
- .createDefaultCarbonMonoxideConcentrationMeasurementClusterServer(100);
633
- await this.registerDevice(this.smoke);
634
- this.bridgedDevices.set(this.smoke.deviceName ?? '', this.smoke);
845
+ .createSmokeOnlySmokeCOAlarmClusterServer(SmokeCoAlarm.AlarmState.Normal);
846
+ this.setSelectDevice(this.smokeOnly.serialNumber ?? '', this.smokeOnly.deviceName ?? '', undefined, 'hub');
847
+ if (this.validateDevice(this.smokeOnly.deviceName ?? '')) {
848
+ await this.registerDevice(this.smokeOnly);
849
+ this.bridgedDevices.set(this.smokeOnly.deviceName ?? '', this.smokeOnly);
850
+ }
851
+ else {
852
+ this.smokeOnly = undefined;
853
+ }
854
+ this.coOnly = new MatterbridgeEndpoint([smokeCoAlarm, bridgedNode], { uniqueStorageKey: 'Co only SmokeCo alarm sensor' }, this.config.debug)
855
+ .createDefaultBridgedDeviceBasicInformationClusterServer('Co only SmokeCo alarm sensor', 'serial_947456317488', 0xfff1, 'Matterbridge', 'Matterbridge SmokeCoAlarm', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
856
+ .createDefaultIdentifyClusterServer()
857
+ .createCoOnlySmokeCOAlarmClusterServer(SmokeCoAlarm.AlarmState.Normal);
858
+ if (this.config.enableConcentrationMeasurements === true)
859
+ this.coOnly.createDefaultCarbonMonoxideConcentrationMeasurementClusterServer(100);
860
+ this.setSelectDevice(this.coOnly.serialNumber ?? '', this.coOnly.deviceName ?? '', undefined, 'hub');
861
+ if (this.validateDevice(this.coOnly.deviceName ?? '')) {
862
+ await this.registerDevice(this.coOnly);
863
+ this.bridgedDevices.set(this.coOnly.deviceName ?? '', this.coOnly);
864
+ }
865
+ else {
866
+ this.coOnly = undefined;
867
+ }
635
868
  this.airQuality = new MatterbridgeEndpoint([airQualitySensor, bridgedNode], { uniqueStorageKey: 'Air quality sensor' }, this.config.debug)
636
869
  .createDefaultBridgedDeviceBasicInformationClusterServer('Air quality sensor', 'serial_987484318322', 0xfff1, 'Matterbridge', 'Matterbridge Air Quality Sensor', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
637
870
  .addRequiredClusterServers()
638
- .addClusterServers([
639
- TemperatureMeasurement.Cluster.id,
640
- RelativeHumidityMeasurement.Cluster.id,
641
- CarbonMonoxideConcentrationMeasurement.Cluster.id,
642
- CarbonDioxideConcentrationMeasurement.Cluster.id,
643
- NitrogenDioxideConcentrationMeasurement.Cluster.id,
644
- OzoneConcentrationMeasurement.Cluster.id,
645
- FormaldehydeConcentrationMeasurement.Cluster.id,
646
- Pm1ConcentrationMeasurement.Cluster.id,
647
- Pm25ConcentrationMeasurement.Cluster.id,
648
- Pm10ConcentrationMeasurement.Cluster.id,
649
- RadonConcentrationMeasurement.Cluster.id,
650
- TotalVolatileOrganicCompoundsConcentrationMeasurement.Cluster.id,
651
- ]);
652
- await this.registerDevice(this.airQuality);
653
- this.bridgedDevices.set(this.airQuality.deviceName ?? '', this.airQuality);
871
+ .addClusterServers([TemperatureMeasurement.Cluster.id, RelativeHumidityMeasurement.Cluster.id]);
872
+ if (this.config.enableConcentrationMeasurements === true) {
873
+ this.airQuality.createDefaultCarbonMonoxideConcentrationMeasurementClusterServer(10);
874
+ this.airQuality.createDefaultCarbonDioxideConcentrationMeasurementClusterServer(400);
875
+ this.airQuality.createDefaultNitrogenDioxideConcentrationMeasurementClusterServer(1);
876
+ this.airQuality.createDefaultOzoneConcentrationMeasurementClusterServer(1);
877
+ this.airQuality.createDefaultFormaldehydeConcentrationMeasurementClusterServer(1);
878
+ this.airQuality.createDefaultPm1ConcentrationMeasurementClusterServer(100);
879
+ this.airQuality.createDefaultPm25ConcentrationMeasurementClusterServer(100);
880
+ this.airQuality.createDefaultPm10ConcentrationMeasurementClusterServer(100);
881
+ this.airQuality.createDefaultRadonConcentrationMeasurementClusterServer(100);
882
+ this.airQuality.createDefaultTvocMeasurementClusterServer(100);
883
+ }
884
+ this.setSelectDevice(this.airQuality.serialNumber ?? '', this.airQuality.deviceName ?? '', undefined, 'hub');
885
+ if (this.validateDevice(this.airQuality.deviceName ?? '')) {
886
+ await this.registerDevice(this.airQuality);
887
+ this.bridgedDevices.set(this.airQuality.deviceName ?? '', this.airQuality);
888
+ }
889
+ else {
890
+ this.airQuality = undefined;
891
+ }
654
892
  this.momentarySwitch = new MatterbridgeEndpoint([genericSwitch, bridgedNode, powerSource], { uniqueStorageKey: 'Momentary switch' }, this.config.debug)
655
893
  .createDefaultBridgedDeviceBasicInformationClusterServer('Momentary switch', 'serial_947942331225', 0xfff1, 'Matterbridge', 'Matterbridge MomentarySwitch', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
656
894
  .createDefaultIdentifyClusterServer()
657
895
  .createDefaultSwitchClusterServer()
658
896
  .createDefaultPowerSourceReplaceableBatteryClusterServer(50, PowerSource.BatChargeLevel.Ok, 2900, 'CR2450', 1);
659
- await this.registerDevice(this.momentarySwitch);
660
- this.bridgedDevices.set(this.momentarySwitch.deviceName ?? '', this.momentarySwitch);
897
+ this.setSelectDevice(this.momentarySwitch.serialNumber ?? '', this.momentarySwitch.deviceName ?? '', undefined, 'hub');
898
+ if (this.validateDevice(this.momentarySwitch.deviceName ?? '')) {
899
+ await this.registerDevice(this.momentarySwitch);
900
+ this.bridgedDevices.set(this.momentarySwitch.deviceName ?? '', this.momentarySwitch);
901
+ }
902
+ else {
903
+ this.momentarySwitch = undefined;
904
+ }
661
905
  this.latchingSwitch = new MatterbridgeEndpoint([genericSwitch, bridgedNode, powerSource], { uniqueStorageKey: 'Latching switch' }, this.config.debug)
662
906
  .createDefaultBridgedDeviceBasicInformationClusterServer('Latching switch', 'serial_947442331225', 0xfff1, 'Matterbridge', 'Matterbridge LatchingSwitch', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion)
663
907
  .createDefaultIdentifyClusterServer()
664
908
  .createDefaultLatchingSwitchClusterServer()
665
909
  .createDefaultPowerSourceReplaceableBatteryClusterServer(10, PowerSource.BatChargeLevel.Critical, 2850, 'CR2032', 1);
666
- await this.registerDevice(this.latchingSwitch);
667
- this.bridgedDevices.set(this.latchingSwitch.deviceName ?? '', this.latchingSwitch);
910
+ this.setSelectDevice(this.latchingSwitch.serialNumber ?? '', this.latchingSwitch.deviceName ?? '', undefined, 'hub');
911
+ if (this.validateDevice(this.latchingSwitch.deviceName ?? '')) {
912
+ await this.registerDevice(this.latchingSwitch);
913
+ this.bridgedDevices.set(this.latchingSwitch.deviceName ?? '', this.latchingSwitch);
914
+ }
915
+ else {
916
+ this.latchingSwitch = undefined;
917
+ }
918
+ const robot = new Robot('Robot Vacuum', '1238777820');
919
+ this.setSelectDevice(robot.serialNumber ?? '', robot.deviceName ?? '', undefined, 'hub');
920
+ if (this.validateDevice(robot.deviceName ?? '')) {
921
+ await this.registerDevice(robot);
922
+ this.bridgedDevices.set(robot.deviceName ?? '', robot);
923
+ }
924
+ const laundryWasherDevice = new Appliances(laundryWasher, 'Laundry Washer', '1234567890');
925
+ this.setSelectDevice(laundryWasherDevice.serialNumber ?? '', laundryWasherDevice.deviceName ?? '', undefined, 'hub');
926
+ if (this.validateDevice(laundryWasherDevice.deviceName ?? '')) {
927
+ await this.registerDevice(laundryWasherDevice);
928
+ this.bridgedDevices.set(laundryWasherDevice.deviceName ?? '', laundryWasherDevice);
929
+ }
930
+ const laundryDryerDevice = new Appliances(laundryDryer, 'Laundry Dryer', '1235227890');
931
+ this.setSelectDevice(laundryDryerDevice.serialNumber ?? '', laundryDryerDevice.deviceName ?? '', undefined, 'hub');
932
+ if (this.validateDevice(laundryDryerDevice.deviceName ?? '')) {
933
+ await this.registerDevice(laundryDryerDevice);
934
+ this.bridgedDevices.set(laundryDryerDevice.deviceName ?? '', laundryDryerDevice);
935
+ }
936
+ const dishwasherDevice = new Appliances(dishwasher, 'Dishwasher', '0987654321');
937
+ this.setSelectDevice(dishwasherDevice.serialNumber ?? '', dishwasherDevice.deviceName ?? '', undefined, 'hub');
938
+ if (this.validateDevice(dishwasherDevice.deviceName ?? '')) {
939
+ await this.registerDevice(dishwasherDevice);
940
+ this.bridgedDevices.set(dishwasherDevice.deviceName ?? '', dishwasherDevice);
941
+ }
942
+ const refrigeratorDevice = new Appliances(refrigerator, 'Refrigerator', '9987654322');
943
+ this.setSelectDevice(refrigeratorDevice.serialNumber ?? '', refrigeratorDevice.deviceName ?? '', undefined, 'hub');
944
+ if (this.validateDevice(refrigeratorDevice.deviceName ?? '')) {
945
+ await this.registerDevice(refrigeratorDevice);
946
+ this.bridgedDevices.set(refrigeratorDevice.deviceName ?? '', refrigeratorDevice);
947
+ }
948
+ const ovenDevice = new Appliances(oven, 'Oven', '1298867891');
949
+ this.setSelectDevice(ovenDevice.serialNumber ?? '', ovenDevice.deviceName ?? '', undefined, 'hub');
950
+ if (this.validateDevice(ovenDevice.deviceName ?? '')) {
951
+ await this.registerDevice(ovenDevice);
952
+ this.bridgedDevices.set(ovenDevice.deviceName ?? '', ovenDevice);
953
+ }
954
+ const microwaveOvenDevice = new Appliances(microwaveOven, 'Microwave Oven', '1234567892');
955
+ this.setSelectDevice(microwaveOvenDevice.serialNumber ?? '', microwaveOvenDevice.deviceName ?? '', undefined, 'hub');
956
+ if (this.validateDevice(microwaveOvenDevice.deviceName ?? '')) {
957
+ await this.registerDevice(microwaveOvenDevice);
958
+ this.bridgedDevices.set(microwaveOvenDevice.deviceName ?? '', microwaveOvenDevice);
959
+ }
960
+ const extractorHoodDevice = new Appliances(extractorHood, 'Extractor Hood', '1234567893');
961
+ this.setSelectDevice(extractorHoodDevice.serialNumber ?? '', extractorHoodDevice.deviceName ?? '', undefined, 'hub');
962
+ if (this.validateDevice(extractorHoodDevice.deviceName ?? '')) {
963
+ await this.registerDevice(extractorHoodDevice);
964
+ this.bridgedDevices.set(extractorHoodDevice.deviceName ?? '', extractorHoodDevice);
965
+ }
966
+ const cooktopDevice = new Appliances(cooktop, 'Cooktop', '1255887894');
967
+ this.setSelectDevice(cooktopDevice.serialNumber ?? '', cooktopDevice.deviceName ?? '', undefined, 'hub');
968
+ if (this.validateDevice(cooktopDevice.deviceName ?? '')) {
969
+ await this.registerDevice(cooktopDevice);
970
+ this.bridgedDevices.set(cooktopDevice.deviceName ?? '', cooktopDevice);
971
+ }
668
972
  }
669
973
  async onConfigure() {
670
974
  await super.onConfigure();
671
975
  this.log.info('onConfigure called');
672
- await this.switch?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.switch.log);
673
- this.switch?.log.info('Set switch initial onOff to false');
976
+ this.log.notice('<iframe width="500" height="500" src="https://www.youtube.com/embed/DLzxrzFCyOs?hl=en_US&version=3&rel=0&autoplay=1" frameborder="1" allowfullscreen></iframe>');
977
+ await this.switch?.setAttribute(OnOff.Cluster.id, 'onOff', this.intervalOnOff, this.switch.log);
978
+ await this.mountedOnOffSwitch?.setAttribute(OnOff.Cluster.id, 'onOff', this.intervalOnOff, this.mountedOnOffSwitch.log);
979
+ this.switch?.log.info(`Set switch initial onOff to ${this.intervalOnOff}`);
674
980
  if (this.config.useInterval) {
675
981
  this.switchInterval = setInterval(async () => {
676
- const status = this.switch?.getAttribute(OnOff.Cluster.id, 'onOff', this.switch.log);
677
- if (isValidBoolean(status)) {
678
- await this.switch?.setAttribute(OnOff.Cluster.id, 'onOff', !status, this.switch.log);
679
- this.switch?.log.info(`Set switch onOff to ${!status}`);
680
- }
982
+ await this.switch?.setAttribute(OnOff.Cluster.id, 'onOff', this.intervalOnOff, this.switch.log);
983
+ await this.mountedOnOffSwitch?.setAttribute(OnOff.Cluster.id, 'onOff', this.intervalOnOff, this.mountedOnOffSwitch.log);
984
+ this.log.info(`Set switches onOff to ${this.intervalOnOff}`);
985
+ this.intervalOnOff = !this.intervalOnOff;
681
986
  }, 60 * 1000 + 100);
682
987
  }
683
988
  await this.lightOnOff?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.lightOnOff.log);
684
989
  this.lightOnOff?.log.info('Set light initial onOff to false.');
685
990
  await this.dimmer?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.dimmer.log);
686
991
  await this.dimmer?.setAttribute(LevelControl.Cluster.id, 'currentLevel', 1, this.dimmer.log);
992
+ await this.mountedDimmerSwitch?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.mountedDimmerSwitch.log);
993
+ await this.mountedDimmerSwitch?.setAttribute(LevelControl.Cluster.id, 'currentLevel', 1, this.mountedDimmerSwitch.log);
687
994
  this.dimmer?.log.info(`Set dimmer initial onOff to false, currentLevel to 1.`);
688
995
  await this.light?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.light.log);
689
996
  await this.light?.setAttribute(LevelControl.Cluster.id, 'currentLevel', 200, this.light.log);
@@ -710,42 +1017,48 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
710
1017
  this.lightCT?.log.info('Set light CT initial onOff to true, currentLevel to 128, colorTemperatureMireds to 250.');
711
1018
  if (this.config.useInterval) {
712
1019
  this.lightInterval = setInterval(async () => {
713
- const state = this.light?.getAttribute(OnOff.Cluster.id, 'onOff', this.light.log);
714
- let level = this.light?.getAttribute(LevelControl.Cluster.id, 'currentLevel', this.light.log);
715
- if (isValidBoolean(state) && isValidNumber(level, 0, 254)) {
716
- level += 10;
717
- if (level >= 250) {
718
- level = 1;
719
- await this.lightOnOff?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.lightOnOff.log);
720
- await this.dimmer?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.dimmer.log);
721
- await this.light?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.light.log);
722
- await this.lightXY?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.lightXY.log);
723
- await this.lightHS?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.lightHS.log);
724
- await this.lightCT?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.lightCT.log);
725
- this.log.info('Set lights onOff to false');
726
- await this.dimmer?.setAttribute(LevelControl.Cluster.id, 'currentLevel', level, this.dimmer.log);
727
- await this.light?.setAttribute(LevelControl.Cluster.id, 'currentLevel', level, this.light.log);
728
- await this.lightXY?.setAttribute(LevelControl.Cluster.id, 'currentLevel', level, this.lightXY.log);
729
- await this.lightHS?.setAttribute(LevelControl.Cluster.id, 'currentLevel', level, this.lightHS.log);
730
- await this.lightCT?.setAttribute(LevelControl.Cluster.id, 'currentLevel', level, this.lightCT.log);
731
- this.log.info(`Set lights currentLevel to ${level}`);
732
- }
733
- else {
734
- await this.lightOnOff?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.lightOnOff?.log);
735
- await this.dimmer?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.dimmer.log);
736
- await this.light?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.light.log);
737
- await this.lightXY?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.lightXY.log);
738
- await this.lightHS?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.lightHS.log);
739
- await this.lightCT?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.lightCT.log);
740
- this.log.info('Set lights onOff to true');
741
- await this.dimmer?.setAttribute(LevelControl.Cluster.id, 'currentLevel', level, this.dimmer.log);
742
- await this.light?.setAttribute(LevelControl.Cluster.id, 'currentLevel', level, this.light.log);
743
- await this.lightXY?.setAttribute(LevelControl.Cluster.id, 'currentLevel', level, this.lightXY.log);
744
- await this.lightHS?.setAttribute(LevelControl.Cluster.id, 'currentLevel', level, this.lightHS.log);
745
- await this.lightCT?.setAttribute(LevelControl.Cluster.id, 'currentLevel', level, this.lightCT.log);
746
- this.log.info(`Set lights currentLevel to ${level}`);
747
- }
1020
+ this.intervalLevel += 10;
1021
+ if (this.intervalLevel >= 250) {
1022
+ this.intervalLevel = 0;
1023
+ await this.lightOnOff?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.lightOnOff.log);
1024
+ await this.dimmer?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.dimmer.log);
1025
+ await this.mountedDimmerSwitch?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.mountedDimmerSwitch.log);
1026
+ await this.light?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.light.log);
1027
+ await this.lightXY?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.lightXY.log);
1028
+ await this.lightHS?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.lightHS.log);
1029
+ await this.lightCT?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.lightCT.log);
1030
+ this.log.info('Set lights onOff to false');
748
1031
  }
1032
+ else {
1033
+ await this.lightOnOff?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.lightOnOff?.log);
1034
+ await this.dimmer?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.dimmer.log);
1035
+ await this.mountedDimmerSwitch?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.mountedDimmerSwitch.log);
1036
+ await this.light?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.light.log);
1037
+ await this.lightXY?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.lightXY.log);
1038
+ await this.lightHS?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.lightHS.log);
1039
+ await this.lightCT?.setAttribute(OnOff.Cluster.id, 'onOff', true, this.lightCT.log);
1040
+ this.log.info('Set lights onOff to true');
1041
+ await this.dimmer?.setAttribute(LevelControl.Cluster.id, 'currentLevel', this.intervalLevel, this.dimmer.log);
1042
+ await this.mountedDimmerSwitch?.setAttribute(LevelControl.Cluster.id, 'currentLevel', this.intervalLevel, this.mountedDimmerSwitch.log);
1043
+ await this.light?.setAttribute(LevelControl.Cluster.id, 'currentLevel', this.intervalLevel, this.light.log);
1044
+ await this.lightXY?.setAttribute(LevelControl.Cluster.id, 'currentLevel', this.intervalLevel, this.lightXY.log);
1045
+ await this.lightHS?.setAttribute(LevelControl.Cluster.id, 'currentLevel', this.intervalLevel, this.lightHS.log);
1046
+ await this.lightCT?.setAttribute(LevelControl.Cluster.id, 'currentLevel', this.intervalLevel, this.lightCT.log);
1047
+ this.log.info(`Set lights currentLevel to ${this.intervalLevel}`);
1048
+ }
1049
+ this.intervalColorTemperature += 50;
1050
+ if (this.intervalColorTemperature > 500) {
1051
+ this.intervalColorTemperature = 147;
1052
+ }
1053
+ await this.light?.setAttribute(ColorControl.Cluster.id, 'colorTemperatureMireds', this.intervalColorTemperature, this.light.log);
1054
+ await this.lightHS?.setAttribute(ColorControl.Cluster.id, 'colorTemperatureMireds', this.intervalColorTemperature, this.lightHS.log);
1055
+ await this.lightXY?.setAttribute(ColorControl.Cluster.id, 'colorTemperatureMireds', this.intervalColorTemperature, this.lightXY.log);
1056
+ await this.lightCT?.setAttribute(ColorControl.Cluster.id, 'colorTemperatureMireds', this.intervalColorTemperature, this.lightCT.log);
1057
+ await this.light?.configureColorControlMode(ColorControl.ColorMode.ColorTemperatureMireds);
1058
+ await this.lightHS?.configureColorControlMode(ColorControl.ColorMode.ColorTemperatureMireds);
1059
+ await this.lightXY?.configureColorControlMode(ColorControl.ColorMode.ColorTemperatureMireds);
1060
+ await this.lightCT?.configureColorControlMode(ColorControl.ColorMode.ColorTemperatureMireds);
1061
+ this.log.info(`Set lights colorTemperatureMireds to ${this.intervalColorTemperature}`);
749
1062
  }, 60 * 1000 + 200);
750
1063
  }
751
1064
  await this.outlet?.setAttribute(OnOff.Cluster.id, 'onOff', false, this.outlet.log);
@@ -883,32 +1196,38 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
883
1196
  }
884
1197
  }, 60 * 1000 + 1000);
885
1198
  }
886
- await this.smoke?.setAttribute(SmokeCoAlarm.Cluster.id, 'smokeState', SmokeCoAlarm.AlarmState.Normal, this.smoke.log);
887
- await this.smoke?.setAttribute(SmokeCoAlarm.Cluster.id, 'coState', SmokeCoAlarm.AlarmState.Normal, this.smoke.log);
1199
+ await this.smokeCo?.setAttribute(SmokeCoAlarm.Cluster.id, 'smokeState', SmokeCoAlarm.AlarmState.Normal, this.smokeCo.log);
1200
+ await this.smokeCo?.setAttribute(SmokeCoAlarm.Cluster.id, 'coState', SmokeCoAlarm.AlarmState.Normal, this.smokeCo.log);
1201
+ await this.smokeOnly?.setAttribute(SmokeCoAlarm.Cluster.id, 'smokeState', SmokeCoAlarm.AlarmState.Normal, this.smokeOnly.log);
1202
+ await this.coOnly?.setAttribute(SmokeCoAlarm.Cluster.id, 'coState', SmokeCoAlarm.AlarmState.Normal, this.coOnly.log);
888
1203
  if (this.config.useInterval) {
889
1204
  this.smokeInterval = setInterval(async () => {
890
- let value = this.smoke?.getAttribute(SmokeCoAlarm.Cluster.id, 'smokeState', this.smoke.log);
1205
+ let value = this.smokeCo?.getAttribute(SmokeCoAlarm.Cluster.id, 'smokeState', this.smokeCo.log);
891
1206
  if (isValidNumber(value, SmokeCoAlarm.AlarmState.Normal, SmokeCoAlarm.AlarmState.Critical)) {
892
1207
  value = value === SmokeCoAlarm.AlarmState.Normal ? SmokeCoAlarm.AlarmState.Critical : SmokeCoAlarm.AlarmState.Normal;
893
- await this.smoke?.setAttribute(SmokeCoAlarm.Cluster.id, 'smokeState', value, this.smoke.log);
894
- await this.smoke?.setAttribute(SmokeCoAlarm.Cluster.id, 'coState', value, this.smoke.log);
895
- this.smoke?.log.info(`Set smoke smokeState and coState to ${value}`);
1208
+ await this.smokeCo?.setAttribute(SmokeCoAlarm.Cluster.id, 'smokeState', value, this.smokeCo.log);
1209
+ await this.smokeCo?.setAttribute(SmokeCoAlarm.Cluster.id, 'coState', value, this.smokeCo.log);
1210
+ await this.smokeOnly?.setAttribute(SmokeCoAlarm.Cluster.id, 'smokeState', value, this.smokeOnly.log);
1211
+ await this.coOnly?.setAttribute(SmokeCoAlarm.Cluster.id, 'coState', value, this.coOnly.log);
1212
+ this.smokeCo?.log.info(`Set smoke smokeState and coState to ${value}`);
896
1213
  }
897
1214
  }, 60 * 1000 + 1100);
898
1215
  }
899
1216
  await this.airQuality?.setAttribute(AirQuality.Cluster.id, 'airQuality', AirQuality.AirQualityEnum.Good, this.airQuality.log);
900
1217
  await this.airQuality?.setAttribute(TemperatureMeasurement.Cluster.id, 'measuredValue', 2150, this.airQuality.log);
901
1218
  await this.airQuality?.setAttribute(RelativeHumidityMeasurement.Cluster.id, 'measuredValue', 5500, this.airQuality.log);
902
- await this.airQuality?.setAttribute(CarbonMonoxideConcentrationMeasurement.Cluster.id, 'measuredValue', 10, this.airQuality.log);
903
- await this.airQuality?.setAttribute(CarbonDioxideConcentrationMeasurement.Cluster.id, 'measuredValue', 400, this.airQuality.log);
904
- await this.airQuality?.setAttribute(NitrogenDioxideConcentrationMeasurement.Cluster.id, 'measuredValue', 1, this.airQuality.log);
905
- await this.airQuality?.setAttribute(OzoneConcentrationMeasurement.Cluster.id, 'measuredValue', 1, this.airQuality.log);
906
- await this.airQuality?.setAttribute(FormaldehydeConcentrationMeasurement.Cluster.id, 'measuredValue', 1, this.airQuality.log);
907
- await this.airQuality?.setAttribute(Pm1ConcentrationMeasurement.Cluster.id, 'measuredValue', 100, this.airQuality.log);
908
- await this.airQuality?.setAttribute(Pm25ConcentrationMeasurement.Cluster.id, 'measuredValue', 100, this.airQuality.log);
909
- await this.airQuality?.setAttribute(Pm10ConcentrationMeasurement.Cluster.id, 'measuredValue', 100, this.airQuality.log);
910
- await this.airQuality?.setAttribute(RadonConcentrationMeasurement.Cluster.id, 'measuredValue', 100, this.airQuality.log);
911
- await this.airQuality?.setAttribute(TotalVolatileOrganicCompoundsConcentrationMeasurement.Cluster.id, 'measuredValue', 100, this.airQuality.log);
1219
+ if (this.config.enableConcentrationMeasurements === true) {
1220
+ await this.airQuality?.setAttribute(CarbonMonoxideConcentrationMeasurement.Cluster.id, 'measuredValue', 10, this.airQuality.log);
1221
+ await this.airQuality?.setAttribute(CarbonDioxideConcentrationMeasurement.Cluster.id, 'measuredValue', 400, this.airQuality.log);
1222
+ await this.airQuality?.setAttribute(NitrogenDioxideConcentrationMeasurement.Cluster.id, 'measuredValue', 1, this.airQuality.log);
1223
+ await this.airQuality?.setAttribute(OzoneConcentrationMeasurement.Cluster.id, 'measuredValue', 1, this.airQuality.log);
1224
+ await this.airQuality?.setAttribute(FormaldehydeConcentrationMeasurement.Cluster.id, 'measuredValue', 1, this.airQuality.log);
1225
+ await this.airQuality?.setAttribute(Pm1ConcentrationMeasurement.Cluster.id, 'measuredValue', 100, this.airQuality.log);
1226
+ await this.airQuality?.setAttribute(Pm25ConcentrationMeasurement.Cluster.id, 'measuredValue', 100, this.airQuality.log);
1227
+ await this.airQuality?.setAttribute(Pm10ConcentrationMeasurement.Cluster.id, 'measuredValue', 100, this.airQuality.log);
1228
+ await this.airQuality?.setAttribute(RadonConcentrationMeasurement.Cluster.id, 'measuredValue', 100, this.airQuality.log);
1229
+ await this.airQuality?.setAttribute(TotalVolatileOrganicCompoundsConcentrationMeasurement.Cluster.id, 'measuredValue', 100, this.airQuality.log);
1230
+ }
912
1231
  if (this.config.useInterval) {
913
1232
  this.airQualityInterval = setInterval(async () => {
914
1233
  let value = this.airQuality?.getAttribute(AirQuality.Cluster.id, 'airQuality', this.airQuality?.log);
@@ -919,6 +1238,24 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
919
1238
  }
920
1239
  }, 60 * 1000 + 1100);
921
1240
  }
1241
+ const airConditionerDevice = this.bridgedDevices.get('Air Conditioner');
1242
+ await airConditionerDevice?.setAttribute(OnOff.Cluster.id, 'onOff', true, airConditionerDevice.log);
1243
+ const laundryWasherDevice = this.bridgedDevices.get('Laundry Washer');
1244
+ await laundryWasherDevice?.setAttribute(OnOff.Cluster.id, 'onOff', true, laundryWasherDevice.log);
1245
+ const laundryDryerDevice = this.bridgedDevices.get('Laundry Dryer');
1246
+ await laundryDryerDevice?.setAttribute(OnOff.Cluster.id, 'onOff', true, laundryDryerDevice.log);
1247
+ const dishwasherDevice = this.bridgedDevices.get('Dishwasher');
1248
+ await dishwasherDevice?.setAttribute(OnOff.Cluster.id, 'onOff', true, dishwasherDevice.log);
1249
+ this.log.info(`Set appliances dead front OnOff to on`);
1250
+ const cooktopDevice = this.bridgedDevices.get('Cooktop');
1251
+ await cooktopDevice?.setAttribute(OnOff.Cluster.id, 'onOff', true, cooktopDevice.log);
1252
+ cooktopDevice?.log.info(`Set Cooktop onOff only OnOff to on`);
1253
+ const surface1 = cooktopDevice?.getChildEndpointByName('Surface1');
1254
+ await surface1?.setAttribute(OnOff.Cluster.id, 'onOff', true, surface1.log);
1255
+ surface1?.log.info(`Set Surface 1 onOff only OnOff to on`);
1256
+ const surface2 = cooktopDevice?.getChildEndpointByName('Surface2');
1257
+ await surface2?.setAttribute(OnOff.Cluster.id, 'onOff', true, surface2.log);
1258
+ surface2?.log.info(`Set Surface 2 onOff only OnOff to on`);
922
1259
  if (this.config.useInterval) {
923
1260
  this.genericSwitchInterval = setInterval(async () => {
924
1261
  if (this.genericSwitchLastEvent === 'Release') {
@@ -962,6 +1299,6 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
962
1299
  await super.onShutdown(reason);
963
1300
  this.log.info('onShutdown called with reason:', reason ?? 'none');
964
1301
  if (this.config.unregisterOnShutdown === true)
965
- await this.unregisterAllDevices();
1302
+ await this.unregisterAllDevices(500);
966
1303
  }
967
1304
  }