matterbridge-example-dynamic-platform 1.1.4-dev.1 → 1.1.5-dev.1

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/CHANGELOG.md CHANGED
@@ -4,15 +4,36 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  If you like this project and find it useful, please consider giving it a star on GitHub at https://github.com/Luligu/matterbridge-example-dynamic-platform and sponsoring it.
6
6
 
7
- ## [1.1.4-dev.1] - 2024-12-17
7
+ ## [1.1.5] - 2025-02-01
8
8
 
9
- - [package]: Added thermostat Heat only with two external temperature sensors (tagged like Indoor and Outdoor).
10
- - [package]: Added thermostat Cool only.
11
- - [package]: Added an airPurifier device with temperature and humidity sensor (supported by Apple Home).
12
- - [package]: Added a pumpDevice device.
13
- - [package]: Added a waterValve device.
14
- - [package]: Require matterbridge 1.6.7.
9
+ ### Added
10
+
11
+ ### Changed
12
+
13
+ - [package]: Require matterbridge 2.1.0.
15
14
  - [package]: Updated dependencies.
15
+ - [package]: Updated package.
16
+
17
+ ### Fixed
18
+
19
+ <a href="https://www.buymeacoffee.com/luligugithub">
20
+ <img src="./yellow-button.png" alt="Buy me a coffee" width="120">
21
+ </a>
22
+
23
+ ## [1.1.4] - 2024-12-21
24
+
25
+ ### Added
26
+
27
+ - [platform]: Added call to super.OnConfigure() and super.OnShutDown() to check endpoints numbers.
28
+
29
+ ### Changed
30
+
31
+ - [package]: Updated dependencies.
32
+ - [package]: Updated package.
33
+
34
+ ### Fixed
35
+
36
+ - [thermostat]: Fixed temperature
16
37
 
17
38
  <a href="https://www.buymeacoffee.com/luligugithub">
18
39
  <img src="./yellow-button.png" alt="Buy me a coffee" width="120">
@@ -20,11 +41,16 @@ If you like this project and find it useful, please consider giving it a star on
20
41
 
21
42
  ## [1.1.3] - 2024-12-16
22
43
 
44
+ ### Added
45
+
23
46
  - [package]: Added thermostat Heat only with two external temperature sensors (tagged like Indoor and Outdoor).
24
47
  - [package]: Added thermostat Cool only.
25
48
  - [package]: Added an airPurifier device with temperature and humidity sensor (supported by Apple Home).
26
49
  - [package]: Added a pumpDevice device.
27
50
  - [package]: Added a waterValve device.
51
+
52
+ ### Changed
53
+
28
54
  - [package]: Require matterbridge 1.6.7.
29
55
  - [package]: Updated dependencies.
30
56
 
@@ -34,9 +60,14 @@ If you like this project and find it useful, please consider giving it a star on
34
60
 
35
61
  ## [1.1.2] - 2024-12-12
36
62
 
63
+ ### Added
64
+
37
65
  - [package]: Added the Matter 1.3 airConditioner device (not supported by Apple Home).
38
66
  - [package]: Require matterbridge 1.6.6.
39
67
  - [package]: Added Jest test with 100% coverage.
68
+
69
+ ### Changed
70
+
40
71
  - [package]: Updated package.
41
72
  - [package]: Updated dependencies.
42
73
 
package/dist/platform.js CHANGED
@@ -1,5 +1,5 @@
1
- import { AirQuality, AirQualityCluster, BooleanStateCluster, BooleanStateConfiguration, CarbonDioxideConcentrationMeasurement, CarbonMonoxideConcentrationMeasurement, ColorControl, ColorControlCluster, DoorLock, DoorLockCluster, FanControl, FanControlCluster, FlowMeasurement, FlowMeasurementCluster, FormaldehydeConcentrationMeasurement, LevelControlCluster, MatterbridgeEndpoint, NitrogenDioxideConcentrationMeasurement, OnOffCluster, OzoneConcentrationMeasurement, Pm10ConcentrationMeasurement, Pm1ConcentrationMeasurement, Pm25ConcentrationMeasurement, RadonConcentrationMeasurement, RelativeHumidityMeasurement, RelativeHumidityMeasurementCluster, SmokeCoAlarm, SmokeCoAlarmCluster, TemperatureMeasurement, TemperatureMeasurementCluster, Thermostat, ThermostatCluster, TotalVolatileOrganicCompoundsConcentrationMeasurement, WindowCovering, WindowCoveringCluster, airConditioner, airQualitySensor, bridgedNode, colorTemperatureLight, coverDevice, dimmableLight, doorLockDevice, fanDevice, flowSensor, humiditySensor, onOffLight, onOffOutlet, onOffSwitch, powerSource, rainSensor, smokeCoAlarm, temperatureSensor, thermostatDevice, waterFreezeDetector, waterLeakDetector, LocationTag, airPurifier, pumpDevice, waterValve, } from 'matterbridge';
2
- import { MatterbridgeDevice, MatterbridgeDynamicPlatform } from 'matterbridge';
1
+ import { AirQuality, AirQualityCluster, BooleanStateCluster, CarbonDioxideConcentrationMeasurement, CarbonMonoxideConcentrationMeasurement, ColorControl, ColorControlCluster, DoorLock, DoorLockCluster, FanControl, FanControlCluster, FlowMeasurementCluster, FormaldehydeConcentrationMeasurement, LevelControlCluster, NitrogenDioxideConcentrationMeasurement, OnOffCluster, OzoneConcentrationMeasurement, Pm10ConcentrationMeasurement, Pm1ConcentrationMeasurement, Pm25ConcentrationMeasurement, RadonConcentrationMeasurement, RelativeHumidityMeasurement, RelativeHumidityMeasurementCluster, SmokeCoAlarm, SmokeCoAlarmCluster, TemperatureMeasurement, TemperatureMeasurementCluster, Thermostat, ThermostatCluster, TotalVolatileOrganicCompoundsConcentrationMeasurement, WindowCovering, WindowCoveringCluster, airConditioner, airQualitySensor, bridgedNode, colorTemperatureLight, coverDevice, dimmableLight, doorLockDevice, fanDevice, flowSensor, humiditySensor, onOffLight, onOffOutlet, onOffSwitch, powerSource, rainSensor, smokeCoAlarm, temperatureSensor, thermostatDevice, waterFreezeDetector, waterLeakDetector, LocationTag, airPurifier, pumpDevice, waterValve, } from 'matterbridge';
2
+ import { MatterbridgeEndpoint, MatterbridgeDynamicPlatform } from 'matterbridge';
3
3
  import { isValidBoolean, isValidNumber } from 'matterbridge/utils';
4
4
  export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatform {
5
5
  switch;
@@ -40,31 +40,21 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
40
40
  airConditionerInterval;
41
41
  bridgedDevices = new Map();
42
42
  fanModeLookup = ['Off', 'Low', 'Medium', 'High', 'On', 'Auto', 'Smart'];
43
- async createMutableDevice(definition, options = {}, debug = false) {
44
- let device;
45
- if (this.matterbridge.edge === true)
46
- device = new MatterbridgeEndpoint(definition, options, debug);
47
- else
48
- device = new MatterbridgeDevice(definition, options, debug);
49
- return device;
50
- }
51
43
  constructor(matterbridge, log, config) {
52
44
  super(matterbridge, log, config);
53
- if (this.verifyMatterbridgeVersion === undefined || typeof this.verifyMatterbridgeVersion !== 'function' || !this.verifyMatterbridgeVersion('1.6.7')) {
54
- throw new Error(`This plugin requires Matterbridge version >= "1.6.7". Please update Matterbridge from ${this.matterbridge.matterbridgeVersion} to the latest version in the frontend.`);
45
+ if (this.verifyMatterbridgeVersion === undefined || typeof this.verifyMatterbridgeVersion !== 'function' || !this.verifyMatterbridgeVersion('2.1.0')) {
46
+ throw new Error(`This plugin requires Matterbridge version >= "2.1.0". Please update Matterbridge from ${this.matterbridge.matterbridgeVersion} to the latest version in the frontend.`);
55
47
  }
56
48
  this.log.info('Initializing platform:', this.config.name);
57
49
  }
58
50
  async onStart(reason) {
59
51
  this.log.info('onStart called with reason:', reason ?? 'none');
60
- this.switch = await this.createMutableDevice([onOffSwitch, bridgedNode], { uniqueStorageKey: 'Switch' }, this.config.debug);
52
+ this.switch = new MatterbridgeEndpoint([onOffSwitch, bridgedNode, powerSource], { uniqueStorageKey: 'Switch' }, this.config.debug);
61
53
  this.switch.log.logName = 'Switch';
62
54
  this.switch.createDefaultIdentifyClusterServer();
63
55
  this.switch.createDefaultGroupsClusterServer();
64
- this.switch.createDefaultScenesClusterServer();
65
56
  this.switch.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);
66
57
  this.switch.createDefaultOnOffClusterServer();
67
- this.switch.addDeviceType(powerSource);
68
58
  this.switch.createDefaultPowerSourceRechargeableBatteryClusterServer(70);
69
59
  await this.registerDevice(this.switch);
70
60
  this.bridgedDevices.set(this.switch.deviceName ?? '', this.switch);
@@ -72,21 +62,19 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
72
62
  this.log.info(`Command identify called identifyTime:${identifyTime}`);
73
63
  });
