@matter/node 0.16.6 → 0.16.8-alpha.0-20260123-dff2cae52
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/system/software-update/OtaAnnouncements.d.ts +5 -1
- package/dist/cjs/behavior/system/software-update/OtaAnnouncements.d.ts.map +1 -1
- package/dist/cjs/behavior/system/software-update/OtaAnnouncements.js +32 -8
- package/dist/cjs/behavior/system/software-update/OtaAnnouncements.js.map +1 -1
- package/dist/cjs/behavior/system/software-update/SoftwareUpdateManager.d.ts +2 -4
- package/dist/cjs/behavior/system/software-update/SoftwareUpdateManager.d.ts.map +1 -1
- package/dist/cjs/behavior/system/software-update/SoftwareUpdateManager.js +18 -24
- package/dist/cjs/behavior/system/software-update/SoftwareUpdateManager.js.map +1 -1
- package/dist/cjs/behaviors/thermostat/ThermostatServer.d.ts.map +1 -1
- package/dist/cjs/behaviors/thermostat/ThermostatServer.js +12 -8
- package/dist/cjs/behaviors/thermostat/ThermostatServer.js.map +1 -1
- package/dist/cjs/node/integration/ProtocolService.js +6 -4
- package/dist/cjs/node/integration/ProtocolService.js.map +1 -1
- package/dist/esm/behavior/system/software-update/OtaAnnouncements.d.ts +5 -1
- package/dist/esm/behavior/system/software-update/OtaAnnouncements.d.ts.map +1 -1
- package/dist/esm/behavior/system/software-update/OtaAnnouncements.js +32 -8
- package/dist/esm/behavior/system/software-update/OtaAnnouncements.js.map +1 -1
- package/dist/esm/behavior/system/software-update/SoftwareUpdateManager.d.ts +2 -4
- package/dist/esm/behavior/system/software-update/SoftwareUpdateManager.d.ts.map +1 -1
- package/dist/esm/behavior/system/software-update/SoftwareUpdateManager.js +18 -24
- package/dist/esm/behavior/system/software-update/SoftwareUpdateManager.js.map +1 -1
- package/dist/esm/behaviors/thermostat/ThermostatServer.d.ts.map +1 -1
- package/dist/esm/behaviors/thermostat/ThermostatServer.js +12 -8
- package/dist/esm/behaviors/thermostat/ThermostatServer.js.map +1 -1
- package/dist/esm/node/integration/ProtocolService.js +6 -4
- package/dist/esm/node/integration/ProtocolService.js.map +1 -1
- package/package.json +7 -7
- package/src/behavior/system/software-update/OtaAnnouncements.ts +36 -9
- package/src/behavior/system/software-update/SoftwareUpdateManager.ts +23 -30
- package/src/behaviors/thermostat/ThermostatServer.ts +15 -9
- package/src/node/integration/ProtocolService.ts +6 -4
|
@@ -21,33 +21,51 @@ const logger = new Logger("OTAAnnouncements");
|
|
|
21
21
|
|
|
22
22
|
export class OtaAnnouncements {
|
|
23
23
|
#announcementQueue = new Array<PeerAddress>();
|
|
24
|
-
#announcementTimer
|
|
24
|
+
#announcementTimer?: Timer;
|
|
25
25
|
#announcementDelayTimer: Timer;
|
|
26
26
|
#ownNodeId: NodeId;
|
|
27
27
|
#ownFabricIndex: FabricIndex;
|
|
28
28
|
#ownVendorId: VendorId;
|
|
29
29
|
#node: ServerNode;
|
|
30
30
|
#otaProviderEndpoint: EndpointNumber;
|
|
31
|
-
#announcementInterval
|
|
31
|
+
#announcementInterval?: Duration;
|
|
32
32
|
#currentAnnouncementPromise?: Promise<void>;
|
|
33
33
|
|
|
34
|
-
constructor(endpoint: Endpoint, ownFabric: Fabric
|
|
34
|
+
constructor(endpoint: Endpoint, ownFabric: Fabric) {
|
|
35
35
|
this.#node = Node.forEndpoint(endpoint) as ServerNode;
|
|
36
36
|
this.#ownNodeId = ownFabric.rootNodeId;
|
|
37
37
|
this.#ownFabricIndex = ownFabric.fabricIndex;
|
|
38
38
|
this.#ownVendorId = ownFabric.rootVendorId;
|
|
39
39
|
this.#otaProviderEndpoint = endpoint.number;
|
|
40
|
+
|
|
41
|
+
// When announcing to multiple nodes, min 1s pause between, let's do some more, but no need for random
|
|
42
|
+
this.#announcementDelayTimer = Time.getTimer("OTA Node announcement delay", Seconds(10), () =>
|
|
43
|
+
this.#processQueueEntry(),
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Set the interval to a time value or undefined to disable announcements
|
|
49
|
+
*/
|
|
50
|
+
set interval(interval: Duration | undefined) {
|
|
51
|
+
if (interval === undefined) {
|
|
52
|
+
this.#announcementInterval = undefined;
|
|
53
|
+
this.#announcementTimer?.stop();
|
|
54
|
+
this.#announcementTimer = undefined;
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
40
58
|
if (interval < Hours(24)) {
|
|
41
59
|
logger.warn("Announcements interval is too short, consider increasing it to at least 24 hours.");
|
|
42
60
|
interval = Hours(24);
|
|
43
61
|
}
|
|
62
|
+
if (interval === this.#announcementInterval) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
44
65
|
// The daily start time should have a random jitter of + >= 60s, so just increase the time randomly a bit
|
|
45
66
|
this.#announcementInterval = Millis(interval + Seconds(Math.floor(Math.random() * 120) + 60));
|
|
46
67
|
|
|
47
|
-
|
|
48
|
-
this.#announcementDelayTimer = Time.getTimer("OTA Node announcement delay", Seconds(10), () =>
|
|
49
|
-
this.#processQueueEntry(),
|
|
50
|
-
);
|
|
68
|
+
this.#announcementTimer?.stop();
|
|
51
69
|
|
|
52
70
|
const initialDelay = Millis(Seconds(Math.floor(Math.random() * 300)) + Minutes(10));
|
|
53
71
|
logger.debug(`Initial OTA announcement delay is ${Duration.format(initialDelay)}`);
|
|
@@ -57,7 +75,10 @@ export class OtaAnnouncements {
|
|
|
57
75
|
}
|
|
58
76
|
|
|
59
77
|
#initializeAnnouncements() {
|
|
60
|
-
this.#
|
|
78
|
+
if (this.#announcementInterval === undefined) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
this.#announcementTimer?.stop();
|
|
61
82
|
this.#announcementTimer = Time.getTimer("OTA All Nodes announcement timer", this.#announcementInterval, () =>
|
|
62
83
|
this.#queueAllPeers(),
|
|
63
84
|
);
|
|
@@ -65,6 +86,9 @@ export class OtaAnnouncements {
|
|
|
65
86
|
}
|
|
66
87
|
|
|
67
88
|
#queueAllPeers() {
|
|
89
|
+
if (this.#announcementTimer === undefined) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
68
92
|
this.#announcementTimer.stop();
|
|
69
93
|
for (const peer of this.#node.peers) {
|
|
70
94
|
if (!peer.lifecycle.isCommissioned || !peer.lifecycle.isOnline) {
|
|
@@ -81,6 +105,9 @@ export class OtaAnnouncements {
|
|
|
81
105
|
|
|
82
106
|
// Queue a peer because processing is delayed and better to check /get peer anew when we process it
|
|
83
107
|
#queuePeer(peerAddress: PeerAddress) {
|
|
108
|
+
if (this.#announcementTimer === undefined) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
84
111
|
this.#announcementQueue.push(peerAddress);
|
|
85
112
|
logger.debug("Queued peer", peerAddress, "for OTA announcement;", this.#announcementQueue.length, "queued");
|
|
86
113
|
if (this.#announcementQueue.length > 0 && !this.#announcementTimer.isRunning) {
|
|
@@ -236,7 +263,7 @@ export class OtaAnnouncements {
|
|
|
236
263
|
}
|
|
237
264
|
|
|
238
265
|
async close() {
|
|
239
|
-
this.#announcementTimer
|
|
266
|
+
this.#announcementTimer?.stop();
|
|
240
267
|
this.#announcementDelayTimer.stop();
|
|
241
268
|
if (this.#currentAnnouncementPromise !== undefined) {
|
|
242
269
|
await this.#currentAnnouncementPromise;
|
|
@@ -144,7 +144,8 @@ export class SoftwareUpdateManager extends Behavior {
|
|
|
144
144
|
await this.#nodeOnline();
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
this.reactTo(this.events.announceAsDefaultProvider$Changed, this.#
|
|
147
|
+
this.reactTo(this.events.announceAsDefaultProvider$Changed, this.#updateAnnouncementSettings);
|
|
148
|
+
this.reactTo(this.events.announcementInterval$Changed, this.#updateAnnouncementSettings);
|
|
148
149
|
}
|
|
149
150
|
|
|
150
151
|
async #nodeOnline() {
|
|
@@ -153,7 +154,19 @@ export class SoftwareUpdateManager extends Behavior {
|
|
|
153
154
|
this.internal.announcements = undefined;
|
|
154
155
|
}
|
|
155
156
|
|
|
156
|
-
|
|
157
|
+
// For now let's just provide update functionality when we are the fabric owner
|
|
158
|
+
// In theory we could also claim that for any other fabric but could conflict with the main controller of
|
|
159
|
+
// the fabric that then also claims being "the one provider".
|
|
160
|
+
const fabricAuthority = this.env.get(FabricAuthority);
|
|
161
|
+
const ownFabric = fabricAuthority.fabrics[0];
|
|
162
|
+
if (!ownFabric) {
|
|
163
|
+
// Can only happen if the SoftwareUpdateManager is used without any commissioned nodes
|
|
164
|
+
logger.info(`No commissioned peers yet, cannot check for OTA updates. Wait for Fabric being added.`);
|
|
165
|
+
fabricAuthority.fabricAdded.once(this.callback(this.#nodeOnline));
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
this.internal.announcements = new OtaAnnouncements(this.endpoint, ownFabric);
|
|
169
|
+
this.#updateAnnouncementSettings();
|
|
157
170
|
|
|
158
171
|
// Randomly force the first update check 5-10 minutes after startup
|
|
159
172
|
const delay = Millis(Seconds(Math.floor(Math.random() * 300)) + Minutes(5));
|
|
@@ -166,33 +179,14 @@ export class SoftwareUpdateManager extends Behavior {
|
|
|
166
179
|
).start();
|
|
167
180
|
}
|
|
168
181
|
|
|
169
|
-
#
|
|
170
|
-
if (
|
|
182
|
+
#updateAnnouncementSettings() {
|
|
183
|
+
if (this.internal.announcements === undefined) {
|
|
171
184
|
return;
|
|
172
185
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
// For now let's just provide update functionality when we are the fabric owner
|
|
176
|
-
// In theory we could also claim that for any other fabric but could conflict with the main controller of
|
|
177
|
-
// the fabric that then also claims being "the one provider".
|
|
178
|
-
const fabricAuthority = this.env.get(FabricAuthority);
|
|
179
|
-
const ownFabric = fabricAuthority.fabrics[0];
|
|
180
|
-
if (!ownFabric) {
|
|
181
|
-
// Can only happen if the SoftwareUpdateManager is used without any commissioned nodes
|
|
182
|
-
logger.info(`No commissioned peers yet, cannot check for OTA updates. Wait for Fabric being added.`);
|
|
183
|
-
fabricAuthority.fabricAdded.once(this.callback(this.#nodeOnline));
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
this.internal.announcements = new OtaAnnouncements(
|
|
188
|
-
this.endpoint,
|
|
189
|
-
ownFabric,
|
|
190
|
-
this.state.announcementInterval,
|
|
191
|
-
);
|
|
186
|
+
if (this.state.announceAsDefaultProvider) {
|
|
187
|
+
this.internal.announcements.interval = this.state.announcementInterval;
|
|
192
188
|
} else {
|
|
193
|
-
|
|
194
|
-
this.internal.announcements = undefined;
|
|
195
|
-
this.env.runtime.add(announcements.close());
|
|
189
|
+
this.internal.announcements.interval = undefined;
|
|
196
190
|
}
|
|
197
191
|
}
|
|
198
192
|
|
|
@@ -851,10 +845,7 @@ export namespace SoftwareUpdateManager {
|
|
|
851
845
|
/** Default Update check Interval */
|
|
852
846
|
updateCheckInterval = Hours(24);
|
|
853
847
|
|
|
854
|
-
/**
|
|
855
|
-
* Announce this controller as Update provider to all nodes
|
|
856
|
-
* Defaults to false because we saw strange effects in the field
|
|
857
|
-
*/
|
|
848
|
+
/** Announce this controller as Update provider to all nodes */
|
|
858
849
|
announceAsDefaultProvider = false;
|
|
859
850
|
|
|
860
851
|
/** Interval to Announces this controller as Update provider. Must not be lower than 24h! */
|
|
@@ -890,5 +881,7 @@ export namespace SoftwareUpdateManager {
|
|
|
890
881
|
updateDone = Observable<[peer: PeerAddress]>();
|
|
891
882
|
|
|
892
883
|
announceAsDefaultProvider$Changed = Observable<[announceAsDefaultProvider: boolean]>();
|
|
884
|
+
|
|
885
|
+
announcementInterval$Changed = Observable<[announcementInterval: Duration]>();
|
|
893
886
|
}
|
|
894
887
|
}
|
|
@@ -335,7 +335,9 @@ export class ThermostatBaseServer extends ThermostatBehaviorLogicBase {
|
|
|
335
335
|
|
|
336
336
|
// TODO Add support for correct Time handling, leave disabled for now
|
|
337
337
|
if (this.state.setpointHoldExpiryTimestamp === undefined) {
|
|
338
|
-
//this.
|
|
338
|
+
//this.agent.asLocalActor(() => {
|
|
339
|
+
// this.state.setpointHoldExpiryTimestamp = null;
|
|
340
|
+
//});
|
|
339
341
|
} else {
|
|
340
342
|
logger.warn(
|
|
341
343
|
"Handling for setpointHoldExpiryTimestamp is not yet implemented. To use this attribute you need to install the needed logic yourself",
|
|
@@ -405,7 +407,9 @@ export class ThermostatBaseServer extends ThermostatBehaviorLogicBase {
|
|
|
405
407
|
}
|
|
406
408
|
break;
|
|
407
409
|
}
|
|
408
|
-
this.
|
|
410
|
+
this.agent.asLocalActor(() => {
|
|
411
|
+
this.state.thermostatRunningMode = newState;
|
|
412
|
+
});
|
|
409
413
|
}
|
|
410
414
|
|
|
411
415
|
/**
|
|
@@ -1000,13 +1004,15 @@ export class ThermostatBaseServer extends ThermostatBehaviorLogicBase {
|
|
|
1000
1004
|
|
|
1001
1005
|
#handleSystemModeChange(newMode: Thermostat.SystemMode) {
|
|
1002
1006
|
if (this.state.thermostatRunningMode !== undefined && newMode !== Thermostat.SystemMode.Auto) {
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1007
|
+
this.agent.asLocalActor(() => {
|
|
1008
|
+
if (newMode === Thermostat.SystemMode.Off) {
|
|
1009
|
+
this.state.thermostatRunningMode = Thermostat.ThermostatRunningMode.Off;
|
|
1010
|
+
} else if (newMode === Thermostat.SystemMode.Heat) {
|
|
1011
|
+
this.state.thermostatRunningMode = Thermostat.ThermostatRunningMode.Heat;
|
|
1012
|
+
} else if (newMode === Thermostat.SystemMode.Cool) {
|
|
1013
|
+
this.state.thermostatRunningMode = Thermostat.ThermostatRunningMode.Cool;
|
|
1014
|
+
}
|
|
1015
|
+
});
|
|
1010
1016
|
}
|
|
1011
1017
|
}
|
|
1012
1018
|
|
|
@@ -610,8 +610,9 @@ function invokeCommand(
|
|
|
610
610
|
result = Promise.resolve(result)
|
|
611
611
|
.then(result => {
|
|
612
612
|
if (isObject(result)) {
|
|
613
|
-
logger.
|
|
614
|
-
"Invoke
|
|
613
|
+
logger.info(
|
|
614
|
+
"Invoke",
|
|
615
|
+
Mark.OUTBOUND,
|
|
615
616
|
Diagnostic.strong(`${path.toString()}.${command.name}`),
|
|
616
617
|
session.transaction!.via,
|
|
617
618
|
Diagnostic.dict(result),
|
|
@@ -622,8 +623,9 @@ function invokeCommand(
|
|
|
622
623
|
.finally(() => activity?.[Symbol.dispose]());
|
|
623
624
|
} else {
|
|
624
625
|
if (isObject(result)) {
|
|
625
|
-
logger.
|
|
626
|
-
"Invoke
|
|
626
|
+
logger.info(
|
|
627
|
+
"Invoke",
|
|
628
|
+
Mark.OUTBOUND,
|
|
627
629
|
Diagnostic.strong(`${path.toString()}.${command.name}`),
|
|
628
630
|
session.transaction.via,
|
|
629
631
|
Diagnostic.dict(result),
|