diff --git a/BUILD_REPORT.md b/BUILD_REPORT.md index 998941e..dbed7b2 100644 --- a/BUILD_REPORT.md +++ b/BUILD_REPORT.md @@ -1,8 +1,8 @@ -# GREE Controller v0.6.2 - build and validation report +# GREE Controller v0.6.3 - build and validation report ## Scope -Version 0.6.2 includes the notification, reverse-proxy, mobile decimal-input, log filtering and thermostat-copy changes described below, plus a Rust type-safety hotfix for communication-failure notifications. +Version 0.6.3 includes the notification, reverse-proxy, mobile decimal-input, log filtering and thermostat-copy changes described below, the Rust type-safety hotfix for communication-failure notifications, and a clearer persistent visual state for the selected house climate mode. ## Implemented changes @@ -107,3 +107,10 @@ Validation performed in the build environment: - Copy-source choices exclude the currently edited zone. - Copying thermostat settings explicitly preserves the destination zone ID, name, assigned device, sensor strategy/entity and enabled state. - Zone updates use the independently tracked destination ID, preventing the source profile from being overwritten by a stale or mutated form ID. + + +## 0.6.3 house climate mode highlight + +- The selected whole-house climate mode (Cool / Heat / Off) now has a persistent illuminated border, accent fill and glowing status dot. +- The active mode is still derived from persisted `settings.house_mode`, so the highlight survives refreshes and reconnects. +- Mode buttons now expose `aria-pressed` for an explicit accessible selected state. diff --git a/Cargo.lock b/Cargo.lock index ae2fc64..767c87a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -633,7 +633,7 @@ dependencies = [ [[package]] name = "gree-controller" -version = "0.6.2" +version = "0.6.3" dependencies = [ "aes", "aes-gcm", diff --git a/Cargo.toml b/Cargo.toml index 345c59f..aaf5a83 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gree-controller" -version = "0.6.2" +version = "0.6.3" edition = "2021" authors = ["GREE Controller contributors"] description = "Standalone local GREE HVAC controller with Web UI, SQLite and Home Assistant sensor support" diff --git a/FILE_MANIFEST.sha256 b/FILE_MANIFEST.sha256 index c4b3370..c33b287 100644 --- a/FILE_MANIFEST.sha256 +++ b/FILE_MANIFEST.sha256 @@ -1,10 +1,10 @@ 623bd769512ef75f51e9bf7fb685d4d59ec84d7ccc75c826fe72c5538be737c5 ./.env.example a4ec3874a2e3ab1bad28fb40bb620f7b01f64d01ad9b699306bf70ada31227db ./.gitignore -2f89ebf1e9b0dfe837ee4efa6f436370dd28a08b603294ef3f20b869fdc44d8d ./BUILD_REPORT.md -13acfef8c5510afc206dc7bc590e76149d9e6dedc7414c3165e20653992d81b0 ./Cargo.lock -59edac9d91b203c2a65168afbcc81ff5fe6e95c05f9f4cbf9c6aa6fb9f8b6a48 ./Cargo.toml +afa44c1b588eddb83ad1300e62ef320bf0264ff05f19c53d42a761a8046c97b4 ./BUILD_REPORT.md +98bf4f4c86d8c6384ca55fac266f9ccae812680ebc6536063194e369669de627 ./Cargo.lock +0971917d970910ff09b0164a36e0c8f32b270ad3115a01a5bf4a53798c1e1854 ./Cargo.toml 19b2943504acb8f8de280f873a8dbec4bb6ebbe3870b158f5655d4fb8c298f5f ./LICENSE -62d29996813c32f86731a5e13635eaa41f698fdba8030ebb42259ce5588c5148 ./README.md +58471cab1a26e1212864a497e9e7b2730d849b7dd175dec7458a5a69dec1eadb ./README.md f2c8eb28fedb26bb8f5636e1805e7a782cc472b87d882f6752d520f16216a248 ./build.rs 674f8cf1ab9f1a49188e20b8e3977f1e2b7e9b8ef975315266730c44a55bbb48 ./docs/API.md 234dd200e380a13ecd3e61b4ea455f6f08d64ce89382077dee80684acadb9703 ./docs/HOME_ASSISTANT_MIGRATION.md @@ -23,7 +23,7 @@ b0314469ddb7c69ee4a96c677815af30cb97713e93911a05597f2fdc3d10f489 ./home-assista 5a96fe8f5c035c34f1339370270cd078056202d09e236dec75735be11de92a7d ./home-assistant/custom_components/gree_controller/entity_map.py c4fb75c246db651087900ebfc2291ff41ac87652cd6194fc0b776b0005c1cbcf ./home-assistant/custom_components/gree_controller/icon.png c4fb75c246db651087900ebfc2291ff41ac87652cd6194fc0b776b0005c1cbcf ./home-assistant/custom_components/gree_controller/logo.png -9d0b7de890d62245211e044801b00a6326f208aab1c016ec490b269afcb7c61b ./home-assistant/custom_components/gree_controller/manifest.json +a789da0f9f7178916227aa1a52575687090c8e82b463a53f1e16edb13f44599c ./home-assistant/custom_components/gree_controller/manifest.json d0206766d76f70ea1c75a618e41bf1e8e8c0429f42ee97f40daac1ea12f16658 ./home-assistant/custom_components/gree_controller/number.py 5c914c2faa18a9cb9eb442dc111c9416f89a630578f820beb021d5381aa1b2d0 ./home-assistant/custom_components/gree_controller/sensor.py 7c23374d1c82e4b361089386ff89265322b80def0f4db9d3fd2c039867033105 ./home-assistant/custom_components/gree_controller/switch.py @@ -61,10 +61,10 @@ a910bd9432a393740c0f6fab52bfcb551f0ea756718d66d290fd2610767cf07c ./src/protocol d1cba5e55c77d44c75a9c9897ae76c327fd96bdf9c01ad27e34322b689348487 ./src/queries.rs f74ac398c6f2e64ebb965900330324f3ec7403e70339638a408229f29fbd07ae ./src/state.rs b92a6cb158b494fe145b43c7641e65f6fafff47201d7d76edbec2cfd8b94835c ./systemd/gree-controller.service -ccb5bfc99a59e3b0530eea39beed95a56fdeffdd460d616ea64103647d292c55 ./web/app.js +c1bcdbbdf45d11aa87aebd82b8553316715e289845563f5af0e493e61243f19c ./web/app.js e98bdd7204349cce1ec6f57283509697af0bbc72280622a6c3efa6fed242db4f ./web/favicon.svg 002c172392a00006a5128fc4cb881b0361a2d3e76298dbd80c0a013f4e1f9dde ./web/index.html fd26156e9f1d6713d3def564ad000553d9a16a24376059701db2ee762c99ee6c ./web/manifest.webmanifest -ad68c73fc9e29c39c844a9cae38f7a50d96ad09020b81219b2a1f6daf3f635bc ./web/styles.css -639c2898baa081dda54216b5000de4e5449d7aec1acc4f45df846709edfb64c3 ./web/sw.js +80ea1c50c3729adb4dd392b12d73b4247659a8b6b948ee76bd2f5df213eae918 ./web/styles.css +b82ee4b915076be30211bc260a9bc33117e5b1890bde7f37ac45aa28d7a7cafe ./web/sw.js d505d793ce7cc9485b45b78bba1c0d51887adc7451ab59a42702946e5b991382 ./web/theme-init.js diff --git a/README.md b/README.md index cf62c98..9bf6be4 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Standalone local GREE air-conditioner controller written in Rust. It runs on a regular Linux host or an LXC container and provides a mobile-first web interface without depending on the vendor cloud. -Current version: **0.6.2**. +Current version: **0.6.3**. ## Highlights @@ -46,7 +46,7 @@ See [`BUILD_REPORT.md`](BUILD_REPORT.md) for package validation details and [`do On Debian, Ubuntu or an LXC container: ```bash -unzip gree-controller-v0.6.2.zip +unzip gree-controller-v0.6.3.zip cd gree-controller chmod +x scripts/*.sh ./scripts/dev.sh diff --git a/home-assistant/custom_components/gree_controller/manifest.json b/home-assistant/custom_components/gree_controller/manifest.json index 9bb7a0f..bf91c30 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.6.2", + "version": "0.6.3", "config_flow": true, "integration_type": "hub", "iot_class": "local_polling", diff --git a/web/app.js b/web/app.js index a64d4e4..4e4554b 100644 --- a/web/app.js +++ b/web/app.js @@ -249,9 +249,9 @@ function renderHouseClimate() { const outdoor = app.outdoorTemperature == null ? tr('common.unavailable') : fmtTemp(app.outdoorTemperature); node.innerHTML = `
${esc(tr('house.seasonMode'))}

