matterbridge-example-dynamic-platform 3.0.4-dev-20260905-cd9c2f3 → 3.0.4-dev-20260908-8b4d88b

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
@@ -35,6 +35,12 @@ If you like this project and find it useful, please consider giving it a star on
35
35
 
36
36
  - [matterbridge]: Require matterbridge v.3.10.8 with matter v.1.6.0.
37
37
 
38
+ ### Added
39
+
40
+ - [platform]: Add `RfidLock` device: a door lock with the User, PinCredential, and RfidCredential (RID) features, testing the `numberOfRfidUsersSupported` parameter of `createUserPinDoorLockClusterServer()` (Matter 1.6.0 § 5.2.4). `SetCredential`, `GetCredentialStatus`, and `ClearCredential` already handle `DoorLock.CredentialType.Rfid` generically in `MatterbridgeDoorLockServer`, so no RFID-specific command handlers were needed for this device.
41
+ - [Oven]/[Refrigerator]: Add a `TemperatureAlarm` example to the demo cabinets.
42
+ - [devcontainer]: Upgrade the `Dev Container` to v.2.1.0, using the Node.js and Bun stack.
43
+
38
44
  ### Changed
39
45
 
40
46
  - [package]: Upgrade package.
package/README.md CHANGED
@@ -23,7 +23,7 @@
23
23
 
24
24
  Matterbridge dynamic platform example plugin is a template to develop your own plugin using the dynamic platform.
25
25
 
26
- It exposes 77 virtual devices:
26
+ It exposes 78 virtual devices:
27
27
 
28
28
  - a door contact sensor
29
29
  - a motion sensor
@@ -51,6 +51,7 @@ It exposes 77 virtual devices:
51
51
  - a lock with doorLock cluster
52
52
  - a lock with doorLock cluster and User and PinCredential support (userPinLock)
53
53
  - a lock with doorLock cluster, User and PinCredential support, and WeekDay, YearDay and Holiday access schedules (scheduleLock)
54
+ - a lock with doorLock cluster, User and PinCredential support, and RfidCredential support (DoorLock.Feature.RfidCredential) via the numberOfRfidUsersSupported attribute (rfidLock)
54
55
  - a thermostat auto mode (i.e. with Auto Heat and Cool features) with thermostat cluster and 3 sub endpoints with flowMeasurement cluster, temperatureMeasurement cluster
55
56
  and relativeHumidityMeasurement cluster (to show how to create a composed device with sub endpoints)
56
57
  - a thermostat with auto mode (i.e. with Auto Heat and Cool features), occupancy and outdoorTemperature
package/dist/module.js CHANGED
@@ -46,6 +46,7 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
46
46
  lock;
47
47
  userPinLock;
48
48
  scheduleLock;
49
+ rfidLock;
49
50
  thermoAuto;
50
51
  thermoAutoOccupancy;
51
52
  thermoAutoPresets;
@@ -887,6 +888,25 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
887
888
  this.scheduleLock?.subscribeAttribute(DoorLock, 'operatingMode', (value) => {
888
889
  this.scheduleLock?.log.info(`Subscribe operatingMode called with: ${getEnumDescription(DoorLock.OperatingMode, value)}`);
889
890
  }, this.scheduleLock.log);
891
+ this.rfidLock = new MatterbridgeEndpoint([doorLock, bridgedNode, powerSource], { id: 'RfidLock' }, this.config.debug)
892
+ .createDefaultIdentifyClusterServer()
893
+ .createDefaultBridgedDeviceBasicInformationClusterServer('Lock with RFID', 'LRF00090', 0xfff1, 'Matterbridge', 'Matterbridge Lock')
894
+ .createUserPinDoorLockClusterServer(DoorLock.LockState.Locked, DoorLock.LockType.DeadBolt, 0, 4, 10, undefined, undefined, undefined, undefined, 10)
895
+ .createDefaultPowerSourceRechargeableBatteryClusterServer(95)
896
+ .addRequiredClusterServers();
897
+ this.rfidLock = await this.addDevice(this.rfidLock);
898
+ this.rfidLock?.addCommandHandler('Identify.identify', ({ request: { identifyTime } }) => {
899
+ this.rfidLock?.log.info(`Command identify called identifyTime:${identifyTime}`);
900
+ });
901
+ this.rfidLock?.addCommandHandler('DoorLock.lockDoor', () => {
902
+ this.rfidLock?.log.info('Command lockDoor called');
903
+ });
904
+ this.rfidLock?.addCommandHandler('DoorLock.unlockDoor', () => {
905
+ this.rfidLock?.log.info('Command unlockDoor called');
906
+ });
907
+ this.rfidLock?.subscribeAttribute(DoorLock, 'operatingMode', (value) => {
908
+ this.rfidLock?.log.info(`Subscribe operatingMode called with: ${getEnumDescription(DoorLock.OperatingMode, value)}`);
909
+ }, this.rfidLock.log);
890
910
  this.thermoAuto = new MatterbridgeEndpoint([thermostat, bridgedNode, powerSource], { id: 'Thermostat (AutoMode)' }, this.config.debug)