74
64
  this.switch.addCommandHandler('on', async () => {
75
- await this.switch?.setAttribute(OnOffCluster.id, 'onOff', true, this.switch.log, this.switch);
65
+ await this.switch?.setAttribute(OnOffCluster.id, 'onOff', true, this.switch.log);
76
66
  this.switch?.log.info('Command on called');
77
67
  });
78
68
  this.switch.addCommandHandler('off', async () => {
79
- await this.switch?.setAttribute(OnOffCluster.id, 'onOff', false, this.switch.log, this.switch);
69
+ await this.switch?.setAttribute(OnOffCluster.id, 'onOff', false, this.switch.log);
80
70
  this.switch?.log.info('Command off called');
81
71
  });
82
- this.lightOnOff = await this.createMutableDevice([onOffLight, bridgedNode], { uniqueStorageKey: 'Light (on/off)' }, this.config.debug);
72
+ this.lightOnOff = new MatterbridgeEndpoint([onOffLight, bridgedNode, powerSource], { uniqueStorageKey: 'Light (on/off)' }, this.config.debug);
83
73
  this.lightOnOff.log.logName = 'Light (on/off)';
84
74
  this.lightOnOff.createDefaultIdentifyClusterServer();
85
75
  this.lightOnOff.createDefaultGroupsClusterServer();
86
- this.lightOnOff.createDefaultScenesClusterServer();
87
76
  this.lightOnOff.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);
88
77
  this.lightOnOff.createDefaultOnOffClusterServer();
89
- this.lightOnOff.addDeviceType(powerSource);
90
78
  this.lightOnOff.createDefaultPowerSourceWiredClusterServer();
91
79
  await this.registerDevice(this.lightOnOff);
92
80
  this.bridgedDevices.set(this.lightOnOff.deviceName ?? '', this.lightOnOff);
@@ -94,22 +82,20 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
94
82
  this.lightOnOff?.log.info(`Command identify called identifyTime:${identifyTime}`);
95
83
  });
96
84
  this.lightOnOff.addCommandHandler('on', async () => {
97
- await this.light?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightOnOff?.log, this.lightOnOff);
85
+ await this.lightOnOff?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightOnOff?.log);
98
86
  this.lightOnOff?.log.info('Command on called');
99
87
  });
100
88
  this.lightOnOff.addCommandHandler('off', async () => {
101
- await this.light?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightOnOff?.log, this.lightOnOff);
89
+ await this.lightOnOff?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightOnOff?.log);
102
90
  this.lightOnOff?.log.info('Command off called');
103
91
  });
104
- this.dimmer = await this.createMutableDevice([dimmableLight, bridgedNode], { uniqueStorageKey: 'Dimmer' }, this.config.debug);
92
+ this.dimmer = new MatterbridgeEndpoint([dimmableLight, bridgedNode, powerSource], { uniqueStorageKey: 'Dimmer' }, this.config.debug);
105
93
  this.dimmer.log.logName = 'Dimmer';
106
94
  this.dimmer.createDefaultIdentifyClusterServer();
107
95
  this.dimmer.createDefaultGroupsClusterServer();
108
- this.dimmer.createDefaultScenesClusterServer();
109
96
  this.dimmer.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);
110
97
  this.dimmer.createDefaultOnOffClusterServer();
111
98
  this.dimmer.createDefaultLevelControlClusterServer();
112
- this.dimmer.addDeviceType(powerSource);
113
99
  this.dimmer.createDefaultPowerSourceReplaceableBatteryClusterServer(70);
114
100
  await this.registerDevice(this.dimmer);
115
101
  this.bridgedDevices.set(this.dimmer.deviceName ?? '', this.dimmer);
@@ -117,31 +103,29 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
117
103
  this.dimmer?.log.info(`Command identify called identifyTime:${identifyTime}`);
118
104
  });
119
105
  this.dimmer.addCommandHandler('on', async () => {
120
- await this.dimmer?.setAttribute(OnOffCluster.id, 'onOff', true, this.dimmer.log, this.dimmer);
106
+ await this.dimmer?.setAttribute(OnOffCluster.id, 'onOff', true, this.dimmer.log);
121
107
  this.dimmer?.log.info('Command on called');
122
108
  });
123
109
  this.dimmer.addCommandHandler('off', async () => {
124
- await this.dimmer?.setAttribute(OnOffCluster.id, 'onOff', false, this.dimmer.log, this.dimmer);
110
+ await this.dimmer?.setAttribute(OnOffCluster.id, 'onOff', false, this.dimmer.log);
125
111
  this.dimmer?.log.info('Command off called');
126
112
  });
127
113
  this.dimmer.addCommandHandler('moveToLevel', async ({ request: { level } }) => {
128
- await this.dimmer?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.dimmer.log, this.dimmer);
114
+ await this.dimmer?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.dimmer.log);
129
115
  this.dimmer?.log.debug(`Command moveToLevel called request: ${level}`);
130
116
  });
131
117
  this.dimmer.addCommandHandler('moveToLevelWithOnOff', async ({ request: { level } }) => {
132
- await this.dimmer?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.dimmer.log, this.dimmer);
118
+ await this.dimmer?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.dimmer.log);
133
119
  this.dimmer?.log.debug(`Command moveToLevelWithOnOff called request: ${level}`);
134
120
  });
135
- this.light = await this.createMutableDevice([colorTemperatureLight, bridgedNode], { uniqueStorageKey: 'Light (XY, HS and CT)' }, this.config.debug);
121
+ this.light = new MatterbridgeEndpoint([colorTemperatureLight, bridgedNode, powerSource], { uniqueStorageKey: 'Light (XY, HS and CT)' }, this.config.debug);
136
122
  this.light.log.logName = 'Light (XY, HS and CT)';
137
123
  this.light.createDefaultIdentifyClusterServer();
138
124
  this.light.createDefaultGroupsClusterServer();
139
- this.light.createDefaultScenesClusterServer();
140
125
  this.light.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);
141
126
  this.light.createDefaultOnOffClusterServer();
142
127
  this.light.createDefaultLevelControlClusterServer();
143
128
  this.light.createDefaultColorControlClusterServer();
144
- this.light.addDeviceType(powerSource);
145
129
  this.light.createDefaultPowerSourceReplaceableBatteryClusterServer(70);
146
130
  await this.registerDevice(this.light);
147
131
  this.bridgedDevices.set(this.light.deviceName ?? '', this.light);
@@ -149,53 +133,51 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
149
133
  this.light?.log.info(`Command identify called identifyTime:${identifyTime}`);
150
134
  });
151
135
  this.light.addCommandHandler('on', async () => {
152
- await this.light?.setAttribute(OnOffCluster.id, 'onOff', true, this.light?.log, this.light);
136
+ await this.light?.setAttribute(OnOffCluster.id, 'onOff', true, this.light?.log);
153
137
  this.light?.log.info('Command on called');
154
138
  });
155
139
  this.light.addCommandHandler('off', async () => {
156
- await this.light?.setAttribute(OnOffCluster.id, 'onOff', false, this.light?.log, this.light);
140
+ await this.light?.setAttribute(OnOffCluster.id, 'onOff', false, this.light?.log);
157
141
  this.light?.log.info('Command off called');
158
142
  });
159
143
  this.light.addCommandHandler('moveToLevel', async ({ request: { level } }) => {
160
- await this.light?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.light?.log, this.light);
144
+ await this.light?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.light?.log);
161
145
  this.light?.log.debug(`Command moveToLevel called request: ${level}`);
162
146
  });
163
147
  this.light.addCommandHandler('moveToLevelWithOnOff', async ({ request: { level } }) => {
164
- await this.light?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.light?.log, this.light);
148
+ await this.light?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.light?.log);
165
149
  this.light?.log.debug(`Command moveToLevelWithOnOff called request: ${level}`);
166
150
  });
167
151
  this.light.addCommandHandler('moveToColor', async ({ request: { colorX, colorY } }) => {
168
- await this.light?.setAttribute(ColorControlCluster.id, 'currentX', colorX, this.light?.log, this.light);
169
- await this.light?.setAttribute(ColorControlCluster.id, 'currentY', colorY, this.light?.log, this.light);
152
+ await this.light?.setAttribute(ColorControlCluster.id, 'currentX', colorX, this.light?.log);
153
+ await this.light?.setAttribute(ColorControlCluster.id, 'currentY', colorY, this.light?.log);
170
154
  this.light?.log.debug(`Command moveToColor called request: X ${colorX / 65536} Y ${colorY / 65536}`);
171
155
  });
