matterbridge-example-dynamic-platform 2.0.12 → 2.0.13-dev-20260302-e8d75fe

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
@@ -26,12 +26,41 @@ If you like this project and find it useful, please consider giving it a star on
26
26
 
27
27
  <a href="https://www.buymeacoffee.com/luligugithub"><img src="https://matterbridge.io/assets/bmc-button.svg" alt="Buy me a coffee" width="120"></a>
28
28
 
29
- ## [2.0.12] - 2026-02-27
29
+ ## [2.0.13] - Dev branch
30
+
31
+ ### Dev Breaking Changes
32
+
33
+ - [oven]: Refactor oven class to use TemperatureNumber for TemperatureControlledCabinet device type (matter 1.4.2 conformance).
34
+ - [refrigerator]: Refactor refrigerator class to use TemperatureNumber for TemperatureControlledCabinet device type (matter 1.4.2 conformance).
30
35
 
31
36
  ### Added
32
37
 
38
+ - [BridgedOutlet]: Add a bridged outlet with four individually controllable plugs.
39
+
40
+ ### Changed
41
+
42
+ - [matterbridge]: Require `matterbridge` v.3.6.0.
43
+ - [package]: Update dependencies.
44
+ - [package]: Bump package to `automator` v.3.1.1.
45
+ - [package]: Add `@eslint/json`.
46
+ - [package]: Add `@eslint/markdown`.
47
+ - [package]: Add `CONTRIBUTING.md`.
48
+ - [package]: Add `STYLEGUIDE.md`.
49
+
50
+ ### Fixed
51
+
52
+ - [matter]: Fix Climate to be a compound device (matter 1.4.2 conformance).
53
+ - [matter]: Fix AirPurifier to be a compound device (matter 1.4.2 conformance).
54
+
55
+ <a href="https://www.buymeacoffee.com/luligugithub"><img src="https://matterbridge.io/assets/bmc-button.svg" alt="Buy me a coffee" width="80"></a>
56
+
57
+ ## [2.0.12] - 2026-02-27
58
+
59
+ ### Dev Breaking Changes
60
+
33
61
  - [devContainer]: Add the new [dev container setup](https://matterbridge.io/reflector/MatterbridgeDevContainer.html).
34
62
  - [devContainer]: Add the new [reflector dev container setup](https://matterbridge.io/reflector/Reflector.html).
63
+ - [devContainer]: Add the guide to [pair Matterbridge with Dev Container](https://matterbridge.io/README-DEV.html#how-to-pair-matterbridge-in-dev-containers)
35
64
 
36
65
  ### Changed
37
66
 
package/README.md CHANGED
@@ -24,7 +24,7 @@
24
24
 
25
25
  Matterbridge dynamic platform example plugin is a template to develop your own plugin using the dynamic platform.
26
26
 
27
- It exposes 63 virtual devices:
27
+ It exposes 64 virtual devices:
28
28
 
29
29
  - a door contact sensor
30
30
  - a motion sensor
@@ -46,6 +46,7 @@ It exposes 63 virtual devices:
46
46
  - an outlet (plug) with onOff cluster, energy measurements and power measurements
47
47
  - an outlet (plug) with onOff cluster, apparent energy measurements and power measurements
48
48
  - a smart outlet with an energy meter and four individually controllable sockets (with tagList 1, 2, 3 and 4)
49
+ - a bridged outlet with four individually controllable plugs
49
50
  - a cover with windowCovering cluster and lift feature
50
51
  - a cover with windowCovering cluster and both lift and tilt features
51
52
  - a lock with doorLock cluster
package/dist/module.js CHANGED
@@ -1,8 +1,8 @@
1
- import { airPurifier, airQualitySensor, bridgedNode, colorTemperatureLight, contactSensor, coverDevice, dimmableLight, dimmableMountedSwitch, dimmableOutlet, doorLockDevice, electricalSensor, extendedColorLight, fanDevice, flowSensor, genericSwitch, humiditySensor, lightSensor, MatterbridgeDynamicPlatform, MatterbridgeEndpoint, modeSelect, occupancySensor, onOffLight, onOffMountedSwitch, onOffOutlet, onOffSwitch, powerSource, pressureSensor, pumpDevice, rainSensor, smokeCoAlarm, temperatureSensor, thermostatDevice, waterFreezeDetector, waterLeakDetector, waterValve, } from 'matterbridge';
1
+ import { aggregator, airPurifier, airQualitySensor, bridgedNode, colorTemperatureLight, contactSensor, coverDevice, dimmableLight, dimmableMountedSwitch, dimmableOutlet, doorLockDevice, electricalSensor, extendedColorLight, fanDevice, flowSensor, genericSwitch, humiditySensor, lightSensor, MatterbridgeDynamicPlatform, MatterbridgeEndpoint, modeSelect, occupancySensor, onOffLight, onOffMountedSwitch, onOffOutlet, onOffSwitch, powerSource, pressureSensor, pumpDevice, rainSensor, smokeCoAlarm, temperatureSensor, thermostatDevice, waterFreezeDetector, waterLeakDetector, waterValve, } from 'matterbridge';
2
2
  import { AirConditioner, BasicVideoPlayer, BatteryStorage, Cooktop, Dishwasher, Evse, ExtractorHood, HeatPump, LaundryDryer, LaundryWasher, MicrowaveOven, Oven, Refrigerator, RoboticVacuumCleaner, SolarPower, Speaker, WaterHeater, } from 'matterbridge/devices';
3
3
  import { debugStringify } from 'matterbridge/logger';
4
4
  import { AreaNamespaceTag, LocationTag, NumberTag, PositionTag, RefrigeratorTag, SwitchesTag, UINT16_MAX, UINT32_MAX } from 'matterbridge/matter';
5
- import { AirQuality, BooleanState, BridgedDeviceBasicInformation, CarbonDioxideConcentrationMeasurement, CarbonMonoxideConcentrationMeasurement, ColorControl, Descriptor, DeviceEnergyManagement, DoorLock, ElectricalEnergyMeasurement, ElectricalPowerMeasurement, EnergyEvse, EnergyEvseMode, FanControl, FlowMeasurement, FormaldehydeConcentrationMeasurement, IlluminanceMeasurement, LevelControl, NitrogenDioxideConcentrationMeasurement, OccupancySensing, OnOff, OnOffCluster, OperationalState, OvenMode, OzoneConcentrationMeasurement, Pm1ConcentrationMeasurement, Pm10ConcentrationMeasurement, Pm25ConcentrationMeasurement, PowerSource, PressureMeasurement, RadonConcentrationMeasurement, RefrigeratorAndTemperatureControlledCabinetMode, RelativeHumidityMeasurement, RelativeHumidityMeasurementCluster, RvcCleanMode, RvcOperationalState, RvcRunMode, SmokeCoAlarm, TemperatureMeasurement, Thermostat, ThermostatCluster, TotalVolatileOrganicCompoundsConcentrationMeasurement, WindowCovering, } from 'matterbridge/matter/clusters';
5
+ import { AirQuality, BooleanState, BridgedDeviceBasicInformation, CarbonDioxideConcentrationMeasurement, CarbonMonoxideConcentrationMeasurement, ColorControl, Descriptor, DeviceEnergyManagement, DoorLock, ElectricalEnergyMeasurement, ElectricalPowerMeasurement, EnergyEvse, EnergyEvseMode, FanControl, FlowMeasurement, FormaldehydeConcentrationMeasurement, IlluminanceMeasurement, LevelControl, NitrogenDioxideConcentrationMeasurement, OccupancySensing, OnOff, OnOffCluster, OperationalState, OvenMode, OzoneConcentrationMeasurement, Pm1ConcentrationMeasurement, Pm10ConcentrationMeasurement, Pm25ConcentrationMeasurement, PowerSource, PressureMeasurement, RadonConcentrationMeasurement, RelativeHumidityMeasurement, RelativeHumidityMeasurementCluster, RvcCleanMode, RvcOperationalState, RvcRunMode, SmokeCoAlarm, TemperatureMeasurement, Thermostat, ThermostatCluster, TotalVolatileOrganicCompoundsConcentrationMeasurement, WindowCovering, } from 'matterbridge/matter/clusters';
6
6
  import { isValidBoolean, isValidNumber, isValidObject, isValidString } from 'matterbridge/utils';
7
7
  function luxToMatter(lux) {
8
8
  if (!Number.isFinite(lux) || lux <= 0)
@@ -46,6 +46,7 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
46
46
  outletEnergy;
47
47
  outletEnergyApparent;
48
48
  smartOutlet;
49
+ smartBridgedOutlet;
49
50
  coverLift;
50
51
  coverLiftTilt;
51
52
  lock;
@@ -99,8 +100,8 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
99
100
  constructor(matterbridge, log, config) {
100
101
  super(matterbridge, log, config);
101
102
  this.config = config;
102
- if (this.verifyMatterbridgeVersion === undefined || typeof this.verifyMatterbridgeVersion !== 'function' || !this.verifyMatterbridgeVersion('3.5.2')) {
103
- throw new Error(`This plugin requires Matterbridge version >= "3.5.2". Please update Matterbridge from ${this.matterbridge.matterbridgeVersion} to the latest version in the frontend.`);
103
+ if (this.verifyMatterbridgeVersion === undefined || typeof this.verifyMatterbridgeVersion !== 'function' || !this.verifyMatterbridgeVersion('3.6.0')) {
104
+ throw new Error(`This plugin requires Matterbridge version >= "3.6.0". Please update Matterbridge from ${this.matterbridge.matterbridgeVersion} to the latest version in the frontend.`);
104
105
  }
105
106
  this.log.info('Initializing platform:', this.config.name);
106
107
  }
@@ -157,14 +158,14 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
157
158
  .createDefaultPowerSourceReplaceableBatteryClusterServer(80, PowerSource.BatChargeLevel.Ok, 3050, 'AA', 1, PowerSource.BatReplaceability.UserReplaceable)
158
159
  .addRequiredClusterServers();
159
160
  this.flow = await this.addDevice(this.flow);
160
- this.climate = new MatterbridgeEndpoint([temperatureSensor, humiditySensor, pressureSensor, bridgedNode, powerSource], { id: 'Climate' }, this.config.debug)
161
- .createDefaultIdentifyClusterServer()
161
+ this.climate = new MatterbridgeEndpoint([bridgedNode, powerSource], { id: 'Climate' }, this.config.debug)
162
162
  .createDefaultBridgedDeviceBasicInformationClusterServer('Climate', 'CLI00008', 0xfff1, 'Matterbridge', 'Matterbridge Climate')
163
- .createDefaultTemperatureMeasurementClusterServer(1000)
164
- .createDefaultRelativeHumidityMeasurementClusterServer(1000)
165
- .createDefaultPressureMeasurementClusterServer(9000)
166
163
  .createDefaultPowerSourceReplaceableBatteryClusterServer(90, PowerSource.BatChargeLevel.Ok, 2990, '2 x AA', 2, PowerSource.BatReplaceability.UserReplaceable)
167
164
  .addRequiredClusterServers();
165
+ this.climate.addFixedLabel('composed', 'Compound device');
166
+ this.climate.addChildDeviceType('Temperature', temperatureSensor).createDefaultTemperatureMeasurementClusterServer(2100, -5000, 10000).addRequiredClusterServers();
167
+ this.climate.addChildDeviceType('Humidity', humiditySensor).createDefaultRelativeHumidityMeasurementClusterServer(5000, 0, 10000).addRequiredClusterServers();
168
+ this.climate.addChildDeviceType('Pressure', pressureSensor).createDefaultPressureMeasurementClusterServer(9000).addRequiredClusterServers();
168
169
  this.climate = await this.addDevice(this.climate);
169
170
  this.select = new MatterbridgeEndpoint([modeSelect, bridgedNode, powerSource], { id: 'Select' }, this.config.debug)
170
171
  .createDefaultBridgedDeviceBasicInformationClusterServer('Select', 'SEL00009', 0xfff1, 'Matterbridge', 'Matterbridge Select')
@@ -486,6 +487,28 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
486
487
  })
487
488
  .addRequiredClusterServers();
488
489
  this.smartOutlet = await this.addDevice(this.smartOutlet);
490
+ this.smartBridgedOutlet = new MatterbridgeEndpoint([aggregator, bridgedNode, powerSource], { id: 'BridgedOutlet' }, this.config.debug)
491
+ .createDefaultBridgedDeviceBasicInformationClusterServer('Bridged outlet', 'SOU00064', 0xfff1, 'Matterbridge', 'Matterbridge Bridged Outlet')
492
+ .createDefaultPowerSourceWiredClusterServer()
493
+ .addRequiredClusterServers();
494
+ this.smartBridgedOutlet.addFixedLabel('composed', 'Bridged device');
495
+ this.smartBridgedOutlet
496
+ .addChildDeviceTypeWithClusterServer('Plug 1', [onOffOutlet, bridgedNode], [OnOffCluster.id])
497
+ .createDefaultBridgedDeviceBasicInformationClusterServer('Plug 1', 'SOU00064-1', 0xfff1, 'Matterbridge', 'Matterbridge Bridged Outlet')
498
+ .addRequiredClusterServers();
499
+ this.smartBridgedOutlet
500
+ .addChildDeviceTypeWithClusterServer('Plug 2', [onOffOutlet, bridgedNode], [OnOffCluster.id])
501
+ .createDefaultBridgedDeviceBasicInformationClusterServer('Plug 2', 'SOU00064-2', 0xfff1, 'Matterbridge', 'Matterbridge Bridged Outlet')
502
+ .addRequiredClusterServers();
503
+ this.smartBridgedOutlet
504
+ .addChildDeviceTypeWithClusterServer('Plug 3', [onOffOutlet, bridgedNode], [OnOffCluster.id])
505
+ .createDefaultBridgedDeviceBasicInformationClusterServer('Plug 3', 'SOU00064-3', 0xfff1, 'Matterbridge', 'Matterbridge Bridged Outlet')
506
+ .addRequiredClusterServers();
507
+ this.smartBridgedOutlet
508
+ .addChildDeviceTypeWithClusterServer('Plug 4', [onOffOutlet, bridgedNode], [OnOffCluster.id])
509
+ .createDefaultBridgedDeviceBasicInformationClusterServer('Plug 4', 'SOU00064-4', 0xfff1, 'Matterbridge', 'Matterbridge Bridged Outlet')
510
+ .addRequiredClusterServers();
511
+ this.smartBridgedOutlet = await this.addDevice(this.smartBridgedOutlet);
489
512
  this.coverLift = new MatterbridgeEndpoint([coverDevice, bridgedNode, powerSource], { id: 'CoverLift' }, this.config.debug)
490
513
  .createDefaultIdentifyClusterServer()
491
514
  .createDefaultBridgedDeviceBasicInformationClusterServer('Cover lift', 'COV00020', 0xfff1, 'Matterbridge', 'Matterbridge Cover')
@@ -845,16 +868,24 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
845
868
  await this.thermoCool?.subscribeAttribute(ThermostatCluster.id, 'occupiedCoolingSetpoint', (value) => {
846
869
  this.thermoCool?.log.info('Subscribe occupiedCoolingSetpoint called with:', value / 100);
847
870
  }, this.thermoCool.log);
848
- this.airPurifier = new MatterbridgeEndpoint([airPurifier, temperatureSensor, humiditySensor, bridgedNode, powerSource], { id: 'Air purifier' }, this.config.debug)
871
+ this.airPurifier = new MatterbridgeEndpoint([airPurifier, bridgedNode, powerSource], { id: 'Air purifier' }, this.config.debug)
849
872
  .createDefaultBridgedDeviceBasicInformationClusterServer('Air purifier', 'AIR00026', 0xfff1, 'Matterbridge', 'Matterbridge Air purifier')
850
873
  .createDefaultIdentifyClusterServer()
851
874
  .createDefaultFanControlClusterServer()
852
- .createDefaultTemperatureMeasurementClusterServer(20 * 100)
853
- .createDefaultRelativeHumidityMeasurementClusterServer(50 * 100)
854
875
  .createDefaultPowerSourceWiredClusterServer()
855
876
  .createDefaultActivatedCarbonFilterMonitoringClusterServer()
856
877
  .createDefaultHepaFilterMonitoringClusterServer()
857
878
  .addRequiredClusterServers();
879
+ this.airPurifier.addFixedLabel('composed', 'Compound device');
880
+ this.airPurifier.addChildDeviceType('AirQuality', airQualitySensor).createDefaultAirQualityClusterServer(AirQuality.AirQualityEnum.Good).addRequiredClusterServers();
881
+ this.airPurifier
882
+ .addChildDeviceType('Temperature', temperatureSensor)
883
+ .createDefaultTemperatureMeasurementClusterServer(20 * 100)
884
+ .addRequiredClusterServers();
885
+ this.airPurifier
886
+ .addChildDeviceType('Humidity', humiditySensor)
887
+ .createDefaultRelativeHumidityMeasurementClusterServer(50 * 100)
888
+ .addRequiredClusterServers();
858
889
  this.airPurifier = await this.addDevice(this.airPurifier);
859
890
  this.airPurifier?.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
860
891
  this.airPurifier?.log.info(`Command identify called identifyTime:${identifyTime}`);
@@ -1146,13 +1177,15 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
1146
1177
  .createDefaultTvocMeasurementClusterServer(100);
1147
1178
  this.airQuality = await this.addDevice(this.airQuality);
1148
1179
  this.momentarySwitch = new MatterbridgeEndpoint([bridgedNode, powerSource], { id: 'Momentary switch composed' }, this.config.debug)
1149
- .createDefaultBridgedDeviceBasicInformationClusterServer('Momentary switch', 'MOS00041', 0xfff1, 'Matterbridge', 'Matterbridge MomentarySwitch')
1180
+ .createDefaultBridgedDeviceBasicInformationClusterServer('Momentary switch', 'MOS00041', 0xfff1, 'Matterbridge', 'Matterbridge Momentary Switch')
1150
1181
  .createDefaultPowerSourceReplaceableBatteryClusterServer(50, PowerSource.BatChargeLevel.Ok, 2900, 'CR2450', 1);
1151
1182
  this.momentarySwitch
1152
1183
  .addChildDeviceType('Momentary switch 1', [genericSwitch], {
1153
1184
  tagList: [
1154
1185
  { mfgCode: null, namespaceId: NumberTag.One.namespaceId, tag: NumberTag.One.tag, label: null },
1155
1186
  { mfgCode: null, namespaceId: PositionTag.Top.namespaceId, tag: PositionTag.Top.tag, label: null },
1187
+ { mfgCode: null, namespaceId: PositionTag.Left.namespaceId, tag: PositionTag.Left.tag, label: null },
1188
+ { mfgCode: null, namespaceId: AreaNamespaceTag.LivingRoom.namespaceId, tag: AreaNamespaceTag.LivingRoom.tag, label: null },
1156
1189
  ],
1157
1190
  })
1158
1191
  .createDefaultIdentifyClusterServer()
@@ -1162,6 +1195,8 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
1162
1195
  tagList: [
1163
1196
  { mfgCode: null, namespaceId: NumberTag.Two.namespaceId, tag: NumberTag.Two.tag, label: null },
1164
1197
  { mfgCode: null, namespaceId: PositionTag.Middle.namespaceId, tag: PositionTag.Middle.tag, label: null },
1198
+ { mfgCode: null, namespaceId: PositionTag.Left.namespaceId, tag: PositionTag.Left.tag, label: null },
1199
+ { mfgCode: null, namespaceId: AreaNamespaceTag.LivingRoom.namespaceId, tag: AreaNamespaceTag.LivingRoom.tag, label: null },
1165
1200
  ],
1166
1201
  })
1167
1202
  .createDefaultIdentifyClusterServer()
@@ -1171,6 +1206,8 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
1171
1206
  tagList: [
1172
1207
  { mfgCode: null, namespaceId: NumberTag.Three.namespaceId, tag: NumberTag.Three.tag, label: null },
1173
1208
  { mfgCode: null, namespaceId: PositionTag.Bottom.namespaceId, tag: PositionTag.Bottom.tag, label: null },
1209
+ { mfgCode: null, namespaceId: PositionTag.Left.namespaceId, tag: PositionTag.Left.tag, label: null },
1210
+ { mfgCode: null, namespaceId: AreaNamespaceTag.LivingRoom.namespaceId, tag: AreaNamespaceTag.LivingRoom.tag, label: null },
1174
1211
  ],
1175
1212
  })
