matterbridge 3.4.1-dev-20251128-441f8db → 3.4.1-dev-20251130-f066d82
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -3
- package/dist/broadcastServer.js +73 -20
- package/dist/deviceManager.js +12 -11
- package/dist/frontend.js +23 -28
- package/dist/jestutils/jestHelpers.js +2 -0
- package/dist/matterNode.js +9 -5
- package/dist/matterbridge.js +15 -29
- package/dist/matterbridgePlatform.js +1 -1
- package/dist/pluginManager.js +49 -48
- package/dist/shelly.js +2 -2
- package/dist/update.js +1 -1
- package/dist/utils/error.js +3 -1
- package/dist/workerGlobalPrefix.js +39 -0
- package/dist/workerTypes.js +1 -0
- package/dist/workers.js +35 -0
- package/frontend/build/assets/index.js +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/scripts/fetch-chip.mjs +14 -12
- package/dist/defaultConfigSchema.js +0 -61
package/CHANGELOG.md
CHANGED
|
@@ -14,8 +14,9 @@ The project will evolve to a multi-threaded architecture (the CLI will become th
|
|
|
14
14
|
- frontend;
|
|
15
15
|
- plugins;
|
|
16
16
|
- devices;
|
|
17
|
-
-
|
|
18
|
-
-
|
|
17
|
+
- check updates;
|
|
18
|
+
- npm install;
|
|
19
|
+
- ✅ get global node_modules;
|
|
19
20
|
- all plugins in bridge mode;
|
|
20
21
|
- each plugin in childbridge mode;
|
|
21
22
|
|
|
@@ -31,7 +32,10 @@ Advantages:
|
|
|
31
32
|
### Added
|
|
32
33
|
|
|
33
34
|
- [matterbridge.io]: Updated website https://matterbridge.io with all guides.
|
|
34
|
-
- [matterbridge]: Added addVirtualEndpoint() to match thread module.
|
|
35
|
+
- [matterbridge]: Added addVirtualEndpoint() to match Matterbridge thread module.
|
|
36
|
+
- [BroadcastServer]: Backport BroadcastServer v.2.0.0 from Matterbridge thread module.
|
|
37
|
+
- [MatterbridgePrefix]: Added worker thread to get global node_modules.
|
|
38
|
+
- [PluginManager]: Improved the resolve method to resolve automatically also in the plugin directory Usefull for developing with DevContainer.
|
|
35
39
|
|
|
36
40
|
### Changed
|
|
37
41
|
|
package/dist/broadcastServer.js
CHANGED
|
@@ -25,24 +25,64 @@ export class BroadcastServer extends EventEmitter {
|
|
|
25
25
|
this.broadcastChannel.close();
|
|
26
26
|
}
|
|
27
27
|
getUniqueId() {
|
|
28
|
-
return Math.floor(Math.random() *
|
|
28
|
+
return Math.floor(Math.random() * 900000000) + 100000000;
|
|
29
29
|
}
|
|
30
|
-
isWorkerRequest(
|
|
31
|
-
|
|
30
|
+
isWorkerRequest(value) {
|
|
31
|
+
if (typeof value !== 'object' || value === null) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
const message = value;
|
|
35
|
+
if (typeof message.type !== 'string' || typeof message.src !== 'string' || typeof message.dst !== 'string' || typeof message.id !== 'number' || typeof message.timestamp !== 'number') {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
return message.result === undefined && message.error === undefined;
|
|
39
|
+
}
|
|
40
|
+
isWorkerRequestOfType(value, type) {
|
|
41
|
+
return this.isWorkerRequest(value) && value.type === type;
|
|
42
|
+
}
|
|
43
|
+
isWorkerResponse(value) {
|
|
44
|
+
if (typeof value !== 'object' || value === null) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
const message = value;
|
|
48
|
+
if (typeof message.type !== 'string' || typeof message.src !== 'string' || typeof message.dst !== 'string' || typeof message.id !== 'number' || typeof message.timestamp !== 'number') {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
const hasError = typeof message.error === 'string';
|
|
52
|
+
const hasResult = message.result !== undefined;
|
|
53
|
+
return hasError !== hasResult;
|
|
32
54
|
}
|
|
33
|
-
|
|
34
|
-
return
|
|
55
|
+
isWorkerResponseOfType(value, type) {
|
|
56
|
+
return this.isWorkerResponse(value) && value.type === type;
|
|
35
57
|
}
|
|
36
58
|
broadcastMessageHandler(event) {
|
|
37
|
-
const
|
|
38
|
-
if (
|
|
39
|
-
|
|
40
|
-
|
|
59
|
+
const msg = event.data;
|
|
60
|
+
if (msg.dst === this.name || msg.dst === 'all') {
|
|
61
|
+
if (this.verbose)
|
|
62
|
+
this.log.debug(`Server ${CYAN}${this.name}${db} received broadcast message: ${debugStringify(msg)}`);
|
|
63
|
+
this.emit('broadcast_message', msg);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
if (this.verbose)
|
|
67
|
+
this.log.debug(`Server ${CYAN}${this.name}${db} received unrelated broadcast message: ${debugStringify(msg)}`);
|
|
68
|
+
}
|
|
41
69
|
}
|
|
42
70
|
broadcast(message) {
|
|
71
|
+
if (message.id === undefined) {
|
|
72
|
+
message.id = this.getUniqueId();
|
|
73
|
+
}
|
|
74
|
+
if (message.timestamp === undefined) {
|
|
75
|
+
message.timestamp = Date.now();
|
|
76
|
+
}
|
|
77
|
+
message.src = this.name;
|
|
43
78
|
if (this.verbose)
|
|
44
79
|
this.log.debug(`Broadcasting message: ${debugStringify(message)}`);
|
|
45
|
-
|
|
80
|
+
try {
|
|
81
|
+
this.broadcastChannel.postMessage(message);
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
logError(this.log, `Failed to broadcast message ${debugStringify(message)}${er}`, error);
|
|
85
|
+
}
|
|
46
86
|
}
|
|
47
87
|
request(message) {
|
|
48
88
|
if (message.id === undefined) {
|
|
@@ -51,8 +91,9 @@ export class BroadcastServer extends EventEmitter {
|
|
|
51
91
|
if (message.timestamp === undefined) {
|
|
52
92
|
message.timestamp = Date.now();
|
|
53
93
|
}
|
|
54
|
-
|
|
55
|
-
|
|
94
|
+
message.src = this.name;
|
|
95
|
+
if (!this.isWorkerRequest(message)) {
|
|
96
|
+
this.log.error(`Invalid request message format: ${debugStringify(message)}`);
|
|
56
97
|
return;
|
|
57
98
|
}
|
|
58
99
|
if (this.verbose)
|
|
@@ -65,11 +106,18 @@ export class BroadcastServer extends EventEmitter {
|
|
|
65
106
|
}
|
|
66
107
|
}
|
|
67
108
|
respond(message) {
|
|
109
|
+
if (typeof message.timestamp === 'number') {
|
|
110
|
+
message.elapsed = Date.now() - message.timestamp;
|
|
111
|
+
}
|
|
68
112
|
if (message.timestamp === undefined) {
|
|
69
113
|
message.timestamp = Date.now();
|
|
70
114
|
}
|
|
71
|
-
if (
|
|
72
|
-
|
|
115
|
+
if (message.dst === this.name || message.dst === 'all') {
|
|
116
|
+
message.dst = message.src;
|
|
117
|
+
}
|
|
118
|
+
message.src = this.name;
|
|
119
|
+
if (!this.isWorkerResponse(message)) {
|
|
120
|
+
this.log.error(`Invalid response message format: ${debugStringify(message)}`);
|
|
73
121
|
return;
|
|
74
122
|
}
|
|
75
123
|
if (this.verbose)
|
|
@@ -92,16 +140,21 @@ export class BroadcastServer extends EventEmitter {
|
|
|
92
140
|
this.log.debug(`Fetching message: ${debugStringify(message)}`);
|
|
93
141
|
return new Promise((resolve, reject) => {
|
|
94
142
|
const responseHandler = (msg) => {
|
|
95
|
-
if (this.
|
|
143
|
+
if (this.isWorkerResponseOfType(msg, message.type) && msg.id === message.id) {
|
|
96
144
|
clearTimeout(timeoutId);
|
|
97
145
|
this.off('broadcast_message', responseHandler);
|
|
98
146
|
if (this.verbose)
|
|
99
147
|
this.log.debug(`Fetch response: ${debugStringify(msg)}`);
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
if (
|
|
104
|
-
|
|
148
|
+
if ('error' in msg && typeof msg.error === 'string') {
|
|
149
|
+
reject(new Error(`Fetch received error response ${msg.error} to message type ${message.type} id ${message.id} from ${message.src} to ${message.dst}`));
|
|
150
|
+
}
|
|
151
|
+
else if ('result' in msg) {
|
|
152
|
+
resolve(msg);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
reject(new Error(`Fetch received malformed response for message type ${message.type} id ${message.id} from ${message.src} to ${message.dst}`));
|
|
156
|
+
}
|
|
157
|
+
return;
|
|
105
158
|
}
|
|
106
159
|
};
|
|
107
160
|
this.on('broadcast_message', responseHandler);
|
package/dist/deviceManager.js
CHANGED
|
@@ -41,47 +41,48 @@ export class DeviceManager {
|
|
|
41
41
|
this.log.debug('Matterbridge device manager started');
|
|
42
42
|
}
|
|
43
43
|
destroy() {
|
|
44
|
+
this.server.off('broadcast_message', this.msgHandler.bind(this));
|
|
44
45
|
this.server.close();
|
|
45
46
|
}
|
|
46
47
|
async msgHandler(msg) {
|
|
47
|
-
if (this.server.isWorkerRequest(msg
|
|
48
|
+
if (this.server.isWorkerRequest(msg)) {
|
|
48
49
|
if (this.verbose)
|
|
49
50
|
this.log.debug(`Received request message ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
|
|
50
51
|
switch (msg.type) {
|
|
51
52
|
case 'get_log_level':
|
|
52
|
-
this.server.respond({ ...msg,
|
|
53
|
+
this.server.respond({ ...msg, result: { logLevel: this.log.logLevel } });
|
|
53
54
|
break;
|
|
54
55
|
case 'set_log_level':
|
|
55
56
|
this.log.logLevel = msg.params.logLevel;
|
|
56
|
-
this.server.respond({ ...msg,
|
|
57
|
+
this.server.respond({ ...msg, result: { logLevel: this.log.logLevel } });
|
|
57
58
|
break;
|
|
58
59
|
case 'devices_length':
|
|
59
|
-
this.server.respond({ ...msg,
|
|
60
|
+
this.server.respond({ ...msg, result: { length: this.length } });
|
|
60
61
|
break;
|
|
61
62
|
case 'devices_size':
|
|
62
|
-
this.server.respond({ ...msg,
|
|
63
|
+
this.server.respond({ ...msg, result: { size: this.size } });
|
|
63
64
|
break;
|
|
64
65
|
case 'devices_has':
|
|
65
|
-
this.server.respond({ ...msg,
|
|
66
|
+
this.server.respond({ ...msg, result: { has: this.has(msg.params.uniqueId) } });
|
|
66
67
|
break;
|
|
67
68
|
case 'devices_get':
|
|
68
69
|
{
|
|
69
70
|
const endpoint = this.get(msg.params.uniqueId);
|
|
70
|
-
this.server.respond({ ...msg,
|
|
71
|
+
this.server.respond({ ...msg, result: { device: endpoint ? toBaseDevice(endpoint) : undefined } });
|
|
71
72
|
}
|
|
72
73
|
break;
|
|
73
74
|
case 'devices_set':
|
|
74
|
-
this.server.respond({ ...msg,
|
|
75
|
+
this.server.respond({ ...msg, result: { device: this.set(toBaseDevice(msg.params.device)) } });
|
|
75
76
|
break;
|
|
76
77
|
case 'devices_remove':
|
|
77
|
-
this.server.respond({ ...msg,
|
|
78
|
+
this.server.respond({ ...msg, result: { success: this.remove(toBaseDevice(msg.params.device)) } });
|
|
78
79
|
break;
|
|
79
80
|
case 'devices_clear':
|
|
80
81
|
this.clear();
|
|
81
|
-
this.server.respond({ ...msg,
|
|
82
|
+
this.server.respond({ ...msg, result: { success: true } });
|
|
82
83
|
break;
|
|
83
84
|
case 'devices_basearray':
|
|
84
|
-
this.server.respond({ ...msg,
|
|
85
|
+
this.server.respond({ ...msg, result: { devices: this.baseArray(msg.params.pluginName) } });
|
|
85
86
|
break;
|
|
86
87
|
default:
|
|
87
88
|
if (this.verbose)
|
package/dist/frontend.js
CHANGED
|
@@ -43,97 +43,92 @@ export class Frontend extends EventEmitter {
|
|
|
43
43
|
this.server.on('broadcast_message', this.msgHandler.bind(this));
|
|
44
44
|
}
|
|
45
45
|
destroy() {
|
|
46
|
+
this.server.off('broadcast_message', this.msgHandler.bind(this));
|
|
46
47
|
this.server.close();
|
|
47
48
|
}
|
|
48
49
|
async msgHandler(msg) {
|
|
49
|
-
if (this.server.isWorkerRequest(msg
|
|
50
|
+
if (this.server.isWorkerRequest(msg)) {
|
|
50
51
|
if (this.verbose)
|
|
51
52
|
this.log.debug(`Received broadcast request ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
|
|
52
53
|
switch (msg.type) {
|
|
53
54
|
case 'get_log_level':
|
|
54
|
-
this.server.respond({ ...msg,
|
|
55
|
+
this.server.respond({ ...msg, result: { logLevel: this.log.logLevel } });
|
|
55
56
|
break;
|
|
56
57
|
case 'set_log_level':
|
|
57
58
|
this.log.logLevel = msg.params.logLevel;
|
|
58
|
-
this.server.respond({ ...msg,
|
|
59
|
+
this.server.respond({ ...msg, result: { logLevel: this.log.logLevel } });
|
|
59
60
|
break;
|
|
60
61
|
case 'frontend_start':
|
|
61
62
|
await this.start(msg.params.port);
|
|
62
|
-
this.server.respond({ ...msg,
|
|
63
|
+
this.server.respond({ ...msg, result: { success: true } });
|
|
63
64
|
break;
|
|
64
65
|
case 'frontend_stop':
|
|
65
66
|
await this.stop();
|
|
66
|
-
this.server.respond({ ...msg,
|
|
67
|
+
this.server.respond({ ...msg, result: { success: true } });
|
|
67
68
|
break;
|
|
68
69
|
case 'frontend_refreshrequired':
|
|
69
70
|
this.wssSendRefreshRequired(msg.params.changed, msg.params.matter ? { matter: msg.params.matter } : undefined);
|
|
70
|
-
this.server.respond({ ...msg,
|
|
71
|
+
this.server.respond({ ...msg, result: { success: true } });
|
|
71
72
|
break;
|
|
72
73
|
case 'frontend_restartrequired':
|
|
73
74
|
this.wssSendRestartRequired(msg.params.snackbar, msg.params.fixed);
|
|
74
|
-
this.server.respond({ ...msg,
|
|
75
|
+
this.server.respond({ ...msg, result: { success: true } });
|
|
75
76
|
break;
|
|
76
77
|
case 'frontend_restartnotrequired':
|
|
77
78
|
this.wssSendRestartNotRequired(msg.params.snackbar);
|
|
78
|
-
this.server.respond({ ...msg,
|
|
79
|
+
this.server.respond({ ...msg, result: { success: true } });
|
|
79
80
|
break;
|
|
80
81
|
case 'frontend_updaterequired':
|
|
81
82
|
this.wssSendUpdateRequired(msg.params.devVersion);
|
|
82
|
-
this.server.respond({ ...msg,
|
|
83
|
+
this.server.respond({ ...msg, result: { success: true } });
|
|
83
84
|
break;
|
|
84
85
|
case 'frontend_snackbarmessage':
|
|
85
86
|
this.wssSendSnackbarMessage(msg.params.message, msg.params.timeout, msg.params.severity);
|
|
86
|
-
this.server.respond({ ...msg,
|
|
87
|
+
this.server.respond({ ...msg, result: { success: true } });
|
|
87
88
|
break;
|
|
88
89
|
case 'frontend_attributechanged':
|
|
89
90
|
this.wssSendAttributeChangedMessage(msg.params.plugin, msg.params.serialNumber, msg.params.uniqueId, msg.params.number, msg.params.id, msg.params.cluster, msg.params.attribute, msg.params.value);
|
|
90
|
-
this.server.respond({ ...msg,
|
|
91
|
+
this.server.respond({ ...msg, result: { success: true } });
|
|
91
92
|
break;
|
|
92
93
|
case 'frontend_logmessage':
|
|
93
94
|
this.wssSendLogMessage(msg.params.level, msg.params.time, msg.params.name, msg.params.message);
|
|
94
|
-
this.server.respond({ ...msg,
|
|
95
|
+
this.server.respond({ ...msg, result: { success: true } });
|
|
95
96
|
break;
|
|
96
97
|
case 'frontend_broadcast_message':
|
|
97
98
|
this.wssBroadcastMessage(msg.params.msg);
|
|
98
|
-
this.server.respond({ ...msg,
|
|
99
|
+
this.server.respond({ ...msg, result: { success: true } });
|
|
99
100
|
break;
|
|
100
101
|
default:
|
|
101
102
|
if (this.verbose)
|
|
102
103
|
this.log.debug(`Unknown broadcast request ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}`);
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
|
-
if (this.server.isWorkerResponse(msg
|
|
106
|
+
if (this.server.isWorkerResponse(msg) && msg.result) {
|
|
106
107
|
if (this.verbose)
|
|
107
108
|
this.log.debug(`Received broadcast response ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
|
|
108
109
|
switch (msg.type) {
|
|
109
|
-
case 'get_log_level':
|
|
110
|
-
case 'set_log_level':
|
|
111
|
-
break;
|
|
112
110
|
case 'plugins_install':
|
|
113
|
-
this.wssSendCloseSnackbarMessage(`Installing package ${msg.
|
|
114
|
-
if (msg.
|
|
111
|
+
this.wssSendCloseSnackbarMessage(`Installing package ${msg.result.packageName}...`);
|
|
112
|
+
if (msg.result.success) {
|
|
115
113
|
this.wssSendRestartRequired(true, true);
|
|
116
114
|
this.wssSendRefreshRequired('plugins');
|
|
117
|
-
this.wssSendSnackbarMessage(`Installed package ${msg.
|
|
115
|
+
this.wssSendSnackbarMessage(`Installed package ${msg.result.packageName}`, 5, 'success');
|
|
118
116
|
}
|
|
119
117
|
else {
|
|
120
|
-
this.wssSendSnackbarMessage(`Package ${msg.
|
|
118
|
+
this.wssSendSnackbarMessage(`Package ${msg.result.packageName} not installed`, 10, 'error');
|
|
121
119
|
}
|
|
122
120
|
break;
|
|
123
121
|
case 'plugins_uninstall':
|
|
124
|
-
this.wssSendCloseSnackbarMessage(`Uninstalling package ${msg.
|
|
125
|
-
if (msg.
|
|
122
|
+
this.wssSendCloseSnackbarMessage(`Uninstalling package ${msg.result.packageName}...`);
|
|
123
|
+
if (msg.result.success) {
|
|
126
124
|
this.wssSendRestartRequired(true, true);
|
|
127
125
|
this.wssSendRefreshRequired('plugins');
|
|
128
|
-
this.wssSendSnackbarMessage(`Uninstalled package ${msg.
|
|
126
|
+
this.wssSendSnackbarMessage(`Uninstalled package ${msg.result.packageName}`, 5, 'success');
|
|
129
127
|
}
|
|
130
128
|
else {
|
|
131
|
-
this.wssSendSnackbarMessage(`Package ${msg.
|
|
129
|
+
this.wssSendSnackbarMessage(`Package ${msg.result.packageName} not uninstalled`, 10, 'error');
|
|
132
130
|
}
|
|
133
131
|
break;
|
|
134
|
-
default:
|
|
135
|
-
if (this.verbose)
|
|
136
|
-
this.log.debug(`Unknown broadcast response ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}`);
|
|
137
132
|
}
|
|
138
133
|
}
|
|
139
134
|
}
|
|
@@ -50,6 +50,7 @@ export let wssSendRestartRequiredSpy;
|
|
|
50
50
|
export let wssSendRestartNotRequiredSpy;
|
|
51
51
|
export let broadcastServerIsWorkerRequestSpy;
|
|
52
52
|
export let broadcastServerIsWorkerResponseSpy;
|
|
53
|
+
export let broadcastServerBroadcastSpy;
|
|
53
54
|
export let broadcastServerRequestSpy;
|
|
54
55
|
export let broadcastServerRespondSpy;
|
|
55
56
|
export let broadcastServerFetchSpy;
|
|
@@ -116,6 +117,7 @@ export async function setupTest(name, debug = false) {
|
|
|
116
117
|
wssSendRestartNotRequiredSpy = jest.spyOn(Frontend.prototype, 'wssSendRestartNotRequired');
|
|
117
118
|
broadcastServerIsWorkerRequestSpy = jest.spyOn(BroadcastServer.prototype, 'isWorkerRequest');
|
|
118
119
|
broadcastServerIsWorkerResponseSpy = jest.spyOn(BroadcastServer.prototype, 'isWorkerResponse');
|
|
120
|
+
broadcastServerBroadcastSpy = jest.spyOn(BroadcastServer.prototype, 'broadcast');
|
|
119
121
|
broadcastServerRequestSpy = jest.spyOn(BroadcastServer.prototype, 'request');
|
|
120
122
|
broadcastServerRespondSpy = jest.spyOn(BroadcastServer.prototype, 'respond');
|
|
121
123
|
broadcastServerFetchSpy = jest.spyOn(BroadcastServer.prototype, 'fetch');
|
package/dist/matterNode.js
CHANGED
|
@@ -92,23 +92,23 @@ export class MatterNode extends EventEmitter {
|
|
|
92
92
|
this.log.debug(`MatterNode ${this.pluginName ? 'for plugin ' + this.pluginName : 'bridge'} loaded`);
|
|
93
93
|
}
|
|
94
94
|
async msgHandler(msg) {
|
|
95
|
-
if (this.server.isWorkerRequest(msg
|
|
95
|
+
if (this.server.isWorkerRequest(msg) && (msg.dst === 'all' || msg.dst === 'matter')) {
|
|
96
96
|
if (this.verbose)
|
|
97
97
|
this.log.debug(`Received broadcast request ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
|
|
98
98
|
switch (msg.type) {
|
|
99
99
|
case 'get_log_level':
|
|
100
|
-
this.server.respond({ ...msg,
|
|
100
|
+
this.server.respond({ ...msg, result: { logLevel: this.log.logLevel } });
|
|
101
101
|
break;
|
|
102
102
|
case 'set_log_level':
|
|
103
103
|
this.log.logLevel = msg.params.logLevel;
|
|
104
|
-
this.server.respond({ ...msg,
|
|
104
|
+
this.server.respond({ ...msg, result: { logLevel: this.log.logLevel } });
|
|
105
105
|
break;
|
|
106
106
|
default:
|
|
107
107
|
if (this.verbose)
|
|
108
108
|
this.log.debug(`Unknown broadcast request ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}`);
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
|
-
if (this.server.isWorkerResponse(msg
|
|
111
|
+
if (this.server.isWorkerResponse(msg) && (msg.dst === 'all' || msg.dst === 'matter')) {
|
|
112
112
|
if (this.verbose)
|
|
113
113
|
this.log.debug(`Received broadcast response ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
|
|
114
114
|
switch (msg.type) {
|
|
@@ -669,6 +669,7 @@ export class MatterNode extends EventEmitter {
|
|
|
669
669
|
await device.construction.ready;
|
|
670
670
|
await this.subscribeAttributeChanged(plugin, device);
|
|
671
671
|
this.log.info(`Added endpoint #${plugin.registeredDevices} ${plg}${pluginName}${nf}:${dev}${device.deviceName}${nf} (${zb}${device.name}${nf})`);
|
|
672
|
+
await this.yieldToNode(10);
|
|
672
673
|
return device;
|
|
673
674
|
}
|
|
674
675
|
async removeBridgedEndpoint(pluginName, device) {
|
|
@@ -697,6 +698,7 @@ export class MatterNode extends EventEmitter {
|
|
|
697
698
|
if (plugin.registeredDevices !== undefined)
|
|
698
699
|
plugin.registeredDevices--;
|
|
699
700
|
await this.server.fetch({ type: 'devices_remove', src: this.server.name, dst: 'devices', params: { device: toBaseDevice(device) } });
|
|
701
|
+
await this.yieldToNode(10);
|
|
700
702
|
return device;
|
|
701
703
|
}
|
|
702
704
|
async removeAllBridgedEndpoints(pluginName, delay = 0) {
|
|
@@ -704,7 +706,7 @@ export class MatterNode extends EventEmitter {
|
|
|
704
706
|
if (!plugin)
|
|
705
707
|
throw new Error(`Error removing all bridged endpoints for plugin ${plg}${pluginName}${er}: plugin not found`);
|
|
706
708
|
this.log.debug(`Removing all #${plugin.registeredDevices} bridged endpoints for plugin ${plg}${pluginName}${db}${delay > 0 ? ` with delay ${delay} ms` : ''}...`);
|
|
707
|
-
const devices = (await this.server.fetch({ type: 'devices_basearray', src: this.server.name, dst: 'devices', params: { pluginName } })).
|
|
709
|
+
const devices = (await this.server.fetch({ type: 'devices_basearray', src: this.server.name, dst: 'devices', params: { pluginName } })).result.devices;
|
|
708
710
|
for (const device of devices) {
|
|
709
711
|
const endpoint = (this.aggregatorNode?.parts.get(device.id || '') || this.serverNode?.parts.get(device.id || ''));
|
|
710
712
|
if (!endpoint)
|
|
@@ -715,6 +717,7 @@ export class MatterNode extends EventEmitter {
|
|
|
715
717
|
if (plugin.registeredDevices !== undefined)
|
|
716
718
|
plugin.registeredDevices--;
|
|
717
719
|
await this.server.fetch({ type: 'devices_remove', src: this.server.name, dst: 'devices', params: { device: toBaseDevice(device) } });
|
|
720
|
+
await this.yieldToNode(10);
|
|
718
721
|
if (delay > 0)
|
|
719
722
|
await wait(delay);
|
|
720
723
|
}
|
|
@@ -742,6 +745,7 @@ export class MatterNode extends EventEmitter {
|
|
|
742
745
|
}
|
|
743
746
|
await addVirtualDevice(this.aggregatorNode, name.slice(0, 32), type, callback);
|
|
744
747
|
this.log.debug(`Created virtual device ${plg}${pluginName}${db}:${dev}${name}${db}`);
|
|
748
|
+
await this.yieldToNode(10);
|
|
745
749
|
return true;
|
|
746
750
|
}
|
|
747
751
|
async subscribeAttributeChanged(plugin, device) {
|
package/dist/matterbridge.js
CHANGED
|
@@ -133,52 +133,45 @@ export class Matterbridge extends EventEmitter {
|
|
|
133
133
|
this.server.close();
|
|
134
134
|
}
|
|
135
135
|
async msgHandler(msg) {
|
|
136
|
-
if (this.server.isWorkerRequest(msg
|
|
136
|
+
if (this.server.isWorkerRequest(msg) && (msg.dst === 'all' || msg.dst === 'matterbridge')) {
|
|
137
137
|
if (this.verbose)
|
|
138
138
|
this.log.debug(`Received broadcast request ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
|
|
139
139
|
switch (msg.type) {
|
|
140
140
|
case 'get_log_level':
|
|
141
|
-
this.server.respond({ ...msg,
|
|
141
|
+
this.server.respond({ ...msg, result: { logLevel: this.log.logLevel } });
|
|
142
142
|
break;
|
|
143
143
|
case 'set_log_level':
|
|
144
144
|
this.log.logLevel = msg.params.logLevel;
|
|
145
|
-
this.server.respond({ ...msg,
|
|
145
|
+
this.server.respond({ ...msg, result: { logLevel: this.log.logLevel } });
|
|
146
146
|
break;
|
|
147
147
|
case 'matterbridge_latest_version':
|
|
148
148
|
this.matterbridgeLatestVersion = msg.params.version;
|
|
149
149
|
await this.nodeContext?.set('matterbridgeLatestVersion', msg.params.version);
|
|
150
|
-
this.server.respond({ ...msg,
|
|
150
|
+
this.server.respond({ ...msg, result: { success: true } });
|
|
151
151
|
break;
|
|
152
152
|
case 'matterbridge_dev_version':
|
|
153
153
|
this.matterbridgeDevVersion = msg.params.version;
|
|
154
154
|
await this.nodeContext?.set('matterbridgeDevVersion', msg.params.version);
|
|
155
|
-
this.server.respond({ ...msg,
|
|
155
|
+
this.server.respond({ ...msg, result: { success: true } });
|
|
156
|
+
break;
|
|
157
|
+
case 'matterbridge_global_prefix':
|
|
158
|
+
this.globalModulesDirectory = msg.params.prefix;
|
|
159
|
+
await this.nodeContext?.set('globalModulesDirectory', msg.params.prefix);
|
|
160
|
+
this.server.respond({ ...msg, result: { success: true } });
|
|
156
161
|
break;
|
|
157
162
|
case 'matterbridge_sys_update':
|
|
158
163
|
this.shellySysUpdate = true;
|
|
159
|
-
this.server.respond({ ...msg,
|
|
164
|
+
this.server.respond({ ...msg, result: { success: true } });
|
|
160
165
|
break;
|
|
161
166
|
case 'matterbridge_main_update':
|
|
162
167
|
this.shellyMainUpdate = true;
|
|
163
|
-
this.server.respond({ ...msg,
|
|
168
|
+
this.server.respond({ ...msg, result: { success: true } });
|
|
164
169
|
break;
|
|
165
170
|
default:
|
|
166
171
|
if (this.verbose)
|
|
167
172
|
this.log.debug(`Unknown broadcast request ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}`);
|
|
168
173
|
}
|
|
169
174
|
}
|
|
170
|
-
if (this.server.isWorkerResponse(msg, msg.type)) {
|
|
171
|
-
if (this.verbose)
|
|
172
|
-
this.log.debug(`Received broadcast response ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
|
|
173
|
-
switch (msg.type) {
|
|
174
|
-
case 'get_log_level':
|
|
175
|
-
case 'set_log_level':
|
|
176
|
-
break;
|
|
177
|
-
default:
|
|
178
|
-
if (this.verbose)
|
|
179
|
-
this.log.debug(`Unknown broadcast response ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}`);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
175
|
}
|
|
183
176
|
static async loadInstance(initialize = false) {
|
|
184
177
|
if (!Matterbridge.instance) {
|
|
@@ -832,16 +825,9 @@ export class Matterbridge extends EventEmitter {
|
|
|
832
825
|
}
|
|
833
826
|
}
|
|
834
827
|
else {
|
|
835
|
-
this.log.debug(`
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
this.globalModulesDirectory = await getGlobalNodeModules();
|
|
839
|
-
this.log.debug(`Global node_modules Directory: ${this.globalModulesDirectory}`);
|
|
840
|
-
await this.nodeContext?.set('globalModulesDirectory', this.globalModulesDirectory);
|
|
841
|
-
}
|
|
842
|
-
catch (error) {
|
|
843
|
-
this.log.error(`Error checking global node_modules directory: ${error}`);
|
|
844
|
-
}
|
|
828
|
+
this.log.debug(`Global node_modules Directory: ${this.globalModulesDirectory}`);
|
|
829
|
+
const { createESMWorker } = await import('./workers.js');
|
|
830
|
+
createESMWorker('NpmGlobalPrefix', './dist/workerGlobalPrefix.js');
|
|
845
831
|
}
|
|
846
832
|
this.log.debug(`Reading matterbridge package.json...`);
|
|
847
833
|
const packageJson = JSON.parse(await fs.promises.readFile(path.join(this.rootDirectory, 'package.json'), 'utf-8'));
|
|
@@ -124,7 +124,7 @@ export class MatterbridgePlatform {
|
|
|
124
124
|
this.#server.request({ type: 'plugins_saveconfigfromjson', src: 'platform', dst: 'plugins', params: { name: this.name, config } });
|
|
125
125
|
}
|
|
126
126
|
async getSchema() {
|
|
127
|
-
return (await this.#server.fetch({ type: 'plugins_getschema', src: 'platform', dst: 'plugins', params: { name: this.name } })).
|
|
127
|
+
return (await this.#server.fetch({ type: 'plugins_getschema', src: 'platform', dst: 'plugins', params: { name: this.name } })).result.schema;
|
|
128
128
|
}
|
|
129
129
|
setSchema(schema) {
|
|
130
130
|
this.#server.request({ type: 'plugins_setschema', src: 'platform', dst: 'plugins', params: { name: this.name, schema } });
|