172
- this.light.addCommandHandler('moveToHueAndSaturation', async ({ request: { hue, saturation }, attributes: { currentHue, currentSaturation } }) => {
173
- await this.light?.setAttribute(ColorControlCluster.id, 'currentHue', hue, this.light?.log, this.light);
174
- await this.light?.setAttribute(ColorControlCluster.id, 'currentSaturation', saturation, this.light?.log, this.light);
175
- this.light?.log.debug(`Command moveToHueAndSaturation called request: hue ${hue} saturation ${saturation} attributes: hue ${currentHue?.getLocal()} saturation ${currentSaturation?.getLocal()}`);
156
+ this.light.addCommandHandler('moveToHueAndSaturation', async ({ request: { hue, saturation } }) => {
157
+ await this.light?.setAttribute(ColorControlCluster.id, 'currentHue', hue, this.light?.log);
158
+ await this.light?.setAttribute(ColorControlCluster.id, 'currentSaturation', saturation, this.light?.log);
159
+ this.light?.log.debug(`Command moveToHueAndSaturation called request: hue ${hue} saturation ${saturation}`);
176
160
  });
177
- this.light.addCommandHandler('moveToHue', async ({ request: { hue }, attributes: { currentHue, currentSaturation } }) => {
178
- await this.light?.setAttribute(ColorControlCluster.id, 'currentHue', hue, this.light?.log, this.light);
179
- this.light?.log.debug(`Command moveToHue called request: hue ${hue} attributes: hue ${currentHue?.getLocal()} saturation ${currentSaturation?.getLocal()}`);
161
+ this.light.addCommandHandler('moveToHue', async ({ request: { hue } }) => {
162
+ await this.light?.setAttribute(ColorControlCluster.id, 'currentHue', hue, this.light?.log);
163
+ this.light?.log.debug(`Command moveToHue called request: hue ${hue}`);
180
164
  });
181
- this.light.addCommandHandler('moveToSaturation', async ({ request: { saturation }, attributes: { currentHue, currentSaturation } }) => {
182
- await this.light?.setAttribute(ColorControlCluster.id, 'currentSaturation', saturation, this.light?.log, this.light);
183
- this.light?.log.debug(`Command moveToSaturation called request: saturation ${saturation} attributes: hue ${currentHue?.getLocal()} saturation ${currentSaturation?.getLocal()}`);
165
+ this.light.addCommandHandler('moveToSaturation', async ({ request: { saturation } }) => {
166
+ await this.light?.setAttribute(ColorControlCluster.id, 'currentSaturation', saturation, this.light?.log);
167
+ this.light?.log.debug(`Command moveToSaturation called request: saturation ${saturation}}`);
184
168
  });
185
- this.light.addCommandHandler('moveToColorTemperature', async ({ request, attributes }) => {
186
- await this.light?.setAttribute(ColorControlCluster.id, 'colorTemperatureMireds', request.colorTemperatureMireds, this.light?.log, this.light);
187
- this.light?.log.debug(`Command moveToColorTemperature called request: ${request.colorTemperatureMireds} attributes: ${attributes.colorTemperatureMireds?.getLocal()}`);
169
+ this.light.addCommandHandler('moveToColorTemperature', async ({ request: { colorTemperatureMireds } }) => {
170
+ await this.light?.setAttribute(ColorControlCluster.id, 'colorTemperatureMireds', colorTemperatureMireds, this.light?.log);
171
+ this.light?.log.debug(`Command moveToColorTemperature called request: ${colorTemperatureMireds}`);
188
172
  });
189
- this.lightHS = await this.createMutableDevice([colorTemperatureLight, bridgedNode], { uniqueStorageKey: 'Light (HS)' }, this.config.debug);
173
+ this.lightHS = new MatterbridgeEndpoint([colorTemperatureLight, bridgedNode, powerSource], { uniqueStorageKey: 'Light (HS, CT)' }, this.config.debug);
190
174
  this.lightHS.log.logName = 'Light (HS, CT)';
191
175
  this.lightHS.createDefaultIdentifyClusterServer();
192
176
  this.lightHS.createDefaultGroupsClusterServer();
193
- this.lightHS.createDefaultScenesClusterServer();
194
177
  this.lightHS.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);
195
178
  this.lightHS.createDefaultOnOffClusterServer();
196
179
  this.lightHS.createDefaultLevelControlClusterServer();
197
180
  this.lightHS.createHsColorControlClusterServer();
198
- this.lightHS.addDeviceType(powerSource);
199
181
  this.lightHS.createDefaultPowerSourceWiredClusterServer();
200
182
  await this.registerDevice(this.lightHS);
201
183
  this.bridgedDevices.set(this.lightHS.deviceName ?? '', this.lightHS);
@@ -203,48 +185,45 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
203
185
  this.lightHS?.log.info(`Command identify called identifyTime:${identifyTime}`);
204
186
  });
205
187
  this.lightHS.addCommandHandler('on', async () => {
206
- await this.lightHS?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightHS?.log, this.lightHS);
188
+ await this.lightHS?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightHS?.log);
207
189
  this.lightHS?.log.info('Command on called');
208
190
  });
209
191
  this.lightHS.addCommandHandler('off', async () => {
210
- await this.lightHS?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightHS?.log, this.lightHS);
192
+ await this.lightHS?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightHS?.log);
211
193
  this.lightHS?.log.info('Command off called');
212
194
  });
213
- this.lightHS.addCommandHandler('moveToLevel', async ({ request: { level }, attributes: { currentLevel } }) => {
214
- await this.lightHS?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightHS?.log, this.lightHS);
215
- this.lightHS?.log.debug(`Command moveToLevel called request: ${level} attributes: ${currentLevel?.getLocal()}`);
195
+ this.lightHS.addCommandHandler('moveToLevel', async ({ request: { level } }) => {
196
+ await this.lightHS?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightHS?.log);
197
+ this.lightHS?.log.debug(`Command moveToLevel called request: ${level}`);
216
198
  });
217
- this.lightHS.addCommandHandler('moveToLevelWithOnOff', async ({ request: { level }, attributes: { currentLevel } }) => {
218
- await this.lightHS?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightHS?.log, this.lightHS);
219
- this.lightHS?.log.debug(`Command moveToLevelWithOnOff called request: ${level} attributes: ${currentLevel?.getLocal()}`);
199
+ this.lightHS.addCommandHandler('moveToLevelWithOnOff', async ({ request: { level } }) => {
200
+ await this.lightHS?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightHS?.log);
201
+ this.lightHS?.log.debug(`Command moveToLevelWithOnOff called request: ${level}`);
220
202
  });
221
- this.lightHS.addCommandHandler('moveToHueAndSaturation', async ({ request: { hue, saturation }, attributes: { currentHue, currentSaturation } }) => {
222
- await this.lightHS?.setAttribute(ColorControlCluster.id, 'currentHue', hue, this.lightHS?.log, this.lightHS);
223
- await this.lightHS?.setAttribute(ColorControlCluster.id, 'currentSaturation', saturation, this.lightHS?.log, this.lightHS);
224
- this.lightHS?.log.debug(`Command moveToHueAndSaturation called request: hue ${hue} saturation ${saturation} attributes: hue ${currentHue?.getLocal()} saturation ${currentSaturation?.getLocal()}`);
203
+ this.lightHS.addCommandHandler('moveToHueAndSaturation', async ({ request: { hue, saturation } }) => {
204
+ await this.lightHS?.setAttribute(ColorControlCluster.id, 'currentHue', hue, this.lightHS?.log);
205
+ await this.lightHS?.setAttribute(ColorControlCluster.id, 'currentSaturation', saturation, this.lightHS?.log);
206
+ this.lightHS?.log.debug(`Command moveToHueAndSaturation called request: hue ${hue} saturation ${saturation}}`);
225
207
  });
226
- this.lightHS.addCommandHandler('moveToHue', async ({ request: { hue }, attributes: { currentHue, currentSaturation } }) => {
227
- await this.lightHS?.setAttribute(ColorControlCluster.id, 'currentHue', hue, this.lightHS?.log, this.lightHS);
228
- this.lightHS?.log.debug(`Command moveToHue called request: hue ${hue} attributes: hue ${currentHue?.getLocal()} saturation ${currentSaturation?.getLocal()}`);
208
+ this.lightHS.addCommandHandler('moveToHue', async ({ request: { hue } }) => {
209
+ await this.lightHS?.setAttribute(ColorControlCluster.id, 'currentHue', hue, this.lightHS?.log);
210
+ this.lightHS?.log.debug(`Command moveToHue called request: hue ${hue}`);
229
211
  });
230
- this.lightHS.addCommandHandler('moveToSaturation', async ({ request: { saturation }, attributes: { currentHue, currentSaturation } }) => {
231
- await this.lightHS?.setAttribute(ColorControlCluster.id, 'currentSaturation', saturation, this.lightHS?.log, this.lightHS);
232
- this.lightHS?.log.debug(`Command moveToSaturation called request: saturation ${saturation} attributes: hue ${currentHue?.getLocal()} saturation ${currentSaturation?.getLocal()}`);
212
+ this.lightHS.addCommandHandler('moveToSaturation', async ({ request: { saturation } }) => {
213
+ await this.lightHS?.setAttribute(ColorControlCluster.id, 'currentSaturation', saturation, this.lightHS?.log);
214
+ this.lightHS?.log.debug(`Command moveToSaturation called request: saturation ${saturation}`);
233
215
  });
234
- this.lightHS.addCommandHandler('moveToColorTemperature', async ({ request, attributes }) => {
235
- await this.light?.setAttribute(ColorControlCluster.id, 'colorTemperatureMireds', request.colorTemperatureMireds, this.light?.log, this.light);
236
- this.light?.log.debug(`Command moveToColorTemperature called request: ${request.colorTemperatureMireds} attributes: ${attributes.colorTemperatureMireds?.getLocal()}`);
216
+ this.lightHS.addCommandHandler('moveToColorTemperature', async ({ request: colorTemperatureMireds }) => {
217
+ this.lightHS?.log.debug(`Command moveToColorTemperature called request: ${colorTemperatureMireds}`);
237
218
  });
238
- this.lightXY = await this.createMutableDevice([colorTemperatureLight, bridgedNode], { uniqueStorageKey: 'Light (XY)' }, this.config.debug);
219
+ this.lightXY = new MatterbridgeEndpoint([colorTemperatureLight, bridgedNode, powerSource], { uniqueStorageKey: 'Light (XY, CT)' }, this.config.debug);
239
220
  this.lightXY.log.logName = 'Light (XY, CT)';
240
221
  this.lightXY.createDefaultIdentifyClusterServer();
241
222
  this.lightXY.createDefaultGroupsClusterServer();
242
- this.lightXY.createDefaultScenesClusterServer();
243
223
  this.lightXY.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);
244
224
  this.lightXY.createDefaultOnOffClusterServer();
245
225
  this.lightXY.createDefaultLevelControlClusterServer();
246
226
  this.lightXY.createXyColorControlClusterServer();
247
- this.lightXY.addDeviceType(powerSource);
248
227
  this.lightXY.createDefaultPowerSourceWiredClusterServer();
249
228
  await this.registerDevice(this.lightXY);
250
229
  this.bridgedDevices.set(this.lightXY.deviceName ?? '', this.lightXY);
@@ -252,40 +231,38 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
252
231
  this.lightXY?.log.info(`Command identify called identifyTime:${identifyTime}`);
253
232
  });
254
233
  this.lightXY.addCommandHandler('on', async () => {
255
- await this.lightXY?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightXY?.log, this.lightXY);
234
+ await this.lightXY?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightXY?.log);
256
235
  this.lightXY?.log.info('Command on called');
257
236
  });
258
237
  this.lightXY.addCommandHandler('off', async () => {
259
- await this.lightXY?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightXY?.log, this.lightXY);
238
+ await this.lightXY?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightXY?.log);
260
239
  this.lightXY?.log.info('Command off called');
261
240
  });
262
241
  this.lightXY.addCommandHandler('moveToLevel', async ({ request: { level } }) => {
263
- await this.lightXY?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightXY?.log, this.lightXY);
242
+ await this.lightXY?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightXY?.log);
264
243
  this.lightXY?.log.debug(`Command moveToLevel called request: ${level}`);
265
244
  });
