Fix connection timeout: use REST API for initial state load, increase WS timeout to 60s

Large HA instances with many entities cause get_states to exceed the 12s
WebSocket timeout. Now loads all states via /api/states HTTP endpoint first
(much more reliable for large payloads), with WebSocket get_states as fallback.
Also bumped WS send timeout from 12s to 60s for slow HA responses.
This commit is contained in:
2026-05-15 16:11:44 +10:00
parent 4bdb228a8c
commit 76b67d3470
+18 -5
View File
@@ -248,17 +248,30 @@ function dispatch(msg) {
function send(msg) {
return new Promise((res, rej) => {
const id = wsId++; msg.id = id; pending[id] = { res, rej };
setTimeout(() => { if (pending[id]) { delete pending[id]; rej(new Error('timeout')); } }, 12000);
setTimeout(() => { if (pending[id]) { delete pending[id]; rej(new Error('timeout')); } }, 60000);
ws.send(JSON.stringify(msg));
});
}
async function onAuth() {
setBadge('connected');
const r = await send({ type: 'get_states' });
r.result.forEach(s => { states[s.entity_id] = s; });
await send({ type: 'subscribe_events', event_type: 'state_changed' });
parseCfg(states[CFG_ENTITY]?.state); render();
// Use REST API for initial state load — handles large HA instances better
// than WebSocket get_states which can timeout with hundreds of entities
try {
const resp = await fetch(`${prefs.url}/api/states`, {
headers: { Authorization: `Bearer ${prefs.token}` }
});
if (resp.ok) { const all = await resp.json(); all.forEach(s => { states[s.entity_id] = s; }); }
} catch(e) {
try { const r = await send({ type: 'get_states' }); r.result.forEach(s => { states[s.entity_id] = s; }); }
catch(e2) { console.warn('Could not load initial states:', e2); }
}
try { await send({ type: 'subscribe_events', event_type: 'state_changed' }); }
catch(e) { console.warn('Could not subscribe to events:', e); }
parseCfg(states[CFG_ENTITY]?.state);
render();
}
function onStateChange({ entity_id, new_state }) {
states[entity_id] = new_state;
if (entity_id === CFG_ENTITY) { parseCfg(new_state?.state); schedRender(); return; }