matterbridge-example-dynamic-platform 2.0.14 → 2.0.15-dev-20260331-5edec31

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,6 +26,23 @@ 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.15] - 2026-03-30
30
+
31
+ ### Added
32
+
33
+ - [DoorLock]: Add a doorLock device with User and Pin features (default Pin is "0000").
34
+
35
+ ### Changed
36
+
37
+ - [package]: Update dependencies.
38
+ - [package]: Bump package to `automator` v.3.1.4.
39
+ - [package]: Bump `typescript` to v.6.0.2.
40
+ - [package]: Bump `typescript-eslint` to v.8.57.2.
41
+ - [package]: Bump `eslint` to v.10.1.0.
42
+ - [package]: Add `CODE_OF_CONDUCT.md`.
43
+
44
+ <a href="https://www.buymeacoffee.com/luligugithub"><img src="https://matterbridge.io/assets/bmc-button.svg" alt="Buy me a coffee" width="80"></a>
45
+
29
46
  ## [2.0.14] - 2026-03-20
30
47
 
31
48
  ### Changed
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 68 virtual devices:
27
+ It exposes 70 virtual devices:
28
28
 
29
29
  - a door contact sensor
30
30
  - a motion sensor
@@ -95,6 +95,7 @@ It exposes 68 virtual devices:
95
95
  - a speaker device (supported by SmartThings)
96
96
  - a soil sensor (Matter 1.5.0)
97
97
  - an irrigation system (Matter 1.5.0)
98
+ - an irrigation system with four zones (Matter 1.5.0)
98
99
 
99
100
  All these devices continuously change their state and position. The plugin also shows how to use all the command handlers (so you can control all the devices), how to subscribe to attributes, and how to trigger events.
100
101
 