1176
1213
  .createDefaultIdentifyClusterServer()
@@ -1179,9 +1216,9 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
1179
1216
  .addChildDeviceType('Momentary switch 4', [genericSwitch], {
1180
1217
  tagList: [
1181
1218
  { mfgCode: null, namespaceId: NumberTag.Four.namespaceId, tag: NumberTag.Four.tag, label: null },
1182
- { mfgCode: null, namespaceId: PositionTag.Bottom.namespaceId, tag: PositionTag.Bottom.tag, label: null },
1219
+ { mfgCode: null, namespaceId: PositionTag.Top.namespaceId, tag: PositionTag.Top.tag, label: null },
1220
+ { mfgCode: null, namespaceId: PositionTag.Right.namespaceId, tag: PositionTag.Right.tag, label: null },
1183
1221
  { mfgCode: null, namespaceId: SwitchesTag.Custom.namespaceId, tag: SwitchesTag.Custom.tag, label: 'Turn on' },
1184
- { mfgCode: null, namespaceId: LocationTag.Indoor.namespaceId, tag: LocationTag.Indoor.tag, label: null },
1185
1222
  { mfgCode: null, namespaceId: AreaNamespaceTag.Bedroom.namespaceId, tag: AreaNamespaceTag.Bedroom.tag, label: null },
1186
1223
  ],
1187
1224
  })
