@riddix/hamh 2.1.0-alpha.839 → 2.1.0-alpha.840
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(logger250) {
|
|
1771
|
+
this.#logger = logger250;
|
|
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, logger250, 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 = logger250;
|
|
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 logger250 = Logger.get(this.#subject.constructor.name);
|
|
5691
|
+
logger250.error(...args);
|
|
5692
5692
|
}
|
|
5693
5693
|
#createErrorHandler(name) {
|
|
5694
5694
|
return (e) => {
|
|
@@ -64070,8 +64070,8 @@ var init_NodeSession = __esm({
|
|
|
64070
64070
|
return session?.type === SessionType.Unicast;
|
|
64071
64071
|
}
|
|
64072
64072
|
NodeSession2.is = is;
|
|
64073
|
-
function logNew(
|
|
64074
|
-
|
|
64073
|
+
function logNew(logger250, operation, session, messenger, fabric, peerNodeId) {
|
|
64074
|
+
logger250.info(
|
|
64075
64075
|
session.via,
|
|
64076
64076
|
`${operation} session with`,
|
|
64077
64077
|
Diagnostic.strong(PeerAddress({ fabricIndex: fabric.fabricIndex, nodeId: peerNodeId }).toString()),
|
|
@@ -117714,11 +117714,11 @@ var init_Api = __esm({
|
|
|
117714
117714
|
}
|
|
117715
117715
|
Api2.resourceFor = resourceFor;
|
|
117716
117716
|
function log(level, facility, id, ...message) {
|
|
117717
|
-
let
|
|
117718
|
-
if (!
|
|
117719
|
-
loggers.set(facility,
|
|
117717
|
+
let logger250 = loggers.get(facility);
|
|
117718
|
+
if (!logger250) {
|
|
117719
|
+
loggers.set(facility, logger250 = Logger.get(facility));
|
|
117720
117720
|
}
|
|
117721
|
-
|
|
117721
|
+
logger250[level](Diagnostic.via(id || "(anon)"), message);
|
|
117722
117722
|
}
|
|
117723
117723
|
Api2.log = log;
|
|
117724
117724
|
function logRequest(facility, id, method, target) {
|
|
@@ -132631,10 +132631,10 @@ var init_home_assistant_actions = __esm({
|
|
|
132631
132631
|
circuitBreakerResetMs: 3e4
|
|
132632
132632
|
};
|
|
132633
132633
|
HomeAssistantActions = class extends Service {
|
|
132634
|
-
constructor(
|
|
132634
|
+
constructor(logger250, client, config11) {
|
|
132635
132635
|
super("HomeAssistantActions");
|
|
132636
132636
|
this.client = client;
|
|
132637
|
-
this.log =
|
|
132637
|
+
this.log = logger250.get(this);
|
|
132638
132638
|
this.config = { ...defaultConfig, ...config11 };
|
|
132639
132639
|
this.circuitBreaker = new CircuitBreaker(
|
|
132640
132640
|
this.config.circuitBreakerThreshold,
|
|
@@ -132980,10 +132980,10 @@ var DiagnosticService = class {
|
|
|
132980
132980
|
};
|
|
132981
132981
|
|
|
132982
132982
|
// src/api/access-log.ts
|
|
132983
|
-
function accessLogger(
|
|
132983
|
+
function accessLogger(logger250) {
|
|
132984
132984
|
return (req, res, next) => {
|
|
132985
132985
|
res.on("finish", () => {
|
|
132986
|
-
|
|
132986
|
+
logger250.debug(
|
|
132987
132987
|
`${req.method} ${decodeURI(req.originalUrl)} ${res.statusCode} ${res.statusMessage} from ${req.socket.remoteAddress}`
|
|
132988
132988
|
);
|
|
132989
132989
|
});
|
|
@@ -137530,7 +137530,7 @@ var WebSocketApi = class {
|
|
|
137530
137530
|
|
|
137531
137531
|
// src/api/web-api.ts
|
|
137532
137532
|
var WebApi = class extends Service {
|
|
137533
|
-
constructor(
|
|
137533
|
+
constructor(logger250, bridgeService, haClient, haRegistry, bridgeStorage, mappingStorage, identityStorage, lockCredentialStorage, settingsStorage, backupService, props) {
|
|
137534
137534
|
super("WebApi");
|
|
137535
137535
|
this.bridgeService = bridgeService;
|
|
137536
137536
|
this.haClient = haClient;
|
|
@@ -137542,8 +137542,8 @@ var WebApi = class extends Service {
|
|
|
137542
137542
|
this.settingsStorage = settingsStorage;
|
|
137543
137543
|
this.backupService = backupService;
|
|
137544
137544
|
this.props = props;
|
|
137545
|
-
this.logger =
|
|
137546
|
-
this.log =
|
|
137545
|
+
this.logger = logger250;
|
|
137546
|
+
this.log = logger250.get(this);
|
|
137547
137547
|
this.accessLogger = accessLogger(this.log.createChild("Access Log"));
|
|
137548
137548
|
this.startTime = Date.now();
|
|
137549
137549
|
this.wsApi = new WebSocketApi(
|
|
@@ -138734,10 +138734,10 @@ function isTransientConnectError(reason) {
|
|
|
138734
138734
|
return msg.includes("socket hang up") || msg.includes("tls") || msg.includes("TLS");
|
|
138735
138735
|
}
|
|
138736
138736
|
var HomeAssistantClient = class extends Service {
|
|
138737
|
-
constructor(
|
|
138737
|
+
constructor(logger250, options) {
|
|
138738
138738
|
super("HomeAssistantClient");
|
|
138739
138739
|
this.options = options;
|
|
138740
|
-
this.log =
|
|
138740
|
+
this.log = logger250.get(this);
|
|
138741
138741
|
}
|
|
138742
138742
|
options;
|
|
138743
138743
|
static Options = /* @__PURE__ */ Symbol.for("HomeAssistantClientProps");
|
|
@@ -157335,11 +157335,11 @@ var AUTO_FORCE_SYNC_INTERVAL_MS = 9e4;
|
|
|
157335
157335
|
var SHUTDOWN_SESSION_CLOSE_TIMEOUT_MS = 2500;
|
|
157336
157336
|
var MDNS_ADDRESS_CHECK_INTERVAL_MS = 6e4;
|
|
157337
157337
|
var Bridge = class {
|
|
157338
|
-
constructor(env,
|
|
157338
|
+
constructor(env, logger250, dataProvider, endpointManager, serverOptions) {
|
|
157339
157339
|
this.dataProvider = dataProvider;
|
|
157340
157340
|
this.endpointManager = endpointManager;
|
|
157341
157341
|
this.serverOptions = serverOptions;
|
|
157342
|
-
this.log =
|
|
157342
|
+
this.log = logger250.get(`Bridge / ${dataProvider.id}`);
|
|
157343
157343
|
this.server = new BridgeServerNode(
|
|
157344
157344
|
env,
|
|
157345
157345
|
this.dataProvider,
|
|
@@ -172957,18 +172957,32 @@ var CameraAvStreamServer = class extends Base4 {
|
|
|
172957
172957
|
})(CameraAvStreamServer || (CameraAvStreamServer = {}));
|
|
172958
172958
|
|
|
172959
172959
|
// src/plugins/builtin/camera/webrtc-provider-server.ts
|
|
172960
|
+
init_esm();
|
|
172960
172961
|
init_esm7();
|
|
172961
172962
|
init_esm3();
|
|
172963
|
+
var logger244 = Logger.get("CameraWebRtc");
|
|
172962
172964
|
var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
|
|
172963
172965
|
solicitOffer(request) {
|
|
172964
172966
|
const id = this.state.nextSessionId++;
|
|
172965
172967
|
this.trackSession(id, request.streamUsage, request.originatingEndpointId);
|
|
172966
|
-
|
|
172967
|
-
|
|
172968
|
+
logger244.info(
|
|
172969
|
+
`solicitOffer session=${id} (${this.state.entityId}), deferred offer`
|
|
172970
|
+
);
|
|
172971
|
+
void this.state.bridge.startSession(id, this.state.entityId, {
|
|
172972
|
+
iceServers: request.iceServers,
|
|
172973
|
+
iceTransportPolicy: request.iceTransportPolicy
|
|
172974
|
+
}).catch(
|
|
172975
|
+
(err) => logger244.info(
|
|
172976
|
+
`solicitOffer startSession failed for ${this.state.entityId}: ${errText(err)}`
|
|
172977
|
+
)
|
|
172978
|
+
);
|
|
172968
172979
|
return { webRtcSessionId: id, deferredOffer: true };
|
|
172969
172980
|
}
|
|
172970
172981
|
async provideOffer(request) {
|
|
172971
172982
|
const id = request.webRtcSessionId ?? this.state.nextSessionId++;
|
|
172983
|
+
logger244.info(
|
|
172984
|
+
`provideOffer entry: entityId=${this.state.entityId} session=${id} (sdp ${request.sdp.length} chars)`
|
|
172985
|
+
);
|
|
172972
172986
|
if (request.webRtcSessionId == null) {
|
|
172973
172987
|
this.trackSession(
|
|
172974
172988
|
id,
|
|
@@ -172976,30 +172990,62 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
|
|
|
172976
172990
|
request.originatingEndpointId ?? EndpointNumber(0)
|
|
172977
172991
|
);
|
|
172978
172992
|
}
|
|
172979
|
-
|
|
172980
|
-
|
|
172981
|
-
this.state.
|
|
172982
|
-
|
|
172993
|
+
let answerSdp;
|
|
172994
|
+
try {
|
|
172995
|
+
answerSdp = await this.state.bridge.acceptControllerOffer(
|
|
172996
|
+
id,
|
|
172997
|
+
this.state.entityId,
|
|
172998
|
+
request.sdp,
|
|
172999
|
+
{
|
|
173000
|
+
iceServers: request.iceServers,
|
|
173001
|
+
iceTransportPolicy: request.iceTransportPolicy
|
|
173002
|
+
}
|
|
173003
|
+
);
|
|
173004
|
+
} catch (err) {
|
|
173005
|
+
const message = errText(err);
|
|
173006
|
+
logger244.info(
|
|
173007
|
+
`provideOffer failed for ${this.state.entityId} session=${id}: ${message}`
|
|
173008
|
+
);
|
|
173009
|
+
this.state.currentSessions = this.state.currentSessions.filter(
|
|
173010
|
+
(s) => s.id !== id
|
|
173011
|
+
);
|
|
173012
|
+
throw new StatusResponseError(
|
|
173013
|
+
`WebRTC offer failed: ${message}`,
|
|
173014
|
+
StatusCode.Failure
|
|
173015
|
+
);
|
|
173016
|
+
}
|
|
173017
|
+
logger244.info(
|
|
173018
|
+
`provideOffer answer computed for ${this.state.entityId} session=${id} (${answerSdp.length} chars); awaiting requestor delivery path`
|
|
172983
173019
|
);
|
|
172984
173020
|
void answerSdp;
|
|
172985
173021
|
return { webRtcSessionId: id };
|
|
172986
173022
|
}
|
|
172987
173023
|
provideAnswer(request) {
|
|
173024
|
+
logger244.info(
|
|
173025
|
+
`provideAnswer session=${request.webRtcSessionId} (sdp ${request.sdp.length} chars, ${this.state.entityId})`
|
|
173026
|
+
);
|
|
172988
173027
|
return this.state.bridge.acceptControllerAnswer(
|
|
172989
173028
|
request.webRtcSessionId,
|
|
172990
173029
|
request.sdp
|
|
172991
173030
|
);
|
|
172992
173031
|
}
|
|
172993
173032
|
async provideIceCandidates(request) {
|
|
173033
|
+
logger244.info(
|
|
173034
|
+
`provideIceCandidates session=${request.webRtcSessionId}: ${request.iceCandidates.length} candidate(s) (${this.state.entityId})`
|
|
173035
|
+
);
|
|
172994
173036
|
for (const c of request.iceCandidates) {
|
|
172995
173037
|
await this.state.bridge.addControllerIceCandidate(
|
|
172996
173038
|
request.webRtcSessionId,
|
|
172997
173039
|
c.candidate,
|
|
172998
|
-
c.sdpMid
|
|
173040
|
+
c.sdpMid,
|
|
173041
|
+
c.sdpmLineIndex
|
|
172999
173042
|
);
|
|
173000
173043
|
}
|
|
173001
173044
|
}
|
|
173002
173045
|
async endSession(request) {
|
|
173046
|
+
logger244.info(
|
|
173047
|
+
`endSession session=${request.webRtcSessionId} (${this.state.entityId})`
|
|
173048
|
+
);
|
|
173003
173049
|
await this.state.bridge.endSession(request.webRtcSessionId);
|
|
173004
173050
|
this.state.currentSessions = this.state.currentSessions.filter(
|
|
173005
173051
|
(s) => s.id !== request.webRtcSessionId
|
|
@@ -173020,6 +173066,9 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
|
|
|
173020
173066
|
];
|
|
173021
173067
|
}
|
|
173022
173068
|
};
|
|
173069
|
+
function errText(err) {
|
|
173070
|
+
return err instanceof Error ? err.message : String(err);
|
|
173071
|
+
}
|
|
173023
173072
|
((CameraWebRtcProviderServer2) => {
|
|
173024
173073
|
class State extends WebRtcTransportProviderServer.State {
|
|
173025
173074
|
bridge;
|
|
@@ -173106,108 +173155,180 @@ function createCameraEndpointType(bridge, entityId, sensor = defaultSensorParams
|
|
|
173106
173155
|
}
|
|
173107
173156
|
|
|
173108
173157
|
// src/plugins/builtin/camera/webrtc-bridge.ts
|
|
173158
|
+
init_esm();
|
|
173109
173159
|
import {
|
|
173110
173160
|
createConnection as createConnection3,
|
|
173111
173161
|
createLongLivedTokenAuth as createLongLivedTokenAuth2
|
|
173112
173162
|
} from "home-assistant-js-websocket";
|
|
173113
173163
|
import { RTCPeerConnection } from "werift";
|
|
173164
|
+
var logger245 = Logger.get("CameraWebRtc");
|
|
173165
|
+
var DEFAULT_HA_WEBRTC_TIMEOUT_MS = 15e3;
|
|
173166
|
+
var haWebRtcTimeoutMs = DEFAULT_HA_WEBRTC_TIMEOUT_MS;
|
|
173114
173167
|
var WebRtcBridge = class {
|
|
173115
|
-
constructor(config11) {
|
|
173168
|
+
constructor(config11, deps = {}) {
|
|
173116
173169
|
this.config = config11;
|
|
173170
|
+
this.deps = deps;
|
|
173117
173171
|
}
|
|
173118
173172
|
config;
|
|
173173
|
+
deps;
|
|
173119
173174
|
connection;
|
|
173120
173175
|
sessions = /* @__PURE__ */ new Map();
|
|
173121
173176
|
async ha() {
|
|
173122
173177
|
if (this.connection) return this.connection;
|
|
173123
|
-
|
|
173124
|
-
this.config
|
|
173125
|
-
|
|
173126
|
-
|
|
173127
|
-
|
|
173178
|
+
if (this.deps.connect) {
|
|
173179
|
+
this.connection = await this.deps.connect(this.config);
|
|
173180
|
+
} else {
|
|
173181
|
+
const auth = createLongLivedTokenAuth2(
|
|
173182
|
+
this.config.haUrl,
|
|
173183
|
+
this.config.haToken
|
|
173184
|
+
);
|
|
173185
|
+
this.connection = await createConnection3({ auth });
|
|
173186
|
+
}
|
|
173128
173187
|
return this.connection;
|
|
173129
173188
|
}
|
|
173130
173189
|
// We offer to the controller; it answers. Pulls HA media first, then forwards.
|
|
173131
|
-
async startSession(matterSessionId, entityId) {
|
|
173190
|
+
async startSession(matterSessionId, entityId, ice) {
|
|
173132
173191
|
const haPeer = new RTCPeerConnection();
|
|
173133
|
-
const controllerPeer = new RTCPeerConnection(
|
|
173134
|
-
|
|
173135
|
-
|
|
173136
|
-
|
|
173137
|
-
|
|
173192
|
+
const controllerPeer = new RTCPeerConnection(
|
|
173193
|
+
this.controllerConfig(entityId, ice)
|
|
173194
|
+
);
|
|
173195
|
+
this.wireStateLogging(haPeer, "haPeer", entityId);
|
|
173196
|
+
this.wireStateLogging(controllerPeer, "controllerPeer", entityId);
|
|
173197
|
+
const senders = /* @__PURE__ */ new Map();
|
|
173198
|
+
senders.set(
|
|
173199
|
+
"video",
|
|
173200
|
+
controllerPeer.addTransceiver("video", { direction: "sendonly" })
|
|
173201
|
+
);
|
|
173202
|
+
this.forwardHaTracks(haPeer, senders, entityId);
|
|
173203
|
+
this.sessions.set(matterSessionId, { entityId, haPeer, controllerPeer });
|
|
173204
|
+
try {
|
|
173205
|
+
haPeer.addTransceiver("video", { direction: "recvonly" });
|
|
173206
|
+
haPeer.addTransceiver("audio", { direction: "recvonly" });
|
|
173207
|
+
const haOffer = await haPeer.createOffer();
|
|
173208
|
+
await haPeer.setLocalDescription(haOffer);
|
|
173209
|
+
const haOfferSdp = this.localSdp(haPeer);
|
|
173210
|
+
logger245.info(`HA offer sent for ${entityId} (${haOfferSdp.length} chars)`);
|
|
173211
|
+
const { answer, sessionId, unsubscribe } = await this.requestHaWebRtc(
|
|
173212
|
+
entityId,
|
|
173213
|
+
haOfferSdp,
|
|
173214
|
+
haPeer
|
|
173138
173215
|
);
|
|
173139
|
-
|
|
173140
|
-
|
|
173141
|
-
|
|
173142
|
-
|
|
173143
|
-
|
|
173144
|
-
|
|
173145
|
-
|
|
173146
|
-
|
|
173147
|
-
|
|
173148
|
-
|
|
173149
|
-
|
|
173150
|
-
|
|
173151
|
-
|
|
173152
|
-
|
|
173153
|
-
|
|
173154
|
-
|
|
173155
|
-
|
|
173156
|
-
|
|
173157
|
-
|
|
173158
|
-
|
|
173159
|
-
|
|
173160
|
-
|
|
173161
|
-
|
|
173162
|
-
|
|
173216
|
+
const session = this.sessions.get(matterSessionId);
|
|
173217
|
+
if (session) {
|
|
173218
|
+
session.haSessionId = sessionId;
|
|
173219
|
+
session.haUnsubscribe = unsubscribe;
|
|
173220
|
+
}
|
|
173221
|
+
await haPeer.setRemoteDescription({ type: "answer", sdp: answer });
|
|
173222
|
+
const iceCandidates = [];
|
|
173223
|
+
controllerPeer.onIceCandidate.subscribe((c) => {
|
|
173224
|
+
if (c?.candidate)
|
|
173225
|
+
iceCandidates.push({
|
|
173226
|
+
candidate: c.candidate,
|
|
173227
|
+
sdpMid: c.sdpMid ?? null
|
|
173228
|
+
});
|
|
173229
|
+
});
|
|
173230
|
+
const controllerOffer = await controllerPeer.createOffer();
|
|
173231
|
+
await controllerPeer.setLocalDescription(controllerOffer);
|
|
173232
|
+
const sdp = this.localSdp(controllerPeer);
|
|
173233
|
+
logger245.info(
|
|
173234
|
+
`controller offer created for ${entityId} (${sdp.length} chars)`
|
|
173235
|
+
);
|
|
173236
|
+
return { sdp, iceCandidates };
|
|
173237
|
+
} catch (err) {
|
|
173238
|
+
logger245.info(`startSession failed for ${entityId}: ${errText2(err)}`);
|
|
173239
|
+
await this.endSession(matterSessionId);
|
|
173240
|
+
throw err;
|
|
173241
|
+
}
|
|
173163
173242
|
}
|
|
173164
173243
|
// ProvideOffer flow: controller sent its offer. Pull HA media, answer it.
|
|
173165
173244
|
// Returning the answer to the controller is the unverified Requestor path.
|
|
173166
|
-
async acceptControllerOffer(matterSessionId, entityId, controllerOfferSdp) {
|
|
173245
|
+
async acceptControllerOffer(matterSessionId, entityId, controllerOfferSdp, ice) {
|
|
173167
173246
|
const haPeer = new RTCPeerConnection();
|
|
173168
|
-
const controllerPeer = new RTCPeerConnection(
|
|
173169
|
-
|
|
173170
|
-
|
|
173171
|
-
|
|
173172
|
-
|
|
173173
|
-
|
|
173174
|
-
|
|
173247
|
+
const controllerPeer = new RTCPeerConnection(
|
|
173248
|
+
this.controllerConfig(entityId, ice)
|
|
173249
|
+
);
|
|
173250
|
+
this.wireStateLogging(haPeer, "haPeer", entityId);
|
|
173251
|
+
this.wireStateLogging(controllerPeer, "controllerPeer", entityId);
|
|
173252
|
+
const senders = /* @__PURE__ */ new Map();
|
|
173253
|
+
for (const kind of offerKinds(controllerOfferSdp)) {
|
|
173254
|
+
senders.set(
|
|
173255
|
+
kind,
|
|
173256
|
+
controllerPeer.addTransceiver(kind, { direction: "sendonly" })
|
|
173257
|
+
);
|
|
173258
|
+
}
|
|
173259
|
+
this.forwardHaTracks(haPeer, senders, entityId);
|
|
173175
173260
|
this.sessions.set(matterSessionId, { entityId, haPeer, controllerPeer });
|
|
173176
|
-
|
|
173177
|
-
|
|
173178
|
-
|
|
173179
|
-
|
|
173180
|
-
|
|
173181
|
-
|
|
173182
|
-
|
|
173183
|
-
|
|
173184
|
-
|
|
173185
|
-
|
|
173186
|
-
|
|
173187
|
-
|
|
173188
|
-
|
|
173261
|
+
try {
|
|
173262
|
+
haPeer.addTransceiver("video", { direction: "recvonly" });
|
|
173263
|
+
haPeer.addTransceiver("audio", { direction: "recvonly" });
|
|
173264
|
+
const haOffer = await haPeer.createOffer();
|
|
173265
|
+
await haPeer.setLocalDescription(haOffer);
|
|
173266
|
+
const haOfferSdp = this.localSdp(haPeer);
|
|
173267
|
+
logger245.info(`HA offer sent for ${entityId} (${haOfferSdp.length} chars)`);
|
|
173268
|
+
const { answer, sessionId, unsubscribe } = await this.requestHaWebRtc(
|
|
173269
|
+
entityId,
|
|
173270
|
+
haOfferSdp,
|
|
173271
|
+
haPeer
|
|
173272
|
+
);
|
|
173273
|
+
const session = this.sessions.get(matterSessionId);
|
|
173274
|
+
if (session) {
|
|
173275
|
+
session.haSessionId = sessionId;
|
|
173276
|
+
session.haUnsubscribe = unsubscribe;
|
|
173277
|
+
}
|
|
173278
|
+
await haPeer.setRemoteDescription({ type: "answer", sdp: answer });
|
|
173279
|
+
await controllerPeer.setRemoteDescription({
|
|
173280
|
+
type: "offer",
|
|
173281
|
+
sdp: controllerOfferSdp
|
|
173282
|
+
});
|
|
173283
|
+
const controllerAnswer = await controllerPeer.createAnswer();
|
|
173284
|
+
await controllerPeer.setLocalDescription(controllerAnswer);
|
|
173285
|
+
const answerSdp = this.localSdp(controllerPeer);
|
|
173286
|
+
logger245.info(
|
|
173287
|
+
`controller answer created for ${entityId} (${answerSdp.length} chars)`
|
|
173288
|
+
);
|
|
173289
|
+
return answerSdp;
|
|
173290
|
+
} catch (err) {
|
|
173291
|
+
logger245.info(
|
|
173292
|
+
`acceptControllerOffer failed for ${entityId}: ${errText2(err)}`
|
|
173293
|
+
);
|
|
173294
|
+
await this.endSession(matterSessionId);
|
|
173295
|
+
throw err;
|
|
173296
|
+
}
|
|
173189
173297
|
}
|
|
173190
173298
|
/** Apply the Matter controller's SDP answer to the controller peer. */
|
|
173191
173299
|
async acceptControllerAnswer(matterSessionId, sdp) {
|
|
173192
173300
|
const session = this.sessions.get(matterSessionId);
|
|
173193
173301
|
if (!session) return;
|
|
173302
|
+
logger245.debug(`controller answer applied for ${session.entityId}`);
|
|
173194
173303
|
await session.controllerPeer.setRemoteDescription({ type: "answer", sdp });
|
|
173195
173304
|
}
|
|
173196
173305
|
/** Add a remote ICE candidate from the Matter controller. */
|
|
173197
|
-
async addControllerIceCandidate(matterSessionId, candidate, sdpMid) {
|
|
173306
|
+
async addControllerIceCandidate(matterSessionId, candidate, sdpMid, sdpMLineIndex) {
|
|
173198
173307
|
const session = this.sessions.get(matterSessionId);
|
|
173199
173308
|
if (!session) return;
|
|
173309
|
+
logger245.debug(
|
|
173310
|
+
`controller ICE candidate for ${session.entityId}: ${candidate}`
|
|
173311
|
+
);
|
|
173200
173312
|
await session.controllerPeer.addIceCandidate({
|
|
173201
173313
|
candidate,
|
|
173202
|
-
sdpMid: sdpMid ?? void 0
|
|
173314
|
+
sdpMid: sdpMid ?? void 0,
|
|
173315
|
+
sdpMLineIndex: sdpMLineIndex ?? void 0
|
|
173203
173316
|
});
|
|
173204
173317
|
}
|
|
173205
173318
|
async endSession(matterSessionId) {
|
|
173206
173319
|
const session = this.sessions.get(matterSessionId);
|
|
173207
173320
|
if (!session) return;
|
|
173321
|
+
logger245.info(`ending session ${matterSessionId} (${session.entityId})`);
|
|
173208
173322
|
this.sessions.delete(matterSessionId);
|
|
173209
|
-
|
|
173210
|
-
|
|
173323
|
+
if (session.haUnsubscribe) {
|
|
173324
|
+
await Promise.resolve(session.haUnsubscribe()).catch(
|
|
173325
|
+
(err) => logger245.debug(`HA unsubscribe failed: ${errText2(err)}`)
|
|
173326
|
+
);
|
|
173327
|
+
}
|
|
173328
|
+
await session.haPeer.close().catch(() => {
|
|
173329
|
+
});
|
|
173330
|
+
await session.controllerPeer.close().catch(() => {
|
|
173331
|
+
});
|
|
173211
173332
|
if (session.haSessionId) {
|
|
173212
173333
|
try {
|
|
173213
173334
|
const conn = await this.ha();
|
|
@@ -173224,10 +173345,19 @@ var WebRtcBridge = class {
|
|
|
173224
173345
|
// Grab a still JPEG via HA's camera proxy (for CaptureSnapshot).
|
|
173225
173346
|
async snapshot(entityId) {
|
|
173226
173347
|
const url2 = `${this.config.haUrl}/api/camera_proxy/${entityId}`;
|
|
173227
|
-
|
|
173228
|
-
|
|
173229
|
-
|
|
173348
|
+
let res;
|
|
173349
|
+
try {
|
|
173350
|
+
res = await fetch(url2, {
|
|
173351
|
+
headers: { Authorization: `Bearer ${this.config.haToken}` }
|
|
173352
|
+
});
|
|
173353
|
+
} catch (err) {
|
|
173354
|
+
logger245.info(`snapshot fetch failed for ${entityId}: ${errText2(err)}`);
|
|
173355
|
+
throw err;
|
|
173356
|
+
}
|
|
173230
173357
|
if (!res.ok) {
|
|
173358
|
+
logger245.info(
|
|
173359
|
+
`snapshot fetch failed for ${entityId}: camera_proxy ${res.status}`
|
|
173360
|
+
);
|
|
173231
173361
|
throw new Error(`HA camera_proxy ${entityId}: ${res.status}`);
|
|
173232
173362
|
}
|
|
173233
173363
|
return new Uint8Array(await res.arrayBuffer());
|
|
@@ -173239,29 +173369,157 @@ var WebRtcBridge = class {
|
|
|
173239
173369
|
this.connection?.close();
|
|
173240
173370
|
this.connection = void 0;
|
|
173241
173371
|
}
|
|
173242
|
-
//
|
|
173243
|
-
|
|
173372
|
+
// Forward every track HA sends into the matching pre-added controller sender.
|
|
173373
|
+
forwardHaTracks(haPeer, senders, entityId) {
|
|
173374
|
+
haPeer.onTrack.subscribe((track) => {
|
|
173375
|
+
logger245.info(`onTrack ${track.kind} from HA (${entityId})`);
|
|
173376
|
+
const transceiver = senders.get(track.kind);
|
|
173377
|
+
if (!transceiver) {
|
|
173378
|
+
logger245.info(
|
|
173379
|
+
`no controller transceiver for ${track.kind} (${entityId})`
|
|
173380
|
+
);
|
|
173381
|
+
return;
|
|
173382
|
+
}
|
|
173383
|
+
let firstLogged = false;
|
|
173384
|
+
track.onReceiveRtp.subscribe((rtp) => {
|
|
173385
|
+
if (!firstLogged) {
|
|
173386
|
+
firstLogged = true;
|
|
173387
|
+
logger245.info(`first RTP forwarded for ${track.kind} (${entityId})`);
|
|
173388
|
+
}
|
|
173389
|
+
transceiver.sender.sendRtp(rtp);
|
|
173390
|
+
});
|
|
173391
|
+
});
|
|
173392
|
+
}
|
|
173393
|
+
// Log connection/ice state transitions (these events fire on change only).
|
|
173394
|
+
wireStateLogging(peer, label, entityId) {
|
|
173395
|
+
peer.connectionStateChange.subscribe(
|
|
173396
|
+
(s) => logger245.info(`${label} connectionState=${s} (${entityId})`)
|
|
173397
|
+
);
|
|
173398
|
+
peer.iceConnectionStateChange.subscribe(
|
|
173399
|
+
(s) => logger245.info(`${label} iceConnectionState=${s} (${entityId})`)
|
|
173400
|
+
);
|
|
173401
|
+
}
|
|
173402
|
+
// Map the Matter ICE struct onto werift's config. Only the controller peer
|
|
173403
|
+
// uses controller-supplied servers; the HA peer keeps werift defaults.
|
|
173404
|
+
controllerConfig(entityId, ice) {
|
|
173405
|
+
const iceServers = (ice?.iceServers ?? []).flatMap(
|
|
173406
|
+
(s) => (s.urLs ?? []).map((url2) => ({
|
|
173407
|
+
urls: url2,
|
|
173408
|
+
username: s.username,
|
|
173409
|
+
credential: s.credential
|
|
173410
|
+
}))
|
|
173411
|
+
);
|
|
173412
|
+
if (iceServers.length === 0) {
|
|
173413
|
+
logger245.info(`controller peer using default ICE servers (${entityId})`);
|
|
173414
|
+
return void 0;
|
|
173415
|
+
}
|
|
173416
|
+
const policy = ice?.iceTransportPolicy === "relay" || ice?.iceTransportPolicy === "all" ? ice.iceTransportPolicy : void 0;
|
|
173417
|
+
logger245.info(
|
|
173418
|
+
`controller peer using ${iceServers.length} controller ICE server(s)${policy ? ` policy=${policy}` : ""} (${entityId})`
|
|
173419
|
+
);
|
|
173420
|
+
return policy ? { iceServers, iceTransportPolicy: policy } : { iceServers };
|
|
173421
|
+
}
|
|
173422
|
+
localSdp(peer) {
|
|
173423
|
+
const local = peer.localDescription;
|
|
173424
|
+
if (!local) throw new Error("no local description");
|
|
173425
|
+
return local.sdp;
|
|
173426
|
+
}
|
|
173427
|
+
// Feed an HA trickle-ICE candidate into the HA peer.
|
|
173428
|
+
feedHaCandidate(entityId, haPeer, candidate) {
|
|
173429
|
+
const value = candidate?.candidate;
|
|
173430
|
+
if (!value) return;
|
|
173431
|
+
logger245.debug(`HA ICE candidate for ${entityId}: ${value}`);
|
|
173432
|
+
void haPeer.addIceCandidate({
|
|
173433
|
+
candidate: value,
|
|
173434
|
+
sdpMid: candidate?.sdpMid ?? void 0,
|
|
173435
|
+
sdpMLineIndex: candidate?.sdpMLineIndex ?? void 0
|
|
173436
|
+
}).catch(
|
|
173437
|
+
(e) => logger245.debug(
|
|
173438
|
+
`HA addIceCandidate failed for ${entityId}: ${errText2(e)}`
|
|
173439
|
+
)
|
|
173440
|
+
);
|
|
173441
|
+
}
|
|
173442
|
+
// Offer to HA's WebRTC and resolve on the first answer. Rejects on an error
|
|
173443
|
+
// reply or after a timeout; keeps the subscription open past the answer so HA
|
|
173444
|
+
// trickle candidates keep flowing into the HA peer until the session ends.
|
|
173445
|
+
async requestHaWebRtc(entityId, offerSdp, haPeer) {
|
|
173244
173446
|
const conn = await this.ha();
|
|
173245
|
-
|
|
173447
|
+
let unsubscribe = () => {
|
|
173448
|
+
};
|
|
173449
|
+
let sessionId;
|
|
173450
|
+
const answer = await new Promise((resolve11, reject) => {
|
|
173246
173451
|
let settled = false;
|
|
173452
|
+
let rejected = false;
|
|
173453
|
+
let timer;
|
|
173454
|
+
const settle = (fn) => {
|
|
173455
|
+
if (settled) return;
|
|
173456
|
+
settled = true;
|
|
173457
|
+
clearTimeout(timer);
|
|
173458
|
+
fn();
|
|
173459
|
+
};
|
|
173460
|
+
const fail = (err) => settle(() => {
|
|
173461
|
+
rejected = true;
|
|
173462
|
+
unsubscribe();
|
|
173463
|
+
reject(err);
|
|
173464
|
+
});
|
|
173465
|
+
timer = setTimeout(() => {
|
|
173466
|
+
logger245.info(
|
|
173467
|
+
`HA WebRTC timed out after ${haWebRtcTimeoutMs}ms for ${entityId}`
|
|
173468
|
+
);
|
|
173469
|
+
fail(
|
|
173470
|
+
new Error(`HA WebRTC request timed out after ${haWebRtcTimeoutMs}ms`)
|
|
173471
|
+
);
|
|
173472
|
+
}, haWebRtcTimeoutMs);
|
|
173247
173473
|
conn.subscribeMessage(
|
|
173248
173474
|
(msg) => {
|
|
173249
|
-
|
|
173250
|
-
|
|
173251
|
-
|
|
173252
|
-
|
|
173253
|
-
|
|
173254
|
-
|
|
173255
|
-
|
|
173475
|
+
switch (msg.type) {
|
|
173476
|
+
case "session":
|
|
173477
|
+
if (msg.session_id) sessionId = msg.session_id;
|
|
173478
|
+
break;
|
|
173479
|
+
case "answer":
|
|
173480
|
+
if (msg.answer) {
|
|
173481
|
+
if (msg.session_id) sessionId = msg.session_id;
|
|
173482
|
+
const ans = msg.answer;
|
|
173483
|
+
settle(() => {
|
|
173484
|
+
logger245.info(
|
|
173485
|
+
`HA answer received for ${entityId} (${ans.length} chars)`
|
|
173486
|
+
);
|
|
173487
|
+
resolve11(ans);
|
|
173488
|
+
});
|
|
173489
|
+
}
|
|
173490
|
+
break;
|
|
173491
|
+
case "error": {
|
|
173492
|
+
const detail = msg.message ?? msg.code ?? "unknown error";
|
|
173493
|
+
logger245.info(`HA WebRTC error for ${entityId}: ${detail}`);
|
|
173494
|
+
fail(new Error(`HA WebRTC error: ${detail}`));
|
|
173495
|
+
break;
|
|
173256
173496
|
}
|
|
173257
|
-
|
|
173497
|
+
case "candidate":
|
|
173498
|
+
this.feedHaCandidate(entityId, haPeer, msg.candidate);
|
|
173499
|
+
break;
|
|
173258
173500
|
}
|
|
173259
173501
|
},
|
|
173260
173502
|
{ type: "camera/webrtc/offer", entity_id: entityId, offer: offerSdp }
|
|
173261
|
-
).
|
|
173503
|
+
).then((unsub) => {
|
|
173504
|
+
unsubscribe = unsub;
|
|
173505
|
+
if (rejected) unsub();
|
|
173506
|
+
}).catch((err) => {
|
|
173507
|
+
fail(err instanceof Error ? err : new Error(String(err)));
|
|
173508
|
+
});
|
|
173262
173509
|
});
|
|
173510
|
+
return { answer, sessionId, unsubscribe };
|
|
173263
173511
|
}
|
|
173264
173512
|
};
|
|
173513
|
+
function offerKinds(sdp) {
|
|
173514
|
+
const kinds = [];
|
|
173515
|
+
for (const m of sdp.matchAll(/^m=(video|audio)/gm)) {
|
|
173516
|
+
kinds.push(m[1]);
|
|
173517
|
+
}
|
|
173518
|
+
return kinds;
|
|
173519
|
+
}
|
|
173520
|
+
function errText2(err) {
|
|
173521
|
+
return err instanceof Error ? err.message : String(err);
|
|
173522
|
+
}
|
|
173265
173523
|
|
|
173266
173524
|
// src/plugins/builtin/camera/camera-plugin.ts
|
|
173267
173525
|
var CONFIG_KEY = "config";
|
|
@@ -173407,7 +173665,7 @@ import {
|
|
|
173407
173665
|
getCollection
|
|
173408
173666
|
} from "home-assistant-js-websocket";
|
|
173409
173667
|
import { atLeastHaVersion } from "home-assistant-js-websocket/dist/util.js";
|
|
173410
|
-
var
|
|
173668
|
+
var logger246 = Logger.get("SubscribeEntities");
|
|
173411
173669
|
function processEvent(store, updates) {
|
|
173412
173670
|
const state = { ...store.state };
|
|
173413
173671
|
if (updates.a) {
|
|
@@ -173433,7 +173691,7 @@ function processEvent(store, updates) {
|
|
|
173433
173691
|
for (const entityId in updates.c) {
|
|
173434
173692
|
let entityState = state[entityId];
|
|
173435
173693
|
if (!entityState) {
|
|
173436
|
-
|
|
173694
|
+
logger246.warn("Received state update for unknown entity", entityId);
|
|
173437
173695
|
continue;
|
|
173438
173696
|
}
|
|
173439
173697
|
entityState = { ...entityState };
|
|
@@ -173522,7 +173780,7 @@ var subscribeEntities = (conn, onChange, entityIds) => {
|
|
|
173522
173780
|
// src/services/bridges/entity-isolation-service.ts
|
|
173523
173781
|
init_esm();
|
|
173524
173782
|
init_diagnostic_event_bus();
|
|
173525
|
-
var
|
|
173783
|
+
var logger247 = Logger.get("EntityIsolation");
|
|
173526
173784
|
var EntityIsolationServiceImpl = class {
|
|
173527
173785
|
isolatedEntities = /* @__PURE__ */ new Map();
|
|
173528
173786
|
isolationCallbacks = /* @__PURE__ */ new Map();
|
|
@@ -173587,13 +173845,13 @@ var EntityIsolationServiceImpl = class {
|
|
|
173587
173845
|
}
|
|
173588
173846
|
const parsed = this.parseEndpointPath(msg);
|
|
173589
173847
|
if (!parsed) {
|
|
173590
|
-
|
|
173848
|
+
logger247.warn("Could not parse entity from error:", msg);
|
|
173591
173849
|
return false;
|
|
173592
173850
|
}
|
|
173593
173851
|
const { bridgeId, entityName } = parsed;
|
|
173594
173852
|
const callback = this.isolationCallbacks.get(bridgeId);
|
|
173595
173853
|
if (!callback) {
|
|
173596
|
-
|
|
173854
|
+
logger247.warn(
|
|
173597
173855
|
`No isolation callback registered for bridge ${bridgeId}, entity: ${entityName}`
|
|
173598
173856
|
);
|
|
173599
173857
|
return false;
|
|
@@ -173608,7 +173866,7 @@ var EntityIsolationServiceImpl = class {
|
|
|
173608
173866
|
reason,
|
|
173609
173867
|
failedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
173610
173868
|
});
|
|
173611
|
-
|
|
173869
|
+
logger247.warn(
|
|
173612
173870
|
`Isolating entity "${entityName}" from bridge ${bridgeId} due to: ${reason}`
|
|
173613
173871
|
);
|
|
173614
173872
|
diagnosticEventBus.emit("entity_error", `Entity isolated: ${entityName}`, {
|
|
@@ -173620,7 +173878,7 @@ var EntityIsolationServiceImpl = class {
|
|
|
173620
173878
|
await callback(entityName);
|
|
173621
173879
|
return true;
|
|
173622
173880
|
} catch (e) {
|
|
173623
|
-
|
|
173881
|
+
logger247.error(`Failed to isolate entity ${entityName}:`, e);
|
|
173624
173882
|
return false;
|
|
173625
173883
|
}
|
|
173626
173884
|
}
|
|
@@ -175138,11 +175396,11 @@ function makeWarmStartState(state, now = (/* @__PURE__ */ new Date()).toISOStrin
|
|
|
175138
175396
|
return { ...state, last_updated: now };
|
|
175139
175397
|
}
|
|
175140
175398
|
var ServerModeBridge = class {
|
|
175141
|
-
constructor(
|
|
175399
|
+
constructor(logger250, dataProvider, endpointManager, server) {
|
|
175142
175400
|
this.dataProvider = dataProvider;
|
|
175143
175401
|
this.endpointManager = endpointManager;
|
|
175144
175402
|
this.server = server;
|
|
175145
|
-
this.log =
|
|
175403
|
+
this.log = logger250.get(`ServerModeBridge / ${dataProvider.id}`);
|
|
175146
175404
|
}
|
|
175147
175405
|
dataProvider;
|
|
175148
175406
|
endpointManager;
|
|
@@ -176172,7 +176430,7 @@ function ServerModeVacuumDevice(homeAssistantEntity, includeOnOff = false, clean
|
|
|
176172
176430
|
}
|
|
176173
176431
|
|
|
176174
176432
|
// src/matter/endpoints/server-mode-vacuum-endpoint.ts
|
|
176175
|
-
var
|
|
176433
|
+
var logger248 = Logger.get("ServerModeVacuumEndpoint");
|
|
176176
176434
|
var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEndpoint {
|
|
176177
176435
|
static async create(registry2, entityId, mapping, endpointId) {
|
|
176178
176436
|
const deviceRegistry = registry2.deviceOf(entityId);
|
|
@@ -176185,7 +176443,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
176185
176443
|
if (mapping?.disableBatteryMapping && mapping.batteryEntity) {
|
|
176186
176444
|
effectiveMapping = { ...mapping, batteryEntity: void 0 };
|
|
176187
176445
|
}
|
|
176188
|
-
|
|
176446
|
+
logger248.info(
|
|
176189
176447
|
`${entityId}: device_id=${entity.device_id}, manualBattery=${mapping?.batteryEntity ?? "none"}`
|
|
176190
176448
|
);
|
|
176191
176449
|
if (entity.device_id) {
|
|
@@ -176200,15 +176458,15 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
176200
176458
|
batteryEntity: batteryEntityId
|
|
176201
176459
|
};
|
|
176202
176460
|
registry2.markBatteryEntityUsed(batteryEntityId);
|
|
176203
|
-
|
|
176461
|
+
logger248.info(`${entityId}: Auto-assigned battery ${batteryEntityId}`);
|
|
176204
176462
|
} else {
|
|
176205
176463
|
const attrs = state.attributes;
|
|
176206
176464
|
if (attrs.battery_level != null || attrs.battery != null) {
|
|
176207
|
-
|
|
176465
|
+
logger248.info(
|
|
176208
176466
|
`${entityId}: No battery entity found, using battery attribute from vacuum state`
|
|
176209
176467
|
);
|
|
176210
176468
|
} else {
|
|
176211
|
-
|
|
176469
|
+
logger248.warn(
|
|
176212
176470
|
`${entityId}: No battery entity found for device ${entity.device_id}`
|
|
176213
176471
|
);
|
|
176214
176472
|
}
|
|
@@ -176223,7 +176481,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
176223
176481
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
176224
176482
|
cleaningModeEntity: vacuumEntities.cleaningModeEntity
|
|
176225
176483
|
};
|
|
176226
|
-
|
|
176484
|
+
logger248.info(
|
|
176227
176485
|
`${entityId}: Auto-assigned cleaningMode ${vacuumEntities.cleaningModeEntity}`
|
|
176228
176486
|
);
|
|
176229
176487
|
}
|
|
@@ -176233,7 +176491,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
176233
176491
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
176234
176492
|
suctionLevelEntity: vacuumEntities.suctionLevelEntity
|
|
176235
176493
|
};
|
|
176236
|
-
|
|
176494
|
+
logger248.info(
|
|
176237
176495
|
`${entityId}: Auto-assigned suctionLevel ${vacuumEntities.suctionLevelEntity}`
|
|
176238
176496
|
);
|
|
176239
176497
|
}
|
|
@@ -176243,7 +176501,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
176243
176501
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
176244
176502
|
mopIntensityEntity: vacuumEntities.mopIntensityEntity
|
|
176245
176503
|
};
|
|
176246
|
-
|
|
176504
|
+
logger248.info(
|
|
176247
176505
|
`${entityId}: Auto-assigned mopIntensity ${vacuumEntities.mopIntensityEntity}`
|
|
176248
176506
|
);
|
|
176249
176507
|
}
|
|
@@ -176253,7 +176511,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
176253
176511
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
176254
176512
|
currentRoomEntity: vacuumEntities.currentRoomEntity
|
|
176255
176513
|
};
|
|
176256
|
-
|
|
176514
|
+
logger248.info(
|
|
176257
176515
|
`${entityId}: Auto-assigned currentRoom ${vacuumEntities.currentRoomEntity}`
|
|
176258
176516
|
);
|
|
176259
176517
|
}
|
|
@@ -176268,7 +176526,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
176268
176526
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
176269
176527
|
cleanAreaRooms
|
|
176270
176528
|
};
|
|
176271
|
-
|
|
176529
|
+
logger248.info(
|
|
176272
176530
|
`${entityId}: Using ${cleanAreaRooms.length} HA areas via CLEAN_AREA`
|
|
176273
176531
|
);
|
|
176274
176532
|
}
|
|
@@ -176289,7 +176547,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
176289
176547
|
rooms: roomsObj
|
|
176290
176548
|
}
|
|
176291
176549
|
};
|
|
176292
|
-
|
|
176550
|
+
logger248.info(
|
|
176293
176551
|
`${entityId}: Auto-detected ${valetudoRooms.length} Valetudo segments`
|
|
176294
176552
|
);
|
|
176295
176553
|
} else {
|
|
@@ -176306,14 +176564,14 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
176306
176564
|
rooms: roomsObj
|
|
176307
176565
|
}
|
|
176308
176566
|
};
|
|
176309
|
-
|
|
176567
|
+
logger248.info(
|
|
176310
176568
|
`${entityId}: Auto-detected ${roborockRooms.length} Roborock rooms`
|
|
176311
176569
|
);
|
|
176312
176570
|
}
|
|
176313
176571
|
}
|
|
176314
176572
|
}
|
|
176315
176573
|
} else {
|
|
176316
|
-
|
|
176574
|
+
logger248.warn(`${entityId}: No device_id, cannot auto-assign battery`);
|
|
176317
176575
|
}
|
|
176318
176576
|
const payload = {
|
|
176319
176577
|
entity_id: entityId,
|
|
@@ -176386,11 +176644,11 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
176386
176644
|
}
|
|
176387
176645
|
if (mappedChanged) {
|
|
176388
176646
|
this.pendingMappedChange = true;
|
|
176389
|
-
|
|
176647
|
+
logger248.debug(
|
|
176390
176648
|
`Mapped entity change detected for ${this.entityId}, forcing update`
|
|
176391
176649
|
);
|
|
176392
176650
|
}
|
|
176393
|
-
|
|
176651
|
+
logger248.debug(
|
|
176394
176652
|
`State update received for ${this.entityId}: state=${state.state}`
|
|
176395
176653
|
);
|
|
176396
176654
|
this.lastState = state;
|
|
@@ -176968,10 +177226,10 @@ var BridgeEnvironmentFactory = class extends BridgeFactory {
|
|
|
176968
177226
|
// src/core/ioc/app-environment.ts
|
|
176969
177227
|
var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
|
|
176970
177228
|
constructor(rootEnv, options) {
|
|
176971
|
-
const
|
|
177229
|
+
const logger250 = rootEnv.get(LoggerService);
|
|
176972
177230
|
super({
|
|
176973
177231
|
id: "App",
|
|
176974
|
-
log:
|
|
177232
|
+
log: logger250.get("AppContainer"),
|
|
176975
177233
|
parent: rootEnv
|
|
176976
177234
|
});
|
|
176977
177235
|
this.options = options;
|
|
@@ -176985,8 +177243,8 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
|
|
|
176985
177243
|
}
|
|
176986
177244
|
construction;
|
|
176987
177245
|
async init() {
|
|
176988
|
-
const
|
|
176989
|
-
this.set(LoggerService,
|
|
177246
|
+
const logger250 = this.get(LoggerService);
|
|
177247
|
+
this.set(LoggerService, logger250);
|
|
176990
177248
|
this.set(AppStorage, new AppStorage(await this.load(StorageService)));
|
|
176991
177249
|
this.set(BridgeStorage, new BridgeStorage(await this.load(AppStorage)));
|
|
176992
177250
|
this.set(
|
|
@@ -177007,7 +177265,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
|
|
|
177007
177265
|
);
|
|
177008
177266
|
this.set(
|
|
177009
177267
|
HomeAssistantClient,
|
|
177010
|
-
new HomeAssistantClient(
|
|
177268
|
+
new HomeAssistantClient(logger250, this.options.homeAssistant)
|
|
177011
177269
|
);
|
|
177012
177270
|
this.set(
|
|
177013
177271
|
HomeAssistantConfig,
|
|
@@ -177015,7 +177273,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
|
|
|
177015
177273
|
);
|
|
177016
177274
|
this.set(
|
|
177017
177275
|
HomeAssistantActions,
|
|
177018
|
-
new HomeAssistantActions(
|
|
177276
|
+
new HomeAssistantActions(logger250, await this.load(HomeAssistantClient))
|
|
177019
177277
|
);
|
|
177020
177278
|
this.set(
|
|
177021
177279
|
HomeAssistantRegistry,
|
|
@@ -177051,7 +177309,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
|
|
|
177051
177309
|
this.set(
|
|
177052
177310
|
WebApi,
|
|
177053
177311
|
new WebApi(
|
|
177054
|
-
|
|
177312
|
+
logger250,
|
|
177055
177313
|
await this.load(BridgeService),
|
|
177056
177314
|
await this.load(HomeAssistantClient),
|
|
177057
177315
|
await this.load(HomeAssistantRegistry),
|
|
@@ -177072,7 +177330,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
|
|
|
177072
177330
|
|
|
177073
177331
|
// src/matter/patches/patch-level-control-tlv.ts
|
|
177074
177332
|
init_esm();
|
|
177075
|
-
var
|
|
177333
|
+
var logger249 = Logger.get("PatchLevelControlTlv");
|
|
177076
177334
|
var optionalFieldModels = /* @__PURE__ */ new WeakSet();
|
|
177077
177335
|
var fieldModelMandatoryGetterPatched = false;
|
|
177078
177336
|
function patchLevelControlTlv() {
|
|
@@ -177128,11 +177386,11 @@ function patchLevelControlTlv() {
|
|
|
177128
177386
|
patched++;
|
|
177129
177387
|
}
|
|
177130
177388
|
if (patched > 0) {
|
|
177131
|
-
|
|
177389
|
+
logger249.info(
|
|
177132
177390
|
`Patched ${patched} LevelControl TLV schema(s): transitionTime is now optional (Google Home compatibility)`
|
|
177133
177391
|
);
|
|
177134
177392
|
} else {
|
|
177135
|
-
|
|
177393
|
+
logger249.warn(
|
|
177136
177394
|
"Failed to patch LevelControl TLV schemas, field definitions not found. Google Home brightness adjustment may not work.",
|
|
177137
177395
|
{
|
|
177138
177396
|
moveToLevel: describeFields(
|