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:
@@ -248,17 +248,30 @@ function dispatch(msg) {
|
|||||||
function send(msg) {
|
function send(msg) {
|
||||||
return new Promise((res, rej) => {
|
return new Promise((res, rej) => {
|
||||||
const id = wsId++; msg.id = id; pending[id] = { 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));
|
ws.send(JSON.stringify(msg));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onAuth() {
|
async function onAuth() {
|
||||||
setBadge('connected');
|
setBadge('connected');
|
||||||
const r = await send({ type: 'get_states' });
|
// Use REST API for initial state load — handles large HA instances better
|
||||||
r.result.forEach(s => { states[s.entity_id] = s; });
|
// than WebSocket get_states which can timeout with hundreds of entities
|
||||||
await send({ type: 'subscribe_events', event_type: 'state_changed' });
|
try {
|
||||||
parseCfg(states[CFG_ENTITY]?.state); render();
|
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 }) {
|
function onStateChange({ entity_id, new_state }) {
|
||||||
states[entity_id] = new_state;
|
states[entity_id] = new_state;
|
||||||
if (entity_id === CFG_ENTITY) { parseCfg(new_state?.state); schedRender(); return; }
|
if (entity_id === CFG_ENTITY) { parseCfg(new_state?.state); schedRender(); return; }
|
||||||
|
|||||||
Reference in New Issue
Block a user