266
245
  this.lightXY.addCommandHandler('moveToLevelWithOnOff', async ({ request: { level } }) => {
267
- await this.lightXY?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightXY?.log, this.lightXY);
246
+ await this.lightXY?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightXY?.log);
268
247
  this.lightXY?.log.debug(`Command moveToLevelWithOnOff called request: ${level}`);
269
248
  });
270
249
  this.lightXY.addCommandHandler('moveToColor', async ({ request: { colorX, colorY } }) => {
271
- await this.lightXY?.setAttribute(ColorControlCluster.id, 'currentX', colorX, this.light?.log, this.light);
272
- await this.lightXY?.setAttribute(ColorControlCluster.id, 'currentY', colorY, this.light?.log, this.light);
250
+ await this.lightXY?.setAttribute(ColorControlCluster.id, 'currentX', colorX, this.lightXY?.log);
251
+ await this.lightXY?.setAttribute(ColorControlCluster.id, 'currentY', colorY, this.lightXY?.log);
273
252
  this.lightXY?.log.debug(`Command moveToColor called request: X ${colorX / 65536} Y ${colorY / 65536}`);
274
253
  });
275
- this.lightXY.addCommandHandler('moveToColorTemperature', async ({ request, attributes }) => {
276
- await this.light?.setAttribute(ColorControlCluster.id, 'colorTemperatureMireds', request.colorTemperatureMireds, this.light?.log, this.light);
277
- this.light?.log.debug(`Command moveToColorTemperature called request: ${request.colorTemperatureMireds} attributes: ${attributes.colorTemperatureMireds?.getLocal()}`);
254
+ this.lightXY.addCommandHandler('moveToColorTemperature', async ({ request: { colorTemperatureMireds } }) => {
255
+ await this.lightXY?.setAttribute(ColorControlCluster.id, 'colorTemperatureMireds', colorTemperatureMireds, this.lightXY?.log);
256
+ this.lightXY?.log.debug(`Command moveToColorTemperature called request: ${colorTemperatureMireds}`);
278
257
  });
279
- this.lightCT = await this.createMutableDevice([colorTemperatureLight, bridgedNode], { uniqueStorageKey: 'Light (CT)' }, this.config.debug);
258
+ this.lightCT = new MatterbridgeEndpoint([colorTemperatureLight, bridgedNode, powerSource], { uniqueStorageKey: 'Light (CT)' }, this.config.debug);
280
259
  this.lightCT.log.logName = 'Light (CT)';
281
260
  this.lightCT.createDefaultIdentifyClusterServer();
282
261
  this.lightCT.createDefaultGroupsClusterServer();
283
- this.lightCT.createDefaultScenesClusterServer();
284
262
  this.lightCT.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);
285
263
  this.lightCT.createDefaultOnOffClusterServer();
286
264
  this.lightCT.createDefaultLevelControlClusterServer();
287
265
  this.lightCT.createCtColorControlClusterServer();
288
- this.lightCT.addDeviceType(powerSource);
289
266
  this.lightCT.createDefaultPowerSourceReplaceableBatteryClusterServer(70);
290
267
  await this.registerDevice(this.lightCT);
291
268
  this.bridgedDevices.set(this.lightCT.deviceName ?? '', this.lightCT);
@@ -293,33 +270,31 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
293
270
  this.lightCT?.log.info(`Command identify called identifyTime:${identifyTime}`);
294
271
  });
295
272
  this.lightCT.addCommandHandler('on', async () => {
296
- await this.lightCT?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightCT?.log, this.lightCT);
273
+ await this.lightCT?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightCT?.log);
297
274
  this.lightCT?.log.info('Command on called');
298
275
  });
299
276
  this.lightCT.addCommandHandler('off', async () => {
300
- await this.lightCT?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightCT?.log, this.lightCT);
277
+ await this.lightCT?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightCT?.log);
301
278
  this.lightCT?.log.info('Command off called');
302
279
  });
303
280
  this.lightCT.addCommandHandler('moveToLevel', async ({ request: { level } }) => {
304
- await this.lightCT?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightCT?.log, this.lightCT);
281
+ await this.lightCT?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightCT?.log);
305
282
  this.lightCT?.log.debug(`Command moveToLevel called request: ${level}`);
306
283
  });
307
284
  this.lightCT.addCommandHandler('moveToLevelWithOnOff', async ({ request: { level } }) => {
308
- await this.lightCT?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightCT?.log, this.lightCT);
285
+ await this.lightCT?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightCT?.log);
309
286
  this.lightCT?.log.debug(`Command moveToLevelWithOnOff called request: ${level}`);
310
287
  });
311
- this.lightCT.addCommandHandler('moveToColorTemperature', async ({ request }) => {
312
- await this.lightCT?.setAttribute(ColorControlCluster.id, 'colorTemperatureMireds', request.colorTemperatureMireds, this.lightCT?.log, this.lightCT);
313
- this.lightCT?.log.debug(`Command moveToColorTemperature called request: ${request.colorTemperatureMireds}`);
288
+ this.lightCT.addCommandHandler('moveToColorTemperature', async ({ request: { colorTemperatureMireds } }) => {
289
+ await this.lightCT?.setAttribute(ColorControlCluster.id, 'colorTemperatureMireds', colorTemperatureMireds, this.lightCT?.log);
290
+ this.lightCT?.log.debug(`Command moveToColorTemperature called request: ${colorTemperatureMireds}`);
314
291
  });
315
- this.outlet = await this.createMutableDevice([onOffOutlet, bridgedNode], { uniqueStorageKey: 'Outlet' }, this.config.debug);
292
+ this.outlet = new MatterbridgeEndpoint([onOffOutlet, bridgedNode, powerSource], { uniqueStorageKey: 'Outlet' }, this.config.debug);
316
293
  this.outlet.log.logName = 'Outlet';
317
294
  this.outlet.createDefaultIdentifyClusterServer();
318
295
  this.outlet.createDefaultGroupsClusterServer();
319
- this.outlet.createDefaultScenesClusterServer();
320
296
  this.outlet.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);
321
297
  this.outlet.createDefaultOnOffClusterServer();
322
- this.outlet.addDeviceType(powerSource);
323
298
  this.outlet.createDefaultPowerSourceWiredClusterServer();
324
299
  await this.registerDevice(this.outlet);
325
300
  this.bridgedDevices.set(this.outlet.deviceName ?? '', this.outlet);
@@ -327,21 +302,19 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
327
302
  this.outlet?.log.info(`Command identify called identifyTime:${identifyTime}`);
328
303
  });
