@matterbridge/core 3.10.8-dev-20260831-e73fc65 → 3.10.8-dev-20260901-c4963a1
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/doorLockServer.js +2 -3
- package/dist/behaviors/thermostatServer.js +19 -19
- package/dist/behaviors/windowCoveringServer.d.ts +13 -3
- package/dist/behaviors/windowCoveringServer.js +115 -19
- package/dist/demoDevices.js +18 -6
- package/dist/matterNode.js +10 -1
- package/dist/matterbridge.js +10 -1
- package/dist/matterbridgeEndpoint.d.ts +3 -2
- package/dist/matterbridgeEndpoint.js +36 -8
- package/package.json +5 -5
|
@@ -122,11 +122,10 @@ export class MatterbridgeDoorLockServer extends DoorLockServer.with(DoorLock.Fea
|
|
|
122
122
|
context: this.context,
|
|
123
123
|
});
|
|
124
124
|
device.log.debug(`MatterbridgeDoorLockServer: setCredential called for userIndex ${request.userIndex} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
125
|
-
|
|
126
|
-
if (auth.isDuplicateCredential(request.credential.credentialType, request.credentialData, request.credential.credentialIndex)) {
|
|
125
|
+
if (this.auth.isDuplicateCredential(request.credential.credentialType, request.credentialData, request.credential.credentialIndex)) {
|
|
127
126
|
throw new DoorLock.DuplicateError(`MatterbridgeDoorLockServer: credential data duplicates another credential of the same type (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
128
127
|
}
|
|
129
|
-
if (request.operationType === DoorLock.DataOperationType.Add && auth.findCredential(request.credential.credentialType, request.credential.credentialIndex)) {
|
|
128
|
+
if (request.operationType === DoorLock.DataOperationType.Add && this.auth.findCredential(request.credential.credentialType, request.credential.credentialIndex)) {
|
|
130
129
|
throw new DoorLock.OccupiedError(`MatterbridgeDoorLockServer: add operation targets an occupied credential index (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
131
130
|
}
|
|
132
131
|
return await super.setCredential(request);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Bytes } from '@matter/general';
|
|
2
2
|
import { ThermostatServer } from '@matter/node/behaviors/thermostat';
|
|
3
|
-
import {
|
|
3
|
+
import { Status, StatusResponseError } from '@matter/types';
|
|
4
4
|
import { Thermostat } from '@matter/types/clusters/thermostat';
|
|
5
5
|
import { MatterbridgeServer } from './matterbridgeServer.js';
|
|
6
6
|
export class MatterbridgeThermostatServer extends ThermostatServer.with(Thermostat.Feature.Cooling, Thermostat.Feature.Heating, Thermostat.Feature.AutoMode, Thermostat.Feature.Presets, Thermostat.Feature.MatterScheduleConfiguration, Thermostat.Feature.ThermostatSuggestions) {
|
|
@@ -30,18 +30,18 @@ export class MatterbridgeThermostatServer extends ThermostatServer.with(Thermost
|
|
|
30
30
|
return;
|
|
31
31
|
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
32
32
|
if (remainingSuggestions.length !== currentSuggestions.length) {
|
|
33
|
-
device.log.info(`
|
|
33
|
+
device.log.info(`MatterbridgeThermostatServer: removing ${currentSuggestions.length - remainingSuggestions.length} thermostat suggestion(s) referencing removed preset(s) (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
34
34
|
this.state.thermostatSuggestions = remainingSuggestions;
|
|
35
35
|
}
|
|
36
36
|
if (clearCurrentSuggestion) {
|
|
37
|
-
device.log.info(`
|
|
37
|
+
device.log.info(`MatterbridgeThermostatServer: clearing current thermostat suggestion referencing a removed preset (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
38
38
|
this.state.currentThermostatSuggestion = null;
|
|
39
39
|
this.state.thermostatSuggestionNotFollowingReason = null;
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
async setpointRaiseLower(request) {
|
|
43
43
|
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
44
|
-
device.log.info(`
|
|
44
|
+
device.log.info(`MatterbridgeThermostatServer: setting setpoint by ${request.amount} in mode ${request.mode} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
45
45
|
await device.commandHandler.executeHandler('Thermostat.setpointRaiseLower', {
|
|
46
46
|
command: 'setpointRaiseLower',
|
|
47
47
|
request,
|
|
@@ -51,13 +51,13 @@ export class MatterbridgeThermostatServer extends ThermostatServer.with(Thermost
|
|
|
51
51
|
context: this.context,
|
|
52
52
|
});
|
|
53
53
|
const lookupSetpointAdjustMode = ['Heat', 'Cool', 'Both'];
|
|
54
|
-
device.log.debug(`MatterbridgeThermostatServer: setpointRaiseLower called with mode: ${lookupSetpointAdjustMode[request.mode]} amount: ${request.amount / 10}`);
|
|
54
|
+
device.log.debug(`MatterbridgeThermostatServer: setpointRaiseLower called with mode: ${lookupSetpointAdjustMode[request.mode]} amount: ${request.amount / 10} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
55
55
|
await super.setpointRaiseLower(request);
|
|
56
56
|
}
|
|
57
57
|
async setActivePresetRequest(request) {
|
|
58
58
|
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
59
59
|
const presetHandle = request.presetHandle ? `0x${Buffer.from(request.presetHandle).toString('hex')}` : 'null';
|
|
60
|
-
device.log.info(`
|
|
60
|
+
device.log.info(`MatterbridgeThermostatServer: setting preset to ${presetHandle} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
61
61
|
await device.commandHandler.executeHandler('Thermostat.setActivePresetRequest', {
|
|
62
62
|
command: 'setActivePresetRequest',
|
|
63
63
|
request,
|
|
@@ -66,15 +66,15 @@ export class MatterbridgeThermostatServer extends ThermostatServer.with(Thermost
|
|
|
66
66
|
endpoint: this.endpoint,
|
|
67
67
|
context: this.context,
|
|
68
68
|
});
|
|
69
|
-
device.log.debug(`MatterbridgeThermostatServer: setActivePresetRequest called with presetHandle: ${presetHandle}`);
|
|
69
|
+
device.log.debug(`MatterbridgeThermostatServer: setActivePresetRequest called with presetHandle: ${presetHandle} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
70
70
|
await super.setActivePresetRequest(request);
|
|
71
71
|
const activePresetHandle = this.state.activePresetHandle ? `0x${Buffer.from(this.state.activePresetHandle).toString('hex')}` : 'null';
|
|
72
|
-
device.log.debug(`MatterbridgeThermostatServer: setActivePresetRequest completed with activePresetHandle: ${activePresetHandle} occupiedHeatingSetpoint: ${this.state.occupiedHeatingSetpoint} occupiedCoolingSetpoint: ${this.state.occupiedCoolingSetpoint}`);
|
|
72
|
+
device.log.debug(`MatterbridgeThermostatServer: setActivePresetRequest completed with activePresetHandle: ${activePresetHandle} occupiedHeatingSetpoint: ${this.state.occupiedHeatingSetpoint} occupiedCoolingSetpoint: ${this.state.occupiedCoolingSetpoint} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
73
73
|
}
|
|
74
74
|
async setActiveScheduleRequest(request) {
|
|
75
75
|
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
76
76
|
const scheduleHandle = `0x${Buffer.from(request.scheduleHandle).toString('hex')}`;
|
|
77
|
-
device.log.info(`
|
|
77
|
+
device.log.info(`MatterbridgeThermostatServer: setting schedule to ${scheduleHandle} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
78
78
|
await device.commandHandler.executeHandler('Thermostat.setActiveScheduleRequest', {
|
|
79
79
|
command: 'setActiveScheduleRequest',
|
|
80
80
|
request,
|
|
@@ -85,10 +85,10 @@ export class MatterbridgeThermostatServer extends ThermostatServer.with(Thermost
|
|
|
85
85
|
});
|
|
86
86
|
const schedule = this.state.schedules.find((s) => s.scheduleHandle !== null && Bytes.areEqual(s.scheduleHandle, request.scheduleHandle));
|
|
87
87
|
if (schedule === undefined) {
|
|
88
|
-
throw new
|
|
88
|
+
throw new StatusResponseError(`MatterbridgeThermostatServer: requested ScheduleHandle not found (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`, Status.InvalidCommand);
|
|
89
89
|
}
|
|
90
90
|
this.state.activeScheduleHandle = Uint8Array.from(request.scheduleHandle);
|
|
91
|
-
device.log.debug(`MatterbridgeThermostatServer: setActiveScheduleRequest completed with activeScheduleHandle: ${scheduleHandle}`);
|
|
91
|
+
device.log.debug(`MatterbridgeThermostatServer: setActiveScheduleRequest completed with activeScheduleHandle: ${scheduleHandle} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
92
92
|
}
|
|
93
93
|
removeExpiredThermostatSuggestions() {
|
|
94
94
|
const now = Math.floor(Date.now() / 1000);
|
|
@@ -112,7 +112,7 @@ export class MatterbridgeThermostatServer extends ThermostatServer.with(Thermost
|
|
|
112
112
|
async addThermostatSuggestion(request) {
|
|
113
113
|
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
114
114
|
const presetHandle = `0x${Buffer.from(request.presetHandle).toString('hex')}`;
|
|
115
|
-
device.log.info(`
|
|
115
|
+
device.log.info(`MatterbridgeThermostatServer: adding thermostat suggestion for preset ${presetHandle} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
116
116
|
await device.commandHandler.executeHandler('Thermostat.addThermostatSuggestion', {
|
|
117
117
|
command: 'addThermostatSuggestion',
|
|
118
118
|
request,
|
|
@@ -122,17 +122,17 @@ export class MatterbridgeThermostatServer extends ThermostatServer.with(Thermost
|
|
|
122
122
|
context: this.context,
|
|
123
123
|
});
|
|
124
124
|
if (this.state.presets.find((p) => p.presetHandle !== null && Bytes.areEqual(p.presetHandle, request.presetHandle)) === undefined) {
|
|
125
|
-
throw new
|
|
125
|
+
throw new StatusResponseError(`MatterbridgeThermostatServer: requested PresetHandle not found (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`, Status.NotFound);
|
|
126
126
|
}
|
|
127
127
|
this.removeExpiredThermostatSuggestions();
|
|
128
128
|
this.reEvaluateCurrentThermostatSuggestion();
|
|
129
129
|
if (this.state.thermostatSuggestions.length >= this.state.maxThermostatSuggestions) {
|
|
130
|
-
throw new
|
|
130
|
+
throw new StatusResponseError(`MatterbridgeThermostatServer: maximum number of thermostat suggestions reached (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`, Status.ResourceExhausted);
|
|
131
131
|
}
|
|
132
132
|
const currentTime = Math.floor(Date.now() / 1000);
|
|
133
133
|
const effectiveTime = request.effectiveTime ?? currentTime;
|
|
134
134
|
if (effectiveTime > currentTime + 24 * 60 * 60) {
|
|
135
|
-
throw new
|
|
135
|
+
throw new StatusResponseError(`MatterbridgeThermostatServer: requested EffectiveTime is more than 24 hours in the future (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`, Status.InvalidCommand);
|
|
136
136
|
}
|
|
137
137
|
const usedUniqueIds = new Set(this.state.thermostatSuggestions.map((s) => s.uniqueId));
|
|
138
138
|
let uniqueId = 0;
|
|
@@ -146,12 +146,12 @@ export class MatterbridgeThermostatServer extends ThermostatServer.with(Thermost
|
|
|
146
146
|
};
|
|
147
147
|
this.state.thermostatSuggestions = [...this.state.thermostatSuggestions, suggestion];
|
|
148
148
|
this.reEvaluateCurrentThermostatSuggestion();
|
|
149
|
-
device.log.debug(`MatterbridgeThermostatServer: addThermostatSuggestion completed with uniqueId: ${uniqueId}`);
|
|
149
|
+
device.log.debug(`MatterbridgeThermostatServer: addThermostatSuggestion completed with uniqueId: ${uniqueId} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
150
150
|
return { uniqueId };
|
|
151
151
|
}
|
|
152
152
|
async removeThermostatSuggestion(request) {
|
|
153
153
|
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
154
|
-
device.log.info(`
|
|
154
|
+
device.log.info(`MatterbridgeThermostatServer: removing thermostat suggestion ${request.uniqueId} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
155
155
|
await device.commandHandler.executeHandler('Thermostat.removeThermostatSuggestion', {
|
|
156
156
|
command: 'removeThermostatSuggestion',
|
|
157
157
|
request,
|
|
@@ -162,11 +162,11 @@ export class MatterbridgeThermostatServer extends ThermostatServer.with(Thermost
|
|
|
162
162
|
});
|
|
163
163
|
const suggestion = this.state.thermostatSuggestions.find((s) => s.uniqueId === request.uniqueId);
|
|
164
164
|
if (suggestion === undefined) {
|
|
165
|
-
throw new
|
|
165
|
+
throw new StatusResponseError(`MatterbridgeThermostatServer: requested UniqueID not found (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`, Status.NotFound);
|
|
166
166
|
}
|
|
167
167
|
this.state.thermostatSuggestions = this.state.thermostatSuggestions.filter((s) => s.uniqueId !== request.uniqueId);
|
|
168
168
|
this.removeExpiredThermostatSuggestions();
|
|
169
169
|
this.reEvaluateCurrentThermostatSuggestion();
|
|
170
|
-
device.log.debug(`MatterbridgeThermostatServer: removeThermostatSuggestion completed for uniqueId: ${request.uniqueId}`);
|
|
170
|
+
device.log.debug(`MatterbridgeThermostatServer: removeThermostatSuggestion completed for uniqueId: ${request.uniqueId} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
171
171
|
}
|
|
172
172
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { WindowCoveringBaseServer, WindowCoveringServer } from '@matter/node/behaviors/window-covering';
|
|
2
2
|
import { WindowCovering } from '@matter/types/clusters/window-covering';
|
|
3
3
|
declare const MatterbridgeWindowCoveringServer_base: import("@matter/node").ClusterBehavior.Type<typeof WindowCoveringServer, import("@matter/types").ClusterType.WithSupportedFeatures<WindowCovering, {
|
|
4
4
|
lift: true;
|
|
@@ -7,7 +7,9 @@ declare const MatterbridgeWindowCoveringServer_base: import("@matter/node").Clus
|
|
|
7
7
|
tilt: true;
|
|
8
8
|
}>, import("@matter/types").ClusterType.Concrete, typeof WindowCoveringBaseServer.Internal, "windowCovering">;
|
|
9
9
|
export declare class MatterbridgeWindowCoveringServer extends MatterbridgeWindowCoveringServer_base {
|
|
10
|
-
|
|
10
|
+
#private;
|
|
11
|
+
readonly state: MatterbridgeWindowCoveringServer.State;
|
|
12
|
+
protected internal: MatterbridgeWindowCoveringServer.Internal;
|
|
11
13
|
lookupMovementStatus: string[];
|
|
12
14
|
private getMovementStatusLabel;
|
|
13
15
|
initialize(): void;
|
|
@@ -16,6 +18,14 @@ export declare class MatterbridgeWindowCoveringServer extends MatterbridgeWindow
|
|
|
16
18
|
stopMotion(): Promise<void>;
|
|
17
19
|
goToLiftPercentage(request: WindowCovering.GoToLiftPercentageRequest): Promise<void>;
|
|
18
20
|
goToTiltPercentage(request: WindowCovering.GoToTiltPercentageRequest): Promise<void>;
|
|
19
|
-
|
|
21
|
+
}
|
|
22
|
+
export declare namespace MatterbridgeWindowCoveringServer {
|
|
23
|
+
class Internal extends WindowCoveringBaseServer.Internal {
|
|
24
|
+
liftMovementTimer?: NodeJS.Timeout;
|
|
25
|
+
tiltMovementTimer?: NodeJS.Timeout;
|
|
26
|
+
}
|
|
27
|
+
class State extends WindowCoveringBaseServer.State {
|
|
28
|
+
movementDuration: number;
|
|
29
|
+
}
|
|
20
30
|
}
|
|
21
31
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { WindowCoveringServer } from '@matter/node/behaviors/window-covering';
|
|
1
|
+
import { WindowCoveringBaseServer, WindowCoveringServer } from '@matter/node/behaviors/window-covering';
|
|
2
2
|
import { WindowCovering } from '@matter/types/clusters/window-covering';
|
|
3
3
|
import { MatterbridgeServer } from './matterbridgeServer.js';
|
|
4
4
|
export class MatterbridgeWindowCoveringServer extends WindowCoveringServer.with(WindowCovering.Feature.Lift, WindowCovering.Feature.PositionAwareLift, WindowCovering.Feature.Tilt, WindowCovering.Feature.PositionAwareTilt) {
|
|
@@ -8,13 +8,77 @@ export class MatterbridgeWindowCoveringServer extends WindowCoveringServer.with(
|
|
|
8
8
|
}
|
|
9
9
|
initialize() {
|
|
10
10
|
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
11
|
-
device.log.info(`
|
|
11
|
+
device.log.info(`MatterbridgeWindowCoveringServer: initializing (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
12
12
|
this.internal.disableOperationalModeHandling = true;
|
|
13
|
+
if (process.env.MATTERBRIDGE_CHIP_TEST) {
|
|
14
|
+
this.state.movementDuration = 3000;
|
|
15
|
+
}
|
|
13
16
|
super.initialize();
|
|
17
|
+
if (this.features.positionAwareLift)
|
|
18
|
+
this.reactTo(this.events.currentPositionLiftPercent100ths$Changing, this.#syncLiftCurrentPositionPercentage);
|
|
19
|
+
if (this.features.positionAwareTilt)
|
|
20
|
+
this.reactTo(this.events.currentPositionTiltPercent100ths$Changing, this.#syncTiltCurrentPositionPercentage);
|
|
14
21
|
}
|
|
22
|
+
#syncLiftCurrentPositionPercentage(percent100ths) {
|
|
23
|
+
this.state.currentPositionLiftPercentage = percent100ths === null ? percent100ths : Math.floor(percent100ths / 100);
|
|
24
|
+
}
|
|
25
|
+
#syncTiltCurrentPositionPercentage(percent100ths) {
|
|
26
|
+
this.state.currentPositionTiltPercentage = percent100ths === null ? percent100ths : Math.floor(percent100ths / 100);
|
|
27
|
+
}
|
|
28
|
+
#computeMovementStatus(target, current) {
|
|
29
|
+
if (current === null || target === null || current === target)
|
|
30
|
+
return WindowCovering.MovementStatus.Stopped;
|
|
31
|
+
return current < target ? WindowCovering.MovementStatus.Closing : WindowCovering.MovementStatus.Opening;
|
|
32
|
+
}
|
|
33
|
+
#updateGlobalOperationalStatus() {
|
|
34
|
+
const { lift, tilt } = this.state.operationalStatus;
|
|
35
|
+
this.state.operationalStatus.global = lift === WindowCovering.MovementStatus.Stopped ? tilt : lift;
|
|
36
|
+
}
|
|
37
|
+
#startLiftMovement(targetPercent100ths) {
|
|
38
|
+
clearTimeout(this.internal.liftMovementTimer);
|
|
39
|
+
this.internal.liftMovementTimer = undefined;
|
|
40
|
+
if (this.state.movementDuration <= 0)
|
|
41
|
+
return;
|
|
42
|
+
const status = this.#computeMovementStatus(targetPercent100ths, this.state.currentPositionLiftPercent100ths);
|
|
43
|
+
this.state.operationalStatus.lift = status;
|
|
44
|
+
this.#updateGlobalOperationalStatus();
|
|
45
|
+
if (status === WindowCovering.MovementStatus.Stopped)
|
|
46
|
+
return;
|
|
47
|
+
this.internal.liftMovementTimer = setTimeout(() => {
|
|
48
|
+
this.internal.liftMovementTimer = undefined;
|
|
49
|
+
void this.#completeLiftMovement(targetPercent100ths);
|
|
50
|
+
}, this.state.movementDuration);
|
|
51
|
+
}
|
|
52
|
+
#completeLiftMovement = async (targetPercent100ths) => {
|
|
53
|
+
const windowCovering = this.endpoint;
|
|
54
|
+
await windowCovering.setAttribute(WindowCovering, 'currentPositionLiftPercent100ths', targetPercent100ths);
|
|
55
|
+
const tilt = windowCovering.getAttribute(WindowCovering, 'operationalStatus')?.tilt ?? WindowCovering.MovementStatus.Stopped;
|
|
56
|
+
await windowCovering.setAttribute(WindowCovering, 'operationalStatus', { global: tilt, lift: WindowCovering.MovementStatus.Stopped, tilt });
|
|
57
|
+
};
|
|
58
|
+
#startTiltMovement(targetPercent100ths) {
|
|
59
|
+
clearTimeout(this.internal.tiltMovementTimer);
|
|
60
|
+
this.internal.tiltMovementTimer = undefined;
|
|
61
|
+
if (this.state.movementDuration <= 0)
|
|
62
|
+
return;
|
|
63
|
+
const status = this.#computeMovementStatus(targetPercent100ths, this.state.currentPositionTiltPercent100ths);
|
|
64
|
+
this.state.operationalStatus.tilt = status;
|
|
65
|
+
this.#updateGlobalOperationalStatus();
|
|
66
|
+
if (status === WindowCovering.MovementStatus.Stopped)
|
|
67
|
+
return;
|
|
68
|
+
this.internal.tiltMovementTimer = setTimeout(() => {
|
|
69
|
+
this.internal.tiltMovementTimer = undefined;
|
|
70
|
+
void this.#completeTiltMovement(targetPercent100ths);
|
|
71
|
+
}, this.state.movementDuration);
|
|
72
|
+
}
|
|
73
|
+
#completeTiltMovement = async (targetPercent100ths) => {
|
|
74
|
+
const windowCovering = this.endpoint;
|
|
75
|
+
await windowCovering.setAttribute(WindowCovering, 'currentPositionTiltPercent100ths', targetPercent100ths);
|
|
76
|
+
const lift = windowCovering.getAttribute(WindowCovering, 'operationalStatus')?.lift ?? WindowCovering.MovementStatus.Stopped;
|
|
77
|
+
await windowCovering.setAttribute(WindowCovering, 'operationalStatus', { global: lift, lift, tilt: WindowCovering.MovementStatus.Stopped });
|
|
78
|
+
};
|
|
15
79
|
async upOrOpen() {
|
|
16
80
|
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
17
|
-
device.log.info(`
|
|
81
|
+
device.log.info(`MatterbridgeWindowCoveringServer: opening cover (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
18
82
|
await device.commandHandler.executeHandler('WindowCovering.upOrOpen', {
|
|
19
83
|
command: 'upOrOpen',
|
|
20
84
|
request: {},
|
|
@@ -23,13 +87,17 @@ export class MatterbridgeWindowCoveringServer extends WindowCoveringServer.with(
|
|
|
23
87
|
endpoint: this.endpoint,
|
|
24
88
|
context: this.context,
|
|
25
89
|
});
|
|
26
|
-
device.log.debug(`MatterbridgeWindowCoveringServer: upOrOpen called`);
|
|
90
|
+
device.log.debug(`MatterbridgeWindowCoveringServer: upOrOpen called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
27
91
|
await super.upOrOpen();
|
|
28
|
-
|
|
92
|
+
if (this.features.positionAwareLift && this.state.targetPositionLiftPercent100ths !== null)
|
|
93
|
+
this.#startLiftMovement(this.state.targetPositionLiftPercent100ths);
|
|
94
|
+
if (this.features.positionAwareTilt && this.state.targetPositionTiltPercent100ths !== null)
|
|
95
|
+
this.#startTiltMovement(this.state.targetPositionTiltPercent100ths);
|
|
96
|
+
device.log.debug(`MatterbridgeWindowCoveringServer: upOrOpen result target ${this.state.targetPositionLiftPercent100ths} current ${this.state.currentPositionLiftPercent100ths} status global ${this.getMovementStatusLabel(this.state.operationalStatus.global)} lift ${this.getMovementStatusLabel(this.state.operationalStatus.lift)} tilt ${this.getMovementStatusLabel(this.state.operationalStatus.tilt)} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
29
97
|
}
|
|
30
98
|
async downOrClose() {
|
|
31
99
|
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
32
|
-
device.log.info(`
|
|
100
|
+
device.log.info(`MatterbridgeWindowCoveringServer: closing cover (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
33
101
|
await device.commandHandler.executeHandler('WindowCovering.downOrClose', {
|
|
34
102
|
command: 'downOrClose',
|
|
35
103
|
request: {},
|
|
@@ -38,13 +106,17 @@ export class MatterbridgeWindowCoveringServer extends WindowCoveringServer.with(
|
|
|
38
106
|
endpoint: this.endpoint,
|
|
39
107
|
context: this.context,
|
|
40
108
|
});
|
|
41
|
-
device.log.debug(`MatterbridgeWindowCoveringServer: downOrClose called`);
|
|
109
|
+
device.log.debug(`MatterbridgeWindowCoveringServer: downOrClose called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
42
110
|
await super.downOrClose();
|
|
43
|
-
|
|
111
|
+
if (this.features.positionAwareLift && this.state.targetPositionLiftPercent100ths !== null)
|
|
112
|
+
this.#startLiftMovement(this.state.targetPositionLiftPercent100ths);
|
|
113
|
+
if (this.features.positionAwareTilt && this.state.targetPositionTiltPercent100ths !== null)
|
|
114
|
+
this.#startTiltMovement(this.state.targetPositionTiltPercent100ths);
|
|
115
|
+
device.log.debug(`MatterbridgeWindowCoveringServer: downOrClose result target ${this.state.targetPositionLiftPercent100ths} current ${this.state.currentPositionLiftPercent100ths} status global ${this.getMovementStatusLabel(this.state.operationalStatus.global)} lift ${this.getMovementStatusLabel(this.state.operationalStatus.lift)} tilt ${this.getMovementStatusLabel(this.state.operationalStatus.tilt)} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
44
116
|
}
|
|
45
117
|
async stopMotion() {
|
|
46
118
|
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
47
|
-
device.log.info(`
|
|
119
|
+
device.log.info(`MatterbridgeWindowCoveringServer: stopping cover (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
48
120
|
await device.commandHandler.executeHandler('WindowCovering.stopMotion', {
|
|
49
121
|
command: 'stopMotion',
|
|
50
122
|
request: {},
|
|
@@ -53,13 +125,24 @@ export class MatterbridgeWindowCoveringServer extends WindowCoveringServer.with(
|
|
|
53
125
|
endpoint: this.endpoint,
|
|
54
126
|
context: this.context,
|
|
55
127
|
});
|
|
56
|
-
device.log.debug(`MatterbridgeWindowCoveringServer: stopMotion called`);
|
|
128
|
+
device.log.debug(`MatterbridgeWindowCoveringServer: stopMotion called (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
57
129
|
await super.stopMotion();
|
|
58
|
-
|
|
130
|
+
clearTimeout(this.internal.liftMovementTimer);
|
|
131
|
+
this.internal.liftMovementTimer = undefined;
|
|
132
|
+
clearTimeout(this.internal.tiltMovementTimer);
|
|
133
|
+
this.internal.tiltMovementTimer = undefined;
|
|
134
|
+
if (this.state.movementDuration > 0) {
|
|
135
|
+
if (this.features.positionAwareLift)
|
|
136
|
+
this.state.targetPositionLiftPercent100ths = this.state.currentPositionLiftPercent100ths;
|
|
137
|
+
if (this.features.positionAwareTilt)
|
|
138
|
+
this.state.targetPositionTiltPercent100ths = this.state.currentPositionTiltPercent100ths;
|
|
139
|
+
this.state.operationalStatus = { global: WindowCovering.MovementStatus.Stopped, lift: WindowCovering.MovementStatus.Stopped, tilt: WindowCovering.MovementStatus.Stopped };
|
|
140
|
+
}
|
|
141
|
+
device.log.debug(`MatterbridgeWindowCoveringServer: stopMotion result target ${this.state.targetPositionLiftPercent100ths} current ${this.state.currentPositionLiftPercent100ths} status global ${this.getMovementStatusLabel(this.state.operationalStatus.global)} lift ${this.getMovementStatusLabel(this.state.operationalStatus.lift)} tilt ${this.getMovementStatusLabel(this.state.operationalStatus.tilt)} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
59
142
|
}
|
|
60
143
|
async goToLiftPercentage(request) {
|
|
61
144
|
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
62
|
-
device.log.info(`
|
|
145
|
+
device.log.info(`MatterbridgeWindowCoveringServer: setting cover lift percentage to ${request.liftPercent100thsValue} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
63
146
|
await device.commandHandler.executeHandler('WindowCovering.goToLiftPercentage', {
|
|
64
147
|
command: 'goToLiftPercentage',
|
|
65
148
|
request,
|
|
@@ -68,13 +151,15 @@ export class MatterbridgeWindowCoveringServer extends WindowCoveringServer.with(
|
|
|
68
151
|
endpoint: this.endpoint,
|
|
69
152
|
context: this.context,
|
|
70
153
|
});
|
|
71
|
-
device.log.debug(`MatterbridgeWindowCoveringServer: goToLiftPercentage with ${request.liftPercent100thsValue}`);
|
|
154
|
+
device.log.debug(`MatterbridgeWindowCoveringServer: goToLiftPercentage with ${request.liftPercent100thsValue} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
72
155
|
await super.goToLiftPercentage(request);
|
|
73
|
-
|
|
156
|
+
if (this.state.targetPositionLiftPercent100ths !== null)
|
|
157
|
+
this.#startLiftMovement(this.state.targetPositionLiftPercent100ths);
|
|
158
|
+
device.log.debug(`MatterbridgeWindowCoveringServer: goToLiftPercentage result target ${this.state.targetPositionLiftPercent100ths} current ${this.state.currentPositionLiftPercent100ths} status global ${this.getMovementStatusLabel(this.state.operationalStatus.global)} lift ${this.getMovementStatusLabel(this.state.operationalStatus.lift)} tilt ${this.getMovementStatusLabel(this.state.operationalStatus.tilt)} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
74
159
|
}
|
|
75
160
|
async goToTiltPercentage(request) {
|
|
76
161
|
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
77
|
-
device.log.info(`
|
|
162
|
+
device.log.info(`MatterbridgeWindowCoveringServer: setting cover tilt percentage to ${request.tiltPercent100thsValue} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
78
163
|
await device.commandHandler.executeHandler('WindowCovering.goToTiltPercentage', {
|
|
79
164
|
command: 'goToTiltPercentage',
|
|
80
165
|
request,
|
|
@@ -83,10 +168,21 @@ export class MatterbridgeWindowCoveringServer extends WindowCoveringServer.with(
|
|
|
83
168
|
endpoint: this.endpoint,
|
|
84
169
|
context: this.context,
|
|
85
170
|
});
|
|
86
|
-
device.log.debug(`MatterbridgeWindowCoveringServer: goToTiltPercentage with ${request.tiltPercent100thsValue}`);
|
|
171
|
+
device.log.debug(`MatterbridgeWindowCoveringServer: goToTiltPercentage with ${request.tiltPercent100thsValue} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
87
172
|
await super.goToTiltPercentage(request);
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
173
|
+
if (this.state.targetPositionTiltPercent100ths !== null)
|
|
174
|
+
this.#startTiltMovement(this.state.targetPositionTiltPercent100ths);
|
|
175
|
+
device.log.debug(`MatterbridgeWindowCoveringServer: goToTiltPercentage result target ${this.state.targetPositionTiltPercent100ths} current ${this.state.currentPositionTiltPercent100ths} status global ${this.getMovementStatusLabel(this.state.operationalStatus.global)} lift ${this.getMovementStatusLabel(this.state.operationalStatus.lift)} tilt ${this.getMovementStatusLabel(this.state.operationalStatus.tilt)} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
91
176
|
}
|
|
92
177
|
}
|
|
178
|
+
(function (MatterbridgeWindowCoveringServer) {
|
|
179
|
+
class Internal extends WindowCoveringBaseServer.Internal {
|
|
180
|
+
liftMovementTimer;
|
|
181
|
+
tiltMovementTimer;
|
|
182
|
+
}
|
|
183
|
+
MatterbridgeWindowCoveringServer.Internal = Internal;
|
|
184
|
+
class State extends WindowCoveringBaseServer.State {
|
|
185
|
+
movementDuration = 0;
|
|
186
|
+
}
|
|
187
|
+
MatterbridgeWindowCoveringServer.State = State;
|
|
188
|
+
})(MatterbridgeWindowCoveringServer || (MatterbridgeWindowCoveringServer = {}));
|
package/dist/demoDevices.js
CHANGED
|
@@ -10,6 +10,7 @@ import { PowerTopology } from '@matter/types/clusters/power-topology';
|
|
|
10
10
|
import { ResourceMonitoring } from '@matter/types/clusters/resource-monitoring';
|
|
11
11
|
import { RvcCleanMode } from '@matter/types/clusters/rvc-clean-mode';
|
|
12
12
|
import { RvcRunMode } from '@matter/types/clusters/rvc-run-mode';
|
|
13
|
+
import { Thermostat } from '@matter/types/clusters/thermostat';
|
|
13
14
|
import { EndpointNumber } from '@matter/types/datatype';
|
|
14
15
|
import { getErrorMessage } from '@matterbridge/utils/error';
|
|
15
16
|
import { AirConditioner } from './devices/airConditioner.js';
|
|
@@ -348,11 +349,15 @@ export async function createDemoDevices(matterbridge) {
|
|
|
348
349
|
await registerDevice(ep, 'Door Lock User PIN Schedules', 'ENTRY-08-01-2');
|
|
349
350
|
ep = new MatterbridgeEndpoint([getSupportedDeviceType('DoorLockController'), bridgedNode, powerSource], { id: 'DoorLockController', number: EndpointNumber(8_02) });
|
|
350
351
|
await registerDevice(ep, 'Door Lock Controller', 'ENTRY-08-02');
|
|
351
|
-
ep = new MatterbridgeEndpoint([getSupportedDeviceType('WindowCovering'), bridgedNode, powerSource], { id: '
|
|
352
|
-
|
|
352
|
+
ep = new MatterbridgeEndpoint([getSupportedDeviceType('WindowCovering'), bridgedNode, powerSource], { id: 'WindowCoveringLift', number: EndpointNumber(8_03) });
|
|
353
|
+
ep.createDefaultWindowCoveringClusterServer();
|
|
354
|
+
await registerDevice(ep, 'Window Covering Lift', 'ENTRY-08-03');
|
|
353
355
|
ep = new MatterbridgeEndpoint([getSupportedDeviceType('WindowCovering'), bridgedNode, powerSource], { id: 'WindowCoveringTilt', number: EndpointNumber(8_03_1) });
|
|
354
|
-
ep.
|
|
356
|
+
ep.createDefaultTiltWindowCoveringClusterServer();
|
|
355
357
|
await registerDevice(ep, 'Window Covering Tilt', 'ENTRY-08-03-1');
|
|
358
|
+
ep = new MatterbridgeEndpoint([getSupportedDeviceType('WindowCovering'), bridgedNode, powerSource], { id: 'WindowCoveringLiftTilt', number: EndpointNumber(8_03_2) });
|
|
359
|
+
ep.createDefaultLiftTiltWindowCoveringClusterServer();
|
|
360
|
+
await registerDevice(ep, 'Window Covering LiftTilt', 'ENTRY-08-03-2');
|
|
356
361
|
ep = new MatterbridgeEndpoint([getSupportedDeviceType('WindowCoveringController'), bridgedNode, powerSource], { id: 'WindowCoveringController', number: EndpointNumber(8_04) });
|
|
357
362
|
await registerDevice(ep, 'Window Covering Controller', 'ENTRY-08-04');
|
|
358
363
|
ep = new Closure('Closure', 'ENTRY-08-05', {
|
|
@@ -443,8 +448,9 @@ export async function createDemoDevices(matterbridge) {
|
|
|
443
448
|
await registerDevice(ep, 'Closure Panel Smart-Glass', 'ENTRY-08-06-5');
|
|
444
449
|
ep = new MatterbridgeEndpoint([getSupportedDeviceType('ClosureController'), bridgedNode, powerSource], { id: 'ClosureController', number: EndpointNumber(8_07) });
|
|
445
450
|
await registerDevice(ep, 'Closure Controller', 'ENTRY-08-07');
|
|
446
|
-
ep = new MatterbridgeEndpoint([getSupportedDeviceType('Thermostat'), bridgedNode, powerSource], { id: '
|
|
447
|
-
|
|
451
|
+
ep = new MatterbridgeEndpoint([getSupportedDeviceType('Thermostat'), bridgedNode, powerSource], { id: 'ThermostatAuto', number: EndpointNumber(9_01) });
|
|
452
|
+
ep.createDefaultThermostatClusterServer(23, 21, 25, 2, 0, 47, 3, 50);
|
|
453
|
+
await registerDevice(ep, 'Thermostat Auto', 'HVAC-09-01');
|
|
448
454
|
ep = new MatterbridgeEndpoint([getSupportedDeviceType('Thermostat'), bridgedNode, powerSource], { id: 'ThermostatHeating', number: EndpointNumber(9_01_1) });
|
|
449
455
|
ep.createDefaultHeatingThermostatClusterServer();
|
|
450
456
|
await registerDevice(ep, 'Thermostat Heating', 'HVAC-09-01-1');
|
|
@@ -458,7 +464,13 @@ export async function createDemoDevices(matterbridge) {
|
|
|
458
464
|
ep.createDefaultSchedulesThermostatClusterServer();
|
|
459
465
|
await registerDevice(ep, 'Thermostat Schedules', 'HVAC-09-01-4');
|
|
460
466
|
ep = new MatterbridgeEndpoint([getSupportedDeviceType('Thermostat'), bridgedNode, powerSource], { id: 'ThermostatSuggestions', number: EndpointNumber(9_01_5) });
|
|
461
|
-
ep.createDefaultThermostatSuggestionsClusterServer(
|
|
467
|
+
ep.createDefaultThermostatSuggestionsClusterServer(23, 21, 25, 0, 0, 50, 0, 50, undefined, undefined, undefined, undefined, null, [
|
|
468
|
+
{ presetHandle: Uint8Array.from([0]), presetScenario: Thermostat.PresetScenario.Occupied, name: 'Occupied', coolingSetpoint: 2500, heatingSetpoint: 2100, builtIn: true },
|
|
469
|
+
{ presetHandle: Uint8Array.from([1]), presetScenario: Thermostat.PresetScenario.Unoccupied, name: 'Unoccupied', coolingSetpoint: 2700, heatingSetpoint: 1900, builtIn: true },
|
|
470
|
+
], [
|
|
471
|
+
{ presetScenario: Thermostat.PresetScenario.Occupied, numberOfPresets: 4, presetTypeFeatures: { automatic: false, supportsNames: true } },
|
|
472
|
+
{ presetScenario: Thermostat.PresetScenario.Unoccupied, numberOfPresets: 4, presetTypeFeatures: { automatic: false, supportsNames: true } },
|
|
473
|
+
]);
|
|
462
474
|
await registerDevice(ep, 'Thermostat Suggestions', 'HVAC-09-01-5');
|
|
463
475
|
ep = new MatterbridgeEndpoint([getSupportedDeviceType('Fan'), bridgedNode, powerSource], { id: 'Fan', number: EndpointNumber(9_02) });
|
|
464
476
|
await registerDevice(ep, 'Fan OffLowMedHighAuto', 'HVAC-09-02');
|
package/dist/matterNode.js
CHANGED
|
@@ -407,7 +407,16 @@ export class MatterNode extends EventEmitter {
|
|
|
407
407
|
this.log.warn(`Invalid discriminator ${discriminator} for server node ${storeId}. Discriminator must be between 0 and 4095 (0xFFF). Generating a random discriminator...`);
|
|
408
408
|
discriminator = PaseClient.generateRandomDiscriminator(this.environment.get(Crypto));
|
|
409
409
|
}
|
|
410
|
-
|
|
410
|
+
let rootEndpoint;
|
|
411
|
+
if (hasParameter('root-power-source') || process.env.MATTERBRIDGE_CHIP_TEST) {
|
|
412
|
+
this.log.warn(' ****************************************************************************************');
|
|
413
|
+
this.log.warn(' * Adding the PowerSource cluster server to the root endpoint. *');
|
|
414
|
+
this.log.warn(' ****************************************************************************************');
|
|
415
|
+
rootEndpoint = ServerNode.RootEndpoint.with(PowerSourceServer.with(PowerSource.Feature.Wired));
|
|
416
|
+
}
|
|
417
|
+
else {
|
|
418
|
+
rootEndpoint = ServerNode.RootEndpoint;
|
|
419
|
+
}
|
|
411
420
|
const serverNode = await ServerNode.create(rootEndpoint, {
|
|
412
421
|
id: storeId,
|
|
413
422
|
environment: this.environment,
|
package/dist/matterbridge.js
CHANGED
|
@@ -1893,7 +1893,16 @@ export class Matterbridge extends EventEmitter {
|
|
|
1893
1893
|
this.log.warn(`Invalid discriminator ${discriminator} for server node ${storeId}. Discriminator must be between 0 and 4095 (0xFFF). Generating a random discriminator...`);
|
|
1894
1894
|
discriminator = PaseClient.generateRandomDiscriminator(this.environment.get(Crypto));
|
|
1895
1895
|
}
|
|
1896
|
-
let rootEndpoint
|
|
1896
|
+
let rootEndpoint;
|
|
1897
|
+
if (hasParameter('root-power-source') || process.env.MATTERBRIDGE_CHIP_TEST) {
|
|
1898
|
+
this.log.warn(' ****************************************************************************************');
|
|
1899
|
+
this.log.warn(' * Adding the PowerSource cluster server to the root endpoint. *');
|
|
1900
|
+
this.log.warn(' ****************************************************************************************');
|
|
1901
|
+
rootEndpoint = ServerNode.RootEndpoint.with(PowerSourceServer.with(PowerSource.Feature.Wired));
|
|
1902
|
+
}
|
|
1903
|
+
else {
|
|
1904
|
+
rootEndpoint = ServerNode.RootEndpoint;
|
|
1905
|
+
}
|
|
1897
1906
|
if (process.env.MATTERBRIDGE_CHIP_TEST && fs.existsSync(path.join(path.dirname(fileURLToPath(import.meta.url)), 'chipTests.js'))) {
|
|
1898
1907
|
this.log.warn(' ****************************************************************************************');
|
|
1899
1908
|
this.log.warn(' * MATTERBRIDGE_CHIP_TEST environment variable is set. Running TestEventTrigger server. *');
|
|
@@ -171,8 +171,9 @@ export declare class MatterbridgeEndpoint extends Endpoint {
|
|
|
171
171
|
createCtColorControlClusterServer(colorTemperatureMireds?: number, colorTempPhysicalMinMireds?: number, colorTempPhysicalMaxMireds?: number): this;
|
|
172
172
|
configureColorControlMode(colorMode: ColorControl.ColorMode): Promise<void>;
|
|
173
173
|
configureEnhancedColorControlMode(colorMode: ColorControl.EnhancedColorMode): Promise<void>;
|
|
174
|
-
createDefaultWindowCoveringClusterServer(positionPercent100ths?: number, type?: WindowCovering.WindowCoveringType, endProductType?: WindowCovering.EndProductType): this;
|
|
175
|
-
createDefaultLiftTiltWindowCoveringClusterServer(positionLiftPercent100ths?: number, positionTiltPercent100ths?: number, type?: WindowCovering.WindowCoveringType, endProductType?: WindowCovering.EndProductType): this;
|
|
174
|
+
createDefaultWindowCoveringClusterServer(positionPercent100ths?: number | null, type?: WindowCovering.WindowCoveringType, endProductType?: WindowCovering.EndProductType, movementDuration?: number): this;
|
|
175
|
+
createDefaultLiftTiltWindowCoveringClusterServer(positionLiftPercent100ths?: number | null, positionTiltPercent100ths?: number | null, type?: WindowCovering.WindowCoveringType, endProductType?: WindowCovering.EndProductType, movementDuration?: number): this;
|
|
176
|
+
createDefaultTiltWindowCoveringClusterServer(positionTiltPercent100ths?: number | null, type?: WindowCovering.WindowCoveringType, endProductType?: WindowCovering.EndProductType, movementDuration?: number): this;
|
|
176
177
|
setWindowCoveringTargetAsCurrentAndStopped(): Promise<void>;
|
|
177
178
|
setWindowCoveringCurrentTargetStatus(current: number, target: number, status: WindowCovering.MovementStatus): Promise<void>;
|
|
178
179
|
setWindowCoveringStatus(status: WindowCovering.MovementStatus): Promise<void>;
|
|
@@ -825,7 +825,7 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
825
825
|
await this.setAttribute(ColorControl.id, 'enhancedColorMode', colorMode, this.log);
|
|
826
826
|
}
|
|
827
827
|
}
|
|
828
|
-
createDefaultWindowCoveringClusterServer(positionPercent100ths, type = WindowCovering.WindowCoveringType.Rollershade, endProductType = WindowCovering.EndProductType.RollerShade) {
|
|
828
|
+
createDefaultWindowCoveringClusterServer(positionPercent100ths = 0, type = WindowCovering.WindowCoveringType.Rollershade, endProductType = WindowCovering.EndProductType.RollerShade, movementDuration = 0) {
|
|
829
829
|
this.behaviors.require(MatterbridgeWindowCoveringServer.with(WindowCovering.Feature.Lift, WindowCovering.Feature.PositionAwareLift), {
|
|
830
830
|
type,
|
|
831
831
|
numberOfActuationsLift: 0,
|
|
@@ -841,12 +841,14 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
841
841
|
operationalStatus: { global: WindowCovering.MovementStatus.Stopped, lift: WindowCovering.MovementStatus.Stopped, tilt: WindowCovering.MovementStatus.Stopped },
|
|
842
842
|
endProductType,
|
|
843
843
|
mode: { motorDirectionReversed: false, calibrationMode: false, maintenanceMode: false, ledFeedback: false },
|
|
844
|
-
targetPositionLiftPercent100ths: positionPercent100ths
|
|
845
|
-
currentPositionLiftPercent100ths: positionPercent100ths
|
|
844
|
+
targetPositionLiftPercent100ths: positionPercent100ths,
|
|
845
|
+
currentPositionLiftPercent100ths: positionPercent100ths,
|
|
846
|
+
currentPositionLiftPercentage: positionPercent100ths === null ? null : Math.floor(positionPercent100ths / 100),
|
|
847
|
+
movementDuration,
|
|
846
848
|
});
|
|
847
849
|
return this;
|
|
848
850
|
}
|
|
849
|
-
createDefaultLiftTiltWindowCoveringClusterServer(positionLiftPercent100ths, positionTiltPercent100ths, type = WindowCovering.WindowCoveringType.TiltBlindLift, endProductType = WindowCovering.EndProductType.InteriorBlind) {
|
|
851
|
+
createDefaultLiftTiltWindowCoveringClusterServer(positionLiftPercent100ths = 0, positionTiltPercent100ths = 0, type = WindowCovering.WindowCoveringType.TiltBlindLift, endProductType = WindowCovering.EndProductType.InteriorBlind, movementDuration = 0) {
|
|
850
852
|
this.behaviors.require(MatterbridgeWindowCoveringServer.with(WindowCovering.Feature.Lift, WindowCovering.Feature.PositionAwareLift, WindowCovering.Feature.Tilt, WindowCovering.Feature.PositionAwareTilt), {
|
|
851
853
|
type,
|
|
852
854
|
numberOfActuationsLift: 0,
|
|
@@ -863,10 +865,36 @@ export class MatterbridgeEndpoint extends Endpoint {
|
|
|
863
865
|
operationalStatus: { global: WindowCovering.MovementStatus.Stopped, lift: WindowCovering.MovementStatus.Stopped, tilt: WindowCovering.MovementStatus.Stopped },
|
|
864
866
|
endProductType,
|
|
865
867
|
mode: { motorDirectionReversed: false, calibrationMode: false, maintenanceMode: false, ledFeedback: false },
|
|
866
|
-
targetPositionLiftPercent100ths: positionLiftPercent100ths
|
|
867
|
-
currentPositionLiftPercent100ths: positionLiftPercent100ths
|
|
868
|
-
|
|
869
|
-
|
|
868
|
+
targetPositionLiftPercent100ths: positionLiftPercent100ths,
|
|
869
|
+
currentPositionLiftPercent100ths: positionLiftPercent100ths,
|
|
870
|
+
currentPositionLiftPercentage: positionLiftPercent100ths === null ? null : Math.floor(positionLiftPercent100ths / 100),
|
|
871
|
+
targetPositionTiltPercent100ths: positionTiltPercent100ths,
|
|
872
|
+
currentPositionTiltPercent100ths: positionTiltPercent100ths,
|
|
873
|
+
currentPositionTiltPercentage: positionTiltPercent100ths === null ? null : Math.floor(positionTiltPercent100ths / 100),
|
|
874
|
+
movementDuration,
|
|
875
|
+
});
|
|
876
|
+
return this;
|
|
877
|
+
}
|
|
878
|
+
createDefaultTiltWindowCoveringClusterServer(positionTiltPercent100ths = 0, type = WindowCovering.WindowCoveringType.TiltBlindTiltOnly, endProductType = WindowCovering.EndProductType.InteriorVenetianBlind, movementDuration = 0) {
|
|
879
|
+
this.behaviors.require(MatterbridgeWindowCoveringServer.with(WindowCovering.Feature.Tilt, WindowCovering.Feature.PositionAwareTilt), {
|
|
880
|
+
type,
|
|
881
|
+
numberOfActuationsTilt: 0,
|
|
882
|
+
configStatus: {
|
|
883
|
+
operational: true,
|
|
884
|
+
onlineReserved: false,
|
|
885
|
+
liftMovementReversed: false,
|
|
886
|
+
liftPositionAware: false,
|
|
887
|
+
tiltPositionAware: true,
|
|
888
|
+
liftEncoderControlled: false,
|
|
889
|
+
tiltEncoderControlled: false,
|
|
890
|
+
},
|
|
891
|
+
operationalStatus: { global: WindowCovering.MovementStatus.Stopped, lift: WindowCovering.MovementStatus.Stopped, tilt: WindowCovering.MovementStatus.Stopped },
|
|
892
|
+
endProductType,
|
|
893
|
+
mode: { motorDirectionReversed: false, calibrationMode: false, maintenanceMode: false, ledFeedback: false },
|
|
894
|
+
targetPositionTiltPercent100ths: positionTiltPercent100ths,
|
|
895
|
+
currentPositionTiltPercent100ths: positionTiltPercent100ths,
|
|
896
|
+
currentPositionTiltPercentage: positionTiltPercent100ths === null ? null : Math.floor(positionTiltPercent100ths / 100),
|
|
897
|
+
movementDuration,
|
|
870
898
|
});
|
|
871
899
|
return this;
|
|
872
900
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matterbridge/core",
|
|
3
|
-
"version": "3.10.8-dev-
|
|
3
|
+
"version": "3.10.8-dev-20260901-c4963a1",
|
|
4
4
|
"description": "Matterbridge core library",
|
|
5
5
|
"author": "https://github.com/Luligu",
|
|
6
6
|
"homepage": "https://matterbridge.io/",
|
|
@@ -132,10 +132,10 @@
|
|
|
132
132
|
},
|
|
133
133
|
"dependencies": {
|
|
134
134
|
"@matter/main": "0.17.9",
|
|
135
|
-
"@matterbridge/dgram": "3.10.8-dev-
|
|
136
|
-
"@matterbridge/thread": "3.10.8-dev-
|
|
137
|
-
"@matterbridge/types": "3.10.8-dev-
|
|
138
|
-
"@matterbridge/utils": "3.10.8-dev-
|
|
135
|
+
"@matterbridge/dgram": "3.10.8-dev-20260901-c4963a1",
|
|
136
|
+
"@matterbridge/thread": "3.10.8-dev-20260901-c4963a1",
|
|
137
|
+
"@matterbridge/types": "3.10.8-dev-20260901-c4963a1",
|
|
138
|
+
"@matterbridge/utils": "3.10.8-dev-20260901-c4963a1",
|
|
139
139
|
"escape-html": "1.0.3",
|
|
140
140
|
"express": "5.2.1",
|
|
141
141
|
"express-rate-limit": "8.7.0",
|