891
911
  .createDefaultIdentifyClusterServer()
892
912
  .createDefaultBridgedDeviceBasicInformationClusterServer('Thermostat (Auto)', 'TAU00023', 0xfff1, 'Matterbridge', 'Matterbridge Thermostat')
@@ -1585,14 +1605,17 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
1585
1605
  await switch4.addFixedLabel('room', 'Living Room');
1586
1606
  await switch4.addFixedLabel('switch', 'Switch 4');
1587
1607
  await switch4.addFixedLabel('button', 'Button 4');
1608
+ await switch4.addFixedLabel('ha_entitylabel', 'DIY');
1588
1609
  await switch5.addFixedLabel('name', 'Switch 5');
1589
1610
  await switch5.addFixedLabel('room', 'Living Room');
1590
1611
  await switch5.addFixedLabel('switch', 'Switch 5');
1591
1612
  await switch5.addFixedLabel('button', 'Button 5');
1613
+ await switch5.addFixedLabel('ha_entitylabel', 'DIY');
1592
1614
  await switch6.addFixedLabel('name', 'Switch 6');
1593
1615
  await switch6.addFixedLabel('room', 'Living Room');
1594
1616
  await switch6.addFixedLabel('switch', 'Switch 6');
1595
1617
  await switch6.addFixedLabel('button', 'Button 6');
1618
+ await switch6.addFixedLabel('ha_entitylabel', 'DIY');
1596
1619
  }
1597
1620
  this.latchingSwitch = new MatterbridgeEndpoint([genericSwitch, bridgedNode, powerSource], { id: 'Latching switch' }, this.config.debug)
1598
1621
  .createDefaultBridgedDeviceBasicInformationClusterServer('Latching switch', 'LAS00042', 0xfff1, 'Matterbridge', 'Matterbridge LatchingSwitch')
@@ -1736,7 +1759,7 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
1736
1759
  this.microwaveOven = new MicrowaveOven('Microwave Oven', 'MWO00053');
1737
1760
  this.microwaveOven = await this.addDevice(this.microwaveOven);
1738
1761
  this.oven = new Oven('Oven', 'OVN00054');
