matterbridge 3.3.4-dev-20251020-4d2dd49 → 3.3.4-dev-20251021-7651f57

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.
Files changed (37) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README-DOCKER.md +4 -1
  3. package/README-SERVICE.md +4 -3
  4. package/dist/cli.js +7 -6
  5. package/dist/devices/airConditioner.js +2 -2
  6. package/dist/devices/batteryStorage.js +3 -3
  7. package/dist/devices/dishwasher.js +4 -4
  8. package/dist/devices/evse.js +6 -5
  9. package/dist/devices/extractorHood.js +1 -1
  10. package/dist/devices/heatPump.js +2 -2
  11. package/dist/devices/laundryDryer.js +3 -3
  12. package/dist/devices/laundryWasher.js +5 -5
  13. package/dist/devices/microwaveOven.js +5 -5
  14. package/dist/devices/oven.js +5 -5
  15. package/dist/devices/refrigerator.js +4 -4
  16. package/dist/devices/roboticVacuumCleaner.js +11 -11
  17. package/dist/devices/solarPower.js +2 -2
  18. package/dist/devices/speaker.js +2 -1
  19. package/dist/devices/temperatureControl.js +2 -2
  20. package/dist/devices/waterHeater.js +6 -6
  21. package/dist/frontend.js +27 -26
  22. package/dist/helpers.js +1 -1
  23. package/dist/matterbridge.js +46 -13
  24. package/dist/matterbridgeAccessoryPlatform.js +2 -0
  25. package/dist/matterbridgeBehaviors.js +39 -20
  26. package/dist/matterbridgeDeviceTypes.js +88 -86
  27. package/dist/matterbridgeDynamicPlatform.js +2 -0
  28. package/dist/matterbridgeEndpoint.js +92 -154
  29. package/dist/matterbridgeEndpointHelpers.js +221 -137
  30. package/dist/matterbridgePlatform.js +2 -2
  31. package/dist/update.js +1 -1
  32. package/dist/utils/format.js +29 -0
  33. package/dist/utils/jestHelpers.js +7 -3
  34. package/dist/utils/network.js +0 -26
  35. package/dist/utils/tracker.js +17 -45
  36. package/npm-shrinkwrap.json +2 -2
  37. package/package.json +1 -1
@@ -1,83 +1,88 @@
1
+ if (process.argv.includes('--loader') || process.argv.includes('-loader'))
2
+ console.log('\u001B[32mMatterbridgeEndpointHelpers loaded.\u001B[40;0m');
1
3
  import { createHash } from 'node:crypto';
2
4
  import { BLUE, CYAN, db, debugStringify, er, hk, or, YELLOW, zb } from 'node-ansi-logger';
