matterbridge-example-dynamic-platform 1.0.24 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/platform.d.ts +2 -1
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +224 -209
- package/dist/platform.js.map +1 -1
- package/npm-shrinkwrap.json +2 -3
- package/package.json +1 -34
package/dist/platform.js
CHANGED
@@ -31,23 +31,35 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
|
|
31
31
|
rainInterval;
|
32
32
|
smokeInterval;
|
33
33
|
airQualityInterval;
|
34
|
+
async createMutableDevice(definition, options = {}, debug = false) {
|
35
|
+
let device;
|
36
|
+
const matterbridge = await import('matterbridge');
|
37
|
+
if ('edge' in this.matterbridge && this.matterbridge.edge === true && 'MatterbridgeEndpoint' in matterbridge) {
|
38
|
+
// Dynamically resolve the MatterbridgeEndpoint class from the imported module and instantiate it without throwing a TypeScript error for old versions of Matterbridge
|
39
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
40
|
+
device = new matterbridge.MatterbridgeEndpoint(definition, options, debug);
|
41
|
+
}
|
42
|
+
else
|
43
|
+
device = new MatterbridgeDevice(definition, options, debug);
|
44
|
+
return device;
|
45
|
+
}
|
34
46
|
constructor(matterbridge, log, config) {
|
35
47
|
super(matterbridge, log, config);
|
36
48
|
// Verify that Matterbridge is the correct version
|
37
|
-
if (this.verifyMatterbridgeVersion === undefined || typeof this.verifyMatterbridgeVersion !== 'function' || !this.verifyMatterbridgeVersion('1.6.
|
38
|
-
throw new Error(`This plugin requires Matterbridge version >= "1.6.
|
49
|
+
if (this.verifyMatterbridgeVersion === undefined || typeof this.verifyMatterbridgeVersion !== 'function' || !this.verifyMatterbridgeVersion('1.6.2')) {
|
50
|
+
throw new Error(`This plugin requires Matterbridge version >= "1.6.2". Please update Matterbridge from ${this.matterbridge.matterbridgeVersion} to the latest version in the frontend."`);
|
39
51
|
}
|
40
52
|
this.log.info('Initializing platform:', this.config.name);
|
41
53
|
}
|
42
54
|
async onStart(reason) {
|
43
55
|
this.log.info('onStart called with reason:', reason ?? 'none');
|
44
56
|
// Create a switch device
|
45
|
-
this.switch =
|
57
|
+
this.switch = await this.createMutableDevice([onOffSwitch, bridgedNode], { uniqueStorageKey: 'Switch' }, this.config.debug);
|
46
58
|
this.switch.log.logName = 'Switch';
|
47
59
|
this.switch.createDefaultIdentifyClusterServer();
|
48
60
|
this.switch.createDefaultGroupsClusterServer();
|
49
61
|
this.switch.createDefaultScenesClusterServer();
|
50
|
-
this.switch.createDefaultBridgedDeviceBasicInformationClusterServer('Switch', '0x23452164', 0xfff1, '
|
62
|
+
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);
|
51
63
|
this.switch.createDefaultOnOffClusterServer();
|
52
64
|
this.switch.addDeviceType(powerSource);
|
53
65
|
this.switch.createDefaultPowerSourceRechargeableBatteryClusterServer(70);
|
@@ -56,20 +68,20 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
|
|
56
68
|
this.log.info(`Command identify called identifyTime:${identifyTime}`);
|
57
69
|
});
|
58
70
|
this.switch.addCommandHandler('on', async () => {
|
59
|
-
this.switch?.setAttribute(OnOffCluster.id, 'onOff', true, this.switch.log, this.switch);
|
71
|
+
await this.switch?.setAttribute(OnOffCluster.id, 'onOff', true, this.switch.log, this.switch);
|
60
72
|
this.switch?.log.info('Command on called');
|
61
73
|
});
|
62
74
|
this.switch.addCommandHandler('off', async () => {
|
63
|
-
this.switch?.setAttribute(OnOffCluster.id, 'onOff', false, this.switch.log, this.switch);
|
75
|
+
await this.switch?.setAttribute(OnOffCluster.id, 'onOff', false, this.switch.log, this.switch);
|
64
76
|
this.switch?.log.info('Command off called');
|
65
77
|
});
|
66
78
|
// Create a on off light device
|
67
|
-
this.lightOnOff =
|
79
|
+
this.lightOnOff = await this.createMutableDevice([DeviceTypes.ON_OFF_LIGHT, bridgedNode], { uniqueStorageKey: 'Light (on/off)' }, this.config.debug);
|
68
80
|
this.lightOnOff.log.logName = 'Light (on/off)';
|
69
81
|
this.lightOnOff.createDefaultIdentifyClusterServer();
|
70
82
|
this.lightOnOff.createDefaultGroupsClusterServer();
|
71
83
|
this.lightOnOff.createDefaultScenesClusterServer();
|
72
|
-
this.lightOnOff.createDefaultBridgedDeviceBasicInformationClusterServer('Light (on/off)', '0x2342375564', 0xfff1, '
|
84
|
+
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);
|
73
85
|
this.lightOnOff.createDefaultOnOffClusterServer();
|
74
86
|
this.lightOnOff.addDeviceType(powerSource);
|
75
87
|
this.lightOnOff.createDefaultPowerSourceWiredClusterServer();
|
@@ -78,20 +90,20 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
|
|
78
90
|
this.lightOnOff?.log.info(`Command identify called identifyTime:${identifyTime}`);
|
79
91
|
});
|
80
92
|
this.lightOnOff.addCommandHandler('on', async () => {
|
81
|
-
this.light?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightOnOff?.log, this.lightOnOff);
|
93
|
+
await this.light?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightOnOff?.log, this.lightOnOff);
|
82
94
|
this.lightOnOff?.log.info('Command on called');
|
83
95
|
});
|
84
96
|
this.lightOnOff.addCommandHandler('off', async () => {
|
85
|
-
this.light?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightOnOff?.log, this.lightOnOff);
|
97
|
+
await this.light?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightOnOff?.log, this.lightOnOff);
|
86
98
|
this.lightOnOff?.log.info('Command off called');
|
87
99
|
});
|
88
100
|
// Create a dimmer device
|
89
|
-
this.dimmer =
|
101
|
+
this.dimmer = await this.createMutableDevice([DeviceTypes.DIMMABLE_LIGHT, bridgedNode], { uniqueStorageKey: 'Dimmer' }, this.config.debug);
|
90
102
|
this.dimmer.log.logName = 'Dimmer';
|
91
103
|
this.dimmer.createDefaultIdentifyClusterServer();
|
92
104
|
this.dimmer.createDefaultGroupsClusterServer();
|
93
105
|
this.dimmer.createDefaultScenesClusterServer();
|
94
|
-
this.dimmer.createDefaultBridgedDeviceBasicInformationClusterServer('Dimmer', '0x234554564', 0xfff1, '
|
106
|
+
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);
|
95
107
|
this.dimmer.createDefaultOnOffClusterServer();
|
96
108
|
this.dimmer.createDefaultLevelControlClusterServer();
|
97
109
|
this.dimmer.addDeviceType(powerSource);
|
@@ -101,28 +113,28 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
|
|
101
113
|
this.dimmer?.log.info(`Command identify called identifyTime:${identifyTime}`);
|
102
114
|
});
|
103
115
|
this.dimmer.addCommandHandler('on', async () => {
|
104
|
-
this.dimmer?.setAttribute(OnOffCluster.id, 'onOff', true, this.dimmer.log, this.dimmer);
|
116
|
+
await this.dimmer?.setAttribute(OnOffCluster.id, 'onOff', true, this.dimmer.log, this.dimmer);
|
105
117
|
this.dimmer?.log.info('Command on called');
|
106
118
|
});
|
107
119
|
this.dimmer.addCommandHandler('off', async () => {
|
108
|
-
this.dimmer?.setAttribute(OnOffCluster.id, 'onOff', false, this.dimmer.log, this.dimmer);
|
120
|
+
await this.dimmer?.setAttribute(OnOffCluster.id, 'onOff', false, this.dimmer.log, this.dimmer);
|
109
121
|
this.dimmer?.log.info('Command off called');
|
110
122
|
});
|
111
123
|
this.dimmer.addCommandHandler('moveToLevel', async ({ request: { level } }) => {
|
112
|
-
this.dimmer?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.dimmer.log, this.dimmer);
|
124
|
+
await this.dimmer?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.dimmer.log, this.dimmer);
|
113
125
|
this.dimmer?.log.debug(`Command moveToLevel called request: ${level}`);
|
114
126
|
});
|
115
127
|
this.dimmer.addCommandHandler('moveToLevelWithOnOff', async ({ request: { level } }) => {
|
116
|
-
this.dimmer?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.dimmer.log, this.dimmer);
|
128
|
+
await this.dimmer?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.dimmer.log, this.dimmer);
|
117
129
|
this.dimmer?.log.debug(`Command moveToLevelWithOnOff called request: ${level}`);
|
118
130
|
});
|
119
131
|
// Create a light device
|
120
|
-
this.light =
|
132
|
+
this.light = await this.createMutableDevice([DeviceTypes.COLOR_TEMPERATURE_LIGHT, bridgedNode], { uniqueStorageKey: 'Light (XY, HS and CT)' }, this.config.debug);
|
121
133
|
this.light.log.logName = 'Light (XY, HS and CT)';
|
122
134
|
this.light.createDefaultIdentifyClusterServer();
|
123
135
|
this.light.createDefaultGroupsClusterServer();
|
124
136
|
this.light.createDefaultScenesClusterServer();
|
125
|
-
this.light.createDefaultBridgedDeviceBasicInformationClusterServer('Light (XY, HS and CT)', '0x23480564', 0xfff1, '
|
137
|
+
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);
|
126
138
|
this.light.createDefaultOnOffClusterServer();
|
127
139
|
this.light.createDefaultLevelControlClusterServer();
|
128
140
|
this.light.createDefaultColorControlClusterServer();
|
@@ -133,54 +145,54 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
|
|
133
145
|
this.light?.log.info(`Command identify called identifyTime:${identifyTime}`);
|
134
146
|
});
|
135
147
|
this.light.addCommandHandler('on', async () => {
|
136
|
-
this.light?.setAttribute(OnOffCluster.id, 'onOff', true, this.light?.log, this.light);
|
148
|
+
await this.light?.setAttribute(OnOffCluster.id, 'onOff', true, this.light?.log, this.light);
|
137
149
|
this.light?.log.info('Command on called');
|
138
150
|
});
|
139
151
|
this.light.addCommandHandler('off', async () => {
|
140
|
-
this.light?.setAttribute(OnOffCluster.id, 'onOff', false, this.light?.log, this.light);
|
152
|
+
await this.light?.setAttribute(OnOffCluster.id, 'onOff', false, this.light?.log, this.light);
|
141
153
|
this.light?.log.info('Command off called');
|
142
154
|
});
|
143
155
|
this.light.addCommandHandler('moveToLevel', async ({ request: { level } }) => {
|
144
|
-
this.light?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.light?.log, this.light);
|
156
|
+
await this.light?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.light?.log, this.light);
|
145
157
|
this.light?.log.debug(`Command moveToLevel called request: ${level}`);
|
146
158
|
});
|
147
159
|
this.light.addCommandHandler('moveToLevelWithOnOff', async ({ request: { level } }) => {
|
148
|
-
this.light?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.light?.log, this.light);
|
160
|
+
await this.light?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.light?.log, this.light);
|
149
161
|
this.light?.log.debug(`Command moveToLevelWithOnOff called request: ${level}`);
|
150
162
|
});
|
151
163
|
this.light.addCommandHandler('moveToColor', async ({ request: { colorX, colorY } }) => {
|
152
|
-
this.light?.setAttribute(ColorControlCluster.id, 'currentX', colorX, this.light?.log, this.light);
|
153
|
-
this.light?.setAttribute(ColorControlCluster.id, 'currentY', colorY, this.light?.log, this.light);
|
164
|
+
await this.light?.setAttribute(ColorControlCluster.id, 'currentX', colorX, this.light?.log, this.light);
|
165
|
+
await this.light?.setAttribute(ColorControlCluster.id, 'currentY', colorY, this.light?.log, this.light);
|
154
166
|
this.light?.log.debug(`Command moveToColor called request: X ${colorX / 65536} Y ${colorY / 65536}`);
|
155
167
|
});
|
156
168
|
this.light.addCommandHandler('moveToHueAndSaturation', async ({ request: { hue, saturation }, attributes: { currentHue, currentSaturation } }) => {
|
157
|
-
this.light?.setAttribute(ColorControlCluster.id, 'currentHue', hue, this.light?.log, this.light);
|
158
|
-
this.light?.setAttribute(ColorControlCluster.id, 'currentSaturation', saturation, this.light?.log, this.light);
|
169
|
+
await this.light?.setAttribute(ColorControlCluster.id, 'currentHue', hue, this.light?.log, this.light);
|
170
|
+
await this.light?.setAttribute(ColorControlCluster.id, 'currentSaturation', saturation, this.light?.log, this.light);
|
159
171
|
this.light?.log.debug(`Command moveToHueAndSaturation called request: hue ${hue} saturation ${saturation} attributes: hue ${currentHue?.getLocal()} saturation ${currentSaturation?.getLocal()}`);
|
160
172
|
});
|
161
173
|
this.light.addCommandHandler('moveToHue', async ({ request: { hue }, attributes: { currentHue, currentSaturation } }) => {
|
162
|
-
this.light?.setAttribute(ColorControlCluster.id, 'currentHue', hue, this.light?.log, this.light);
|
174
|
+
await this.light?.setAttribute(ColorControlCluster.id, 'currentHue', hue, this.light?.log, this.light);
|
163
175
|
this.light?.log.debug(`Command moveToHue called request: hue ${hue} attributes: hue ${currentHue?.getLocal()} saturation ${currentSaturation?.getLocal()}`);
|
164
176
|
});
|
165
177
|
this.light.addCommandHandler('moveToSaturation', async ({ request: { saturation }, attributes: { currentHue, currentSaturation } }) => {
|
166
|
-
this.light?.setAttribute(ColorControlCluster.id, 'currentSaturation', saturation, this.light?.log, this.light);
|
178
|
+
await this.light?.setAttribute(ColorControlCluster.id, 'currentSaturation', saturation, this.light?.log, this.light);
|
167
179
|
this.light?.log.debug(`Command moveToSaturation called request: saturation ${saturation} attributes: hue ${currentHue?.getLocal()} saturation ${currentSaturation?.getLocal()}`);
|
168
180
|
});
|
169
181
|
this.light.addCommandHandler('moveToColorTemperature', async ({ request, attributes }) => {
|
170
|
-
this.light?.setAttribute(ColorControlCluster.id, 'colorTemperatureMireds', request.colorTemperatureMireds, this.light?.log, this.light);
|
182
|
+
await this.light?.setAttribute(ColorControlCluster.id, 'colorTemperatureMireds', request.colorTemperatureMireds, this.light?.log, this.light);
|
171
183
|
this.light?.log.debug(`Command moveToColorTemperature called request: ${request.colorTemperatureMireds} attributes: ${attributes.colorTemperatureMireds?.getLocal()}`);
|
172
184
|
});
|
173
185
|
// Create a light device with HS color control
|
174
|
-
this.lightHS =
|
186
|
+
this.lightHS = await this.createMutableDevice([DeviceTypes.COLOR_TEMPERATURE_LIGHT, bridgedNode], { uniqueStorageKey: 'Light (HS)' }, this.config.debug);
|
175
187
|
this.lightHS.log.logName = 'Light (HS)';
|
176
188
|
this.lightHS.createDefaultIdentifyClusterServer();
|
177
189
|
this.lightHS.createDefaultGroupsClusterServer();
|
178
190
|
this.lightHS.createDefaultScenesClusterServer();
|
179
|
-
this.lightHS.createDefaultBridgedDeviceBasicInformationClusterServer('Light (HS)', '0x25097564', 0xfff1, '
|
191
|
+
this.lightHS.createDefaultBridgedDeviceBasicInformationClusterServer('Light (HS)', '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);
|
180
192
|
this.lightHS.createDefaultOnOffClusterServer();
|
181
193
|
this.lightHS.createDefaultLevelControlClusterServer();
|
182
194
|
this.lightHS.createDefaultColorControlClusterServer();
|
183
|
-
this.lightHS.configureColorControlCluster(true, false, false, ColorControl.ColorMode.CurrentHueAndCurrentSaturation);
|
195
|
+
await this.lightHS.configureColorControlCluster(true, false, false, ColorControl.ColorMode.CurrentHueAndCurrentSaturation);
|
184
196
|
this.lightHS.addDeviceType(powerSource);
|
185
197
|
this.lightHS.createDefaultPowerSourceWiredClusterServer();
|
186
198
|
await this.registerDevice(this.lightHS);
|
@@ -188,45 +200,45 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
|
|
188
200
|
this.lightHS?.log.info(`Command identify called identifyTime:${identifyTime}`);
|
189
201
|
});
|
190
202
|
this.lightHS.addCommandHandler('on', async () => {
|
191
|
-
this.lightHS?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightHS?.log, this.lightHS);
|
203
|
+
await this.lightHS?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightHS?.log, this.lightHS);
|
192
204
|
this.lightHS?.log.info('Command on called');
|
193
205
|
});
|
194
206
|
this.lightHS.addCommandHandler('off', async () => {
|
195
|
-
this.lightHS?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightHS?.log, this.lightHS);
|
207
|
+
await this.lightHS?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightHS?.log, this.lightHS);
|
196
208
|
this.lightHS?.log.info('Command off called');
|
197
209
|
});
|
198
210
|
this.lightHS.addCommandHandler('moveToLevel', async ({ request: { level }, attributes: { currentLevel } }) => {
|
199
|
-
this.lightHS?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightHS?.log, this.lightHS);
|
211
|
+
await this.lightHS?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightHS?.log, this.lightHS);
|
200
212
|
this.lightHS?.log.debug(`Command moveToLevel called request: ${level} attributes: ${currentLevel?.getLocal()}`);
|
201
213
|
});
|
202
214
|
this.lightHS.addCommandHandler('moveToLevelWithOnOff', async ({ request: { level }, attributes: { currentLevel } }) => {
|
203
|
-
this.lightHS?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightHS?.log, this.lightHS);
|
215
|
+
await this.lightHS?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightHS?.log, this.lightHS);
|
204
216
|
this.lightHS?.log.debug(`Command moveToLevelWithOnOff called request: ${level} attributes: ${currentLevel?.getLocal()}`);
|
205
217
|
});
|
206
218
|
this.lightHS.addCommandHandler('moveToHueAndSaturation', async ({ request: { hue, saturation }, attributes: { currentHue, currentSaturation } }) => {
|
207
|
-
this.lightHS?.setAttribute(ColorControlCluster.id, 'currentHue', hue, this.lightHS?.log, this.lightHS);
|
208
|
-
this.lightHS?.setAttribute(ColorControlCluster.id, 'currentSaturation', saturation, this.lightHS?.log, this.lightHS);
|
219
|
+
await this.lightHS?.setAttribute(ColorControlCluster.id, 'currentHue', hue, this.lightHS?.log, this.lightHS);
|
220
|
+
await this.lightHS?.setAttribute(ColorControlCluster.id, 'currentSaturation', saturation, this.lightHS?.log, this.lightHS);
|
209
221
|
this.lightHS?.log.debug(`Command moveToHueAndSaturation called request: hue ${hue} saturation ${saturation} attributes: hue ${currentHue?.getLocal()} saturation ${currentSaturation?.getLocal()}`);
|
210
222
|
});
|
211
223
|
this.lightHS.addCommandHandler('moveToHue', async ({ request: { hue }, attributes: { currentHue, currentSaturation } }) => {
|
212
|
-
this.lightHS?.setAttribute(ColorControlCluster.id, 'currentHue', hue, this.lightHS?.log, this.lightHS);
|
224
|
+
await this.lightHS?.setAttribute(ColorControlCluster.id, 'currentHue', hue, this.lightHS?.log, this.lightHS);
|
213
225
|
this.lightHS?.log.debug(`Command moveToHue called request: hue ${hue} attributes: hue ${currentHue?.getLocal()} saturation ${currentSaturation?.getLocal()}`);
|
214
226
|
});
|
215
227
|
this.lightHS.addCommandHandler('moveToSaturation', async ({ request: { saturation }, attributes: { currentHue, currentSaturation } }) => {
|
216
|
-
this.lightHS?.setAttribute(ColorControlCluster.id, 'currentSaturation', saturation, this.lightHS?.log, this.lightHS);
|
228
|
+
await this.lightHS?.setAttribute(ColorControlCluster.id, 'currentSaturation', saturation, this.lightHS?.log, this.lightHS);
|
217
229
|
this.lightHS?.log.debug(`Command moveToSaturation called request: saturation ${saturation} attributes: hue ${currentHue?.getLocal()} saturation ${currentSaturation?.getLocal()}`);
|
218
230
|
});
|
219
231
|
// Create a light device with XY color control
|
220
|
-
this.lightXY =
|
232
|
+
this.lightXY = await this.createMutableDevice([DeviceTypes.COLOR_TEMPERATURE_LIGHT, bridgedNode], { uniqueStorageKey: 'Light (XY)' }, this.config.debug);
|
221
233
|
this.lightXY.log.logName = 'Light (XY)';
|
222
234
|
this.lightXY.createDefaultIdentifyClusterServer();
|
223
235
|
this.lightXY.createDefaultGroupsClusterServer();
|
224
236
|
this.lightXY.createDefaultScenesClusterServer();
|
225
|
-
this.lightXY.createDefaultBridgedDeviceBasicInformationClusterServer('Light (XY)', '0x23497564', 0xfff1, '
|
237
|
+
this.lightXY.createDefaultBridgedDeviceBasicInformationClusterServer('Light (XY)', '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);
|
226
238
|
this.lightXY.createDefaultOnOffClusterServer();
|
227
239
|
this.lightXY.createDefaultLevelControlClusterServer();
|
228
240
|
this.lightXY.createDefaultColorControlClusterServer();
|
229
|
-
this.lightXY.configureColorControlCluster(false, true, false, ColorControl.ColorMode.CurrentXAndCurrentY);
|
241
|
+
await this.lightXY.configureColorControlCluster(false, true, false, ColorControl.ColorMode.CurrentXAndCurrentY);
|
230
242
|
this.lightXY.addDeviceType(powerSource);
|
231
243
|
this.lightXY.createDefaultPowerSourceWiredClusterServer();
|
232
244
|
await this.registerDevice(this.lightXY);
|
@@ -234,37 +246,37 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
|
|
234
246
|
this.lightXY?.log.info(`Command identify called identifyTime:${identifyTime}`);
|
235
247
|
});
|
236
248
|
this.lightXY.addCommandHandler('on', async () => {
|
237
|
-
this.lightXY?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightXY?.log, this.lightXY);
|
249
|
+
await this.lightXY?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightXY?.log, this.lightXY);
|
238
250
|
this.lightXY?.log.info('Command on called');
|
239
251
|
});
|
240
252
|
this.lightXY.addCommandHandler('off', async () => {
|
241
|
-
this.lightXY?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightXY?.log, this.lightXY);
|
253
|
+
await this.lightXY?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightXY?.log, this.lightXY);
|
242
254
|
this.lightXY?.log.info('Command off called');
|
243
255
|
});
|
244
256
|
this.lightXY.addCommandHandler('moveToLevel', async ({ request: { level } }) => {
|
245
|
-
this.lightXY?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightXY?.log, this.lightXY);
|
257
|
+
await this.lightXY?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightXY?.log, this.lightXY);
|
246
258
|
this.lightXY?.log.debug(`Command moveToLevel called request: ${level}`);
|
247
259
|
});
|
248
260
|
this.lightXY.addCommandHandler('moveToLevelWithOnOff', async ({ request: { level } }) => {
|
249
|
-
this.lightXY?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightXY?.log, this.lightXY);
|
261
|
+
await this.lightXY?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightXY?.log, this.lightXY);
|
250
262
|
this.lightXY?.log.debug(`Command moveToLevelWithOnOff called request: ${level}`);
|
251
263
|
});
|
252
264
|
this.lightXY.addCommandHandler('moveToColor', async ({ request: { colorX, colorY } }) => {
|
253
|
-
this.lightXY?.setAttribute(ColorControlCluster.id, 'currentX', colorX, this.light?.log, this.light);
|
254
|
-
this.lightXY?.setAttribute(ColorControlCluster.id, 'currentY', colorY, this.light?.log, this.light);
|
265
|
+
await this.lightXY?.setAttribute(ColorControlCluster.id, 'currentX', colorX, this.light?.log, this.light);
|
266
|
+
await this.lightXY?.setAttribute(ColorControlCluster.id, 'currentY', colorY, this.light?.log, this.light);
|
255
267
|
this.lightXY?.log.debug(`Command moveToColor called request: X ${colorX / 65536} Y ${colorY / 65536}`);
|
256
268
|
});
|
257
269
|
// Create a light device with CT color control
|
258
|
-
this.lightCT =
|
270
|
+
this.lightCT = await this.createMutableDevice([DeviceTypes.COLOR_TEMPERATURE_LIGHT, bridgedNode], { uniqueStorageKey: 'Light (CT)' }, this.config.debug);
|
259
271
|
this.lightCT.log.logName = 'Light (CT)';
|
260
272
|
this.lightCT.createDefaultIdentifyClusterServer();
|
261
273
|
this.lightCT.createDefaultGroupsClusterServer();
|
262
274
|
this.lightCT.createDefaultScenesClusterServer();
|
263
|
-
this.lightCT.createDefaultBridgedDeviceBasicInformationClusterServer('Light (CT)', '0x23480749', 0xfff1, '
|
275
|
+
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);
|
264
276
|
this.lightCT.createDefaultOnOffClusterServer();
|
265
277
|
this.lightCT.createDefaultLevelControlClusterServer();
|
266
278
|
this.lightCT.createDefaultColorControlClusterServer();
|
267
|
-
this.lightCT.configureColorControlCluster(false, false, true, ColorControl.ColorMode.ColorTemperatureMireds);
|
279
|
+
await this.lightCT.configureColorControlCluster(false, false, true, ColorControl.ColorMode.ColorTemperatureMireds);
|
268
280
|
this.lightCT.addDeviceType(powerSource);
|
269
281
|
this.lightCT.createDefaultPowerSourceReplaceableBatteryClusterServer(70);
|
270
282
|
await this.registerDevice(this.lightCT);
|
@@ -272,32 +284,32 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
|
|
272
284
|
this.lightCT?.log.info(`Command identify called identifyTime:${identifyTime}`);
|
273
285
|
});
|
274
286
|
this.lightCT.addCommandHandler('on', async () => {
|
275
|
-
this.lightCT?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightCT?.log, this.lightCT);
|
287
|
+
await this.lightCT?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightCT?.log, this.lightCT);
|
276
288
|
this.lightCT?.log.info('Command on called');
|
277
289
|
});
|
278
290
|
this.lightCT.addCommandHandler('off', async () => {
|
279
|
-
this.lightCT?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightCT?.log, this.lightCT);
|
291
|
+
await this.lightCT?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightCT?.log, this.lightCT);
|
280
292
|
this.lightCT?.log.info('Command off called');
|
281
293
|
});
|
282
294
|
this.lightCT.addCommandHandler('moveToLevel', async ({ request: { level } }) => {
|
283
|
-
this.lightCT?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightCT?.log, this.lightCT);
|
295
|
+
await this.lightCT?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightCT?.log, this.lightCT);
|
284
296
|
this.lightCT?.log.debug(`Command moveToLevel called request: ${level}`);
|
285
297
|
});
|
286
298
|
this.lightCT.addCommandHandler('moveToLevelWithOnOff', async ({ request: { level } }) => {
|
287
|
-
this.lightCT?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightCT?.log, this.lightCT);
|
299
|
+
await this.lightCT?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightCT?.log, this.lightCT);
|
288
300
|
this.lightCT?.log.debug(`Command moveToLevelWithOnOff called request: ${level}`);
|
289
301
|
});
|
290
302
|
this.lightCT.addCommandHandler('moveToColorTemperature', async ({ request }) => {
|
291
|
-
this.lightCT?.setAttribute(ColorControlCluster.id, 'colorTemperatureMireds', request.colorTemperatureMireds, this.lightCT?.log, this.lightCT);
|
303
|
+
await this.lightCT?.setAttribute(ColorControlCluster.id, 'colorTemperatureMireds', request.colorTemperatureMireds, this.lightCT?.log, this.lightCT);
|
292
304
|
this.lightCT?.log.debug(`Command moveToColorTemperature called request: ${request.colorTemperatureMireds}`);
|
293
305
|
});
|
294
306
|
// Create an outlet device
|
295
|
-
this.outlet =
|
307
|
+
this.outlet = await this.createMutableDevice([DeviceTypes.ON_OFF_PLUGIN_UNIT, bridgedNode], { uniqueStorageKey: 'Outlet' }, this.config.debug);
|
296
308
|
this.outlet.log.logName = 'Outlet';
|
297
309
|
this.outlet.createDefaultIdentifyClusterServer();
|
298
310
|
this.outlet.createDefaultGroupsClusterServer();
|
299
311
|
this.outlet.createDefaultScenesClusterServer();
|
300
|
-
this.outlet.createDefaultBridgedDeviceBasicInformationClusterServer('Outlet', '0x29252164', 0xfff1, '
|
312
|
+
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);
|
301
313
|
this.outlet.createDefaultOnOffClusterServer();
|
302
314
|
this.outlet.addDeviceType(powerSource);
|
303
315
|
this.outlet.createDefaultPowerSourceWiredClusterServer();
|
@@ -306,21 +318,21 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
|
|
306
318
|
this.outlet?.log.info(`Command identify called identifyTime:${identifyTime}`);
|
307
319
|
});
|
308
320
|
this.outlet.addCommandHandler('on', async () => {
|
309
|
-
this.outlet?.setAttribute(OnOffCluster.id, 'onOff', true, this.outlet?.log, this.outlet);
|
321
|
+
await this.outlet?.setAttribute(OnOffCluster.id, 'onOff', true, this.outlet?.log, this.outlet);
|
310
322
|
this.outlet?.log.info('Command on called');
|
311
323
|
});
|
312
324
|
this.outlet.addCommandHandler('off', async () => {
|
313
|
-
this.outlet?.setAttribute(OnOffCluster.id, 'onOff', false, this.outlet?.log, this.outlet);
|
325
|
+
await this.outlet?.setAttribute(OnOffCluster.id, 'onOff', false, this.outlet?.log, this.outlet);
|
314
326
|
this.outlet?.log.info('Command off called');
|
315
327
|
});
|
316
328
|
// Create a window covering device
|
317
329
|
// Matter uses 10000 = fully closed 0 = fully opened
|
318
|
-
this.cover =
|
330
|
+
this.cover = await this.createMutableDevice([DeviceTypes.WINDOW_COVERING, bridgedNode], { uniqueStorageKey: 'Cover' }, this.config.debug);
|
319
331
|
this.cover.log.logName = 'Cover';
|
320
332
|
this.cover.createDefaultIdentifyClusterServer();
|
321
333
|
this.cover.createDefaultGroupsClusterServer();
|
322
334
|
this.cover.createDefaultScenesClusterServer();
|
323
|
-
this.cover.createDefaultBridgedDeviceBasicInformationClusterServer('Cover', '0x01020564', 0xfff1, '
|
335
|
+
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);
|
324
336
|
this.cover.createDefaultWindowCoveringClusterServer();
|
325
337
|
this.cover.addDeviceType(powerSource);
|
326
338
|
this.cover.createDefaultPowerSourceRechargeableBatteryClusterServer(86);
|
@@ -332,26 +344,26 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
|
|
332
344
|
this.cover?.log.info(`Command identify called identifyTime:${identifyTime}`);
|
333
345
|
});
|
334
346
|
this.cover.addCommandHandler('stopMotion', async () => {
|
335
|
-
this.cover?.setWindowCoveringTargetAsCurrentAndStopped();
|
347
|
+
await this.cover?.setWindowCoveringTargetAsCurrentAndStopped();
|
336
348
|
this.cover?.log.info(`Command stopMotion called`);
|
337
349
|
});
|
338
350
|
this.cover.addCommandHandler('downOrClose', async () => {
|
339
|
-
this.cover?.setWindowCoveringCurrentTargetStatus(10000, 10000, WindowCovering.MovementStatus.Stopped);
|
351
|
+
await this.cover?.setWindowCoveringCurrentTargetStatus(10000, 10000, WindowCovering.MovementStatus.Stopped);
|
340
352
|
this.cover?.log.info(`Command downOrClose called`);
|
341
353
|
});
|
342
354
|
this.cover.addCommandHandler('upOrOpen', async () => {
|
343
|
-
this.cover?.setWindowCoveringCurrentTargetStatus(0, 0, WindowCovering.MovementStatus.Stopped);
|
355
|
+
await this.cover?.setWindowCoveringCurrentTargetStatus(0, 0, WindowCovering.MovementStatus.Stopped);
|
344
356
|
this.cover?.log.info(`Command upOrOpen called`);
|
345
357
|
});
|
346
358
|
this.cover.addCommandHandler('goToLiftPercentage', async ({ request: { liftPercent100thsValue } }) => {
|
347
|
-
this.cover?.setWindowCoveringCurrentTargetStatus(liftPercent100thsValue, liftPercent100thsValue, WindowCovering.MovementStatus.Stopped);
|
359
|
+
await this.cover?.setWindowCoveringCurrentTargetStatus(liftPercent100thsValue, liftPercent100thsValue, WindowCovering.MovementStatus.Stopped);
|
348
360
|
this.cover?.log.info(`Command goToLiftPercentage ${liftPercent100thsValue} called`);
|
349
361
|
});
|
350
362
|
// Create a lock device
|
351
|
-
this.lock =
|
363
|
+
this.lock = await this.createMutableDevice([DeviceTypes.DOOR_LOCK, bridgedNode], { uniqueStorageKey: 'Lock' }, this.config.debug);
|
352
364
|
this.lock.log.logName = 'Lock';
|
353
365
|
this.lock.createDefaultIdentifyClusterServer();
|
354
|
-
this.lock.createDefaultBridgedDeviceBasicInformationClusterServer('Lock', '0x96352164', 0xfff1, '
|
366
|
+
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);
|
355
367
|
this.lock.createDefaultDoorLockClusterServer();
|
356
368
|
this.lock.addDeviceType(powerSource);
|
357
369
|
this.lock.createDefaultPowerSourceRechargeableBatteryClusterServer(30);
|
@@ -360,20 +372,20 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
|
|
360
372
|
this.lock?.log.info(`Command identify called identifyTime:${identifyTime}`);
|
361
373
|
});
|
362
374
|
this.lock.addCommandHandler('lockDoor', async () => {
|
363
|
-
this.lock?.setAttribute(DoorLockCluster.id, 'lockState', DoorLock.LockState.Locked, this.lock?.log, this.lock);
|
375
|
+
await this.lock?.setAttribute(DoorLockCluster.id, 'lockState', DoorLock.LockState.Locked, this.lock?.log, this.lock);
|
364
376
|
this.lock?.log.info('Command lockDoor called');
|
365
377
|
});
|
366
378
|
this.lock.addCommandHandler('unlockDoor', async () => {
|
367
|
-
this.lock?.setAttribute(DoorLockCluster.id, 'lockState', DoorLock.LockState.Unlocked, this.lock?.log, this.lock);
|
379
|
+
await this.lock?.setAttribute(DoorLockCluster.id, 'lockState', DoorLock.LockState.Unlocked, this.lock?.log, this.lock);
|
368
380
|
this.lock?.log.info('Command unlockDoor called');
|
369
381
|
});
|
370
382
|
// Create a thermostat device
|
371
|
-
this.thermo =
|
383
|
+
this.thermo = await this.createMutableDevice([DeviceTypes.THERMOSTAT, bridgedNode], { uniqueStorageKey: 'Thermostat' }, this.config.debug);
|
372
384
|
this.thermo.log.logName = 'Thermostat';
|
373
385
|
this.thermo.createDefaultIdentifyClusterServer();
|
374
386
|
this.thermo.createDefaultGroupsClusterServer();
|
375
387
|
this.thermo.createDefaultScenesClusterServer();
|
376
|
-
this.thermo.createDefaultBridgedDeviceBasicInformationClusterServer('Thermostat', '0x96382164', 0xfff1, '
|
388
|
+
this.thermo.createDefaultBridgedDeviceBasicInformationClusterServer('Thermostat', '0x96382164', 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);
|
377
389
|
this.thermo.createDefaultThermostatClusterServer(20, 18, 22);
|
378
390
|
this.thermo.addDeviceType(powerSource);
|
379
391
|
this.thermo.createDefaultPowerSourceRechargeableBatteryClusterServer(70);
|
@@ -392,12 +404,12 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
|
|
392
404
|
this.thermo?.log.info(`Command setpointRaiseLower called with mode: ${lookupSetpointAdjustMode[mode]} amount: ${amount / 10}`);
|
393
405
|
if (mode === Thermostat.SetpointRaiseLowerMode.Heat || mode === Thermostat.SetpointRaiseLowerMode.Both) {
|
394
406
|
const setpoint = this.thermo?.getAttribute(ThermostatCluster.id, 'occupiedHeatingSetpoint', this.thermo?.log) / 100 + amount / 10;
|
395
|
-
this.thermo?.setAttribute(ThermostatCluster.id, 'occupiedHeatingSetpoint', setpoint * 100, this.thermo?.log);
|
407
|
+
await this.thermo?.setAttribute(ThermostatCluster.id, 'occupiedHeatingSetpoint', setpoint * 100, this.thermo?.log);
|
396
408
|
this.thermo?.log.info('Set occupiedHeatingSetpoint:', setpoint);
|
397
409
|
}
|
398
410
|
if (mode === Thermostat.SetpointRaiseLowerMode.Cool || mode === Thermostat.SetpointRaiseLowerMode.Both) {
|
399
411
|
const setpoint = this.thermo?.getAttribute(ThermostatCluster.id, 'occupiedCoolingSetpoint', this.thermo?.log) / 100 + amount / 10;
|
400
|
-
this.thermo?.setAttribute(ThermostatCluster.id, 'occupiedCoolingSetpoint', setpoint * 100, this.thermo?.log);
|
412
|
+
await this.thermo?.setAttribute(ThermostatCluster.id, 'occupiedCoolingSetpoint', setpoint * 100, this.thermo?.log);
|
401
413
|
this.thermo?.log.info('Set occupiedCoolingSetpoint:', setpoint);
|
402
414
|
}
|
403
415
|
});
|
@@ -412,73 +424,73 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
|
|
412
424
|
this.thermo?.log.info('Subscribe occupiedCoolingSetpoint called with:', value / 100);
|
413
425
|
}, this.thermo.log, this.thermo);
|
414
426
|
// Create a fan device
|
415
|
-
this.fan =
|
427
|
+
this.fan = await this.createMutableDevice([DeviceTypes.FAN, bridgedNode], { uniqueStorageKey: 'Fan' }, this.config.debug);
|
416
428
|
this.fan.log.logName = 'Fan';
|
417
|
-
this.fan.createDefaultBridgedDeviceBasicInformationClusterServer('Fan', 'serial_980545631228', 0xfff1, '
|
429
|
+
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);
|
418
430
|
this.fan.addDeviceTypeWithClusterServer([DeviceTypes.FAN], []);
|
419
431
|
await this.registerDevice(this.fan);
|
420
432
|
const fanModeLookup = ['Off', 'Low', 'Medium', 'High', 'On', 'Auto', 'Smart'];
|
421
|
-
this.
|
433
|
+
this.fan.subscribeAttribute(FanControlCluster.id, 'fanMode', async (newValue, oldValue) => {
|
422
434
|
this.fan?.log.info(`Fan mode changed from ${fanModeLookup[oldValue]} to ${fanModeLookup[newValue]}`);
|
423
435
|
if (newValue === FanControl.FanMode.Off) {
|
424
|
-
this.fan?.setAttribute(FanControlCluster.id, 'percentCurrent', 0, this.fan?.log);
|
436
|
+
await this.fan?.setAttribute(FanControlCluster.id, 'percentCurrent', 0, this.fan?.log);
|
425
437
|
}
|
426
438
|
else if (newValue === FanControl.FanMode.Low) {
|
427
|
-
this.fan?.setAttribute(FanControlCluster.id, 'percentCurrent', 33, this.fan?.log);
|
439
|
+
await this.fan?.setAttribute(FanControlCluster.id, 'percentCurrent', 33, this.fan?.log);
|
428
440
|
}
|
429
441
|
else if (newValue === FanControl.FanMode.Medium) {
|
430
|
-
this.fan?.setAttribute(FanControlCluster.id, 'percentCurrent', 66, this.fan?.log);
|
442
|
+
await this.fan?.setAttribute(FanControlCluster.id, 'percentCurrent', 66, this.fan?.log);
|
431
443
|
}
|
432
444
|
else if (newValue === FanControl.FanMode.High) {
|
433
|
-
this.fan?.setAttribute(FanControlCluster.id, 'percentCurrent', 100, this.fan?.log);
|
445
|
+
await this.fan?.setAttribute(FanControlCluster.id, 'percentCurrent', 100, this.fan?.log);
|
434
446
|
}
|
435
447
|
else if (newValue === FanControl.FanMode.On) {
|
436
|
-
this.fan?.setAttribute(FanControlCluster.id, 'percentCurrent', 100, this.fan?.log);
|
448
|
+
await this.fan?.setAttribute(FanControlCluster.id, 'percentCurrent', 100, this.fan?.log);
|
437
449
|
}
|
438
450
|
else if (newValue === FanControl.FanMode.Auto) {
|
439
|
-
this.fan?.setAttribute(FanControlCluster.id, 'percentCurrent', 50, this.fan?.log);
|
451
|
+
await this.fan?.setAttribute(FanControlCluster.id, 'percentCurrent', 50, this.fan?.log);
|
440
452
|
}
|
441
453
|
}, this.fan.log, this.fan);
|
442
|
-
this.
|
454
|
+
this.fan.subscribeAttribute(FanControlCluster.id, 'percentSetting', async (newValue, oldValue) => {
|
443
455
|
this.fan?.log.info(`Percent setting changed from ${oldValue} to ${newValue}`);
|
444
456
|
if (isValidNumber(newValue, 0, 100))
|
445
|
-
this.fan?.setAttribute(FanControlCluster.id, 'percentCurrent', newValue, this.fan?.log);
|
457
|
+
await this.fan?.setAttribute(FanControlCluster.id, 'percentCurrent', newValue, this.fan?.log);
|
446
458
|
}, this.fan.log, this.fan);
|
447
|
-
this.
|
459
|
+
this.fan.subscribeAttribute(FanControlCluster.id, 'speedSetting', async (newValue, oldValue) => {
|
448
460
|
this.fan?.log.info(`Speed setting changed from ${oldValue} to ${newValue}`);
|
449
461
|
if (isValidNumber(newValue, 0, 100))
|
450
|
-
this.fan?.setAttribute(FanControlCluster.id, 'speedCurrent', newValue, this.fan?.log);
|
462
|
+
await this.fan?.setAttribute(FanControlCluster.id, 'speedCurrent', newValue, this.fan?.log);
|
451
463
|
}, this.fan.log, this.fan);
|
452
|
-
this.waterLeak =
|
464
|
+
this.waterLeak = await this.createMutableDevice([waterLeakDetector, bridgedNode], { uniqueStorageKey: 'Water leak detector' }, this.config.debug);
|
453
465
|
this.waterLeak.log.logName = 'Water leak detector';
|
454
|
-
this.waterLeak.createDefaultBridgedDeviceBasicInformationClusterServer('Water leak detector', 'serial_98745631222', 0xfff1, '
|
466
|
+
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);
|
455
467
|
this.waterLeak.addDeviceTypeWithClusterServer([waterLeakDetector], [BooleanStateConfiguration.Cluster.id]);
|
456
468
|
await this.registerDevice(this.waterLeak);
|
457
|
-
this.waterLeak.setAttribute(BooleanStateCluster.id, 'stateValue', false, this.waterLeak.log);
|
458
|
-
this.waterFreeze =
|
469
|
+
await this.waterLeak.setAttribute(BooleanStateCluster.id, 'stateValue', false, this.waterLeak.log);
|
470
|
+
this.waterFreeze = await this.createMutableDevice([waterFreezeDetector, bridgedNode], { uniqueStorageKey: 'Water freeze detector' }, this.config.debug);
|
459
471
|
this.waterFreeze.log.logName = 'Water freeze detector';
|
460
|
-
this.waterFreeze.createDefaultBridgedDeviceBasicInformationClusterServer('Water freeze detector', 'serial_98745631223', 0xfff1, '
|
472
|
+
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);
|
461
473
|
this.waterFreeze.addDeviceTypeWithClusterServer([waterFreezeDetector], [BooleanStateConfiguration.Cluster.id]);
|
462
474
|
await this.registerDevice(this.waterFreeze);
|
463
|
-
this.waterFreeze.setAttribute(BooleanStateCluster.id, 'stateValue', false, this.waterFreeze.log);
|
464
|
-
this.rain =
|
475
|
+
await this.waterFreeze.setAttribute(BooleanStateCluster.id, 'stateValue', false, this.waterFreeze.log);
|
476
|
+
this.rain = await this.createMutableDevice([rainSensor, bridgedNode], { uniqueStorageKey: 'Rain sensor' }, this.config.debug);
|
465
477
|
this.rain.log.logName = 'Rain sensor';
|
466
|
-
this.rain.createDefaultBridgedDeviceBasicInformationClusterServer('Rain sensor', 'serial_98745631224', 0xfff1, '
|
478
|
+
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);
|
467
479
|
this.rain.addDeviceTypeWithClusterServer([rainSensor], [BooleanStateConfiguration.Cluster.id]);
|
468
480
|
await this.registerDevice(this.rain);
|
469
|
-
this.rain.setAttribute(BooleanStateCluster.id, 'stateValue', false, this.rain.log);
|
470
|
-
this.smoke =
|
481
|
+
await this.rain.setAttribute(BooleanStateCluster.id, 'stateValue', false, this.rain.log);
|
482
|
+
this.smoke = await this.createMutableDevice([smokeCoAlarm, bridgedNode], { uniqueStorageKey: 'Smoke alarm sensor' }, this.config.debug);
|
471
483
|
this.smoke.log.logName = 'Smoke alarm sensor';
|
472
|
-
this.smoke.createDefaultBridgedDeviceBasicInformationClusterServer('Smoke alarm sensor', 'serial_94745631225', 0xfff1, '
|
484
|
+
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);
|
473
485
|
this.smoke.addDeviceTypeWithClusterServer([smokeCoAlarm], [CarbonMonoxideConcentrationMeasurement.Cluster.id]);
|
474
486
|
await this.registerDevice(this.smoke);
|
475
|
-
this.smoke.setAttribute(SmokeCoAlarmCluster.id, 'smokeState', SmokeCoAlarm.AlarmState.Normal, this.smoke.log);
|
476
|
-
this.smoke.setAttribute(SmokeCoAlarmCluster.id, 'coState', SmokeCoAlarm.AlarmState.Normal, this.smoke.log);
|
477
|
-
this.smoke.setAttribute(CarbonMonoxideConcentrationMeasurement.Cluster.id, 'measuredValue', 100, this.smoke.log);
|
487
|
+
await this.smoke.setAttribute(SmokeCoAlarmCluster.id, 'smokeState', SmokeCoAlarm.AlarmState.Normal, this.smoke.log);
|
488
|
+
await this.smoke.setAttribute(SmokeCoAlarmCluster.id, 'coState', SmokeCoAlarm.AlarmState.Normal, this.smoke.log);
|
489
|
+
await this.smoke.setAttribute(CarbonMonoxideConcentrationMeasurement.Cluster.id, 'measuredValue', 100, this.smoke.log);
|
478
490
|
// Create an airQuality device
|
479
|
-
this.airQuality =
|
491
|
+
this.airQuality = await this.createMutableDevice([airQualitySensor, bridgedNode], { uniqueStorageKey: 'Air quality sensor' }, this.config.debug);
|
480
492
|
this.airQuality.log.logName = 'Air quality Sensor';
|
481
|
-
this.airQuality.createDefaultBridgedDeviceBasicInformationClusterServer('Air quality sensor', 'serial_987484318322', 0xfff1, '
|
493
|
+
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);
|
482
494
|
this.airQuality.addDeviceTypeWithClusterServer([airQualitySensor], [
|
483
495
|
TemperatureMeasurement.Cluster.id,
|
484
496
|
RelativeHumidityMeasurement.Cluster.id,
|
@@ -494,236 +506,239 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
|
|
494
506
|
TotalVolatileOrganicCompoundsConcentrationMeasurement.Cluster.id,
|
495
507
|
]);
|
496
508
|
await this.registerDevice(this.airQuality);
|
497
|
-
this.airQuality.setAttribute(AirQuality.Cluster.id, 'airQuality', AirQuality.AirQualityEnum.Good, this.airQuality.log);
|
498
|
-
this.airQuality.setAttribute(TemperatureMeasurement.Cluster.id, 'measuredValue', 2150, this.airQuality.log);
|
499
|
-
this.airQuality.setAttribute(RelativeHumidityMeasurement.Cluster.id, 'measuredValue', 5500, this.airQuality.log);
|
500
|
-
this.airQuality.setAttribute(CarbonMonoxideConcentrationMeasurement.Cluster.id, 'measuredValue', 10, this.airQuality.log);
|
501
|
-
this.airQuality.setAttribute(CarbonDioxideConcentrationMeasurement.Cluster.id, 'measuredValue', 400, this.airQuality.log);
|
502
|
-
this.airQuality.setAttribute(NitrogenDioxideConcentrationMeasurement.Cluster.id, 'measuredValue', 1, this.airQuality.log);
|
503
|
-
this.airQuality.setAttribute(OzoneConcentrationMeasurement.Cluster.id, 'measuredValue', 1, this.airQuality.log);
|
504
|
-
this.airQuality.setAttribute(FormaldehydeConcentrationMeasurement.Cluster.id, 'measuredValue', 1, this.airQuality.log);
|
505
|
-
this.airQuality.setAttribute(Pm1ConcentrationMeasurement.Cluster.id, 'measuredValue', 100, this.airQuality.log);
|
506
|
-
this.airQuality.setAttribute(Pm25ConcentrationMeasurement.Cluster.id, 'measuredValue', 100, this.airQuality.log);
|
507
|
-
this.airQuality.setAttribute(Pm10ConcentrationMeasurement.Cluster.id, 'measuredValue', 100, this.airQuality.log);
|
508
|
-
this.airQuality.setAttribute(RadonConcentrationMeasurement.Cluster.id, 'measuredValue', 100, this.airQuality.log);
|
509
|
-
this.airQuality.setAttribute(TotalVolatileOrganicCompoundsConcentrationMeasurement.Cluster.id, 'measuredValue', 100, this.airQuality.log);
|
509
|
+
await this.airQuality.setAttribute(AirQuality.Cluster.id, 'airQuality', AirQuality.AirQualityEnum.Good, this.airQuality.log);
|
510
|
+
await this.airQuality.setAttribute(TemperatureMeasurement.Cluster.id, 'measuredValue', 2150, this.airQuality.log);
|
511
|
+
await this.airQuality.setAttribute(RelativeHumidityMeasurement.Cluster.id, 'measuredValue', 5500, this.airQuality.log);
|
512
|
+
await this.airQuality.setAttribute(CarbonMonoxideConcentrationMeasurement.Cluster.id, 'measuredValue', 10, this.airQuality.log);
|
513
|
+
await this.airQuality.setAttribute(CarbonDioxideConcentrationMeasurement.Cluster.id, 'measuredValue', 400, this.airQuality.log);
|
514
|
+
await this.airQuality.setAttribute(NitrogenDioxideConcentrationMeasurement.Cluster.id, 'measuredValue', 1, this.airQuality.log);
|
515
|
+
await this.airQuality.setAttribute(OzoneConcentrationMeasurement.Cluster.id, 'measuredValue', 1, this.airQuality.log);
|
516
|
+
await this.airQuality.setAttribute(FormaldehydeConcentrationMeasurement.Cluster.id, 'measuredValue', 1, this.airQuality.log);
|
517
|
+
await this.airQuality.setAttribute(Pm1ConcentrationMeasurement.Cluster.id, 'measuredValue', 100, this.airQuality.log);
|
518
|
+
await this.airQuality.setAttribute(Pm25ConcentrationMeasurement.Cluster.id, 'measuredValue', 100, this.airQuality.log);
|
519
|
+
await this.airQuality.setAttribute(Pm10ConcentrationMeasurement.Cluster.id, 'measuredValue', 100, this.airQuality.log);
|
520
|
+
await this.airQuality.setAttribute(RadonConcentrationMeasurement.Cluster.id, 'measuredValue', 100, this.airQuality.log);
|
521
|
+
await this.airQuality.setAttribute(TotalVolatileOrganicCompoundsConcentrationMeasurement.Cluster.id, 'measuredValue', 100, this.airQuality.log);
|
510
522
|
}
|
511
523
|
async onConfigure() {
|
512
524
|
this.log.info('onConfigure called');
|
513
525
|
// Set switch to off
|
514
|
-
this.switch?.setAttribute(OnOffCluster.id, 'onOff', false, this.switch.log);
|
526
|
+
await this.switch?.setAttribute(OnOffCluster.id, 'onOff', false, this.switch.log);
|
515
527
|
this.switch?.log.info('Set switch initial onOff to false');
|
516
528
|
// Toggle switch onOff every minute
|
517
|
-
this.switchInterval = setInterval(() => {
|
529
|
+
this.switchInterval = setInterval(async () => {
|
518
530
|
const status = this.switch?.getAttribute(OnOffCluster.id, 'onOff', this.switch.log);
|
519
531
|
if (isValidBoolean(status)) {
|
520
|
-
this.switch?.setAttribute(OnOffCluster.id, 'onOff', !status, this.switch.log);
|
532
|
+
await this.switch?.setAttribute(OnOffCluster.id, 'onOff', !status, this.switch.log);
|
521
533
|
this.switch?.log.info(`Set switch onOff to ${!status}`);
|
522
534
|
}
|
523
535
|
}, 60 * 1000 + 100);
|
524
536
|
// Set light on/off to off
|
525
|
-
this.lightOnOff?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightOnOff.log);
|
537
|
+
await this.lightOnOff?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightOnOff.log);
|
526
538
|
this.lightOnOff?.log.info('Set light initial onOff to false.');
|
527
539
|
// Set light on/off to off
|
528
|
-
this.dimmer?.setAttribute(OnOffCluster.id, 'onOff', false, this.dimmer.log);
|
529
|
-
this.dimmer?.setAttribute(LevelControlCluster.id, 'currentLevel', 0, this.dimmer.log);
|
540
|
+
await this.dimmer?.setAttribute(OnOffCluster.id, 'onOff', false, this.dimmer.log);
|
541
|
+
await this.dimmer?.setAttribute(LevelControlCluster.id, 'currentLevel', 0, this.dimmer.log);
|
530
542
|
this.dimmer?.log.info('Set dimmer initial onOff to false, currentLevel to 0.');
|
531
543
|
// Set light to off, level to 0 and hue to 0 and saturation to 50% (pink color)
|
532
|
-
this.light?.setAttribute(OnOffCluster.id, 'onOff', false, this.light.log);
|
533
|
-
this.light?.setAttribute(LevelControlCluster.id, 'currentLevel', 0, this.light.log);
|
534
|
-
this.light?.setAttribute(ColorControlCluster.id, 'currentHue', 0, this.light.log);
|
535
|
-
this.light?.setAttribute(ColorControlCluster.id, 'currentSaturation', 128, this.light.log);
|
536
|
-
this.light?.configureColorControlMode(ColorControl.ColorMode.CurrentHueAndCurrentSaturation);
|
544
|
+
await this.light?.setAttribute(OnOffCluster.id, 'onOff', false, this.light.log);
|
545
|
+
await this.light?.setAttribute(LevelControlCluster.id, 'currentLevel', 0, this.light.log);
|
546
|
+
await this.light?.setAttribute(ColorControlCluster.id, 'currentHue', 0, this.light.log);
|
547
|
+
await this.light?.setAttribute(ColorControlCluster.id, 'currentSaturation', 128, this.light.log);
|
548
|
+
await this.light?.configureColorControlMode(ColorControl.ColorMode.CurrentHueAndCurrentSaturation);
|
537
549
|
this.light?.log.info('Set light initial onOff to false, currentLevel to 0, hue to 0 and saturation to 50%.');
|
538
550
|
// Set light XY to true, level to 100% and XY to red
|
539
|
-
this.lightXY?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightXY.log);
|
540
|
-
this.lightXY?.setAttribute(LevelControlCluster.id, 'currentLevel', 254, this.lightXY.log);
|
541
|
-
this.lightXY?.setAttribute(ColorControlCluster.id, 'currentX', 0.7006 * 65536, this.lightXY.log);
|
542
|
-
this.lightXY?.setAttribute(ColorControlCluster.id, 'currentY', 0.2993 * 65536, this.lightXY.log);
|
543
|
-
this.lightXY?.configureColorControlMode(ColorControl.ColorMode.CurrentXAndCurrentY);
|
551
|
+
await this.lightXY?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightXY.log);
|
552
|
+
await this.lightXY?.setAttribute(LevelControlCluster.id, 'currentLevel', 254, this.lightXY.log);
|
553
|
+
await this.lightXY?.setAttribute(ColorControlCluster.id, 'currentX', 0.7006 * 65536, this.lightXY.log);
|
554
|
+
await this.lightXY?.setAttribute(ColorControlCluster.id, 'currentY', 0.2993 * 65536, this.lightXY.log);
|
555
|
+
await this.lightXY?.configureColorControlMode(ColorControl.ColorMode.CurrentXAndCurrentY);
|
544
556
|
this.lightXY?.log.info('Set light XY initial onOff to true, currentLevel to 254, X to 0.7006 and Y to 0.2993.');
|
545
557
|
// Set light HS to off, level to 0 and hue to 0 and saturation to 50% (pink color)
|
546
|
-
this.lightHS?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightHS.log);
|
547
|
-
this.lightHS?.setAttribute(LevelControlCluster.id, 'currentLevel', 0, this.lightHS.log);
|
548
|
-
this.lightHS?.setAttribute(ColorControlCluster.id, 'currentHue', 0, this.lightHS.log);
|
549
|
-
this.lightHS?.setAttribute(ColorControlCluster.id, 'currentSaturation', 128, this.lightHS.log);
|
550
|
-
this.lightHS?.configureColorControlMode(ColorControl.ColorMode.CurrentHueAndCurrentSaturation);
|
558
|
+
await this.lightHS?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightHS.log);
|
559
|
+
await this.lightHS?.setAttribute(LevelControlCluster.id, 'currentLevel', 0, this.lightHS.log);
|
560
|
+
await this.lightHS?.setAttribute(ColorControlCluster.id, 'currentHue', 0, this.lightHS.log);
|
561
|
+
await this.lightHS?.setAttribute(ColorControlCluster.id, 'currentSaturation', 128, this.lightHS.log);
|
562
|
+
await this.lightHS?.configureColorControlMode(ColorControl.ColorMode.CurrentHueAndCurrentSaturation);
|
551
563
|
this.lightHS?.log.info('Set light HS initial onOff to false, currentLevel to 0, hue to 0 and saturation to 50%.');
|
552
564
|
// Set light CT to true, level to 50% and colorTemperatureMireds to 250
|
553
|
-
this.lightCT?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightCT.log);
|
554
|
-
this.lightCT?.setAttribute(LevelControlCluster.id, 'currentLevel', 128, this.lightCT.log);
|
555
|
-
this.lightCT?.setAttribute(ColorControlCluster.id, 'colorTemperatureMireds', 250, this.lightCT.log);
|
556
|
-
this.lightCT?.configureColorControlMode(ColorControl.ColorMode.ColorTemperatureMireds);
|
565
|
+
await this.lightCT?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightCT.log);
|
566
|
+
await this.lightCT?.setAttribute(LevelControlCluster.id, 'currentLevel', 128, this.lightCT.log);
|
567
|
+
await this.lightCT?.setAttribute(ColorControlCluster.id, 'colorTemperatureMireds', 250, this.lightCT.log);
|
568
|
+
await this.lightCT?.configureColorControlMode(ColorControl.ColorMode.ColorTemperatureMireds);
|
557
569
|
this.lightCT?.log.info('Set light CT initial onOff to true, currentLevel to 128, colorTemperatureMireds to 250.');
|
558
|
-
this.lightInterval = setInterval(() => {
|
570
|
+
this.lightInterval = setInterval(async () => {
|
559
571
|
const state = this.light?.getAttribute(OnOffCluster.id, 'onOff', this.light.log);
|
560
572
|
let level = this.light?.getAttribute(LevelControlCluster.id, 'currentLevel', this.light.log);
|
561
573
|
if (isValidBoolean(state) && isValidNumber(level, 0, 254)) {
|
562
574
|
level += 10;
|
563
575
|
if (level > 254) {
|
564
576
|
level = 0;
|
565
|
-
this.lightOnOff?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightOnOff.log);
|
566
|
-
this.dimmer?.setAttribute(OnOffCluster.id, 'onOff', false, this.dimmer.log);
|
567
|
-
this.light?.setAttribute(OnOffCluster.id, 'onOff', false, this.light.log);
|
568
|
-
this.lightXY?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightXY.log);
|
569
|
-
this.lightHS?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightHS.log);
|
570
|
-
this.lightCT?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightCT.log);
|
577
|
+
await this.lightOnOff?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightOnOff.log);
|
578
|
+
await this.dimmer?.setAttribute(OnOffCluster.id, 'onOff', false, this.dimmer.log);
|
579
|
+
await this.light?.setAttribute(OnOffCluster.id, 'onOff', false, this.light.log);
|
580
|
+
await this.lightXY?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightXY.log);
|
581
|
+
await this.lightHS?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightHS.log);
|
582
|
+
await this.lightCT?.setAttribute(OnOffCluster.id, 'onOff', false, this.lightCT.log);
|
571
583
|
this.log.info('Set lights onOff to false');
|
572
|
-
this.dimmer?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.dimmer.log);
|
573
|
-
this.light?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.light.log);
|
574
|
-
this.lightXY?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightXY.log);
|
575
|
-
this.lightHS?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightHS.log);
|
576
|
-
this.lightCT?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightCT.log);
|
584
|
+
await this.dimmer?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.dimmer.log);
|
585
|
+
await this.light?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.light.log);
|
586
|
+
await this.lightXY?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightXY.log);
|
587
|
+
await this.lightHS?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightHS.log);
|
588
|
+
await this.lightCT?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightCT.log);
|
577
589
|
this.log.info(`Set lights currentLevel to ${level}`);
|
578
590
|
}
|
579
591
|
else {
|
580
|
-
this.lightOnOff?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightOnOff?.log);
|
581
|
-
this.dimmer?.setAttribute(OnOffCluster.id, 'onOff', true, this.dimmer.log);
|
582
|
-
this.light?.setAttribute(OnOffCluster.id, 'onOff', true, this.light.log);
|
583
|
-
this.lightXY?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightXY.log);
|
584
|
-
this.lightHS?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightHS.log);
|
585
|
-
this.lightCT?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightCT.log);
|
592
|
+
await this.lightOnOff?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightOnOff?.log);
|
593
|
+
await this.dimmer?.setAttribute(OnOffCluster.id, 'onOff', true, this.dimmer.log);
|
594
|
+
await this.light?.setAttribute(OnOffCluster.id, 'onOff', true, this.light.log);
|
595
|
+
await this.lightXY?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightXY.log);
|
596
|
+
await this.lightHS?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightHS.log);
|
597
|
+
await this.lightCT?.setAttribute(OnOffCluster.id, 'onOff', true, this.lightCT.log);
|
586
598
|
this.log.info('Set lights onOff to true');
|
587
|
-
this.dimmer?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.dimmer.log);
|
588
|
-
this.light?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.light.log);
|
589
|
-
this.lightXY?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightXY.log);
|
590
|
-
this.lightHS?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightHS.log);
|
591
|
-
this.lightCT?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightCT.log);
|
599
|
+
await this.dimmer?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.dimmer.log);
|
600
|
+
await this.light?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.light.log);
|
601
|
+
await this.lightXY?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightXY.log);
|
602
|
+
await this.lightHS?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightHS.log);
|
603
|
+
await this.lightCT?.setAttribute(LevelControlCluster.id, 'currentLevel', level, this.lightCT.log);
|
592
604
|
this.log.info(`Set lights currentLevel to ${level}`);
|
593
605
|
}
|
594
606
|
}
|
595
607
|
}, 60 * 1000 + 200);
|
596
608
|
// Set outlet to off
|
597
|
-
this.outlet?.setAttribute(OnOffCluster.id, 'onOff', false, this.outlet.log);
|
609
|
+
await this.outlet?.setAttribute(OnOffCluster.id, 'onOff', false, this.outlet.log);
|
598
610
|
this.outlet?.log.info('Set outlet initial onOff to false');
|
599
611
|
// Toggle outlet onOff every minute
|
600
|
-
this.outletInterval = setInterval(() => {
|
612
|
+
this.outletInterval = setInterval(async () => {
|
601
613
|
const state = this.outlet?.getAttribute(OnOffCluster.id, 'onOff', this.outlet.log);
|
602
614
|
if (isValidBoolean(state)) {
|
603
|
-
this.outlet?.setAttribute(OnOffCluster.id, 'onOff', !state, this.outlet.log);
|
615
|
+
await this.outlet?.setAttribute(OnOffCluster.id, 'onOff', !state, this.outlet.log);
|
604
616
|
this.outlet?.log.info(`Set outlet onOff to ${!state}`);
|
605
617
|
}
|
606
618
|
}, 60 * 1000 + 300);
|
607
619
|
// Set cover to target = current position and status to stopped (current position is persisted in the cluster)
|
608
|
-
this.cover?.setWindowCoveringTargetAsCurrentAndStopped();
|
620
|
+
await this.cover?.setWindowCoveringTargetAsCurrentAndStopped();
|
609
621
|
this.cover?.log.info('Set cover initial targetPositionLiftPercent100ths = currentPositionLiftPercent100ths and operationalStatus to Stopped.');
|
610
622
|
// Increment cover position every minute
|
611
|
-
this.coverInterval = setInterval(() => {
|
623
|
+
this.coverInterval = setInterval(async () => {
|
612
624
|
let position = this.cover?.getAttribute(WindowCoveringCluster.id, 'currentPositionLiftPercent100ths', this.cover.log);
|
613
625
|
if (isValidNumber(position, 0, 10000)) {
|
614
626
|
position = position > 9000 ? 0 : position + 1000;
|
615
|
-
this.cover?.setAttribute(WindowCoveringCluster.id, 'targetPositionLiftPercent100ths', position, this.cover.log);
|
616
|
-
this.cover?.setAttribute(WindowCoveringCluster.id, 'currentPositionLiftPercent100ths', position, this.cover.log);
|
617
|
-
this.cover?.setAttribute(WindowCoveringCluster.id, 'operationalStatus', { global: WindowCovering.MovementStatus.Stopped, lift: WindowCovering.MovementStatus.Stopped, tilt: WindowCovering.MovementStatus.Stopped }, this.cover.log);
|
627
|
+
await this.cover?.setAttribute(WindowCoveringCluster.id, 'targetPositionLiftPercent100ths', position, this.cover.log);
|
628
|
+
await this.cover?.setAttribute(WindowCoveringCluster.id, 'currentPositionLiftPercent100ths', position, this.cover.log);
|
629
|
+
await this.cover?.setAttribute(WindowCoveringCluster.id, 'operationalStatus', { global: WindowCovering.MovementStatus.Stopped, lift: WindowCovering.MovementStatus.Stopped, tilt: WindowCovering.MovementStatus.Stopped }, this.cover.log);
|
618
630
|
this.cover?.log.info(`Set cover current and target positionLiftPercent100ths to ${position} and operationalStatus to Stopped`);
|
619
631
|
}
|
620
632
|
}, 60 * 1000 + 400);
|
621
633
|
// Set lock to Locked
|
622
|
-
this.lock?.setAttribute(DoorLockCluster.id, 'lockState', DoorLock.LockState.Locked, this.lock.log);
|
634
|
+
await this.lock?.setAttribute(DoorLockCluster.id, 'lockState', DoorLock.LockState.Locked, this.lock.log);
|
623
635
|
this.lock?.log.info('Set lock initial lockState to Locked');
|
624
636
|
// Toggle lock every minute
|
625
|
-
this.lockInterval = setInterval(() => {
|
637
|
+
this.lockInterval = setInterval(async () => {
|
626
638
|
const status = this.lock?.getAttribute(DoorLockCluster.id, 'lockState', this.lock.log);
|
627
639
|
if (isValidNumber(status, DoorLock.LockState.Locked, DoorLock.LockState.Unlocked)) {
|
628
|
-
this.lock?.setAttribute(DoorLockCluster.id, 'lockState', status === DoorLock.LockState.Locked ? DoorLock.LockState.Unlocked : DoorLock.LockState.Locked, this.lock.log);
|
640
|
+
await this.lock?.setAttribute(DoorLockCluster.id, 'lockState', status === DoorLock.LockState.Locked ? DoorLock.LockState.Unlocked : DoorLock.LockState.Locked, this.lock.log);
|
629
641
|
this.lock?.log.info(`Set lock lockState to ${status === DoorLock.LockState.Locked ? 'Unlocked' : 'Locked'}`);
|
630
642
|
}
|
631
643
|
}, 60 * 1000 + 500);
|
632
644
|
// Set local to 16°C
|
633
|
-
this.thermo?.setAttribute(ThermostatCluster.id, 'localTemperature', 16 * 100, this.thermo.log);
|
634
|
-
this.thermo?.setAttribute(ThermostatCluster.id, 'systemMode', Thermostat.SystemMode.Auto, this.thermo.log);
|
645
|
+
await this.thermo?.setAttribute(ThermostatCluster.id, 'localTemperature', 16 * 100, this.thermo.log);
|
646
|
+
await this.thermo?.setAttribute(ThermostatCluster.id, 'systemMode', Thermostat.SystemMode.Auto, this.thermo.log);
|
635
647
|
this.thermo?.log.info('Set thermostat initial localTemperature to 16°C and mode Auto');
|
636
648
|
const temperature = this.thermo?.getChildEndpointByName('Temperature');
|
637
|
-
this.thermo?.setAttribute(TemperatureMeasurementCluster.id, 'measuredValue', 16 * 100, this.thermo.log, temperature);
|
649
|
+
await this.thermo?.setAttribute(TemperatureMeasurementCluster.id, 'measuredValue', 16 * 100, this.thermo.log, temperature);
|
638
650
|
const humidity = this.thermo?.getChildEndpointByName('Humidity');
|
639
|
-
this.thermo?.setAttribute(RelativeHumidityMeasurementCluster.id, 'measuredValue', 50 * 100, this.thermo.log, humidity);
|
651
|
+
await this.thermo?.setAttribute(RelativeHumidityMeasurementCluster.id, 'measuredValue', 50 * 100, this.thermo.log, humidity);
|
640
652
|
const flow = this.thermo?.getChildEndpointByName('Flow');
|
641
|
-
this.thermo?.setAttribute(FlowMeasurementCluster.id, 'measuredValue', 10, this.thermo.log, flow);
|
653
|
+
await this.thermo?.setAttribute(FlowMeasurementCluster.id, 'measuredValue', 10, this.thermo.log, flow);
|
642
654
|
this.thermo?.log.info('Set thermostat ext temperature to 16°C, ext humidity to 50% and ext valve flow to 10');
|
643
655
|
// Increment localTemperature every minute
|
644
|
-
this.thermoInterval = setInterval(() => {
|
656
|
+
this.thermoInterval = setInterval(async () => {
|
645
657
|
let temperature = this.thermo?.getAttribute(ThermostatCluster.id, 'localTemperature', this.thermo.log);
|
646
658
|
if (isValidNumber(temperature, 1600, 2400)) {
|
647
659
|
temperature = temperature + 100 > 2400 ? 1600 : temperature + 100;
|
648
|
-
this.thermo?.setAttribute(ThermostatCluster.id, 'localTemperature', temperature, this.thermo.log);
|
660
|
+
await this.thermo?.setAttribute(ThermostatCluster.id, 'localTemperature', temperature, this.thermo.log);
|
649
661
|
const temp = this.thermo?.getChildEndpointByName('Temperature');
|
650
|
-
this.thermo?.setAttribute(TemperatureMeasurementCluster.id, 'measuredValue', temperature, this.thermo.log, temp);
|
662
|
+
await this.thermo?.setAttribute(TemperatureMeasurementCluster.id, 'measuredValue', temperature, this.thermo.log, temp);
|
651
663
|
const humidity = this.thermo?.getChildEndpointByName('Humidity');
|
652
|
-
this.thermo?.setAttribute(RelativeHumidityMeasurementCluster.id, 'measuredValue', 50 * 100, this.thermo.log, humidity);
|
664
|
+
await this.thermo?.setAttribute(RelativeHumidityMeasurementCluster.id, 'measuredValue', 50 * 100, this.thermo.log, humidity);
|
653
665
|
const flow = this.thermo?.getChildEndpointByName('Flow');
|
654
|
-
this.thermo?.setAttribute(FlowMeasurementCluster.id, 'measuredValue', 10, this.thermo.log, flow);
|
666
|
+
await this.thermo?.setAttribute(FlowMeasurementCluster.id, 'measuredValue', 10, this.thermo.log, flow);
|
655
667
|
this.thermo?.log.info(`Set thermostat localTemperature to ${temperature / 100}°C`);
|
656
668
|
}
|
657
669
|
}, 60 * 1000 + 600);
|
658
670
|
// Set fan to auto
|
659
|
-
this.fan?.log.info('Set fan initial fanMode to Auto, percentCurrent to 50 and speedCurrent to 50');
|
660
|
-
this.fan?.setAttribute(FanControlCluster.id, 'fanMode', FanControl.FanMode.Auto, this.fan.log);
|
661
|
-
this.fan?.setAttribute(FanControlCluster.id, 'percentCurrent', 50, this.fan.log);
|
662
|
-
this.fan?.setAttribute(FanControlCluster.id, '
|
671
|
+
this.fan?.log.info('Set fan initial fanMode to Auto, percentCurrent and percentSetting to 50 and speedCurrent and speedSetting to 50');
|
672
|
+
await this.fan?.setAttribute(FanControlCluster.id, 'fanMode', FanControl.FanMode.Auto, this.fan.log);
|
673
|
+
await this.fan?.setAttribute(FanControlCluster.id, 'percentCurrent', 50, this.fan.log);
|
674
|
+
await this.fan?.setAttribute(FanControlCluster.id, 'percentSetting', 50, this.fan.log);
|
675
|
+
await this.fan?.setAttribute(FanControlCluster.id, 'speedCurrent', 50, this.fan.log);
|
676
|
+
await this.fan?.setAttribute(FanControlCluster.id, 'speedSetting', 50, this.fan.log);
|
663
677
|
// Increment fan percentCurrent every minute
|
664
|
-
this.fanInterval = setInterval(() => {
|
678
|
+
this.fanInterval = setInterval(async () => {
|
665
679
|
const mode = this.fan?.getAttribute(FanControlCluster.id, 'fanMode', this.fan.log);
|
666
680
|
let value = this.fan?.getAttribute(FanControlCluster.id, 'percentCurrent', this.fan.log);
|
667
681
|
if (isValidNumber(mode, FanControl.FanMode.Off, FanControl.FanMode.Auto) && mode === FanControl.FanMode.Auto && isValidNumber(value, 0, 100)) {
|
668
682
|
value = value + 10 >= 100 ? 0 : value + 10;
|
669
|
-
this.fan?.setAttribute(FanControlCluster.id, 'percentCurrent', value, this.fan.log);
|
670
|
-
this.fan?.
|
683
|
+
await this.fan?.setAttribute(FanControlCluster.id, 'percentCurrent', value, this.fan.log);
|
684
|
+
await this.fan?.setAttribute(FanControlCluster.id, 'percentSetting', value, this.fan.log);
|
685
|
+
this.fan?.log.info(`Set fan percentCurrent and percentSetting to ${value}`);
|
671
686
|
}
|
672
687
|
}, 60 * 1000 + 700);
|
673
688
|
// Set waterLeak to false
|
674
|
-
this.waterLeak?.setAttribute(BooleanStateCluster.id, 'stateValue', false, this.waterLeak.log);
|
689
|
+
await this.waterLeak?.setAttribute(BooleanStateCluster.id, 'stateValue', false, this.waterLeak.log);
|
675
690
|
// Toggle waterLeak every minute
|
676
|
-
this.waterLeakInterval = setInterval(() => {
|
691
|
+
this.waterLeakInterval = setInterval(async () => {
|
677
692
|
let value = this.waterLeak?.getAttribute(BooleanStateCluster.id, 'stateValue', this.waterLeak.log);
|
678
693
|
if (isValidBoolean(value)) {
|
679
694
|
value = !value;
|
680
|
-
this.waterLeak?.setAttribute(BooleanStateCluster.id, 'stateValue', value, this.waterLeak.log);
|
695
|
+
await this.waterLeak?.setAttribute(BooleanStateCluster.id, 'stateValue', value, this.waterLeak.log);
|
681
696
|
this.waterLeak?.log.info(`Set waterLeak stateValue to ${value}`);
|
682
697
|
}
|
683
698
|
}, 60 * 1000 + 800);
|
684
699
|
// Set waterFreeze to false
|
685
|
-
this.waterFreeze?.setAttribute(BooleanStateCluster.id, 'stateValue', false, this.waterFreeze.log);
|
700
|
+
await this.waterFreeze?.setAttribute(BooleanStateCluster.id, 'stateValue', false, this.waterFreeze.log);
|
686
701
|
// Toggle waterFreeze every minute
|
687
|
-
this.waterFreezeInterval = setInterval(() => {
|
702
|
+
this.waterFreezeInterval = setInterval(async () => {
|
688
703
|
let value = this.waterFreeze?.getAttribute(BooleanStateCluster.id, 'stateValue', this.waterFreeze.log);
|
689
704
|
if (isValidBoolean(value)) {
|
690
705
|
value = !value;
|
691
|
-
this.waterFreeze?.setAttribute(BooleanStateCluster.id, 'stateValue', value, this.waterFreeze.log);
|
706
|
+
await this.waterFreeze?.setAttribute(BooleanStateCluster.id, 'stateValue', value, this.waterFreeze.log);
|
692
707
|
this.waterFreeze?.log.info(`Set waterFreeze stateValue to ${value}`);
|
693
708
|
}
|
694
709
|
}, 60 * 1000 + 900);
|
695
710
|
// Set rain to false
|
696
|
-
this.rain?.setAttribute(BooleanStateCluster.id, 'stateValue', false, this.rain.log);
|
711
|
+
await this.rain?.setAttribute(BooleanStateCluster.id, 'stateValue', false, this.rain.log);
|
697
712
|
// Toggle rain every minute
|
698
|
-
this.rainInterval = setInterval(() => {
|
713
|
+
this.rainInterval = setInterval(async () => {
|
699
714
|
let value = this.rain?.getAttribute(BooleanStateCluster.id, 'stateValue', this.rain.log);
|
700
715
|
if (isValidBoolean(value)) {
|
701
716
|
value = !value;
|
702
|
-
this.rain?.setAttribute(BooleanStateCluster.id, 'stateValue', value, this.rain.log);
|
717
|
+
await this.rain?.setAttribute(BooleanStateCluster.id, 'stateValue', value, this.rain.log);
|
703
718
|
this.rain?.log.info(`Set rain stateValue to ${value}`);
|
704
719
|
}
|
705
720
|
}, 60 * 1000 + 1000);
|
706
721
|
// Set smoke to Normal
|
707
|
-
this.smoke?.setAttribute(SmokeCoAlarmCluster.id, 'smokeState', SmokeCoAlarm.AlarmState.Normal, this.smoke.log);
|
708
|
-
this.smoke?.setAttribute(SmokeCoAlarmCluster.id, 'coState', SmokeCoAlarm.AlarmState.Normal, this.smoke.log);
|
722
|
+
await this.smoke?.setAttribute(SmokeCoAlarmCluster.id, 'smokeState', SmokeCoAlarm.AlarmState.Normal, this.smoke.log);
|
723
|
+
await this.smoke?.setAttribute(SmokeCoAlarmCluster.id, 'coState', SmokeCoAlarm.AlarmState.Normal, this.smoke.log);
|
709
724
|
// Toggle smoke every minute
|
710
|
-
this.smokeInterval = setInterval(() => {
|
725
|
+
this.smokeInterval = setInterval(async () => {
|
711
726
|
let value = this.smoke?.getAttribute(SmokeCoAlarmCluster.id, 'smokeState', this.smoke.log);
|
712
727
|
if (isValidNumber(value, SmokeCoAlarm.AlarmState.Normal, SmokeCoAlarm.AlarmState.Critical)) {
|
713
728
|
value = value === SmokeCoAlarm.AlarmState.Normal ? SmokeCoAlarm.AlarmState.Critical : SmokeCoAlarm.AlarmState.Normal;
|
714
|
-
this.smoke?.setAttribute(SmokeCoAlarmCluster.id, 'smokeState', value, this.smoke.log);
|
715
|
-
this.smoke?.setAttribute(SmokeCoAlarmCluster.id, 'coState', value, this.smoke.log);
|
729
|
+
await this.smoke?.setAttribute(SmokeCoAlarmCluster.id, 'smokeState', value, this.smoke.log);
|
730
|
+
await this.smoke?.setAttribute(SmokeCoAlarmCluster.id, 'coState', value, this.smoke.log);
|
716
731
|
this.smoke?.log.info(`Set smoke smokeState and coState to ${value}`);
|
717
732
|
}
|
718
733
|
}, 60 * 1000 + 1100);
|
719
734
|
// Set air quality to Normal
|
720
735
|
this.airQuality?.setAttribute(AirQualityCluster.id, 'airQuality', AirQuality.AirQualityEnum.Good, this.airQuality.log);
|
721
736
|
// Toggle air quality every minute
|
722
|
-
this.airQualityInterval = setInterval(() => {
|
737
|
+
this.airQualityInterval = setInterval(async () => {
|
723
738
|
let value = this.airQuality?.getAttribute(AirQualityCluster.id, 'airQuality', this.airQuality?.log);
|
724
739
|
if (isValidNumber(value, AirQuality.AirQualityEnum.Good, AirQuality.AirQualityEnum.ExtremelyPoor)) {
|
725
740
|
value = value >= AirQuality.AirQualityEnum.ExtremelyPoor ? AirQuality.AirQualityEnum.Good : value + 1;
|
726
|
-
this.airQuality?.setAttribute(AirQualityCluster.id, 'airQuality', value, this.airQuality.log);
|
741
|
+
await this.airQuality?.setAttribute(AirQualityCluster.id, 'airQuality', value, this.airQuality.log);
|
727
742
|
this.smoke?.log.info(`Set air quality to ${value}`);
|
728
743
|
}
|
729
744
|
}, 60 * 1000 + 1100);
|