${esc(tr('house.smartThermostat'))}

${esc(tr('house.setpointStrategy'))}

${esc(tr('house.outdoor'))}${esc(outdoor)}
- - - + + +
${['auto','comfort','sleep','away'].map(p=>``).join('')}
`; } diff --git a/web/styles.css b/web/styles.css index a5f02b6..126f27b 100644 --- a/web/styles.css +++ b/web/styles.css @@ -322,8 +322,10 @@ legend { padding: 0 5px; color: var(--muted); font-size: 11px; } .plan-house { border-color: color-mix(in srgb, var(--accent) 30%, var(--line)); } .plan-loading { grid-column: 1/-1; padding: 18px; color: var(--muted); } .house-mode-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; } -.house-mode-row button { min-height: 44px; color: var(--muted); background: var(--surface-muted); } -.house-mode-row button.active { color: var(--accent-text); background: var(--accent); font-weight: 800; } +.house-mode-row button { display: flex; align-items: center; justify-content: center; gap: 8px; min-height: 44px; border: 1px solid transparent; color: var(--muted); background: var(--surface-muted); } +.house-mode-row .mode-indicator { width: 8px; height: 8px; flex: 0 0 auto; border-radius: 50%; background: var(--muted-2); transition: background .15s ease, box-shadow .15s ease, transform .15s ease; } +.house-mode-row button.active { border-color: var(--accent); color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, var(--surface)); box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 22%, transparent), 0 0 18px color-mix(in srgb, var(--accent) 28%, transparent), inset 0 0 14px color-mix(in srgb, var(--accent) 8%, transparent); font-weight: 800; } +.house-mode-row button.active .mode-indicator { background: var(--accent); box-shadow: 0 0 4px var(--accent), 0 0 12px color-mix(in srgb, var(--accent) 82%, transparent); transform: scale(1.12); } .zone-thermostat { overflow: hidden; } .zone-thermostat.demanding { border-color: color-mix(in srgb, var(--accent) 38%, var(--line)); } @@ -613,7 +615,7 @@ html[data-theme='light'] .simulation-metrics > div, html[data-theme='light'] .si .device-capability-buttons button { min-height:34px; padding:7px 11px; border:1px solid var(--line); border-radius:11px; background:var(--surface-muted); color:var(--text); } .device-capability-buttons button.active { border-color:var(--accent); color:var(--accent); } -/* v0.6.2: compact, centered unit-feature controls */ +/* compact, centered unit-feature controls */ .device-capability-panel { justify-items:center; text-align:center; padding:11px 0 3px; } .device-capability-panel > small { text-align:center; } .device-capability-buttons { justify-content:center; align-items:center; gap:6px; max-width:100%; } diff --git a/web/sw.js b/web/sw.js index e974966..a42351a 100644 --- a/web/sw.js +++ b/web/sw.js @@ -1,4 +1,4 @@ -const CACHE = 'gree-controller-v062'; +const CACHE = 'gree-controller-v063'; const SCOPE = new URL(self.registration.scope).pathname.replace(/\/$/, ''); const path = value => `${SCOPE}${value.startsWith('/') ? value : `/${value}`}` || '/'; const ASSETS = [path('/'), path('/styles.css'), path('/app.js'), path('/theme-init.js'), path('/favicon.svg'), path('/manifest.webmanifest'), path('/lang/index.json'), path('/lang/en.json')];