3
- import { Lifecycle } from '@matter/main';
4
- import { getClusterNameById, MeasurementType } from '@matter/main/types';
5
- import { PowerSource } from '@matter/main/clusters/power-source';
6
- import { UserLabel } from '@matter/main/clusters/user-label';
7
- import { FixedLabel } from '@matter/main/clusters/fixed-label';
8
- import { BasicInformation } from '@matter/main/clusters/basic-information';
9
- import { BridgedDeviceBasicInformation } from '@matter/main/clusters/bridged-device-basic-information';
10
- import { Identify } from '@matter/main/clusters/identify';
11
- import { Groups } from '@matter/main/clusters/groups';
12
- import { OnOff } from '@matter/main/clusters/on-off';
13
- import { LevelControl } from '@matter/main/clusters/level-control';
14
- import { ColorControl } from '@matter/main/clusters/color-control';
15
- import { WindowCovering } from '@matter/main/clusters/window-covering';
16
- import { Thermostat } from '@matter/main/clusters/thermostat';
17
- import { FanControl } from '@matter/main/clusters/fan-control';
18
- import { DoorLock } from '@matter/main/clusters/door-lock';
19
- import { ModeSelect } from '@matter/main/clusters/mode-select';
20
- import { ValveConfigurationAndControl } from '@matter/main/clusters/valve-configuration-and-control';
21
- import { PumpConfigurationAndControl } from '@matter/main/clusters/pump-configuration-and-control';
22
- import { SmokeCoAlarm } from '@matter/main/clusters/smoke-co-alarm';
23
- import { Switch } from '@matter/main/clusters/switch';
24
- import { BooleanState } from '@matter/main/clusters/boolean-state';
25
- import { BooleanStateConfiguration } from '@matter/main/clusters/boolean-state-configuration';
26
- import { PowerTopology } from '@matter/main/clusters/power-topology';
27
- import { ElectricalPowerMeasurement } from '@matter/main/clusters/electrical-power-measurement';
28
- import { ElectricalEnergyMeasurement } from '@matter/main/clusters/electrical-energy-measurement';
29
- import { TemperatureMeasurement } from '@matter/main/clusters/temperature-measurement';
30
- import { RelativeHumidityMeasurement } from '@matter/main/clusters/relative-humidity-measurement';
31
- import { PressureMeasurement } from '@matter/main/clusters/pressure-measurement';
32
- import { FlowMeasurement } from '@matter/main/clusters/flow-measurement';
33
- import { IlluminanceMeasurement } from '@matter/main/clusters/illuminance-measurement';
34
- import { OccupancySensing } from '@matter/main/clusters/occupancy-sensing';
35
- import { AirQuality } from '@matter/main/clusters/air-quality';
36
- import { CarbonMonoxideConcentrationMeasurement } from '@matter/main/clusters/carbon-monoxide-concentration-measurement';
37
- import { CarbonDioxideConcentrationMeasurement } from '@matter/main/clusters/carbon-dioxide-concentration-measurement';
38
- import { NitrogenDioxideConcentrationMeasurement } from '@matter/main/clusters/nitrogen-dioxide-concentration-measurement';
39
- import { OzoneConcentrationMeasurement } from '@matter/main/clusters/ozone-concentration-measurement';
40
- import { FormaldehydeConcentrationMeasurement } from '@matter/main/clusters/formaldehyde-concentration-measurement';
41
- import { Pm1ConcentrationMeasurement } from '@matter/main/clusters/pm1-concentration-measurement';
42
- import { Pm25ConcentrationMeasurement } from '@matter/main/clusters/pm25-concentration-measurement';
43
- import { Pm10ConcentrationMeasurement } from '@matter/main/clusters/pm10-concentration-measurement';
44
- import { RadonConcentrationMeasurement } from '@matter/main/clusters/radon-concentration-measurement';
45
- import { TotalVolatileOrganicCompoundsConcentrationMeasurement } from '@matter/main/clusters/total-volatile-organic-compounds-concentration-measurement';
46
- import { OperationalState } from '@matter/main/clusters/operational-state';
47
- import { DeviceEnergyManagement } from '@matter/main/clusters/device-energy-management';
48
- import { DeviceEnergyManagementMode } from '@matter/main/clusters/device-energy-management-mode';
49
- import { PowerSourceServer } from '@matter/main/behaviors/power-source';
50
- import { UserLabelServer } from '@matter/main/behaviors/user-label';
51
- import { FixedLabelServer } from '@matter/main/behaviors/fixed-label';
52
- import { BasicInformationServer } from '@matter/main/behaviors/basic-information';
53
- import { BridgedDeviceBasicInformationServer } from '@matter/main/behaviors/bridged-device-basic-information';
54
- import { GroupsServer } from '@matter/main/behaviors/groups';
55
- import { PumpConfigurationAndControlServer } from '@matter/main/behaviors/pump-configuration-and-control';
56
- import { SwitchServer } from '@matter/main/behaviors/switch';
57
- import { BooleanStateServer } from '@matter/main/behaviors/boolean-state';
58
- import { PowerTopologyServer } from '@matter/main/behaviors/power-topology';
59
- import { ElectricalPowerMeasurementServer } from '@matter/main/behaviors/electrical-power-measurement';
60
- import { ElectricalEnergyMeasurementServer } from '@matter/main/behaviors/electrical-energy-measurement';
61
- import { TemperatureMeasurementServer } from '@matter/main/behaviors/temperature-measurement';
62
- import { RelativeHumidityMeasurementServer } from '@matter/main/behaviors/relative-humidity-measurement';
63
- import { PressureMeasurementServer } from '@matter/main/behaviors/pressure-measurement';
64
- import { FlowMeasurementServer } from '@matter/main/behaviors/flow-measurement';
65
- import { IlluminanceMeasurementServer } from '@matter/main/behaviors/illuminance-measurement';
66
- import { OccupancySensingServer } from '@matter/main/behaviors/occupancy-sensing';
67
- import { AirQualityServer } from '@matter/main/behaviors/air-quality';
68
- import { CarbonMonoxideConcentrationMeasurementServer } from '@matter/main/behaviors/carbon-monoxide-concentration-measurement';
69
- import { CarbonDioxideConcentrationMeasurementServer } from '@matter/main/behaviors/carbon-dioxide-concentration-measurement';
70
- import { NitrogenDioxideConcentrationMeasurementServer } from '@matter/main/behaviors/nitrogen-dioxide-concentration-measurement';
71
- import { OzoneConcentrationMeasurementServer } from '@matter/main/behaviors/ozone-concentration-measurement';
72
- import { FormaldehydeConcentrationMeasurementServer } from '@matter/main/behaviors/formaldehyde-concentration-measurement';
73
- import { Pm1ConcentrationMeasurementServer } from '@matter/main/behaviors/pm1-concentration-measurement';
74
- import { Pm25ConcentrationMeasurementServer } from '@matter/main/behaviors/pm25-concentration-measurement';
75
- import { Pm10ConcentrationMeasurementServer } from '@matter/main/behaviors/pm10-concentration-measurement';
76
- import { RadonConcentrationMeasurementServer } from '@matter/main/behaviors/radon-concentration-measurement';
77
- import { TotalVolatileOrganicCompoundsConcentrationMeasurementServer } from '@matter/main/behaviors/total-volatile-organic-compounds-concentration-measurement';
5
+ import { Lifecycle } from '@matter/general';
6
+ import { MeasurementType } from '@matter/types/globals';
7
+ import { getClusterNameById } from '@matter/types/cluster';
8
+ import { PowerSource } from '@matter/types/clusters/power-source';
9
+ import { UserLabel } from '@matter/types/clusters/user-label';
10
+ import { FixedLabel } from '@matter/types/clusters/fixed-label';
11
+ import { BasicInformation } from '@matter/types/clusters/basic-information';
12
+ import { BridgedDeviceBasicInformation } from '@matter/types/clusters/bridged-device-basic-information';
13
+ import { Identify } from '@matter/types/clusters/identify';
14
+ import { Groups } from '@matter/types/clusters/groups';
15
+ import { OnOff } from '@matter/types/clusters/on-off';
16
+ import { LevelControl } from '@matter/types/clusters/level-control';
17
+ import { ColorControl } from '@matter/types/clusters/color-control';
18
+ import { WindowCovering } from '@matter/types/clusters/window-covering';
19
+ import { Thermostat } from '@matter/types/clusters/thermostat';
20
+ import { FanControl } from '@matter/types/clusters/fan-control';
21
+ import { DoorLock } from '@matter/types/clusters/door-lock';
22
+ import { ModeSelect } from '@matter/types/clusters/mode-select';
23
+ import { ValveConfigurationAndControl } from '@matter/types/clusters/valve-configuration-and-control';
24
+ import { PumpConfigurationAndControl } from '@matter/types/clusters/pump-configuration-and-control';
25
+ import { SmokeCoAlarm } from '@matter/types/clusters/smoke-co-alarm';
26
+ import { Switch } from '@matter/types/clusters/switch';
27
+ import { BooleanState } from '@matter/types/clusters/boolean-state';
28
+ import { BooleanStateConfiguration } from '@matter/types/clusters/boolean-state-configuration';
29
+ import { PowerTopology } from '@matter/types/clusters/power-topology';
30
+ import { ElectricalPowerMeasurement } from '@matter/types/clusters/electrical-power-measurement';
31
+ import { ElectricalEnergyMeasurement } from '@matter/types/clusters/electrical-energy-measurement';
32
+ import { TemperatureMeasurement } from '@matter/types/clusters/temperature-measurement';
33
+ import { RelativeHumidityMeasurement } from '@matter/types/clusters/relative-humidity-measurement';
34
+ import { PressureMeasurement } from '@matter/types/clusters/pressure-measurement';
35
+ import { FlowMeasurement } from '@matter/types/clusters/flow-measurement';
36
+ import { IlluminanceMeasurement } from '@matter/types/clusters/illuminance-measurement';
37
+ import { OccupancySensing } from '@matter/types/clusters/occupancy-sensing';
38
+ import { AirQuality } from '@matter/types/clusters/air-quality';
39
+ import { CarbonMonoxideConcentrationMeasurement } from '@matter/types/clusters/carbon-monoxide-concentration-measurement';
40
+ import { CarbonDioxideConcentrationMeasurement } from '@matter/types/clusters/carbon-dioxide-concentration-measurement';
41
+ import { NitrogenDioxideConcentrationMeasurement } from '@matter/types/clusters/nitrogen-dioxide-concentration-measurement';
42
+ import { OzoneConcentrationMeasurement } from '@matter/types/clusters/ozone-concentration-measurement';
43
+ import { FormaldehydeConcentrationMeasurement } from '@matter/types/clusters/formaldehyde-concentration-measurement';
44
+ import { Pm1ConcentrationMeasurement } from '@matter/types/clusters/pm1-concentration-measurement';
45
+ import { Pm25ConcentrationMeasurement } from '@matter/types/clusters/pm25-concentration-measurement';
46
+ import { Pm10ConcentrationMeasurement } from '@matter/types/clusters/pm10-concentration-measurement';
47
+ import { RadonConcentrationMeasurement } from '@matter/types/clusters/radon-concentration-measurement';
48
+ import { TotalVolatileOrganicCompoundsConcentrationMeasurement } from '@matter/types/clusters/total-volatile-organic-compounds-concentration-measurement';
49
+ import { OperationalState } from '@matter/types/clusters/operational-state';
50
+ import { DeviceEnergyManagement } from '@matter/types/clusters/device-energy-management';
51
+ import { DeviceEnergyManagementMode } from '@matter/types/clusters/device-energy-management-mode';
52
+ import { PowerSourceServer } from '@matter/node/behaviors/power-source';
53
+ import { UserLabelServer } from '@matter/node/behaviors/user-label';
54
+ import { FixedLabelServer } from '@matter/node/behaviors/fixed-label';
55
+ import { BasicInformationServer } from '@matter/node/behaviors/basic-information';
56
+ import { BridgedDeviceBasicInformationServer } from '@matter/node/behaviors/bridged-device-basic-information';
57
+ import { GroupsServer } from '@matter/node/behaviors/groups';
58
+ import { PumpConfigurationAndControlServer } from '@matter/node/behaviors/pump-configuration-and-control';
59
+ import { SwitchServer } from '@matter/node/behaviors/switch';
60
+ import { BooleanStateServer } from '@matter/node/behaviors/boolean-state';
61
+ import { PowerTopologyServer } from '@matter/node/behaviors/power-topology';
62
+ import { ElectricalPowerMeasurementServer } from '@matter/node/behaviors/electrical-power-measurement';
63
+ import { ElectricalEnergyMeasurementServer } from '@matter/node/behaviors/electrical-energy-measurement';
64
+ import { TemperatureMeasurementServer } from '@matter/node/behaviors/temperature-measurement';
65
+ import { RelativeHumidityMeasurementServer } from '@matter/node/behaviors/relative-humidity-measurement';
66
+ import { PressureMeasurementServer } from '@matter/node/behaviors/pressure-measurement';
67
+ import { FlowMeasurementServer } from '@matter/node/behaviors/flow-measurement';
68
+ import { IlluminanceMeasurementServer } from '@matter/node/behaviors/illuminance-measurement';
69
+ import { OccupancySensingServer } from '@matter/node/behaviors/occupancy-sensing';
70
+ import { AirQualityServer } from '@matter/node/behaviors/air-quality';
71
+ import { CarbonMonoxideConcentrationMeasurementServer } from '@matter/node/behaviors/carbon-monoxide-concentration-measurement';
72
+ import { CarbonDioxideConcentrationMeasurementServer } from '@matter/node/behaviors/carbon-dioxide-concentration-measurement';
73
+ import { NitrogenDioxideConcentrationMeasurementServer } from '@matter/node/behaviors/nitrogen-dioxide-concentration-measurement';
74
+ import { OzoneConcentrationMeasurementServer } from '@matter/node/behaviors/ozone-concentration-measurement';
75
+ import { FormaldehydeConcentrationMeasurementServer } from '@matter/node/behaviors/formaldehyde-concentration-measurement';
76
+ import { Pm1ConcentrationMeasurementServer } from '@matter/node/behaviors/pm1-concentration-measurement';
77
+ import { Pm25ConcentrationMeasurementServer } from '@matter/node/behaviors/pm25-concentration-measurement';
78
+ import { Pm10ConcentrationMeasurementServer } from '@matter/node/behaviors/pm10-concentration-measurement';
79
+ import { RadonConcentrationMeasurementServer } from '@matter/node/behaviors/radon-concentration-measurement';
80
+ import { TotalVolatileOrganicCompoundsConcentrationMeasurementServer } from '@matter/node/behaviors/total-volatile-organic-compounds-concentration-measurement';
78
81
  import { DeviceEnergyManagementServer } from '@matter/node/behaviors/device-energy-management';
