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 +17 -0
- package/README.md +2 -1
- package/dist/module.js +34 -11
- package/matterbridge-example-dynamic-platform.schema.json +4 -4
- package/npm-shrinkwrap.json +3 -3
- package/package.json +3 -2
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
|
|
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.
|
|
109
|
-
throw new Error(`This plugin requires Matterbridge version >= "3.7.
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
58
|
+
"title": "Unregister On Shutdown",
|
|
59
59
|
"description": "Unregister all devices on shutdown (development only)",
|
|
60
60
|
"type": "boolean",
|
|
61
61
|
"default": false
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "matterbridge-example-dynamic-platform",
|
|
3
|
-
"version": "2.0.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
}
|