This commit is contained in:
Mateusz Gruszczyński
2026-09-04 11:43:37 +02:00
parent 9b4fafdfa6
commit ade221bb76
16 changed files with 338 additions and 40 deletions
+5 -1
View File
@@ -1,5 +1,5 @@
async function loadBootstrap(showMessage = false) {
if (app.loading) return;
if (app.loading) { app.bootstrapReloadPending = true; return; }
app.loading = true;
try {
const [data, sections] = await Promise.all([api('/api/bootstrap'), fetchSettingsSections()]);
@@ -28,6 +28,10 @@ async function loadBootstrap(showMessage = false) {
if (!String(error.message).toLowerCase().includes('token')) toast(error.message, true);
} finally {
app.loading = false;
if (app.bootstrapReloadPending) {
app.bootstrapReloadPending = false;
setTimeout(() => loadBootstrap(), 0);
}
}
}
+1 -1
View File
@@ -27,7 +27,7 @@ const preferredTheme = ['system', 'light', 'dark'].includes(getCookie('gree_cont
const app = {
devices: [], zones: [], groups: [], schedules: [], automations: [], flows: [], accessTokens: [], settings: null, system: {}, outdoorTemperature: null,
token: localStorage.getItem('gree_controller_token') || '', ws: null, wsTimer: null,
currentView: 'dashboard', loading: false, language: preferredLanguage, theme: preferredTheme, connectionStatus: 'connecting',
currentView: 'dashboard', loading: false, bootstrapReloadPending: false, language: preferredLanguage, theme: preferredTheme, connectionStatus: 'connecting',
languages: [], translations: {}, locales: {},
historyTab: 'overview', historyData: { zones: [], devices: [], sensors: [] }, historyCounts: {},
historyZone: 'all', historyDevice: 'all', historySensor: 'all', historyLoading: false,
+9 -2
View File
@@ -28,13 +28,20 @@ async function handleWebSocketMessage(event) {
}
const data = message.data || {};
if (message.event === 'control_plan.updated') { app.controlPlanPushReady = true; stopControlPlanFallback(); applyControlPlan(data.plan, data.revision); }
else if (['device.updated', 'device.created'].includes(message.event)) { updateDevice(data); renderSummary(); renderDevices(); renderGroups(); scheduleControlPlanLoad(); }
else if (message.event === 'device.updated') { updateDevice(data); renderSummary(); renderDevices(); renderGroups(); scheduleControlPlanLoad(); }
else if (message.event === 'device.created') { updateDevice(data); renderSummary(); renderDevices(); renderGroups(); fillSelects(); scheduleControlPlanLoad(); }
else if (message.event === 'device.deleted') { app.devices = app.devices.filter(v => v.id !== data.id); renderAll(); scheduleControlPlanLoad(); }
else if (message.event === 'devices.discovered') { (data.devices || []).forEach(updateDevice); renderAll(); scheduleControlPlanLoad(); }
else if (message.event === 'zone.updated') { const i = app.zones.findIndex(v => v.id === data.id); if (i >= 0) app.zones[i] = data; else app.zones.push(data); renderSummary(); renderHouseClimate(); renderZones(); renderDevices(); renderGroups(); scheduleControlPlanLoad(); }
else if (message.event === 'zone.created') { const i = app.zones.findIndex(v => v.id === data.id); if (i >= 0) app.zones[i] = data; else app.zones.push(data); renderSummary(); renderHouseClimate(); renderZones(); renderDevices(); renderGroups(); fillSelects(); scheduleControlPlanLoad(); }
else if (message.event === 'zone.deleted') { app.zones = app.zones.filter(v => v.id !== data.id); renderAll(); scheduleControlPlanLoad(); }
else if (['group.updated', 'group.created'].includes(message.event)) { const i = app.groups.findIndex(v => v.id === data.id); if (i >= 0) app.groups[i] = data; else app.groups.push(data); renderGroups(); fillSelects(); scheduleControlPlanLoad(); }
else if (message.event === 'group.deleted') { app.groups = app.groups.filter(v => v.id !== data.id); renderGroups(); fillSelects(); scheduleControlPlanLoad(); }
else if (['schedule.updated', 'schedule.created'].includes(message.event)) { const i = app.schedules.findIndex(v => v.id === data.id); if (i >= 0) app.schedules[i] = data; else app.schedules.push(data); renderSchedules(); fillSelects(); scheduleControlPlanLoad(); }
else if (message.event === 'schedule.deleted') { app.schedules = app.schedules.filter(v => v.id !== data.id); renderSchedules(); fillSelects(); scheduleControlPlanLoad(); }
else if (message.event === 'schedule.template_applied') { try { app.schedules = await api('/api/schedules'); renderSchedules(); fillSelects(); } catch (_) { } scheduleControlPlanLoad(); }
else if (['automation.updated', 'automation.created'].includes(message.event)) { const i = app.automations.findIndex(v => v.id === data.id); if (i >= 0) app.automations[i] = data; else app.automations.push(data); renderAutomations(); fillSelects(); scheduleControlPlanLoad(); }
else if (message.event === 'automation.deleted') { app.automations = app.automations.filter(v => v.id !== data.id); renderAutomations(); fillSelects(); scheduleControlPlanLoad(); }
else if (['flow.updated', 'flow.created'].includes(message.event)) { const i = app.flows.findIndex(v => v.id === data.id); if (i >= 0) app.flows[i] = data; else app.flows.push(data); renderFlows(); scheduleControlPlanLoad(); }
else if (message.event === 'flow.deleted') { app.flows = app.flows.filter(v => v.id !== data.id); renderFlows(); scheduleControlPlanLoad(); }
else if (message.event === 'settings.application.updated') { applySettingsSection('application', data); if (!isFormDirty($('#settingsForm'))) renderSettings(); renderSimulationModeBanner(); renderSystemInfo(); }
@@ -51,6 +58,7 @@ async function handleWebSocketMessage(event) {
}
else if (message.event === 'house.mode_changed') { app.settings = app.settings || {}; app.settings.house_mode = data.mode || 'cool'; renderHouseClimate(); renderGroups(); scheduleControlPlanLoad(); }
else if (message.event === 'outdoor.updated') { app.outdoorTemperature = Number.isFinite(Number(data.temperature)) ? Number(data.temperature) : null; renderHouseClimate(); scheduleControlPlanLoad(); }
else if (message.event === 'configuration.imported') { await loadBootstrap(); return; }
else if (message.event === 'gree.frame_received') {
app.system = app.system || {};
app.system.gree_received_frames = Number(data.total || 0);
@@ -62,7 +70,6 @@ async function handleWebSocketMessage(event) {
else if (message.event === 'gree.frame') { if (app.settings?.debug?.overlay_enabled) debugLine('GREE', `${data.direction || '?'} ${data.protocol_version || ''}`, data.device_name || data.device_id || data.target || '', message.timestamp, data.payload); }
else if (message.event === 'api.request') { if (app.settings?.debug?.overlay_enabled) debugLine('HTTP', `${data.method || '?'} ${data.status || ''}`, `${data.path || ''} · ${data.duration_ms ?? '?'} ms`, message.timestamp); }
else if (message.event === 'log.created') { if (app.settings?.debug?.overlay_enabled) debugLine('API', data.kind || data.level || 'log', data.message || '', message.timestamp, data.metadata); if (app.currentView === 'logs') loadLogs(); }
else if (message.event.startsWith('schedule.') || message.event.startsWith('automation.') || message.event.startsWith('flow.')) scheduleControlPlanLoad();
} catch (_) { }
}