@@ -1192,8 +1229,8 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
1192
1229
  tagList: [
1193
1230
  { mfgCode: null, namespaceId: NumberTag.Five.namespaceId, tag: NumberTag.Five.tag, label: null },
1194
1231
  { mfgCode: null, namespaceId: PositionTag.Middle.namespaceId, tag: PositionTag.Middle.tag, label: null },
1232
+ { mfgCode: null, namespaceId: PositionTag.Right.namespaceId, tag: PositionTag.Right.tag, label: null },
1195
1233
  { mfgCode: null, namespaceId: SwitchesTag.Custom.namespaceId, tag: SwitchesTag.Custom.tag, label: 'Turn off' },
1196
- { mfgCode: null, namespaceId: LocationTag.Indoor.namespaceId, tag: LocationTag.Indoor.tag, label: null },
1197
1234
  { mfgCode: null, namespaceId: AreaNamespaceTag.Bedroom.namespaceId, tag: AreaNamespaceTag.Bedroom.tag, label: null },
1198
1235
  ],
1199
1236
  })
@@ -1204,8 +1241,8 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
1204
1241
  tagList: [
1205
1242
  { mfgCode: null, namespaceId: NumberTag.Seven.namespaceId, tag: NumberTag.Seven.tag, label: null },
1206
1243
  { mfgCode: null, namespaceId: PositionTag.Bottom.namespaceId, tag: PositionTag.Bottom.tag, label: null },
1244
+ { mfgCode: null, namespaceId: PositionTag.Right.namespaceId, tag: PositionTag.Right.tag, label: null },
1207
1245
  { mfgCode: null, namespaceId: SwitchesTag.Custom.namespaceId, tag: SwitchesTag.Custom.tag, label: 'Toggle' },
1208
- { mfgCode: null, namespaceId: LocationTag.Indoor.namespaceId, tag: LocationTag.Indoor.tag, label: null },
1209
1246
  { mfgCode: null, namespaceId: AreaNamespaceTag.Bedroom.namespaceId, tag: AreaNamespaceTag.Bedroom.tag, label: null },
1210
1247
  ],
