v0.15.18
This commit is contained in:
1 parent
0148daf410
commit
f08613a254
23 files changed
+290
-70
No files matched your search
Generated
+1
-1
@@ -719,7 +719,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "gree-controller"
|
||||
version = "0.15.17"
|
||||
version = "0.15.18"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"aes-gcm",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "gree-controller"
|
||||
version = "0.15.17"
|
||||
version = "0.15.18"
|
||||
edition = "2021"
|
||||
authors = ["GREE Controller contributors"]
|
||||
description = "Standalone local GREE HVAC controller with Web UI, SQLite and Home Assistant sensor support"
|
||||
|
||||
+22
-22
@@ -1,14 +1,14 @@
|
||||
de0793949cf01d27d903653226ecc9b5f72523d8711f20bcab022cf42c4c4ed0 ./.env.example
|
||||
a4ec3874a2e3ab1bad28fb40bb620f7b01f64d01ad9b699306bf70ada31227db ./.gitignore
|
||||
4051d2de7fa9858545582dc6bb5a411c980a282d0b25aa3766df88597442f94a ./Cargo.lock
|
||||
4bf5b286ffb52b22a32ef3d2d5e4dfaae600c1be01c1cac0b87c7138ecb4a129 ./Cargo.toml
|
||||
dfac61e5ea474221798f0a72d6cb4d6b5a31bcd853573e14c172087c2f7e98c5 ./Cargo.lock
|
||||
f8e6fa48a584d6446e6360185b0ca320379b325d62afc062e7d2efedc2b14af1 ./Cargo.toml
|
||||
19b2943504acb8f8de280f873a8dbec4bb6ebbe3870b158f5655d4fb8c298f5f ./LICENSE
|
||||
9a429e8b766c66061e85ccd535cc1429fe1284d14fcf75daa362fea724e0bf85 ./README.md
|
||||
03d73e4b4c0036d2cc07d8057f25ae8c9d89451eebfb43715ee51aa06edd1c93 ./SOURCE_MANIFEST.sha256
|
||||
591cf7e1fc98bbcdf4854c28ffc22df92b47ac7cd6e81bfa07ae4f99a9baaa3c ./README.md
|
||||
7da5e80fea6c3ba99fc7d66224d377dcaa15c287a2a4a16acef847aeb1e0aa44 ./SOURCE_MANIFEST.sha256
|
||||
29e9821e5ed216ea3565dd6d8bc0b174ed3cf9fa72c4ccebbfa99e98db3ad8f9 ./build.rs
|
||||
3c1fce0f3097e7860f8ccf6a79749af4e7e4bd43e612c6419d91c0e620480506 ./docs/API.md
|
||||
312ca0de508126a473cad4a06d35eb5b44086de37f6d0f5f4d9f5fa85e5992fe ./docs/API.md
|
||||
43af7941ec4d427f9db7ab3cc6baf3d182a72dba7a6791f14094fee138324d8d ./docs/FLOW.md
|
||||
3ef573d60de5dcba3fdb4004df53ea170440cbeae2e244a1f6acfcb3255b7c78 ./docs/openapi.json
|
||||
d3702f852b4427c67043d16d3edab40be23a1ebf9a3baf44902ef764241643dd ./docs/openapi.json
|
||||
77b8becf7a2c16a384ea85721d878b76e2d520549cb4455d9aa806e57e5a2ecd ./ha-addon/.env.example
|
||||
0ca6e58170c2b8925194431ebbdb55f0c8b377fec5cd422cd2bd257e2d9328e3 ./ha-addon/Dockerfile
|
||||
0951696a2c2e66d4d969f8e7f8641184e3012f261583b31074bc38a7a1c0cc1a ./ha-addon/README.md
|
||||
@@ -22,7 +22,7 @@ b7f0873109c52be9d7f09bea3dffc416103c50085e1f0680d11661a969479898 ./ha-addon/hom
|
||||
6509286c7b7de638dcc5d40ce53181e65d1eddc5dc36a13306dc6d87220fedbb ./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
|
||||
5aea34a2adb03ed46a93199e943d7820e34825658fefc3d7c3eb5267ac9066b0 ./ha-addon/home-assistant/custom_components/gree_controller/manifest.json
|
||||
813f932b99eda416330688504c67872148b6aeae27042f93505085cbfe06a3ed ./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 +30,10 @@ cca65482e36d48035aca178121a378fe7d578d600acff267ae81a6399c0da653 ./ha-addon/hom
|
||||
a745cc458c235158d5d70b6a33d8000fd8b40ff93bfe2f2796af0f4b3a9eef9b ./ha-addon/home-assistant/custom_components/gree_controller/translations/en.json
|
||||
50b7d6fe6329ad4ea6bee9612ab141c2f73f8382fcc2af0bb076a8e8d4dd4465 ./ha-addon/home-assistant/custom_components/gree_controller/translations/pl.json
|
||||
c5fc5c87273d82d2834a0a5a365c821a416413ed509613441e24e4dc3507c4d2 ./ha-addon/home-assistant/generated/gree_controller_entities.example.json
|
||||
69d6cf26824f8851cdf076f87c7270d6f87717a2820b68b57a82beed53d2c736 ./ha-addon/repository/gree-controller/CHANGELOG.md
|
||||
e8b1f335c9c7c5e3510aad8961f8f3e67d9fdd711d5407f1adb9db1746fd2407 ./ha-addon/repository/gree-controller/CHANGELOG.md
|
||||
50b8ba050c6b4919e4d057f7b38c1e23d3913b5b7c87552626452e9695d37251 ./ha-addon/repository/gree-controller/DOCS.md
|
||||
d3d0e54672751a3400021ffd1fdcc83a9a903be72cff32cdc3607a61aec0a31e ./ha-addon/repository/gree-controller/README.md
|
||||
c591ab21837150e313407a34a5a3758302aaafd91cd5fcebe18bb5358b702433 ./ha-addon/repository/gree-controller/config.yaml
|
||||
cf3e7106bb516598ca7d635be3d00807af024a9448632d89ee1a60d139c1c573 ./ha-addon/repository/gree-controller/README.md
|
||||
0733d428c986e22c0300c3d8a82971dc1d6cadc88d38c928667c74c93638b5df ./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
|
||||
@@ -43,8 +43,8 @@ cea12bc74c066a588a5ef0ef7bad9d4906bdbcea99f2d275429b0eefc94b4b5f ./ha-addon/run
|
||||
081e27b6e43070d44f865335c30a42a5a29668eaa6a5ea5ab6967ac4447b8e06 ./ha-addon/sync-repository.sh
|
||||
f9e31de3d109ead32bf531c074d46a087df398d62488caee0b46b5e0a1c027f7 ./ha_addon.md
|
||||
253a0bc912786e67ea7fc92a64e4a510ad973bec343a88ccfb1f28fca3e8cf01 ./lang/README.md
|
||||
859875af2aad9929fe6ecfb80244c8d09182345edd99663e54b04910268e902e ./lang/en.json
|
||||
7139d82eb65341e72ad978be3f57efbe04228b2101b19f792d665d146697d24f ./lang/pl.json
|
||||
c5c95c19ceac8969435c6f7742c86e7efa4db9bf723a0b30b098acf7fe6295fa ./lang/en.json
|
||||
9ebf7bcfd49220e828336f551251ffc86986772864e75a5a74493cee27929749 ./lang/pl.json
|
||||
d8459024f04ca514bd8e9d6bd3af872fb942fd85a7cdd5583f4a9d28aab6faba ./make_zip.py
|
||||
b14233a8987e53bbbdd6770386ba10fa166ec25c1e098275c173c544b37846fc ./presets/bedroom_window_night.json
|
||||
1960841119c0b673fb2f03621b32237552fd828045304cd221401214b997c910 ./presets/device_resilience.json
|
||||
@@ -85,7 +85,7 @@ fdcd9a5055d08037278b842e7ab69265345c5811f0a06867136c511d140bb191 ./presets/wind
|
||||
804f22123cd3e8db0fac791826c8dd9f758fb866c8e3b5655fb6d25d259dccf1 ./presets/workday_comfort.json
|
||||
fd7390d64a2378352c09382accf6efff43903d952d111b22a982f06c5b2a3b4b ./regenerate-sha.sh
|
||||
c64b1c6deeb24f20af662bfce7fa3683703914987241107ce664fa2f6d1a9dcb ./scripts/README.md
|
||||
5969f2442a8d61ac5b1303f4cd6d8dcfe80596ef5427a513ae3addb126bf0273 ./scripts/api_dev_test.py
|
||||
ff01f3a4b69bbd58e824eb6dfb8d36568c189cbc38bea21417b91ae81c4c43dc ./scripts/api_dev_test.py
|
||||
5bc736c7bc76ca80aaa406bb171d2aa91baf4c3aa8695dce0e09b888b6ab3146 ./scripts/common.sh
|
||||
6403786610ee6d2f628193c25aee0dd058d62e904aa1a31d5f62fdaae0e94b4f ./scripts/configure-gree-network.sh
|
||||
1d6e14e26e49aa9d3527f30a23668bf8d9c48b67e6628ef686c3155c012155de ./scripts/dev.sh
|
||||
@@ -101,13 +101,13 @@ b50782b3742dfbf8a319c60571c968e93fdf8547db747c759edcffae68cb98bf ./scripts/upda
|
||||
ea84f5230da97447c60dfb4f8dadd0747c92fd1f7a74d5a65d6fdb6f23cf4b6d ./src/api.rs
|
||||
0db0d81da4b8161004ddcbed2096812c285ecec9d944771670e6c8edf0775175 ./src/api/assets.rs
|
||||
1139dacbd3f6ff94bf721eb5a60d469016fb935ddcf484d71bfeb249b72c833a ./src/api/auth.rs
|
||||
9e4fc675306e111ed3db7af9822e2925d88109c31b9e309851665a975c0bd83c ./src/api/automations.rs
|
||||
a652409de6e2e2897d67d19dc16a7d4209c5c35afda39081fef627a098a739b4 ./src/api/automations.rs
|
||||
fffad7874465739cd6b508e9d7791387b864fa88420ce0f7e2fc933d129a2751 ./src/api/configuration.rs
|
||||
19bc141286a336ad67e99079496eb0ae5126f986ab28be62b5f97758e5f6969c ./src/api/debug_tokens.rs
|
||||
ca21f6d5a407e2e3532899d53ba4e8682c2fe961a46d8cd870ddc459721513ef ./src/api/device_groups.rs
|
||||
8f92909dc575ea6238f4a003f8bd4056c2752fa3247b9ab226e47f875c80b916 ./src/api/devices.rs
|
||||
4b5b784670ae761a6848b9a33fe3fb391bebd39d65e87936907428711e96ca44 ./src/api/events.rs
|
||||
ca5bc21e051222dcaf0c507e84cb3e60f52a0b612a6056847fa0aee3a4d1a672 ./src/api/flows.rs
|
||||
b1e9567cae7036af51945ce1219f537567c944c0402c2ff03edb1249403670b5 ./src/api/flows.rs
|
||||
82c02fa135132ea3ebdb4d88dd1210dc536d22f987151d7f82595ee3d3d03440 ./src/api/gree_cloud.rs
|
||||
b61b0b4f196c5e72e47cf06ca0c14df3cf8eedbdef0242a9d2af33623663489f ./src/api/groups.rs
|
||||
b6d586bc42b166ac05648f3da7d9aeb88efde2e9eaab5642685eb4d9cf15f95a ./src/api/history.rs
|
||||
@@ -136,10 +136,10 @@ d6b9b70a04c774173c97f7426487d5e2932d7713e12ae3fb7f64cf2b4e0b3c10 ./src/db/sched
|
||||
28ee42d08147b0f154af818065d7d014d74ee8ddd59fdef98115f5c5368056cc ./src/db/tests.rs
|
||||
f90fbb14f29a20b799b3856bdaa22812a9f0d9dfa46693f1341c160dccda8a97 ./src/db/zone_history.rs
|
||||
0e49ea4a52017b0a8501d5101b1906a7a1e8d5158acb0bb65caa43cde2836ec0 ./src/engine.rs
|
||||
f3cc7d2cbf44180372d987d7502409547eadb1c725bcce6eeb5a26cc4277b83f ./src/engine/automations.rs
|
||||
8c8d45fa9f37c724a758128726403cf64a2af2ab4e063f1b3e74e4986082de79 ./src/engine/automations.rs
|
||||
1dccb8779f87dfdbd4ccda3f02ec51273e7be2e34e85166861668685528eca79 ./src/engine/commands.rs
|
||||
357ef92c3cc42b243af4da31ac52bb360d7444ae423f58d7a13bdee79bf0a748 ./src/engine/connectivity.rs
|
||||
315116a0dbeeba1af2f72513ea5fcc238da1b5ce9501b039c5188e44976978dc ./src/engine/control_plan.rs
|
||||
828657b3c13b68792991b5ca2a26ae0b1d5c417191c83c4e5f650f62b6440096 ./src/engine/control_plan.rs
|
||||
7b48a33343d519a2ff2d81e9d757eb56a0c1beacfc0b7b8ef61f49c2ad363f9a ./src/engine/deadlines.rs
|
||||
519f67ab805f61afea107215f5df50562fa1669a48334cc015570952e25e773a ./src/engine/energy.rs
|
||||
e350aa63f3bb14ca887eaaa7555edbeae00fb584cbcaf552cc972f0c8918f5d8 ./src/engine/groups.rs
|
||||
@@ -152,7 +152,7 @@ c73691c3637465ab0f79aecf7f5428d0317799a8ab5329ed564cf57963bbe86e ./src/engine/r
|
||||
b0189f28d0f337dfd3ce0934da7a565e4a5535afc1c242214c26ed584b3b7840 ./src/engine/targets.rs
|
||||
682c8b3956c657b655746cbd19ee97ee2f4cf953bc9de67d6d70a1b14f3dd746 ./src/engine/temperature.rs
|
||||
833b72907375e75c3f42b3921ad70a8e298f5a93743bf0d0c19059aa272462d1 ./src/engine/temporary_thermostat.rs
|
||||
bf1a3840135a71ce64148559cce0fbd570ff99d31c8972cdea7447a49f6868f7 ./src/engine/tests.rs
|
||||
0d4f2df3c3881aceb41b9f8d78adde7ecbb5b39d2f8aea444b865166a0670dec ./src/engine/tests.rs
|
||||
c89ff36c6a67bf4fbf68c43e18aa0a556de2dc69263fd79db376363afc741a4f ./src/engine/zone_actions.rs
|
||||
87ab87d434a6462a2c3f25249b42c59ecb2bca6ed700ec73e95e4613349cf16f ./src/engine/zone_control.rs
|
||||
bfac95cec87f0df6ce562153cd3cfe6731359d703e6c592d2c2f7ba01ea62d99 ./src/error.rs
|
||||
@@ -163,8 +163,8 @@ da4068295f37c23222bb13bebac022d88ba7729604a49ad25438c55e45458a49 ./src/influxdb
|
||||
67e42a92295480d2f1d364958f184654cfb5d4b77e7e1df47f588bdec18868a0 ./src/influxdb/write.rs
|
||||
62f9da6ef4f5fd92701d0857773f9f6236ef25356f21b9b42236abab6ba7da53 ./src/main.rs
|
||||
23688a5cb68efded89471ce959328d27adff370d451bd9f378a283ab51437e76 ./src/models.rs
|
||||
e7b6e49d369aaf665a8aea2464950fd795957de0ad7528a002e11c55c7983f35 ./src/models/automation.rs
|
||||
a7a35e60318a620d411ec16ab8faecd34410ccba3310f612e89c06904a16539b ./src/models/control_plan.rs
|
||||
a7d40ff2b00c6352223bd6335dc734925c42d70be2c70d1cb0b23051baa6f867 ./src/models/automation.rs
|
||||
e4195a40135f408302a78cb200a54e6ef1c0e6031fb069a2431d068e5dbbdd8d ./src/models/control_plan.rs
|
||||
06357b352ff6494d83e72796b869573a8b8f36b835985a5900ac571c922b8da9 ./src/models/defaults.rs
|
||||
698dcbeba72037a251c25d07c95833f121716d949f9217f1f9429e8cd40638e5 ./src/models/device.rs
|
||||
aeab5b5acf35d38a54fd1d82e964fe56635ade69c0149ad423df317095d01555 ./src/models/flow.rs
|
||||
@@ -199,7 +199,7 @@ f13f1be3d5789539eba3fc1b59c14835f8c681eca7634e118fa3763a53aeee2b ./src/queries/
|
||||
d8a602ed8906d77593bd140315ce1bd56716038e789f53ff31762e9b3cb7220d ./src/state.rs
|
||||
b92a6cb158b494fe145b43c7641e65f6fafff47201d7d76edbec2cfd8b94835c ./systemd/gree-controller.service
|
||||
544a31cb2e5374227026afd6abd0d910381f3fca1638154ebd74e3c3d96a35d1 ./web/404.html
|
||||
1d6fa9e291ebbae40a7a8b06a7cef9dbd0ee06d88ec6b664361c37cb6c1aa281 ./web/css/styles.css
|
||||
da9cb50e003fa25989a693741c81ceb8b36c2bebbbb370c42184e2a89057c83c ./web/css/styles.css
|
||||
183d122ba366303d9952ac0e68aff4bced4e0d9a468fbe51316c13f15227402b ./web/custom-chart.html
|
||||
e98bdd7204349cce1ec6f57283509697af0bbc72280622a6c3efa6fed242db4f ./web/favicon.svg
|
||||
43f33fc21bb11df0ea149fe7fbca722a57f93890e4d9bb542ced703c1311207e ./web/index.html
|
||||
@@ -207,7 +207,7 @@ e98bdd7204349cce1ec6f57283509697af0bbc72280622a6c3efa6fed242db4f ./web/favicon.
|
||||
e7318cd92b76e8a0109dc01adc2431474be17d8bb1488cdf6ffb39dc5450909d ./web/js-dynamic/bootstrap.js
|
||||
5d57253a013fd1cb79e4b8701d4be6e394e3f2acbce73dfcd726a86e5878f1a1 ./web/js-dynamic/charts.js
|
||||
07629b331bd498e8bea769d577321bbd12d9b076264242706d4ef16165fb22fa ./web/js-dynamic/core.js
|
||||
5e681095a559fafbeca067024afb3705ba114f01fa562d487a5717d12dac0123 ./web/js-dynamic/dashboard.js
|
||||
80aaf5c56375345c67fd30c4fc1622319e4749b2859ec10613f77ac117f0441e ./web/js-dynamic/dashboard.js
|
||||
930e67432f55e8476513e808edfa9a0809a8da7479307284fcc136082a4129a4 ./web/js-dynamic/entities.js
|
||||
4612c958d7b9ccf89d6d45a11c3bc7e864bbd2ceaccc16fd7d76811ba4c74196 ./web/js-dynamic/events.js
|
||||
43c78a3871cfdb0382081ec30b8d48650450c71b44d006414b161349ac1fa659 ./web/js-dynamic/flows.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.
|
||||
|
||||
**Version: 0.15.17**
|
||||
**Version: 0.15.18**
|
||||
|
||||
Version 0.15.17 hides the Global power emergency STOP while the system is idle, keeps the green return-to-normal action visible whenever STOP is active, and shows the source Flow name for Flow-generated entries in Recently triggered automations.
|
||||
Version 0.15.18 records the exact Flow condition trace at execution time and shows the evaluated Flow variables and gates directly under Recently triggered automations in Control plan.
|
||||
|
||||
> [Full API reference](docs/API.md) — authentication, every endpoint, request bodies, response models, WebSocket events and examples.
|
||||
> Built-in API: `/api/*` and `/ws`; interactive Swagger docs: `/api-docs`; OpenAPI JSON: `/api-docs/openapi.json`.
|
||||
|
||||
+21
-21
@@ -1,13 +1,13 @@
|
||||
de0793949cf01d27d903653226ecc9b5f72523d8711f20bcab022cf42c4c4ed0 ./.env.example
|
||||
a4ec3874a2e3ab1bad28fb40bb620f7b01f64d01ad9b699306bf70ada31227db ./.gitignore
|
||||
4051d2de7fa9858545582dc6bb5a411c980a282d0b25aa3766df88597442f94a ./Cargo.lock
|
||||
4bf5b286ffb52b22a32ef3d2d5e4dfaae600c1be01c1cac0b87c7138ecb4a129 ./Cargo.toml
|
||||
dfac61e5ea474221798f0a72d6cb4d6b5a31bcd853573e14c172087c2f7e98c5 ./Cargo.lock
|
||||
f8e6fa48a584d6446e6360185b0ca320379b325d62afc062e7d2efedc2b14af1 ./Cargo.toml
|
||||
19b2943504acb8f8de280f873a8dbec4bb6ebbe3870b158f5655d4fb8c298f5f ./LICENSE
|
||||
9a429e8b766c66061e85ccd535cc1429fe1284d14fcf75daa362fea724e0bf85 ./README.md
|
||||
591cf7e1fc98bbcdf4854c28ffc22df92b47ac7cd6e81bfa07ae4f99a9baaa3c ./README.md
|
||||
29e9821e5ed216ea3565dd6d8bc0b174ed3cf9fa72c4ccebbfa99e98db3ad8f9 ./build.rs
|
||||
3c1fce0f3097e7860f8ccf6a79749af4e7e4bd43e612c6419d91c0e620480506 ./docs/API.md
|
||||
312ca0de508126a473cad4a06d35eb5b44086de37f6d0f5f4d9f5fa85e5992fe ./docs/API.md
|
||||
43af7941ec4d427f9db7ab3cc6baf3d182a72dba7a6791f14094fee138324d8d ./docs/FLOW.md
|
||||
3ef573d60de5dcba3fdb4004df53ea170440cbeae2e244a1f6acfcb3255b7c78 ./docs/openapi.json
|
||||
d3702f852b4427c67043d16d3edab40be23a1ebf9a3baf44902ef764241643dd ./docs/openapi.json
|
||||
77b8becf7a2c16a384ea85721d878b76e2d520549cb4455d9aa806e57e5a2ecd ./ha-addon/.env.example
|
||||
0ca6e58170c2b8925194431ebbdb55f0c8b377fec5cd422cd2bd257e2d9328e3 ./ha-addon/Dockerfile
|
||||
0951696a2c2e66d4d969f8e7f8641184e3012f261583b31074bc38a7a1c0cc1a ./ha-addon/README.md
|
||||
@@ -21,7 +21,7 @@ b7f0873109c52be9d7f09bea3dffc416103c50085e1f0680d11661a969479898 ./ha-addon/hom
|
||||
6509286c7b7de638dcc5d40ce53181e65d1eddc5dc36a13306dc6d87220fedbb ./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
|
||||
5aea34a2adb03ed46a93199e943d7820e34825658fefc3d7c3eb5267ac9066b0 ./ha-addon/home-assistant/custom_components/gree_controller/manifest.json
|
||||
813f932b99eda416330688504c67872148b6aeae27042f93505085cbfe06a3ed ./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 +29,10 @@ cca65482e36d48035aca178121a378fe7d578d600acff267ae81a6399c0da653 ./ha-addon/hom
|
||||
a745cc458c235158d5d70b6a33d8000fd8b40ff93bfe2f2796af0f4b3a9eef9b ./ha-addon/home-assistant/custom_components/gree_controller/translations/en.json
|
||||
50b7d6fe6329ad4ea6bee9612ab141c2f73f8382fcc2af0bb076a8e8d4dd4465 ./ha-addon/home-assistant/custom_components/gree_controller/translations/pl.json
|
||||
c5fc5c87273d82d2834a0a5a365c821a416413ed509613441e24e4dc3507c4d2 ./ha-addon/home-assistant/generated/gree_controller_entities.example.json
|
||||
69d6cf26824f8851cdf076f87c7270d6f87717a2820b68b57a82beed53d2c736 ./ha-addon/repository/gree-controller/CHANGELOG.md
|
||||
e8b1f335c9c7c5e3510aad8961f8f3e67d9fdd711d5407f1adb9db1746fd2407 ./ha-addon/repository/gree-controller/CHANGELOG.md
|
||||
50b8ba050c6b4919e4d057f7b38c1e23d3913b5b7c87552626452e9695d37251 ./ha-addon/repository/gree-controller/DOCS.md
|
||||
d3d0e54672751a3400021ffd1fdcc83a9a903be72cff32cdc3607a61aec0a31e ./ha-addon/repository/gree-controller/README.md
|
||||
c591ab21837150e313407a34a5a3758302aaafd91cd5fcebe18bb5358b702433 ./ha-addon/repository/gree-controller/config.yaml
|
||||
cf3e7106bb516598ca7d635be3d00807af024a9448632d89ee1a60d139c1c573 ./ha-addon/repository/gree-controller/README.md
|
||||
0733d428c986e22c0300c3d8a82971dc1d6cadc88d38c928667c74c93638b5df ./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
|
||||
@@ -42,8 +42,8 @@ cea12bc74c066a588a5ef0ef7bad9d4906bdbcea99f2d275429b0eefc94b4b5f ./ha-addon/run
|
||||
081e27b6e43070d44f865335c30a42a5a29668eaa6a5ea5ab6967ac4447b8e06 ./ha-addon/sync-repository.sh
|
||||
f9e31de3d109ead32bf531c074d46a087df398d62488caee0b46b5e0a1c027f7 ./ha_addon.md
|
||||
253a0bc912786e67ea7fc92a64e4a510ad973bec343a88ccfb1f28fca3e8cf01 ./lang/README.md
|
||||
859875af2aad9929fe6ecfb80244c8d09182345edd99663e54b04910268e902e ./lang/en.json
|
||||
7139d82eb65341e72ad978be3f57efbe04228b2101b19f792d665d146697d24f ./lang/pl.json
|
||||
c5c95c19ceac8969435c6f7742c86e7efa4db9bf723a0b30b098acf7fe6295fa ./lang/en.json
|
||||
9ebf7bcfd49220e828336f551251ffc86986772864e75a5a74493cee27929749 ./lang/pl.json
|
||||
d8459024f04ca514bd8e9d6bd3af872fb942fd85a7cdd5583f4a9d28aab6faba ./make_zip.py
|
||||
b14233a8987e53bbbdd6770386ba10fa166ec25c1e098275c173c544b37846fc ./presets/bedroom_window_night.json
|
||||
1960841119c0b673fb2f03621b32237552fd828045304cd221401214b997c910 ./presets/device_resilience.json
|
||||
@@ -84,7 +84,7 @@ fdcd9a5055d08037278b842e7ab69265345c5811f0a06867136c511d140bb191 ./presets/wind
|
||||
804f22123cd3e8db0fac791826c8dd9f758fb866c8e3b5655fb6d25d259dccf1 ./presets/workday_comfort.json
|
||||
fd7390d64a2378352c09382accf6efff43903d952d111b22a982f06c5b2a3b4b ./regenerate-sha.sh
|
||||
c64b1c6deeb24f20af662bfce7fa3683703914987241107ce664fa2f6d1a9dcb ./scripts/README.md
|
||||
5969f2442a8d61ac5b1303f4cd6d8dcfe80596ef5427a513ae3addb126bf0273 ./scripts/api_dev_test.py
|
||||
ff01f3a4b69bbd58e824eb6dfb8d36568c189cbc38bea21417b91ae81c4c43dc ./scripts/api_dev_test.py
|
||||
5bc736c7bc76ca80aaa406bb171d2aa91baf4c3aa8695dce0e09b888b6ab3146 ./scripts/common.sh
|
||||
6403786610ee6d2f628193c25aee0dd058d62e904aa1a31d5f62fdaae0e94b4f ./scripts/configure-gree-network.sh
|
||||
1d6e14e26e49aa9d3527f30a23668bf8d9c48b67e6628ef686c3155c012155de ./scripts/dev.sh
|
||||
@@ -100,13 +100,13 @@ b50782b3742dfbf8a319c60571c968e93fdf8547db747c759edcffae68cb98bf ./scripts/upda
|
||||
ea84f5230da97447c60dfb4f8dadd0747c92fd1f7a74d5a65d6fdb6f23cf4b6d ./src/api.rs
|
||||
0db0d81da4b8161004ddcbed2096812c285ecec9d944771670e6c8edf0775175 ./src/api/assets.rs
|
||||
1139dacbd3f6ff94bf721eb5a60d469016fb935ddcf484d71bfeb249b72c833a ./src/api/auth.rs
|
||||
9e4fc675306e111ed3db7af9822e2925d88109c31b9e309851665a975c0bd83c ./src/api/automations.rs
|
||||
a652409de6e2e2897d67d19dc16a7d4209c5c35afda39081fef627a098a739b4 ./src/api/automations.rs
|
||||
fffad7874465739cd6b508e9d7791387b864fa88420ce0f7e2fc933d129a2751 ./src/api/configuration.rs
|
||||
19bc141286a336ad67e99079496eb0ae5126f986ab28be62b5f97758e5f6969c ./src/api/debug_tokens.rs
|
||||
ca21f6d5a407e2e3532899d53ba4e8682c2fe961a46d8cd870ddc459721513ef ./src/api/device_groups.rs
|
||||
8f92909dc575ea6238f4a003f8bd4056c2752fa3247b9ab226e47f875c80b916 ./src/api/devices.rs
|
||||
4b5b784670ae761a6848b9a33fe3fb391bebd39d65e87936907428711e96ca44 ./src/api/events.rs
|
||||
ca5bc21e051222dcaf0c507e84cb3e60f52a0b612a6056847fa0aee3a4d1a672 ./src/api/flows.rs
|
||||
b1e9567cae7036af51945ce1219f537567c944c0402c2ff03edb1249403670b5 ./src/api/flows.rs
|
||||
82c02fa135132ea3ebdb4d88dd1210dc536d22f987151d7f82595ee3d3d03440 ./src/api/gree_cloud.rs
|
||||
b61b0b4f196c5e72e47cf06ca0c14df3cf8eedbdef0242a9d2af33623663489f ./src/api/groups.rs
|
||||
b6d586bc42b166ac05648f3da7d9aeb88efde2e9eaab5642685eb4d9cf15f95a ./src/api/history.rs
|
||||
@@ -135,10 +135,10 @@ d6b9b70a04c774173c97f7426487d5e2932d7713e12ae3fb7f64cf2b4e0b3c10 ./src/db/sched
|
||||
28ee42d08147b0f154af818065d7d014d74ee8ddd59fdef98115f5c5368056cc ./src/db/tests.rs
|
||||
f90fbb14f29a20b799b3856bdaa22812a9f0d9dfa46693f1341c160dccda8a97 ./src/db/zone_history.rs
|
||||
0e49ea4a52017b0a8501d5101b1906a7a1e8d5158acb0bb65caa43cde2836ec0 ./src/engine.rs
|
||||
f3cc7d2cbf44180372d987d7502409547eadb1c725bcce6eeb5a26cc4277b83f ./src/engine/automations.rs
|
||||
8c8d45fa9f37c724a758128726403cf64a2af2ab4e063f1b3e74e4986082de79 ./src/engine/automations.rs
|
||||
1dccb8779f87dfdbd4ccda3f02ec51273e7be2e34e85166861668685528eca79 ./src/engine/commands.rs
|
||||
357ef92c3cc42b243af4da31ac52bb360d7444ae423f58d7a13bdee79bf0a748 ./src/engine/connectivity.rs
|
||||
315116a0dbeeba1af2f72513ea5fcc238da1b5ce9501b039c5188e44976978dc ./src/engine/control_plan.rs
|
||||
828657b3c13b68792991b5ca2a26ae0b1d5c417191c83c4e5f650f62b6440096 ./src/engine/control_plan.rs
|
||||
7b48a33343d519a2ff2d81e9d757eb56a0c1beacfc0b7b8ef61f49c2ad363f9a ./src/engine/deadlines.rs
|
||||
519f67ab805f61afea107215f5df50562fa1669a48334cc015570952e25e773a ./src/engine/energy.rs
|
||||
e350aa63f3bb14ca887eaaa7555edbeae00fb584cbcaf552cc972f0c8918f5d8 ./src/engine/groups.rs
|
||||
@@ -151,7 +151,7 @@ c73691c3637465ab0f79aecf7f5428d0317799a8ab5329ed564cf57963bbe86e ./src/engine/r
|
||||
b0189f28d0f337dfd3ce0934da7a565e4a5535afc1c242214c26ed584b3b7840 ./src/engine/targets.rs
|
||||
682c8b3956c657b655746cbd19ee97ee2f4cf953bc9de67d6d70a1b14f3dd746 ./src/engine/temperature.rs
|
||||
833b72907375e75c3f42b3921ad70a8e298f5a93743bf0d0c19059aa272462d1 ./src/engine/temporary_thermostat.rs
|
||||
bf1a3840135a71ce64148559cce0fbd570ff99d31c8972cdea7447a49f6868f7 ./src/engine/tests.rs
|
||||
0d4f2df3c3881aceb41b9f8d78adde7ecbb5b39d2f8aea444b865166a0670dec ./src/engine/tests.rs
|
||||
c89ff36c6a67bf4fbf68c43e18aa0a556de2dc69263fd79db376363afc741a4f ./src/engine/zone_actions.rs
|
||||
87ab87d434a6462a2c3f25249b42c59ecb2bca6ed700ec73e95e4613349cf16f ./src/engine/zone_control.rs
|
||||
bfac95cec87f0df6ce562153cd3cfe6731359d703e6c592d2c2f7ba01ea62d99 ./src/error.rs
|
||||
@@ -162,8 +162,8 @@ da4068295f37c23222bb13bebac022d88ba7729604a49ad25438c55e45458a49 ./src/influxdb
|
||||
67e42a92295480d2f1d364958f184654cfb5d4b77e7e1df47f588bdec18868a0 ./src/influxdb/write.rs
|
||||
62f9da6ef4f5fd92701d0857773f9f6236ef25356f21b9b42236abab6ba7da53 ./src/main.rs
|
||||
23688a5cb68efded89471ce959328d27adff370d451bd9f378a283ab51437e76 ./src/models.rs
|
||||
e7b6e49d369aaf665a8aea2464950fd795957de0ad7528a002e11c55c7983f35 ./src/models/automation.rs
|
||||
a7a35e60318a620d411ec16ab8faecd34410ccba3310f612e89c06904a16539b ./src/models/control_plan.rs
|
||||
a7d40ff2b00c6352223bd6335dc734925c42d70be2c70d1cb0b23051baa6f867 ./src/models/automation.rs
|
||||
e4195a40135f408302a78cb200a54e6ef1c0e6031fb069a2431d068e5dbbdd8d ./src/models/control_plan.rs
|
||||
06357b352ff6494d83e72796b869573a8b8f36b835985a5900ac571c922b8da9 ./src/models/defaults.rs
|
||||
698dcbeba72037a251c25d07c95833f121716d949f9217f1f9429e8cd40638e5 ./src/models/device.rs
|
||||
aeab5b5acf35d38a54fd1d82e964fe56635ade69c0149ad423df317095d01555 ./src/models/flow.rs
|
||||
@@ -198,7 +198,7 @@ f13f1be3d5789539eba3fc1b59c14835f8c681eca7634e118fa3763a53aeee2b ./src/queries/
|
||||
d8a602ed8906d77593bd140315ce1bd56716038e789f53ff31762e9b3cb7220d ./src/state.rs
|
||||
b92a6cb158b494fe145b43c7641e65f6fafff47201d7d76edbec2cfd8b94835c ./systemd/gree-controller.service
|
||||
544a31cb2e5374227026afd6abd0d910381f3fca1638154ebd74e3c3d96a35d1 ./web/404.html
|
||||
1d6fa9e291ebbae40a7a8b06a7cef9dbd0ee06d88ec6b664361c37cb6c1aa281 ./web/css/styles.css
|
||||
da9cb50e003fa25989a693741c81ceb8b36c2bebbbb370c42184e2a89057c83c ./web/css/styles.css
|
||||
183d122ba366303d9952ac0e68aff4bced4e0d9a468fbe51316c13f15227402b ./web/custom-chart.html
|
||||
e98bdd7204349cce1ec6f57283509697af0bbc72280622a6c3efa6fed242db4f ./web/favicon.svg
|
||||
43f33fc21bb11df0ea149fe7fbca722a57f93890e4d9bb542ced703c1311207e ./web/index.html
|
||||
@@ -206,7 +206,7 @@ e98bdd7204349cce1ec6f57283509697af0bbc72280622a6c3efa6fed242db4f ./web/favicon.
|
||||
e7318cd92b76e8a0109dc01adc2431474be17d8bb1488cdf6ffb39dc5450909d ./web/js-dynamic/bootstrap.js
|
||||
5d57253a013fd1cb79e4b8701d4be6e394e3f2acbce73dfcd726a86e5878f1a1 ./web/js-dynamic/charts.js
|
||||
07629b331bd498e8bea769d577321bbd12d9b076264242706d4ef16165fb22fa ./web/js-dynamic/core.js
|
||||
5e681095a559fafbeca067024afb3705ba114f01fa562d487a5717d12dac0123 ./web/js-dynamic/dashboard.js
|
||||
80aaf5c56375345c67fd30c4fc1622319e4749b2859ec10613f77ac117f0441e ./web/js-dynamic/dashboard.js
|
||||
930e67432f55e8476513e808edfa9a0809a8da7479307284fcc136082a4129a4 ./web/js-dynamic/entities.js
|
||||
4612c958d7b9ccf89d6d45a11c3bc7e864bbd2ceaccc16fd7d76811ba4c74196 ./web/js-dynamic/events.js
|
||||
43c78a3871cfdb0382081ec30b8d48650450c71b44d006414b161349ac1fa659 ./web/js-dynamic/flows.js
|
||||
|
||||
+7
-5
@@ -1,6 +1,6 @@
|
||||
# GREE Controller API reference
|
||||
|
||||
HTTP and WebSocket API for GREE Controller **0.15.17**.
|
||||
HTTP and WebSocket API for GREE Controller **0.15.18**.
|
||||
|
||||
[← Main documentation](../README.md)
|
||||
|
||||
@@ -243,7 +243,7 @@ Response:
|
||||
{
|
||||
"status": "ok",
|
||||
"name": "gree-controller",
|
||||
"version": "0.15.17",
|
||||
"version": "0.15.18",
|
||||
"uptime_seconds": 1234,
|
||||
"control_ready": true,
|
||||
"time": "2026-08-30T06:54:00Z"
|
||||
@@ -306,7 +306,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.15.17",
|
||||
"version": "0.15.18",
|
||||
"uptime_seconds": 1234,
|
||||
"auth_required": false,
|
||||
"control_ready": true,
|
||||
@@ -955,7 +955,7 @@ Action target is either:
|
||||
- direct device: `action_device_id` + full `DeviceCommand`, or
|
||||
- group: `action_group_id`; group automation supports only power, `house`/`cool`/`heat` mode and optional `action_preset` (`auto|comfort|sleep|away`).
|
||||
|
||||
The response also contains runtime `last_fired_at`, `created_at`, `updated_at`.
|
||||
The response also contains runtime `last_fired_at`, `last_trigger_trace`, `created_at`, `updated_at`. For Flow-generated automations, `last_trigger_trace` is the snapshot of evaluated Flow blocks from the latest execution attempt (`node_id`, `kind`, `matched`, `actual`, `expected`, `config`, `inputs`).
|
||||
|
||||
Routes:
|
||||
|
||||
@@ -1056,7 +1056,7 @@ When InfluxDB is enabled, older history can be read from Influx and merged with
|
||||
|
||||
### `GET /api/control-plan`
|
||||
|
||||
Returns the latest materialized machine-readable thermostat plan. The response shape is unchanged; the bundled Web UI receives plan updates primarily through WebSocket and uses this endpoint for fallback/resynchronization.
|
||||
Returns the latest materialized machine-readable thermostat plan. The bundled Web UI receives plan updates primarily through WebSocket and uses this endpoint for fallback/resynchronization. Flow-generated entries in `rules[]` include `flow_id`, `flow_node_id` and the persisted `last_trigger_trace` snapshot used by Recently triggered automations.
|
||||
|
||||
|
||||
Top-level fields:
|
||||
@@ -1097,6 +1097,8 @@ current_schedule_id, current_schedule_name,
|
||||
next_events[]
|
||||
```
|
||||
|
||||
Each automation rule includes runtime readiness fields. Flow-generated rules also expose `flow_id`, `flow_node_id` and `last_trigger_trace[]`; the trace preserves the evaluated block configuration and observed values from the latest execution attempt.
|
||||
|
||||
This endpoint is the best way for another client to understand **desired vs actual state**, who owns control, and why a zone is blocked/paused.
|
||||
|
||||
---
|
||||
|
||||
+13
-4
@@ -2,7 +2,7 @@
|
||||
"openapi": "3.1.0",
|
||||
"info": {
|
||||
"title": "GREE Controller API",
|
||||
"version": "0.15.17",
|
||||
"version": "0.15.18",
|
||||
"summary": "Local HTTP/WebSocket API for GREE Controller",
|
||||
"description": "Local API used by the GREE Controller Web UI and Home Assistant integration.",
|
||||
"license": {
|
||||
@@ -3120,7 +3120,7 @@
|
||||
"History"
|
||||
],
|
||||
"summary": "Get resolved control plan",
|
||||
"description": "Machine-readable desired-vs-actual thermostat plan with ownership, blocking reasons, schedules, next events and per-zone control decisions. The response shape is unchanged; the bundled Web UI receives plan changes through WebSocket and uses this endpoint as a fallback/resynchronization surface.",
|
||||
"description": "Machine-readable desired-vs-actual thermostat plan with ownership, blocking reasons, schedules, next events and per-zone control decisions. Flow-generated rules include flow ownership and the persisted last_trigger_trace snapshot from the latest execution attempt. The bundled Web UI receives plan changes through WebSocket and uses this endpoint as a fallback/resynchronization surface.",
|
||||
"operationId": "controlPlan",
|
||||
"security": [
|
||||
{
|
||||
@@ -6079,7 +6079,7 @@
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"example": "0.15.17"
|
||||
"example": "0.15.18"
|
||||
},
|
||||
"uptime_seconds": {
|
||||
"type": "integer",
|
||||
@@ -7846,7 +7846,8 @@
|
||||
"enum": [
|
||||
"temperature_above",
|
||||
"temperature_below",
|
||||
"time"
|
||||
"time",
|
||||
"flow"
|
||||
],
|
||||
"example": "temperature_above"
|
||||
},
|
||||
@@ -7914,6 +7915,14 @@
|
||||
],
|
||||
"format": "date-time"
|
||||
},
|
||||
"last_trigger_trace": {
|
||||
"type": "array",
|
||||
"description": "For Flow-generated automations, snapshot of evaluated Flow blocks from the latest execution attempt.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"flow_id": {
|
||||
"type": [
|
||||
"string",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"domain": "gree_controller",
|
||||
"name": "GREE Controller",
|
||||
"version": "0.15.17",
|
||||
"version": "0.15.18",
|
||||
"config_flow": true,
|
||||
"integration_type": "hub",
|
||||
"iot_class": "local_polling",
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Changelog
|
||||
|
||||
## 0.15.18
|
||||
|
||||
- Persists the evaluated Flow trigger trace whenever a Flow-generated automation executes or reaches a failed execution attempt, so the trigger context reflects the values from that exact moment instead of current live readings.
|
||||
- Expands Control plan → Recently triggered automations with per-block Flow details: matched state, configured condition, observed value, timing/rolling-stat/rate-limit state and logic gates.
|
||||
- Keeps the newest Flow trigger details expanded by default while older recent entries remain available in compact expandable sections.
|
||||
|
||||
## 0.15.17
|
||||
|
||||
- Hides Dashboard → Global power Emergency STOP whenever all units are off and no automatic control is currently requesting work; an active STOP always keeps the green return-to-normal action visible.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Local GREE HVAC controller packaged as a Home Assistant add-on, with Web UI, HTTP/WebSocket API, built-in Swagger API documentation, UDP discovery/control, `amd64` and `aarch64` support, ingress, and database backup from `/data/gree-controller.db`.
|
||||
|
||||
Version 0.15.17 hides the Global power emergency STOP while the system is idle, keeps the green return-to-normal action visible whenever STOP is active, and shows the source Flow name for Flow-generated entries in Recently triggered automations.
|
||||
Version 0.15.18 records the exact Flow condition trace at execution time and shows the evaluated Flow variables and gates directly under Recently triggered automations in Control plan.
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: "GREE Controller"
|
||||
version: "0.15.17"
|
||||
version: "0.15.18"
|
||||
slug: "gree_controller"
|
||||
description: "Local GREE HVAC controller with Web UI, API, and Home Assistant integration"
|
||||
url: "https://git.linuxiarz.pl/gru/gree-controller-ha-addon/"
|
||||
|
||||
@@ -467,6 +467,7 @@
|
||||
"plan.reasonSourceThermostat": "Local thermostat",
|
||||
"plan.reasonSourceAutomation": "Automation",
|
||||
"plan.reasonTriggerReading": "{trigger} · now {current}",
|
||||
"plan.reasonTriggerDetails": "Trigger details · {count} Flow blocks",
|
||||
"plan.reasonLastTriggered": "Last triggered: {when}",
|
||||
"zones.enable": "Enable zone",
|
||||
"zones.disable": "Disable zone",
|
||||
|
||||
@@ -467,6 +467,7 @@
|
||||
"plan.reasonSourceThermostat": "Termostat lokalny",
|
||||
"plan.reasonSourceAutomation": "Automatyka",
|
||||
"plan.reasonTriggerReading": "{trigger} · teraz {current}",
|
||||
"plan.reasonTriggerDetails": "Szczegóły wyzwolenia · {count} bloków Flow",
|
||||
"plan.reasonLastTriggered": "Ostatnie wyzwolenie: {when}",
|
||||
"zones.enable": "Włącz strefę",
|
||||
"zones.disable": "Wyłącz strefę",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Developer smoke/integration tests for GREE Controller API 0.15.17.
|
||||
"""Developer smoke/integration tests for GREE Controller API 0.15.18.
|
||||
|
||||
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.15.17"
|
||||
DEFAULT_EXPECTED_VERSION = "0.15.18"
|
||||
|
||||
SETTINGS_PATHS: dict[str, set[str]] = {
|
||||
"/api/settings/application": {"simulator_enabled"},
|
||||
@@ -599,7 +599,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.15.17 contract", lambda: test_openapi(client, args.expected_version))
|
||||
runner.run("OpenAPI 0.15.18 contract", lambda: test_openapi(client, args.expected_version))
|
||||
runner.run("bootstrap snapshot contract", lambda: test_bootstrap_contract(client))
|
||||
runner.run("protected API requires auth", lambda: test_protected_auth(client))
|
||||
|
||||
|
||||
@@ -161,6 +161,7 @@ impl AutomationInput {
|
||||
action: self.action,
|
||||
cooldown_seconds: self.cooldown_seconds.max(30),
|
||||
last_fired_at,
|
||||
last_trigger_trace: vec![],
|
||||
action_zone_id: None,
|
||||
action_zone_preset: None,
|
||||
action_ha_domain: None,
|
||||
|
||||
@@ -1361,6 +1361,10 @@ fn compile_flow(
|
||||
let last_fired_at = previous_automations
|
||||
.get(&id)
|
||||
.and_then(|item| item.last_fired_at.clone());
|
||||
let last_trigger_trace = previous_automations
|
||||
.get(&id)
|
||||
.map(|item| item.last_trigger_trace.clone())
|
||||
.unwrap_or_default();
|
||||
let flow_runtime = previous_automations
|
||||
.get(&id)
|
||||
.map(|item| {
|
||||
@@ -1411,6 +1415,7 @@ fn compile_flow(
|
||||
action: DeviceCommand::default(),
|
||||
cooldown_seconds: 60,
|
||||
last_fired_at,
|
||||
last_trigger_trace,
|
||||
action_zone_id: None,
|
||||
action_zone_preset: None,
|
||||
action_ha_domain: None,
|
||||
|
||||
@@ -26,6 +26,7 @@ async fn run_automations(state: &AppState) -> Result<()> {
|
||||
for mut item in automations {
|
||||
if !item.enabled { continue; }
|
||||
let ready = automation_ready(&item);
|
||||
let mut trigger_trace = Vec::<Value>::new();
|
||||
let should_fire = match item.trigger_kind.as_str() {
|
||||
// Stateful Flow blocks must keep observing while an action is in cooldown. Otherwise
|
||||
// stable/change-duration state could silently span an unobserved interval.
|
||||
@@ -34,7 +35,10 @@ async fn run_automations(state: &AppState) -> Result<()> {
|
||||
let result = flow_conditions_match(state, &devices, &mut item).await;
|
||||
if item.flow_runtime != before_runtime { state.db.save_automation(&item)?; }
|
||||
match result {
|
||||
Ok(value) => value,
|
||||
Ok((value, trace)) => {
|
||||
trigger_trace = trace;
|
||||
value
|
||||
},
|
||||
Err(err) => {
|
||||
state.log("warn", "flow.condition_error", &format!("Flow automation {} condition evaluation failed: {}", item.name, err), json!({"automation_id": item.id, "flow_id": item.flow_id, "flow_node_id": item.flow_node_id}));
|
||||
false
|
||||
@@ -168,6 +172,7 @@ async fn run_automations(state: &AppState) -> Result<()> {
|
||||
flow_acknowledge_change_gates(&mut item);
|
||||
flow_record_rate_limited_execution(&mut item, fired_at.clone());
|
||||
item.last_fired_at = Some(fired_at);
|
||||
item.last_trigger_trace = trigger_trace.clone();
|
||||
item.updated_at = Utc::now();
|
||||
state.db.save_automation(&item)?;
|
||||
// Keep connected clients in sync with runtime metadata such as last_fired_at.
|
||||
@@ -191,6 +196,7 @@ async fn run_automations(state: &AppState) -> Result<()> {
|
||||
// A failed action is still an execution attempt. Apply the configured cooldown
|
||||
// so an offline/disabled target cannot be hammered on every automation cycle.
|
||||
item.last_fired_at = Some(Utc::now());
|
||||
item.last_trigger_trace = trigger_trace.clone();
|
||||
item.updated_at = Utc::now();
|
||||
state.db.save_automation(&item)?;
|
||||
state.broadcast("automation.updated", serde_json::to_value(&item)?);
|
||||
@@ -704,7 +710,7 @@ pub async fn evaluate_flow_conditions_trace(
|
||||
for condition in conditions {
|
||||
let (matched, actual) = flow_leaf_observation(state, devices, &zones, outdoor_temperature, condition, &now, &settings, overrides).await?;
|
||||
final_value &= matched;
|
||||
trace.push(json!({"node_id": condition.id, "kind": condition.kind, "matched": matched, "actual": actual, "expected": condition.config.get("value")}));
|
||||
trace.push(json!({"node_id": condition.id, "kind": condition.kind, "matched": matched, "actual": actual, "expected": condition.config.get("value"), "config": condition.config}));
|
||||
}
|
||||
return Ok((final_value, trace));
|
||||
}
|
||||
@@ -875,23 +881,24 @@ pub async fn evaluate_flow_conditions_trace(
|
||||
"matched": matched,
|
||||
"actual": actual,
|
||||
"expected": expected,
|
||||
"config": condition.config,
|
||||
"inputs": condition.inputs
|
||||
}));
|
||||
}
|
||||
Ok((final_id.and_then(|id| values.get(&id).copied()).unwrap_or(false), trace))
|
||||
}
|
||||
|
||||
async fn flow_conditions_match(state: &AppState, devices: &[Device], item: &mut Automation) -> Result<bool, AppError> {
|
||||
async fn flow_conditions_match(state: &AppState, devices: &[Device], item: &mut Automation) -> Result<(bool, Vec<Value>), AppError> {
|
||||
let overrides = HashMap::new();
|
||||
let conditions = item.flow_conditions.clone();
|
||||
let now = Local::now();
|
||||
let (matched, _) = evaluate_flow_conditions_trace(state, devices, &conditions, now.clone(), &overrides, Some(&mut item.flow_runtime)).await?;
|
||||
let (matched, trace) = evaluate_flow_conditions_trace(state, devices, &conditions, now.clone(), &overrides, Some(&mut item.flow_runtime)).await?;
|
||||
if matched && conditions.iter().any(|condition| condition.kind == "cron_trigger") {
|
||||
if let Some(last) = item.last_fired_at.as_ref().map(|value| value.with_timezone(&Local)) {
|
||||
if last.year() == now.year() && last.ordinal() == now.ordinal() && last.hour() == now.hour() && last.minute() == now.minute() { return Ok(false); }
|
||||
if last.year() == now.year() && last.ordinal() == now.ordinal() && last.hour() == now.hour() && last.minute() == now.minute() { return Ok((false, trace)); }
|
||||
}
|
||||
}
|
||||
Ok(matched)
|
||||
Ok((matched, trace))
|
||||
}
|
||||
|
||||
fn flow_condition_kind_runtime(kind: &str) -> bool {
|
||||
|
||||
@@ -326,6 +326,9 @@ pub async fn build_control_plan(state: &AppState) -> Result<ControlPlan, AppErro
|
||||
action_preset: item.action_preset,
|
||||
action: item.action,
|
||||
last_fired_at: item.last_fired_at,
|
||||
last_trigger_trace: item.last_trigger_trace,
|
||||
flow_id: item.flow_id,
|
||||
flow_node_id: item.flow_node_id,
|
||||
next_ready_at,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -431,6 +431,7 @@ mod tests {
|
||||
},
|
||||
cooldown_seconds: 30,
|
||||
last_fired_at: None,
|
||||
last_trigger_trace: vec![],
|
||||
action_zone_id: None,
|
||||
action_zone_preset: None,
|
||||
action_ha_domain: None,
|
||||
|
||||
@@ -74,6 +74,10 @@ pub struct Automation {
|
||||
pub cooldown_seconds: u64,
|
||||
#[serde(default)]
|
||||
pub last_fired_at: Option<DateTime<Utc>>,
|
||||
/// Snapshot of the evaluated Flow condition trace from the most recent execution attempt.
|
||||
/// Empty for legacy/direct automations and for Flow automations that have never executed.
|
||||
#[serde(default)]
|
||||
pub last_trigger_trace: Vec<Value>,
|
||||
/// Optional Flow-owned thermostat zone target.
|
||||
#[serde(default)]
|
||||
pub action_zone_id: Option<String>,
|
||||
|
||||
@@ -92,6 +92,12 @@ pub struct AutomationPlanRule {
|
||||
pub action_preset: Option<String>,
|
||||
pub action: DeviceCommand,
|
||||
pub last_fired_at: Option<DateTime<Utc>>,
|
||||
#[serde(default)]
|
||||
pub last_trigger_trace: Vec<Value>,
|
||||
#[serde(default)]
|
||||
pub flow_id: Option<String>,
|
||||
#[serde(default)]
|
||||
pub flow_node_id: Option<String>,
|
||||
pub next_ready_at: Option<DateTime<Utc>>,
|
||||
}
|
||||
|
||||
|
||||
@@ -4895,6 +4895,90 @@ body.simulation-standalone [data-view="simulation"] {
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
#controlPlan .plan-recent-trigger {
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
#controlPlan .plan-trigger-trace {
|
||||
grid-column: 1 / -1;
|
||||
min-width: 0;
|
||||
margin-top: 2px;
|
||||
border-top: 1px solid var(--line);
|
||||
padding-top: 7px;
|
||||
}
|
||||
|
||||
#controlPlan .plan-trigger-trace summary {
|
||||
width: max-content;
|
||||
max-width: 100%;
|
||||
cursor: pointer;
|
||||
color: var(--muted);
|
||||
font-size: 10px;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
#controlPlan .plan-trigger-trace-list {
|
||||
display: grid;
|
||||
gap: 5px;
|
||||
margin-top: 7px;
|
||||
}
|
||||
|
||||
#controlPlan .plan-trigger-trace-row {
|
||||
display: grid;
|
||||
grid-template-columns: 18px minmax(150px, 1fr) minmax(110px, .85fr);
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
padding: 5px 7px;
|
||||
border-radius: 8px;
|
||||
background: var(--surface);
|
||||
}
|
||||
|
||||
#controlPlan .plan-trigger-trace-row>div {
|
||||
display: grid;
|
||||
gap: 1px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
#controlPlan .plan-trigger-trace-row strong {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
#controlPlan .plan-trigger-trace-row small {
|
||||
overflow: hidden;
|
||||
color: var(--muted);
|
||||
font-size: 9px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#controlPlan .plan-trigger-trace-row code {
|
||||
overflow: hidden;
|
||||
color: var(--text-soft);
|
||||
font-size: 9px;
|
||||
text-align: right;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#controlPlan .plan-trigger-trace-mark {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 999px;
|
||||
font-size: 11px;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
#controlPlan .plan-trigger-trace-row.pass .plan-trigger-trace-mark {
|
||||
color: var(--accent-text);
|
||||
background: var(--accent);
|
||||
}
|
||||
|
||||
#controlPlan .plan-trigger-trace-row.fail .plan-trigger-trace-mark {
|
||||
color: var(--warning);
|
||||
background: var(--warning-soft);
|
||||
}
|
||||
|
||||
#controlPlan .plan-reason-alert {
|
||||
display: grid;
|
||||
gap: 3px;
|
||||
@@ -10939,4 +11023,13 @@ select.select-native-proxy[aria-invalid="true"]+.custom-select .custom-select-tr
|
||||
grid-template-columns: 1fr;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
#controlPlan .plan-trigger-trace-row {
|
||||
grid-template-columns: 18px minmax(0, 1fr);
|
||||
}
|
||||
|
||||
#controlPlan .plan-trigger-trace-row code {
|
||||
grid-column: 2;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
@@ -104,6 +104,86 @@ function planZoneReason(zone) {
|
||||
return tr('plan.reasonWaiting');
|
||||
}
|
||||
|
||||
|
||||
function planFlowTraceNode(rule, item) {
|
||||
const flow = rule.flow_id ? (app.flows || []).find(candidate => candidate.id === rule.flow_id) : null;
|
||||
const current = flow?.nodes?.find(node => node.id === item.node_id);
|
||||
return {
|
||||
id: item.node_id || current?.id || '',
|
||||
kind: item.kind || current?.kind || '',
|
||||
config: item.config && typeof item.config === 'object' ? item.config : (current?.config || {}),
|
||||
};
|
||||
}
|
||||
|
||||
function planFlowTraceSourceLabel(node) {
|
||||
const c = node?.config || {};
|
||||
if (!['rolling_stat', 'oscillates'].includes(node?.kind)) return '';
|
||||
if (c.source === 'outdoor_temperature') return tr('house.outdoor');
|
||||
if (c.source === 'device_temperature') return (app.devices || []).find(device => device.id === c.device_id)?.name || c.device_id || '';
|
||||
if (c.source === 'zone_temperature') return (app.zones || []).find(zone => zone.id === c.zone_id)?.name || c.zone_id || '';
|
||||
if (c.source === 'ha_numeric') return c.entity_id ? haSensorLabel(c.entity_id) : '';
|
||||
return c.source || '';
|
||||
}
|
||||
|
||||
function planFlowTraceScalar(node, value) {
|
||||
const formatted = flowSimpleSimulationActualText(node, value);
|
||||
if (formatted) return formatted;
|
||||
if (value === null || value === undefined) return '—';
|
||||
if (typeof value === 'object') return JSON.stringify(value);
|
||||
return String(value);
|
||||
}
|
||||
|
||||
function planFlowTraceActual(rule, item, node) {
|
||||
const actual = item?.actual;
|
||||
if (!actual || typeof actual !== 'object' || Array.isArray(actual)) return planFlowTraceScalar(node, actual);
|
||||
if (actual.error) return `${actual.error}${actual.entity_id ? ` · ${actual.entity_id}` : ''}`;
|
||||
if (node.kind === 'stable_for' || node.kind === 'delay') {
|
||||
const since = actual.since ? new Date(actual.since).toLocaleTimeString(locale(), { hour: '2-digit', minute: '2-digit', second: '2-digit' }) : '—';
|
||||
return `${actual.input ? tr('common.yes') : tr('common.no')} · ≥${flowDurationLabel(actual.seconds)} · ${since}`;
|
||||
}
|
||||
if (node.kind === 'state_duration') {
|
||||
const max = actual.max_seconds == null ? '∞' : flowDurationLabel(actual.max_seconds);
|
||||
return `${flowDurationLabel(actual.elapsed_seconds)} · ${flowDurationLabel(actual.min_seconds)}–${max}`;
|
||||
}
|
||||
if (node.kind === 'on_change') {
|
||||
const previous = actual.previous === null || actual.previous === undefined ? '—' : planFlowTraceScalar(node, actual.previous);
|
||||
const current = actual.current === null || actual.current === undefined ? '—' : planFlowTraceScalar(node, actual.current);
|
||||
return `${previous} → ${current}`;
|
||||
}
|
||||
if (node.kind === 'rate_limit') return `${Number(actual.used || 0)}/${Number(actual.max_count || 0)} · ${flowDurationLabel(actual.period_seconds)}`;
|
||||
if (node.kind === 'rolling_stat') {
|
||||
const sourceKind = node.config?.source;
|
||||
const tempSource = ['outdoor_temperature', 'device_temperature', 'zone_temperature'].includes(sourceKind);
|
||||
const aggregate = actual.aggregate == null ? '—' : tempSource ? fmtTemp(Number(actual.aggregate)) : Number(actual.aggregate).toFixed(2);
|
||||
const sample = actual.sample == null ? '—' : tempSource ? fmtTemp(Number(actual.sample)) : Number(actual.sample).toFixed(2);
|
||||
return `${aggregate} · x=${sample} · n=${Number(actual.samples || 0)}`;
|
||||
}
|
||||
if (node.kind === 'oscillates') {
|
||||
const span = actual.span == null ? '—' : Number(actual.span).toFixed(2);
|
||||
return `Δ=${span} · ↕=${Number(actual.direction_changes || 0)} · n=${Number(actual.samples || 0)}`;
|
||||
}
|
||||
if (node.kind === 'logic_and' || node.kind === 'logic_or') {
|
||||
return (Array.isArray(actual) ? actual : []).map(value => value ? tr('common.yes') : tr('common.no')).join(' · ') || '—';
|
||||
}
|
||||
if (node.kind === 'logic_not') return actual ? tr('common.yes') : tr('common.no');
|
||||
return JSON.stringify(actual);
|
||||
}
|
||||
|
||||
function planFlowTriggerTrace(rule, expanded = false) {
|
||||
const trace = Array.isArray(rule.last_trigger_trace) ? rule.last_trigger_trace : [];
|
||||
if (rule.trigger_kind !== 'flow' || !trace.length) return '';
|
||||
const rows = trace.map(item => {
|
||||
const node = planFlowTraceNode(rule, item);
|
||||
const meta = FLOW_NODE_META[node.kind] || { title: node.kind || item.node_id || 'Flow' };
|
||||
const source = planFlowTraceSourceLabel(node);
|
||||
const summary = [source, flowNodeSummary(node)].filter(Boolean).join(' · ');
|
||||
const actual = planFlowTraceActual(rule, item, node);
|
||||
const matched = item.matched === true;
|
||||
return `<div class="plan-trigger-trace-row ${matched ? 'pass' : 'fail'}"><span class="plan-trigger-trace-mark" aria-hidden="true">${matched ? '✓' : '×'}</span><div><strong>${esc(flowNodeTitle(meta))}</strong>${summary ? `<small>${esc(summary)}</small>` : ''}</div><code>${esc(actual)}</code></div>`;
|
||||
}).join('');
|
||||
return `<details class="plan-trigger-trace" ${expanded ? 'open' : ''}><summary>${esc(tr('plan.reasonTriggerDetails', { count: trace.length }))}</summary><div class="plan-trigger-trace-list">${rows}</div></details>`;
|
||||
}
|
||||
|
||||
function planReasonCard(plan) {
|
||||
const zones = (plan.zones || []).map(zone => {
|
||||
const reason = planZoneReason(zone);
|
||||
@@ -118,14 +198,15 @@ function planReasonCard(plan) {
|
||||
.filter(rule => rule.enabled && rule.last_fired_at)
|
||||
.sort((a, b) => new Date(b.last_fired_at) - new Date(a.last_fired_at))
|
||||
.slice(0, 4)
|
||||
.map(rule => {
|
||||
.map((rule, index) => {
|
||||
const when = new Date(rule.last_fired_at).toLocaleString(locale(), { weekday: 'short', hour: '2-digit', minute: '2-digit' });
|
||||
const triggerDevice = rule.trigger_device_id ? (app.devices || []).find(device => device.id === rule.trigger_device_id) : null;
|
||||
const current = triggerDevice?.current_temperature == null ? null : Number(triggerDevice.current_temperature);
|
||||
const trigger = Number.isFinite(current)
|
||||
? tr('plan.reasonTriggerReading', { trigger: automationTriggerLabel(rule), current: fmtTemp(current) })
|
||||
: automationTriggerLabel(rule);
|
||||
return `<li><div><strong>${esc(rule.name)}</strong><small>${esc(trigger)}</small></div><span>${esc(tr('plan.reasonLastTriggered', { when }))}</span></li>`;
|
||||
const trace = planFlowTriggerTrace(rule, index === 0);
|
||||
return `<li class="plan-recent-trigger"><div><strong>${esc(rule.name)}</strong><small>${esc(trigger)}</small></div><span>${esc(tr('plan.reasonLastTriggered', { when }))}</span>${trace}</li>`;
|
||||
}).join('');
|
||||
|
||||
const emergency = plan.emergency_stop_active
|
||||
|
||||
Reference in new issue
Block a user