@matterbridge/core 3.10.15-dev-20261020-1bd3061 → 3.11.0-dev-20261021-c0f9ee2
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/dist/backend.js +1 -1
- package/dist/behaviors/cameraAvStreamManagementServer.js +0 -4
- package/dist/behaviors/colorControlServer.d.ts +13 -1
- package/dist/behaviors/doorLockServer.d.ts +58 -2
- package/dist/behaviors/smokeCoAlarmServer.d.ts +7 -1
- package/dist/behaviors/thermostatServer.d.ts +23 -1
- package/dist/behaviors/windowCoveringServer.d.ts +11 -1
- package/dist/chipTests.js +9 -9
- package/dist/devices/electricalUtilityMeter.js +2 -2
- package/dist/devices/roboticVacuumCleaner.js +2 -1
- package/dist/frontend.d.ts +0 -4
- package/dist/frontend.js +38 -20
- package/dist/matterbridge.d.ts +5 -0
- package/dist/matterbridge.js +42 -23
- package/dist/matterbridgeDeviceTypes.js +41 -41
- package/dist/matterbridgeEndpointHelpers.d.ts +89 -7
- package/dist/matterbridgeEndpointHelpers.js +3 -0
- package/package.json +6 -6
package/dist/backend.js
CHANGED
|
@@ -329,7 +329,7 @@ export class Backend extends EventEmitter {
|
|
|
329
329
|
}
|
|
330
330
|
async getApiSettings() {
|
|
331
331
|
const start = performance.now();
|
|
332
|
-
const response = await this.server.fetch({ type: 'matterbridge_apisettings', src: 'frontend', dst: 'matterbridge', params:
|
|
332
|
+
const response = await this.server.fetch({ type: 'matterbridge_apisettings', src: 'frontend', dst: 'matterbridge', params: {} });
|
|
333
333
|
if (this.diagnostic)
|
|
334
334
|
writeDiagnostic('Backend', `getApiSettings() took ${(performance.now() - start).toFixed(2)} ms`);
|
|
335
335
|
return response.result.data;
|
|
@@ -42,8 +42,6 @@ export class MatterbridgeCameraAvStreamManagementServer extends MatterbridgeCame
|
|
|
42
42
|
minBitRate,
|
|
43
43
|
maxBitRate: minBitRate * 4,
|
|
44
44
|
keyFrameInterval: 4000,
|
|
45
|
-
...(this.features.watermark ? { watermarkEnabled: false } : {}),
|
|
46
|
-
...(this.features.onScreenDisplay ? { osdEnabled: false } : {}),
|
|
47
45
|
referenceCount: 0,
|
|
48
46
|
},
|
|
49
47
|
];
|
|
@@ -87,8 +85,6 @@ export class MatterbridgeCameraAvStreamManagementServer extends MatterbridgeCame
|
|
|
87
85
|
referenceCount: 0,
|
|
88
86
|
encodedPixels: false,
|
|
89
87
|
hardwareEncoder: false,
|
|
90
|
-
...(this.features.watermark ? { watermarkEnabled: false } : {}),
|
|
91
|
-
...(this.features.onScreenDisplay ? { osdEnabled: false } : {}),
|
|
92
88
|
},
|
|
93
89
|
];
|
|
94
90
|
}
|
|
@@ -2,7 +2,19 @@ import type { MaybePromise } from '@matter/general';
|
|
|
2
2
|
import { ColorControlServer } from '@matter/node/behaviors/color-control';
|
|
3
3
|
import { ColorControl } from '@matter/types/clusters/color-control';
|
|
4
4
|
import type { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
|
|
5
|
-
declare const MatterbridgeColorControlServer_base: import("@matter/node").ClusterBehavior.Type<typeof ColorControlServer, import("@matter/types").ClusterType.WithSupportedFeatures<ColorControl, {
|
|
5
|
+
declare const MatterbridgeColorControlServer_base: import("@matter/node").ClusterBehavior.Type<typeof ColorControlServer, import("@matter/types").ClusterType.WithSupportedFeatures<import("@matter/types").ClusterType.WithSupportedFeatures<import("@matter/types").ClusterType.WithSupportedFeatures<ColorControl, {
|
|
6
|
+
colorLoop: true;
|
|
7
|
+
colorTemperature: true;
|
|
8
|
+
enhancedHue: true;
|
|
9
|
+
hueSaturation: true;
|
|
10
|
+
xy: true;
|
|
11
|
+
}>, {
|
|
12
|
+
colorLoop: false;
|
|
13
|
+
colorTemperature: false;
|
|
14
|
+
enhancedHue: false;
|
|
15
|
+
hueSaturation: false;
|
|
16
|
+
xy: false;
|
|
17
|
+
}>, {
|
|
6
18
|
colorLoop: false;
|
|
7
19
|
colorTemperature: true;
|
|
8
20
|
enhancedHue: true;
|
|
@@ -1,7 +1,35 @@
|
|
|
1
1
|
import { DoorLockServer } from '@matter/node/behaviors/door-lock';
|
|
2
2
|
import { DoorLock } from '@matter/types/clusters/door-lock';
|
|
3
3
|
import type { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
|
|
4
|
-
declare const MatterbridgeDoorLockServer_base: import("@matter/node").ClusterBehavior.Type<import("@matter/node").ClusterBehavior.Type<typeof DoorLockServer, import("@matter/types").ClusterType.WithSupportedFeatures<DoorLock, {
|
|
4
|
+
declare const MatterbridgeDoorLockServer_base: import("@matter/node").ClusterBehavior.Type<import("@matter/node").ClusterBehavior.Type<typeof DoorLockServer, import("@matter/types").ClusterType.WithSupportedFeatures<import("@matter/types").ClusterType.WithSupportedFeatures<import("@matter/types").ClusterType.WithSupportedFeatures<DoorLock, {
|
|
5
|
+
aliroBleuwb: false;
|
|
6
|
+
aliroProvisioning: false;
|
|
7
|
+
credentialOverTheAirAccess: true;
|
|
8
|
+
doorPositionSensor: true;
|
|
9
|
+
faceCredentials: true;
|
|
10
|
+
fingerCredentials: true;
|
|
11
|
+
holidaySchedules: true;
|
|
12
|
+
pinCredential: true;
|
|
13
|
+
rfidCredential: true;
|
|
14
|
+
unbolting: true;
|
|
15
|
+
user: true;
|
|
16
|
+
weekDayAccessSchedules: true;
|
|
17
|
+
yearDayAccessSchedules: true;
|
|
18
|
+
}>, {
|
|
19
|
+
aliroBleuwb: false;
|
|
20
|
+
aliroProvisioning: false;
|
|
21
|
+
credentialOverTheAirAccess: false;
|
|
22
|
+
doorPositionSensor: false;
|
|
23
|
+
faceCredentials: false;
|
|
24
|
+
fingerCredentials: false;
|
|
25
|
+
holidaySchedules: false;
|
|
26
|
+
pinCredential: false;
|
|
27
|
+
rfidCredential: false;
|
|
28
|
+
unbolting: false;
|
|
29
|
+
user: false;
|
|
30
|
+
weekDayAccessSchedules: false;
|
|
31
|
+
yearDayAccessSchedules: false;
|
|
32
|
+
}>, {
|
|
5
33
|
aliroBleuwb: false;
|
|
6
34
|
aliroProvisioning: false;
|
|
7
35
|
credentialOverTheAirAccess: false;
|
|
@@ -15,7 +43,35 @@ declare const MatterbridgeDoorLockServer_base: import("@matter/node").ClusterBeh
|
|
|
15
43
|
user: true;
|
|
16
44
|
weekDayAccessSchedules: true;
|
|
17
45
|
yearDayAccessSchedules: true;
|
|
18
|
-
}>, import("@matter/types").ClusterType.Concrete, typeof import("@matter/node/behaviors/door-lock").DoorLockBaseServer.Internal, "doorLock">, import("@matter/types").ClusterType.WithEnabledAttributes<import("@matter/types").ClusterType.WithEnabledEvents<import("@matter/types").ClusterType.WithSupportedFeatures<DoorLock, {
|
|
46
|
+
}>, import("@matter/types").ClusterType.Concrete, typeof import("@matter/node/behaviors/door-lock").DoorLockBaseServer.Internal, "doorLock">, import("@matter/types").ClusterType.WithEnabledAttributes<import("@matter/types").ClusterType.WithEnabledEvents<import("@matter/types").ClusterType.WithSupportedFeatures<import("@matter/types").ClusterType.WithSupportedFeatures<import("@matter/types").ClusterType.WithSupportedFeatures<DoorLock, {
|
|
47
|
+
aliroBleuwb: false;
|
|
48
|
+
aliroProvisioning: false;
|
|
49
|
+
credentialOverTheAirAccess: true;
|
|
50
|
+
doorPositionSensor: true;
|
|
51
|
+
faceCredentials: true;
|
|
52
|
+
fingerCredentials: true;
|
|
53
|
+
holidaySchedules: true;
|
|
54
|
+
pinCredential: true;
|
|
55
|
+
rfidCredential: true;
|
|
56
|
+
unbolting: true;
|
|
57
|
+
user: true;
|
|
58
|
+
weekDayAccessSchedules: true;
|
|
59
|
+
yearDayAccessSchedules: true;
|
|
60
|
+
}>, {
|
|
61
|
+
aliroBleuwb: false;
|
|
62
|
+
aliroProvisioning: false;
|
|
63
|
+
credentialOverTheAirAccess: false;
|
|
64
|
+
doorPositionSensor: false;
|
|
65
|
+
faceCredentials: false;
|
|
66
|
+
fingerCredentials: false;
|
|
67
|
+
holidaySchedules: false;
|
|
68
|
+
pinCredential: false;
|
|
69
|
+
rfidCredential: false;
|
|
70
|
+
unbolting: false;
|
|
71
|
+
user: false;
|
|
72
|
+
weekDayAccessSchedules: false;
|
|
73
|
+
yearDayAccessSchedules: false;
|
|
74
|
+
}>, {
|
|
19
75
|
aliroBleuwb: false;
|
|
20
76
|
aliroProvisioning: false;
|
|
21
77
|
credentialOverTheAirAccess: false;
|
|
@@ -2,7 +2,13 @@ import { type Timer } from '@matter/general';
|
|
|
2
2
|
import { SmokeCoAlarmServer } from '@matter/node/behaviors/smoke-co-alarm';
|
|
3
3
|
import { SmokeCoAlarm } from '@matter/types/clusters/smoke-co-alarm';
|
|
4
4
|
import type { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
|
|
5
|
-
declare const MatterbridgeSmokeCoAlarmServer_base: import("@matter/node").ClusterBehavior.Type<typeof SmokeCoAlarmServer, import("@matter/types").ClusterType.WithSupportedFeatures<SmokeCoAlarm, {
|
|
5
|
+
declare const MatterbridgeSmokeCoAlarmServer_base: import("@matter/node").ClusterBehavior.Type<typeof SmokeCoAlarmServer, import("@matter/types").ClusterType.WithSupportedFeatures<import("@matter/types").ClusterType.WithSupportedFeatures<import("@matter/types").ClusterType.WithSupportedFeatures<SmokeCoAlarm, {
|
|
6
|
+
coAlarm: true;
|
|
7
|
+
smokeAlarm: true;
|
|
8
|
+
}>, {
|
|
9
|
+
coAlarm: false;
|
|
10
|
+
smokeAlarm: false;
|
|
11
|
+
}>, {
|
|
6
12
|
coAlarm: true;
|
|
7
13
|
smokeAlarm: true;
|
|
8
14
|
}>, import("@matter/types").ClusterType.Concrete, new () => {}, "smokeCoAlarm">;
|
|
@@ -1,7 +1,29 @@
|
|
|
1
1
|
import { ThermostatServer } from '@matter/node/behaviors/thermostat';
|
|
2
2
|
import { Thermostat } from '@matter/types/clusters/thermostat';
|
|
3
3
|
import type { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
|
|
4
|
-
declare const MatterbridgeThermostatServer_base: import("@matter/node").ClusterBehavior.Type<typeof ThermostatServer, import("@matter/types").ClusterType.WithSupportedFeatures<Thermostat, {
|
|
4
|
+
declare const MatterbridgeThermostatServer_base: import("@matter/node").ClusterBehavior.Type<typeof ThermostatServer, import("@matter/types").ClusterType.WithSupportedFeatures<import("@matter/types").ClusterType.WithSupportedFeatures<import("@matter/types").ClusterType.WithSupportedFeatures<Thermostat, {
|
|
5
|
+
autoMode: true;
|
|
6
|
+
cooling: true;
|
|
7
|
+
events: false;
|
|
8
|
+
heating: true;
|
|
9
|
+
localTemperatureNotExposed: false;
|
|
10
|
+
matterScheduleConfiguration: false;
|
|
11
|
+
occupancy: true;
|
|
12
|
+
presets: true;
|
|
13
|
+
setback: false;
|
|
14
|
+
thermostatSuggestions: false;
|
|
15
|
+
}>, {
|
|
16
|
+
autoMode: false;
|
|
17
|
+
cooling: false;
|
|
18
|
+
events: false;
|
|
19
|
+
heating: false;
|
|
20
|
+
localTemperatureNotExposed: false;
|
|
21
|
+
matterScheduleConfiguration: false;
|
|
22
|
+
occupancy: false;
|
|
23
|
+
presets: false;
|
|
24
|
+
setback: false;
|
|
25
|
+
thermostatSuggestions: false;
|
|
26
|
+
}>, {
|
|
5
27
|
autoMode: true;
|
|
6
28
|
cooling: true;
|
|
7
29
|
events: false;
|
|
@@ -2,7 +2,17 @@ import { type Timer } from '@matter/general';
|
|
|
2
2
|
import { WindowCoveringBaseServer, WindowCoveringServer } from '@matter/node/behaviors/window-covering';
|
|
3
3
|
import { WindowCovering } from '@matter/types/clusters/window-covering';
|
|
4
4
|
import type { MatterbridgeEndpoint } from '../matterbridgeEndpoint.js';
|
|
5
|
-
declare const MatterbridgeWindowCoveringServer_base: import("@matter/node").ClusterBehavior.Type<typeof WindowCoveringServer, import("@matter/types").ClusterType.WithSupportedFeatures<WindowCovering, {
|
|
5
|
+
declare const MatterbridgeWindowCoveringServer_base: import("@matter/node").ClusterBehavior.Type<typeof WindowCoveringServer, import("@matter/types").ClusterType.WithSupportedFeatures<import("@matter/types").ClusterType.WithSupportedFeatures<import("@matter/types").ClusterType.WithSupportedFeatures<WindowCovering, {
|
|
6
|
+
lift: true;
|
|
7
|
+
positionAwareLift: true;
|
|
8
|
+
positionAwareTilt: true;
|
|
9
|
+
tilt: true;
|
|
10
|
+
}>, {
|
|
11
|
+
lift: false;
|
|
12
|
+
positionAwareLift: false;
|
|
13
|
+
positionAwareTilt: false;
|
|
14
|
+
tilt: false;
|
|
15
|
+
}>, {
|
|
6
16
|
lift: true;
|
|
7
17
|
positionAwareLift: true;
|
|
8
18
|
positionAwareTilt: true;
|
package/dist/chipTests.js
CHANGED
|
@@ -787,7 +787,7 @@ async function handleMeterIdentificationTestEventTrigger(eventTrigger) {
|
|
|
787
787
|
}
|
|
788
788
|
const commodityMeteringFakeValues = {
|
|
789
789
|
maximumMeteredQuantities: 8,
|
|
790
|
-
meteredQuantity: [{
|
|
790
|
+
meteredQuantity: [{ tariffComponentIds: [1], quantity: 1_234 }],
|
|
791
791
|
meteredQuantityTimestamp: Math.floor(Date.now() / 1000),
|
|
792
792
|
tariffUnit: TariffUnit.KWh,
|
|
793
793
|
};
|
|
@@ -843,8 +843,8 @@ const commodityTariffTariffComponents = [
|
|
|
843
843
|
},
|
|
844
844
|
];
|
|
845
845
|
const commodityTariffTariffPeriods = [
|
|
846
|
-
{ label: 'Morning',
|
|
847
|
-
{ label: 'Afternoon',
|
|
846
|
+
{ label: 'Morning', dayEntryIds: [1], tariffComponentIds: [100] },
|
|
847
|
+
{ label: 'Afternoon', dayEntryIds: [2], tariffComponentIds: [101] },
|
|
848
848
|
];
|
|
849
849
|
const commodityTariffClearedValues = {
|
|
850
850
|
tariffInfo: null,
|
|
@@ -870,12 +870,12 @@ let commodityTariffEntryIndex = 0;
|
|
|
870
870
|
function buildCommodityTariffFakeValues(dayOffset, entryIndex) {
|
|
871
871
|
const anchor = Math.floor(Date.now() / 86_400_000) * 86_400;
|
|
872
872
|
const tariffStartDate = anchor - 365 * 86_400;
|
|
873
|
-
const dayOf = (offset) => ({ date: anchor + offset * 86_400, dayType: CommodityTariff.DayType.Standard,
|
|
873
|
+
const dayOf = (offset) => ({ date: anchor + offset * 86_400, dayType: CommodityTariff.DayType.Standard, dayEntryIds: [1, 2] });
|
|
874
874
|
const entryDate = (offset, idx) => anchor + offset * 86_400 + commodityTariffDayEntries[idx].startTime * 60;
|
|
875
875
|
const nextEntry = entryIndex === commodityTariffDayEntries.length - 1 ? { offset: dayOffset + 1, idx: 0 } : { offset: dayOffset, idx: entryIndex + 1 };
|
|
876
876
|
const tariffComponentsFor = (dayEntryId) => commodityTariffTariffPeriods
|
|
877
|
-
.filter((period) => period.
|
|
878
|
-
.flatMap((period) => period.
|
|
877
|
+
.filter((period) => period.dayEntryIds.includes(dayEntryId))
|
|
878
|
+
.flatMap((period) => period.tariffComponentIds)
|
|
879
879
|
.map((id) => commodityTariffTariffComponents.find((component) => component.tariffComponentId === id))
|
|
880
880
|
.filter((component) => component !== undefined);
|
|
881
881
|
return {
|
|
@@ -888,9 +888,9 @@ function buildCommodityTariffFakeValues(dayOffset, entryIndex) {
|
|
|
888
888
|
tariffUnit: TariffUnit.KWh,
|
|
889
889
|
startDate: tariffStartDate,
|
|
890
890
|
dayEntries: commodityTariffDayEntries,
|
|
891
|
-
dayPatterns: [{ dayPatternId: commodityTariffDayPatternId, daysOfWeek: commodityTariffAllDaysOfWeek,
|
|
892
|
-
calendarPeriods: [{ startDate: tariffStartDate,
|
|
893
|
-
individualDays: [{ date: anchor - 30 * 86_400, dayType: CommodityTariff.DayType.Holiday,
|
|
891
|
+
dayPatterns: [{ dayPatternId: commodityTariffDayPatternId, daysOfWeek: commodityTariffAllDaysOfWeek, dayEntryIds: [1, 2] }],
|
|
892
|
+
calendarPeriods: [{ startDate: tariffStartDate, dayPatternIds: [commodityTariffDayPatternId] }],
|
|
893
|
+
individualDays: [{ date: anchor - 30 * 86_400, dayType: CommodityTariff.DayType.Holiday, dayEntryIds: [1, 2] }],
|
|
894
894
|
currentDay: dayOf(dayOffset),
|
|
895
895
|
nextDay: dayOf(dayOffset + 1),
|
|
896
896
|
currentDayEntry: commodityTariffDayEntries[entryIndex],
|
|
@@ -46,8 +46,8 @@ export class MatterbridgeCommodityTariffServer extends CommodityTariffServer.wit
|
|
|
46
46
|
if (!tariffComponent) {
|
|
47
47
|
throw new StatusResponse.NotFoundError(`MatterbridgeCommodityTariffServer: no TariffComponent with id ${request.tariffComponentId} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
48
48
|
}
|
|
49
|
-
const period = (this.state.tariffPeriods ?? []).find((p) => p.
|
|
50
|
-
const response = { label: period?.label ?? null,
|
|
49
|
+
const period = (this.state.tariffPeriods ?? []).find((p) => p.tariffComponentIds.includes(request.tariffComponentId));
|
|
50
|
+
const response = { label: period?.label ?? null, dayEntryIds: period?.dayEntryIds ?? [], tariffComponent };
|
|
51
51
|
this.endpoint.emitCommand(CommodityTariff, 'getTariffComponent', request, this.context);
|
|
52
52
|
return response;
|
|
53
53
|
}
|
|
@@ -240,7 +240,8 @@ export class MatterbridgeRvcOperationalStateServer extends MatterbridgeRvcOperat
|
|
|
240
240
|
if (this.state.operationalState === RvcOperationalState.OperationalState.Paused) {
|
|
241
241
|
return { commandResponseState: { errorStateId: OperationalState.ErrorState.NoError, errorStateDetails: 'Already paused' } };
|
|
242
242
|
}
|
|
243
|
-
if (this.state.operationalState !== RvcOperationalState.OperationalState.Running &&
|
|
243
|
+
if (this.state.operationalState !== RvcOperationalState.OperationalState.Running &&
|
|
244
|
+
this.state.operationalState !== RvcOperationalState.OperationalState.SeekingCharger) {
|
|
244
245
|
return {
|
|
245
246
|
commandResponseState: { errorStateId: OperationalState.ErrorState.CommandInvalidInState, errorStateDetails: 'Not Pause-compatible in the current operational state' },
|
|
246
247
|
};
|
package/dist/frontend.d.ts
CHANGED
|
@@ -27,10 +27,6 @@ export declare class Frontend extends EventEmitter<FrontendEvents> {
|
|
|
27
27
|
private readonly debug;
|
|
28
28
|
private readonly verbose;
|
|
29
29
|
private readonly diagnostic;
|
|
30
|
-
readonly readOnly: boolean;
|
|
31
|
-
restartRequired: boolean;
|
|
32
|
-
fixedRestartRequired: boolean;
|
|
33
|
-
updateRequired: boolean;
|
|
34
30
|
constructor(matterbridge: Matterbridge);
|
|
35
31
|
destroy(): void;
|
|
36
32
|
private broadcastMsgHandler;
|
package/dist/frontend.js
CHANGED
|
@@ -14,7 +14,7 @@ import { getErrorMessage, inspectError, logError } from '@matterbridge/utils/err
|
|
|
14
14
|
import { formatBytes, formatPercent, formatUptime } from '@matterbridge/utils/format';
|
|
15
15
|
import { logModuleLoaded } from '@matterbridge/utils/loader';
|
|
16
16
|
import { isValidArray, isValidBoolean, isValidNumber, isValidObject, isValidString } from '@matterbridge/utils/validate';
|
|
17
|
-
import { fireAndForget,
|
|
17
|
+
import { fireAndForget, withTimeout } from '@matterbridge/utils/wait';
|
|
18
18
|
import { AnsiLogger, bgHex, CYAN, db, debugStringify, er, GREEN, nf, nt, rs, UNDERLINE, UNDERLINEOFF, wr, YELLOW } from 'node-ansi-logger';
|
|
19
19
|
import { generateHistoryPage } from './cliHistory.js';
|
|
20
20
|
import { deleteAdvertisingNode, getBatteryLevel, getClusterTextFromDevice, getPowerSource, getReachability, getServerNodeData, setAdvertisingNode, toApiClusters, } from './matterNodeHelpers.js';
|
|
@@ -42,10 +42,6 @@ export class Frontend extends EventEmitter {
|
|
|
42
42
|
debug = hasAnyParameter('debug', 'debug-frontend', 'verbose', 'verbose-frontend');
|
|
43
43
|
verbose = hasAnyParameter('verbose', 'verbose-frontend');
|
|
44
44
|
diagnostic = hasAnyParameter('diagnostic', 'diagnostic-frontend');
|
|
45
|
-
readOnly = hasParameter('readonly');
|
|
46
|
-
restartRequired = false;
|
|
47
|
-
fixedRestartRequired = false;
|
|
48
|
-
updateRequired = false;
|
|
49
45
|
constructor(matterbridge) {
|
|
50
46
|
super();
|
|
51
47
|
this.matterbridge = matterbridge;
|
|
@@ -90,14 +86,22 @@ export class Frontend extends EventEmitter {
|
|
|
90
86
|
this.server.respond({ ...msg, result: { success: true } });
|
|
91
87
|
break;
|
|
92
88
|
case 'frontend_restartrequired':
|
|
89
|
+
this.server.request({
|
|
90
|
+
type: 'matterbridge_apisettings',
|
|
91
|
+
src: 'frontend',
|
|
92
|
+
dst: 'matterbridge',
|
|
93
|
+
params: { restartRequired: true, fixedRestartRequired: msg.params.fixed },
|
|
94
|
+
});
|
|
93
95
|
this.wssSendRestartRequired(msg.params.snackbar, msg.params.fixed);
|
|
94
96
|
this.server.respond({ ...msg, result: { success: true } });
|
|
95
97
|
break;
|
|
96
98
|
case 'frontend_restartnotrequired':
|
|
99
|
+
this.server.request({ type: 'matterbridge_apisettings', src: 'frontend', dst: 'matterbridge', params: { restartRequired: false } });
|
|
97
100
|
this.wssSendRestartNotRequired(msg.params.snackbar);
|
|
98
101
|
this.server.respond({ ...msg, result: { success: true } });
|
|
99
102
|
break;
|
|
100
103
|
case 'frontend_updaterequired':
|
|
104
|
+
this.server.request({ type: 'matterbridge_apisettings', src: 'frontend', dst: 'matterbridge', params: { updateRequired: true } });
|
|
101
105
|
this.wssSendUpdateRequired(msg.params.version, msg.params.devVersion);
|
|
102
106
|
this.server.respond({ ...msg, result: { success: true } });
|
|
103
107
|
break;
|
|
@@ -146,8 +150,7 @@ export class Frontend extends EventEmitter {
|
|
|
146
150
|
if (msg.result?.packageCommand === 'install') {
|
|
147
151
|
this.wssSendCloseSnackbarMessage(`Installing package ${msg.result.packageName}...`);
|
|
148
152
|
if (msg.result.success) {
|
|
149
|
-
this.restartRequired
|
|
150
|
-
this.fixedRestartRequired = true;
|
|
153
|
+
this.server.request({ type: 'matterbridge_apisettings', src: 'frontend', dst: 'matterbridge', params: { restartRequired: true, fixedRestartRequired: true } });
|
|
151
154
|
this.wssSendRestartRequired(true, true);
|
|
152
155
|
this.wssSendSnackbarMessage(`Installed package ${msg.result.packageName}`, 5, 'success');
|
|
153
156
|
setTimeout(() => this.wssSendRefreshRequired('plugins'), 2000).unref();
|
|
@@ -159,8 +162,7 @@ export class Frontend extends EventEmitter {
|
|
|
159
162
|
if (msg.result?.packageCommand === 'uninstall') {
|
|
160
163
|
this.wssSendCloseSnackbarMessage(`Uninstalling package ${msg.result.packageName}...`);
|
|
161
164
|
if (msg.result.success) {
|
|
162
|
-
this.restartRequired
|
|
163
|
-
this.fixedRestartRequired = true;
|
|
165
|
+
this.server.request({ type: 'matterbridge_apisettings', src: 'frontend', dst: 'matterbridge', params: { restartRequired: true, fixedRestartRequired: true } });
|
|
164
166
|
this.wssSendRestartRequired(true, true);
|
|
165
167
|
this.wssSendSnackbarMessage(`Uninstalled package ${msg.result.packageName}`, 5, 'success');
|
|
166
168
|
setTimeout(() => this.wssSendRefreshRequired('plugins'), 2000).unref();
|
|
@@ -956,10 +958,10 @@ export class Frontend extends EventEmitter {
|
|
|
956
958
|
matterPort: this.matterbridge.initialPort || 5540,
|
|
957
959
|
matterDiscriminator: this.matterbridge.initialDiscriminator,
|
|
958
960
|
matterPasscode: this.matterbridge.initialPasscode,
|
|
959
|
-
readOnly: this.readOnly,
|
|
960
|
-
restartRequired: this.restartRequired,
|
|
961
|
-
fixedRestartRequired: this.fixedRestartRequired,
|
|
962
|
-
updateRequired: this.updateRequired,
|
|
961
|
+
readOnly: this.matterbridge.readOnly,
|
|
962
|
+
restartRequired: this.matterbridge.restartRequired,
|
|
963
|
+
fixedRestartRequired: this.matterbridge.fixedRestartRequired,
|
|
964
|
+
updateRequired: this.matterbridge.updateRequired,
|
|
963
965
|
startupAt: this.matterbridge.startupAt,
|
|
964
966
|
shutdownAt: this.matterbridge.shutdownAt,
|
|
965
967
|
runningTimes: this.matterbridge.runningTimes,
|
|
@@ -1067,8 +1069,11 @@ export class Frontend extends EventEmitter {
|
|
|
1067
1069
|
if (fs.existsSync(path.join(this.matterbridge.matterbridgeDirectory, MATTERBRIDGE_DIAGNOSTIC_FILE)))
|
|
1068
1070
|
fs.unlinkSync(path.join(this.matterbridge.matterbridgeDirectory, MATTERBRIDGE_DIAGNOSTIC_FILE));
|
|
1069
1071
|
const diagnosticDestination = LogDestination({ name: 'diagnostic', level: MatterLogLevel.INFO, format: MatterLogFormat.formats.plain });
|
|
1072
|
+
const writes = [];
|
|
1070
1073
|
diagnosticDestination.write = async (text, _message) => {
|
|
1071
|
-
|
|
1074
|
+
const write = fs.promises.appendFile(path.join(this.matterbridge.matterbridgeDirectory, MATTERBRIDGE_DIAGNOSTIC_FILE), text + '\n', { encoding: 'utf8' });
|
|
1075
|
+
writes.push(write);
|
|
1076
|
+
await write;
|
|
1072
1077
|
};
|
|
1073
1078
|
Logger.destinations.diagnostic = diagnosticDestination;
|
|
1074
1079
|
if (!diagnosticDestination.context) {
|
|
@@ -1082,7 +1087,7 @@ export class Frontend extends EventEmitter {
|
|
|
1082
1087
|
values: [...serverNodes],
|
|
1083
1088
|
})));
|
|
1084
1089
|
delete Logger.destinations.diagnostic;
|
|
1085
|
-
await
|
|
1090
|
+
await Promise.allSettled(writes);
|
|
1086
1091
|
}
|
|
1087
1092
|
async wsMessageHandler(client, message) {
|
|
1088
1093
|
let data;
|
|
@@ -1170,6 +1175,7 @@ export class Frontend extends EventEmitter {
|
|
|
1170
1175
|
this.wssSendCloseSnackbarMessage(`Adding plugin ${data.params.pluginNameOrPath}...`);
|
|
1171
1176
|
this.wssSendSnackbarMessage(`Added plugin ${data.params.pluginNameOrPath}`, 5, 'success');
|
|
1172
1177
|
await this.server.fetch({ type: 'plugins_load', src: this.server.name, dst: 'plugins', params: { plugin: plugin.name } }, this.serverFetchTimeout);
|
|
1178
|
+
this.server.request({ type: 'matterbridge_apisettings', src: 'frontend', dst: 'matterbridge', params: { restartRequired: true } });
|
|
1173
1179
|
this.wssSendRestartRequired();
|
|
1174
1180
|
this.wssSendRefreshRequired('plugins');
|
|
1175
1181
|
this.wssSendRefreshRequired('devices');
|
|
@@ -1271,8 +1277,10 @@ export class Frontend extends EventEmitter {
|
|
|
1271
1277
|
if (plugin.restartRequired)
|
|
1272
1278
|
needRestart++;
|
|
1273
1279
|
}
|
|
1274
|
-
if (needRestart === 0)
|
|
1280
|
+
if (needRestart === 0) {
|
|
1275
1281
|
this.wssSendRestartNotRequired(true);
|
|
1282
|
+
this.server.request({ type: 'matterbridge_apisettings', src: 'frontend', dst: 'matterbridge', params: { restartRequired: false } });
|
|
1283
|
+
}
|
|
1276
1284
|
if (plugin.serverNode)
|
|
1277
1285
|
await this.matterbridge.startServerNode(plugin.serverNode);
|
|
1278
1286
|
for (const device of this.matterbridge.devices.array().filter((d) => d.plugin === plugin.name && d.serverNode))
|
|
@@ -1296,6 +1304,7 @@ export class Frontend extends EventEmitter {
|
|
|
1296
1304
|
if (plugin) {
|
|
1297
1305
|
fireAndForget(this.matterbridge.plugins.saveConfigFromJson(plugin, data.params.formData, true), this.log, `Save config for plugin ${plugin.name}`);
|
|
1298
1306
|
this.wssSendSnackbarMessage(`Saved config for plugin ${data.params.pluginName}`);
|
|
1307
|
+
this.server.request({ type: 'matterbridge_apisettings', src: 'frontend', dst: 'matterbridge', params: { restartRequired: true } });
|
|
1299
1308
|
this.wssSendRestartRequired();
|
|
1300
1309
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
1301
1310
|
}
|
|
@@ -1558,6 +1567,7 @@ export class Frontend extends EventEmitter {
|
|
|
1558
1567
|
case 'setbridgemode':
|
|
1559
1568
|
if (isValidString(data.params.value) && ['bridge', 'childbridge'].includes(data.params.value)) {
|
|
1560
1569
|
await this.matterbridge.nodeContext?.set('bridgeMode', data.params.value);
|
|
1570
|
+
this.server.request({ type: 'matterbridge_apisettings', src: 'frontend', dst: 'matterbridge', params: { restartRequired: true } });
|
|
1561
1571
|
this.wssSendRestartRequired();
|
|
1562
1572
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
1563
1573
|
}
|
|
@@ -1651,6 +1661,7 @@ export class Frontend extends EventEmitter {
|
|
|
1651
1661
|
this.log.debug(`Matter.js mdns interface: ${data.params.value === '' ? 'all interfaces' : data.params.value}`);
|
|
1652
1662
|
this.matterbridge.mdnsInterface = data.params.value === '' ? undefined : data.params.value;
|
|
1653
1663
|
await this.matterbridge.nodeContext?.set('mattermdnsinterface', data.params.value);
|
|
1664
|
+
this.server.request({ type: 'matterbridge_apisettings', src: 'frontend', dst: 'matterbridge', params: { restartRequired: true } });
|
|
1654
1665
|
this.wssSendRestartRequired();
|
|
1655
1666
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
1656
1667
|
this.wssSendSnackbarMessage(`Mdns interface changed to ${data.params.value === '' ? 'all interfaces' : data.params.value}`);
|
|
@@ -1661,6 +1672,7 @@ export class Frontend extends EventEmitter {
|
|
|
1661
1672
|
this.log.debug(`Matter.js ipv4 address: ${data.params.value === '' ? 'all ipv4 addresses' : data.params.value}`);
|
|
1662
1673
|
this.matterbridge.ipv4Address = data.params.value === '' ? undefined : data.params.value;
|
|
1663
1674
|
await this.matterbridge.nodeContext?.set('matteripv4address', data.params.value);
|
|
1675
|
+
this.server.request({ type: 'matterbridge_apisettings', src: 'frontend', dst: 'matterbridge', params: { restartRequired: true } });
|
|
1664
1676
|
this.wssSendRestartRequired();
|
|
1665
1677
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
1666
1678
|
this.wssSendSnackbarMessage(`IPv4 address changed to ${data.params.value === '' ? 'all ipv4 addresses' : data.params.value}`);
|
|
@@ -1671,6 +1683,7 @@ export class Frontend extends EventEmitter {
|
|
|
1671
1683
|
this.log.debug(`Matter.js ipv6 address: ${data.params.value === '' ? 'all ipv6 addresses' : data.params.value}`);
|
|
1672
1684
|
this.matterbridge.ipv6Address = data.params.value === '' ? undefined : data.params.value;
|
|
1673
1685
|
await this.matterbridge.nodeContext?.set('matteripv6address', data.params.value);
|
|
1686
|
+
this.server.request({ type: 'matterbridge_apisettings', src: 'frontend', dst: 'matterbridge', params: { restartRequired: true } });
|
|
1674
1687
|
this.wssSendRestartRequired();
|
|
1675
1688
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
1676
1689
|
this.wssSendSnackbarMessage(`IPv6 address changed to ${data.params.value === '' ? 'all ipv6 addresses' : data.params.value}`);
|
|
@@ -1682,6 +1695,7 @@ export class Frontend extends EventEmitter {
|
|
|
1682
1695
|
this.log.debug(`Set matter commissioning port to ${CYAN}${port}${db}`);
|
|
1683
1696
|
this.matterbridge.port = this.matterbridge.initialPort = port;
|
|
1684
1697
|
await this.matterbridge.nodeContext?.set('matterport', port);
|
|
1698
|
+
this.server.request({ type: 'matterbridge_apisettings', src: 'frontend', dst: 'matterbridge', params: { restartRequired: true } });
|
|
1685
1699
|
this.wssSendRestartRequired();
|
|
1686
1700
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
1687
1701
|
this.wssSendSnackbarMessage(`Matter port changed to ${port}`);
|
|
@@ -1690,6 +1704,7 @@ export class Frontend extends EventEmitter {
|
|
|
1690
1704
|
this.log.debug(`Reset matter commissioning port to ${CYAN}5540${db}`);
|
|
1691
1705
|
this.matterbridge.port = this.matterbridge.initialPort = 5540;
|
|
1692
1706
|
await this.matterbridge.nodeContext?.set('matterport', 5540);
|
|
1707
|
+
this.server.request({ type: 'matterbridge_apisettings', src: 'frontend', dst: 'matterbridge', params: { restartRequired: true } });
|
|
1693
1708
|
this.wssSendRestartRequired();
|
|
1694
1709
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, error: 'Invalid value: reset matter commissioning port to default 5540' });
|
|
1695
1710
|
this.wssSendSnackbarMessage(`Matter port reset to default 5540`, undefined, 'error');
|
|
@@ -1701,6 +1716,7 @@ export class Frontend extends EventEmitter {
|
|
|
1701
1716
|
this.log.debug(`Set matter commissioning discriminator to ${CYAN}${discriminator}${db}`);
|
|
1702
1717
|
this.matterbridge.discriminator = this.matterbridge.initialDiscriminator = discriminator;
|
|
1703
1718
|
await this.matterbridge.nodeContext?.set('matterdiscriminator', discriminator);
|
|
1719
|
+
this.server.request({ type: 'matterbridge_apisettings', src: 'frontend', dst: 'matterbridge', params: { restartRequired: true } });
|
|
1704
1720
|
this.wssSendRestartRequired();
|
|
1705
1721
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
1706
1722
|
this.wssSendSnackbarMessage(`Matter discriminator changed to ${discriminator}`);
|
|
@@ -1709,6 +1725,7 @@ export class Frontend extends EventEmitter {
|
|
|
1709
1725
|
this.log.debug(`Reset matter commissioning discriminator to ${CYAN}undefined${db}`);
|
|
1710
1726
|
this.matterbridge.discriminator = this.matterbridge.initialDiscriminator = undefined;
|
|
1711
1727
|
await this.matterbridge.nodeContext?.remove('matterdiscriminator');
|
|
1728
|
+
this.server.request({ type: 'matterbridge_apisettings', src: 'frontend', dst: 'matterbridge', params: { restartRequired: true } });
|
|
1712
1729
|
this.wssSendRestartRequired();
|
|
1713
1730
|
sendResponse({
|
|
1714
1731
|
id: data.id,
|
|
@@ -1726,6 +1743,7 @@ export class Frontend extends EventEmitter {
|
|
|
1726
1743
|
this.matterbridge.passcode = this.matterbridge.initialPasscode = passcode;
|
|
1727
1744
|
this.log.debug(`Set matter commissioning passcode to ${CYAN}${passcode}${db}`);
|
|
1728
1745
|
await this.matterbridge.nodeContext?.set('matterpasscode', passcode);
|
|
1746
|
+
this.server.request({ type: 'matterbridge_apisettings', src: 'frontend', dst: 'matterbridge', params: { restartRequired: true } });
|
|
1729
1747
|
this.wssSendRestartRequired();
|
|
1730
1748
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
1731
1749
|
this.wssSendSnackbarMessage(`Matter passcode changed to ${passcode}`);
|
|
@@ -1734,6 +1752,7 @@ export class Frontend extends EventEmitter {
|
|
|
1734
1752
|
this.log.debug(`Reset matter commissioning passcode to ${CYAN}undefined${db}`);
|
|
1735
1753
|
this.matterbridge.passcode = this.matterbridge.initialPasscode = undefined;
|
|
1736
1754
|
await this.matterbridge.nodeContext?.remove('matterpasscode');
|
|
1755
|
+
this.server.request({ type: 'matterbridge_apisettings', src: 'frontend', dst: 'matterbridge', params: { restartRequired: true } });
|
|
1737
1756
|
this.wssSendRestartRequired();
|
|
1738
1757
|
sendResponse({
|
|
1739
1758
|
id: data.id,
|
|
@@ -1750,6 +1769,7 @@ export class Frontend extends EventEmitter {
|
|
|
1750
1769
|
this.matterbridge.virtualMode = data.params.value;
|
|
1751
1770
|
this.log.debug(`Set matterbridge virtual mode to ${CYAN}${data.params.value}${db}`);
|
|
1752
1771
|
await this.matterbridge.nodeContext?.set('virtualmode', data.params.value);
|
|
1772
|
+
this.server.request({ type: 'matterbridge_apisettings', src: 'frontend', dst: 'matterbridge', params: { restartRequired: true } });
|
|
1753
1773
|
this.wssSendRestartRequired();
|
|
1754
1774
|
}
|
|
1755
1775
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
@@ -1801,6 +1821,7 @@ export class Frontend extends EventEmitter {
|
|
|
1801
1821
|
plugin.platform.config = config;
|
|
1802
1822
|
plugin.configJson = config;
|
|
1803
1823
|
await this.matterbridge.plugins.saveConfigFromPlugin(plugin, true);
|
|
1824
|
+
this.server.request({ type: 'matterbridge_apisettings', src: 'frontend', dst: 'matterbridge', params: { restartRequired: true } });
|
|
1804
1825
|
this.wssSendRestartRequired(false);
|
|
1805
1826
|
this.wssSendRefreshRequired('plugins', { lock: plugin.name });
|
|
1806
1827
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
@@ -1849,6 +1870,7 @@ export class Frontend extends EventEmitter {
|
|
|
1849
1870
|
plugin.platform.config = config;
|
|
1850
1871
|
plugin.configJson = config;
|
|
1851
1872
|
await this.matterbridge.plugins.saveConfigFromPlugin(plugin, true);
|
|
1873
|
+
this.server.request({ type: 'matterbridge_apisettings', src: 'frontend', dst: 'matterbridge', params: { restartRequired: true } });
|
|
1852
1874
|
this.wssSendRestartRequired(false);
|
|
1853
1875
|
this.wssSendRefreshRequired('plugins', { lock: plugin.name });
|
|
1854
1876
|
sendResponse({ id: data.id, method: data.method, src: 'Matterbridge', dst: data.src, success: true });
|
|
@@ -1905,8 +1927,6 @@ export class Frontend extends EventEmitter {
|
|
|
1905
1927
|
if (!this.listening || this.webSocketServer?.clients.size === 0)
|
|
1906
1928
|
return;
|
|
1907
1929
|
this.log.debug('Sending a restart required message to all connected clients');
|
|
1908
|
-
this.restartRequired = true;
|
|
1909
|
-
this.fixedRestartRequired = fixed;
|
|
1910
1930
|
if (snackbar)
|
|
1911
1931
|
this.wssSendSnackbarMessage(`Restart required`, 0);
|
|
1912
1932
|
this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'restart_required', success: true, response: { fixed } });
|
|
@@ -1915,7 +1935,6 @@ export class Frontend extends EventEmitter {
|
|
|
1915
1935
|
if (!this.listening || this.webSocketServer?.clients.size === 0)
|
|
1916
1936
|
return;
|
|
1917
1937
|
this.log.debug('Sending a restart not required message to all connected clients');
|
|
1918
|
-
this.restartRequired = false;
|
|
1919
1938
|
if (snackbar)
|
|
1920
1939
|
this.wssSendCloseSnackbarMessage(`Restart required`);
|
|
1921
1940
|
this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'restart_not_required', success: true });
|
|
@@ -1924,7 +1943,6 @@ export class Frontend extends EventEmitter {
|
|
|
1924
1943
|
if (!this.listening || this.webSocketServer?.clients.size === 0)
|
|
1925
1944
|
return;
|
|
1926
1945
|
this.log.debug('Sending a matterbridge version update required message to all connected clients');
|
|
1927
|
-
this.updateRequired = true;
|
|
1928
1946
|
this.wssBroadcastMessage({ id: 0, src: 'Matterbridge', dst: 'Frontend', method: 'update_required', success: true, response: { version, devVersion } });
|
|
1929
1947
|
}
|
|
1930
1948
|
wssSendPluginUpdateRequired(plugin, version, devVersion = false) {
|
package/dist/matterbridge.d.ts
CHANGED
|
@@ -34,6 +34,7 @@ interface MatterbridgeEvents {
|
|
|
34
34
|
export declare class Matterbridge extends EventEmitter<MatterbridgeEvents> {
|
|
35
35
|
private readonly debug;
|
|
36
36
|
private readonly verbose;
|
|
37
|
+
private readonly diagnostic;
|
|
37
38
|
systemInformation: SystemInformation;
|
|
38
39
|
uuid: string;
|
|
39
40
|
homeDirectory: string;
|
|
@@ -55,6 +56,10 @@ export declare class Matterbridge extends EventEmitter<MatterbridgeEvents> {
|
|
|
55
56
|
virtualMode: VirtualMode;
|
|
56
57
|
bridgeStatus: BridgeStatus;
|
|
57
58
|
readonly profile: string | undefined;
|
|
59
|
+
readonly readOnly: boolean;
|
|
60
|
+
restartRequired: boolean;
|
|
61
|
+
fixedRestartRequired: boolean;
|
|
62
|
+
updateRequired: boolean;
|
|
58
63
|
readonly log: AnsiLogger;
|
|
59
64
|
logLevel: LogLevel;
|
|
60
65
|
fileLogger: boolean;
|
package/dist/matterbridge.js
CHANGED
|
@@ -37,8 +37,9 @@ import { clearAdvertisingNodes, deleteAdvertisingNode, getServerNodeData, setAdv
|
|
|
37
37
|
import { PluginManager } from './pluginManager.js';
|
|
38
38
|
logModuleLoaded('Matterbridge');
|
|
39
39
|
export class Matterbridge extends EventEmitter {
|
|
40
|
-
debug =
|
|
41
|
-
verbose =
|
|
40
|
+
debug = hasAnyParameter('debug', 'verbose', 'debug-matterbridge', 'verbose-matterbridge');
|
|
41
|
+
verbose = hasAnyParameter('verbose', 'verbose-matterbridge');
|
|
42
|
+
diagnostic = hasAnyParameter('diagnostic', 'diagnostic-matterbridge');
|
|
42
43
|
systemInformation = {
|
|
43
44
|
interfaceName: '',
|
|
44
45
|
macAddress: '',
|
|
@@ -82,6 +83,10 @@ export class Matterbridge extends EventEmitter {
|
|
|
82
83
|
virtualMode = 'outlet';
|
|
83
84
|
bridgeStatus = 'inactive';
|
|
84
85
|
profile = getParameter('profile');
|
|
86
|
+
readOnly = hasParameter('readonly');
|
|
87
|
+
restartRequired = false;
|
|
88
|
+
fixedRestartRequired = false;
|
|
89
|
+
updateRequired = false;
|
|
85
90
|
log = new AnsiLogger({
|
|
86
91
|
logName: 'Matterbridge',
|
|
87
92
|
logNameColor: '\x1b[38;5;115m',
|
|
@@ -278,7 +283,10 @@ export class Matterbridge extends EventEmitter {
|
|
|
278
283
|
virtualMode: this.virtualMode,
|
|
279
284
|
bridgeStatus: this.bridgeStatus,
|
|
280
285
|
profile: this.profile,
|
|
281
|
-
readOnly:
|
|
286
|
+
readOnly: this.readOnly,
|
|
287
|
+
restartRequired: this.restartRequired,
|
|
288
|
+
fixedRestartRequired: this.fixedRestartRequired,
|
|
289
|
+
updateRequired: this.updateRequired,
|
|
282
290
|
loggerLevel: this.logLevel,
|
|
283
291
|
fileLogger: this.fileLogger,
|
|
284
292
|
matterLoggerLevel: this.matterLogLevel,
|
|
@@ -289,9 +297,6 @@ export class Matterbridge extends EventEmitter {
|
|
|
289
297
|
matterPort: this.port ?? 5540,
|
|
290
298
|
matterDiscriminator: this.discriminator,
|
|
291
299
|
matterPasscode: this.passcode,
|
|
292
|
-
restartRequired: false,
|
|
293
|
-
fixedRestartRequired: false,
|
|
294
|
-
updateRequired: false,
|
|
295
300
|
startupAt: this.startupAt,
|
|
296
301
|
shutdownAt: this.shutdownAt,
|
|
297
302
|
runningTimes: this.runningTimes,
|
|
@@ -357,6 +362,14 @@ export class Matterbridge extends EventEmitter {
|
|
|
357
362
|
await this.shutdownProcess();
|
|
358
363
|
break;
|
|
359
364
|
case 'matterbridge_apisettings':
|
|
365
|
+
if (msg.params?.fixedRestartRequired === true)
|
|
366
|
+
this.fixedRestartRequired = true;
|
|
367
|
+
if (this.fixedRestartRequired)
|
|
368
|
+
this.restartRequired = true;
|
|
369
|
+
else if (msg.params?.restartRequired !== undefined)
|
|
370
|
+
this.restartRequired = msg.params.restartRequired;
|
|
371
|
+
if (msg.params?.updateRequired !== undefined)
|
|
372
|
+
this.updateRequired = msg.params.updateRequired;
|
|
360
373
|
this.server.respond({ ...msg, result: { data: this.getApiSettings(), success: true } });
|
|
361
374
|
break;
|
|
362
375
|
case 'matterbridge_start_plugin_server':
|
|
@@ -1901,23 +1914,28 @@ export class Matterbridge extends EventEmitter {
|
|
|
1901
1914
|
this.serverNodeStorageManagers.set(storeId, storageManager);
|
|
1902
1915
|
const storageContext = storageManager.createContext('persist');
|
|
1903
1916
|
const random = randomBytes(8).toString('hex');
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
await
|
|
1910
|
-
await
|
|
1911
|
-
await
|
|
1912
|
-
await
|
|
1913
|
-
await
|
|
1914
|
-
await
|
|
1915
|
-
await
|
|
1916
|
-
await
|
|
1917
|
-
await
|
|
1918
|
-
await
|
|
1919
|
-
await storageContext.
|
|
1920
|
-
await storageContext.
|
|
1917
|
+
async function setIfDifferent(key, value) {
|
|
1918
|
+
if (!(await storageContext.has(key)) || (await storageContext.get(key)) !== value) {
|
|
1919
|
+
await storageContext.set(key, value);
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1922
|
+
await setIfDifferent('storeId', storeId);
|
|
1923
|
+
await setIfDifferent('deviceName', deviceName);
|
|
1924
|
+
await setIfDifferent('deviceType', deviceType);
|
|
1925
|
+
await setIfDifferent('vendorId', vendorId);
|
|
1926
|
+
await setIfDifferent('vendorName', vendorName.slice(0, 32));
|
|
1927
|
+
await setIfDifferent('productId', productId);
|
|
1928
|
+
await setIfDifferent('productName', productName.slice(0, 32));
|
|
1929
|
+
await setIfDifferent('productLabel', productLabel.replace(vendorName, '').trim().slice(0, 64));
|
|
1930
|
+
await setIfDifferent('productUrl', isValidString(productUrl, 8, 256) && productUrl.startsWith('https://') ? productUrl : 'https://matterbridge.io');
|
|
1931
|
+
await setIfDifferent('nodeLabel', deviceName.slice(0, 32));
|
|
1932
|
+
await setIfDifferent('serialNumber', await storageContext.get('serialNumber', serialNumber ? serialNumber.slice(0, 32) : 'SN' + random));
|
|
1933
|
+
await setIfDifferent('uniqueId', await storageContext.get('uniqueId', uniqueId ? uniqueId.slice(0, 32) : 'UI' + random));
|
|
1934
|
+
await setIfDifferent('softwareVersion', isValidInteger(softwareVersion, 0, UINT32_MAX) ? softwareVersion : 1);
|
|
1935
|
+
await setIfDifferent('softwareVersionString', isValidString(softwareVersionString, 1, 64) ? softwareVersionString : '1.0.0');
|
|
1936
|
+
await setIfDifferent('hardwareVersion', isValidInteger(hardwareVersion, 0, UINT16_MAX) ? hardwareVersion : 1);
|
|
1937
|
+
await setIfDifferent('hardwareVersionString', isValidString(hardwareVersionString, 1, 64) ? hardwareVersionString : '1.0.0');
|
|
1938
|
+
await setIfDifferent('configurationVersion', isValidInteger(configurationVersion, 1, UINT32_MAX) ? configurationVersion : 1);
|
|
1921
1939
|
this.log.debug(`Created server node storage context "${storeId}.persist" for ${storeId}:`);
|
|
1922
1940
|
this.log.debug(`- storeId: ${await storageContext.get('storeId')}`);
|
|
1923
1941
|
this.log.debug(`- deviceName: ${await storageContext.get('deviceName')}`);
|
|
@@ -2046,6 +2064,7 @@ export class Matterbridge extends EventEmitter {
|
|
|
2046
2064
|
this.frontend.wssSendSnackbarMessage(`${storeId} is offline`, 5, 'warning');
|
|
2047
2065
|
this.frontend.wssSendSnackbarMessage(`Server node for ${storeId} fully decommissioned successfully!`, 5, 'success');
|
|
2048
2066
|
this.log.notice(`Server node for ${storeId} was reset to factory defaults: restart Matterbridge before pairing it again`);
|
|
2067
|
+
this.restartRequired = true;
|
|
2049
2068
|
this.frontend.wssSendRestartRequired();
|
|
2050
2069
|
this.frontend.wssSendSnackbarMessage(`Server node for ${storeId} was reset to factory defaults: restart Matterbridge before pairing it again`, 10, 'warning');
|
|
2051
2070
|
});
|
|
@@ -158,7 +158,7 @@ export const rootNode = DeviceTypeDefinition({
|
|
|
158
158
|
code: 0x0016,
|
|
159
159
|
deviceClass: DeviceClasses.Node,
|
|
160
160
|
deviceScope: DeviceScopes.Node,
|
|
161
|
-
revision:
|
|
161
|
+
revision: 5,
|
|
162
162
|
requiredServerClusters: [],
|
|
163
163
|
optionalServerClusters: [],
|
|
164
164
|
requiredClientClusters: [],
|
|
@@ -230,7 +230,7 @@ export const onOffLight = DeviceTypeDefinition({
|
|
|
230
230
|
code: 0x0100,
|
|
231
231
|
deviceClass: DeviceClasses.Simple,
|
|
232
232
|
deviceScope: DeviceScopes.Endpoint,
|
|
233
|
-
revision:
|
|
233
|
+
revision: 4,
|
|
234
234
|
requiredServerClusters: [Identify.id, Groups.id, ScenesManagement.id, OnOff.id],
|
|
235
235
|
optionalServerClusters: [LevelControl.id],
|
|
236
236
|
requiredClientClusters: [],
|
|
@@ -241,7 +241,7 @@ export const dimmableLight = DeviceTypeDefinition({
|
|
|
241
241
|
code: 0x0101,
|
|
242
242
|
deviceClass: DeviceClasses.Simple,
|
|
243
243
|
deviceScope: DeviceScopes.Endpoint,
|
|
244
|
-
revision:
|
|
244
|
+
revision: 4,
|
|
245
245
|
requiredServerClusters: [Identify.id, Groups.id, ScenesManagement.id, OnOff.id, LevelControl.id],
|
|
246
246
|
optionalServerClusters: [],
|
|
247
247
|
requiredClientClusters: [],
|
|
@@ -252,7 +252,7 @@ export const colorTemperatureLight = DeviceTypeDefinition({
|
|
|
252
252
|
code: 0x010c,
|
|
253
253
|
deviceClass: DeviceClasses.Simple,
|
|
254
254
|
deviceScope: DeviceScopes.Endpoint,
|
|
255
|
-
revision:
|
|
255
|
+
revision: 5,
|
|
256
256
|
requiredServerClusters: [Identify.id, Groups.id, ScenesManagement.id, OnOff.id, LevelControl.id, ColorControl.id],
|
|
257
257
|
optionalServerClusters: [],
|
|
258
258
|
requiredClientClusters: [],
|
|
@@ -263,7 +263,7 @@ export const extendedColorLight = DeviceTypeDefinition({
|
|
|
263
263
|
code: 0x010d,
|
|
264
264
|
deviceClass: DeviceClasses.Simple,
|
|
265
265
|
deviceScope: DeviceScopes.Endpoint,
|
|
266
|
-
revision:
|
|
266
|
+
revision: 5,
|
|
267
267
|
requiredServerClusters: [Identify.id, Groups.id, ScenesManagement.id, OnOff.id, LevelControl.id, ColorControl.id],
|
|
268
268
|
optionalServerClusters: [],
|
|
269
269
|
requiredClientClusters: [],
|
|
@@ -274,7 +274,7 @@ export const onOffPlugInUnit = DeviceTypeDefinition({
|
|
|
274
274
|
code: 0x010a,
|
|
275
275
|
deviceClass: DeviceClasses.Simple,
|
|
276
276
|
deviceScope: DeviceScopes.Endpoint,
|
|
277
|
-
revision:
|
|
277
|
+
revision: 5,
|
|
278
278
|
requiredServerClusters: [Identify.id, Groups.id, ScenesManagement.id, OnOff.id],
|
|
279
279
|
optionalServerClusters: [LevelControl.id],
|
|
280
280
|
requiredClientClusters: [],
|
|
@@ -285,7 +285,7 @@ export const dimmablePlugInUnit = DeviceTypeDefinition({
|
|
|
285
285
|
code: 0x010b,
|
|
286
286
|
deviceClass: DeviceClasses.Simple,
|
|
287
287
|
deviceScope: DeviceScopes.Endpoint,
|
|
288
|
-
revision:
|
|
288
|
+
revision: 6,
|
|
289
289
|
requiredServerClusters: [Identify.id, Groups.id, ScenesManagement.id, OnOff.id, LevelControl.id],
|
|
290
290
|
optionalServerClusters: [],
|
|
291
291
|
requiredClientClusters: [],
|
|
@@ -296,7 +296,7 @@ export const mountedOnOffControl = DeviceTypeDefinition({
|
|
|
296
296
|
code: 0x010f,
|
|
297
297
|
deviceClass: DeviceClasses.Simple,
|
|
298
298
|
deviceScope: DeviceScopes.Endpoint,
|
|
299
|
-
revision:
|
|
299
|
+
revision: 3,
|
|
300
300
|
requiredServerClusters: [Identify.id, Groups.id, ScenesManagement.id, OnOff.id],
|
|
301
301
|
optionalServerClusters: [LevelControl.id],
|
|
302
302
|
requiredClientClusters: [],
|
|
@@ -307,7 +307,7 @@ export const mountedDimmableLoadControl = DeviceTypeDefinition({
|
|
|
307
307
|
code: 0x0110,
|
|
308
308
|
deviceClass: DeviceClasses.Simple,
|
|
309
309
|
deviceScope: DeviceScopes.Endpoint,
|
|
310
|
-
revision:
|
|
310
|
+
revision: 3,
|
|
311
311
|
requiredServerClusters: [Identify.id, Groups.id, ScenesManagement.id, OnOff.id, LevelControl.id],
|
|
312
312
|
optionalServerClusters: [],
|
|
313
313
|
requiredClientClusters: [],
|
|
@@ -318,7 +318,7 @@ export const pump = DeviceTypeDefinition({
|
|
|
318
318
|
code: 0x303,
|
|
319
319
|
deviceClass: DeviceClasses.Simple,
|
|
320
320
|
deviceScope: DeviceScopes.Endpoint,
|
|
321
|
-
revision:
|
|
321
|
+
revision: 4,
|
|
322
322
|
requiredServerClusters: [OnOff.id, PumpConfigurationAndControl.id, Identify.id],
|
|
323
323
|
optionalServerClusters: [LevelControl.id, Groups.id, ScenesManagement.id, TemperatureMeasurement.id, PressureMeasurement.id, FlowMeasurement.id],
|
|
324
324
|
requiredClientClusters: [],
|
|
@@ -352,8 +352,8 @@ export const onOffLightSwitch = DeviceTypeDefinition({
|
|
|
352
352
|
code: 0x0103,
|
|
353
353
|
deviceClass: DeviceClasses.Simple,
|
|
354
354
|
deviceScope: DeviceScopes.Endpoint,
|
|
355
|
-
revision:
|
|
356
|
-
requiredServerClusters: [Identify.id],
|
|
355
|
+
revision: 4,
|
|
356
|
+
requiredServerClusters: [Identify.id, Binding.id],
|
|
357
357
|
optionalServerClusters: [],
|
|
358
358
|
requiredClientClusters: [Identify.id, OnOff.id],
|
|
359
359
|
optionalClientClusters: [Groups.id, ScenesManagement.id],
|
|
@@ -363,8 +363,8 @@ export const dimmerSwitch = DeviceTypeDefinition({
|
|
|
363
363
|
code: 0x0104,
|
|
364
364
|
deviceClass: DeviceClasses.Simple,
|
|
365
365
|
deviceScope: DeviceScopes.Endpoint,
|
|
366
|
-
revision:
|
|
367
|
-
requiredServerClusters: [Identify.id],
|
|
366
|
+
revision: 4,
|
|
367
|
+
requiredServerClusters: [Identify.id, Binding.id],
|
|
368
368
|
optionalServerClusters: [],
|
|
369
369
|
requiredClientClusters: [Identify.id, OnOff.id, LevelControl.id],
|
|
370
370
|
optionalClientClusters: [Groups.id, ScenesManagement.id],
|
|
@@ -374,8 +374,8 @@ export const colorDimmerSwitch = DeviceTypeDefinition({
|
|
|
374
374
|
code: 0x0105,
|
|
375
375
|
deviceClass: DeviceClasses.Simple,
|
|
376
376
|
deviceScope: DeviceScopes.Endpoint,
|
|
377
|
-
revision:
|
|
378
|
-
requiredServerClusters: [Identify.id],
|
|
377
|
+
revision: 4,
|
|
378
|
+
requiredServerClusters: [Identify.id, Binding.id],
|
|
379
379
|
optionalServerClusters: [],
|
|
380
380
|
requiredClientClusters: [Identify.id, OnOff.id, LevelControl.id, ColorControl.id],
|
|
381
381
|
optionalClientClusters: [Groups.id, ScenesManagement.id],
|
|
@@ -385,8 +385,8 @@ export const controlBridge = DeviceTypeDefinition({
|
|
|
385
385
|
code: 0x0840,
|
|
386
386
|
deviceClass: DeviceClasses.Simple,
|
|
387
387
|
deviceScope: DeviceScopes.Endpoint,
|
|
388
|
-
revision:
|
|
389
|
-
requiredServerClusters: [Identify.id],
|
|
388
|
+
revision: 4,
|
|
389
|
+
requiredServerClusters: [Identify.id, Binding.id],
|
|
390
390
|
optionalServerClusters: [],
|
|
391
391
|
requiredClientClusters: [Identify.id, Groups.id, ScenesManagement.id, OnOff.id, LevelControl.id, ColorControl.id],
|
|
392
392
|
optionalClientClusters: [IlluminanceMeasurement.id, OccupancySensing.id],
|
|
@@ -396,8 +396,8 @@ export const pumpController = DeviceTypeDefinition({
|
|
|
396
396
|
code: 0x0304,
|
|
397
397
|
deviceClass: DeviceClasses.Simple,
|
|
398
398
|
deviceScope: DeviceScopes.Endpoint,
|
|
399
|
-
revision:
|
|
400
|
-
requiredServerClusters: [Identify.id],
|
|
399
|
+
revision: 5,
|
|
400
|
+
requiredServerClusters: [Identify.id, Binding.id],
|
|
401
401
|
optionalServerClusters: [],
|
|
402
402
|
requiredClientClusters: [OnOff.id, PumpConfigurationAndControl.id],
|
|
403
403
|
optionalClientClusters: [Identify.id, Groups.id, LevelControl.id, ScenesManagement.id, TemperatureMeasurement.id, PressureMeasurement.id, FlowMeasurement.id],
|
|
@@ -475,8 +475,8 @@ export const onOffSensor = DeviceTypeDefinition({
|
|
|
475
475
|
code: 0x0850,
|
|
476
476
|
deviceClass: DeviceClasses.Simple,
|
|
477
477
|
deviceScope: DeviceScopes.Endpoint,
|
|
478
|
-
revision:
|
|
479
|
-
requiredServerClusters: [Identify.id],
|
|
478
|
+
revision: 4,
|
|
479
|
+
requiredServerClusters: [Identify.id, Binding.id],
|
|
480
480
|
requiredClientClusters: [Identify.id, OnOff.id],
|
|
481
481
|
optionalClientClusters: [Groups.id, LevelControl.id, ColorControl.id, ScenesManagement.id],
|
|
482
482
|
});
|
|
@@ -485,7 +485,7 @@ export const smokeCoAlarm = DeviceTypeDefinition({
|
|
|
485
485
|
code: 0x0076,
|
|
486
486
|
deviceClass: DeviceClasses.Simple,
|
|
487
487
|
deviceScope: DeviceScopes.Endpoint,
|
|
488
|
-
revision:
|
|
488
|
+
revision: 2,
|
|
489
489
|
requiredServerClusters: [Identify.id, SmokeCoAlarm.id],
|
|
490
490
|
optionalServerClusters: [Groups.id, TemperatureMeasurement.id, RelativeHumidityMeasurement.id, CarbonMonoxideConcentrationMeasurement.id],
|
|
491
491
|
requiredDeviceTypes: [powerSource],
|
|
@@ -562,8 +562,8 @@ export const doorLockController = DeviceTypeDefinition({
|
|
|
562
562
|
code: 0x00b,
|
|
563
563
|
deviceClass: DeviceClasses.Simple,
|
|
564
564
|
deviceScope: DeviceScopes.Endpoint,
|
|
565
|
-
revision:
|
|
566
|
-
requiredServerClusters: [],
|
|
565
|
+
revision: 4,
|
|
566
|
+
requiredServerClusters: [Binding.id],
|
|
567
567
|
optionalServerClusters: [],
|
|
568
568
|
requiredClientClusters: [DoorLock.id],
|
|
569
569
|
optionalClientClusters: [Groups.id, ScenesManagement.id],
|
|
@@ -573,7 +573,7 @@ export const windowCovering = DeviceTypeDefinition({
|
|
|
573
573
|
code: 0x202,
|
|
574
574
|
deviceClass: DeviceClasses.Simple,
|
|
575
575
|
deviceScope: DeviceScopes.Endpoint,
|
|
576
|
-
revision:
|
|
576
|
+
revision: 7,
|
|
577
577
|
requiredServerClusters: [Identify.id, WindowCovering.id],
|
|
578
578
|
optionalServerClusters: [Groups.id],
|
|
579
579
|
});
|
|
@@ -582,8 +582,8 @@ export const windowCoveringController = DeviceTypeDefinition({
|
|
|
582
582
|
code: 0x203,
|
|
583
583
|
deviceClass: DeviceClasses.Simple,
|
|
584
584
|
deviceScope: DeviceScopes.Endpoint,
|
|
585
|
-
revision:
|
|
586
|
-
requiredServerClusters: [],
|
|
585
|
+
revision: 5,
|
|
586
|
+
requiredServerClusters: [Binding.id],
|
|
587
587
|
optionalServerClusters: [Identify.id],
|
|
588
588
|
requiredClientClusters: [WindowCovering.id],
|
|
589
589
|
optionalClientClusters: [Identify.id, Groups.id],
|
|
@@ -611,8 +611,8 @@ export const closureController = DeviceTypeDefinition({
|
|
|
611
611
|
code: 0x023e,
|
|
612
612
|
deviceClass: DeviceClasses.Simple,
|
|
613
613
|
deviceScope: DeviceScopes.Endpoint,
|
|
614
|
-
revision:
|
|
615
|
-
requiredServerClusters: [],
|
|
614
|
+
revision: 2,
|
|
615
|
+
requiredServerClusters: [Binding.id],
|
|
616
616
|
optionalServerClusters: [],
|
|
617
617
|
requiredClientClusters: [ClosureControl.id],
|
|
618
618
|
optionalClientClusters: [Identify.id, ClosureDimension.id],
|
|
@@ -622,7 +622,7 @@ export const thermostat = DeviceTypeDefinition({
|
|
|
622
622
|
code: 0x301,
|
|
623
623
|
deviceClass: DeviceClasses.Simple,
|
|
624
624
|
deviceScope: DeviceScopes.Endpoint,
|
|
625
|
-
revision:
|
|
625
|
+
revision: 7,
|
|
626
626
|
requiredServerClusters: [Identify.id, Thermostat.id],
|
|
627
627
|
optionalServerClusters: [Groups.id, ThermostatUserInterfaceConfiguration.id, EnergyPreference.id],
|
|
628
628
|
requiredClientClusters: [],
|
|
@@ -633,7 +633,7 @@ export const fan = DeviceTypeDefinition({
|
|
|
633
633
|
code: 0x2b,
|
|
634
634
|
deviceClass: DeviceClasses.Simple,
|
|
635
635
|
deviceScope: DeviceScopes.Endpoint,
|
|
636
|
-
revision:
|
|
636
|
+
revision: 5,
|
|
637
637
|
requiredServerClusters: [Identify.id, Groups.id, FanControl.id],
|
|
638
638
|
optionalServerClusters: [OnOff.id],
|
|
639
639
|
});
|
|
@@ -642,7 +642,7 @@ export const airPurifier = DeviceTypeDefinition({
|
|
|
642
642
|
code: 0x2d,
|
|
643
643
|
deviceClass: DeviceClasses.Simple,
|
|
644
644
|
deviceScope: DeviceScopes.Endpoint,
|
|
645
|
-
revision:
|
|
645
|
+
revision: 3,
|
|
646
646
|
requiredServerClusters: [Identify.id, FanControl.id],
|
|
647
647
|
optionalServerClusters: [Groups.id, OnOff.id, HepaFilterMonitoring.id, ActivatedCarbonFilterMonitoring.id],
|
|
648
648
|
});
|
|
@@ -651,8 +651,8 @@ export const thermostatController = DeviceTypeDefinition({
|
|
|
651
651
|
code: 0x030a,
|
|
652
652
|
deviceClass: DeviceClasses.Simple,
|
|
653
653
|
deviceScope: DeviceScopes.Endpoint,
|
|
654
|
-
revision:
|
|
655
|
-
requiredServerClusters: [],
|
|
654
|
+
revision: 2,
|
|
655
|
+
requiredServerClusters: [Binding.id],
|
|
656
656
|
optionalServerClusters: [],
|
|
657
657
|
requiredClientClusters: [Thermostat.id],
|
|
658
658
|
optionalClientClusters: [Identify.id, Groups.id, ScenesManagement.id],
|
|
@@ -712,7 +712,7 @@ export const castingVideoClient = DeviceTypeDefinition({
|
|
|
712
712
|
deviceClass: DeviceClasses.Simple,
|
|
713
713
|
deviceScope: DeviceScopes.Endpoint,
|
|
714
714
|
revision: 2,
|
|
715
|
-
requiredServerClusters: [],
|
|
715
|
+
requiredServerClusters: [Binding.id],
|
|
716
716
|
optionalServerClusters: [ContentAppObserver.id],
|
|
717
717
|
requiredClientClusters: [OnOff.id, KeypadInput.id, ContentLauncher.id, ApplicationBasic.id],
|
|
718
718
|
optionalClientClusters: [
|
|
@@ -736,7 +736,7 @@ export const videoRemoteControl = DeviceTypeDefinition({
|
|
|
736
736
|
deviceClass: DeviceClasses.Simple,
|
|
737
737
|
deviceScope: DeviceScopes.Endpoint,
|
|
738
738
|
revision: 2,
|
|
739
|
-
requiredServerClusters: [],
|
|
739
|
+
requiredServerClusters: [Binding.id],
|
|
740
740
|
optionalServerClusters: [],
|
|
741
741
|
requiredClientClusters: [OnOff.id, MediaPlayback.id, KeypadInput.id],
|
|
742
742
|
optionalClientClusters: [
|
|
@@ -803,7 +803,7 @@ export const roomAirConditioner = DeviceTypeDefinition({
|
|
|
803
803
|
code: 0x72,
|
|
804
804
|
deviceClass: DeviceClasses.Simple,
|
|
805
805
|
deviceScope: DeviceScopes.Endpoint,
|
|
806
|
-
revision:
|
|
806
|
+
revision: 4,
|
|
807
807
|
requiredServerClusters: [Identify.id, OnOff.id, Thermostat.id],
|
|
808
808
|
optionalServerClusters: [
|
|
809
809
|
Groups.id,
|
|
@@ -1026,7 +1026,7 @@ export const audioDoorbell = DeviceTypeDefinition({
|
|
|
1026
1026
|
deviceClass: DeviceClasses.Simple,
|
|
1027
1027
|
deviceScope: DeviceScopes.Endpoint,
|
|
1028
1028
|
revision: 2,
|
|
1029
|
-
requiredServerClusters: [Identify.id, Switch.id, CameraAvStreamManagement.id, WebRtcTransportProvider.id],
|
|
1029
|
+
requiredServerClusters: [Identify.id, Switch.id, CameraAvStreamManagement.id, WebRtcTransportProvider.id, Binding.id],
|
|
1030
1030
|
optionalServerClusters: [WebRtcTransportRequestor.id, PushAvStreamTransport.id],
|
|
1031
1031
|
requiredClientClusters: [WebRtcTransportRequestor.id, Chime.id],
|
|
1032
1032
|
optionalClientClusters: [WebRtcTransportProvider.id],
|
|
@@ -1045,7 +1045,7 @@ export const chime = DeviceTypeDefinition({
|
|
|
1045
1045
|
code: 0x0146,
|
|
1046
1046
|
deviceClass: DeviceClasses.Simple,
|
|
1047
1047
|
deviceScope: DeviceScopes.Endpoint,
|
|
1048
|
-
revision:
|
|
1048
|
+
revision: 2,
|
|
1049
1049
|
requiredServerClusters: [Chime.id],
|
|
1050
1050
|
optionalServerClusters: [Identify.id],
|
|
1051
1051
|
});
|
|
@@ -1076,7 +1076,7 @@ export const doorbell = DeviceTypeDefinition({
|
|
|
1076
1076
|
deviceClass: DeviceClasses.Simple,
|
|
1077
1077
|
deviceScope: DeviceScopes.Endpoint,
|
|
1078
1078
|
revision: 2,
|
|
1079
|
-
requiredServerClusters: [Identify.id, Switch.id],
|
|
1079
|
+
requiredServerClusters: [Identify.id, Switch.id, Binding.id],
|
|
1080
1080
|
optionalServerClusters: [],
|
|
1081
1081
|
requiredClientClusters: [Chime.id],
|
|
1082
1082
|
});
|
|
@@ -63,31 +63,85 @@ export declare function emitCommand(endpoint: MatterbridgeEndpoint, cluster: str
|
|
|
63
63
|
export declare function setCluster(endpoint: MatterbridgeEndpoint, cluster: Behavior.Type | ClusterType | ClusterId | string, value: Record<string, boolean | number | bigint | string | object | undefined | null>, log?: AnsiLogger): Promise<boolean>;
|
|
64
64
|
export declare function getCluster(endpoint: MatterbridgeEndpoint, cluster: Behavior.Type | ClusterType | ClusterId | string, log?: AnsiLogger): Record<string, boolean | number | bigint | string | object | undefined | null> | undefined;
|
|
65
65
|
export declare function triggerEvent(endpoint: MatterbridgeEndpoint, cluster: Behavior.Type | ClusterType | ClusterId | string, event: string, payload: Record<string, boolean | number | bigint | string | object | undefined | null>, log?: AnsiLogger): Promise<boolean>;
|
|
66
|
-
export declare function getDefaultPowerSourceWiredClusterServer(wiredCurrentType?: PowerSource.WiredCurrentType): Partial<import("@matter/node").ClusterState.Type<ClusterType.WithSupportedFeatures<PowerSource, {
|
|
66
|
+
export declare function getDefaultPowerSourceWiredClusterServer(wiredCurrentType?: PowerSource.WiredCurrentType): Partial<import("@matter/node").ClusterState.Type<ClusterType.WithSupportedFeatures<ClusterType.WithSupportedFeatures<ClusterType.WithSupportedFeatures<PowerSource, {
|
|
67
|
+
battery: true;
|
|
68
|
+
rechargeable: true;
|
|
69
|
+
replaceable: false;
|
|
70
|
+
wired: true;
|
|
71
|
+
}>, {
|
|
72
|
+
battery: false;
|
|
73
|
+
rechargeable: false;
|
|
74
|
+
replaceable: false;
|
|
75
|
+
wired: false;
|
|
76
|
+
}>, {
|
|
67
77
|
battery: false;
|
|
68
78
|
rechargeable: false;
|
|
69
79
|
replaceable: false;
|
|
70
80
|
wired: true;
|
|
71
81
|
}>, typeof MatterbridgePowerSourceServer>>;
|
|
72
|
-
export declare function getDefaultPowerSourceBatteryClusterServer(batPercentRemaining?: null | number, batChargeLevel?: PowerSource.BatChargeLevel, batVoltage?: null | number, batReplaceability?: PowerSource.BatReplaceability): Partial<import("@matter/node").ClusterState.Type<ClusterType.WithSupportedFeatures<PowerSource, {
|
|
82
|
+
export declare function getDefaultPowerSourceBatteryClusterServer(batPercentRemaining?: null | number, batChargeLevel?: PowerSource.BatChargeLevel, batVoltage?: null | number, batReplaceability?: PowerSource.BatReplaceability): Partial<import("@matter/node").ClusterState.Type<ClusterType.WithSupportedFeatures<ClusterType.WithSupportedFeatures<ClusterType.WithSupportedFeatures<PowerSource, {
|
|
83
|
+
battery: true;
|
|
84
|
+
rechargeable: true;
|
|
85
|
+
replaceable: false;
|
|
86
|
+
wired: true;
|
|
87
|
+
}>, {
|
|
88
|
+
battery: false;
|
|
89
|
+
rechargeable: false;
|
|
90
|
+
replaceable: false;
|
|
91
|
+
wired: false;
|
|
92
|
+
}>, {
|
|
73
93
|
battery: true;
|
|
74
94
|
rechargeable: false;
|
|
75
95
|
replaceable: false;
|
|
76
96
|
wired: false;
|
|
77
97
|
}>, typeof MatterbridgePowerSourceServer>>;
|
|
78
|
-
export declare function getDefaultPowerSourceReplaceableBatteryClusterServer(batPercentRemaining?: number | null, batChargeLevel?: PowerSource.BatChargeLevel, batVoltage?: number | null, batReplacementDescription?: string, batQuantity?: number, batReplaceability?: PowerSource.BatReplaceability): Partial<import("@matter/node").ClusterState.Type<ClusterType.WithSupportedFeatures<PowerSource, {
|
|
98
|
+
export declare function getDefaultPowerSourceReplaceableBatteryClusterServer(batPercentRemaining?: number | null, batChargeLevel?: PowerSource.BatChargeLevel, batVoltage?: number | null, batReplacementDescription?: string, batQuantity?: number, batReplaceability?: PowerSource.BatReplaceability): Partial<import("@matter/node").ClusterState.Type<ClusterType.WithSupportedFeatures<ClusterType.WithSupportedFeatures<ClusterType.WithSupportedFeatures<PowerSource, {
|
|
99
|
+
battery: true;
|
|
100
|
+
rechargeable: true;
|
|
101
|
+
replaceable: false;
|
|
102
|
+
wired: true;
|
|
103
|
+
}>, {
|
|
104
|
+
battery: false;
|
|
105
|
+
rechargeable: false;
|
|
106
|
+
replaceable: false;
|
|
107
|
+
wired: false;
|
|
108
|
+
}>, {
|
|
79
109
|
battery: true;
|
|
80
110
|
rechargeable: false;
|
|
81
111
|
replaceable: true;
|
|
82
112
|
wired: false;
|
|
83
113
|
}>, typeof MatterbridgePowerSourceServer>>;
|
|
84
|
-
export declare function getDefaultPowerSourceRechargeableBatteryClusterServer(batPercentRemaining?: number | null, batChargeLevel?: PowerSource.BatChargeLevel, batVoltage?: number | null, batReplaceability?: PowerSource.BatReplaceability, batCapacity?: number, batTimeToFullCharge?: number | null, batChargingCurrent?: number | null, activeBatChargeFaults?: PowerSource.BatChargeFault[]): Partial<import("@matter/node").ClusterState.Type<ClusterType.WithSupportedFeatures<PowerSource, {
|
|
114
|
+
export declare function getDefaultPowerSourceRechargeableBatteryClusterServer(batPercentRemaining?: number | null, batChargeLevel?: PowerSource.BatChargeLevel, batVoltage?: number | null, batReplaceability?: PowerSource.BatReplaceability, batCapacity?: number, batTimeToFullCharge?: number | null, batChargingCurrent?: number | null, activeBatChargeFaults?: PowerSource.BatChargeFault[]): Partial<import("@matter/node").ClusterState.Type<ClusterType.WithSupportedFeatures<ClusterType.WithSupportedFeatures<ClusterType.WithSupportedFeatures<PowerSource, {
|
|
115
|
+
battery: true;
|
|
116
|
+
rechargeable: true;
|
|
117
|
+
replaceable: false;
|
|
118
|
+
wired: true;
|
|
119
|
+
}>, {
|
|
120
|
+
battery: false;
|
|
121
|
+
rechargeable: false;
|
|
122
|
+
replaceable: false;
|
|
123
|
+
wired: false;
|
|
124
|
+
}>, {
|
|
85
125
|
battery: true;
|
|
86
126
|
rechargeable: true;
|
|
87
127
|
replaceable: false;
|
|
88
128
|
wired: false;
|
|
89
129
|
}>, typeof MatterbridgePowerSourceServer>>;
|
|
90
|
-
export declare function getDefaultElectricalEnergyMeasurementClusterServer(energyImported?: number | bigint | null, energyExported?: number | bigint | null): Partial<import("@matter/node").ClusterState.Type<ClusterType.WithSupportedFeatures<ElectricalEnergyMeasurement, {
|
|
130
|
+
export declare function getDefaultElectricalEnergyMeasurementClusterServer(energyImported?: number | bigint | null, energyExported?: number | bigint | null): Partial<import("@matter/node").ClusterState.Type<ClusterType.WithSupportedFeatures<ClusterType.WithSupportedFeatures<ClusterType.WithSupportedFeatures<ElectricalEnergyMeasurement, {
|
|
131
|
+
apparentEnergy: false;
|
|
132
|
+
cumulativeEnergy: true;
|
|
133
|
+
exportedEnergy: true;
|
|
134
|
+
importedEnergy: true;
|
|
135
|
+
periodicEnergy: true;
|
|
136
|
+
reactiveEnergy: false;
|
|
137
|
+
}>, {
|
|
138
|
+
apparentEnergy: false;
|
|
139
|
+
cumulativeEnergy: false;
|
|
140
|
+
exportedEnergy: false;
|
|
141
|
+
importedEnergy: false;
|
|
142
|
+
periodicEnergy: false;
|
|
143
|
+
reactiveEnergy: false;
|
|
144
|
+
}>, {
|
|
91
145
|
apparentEnergy: false;
|
|
92
146
|
cumulativeEnergy: true;
|
|
93
147
|
exportedEnergy: true;
|
|
@@ -95,7 +149,21 @@ export declare function getDefaultElectricalEnergyMeasurementClusterServer(energ
|
|
|
95
149
|
periodicEnergy: false;
|
|
96
150
|
reactiveEnergy: false;
|
|
97
151
|
}>, typeof ElectricalEnergyMeasurementServer>>;
|
|
98
|
-
export declare function getImportedElectricalEnergyMeasurementClusterServer(energyImported?: number | bigint | null): Partial<import("@matter/node").ClusterState.Type<ClusterType.WithSupportedFeatures<ElectricalEnergyMeasurement, {
|
|
152
|
+
export declare function getImportedElectricalEnergyMeasurementClusterServer(energyImported?: number | bigint | null): Partial<import("@matter/node").ClusterState.Type<ClusterType.WithSupportedFeatures<ClusterType.WithSupportedFeatures<ClusterType.WithSupportedFeatures<ElectricalEnergyMeasurement, {
|
|
153
|
+
apparentEnergy: false;
|
|
154
|
+
cumulativeEnergy: true;
|
|
155
|
+
exportedEnergy: true;
|
|
156
|
+
importedEnergy: true;
|
|
157
|
+
periodicEnergy: true;
|
|
158
|
+
reactiveEnergy: false;
|
|
159
|
+
}>, {
|
|
160
|
+
apparentEnergy: false;
|
|
161
|
+
cumulativeEnergy: false;
|
|
162
|
+
exportedEnergy: false;
|
|
163
|
+
importedEnergy: false;
|
|
164
|
+
periodicEnergy: false;
|
|
165
|
+
reactiveEnergy: false;
|
|
166
|
+
}>, {
|
|
99
167
|
apparentEnergy: false;
|
|
100
168
|
cumulativeEnergy: true;
|
|
101
169
|
exportedEnergy: false;
|
|
@@ -103,7 +171,21 @@ export declare function getImportedElectricalEnergyMeasurementClusterServer(ener
|
|
|
103
171
|
periodicEnergy: false;
|
|
104
172
|
reactiveEnergy: false;
|
|
105
173
|
}>, typeof ElectricalEnergyMeasurementServer>>;
|
|
106
|
-
export declare function getExportedElectricalEnergyMeasurementClusterServer(energyExported?: number | bigint | null): Partial<import("@matter/node").ClusterState.Type<ClusterType.WithSupportedFeatures<ElectricalEnergyMeasurement, {
|
|
174
|
+
export declare function getExportedElectricalEnergyMeasurementClusterServer(energyExported?: number | bigint | null): Partial<import("@matter/node").ClusterState.Type<ClusterType.WithSupportedFeatures<ClusterType.WithSupportedFeatures<ClusterType.WithSupportedFeatures<ElectricalEnergyMeasurement, {
|
|
175
|
+
apparentEnergy: false;
|
|
176
|
+
cumulativeEnergy: true;
|
|
177
|
+
exportedEnergy: true;
|
|
178
|
+
importedEnergy: true;
|
|
179
|
+
periodicEnergy: true;
|
|
180
|
+
reactiveEnergy: false;
|
|
181
|
+
}>, {
|
|
182
|
+
apparentEnergy: false;
|
|
183
|
+
cumulativeEnergy: false;
|
|
184
|
+
exportedEnergy: false;
|
|
185
|
+
importedEnergy: false;
|
|
186
|
+
periodicEnergy: false;
|
|
187
|
+
reactiveEnergy: false;
|
|
188
|
+
}>, {
|
|
107
189
|
apparentEnergy: false;
|
|
108
190
|
cumulativeEnergy: true;
|
|
109
191
|
exportedEnergy: true;
|
|
@@ -55,6 +55,7 @@ import { ActivatedCarbonFilterMonitoring } from '@matter/types/clusters/activate
|
|
|
55
55
|
import { AirQuality } from '@matter/types/clusters/air-quality';
|
|
56
56
|
import { AmbientContextSensing } from '@matter/types/clusters/ambient-context-sensing';
|
|
57
57
|
import { BasicInformation } from '@matter/types/clusters/basic-information';
|
|
58
|
+
import { Binding } from '@matter/types/clusters/binding';
|
|
58
59
|
import { BooleanState } from '@matter/types/clusters/boolean-state';
|
|
59
60
|
import { BooleanStateConfiguration } from '@matter/types/clusters/boolean-state-configuration';
|
|
60
61
|
import { BridgedDeviceBasicInformation } from '@matter/types/clusters/bridged-device-basic-information';
|
|
@@ -272,6 +273,8 @@ export function getBehaviourTypeFromClusterServerId(clusterId) {
|
|
|
272
273
|
return BasicInformationServer;
|
|
273
274
|
if (clusterId === BridgedDeviceBasicInformation.id)
|
|
274
275
|
return BridgedDeviceBasicInformationServer;
|
|
276
|
+
if (clusterId === Binding.id)
|
|
277
|
+
return MatterbridgeBindingServer;
|
|
275
278
|
if (clusterId === Identify.id)
|
|
276
279
|
return MatterbridgeIdentifyServer;
|
|
277
280
|
if (clusterId === Groups.id)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matterbridge/core",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.11.0-dev-20261021-c0f9ee2",
|
|
4
4
|
"description": "Matterbridge core library",
|
|
5
5
|
"author": "https://github.com/Luligu",
|
|
6
6
|
"homepage": "https://matterbridge.io/",
|
|
@@ -135,11 +135,11 @@
|
|
|
135
135
|
"skipTsconfig": true
|
|
136
136
|
},
|
|
137
137
|
"dependencies": {
|
|
138
|
-
"@matter/main": "0.
|
|
139
|
-
"@matterbridge/dgram": "3.
|
|
140
|
-
"@matterbridge/thread": "3.
|
|
141
|
-
"@matterbridge/types": "3.
|
|
142
|
-
"@matterbridge/utils": "3.
|
|
138
|
+
"@matter/main": "0.18.0",
|
|
139
|
+
"@matterbridge/dgram": "3.11.0-dev-20261021-c0f9ee2",
|
|
140
|
+
"@matterbridge/thread": "3.11.0-dev-20261021-c0f9ee2",
|
|
141
|
+
"@matterbridge/types": "3.11.0-dev-20261021-c0f9ee2",
|
|
142
|
+
"@matterbridge/utils": "3.11.0-dev-20261021-c0f9ee2",
|
|
143
143
|
"escape-html": "1.0.3",
|
|
144
144
|
"express": "5.3.0",
|
|
145
145
|
"express-rate-limit": "8.7.1",
|