1211
1248
  })
@@ -1302,12 +1339,23 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
1302
1339
  this.microwaveOven = new MicrowaveOven('Microwave Oven', 'MWO00053');
1303
1340
  this.microwaveOven = await this.addDevice(this.microwaveOven);
1304
1341
  this.oven = new Oven('Oven', 'OVN00054');
1305
- this.oven.addCabinet('Upper Cabinet', [{ mfgCode: null, namespaceId: PositionTag.Top.namespaceId, tag: PositionTag.Top.tag, label: PositionTag.Top.label }], undefined, undefined, undefined, undefined, undefined, undefined, ['pre-heating', 'pre-heated', 'cooling down']);
1342
+ this.oven.addCabinet('Upper Cabinet', [{ mfgCode: null, namespaceId: PositionTag.Top.namespaceId, tag: PositionTag.Top.tag, label: PositionTag.Top.label }], 2, [
1343
+ { label: 'Bake', mode: 1, modeTags: [{ value: OvenMode.ModeTag.Bake }] },
1344
+ { label: 'Convection', mode: 2, modeTags: [{ value: OvenMode.ModeTag.Convection }] },
1345
+ { label: 'Grill', mode: 3, modeTags: [{ value: OvenMode.ModeTag.Grill }] },
1346
+ { label: 'Roast', mode: 4, modeTags: [{ value: OvenMode.ModeTag.Roast }] },
1347
+ { label: 'Clean', mode: 5, modeTags: [{ value: OvenMode.ModeTag.Clean }] },
1348
+ { label: 'Convection Bake', mode: 6, modeTags: [{ value: OvenMode.ModeTag.ConvectionBake }] },
1349
+ { label: 'Convection Roast', mode: 7, modeTags: [{ value: OvenMode.ModeTag.ConvectionRoast }] },
1350
+ { label: 'Warming', mode: 8, modeTags: [{ value: OvenMode.ModeTag.Warming }] },
1351
+ { label: 'Proofing', mode: 9, modeTags: [{ value: OvenMode.ModeTag.Proofing }] },
1352
+ { label: 'Steam', mode: 10, modeTags: [{ value: OvenMode.ModeTag.Steam }] },
1353
+ ], 180 * 100, 100 * 100, 300 * 100, 10 * 100, 20 * 100, OperationalState.OperationalStateEnum.Stopped, 2, ['pre-heating', 'pre-heated', 'cooling down']);
1306
1354
  this.oven.addCabinet('Lower Cabinet', [{ mfgCode: null, namespaceId: PositionTag.Bottom.namespaceId, tag: PositionTag.Bottom.tag, label: PositionTag.Bottom.label }], 3, [
1307
1355
  { label: 'Convection', mode: 1, modeTags: [{ value: OvenMode.ModeTag.Convection }] },
1308
1356
  { label: 'Clean', mode: 2, modeTags: [{ value: OvenMode.ModeTag.Clean }] },
1309
1357
  { label: 'Steam', mode: 3, modeTags: [{ value: OvenMode.ModeTag.Steam }] },
1310
- ], 2, ['180°', '190°', '200°'], OperationalState.OperationalStateEnum.Running, undefined, ['pre-heating', 'pre-heated', 'cooling down']);
1358
+ ], 200 * 100, 100 * 100, 300 * 100, 10 * 100, 200 * 100, OperationalState.OperationalStateEnum.Running, 1, ['pre-heating', 'pre-heated', 'cooling down']);
1311
1359
  this.oven = (await this.addDevice(this.oven));
