ha-opencode 0.1.1 → 0.2.1
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/README.md +136 -236
- package/dist/commands.d.ts +13 -11
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +87 -135
- package/dist/commands.js.map +1 -1
- package/dist/ha-config.d.ts +42 -0
- package/dist/ha-config.d.ts.map +1 -0
- package/dist/ha-config.js +104 -0
- package/dist/ha-config.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +255 -83
- package/dist/index.js.map +1 -1
- package/dist/state.d.ts +20 -18
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +99 -108
- package/dist/state.js.map +1 -1
- package/dist/websocket.d.ts +113 -0
- package/dist/websocket.d.ts.map +1 -0
- package/dist/websocket.js +394 -0
- package/dist/websocket.js.map +1 -0
- package/package.json +9 -9
- package/blueprints/opencode_permission_response.yaml +0 -81
- package/blueprints/opencode_state_notifications.yaml +0 -191
- package/dist/cleanup.d.ts +0 -30
- package/dist/cleanup.d.ts.map +0 -1
- package/dist/cleanup.js +0 -125
- package/dist/cleanup.js.map +0 -1
- package/dist/config.d.ts +0 -28
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -18
- package/dist/config.js.map +0 -1
- package/dist/discovery.d.ts +0 -129
- package/dist/discovery.d.ts.map +0 -1
- package/dist/discovery.js +0 -257
- package/dist/discovery.js.map +0 -1
- package/dist/mqtt.d.ts +0 -16
- package/dist/mqtt.d.ts.map +0 -1
- package/dist/mqtt.js +0 -141
- package/dist/mqtt.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import "source-map-support/register.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { hostname } from "os";
|
|
3
|
+
import { tool } from "@opencode-ai/plugin";
|
|
4
|
+
import { createHAWebSocketClient, createReconnectingClient, } from "./websocket.js";
|
|
5
|
+
import { loadHAConnectionConfig, saveHAConnectionConfig, clearHAConnectionConfig, buildWebSocketUrl, } from "./ha-config.js";
|
|
5
6
|
import { StateTracker } from "./state.js";
|
|
6
7
|
import { CommandHandler } from "./commands.js";
|
|
7
8
|
import { notify } from "./notify.js";
|
|
8
|
-
import { runCleanupInBackground } from "./cleanup.js";
|
|
9
9
|
/**
|
|
10
10
|
* Extract project name from worktree path.
|
|
11
11
|
* e.g., "/Users/foo/code/myproject" -> "myproject"
|
|
@@ -16,28 +16,19 @@ function getProjectName(worktree) {
|
|
|
16
16
|
export const HomeAssistantPlugin = async (input) => {
|
|
17
17
|
// Track initialization state
|
|
18
18
|
let state = null;
|
|
19
|
-
let discovery = null;
|
|
20
19
|
let commands = null;
|
|
21
|
-
let
|
|
22
|
-
let
|
|
23
|
-
let
|
|
20
|
+
let wsClient = null;
|
|
21
|
+
let haConfig = null;
|
|
22
|
+
let connected = false;
|
|
24
23
|
let sessionInitialized = false;
|
|
25
24
|
let currentSessionId = null;
|
|
26
25
|
const projectName = getProjectName(input.project.worktree);
|
|
26
|
+
const machineHostname = hostname();
|
|
27
27
|
// Cleanup function for graceful shutdown
|
|
28
28
|
const cleanup = async () => {
|
|
29
|
-
if (
|
|
29
|
+
if (wsClient) {
|
|
30
30
|
try {
|
|
31
|
-
await
|
|
32
|
-
await discovery.unregisterDevice();
|
|
33
|
-
}
|
|
34
|
-
catch {
|
|
35
|
-
// Ignore errors during cleanup
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
if (mqttClient) {
|
|
39
|
-
try {
|
|
40
|
-
await mqttClient.close();
|
|
31
|
+
await wsClient.disconnect();
|
|
41
32
|
}
|
|
42
33
|
catch {
|
|
43
34
|
// Ignore errors during cleanup
|
|
@@ -50,45 +41,204 @@ export const HomeAssistantPlugin = async (input) => {
|
|
|
50
41
|
};
|
|
51
42
|
process.once("SIGINT", handleExit);
|
|
52
43
|
process.once("SIGTERM", handleExit);
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Try to connect to Home Assistant using saved config.
|
|
46
|
+
*/
|
|
47
|
+
async function tryConnect() {
|
|
48
|
+
haConfig = await loadHAConnectionConfig();
|
|
49
|
+
if (!haConfig) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
57
52
|
try {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
53
|
+
wsClient = createReconnectingClient({ url: haConfig.url, accessToken: haConfig.accessToken }, haConfig.instanceToken, machineHostname, {
|
|
54
|
+
onReconnected: () => {
|
|
55
|
+
connected = true;
|
|
56
|
+
notify("Home Assistant", "Reconnected");
|
|
57
|
+
// Re-send current state
|
|
58
|
+
if (state && wsClient && haConfig) {
|
|
59
|
+
const sessions = state.getAllSessions();
|
|
60
|
+
if (sessions.length > 0) {
|
|
61
|
+
wsClient
|
|
62
|
+
.sendStateResponse(haConfig.instanceToken, sessions)
|
|
63
|
+
.catch(() => { });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
onDisconnected: () => {
|
|
68
|
+
connected = false;
|
|
69
|
+
notify("Home Assistant", "Disconnected - reconnecting...");
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
await wsClient.connect();
|
|
73
|
+
const result = await wsClient.reconnect(haConfig.instanceToken, machineHostname);
|
|
74
|
+
if (!result.success) {
|
|
75
|
+
// Token might be invalid, clear it
|
|
76
|
+
if (result.error?.includes("invalid_token")) {
|
|
77
|
+
await clearHAConnectionConfig();
|
|
78
|
+
notify("Home Assistant", "Token invalid - please re-pair");
|
|
64
79
|
}
|
|
80
|
+
return false;
|
|
65
81
|
}
|
|
82
|
+
connected = true;
|
|
83
|
+
return true;
|
|
66
84
|
}
|
|
67
85
|
catch {
|
|
68
|
-
//
|
|
86
|
+
// Silent failure - will retry on next event
|
|
87
|
+
return false;
|
|
69
88
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Handle pairing with Home Assistant.
|
|
92
|
+
*/
|
|
93
|
+
async function handlePair(url, accessToken, code) {
|
|
94
|
+
const wsUrl = buildWebSocketUrl(url);
|
|
73
95
|
try {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
96
|
+
// Disconnect existing connection if any
|
|
97
|
+
if (wsClient) {
|
|
98
|
+
await wsClient.disconnect();
|
|
99
|
+
wsClient = null;
|
|
100
|
+
connected = false;
|
|
101
|
+
}
|
|
102
|
+
// Create new connection with access token for authentication
|
|
103
|
+
wsClient = createHAWebSocketClient({ url: wsUrl, accessToken });
|
|
104
|
+
await wsClient.connect();
|
|
105
|
+
// Attempt pairing
|
|
106
|
+
const result = await wsClient.pair(code.toUpperCase(), machineHostname);
|
|
107
|
+
if (!result.success) {
|
|
108
|
+
await wsClient.disconnect();
|
|
109
|
+
wsClient = null;
|
|
110
|
+
return `Pairing failed: ${result.error}`;
|
|
111
|
+
}
|
|
112
|
+
// Save the connection config
|
|
113
|
+
haConfig = {
|
|
114
|
+
url: wsUrl,
|
|
115
|
+
accessToken,
|
|
116
|
+
instanceToken: result.instanceToken,
|
|
117
|
+
instanceId: result.instanceId,
|
|
118
|
+
pairedAt: new Date().toISOString(),
|
|
119
|
+
};
|
|
120
|
+
await saveHAConnectionConfig(haConfig);
|
|
121
|
+
connected = true;
|
|
122
|
+
// Set up disconnect handler for reconnection on the existing client
|
|
123
|
+
const currentToken = haConfig.instanceToken;
|
|
124
|
+
let hasNotifiedDisconnect = false;
|
|
125
|
+
wsClient.onDisconnect(() => {
|
|
126
|
+
connected = false;
|
|
127
|
+
// Only notify once per disconnect cycle
|
|
128
|
+
if (!hasNotifiedDisconnect) {
|
|
129
|
+
hasNotifiedDisconnect = true;
|
|
130
|
+
notify("Home Assistant", "Disconnected - reconnecting...");
|
|
131
|
+
}
|
|
132
|
+
// Schedule reconnection
|
|
133
|
+
setTimeout(async () => {
|
|
134
|
+
try {
|
|
135
|
+
wsClient = createReconnectingClient({ url: wsUrl, accessToken }, currentToken, machineHostname, {
|
|
136
|
+
onReconnected: () => {
|
|
137
|
+
connected = true;
|
|
138
|
+
hasNotifiedDisconnect = false;
|
|
139
|
+
notify("Home Assistant", "Reconnected");
|
|
140
|
+
if (state && haConfig) {
|
|
141
|
+
const sessions = state.getAllSessions();
|
|
142
|
+
if (sessions.length > 0 && wsClient) {
|
|
143
|
+
wsClient
|
|
144
|
+
.sendStateResponse(haConfig.instanceToken, sessions)
|
|
145
|
+
.catch(() => { });
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
onDisconnected: () => {
|
|
150
|
+
connected = false;
|
|
151
|
+
if (!hasNotifiedDisconnect) {
|
|
152
|
+
hasNotifiedDisconnect = true;
|
|
153
|
+
notify("Home Assistant", "Disconnected - reconnecting...");
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
await wsClient.connect();
|
|
158
|
+
const reconnResult = await wsClient.reconnect(currentToken, machineHostname);
|
|
159
|
+
if (reconnResult.success) {
|
|
160
|
+
connected = true;
|
|
161
|
+
hasNotifiedDisconnect = false;
|
|
162
|
+
notify("Home Assistant", "Reconnected");
|
|
163
|
+
if (currentSessionId && haConfig) {
|
|
164
|
+
state = new StateTracker(wsClient, haConfig.instanceToken, projectName);
|
|
165
|
+
commands = new CommandHandler(wsClient, state, input.client, haConfig.instanceToken);
|
|
166
|
+
commands.start();
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
// Silent retry - the reconnecting client will keep trying
|
|
172
|
+
}
|
|
173
|
+
}, 5000);
|
|
80
174
|
});
|
|
175
|
+
// Initialize session tracking with the current connected client
|
|
176
|
+
if (currentSessionId) {
|
|
177
|
+
state = new StateTracker(wsClient, haConfig.instanceToken, projectName);
|
|
178
|
+
commands = new CommandHandler(wsClient, state, input.client, haConfig.instanceToken);
|
|
179
|
+
commands.start();
|
|
180
|
+
// Set the session ID and immediately publish an update to HA
|
|
181
|
+
try {
|
|
182
|
+
await state.setSessionId(currentSessionId, true);
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
// Silent failure
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return `Successfully paired with Home Assistant!
|
|
189
|
+
|
|
190
|
+
Instance ID: ${result.instanceId}
|
|
191
|
+
URL: ${wsUrl}
|
|
192
|
+
|
|
193
|
+
The connection will automatically reconnect if interrupted.`;
|
|
81
194
|
}
|
|
82
195
|
catch (err) {
|
|
83
|
-
|
|
196
|
+
const errorMsg = err instanceof Error ? err.message : "Unknown error";
|
|
197
|
+
return `Failed to pair: ${errorMsg}`;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Handle unpairing from Home Assistant.
|
|
202
|
+
*/
|
|
203
|
+
async function handleUnpair() {
|
|
204
|
+
if (wsClient) {
|
|
205
|
+
await wsClient.disconnect();
|
|
206
|
+
wsClient = null;
|
|
84
207
|
}
|
|
85
|
-
|
|
208
|
+
await clearHAConnectionConfig();
|
|
209
|
+
connected = false;
|
|
210
|
+
state = null;
|
|
211
|
+
commands = null;
|
|
212
|
+
haConfig = null;
|
|
213
|
+
return "Disconnected from Home Assistant. Pairing cleared.";
|
|
214
|
+
}
|
|
86
215
|
/**
|
|
87
|
-
*
|
|
88
|
-
* This creates Discovery, StateTracker, and CommandHandler for the session.
|
|
216
|
+
* Get connection status.
|
|
89
217
|
*/
|
|
90
|
-
|
|
91
|
-
if (!
|
|
218
|
+
function getStatus() {
|
|
219
|
+
if (!haConfig) {
|
|
220
|
+
return `Home Assistant: Not configured
|
|
221
|
+
|
|
222
|
+
Use the ha_pair tool to connect:
|
|
223
|
+
- url: Your Home Assistant URL (e.g., http://homeassistant.local:8123)
|
|
224
|
+
- access_token: A long-lived access token from HA (Profile > Long-Lived Access Tokens)
|
|
225
|
+
- code: The pairing code from the OpenCode integration in HA`;
|
|
226
|
+
}
|
|
227
|
+
const connStatus = connected && wsClient?.isConnected() ? "Connected" : "Disconnected";
|
|
228
|
+
return `Home Assistant: ${connStatus}
|
|
229
|
+
|
|
230
|
+
URL: ${haConfig.url}
|
|
231
|
+
Instance ID: ${haConfig.instanceId}
|
|
232
|
+
Paired: ${haConfig.pairedAt}
|
|
233
|
+
Current Session: ${currentSessionId || "None"}`;
|
|
234
|
+
}
|
|
235
|
+
// Try to connect on startup (non-blocking)
|
|
236
|
+
const connectPromise = tryConnect();
|
|
237
|
+
/**
|
|
238
|
+
* Initialize session tracking when we receive the first session event.
|
|
239
|
+
*/
|
|
240
|
+
function initializeSession(sessionId) {
|
|
241
|
+
if (!wsClient || !connected || !haConfig) {
|
|
92
242
|
return;
|
|
93
243
|
}
|
|
94
244
|
// Already initialized for this session
|
|
@@ -96,67 +246,89 @@ export const HomeAssistantPlugin = async (input) => {
|
|
|
96
246
|
return;
|
|
97
247
|
}
|
|
98
248
|
currentSessionId = sessionId;
|
|
99
|
-
// Create session
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
commands
|
|
103
|
-
|
|
104
|
-
await state.initialize();
|
|
105
|
-
await commands.start();
|
|
106
|
-
sessionInitialized = true;
|
|
107
|
-
}
|
|
108
|
-
catch (err) {
|
|
109
|
-
console.error("[ha-opencode] Failed to initialize session:", err);
|
|
110
|
-
sessionInitialized = false;
|
|
111
|
-
}
|
|
249
|
+
// Create session tracking components
|
|
250
|
+
state = new StateTracker(wsClient, haConfig.instanceToken, projectName);
|
|
251
|
+
commands = new CommandHandler(wsClient, state, input.client, haConfig.instanceToken);
|
|
252
|
+
commands.start();
|
|
253
|
+
sessionInitialized = true;
|
|
112
254
|
}
|
|
113
255
|
/**
|
|
114
256
|
* Extract session ID from event if available.
|
|
115
257
|
*/
|
|
116
258
|
function getSessionIdFromEvent(event) {
|
|
117
259
|
const props = event.properties;
|
|
118
|
-
//
|
|
119
|
-
if (props.info && typeof props.info === "object") {
|
|
120
|
-
const info = props.info;
|
|
121
|
-
if (typeof info.id === "string") {
|
|
122
|
-
return info.id;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
// permission.updated has sessionID
|
|
260
|
+
// permission.updated has sessionID at top level
|
|
126
261
|
if (typeof props.sessionID === "string") {
|
|
127
262
|
return props.sessionID;
|
|
128
263
|
}
|
|
129
|
-
//
|
|
264
|
+
// Most events have info object
|
|
130
265
|
if (props.info && typeof props.info === "object") {
|
|
131
266
|
const info = props.info;
|
|
267
|
+
// message.updated has info.sessionID (not info.id - that's the message ID!)
|
|
132
268
|
if (typeof info.sessionID === "string") {
|
|
133
269
|
return info.sessionID;
|
|
134
270
|
}
|
|
271
|
+
// session.created / session.updated have session info with id
|
|
272
|
+
// Only use info.id for session events (which start with "ses_")
|
|
273
|
+
if (typeof info.id === "string" && info.id.startsWith("ses_")) {
|
|
274
|
+
return info.id;
|
|
275
|
+
}
|
|
135
276
|
}
|
|
136
277
|
return null;
|
|
137
278
|
}
|
|
138
|
-
// Return hooks
|
|
279
|
+
// Return hooks
|
|
139
280
|
return {
|
|
281
|
+
// Custom tools for HA integration
|
|
282
|
+
tool: {
|
|
283
|
+
ha_pair: tool({
|
|
284
|
+
description: "Pair OpenCode with Home Assistant. First, add the OpenCode integration in Home Assistant (Settings > Devices & Services > Add Integration > OpenCode) to get a pairing code.",
|
|
285
|
+
args: {
|
|
286
|
+
url: tool.schema.string().describe("Home Assistant URL (e.g., http://homeassistant.local:8123)"),
|
|
287
|
+
access_token: tool.schema.string().describe("Long-lived access token from Home Assistant (Profile > Security > Long-Lived Access Tokens)"),
|
|
288
|
+
code: tool.schema.string().describe("Pairing code from the OpenCode integration in Home Assistant"),
|
|
289
|
+
},
|
|
290
|
+
async execute(args) {
|
|
291
|
+
return await handlePair(args.url, args.access_token, args.code);
|
|
292
|
+
},
|
|
293
|
+
}),
|
|
294
|
+
ha_unpair: tool({
|
|
295
|
+
description: "Disconnect and unpair from Home Assistant. This will clear the saved connection config.",
|
|
296
|
+
args: {},
|
|
297
|
+
async execute() {
|
|
298
|
+
return await handleUnpair();
|
|
299
|
+
},
|
|
300
|
+
}),
|
|
301
|
+
ha_status: tool({
|
|
302
|
+
description: "Check the Home Assistant connection status.",
|
|
303
|
+
args: {},
|
|
304
|
+
async execute() {
|
|
305
|
+
return getStatus();
|
|
306
|
+
},
|
|
307
|
+
}),
|
|
308
|
+
},
|
|
309
|
+
// Handle OpenCode events
|
|
140
310
|
event: async ({ event }) => {
|
|
141
311
|
// Send notification when session becomes idle (task complete)
|
|
142
312
|
if (event.type === "session.idle") {
|
|
143
313
|
notify("OpenCode", "Task complete");
|
|
144
314
|
}
|
|
145
|
-
// Wait for
|
|
146
|
-
if (!
|
|
147
|
-
await
|
|
148
|
-
mqttPromise,
|
|
149
|
-
new Promise((resolve) => setTimeout(resolve, 15000)),
|
|
150
|
-
]);
|
|
315
|
+
// Wait for connection attempt on first event
|
|
316
|
+
if (!connected) {
|
|
317
|
+
await connectPromise;
|
|
151
318
|
}
|
|
152
|
-
if (!
|
|
153
|
-
return; //
|
|
319
|
+
if (!wsClient || !connected || !haConfig) {
|
|
320
|
+
return; // Not connected, skip event
|
|
154
321
|
}
|
|
155
|
-
// Try to extract session ID from event
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
322
|
+
// Try to extract session ID from event, fall back to current session
|
|
323
|
+
// (some events like message.part.updated don't include session ID)
|
|
324
|
+
const sessionId = getSessionIdFromEvent(event) || currentSessionId;
|
|
325
|
+
// Initialize session tracking when we get a session ID
|
|
326
|
+
if (sessionId && (!sessionInitialized || currentSessionId !== sessionId)) {
|
|
327
|
+
initializeSession(sessionId);
|
|
328
|
+
// Also set the session ID in the state tracker
|
|
329
|
+
if (state) {
|
|
330
|
+
await state.setSessionId(sessionId, false);
|
|
331
|
+
}
|
|
160
332
|
}
|
|
161
333
|
if (!state || !sessionInitialized) {
|
|
162
334
|
return; // Session not ready, skip event
|
|
@@ -164,8 +336,8 @@ export const HomeAssistantPlugin = async (input) => {
|
|
|
164
336
|
try {
|
|
165
337
|
await state.handleEvent(event);
|
|
166
338
|
}
|
|
167
|
-
catch
|
|
168
|
-
|
|
339
|
+
catch {
|
|
340
|
+
// Silent failure
|
|
169
341
|
}
|
|
170
342
|
},
|
|
171
343
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/state.d.ts
CHANGED
|
@@ -1,31 +1,36 @@
|
|
|
1
1
|
import type { Event } from "@opencode-ai/sdk";
|
|
2
|
-
import type {
|
|
2
|
+
import type { HAWebSocketClient, SessionUpdate, PermissionInfo } from "./websocket.js";
|
|
3
3
|
export declare class StateTracker {
|
|
4
|
-
private readonly
|
|
4
|
+
private readonly wsClient;
|
|
5
|
+
private readonly instanceToken;
|
|
5
6
|
private state;
|
|
6
7
|
private pendingPermission;
|
|
7
8
|
private currentSessionId;
|
|
8
|
-
private
|
|
9
|
-
constructor(
|
|
9
|
+
private projectName;
|
|
10
|
+
constructor(wsClient: HAWebSocketClient, instanceToken: string, projectName: string);
|
|
10
11
|
getCurrentSessionId(): string | null;
|
|
12
|
+
getPendingPermission(): PermissionInfo | null;
|
|
11
13
|
/**
|
|
12
|
-
*
|
|
14
|
+
* Set the current session ID and optionally publish an update.
|
|
15
|
+
* Used when initializing with an existing session.
|
|
13
16
|
*/
|
|
14
|
-
|
|
17
|
+
setSessionId(sessionId: string, publishUpdate?: boolean): Promise<void>;
|
|
15
18
|
/**
|
|
16
|
-
*
|
|
17
|
-
* Registers the device with Home Assistant immediately since we have the session ID.
|
|
19
|
+
* Build a session update object for sending to HA.
|
|
18
20
|
*/
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
private buildSessionUpdate;
|
|
22
|
+
/**
|
|
23
|
+
* Send the current session state to Home Assistant.
|
|
24
|
+
*/
|
|
25
|
+
private publishUpdate;
|
|
26
|
+
/**
|
|
27
|
+
* Get all current sessions for state response.
|
|
28
|
+
* Currently we only track one session at a time.
|
|
29
|
+
*/
|
|
30
|
+
getAllSessions(): SessionUpdate[];
|
|
21
31
|
handleEvent(event: Event): Promise<void>;
|
|
22
32
|
private onSessionCreated;
|
|
23
33
|
private onSessionUpdated;
|
|
24
|
-
/**
|
|
25
|
-
* Update the device friendly name in Home Assistant if we have a valid title
|
|
26
|
-
* and haven't done so yet.
|
|
27
|
-
*/
|
|
28
|
-
private maybeUpdateDeviceName;
|
|
29
34
|
private onSessionIdle;
|
|
30
35
|
private onSessionError;
|
|
31
36
|
private onMessageUpdated;
|
|
@@ -35,8 +40,5 @@ export declare class StateTracker {
|
|
|
35
40
|
clearPermission(): Promise<void>;
|
|
36
41
|
private updateActivity;
|
|
37
42
|
private updateState;
|
|
38
|
-
private publishStateAttributes;
|
|
39
|
-
private publish;
|
|
40
|
-
private publishAll;
|
|
41
43
|
}
|
|
42
44
|
//# sourceMappingURL=state.d.ts.map
|
package/dist/state.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAc,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAc,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAmBvF,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAC7C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,WAAW,CAAS;gBAG1B,QAAQ,EAAE,iBAAiB,EAC3B,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM;IAqBrB,mBAAmB,IAAI,MAAM,GAAG,IAAI;IAIpC,oBAAoB,IAAI,cAAc,GAAG,IAAI;IAI7C;;;OAGG;IACG,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAOpF;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAoB1B;;OAEG;YACW,aAAa;IAe3B;;;OAGG;IACH,cAAc,IAAI,aAAa,EAAE;IAO3B,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;YAiChC,gBAAgB;YA0BhB,gBAAgB;YAYhB,aAAa;YASb,cAAc;YAkBd,gBAAgB;YA2BhB,oBAAoB;YA4CpB,mBAAmB;YA0BnB,mBAAmB;IAS3B,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtC,OAAO,CAAC,cAAc;YAIR,WAAW;CAa1B"}
|