@matter/node 0.16.0-alpha.0-20251101-70c8d51d7 → 0.16.0-alpha.0-20251103-b47ffa15b
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/cjs/behavior/Behavior.d.ts +2 -2
- package/dist/cjs/behavior/Behavior.d.ts.map +1 -1
- package/dist/cjs/behavior/Behavior.js +1 -1
- package/dist/cjs/behavior/Behavior.js.map +1 -1
- package/dist/cjs/behavior/Events.js.map +1 -1
- package/dist/cjs/behavior/cluster/ClusterBehavior.d.ts +3 -2
- package/dist/cjs/behavior/cluster/ClusterBehavior.d.ts.map +1 -1
- package/dist/cjs/behavior/cluster/ClusterBehavior.js.map +1 -1
- package/dist/cjs/behavior/cluster/ClusterBehaviorUtil.js +1 -1
- package/dist/cjs/behavior/cluster/ClusterBehaviorUtil.js.map +1 -1
- package/dist/cjs/behavior/internal/BehaviorBacking.js +1 -1
- package/dist/cjs/behavior/internal/BehaviorBacking.js.map +1 -1
- package/dist/cjs/behavior/system/mqtt/MqttInterface.js +1 -1
- package/dist/cjs/behavior/system/mqtt/MqttInterface.js.map +1 -1
- package/dist/cjs/behaviors/basic-information/BasicInformationServer.d.ts +2 -2
- package/dist/cjs/behaviors/basic-information/BasicInformationServer.d.ts.map +1 -1
- package/dist/cjs/behaviors/basic-information/BasicInformationServer.js +0 -3
- package/dist/cjs/behaviors/basic-information/BasicInformationServer.js.map +1 -1
- package/dist/cjs/behaviors/bridged-device-basic-information/BridgedDeviceBasicInformationServer.d.ts +1 -1
- package/dist/cjs/behaviors/bridged-device-basic-information/BridgedDeviceBasicInformationServer.d.ts.map +1 -1
- package/dist/cjs/behaviors/color-control/ColorControlServer.d.ts +3 -3
- package/dist/cjs/behaviors/color-control/ColorControlServer.d.ts.map +1 -1
- package/dist/cjs/behaviors/color-control/ColorControlServer.js +118 -3
- package/dist/cjs/behaviors/color-control/ColorControlServer.js.map +1 -1
- package/dist/cjs/behaviors/general-diagnostics/GeneralDiagnosticsServer.d.ts +1 -1
- package/dist/cjs/behaviors/general-diagnostics/GeneralDiagnosticsServer.d.ts.map +1 -1
- package/dist/cjs/behaviors/general-diagnostics/GeneralDiagnosticsServer.js.map +1 -1
- package/dist/cjs/behaviors/group-key-management/GroupKeyManagementServer.d.ts +1 -1
- package/dist/cjs/behaviors/group-key-management/GroupKeyManagementServer.d.ts.map +1 -1
- package/dist/cjs/behaviors/group-key-management/GroupKeyManagementServer.js.map +1 -1
- package/dist/cjs/behaviors/groups/GroupsServer.d.ts.map +1 -1
- package/dist/cjs/behaviors/groups/GroupsServer.js +9 -1
- package/dist/cjs/behaviors/groups/GroupsServer.js.map +1 -1
- package/dist/cjs/behaviors/level-control/LevelControlServer.d.ts +5 -5
- package/dist/cjs/behaviors/level-control/LevelControlServer.d.ts.map +1 -1
- package/dist/cjs/behaviors/level-control/LevelControlServer.js +54 -27
- package/dist/cjs/behaviors/level-control/LevelControlServer.js.map +1 -1
- package/dist/cjs/behaviors/on-off/OnOffServer.d.ts +3 -6
- package/dist/cjs/behaviors/on-off/OnOffServer.d.ts.map +1 -1
- package/dist/cjs/behaviors/on-off/OnOffServer.js +59 -7
- package/dist/cjs/behaviors/on-off/OnOffServer.js.map +1 -1
- package/dist/cjs/behaviors/scenes-management/ScenesManagementServer.d.ts +122 -3
- package/dist/cjs/behaviors/scenes-management/ScenesManagementServer.d.ts.map +1 -1
- package/dist/cjs/behaviors/scenes-management/ScenesManagementServer.js +909 -1
- package/dist/cjs/behaviors/scenes-management/ScenesManagementServer.js.map +2 -2
- package/dist/cjs/behaviors/switch/SwitchServer.d.ts +1 -1
- package/dist/cjs/behaviors/switch/SwitchServer.d.ts.map +1 -1
- package/dist/cjs/behaviors/switch/SwitchServer.js.map +1 -1
- package/dist/cjs/behaviors/thermostat/AtomicWriteHandler.js +2 -2
- package/dist/cjs/behaviors/thermostat/AtomicWriteHandler.js.map +1 -1
- package/dist/cjs/behaviors/thermostat/ThermostatServer.d.ts +1 -1
- package/dist/cjs/behaviors/thermostat/ThermostatServer.d.ts.map +1 -1
- package/dist/cjs/behaviors/thermostat/ThermostatServer.js.map +1 -1
- package/dist/cjs/devices/color-temperature-light.d.ts +4 -4
- package/dist/cjs/devices/dimmable-light.d.ts +4 -4
- package/dist/cjs/devices/dimmable-plug-in-unit.d.ts +4 -4
- package/dist/cjs/devices/extended-color-light.d.ts +4 -4
- package/dist/cjs/devices/mounted-dimmable-load-control.d.ts +4 -4
- package/dist/cjs/devices/mounted-on-off-control.d.ts +4 -4
- package/dist/cjs/devices/on-off-light.d.ts +4 -4
- package/dist/cjs/devices/on-off-plug-in-unit.d.ts +4 -4
- package/dist/cjs/endpoint/Agent.d.ts +5 -0
- package/dist/cjs/endpoint/Agent.d.ts.map +1 -1
- package/dist/cjs/endpoint/Agent.js +9 -0
- package/dist/cjs/endpoint/Agent.js.map +1 -1
- package/dist/cjs/endpoint/properties/Behaviors.js +1 -1
- package/dist/cjs/endpoint/properties/Behaviors.js.map +1 -1
- package/dist/cjs/node/integration/ProtocolService.js +1 -1
- package/dist/cjs/node/integration/ProtocolService.js.map +1 -1
- package/dist/esm/behavior/Behavior.d.ts +2 -2
- package/dist/esm/behavior/Behavior.d.ts.map +1 -1
- package/dist/esm/behavior/Behavior.js +1 -1
- package/dist/esm/behavior/Behavior.js.map +1 -1
- package/dist/esm/behavior/Events.js.map +1 -1
- package/dist/esm/behavior/cluster/ClusterBehavior.d.ts +3 -2
- package/dist/esm/behavior/cluster/ClusterBehavior.d.ts.map +1 -1
- package/dist/esm/behavior/cluster/ClusterBehavior.js.map +1 -1
- package/dist/esm/behavior/cluster/ClusterBehaviorUtil.js +1 -1
- package/dist/esm/behavior/cluster/ClusterBehaviorUtil.js.map +1 -1
- package/dist/esm/behavior/internal/BehaviorBacking.js +1 -1
- package/dist/esm/behavior/internal/BehaviorBacking.js.map +1 -1
- package/dist/esm/behavior/system/mqtt/MqttInterface.js +1 -1
- package/dist/esm/behavior/system/mqtt/MqttInterface.js.map +1 -1
- package/dist/esm/behaviors/basic-information/BasicInformationServer.d.ts +2 -2
- package/dist/esm/behaviors/basic-information/BasicInformationServer.d.ts.map +1 -1
- package/dist/esm/behaviors/basic-information/BasicInformationServer.js +1 -4
- package/dist/esm/behaviors/basic-information/BasicInformationServer.js.map +1 -1
- package/dist/esm/behaviors/bridged-device-basic-information/BridgedDeviceBasicInformationServer.d.ts +1 -1
- package/dist/esm/behaviors/bridged-device-basic-information/BridgedDeviceBasicInformationServer.d.ts.map +1 -1
- package/dist/esm/behaviors/color-control/ColorControlServer.d.ts +3 -3
- package/dist/esm/behaviors/color-control/ColorControlServer.d.ts.map +1 -1
- package/dist/esm/behaviors/color-control/ColorControlServer.js +118 -3
- package/dist/esm/behaviors/color-control/ColorControlServer.js.map +1 -1
- package/dist/esm/behaviors/general-diagnostics/GeneralDiagnosticsServer.d.ts +1 -1
- package/dist/esm/behaviors/general-diagnostics/GeneralDiagnosticsServer.d.ts.map +1 -1
- package/dist/esm/behaviors/general-diagnostics/GeneralDiagnosticsServer.js.map +1 -1
- package/dist/esm/behaviors/group-key-management/GroupKeyManagementServer.d.ts +1 -1
- package/dist/esm/behaviors/group-key-management/GroupKeyManagementServer.d.ts.map +1 -1
- package/dist/esm/behaviors/group-key-management/GroupKeyManagementServer.js.map +1 -1
- package/dist/esm/behaviors/groups/GroupsServer.d.ts.map +1 -1
- package/dist/esm/behaviors/groups/GroupsServer.js +9 -1
- package/dist/esm/behaviors/groups/GroupsServer.js.map +1 -1
- package/dist/esm/behaviors/level-control/LevelControlServer.d.ts +5 -5
- package/dist/esm/behaviors/level-control/LevelControlServer.d.ts.map +1 -1
- package/dist/esm/behaviors/level-control/LevelControlServer.js +55 -28
- package/dist/esm/behaviors/level-control/LevelControlServer.js.map +1 -1
- package/dist/esm/behaviors/on-off/OnOffServer.d.ts +3 -6
- package/dist/esm/behaviors/on-off/OnOffServer.d.ts.map +1 -1
- package/dist/esm/behaviors/on-off/OnOffServer.js +59 -7
- package/dist/esm/behaviors/on-off/OnOffServer.js.map +1 -1
- package/dist/esm/behaviors/scenes-management/ScenesManagementServer.d.ts +122 -3
- package/dist/esm/behaviors/scenes-management/ScenesManagementServer.d.ts.map +1 -1
- package/dist/esm/behaviors/scenes-management/ScenesManagementServer.js +960 -1
- package/dist/esm/behaviors/scenes-management/ScenesManagementServer.js.map +2 -2
- package/dist/esm/behaviors/switch/SwitchServer.d.ts +1 -1
- package/dist/esm/behaviors/switch/SwitchServer.d.ts.map +1 -1
- package/dist/esm/behaviors/switch/SwitchServer.js.map +1 -1
- package/dist/esm/behaviors/thermostat/AtomicWriteHandler.js +2 -2
- package/dist/esm/behaviors/thermostat/AtomicWriteHandler.js.map +1 -1
- package/dist/esm/behaviors/thermostat/ThermostatServer.d.ts +1 -1
- package/dist/esm/behaviors/thermostat/ThermostatServer.d.ts.map +1 -1
- package/dist/esm/behaviors/thermostat/ThermostatServer.js.map +1 -1
- package/dist/esm/devices/color-temperature-light.d.ts +4 -4
- package/dist/esm/devices/dimmable-light.d.ts +4 -4
- package/dist/esm/devices/dimmable-plug-in-unit.d.ts +4 -4
- package/dist/esm/devices/extended-color-light.d.ts +4 -4
- package/dist/esm/devices/mounted-dimmable-load-control.d.ts +4 -4
- package/dist/esm/devices/mounted-on-off-control.d.ts +4 -4
- package/dist/esm/devices/on-off-light.d.ts +4 -4
- package/dist/esm/devices/on-off-plug-in-unit.d.ts +4 -4
- package/dist/esm/endpoint/Agent.d.ts +5 -0
- package/dist/esm/endpoint/Agent.d.ts.map +1 -1
- package/dist/esm/endpoint/Agent.js +9 -0
- package/dist/esm/endpoint/Agent.js.map +1 -1
- package/dist/esm/endpoint/properties/Behaviors.js +1 -1
- package/dist/esm/endpoint/properties/Behaviors.js.map +1 -1
- package/dist/esm/node/integration/ProtocolService.js +1 -1
- package/dist/esm/node/integration/ProtocolService.js.map +1 -1
- package/package.json +7 -7
- package/src/behavior/Behavior.ts +2 -2
- package/src/behavior/Events.ts +1 -1
- package/src/behavior/cluster/ClusterBehavior.ts +4 -2
- package/src/behavior/cluster/ClusterBehaviorUtil.ts +1 -1
- package/src/behavior/internal/BehaviorBacking.ts +1 -1
- package/src/behavior/system/mqtt/MqttInterface.ts +1 -1
- package/src/behaviors/basic-information/BasicInformationServer.ts +3 -7
- package/src/behaviors/color-control/ColorControlServer.ts +132 -3
- package/src/behaviors/general-diagnostics/GeneralDiagnosticsServer.ts +1 -1
- package/src/behaviors/group-key-management/GroupKeyManagementServer.ts +2 -2
- package/src/behaviors/groups/GroupsServer.ts +13 -1
- package/src/behaviors/level-control/LevelControlServer.ts +72 -29
- package/src/behaviors/on-off/OnOffServer.ts +78 -9
- package/src/behaviors/scenes-management/ScenesManagementServer.ts +1123 -3
- package/src/behaviors/switch/SwitchServer.ts +1 -1
- package/src/behaviors/thermostat/AtomicWriteHandler.ts +4 -4
- package/src/behaviors/thermostat/ThermostatServer.ts +1 -1
- package/src/endpoint/Agent.ts +10 -0
- package/src/endpoint/properties/Behaviors.ts +1 -1
- package/src/node/integration/ProtocolService.ts +1 -1
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import { GroupKeyManagementServer } from "#behaviors/group-key-management";
|
|
8
8
|
import { IdentifyBehavior } from "#behaviors/identify";
|
|
9
|
+
import { ScenesManagementServer } from "#behaviors/scenes-management";
|
|
9
10
|
import { Groups } from "#clusters/groups";
|
|
10
11
|
import { Endpoint } from "#endpoint/Endpoint.js";
|
|
11
12
|
import { RootEndpoint } from "#endpoints/root";
|
|
@@ -164,11 +165,17 @@ export class GroupsServer extends GroupsBase {
|
|
|
164
165
|
}
|
|
165
166
|
|
|
166
167
|
try {
|
|
168
|
+
assertRemoteActor(this.context);
|
|
167
169
|
if (
|
|
168
170
|
await this.#actOnGroupKeyManagement((fabric, gkm) =>
|
|
169
171
|
gkm.removeEndpoint(fabric, this.endpoint.number, groupId),
|
|
170
172
|
)
|
|
171
173
|
) {
|
|
174
|
+
if (this.agent.has(ScenesManagementServer)) {
|
|
175
|
+
this.agent
|
|
176
|
+
.get(ScenesManagementServer)
|
|
177
|
+
.removeScenesForGroupOnFabric(this.context.session.associatedFabric.fabricIndex, groupId);
|
|
178
|
+
}
|
|
172
179
|
return { status: StatusCode.Success, groupId };
|
|
173
180
|
}
|
|
174
181
|
return { status: StatusCode.NotFound, groupId };
|
|
@@ -178,10 +185,15 @@ export class GroupsServer extends GroupsBase {
|
|
|
178
185
|
}
|
|
179
186
|
}
|
|
180
187
|
|
|
181
|
-
// TODO ScenesManagement cluster is also affected by this command
|
|
182
188
|
override async removeAllGroups() {
|
|
183
189
|
try {
|
|
190
|
+
assertRemoteActor(this.context);
|
|
184
191
|
await this.#actOnGroupKeyManagement((fabric, gkm) => gkm.removeEndpoint(fabric, this.endpoint.number));
|
|
192
|
+
if (this.agent.has(ScenesManagementServer)) {
|
|
193
|
+
this.agent
|
|
194
|
+
.get(ScenesManagementServer)
|
|
195
|
+
.removeScenesForAllGroupsForFabric(this.context.session.associatedFabric.fabricIndex);
|
|
196
|
+
}
|
|
185
197
|
} catch (error) {
|
|
186
198
|
StatusResponseError.accept(error);
|
|
187
199
|
throw error;
|
|
@@ -10,10 +10,11 @@ import { Transitions } from "#behavior/Transitions.js";
|
|
|
10
10
|
import { ColorControlServer } from "#behaviors/color-control";
|
|
11
11
|
import { GeneralDiagnosticsBehavior } from "#behaviors/general-diagnostics";
|
|
12
12
|
import { OnOffServer } from "#behaviors/on-off";
|
|
13
|
+
import { ScenesManagementServer } from "#behaviors/scenes-management";
|
|
13
14
|
import { GeneralDiagnostics } from "#clusters/general-diagnostics";
|
|
14
15
|
import { LevelControl } from "#clusters/level-control";
|
|
15
16
|
import { Endpoint } from "#endpoint/Endpoint.js";
|
|
16
|
-
import { AsyncObservable, Identity, Logger, MaybePromise, Millis } from "#general";
|
|
17
|
+
import { AsyncObservable, cropValueRange, Identity, Logger, MaybePromise, Millis } from "#general";
|
|
17
18
|
import { ServerNode } from "#node/ServerNode.js";
|
|
18
19
|
import { Val } from "#protocol";
|
|
19
20
|
import { ClusterType, StatusCode, StatusResponseError, TypeFromPartialBitSchema } from "#types";
|
|
@@ -105,6 +106,8 @@ export class LevelControlBaseServer extends LevelControlBase {
|
|
|
105
106
|
if (this.features.onOff && this.agent.has(OnOffServer)) {
|
|
106
107
|
this.initializeOnOff();
|
|
107
108
|
}
|
|
109
|
+
|
|
110
|
+
this.agent.maybeGet(ScenesManagementServer)?.implementScenes(this, this.#applySceneValues);
|
|
108
111
|
}
|
|
109
112
|
|
|
110
113
|
/**
|
|
@@ -230,8 +233,9 @@ export class LevelControlBaseServer extends LevelControlBase {
|
|
|
230
233
|
return;
|
|
231
234
|
}
|
|
232
235
|
|
|
233
|
-
|
|
236
|
+
level = cropValueRange(level, this.minLevel, this.maxLevel);
|
|
234
237
|
|
|
238
|
+
this.#invalidateScenes();
|
|
235
239
|
return this.moveToLevelLogic(level, transitionTime, false, effectiveOptions);
|
|
236
240
|
}
|
|
237
241
|
|
|
@@ -241,8 +245,9 @@ export class LevelControlBaseServer extends LevelControlBase {
|
|
|
241
245
|
* To replace this logic, override {@link moveToLevelLogic} whicih also implements {@link moveToLevel}.
|
|
242
246
|
*/
|
|
243
247
|
override moveToLevelWithOnOff({ level, transitionTime }: LevelControl.MoveToLevelRequest): MaybePromise {
|
|
244
|
-
|
|
248
|
+
level = cropValueRange(level, this.minLevel, this.maxLevel);
|
|
245
249
|
|
|
250
|
+
this.#invalidateScenes();
|
|
246
251
|
return this.moveToLevelLogic(level, transitionTime, true);
|
|
247
252
|
}
|
|
248
253
|
|
|
@@ -280,9 +285,11 @@ export class LevelControlBaseServer extends LevelControlBase {
|
|
|
280
285
|
|
|
281
286
|
let effectiveRate;
|
|
282
287
|
if (effectiveTransitionTime) {
|
|
283
|
-
|
|
288
|
+
// Delay the calculation of the effective rate because the coupling to OnOff might change the currentLevel
|
|
289
|
+
effectiveRate = (currentLevel: number) => ((level - currentLevel) / effectiveTransitionTime) * 10;
|
|
284
290
|
}
|
|
285
291
|
|
|
292
|
+
this.#invalidateScenes();
|
|
286
293
|
return this.transition(level, effectiveRate, withOnOff, options);
|
|
287
294
|
}
|
|
288
295
|
|
|
@@ -301,6 +308,7 @@ export class LevelControlBaseServer extends LevelControlBase {
|
|
|
301
308
|
return;
|
|
302
309
|
}
|
|
303
310
|
|
|
311
|
+
this.#invalidateScenes();
|
|
304
312
|
return this.moveLogic(moveMode, rate, false, effectiveOptions);
|
|
305
313
|
}
|
|
306
314
|
|
|
@@ -314,6 +322,7 @@ export class LevelControlBaseServer extends LevelControlBase {
|
|
|
314
322
|
override moveWithOnOff({ moveMode, rate }: LevelControl.MoveRequest): MaybePromise {
|
|
315
323
|
rate = this.#assertRateValue(rate);
|
|
316
324
|
|
|
325
|
+
this.#invalidateScenes();
|
|
317
326
|
return this.moveLogic(moveMode, rate, true);
|
|
318
327
|
}
|
|
319
328
|
|
|
@@ -365,6 +374,8 @@ export class LevelControlBaseServer extends LevelControlBase {
|
|
|
365
374
|
if (!this.#optionsAllowExecution(effectiveOptions)) {
|
|
366
375
|
return;
|
|
367
376
|
}
|
|
377
|
+
|
|
378
|
+
this.#invalidateScenes();
|
|
368
379
|
return this.stepLogic(stepMode, stepSize, transitionTime, false, effectiveOptions);
|
|
369
380
|
}
|
|
370
381
|
|
|
@@ -374,6 +385,7 @@ export class LevelControlBaseServer extends LevelControlBase {
|
|
|
374
385
|
* To replace default beahavior, override {@link stepLogic} which also implements {@link step}.
|
|
375
386
|
*/
|
|
376
387
|
override stepWithOnOff({ stepMode, stepSize, transitionTime }: LevelControl.StepRequest): MaybePromise {
|
|
388
|
+
this.#invalidateScenes();
|
|
377
389
|
return this.stepLogic(stepMode, stepSize, transitionTime, true);
|
|
378
390
|
}
|
|
379
391
|
|
|
@@ -412,6 +424,7 @@ export class LevelControlBaseServer extends LevelControlBase {
|
|
|
412
424
|
return;
|
|
413
425
|
}
|
|
414
426
|
|
|
427
|
+
this.#invalidateScenes();
|
|
415
428
|
return this.stopLogic(effectiveOptions);
|
|
416
429
|
}
|
|
417
430
|
|
|
@@ -430,17 +443,20 @@ export class LevelControlBaseServer extends LevelControlBase {
|
|
|
430
443
|
* Change to a designated level.
|
|
431
444
|
*
|
|
432
445
|
* @param targetLevel the new level once transition completes; if omitted transition will stop at min or max value
|
|
433
|
-
* @param changePerS the move rate; 0 or nullish means transition instantly
|
|
446
|
+
* @param changePerS the move rate; 0 or nullish means transition instantly; use function to calculate rate based on current level after coupling logics
|
|
434
447
|
* @param withOnOff if true follows rules for On/Off command variants
|
|
435
448
|
* @param options additional options supplied by the client
|
|
436
449
|
*/
|
|
437
450
|
protected transition(
|
|
438
451
|
targetLevel?: number,
|
|
439
|
-
changePerS?: number | null,
|
|
452
|
+
changePerS?: number | null | ((currentLevel: number) => number),
|
|
440
453
|
withOnOff = false,
|
|
441
454
|
options: TypeFromPartialBitSchema<typeof LevelControl.Options> = {},
|
|
442
455
|
): MaybePromise {
|
|
443
|
-
return MaybePromise.then(this.couple(withOnOff, options, targetLevel), () =>
|
|
456
|
+
return MaybePromise.then(this.couple(withOnOff, options, targetLevel), () => {
|
|
457
|
+
if (typeof changePerS === "function") {
|
|
458
|
+
changePerS = changePerS(this.currentLevel);
|
|
459
|
+
}
|
|
444
460
|
this.internal.transitions?.start({
|
|
445
461
|
name: "currentLevel",
|
|
446
462
|
owner: this,
|
|
@@ -450,8 +466,8 @@ export class LevelControlBaseServer extends LevelControlBase {
|
|
|
450
466
|
onStep() {
|
|
451
467
|
this.couple(withOnOff, options, targetLevel);
|
|
452
468
|
},
|
|
453
|
-
})
|
|
454
|
-
);
|
|
469
|
+
});
|
|
470
|
+
});
|
|
455
471
|
}
|
|
456
472
|
|
|
457
473
|
/**
|
|
@@ -464,6 +480,8 @@ export class LevelControlBaseServer extends LevelControlBase {
|
|
|
464
480
|
options: TypeFromPartialBitSchema<typeof LevelControl.Options> = {},
|
|
465
481
|
targetLevel?: number,
|
|
466
482
|
): MaybePromise {
|
|
483
|
+
let result: MaybePromise = undefined;
|
|
484
|
+
|
|
467
485
|
// Couple with On/Off state
|
|
468
486
|
if (this.features.onOff && withOnOff && this.agent.has(OnOffServer)) {
|
|
469
487
|
if (targetLevel === undefined) {
|
|
@@ -491,8 +509,18 @@ export class LevelControlBaseServer extends LevelControlBase {
|
|
|
491
509
|
if (!onOff.state.onOff) {
|
|
492
510
|
onOff.state.onOff = true;
|
|
493
511
|
|
|
494
|
-
|
|
495
|
-
|
|
512
|
+
if (this.state.onLevel !== null) {
|
|
513
|
+
// Ensure we move to "on" level before initiating any transition
|
|
514
|
+
result = this.handleOnOffChange(true);
|
|
515
|
+
this.internal.blockOnOffCouplingOnce = true; // But block the second call by listener
|
|
516
|
+
this.context.transaction.addParticipants({
|
|
517
|
+
postCommit: () => {
|
|
518
|
+
if (this.internal.blockOnOffCouplingOnce) {
|
|
519
|
+
this.internal.blockOnOffCouplingOnce = false;
|
|
520
|
+
}
|
|
521
|
+
},
|
|
522
|
+
});
|
|
523
|
+
}
|
|
496
524
|
}
|
|
497
525
|
}
|
|
498
526
|
}
|
|
@@ -513,6 +541,8 @@ export class LevelControlBaseServer extends LevelControlBase {
|
|
|
513
541
|
},
|
|
514
542
|
});
|
|
515
543
|
}
|
|
544
|
+
|
|
545
|
+
return result;
|
|
516
546
|
}
|
|
517
547
|
|
|
518
548
|
/**
|
|
@@ -526,9 +556,16 @@ export class LevelControlBaseServer extends LevelControlBase {
|
|
|
526
556
|
* @param onOff The new onOff state
|
|
527
557
|
*/
|
|
528
558
|
protected handleOnOffChange(onOff: boolean): MaybePromise {
|
|
559
|
+
if (this.internal.blockOnOffCouplingOnce) {
|
|
560
|
+
this.internal.blockOnOffCouplingOnce = false;
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
|
|
529
564
|
if (!onOff || this.state.onLevel === null) {
|
|
530
565
|
return;
|
|
531
566
|
}
|
|
567
|
+
|
|
568
|
+
logger.debug(`OnOff changed to ON, setting level to onLevel value of ${this.state.onLevel}`);
|
|
532
569
|
this.state.currentLevel = this.state.onLevel;
|
|
533
570
|
}
|
|
534
571
|
|
|
@@ -556,21 +593,6 @@ export class LevelControlBaseServer extends LevelControlBase {
|
|
|
556
593
|
);
|
|
557
594
|
}
|
|
558
595
|
|
|
559
|
-
#assertLevelValue(level: number) {
|
|
560
|
-
if (level < this.minLevel) {
|
|
561
|
-
throw new StatusResponseError(
|
|
562
|
-
`The level value of ${level} is invalid. It must be greater or equal to ${this.minLevel}.`,
|
|
563
|
-
StatusCode.ConstraintError,
|
|
564
|
-
);
|
|
565
|
-
}
|
|
566
|
-
if (level > this.maxLevel) {
|
|
567
|
-
throw new StatusResponseError(
|
|
568
|
-
`The level value of ${level} is invalid. It must be less or equal to ${this.maxLevel}.`,
|
|
569
|
-
StatusCode.ConstraintError,
|
|
570
|
-
);
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
|
|
574
596
|
#getBootReason() {
|
|
575
597
|
const rootEndpoint = this.env.get(ServerNode);
|
|
576
598
|
if (rootEndpoint.behaviors.has(GeneralDiagnosticsBehavior)) {
|
|
@@ -578,6 +600,26 @@ export class LevelControlBaseServer extends LevelControlBase {
|
|
|
578
600
|
}
|
|
579
601
|
}
|
|
580
602
|
|
|
603
|
+
/** Apply Scene values when requested from ScenesManagement cluster */
|
|
604
|
+
#applySceneValues(values: Val.Struct, transitionTime: number): MaybePromise {
|
|
605
|
+
const level = values.currentLevel;
|
|
606
|
+
// If no number (including null), or already current level or outside our range, ignore
|
|
607
|
+
// This is the only supported sceneable attribute in Level Control, so ignore all others for now
|
|
608
|
+
if (
|
|
609
|
+
typeof level !== "number" ||
|
|
610
|
+
this.state.currentLevel === level ||
|
|
611
|
+
cropValueRange(level, this.minLevel, this.maxLevel) !== level
|
|
612
|
+
) {
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
return this.moveToLevelLogic(level, transitionTime / 100, false, { executeIfOff: true });
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
/** Invalidate all stored scenes manually for this endpoint in the Scenesmanagement cluster because SDK behavior. */
|
|
619
|
+
#invalidateScenes() {
|
|
620
|
+
this.agent.maybeGet(ScenesManagementServer)?.makeAllFabricSceneInfoEntriesInvalid();
|
|
621
|
+
}
|
|
622
|
+
|
|
581
623
|
override async [Symbol.asyncDispose]() {
|
|
582
624
|
if (this.internal.transitions) {
|
|
583
625
|
await this.internal.transitions.close();
|
|
@@ -589,10 +631,11 @@ export class LevelControlBaseServer extends LevelControlBase {
|
|
|
589
631
|
|
|
590
632
|
export namespace LevelControlBaseServer {
|
|
591
633
|
export class Internal {
|
|
592
|
-
/**
|
|
593
|
-
* Transition management.
|
|
594
|
-
*/
|
|
634
|
+
/** Transition management. */
|
|
595
635
|
transitions?: Transitions<LevelControlBaseServer>;
|
|
636
|
+
|
|
637
|
+
/** Internal flag to avoid on/off coupling during transitions */
|
|
638
|
+
blockOnOffCouplingOnce = false;
|
|
596
639
|
}
|
|
597
640
|
|
|
598
641
|
export class State extends LevelControlBase.State {
|
|
@@ -5,10 +5,12 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { GeneralDiagnosticsBehavior } from "#behaviors/general-diagnostics";
|
|
8
|
+
import { ScenesManagementServer } from "#behaviors/scenes-management";
|
|
8
9
|
import { GeneralDiagnostics } from "#clusters/general-diagnostics";
|
|
9
10
|
import { OnOff } from "#clusters/on-off";
|
|
10
11
|
import { MaybePromise, Millis, Time, Timer } from "#general";
|
|
11
12
|
import { ServerNode } from "#node/ServerNode.js";
|
|
13
|
+
import { hasRemoteActor, Val } from "#protocol";
|
|
12
14
|
import { OnOffBehavior } from "./OnOffBehavior.js";
|
|
13
15
|
|
|
14
16
|
const OnOffLogicBase = OnOffBehavior.with(OnOff.Feature.Lighting);
|
|
@@ -41,6 +43,11 @@ export class OnOffBaseServer extends OnOffLogicBase {
|
|
|
41
43
|
}
|
|
42
44
|
}
|
|
43
45
|
}
|
|
46
|
+
|
|
47
|
+
if (this.agent.has(ScenesManagementServer)) {
|
|
48
|
+
this.agent.get(ScenesManagementServer).implementScenes(this, this.#applySceneValues);
|
|
49
|
+
this.reactTo(this.events.onOff$Changed, this.#clearDelayedSceneApplyData);
|
|
50
|
+
}
|
|
44
51
|
}
|
|
45
52
|
|
|
46
53
|
override async [Symbol.asyncDispose]() {
|
|
@@ -50,6 +57,9 @@ export class OnOffBaseServer extends OnOffLogicBase {
|
|
|
50
57
|
}
|
|
51
58
|
|
|
52
59
|
override on(): MaybePromise {
|
|
60
|
+
if (!this.state.onOff) {
|
|
61
|
+
this.#invalidateScenes();
|
|
62
|
+
}
|
|
53
63
|
this.state.onOff = true;
|
|
54
64
|
if (this.features.lighting) {
|
|
55
65
|
this.state.globalSceneControl = true;
|
|
@@ -62,7 +72,15 @@ export class OnOffBaseServer extends OnOffLogicBase {
|
|
|
62
72
|
}
|
|
63
73
|
}
|
|
64
74
|
|
|
75
|
+
/** Invalidate all stored scenes manually for this endpoint in the Scenesmanagement cluster because SDK behavior. */
|
|
76
|
+
#invalidateScenes() {
|
|
77
|
+
this.agent.maybeGet(ScenesManagementServer)?.makeAllFabricSceneInfoEntriesInvalid();
|
|
78
|
+
}
|
|
79
|
+
|
|
65
80
|
override off(): MaybePromise {
|
|
81
|
+
if (this.state.onOff) {
|
|
82
|
+
this.#invalidateScenes();
|
|
83
|
+
}
|
|
66
84
|
this.state.onOff = false;
|
|
67
85
|
if (this.features.lighting) {
|
|
68
86
|
if (this.timedOnTimer.isRunning) {
|
|
@@ -91,30 +109,40 @@ export class OnOffBaseServer extends OnOffLogicBase {
|
|
|
91
109
|
/**
|
|
92
110
|
* Default implementation notes:
|
|
93
111
|
* * This implementation ignores the effect and just calls off().
|
|
94
|
-
* * Global Scene Control is not supported yet.
|
|
95
112
|
*/
|
|
96
113
|
override offWithEffect(): MaybePromise {
|
|
97
114
|
if (this.state.globalSceneControl) {
|
|
98
|
-
|
|
115
|
+
if (hasRemoteActor(this.context) && this.context.session.fabric !== undefined) {
|
|
116
|
+
this.endpoint
|
|
117
|
+
.agentFor(this.context)
|
|
118
|
+
.maybeGet(ScenesManagementServer)
|
|
119
|
+
?.storeGlobalScene(this.context.session.fabric.fabricIndex);
|
|
120
|
+
}
|
|
99
121
|
this.state.globalSceneControl = false;
|
|
100
122
|
}
|
|
101
123
|
return this.off();
|
|
102
124
|
}
|
|
103
125
|
|
|
104
|
-
|
|
105
|
-
* Default implementation notes:
|
|
106
|
-
* * Global Scene Control is not supported yet, so the device is just turned on.
|
|
107
|
-
*/
|
|
108
|
-
override onWithRecallGlobalScene(): MaybePromise {
|
|
126
|
+
override async onWithRecallGlobalScene() {
|
|
109
127
|
if (this.state.globalSceneControl) {
|
|
110
128
|
return;
|
|
111
129
|
}
|
|
112
|
-
|
|
130
|
+
if (
|
|
131
|
+
hasRemoteActor(this.context) &&
|
|
132
|
+
this.context.session.fabric !== undefined &&
|
|
133
|
+
this.agent.has(ScenesManagementServer)
|
|
134
|
+
) {
|
|
135
|
+
await this.endpoint
|
|
136
|
+
.agentFor(this.context)
|
|
137
|
+
.maybeGet(ScenesManagementServer)
|
|
138
|
+
?.recallGlobalScene(this.context.session.fabric.fabricIndex);
|
|
139
|
+
}
|
|
140
|
+
|
|
113
141
|
this.state.globalSceneControl = true;
|
|
114
142
|
if (this.state.onTime === 0) {
|
|
115
143
|
this.state.offWaitTime = 0;
|
|
116
144
|
}
|
|
117
|
-
|
|
145
|
+
await this.on();
|
|
118
146
|
}
|
|
119
147
|
|
|
120
148
|
/**
|
|
@@ -177,6 +205,45 @@ export class OnOffBaseServer extends OnOffLogicBase {
|
|
|
177
205
|
return timer;
|
|
178
206
|
}
|
|
179
207
|
|
|
208
|
+
/** Apply Scene values when requested from ScenesManagement cluster */
|
|
209
|
+
#applySceneValues(values: Val.Struct, transitionTime: number): MaybePromise {
|
|
210
|
+
this.#clearDelayedSceneApplyData();
|
|
211
|
+
|
|
212
|
+
const onOff = values.onOff;
|
|
213
|
+
// If no number (including null) or outside our range, ignore
|
|
214
|
+
if (typeof onOff !== "boolean" || this.state.onOff === onOff) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (transitionTime === 0) {
|
|
219
|
+
this.state.onOff = onOff;
|
|
220
|
+
} else {
|
|
221
|
+
this.internal.applyScenePendingOnOff = onOff;
|
|
222
|
+
this.internal.applySceneDelayTimer = Time.getPeriodicTimer(
|
|
223
|
+
"delayed scene apply",
|
|
224
|
+
Millis(transitionTime),
|
|
225
|
+
this.callback(this.#applyDelayedSceneOnOffValue),
|
|
226
|
+
).start();
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
#clearDelayedSceneApplyData() {
|
|
231
|
+
if (this.internal.applySceneDelayTimer?.isRunning) {
|
|
232
|
+
this.internal.applySceneDelayTimer.stop();
|
|
233
|
+
}
|
|
234
|
+
this.internal.applySceneDelayTimer = undefined;
|
|
235
|
+
this.internal.applyScenePendingOnOff = undefined;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
#applyDelayedSceneOnOffValue() {
|
|
239
|
+
const onOff = this.internal.applyScenePendingOnOff;
|
|
240
|
+
this.#clearDelayedSceneApplyData();
|
|
241
|
+
if (onOff === undefined) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
this.state.onOff = onOff;
|
|
245
|
+
}
|
|
246
|
+
|
|
180
247
|
#delayedOffTick() {
|
|
181
248
|
let time = (this.state.offWaitTime ?? 0) - 1;
|
|
182
249
|
if (time <= 0) {
|
|
@@ -198,6 +265,8 @@ export namespace OnOffBaseServer {
|
|
|
198
265
|
export class Internal {
|
|
199
266
|
timedOnTimer?: Timer;
|
|
200
267
|
delayedOffTimer?: Timer;
|
|
268
|
+
applySceneDelayTimer?: Timer;
|
|
269
|
+
applyScenePendingOnOff?: boolean;
|
|
201
270
|
}
|
|
202
271
|
}
|
|
203
272
|
|