This commit is contained in:
Mateusz Gruszczyński
2026-09-16 14:24:40 +02:00
parent d0ae3d0f6a
commit 3f9acb1675
28 changed files with 726 additions and 127 deletions
+55 -6
View File
@@ -146,6 +146,7 @@ function homeAssistantSettingsBodyFromForm(form) {
outdoor_entity_id: raw.ha_outdoor_entity_id,
sensor_stale_after_seconds: Math.max(60, Math.min(86400, Math.round(Number(raw.ha_sensor_stale_after_minutes || 5) * 60))),
allow_invalid_tls: form.ha_allow_invalid_tls.checked,
manual_auth_override: form.dataset.haManualOverride === 'true',
sensor_aliases: { ...(app.sensorAliases || {}) },
flow_inputs: JSON.parse(JSON.stringify(app.flowSharedInputs || [])),
outdoor_assist_enabled: form.outdoor_assist_enabled.checked,
@@ -200,6 +201,7 @@ async function saveHomeAssistantSettings(form, notify = true) {
applySettingsSection('homeAssistant', data);
app.sensorAliases = { ...(data.sensor_aliases || {}) };
app.flowSharedInputs = JSON.parse(JSON.stringify(data.flow_inputs || []));
app.haEntityCatalogLoadedAt = 0;
refreshSettingsUi();
if (notify) toast(tr('common.saved'));
}
@@ -280,19 +282,66 @@ $('#copyAccessToken').addEventListener('click', async () => {
}
});
function homeAssistantTestToast(result) {
const sample = result?.sample;
if (!sample?.entity_id) return tr('toast.haConnected');
const value = `${sample.state ?? '—'}${sample.unit ? ` ${sample.unit}` : ''}`;
const label = sample.name ? `${sample.name} (${sample.entity_id})` : sample.entity_id;
return tr('toast.haConnectedSample', { entity: label, value });
}
$('#haTest').addEventListener('click', async event => {
const form = $('#homeAssistantForm'), button = event.currentTarget;
if (!validateForm(form)) return;
clearFormErrors(form);
const ha = app.settings?.home_assistant || {};
const supervisorAuto = ha.supervisor_detected === true && form.dataset.haManualOverride !== 'true';
if (!supervisorAuto && !validateForm(form)) return;
button.disabled = true;
const idle = button.textContent;
button.textContent = tr('settings.testingHa');
try {
await saveHomeAssistantSettings(form, false);
await api('/api/integrations/home-assistant/test', { method: 'POST' });
if (!supervisorAuto) await saveHomeAssistantSettings(form, false);
const result = await api('/api/integrations/home-assistant/test', { method: 'POST' });
app.haSupervisorTestState = { ok: true, sample: result.sample || null };
if (app.settings?.home_assistant?.supervisor_detected && app.settings.home_assistant.auth_mode === 'supervisor') {
app.haManualFallbackVisible = false;
}
app.haEntityCatalogLoadedAt = 0;
renderHomeAssistantAuthState();
markFormClean(form);
toast(tr('toast.haConnected'));
} catch (error) { presentFormError(form, error); }
finally { button.disabled = false; button.textContent = idle; }
toast(homeAssistantTestToast(result));
} catch (error) {
if (supervisorAuto) {
app.haSupervisorTestState = { ok: false, message: error.message };
app.haManualFallbackVisible = true;
renderHomeAssistantAuthState();
toast(`${tr('settings.haSupervisorTestFailedTitle')}: ${error.message}`, true);
} else {
presentFormError(form, error);
}
} finally { button.disabled = false; button.textContent = idle; }
});
$('#haUseSupervisor')?.addEventListener('click', async event => {
const form = $('#homeAssistantForm'), button = event.currentTarget;
const idle = button.textContent;
button.disabled = true;
clearFormErrors(form);
try {
app.haManualFallbackVisible = false;
form.dataset.haManualOverride = 'false';
await saveHomeAssistantSettings(form, false);
const result = await api('/api/integrations/home-assistant/test', { method: 'POST' });
app.haSupervisorTestState = { ok: true, sample: result.sample || null };
app.haEntityCatalogLoadedAt = 0;
renderHomeAssistantSettings();
toast(homeAssistantTestToast(result));
} catch (error) {
app.haManualFallbackVisible = true;
app.haSupervisorTestState = { ok: false, message: error.message };
renderHomeAssistantAuthState();
toast(`${tr('settings.haSupervisorTestFailedTitle')}: ${error.message}`, true);
} finally { button.disabled = false; button.textContent = idle; }
});
$('#exportSettings').addEventListener('click', async () => {