matterbridge 3.0.4-dev-20250525-b1cbfb7 → 3.0.5-dev-20250526-422f029
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 +16 -2
- package/dist/cli.js +14 -6
- package/dist/laundryWasher.js +122 -0
- package/dist/matterbridgeBehaviors.js +0 -2
- package/dist/matterbridgeEndpointHelpers.js +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,12 +8,26 @@ If you like this project and find it useful, please consider giving it a star on
|
|
|
8
8
|
<img src="bmc-button.svg" alt="Buy me a coffee" width="120">
|
|
9
9
|
</a>
|
|
10
10
|
|
|
11
|
-
## [3.0.
|
|
11
|
+
## [3.0.5] - 2025-05-??
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- [selectAreas]: Fixed MatterbridgeServiceAreaServer.selectAreas.
|
|
20
|
+
|
|
21
|
+
<a href="https://www.buymeacoffee.com/luligugithub">
|
|
22
|
+
<img src="bmc-button.svg" alt="Buy me a coffee" width="80">
|
|
23
|
+
</a>
|
|
24
|
+
|
|
25
|
+
## [3.0.4] - 2025-05-26
|
|
12
26
|
|
|
13
27
|
### Added
|
|
14
28
|
|
|
15
29
|
- [jsdoc]: Improved jsdoc for cluster helpers.
|
|
16
|
-
- [cover]: Added
|
|
30
|
+
- [cover]: Added createDefaultLiftTiltWindowCoveringClusterServer() that create a window covering cluser with both lift and tilt features (supported by Apple Home).
|
|
17
31
|
|
|
18
32
|
### Changed
|
|
19
33
|
|
package/dist/cli.js
CHANGED
|
@@ -100,12 +100,20 @@ async function stopCpuMemoryCheck() {
|
|
|
100
100
|
async function startInspector() {
|
|
101
101
|
const { Session } = await import('node:inspector');
|
|
102
102
|
log.debug(`Starting heap sampling...`);
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
103
|
+
try {
|
|
104
|
+
session = new Session();
|
|
105
|
+
session.connect();
|
|
106
|
+
await new Promise((resolve, reject) => {
|
|
107
|
+
session?.post('HeapProfiler.startSampling', (err) => (err ? reject(err) : resolve()));
|
|
108
|
+
});
|
|
109
|
+
log.debug(`Started heap sampling`);
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
log.error(`Failed to start heap sampling: ${err instanceof Error ? err.message : err}`);
|
|
113
|
+
session?.disconnect();
|
|
114
|
+
session = undefined;
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
109
117
|
}
|
|
110
118
|
async function stopInspector() {
|
|
111
119
|
const { writeFileSync } = await import('node:fs');
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { OperationalState } from '@matter/main/clusters/operational-state';
|
|
2
|
+
import { LaundryWasherControls } from '@matter/main/clusters/laundry-washer-controls';
|
|
3
|
+
import { LaundryWasherMode } from '@matter/main/clusters/laundry-washer-mode';
|
|
4
|
+
import { TemperatureControl } from '@matter/main/clusters/temperature-control';
|
|
5
|
+
import { ModeBase } from '@matter/main/clusters/mode-base';
|
|
6
|
+
import { TemperatureControlServer } from '@matter/main/behaviors/temperature-control';
|
|
7
|
+
import { LaundryWasherModeServer } from '@matter/main/behaviors/laundry-washer-mode';
|
|
8
|
+
import { LaundryWasherControlsServer } from '@matter/main/behaviors/laundry-washer-controls';
|
|
9
|
+
import { laundryWasher } from './matterbridgeDeviceTypes.js';
|
|
10
|
+
import { MatterbridgeEndpoint } from './matterbridgeEndpoint.js';
|
|
11
|
+
import { MatterbridgeOnOffServer, MatterbridgeServer } from './matterbridgeBehaviors.js';
|
|
12
|
+
export class LaundryWasher extends MatterbridgeEndpoint {
|
|
13
|
+
constructor(name, serial) {
|
|
14
|
+
super(laundryWasher, { uniqueStorageKey: `${name.replaceAll(' ', '')}-${serial.replaceAll(' ', '')}` }, true);
|
|
15
|
+
this.createDefaultIdentifyClusterServer();
|
|
16
|
+
this.createDefaultBasicInformationClusterServer(name, serial, 0xfff1, 'Matterbridge', 0x8000, 'Matterbridge Laundry Washer');
|
|
17
|
+
this.createDefaultPowerSourceWiredClusterServer();
|
|
18
|
+
this.createDeadFrontOnOffClusterServer();
|
|
19
|
+
this.createLevelTemperatureControlClusterServer(3, ['Cold', '30°', '40°', '60°', '80°']);
|
|
20
|
+
this.createDefaultLaundryWasherControlsClusterServer();
|
|
21
|
+
this.createDefaultLaundryWasherModeClusterServer();
|
|
22
|
+
this.createDefaultOperationalStateClusterServer(OperationalState.OperationalStateEnum.Stopped);
|
|
23
|
+
}
|
|
24
|
+
createDefaultLaundryWasherControlsClusterServer(spinSpeedCurrent = 3, spinSpeeds = ['400', '800', '1200', '1600'], numberOfRinses = LaundryWasherControls.NumberOfRinses.Normal, supportedRinses = [LaundryWasherControls.NumberOfRinses.None, LaundryWasherControls.NumberOfRinses.Normal, LaundryWasherControls.NumberOfRinses.Max, LaundryWasherControls.NumberOfRinses.Extra]) {
|
|
25
|
+
this.behaviors.require(LaundryWasherControlsServer.with(LaundryWasherControls.Feature.Spin, LaundryWasherControls.Feature.Rinse), {
|
|
26
|
+
spinSpeeds,
|
|
27
|
+
spinSpeedCurrent,
|
|
28
|
+
supportedRinses,
|
|
29
|
+
numberOfRinses,
|
|
30
|
+
});
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
createDefaultLaundryWasherModeClusterServer(currentMode = 2, supportedModes = [
|
|
34
|
+
{ label: 'Delicate', mode: 1, modeTags: [{ value: LaundryWasherMode.ModeTag.Delicate }] },
|
|
35
|
+
{ label: 'Normal', mode: 2, modeTags: [{ value: LaundryWasherMode.ModeTag.Normal }] },
|
|
36
|
+
{ label: 'Heavy', mode: 3, modeTags: [{ value: LaundryWasherMode.ModeTag.Heavy }] },
|
|
37
|
+
{ label: 'Whites', mode: 4, modeTags: [{ value: LaundryWasherMode.ModeTag.Whites }] },
|
|
38
|
+
]) {
|
|
39
|
+
this.behaviors.require(MatterbridgeLaundryWasherModeServer, {
|
|
40
|
+
supportedModes,
|
|
41
|
+
currentMode,
|
|
42
|
+
});
|
|
43
|
+
return this;
|
|
44
|
+
}
|
|
45
|
+
createLevelTemperatureControlClusterServer(selectedTemperatureLevel = 1, supportedTemperatureLevels = ['Cold', 'Warm', 'Hot']) {
|
|
46
|
+
this.behaviors.require(MatterbridgeLevelTemperatureControlServer.with(TemperatureControl.Feature.TemperatureLevel), {
|
|
47
|
+
selectedTemperatureLevel,
|
|
48
|
+
supportedTemperatureLevels,
|
|
49
|
+
});
|
|
50
|
+
return this;
|
|
51
|
+
}
|
|
52
|
+
createNumberTemperatureControlClusterServer(temperatureSetpoint = 40 * 100, minTemperature = 30 * 100, maxTemperature = 60 * 100, step = 10 * 100) {
|
|
53
|
+
this.behaviors.require(MatterbridgeNumberTemperatureControlServer.with(TemperatureControl.Feature.TemperatureNumber, TemperatureControl.Feature.TemperatureStep), {
|
|
54
|
+
temperatureSetpoint,
|
|
55
|
+
minTemperature,
|
|
56
|
+
maxTemperature,
|
|
57
|
+
step,
|
|
58
|
+
});
|
|
59
|
+
return this;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
class MatterbridgeLevelTemperatureControlServer extends TemperatureControlServer.with(TemperatureControl.Feature.TemperatureLevel) {
|
|
63
|
+
initialize() {
|
|
64
|
+
if (this.state.supportedTemperatureLevels.length >= 2) {
|
|
65
|
+
const device = this.endpoint.stateOf(MatterbridgeServer).deviceCommand;
|
|
66
|
+
device.log.info('MatterbridgeLevelTemperatureControlServer initialized');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
setTemperature(request) {
|
|
70
|
+
const device = this.endpoint.stateOf(MatterbridgeServer).deviceCommand;
|
|
71
|
+
if (request.targetTemperatureLevel !== undefined && request.targetTemperatureLevel >= 0 && request.targetTemperatureLevel < this.state.supportedTemperatureLevels.length) {
|
|
72
|
+
device.log.info(`MatterbridgeLevelTemperatureControlServer: setTemperature called setting selectedTemperatureLevel to ${request.targetTemperatureLevel}: ${this.state.supportedTemperatureLevels[request.targetTemperatureLevel]}`);
|
|
73
|
+
this.state.selectedTemperatureLevel = request.targetTemperatureLevel;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
device.log.error(`MatterbridgeLevelTemperatureControlServer: setTemperature called with invalid targetTemperatureLevel ${request.targetTemperatureLevel}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
class MatterbridgeNumberTemperatureControlServer extends TemperatureControlServer.with(TemperatureControl.Feature.TemperatureNumber) {
|
|
81
|
+
initialize() {
|
|
82
|
+
const device = this.endpoint.stateOf(MatterbridgeServer).deviceCommand;
|
|
83
|
+
device.log.info('MatterbridgeNumberTemperatureControlServer initialized');
|
|
84
|
+
}
|
|
85
|
+
setTemperature(request) {
|
|
86
|
+
const device = this.endpoint.stateOf(MatterbridgeServer).deviceCommand;
|
|
87
|
+
if (request.targetTemperature !== undefined && request.targetTemperature >= this.state.minTemperature && request.targetTemperature <= this.state.maxTemperature) {
|
|
88
|
+
device.log.info(`MatterbridgeNumberTemperatureControlServer: setTemperature called setting temperatureSetpoint to ${request.targetTemperature}`);
|
|
89
|
+
this.state.temperatureSetpoint = request.targetTemperature;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
device.log.error(`MatterbridgeNumberTemperatureControlServer: setTemperature called with invalid targetTemperature ${request.targetTemperature}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
class MatterbridgeLaundryWasherModeServer extends LaundryWasherModeServer {
|
|
97
|
+
initialize() {
|
|
98
|
+
const device = this.endpoint.stateOf(MatterbridgeServer).deviceCommand;
|
|
99
|
+
device.log.info(`LaundryWasherModeServer initialized: currentMode is ${this.state.currentMode}`);
|
|
100
|
+
this.reactTo(this.agent.get(MatterbridgeOnOffServer).events.onOff$Changed, this.handleOnOffChange);
|
|
101
|
+
}
|
|
102
|
+
handleOnOffChange(onOff) {
|
|
103
|
+
const device = this.endpoint.stateOf(MatterbridgeServer).deviceCommand;
|
|
104
|
+
if (onOff === false) {
|
|
105
|
+
device.log.notice('OnOffServer changed to OFF: setting Dead Front state to Manufacturer Specific');
|
|
106
|
+
this.state.currentMode = 2;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
changeToMode(request) {
|
|
110
|
+
const device = this.endpoint.stateOf(MatterbridgeServer).deviceCommand;
|
|
111
|
+
const supportedMode = this.state.supportedModes.find((supportedMode) => supportedMode.mode === request.newMode);
|
|
112
|
+
if (supportedMode) {
|
|
113
|
+
device.log.info(`LaundryWasherModeServer: changeToMode called with mode ${supportedMode.mode} = ${supportedMode.label}`);
|
|
114
|
+
this.state.currentMode = request.newMode;
|
|
115
|
+
return { status: ModeBase.ModeChangeStatus.Success, statusText: 'Success' };
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
device.log.error(`LaundryWasherModeServer: changeToMode called with invalid mode ${request.newMode}`);
|
|
119
|
+
return { status: ModeBase.ModeChangeStatus.InvalidInMode, statusText: 'Invalid mode' };
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -581,9 +581,7 @@ export class MatterbridgeServiceAreaServer extends ServiceAreaServer {
|
|
|
581
581
|
}
|
|
582
582
|
device.selectAreas({ newAreas });
|
|
583
583
|
this.state.selectedAreas = newAreas;
|
|
584
|
-
this.state.currentArea = newAreas[0];
|
|
585
584
|
device.log.info(`MatterbridgeServiceAreaServer selectAreas called with: ${newAreas.map((area) => area.toString()).join(', ')}`);
|
|
586
|
-
device.selectAreas({ newAreas });
|
|
587
585
|
return { status: ServiceArea.SelectAreasStatus.Success, statusText: 'Succesfully selected new areas' };
|
|
588
586
|
}
|
|
589
587
|
}
|
|
@@ -384,7 +384,7 @@ export function getClusterId(endpoint, cluster) {
|
|
|
384
384
|
}
|
|
385
385
|
export function getAttributeId(endpoint, cluster, attribute) {
|
|
386
386
|
const clusterBehavior = endpoint.behaviors.supported[lowercaseFirstLetter(cluster)];
|
|
387
|
-
return clusterBehavior?.cluster
|
|
387
|
+
return clusterBehavior?.cluster?.attributes[lowercaseFirstLetter(attribute)]?.id;
|
|
388
388
|
}
|
|
389
389
|
export function getAttribute(endpoint, cluster, attribute, log) {
|
|
390
390
|
const clusterName = getBehavior(endpoint, cluster)?.id;
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "matterbridge",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.5-dev-20250526-422f029",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "matterbridge",
|
|
9
|
-
"version": "3.0.
|
|
9
|
+
"version": "3.0.5-dev-20250526-422f029",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@matter/main": "0.13.0",
|
package/package.json
CHANGED