329
304
  this.outlet.addCommandHandler('on', async () => {
330
- await this.outlet?.setAttribute(OnOffCluster.id, 'onOff', true, this.outlet?.log, this.outlet);
305
+ await this.outlet?.setAttribute(OnOffCluster.id, 'onOff', true, this.outlet?.log);
331
306
  this.outlet?.log.info('Command on called');
332
307
  });
333
308
  this.outlet.addCommandHandler('off', async () => {
334
- await this.outlet?.setAttribute(OnOffCluster.id, 'onOff', false, this.outlet?.log, this.outlet);
309
+ await this.outlet?.setAttribute(OnOffCluster.id, 'onOff', false, this.outlet?.log);
335
310
  this.outlet?.log.info('Command off called');
336
311
  });
337
- this.cover = await this.createMutableDevice([coverDevice, bridgedNode], { uniqueStorageKey: 'Cover' }, this.config.debug);
312
+ this.cover = new MatterbridgeEndpoint([coverDevice, bridgedNode, powerSource], { uniqueStorageKey: 'Cover' }, this.config.debug);
338
313
  this.cover.log.logName = 'Cover';
339
314
  this.cover.createDefaultIdentifyClusterServer();
340
315
  this.cover.createDefaultGroupsClusterServer();
341
- this.cover.createDefaultScenesClusterServer();
342
316
  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);
343
317
  this.cover.createDefaultWindowCoveringClusterServer();
344
- this.cover.addDeviceType(powerSource);
345
318
  this.cover.createDefaultPowerSourceRechargeableBatteryClusterServer(86);
346
319
  await this.registerDevice(this.cover);
347
320
  this.bridgedDevices.set(this.cover.deviceName ?? '', this.cover);
@@ -367,12 +340,11 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
367
340
  await this.cover?.setWindowCoveringCurrentTargetStatus(liftPercent100thsValue, liftPercent100thsValue, WindowCovering.MovementStatus.Stopped);
368
341
  this.cover?.log.info(`Command goToLiftPercentage ${liftPercent100thsValue} called`);
369
342
  });
370
- this.lock = await this.createMutableDevice([doorLockDevice, bridgedNode], { uniqueStorageKey: 'Lock' }, this.config.debug);
343
+ this.lock = new MatterbridgeEndpoint([doorLockDevice, bridgedNode, powerSource], { uniqueStorageKey: 'Lock' }, this.config.debug);
371
344
  this.lock.log.logName = 'Lock';
372
345
  this.lock.createDefaultIdentifyClusterServer();
373
346
  this.lock.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);
374
347
  this.lock.createDefaultDoorLockClusterServer();
375
- this.lock.addDeviceType(powerSource);
376
348
  this.lock.createDefaultPowerSourceRechargeableBatteryClusterServer(30);
377
349
  await this.registerDevice(this.lock);
378
350
  this.bridgedDevices.set(this.lock.deviceName ?? '', this.lock);
@@ -380,28 +352,29 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
380
352
  this.lock?.log.info(`Command identify called identifyTime:${identifyTime}`);
381
353
  });
382
354
  this.lock.addCommandHandler('lockDoor', async () => {
383
- await this.lock?.setAttribute(DoorLockCluster.id, 'lockState', DoorLock.LockState.Locked, this.lock?.log, this.lock);
355
+ await this.lock?.setAttribute(DoorLockCluster.id, 'lockState', DoorLock.LockState.Locked, this.lock?.log);
384
356
  this.lock?.log.info('Command lockDoor called');
385
357
  });
386
358
  this.lock.addCommandHandler('unlockDoor', async () => {
387
- await this.lock?.setAttribute(DoorLockCluster.id, 'lockState', DoorLock.LockState.Unlocked, this.lock?.log, this.lock);
359
+ await this.lock?.setAttribute(DoorLockCluster.id, 'lockState', DoorLock.LockState.Unlocked, this.lock?.log);
388
360
  this.lock?.log.info('Command unlockDoor called');
389
361
  });
390
- this.thermoAuto = await this.createMutableDevice([thermostatDevice, bridgedNode], { uniqueStorageKey: 'ThermostatAuto' }, this.config.debug);
362
+ this.thermoAuto = new MatterbridgeEndpoint([thermostatDevice, bridgedNode, powerSource], { uniqueStorageKey: 'Thermostat (AutoMode)' }, this.config.debug);
391
363
  this.thermoAuto.log.logName = 'Thermostat (AutoMode)';
392
364
  this.thermoAuto.createDefaultIdentifyClusterServer();
393
365
  this.thermoAuto.createDefaultGroupsClusterServer();
394
- this.thermoAuto.createDefaultScenesClusterServer();
395
366
  this.thermoAuto.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);
396
367
  this.thermoAuto.createDefaultThermostatClusterServer(20, 18, 22);
397
- this.thermoAuto.addDeviceType(powerSource);
398
368
  this.thermoAuto.createDefaultPowerSourceRechargeableBatteryClusterServer(70);
399
- const flowChild = this.thermoAuto.addChildDeviceTypeWithClusterServer('Flow', [flowSensor], [FlowMeasurement.Cluster.id]);
400
- flowChild.getClusterServer(FlowMeasurement.Cluster)?.setMeasuredValueAttribute(1 * 10);
401
- const tempChild = this.thermoAuto.addChildDeviceTypeWithClusterServer('Temperature', [temperatureSensor], [TemperatureMeasurement.Cluster.id]);
402
- tempChild.getClusterServer(TemperatureMeasurement.Cluster)?.setMeasuredValueAttribute(41 * 100);
403
- const humidityChild = this.thermoAuto.addChildDeviceTypeWithClusterServer('Humidity', [humiditySensor], [RelativeHumidityMeasurement.Cluster.id]);
404
- humidityChild.getClusterServer(RelativeHumidityMeasurement.Cluster)?.setMeasuredValueAttribute(80 * 100);
369
+ const flowChild = this.thermoAuto.addChildDeviceType('Flow', flowSensor);
370
+ flowChild.createDefaultFlowMeasurementClusterServer(1 * 10);
371
+ flowChild.addRequiredClusterServers();
372
+ const tempChild = this.thermoAuto.addChildDeviceType('Temperature', temperatureSensor);
373
+ tempChild.createDefaultTemperatureMeasurementClusterServer(21 * 100);
374
+ tempChild.addRequiredClusterServers();
375
+ const humidityChild = this.thermoAuto.addChildDeviceType('Humidity', humiditySensor);
376
+ humidityChild.createDefaultRelativeHumidityMeasurementClusterServer(50 * 100);
377
+ humidityChild.addRequiredClusterServers();
405
378
  await this.registerDevice(this.thermoAuto);
406
379
  this.bridgedDevices.set(this.thermoAuto.deviceName ?? '', this.thermoAuto);
407
380
  this.thermoAuto.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
@@ -427,21 +400,19 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
427
400
  this.thermoAuto.subscribeAttribute(ThermostatCluster.id, 'systemMode', async (value) => {
428
401
  const lookupSystemMode = ['Off', 'Auto', '', 'Cool', 'Heat', 'EmergencyHeat', 'Precooling', 'FanOnly', 'Dry', 'Sleep'];
429
402
  this.thermoAuto?.log.info('Subscribe systemMode called with:', lookupSystemMode[value]);
430
- }, this.thermoAuto.log, this.thermoAuto);
403
+ }, this.thermoAuto.log);
431
404
  this.thermoAuto.subscribeAttribute(ThermostatCluster.id, 'occupiedHeatingSetpoint', async (value) => {
432
405
  this.thermoAuto?.log.info('Subscribe occupiedHeatingSetpoint called with:', value / 100);
433
- }, this.thermoAuto.log, this.thermoAuto);
406
+ }, this.thermoAuto.log);
434
407
  this.thermoAuto.subscribeAttribute(ThermostatCluster.id, 'occupiedCoolingSetpoint', async (value) => {
435
408
  this.thermoAuto?.log.info('Subscribe occupiedCoolingSetpoint called with:', value / 100);
436
- }, this.thermoAuto.log, this.thermoAuto);
437
- this.thermoHeat = await this.createMutableDevice([thermostatDevice, bridgedNode], { uniqueStorageKey: 'ThermostatHeat' }, this.config.debug);
409
+ }, this.thermoAuto.log);
410
+ this.thermoHeat = new MatterbridgeEndpoint([thermostatDevice, bridgedNode, powerSource], { uniqueStorageKey: 'Thermostat (Heat)' }, this.config.debug);
438
411
  this.thermoHeat.log.logName = 'Thermostat (Heat)';
439
412
  this.thermoHeat.createDefaultIdentifyClusterServer();
440
413
  this.thermoHeat.createDefaultGroupsClusterServer();
441
- this.thermoHeat.createDefaultScenesClusterServer();
442
414
  this.thermoHeat.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);
443
415
  this.thermoHeat.createDefaultHeatingThermostatClusterServer(20, 18, 5, 35);
444
- this.thermoHeat.addDeviceType(powerSource);
445
416
  this.thermoHeat.createDefaultPowerSourceRechargeableBatteryClusterServer(70);
