@riddix/hamh 2.1.0-alpha.861 → 2.1.0-alpha.863
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/backend/cli.js
CHANGED
|
@@ -1767,8 +1767,8 @@ var init_Cancelable = __esm({
|
|
|
1767
1767
|
};
|
|
1768
1768
|
return result;
|
|
1769
1769
|
}
|
|
1770
|
-
static set logger(
|
|
1771
|
-
this.#logger =
|
|
1770
|
+
static set logger(logger255) {
|
|
1771
|
+
this.#logger = logger255;
|
|
1772
1772
|
}
|
|
1773
1773
|
static get logger() {
|
|
1774
1774
|
return this.#logger;
|
|
@@ -3475,13 +3475,13 @@ var init_Logger = __esm({
|
|
|
3475
3475
|
*
|
|
3476
3476
|
* @deprecated use {@link destinations}
|
|
3477
3477
|
*/
|
|
3478
|
-
static addLogger(identifier,
|
|
3478
|
+
static addLogger(identifier, logger255, options) {
|
|
3479
3479
|
if (identifier in this.destinations) {
|
|
3480
3480
|
throw new ImplementationError(`Logger "${identifier}" already exists`);
|
|
3481
3481
|
}
|
|
3482
3482
|
const dest = LogDestination({ name: identifier });
|
|
3483
3483
|
const legacy = adaptDestinationToLegacy(dest);
|
|
3484
|
-
legacy.log =
|
|
3484
|
+
legacy.log = logger255;
|
|
3485
3485
|
if (options?.defaultLogLevel !== void 0) {
|
|
3486
3486
|
legacy.defaultLogLevel = options.defaultLogLevel;
|
|
3487
3487
|
}
|
|
@@ -5687,8 +5687,8 @@ var init_Construction = __esm({
|
|
|
5687
5687
|
}
|
|
5688
5688
|
}
|
|
5689
5689
|
#unhandledError(...args) {
|
|
5690
|
-
const
|
|
5691
|
-
|
|
5690
|
+
const logger255 = Logger.get(this.#subject.constructor.name);
|
|
5691
|
+
logger255.error(...args);
|
|
5692
5692
|
}
|
|
5693
5693
|
#createErrorHandler(name) {
|
|
5694
5694
|
return (e) => {
|
|
@@ -64126,8 +64126,8 @@ var init_NodeSession = __esm({
|
|
|
64126
64126
|
return session?.type === SessionType.Unicast;
|
|
64127
64127
|
}
|
|
64128
64128
|
NodeSession2.is = is;
|
|
64129
|
-
function logNew(
|
|
64130
|
-
|
|
64129
|
+
function logNew(logger255, operation, session, messenger, fabric, peerNodeId) {
|
|
64130
|
+
logger255.info(
|
|
64131
64131
|
session.via,
|
|
64132
64132
|
`${operation} session with`,
|
|
64133
64133
|
Diagnostic.strong(PeerAddress({ fabricIndex: fabric.fabricIndex, nodeId: peerNodeId }).toString()),
|
|
@@ -118041,11 +118041,11 @@ var init_Api = __esm({
|
|
|
118041
118041
|
}
|
|
118042
118042
|
Api2.resourceFor = resourceFor;
|
|
118043
118043
|
function log(level, facility, id, ...message) {
|
|
118044
|
-
let
|
|
118045
|
-
if (!
|
|
118046
|
-
loggers.set(facility,
|
|
118044
|
+
let logger255 = loggers.get(facility);
|
|
118045
|
+
if (!logger255) {
|
|
118046
|
+
loggers.set(facility, logger255 = Logger.get(facility));
|
|
118047
118047
|
}
|
|
118048
|
-
|
|
118048
|
+
logger255[level](Diagnostic.via(id || "(anon)"), message);
|
|
118049
118049
|
}
|
|
118050
118050
|
Api2.log = log;
|
|
118051
118051
|
function logRequest(facility, id, method, target) {
|
|
@@ -132771,6 +132771,14 @@ var init_esm7 = __esm({
|
|
|
132771
132771
|
}
|
|
132772
132772
|
});
|
|
132773
132773
|
|
|
132774
|
+
// ../../node_modules/.pnpm/@matter+main@0.17.9/node_modules/@matter/main/dist/esm/protocol.js
|
|
132775
|
+
var init_protocol3 = __esm({
|
|
132776
|
+
"../../node_modules/.pnpm/@matter+main@0.17.9/node_modules/@matter/main/dist/esm/protocol.js"() {
|
|
132777
|
+
init_nodejs();
|
|
132778
|
+
init_esm4();
|
|
132779
|
+
}
|
|
132780
|
+
});
|
|
132781
|
+
|
|
132774
132782
|
// src/utils/debounce-context.ts
|
|
132775
132783
|
import debounce from "debounce";
|
|
132776
132784
|
var DebounceContext;
|
|
@@ -132850,7 +132858,7 @@ async function withRetry(fn, options = {}) {
|
|
|
132850
132858
|
return await fn();
|
|
132851
132859
|
} catch (error) {
|
|
132852
132860
|
lastError = error;
|
|
132853
|
-
if (attempt === opts.maxAttempts) {
|
|
132861
|
+
if (attempt === opts.maxAttempts || options.shouldRetry?.(error) === false) {
|
|
132854
132862
|
break;
|
|
132855
132863
|
}
|
|
132856
132864
|
const delayMs = Math.min(
|
|
@@ -132914,6 +132922,12 @@ var init_retry = __esm({
|
|
|
132914
132922
|
get isOpen() {
|
|
132915
132923
|
return this.state === "open";
|
|
132916
132924
|
}
|
|
132925
|
+
// Open AND still inside the reset window. Callers that pre-check
|
|
132926
|
+
// availability must use this, not isOpen, or the half-open probe never
|
|
132927
|
+
// happens and the breaker stays latched forever (#446).
|
|
132928
|
+
get isBlocking() {
|
|
132929
|
+
return this.state === "open" && Date.now() - this.lastFailureTime < this.resetTimeoutMs;
|
|
132930
|
+
}
|
|
132917
132931
|
reset() {
|
|
132918
132932
|
this.failures = 0;
|
|
132919
132933
|
this.state = "closed";
|
|
@@ -132950,8 +132964,7 @@ var init_send_ha_message = __esm({
|
|
|
132950
132964
|
});
|
|
132951
132965
|
|
|
132952
132966
|
// src/services/home-assistant/home-assistant-actions.ts
|
|
132953
|
-
|
|
132954
|
-
var defaultConfig, HomeAssistantActions;
|
|
132967
|
+
var TARGET_FAILURE_THRESHOLD, defaultConfig, HomeAssistantActions;
|
|
132955
132968
|
var init_home_assistant_actions = __esm({
|
|
132956
132969
|
"src/services/home-assistant/home-assistant-actions.ts"() {
|
|
132957
132970
|
"use strict";
|
|
@@ -132960,6 +132973,7 @@ var init_home_assistant_actions = __esm({
|
|
|
132960
132973
|
init_retry();
|
|
132961
132974
|
init_send_ha_message();
|
|
132962
132975
|
init_diagnostic_event_bus();
|
|
132976
|
+
TARGET_FAILURE_THRESHOLD = 3;
|
|
132963
132977
|
defaultConfig = {
|
|
132964
132978
|
retryAttempts: 3,
|
|
132965
132979
|
retryBaseDelayMs: 100,
|
|
@@ -132968,10 +132982,10 @@ var init_home_assistant_actions = __esm({
|
|
|
132968
132982
|
circuitBreakerResetMs: 3e4
|
|
132969
132983
|
};
|
|
132970
132984
|
HomeAssistantActions = class extends Service {
|
|
132971
|
-
constructor(
|
|
132985
|
+
constructor(logger255, client, config8) {
|
|
132972
132986
|
super("HomeAssistantActions");
|
|
132973
132987
|
this.client = client;
|
|
132974
|
-
this.log =
|
|
132988
|
+
this.log = logger255.get(this);
|
|
132975
132989
|
this.config = { ...defaultConfig, ...config8 };
|
|
132976
132990
|
this.circuitBreaker = new CircuitBreaker(
|
|
132977
132991
|
this.config.circuitBreakerThreshold,
|
|
@@ -132979,6 +132993,13 @@ var init_home_assistant_actions = __esm({
|
|
|
132979
132993
|
);
|
|
132980
132994
|
}
|
|
132981
132995
|
client;
|
|
132996
|
+
// #446: a Matter command must not report success while HA cannot take the
|
|
132997
|
+
// call. Only the transport counts here: the breaker is app-wide, so ten
|
|
132998
|
+
// failures from one broken entity would otherwise make every device on
|
|
132999
|
+
// every bridge fail.
|
|
133000
|
+
get available() {
|
|
133001
|
+
return this.client.haRunning;
|
|
133002
|
+
}
|
|
132982
133003
|
log;
|
|
132983
133004
|
debounceContext = new DebounceContext(
|
|
132984
133005
|
this.processAction.bind(this)
|
|
@@ -132987,6 +133008,27 @@ var init_home_assistant_actions = __esm({
|
|
|
132987
133008
|
config;
|
|
132988
133009
|
consecutiveFailures = 0;
|
|
132989
133010
|
lastSuccessTime = Date.now();
|
|
133011
|
+
// Per entity, not app wide: the shared breaker would let one broken entity
|
|
133012
|
+
// make every device on every bridge fail (#446).
|
|
133013
|
+
targetFailures = /* @__PURE__ */ new Map();
|
|
133014
|
+
// A target that just failed repeatedly is reported as unavailable, so the
|
|
133015
|
+
// controller sees the failure on that device instead of a false success.
|
|
133016
|
+
isTargetBlocked(entityId) {
|
|
133017
|
+
const entry = this.targetFailures.get(entityId);
|
|
133018
|
+
return entry != null && Date.now() < entry.blockedUntil;
|
|
133019
|
+
}
|
|
133020
|
+
recordTargetResult(entityId, failed) {
|
|
133021
|
+
if (!entityId) return;
|
|
133022
|
+
if (!failed) {
|
|
133023
|
+
this.targetFailures.delete(entityId);
|
|
133024
|
+
return;
|
|
133025
|
+
}
|
|
133026
|
+
const count = (this.targetFailures.get(entityId)?.count ?? 0) + 1;
|
|
133027
|
+
this.targetFailures.set(entityId, {
|
|
133028
|
+
count,
|
|
133029
|
+
blockedUntil: count >= TARGET_FAILURE_THRESHOLD ? Date.now() + this.config.circuitBreakerResetMs : 0
|
|
133030
|
+
});
|
|
133031
|
+
}
|
|
132990
133032
|
processAction(_key, calls) {
|
|
132991
133033
|
const skipTarget = calls[0].target === false;
|
|
132992
133034
|
const entity_id = skipTarget ? void 0 : calls[0].target || calls[0].entityId;
|
|
@@ -132994,7 +133036,9 @@ var init_home_assistant_actions = __esm({
|
|
|
132994
133036
|
const data = Object.assign({}, ...calls.map((c) => c.data));
|
|
132995
133037
|
const [domain, actionName] = action.split(".");
|
|
132996
133038
|
const target = entity_id ? { entity_id } : {};
|
|
132997
|
-
|
|
133039
|
+
const origin = calls[0].entityId;
|
|
133040
|
+
this.callAction(domain, actionName, data, target, false).then(() => this.recordTargetResult(origin, false)).catch((error) => {
|
|
133041
|
+
this.recordTargetResult(origin, true);
|
|
132998
133042
|
const errorMsg = this.formatError(error);
|
|
132999
133043
|
this.log.error(
|
|
133000
133044
|
`Failed to call action '${action}' for entity '${entity_id ?? "(no target)"}': ${errorMsg}`
|
|
@@ -133030,13 +133074,17 @@ var init_home_assistant_actions = __esm({
|
|
|
133030
133074
|
const result = await this.circuitBreaker.execute(
|
|
133031
133075
|
() => withRetry(
|
|
133032
133076
|
async () => {
|
|
133033
|
-
const res = await
|
|
133077
|
+
const res = await sendHaMessage(
|
|
133034
133078
|
this.client.connection,
|
|
133035
|
-
|
|
133036
|
-
|
|
133037
|
-
|
|
133038
|
-
|
|
133039
|
-
|
|
133079
|
+
{
|
|
133080
|
+
type: "call_service",
|
|
133081
|
+
domain,
|
|
133082
|
+
service: action,
|
|
133083
|
+
service_data: data,
|
|
133084
|
+
target,
|
|
133085
|
+
return_response: returnResponse
|
|
133086
|
+
},
|
|
133087
|
+
this.client.messageTimeoutMs
|
|
133040
133088
|
);
|
|
133041
133089
|
return res;
|
|
133042
133090
|
},
|
|
@@ -133044,6 +133092,9 @@ var init_home_assistant_actions = __esm({
|
|
|
133044
133092
|
maxAttempts: this.config.retryAttempts,
|
|
133045
133093
|
baseDelayMs: this.config.retryBaseDelayMs,
|
|
133046
133094
|
maxDelayMs: this.config.retryMaxDelayMs,
|
|
133095
|
+
// A timeout does not mean HA ignored the call, it may have run it.
|
|
133096
|
+
// Repeating a button press or a script would be worse than failing.
|
|
133097
|
+
shouldRetry: (error) => !(error instanceof Error && error.message.includes("timed out")),
|
|
133047
133098
|
onRetry: (attempt, error, delayMs) => {
|
|
133048
133099
|
const errorMsg = this.formatError(error);
|
|
133049
133100
|
this.log.warn(
|
|
@@ -133117,6 +133168,14 @@ var init_home_assistant_actions = __esm({
|
|
|
133117
133168
|
}
|
|
133118
133169
|
});
|
|
133119
133170
|
|
|
133171
|
+
// ../../node_modules/.pnpm/@matter+main@0.17.9/node_modules/@matter/main/dist/esm/types.js
|
|
133172
|
+
var init_types2 = __esm({
|
|
133173
|
+
"../../node_modules/.pnpm/@matter+main@0.17.9/node_modules/@matter/main/dist/esm/types.js"() {
|
|
133174
|
+
init_nodejs();
|
|
133175
|
+
init_esm3();
|
|
133176
|
+
}
|
|
133177
|
+
});
|
|
133178
|
+
|
|
133120
133179
|
// src/utils/async-observable.ts
|
|
133121
133180
|
var AsyncObservable2;
|
|
133122
133181
|
var init_async_observable = __esm({
|
|
@@ -133127,6 +133186,17 @@ var init_async_observable = __esm({
|
|
|
133127
133186
|
}
|
|
133128
133187
|
});
|
|
133129
133188
|
|
|
133189
|
+
// src/utils/transaction-is-offline.ts
|
|
133190
|
+
function transactionIsOffline(context) {
|
|
133191
|
+
return !context || hasLocalActor(context);
|
|
133192
|
+
}
|
|
133193
|
+
var init_transaction_is_offline = __esm({
|
|
133194
|
+
"src/utils/transaction-is-offline.ts"() {
|
|
133195
|
+
"use strict";
|
|
133196
|
+
init_protocol3();
|
|
133197
|
+
}
|
|
133198
|
+
});
|
|
133199
|
+
|
|
133130
133200
|
// src/matter/behaviors/home-assistant-entity-behavior.ts
|
|
133131
133201
|
var home_assistant_entity_behavior_exports = {};
|
|
133132
133202
|
__export(home_assistant_entity_behavior_exports, {
|
|
@@ -133138,8 +133208,10 @@ var init_home_assistant_entity_behavior = __esm({
|
|
|
133138
133208
|
"use strict";
|
|
133139
133209
|
init_dist();
|
|
133140
133210
|
init_esm7();
|
|
133211
|
+
init_types2();
|
|
133141
133212
|
init_home_assistant_actions();
|
|
133142
133213
|
init_async_observable();
|
|
133214
|
+
init_transaction_is_offline();
|
|
133143
133215
|
HomeAssistantEntityBehavior = class extends Behavior {
|
|
133144
133216
|
static id = ClusterId2.homeAssistantEntity;
|
|
133145
133217
|
get entityId() {
|
|
@@ -133154,7 +133226,24 @@ var init_home_assistant_entity_behavior = __esm({
|
|
|
133154
133226
|
get isAvailable() {
|
|
133155
133227
|
return this.entity.state.state !== "unavailable" && this.entity.state.state !== "unknown";
|
|
133156
133228
|
}
|
|
133229
|
+
// #446: fail the command instead of telling the controller it worked while
|
|
133230
|
+
// the call never reaches HA. `=== false` on purpose: test stubs do not
|
|
133231
|
+
// define `available`, and undefined must read as "no opinion".
|
|
133232
|
+
// ponytail: commands only. Attribute writes that fan and thermostat handle
|
|
133233
|
+
// in reactors run as a local actor, so they still go through and rely on HA
|
|
133234
|
+
// state to correct them. Plumb it there too if that shows up in reports.
|
|
133235
|
+
assertAvailable() {
|
|
133236
|
+
const actions = this.env.get(HomeAssistantActions);
|
|
133237
|
+
const blocked = actions.available === false || actions.isTargetBlocked?.(this.entityId) === true;
|
|
133238
|
+
if (blocked && !transactionIsOffline(this.context)) {
|
|
133239
|
+
throw new StatusResponseError(
|
|
133240
|
+
"Home Assistant is not reachable",
|
|
133241
|
+
StatusCode.Failure
|
|
133242
|
+
);
|
|
133243
|
+
}
|
|
133244
|
+
}
|
|
133157
133245
|
callAction(action) {
|
|
133246
|
+
this.assertAvailable();
|
|
133158
133247
|
const actions = this.env.get(HomeAssistantActions);
|
|
133159
133248
|
actions.call(action, this.entityId);
|
|
133160
133249
|
}
|
|
@@ -133317,10 +133406,10 @@ var DiagnosticService = class {
|
|
|
133317
133406
|
};
|
|
133318
133407
|
|
|
133319
133408
|
// src/api/access-log.ts
|
|
133320
|
-
function accessLogger(
|
|
133409
|
+
function accessLogger(logger255) {
|
|
133321
133410
|
return (req, res, next) => {
|
|
133322
133411
|
res.on("finish", () => {
|
|
133323
|
-
|
|
133412
|
+
logger255.debug(
|
|
133324
133413
|
`${req.method} ${decodeURI(req.originalUrl)} ${res.statusCode} ${res.statusMessage} from ${req.socket.remoteAddress}`
|
|
133325
133414
|
);
|
|
133326
133415
|
});
|
|
@@ -138058,7 +138147,7 @@ var WebSocketApi = class {
|
|
|
138058
138147
|
|
|
138059
138148
|
// src/api/web-api.ts
|
|
138060
138149
|
var WebApi = class extends Service {
|
|
138061
|
-
constructor(
|
|
138150
|
+
constructor(logger255, bridgeService, haClient, haRegistry, bridgeStorage, mappingStorage, identityStorage, lockCredentialStorage, settingsStorage, backupService, props) {
|
|
138062
138151
|
super("WebApi");
|
|
138063
138152
|
this.bridgeService = bridgeService;
|
|
138064
138153
|
this.haClient = haClient;
|
|
@@ -138070,8 +138159,8 @@ var WebApi = class extends Service {
|
|
|
138070
138159
|
this.settingsStorage = settingsStorage;
|
|
138071
138160
|
this.backupService = backupService;
|
|
138072
138161
|
this.props = props;
|
|
138073
|
-
this.logger =
|
|
138074
|
-
this.log =
|
|
138162
|
+
this.logger = logger255;
|
|
138163
|
+
this.log = logger255.get(this);
|
|
138075
138164
|
this.accessLogger = accessLogger(this.log.createChild("Access Log"));
|
|
138076
138165
|
this.startTime = Date.now();
|
|
138077
138166
|
this.wsApi = new WebSocketApi(
|
|
@@ -138492,12 +138581,9 @@ var BetterLogger = class _BetterLogger extends Logger {
|
|
|
138492
138581
|
// src/core/app/mdns.ts
|
|
138493
138582
|
init_esm();
|
|
138494
138583
|
init_esm7();
|
|
138584
|
+
init_protocol3();
|
|
138495
138585
|
import * as os5 from "node:os";
|
|
138496
138586
|
|
|
138497
|
-
// ../../node_modules/.pnpm/@matter+main@0.17.9/node_modules/@matter/main/dist/esm/protocol.js
|
|
138498
|
-
init_nodejs();
|
|
138499
|
-
init_esm4();
|
|
138500
|
-
|
|
138501
138587
|
// src/core/app/filtered-network.ts
|
|
138502
138588
|
init_esm6();
|
|
138503
138589
|
function filterAdvertisedIpv6(ipV6) {
|
|
@@ -139247,6 +139333,7 @@ init_home_assistant_actions();
|
|
|
139247
139333
|
// src/services/home-assistant/home-assistant-client.ts
|
|
139248
139334
|
init_service();
|
|
139249
139335
|
init_retry();
|
|
139336
|
+
init_send_ha_message();
|
|
139250
139337
|
import {
|
|
139251
139338
|
createConnection as createConnection2,
|
|
139252
139339
|
createLongLivedTokenAuth,
|
|
@@ -139272,30 +139359,92 @@ function isTransientConnectError(reason) {
|
|
|
139272
139359
|
return msg.includes("socket hang up") || msg.includes("tls") || msg.includes("TLS");
|
|
139273
139360
|
}
|
|
139274
139361
|
var HomeAssistantClient = class extends Service {
|
|
139275
|
-
constructor(
|
|
139362
|
+
constructor(logger255, options) {
|
|
139276
139363
|
super("HomeAssistantClient");
|
|
139277
139364
|
this.options = options;
|
|
139278
|
-
this.log =
|
|
139365
|
+
this.log = logger255.get(this);
|
|
139279
139366
|
}
|
|
139280
139367
|
options;
|
|
139281
139368
|
static Options = /* @__PURE__ */ Symbol.for("HomeAssistantClientProps");
|
|
139282
139369
|
_connection;
|
|
139283
139370
|
log;
|
|
139371
|
+
_haRunning = false;
|
|
139372
|
+
_runningSince = 0;
|
|
139373
|
+
runningPollGeneration = 0;
|
|
139284
139374
|
get connection() {
|
|
139285
139375
|
return this._connection;
|
|
139286
139376
|
}
|
|
139377
|
+
// False during HA's own startup and after any WS drop, true only once
|
|
139378
|
+
// getConfig reports RUNNING again. Endpoint managers use this to not trust
|
|
139379
|
+
// partial registry snapshots (#438).
|
|
139380
|
+
get haRunning() {
|
|
139381
|
+
return this._haRunning;
|
|
139382
|
+
}
|
|
139383
|
+
// When HA last reached RUNNING. The removal grace has to outlast HA's own
|
|
139384
|
+
// start, so it counts from here, not from wall time (#438).
|
|
139385
|
+
get runningSince() {
|
|
139386
|
+
return this._runningSince;
|
|
139387
|
+
}
|
|
139287
139388
|
get baseUrl() {
|
|
139288
139389
|
return this.options.url;
|
|
139289
139390
|
}
|
|
139290
139391
|
get accessToken() {
|
|
139291
139392
|
return this.options.accessToken;
|
|
139292
139393
|
}
|
|
139394
|
+
get messageTimeoutMs() {
|
|
139395
|
+
return this.options.messageTimeoutMs;
|
|
139396
|
+
}
|
|
139293
139397
|
async initialize() {
|
|
139294
139398
|
this._connection = await this.createConnection(this.options);
|
|
139399
|
+
this.watchRunningState(this._connection);
|
|
139400
|
+
this.setRunning(this._connection.connected ?? true);
|
|
139401
|
+
}
|
|
139402
|
+
setRunning(running) {
|
|
139403
|
+
if (running && !this._haRunning) {
|
|
139404
|
+
this._runningSince = Date.now();
|
|
139405
|
+
}
|
|
139406
|
+
this._haRunning = running;
|
|
139295
139407
|
}
|
|
139296
139408
|
async dispose() {
|
|
139409
|
+
this.runningPollGeneration++;
|
|
139297
139410
|
this.connection?.close();
|
|
139298
139411
|
}
|
|
139412
|
+
// The websocket library reconnects on its own after a drop and nothing
|
|
139413
|
+
// re-checks HA's lifecycle state, so a core restart resumed registry reads
|
|
139414
|
+
// mid-boot (#438). Force false on every drop and only flip back once a
|
|
139415
|
+
// fresh getConfig poll sees RUNNING. The generation counter kills stale
|
|
139416
|
+
// polls from an older reconnect.
|
|
139417
|
+
watchRunningState(connection) {
|
|
139418
|
+
connection.addEventListener("disconnected", () => {
|
|
139419
|
+
this.runningPollGeneration++;
|
|
139420
|
+
this.setRunning(false);
|
|
139421
|
+
});
|
|
139422
|
+
connection.addEventListener("ready", () => {
|
|
139423
|
+
const generation = ++this.runningPollGeneration;
|
|
139424
|
+
this.setRunning(false);
|
|
139425
|
+
this.confirmRunning(connection, generation).catch((e) => {
|
|
139426
|
+
this.log.warnCtx("HA running state check failed", {
|
|
139427
|
+
reason: e instanceof Error ? e.message : String(e)
|
|
139428
|
+
});
|
|
139429
|
+
});
|
|
139430
|
+
});
|
|
139431
|
+
}
|
|
139432
|
+
async confirmRunning(connection, generation) {
|
|
139433
|
+
while (this.runningPollGeneration === generation) {
|
|
139434
|
+
const config8 = await sendHaMessage(
|
|
139435
|
+
connection,
|
|
139436
|
+
{ type: "get_config" },
|
|
139437
|
+
this.options.messageTimeoutMs
|
|
139438
|
+
).catch(() => void 0);
|
|
139439
|
+
if (this.runningPollGeneration !== generation) return;
|
|
139440
|
+
if (config8?.state === "RUNNING") {
|
|
139441
|
+
this.setRunning(true);
|
|
139442
|
+
this.log.infoCtx("Home Assistant is up and running again", {});
|
|
139443
|
+
return;
|
|
139444
|
+
}
|
|
139445
|
+
await new Promise((resolve11) => setTimeout(resolve11, 5e3));
|
|
139446
|
+
}
|
|
139447
|
+
}
|
|
139299
139448
|
async createConnection(props) {
|
|
139300
139449
|
const maxConnectAttempts = 60;
|
|
139301
139450
|
for (let attempt = 1; attempt <= maxConnectAttempts; attempt++) {
|
|
@@ -139479,6 +139628,16 @@ var HomeAssistantRegistry = class extends Service {
|
|
|
139479
139628
|
options;
|
|
139480
139629
|
autoRefresh;
|
|
139481
139630
|
lastRegistryFingerprint = "";
|
|
139631
|
+
// Bumped on every successful reload, even an unchanged one. Endpoint
|
|
139632
|
+
// removal requires a bump between stamp and delete, so a stale cached
|
|
139633
|
+
// snapshot can never confirm a removal (#438).
|
|
139634
|
+
_snapshotGeneration = 0;
|
|
139635
|
+
get snapshotGeneration() {
|
|
139636
|
+
return this._snapshotGeneration;
|
|
139637
|
+
}
|
|
139638
|
+
// Last HA uptime stamp the auto-refresh saw, so a restart between ticks
|
|
139639
|
+
// still drives one reconcile (#438).
|
|
139640
|
+
lastRunningSince = 0;
|
|
139482
139641
|
_devices = {};
|
|
139483
139642
|
get devices() {
|
|
139484
139643
|
return this._devices;
|
|
@@ -139522,8 +139681,11 @@ var HomeAssistantRegistry = class extends Service {
|
|
|
139522
139681
|
}
|
|
139523
139682
|
refreshing = true;
|
|
139524
139683
|
try {
|
|
139684
|
+
const runningSince = this.client.runningSince;
|
|
139685
|
+
const restarted = runningSince !== this.lastRunningSince;
|
|
139525
139686
|
const changed = await this.reload();
|
|
139526
|
-
|
|
139687
|
+
this.lastRunningSince = runningSince;
|
|
139688
|
+
if (changed || restarted) {
|
|
139527
139689
|
await onRefresh();
|
|
139528
139690
|
}
|
|
139529
139691
|
} catch (e) {
|
|
@@ -139586,6 +139748,7 @@ var HomeAssistantRegistry = class extends Service {
|
|
|
139586
139748
|
});
|
|
139587
139749
|
}
|
|
139588
139750
|
async runRegistryQueries() {
|
|
139751
|
+
const trustedAtStart = this.client.haRunning;
|
|
139589
139752
|
const connection = this.client.connection;
|
|
139590
139753
|
const timeoutMs = this.options.messageTimeoutMs;
|
|
139591
139754
|
const [entityRegistry, statesList, deviceRegistry, labels, areas] = await Promise.all([
|
|
@@ -139625,6 +139788,12 @@ var HomeAssistantRegistry = class extends Service {
|
|
|
139625
139788
|
for (const a of areas) hash2.update(`${a.area_id}\0${a.name}
|
|
139626
139789
|
`);
|
|
139627
139790
|
const fingerprint = hash2.digest("hex");
|
|
139791
|
+
if (!trustedAtStart || !this.client.haRunning) {
|
|
139792
|
+
logger183.debug("Discarding registry snapshot, HA was not running");
|
|
139793
|
+
this.lastRegistryFingerprint = "";
|
|
139794
|
+
return false;
|
|
139795
|
+
}
|
|
139796
|
+
this._snapshotGeneration++;
|
|
139628
139797
|
this._states = keyBy(statesList, "entity_id");
|
|
139629
139798
|
if (fingerprint === this.lastRegistryFingerprint) {
|
|
139630
139799
|
logger183.debug("Registry unchanged, skipping full refresh");
|
|
@@ -155052,9 +155221,8 @@ var WindowCoveringDevice = WindowCoveringDeviceDefinition;
|
|
|
155052
155221
|
init_nodejs();
|
|
155053
155222
|
init_esm5();
|
|
155054
155223
|
|
|
155055
|
-
//
|
|
155056
|
-
|
|
155057
|
-
init_esm3();
|
|
155224
|
+
// src/matter/endpoints/server-mode-server-node.ts
|
|
155225
|
+
init_types2();
|
|
155058
155226
|
|
|
155059
155227
|
// src/utils/sanitize-matter-string.ts
|
|
155060
155228
|
function sanitizeMatterString(value) {
|
|
@@ -155238,6 +155406,9 @@ import * as path12 from "node:path";
|
|
|
155238
155406
|
// src/plugins/plugin-device-factory.ts
|
|
155239
155407
|
init_esm();
|
|
155240
155408
|
|
|
155409
|
+
// src/matter/behaviors/identify-server.ts
|
|
155410
|
+
init_esm();
|
|
155411
|
+
|
|
155241
155412
|
// ../../node_modules/.pnpm/@matter+main@0.17.9/node_modules/@matter/main/dist/esm/behaviors.js
|
|
155242
155413
|
init_nodejs();
|
|
155243
155414
|
|
|
@@ -156433,14 +156604,138 @@ init_wi_fi_network_diagnostics2();
|
|
|
156433
156604
|
init_ClientBehavior();
|
|
156434
156605
|
var WiFiNetworkManagementClientConstructor = ClientBehavior(WiFiNetworkManagement3);
|
|
156435
156606
|
|
|
156607
|
+
// ../../node_modules/.pnpm/@matter+main@0.17.9/node_modules/@matter/main/dist/esm/clusters.js
|
|
156608
|
+
init_nodejs();
|
|
156609
|
+
|
|
156610
|
+
// ../../node_modules/.pnpm/@matter+types@0.17.9/node_modules/@matter/types/dist/esm/clusters/index.js
|
|
156611
|
+
init_access_control();
|
|
156612
|
+
init_actions();
|
|
156613
|
+
init_administrator_commissioning();
|
|
156614
|
+
|
|
156615
|
+
// ../../node_modules/.pnpm/@matter+types@0.17.9/node_modules/@matter/types/dist/esm/clusters/alarm-base.js
|
|
156616
|
+
init_ClusterType();
|
|
156617
|
+
init_esm2();
|
|
156618
|
+
var AlarmBase3 = ClusterType(AlarmBase2);
|
|
156619
|
+
|
|
156620
|
+
// ../../node_modules/.pnpm/@matter+types@0.17.9/node_modules/@matter/types/dist/esm/clusters/index.js
|
|
156621
|
+
init_basic_information();
|
|
156622
|
+
init_binding();
|
|
156623
|
+
init_bridged_device_basic_information();
|
|
156624
|
+
init_commissioner_control();
|
|
156625
|
+
|
|
156626
|
+
// ../../node_modules/.pnpm/@matter+types@0.17.9/node_modules/@matter/types/dist/esm/clusters/concentration-measurement.js
|
|
156627
|
+
init_ClusterType();
|
|
156628
|
+
init_esm2();
|
|
156629
|
+
var ConcentrationMeasurement3 = ClusterType(ConcentrationMeasurement2);
|
|
156630
|
+
|
|
156631
|
+
// ../../node_modules/.pnpm/@matter+types@0.17.9/node_modules/@matter/types/dist/esm/clusters/index.js
|
|
156632
|
+
init_descriptor();
|
|
156633
|
+
init_diagnostic_logs();
|
|
156634
|
+
init_ethernet_network_diagnostics();
|
|
156635
|
+
init_general_commissioning();
|
|
156636
|
+
init_general_diagnostics();
|
|
156637
|
+
init_group_key_management();
|
|
156638
|
+
init_groupcast();
|
|
156639
|
+
init_icd_management();
|
|
156640
|
+
init_identify();
|
|
156641
|
+
|
|
156642
|
+
// ../../node_modules/.pnpm/@matter+types@0.17.9/node_modules/@matter/types/dist/esm/clusters/label.js
|
|
156643
|
+
init_ClusterType();
|
|
156644
|
+
init_esm2();
|
|
156645
|
+
var Label3 = ClusterType(Label2);
|
|
156646
|
+
|
|
156647
|
+
// ../../node_modules/.pnpm/@matter+types@0.17.9/node_modules/@matter/types/dist/esm/clusters/index.js
|
|
156648
|
+
init_localization_configuration();
|
|
156649
|
+
init_network_commissioning();
|
|
156650
|
+
init_operational_credentials();
|
|
156651
|
+
init_ota_software_update_provider();
|
|
156652
|
+
init_ota_software_update_requestor();
|
|
156653
|
+
init_power_source();
|
|
156654
|
+
init_power_source_configuration();
|
|
156655
|
+
|
|
156656
|
+
// ../../node_modules/.pnpm/@matter+types@0.17.9/node_modules/@matter/types/dist/esm/clusters/resource-monitoring.js
|
|
156657
|
+
init_ClusterType();
|
|
156658
|
+
init_esm2();
|
|
156659
|
+
var ResourceMonitoring3 = ClusterType(ResourceMonitoring2);
|
|
156660
|
+
|
|
156661
|
+
// ../../node_modules/.pnpm/@matter+types@0.17.9/node_modules/@matter/types/dist/esm/clusters/index.js
|
|
156662
|
+
init_software_diagnostics();
|
|
156663
|
+
init_thread_network_diagnostics();
|
|
156664
|
+
init_time_format_localization();
|
|
156665
|
+
init_time_synchronization();
|
|
156666
|
+
init_tls_certificate_management();
|
|
156667
|
+
init_tls_client_management();
|
|
156668
|
+
init_unit_localization();
|
|
156669
|
+
|
|
156670
|
+
// ../../node_modules/.pnpm/@matter+types@0.17.9/node_modules/@matter/types/dist/esm/clusters/web-rtc-transport-definitions.js
|
|
156671
|
+
init_ClusterType();
|
|
156672
|
+
init_esm2();
|
|
156673
|
+
var WebRtcTransportDefinitions3 = ClusterType(WebRtcTransportDefinitions2);
|
|
156674
|
+
|
|
156675
|
+
// ../../node_modules/.pnpm/@matter+types@0.17.9/node_modules/@matter/types/dist/esm/clusters/index.js
|
|
156676
|
+
init_wi_fi_network_diagnostics();
|
|
156677
|
+
|
|
156436
156678
|
// src/matter/behaviors/identify-server.ts
|
|
156679
|
+
init_home_assistant_entity_behavior();
|
|
156680
|
+
var logger198 = Logger.get("IdentifyServer");
|
|
156681
|
+
var IDENTIFY_BUTTON_SUFFIXES = ["_identify", "_locate", "_find_me"];
|
|
156437
156682
|
var IdentifyServer2 = class extends IdentifyServer {
|
|
156683
|
+
identify(request) {
|
|
156684
|
+
if (request.identifyTime > 0) {
|
|
156685
|
+
this.identifyInHomeAssistant("identify");
|
|
156686
|
+
}
|
|
156687
|
+
return super.identify(request);
|
|
156688
|
+
}
|
|
156689
|
+
triggerEffect(effect) {
|
|
156690
|
+
if (effect.effectIdentifier !== Identify3.EffectIdentifier.StopEffect && effect.effectIdentifier !== Identify3.EffectIdentifier.FinishEffect) {
|
|
156691
|
+
this.identifyInHomeAssistant("triggerEffect");
|
|
156692
|
+
}
|
|
156693
|
+
return super.triggerEffect(effect);
|
|
156694
|
+
}
|
|
156695
|
+
identifyInHomeAssistant(source) {
|
|
156696
|
+
if (!this.agent.has(HomeAssistantEntityBehavior)) return;
|
|
156697
|
+
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
156698
|
+
const target = this.findIdentifyEntity(homeAssistant);
|
|
156699
|
+
if (!target) {
|
|
156700
|
+
logger198.debug(
|
|
156701
|
+
`${source} for ${homeAssistant.entityId}, no identify entity on this device`
|
|
156702
|
+
);
|
|
156703
|
+
return;
|
|
156704
|
+
}
|
|
156705
|
+
logger198.info(
|
|
156706
|
+
`${source} \u2192 button.press ${target} for ${homeAssistant.entityId}`
|
|
156707
|
+
);
|
|
156708
|
+
homeAssistant.callAction({ action: "button.press", target });
|
|
156709
|
+
}
|
|
156710
|
+
// Searches the FULL registry: an identify button rarely matches the bridge
|
|
156711
|
+
// filter, same reason the battery and problem lookups do it.
|
|
156712
|
+
findIdentifyEntity(homeAssistant) {
|
|
156713
|
+
const deviceId = homeAssistant.entity.registry?.device_id;
|
|
156714
|
+
if (!deviceId) return void 0;
|
|
156715
|
+
const registry3 = this.env.maybeGet(HomeAssistantRegistry);
|
|
156716
|
+
if (!registry3) return void 0;
|
|
156717
|
+
let byName;
|
|
156718
|
+
for (const entity of Object.values(registry3.entities)) {
|
|
156719
|
+
if (entity.device_id !== deviceId) continue;
|
|
156720
|
+
if (entity.disabled_by != null) continue;
|
|
156721
|
+
if (!entity.entity_id.startsWith("button.")) continue;
|
|
156722
|
+
const deviceClass = registry3.states[entity.entity_id]?.attributes?.device_class;
|
|
156723
|
+
if (deviceClass === "identify") return entity.entity_id;
|
|
156724
|
+
const uniqueId = entity.unique_id ?? "";
|
|
156725
|
+
if (byName == null && IDENTIFY_BUTTON_SUFFIXES.some(
|
|
156726
|
+
(s) => entity.entity_id.endsWith(s) || uniqueId.endsWith(s)
|
|
156727
|
+
)) {
|
|
156728
|
+
byName = entity.entity_id;
|
|
156729
|
+
}
|
|
156730
|
+
}
|
|
156731
|
+
return byName;
|
|
156732
|
+
}
|
|
156438
156733
|
};
|
|
156439
156734
|
|
|
156440
156735
|
// src/matter/endpoints/validate-endpoint-type.ts
|
|
156441
156736
|
init_esm();
|
|
156442
156737
|
init_esm7();
|
|
156443
|
-
var
|
|
156738
|
+
var logger199 = Logger.get("EndpointValidation");
|
|
156444
156739
|
function toCamelCase(name) {
|
|
156445
156740
|
return name.charAt(0).toLowerCase() + name.slice(1);
|
|
156446
156741
|
}
|
|
@@ -156470,12 +156765,12 @@ function validateEndpointType(endpointType, entityId) {
|
|
|
156470
156765
|
}
|
|
156471
156766
|
const prefix = entityId ? `[${entityId}] ` : "";
|
|
156472
156767
|
if (missingMandatory.length > 0) {
|
|
156473
|
-
|
|
156768
|
+
logger199.warn(
|
|
156474
156769
|
`${prefix}${deviceTypeModel.name} (0x${endpointType.deviceType.toString(16)}): missing mandatory clusters: ${missingMandatory.join(", ")}`
|
|
156475
156770
|
);
|
|
156476
156771
|
}
|
|
156477
156772
|
if (availableOptional.length > 0) {
|
|
156478
|
-
|
|
156773
|
+
logger199.debug(
|
|
156479
156774
|
`${prefix}${deviceTypeModel.name} (0x${endpointType.deviceType.toString(16)}): optional clusters not used: ${availableOptional.join(", ")}`
|
|
156480
156775
|
);
|
|
156481
156776
|
}
|
|
@@ -156599,7 +156894,7 @@ var BridgeDataProvider = class extends Service {
|
|
|
156599
156894
|
|
|
156600
156895
|
// src/utils/apply-patch-state.ts
|
|
156601
156896
|
init_esm();
|
|
156602
|
-
var
|
|
156897
|
+
var logger200 = Logger.get("ApplyPatchState");
|
|
156603
156898
|
function applyPatchState(state, patch, options) {
|
|
156604
156899
|
return applyPatch(state, patch, options?.force);
|
|
156605
156900
|
}
|
|
@@ -156626,23 +156921,23 @@ function applyPatch(state, patch, force = false) {
|
|
|
156626
156921
|
if (errorMessage.includes(
|
|
156627
156922
|
"Endpoint storage inaccessible because endpoint is not a node and is not owned by another endpoint"
|
|
156628
156923
|
)) {
|
|
156629
|
-
|
|
156924
|
+
logger200.debug(
|
|
156630
156925
|
`Suppressed endpoint storage error, patch not applied: ${JSON.stringify(actualPatch)}`
|
|
156631
156926
|
);
|
|
156632
156927
|
return actualPatch;
|
|
156633
156928
|
}
|
|
156634
156929
|
if (errorMessage.includes("synchronous-transaction-conflict")) {
|
|
156635
|
-
|
|
156930
|
+
logger200.warn(
|
|
156636
156931
|
`Transaction conflict, state update DROPPED: ${JSON.stringify(actualPatch)}`
|
|
156637
156932
|
);
|
|
156638
156933
|
return actualPatch;
|
|
156639
156934
|
}
|
|
156640
156935
|
failedKeys.push(key);
|
|
156641
|
-
|
|
156936
|
+
logger200.warn(`Failed to set property '${key}': ${errorMessage}`);
|
|
156642
156937
|
}
|
|
156643
156938
|
}
|
|
156644
156939
|
if (failedKeys.length > 0) {
|
|
156645
|
-
|
|
156940
|
+
logger200.warn(
|
|
156646
156941
|
`${failedKeys.length} properties failed to update: [${failedKeys.join(", ")}]`
|
|
156647
156942
|
);
|
|
156648
156943
|
}
|
|
@@ -156712,7 +157007,7 @@ function truncate(maxLength, value) {
|
|
|
156712
157007
|
}
|
|
156713
157008
|
|
|
156714
157009
|
// src/plugins/plugin-device-factory.ts
|
|
156715
|
-
var
|
|
157010
|
+
var logger201 = Logger.get("PluginDeviceFactory");
|
|
156716
157011
|
var deviceTypeMap = {
|
|
156717
157012
|
on_off_light: () => OnOffLightDevice.with(
|
|
156718
157013
|
IdentifyServer2,
|
|
@@ -156818,7 +157113,7 @@ var deviceTypeMap = {
|
|
|
156818
157113
|
function createPluginEndpointType(deviceType) {
|
|
156819
157114
|
const factory = deviceTypeMap[deviceType];
|
|
156820
157115
|
if (!factory) {
|
|
156821
|
-
|
|
157116
|
+
logger201.warn(`Unsupported plugin device type: "${deviceType}"`);
|
|
156822
157117
|
return void 0;
|
|
156823
157118
|
}
|
|
156824
157119
|
const endpoint = factory();
|
|
@@ -156831,7 +157126,7 @@ function getSupportedPluginDeviceTypes() {
|
|
|
156831
157126
|
|
|
156832
157127
|
// src/plugins/safe-plugin-runner.ts
|
|
156833
157128
|
init_esm();
|
|
156834
|
-
var
|
|
157129
|
+
var logger202 = Logger.get("SafePluginRunner");
|
|
156835
157130
|
var DEFAULT_TIMEOUT_MS = 1e4;
|
|
156836
157131
|
var CIRCUIT_BREAKER_THRESHOLD = 3;
|
|
156837
157132
|
var SafePluginRunner = class {
|
|
@@ -156864,7 +157159,7 @@ var SafePluginRunner = class {
|
|
|
156864
157159
|
async run(pluginName, operation, fn, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
156865
157160
|
const state = this.getState(pluginName);
|
|
156866
157161
|
if (state.disabled) {
|
|
156867
|
-
|
|
157162
|
+
logger202.debug(
|
|
156868
157163
|
`Plugin "${pluginName}" is disabled (circuit breaker open), skipping ${operation}`
|
|
156869
157164
|
);
|
|
156870
157165
|
return void 0;
|
|
@@ -156882,13 +157177,13 @@ var SafePluginRunner = class {
|
|
|
156882
157177
|
timeout.clear();
|
|
156883
157178
|
state.failures++;
|
|
156884
157179
|
state.lastError = error instanceof Error ? error.message : String(error);
|
|
156885
|
-
|
|
157180
|
+
logger202.error(
|
|
156886
157181
|
`Plugin "${pluginName}" failed during ${operation} (failure ${state.failures}/${CIRCUIT_BREAKER_THRESHOLD}): ${state.lastError}`
|
|
156887
157182
|
);
|
|
156888
157183
|
if (state.failures >= CIRCUIT_BREAKER_THRESHOLD) {
|
|
156889
157184
|
state.disabled = true;
|
|
156890
157185
|
state.disabledAt = Date.now();
|
|
156891
|
-
|
|
157186
|
+
logger202.error(
|
|
156892
157187
|
`Plugin "${pluginName}" DISABLED after ${CIRCUIT_BREAKER_THRESHOLD} consecutive failures. Last error: ${state.lastError}`
|
|
156893
157188
|
);
|
|
156894
157189
|
}
|
|
@@ -156911,7 +157206,7 @@ var SafePluginRunner = class {
|
|
|
156911
157206
|
return result;
|
|
156912
157207
|
} catch (error) {
|
|
156913
157208
|
timeout.clear();
|
|
156914
|
-
|
|
157209
|
+
logger202.error(
|
|
156915
157210
|
`Plugin "${pluginName}" failed during ${operation}: ${error instanceof Error ? error.message : String(error)}`
|
|
156916
157211
|
);
|
|
156917
157212
|
return void 0;
|
|
@@ -156932,13 +157227,13 @@ var SafePluginRunner = class {
|
|
|
156932
157227
|
} catch (error) {
|
|
156933
157228
|
state.failures++;
|
|
156934
157229
|
state.lastError = error instanceof Error ? error.message : String(error);
|
|
156935
|
-
|
|
157230
|
+
logger202.error(
|
|
156936
157231
|
`Plugin "${pluginName}" failed during ${operation} (sync, failure ${state.failures}/${CIRCUIT_BREAKER_THRESHOLD}): ${state.lastError}`
|
|
156937
157232
|
);
|
|
156938
157233
|
if (state.failures >= CIRCUIT_BREAKER_THRESHOLD) {
|
|
156939
157234
|
state.disabled = true;
|
|
156940
157235
|
state.disabledAt = Date.now();
|
|
156941
|
-
|
|
157236
|
+
logger202.error(
|
|
156942
157237
|
`Plugin "${pluginName}" DISABLED after ${CIRCUIT_BREAKER_THRESHOLD} consecutive failures.`
|
|
156943
157238
|
);
|
|
156944
157239
|
}
|
|
@@ -156964,7 +157259,7 @@ var SafePluginRunner = class {
|
|
|
156964
157259
|
};
|
|
156965
157260
|
|
|
156966
157261
|
// src/plugins/plugin-manager.ts
|
|
156967
|
-
var
|
|
157262
|
+
var logger203 = Logger.get("PluginManager");
|
|
156968
157263
|
var PLUGIN_API_VERSION = 1;
|
|
156969
157264
|
var MAX_PLUGIN_DEVICE_ID_LENGTH = 100;
|
|
156970
157265
|
var LEGACY_ENABLED_KEY = "__enabled";
|
|
@@ -157059,7 +157354,7 @@ var PluginManager = class {
|
|
|
157059
157354
|
throw new Error(`Plugin at ${packagePath} package.json missing "main"`);
|
|
157060
157355
|
}
|
|
157061
157356
|
if (manifest.hamhPluginApiVersion != null && manifest.hamhPluginApiVersion !== PLUGIN_API_VERSION) {
|
|
157062
|
-
|
|
157357
|
+
logger203.warn(
|
|
157063
157358
|
`Plugin "${manifest.name}" declares API version ${manifest.hamhPluginApiVersion}, current is ${PLUGIN_API_VERSION}. It may not work correctly.`
|
|
157064
157359
|
);
|
|
157065
157360
|
}
|
|
@@ -157090,7 +157385,7 @@ var PluginManager = class {
|
|
|
157090
157385
|
};
|
|
157091
157386
|
await this.register(plugin, metadata);
|
|
157092
157387
|
} catch (e) {
|
|
157093
|
-
|
|
157388
|
+
logger203.error(`Failed to load external plugin from ${packagePath}:`, e);
|
|
157094
157389
|
throw e;
|
|
157095
157390
|
}
|
|
157096
157391
|
}
|
|
@@ -157115,7 +157410,7 @@ var PluginManager = class {
|
|
|
157115
157410
|
}
|
|
157116
157411
|
if (enabled === false) {
|
|
157117
157412
|
metadata.enabled = false;
|
|
157118
|
-
|
|
157413
|
+
logger203.info(`Plugin "${plugin.name}" stays disabled (persisted)`);
|
|
157119
157414
|
}
|
|
157120
157415
|
const devices = /* @__PURE__ */ new Map();
|
|
157121
157416
|
const pluginLogger = Logger.get(`Plugin:${plugin.name}`);
|
|
@@ -157154,7 +157449,7 @@ var PluginManager = class {
|
|
|
157154
157449
|
}
|
|
157155
157450
|
devices.delete(deviceId);
|
|
157156
157451
|
await this.onDeviceUnregistered?.(plugin.name, deviceId, {
|
|
157157
|
-
keepIdentity:
|
|
157452
|
+
keepIdentity: true
|
|
157158
157453
|
});
|
|
157159
157454
|
pluginLogger.debug(`Unregistered device: ${deviceId}`);
|
|
157160
157455
|
},
|
|
@@ -157203,7 +157498,7 @@ var PluginManager = class {
|
|
|
157203
157498
|
}),
|
|
157204
157499
|
suspending: false
|
|
157205
157500
|
});
|
|
157206
|
-
|
|
157501
|
+
logger203.info(
|
|
157207
157502
|
`Registered plugin: ${plugin.name} v${plugin.version} (${metadata.source})`
|
|
157208
157503
|
);
|
|
157209
157504
|
}
|
|
@@ -157228,13 +157523,13 @@ var PluginManager = class {
|
|
|
157228
157523
|
async startPlugin(name, instance) {
|
|
157229
157524
|
if (!instance.metadata.enabled) return;
|
|
157230
157525
|
if (this.runner.isDisabled(name)) {
|
|
157231
|
-
|
|
157526
|
+
logger203.warn(
|
|
157232
157527
|
`Plugin "${name}" is disabled (circuit breaker), skipping start`
|
|
157233
157528
|
);
|
|
157234
157529
|
instance.metadata.enabled = false;
|
|
157235
157530
|
return;
|
|
157236
157531
|
}
|
|
157237
|
-
|
|
157532
|
+
logger203.info(`Starting plugin: ${name}`);
|
|
157238
157533
|
const epoch = ++instance.epoch;
|
|
157239
157534
|
await this.runner.run(
|
|
157240
157535
|
name,
|
|
@@ -157293,7 +157588,7 @@ var PluginManager = class {
|
|
|
157293
157588
|
storage2.flush();
|
|
157294
157589
|
}
|
|
157295
157590
|
instance.started = false;
|
|
157296
|
-
|
|
157591
|
+
logger203.info(`Plugin "${name}" shut down`);
|
|
157297
157592
|
});
|
|
157298
157593
|
}
|
|
157299
157594
|
this.instances.clear();
|
|
@@ -157389,13 +157684,13 @@ var PluginManager = class {
|
|
|
157389
157684
|
instance.metadata.config = pending;
|
|
157390
157685
|
instance.pendingConfig = void 0;
|
|
157391
157686
|
} catch (e) {
|
|
157392
|
-
|
|
157687
|
+
logger203.warn(
|
|
157393
157688
|
`Failed to persist the parked config for "${pluginName}", it stays parked:`,
|
|
157394
157689
|
e
|
|
157395
157690
|
);
|
|
157396
157691
|
}
|
|
157397
157692
|
}
|
|
157398
|
-
|
|
157693
|
+
logger203.info(`Starting plugin: ${pluginName}`);
|
|
157399
157694
|
const epoch = ++instance.epoch;
|
|
157400
157695
|
await this.runner.run(
|
|
157401
157696
|
pluginName,
|
|
@@ -157428,7 +157723,7 @@ var PluginManager = class {
|
|
|
157428
157723
|
return JSON.parse(fs10.readFileSync(this.stateFile, "utf-8"));
|
|
157429
157724
|
}
|
|
157430
157725
|
} catch (e) {
|
|
157431
|
-
|
|
157726
|
+
logger203.warn(`Failed to read the plugin state file:`, e);
|
|
157432
157727
|
}
|
|
157433
157728
|
return {};
|
|
157434
157729
|
}
|
|
@@ -157439,7 +157734,7 @@ var PluginManager = class {
|
|
|
157439
157734
|
fs10.mkdirSync(path12.dirname(this.stateFile), { recursive: true });
|
|
157440
157735
|
fs10.writeFileSync(this.stateFile, JSON.stringify(state, null, 2));
|
|
157441
157736
|
} catch (e) {
|
|
157442
|
-
|
|
157737
|
+
logger203.warn(
|
|
157443
157738
|
`Failed to persist enabled=${enabled} for "${pluginName}":`,
|
|
157444
157739
|
e
|
|
157445
157740
|
);
|
|
@@ -157473,7 +157768,7 @@ var PluginManager = class {
|
|
|
157473
157768
|
if (instance.plugin.onConfigChanged) {
|
|
157474
157769
|
if (!instance.metadata.enabled) {
|
|
157475
157770
|
instance.pendingConfig = config8;
|
|
157476
|
-
|
|
157771
|
+
logger203.info(
|
|
157477
157772
|
`Plugin "${pluginName}" is disabled, the config applies on enable`
|
|
157478
157773
|
);
|
|
157479
157774
|
} else {
|
|
@@ -157493,6 +157788,7 @@ var PluginManager = class {
|
|
|
157493
157788
|
init_dist();
|
|
157494
157789
|
init_esm7();
|
|
157495
157790
|
import * as os9 from "node:os";
|
|
157791
|
+
init_protocol3();
|
|
157496
157792
|
|
|
157497
157793
|
// src/utils/json/create-bridge-server-config.ts
|
|
157498
157794
|
import crypto5 from "node:crypto";
|
|
@@ -157749,6 +158045,7 @@ var SecondaryNetworkInterfaceEndpointDefinition = MutableEndpoint({
|
|
|
157749
158045
|
Object.freeze(SecondaryNetworkInterfaceEndpointDefinition);
|
|
157750
158046
|
|
|
157751
158047
|
// src/utils/json/create-bridge-server-config.ts
|
|
158048
|
+
init_types2();
|
|
157752
158049
|
function createBridgeServerConfig(data, options) {
|
|
157753
158050
|
return {
|
|
157754
158051
|
type: ServerNode.RootEndpoint,
|
|
@@ -157845,6 +158142,7 @@ async function runMdnsAddressWatchTick(deps) {
|
|
|
157845
158142
|
}
|
|
157846
158143
|
|
|
157847
158144
|
// src/utils/ensure-commissioning-config.ts
|
|
158145
|
+
init_protocol3();
|
|
157848
158146
|
var ServerNodeConfigProvider = class extends CommissioningConfigProvider {
|
|
157849
158147
|
#node;
|
|
157850
158148
|
constructor(node) {
|
|
@@ -158038,11 +158336,11 @@ var AUTO_FORCE_SYNC_INTERVAL_MS = 9e4;
|
|
|
158038
158336
|
var SHUTDOWN_SESSION_CLOSE_TIMEOUT_MS = 2500;
|
|
158039
158337
|
var MDNS_ADDRESS_CHECK_INTERVAL_MS = 6e4;
|
|
158040
158338
|
var Bridge = class {
|
|
158041
|
-
constructor(env,
|
|
158339
|
+
constructor(env, logger255, dataProvider, endpointManager, serverOptions) {
|
|
158042
158340
|
this.dataProvider = dataProvider;
|
|
158043
158341
|
this.endpointManager = endpointManager;
|
|
158044
158342
|
this.serverOptions = serverOptions;
|
|
158045
|
-
this.log =
|
|
158343
|
+
this.log = logger255.get(`Bridge / ${dataProvider.id}`);
|
|
158046
158344
|
this.server = new BridgeServerNode(
|
|
158047
158345
|
env,
|
|
158048
158346
|
this.dataProvider,
|
|
@@ -159329,77 +159627,6 @@ var EntityStateProvider = class extends Service {
|
|
|
159329
159627
|
}
|
|
159330
159628
|
};
|
|
159331
159629
|
|
|
159332
|
-
// ../../node_modules/.pnpm/@matter+main@0.17.9/node_modules/@matter/main/dist/esm/clusters.js
|
|
159333
|
-
init_nodejs();
|
|
159334
|
-
|
|
159335
|
-
// ../../node_modules/.pnpm/@matter+types@0.17.9/node_modules/@matter/types/dist/esm/clusters/index.js
|
|
159336
|
-
init_access_control();
|
|
159337
|
-
init_actions();
|
|
159338
|
-
init_administrator_commissioning();
|
|
159339
|
-
|
|
159340
|
-
// ../../node_modules/.pnpm/@matter+types@0.17.9/node_modules/@matter/types/dist/esm/clusters/alarm-base.js
|
|
159341
|
-
init_ClusterType();
|
|
159342
|
-
init_esm2();
|
|
159343
|
-
var AlarmBase3 = ClusterType(AlarmBase2);
|
|
159344
|
-
|
|
159345
|
-
// ../../node_modules/.pnpm/@matter+types@0.17.9/node_modules/@matter/types/dist/esm/clusters/index.js
|
|
159346
|
-
init_basic_information();
|
|
159347
|
-
init_binding();
|
|
159348
|
-
init_bridged_device_basic_information();
|
|
159349
|
-
init_commissioner_control();
|
|
159350
|
-
|
|
159351
|
-
// ../../node_modules/.pnpm/@matter+types@0.17.9/node_modules/@matter/types/dist/esm/clusters/concentration-measurement.js
|
|
159352
|
-
init_ClusterType();
|
|
159353
|
-
init_esm2();
|
|
159354
|
-
var ConcentrationMeasurement3 = ClusterType(ConcentrationMeasurement2);
|
|
159355
|
-
|
|
159356
|
-
// ../../node_modules/.pnpm/@matter+types@0.17.9/node_modules/@matter/types/dist/esm/clusters/index.js
|
|
159357
|
-
init_descriptor();
|
|
159358
|
-
init_diagnostic_logs();
|
|
159359
|
-
init_ethernet_network_diagnostics();
|
|
159360
|
-
init_general_commissioning();
|
|
159361
|
-
init_general_diagnostics();
|
|
159362
|
-
init_group_key_management();
|
|
159363
|
-
init_groupcast();
|
|
159364
|
-
init_icd_management();
|
|
159365
|
-
init_identify();
|
|
159366
|
-
|
|
159367
|
-
// ../../node_modules/.pnpm/@matter+types@0.17.9/node_modules/@matter/types/dist/esm/clusters/label.js
|
|
159368
|
-
init_ClusterType();
|
|
159369
|
-
init_esm2();
|
|
159370
|
-
var Label3 = ClusterType(Label2);
|
|
159371
|
-
|
|
159372
|
-
// ../../node_modules/.pnpm/@matter+types@0.17.9/node_modules/@matter/types/dist/esm/clusters/index.js
|
|
159373
|
-
init_localization_configuration();
|
|
159374
|
-
init_network_commissioning();
|
|
159375
|
-
init_operational_credentials();
|
|
159376
|
-
init_ota_software_update_provider();
|
|
159377
|
-
init_ota_software_update_requestor();
|
|
159378
|
-
init_power_source();
|
|
159379
|
-
init_power_source_configuration();
|
|
159380
|
-
|
|
159381
|
-
// ../../node_modules/.pnpm/@matter+types@0.17.9/node_modules/@matter/types/dist/esm/clusters/resource-monitoring.js
|
|
159382
|
-
init_ClusterType();
|
|
159383
|
-
init_esm2();
|
|
159384
|
-
var ResourceMonitoring3 = ClusterType(ResourceMonitoring2);
|
|
159385
|
-
|
|
159386
|
-
// ../../node_modules/.pnpm/@matter+types@0.17.9/node_modules/@matter/types/dist/esm/clusters/index.js
|
|
159387
|
-
init_software_diagnostics();
|
|
159388
|
-
init_thread_network_diagnostics();
|
|
159389
|
-
init_time_format_localization();
|
|
159390
|
-
init_time_synchronization();
|
|
159391
|
-
init_tls_certificate_management();
|
|
159392
|
-
init_tls_client_management();
|
|
159393
|
-
init_unit_localization();
|
|
159394
|
-
|
|
159395
|
-
// ../../node_modules/.pnpm/@matter+types@0.17.9/node_modules/@matter/types/dist/esm/clusters/web-rtc-transport-definitions.js
|
|
159396
|
-
init_ClusterType();
|
|
159397
|
-
init_esm2();
|
|
159398
|
-
var WebRtcTransportDefinitions3 = ClusterType(WebRtcTransportDefinitions2);
|
|
159399
|
-
|
|
159400
|
-
// ../../node_modules/.pnpm/@matter+types@0.17.9/node_modules/@matter/types/dist/esm/clusters/index.js
|
|
159401
|
-
init_wi_fi_network_diagnostics();
|
|
159402
|
-
|
|
159403
159630
|
// src/utils/converters/fan-mode.ts
|
|
159404
159631
|
var FanMode = class _FanMode {
|
|
159405
159632
|
constructor(mode, sequence) {
|
|
@@ -159588,7 +159815,7 @@ init_esm();
|
|
|
159588
159815
|
init_esm7();
|
|
159589
159816
|
import crypto6 from "node:crypto";
|
|
159590
159817
|
init_home_assistant_entity_behavior();
|
|
159591
|
-
var
|
|
159818
|
+
var logger204 = Logger.get("BasicInformationServer");
|
|
159592
159819
|
var appliedUniqueIds = /* @__PURE__ */ new Map();
|
|
159593
159820
|
var BasicInformationServer2 = class extends BridgedDeviceBasicInformationServer {
|
|
159594
159821
|
async initialize() {
|
|
@@ -159634,7 +159861,7 @@ var BasicInformationServer2 = class extends BridgedDeviceBasicInformationServer
|
|
|
159634
159861
|
// records keyed on it can be shed (#385).
|
|
159635
159862
|
uniqueId: this.frozenUniqueId(anchor)
|
|
159636
159863
|
});
|
|
159637
|
-
|
|
159864
|
+
logger204.debug(
|
|
159638
159865
|
`[${entity.entity_id}] basicInfo vendor=${this.state.vendorName} product=${this.state.productName} label=${this.state.productLabel} serial=${this.state.serialNumber} node=${this.state.nodeLabel} uniqueId=${this.state.uniqueId}`
|
|
159639
159866
|
);
|
|
159640
159867
|
}
|
|
@@ -159664,7 +159891,7 @@ function isValidVendorId(value) {
|
|
|
159664
159891
|
// src/matter/behaviors/electrical-energy-measurement-server.ts
|
|
159665
159892
|
init_esm();
|
|
159666
159893
|
init_home_assistant_entity_behavior();
|
|
159667
|
-
var
|
|
159894
|
+
var logger205 = Logger.get("ElectricalEnergyMeasurementServer");
|
|
159668
159895
|
var FeaturedBase = ElectricalEnergyMeasurementServer.with("CumulativeEnergy", "ImportedEnergy");
|
|
159669
159896
|
var ElectricalEnergyMeasurementServerBase = class extends FeaturedBase {
|
|
159670
159897
|
async initialize() {
|
|
@@ -159673,7 +159900,7 @@ var ElectricalEnergyMeasurementServerBase = class extends FeaturedBase {
|
|
|
159673
159900
|
const entityId = homeAssistant.entityId;
|
|
159674
159901
|
const energyEntity = homeAssistant.state.mapping?.energyEntity;
|
|
159675
159902
|
if (energyEntity) {
|
|
159676
|
-
|
|
159903
|
+
logger205.debug(
|
|
159677
159904
|
`[${entityId}] ElectricalEnergyMeasurement using mapped energy entity: ${energyEntity}`
|
|
159678
159905
|
);
|
|
159679
159906
|
}
|
|
@@ -159729,7 +159956,7 @@ var HaElectricalEnergyMeasurementServer = ElectricalEnergyMeasurementServerBase.
|
|
|
159729
159956
|
// src/matter/behaviors/electrical-power-measurement-server.ts
|
|
159730
159957
|
init_esm();
|
|
159731
159958
|
init_home_assistant_entity_behavior();
|
|
159732
|
-
var
|
|
159959
|
+
var logger206 = Logger.get("ElectricalPowerMeasurementServer");
|
|
159733
159960
|
var FeaturedBase2 = ElectricalPowerMeasurementServer.with("AlternatingCurrent");
|
|
159734
159961
|
var ElectricalPowerMeasurementServerBase = class extends FeaturedBase2 {
|
|
159735
159962
|
async initialize() {
|
|
@@ -159738,7 +159965,7 @@ var ElectricalPowerMeasurementServerBase = class extends FeaturedBase2 {
|
|
|
159738
159965
|
const entityId = homeAssistant.entityId;
|
|
159739
159966
|
const powerEntity = homeAssistant.state.mapping?.powerEntity;
|
|
159740
159967
|
if (powerEntity) {
|
|
159741
|
-
|
|
159968
|
+
logger206.debug(
|
|
159742
159969
|
`[${entityId}] ElectricalPowerMeasurement using mapped power entity: ${powerEntity}`
|
|
159743
159970
|
);
|
|
159744
159971
|
}
|
|
@@ -159877,7 +160104,7 @@ init_home_assistant_entity_behavior();
|
|
|
159877
160104
|
// src/matter/behaviors/humidity-measurement-server.ts
|
|
159878
160105
|
init_esm();
|
|
159879
160106
|
init_home_assistant_entity_behavior();
|
|
159880
|
-
var
|
|
160107
|
+
var logger207 = Logger.get("HumidityMeasurementServer");
|
|
159881
160108
|
var HumidityMeasurementServerBase = class extends RelativeHumidityMeasurementServer {
|
|
159882
160109
|
async initialize() {
|
|
159883
160110
|
await super.initialize();
|
|
@@ -159890,7 +160117,7 @@ var HumidityMeasurementServerBase = class extends RelativeHumidityMeasurementSer
|
|
|
159890
160117
|
return;
|
|
159891
160118
|
}
|
|
159892
160119
|
const humidity = this.getHumidity(this.state.config, entity.state);
|
|
159893
|
-
|
|
160120
|
+
logger207.debug(
|
|
159894
160121
|
`Humidity ${entity.state.entity_id} raw=${entity.state.state} measuredValue=${humidity}`
|
|
159895
160122
|
);
|
|
159896
160123
|
applyPatchState(this.state, {
|
|
@@ -159920,7 +160147,7 @@ function HumidityMeasurementServer(config8) {
|
|
|
159920
160147
|
// src/matter/behaviors/power-source-server.ts
|
|
159921
160148
|
init_esm();
|
|
159922
160149
|
init_home_assistant_entity_behavior();
|
|
159923
|
-
var
|
|
160150
|
+
var logger208 = Logger.get("PowerSourceServer");
|
|
159924
160151
|
var FeaturedBase3 = PowerSourceServer.with("Battery", "Rechargeable");
|
|
159925
160152
|
var PowerSourceServerBase = class extends FeaturedBase3 {
|
|
159926
160153
|
async initialize() {
|
|
@@ -159932,17 +160159,17 @@ var PowerSourceServerBase = class extends FeaturedBase3 {
|
|
|
159932
160159
|
applyPatchState(this.state, {
|
|
159933
160160
|
endpointList: [endpointNumber]
|
|
159934
160161
|
});
|
|
159935
|
-
|
|
160162
|
+
logger208.debug(
|
|
159936
160163
|
`[${entityId}] PowerSource initialized with endpointList=[${endpointNumber}]`
|
|
159937
160164
|
);
|
|
159938
160165
|
} else {
|
|
159939
|
-
|
|
160166
|
+
logger208.warn(
|
|
159940
160167
|
`[${entityId}] PowerSource endpoint number is null during initialize - endpointList will be empty!`
|
|
159941
160168
|
);
|
|
159942
160169
|
}
|
|
159943
160170
|
const batteryEntity = homeAssistant.state.mapping?.batteryEntity;
|
|
159944
160171
|
if (batteryEntity) {
|
|
159945
|
-
|
|
160172
|
+
logger208.debug(
|
|
159946
160173
|
`[${entityId}] PowerSource using mapped battery entity: ${batteryEntity}`
|
|
159947
160174
|
);
|
|
159948
160175
|
}
|
|
@@ -160263,12 +160490,8 @@ var FanSpeed = class _FanSpeed {
|
|
|
160263
160490
|
}
|
|
160264
160491
|
};
|
|
160265
160492
|
|
|
160266
|
-
// src/utils/transaction-is-offline.ts
|
|
160267
|
-
function transactionIsOffline(context) {
|
|
160268
|
-
return !context || hasLocalActor(context);
|
|
160269
|
-
}
|
|
160270
|
-
|
|
160271
160493
|
// src/matter/behaviors/fan-control-server.ts
|
|
160494
|
+
init_transaction_is_offline();
|
|
160272
160495
|
init_home_assistant_entity_behavior();
|
|
160273
160496
|
|
|
160274
160497
|
// src/matter/behaviors/on-off-server.ts
|
|
@@ -160322,7 +160545,7 @@ function notifyLightTurnedOff(entityId, haLastChanged) {
|
|
|
160322
160545
|
sweepLastTurnOff(now);
|
|
160323
160546
|
lastTurnOffTimestamps.set(entityId, { ts: now, haLastChanged });
|
|
160324
160547
|
}
|
|
160325
|
-
var
|
|
160548
|
+
var logger209 = Logger.get("LevelControlServer");
|
|
160326
160549
|
var FeaturedBase5 = LevelControlServer.with("OnOff", "Lighting");
|
|
160327
160550
|
var LevelControlServerBase = class extends FeaturedBase5 {
|
|
160328
160551
|
pendingTransitionTime;
|
|
@@ -160340,7 +160563,7 @@ var LevelControlServerBase = class extends FeaturedBase5 {
|
|
|
160340
160563
|
try {
|
|
160341
160564
|
await super.initialize();
|
|
160342
160565
|
} catch (error) {
|
|
160343
|
-
|
|
160566
|
+
logger209.error("super.initialize() failed:", error);
|
|
160344
160567
|
throw error;
|
|
160345
160568
|
}
|
|
160346
160569
|
const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
|
|
@@ -160458,7 +160681,7 @@ var LevelControlServerBase = class extends FeaturedBase5 {
|
|
|
160458
160681
|
expectedLevel: remembered,
|
|
160459
160682
|
timestamp: now2
|
|
160460
160683
|
});
|
|
160461
|
-
|
|
160684
|
+
logger209.debug(
|
|
160462
160685
|
`[${entityId}] Storing level ${level} without calling HA - moveToLevel arrived ${sinceTurnOff}ms after a Matter off while still off (#434)`
|
|
160463
160686
|
);
|
|
160464
160687
|
return;
|
|
@@ -160469,7 +160692,7 @@ var LevelControlServerBase = class extends FeaturedBase5 {
|
|
|
160469
160692
|
const lastTurnOn = lastTurnOnTimestamps.get(entityId);
|
|
160470
160693
|
const timeSinceTurnOn = lastTurnOn ? Date.now() - lastTurnOn : Infinity;
|
|
160471
160694
|
if (level >= this.maxLevel && timeSinceTurnOn < 200) {
|
|
160472
|
-
|
|
160695
|
+
logger209.debug(
|
|
160473
160696
|
`[${entityId}] Ignoring moveToLevel(${level}) - Alexa brightness reset detected (${timeSinceTurnOn}ms after turn-on)`
|
|
160474
160697
|
);
|
|
160475
160698
|
return;
|
|
@@ -160515,7 +160738,7 @@ function LevelControlServer2(config8) {
|
|
|
160515
160738
|
}
|
|
160516
160739
|
|
|
160517
160740
|
// src/matter/behaviors/on-off-server.ts
|
|
160518
|
-
var
|
|
160741
|
+
var logger210 = Logger.get("OnOffServer");
|
|
160519
160742
|
var optimisticOnOffState = /* @__PURE__ */ new Map();
|
|
160520
160743
|
var OPTIMISTIC_TIMEOUT_MS2 = 3e3;
|
|
160521
160744
|
function sweepOptimisticOnOff(now) {
|
|
@@ -160579,7 +160802,7 @@ var OnOffServerBase = class extends OnOffServer {
|
|
|
160579
160802
|
if (!action) {
|
|
160580
160803
|
return;
|
|
160581
160804
|
}
|
|
160582
|
-
|
|
160805
|
+
logger210.info(`[${homeAssistant.entityId}] Turning ON -> ${action.action}`);
|
|
160583
160806
|
notifyLightTurnedOn(homeAssistant.entityId);
|
|
160584
160807
|
if (!skipMomentaryFlip) {
|
|
160585
160808
|
const now = Date.now();
|
|
@@ -160610,7 +160833,7 @@ var OnOffServerBase = class extends OnOffServer {
|
|
|
160610
160833
|
if (!action) {
|
|
160611
160834
|
return;
|
|
160612
160835
|
}
|
|
160613
|
-
|
|
160836
|
+
logger210.info(`[${homeAssistant.entityId}] Turning OFF -> ${action.action}`);
|
|
160614
160837
|
const now = Date.now();
|
|
160615
160838
|
sweepOptimisticOnOff(now);
|
|
160616
160839
|
optimisticOnOffState.set(homeAssistant.entityId, {
|
|
@@ -160644,7 +160867,7 @@ function setOptimisticOnOff(entityId, expectedOnOff) {
|
|
|
160644
160867
|
}
|
|
160645
160868
|
|
|
160646
160869
|
// src/matter/behaviors/fan-control-server.ts
|
|
160647
|
-
var
|
|
160870
|
+
var logger211 = Logger.get("FanControlServer");
|
|
160648
160871
|
var defaultStepSize = 33.33;
|
|
160649
160872
|
var minSpeedMax = 3;
|
|
160650
160873
|
var maxSpeedMax = 100;
|
|
@@ -160951,6 +161174,7 @@ var FanControlServerBase = class extends FeaturedBase6 {
|
|
|
160951
161174
|
homeAssistant.callAction(action);
|
|
160952
161175
|
return;
|
|
160953
161176
|
}
|
|
161177
|
+
homeAssistant.assertAvailable();
|
|
160954
161178
|
const entityId = homeAssistant.entityId;
|
|
160955
161179
|
const actions = this.env.get(HomeAssistantActions);
|
|
160956
161180
|
const st = getFanDebounce(this.endpoint);
|
|
@@ -160983,7 +161207,7 @@ var FanControlServerBase = class extends FeaturedBase6 {
|
|
|
160983
161207
|
const wasOff = homeAssistant.entity.state?.state === "off" || this.agent.has(OnOffBehavior) && !this.agent.get(OnOffBehavior).state.onOff;
|
|
160984
161208
|
const remembered = this.remembered();
|
|
160985
161209
|
if (wasOff) {
|
|
160986
|
-
|
|
161210
|
+
logger211.debug(
|
|
160987
161211
|
`[${homeAssistant.entityId}] power-on write ${percentage}%: restore flag=${restoreOnPowerOn}, last speed=${remembered.percent}`
|
|
160988
161212
|
);
|
|
160989
161213
|
}
|
|
@@ -161176,7 +161400,7 @@ var FanControlServerBase = class extends FeaturedBase6 {
|
|
|
161176
161400
|
const entityId = this.agent.get(HomeAssistantEntityBehavior).entity.entity_id;
|
|
161177
161401
|
setOptimisticOnOff(entityId, on);
|
|
161178
161402
|
} catch (e) {
|
|
161179
|
-
|
|
161403
|
+
logger211.debug(
|
|
161180
161404
|
`syncOnOff(${on}) failed: ${e instanceof Error ? e.message : String(e)}`
|
|
161181
161405
|
);
|
|
161182
161406
|
}
|
|
@@ -161319,7 +161543,7 @@ var FanOnOffServer = OnOffServer2({
|
|
|
161319
161543
|
});
|
|
161320
161544
|
|
|
161321
161545
|
// src/matter/endpoints/composed/composed-air-purifier-endpoint.ts
|
|
161322
|
-
var
|
|
161546
|
+
var logger212 = Logger.get("ComposedAirPurifierEndpoint");
|
|
161323
161547
|
var temperatureConfig = {
|
|
161324
161548
|
getValue(entity, agent) {
|
|
161325
161549
|
const fallbackUnit = agent.env.get(HomeAssistantConfig).unitSystem.temperature;
|
|
@@ -161537,7 +161761,7 @@ var ComposedAirPurifierEndpoint = class _ComposedAirPurifierEndpoint extends End
|
|
|
161537
161761
|
config8.powerEntityId ? "+Pwr" : "",
|
|
161538
161762
|
config8.energyEntityId ? "+Nrg" : ""
|
|
161539
161763
|
].filter(Boolean).join("");
|
|
161540
|
-
|
|
161764
|
+
logger212.info(
|
|
161541
161765
|
`Created composed air purifier ${primaryEntityId}: ${clusterLabels}`
|
|
161542
161766
|
);
|
|
161543
161767
|
return endpoint;
|
|
@@ -161855,12 +162079,12 @@ var ClimateHumidityMeasurementServer = HumidityMeasurementServer(humidityConfig2
|
|
|
161855
162079
|
// src/matter/endpoints/legacy/climate/behaviors/climate-on-off-server.ts
|
|
161856
162080
|
init_esm();
|
|
161857
162081
|
init_home_assistant_entity_behavior();
|
|
161858
|
-
var
|
|
162082
|
+
var logger213 = Logger.get("ClimateOnOffServer");
|
|
161859
162083
|
var ClimateOnOffServer = OnOffServer2({
|
|
161860
162084
|
turnOn: (_value, agent) => {
|
|
161861
162085
|
const entity = agent.get(HomeAssistantEntityBehavior).entity;
|
|
161862
162086
|
if (entity.state.state !== "off" && agent.get(OnOffServer).state.onOff) {
|
|
161863
|
-
|
|
162087
|
+
logger213.debug(
|
|
161864
162088
|
`[${entity.entity_id}] Skipping redundant OnOff.on(), cached state "${entity.state.state}"`
|
|
161865
162089
|
);
|
|
161866
162090
|
return void 0;
|
|
@@ -161894,7 +162118,8 @@ init_home_assistant_entity_behavior();
|
|
|
161894
162118
|
// src/matter/behaviors/thermostat-server.ts
|
|
161895
162119
|
init_esm();
|
|
161896
162120
|
init_home_assistant_entity_behavior();
|
|
161897
|
-
|
|
162121
|
+
init_transaction_is_offline();
|
|
162122
|
+
var logger214 = Logger.get("ThermostatServer");
|
|
161898
162123
|
var SystemMode = Thermostat3.SystemMode;
|
|
161899
162124
|
var RunningMode = Thermostat3.ThermostatRunningMode;
|
|
161900
162125
|
var nudgingSetpoints = /* @__PURE__ */ new Set();
|
|
@@ -161973,7 +162198,7 @@ function clearInactiveSetpointState(self, scope) {
|
|
|
161973
162198
|
}
|
|
161974
162199
|
function thermostatPreInitialize(self) {
|
|
161975
162200
|
const currentLocal = self.state.localTemperature;
|
|
161976
|
-
|
|
162201
|
+
logger214.debug(
|
|
161977
162202
|
`initialize: features - heating=${self.features.heating}, cooling=${self.features.cooling}`
|
|
161978
162203
|
);
|
|
161979
162204
|
const localValue = typeof currentLocal === "number" && !Number.isNaN(currentLocal) ? currentLocal : currentLocal === null ? null : 2100;
|
|
@@ -162020,7 +162245,7 @@ function thermostatPreInitialize(self) {
|
|
|
162020
162245
|
} else {
|
|
162021
162246
|
clearInactiveSetpointState(self, "Cool");
|
|
162022
162247
|
}
|
|
162023
|
-
|
|
162248
|
+
logger214.debug(
|
|
162024
162249
|
`initialize: after force-set - local=${self.state.localTemperature}`
|
|
162025
162250
|
);
|
|
162026
162251
|
self.state.thermostatRunningState = runningStateAllOff;
|
|
@@ -162113,7 +162338,7 @@ var ThermostatServerBase = class extends FullFeaturedBase {
|
|
|
162113
162338
|
maxCoolLimit,
|
|
162114
162339
|
"cool"
|
|
162115
162340
|
);
|
|
162116
|
-
|
|
162341
|
+
logger214.debug(
|
|
162117
162342
|
`update: limits heat=[${minHeatLimit}, ${maxHeatLimit}], cool=[${minCoolLimit}, ${maxCoolLimit}], systemMode=${systemMode}, runningMode=${runningMode}`
|
|
162118
162343
|
);
|
|
162119
162344
|
let controlSequence = config8.getControlSequence(entity.state, this.agent);
|
|
@@ -162186,18 +162411,18 @@ var ThermostatServerBase = class extends FullFeaturedBase {
|
|
|
162186
162411
|
*/
|
|
162187
162412
|
// biome-ignore lint/correctness/noUnusedPrivateClassMembers: Called via thermostatPostInitialize + prototype copy
|
|
162188
162413
|
heatingSetpointChanging(value, _oldValue, context) {
|
|
162189
|
-
|
|
162414
|
+
logger214.debug(
|
|
162190
162415
|
`heatingSetpointChanging: value=${value}, oldValue=${_oldValue}, isOffline=${transactionIsOffline(context)}`
|
|
162191
162416
|
);
|
|
162192
162417
|
if (transactionIsOffline(context)) {
|
|
162193
|
-
|
|
162418
|
+
logger214.debug(
|
|
162194
162419
|
"heatingSetpointChanging: skipping - transaction is offline"
|
|
162195
162420
|
);
|
|
162196
162421
|
return;
|
|
162197
162422
|
}
|
|
162198
162423
|
const next = Temperature.celsius(value / 100);
|
|
162199
162424
|
if (!next) {
|
|
162200
|
-
|
|
162425
|
+
logger214.debug("heatingSetpointChanging: skipping - invalid temperature");
|
|
162201
162426
|
return;
|
|
162202
162427
|
}
|
|
162203
162428
|
this.agent.asLocalActor(() => {
|
|
@@ -162208,7 +162433,7 @@ var ThermostatServerBase = class extends FullFeaturedBase {
|
|
|
162208
162433
|
this.agent
|
|
162209
162434
|
);
|
|
162210
162435
|
const currentMode2 = this.state.systemMode;
|
|
162211
|
-
|
|
162436
|
+
logger214.debug(
|
|
162212
162437
|
`heatingSetpointChanging: supportsRange=${supportsRange}, systemMode=${currentMode2}, features.heating=${this.features.heating}, features.cooling=${this.features.cooling}`
|
|
162213
162438
|
);
|
|
162214
162439
|
if (!supportsRange) {
|
|
@@ -162218,12 +162443,12 @@ var ThermostatServerBase = class extends FullFeaturedBase {
|
|
|
162218
162443
|
const isOff = currentMode2 === Thermostat3.SystemMode.Off;
|
|
162219
162444
|
if (isOff && this.features.heating) {
|
|
162220
162445
|
if (nudgingSetpoints.has(homeAssistant.entityId)) {
|
|
162221
|
-
|
|
162446
|
+
logger214.debug(
|
|
162222
162447
|
`heatingSetpointChanging: skipping auto-resume - nudge write in progress`
|
|
162223
162448
|
);
|
|
162224
162449
|
return;
|
|
162225
162450
|
}
|
|
162226
|
-
|
|
162451
|
+
logger214.info(
|
|
162227
162452
|
`heatingSetpointChanging: auto-resume - switching to Heat (was Off)`
|
|
162228
162453
|
);
|
|
162229
162454
|
const modeAction = config8.setSystemMode(
|
|
@@ -162232,17 +162457,17 @@ var ThermostatServerBase = class extends FullFeaturedBase {
|
|
|
162232
162457
|
);
|
|
162233
162458
|
homeAssistant.callAction(modeAction);
|
|
162234
162459
|
} else if (!isAutoMode && !isHeatingMode) {
|
|
162235
|
-
|
|
162460
|
+
logger214.debug(
|
|
162236
162461
|
`heatingSetpointChanging: skipping - not in heating/auto mode (mode=${currentMode2}, haMode=${haHvacMode})`
|
|
162237
162462
|
);
|
|
162238
162463
|
return;
|
|
162239
162464
|
}
|
|
162240
|
-
|
|
162465
|
+
logger214.debug(
|
|
162241
162466
|
`heatingSetpointChanging: proceeding - isAutoMode=${isAutoMode}, isHeatingMode=${isHeatingMode}, isOff=${isOff}, haMode=${haHvacMode}`
|
|
162242
162467
|
);
|
|
162243
162468
|
}
|
|
162244
162469
|
const coolingSetpoint = this.features.cooling ? this.state.occupiedCoolingSetpoint : value;
|
|
162245
|
-
|
|
162470
|
+
logger214.debug(
|
|
162246
162471
|
`heatingSetpointChanging: calling setTemperature with heat=${next.celsius(true)}, cool=${coolingSetpoint}`
|
|
162247
162472
|
);
|
|
162248
162473
|
this.setTemperature(
|
|
@@ -162281,12 +162506,12 @@ var ThermostatServerBase = class extends FullFeaturedBase {
|
|
|
162281
162506
|
const isOff = currentMode2 === Thermostat3.SystemMode.Off;
|
|
162282
162507
|
if (isOff && !this.features.heating && this.features.cooling) {
|
|
162283
162508
|
if (nudgingSetpoints.has(homeAssistant.entityId)) {
|
|
162284
|
-
|
|
162509
|
+
logger214.debug(
|
|
162285
162510
|
`coolingSetpointChanging: skipping auto-resume - nudge write in progress`
|
|
162286
162511
|
);
|
|
162287
162512
|
return;
|
|
162288
162513
|
}
|
|
162289
|
-
|
|
162514
|
+
logger214.info(
|
|
162290
162515
|
`coolingSetpointChanging: auto-resume - switching to Cool (was Off)`
|
|
162291
162516
|
);
|
|
162292
162517
|
const modeAction = config8.setSystemMode(
|
|
@@ -162295,12 +162520,12 @@ var ThermostatServerBase = class extends FullFeaturedBase {
|
|
|
162295
162520
|
);
|
|
162296
162521
|
homeAssistant.callAction(modeAction);
|
|
162297
162522
|
} else if (!isAutoMode && !isCoolingMode) {
|
|
162298
|
-
|
|
162523
|
+
logger214.debug(
|
|
162299
162524
|
`coolingSetpointChanging: skipping - not in cooling/auto mode (mode=${currentMode2}, haMode=${haHvacMode})`
|
|
162300
162525
|
);
|
|
162301
162526
|
return;
|
|
162302
162527
|
}
|
|
162303
|
-
|
|
162528
|
+
logger214.debug(
|
|
162304
162529
|
`coolingSetpointChanging: proceeding - isAutoMode=${isAutoMode}, isCoolingMode=${isCoolingMode}, isOff=${isOff}, haMode=${haHvacMode}`
|
|
162305
162530
|
);
|
|
162306
162531
|
}
|
|
@@ -162414,7 +162639,7 @@ var ThermostatServerBase = class extends FullFeaturedBase {
|
|
|
162414
162639
|
const effectiveMax = max ?? 5e3;
|
|
162415
162640
|
if (value == null || Number.isNaN(value)) {
|
|
162416
162641
|
const defaultValue = type === "heat" ? 2e3 : 2400;
|
|
162417
|
-
|
|
162642
|
+
logger214.debug(
|
|
162418
162643
|
`${type} setpoint is undefined, using default: ${defaultValue}`
|
|
162419
162644
|
);
|
|
162420
162645
|
return Math.max(effectiveMin, Math.min(effectiveMax, defaultValue));
|
|
@@ -162992,7 +163217,7 @@ function ClimateDevice(homeAssistantEntity, includeBasicInformation = true) {
|
|
|
162992
163217
|
}
|
|
162993
163218
|
|
|
162994
163219
|
// src/matter/endpoints/composed/composed-climate-fan-endpoint.ts
|
|
162995
|
-
var
|
|
163220
|
+
var logger215 = Logger.get("ComposedClimateFanEndpoint");
|
|
162996
163221
|
function createEndpointId3(entityId, customName) {
|
|
162997
163222
|
const baseName = customName || entityId;
|
|
162998
163223
|
return baseName.replace(/\./g, "_").replace(/\s+/g, "_");
|
|
@@ -163030,7 +163255,7 @@ var ComposedClimateFanEndpoint = class _ComposedClimateFanEndpoint extends Endpo
|
|
|
163030
163255
|
climateSub = new Endpoint(climateType, { id: `${endpointId}_climate` });
|
|
163031
163256
|
} catch (error) {
|
|
163032
163257
|
const message = error instanceof Error ? error.message : String(error);
|
|
163033
|
-
|
|
163258
|
+
logger215.warn(
|
|
163034
163259
|
`Companion fan: climate sub build failed for ${primaryEntityId}: ${message}`
|
|
163035
163260
|
);
|
|
163036
163261
|
return void 0;
|
|
@@ -163074,7 +163299,7 @@ var ComposedClimateFanEndpoint = class _ComposedClimateFanEndpoint extends Endpo
|
|
|
163074
163299
|
endpointId,
|
|
163075
163300
|
[climateSub, fanSub]
|
|
163076
163301
|
);
|
|
163077
|
-
|
|
163302
|
+
logger215.info(`Created composed climate+fan endpoint ${primaryEntityId}`);
|
|
163078
163303
|
return endpoint;
|
|
163079
163304
|
}
|
|
163080
163305
|
constructor(type, entityId, id, parts) {
|
|
@@ -163169,7 +163394,7 @@ init_home_assistant_entity_behavior();
|
|
|
163169
163394
|
// src/matter/behaviors/pressure-measurement-server.ts
|
|
163170
163395
|
init_esm();
|
|
163171
163396
|
init_home_assistant_entity_behavior();
|
|
163172
|
-
var
|
|
163397
|
+
var logger216 = Logger.get("PressureMeasurementServer");
|
|
163173
163398
|
var MIN_PRESSURE = 300;
|
|
163174
163399
|
var MAX_PRESSURE = 1100;
|
|
163175
163400
|
var PressureMeasurementServerBase = class extends PressureMeasurementServer {
|
|
@@ -163197,7 +163422,7 @@ var PressureMeasurementServerBase = class extends PressureMeasurementServer {
|
|
|
163197
163422
|
}
|
|
163198
163423
|
const rounded = Math.round(value);
|
|
163199
163424
|
if (rounded < MIN_PRESSURE || rounded > MAX_PRESSURE) {
|
|
163200
|
-
|
|
163425
|
+
logger216.warn(
|
|
163201
163426
|
`Pressure value ${rounded} (raw: ${value}) for ${entity.entity_id} is outside valid range [${MIN_PRESSURE}-${MAX_PRESSURE}], ignoring`
|
|
163202
163427
|
);
|
|
163203
163428
|
return null;
|
|
@@ -163216,7 +163441,7 @@ function PressureMeasurementServer2(config8) {
|
|
|
163216
163441
|
}
|
|
163217
163442
|
|
|
163218
163443
|
// src/matter/endpoints/composed/composed-sensor-endpoint.ts
|
|
163219
|
-
var
|
|
163444
|
+
var logger217 = Logger.get("ComposedSensorEndpoint");
|
|
163220
163445
|
var temperatureConfig2 = {
|
|
163221
163446
|
getValue(entity, agent) {
|
|
163222
163447
|
const fallbackUnit = agent.env.get(HomeAssistantConfig).unitSystem.temperature;
|
|
@@ -163394,7 +163619,7 @@ var ComposedSensorEndpoint = class _ComposedSensorEndpoint extends Endpoint {
|
|
|
163394
163619
|
if (config8.pressureEntityId && pressSub) {
|
|
163395
163620
|
endpoint.subEndpoints.set(config8.pressureEntityId, pressSub);
|
|
163396
163621
|
}
|
|
163397
|
-
|
|
163622
|
+
logger217.info(
|
|
163398
163623
|
`Created composed sensor ${primaryEntityId} with ${parts.length} sub-endpoint(s): T${humSub ? "+H" : ""}${pressSub ? "+P" : ""}${config8.batteryEntityId ? "+Bat" : ""}${config8.powerEntityId ? "+Pwr" : ""}${config8.energyEntityId ? "+Nrg" : ""}`
|
|
163399
163624
|
);
|
|
163400
163625
|
return endpoint;
|
|
@@ -163531,7 +163756,7 @@ init_home_assistant_entity_behavior();
|
|
|
163531
163756
|
// src/matter/behaviors/mode-select-server.ts
|
|
163532
163757
|
init_esm();
|
|
163533
163758
|
init_home_assistant_entity_behavior();
|
|
163534
|
-
var
|
|
163759
|
+
var logger218 = Logger.get("ModeSelectServer");
|
|
163535
163760
|
function buildSupportedModes(options) {
|
|
163536
163761
|
return options.map((label, index) => ({
|
|
163537
163762
|
label: label.length > 64 ? label.substring(0, 64) : label,
|
|
@@ -163568,13 +163793,13 @@ var ModeSelectServerBase = class extends ModeSelectServer {
|
|
|
163568
163793
|
const options = config8.getOptions(homeAssistant.entity);
|
|
163569
163794
|
const { newMode } = request;
|
|
163570
163795
|
if (newMode < 0 || newMode >= options.length) {
|
|
163571
|
-
|
|
163796
|
+
logger218.warn(
|
|
163572
163797
|
`[${homeAssistant.entityId}] Invalid mode ${newMode}, options: [${options.join(", ")}]`
|
|
163573
163798
|
);
|
|
163574
163799
|
return;
|
|
163575
163800
|
}
|
|
163576
163801
|
const option = options[newMode];
|
|
163577
|
-
|
|
163802
|
+
logger218.info(
|
|
163578
163803
|
`[${homeAssistant.entityId}] changeToMode(${newMode}) -> "${option}"`
|
|
163579
163804
|
);
|
|
163580
163805
|
applyPatchState(this.state, { currentMode: newMode });
|
|
@@ -164125,7 +164350,7 @@ var CoAlarmWithBatteryType = SmokeCoAlarmDevice.with(
|
|
|
164125
164350
|
);
|
|
164126
164351
|
|
|
164127
164352
|
// src/matter/endpoints/legacy/binary-sensor/index.ts
|
|
164128
|
-
var
|
|
164353
|
+
var logger219 = Logger.get("BinarySensorDevice");
|
|
164129
164354
|
var deviceClasses = {
|
|
164130
164355
|
[BinarySensorDeviceClass.CarbonMonoxide]: CoAlarmType,
|
|
164131
164356
|
[BinarySensorDeviceClass.Gas]: CoAlarmType,
|
|
@@ -164176,11 +164401,11 @@ function BinarySensorDevice(homeAssistantEntity) {
|
|
|
164176
164401
|
const originalTypeName = type.name;
|
|
164177
164402
|
if (hasBattery && batteryTypes.has(type)) {
|
|
164178
164403
|
type = batteryTypes.get(type);
|
|
164179
|
-
|
|
164404
|
+
logger219.info(
|
|
164180
164405
|
`[${entityId}] Using battery variant: ${originalTypeName} -> ${type.name}, batteryAttr=${hasBatteryAttr}, batteryEntity=${homeAssistantEntity.mapping?.batteryEntity ?? "none"}`
|
|
164181
164406
|
);
|
|
164182
164407
|
} else if (hasBattery) {
|
|
164183
|
-
|
|
164408
|
+
logger219.warn(
|
|
164184
164409
|
`[${entityId}] Has battery but no variant available for ${originalTypeName}`
|
|
164185
164410
|
);
|
|
164186
164411
|
}
|
|
@@ -164267,7 +164492,7 @@ init_home_assistant_entity_behavior();
|
|
|
164267
164492
|
init_esm();
|
|
164268
164493
|
init_home_assistant_actions();
|
|
164269
164494
|
init_home_assistant_entity_behavior();
|
|
164270
|
-
var
|
|
164495
|
+
var logger220 = Logger.get("WindowCoveringServer");
|
|
164271
164496
|
var MovementStatus = WindowCovering3.MovementStatus;
|
|
164272
164497
|
var FeaturedBase7 = WindowCoveringServer.with(
|
|
164273
164498
|
"Lift",
|
|
@@ -164478,7 +164703,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
164478
164703
|
}
|
|
164479
164704
|
return existing100ths ?? current100ths;
|
|
164480
164705
|
};
|
|
164481
|
-
|
|
164706
|
+
logger220.debug(
|
|
164482
164707
|
`Cover update for ${entity.entity_id}: state=${state.state}, lift=${currentLift}%, tilt=${currentTilt}%, ha=${MovementStatus[movementStatus]}, effective=${MovementStatus[globalStatus]}`
|
|
164483
164708
|
);
|
|
164484
164709
|
const overrideType = config8.getCoverType?.(state, this.agent);
|
|
@@ -164523,9 +164748,9 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
164523
164748
|
);
|
|
164524
164749
|
if (Object.keys(appliedPatch).length > 0) {
|
|
164525
164750
|
const hasOperationalChange = "operationalStatus" in appliedPatch;
|
|
164526
|
-
const log = hasOperationalChange ?
|
|
164751
|
+
const log = hasOperationalChange ? logger220.info : logger220.debug;
|
|
164527
164752
|
log.call(
|
|
164528
|
-
|
|
164753
|
+
logger220,
|
|
164529
164754
|
`Cover ${entity.entity_id} state changed: ${JSON.stringify(appliedPatch)}`
|
|
164530
164755
|
);
|
|
164531
164756
|
}
|
|
@@ -164634,7 +164859,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
164634
164859
|
}
|
|
164635
164860
|
});
|
|
164636
164861
|
} catch (error) {
|
|
164637
|
-
|
|
164862
|
+
logger220.debug(
|
|
164638
164863
|
`Optimistic ${axis} timeout write failed (endpoint may be closing): ${error}`
|
|
164639
164864
|
);
|
|
164640
164865
|
}
|
|
@@ -164644,12 +164869,32 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
164644
164869
|
optimistic[axis] = { status: status3, startedAt, timer, expectedRestEnd };
|
|
164645
164870
|
this.writeOperationalStatus({ [axis]: status3 });
|
|
164646
164871
|
}
|
|
164872
|
+
// matter.js runs handleMovement as a worker, so a throw in there cannot fail
|
|
164873
|
+
// the command. The commands that start movement check up front instead, and
|
|
164874
|
+
// the HA call is deferred past the debounce anyway, outside the transaction
|
|
164875
|
+
// where a rollback could not undo the optimistic target (#446).
|
|
164876
|
+
async upOrOpen() {
|
|
164877
|
+
this.agent.get(HomeAssistantEntityBehavior).assertAvailable();
|
|
164878
|
+
return super.upOrOpen();
|
|
164879
|
+
}
|
|
164880
|
+
async downOrClose() {
|
|
164881
|
+
this.agent.get(HomeAssistantEntityBehavior).assertAvailable();
|
|
164882
|
+
return super.downOrClose();
|
|
164883
|
+
}
|
|
164884
|
+
async goToLiftPercentage(request) {
|
|
164885
|
+
this.agent.get(HomeAssistantEntityBehavior).assertAvailable();
|
|
164886
|
+
return super.goToLiftPercentage(request);
|
|
164887
|
+
}
|
|
164888
|
+
async goToTiltPercentage(request) {
|
|
164889
|
+
this.agent.get(HomeAssistantEntityBehavior).assertAvailable();
|
|
164890
|
+
return super.goToTiltPercentage(request);
|
|
164891
|
+
}
|
|
164647
164892
|
async handleMovement(type, _, direction, targetPercent100ths) {
|
|
164648
164893
|
const currentLift = this.state.currentPositionLiftPercent100ths ?? 0;
|
|
164649
164894
|
const currentTilt = this.state.currentPositionTiltPercent100ths ?? 0;
|
|
164650
164895
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
164651
164896
|
const flags2 = this.state.config.getDiagnosticFlags?.(this.agent);
|
|
164652
|
-
|
|
164897
|
+
logger220.info(
|
|
164653
164898
|
`handleMovement ${homeAssistant.entityId}: type=${MovementType[type]}, direction=${MovementDirection[direction]}, target=${targetPercent100ths}, currentLift=${currentLift}, currentTilt=${currentTilt}${flags2 ? `, ${flags2}` : ""}`
|
|
164654
164899
|
);
|
|
164655
164900
|
if (type === MovementType.Lift) {
|
|
@@ -164668,7 +164913,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
164668
164913
|
}
|
|
164669
164914
|
} else if (type === MovementType.Tilt) {
|
|
164670
164915
|
if (targetPercent100ths == null && this.lastLiftMovementDirection === direction && Date.now() - this.lastLiftMovementMs < 50) {
|
|
164671
|
-
|
|
164916
|
+
logger220.info(
|
|
164672
164917
|
`Skipping tilt ${MovementDirection[direction]}, lift already moving in same direction`
|
|
164673
164918
|
);
|
|
164674
164919
|
return;
|
|
@@ -164713,7 +164958,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
164713
164958
|
} else {
|
|
164714
164959
|
this.startOptimisticMovement("lift", MovementStatus.Opening, end);
|
|
164715
164960
|
}
|
|
164716
|
-
|
|
164961
|
+
logger220.info(
|
|
164717
164962
|
`handleLiftOpen ${homeAssistant.entityId}: calling action=${action.action}, atRest=${atRest}, ${this.state.config.getDiagnosticFlags?.(this.agent) ?? ""}`
|
|
164718
164963
|
);
|
|
164719
164964
|
homeAssistant.callAction(action);
|
|
@@ -164729,7 +164974,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
164729
164974
|
} else {
|
|
164730
164975
|
this.startOptimisticMovement("lift", MovementStatus.Closing, end);
|
|
164731
164976
|
}
|
|
164732
|
-
|
|
164977
|
+
logger220.info(
|
|
164733
164978
|
`handleLiftClose ${homeAssistant.entityId}: calling action=${action.action}, atRest=${atRest}, ${this.state.config.getDiagnosticFlags?.(this.agent) ?? ""}`
|
|
164734
164979
|
);
|
|
164735
164980
|
homeAssistant.callAction(action);
|
|
@@ -164759,7 +165004,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
164759
165004
|
const isFirstInSequence = timeSinceLastCommand > _WindowCoveringServerBase.COMMAND_SEQUENCE_THRESHOLD_MS;
|
|
164760
165005
|
const overrideMs = this.resolveDebounceOverride(homeAssistant);
|
|
164761
165006
|
const debounceMs = overrideMs != null ? overrideMs : isFirstInSequence ? _WindowCoveringServerBase.DEBOUNCE_INITIAL_MS : _WindowCoveringServerBase.DEBOUNCE_SUBSEQUENT_MS;
|
|
164762
|
-
|
|
165007
|
+
logger220.debug(
|
|
164763
165008
|
`Lift command: target=${targetPosition}%, debounce=${debounceMs}ms (${overrideMs != null ? "override" : isFirstInSequence ? "initial" : "subsequent"})`
|
|
164764
165009
|
);
|
|
164765
165010
|
if (st.liftTimer) {
|
|
@@ -164791,7 +165036,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
164791
165036
|
this.startOptimisticMovement("tilt", MovementStatus.Opening, end);
|
|
164792
165037
|
}
|
|
164793
165038
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
164794
|
-
|
|
165039
|
+
logger220.info(
|
|
164795
165040
|
`handleTiltOpen ${homeAssistant.entityId}: calling action=${action.action}, atRest=${atRest}, ${this.state.config.getDiagnosticFlags?.(this.agent) ?? ""}`
|
|
164796
165041
|
);
|
|
164797
165042
|
homeAssistant.callAction(action);
|
|
@@ -164809,7 +165054,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
164809
165054
|
this.startOptimisticMovement("tilt", MovementStatus.Closing, end);
|
|
164810
165055
|
}
|
|
164811
165056
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
164812
|
-
|
|
165057
|
+
logger220.info(
|
|
164813
165058
|
`handleTiltClose ${homeAssistant.entityId}: calling action=${action.action}, atRest=${atRest}, ${this.state.config.getDiagnosticFlags?.(this.agent) ?? ""}`
|
|
164814
165059
|
);
|
|
164815
165060
|
homeAssistant.callAction(action);
|
|
@@ -164839,7 +165084,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
164839
165084
|
const isFirstInSequence = timeSinceLastCommand > _WindowCoveringServerBase.COMMAND_SEQUENCE_THRESHOLD_MS;
|
|
164840
165085
|
const overrideMs = this.resolveDebounceOverride(homeAssistant);
|
|
164841
165086
|
const debounceMs = overrideMs != null ? overrideMs : isFirstInSequence ? _WindowCoveringServerBase.DEBOUNCE_INITIAL_MS : _WindowCoveringServerBase.DEBOUNCE_SUBSEQUENT_MS;
|
|
164842
|
-
|
|
165087
|
+
logger220.debug(
|
|
164843
165088
|
`Tilt command: target=${targetPosition}%, debounce=${debounceMs}ms (${overrideMs != null ? "override" : isFirstInSequence ? "initial" : "subsequent"})`
|
|
164844
165089
|
);
|
|
164845
165090
|
if (st.tiltTimer) {
|
|
@@ -164891,7 +165136,7 @@ function adjustPositionForWriting(position, flags2, matterSemantics) {
|
|
|
164891
165136
|
}
|
|
164892
165137
|
|
|
164893
165138
|
// src/matter/endpoints/legacy/cover/behaviors/cover-window-covering-server.ts
|
|
164894
|
-
var
|
|
165139
|
+
var logger221 = Logger.get("CoverWindowCoveringServer");
|
|
164895
165140
|
var attributes6 = (entity) => entity.attributes;
|
|
164896
165141
|
var DEVICE_CLASS_TO_MATTER_TYPE = {
|
|
164897
165142
|
curtain: {
|
|
@@ -164963,7 +165208,7 @@ var adjustPositionForReading2 = (position, agent) => {
|
|
|
164963
165208
|
const { featureFlags } = agent.env.get(BridgeDataProvider);
|
|
164964
165209
|
const matterSem = usesMatterSemantics(agent);
|
|
164965
165210
|
const result = adjustPositionForReading(position, featureFlags, matterSem);
|
|
164966
|
-
|
|
165211
|
+
logger221.debug(`adjustPositionForReading: HA=${position}%, result=${result}%`);
|
|
164967
165212
|
return result;
|
|
164968
165213
|
};
|
|
164969
165214
|
var adjustPositionForWriting2 = (position, agent) => {
|
|
@@ -165188,14 +165433,14 @@ var CoverAsDimmableLightWithBatteryType = DimmableLightDevice.with(
|
|
|
165188
165433
|
);
|
|
165189
165434
|
|
|
165190
165435
|
// src/matter/endpoints/legacy/cover/index.ts
|
|
165191
|
-
var
|
|
165436
|
+
var logger222 = Logger.get("CoverDevice");
|
|
165192
165437
|
var CoverDeviceType = (supportedFeatures, hasBattery, entityId) => {
|
|
165193
165438
|
const features = /* @__PURE__ */ new Set();
|
|
165194
165439
|
if (testBit(supportedFeatures, CoverSupportedFeatures.support_open)) {
|
|
165195
165440
|
features.add("Lift");
|
|
165196
165441
|
features.add("PositionAwareLift");
|
|
165197
165442
|
} else {
|
|
165198
|
-
|
|
165443
|
+
logger222.warn(
|
|
165199
165444
|
`[${entityId}] Cover has no support_open feature (supported_features=${supportedFeatures}), adding Lift anyway`
|
|
165200
165445
|
);
|
|
165201
165446
|
features.add("Lift");
|
|
@@ -165210,7 +165455,7 @@ var CoverDeviceType = (supportedFeatures, hasBattery, entityId) => {
|
|
|
165210
165455
|
features.add("PositionAwareTilt");
|
|
165211
165456
|
}
|
|
165212
165457
|
}
|
|
165213
|
-
|
|
165458
|
+
logger222.info(
|
|
165214
165459
|
`[${entityId}] Creating WindowCovering with features: [${[...features].join(", ")}], supported_features=${supportedFeatures}`
|
|
165215
165460
|
);
|
|
165216
165461
|
const baseBehaviors2 = [
|
|
@@ -165234,16 +165479,16 @@ function CoverDevice(homeAssistantEntity) {
|
|
|
165234
165479
|
const hasBatteryEntity = !!homeAssistantEntity.mapping?.batteryEntity;
|
|
165235
165480
|
const hasBattery = hasBatteryAttr || hasBatteryEntity;
|
|
165236
165481
|
if (hasBattery) {
|
|
165237
|
-
|
|
165482
|
+
logger222.info(
|
|
165238
165483
|
`[${entityId}] Creating cover with PowerSource cluster, batteryAttr=${hasBatteryAttr}, batteryEntity=${homeAssistantEntity.mapping?.batteryEntity ?? "none"}`
|
|
165239
165484
|
);
|
|
165240
165485
|
} else {
|
|
165241
|
-
|
|
165486
|
+
logger222.debug(
|
|
165242
165487
|
`[${entityId}] Creating cover without battery (batteryAttr=${hasBatteryAttr}, batteryEntity=${homeAssistantEntity.mapping?.batteryEntity ?? "none"})`
|
|
165243
165488
|
);
|
|
165244
165489
|
}
|
|
165245
165490
|
if (homeAssistantEntity.mapping?.coverExposeAsDimmableLight) {
|
|
165246
|
-
|
|
165491
|
+
logger222.info(`[${entityId}] Exposing cover as a Dimmable Light (#372)`);
|
|
165247
165492
|
const type = hasBattery ? CoverAsDimmableLightWithBatteryType : CoverAsDimmableLightType;
|
|
165248
165493
|
return type.set({ homeAssistantEntity });
|
|
165249
165494
|
}
|
|
@@ -165358,7 +165603,7 @@ function DishwasherEndpoint(homeAssistantEntity) {
|
|
|
165358
165603
|
// src/matter/behaviors/generic-switch-server.ts
|
|
165359
165604
|
init_esm();
|
|
165360
165605
|
init_home_assistant_entity_behavior();
|
|
165361
|
-
var
|
|
165606
|
+
var logger223 = Logger.get("GenericSwitchServer");
|
|
165362
165607
|
var SimpleBase = SwitchServer.with(
|
|
165363
165608
|
"MomentarySwitch",
|
|
165364
165609
|
"MomentarySwitchRelease",
|
|
@@ -165400,7 +165645,7 @@ var HaGenericSwitchServerBase = class extends SimpleBase {
|
|
|
165400
165645
|
await super.initialize();
|
|
165401
165646
|
const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
|
|
165402
165647
|
const entityId = homeAssistant.entityId;
|
|
165403
|
-
|
|
165648
|
+
logger223.debug(`[${entityId}] GenericSwitch initialized (simple)`);
|
|
165404
165649
|
this.reactTo(homeAssistant.onChange, this.handleEventChange);
|
|
165405
165650
|
}
|
|
165406
165651
|
handleEventChange() {
|
|
@@ -165411,7 +165656,7 @@ var HaGenericSwitchServerBase = class extends SimpleBase {
|
|
|
165411
165656
|
const eventType = attrs.event_type;
|
|
165412
165657
|
if (!eventType) return;
|
|
165413
165658
|
const entityId = homeAssistant.entityId;
|
|
165414
|
-
|
|
165659
|
+
logger223.debug(`[${entityId}] Event fired: ${eventType}`);
|
|
165415
165660
|
this.triggerPress(eventType);
|
|
165416
165661
|
}
|
|
165417
165662
|
triggerPress(eventType) {
|
|
@@ -165457,7 +165702,7 @@ var HaGenericSwitchServerMultiBase = class extends FullBase {
|
|
|
165457
165702
|
await super.initialize();
|
|
165458
165703
|
const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
|
|
165459
165704
|
const entityId = homeAssistant.entityId;
|
|
165460
|
-
|
|
165705
|
+
logger223.debug(`[${entityId}] GenericSwitch initialized (multi)`);
|
|
165461
165706
|
this.reactTo(homeAssistant.onChange, this.handleEventChange);
|
|
165462
165707
|
}
|
|
165463
165708
|
handleEventChange() {
|
|
@@ -165468,7 +165713,7 @@ var HaGenericSwitchServerMultiBase = class extends FullBase {
|
|
|
165468
165713
|
const eventType = attrs.event_type;
|
|
165469
165714
|
if (!eventType) return;
|
|
165470
165715
|
const entityId = homeAssistant.entityId;
|
|
165471
|
-
|
|
165716
|
+
logger223.debug(`[${entityId}] Event fired: ${eventType}`);
|
|
165472
165717
|
this.triggerPress(eventType);
|
|
165473
165718
|
}
|
|
165474
165719
|
triggerPress(eventType) {
|
|
@@ -165845,7 +166090,7 @@ init_nodejs();
|
|
|
165845
166090
|
init_home_assistant_entity_behavior();
|
|
165846
166091
|
var OperationalState4 = RvcOperationalState4.OperationalState;
|
|
165847
166092
|
var ErrorState = RvcOperationalState4.ErrorState;
|
|
165848
|
-
var
|
|
166093
|
+
var logger224 = Logger.get("RvcOperationalStateServer");
|
|
165849
166094
|
var activeStates = /* @__PURE__ */ new Set([
|
|
165850
166095
|
OperationalState4.Running,
|
|
165851
166096
|
OperationalState4.SeekingCharger
|
|
@@ -165897,7 +166142,7 @@ var RvcOperationalStateServerBase = class extends RvcOperationalStateServer {
|
|
|
165897
166142
|
{ force: true }
|
|
165898
166143
|
);
|
|
165899
166144
|
if (activeStates.has(previousState) && !activeStates.has(newState)) {
|
|
165900
|
-
|
|
166145
|
+
logger224.info(
|
|
165901
166146
|
`Operation completed: ${OperationalState4[previousState]} -> ${OperationalState4[newState]}`
|
|
165902
166147
|
);
|
|
165903
166148
|
try {
|
|
@@ -165910,7 +166155,7 @@ var RvcOperationalStateServerBase = class extends RvcOperationalStateServer {
|
|
|
165910
166155
|
this.context
|
|
165911
166156
|
);
|
|
165912
166157
|
} catch (e) {
|
|
165913
|
-
|
|
166158
|
+
logger224.debug("Failed to emit operationCompletion event:", e);
|
|
165914
166159
|
}
|
|
165915
166160
|
}
|
|
165916
166161
|
}
|
|
@@ -165945,7 +166190,7 @@ var RvcOperationalStateServerBase = class extends RvcOperationalStateServer {
|
|
|
165945
166190
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
165946
166191
|
homeAssistant.callAction(goHomeAction(void 0, this.agent));
|
|
165947
166192
|
} else {
|
|
165948
|
-
|
|
166193
|
+
logger224.warn("GoHome command received but no goHome action configured");
|
|
165949
166194
|
}
|
|
165950
166195
|
return {
|
|
165951
166196
|
commandResponseState: {
|
|
@@ -165965,7 +166210,7 @@ function RvcOperationalStateServer2(config8) {
|
|
|
165965
166210
|
}
|
|
165966
166211
|
|
|
165967
166212
|
// src/matter/endpoints/legacy/lawn-mower/behaviors/lawn-mower-rvc-operational-state-server.ts
|
|
165968
|
-
var
|
|
166213
|
+
var logger225 = Logger.get("LawnMowerRvcOperationalStateServer");
|
|
165969
166214
|
function mapLawnMowerOperationalState(entity) {
|
|
165970
166215
|
const state = entity.state;
|
|
165971
166216
|
switch (state) {
|
|
@@ -165981,7 +166226,7 @@ function mapLawnMowerOperationalState(entity) {
|
|
|
165981
166226
|
case "unavailable":
|
|
165982
166227
|
return RvcOperationalState4.OperationalState.Error;
|
|
165983
166228
|
default:
|
|
165984
|
-
|
|
166229
|
+
logger225.info(`Unknown lawn_mower state "${state}", treating as Stopped`);
|
|
165985
166230
|
return RvcOperationalState4.OperationalState.Stopped;
|
|
165986
166231
|
}
|
|
165987
166232
|
}
|
|
@@ -166035,7 +166280,7 @@ function inferCleanedAreaProgress(cleanedSqm, orderedAreas) {
|
|
|
166035
166280
|
}
|
|
166036
166281
|
|
|
166037
166282
|
// src/matter/behaviors/rvc-run-mode-server.ts
|
|
166038
|
-
var
|
|
166283
|
+
var logger226 = Logger.get("RvcRunModeServer");
|
|
166039
166284
|
var ROOM_MODE_BASE = 100;
|
|
166040
166285
|
function isRoomMode(mode) {
|
|
166041
166286
|
return mode >= ROOM_MODE_BASE;
|
|
@@ -166161,7 +166406,7 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
|
|
|
166161
166406
|
const s = getSession(this.endpoint);
|
|
166162
166407
|
if (s.loggedShortCircuits.has(reason)) return;
|
|
166163
166408
|
s.loggedShortCircuits.add(reason);
|
|
166164
|
-
|
|
166409
|
+
logger226.info(message);
|
|
166165
166410
|
}
|
|
166166
166411
|
/**
|
|
166167
166412
|
* Read the currentRoomEntity sensor and update currentArea + progress
|
|
@@ -166218,7 +166463,7 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
|
|
|
166218
166463
|
}
|
|
166219
166464
|
}
|
|
166220
166465
|
if (matchedAreaId === null) {
|
|
166221
|
-
|
|
166466
|
+
logger226.info(
|
|
166222
166467
|
`currentRoom sensor: no match for "${roomName}" (segmentId=${segmentId}), activeAreas=[${s.activeAreas.join(", ")}], supportedAreas=[${serviceArea.state.supportedAreas.map((a) => `${a.areaId}:${a.areaInfo.locationInfo?.locationName}`).join(", ")}]`
|
|
166223
166468
|
);
|
|
166224
166469
|
return;
|
|
@@ -166228,14 +166473,14 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
|
|
|
166228
166473
|
s.completedAreas.add(s.lastCurrentArea);
|
|
166229
166474
|
}
|
|
166230
166475
|
s.lastCurrentArea = matchedAreaId;
|
|
166231
|
-
|
|
166476
|
+
logger226.info(
|
|
166232
166477
|
`currentRoom sensor: transition to area ${matchedAreaId} ("${roomName}"), completed: [${[...s.completedAreas].join(", ")}]`
|
|
166233
166478
|
);
|
|
166234
166479
|
this.trySetCurrentArea(matchedAreaId);
|
|
166235
166480
|
} catch (e) {
|
|
166236
166481
|
const msg = e instanceof Error ? e.message : String(e);
|
|
166237
166482
|
if (!msg.includes("No provider for") && !msg.includes("not supported")) {
|
|
166238
|
-
|
|
166483
|
+
logger226.warn(`currentRoom sensor update failed: ${msg}`);
|
|
166239
166484
|
}
|
|
166240
166485
|
}
|
|
166241
166486
|
}
|
|
@@ -166315,7 +166560,7 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
|
|
|
166315
166560
|
cleaned,
|
|
166316
166561
|
ordered
|
|
166317
166562
|
);
|
|
166318
|
-
|
|
166563
|
+
logger226.debug(
|
|
166319
166564
|
`cleanedArea: raw=${raw} baseline=${s.cleanedAreaBaseline} cleaned=${cleaned} sizes=[${ordered.map((o) => `${o.areaId}:${o.sizeSqm}`).join(",")}] -> current=${currentArea} completed=[${completed.join(",")}]`
|
|
166320
166565
|
);
|
|
166321
166566
|
for (const id of completed) {
|
|
@@ -166329,7 +166574,7 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
|
|
|
166329
166574
|
} catch (e) {
|
|
166330
166575
|
const msg = e instanceof Error ? e.message : String(e);
|
|
166331
166576
|
if (!msg.includes("No provider for") && !msg.includes("not supported")) {
|
|
166332
|
-
|
|
166577
|
+
logger226.warn(`cleanedArea room update failed: ${msg}`);
|
|
166333
166578
|
}
|
|
166334
166579
|
}
|
|
166335
166580
|
}
|
|
@@ -166344,7 +166589,7 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
|
|
|
166344
166589
|
const serviceArea = this.agent.get(ServiceAreaBehavior);
|
|
166345
166590
|
if (serviceArea.state.currentArea !== areaId) {
|
|
166346
166591
|
serviceArea.state.currentArea = areaId;
|
|
166347
|
-
|
|
166592
|
+
logger226.debug(`currentArea set to ${areaId}`);
|
|
166348
166593
|
}
|
|
166349
166594
|
this.updateProgress(serviceArea, areaId);
|
|
166350
166595
|
} catch {
|
|
@@ -166627,7 +166872,7 @@ init_nodejs();
|
|
|
166627
166872
|
|
|
166628
166873
|
// src/matter/behaviors/color-control-server.ts
|
|
166629
166874
|
init_home_assistant_entity_behavior();
|
|
166630
|
-
var
|
|
166875
|
+
var logger227 = Logger.get("ColorControlServer");
|
|
166631
166876
|
var optimisticColorState = /* @__PURE__ */ new Map();
|
|
166632
166877
|
var OPTIMISTIC_TIMEOUT_MS3 = 3e3;
|
|
166633
166878
|
var OPTIMISTIC_TOLERANCE2 = 5;
|
|
@@ -166666,7 +166911,7 @@ var ColorControlServerBase = class extends FeaturedBase8 {
|
|
|
166666
166911
|
if (this.state.startUpColorTemperatureMireds == null) {
|
|
166667
166912
|
this.state.startUpColorTemperatureMireds = defaultMireds;
|
|
166668
166913
|
}
|
|
166669
|
-
|
|
166914
|
+
logger227.debug(
|
|
166670
166915
|
`initialize: set ColorTemperature defaults - min=${this.state.colorTempPhysicalMinMireds}, max=${this.state.colorTempPhysicalMaxMireds}, current=${this.state.colorTemperatureMireds}`
|
|
166671
166916
|
);
|
|
166672
166917
|
}
|
|
@@ -167220,8 +167465,9 @@ init_home_assistant_entity_behavior();
|
|
|
167220
167465
|
|
|
167221
167466
|
// src/matter/behaviors/lock-server.ts
|
|
167222
167467
|
init_esm();
|
|
167468
|
+
init_types2();
|
|
167223
167469
|
init_home_assistant_entity_behavior();
|
|
167224
|
-
var
|
|
167470
|
+
var logger228 = Logger.get("LockServer");
|
|
167225
167471
|
var SUPPORTED_SLOT = 1;
|
|
167226
167472
|
function normalizeSupportedIndex(index) {
|
|
167227
167473
|
if (index === 0 || index === SUPPORTED_SLOT) {
|
|
@@ -167562,7 +167808,7 @@ var LockServerWithPinBase = class extends PinCredentialBase {
|
|
|
167562
167808
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
167563
167809
|
const action = this.state.config.lock(void 0, this.agent);
|
|
167564
167810
|
const hasPinProvided = !!request.pinCode;
|
|
167565
|
-
|
|
167811
|
+
logger228.debug(
|
|
167566
167812
|
`lockDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}`
|
|
167567
167813
|
);
|
|
167568
167814
|
if (request.pinCode) {
|
|
@@ -167575,12 +167821,12 @@ var LockServerWithPinBase = class extends PinCredentialBase {
|
|
|
167575
167821
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
167576
167822
|
const action = this.state.config.unlock(void 0, this.agent);
|
|
167577
167823
|
const hasPinProvided = !!request.pinCode;
|
|
167578
|
-
|
|
167824
|
+
logger228.debug(
|
|
167579
167825
|
`unlockDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}, requirePin: ${this.state.requirePinForRemoteOperation}`
|
|
167580
167826
|
);
|
|
167581
167827
|
if (this.state.requirePinForRemoteOperation) {
|
|
167582
167828
|
if (!request.pinCode) {
|
|
167583
|
-
|
|
167829
|
+
logger228.info(
|
|
167584
167830
|
`unlockDoor REJECTED for ${homeAssistant.entityId} - no PIN provided`
|
|
167585
167831
|
);
|
|
167586
167832
|
throw new StatusResponseError(
|
|
@@ -167590,12 +167836,12 @@ var LockServerWithPinBase = class extends PinCredentialBase {
|
|
|
167590
167836
|
}
|
|
167591
167837
|
const providedPin = new TextDecoder().decode(request.pinCode);
|
|
167592
167838
|
if (!verifyStoredPinHelper(this.env, homeAssistant.entityId, providedPin)) {
|
|
167593
|
-
|
|
167839
|
+
logger228.info(
|
|
167594
167840
|
`unlockDoor REJECTED for ${homeAssistant.entityId} - invalid PIN`
|
|
167595
167841
|
);
|
|
167596
167842
|
throw new StatusResponseError("Invalid PIN code", StatusCode.Failure);
|
|
167597
167843
|
}
|
|
167598
|
-
|
|
167844
|
+
logger228.debug(`unlockDoor PIN verified for ${homeAssistant.entityId}`);
|
|
167599
167845
|
action.data = { ...action.data, code: providedPin };
|
|
167600
167846
|
}
|
|
167601
167847
|
homeAssistant.callAction(action);
|
|
@@ -167737,7 +167983,7 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
|
|
|
167737
167983
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
167738
167984
|
const action = this.state.config.lock(void 0, this.agent);
|
|
167739
167985
|
const hasPinProvided = !!request.pinCode;
|
|
167740
|
-
|
|
167986
|
+
logger228.debug(
|
|
167741
167987
|
`lockDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}`
|
|
167742
167988
|
);
|
|
167743
167989
|
if (request.pinCode) {
|
|
@@ -167751,12 +167997,12 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
|
|
|
167751
167997
|
const unlatchConfig = this.state.config.unlatch;
|
|
167752
167998
|
const action = unlatchConfig ? unlatchConfig(void 0, this.agent) : this.state.config.unlock(void 0, this.agent);
|
|
167753
167999
|
const hasPinProvided = !!request.pinCode;
|
|
167754
|
-
|
|
168000
|
+
logger228.debug(
|
|
167755
168001
|
`unlockDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}, requirePin: ${this.state.requirePinForRemoteOperation}, usingUnlatch: ${!!unlatchConfig}`
|
|
167756
168002
|
);
|
|
167757
168003
|
if (this.state.requirePinForRemoteOperation) {
|
|
167758
168004
|
if (!request.pinCode) {
|
|
167759
|
-
|
|
168005
|
+
logger228.info(
|
|
167760
168006
|
`unlockDoor REJECTED for ${homeAssistant.entityId} - no PIN provided`
|
|
167761
168007
|
);
|
|
167762
168008
|
throw new StatusResponseError(
|
|
@@ -167766,12 +168012,12 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
|
|
|
167766
168012
|
}
|
|
167767
168013
|
const providedPin = new TextDecoder().decode(request.pinCode);
|
|
167768
168014
|
if (!verifyStoredPinHelper(this.env, homeAssistant.entityId, providedPin)) {
|
|
167769
|
-
|
|
168015
|
+
logger228.info(
|
|
167770
168016
|
`unlockDoor REJECTED for ${homeAssistant.entityId} - invalid PIN`
|
|
167771
168017
|
);
|
|
167772
168018
|
throw new StatusResponseError("Invalid PIN code", StatusCode.Failure);
|
|
167773
168019
|
}
|
|
167774
|
-
|
|
168020
|
+
logger228.debug(`unlockDoor PIN verified for ${homeAssistant.entityId}`);
|
|
167775
168021
|
action.data = { ...action.data, code: providedPin };
|
|
167776
168022
|
}
|
|
167777
168023
|
homeAssistant.callAction(action);
|
|
@@ -167780,12 +168026,12 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
|
|
|
167780
168026
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
167781
168027
|
const action = this.state.config.unlock(void 0, this.agent);
|
|
167782
168028
|
const hasPinProvided = !!request.pinCode;
|
|
167783
|
-
|
|
168029
|
+
logger228.debug(
|
|
167784
168030
|
`unboltDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}, requirePin: ${this.state.requirePinForRemoteOperation}`
|
|
167785
168031
|
);
|
|
167786
168032
|
if (this.state.requirePinForRemoteOperation) {
|
|
167787
168033
|
if (!request.pinCode) {
|
|
167788
|
-
|
|
168034
|
+
logger228.info(
|
|
167789
168035
|
`unboltDoor REJECTED for ${homeAssistant.entityId} - no PIN provided`
|
|
167790
168036
|
);
|
|
167791
168037
|
throw new StatusResponseError(
|
|
@@ -167795,12 +168041,12 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
|
|
|
167795
168041
|
}
|
|
167796
168042
|
const providedPin = new TextDecoder().decode(request.pinCode);
|
|
167797
168043
|
if (!verifyStoredPinHelper(this.env, homeAssistant.entityId, providedPin)) {
|
|
167798
|
-
|
|
168044
|
+
logger228.info(
|
|
167799
168045
|
`unboltDoor REJECTED for ${homeAssistant.entityId} - invalid PIN`
|
|
167800
168046
|
);
|
|
167801
168047
|
throw new StatusResponseError("Invalid PIN code", StatusCode.Failure);
|
|
167802
168048
|
}
|
|
167803
|
-
|
|
168049
|
+
logger228.debug(`unboltDoor PIN verified for ${homeAssistant.entityId}`);
|
|
167804
168050
|
action.data = { ...action.data, code: providedPin };
|
|
167805
168051
|
}
|
|
167806
168052
|
homeAssistant.callAction(action);
|
|
@@ -167939,7 +168185,7 @@ init_home_assistant_entity_behavior();
|
|
|
167939
168185
|
init_dist();
|
|
167940
168186
|
init_esm();
|
|
167941
168187
|
init_home_assistant_entity_behavior();
|
|
167942
|
-
var
|
|
168188
|
+
var logger229 = Logger.get("MediaPlayerKeypadInputServer");
|
|
167943
168189
|
var MediaPlayerKeypadInputServer = class extends KeypadInputServer {
|
|
167944
168190
|
sendKey(request) {
|
|
167945
168191
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
@@ -167950,12 +168196,12 @@ var MediaPlayerKeypadInputServer = class extends KeypadInputServer {
|
|
|
167950
168196
|
const features = attributes9.supported_features ?? 0;
|
|
167951
168197
|
const action = this.mapKeyToAction(request.keyCode, features);
|
|
167952
168198
|
if (!action) {
|
|
167953
|
-
|
|
168199
|
+
logger229.debug(
|
|
167954
168200
|
`Unsupported key code ${request.keyCode} for ${homeAssistant.entityId}`
|
|
167955
168201
|
);
|
|
167956
168202
|
return { status: KeypadInput3.Status.UnsupportedKey };
|
|
167957
168203
|
}
|
|
167958
|
-
|
|
168204
|
+
logger229.debug(
|
|
167959
168205
|
`sendKey(${request.keyCode}) \u2192 ${action} for ${homeAssistant.entityId}`
|
|
167960
168206
|
);
|
|
167961
168207
|
homeAssistant.callAction({ action });
|
|
@@ -168234,7 +168480,7 @@ init_home_assistant_entity_behavior();
|
|
|
168234
168480
|
// src/matter/behaviors/speaker-level-control-server.ts
|
|
168235
168481
|
init_esm();
|
|
168236
168482
|
init_home_assistant_entity_behavior();
|
|
168237
|
-
var
|
|
168483
|
+
var logger230 = Logger.get("SpeakerLevelControlServer");
|
|
168238
168484
|
var optimisticLevelState2 = /* @__PURE__ */ new Map();
|
|
168239
168485
|
var OPTIMISTIC_TIMEOUT_MS4 = 3e3;
|
|
168240
168486
|
var OPTIMISTIC_TOLERANCE3 = 5;
|
|
@@ -168277,7 +168523,7 @@ var SpeakerLevelControlServerBase = class extends FeaturedBase9 {
|
|
|
168277
168523
|
currentLevel = Math.min(Math.max(minLevel, currentLevel), maxLevel);
|
|
168278
168524
|
}
|
|
168279
168525
|
const entityId = this.agent.get(HomeAssistantEntityBehavior).entity.entity_id;
|
|
168280
|
-
|
|
168526
|
+
logger230.debug(
|
|
168281
168527
|
`[${entityId}] Volume update: HA=${currentLevelPercent != null ? Math.round(currentLevelPercent * 100) : "null"}% -> currentLevel=${currentLevel}`
|
|
168282
168528
|
);
|
|
168283
168529
|
const optimistic = optimisticLevelState2.get(entity.entity_id);
|
|
@@ -168325,7 +168571,7 @@ var SpeakerLevelControlServerBase = class extends FeaturedBase9 {
|
|
|
168325
168571
|
const config8 = this.state.config;
|
|
168326
168572
|
const entityId = homeAssistant.entity.entity_id;
|
|
168327
168573
|
const levelPercent = level / 254;
|
|
168328
|
-
|
|
168574
|
+
logger230.debug(
|
|
168329
168575
|
`[${entityId}] Volume command: level=${level} -> HA volume_level=${levelPercent}`
|
|
168330
168576
|
);
|
|
168331
168577
|
const current = config8.getValuePercent(
|
|
@@ -169212,6 +169458,7 @@ var ElectricalUtilityMeterType = ElectricalUtilityMeterDevice.with(
|
|
|
169212
169458
|
|
|
169213
169459
|
// src/matter/endpoints/legacy/sensor/devices/energy-evse.ts
|
|
169214
169460
|
init_esm();
|
|
169461
|
+
init_types2();
|
|
169215
169462
|
init_home_assistant_actions();
|
|
169216
169463
|
init_home_assistant_entity_behavior();
|
|
169217
169464
|
|
|
@@ -169269,7 +169516,7 @@ function mapEvseStatus(rawState, chargingSwitchOn) {
|
|
|
169269
169516
|
}
|
|
169270
169517
|
|
|
169271
169518
|
// src/matter/endpoints/legacy/sensor/devices/energy-evse.ts
|
|
169272
|
-
var
|
|
169519
|
+
var logger231 = Logger.get("EnergyEvse");
|
|
169273
169520
|
var MIN_CHARGE_CURRENT_MA = 6e3;
|
|
169274
169521
|
var MAX_CHARGE_CURRENT_MA = 32e3;
|
|
169275
169522
|
var CIRCUIT_CAPACITY_MA = 32e3;
|
|
@@ -169353,7 +169600,7 @@ var EvseStatusServer = class _EvseStatusServer extends EnergyEvseServer {
|
|
|
169353
169600
|
dispatched = true;
|
|
169354
169601
|
}
|
|
169355
169602
|
if (!dispatched) {
|
|
169356
|
-
|
|
169603
|
+
logger231.debug(
|
|
169357
169604
|
`enableCharging ignored for ${homeAssistant.entityId}: no charging switch or current limit mapped`
|
|
169358
169605
|
);
|
|
169359
169606
|
return;
|
|
@@ -169393,7 +169640,7 @@ var EvseStatusServer = class _EvseStatusServer extends EnergyEvseServer {
|
|
|
169393
169640
|
chargingEnabledUntil: null
|
|
169394
169641
|
});
|
|
169395
169642
|
} catch (error) {
|
|
169396
|
-
|
|
169643
|
+
logger231.debug(
|
|
169397
169644
|
`EVSE charge-window expiry write failed (endpoint may be closing): ${error}`
|
|
169398
169645
|
);
|
|
169399
169646
|
} finally {
|
|
@@ -169424,7 +169671,7 @@ var EvseStatusServer = class _EvseStatusServer extends EnergyEvseServer {
|
|
|
169424
169671
|
chargingEnabledUntil: null
|
|
169425
169672
|
});
|
|
169426
169673
|
} else {
|
|
169427
|
-
|
|
169674
|
+
logger231.debug(
|
|
169428
169675
|
`disable ignored for ${homeAssistant.entityId}: no charging switch mapped`
|
|
169429
169676
|
);
|
|
169430
169677
|
}
|
|
@@ -170229,7 +170476,7 @@ var TvocConcentrationMeasurementServer = class extends TvocConcentrationMeasurem
|
|
|
170229
170476
|
};
|
|
170230
170477
|
|
|
170231
170478
|
// src/matter/endpoints/legacy/sensor/devices/tvoc-sensor.ts
|
|
170232
|
-
var
|
|
170479
|
+
var logger232 = Logger.get("TvocSensor");
|
|
170233
170480
|
function airQualityFromUgm3(value) {
|
|
170234
170481
|
if (value <= 300) return AirQuality3.AirQualityEnum.Good;
|
|
170235
170482
|
if (value <= 1e3) return AirQuality3.AirQualityEnum.Fair;
|
|
@@ -170270,17 +170517,17 @@ var TvocAirQualityServer = class extends TvocAirQualityServerBase {
|
|
|
170270
170517
|
const attributes9 = entity.state.attributes;
|
|
170271
170518
|
const deviceClass = attributes9.device_class;
|
|
170272
170519
|
let airQuality = AirQuality3.AirQualityEnum.Unknown;
|
|
170273
|
-
|
|
170520
|
+
logger232.debug(
|
|
170274
170521
|
`[${entity.entity_id}] TVOC update: state="${state}", device_class="${deviceClass}"`
|
|
170275
170522
|
);
|
|
170276
170523
|
if (state != null && !Number.isNaN(+state)) {
|
|
170277
170524
|
const value = +state;
|
|
170278
170525
|
airQuality = deviceClass === SensorDeviceClass.volatile_organic_compounds ? airQualityFromUgm3(value) : airQualityFromPpb(value);
|
|
170279
|
-
|
|
170526
|
+
logger232.debug(
|
|
170280
170527
|
`[${entity.entity_id}] TVOC value=${value} (${deviceClass}) -> airQuality=${AirQuality3.AirQualityEnum[airQuality]}`
|
|
170281
170528
|
);
|
|
170282
170529
|
} else {
|
|
170283
|
-
|
|
170530
|
+
logger232.warn(
|
|
170284
170531
|
`[${entity.entity_id}] TVOC state not a valid number: "${state}"`
|
|
170285
170532
|
);
|
|
170286
170533
|
}
|
|
@@ -170297,6 +170544,7 @@ var TvocSensorType = AirQualitySensorDevice.with(
|
|
|
170297
170544
|
|
|
170298
170545
|
// src/matter/endpoints/legacy/sensor/index.ts
|
|
170299
170546
|
init_dist();
|
|
170547
|
+
init_types2();
|
|
170300
170548
|
init_diagnostic_event_bus();
|
|
170301
170549
|
|
|
170302
170550
|
// src/matter/behaviors/carbon-dioxide-concentration-measurement-server.ts
|
|
@@ -170494,7 +170742,7 @@ init_home_assistant_entity_behavior();
|
|
|
170494
170742
|
// src/matter/behaviors/pm25-concentration-measurement-server.ts
|
|
170495
170743
|
init_esm();
|
|
170496
170744
|
init_home_assistant_entity_behavior();
|
|
170497
|
-
var
|
|
170745
|
+
var logger233 = Logger.get("Pm25ConcentrationMeasurementServer");
|
|
170498
170746
|
var Pm25ConcentrationMeasurementServerBase = Pm25ConcentrationMeasurementServer.with(
|
|
170499
170747
|
ConcentrationMeasurement3.Feature.NumericMeasurement
|
|
170500
170748
|
);
|
|
@@ -170518,11 +170766,11 @@ var Pm25ConcentrationMeasurementServer2 = class extends Pm25ConcentrationMeasure
|
|
|
170518
170766
|
if (this.state.measurementMedium === void 0) {
|
|
170519
170767
|
this.state.measurementMedium = ConcentrationMeasurement3.MeasurementMedium.Air;
|
|
170520
170768
|
}
|
|
170521
|
-
|
|
170769
|
+
logger233.debug(
|
|
170522
170770
|
"Pm25ConcentrationMeasurementServer: before super.initialize()"
|
|
170523
170771
|
);
|
|
170524
170772
|
await super.initialize();
|
|
170525
|
-
|
|
170773
|
+
logger233.debug(
|
|
170526
170774
|
"Pm25ConcentrationMeasurementServer: after super.initialize()"
|
|
170527
170775
|
);
|
|
170528
170776
|
const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
|
|
@@ -170545,7 +170793,7 @@ var Pm25ConcentrationMeasurementServer2 = class extends Pm25ConcentrationMeasure
|
|
|
170545
170793
|
};
|
|
170546
170794
|
|
|
170547
170795
|
// src/matter/endpoints/legacy/sensor/devices/pm25-sensor.ts
|
|
170548
|
-
var
|
|
170796
|
+
var logger234 = Logger.get("Pm25AirQualityServer");
|
|
170549
170797
|
var Pm25AirQualityServerBase = AirQualityServer.with(
|
|
170550
170798
|
AirQuality3.Feature.Fair,
|
|
170551
170799
|
AirQuality3.Feature.Moderate,
|
|
@@ -170557,9 +170805,9 @@ var Pm25AirQualityServer = class extends Pm25AirQualityServerBase {
|
|
|
170557
170805
|
if (this.state.airQuality === void 0) {
|
|
170558
170806
|
this.state.airQuality = AirQuality3.AirQualityEnum.Unknown;
|
|
170559
170807
|
}
|
|
170560
|
-
|
|
170808
|
+
logger234.debug("Pm25AirQualityServer: before super.initialize()");
|
|
170561
170809
|
await super.initialize();
|
|
170562
|
-
|
|
170810
|
+
logger234.debug("Pm25AirQualityServer: after super.initialize()");
|
|
170563
170811
|
const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
|
|
170564
170812
|
this.update(homeAssistant.entity);
|
|
170565
170813
|
this.reactTo(homeAssistant.onChange, this.update, { offline: true });
|
|
@@ -170984,56 +171232,25 @@ init_home_assistant_entity_behavior();
|
|
|
170984
171232
|
init_dist();
|
|
170985
171233
|
init_esm();
|
|
170986
171234
|
init_home_assistant_entity_behavior();
|
|
170987
|
-
var
|
|
170988
|
-
var IDENTIFY_BUTTON_SUFFIXES = ["_identify", "_locate", "_find_me"];
|
|
171235
|
+
var logger235 = Logger.get("VacuumIdentifyServer");
|
|
170989
171236
|
var VacuumIdentifyServer = class extends IdentifyServer2 {
|
|
170990
|
-
|
|
170991
|
-
this.#locate("triggerEffect");
|
|
170992
|
-
return super.triggerEffect(effect);
|
|
170993
|
-
}
|
|
170994
|
-
identify(request) {
|
|
170995
|
-
if (request.identifyTime > 0) {
|
|
170996
|
-
this.#locate("identify");
|
|
170997
|
-
}
|
|
170998
|
-
return super.identify(request);
|
|
170999
|
-
}
|
|
171000
|
-
#locate(source) {
|
|
171237
|
+
identifyInHomeAssistant(source) {
|
|
171001
171238
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
171002
171239
|
const features = homeAssistant.entity.state.attributes.supported_features ?? 0;
|
|
171003
171240
|
if (testBit(features, VacuumDeviceFeature.LOCATE)) {
|
|
171004
|
-
|
|
171241
|
+
logger235.info(`${source} \u2192 vacuum.locate for ${homeAssistant.entityId}`);
|
|
171005
171242
|
homeAssistant.callAction({ action: "vacuum.locate" });
|
|
171006
171243
|
return;
|
|
171007
171244
|
}
|
|
171008
|
-
|
|
171009
|
-
|
|
171010
|
-
logger234.info(
|
|
171011
|
-
`${source} \u2192 button.press ${sibling} for ${homeAssistant.entityId}`
|
|
171012
|
-
);
|
|
171013
|
-
homeAssistant.callAction({ action: "button.press", target: sibling });
|
|
171245
|
+
if (this.findIdentifyEntity(homeAssistant)) {
|
|
171246
|
+
super.identifyInHomeAssistant(source);
|
|
171014
171247
|
return;
|
|
171015
171248
|
}
|
|
171016
|
-
|
|
171249
|
+
logger235.warn(
|
|
171017
171250
|
`${source} for ${homeAssistant.entityId}, LOCATE not in supported_features (${features}), trying vacuum.locate anyway`
|
|
171018
171251
|
);
|
|
171019
171252
|
homeAssistant.callAction({ action: "vacuum.locate" });
|
|
171020
171253
|
}
|
|
171021
|
-
#findIdentifyButton(homeAssistant) {
|
|
171022
|
-
const deviceId = homeAssistant.entity.registry?.device_id;
|
|
171023
|
-
if (!deviceId) return void 0;
|
|
171024
|
-
const registry3 = this.env.get(HomeAssistantRegistry);
|
|
171025
|
-
for (const entity of Object.values(registry3.entities)) {
|
|
171026
|
-
if (entity.device_id !== deviceId) continue;
|
|
171027
|
-
if (!entity.entity_id.startsWith("button.")) continue;
|
|
171028
|
-
const uniqueId = entity.unique_id ?? "";
|
|
171029
|
-
if (IDENTIFY_BUTTON_SUFFIXES.some(
|
|
171030
|
-
(s) => entity.entity_id.endsWith(s) || uniqueId.endsWith(s)
|
|
171031
|
-
)) {
|
|
171032
|
-
return entity.entity_id;
|
|
171033
|
-
}
|
|
171034
|
-
}
|
|
171035
|
-
return void 0;
|
|
171036
|
-
}
|
|
171037
171254
|
};
|
|
171038
171255
|
|
|
171039
171256
|
// src/matter/endpoints/legacy/vacuum/behaviors/vacuum-rvc-run-mode-server.ts
|
|
@@ -171213,7 +171430,7 @@ init_esm();
|
|
|
171213
171430
|
// src/matter/behaviors/service-area-server.ts
|
|
171214
171431
|
init_esm();
|
|
171215
171432
|
init_home_assistant_entity_behavior();
|
|
171216
|
-
var
|
|
171433
|
+
var logger236 = Logger.get("ServiceAreaServer");
|
|
171217
171434
|
function orderSelection(areas, agent) {
|
|
171218
171435
|
try {
|
|
171219
171436
|
const ascending = agent?.get(HomeAssistantEntityBehavior).state.mapping?.vacuumAscendingRoomOrder === true;
|
|
@@ -171228,7 +171445,7 @@ var ServiceAreaWithProgress = ServiceAreaBehavior.with(
|
|
|
171228
171445
|
var ServiceAreaServerBase = class extends ServiceAreaWithProgress {
|
|
171229
171446
|
selectAreas(request) {
|
|
171230
171447
|
const { newAreas } = request;
|
|
171231
|
-
|
|
171448
|
+
logger236.info(
|
|
171232
171449
|
`ServiceArea selectAreas called with: ${JSON.stringify(newAreas)}`
|
|
171233
171450
|
);
|
|
171234
171451
|
const uniqueAreas = orderSelection([...new Set(newAreas)], this.agent);
|
|
@@ -171237,7 +171454,7 @@ var ServiceAreaServerBase = class extends ServiceAreaWithProgress {
|
|
|
171237
171454
|
(id) => !supportedAreaIds.includes(id)
|
|
171238
171455
|
);
|
|
171239
171456
|
if (invalidAreas.length > 0) {
|
|
171240
|
-
|
|
171457
|
+
logger236.warn(`Invalid area IDs requested: ${invalidAreas.join(", ")}`);
|
|
171241
171458
|
return {
|
|
171242
171459
|
status: ServiceArea3.SelectAreasStatus.UnsupportedArea,
|
|
171243
171460
|
statusText: `Invalid area IDs: ${invalidAreas.join(", ")}`
|
|
@@ -171249,7 +171466,7 @@ var ServiceAreaServerBase = class extends ServiceAreaWithProgress {
|
|
|
171249
171466
|
status: ServiceArea3.OperationalStatus.Pending
|
|
171250
171467
|
}));
|
|
171251
171468
|
this.state.currentArea = null;
|
|
171252
|
-
|
|
171469
|
+
logger236.info(
|
|
171253
171470
|
`ServiceArea: Stored ${uniqueAreas.length} areas for cleaning: ${uniqueAreas.join(", ")}`
|
|
171254
171471
|
);
|
|
171255
171472
|
return {
|
|
@@ -171270,7 +171487,7 @@ var ServiceAreaServerBase = class extends ServiceAreaWithProgress {
|
|
|
171270
171487
|
ServiceAreaServerBase2.State = State;
|
|
171271
171488
|
})(ServiceAreaServerBase || (ServiceAreaServerBase = {}));
|
|
171272
171489
|
function ServiceAreaServer2(initialState) {
|
|
171273
|
-
|
|
171490
|
+
logger236.info(
|
|
171274
171491
|
`Creating ServiceAreaServer with ${initialState.supportedAreas.length} areas`
|
|
171275
171492
|
);
|
|
171276
171493
|
return ServiceAreaServerBase.set({
|
|
@@ -171287,7 +171504,7 @@ var ServiceAreaWithMapsAndProgress = ServiceAreaBehavior.with(
|
|
|
171287
171504
|
var ServiceAreaServerWithMapsBase = class extends ServiceAreaWithMapsAndProgress {
|
|
171288
171505
|
selectAreas(request) {
|
|
171289
171506
|
const { newAreas } = request;
|
|
171290
|
-
|
|
171507
|
+
logger236.info(
|
|
171291
171508
|
`ServiceArea selectAreas called with: ${JSON.stringify(newAreas)}`
|
|
171292
171509
|
);
|
|
171293
171510
|
const uniqueAreas = orderSelection([...new Set(newAreas)], this.agent);
|
|
@@ -171296,7 +171513,7 @@ var ServiceAreaServerWithMapsBase = class extends ServiceAreaWithMapsAndProgress
|
|
|
171296
171513
|
(id) => !supportedAreaIds.includes(id)
|
|
171297
171514
|
);
|
|
171298
171515
|
if (invalidAreas.length > 0) {
|
|
171299
|
-
|
|
171516
|
+
logger236.warn(`Invalid area IDs requested: ${invalidAreas.join(", ")}`);
|
|
171300
171517
|
return {
|
|
171301
171518
|
status: ServiceArea3.SelectAreasStatus.UnsupportedArea,
|
|
171302
171519
|
statusText: `Invalid area IDs: ${invalidAreas.join(", ")}`
|
|
@@ -171308,7 +171525,7 @@ var ServiceAreaServerWithMapsBase = class extends ServiceAreaWithMapsAndProgress
|
|
|
171308
171525
|
status: ServiceArea3.OperationalStatus.Pending
|
|
171309
171526
|
}));
|
|
171310
171527
|
this.state.currentArea = null;
|
|
171311
|
-
|
|
171528
|
+
logger236.info(
|
|
171312
171529
|
`ServiceArea: Stored ${uniqueAreas.length} areas for cleaning: ${uniqueAreas.join(", ")}`
|
|
171313
171530
|
);
|
|
171314
171531
|
return {
|
|
@@ -171329,14 +171546,14 @@ var ServiceAreaServerWithMapsBase = class extends ServiceAreaWithMapsAndProgress
|
|
|
171329
171546
|
ServiceAreaServerWithMapsBase2.State = State;
|
|
171330
171547
|
})(ServiceAreaServerWithMapsBase || (ServiceAreaServerWithMapsBase = {}));
|
|
171331
171548
|
function ServiceAreaServerWithMaps(initialState) {
|
|
171332
|
-
|
|
171549
|
+
logger236.info(
|
|
171333
171550
|
`Creating ServiceAreaServer with Maps: ${initialState.supportedAreas.length} areas, ${initialState.supportedMaps.length} maps`
|
|
171334
171551
|
);
|
|
171335
171552
|
for (const map of initialState.supportedMaps) {
|
|
171336
171553
|
const areaCount = initialState.supportedAreas.filter(
|
|
171337
171554
|
(a) => a.mapId === map.mapId
|
|
171338
171555
|
).length;
|
|
171339
|
-
|
|
171556
|
+
logger236.info(` Map ${map.mapId}: "${map.name}" (${areaCount} areas)`);
|
|
171340
171557
|
}
|
|
171341
171558
|
return ServiceAreaServerWithMapsBase.set({
|
|
171342
171559
|
supportedAreas: initialState.supportedAreas,
|
|
@@ -171348,7 +171565,7 @@ function ServiceAreaServerWithMaps(initialState) {
|
|
|
171348
171565
|
}
|
|
171349
171566
|
|
|
171350
171567
|
// src/matter/endpoints/legacy/vacuum/behaviors/vacuum-service-area-server.ts
|
|
171351
|
-
var
|
|
171568
|
+
var logger237 = Logger.get("VacuumServiceAreaServer");
|
|
171352
171569
|
function toAreaId(roomId) {
|
|
171353
171570
|
if (typeof roomId === "number") {
|
|
171354
171571
|
return roomId;
|
|
@@ -171427,13 +171644,13 @@ function createVacuumServiceAreaServer(attributes9, roomEntities, includeUnnamed
|
|
|
171427
171644
|
let rooms;
|
|
171428
171645
|
if (roomEntities && roomEntities.length > 0) {
|
|
171429
171646
|
rooms = buttonEntitiesToRooms(roomEntities, attributes9);
|
|
171430
|
-
|
|
171647
|
+
logger237.info(
|
|
171431
171648
|
`Using ${rooms.length} button entities as rooms: ${rooms.map((r) => r.name).join(", ")}`
|
|
171432
171649
|
);
|
|
171433
171650
|
} else {
|
|
171434
171651
|
rooms = parseVacuumRooms(attributes9, includeUnnamedRooms);
|
|
171435
171652
|
if (rooms.length > 0) {
|
|
171436
|
-
|
|
171653
|
+
logger237.info(
|
|
171437
171654
|
`Using ${rooms.length} rooms from attributes: ${rooms.map((r) => r.name).join(", ")}`
|
|
171438
171655
|
);
|
|
171439
171656
|
}
|
|
@@ -171487,7 +171704,7 @@ function createCustomServiceAreaServer(customAreas) {
|
|
|
171487
171704
|
landmarkInfo: null
|
|
171488
171705
|
}
|
|
171489
171706
|
}));
|
|
171490
|
-
|
|
171707
|
+
logger237.info(
|
|
171491
171708
|
`Using ${customAreas.length} custom service areas: ${customAreas.map((a) => a.name).join(", ")}`
|
|
171492
171709
|
);
|
|
171493
171710
|
return ServiceAreaServer2({
|
|
@@ -171509,7 +171726,7 @@ function createCleanAreaServiceAreaServer(cleanAreaRooms) {
|
|
|
171509
171726
|
landmarkInfo: null
|
|
171510
171727
|
}
|
|
171511
171728
|
}));
|
|
171512
|
-
|
|
171729
|
+
logger237.info(
|
|
171513
171730
|
`Using ${cleanAreaRooms.length} HA areas via CLEAN_AREA: ${cleanAreaRooms.map((r) => r.name).join(", ")}`
|
|
171514
171731
|
);
|
|
171515
171732
|
return ServiceAreaServer2({
|
|
@@ -171545,11 +171762,11 @@ function getVacuumServiceAreas(attributes9, mapping) {
|
|
|
171545
171762
|
}
|
|
171546
171763
|
|
|
171547
171764
|
// src/matter/endpoints/legacy/vacuum/behaviors/vacuum-rvc-run-mode-server.ts
|
|
171548
|
-
var
|
|
171765
|
+
var logger238 = Logger.get("VacuumRvcRunModeServer");
|
|
171549
171766
|
function buildValetudoSegmentAction(vacuumEntityId, segmentIds, valetudoIdentifier) {
|
|
171550
171767
|
const identifier = valetudoIdentifier || vacuumEntityId.replace(/^vacuum\.valetudo_/, "");
|
|
171551
171768
|
const topic = `valetudo/${identifier}/MapSegmentationCapability/clean/set`;
|
|
171552
|
-
|
|
171769
|
+
logger238.info(
|
|
171553
171770
|
`Valetudo: mqtt.publish to ${topic}, segments: ${segmentIds.join(", ")}`
|
|
171554
171771
|
);
|
|
171555
171772
|
return {
|
|
@@ -171654,14 +171871,14 @@ function mergeBatchData(areas) {
|
|
|
171654
171871
|
function handleCustomServiceAreas(selectedAreas, customAreas, session) {
|
|
171655
171872
|
const matched = selectedAreas.map((areaId) => ({ areaId, area: customAreas[areaId - 1] })).filter((m) => !!m.area);
|
|
171656
171873
|
if (matched.length === 0) {
|
|
171657
|
-
|
|
171874
|
+
logger238.warn(
|
|
171658
171875
|
`Custom service areas: no match for selected IDs ${selectedAreas.join(", ")}`
|
|
171659
171876
|
);
|
|
171660
171877
|
return { action: "vacuum.start" };
|
|
171661
171878
|
}
|
|
171662
171879
|
const batchArea = matched.find(({ area }) => area.batchDispatch === true);
|
|
171663
171880
|
if (batchArea) {
|
|
171664
|
-
|
|
171881
|
+
logger238.info(
|
|
171665
171882
|
`Custom service areas (batch): single call for ${matched.length} room(s): ${matched.map(({ area }) => area.name).join(", ")}`
|
|
171666
171883
|
);
|
|
171667
171884
|
session.pendingDispatches = [];
|
|
@@ -171682,7 +171899,7 @@ function handleCustomServiceAreas(selectedAreas, customAreas, session) {
|
|
|
171682
171899
|
}
|
|
171683
171900
|
};
|
|
171684
171901
|
}
|
|
171685
|
-
|
|
171902
|
+
logger238.info(
|
|
171686
171903
|
`Custom service areas: ${matched.length} room(s) queued: ${matched.map(({ area }) => `${area.service} (${area.name})`).join(", ")}`
|
|
171687
171904
|
);
|
|
171688
171905
|
session.pendingDispatches = matched.slice(1).map(({ areaId, area }) => ({
|
|
@@ -171740,7 +171957,7 @@ function dispatchRoomClean(attributes9, mapping, entityId, selectedAreas, seam)
|
|
|
171740
171957
|
if (cleanAreaRooms && cleanAreaRooms.length > 0) {
|
|
171741
171958
|
const haAreaIds = resolveCleanAreaIds(selectedAreas, cleanAreaRooms);
|
|
171742
171959
|
if (haAreaIds.length > 0) {
|
|
171743
|
-
|
|
171960
|
+
logger238.info(`CLEAN_AREA: cleaning HA areas: ${haAreaIds.join(", ")}`);
|
|
171744
171961
|
return {
|
|
171745
171962
|
action: {
|
|
171746
171963
|
action: "vacuum.clean_area",
|
|
@@ -171760,7 +171977,7 @@ function dispatchRoomClean(attributes9, mapping, entityId, selectedAreas, seam)
|
|
|
171760
171977
|
}
|
|
171761
171978
|
}
|
|
171762
171979
|
if (matched.length > 0) {
|
|
171763
|
-
|
|
171980
|
+
logger238.info(
|
|
171764
171981
|
`Roborock: ${matched.length} room button(s) queued: ${matched.map((m) => m.entityId).join(", ")}`
|
|
171765
171982
|
);
|
|
171766
171983
|
return {
|
|
@@ -171795,12 +172012,12 @@ function dispatchRoomClean(attributes9, mapping, entityId, selectedAreas, seam)
|
|
|
171795
172012
|
}
|
|
171796
172013
|
}
|
|
171797
172014
|
if (roomIds.length > 0) {
|
|
171798
|
-
|
|
172015
|
+
logger238.info(`Starting cleaning with selected areas: ${roomIds.join(", ")}`);
|
|
171799
172016
|
if (isDreameVacuum(attributes9)) {
|
|
171800
172017
|
if (targetMapName) {
|
|
171801
172018
|
const vacName = entityId.replace("vacuum.", "");
|
|
171802
172019
|
const selectedMapEntity = `select.${vacName}_selected_map`;
|
|
171803
|
-
|
|
172020
|
+
logger238.info(
|
|
171804
172021
|
`Dreame multi-floor: switching to map "${targetMapName}" via ${selectedMapEntity}`
|
|
171805
172022
|
);
|
|
171806
172023
|
seam.callAction({
|
|
@@ -171828,7 +172045,7 @@ function dispatchRoomClean(attributes9, mapping, entityId, selectedAreas, seam)
|
|
|
171828
172045
|
}
|
|
171829
172046
|
if (isEcovacsVacuum(attributes9)) {
|
|
171830
172047
|
const roomIdStr = roomIds.join(",");
|
|
171831
|
-
|
|
172048
|
+
logger238.info(`Ecovacs vacuum: Using spot_area for rooms: ${roomIdStr}`);
|
|
171832
172049
|
return {
|
|
171833
172050
|
action: {
|
|
171834
172051
|
action: "vacuum.send_command",
|
|
@@ -171840,7 +172057,7 @@ function dispatchRoomClean(attributes9, mapping, entityId, selectedAreas, seam)
|
|
|
171840
172057
|
pending: []
|
|
171841
172058
|
};
|
|
171842
172059
|
}
|
|
171843
|
-
|
|
172060
|
+
logger238.warn(
|
|
171844
172061
|
`Room cleaning via send_command not supported for this vacuum type. Rooms: ${roomIds.join(", ")}. Falling back to vacuum.start`
|
|
171845
172062
|
);
|
|
171846
172063
|
}
|
|
@@ -171849,7 +172066,7 @@ function dispatchRoomClean(attributes9, mapping, entityId, selectedAreas, seam)
|
|
|
171849
172066
|
var vacuumRvcRunModeConfig = {
|
|
171850
172067
|
getCurrentMode: (entity) => {
|
|
171851
172068
|
const isCleaning = vacuumIsCleaning(entity.state);
|
|
171852
|
-
|
|
172069
|
+
logger238.debug(
|
|
171853
172070
|
`Vacuum state: "${entity.state}", isCleaning: ${isCleaning}, currentMode: ${isCleaning ? "Cleaning" : "Idle"}`
|
|
171854
172071
|
);
|
|
171855
172072
|
return isCleaning ? 1 /* Cleaning */ : 0 /* Idle */;
|
|
@@ -171888,7 +172105,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
171888
172105
|
}
|
|
171889
172106
|
} catch {
|
|
171890
172107
|
}
|
|
171891
|
-
|
|
172108
|
+
logger238.info("Starting regular cleaning (no areas selected)");
|
|
171892
172109
|
return { action: "vacuum.start" };
|
|
171893
172110
|
},
|
|
171894
172111
|
returnToBase: () => ({ action: "vacuum.return_to_base" }),
|
|
@@ -171903,7 +172120,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
171903
172120
|
const homeAssistant = agent.get(HomeAssistantEntityBehavior);
|
|
171904
172121
|
const entity = homeAssistant.entity;
|
|
171905
172122
|
const attributes9 = entity.state.attributes;
|
|
171906
|
-
|
|
172123
|
+
logger238.info(`cleanRoom called: roomMode=${roomMode}`);
|
|
171907
172124
|
const cleanAreaRooms = homeAssistant.state.mapping?.cleanAreaRooms;
|
|
171908
172125
|
if (cleanAreaRooms && cleanAreaRooms.length > 0) {
|
|
171909
172126
|
const sorted = [...cleanAreaRooms].sort(
|
|
@@ -171912,7 +172129,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
171912
172129
|
const areaIndex = roomMode - ROOM_MODE_BASE2 - 1;
|
|
171913
172130
|
if (areaIndex >= 0 && areaIndex < sorted.length) {
|
|
171914
172131
|
const area = sorted[areaIndex];
|
|
171915
|
-
|
|
172132
|
+
logger238.info(
|
|
171916
172133
|
`cleanRoom: CLEAN_AREA "${area.name}" \u2192 vacuum.clean_area(${area.haAreaId})`
|
|
171917
172134
|
);
|
|
171918
172135
|
return {
|
|
@@ -171929,7 +172146,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
171929
172146
|
const areaIndex = roomMode - ROOM_MODE_BASE2 - 1;
|
|
171930
172147
|
if (areaIndex >= 0 && areaIndex < sorted.length) {
|
|
171931
172148
|
const area = sorted[areaIndex];
|
|
171932
|
-
|
|
172149
|
+
logger238.info(
|
|
171933
172150
|
`cleanRoom: custom service area "${area.name}" \u2192 ${area.service}`
|
|
171934
172151
|
);
|
|
171935
172152
|
return {
|
|
@@ -171950,7 +172167,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
171950
172167
|
}
|
|
171951
172168
|
const rooms = parseVacuumRooms(attributes9);
|
|
171952
172169
|
const numericIdFromMode = getRoomIdFromMode(roomMode);
|
|
171953
|
-
|
|
172170
|
+
logger238.info(
|
|
171954
172171
|
`cleanRoom: numericIdFromMode=${numericIdFromMode}, available rooms: ${JSON.stringify(rooms.map((r) => ({ id: r.id, name: r.name, modeValue: getRoomModeValue(r) })))}`
|
|
171955
172172
|
);
|
|
171956
172173
|
const room = rooms.find((r) => getRoomModeValue(r) === roomMode);
|
|
@@ -171960,7 +172177,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
171960
172177
|
if (room.mapName) {
|
|
171961
172178
|
const vacuumName = vacuumEntityId.replace("vacuum.", "");
|
|
171962
172179
|
const selectedMapEntity = `select.${vacuumName}_selected_map`;
|
|
171963
|
-
|
|
172180
|
+
logger238.info(
|
|
171964
172181
|
`Dreame multi-floor: switching to map "${room.mapName}" via ${selectedMapEntity}`
|
|
171965
172182
|
);
|
|
171966
172183
|
homeAssistant.callAction({
|
|
@@ -171969,7 +172186,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
171969
172186
|
data: { option: room.mapName }
|
|
171970
172187
|
});
|
|
171971
172188
|
}
|
|
171972
|
-
|
|
172189
|
+
logger238.debug(
|
|
171973
172190
|
`Dreame vacuum detected, using dreame_vacuum.vacuum_clean_segment for room ${room.name} (commandId: ${commandId3}, id: ${room.id})`
|
|
171974
172191
|
);
|
|
171975
172192
|
return {
|
|
@@ -171980,7 +172197,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
171980
172197
|
};
|
|
171981
172198
|
}
|
|
171982
172199
|
if (isRoborockVacuum(attributes9) || isXiaomiMiotVacuum(attributes9)) {
|
|
171983
|
-
|
|
172200
|
+
logger238.debug(
|
|
171984
172201
|
`Using vacuum.send_command with app_segment_clean for room ${room.name} (commandId: ${commandId3}, id: ${room.id})`
|
|
171985
172202
|
);
|
|
171986
172203
|
return {
|
|
@@ -171993,7 +172210,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
171993
172210
|
}
|
|
171994
172211
|
if (isEcovacsVacuum(attributes9)) {
|
|
171995
172212
|
const roomIdStr = String(commandId3);
|
|
171996
|
-
|
|
172213
|
+
logger238.info(
|
|
171997
172214
|
`Ecovacs vacuum: Using spot_area for room ${room.name} (id: ${roomIdStr})`
|
|
171998
172215
|
);
|
|
171999
172216
|
return {
|
|
@@ -172008,7 +172225,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
172008
172225
|
}
|
|
172009
172226
|
};
|
|
172010
172227
|
}
|
|
172011
|
-
|
|
172228
|
+
logger238.warn(
|
|
172012
172229
|
`Room cleaning via send_command not supported for this vacuum type. Room: ${room.name} (id=${commandId3}). Falling back to vacuum.start`
|
|
172013
172230
|
);
|
|
172014
172231
|
}
|
|
@@ -172025,20 +172242,20 @@ function createVacuumRvcRunModeServer(attributes9, includeUnnamedRooms = false,
|
|
|
172025
172242
|
customAreas,
|
|
172026
172243
|
disableRoomModes
|
|
172027
172244
|
);
|
|
172028
|
-
|
|
172245
|
+
logger238.info(
|
|
172029
172246
|
`Creating VacuumRvcRunModeServer with ${rooms.length} rooms, ${supportedModes2.length} total modes`
|
|
172030
172247
|
);
|
|
172031
172248
|
if (rooms.length > 0) {
|
|
172032
|
-
|
|
172249
|
+
logger238.info(`Rooms found: ${rooms.map((r) => r.name).join(", ")}`);
|
|
172033
172250
|
}
|
|
172034
172251
|
if (filteredCount > 0) {
|
|
172035
172252
|
const filtered = allRooms.filter((r) => !rooms.some((x) => x.id === r.id));
|
|
172036
|
-
|
|
172253
|
+
logger238.info(
|
|
172037
172254
|
`Filtered out ${filteredCount} unnamed room(s): ${filtered.map((r) => r.name).join(", ")}`
|
|
172038
172255
|
);
|
|
172039
172256
|
}
|
|
172040
172257
|
if (allRooms.length === 0) {
|
|
172041
|
-
|
|
172258
|
+
logger238.debug(
|
|
172042
172259
|
`No rooms found. Attributes: rooms=${JSON.stringify(attributes9.rooms)}, segments=${JSON.stringify(attributes9.segments)}, room_list=${attributes9.room_list}`
|
|
172043
172260
|
);
|
|
172044
172261
|
}
|
|
@@ -172072,7 +172289,7 @@ function createCleanAreaRvcRunModeServer(cleanAreaRooms) {
|
|
|
172072
172289
|
modeTags: [{ value: RvcRunMode3.ModeTag.Cleaning }]
|
|
172073
172290
|
});
|
|
172074
172291
|
}
|
|
172075
|
-
|
|
172292
|
+
logger238.info(
|
|
172076
172293
|
`Creating CLEAN_AREA RvcRunModeServer with ${cleanAreaRooms.length} HA areas, ${modes.length} total modes`
|
|
172077
172294
|
);
|
|
172078
172295
|
return RvcRunModeServer2(vacuumRvcRunModeConfig, {
|
|
@@ -172162,7 +172379,7 @@ init_nodejs();
|
|
|
172162
172379
|
|
|
172163
172380
|
// src/matter/behaviors/rvc-clean-mode-server.ts
|
|
172164
172381
|
init_home_assistant_entity_behavior();
|
|
172165
|
-
var
|
|
172382
|
+
var logger239 = Logger.get("RvcCleanModeServerBase");
|
|
172166
172383
|
var RvcCleanModeServerBase = class _RvcCleanModeServerBase extends RvcCleanModeServer {
|
|
172167
172384
|
// Pending mode from a recent changeToMode command.
|
|
172168
172385
|
// Prevents stale HA state (from a different entity like select.xxx)
|
|
@@ -172209,14 +172426,14 @@ var RvcCleanModeServerBase = class _RvcCleanModeServerBase extends RvcCleanModeS
|
|
|
172209
172426
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
172210
172427
|
const { newMode } = request;
|
|
172211
172428
|
if (newMode !== this.state.currentMode && !this.state.supportedModes.some((m) => m.mode === newMode)) {
|
|
172212
|
-
|
|
172429
|
+
logger239.warn(`changeToMode(${newMode}) rejected: unsupported mode`);
|
|
172213
172430
|
return {
|
|
172214
172431
|
status: ModeBase3.ModeChangeStatus.UnsupportedMode,
|
|
172215
172432
|
statusText: `Unsupported mode: ${newMode}`
|
|
172216
172433
|
};
|
|
172217
172434
|
}
|
|
172218
172435
|
const modeLabel = this.state.supportedModes.find((m) => m.mode === newMode);
|
|
172219
|
-
|
|
172436
|
+
logger239.info(
|
|
172220
172437
|
`changeToMode(${newMode}) "${modeLabel?.label ?? "unknown"}" for ${homeAssistant.entityId}`
|
|
172221
172438
|
);
|
|
172222
172439
|
this.pendingMode = newMode;
|
|
@@ -172224,7 +172441,7 @@ var RvcCleanModeServerBase = class _RvcCleanModeServerBase extends RvcCleanModeS
|
|
|
172224
172441
|
this.state.currentMode = newMode;
|
|
172225
172442
|
const action = this.state.config.setCleanMode(newMode, this.agent);
|
|
172226
172443
|
if (action) {
|
|
172227
|
-
|
|
172444
|
+
logger239.info(
|
|
172228
172445
|
`changeToMode: dispatching action ${action.action} \u2192 ${action.target ?? homeAssistant.entityId}`
|
|
172229
172446
|
);
|
|
172230
172447
|
homeAssistant.callAction(action);
|
|
@@ -172257,7 +172474,7 @@ function RvcCleanModeServer2(config8, initialState) {
|
|
|
172257
172474
|
}
|
|
172258
172475
|
|
|
172259
172476
|
// src/matter/endpoints/legacy/vacuum/behaviors/vacuum-rvc-clean-mode-server.ts
|
|
172260
|
-
var
|
|
172477
|
+
var logger240 = Logger.get("VacuumRvcCleanModeServer");
|
|
172261
172478
|
var MODE_VACUUM = 0;
|
|
172262
172479
|
var MODE_VACUUM_AND_MOP = 1;
|
|
172263
172480
|
var MODE_MOP = 2;
|
|
@@ -172527,7 +172744,7 @@ function findMatchingCleanOption(ct, availableOptions) {
|
|
|
172527
172744
|
const match = availableOptions.find((o) => classifyCleanOption(o) === type);
|
|
172528
172745
|
if (match) return match;
|
|
172529
172746
|
}
|
|
172530
|
-
|
|
172747
|
+
logger240.warn(
|
|
172531
172748
|
`No match for ${CLEAN_TYPE_LABELS[ct]} in [${availableOptions.join(", ")}]`
|
|
172532
172749
|
);
|
|
172533
172750
|
return availableOptions[0];
|
|
@@ -172536,7 +172753,7 @@ function buildCleaningModeAction(targetCleanType, agent) {
|
|
|
172536
172753
|
const selectEntityId = getCleaningModeSelectEntity(agent);
|
|
172537
172754
|
const { options } = readSelectEntity(selectEntityId, agent);
|
|
172538
172755
|
const optionToUse = findMatchingCleanOption(targetCleanType, options);
|
|
172539
|
-
|
|
172756
|
+
logger240.info(
|
|
172540
172757
|
`Switching cleaning mode to: ${optionToUse} via ${selectEntityId}`
|
|
172541
172758
|
);
|
|
172542
172759
|
return {
|
|
@@ -172625,7 +172842,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
172625
172842
|
}
|
|
172626
172843
|
}
|
|
172627
172844
|
if (speedMode !== void 0) {
|
|
172628
|
-
|
|
172845
|
+
logger240.debug(
|
|
172629
172846
|
`Current mode: Vacuum + fan_speed="${speedState}" -> mode ${speedMode}`
|
|
172630
172847
|
);
|
|
172631
172848
|
return speedMode;
|
|
@@ -172646,7 +172863,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
172646
172863
|
}
|
|
172647
172864
|
}
|
|
172648
172865
|
if (mopMode !== void 0) {
|
|
172649
|
-
|
|
172866
|
+
logger240.debug(
|
|
172650
172867
|
`Current mode: Mop + intensity="${state}" -> mode ${mopMode}`
|
|
172651
172868
|
);
|
|
172652
172869
|
return mopMode;
|
|
@@ -172664,14 +172881,14 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
172664
172881
|
const homeAssistant = agent.get(HomeAssistantEntityBehavior);
|
|
172665
172882
|
const vacuumEntityId = homeAssistant.entityId;
|
|
172666
172883
|
const mapping = homeAssistant.state.mapping;
|
|
172667
|
-
|
|
172884
|
+
logger240.info(
|
|
172668
172885
|
`setCleanMode(${mode}) for ${vacuumEntityId}, suctionEntity=${mapping?.suctionLevelEntity ?? "none"}, mopEntity=${mapping?.mopIntensityEntity ?? "none"}, fanSpeedList=${JSON.stringify(fanSpeedList ?? [])}, mopIntensityList=${JSON.stringify(mopIntensityList ?? [])}, customTags=${JSON.stringify(customFanSpeedTags ?? {})}`
|
|
172669
172886
|
);
|
|
172670
172887
|
if (mopIntensityList && mopIntensityList.length > 0 && isMopIntensityMode(mode)) {
|
|
172671
172888
|
const mopIndex = mode - MOP_INTENSITY_MODE_BASE;
|
|
172672
172889
|
const mopName = mopIntensityList[mopIndex];
|
|
172673
172890
|
if (!mopName) {
|
|
172674
|
-
|
|
172891
|
+
logger240.warn(`Invalid mop intensity mode index: ${mopIndex}`);
|
|
172675
172892
|
return void 0;
|
|
172676
172893
|
}
|
|
172677
172894
|
if (hasCleanTypes) {
|
|
@@ -172684,18 +172901,18 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
172684
172901
|
mapping.mopIntensityEntity,
|
|
172685
172902
|
agent
|
|
172686
172903
|
);
|
|
172687
|
-
|
|
172904
|
+
logger240.info(
|
|
172688
172905
|
`Mop intensity entity ${mapping.mopIntensityEntity}: current="${state}", options=${JSON.stringify(options ?? [])}`
|
|
172689
172906
|
);
|
|
172690
172907
|
let option = matchMopIntensityOption(mopName, options);
|
|
172691
172908
|
if (!option && options && mopIndex < options.length) {
|
|
172692
172909
|
option = options[mopIndex];
|
|
172693
|
-
|
|
172910
|
+
logger240.info(
|
|
172694
172911
|
`Positional match for mop "${mopName}" -> "${option}" (index ${mopIndex})`
|
|
172695
172912
|
);
|
|
172696
172913
|
}
|
|
172697
172914
|
if (option) {
|
|
172698
|
-
|
|
172915
|
+
logger240.info(
|
|
172699
172916
|
`Setting mop intensity to: ${option} via ${mapping.mopIntensityEntity}`
|
|
172700
172917
|
);
|
|
172701
172918
|
return {
|
|
@@ -172704,11 +172921,11 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
172704
172921
|
target: mapping.mopIntensityEntity
|
|
172705
172922
|
};
|
|
172706
172923
|
}
|
|
172707
|
-
|
|
172924
|
+
logger240.warn(
|
|
172708
172925
|
`No match for mop intensity "${mopName}" in options: [${(options ?? []).join(", ")}]`
|
|
172709
172926
|
);
|
|
172710
172927
|
} else {
|
|
172711
|
-
|
|
172928
|
+
logger240.warn(
|
|
172712
172929
|
`Mop intensity mode ${mode} requested but no mopIntensityEntity configured`
|
|
172713
172930
|
);
|
|
172714
172931
|
}
|
|
@@ -172718,7 +172935,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
172718
172935
|
const fanSpeedIndex = mode - FAN_SPEED_MODE_BASE;
|
|
172719
172936
|
const fanSpeedName = fanSpeedList[fanSpeedIndex];
|
|
172720
172937
|
if (!fanSpeedName) {
|
|
172721
|
-
|
|
172938
|
+
logger240.warn(`Invalid fan speed mode index: ${fanSpeedIndex}`);
|
|
172722
172939
|
return void 0;
|
|
172723
172940
|
}
|
|
172724
172941
|
if (mapping?.suctionLevelEntity) {
|
|
@@ -172731,7 +172948,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
172731
172948
|
mapping.suctionLevelEntity,
|
|
172732
172949
|
agent
|
|
172733
172950
|
);
|
|
172734
|
-
|
|
172951
|
+
logger240.info(
|
|
172735
172952
|
`Suction entity ${mapping.suctionLevelEntity}: current="${state}", options=${JSON.stringify(options ?? [])}`
|
|
172736
172953
|
);
|
|
172737
172954
|
let option = matchFanSpeedOption(
|
|
@@ -172741,12 +172958,12 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
172741
172958
|
);
|
|
172742
172959
|
if (!option && options && fanSpeedIndex < options.length) {
|
|
172743
172960
|
option = options[fanSpeedIndex];
|
|
172744
|
-
|
|
172961
|
+
logger240.info(
|
|
172745
172962
|
`Positional match for fan "${fanSpeedName}" -> "${option}" (index ${fanSpeedIndex})`
|
|
172746
172963
|
);
|
|
172747
172964
|
}
|
|
172748
172965
|
if (option) {
|
|
172749
|
-
|
|
172966
|
+
logger240.info(
|
|
172750
172967
|
`Setting suction to: ${option} via ${mapping.suctionLevelEntity}`
|
|
172751
172968
|
);
|
|
172752
172969
|
return {
|
|
@@ -172755,7 +172972,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
172755
172972
|
target: mapping.suctionLevelEntity
|
|
172756
172973
|
};
|
|
172757
172974
|
}
|
|
172758
|
-
|
|
172975
|
+
logger240.warn(
|
|
172759
172976
|
`No match for fan speed "${fanSpeedName}" in suction options: [${(options ?? []).join(", ")}]`
|
|
172760
172977
|
);
|
|
172761
172978
|
return void 0;
|
|
@@ -172765,7 +172982,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
172765
172982
|
buildCleaningModeAction(0 /* Sweeping */, agent)
|
|
172766
172983
|
);
|
|
172767
172984
|
}
|
|
172768
|
-
|
|
172985
|
+
logger240.info(
|
|
172769
172986
|
`Setting fan speed to: ${fanSpeedName} via vacuum.set_fan_speed`
|
|
172770
172987
|
);
|
|
172771
172988
|
return {
|
|
@@ -172775,7 +172992,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
172775
172992
|
};
|
|
172776
172993
|
}
|
|
172777
172994
|
if (!hasCleanTypes) {
|
|
172778
|
-
|
|
172995
|
+
logger240.debug(
|
|
172779
172996
|
`Ignoring cleaning type change (mode=${mode}): no cleaning mode entity`
|
|
172780
172997
|
);
|
|
172781
172998
|
return void 0;
|
|
@@ -172787,7 +173004,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
172787
173004
|
agent
|
|
172788
173005
|
);
|
|
172789
173006
|
const optionToUse = findMatchingCleanOption(cleanType, availableOptions);
|
|
172790
|
-
|
|
173007
|
+
logger240.info(
|
|
172791
173008
|
`Setting cleaning mode to: ${optionToUse} (mode=${mode}) via ${selectEntityId}`
|
|
172792
173009
|
);
|
|
172793
173010
|
return {
|
|
@@ -172805,10 +173022,10 @@ function createVacuumRvcCleanModeServer(_attributes, fanSpeedList, mopIntensityL
|
|
|
172805
173022
|
cleaningModeOptions,
|
|
172806
173023
|
customFanSpeedTags
|
|
172807
173024
|
);
|
|
172808
|
-
|
|
173025
|
+
logger240.info(
|
|
172809
173026
|
`Creating VacuumRvcCleanModeServer with ${supportedModes2.length} modes (fanSpeedList=${JSON.stringify(fanSpeedList ?? [])}, mopIntensityList=${JSON.stringify(mopIntensityList ?? [])}, cleaningModeOptions=${JSON.stringify(cleaningModeOptions ?? [])}, customTags=${JSON.stringify(customFanSpeedTags ?? {})})`
|
|
172810
173027
|
);
|
|
172811
|
-
|
|
173028
|
+
logger240.info(
|
|
172812
173029
|
`Modes: ${supportedModes2.map((m) => `${m.mode}:${m.label}[${m.modeTags.map((t) => t.value).join(",")}]`).join(", ")}`
|
|
172813
173030
|
);
|
|
172814
173031
|
const initialState = {
|
|
@@ -172871,7 +173088,7 @@ function resolveMopIntensityList(mopIntensityEntity) {
|
|
|
172871
173088
|
init_dist();
|
|
172872
173089
|
init_esm();
|
|
172873
173090
|
init_home_assistant_entity_behavior();
|
|
172874
|
-
var
|
|
173091
|
+
var logger241 = Logger.get("VacuumRvcOperationalStateServer");
|
|
172875
173092
|
function batteryFromAttributes(attrs) {
|
|
172876
173093
|
const raw = attrs.battery_level ?? attrs.battery;
|
|
172877
173094
|
if (raw == null) return null;
|
|
@@ -172922,16 +173139,16 @@ function mapVacuumOperationalState(entity, batteryPercent = batteryFromAttribute
|
|
|
172922
173139
|
operationalState = RvcOperationalState4.OperationalState.Error;
|
|
172923
173140
|
} else {
|
|
172924
173141
|
if (state.toLowerCase().includes("clean")) {
|
|
172925
|
-
|
|
173142
|
+
logger241.info(
|
|
172926
173143
|
`Unknown vacuum state "${state}" contains 'clean', treating as Running`
|
|
172927
173144
|
);
|
|
172928
173145
|
operationalState = RvcOperationalState4.OperationalState.Running;
|
|
172929
173146
|
} else {
|
|
172930
|
-
|
|
173147
|
+
logger241.info(`Unknown vacuum state "${state}", treating as Stopped`);
|
|
172931
173148
|
operationalState = RvcOperationalState4.OperationalState.Stopped;
|
|
172932
173149
|
}
|
|
172933
173150
|
}
|
|
172934
|
-
|
|
173151
|
+
logger241.debug(
|
|
172935
173152
|
`Vacuum operationalState: "${state}" -> ${RvcOperationalState4.OperationalState[operationalState]}`
|
|
172936
173153
|
);
|
|
172937
173154
|
return operationalState;
|
|
@@ -172960,7 +173177,7 @@ var VacuumRvcOperationalStateServer = RvcOperationalStateServer2({
|
|
|
172960
173177
|
});
|
|
172961
173178
|
|
|
172962
173179
|
// src/matter/endpoints/legacy/vacuum/index.ts
|
|
172963
|
-
var
|
|
173180
|
+
var logger242 = Logger.get("VacuumDevice");
|
|
172964
173181
|
var VacuumEndpointType = RoboticVacuumCleanerDevice.with(
|
|
172965
173182
|
BasicInformationServer2,
|
|
172966
173183
|
VacuumIdentifyServer,
|
|
@@ -172974,7 +173191,7 @@ function VacuumDevice(homeAssistantEntity, includeOnOff = false, cleaningModeOpt
|
|
|
172974
173191
|
const entityId = homeAssistantEntity.entity.entity_id;
|
|
172975
173192
|
const attributes9 = homeAssistantEntity.entity.state.attributes;
|
|
172976
173193
|
const customAreas = homeAssistantEntity.mapping?.customServiceAreas;
|
|
172977
|
-
|
|
173194
|
+
logger242.info(
|
|
172978
173195
|
`Creating vacuum endpoint for ${entityId}, mapping: ${JSON.stringify(homeAssistantEntity.mapping ?? "none")}`
|
|
172979
173196
|
);
|
|
172980
173197
|
const cleanAreaRooms = homeAssistantEntity.mapping?.cleanAreaRooms;
|
|
@@ -172987,32 +173204,32 @@ function VacuumDevice(homeAssistantEntity, includeOnOff = false, cleaningModeOpt
|
|
|
172987
173204
|
)
|
|
172988
173205
|
).set({ homeAssistantEntity });
|
|
172989
173206
|
if (includeOnOff) {
|
|
172990
|
-
|
|
173207
|
+
logger242.info(`${entityId}: Adding OnOff cluster (vacuumOnOff flag enabled)`);
|
|
172991
173208
|
device = device.with(VacuumOnOffServer);
|
|
172992
173209
|
}
|
|
172993
173210
|
device = device.with(VacuumPowerSourceServer);
|
|
172994
173211
|
const roomEntities = homeAssistantEntity.mapping?.roomEntities;
|
|
172995
173212
|
const rooms = parseVacuumRooms(attributes9);
|
|
172996
|
-
|
|
173213
|
+
logger242.info(
|
|
172997
173214
|
`${entityId}: customAreas=${customAreas?.length ?? 0}, roomEntities=${JSON.stringify(roomEntities ?? [])}, parsedRooms=${rooms.length}, cleanAreaRooms=${cleanAreaRooms?.length ?? 0}`
|
|
172998
173215
|
);
|
|
172999
173216
|
if (cleanAreaRooms && cleanAreaRooms.length > 0) {
|
|
173000
|
-
|
|
173217
|
+
logger242.info(
|
|
173001
173218
|
`${entityId}: Adding ServiceArea (${cleanAreaRooms.length} HA areas via CLEAN_AREA)`
|
|
173002
173219
|
);
|
|
173003
173220
|
device = device.with(createCleanAreaServiceAreaServer(cleanAreaRooms));
|
|
173004
173221
|
} else if (customAreas && customAreas.length > 0) {
|
|
173005
|
-
|
|
173222
|
+
logger242.info(
|
|
173006
173223
|
`${entityId}: Adding ServiceArea (${customAreas.length} custom areas)`
|
|
173007
173224
|
);
|
|
173008
173225
|
device = device.with(createCustomServiceAreaServer(customAreas));
|
|
173009
173226
|
} else if (rooms.length > 0 || roomEntities && roomEntities.length > 0) {
|
|
173010
|
-
|
|
173227
|
+
logger242.info(`${entityId}: Adding ServiceArea (${rooms.length} rooms)`);
|
|
173011
173228
|
device = device.with(
|
|
173012
173229
|
createVacuumServiceAreaServer(attributes9, roomEntities)
|
|
173013
173230
|
);
|
|
173014
173231
|
} else {
|
|
173015
|
-
|
|
173232
|
+
logger242.info(`${entityId}: Adding ServiceArea (default single-area)`);
|
|
173016
173233
|
device = device.with(createDefaultServiceAreaServer());
|
|
173017
173234
|
}
|
|
173018
173235
|
const fanSpeedList = resolveFanSpeedList(
|
|
@@ -173023,7 +173240,7 @@ function VacuumDevice(homeAssistantEntity, includeOnOff = false, cleaningModeOpt
|
|
|
173023
173240
|
homeAssistantEntity.mapping?.mopIntensityEntity
|
|
173024
173241
|
);
|
|
173025
173242
|
if (cleaningModeOptions || fanSpeedList || mopIntensityList) {
|
|
173026
|
-
|
|
173243
|
+
logger242.info(
|
|
173027
173244
|
`${entityId}: Adding RvcCleanMode (multi-mode, cleaningModeOptions=${JSON.stringify(cleaningModeOptions ?? [])}, fanSpeedList=${JSON.stringify(fanSpeedList ?? [])}, mopIntensityList=${JSON.stringify(mopIntensityList ?? [])})`
|
|
173028
173245
|
);
|
|
173029
173246
|
device = device.with(
|
|
@@ -173036,7 +173253,7 @@ function VacuumDevice(homeAssistantEntity, includeOnOff = false, cleaningModeOpt
|
|
|
173036
173253
|
)
|
|
173037
173254
|
);
|
|
173038
173255
|
} else {
|
|
173039
|
-
|
|
173256
|
+
logger242.info(`${entityId}: Adding RvcCleanMode (default single-mode)`);
|
|
173040
173257
|
device = device.with(createDefaultRvcCleanModeServer());
|
|
173041
173258
|
}
|
|
173042
173259
|
return device;
|
|
@@ -173202,7 +173419,7 @@ var WaterHeaterThermostatServer = ThermostatServer2(
|
|
|
173202
173419
|
);
|
|
173203
173420
|
|
|
173204
173421
|
// src/matter/endpoints/legacy/water-heater/index.ts
|
|
173205
|
-
var
|
|
173422
|
+
var logger243 = Logger.get("WaterHeaterDevice");
|
|
173206
173423
|
var WaterHeaterDeviceType = ThermostatDevice.with(
|
|
173207
173424
|
BasicInformationServer2,
|
|
173208
173425
|
IdentifyServer2,
|
|
@@ -173218,7 +173435,7 @@ function toMatterTemp2(value) {
|
|
|
173218
173435
|
}
|
|
173219
173436
|
function WaterHeaterDevice2(homeAssistantEntity) {
|
|
173220
173437
|
const attributes9 = homeAssistantEntity.entity.state.attributes;
|
|
173221
|
-
|
|
173438
|
+
logger243.debug(
|
|
173222
173439
|
`Creating device for ${homeAssistantEntity.entity.entity_id}, min_temp=${attributes9.min_temp}, max_temp=${attributes9.max_temp}`
|
|
173223
173440
|
);
|
|
173224
173441
|
const minLimit = toMatterTemp2(attributes9.min_temp) ?? 0;
|
|
@@ -173304,6 +173521,7 @@ var WaterHeaterBoostMemoryBehavior = class extends Behavior {
|
|
|
173304
173521
|
// src/matter/endpoints/legacy/water-heater/behaviors/water-heater-management-server.ts
|
|
173305
173522
|
init_dist();
|
|
173306
173523
|
init_esm();
|
|
173524
|
+
init_types2();
|
|
173307
173525
|
init_home_assistant_entity_behavior();
|
|
173308
173526
|
|
|
173309
173527
|
// src/matter/endpoints/legacy/water-heater/water-heater-modes.ts
|
|
@@ -173460,7 +173678,7 @@ function activeHeatSource(attributes9) {
|
|
|
173460
173678
|
}
|
|
173461
173679
|
|
|
173462
173680
|
// src/matter/endpoints/legacy/water-heater/behaviors/water-heater-management-server.ts
|
|
173463
|
-
var
|
|
173681
|
+
var logger244 = Logger.get("WaterHeaterManagementServer");
|
|
173464
173682
|
var MAX_TIMER_MS2 = 2147483647;
|
|
173465
173683
|
var boostSessions = /* @__PURE__ */ new WeakMap();
|
|
173466
173684
|
function clearBoostTimer(endpoint) {
|
|
@@ -173706,7 +173924,7 @@ var WaterHeaterManagementServerBase = class _WaterHeaterManagementServerBase ext
|
|
|
173706
173924
|
armBoostTimer(durationSeconds) {
|
|
173707
173925
|
const delay = durationSeconds * 1e3;
|
|
173708
173926
|
if (!Number.isFinite(delay) || delay <= 0 || delay > MAX_TIMER_MS2) {
|
|
173709
|
-
|
|
173927
|
+
logger244.debug(
|
|
173710
173928
|
`Boost duration ${durationSeconds}s outside the timer range, boost stays active until CancelBoost`
|
|
173711
173929
|
);
|
|
173712
173930
|
return;
|
|
@@ -173720,7 +173938,7 @@ var WaterHeaterManagementServerBase = class _WaterHeaterManagementServerBase ext
|
|
|
173720
173938
|
agent.get(_WaterHeaterManagementServerBase).endBoost({ restoreMode: true });
|
|
173721
173939
|
});
|
|
173722
173940
|
} catch (error) {
|
|
173723
|
-
|
|
173941
|
+
logger244.debug(
|
|
173724
173942
|
`Boost expiry failed (endpoint may be closing): ${error}`
|
|
173725
173943
|
);
|
|
173726
173944
|
}
|
|
@@ -173823,13 +174041,13 @@ function WaterHeaterModeServer2(mapping, initialMode) {
|
|
|
173823
174041
|
}
|
|
173824
174042
|
|
|
173825
174043
|
// src/matter/endpoints/legacy/water-heater/water-heater-management-device.ts
|
|
173826
|
-
var
|
|
174044
|
+
var logger245 = Logger.get("WaterHeaterManagementDevice");
|
|
173827
174045
|
function WaterHeaterManagementDevice(homeAssistantEntity) {
|
|
173828
174046
|
const entityState = homeAssistantEntity.entity.state;
|
|
173829
174047
|
const attributes9 = entityState.attributes;
|
|
173830
174048
|
const modeMapping = buildModeMapping(attributes9);
|
|
173831
174049
|
const initialMode = currentMode(modeMapping, entityState.state, attributes9);
|
|
173832
|
-
|
|
174050
|
+
logger245.debug(
|
|
173833
174051
|
`Creating Matter 1.4 water heater for ${homeAssistantEntity.entity.entity_id}, modes=[${modeMapping.supportedModes.map((m) => `${m.mode}:${m.label}`).join(", ")}], boostMode=${modeMapping.boostOperationMode ?? "none"}`
|
|
173834
174052
|
);
|
|
173835
174053
|
const minLimit = toMatterTemp2(attributes9.min_temp) ?? 0;
|
|
@@ -174100,7 +174318,7 @@ var matterDeviceTypeFactories = {
|
|
|
174100
174318
|
};
|
|
174101
174319
|
|
|
174102
174320
|
// src/matter/endpoints/composed/user-composed-endpoint.ts
|
|
174103
|
-
var
|
|
174321
|
+
var logger246 = Logger.get("UserComposedEndpoint");
|
|
174104
174322
|
function stripBasicInformation(type) {
|
|
174105
174323
|
const behaviors = { ...type.behaviors };
|
|
174106
174324
|
delete behaviors.bridgedDeviceBasicInformation;
|
|
@@ -174176,7 +174394,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
|
|
|
174176
174394
|
{ vacuumOnOff: registry3.isVacuumOnOffEnabled() }
|
|
174177
174395
|
);
|
|
174178
174396
|
if (!primaryType) {
|
|
174179
|
-
|
|
174397
|
+
logger246.warn(
|
|
174180
174398
|
`Cannot create endpoint type for primary entity ${primaryEntityId}`
|
|
174181
174399
|
);
|
|
174182
174400
|
return void 0;
|
|
@@ -174191,7 +174409,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
|
|
|
174191
174409
|
if (!sub.entityId) continue;
|
|
174192
174410
|
const subPayload = buildEntityPayload4(registry3, sub.entityId);
|
|
174193
174411
|
if (!subPayload) {
|
|
174194
|
-
|
|
174412
|
+
logger246.warn(
|
|
174195
174413
|
`Cannot find state for composed sub-entity ${sub.entityId}, it does not exist in Home Assistant (removed or renamed?)`
|
|
174196
174414
|
);
|
|
174197
174415
|
continue;
|
|
@@ -174206,7 +174424,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
|
|
|
174206
174424
|
config8.areaName
|
|
174207
174425
|
);
|
|
174208
174426
|
if (!subType) {
|
|
174209
|
-
|
|
174427
|
+
logger246.warn(
|
|
174210
174428
|
`Cannot create endpoint type for composed sub-entity ${sub.entityId}`
|
|
174211
174429
|
);
|
|
174212
174430
|
continue;
|
|
@@ -174219,7 +174437,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
|
|
|
174219
174437
|
mappedIds.push(sub.entityId);
|
|
174220
174438
|
}
|
|
174221
174439
|
if (parts.length < 2) {
|
|
174222
|
-
|
|
174440
|
+
logger246.warn(
|
|
174223
174441
|
`User composed device ${primaryEntityId}: only ${parts.length} sub-endpoint(s), need at least 2 (primary + one sub-entity). Falling back to standalone.`
|
|
174224
174442
|
);
|
|
174225
174443
|
return void 0;
|
|
@@ -174243,7 +174461,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
|
|
|
174243
174461
|
const labels = parts.map(
|
|
174244
174462
|
(_, i) => i === 0 ? primaryEntityId.split(".")[0] : composedEntities[i - 1]?.entityId?.split(".")[0] ?? "?"
|
|
174245
174463
|
).join("+");
|
|
174246
|
-
|
|
174464
|
+
logger246.info(
|
|
174247
174465
|
`Created user composed device ${primaryEntityId}: ${parts.length} sub-endpoint(s) [${labels}]`
|
|
174248
174466
|
);
|
|
174249
174467
|
return endpoint;
|
|
@@ -174349,7 +174567,7 @@ function asStandaloneEndpointType(type) {
|
|
|
174349
174567
|
}
|
|
174350
174568
|
|
|
174351
174569
|
// src/matter/endpoints/legacy/legacy-endpoint.ts
|
|
174352
|
-
var
|
|
174570
|
+
var logger247 = Logger.get("LegacyEndpoint");
|
|
174353
174571
|
var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
174354
174572
|
constructor(type, entityId, customName, mappedEntityIds, throttleMs, endpointId, vacuumEffective) {
|
|
174355
174573
|
super(type, entityId, customName, mappedEntityIds, endpointId);
|
|
@@ -174365,25 +174583,25 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174365
174583
|
return;
|
|
174366
174584
|
}
|
|
174367
174585
|
if (registry3.isAutoBatteryMappingEnabled() && registry3.isBatteryEntityUsed(entityId)) {
|
|
174368
|
-
|
|
174586
|
+
logger247.debug(
|
|
174369
174587
|
`Skipping ${entityId} - already auto-assigned as battery to another device`
|
|
174370
174588
|
);
|
|
174371
174589
|
return;
|
|
174372
174590
|
}
|
|
174373
174591
|
if (registry3.isAutoHumidityMappingEnabled() && registry3.isHumidityEntityUsed(entityId)) {
|
|
174374
|
-
|
|
174592
|
+
logger247.debug(
|
|
174375
174593
|
`Skipping ${entityId} - already auto-assigned as humidity to a temperature sensor`
|
|
174376
174594
|
);
|
|
174377
174595
|
return;
|
|
174378
174596
|
}
|
|
174379
174597
|
if (registry3.isAutoPressureMappingEnabled() && registry3.isPressureEntityUsed(entityId)) {
|
|
174380
|
-
|
|
174598
|
+
logger247.debug(
|
|
174381
174599
|
`Skipping ${entityId} - already auto-assigned as pressure to a temperature sensor`
|
|
174382
174600
|
);
|
|
174383
174601
|
return;
|
|
174384
174602
|
}
|
|
174385
174603
|
if (registry3.isAutoComposedDevicesEnabled() && registry3.isComposedSubEntityUsed(entityId)) {
|
|
174386
|
-
|
|
174604
|
+
logger247.debug(
|
|
174387
174605
|
`Skipping ${entityId} - already consumed by a composed device`
|
|
174388
174606
|
);
|
|
174389
174607
|
return;
|
|
@@ -174403,7 +174621,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174403
174621
|
humidityEntity: humidityEntityId
|
|
174404
174622
|
};
|
|
174405
174623
|
registry3.markHumidityEntityUsed(humidityEntityId);
|
|
174406
|
-
|
|
174624
|
+
logger247.debug(
|
|
174407
174625
|
`Auto-assigned humidity ${humidityEntityId} to ${entityId}`
|
|
174408
174626
|
);
|
|
174409
174627
|
}
|
|
@@ -174422,7 +174640,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174422
174640
|
pressureEntity: pressureEntityId
|
|
174423
174641
|
};
|
|
174424
174642
|
registry3.markPressureEntityUsed(pressureEntityId);
|
|
174425
|
-
|
|
174643
|
+
logger247.debug(
|
|
174426
174644
|
`Auto-assigned pressure ${pressureEntityId} to ${entityId}`
|
|
174427
174645
|
);
|
|
174428
174646
|
}
|
|
@@ -174440,7 +174658,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174440
174658
|
batteryEntity: batteryEntityId
|
|
174441
174659
|
};
|
|
174442
174660
|
registry3.markBatteryEntityUsed(batteryEntityId);
|
|
174443
|
-
|
|
174661
|
+
logger247.debug(
|
|
174444
174662
|
`Auto-assigned battery ${batteryEntityId} to ${entityId}`
|
|
174445
174663
|
);
|
|
174446
174664
|
}
|
|
@@ -174457,7 +174675,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174457
174675
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
174458
174676
|
faultEntity: faultEntityId
|
|
174459
174677
|
};
|
|
174460
|
-
|
|
174678
|
+
logger247.debug(`Auto-assigned fault ${faultEntityId} to ${entityId}`);
|
|
174461
174679
|
}
|
|
174462
174680
|
}
|
|
174463
174681
|
if (!mapping?.powerEntity) {
|
|
@@ -174473,7 +174691,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174473
174691
|
powerEntity: powerEntityId
|
|
174474
174692
|
};
|
|
174475
174693
|
registry3.markPowerEntityUsed(powerEntityId);
|
|
174476
|
-
|
|
174694
|
+
logger247.debug(`Auto-assigned power ${powerEntityId} to ${entityId}`);
|
|
174477
174695
|
}
|
|
174478
174696
|
}
|
|
174479
174697
|
}
|
|
@@ -174490,7 +174708,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174490
174708
|
energyEntity: energyEntityId
|
|
174491
174709
|
};
|
|
174492
174710
|
registry3.markEnergyEntityUsed(energyEntityId);
|
|
174493
|
-
|
|
174711
|
+
logger247.debug(
|
|
174494
174712
|
`Auto-assigned energy ${energyEntityId} to ${entityId}`
|
|
174495
174713
|
);
|
|
174496
174714
|
}
|
|
@@ -174506,7 +174724,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174506
174724
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
174507
174725
|
cleaningModeEntity: vacuumEntities.cleaningModeEntity
|
|
174508
174726
|
};
|
|
174509
|
-
|
|
174727
|
+
logger247.info(
|
|
174510
174728
|
`Auto-assigned cleaningMode ${vacuumEntities.cleaningModeEntity} to ${entityId}`
|
|
174511
174729
|
);
|
|
174512
174730
|
}
|
|
@@ -174516,7 +174734,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174516
174734
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
174517
174735
|
suctionLevelEntity: vacuumEntities.suctionLevelEntity
|
|
174518
174736
|
};
|
|
174519
|
-
|
|
174737
|
+
logger247.info(
|
|
174520
174738
|
`Auto-assigned suctionLevel ${vacuumEntities.suctionLevelEntity} to ${entityId}`
|
|
174521
174739
|
);
|
|
174522
174740
|
}
|
|
@@ -174526,7 +174744,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174526
174744
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
174527
174745
|
mopIntensityEntity: vacuumEntities.mopIntensityEntity
|
|
174528
174746
|
};
|
|
174529
|
-
|
|
174747
|
+
logger247.info(
|
|
174530
174748
|
`Auto-assigned mopIntensity ${vacuumEntities.mopIntensityEntity} to ${entityId}`
|
|
174531
174749
|
);
|
|
174532
174750
|
}
|
|
@@ -174536,7 +174754,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174536
174754
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
174537
174755
|
currentRoomEntity: vacuumEntities.currentRoomEntity
|
|
174538
174756
|
};
|
|
174539
|
-
|
|
174757
|
+
logger247.info(
|
|
174540
174758
|
`Auto-assigned currentRoom ${vacuumEntities.currentRoomEntity} to ${entityId}`
|
|
174541
174759
|
);
|
|
174542
174760
|
}
|
|
@@ -174551,7 +174769,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174551
174769
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
174552
174770
|
cleanAreaRooms
|
|
174553
174771
|
};
|
|
174554
|
-
|
|
174772
|
+
logger247.info(
|
|
174555
174773
|
`Using ${cleanAreaRooms.length} HA areas via CLEAN_AREA for ${entityId}`
|
|
174556
174774
|
);
|
|
174557
174775
|
}
|
|
@@ -174572,7 +174790,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174572
174790
|
rooms: roomsObj
|
|
174573
174791
|
}
|
|
174574
174792
|
};
|
|
174575
|
-
|
|
174793
|
+
logger247.debug(
|
|
174576
174794
|
`Auto-detected ${valetudoRooms.length} Valetudo segments for ${entityId}`
|
|
174577
174795
|
);
|
|
174578
174796
|
} else {
|
|
@@ -174589,7 +174807,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174589
174807
|
rooms: roomsObj
|
|
174590
174808
|
}
|
|
174591
174809
|
};
|
|
174592
|
-
|
|
174810
|
+
logger247.debug(
|
|
174593
174811
|
`Auto-detected ${roborockRooms.length} Roborock rooms for ${entityId}`
|
|
174594
174812
|
);
|
|
174595
174813
|
}
|
|
@@ -174598,7 +174816,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174598
174816
|
}
|
|
174599
174817
|
}
|
|
174600
174818
|
if (standalone && ((effectiveMapping?.composedEntities?.length ?? 0) > 0 || effectiveMapping?.climateExposeFan === true)) {
|
|
174601
|
-
|
|
174819
|
+
logger247.warn(
|
|
174602
174820
|
`Composed mappings are not supported in server mode, exposing ${entityId} as a flat standalone endpoint`
|
|
174603
174821
|
);
|
|
174604
174822
|
}
|
|
@@ -174617,7 +174835,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174617
174835
|
if (composed) {
|
|
174618
174836
|
return composed;
|
|
174619
174837
|
}
|
|
174620
|
-
|
|
174838
|
+
logger247.warn(
|
|
174621
174839
|
`User composed device creation failed for ${entityId}, falling back to standalone`
|
|
174622
174840
|
);
|
|
174623
174841
|
}
|
|
@@ -174682,7 +174900,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174682
174900
|
if (composed) {
|
|
174683
174901
|
return composed;
|
|
174684
174902
|
}
|
|
174685
|
-
|
|
174903
|
+
logger247.warn(
|
|
174686
174904
|
`Companion fan creation failed for ${entityId}, falling back to standalone`
|
|
174687
174905
|
);
|
|
174688
174906
|
}
|
|
@@ -174760,11 +174978,11 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174760
174978
|
}
|
|
174761
174979
|
if (mappedChanged) {
|
|
174762
174980
|
this.pendingMappedChange = true;
|
|
174763
|
-
|
|
174981
|
+
logger247.debug(
|
|
174764
174982
|
`Mapped entity change detected for ${this.entityId}, forcing update`
|
|
174765
174983
|
);
|
|
174766
174984
|
}
|
|
174767
|
-
|
|
174985
|
+
logger247.debug(
|
|
174768
174986
|
`State update received for ${this.entityId}: state=${state.state}`
|
|
174769
174987
|
);
|
|
174770
174988
|
this.lastState = state;
|
|
@@ -174985,12 +175203,14 @@ var CameraAvStreamServer = class extends Base4 {
|
|
|
174985
175203
|
// src/plugins/builtin/camera/webrtc-provider-server.ts
|
|
174986
175204
|
init_esm();
|
|
174987
175205
|
init_esm7();
|
|
175206
|
+
init_types2();
|
|
174988
175207
|
init_esm3();
|
|
174989
175208
|
|
|
174990
175209
|
// src/plugins/builtin/camera/requestor-client.ts
|
|
174991
175210
|
init_esm();
|
|
175211
|
+
init_types2();
|
|
174992
175212
|
init_esm4();
|
|
174993
|
-
var
|
|
175213
|
+
var logger248 = Logger.get("CameraWebRtcRequestor");
|
|
174994
175214
|
var registry2 = /* @__PURE__ */ new Map();
|
|
174995
175215
|
var pendingDeliveries = /* @__PURE__ */ new Map();
|
|
174996
175216
|
var invokeTransport = defaultInvoke;
|
|
@@ -175024,19 +175244,19 @@ function deliverAnswerDeferred(sessionId, sdp, onGiveUp) {
|
|
|
175024
175244
|
return;
|
|
175025
175245
|
}
|
|
175026
175246
|
if (await sendAnswer(sessionId, sdp)) {
|
|
175027
|
-
|
|
175247
|
+
logger248.info(`answer delivered for session ${sessionId}`);
|
|
175028
175248
|
return;
|
|
175029
175249
|
}
|
|
175030
175250
|
}
|
|
175031
175251
|
if (registry2.get(sessionId) !== owner || pendingDeliveries.get(sessionId) !== timer) {
|
|
175032
175252
|
return;
|
|
175033
175253
|
}
|
|
175034
|
-
|
|
175254
|
+
logger248.info(
|
|
175035
175255
|
`answer delivery failed for session ${sessionId}, giving up`
|
|
175036
175256
|
);
|
|
175037
175257
|
await onGiveUp();
|
|
175038
175258
|
} catch (err) {
|
|
175039
|
-
|
|
175259
|
+
logger248.info(
|
|
175040
175260
|
`answer delivery for session ${sessionId} threw: ${errText(err)}`
|
|
175041
175261
|
);
|
|
175042
175262
|
} finally {
|
|
@@ -175061,11 +175281,11 @@ function sendAnswer(sessionId, sdp) {
|
|
|
175061
175281
|
async function invokeRequestor(sessionId, command, fields) {
|
|
175062
175282
|
const registration = registry2.get(sessionId);
|
|
175063
175283
|
if (!registration) {
|
|
175064
|
-
|
|
175284
|
+
logger248.info(`requestor ${command}: no session ${sessionId} registered`);
|
|
175065
175285
|
return false;
|
|
175066
175286
|
}
|
|
175067
175287
|
if (registration.session.isClosed) {
|
|
175068
|
-
|
|
175288
|
+
logger248.info(`requestor ${command}: session ${sessionId} already closed`);
|
|
175069
175289
|
return false;
|
|
175070
175290
|
}
|
|
175071
175291
|
const request = {
|
|
@@ -175077,7 +175297,7 @@ async function invokeRequestor(sessionId, command, fields) {
|
|
|
175077
175297
|
try {
|
|
175078
175298
|
return await invokeTransport({ registration, request });
|
|
175079
175299
|
} catch (err) {
|
|
175080
|
-
|
|
175300
|
+
logger248.info(
|
|
175081
175301
|
`requestor ${command} failed for session ${sessionId}: ${errText(err)}`
|
|
175082
175302
|
);
|
|
175083
175303
|
return false;
|
|
@@ -175112,7 +175332,7 @@ async function defaultInvoke({
|
|
|
175112
175332
|
for (const entry of chunk) {
|
|
175113
175333
|
if (entry.kind === "cmd-status") {
|
|
175114
175334
|
if (entry.status !== Status2.Success) {
|
|
175115
|
-
|
|
175335
|
+
logger248.info(
|
|
175116
175336
|
`requestor ${request.command} status ${entry.status} for session ${String(request.fields.webRtcSessionId)}`
|
|
175117
175337
|
);
|
|
175118
175338
|
return false;
|
|
@@ -175132,7 +175352,7 @@ function errText(err) {
|
|
|
175132
175352
|
}
|
|
175133
175353
|
|
|
175134
175354
|
// src/plugins/builtin/camera/webrtc-provider-server.ts
|
|
175135
|
-
var
|
|
175355
|
+
var logger249 = Logger.get("CameraWebRtc");
|
|
175136
175356
|
var nextGlobalSessionId = 0;
|
|
175137
175357
|
function mintSessionId() {
|
|
175138
175358
|
for (let i = 0; i <= 65534; i++) {
|
|
@@ -175146,14 +175366,14 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
|
|
|
175146
175366
|
solicitOffer(request) {
|
|
175147
175367
|
const id = mintSessionId();
|
|
175148
175368
|
this.trackSession(id, request.streamUsage, request.originatingEndpointId);
|
|
175149
|
-
|
|
175369
|
+
logger249.info(
|
|
175150
175370
|
`solicitOffer session=${id} (${this.state.entityId}), deferred offer`
|
|
175151
175371
|
);
|
|
175152
175372
|
void this.state.bridge.startSession(id, this.state.entityId, {
|
|
175153
175373
|
iceServers: request.iceServers,
|
|
175154
175374
|
iceTransportPolicy: request.iceTransportPolicy
|
|
175155
175375
|
}).catch(
|
|
175156
|
-
(err) =>
|
|
175376
|
+
(err) => logger249.info(
|
|
175157
175377
|
`solicitOffer startSession failed for ${this.state.entityId}: ${errText2(err)}`
|
|
175158
175378
|
)
|
|
175159
175379
|
);
|
|
@@ -175161,7 +175381,7 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
|
|
|
175161
175381
|
}
|
|
175162
175382
|
async provideOffer(request) {
|
|
175163
175383
|
const id = request.webRtcSessionId ?? mintSessionId();
|
|
175164
|
-
|
|
175384
|
+
logger249.info(
|
|
175165
175385
|
`provideOffer entry: entityId=${this.state.entityId} session=${id} (sdp ${request.sdp.length} chars)`
|
|
175166
175386
|
);
|
|
175167
175387
|
if (request.webRtcSessionId == null) {
|
|
@@ -175195,7 +175415,7 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
|
|
|
175195
175415
|
);
|
|
175196
175416
|
} catch (err) {
|
|
175197
175417
|
const message = errText2(err);
|
|
175198
|
-
|
|
175418
|
+
logger249.info(
|
|
175199
175419
|
`provideOffer failed for ${this.state.entityId} session=${id}: ${message}`
|
|
175200
175420
|
);
|
|
175201
175421
|
unregisterRequestor(id);
|
|
@@ -175207,7 +175427,7 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
|
|
|
175207
175427
|
StatusCode.Failure
|
|
175208
175428
|
);
|
|
175209
175429
|
}
|
|
175210
|
-
|
|
175430
|
+
logger249.info(
|
|
175211
175431
|
`provideOffer answer computed for ${this.state.entityId} session=${id} (${answerSdp.length} chars); delivering via requestor`
|
|
175212
175432
|
);
|
|
175213
175433
|
const bridge = this.state.bridge;
|
|
@@ -175226,7 +175446,7 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
|
|
|
175226
175446
|
return { webRtcSessionId: id };
|
|
175227
175447
|
}
|
|
175228
175448
|
provideAnswer(request) {
|
|
175229
|
-
|
|
175449
|
+
logger249.info(
|
|
175230
175450
|
`provideAnswer session=${request.webRtcSessionId} (sdp ${request.sdp.length} chars, ${this.state.entityId})`
|
|
175231
175451
|
);
|
|
175232
175452
|
return this.state.bridge.acceptControllerAnswer(
|
|
@@ -175235,7 +175455,7 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
|
|
|
175235
175455
|
);
|
|
175236
175456
|
}
|
|
175237
175457
|
async provideIceCandidates(request) {
|
|
175238
|
-
|
|
175458
|
+
logger249.info(
|
|
175239
175459
|
`provideIceCandidates session=${request.webRtcSessionId}: ${request.iceCandidates.length} candidate(s) (${this.state.entityId})`
|
|
175240
175460
|
);
|
|
175241
175461
|
for (const c of request.iceCandidates) {
|
|
@@ -175248,7 +175468,7 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
|
|
|
175248
175468
|
}
|
|
175249
175469
|
}
|
|
175250
175470
|
async endSession(request) {
|
|
175251
|
-
|
|
175471
|
+
logger249.info(
|
|
175252
175472
|
`endSession session=${request.webRtcSessionId} (${this.state.entityId})`
|
|
175253
175473
|
);
|
|
175254
175474
|
await this.state.bridge.endSession(request.webRtcSessionId);
|
|
@@ -175369,7 +175589,7 @@ import {
|
|
|
175369
175589
|
createLongLivedTokenAuth as createLongLivedTokenAuth2
|
|
175370
175590
|
} from "home-assistant-js-websocket";
|
|
175371
175591
|
import { RTCPeerConnection } from "werift";
|
|
175372
|
-
var
|
|
175592
|
+
var logger250 = Logger.get("CameraWebRtc");
|
|
175373
175593
|
var DEFAULT_HA_WEBRTC_TIMEOUT_MS = 15e3;
|
|
175374
175594
|
var haWebRtcTimeoutMs = DEFAULT_HA_WEBRTC_TIMEOUT_MS;
|
|
175375
175595
|
var WebRtcBridge = class {
|
|
@@ -175416,7 +175636,7 @@ var WebRtcBridge = class {
|
|
|
175416
175636
|
const haOffer = await haPeer.createOffer();
|
|
175417
175637
|
await haPeer.setLocalDescription(haOffer);
|
|
175418
175638
|
const haOfferSdp = this.localSdp(haPeer);
|
|
175419
|
-
|
|
175639
|
+
logger250.info(`HA offer sent for ${entityId} (${haOfferSdp.length} chars)`);
|
|
175420
175640
|
const { answer, sessionId, unsubscribe } = await this.requestHaWebRtc(
|
|
175421
175641
|
entityId,
|
|
175422
175642
|
haOfferSdp,
|
|
@@ -175439,12 +175659,12 @@ var WebRtcBridge = class {
|
|
|
175439
175659
|
const controllerOffer = await controllerPeer.createOffer();
|
|
175440
175660
|
await controllerPeer.setLocalDescription(controllerOffer);
|
|
175441
175661
|
const sdp = this.localSdp(controllerPeer);
|
|
175442
|
-
|
|
175662
|
+
logger250.info(
|
|
175443
175663
|
`controller offer created for ${entityId} (${sdp.length} chars)`
|
|
175444
175664
|
);
|
|
175445
175665
|
return { sdp, iceCandidates };
|
|
175446
175666
|
} catch (err) {
|
|
175447
|
-
|
|
175667
|
+
logger250.info(`startSession failed for ${entityId}: ${errText3(err)}`);
|
|
175448
175668
|
await this.endSession(matterSessionId);
|
|
175449
175669
|
throw err;
|
|
175450
175670
|
}
|
|
@@ -175474,7 +175694,7 @@ var WebRtcBridge = class {
|
|
|
175474
175694
|
const haOffer = await haPeer.createOffer();
|
|
175475
175695
|
await haPeer.setLocalDescription(haOffer);
|
|
175476
175696
|
const haOfferSdp = this.localSdp(haPeer);
|
|
175477
|
-
|
|
175697
|
+
logger250.info(`HA offer sent for ${entityId} (${haOfferSdp.length} chars)`);
|
|
175478
175698
|
const { answer, sessionId, unsubscribe } = await this.requestHaWebRtc(
|
|
175479
175699
|
entityId,
|
|
175480
175700
|
haOfferSdp,
|
|
@@ -175493,12 +175713,12 @@ var WebRtcBridge = class {
|
|
|
175493
175713
|
const controllerAnswer = await controllerPeer.createAnswer();
|
|
175494
175714
|
await controllerPeer.setLocalDescription(controllerAnswer);
|
|
175495
175715
|
const answerSdp = this.localSdp(controllerPeer);
|
|
175496
|
-
|
|
175716
|
+
logger250.info(
|
|
175497
175717
|
`controller answer created for ${entityId} (${answerSdp.length} chars)`
|
|
175498
175718
|
);
|
|
175499
175719
|
return answerSdp;
|
|
175500
175720
|
} catch (err) {
|
|
175501
|
-
|
|
175721
|
+
logger250.info(
|
|
175502
175722
|
`acceptControllerOffer failed for ${entityId}: ${errText3(err)}`
|
|
175503
175723
|
);
|
|
175504
175724
|
await this.endSession(matterSessionId);
|
|
@@ -175509,14 +175729,14 @@ var WebRtcBridge = class {
|
|
|
175509
175729
|
async acceptControllerAnswer(matterSessionId, sdp) {
|
|
175510
175730
|
const session = this.sessions.get(matterSessionId);
|
|
175511
175731
|
if (!session) return;
|
|
175512
|
-
|
|
175732
|
+
logger250.debug(`controller answer applied for ${session.entityId}`);
|
|
175513
175733
|
await session.controllerPeer.setRemoteDescription({ type: "answer", sdp });
|
|
175514
175734
|
}
|
|
175515
175735
|
/** Add a remote ICE candidate from the Matter controller. */
|
|
175516
175736
|
async addControllerIceCandidate(matterSessionId, candidate, sdpMid, sdpMLineIndex) {
|
|
175517
175737
|
const session = this.sessions.get(matterSessionId);
|
|
175518
175738
|
if (!session) return;
|
|
175519
|
-
|
|
175739
|
+
logger250.debug(
|
|
175520
175740
|
`controller ICE candidate for ${session.entityId}: ${candidate}`
|
|
175521
175741
|
);
|
|
175522
175742
|
await session.controllerPeer.addIceCandidate({
|
|
@@ -175530,12 +175750,12 @@ var WebRtcBridge = class {
|
|
|
175530
175750
|
async closeExistingPeers(matterSessionId) {
|
|
175531
175751
|
const prior = this.sessions.get(matterSessionId);
|
|
175532
175752
|
if (!prior) return;
|
|
175533
|
-
|
|
175753
|
+
logger250.info(
|
|
175534
175754
|
`replacing session ${matterSessionId} (${prior.entityId}), closing prior peers`
|
|
175535
175755
|
);
|
|
175536
175756
|
if (prior.haUnsubscribe) {
|
|
175537
175757
|
await Promise.resolve(prior.haUnsubscribe()).catch(
|
|
175538
|
-
(err) =>
|
|
175758
|
+
(err) => logger250.debug(`HA unsubscribe failed: ${errText3(err)}`)
|
|
175539
175759
|
);
|
|
175540
175760
|
}
|
|
175541
175761
|
await prior.haPeer.close().catch(() => {
|
|
@@ -175548,11 +175768,11 @@ var WebRtcBridge = class {
|
|
|
175548
175768
|
async endSession(matterSessionId) {
|
|
175549
175769
|
const session = this.sessions.get(matterSessionId);
|
|
175550
175770
|
if (!session) return;
|
|
175551
|
-
|
|
175771
|
+
logger250.info(`ending session ${matterSessionId} (${session.entityId})`);
|
|
175552
175772
|
this.sessions.delete(matterSessionId);
|
|
175553
175773
|
if (session.haUnsubscribe) {
|
|
175554
175774
|
await Promise.resolve(session.haUnsubscribe()).catch(
|
|
175555
|
-
(err) =>
|
|
175775
|
+
(err) => logger250.debug(`HA unsubscribe failed: ${errText3(err)}`)
|
|
175556
175776
|
);
|
|
175557
175777
|
}
|
|
175558
175778
|
await session.haPeer.close().catch(() => {
|
|
@@ -175582,11 +175802,11 @@ var WebRtcBridge = class {
|
|
|
175582
175802
|
headers: { Authorization: `Bearer ${this.config.haToken}` }
|
|
175583
175803
|
});
|
|
175584
175804
|
} catch (err) {
|
|
175585
|
-
|
|
175805
|
+
logger250.info(`snapshot fetch failed for ${entityId}: ${errText3(err)}`);
|
|
175586
175806
|
throw err;
|
|
175587
175807
|
}
|
|
175588
175808
|
if (!res.ok) {
|
|
175589
|
-
|
|
175809
|
+
logger250.info(
|
|
175590
175810
|
`snapshot fetch failed for ${entityId}: camera_proxy ${res.status}`
|
|
175591
175811
|
);
|
|
175592
175812
|
throw new Error(`HA camera_proxy ${entityId}: ${res.status}`);
|
|
@@ -175603,10 +175823,10 @@ var WebRtcBridge = class {
|
|
|
175603
175823
|
// Forward every track HA sends into the matching pre-added controller sender.
|
|
175604
175824
|
forwardHaTracks(haPeer, senders, entityId) {
|
|
175605
175825
|
haPeer.onTrack.subscribe((track) => {
|
|
175606
|
-
|
|
175826
|
+
logger250.info(`onTrack ${track.kind} from HA (${entityId})`);
|
|
175607
175827
|
const transceiver = senders.get(track.kind);
|
|
175608
175828
|
if (!transceiver) {
|
|
175609
|
-
|
|
175829
|
+
logger250.info(
|
|
175610
175830
|
`no controller transceiver for ${track.kind} (${entityId})`
|
|
175611
175831
|
);
|
|
175612
175832
|
return;
|
|
@@ -175615,7 +175835,7 @@ var WebRtcBridge = class {
|
|
|
175615
175835
|
track.onReceiveRtp.subscribe((rtp) => {
|
|
175616
175836
|
if (!firstLogged) {
|
|
175617
175837
|
firstLogged = true;
|
|
175618
|
-
|
|
175838
|
+
logger250.info(`first RTP forwarded for ${track.kind} (${entityId})`);
|
|
175619
175839
|
}
|
|
175620
175840
|
transceiver.sender.sendRtp(rtp);
|
|
175621
175841
|
});
|
|
@@ -175624,10 +175844,10 @@ var WebRtcBridge = class {
|
|
|
175624
175844
|
// Log connection/ice state transitions (these events fire on change only).
|
|
175625
175845
|
wireStateLogging(peer, label, entityId) {
|
|
175626
175846
|
peer.connectionStateChange.subscribe(
|
|
175627
|
-
(s) =>
|
|
175847
|
+
(s) => logger250.info(`${label} connectionState=${s} (${entityId})`)
|
|
175628
175848
|
);
|
|
175629
175849
|
peer.iceConnectionStateChange.subscribe(
|
|
175630
|
-
(s) =>
|
|
175850
|
+
(s) => logger250.info(`${label} iceConnectionState=${s} (${entityId})`)
|
|
175631
175851
|
);
|
|
175632
175852
|
}
|
|
175633
175853
|
// Map the Matter ICE struct onto werift's config. Only the controller peer
|
|
@@ -175641,11 +175861,11 @@ var WebRtcBridge = class {
|
|
|
175641
175861
|
}))
|
|
175642
175862
|
);
|
|
175643
175863
|
if (iceServers.length === 0) {
|
|
175644
|
-
|
|
175864
|
+
logger250.info(`controller peer using default ICE servers (${entityId})`);
|
|
175645
175865
|
return void 0;
|
|
175646
175866
|
}
|
|
175647
175867
|
const policy = ice?.iceTransportPolicy === "relay" || ice?.iceTransportPolicy === "all" ? ice.iceTransportPolicy : void 0;
|
|
175648
|
-
|
|
175868
|
+
logger250.info(
|
|
175649
175869
|
`controller peer using ${iceServers.length} controller ICE server(s)${policy ? ` policy=${policy}` : ""} (${entityId})`
|
|
175650
175870
|
);
|
|
175651
175871
|
return policy ? { iceServers, iceTransportPolicy: policy } : { iceServers };
|
|
@@ -175659,13 +175879,13 @@ var WebRtcBridge = class {
|
|
|
175659
175879
|
feedHaCandidate(entityId, haPeer, candidate) {
|
|
175660
175880
|
const value = candidate?.candidate;
|
|
175661
175881
|
if (!value) return;
|
|
175662
|
-
|
|
175882
|
+
logger250.debug(`HA ICE candidate for ${entityId}: ${value}`);
|
|
175663
175883
|
void haPeer.addIceCandidate({
|
|
175664
175884
|
candidate: value,
|
|
175665
175885
|
sdpMid: candidate?.sdpMid ?? void 0,
|
|
175666
175886
|
sdpMLineIndex: candidate?.sdpMLineIndex ?? void 0
|
|
175667
175887
|
}).catch(
|
|
175668
|
-
(e) =>
|
|
175888
|
+
(e) => logger250.debug(
|
|
175669
175889
|
`HA addIceCandidate failed for ${entityId}: ${errText3(e)}`
|
|
175670
175890
|
)
|
|
175671
175891
|
);
|
|
@@ -175694,7 +175914,7 @@ var WebRtcBridge = class {
|
|
|
175694
175914
|
reject(err);
|
|
175695
175915
|
});
|
|
175696
175916
|
timer = setTimeout(() => {
|
|
175697
|
-
|
|
175917
|
+
logger250.info(
|
|
175698
175918
|
`HA WebRTC timed out after ${haWebRtcTimeoutMs}ms for ${entityId}`
|
|
175699
175919
|
);
|
|
175700
175920
|
fail(
|
|
@@ -175712,7 +175932,7 @@ var WebRtcBridge = class {
|
|
|
175712
175932
|
if (msg.session_id) sessionId = msg.session_id;
|
|
175713
175933
|
const ans = msg.answer;
|
|
175714
175934
|
settle(() => {
|
|
175715
|
-
|
|
175935
|
+
logger250.info(
|
|
175716
175936
|
`HA answer received for ${entityId} (${ans.length} chars)`
|
|
175717
175937
|
);
|
|
175718
175938
|
resolve11(ans);
|
|
@@ -175721,7 +175941,7 @@ var WebRtcBridge = class {
|
|
|
175721
175941
|
break;
|
|
175722
175942
|
case "error": {
|
|
175723
175943
|
const detail = msg.message ?? msg.code ?? "unknown error";
|
|
175724
|
-
|
|
175944
|
+
logger250.info(`HA WebRTC error for ${entityId}: ${detail}`);
|
|
175725
175945
|
fail(new Error(`HA WebRTC error: ${detail}`));
|
|
175726
175946
|
break;
|
|
175727
175947
|
}
|
|
@@ -175895,7 +176115,7 @@ var CameraPlugin = class {
|
|
|
175895
176115
|
// src/plugins/builtin/security/security-plugin.ts
|
|
175896
176116
|
init_esm();
|
|
175897
176117
|
import {
|
|
175898
|
-
callService
|
|
176118
|
+
callService,
|
|
175899
176119
|
createConnection as createConnection4,
|
|
175900
176120
|
createLongLivedTokenAuth as createLongLivedTokenAuth3
|
|
175901
176121
|
} from "home-assistant-js-websocket";
|
|
@@ -176747,7 +176967,7 @@ var SecurityPlugin = class {
|
|
|
176747
176967
|
let timer;
|
|
176748
176968
|
try {
|
|
176749
176969
|
await Promise.race([
|
|
176750
|
-
|
|
176970
|
+
callService(connection, domain, service, void 0, {
|
|
176751
176971
|
entity_id: entityId
|
|
176752
176972
|
}),
|
|
176753
176973
|
new Promise((_, reject) => {
|
|
@@ -176878,7 +177098,7 @@ import {
|
|
|
176878
177098
|
getCollection
|
|
176879
177099
|
} from "home-assistant-js-websocket";
|
|
176880
177100
|
import { atLeastHaVersion } from "home-assistant-js-websocket/dist/util.js";
|
|
176881
|
-
var
|
|
177101
|
+
var logger251 = Logger.get("SubscribeEntities");
|
|
176882
177102
|
function processEvent(store, updates) {
|
|
176883
177103
|
const state = { ...store.state };
|
|
176884
177104
|
if (updates.a) {
|
|
@@ -176904,7 +177124,7 @@ function processEvent(store, updates) {
|
|
|
176904
177124
|
for (const entityId in updates.c) {
|
|
176905
177125
|
let entityState = state[entityId];
|
|
176906
177126
|
if (!entityState) {
|
|
176907
|
-
|
|
177127
|
+
logger251.warn("Received state update for unknown entity", entityId);
|
|
176908
177128
|
continue;
|
|
176909
177129
|
}
|
|
176910
177130
|
entityState = { ...entityState };
|
|
@@ -176993,7 +177213,7 @@ var subscribeEntities = (conn, onChange, entityIds) => {
|
|
|
176993
177213
|
// src/services/bridges/entity-isolation-service.ts
|
|
176994
177214
|
init_esm();
|
|
176995
177215
|
init_diagnostic_event_bus();
|
|
176996
|
-
var
|
|
177216
|
+
var logger252 = Logger.get("EntityIsolation");
|
|
176997
177217
|
var EntityIsolationServiceImpl = class {
|
|
176998
177218
|
isolatedEntities = /* @__PURE__ */ new Map();
|
|
176999
177219
|
isolationCallbacks = /* @__PURE__ */ new Map();
|
|
@@ -177061,13 +177281,13 @@ var EntityIsolationServiceImpl = class {
|
|
|
177061
177281
|
}
|
|
177062
177282
|
const parsed = this.parseEndpointPath(msg);
|
|
177063
177283
|
if (!parsed) {
|
|
177064
|
-
|
|
177284
|
+
logger252.warn("Could not parse entity from error:", msg);
|
|
177065
177285
|
return false;
|
|
177066
177286
|
}
|
|
177067
177287
|
const { bridgeId, entityName } = parsed;
|
|
177068
177288
|
const callback = this.isolationCallbacks.get(bridgeId);
|
|
177069
177289
|
if (!callback) {
|
|
177070
|
-
|
|
177290
|
+
logger252.warn(
|
|
177071
177291
|
`No isolation callback registered for bridge ${bridgeId}, entity: ${entityName}`
|
|
177072
177292
|
);
|
|
177073
177293
|
return false;
|
|
@@ -177082,7 +177302,7 @@ var EntityIsolationServiceImpl = class {
|
|
|
177082
177302
|
reason,
|
|
177083
177303
|
failedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
177084
177304
|
});
|
|
177085
|
-
|
|
177305
|
+
logger252.warn(
|
|
177086
177306
|
`Isolating entity "${entityName}" from bridge ${bridgeId} due to: ${reason}`
|
|
177087
177307
|
);
|
|
177088
177308
|
diagnosticEventBus.emit("entity_error", `Entity isolated: ${entityName}`, {
|
|
@@ -177094,7 +177314,7 @@ var EntityIsolationServiceImpl = class {
|
|
|
177094
177314
|
await callback(entityName);
|
|
177095
177315
|
return true;
|
|
177096
177316
|
} catch (e) {
|
|
177097
|
-
|
|
177317
|
+
logger252.error(`Failed to isolate entity ${entityName}:`, e);
|
|
177098
177318
|
return false;
|
|
177099
177319
|
}
|
|
177100
177320
|
}
|
|
@@ -177125,7 +177345,7 @@ var EntityIsolationService = new EntityIsolationServiceImpl();
|
|
|
177125
177345
|
|
|
177126
177346
|
// src/services/bridges/bridge-endpoint-manager.ts
|
|
177127
177347
|
var MAX_ENTITY_ID_LENGTH = 150;
|
|
177128
|
-
var ENDPOINT_REMOVAL_GRACE_MS =
|
|
177348
|
+
var ENDPOINT_REMOVAL_GRACE_MS = 3e5;
|
|
177129
177349
|
function isEntityPart(p) {
|
|
177130
177350
|
return typeof p.updateStates === "function";
|
|
177131
177351
|
}
|
|
@@ -177169,11 +177389,15 @@ var BridgeEndpointManager = class extends Service {
|
|
|
177169
177389
|
root;
|
|
177170
177390
|
entityIds = [];
|
|
177171
177391
|
unsubscribe;
|
|
177392
|
+
observingRequested = false;
|
|
177172
177393
|
_failedEntities = [];
|
|
177173
177394
|
mappingFingerprints = /* @__PURE__ */ new Map();
|
|
177174
|
-
// entityId -> first
|
|
177395
|
+
// entityId -> first absence stamp (grace window)
|
|
177175
177396
|
pendingRemovals = /* @__PURE__ */ new Map();
|
|
177176
177397
|
removalRecheckTimer = null;
|
|
177398
|
+
// Bumped on every stop, so a refresh that was already running cannot arm a
|
|
177399
|
+
// timer on a bridge that has since stopped (#438).
|
|
177400
|
+
lifecycle = 0;
|
|
177177
177401
|
pluginEndpoints = /* @__PURE__ */ new Map();
|
|
177178
177402
|
pluginStateUpdating = /* @__PURE__ */ new Set();
|
|
177179
177403
|
pluginListeners = /* @__PURE__ */ new Map();
|
|
@@ -177379,9 +177603,9 @@ var BridgeEndpointManager = class extends Service {
|
|
|
177379
177603
|
await this.pluginManager.shutdownAll("Bridge stopping");
|
|
177380
177604
|
for (const [id, endpoint] of this.pluginEndpoints) {
|
|
177381
177605
|
try {
|
|
177382
|
-
await endpoint.
|
|
177606
|
+
await endpoint.close();
|
|
177383
177607
|
} catch (e) {
|
|
177384
|
-
this.log.warn(`Failed to
|
|
177608
|
+
this.log.warn(`Failed to close plugin endpoint ${id}:`, e);
|
|
177385
177609
|
}
|
|
177386
177610
|
}
|
|
177387
177611
|
this.pluginEndpoints.clear();
|
|
@@ -177430,9 +177654,9 @@ var BridgeEndpointManager = class extends Service {
|
|
|
177430
177654
|
`Isolating entity ${endpoint.entityId} due to runtime error`
|
|
177431
177655
|
);
|
|
177432
177656
|
try {
|
|
177433
|
-
await endpoint.
|
|
177657
|
+
await endpoint.close();
|
|
177434
177658
|
} catch (e) {
|
|
177435
|
-
this.log.error(`Failed to
|
|
177659
|
+
this.log.error(`Failed to close isolated endpoint:`, e);
|
|
177436
177660
|
}
|
|
177437
177661
|
this.pendingRemovals.delete(endpoint.entityId);
|
|
177438
177662
|
this.mappingFingerprints.delete(endpoint.entityId);
|
|
@@ -177441,7 +177665,7 @@ var BridgeEndpointManager = class extends Service {
|
|
|
177441
177665
|
if (!(sw instanceof VacuumAreaSwitchEndpoint)) continue;
|
|
177442
177666
|
if (sw.vacuumEndpointId !== endpoint.id) continue;
|
|
177443
177667
|
try {
|
|
177444
|
-
await sw.
|
|
177668
|
+
await sw.close();
|
|
177445
177669
|
} catch (e) {
|
|
177446
177670
|
this.log.warn(`Failed to remove area switch ${sw.id}:`, e);
|
|
177447
177671
|
}
|
|
@@ -177458,11 +177682,13 @@ var BridgeEndpointManager = class extends Service {
|
|
|
177458
177682
|
this.removalRecheckTimer = null;
|
|
177459
177683
|
}
|
|
177460
177684
|
if (this.pendingRemovals.size === 0) return;
|
|
177685
|
+
const lifecycle = this.lifecycle;
|
|
177461
177686
|
this.removalRecheckTimer = setTimeout(() => {
|
|
177462
177687
|
this.removalRecheckTimer = null;
|
|
177463
|
-
this.refreshDevices().catch(
|
|
177464
|
-
|
|
177465
|
-
|
|
177688
|
+
this.refreshDevices().catch((e) => {
|
|
177689
|
+
this.log.warn("Endpoint removal recheck failed:", e);
|
|
177690
|
+
if (lifecycle === this.lifecycle) this.scheduleRemovalRecheck();
|
|
177691
|
+
});
|
|
177466
177692
|
}, ENDPOINT_REMOVAL_GRACE_MS + 5e3);
|
|
177467
177693
|
}
|
|
177468
177694
|
getPluginDomainMappings() {
|
|
@@ -177501,7 +177727,8 @@ var BridgeEndpointManager = class extends Service {
|
|
|
177501
177727
|
}
|
|
177502
177728
|
}
|
|
177503
177729
|
async startObserving() {
|
|
177504
|
-
this.
|
|
177730
|
+
this.clearSubscription();
|
|
177731
|
+
this.observingRequested = true;
|
|
177505
177732
|
if (!this.entityIds.length) {
|
|
177506
177733
|
return;
|
|
177507
177734
|
}
|
|
@@ -177525,14 +177752,32 @@ var BridgeEndpointManager = class extends Service {
|
|
|
177525
177752
|
}
|
|
177526
177753
|
return [...ids];
|
|
177527
177754
|
}
|
|
177528
|
-
|
|
177755
|
+
clearSubscription() {
|
|
177529
177756
|
this.unsubscribe?.();
|
|
177530
177757
|
this.unsubscribe = void 0;
|
|
177531
177758
|
}
|
|
177759
|
+
stopObserving() {
|
|
177760
|
+
this.observingRequested = false;
|
|
177761
|
+
this.lifecycle++;
|
|
177762
|
+
this.clearSubscription();
|
|
177763
|
+
if (this.removalRecheckTimer) {
|
|
177764
|
+
clearTimeout(this.removalRecheckTimer);
|
|
177765
|
+
this.removalRecheckTimer = null;
|
|
177766
|
+
}
|
|
177767
|
+
}
|
|
177532
177768
|
async refreshDevices() {
|
|
177533
177769
|
this.registry.refresh();
|
|
177534
|
-
|
|
177770
|
+
const lifecycle = this.lifecycle;
|
|
177535
177771
|
const endpoints = [...this.root.parts].filter(hasEntityIdentity).filter((p) => !(p instanceof VacuumAreaSwitchEndpoint));
|
|
177772
|
+
const fullEntities = this.registry.fullEntities;
|
|
177773
|
+
if (!this.client.haRunning || Object.keys(fullEntities).length === 0) {
|
|
177774
|
+
this.pendingRemovals.clear();
|
|
177775
|
+
this.log.warn(
|
|
177776
|
+
`HA not running or registry empty, deferring reconcile of ${endpoints.length} endpoints`
|
|
177777
|
+
);
|
|
177778
|
+
return;
|
|
177779
|
+
}
|
|
177780
|
+
this._failedEntities = [];
|
|
177536
177781
|
this.entityIds = this.registry.entityIds;
|
|
177537
177782
|
if (this.registry.isAutoComposedDevicesEnabled()) {
|
|
177538
177783
|
for (const eid of this.entityIds) {
|
|
@@ -177584,7 +177829,6 @@ var BridgeEndpointManager = class extends Service {
|
|
|
177584
177829
|
this.mappingFingerprints.set(entityId, fp);
|
|
177585
177830
|
}
|
|
177586
177831
|
}
|
|
177587
|
-
const fullEntities = this.registry.fullEntities;
|
|
177588
177832
|
stampIdentityPresence(
|
|
177589
177833
|
this.identityStorage,
|
|
177590
177834
|
this.bridgeId,
|
|
@@ -177608,13 +177852,6 @@ var BridgeEndpointManager = class extends Service {
|
|
|
177608
177852
|
this.log.warn(`Failed to remove colliding area switch ${part.id}:`, e);
|
|
177609
177853
|
}
|
|
177610
177854
|
}
|
|
177611
|
-
if (Object.keys(this.registry.fullEntities).length === 0 && endpoints.length > 0) {
|
|
177612
|
-
this.pendingRemovals.clear();
|
|
177613
|
-
this.log.warn(
|
|
177614
|
-
`HA registry has no entities, skipping removal of ${endpoints.length} endpoints (HA down?)`
|
|
177615
|
-
);
|
|
177616
|
-
return;
|
|
177617
|
-
}
|
|
177618
177855
|
const existingEndpoints = [];
|
|
177619
177856
|
const now = Date.now();
|
|
177620
177857
|
for (const endpoint of endpoints) {
|
|
@@ -177640,13 +177877,16 @@ var BridgeEndpointManager = class extends Service {
|
|
|
177640
177877
|
this.pendingRemovals.delete(endpoint.entityId);
|
|
177641
177878
|
}
|
|
177642
177879
|
if (!present) {
|
|
177643
|
-
const
|
|
177644
|
-
if (
|
|
177645
|
-
this.pendingRemovals.set(endpoint.entityId,
|
|
177880
|
+
const entry = this.pendingRemovals.get(endpoint.entityId);
|
|
177881
|
+
if (entry == null) {
|
|
177882
|
+
this.pendingRemovals.set(endpoint.entityId, {
|
|
177883
|
+
since: now,
|
|
177884
|
+
generation: this.registry.snapshotGeneration
|
|
177885
|
+
});
|
|
177646
177886
|
existingEndpoints.push(endpoint);
|
|
177647
177887
|
continue;
|
|
177648
177888
|
}
|
|
177649
|
-
if (now - since < ENDPOINT_REMOVAL_GRACE_MS) {
|
|
177889
|
+
if (now - entry.since < ENDPOINT_REMOVAL_GRACE_MS || now - this.client.runningSince < ENDPOINT_REMOVAL_GRACE_MS || this.registry.snapshotGeneration <= entry.generation) {
|
|
177650
177890
|
existingEndpoints.push(endpoint);
|
|
177651
177891
|
continue;
|
|
177652
177892
|
}
|
|
@@ -177662,13 +177902,13 @@ var BridgeEndpointManager = class extends Service {
|
|
|
177662
177902
|
this.pendingRemovals.delete(endpoint.entityId);
|
|
177663
177903
|
} else if (this.registry.isAutoComposedDevicesEnabled() && this.registry.isComposedSubEntityUsed(endpoint.entityId)) {
|
|
177664
177904
|
this.log.info(
|
|
177665
|
-
`
|
|
177905
|
+
`Removing standalone endpoint ${endpoint.entityId}, consumed by composed device`
|
|
177666
177906
|
);
|
|
177667
177907
|
try {
|
|
177668
|
-
await endpoint.
|
|
177908
|
+
await endpoint.close();
|
|
177669
177909
|
} catch (e) {
|
|
177670
177910
|
this.log.warn(
|
|
177671
|
-
`Failed to
|
|
177911
|
+
`Failed to remove composed sub-entity endpoint ${endpoint.entityId}:`,
|
|
177672
177912
|
e
|
|
177673
177913
|
);
|
|
177674
177914
|
}
|
|
@@ -177701,7 +177941,9 @@ var BridgeEndpointManager = class extends Service {
|
|
|
177701
177941
|
}
|
|
177702
177942
|
}
|
|
177703
177943
|
}
|
|
177704
|
-
this.
|
|
177944
|
+
if (lifecycle === this.lifecycle) {
|
|
177945
|
+
this.scheduleRemovalRecheck();
|
|
177946
|
+
}
|
|
177705
177947
|
let memoryLimitReached = false;
|
|
177706
177948
|
for (const entityId of this.entityIds) {
|
|
177707
177949
|
if (!memoryLimitReached && isHeapUnderPressure()) {
|
|
@@ -177775,7 +178017,7 @@ var BridgeEndpointManager = class extends Service {
|
|
|
177775
178017
|
}
|
|
177776
178018
|
}
|
|
177777
178019
|
await this.reconcileAreaSwitches();
|
|
177778
|
-
if (this.
|
|
178020
|
+
if (this.observingRequested) {
|
|
177779
178021
|
this.startObserving();
|
|
177780
178022
|
}
|
|
177781
178023
|
}
|
|
@@ -178000,7 +178242,7 @@ var BridgeEndpointManager = class extends Service {
|
|
|
178000
178242
|
init_dist();
|
|
178001
178243
|
init_esm();
|
|
178002
178244
|
init_send_ha_message();
|
|
178003
|
-
import { callService as
|
|
178245
|
+
import { callService as callService2 } from "home-assistant-js-websocket";
|
|
178004
178246
|
import { keys as keys2, pickBy, values as values3 } from "lodash-es";
|
|
178005
178247
|
var BridgeRegistry = class _BridgeRegistry {
|
|
178006
178248
|
constructor(registry3, dataProvider, client) {
|
|
@@ -178049,6 +178291,10 @@ var BridgeRegistry = class _BridgeRegistry {
|
|
|
178049
178291
|
get fullEntities() {
|
|
178050
178292
|
return this.registry.entities;
|
|
178051
178293
|
}
|
|
178294
|
+
// Successful-reload counter, see HomeAssistantRegistry (#438).
|
|
178295
|
+
get snapshotGeneration() {
|
|
178296
|
+
return this.registry.snapshotGeneration;
|
|
178297
|
+
}
|
|
178052
178298
|
// composed sub-entities may sit outside the bridge filter (#408), so these
|
|
178053
178299
|
// fall back to the full HA registry. keep them separate from the strict
|
|
178054
178300
|
// accessors above, every other caller must stay filtered.
|
|
@@ -178386,7 +178632,7 @@ var BridgeRegistry = class _BridgeRegistry {
|
|
|
178386
178632
|
async resolveRoborockRooms(entityId) {
|
|
178387
178633
|
if (!this.client) return [];
|
|
178388
178634
|
try {
|
|
178389
|
-
const raw = await
|
|
178635
|
+
const raw = await callService2(
|
|
178390
178636
|
this.client.connection,
|
|
178391
178637
|
"roborock",
|
|
178392
178638
|
"get_maps",
|
|
@@ -178765,6 +179011,7 @@ function hashAreaId(areaId) {
|
|
|
178765
179011
|
init_dist();
|
|
178766
179012
|
init_esm7();
|
|
178767
179013
|
import * as os10 from "node:os";
|
|
179014
|
+
init_protocol3();
|
|
178768
179015
|
init_diagnostic_event_bus();
|
|
178769
179016
|
var imWrapMarker2 = /* @__PURE__ */ Symbol("hamh.wedgeImWrap");
|
|
178770
179017
|
var commandMessageTypes2 = [
|
|
@@ -178780,11 +179027,11 @@ function makeWarmStartState(state, now = (/* @__PURE__ */ new Date()).toISOStrin
|
|
|
178780
179027
|
return { ...state, last_updated: now };
|
|
178781
179028
|
}
|
|
178782
179029
|
var ServerModeBridge = class {
|
|
178783
|
-
constructor(
|
|
179030
|
+
constructor(logger255, dataProvider, endpointManager, server) {
|
|
178784
179031
|
this.dataProvider = dataProvider;
|
|
178785
179032
|
this.endpointManager = endpointManager;
|
|
178786
179033
|
this.server = server;
|
|
178787
|
-
this.log =
|
|
179034
|
+
this.log = logger255.get(`ServerModeBridge / ${dataProvider.id}`);
|
|
178788
179035
|
}
|
|
178789
179036
|
dataProvider;
|
|
178790
179037
|
endpointManager;
|
|
@@ -179926,7 +180173,7 @@ function ServerModeVacuumDevice(homeAssistantEntity, includeOnOff = false, clean
|
|
|
179926
180173
|
}
|
|
179927
180174
|
|
|
179928
180175
|
// src/matter/endpoints/server-mode-vacuum-endpoint.ts
|
|
179929
|
-
var
|
|
180176
|
+
var logger253 = Logger.get("ServerModeVacuumEndpoint");
|
|
179930
180177
|
var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEndpoint {
|
|
179931
180178
|
static async create(registry3, entityId, mapping, endpointId) {
|
|
179932
180179
|
const deviceRegistry = registry3.deviceOf(entityId);
|
|
@@ -179939,7 +180186,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
179939
180186
|
if (mapping?.disableBatteryMapping && mapping.batteryEntity) {
|
|
179940
180187
|
effectiveMapping = { ...mapping, batteryEntity: void 0 };
|
|
179941
180188
|
}
|
|
179942
|
-
|
|
180189
|
+
logger253.info(
|
|
179943
180190
|
`${entityId}: device_id=${entity.device_id}, manualBattery=${mapping?.batteryEntity ?? "none"}`
|
|
179944
180191
|
);
|
|
179945
180192
|
if (entity.device_id) {
|
|
@@ -179954,15 +180201,15 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
179954
180201
|
batteryEntity: batteryEntityId
|
|
179955
180202
|
};
|
|
179956
180203
|
registry3.markBatteryEntityUsed(batteryEntityId);
|
|
179957
|
-
|
|
180204
|
+
logger253.info(`${entityId}: Auto-assigned battery ${batteryEntityId}`);
|
|
179958
180205
|
} else {
|
|
179959
180206
|
const attrs = state.attributes;
|
|
179960
180207
|
if (attrs.battery_level != null || attrs.battery != null) {
|
|
179961
|
-
|
|
180208
|
+
logger253.info(
|
|
179962
180209
|
`${entityId}: No battery entity found, using battery attribute from vacuum state`
|
|
179963
180210
|
);
|
|
179964
180211
|
} else {
|
|
179965
|
-
|
|
180212
|
+
logger253.warn(
|
|
179966
180213
|
`${entityId}: No battery entity found for device ${entity.device_id}`
|
|
179967
180214
|
);
|
|
179968
180215
|
}
|
|
@@ -179977,7 +180224,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
179977
180224
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
179978
180225
|
cleaningModeEntity: vacuumEntities.cleaningModeEntity
|
|
179979
180226
|
};
|
|
179980
|
-
|
|
180227
|
+
logger253.info(
|
|
179981
180228
|
`${entityId}: Auto-assigned cleaningMode ${vacuumEntities.cleaningModeEntity}`
|
|
179982
180229
|
);
|
|
179983
180230
|
}
|
|
@@ -179987,7 +180234,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
179987
180234
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
179988
180235
|
suctionLevelEntity: vacuumEntities.suctionLevelEntity
|
|
179989
180236
|
};
|
|
179990
|
-
|
|
180237
|
+
logger253.info(
|
|
179991
180238
|
`${entityId}: Auto-assigned suctionLevel ${vacuumEntities.suctionLevelEntity}`
|
|
179992
180239
|
);
|
|
179993
180240
|
}
|
|
@@ -179997,7 +180244,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
179997
180244
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
179998
180245
|
mopIntensityEntity: vacuumEntities.mopIntensityEntity
|
|
179999
180246
|
};
|
|
180000
|
-
|
|
180247
|
+
logger253.info(
|
|
180001
180248
|
`${entityId}: Auto-assigned mopIntensity ${vacuumEntities.mopIntensityEntity}`
|
|
180002
180249
|
);
|
|
180003
180250
|
}
|
|
@@ -180007,7 +180254,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
180007
180254
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
180008
180255
|
currentRoomEntity: vacuumEntities.currentRoomEntity
|
|
180009
180256
|
};
|
|
180010
|
-
|
|
180257
|
+
logger253.info(
|
|
180011
180258
|
`${entityId}: Auto-assigned currentRoom ${vacuumEntities.currentRoomEntity}`
|
|
180012
180259
|
);
|
|
180013
180260
|
}
|
|
@@ -180022,7 +180269,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
180022
180269
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
180023
180270
|
cleanAreaRooms
|
|
180024
180271
|
};
|
|
180025
|
-
|
|
180272
|
+
logger253.info(
|
|
180026
180273
|
`${entityId}: Using ${cleanAreaRooms.length} HA areas via CLEAN_AREA`
|
|
180027
180274
|
);
|
|
180028
180275
|
}
|
|
@@ -180043,7 +180290,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
180043
180290
|
rooms: roomsObj
|
|
180044
180291
|
}
|
|
180045
180292
|
};
|
|
180046
|
-
|
|
180293
|
+
logger253.info(
|
|
180047
180294
|
`${entityId}: Auto-detected ${valetudoRooms.length} Valetudo segments`
|
|
180048
180295
|
);
|
|
180049
180296
|
} else {
|
|
@@ -180060,14 +180307,14 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
180060
180307
|
rooms: roomsObj
|
|
180061
180308
|
}
|
|
180062
180309
|
};
|
|
180063
|
-
|
|
180310
|
+
logger253.info(
|
|
180064
180311
|
`${entityId}: Auto-detected ${roborockRooms.length} Roborock rooms`
|
|
180065
180312
|
);
|
|
180066
180313
|
}
|
|
180067
180314
|
}
|
|
180068
180315
|
}
|
|
180069
180316
|
} else {
|
|
180070
|
-
|
|
180317
|
+
logger253.warn(`${entityId}: No device_id, cannot auto-assign battery`);
|
|
180071
180318
|
}
|
|
180072
180319
|
const payload = {
|
|
180073
180320
|
entity_id: entityId,
|
|
@@ -180140,11 +180387,11 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
180140
180387
|
}
|
|
180141
180388
|
if (mappedChanged) {
|
|
180142
180389
|
this.pendingMappedChange = true;
|
|
180143
|
-
|
|
180390
|
+
logger253.debug(
|
|
180144
180391
|
`Mapped entity change detected for ${this.entityId}, forcing update`
|
|
180145
180392
|
);
|
|
180146
180393
|
}
|
|
180147
|
-
|
|
180394
|
+
logger253.debug(
|
|
180148
180395
|
`State update received for ${this.entityId}: state=${state.state}`
|
|
180149
180396
|
);
|
|
180150
180397
|
this.lastState = state;
|
|
@@ -180207,8 +180454,20 @@ var ServerModeEndpointManager = class extends Service {
|
|
|
180207
180454
|
log;
|
|
180208
180455
|
entityIds = [];
|
|
180209
180456
|
unsubscribe;
|
|
180457
|
+
observingRequested = false;
|
|
180210
180458
|
_failedEntities = [];
|
|
180211
180459
|
endpoints = /* @__PURE__ */ new Map();
|
|
180460
|
+
// Same grace as the aggregator manager: server mode deleted on the FIRST
|
|
180461
|
+
// refresh an entity was absent, so one partial HA snapshot re-minted the
|
|
180462
|
+
// device (#438).
|
|
180463
|
+
pendingRemovals = /* @__PURE__ */ new Map();
|
|
180464
|
+
removalRecheckTimer = null;
|
|
180465
|
+
// endpoint id -> entity that closed but may come back (disable). Its number
|
|
180466
|
+
// is still parked, so nobody else may mount on that id (#438).
|
|
180467
|
+
parkedEndpointIds = /* @__PURE__ */ new Map();
|
|
180468
|
+
// Bumped on every stop, so a refresh that was already running cannot arm a
|
|
180469
|
+
// timer on a bridge that has since stopped.
|
|
180470
|
+
lifecycle = 0;
|
|
180212
180471
|
get failedEntities() {
|
|
180213
180472
|
return this._failedEntities;
|
|
180214
180473
|
}
|
|
@@ -180226,6 +180485,11 @@ var ServerModeEndpointManager = class extends Service {
|
|
|
180226
180485
|
}
|
|
180227
180486
|
async dispose() {
|
|
180228
180487
|
this.stopObserving();
|
|
180488
|
+
if (this.removalRecheckTimer) {
|
|
180489
|
+
clearTimeout(this.removalRecheckTimer);
|
|
180490
|
+
this.removalRecheckTimer = null;
|
|
180491
|
+
}
|
|
180492
|
+
this.pendingRemovals.clear();
|
|
180229
180493
|
for (const [entityId, entry] of this.endpoints) {
|
|
180230
180494
|
try {
|
|
180231
180495
|
await entry.endpoint.close();
|
|
@@ -180239,7 +180503,8 @@ var ServerModeEndpointManager = class extends Service {
|
|
|
180239
180503
|
this.endpoints.clear();
|
|
180240
180504
|
}
|
|
180241
180505
|
async startObserving() {
|
|
180242
|
-
this.
|
|
180506
|
+
this.clearSubscription();
|
|
180507
|
+
this.observingRequested = true;
|
|
180243
180508
|
if (!this.entityIds.length) {
|
|
180244
180509
|
return;
|
|
180245
180510
|
}
|
|
@@ -180259,10 +180524,19 @@ var ServerModeEndpointManager = class extends Service {
|
|
|
180259
180524
|
}
|
|
180260
180525
|
return [...ids];
|
|
180261
180526
|
}
|
|
180262
|
-
|
|
180527
|
+
clearSubscription() {
|
|
180263
180528
|
this.unsubscribe?.();
|
|
180264
180529
|
this.unsubscribe = void 0;
|
|
180265
180530
|
}
|
|
180531
|
+
stopObserving() {
|
|
180532
|
+
this.observingRequested = false;
|
|
180533
|
+
this.lifecycle++;
|
|
180534
|
+
this.clearSubscription();
|
|
180535
|
+
if (this.removalRecheckTimer) {
|
|
180536
|
+
clearTimeout(this.removalRecheckTimer);
|
|
180537
|
+
this.removalRecheckTimer = null;
|
|
180538
|
+
}
|
|
180539
|
+
}
|
|
180266
180540
|
/** Primary first (the entity the first include matcher tests true for). */
|
|
180267
180541
|
orderEntityIds(ids) {
|
|
180268
180542
|
const firstMatcher = this.dataProvider.filter?.include?.[0];
|
|
@@ -180285,6 +180559,44 @@ var ServerModeEndpointManager = class extends Service {
|
|
|
180285
180559
|
this.endpoints.delete(entityId);
|
|
180286
180560
|
}
|
|
180287
180561
|
}
|
|
180562
|
+
// Absence-driven removals wait out the grace window AND a fresh successful
|
|
180563
|
+
// HA reload, so restarts and stale snapshots never erase numbers (#438).
|
|
180564
|
+
// Returns the ids whose absence is confirmed, ready for removeEndpoints.
|
|
180565
|
+
removableAfterGrace(entityIds) {
|
|
180566
|
+
const now = Date.now();
|
|
180567
|
+
const generation = this.registry.snapshotGeneration;
|
|
180568
|
+
const ready = [];
|
|
180569
|
+
for (const entityId of entityIds) {
|
|
180570
|
+
const entry = this.pendingRemovals.get(entityId);
|
|
180571
|
+
if (entry == null) {
|
|
180572
|
+
this.pendingRemovals.set(entityId, { since: now, generation });
|
|
180573
|
+
continue;
|
|
180574
|
+
}
|
|
180575
|
+
if (now - entry.since < ENDPOINT_REMOVAL_GRACE_MS || now - this.client.runningSince < ENDPOINT_REMOVAL_GRACE_MS || generation <= entry.generation) {
|
|
180576
|
+
continue;
|
|
180577
|
+
}
|
|
180578
|
+
ready.push(entityId);
|
|
180579
|
+
this.pendingRemovals.delete(entityId);
|
|
180580
|
+
}
|
|
180581
|
+
return ready;
|
|
180582
|
+
}
|
|
180583
|
+
// refreshDevices only runs on registry-fingerprint changes, which may not
|
|
180584
|
+
// recur, so drive held removals to completion ourselves after the grace.
|
|
180585
|
+
scheduleRemovalRecheck() {
|
|
180586
|
+
if (this.removalRecheckTimer) {
|
|
180587
|
+
clearTimeout(this.removalRecheckTimer);
|
|
180588
|
+
this.removalRecheckTimer = null;
|
|
180589
|
+
}
|
|
180590
|
+
if (this.pendingRemovals.size === 0) return;
|
|
180591
|
+
const lifecycle = this.lifecycle;
|
|
180592
|
+
this.removalRecheckTimer = setTimeout(() => {
|
|
180593
|
+
this.removalRecheckTimer = null;
|
|
180594
|
+
this.refreshDevices().catch((e) => {
|
|
180595
|
+
this.log.warn("Endpoint removal recheck failed:", e);
|
|
180596
|
+
if (lifecycle === this.lifecycle) this.scheduleRemovalRecheck();
|
|
180597
|
+
});
|
|
180598
|
+
}, ENDPOINT_REMOVAL_GRACE_MS + 5e3);
|
|
180599
|
+
}
|
|
180288
180600
|
// Like removeEndpoints but close() keeps the persisted number pre-allocated,
|
|
180289
180601
|
// so a same-id recreate reuses it. Used on rename and same-id recreates (#404).
|
|
180290
180602
|
async closeEndpoint(entityId) {
|
|
@@ -180294,35 +180606,40 @@ var ServerModeEndpointManager = class extends Service {
|
|
|
180294
180606
|
await entry.endpoint.close();
|
|
180295
180607
|
} catch (e) {
|
|
180296
180608
|
this.log.warn(`Failed to close endpoint ${entityId}:`, e);
|
|
180609
|
+
return;
|
|
180297
180610
|
}
|
|
180298
180611
|
this.serverNode.forgetDevice(entry.endpoint);
|
|
180299
180612
|
this.endpoints.delete(entityId);
|
|
180300
180613
|
}
|
|
180301
180614
|
async refreshDevices() {
|
|
180302
180615
|
this.registry.refresh();
|
|
180303
|
-
|
|
180304
|
-
this.entityIds = this.registry.entityIds;
|
|
180616
|
+
const lifecycle = this.lifecycle;
|
|
180305
180617
|
const fullEntities = this.registry.fullEntities;
|
|
180306
|
-
stampIdentityPresence(
|
|
180307
|
-
this.identityStorage,
|
|
180308
|
-
this.dataProvider.id,
|
|
180309
|
-
buildPresentIdentityKeys(fullEntities)
|
|
180310
|
-
);
|
|
180311
|
-
stampMappingPresence(
|
|
180312
|
-
this.mappingStorage,
|
|
180313
|
-
this.dataProvider.id,
|
|
180314
|
-
buildPresentEntityIds(fullEntities)
|
|
180315
|
-
);
|
|
180316
180618
|
try {
|
|
180317
|
-
if (Object.keys(fullEntities).length === 0
|
|
180619
|
+
if (!this.client.haRunning || Object.keys(fullEntities).length === 0) {
|
|
180620
|
+
this.pendingRemovals.clear();
|
|
180318
180621
|
this.log.warn(
|
|
180319
|
-
"HA
|
|
180622
|
+
"HA not running or registry empty, deferring server mode reconcile"
|
|
180320
180623
|
);
|
|
180321
180624
|
return;
|
|
180322
180625
|
}
|
|
180626
|
+
this._failedEntities = [];
|
|
180627
|
+
this.entityIds = this.registry.entityIds;
|
|
180628
|
+
stampIdentityPresence(
|
|
180629
|
+
this.identityStorage,
|
|
180630
|
+
this.dataProvider.id,
|
|
180631
|
+
buildPresentIdentityKeys(fullEntities)
|
|
180632
|
+
);
|
|
180633
|
+
stampMappingPresence(
|
|
180634
|
+
this.mappingStorage,
|
|
180635
|
+
this.dataProvider.id,
|
|
180636
|
+
buildPresentEntityIds(fullEntities)
|
|
180637
|
+
);
|
|
180323
180638
|
if (this.entityIds.length === 0) {
|
|
180324
180639
|
this.log.warn("Server mode bridge has no entities configured");
|
|
180325
|
-
await this.removeEndpoints(
|
|
180640
|
+
await this.removeEndpoints(
|
|
180641
|
+
this.removableAfterGrace([...this.endpoints.keys()])
|
|
180642
|
+
);
|
|
180326
180643
|
this._failedEntities.push({
|
|
180327
180644
|
entityId: this.dataProvider.filter?.include?.[0]?.value ?? "(no entity configured)",
|
|
180328
180645
|
reason: "No Home Assistant entity matched this bridge's filter. Check for typos or renamed/removed entities."
|
|
@@ -180368,19 +180685,35 @@ var ServerModeEndpointManager = class extends Service {
|
|
|
180368
180685
|
endpointIdToEntity.set(resolved.endpointId, entityId);
|
|
180369
180686
|
}
|
|
180370
180687
|
const keep = new Set(orderedIds);
|
|
180688
|
+
for (const id of keep) {
|
|
180689
|
+
this.pendingRemovals.delete(id);
|
|
180690
|
+
}
|
|
180371
180691
|
const removed = [...this.endpoints.keys()].filter((id) => !keep.has(id));
|
|
180372
|
-
let structureChanged = removed.length > 0;
|
|
180373
180692
|
const genuinelyRemoved = [];
|
|
180374
180693
|
for (const oldId of removed) {
|
|
180375
180694
|
const entry = this.endpoints.get(oldId);
|
|
180376
180695
|
const claimant = entry ? endpointIdToEntity.get(entry.endpoint.id) : void 0;
|
|
180377
180696
|
if (entry && claimant != null && claimant !== oldId) {
|
|
180378
180697
|
await this.closeEndpoint(oldId);
|
|
180698
|
+
this.pendingRemovals.delete(oldId);
|
|
180379
180699
|
} else {
|
|
180380
180700
|
genuinelyRemoved.push(oldId);
|
|
180381
180701
|
}
|
|
180382
180702
|
}
|
|
180383
|
-
|
|
180703
|
+
const confirmedRemoved = this.removableAfterGrace(genuinelyRemoved);
|
|
180704
|
+
let structureChanged = removed.length > genuinelyRemoved.length || confirmedRemoved.length > 0;
|
|
180705
|
+
await this.removeEndpoints(confirmedRemoved);
|
|
180706
|
+
for (const entityId of orderedIds) {
|
|
180707
|
+
const mapping = this.getEntityMapping(entityId);
|
|
180708
|
+
if (!mapping?.disabled) continue;
|
|
180709
|
+
for (const [id, owner] of this.parkedEndpointIds) {
|
|
180710
|
+
if (owner === entityId) this.parkedEndpointIds.delete(id);
|
|
180711
|
+
}
|
|
180712
|
+
this.parkedEndpointIds.set(
|
|
180713
|
+
this.endpoints.get(entityId)?.endpoint.id ?? resolvedByEntity.get(entityId)?.endpointId ?? createEndpointId(entityId, mapping.customName),
|
|
180714
|
+
entityId
|
|
180715
|
+
);
|
|
180716
|
+
}
|
|
180384
180717
|
for (const entityId of orderedIds) {
|
|
180385
180718
|
const mapping = this.getEntityMapping(entityId);
|
|
180386
180719
|
if (mapping?.disabled) {
|
|
@@ -180388,7 +180721,7 @@ var ServerModeEndpointManager = class extends Service {
|
|
|
180388
180721
|
`Entity in server mode bridge is disabled: ${entityId}`
|
|
180389
180722
|
);
|
|
180390
180723
|
if (this.endpoints.has(entityId)) {
|
|
180391
|
-
await this.
|
|
180724
|
+
await this.closeEndpoint(entityId);
|
|
180392
180725
|
structureChanged = true;
|
|
180393
180726
|
}
|
|
180394
180727
|
this._failedEntities.push({
|
|
@@ -180427,10 +180760,11 @@ var ServerModeEndpointManager = class extends Service {
|
|
|
180427
180760
|
const collision = [...this.endpoints.entries()].find(
|
|
180428
180761
|
([, entry]) => entry.endpoint.id === endpointId
|
|
180429
180762
|
);
|
|
180430
|
-
|
|
180763
|
+
const parkedBy = this.parkedEndpointIds.get(endpointId);
|
|
180764
|
+
if (collision || parkedBy != null && parkedBy !== entityId) {
|
|
180431
180765
|
this._failedEntities.push({
|
|
180432
180766
|
entityId,
|
|
180433
|
-
reason: `Endpoint id collides with ${collision[0]}. Set distinct custom names.`
|
|
180767
|
+
reason: `Endpoint id collides with ${collision?.[0] ?? parkedBy}. Set distinct custom names.`
|
|
180434
180768
|
});
|
|
180435
180769
|
continue;
|
|
180436
180770
|
}
|
|
@@ -180468,6 +180802,11 @@ var ServerModeEndpointManager = class extends Service {
|
|
|
180468
180802
|
}
|
|
180469
180803
|
await this.serverNode.addDevice(endpoint);
|
|
180470
180804
|
this.endpoints.set(entityId, { endpoint, fingerprint });
|
|
180805
|
+
for (const [id, owner] of this.parkedEndpointIds) {
|
|
180806
|
+
if (id === endpointId || owner === entityId) {
|
|
180807
|
+
this.parkedEndpointIds.delete(id);
|
|
180808
|
+
}
|
|
180809
|
+
}
|
|
180471
180810
|
structureChanged = true;
|
|
180472
180811
|
this.log.info(`Server mode: Added device ${entityId}`);
|
|
180473
180812
|
} catch (e) {
|
|
@@ -180487,7 +180826,10 @@ var ServerModeEndpointManager = class extends Service {
|
|
|
180487
180826
|
}
|
|
180488
180827
|
}
|
|
180489
180828
|
} finally {
|
|
180490
|
-
if (this.
|
|
180829
|
+
if (lifecycle === this.lifecycle) {
|
|
180830
|
+
this.scheduleRemovalRecheck();
|
|
180831
|
+
}
|
|
180832
|
+
if (this.observingRequested) {
|
|
180491
180833
|
this.startObserving();
|
|
180492
180834
|
}
|
|
180493
180835
|
}
|
|
@@ -180728,10 +181070,10 @@ var BridgeEnvironmentFactory = class extends BridgeFactory {
|
|
|
180728
181070
|
// src/core/ioc/app-environment.ts
|
|
180729
181071
|
var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
|
|
180730
181072
|
constructor(rootEnv, options) {
|
|
180731
|
-
const
|
|
181073
|
+
const logger255 = rootEnv.get(LoggerService);
|
|
180732
181074
|
super({
|
|
180733
181075
|
id: "App",
|
|
180734
|
-
log:
|
|
181076
|
+
log: logger255.get("AppContainer"),
|
|
180735
181077
|
parent: rootEnv
|
|
180736
181078
|
});
|
|
180737
181079
|
this.options = options;
|
|
@@ -180745,8 +181087,8 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
|
|
|
180745
181087
|
}
|
|
180746
181088
|
construction;
|
|
180747
181089
|
async init() {
|
|
180748
|
-
const
|
|
180749
|
-
this.set(LoggerService,
|
|
181090
|
+
const logger255 = this.get(LoggerService);
|
|
181091
|
+
this.set(LoggerService, logger255);
|
|
180750
181092
|
this.set(AppStorage, new AppStorage(await this.load(StorageService)));
|
|
180751
181093
|
this.set(BridgeStorage, new BridgeStorage(await this.load(AppStorage)));
|
|
180752
181094
|
this.set(
|
|
@@ -180767,7 +181109,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
|
|
|
180767
181109
|
);
|
|
180768
181110
|
this.set(
|
|
180769
181111
|
HomeAssistantClient,
|
|
180770
|
-
new HomeAssistantClient(
|
|
181112
|
+
new HomeAssistantClient(logger255, this.options.homeAssistant)
|
|
180771
181113
|
);
|
|
180772
181114
|
this.set(
|
|
180773
181115
|
HomeAssistantConfig,
|
|
@@ -180775,7 +181117,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
|
|
|
180775
181117
|
);
|
|
180776
181118
|
this.set(
|
|
180777
181119
|
HomeAssistantActions,
|
|
180778
|
-
new HomeAssistantActions(
|
|
181120
|
+
new HomeAssistantActions(logger255, await this.load(HomeAssistantClient))
|
|
180779
181121
|
);
|
|
180780
181122
|
this.set(
|
|
180781
181123
|
HomeAssistantRegistry,
|
|
@@ -180811,7 +181153,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
|
|
|
180811
181153
|
this.set(
|
|
180812
181154
|
WebApi,
|
|
180813
181155
|
new WebApi(
|
|
180814
|
-
|
|
181156
|
+
logger255,
|
|
180815
181157
|
await this.load(BridgeService),
|
|
180816
181158
|
await this.load(HomeAssistantClient),
|
|
180817
181159
|
await this.load(HomeAssistantRegistry),
|
|
@@ -180832,7 +181174,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
|
|
|
180832
181174
|
|
|
180833
181175
|
// src/matter/patches/patch-level-control-tlv.ts
|
|
180834
181176
|
init_esm();
|
|
180835
|
-
var
|
|
181177
|
+
var logger254 = Logger.get("PatchLevelControlTlv");
|
|
180836
181178
|
var optionalFieldModels = /* @__PURE__ */ new WeakSet();
|
|
180837
181179
|
var fieldModelMandatoryGetterPatched = false;
|
|
180838
181180
|
function patchLevelControlTlv() {
|
|
@@ -180888,11 +181230,11 @@ function patchLevelControlTlv() {
|
|
|
180888
181230
|
patched++;
|
|
180889
181231
|
}
|
|
180890
181232
|
if (patched > 0) {
|
|
180891
|
-
|
|
181233
|
+
logger254.info(
|
|
180892
181234
|
`Patched ${patched} LevelControl TLV schema(s): transitionTime is now optional (Google Home compatibility)`
|
|
180893
181235
|
);
|
|
180894
181236
|
} else {
|
|
180895
|
-
|
|
181237
|
+
logger254.warn(
|
|
180896
181238
|
"Failed to patch LevelControl TLV schemas, field definitions not found. Google Home brightness adjustment may not work.",
|
|
180897
181239
|
{
|
|
180898
181240
|
moveToLevel: describeFields(
|
|
@@ -182634,6 +182976,7 @@ export {
|
|
|
182634
182976
|
@matter/main/dist/esm/version.js:
|
|
182635
182977
|
@matter/main/dist/esm/index.js:
|
|
182636
182978
|
@matter/main/dist/esm/protocol.js:
|
|
182979
|
+
@matter/main/dist/esm/types.js:
|
|
182637
182980
|
@matter/types/dist/esm/clusters/fan-control.js:
|
|
182638
182981
|
@matter/node/dist/esm/behaviors/fan-control/FanControlBehavior.js:
|
|
182639
182982
|
@matter/node/dist/esm/behaviors/fan-control/FanControlServer.js:
|
|
@@ -183064,7 +183407,6 @@ export {
|
|
|
183064
183407
|
@matter/node/dist/esm/devices/index.js:
|
|
183065
183408
|
@matter/main/dist/esm/devices.js:
|
|
183066
183409
|
@matter/main/dist/esm/node.js:
|
|
183067
|
-
@matter/main/dist/esm/types.js:
|
|
183068
183410
|
@matter/node/dist/esm/behaviors/account-login/index.js:
|
|
183069
183411
|
@matter/node/dist/esm/behaviors/actions/ActionsClient.js:
|
|
183070
183412
|
@matter/node/dist/esm/behaviors/actions/index.js:
|
|
@@ -183289,6 +183631,13 @@ export {
|
|
|
183289
183631
|
@matter/node/dist/esm/behaviors/zone-management/index.js:
|
|
183290
183632
|
@matter/node/dist/esm/behaviors/index.js:
|
|
183291
183633
|
@matter/main/dist/esm/behaviors.js:
|
|
183634
|
+
@matter/types/dist/esm/clusters/alarm-base.js:
|
|
183635
|
+
@matter/types/dist/esm/clusters/concentration-measurement.js:
|
|
183636
|
+
@matter/types/dist/esm/clusters/label.js:
|
|
183637
|
+
@matter/types/dist/esm/clusters/resource-monitoring.js:
|
|
183638
|
+
@matter/types/dist/esm/clusters/web-rtc-transport-definitions.js:
|
|
183639
|
+
@matter/types/dist/esm/clusters/index.js:
|
|
183640
|
+
@matter/main/dist/esm/clusters.js:
|
|
183292
183641
|
@matter/node/dist/esm/endpoints/base.js:
|
|
183293
183642
|
@matter/node/dist/esm/endpoints/bridged-node.js:
|
|
183294
183643
|
@matter/node/dist/esm/endpoints/device-energy-management.js:
|
|
@@ -183300,13 +183649,6 @@ export {
|
|
|
183300
183649
|
@matter/node/dist/esm/endpoints/secondary-network-interface.js:
|
|
183301
183650
|
@matter/node/dist/esm/endpoints/index.js:
|
|
183302
183651
|
@matter/main/dist/esm/endpoints.js:
|
|
183303
|
-
@matter/types/dist/esm/clusters/alarm-base.js:
|
|
183304
|
-
@matter/types/dist/esm/clusters/concentration-measurement.js:
|
|
183305
|
-
@matter/types/dist/esm/clusters/label.js:
|
|
183306
|
-
@matter/types/dist/esm/clusters/resource-monitoring.js:
|
|
183307
|
-
@matter/types/dist/esm/clusters/web-rtc-transport-definitions.js:
|
|
183308
|
-
@matter/types/dist/esm/clusters/index.js:
|
|
183309
|
-
@matter/main/dist/esm/clusters.js:
|
|
183310
183652
|
@matter/main/dist/esm/model.js:
|
|
183311
183653
|
@matter/main/dist/esm/forwards/clusters/level-control.js:
|
|
183312
183654
|
@matter/main/dist/esm/forwards/behaviors/boolean-state.js:
|