This commit is contained in:
Mateusz Gruszczyński
2026-09-01 11:36:11 +02:00
parent 3e3f8c3f19
commit 6207bc4de6
9 changed files with 29 additions and 20 deletions
Generated
+1 -1
View File
@@ -633,7 +633,7 @@ dependencies = [
[[package]]
name = "gree-controller"
version = "0.8.21"
version = "0.8.22"
dependencies = [
"aes",
"aes-gcm",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "gree-controller"
version = "0.8.21"
version = "0.8.22"
edition = "2021"
authors = ["GREE Controller contributors"]
description = "Standalone local GREE HVAC controller with Web UI, SQLite and Home Assistant sensor support"
+8 -8
View File
@@ -1,11 +1,11 @@
d67af429e4da9ce08e9d2f2a8472849ffbd70d135b1c5da535a076026794d04c ./.env.example
a4ec3874a2e3ab1bad28fb40bb620f7b01f64d01ad9b699306bf70ada31227db ./.gitignore
630d1a19741908e389efefb4b2db81c089c84203024c7baf0ea94754a7da2a2c ./Cargo.lock
96e7395b59b0e6e8e7b0fd4311d33dcbb2910c756a7f3301299e92fa155b20dc ./Cargo.toml
0571baaa38d6affcd32de5842628a53e0207795a1bb11abceded67ddaf4fbc89 ./Cargo.lock
a746338d1f28b0b6ca4118cdf0bedf5d6e68a5539d2e52b48387763899d96118 ./Cargo.toml
19b2943504acb8f8de280f873a8dbec4bb6ebbe3870b158f5655d4fb8c298f5f ./LICENSE
1af97e3a6eec1efa2c91f147dee689beeb33cc7efab0703c91753e056441f1aa ./README.md
f07790d52e9eb7cc9148093c44b3755341dcdfadfe2552457f0fb902ea226f5e ./README.md
ec0f495ee6a618bdec10b260ee7838f7a872d8c5b0aa91c546226c1ad818f601 ./build.rs
0c47e3dbaf24ab2d7c05a55f22ab2e3c38146acf9864083ffa5b92f453f5735e ./docs/API.md
4f0cd0c69d168e0c17ec85c9326bf2b105cb82b7fc1dfd20c5f27de9f9e7b6a9 ./docs/API.md
95e3c8c99ba439a86a2fb05cfd8ef00c75cb959a024a349a082da935b726f500 ./home-assistant/README.md
f8e8559fe10fe523ac5bc9aac25c6e26e862f679d502e8f3c39f38a0a8e40911 ./home-assistant/custom_components/gree_controller/__init__.py
6910589f27960a28d4de9735884a7e5376e455cd885f19ce2b55947fcd135114 ./home-assistant/custom_components/gree_controller/api.py
@@ -16,7 +16,7 @@ ab08fbe40e9bb48ebcbfff98760aaa0c9434b61b705aaaadea0c09c255d99b0e ./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
99d34f75475a352410525dd395cc563160d8f8d2f85e22f8287a5c2f5b36062d ./home-assistant/custom_components/gree_controller/manifest.json
d55689391ec02289dfffb622c18d8bc6423df192c267959395751d634ebe3358 ./home-assistant/custom_components/gree_controller/manifest.json
38d659d0273c0d1428679e44574a2666c605d1b3796d323b626baa40560788cf ./home-assistant/custom_components/gree_controller/number.py
39c4309001b75abb56234f05662bc06e077054986876f1927937edbce528ec95 ./home-assistant/custom_components/gree_controller/select.py
1cae12876eb81085910907cf1fcf340a18dcba4f8c967ef222c9496325057849 ./home-assistant/custom_components/gree_controller/sensor.py
@@ -131,7 +131,7 @@ e98bdd7204349cce1ec6f57283509697af0bbc72280622a6c3efa6fed242db4f ./web/favicon.
9ba3f6fa05b72aa989139b2a909982571b2a02055052e4c40104f1e81a9aa7eb ./web/js/README.md
b3d5cb473bf9771de78e14c7de730cb86c73f8cdbb6344da67ba7d6abac879ea ./web/js/bootstrap.js
64a43e2142a69ebddf4160c0d0d3b573fa379c650431090fd15c9ba3b62bc4e7 ./web/js/charts.js
82da7a69028e159ef9b72ba32b111916e9dc21618f8c7c0e410e3492773e7c12 ./web/js/core.js
cf8d97770985b8cf920382725fa33d5f61497a639544bfc528af72b276de0b6a ./web/js/core.js
6e421388c7f6deb2aa42f1205dfdc52839f9f178fbd672129972528b8517a870 ./web/js/dashboard.js
7ed64ca0ef62c4cd3d9c314adfcf1c3874a0c49139379dd6f175710786a2ced9 ./web/js/entities.js
8c94a3b4aa5455638332362379b09dc151cdf47ab24774c9fd52100ecad689c5 ./web/js/events.js
@@ -144,6 +144,6 @@ d375868ded6ffcd6b18d4c661bb2051e7cc5b136f95d4d68355cdd6e0caaf278 ./web/js/realt
28ff1324f4495b7bcd431eb94f51012c1b1e558f8acb931ac35b71b48374c200 ./web/js/settings-ui.js
9d44596929f67400f5f09d82330af4452914f2b4729eadcd4f695672d2cd849c ./web/js/settings.js
fd26156e9f1d6713d3def564ad000553d9a16a24376059701db2ee762c99ee6c ./web/manifest.webmanifest
e97553a992815ba49830514b0f1eb4d686f2097889574e9da6741af90b7ab5eb ./web/styles.css
03ac3a5918539904ae829ee24999d8d59efb41bdf6c0e30f76bab4cee98c3130 ./web/sw.js
32898e4562f8e7e70a20f95d2eecde235f4ecb1799b515f57e55579b0d4fd604 ./web/styles.css
bc95830ec8273818ffde0a6b50eb3cc9ecbeee65a7a1d3aeff08cde86d05dc7b ./web/sw.js
d505d793ce7cc9485b45b78bba1c0d51887adc7451ab59a42702946e5b991382 ./web/theme-init.js
+1 -1
View File
@@ -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.8.21**
**Current release: 0.8.22**
> [Full API reference](docs/API.md) — authentication, every endpoint, request bodies, response models, WebSocket events and examples.
+3 -3
View File
@@ -1,6 +1,6 @@
# GREE Controller API reference
HTTP and WebSocket API for GREE Controller **0.8.21**.
HTTP and WebSocket API for GREE Controller **0.8.22**.
[← Main documentation](../README.md)
@@ -212,7 +212,7 @@ Response:
{
"status": "ok",
"name": "gree-controller",
"version": "0.8.21",
"version": "0.8.22",
"uptime_seconds": 1234,
"control_ready": true,
"time": "2026-08-30T06:54:00Z"
@@ -236,7 +236,7 @@ Returns the initial Web UI snapshot:
"settings": {},
"outdoor_temperature": null,
"system": {
"version": "0.8.21",
"version": "0.8.22",
"uptime_seconds": 1234,
"auth_required": false,
"control_ready": true,
@@ -1,7 +1,7 @@
{
"domain": "gree_controller",
"name": "GREE Controller",
"version": "0.8.21",
"version": "0.8.22",
"config_flow": true,
"integration_type": "hub",
"iot_class": "local_polling",
+9 -2
View File
@@ -262,14 +262,21 @@ function renderLanguageOptions() {
async function loadLanguages() {
try {
const response = await fetch(withBase('/lang/index.json'), {cache: 'no-cache'});
// Language packs must never come from a stale Service Worker/browser cache.
// A cache-busting nonce is intentional: translations can change without the JS asset hash changing.
const languageNonce = Date.now().toString(36);
const languageUrl = path => {
const separator = String(path).includes('?') ? '&' : '?';
return `${withBase(path)}${separator}v=${languageNonce}`;
};
const response = await fetch(languageUrl('/lang/index.json'), {cache: 'no-store'});
if (!response.ok) throw new Error(`Language index HTTP ${response.status}`);
const manifest = await response.json();
const languages = Array.isArray(manifest.languages) ? manifest.languages : [];
if (!languages.some(item => item.code === DEFAULT_LANGUAGE)) throw new Error('Default English language pack is missing');
const loaded = await Promise.all(languages.map(async item => {
const packResponse = await fetch(withBase(item.path || `/lang/${encodeURIComponent(item.code)}.json`), {cache: 'no-cache'});
const packResponse = await fetch(languageUrl(item.path || `/lang/${encodeURIComponent(item.code)}.json`), {cache: 'no-store'});
if (!packResponse.ok) throw new Error(`Language ${item.code} HTTP ${packResponse.status}`);
const pack = await packResponse.json();
return {item, pack};
+1 -1
View File
@@ -1386,7 +1386,7 @@ textarea[aria-invalid="true"] {
.group-custom-temperature-row button { grid-column:auto; }
}
/* v0.8.21: make group gates visually unambiguous. */
/* v0.8.22: make group gates visually unambiguous. */
.list-card.group-card.group-linked {
border-color:color-mix(in srgb,var(--group-control-color) 42%,var(--line));
}
+4 -2
View File
@@ -1,12 +1,14 @@
const CACHE = 'gree-controller-__GREE_ASSET_CACHE__';
const SCOPE = new URL(self.registration.scope).pathname.replace(/\/$/, '');
const path = value => `${SCOPE}${value.startsWith('/') ? value : `/${value}`}` || '/';
const ASSETS = [path('__GREE_STYLES_ASSET__'), path('__GREE_APP_ASSET__'), path('__GREE_THEME_INIT_ASSET__'), path('/favicon.svg'), path('/manifest.webmanifest'), path('/lang/index.json'), path('/lang/en.json'), path('/lang/pl.json')];
const ASSETS = [path('__GREE_STYLES_ASSET__'), path('__GREE_APP_ASSET__'), path('__GREE_THEME_INIT_ASSET__'), path('/favicon.svg'), path('/manifest.webmanifest')];
self.addEventListener('install', event => event.waitUntil(caches.open(CACHE).then(cache => cache.addAll(ASSETS)).then(() => self.skipWaiting())));
self.addEventListener('activate', event => event.waitUntil(caches.keys().then(keys => Promise.all(keys.filter(key => key !== CACHE).map(key => caches.delete(key)))).then(() => self.clients.claim())));
self.addEventListener('fetch', event => {
const url = new URL(event.request.url);
if (event.request.method !== 'GET' || url.pathname.startsWith(path('/api/')) || event.request.mode === 'navigate') return;
// API and language packs stay network-owned. Language JSON is deliberately not
// cache-first so a newly deployed translation can never be masked by an old pack.
if (event.request.method !== 'GET' || url.pathname.startsWith(path('/api/')) || url.pathname.startsWith(path('/lang/')) || event.request.mode === 'navigate') return;
event.respondWith(caches.match(event.request).then(cached => cached || fetch(event.request).then(response => {
const copy = response.clone(); caches.open(CACHE).then(cache => cache.put(event.request, copy)); return response;
})));