matterbridge-example-dynamic-platform 1.3.4-dev-20250720-e338589 → 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/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 44 virtual devices:
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
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
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;
@@ -65,6 +67,7 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
65
67
  intervalColorTemperature = 147;
66
68
  bridgedDevices = new Map();
67
69
  fanModeLookup = ['Off', 'Low', 'Medium', 'High', 'On', 'Auto', 'Smart'];
70
+ fanDirectionLookup = ['Forward', 'Reverse'];
68
71
  constructor(matterbridge, log, config) {
69
72
  super(matterbridge, log, config);
70
73
  if (this.verifyMatterbridgeVersion === undefined || typeof this.verifyMatterbridgeVersion !== 'function' || !this.verifyMatterbridgeVersion('3.1.6')) {
@@ -844,6 +847,64 @@ export class ExampleMatterbridgeDynamicPlatform extends MatterbridgeDynamicPlatf
844
847
  if (isValidNumber(newValue, 0, 100))
845
848
  this.fan?.setAttribute(FanControl.Cluster.id, 'percentCurrent', newValue, this.fan?.log);
846
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);
847
908
  this.waterLeak = new MatterbridgeEndpoint([waterLeakDetector, bridgedNode, powerSource], { uniqueStorageKey: 'Water leak detector' }, this.config.debug)
848
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)
849
910
  .createDefaultPowerSourceRechargeableBatteryClusterServer()
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "matterbridge-example-dynamic-platform",
3
- "version": "1.3.4-dev-20250720-e338589",
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.4-dev-20250720-e338589",
9
+ "version": "1.3.4",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "node-ansi-logger": "3.1.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "matterbridge-example-dynamic-platform",
3
- "version": "1.3.4-dev-20250720-e338589",
3
+ "version": "1.3.4",
4
4
  "description": "Matterbridge dynamic plugin",
5
5
  "author": "https://github.com/Luligu",
6
6
  "license": "Apache-2.0",