v0.14.2-hotfix

This commit is contained in:
Mateusz Gruszczyński
2026-09-15 10:14:01 +02:00
parent c3f6e773f8
commit 7ffaba6c7a
12 changed files with 103 additions and 35 deletions
+15 -5
View File
@@ -720,7 +720,7 @@
</div>
</div>
<div class="settings-grid">
<label class="check wide"><input type="checkbox" name="ping_metrics_enabled"> <span data-i18n="settings.connectivityEnable">Enable local connectivity metrics</span></label>
<label class="check wide"><input type="checkbox" name="ping_metrics_enabled"> <span data-i18n="settings.connectivityEnable">Enable local unit ping measurements</span></label>
<label><span data-i18n="settings.connectivityInterval">Measurement interval (s)</span><input type="number" name="ping_interval_seconds" min="10" max="3600" value="60"></label>
<label><span data-i18n="settings.connectivitySamples">Samples per measurement</span><input type="number" name="ping_sample_count" min="1" max="10" value="3"></label>
<p class="field-note wide" data-i18n="settings.connectivityLocalOnly">Only Local/LAN installations are probed. Cloud devices are not pinged directly.</p>
@@ -766,10 +766,6 @@
<option>Australia</option><option>China Mainland</option><option>East South Asia</option><option selected>Europe</option><option>India</option><option>Latin American</option><option>Middle East</option><option>North American</option><option>Russia</option><option>South American</option>
</select></label>
<label><span data-i18n="settings.cloudPolling">Cloud fallback polling interval (s)</span><input type="number" name="gree_cloud_polling_interval_seconds" min="30" max="3600" value="60"></label>
<label class="check wide"><input type="checkbox" name="gree_cloud_connectivity_metrics_enabled"> <span data-i18n="settings.cloudConnectivityEnable">Measure Cloud REST/MQTT connectivity</span></label>
<label><span data-i18n="settings.connectivityInterval">Measurement interval (s)</span><input type="number" name="gree_cloud_connectivity_metrics_interval_seconds" min="30" max="3600" value="300"></label>
<label><span data-i18n="settings.connectivitySamples">Samples per measurement</span><input type="number" name="gree_cloud_connectivity_metrics_sample_count" min="1" max="10" value="3"></label>
<p class="field-note wide" data-i18n="settings.cloudConnectivityHint">Optional. Disabled by default. Measures REST login response and MQTT PINGRESP round-trip.</p>
<label class="wide"><span data-i18n="settings.cloudLogin">Login / email</span><input name="gree_cloud_username" autocomplete="username"></label>
<label class="wide"><span data-i18n="settings.cloudPassword">Password</span><input type="password" name="gree_cloud_password" autocomplete="new-password" data-i18n-placeholder="settings.cloudPasswordPlaceholder" placeholder="Leave empty to keep saved secret"></label>
<div class="wide cloud-runtime-summary" aria-live="polite" hidden>
@@ -793,6 +789,20 @@
<div id="greeCloudTestResult" class="inline-alert wide" hidden></div>
</div>
</section>
<section class="panel settings-block">
<div class="settings-block-head">
<div>
<h3 data-i18n="settings.cloudConnectivityTitle">Cloud connectivity metrics</h3>
<p data-i18n="settings.cloudConnectivityHint">Optional. Disabled by default. Measures REST login response and MQTT PINGRESP round-trip.</p>
</div>
</div>
<div class="settings-grid">
<label class="check wide"><input type="checkbox" name="gree_cloud_connectivity_metrics_enabled"> <span data-i18n="settings.cloudConnectivityEnable">Measure Cloud REST/MQTT connectivity</span></label>
<label><span data-i18n="settings.connectivityInterval">Measurement interval (s)</span><input type="number" name="gree_cloud_connectivity_metrics_interval_seconds" min="30" max="3600" value="300"></label>
<label><span data-i18n="settings.connectivitySamples">Samples per measurement</span><input type="number" name="gree_cloud_connectivity_metrics_sample_count" min="1" max="10" value="3"></label>
<p class="field-note wide" data-i18n="settings.cloudConnectivityHistoryHint">REST and MQTT measurements are stored in History → Pings together with Local/LAN measurements.</p>
</div>
</section>
</div>
<div class="settings-save-bar"><span data-i18n="settings.saveHint">Save changes made in the blocks
above.</span><button class="primary" type="submit" data-i18n="actions.save">Save</button></div>
+3 -2
View File
@@ -109,7 +109,8 @@ function renderHistoryNavigation() {
} else if (app.historyTab === 'network') {
const targets = app.historyNetworkTargets || [];
const targetOptions = targets.map(target => `<option value="${esc(target.id)}">${esc(target.name)}</option>`).join('');
host.innerHTML = `<label><span>${esc(tr('history.networkTarget'))}</span><select id="historyNetworkSelect"><option value="all">${esc(tr('history.allNetworkTargets'))}</option>${targetOptions}</select></label>`;
const jitterEnabled = app.historyNetworkShowJitter !== false;
host.innerHTML = `<div class="history-network-controls"><label><span>${esc(tr('history.networkTarget'))}</span><select id="historyNetworkSelect"><option value="all">${esc(tr('history.allNetworkTargets'))}</option>${targetOptions}</select></label><button type="button" class="secondary history-jitter-toggle${jitterEnabled ? ' active' : ''}" data-action="toggle-network-jitter" aria-pressed="${jitterEnabled ? 'true' : 'false'}" title="${esc(tr('history.networkJitterToggleHint'))}">${esc(tr(jitterEnabled ? 'history.networkJitterOn' : 'history.networkJitterOff'))}</button></div>`;
const select = $('#historyNetworkSelect'); if ([...select.options].some(option => option.value === app.historyNetworkTarget)) select.value = app.historyNetworkTarget;
} else if (app.historyTab === 'sensors') {
host.innerHTML = `<label><span>${esc(tr('history.haSensor'))}</span><select id="historySensorSelect"><option value="all">${esc(tr('history.allSensors'))}</option>${options.sensors}</select></label>`;
@@ -650,7 +651,7 @@ function renderLegend(host, series) {
host.innerHTML = series.map((item, index) => {
const hidden = isChartSeriesHidden(chartId, item, index);
const title = tr(hidden ? 'history.legendShow' : 'history.legendHide', { name: item.label });
return `<button type="button" class="legend-item${hidden ? ' is-hidden' : ''}" data-chart-id="${esc(chartId)}" data-chart-legend="${index}" aria-pressed="${hidden ? 'false' : 'true'}" title="${esc(title)}"><i class="legend-line" style="--legend-color:${esc(item.color)}"></i><span>${esc(item.label)}</span></button>`;
return `<button type="button" class="legend-item${hidden ? ' is-hidden' : ''}" data-chart-id="${esc(chartId)}" data-chart-legend="${index}" aria-pressed="${hidden ? 'false' : 'true'}" title="${esc(title)}"><i class="legend-line${item.dash?.length ? ' is-dashed' : ''}" style="--legend-color:${esc(item.color)}"></i><span>${esc(item.label)}</span></button>`;
}).join('');
}
+1 -1
View File
@@ -30,7 +30,7 @@ const app = {
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', historyNetworkTarget: 'all', historyNetwork: [], historyNetworkTargets: [], historyEnergyDevice: '', historyEnergyTargets: [], historyEnergyInterval: 'daily', historyEnergyCompare: 'none', historyEnergy: [], historyLoading: false, historyReloadPending: false,
historyZone: 'all', historyDevice: 'all', historySensor: 'all', historyNetworkTarget: 'all', historyNetworkShowJitter: true, historyNetwork: [], historyNetworkTargets: [], historyEnergyDevice: '', historyEnergyTargets: [], historyEnergyInterval: 'daily', historyEnergyCompare: 'none', historyEnergy: [], historyLoading: false, historyReloadPending: false,
customChartSeries: [], savedCharts: [], chartZooms: {}, chartHiddenSeries: {}, zoneControlSeq: {}, groupControlSeq: {}, zoneControlQueue: {}, groupControlQueue: {}, deviceControlQueue: {}, houseControlQueue: null, climateControlQueue: null, groupCustomDrafts: {}, zoneTemperatureTimers: {}, deviceTemperatureDrafts: {},
controlPlan: null, controlPlanRevision: null, controlPlanPushReady: false, controlPlanTimer: null, debugLines: [], debugBacklogLoaded: false, debugFilter: 'all', sensorAliases: {}, flowSharedInputs: [], flowSharedInputValueCache: {}, flowSharedInputValueRequests: {}, flowSharedInputValueTimer: null,
simulationScope: 'units', simulationTarget: 'all', standaloneSimulation: false, dashboardTab: 'main', settingsTab: 'app', systemSnapshotAt: Date.now(),
+3
View File
@@ -99,6 +99,7 @@ document.addEventListener('click', async event => {
return;
}
const device = app.devices.find(v => v.id === button.dataset.device);
if (action === 'toggle-network-jitter') { app.historyNetworkShowJitter = app.historyNetworkShowJitter === false; renderHistoryNavigation(); renderNetworkHistory(); return; }
if (action === 'open-ping' && device) { openDevicePing(device.id); return; }
if (action === 'ping-toggle') { if (app.pingMonitor.running) stopPingMonitor(); else startPingMonitor(); return; }
if (action === 'power' && device) return sendDeviceCommand(device.id, current => ({ power: !current?.power }));
@@ -253,6 +254,8 @@ $('#themeSelect')?.addEventListener('change', event => setTheme(event.target.val
$('#logLevelFilter')?.addEventListener('change', loadLogs); $('#logCategoryFilter')?.addEventListener('change', loadLogs);
$('#settingsForm [name=notifications_provider]')?.addEventListener('change', updateNotificationFields);
$('#settingsForm [name=compressor_protection_enabled]')?.addEventListener('change', updateCompressorProtectionFields);
$('#settingsForm [name=ping_metrics_enabled]')?.addEventListener('change', updateConnectivityMetricFields);
$('#settingsForm [name=gree_cloud_connectivity_metrics_enabled]')?.addEventListener('change', updateConnectivityMetricFields);
$('#zoneForm [name=sensor_source]').addEventListener('change', updateZoneSensorFields);
document.addEventListener('input', event => {
const input = event.target.closest?.('[data-group-custom-temperature]');
+2 -2
View File
@@ -156,8 +156,8 @@ function renderNetworkHistory() {
value: row => row.target_id === id ? historyNumber(row.latency_ms) : NaN,
tooltipValue: value => `${Number(value).toLocaleString(locale(), { maximumFractionDigits: 2 })} ms`,
});
latencySeries.push({
key: `${id}:jitter`, label: `${label} · ${tr('history.networkJitter')}`, color, dash: [5, 4],
if (app.historyNetworkShowJitter !== false) latencySeries.push({
key: `${id}:jitter`, label: `${label} · ${tr('history.networkJitter')}`, color, dash: [7, 5],
value: row => row.target_id === id ? historyNumber(row.jitter_ms) : NaN,
tooltipValue: value => `${Number(value).toLocaleString(locale(), { maximumFractionDigits: 2 })} ms`,
});
+13
View File
@@ -164,6 +164,18 @@ function renderLogRetention() {
select.value = days;
}
function updateConnectivityMetricFields() {
const form = $('#settingsForm');
if (!form) return;
const localEnabled = !!form.ping_metrics_enabled?.checked;
if (form.ping_interval_seconds) form.ping_interval_seconds.disabled = !localEnabled;
if (form.ping_sample_count) form.ping_sample_count.disabled = !localEnabled;
const cloudEnabled = !!form.gree_cloud_connectivity_metrics_enabled?.checked;
if (form.gree_cloud_connectivity_metrics_interval_seconds) form.gree_cloud_connectivity_metrics_interval_seconds.disabled = !cloudEnabled;
if (form.gree_cloud_connectivity_metrics_sample_count) form.gree_cloud_connectivity_metrics_sample_count.disabled = !cloudEnabled;
}
function renderSettings() {
if (!app.settings) return;
const form = $('#settingsForm');
@@ -191,6 +203,7 @@ function renderSettings() {
form.gree_cloud_connectivity_metrics_enabled.checked = !!cloud.connectivity_metrics_enabled;
form.gree_cloud_connectivity_metrics_interval_seconds.value = Number(cloud.connectivity_metrics_interval_seconds || 300);
form.gree_cloud_connectivity_metrics_sample_count.value = Number(cloud.connectivity_metrics_sample_count || 3);
updateConnectivityMetricFields();
const cloudInstance = $('#greeCloudInstanceId');
if (cloudInstance) cloudInstance.textContent = cloud.installation_id || '—';
const cloudLastContact = $('#greeCloudLastContact');
+30
View File
@@ -2040,6 +2040,11 @@ legend {
background: var(--legend-color, var(--accent));
}
.legend-line.is-dashed {
background: repeating-linear-gradient(90deg, var(--legend-color, var(--accent)) 0 7px, transparent 7px 12px);
}
@media (max-width: 620px) {
.history-summary {
grid-template-columns: repeat(2, minmax(0, 1fr));
@@ -2799,6 +2804,26 @@ legend {
width: 100%;
}
.history-network-controls {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: 10px;
align-items: end;
}
.history-network-controls label { min-width: 0; }
.history-jitter-toggle {
min-height: 45px;
white-space: nowrap;
}
.history-jitter-toggle.active {
color: var(--accent-text);
border-color: var(--accent);
background: var(--accent);
}
.history-range-control {
display: grid;
gap: 7px;
@@ -9613,3 +9638,8 @@ body.flow-editor-open {
.history-energy-options { width: min(420px, calc(100vw - 40px)); max-height: 46vh; }
}
@media (max-width: 640px) {
.history-network-controls { grid-template-columns: 1fr; }
.history-jitter-toggle { width: 100%; }
}