1739
- this.oven.addCabinet('Upper Cabinet', {
1762
+ const ovenUpperCabinet = this.oven.addCabinet('Upper Cabinet', {
1740
1763
  tagList: [{ mfgCode: null, namespaceId: CommonPositionTag.Top.namespaceId, tag: CommonPositionTag.Top.tag, label: CommonPositionTag.Top.label }],
1741
1764
  currentMode: 2,
1742
1765
  supportedModes: [
@@ -1760,7 +1783,8 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
1760
1783
  currentPhase: 2,
1761
1784
  phaseList: ['pre-heating', 'pre-heated', 'cooling down'],
1762
1785
  });
1763
- this.oven.addCabinet('Lower Cabinet', {
1786
+ ovenUpperCabinet.createDefaultTemperatureAlarmClusterServer(280_00);
1787
+ const ovenLowerCabinet = this.oven.addCabinet('Lower Cabinet', {
1764
1788
  tagList: [{ mfgCode: null, namespaceId: CommonPositionTag.Bottom.namespaceId, tag: CommonPositionTag.Bottom.tag, label: CommonPositionTag.Bottom.label }],
1765
1789
  currentMode: 3,
1766
1790
  supportedModes: [
@@ -1777,6 +1801,7 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
1777
1801
  currentPhase: 1,
1778
1802
  phaseList: ['pre-heating', 'pre-heated', 'cooling down'],
1779
1803
  });
1804
+ ovenLowerCabinet.createDefaultTemperatureAlarmClusterServer(280_00);
1780
1805
  this.oven = await this.addDevice(this.oven);
1781
1806
  this.cooktop = new Cooktop('Cooktop', 'CKT00055');
1782
1807
  this.cooktop.addSurface('Surface Top Left', {
@@ -1805,7 +1830,7 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
1805
1830
  });
1806
1831
  this.cooktop = await this.addDevice(this.cooktop);
1807
1832
  const refrigerator = new Refrigerator('Refrigerator', 'REF00056');
1808
- refrigerator.addCabinet('Refrigerator Top', {
1833
+ const refrigeratorTopCabinet = refrigerator.addCabinet('Refrigerator Top', {
1809
1834
  tagList: [
1810
1835
  { mfgCode: null, namespaceId: CommonPositionTag.Top.namespaceId, tag: CommonPositionTag.Top.tag, label: 'Refrigerator Top' },
1811
1836
  { mfgCode: null, namespaceId: RefrigeratorTag.Refrigerator.namespaceId, tag: RefrigeratorTag.Refrigerator.tag, label: RefrigeratorTag.Refrigerator.label },
@@ -1816,17 +1841,19 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
1816
1841
  step: 1 * 100,
1817
1842
  currentTemperature: 1200,
1818
1843
  });
1819
- refrigerator.addCabinet('Freezer Bottom', {
1844
+ refrigeratorTopCabinet.createDefaultTemperatureAlarmClusterServer(20_00, 5_00);
1845
+ const freezerBottomCabinet = refrigerator.addCabinet('Freezer Bottom', {
1820
1846
  tagList: [
1821
1847
  { mfgCode: null, namespaceId: CommonPositionTag.Bottom.namespaceId, tag: CommonPositionTag.Bottom.tag, label: 'Freezer Bottom' },
1822
1848
  { mfgCode: null, namespaceId: RefrigeratorTag.Freezer.namespaceId, tag: RefrigeratorTag.Freezer.tag, label: RefrigeratorTag.Freezer.label },
1823
1849
  ],
1824
1850
  targetTemperature: -18 * 100,
1825
- minTemperature: -30 * 100,
1851
+ minTemperature: -25 * 100,
1826
1852
  maxTemperature: -10 * 100,
1827
1853
  step: 1 * 100,
1828
1854
  currentTemperature: -1800,
1829
1855
  });
1856
+ freezerBottomCabinet.createDefaultTemperatureAlarmClusterServer(-5_00, -30_00);
1830
1857
  this.refrigerator = await this.addDevice(refrigerator);
1831
1858
  this.airConditioner = new AirConditioner('Air Conditioner', 'ACO00027', {
1832
1859
  localTemperature: 20,
@@ -2367,6 +2394,8 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
2367
2394
  }
2368
2395
  await this.scheduleLock?.setAttribute(DoorLock.id, 'lockState', DoorLock.LockState.Locked, this.scheduleLock.log);
2369
2396
  this.scheduleLock?.log.info('Set schedule lock initial lockState to Locked');
2397
+ await this.rfidLock?.setAttribute(DoorLock.id, 'lockState', DoorLock.LockState.Locked, this.rfidLock.log);
2398
+ this.rfidLock?.log.info('Set rfid lock initial lockState to Locked');
2370
2399
  await this.thermoAuto?.setAttribute(Thermostat.id, 'localTemperature', 16 * 100, this.thermoAuto.log);
2371
2400
  await this.thermoAuto?.setAttribute(Thermostat.id, 'systemMode', Thermostat.SystemMode.Auto, this.thermoAuto.log);
2372
2401
  if (this.thermoAuto?.hasAttributeServer(Thermostat.id, 'thermostatRunningState')) {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "matterbridge-example-dynamic-platform",
3
- "version": "3.0.4-dev-20260905-cd9c2f3",
3
+ "version": "3.0.4-dev-20260908-8b4d88b",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "matterbridge-example-dynamic-platform",
9
- "version": "3.0.4-dev-20260905-cd9c2f3",
9
+ "version": "3.0.4-dev-20260908-8b4d88b",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "node-ansi-logger": "3.3.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "matterbridge-example-dynamic-platform",
3
- "version": "3.0.4-dev-20260905-cd9c2f3",
3
+ "version": "3.0.4-dev-20260908-8b4d88b",
4
4
  "description": "Matterbridge dynamic plugin",
5
5
  "author": "https://github.com/Luligu",
6
6
  "license": "Apache-2.0",