From 63e6e13a5d0ed7ef23f2d8c8b64b5874a1088c71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Gruszczy=C5=84ski?= Date: Fri, 4 Sep 2026 13:44:18 +0200 Subject: [PATCH] v0.13.6 --- Cargo.lock | 2 +- Cargo.toml | 2 +- FILE_MANIFEST.sha256 | 61 +++++++++---------- README.md | 4 +- docs/API.md | 11 ++-- docs/openapi.json | 11 +++- .../gree_controller/manifest.json | 2 +- lang/en.json | 3 +- lang/pl.json | 3 +- scripts/api_dev_test.py | 8 +-- src/models/integrations.rs | 6 +- src/notifications.rs | 23 ++++++- web/index.html | 2 + web/js/events.js | 2 +- web/js/settings-ui.js | 1 + web/js/settings.js | 1 + 16 files changed, 89 insertions(+), 53 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9e40a89..1ebdeac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -700,7 +700,7 @@ dependencies = [ [[package]] name = "gree-controller" -version = "0.13.5" +version = "0.13.6" dependencies = [ "aes", "aes-gcm", diff --git a/Cargo.toml b/Cargo.toml index bdd9bd6..0afeacf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gree-controller" -version = "0.13.5" +version = "0.13.6" 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 0d13fa9..46b962b 100644 --- a/FILE_MANIFEST.sha256 +++ b/FILE_MANIFEST.sha256 @@ -1,14 +1,15 @@ -d56cfff4179a6511aa764a91c6ddebe21fcd35f36b7298e62d012e11f62bfeb9 ./build.rs -b0270ac12ff6e0a9c8ab4325065ddd36eb7d432dc8f59293dd86591d4fa02015 ./Cargo.lock -d6ba6362369bfa0fedab8e95bf0fe2839270dbb8a9f4c13a78bddb5450262a55 ./Cargo.toml -ceafb0ec649a7a7ea0c469501dab144743306150c15869f3a084bab3ce47f51d ./data/gree-controller.db -237eab440e33eb7f88173a143112b90c4343d9272720068640e289d63220d415 ./docs/API.md -2e1e18fd8167dabfe2469c26e85cce62486c7cb6a502c63c6f6b0cd74d5885e0 ./docs/FLOW.md -4e747f2e3e2cbe7d20b0da76556035d7bc4bd80f789f61522e1a214c56f5c35c ./docs/openapi.json -d67af429e4da9ce08e9d2f2a8472849ffbd70d135b1c5da535a076026794d04c ./.env d67af429e4da9ce08e9d2f2a8472849ffbd70d135b1c5da535a076026794d04c ./.env.example a4ec3874a2e3ab1bad28fb40bb620f7b01f64d01ad9b699306bf70ada31227db ./.gitignore -2fbfbfeb87b04b364464269c190979bab48ee79bc6abff5c7b2292c61fddc8bd ./gree-controller.zip +174b5c57813e07375723f80f92772d965b1b434c02881d916c89efac0b61ee7e ./Cargo.lock +dc8d8412b74e19f2d32570ca0ef176c0036a140e47e41d020cb4d140ad9bfe39 ./Cargo.toml +19b2943504acb8f8de280f873a8dbec4bb6ebbe3870b158f5655d4fb8c298f5f ./LICENSE +079ddac7ba983a3d679b8c748bd43c731eb078e91a40c5d8a683bd76e14f06c5 ./README.md +d56cfff4179a6511aa764a91c6ddebe21fcd35f36b7298e62d012e11f62bfeb9 ./build.rs +514065eefa7428afbcacaca7095605495f95339a2ae8b23707315dc434f9c4c5 ./docs/API.md +2e1e18fd8167dabfe2469c26e85cce62486c7cb6a502c63c6f6b0cd74d5885e0 ./docs/FLOW.md +cb62e2ea377bdf4785c139ee169eec4914e04ceac6883c0afcb4c96fe60427b0 ./docs/openapi.json +b11e581dd916676e24402112fe6896bc681abf3c94cafc85c4d3ded3f3a272a3 ./home-assistant/README.md +f8e8559fe10fe523ac5bc9aac25c6e26e862f679d502e8f3c39f38a0a8e40911 ./home-assistant/custom_components/gree_controller/__init__.py 3f6ef15ef58456376ac53fde7cace1ef359d6a6f7a64c5b575ad77ea6e55ccc4 ./home-assistant/custom_components/gree_controller/api.py 71c8058f85fd9ce9f063b7a84dcf2956f23cdbbd02bd4bd99d2fbb9d177c72ad ./home-assistant/custom_components/gree_controller/climate.py 5e4aef2143e81bedb5a15dd4be5c71b64a3ab448ec6d33a20851edd098e5f529 ./home-assistant/custom_components/gree_controller/config_flow.py @@ -16,9 +17,8 @@ b7f0873109c52be9d7f09bea3dffc416103c50085e1f0680d11661a969479898 ./home-assista 41a8958a6fe6d10e5679c95ac34832583a2a15ecfd67d09b4e094a83d06f5c47 ./home-assistant/custom_components/gree_controller/coordinator.py 5a96fe8f5c035c34f1339370270cd078056202d09e236dec75735be11de92a7d ./home-assistant/custom_components/gree_controller/entity_map.py c4fb75c246db651087900ebfc2291ff41ac87652cd6194fc0b776b0005c1cbcf ./home-assistant/custom_components/gree_controller/icon.png -f8e8559fe10fe523ac5bc9aac25c6e26e862f679d502e8f3c39f38a0a8e40911 ./home-assistant/custom_components/gree_controller/__init__.py c4fb75c246db651087900ebfc2291ff41ac87652cd6194fc0b776b0005c1cbcf ./home-assistant/custom_components/gree_controller/logo.png -aa1384a3152f133bd2d4f9cabe0118820d68936d43c05b2ef8af9e51e955d000 ./home-assistant/custom_components/gree_controller/manifest.json +5d8a5f7be7e11b385d7c22a10dedce418c809e5d737e3a402ee21c7e2a5ae316 ./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 cca65482e36d48035aca178121a378fe7d578d600acff267ae81a6399c0da653 ./home-assistant/custom_components/gree_controller/sensor.py @@ -26,11 +26,9 @@ cca65482e36d48035aca178121a378fe7d578d600acff267ae81a6399c0da653 ./home-assista 6bddb7b4620021ecd2099a86a77ef5c7f2c2dcd3d07d5db4e7b4c4ce6d3e8c03 ./home-assistant/custom_components/gree_controller/translations/en.json 13f30e2dcdcedbd1b6c3f99c2335e0487108fd72c8e86922368b84f2fa2038ae ./home-assistant/custom_components/gree_controller/translations/pl.json c5fc5c87273d82d2834a0a5a365c821a416413ed509613441e24e4dc3507c4d2 ./home-assistant/generated/gree_controller_entities.example.json -b11e581dd916676e24402112fe6896bc681abf3c94cafc85c4d3ded3f3a272a3 ./home-assistant/README.md -bb280ce427875526f5a1e35a2fad9586615bf684929212476297d32c55a68771 ./lang/en.json -eb1616b13468caa683e6280ffd0fe00f760406cc25cf9f71751461962a23b774 ./lang/pl.json 253a0bc912786e67ea7fc92a64e4a510ad973bec343a88ccfb1f28fca3e8cf01 ./lang/README.md -19b2943504acb8f8de280f873a8dbec4bb6ebbe3870b158f5655d4fb8c298f5f ./LICENSE +00cd78873d3a3290419a83ea736a9ec5f0d93f590159cbf40c54d5ea6c3c89fb ./lang/en.json +a088acc585a863e204100af7f5465a5d761ba94c0afff66b5ed329e7d204ec35 ./lang/pl.json d8459024f04ca514bd8e9d6bd3af872fb942fd85a7cdd5583f4a9d28aab6faba ./make_zip.py b14233a8987e53bbbdd6770386ba10fa166ec25c1e098275c173c544b37846fc ./presets/bedroom_window_night.json 1960841119c0b673fb2f03621b32237552fd828045304cd221401214b997c910 ./presets/device_resilience.json @@ -69,9 +67,9 @@ fffa18bd989a0dcc1c5458975522517d40af4af40cc1ca30640e79d3db711053 ./presets/unoc ae21459a261712bcb8d57594528b1648432e8d03a8a38502234829c0dbfef774 ./presets/weekend_comfort.json fdcd9a5055d08037278b842e7ab69265345c5811f0a06867136c511d140bb191 ./presets/window_available_guard.json 804f22123cd3e8db0fac791826c8dd9f758fb866c8e3b5655fb6d25d259dccf1 ./presets/workday_comfort.json -4c529802f159c34cab82585a537d6c193940d8ddbd14a07076bd13ba2d9fcf54 ./README.md 01952aa92b217f8eae2493b88870e2dec595100cd15c4d561ff11ae2b936c46f ./regenerate-sha.sh -a937b937c8ac39d9b01e791b405f9c996314f5a563946bae94c3cbbefecc3411 ./scripts/api_dev_test.py +c64b1c6deeb24f20af662bfce7fa3683703914987241107ce664fa2f6d1a9dcb ./scripts/README.md +0e734dd7cdb8fa6226e31a96927861b44a41e75dea27f27ff4a539002d5bcf35 ./scripts/api_dev_test.py 5bc736c7bc76ca80aaa406bb171d2aa91baf4c3aa8695dce0e09b888b6ab3146 ./scripts/common.sh 6403786610ee6d2f628193c25aee0dd058d62e904aa1a31d5f62fdaae0e94b4f ./scripts/configure-gree-network.sh 1d6e14e26e49aa9d3527f30a23668bf8d9c48b67e6628ef686c3155c012155de ./scripts/dev.sh @@ -80,11 +78,11 @@ e4849261fd9ed1f01df96c0637c439c0c4eff8fa317b2918026167bba343af79 ./scripts/inst bb7cd2c5b27c9dceec1d1d2846fbad9600df9c08e0ad07d13fcde97af533091c ./scripts/install.sh 2af0a1390e69330acb6d62bafefafd3f33088b712867f9b1fc2f8604e2f253cd ./scripts/live_realtime_test.js e00d211e3885e30d7fed1e43b44e6fdad40a67019060156c0641816a93e3365f ./scripts/network-debug.sh -c64b1c6deeb24f20af662bfce7fa3683703914987241107ce664fa2f6d1a9dcb ./scripts/README.md 01952aa92b217f8eae2493b88870e2dec595100cd15c4d561ff11ae2b936c46f ./scripts/regenerate-sha.sh 81345b6a0b51736bdbc98fd23199b62e4c721b4e7437e02dab7ea79b97dff29a ./scripts/service.sh 7e8f558b284362f55f50bd7223a89754a2a4960e746a27035cc61180f4a2da6f ./scripts/smoke.sh b50782b3742dfbf8a319c60571c968e93fdf8547db747c759edcffae68cb98bf ./scripts/update.sh +4b795bcb2e6b73c0dc9687325f6ffb0e6f008c6694b2a9fb8190a45a563451b2 ./src/api.rs 5027797b9cefb9f0aa04c792e2ac9a38745c6bf1ee822f50eb70574fa6f997e2 ./src/api/assets.rs 05c255919f7b3d81188fc5f1410be6a0037471dfc44e93bffb009f29a1e6a3fc ./src/api/auth.rs 9e4fc675306e111ed3db7af9822e2925d88109c31b9e309851665a975c0bd83c ./src/api/automations.rs @@ -100,13 +98,13 @@ e8edfbb725d6de650442444b0a929ad2be0bd2c2d7d227d2b3fdd99d05c94f94 ./src/api/hous 6bfbe5135d4f93bd8d19a707877b53ed2029fd8490b4b1954a7520888fb1d664 ./src/api/middleware.rs 45e34a447ff384d99a3c42c489ca9fa75849c74d4d246caa91c63d927de17396 ./src/api/openapi.rs 744ce18aa9e0227c6cdfb6980063d0d738d74c5865d45c20fd20026d4742bb3e ./src/api/public_settings.rs -4b795bcb2e6b73c0dc9687325f6ffb0e6f008c6694b2a9fb8190a45a563451b2 ./src/api.rs 5b29f2e5aa2c422c5829ef89c7b59cf753883aa7f60661c95ab0f95cf676fa3f ./src/api/schedules.rs 9d157e1901081c077e32430d5d4d7f328ffb4933996579f584ce2959d5d10f47 ./src/api/settings.rs df3297f36f0d0fa071b872967c5c124ed3887805d4f0f1031761cfba25331e97 ./src/api/system.rs badd52159fa5d19c236cf9022b623d15c6fbfc7f0b7fc59e269717eb5ee3d10b ./src/api/websocket.rs 455c7238c9788d378e909a4fbc94d5390b67edd92e127f48b4b913ddcbe82fb0 ./src/api/zones.rs f06014454d5062b1be17ac50d875a42c02fc778b59702ec455611265ab7de934 ./src/config.rs +e0340b0e5945d5a38a1054e549c819566d5c1ef6034ab0e4d44c68a3b9a249cf ./src/db.rs 6c278fc5728124ab2f53ac7789a733942a0462f397144a231cc878c8cfcf7426 ./src/db/climate.rs be4082b142fe16ba40c5978b287b7ef808e67c13edbd8f2d6637ccad974b8847 ./src/db/configuration.rs bc10f1a66ddcaacbb08b096a02998482da547024dd0ba3144d00f993b4351cb0 ./src/db/core_devices.rs @@ -114,10 +112,10 @@ bc10f1a66ddcaacbb08b096a02998482da547024dd0ba3144d00f993b4351cb0 ./src/db/core_ eb07d94b58bcc8ea17b5b086cc88c165a35666f84c3d9a1d74f72dc30b979829 ./src/db/events_tokens.rs bb5048ee60053f39ce3c1203dc1f24c7047310538d2357f105a052c016d21ec4 ./src/db/flows.rs 5f4b567c6bc866d0674b3b0c66f4aeccf561774623f575b872ff25bf015b91c2 ./src/db/ha_history.rs -e0340b0e5945d5a38a1054e549c819566d5c1ef6034ab0e4d44c68a3b9a249cf ./src/db.rs c0a7fa3eac198737d7261ad00c542a614e6d7291f6581af8e7f7aef9dec1a049 ./src/db/schedules_automations.rs 1a209dc6d8df864778bb03c980f309a2ec86fc62df274880fbb95eff8470174e ./src/db/tests.rs f90fbb14f29a20b799b3856bdaa22812a9f0d9dfa46693f1341c160dccda8a97 ./src/db/zone_history.rs +4d2c6053586558afbca6b60fbbc9b1cd397f74f8284d7c01f3337eb42bf6d4f7 ./src/engine.rs 6046bdbc9c02ac74f47068229c59af69abc8bfa46cfeff6fe7ba573b493e128c ./src/engine/automations.rs 88f85acf692e12c7061e039dd7c54f101fe0b014c4a3d799150ad92eea9e2894 ./src/engine/commands.rs 8ee70ad21d8ee32914dd90952b04dfa8355ee868252ef4fc682ec40503590a7a ./src/engine/control_plan.rs @@ -127,7 +125,6 @@ f0c8f3384b6174771aeb5640ee1eec87f3d6d9ff79a4fbd6a35554a4eec00cfa ./src/engine/h 41b7045877771b7c352328998cb45ce2433e7f9631fad3eb1a882ab4897dc31f ./src/engine/local_thermostat.rs 6280a7f5059d9737987bf2d72b19a26b3a6709ce578af1108c4215f3f47d7763 ./src/engine/ownership.rs 3d7e74a8180e14f398363af1a45b32a5e4c89f749d631afce556a1ecd5fe4e80 ./src/engine/polling.rs -4d2c6053586558afbca6b60fbbc9b1cd397f74f8284d7c01f3337eb42bf6d4f7 ./src/engine.rs f0bcd3a56b600944ccc62fa24ce20838033eeb4354f937cdb534630c1a1f5a78 ./src/engine/runtime.rs c1e8de5392681ba1255e3e2d871a6ee860fb8ca987a0a8f973d9ded3977a68fb ./src/engine/schedules.rs b0189f28d0f337dfd3ce0934da7a565e4a5535afc1c242214c26ed584b3b7840 ./src/engine/targets.rs @@ -138,25 +135,26 @@ c89ff36c6a67bf4fbf68c43e18aa0a556de2dc69263fd79db376363afc741a4f ./src/engine/z dd38a8b8f6e910e4475c42ae41eaad2c68237fb36b78a3d7dd5d147c08487568 ./src/engine/zone_control.rs 2276aca42bca712a55de9b6c5dbe64639675c84befa85a446a7d34613596ed7e ./src/error.rs 2731f629f22a9d4fdb831ea3b283f43900b190f7e6a08fdab5b8fbb2c288547b ./src/home_assistant.rs +342dcb54caf22d2282a3f3f2297f54bd413b5242c17756276ea74994e88e28fb ./src/influxdb.rs da4068295f37c23222bb13bebac022d88ba7729604a49ad25438c55e45458a49 ./src/influxdb/codec.rs 1769e2a96e336bf39b28ae9de02a5d942350afa2bb9702df7603fabe9d7fcba7 ./src/influxdb/query.rs -342dcb54caf22d2282a3f3f2297f54bd413b5242c17756276ea74994e88e28fb ./src/influxdb.rs 29dc8ed02dfa1f6419bf4aedfb99c805b25c8a2e772efef20681c750570928cf ./src/influxdb/write.rs 9ec1bc25ebd06cc925e4fddc8b49e189a21ae495c6709c8cb1bba5b4dfa35388 ./src/main.rs +23688a5cb68efded89471ce959328d27adff370d451bd9f378a283ab51437e76 ./src/models.rs 920e028d96a14cca9f74a964bb296e68a109cfead314d3164c180201e606d151 ./src/models/automation.rs 3c3f344fe42cdde980b13dbec6e92ed0e2f5946cba8ac19b1a668846b48e7c81 ./src/models/control_plan.rs 9cd1904a0f822c557f6ad4576cdb5f96d9668d04e79ea9783885c9f39519752e ./src/models/defaults.rs f935d35b4a409f12774209f3fa2ffe60f579a8bc1722badbb27d4766efd6368e ./src/models/device.rs aeab5b5acf35d38a54fd1d82e964fe56635ade69c0149ad423df317095d01555 ./src/models/flow.rs cf63af00d98410a1452f205ce00b8a6c5f0f3525b994cba3e971d631db288396 ./src/models/history.rs -ea216f24f0f385903324f15a1164a0fc508adbdcc3c30d16383ea2e835c53e6e ./src/models/integrations.rs -23688a5cb68efded89471ce959328d27adff370d451bd9f378a283ab51437e76 ./src/models.rs +e1621255217ee6128151cc898373dd404123cb6d54017beec6c7e3e5c3030486 ./src/models/integrations.rs 8294749dd3af524925309c51ad641ffd32ff1fd9c164cfa71660aa88c2d13d6e ./src/models/runtime.rs 887eb80a58998e90023e952c1fde67435eb843493387ae64536613b74c084534 ./src/models/settings_api.rs c4de6101de85d9d7e6814b2504b87d9216561e3d9e274054f081f505fb152140 ./src/models/temporary_thermostat.rs 7d798228a8d4d4e60a112167c001535f4b8a5fa32ec7a33554c73125c42256c2 ./src/models/zone.rs -2ccac88080ef3ca8546facad5167cbaadc080bdee3f5d9100c8fabb0fc3ae49d ./src/notifications.rs +48e5d0e0c8b2863daf35c64ad49bf5333fb3b807568323cf0958efbc3aee7433 ./src/notifications.rs cca742bb2b500eb9269f69385fcf88053cd08aabf6a98b7669b8a7a2fd67df13 ./src/protocol/crypto.rs +28969da06a454ddd1ebea5fa606e8446a83dfd21e21352767c189013c508cb90 ./src/protocol/gree.rs 7907c33e6396c7e0d61705b735b21c84d6ed784012fb61022b872c6745540f1d ./src/protocol/gree/binding.rs d4df52f0202eb32290e68dc945c4b0b44f3be8aa90bd57fd116eb20285960616 ./src/protocol/gree/commands.rs 4e419ba3b86ca9d154e8c04445cf005965175c54041093b2daad3666d4d852bd ./src/protocol/gree/core.rs @@ -164,38 +162,37 @@ d4df52f0202eb32290e68dc945c4b0b44f3be8aa90bd57fd116eb20285960616 ./src/protocol 0ab094f609edb99715402d8eeaa7e38cbfd2d271036aec787dcbb3be3e005720 ./src/protocol/gree/merge.rs a96061fbbcadac6c2df2e9708a48dcf819b951eb147f32c7d0d285ac5ae2491b ./src/protocol/gree/network.rs de37931303fc92a9399e6edc17dfabd6870a38cd2ddb27257427c76768a66ec2 ./src/protocol/gree/polling.rs -28969da06a454ddd1ebea5fa606e8446a83dfd21e21352767c189013c508cb90 ./src/protocol/gree.rs c868422c02ba457df21ae92acbd00698c243855ddd1d4e95ac2166796eba9a44 ./src/protocol/gree/tests.rs 3c93e5b254a2a40a07854532cb5fc07e493ad65d9ba2cf28093cff4a4a4e451c ./src/protocol/gree/transport.rs 923bb4b2d342d6c1870474e43f33b0aba16dc88590c561d765b874412e83df1f ./src/protocol/mod.rs +830621fa75265da7288b8135704c0ce27e0687f87d55abf3cdbe40a6e2f3d2b1 ./src/queries.rs 7fac65a9dcbcecee09816f5447c7792dc94f736b1efb66ac85629db75f6280be ./src/queries/device_history.rs 3fb50f57d30ac23ef122c45dae4bd96c7cb7184df02d99aef00d9890b66479e2 ./src/queries/entities.rs 2c5fba462b72158b04dbaaa53c8536263f8d72a1338a6c4ff06cb28a36f6ae27 ./src/queries/ha_history.rs c91e4b8b250b30cbe76f313b70c16244e9003bce92e02c82283a1831f91974c5 ./src/queries/maintenance.rs -830621fa75265da7288b8135704c0ce27e0687f87d55abf3cdbe40a6e2f3d2b1 ./src/queries.rs 3a49bad74a2f047893e726b5e00a6e833c228ad268bdf50cd60f786ba164ea54 ./src/queries/schema.rs f13f1be3d5789539eba3fc1b59c14835f8c681eca7634e118fa3763a53aeee2b ./src/queries/zone_history.rs 008be170ed418f8701c512f521828b8e6c0071ff195cd6f7aa39fade6c7c3fa9 ./src/state.rs b92a6cb158b494fe145b43c7641e65f6fafff47201d7d76edbec2cfd8b94835c ./systemd/gree-controller.service 544a31cb2e5374227026afd6abd0d910381f3fca1638154ebd74e3c3d96a35d1 ./web/404.html e98bdd7204349cce1ec6f57283509697af0bbc72280622a6c3efa6fed242db4f ./web/favicon.svg -b8df5b68b752c717a7772c6f70a00f748d20b245eff4ca0cda937ad603104d16 ./web/index.html +62e0a01a47a2d30e5265010aef5a089b0055d824fede940b7665d76f92018522 ./web/index.html +9ba3f6fa05b72aa989139b2a909982571b2a02055052e4c40104f1e81a9aa7eb ./web/js/README.md 45fb54541a117a8ee0dc484cd263b6af4aafab75d94d269b126bb603b5f0392c ./web/js/bootstrap.js badde8a5214a0322b2c45803c02a1cb723d53b25e57c687369cd804f509d9744 ./web/js/charts.js dd596b3362643b96be8537b9415e8c1be90d7cf458124b61121016a6742951c7 ./web/js/core.js d880ffdac6aa07cd10d79fbacf12f87eb4c69b48a80564bbfdd0248abe8884d5 ./web/js/dashboard.js 6c0d310e39a1e1f618a31fbdf5560a850023bf2219d897c69d636d0179dff004 ./web/js/entities.js -e332b3f811958a938105272c1e8e28d6ca8ba69303001da165b4b0b85727695c ./web/js/events.js +0a23ac65a4a0bd113a9f78fe1d25621d6a178e10aaca53e5df8df87587998cb4 ./web/js/events.js 2e822a00b5a6941b6a251eaf2c54ca95a53399b5d1056f3d8240e11f82d6065f ./web/js/flows.js cf1ebf3b9d666f309a1add070b4da86be86d990b02c8d6474f6d121c6d332746 ./web/js/forms.js dbf36223863ba882c03eccea4516ba8db7acf0c2e72c6c64490cb994f1e20f96 ./web/js/history.js 7eaa04992ea828dc89f5eaebf674cbbfd160f53eb8d0d6ef0d4e47bd8c28c435 ./web/js/main.js 733fcc595ed9c03c9639acc6caba46f0588f29e0b95bf72891e34443e7aa9db8 ./web/js/navigation.js -9ba3f6fa05b72aa989139b2a909982571b2a02055052e4c40104f1e81a9aa7eb ./web/js/README.md e3e01511a34175b88eb01dac2c557e8b112fcad5826f02a0bc3cd1e8dfb7ff91 ./web/js/realtime.js c8c82e88c3715b1bfabf155e36266a4c94f5e2fc03eb39dcdd9d08a1985a997c ./web/js/router.js -9dd9fbcc5f00584562bae6a840189495f830d1086d9679763dbad6e9c18c4fdb ./web/js/settings.js -427376a35832cb3644206c6e89e1654bd807eec78352f80bd0dd43f74b4ec810 ./web/js/settings-ui.js +25f5c9a0aa8622f419b05f64712c9eca4896f0e79818616904b83051fd77b07b ./web/js/settings-ui.js +7399a951ae585d7c9ee55cc57064c64a2806ec725e2456cfe6b09bc61f8f4166 ./web/js/settings.js 6b653e4fe2d4db4ffae6ff8f39b8ce57a10a990dc0000ee4aae51d949afadd52 ./web/manifest.webmanifest 801bb151f7b6220587e22c3114fb224a540dcfbddd1c09870007b7b893a01301 ./web/styles.css ae1b03f30b494f474a781a5d32072f1e73eba2b7c768109fc1cc8028cb6662a4 ./web/sw.js diff --git a/README.md b/README.md index 3b560ea..01751fb 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ 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.13.5** +**Current release: 0.13.6** -Release 0.13.5 keeps the 0.13.x HTTP/WS contracts and makes disabled-zone semantics explicit in both thermostat controls and zone settings. Disabling a zone stops automation, while manual thermostat, temporary thermostat and direct manual control remain available. The 0.1 °C logical thermostat precision introduced in 0.13.3 is unchanged. +Release 0.13.6 adds a dedicated notification toggle for GREE vs Home Assistant room-temperature discrepancies. Disabling this alert suppresses `zone.sensor_discrepancy` notifications only; sensor fallback and thermostat safety behavior are unchanged. > [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 5f6d32e..c457797 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.13.5**. +HTTP and WebSocket API for GREE Controller **0.13.6**. [← Main documentation](../README.md) @@ -231,7 +231,7 @@ Response: { "status": "ok", "name": "gree-controller", - "version": "0.13.5", + "version": "0.13.6", "uptime_seconds": 1234, "control_ready": true, "time": "2026-08-30T06:54:00Z" @@ -257,7 +257,7 @@ Returns the initial Web UI snapshot: "control_plan": {"generated_at": "2026-09-04T08:00:00Z", "zones": [], "rules": []}, "control_plan_revision": 42, "system": { - "version": "0.13.5", + "version": "0.13.6", "uptime_seconds": 1234, "auth_required": false, "control_ready": true, @@ -1107,6 +1107,7 @@ Retention values are clamped to `1..3650` days. Updating this section immediatel "communication": true, "target_timeout": true, "automation": true, + "sensor_discrepancy": true, "control_errors": true, "important_events": true, "other": true @@ -1114,7 +1115,7 @@ Retention values are clamped to `1..3650` days. Updating this section immediatel } ``` -`PUT` accepts the same behavioral fields plus optional `pushover_app_token`, `pushover_user_key`, `slack_webhook_url` and `discord_webhook_url`. Omitted/`null` secrets are preserved; an explicit empty string clears them. Modes: `problems`, `important`. Providers: `pushover`, `slack`, `discord`. Cooldown is clamped to `30..86400` seconds, failure threshold to `2..100`, target timeout to `5..1440` minutes. +`PUT` accepts the same behavioral fields plus optional `pushover_app_token`, `pushover_user_key`, `slack_webhook_url` and `discord_webhook_url`. Omitted/`null` secrets are preserved; an explicit empty string clears them. Modes: `problems`, `important`. Providers: `pushover`, `slack`, `discord`. Cooldown is clamped to `30..86400` seconds, failure threshold to `2..100`, target timeout to `5..1440` minutes. `alert_types.sensor_discrepancy` controls only notifications about GREE vs Home Assistant room-temperature divergence; the safety fallback to the GREE sensor remains active. ### `/api/settings/night` @@ -1467,6 +1468,8 @@ In `0.13.4`, disabled-zone thermostat controls remain visually active because ex In `0.13.5`, the same disabled-zone behavior is explained directly beside the zone enabled/disabled setting, so users see before changing it that disabling a zone stops automation but does not block manual thermostat, temporary thermostat or direct manual control. HTTP and WebSocket contracts remain unchanged. +In `0.13.6`, notification settings add `alert_types.sensor_discrepancy`, allowing GREE vs Home Assistant temperature-difference notifications to be disabled independently from thermostat/group control errors. The sensor fallback behavior itself is unchanged. + Additional engine/integration events may be introduced without changing the envelope. `api.request` data: diff --git a/docs/openapi.json b/docs/openapi.json index 2683afc..02d4563 100644 --- a/docs/openapi.json +++ b/docs/openapi.json @@ -2,9 +2,9 @@ "openapi": "3.1.0", "info": { "title": "GREE Controller API", - "version": "0.13.5", + "version": "0.13.6", "summary": "Local HTTP/WebSocket API for GREE HVAC control", - "description": "Self-hosted API used by the GREE Controller Web UI and Home Assistant integration.\n\n### Authentication\nNormal administrator endpoints accept `Authorization: Bearer ` or `x-api-token: ` when `GREE_CONTROLLER_APP_TOKEN` is configured. If the app token is empty, those endpoints intentionally run in trusted-LAN mode without authentication.\n\nThe restricted `/api/integrations/home-assistant/*` control surface always requires either a generated access token or the administrator app token. Generated tokens do **not** grant normal administrator API access.\n\nIn Swagger UI use **Authorize** and enter the token in either the bearer field or `x-api-token` field.\n\n### Control ownership\nThermostat zones, groups, house rules, direct device control, schedules and visual Flows share an ownership/arbitration model. Prefer zone/group/house endpoints for thermostat intent; direct device commands are technical/manual control and can deliberately take ownership.\n\n### 0.12.0 breaking API\nRuntime settings are split into functional `/api/settings/*` resources. The former `/api/settings`, `/api/debug`, `/api/events/retention`, `/api/settings/export` and `/api/settings/import` endpoints were removed without compatibility aliases.\n\n### 0.13.0\n`control-plan` keeps its existing HTTP response shape but is materialized in memory and pushed to WebSocket clients as `control_plan.updated`; HTTP remains the fallback/resync path. A restricted Home Assistant snapshot endpoint combines devices, groups and the control plan.\n\n### 0.13.1\nRuntime WebSocket churn is reduced without changing contracts: no-op zone regulator heartbeats are deduplicated and device heartbeat polls only invalidate the materialized control plan when plan-relevant device state changes.\n\n### 0.13.2\nCompletes live WebSocket synchronization for entity creation, schedules, automations, configuration imports and runtime device/automation state while preserving the existing HTTP API contracts and control-plan fallback behavior.\n\n### 0.13.3\nLogical thermostat targets are normalized to 0.1 C consistently, including Temporary Quick Thermostat and thermostat-managed automation/Flow actions. The bundled Web UI accepts comma or dot decimal input for the temporary thermostat target; physical GREE setpoint rounding is unchanged.\n\n### 0.13.4\nDisabled-zone thermostat controls remain visually active in the bundled Web UI because explicit temporary/manual thermostat and direct manual control remain available while zone automation is disabled. HTTP and WebSocket contracts are unchanged.\n\n### 0.13.5\nThe zone settings dialog now explains directly beside the enabled/disabled option that disabling a zone stops automation but does not block manual thermostat, temporary thermostat or direct manual control. HTTP and WebSocket contracts remain unchanged.", + "description": "Self-hosted API used by the GREE Controller Web UI and Home Assistant integration.\n\n### Authentication\nNormal administrator endpoints accept `Authorization: Bearer ` or `x-api-token: ` when `GREE_CONTROLLER_APP_TOKEN` is configured. If the app token is empty, those endpoints intentionally run in trusted-LAN mode without authentication.\n\nThe restricted `/api/integrations/home-assistant/*` control surface always requires either a generated access token or the administrator app token. Generated tokens do **not** grant normal administrator API access.\n\nIn Swagger UI use **Authorize** and enter the token in either the bearer field or `x-api-token` field.\n\n### Control ownership\nThermostat zones, groups, house rules, direct device control, schedules and visual Flows share an ownership/arbitration model. Prefer zone/group/house endpoints for thermostat intent; direct device commands are technical/manual control and can deliberately take ownership.\n\n### 0.12.0 breaking API\nRuntime settings are split into functional `/api/settings/*` resources. The former `/api/settings`, `/api/debug`, `/api/events/retention`, `/api/settings/export` and `/api/settings/import` endpoints were removed without compatibility aliases.\n\n### 0.13.0\n`control-plan` keeps its existing HTTP response shape but is materialized in memory and pushed to WebSocket clients as `control_plan.updated`; HTTP remains the fallback/resync path. A restricted Home Assistant snapshot endpoint combines devices, groups and the control plan.\n\n### 0.13.1\nRuntime WebSocket churn is reduced without changing contracts: no-op zone regulator heartbeats are deduplicated and device heartbeat polls only invalidate the materialized control plan when plan-relevant device state changes.\n\n### 0.13.2\nCompletes live WebSocket synchronization for entity creation, schedules, automations, configuration imports and runtime device/automation state while preserving the existing HTTP API contracts and control-plan fallback behavior.\n\n### 0.13.3\nLogical thermostat targets are normalized to 0.1 C consistently, including Temporary Quick Thermostat and thermostat-managed automation/Flow actions. The bundled Web UI accepts comma or dot decimal input for the temporary thermostat target; physical GREE setpoint rounding is unchanged.\n\n### 0.13.4\nDisabled-zone thermostat controls remain visually active in the bundled Web UI because explicit temporary/manual thermostat and direct manual control remain available while zone automation is disabled. HTTP and WebSocket contracts are unchanged.\n\n### 0.13.5\nThe zone settings dialog now explains directly beside the enabled/disabled option that disabling a zone stops automation but does not block manual thermostat, temporary thermostat or direct manual control. HTTP and WebSocket contracts remain unchanged.\n\n### 0.13.6\nNotification settings add a dedicated sensor_discrepancy alert type for GREE vs Home Assistant room-temperature divergence. Disabling it suppresses only that notification; the GREE safety fallback remains active.", "license": { "name": "MIT" } @@ -4891,7 +4891,7 @@ }, "version": { "type": "string", - "example": "0.13.5" + "example": "0.13.6" }, "uptime_seconds": { "type": "integer", @@ -7488,6 +7488,10 @@ "automation": { "type": "boolean" }, + "sensor_discrepancy": { + "type": "boolean", + "description": "Send notifications when GREE and Home Assistant room-temperature sensors differ beyond the configured zone limit. This does not disable the GREE safety fallback." + }, "control_errors": { "type": "boolean" }, @@ -7504,6 +7508,7 @@ "communication", "target_timeout", "automation", + "sensor_discrepancy", "control_errors", "important_events", "other" diff --git a/home-assistant/custom_components/gree_controller/manifest.json b/home-assistant/custom_components/gree_controller/manifest.json index 16d2c71..6ff6ae4 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.13.5", + "version": "0.13.6", "config_flow": true, "integration_type": "hub", "iot_class": "local_polling", diff --git a/lang/en.json b/lang/en.json index abf0e17..8fc4d92 100644 --- a/lang/en.json +++ b/lang/en.json @@ -736,6 +736,7 @@ "notifications.alertCommunication": "Device communication problems", "notifications.alertTargetTimeout": "Target temperature timeout", "notifications.alertAutomation": "Automation errors and conflicts", + "notifications.alertSensorDiscrepancy": "GREE vs Home Assistant temperature difference", "notifications.alertControlErrors": "Thermostat and group control errors", "notifications.alertImportantEvents": "Important state changes", "notifications.alertOther": "Other warnings and errors", @@ -1171,4 +1172,4 @@ "schedules.enabledState": "Enabled", "schedules.disabledState": "Disabled" } -} \ No newline at end of file +} diff --git a/lang/pl.json b/lang/pl.json index 8a648dc..a978c6c 100644 --- a/lang/pl.json +++ b/lang/pl.json @@ -736,6 +736,7 @@ "notifications.alertCommunication": "Problemy komunikacji z urządzeniami", "notifications.alertTargetTimeout": "Nieosiągnięcie temperatury w limicie czasu", "notifications.alertAutomation": "Błędy i konflikty automatyzacji", + "notifications.alertSensorDiscrepancy": "Różnica temperatury GREE względem Home Assistant", "notifications.alertControlErrors": "Błędy sterowania termostatami i grupami", "notifications.alertImportantEvents": "Ważne zmiany stanu", "notifications.alertOther": "Pozostałe ostrzeżenia i błędy", @@ -1171,4 +1172,4 @@ "schedules.enabledState": "Włączony", "schedules.disabledState": "Wyłączony" } -} \ No newline at end of file +} diff --git a/scripts/api_dev_test.py b/scripts/api_dev_test.py index d47a53c..cfa93e9 100644 --- a/scripts/api_dev_test.py +++ b/scripts/api_dev_test.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Developer smoke/integration tests for GREE Controller API 0.13.5. +"""Developer smoke/integration tests for GREE Controller API 0.13.6. Default mode is read-only and safe to run against a real controller. Use --settings-write to additionally round-trip all split settings resources and @@ -26,7 +26,7 @@ from typing import Any, Callable, Iterable, Optional DEFAULT_BASE_URL = os.environ.get("GREE_API_URL", "http://127.0.0.1:8787") DEFAULT_TOKEN = os.environ.get("GREE_API_TOKEN", "") -DEFAULT_EXPECTED_VERSION = "0.13.5" +DEFAULT_EXPECTED_VERSION = "0.13.6" SETTINGS_PATHS: dict[str, set[str]] = { "/api/settings/application": {"simulator_enabled"}, @@ -519,7 +519,7 @@ def run_suite(args: argparse.Namespace) -> int: print(f"Settings write tests: {'ENABLED' if args.settings_write else 'disabled'}\n") runner.run("public health", lambda: test_health(client, args.expected_version)) - runner.run("OpenAPI 0.13.5 contract", lambda: test_openapi(client, args.expected_version)) + runner.run("OpenAPI 0.13.6 contract", lambda: test_openapi(client, args.expected_version)) runner.run("protected API requires auth", lambda: test_protected_auth(client)) for path in SAFE_GET_PATHS: @@ -587,7 +587,7 @@ def run_suite(args: argparse.Namespace) -> int: def parse_args(argv: Optional[Iterable[str]] = None) -> argparse.Namespace: parser = argparse.ArgumentParser( - description="Developer smoke/integration tests for GREE Controller API 0.13.5.", + description="Developer smoke/integration tests for GREE Controller API 0.13.6.", formatter_class=argparse.RawDescriptionHelpFormatter, epilog="""Examples: python3 scripts/api_dev_test.py diff --git a/src/models/integrations.rs b/src/models/integrations.rs index db76cd6..f3f16e2 100644 --- a/src/models/integrations.rs +++ b/src/models/integrations.rs @@ -95,7 +95,10 @@ pub struct NotificationAlertTypes { /// Automation execution errors and conflicts. #[serde(default = "default_true")] pub automation: bool, - /// Thermostat/group/device control failures and sensor discrepancies. + /// GREE room temperature differs from the configured Home Assistant sensor beyond the zone limit. + #[serde(default = "default_true")] + pub sensor_discrepancy: bool, + /// Thermostat/group/device control failures. #[serde(default = "default_true")] pub control_errors: bool, /// Informational state changes sent when notification mode is "important". @@ -114,6 +117,7 @@ impl Default for NotificationAlertTypes { communication: true, target_timeout: true, automation: true, + sensor_discrepancy: true, control_errors: true, important_events: true, other: true, diff --git a/src/notifications.rs b/src/notifications.rs index 11b2a0c..70e0b2a 100644 --- a/src/notifications.rs +++ b/src/notifications.rs @@ -43,13 +43,15 @@ fn alert_type_enabled(cfg: &NotificationSettings, kind: &str) -> bool { if kind.starts_with("automation.") { return types.automation; } + if kind == "zone.sensor_discrepancy" { + return types.sensor_discrepancy; + } if matches!( kind, "zone.action_error" | "zone.mode_change_off_error" | "zone.local_power_error" | "zone.device_missing" - | "zone.sensor_discrepancy" | "zone.temporary_quick_thermostat_cancelled" | "zone.temporary_quick_thermostat_poweroff_error" | "group.power_error" @@ -142,6 +144,25 @@ pub async fn dispatch( } } +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn sensor_discrepancy_has_its_own_notification_toggle() { + let mut cfg = NotificationSettings::default(); + cfg.alert_types.control_errors = true; + cfg.alert_types.sensor_discrepancy = false; + assert!(!alert_type_enabled(&cfg, "zone.sensor_discrepancy")); + assert!(alert_type_enabled(&cfg, "zone.action_error")); + + cfg.alert_types.control_errors = false; + cfg.alert_types.sensor_discrepancy = true; + assert!(alert_type_enabled(&cfg, "zone.sensor_discrepancy")); + assert!(!alert_type_enabled(&cfg, "zone.action_error")); + } +} + async fn send_pushover( state: &AppState, cfg: &NotificationSettings, diff --git a/web/index.html b/web/index.html index 403baaf..5174da1 100644 --- a/web/index.html +++ b/web/index.html @@ -585,6 +585,8 @@ data-i18n="notifications.alertTargetTimeout">Target temperature timeout +