From e02557bb6559b4b4ea1e4b2ce839801b8f5f6f6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Gruszczy=C5=84ski?= Date: Wed, 16 Sep 2026 22:38:45 +0200 Subject: [PATCH] v0.14.19 --- Cargo.lock | 2 +- Cargo.toml | 2 +- FILE_MANIFEST.sha256 | 29 +++++---- README.md | 4 +- SOURCE_MANIFEST.sha256 | 27 ++++---- docs/API.md | 6 +- docs/openapi.json | 6 +- ha-addon/Dockerfile | 64 +++++++++++++++---- ha-addon/README.md | 2 + .../gree_controller/manifest.json | 2 +- .../repository/gree-controller/CHANGELOG.md | 8 +++ .../repository/gree-controller/config.yaml | 2 +- web/js/events.js | 2 +- web/js/settings-ui.js | 33 +++++++++- web/js/settings.js | 2 + 15 files changed, 136 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c704996..275f651 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -700,7 +700,7 @@ dependencies = [ [[package]] name = "gree-controller" -version = "0.14.18" +version = "0.14.19" dependencies = [ "aes", "aes-gcm", diff --git a/Cargo.toml b/Cargo.toml index 2480e37..3f7f94e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gree-controller" -version = "0.14.18" +version = "0.14.19" 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 4081607..9f05e19 100644 --- a/FILE_MANIFEST.sha256 +++ b/FILE_MANIFEST.sha256 @@ -1,17 +1,18 @@ +8c09c8a2203e7b42ba62cbf7a354e57cb70941a5ecc77949368770e65fe9c8f7 ./.dockerignore de0793949cf01d27d903653226ecc9b5f72523d8711f20bcab022cf42c4c4ed0 ./.env.example a4ec3874a2e3ab1bad28fb40bb620f7b01f64d01ad9b699306bf70ada31227db ./.gitignore -ae81cbdcd9800a5b705f5321034f001571cecc8124671c7ebb77de8ce9d0033e ./Cargo.lock -5190ac715681fbb1aa4b2bcebf1478c58791794507e3f4f70af37fc6bf1b29bc ./Cargo.toml +dedaf21f819781eec228f2c0157763cede750924702188a0364c8ebb9883fd5c ./Cargo.lock +8d55d4634d79e78441cfbc4ffb7b4670b72e3db5479635b1c00c1a8b457c0c11 ./Cargo.toml 19b2943504acb8f8de280f873a8dbec4bb6ebbe3870b158f5655d4fb8c298f5f ./LICENSE -414ce67f34d7eccde894167b383a2cf4f18ae9f275e782d61f48569b1297b0a8 ./README.md -a1a12263a9409f687783d79b83e285785cc735ab80288f37b57cf6cccca967d4 ./SOURCE_MANIFEST.sha256 +31e586f1b862749e1b84b9377e84a4c7782b926b8750a32288c450b8f585e0b8 ./README.md +261aaaca41949e089df4a9534a81963f773e30f34e19969c1c0ca1ca6a8af13f ./SOURCE_MANIFEST.sha256 5302570299af2c2650bada12e123f598c5db8009949c75761385f73ed57343c5 ./build.rs -a2ce53408ca7ea559da735b1d7d0bb6d3d050eca220a5fcfe43f264b336e583f ./docs/API.md +5dfcac9595844437fbc8f0bc18919cfced53b3d54983cddaa0cad6668614dd7b ./docs/API.md f21d732eb1147f8f3167d2172cdf0b57e61edabdfecbaf97811d46c5bff7e47a ./docs/FLOW.md -9dc6076abac0bd394682206a365a179b64a798104b5f300135de5a74ed6a580c ./docs/openapi.json +46530da47203469fd6212fe6d77381204a8d3d6947e8c0554245a90c4206c824 ./docs/openapi.json c65aa543d2e99f8f7d52736307b07ebd182597d80124661d53a16bb23f6f1118 ./ha-addon/.env.example -ddec80cf2b5da73fd1bae50e46398033c95aa088afdb7c07d4889b5987a17a3f ./ha-addon/Dockerfile -3702707b5fd4f3a3d5d73e2dc827a6a43c144a22ff94861ab38720207bfcd94b ./ha-addon/README.md +8e500c57acbd92551c503cb010ae992c1aac524b3720b1d40043d1c8a22ccac5 ./ha-addon/Dockerfile +adf7ff248d782a3b1cba82b8789c57b6849ddaaaf5fbc108af75e18b1534a885 ./ha-addon/README.md dd9291b12afade6fc20d66e80a5513251270e18e4c265260b2bbbe393a5a94c4 ./ha-addon/build.sh 082dfeb6326f3e1b9841ccf7f2954117ecdf0aa1a90b0aef1e6a1960dacdecbf ./ha-addon/home-assistant/README.md f8e8559fe10fe523ac5bc9aac25c6e26e862f679d502e8f3c39f38a0a8e40911 ./ha-addon/home-assistant/custom_components/gree_controller/__init__.py @@ -22,7 +23,7 @@ b7f0873109c52be9d7f09bea3dffc416103c50085e1f0680d11661a969479898 ./ha-addon/hom 41a8958a6fe6d10e5679c95ac34832583a2a15ecfd67d09b4e094a83d06f5c47 ./ha-addon/home-assistant/custom_components/gree_controller/coordinator.py 5a96fe8f5c035c34f1339370270cd078056202d09e236dec75735be11de92a7d ./ha-addon/home-assistant/custom_components/gree_controller/entity_map.py c4fb75c246db651087900ebfc2291ff41ac87652cd6194fc0b776b0005c1cbcf ./ha-addon/home-assistant/custom_components/gree_controller/icon.png -3af12a645805dd8f70be900d1f962be1dfef1c252ba5d2f72bef89c1e4ed7587 ./ha-addon/home-assistant/custom_components/gree_controller/manifest.json +55d35c83df15e87c1e8a44120dc4bf8187b29cc880d8817d857bc15976114c51 ./ha-addon/home-assistant/custom_components/gree_controller/manifest.json c52a484b671ce738ecc00228a1db19a5d703f69ab27530c2896a5c2ae3b4a96f ./ha-addon/home-assistant/custom_components/gree_controller/number.py 39c4309001b75abb56234f05662bc06e077054986876f1927937edbce528ec95 ./ha-addon/home-assistant/custom_components/gree_controller/select.py cca65482e36d48035aca178121a378fe7d578d600acff267ae81a6399c0da653 ./ha-addon/home-assistant/custom_components/gree_controller/sensor.py @@ -30,10 +31,10 @@ cca65482e36d48035aca178121a378fe7d578d600acff267ae81a6399c0da653 ./ha-addon/hom 6bddb7b4620021ecd2099a86a77ef5c7f2c2dcd3d07d5db4e7b4c4ce6d3e8c03 ./ha-addon/home-assistant/custom_components/gree_controller/translations/en.json 13f30e2dcdcedbd1b6c3f99c2335e0487108fd72c8e86922368b84f2fa2038ae ./ha-addon/home-assistant/custom_components/gree_controller/translations/pl.json c5fc5c87273d82d2834a0a5a365c821a416413ed509613441e24e4dc3507c4d2 ./ha-addon/home-assistant/generated/gree_controller_entities.example.json -6339b12ea19bcde3628ac34cc7b65fd971e3e44bcaf28c7a144fa8042a25aada ./ha-addon/repository/gree-controller/CHANGELOG.md +88e6f4f911b3454fbdfc7d5cb9ea405d850f476f95f261e2fce03f45d4e4d6e7 ./ha-addon/repository/gree-controller/CHANGELOG.md 1b5599195329cc3e643c23aa1caadcec80f133e8e515eec7d92b9f3cbda5b80b ./ha-addon/repository/gree-controller/DOCS.md c3db302f38d26dc9f8caf37a1a8a07a1334cc07ae301d452f2940a5ec5915719 ./ha-addon/repository/gree-controller/README.md -a07415454295755b8920fe305deff439e6ebc79f0f4ba184cd3ae91d41c8d420 ./ha-addon/repository/gree-controller/config.yaml +78898b62a10a4929fee6f1ccd1778620397a2aa55eb639d99e2061a7b58a57d6 ./ha-addon/repository/gree-controller/config.yaml 3aae6cdae4c3aaab7786a9575e7093b7e2c5b69288167075f4b7475611691a6b ./ha-addon/repository/gree-controller/topologia-ha-vlan-gree-pl.png 0d0b42a7639b128946eec379175436fa1f150294f39d2dfd169077bfa87fd14d ./ha-addon/repository/gree-controller/topology-ha-vlan-gree-en.png 2272740b185e9520e948f74b8f45cf98b8b5fd28c93bdee760da626f91fe5c2a ./ha-addon/repository/gree-controller/translations/en.yaml @@ -210,7 +211,7 @@ e98bdd7204349cce1ec6f57283509697af0bbc72280622a6c3efa6fed242db4f ./web/favicon. 5c46d271550f3db38ecbfc09e3a620f6f0e6a907a3d6d56feae9b08e894df196 ./web/js/core.js 752b3c3b59558b42d867d4a15329238f0213f354b76f7011c10e31b4e6dbb311 ./web/js/dashboard.js 0f975542ae1d9bd7216123dd3718be6e9a25dbe643eb899c67024d293940fae5 ./web/js/entities.js -7c08eb200684e6fff521db589fd4417eea050f4eac02f9a2e6b53d212dd33f75 ./web/js/events.js +aaa874637d4a63876aa1248f995190316de80031b4bbcac1e8943238d2bafb53 ./web/js/events.js 473511ca11a0412a794b20430c077843072e9abe0d2510552ac83b226c381453 ./web/js/flows.js a3d9f77a40a2574a668855125c781c067289944c6f93179ff23e3dae150e7dac ./web/js/forms.js edde2969c9c1376f4df37224daa291256ebbbe713903d98e26b6aaa6ca467911 ./web/js/history.js @@ -219,8 +220,8 @@ edde2969c9c1376f4df37224daa291256ebbbe713903d98e26b6aaa6ca467911 ./web/js/histo 799613c6d465cb2f92ecb57cb082d0c33729a03d88ab4ca7fa12a3cbd7e38e75 ./web/js/realtime.js 9546ca5c5566994aff3c33d92295be46b65d51d874681764abe77470dc9c9c73 ./web/js/router.js c2710fd9c1f2b31878c1e25ceb02d74ae30456c1bbb400e69fcf7619ecc72bc2 ./web/js/select-ui.js -420cc44008d739ece4031093db772cc2bd6cdc0573b971b04ccce2aedb5762dd ./web/js/settings-ui.js -9f50794a92059357301b4c920b066bdb20ce1f64fbccea42effcd196d0a00cc4 ./web/js/settings.js +f7245f0e6cb5011196704f201675ebc6c19d902b8253ffcdbf9ead46cb1c6f86 ./web/js/settings-ui.js +335317bd50dd411f8c5e6d00b22d30e53172484626f2ad9901e32cab469724ac ./web/js/settings.js 3815fea7ae1694568c2f249bc8460e0563ced6bde89214f74f21b41fe8cad9a6 ./web/lang-init.js 6b653e4fe2d4db4ffae6ff8f39b8ce57a10a990dc0000ee4aae51d949afadd52 ./web/manifest.webmanifest 0efe0cdff18beff496017a984f6d189ea6463e14b517f2f5c5fc46923579ab15 ./web/styles.css diff --git a/README.md b/README.md index 54c299b..eafa034 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. -**Version: 0.14.18** +**Version: 0.14.19** -Version 0.14.18 refactors shared Web UI CSS classes to generic component names. Segmented navigation, configuration forms/sections, chart cards, enable toggles, diagram nodes/ports and Flow block-category styling now use reusable names instead of classes tied to one feature. +Version 0.14.19 speeds up amd64/arm64 Home Assistant image builds by cross-compiling Rust on the build host with persistent Cargo caches while preserving the selected Alpine or Debian Trixie target runtime. It also deduplicates the GREE Cloud runtime-status request during the initial HTTP/WebSocket bootstrap. > [Full API reference](docs/API.md) — authentication, every endpoint, request bodies, response models, WebSocket events and examples. diff --git a/SOURCE_MANIFEST.sha256 b/SOURCE_MANIFEST.sha256 index 9d6e3fe..4618fff 100644 --- a/SOURCE_MANIFEST.sha256 +++ b/SOURCE_MANIFEST.sha256 @@ -1,16 +1,17 @@ +8c09c8a2203e7b42ba62cbf7a354e57cb70941a5ecc77949368770e65fe9c8f7 ./.dockerignore de0793949cf01d27d903653226ecc9b5f72523d8711f20bcab022cf42c4c4ed0 ./.env.example a4ec3874a2e3ab1bad28fb40bb620f7b01f64d01ad9b699306bf70ada31227db ./.gitignore -ae81cbdcd9800a5b705f5321034f001571cecc8124671c7ebb77de8ce9d0033e ./Cargo.lock -5190ac715681fbb1aa4b2bcebf1478c58791794507e3f4f70af37fc6bf1b29bc ./Cargo.toml +dedaf21f819781eec228f2c0157763cede750924702188a0364c8ebb9883fd5c ./Cargo.lock +8d55d4634d79e78441cfbc4ffb7b4670b72e3db5479635b1c00c1a8b457c0c11 ./Cargo.toml 19b2943504acb8f8de280f873a8dbec4bb6ebbe3870b158f5655d4fb8c298f5f ./LICENSE -414ce67f34d7eccde894167b383a2cf4f18ae9f275e782d61f48569b1297b0a8 ./README.md +31e586f1b862749e1b84b9377e84a4c7782b926b8750a32288c450b8f585e0b8 ./README.md 5302570299af2c2650bada12e123f598c5db8009949c75761385f73ed57343c5 ./build.rs -a2ce53408ca7ea559da735b1d7d0bb6d3d050eca220a5fcfe43f264b336e583f ./docs/API.md +5dfcac9595844437fbc8f0bc18919cfced53b3d54983cddaa0cad6668614dd7b ./docs/API.md f21d732eb1147f8f3167d2172cdf0b57e61edabdfecbaf97811d46c5bff7e47a ./docs/FLOW.md -9dc6076abac0bd394682206a365a179b64a798104b5f300135de5a74ed6a580c ./docs/openapi.json +46530da47203469fd6212fe6d77381204a8d3d6947e8c0554245a90c4206c824 ./docs/openapi.json c65aa543d2e99f8f7d52736307b07ebd182597d80124661d53a16bb23f6f1118 ./ha-addon/.env.example -ddec80cf2b5da73fd1bae50e46398033c95aa088afdb7c07d4889b5987a17a3f ./ha-addon/Dockerfile -3702707b5fd4f3a3d5d73e2dc827a6a43c144a22ff94861ab38720207bfcd94b ./ha-addon/README.md +8e500c57acbd92551c503cb010ae992c1aac524b3720b1d40043d1c8a22ccac5 ./ha-addon/Dockerfile +adf7ff248d782a3b1cba82b8789c57b6849ddaaaf5fbc108af75e18b1534a885 ./ha-addon/README.md dd9291b12afade6fc20d66e80a5513251270e18e4c265260b2bbbe393a5a94c4 ./ha-addon/build.sh 082dfeb6326f3e1b9841ccf7f2954117ecdf0aa1a90b0aef1e6a1960dacdecbf ./ha-addon/home-assistant/README.md f8e8559fe10fe523ac5bc9aac25c6e26e862f679d502e8f3c39f38a0a8e40911 ./ha-addon/home-assistant/custom_components/gree_controller/__init__.py @@ -21,7 +22,7 @@ b7f0873109c52be9d7f09bea3dffc416103c50085e1f0680d11661a969479898 ./ha-addon/hom 41a8958a6fe6d10e5679c95ac34832583a2a15ecfd67d09b4e094a83d06f5c47 ./ha-addon/home-assistant/custom_components/gree_controller/coordinator.py 5a96fe8f5c035c34f1339370270cd078056202d09e236dec75735be11de92a7d ./ha-addon/home-assistant/custom_components/gree_controller/entity_map.py c4fb75c246db651087900ebfc2291ff41ac87652cd6194fc0b776b0005c1cbcf ./ha-addon/home-assistant/custom_components/gree_controller/icon.png -3af12a645805dd8f70be900d1f962be1dfef1c252ba5d2f72bef89c1e4ed7587 ./ha-addon/home-assistant/custom_components/gree_controller/manifest.json +55d35c83df15e87c1e8a44120dc4bf8187b29cc880d8817d857bc15976114c51 ./ha-addon/home-assistant/custom_components/gree_controller/manifest.json c52a484b671ce738ecc00228a1db19a5d703f69ab27530c2896a5c2ae3b4a96f ./ha-addon/home-assistant/custom_components/gree_controller/number.py 39c4309001b75abb56234f05662bc06e077054986876f1927937edbce528ec95 ./ha-addon/home-assistant/custom_components/gree_controller/select.py cca65482e36d48035aca178121a378fe7d578d600acff267ae81a6399c0da653 ./ha-addon/home-assistant/custom_components/gree_controller/sensor.py @@ -29,10 +30,10 @@ cca65482e36d48035aca178121a378fe7d578d600acff267ae81a6399c0da653 ./ha-addon/hom 6bddb7b4620021ecd2099a86a77ef5c7f2c2dcd3d07d5db4e7b4c4ce6d3e8c03 ./ha-addon/home-assistant/custom_components/gree_controller/translations/en.json 13f30e2dcdcedbd1b6c3f99c2335e0487108fd72c8e86922368b84f2fa2038ae ./ha-addon/home-assistant/custom_components/gree_controller/translations/pl.json c5fc5c87273d82d2834a0a5a365c821a416413ed509613441e24e4dc3507c4d2 ./ha-addon/home-assistant/generated/gree_controller_entities.example.json -6339b12ea19bcde3628ac34cc7b65fd971e3e44bcaf28c7a144fa8042a25aada ./ha-addon/repository/gree-controller/CHANGELOG.md +88e6f4f911b3454fbdfc7d5cb9ea405d850f476f95f261e2fce03f45d4e4d6e7 ./ha-addon/repository/gree-controller/CHANGELOG.md 1b5599195329cc3e643c23aa1caadcec80f133e8e515eec7d92b9f3cbda5b80b ./ha-addon/repository/gree-controller/DOCS.md c3db302f38d26dc9f8caf37a1a8a07a1334cc07ae301d452f2940a5ec5915719 ./ha-addon/repository/gree-controller/README.md -a07415454295755b8920fe305deff439e6ebc79f0f4ba184cd3ae91d41c8d420 ./ha-addon/repository/gree-controller/config.yaml +78898b62a10a4929fee6f1ccd1778620397a2aa55eb639d99e2061a7b58a57d6 ./ha-addon/repository/gree-controller/config.yaml 3aae6cdae4c3aaab7786a9575e7093b7e2c5b69288167075f4b7475611691a6b ./ha-addon/repository/gree-controller/topologia-ha-vlan-gree-pl.png 0d0b42a7639b128946eec379175436fa1f150294f39d2dfd169077bfa87fd14d ./ha-addon/repository/gree-controller/topology-ha-vlan-gree-en.png 2272740b185e9520e948f74b8f45cf98b8b5fd28c93bdee760da626f91fe5c2a ./ha-addon/repository/gree-controller/translations/en.yaml @@ -209,7 +210,7 @@ e98bdd7204349cce1ec6f57283509697af0bbc72280622a6c3efa6fed242db4f ./web/favicon. 5c46d271550f3db38ecbfc09e3a620f6f0e6a907a3d6d56feae9b08e894df196 ./web/js/core.js 752b3c3b59558b42d867d4a15329238f0213f354b76f7011c10e31b4e6dbb311 ./web/js/dashboard.js 0f975542ae1d9bd7216123dd3718be6e9a25dbe643eb899c67024d293940fae5 ./web/js/entities.js -7c08eb200684e6fff521db589fd4417eea050f4eac02f9a2e6b53d212dd33f75 ./web/js/events.js +aaa874637d4a63876aa1248f995190316de80031b4bbcac1e8943238d2bafb53 ./web/js/events.js 473511ca11a0412a794b20430c077843072e9abe0d2510552ac83b226c381453 ./web/js/flows.js a3d9f77a40a2574a668855125c781c067289944c6f93179ff23e3dae150e7dac ./web/js/forms.js edde2969c9c1376f4df37224daa291256ebbbe713903d98e26b6aaa6ca467911 ./web/js/history.js @@ -218,8 +219,8 @@ edde2969c9c1376f4df37224daa291256ebbbe713903d98e26b6aaa6ca467911 ./web/js/histo 799613c6d465cb2f92ecb57cb082d0c33729a03d88ab4ca7fa12a3cbd7e38e75 ./web/js/realtime.js 9546ca5c5566994aff3c33d92295be46b65d51d874681764abe77470dc9c9c73 ./web/js/router.js c2710fd9c1f2b31878c1e25ceb02d74ae30456c1bbb400e69fcf7619ecc72bc2 ./web/js/select-ui.js -420cc44008d739ece4031093db772cc2bd6cdc0573b971b04ccce2aedb5762dd ./web/js/settings-ui.js -9f50794a92059357301b4c920b066bdb20ce1f64fbccea42effcd196d0a00cc4 ./web/js/settings.js +f7245f0e6cb5011196704f201675ebc6c19d902b8253ffcdbf9ead46cb1c6f86 ./web/js/settings-ui.js +335317bd50dd411f8c5e6d00b22d30e53172484626f2ad9901e32cab469724ac ./web/js/settings.js 3815fea7ae1694568c2f249bc8460e0563ced6bde89214f74f21b41fe8cad9a6 ./web/lang-init.js 6b653e4fe2d4db4ffae6ff8f39b8ce57a10a990dc0000ee4aae51d949afadd52 ./web/manifest.webmanifest 0efe0cdff18beff496017a984f6d189ea6463e14b517f2f5c5fc46923579ab15 ./web/styles.css diff --git a/docs/API.md b/docs/API.md index 9dcc79b..b6a6925 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.14.18**. +HTTP and WebSocket API for GREE Controller **0.14.19**. [← Main documentation](../README.md) @@ -239,7 +239,7 @@ Response: { "status": "ok", "name": "gree-controller", - "version": "0.14.18", + "version": "0.14.19", "uptime_seconds": 1234, "control_ready": true, "time": "2026-08-30T06:54:00Z" @@ -302,7 +302,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.14.18", + "version": "0.14.19", "uptime_seconds": 1234, "auth_required": false, "control_ready": true, diff --git a/docs/openapi.json b/docs/openapi.json index c8373ab..873f8fe 100644 --- a/docs/openapi.json +++ b/docs/openapi.json @@ -2,9 +2,9 @@ "openapi": "3.1.0", "info": { "title": "GREE Controller API", - "version": "0.14.18", + "version": "0.14.19", "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\nAdministrator endpoints accept `Authorization: Bearer ` or `x-api-token: ` when configured. Restricted Home Assistant control endpoints also accept generated integration tokens.\n\n### Local and GREE Cloud\nDevices use one API model and one command surface. `connection_type=local` is dispatched only to the existing LAN/UDP provider; `connection_type=gree_cloud` is dispatched only to the GREE Cloud provider. No automatic transport fallback is performed.\n\n### GREE Cloud security\nCloud passwords, REST/MQTT tokens, Authorization values and device cipher keys are never returned in normal API responses or Cloud diagnostics. MQTT uses TLS with certificate and hostname validation.\n\n### Energy\nGREE Cloud `ElcAll` and selected Home Assistant cumulative energy sensors are normalized to kWh and converted to consumption deltas before aggregation. Raw cumulative values are retained only as meter samples/baselines.\n\n### 0.14.18\nShared Web UI CSS now uses generic reusable class names for segmented tabs, configuration layouts, chart cards, enable toggles, diagram primitives and Flow block categories; behavior and visual styling are unchanged.\n\n### 0.14.17\nHistory navigation now reuses the same segmented tab component as Flow / Schedules / Automations, with redundant History-specific tab CSS removed.\n\n### 0.14.16\nCustom Charts now expose saved-chart editing in the Web UI, public chart pages can switch history range through an optional hours override, and the standalone chart layout fits the viewport without vertical page scrolling.\n\n### 0.14.15\nHome Assistant add-on Custom Chart links now resolve the primary HA host IPv4 through Supervisor, support an explicit public_chart_base_url override, and enforce the fixed 8787 ingress/application port contract at startup and build time. Standalone bind/port behavior remains configurable.\n\n### 0.14.14\nShared Flow input Home Assistant sources now expose a dedicated entity search box separate from the selected entity_id, making large live entity catalogs easy to filter by name, ID and state.\n\n### 0.14.13\nHome Assistant add-on authentication is now hidden behind an automatic Supervisor status, manual URL/token fallback is unlocked only after a failed HA test, connection tests return a live sample entity reading, and Shared Flow input HA sources include searchable live entity suggestions.\n\n### 0.14.12\nThe Home Assistant add-on now uses the Supervisor Core API proxy and runtime SUPERVISOR_TOKEN automatically; standalone Home Assistant URL/token configuration is unchanged.\n\n### 0.14.11\nWeb UI icons now use a shared inline SVG set instead of font-dependent Unicode glyphs across navigation, dialogs, Flow, charts, controls and event categories for consistent cross-platform rendering.\n\n\n### 0.14.10\nNight mode and Home Assistant / Sensors standalone settings now use the full available page width, matching the other Web UI sections.\n\n### 0.14.9\nPower controls use an embedded SVG icon instead of a font-dependent Unicode glyph. Home Assistant room-sensor stale/error events identify the affected entity and zone, and historical event rows can recover that context from metadata.\n\n### 0.14.8\nRemaining Home Assistant and notification diagnostic errors no longer use device-transport 502 responses. Missing/invalid integration configuration returns 400, configured external dependency failures return 424, and 502 is reserved for Local/LAN GREE device communication.\n\n### 0.14.7\nHome Assistant energy-sensor discovery now returns an empty optional result when HA is not configured, uses 424 for configured external-dependency failures, and custom select popovers use their rendered height when positioning above a field.\n\n\n### 0.14.6\nFixes dynamic custom-select duplication in History → Energy and hides Energy history controls when no energy source is configured.\n\n### 0.14.5\nWeb UI single-choice controls now use one consistent custom dropdown, language packs are loaded on demand, and the dashboard outdoor temperature opens a 24-hour history modal.\n\n### 0.14.4\nHome Assistant connection tests validate only the configured server/API token and require no entity. `outdoor_entity_id` is the global Home Assistant outdoor-temperature sensor; zones can override it with `ha_outdoor_entity_id`. Room-temperature Home Assistant sensors remain configured per zone with `ha_entity_id`. Global/per-zone outdoor sensors are integrated with aliases, metrics/history and Visual Flow entity suggestions.\n\n### 0.14.2\nAdds independent vertical/horizontal swing controls across manual device control, thermostat zones, legacy automations, Visual Flow and Home Assistant zone climates. Swing is treated as an auxiliary one-shot unit setting and does not replace thermostat ownership.\n\n### 0.14.1\nAdds split/multisplit installation groups with shared energy and outdoor-temperature sources, multi-target energy charts with period comparison, cleaner Cloud status/alerts and safe MQTT cleanup after the last Cloud device is removed.\n\n### 0.14.0\nAdds first-class GREE Cloud MQTT status/control, reconnect/resubscribe lifecycle, Cloud diagnostics, per-device capabilities, Cloud/HA energy sources and energy-history aggregation while preserving the LAN transport contract.", + "description": "Self-hosted API used by the GREE Controller Web UI and Home Assistant integration.\n\n### Authentication\nAdministrator endpoints accept `Authorization: Bearer ` or `x-api-token: ` when configured. Restricted Home Assistant control endpoints also accept generated integration tokens.\n\n### Local and GREE Cloud\nDevices use one API model and one command surface. `connection_type=local` is dispatched only to the existing LAN/UDP provider; `connection_type=gree_cloud` is dispatched only to the GREE Cloud provider. No automatic transport fallback is performed.\n\n### GREE Cloud security\nCloud passwords, REST/MQTT tokens, Authorization values and device cipher keys are never returned in normal API responses or Cloud diagnostics. MQTT uses TLS with certificate and hostname validation.\n\n### Energy\nGREE Cloud `ElcAll` and selected Home Assistant cumulative energy sensors are normalized to kWh and converted to consumption deltas before aggregation. Raw cumulative values are retained only as meter samples/baselines.\n\n### 0.14.19\nHome Assistant OCI builds now compile Rust for amd64/arm64 on the native build platform through xx cross-compilation, keep Cargo registry/target caches between builds, and send a smaller Docker context while preserving the selected Alpine (musl) or Debian Trixie (glibc) runtime. The Web UI also deduplicates the initial GREE Cloud runtime-status GET across the HTTP and WebSocket bootstrap renders.\n\n### 0.14.18\nShared Web UI CSS now uses generic reusable class names for segmented tabs, configuration layouts, chart cards, enable toggles, diagram primitives and Flow block categories; behavior and visual styling are unchanged.\n\n### 0.14.17\nHistory navigation now reuses the same segmented tab component as Flow / Schedules / Automations, with redundant History-specific tab CSS removed.\n\n### 0.14.16\nCustom Charts now expose saved-chart editing in the Web UI, public chart pages can switch history range through an optional hours override, and the standalone chart layout fits the viewport without vertical page scrolling.\n\n### 0.14.15\nHome Assistant add-on Custom Chart links now resolve the primary HA host IPv4 through Supervisor, support an explicit public_chart_base_url override, and enforce the fixed 8787 ingress/application port contract at startup and build time. Standalone bind/port behavior remains configurable.\n\n### 0.14.14\nShared Flow input Home Assistant sources now expose a dedicated entity search box separate from the selected entity_id, making large live entity catalogs easy to filter by name, ID and state.\n\n### 0.14.13\nHome Assistant add-on authentication is now hidden behind an automatic Supervisor status, manual URL/token fallback is unlocked only after a failed HA test, connection tests return a live sample entity reading, and Shared Flow input HA sources include searchable live entity suggestions.\n\n### 0.14.12\nThe Home Assistant add-on now uses the Supervisor Core API proxy and runtime SUPERVISOR_TOKEN automatically; standalone Home Assistant URL/token configuration is unchanged.\n\n### 0.14.11\nWeb UI icons now use a shared inline SVG set instead of font-dependent Unicode glyphs across navigation, dialogs, Flow, charts, controls and event categories for consistent cross-platform rendering.\n\n\n### 0.14.10\nNight mode and Home Assistant / Sensors standalone settings now use the full available page width, matching the other Web UI sections.\n\n### 0.14.9\nPower controls use an embedded SVG icon instead of a font-dependent Unicode glyph. Home Assistant room-sensor stale/error events identify the affected entity and zone, and historical event rows can recover that context from metadata.\n\n### 0.14.8\nRemaining Home Assistant and notification diagnostic errors no longer use device-transport 502 responses. Missing/invalid integration configuration returns 400, configured external dependency failures return 424, and 502 is reserved for Local/LAN GREE device communication.\n\n### 0.14.7\nHome Assistant energy-sensor discovery now returns an empty optional result when HA is not configured, uses 424 for configured external-dependency failures, and custom select popovers use their rendered height when positioning above a field.\n\n\n### 0.14.6\nFixes dynamic custom-select duplication in History → Energy and hides Energy history controls when no energy source is configured.\n\n### 0.14.5\nWeb UI single-choice controls now use one consistent custom dropdown, language packs are loaded on demand, and the dashboard outdoor temperature opens a 24-hour history modal.\n\n### 0.14.4\nHome Assistant connection tests validate only the configured server/API token and require no entity. `outdoor_entity_id` is the global Home Assistant outdoor-temperature sensor; zones can override it with `ha_outdoor_entity_id`. Room-temperature Home Assistant sensors remain configured per zone with `ha_entity_id`. Global/per-zone outdoor sensors are integrated with aliases, metrics/history and Visual Flow entity suggestions.\n\n### 0.14.2\nAdds independent vertical/horizontal swing controls across manual device control, thermostat zones, legacy automations, Visual Flow and Home Assistant zone climates. Swing is treated as an auxiliary one-shot unit setting and does not replace thermostat ownership.\n\n### 0.14.1\nAdds split/multisplit installation groups with shared energy and outdoor-temperature sources, multi-target energy charts with period comparison, cleaner Cloud status/alerts and safe MQTT cleanup after the last Cloud device is removed.\n\n### 0.14.0\nAdds first-class GREE Cloud MQTT status/control, reconnect/resubscribe lifecycle, Cloud diagnostics, per-device capabilities, Cloud/HA energy sources and energy-history aggregation while preserving the LAN transport contract.", "license": { "name": "MIT" } @@ -5830,7 +5830,7 @@ }, "version": { "type": "string", - "example": "0.14.18" + "example": "0.14.19" }, "uptime_seconds": { "type": "integer", diff --git a/ha-addon/Dockerfile b/ha-addon/Dockerfile index 5188ce7..bd7cd76 100644 --- a/ha-addon/Dockerfile +++ b/ha-addon/Dockerfile @@ -1,29 +1,67 @@ # syntax=docker/dockerfile:1.7 ARG RUST_VERSION=1.89 +ARG XX_VERSION=1.9.0 -FROM --platform=$TARGETPLATFORM rust:${RUST_VERSION}-trixie AS builder-trixie +# Cross-compilation helpers. Builder stages always run on BUILDPLATFORM, so an +# amd64 host can compile arm64 without running rustc/cargo under QEMU. +FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx + +FROM --platform=$BUILDPLATFORM rust:${RUST_VERSION}-trixie AS builder-trixie +COPY --from=xx / / WORKDIR /src RUN apt-get update \ - && apt-get install -y --no-install-recommends build-essential pkg-config \ - && rm -rf /var/lib/apt/lists/* -COPY Cargo.toml Cargo.lock build.rs ./ + && apt-get install -y --no-install-recommends clang lld llvm file pkg-config +ARG TARGETPLATFORM +RUN xx-apt-get update \ + && xx-apt-get install -y --no-install-recommends xx-c-essentials \ + && rm -rf /var/lib/apt/lists/* \ + && xx-cargo --version >/dev/null +COPY Cargo.toml Cargo.lock ./ +RUN --mount=type=cache,id=gree-controller-cargo-registry,target=/usr/local/cargo/registry \ + --mount=type=cache,id=gree-controller-cargo-git,target=/usr/local/cargo/git \ + cargo fetch --locked +COPY build.rs ./ COPY src ./src COPY web ./web COPY lang ./lang COPY presets ./presets -COPY docs ./docs -RUN cargo build --locked --release +COPY docs/openapi.json ./docs/openapi.json +RUN --mount=type=cache,id=gree-controller-cargo-registry,target=/usr/local/cargo/registry \ + --mount=type=cache,id=gree-controller-cargo-git,target=/usr/local/cargo/git \ + --mount=type=cache,id=gree-controller-target-trixie,target=/src/target \ + set -eux; \ + xx-cargo build --locked --release --target-dir /src/target; \ + binary="/src/target/$(xx-cargo --print-target-triple)/release/gree-controller"; \ + xx-verify "$binary"; \ + mkdir -p /out; \ + cp "$binary" /out/gree-controller -FROM --platform=$TARGETPLATFORM rust:${RUST_VERSION}-alpine AS builder-alpine +FROM --platform=$BUILDPLATFORM rust:${RUST_VERSION}-alpine AS builder-alpine +COPY --from=xx / / WORKDIR /src -RUN apk add --no-cache build-base pkgconfig musl-dev -COPY Cargo.toml Cargo.lock build.rs ./ +RUN apk add --no-cache clang lld llvm file pkgconf +ARG TARGETPLATFORM +RUN xx-apk add --no-cache xx-c-essentials \ + && xx-cargo --version >/dev/null +COPY Cargo.toml Cargo.lock ./ +RUN --mount=type=cache,id=gree-controller-cargo-registry,target=/usr/local/cargo/registry \ + --mount=type=cache,id=gree-controller-cargo-git,target=/usr/local/cargo/git \ + cargo fetch --locked +COPY build.rs ./ COPY src ./src COPY web ./web COPY lang ./lang COPY presets ./presets -COPY docs ./docs -RUN cargo build --locked --release +COPY docs/openapi.json ./docs/openapi.json +RUN --mount=type=cache,id=gree-controller-cargo-registry,target=/usr/local/cargo/registry \ + --mount=type=cache,id=gree-controller-cargo-git,target=/usr/local/cargo/git \ + --mount=type=cache,id=gree-controller-target-alpine,target=/src/target \ + set -eux; \ + xx-cargo build --locked --release --target-dir /src/target; \ + binary="/src/target/$(xx-cargo --print-target-triple)/release/gree-controller"; \ + xx-verify "$binary"; \ + mkdir -p /out; \ + cp "$binary" /out/gree-controller FROM --platform=$TARGETPLATFORM debian:trixie-slim AS runtime-trixie ARG BUILD_VERSION=dev @@ -39,7 +77,7 @@ LABEL io.hass.version="${BUILD_VERSION}" \ RUN apt-get update \ && apt-get install -y --no-install-recommends ca-certificates tzdata jq iproute2 curl \ && rm -rf /var/lib/apt/lists/* -COPY --from=builder-trixie /src/target/release/gree-controller /usr/local/bin/gree-controller +COPY --from=builder-trixie /out/gree-controller /usr/local/bin/gree-controller COPY ha-addon/run.sh /usr/local/bin/run.sh RUN chmod 0755 /usr/local/bin/run.sh /usr/local/bin/gree-controller EXPOSE 8787/tcp @@ -57,7 +95,7 @@ LABEL io.hass.version="${BUILD_VERSION}" \ org.opencontainers.image.version="${BUILD_VERSION}" \ org.opencontainers.image.architecture="${TARGETARCH}" RUN apk add --no-cache ca-certificates tzdata jq iproute2 curl -COPY --from=builder-alpine /src/target/release/gree-controller /usr/local/bin/gree-controller +COPY --from=builder-alpine /out/gree-controller /usr/local/bin/gree-controller COPY ha-addon/run.sh /usr/local/bin/run.sh RUN chmod 0755 /usr/local/bin/run.sh /usr/local/bin/gree-controller EXPOSE 8787/tcp diff --git a/ha-addon/README.md b/ha-addon/README.md index 47bd715..3f002c4 100644 --- a/ha-addon/README.md +++ b/ha-addon/README.md @@ -44,6 +44,8 @@ The project version comes only from root `Cargo.toml`. `render` synchronizes it For the Home Assistant package, TCP `8787` is an intentional fixed host-network/ingress port contract. `build.sh render` verifies `config.yaml`, `run.sh`, the watchdog URL and Docker image metadata stay consistent. The runtime also compares the Supervisor-reported ingress port before starting. Standalone installations remain free to use any `GREE_CONTROLLER_BIND` port. +`DISTRO` still selects the target image system: `alpine` builds a musl binary for Alpine and `trixie` builds a GNU/glibc binary for Debian Trixie. Multi-architecture builds continue to run through `build.sh`; the Docker builder cross-compiles Rust on `BUILDPLATFORM` so ARM compilation does not run under QEMU, and BuildKit cache mounts preserve Cargo downloads and target artifacts between builds. + ## Home Assistant repository ```bash diff --git a/ha-addon/home-assistant/custom_components/gree_controller/manifest.json b/ha-addon/home-assistant/custom_components/gree_controller/manifest.json index d5c3300..18af4e6 100644 --- a/ha-addon/home-assistant/custom_components/gree_controller/manifest.json +++ b/ha-addon/home-assistant/custom_components/gree_controller/manifest.json @@ -1,7 +1,7 @@ { "domain": "gree_controller", "name": "GREE Controller", - "version": "0.14.18", + "version": "0.14.19", "config_flow": true, "integration_type": "hub", "iot_class": "local_polling", diff --git a/ha-addon/repository/gree-controller/CHANGELOG.md b/ha-addon/repository/gree-controller/CHANGELOG.md index d8e429a..6143841 100644 --- a/ha-addon/repository/gree-controller/CHANGELOG.md +++ b/ha-addon/repository/gree-controller/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.14.19 + +- Speeds up multi-architecture OCI builds by running Rust/Cargo on `BUILDPLATFORM` and cross-compiling to amd64/arm64 instead of compiling ARM under QEMU. +- Keeps `DISTRO=alpine` as a musl/Alpine target and `DISTRO=trixie` as a GNU/glibc Debian Trixie target; `build.sh` remains the build entry point. +- Adds persistent BuildKit caches for Cargo registry/git data and compiled target artifacts; target Rust/C toolchains are prepared before project manifests so normal version/source changes keep the cross-toolchain layer cached. +- Reduces Docker build context and avoids invalidating Rust compilation for unrelated documentation/repository changes; only `docs/openapi.json` is copied because it is embedded by the binary. +- Deduplicates `/api/integrations/gree-cloud/status` across the initial HTTP bootstrap and immediate WebSocket bootstrap render while keeping manual Cloud reconnect refreshes forced. + ## 0.14.18 - Renames the shared segmented navigation class from feature-specific `automation-tabs` to generic `segmented-tabs`. diff --git a/ha-addon/repository/gree-controller/config.yaml b/ha-addon/repository/gree-controller/config.yaml index 1d205f3..80568e7 100644 --- a/ha-addon/repository/gree-controller/config.yaml +++ b/ha-addon/repository/gree-controller/config.yaml @@ -1,5 +1,5 @@ name: "GREE Controller" -version: "0.14.18" +version: "0.14.19" slug: "gree_controller" description: "Local GREE HVAC controller with Web UI and Home Assistant integration" url: "https://git.linuxiarz.pl/gru/gree-controller-ha-addon/" diff --git a/web/js/events.js b/web/js/events.js index 9b526cf..b315533 100644 --- a/web/js/events.js +++ b/web/js/events.js @@ -646,7 +646,7 @@ $('#greeCloudReconnectButton')?.addEventListener('click', async event => { try { button.disabled = true; await api('/api/integrations/gree-cloud/reconnect', { method: 'POST' }); - await refreshGreeCloudRuntimeStatus(); + await refreshGreeCloudRuntimeStatus({ force: true }); toast(tr('common.saved')); } catch (error) { toast(error.message, true); diff --git a/web/js/settings-ui.js b/web/js/settings-ui.js index aa7a262..1ef854d 100644 --- a/web/js/settings-ui.js +++ b/web/js/settings-ui.js @@ -584,7 +584,36 @@ function formatDuration(seconds) { setInterval(() => { if (app.currentView === 'settings') renderSystemInfo(); }, 30000); -async function refreshGreeCloudRuntimeStatus() { +let greeCloudRuntimeStatusCache = null; +let greeCloudRuntimeStatusCachedAt = 0; +let greeCloudRuntimeStatusRequest = null; +const GREE_CLOUD_RUNTIME_STATUS_CACHE_MS = 5000; + +function invalidateGreeCloudRuntimeStatusCache() { + greeCloudRuntimeStatusCache = null; + greeCloudRuntimeStatusCachedAt = 0; +} + +async function getGreeCloudRuntimeStatus(force = false) { + const now = Date.now(); + if (!force && greeCloudRuntimeStatusCache && now - greeCloudRuntimeStatusCachedAt < GREE_CLOUD_RUNTIME_STATUS_CACHE_MS) { + return greeCloudRuntimeStatusCache; + } + if (!force && greeCloudRuntimeStatusRequest) return greeCloudRuntimeStatusRequest; + + const request = api('/api/integrations/gree-cloud/status'); + if (!force) greeCloudRuntimeStatusRequest = request; + try { + const status = await request; + greeCloudRuntimeStatusCache = status; + greeCloudRuntimeStatusCachedAt = Date.now(); + return status; + } finally { + if (greeCloudRuntimeStatusRequest === request) greeCloudRuntimeStatusRequest = null; + } +} + +async function refreshGreeCloudRuntimeStatus({ force = false } = {}) { const summary = $('.cloud-runtime-summary'); if (!summary) return; const metricSelectors = [ @@ -602,7 +631,7 @@ async function refreshGreeCloudRuntimeStatus() { const lastContact = $('#greeCloudLastContact'); const lastContactRow = lastContact?.closest('small'); try { - const status = await api('/api/integrations/gree-cloud/status'); + const status = await getGreeCloudRuntimeStatus(force); const runtime = status.runtime || {}; const enabled = status.enabled === true; const deviceCount = Number(status.device_count || 0); diff --git a/web/js/settings.js b/web/js/settings.js index ec6ee99..fe5db10 100644 --- a/web/js/settings.js +++ b/web/js/settings.js @@ -181,6 +181,7 @@ async function saveMainSettings(form, notify = true) { applySettingsSection('application', application); applySettingsSection('gree', gree); applySettingsSection('greeCloud', greeCloud); + invalidateGreeCloudRuntimeStatusCache(); applySettingsSection('history', history); applySettingsSection('influxdb', influxdb); applySettingsSection('notifications', notifications); @@ -474,6 +475,7 @@ document.addEventListener('click', event => { async function saveGreeCloudSettings(form = $('#settingsForm')) { const data = await api(SETTINGS_ENDPOINTS.greeCloud, { method: 'PUT', body: greeCloudSettingsBodyFromForm(form) }); applySettingsSection('greeCloud', data); + invalidateGreeCloudRuntimeStatusCache(); return data; }