79
- import { deepCopy, deepEqual, isValidArray } from './utils/export.js';
80
- import { MatterbridgeIdentifyServer, MatterbridgeOnOffServer, MatterbridgeLevelControlServer, MatterbridgeColorControlServer, MatterbridgeLiftWindowCoveringServer, MatterbridgeThermostatServer, MatterbridgeFanControlServer, MatterbridgeDoorLockServer, MatterbridgeModeSelectServer, MatterbridgeValveConfigurationAndControlServer, MatterbridgeSmokeCoAlarmServer, MatterbridgeBooleanStateConfigurationServer, MatterbridgeOperationalStateServer, MatterbridgeDeviceEnergyManagementModeServer, } from './matterbridgeBehaviors.js';
82
+ import { deepCopy } from './utils/deepCopy.js';
83
+ import { deepEqual } from './utils/deepEqual.js';
84
+ import { isValidArray } from './utils/isvalid.js';
85
+ import { MatterbridgeIdentifyServer, MatterbridgeOnOffServer, MatterbridgeLevelControlServer, MatterbridgeColorControlServer, MatterbridgeLiftWindowCoveringServer, MatterbridgeThermostatServer, MatterbridgeFanControlServer, MatterbridgeDoorLockServer, MatterbridgeModeSelectServer, MatterbridgeValveConfigurationAndControlServer, MatterbridgeSmokeCoAlarmServer, MatterbridgeBooleanStateConfigurationServer, MatterbridgeOperationalStateServer, MatterbridgeDeviceEnergyManagementModeServer, MatterbridgePowerSourceServer, MatterbridgeDeviceEnergyManagementServer, } from './matterbridgeBehaviors.js';
81
86
  export function capitalizeFirstLetter(name) {
82
87
  if (!name)
83
88
  return name;
@@ -535,70 +540,47 @@ export async function triggerEvent(endpoint, cluster, event, payload, log) {
535
540
  log?.info(`${db}Trigger event ${hk}${capitalizeFirstLetter(clusterName)}${db}.${hk}${event}${db} with ${debugStringify(payload)}${db} on endpoint ${or}${endpoint.id}${db}:${or}${endpoint.number}${db} `);
536
541
  return true;
537
542
  }
538
- export function getDefaultOperationalStateClusterServer(operationalState = OperationalState.OperationalStateEnum.Stopped) {
539
- return optionsFor(MatterbridgeOperationalStateServer, {
540
- phaseList: [],
541
- currentPhase: null,
542
- countdownTime: null,
543
- operationalStateList: [
544
- { operationalStateId: OperationalState.OperationalStateEnum.Stopped, operationalStateLabel: 'Stopped' },
545
- { operationalStateId: OperationalState.OperationalStateEnum.Running, operationalStateLabel: 'Running' },
546
- { operationalStateId: OperationalState.OperationalStateEnum.Paused, operationalStateLabel: 'Paused' },
547
- { operationalStateId: OperationalState.OperationalStateEnum.Error, operationalStateLabel: 'Error' },
548
- ],
549
- operationalState,
550
- operationalError: { errorStateId: OperationalState.ErrorState.NoError, errorStateLabel: 'No error', errorStateDetails: 'Fully operational' },
543
+ export function getDefaultPowerSourceWiredClusterServer(wiredCurrentType = PowerSource.WiredCurrentType.Ac) {
544
+ return optionsFor(MatterbridgePowerSourceServer.with(PowerSource.Feature.Wired), {
545
+ status: PowerSource.PowerSourceStatus.Active,
546
+ order: 0,
547
+ description: wiredCurrentType === PowerSource.WiredCurrentType.Ac ? 'AC Power' : 'DC Power',
548
+ endpointList: [],
549
+ wiredCurrentType,
551
550
  });
552
551
  }
553
- export function getDefaultTemperatureMeasurementClusterServer(measuredValue = null, minMeasuredValue = null, maxMeasuredValue = null) {
554
- return optionsFor(TemperatureMeasurementServer, {
555
- measuredValue,
556
- minMeasuredValue,
557
- maxMeasuredValue,
558
- tolerance: 0,
552
+ export function getDefaultPowerSourceReplaceableBatteryClusterServer(batPercentRemaining = 100, batChargeLevel = PowerSource.BatChargeLevel.Ok, batVoltage = 1500, batReplacementDescription = 'Battery type', batQuantity = 1, batReplaceability = PowerSource.BatReplaceability.UserReplaceable) {
553
+ return optionsFor(MatterbridgePowerSourceServer.with(PowerSource.Feature.Battery, PowerSource.Feature.Replaceable), {
554
+ status: PowerSource.PowerSourceStatus.Active,
555
+ order: 0,
556
+ description: 'Primary battery',
557
+ endpointList: [],
558
+ batVoltage,
559
+ batPercentRemaining: Math.min(Math.max(batPercentRemaining * 2, 0), 200),
560
+ batChargeLevel,
561
+ batReplacementNeeded: false,
562
+ batReplaceability,
563
+ activeBatFaults: undefined,
564
+ batReplacementDescription,
565
+ batQuantity,
559
566
  });
560
567
  }
561
- export function getDefaultRelativeHumidityMeasurementClusterServer(measuredValue = null, minMeasuredValue = null, maxMeasuredValue = null) {
562
- return optionsFor(RelativeHumidityMeasurementServer, {
563
- measuredValue,
564
- minMeasuredValue,
565
- maxMeasuredValue,
566
- tolerance: 0,
567
- });
568
- }
569
- export function getDefaultPressureMeasurementClusterServer(measuredValue = null, minMeasuredValue = null, maxMeasuredValue = null) {
570
- return optionsFor(PressureMeasurementServer, {
571
- measuredValue,
572
- minMeasuredValue,
573
- maxMeasuredValue,
574
- tolerance: 0,
575
- });
576
- }
577
- export function getDefaultIlluminanceMeasurementClusterServer(measuredValue = null, minMeasuredValue = null, maxMeasuredValue = null) {
578
- return optionsFor(IlluminanceMeasurementServer, {
579
- measuredValue,
580
- minMeasuredValue,
581
- maxMeasuredValue,
582
- tolerance: 0,
583
- });
584
- }
585
- export function getDefaultFlowMeasurementClusterServer(measuredValue = null, minMeasuredValue = null, maxMeasuredValue = null) {
586
- return optionsFor(FlowMeasurementServer, {
587
- measuredValue,
588
- minMeasuredValue,
589
- maxMeasuredValue,
590
- tolerance: 0,
591
- });
592
- }
593
- export function getDefaultOccupancySensingClusterServer(occupied = false, holdTime = 30, holdTimeMin = 1, holdTimeMax = 300) {
594
- return optionsFor(OccupancySensingServer.with(OccupancySensing.Feature.PassiveInfrared), {
595
- occupancy: { occupied },
596
- occupancySensorType: OccupancySensing.OccupancySensorType.Pir,
597
- occupancySensorTypeBitmap: { pir: true, ultrasonic: false, physicalContact: false },
598
- pirOccupiedToUnoccupiedDelay: holdTime,
599
- pirUnoccupiedToOccupiedDelay: holdTime,
600
- holdTime,
601
- holdTimeLimits: { holdTimeMin, holdTimeMax, holdTimeDefault: holdTime },
568
+ export function getDefaultPowerSourceRechargeableBatteryClusterServer(batPercentRemaining = 100, batChargeLevel = PowerSource.BatChargeLevel.Ok, batVoltage = 1500, batReplaceability = PowerSource.BatReplaceability.Unspecified) {
569
+ return optionsFor(MatterbridgePowerSourceServer.with(PowerSource.Feature.Battery, PowerSource.Feature.Rechargeable), {
570
+ status: PowerSource.PowerSourceStatus.Active,
571
+ order: 0,
572
+ description: 'Primary battery',
573
+ endpointList: [],
574
+ batVoltage,
575
+ batPercentRemaining: Math.min(Math.max(batPercentRemaining * 2, 0), 200),
576
+ batTimeRemaining: null,
577
+ batChargeLevel,
578
+ batReplacementNeeded: false,
579
+ batReplaceability,
580
+ batPresent: true,
581
+ activeBatFaults: [],
582
+ batChargeState: PowerSource.BatChargeState.IsNotCharging,
583
+ batFunctionalWhileCharging: true,
602
584
  });
603
585
  }
604
586
  export function getDefaultElectricalEnergyMeasurementClusterServer(energyImported = null, energyExported = null) {
@@ -695,3 +677,105 @@ export function getApparentElectricalPowerMeasurementClusterServer(voltage = nul
695
677
  frequency: frequency,
696
678
  });
697
679
  }
680
+ export function getDefaultDeviceEnergyManagementClusterServer(esaType = DeviceEnergyManagement.EsaType.Other, esaCanGenerate = false, esaState = DeviceEnergyManagement.EsaState.Online, absMinPower = 0, absMaxPower = 0) {
681
+ return optionsFor(MatterbridgeDeviceEnergyManagementServer.with(DeviceEnergyManagement.Feature.PowerForecastReporting, DeviceEnergyManagement.Feature.PowerAdjustment), {
682
+ esaType,
683
+ esaCanGenerate,
684
+ esaState,
685
+ absMinPower,
686
+ absMaxPower,
687
+ powerAdjustmentCapability: null,
688
+ optOutState: DeviceEnergyManagement.OptOutState.NoOptOut,
689
+ forecast: null,
690
+ });
691
+ }
692
+ export function getDefaultDeviceEnergyManagementModeClusterServer(currentMode, supportedModes) {
693
+ return optionsFor(MatterbridgeDeviceEnergyManagementModeServer, {
694
+ supportedModes: supportedModes ?? [
695
+ { label: 'No Energy Management (Forecast reporting only)', mode: 1, modeTags: [{ value: DeviceEnergyManagementMode.ModeTag.NoOptimization }] },
696
+ {
697
+ label: 'Device Energy Management',
698
+ mode: 2,
699
+ modeTags: [{ value: DeviceEnergyManagementMode.ModeTag.DeviceOptimization }, { value: DeviceEnergyManagementMode.ModeTag.LocalOptimization }],
700
+ },
701
+ {
702
+ label: 'Home Energy Management',
703
+ mode: 3,
704
+ modeTags: [{ value: DeviceEnergyManagementMode.ModeTag.GridOptimization }, { value: DeviceEnergyManagementMode.ModeTag.LocalOptimization }],
705
+ },
706
+ { label: 'Grid Energy Managemen', mode: 4, modeTags: [{ value: DeviceEnergyManagementMode.ModeTag.GridOptimization }] },
707
+ {
708
+ label: 'Full Energy Management',
709
+ mode: 5,
710
+ modeTags: [{ value: DeviceEnergyManagementMode.ModeTag.DeviceOptimization }, { value: DeviceEnergyManagementMode.ModeTag.LocalOptimization }, { value: DeviceEnergyManagementMode.ModeTag.GridOptimization }],
711
+ },
712
+ ],
713
+ currentMode: currentMode ?? 1,
714
+ });
715
+ }
716
+ export function getDefaultOperationalStateClusterServer(operationalState = OperationalState.OperationalStateEnum.Stopped) {
717
+ return optionsFor(MatterbridgeOperationalStateServer, {
718
+ phaseList: [],
719
+ currentPhase: null,
720
+ countdownTime: null,
721
+ operationalStateList: [
722
+ { operationalStateId: OperationalState.OperationalStateEnum.Stopped, operationalStateLabel: 'Stopped' },
723
+ { operationalStateId: OperationalState.OperationalStateEnum.Running, operationalStateLabel: 'Running' },
724
+ { operationalStateId: OperationalState.OperationalStateEnum.Paused, operationalStateLabel: 'Paused' },
725
+ { operationalStateId: OperationalState.OperationalStateEnum.Error, operationalStateLabel: 'Error' },
726
+ ],
727
+ operationalState,
728
+ operationalError: { errorStateId: OperationalState.ErrorState.NoError, errorStateLabel: 'No error', errorStateDetails: 'Fully operational' },
729
+ });
730
+ }
731
+ export function getDefaultTemperatureMeasurementClusterServer(measuredValue = null, minMeasuredValue = null, maxMeasuredValue = null) {
732
+ return optionsFor(TemperatureMeasurementServer, {
733
+ measuredValue,
734
+ minMeasuredValue,
735
+ maxMeasuredValue,
736
+ tolerance: 0,
737
+ });
738
+ }
739
+ export function getDefaultRelativeHumidityMeasurementClusterServer(measuredValue = null, minMeasuredValue = null, maxMeasuredValue = null) {
740
+ return optionsFor(RelativeHumidityMeasurementServer, {
741
+ measuredValue,
742
+ minMeasuredValue,
743
+ maxMeasuredValue,
744
+ tolerance: 0,
745
+ });
746
+ }
747
+ export function getDefaultPressureMeasurementClusterServer(measuredValue = null, minMeasuredValue = null, maxMeasuredValue = null) {
748
+ return optionsFor(PressureMeasurementServer, {
749
+ measuredValue,
750
+ minMeasuredValue,
751
+ maxMeasuredValue,
752
+ tolerance: 0,
753
+ });
754
+ }
755
+ export function getDefaultIlluminanceMeasurementClusterServer(measuredValue = null, minMeasuredValue = null, maxMeasuredValue = null) {
756
+ return optionsFor(IlluminanceMeasurementServer, {
757
+ measuredValue,
758
+ minMeasuredValue,
759
+ maxMeasuredValue,
760
+ tolerance: 0,
761
+ });
762
+ }
763
+ export function getDefaultFlowMeasurementClusterServer(measuredValue = null, minMeasuredValue = null, maxMeasuredValue = null) {
764
+ return optionsFor(FlowMeasurementServer, {
765
+ measuredValue,
766
+ minMeasuredValue,
767
+ maxMeasuredValue,
768
+ tolerance: 0,
769
+ });
770
+ }
771
+ export function getDefaultOccupancySensingClusterServer(occupied = false, holdTime = 30, holdTimeMin = 1, holdTimeMax = 300) {
772
+ return optionsFor(OccupancySensingServer.with(OccupancySensing.Feature.PassiveInfrared), {
773
+ occupancy: { occupied },
774
+ occupancySensorType: OccupancySensing.OccupancySensorType.Pir,
775
+ occupancySensorTypeBitmap: { pir: true, ultrasonic: false, physicalContact: false },
776
+ pirOccupiedToUnoccupiedDelay: holdTime,
777
+ pirUnoccupiedToOccupiedDelay: holdTime,
778
+ holdTime,
779
+ holdTimeLimits: { holdTimeMin, holdTimeMax, holdTimeDefault: holdTime },
780
+ });
781
+ }
@@ -1,10 +1,10 @@
1
1
  if (process.argv.includes('--loader') || process.argv.includes('-loader'))
2
2
  console.log('\u001B[32mMatterbridgePlatform loaded.\u001B[40;0m');
3
3
  import path from 'node:path';
4
- import { Descriptor } from '@matter/main/clusters/descriptor';
5
- import { BridgedDeviceBasicInformation } from '@matter/main/clusters/bridged-device-basic-information';
6
4
  import { CYAN, db, er, nf, wr } from 'node-ansi-logger';
7
5
  import { NodeStorageManager } from 'node-persist-manager';
6
+ import { Descriptor } from '@matter/types/clusters/descriptor';
7
+ import { BridgedDeviceBasicInformation } from '@matter/types/clusters/bridged-device-basic-information';
8
8
  import { checkNotLatinCharacters } from './matterbridgeEndpointHelpers.js';
9
9
  import { bridgedNode } from './matterbridgeDeviceTypes.js';
10
10
  import { isValidArray, isValidObject, isValidString } from './utils/isvalid.js';
package/dist/update.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import { db, debugStringify, nt, wr } from 'node-ansi-logger';
2
2
  import { plg } from './matterbridgeTypes.js';
3
- import { isValidString } from './utils/isvalid.js';
4
3
  export async function checkUpdates(matterbridge) {
5
4
  const { hasParameter } = await import('./utils/commandLine.js');
6
5
  const update = checkUpdatesAndLog(matterbridge);
@@ -26,6 +25,7 @@ export async function checkUpdates(matterbridge) {
26
25
  }
27
26
  export async function checkUpdatesAndLog(matterbridge) {
28
27
  const { getGitHubUpdate } = await import('./utils/network.js');
28
+ const { isValidString } = await import('./utils/isvalid.js');
29
29
  const branch = matterbridge.matterbridgeVersion.includes('-dev-') ? 'dev' : 'main';
30
30
  try {
31
31
  const updateJson = await getGitHubUpdate(branch, 'update.json', 5_000);
@@ -0,0 +1,29 @@
1
+ export function formatTimeStamp(timestamp) {
2
+ return `${new Date(timestamp).toLocaleString()}`;
3
+ }
4
+ export function formatPercent(percent, digits = 2) {
5
+ return `${percent.toFixed(digits)} %`;
6
+ }
7
+ export function formatBytes(bytes, digits = 2) {
8
+ if (bytes === 0)
9
+ return `${bytes.toFixed(digits)} B`;
10
+ const units = ['B', 'KB', 'MB', 'GB', 'TB'];
11
+ const idx = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1);
12
+ const value = bytes / Math.pow(1024, idx);
13
+ return `${value.toFixed(digits)} ${units[idx]}`;
14
+ }
15
+ export function formatUptime(seconds) {
16
+ if (seconds >= 86400) {
17
+ const days = Math.floor(seconds / 86400);
18
+ return `${days} day${days !== 1 ? 's' : ''}`;
19
+ }
20
+ if (seconds >= 3600) {
21
+ const hours = Math.floor(seconds / 3600);
22
+ return `${hours} hour${hours !== 1 ? 's' : ''}`;
23
+ }
24
+ if (seconds >= 60) {
25
+ const minutes = Math.floor(seconds / 60);
26
+ return `${minutes} minute${minutes !== 1 ? 's' : ''}`;
27
+ }
28
+ return `${seconds} second${seconds !== 1 ? 's' : ''}`;
29
+ }
@@ -2,10 +2,14 @@ import { rmSync } from 'node:fs';
2
2
  import { inspect } from 'node:util';
3
3
  import path from 'node:path';
4
4
  import { jest } from '@jest/globals';
5
- import { DeviceTypeId, Endpoint, Environment, ServerNode, ServerNodeStore, VendorId, LogFormat as MatterLogFormat, LogLevel as MatterLogLevel, Lifecycle } from '@matter/main';
6
- import { AggregatorEndpoint, RootEndpoint } from '@matter/main/endpoints';
7
- import { MdnsService } from '@matter/main/protocol';
8
5
  import { AnsiLogger } from 'node-ansi-logger';
6
+ import '@matter/nodejs';
7
+ import { LogFormat as MatterLogFormat, LogLevel as MatterLogLevel, Environment, Lifecycle } from '@matter/general';
8
+ import { DeviceTypeId, VendorId } from '@matter/types';
9
+ import { MdnsService } from '@matter/protocol';
10
+ import { ServerNode, Endpoint, ServerNodeStore } from '@matter/node';
11
+ import { AggregatorEndpoint } from '@matter/node/endpoints/aggregator';
12
+ import { RootEndpoint } from '@matter/node/endpoints/root';
9
13
  export let loggerLogSpy;
10
14
  export let consoleLogSpy;
11
15
  export let consoleDebugSpy;
@@ -180,29 +180,3 @@ export async function getGlobalNodeModules() {
180
180
  });
181
181
  });
182
182
  }
183
- export function formatMemoryUsage(bytes) {
184
- if (bytes >= 1024 ** 3) {
185
- return `${(bytes / 1024 ** 3).toFixed(2)} GB`;
186
- }
187
- else if (bytes >= 1024 ** 2) {
188
- return `${(bytes / 1024 ** 2).toFixed(2)} MB`;
189
- }
190
- else {
191
- return `${(bytes / 1024).toFixed(2)} KB`;
192
- }
193
- }
194
- export function formatOsUpTime(seconds) {
195
- if (seconds >= 86400) {
196
- const days = Math.floor(seconds / 86400);
197
- return `${days} day${days !== 1 ? 's' : ''}`;
198
- }
199
- if (seconds >= 3600) {
200
- const hours = Math.floor(seconds / 3600);
201
- return `${hours} hour${hours !== 1 ? 's' : ''}`;
202
- }
203
- if (seconds >= 60) {
204
- const minutes = Math.floor(seconds / 60);
205
- return `${minutes} minute${minutes !== 1 ? 's' : ''}`;
206
- }
207
- return `${seconds} second${seconds !== 1 ? 's' : ''}`;
208
- }
@@ -3,6 +3,7 @@ if (process.argv.includes('--loader') || process.argv.includes('-loader'))
3
3
  import os from 'node:os';
4
4
  import EventEmitter from 'node:events';
5
5
  import { AnsiLogger, BRIGHT, CYAN, RESET, YELLOW, db, RED } from 'node-ansi-logger';
6
+ import { formatPercent, formatBytes, formatTimeStamp } from './format.js';
6
7
  export class Tracker extends EventEmitter {
7
8
  name;
8
9
  debug;
@@ -65,35 +66,6 @@ export class Tracker extends EventEmitter {
65
66
  this.runGarbageCollector();
66
67
  });
67
68
  }
68
- formatTimeStamp(timestamp) {
69
- return `${new Date(timestamp).toLocaleString()}`;
70
- }
71
- formatOsUpTime(seconds) {
72
- if (seconds >= 86400) {
73
- const days = Math.floor(seconds / 86400);
74
- return `${days} day${days !== 1 ? 's' : ''}`;
75
- }
76
- if (seconds >= 3600) {
77
- const hours = Math.floor(seconds / 3600);
78
- return `${hours} hour${hours !== 1 ? 's' : ''}`;
79
- }
80
- if (seconds >= 60) {
81
- const minutes = Math.floor(seconds / 60);
82
- return `${minutes} minute${minutes !== 1 ? 's' : ''}`;
83
- }
84
- return `${seconds} second${seconds !== 1 ? 's' : ''}`;
85
- }
86
- formatPercent(percent) {
87
- return `${percent.toFixed(2)} %`;
88
- }
89
- formatBytes(bytes) {
90
- if (bytes === 0)
91
- return '0 B';
92
- const units = ['B', 'KB', 'MB', 'GB', 'TB'];
93
- const idx = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1);
94
- const value = bytes / Math.pow(1024, idx);
95
- return `${value.toFixed(2)} ${units[idx]}`;
96
- }
97
69
  start(sampleIntervalMs = 10000) {
98
70
  if (this.trackerInterval)
99
71
  return;
@@ -154,14 +126,14 @@ export class Tracker extends EventEmitter {
154
126
  this.emit('memory', entry.freeMemory, entry.totalMemory, entry.rss, entry.heapUsed, entry.heapTotal, entry.external, entry.arrayBuffers);
155
127
  this.emit('snapshot', entry);
156
128
  if (this.debug) {
157
- this.log.debug(`Time: ${this.formatTimeStamp(entry.timestamp)} ` +
158
- `os ${CYAN}${BRIGHT}${this.formatPercent(entry.osCpu)}${RESET}${db} (${entry.peakOsCpu > prevEntry.peakOsCpu ? RED : ''}${this.formatPercent(entry.peakOsCpu)}${db}) ` +
159
- `process ${CYAN}${BRIGHT}${this.formatPercent(entry.processCpu)}${RESET}${db} (${entry.peakProcessCpu > prevEntry.peakProcessCpu ? RED : ''}${this.formatPercent(entry.peakProcessCpu)}${db}) ` +
160
- `rss: ${CYAN}${BRIGHT}${this.formatBytes(entry.rss)}${RESET}${db} (${entry.peakRss > prevEntry.peakRss ? RED : ''}${this.formatBytes(entry.peakRss)}${db}) ` +
161
- `heapUsed: ${CYAN}${BRIGHT}${this.formatBytes(entry.heapUsed)}${RESET}${db} (${entry.peakHeapUsed > prevEntry.peakHeapUsed ? RED : ''}${this.formatBytes(entry.peakHeapUsed)}${db}) ` +
162
- `heapTotal: ${CYAN}${BRIGHT}${this.formatBytes(entry.heapTotal)}${RESET}${db} (${entry.peakHeapTotal > prevEntry.peakHeapTotal ? RED : ''}${this.formatBytes(entry.peakHeapTotal)}${db}) ` +
163
- `external: ${CYAN}${BRIGHT}${this.formatBytes(entry.external)}${RESET}${db} (${entry.peakExternal > prevEntry.peakExternal ? RED : ''}${this.formatBytes(entry.peakExternal)}${db}) ` +
164
- `arrayBuffers: ${CYAN}${BRIGHT}${this.formatBytes(entry.arrayBuffers)}${RESET}${db} (${entry.peakArrayBuffers > prevEntry.peakArrayBuffers ? RED : ''}${this.formatBytes(entry.peakArrayBuffers)}${db})`);
129
+ this.log.debug(`Time: ${formatTimeStamp(entry.timestamp)} ` +
130
+ `os ${CYAN}${BRIGHT}${formatPercent(entry.osCpu)}${RESET}${db} (${entry.peakOsCpu > prevEntry.peakOsCpu ? RED : ''}${formatPercent(entry.peakOsCpu)}${db}) ` +
131
+ `process ${CYAN}${BRIGHT}${formatPercent(entry.processCpu)}${RESET}${db} (${entry.peakProcessCpu > prevEntry.peakProcessCpu ? RED : ''}${formatPercent(entry.peakProcessCpu)}${db}) ` +
132
+ `rss: ${CYAN}${BRIGHT}${formatBytes(entry.rss)}${RESET}${db} (${entry.peakRss > prevEntry.peakRss ? RED : ''}${formatBytes(entry.peakRss)}${db}) ` +
133
+ `heapUsed: ${CYAN}${BRIGHT}${formatBytes(entry.heapUsed)}${RESET}${db} (${entry.peakHeapUsed > prevEntry.peakHeapUsed ? RED : ''}${formatBytes(entry.peakHeapUsed)}${db}) ` +
134
+ `heapTotal: ${CYAN}${BRIGHT}${formatBytes(entry.heapTotal)}${RESET}${db} (${entry.peakHeapTotal > prevEntry.peakHeapTotal ? RED : ''}${formatBytes(entry.peakHeapTotal)}${db}) ` +
135
+ `external: ${CYAN}${BRIGHT}${formatBytes(entry.external)}${RESET}${db} (${entry.peakExternal > prevEntry.peakExternal ? RED : ''}${formatBytes(entry.peakExternal)}${db}) ` +
136
+ `arrayBuffers: ${CYAN}${BRIGHT}${formatBytes(entry.arrayBuffers)}${RESET}${db} (${entry.peakArrayBuffers > prevEntry.peakArrayBuffers ? RED : ''}${formatBytes(entry.peakArrayBuffers)}${db})`);
165
137
  }
166
138
  Tracker.historyIndex = (Tracker.historyIndex + 1) % Tracker.historySize;
167
139
  }, sampleIntervalMs);
@@ -214,14 +186,14 @@ export class Tracker extends EventEmitter {
214
186
  const entry = Tracker.history[index];
215
187
  if (entry.timestamp === 0)
216
188
  continue;
217
- this.log.debug(`${this.formatTimeStamp(entry.timestamp)} ` +
218
- `${CYAN}${BRIGHT}${this.formatPercent(entry.osCpu).padStart(8)}${RESET} (${this.formatPercent(entry.peakOsCpu).padStart(8)}) ` +
219
- `${CYAN}${BRIGHT}${this.formatPercent(entry.processCpu).padStart(8)}${RESET} (${this.formatPercent(entry.peakProcessCpu).padStart(8)}) ` +
220
- `${CYAN}${BRIGHT}${this.formatBytes(entry.rss).padStart(9)}${RESET} (${this.formatBytes(entry.peakRss).padStart(9)}) ` +
221
- `${CYAN}${BRIGHT}${this.formatBytes(entry.heapUsed).padStart(9)}${RESET} (${this.formatBytes(entry.peakHeapUsed).padStart(9)}) ` +
222
- `${CYAN}${BRIGHT}${this.formatBytes(entry.heapTotal).padStart(9)}${RESET} (${this.formatBytes(entry.peakHeapTotal).padStart(9)}) ` +
223
- `${CYAN}${BRIGHT}${this.formatBytes(entry.external).padStart(9)}${RESET} (${this.formatBytes(entry.peakExternal).padStart(9)}) ` +
224
- `${CYAN}${BRIGHT}${this.formatBytes(entry.arrayBuffers).padStart(9)}${RESET} (${this.formatBytes(entry.peakArrayBuffers).padStart(9)})`);
189
+ this.log.debug(`${formatTimeStamp(entry.timestamp)} ` +
190
+ `${CYAN}${BRIGHT}${formatPercent(entry.osCpu).padStart(8)}${RESET} (${formatPercent(entry.peakOsCpu).padStart(8)}) ` +
191
+ `${CYAN}${BRIGHT}${formatPercent(entry.processCpu).padStart(8)}${RESET} (${formatPercent(entry.peakProcessCpu).padStart(8)}) ` +
192
+ `${CYAN}${BRIGHT}${formatBytes(entry.rss).padStart(9)}${RESET} (${formatBytes(entry.peakRss).padStart(9)}) ` +
193
+ `${CYAN}${BRIGHT}${formatBytes(entry.heapUsed).padStart(9)}${RESET} (${formatBytes(entry.peakHeapUsed).padStart(9)}) ` +
194
+ `${CYAN}${BRIGHT}${formatBytes(entry.heapTotal).padStart(9)}${RESET} (${formatBytes(entry.peakHeapTotal).padStart(9)}) ` +
195
+ `${CYAN}${BRIGHT}${formatBytes(entry.external).padStart(9)}${RESET} (${formatBytes(entry.peakExternal).padStart(9)}) ` +
196
+ `${CYAN}${BRIGHT}${formatBytes(entry.arrayBuffers).padStart(9)}${RESET} (${formatBytes(entry.peakArrayBuffers).padStart(9)})`);
225
197
  }
226
198
  }
227
199
  this.log.debug(`Tracker stopped`);
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "matterbridge",
3
- "version": "3.3.4-dev-20251020-4d2dd49",
3
+ "version": "3.3.4-dev-20251021-7651f57",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "matterbridge",
9
- "version": "3.3.4-dev-20251020-4d2dd49",
9
+ "version": "3.3.4-dev-20251021-7651f57",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "@matter/main": "0.15.6",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "matterbridge",
3
- "version": "3.3.4-dev-20251020-4d2dd49",
3
+ "version": "3.3.4-dev-20251021-7651f57",
4
4
  "description": "Matterbridge plugin manager for Matter",
5
5
  "author": "https://github.com/Luligu",
6
6
  "license": "Apache-2.0",