@matterbridge/core 3.8.0-dev-20260529-1971f9d → 3.8.0-dev-20260531-fafe993
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/behaviors/bindingServer.d.ts +7 -2
- package/dist/behaviors/bindingServer.js +38 -4
- package/dist/frontend.js +46 -1
- package/dist/matterbridgeEndpoint.d.ts +4 -0
- package/dist/matterbridgeEndpoint.js +17 -1
- package/dist/matterbridgeEndpointHelpers.d.ts +3 -0
- package/dist/matterbridgeEndpointHelpers.js +39 -0
- package/dist/matterbridgePlatform.d.ts +1 -0
- package/dist/matterbridgePlatform.js +4 -0
- package/dist/pluginManager.js +5 -0
- package/package.json +6 -6
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Endpoint } from '@matter/main/node';
|
|
2
|
+
import { BindingBehavior, BindingServer } from '@matter/node/behaviors/binding';
|
|
2
3
|
import { ClusterId } from '@matter/types';
|
|
3
|
-
|
|
4
|
+
import { Binding } from '@matter/types/clusters/binding';
|
|
5
|
+
export declare class MatterbridgeBindingServer extends BindingServer {
|
|
4
6
|
protected internal: MatterbridgeBindingServer.Internal;
|
|
5
7
|
state: MatterbridgeBindingServer.State;
|
|
6
8
|
initialize(): Promise<void>;
|
|
9
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
10
|
+
getEndpoint(clusterId: ClusterId): Endpoint | undefined;
|
|
7
11
|
}
|
|
8
12
|
export declare namespace MatterbridgeBindingServer {
|
|
9
13
|
class Internal {
|
|
10
14
|
bound: boolean;
|
|
15
|
+
boundEndpoints: Map<Binding.Target, Endpoint>;
|
|
11
16
|
}
|
|
12
17
|
class State extends BindingBehavior.State {
|
|
13
18
|
clientList: ClusterId[];
|
|
@@ -1,19 +1,53 @@
|
|
|
1
|
-
import { BindingBehavior } from '@matter/node/behaviors/binding';
|
|
1
|
+
import { BindingBehavior, BindingServer } from '@matter/node/behaviors/binding';
|
|
2
|
+
import { DescriptorServer } from '@matter/node/behaviors/descriptor';
|
|
3
|
+
import { debugStringify, nt } from 'node-ansi-logger';
|
|
2
4
|
import { MatterbridgeServer } from './matterbridgeServer.js';
|
|
3
|
-
export class MatterbridgeBindingServer extends
|
|
5
|
+
export class MatterbridgeBindingServer extends BindingServer {
|
|
4
6
|
async initialize() {
|
|
7
|
+
super.initialize();
|
|
5
8
|
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
6
9
|
device.log.info(`Initializing MatterbridgeBindingServer (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber}) with clientList: ${this.state.clientList.join(', ')}`);
|
|
10
|
+
const clientList = this.state.clientList;
|
|
11
|
+
this.endpoint.construction.onSuccess(async () => {
|
|
12
|
+
const currentClientList = this.endpoint.stateOf(DescriptorServer).clientList;
|
|
13
|
+
const toAddClientList = clientList.filter((id) => !currentClientList.includes(id));
|
|
14
|
+
if (toAddClientList.length > 0) {
|
|
15
|
+
await this.endpoint.setStateOf(DescriptorServer, { clientList: [...currentClientList, ...toAddClientList] });
|
|
16
|
+
device.log.info(`Adding client clusters to endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber}: ${toAddClientList.join(', ')}`);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
7
19
|
this.reactTo(this.events.binding$Changed, (value) => {
|
|
8
20
|
this.internal.bound = value.length > 0;
|
|
9
|
-
device.log.notice(`MatterbridgeBindingServer (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber}) binding changed: ${value}, bound: ${this.internal.bound}`);
|
|
21
|
+
device.log.notice(`MatterbridgeBindingServer (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber}) binding changed: ${debugStringify(value)}${nt}, bound: ${this.internal.bound}`);
|
|
22
|
+
});
|
|
23
|
+
this.reactTo(this.events.established, async (resolution) => {
|
|
24
|
+
device.log.notice(`MatterbridgeBindingServer (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber}) binding established: kind ${resolution.kind} entry ${debugStringify(resolution.entry)}${nt}`);
|
|
25
|
+
this.internal.boundEndpoints.set(resolution.entry, resolution.endpoint);
|
|
26
|
+
if (resolution.kind !== 'client')
|
|
27
|
+
return;
|
|
28
|
+
await resolution.node.set({ network: { autoSubscribe: true } });
|
|
29
|
+
});
|
|
30
|
+
this.reactTo(this.events.removed, async (resolution) => {
|
|
31
|
+
device.log.notice(`MatterbridgeBindingServer (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber}) binding removed: kind ${resolution.kind} entry ${debugStringify(resolution.entry)}${nt}`);
|
|
32
|
+
this.internal.boundEndpoints.delete(resolution.entry);
|
|
10
33
|
});
|
|
11
|
-
|
|
34
|
+
}
|
|
35
|
+
async [Symbol.asyncDispose]() {
|
|
36
|
+
this.internal.boundEndpoints.clear();
|
|
37
|
+
await super[Symbol.asyncDispose]();
|
|
38
|
+
}
|
|
39
|
+
getEndpoint(clusterId) {
|
|
40
|
+
for (const [target, endpoint] of this.internal.boundEndpoints) {
|
|
41
|
+
if (target.cluster === clusterId)
|
|
42
|
+
return endpoint;
|
|
43
|
+
}
|
|
44
|
+
return undefined;
|
|
12
45
|
}
|
|
13
46
|
}
|
|
14
47
|
(function (MatterbridgeBindingServer) {
|
|
15
48
|
class Internal {
|
|
16
49
|
bound = false;
|
|
50
|
+
boundEndpoints = new Map();
|
|
17
51
|
}
|
|
18
52
|
MatterbridgeBindingServer.Internal = Internal;
|
|
19
53
|
class State extends BindingBehavior.State {
|
package/dist/frontend.js
CHANGED
|
@@ -14,10 +14,11 @@ import { inspectError } from '@matterbridge/utils/error';
|
|
|
14
14
|
import { formatBytes, formatPercent, formatUptime } from '@matterbridge/utils/format';
|
|
15
15
|
import { isValidArray, isValidBoolean, isValidNumber, isValidObject, isValidString } from '@matterbridge/utils/validate';
|
|
16
16
|
import { fireAndForget, wait, withTimeout } from '@matterbridge/utils/wait';
|
|
17
|
-
import { AnsiLogger, CYAN, db, debugStringify, er, nf, nt, rs, stringify, UNDERLINE, UNDERLINEOFF, YELLOW } from 'node-ansi-logger';
|
|
17
|
+
import { AnsiLogger, bgHex, CYAN, db, debugStringify, er, GREEN, nf, nt, rs, stringify, UNDERLINE, UNDERLINEOFF, wr, YELLOW } from 'node-ansi-logger';
|
|
18
18
|
import { cliEmitter, lastOsCpuUsage, lastProcessCpuUsage } from './cliEmitter.js';
|
|
19
19
|
import { generateHistoryPage } from './cliHistory.js';
|
|
20
20
|
import { capitalizeFirstLetter, getAttribute } from './matterbridgeEndpointHelpers.js';
|
|
21
|
+
import { logError } from './utils/export.js';
|
|
21
22
|
if (hasParameter('loader'))
|
|
22
23
|
console.log('\u001B[32mFrontend loaded.\u001B[40;0m');
|
|
23
24
|
export class Frontend extends EventEmitter {
|
|
@@ -801,6 +802,50 @@ export class Frontend extends EventEmitter {
|
|
|
801
802
|
res.status(500).send(`Error uploading or installing plugin package ${filename}`);
|
|
802
803
|
}
|
|
803
804
|
});
|
|
805
|
+
for (const plugin of this.matterbridge.plugins.array().filter((p) => p.enabled && !p.error)) {
|
|
806
|
+
const { existsSync } = await import('node:fs');
|
|
807
|
+
if (plugin.frontendPath && existsSync(plugin.frontendPath)) {
|
|
808
|
+
this.log.debug(`Registering frontend route for plugin ${plg}${plugin.name}${db} at ${GREEN}/plugins/${plugin.name}${db} with path ${CYAN}${plugin.frontendPath}${db}`);
|
|
809
|
+
this.expressApp.use(`/plugins/${plugin.name}`, express.static(path.dirname(plugin.frontendPath)));
|
|
810
|
+
const apiHandler = async (req, res) => {
|
|
811
|
+
const method = req.method.toUpperCase();
|
|
812
|
+
const path = Array.isArray(req.params.path) ? req.params.path[0] : req.params.path;
|
|
813
|
+
const query = req.query;
|
|
814
|
+
const body = req.body;
|
|
815
|
+
this.log.debug(`The frontend sent ${bgHex('#0ba7bc').bold.white ` ${method} `} ${bgHex('#0b6a2b').bold.italic.white ` /plugins/${plugin.name}/api/${path ?? ''} `}`);
|
|
816
|
+
if (!plugin.platform) {
|
|
817
|
+
this.log.error(`The platform for plugin ${plg}${plugin.name}${er} is not running`);
|
|
818
|
+
res.status(503).json({ error: `Plugin ${plugin.name} platform is not running` });
|
|
819
|
+
return;
|
|
820
|
+
}
|
|
821
|
+
try {
|
|
822
|
+
const value = await plugin.platform.onFetch(method, path, query, body);
|
|
823
|
+
if (value === undefined) {
|
|
824
|
+
this.log.warn(`MatterbridgePlatform.onFetch returned undefined for plugin ${plg}${plugin.name}${wr} method ${method} path ${path}`);
|
|
825
|
+
res.status(404).json({ error: `Not found in plugin ${plugin.name}` });
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
828
|
+
if (method === 'DELETE')
|
|
829
|
+
res.status(204).send();
|
|
830
|
+
else
|
|
831
|
+
res.json(value);
|
|
832
|
+
}
|
|
833
|
+
catch (error) {
|
|
834
|
+
logError(this.log, `MatterbridgePlatform.onFetch threw an error for plugin ${plg}${plugin.name}${er}`, error);
|
|
835
|
+
res.status(500).json({ error: `Internal error in plugin ${plugin.name}` });
|
|
836
|
+
}
|
|
837
|
+
};
|
|
838
|
+
this.expressApp.get(`/plugins/${plugin.name}/api/:path`, apiHandler);
|
|
839
|
+
this.expressApp.post(`/plugins/${plugin.name}/api/:path`, apiHandler);
|
|
840
|
+
this.expressApp.put(`/plugins/${plugin.name}/api/:path`, apiHandler);
|
|
841
|
+
this.expressApp.patch(`/plugins/${plugin.name}/api/:path`, apiHandler);
|
|
842
|
+
this.expressApp.delete(`/plugins/${plugin.name}/api/:path`, apiHandler);
|
|
843
|
+
this.expressApp.get(`/plugins/${plugin.name}/{*splat}`, (_req, res) => {
|
|
844
|
+
this.log.warn(`The plugin frontend sent /plugins/${plugin.name}/index.html (plugin SPA fallback)`);
|
|
845
|
+
res.sendFile('index.html', { root: path.dirname(plugin.frontendPath) });
|
|
846
|
+
});
|
|
847
|
+
}
|
|
848
|
+
}
|
|
804
849
|
this.expressApp.use((req, res) => {
|
|
805
850
|
const filePath = path.resolve(this.matterbridge.rootDirectory, 'apps', 'frontend', 'build');
|
|
806
851
|
this.log.debug(`The frontend sent ${req.url} method ${req.method}: sending index.html in ${filePath} as fallback`);
|
|
@@ -119,6 +119,9 @@ export declare class MatterbridgeEndpoint extends Endpoint {
|
|
|
119
119
|
invokeBehaviorCommand(cluster: ClusterId | string, command: CommandHandlers, params?: Record<string, boolean | number | bigint | string | object | null>): Promise<void>;
|
|
120
120
|
addRequiredClusterServers(): MatterbridgeEndpoint;
|
|
121
121
|
addOptionalClusterServers(): MatterbridgeEndpoint;
|
|
122
|
+
addRequiredClusterClients(): MatterbridgeEndpoint;
|
|
123
|
+
addOptionalClusterClients(): MatterbridgeEndpoint;
|
|
124
|
+
addClusterClients(clientList: ClusterId[]): MatterbridgeEndpoint;
|
|
122
125
|
getAllClusterServers(): Behavior.Type[];
|
|
123
126
|
getAllClusterServerNames(): string[];
|
|
124
127
|
forEachAttribute(callback: (clusterName: string, clusterId: number, attributeName: string, attributeId: number, attributeValue: boolean | number | bigint | string | object | null | undefined) => void): void;
|
|
@@ -143,6 +146,7 @@ export declare class MatterbridgeEndpoint extends Endpoint {
|
|
|
143
146
|
createApparentElectricalPowerMeasurementClusterServer(voltage?: number | bigint | null, apparentCurrent?: number | bigint | null, apparentPower?: number | bigint | null, frequency?: number | bigint | null): this;
|
|
144
147
|
createDefaultDeviceEnergyManagementClusterServer(esaType?: DeviceEnergyManagement.EsaType, esaCanGenerate?: boolean, esaState?: DeviceEnergyManagement.EsaState, absMinPower?: number, absMaxPower?: number): this;
|
|
145
148
|
createDefaultDeviceEnergyManagementModeClusterServer(currentMode?: number, supportedModes?: DeviceEnergyManagementMode.ModeOption[]): this;
|
|
149
|
+
createDefaultBindingClusterServer(clientList?: ClusterId[]): this;
|
|
146
150
|
createDefaultIdentifyClusterServer(identifyTime?: number, identifyType?: Identify.IdentifyType): this;
|
|
147
151
|
createDefaultGroupsClusterServer(): this;
|
|
148
152
|
createDefaultScenesManagementClusterServer(): this;
|
|
@@ -83,7 +83,7 @@ import { MatterbridgeThermostatServer } from './behaviors/thermostatServer.js';
|
|
|
83
83
|
import { MatterbridgeValveConfigurationAndControlServer } from './behaviors/valveConfigurationAndControlServer.js';
|
|
84
84
|
import { MatterbridgeWindowCoveringServer } from './behaviors/windowCoveringServer.js';
|
|
85
85
|
import { CommandHandler } from './matterbridgeEndpointCommandHandler.js';
|
|
86
|
-
import { addClusterServers, addFixedLabel, addOptionalClusterServers, addRequiredClusterServers, addUserLabel, checkNotLatinCharacters, createUniqueId, defaultFor, featuresFor, generateUniqueId, getApparentElectricalPowerMeasurementClusterServer, getAttribute, getAttributeId, getBehavior, getBehaviourTypesFromClusterClientIds, getBehaviourTypesFromClusterServerIds, getCluster, getClusterId, getDefaultDeviceEnergyManagementClusterServer, getDefaultDeviceEnergyManagementModeClusterServer, getDefaultElectricalEnergyMeasurementClusterServer, getDefaultElectricalPowerMeasurementClusterServer, getDefaultFlowMeasurementClusterServer, getDefaultIlluminanceMeasurementClusterServer, getDefaultOccupancySensingClusterServer, getDefaultOperationalStateClusterServer, getDefaultPowerSourceBatteryClusterServer, getDefaultPowerSourceRechargeableBatteryClusterServer, getDefaultPowerSourceReplaceableBatteryClusterServer, getDefaultPowerSourceWiredClusterServer, getDefaultPressureMeasurementClusterServer, getDefaultRelativeHumidityMeasurementClusterServer, getDefaultTemperatureMeasurementClusterServer, invokeBehaviorCommand, lowercaseFirstLetter, setAttribute, setCluster, subscribeAttribute, triggerEvent, updateAttribute, } from './matterbridgeEndpointHelpers.js';
|
|
86
|
+
import { addClusterClients, addClusterServers, addFixedLabel, addOptionalClusterClients, addOptionalClusterServers, addRequiredClusterClients, addRequiredClusterServers, addUserLabel, checkNotLatinCharacters, createUniqueId, defaultFor, featuresFor, generateUniqueId, getApparentElectricalPowerMeasurementClusterServer, getAttribute, getAttributeId, getBehavior, getBehaviourTypesFromClusterClientIds, getBehaviourTypesFromClusterServerIds, getCluster, getClusterId, getDefaultDeviceEnergyManagementClusterServer, getDefaultDeviceEnergyManagementModeClusterServer, getDefaultElectricalEnergyMeasurementClusterServer, getDefaultElectricalPowerMeasurementClusterServer, getDefaultFlowMeasurementClusterServer, getDefaultIlluminanceMeasurementClusterServer, getDefaultOccupancySensingClusterServer, getDefaultOperationalStateClusterServer, getDefaultPowerSourceBatteryClusterServer, getDefaultPowerSourceRechargeableBatteryClusterServer, getDefaultPowerSourceReplaceableBatteryClusterServer, getDefaultPowerSourceWiredClusterServer, getDefaultPressureMeasurementClusterServer, getDefaultRelativeHumidityMeasurementClusterServer, getDefaultTemperatureMeasurementClusterServer, invokeBehaviorCommand, lowercaseFirstLetter, setAttribute, setCluster, subscribeAttribute, triggerEvent, updateAttribute, } from './matterbridgeEndpointHelpers.js';
|
|
87
87
|
const MATTERBRIDGE_ENDPOINT_BRAND = Symbol('MatterbridgeEndpoint.brand');
|
|
88
88
|
export function isMatterbridgeEndpoint(value) {
|
|
89
89
|
if (!value || typeof value !== 'object')
|
|
@@ -276,6 +276,18 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
276
276
|
addOptionalClusterServers(this);
|
|
277
277
|
return this;
|
|
278
278
|
}
|
|
279
|
+
addRequiredClusterClients() {
|
|
280
|
+
addRequiredClusterClients(this);
|
|
281
|
+
return this;
|
|
282
|
+
}
|
|
283
|
+
addOptionalClusterClients() {
|
|
284
|
+
addOptionalClusterClients(this);
|
|
285
|
+
return this;
|
|
286
|
+
}
|
|
287
|
+
addClusterClients(clientList) {
|
|
288
|
+
addClusterClients(this, clientList);
|
|
289
|
+
return this;
|
|
290
|
+
}
|
|
279
291
|
getAllClusterServers() {
|
|
280
292
|
return Object.values(this.behaviors.supported);
|
|
281
293
|
}
|
|
@@ -560,6 +572,10 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
560
572
|
this.behaviors.require(MatterbridgeDeviceEnergyManagementModeServer, getDefaultDeviceEnergyManagementModeClusterServer(currentMode, supportedModes));
|
|
561
573
|
return this;
|
|
562
574
|
}
|
|
575
|
+
createDefaultBindingClusterServer(clientList = []) {
|
|
576
|
+
addClusterClients(this, clientList);
|
|
577
|
+
return this;
|
|
578
|
+
}
|
|
563
579
|
createDefaultIdentifyClusterServer(identifyTime = 0, identifyType = Identify.IdentifyType.None) {
|
|
564
580
|
this.behaviors.require(MatterbridgeIdentifyServer, {
|
|
565
581
|
identifyTime,
|
|
@@ -46,6 +46,9 @@ export declare function invokeSubscribeHandler(endpoint: MatterbridgeEndpoint, c
|
|
|
46
46
|
export declare function addRequiredClusterServers(endpoint: MatterbridgeEndpoint): void;
|
|
47
47
|
export declare function addOptionalClusterServers(endpoint: MatterbridgeEndpoint): void;
|
|
48
48
|
export declare function addClusterServers(endpoint: MatterbridgeEndpoint, serverList: ClusterId[]): void;
|
|
49
|
+
export declare function addClusterClients(endpoint: MatterbridgeEndpoint, clientList: ClusterId[]): void;
|
|
50
|
+
export declare function addRequiredClusterClients(endpoint: MatterbridgeEndpoint): void;
|
|
51
|
+
export declare function addOptionalClusterClients(endpoint: MatterbridgeEndpoint): void;
|
|
49
52
|
export declare function addFixedLabel(endpoint: MatterbridgeEndpoint, label: string, value: string): Promise<void>;
|
|
50
53
|
export declare function addUserLabel(endpoint: MatterbridgeEndpoint, label: string, value: string): Promise<void>;
|
|
51
54
|
export declare function getClusterId(endpoint: Endpoint, cluster: string): number | undefined;
|
|
@@ -84,6 +84,7 @@ import { MeasurementType } from '@matter/types/globals';
|
|
|
84
84
|
import { deepEqual } from '@matterbridge/utils/deep-equal';
|
|
85
85
|
import { isValidArray } from '@matterbridge/utils/validate';
|
|
86
86
|
import { BLUE, CYAN, db, debugStringify, er, hk, or, YELLOW, zb } from 'node-ansi-logger';
|
|
87
|
+
import { MatterbridgeBindingServer } from './behaviors/bindingServer.js';
|
|
87
88
|
import { MatterbridgeBooleanStateConfigurationServer } from './behaviors/booleanStateConfigurationServer.js';
|
|
88
89
|
import { MatterbridgeColorControlServer } from './behaviors/colorControlServer.js';
|
|
89
90
|
import { MatterbridgeDeviceEnergyManagementModeServer } from './behaviors/deviceEnergyManagementModeServer.js';
|
|
@@ -491,6 +492,44 @@ export function addClusterServers(endpoint, serverList) {
|
|
|
491
492
|
if (serverList.includes(DeviceEnergyManagementMode.Cluster.id))
|
|
492
493
|
endpoint.createDefaultDeviceEnergyManagementModeClusterServer();
|
|
493
494
|
}
|
|
495
|
+
export function addClusterClients(endpoint, clientList) {
|
|
496
|
+
if (clientList.length === 0)
|
|
497
|
+
return;
|
|
498
|
+
if (!endpoint.behaviors.has(MatterbridgeBindingServer)) {
|
|
499
|
+
endpoint.behaviors.require(MatterbridgeBindingServer, { clientList });
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
const existing = endpoint.behaviors.optionsFor(MatterbridgeBindingServer)?.clientList ?? [];
|
|
503
|
+
endpoint.behaviors.inject(MatterbridgeBindingServer, { clientList: [...new Set([...existing, ...clientList])] });
|
|
504
|
+
}
|
|
505
|
+
export function addRequiredClusterClients(endpoint) {
|
|
506
|
+
const requiredClientList = [];
|
|
507
|
+
endpoint.log.debug(`addRequiredClusterClients for ${CYAN}${endpoint.maybeId}${db}`);
|
|
508
|
+
Array.from(endpoint.deviceTypes.values()).forEach((deviceType) => {
|
|
509
|
+
endpoint.log.debug(`- for deviceType: ${zb}${'0x' + deviceType.code.toString(16).padStart(4, '0')}${db}-${zb}${deviceType.name}${db}`);
|
|
510
|
+
deviceType.requiredClientClusters.forEach((clusterId) => {
|
|
511
|
+
if (!requiredClientList.includes(clusterId)) {
|
|
512
|
+
requiredClientList.push(clusterId);
|
|
513
|
+
endpoint.log.debug(`- cluster: ${hk}${'0x' + clusterId.toString(16).padStart(4, '0')}${db}-${hk}${getClusterNameById(clusterId)}${db}`);
|
|
514
|
+
}
|
|
515
|
+
});
|
|
516
|
+
});
|
|
517
|
+
addClusterClients(endpoint, requiredClientList);
|
|
518
|
+
}
|
|
519
|
+
export function addOptionalClusterClients(endpoint) {
|
|
520
|
+
const optionalClientList = [];
|
|
521
|
+
endpoint.log.debug(`addOptionalClusterClients for ${CYAN}${endpoint.maybeId}${db}`);
|
|
522
|
+
Array.from(endpoint.deviceTypes.values()).forEach((deviceType) => {
|
|
523
|
+
endpoint.log.debug(`- for deviceType: ${zb}${'0x' + deviceType.code.toString(16).padStart(4, '0')}${db}-${zb}${deviceType.name}${db}`);
|
|
524
|
+
deviceType.optionalClientClusters.forEach((clusterId) => {
|
|
525
|
+
if (!optionalClientList.includes(clusterId)) {
|
|
526
|
+
optionalClientList.push(clusterId);
|
|
527
|
+
endpoint.log.debug(`- cluster: ${hk}${'0x' + clusterId.toString(16).padStart(4, '0')}${db}-${hk}${getClusterNameById(clusterId)}${db}`);
|
|
528
|
+
}
|
|
529
|
+
});
|
|
530
|
+
});
|
|
531
|
+
addClusterClients(endpoint, optionalClientList);
|
|
532
|
+
}
|
|
494
533
|
export async function addFixedLabel(endpoint, label, value) {
|
|
495
534
|
if (!endpoint.hasClusterServer(FixedLabel.Cluster.id)) {
|
|
496
535
|
endpoint.log.debug(`addFixedLabel: add cluster ${hk}FixedLabel${db}:${hk}fixedLabel${db} with label ${CYAN}${label}${db} value ${CYAN}${value}${db}`);
|
|
@@ -29,6 +29,7 @@ export declare class MatterbridgePlatform {
|
|
|
29
29
|
onShutdown(reason?: string): Promise<void>;
|
|
30
30
|
onChangeLoggerLevel(logLevel: LogLevel): Promise<void>;
|
|
31
31
|
onAction(action: string, value?: string, id?: string, formData?: PlatformConfig): Promise<void>;
|
|
32
|
+
onFetch(method: string, path?: string, query?: Record<string, unknown>, body?: unknown): Promise<unknown>;
|
|
32
33
|
onConfigChanged(config: PlatformConfig): Promise<void>;
|
|
33
34
|
saveConfig(config: PlatformConfig): void;
|
|
34
35
|
getSchema(): Promise<PlatformSchema | undefined>;
|
|
@@ -156,6 +156,10 @@ export class MatterbridgePlatform {
|
|
|
156
156
|
async onAction(action, value, id, formData) {
|
|
157
157
|
this.log.debug(`The plugin ${CYAN}${this.name}${db} doesn't override onAction. Received action ${CYAN}${action}${db}${value ? ' with ' + CYAN + value + db : ''} ${id ? ' for schema ' + CYAN + id + db : ''}`, formData);
|
|
158
158
|
}
|
|
159
|
+
async onFetch(method, path, query, body) {
|
|
160
|
+
this.log.debug(`onFetch called: method=${method} path=${path ?? 'none'} query=${query ? JSON.stringify(query) : 'none'} body=${body ? JSON.stringify(body) : 'none'}`);
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
159
163
|
async onConfigChanged(config) {
|
|
160
164
|
this.log.debug(`The plugin ${CYAN}${config.name}${db} doesn't override onConfigChanged. Received new config.`);
|
|
161
165
|
}
|
package/dist/pluginManager.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
if (process.argv.includes('--loader') || process.argv.includes('-loader'))
|
|
2
2
|
console.log('\u001B[32mPlugin Manager loaded.\u001B[40;0m');
|
|
3
3
|
import EventEmitter from 'node:events';
|
|
4
|
+
import path from 'node:path';
|
|
4
5
|
import { BroadcastServer } from '@matterbridge/thread/server';
|
|
5
6
|
import { plg, typ } from '@matterbridge/types';
|
|
6
7
|
import { hasParameter } from '@matterbridge/utils/cli';
|
|
@@ -657,6 +658,10 @@ export class PluginManager extends EventEmitter {
|
|
|
657
658
|
plugin.funding = this.getFunding(packageJson);
|
|
658
659
|
if (!plugin.type)
|
|
659
660
|
this.log.warn(`Plugin ${plg}${plugin.name}${wr} has no type`);
|
|
661
|
+
const frontendPath = path.join(plugin.path.replace('package.json', ''), 'apps', 'frontend', 'build', 'index.html');
|
|
662
|
+
const { existsSync } = await import('node:fs');
|
|
663
|
+
if (existsSync(frontendPath))
|
|
664
|
+
plugin.frontendPath = frontendPath;
|
|
660
665
|
const invalidDependencies = this.findInvalidDependencies(packageJson);
|
|
661
666
|
if (invalidDependencies) {
|
|
662
667
|
this.logInvalidDependencies(packageJson, invalidDependencies, plugin.name);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matterbridge/core",
|
|
3
|
-
"version": "3.8.0-dev-
|
|
3
|
+
"version": "3.8.0-dev-20260531-fafe993",
|
|
4
4
|
"description": "Matterbridge core library",
|
|
5
5
|
"author": "https://github.com/Luligu",
|
|
6
6
|
"homepage": "https://matterbridge.io/",
|
|
@@ -130,16 +130,16 @@
|
|
|
130
130
|
],
|
|
131
131
|
"dependencies": {
|
|
132
132
|
"@matter/main": "0.17.0",
|
|
133
|
-
"@matterbridge/dgram": "3.8.0-dev-
|
|
134
|
-
"@matterbridge/thread": "3.8.0-dev-
|
|
135
|
-
"@matterbridge/types": "3.8.0-dev-
|
|
136
|
-
"@matterbridge/utils": "3.8.0-dev-
|
|
133
|
+
"@matterbridge/dgram": "3.8.0-dev-20260531-fafe993",
|
|
134
|
+
"@matterbridge/thread": "3.8.0-dev-20260531-fafe993",
|
|
135
|
+
"@matterbridge/types": "3.8.0-dev-20260531-fafe993",
|
|
136
|
+
"@matterbridge/utils": "3.8.0-dev-20260531-fafe993",
|
|
137
137
|
"escape-html": "1.0.3",
|
|
138
138
|
"express": "5.2.1",
|
|
139
139
|
"express-rate-limit": "8.5.2",
|
|
140
140
|
"multer": "2.1.1",
|
|
141
141
|
"node-ansi-logger": "3.3.0-dev-20260524-cac9dd5",
|
|
142
142
|
"node-persist-manager": "2.1.0-dev-20260524-6a6019a",
|
|
143
|
-
"ws": "8.
|
|
143
|
+
"ws": "8.21.0"
|
|
144
144
|
}
|
|
145
145
|
}
|