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.
- package/CHANGELOG.md +9 -0
- package/README-DOCKER.md +4 -1
- package/README-SERVICE.md +4 -3
- package/dist/cli.js +7 -6
- package/dist/devices/airConditioner.js +2 -2
- package/dist/devices/batteryStorage.js +3 -3
- package/dist/devices/dishwasher.js +4 -4
- package/dist/devices/evse.js +6 -5
- package/dist/devices/extractorHood.js +1 -1
- package/dist/devices/heatPump.js +2 -2
- package/dist/devices/laundryDryer.js +3 -3
- package/dist/devices/laundryWasher.js +5 -5
- package/dist/devices/microwaveOven.js +5 -5
- package/dist/devices/oven.js +5 -5
- package/dist/devices/refrigerator.js +4 -4
- package/dist/devices/roboticVacuumCleaner.js +11 -11
- package/dist/devices/solarPower.js +2 -2
- package/dist/devices/speaker.js +2 -1
- package/dist/devices/temperatureControl.js +2 -2
- package/dist/devices/waterHeater.js +6 -6
- package/dist/frontend.js +27 -26
- package/dist/helpers.js +1 -1
- package/dist/matterbridge.js +46 -13
- package/dist/matterbridgeAccessoryPlatform.js +2 -0
- package/dist/matterbridgeBehaviors.js +39 -20
- package/dist/matterbridgeDeviceTypes.js +88 -86
- package/dist/matterbridgeDynamicPlatform.js +2 -0
- package/dist/matterbridgeEndpoint.js +92 -154
- package/dist/matterbridgeEndpointHelpers.js +221 -137
- package/dist/matterbridgePlatform.js +2 -2
- package/dist/update.js +1 -1
- package/dist/utils/format.js +29 -0
- package/dist/utils/jestHelpers.js +7 -3
- package/dist/utils/network.js +0 -26
- package/dist/utils/tracker.js +17 -45
- package/npm-shrinkwrap.json +2 -2
- 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/
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
42
|
-
import {
|
|
43
|
-
import {
|
|
44
|
-
import {
|
|
45
|
-
import {
|
|
46
|
-
import {
|
|
47
|
-
import {
|
|
48
|
-
import {
|
|
49
|
-
import {
|
|
50
|
-
import {
|
|
51
|
-
import {
|
|
52
|
-
import {
|
|
53
|
-
import {
|
|
54
|
-
import {
|
|
55
|
-
import {
|
|
56
|
-
import {
|
|
57
|
-
import {
|
|
58
|
-
import {
|
|
59
|
-
import {
|
|
60
|
-
import {
|
|
61
|
-
import {
|
|
62
|
-
import {
|
|
63
|
-
import {
|
|
64
|
-
import {
|
|
65
|
-
import {
|
|
66
|
-
import {
|
|
67
|
-
import {
|
|
68
|
-
import {
|
|
69
|
-
import {
|
|
70
|
-
import {
|
|
71
|
-
import {
|
|
72
|
-
import {
|
|
73
|
-
import {
|
|
74
|
-
import {
|
|
75
|
-
import {
|
|
76
|
-
import {
|
|
77
|
-
import {
|
|
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
|
|
80
|
-
import {
|
|
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
|
|
539
|
-
return optionsFor(
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
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
|
|
554
|
-
return optionsFor(
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
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
|
|
562
|
-
return optionsFor(
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
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;
|
package/dist/utils/network.js
CHANGED
|
@@ -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
|
-
}
|
package/dist/utils/tracker.js
CHANGED
|
@@ -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: ${
|
|
158
|
-
`os ${CYAN}${BRIGHT}${
|
|
159
|
-
`process ${CYAN}${BRIGHT}${
|
|
160
|
-
`rss: ${CYAN}${BRIGHT}${
|
|
161
|
-
`heapUsed: ${CYAN}${BRIGHT}${
|
|
162
|
-
`heapTotal: ${CYAN}${BRIGHT}${
|
|
163
|
-
`external: ${CYAN}${BRIGHT}${
|
|
164
|
-
`arrayBuffers: ${CYAN}${BRIGHT}${
|
|
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(`${
|
|
218
|
-
`${CYAN}${BRIGHT}${
|
|
219
|
-
`${CYAN}${BRIGHT}${
|
|
220
|
-
`${CYAN}${BRIGHT}${
|
|
221
|
-
`${CYAN}${BRIGHT}${
|
|
222
|
-
`${CYAN}${BRIGHT}${
|
|
223
|
-
`${CYAN}${BRIGHT}${
|
|
224
|
-
`${CYAN}${BRIGHT}${
|
|
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`);
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "matterbridge",
|
|
3
|
-
"version": "3.3.4-dev-
|
|
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-
|
|
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