1312
1360
  this.cooktop = new Cooktop('Cooktop', 'CKT00055');
1313
1361
  this.cooktop.addSurface('Surface Top Left', [
@@ -1331,17 +1379,11 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
1331
1379
  refrigerator.addCabinet('Refrigerator Top', [
1332
1380
  { mfgCode: null, namespaceId: PositionTag.Top.namespaceId, tag: PositionTag.Top.tag, label: 'Refrigerator Top' },
1333
1381
  { mfgCode: null, namespaceId: RefrigeratorTag.Refrigerator.namespaceId, tag: RefrigeratorTag.Refrigerator.tag, label: RefrigeratorTag.Refrigerator.label },
1334
- ], 1, [
1335
- { label: 'Auto', mode: 1, modeTags: [{ value: RefrigeratorAndTemperatureControlledCabinetMode.ModeTag.Auto }] },
1336
- { label: 'RapidCool', mode: 2, modeTags: [{ value: RefrigeratorAndTemperatureControlledCabinetMode.ModeTag.RapidCool }] },
1337
- ], undefined, undefined, 1200);
1382
+ ], 12 * 100, 5 * 100, 20 * 100, 1 * 100, 1200);
1338
1383
  refrigerator.addCabinet('Freezer Bottom', [
1339
1384
  { mfgCode: null, namespaceId: PositionTag.Bottom.namespaceId, tag: PositionTag.Bottom.tag, label: 'Freezer Bottom' },
1340
1385
  { mfgCode: null, namespaceId: RefrigeratorTag.Freezer.namespaceId, tag: RefrigeratorTag.Freezer.tag, label: RefrigeratorTag.Freezer.label },
1341
- ], 1, [
1342
- { label: 'Auto', mode: 1, modeTags: [{ value: RefrigeratorAndTemperatureControlledCabinetMode.ModeTag.Auto }] },
1343
- { label: 'RapidFreeze', mode: 2, modeTags: [{ value: RefrigeratorAndTemperatureControlledCabinetMode.ModeTag.RapidFreeze }] },
1344
- ], undefined, undefined, -1000);
1386
+ ], -18 * 100, -30 * 100, -10 * 100, 1 * 100, -1800);
1345
1387
  this.refrigerator = (await this.addDevice(refrigerator));