446
417
  const heatTempIN = this.thermoHeat.addChildDeviceType('TemperatureIN', [temperatureSensor], {
447
418
  tagList: [{ mfgCode: null, namespaceId: LocationTag.Indoor.namespaceId, tag: LocationTag.Indoor.tag, label: null }],
@@ -468,14 +439,12 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
468
439
  this.thermoHeat.subscribeAttribute(ThermostatCluster.id, 'occupiedHeatingSetpoint', async (value) => {
469
440
  this.thermoHeat?.log.info('Subscribe occupiedHeatingSetpoint called with:', value / 100);
470
441
  }, this.thermoHeat.log);
471
- this.thermoCool = await this.createMutableDevice([thermostatDevice, bridgedNode], { uniqueStorageKey: 'ThermostatCool' }, this.config.debug);
442
+ this.thermoCool = new MatterbridgeEndpoint([thermostatDevice, bridgedNode, powerSource], { uniqueStorageKey: 'Thermostat (Cool)' }, this.config.debug);
472
443
  this.thermoCool.log.logName = 'Thermostat (Cool)';
473
444
  this.thermoCool.createDefaultIdentifyClusterServer();
474
445
  this.thermoCool.createDefaultGroupsClusterServer();
475
- this.thermoCool.createDefaultScenesClusterServer();
476
446
  this.thermoCool.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);
477
447
  this.thermoCool.createDefaultCoolingThermostatClusterServer(20, 18, 5, 35);
478
- this.thermoCool.addDeviceType(powerSource);
479
448
  this.thermoCool.createDefaultPowerSourceRechargeableBatteryClusterServer(70);
480
449
  await this.registerDevice(this.thermoCool);
481
450
  this.bridgedDevices.set(this.thermoCool.deviceName ?? '', this.thermoCool);
@@ -492,14 +461,13 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
492
461
  this.thermoCool.subscribeAttribute(ThermostatCluster.id, 'occupiedCoolingSetpoint', async (value) => {
493
462
  this.thermoCool?.log.info('Subscribe occupiedCoolingSetpoint called with:', value / 100);
494
463
  }, this.thermoCool.log);
495
- this.airPurifier = await this.createMutableDevice([airPurifier, temperatureSensor, humiditySensor, bridgedNode], { uniqueStorageKey: 'Air purifier' }, this.config.debug);
464
+ this.airPurifier = new MatterbridgeEndpoint([airPurifier, temperatureSensor, humiditySensor, bridgedNode, powerSource], { uniqueStorageKey: 'Air purifier' }, this.config.debug);
496
465
  this.airPurifier.log.logName = 'Air purifier';
497
466
  this.airPurifier.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);
498
467
  this.airPurifier.createDefaultIdentifyClusterServer();
499
468
  this.airPurifier.createDefaultFanControlClusterServer();
500
469
  this.airPurifier.createDefaultTemperatureMeasurementClusterServer(20 * 100);
501
470
  this.airPurifier.createDefaultRelativeHumidityMeasurementClusterServer(50 * 100);
502
- this.airPurifier.addDeviceType(powerSource);
503
471
  this.airPurifier.createDefaultPowerSourceWiredClusterServer();
504
472
  await this.registerDevice(this.airPurifier);
505
473
  this.bridgedDevices.set(this.airPurifier.deviceName ?? '', this.airPurifier);
@@ -532,7 +500,7 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
532
500
  if (isValidNumber(newValue, 0, 100))
533
501
  await this.airPurifier?.setAttribute(FanControlCluster.id, 'percentCurrent', newValue, this.airPurifier?.log);
534
502
  }, this.airPurifier.log);
535
- this.airConditioner = await this.createMutableDevice([airConditioner, bridgedNode], { uniqueStorageKey: 'Air conditioner' }, this.config.debug);
503
+ this.airConditioner = new MatterbridgeEndpoint([airConditioner, bridgedNode, powerSource], { uniqueStorageKey: 'Air conditioner' }, this.config.debug);
536
504
  this.airConditioner.log.logName = 'Air conditioner';
537
505
  this.airConditioner.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);
538
506
  this.airConditioner.createDefaultIdentifyClusterServer();
@@ -541,18 +509,17 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
541
509
  this.airConditioner.createDefaultFanControlClusterServer(FanControl.FanMode.Auto);
542
510
  this.airConditioner.createDefaultTemperatureMeasurementClusterServer(20 * 100);
543
511
  this.airConditioner.createDefaultRelativeHumidityMeasurementClusterServer(50 * 100);
544
- this.airConditioner.addDeviceType(powerSource);
545
512
  this.airConditioner.createDefaultPowerSourceWiredClusterServer();
546
- this.airConditioner.addRequiredClusterServers(this.airConditioner);
513
+ this.airConditioner.addRequiredClusterServers();
547
514
  await this.registerDevice(this.airConditioner);
548
515
  this.bridgedDevices.set(this.airConditioner.deviceName ?? '', this.airConditioner);
549
516
  this.airConditioner.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
550
517
  this.airConditioner?.log.info(`Command identify called identifyTime:${identifyTime}`);
551
518
  });
552
519
  this.airConditioner.addCommandHandler('on', async () => {
553
- await this.airConditioner?.setAttribute(OnOffCluster.id, 'onOff', true, this.airConditioner?.log);
554
520
  this.airConditioner?.log.info('Command on called');
555
521
  await this.airConditioner?.setAttribute(OnOffCluster.id, 'onOff', true, this.airConditioner?.log);
522
+ await this.airConditioner?.setAttribute(OnOffCluster.id, 'onOff', true, this.airConditioner?.log);
556
523
  await this.airConditioner?.setAttribute(ThermostatCluster.id, 'localTemperature', 20 * 100, this.airConditioner?.log);
557
524
  await this.airConditioner?.setAttribute(TemperatureMeasurementCluster.id, 'measuredValue', 20 * 100, this.airConditioner?.log);
558
525
  await this.airConditioner?.setAttribute(RelativeHumidityMeasurementCluster.id, 'measuredValue', 50 * 100, this.airConditioner?.log);
@@ -560,21 +527,20 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
560
527
  await this.airConditioner?.setAttribute(FanControlCluster.id, 'percentSetting', 50, this.airConditioner?.log);
561
528
  });
562
529
  this.airConditioner.addCommandHandler('off', async () => {
530
+ this.airConditioner?.log.info('Command off called');
563
531
  await this.airConditioner?.setAttribute(OnOffCluster.id, 'onOff', false, this.airConditioner?.log);
564
532
  await this.airConditioner?.setAttribute(ThermostatCluster.id, 'localTemperature', null, this.airConditioner?.log);
565
533
  await this.airConditioner?.setAttribute(TemperatureMeasurementCluster.id, 'measuredValue', null, this.airConditioner?.log);
566
534
  await this.airConditioner?.setAttribute(RelativeHumidityMeasurementCluster.id, 'measuredValue', null, this.airConditioner?.log);
567
535
  await this.airConditioner?.setAttribute(FanControlCluster.id, 'speedSetting', null, this.airConditioner?.log);
568
536
  await this.airConditioner?.setAttribute(FanControlCluster.id, 'percentSetting', null, this.airConditioner?.log);
569
- this.airConditioner?.log.info('Command off called');
570
537
  });
571
- this.pump = await this.createMutableDevice([pumpDevice, bridgedNode], { uniqueStorageKey: 'Pump' }, this.config.debug);
538
+ this.pump = new MatterbridgeEndpoint([pumpDevice, bridgedNode, powerSource], { uniqueStorageKey: 'Pump' }, this.config.debug);
572
539
  this.pump.log.logName = 'Pump';
573
540
  this.pump.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);
574
541
  this.pump.createDefaultIdentifyClusterServer();
575
542
  this.pump.createDefaultOnOffClusterServer(true);
576
543
  this.pump.createDefaultPumpConfigurationAndControlClusterServer();
577
- this.pump.addDeviceType(powerSource);
578
544
  this.pump.createDefaultPowerSourceWiredClusterServer();
579
545
  await this.registerDevice(this.pump);
580
546
  this.bridgedDevices.set(this.pump.deviceName ?? '', this.pump);
@@ -582,29 +548,28 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
582
548
  this.pump?.log.info(`Command identify called identifyTime:${identifyTime}`);
583
549
  });
584
550
  this.pump.addCommandHandler('on', async () => {
585
- await this.pump?.setAttribute(OnOffCluster.id, 'onOff', true, this.pump?.log);
586
551
  this.pump?.log.info('Command on called');
552
+ await this.pump?.setAttribute(OnOffCluster.id, 'onOff', true, this.pump?.log);
587
553
  });
588
554
  this.pump.addCommandHandler('off', async () => {
589
- await this.pump?.setAttribute(OnOffCluster.id, 'onOff', false, this.pump?.log);
590
555
  this.pump?.log.info('Command off called');
556
+ await this.pump?.setAttribute(OnOffCluster.id, 'onOff', false, this.pump?.log);
591
557
  });
592
- this.valve = await this.createMutableDevice([waterValve, bridgedNode], { uniqueStorageKey: 'Water valve' }, this.config.debug);
558
+ this.valve = new MatterbridgeEndpoint([waterValve, bridgedNode, powerSource], { uniqueStorageKey: 'Water valve' }, this.config.debug);
593
559
  this.valve.log.logName = 'Water valve';