package/dist/module.js CHANGED
@@ -3,7 +3,7 @@ import { AirConditioner, BasicVideoPlayer, BatteryStorage, Cooktop, Dishwasher,
3
3
  import { debugStringify } from 'matterbridge/logger';
4
4
  import { AreaNamespaceTag, LocationTag, NumberTag, PositionTag, RefrigeratorTag, SwitchesTag, UINT16_MAX, UINT32_MAX } from 'matterbridge/matter';
5
5
  import { AirQuality, BooleanState, BridgedDeviceBasicInformation, CarbonDioxideConcentrationMeasurement, CarbonMonoxideConcentrationMeasurement, ColorControl, Descriptor, DeviceEnergyManagement, DoorLock, ElectricalEnergyMeasurement, ElectricalPowerMeasurement, EnergyEvse, EnergyEvseMode, FanControl, FlowMeasurement, FormaldehydeConcentrationMeasurement, Identify, 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
- import { isValidBoolean, isValidNumber, isValidObject, isValidString } from 'matterbridge/utils';
6
+ import { getEnumDescription, isValidBoolean, isValidNumber, isValidObject, isValidString } from 'matterbridge/utils';
7
7
  function luxToMatter(lux) {
8
8
  if (!Number.isFinite(lux) || lux <= 0)
9
9
  return 0;
@@ -55,6 +55,7 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
55
55
  coverLift;
56
56
  coverLiftTilt;
57
57
  lock;
58
+ userPinLock;
58
59
  thermoAuto;
59
60
  thermoAutoOccupancy;
60
61
  thermoAutoPresets;
@@ -105,8 +106,8 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
105
106
  constructor(matterbridge, log, config) {
106
107
  super(matterbridge, log, config);
107
108
  this.config = config;
108
- if (this.verifyMatterbridgeVersion === undefined || typeof this.verifyMatterbridgeVersion !== 'function' || !this.verifyMatterbridgeVersion('3.7.0')) {
109
- throw new Error(`This plugin requires Matterbridge version >= "3.7.0". Please update Matterbridge from ${this.matterbridge.matterbridgeVersion} to the latest version in the frontend.`);
109
+ if (this.verifyMatterbridgeVersion === undefined || typeof this.verifyMatterbridgeVersion !== 'function' || !this.verifyMatterbridgeVersion('3.7.2')) {
110
+ throw new Error(`This plugin requires Matterbridge version >= "3.7.2". Please update Matterbridge from ${this.matterbridge.matterbridgeVersion} to the latest version in the frontend.`);
110
111
  }
111
112
  this.log.info('Initializing platform:', this.config.name);
112
113
  }
@@ -700,22 +701,44 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
700
701
  .createDefaultPowerSourceRechargeableBatteryClusterServer(30)
701
702
  .addRequiredClusterServers();
702
703
  this.lock = await this.addDevice(this.lock);
703
- this.lock?.addCommandHandler('identify', async ({ request: { identifyTime } }) => {
704
+ this.lock?.addCommandHandler('Identify.identify', async ({ request: { identifyTime } }) => {
704
705
  this.lock?.log.info(`Command identify called identifyTime:${identifyTime}`);
705
706
  });
706
- this.lock?.addCommandHandler('lockDoor', async () => {
707
+ this.lock?.addCommandHandler('DoorLock.lockDoor', async () => {
707
708
  this.lock?.log.info('Command lockDoor called');
708
709
  });
709
- this.lock?.addCommandHandler('unlockDoor', async () => {
710
+ this.lock?.addCommandHandler('DoorLock.unlockDoor', async () => {
710
711
  this.lock?.log.info('Command unlockDoor called');
711
712
  });
712
713
  await this.lock?.subscribeAttribute(DoorLock.Cluster.id, 'operatingMode', (value) => {
713
- const lookupOperatingMode = ['Normal', 'Vacation', 'Privacy', 'NoRemoteLockUnlock', 'Passage'];
714
- this.lock?.log.info('Subscribe operatingMode called with:', lookupOperatingMode[value]);
715
- const actuatorEnabled = value !== DoorLock.OperatingMode.NoRemoteLockUnlock;
716
- this.lock?.setAttribute(DoorLock.Cluster.id, 'actuatorEnabled', actuatorEnabled);
717
- this.lock?.log.info(`actuatorEnabled set to ${actuatorEnabled}`);
714
+ this.lock?.log.info(`Subscribe operatingMode called with: ${getEnumDescription(DoorLock.OperatingMode, value)}`);
718
715
  }, this.lock.log);
716
+ this.userPinLock = new MatterbridgeEndpoint([doorLockDevice, bridgedNode, powerSource], { id: 'UserPinLock' }, this.config.debug)
717
+ .createDefaultIdentifyClusterServer()
718
+ .createDefaultBridgedDeviceBasicInformationClusterServer('Lock with User and Pin', 'LUP00070', 0xfff1, 'Matterbridge', 'Matterbridge Lock')
719
+ .createUserPinDoorLockClusterServer()
720
+ .createDefaultPowerSourceRechargeableBatteryClusterServer(95)
721
+ .addRequiredClusterServers();
722
+ this.userPinLock = await this.addDevice(this.userPinLock);
723
+ await this.userPinLock?.setAttribute(PowerSource.Cluster.with(PowerSource.Feature.Rechargeable, PowerSource.Feature.Battery), 'batChargeState', PowerSource.BatChargeState.IsCharging);
724
+ this.userPinLock?.addCommandHandler('Identify.identify', async ({ request: { identifyTime } }) => {
725
+ this.userPinLock?.log.info(`Command identify called identifyTime:${identifyTime}`);
726
+ });
727
+ this.userPinLock?.addCommandHandler('DoorLock.lockDoor', async () => {
728
+ this.userPinLock?.log.info('Command lockDoor called');
729
+ });
730
+ this.userPinLock?.addCommandHandler('DoorLock.unlockDoor', async () => {
731
+ this.userPinLock?.log.info('Command unlockDoor called');
732
+ });
733
+ await this.userPinLock?.subscribeAttribute(DoorLock.Cluster, 'operatingMode', (value) => {
734
+ this.userPinLock?.log.info(`Subscribe operatingMode called with: ${getEnumDescription(DoorLock.OperatingMode, value)}`);
735
+ }, this.userPinLock.log);
736
+ await this.userPinLock?.subscribeAttribute(DoorLock.Complete, 'wrongCodeEntryLimit', (value) => {
737
+ this.userPinLock?.log.info(`Subscribe wrongCodeEntryLimit called with: ${value}`);
738
+ }, this.userPinLock.log);
739
+ await this.userPinLock?.subscribeAttribute(DoorLock.Complete, 'userCodeTemporaryDisableTime', (value) => {
740
+ this.userPinLock?.log.info(`Subscribe userCodeTemporaryDisableTime called with: ${value}`);
741
+ }, this.userPinLock.log);
719
742
  this.thermoAuto = new MatterbridgeEndpoint([thermostatDevice, bridgedNode, powerSource], { id: 'Thermostat (AutoMode)' }, this.config.debug)
720
743
  .createDefaultIdentifyClusterServer()
721
744
  .createDefaultBridgedDeviceBasicInformationClusterServer('Thermostat (Auto)', 'TAU00023', 0xfff1, 'Matterbridge', 'Matterbridge Thermostat')
@@ -5,13 +5,13 @@
5
5
  "required": [],
6
6
  "properties": {
7
7
  "name": {
8
- "description": "Plugin name",
8
+ "description": "Plugin Name",
9
9
  "type": "string",
10
10
  "readOnly": true,
11
11
  "ui:widget": "hidden"
12
12
  },
13
13
  "type": {
14
- "description": "Plugin type",
14
+ "description": "Plugin Type",
15
15
  "type": "string",
16
16
  "readOnly": true,
17
17
  "ui:widget": "hidden"
@@ -49,13 +49,13 @@
49
49
  "default": true
50
50
  },
51
51
  "debug": {
52
- "title": "Debug",
52
+ "title": "Enable Debug",
53
53
  "description": "Enable the debug for the plugin (development only)",
54
54
  "type": "boolean",
55
55
  "default": false
56
56
  },
57
57
  "unregisterOnShutdown": {
58
- "title": "Unregister on Shutdown",
58
+ "title": "Unregister On Shutdown",
59
59
  "description": "Unregister all devices on shutdown (development only)",
60
60
  "type": "boolean",
61
61
  "default": false
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "matterbridge-example-dynamic-platform",
3
- "version": "2.0.14",
3
+ "version": "2.0.15-dev-20260331-5edec31",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "matterbridge-example-dynamic-platform",
9
- "version": "2.0.14",
9
+ "version": "2.0.15-dev-20260331-5edec31",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "node-ansi-logger": "3.2.0",
13
13
  "node-persist-manager": "2.0.1"
14
14
  },
15
15
  "engines": {
16
- "node": ">=20.0.0 <21.0.0 || >=22.0.0 <23.0.0 || >=24.0.0 <25.0.0"
16
+ "node": ">=20.19.0 <21.0.0 || >=22.13.0 <23.0.0 || >=24.0.0 <25.0.0"
17
17
  },
18
18
  "funding": {
19
19
  "type": "buymeacoffee",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "matterbridge-example-dynamic-platform",
3
- "version": "2.0.14",
3
+ "version": "2.0.15-dev-20260331-5edec31",
4
4
  "description": "Matterbridge dynamic plugin",
5
5
  "author": "https://github.com/Luligu",
6
6
  "license": "Apache-2.0",
@@ -56,7 +56,7 @@
56
56
  "ewelink"
57
57
  ],
58
58
  "engines": {
59
- "node": ">=20.0.0 <21.0.0 || >=22.0.0 <23.0.0 || >=24.0.0 <25.0.0"
59
+ "node": ">=20.19.0 <21.0.0 || >=22.13.0 <23.0.0 || >=24.0.0 <25.0.0"
60
60
  },
61
61
  "files": [
62
62
  "bin",
@@ -71,6 +71,7 @@
71
71
  "node-persist-manager": "2.0.1"
72
72
  },
73
73
  "overrides": {
74
+ "typescript": "6.0.2",
74
75
  "eslint": "10.1.0",
75
76
  "@eslint/js": "10.0.1"
76
77
  }