1346
1388
  this.airConditioner = new AirConditioner('Air Conditioner', 'ACO00027', {
1347
1389
  localTemperature: 20,
@@ -1567,52 +1609,52 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
1567
1609
  await upperCabinet?.setAttribute('OvenMode', 'currentMode', 3, upperCabinet.log);
1568
1610
  await upperCabinet?.setAttribute('OvenCavityOperationalState', 'operationalState', OperationalState.OperationalStateEnum.Stopped, upperCabinet.log);
1569
1611
  await upperCabinet?.setAttribute('OvenCavityOperationalState', 'currentPhase', 2, upperCabinet.log);
1570
- await upperCabinet?.setAttribute('TemperatureControl', 'selectedTemperatureLevel', 2, upperCabinet.log);
1612
+ await upperCabinet?.setAttribute('TemperatureControl', 'temperatureSetpoint', 190 * 100, upperCabinet.log);
1571
1613
  await upperCabinet?.setAttribute('TemperatureMeasurement', 'measuredValue', 2000, upperCabinet.log);
1572
1614
  await lowerCabinet?.setAttribute('OvenMode', 'currentMode', 3, lowerCabinet.log);
1573
1615
  await lowerCabinet?.setAttribute('OvenCavityOperationalState', 'operationalState', OperationalState.OperationalStateEnum.Stopped, lowerCabinet.log);
1574
1616
  await lowerCabinet?.setAttribute('OvenCavityOperationalState', 'currentPhase', 2, lowerCabinet.log);
1575
- await lowerCabinet?.setAttribute('TemperatureControl', 'selectedTemperatureLevel', 2, lowerCabinet.log);
1617
+ await lowerCabinet?.setAttribute('TemperatureControl', 'temperatureSetpoint', 210 * 100, lowerCabinet.log);
1576
1618
  await lowerCabinet?.setAttribute('TemperatureMeasurement', 'measuredValue', 2000, lowerCabinet.log);
1577
1619
  }
1578
1620
  if (this.phase === 1) {
1579
1621
  await upperCabinet?.setAttribute('OvenCavityOperationalState', 'operationalState', OperationalState.OperationalStateEnum.Running, upperCabinet.log);
1580
1622
  await upperCabinet?.setAttribute('OvenCavityOperationalState', 'currentPhase', 0, upperCabinet.log);
1581
- await upperCabinet?.setAttribute('TemperatureControl', 'selectedTemperatureLevel', 2, upperCabinet.log);
1623
+ await upperCabinet?.setAttribute('TemperatureControl', 'temperatureSetpoint', 200 * 100, upperCabinet.log);
1582
1624
  await upperCabinet?.setAttribute('TemperatureMeasurement', 'measuredValue', 5000, upperCabinet.log);
1583
1625
  await lowerCabinet?.setAttribute('OvenCavityOperationalState', 'operationalState', OperationalState.OperationalStateEnum.Running, lowerCabinet.log);
1584
1626
  await lowerCabinet?.setAttribute('OvenCavityOperationalState', 'currentPhase', 0, lowerCabinet.log);
1585
- await lowerCabinet?.setAttribute('TemperatureControl', 'selectedTemperatureLevel', 2, lowerCabinet.log);
1627
+ await lowerCabinet?.setAttribute('TemperatureControl', 'temperatureSetpoint', 220 * 100, lowerCabinet.log);
1586
1628
  await lowerCabinet?.setAttribute('TemperatureMeasurement', 'measuredValue', 5000, lowerCabinet.log);
1587
1629
  }
1588
1630
  if (this.phase === 2) {
1589
1631
  await upperCabinet?.setAttribute('OvenCavityOperationalState', 'operationalState', OperationalState.OperationalStateEnum.Running, upperCabinet.log);
1590
1632
  await upperCabinet?.setAttribute('OvenCavityOperationalState', 'currentPhase', 1, upperCabinet.log);
1591
- await upperCabinet?.setAttribute('TemperatureControl', 'selectedTemperatureLevel', 2, upperCabinet.log);
1633
+ await upperCabinet?.setAttribute('TemperatureControl', 'temperatureSetpoint', 190 * 100, upperCabinet.log);
1592
1634
  await upperCabinet?.setAttribute('TemperatureMeasurement', 'measuredValue', 19000, upperCabinet.log);
1593
1635
  await lowerCabinet?.setAttribute('OvenCavityOperationalState', 'operationalState', OperationalState.OperationalStateEnum.Running, lowerCabinet.log);
1594
1636
  await lowerCabinet?.setAttribute('OvenCavityOperationalState', 'currentPhase', 1, lowerCabinet.log);
1595
- await lowerCabinet?.setAttribute('TemperatureControl', 'selectedTemperatureLevel', 2, lowerCabinet.log);
1637
+ await lowerCabinet?.setAttribute('TemperatureControl', 'temperatureSetpoint', 200 * 100, lowerCabinet.log);
1596
1638
  await lowerCabinet?.setAttribute('TemperatureMeasurement', 'measuredValue', 20000, lowerCabinet.log);
1597
1639
  }
1598
1640
  if (this.phase === 8) {
1599
1641
  await upperCabinet?.setAttribute('OvenCavityOperationalState', 'operationalState', OperationalState.OperationalStateEnum.Stopped, upperCabinet.log);
1600
1642
  await upperCabinet?.setAttribute('OvenCavityOperationalState', 'currentPhase', 2, upperCabinet.log);
1601
- await upperCabinet?.setAttribute('TemperatureControl', 'selectedTemperatureLevel', 2, upperCabinet.log);
1643
+ await upperCabinet?.setAttribute('TemperatureControl', 'temperatureSetpoint', 190 * 100, upperCabinet.log);
1602
1644
  await upperCabinet?.setAttribute('TemperatureMeasurement', 'measuredValue', 10000, upperCabinet.log);
1603
1645
  await lowerCabinet?.setAttribute('OvenCavityOperationalState', 'operationalState', OperationalState.OperationalStateEnum.Stopped, lowerCabinet.log);
1604
1646
  await lowerCabinet?.setAttribute('OvenCavityOperationalState', 'currentPhase', 2, lowerCabinet.log);
1605
- await lowerCabinet?.setAttribute('TemperatureControl', 'selectedTemperatureLevel', 2, lowerCabinet.log);
1647
+ await lowerCabinet?.setAttribute('TemperatureControl', 'temperatureSetpoint', 200 * 100, lowerCabinet.log);
1606
1648
  await lowerCabinet?.setAttribute('TemperatureMeasurement', 'measuredValue', 10000, lowerCabinet.log);
1607
1649
  }
1608
1650
  if (this.phase === 9) {
1609
1651
  await upperCabinet?.setAttribute('OvenCavityOperationalState', 'operationalState', OperationalState.OperationalStateEnum.Stopped, upperCabinet.log);
1610
1652
  await upperCabinet?.setAttribute('OvenCavityOperationalState', 'currentPhase', 2, upperCabinet.log);
1611
- await upperCabinet?.setAttribute('TemperatureControl', 'selectedTemperatureLevel', 2, upperCabinet.log);
1653
+ await upperCabinet?.setAttribute('TemperatureControl', 'temperatureSetpoint', 190 * 100, upperCabinet.log);
1612
1654
  await upperCabinet?.setAttribute('TemperatureMeasurement', 'measuredValue', 5000, upperCabinet.log);
1613
1655
  await lowerCabinet?.setAttribute('OvenCavityOperationalState', 'operationalState', OperationalState.OperationalStateEnum.Stopped, lowerCabinet.log);
1614
1656
  await lowerCabinet?.setAttribute('OvenCavityOperationalState', 'currentPhase', 2, lowerCabinet.log);
1615
- await lowerCabinet?.setAttribute('TemperatureControl', 'selectedTemperatureLevel', 2, lowerCabinet.log);
1657
+ await lowerCabinet?.setAttribute('TemperatureControl', 'temperatureSetpoint', 200 * 100, lowerCabinet.log);
1616
1658
  await lowerCabinet?.setAttribute('TemperatureMeasurement', 'measuredValue', 5000, lowerCabinet.log);
1617
1659
  }
1618
1660
  }
