matterbridge-example-dynamic-platform 1.3.3 → 1.3.4
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 +15 -0
- package/README.md +2 -1
- package/dist/platform.js +78 -15
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
@@ -23,6 +23,21 @@ If you like this project and find it useful, please consider giving it a star on
|
|
23
23
|
<img src="bmc-button.svg" alt="Buy me a coffee" width="120">
|
24
24
|
</a>
|
25
25
|
|
26
|
+
## [1.3.4] - 2025-07-22
|
27
|
+
|
28
|
+
### Added
|
29
|
+
|
30
|
+
- [platform]: Changed to the new ExtratorHood() and Dishwasher() from Matterbridge.
|
31
|
+
|
32
|
+
### Changed
|
33
|
+
|
34
|
+
- [package]: Updated dependencies.
|
35
|
+
- [package]: Required matterbridge 3.1.6.
|
36
|
+
|
37
|
+
<a href="https://www.buymeacoffee.com/luligugithub">
|
38
|
+
<img src="bmc-button.svg" alt="Buy me a coffee" width="80">
|
39
|
+
</a>
|
40
|
+
|
26
41
|
## [1.3.3] - 2025-07-20
|
27
42
|
|
28
43
|
### Added
|
package/README.md
CHANGED
@@ -17,7 +17,7 @@
|
|
17
17
|
|
18
18
|
Matterbridge dynamic platform example plugin is a template to develop your own plugin using the dynamic platform.
|
19
19
|
|
20
|
-
It exposes
|
20
|
+
It exposes 45 virtual devices:
|
21
21
|
|
22
22
|
- a switch with onOff cluster
|
23
23
|
- a light with onOff
|
@@ -35,6 +35,7 @@ It exposes 44 virtual devices:
|
|
35
35
|
- a thermo heat only with two external temperature sensors (tagged like Indoor and Outdoor)
|
36
36
|
- a thermo cool only
|
37
37
|
- a fan with FanControl cluster
|
38
|
+
- a fan with all the features from FanControl cluster
|
38
39
|
- a rainSensor device
|
39
40
|
- a waterFreezeDetector device
|
40
41
|
- a waterLeakDetector device
|
package/dist/platform.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
import { MatterbridgeEndpoint, MatterbridgeDynamicPlatform, airQualitySensor, bridgedNode, colorTemperatureLight, coverDevice, dimmableLight, doorLockDevice, fanDevice, flowSensor, humiditySensor, onOffLight, onOffOutlet, onOffSwitch, powerSource, rainSensor, smokeCoAlarm, temperatureSensor, thermostatDevice, waterFreezeDetector, waterLeakDetector, airPurifier, pumpDevice, waterValve, genericSwitch, airConditioner, cooktop,
|
2
|
-
import { RoboticVacuumCleaner, LaundryWasher, WaterHeater, Evse, SolarPower, BatteryStorage, LaundryDryer, HeatPump } from 'matterbridge/devices';
|
1
|
+
import { MatterbridgeEndpoint, MatterbridgeDynamicPlatform, airQualitySensor, bridgedNode, colorTemperatureLight, coverDevice, dimmableLight, doorLockDevice, fanDevice, flowSensor, humiditySensor, onOffLight, onOffOutlet, onOffSwitch, powerSource, rainSensor, smokeCoAlarm, temperatureSensor, thermostatDevice, waterFreezeDetector, waterLeakDetector, airPurifier, pumpDevice, waterValve, genericSwitch, airConditioner, cooktop, microwaveOven, oven, refrigerator, onOffMountedSwitch, dimmableMountedSwitch, extendedColorLight, } from 'matterbridge';
|
2
|
+
import { RoboticVacuumCleaner, LaundryWasher, WaterHeater, Evse, SolarPower, BatteryStorage, LaundryDryer, HeatPump, Dishwasher, ExtractorHood } from 'matterbridge/devices';
|
3
3
|
import { isValidBoolean, isValidNumber } from 'matterbridge/utils';
|
4
|
+
import { debugStringify } from 'matterbridge/logger';
|
4
5
|
import { AreaNamespaceTag, LocationTag, NumberTag, PositionTag } from 'matterbridge/matter';
|
5
6
|
import { PowerSource, BooleanState, OnOff, LevelControl, AirQuality, CarbonDioxideConcentrationMeasurement, CarbonMonoxideConcentrationMeasurement, FlowMeasurement, ColorControl, DoorLock, FanControl, FormaldehydeConcentrationMeasurement, NitrogenDioxideConcentrationMeasurement, OzoneConcentrationMeasurement, Pm10ConcentrationMeasurement, Pm1ConcentrationMeasurement, Pm25ConcentrationMeasurement, RadonConcentrationMeasurement, RelativeHumidityMeasurement, RelativeHumidityMeasurementCluster, SmokeCoAlarm, TemperatureMeasurement, Thermostat, ThermostatCluster, TotalVolatileOrganicCompoundsConcentrationMeasurement, WindowCovering, EnergyEvseMode, EnergyEvse, RvcRunMode, RvcCleanMode, } from 'matterbridge/matter/clusters';
|
6
7
|
import { Appliances } from './appliances.js';
|
@@ -22,6 +23,7 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
|
|
22
23
|
thermoHeat;
|
23
24
|
thermoCool;
|
24
25
|
fan;
|
26
|
+
fanComplete;
|
25
27
|
waterLeak;
|
26
28
|
waterFreeze;
|
27
29
|
rain;
|
@@ -40,6 +42,8 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
|
|
40
42
|
evse;
|
41
43
|
laundryWasher;
|
42
44
|
laundryDryer;
|
45
|
+
dishwasher;
|
46
|
+
extractorHood;
|
43
47
|
solarPower;
|
44
48
|
batteryStorage;
|
45
49
|
heatPump;
|
@@ -63,10 +67,11 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
|
|
63
67
|
intervalColorTemperature = 147;
|
64
68
|
bridgedDevices = new Map();
|
65
69
|
fanModeLookup = ['Off', 'Low', 'Medium', 'High', 'On', 'Auto', 'Smart'];
|
70
|
+
fanDirectionLookup = ['Forward', 'Reverse'];
|
66
71
|
constructor(matterbridge, log, config) {
|
67
72
|
super(matterbridge, log, config);
|
68
|
-
if (this.verifyMatterbridgeVersion === undefined || typeof this.verifyMatterbridgeVersion !== 'function' || !this.verifyMatterbridgeVersion('3.1.
|
69
|
-
throw new Error(`This plugin requires Matterbridge version >= "3.1.
|
73
|
+
if (this.verifyMatterbridgeVersion === undefined || typeof this.verifyMatterbridgeVersion !== 'function' || !this.verifyMatterbridgeVersion('3.1.6')) {
|
74
|
+
throw new Error(`This plugin requires Matterbridge version >= "3.1.6". Please update Matterbridge from ${this.matterbridge.matterbridgeVersion} to the latest version in the frontend.`);
|
70
75
|
}
|
71
76
|
this.log.info('Initializing platform:', this.config.name);
|
72
77
|
if (config.whiteList === undefined)
|
@@ -842,6 +847,64 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
|
|
842
847
|
if (isValidNumber(newValue, 0, 100))
|
843
848
|
this.fan?.setAttribute(FanControl.Cluster.id, 'percentCurrent', newValue, this.fan?.log);
|
844
849
|
}, this.fan.log);
|
850
|
+
this.fanComplete = new MatterbridgeEndpoint([fanDevice, bridgedNode, powerSource], { uniqueStorageKey: 'Fan complete' }, this.config.debug)
|
851
|
+
.createDefaultBridgedDeviceBasicInformationClusterServer('Fan complete', 'serial_980995631228', 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)
|
852
|
+
.createDefaultPowerSourceWiredClusterServer()
|
853
|
+
.createCompleteFanControlClusterServer()
|
854
|
+
.addRequiredClusterServers();
|
855
|
+
this.setSelectDevice(this.fanComplete.serialNumber ?? '', this.fanComplete.deviceName ?? '', undefined, 'hub');
|
856
|
+
if (this.validateDevice(this.fanComplete.deviceName ?? '')) {
|
857
|
+
await this.registerDevice(this.fanComplete);
|
858
|
+
this.bridgedDevices.set(this.fanComplete.deviceName ?? '', this.fanComplete);
|
859
|
+
}
|
860
|
+
else {
|
861
|
+
this.fanComplete = undefined;
|
862
|
+
}
|
863
|
+
await this.fanComplete?.subscribeAttribute(FanControl.Cluster.id, 'fanMode', (newValue, oldValue, context) => {
|
864
|
+
this.fanComplete?.log.info(`Fan mode changed from ${this.fanModeLookup[oldValue]} to ${this.fanModeLookup[newValue]} context: ${context.offline === true ? 'offline' : 'online'}`);
|
865
|
+
if (context.offline === true)
|
866
|
+
return;
|
867
|
+
if (newValue === FanControl.FanMode.Off) {
|
868
|
+
this.fanComplete?.setAttribute(FanControl.Cluster.id, 'percentSetting', 0, this.fanComplete?.log);
|
869
|
+
this.fanComplete?.setAttribute(FanControl.Cluster.id, 'percentCurrent', 0, this.fanComplete?.log);
|
870
|
+
}
|
871
|
+
else if (newValue === FanControl.FanMode.Low) {
|
872
|
+
this.fanComplete?.setAttribute(FanControl.Cluster.id, 'percentSetting', 33, this.fanComplete?.log);
|
873
|
+
this.fanComplete?.setAttribute(FanControl.Cluster.id, 'percentCurrent', 33, this.fanComplete?.log);
|
874
|
+
}
|
875
|
+
else if (newValue === FanControl.FanMode.Medium) {
|
876
|
+
this.fanComplete?.setAttribute(FanControl.Cluster.id, 'percentSetting', 66, this.fanComplete?.log);
|
877
|
+
this.fanComplete?.setAttribute(FanControl.Cluster.id, 'percentCurrent', 66, this.fanComplete?.log);
|
878
|
+
}
|
879
|
+
else if (newValue === FanControl.FanMode.High) {
|
880
|
+
this.fanComplete?.setAttribute(FanControl.Cluster.id, 'percentSetting', 100, this.fanComplete?.log);
|
881
|
+
this.fanComplete?.setAttribute(FanControl.Cluster.id, 'percentCurrent', 100, this.fanComplete?.log);
|
882
|
+
}
|
883
|
+
else if (newValue === FanControl.FanMode.On) {
|
884
|
+
this.fanComplete?.setAttribute(FanControl.Cluster.id, 'percentSetting', 100, this.fanComplete?.log);
|
885
|
+
this.fanComplete?.setAttribute(FanControl.Cluster.id, 'percentCurrent', 100, this.fanComplete?.log);
|
886
|
+
}
|
887
|
+
else if (newValue === FanControl.FanMode.Auto) {
|
888
|
+
this.fanComplete?.setAttribute(FanControl.Cluster.id, 'percentSetting', 50, this.fanComplete?.log);
|
889
|
+
this.fanComplete?.setAttribute(FanControl.Cluster.id, 'percentCurrent', 50, this.fanComplete?.log);
|
890
|
+
}
|
891
|
+
}, this.fanComplete?.log);
|
892
|
+
await this.fanComplete?.subscribeAttribute(FanControl.Cluster.id, 'percentSetting', (newValue, oldValue, context) => {
|
893
|
+
this.fanComplete?.log.info(`Percent setting changed from ${oldValue} to ${newValue} context: ${context.offline === true ? 'offline' : 'online'}`);
|
894
|
+
if (context.offline === true)
|
895
|
+
return;
|
896
|
+
if (isValidNumber(newValue, 0, 100))
|
897
|
+
this.fanComplete?.setAttribute(FanControl.Cluster.id, 'percentCurrent', newValue, this.fanComplete?.log);
|
898
|
+
}, this.fanComplete?.log);
|
899
|
+
await this.fanComplete?.subscribeAttribute(FanControl.Cluster.id, 'rockSetting', (newValue, oldValue, context) => {
|
900
|
+
this.fanComplete?.log.info(`Rock setting changed from ${debugStringify(oldValue)} to ${debugStringify(newValue)} context: ${context.offline === true ? 'offline' : 'online'}`);
|
901
|
+
}, this.fanComplete?.log);
|
902
|
+
await this.fanComplete?.subscribeAttribute(FanControl.Cluster.id, 'windSetting', (newValue, oldValue, context) => {
|
903
|
+
this.fanComplete?.log.info(`Wind setting changed from ${debugStringify(oldValue)} to ${debugStringify(newValue)} context: ${context.offline === true ? 'offline' : 'online'}`);
|
904
|
+
}, this.fanComplete?.log);
|
905
|
+
await this.fanComplete?.subscribeAttribute(FanControl.Cluster.id, 'airflowDirection', (newValue, oldValue, context) => {
|
906
|
+
this.fanComplete?.log.info(`Airflow direction changed from ${this.fanDirectionLookup[oldValue]} to ${this.fanDirectionLookup[newValue]} context: ${context.offline === true ? 'offline' : 'online'}`);
|
907
|
+
}, this.fanComplete?.log);
|
845
908
|
this.waterLeak = new MatterbridgeEndpoint([waterLeakDetector, bridgedNode, powerSource], { uniqueStorageKey: 'Water leak detector' }, this.config.debug)
|
846
909
|
.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)
|
847
910
|
.createDefaultPowerSourceRechargeableBatteryClusterServer()
|
@@ -1103,11 +1166,17 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
|
|
1103
1166
|
await this.registerDevice(this.laundryDryer);
|
1104
1167
|
this.bridgedDevices.set(this.laundryDryer.deviceName ?? '', this.laundryDryer);
|
1105
1168
|
}
|
1106
|
-
|
1107
|
-
this.setSelectDevice(
|
1108
|
-
if (this.validateDevice(
|
1109
|
-
await this.registerDevice(
|
1110
|
-
this.bridgedDevices.set(
|
1169
|
+
this.dishwasher = new Dishwasher('Dishwasher', 'DW1234567890');
|
1170
|
+
this.setSelectDevice(this.dishwasher.serialNumber ?? '', this.dishwasher.deviceName ?? '', undefined, 'hub');
|
1171
|
+
if (this.validateDevice(this.dishwasher.deviceName ?? '')) {
|
1172
|
+
await this.registerDevice(this.dishwasher);
|
1173
|
+
this.bridgedDevices.set(this.dishwasher.deviceName ?? '', this.dishwasher);
|
1174
|
+
}
|
1175
|
+
this.extractorHood = new ExtractorHood('Extractor Hood', 'EH1234567893');
|
1176
|
+
this.setSelectDevice(this.extractorHood.serialNumber ?? '', this.extractorHood.deviceName ?? '', undefined, 'hub');
|
1177
|
+
if (this.validateDevice(this.extractorHood.deviceName ?? '')) {
|
1178
|
+
await this.registerDevice(this.extractorHood);
|
1179
|
+
this.bridgedDevices.set(this.extractorHood.deviceName ?? '', this.extractorHood);
|
1111
1180
|
}
|
1112
1181
|
const refrigeratorDevice = new Appliances(refrigerator, 'Refrigerator', 'RE9987654322');
|
1113
1182
|
refrigeratorDevice.addFixedLabel('composed', 'Refrigerator');
|
@@ -1129,12 +1198,6 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
|
|
1129
1198
|
await this.registerDevice(microwaveOvenDevice);
|
1130
1199
|
this.bridgedDevices.set(microwaveOvenDevice.deviceName ?? '', microwaveOvenDevice);
|
1131
1200
|
}
|
1132
|
-
const extractorHoodDevice = new Appliances(extractorHood, 'Extractor Hood', 'EH1234567893');
|
1133
|
-
this.setSelectDevice(extractorHoodDevice.serialNumber ?? '', extractorHoodDevice.deviceName ?? '', undefined, 'hub');
|
1134
|
-
if (this.validateDevice(extractorHoodDevice.deviceName ?? '')) {
|
1135
|
-
await this.registerDevice(extractorHoodDevice);
|
1136
|
-
this.bridgedDevices.set(extractorHoodDevice.deviceName ?? '', extractorHoodDevice);
|
1137
|
-
}
|
1138
1201
|
const cooktopDevice = new Appliances(cooktop, 'Cooktop', 'CT1255887894');
|
1139
1202
|
this.setSelectDevice(cooktopDevice.serialNumber ?? '', cooktopDevice.deviceName ?? '', undefined, 'hub');
|
1140
1203
|
if (this.validateDevice(cooktopDevice.deviceName ?? '')) {
|
package/npm-shrinkwrap.json
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
{
|
2
2
|
"name": "matterbridge-example-dynamic-platform",
|
3
|
-
"version": "1.3.
|
3
|
+
"version": "1.3.4",
|
4
4
|
"lockfileVersion": 3,
|
5
5
|
"requires": true,
|
6
6
|
"packages": {
|
7
7
|
"": {
|
8
8
|
"name": "matterbridge-example-dynamic-platform",
|
9
|
-
"version": "1.3.
|
9
|
+
"version": "1.3.4",
|
10
10
|
"license": "Apache-2.0",
|
11
11
|
"dependencies": {
|
12
12
|
"node-ansi-logger": "3.1.1",
|