matterbridge 3.0.7-dev-20250614-0d145a8 → 3.0.7-dev-20250616-cd7fd1c

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 CHANGED
@@ -10,13 +10,20 @@ If you like this project and find it useful, please consider giving it a star on
10
10
 
11
11
  ## [3.0.7] - 2025-06-??
12
12
 
13
+ ### Breaking Changes
14
+
15
+ - [devices]: The single devices (i.e. Rvc, Evse etc...) are exported from matterbridge/devices. Please update your imports to use the new export path. Refer to the [documentation](README-DEV.md) for details on imports.
16
+
13
17
  ### Added
14
18
 
19
+ - [template]: Added the [Matterbridge Plugin Template](https://github.com/Luligu/matterbridge-plugin-template).
20
+
15
21
  ### Changed
16
22
 
17
23
  - [package]: Updated dependencies.
18
24
  - [package]: Downgrade jest to 29.7.0.
19
25
  - [energy]: Added parameter for cumulativeEnergyExported to the helper. For solar power device.
26
+ - [platform]: Removed long deprecated methods: validateEntityBlackList and validateDeviceWhiteBlackList. Use validateDevice and validateEntity.
20
27
 
21
28
  ### Fixed
22
29
 
package/README-DEV.md CHANGED
@@ -14,65 +14,83 @@
14
14
 
15
15
  # Development
16
16
 
17
+ ## How to create your plugin
18
+
19
+ The easiest way is to clone the [Matterbridge Plugin Template](https://github.com/Luligu/matterbridge-plugin-template) that has **Dev Container support for instant development environment** and all tools and extensions (like Node.js, npm, TypeScript, ESLint, Prettier, Jest) already loaded and configured.
20
+
21
+ Then change the name (keep matterbridge- at the beginning of the name), version, description, author, homepage, repository, bugs and funding in the package.json.
22
+
23
+ It is possible to add two custom properties to the package.json: **help** and **changelog** with a url that will be used in the frontend instead of the default (/blob/main/README.md and /blob/main/CHANGELOG.md).
24
+
25
+ Add your plugin logic in module.ts.
26
+
27
+ The Matterbridge Plugin Template has an already configured Jest test (coverage 100%) that you can expand while you add your own plugin logic.
28
+
29
+ It also has a workflow configured to run on push and pull request that build, lint and test the plugin on node 18, 20, 22 and 24 with ubuntu, macOS and windows.
30
+
17
31
  ## Guidelines on imports/exports
18
32
 
19
33
  Matterbridge exports from:
20
34
 
21
- "matterbridge"
35
+ ### "matterbridge"
22
36
 
23
37
  - Matterbridge and all Matterbridge related classes.
24
38
 
25
- "matterbridge/matter"
39
+ ### "matterbridge/devices"
26
40
 
27
- - All relevant matter.js exports.
41
+ - All single device classes like the Rvc, LaundryWasher, etc...
28
42
 
29
- "matterbridge/matter/behaviors"
43
+ ### "matterbridge/clusters"
30
44
 
31
- - All matter.js behaviors.
45
+ - All clusters not present in matter.js or modified.
32
46
 
33
- "matterbridge/matter/clusters"
47
+ ### "matterbridge/utils"
34
48
 
35
- - All matter.js clusters.
49
+ - All general utils and colorUtils functions.
36
50
 
37
- "matterbridge/matter/devices"
51
+ ### "matterbridge/logger"
38
52
 
39
- - All matter.js devices.
53
+ - AnsiLogger class.
40
54
 
41
- "matterbridge/matter/endpoints"
55
+ ### "matterbridge/storage"
42
56
 
43
- - All matter.js endpoints.
57
+ - NodeStorageManager and NodeStorage classes.
44
58
 
45
- "matterbridge/matter/types"
59
+ ### "matterbridge/matter"
46
60
 
47
- - All matter.js types.
61
+ - All relevant matter.js exports.
48
62
 
49
- "matterbridge/cluster"
63
+ ### "matterbridge/matter/behaviors"
50
64
 
51
- - All clusters not present in matter.js or modified.
65
+ - All matter.js behaviors.
52
66
 
53
- "matterbridge/utils"
67
+ ### "matterbridge/matter/clusters"
54
68
 
55
- - All general utils and colorUtils functions.
69
+ - All matter.js clusters.
56
70
 
57
- "matterbridge/logger"
71
+ ### "matterbridge/matter/devices"
58
72
 
59
- - AnsiLogger class.
73
+ - All matter.js devices.
60
74
 
61
- "matterbridge/storage"
75
+ ### "matterbridge/matter/endpoints"
62
76
 
63
- - NodeStorageManager and NodeStorage classes.
77
+ - All matter.js endpoints.
78
+
79
+ ### "matterbridge/matter/types"
80
+
81
+ - All matter.js types.
64
82
 
65
- # \***\*\*\*\*\***
83
+ ### WARNING \***\*\*\*\*\***
66
84
 
67
85
  A plugin must never install or import from `@matter` or `@project-chip` directly (neither as a dependency, devDependency, nor peerDependency), as this leads to a second instance of `matter.js`, causing instability and unpredictable errors such as "The only instance is Endpoint".
68
86
 
69
87
  Additionally, when Matterbridge updates the `matter.js` version, it should be consistent across all plugins.
70
88
 
71
- # \***\*\*\*\*\***
89
+ ### WARNING \***\*\*\*\*\***
72
90
 
73
91
  A plugin must never install Matterbridge (neither as a dependency, devDependency, nor peerDependency).
74
92
 
75
- Matterbridge must be linked to the plugin in development only.
93
+ Matterbridge must be linked to the plugin in development only. At runtime the plugin is loaded directly from the running Mattebridge instance.
76
94
 
77
95
  ```json
78
96
  "scripts": {
@@ -82,27 +100,15 @@ Matterbridge must be linked to the plugin in development only.
82
100
  }
83
101
  ```
84
102
 
85
- On the machine you use for development you should also have matterbridge installed globally or built locally and linked (npm link from the package root).
103
+ If you don't use Dev Container from the Matterbridge Plugin Template, on the machine you use for development of your plugin, you need to clone matterbridge, built it locally and link it globally (npm link from the matterbridge package root).
86
104
 
87
- Dev and edge branches of matterbridge are not suitable for developemnt cause they are published for production without types. If you want to develop a plugin using the dev or edge branch of matterbridge, you have to clone the dev or edge branch of matterbridge, build locally and link (npm run deepCleanBuild).
105
+ If you want to develop a plugin using the dev branch of matterbridge (I suggest you do it), you have to clone the dev branch of matterbridge, build it locally and link it (npm run deepCleanBuild does all necessary steps).
88
106
 
89
- # \***\*\*\*\*\***
90
-
91
- I added some error messages when a plugin has wrong imports or configurations and the plugin will be disabled to prevent instability and crashes.
92
-
93
- ## How to create your plugin
107
+ Always keep your local instance of matterbridge up to date.
94
108
 
95
- The easiest way is to clone:
109
+ ### WARNING \***\*\*\*\*\***
96
110
 
97
- - https://github.com/Luligu/matterbridge-example-accessory-platform if you want to create an Accessory Platform Plugin.
98
-
99
- - https://github.com/Luligu/matterbridge-example-dynamic-platform if you want to create a Dynamic Platform Plugin.
100
-
101
- Then change the name (keep matterbridge- at the beginning of the name), version, description, author and funding in the package.json.
102
-
103
- It is possible to add these custom properties to the package.json: help and changelog with a url that will be used in the frontend instead of the default (/blob/main/README.md and /blob/main/CHANGELOG.md).
104
-
105
- Add your plugin logic in platform.ts.
111
+ Some error messages are logged on start when a plugin has wrong imports or configurations and the plugin will be disabled to prevent instability and crashes.
106
112
 
107
113
  ## How to install and register a plugin for development (from github)
108
114
 
@@ -114,7 +120,7 @@ On windows:
114
120
  cd $HOME\Matterbridge
115
121
  ```
116
122
 
117
- On linux:
123
+ On linux or macOS:
118
124
 
119
125
  ```
120
126
  cd ~/Matterbridge
@@ -126,6 +132,7 @@ then clone the plugin
126
132
  git clone https://github.com/Luligu/matterbridge-example-accessory-platform
127
133
  cd matterbridge-example-accessory-platform
128
134
  npm install
135
+ npm link matterbridge
129
136
  npm run build
130
137
  ```
131
138
 
@@ -150,41 +157,71 @@ The plugin platform type.
150
157
  The plugin config (loaded before the platform constructor is called and saved after onShutdown() is called).
151
158
  Here you can store your plugin configuration (see matterbridge-zigbee2mqtt for example)
152
159
 
160
+ ### constructor(matterbridge: Matterbridge, log: AnsiLogger, config: PlatformConfig)
161
+
162
+ The contructor is called when is plugin is loaded.
163
+
153
164
  ### async onStart(reason?: string)
154
165
 
155
- The method onStart() is where you have to create your MatterbridgeDevice and add all needed clusters and command handlers.
166
+ The method onStart() is where you have to create your MatterbridgeEndpoint and add all needed clusters.
156
167
 
157
- The MatterbridgeDevice class has the create cluster methods already done and all command handlers needed (see plugin examples).
168
+ After add the command handlers and subscribe to the attributes when needed.
169
+
170
+ The MatterbridgeEndpoint class has the create cluster methods already done and all command handlers needed (see plugin examples).
158
171
 
159
172
  The method is called when Matterbridge load the plugin.
160
173
 
161
174
  ### async onConfigure()
162
175
 
163
- The method onConfigure() is where you can configure or initialize your device.
176
+ The method onConfigure() is where you can configure your matter device.
177
+
178
+ The method is called when the server node the platform belongs to is online.
164
179
 
165
- The method is called when the platform is commissioned.
180
+ Since the persistent attributes are loaded from the storage when the server node goes online, you may need to set them in onConfigure().
166
181
 
167
182
  ### async onShutdown(reason?: string)
168
183
 
169
- The method onShutdown() is where you have to eventually cleanup some resources.
184
+ The method onShutdown() is where you have to stop your platform and cleanup all the used resources.
185
+
186
+ The method is called when Matterbridge is shutting down or when the plugin is disabled.
187
+
188
+ Since the frontend can enable and disable the plugin many times, you need to clean all resources (i.e. handlers, intervals, timers...) here.
189
+
190
+ ### async onChangeLoggerLevel(logLevel: LogLevel)
191
+
192
+ It is called when the user changes the logger level in the frontend.
193
+
194
+ ### async onAction(action: string, value?: string, id?: string, formData?: PlatformConfig)
195
+
196
+ It is called when a plugin config includes an action button or an action button with text field.
197
+
198
+ ### async onConfigChanged(config: PlatformConfig)
199
+
200
+ It is called when the plugin config has been updated.
201
+
202
+ ### getDevices(): MatterbridgeEndpoint[]
203
+
204
+ Retrieves the devices registered with the platform.
205
+
206
+ ### hasDeviceName(deviceName: string): boolean
170
207
 
171
- The method is called when Matterbridge is shutting down.
208
+ Checks if a device with this name is already registered in the platform.
172
209
 
173
- ### async registerDevice(device: MatterbridgeDevice)
210
+ ### async registerDevice(device: MatterbridgeEndpoint)
174
211
 
175
- After you created your device, add it to the platform.
212
+ After you have created your device, add it to the platform.
176
213
 
177
- ### async unregisterDevice(device: MatterbridgeDevice)
214
+ ### async unregisterDevice(device: MatterbridgeEndpoint)
178
215
 
179
- You can unregister one or more device.
216
+ You can unregister a device.
180
217
 
181
218
  ### async unregisterAllDevices()
182
219
 
183
- You can unregister all devices you added.
220
+ You can unregister all the devices you added.
184
221
 
185
222
  It can be useful to call this method from onShutdown() if you don't want to keep all the devices during development.
186
223
 
187
- ## MatterbridgeDevice api
224
+ ## MatterbridgeEndpoint api
188
225
 
189
226
  Work in progress...
190
227
 
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  [![Docker Version](https://img.shields.io/docker/v/luligu/matterbridge?label=docker%20version&sort=semver)](https://hub.docker.com/r/luligu/matterbridge)
6
6
  [![Docker Pulls](https://img.shields.io/docker/pulls/luligu/matterbridge.svg)](https://hub.docker.com/r/luligu/matterbridge)
7
7
  ![Node.js CI](https://github.com/Luligu/matterbridge/actions/workflows/build.yml/badge.svg)
8
- ![Coverage](https://img.shields.io/badge/Jest%20coverage-88%25-brightgreen)
8
+ ![Coverage](https://img.shields.io/badge/Jest%20coverage-89%25-brightgreen)
9
9
 
10
10
  [![power by](https://img.shields.io/badge/powered%20by-matter--history-blue)](https://www.npmjs.com/package/matter-history)
11
11
  [![power by](https://img.shields.io/badge/powered%20by-node--ansi--logger-blue)](https://www.npmjs.com/package/node-ansi-logger)
@@ -22,10 +22,10 @@ The developer just focuses on the device development extending the provided clas
22
22
 
23
23
  Just pair Matterbridge once, and it will load all your registered plugins.
24
24
 
25
- This project aims to allow the porting of homebridge plugins to matterbridge plugins without recoding everything.
25
+ This project aims to allow the porting of homebridge plugins to matterbridge plugins without recoding everything ([Development](README-DEV.md)).
26
26
 
27
- It creates a device to pair in any ecosystem like Apple Home, Google Home, Amazon Alexa, or
28
- any other ecosystem supporting Matter like Home Assistant.
27
+ It creates a device to pair in any ecosystem like Apple Home, Google Home, Amazon Alexa, Home Assistant or
28
+ any other ecosystem supporting Matter.
29
29
 
30
30
  You don't need a hub or a dedicated new machine.
31
31
 
@@ -0,0 +1,4 @@
1
+ export * from '../roboticVacuumCleaner.js';
2
+ export * from '../laundryWasher.js';
3
+ export * from '../waterHeater.js';
4
+ export * from '../evse.js';
@@ -1598,10 +1598,10 @@ export class Matterbridge extends EventEmitter {
1598
1598
  }
1599
1599
  startEndAdvertiseTimer(matterServerNode) {
1600
1600
  if (this.endAdvertiseTimeout) {
1601
- this.log.debug(`***Clear ${matterServerNode.id} server node end advertise timer`);
1601
+ this.log.debug(`Clear ${matterServerNode.id} server node end advertise timer`);
1602
1602
  clearTimeout(this.endAdvertiseTimeout);
1603
1603
  }
1604
- this.log.debug(`***Starting ${matterServerNode.id} server node end advertise timer`);
1604
+ this.log.debug(`Starting ${matterServerNode.id} server node end advertise timer`);
1605
1605
  this.endAdvertiseTimeout = setTimeout(() => {
1606
1606
  if (matterServerNode.lifecycle.isCommissioned)
1607
1607
  return;
@@ -20,7 +20,6 @@ export class MatterbridgePlatform {
20
20
  ready;
21
21
  _registeredEndpoints = new Map();
22
22
  _registeredEndpointsByName = new Map();
23
- _storedDevices = new Map();
24
23
  constructor(matterbridge, log, config) {
25
24
  this.matterbridge = matterbridge;
26
25
  this.log = log;
@@ -76,7 +75,6 @@ export class MatterbridgePlatform {
76
75
  this.selectEntity.clear();
77
76
  this._registeredEndpoints.clear();
78
77
  this._registeredEndpointsByName.clear();
79
- this._storedDevices.clear();
80
78
  await this.context?.close();
81
79
  this.context = undefined;
82
80
  await this.storage?.close();
@@ -90,6 +88,9 @@ export class MatterbridgePlatform {
90
88
  async onConfigChanged(config) {
91
89
  this.log.debug(`The plugin ${CYAN}${config.name}${db} doesn't override onConfigChanged. Received new config.`);
92
90
  }
91
+ getDevices() {
92
+ return Array.from(this._registeredEndpoints.values());
93
+ }
93
94
  hasDeviceName(deviceName) {
94
95
  return this._registeredEndpointsByName.has(deviceName);
95
96
  }
@@ -207,9 +208,6 @@ export class MatterbridgePlatform {
207
208
  return false;
208
209
  return true;
209
210
  }
210
- validateDeviceWhiteBlackList(device, log = true) {
211
- return this.validateDevice(device, log);
212
- }
213
211
  validateDevice(device, log = true) {
214
212
  if (!Array.isArray(device))
215
213
  device = [device];
@@ -239,9 +237,6 @@ export class MatterbridgePlatform {
239
237
  this.log.info(`Skipping device ${CYAN}${device.join(', ')}${nf} because not in whitelist`);
240
238
  return false;
241
239
  }
242
- validateEntityBlackList(device, entity, log = true) {
243
- return this.validateEntity(device, entity, log);
244
- }
245
240
  validateEntity(device, entity, log = true) {
246
241
  if (isValidArray(this.config.entityBlackList, 1) && this.config.entityBlackList.find((e) => e === entity)) {
247
242
  if (log)
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "matterbridge",
3
- "version": "3.0.7-dev-20250614-0d145a8",
3
+ "version": "3.0.7-dev-20250616-cd7fd1c",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "matterbridge",
9
- "version": "3.0.7-dev-20250614-0d145a8",
9
+ "version": "3.0.7-dev-20250616-cd7fd1c",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "@matter/main": "0.14.0",
@@ -22,7 +22,7 @@
22
22
  "matterbridge": "dist/cli.js"
23
23
  },
24
24
  "engines": {
25
- "node": ">=18.0.0 <19.0.0 || >=20.0.0 <21.0.0 || >=22.0.0"
25
+ "node": ">=18.0.0 <19.0.0 || >=20.0.0 <21.0.0 || >=22.0.0 <23.0.0 || >=24.0.0 <25.0.0"
26
26
  },
27
27
  "funding": {
28
28
  "type": "buymeacoffee",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "matterbridge",
3
- "version": "3.0.7-dev-20250614-0d145a8",
3
+ "version": "3.0.7-dev-20250616-cd7fd1c",
4
4
  "description": "Matterbridge plugin manager for Matter",
5
5
  "author": "https://github.com/Luligu",
6
6
  "license": "Apache-2.0",
@@ -45,13 +45,33 @@
45
45
  "matterbridge": "dist/cli.js"
46
46
  },
47
47
  "engines": {
48
- "node": ">=18.0.0 <19.0.0 || >=20.0.0 <21.0.0 || >=22.0.0"
48
+ "node": ">=18.0.0 <19.0.0 || >=20.0.0 <21.0.0 || >=22.0.0 <23.0.0 || >=24.0.0 <25.0.0"
49
49
  },
50
50
  "exports": {
51
51
  ".": {
52
52
  "import": "./dist/index.js",
53
53
  "types": "./dist/index.d.ts"
54
54
  },
55
+ "./devices": {
56
+ "import": "./dist/devices/export.js",
57
+ "types": "./dist/devices/export.d.ts"
58
+ },
59
+ "./clusters": {
60
+ "import": "./dist/clusters/export.js",
61
+ "types": "./dist/clusters/export.d.ts"
62
+ },
63
+ "./utils": {
64
+ "import": "./dist/utils/export.js",
65
+ "types": "./dist/utils/export.d.ts"
66
+ },
67
+ "./logger": {
68
+ "import": "./dist/logger/export.js",
69
+ "types": "./dist/logger/export.d.ts"
70
+ },
71
+ "./storage": {
72
+ "import": "./dist/storage/export.js",
73
+ "types": "./dist/storage/export.d.ts"
74
+ },
55
75
  "./matter": {
56
76
  "import": "./dist/matter/export.js",
57
77
  "types": "./dist/matter/export.d.ts"
@@ -75,22 +95,6 @@
75
95
  "./matter/types": {
76
96
  "import": "./dist/matter/types.js",
77
97
  "types": "./dist/matter/types.d.ts"
78
- },
79
- "./cluster": {
80
- "import": "./dist/cluster/export.js",
81
- "types": "./dist/cluster/export.d.ts"
82
- },
83
- "./utils": {
84
- "import": "./dist/utils/export.js",
85
- "types": "./dist/utils/export.d.ts"
86
- },
87
- "./logger": {
88
- "import": "./dist/logger/export.js",
89
- "types": "./dist/logger/export.d.ts"
90
- },
91
- "./storage": {
92
- "import": "./dist/storage/export.js",
93
- "types": "./dist/storage/export.d.ts"
94
98
  }
95
99
  },
96
100
  "dependencies": {
File without changes