v0.14.24
This commit is contained in:
Generated
+1
-1
@@ -700,7 +700,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gree-controller"
|
name = "gree-controller"
|
||||||
version = "0.14.23"
|
version = "0.14.24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"aes-gcm",
|
"aes-gcm",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "gree-controller"
|
name = "gree-controller"
|
||||||
version = "0.14.23"
|
version = "0.14.24"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = ["GREE Controller contributors"]
|
authors = ["GREE Controller contributors"]
|
||||||
description = "Standalone local GREE HVAC controller with Web UI, SQLite and Home Assistant sensor support"
|
description = "Standalone local GREE HVAC controller with Web UI, SQLite and Home Assistant sensor support"
|
||||||
|
|||||||
+11
-11
@@ -1,14 +1,14 @@
|
|||||||
de0793949cf01d27d903653226ecc9b5f72523d8711f20bcab022cf42c4c4ed0 ./.env.example
|
de0793949cf01d27d903653226ecc9b5f72523d8711f20bcab022cf42c4c4ed0 ./.env.example
|
||||||
a4ec3874a2e3ab1bad28fb40bb620f7b01f64d01ad9b699306bf70ada31227db ./.gitignore
|
a4ec3874a2e3ab1bad28fb40bb620f7b01f64d01ad9b699306bf70ada31227db ./.gitignore
|
||||||
9016ecffc9cc145fe5c2cee1e097b170de5c71a6f9c971331f5ee388c2d0509c ./Cargo.lock
|
f71644d81f7f91aee248bf6f61d711a8429694dae6a785706679468cde082e28 ./Cargo.lock
|
||||||
f22febd60f53442e200fd1cb2d077d55319918a034812645f96f07d70abace89 ./Cargo.toml
|
ed4fcc9fcf0d11995f086047c5876787e035a539d0aa588397f90862686adab1 ./Cargo.toml
|
||||||
19b2943504acb8f8de280f873a8dbec4bb6ebbe3870b158f5655d4fb8c298f5f ./LICENSE
|
19b2943504acb8f8de280f873a8dbec4bb6ebbe3870b158f5655d4fb8c298f5f ./LICENSE
|
||||||
120d48f01abeee74e84d4257bffc1fe7da9e8b3a07a048284b2c18ea273b07a6 ./README.md
|
9b0edc59898f7fdfa169cacc17b9c3307fd555cd9c4ca4079b534d0ae2437d23 ./README.md
|
||||||
83dbdd1c6acd9ffbab24d367b70ce20c59bf03d6a545b6bac8348145c777cdc2 ./SOURCE_MANIFEST.sha256
|
67fc31faccb818e097c4ee5fd54c5929c6a1d63cf12cc36c652d6562a3bc82cd ./SOURCE_MANIFEST.sha256
|
||||||
29e9821e5ed216ea3565dd6d8bc0b174ed3cf9fa72c4ccebbfa99e98db3ad8f9 ./build.rs
|
29e9821e5ed216ea3565dd6d8bc0b174ed3cf9fa72c4ccebbfa99e98db3ad8f9 ./build.rs
|
||||||
27203e279ab83dd2ff638db02d23d4b00f8864c92f09e8ed3194574b989c43ae ./docs/API.md
|
dfb2736a61aa52634a0ac23fe379baf5f6c03e04837356a1c0ff93e25dc41832 ./docs/API.md
|
||||||
8b548d02dbdf0563f2be617a1d677459bd1959bed93a1799a01bf61bb5aed405 ./docs/FLOW.md
|
8b548d02dbdf0563f2be617a1d677459bd1959bed93a1799a01bf61bb5aed405 ./docs/FLOW.md
|
||||||
bd95027c838d47f4829082c29d2d8b108d56cbd37230f8b894e954208ef18a37 ./docs/openapi.json
|
d9bf3a1644ed3628bd574109602857d7e425a272b9d168416911a8d93bf6f8c5 ./docs/openapi.json
|
||||||
c65aa543d2e99f8f7d52736307b07ebd182597d80124661d53a16bb23f6f1118 ./ha-addon/.env.example
|
c65aa543d2e99f8f7d52736307b07ebd182597d80124661d53a16bb23f6f1118 ./ha-addon/.env.example
|
||||||
0993076ca45b6d31859680835204cdc111b3f9bdbf460d50b4efec56cd5e685b ./ha-addon/Dockerfile
|
0993076ca45b6d31859680835204cdc111b3f9bdbf460d50b4efec56cd5e685b ./ha-addon/Dockerfile
|
||||||
adf7ff248d782a3b1cba82b8789c57b6849ddaaaf5fbc108af75e18b1534a885 ./ha-addon/README.md
|
adf7ff248d782a3b1cba82b8789c57b6849ddaaaf5fbc108af75e18b1534a885 ./ha-addon/README.md
|
||||||
@@ -22,7 +22,7 @@ b7f0873109c52be9d7f09bea3dffc416103c50085e1f0680d11661a969479898 ./ha-addon/hom
|
|||||||
41a8958a6fe6d10e5679c95ac34832583a2a15ecfd67d09b4e094a83d06f5c47 ./ha-addon/home-assistant/custom_components/gree_controller/coordinator.py
|
41a8958a6fe6d10e5679c95ac34832583a2a15ecfd67d09b4e094a83d06f5c47 ./ha-addon/home-assistant/custom_components/gree_controller/coordinator.py
|
||||||
5a96fe8f5c035c34f1339370270cd078056202d09e236dec75735be11de92a7d ./ha-addon/home-assistant/custom_components/gree_controller/entity_map.py
|
5a96fe8f5c035c34f1339370270cd078056202d09e236dec75735be11de92a7d ./ha-addon/home-assistant/custom_components/gree_controller/entity_map.py
|
||||||
c4fb75c246db651087900ebfc2291ff41ac87652cd6194fc0b776b0005c1cbcf ./ha-addon/home-assistant/custom_components/gree_controller/icon.png
|
c4fb75c246db651087900ebfc2291ff41ac87652cd6194fc0b776b0005c1cbcf ./ha-addon/home-assistant/custom_components/gree_controller/icon.png
|
||||||
3235e64a80782c561645e4bad4444e2409a19b4d1f8f4c93a0296a443d6cca3b ./ha-addon/home-assistant/custom_components/gree_controller/manifest.json
|
37ce45f7e9a9fdf258ee1e97ca47599a86b33017e0c52227cdfc900f637b7f80 ./ha-addon/home-assistant/custom_components/gree_controller/manifest.json
|
||||||
c52a484b671ce738ecc00228a1db19a5d703f69ab27530c2896a5c2ae3b4a96f ./ha-addon/home-assistant/custom_components/gree_controller/number.py
|
c52a484b671ce738ecc00228a1db19a5d703f69ab27530c2896a5c2ae3b4a96f ./ha-addon/home-assistant/custom_components/gree_controller/number.py
|
||||||
39c4309001b75abb56234f05662bc06e077054986876f1927937edbce528ec95 ./ha-addon/home-assistant/custom_components/gree_controller/select.py
|
39c4309001b75abb56234f05662bc06e077054986876f1927937edbce528ec95 ./ha-addon/home-assistant/custom_components/gree_controller/select.py
|
||||||
cca65482e36d48035aca178121a378fe7d578d600acff267ae81a6399c0da653 ./ha-addon/home-assistant/custom_components/gree_controller/sensor.py
|
cca65482e36d48035aca178121a378fe7d578d600acff267ae81a6399c0da653 ./ha-addon/home-assistant/custom_components/gree_controller/sensor.py
|
||||||
@@ -30,10 +30,10 @@ cca65482e36d48035aca178121a378fe7d578d600acff267ae81a6399c0da653 ./ha-addon/hom
|
|||||||
6bddb7b4620021ecd2099a86a77ef5c7f2c2dcd3d07d5db4e7b4c4ce6d3e8c03 ./ha-addon/home-assistant/custom_components/gree_controller/translations/en.json
|
6bddb7b4620021ecd2099a86a77ef5c7f2c2dcd3d07d5db4e7b4c4ce6d3e8c03 ./ha-addon/home-assistant/custom_components/gree_controller/translations/en.json
|
||||||
13f30e2dcdcedbd1b6c3f99c2335e0487108fd72c8e86922368b84f2fa2038ae ./ha-addon/home-assistant/custom_components/gree_controller/translations/pl.json
|
13f30e2dcdcedbd1b6c3f99c2335e0487108fd72c8e86922368b84f2fa2038ae ./ha-addon/home-assistant/custom_components/gree_controller/translations/pl.json
|
||||||
c5fc5c87273d82d2834a0a5a365c821a416413ed509613441e24e4dc3507c4d2 ./ha-addon/home-assistant/generated/gree_controller_entities.example.json
|
c5fc5c87273d82d2834a0a5a365c821a416413ed509613441e24e4dc3507c4d2 ./ha-addon/home-assistant/generated/gree_controller_entities.example.json
|
||||||
24f341cd167c903db0522a6a21f0714a7ec19c560be183bed745c50d0d6b599a ./ha-addon/repository/gree-controller/CHANGELOG.md
|
a1cfb2ec0dfc786e8d2c9adad5ad7b62abdf917c0090f06c817e78cd26115683 ./ha-addon/repository/gree-controller/CHANGELOG.md
|
||||||
1b5599195329cc3e643c23aa1caadcec80f133e8e515eec7d92b9f3cbda5b80b ./ha-addon/repository/gree-controller/DOCS.md
|
1b5599195329cc3e643c23aa1caadcec80f133e8e515eec7d92b9f3cbda5b80b ./ha-addon/repository/gree-controller/DOCS.md
|
||||||
c3db302f38d26dc9f8caf37a1a8a07a1334cc07ae301d452f2940a5ec5915719 ./ha-addon/repository/gree-controller/README.md
|
c3db302f38d26dc9f8caf37a1a8a07a1334cc07ae301d452f2940a5ec5915719 ./ha-addon/repository/gree-controller/README.md
|
||||||
c849408ccc076b254f01dc464935812c44e4bbec1e9727cc7664c900d4539563 ./ha-addon/repository/gree-controller/config.yaml
|
e87466f09667d3b7ba35a09e1879cd616ce62c28d99c60363ec835a3bb07ffa6 ./ha-addon/repository/gree-controller/config.yaml
|
||||||
3aae6cdae4c3aaab7786a9575e7093b7e2c5b69288167075f4b7475611691a6b ./ha-addon/repository/gree-controller/topologia-ha-vlan-gree-pl.png
|
3aae6cdae4c3aaab7786a9575e7093b7e2c5b69288167075f4b7475611691a6b ./ha-addon/repository/gree-controller/topologia-ha-vlan-gree-pl.png
|
||||||
0d0b42a7639b128946eec379175436fa1f150294f39d2dfd169077bfa87fd14d ./ha-addon/repository/gree-controller/topology-ha-vlan-gree-en.png
|
0d0b42a7639b128946eec379175436fa1f150294f39d2dfd169077bfa87fd14d ./ha-addon/repository/gree-controller/topology-ha-vlan-gree-en.png
|
||||||
2272740b185e9520e948f74b8f45cf98b8b5fd28c93bdee760da626f91fe5c2a ./ha-addon/repository/gree-controller/translations/en.yaml
|
2272740b185e9520e948f74b8f45cf98b8b5fd28c93bdee760da626f91fe5c2a ./ha-addon/repository/gree-controller/translations/en.yaml
|
||||||
@@ -200,7 +200,7 @@ f13f1be3d5789539eba3fc1b59c14835f8c681eca7634e118fa3763a53aeee2b ./src/queries/
|
|||||||
8c34b70fb5f80e3249c2e0c63686e60ce1697cf44a7e6f11b3ad6f689ce17792 ./src/state.rs
|
8c34b70fb5f80e3249c2e0c63686e60ce1697cf44a7e6f11b3ad6f689ce17792 ./src/state.rs
|
||||||
b92a6cb158b494fe145b43c7641e65f6fafff47201d7d76edbec2cfd8b94835c ./systemd/gree-controller.service
|
b92a6cb158b494fe145b43c7641e65f6fafff47201d7d76edbec2cfd8b94835c ./systemd/gree-controller.service
|
||||||
544a31cb2e5374227026afd6abd0d910381f3fca1638154ebd74e3c3d96a35d1 ./web/404.html
|
544a31cb2e5374227026afd6abd0d910381f3fca1638154ebd74e3c3d96a35d1 ./web/404.html
|
||||||
8b8b5e9511a833d6dc0eb902048e8f48f26395faf55f19962c3e6f06ae0fb4e4 ./web/css/styles.css
|
6531bd30b81e8fe22ce973c2be3308e8ef7e3aa42285d86175b8329f2a670b61 ./web/css/styles.css
|
||||||
183d122ba366303d9952ac0e68aff4bced4e0d9a468fbe51316c13f15227402b ./web/custom-chart.html
|
183d122ba366303d9952ac0e68aff4bced4e0d9a468fbe51316c13f15227402b ./web/custom-chart.html
|
||||||
e98bdd7204349cce1ec6f57283509697af0bbc72280622a6c3efa6fed242db4f ./web/favicon.svg
|
e98bdd7204349cce1ec6f57283509697af0bbc72280622a6c3efa6fed242db4f ./web/favicon.svg
|
||||||
784e2c28effb9872b582298292d3e2a6b8dd6140207342452193894d210e2f45 ./web/index.html
|
784e2c28effb9872b582298292d3e2a6b8dd6140207342452193894d210e2f45 ./web/index.html
|
||||||
@@ -221,7 +221,7 @@ e98bdd7204349cce1ec6f57283509697af0bbc72280622a6c3efa6fed242db4f ./web/favicon.
|
|||||||
c2710fd9c1f2b31878c1e25ceb02d74ae30456c1bbb400e69fcf7619ecc72bc2 ./web/js-dynamic/select-ui.js
|
c2710fd9c1f2b31878c1e25ceb02d74ae30456c1bbb400e69fcf7619ecc72bc2 ./web/js-dynamic/select-ui.js
|
||||||
f7245f0e6cb5011196704f201675ebc6c19d902b8253ffcdbf9ead46cb1c6f86 ./web/js-dynamic/settings-ui.js
|
f7245f0e6cb5011196704f201675ebc6c19d902b8253ffcdbf9ead46cb1c6f86 ./web/js-dynamic/settings-ui.js
|
||||||
672e404470bc6331aa6d658523b221659ec64222af9cc9c17ced978f725790da ./web/js-dynamic/settings.js
|
672e404470bc6331aa6d658523b221659ec64222af9cc9c17ced978f725790da ./web/js-dynamic/settings.js
|
||||||
930777048669688985b494a10dad8e591c82666071bde1018eef8f725a660895 ./web/js/custom-chart.js
|
489ab0208c86f7a2bb0d721106f01fb5d4f39f41e94749b440a6c58e13c4de07 ./web/js/custom-chart.js
|
||||||
6ae536b18db756bf5eda9adb1b8a550d5a02bfc80f0b7da27fa146039f22e884 ./web/js/lang-init.js
|
6ae536b18db756bf5eda9adb1b8a550d5a02bfc80f0b7da27fa146039f22e884 ./web/js/lang-init.js
|
||||||
e3fc113d4c349f33f3faa32e7a46c96a85c71643f43f2e488065dc9715e27333 ./web/js/sw.js
|
e3fc113d4c349f33f3faa32e7a46c96a85c71643f43f2e488065dc9715e27333 ./web/js/sw.js
|
||||||
d505d793ce7cc9485b45b78bba1c0d51887adc7451ab59a42702946e5b991382 ./web/js/theme-init.js
|
d505d793ce7cc9485b45b78bba1c0d51887adc7451ab59a42702946e5b991382 ./web/js/theme-init.js
|
||||||
|
|||||||
@@ -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.
|
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.23**
|
**Version: 0.14.24**
|
||||||
|
|
||||||
Version 0.14.23 includes code cleanup and small UX changes.
|
Version 0.14.24 improves public Custom Charts with single-pass language loading, English 404 fallback, pinch-to-zoom/pan and clickable metric legends, and includes the related public-chart, favicon and access-token fixes.
|
||||||
|
|
||||||
> [Full API reference](docs/API.md) — authentication, every endpoint, request bodies, response models, WebSocket events and examples.
|
> [Full API reference](docs/API.md) — authentication, every endpoint, request bodies, response models, WebSocket events and examples.
|
||||||
|
|
||||||
|
|||||||
+10
-10
@@ -1,13 +1,13 @@
|
|||||||
de0793949cf01d27d903653226ecc9b5f72523d8711f20bcab022cf42c4c4ed0 ./.env.example
|
de0793949cf01d27d903653226ecc9b5f72523d8711f20bcab022cf42c4c4ed0 ./.env.example
|
||||||
a4ec3874a2e3ab1bad28fb40bb620f7b01f64d01ad9b699306bf70ada31227db ./.gitignore
|
a4ec3874a2e3ab1bad28fb40bb620f7b01f64d01ad9b699306bf70ada31227db ./.gitignore
|
||||||
9016ecffc9cc145fe5c2cee1e097b170de5c71a6f9c971331f5ee388c2d0509c ./Cargo.lock
|
f71644d81f7f91aee248bf6f61d711a8429694dae6a785706679468cde082e28 ./Cargo.lock
|
||||||
f22febd60f53442e200fd1cb2d077d55319918a034812645f96f07d70abace89 ./Cargo.toml
|
ed4fcc9fcf0d11995f086047c5876787e035a539d0aa588397f90862686adab1 ./Cargo.toml
|
||||||
19b2943504acb8f8de280f873a8dbec4bb6ebbe3870b158f5655d4fb8c298f5f ./LICENSE
|
19b2943504acb8f8de280f873a8dbec4bb6ebbe3870b158f5655d4fb8c298f5f ./LICENSE
|
||||||
120d48f01abeee74e84d4257bffc1fe7da9e8b3a07a048284b2c18ea273b07a6 ./README.md
|
9b0edc59898f7fdfa169cacc17b9c3307fd555cd9c4ca4079b534d0ae2437d23 ./README.md
|
||||||
29e9821e5ed216ea3565dd6d8bc0b174ed3cf9fa72c4ccebbfa99e98db3ad8f9 ./build.rs
|
29e9821e5ed216ea3565dd6d8bc0b174ed3cf9fa72c4ccebbfa99e98db3ad8f9 ./build.rs
|
||||||
27203e279ab83dd2ff638db02d23d4b00f8864c92f09e8ed3194574b989c43ae ./docs/API.md
|
dfb2736a61aa52634a0ac23fe379baf5f6c03e04837356a1c0ff93e25dc41832 ./docs/API.md
|
||||||
8b548d02dbdf0563f2be617a1d677459bd1959bed93a1799a01bf61bb5aed405 ./docs/FLOW.md
|
8b548d02dbdf0563f2be617a1d677459bd1959bed93a1799a01bf61bb5aed405 ./docs/FLOW.md
|
||||||
bd95027c838d47f4829082c29d2d8b108d56cbd37230f8b894e954208ef18a37 ./docs/openapi.json
|
d9bf3a1644ed3628bd574109602857d7e425a272b9d168416911a8d93bf6f8c5 ./docs/openapi.json
|
||||||
c65aa543d2e99f8f7d52736307b07ebd182597d80124661d53a16bb23f6f1118 ./ha-addon/.env.example
|
c65aa543d2e99f8f7d52736307b07ebd182597d80124661d53a16bb23f6f1118 ./ha-addon/.env.example
|
||||||
0993076ca45b6d31859680835204cdc111b3f9bdbf460d50b4efec56cd5e685b ./ha-addon/Dockerfile
|
0993076ca45b6d31859680835204cdc111b3f9bdbf460d50b4efec56cd5e685b ./ha-addon/Dockerfile
|
||||||
adf7ff248d782a3b1cba82b8789c57b6849ddaaaf5fbc108af75e18b1534a885 ./ha-addon/README.md
|
adf7ff248d782a3b1cba82b8789c57b6849ddaaaf5fbc108af75e18b1534a885 ./ha-addon/README.md
|
||||||
@@ -21,7 +21,7 @@ b7f0873109c52be9d7f09bea3dffc416103c50085e1f0680d11661a969479898 ./ha-addon/hom
|
|||||||
41a8958a6fe6d10e5679c95ac34832583a2a15ecfd67d09b4e094a83d06f5c47 ./ha-addon/home-assistant/custom_components/gree_controller/coordinator.py
|
41a8958a6fe6d10e5679c95ac34832583a2a15ecfd67d09b4e094a83d06f5c47 ./ha-addon/home-assistant/custom_components/gree_controller/coordinator.py
|
||||||
5a96fe8f5c035c34f1339370270cd078056202d09e236dec75735be11de92a7d ./ha-addon/home-assistant/custom_components/gree_controller/entity_map.py
|
5a96fe8f5c035c34f1339370270cd078056202d09e236dec75735be11de92a7d ./ha-addon/home-assistant/custom_components/gree_controller/entity_map.py
|
||||||
c4fb75c246db651087900ebfc2291ff41ac87652cd6194fc0b776b0005c1cbcf ./ha-addon/home-assistant/custom_components/gree_controller/icon.png
|
c4fb75c246db651087900ebfc2291ff41ac87652cd6194fc0b776b0005c1cbcf ./ha-addon/home-assistant/custom_components/gree_controller/icon.png
|
||||||
3235e64a80782c561645e4bad4444e2409a19b4d1f8f4c93a0296a443d6cca3b ./ha-addon/home-assistant/custom_components/gree_controller/manifest.json
|
37ce45f7e9a9fdf258ee1e97ca47599a86b33017e0c52227cdfc900f637b7f80 ./ha-addon/home-assistant/custom_components/gree_controller/manifest.json
|
||||||
c52a484b671ce738ecc00228a1db19a5d703f69ab27530c2896a5c2ae3b4a96f ./ha-addon/home-assistant/custom_components/gree_controller/number.py
|
c52a484b671ce738ecc00228a1db19a5d703f69ab27530c2896a5c2ae3b4a96f ./ha-addon/home-assistant/custom_components/gree_controller/number.py
|
||||||
39c4309001b75abb56234f05662bc06e077054986876f1927937edbce528ec95 ./ha-addon/home-assistant/custom_components/gree_controller/select.py
|
39c4309001b75abb56234f05662bc06e077054986876f1927937edbce528ec95 ./ha-addon/home-assistant/custom_components/gree_controller/select.py
|
||||||
cca65482e36d48035aca178121a378fe7d578d600acff267ae81a6399c0da653 ./ha-addon/home-assistant/custom_components/gree_controller/sensor.py
|
cca65482e36d48035aca178121a378fe7d578d600acff267ae81a6399c0da653 ./ha-addon/home-assistant/custom_components/gree_controller/sensor.py
|
||||||
@@ -29,10 +29,10 @@ cca65482e36d48035aca178121a378fe7d578d600acff267ae81a6399c0da653 ./ha-addon/hom
|
|||||||
6bddb7b4620021ecd2099a86a77ef5c7f2c2dcd3d07d5db4e7b4c4ce6d3e8c03 ./ha-addon/home-assistant/custom_components/gree_controller/translations/en.json
|
6bddb7b4620021ecd2099a86a77ef5c7f2c2dcd3d07d5db4e7b4c4ce6d3e8c03 ./ha-addon/home-assistant/custom_components/gree_controller/translations/en.json
|
||||||
13f30e2dcdcedbd1b6c3f99c2335e0487108fd72c8e86922368b84f2fa2038ae ./ha-addon/home-assistant/custom_components/gree_controller/translations/pl.json
|
13f30e2dcdcedbd1b6c3f99c2335e0487108fd72c8e86922368b84f2fa2038ae ./ha-addon/home-assistant/custom_components/gree_controller/translations/pl.json
|
||||||
c5fc5c87273d82d2834a0a5a365c821a416413ed509613441e24e4dc3507c4d2 ./ha-addon/home-assistant/generated/gree_controller_entities.example.json
|
c5fc5c87273d82d2834a0a5a365c821a416413ed509613441e24e4dc3507c4d2 ./ha-addon/home-assistant/generated/gree_controller_entities.example.json
|
||||||
24f341cd167c903db0522a6a21f0714a7ec19c560be183bed745c50d0d6b599a ./ha-addon/repository/gree-controller/CHANGELOG.md
|
a1cfb2ec0dfc786e8d2c9adad5ad7b62abdf917c0090f06c817e78cd26115683 ./ha-addon/repository/gree-controller/CHANGELOG.md
|
||||||
1b5599195329cc3e643c23aa1caadcec80f133e8e515eec7d92b9f3cbda5b80b ./ha-addon/repository/gree-controller/DOCS.md
|
1b5599195329cc3e643c23aa1caadcec80f133e8e515eec7d92b9f3cbda5b80b ./ha-addon/repository/gree-controller/DOCS.md
|
||||||
c3db302f38d26dc9f8caf37a1a8a07a1334cc07ae301d452f2940a5ec5915719 ./ha-addon/repository/gree-controller/README.md
|
c3db302f38d26dc9f8caf37a1a8a07a1334cc07ae301d452f2940a5ec5915719 ./ha-addon/repository/gree-controller/README.md
|
||||||
c849408ccc076b254f01dc464935812c44e4bbec1e9727cc7664c900d4539563 ./ha-addon/repository/gree-controller/config.yaml
|
e87466f09667d3b7ba35a09e1879cd616ce62c28d99c60363ec835a3bb07ffa6 ./ha-addon/repository/gree-controller/config.yaml
|
||||||
3aae6cdae4c3aaab7786a9575e7093b7e2c5b69288167075f4b7475611691a6b ./ha-addon/repository/gree-controller/topologia-ha-vlan-gree-pl.png
|
3aae6cdae4c3aaab7786a9575e7093b7e2c5b69288167075f4b7475611691a6b ./ha-addon/repository/gree-controller/topologia-ha-vlan-gree-pl.png
|
||||||
0d0b42a7639b128946eec379175436fa1f150294f39d2dfd169077bfa87fd14d ./ha-addon/repository/gree-controller/topology-ha-vlan-gree-en.png
|
0d0b42a7639b128946eec379175436fa1f150294f39d2dfd169077bfa87fd14d ./ha-addon/repository/gree-controller/topology-ha-vlan-gree-en.png
|
||||||
2272740b185e9520e948f74b8f45cf98b8b5fd28c93bdee760da626f91fe5c2a ./ha-addon/repository/gree-controller/translations/en.yaml
|
2272740b185e9520e948f74b8f45cf98b8b5fd28c93bdee760da626f91fe5c2a ./ha-addon/repository/gree-controller/translations/en.yaml
|
||||||
@@ -199,7 +199,7 @@ f13f1be3d5789539eba3fc1b59c14835f8c681eca7634e118fa3763a53aeee2b ./src/queries/
|
|||||||
8c34b70fb5f80e3249c2e0c63686e60ce1697cf44a7e6f11b3ad6f689ce17792 ./src/state.rs
|
8c34b70fb5f80e3249c2e0c63686e60ce1697cf44a7e6f11b3ad6f689ce17792 ./src/state.rs
|
||||||
b92a6cb158b494fe145b43c7641e65f6fafff47201d7d76edbec2cfd8b94835c ./systemd/gree-controller.service
|
b92a6cb158b494fe145b43c7641e65f6fafff47201d7d76edbec2cfd8b94835c ./systemd/gree-controller.service
|
||||||
544a31cb2e5374227026afd6abd0d910381f3fca1638154ebd74e3c3d96a35d1 ./web/404.html
|
544a31cb2e5374227026afd6abd0d910381f3fca1638154ebd74e3c3d96a35d1 ./web/404.html
|
||||||
8b8b5e9511a833d6dc0eb902048e8f48f26395faf55f19962c3e6f06ae0fb4e4 ./web/css/styles.css
|
6531bd30b81e8fe22ce973c2be3308e8ef7e3aa42285d86175b8329f2a670b61 ./web/css/styles.css
|
||||||
183d122ba366303d9952ac0e68aff4bced4e0d9a468fbe51316c13f15227402b ./web/custom-chart.html
|
183d122ba366303d9952ac0e68aff4bced4e0d9a468fbe51316c13f15227402b ./web/custom-chart.html
|
||||||
e98bdd7204349cce1ec6f57283509697af0bbc72280622a6c3efa6fed242db4f ./web/favicon.svg
|
e98bdd7204349cce1ec6f57283509697af0bbc72280622a6c3efa6fed242db4f ./web/favicon.svg
|
||||||
784e2c28effb9872b582298292d3e2a6b8dd6140207342452193894d210e2f45 ./web/index.html
|
784e2c28effb9872b582298292d3e2a6b8dd6140207342452193894d210e2f45 ./web/index.html
|
||||||
@@ -220,7 +220,7 @@ e98bdd7204349cce1ec6f57283509697af0bbc72280622a6c3efa6fed242db4f ./web/favicon.
|
|||||||
c2710fd9c1f2b31878c1e25ceb02d74ae30456c1bbb400e69fcf7619ecc72bc2 ./web/js-dynamic/select-ui.js
|
c2710fd9c1f2b31878c1e25ceb02d74ae30456c1bbb400e69fcf7619ecc72bc2 ./web/js-dynamic/select-ui.js
|
||||||
f7245f0e6cb5011196704f201675ebc6c19d902b8253ffcdbf9ead46cb1c6f86 ./web/js-dynamic/settings-ui.js
|
f7245f0e6cb5011196704f201675ebc6c19d902b8253ffcdbf9ead46cb1c6f86 ./web/js-dynamic/settings-ui.js
|
||||||
672e404470bc6331aa6d658523b221659ec64222af9cc9c17ced978f725790da ./web/js-dynamic/settings.js
|
672e404470bc6331aa6d658523b221659ec64222af9cc9c17ced978f725790da ./web/js-dynamic/settings.js
|
||||||
930777048669688985b494a10dad8e591c82666071bde1018eef8f725a660895 ./web/js/custom-chart.js
|
489ab0208c86f7a2bb0d721106f01fb5d4f39f41e94749b440a6c58e13c4de07 ./web/js/custom-chart.js
|
||||||
6ae536b18db756bf5eda9adb1b8a550d5a02bfc80f0b7da27fa146039f22e884 ./web/js/lang-init.js
|
6ae536b18db756bf5eda9adb1b8a550d5a02bfc80f0b7da27fa146039f22e884 ./web/js/lang-init.js
|
||||||
e3fc113d4c349f33f3faa32e7a46c96a85c71643f43f2e488065dc9715e27333 ./web/js/sw.js
|
e3fc113d4c349f33f3faa32e7a46c96a85c71643f43f2e488065dc9715e27333 ./web/js/sw.js
|
||||||
d505d793ce7cc9485b45b78bba1c0d51887adc7451ab59a42702946e5b991382 ./web/js/theme-init.js
|
d505d793ce7cc9485b45b78bba1c0d51887adc7451ab59a42702946e5b991382 ./web/js/theme-init.js
|
||||||
|
|||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
# GREE Controller API reference
|
# GREE Controller API reference
|
||||||
|
|
||||||
HTTP and WebSocket API for GREE Controller **0.14.23**.
|
HTTP and WebSocket API for GREE Controller **0.14.24**.
|
||||||
|
|
||||||
[← Main documentation](../README.md)
|
[← Main documentation](../README.md)
|
||||||
|
|
||||||
@@ -240,7 +240,7 @@ Response:
|
|||||||
{
|
{
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
"name": "gree-controller",
|
"name": "gree-controller",
|
||||||
"version": "0.14.23",
|
"version": "0.14.24",
|
||||||
"uptime_seconds": 1234,
|
"uptime_seconds": 1234,
|
||||||
"control_ready": true,
|
"control_ready": true,
|
||||||
"time": "2026-08-30T06:54:00Z"
|
"time": "2026-08-30T06:54:00Z"
|
||||||
@@ -303,7 +303,7 @@ Returns the initial Web UI snapshot:
|
|||||||
"control_plan": {"generated_at": "2026-09-04T08:00:00Z", "zones": [], "rules": []},
|
"control_plan": {"generated_at": "2026-09-04T08:00:00Z", "zones": [], "rules": []},
|
||||||
"control_plan_revision": 42,
|
"control_plan_revision": 42,
|
||||||
"system": {
|
"system": {
|
||||||
"version": "0.14.23",
|
"version": "0.14.24",
|
||||||
"uptime_seconds": 1234,
|
"uptime_seconds": 1234,
|
||||||
"auth_required": false,
|
"auth_required": false,
|
||||||
"control_ready": true,
|
"control_ready": true,
|
||||||
|
|||||||
+3
-3
File diff suppressed because one or more lines are too long
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"domain": "gree_controller",
|
"domain": "gree_controller",
|
||||||
"name": "GREE Controller",
|
"name": "GREE Controller",
|
||||||
"version": "0.14.23",
|
"version": "0.14.24",
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"integration_type": "hub",
|
"integration_type": "hub",
|
||||||
"iot_class": "local_polling",
|
"iot_class": "local_polling",
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.14.24
|
||||||
|
|
||||||
|
- Public Custom Charts fetch chart metadata before language assets, so a chart loads only its selected language pack; missing chart IDs fall back to English.
|
||||||
|
- Public Custom Charts support pinch-to-zoom, one-finger horizontal panning while zoomed and per-metric visibility toggles through the legend.
|
||||||
|
- Missing public chart IDs now return `chart id not found`, the favicon is no longer redundantly pre-cached, and invalid Access Tokens show an inline authentication error.
|
||||||
|
|
||||||
## 0.14.23
|
## 0.14.23
|
||||||
|
|
||||||
- Code cleanup and small UX changes.
|
- Code cleanup and small UX changes.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: "GREE Controller"
|
name: "GREE Controller"
|
||||||
version: "0.14.23"
|
version: "0.14.24"
|
||||||
slug: "gree_controller"
|
slug: "gree_controller"
|
||||||
description: "Local GREE HVAC controller with Web UI and Home Assistant integration"
|
description: "Local GREE HVAC controller with Web UI and Home Assistant integration"
|
||||||
url: "https://git.linuxiarz.pl/gru/gree-controller-ha-addon/"
|
url: "https://git.linuxiarz.pl/gru/gree-controller-ha-addon/"
|
||||||
|
|||||||
+2
-7
@@ -10226,6 +10226,7 @@ select.select-native-proxy[aria-invalid="true"]+.custom-select .custom-select-tr
|
|||||||
min-width: 720px;
|
min-width: 720px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
|
touch-action: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.public-custom-chart-card .legend {
|
.public-custom-chart-card .legend {
|
||||||
@@ -10241,13 +10242,7 @@ select.select-native-proxy[aria-invalid="true"]+.custom-select .custom-select-tr
|
|||||||
}
|
}
|
||||||
|
|
||||||
.public-chart-legend-item {
|
.public-chart-legend-item {
|
||||||
cursor: default;
|
flex: 0 0 auto;
|
||||||
}
|
|
||||||
|
|
||||||
.public-chart-legend-item:hover {
|
|
||||||
border-color: transparent;
|
|
||||||
background: transparent;
|
|
||||||
color: var(--muted);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.public-custom-chart-error {
|
.public-custom-chart-error {
|
||||||
|
|||||||
+128
-21
@@ -4,6 +4,7 @@ const PUBLIC_CHART_COLORS = ['--accent', '--info', '--warning', '--purple', '--d
|
|||||||
const $ = selector => document.querySelector(selector);
|
const $ = selector => document.querySelector(selector);
|
||||||
const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
||||||
const PUBLIC_CHART_RANGES = [6, 24, 168, 720, 2160, 8760];
|
const PUBLIC_CHART_RANGES = [6, 24, 168, 720, 2160, 8760];
|
||||||
|
const PUBLIC_MAX_CHART_ZOOM = 16;
|
||||||
|
|
||||||
function basePathFromScript() {
|
function basePathFromScript() {
|
||||||
const src = document.currentScript?.src || '';
|
const src = document.currentScript?.src || '';
|
||||||
@@ -23,11 +24,8 @@ const publicLanguagePacks = new Map();
|
|||||||
let publicChartLanguage = PUBLIC_DEFAULT_LANGUAGE;
|
let publicChartLanguage = PUBLIC_DEFAULT_LANGUAGE;
|
||||||
let publicChartTranslations = {};
|
let publicChartTranslations = {};
|
||||||
let publicChartLocale = PUBLIC_DEFAULT_LANGUAGE;
|
let publicChartLocale = PUBLIC_DEFAULT_LANGUAGE;
|
||||||
|
let publicChartZoom = 1;
|
||||||
function publicCookie(name) {
|
const publicChartHiddenSeries = new Set();
|
||||||
const row = document.cookie.split('; ').find(item => item.startsWith(`${name}=`));
|
|
||||||
return row ? decodeURIComponent(row.split('=').slice(1).join('=')) : '';
|
|
||||||
}
|
|
||||||
|
|
||||||
function publicTr(key, params = {}) {
|
function publicTr(key, params = {}) {
|
||||||
const template = publicChartTranslations[key] ?? key;
|
const template = publicChartTranslations[key] ?? key;
|
||||||
@@ -85,7 +83,8 @@ function preciseTime(timestamp, locale) {
|
|||||||
|
|
||||||
function prepareCanvas(canvas, height = 520) {
|
function prepareCanvas(canvas, height = 520) {
|
||||||
const wrap = canvas.parentElement;
|
const wrap = canvas.parentElement;
|
||||||
const width = Math.max(720, Math.floor(wrap?.clientWidth || canvas.getBoundingClientRect().width || 720));
|
const baseWidth = Math.max(720, Math.floor(wrap?.clientWidth || canvas.getBoundingClientRect().width || 720));
|
||||||
|
const width = Math.max(1, Math.floor(baseWidth * publicChartZoom));
|
||||||
const actualHeight = Math.max(180, Math.floor(wrap?.clientHeight || height));
|
const actualHeight = Math.max(180, Math.floor(wrap?.clientHeight || height));
|
||||||
const dpr = window.devicePixelRatio || 1;
|
const dpr = window.devicePixelRatio || 1;
|
||||||
canvas.width = Math.floor(width * dpr);
|
canvas.width = Math.floor(width * dpr);
|
||||||
@@ -98,12 +97,21 @@ function prepareCanvas(canvas, height = 520) {
|
|||||||
return { ctx, width, height: actualHeight };
|
return { ctx, width, height: actualHeight };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function publicChartSeriesKey(item, index) {
|
||||||
|
return item.key || `${index}:${item.label}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isPublicChartSeriesHidden(item, index) {
|
||||||
|
return publicChartHiddenSeries.has(publicChartSeriesKey(item, index));
|
||||||
|
}
|
||||||
|
|
||||||
function renderLegend(series) {
|
function renderLegend(series) {
|
||||||
const host = $('#publicCustomChartLegend');
|
const host = $('#publicCustomChartLegend');
|
||||||
host.innerHTML = series.map((item, index) => {
|
host.innerHTML = series.map((item, index) => {
|
||||||
const color = cssColor(PUBLIC_CHART_COLORS[index % PUBLIC_CHART_COLORS.length], '#3ecf8e');
|
const hidden = isPublicChartSeriesHidden(item, index);
|
||||||
const dashed = item.dashed ? ' is-dashed' : '';
|
const dashed = item.dashed ? ' is-dashed' : '';
|
||||||
return `<span class="legend-item public-chart-legend-item"><i class="legend-line${dashed}" style="--legend-color:${color}"></i><span>${escapeHtml(item.label)}</span></span>`;
|
const title = publicTr(hidden ? 'history.legendShow' : 'history.legendHide', { name: item.label });
|
||||||
|
return `<button type="button" class="legend-item public-chart-legend-item${hidden ? ' is-hidden' : ''}" data-public-chart-legend="${index}" aria-pressed="${hidden ? 'false' : 'true'}" title="${escapeHtml(title)}"><i class="legend-line${dashed}" style="--legend-color:${escapeHtml(item.color)}"></i><span>${escapeHtml(item.label)}</span></button>`;
|
||||||
}).join('');
|
}).join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,6 +125,13 @@ function drawEmpty(canvas, message) {
|
|||||||
ctx.font = '13px system-ui';
|
ctx.font = '13px system-ui';
|
||||||
ctx.textAlign = 'center';
|
ctx.textAlign = 'center';
|
||||||
ctx.fillText(message, width / 2, height / 2);
|
ctx.fillText(message, width / 2, height / 2);
|
||||||
|
const wrap = canvas.parentElement;
|
||||||
|
const tooltip = wrap?.querySelector('.chart-tooltip');
|
||||||
|
const line = wrap?.querySelector('.chart-hover-line');
|
||||||
|
if (tooltip) tooltip.hidden = true;
|
||||||
|
if (line) line.hidden = true;
|
||||||
|
canvas.onpointermove = null;
|
||||||
|
canvas.onpointerleave = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function nearestPoint(points, targetTs) {
|
function nearestPoint(points, targetTs) {
|
||||||
@@ -142,7 +157,7 @@ function bindTooltip(canvas, series, geometry, locale) {
|
|||||||
const timestampPoints = timestamps.map(ts => ({ ts }));
|
const timestampPoints = timestamps.map(ts => ({ ts }));
|
||||||
const seriesPoints = series.map((item, index) => ({
|
const seriesPoints = series.map((item, index) => ({
|
||||||
item,
|
item,
|
||||||
color: cssColor(PUBLIC_CHART_COLORS[index % PUBLIC_CHART_COLORS.length], '#3ecf8e'),
|
color: item.color || cssColor(PUBLIC_CHART_COLORS[index % PUBLIC_CHART_COLORS.length], '#3ecf8e'),
|
||||||
points: item.points.map(point => ({ ts: new Date(point.timestamp).getTime(), value: Number(point.value) }))
|
points: item.points.map(point => ({ ts: new Date(point.timestamp).getTime(), value: Number(point.value) }))
|
||||||
.filter(point => Number.isFinite(point.ts) && Number.isFinite(point.value))
|
.filter(point => Number.isFinite(point.ts) && Number.isFinite(point.value))
|
||||||
.sort((a, b) => a.ts - b.ts)
|
.sort((a, b) => a.ts - b.ts)
|
||||||
@@ -178,12 +193,13 @@ function bindTooltip(canvas, series, geometry, locale) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function drawChart(canvas, payload, locale) {
|
function drawChart(canvas, payload, locale) {
|
||||||
const series = (payload.series || []).map((item, index) => ({
|
const allSeries = (payload.series || []).map((item, index) => ({
|
||||||
...item,
|
...item,
|
||||||
color: cssColor(PUBLIC_CHART_COLORS[index % PUBLIC_CHART_COLORS.length], '#3ecf8e'),
|
color: cssColor(PUBLIC_CHART_COLORS[index % PUBLIC_CHART_COLORS.length], '#3ecf8e'),
|
||||||
points: Array.isArray(item.points) ? item.points : []
|
points: Array.isArray(item.points) ? item.points : []
|
||||||
}));
|
}));
|
||||||
renderLegend(series);
|
renderLegend(allSeries);
|
||||||
|
const series = allSeries.filter((item, index) => !isPublicChartSeriesHidden(item, index));
|
||||||
const allPoints = series.flatMap(item => item.points.map(point => ({ ...point, value: Number(point.value) })))
|
const allPoints = series.flatMap(item => item.points.map(point => ({ ...point, value: Number(point.value) })))
|
||||||
.filter(point => Number.isFinite(point.value) && Number.isFinite(new Date(point.timestamp).getTime()));
|
.filter(point => Number.isFinite(point.value) && Number.isFinite(new Date(point.timestamp).getTime()));
|
||||||
if (!allPoints.length) return drawEmpty(canvas, payload.no_data_label || publicTr('publicChart.noData'));
|
if (!allPoints.length) return drawEmpty(canvas, payload.no_data_label || publicTr('publicChart.noData'));
|
||||||
@@ -288,6 +304,80 @@ function redrawPublicChart() {
|
|||||||
drawChart($('#publicCustomChart'), publicChartPayload, publicChartLocale);
|
drawChart($('#publicCustomChart'), publicChartPayload, publicChartLocale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setPublicChartZoom(value, anchorRatio = null, anchorViewportX = null) {
|
||||||
|
const canvas = $('#publicCustomChart');
|
||||||
|
const wrap = canvas?.parentElement;
|
||||||
|
if (!canvas || !wrap || !publicChartPayload) return;
|
||||||
|
const oldWidth = canvas.getBoundingClientRect().width || 1;
|
||||||
|
const ratio = Number.isFinite(anchorRatio)
|
||||||
|
? clamp(anchorRatio, 0, 1)
|
||||||
|
: clamp((wrap.scrollLeft + wrap.clientWidth / 2) / oldWidth, 0, 1);
|
||||||
|
const viewportX = Number.isFinite(anchorViewportX) ? anchorViewportX : wrap.clientWidth / 2;
|
||||||
|
const next = clamp(Number(value) || 1, 1, PUBLIC_MAX_CHART_ZOOM);
|
||||||
|
if (Math.abs(next - publicChartZoom) < 0.001) return;
|
||||||
|
publicChartZoom = next;
|
||||||
|
redrawPublicChart();
|
||||||
|
const nextWidth = canvas.getBoundingClientRect().width || 1;
|
||||||
|
wrap.scrollLeft = Math.max(0, ratio * nextWidth - viewportX);
|
||||||
|
}
|
||||||
|
|
||||||
|
function bindPublicChartTouchGestures() {
|
||||||
|
const canvas = $('#publicCustomChart');
|
||||||
|
const wrap = canvas?.parentElement;
|
||||||
|
if (!canvas || !wrap) return;
|
||||||
|
let pinch = null;
|
||||||
|
let pan = null;
|
||||||
|
const distance = touches => Math.hypot(
|
||||||
|
touches[0].clientX - touches[1].clientX,
|
||||||
|
touches[0].clientY - touches[1].clientY
|
||||||
|
);
|
||||||
|
const beginPinch = touches => {
|
||||||
|
const rect = canvas.getBoundingClientRect();
|
||||||
|
const wrapRect = wrap.getBoundingClientRect();
|
||||||
|
const centerX = (touches[0].clientX + touches[1].clientX) / 2;
|
||||||
|
pinch = {
|
||||||
|
distance: Math.max(1, distance(touches)),
|
||||||
|
zoom: publicChartZoom,
|
||||||
|
anchorRatio: clamp((centerX - rect.left) / Math.max(1, rect.width), 0, 1),
|
||||||
|
anchorViewportX: clamp(centerX - wrapRect.left, 0, wrap.clientWidth),
|
||||||
|
};
|
||||||
|
pan = null;
|
||||||
|
};
|
||||||
|
const beginPan = touch => {
|
||||||
|
pan = { clientX: touch.clientX, scrollLeft: wrap.scrollLeft };
|
||||||
|
};
|
||||||
|
|
||||||
|
canvas.addEventListener('touchstart', event => {
|
||||||
|
if (event.touches.length >= 2) {
|
||||||
|
event.preventDefault();
|
||||||
|
beginPinch(event.touches);
|
||||||
|
} else if (event.touches.length === 1) {
|
||||||
|
beginPan(event.touches[0]);
|
||||||
|
}
|
||||||
|
}, { passive: false });
|
||||||
|
|
||||||
|
canvas.addEventListener('touchmove', event => {
|
||||||
|
if (event.touches.length >= 2) {
|
||||||
|
event.preventDefault();
|
||||||
|
if (!pinch) beginPinch(event.touches);
|
||||||
|
const scale = distance(event.touches) / Math.max(1, pinch.distance);
|
||||||
|
setPublicChartZoom(pinch.zoom * scale, pinch.anchorRatio, pinch.anchorViewportX);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (event.touches.length === 1 && pan && wrap.scrollWidth > wrap.clientWidth + 1) {
|
||||||
|
event.preventDefault();
|
||||||
|
wrap.scrollLeft = pan.scrollLeft + (pan.clientX - event.touches[0].clientX);
|
||||||
|
}
|
||||||
|
}, { passive: false });
|
||||||
|
|
||||||
|
canvas.addEventListener('touchend', event => {
|
||||||
|
pinch = null;
|
||||||
|
if (event.touches.length === 1) beginPan(event.touches[0]);
|
||||||
|
else pan = null;
|
||||||
|
}, { passive: true });
|
||||||
|
canvas.addEventListener('touchcancel', () => { pinch = null; pan = null; }, { passive: true });
|
||||||
|
}
|
||||||
|
|
||||||
async function loadPublicChart(hours = requestedPublicChartHours()) {
|
async function loadPublicChart(hours = requestedPublicChartHours()) {
|
||||||
const token = publicChartToken();
|
const token = publicChartToken();
|
||||||
const title = $('#publicChartTitle');
|
const title = $('#publicChartTitle');
|
||||||
@@ -297,6 +387,7 @@ async function loadPublicChart(hours = requestedPublicChartHours()) {
|
|||||||
const range = $('#publicChartHours');
|
const range = $('#publicChartHours');
|
||||||
|
|
||||||
if (!token.startsWith('chart_')) {
|
if (!token.startsWith('chart_')) {
|
||||||
|
await setPublicChartLanguage('en');
|
||||||
title.textContent = publicTr('publicChart.title');
|
title.textContent = publicTr('publicChart.title');
|
||||||
hint.textContent = '';
|
hint.textContent = '';
|
||||||
error.hidden = false;
|
error.hidden = false;
|
||||||
@@ -306,16 +397,19 @@ async function loadPublicChart(hours = requestedPublicChartHours()) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (range) range.disabled = true;
|
if (range) range.disabled = true;
|
||||||
if (hint) hint.textContent = publicTr('publicChart.loading');
|
if (hint) hint.textContent = Object.keys(publicChartTranslations).length ? publicTr('publicChart.loading') : 'Loading…';
|
||||||
error.hidden = true;
|
error.hidden = true;
|
||||||
const response = await fetch(withBase(publicChartApiPath(token, hours)), { headers: { Accept: 'application/json' }, cache: 'no-store' });
|
const response = await fetch(withBase(publicChartApiPath(token, hours)), { headers: { Accept: 'application/json' }, cache: 'no-store' });
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
let message = `${response.status}`;
|
let message = `${response.status}`;
|
||||||
try { message = (await response.json()).error || message; } catch (_) { }
|
try { message = (await response.json()).error || message; } catch (_) { }
|
||||||
throw new Error(message);
|
if (response.status === 404) await setPublicChartLanguage('en');
|
||||||
|
const requestError = new Error(message);
|
||||||
|
requestError.status = response.status;
|
||||||
|
throw requestError;
|
||||||
}
|
}
|
||||||
const payload = await response.json();
|
const payload = await response.json();
|
||||||
await setPublicChartLanguage(payload.lang || publicChartLanguage);
|
await setPublicChartLanguage(payload.lang || 'en');
|
||||||
title.textContent = payload.title || publicTr('publicChart.title');
|
title.textContent = payload.title || publicTr('publicChart.title');
|
||||||
hint.textContent = payload.hint || publicTr('publicChart.periodHint', { hours: payload.hours });
|
hint.textContent = payload.hint || publicTr('publicChart.periodHint', { hours: payload.hours });
|
||||||
canvas.setAttribute('aria-label', title.textContent);
|
canvas.setAttribute('aria-label', title.textContent);
|
||||||
@@ -329,6 +423,18 @@ async function loadPublicChart(hours = requestedPublicChartHours()) {
|
|||||||
if (range) range.disabled = false;
|
if (range) range.disabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$('#publicCustomChartLegend')?.addEventListener('click', event => {
|
||||||
|
const button = event.target.closest('button[data-public-chart-legend]');
|
||||||
|
if (!button || !publicChartPayload) return;
|
||||||
|
const index = Number(button.dataset.publicChartLegend);
|
||||||
|
const item = publicChartPayload.series?.[index];
|
||||||
|
if (!item) return;
|
||||||
|
const key = publicChartSeriesKey(item, index);
|
||||||
|
if (publicChartHiddenSeries.has(key)) publicChartHiddenSeries.delete(key);
|
||||||
|
else publicChartHiddenSeries.add(key);
|
||||||
|
redrawPublicChart();
|
||||||
|
});
|
||||||
|
|
||||||
$('#publicChartHours')?.addEventListener('change', async event => {
|
$('#publicChartHours')?.addEventListener('change', async event => {
|
||||||
const hours = Number(event.currentTarget.value);
|
const hours = Number(event.currentTarget.value);
|
||||||
if (!Number.isInteger(hours) || hours < 1 || hours > 87600) return;
|
if (!Number.isInteger(hours) || hours < 1 || hours > 87600) return;
|
||||||
@@ -351,16 +457,15 @@ window.addEventListener('resize', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
async function initPublicChart() {
|
async function initPublicChart() {
|
||||||
try {
|
bindPublicChartTouchGestures();
|
||||||
await setPublicChartLanguage(publicCookie('gree_controller_language') || PUBLIC_DEFAULT_LANGUAGE);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Public chart language initialization failed:', error);
|
|
||||||
} finally {
|
|
||||||
document.documentElement.classList.remove('i18n-loading');
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
await loadPublicChart();
|
await loadPublicChart();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
if (!Object.keys(publicChartTranslations).length) {
|
||||||
|
try { await setPublicChartLanguage('en'); } catch (languageError) {
|
||||||
|
console.error('Public chart fallback language initialization failed:', languageError);
|
||||||
|
}
|
||||||
|
}
|
||||||
const host = $('#publicChartError');
|
const host = $('#publicChartError');
|
||||||
host.hidden = false;
|
host.hidden = false;
|
||||||
host.textContent = publicChartTranslations['publicChart.loadFailed']
|
host.textContent = publicChartTranslations['publicChart.loadFailed']
|
||||||
@@ -369,6 +474,8 @@ async function initPublicChart() {
|
|||||||
$('#publicChartHint').textContent = '';
|
$('#publicChartHint').textContent = '';
|
||||||
$('#publicChartHours').disabled = false;
|
$('#publicChartHours').disabled = false;
|
||||||
drawEmpty($('#publicCustomChart'), host.textContent);
|
drawEmpty($('#publicCustomChart'), host.textContent);
|
||||||
|
} finally {
|
||||||
|
document.documentElement.classList.remove('i18n-loading');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user