diff --git a/www/parental_controls.html b/www/parental_controls.html index 2e68cc5..f6582f4 100644 --- a/www/parental_controls.html +++ b/www/parental_controls.html @@ -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; }