594
560
  this.valve.createDefaultBridgedDeviceBasicInformationClusterServer('Water valve', '0x96382864WV', 0xfff1, 'Matterbridge', 'Matterbridge Water valve', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion);
595
561
  this.valve.createDefaultIdentifyClusterServer();
596
562
  this.valve.createDefaultValveConfigurationAndControlClusterServer();
597
- this.valve.addDeviceType(powerSource);
598
563
  this.valve.createDefaultPowerSourceWiredClusterServer();
599
564
  await this.registerDevice(this.valve);
600
565
  this.bridgedDevices.set(this.valve.deviceName ?? '', this.valve);
601
566
  this.valve.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
602
567
  this.valve?.log.info(`Command identify called identifyTime:${identifyTime}`);
603
568
  });
604
- this.fan = await this.createMutableDevice([fanDevice, bridgedNode], { uniqueStorageKey: 'Fan' }, this.config.debug);
569
+ this.fan = new MatterbridgeEndpoint([fanDevice, bridgedNode], { uniqueStorageKey: 'Fan' }, this.config.debug);
605
570
  this.fan.log.logName = 'Fan';
606
571
  this.fan.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);
607
- this.fan.addDeviceTypeWithClusterServer([fanDevice], []);
572
+ this.fan.addRequiredClusterServers();
608
573
  await this.registerDevice(this.fan);
609
574
  this.bridgedDevices.set(this.fan.deviceName ?? '', this.fan);
610
575
  this.fan.subscribeAttribute(FanControlCluster.id, 'fanMode', async (newValue, oldValue) => {
@@ -627,7 +592,7 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
627
592
  else if (newValue === FanControl.FanMode.Auto) {
628
593
  await this.fan?.setAttribute(FanControlCluster.id, 'percentCurrent', 50, this.fan?.log);
629
594
  }
630
- }, this.fan.log, this.fan);
595
+ }, this.fan.log);
631
596
  this.fan.subscribeAttribute(FanControlCluster.id, 'percentSetting', async (newValue, oldValue) => {
632
597
  this.fan?.log.info(`Percent setting changed from ${oldValue} to ${newValue}`);
633
598
  if (isValidNumber(newValue, 0, 100))
@@ -638,40 +603,43 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
638
603
  if (isValidNumber(newValue, 0, 100))
639
604
  await this.fan?.setAttribute(FanControlCluster.id, 'speedCurrent', newValue, this.fan?.log);
640
605
  }, this.fan.log);
641
- this.waterLeak = await this.createMutableDevice([waterLeakDetector, bridgedNode], { uniqueStorageKey: 'Water leak detector' }, this.config.debug);
606
+ this.waterLeak = new MatterbridgeEndpoint([waterLeakDetector, bridgedNode], { uniqueStorageKey: 'Water leak detector' }, this.config.debug);
642
607
  this.waterLeak.log.logName = 'Water leak detector';
643
608
  this.waterLeak.createDefaultBridgedDeviceBasicInformationClusterServer('Water leak detector', 'serial_98745631222', 0xfff1, 'Matterbridge', 'Matterbridge WaterLeakDetector', parseInt(this.version.replace(/\D/g, '')), this.version === '' ? 'Unknown' : this.version, parseInt(this.matterbridge.matterbridgeVersion.replace(/\D/g, '')), this.matterbridge.matterbridgeVersion);
644
- this.waterLeak.addDeviceTypeWithClusterServer([waterLeakDetector], [BooleanStateConfiguration.Cluster.id]);
609
+ this.waterLeak.addRequiredClusterServers();
610
+ this.waterLeak.addOptionalClusterServers();
645
611
  await this.registerDevice(this.waterLeak);
646
612
  this.bridgedDevices.set(this.waterLeak.deviceName ?? '', this.waterLeak);
647
613
  await this.waterLeak.setAttribute(BooleanStateCluster.id, 'stateValue', false, this.waterLeak.log);
648
- this.waterFreeze = await this.createMutableDevice([waterFreezeDetector, bridgedNode], { uniqueStorageKey: 'Water freeze detector' }, this.config.debug);
614
+ this.waterFreeze = new MatterbridgeEndpoint([waterFreezeDetector, bridgedNode], { uniqueStorageKey: 'Water freeze detector' }, this.config.debug);
649
615
  this.waterFreeze.log.logName = 'Water freeze detector';
650
616
  this.waterFreeze.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);
651
- this.waterFreeze.addDeviceTypeWithClusterServer([waterFreezeDetector], [BooleanStateConfiguration.Cluster.id]);
617
+ this.waterFreeze.addRequiredClusterServers();
618
+ this.waterFreeze.addOptionalClusterServers();
652
619
  await this.registerDevice(this.waterFreeze);
653
620
  this.bridgedDevices.set(this.waterFreeze.deviceName ?? '', this.waterFreeze);
654
621
  await this.waterFreeze.setAttribute(BooleanStateCluster.id, 'stateValue', false, this.waterFreeze.log);
655
- this.rain = await this.createMutableDevice([rainSensor, bridgedNode], { uniqueStorageKey: 'Rain sensor' }, this.config.debug);
622
+ this.rain = new MatterbridgeEndpoint([rainSensor, bridgedNode], { uniqueStorageKey: 'Rain sensor' }, this.config.debug);
656
623
  this.rain.log.logName = 'Rain sensor';
657
624
  this.rain.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);
658
- this.rain.addDeviceTypeWithClusterServer([rainSensor], [BooleanStateConfiguration.Cluster.id]);
625
+ this.rain.createDefaultIdentifyClusterServer();
626
+ this.rain.createDefaultBooleanStateClusterServer(false);
627
+ this.rain.createDefaultBooleanStateConfigurationClusterServer();
659
628
  await this.registerDevice(this.rain);
660
629
  this.bridgedDevices.set(this.rain.deviceName ?? '', this.rain);
661
- await this.rain.setAttribute(BooleanStateCluster.id, 'stateValue', false, this.rain.log);
662
- this.smoke = await this.createMutableDevice([smokeCoAlarm, bridgedNode], { uniqueStorageKey: 'Smoke alarm sensor' }, this.config.debug);
630
+ this.smoke = new MatterbridgeEndpoint([smokeCoAlarm, bridgedNode], { uniqueStorageKey: 'Smoke alarm sensor' }, this.config.debug);
663
631
  this.smoke.log.logName = 'Smoke alarm sensor';
664
632
  this.smoke.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);
665
- this.smoke.addDeviceTypeWithClusterServer([smokeCoAlarm], [CarbonMonoxideConcentrationMeasurement.Cluster.id]);
633
+ this.smoke.createDefaultIdentifyClusterServer();
634
+ this.smoke.createDefaultSmokeCOAlarmClusterServer(SmokeCoAlarm.AlarmState.Normal, SmokeCoAlarm.AlarmState.Normal);
635
+ this.smoke.createDefaultCarbonMonoxideConcentrationMeasurementClusterServer(100);
666
636
  await this.registerDevice(this.smoke);
667
637
  this.bridgedDevices.set(this.smoke.deviceName ?? '', this.smoke);
668
- await this.smoke.setAttribute(SmokeCoAlarmCluster.id, 'smokeState', SmokeCoAlarm.AlarmState.Normal, this.smoke.log);
669
- await this.smoke.setAttribute(SmokeCoAlarmCluster.id, 'coState', SmokeCoAlarm.AlarmState.Normal, this.smoke.log);
670
- await this.smoke.setAttribute(CarbonMonoxideConcentrationMeasurement.Cluster.id, 'measuredValue', 100, this.smoke.log);
671
- this.airQuality = await this.createMutableDevice([airQualitySensor, bridgedNode], { uniqueStorageKey: 'Air quality sensor' }, this.config.debug);
638
+ this.airQuality = new MatterbridgeEndpoint([airQualitySensor, bridgedNode], { uniqueStorageKey: 'Air quality sensor' }, this.config.debug);
672
639
  this.airQuality.log.logName = 'Air quality Sensor';
673
640
  this.airQuality.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);
