From 8180d22cef9d1fd9fb300393c9e705e2d66c5175 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Gruszczy=C5=84ski?= Date: Wed, 2 Sep 2026 09:27:24 +0200 Subject: [PATCH] v0.9.14 --- Cargo.lock | 2 +- Cargo.toml | 2 +- README.md | 2 +- docs/API.md | 6 +++--- .../custom_components/gree_controller/manifest.json | 2 +- web/index.html | 5 ++--- web/js/settings.js | 13 +++++++------ 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 874f6ac..ad32905 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -633,7 +633,7 @@ dependencies = [ [[package]] name = "gree-controller" -version = "0.9.13" +version = "0.9.14" dependencies = [ "aes", "aes-gcm", diff --git a/Cargo.toml b/Cargo.toml index 774f4d0..170ac5f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gree-controller" -version = "0.9.13" +version = "0.9.14" edition = "2021" authors = ["GREE Controller contributors"] description = "Standalone local GREE HVAC controller with Web UI, SQLite and Home Assistant sensor support" diff --git a/README.md b/README.md index 30db1f2..6d5d2f4 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Self-hosted controller for GREE-compatible air conditioners with a local Web UI, thermostat zones, schedules, Home Assistant integration, history, notifications and a documented HTTP/WebSocket API. -**Current release: 0.9.13** +**Current release: 0.9.14** > [Full API reference](docs/API.md) — authentication, every endpoint, request bodies, response models, WebSocket events and examples. diff --git a/docs/API.md b/docs/API.md index c4b434c..d83485c 100644 --- a/docs/API.md +++ b/docs/API.md @@ -1,6 +1,6 @@ # GREE Controller API reference -HTTP and WebSocket API for GREE Controller **0.9.13**. +HTTP and WebSocket API for GREE Controller **0.9.14**. [← Main documentation](../README.md) @@ -213,7 +213,7 @@ Response: { "status": "ok", "name": "gree-controller", - "version": "0.9.13", + "version": "0.9.14", "uptime_seconds": 1234, "control_ready": true, "time": "2026-08-30T06:54:00Z" @@ -237,7 +237,7 @@ Returns the initial Web UI snapshot: "settings": {}, "outdoor_temperature": null, "system": { - "version": "0.9.13", + "version": "0.9.14", "uptime_seconds": 1234, "auth_required": false, "control_ready": true, diff --git a/home-assistant/custom_components/gree_controller/manifest.json b/home-assistant/custom_components/gree_controller/manifest.json index 5b532c5..95e4c97 100644 --- a/home-assistant/custom_components/gree_controller/manifest.json +++ b/home-assistant/custom_components/gree_controller/manifest.json @@ -1,7 +1,7 @@ { "domain": "gree_controller", "name": "GREE Controller", - "version": "0.9.13", + "version": "0.9.14", "config_flow": true, "integration_type": "hub", "iot_class": "local_polling", diff --git a/web/index.html b/web/index.html index 5d942c9..6477d9b 100644 --- a/web/index.html +++ b/web/index.html @@ -243,8 +243,7 @@
+ id="simulationFullscreen" data-i18n="simulation.fullscreen">Full screen

Live preview of the thermostat and automation logic. The flow board shows how sensor readings, schedules, night mode and thermostat decisions become commands sent to each @@ -731,7 +730,7 @@

diff --git a/web/js/settings.js b/web/js/settings.js index b3d343a..1890e78 100644 --- a/web/js/settings.js +++ b/web/js/settings.js @@ -255,11 +255,6 @@ $('#haTest').addEventListener('click', async event => { finally { button.disabled = false; button.textContent = idle; } }); -$('#simulationRefresh')?.addEventListener('click', async () => { - try { await loadControlPlan(); toast(tr('common.updated')); } - catch (error) { toast(error.message, true); } -}); - $('#exportSettings').addEventListener('click', async () => { try { const data = await api('/api/settings/export'); @@ -327,7 +322,13 @@ $('#flowSharedInputTest')?.addEventListener('click', async event => { if (!form || !resultHost) return; const kind = form.kind.value, config = collectFlowSharedInputConfig(kind); const entityId = String(config.entity_id || '').trim(); - if (!entityId) return toast(tr('flow.sharedInputTestEntityRequired'), true); + if (!entityId) { + resultHost.hidden = false; + resultHost.classList.remove('pass'); + resultHost.classList.add('fail'); + resultHost.innerHTML = `${esc(tr('flow.sharedInputTestUnavailable'))}${esc(tr('flow.sharedInputTestEntityRequired'))}`; + return; + } const button = event.currentTarget, idle = button.textContent; button.disabled = true; button.textContent = tr('flow.sharedInputTesting'); resultHost.hidden = false; resultHost.innerHTML = `${esc(tr('flow.sharedInputTesting'))}`;