@@ -1631,46 +1673,46 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
1631
1673
  if (this.phase === 0) {
1632
1674
  let mode;
1633
1675
  const refrigerator = this.refrigerator.getChildEndpointByName('RefrigeratorTop');
1634
- mode = refrigerator?.getAttribute('RefrigeratorAndTemperatureControlledCabinetMode', 'currentMode', refrigerator.log);
1676
+ mode = this.refrigerator.getAttribute('RefrigeratorAndTemperatureControlledCabinetMode', 'currentMode', this.refrigerator.log);
1635
1677
  mode = mode === 1 ? 2 : 1;
1636
- await refrigerator?.setAttribute('RefrigeratorAndTemperatureControlledCabinetMode', 'currentMode', mode, refrigerator.log);
1678
+ await this.refrigerator.setAttribute('RefrigeratorAndTemperatureControlledCabinetMode', 'currentMode', mode, this.refrigerator.log);
1637
1679
  if (mode === 1)
1638
- await refrigerator?.setAttribute('TemperatureControl', 'selectedTemperatureLevel', 2, refrigerator.log);
1680
+ await refrigerator?.setAttribute('TemperatureControl', 'temperatureSetpoint', 9 * 100, refrigerator.log);
1639
1681
  if (mode === 1)
1640
1682
  await refrigerator?.setAttribute('TemperatureMeasurement', 'measuredValue', 1200, refrigerator.log);
1641
1683
  if (mode === 2)
1642
- await refrigerator?.setAttribute('TemperatureControl', 'selectedTemperatureLevel', 0, refrigerator.log);
1684
+ await refrigerator?.setAttribute('TemperatureControl', 'temperatureSetpoint', 10 * 100, refrigerator.log);
1643
1685
  if (mode === 2)
1644
1686
  await refrigerator?.setAttribute('TemperatureMeasurement', 'measuredValue', 1000, refrigerator.log);
1645
1687
  const freezer = this.refrigerator.getChildEndpointByName('FreezerBottom');
1646
- mode = freezer?.getAttribute('RefrigeratorAndTemperatureControlledCabinetMode', 'currentMode', freezer.log);
1688
+ mode = this.refrigerator.getAttribute('RefrigeratorAndTemperatureControlledCabinetMode', 'currentMode', this.refrigerator.log);
1647
1689
  mode = mode === 1 ? 2 : 1;
1648
- await freezer?.setAttribute('RefrigeratorAndTemperatureControlledCabinetMode', 'currentMode', mode, freezer.log);
1690
+ await this.refrigerator.setAttribute('RefrigeratorAndTemperatureControlledCabinetMode', 'currentMode', mode, this.refrigerator.log);
1649
1691
  if (mode === 1)
1650
- await freezer?.setAttribute('TemperatureControl', 'selectedTemperatureLevel', 2, freezer.log);
1692
+ await freezer?.setAttribute('TemperatureControl', 'temperatureSetpoint', -18 * 100, freezer.log);
1651
1693
  if (mode === 1)
1652
1694
  await freezer?.setAttribute('TemperatureMeasurement', 'measuredValue', -1000, freezer.log);
1653
1695
  if (mode === 2)
1654
- await freezer?.setAttribute('TemperatureControl', 'selectedTemperatureLevel', 0, freezer.log);
1696
+ await freezer?.setAttribute('TemperatureControl', 'temperatureSetpoint', -24 * 100, freezer.log);
1655
1697
  if (mode === 2)
1656
1698
  await freezer?.setAttribute('TemperatureMeasurement', 'measuredValue', -1500, freezer.log);
1657
1699
  }