674
- this.airQuality.addDeviceTypeWithClusterServer([airQualitySensor], [
641
+ this.airQuality.addRequiredClusterServers();
642
+ this.airQuality.addClusterServers([
675
643
  TemperatureMeasurement.Cluster.id,
676
644
  RelativeHumidityMeasurement.Cluster.id,
677
645
  CarbonMonoxideConcentrationMeasurement.Cluster.id,
@@ -702,6 +670,7 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
702
670
  await this.airQuality.setAttribute(TotalVolatileOrganicCompoundsConcentrationMeasurement.Cluster.id, 'measuredValue', 100, this.airQuality.log);
703
671
  }
704
672
  async onConfigure() {
673
+ await super.onConfigure();
705
674
  this.log.info('onConfigure called');
706
675
  await this.switch?.setAttribute(OnOffCluster.id, 'onOff', false, this.switch.log);
707
676
  this.switch?.log.info('Set switch initial onOff to false');
@@ -745,7 +714,7 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
745
714
  let level = this.light?.getAttribute(LevelControlCluster.id, 'currentLevel', this.light.log);
746
715
  if (isValidBoolean(state) && isValidNumber(level, 0, 254)) {
747
716
  level += 10;
748
- if (level >= 250) {
717
+ if (level >= 230) {
749
718
  level = 1;
750
719
  await this.lightOnOff?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightOnOff.log);
751
720
  await this.dimmer?.setAttribute(OnOffCluster.id, 'onOff', false, this.dimmer.log);
@@ -777,9 +746,6 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
777
746
  this.log.info(`Set lights currentLevel to ${level}`);
778
747
  }
779
748
  }
780
- else {
781
- this.log.error(`Invalid state ${state} or level ${level}`);
782
- }
783
749
  }, 60 * 1000 + 200);
784
750
  await this.outlet?.setAttribute(OnOffCluster.id, 'onOff', false, this.outlet.log);
785
751
  this.outlet?.log.info('Set outlet initial onOff to false');
@@ -815,11 +781,11 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
815
781
  await this.thermoAuto?.setAttribute(ThermostatCluster.id, 'systemMode', Thermostat.SystemMode.Auto, this.thermoAuto.log);
816
782
  this.thermoAuto?.log.info('Set thermostat initial localTemperature to 16°C and mode Auto');
817
783
  const temperature = this.thermoAuto?.getChildEndpointByName('Temperature');
818
- await this.thermoAuto?.setAttribute(TemperatureMeasurementCluster.id, 'measuredValue', 16 * 100, this.thermoAuto.log, temperature);
784
+ await temperature?.setAttribute(TemperatureMeasurementCluster.id, 'measuredValue', 16 * 100, this.thermoAuto?.log);
819
785
  const humidity = this.thermoAuto?.getChildEndpointByName('Humidity');
820
- await this.thermoAuto?.setAttribute(RelativeHumidityMeasurementCluster.id, 'measuredValue', 50 * 100, this.thermoAuto.log, humidity);
786
+ await humidity?.setAttribute(RelativeHumidityMeasurementCluster.id, 'measuredValue', 50 * 100, this.thermoAuto?.log);
821
787
  const flow = this.thermoAuto?.getChildEndpointByName('Flow');
822
- await this.thermoAuto?.setAttribute(FlowMeasurementCluster.id, 'measuredValue', 10, this.thermoAuto.log, flow);
788
+ await flow?.setAttribute(FlowMeasurementCluster.id, 'measuredValue', 10, this.thermoAuto?.log);
823
789
  this.thermoAuto?.log.info('Set thermostat ext temperature to 16°C, ext humidity to 50% and ext valve flow to 10');
824
790
  this.thermoInterval = setInterval(async () => {
825
791
  let temperature = this.thermoAuto?.getAttribute(ThermostatCluster.id, 'localTemperature', this.thermoAuto.log);
@@ -832,18 +798,19 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
832
798
  const tempOut = this.thermoHeat?.getChildEndpointByName('TemperatureOUT');
833
799
  await tempOut?.setAttribute(TemperatureMeasurementCluster.id, 'measuredValue', temperature - 400, this.thermoHeat?.log);
834
800
  await this.thermoCool?.setAttribute(ThermostatCluster.id, 'localTemperature', temperature, this.thermoCool.log);
835
- const temp = this.thermoAuto?.getChildEndpointByName('Temperature');
836
- await this.thermoAuto?.setAttribute(TemperatureMeasurementCluster.id, 'measuredValue', temperature, this.thermoAuto.log, temp);
837
- const humidity = this.thermoAuto?.getChildEndpointByName('Humidity');
838
- await this.thermoAuto?.setAttribute(RelativeHumidityMeasurementCluster.id, 'measuredValue', 50 * 100, this.thermoAuto.log, humidity);
839
- const flow = this.thermoAuto?.getChildEndpointByName('Flow');
840
- await this.thermoAuto?.setAttribute(FlowMeasurementCluster.id, 'measuredValue', 10, this.thermoAuto.log, flow);
801
+ const temp = this.thermoCool?.getChildEndpointByName('Temperature');
802
+ await temp?.setAttribute(TemperatureMeasurementCluster.id, 'measuredValue', temperature, this.thermoCool?.log);
803
+ const humidity = this.thermoCool?.getChildEndpointByName('Humidity');
804
+ await humidity?.setAttribute(RelativeHumidityMeasurementCluster.id, 'measuredValue', 50 * 100, this.thermoCool?.log);
805
+ const flow = this.thermoCool?.getChildEndpointByName('Flow');
806
+ await flow?.setAttribute(FlowMeasurementCluster.id, 'measuredValue', 10, this.thermoCool?.log);
841
807
  this.thermoAuto?.log.info(`Set thermostat localTemperature to ${temperature / 100}°C`);
842
808
  this.thermoHeat?.log.info(`Set thermostat localTemperature to ${temperature / 100}°C`);
843
809
  this.thermoCool?.log.info(`Set thermostat localTemperature to ${temperature / 100}°C`);
844
810
  }
845
811
  }, 60 * 1000 + 600);
846
812
  await this.airConditioner?.setAttribute(OnOffCluster.id, 'onOff', true, this.airConditioner.log);
813
+ await this.airConditioner?.setAttribute(ThermostatCluster.id, 'localTemperature', 2000, this.airConditioner.log);
847
814
  this.airConditionerInterval = setInterval(async () => {
848
815
  let temperature = this.airConditioner?.getAttribute(ThermostatCluster.id, 'localTemperature', this.airConditioner.log);
849
816
  if (isValidNumber(temperature, 1600, 2400)) {
@@ -919,7 +886,6 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
919
886
  }, 60 * 1000 + 1100);
920
887
  }
921
888
  async onShutdown(reason) {
922
- this.log.info('onShutdown called with reason:', reason ?? 'none');
923
889
  clearInterval(this.switchInterval);
924
890
  clearInterval(this.lightInterval);
925
891
  clearInterval(this.outletInterval);
@@ -933,6 +899,8 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
933
899
  clearInterval(this.smokeInterval);
934
900
  clearInterval(this.airQualityInterval);
935
901
  clearInterval(this.airConditionerInterval);
902
+ await super.onShutdown(reason);
903
+ this.log.info('onShutdown called with reason:', reason ?? 'none');
936
904
  if (this.config.unregisterOnShutdown === true)
937
905
  await this.unregisterAllDevices();
938
906
  }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "matterbridge-example-dynamic-platform",
3
- "version": "1.1.4-dev.1",
3
+ "version": "1.1.5-dev.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "matterbridge-example-dynamic-platform",
9
- "version": "1.1.4-dev.1",
9
+ "version": "1.1.5-dev.1",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "node-ansi-logger": "3.0.0",
@@ -34,10 +34,13 @@
34
34
  }
35
35
  },
36
36
  "node_modules/node-persist": {
37
- "version": "4.0.3",
38
- "resolved": "https://registry.npmjs.org/node-persist/-/node-persist-4.0.3.tgz",
39
- "integrity": "sha512-0gDy86TNShzfbpUKFbH8KJFjoovuUgVh/FqL4jrJWYz0cET76Uohl118utG/Ft6wl4sHOPXdRSY7eXH5kVY06w==",
37
+ "version": "4.0.4",
38
+ "resolved": "https://registry.npmjs.org/node-persist/-/node-persist-4.0.4.tgz",
39
+ "integrity": "sha512-8sPAz/7tw1mCCc8xBG4f0wi+flHkSSgQeX998iQ75Pu27evA6UUWCjSE7xnrYTg2q33oU5leJ061EKPDv6BocQ==",
40
40
  "license": "MIT",
41
+ "dependencies": {
42
+ "p-limit": "^3.1.0"
43
+ },
41
44
  "engines": {
42
45
  "node": ">=10.12.0"
43
46
  }
@@ -57,6 +60,33 @@
57
60
  "type": "buymeacoffee",
58
61
  "url": "https://www.buymeacoffee.com/luligugithub"
59
62
  }
63
+ },
64
+ "node_modules/p-limit": {
65
+ "version": "3.1.0",
66
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
67
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
68
+ "license": "MIT",
69
+ "dependencies": {
70
+ "yocto-queue": "^0.1.0"
71
+ },
72
+ "engines": {
73
+ "node": ">=10"
74
+ },
75
+ "funding": {
76
+ "url": "https://github.com/sponsors/sindresorhus"
77
+ }
78
+ },
79
+ "node_modules/yocto-queue": {
80
+ "version": "0.1.0",
81
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
82
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
83
+ "license": "MIT",
84
+ "engines": {
85
+ "node": ">=10"
86
+ },
87
+ "funding": {
88
+ "url": "https://github.com/sponsors/sindresorhus"
89
+ }
60
90
  }
61
91
  }
62
92
  }
package/package.json CHANGED
@@ -1,12 +1,11 @@
1
1
  {
2
2
  "name": "matterbridge-example-dynamic-platform",
3
- "version": "1.1.4-dev.1",
3
+ "version": "1.1.5-dev.1",
4
4
  "description": "Matterbridge dynamic plugin",
5
5
  "author": "https://github.com/Luligu",
6
6
  "license": "MIT",
7
7
  "type": "module",
8
8
  "main": "dist/index.js",
9
- "types": "dist/index.d.ts",
10
9
  "repository": {
11
10
  "type": "git",
12
11
  "url": "git+https://github.com/Luligu/matterbridge-example-dynamic-platform.git"