matterbridge 3.3.0-dev-20251004-43d8106 → 3.3.1-dev-20251007-4e5eaac
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 +29 -3
- package/README.md +9 -1
- package/dist/broadcastServer.js +73 -0
- package/dist/broadcastServerTypes.js +1 -0
- package/dist/deviceManager.js +44 -5
- package/dist/frontend.js +150 -190
- package/dist/helpers.js +4 -4
- package/dist/index.js +0 -12
- package/dist/matterbridge.js +112 -117
- package/dist/matterbridgePlatform.js +1 -1
- package/dist/pluginManager.js +130 -5
- package/dist/shelly.js +4 -4
- package/dist/update.js +0 -2
- package/dist/utils/network.js +71 -38
- package/dist/utils/spawn.js +5 -6
- package/frontend/build/assets/index.js +4 -7
- package/frontend/build/assets/vendor_mui.js +1 -1
- package/frontend/package.json +1 -1
- package/npm-shrinkwrap.json +44 -44
- package/package.json +2 -2
- package/dist/globalMatterbridge.js +0 -23
package/CHANGELOG.md
CHANGED
|
@@ -23,7 +23,35 @@ Advantages:
|
|
|
23
23
|
- isolation between threads;
|
|
24
24
|
- individual plugin isolation in childbridge mode;
|
|
25
25
|
|
|
26
|
-
## [3.3.
|
|
26
|
+
## [3.3.1] - Not released
|
|
27
|
+
|
|
28
|
+
### Breaking Changes
|
|
29
|
+
|
|
30
|
+
- [frontend]: When a plugin is first installed, it will not be anymore started to allow to configure it before restarting.
|
|
31
|
+
- [index]: Removed old plugin api compatibility since it was changed one year ago.
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
|
|
35
|
+
- [network]: Added getInterfaceDetails() function.
|
|
36
|
+
- [network]: Added getInterfaceName() function.
|
|
37
|
+
- [network]: Optimized code.
|
|
38
|
+
- [matterbridge]: Added SharedMatterbridge readonly type.
|
|
39
|
+
- [thread]: Add BroadcastServer to frontend plugins and devices.
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
|
|
43
|
+
- [package]: Updated dependencies.
|
|
44
|
+
- [matterbridge]: Removed matterbridgeInformation. It will be recreated when the frontend requires it.
|
|
45
|
+
- [frontend]: Bumped `frontend` version to 3.2.1.
|
|
46
|
+
- [frontend]: Refactored InstallProgressDialog.
|
|
47
|
+
- [spawn]: Refactored spawnCommand for compatibility with InstallProgressDialog.
|
|
48
|
+
- [matter.js]: Bumped `matter.js` to 0.15.5. Thanks matter.js!
|
|
49
|
+
|
|
50
|
+
<a href="https://www.buymeacoffee.com/luligugithub">
|
|
51
|
+
<img src="bmc-button.svg" alt="Buy me a coffee" width="80">
|
|
52
|
+
</a>
|
|
53
|
+
|
|
54
|
+
## [3.3.0] - 2025-10-03
|
|
27
55
|
|
|
28
56
|
### Development Breaking Changes Notice
|
|
29
57
|
|
|
@@ -98,8 +126,6 @@ In this phase (matterbridge `3.4.x`) all plugins will not build and will not run
|
|
|
98
126
|
- [package]: Updated dependencies.
|
|
99
127
|
- [frontend]: General improvements and small bug fixes.
|
|
100
128
|
|
|
101
|
-
### Fixed
|
|
102
|
-
|
|
103
129
|
<a href="https://www.buymeacoffee.com/luligugithub">
|
|
104
130
|
<img src="bmc-button.svg" alt="Buy me a coffee" width="80">
|
|
105
131
|
</a>
|
package/README.md
CHANGED
|
@@ -78,10 +78,14 @@ After follow the guidelines for the [Docker configurations](README-DOCKER.md).
|
|
|
78
78
|
|
|
79
79
|
I suggest using Docker for its simplicity.
|
|
80
80
|
|
|
81
|
-
Since
|
|
81
|
+
Since Matter is designed as "a universal IPv6-based communication protocol for smart home devices" (per the Matter specifications), **IPv6 must be enabled on your local network (LAN)**.
|
|
82
|
+
|
|
83
|
+
**Important:** You only need IPv6 on your local network - it doesn't matter if your internet provider doesn't provide IPv6 on the internet side (WAN).
|
|
82
84
|
|
|
83
85
|
Avoid using VLAN and firewall blocking the communications between the controllers and Matterbridge.
|
|
84
86
|
|
|
87
|
+
To pair matterbridge, you need a matter enabled controller (Apple Home, Smart Things, Google Home, Alexa, Hose Assistant etc.).
|
|
88
|
+
|
|
85
89
|
## Installation
|
|
86
90
|
|
|
87
91
|
Follow these steps to install Matterbridge:
|
|
@@ -574,3 +578,7 @@ Click on the badge below to get started:
|
|
|
574
578
|
</a>
|
|
575
579
|
|
|
576
580
|
Thank you for your support!
|
|
581
|
+
|
|
582
|
+
# Licensing
|
|
583
|
+
|
|
584
|
+
Matterbridge is licensed under the [Apache License 2.0](./LICENSE).
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import { BroadcastChannel } from 'node:worker_threads';
|
|
3
|
+
import { debugStringify } from 'node-ansi-logger';
|
|
4
|
+
export class BroadcastServer extends EventEmitter {
|
|
5
|
+
name;
|
|
6
|
+
log;
|
|
7
|
+
channel;
|
|
8
|
+
broadcastChannel;
|
|
9
|
+
constructor(name, log, channel = 'broadcast-channel') {
|
|
10
|
+
super();
|
|
11
|
+
this.name = name;
|
|
12
|
+
this.log = log;
|
|
13
|
+
this.channel = channel;
|
|
14
|
+
this.broadcastChannel = new BroadcastChannel(this.channel);
|
|
15
|
+
this.broadcastChannel.onmessage = this.broadcastMessageHandler.bind(this);
|
|
16
|
+
}
|
|
17
|
+
close() {
|
|
18
|
+
this.broadcastChannel.onmessage = null;
|
|
19
|
+
this.broadcastChannel.close();
|
|
20
|
+
}
|
|
21
|
+
getUniqueId() {
|
|
22
|
+
return Math.floor(Math.random() * (999999 - 100000 + 1)) + 100000;
|
|
23
|
+
}
|
|
24
|
+
isWorkerRequest(msg, type) {
|
|
25
|
+
return typeof msg === 'object' && msg !== null && 'id' in msg && 'type' in msg && msg.type === type && !('response' in msg) && 'src' in msg && 'dst' in msg;
|
|
26
|
+
}
|
|
27
|
+
isWorkerResponse(msg, type) {
|
|
28
|
+
return typeof msg === 'object' && msg !== null && 'id' in msg && 'type' in msg && msg.type === type && 'response' in msg && 'src' in msg && 'dst' in msg;
|
|
29
|
+
}
|
|
30
|
+
broadcastMessageHandler(event) {
|
|
31
|
+
const data = event.data;
|
|
32
|
+
this.log.debug(`*Received broadcast message: ${debugStringify(data)}`);
|
|
33
|
+
this.emit('broadcast_message', data);
|
|
34
|
+
}
|
|
35
|
+
request(message) {
|
|
36
|
+
if (message.id === undefined) {
|
|
37
|
+
message.id = this.getUniqueId();
|
|
38
|
+
}
|
|
39
|
+
if (!this.isWorkerRequest(message, message.type)) {
|
|
40
|
+
this.log.error(`Invalid request message format for broadcast: ${debugStringify(message)}`);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
this.log.debug(`*Broadcasting message: ${debugStringify(message)}`);
|
|
44
|
+
this.broadcastChannel.postMessage(message);
|
|
45
|
+
}
|
|
46
|
+
respond(message) {
|
|
47
|
+
if (!this.isWorkerResponse(message, message.type)) {
|
|
48
|
+
this.log.error(`Invalid response message format for broadcast: ${debugStringify(message)}`);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
this.log.debug(`*Broadcasting message: ${debugStringify(message)}`);
|
|
52
|
+
this.broadcastChannel.postMessage(message);
|
|
53
|
+
}
|
|
54
|
+
async fetch(message) {
|
|
55
|
+
this.log.debug(`*Fetching message: ${debugStringify(message)}`);
|
|
56
|
+
return new Promise((resolve, reject) => {
|
|
57
|
+
const responseHandler = (msg) => {
|
|
58
|
+
if (this.isWorkerResponse(msg, message.type) && msg.id === message.id) {
|
|
59
|
+
clearTimeout(timeoutId);
|
|
60
|
+
this.off('broadcast_message', responseHandler);
|
|
61
|
+
this.log.debug(`*Fetch response: ${debugStringify(msg)}`);
|
|
62
|
+
resolve(msg);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
this.on('broadcast_message', responseHandler);
|
|
66
|
+
this.request(message);
|
|
67
|
+
const timeoutId = setTimeout(() => {
|
|
68
|
+
this.off('broadcast_message', responseHandler);
|
|
69
|
+
reject(new Error(`Fetch timeout after 100ms for message id ${message.id}`));
|
|
70
|
+
}, 100);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/deviceManager.js
CHANGED
|
@@ -1,13 +1,52 @@
|
|
|
1
|
-
import { AnsiLogger, BLUE, er } from 'node-ansi-logger';
|
|
1
|
+
import { AnsiLogger, BLUE, CYAN, db, debugStringify, er, wr } from 'node-ansi-logger';
|
|
2
2
|
import { dev } from './matterbridgeTypes.js';
|
|
3
|
+
import { BroadcastServer } from './broadcastServer.js';
|
|
3
4
|
export class DeviceManager {
|
|
4
5
|
_devices = new Map();
|
|
5
|
-
matterbridge;
|
|
6
6
|
log;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
this.log = new AnsiLogger({ logName: 'DeviceManager', logTimestampFormat: 4, logLevel:
|
|
7
|
+
server;
|
|
8
|
+
constructor() {
|
|
9
|
+
this.log = new AnsiLogger({ logName: 'DeviceManager', logTimestampFormat: 4, logLevel: "info" });
|
|
10
10
|
this.log.debug('Matterbridge device manager starting...');
|
|
11
|
+
this.server = new BroadcastServer('devices', this.log);
|
|
12
|
+
this.server.on('broadcast_message', this.msgHandler.bind(this));
|
|
13
|
+
this.log.debug('Matterbridge device manager started');
|
|
14
|
+
}
|
|
15
|
+
destroy() {
|
|
16
|
+
this.server.close();
|
|
17
|
+
}
|
|
18
|
+
async msgHandler(msg) {
|
|
19
|
+
if (!this.server.isWorkerRequest(msg, msg.type))
|
|
20
|
+
return;
|
|
21
|
+
if (!msg.id || (msg.dst !== 'all' && msg.dst !== 'devices'))
|
|
22
|
+
return;
|
|
23
|
+
this.log.debug(`**Received request message ${CYAN}${msg.type}${db} from ${CYAN}${msg.src}${db}: ${debugStringify(msg)}${db}`);
|
|
24
|
+
switch (msg.type) {
|
|
25
|
+
case 'devices_length':
|
|
26
|
+
this.server.respond({ ...msg, id: msg.id, response: { length: this.length } });
|
|
27
|
+
break;
|
|
28
|
+
case 'devices_size':
|
|
29
|
+
this.server.respond({ ...msg, id: msg.id, response: { size: this.size } });
|
|
30
|
+
break;
|
|
31
|
+
case 'devices_has':
|
|
32
|
+
this.server.respond({ ...msg, id: msg.id, response: { has: this.has(msg.params.uniqueId) } });
|
|
33
|
+
break;
|
|
34
|
+
case 'devices_get':
|
|
35
|
+
this.server.respond({ ...msg, id: msg.id, response: { device: this.get(msg.params.uniqueId) } });
|
|
36
|
+
break;
|
|
37
|
+
case 'devices_set':
|
|
38
|
+
this.server.respond({ ...msg, id: msg.id, response: { device: this.set(msg.params.device) } });
|
|
39
|
+
break;
|
|
40
|
+
case 'devices_remove':
|
|
41
|
+
this.server.respond({ ...msg, id: msg.id, response: { success: this.remove(msg.params.device) } });
|
|
42
|
+
break;
|
|
43
|
+
case 'devices_clear':
|
|
44
|
+
this.clear();
|
|
45
|
+
this.server.respond({ ...msg, id: msg.id, response: { success: true } });
|
|
46
|
+
break;
|
|
47
|
+
default:
|
|
48
|
+
this.log.warn(`Unknown broadcast message ${CYAN}${msg.type}${wr} from ${CYAN}${msg.src}${wr}`);
|
|
49
|
+
}
|
|
11
50
|
}
|
|
12
51
|
get length() {
|
|
13
52
|
return this._devices.size;
|