mirror of
https://github.com/myronblair/jarvis
synced 2026-06-30 17:50:23 -05:00
fix: HA toggles — real-time ha_entities table, optimistic update, renderHATable extracted
This commit is contained in:
+22
-4
@@ -1165,6 +1165,7 @@ function toggleCamera() {
|
||||
let _refreshTick = 0;
|
||||
let selectedContext = null;
|
||||
const _panelCtx = {};
|
||||
let _haEntities = {};
|
||||
const _svcLabels = {lshttpd:'WEB',mysql:'MYSQL',redis:'REDIS',memcached:'MEMCACHE',postfix:'POSTFIX',dovecot:'DOVECOT','jarvis-agent':'AGENT'};
|
||||
|
||||
async function refreshAll() {
|
||||
@@ -1436,21 +1437,29 @@ async function loadHA() {
|
||||
dot.className='bb-dot online'; sta.textContent='ONLINE';
|
||||
|
||||
const entities = data.entities || {};
|
||||
_haEntities = entities;
|
||||
if (!Object.keys(entities).length) {
|
||||
el.innerHTML = '<div class="text-dim" style="font-size:0.75rem">No entities found.</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
const domainIcon = {
|
||||
renderHATable(entities);
|
||||
}}
|
||||
|
||||
const _domainIcon = {
|
||||
light:'\u{1F4A1}', switch:'\u{1F50C}', scene:'\u{1F3AC}',
|
||||
media_player:'\u{1F4FA}', alarm_control_panel:'\u{1F512}',
|
||||
lawn_mower:'\u{1F33F}', water_heater:'\u{1F321}', fan:'\u{1F4A8}',
|
||||
lock:'\u{1F511}', cover:'\u{1FA9F}', climate:'☃', input_boolean:'⚙'
|
||||
};
|
||||
|
||||
function renderHATable(entities) {
|
||||
const el = document.getElementById('ha-list');
|
||||
if (!el) return;
|
||||
let rows = '';
|
||||
let totalShown = 0;
|
||||
for (const [domain, items] of Object.entries(entities)) {
|
||||
const icon = domainIcon[domain] || '•';
|
||||
const icon = _domainIcon[domain] || '•';
|
||||
const available = items.filter(e => e.state !== 'unavailable' && e.state !== 'unknown');
|
||||
if (!available.length) continue;
|
||||
available.forEach(e => {
|
||||
@@ -1485,16 +1494,25 @@ async function loadHA() {
|
||||
|
||||
async function toggleHA(entityId, domain, currentState) {
|
||||
let service;
|
||||
const ON_STATES = ['on','home','open','locked','playing','mowing','armed_home','armed_away','armed_night','active'];
|
||||
const wasOn = ON_STATES.includes(currentState);
|
||||
if (domain === 'scene') {
|
||||
service = 'turn_on';
|
||||
} else if (domain === 'alarm_control_panel') {
|
||||
service = currentState === 'disarmed' ? 'alarm_arm_away' : 'alarm_disarm';
|
||||
} else {
|
||||
service = currentState === 'on' ? 'turn_off' : 'turn_on';
|
||||
service = wasOn ? 'turn_off' : 'turn_on';
|
||||
}
|
||||
try {
|
||||
await api('ha/service', 'POST', {domain, service, entity_id: entityId});
|
||||
setTimeout(loadHA, 1500);
|
||||
// Optimistic update — flip state immediately so toggle doesn't snap back
|
||||
if (_haEntities[domain]) {
|
||||
const ent = _haEntities[domain].find(e => e.entity_id === entityId);
|
||||
if (ent && domain !== 'scene') ent.state = wasOn ? 'off' : 'on';
|
||||
}
|
||||
renderHATable(_haEntities);
|
||||
// Full sync after 4s — HA executes + agent pushes new state
|
||||
setTimeout(loadHA, 4000);
|
||||
} catch(e) {}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user