1658
1700
  if (this.phase === 1)
1659
- await this.refrigerator.setDoorOpenState('RefrigeratorTop', true);
1701
+ await this.refrigerator.setDoorOpenState(true);
1660
1702
  if (this.phase === 2)
1661
- await this.refrigerator.triggerDoorOpenState('RefrigeratorTop', true);
1703
+ await this.refrigerator.triggerDoorOpenState(true);
1662
1704
  if (this.phase === 4)
1663
- await this.refrigerator.setDoorOpenState('RefrigeratorTop', false);
1705
+ await this.refrigerator.setDoorOpenState(false);
1664
1706
  if (this.phase === 4)
1665
- await this.refrigerator.triggerDoorOpenState('RefrigeratorTop', false);
1707
+ await this.refrigerator.triggerDoorOpenState(false);
1666
1708
  if (this.phase === 6)
1667
- await this.refrigerator.setDoorOpenState('FreezerBottom', true);
1709
+ await this.refrigerator.setDoorOpenState(true);
1668
1710
  if (this.phase === 7)
1669
- await this.refrigerator.triggerDoorOpenState('FreezerBottom', true);
1711
+ await this.refrigerator.triggerDoorOpenState(true);
1670
1712
  if (this.phase === 9)
1671
- await this.refrigerator.setDoorOpenState('FreezerBottom', false);
1713
+ await this.refrigerator.setDoorOpenState(false);
1672
1714
  if (this.phase === 9)
1673
- await this.refrigerator.triggerDoorOpenState('FreezerBottom', false);
1715
+ await this.refrigerator.triggerDoorOpenState(false);
1674
1716
  }
1675
1717
  this.phase++;
1676
1718
  this.phase = this.phase >= 10 ? 0 : this.phase;
@@ -1701,21 +1743,21 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
1701
1743
  if (isValidNumber(value, 0, 0xfffe)) {
1702
1744
  value = value + 100 < 3000 ? value + 100 : 1000;
1703
1745
  await this.temperature?.setAttribute(TemperatureMeasurement.Cluster.id, 'measuredValue', value, this.temperature.log);
1704
- await this.climate?.setAttribute(TemperatureMeasurement.Cluster.id, 'measuredValue', value, this.climate.log);
1746
+ await this.climate?.getChildEndpointById('Temperature')?.setAttribute(TemperatureMeasurement.Cluster.id, 'measuredValue', value, this.climate.log);
1705
1747
  this.temperature?.log.info(`Set temperature measuredValue to ${value}`);
1706
1748
  }
1707
1749
  value = this.humidity?.getAttribute(RelativeHumidityMeasurement.Cluster.id, 'measuredValue', this.humidity.log);
1708
1750
  if (isValidNumber(value, 0, 0xfffe)) {
1709
1751
  value = value + 100 < 10000 ? value + 100 : 100;
1710
1752
  await this.humidity?.setAttribute(RelativeHumidityMeasurement.Cluster.id, 'measuredValue', value, this.humidity.log);
1711
- await this.climate?.setAttribute(RelativeHumidityMeasurement.Cluster.id, 'measuredValue', value, this.climate.log);
1753
+ await this.climate?.getChildEndpointById('Humidity')?.setAttribute(RelativeHumidityMeasurement.Cluster.id, 'measuredValue', value, this.climate.log);
1712
1754
  this.humidity?.log.info(`Set humidity measuredValue to ${value}`);
1713
1755
  }
1714
1756
  value = this.pressure?.getAttribute(PressureMeasurement.Cluster.id, 'measuredValue', this.pressure.log);
1715
1757
  if (isValidNumber(value, 0, 0xfffe)) {
1716
1758
  value = value + 10 < 9900 ? value + 10 : 8600;
1717
1759
  await this.pressure?.setAttribute(PressureMeasurement.Cluster.id, 'measuredValue', value, this.pressure.log);
1718
- await this.climate?.setAttribute(PressureMeasurement.Cluster.id, 'measuredValue', value, this.climate.log);
1760
+ await this.climate?.getChildEndpointById('Pressure')?.setAttribute(PressureMeasurement.Cluster.id, 'measuredValue', value, this.climate.log);
1719
1761
  this.pressure?.log.info(`Set pressure measuredValue to ${value}`);
1720
1762
  }
1721
1763
  value = this.flow?.getAttribute(FlowMeasurement.Cluster.id, 'measuredValue', this.flow.log);
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "matterbridge-example-dynamic-platform",
3
- "version": "2.0.12",
3
+ "version": "2.0.13-dev-20260302-e8d75fe",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "matterbridge-example-dynamic-platform",
9
- "version": "2.0.12",
9
+ "version": "2.0.13-dev-20260302-e8d75fe",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "node-ansi-logger": "3.2.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "matterbridge-example-dynamic-platform",
3
- "version": "2.0.12",
3
+ "version": "2.0.13-dev-20260302-e8d75fe",
4
4
  "description": "Matterbridge dynamic plugin",
5
5
  "author": "https://github.com/Luligu",
6
6
  "license": "Apache-2.0",