mirror of
https://github.com/joBr99/nspanel-lovelace-ui.git
synced 2025-12-27 09:54:25 +01:00
Compare commits
565 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b6f36d4eac | ||
|
|
fa239f8bf0 | ||
|
|
2d1719673c | ||
|
|
e9c275216c | ||
|
|
b226b61281 | ||
|
|
056d8f95c2 | ||
|
|
52c695cf1c | ||
|
|
8805e2189c | ||
|
|
341cdb47ab | ||
|
|
3b25d47bc7 | ||
|
|
a721d4ccd7 | ||
|
|
044abda65b | ||
|
|
155b08d6d5 | ||
|
|
c038745d1b | ||
|
|
154c9aced1 | ||
|
|
f5119f86ac | ||
|
|
77b7400b04 | ||
|
|
995e7eebd2 | ||
|
|
c91ca0912a | ||
|
|
a6742f88c8 | ||
|
|
9f146ec8b3 | ||
|
|
0cccfac4a6 | ||
|
|
fbe5f9658e | ||
|
|
603d207e12 | ||
|
|
338c3af940 | ||
|
|
ce6ff734d1 | ||
|
|
4308c12508 | ||
|
|
ea0f3cc411 | ||
|
|
2b4c8d3b94 | ||
|
|
ff25f07b8f | ||
|
|
59efd21251 | ||
|
|
20ae492cf3 | ||
|
|
512a89b7d6 | ||
|
|
a6c366ed41 | ||
|
|
e13d1aaecb | ||
|
|
3b6d53c78c | ||
|
|
f789e33fe5 | ||
|
|
22455546f6 | ||
|
|
e0e9815911 | ||
|
|
3e0d0e8854 | ||
|
|
98f70b20f0 | ||
|
|
4c02b5bc26 | ||
|
|
fb841abf45 | ||
|
|
bff89f0364 | ||
|
|
27ccc0cfe7 | ||
|
|
22a54c88c8 | ||
|
|
87c58cc62d | ||
|
|
1ee19213bd | ||
|
|
0c3d173f40 | ||
|
|
cc201fb7fe | ||
|
|
44d2c6fbfc | ||
|
|
9cd2f6a464 | ||
|
|
7473d13762 | ||
|
|
f57b3fe8e4 | ||
|
|
9b1558c9a6 | ||
|
|
6181dec958 | ||
|
|
a94cf0cef3 | ||
|
|
d01ccede57 | ||
|
|
65be5ffeb0 | ||
|
|
d53afb0b20 | ||
|
|
9822870fc9 | ||
|
|
8a54d1422c | ||
|
|
3f573557f0 | ||
|
|
c2ca3b26d1 | ||
|
|
476a252a92 | ||
|
|
0af779973b | ||
|
|
8e0609a781 | ||
|
|
5dab816259 | ||
|
|
5f8409f5f1 | ||
|
|
3d85e86a95 | ||
|
|
85de880cda | ||
|
|
98269b19aa | ||
|
|
d77382ee88 | ||
|
|
e925d133d2 | ||
|
|
5ef3e8132b | ||
|
|
662b79a389 | ||
|
|
c984ff53a3 | ||
|
|
f8b748a418 | ||
|
|
bc31670760 | ||
|
|
cbf6abf4dd | ||
|
|
5c85e4a6e1 | ||
|
|
cbede2412e | ||
|
|
82d22743cc | ||
|
|
640d0dfa14 | ||
|
|
ccc62d1e6a | ||
|
|
6cec0245a3 | ||
|
|
f3c98adf06 | ||
|
|
f4487e4285 | ||
|
|
8e2780b2cb | ||
|
|
0372221973 | ||
|
|
947ef2d592 | ||
|
|
a1f39236c4 | ||
|
|
4cdd1ed586 | ||
|
|
1836d29931 | ||
|
|
fca29cfbd8 | ||
|
|
b27910c1af | ||
|
|
f046ae6031 | ||
|
|
4475ab1277 | ||
|
|
9afdb71a7c | ||
|
|
c84d78551f | ||
|
|
5e2a4b17ae | ||
|
|
acdba468b3 | ||
|
|
5803a489f5 | ||
|
|
54c8d302a8 | ||
|
|
8059905579 | ||
|
|
4dc39c1b79 | ||
|
|
16909f7e7f | ||
|
|
397932a6bc | ||
|
|
04ac10b453 | ||
|
|
ff103927e8 | ||
|
|
c6e94f80de | ||
|
|
5d4ae6247d | ||
|
|
8b63322e50 | ||
|
|
7fd5b3967a | ||
|
|
1d719446c0 | ||
|
|
3913b86228 | ||
|
|
3fddbfe451 | ||
|
|
c7b492c276 | ||
|
|
2e0cff80c1 | ||
|
|
3943dee733 | ||
|
|
41e7f3c3e2 | ||
|
|
5e373ad856 | ||
|
|
0d3d40cca2 | ||
|
|
221063a5a6 | ||
|
|
8e9b8ab476 | ||
|
|
1c6be4681e | ||
|
|
7b4f4cd863 | ||
|
|
9b285efe2d | ||
|
|
22e96f2b3a | ||
|
|
23da51f662 | ||
|
|
b395a08b6e | ||
|
|
ac07dbb185 | ||
|
|
86ab806b6e | ||
|
|
89d08ea507 | ||
|
|
deacd17fc9 | ||
|
|
4372e4193e | ||
|
|
d4cb8b548d | ||
|
|
faa2880e8d | ||
|
|
eeeccc786d | ||
|
|
3bcf2372b0 | ||
|
|
9612f882a5 | ||
|
|
aa29552a90 | ||
|
|
a38393338a | ||
|
|
d2e953410c | ||
|
|
0ac345328b | ||
|
|
11bf450e4c | ||
|
|
e54faea639 | ||
|
|
25062483c9 | ||
|
|
f58be676bf | ||
|
|
cc147d29ab | ||
|
|
78d20f81d2 | ||
|
|
29a3c8123c | ||
|
|
7807651223 | ||
|
|
deb7f6788e | ||
|
|
9ca7a4e829 | ||
|
|
855ab2b28c | ||
|
|
b1b042a25f | ||
|
|
3a82af67b1 | ||
|
|
84e2105361 | ||
|
|
bae90b2b55 | ||
|
|
f6b605443d | ||
|
|
14d337891a | ||
|
|
a3df442a6a | ||
|
|
53af81f84d | ||
|
|
02332cc094 | ||
|
|
19964f4ea6 | ||
|
|
3e777246a0 | ||
|
|
737bb80af0 | ||
|
|
07155018ef | ||
|
|
b8c0939382 | ||
|
|
985d395ba3 | ||
|
|
9f8e899af7 | ||
|
|
5359ed5e4b | ||
|
|
081d176f24 | ||
|
|
0bfe72eec9 | ||
|
|
d417aa2fb9 | ||
|
|
d647fb3b4f | ||
|
|
ebf6300b06 | ||
|
|
3977f9aa53 | ||
|
|
8478194bb0 | ||
|
|
417c99cdb9 | ||
|
|
0e8849a382 | ||
|
|
dd9ccaf076 | ||
|
|
ff461d821c | ||
|
|
6d68165fb6 | ||
|
|
489fd23edb | ||
|
|
4b39d5b438 | ||
|
|
b5a5aa41c6 | ||
|
|
e878e08675 | ||
|
|
246a7f1922 | ||
|
|
c83921ca71 | ||
|
|
c9deae3d5c | ||
|
|
8184c10e93 | ||
|
|
98746cc8d1 | ||
|
|
79fe05eb9c | ||
|
|
b2dd46411a | ||
|
|
2c7dd23220 | ||
|
|
a873e3e29e | ||
|
|
6a3b984c6c | ||
|
|
ebbcf7c21e | ||
|
|
0526b26b4a | ||
|
|
c20dab43a6 | ||
|
|
918a859a74 | ||
|
|
b3d3902399 | ||
|
|
69e02b0886 | ||
|
|
74a602c34d | ||
|
|
710bb2d884 | ||
|
|
7396806fab | ||
|
|
a87044a2b9 | ||
|
|
0c54f747b9 | ||
|
|
d6955eaad7 | ||
|
|
5638720336 | ||
|
|
e33875e9f5 | ||
|
|
9532ca2442 | ||
|
|
47f59e1b63 | ||
|
|
b9195101da | ||
|
|
34a9424c29 | ||
|
|
54ce2a1c10 | ||
|
|
5166fb1f58 | ||
|
|
5e9434b7eb | ||
|
|
a7398e54e3 | ||
|
|
ac54e042ea | ||
|
|
4f17085a81 | ||
|
|
c864eb6e73 | ||
|
|
828aa8fd21 | ||
|
|
84615fad05 | ||
|
|
b90b50395c | ||
|
|
c27a23e5fe | ||
|
|
1b33ddb207 | ||
|
|
d68de45c3b | ||
|
|
5b46b39dac | ||
|
|
2d0201759d | ||
|
|
104788e2a4 | ||
|
|
4f1139a531 | ||
|
|
f673aad38e | ||
|
|
c8a8e1351c | ||
|
|
5d84b59bbd | ||
|
|
2a807702f4 | ||
|
|
448b9cb30c | ||
|
|
248dc3a1c9 | ||
|
|
cd76c0528e | ||
|
|
58e2febf64 | ||
|
|
0372b034f6 | ||
|
|
1d730a0ce5 | ||
|
|
1a629ee8d5 | ||
|
|
cd563ad1ce | ||
|
|
ec18b6349b | ||
|
|
4d7d87d62a | ||
|
|
15a021a58f | ||
|
|
63c85e6b96 | ||
|
|
6a94795a67 | ||
|
|
d302567369 | ||
|
|
f8d6a1543d | ||
|
|
6df5a68682 | ||
|
|
7e1cc36805 | ||
|
|
491ed21f98 | ||
|
|
e53cf5dab0 | ||
|
|
e853889247 | ||
|
|
19b0fe4052 | ||
|
|
d94d937d77 | ||
|
|
e5c1f0588a | ||
|
|
dd88ebe5da | ||
|
|
5536335ac9 | ||
|
|
df4fff6911 | ||
|
|
3dd83fde66 | ||
|
|
f50b1ececa | ||
|
|
ebee7b379e | ||
|
|
255db25f58 | ||
|
|
19050079d4 | ||
|
|
8d97f98a29 | ||
|
|
137ca5855e | ||
|
|
7707b48622 | ||
|
|
193546d1ed | ||
|
|
6703bca1d0 | ||
|
|
5739947586 | ||
|
|
5e1a7f2102 | ||
|
|
a0e574391b | ||
|
|
bd107d930a | ||
|
|
66f83732bb | ||
|
|
e796891d8e | ||
|
|
ba46bc9189 | ||
|
|
64ff369a90 | ||
|
|
92616429ba | ||
|
|
377383d672 | ||
|
|
52d405a6d6 | ||
|
|
2e1492c4fa | ||
|
|
16673df8cf | ||
|
|
cb4c26acfd | ||
|
|
fda7ca4574 | ||
|
|
8e2e8d1e82 | ||
|
|
4e36f47774 | ||
|
|
858dac73d0 | ||
|
|
3cccefb715 | ||
|
|
44640f33d2 | ||
|
|
2ae3b9bd8e | ||
|
|
2db991a371 | ||
|
|
2e52abd76c | ||
|
|
03c3acd214 | ||
|
|
c26b277c56 | ||
|
|
3f7fd40d17 | ||
|
|
0b01c0d236 | ||
|
|
3107b73430 | ||
|
|
5d421ae525 | ||
|
|
56a8495787 | ||
|
|
a12bc03dd7 | ||
|
|
6b1a65f8f4 | ||
|
|
9d94155480 | ||
|
|
3b46759134 | ||
|
|
8d21c653ae | ||
|
|
d983c44db7 | ||
|
|
467a1d92bb | ||
|
|
157d3e3e66 | ||
|
|
51bb320dce | ||
|
|
12c99c6857 | ||
|
|
62e905f336 | ||
|
|
9b5964a758 | ||
|
|
9c49a9c67d | ||
|
|
0a2461f4a5 | ||
|
|
49577ddbb6 | ||
|
|
6172b0c35f | ||
|
|
e7cc10692b | ||
|
|
221d2c717d | ||
|
|
2b54f742c5 | ||
|
|
f02eddcebe | ||
|
|
c25a5cef67 | ||
|
|
0f69ee951c | ||
|
|
fd6650db50 | ||
|
|
f2ad80665a | ||
|
|
cff9c94c27 | ||
|
|
b6fdc12820 | ||
|
|
01265faef9 | ||
|
|
a2feae891e | ||
|
|
bd24d4bcd1 | ||
|
|
0efbd9e23c | ||
|
|
4aab72fb10 | ||
|
|
aa266da5ac | ||
|
|
49987d55ce | ||
|
|
c6939efd70 | ||
|
|
f7f853f05e | ||
|
|
1faa540a70 | ||
|
|
1746c876bd | ||
|
|
cd0c015fea | ||
|
|
760b25b7a2 | ||
|
|
eccfad5615 | ||
|
|
27034e4bae | ||
|
|
99376c8fc2 | ||
|
|
17e7ba1ef2 | ||
|
|
38526890cc | ||
|
|
ae9b33d5f0 | ||
|
|
ff96812d26 | ||
|
|
0359a4b3dc | ||
|
|
f75dd3a800 | ||
|
|
a992dc56c5 | ||
|
|
576176e1cc | ||
|
|
1d3914ce86 | ||
|
|
b2f338cad8 | ||
|
|
74a329ca29 | ||
|
|
29ae1b4034 | ||
|
|
ae5cab9830 | ||
|
|
a986e588b5 | ||
|
|
8c84c1050f | ||
|
|
c3ded4d817 | ||
|
|
db32de68e3 | ||
|
|
f76f2ca393 | ||
|
|
8449257628 | ||
|
|
2bd3d0d290 | ||
|
|
117798a3f5 | ||
|
|
01392bcbf8 | ||
|
|
5a3478d916 | ||
|
|
f3b545fd90 | ||
|
|
e7a6a05a1b | ||
|
|
f65ff57a95 | ||
|
|
9a8f53e890 | ||
|
|
e94c711f12 | ||
|
|
4cc8455fff | ||
|
|
943bb93398 | ||
|
|
0a1eb8c2e5 | ||
|
|
b7fd06413d | ||
|
|
a2b805f4e1 | ||
|
|
bc69af7b6b | ||
|
|
c36202878f | ||
|
|
60f31595d4 | ||
|
|
7194d7f613 | ||
|
|
af02a70600 | ||
|
|
77d8e0607d | ||
|
|
d6d12bc93c | ||
|
|
ead1def4bb | ||
|
|
14e944885f | ||
|
|
a075e0cba8 | ||
|
|
dd14e66f10 | ||
|
|
ce0892b986 | ||
|
|
71b84cc8d3 | ||
|
|
fd3ce243a6 | ||
|
|
aa3e90ef98 | ||
|
|
2621b22ffd | ||
|
|
6460f5f4ff | ||
|
|
e45560c27f | ||
|
|
0c6cd158dd | ||
|
|
f11de05eb3 | ||
|
|
ef47efb9aa | ||
|
|
54422eccaa | ||
|
|
02004f4b6d | ||
|
|
58278c5388 | ||
|
|
ff7d2020f7 | ||
|
|
160420fe82 | ||
|
|
56703ec458 | ||
|
|
9947664ae8 | ||
|
|
4d3f54439e | ||
|
|
6254f369f4 | ||
|
|
9b98cac4c8 | ||
|
|
71f3b75ab2 | ||
|
|
1a5cf8a2f7 | ||
|
|
33712b198d | ||
|
|
1fd5784a54 | ||
|
|
3904ca2343 | ||
|
|
8ebd0f5193 | ||
|
|
8c9bca3f25 | ||
|
|
6908744669 | ||
|
|
d0e463de98 | ||
|
|
f4c7287dfd | ||
|
|
a33df14761 | ||
|
|
3afc41269c | ||
|
|
11add2bfcc | ||
|
|
dd84fa16e5 | ||
|
|
e823c0f1ec | ||
|
|
56c104a5bc | ||
|
|
bfb2c2eaab | ||
|
|
7d57205ac2 | ||
|
|
4b81b1794d | ||
|
|
f5019b494f | ||
|
|
5102b8b955 | ||
|
|
089e553944 | ||
|
|
dfc07a6d76 | ||
|
|
b7687e006c | ||
|
|
10cf15bebd | ||
|
|
fc3d4adc72 | ||
|
|
bc330d5aaf | ||
|
|
c8a8feace2 | ||
|
|
9afdaa4cbc | ||
|
|
18c7f2eb9c | ||
|
|
de237171ef | ||
|
|
a4b90944e8 | ||
|
|
cb44fcc8c9 | ||
|
|
03bae9e9bd | ||
|
|
1ec463f6c7 | ||
|
|
5420abcfaa | ||
|
|
e2530cdf62 | ||
|
|
b14687cb30 | ||
|
|
360fb881f1 | ||
|
|
90d35a8574 | ||
|
|
73a0ba468e | ||
|
|
4e7119768b | ||
|
|
8bfa6deb76 | ||
|
|
e87febc54a | ||
|
|
43df10e823 | ||
|
|
e2acb70a1c | ||
|
|
f8774af675 | ||
|
|
9ddb6c7834 | ||
|
|
330e5fecdf | ||
|
|
6cc41bf510 | ||
|
|
956bd23a56 | ||
|
|
f1ce806ded | ||
|
|
7748c22292 | ||
|
|
131aa491b9 | ||
|
|
dbc5ff7ccd | ||
|
|
5c3f366e53 | ||
|
|
b1b679701e | ||
|
|
c489f07c0a | ||
|
|
14bc7dedec | ||
|
|
d4067c5ddb | ||
|
|
50209418d7 | ||
|
|
8f3c74165d | ||
|
|
b7b8f389eb | ||
|
|
9082ed20f3 | ||
|
|
f807406a97 | ||
|
|
93aafe259b | ||
|
|
b96fc6e6bd | ||
|
|
1996b29c60 | ||
|
|
c8eb476ca8 | ||
|
|
aeaa995a0a | ||
|
|
b35122868f | ||
|
|
1cb974494f | ||
|
|
723ecde4cd | ||
|
|
f29e5c4978 | ||
|
|
46ffff7eea | ||
|
|
774c920591 | ||
|
|
f27eb07827 | ||
|
|
da8362d81d | ||
|
|
6e38d4f38d | ||
|
|
2344c9a9ed | ||
|
|
5180f0f869 | ||
|
|
b4f2789834 | ||
|
|
78c6029200 | ||
|
|
dca112e42b | ||
|
|
5ad16dd735 | ||
|
|
723be0735e | ||
|
|
a5bfb9388f | ||
|
|
9c6f24f984 | ||
|
|
59843ffea5 | ||
|
|
4de9c4a12f | ||
|
|
3eb05e5a84 | ||
|
|
5d7a7ed1a4 | ||
|
|
7124a22c38 | ||
|
|
fa4d65a383 | ||
|
|
d26306f892 | ||
|
|
9c0bb037fb | ||
|
|
4b73e20b9b | ||
|
|
3940a0c2e9 | ||
|
|
8f57d4a642 | ||
|
|
3979fdf6a0 | ||
|
|
4cd47126eb | ||
|
|
eb0dd79c80 | ||
|
|
3a39a8ca0e | ||
|
|
b5c4a2128b | ||
|
|
41f43fe5d0 | ||
|
|
f3f93b7136 | ||
|
|
2fb1855842 | ||
|
|
9a3627427f | ||
|
|
94fbf0a5f7 | ||
|
|
caddec1190 | ||
|
|
03367ea27d | ||
|
|
8e792ae8fc | ||
|
|
0a03f736ce | ||
|
|
8d7f6ffea5 | ||
|
|
93a6a7a88a | ||
|
|
3913b17596 | ||
|
|
d08e8eb40c | ||
|
|
c2d281658e | ||
|
|
108582cbfb | ||
|
|
b17db265f4 | ||
|
|
206739dcc5 | ||
|
|
adcb618a11 | ||
|
|
dfba3b6e84 | ||
|
|
2726859135 | ||
|
|
c0e20e6f25 | ||
|
|
148c2fc5a2 | ||
|
|
526f5e8946 | ||
|
|
8cd17b9d9a | ||
|
|
70ff46ab4b | ||
|
|
770348b07b | ||
|
|
4795cc23ad | ||
|
|
bae64dcee5 | ||
|
|
953a8d7110 | ||
|
|
3b5eaac976 | ||
|
|
6e28237ec5 | ||
|
|
b8c47948c3 | ||
|
|
0e8f9ad220 | ||
|
|
79e43e2740 | ||
|
|
c32d2958a6 | ||
|
|
3b7c934972 | ||
|
|
40f29d09c1 | ||
|
|
b601f2d860 | ||
|
|
5953d7c8dd | ||
|
|
e9859c0d32 | ||
|
|
4ad997515f | ||
|
|
ba637cf11e | ||
|
|
a4abcd1734 | ||
|
|
86bbd36813 | ||
|
|
c9dffc431c | ||
|
|
04ffd6257e | ||
|
|
4102f56cee | ||
|
|
6a62a6206a | ||
|
|
0bddceccfa | ||
|
|
09156fbc89 | ||
|
|
76d0075c7d |
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -58,5 +58,5 @@ _If applicable, add screenshots/pictures to help explain your problem._
|
|||||||
_Add any other context about the problem here._
|
_Add any other context about the problem here._
|
||||||
_Please note here in case you are using ioBroker_
|
_Please note here in case you are using ioBroker_
|
||||||
|
|
||||||
### PANEL / FIRMWARE VERION
|
### PANEL / FIRMWARE VERSION
|
||||||
_Please add the Panel/Firmware Version you are using (EU, US-L or US-P)_
|
_Please add the Panel/Firmware Version you are using (EU, US-L or US-P)_
|
||||||
|
|||||||
2
.github/ISSUE_TEMPLATE/feature-request.md
vendored
2
.github/ISSUE_TEMPLATE/feature-request.md
vendored
@@ -24,5 +24,5 @@ _A clear and concise description of what the feature should do._
|
|||||||
### ADDITIONAL CONTEXT
|
### ADDITIONAL CONTEXT
|
||||||
_Add any other context about the problem here._
|
_Add any other context about the problem here._
|
||||||
|
|
||||||
### PANEL / FIRMWARE VERION
|
### PANEL / FIRMWARE VERSION
|
||||||
_Please add the Panel/Firmware Version you are using (EU, US-L or US-P)_
|
_Please add the Panel/Firmware Version you are using (EU, US-L or US-P)_
|
||||||
|
|||||||
8
.github/workflows/builder.yaml
vendored
8
.github/workflows/builder.yaml
vendored
@@ -21,7 +21,7 @@ jobs:
|
|||||||
changed: ${{ steps.changed_addons.outputs.changed }}
|
changed: ${{ steps.changed_addons.outputs.changed }}
|
||||||
steps:
|
steps:
|
||||||
- name: Check out the repository
|
- name: Check out the repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Get changed files
|
- name: Get changed files
|
||||||
id: changed_files
|
id: changed_files
|
||||||
@@ -68,7 +68,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check out repository
|
- name: Check out repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Get information
|
- name: Get information
|
||||||
id: info
|
id: info
|
||||||
@@ -92,7 +92,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Login to GitHub Container Registry
|
- name: Login to GitHub Container Registry
|
||||||
if: env.BUILD_ARGS != '--test'
|
if: env.BUILD_ARGS != '--test'
|
||||||
uses: docker/login-action@v3.0.0
|
uses: docker/login-action@v3.6.0
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.repository_owner }}
|
username: ${{ github.repository_owner }}
|
||||||
@@ -100,7 +100,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build ${{ matrix.addon }} add-on
|
- name: Build ${{ matrix.addon }} add-on
|
||||||
if: steps.check.outputs.build_arch == 'true'
|
if: steps.check.outputs.build_arch == 'true'
|
||||||
uses: home-assistant/builder@2023.09.0
|
uses: home-assistant/builder@2025.09.0
|
||||||
with:
|
with:
|
||||||
args: |
|
args: |
|
||||||
${{ env.BUILD_ARGS }} \
|
${{ env.BUILD_ARGS }} \
|
||||||
|
|||||||
8
.github/workflows/codeql-analysis.yml
vendored
8
.github/workflows/codeql-analysis.yml
vendored
@@ -43,11 +43,11 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v2
|
uses: github/codeql-action/init@v3
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
@@ -58,7 +58,7 @@ jobs:
|
|||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@v2
|
uses: github/codeql-action/autobuild@v3
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
# 📚 https://git.io/JvXDl
|
# 📚 https://git.io/JvXDl
|
||||||
@@ -72,4 +72,4 @@ jobs:
|
|||||||
# make release
|
# make release
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v2
|
uses: github/codeql-action/analyze@v3
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
name: docs-ci
|
name: docs-ci
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- dev
|
||||||
paths:
|
paths:
|
||||||
- docs/*
|
- docs/*
|
||||||
- .github/workflows/docs.yml
|
- .github/workflows/docs.yml
|
||||||
@@ -15,21 +15,14 @@ jobs:
|
|||||||
deploy:
|
deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: actions/setup-python@v4
|
- uses: actions/setup-python@v6
|
||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
- run: pip install mkdocs-material mkdocs-video markdown-include mike
|
- run: pip install mkdocs-material mkdocs-video markdown-include mike
|
||||||
- run: cp HMI/README.md docs/hmi-serial-protocol.md
|
- run: cp HMI/README.md docs/hmi-serial-protocol.md
|
||||||
#- run: mkdocs gh-deploy --force
|
|
||||||
- run: git config --global user.name Docs deploy
|
- run: git config --global user.name Docs deploy
|
||||||
- run: git config --global user.email docs@dummy.bot.com
|
- run: git config --global user.email docs@dummy.bot.com
|
||||||
- run: mike deploy --push --update-aliases dev
|
- run: mike deploy --push --update-aliases dev
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
29
.github/workflows/docs-release.yml
vendored
Normal file
29
.github/workflows/docs-release.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
name: docs-ci
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths:
|
||||||
|
- docs/*
|
||||||
|
- .github/workflows/docs-release.yml
|
||||||
|
- mkdocs.yml
|
||||||
|
- HMI/README.md
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v5
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- uses: actions/setup-python@v6
|
||||||
|
with:
|
||||||
|
python-version: 3.x
|
||||||
|
- run: pip install mkdocs-material mkdocs-video markdown-include mike
|
||||||
|
- run: cp HMI/README.md docs/hmi-serial-protocol.md
|
||||||
|
- run: git config --global user.name Docs deploy
|
||||||
|
- run: git config --global user.email docs@dummy.bot.com
|
||||||
|
- run: mike set-default stable
|
||||||
|
- run: mike deploy --push --update-aliases stable
|
||||||
2
.github/workflows/hacs-validation.yaml
vendored
2
.github/workflows/hacs-validation.yaml
vendored
@@ -11,7 +11,7 @@ jobs:
|
|||||||
name: HACS Action
|
name: HACS Action
|
||||||
runs-on: "ubuntu-latest"
|
runs-on: "ubuntu-latest"
|
||||||
steps:
|
steps:
|
||||||
- uses: "actions/checkout@v4"
|
- uses: "actions/checkout@v5"
|
||||||
- name: HACS Action
|
- name: HACS Action
|
||||||
uses: "hacs/action@main"
|
uses: "hacs/action@main"
|
||||||
with:
|
with:
|
||||||
|
|||||||
4
.github/workflows/iobroker-localization.yml
vendored
4
.github/workflows/iobroker-localization.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
|||||||
gen-ioBroker-localization:
|
gen-ioBroker-localization:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.head_ref }}
|
ref: ${{ github.head_ref }}
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ jobs:
|
|||||||
python HMI/code_gen/localization/iobroker.py
|
python HMI/code_gen/localization/iobroker.py
|
||||||
mv ioBroker_NSPanel_locales.json ioBroker/ioBroker_NSPanel_locales.json
|
mv ioBroker_NSPanel_locales.json ioBroker/ioBroker_NSPanel_locales.json
|
||||||
|
|
||||||
- uses: stefanzweifel/git-auto-commit-action@v5
|
- uses: stefanzweifel/git-auto-commit-action@v7
|
||||||
with:
|
with:
|
||||||
commit_message: Update iobroker localization file
|
commit_message: Update iobroker localization file
|
||||||
#file_pattern: "**.txt"
|
#file_pattern: "**.txt"
|
||||||
|
|||||||
6
.github/workflows/lint.yaml
vendored
6
.github/workflows/lint.yaml
vendored
@@ -18,7 +18,7 @@ jobs:
|
|||||||
addons: ${{ steps.addons.outputs.addons_list }}
|
addons: ${{ steps.addons.outputs.addons_list }}
|
||||||
steps:
|
steps:
|
||||||
- name: ⤵️ Check out code from GitHub
|
- name: ⤵️ Check out code from GitHub
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: 🔍 Find add-on directories
|
- name: 🔍 Find add-on directories
|
||||||
id: addons
|
id: addons
|
||||||
@@ -33,9 +33,9 @@ jobs:
|
|||||||
path: ${{ fromJson(needs.find.outputs.addons) }}
|
path: ${{ fromJson(needs.find.outputs.addons) }}
|
||||||
steps:
|
steps:
|
||||||
- name: ⤵️ Check out code from GitHub
|
- name: ⤵️ Check out code from GitHub
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: 🚀 Run Home Assistant Add-on Lint
|
- name: 🚀 Run Home Assistant Add-on Lint
|
||||||
uses: frenck/action-addon-linter@v2.15
|
uses: frenck/action-addon-linter@v2.18
|
||||||
with:
|
with:
|
||||||
path: "./${{ matrix.path }}"
|
path: "./${{ matrix.path }}"
|
||||||
|
|||||||
4
.github/workflows/nextion2text.yml
vendored
4
.github/workflows/nextion2text.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.head_ref }}
|
ref: ${{ github.head_ref }}
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ jobs:
|
|||||||
find -name "**.txt"
|
find -name "**.txt"
|
||||||
rm Nextion2Text.py* ignore-id.py out.txt
|
rm Nextion2Text.py* ignore-id.py out.txt
|
||||||
|
|
||||||
- uses: stefanzweifel/git-auto-commit-action@v5
|
- uses: stefanzweifel/git-auto-commit-action@v7
|
||||||
with:
|
with:
|
||||||
commit_message: ${{ steps.last-commit-message.outputs.msg }} (add nextion2text)
|
commit_message: ${{ steps.last-commit-message.outputs.msg }} (add nextion2text)
|
||||||
#file_pattern: "**.txt"
|
#file_pattern: "**.txt"
|
||||||
|
|||||||
@@ -1,17 +1,5 @@
|
|||||||
--- HMI/n2t-out
|
--- HMI/n2t-out
|
||||||
+++ HMI/US/landscape/n2t-out
|
+++ HMI/US/landscape/n2t-out
|
||||||
├── file list
|
|
||||||
│ @@ -1,10 +1,9 @@
|
|
||||||
│ Program.s.txt
|
|
||||||
│ cardAlarm.txt
|
|
||||||
│ -cardBurnRec.txt
|
|
||||||
│ cardChart.txt
|
|
||||||
│ cardEntities.txt
|
|
||||||
│ cardGrid.txt
|
|
||||||
│ cardGrid2.txt
|
|
||||||
│ cardLChart.txt
|
|
||||||
│ cardMedia.txt
|
|
||||||
│ cardPower.txt
|
|
||||||
│ --- HMI/n2t-out/Program.s.txt
|
│ --- HMI/n2t-out/Program.s.txt
|
||||||
├── +++ HMI/US/landscape/n2t-out/Program.s.txt
|
├── +++ HMI/US/landscape/n2t-out/Program.s.txt
|
||||||
│ @@ -13,10 +13,10 @@
|
│ @@ -13,10 +13,10 @@
|
||||||
@@ -114,6 +102,49 @@
|
|||||||
│ crcputs sys0,2
|
│ crcputs sys0,2
|
||||||
│ crcputs tSend.txt,0
|
│ crcputs tSend.txt,0
|
||||||
│ //send cmd
|
│ //send cmd
|
||||||
|
│ --- HMI/n2t-out/popupLight.txt
|
||||||
|
├── +++ HMI/US/landscape/n2t-out/popupLight.txt
|
||||||
|
│ @@ -453,19 +453,14 @@
|
||||||
|
│ ucopy strCommand.txt,4,payloadLength-5,0
|
||||||
|
│ // write instruction to tInstuction (debug output, but used as variable here, ui elements will be disabled by default)
|
||||||
|
│ spstr strCommand.txt,tInstruction.txt,"~",0
|
||||||
|
│ spstr strCommand.txt,tTmp.txt,"~",1
|
||||||
|
│ if(tInstruction.txt=="entityUpdateDetail"&&entn.txt==tTmp.txt)
|
||||||
|
│ {
|
||||||
|
│ // change icon
|
||||||
|
│ - spstr strCommand.txt,tTmp.txt,"~",2
|
||||||
|
│ - if(tTmp.txt!="")
|
||||||
|
│ - {
|
||||||
|
│ - tIcon1.txt=tTmp.txt
|
||||||
|
│ - }
|
||||||
|
│ //spstr strCommand.txt,tIcon1.txt,"~",2
|
||||||
|
│ vis tIcon1,1
|
||||||
|
│ // change icon color
|
||||||
|
│ spstr strCommand.txt,tTmp.txt,"~",3
|
||||||
|
│ covx tTmp.txt,sys0,0,0
|
||||||
|
│ tIcon1.pco=sys0
|
||||||
|
│ // get Button State
|
||||||
|
│ --- HMI/n2t-out/popupNotify.txt
|
||||||
|
├── +++ HMI/US/landscape/n2t-out/popupNotify.txt
|
||||||
|
│ @@ -439,18 +439,14 @@
|
||||||
|
│ {
|
||||||
|
│ page cardPower
|
||||||
|
│ }
|
||||||
|
│ if(tId.txt=="cardChart")
|
||||||
|
│ {
|
||||||
|
│ page cardChart
|
||||||
|
│ }
|
||||||
|
│ - if(tId.txt=="cardLChart")
|
||||||
|
│ - {
|
||||||
|
│ - page cardLChart
|
||||||
|
│ - }
|
||||||
|
│ }
|
||||||
|
│ // end of user code
|
||||||
|
│ udelete payloadLength-1
|
||||||
|
│ bufferPos=0
|
||||||
|
│ }
|
||||||
|
│ }
|
||||||
|
│ }
|
||||||
│ --- HMI/n2t-out/screensaver.txt
|
│ --- HMI/n2t-out/screensaver.txt
|
||||||
├── +++ HMI/US/landscape/n2t-out/screensaver.txt
|
├── +++ HMI/US/landscape/n2t-out/screensaver.txt
|
||||||
│ @@ -19,15 +19,14 @@
|
│ @@ -19,15 +19,14 @@
|
||||||
@@ -221,7 +252,7 @@
|
|||||||
│ vis p0,0
|
│ vis p0,0
|
||||||
│ vis tNotifyHead,0
|
│ vis tNotifyHead,0
|
||||||
│ vis tNotifyText,0
|
│ vis tNotifyText,0
|
||||||
│ @@ -41,17 +40,14 @@
|
│ @@ -41,52 +40,19 @@
|
||||||
│ }
|
│ }
|
||||||
│ tDate.txt=pageIcons.vaDate.txt
|
│ tDate.txt=pageIcons.vaDate.txt
|
||||||
│ dim=dimValue
|
│ dim=dimValue
|
||||||
@@ -232,14 +263,80 @@
|
|||||||
│ - Postinitialize Event
|
│ - Postinitialize Event
|
||||||
│ - click m0,1
|
│ - click m0,1
|
||||||
│ -
|
│ -
|
||||||
|
│ -Variable (string) entn1
|
||||||
|
│ - Attributes
|
||||||
|
│ - Scope : local
|
||||||
|
│ - Text :
|
||||||
|
│ - Max. Text Size: 14
|
||||||
|
│ -
|
||||||
|
│ -Variable (string) entn2
|
||||||
|
│ - Attributes
|
||||||
|
│ - Scope : local
|
||||||
|
│ - Text :
|
||||||
|
│ - Max. Text Size: 14
|
||||||
|
│ -
|
||||||
|
│ -Variable (string) entn3
|
||||||
|
│ - Attributes
|
||||||
|
│ - Scope : local
|
||||||
|
│ - Text :
|
||||||
|
│ - Max. Text Size: 14
|
||||||
|
│ -
|
||||||
|
│ -Variable (string) entn4
|
||||||
|
│ - Attributes
|
||||||
|
│ - Scope : local
|
||||||
|
│ - Text :
|
||||||
|
│ - Max. Text Size: 14
|
||||||
|
│ -
|
||||||
|
│ -Variable (string) entn5
|
||||||
|
│ - Attributes
|
||||||
|
│ - Scope : local
|
||||||
|
│ - Text :
|
||||||
|
│ - Max. Text Size: 14
|
||||||
|
│ -
|
||||||
│ Variable (string) strCommand
|
│ Variable (string) strCommand
|
||||||
│ Attributes
|
│ Attributes
|
||||||
│ Scope : local
|
│ Scope : local
|
||||||
│ Text :
|
│ Text :
|
||||||
│ Max. Text Size: 1979
|
│ - Max. Text Size: 1935
|
||||||
|
│ + Max. Text Size: 1979
|
||||||
│
|
│
|
||||||
│ Variable (string) strTmp
|
│ Variable (string) strTmp
|
||||||
│ @@ -376,34 +372,14 @@
|
│ Attributes
|
||||||
|
│ Scope : local
|
||||||
|
│ Text :
|
||||||
|
│ Max. Text Size: 2
|
||||||
|
│
|
||||||
|
│ @@ -96,27 +62,27 @@
|
||||||
|
│ Text :
|
||||||
|
│ Max. Text Size: 25
|
||||||
|
│
|
||||||
|
│ Variable (string) tInstruction
|
||||||
|
│ Attributes
|
||||||
|
│ Scope : local
|
||||||
|
│ Text :
|
||||||
|
│ - Max. Text Size: 15
|
||||||
|
│ + Max. Text Size: 50
|
||||||
|
│
|
||||||
|
│ Variable (string) tSend
|
||||||
|
│ Attributes
|
||||||
|
│ Scope : local
|
||||||
|
│ Text :
|
||||||
|
│ Max. Text Size: 50
|
||||||
|
│
|
||||||
|
│ Variable (string) tTmp
|
||||||
|
│ Attributes
|
||||||
|
│ Scope : local
|
||||||
|
│ Text :
|
||||||
|
│ - Max. Text Size: 30
|
||||||
|
│ + Max. Text Size: 50
|
||||||
|
│
|
||||||
|
│ Variable (int32) vaTap
|
||||||
|
│ Attributes
|
||||||
|
│ Scope: local
|
||||||
|
│ Value: 0
|
||||||
|
│
|
||||||
|
│ Variable (int32) xc1
|
||||||
|
│ @@ -370,165 +336,50 @@
|
||||||
│ Scope : local
|
│ Scope : local
|
||||||
│ Dragging : 0
|
│ Dragging : 0
|
||||||
│ Send Component ID : disabled
|
│ Send Component ID : disabled
|
||||||
@@ -247,6 +344,137 @@
|
|||||||
│ Text :
|
│ Text :
|
||||||
│ Max. Text Size : 4
|
│ Max. Text Size : 4
|
||||||
│
|
│
|
||||||
|
│ - Events
|
||||||
|
│ - Touch Press Event
|
||||||
|
│ - tSend.txt="event,buttonPress2,"+entn1.txt+",button"
|
||||||
|
│ - if(entn1.txt=="")
|
||||||
|
│ - {
|
||||||
|
│ - tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.txt
|
||||||
|
│ - }
|
||||||
|
│ - //send calc crc
|
||||||
|
│ - btlen tSend.txt,sys0
|
||||||
|
│ - crcrest 1,0xffff // reset CRC
|
||||||
|
│ - crcputh 55 bb
|
||||||
|
│ - crcputs sys0,2
|
||||||
|
│ - crcputs tSend.txt,0
|
||||||
|
│ - //send cmd
|
||||||
|
│ - printh 55 bb
|
||||||
|
│ - prints sys0,2
|
||||||
|
│ - prints tSend.txt,0
|
||||||
|
│ - prints crcval,2
|
||||||
|
│ -
|
||||||
|
│ Text f2Icon
|
||||||
|
│ Attributes
|
||||||
|
│ Scope : local
|
||||||
|
│ Dragging : 0
|
||||||
|
│ Send Component ID : disabled
|
||||||
|
│ Associated Keyboard: none
|
||||||
|
│ Text :
|
||||||
|
│ Max. Text Size : 4
|
||||||
|
│
|
||||||
|
│ - Events
|
||||||
|
│ - Touch Press Event
|
||||||
|
│ - tSend.txt="event,buttonPress2,"+entn2.txt+",button"
|
||||||
|
│ - if(entn2.txt=="")
|
||||||
|
│ - {
|
||||||
|
│ - tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.txt
|
||||||
|
│ - }
|
||||||
|
│ - //send calc crc
|
||||||
|
│ - btlen tSend.txt,sys0
|
||||||
|
│ - crcrest 1,0xffff // reset CRC
|
||||||
|
│ - crcputh 55 bb
|
||||||
|
│ - crcputs sys0,2
|
||||||
|
│ - crcputs tSend.txt,0
|
||||||
|
│ - //send cmd
|
||||||
|
│ - printh 55 bb
|
||||||
|
│ - prints sys0,2
|
||||||
|
│ - prints tSend.txt,0
|
||||||
|
│ - prints crcval,2
|
||||||
|
│ -
|
||||||
|
│ Text f3Icon
|
||||||
|
│ Attributes
|
||||||
|
│ Scope : local
|
||||||
|
│ Dragging : 0
|
||||||
|
│ Send Component ID : disabled
|
||||||
|
│ Associated Keyboard: none
|
||||||
|
│ Text :
|
||||||
|
│ Max. Text Size : 4
|
||||||
|
│
|
||||||
|
│ - Events
|
||||||
|
│ - Touch Press Event
|
||||||
|
│ - tSend.txt="event,buttonPress2,"+entn3.txt+",button"
|
||||||
|
│ - if(entn3.txt=="")
|
||||||
|
│ - {
|
||||||
|
│ - tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.txt
|
||||||
|
│ - }
|
||||||
|
│ - //send calc crc
|
||||||
|
│ - btlen tSend.txt,sys0
|
||||||
|
│ - crcrest 1,0xffff // reset CRC
|
||||||
|
│ - crcputh 55 bb
|
||||||
|
│ - crcputs sys0,2
|
||||||
|
│ - crcputs tSend.txt,0
|
||||||
|
│ - //send cmd
|
||||||
|
│ - printh 55 bb
|
||||||
|
│ - prints sys0,2
|
||||||
|
│ - prints tSend.txt,0
|
||||||
|
│ - prints crcval,2
|
||||||
|
│ -
|
||||||
|
│ Text f4Icon
|
||||||
|
│ Attributes
|
||||||
|
│ Scope : local
|
||||||
|
│ Dragging : 0
|
||||||
|
│ Send Component ID : disabled
|
||||||
|
│ Associated Keyboard: none
|
||||||
|
│ Text :
|
||||||
|
│ Max. Text Size : 4
|
||||||
|
│
|
||||||
|
│ - Events
|
||||||
|
│ - Touch Press Event
|
||||||
|
│ - tSend.txt="event,buttonPress2,"+entn4.txt+",button"
|
||||||
|
│ - if(entn4.txt=="")
|
||||||
|
│ - {
|
||||||
|
│ - tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.txt
|
||||||
|
│ - }
|
||||||
|
│ - //send calc crc
|
||||||
|
│ - btlen tSend.txt,sys0
|
||||||
|
│ - crcrest 1,0xffff // reset CRC
|
||||||
|
│ - crcputh 55 bb
|
||||||
|
│ - crcputs sys0,2
|
||||||
|
│ - crcputs tSend.txt,0
|
||||||
|
│ - //send cmd
|
||||||
|
│ - printh 55 bb
|
||||||
|
│ - prints sys0,2
|
||||||
|
│ - prints tSend.txt,0
|
||||||
|
│ - prints crcval,2
|
||||||
|
│ -
|
||||||
|
│ Text f5Icon
|
||||||
|
│ Attributes
|
||||||
|
│ Scope : local
|
||||||
|
│ Dragging : 0
|
||||||
|
│ Send Component ID : disabled
|
||||||
|
│ Associated Keyboard: none
|
||||||
|
│ Text :
|
||||||
|
│ Max. Text Size : 4
|
||||||
|
│
|
||||||
|
│ - Events
|
||||||
|
│ - Touch Press Event
|
||||||
|
│ - tSend.txt="event,buttonPress2,"+entn5.txt+",button"
|
||||||
|
│ - if(entn5.txt=="")
|
||||||
|
│ - {
|
||||||
|
│ - tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.txt
|
||||||
|
│ - }
|
||||||
|
│ - //send calc crc
|
||||||
|
│ - btlen tSend.txt,sys0
|
||||||
|
│ - crcrest 1,0xffff // reset CRC
|
||||||
|
│ - crcputh 55 bb
|
||||||
|
│ - crcputs sys0,2
|
||||||
|
│ - crcputs tSend.txt,0
|
||||||
|
│ - //send cmd
|
||||||
|
│ - printh 55 bb
|
||||||
|
│ - prints sys0,2
|
||||||
|
│ - prints tSend.txt,0
|
||||||
|
│ - prints crcval,2
|
||||||
|
│ -
|
||||||
│ -Text m0
|
│ -Text m0
|
||||||
│ - Attributes
|
│ - Attributes
|
||||||
│ - Scope : local
|
│ - Scope : local
|
||||||
@@ -274,7 +502,7 @@
|
|||||||
│ Send Component ID : disabled
|
│ Send Component ID : disabled
|
||||||
│ Associated Keyboard: none
|
│ Associated Keyboard: none
|
||||||
│ Text : PM
|
│ Text : PM
|
||||||
│ @@ -585,15 +561,14 @@
|
│ @@ -710,15 +561,14 @@
|
||||||
│ if(tTmp.txt!="")
|
│ if(tTmp.txt!="")
|
||||||
│ {
|
│ {
|
||||||
│ covx tTmp.txt,defaultFontColor,0,0
|
│ covx tTmp.txt,defaultFontColor,0,0
|
||||||
@@ -290,3 +518,48 @@
|
|||||||
│ if(tAMPM.txt=="")
|
│ if(tAMPM.txt=="")
|
||||||
│ {
|
│ {
|
||||||
│ vis tAMPM,0
|
│ vis tAMPM,0
|
||||||
|
│ @@ -839,44 +689,34 @@
|
||||||
|
│ //e6Val
|
||||||
|
│ spstr strCommand.txt,e6Val.txt,"~",60
|
||||||
|
│ //f1Icon
|
||||||
|
│ spstr strCommand.txt,f1Icon.txt,"~",63
|
||||||
|
│ //f1Icon Color
|
||||||
|
│ spstr strCommand.txt,tTmp.txt,"~",64
|
||||||
|
│ covx tTmp.txt,f1Icon.pco,0,0
|
||||||
|
│ - //f1Icon intNameEntity
|
||||||
|
│ - spstr strCommand.txt,entn1.txt,"~",62
|
||||||
|
│ //f2Icon
|
||||||
|
│ spstr strCommand.txt,f2Icon.txt,"~",69
|
||||||
|
│ //f2Icon Color
|
||||||
|
│ spstr strCommand.txt,tTmp.txt,"~",70
|
||||||
|
│ covx tTmp.txt,f2Icon.pco,0,0
|
||||||
|
│ - //f2Icon intNameEntity
|
||||||
|
│ - spstr strCommand.txt,entn2.txt,"~",68
|
||||||
|
│ //f3Icon
|
||||||
|
│ spstr strCommand.txt,f3Icon.txt,"~",75
|
||||||
|
│ //f3Icon Color
|
||||||
|
│ spstr strCommand.txt,tTmp.txt,"~",76
|
||||||
|
│ covx tTmp.txt,f3Icon.pco,0,0
|
||||||
|
│ - //f3Icon intNameEntity
|
||||||
|
│ - spstr strCommand.txt,entn3.txt,"~",74
|
||||||
|
│ //f4Icon
|
||||||
|
│ spstr strCommand.txt,f4Icon.txt,"~",81
|
||||||
|
│ //f4Icon Color
|
||||||
|
│ spstr strCommand.txt,tTmp.txt,"~",82
|
||||||
|
│ covx tTmp.txt,f4Icon.pco,0,0
|
||||||
|
│ - //f4Icon intNameEntity
|
||||||
|
│ - spstr strCommand.txt,entn4.txt,"~",80
|
||||||
|
│ //f5Icon
|
||||||
|
│ spstr strCommand.txt,f5Icon.txt,"~",87
|
||||||
|
│ //f5Icon Color
|
||||||
|
│ spstr strCommand.txt,tTmp.txt,"~",88
|
||||||
|
│ covx tTmp.txt,f5Icon.pco,0,0
|
||||||
|
│ - //f5Icon intNameEntity
|
||||||
|
│ - spstr strCommand.txt,entn5.txt,"~",86
|
||||||
|
│ }
|
||||||
|
│ if(tInstruction.txt=="notify")
|
||||||
|
│ {
|
||||||
|
│ spstr strCommand.txt,tNotifyHead.txt,"~",1
|
||||||
|
│ spstr strCommand.txt,tNotifyText.txt,"~",2
|
||||||
|
│ if(tNotifyHead.txt!=""||tNotifyText.txt!="")
|
||||||
|
│ {
|
||||||
|
|||||||
@@ -1,17 +1,5 @@
|
|||||||
--- HMI/n2t-out
|
--- HMI/n2t-out
|
||||||
+++ HMI/US/portrait/n2t-out
|
+++ HMI/US/portrait/n2t-out
|
||||||
├── file list
|
|
||||||
│ @@ -1,10 +1,9 @@
|
|
||||||
│ Program.s.txt
|
|
||||||
│ cardAlarm.txt
|
|
||||||
│ -cardBurnRec.txt
|
|
||||||
│ cardChart.txt
|
|
||||||
│ cardEntities.txt
|
|
||||||
│ cardGrid.txt
|
|
||||||
│ cardGrid2.txt
|
|
||||||
│ cardLChart.txt
|
|
||||||
│ cardMedia.txt
|
|
||||||
│ cardPower.txt
|
|
||||||
│ --- HMI/n2t-out/Program.s.txt
|
│ --- HMI/n2t-out/Program.s.txt
|
||||||
├── +++ HMI/US/portrait/n2t-out/Program.s.txt
|
├── +++ HMI/US/portrait/n2t-out/Program.s.txt
|
||||||
│ @@ -12,11 +12,11 @@
|
│ @@ -12,11 +12,11 @@
|
||||||
@@ -1997,6 +1985,26 @@
|
|||||||
│ Variable (string) entn
|
│ Variable (string) entn
|
||||||
│ Attributes
|
│ Attributes
|
||||||
│ Scope : local
|
│ Scope : local
|
||||||
|
│ @@ -453,19 +453,14 @@
|
||||||
|
│ ucopy strCommand.txt,4,payloadLength-5,0
|
||||||
|
│ // write instruction to tInstuction (debug output, but used as variable here, ui elements will be disabled by default)
|
||||||
|
│ spstr strCommand.txt,tInstruction.txt,"~",0
|
||||||
|
│ spstr strCommand.txt,tTmp.txt,"~",1
|
||||||
|
│ if(tInstruction.txt=="entityUpdateDetail"&&entn.txt==tTmp.txt)
|
||||||
|
│ {
|
||||||
|
│ // change icon
|
||||||
|
│ - spstr strCommand.txt,tTmp.txt,"~",2
|
||||||
|
│ - if(tTmp.txt!="")
|
||||||
|
│ - {
|
||||||
|
│ - tIcon1.txt=tTmp.txt
|
||||||
|
│ - }
|
||||||
|
│ //spstr strCommand.txt,tIcon1.txt,"~",2
|
||||||
|
│ vis tIcon1,1
|
||||||
|
│ // change icon color
|
||||||
|
│ spstr strCommand.txt,tTmp.txt,"~",3
|
||||||
|
│ covx tTmp.txt,sys0,0,0
|
||||||
|
│ tIcon1.pco=sys0
|
||||||
|
│ // get Button State
|
||||||
│ --- HMI/n2t-out/popupNotify.txt
|
│ --- HMI/n2t-out/popupNotify.txt
|
||||||
├── +++ HMI/US/portrait/n2t-out/popupNotify.txt
|
├── +++ HMI/US/portrait/n2t-out/popupNotify.txt
|
||||||
│ @@ -348,15 +348,15 @@
|
│ @@ -348,15 +348,15 @@
|
||||||
@@ -2016,6 +2024,25 @@
|
|||||||
│ }
|
│ }
|
||||||
│ if(tInstruction.txt=="exitPopup")
|
│ if(tInstruction.txt=="exitPopup")
|
||||||
│ {
|
│ {
|
||||||
|
│ @@ -439,18 +439,14 @@
|
||||||
|
│ {
|
||||||
|
│ page cardPower
|
||||||
|
│ }
|
||||||
|
│ if(tId.txt=="cardChart")
|
||||||
|
│ {
|
||||||
|
│ page cardChart
|
||||||
|
│ }
|
||||||
|
│ - if(tId.txt=="cardLChart")
|
||||||
|
│ - {
|
||||||
|
│ - page cardLChart
|
||||||
|
│ - }
|
||||||
|
│ }
|
||||||
|
│ // end of user code
|
||||||
|
│ udelete payloadLength-1
|
||||||
|
│ bufferPos=0
|
||||||
|
│ }
|
||||||
|
│ }
|
||||||
|
│ }
|
||||||
│ --- HMI/n2t-out/screensaver.txt
|
│ --- HMI/n2t-out/screensaver.txt
|
||||||
├── +++ HMI/US/portrait/n2t-out/screensaver.txt
|
├── +++ HMI/US/portrait/n2t-out/screensaver.txt
|
||||||
│ @@ -7,27 +7,14 @@
|
│ @@ -7,27 +7,14 @@
|
||||||
@@ -2168,7 +2195,7 @@
|
|||||||
│ vis p0,0
|
│ vis p0,0
|
||||||
│ vis tNotifyHead,0
|
│ vis tNotifyHead,0
|
||||||
│ vis tNotifyText,0
|
│ vis tNotifyText,0
|
||||||
│ @@ -41,17 +28,14 @@
|
│ @@ -41,52 +28,19 @@
|
||||||
│ }
|
│ }
|
||||||
│ tDate.txt=pageIcons.vaDate.txt
|
│ tDate.txt=pageIcons.vaDate.txt
|
||||||
│ dim=dimValue
|
│ dim=dimValue
|
||||||
@@ -2179,14 +2206,80 @@
|
|||||||
│ - Postinitialize Event
|
│ - Postinitialize Event
|
||||||
│ - click m0,1
|
│ - click m0,1
|
||||||
│ -
|
│ -
|
||||||
|
│ -Variable (string) entn1
|
||||||
|
│ - Attributes
|
||||||
|
│ - Scope : local
|
||||||
|
│ - Text :
|
||||||
|
│ - Max. Text Size: 14
|
||||||
|
│ -
|
||||||
|
│ -Variable (string) entn2
|
||||||
|
│ - Attributes
|
||||||
|
│ - Scope : local
|
||||||
|
│ - Text :
|
||||||
|
│ - Max. Text Size: 14
|
||||||
|
│ -
|
||||||
|
│ -Variable (string) entn3
|
||||||
|
│ - Attributes
|
||||||
|
│ - Scope : local
|
||||||
|
│ - Text :
|
||||||
|
│ - Max. Text Size: 14
|
||||||
|
│ -
|
||||||
|
│ -Variable (string) entn4
|
||||||
|
│ - Attributes
|
||||||
|
│ - Scope : local
|
||||||
|
│ - Text :
|
||||||
|
│ - Max. Text Size: 14
|
||||||
|
│ -
|
||||||
|
│ -Variable (string) entn5
|
||||||
|
│ - Attributes
|
||||||
|
│ - Scope : local
|
||||||
|
│ - Text :
|
||||||
|
│ - Max. Text Size: 14
|
||||||
|
│ -
|
||||||
│ Variable (string) strCommand
|
│ Variable (string) strCommand
|
||||||
│ Attributes
|
│ Attributes
|
||||||
│ Scope : local
|
│ Scope : local
|
||||||
│ Text :
|
│ Text :
|
||||||
│ Max. Text Size: 1979
|
│ - Max. Text Size: 1935
|
||||||
|
│ + Max. Text Size: 1979
|
||||||
│
|
│
|
||||||
│ Variable (string) strTmp
|
│ Variable (string) strTmp
|
||||||
│ @@ -376,34 +360,14 @@
|
│ Attributes
|
||||||
|
│ Scope : local
|
||||||
|
│ Text :
|
||||||
|
│ Max. Text Size: 2
|
||||||
|
│
|
||||||
|
│ @@ -96,27 +50,27 @@
|
||||||
|
│ Text :
|
||||||
|
│ Max. Text Size: 25
|
||||||
|
│
|
||||||
|
│ Variable (string) tInstruction
|
||||||
|
│ Attributes
|
||||||
|
│ Scope : local
|
||||||
|
│ Text :
|
||||||
|
│ - Max. Text Size: 15
|
||||||
|
│ + Max. Text Size: 50
|
||||||
|
│
|
||||||
|
│ Variable (string) tSend
|
||||||
|
│ Attributes
|
||||||
|
│ Scope : local
|
||||||
|
│ Text :
|
||||||
|
│ Max. Text Size: 50
|
||||||
|
│
|
||||||
|
│ Variable (string) tTmp
|
||||||
|
│ Attributes
|
||||||
|
│ Scope : local
|
||||||
|
│ Text :
|
||||||
|
│ - Max. Text Size: 30
|
||||||
|
│ + Max. Text Size: 50
|
||||||
|
│
|
||||||
|
│ Variable (int32) vaTap
|
||||||
|
│ Attributes
|
||||||
|
│ Scope: local
|
||||||
|
│ Value: 0
|
||||||
|
│
|
||||||
|
│ Variable (int32) xc1
|
||||||
|
│ @@ -370,165 +324,50 @@
|
||||||
│ Scope : local
|
│ Scope : local
|
||||||
│ Dragging : 0
|
│ Dragging : 0
|
||||||
│ Send Component ID : disabled
|
│ Send Component ID : disabled
|
||||||
@@ -2194,6 +2287,137 @@
|
|||||||
│ Text :
|
│ Text :
|
||||||
│ Max. Text Size : 4
|
│ Max. Text Size : 4
|
||||||
│
|
│
|
||||||
|
│ - Events
|
||||||
|
│ - Touch Press Event
|
||||||
|
│ - tSend.txt="event,buttonPress2,"+entn1.txt+",button"
|
||||||
|
│ - if(entn1.txt=="")
|
||||||
|
│ - {
|
||||||
|
│ - tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.txt
|
||||||
|
│ - }
|
||||||
|
│ - //send calc crc
|
||||||
|
│ - btlen tSend.txt,sys0
|
||||||
|
│ - crcrest 1,0xffff // reset CRC
|
||||||
|
│ - crcputh 55 bb
|
||||||
|
│ - crcputs sys0,2
|
||||||
|
│ - crcputs tSend.txt,0
|
||||||
|
│ - //send cmd
|
||||||
|
│ - printh 55 bb
|
||||||
|
│ - prints sys0,2
|
||||||
|
│ - prints tSend.txt,0
|
||||||
|
│ - prints crcval,2
|
||||||
|
│ -
|
||||||
|
│ Text f2Icon
|
||||||
|
│ Attributes
|
||||||
|
│ Scope : local
|
||||||
|
│ Dragging : 0
|
||||||
|
│ Send Component ID : disabled
|
||||||
|
│ Associated Keyboard: none
|
||||||
|
│ Text :
|
||||||
|
│ Max. Text Size : 4
|
||||||
|
│
|
||||||
|
│ - Events
|
||||||
|
│ - Touch Press Event
|
||||||
|
│ - tSend.txt="event,buttonPress2,"+entn2.txt+",button"
|
||||||
|
│ - if(entn2.txt=="")
|
||||||
|
│ - {
|
||||||
|
│ - tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.txt
|
||||||
|
│ - }
|
||||||
|
│ - //send calc crc
|
||||||
|
│ - btlen tSend.txt,sys0
|
||||||
|
│ - crcrest 1,0xffff // reset CRC
|
||||||
|
│ - crcputh 55 bb
|
||||||
|
│ - crcputs sys0,2
|
||||||
|
│ - crcputs tSend.txt,0
|
||||||
|
│ - //send cmd
|
||||||
|
│ - printh 55 bb
|
||||||
|
│ - prints sys0,2
|
||||||
|
│ - prints tSend.txt,0
|
||||||
|
│ - prints crcval,2
|
||||||
|
│ -
|
||||||
|
│ Text f3Icon
|
||||||
|
│ Attributes
|
||||||
|
│ Scope : local
|
||||||
|
│ Dragging : 0
|
||||||
|
│ Send Component ID : disabled
|
||||||
|
│ Associated Keyboard: none
|
||||||
|
│ Text :
|
||||||
|
│ Max. Text Size : 4
|
||||||
|
│
|
||||||
|
│ - Events
|
||||||
|
│ - Touch Press Event
|
||||||
|
│ - tSend.txt="event,buttonPress2,"+entn3.txt+",button"
|
||||||
|
│ - if(entn3.txt=="")
|
||||||
|
│ - {
|
||||||
|
│ - tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.txt
|
||||||
|
│ - }
|
||||||
|
│ - //send calc crc
|
||||||
|
│ - btlen tSend.txt,sys0
|
||||||
|
│ - crcrest 1,0xffff // reset CRC
|
||||||
|
│ - crcputh 55 bb
|
||||||
|
│ - crcputs sys0,2
|
||||||
|
│ - crcputs tSend.txt,0
|
||||||
|
│ - //send cmd
|
||||||
|
│ - printh 55 bb
|
||||||
|
│ - prints sys0,2
|
||||||
|
│ - prints tSend.txt,0
|
||||||
|
│ - prints crcval,2
|
||||||
|
│ -
|
||||||
|
│ Text f4Icon
|
||||||
|
│ Attributes
|
||||||
|
│ Scope : local
|
||||||
|
│ Dragging : 0
|
||||||
|
│ Send Component ID : disabled
|
||||||
|
│ Associated Keyboard: none
|
||||||
|
│ Text :
|
||||||
|
│ Max. Text Size : 4
|
||||||
|
│
|
||||||
|
│ - Events
|
||||||
|
│ - Touch Press Event
|
||||||
|
│ - tSend.txt="event,buttonPress2,"+entn4.txt+",button"
|
||||||
|
│ - if(entn4.txt=="")
|
||||||
|
│ - {
|
||||||
|
│ - tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.txt
|
||||||
|
│ - }
|
||||||
|
│ - //send calc crc
|
||||||
|
│ - btlen tSend.txt,sys0
|
||||||
|
│ - crcrest 1,0xffff // reset CRC
|
||||||
|
│ - crcputh 55 bb
|
||||||
|
│ - crcputs sys0,2
|
||||||
|
│ - crcputs tSend.txt,0
|
||||||
|
│ - //send cmd
|
||||||
|
│ - printh 55 bb
|
||||||
|
│ - prints sys0,2
|
||||||
|
│ - prints tSend.txt,0
|
||||||
|
│ - prints crcval,2
|
||||||
|
│ -
|
||||||
|
│ Text f5Icon
|
||||||
|
│ Attributes
|
||||||
|
│ Scope : local
|
||||||
|
│ Dragging : 0
|
||||||
|
│ Send Component ID : disabled
|
||||||
|
│ Associated Keyboard: none
|
||||||
|
│ Text :
|
||||||
|
│ Max. Text Size : 4
|
||||||
|
│
|
||||||
|
│ - Events
|
||||||
|
│ - Touch Press Event
|
||||||
|
│ - tSend.txt="event,buttonPress2,"+entn5.txt+",button"
|
||||||
|
│ - if(entn5.txt=="")
|
||||||
|
│ - {
|
||||||
|
│ - tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.txt
|
||||||
|
│ - }
|
||||||
|
│ - //send calc crc
|
||||||
|
│ - btlen tSend.txt,sys0
|
||||||
|
│ - crcrest 1,0xffff // reset CRC
|
||||||
|
│ - crcputh 55 bb
|
||||||
|
│ - crcputs sys0,2
|
||||||
|
│ - crcputs tSend.txt,0
|
||||||
|
│ - //send cmd
|
||||||
|
│ - printh 55 bb
|
||||||
|
│ - prints sys0,2
|
||||||
|
│ - prints tSend.txt,0
|
||||||
|
│ - prints crcval,2
|
||||||
|
│ -
|
||||||
│ -Text m0
|
│ -Text m0
|
||||||
│ - Attributes
|
│ - Attributes
|
||||||
│ - Scope : local
|
│ - Scope : local
|
||||||
@@ -2221,7 +2445,7 @@
|
|||||||
│ Send Component ID : disabled
|
│ Send Component ID : disabled
|
||||||
│ Associated Keyboard: none
|
│ Associated Keyboard: none
|
||||||
│ Text : PM
|
│ Text : PM
|
||||||
│ @@ -585,15 +549,14 @@
|
│ @@ -710,15 +549,14 @@
|
||||||
│ if(tTmp.txt!="")
|
│ if(tTmp.txt!="")
|
||||||
│ {
|
│ {
|
||||||
│ covx tTmp.txt,defaultFontColor,0,0
|
│ covx tTmp.txt,defaultFontColor,0,0
|
||||||
@@ -2237,3 +2461,48 @@
|
|||||||
│ if(tAMPM.txt=="")
|
│ if(tAMPM.txt=="")
|
||||||
│ {
|
│ {
|
||||||
│ vis tAMPM,0
|
│ vis tAMPM,0
|
||||||
|
│ @@ -839,44 +677,34 @@
|
||||||
|
│ //e6Val
|
||||||
|
│ spstr strCommand.txt,e6Val.txt,"~",60
|
||||||
|
│ //f1Icon
|
||||||
|
│ spstr strCommand.txt,f1Icon.txt,"~",63
|
||||||
|
│ //f1Icon Color
|
||||||
|
│ spstr strCommand.txt,tTmp.txt,"~",64
|
||||||
|
│ covx tTmp.txt,f1Icon.pco,0,0
|
||||||
|
│ - //f1Icon intNameEntity
|
||||||
|
│ - spstr strCommand.txt,entn1.txt,"~",62
|
||||||
|
│ //f2Icon
|
||||||
|
│ spstr strCommand.txt,f2Icon.txt,"~",69
|
||||||
|
│ //f2Icon Color
|
||||||
|
│ spstr strCommand.txt,tTmp.txt,"~",70
|
||||||
|
│ covx tTmp.txt,f2Icon.pco,0,0
|
||||||
|
│ - //f2Icon intNameEntity
|
||||||
|
│ - spstr strCommand.txt,entn2.txt,"~",68
|
||||||
|
│ //f3Icon
|
||||||
|
│ spstr strCommand.txt,f3Icon.txt,"~",75
|
||||||
|
│ //f3Icon Color
|
||||||
|
│ spstr strCommand.txt,tTmp.txt,"~",76
|
||||||
|
│ covx tTmp.txt,f3Icon.pco,0,0
|
||||||
|
│ - //f3Icon intNameEntity
|
||||||
|
│ - spstr strCommand.txt,entn3.txt,"~",74
|
||||||
|
│ //f4Icon
|
||||||
|
│ spstr strCommand.txt,f4Icon.txt,"~",81
|
||||||
|
│ //f4Icon Color
|
||||||
|
│ spstr strCommand.txt,tTmp.txt,"~",82
|
||||||
|
│ covx tTmp.txt,f4Icon.pco,0,0
|
||||||
|
│ - //f4Icon intNameEntity
|
||||||
|
│ - spstr strCommand.txt,entn4.txt,"~",80
|
||||||
|
│ //f5Icon
|
||||||
|
│ spstr strCommand.txt,f5Icon.txt,"~",87
|
||||||
|
│ //f5Icon Color
|
||||||
|
│ spstr strCommand.txt,tTmp.txt,"~",88
|
||||||
|
│ covx tTmp.txt,f5Icon.pco,0,0
|
||||||
|
│ - //f5Icon intNameEntity
|
||||||
|
│ - spstr strCommand.txt,entn5.txt,"~",86
|
||||||
|
│ }
|
||||||
|
│ if(tInstruction.txt=="notify")
|
||||||
|
│ {
|
||||||
|
│ spstr strCommand.txt,tNotifyHead.txt,"~",1
|
||||||
|
│ spstr strCommand.txt,tNotifyText.txt,"~",2
|
||||||
|
│ if(tNotifyHead.txt!=""||tNotifyText.txt!="")
|
||||||
|
│ {
|
||||||
|
|||||||
@@ -1,16 +1,4 @@
|
|||||||
+++ /dev/fd/62 2023-11-27 23:28:52.512823638 +0000
|
+++ /dev/fd/62 2025-12-26 19:43:25.803166597 +0000
|
||||||
+le list
|
|
||||||
+ +1,9 @@
|
|
||||||
+.s.txt
|
|
||||||
+rm.txt
|
|
||||||
+nRec.txt
|
|
||||||
+rt.txt
|
|
||||||
+ities.txt
|
|
||||||
+d.txt
|
|
||||||
+d2.txt
|
|
||||||
+art.txt
|
|
||||||
+ia.txt
|
|
||||||
+er.txt
|
|
||||||
+I/n2t-out/Program.s.txt
|
+I/n2t-out/Program.s.txt
|
||||||
++ HMI/US/portrait/n2t-out/Program.s.txt
|
++ HMI/US/portrait/n2t-out/Program.s.txt
|
||||||
+1 +12,11 @@
|
+1 +12,11 @@
|
||||||
@@ -1539,6 +1527,26 @@
|
|||||||
+e (string) entn
|
+e (string) entn
|
||||||
+ributes
|
+ributes
|
||||||
+ Scope : local
|
+ Scope : local
|
||||||
|
+19 +453,14 @@
|
||||||
|
+ ucopy strCommand.txt,4,payloadLength-5,0
|
||||||
|
+ // write instruction to tInstuction (debug output, but used as variable here, ui elements will be disabled by default)
|
||||||
|
+ spstr strCommand.txt,tInstruction.txt,"~",0
|
||||||
|
+ spstr strCommand.txt,tTmp.txt,"~",1
|
||||||
|
+ if(tInstruction.txt=="entityUpdateDetail"&&entn.txt==tTmp.txt)
|
||||||
|
+ {
|
||||||
|
+ // change icon
|
||||||
|
+ spstr strCommand.txt,tTmp.txt,"~",2
|
||||||
|
+ if(tTmp.txt!="")
|
||||||
|
+ {
|
||||||
|
+ tIcon1.txt=tTmp.txt
|
||||||
|
+ }
|
||||||
|
+ //spstr strCommand.txt,tIcon1.txt,"~",2
|
||||||
|
+ vis tIcon1,1
|
||||||
|
+ // change icon color
|
||||||
|
+ spstr strCommand.txt,tTmp.txt,"~",3
|
||||||
|
+ covx tTmp.txt,sys0,0,0
|
||||||
|
+ tIcon1.pco=sys0
|
||||||
|
+ // get Button State
|
||||||
+I/n2t-out/popupNotify.txt
|
+I/n2t-out/popupNotify.txt
|
||||||
++ HMI/US/portrait/n2t-out/popupNotify.txt
|
++ HMI/US/portrait/n2t-out/popupNotify.txt
|
||||||
+15 +348,15 @@
|
+15 +348,15 @@
|
||||||
@@ -1558,6 +1566,25 @@
|
|||||||
+ }
|
+ }
|
||||||
+ if(tInstruction.txt=="exitPopup")
|
+ if(tInstruction.txt=="exitPopup")
|
||||||
+ {
|
+ {
|
||||||
|
+18 +439,14 @@
|
||||||
|
+ {
|
||||||
|
+ page cardPower
|
||||||
|
+ }
|
||||||
|
+ if(tId.txt=="cardChart")
|
||||||
|
+ {
|
||||||
|
+ page cardChart
|
||||||
|
+ }
|
||||||
|
+ if(tId.txt=="cardLChart")
|
||||||
|
+ {
|
||||||
|
+ page cardLChart
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ // end of user code
|
||||||
|
+ udelete payloadLength-1
|
||||||
|
+ bufferPos=0
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
+I/n2t-out/screensaver.txt
|
+I/n2t-out/screensaver.txt
|
||||||
++ HMI/US/portrait/n2t-out/screensaver.txt
|
++ HMI/US/portrait/n2t-out/screensaver.txt
|
||||||
+ +7,14 @@
|
+ +7,14 @@
|
||||||
@@ -1710,7 +1737,7 @@
|
|||||||
+ vis p0,0
|
+ vis p0,0
|
||||||
+ vis tNotifyHead,0
|
+ vis tNotifyHead,0
|
||||||
+ vis tNotifyText,0
|
+ vis tNotifyText,0
|
||||||
+7 +28,14 @@
|
+2 +28,19 @@
|
||||||
+ }
|
+ }
|
||||||
+ tDate.txt=pageIcons.vaDate.txt
|
+ tDate.txt=pageIcons.vaDate.txt
|
||||||
+ dim=dimValue
|
+ dim=dimValue
|
||||||
@@ -1721,14 +1748,80 @@
|
|||||||
+ Postinitialize Event
|
+ Postinitialize Event
|
||||||
+ click m0,1
|
+ click m0,1
|
||||||
+
|
+
|
||||||
|
+e (string) entn1
|
||||||
|
+ributes
|
||||||
|
+ Scope : local
|
||||||
|
+ Text :
|
||||||
|
+ Max. Text Size: 14
|
||||||
|
+
|
||||||
|
+e (string) entn2
|
||||||
|
+ributes
|
||||||
|
+ Scope : local
|
||||||
|
+ Text :
|
||||||
|
+ Max. Text Size: 14
|
||||||
|
+
|
||||||
|
+e (string) entn3
|
||||||
|
+ributes
|
||||||
|
+ Scope : local
|
||||||
|
+ Text :
|
||||||
|
+ Max. Text Size: 14
|
||||||
|
+
|
||||||
|
+e (string) entn4
|
||||||
|
+ributes
|
||||||
|
+ Scope : local
|
||||||
|
+ Text :
|
||||||
|
+ Max. Text Size: 14
|
||||||
|
+
|
||||||
|
+e (string) entn5
|
||||||
|
+ributes
|
||||||
|
+ Scope : local
|
||||||
|
+ Text :
|
||||||
|
+ Max. Text Size: 14
|
||||||
|
+
|
||||||
+e (string) strCommand
|
+e (string) strCommand
|
||||||
+ributes
|
+ributes
|
||||||
+ Scope : local
|
+ Scope : local
|
||||||
+ Text :
|
+ Text :
|
||||||
|
+ Max. Text Size: 1935
|
||||||
+ Max. Text Size: 1979
|
+ Max. Text Size: 1979
|
||||||
+
|
+
|
||||||
+e (string) strTmp
|
+e (string) strTmp
|
||||||
+34 +360,14 @@
|
+ributes
|
||||||
|
+ Scope : local
|
||||||
|
+ Text :
|
||||||
|
+ Max. Text Size: 2
|
||||||
|
+
|
||||||
|
+7 +50,27 @@
|
||||||
|
+ Text :
|
||||||
|
+ Max. Text Size: 25
|
||||||
|
+
|
||||||
|
+e (string) tInstruction
|
||||||
|
+ributes
|
||||||
|
+ Scope : local
|
||||||
|
+ Text :
|
||||||
|
+ Max. Text Size: 15
|
||||||
|
+ Max. Text Size: 50
|
||||||
|
+
|
||||||
|
+e (string) tSend
|
||||||
|
+ributes
|
||||||
|
+ Scope : local
|
||||||
|
+ Text :
|
||||||
|
+ Max. Text Size: 50
|
||||||
|
+
|
||||||
|
+e (string) tTmp
|
||||||
|
+ributes
|
||||||
|
+ Scope : local
|
||||||
|
+ Text :
|
||||||
|
+ Max. Text Size: 30
|
||||||
|
+ Max. Text Size: 50
|
||||||
|
+
|
||||||
|
+e (int32) vaTap
|
||||||
|
+ributes
|
||||||
|
+ Scope: local
|
||||||
|
+ Value: 0
|
||||||
|
+
|
||||||
|
+e (int32) xc1
|
||||||
|
+165 +324,50 @@
|
||||||
+ Scope : local
|
+ Scope : local
|
||||||
+ Dragging : 0
|
+ Dragging : 0
|
||||||
+ Send Component ID : disabled
|
+ Send Component ID : disabled
|
||||||
@@ -1736,6 +1829,137 @@
|
|||||||
+ Text :
|
+ Text :
|
||||||
+ Max. Text Size : 4
|
+ Max. Text Size : 4
|
||||||
+
|
+
|
||||||
|
+nts
|
||||||
|
+ Touch Press Event
|
||||||
|
+ tSend.txt="event,buttonPress2,"+entn1.txt+",button"
|
||||||
|
+ if(entn1.txt=="")
|
||||||
|
+ {
|
||||||
|
+ tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.txt
|
||||||
|
+ }
|
||||||
|
+ //send calc crc
|
||||||
|
+ btlen tSend.txt,sys0
|
||||||
|
+ crcrest 1,0xffff // reset CRC
|
||||||
|
+ crcputh 55 bb
|
||||||
|
+ crcputs sys0,2
|
||||||
|
+ crcputs tSend.txt,0
|
||||||
|
+ //send cmd
|
||||||
|
+ printh 55 bb
|
||||||
|
+ prints sys0,2
|
||||||
|
+ prints tSend.txt,0
|
||||||
|
+ prints crcval,2
|
||||||
|
+
|
||||||
|
+Icon
|
||||||
|
+ributes
|
||||||
|
+ Scope : local
|
||||||
|
+ Dragging : 0
|
||||||
|
+ Send Component ID : disabled
|
||||||
|
+ Associated Keyboard: none
|
||||||
|
+ Text :
|
||||||
|
+ Max. Text Size : 4
|
||||||
|
+
|
||||||
|
+nts
|
||||||
|
+ Touch Press Event
|
||||||
|
+ tSend.txt="event,buttonPress2,"+entn2.txt+",button"
|
||||||
|
+ if(entn2.txt=="")
|
||||||
|
+ {
|
||||||
|
+ tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.txt
|
||||||
|
+ }
|
||||||
|
+ //send calc crc
|
||||||
|
+ btlen tSend.txt,sys0
|
||||||
|
+ crcrest 1,0xffff // reset CRC
|
||||||
|
+ crcputh 55 bb
|
||||||
|
+ crcputs sys0,2
|
||||||
|
+ crcputs tSend.txt,0
|
||||||
|
+ //send cmd
|
||||||
|
+ printh 55 bb
|
||||||
|
+ prints sys0,2
|
||||||
|
+ prints tSend.txt,0
|
||||||
|
+ prints crcval,2
|
||||||
|
+
|
||||||
|
+Icon
|
||||||
|
+ributes
|
||||||
|
+ Scope : local
|
||||||
|
+ Dragging : 0
|
||||||
|
+ Send Component ID : disabled
|
||||||
|
+ Associated Keyboard: none
|
||||||
|
+ Text :
|
||||||
|
+ Max. Text Size : 4
|
||||||
|
+
|
||||||
|
+nts
|
||||||
|
+ Touch Press Event
|
||||||
|
+ tSend.txt="event,buttonPress2,"+entn3.txt+",button"
|
||||||
|
+ if(entn3.txt=="")
|
||||||
|
+ {
|
||||||
|
+ tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.txt
|
||||||
|
+ }
|
||||||
|
+ //send calc crc
|
||||||
|
+ btlen tSend.txt,sys0
|
||||||
|
+ crcrest 1,0xffff // reset CRC
|
||||||
|
+ crcputh 55 bb
|
||||||
|
+ crcputs sys0,2
|
||||||
|
+ crcputs tSend.txt,0
|
||||||
|
+ //send cmd
|
||||||
|
+ printh 55 bb
|
||||||
|
+ prints sys0,2
|
||||||
|
+ prints tSend.txt,0
|
||||||
|
+ prints crcval,2
|
||||||
|
+
|
||||||
|
+Icon
|
||||||
|
+ributes
|
||||||
|
+ Scope : local
|
||||||
|
+ Dragging : 0
|
||||||
|
+ Send Component ID : disabled
|
||||||
|
+ Associated Keyboard: none
|
||||||
|
+ Text :
|
||||||
|
+ Max. Text Size : 4
|
||||||
|
+
|
||||||
|
+nts
|
||||||
|
+ Touch Press Event
|
||||||
|
+ tSend.txt="event,buttonPress2,"+entn4.txt+",button"
|
||||||
|
+ if(entn4.txt=="")
|
||||||
|
+ {
|
||||||
|
+ tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.txt
|
||||||
|
+ }
|
||||||
|
+ //send calc crc
|
||||||
|
+ btlen tSend.txt,sys0
|
||||||
|
+ crcrest 1,0xffff // reset CRC
|
||||||
|
+ crcputh 55 bb
|
||||||
|
+ crcputs sys0,2
|
||||||
|
+ crcputs tSend.txt,0
|
||||||
|
+ //send cmd
|
||||||
|
+ printh 55 bb
|
||||||
|
+ prints sys0,2
|
||||||
|
+ prints tSend.txt,0
|
||||||
|
+ prints crcval,2
|
||||||
|
+
|
||||||
|
+Icon
|
||||||
|
+ributes
|
||||||
|
+ Scope : local
|
||||||
|
+ Dragging : 0
|
||||||
|
+ Send Component ID : disabled
|
||||||
|
+ Associated Keyboard: none
|
||||||
|
+ Text :
|
||||||
|
+ Max. Text Size : 4
|
||||||
|
+
|
||||||
|
+nts
|
||||||
|
+ Touch Press Event
|
||||||
|
+ tSend.txt="event,buttonPress2,"+entn5.txt+",button"
|
||||||
|
+ if(entn5.txt=="")
|
||||||
|
+ {
|
||||||
|
+ tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.txt
|
||||||
|
+ }
|
||||||
|
+ //send calc crc
|
||||||
|
+ btlen tSend.txt,sys0
|
||||||
|
+ crcrest 1,0xffff // reset CRC
|
||||||
|
+ crcputh 55 bb
|
||||||
|
+ crcputs sys0,2
|
||||||
|
+ crcputs tSend.txt,0
|
||||||
|
+ //send cmd
|
||||||
|
+ printh 55 bb
|
||||||
|
+ prints sys0,2
|
||||||
|
+ prints tSend.txt,0
|
||||||
|
+ prints crcval,2
|
||||||
|
+
|
||||||
+
|
+
|
||||||
+ributes
|
+ributes
|
||||||
+ Scope : local
|
+ Scope : local
|
||||||
@@ -1779,3 +2003,48 @@
|
|||||||
+ if(tAMPM.txt=="")
|
+ if(tAMPM.txt=="")
|
||||||
+ {
|
+ {
|
||||||
+ vis tAMPM,0
|
+ vis tAMPM,0
|
||||||
|
+44 +677,34 @@
|
||||||
|
+ //e6Val
|
||||||
|
+ spstr strCommand.txt,e6Val.txt,"~",60
|
||||||
|
+ //f1Icon
|
||||||
|
+ spstr strCommand.txt,f1Icon.txt,"~",63
|
||||||
|
+ //f1Icon Color
|
||||||
|
+ spstr strCommand.txt,tTmp.txt,"~",64
|
||||||
|
+ covx tTmp.txt,f1Icon.pco,0,0
|
||||||
|
+ //f1Icon intNameEntity
|
||||||
|
+ spstr strCommand.txt,entn1.txt,"~",62
|
||||||
|
+ //f2Icon
|
||||||
|
+ spstr strCommand.txt,f2Icon.txt,"~",69
|
||||||
|
+ //f2Icon Color
|
||||||
|
+ spstr strCommand.txt,tTmp.txt,"~",70
|
||||||
|
+ covx tTmp.txt,f2Icon.pco,0,0
|
||||||
|
+ //f2Icon intNameEntity
|
||||||
|
+ spstr strCommand.txt,entn2.txt,"~",68
|
||||||
|
+ //f3Icon
|
||||||
|
+ spstr strCommand.txt,f3Icon.txt,"~",75
|
||||||
|
+ //f3Icon Color
|
||||||
|
+ spstr strCommand.txt,tTmp.txt,"~",76
|
||||||
|
+ covx tTmp.txt,f3Icon.pco,0,0
|
||||||
|
+ //f3Icon intNameEntity
|
||||||
|
+ spstr strCommand.txt,entn3.txt,"~",74
|
||||||
|
+ //f4Icon
|
||||||
|
+ spstr strCommand.txt,f4Icon.txt,"~",81
|
||||||
|
+ //f4Icon Color
|
||||||
|
+ spstr strCommand.txt,tTmp.txt,"~",82
|
||||||
|
+ covx tTmp.txt,f4Icon.pco,0,0
|
||||||
|
+ //f4Icon intNameEntity
|
||||||
|
+ spstr strCommand.txt,entn4.txt,"~",80
|
||||||
|
+ //f5Icon
|
||||||
|
+ spstr strCommand.txt,f5Icon.txt,"~",87
|
||||||
|
+ //f5Icon Color
|
||||||
|
+ spstr strCommand.txt,tTmp.txt,"~",88
|
||||||
|
+ covx tTmp.txt,f5Icon.pco,0,0
|
||||||
|
+ //f5Icon intNameEntity
|
||||||
|
+ spstr strCommand.txt,entn5.txt,"~",86
|
||||||
|
+ }
|
||||||
|
+ if(tInstruction.txt=="notify")
|
||||||
|
+ {
|
||||||
|
+ spstr strCommand.txt,tNotifyHead.txt,"~",1
|
||||||
|
+ spstr strCommand.txt,tNotifyText.txt,"~",2
|
||||||
|
+ if(tNotifyHead.txt!=""||tNotifyText.txt!="")
|
||||||
|
+ {
|
||||||
|
|||||||
@@ -1,272 +1,274 @@
|
|||||||
from shared import *
|
from shared import *
|
||||||
head = sharedhead + """
|
head = sharedhead + """
|
||||||
if(tInstruction.txt=="wake")
|
if(tInstruction.txt=="wake")
|
||||||
{
|
{
|
||||||
click tc0,1
|
click tc0,1
|
||||||
}
|
}
|
||||||
if(tInstruction.txt=="dimmode")
|
if(tInstruction.txt=="dimmode")
|
||||||
{
|
{
|
||||||
// get value
|
// get value
|
||||||
spstr strCommand.txt,tTmp.txt,"~",1
|
spstr strCommand.txt,tTmp.txt,"~",1
|
||||||
covx tTmp.txt,dimValue,0,0
|
covx tTmp.txt,dimValue,0,0
|
||||||
dim=dimValue
|
dim=dimValue
|
||||||
// get value normal
|
// get value normal
|
||||||
spstr strCommand.txt,tTmp.txt,"~",2
|
spstr strCommand.txt,tTmp.txt,"~",2
|
||||||
covx tTmp.txt,dimValueNormal,0,0
|
covx tTmp.txt,dimValueNormal,0,0
|
||||||
// get background color
|
// get background color
|
||||||
spstr strCommand.txt,tTmp.txt,"~",3
|
spstr strCommand.txt,tTmp.txt,"~",3
|
||||||
if(tTmp.txt!="")
|
if(tTmp.txt!="")
|
||||||
{
|
{
|
||||||
covx tTmp.txt,defaultBcoColor,0,0
|
covx tTmp.txt,defaultBcoColor,0,0
|
||||||
}
|
}
|
||||||
// get font color
|
// get font color
|
||||||
spstr strCommand.txt,tTmp.txt,"~",4
|
spstr strCommand.txt,tTmp.txt,"~",4
|
||||||
if(tTmp.txt!="")
|
if(tTmp.txt!="")
|
||||||
{
|
{
|
||||||
covx tTmp.txt,defaultFontColor,0,0
|
covx tTmp.txt,defaultFontColor,0,0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(tInstruction.txt=="time")
|
if(tInstruction.txt=="time")
|
||||||
{
|
{
|
||||||
click m0,1
|
click m0,1
|
||||||
//get set time to global variable
|
//get set time to global variable
|
||||||
spstr strCommand.txt,pageIcons.vaTime.txt,"~",1
|
spstr strCommand.txt,pageIcons.vaTime.txt,"~",1
|
||||||
spstr pageIcons.vaTime.txt,tTime.txt,"?",0
|
spstr pageIcons.vaTime.txt,tTime.txt,"?",0
|
||||||
spstr pageIcons.vaTime.txt,tAMPM.txt,"?",1
|
spstr pageIcons.vaTime.txt,tAMPM.txt,"?",1
|
||||||
if(tAMPM.txt=="")
|
if(tAMPM.txt=="")
|
||||||
{
|
{
|
||||||
vis tAMPM,0
|
vis tAMPM,0
|
||||||
}
|
}
|
||||||
spstr strCommand.txt,tTimeAdd.txt,"~",2
|
spstr strCommand.txt,tTimeAdd.txt,"~",2
|
||||||
ref tIcon1
|
ref tIcon1
|
||||||
ref tIcon2
|
ref tIcon2
|
||||||
}
|
}
|
||||||
if(tInstruction.txt=="date")
|
if(tInstruction.txt=="date")
|
||||||
{
|
{
|
||||||
//get set date to global variable
|
//get set date to global variable
|
||||||
spstr strCommand.txt,pageIcons.vaDate.txt,"~",1
|
spstr strCommand.txt,pageIcons.vaDate.txt,"~",1
|
||||||
tDate.txt=pageIcons.vaDate.txt
|
tDate.txt=pageIcons.vaDate.txt
|
||||||
}
|
}
|
||||||
if(tInstruction.txt=="statusUpdate")
|
if(tInstruction.txt=="statusUpdate")
|
||||||
{
|
{
|
||||||
//statusIcon1
|
//statusIcon1
|
||||||
spstr strCommand.txt,tIcon1.txt,"~",1
|
spstr strCommand.txt,tIcon1.txt,"~",1
|
||||||
spstr strCommand.txt,tTmp.txt,"~",2
|
spstr strCommand.txt,tTmp.txt,"~",2
|
||||||
covx tTmp.txt,tIcon1.pco,0,0
|
covx tTmp.txt,tIcon1.pco,0,0
|
||||||
//statusIcon2
|
//statusIcon2
|
||||||
spstr strCommand.txt,tIcon2.txt,"~",3
|
spstr strCommand.txt,tIcon2.txt,"~",3
|
||||||
spstr strCommand.txt,tTmp.txt,"~",4
|
spstr strCommand.txt,tTmp.txt,"~",4
|
||||||
covx tTmp.txt,tIcon2.pco,0,0
|
covx tTmp.txt,tIcon2.pco,0,0
|
||||||
spstr strCommand.txt,tTmp.txt,"~",5
|
spstr strCommand.txt,tTmp.txt,"~",5
|
||||||
if(tTmp.txt!="")
|
if(tTmp.txt!="")
|
||||||
{
|
{
|
||||||
tIcon1.font=3
|
tIcon1.font=3
|
||||||
}
|
}
|
||||||
spstr strCommand.txt,tTmp.txt,"~",6
|
spstr strCommand.txt,tTmp.txt,"~",6
|
||||||
if(tTmp.txt!="")
|
if(tTmp.txt!="")
|
||||||
{
|
{
|
||||||
tIcon2.font=3
|
tIcon2.font=3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(tInstruction.txt=="weatherUpdate"&&tNotifyHead.txt==""&&tNotifyText.txt=="")
|
if(tInstruction.txt=="weatherUpdate"&&tNotifyHead.txt==""&&tNotifyText.txt=="")
|
||||||
{
|
{
|
||||||
|
|
||||||
//tMainIcon
|
//tMainIcon
|
||||||
spstr strCommand.txt,tMainIcon.txt,"~",3
|
spstr strCommand.txt,tMainIcon.txt,"~",3
|
||||||
//tMainIcon Color
|
//tMainIcon Color
|
||||||
spstr strCommand.txt,tTmp.txt,"~",4
|
spstr strCommand.txt,tTmp.txt,"~",4
|
||||||
covx tTmp.txt,tMainIcon.pco,0,0
|
covx tTmp.txt,tMainIcon.pco,0,0
|
||||||
//tMainText
|
//tMainText
|
||||||
spstr strCommand.txt,tMainText.txt,"~",6
|
spstr strCommand.txt,tMainText.txt,"~",6
|
||||||
"""
|
"""
|
||||||
|
|
||||||
start = 7
|
start = 7
|
||||||
for i in range(1,4):
|
for i in range(1,4):
|
||||||
idxstart = start + (i-1)*6
|
idxstart = start + (i-1)*6
|
||||||
item = f"""
|
item = f"""
|
||||||
//d{i}Icon
|
//d{i}Icon
|
||||||
spstr strCommand.txt,d{i}Icon.txt,"~",{idxstart+2}
|
spstr strCommand.txt,d{i}Icon.txt,"~",{idxstart+2}
|
||||||
//d{i}Icon Color
|
//d{i}Icon Color
|
||||||
spstr strCommand.txt,tTmp.txt,"~",{idxstart+3}
|
spstr strCommand.txt,tTmp.txt,"~",{idxstart+3}
|
||||||
covx tTmp.txt,d{i}Icon.pco,0,0
|
covx tTmp.txt,d{i}Icon.pco,0,0
|
||||||
//d{i}Val
|
//d{i}Val
|
||||||
spstr strCommand.txt,d{i}Val.txt,"~",{idxstart+5}
|
spstr strCommand.txt,d{i}Val.txt,"~",{idxstart+5}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
head = head + item
|
head = head + item
|
||||||
|
|
||||||
start = idxstart+6
|
start = idxstart+6
|
||||||
for i in range(1,7):
|
for i in range(1,7):
|
||||||
idxstart = start + (i-1)*6
|
idxstart = start + (i-1)*6
|
||||||
item = f"""
|
item = f"""
|
||||||
//e{i}Name
|
//e{i}Name
|
||||||
spstr strCommand.txt,e{i}Name.txt,"~",{idxstart+4}
|
spstr strCommand.txt,e{i}Name.txt,"~",{idxstart+4}
|
||||||
//e{i}Icon
|
//e{i}Icon
|
||||||
spstr strCommand.txt,e{i}Icon.txt,"~",{idxstart+2}
|
spstr strCommand.txt,e{i}Icon.txt,"~",{idxstart+2}
|
||||||
//e{i}Icon Color
|
//e{i}Icon Color
|
||||||
spstr strCommand.txt,tTmp.txt,"~",{idxstart+3}
|
spstr strCommand.txt,tTmp.txt,"~",{idxstart+3}
|
||||||
covx tTmp.txt,e{i}Icon.pco,0,0
|
covx tTmp.txt,e{i}Icon.pco,0,0
|
||||||
//e{i}Val
|
//e{i}Val
|
||||||
spstr strCommand.txt,e{i}Val.txt,"~",{idxstart+5}
|
spstr strCommand.txt,e{i}Val.txt,"~",{idxstart+5}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
head = head + item
|
head = head + item
|
||||||
|
|
||||||
start = idxstart+6
|
start = idxstart+6
|
||||||
for i in range(1,6):
|
for i in range(1,6):
|
||||||
idxstart = start + (i-1)*6
|
idxstart = start + (i-1)*6
|
||||||
item = f"""
|
item = f"""
|
||||||
//f{i}Icon
|
//f{i}Icon
|
||||||
spstr strCommand.txt,f{i}Icon.txt,"~",{idxstart+2}
|
spstr strCommand.txt,f{i}Icon.txt,"~",{idxstart+2}
|
||||||
//f{i}Icon Color
|
//f{i}Icon Color
|
||||||
spstr strCommand.txt,tTmp.txt,"~",{idxstart+3}
|
spstr strCommand.txt,tTmp.txt,"~",{idxstart+3}
|
||||||
covx tTmp.txt,f{i}Icon.pco,0,0
|
covx tTmp.txt,f{i}Icon.pco,0,0
|
||||||
"""
|
//f{i}Icon intNameEntity
|
||||||
head = head + item
|
spstr strCommand.txt,entn{i}.txt,"~",{idxstart+1}
|
||||||
|
"""
|
||||||
head = head + """
|
head = head + item
|
||||||
}
|
|
||||||
|
head = head + """
|
||||||
if(tInstruction.txt=="color"&&tNotifyHead.txt==""&&tNotifyText.txt=="")
|
}
|
||||||
{
|
|
||||||
spstr strCommand.txt,tTmp.txt,"~",1
|
if(tInstruction.txt=="color"&&tNotifyHead.txt==""&&tNotifyText.txt=="")
|
||||||
covx tTmp.txt,tTime.bco,0,0
|
{
|
||||||
if(tTime.bco!=screensaver.bco)
|
spstr strCommand.txt,tTmp.txt,"~",1
|
||||||
{
|
covx tTmp.txt,tTime.bco,0,0
|
||||||
for(sys0=0;sys0<60;sys0++)
|
if(tTime.bco!=screensaver.bco)
|
||||||
{
|
{
|
||||||
if(b[sys0].type==98||b[sys0].type==116||b[sys0].type==54)
|
for(sys0=0;sys0<60;sys0++)
|
||||||
{
|
{
|
||||||
b[sys0].bco=tTime.bco
|
if(b[sys0].type==98||b[sys0].type==116||b[sys0].type==54)
|
||||||
}
|
{
|
||||||
}
|
b[sys0].bco=tTime.bco
|
||||||
}
|
}
|
||||||
spstr strCommand.txt,tTmp.txt,"~",2
|
}
|
||||||
covx tTmp.txt,tTime.pco,0,0
|
}
|
||||||
spstr strCommand.txt,tTmp.txt,"~",3
|
spstr strCommand.txt,tTmp.txt,"~",2
|
||||||
covx tTmp.txt,tAMPM.pco,0,0
|
covx tTmp.txt,tTime.pco,0,0
|
||||||
spstr strCommand.txt,tTmp.txt,"~",4
|
spstr strCommand.txt,tTmp.txt,"~",3
|
||||||
covx tTmp.txt,tDate.pco,0,0
|
covx tTmp.txt,tAMPM.pco,0,0
|
||||||
spstr strCommand.txt,tTmp.txt,"~",5
|
spstr strCommand.txt,tTmp.txt,"~",4
|
||||||
covx tTmp.txt,tMainText.pco,0,0
|
covx tTmp.txt,tDate.pco,0,0
|
||||||
//spstr strCommand.txt,tTmp.txt,"~",6
|
spstr strCommand.txt,tTmp.txt,"~",5
|
||||||
//covx tTmp.txt,tForecast1.pco,0,0
|
covx tTmp.txt,tMainText.pco,0,0
|
||||||
//spstr strCommand.txt,tTmp.txt,"~",7
|
//spstr strCommand.txt,tTmp.txt,"~",6
|
||||||
//covx tTmp.txt,tForecast2.pco,0,0
|
//covx tTmp.txt,tForecast1.pco,0,0
|
||||||
//spstr strCommand.txt,tTmp.txt,"~",8
|
//spstr strCommand.txt,tTmp.txt,"~",7
|
||||||
//covx tTmp.txt,tForecast3.pco,0,0
|
//covx tTmp.txt,tForecast2.pco,0,0
|
||||||
//spstr strCommand.txt,tTmp.txt,"~",9
|
//spstr strCommand.txt,tTmp.txt,"~",8
|
||||||
//covx tTmp.txt,tForecast4.pco,0,0
|
//covx tTmp.txt,tForecast3.pco,0,0
|
||||||
//spstr strCommand.txt,tTmp.txt,"~",10
|
//spstr strCommand.txt,tTmp.txt,"~",9
|
||||||
//covx tTmp.txt,tForecast1Val.pco,0,0
|
//covx tTmp.txt,tForecast4.pco,0,0
|
||||||
//spstr strCommand.txt,tTmp.txt,"~",11
|
//spstr strCommand.txt,tTmp.txt,"~",10
|
||||||
//covx tTmp.txt,tForecast2Val.pco,0,0
|
//covx tTmp.txt,tForecast1Val.pco,0,0
|
||||||
//spstr strCommand.txt,tTmp.txt,"~",12
|
//spstr strCommand.txt,tTmp.txt,"~",11
|
||||||
//covx tTmp.txt,tForecast3Val.pco,0,0
|
//covx tTmp.txt,tForecast2Val.pco,0,0
|
||||||
//spstr strCommand.txt,tTmp.txt,"~",13
|
//spstr strCommand.txt,tTmp.txt,"~",12
|
||||||
//covx tTmp.txt,tForecast4Val.pco,0,0
|
//covx tTmp.txt,tForecast3Val.pco,0,0
|
||||||
//spstr strCommand.txt,tTmp.txt,"~",14
|
//spstr strCommand.txt,tTmp.txt,"~",13
|
||||||
//covx tTmp.txt,t10.bco,0,0
|
//covx tTmp.txt,tForecast4Val.pco,0,0
|
||||||
//spstr strCommand.txt,tTmp.txt,"~",15
|
//spstr strCommand.txt,tTmp.txt,"~",14
|
||||||
//covx tTmp.txt,tMainTextAlt2.pco,0,0
|
//covx tTmp.txt,t10.bco,0,0
|
||||||
//spstr strCommand.txt,tTmp.txt,"~",16
|
//spstr strCommand.txt,tTmp.txt,"~",15
|
||||||
//covx tTmp.txt,tTimeAdd.pco,0,0
|
//covx tTmp.txt,tMainTextAlt2.pco,0,0
|
||||||
}
|
//spstr strCommand.txt,tTmp.txt,"~",16
|
||||||
|
//covx tTmp.txt,tTimeAdd.pco,0,0
|
||||||
|
}
|
||||||
|
|
||||||
if(tInstruction.txt=="notify")
|
|
||||||
{
|
|
||||||
spstr strCommand.txt,tNotifyHead.txt,"~",1
|
if(tInstruction.txt=="notify")
|
||||||
spstr strCommand.txt,tNotifyText.txt,"~",2
|
{
|
||||||
if(tNotifyHead.txt!=""||tNotifyText.txt!="")
|
spstr strCommand.txt,tNotifyHead.txt,"~",1
|
||||||
{
|
spstr strCommand.txt,tNotifyText.txt,"~",2
|
||||||
vis tNotifyHead,1
|
if(tNotifyHead.txt!=""||tNotifyText.txt!="")
|
||||||
vis tNotifyText,1
|
{
|
||||||
}else
|
vis tNotifyHead,1
|
||||||
{
|
vis tNotifyText,1
|
||||||
vis tNotifyHead,0
|
}else
|
||||||
vis tNotifyText,0
|
{
|
||||||
}
|
vis tNotifyHead,0
|
||||||
tNotifyHead.bco=tTime.bco
|
vis tNotifyText,0
|
||||||
tNotifyText.bco=tTime.bco
|
}
|
||||||
spstr strCommand.txt,tTmp.txt,"~",3
|
tNotifyHead.bco=tTime.bco
|
||||||
if(tTmp.txt!="")
|
tNotifyText.bco=tTime.bco
|
||||||
{
|
spstr strCommand.txt,tTmp.txt,"~",3
|
||||||
covx tTmp.txt,tNotifyHead.pco,0,0
|
if(tTmp.txt!="")
|
||||||
}
|
{
|
||||||
spstr strCommand.txt,tTmp.txt,"~",4
|
covx tTmp.txt,tNotifyHead.pco,0,0
|
||||||
if(tTmp.txt!="")
|
}
|
||||||
{
|
spstr strCommand.txt,tTmp.txt,"~",4
|
||||||
covx tTmp.txt,tNotifyText.pco,0,0
|
if(tTmp.txt!="")
|
||||||
}
|
{
|
||||||
"""
|
covx tTmp.txt,tNotifyText.pco,0,0
|
||||||
|
}
|
||||||
print(head)
|
"""
|
||||||
|
|
||||||
|
print(head)
|
||||||
#start = 23
|
|
||||||
#for i in range(1,7):
|
|
||||||
# idxstart = start + (i-1)*6
|
#start = 23
|
||||||
# item = f"""
|
#for i in range(1,7):
|
||||||
# // get Type
|
# idxstart = start + (i-1)*6
|
||||||
# spstr strCommand.txt,type{i}.txt,"~",{idxstart}
|
# item = f"""
|
||||||
# // get internal name
|
# // get Type
|
||||||
# spstr strCommand.txt,entn{i}.txt,"~",{idxstart+1}
|
# spstr strCommand.txt,type{i}.txt,"~",{idxstart}
|
||||||
# if(type{i}.txt=="delete"||type{i}.txt=="")
|
# // get internal name
|
||||||
# {{
|
# spstr strCommand.txt,entn{i}.txt,"~",{idxstart+1}
|
||||||
# vis tEntity{i},0
|
# if(type{i}.txt=="delete"||type{i}.txt=="")
|
||||||
# vis bEntity{i},0
|
# {{
|
||||||
# }}else
|
# vis tEntity{i},0
|
||||||
# {{
|
# vis bEntity{i},0
|
||||||
# // change icon
|
# }}else
|
||||||
# spstr strCommand.txt,bEntity{i}.txt,"~",{idxstart+2}
|
# {{
|
||||||
# vis bEntity{i},1
|
# // change icon
|
||||||
# // change icon color
|
# spstr strCommand.txt,bEntity{i}.txt,"~",{idxstart+2}
|
||||||
# spstr strCommand.txt,tTmp.txt,"~",{idxstart+3}
|
# vis bEntity{i},1
|
||||||
# covx tTmp.txt,sys0,0,0
|
# // change icon color
|
||||||
# bEntity{i}.pco=sys0
|
# spstr strCommand.txt,tTmp.txt,"~",{idxstart+3}
|
||||||
# // set name
|
# covx tTmp.txt,sys0,0,0
|
||||||
# spstr strCommand.txt,tEntity{i}.txt,"~",{idxstart+4}
|
# bEntity{i}.pco=sys0
|
||||||
# vis tEntity{i},1
|
# // set name
|
||||||
# }}
|
# spstr strCommand.txt,tEntity{i}.txt,"~",{idxstart+4}
|
||||||
#"""
|
# vis tEntity{i},1
|
||||||
# print(item)
|
# }}
|
||||||
foot = """
|
#"""
|
||||||
}
|
# print(item)
|
||||||
""" + sharedfoot.replace("sleepValue=0", "dim=100").replace("""
|
foot = """
|
||||||
if(tInstruction.txt=="time")
|
}
|
||||||
{
|
""" + sharedfoot.replace("sleepValue=0", "dim=100").replace("""
|
||||||
// get set time to global variable
|
if(tInstruction.txt=="time")
|
||||||
spstr strCommand.txt,pageIcons.vaTime.txt,"~",1
|
{
|
||||||
}
|
// get set time to global variable
|
||||||
if(tInstruction.txt=="date")
|
spstr strCommand.txt,pageIcons.vaTime.txt,"~",1
|
||||||
{
|
}
|
||||||
// get set date to global variable
|
if(tInstruction.txt=="date")
|
||||||
spstr strCommand.txt,pageIcons.vaDate.txt,"~",1
|
{
|
||||||
}
|
// get set date to global variable
|
||||||
if(tInstruction.txt=="dimmode")
|
spstr strCommand.txt,pageIcons.vaDate.txt,"~",1
|
||||||
{
|
}
|
||||||
// get value
|
if(tInstruction.txt=="dimmode")
|
||||||
spstr strCommand.txt,tTmp.txt,"~",1
|
{
|
||||||
covx tTmp.txt,dimValue,0,0
|
// get value
|
||||||
// get value normal
|
spstr strCommand.txt,tTmp.txt,"~",1
|
||||||
spstr strCommand.txt,tTmp.txt,"~",2
|
covx tTmp.txt,dimValue,0,0
|
||||||
covx tTmp.txt,dimValueNormal,0,0
|
// get value normal
|
||||||
dim=dimValueNormal
|
spstr strCommand.txt,tTmp.txt,"~",2
|
||||||
// get background color
|
covx tTmp.txt,dimValueNormal,0,0
|
||||||
spstr strCommand.txt,tTmp.txt,"~",3
|
dim=dimValueNormal
|
||||||
if(tTmp.txt!="")
|
// get background color
|
||||||
{
|
spstr strCommand.txt,tTmp.txt,"~",3
|
||||||
covx tTmp.txt,defaultBcoColor,0,0
|
if(tTmp.txt!="")
|
||||||
}
|
{
|
||||||
// get font color
|
covx tTmp.txt,defaultBcoColor,0,0
|
||||||
spstr strCommand.txt,tTmp.txt,"~",4
|
}
|
||||||
if(tTmp.txt!="")
|
// get font color
|
||||||
{
|
spstr strCommand.txt,tTmp.txt,"~",4
|
||||||
covx tTmp.txt,defaultFontColor,0,0
|
if(tTmp.txt!="")
|
||||||
}
|
{
|
||||||
}""","")
|
covx tTmp.txt,defaultFontColor,0,0
|
||||||
print(foot)
|
}
|
||||||
|
}""","")
|
||||||
|
print(foot)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,63 +0,0 @@
|
|||||||
Page cardBurnRec
|
|
||||||
Attributes
|
|
||||||
ID : 0
|
|
||||||
Scope : local
|
|
||||||
Dragging : 0
|
|
||||||
Send Component ID : disabled
|
|
||||||
Opacity : 127
|
|
||||||
Width : 480
|
|
||||||
Effect : load
|
|
||||||
Effect Priority : 0
|
|
||||||
Effect Time : 300
|
|
||||||
Locked : no
|
|
||||||
Swide up page ID : disabled
|
|
||||||
Swide down page ID : disabled
|
|
||||||
Swide left page ID : disabled
|
|
||||||
Swide right page ID: disabled
|
|
||||||
Fill : solid color
|
|
||||||
Back. Color : 65535
|
|
||||||
|
|
||||||
Timer tm0
|
|
||||||
Attributes
|
|
||||||
ID : 1
|
|
||||||
Scope : local
|
|
||||||
Period (ms): 1001
|
|
||||||
Enabled : yes
|
|
||||||
|
|
||||||
Events
|
|
||||||
Timer Event
|
|
||||||
dim=100
|
|
||||||
sys0=0
|
|
||||||
sys1=0
|
|
||||||
if(sys2==WHITE)
|
|
||||||
{
|
|
||||||
sys2=BLACK
|
|
||||||
}else
|
|
||||||
{
|
|
||||||
sys2=WHITE
|
|
||||||
}
|
|
||||||
sya1=sys2
|
|
||||||
while(sys0<8)
|
|
||||||
{
|
|
||||||
sya0=sys0%2
|
|
||||||
if(sya1==WHITE)
|
|
||||||
{
|
|
||||||
sya1=BLACK
|
|
||||||
}else
|
|
||||||
{
|
|
||||||
sya1=WHITE
|
|
||||||
}
|
|
||||||
fill 0,40*sys0,480,40,sya1
|
|
||||||
sys0++
|
|
||||||
}
|
|
||||||
|
|
||||||
TouchCap tc0
|
|
||||||
Attributes
|
|
||||||
ID : 2
|
|
||||||
Scope: local
|
|
||||||
Value: 0
|
|
||||||
|
|
||||||
Events
|
|
||||||
Touch Press Event
|
|
||||||
page pageStartup
|
|
||||||
|
|
||||||
@@ -6,10 +6,14 @@ pageIcons
|
|||||||
7 Component(s)
|
7 Component(s)
|
||||||
0 Line(s) of event code
|
0 Line(s) of event code
|
||||||
0 Unique line(s) of event code
|
0 Unique line(s) of event code
|
||||||
cardBurnRec
|
pageTest
|
||||||
3 Component(s)
|
25 Component(s)
|
||||||
25 Line(s) of event code
|
68 Line(s) of event code
|
||||||
21 Unique line(s) of event code
|
66 Unique line(s) of event code
|
||||||
|
popupNotify
|
||||||
|
19 Component(s)
|
||||||
|
271 Line(s) of event code
|
||||||
|
174 Unique line(s) of event code
|
||||||
popupFan
|
popupFan
|
||||||
27 Component(s)
|
27 Component(s)
|
||||||
355 Line(s) of event code
|
355 Line(s) of event code
|
||||||
@@ -26,14 +30,10 @@ popupLightNew
|
|||||||
23 Component(s)
|
23 Component(s)
|
||||||
412 Line(s) of event code
|
412 Line(s) of event code
|
||||||
209 Unique line(s) of event code
|
209 Unique line(s) of event code
|
||||||
popupNotify
|
popupLight
|
||||||
19 Component(s)
|
28 Component(s)
|
||||||
267 Line(s) of event code
|
417 Line(s) of event code
|
||||||
172 Unique line(s) of event code
|
228 Unique line(s) of event code
|
||||||
pageTest
|
|
||||||
26 Component(s)
|
|
||||||
69 Line(s) of event code
|
|
||||||
67 Unique line(s) of event code
|
|
||||||
cardGrid2
|
cardGrid2
|
||||||
52 Component(s)
|
52 Component(s)
|
||||||
703 Line(s) of event code
|
703 Line(s) of event code
|
||||||
@@ -46,6 +46,10 @@ cardChart
|
|||||||
33 Component(s)
|
33 Component(s)
|
||||||
447 Line(s) of event code
|
447 Line(s) of event code
|
||||||
297 Unique line(s) of event code
|
297 Unique line(s) of event code
|
||||||
|
cardGrid
|
||||||
|
44 Component(s)
|
||||||
|
593 Line(s) of event code
|
||||||
|
333 Unique line(s) of event code
|
||||||
cardQR
|
cardQR
|
||||||
34 Component(s)
|
34 Component(s)
|
||||||
420 Line(s) of event code
|
420 Line(s) of event code
|
||||||
@@ -54,10 +58,6 @@ cardLChart
|
|||||||
33 Component(s)
|
33 Component(s)
|
||||||
412 Line(s) of event code
|
412 Line(s) of event code
|
||||||
267 Unique line(s) of event code
|
267 Unique line(s) of event code
|
||||||
popupLight
|
|
||||||
28 Component(s)
|
|
||||||
412 Line(s) of event code
|
|
||||||
227 Unique line(s) of event code
|
|
||||||
cardPower
|
cardPower
|
||||||
54 Component(s)
|
54 Component(s)
|
||||||
541 Line(s) of event code
|
541 Line(s) of event code
|
||||||
@@ -66,10 +66,6 @@ cardThermo
|
|||||||
57 Component(s)
|
57 Component(s)
|
||||||
550 Line(s) of event code
|
550 Line(s) of event code
|
||||||
320 Unique line(s) of event code
|
320 Unique line(s) of event code
|
||||||
cardGrid
|
|
||||||
44 Component(s)
|
|
||||||
593 Line(s) of event code
|
|
||||||
333 Unique line(s) of event code
|
|
||||||
popupInSel
|
popupInSel
|
||||||
34 Component(s)
|
34 Component(s)
|
||||||
621 Line(s) of event code
|
621 Line(s) of event code
|
||||||
@@ -91,16 +87,16 @@ popupThermo
|
|||||||
523 Line(s) of event code
|
523 Line(s) of event code
|
||||||
276 Unique line(s) of event code
|
276 Unique line(s) of event code
|
||||||
screensaver2
|
screensaver2
|
||||||
59 Component(s)
|
64 Component(s)
|
||||||
373 Line(s) of event code
|
448 Line(s) of event code
|
||||||
256 Unique line(s) of event code
|
272 Unique line(s) of event code
|
||||||
cardEntities
|
cardEntities
|
||||||
67 Component(s)
|
67 Component(s)
|
||||||
1205 Line(s) of event code
|
1205 Line(s) of event code
|
||||||
536 Unique line(s) of event code
|
536 Unique line(s) of event code
|
||||||
|
|
||||||
Total
|
Total
|
||||||
24 Page(s)
|
23 Page(s)
|
||||||
880 Component(s)
|
881 Component(s)
|
||||||
10740 Line(s) of event code
|
10798 Line(s) of event code
|
||||||
2475 Unique line(s) of event code
|
2472 Unique line(s) of event code
|
||||||
|
|||||||
@@ -335,41 +335,6 @@ Button b13
|
|||||||
Touch Press Event
|
Touch Press Event
|
||||||
showqq
|
showqq
|
||||||
|
|
||||||
Button b14
|
|
||||||
Attributes
|
|
||||||
ID : 25
|
|
||||||
Scope : local
|
|
||||||
Dragging : 0
|
|
||||||
Send Component ID : disabled
|
|
||||||
Opacity : 127
|
|
||||||
x coordinate : 229
|
|
||||||
y coordinate : 188
|
|
||||||
Width : 106
|
|
||||||
Height : 40
|
|
||||||
Effect : load
|
|
||||||
Effect Priority : 0
|
|
||||||
Effect Time : 300
|
|
||||||
Fill : solid color
|
|
||||||
Style : 3D auto
|
|
||||||
Font ID : 1
|
|
||||||
Back. Color : 50712
|
|
||||||
Back. Picture ID (Pressed): 65535
|
|
||||||
Back. Color (Pressed) : 1024
|
|
||||||
Font Color (Unpressed) : 0
|
|
||||||
Font Color (Pressed) : 65535
|
|
||||||
Horizontal Alignment : center
|
|
||||||
Vertical Alignment : center
|
|
||||||
State : unpressed
|
|
||||||
Text : burntest
|
|
||||||
Max. Text Size : 10
|
|
||||||
Word wrap : disabled
|
|
||||||
Horizontal Spacing : 0
|
|
||||||
Vertical Spacing : 0
|
|
||||||
|
|
||||||
Events
|
|
||||||
Touch Press Event
|
|
||||||
page cardBurnRec
|
|
||||||
|
|
||||||
Button b15
|
Button b15
|
||||||
Attributes
|
Attributes
|
||||||
ID : 21
|
ID : 21
|
||||||
|
|||||||
@@ -806,6 +806,11 @@ Timer tmSerial
|
|||||||
if(tInstruction.txt=="entityUpdateDetail"&&entn.txt==tTmp.txt)
|
if(tInstruction.txt=="entityUpdateDetail"&&entn.txt==tTmp.txt)
|
||||||
{
|
{
|
||||||
// change icon
|
// change icon
|
||||||
|
spstr strCommand.txt,tTmp.txt,"~",2
|
||||||
|
if(tTmp.txt!="")
|
||||||
|
{
|
||||||
|
tIcon1.txt=tTmp.txt
|
||||||
|
}
|
||||||
//spstr strCommand.txt,tIcon1.txt,"~",2
|
//spstr strCommand.txt,tIcon1.txt,"~",2
|
||||||
vis tIcon1,1
|
vis tIcon1,1
|
||||||
// change icon color
|
// change icon color
|
||||||
|
|||||||
@@ -672,6 +672,10 @@ Timer tmSerial
|
|||||||
{
|
{
|
||||||
page cardChart
|
page cardChart
|
||||||
}
|
}
|
||||||
|
if(tId.txt=="cardLChart")
|
||||||
|
{
|
||||||
|
page cardLChart
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// end of user code
|
// end of user code
|
||||||
udelete payloadLength-1
|
udelete payloadLength-1
|
||||||
|
|||||||
@@ -56,12 +56,47 @@ Page screensaver2
|
|||||||
Postinitialize Event
|
Postinitialize Event
|
||||||
click m0,1
|
click m0,1
|
||||||
|
|
||||||
|
Variable (string) entn1
|
||||||
|
Attributes
|
||||||
|
ID : 59
|
||||||
|
Scope : local
|
||||||
|
Text :
|
||||||
|
Max. Text Size: 14
|
||||||
|
|
||||||
|
Variable (string) entn2
|
||||||
|
Attributes
|
||||||
|
ID : 60
|
||||||
|
Scope : local
|
||||||
|
Text :
|
||||||
|
Max. Text Size: 14
|
||||||
|
|
||||||
|
Variable (string) entn3
|
||||||
|
Attributes
|
||||||
|
ID : 61
|
||||||
|
Scope : local
|
||||||
|
Text :
|
||||||
|
Max. Text Size: 14
|
||||||
|
|
||||||
|
Variable (string) entn4
|
||||||
|
Attributes
|
||||||
|
ID : 62
|
||||||
|
Scope : local
|
||||||
|
Text :
|
||||||
|
Max. Text Size: 14
|
||||||
|
|
||||||
|
Variable (string) entn5
|
||||||
|
Attributes
|
||||||
|
ID : 63
|
||||||
|
Scope : local
|
||||||
|
Text :
|
||||||
|
Max. Text Size: 14
|
||||||
|
|
||||||
Variable (string) strCommand
|
Variable (string) strCommand
|
||||||
Attributes
|
Attributes
|
||||||
ID : 4
|
ID : 4
|
||||||
Scope : local
|
Scope : local
|
||||||
Text :
|
Text :
|
||||||
Max. Text Size: 1979
|
Max. Text Size: 1935
|
||||||
|
|
||||||
Variable (string) strTmp
|
Variable (string) strTmp
|
||||||
Attributes
|
Attributes
|
||||||
@@ -82,7 +117,7 @@ Variable (string) tInstruction
|
|||||||
ID : 18
|
ID : 18
|
||||||
Scope : local
|
Scope : local
|
||||||
Text :
|
Text :
|
||||||
Max. Text Size: 50
|
Max. Text Size: 15
|
||||||
|
|
||||||
Variable (string) tSend
|
Variable (string) tSend
|
||||||
Attributes
|
Attributes
|
||||||
@@ -96,7 +131,7 @@ Variable (string) tTmp
|
|||||||
ID : 19
|
ID : 19
|
||||||
Scope : local
|
Scope : local
|
||||||
Text :
|
Text :
|
||||||
Max. Text Size: 50
|
Max. Text Size: 30
|
||||||
|
|
||||||
Variable (int32) vaTap
|
Variable (int32) vaTap
|
||||||
Attributes
|
Attributes
|
||||||
@@ -865,6 +900,25 @@ Text f1Icon
|
|||||||
Horizontal Spacing : 0
|
Horizontal Spacing : 0
|
||||||
Vertical Spacing : 0
|
Vertical Spacing : 0
|
||||||
|
|
||||||
|
Events
|
||||||
|
Touch Press Event
|
||||||
|
tSend.txt="event,buttonPress2,"+entn1.txt+",button"
|
||||||
|
if(entn1.txt=="")
|
||||||
|
{
|
||||||
|
tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.txt
|
||||||
|
}
|
||||||
|
//send calc crc
|
||||||
|
btlen tSend.txt,sys0
|
||||||
|
crcrest 1,0xffff // reset CRC
|
||||||
|
crcputh 55 bb
|
||||||
|
crcputs sys0,2
|
||||||
|
crcputs tSend.txt,0
|
||||||
|
//send cmd
|
||||||
|
printh 55 bb
|
||||||
|
prints sys0,2
|
||||||
|
prints tSend.txt,0
|
||||||
|
prints crcval,2
|
||||||
|
|
||||||
Text f2Icon
|
Text f2Icon
|
||||||
Attributes
|
Attributes
|
||||||
ID : 54
|
ID : 54
|
||||||
@@ -894,6 +948,25 @@ Text f2Icon
|
|||||||
Horizontal Spacing : 0
|
Horizontal Spacing : 0
|
||||||
Vertical Spacing : 0
|
Vertical Spacing : 0
|
||||||
|
|
||||||
|
Events
|
||||||
|
Touch Press Event
|
||||||
|
tSend.txt="event,buttonPress2,"+entn2.txt+",button"
|
||||||
|
if(entn2.txt=="")
|
||||||
|
{
|
||||||
|
tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.txt
|
||||||
|
}
|
||||||
|
//send calc crc
|
||||||
|
btlen tSend.txt,sys0
|
||||||
|
crcrest 1,0xffff // reset CRC
|
||||||
|
crcputh 55 bb
|
||||||
|
crcputs sys0,2
|
||||||
|
crcputs tSend.txt,0
|
||||||
|
//send cmd
|
||||||
|
printh 55 bb
|
||||||
|
prints sys0,2
|
||||||
|
prints tSend.txt,0
|
||||||
|
prints crcval,2
|
||||||
|
|
||||||
Text f3Icon
|
Text f3Icon
|
||||||
Attributes
|
Attributes
|
||||||
ID : 55
|
ID : 55
|
||||||
@@ -923,6 +996,25 @@ Text f3Icon
|
|||||||
Horizontal Spacing : 0
|
Horizontal Spacing : 0
|
||||||
Vertical Spacing : 0
|
Vertical Spacing : 0
|
||||||
|
|
||||||
|
Events
|
||||||
|
Touch Press Event
|
||||||
|
tSend.txt="event,buttonPress2,"+entn3.txt+",button"
|
||||||
|
if(entn3.txt=="")
|
||||||
|
{
|
||||||
|
tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.txt
|
||||||
|
}
|
||||||
|
//send calc crc
|
||||||
|
btlen tSend.txt,sys0
|
||||||
|
crcrest 1,0xffff // reset CRC
|
||||||
|
crcputh 55 bb
|
||||||
|
crcputs sys0,2
|
||||||
|
crcputs tSend.txt,0
|
||||||
|
//send cmd
|
||||||
|
printh 55 bb
|
||||||
|
prints sys0,2
|
||||||
|
prints tSend.txt,0
|
||||||
|
prints crcval,2
|
||||||
|
|
||||||
Text f4Icon
|
Text f4Icon
|
||||||
Attributes
|
Attributes
|
||||||
ID : 53
|
ID : 53
|
||||||
@@ -952,6 +1044,25 @@ Text f4Icon
|
|||||||
Horizontal Spacing : 0
|
Horizontal Spacing : 0
|
||||||
Vertical Spacing : 0
|
Vertical Spacing : 0
|
||||||
|
|
||||||
|
Events
|
||||||
|
Touch Press Event
|
||||||
|
tSend.txt="event,buttonPress2,"+entn4.txt+",button"
|
||||||
|
if(entn4.txt=="")
|
||||||
|
{
|
||||||
|
tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.txt
|
||||||
|
}
|
||||||
|
//send calc crc
|
||||||
|
btlen tSend.txt,sys0
|
||||||
|
crcrest 1,0xffff // reset CRC
|
||||||
|
crcputh 55 bb
|
||||||
|
crcputs sys0,2
|
||||||
|
crcputs tSend.txt,0
|
||||||
|
//send cmd
|
||||||
|
printh 55 bb
|
||||||
|
prints sys0,2
|
||||||
|
prints tSend.txt,0
|
||||||
|
prints crcval,2
|
||||||
|
|
||||||
Text f5Icon
|
Text f5Icon
|
||||||
Attributes
|
Attributes
|
||||||
ID : 52
|
ID : 52
|
||||||
@@ -981,6 +1092,25 @@ Text f5Icon
|
|||||||
Horizontal Spacing : 0
|
Horizontal Spacing : 0
|
||||||
Vertical Spacing : 0
|
Vertical Spacing : 0
|
||||||
|
|
||||||
|
Events
|
||||||
|
Touch Press Event
|
||||||
|
tSend.txt="event,buttonPress2,"+entn5.txt+",button"
|
||||||
|
if(entn5.txt=="")
|
||||||
|
{
|
||||||
|
tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.txt
|
||||||
|
}
|
||||||
|
//send calc crc
|
||||||
|
btlen tSend.txt,sys0
|
||||||
|
crcrest 1,0xffff // reset CRC
|
||||||
|
crcputh 55 bb
|
||||||
|
crcputs sys0,2
|
||||||
|
crcputs tSend.txt,0
|
||||||
|
//send cmd
|
||||||
|
printh 55 bb
|
||||||
|
prints sys0,2
|
||||||
|
prints tSend.txt,0
|
||||||
|
prints crcval,2
|
||||||
|
|
||||||
Text m0
|
Text m0
|
||||||
Attributes
|
Attributes
|
||||||
ID : 32
|
ID : 32
|
||||||
@@ -1551,26 +1681,36 @@ Timer tmSerial
|
|||||||
//f1Icon Color
|
//f1Icon Color
|
||||||
spstr strCommand.txt,tTmp.txt,"~",64
|
spstr strCommand.txt,tTmp.txt,"~",64
|
||||||
covx tTmp.txt,f1Icon.pco,0,0
|
covx tTmp.txt,f1Icon.pco,0,0
|
||||||
|
//f1Icon intNameEntity
|
||||||
|
spstr strCommand.txt,entn1.txt,"~",62
|
||||||
//f2Icon
|
//f2Icon
|
||||||
spstr strCommand.txt,f2Icon.txt,"~",69
|
spstr strCommand.txt,f2Icon.txt,"~",69
|
||||||
//f2Icon Color
|
//f2Icon Color
|
||||||
spstr strCommand.txt,tTmp.txt,"~",70
|
spstr strCommand.txt,tTmp.txt,"~",70
|
||||||
covx tTmp.txt,f2Icon.pco,0,0
|
covx tTmp.txt,f2Icon.pco,0,0
|
||||||
|
//f2Icon intNameEntity
|
||||||
|
spstr strCommand.txt,entn2.txt,"~",68
|
||||||
//f3Icon
|
//f3Icon
|
||||||
spstr strCommand.txt,f3Icon.txt,"~",75
|
spstr strCommand.txt,f3Icon.txt,"~",75
|
||||||
//f3Icon Color
|
//f3Icon Color
|
||||||
spstr strCommand.txt,tTmp.txt,"~",76
|
spstr strCommand.txt,tTmp.txt,"~",76
|
||||||
covx tTmp.txt,f3Icon.pco,0,0
|
covx tTmp.txt,f3Icon.pco,0,0
|
||||||
|
//f3Icon intNameEntity
|
||||||
|
spstr strCommand.txt,entn3.txt,"~",74
|
||||||
//f4Icon
|
//f4Icon
|
||||||
spstr strCommand.txt,f4Icon.txt,"~",81
|
spstr strCommand.txt,f4Icon.txt,"~",81
|
||||||
//f4Icon Color
|
//f4Icon Color
|
||||||
spstr strCommand.txt,tTmp.txt,"~",82
|
spstr strCommand.txt,tTmp.txt,"~",82
|
||||||
covx tTmp.txt,f4Icon.pco,0,0
|
covx tTmp.txt,f4Icon.pco,0,0
|
||||||
|
//f4Icon intNameEntity
|
||||||
|
spstr strCommand.txt,entn4.txt,"~",80
|
||||||
//f5Icon
|
//f5Icon
|
||||||
spstr strCommand.txt,f5Icon.txt,"~",87
|
spstr strCommand.txt,f5Icon.txt,"~",87
|
||||||
//f5Icon Color
|
//f5Icon Color
|
||||||
spstr strCommand.txt,tTmp.txt,"~",88
|
spstr strCommand.txt,tTmp.txt,"~",88
|
||||||
covx tTmp.txt,f5Icon.pco,0,0
|
covx tTmp.txt,f5Icon.pco,0,0
|
||||||
|
//f5Icon intNameEntity
|
||||||
|
spstr strCommand.txt,entn5.txt,"~",86
|
||||||
}
|
}
|
||||||
if(tInstruction.txt=="notify")
|
if(tInstruction.txt=="notify")
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,53 +0,0 @@
|
|||||||
Page cardBurnRec
|
|
||||||
Attributes
|
|
||||||
Scope : local
|
|
||||||
Dragging : 0
|
|
||||||
Send Component ID : disabled
|
|
||||||
Locked : no
|
|
||||||
Swide up page ID : disabled
|
|
||||||
Swide down page ID : disabled
|
|
||||||
Swide left page ID : disabled
|
|
||||||
Swide right page ID: disabled
|
|
||||||
|
|
||||||
Timer tm0
|
|
||||||
Attributes
|
|
||||||
Scope : local
|
|
||||||
Period (ms): 1001
|
|
||||||
Enabled : yes
|
|
||||||
|
|
||||||
Events
|
|
||||||
Timer Event
|
|
||||||
dim=100
|
|
||||||
sys0=0
|
|
||||||
sys1=0
|
|
||||||
if(sys2==WHITE)
|
|
||||||
{
|
|
||||||
sys2=BLACK
|
|
||||||
}else
|
|
||||||
{
|
|
||||||
sys2=WHITE
|
|
||||||
}
|
|
||||||
sya1=sys2
|
|
||||||
while(sys0<8)
|
|
||||||
{
|
|
||||||
sya0=sys0%2
|
|
||||||
if(sya1==WHITE)
|
|
||||||
{
|
|
||||||
sya1=BLACK
|
|
||||||
}else
|
|
||||||
{
|
|
||||||
sya1=WHITE
|
|
||||||
}
|
|
||||||
fill 0,40*sys0,480,40,sya1
|
|
||||||
sys0++
|
|
||||||
}
|
|
||||||
|
|
||||||
TouchCap tc0
|
|
||||||
Attributes
|
|
||||||
Scope: local
|
|
||||||
Value: 0
|
|
||||||
|
|
||||||
Events
|
|
||||||
Touch Press Event
|
|
||||||
page pageStartup
|
|
||||||
|
|
||||||
@@ -141,19 +141,6 @@ Button b13
|
|||||||
Touch Press Event
|
Touch Press Event
|
||||||
showqq
|
showqq
|
||||||
|
|
||||||
Button b14
|
|
||||||
Attributes
|
|
||||||
Scope : local
|
|
||||||
Dragging : 0
|
|
||||||
Send Component ID: disabled
|
|
||||||
State : unpressed
|
|
||||||
Text : burntest
|
|
||||||
Max. Text Size : 10
|
|
||||||
|
|
||||||
Events
|
|
||||||
Touch Press Event
|
|
||||||
page cardBurnRec
|
|
||||||
|
|
||||||
Button b15
|
Button b15
|
||||||
Attributes
|
Attributes
|
||||||
Scope : local
|
Scope : local
|
||||||
|
|||||||
@@ -457,6 +457,11 @@ Timer tmSerial
|
|||||||
if(tInstruction.txt=="entityUpdateDetail"&&entn.txt==tTmp.txt)
|
if(tInstruction.txt=="entityUpdateDetail"&&entn.txt==tTmp.txt)
|
||||||
{
|
{
|
||||||
// change icon
|
// change icon
|
||||||
|
spstr strCommand.txt,tTmp.txt,"~",2
|
||||||
|
if(tTmp.txt!="")
|
||||||
|
{
|
||||||
|
tIcon1.txt=tTmp.txt
|
||||||
|
}
|
||||||
//spstr strCommand.txt,tIcon1.txt,"~",2
|
//spstr strCommand.txt,tIcon1.txt,"~",2
|
||||||
vis tIcon1,1
|
vis tIcon1,1
|
||||||
// change icon color
|
// change icon color
|
||||||
|
|||||||
@@ -443,6 +443,10 @@ Timer tmSerial
|
|||||||
{
|
{
|
||||||
page cardChart
|
page cardChart
|
||||||
}
|
}
|
||||||
|
if(tId.txt=="cardLChart")
|
||||||
|
{
|
||||||
|
page cardLChart
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// end of user code
|
// end of user code
|
||||||
udelete payloadLength-1
|
udelete payloadLength-1
|
||||||
|
|||||||
@@ -48,11 +48,41 @@ Page screensaver2
|
|||||||
Postinitialize Event
|
Postinitialize Event
|
||||||
click m0,1
|
click m0,1
|
||||||
|
|
||||||
|
Variable (string) entn1
|
||||||
|
Attributes
|
||||||
|
Scope : local
|
||||||
|
Text :
|
||||||
|
Max. Text Size: 14
|
||||||
|
|
||||||
|
Variable (string) entn2
|
||||||
|
Attributes
|
||||||
|
Scope : local
|
||||||
|
Text :
|
||||||
|
Max. Text Size: 14
|
||||||
|
|
||||||
|
Variable (string) entn3
|
||||||
|
Attributes
|
||||||
|
Scope : local
|
||||||
|
Text :
|
||||||
|
Max. Text Size: 14
|
||||||
|
|
||||||
|
Variable (string) entn4
|
||||||
|
Attributes
|
||||||
|
Scope : local
|
||||||
|
Text :
|
||||||
|
Max. Text Size: 14
|
||||||
|
|
||||||
|
Variable (string) entn5
|
||||||
|
Attributes
|
||||||
|
Scope : local
|
||||||
|
Text :
|
||||||
|
Max. Text Size: 14
|
||||||
|
|
||||||
Variable (string) strCommand
|
Variable (string) strCommand
|
||||||
Attributes
|
Attributes
|
||||||
Scope : local
|
Scope : local
|
||||||
Text :
|
Text :
|
||||||
Max. Text Size: 1979
|
Max. Text Size: 1935
|
||||||
|
|
||||||
Variable (string) strTmp
|
Variable (string) strTmp
|
||||||
Attributes
|
Attributes
|
||||||
@@ -70,7 +100,7 @@ Variable (string) tInstruction
|
|||||||
Attributes
|
Attributes
|
||||||
Scope : local
|
Scope : local
|
||||||
Text :
|
Text :
|
||||||
Max. Text Size: 50
|
Max. Text Size: 15
|
||||||
|
|
||||||
Variable (string) tSend
|
Variable (string) tSend
|
||||||
Attributes
|
Attributes
|
||||||
@@ -82,7 +112,7 @@ Variable (string) tTmp
|
|||||||
Attributes
|
Attributes
|
||||||
Scope : local
|
Scope : local
|
||||||
Text :
|
Text :
|
||||||
Max. Text Size: 50
|
Max. Text Size: 30
|
||||||
|
|
||||||
Variable (int32) vaTap
|
Variable (int32) vaTap
|
||||||
Attributes
|
Attributes
|
||||||
@@ -344,6 +374,25 @@ Text f1Icon
|
|||||||
Text :
|
Text :
|
||||||
Max. Text Size : 4
|
Max. Text Size : 4
|
||||||
|
|
||||||
|
Events
|
||||||
|
Touch Press Event
|
||||||
|
tSend.txt="event,buttonPress2,"+entn1.txt+",button"
|
||||||
|
if(entn1.txt=="")
|
||||||
|
{
|
||||||
|
tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.txt
|
||||||
|
}
|
||||||
|
//send calc crc
|
||||||
|
btlen tSend.txt,sys0
|
||||||
|
crcrest 1,0xffff // reset CRC
|
||||||
|
crcputh 55 bb
|
||||||
|
crcputs sys0,2
|
||||||
|
crcputs tSend.txt,0
|
||||||
|
//send cmd
|
||||||
|
printh 55 bb
|
||||||
|
prints sys0,2
|
||||||
|
prints tSend.txt,0
|
||||||
|
prints crcval,2
|
||||||
|
|
||||||
Text f2Icon
|
Text f2Icon
|
||||||
Attributes
|
Attributes
|
||||||
Scope : local
|
Scope : local
|
||||||
@@ -353,6 +402,25 @@ Text f2Icon
|
|||||||
Text :
|
Text :
|
||||||
Max. Text Size : 4
|
Max. Text Size : 4
|
||||||
|
|
||||||
|
Events
|
||||||
|
Touch Press Event
|
||||||
|
tSend.txt="event,buttonPress2,"+entn2.txt+",button"
|
||||||
|
if(entn2.txt=="")
|
||||||
|
{
|
||||||
|
tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.txt
|
||||||
|
}
|
||||||
|
//send calc crc
|
||||||
|
btlen tSend.txt,sys0
|
||||||
|
crcrest 1,0xffff // reset CRC
|
||||||
|
crcputh 55 bb
|
||||||
|
crcputs sys0,2
|
||||||
|
crcputs tSend.txt,0
|
||||||
|
//send cmd
|
||||||
|
printh 55 bb
|
||||||
|
prints sys0,2
|
||||||
|
prints tSend.txt,0
|
||||||
|
prints crcval,2
|
||||||
|
|
||||||
Text f3Icon
|
Text f3Icon
|
||||||
Attributes
|
Attributes
|
||||||
Scope : local
|
Scope : local
|
||||||
@@ -362,6 +430,25 @@ Text f3Icon
|
|||||||
Text :
|
Text :
|
||||||
Max. Text Size : 4
|
Max. Text Size : 4
|
||||||
|
|
||||||
|
Events
|
||||||
|
Touch Press Event
|
||||||
|
tSend.txt="event,buttonPress2,"+entn3.txt+",button"
|
||||||
|
if(entn3.txt=="")
|
||||||
|
{
|
||||||
|
tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.txt
|
||||||
|
}
|
||||||
|
//send calc crc
|
||||||
|
btlen tSend.txt,sys0
|
||||||
|
crcrest 1,0xffff // reset CRC
|
||||||
|
crcputh 55 bb
|
||||||
|
crcputs sys0,2
|
||||||
|
crcputs tSend.txt,0
|
||||||
|
//send cmd
|
||||||
|
printh 55 bb
|
||||||
|
prints sys0,2
|
||||||
|
prints tSend.txt,0
|
||||||
|
prints crcval,2
|
||||||
|
|
||||||
Text f4Icon
|
Text f4Icon
|
||||||
Attributes
|
Attributes
|
||||||
Scope : local
|
Scope : local
|
||||||
@@ -371,6 +458,25 @@ Text f4Icon
|
|||||||
Text :
|
Text :
|
||||||
Max. Text Size : 4
|
Max. Text Size : 4
|
||||||
|
|
||||||
|
Events
|
||||||
|
Touch Press Event
|
||||||
|
tSend.txt="event,buttonPress2,"+entn4.txt+",button"
|
||||||
|
if(entn4.txt=="")
|
||||||
|
{
|
||||||
|
tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.txt
|
||||||
|
}
|
||||||
|
//send calc crc
|
||||||
|
btlen tSend.txt,sys0
|
||||||
|
crcrest 1,0xffff // reset CRC
|
||||||
|
crcputh 55 bb
|
||||||
|
crcputs sys0,2
|
||||||
|
crcputs tSend.txt,0
|
||||||
|
//send cmd
|
||||||
|
printh 55 bb
|
||||||
|
prints sys0,2
|
||||||
|
prints tSend.txt,0
|
||||||
|
prints crcval,2
|
||||||
|
|
||||||
Text f5Icon
|
Text f5Icon
|
||||||
Attributes
|
Attributes
|
||||||
Scope : local
|
Scope : local
|
||||||
@@ -380,6 +486,25 @@ Text f5Icon
|
|||||||
Text :
|
Text :
|
||||||
Max. Text Size : 4
|
Max. Text Size : 4
|
||||||
|
|
||||||
|
Events
|
||||||
|
Touch Press Event
|
||||||
|
tSend.txt="event,buttonPress2,"+entn5.txt+",button"
|
||||||
|
if(entn5.txt=="")
|
||||||
|
{
|
||||||
|
tSend.txt="event,buttonPress2,screensaver,bExit,"+tTmp.txt
|
||||||
|
}
|
||||||
|
//send calc crc
|
||||||
|
btlen tSend.txt,sys0
|
||||||
|
crcrest 1,0xffff // reset CRC
|
||||||
|
crcputh 55 bb
|
||||||
|
crcputs sys0,2
|
||||||
|
crcputs tSend.txt,0
|
||||||
|
//send cmd
|
||||||
|
printh 55 bb
|
||||||
|
prints sys0,2
|
||||||
|
prints tSend.txt,0
|
||||||
|
prints crcval,2
|
||||||
|
|
||||||
Text m0
|
Text m0
|
||||||
Attributes
|
Attributes
|
||||||
Scope : local
|
Scope : local
|
||||||
@@ -718,26 +843,36 @@ Timer tmSerial
|
|||||||
//f1Icon Color
|
//f1Icon Color
|
||||||
spstr strCommand.txt,tTmp.txt,"~",64
|
spstr strCommand.txt,tTmp.txt,"~",64
|
||||||
covx tTmp.txt,f1Icon.pco,0,0
|
covx tTmp.txt,f1Icon.pco,0,0
|
||||||
|
//f1Icon intNameEntity
|
||||||
|
spstr strCommand.txt,entn1.txt,"~",62
|
||||||
//f2Icon
|
//f2Icon
|
||||||
spstr strCommand.txt,f2Icon.txt,"~",69
|
spstr strCommand.txt,f2Icon.txt,"~",69
|
||||||
//f2Icon Color
|
//f2Icon Color
|
||||||
spstr strCommand.txt,tTmp.txt,"~",70
|
spstr strCommand.txt,tTmp.txt,"~",70
|
||||||
covx tTmp.txt,f2Icon.pco,0,0
|
covx tTmp.txt,f2Icon.pco,0,0
|
||||||
|
//f2Icon intNameEntity
|
||||||
|
spstr strCommand.txt,entn2.txt,"~",68
|
||||||
//f3Icon
|
//f3Icon
|
||||||
spstr strCommand.txt,f3Icon.txt,"~",75
|
spstr strCommand.txt,f3Icon.txt,"~",75
|
||||||
//f3Icon Color
|
//f3Icon Color
|
||||||
spstr strCommand.txt,tTmp.txt,"~",76
|
spstr strCommand.txt,tTmp.txt,"~",76
|
||||||
covx tTmp.txt,f3Icon.pco,0,0
|
covx tTmp.txt,f3Icon.pco,0,0
|
||||||
|
//f3Icon intNameEntity
|
||||||
|
spstr strCommand.txt,entn3.txt,"~",74
|
||||||
//f4Icon
|
//f4Icon
|
||||||
spstr strCommand.txt,f4Icon.txt,"~",81
|
spstr strCommand.txt,f4Icon.txt,"~",81
|
||||||
//f4Icon Color
|
//f4Icon Color
|
||||||
spstr strCommand.txt,tTmp.txt,"~",82
|
spstr strCommand.txt,tTmp.txt,"~",82
|
||||||
covx tTmp.txt,f4Icon.pco,0,0
|
covx tTmp.txt,f4Icon.pco,0,0
|
||||||
|
//f4Icon intNameEntity
|
||||||
|
spstr strCommand.txt,entn4.txt,"~",80
|
||||||
//f5Icon
|
//f5Icon
|
||||||
spstr strCommand.txt,f5Icon.txt,"~",87
|
spstr strCommand.txt,f5Icon.txt,"~",87
|
||||||
//f5Icon Color
|
//f5Icon Color
|
||||||
spstr strCommand.txt,tTmp.txt,"~",88
|
spstr strCommand.txt,tTmp.txt,"~",88
|
||||||
covx tTmp.txt,f5Icon.pco,0,0
|
covx tTmp.txt,f5Icon.pco,0,0
|
||||||
|
//f5Icon intNameEntity
|
||||||
|
spstr strCommand.txt,entn5.txt,"~",86
|
||||||
}
|
}
|
||||||
if(tInstruction.txt=="notify")
|
if(tInstruction.txt=="notify")
|
||||||
{
|
{
|
||||||
|
|||||||
BIN
HMI/nspanel.HMI
BIN
HMI/nspanel.HMI
Binary file not shown.
BIN
HMI/nspanel.tft
BIN
HMI/nspanel.tft
Binary file not shown.
@@ -5,7 +5,7 @@ If you like this project consider buying me a pizza 🍕 <a href="https://paypal
|
|||||||
[](https://github.com/hacs/integration)
|
[](https://github.com/hacs/integration)
|
||||||

|

|
||||||
[](https://github.com/joBr99/nspanel-lovelace-ui/releases)
|
[](https://github.com/joBr99/nspanel-lovelace-ui/releases)
|
||||||

|

|
||||||
[](https://github.com/joBr99/nspanel-lovelace-ui/commits/main)
|
[](https://github.com/joBr99/nspanel-lovelace-ui/commits/main)
|
||||||
|
|
||||||
|
|
||||||
@@ -65,3 +65,5 @@ SmartHomeNG: https://github.com/sisamiwe/shng-nspanel-plugin
|
|||||||
OpenHAB: https://github.com/donoo/o2n2l
|
OpenHAB: https://github.com/donoo/o2n2l
|
||||||
|
|
||||||
NodeRed: https://github.com/laluz742/node-red-contrib-nspanel-lui
|
NodeRed: https://github.com/laluz742/node-red-contrib-nspanel-lui
|
||||||
|
|
||||||
|
ESPHome without any Backend: https://github.com/olicooper/esphome-nspanel-lovelace-native
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
ha_api = None
|
ha_api = None
|
||||||
mqtt_api = None
|
mqtt_api = None
|
||||||
|
ad_api = None
|
||||||
@@ -132,6 +132,7 @@ class LuiBackendConfig(object):
|
|||||||
'sleepTrackingZones': ["not_home", "off"],
|
'sleepTrackingZones': ["not_home", "off"],
|
||||||
'sleepOverride': None,
|
'sleepOverride': None,
|
||||||
'locale': "en_US",
|
'locale': "en_US",
|
||||||
|
'quiet': True,
|
||||||
'timeFormat': "%H:%M",
|
'timeFormat': "%H:%M",
|
||||||
'dateFormatBabel': "full",
|
'dateFormatBabel': "full",
|
||||||
'dateAdditionalTemplate': "",
|
'dateAdditionalTemplate': "",
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import datetime
|
|||||||
import apis
|
import apis
|
||||||
from helper import scale, pos_to_color, rgb_dec565
|
from helper import scale, pos_to_color, rgb_dec565
|
||||||
from pages import LuiPagesGen
|
from pages import LuiPagesGen
|
||||||
|
from luibackend.config import Card
|
||||||
|
|
||||||
class LuiController(object):
|
class LuiController(object):
|
||||||
|
|
||||||
@@ -150,7 +151,7 @@ class LuiController(object):
|
|||||||
items = self._config.get_all_entity_names()
|
items = self._config.get_all_entity_names()
|
||||||
apis.ha_api.log(f"gtest123: {items}")
|
apis.ha_api.log(f"gtest123: {items}")
|
||||||
prefixes = ("navigate.", "delete", "iText")
|
prefixes = ("navigate.", "delete", "iText")
|
||||||
items = [x for x in items if not (x is None or x.startswith(prefixes))]
|
items = set([x for x in items if not (x is None or x.startswith(prefixes))])
|
||||||
apis.ha_api.log(f"Registering callbacks for the following items: {items}")
|
apis.ha_api.log(f"Registering callbacks for the following items: {items}")
|
||||||
for item in items:
|
for item in items:
|
||||||
if apis.ha_api.entity_exists(item):
|
if apis.ha_api.entity_exists(item):
|
||||||
@@ -333,6 +334,11 @@ class LuiController(object):
|
|||||||
apis.ha_api.get_entity(entity_id).call_service("return_to_base")
|
apis.ha_api.get_entity(entity_id).call_service("return_to_base")
|
||||||
elif entity_id.startswith('service'):
|
elif entity_id.startswith('service'):
|
||||||
apis.ha_api.call_service(entity_id.replace('service.', '', 1).replace('.','/', 1), **entity_config.data)
|
apis.ha_api.call_service(entity_id.replace('service.', '', 1).replace('.','/', 1), **entity_config.data)
|
||||||
|
elif entity_id.startswith('valve'):
|
||||||
|
if apis.ha_api.get_entity(entity_id).state == "open":
|
||||||
|
apis.ha_api.get_entity(entity_id).call_service("close_valve")
|
||||||
|
else:
|
||||||
|
apis.ha_api.get_entity(entity_id).call_service("open_valve")
|
||||||
|
|
||||||
# for media page
|
# for media page
|
||||||
if button_type == "media-next":
|
if button_type == "media-next":
|
||||||
@@ -347,8 +353,8 @@ class LuiController(object):
|
|||||||
else:
|
else:
|
||||||
apis.ha_api.get_entity(entity_id).call_service("turn_off")
|
apis.ha_api.get_entity(entity_id).call_service("turn_off")
|
||||||
if button_type == "media-shuffle":
|
if button_type == "media-shuffle":
|
||||||
suffle = not apis.ha_api.get_entity(entity_id).attributes.shuffle
|
shuffle = not apis.ha_api.get_entity(entity_id).attributes['shuffle']
|
||||||
apis.ha_api.get_entity(entity_id).call_service("shuffle_set", shuffle=suffle)
|
apis.ha_api.get_entity(entity_id).call_service("shuffle_set", shuffle=shuffle)
|
||||||
if button_type == "volumeSlider":
|
if button_type == "volumeSlider":
|
||||||
pos = int(value)
|
pos = int(value)
|
||||||
# HA wants this value between 0 and 1 as float
|
# HA wants this value between 0 and 1 as float
|
||||||
@@ -365,7 +371,7 @@ class LuiController(object):
|
|||||||
if button_type == "colorTempSlider":
|
if button_type == "colorTempSlider":
|
||||||
entity = apis.ha_api.get_entity(entity_id)
|
entity = apis.ha_api.get_entity(entity_id)
|
||||||
#scale 0-100 from slider to color range of lamp
|
#scale 0-100 from slider to color range of lamp
|
||||||
color_val = scale(int(value), (0, 100), (entity.attributes.min_mireds, entity.attributes.max_mireds))
|
color_val = scale(int(value), (0, 100), (entity.attributes['min_mireds'], entity.attributes['max_mireds']))
|
||||||
apis.ha_api.get_entity(entity_id).call_service("turn_on", color_temp=color_val)
|
apis.ha_api.get_entity(entity_id).call_service("turn_on", color_temp=color_val)
|
||||||
if button_type == "colorWheel":
|
if button_type == "colorWheel":
|
||||||
apis.ha_api.log(value)
|
apis.ha_api.log(value)
|
||||||
@@ -392,9 +398,9 @@ class LuiController(object):
|
|||||||
if button_type == "opnSensorNotify":
|
if button_type == "opnSensorNotify":
|
||||||
msg = ""
|
msg = ""
|
||||||
entity = apis.ha_api.get_entity(entity_id)
|
entity = apis.ha_api.get_entity(entity_id)
|
||||||
if "open_sensors" in entity.attributes and entity.attributes.open_sensors is not None:
|
if open_sensors := entity.attributes.get("open_sensors") is not None:
|
||||||
for e in entity.attributes.open_sensors:
|
for e in open_sensors:
|
||||||
msg += f"- {apis.ha_api.get_entity(e).attributes.friendly_name}\r\n"
|
msg += f"- {apis.ha_api.get_entity(e).attributes['friendly_name']}\r\n"
|
||||||
self._pages_gen.send_message_page("opnSensorNotifyRes", "", msg, "", "")
|
self._pages_gen.send_message_page("opnSensorNotifyRes", "", msg, "", "")
|
||||||
|
|
||||||
# for cardUnlock
|
# for cardUnlock
|
||||||
@@ -411,22 +417,22 @@ class LuiController(object):
|
|||||||
|
|
||||||
if button_type == "mode-preset_modes":
|
if button_type == "mode-preset_modes":
|
||||||
entity = apis.ha_api.get_entity(entity_id)
|
entity = apis.ha_api.get_entity(entity_id)
|
||||||
preset_mode = entity.attributes.preset_modes[int(value)]
|
preset_mode = entity.attributes['preset_modes'][int(value)]
|
||||||
entity.call_service("set_preset_mode", preset_mode=preset_mode)
|
entity.call_service("set_preset_mode", preset_mode=preset_mode)
|
||||||
|
|
||||||
if button_type == "mode-swing_modes":
|
if button_type == "mode-swing_modes":
|
||||||
entity = apis.ha_api.get_entity(entity_id)
|
entity = apis.ha_api.get_entity(entity_id)
|
||||||
swing_mode = entity.attributes.swing_modes[int(value)]
|
swing_mode = entity.attributes['swing_modes'][int(value)]
|
||||||
entity.call_service("set_swing_mode", swing_mode=swing_mode)
|
entity.call_service("set_swing_mode", swing_mode=swing_mode)
|
||||||
|
|
||||||
if button_type == "mode-fan_modes":
|
if button_type == "mode-fan_modes":
|
||||||
entity = apis.ha_api.get_entity(entity_id)
|
entity = apis.ha_api.get_entity(entity_id)
|
||||||
fan_mode = entity.attributes.fan_modes[int(value)]
|
fan_mode = entity.attributes['fan_modes'][int(value)]
|
||||||
entity.call_service("set_fan_mode", fan_mode=fan_mode)
|
entity.call_service("set_fan_mode", fan_mode=fan_mode)
|
||||||
|
|
||||||
if button_type in ["mode-input_select", "mode-select"]:
|
if button_type in ["mode-input_select", "mode-select"]:
|
||||||
entity = apis.ha_api.get_entity(entity_id)
|
entity = apis.ha_api.get_entity(entity_id)
|
||||||
option = entity.attributes.options[int(value)]
|
option = entity.attributes['options'][int(value)]
|
||||||
entity.call_service("select_option", option=option)
|
entity.call_service("select_option", option=option)
|
||||||
|
|
||||||
if button_type == "mode-light":
|
if button_type == "mode-light":
|
||||||
@@ -438,12 +444,12 @@ class LuiController(object):
|
|||||||
if options_list is not None:
|
if options_list is not None:
|
||||||
option = options_list[int(value)]
|
option = options_list[int(value)]
|
||||||
else:
|
else:
|
||||||
option = entity.attributes.effect_list[int(value)]
|
option = entity.attributes['effect_list'][int(value)]
|
||||||
entity.call_service("turn_on", effect=option)
|
entity.call_service("turn_on", effect=option)
|
||||||
|
|
||||||
if button_type == "mode-media_player":
|
if button_type == "mode-media_player":
|
||||||
entity = apis.ha_api.get_entity(entity_id)
|
entity = apis.ha_api.get_entity(entity_id)
|
||||||
option = entity.attributes.source_list[int(value)]
|
option = entity.attributes['source_list'][int(value)]
|
||||||
entity.call_service("select_source", source=option)
|
entity.call_service("select_source", source=option)
|
||||||
|
|
||||||
# timer detail page
|
# timer detail page
|
||||||
@@ -458,3 +464,9 @@ class LuiController(object):
|
|||||||
apis.ha_api.get_entity(entity_id).call_service("pause")
|
apis.ha_api.get_entity(entity_id).call_service("pause")
|
||||||
if button_type == "timer-finish":
|
if button_type == "timer-finish":
|
||||||
apis.ha_api.get_entity(entity_id).call_service("finish")
|
apis.ha_api.get_entity(entity_id).call_service("finish")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_card(self) -> Card:
|
||||||
|
"""Used to get the current card"""
|
||||||
|
|
||||||
|
return self._current_card
|
||||||
|
|||||||
@@ -159,8 +159,8 @@ alarm_control_panel_mapping = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
climate_mapping = {
|
climate_mapping = {
|
||||||
'auto': 'calendar-sync',
|
'auto': 'fan-auto',
|
||||||
'heat_cool': 'calendar-sync',
|
'heat_cool': 'sun-snowflake-variant',
|
||||||
'heat': 'fire',
|
'heat': 'fire',
|
||||||
'off': 'power',
|
'off': 'power',
|
||||||
'cool': 'snowflake',
|
'cool': 'snowflake',
|
||||||
@@ -213,6 +213,9 @@ def get_icon_ha(entity_id, overwrite=None, stateOverwrite=None):
|
|||||||
entity = apis.ha_api.get_entity(entity_id)
|
entity = apis.ha_api.get_entity(entity_id)
|
||||||
state = entity.state if stateOverwrite is None else stateOverwrite
|
state = entity.state if stateOverwrite is None else stateOverwrite
|
||||||
|
|
||||||
|
if entity_id in ["sensor.weather_forecast_daily", "sensor.weather_forecast_hourly"]:
|
||||||
|
ha_type = "weather"
|
||||||
|
|
||||||
if overwrite is not None:
|
if overwrite is not None:
|
||||||
if type(overwrite) is str:
|
if type(overwrite) is str:
|
||||||
return get_icon_char(overwrite)
|
return get_icon_char(overwrite)
|
||||||
@@ -263,8 +266,8 @@ def get_icon_ha(entity_id, overwrite=None, stateOverwrite=None):
|
|||||||
# based on media_content_type
|
# based on media_content_type
|
||||||
elif ha_type == "media_player":
|
elif ha_type == "media_player":
|
||||||
result_icon = "speaker-off"
|
result_icon = "speaker-off"
|
||||||
if "media_content_type" in entity.attributes:
|
if media_content_type := entity.attributes.get("media_content_type"):
|
||||||
if entity.attributes.media_content_type in media_content_type_mapping:
|
if media_content_type in media_content_type_mapping:
|
||||||
result_icon = media_content_type_mapping[entity.attributes.media_content_type]
|
result_icon = media_content_type_mapping[media_content_type]
|
||||||
|
|
||||||
return get_icon_char(result_icon)
|
return get_icon_char(result_icon)
|
||||||
|
|||||||
@@ -77,12 +77,13 @@ class LuiMqttListener(object):
|
|||||||
self._controller.detail_open(msg[2], msg[3])
|
self._controller.detail_open(msg[2], msg[3])
|
||||||
|
|
||||||
class LuiMqttSender(object):
|
class LuiMqttSender(object):
|
||||||
def __init__(self, api, use_api, topic_send, api_panel_name):
|
def __init__(self, api, use_api, topic_send, api_panel_name, quiet):
|
||||||
self._ha_api = api
|
self._ha_api = api
|
||||||
self._use_api = use_api
|
self._use_api = use_api
|
||||||
self._topic_send = topic_send
|
self._topic_send = topic_send
|
||||||
self._api_panel_name = api_panel_name
|
self._api_panel_name = api_panel_name
|
||||||
self._prev_msg = ""
|
self._prev_msg = ""
|
||||||
|
self._quiet = quiet
|
||||||
|
|
||||||
def send_mqtt_msg(self, msg, topic=None, force=False):
|
def send_mqtt_msg(self, msg, topic=None, force=False):
|
||||||
if not force and self._prev_msg == msg:
|
if not force and self._prev_msg == msg:
|
||||||
@@ -90,7 +91,9 @@ class LuiMqttSender(object):
|
|||||||
return
|
return
|
||||||
self._prev_msg = msg
|
self._prev_msg = msg
|
||||||
|
|
||||||
apis.ha_api.log(f"Sending Message: {msg}")
|
if self._quiet is False:
|
||||||
|
apis.ha_api.log(f"Sending Message: {msg}")
|
||||||
|
|
||||||
if self._use_api:
|
if self._use_api:
|
||||||
apis.ha_api.call_service(service="esphome/" + self._api_panel_name + "_nspanelui_api_call", command=2, data=msg)
|
apis.ha_api.call_service(service="esphome/" + self._api_panel_name + "_nspanelui_api_call", command=2, data=msg)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class LuiPagesGen(object):
|
|||||||
self._config = config
|
self._config = config
|
||||||
self._locale = config.get("locale")
|
self._locale = config.get("locale")
|
||||||
self._send_mqtt_msg = send_mqtt_msg
|
self._send_mqtt_msg = send_mqtt_msg
|
||||||
|
|
||||||
def get_entity_color(self, entity, ha_type=None, stateOverwrite=None, overwrite=None):
|
def get_entity_color(self, entity, ha_type=None, stateOverwrite=None, overwrite=None):
|
||||||
if overwrite is not None:
|
if overwrite is not None:
|
||||||
if type(overwrite) in [str, list]:
|
if type(overwrite) in [str, list]:
|
||||||
@@ -82,7 +82,7 @@ class LuiPagesGen(object):
|
|||||||
icon_color = 63878 #red
|
icon_color = 63878 #red
|
||||||
if state == "fog":
|
if state == "fog":
|
||||||
icon_color = 38066 #75% grey
|
icon_color = 38066 #75% grey
|
||||||
if state in ["hail", "snowy"]:
|
if state in ["hail", "snowy"]:
|
||||||
icon_color = 65535 #white
|
icon_color = 65535 #white
|
||||||
if state == "lightning":
|
if state == "lightning":
|
||||||
icon_color = 65120 #golden-yellow
|
icon_color = 65120 #golden-yellow
|
||||||
@@ -97,13 +97,12 @@ class LuiPagesGen(object):
|
|||||||
if state == "sunny":
|
if state == "sunny":
|
||||||
icon_color = 65504 #bright-yellow
|
icon_color = 65504 #bright-yellow
|
||||||
|
|
||||||
if "rgb_color" in attr and attr.rgb_color:
|
if color := attr.get("rgb_color"):
|
||||||
color = attr.rgb_color
|
if brightness := attr.get("brightness"):
|
||||||
if "brightness" in attr and attr.brightness:
|
color = rgb_brightness(color, brightness)
|
||||||
color = rgb_brightness(color, attr.brightness)
|
|
||||||
icon_color = rgb_dec565(color)
|
icon_color = rgb_dec565(color)
|
||||||
elif "brightness" in attr and attr.brightness:
|
elif brightness := attr.get("brightness"):
|
||||||
color = rgb_brightness([253, 216, 53], attr.brightness)
|
color = rgb_brightness([253, 216, 53], brightness)
|
||||||
icon_color = rgb_dec565(color)
|
icon_color = rgb_dec565(color)
|
||||||
return icon_color
|
return icon_color
|
||||||
|
|
||||||
@@ -129,7 +128,7 @@ class LuiPagesGen(object):
|
|||||||
else:
|
else:
|
||||||
dateformat = self._config.get("dateFormat")
|
dateformat = self._config.get("dateFormat")
|
||||||
date = datetime.datetime.now().strftime(dateformat)
|
date = datetime.datetime.now().strftime(dateformat)
|
||||||
|
|
||||||
addTemplate = self._config.get("dateAdditionalTemplate")
|
addTemplate = self._config.get("dateAdditionalTemplate")
|
||||||
addDateText = apis.ha_api.render_template(addTemplate)
|
addDateText = apis.ha_api.render_template(addTemplate)
|
||||||
self._send_mqtt_msg(f"date~{date}{addDateText}")
|
self._send_mqtt_msg(f"date~{date}{addDateText}")
|
||||||
@@ -138,7 +137,7 @@ class LuiPagesGen(object):
|
|||||||
if target_page == "cardUnlock":
|
if target_page == "cardUnlock":
|
||||||
target_page = "cardAlarm"
|
target_page = "cardAlarm"
|
||||||
self._send_mqtt_msg(f"pageType~{target_page}")
|
self._send_mqtt_msg(f"pageType~{target_page}")
|
||||||
|
|
||||||
def update_screensaver_weather(self, theme):
|
def update_screensaver_weather(self, theme):
|
||||||
entities = self._config._config_screensaver.entities
|
entities = self._config._config_screensaver.entities
|
||||||
|
|
||||||
@@ -151,7 +150,7 @@ class LuiPagesGen(object):
|
|||||||
item_str = ""
|
item_str = ""
|
||||||
for item in entities:
|
for item in entities:
|
||||||
item_str += self.generate_entities_item(item, "cardEntities", mask=["type", "entityId"])
|
item_str += self.generate_entities_item(item, "cardEntities", mask=["type", "entityId"])
|
||||||
|
|
||||||
self._send_mqtt_msg(f"weatherUpdate{item_str}")
|
self._send_mqtt_msg(f"weatherUpdate{item_str}")
|
||||||
# send color if configured in screensaver
|
# send color if configured in screensaver
|
||||||
if theme is not None:
|
if theme is not None:
|
||||||
@@ -181,17 +180,20 @@ class LuiPagesGen(object):
|
|||||||
colorOverride = item.colorOverride
|
colorOverride = item.colorOverride
|
||||||
name = item.nameOverride
|
name = item.nameOverride
|
||||||
uuid = item.uuid
|
uuid = item.uuid
|
||||||
|
|
||||||
# check ha template for name
|
# check ha template for name
|
||||||
if item.nameOverride is not None and ("{" in item.nameOverride and "}" in item.nameOverride):
|
if item.nameOverride is not None and ("{" in item.nameOverride and "}" in item.nameOverride):
|
||||||
name = apis.ha_api.render_template(item.nameOverride)
|
name = apis.ha_api.render_template(item.nameOverride)
|
||||||
|
|
||||||
# type of the item is the string before the "." in the entityId
|
# type of the item is the string before the "." in the entityId
|
||||||
if entityId is not None:
|
if entityId is not None:
|
||||||
entityType = entityId.split(".")[0]
|
entityType = entityId.split(".")[0]
|
||||||
else:
|
else:
|
||||||
entityType = "delete"
|
entityType = "delete"
|
||||||
|
|
||||||
|
if entityId in ["sensor.weather_forecast_daily", "sensor.weather_forecast_hourly"]:
|
||||||
|
entityType = "weather"
|
||||||
|
|
||||||
apis.ha_api.log(f"Generating item for {entityId} with type {entityType}", level="DEBUG")
|
apis.ha_api.log(f"Generating item for {entityId} with type {entityType}", level="DEBUG")
|
||||||
|
|
||||||
status_entity = apis.ha_api.get_entity(item.status) if item.status and apis.ha_api.entity_exists(item.status) else None
|
status_entity = apis.ha_api.get_entity(item.status) if item.status and apis.ha_api.entity_exists(item.status) else None
|
||||||
@@ -221,7 +223,7 @@ class LuiPagesGen(object):
|
|||||||
if status_entity:
|
if status_entity:
|
||||||
icon_res = get_icon_ha(item.status, overwrite=icon)
|
icon_res = get_icon_ha(item.status, overwrite=icon)
|
||||||
icon_color = self.get_entity_color(status_entity, ha_type=item.status.split(".")[0], overwrite=colorOverride)
|
icon_color = self.get_entity_color(status_entity, ha_type=item.status.split(".")[0], overwrite=colorOverride)
|
||||||
if item.status.startswith("sensor") and (cardType == "cardGrid" or cardType == "cardGrid2") and item.iconOverride is None:
|
if item.status.startswith("sensor") and cardType in ["cardGrid", "cardGrid1", "cardGrid2"] and item.iconOverride is None:
|
||||||
icon_res = status_entity.state[:4]
|
icon_res = status_entity.state[:4]
|
||||||
if icon_res[-1] == ".":
|
if icon_res[-1] == ".":
|
||||||
icon_res = icon_res[:-1]
|
icon_res = icon_res[:-1]
|
||||||
@@ -245,7 +247,7 @@ class LuiPagesGen(object):
|
|||||||
if status_entity:
|
if status_entity:
|
||||||
icon_id = get_icon_ha(item.status, overwrite=icon)
|
icon_id = get_icon_ha(item.status, overwrite=icon)
|
||||||
icon_color = self.get_entity_color(status_entity, ha_type=item.status.split(".")[0], overwrite=colorOverride)
|
icon_color = self.get_entity_color(status_entity, ha_type=item.status.split(".")[0], overwrite=colorOverride)
|
||||||
if item.status.startswith("sensor") and (cardType == "cardGrid" or cardType == "cardGrid2") and item.iconOverride is None:
|
if item.status.startswith("sensor") and cardType in ["cardGrid", "cardGrid1", "cardGrid2"] and item.iconOverride is None:
|
||||||
icon_id = status_entity.state[:4]
|
icon_id = status_entity.state[:4]
|
||||||
if icon_id[-1] == ".":
|
if icon_id[-1] == ".":
|
||||||
icon_id = icon_id[:-1]
|
icon_id = icon_id[:-1]
|
||||||
@@ -254,7 +256,7 @@ class LuiPagesGen(object):
|
|||||||
if entity is None:
|
if entity is None:
|
||||||
return f"~text~{entityId}~{get_icon_id('alert-circle-outline')}~17299~Not found check~ apps.yaml"
|
return f"~text~{entityId}~{get_icon_id('alert-circle-outline')}~17299~Not found check~ apps.yaml"
|
||||||
|
|
||||||
|
|
||||||
# HA Entities
|
# HA Entities
|
||||||
# common res vars
|
# common res vars
|
||||||
entityTypePanel = "text"
|
entityTypePanel = "text"
|
||||||
@@ -273,7 +275,7 @@ class LuiPagesGen(object):
|
|||||||
icon_up_status = "disable"
|
icon_up_status = "disable"
|
||||||
icon_stop_status = "disable"
|
icon_stop_status = "disable"
|
||||||
icon_down_status = "disable"
|
icon_down_status = "disable"
|
||||||
bits = entity.attributes.supported_features
|
bits = entity.attributes.get('supported_features')
|
||||||
pos = entity.attributes.get("current_position")
|
pos = entity.attributes.get("current_position")
|
||||||
if pos is None:
|
if pos is None:
|
||||||
pos_status = entity.state
|
pos_status = entity.state
|
||||||
@@ -306,19 +308,24 @@ class LuiPagesGen(object):
|
|||||||
device_class = entity.attributes.get("device_class", "")
|
device_class = entity.attributes.get("device_class", "")
|
||||||
unit_of_measurement = entity.attributes.get("unit_of_measurement", "")
|
unit_of_measurement = entity.attributes.get("unit_of_measurement", "")
|
||||||
value = entity.state
|
value = entity.state
|
||||||
|
|
||||||
|
try:
|
||||||
|
value = str(round(float(value), 1))
|
||||||
|
except:
|
||||||
|
print("An exception occurred")
|
||||||
|
|
||||||
# limit value to 4 chars on us-p
|
# limit value to 4 chars on us-p
|
||||||
if self._config.get("model") == "us-p" and cardType == "cardEntities":
|
if self._config.get("model") == "us-p" and cardType == "cardEntities":
|
||||||
value = entity.state[:4]
|
value = entity.state[:4]
|
||||||
if value[-1] == ".":
|
if value[-1] == ".":
|
||||||
value = value[:-1]
|
value = value[:-1]
|
||||||
|
|
||||||
if device_class != "temperature":
|
if device_class != "temperature":
|
||||||
value = value + " "
|
value = value + " "
|
||||||
value = value + unit_of_measurement
|
value = value + unit_of_measurement
|
||||||
if entityType == "binary_sensor":
|
if entityType == "binary_sensor":
|
||||||
value = get_translation(self._locale, f"backend.component.binary_sensor.state.{device_class}.{entity.state}")
|
value = get_translation(self._locale, f"backend.component.binary_sensor.state.{device_class}.{entity.state}")
|
||||||
if (cardType == "cardGrid" or cardType == "cardGrid2") and entityType == "sensor" and icon is None:
|
if cardType in ["cardGrid", "cardGrid1", "cardGrid2"] and entityType == "sensor" and icon is None:
|
||||||
icon_id = entity.state[:4]
|
icon_id = entity.state[:4]
|
||||||
if icon_id[-1] == ".":
|
if icon_id[-1] == ".":
|
||||||
icon_id = icon_id[:-1]
|
icon_id = icon_id[:-1]
|
||||||
@@ -380,20 +387,51 @@ class LuiPagesGen(object):
|
|||||||
elif entityType == "weather":
|
elif entityType == "weather":
|
||||||
entityTypePanel = "text"
|
entityTypePanel = "text"
|
||||||
unit = get_attr_safe(entity, "temperature_unit", "")
|
unit = get_attr_safe(entity, "temperature_unit", "")
|
||||||
if type(item.stype) == int and len(entity.attributes.forecast) >= item.stype:
|
rt = None
|
||||||
fdate = dp.parse(entity.attributes.forecast[item.stype]['datetime'])
|
index = item.stype
|
||||||
global babel_spec
|
if type(item.stype) == str and ":" in item.stype and len(item.stype.split(":")) == 2:
|
||||||
if babel_spec is not None:
|
spintstr = item.stype.split(":")
|
||||||
dateformat = "E" if item.nameOverride is None else item.nameOverride
|
rt = spintstr[0]
|
||||||
name = babel.dates.format_datetime(fdate.astimezone(), dateformat, locale=self._locale)
|
index = int(spintstr[1])
|
||||||
|
if type(index) == int:
|
||||||
|
bits = get_attr_safe(entity, "supported_features", 0b0)
|
||||||
|
if not rt:
|
||||||
|
rt = "daily"
|
||||||
|
if bits & 0b001: #FORECAST_DAILY
|
||||||
|
rt = "daily"
|
||||||
|
elif bits & 0b010: #FORECAST_HOURLY
|
||||||
|
rt = "hourly"
|
||||||
|
elif bits & 0b100: #FORECAST_TWICE_DAILY
|
||||||
|
rt = "twice_daily"
|
||||||
|
|
||||||
|
results = apis.ha_api.call_service(
|
||||||
|
"weather/get_forecasts", target={"entity_id": entityId}, service_data={"type": rt}
|
||||||
|
)
|
||||||
|
forecast = results.get("result", {}).get("response", {}).get(entityId, {}).get('forecast') or entity.attributes.get('forecast', [])
|
||||||
|
if len(forecast) >= index:
|
||||||
|
day_forecast = forecast[index]
|
||||||
|
fdate = dp.parse(day_forecast['datetime'])
|
||||||
|
global babel_spec
|
||||||
|
if babel_spec is not None:
|
||||||
|
dateformat = "E" if item.nameOverride is None else item.nameOverride
|
||||||
|
name = babel.dates.format_datetime(fdate.astimezone(), dateformat, locale=self._locale)
|
||||||
|
else:
|
||||||
|
dateformat = "%a" if item.nameOverride is None else item.nameOverride
|
||||||
|
name = fdate.astimezone().strftime(dateformat)
|
||||||
|
icon_id = get_icon_ha(entityId, stateOverwrite=day_forecast['condition'])
|
||||||
|
value = f'{day_forecast.get("temperature", "")}{unit}'
|
||||||
|
color = self.get_entity_color(entity, ha_type=entityType, stateOverwrite=day_forecast['condition'], overwrite=colorOverride)
|
||||||
else:
|
else:
|
||||||
dateformat = "%a" if item.nameOverride is None else item.nameOverride
|
value = f'{get_attr_safe(entity, "temperature", "")}{unit}'
|
||||||
name = fdate.astimezone().strftime(dateformat)
|
|
||||||
icon_id = get_icon_ha(entityId, stateOverwrite=entity.attributes.forecast[item.stype]['condition'])
|
|
||||||
value = f'{entity.attributes.forecast[item.stype].get("temperature", "")}{unit}'
|
|
||||||
color = self.get_entity_color(entity, ha_type=entityType, stateOverwrite=entity.attributes.forecast[item.stype]['condition'], overwrite=colorOverride)
|
|
||||||
else:
|
else:
|
||||||
value = f'{get_attr_safe(entity, "temperature", "")}{unit}'
|
value = f'{get_attr_safe(entity, "temperature", "")}{unit}'
|
||||||
|
elif entityType == "valve":
|
||||||
|
entityTypePanel = "valve"
|
||||||
|
value = get_translation(self._locale, f"backend.component.binary_sensor.state.door.{entity.state}")
|
||||||
|
if entity.state == "open":
|
||||||
|
icon_id = get_icon_id("valve-open")
|
||||||
|
else:
|
||||||
|
icon_id = get_icon_id("valve-closed")
|
||||||
else:
|
else:
|
||||||
name = "unsupported"
|
name = "unsupported"
|
||||||
# Overwrite for value
|
# Overwrite for value
|
||||||
@@ -452,7 +490,7 @@ class LuiPagesGen(object):
|
|||||||
command = f"entityUpd~Not found~{navigation}~{item}~check~220~apps.yaml~150~300~5~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Please~your~~"
|
command = f"entityUpd~Not found~{navigation}~{item}~check~220~apps.yaml~150~300~5~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Please~your~~"
|
||||||
else:
|
else:
|
||||||
entity = apis.ha_api.get_entity(item)
|
entity = apis.ha_api.get_entity(item)
|
||||||
heading = title if title != "unknown" else entity.attributes.friendly_name
|
heading = title if title != "unknown" else entity.attributes['friendly_name']
|
||||||
current_temp = get_attr_safe(entity, "current_temperature", "")
|
current_temp = get_attr_safe(entity, "current_temperature", "")
|
||||||
dest_temp = get_attr_safe(entity, "temperature", None)
|
dest_temp = get_attr_safe(entity, "temperature", None)
|
||||||
dest_temp2 = ""
|
dest_temp2 = ""
|
||||||
@@ -473,10 +511,10 @@ class LuiPagesGen(object):
|
|||||||
state_value += get_translation(self._locale, f"backend.component.climate.state._.{entity.state}")
|
state_value += get_translation(self._locale, f"backend.component.climate.state._.{entity.state}")
|
||||||
if hvac_action != "":
|
if hvac_action != "":
|
||||||
state_value += ")"
|
state_value += ")"
|
||||||
|
|
||||||
min_temp = int(get_attr_safe(entity, "min_temp", 0)*10)
|
min_temp = int(get_attr_safe(entity, "min_temp", 0)*10)
|
||||||
max_temp = int(get_attr_safe(entity, "max_temp", 0)*10)
|
max_temp = int(get_attr_safe(entity, "max_temp", 0)*10)
|
||||||
step_temp = int(get_attr_safe(entity, "target_temp_step", 0.5)*10)
|
step_temp = int(get_attr_safe(entity, "target_temp_step", 0.5)*10)
|
||||||
icon_res_list = []
|
icon_res_list = []
|
||||||
icon_res = ""
|
icon_res = ""
|
||||||
|
|
||||||
@@ -501,7 +539,7 @@ class LuiPagesGen(object):
|
|||||||
state = 0
|
state = 0
|
||||||
if(mode == entity.state):
|
if(mode == entity.state):
|
||||||
state = 1
|
state = 1
|
||||||
|
|
||||||
icon_res_list.append(f"~{icon_id}~{color_on}~{state}~{mode}")
|
icon_res_list.append(f"~{icon_id}~{color_on}~{state}~{mode}")
|
||||||
|
|
||||||
icon_res = "".join(icon_res_list)
|
icon_res = "".join(icon_res_list)
|
||||||
@@ -516,11 +554,11 @@ class LuiPagesGen(object):
|
|||||||
icon_res = "~"*4 + icon_res_list[0] + "~"*4 + icon_res_list[1] + "~"*4 + icon_res_list[2] + "~"*4 + icon_res_list[3]
|
icon_res = "~"*4 + icon_res_list[0] + "~"*4 + icon_res_list[1] + "~"*4 + icon_res_list[2] + "~"*4 + icon_res_list[3]
|
||||||
elif len(icon_res_list) >= 5 or self._config.get("model") == "us-p":
|
elif len(icon_res_list) >= 5 or self._config.get("model") == "us-p":
|
||||||
icon_res = "".join(icon_res_list) + "~"*4*(8-len(icon_res_list))
|
icon_res = "".join(icon_res_list) + "~"*4*(8-len(icon_res_list))
|
||||||
|
|
||||||
currently_translation = get_translation(self._locale, "frontend.ui.card.climate.currently")
|
currently_translation = get_translation(self._locale, "frontend.ui.card.climate.currently")
|
||||||
state_translation = get_translation(self._locale, "frontend.ui.panel.config.devices.entities.state")
|
state_translation = get_translation(self._locale, "frontend.ui.panel.config.devices.entities.state")
|
||||||
action_translation = get_translation(self._locale, "frontend.ui.card.climate.operation").replace(' ','\r\n')
|
action_translation = get_translation(self._locale, "frontend.ui.card.climate.operation").replace(' ','\r\n')
|
||||||
|
|
||||||
detailPage = "1"
|
detailPage = "1"
|
||||||
if any(x in ["preset_modes", "swing_modes", "fan_modes"] for x in entity.attributes):
|
if any(x in ["preset_modes", "swing_modes", "fan_modes"] for x in entity.attributes):
|
||||||
detailPage = "0"
|
detailPage = "0"
|
||||||
@@ -534,7 +572,7 @@ class LuiPagesGen(object):
|
|||||||
command = f"entityUpd~Not found~{navigation}"
|
command = f"entityUpd~Not found~{navigation}"
|
||||||
else:
|
else:
|
||||||
entity = apis.ha_api.get_entity(item)
|
entity = apis.ha_api.get_entity(item)
|
||||||
heading = title if title != "unknown" else entity.attributes.friendly_name
|
heading = title if title != "unknown" else entity.attributes['friendly_name']
|
||||||
|
|
||||||
# get data from homeassistant
|
# get data from homeassistant
|
||||||
data_raw = apis.ha_api.get_history(entity_id = item, days = 7)
|
data_raw = apis.ha_api.get_history(entity_id = item, days = 7)
|
||||||
@@ -581,12 +619,12 @@ class LuiPagesGen(object):
|
|||||||
else:
|
else:
|
||||||
media_icon = self.generate_entities_item(entity, "cardGrid")
|
media_icon = self.generate_entities_item(entity, "cardGrid")
|
||||||
ha_entity = apis.ha_api.get_entity(entityId)
|
ha_entity = apis.ha_api.get_entity(entityId)
|
||||||
heading = title if title != "unknown" else ha_entity.attributes.friendly_name
|
heading = title if title != "unknown" else ha_entity.attributes['friendly_name']
|
||||||
title = get_attr_safe(ha_entity, "media_title", "")
|
title = get_attr_safe(ha_entity, "media_title", "")
|
||||||
author = get_attr_safe(ha_entity, "media_artist", "")
|
author = get_attr_safe(ha_entity, "media_artist", "")
|
||||||
volume = int(get_attr_safe(ha_entity, "volume_level", 0)*100)
|
volume = int(get_attr_safe(ha_entity, "volume_level", 0)*100)
|
||||||
iconplaypause = get_icon_id("pause") if ha_entity.state == "playing" else get_icon_id("play")
|
iconplaypause = get_icon_id("pause") if ha_entity.state == "playing" else get_icon_id("play")
|
||||||
bits = ha_entity.attributes.supported_features
|
bits = ha_entity.attributes['supported_features']
|
||||||
onoffbutton = "disable"
|
onoffbutton = "disable"
|
||||||
if bits & 0b10000000:
|
if bits & 0b10000000:
|
||||||
if ha_entity.state == "off":
|
if ha_entity.state == "off":
|
||||||
@@ -604,7 +642,7 @@ class LuiPagesGen(object):
|
|||||||
item_str = ""
|
item_str = ""
|
||||||
for item in entities:
|
for item in entities:
|
||||||
item_str += self.generate_entities_item(item, "cardGrid")
|
item_str += self.generate_entities_item(item, "cardGrid")
|
||||||
|
|
||||||
bck_override = entity.iconOverride
|
bck_override = entity.iconOverride
|
||||||
if entity.status is not None:
|
if entity.status is not None:
|
||||||
bck_entity = entity.entityId
|
bck_entity = entity.entityId
|
||||||
@@ -612,14 +650,14 @@ class LuiPagesGen(object):
|
|||||||
|
|
||||||
entity.iconOverride = "mdi:speaker"
|
entity.iconOverride = "mdi:speaker"
|
||||||
item_str += self.generate_entities_item(entity, "cardGrid")
|
item_str += self.generate_entities_item(entity, "cardGrid")
|
||||||
|
|
||||||
entity.iconOverride = bck_override
|
entity.iconOverride = bck_override
|
||||||
if entity.status is not None:
|
if entity.status is not None:
|
||||||
entity.entityId = bck_entity
|
entity.entityId = bck_entity
|
||||||
|
|
||||||
command = f"entityUpd~{heading}~{navigation}~{entityId}~{title}~~{author}~~{volume}~{iconplaypause}~{onoffbutton}~{shuffleBtn}{media_icon}{item_str}"
|
command = f"entityUpd~{heading}~{navigation}~{entityId}~{title}~~{author}~~{volume}~{iconplaypause}~{onoffbutton}~{shuffleBtn}{media_icon}{item_str}"
|
||||||
self._send_mqtt_msg(command)
|
self._send_mqtt_msg(command)
|
||||||
|
|
||||||
def generate_alarm_page(self, navigation, title, entity, overwrite_supported_modes, alarmBtn):
|
def generate_alarm_page(self, navigation, title, entity, overwrite_supported_modes, alarmBtn):
|
||||||
item = entity.entityId
|
item = entity.entityId
|
||||||
if not apis.ha_api.entity_exists(item):
|
if not apis.ha_api.entity_exists(item):
|
||||||
@@ -636,7 +674,7 @@ class LuiPagesGen(object):
|
|||||||
if not entity.attributes.get("code_arm_required", False):
|
if not entity.attributes.get("code_arm_required", False):
|
||||||
numpad = "disable"
|
numpad = "disable"
|
||||||
if overwrite_supported_modes is None:
|
if overwrite_supported_modes is None:
|
||||||
bits = entity.attributes.supported_features
|
bits = entity.attributes['supported_features']
|
||||||
if bits & 0b000001:
|
if bits & 0b000001:
|
||||||
supported_modes.append("arm_home")
|
supported_modes.append("arm_home")
|
||||||
if bits & 0b000010:
|
if bits & 0b000010:
|
||||||
@@ -675,7 +713,7 @@ class LuiPagesGen(object):
|
|||||||
|
|
||||||
#add button to show sensor state
|
#add button to show sensor state
|
||||||
add_btn = ""
|
add_btn = ""
|
||||||
if "open_sensors" in entity.attributes and entity.attributes.open_sensors is not None:
|
if entity.attributes.get("open_sensors") is not None:
|
||||||
add_btn=f"{get_icon_id('progress-alert')}~{rgb_dec565([243,179,0])}~"
|
add_btn=f"{get_icon_id('progress-alert')}~{rgb_dec565([243,179,0])}~"
|
||||||
if alarmBtn is not None and type(alarmBtn) is dict:
|
if alarmBtn is not None and type(alarmBtn) is dict:
|
||||||
entity = alarmBtn.get("entity")
|
entity = alarmBtn.get("entity")
|
||||||
@@ -686,8 +724,8 @@ class LuiPagesGen(object):
|
|||||||
else:
|
else:
|
||||||
icon_color = rgb_dec565([243,179,0])
|
icon_color = rgb_dec565([243,179,0])
|
||||||
add_btn=f"{iconnav}~{icon_color}~{entity}"
|
add_btn=f"{iconnav}~{icon_color}~{entity}"
|
||||||
|
|
||||||
|
|
||||||
# add padding to arm buttons
|
# add padding to arm buttons
|
||||||
arm_buttons = ""
|
arm_buttons = ""
|
||||||
for b in supported_modes:
|
for b in supported_modes:
|
||||||
@@ -697,12 +735,12 @@ class LuiPagesGen(object):
|
|||||||
arm_buttons += "~"*((4-len(supported_modes))*2)
|
arm_buttons += "~"*((4-len(supported_modes))*2)
|
||||||
command = f"entityUpd~{title}~{navigation}~{item}{arm_buttons}~{icon}~{color}~{numpad}~{flashing}~{add_btn}"
|
command = f"entityUpd~{title}~{navigation}~{item}{arm_buttons}~{icon}~{color}~{numpad}~{flashing}~{add_btn}"
|
||||||
self._send_mqtt_msg(command)
|
self._send_mqtt_msg(command)
|
||||||
|
|
||||||
def generate_unlock_page(self, navigation, item, title, destination, pin):
|
def generate_unlock_page(self, navigation, item, title, destination, pin):
|
||||||
color = rgb_dec565([255,0,0])
|
color = rgb_dec565([255,0,0])
|
||||||
icon = get_icon_id("lock")
|
icon = get_icon_id("lock")
|
||||||
supported_modes = ["cardUnlock-unlock"]
|
supported_modes = ["cardUnlock-unlock"]
|
||||||
|
|
||||||
# add padding to arm buttons
|
# add padding to arm buttons
|
||||||
arm_buttons = ""
|
arm_buttons = ""
|
||||||
for b in supported_modes:
|
for b in supported_modes:
|
||||||
@@ -741,8 +779,8 @@ class LuiPagesGen(object):
|
|||||||
if (time.time()-card.last_update) < card.cooldown:
|
if (time.time()-card.last_update) < card.cooldown:
|
||||||
return
|
return
|
||||||
card.last_update = time.time()
|
card.last_update = time.time()
|
||||||
|
|
||||||
|
|
||||||
leftBtn = "delete~~~~~"
|
leftBtn = "delete~~~~~"
|
||||||
if card.uuid_prev is not None:
|
if card.uuid_prev is not None:
|
||||||
leftBtn = self.generate_entities_item(Entity(
|
leftBtn = self.generate_entities_item(Entity(
|
||||||
@@ -779,6 +817,8 @@ class LuiPagesGen(object):
|
|||||||
if send_page_type:
|
if send_page_type:
|
||||||
if card.cardType == "cardGrid" and len(card.entities) > 6:
|
if card.cardType == "cardGrid" and len(card.entities) > 6:
|
||||||
card.cardType = "cardGrid2"
|
card.cardType = "cardGrid2"
|
||||||
|
if card.cardType == "cardGrid1":
|
||||||
|
card.cardType = "cardGrid"
|
||||||
self.page_type(card.cardType)
|
self.page_type(card.cardType)
|
||||||
|
|
||||||
# send sleep timeout if there is one configured for the current card
|
# send sleep timeout if there is one configured for the current card
|
||||||
@@ -786,9 +826,9 @@ class LuiPagesGen(object):
|
|||||||
self._send_mqtt_msg(f"timeout~{card.sleepTimeout}")
|
self._send_mqtt_msg(f"timeout~{card.sleepTimeout}")
|
||||||
else:
|
else:
|
||||||
self._send_mqtt_msg(f'timeout~{self._config.get("sleepTimeout")}')
|
self._send_mqtt_msg(f'timeout~{self._config.get("sleepTimeout")}')
|
||||||
|
|
||||||
temp_unit = card.raw_config.get("temperatureUnit", "celsius")
|
temp_unit = card.raw_config.get("temperatureUnit", "celsius")
|
||||||
if card.cardType in ["cardEntities", "cardGrid", "cardGrid2"]:
|
if card.cardType in ["cardEntities", "cardGrid", "cardGrid1","cardGrid2"]:
|
||||||
self.generate_entities_page(navigation, card.title, card.entities, card.cardType, temp_unit)
|
self.generate_entities_page(navigation, card.title, card.entities, card.cardType, temp_unit)
|
||||||
return
|
return
|
||||||
if card.cardType == "cardThermo":
|
if card.cardType == "cardThermo":
|
||||||
@@ -840,25 +880,26 @@ class LuiPagesGen(object):
|
|||||||
color_temp = "disable"
|
color_temp = "disable"
|
||||||
color = "disable"
|
color = "disable"
|
||||||
effect_supported = "disable"
|
effect_supported = "disable"
|
||||||
|
supported_color_modes = entity.attributes['supported_color_modes']
|
||||||
if "onoff" not in entity.attributes.supported_color_modes:
|
|
||||||
|
if "onoff" not in supported_color_modes:
|
||||||
brightness = 0
|
brightness = 0
|
||||||
if entity.state == "on":
|
if entity.state == "on":
|
||||||
if "brightness" in entity.attributes and entity.attributes.brightness:
|
if brightness := entity.attributes.get("brightness"):
|
||||||
# scale 0-255 brightness from ha to 0-100
|
# scale 0-255 brightness from ha to 0-100
|
||||||
brightness = int(scale(entity.attributes.brightness,(0,255),(0,100)))
|
brightness = int(scale(brightness, (0,255), (0,100)))
|
||||||
else:
|
else:
|
||||||
brightness = "disable"
|
brightness = "disable"
|
||||||
if "color_temp" in entity.attributes.supported_color_modes and entity.attributes.supported_color_modes:
|
if "color_temp" in supported_color_modes:
|
||||||
if "color_temp" in entity.attributes and entity.attributes.color_temp:
|
if color_temp := entity.attributes.get("color_temp"):
|
||||||
# scale ha color temp range to 0-100
|
# scale ha color temp range to 0-100
|
||||||
color_temp = int(scale(entity.attributes.color_temp,(entity.attributes.min_mireds, entity.attributes.max_mireds),(0,100)))
|
color_temp = int(scale(color_temp, (entity.attributes['min_mireds'], entity.attributes['max_mireds']),(0, 100)))
|
||||||
else:
|
else:
|
||||||
color_temp = "unknown"
|
color_temp = "unknown"
|
||||||
else:
|
else:
|
||||||
color_temp = "disable"
|
color_temp = "disable"
|
||||||
list_color_modes = ["xy", "rgb", "rgbw", "hs"]
|
list_color_modes = ["xy", "rgb", "rgbw", "hs"]
|
||||||
if any(item in list_color_modes for item in entity.attributes.supported_color_modes):
|
if any(item in list_color_modes for item in supported_color_modes):
|
||||||
color = "enable"
|
color = "enable"
|
||||||
else:
|
else:
|
||||||
color = "disable"
|
color = "disable"
|
||||||
@@ -868,20 +909,20 @@ class LuiPagesGen(object):
|
|||||||
brightness_translation = get_translation(self._locale, "frontend.ui.card.light.brightness")
|
brightness_translation = get_translation(self._locale, "frontend.ui.card.light.brightness")
|
||||||
color_temp_translation = get_translation(self._locale, "frontend.ui.card.light.color_temperature")
|
color_temp_translation = get_translation(self._locale, "frontend.ui.card.light.color_temperature")
|
||||||
self._send_mqtt_msg(f"entityUpdateDetail~{entity_id}~~{icon_color}~{switch_val}~{brightness}~{color_temp}~{color}~{color_translation}~{color_temp_translation}~{brightness_translation}~{effect_supported}", force=is_open_detail)
|
self._send_mqtt_msg(f"entityUpdateDetail~{entity_id}~~{icon_color}~{switch_val}~{brightness}~{color_temp}~{color}~{color_translation}~{color_temp_translation}~{brightness_translation}~{effect_supported}", force=is_open_detail)
|
||||||
|
|
||||||
def generate_shutter_detail_page(self, entity_id, is_open_detail=False):
|
def generate_shutter_detail_page(self, entity_id, is_open_detail=False):
|
||||||
entity = apis.ha_api.get_entity(entity_id)
|
entity = apis.ha_api.get_entity(entity_id)
|
||||||
entityType = "cover"
|
entityType = "cover"
|
||||||
device_class = entity.attributes.get("device_class", "window")
|
device_class = entity.attributes.get("device_class", "window")
|
||||||
icon_id = get_icon_ha(entity_id)
|
icon_id = get_icon_ha(entity_id)
|
||||||
|
|
||||||
pos = entity.attributes.get("current_position")
|
pos = entity.attributes.get("current_position")
|
||||||
if pos is None:
|
if pos is None:
|
||||||
pos_status = entity.state
|
pos_status = entity.state
|
||||||
pos = "disable"
|
pos = "disable"
|
||||||
else:
|
else:
|
||||||
pos_status = pos
|
pos_status = pos
|
||||||
|
|
||||||
pos_translation = ""
|
pos_translation = ""
|
||||||
icon_up = ""
|
icon_up = ""
|
||||||
icon_stop = ""
|
icon_stop = ""
|
||||||
@@ -898,7 +939,7 @@ class LuiPagesGen(object):
|
|||||||
iconTiltRightStatus = "disable"
|
iconTiltRightStatus = "disable"
|
||||||
tilt_pos = "disable"
|
tilt_pos = "disable"
|
||||||
|
|
||||||
bits = entity.attributes.supported_features
|
bits = entity.attributes['supported_features']
|
||||||
|
|
||||||
# position supported
|
# position supported
|
||||||
if bits & 0b00001111:
|
if bits & 0b00001111:
|
||||||
@@ -985,7 +1026,7 @@ class LuiPagesGen(object):
|
|||||||
if modes:
|
if modes:
|
||||||
modes_out += f"{heading}~{mode}~{cur_mode}~{modes_res}~"
|
modes_out += f"{heading}~{mode}~{cur_mode}~{modes_res}~"
|
||||||
|
|
||||||
self._send_mqtt_msg(f"entityUpdateDetail~{entity_id}~{icon_id}~{icon_color}~{modes_out}", force=is_open_detail)
|
self._send_mqtt_msg(f"entityUpdateDetail~{entity_id}~{icon_id}~{icon_color}~{modes_out}", force=is_open_detail)
|
||||||
|
|
||||||
def generate_input_select_detail_page(self, entity_id, is_open_detail=False):
|
def generate_input_select_detail_page(self, entity_id, is_open_detail=False):
|
||||||
options_list = None
|
options_list = None
|
||||||
@@ -1049,8 +1090,9 @@ class LuiPagesGen(object):
|
|||||||
label2 = get_translation(self._locale, "frontend.ui.card.timer.actions.cancel")
|
label2 = get_translation(self._locale, "frontend.ui.card.timer.actions.cancel")
|
||||||
label3 = get_translation(self._locale, "frontend.ui.card.timer.actions.finish")
|
label3 = get_translation(self._locale, "frontend.ui.card.timer.actions.finish")
|
||||||
self._send_mqtt_msg(f"entityUpdateDetail~{entity_id}~~{icon_color}~{entity_id}~{min_remaining}~{sec_remaining}~{editable}~{action1}~{action2}~{action3}~{label1}~{label2}~{label3}", force=is_open_detail)
|
self._send_mqtt_msg(f"entityUpdateDetail~{entity_id}~~{icon_color}~{entity_id}~{min_remaining}~{sec_remaining}~{editable}~{action1}~{action2}~{action3}~{label1}~{label2}~{label3}", force=is_open_detail)
|
||||||
|
|
||||||
def send_message_page(self, ident, heading, msg, b1, b2):
|
def send_message_page(self, ident, heading, msg, b1, b2):
|
||||||
self._send_mqtt_msg(f"pageType~popupNotify")
|
self._send_mqtt_msg(f"pageType~popupNotify")
|
||||||
self._send_mqtt_msg(f"entityUpdateDetail~{ident}~{heading}~65535~{b1}~65535~{b2}~65535~{msg}~65535~0")
|
self._send_mqtt_msg(f"entityUpdateDetail~{ident}~{heading}~65535~{b1}~65535~{b2}~65535~{msg}~65535~0")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import hassapi as hass
|
import adbase as ad
|
||||||
|
|
||||||
from luibackend.config import LuiBackendConfig
|
from luibackend.config import LuiBackendConfig
|
||||||
from luibackend.controller import LuiController
|
from luibackend.controller import LuiController
|
||||||
@@ -6,15 +6,19 @@ from luibackend.mqtt import LuiMqttListener, LuiMqttSender
|
|||||||
from luibackend.updater import Updater
|
from luibackend.updater import Updater
|
||||||
|
|
||||||
import apis
|
import apis
|
||||||
|
import json
|
||||||
|
from typing import Literal
|
||||||
|
|
||||||
class NsPanelLovelaceUIManager(hass.Hass):
|
class NsPanelLovelaceUIManager(ad.ADBase):
|
||||||
|
|
||||||
def initialize(self):
|
def initialize(self):
|
||||||
self.log('Starting')
|
self.adapi = self.get_ad_api()
|
||||||
apis.ha_api = self
|
self.adapi.log('Starting')
|
||||||
|
apis.ad_api = self.adapi
|
||||||
|
apis.ha_api = self.get_plugin_api("HASS")
|
||||||
apis.mqtt_api = self.get_plugin_api("MQTT")
|
apis.mqtt_api = self.get_plugin_api("MQTT")
|
||||||
|
|
||||||
cfg = self._cfg = LuiBackendConfig(self, self.args["config"])
|
cfg = self._cfg = LuiBackendConfig(apis.ha_api, self.args["config"])
|
||||||
|
|
||||||
use_api = cfg.get("use_api") == True
|
use_api = cfg.get("use_api") == True
|
||||||
|
|
||||||
@@ -22,14 +26,15 @@ class NsPanelLovelaceUIManager(hass.Hass):
|
|||||||
topic_recv = cfg.get("panelRecvTopic")
|
topic_recv = cfg.get("panelRecvTopic")
|
||||||
api_panel_name = cfg.get("panelName")
|
api_panel_name = cfg.get("panelName")
|
||||||
api_device_id = cfg.get("panelDeviceId")
|
api_device_id = cfg.get("panelDeviceId")
|
||||||
|
quiet = cfg.get("quiet")
|
||||||
|
|
||||||
mqttsend = LuiMqttSender(self, use_api, topic_send, api_panel_name)
|
mqttsender = self._mqttsender = LuiMqttSender(apis.ha_api, use_api, topic_send, api_panel_name, quiet)
|
||||||
|
|
||||||
controller = LuiController(cfg, mqttsend.send_mqtt_msg)
|
self._controller = LuiController(cfg, mqttsender.send_mqtt_msg)
|
||||||
|
|
||||||
desired_tasmota_driver_version = 8
|
desired_tasmota_driver_version = 8
|
||||||
desired_display_firmware_version = 53
|
desired_display_firmware_version = 53
|
||||||
version = "v4.3.3"
|
version = "v4.7.3"
|
||||||
|
|
||||||
model = cfg.get("model")
|
model = cfg.get("model")
|
||||||
if model == "us-l":
|
if model == "us-l":
|
||||||
@@ -41,11 +46,35 @@ class NsPanelLovelaceUIManager(hass.Hass):
|
|||||||
desired_tasmota_driver_url = cfg._config.get("berryURL", "https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be")
|
desired_tasmota_driver_url = cfg._config.get("berryURL", "https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be")
|
||||||
|
|
||||||
mode = cfg.get("updateMode")
|
mode = cfg.get("updateMode")
|
||||||
updater = Updater(self.log, mqttsend, topic_send, mode, desired_display_firmware_version, model, desired_display_firmware_url, desired_tasmota_driver_version, desired_tasmota_driver_url)
|
updater = Updater(self.adapi.log, mqttsender, topic_send, mode, desired_display_firmware_version, model, desired_display_firmware_url, desired_tasmota_driver_version, desired_tasmota_driver_url)
|
||||||
|
|
||||||
# Request Tasmota Driver Version
|
# Request Tasmota Driver Version
|
||||||
updater.request_berry_driver_version()
|
updater.request_berry_driver_version()
|
||||||
|
|
||||||
LuiMqttListener(use_api, topic_recv, api_panel_name, api_device_id, controller, updater)
|
LuiMqttListener(use_api, topic_recv, api_panel_name, api_device_id, self._controller, updater)
|
||||||
|
|
||||||
self.log(f'Started ({version})')
|
self.adapi.log(f'Started ({version})')
|
||||||
|
|
||||||
|
#
|
||||||
|
# helpers
|
||||||
|
#
|
||||||
|
|
||||||
|
def show_card(self, card_key: str) -> None:
|
||||||
|
"""Used to show card on panel"""
|
||||||
|
|
||||||
|
msg = json.dumps({"CustomRecv":f"event,buttonPress2,navigate.{card_key},button"})
|
||||||
|
topic = self._cfg.get("panelRecvTopic")
|
||||||
|
self._mqttsender.send_mqtt_msg(msg, topic)
|
||||||
|
|
||||||
|
def navigate(self, direction: Literal['up', 'prev', 'next']) -> None:
|
||||||
|
"""Used to navigate different directions on the panel"""
|
||||||
|
|
||||||
|
msg = json.dumps({"CustomRecv":f"event,buttonPress2,nav{direction.title()},button"})
|
||||||
|
topic = self._cfg.get("panelRecvTopic")
|
||||||
|
self._mqttsender.send_mqtt_msg(msg, topic)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_card(self) -> str:
|
||||||
|
"""Used to get the panel's current card"""
|
||||||
|
|
||||||
|
return self._controller.current_card.key
|
||||||
|
|||||||
@@ -93,3 +93,4 @@ Now, to install NSPanel Lovelace UI Backend with HACS, follow these steps:
|
|||||||
6. A confirmation panel will appear, click on `Download`, and wait for HACS to
|
6. A confirmation panel will appear, click on `Download`, and wait for HACS to
|
||||||
proceed with the download
|
proceed with the download
|
||||||
7. The Backend Application is now installed, and HACS will inform you when updates are available
|
7. The Backend Application is now installed, and HACS will inform you when updates are available
|
||||||
|
|
||||||
|
|||||||
@@ -1,65 +1,71 @@
|
|||||||
# Flash Tasmota to your NSPanel
|
# Flash Tasmota to Your NSPanel
|
||||||
|
|
||||||
You need to connect to your nspanel via serial and flash tasmota [tasmota32-nspanel.bin](http://ota.tasmota.com/tasmota32/release/tasmota32-nspanel.bin) to your NSPanel.
|
You need to connect to your NSPanel via serial and flash Tasmota using [tasmota32-nspanel.bin](http://ota.tasmota.com/tasmota32/release/tasmota32-nspanel.bin).
|
||||||
You can use the Tasmota Web Installer to do so. [Tasmota Web Installer](https://tasmota.github.io/install/)
|
You can use the [Tasmota Web Installer](https://tasmota.github.io/install/) to do so.
|
||||||
|
|
||||||
Checkout Blakadders Template Repo for more information on flashing, do not use the autoexec.be from this page.
|
Check out Blakadder's Template Repo for more information on flashing. **Do not** use the autoexec.be from that page.
|
||||||
[NSPanel Page of the Tasmota Template Repository](https://templates.blakadder.com/sonoff_NSPanel.html)
|
[NSPanel Page of the Tasmota Template Repository](https://templates.blakadder.com/sonoff_NSPanel.html)
|
||||||
|
|
||||||
If you prefer EspHome over Tasmota, you can use this thrid party esphome component, which is replacing tasmota and the berry driver of this project.
|
If you prefer ESPHome over Tasmota, you can use this third-party ESPHome component, which replaces Tasmota and the Berry driver used in this project.
|
||||||
[ESPHome component](https://github.com/sairon/esphome-nspanel-lovelace-ui)
|
[ESPHome Component](https://github.com/sairon/esphome-nspanel-lovelace-ui)
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Configure Tasmota Template for NSPanel
|
## Configure Tasmota Template for NSPanel
|
||||||
|
|
||||||
Configure the NSPanel template for Tasmota. (Go to Configuration and Configure Other and paste the template there, make sure to tick the activate checkbox)
|
Configure the NSPanel template for Tasmota. (Go to Configuration > Configure Other, paste the template there, and make sure to tick the Activate checkbox.)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
You can use the following template or copy the one on the [Tasmota Template Repo Site](https://templates.blakadder.com/sonoff_NSPanel.html).
|
You can use the following template or copy the one from the [Tasmota Template Repo Site](https://templates.blakadder.com/sonoff_NSPanel.html):
|
||||||
|
|
||||||
`{"NAME":"NSPanel","GPIO":[0,0,0,0,3872,0,0,0,0,0,32,0,0,0,0,225,0,480,224,1,0,0,0,33,0,0,0,0,0,0,0,0,0,0,4736,0],"FLAG":0,"BASE":1,"CMND":"ADCParam 2,11200,10000,3950 | Sleep 0 | BuzzerPWM 1"}`
|
{"NAME":"NSPanel","GPIO":[0,0,0,0,3872,0,0,0,0,0,32,0,0,0,0,225,0,480,224,1,0,0,0,33,0,0,0,0,0,0,0,0,0,0,4736,0],"FLAG":0,"BASE":1,"CMND":"ADCParam 2,11200,10000,3950 | Sleep 0 | BuzzerPWM 1"}
|
||||||
|
|
||||||
After a reboot of tasmota your screen will light up with the stock display firmware.
|
After a reboot of Tasmota, your screen will light up with the stock display firmware.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Upload Berry Driver to Tasmota
|
## Upload Berry Driver to Tasmota
|
||||||
|
|
||||||
Go to `Consoles` > `Console` in Tasmota and execute the following command:
|
Go to Consoles > Console in Tasmota and execute the following command:
|
||||||
|
|
||||||
```
|
Backlog UrlFetch https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be; SetOption151 0; Restart 1
|
||||||
Backlog UrlFetch https://raw.githubusercontent.com/joBr99/nspanel-lovelace-ui/main/tasmota/autoexec.be; SetOption151 0;Restart 1
|
|
||||||
```
|
|
||||||
|
|
||||||
This will download the autoexec.be file from the repository and restart tasmota.
|
This downloads the autoexec.be file from the repository and restarts Tasmota.
|
||||||
|
|
||||||
Note: The command is also disabling matter to free up memory, as it's most likely not used by any homeassistant users anyway.
|
Note: This command also disables Matter to free up memory, as it's unlikely to be used by most Home Assistant users. (Matter can cause memory issues during flashing of the Nextion screen, but you can re-enable it later if needed.)
|
||||||
(Matter could cause memory issues during flashing of the Nextion Screen, but you can still enable it if you need to.)
|
|
||||||
|
---
|
||||||
|
|
||||||
## Flash Firmware to Nextion Screen
|
## Flash Firmware to Nextion Screen
|
||||||
|
|
||||||
Due the limitations of Berry, it's not possible to download the tft file directly from github, so I'm also renting a small server where you can download the file via HTTP.
|
Due to the limitations of Berry, it's not possible to download the TFT file directly from GitHub. A small server is available to download the file via HTTP.
|
||||||
|
|
||||||
Use the one following commands in the tasmota console (not berry console) to flash the latest release from this repository:
|
Use one of the following commands in the Tasmota console (not the Berry console) to flash the latest release from this repository:
|
||||||
|
|
||||||
EU Version: `FlashNextion http://nspanel.pky.eu/lui-release.tft`
|
EU Version:
|
||||||
|
FlashNextion http://nspanel.pky.eu/lui-release.tft
|
||||||
|
|
||||||
US Version Portrait: `FlashNextion http://nspanel.pky.eu/lui-us-p-release.tft`
|
US Version Portrait:
|
||||||
|
FlashNextion http://nspanel.pky.eu/lui-us-p-release.tft
|
||||||
|
|
||||||
US Version Landscape: `FlashNextion http://nspanel.pky.eu/lui-us-l-release.tft`
|
US Version Landscape:
|
||||||
|
FlashNextion http://nspanel.pky.eu/lui-us-l-release.tft
|
||||||
|
|
||||||
After sending the command, the screen should show a progress bar. The flashing progress takes around 5 minutes.
|
After sending the command, the screen should show a progress bar. The flashing process takes around 5 minutes.
|
||||||
|
|
||||||
Note: For the US Version Users - keep in mind that you need to add the model config option to your apps.yaml later, more details on config overview page
|
Note for US users: You'll need to add the model config option to your apps.yaml later. More details can be found on the config overview page.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Alternatively you can use your own webserver or the one build into HomeAssistant:</summary>
|
<summary>Alternatively, you can use your own web server or the one built into Home Assistant:</summary>
|
||||||
<br>
|
<br>
|
||||||
Upload the nspanel.tft from the lastest release to a Webserver (for example www folder of Home Assistant) and execute the following command in Tasmota Console. (Development Version: [tft file from HMI folder](HMI/nspanel.tft))
|
Upload the nspanel.tft from the latest release to a web server (for example, the www folder of Home Assistant) and execute the following command in the Tasmota Console.
|
||||||
|
(Development version: [TFT file from HMI folder](HMI/nspanel.tft))
|
||||||
|
|
||||||
**Webserver must be HTTP, HTTPS is not supported, due to limitations of berry lang on tasmota**
|
**The web server must be HTTP. HTTPS is not supported due to Berry language limitations in Tasmota.**
|
||||||
|
|
||||||
`FlashNextion http://ip-address-of-your-homeassistant:8123/local/nspanel.tft`
|
FlashNextion http://ip-address-of-your-homeassistant:8123/local/nspanel.tft
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
1732
ioBroker/.iobroker/types/javascript.d.ts
vendored
Normal file
1732
ioBroker/.iobroker/types/javascript.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,74 +0,0 @@
|
|||||||
const idAbfalliCal = 'ical.1'; // iCal Instanz zum Abfallkalender
|
|
||||||
const idZeichenLoeschen = 14; // x Zeichen links vom String abziehen, wenn vor dem Eventname noch Text steht z.B. Strassenname; Standard = 0
|
|
||||||
const idRestmuellName ='Hausmüll'; // Schwarze Tonne
|
|
||||||
const idWertstoffName = 'Gelber Sack'; // Gelbe Tonne / Sack
|
|
||||||
const idPappePapierName = 'Papier'; // Blaue Tonne
|
|
||||||
const idBioabfaelleName = 'Biomüll'; // Braune Tonne
|
|
||||||
|
|
||||||
|
|
||||||
var i, Muell_JSON, Event2, Color = 0;
|
|
||||||
|
|
||||||
for (i = 1; i <= 4; i++) {
|
|
||||||
if (!existsState('0_userdata.0.Abfallkalender.' + parseFloat(i) + '.date')) {
|
|
||||||
log(i + '.date nicht vorhanden, wurde erstellt');
|
|
||||||
createState('0_userdata.0.Abfallkalender.' + parseFloat(i) + '.date', '',
|
|
||||||
{
|
|
||||||
name: parseFloat(i) + '.date',
|
|
||||||
role: 'state',
|
|
||||||
type: 'string',
|
|
||||||
read: true,
|
|
||||||
write: true,
|
|
||||||
def: ''
|
|
||||||
});
|
|
||||||
};
|
|
||||||
if (!existsState('0_userdata.0.Abfallkalender.' + parseFloat(i) + '.event')) {
|
|
||||||
log(i + '.event nicht vorhanden, wurde erstellt');
|
|
||||||
createState('0_userdata.0.Abfallkalender.' + parseFloat(i) + '.event', '',
|
|
||||||
{
|
|
||||||
name: parseFloat(i) + '.event',
|
|
||||||
role: 'state',
|
|
||||||
type: 'string',
|
|
||||||
read: true,
|
|
||||||
write: true,
|
|
||||||
def: ''
|
|
||||||
});
|
|
||||||
};
|
|
||||||
if (!existsState('0_userdata.0.Abfallkalender.' + parseFloat(i) + '.color')) {
|
|
||||||
log(i + '.color nicht vorhanden, wurde erstellt');
|
|
||||||
createState('0_userdata.0.Abfallkalender.' + parseFloat(i) + '.color', 0,
|
|
||||||
{
|
|
||||||
name: parseFloat(i) + '.color',
|
|
||||||
role: 'state',
|
|
||||||
type: 'number',
|
|
||||||
read: true,
|
|
||||||
write: true,
|
|
||||||
def: 0
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function subsequenceFromStartLast(sequence, at1) {
|
|
||||||
var start = at1;
|
|
||||||
var end = sequence.length;
|
|
||||||
return sequence.slice(start, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
on({ id: idAbfalliCal + '.data.table', change: "ne" }, async function () {
|
|
||||||
|
|
||||||
for (i = 0; i <= 3; i++) {
|
|
||||||
Muell_JSON = getState(idAbfalliCal + '.data.table').val;
|
|
||||||
setStateDelayed((['0_userdata.0.Abfallkalender.', parseFloat(i) + 1, '.date'].join('')), getAttr(Muell_JSON, (String(i) + '.date')), false, parseInt(((0) || "").toString(), 10), false);
|
|
||||||
Event2 = subsequenceFromStartLast(getAttr(Muell_JSON, (String(i) + '.event')), idZeichenLoeschen);
|
|
||||||
setStateDelayed((['0_userdata.0.Abfallkalender.', parseFloat(i) + 1, '.event'].join('')), Event2, false, parseInt(((0) || "").toString(), 10), false);
|
|
||||||
if (Event2 == idRestmuellName) {
|
|
||||||
Color = 33840;
|
|
||||||
} else if (Event2 == idBioabfaelleName) {
|
|
||||||
Color = 2016;
|
|
||||||
} else if (Event2 == idPappePapierName) {
|
|
||||||
Color = 31;
|
|
||||||
} else if (Event2 == idWertstoffName) {
|
|
||||||
Color = 65504;
|
|
||||||
}
|
|
||||||
setStateDelayed((['0_userdata.0.Abfallkalender.', parseFloat(i) + 1, '.color'].join('')), Color, false, parseInt(((0) || "").toString(), 10), false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
224
ioBroker/Blockly/Abfallkalender.ts
Normal file
224
ioBroker/Blockly/Abfallkalender.ts
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
/*
|
||||||
|
* @author 2023 @tt-tom
|
||||||
|
*
|
||||||
|
* Version 5.1.1
|
||||||
|
*
|
||||||
|
* Das Script erstellt die Datenpunkte und Alias für den Abfallkalender im Sonoff NSPanel
|
||||||
|
* Es wird der iCal Adapter benötigt und eine URL mit Terminen vom Entsorger bzw. eine .ics-Datei mit den Terminen.
|
||||||
|
* Das Script triggert auf dem bereitgestellten JSON im iCal adapter und füllt die 0_userdata.0 Datenpunkte
|
||||||
|
* Weitere Informationen findest du in der FAQ auf Github https://github.com/joBr99/nspanel-lovelace-ui/wiki
|
||||||
|
*
|
||||||
|
* changelog
|
||||||
|
* - 06.12.2023 - v5.0.2 add custom name for trashtype
|
||||||
|
* - 06.12.2023 - v5.1.0 Refactoring
|
||||||
|
* - 22.01.2024 - v5.1.1 Add tow Events more
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
const idTrashData: string = 'ical.0.data.table'; // Datenpunkt mit Daten im JSON Format
|
||||||
|
const idUserdataAbfallVerzeichnis: string = '0_userdata.0.Abfallkalender'; // Name des Datenpunktverzeichnis unter 0_userdata.0 -> Strandard = 0_userdata.0.Abfallkalender
|
||||||
|
const idAliasPanelVerzeichnis: string = 'alias.0.NSPanel.allgemein'; //Name PanelVerzeichnis unter alias.0. Standard = alias.0.NSPanel.1
|
||||||
|
const idAliasAbfallVerzeichnis: string = 'Abfall'; //Name Verzeichnis unterhalb der idPanelverzeichnis Standard = Abfall
|
||||||
|
|
||||||
|
const anzahlZeichenLoeschen: number = 14; // x Zeichen links vom String abziehen, wenn vor dem Eventname noch Text steht z.B. Strassenname; Standard = 0
|
||||||
|
const jsonEventName1: string = 'Hausmüll'; // Vergleichstring für Schwarze Tonne
|
||||||
|
const customEventName1: string = ''; // benutzerdefinierter Text für schwarze Tonne
|
||||||
|
const jsonEventName2: string = 'Gelber Sack'; // Vergleichstring für Gelbe Tonne / Sack
|
||||||
|
const customEventName2: string = ''; // benutzerdefinierter Text für gelbe Tonne
|
||||||
|
const jsonEventName3: string = 'Papier'; // Vergleichstring für Blaue Tonne
|
||||||
|
const customEventName3: string = ''; // benutzerdefinierter Text für blaue Tonne
|
||||||
|
const jsonEventName4: string = 'Biomüll'; // Vergleichstring für Braune Tonne
|
||||||
|
const customEventName4: string = ''; // benutzerdefinierter Text für braune Tonne
|
||||||
|
const jsonEventName5: string = 'Treppe'; // Vergleichstring für Event 5
|
||||||
|
const customEventName5: string = 'Besen schwingen'; // benutzerdefinierter Text für Event 5
|
||||||
|
const jsonEventName6: string = ''; // Vergleichstring für Event 6
|
||||||
|
const customEventName6: string = ''; // benutzerdefinierter Text für Event 6
|
||||||
|
|
||||||
|
const Debug: boolean = false;
|
||||||
|
|
||||||
|
// ------------------------- Trigger zum füllen der 0_userdata Datenpunkte aus dem json vom ical Adapter -------------------------------
|
||||||
|
|
||||||
|
// Trigger auf JSON Datenpunkt
|
||||||
|
on({ id: idTrashData, change: 'ne' }, async function () {
|
||||||
|
JSON_auswerten();
|
||||||
|
});
|
||||||
|
|
||||||
|
// ------------------------------------- Ende Trigger ------------------------------------
|
||||||
|
|
||||||
|
// ------------------------------------- Funktion JSON auswerten und DP füllen -------------------------------
|
||||||
|
async function JSON_auswerten() {
|
||||||
|
try {
|
||||||
|
|
||||||
|
let trashJSON: any;
|
||||||
|
let instanzName: any;
|
||||||
|
let eventName: string;
|
||||||
|
let eventDatum: string;
|
||||||
|
let eventStartdatum: string;
|
||||||
|
let farbNummer: number = 0;
|
||||||
|
let farbString: string;
|
||||||
|
let abfallNummer: number = 1;
|
||||||
|
|
||||||
|
trashJSON = getState(idTrashData).val;
|
||||||
|
instanzName = idTrashData.split('.');
|
||||||
|
|
||||||
|
if (Debug) log('Rohdaten von Instanz ' + instanzName[0] + ': ' + JSON.stringify(trashJSON), 'info')
|
||||||
|
|
||||||
|
|
||||||
|
if (Debug) log('Anzahl Trash - Daten: ' + trashJSON.length, 'info');
|
||||||
|
|
||||||
|
for (let i = 0; i < trashJSON.length; i++) {
|
||||||
|
if (abfallNummer === 7) {
|
||||||
|
if (Debug) log('Alle Abfall-Datenpunkte gefüllt', 'warn');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
log('Daten vom ical Adapter werden ausgewertet', 'info');
|
||||||
|
eventName = getAttr(trashJSON, (String(i) + '.event')).slice(anzahlZeichenLoeschen, getAttr(trashJSON, (String(i) + '.event')).length);
|
||||||
|
// Leerzeichen vorne und hinten löschen
|
||||||
|
eventName = eventName.trimEnd();
|
||||||
|
eventName = eventName.trimStart();
|
||||||
|
eventDatum = getAttr(trashJSON, (String(i) + '.date'));
|
||||||
|
eventStartdatum = getAttr(trashJSON, (String(i) + '._date'));
|
||||||
|
|
||||||
|
let d: Date = currentDate();
|
||||||
|
let d1: Date = new Date(eventStartdatum);
|
||||||
|
|
||||||
|
if (Debug) log('--------- Nächster Termin wird geprüft ---------', 'info');
|
||||||
|
//if (Debug) log(d + ' ' + d1, 'info');
|
||||||
|
if (Debug) log('Startdatum UTC: ' + eventStartdatum, 'info');
|
||||||
|
if (Debug) log('Datum: ' + eventDatum, 'info');
|
||||||
|
if (Debug) log('Event: ' + eventName, 'info');
|
||||||
|
if (Debug) log('Kontrolle Leerzeichen %' + eventName + '%', 'info');
|
||||||
|
|
||||||
|
if (d.getTime() <= d1.getTime()) {
|
||||||
|
if ((eventName == jsonEventName1) || (eventName == jsonEventName2) || (eventName == jsonEventName3) || (eventName == jsonEventName4) || (eventName == jsonEventName5) || (eventName == jsonEventName6)) {
|
||||||
|
|
||||||
|
switch (eventName) {
|
||||||
|
case jsonEventName1:
|
||||||
|
farbNummer = 33840;
|
||||||
|
if (customEventName1 != '') {
|
||||||
|
eventName = customEventName1;
|
||||||
|
if (Debug) log('Event customName: ' + eventName, 'info');
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case jsonEventName2:
|
||||||
|
farbNummer = 65504;
|
||||||
|
if (customEventName2 != '') {
|
||||||
|
eventName = customEventName2;
|
||||||
|
if (Debug) log('Event customName: ' + eventName, 'info');
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case jsonEventName3:
|
||||||
|
farbNummer = 31;
|
||||||
|
if (customEventName3 != '') {
|
||||||
|
eventName = customEventName3
|
||||||
|
if (Debug) log('Event customName: ' + eventName, 'info');
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case jsonEventName4:
|
||||||
|
farbNummer = 2016;
|
||||||
|
if (customEventName4 != '') {
|
||||||
|
eventName = customEventName4;
|
||||||
|
if (Debug) log('Event customName: ' + eventName, 'info');
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case jsonEventName5:
|
||||||
|
farbNummer = 2016;
|
||||||
|
if (customEventName5 != '') {
|
||||||
|
eventName = customEventName5;
|
||||||
|
if (Debug) log('Event customName: ' + eventName, 'info');
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case jsonEventName6:
|
||||||
|
farbNummer = 2016;
|
||||||
|
if (customEventName6 != '') {
|
||||||
|
eventName = customEventName6
|
||||||
|
if (Debug) log('Event customName: ' + eventName, 'info');
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (farbString != undefined) farbNummer = rgb_dec565(hex_rgb(farbString));
|
||||||
|
|
||||||
|
|
||||||
|
setState(idUserdataAbfallVerzeichnis + '.' + String(abfallNummer) + '.date', eventDatum);
|
||||||
|
setState(idUserdataAbfallVerzeichnis + '.' + String(abfallNummer) + '.event', eventName);
|
||||||
|
setState(idUserdataAbfallVerzeichnis + '.' + String(abfallNummer) + '.color', farbNummer);
|
||||||
|
|
||||||
|
|
||||||
|
//if (Debug) log('farbString: ' + farbString + ' farbNummer: ' + farbNummer, 'info');
|
||||||
|
if (Debug) log('Abfallnummer: ' + abfallNummer, 'info');
|
||||||
|
|
||||||
|
abfallNummer += 1
|
||||||
|
} else {
|
||||||
|
if (Debug) log('Kein Abfalltermin => Event passt mit keinem Abfallnamen überein.', 'warn');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (Debug) log('Termin liegt vor dem heutigen Tag', 'warn');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
log('error at subscrption: ' + err.message, 'warn');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ------------------------------------- Ende Funktion JSON ------------------------------
|
||||||
|
|
||||||
|
// ------------------------------------- Funktion zur Prüfung und Erstellung der Datenpunkte in 0_userdata.0 und alias.0 -----------------------
|
||||||
|
|
||||||
|
async function Init_Datenpunkte() {
|
||||||
|
try {
|
||||||
|
for (let i = 1; i <= 6; i++) {
|
||||||
|
if (existsObject(idUserdataAbfallVerzeichnis + '.' + String(i)) == false) {
|
||||||
|
log('Datenpunkt ' + idUserdataAbfallVerzeichnis + '.' + String(i) + ' werden angelegt', 'info')
|
||||||
|
await createStateAsync(idUserdataAbfallVerzeichnis + '.' + String(i) + '.date', '', { type: 'string' });
|
||||||
|
await createStateAsync(idUserdataAbfallVerzeichnis + '.' + String(i) + '.event', '', { type: 'string' });
|
||||||
|
await createStateAsync(idUserdataAbfallVerzeichnis + '.' + String(i) + '.color', 0, { type: 'number' });
|
||||||
|
setObject(idAliasPanelVerzeichnis + '.' + idAliasAbfallVerzeichnis, { type: 'device', common: { name: { de: 'Abfall', en: 'Trash' } }, native: {} });
|
||||||
|
setObject(idAliasPanelVerzeichnis + '.' + idAliasAbfallVerzeichnis + '.event' + String(i), { type: 'channel', common: { role: 'warning', name: { de: 'Ereignis ' + String(i), en: 'Event' + String(i) } }, native: {} });
|
||||||
|
await createAliasAsync(idAliasPanelVerzeichnis + '.' + idAliasAbfallVerzeichnis + '.event' + String(i) + '.TITLE', idUserdataAbfallVerzeichnis + '.' + String(i) + '.event', true, <iobJS.StateCommon>{ type: 'string', role: 'weather.title.short', name: { de: 'TITEL', en: 'TITLE' } });
|
||||||
|
await createAliasAsync(idAliasPanelVerzeichnis + '.' + idAliasAbfallVerzeichnis + '.event' + String(i) + '.LEVEL', idUserdataAbfallVerzeichnis + '.' + String(i) + '.color', true, <iobJS.StateCommon>{ type: 'number', role: 'value.warning', name: { de: 'LEVEL', en: 'LEVEL' } });
|
||||||
|
await createAliasAsync(idAliasPanelVerzeichnis + '.' + idAliasAbfallVerzeichnis + '.event' + String(i) + '.INFO', idUserdataAbfallVerzeichnis + '.' + String(i) + '.date', true, <iobJS.StateCommon>{ type: 'string', role: 'weather.title', name: { de: 'INFO', en: 'INFO' } });
|
||||||
|
log('Fertig', 'info')
|
||||||
|
} else {
|
||||||
|
log('Datenpunkt ' + idUserdataAbfallVerzeichnis + '.' + String(i) + ' vorhanden', 'info')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log('Startabfrage der Daten', 'info');
|
||||||
|
JSON_auswerten();
|
||||||
|
} catch (err) {
|
||||||
|
log('error at function Init_Datenpunkte: ' + err.message, 'warn');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Init_Datenpunkte();
|
||||||
|
|
||||||
|
// --------------------------- Ende Funktion Datenpunkte ------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------- Zusatzfuktionen -------------------------------------------------------------
|
||||||
|
function currentDate() {
|
||||||
|
let d: Date = new Date();
|
||||||
|
return new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
function rgb_dec565(rgb: RGB): number {
|
||||||
|
//return ((Math.floor(rgb.red / 255 * 31) << 11) | (Math.floor(rgb.green / 255 * 63) << 5) | (Math.floor(rgb.blue / 255 * 31)));
|
||||||
|
return ((rgb.red >> 3) << 11) | ((rgb.green >> 2)) << 5 | ((rgb.blue) >> 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
function hex_rgb(colorhex: string): RGB {
|
||||||
|
let r = parseInt(colorhex.substring(1, 3), 16);
|
||||||
|
let g = parseInt(colorhex.substring(3, 5), 16);
|
||||||
|
let b = parseInt(colorhex.substring(5, 7), 16);
|
||||||
|
return { red: r, green: g, blue: b };
|
||||||
|
}
|
||||||
|
|
||||||
|
type RGB = {
|
||||||
|
red: number,
|
||||||
|
green: number,
|
||||||
|
blue: number
|
||||||
|
};
|
||||||
|
|
||||||
|
// -------------------- Ende Zudatzfunktionen --------------------------------------------------------------------------
|
||||||
@@ -971,12 +971,37 @@
|
|||||||
</value>
|
</value>
|
||||||
</block>
|
</block>
|
||||||
</value>
|
</value>
|
||||||
<value name="VALUE">
|
<value name="VALUE">
|
||||||
<shadow type="logic_boolean" id="I4PsJQb;6k+70^g*Xt/}">
|
<shadow type="logic_boolean" id="I4PsJQb;6k+70^g*Xt/}">
|
||||||
<field name="BOOL">TRUE</field>
|
<field name="BOOL">TRUE</field>
|
||||||
</shadow>
|
</shadow>
|
||||||
<block type="math_random_float" id="C5/h)jq=yPM?,9J=(w65"></block>
|
<block type="text_join" id="XdhGC7#MxGw|KhC1x#MY">
|
||||||
</value>
|
<mutation items="2"></mutation>
|
||||||
|
<value name="ADD0">
|
||||||
|
<block type="text" id="[(_1;{xE-xfzeB4]$uk;">
|
||||||
|
<field name="TEXT">ID</field>
|
||||||
|
</block>
|
||||||
|
</value>
|
||||||
|
<value name="ADD1">
|
||||||
|
<block type="convert_tostring" id="g{jZOA*6Clhc5`9::h.S">
|
||||||
|
<value name="VALUE">
|
||||||
|
<block type="math_random_int" id="SXG?j1]Jza!2fg[(cl!i">
|
||||||
|
<value name="FROM">
|
||||||
|
<shadow type="math_number" id="#/-;$~`{=}8wYY$kbvA9">
|
||||||
|
<field name="NUM">1</field>
|
||||||
|
</shadow>
|
||||||
|
</value>
|
||||||
|
<value name="TO">
|
||||||
|
<shadow type="math_number" id="0x8~a;asHsiJ2Its%!VJ">
|
||||||
|
<field name="NUM">100</field>
|
||||||
|
</shadow>
|
||||||
|
</value>
|
||||||
|
</block>
|
||||||
|
</value>
|
||||||
|
</block>
|
||||||
|
</value>
|
||||||
|
</block>
|
||||||
|
</value>
|
||||||
<value name="DELAY_MS">
|
<value name="DELAY_MS">
|
||||||
<shadow type="math_number" id="+6#n%fO}e4h%;FhKPV0c">
|
<shadow type="math_number" id="+6#n%fO}e4h%;FhKPV0c">
|
||||||
<field name="NUM">0</field>
|
<field name="NUM">0</field>
|
||||||
|
|||||||
44
ioBroker/Blockly/Alarm_clock.ts
Normal file
44
ioBroker/Blockly/Alarm_clock.ts
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
const dp_userdata: string = '0_userdata.0.NSPanel';
|
||||||
|
const dp_alias: string = 'alias.0.NSPanel';
|
||||||
|
|
||||||
|
// dpAction wird wenn der Wecker gestellt wird auf false geschaltet
|
||||||
|
// dpAction wird wenn die Weckzeit erreicht ist auf true geschaltet
|
||||||
|
// Der nachfolgende Datenpunkt muss manuell erstellt werden...
|
||||||
|
const dpAction: string = '0_userdata.0.example_boolean';
|
||||||
|
|
||||||
|
const Debug = true;
|
||||||
|
|
||||||
|
let time: number;
|
||||||
|
let scheduleAlarmTime: any = null;
|
||||||
|
on({ id: dp_userdata + '.AlarmTime.State', change: 'ne' }, async (obj) => {
|
||||||
|
|
||||||
|
time = getState(dp_userdata + '.AlarmTime.Time').val;
|
||||||
|
if (Debug) log('Uhrzeit: ' + time, 'info');
|
||||||
|
if ('paused' == obj.state.val) {
|
||||||
|
(function () { if (scheduleAlarmTime) {
|
||||||
|
clearSchedule(scheduleAlarmTime);
|
||||||
|
scheduleAlarmTime = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if ('active' == obj.state.val) {
|
||||||
|
let stunde: number = Math.floor(time / 60);
|
||||||
|
let minute: number = time % 60;
|
||||||
|
if (Debug) log('Weckzeit: ' + ('0' + stunde).slice(-2) + ':' + ('0' + minute).slice(-2), 'info');
|
||||||
|
scheduleAlarmTime = schedule(minute + ' ' + stunde + ' * * *', async () => {
|
||||||
|
await setStateAsync(dpAction, <iobJS.State>{ val: true, ack: true });
|
||||||
|
await setStateAsync(dp_userdata + '.AlarmTime.State', <iobJS.State>{ val: 'paused', ack: true });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
async function Init_Datenpunkte() {
|
||||||
|
if (existsState(dp_alias + '.AlarmTime.ACTUAL') == false) {
|
||||||
|
await createStateAsync(dp_userdata + '.AlarmTime.Time', '0', { type: 'number' });
|
||||||
|
await createStateAsync(dp_userdata + '.AlarmTime.State', 'paused', { type: 'string' });
|
||||||
|
setObject(dp_alias + '.AlarmTime', { type: 'channel', common: { role: 'value.alarmtime', name: 'Alarmtime' }, native: {} });
|
||||||
|
await createAliasAsync(dp_alias + '.AlarmTime.ACTUAL', dp_userdata + '.AlarmTime.Time', true, <iobJS.StateCommon>{ type: 'number', role: 'state', name: 'ACTUAL' });
|
||||||
|
await createAliasAsync(dp_alias + '.AlarmTime.STATE', dp_userdata + '.AlarmTime.State', true, <iobJS.StateCommon>{ type: 'string', role: 'state', name: 'STATE' });
|
||||||
|
log("<PageItem>{id: '"+ dp_alias + ".AlarmTime', name: 'Wecker', onColor: Red, offColor: Green, useColor: true}", 'info');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Init_Datenpunkte();
|
||||||
51
ioBroker/Blockly/CardChart_History.js
Normal file
51
ioBroker/Blockly/CardChart_History.js
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
const sourceDP = 'alias.0.Wohnzimmer.Heizung.ACTUAL';
|
||||||
|
const targetDP = '0_userdata.0.Test.chartTest';
|
||||||
|
const rangeHours = 24;
|
||||||
|
const maxXAchsisTicks = 6;
|
||||||
|
const historyInstance = 'history.0';
|
||||||
|
const factor = 1; // Bei zu großen Werten und negativen Anzeigen im Panel um das 10fache erhöhen
|
||||||
|
|
||||||
|
on({id: sourceDP, change: "any"}, async function (obj) {
|
||||||
|
sendTo(historyInstance, 'getHistory', {
|
||||||
|
id: sourceDP,
|
||||||
|
options: {
|
||||||
|
start: Date.now() - (60 * 60 * 1000 * rangeHours),
|
||||||
|
end: Date.now(),
|
||||||
|
count: rangeHours,
|
||||||
|
limit: rangeHours,
|
||||||
|
aggregate: 'average'
|
||||||
|
}
|
||||||
|
}, function (result) {
|
||||||
|
var cardChartString = "";
|
||||||
|
var stepXAchsis = rangeHours / maxXAchsisTicks;
|
||||||
|
|
||||||
|
for (var i = 0; i < rangeHours; i++){
|
||||||
|
var deltaHour = rangeHours - i;
|
||||||
|
var targetDate = new Date(Date.now() - (deltaHour * 60 * 60 * 1000));
|
||||||
|
|
||||||
|
//Check history items for requested hours
|
||||||
|
for (var j = 0, targetValue = 0; j < result.result.length; j++) {
|
||||||
|
var valueDate = new Date(result.result[j].ts);
|
||||||
|
var value = Math.round(result.result[j].val / factor * 10);
|
||||||
|
|
||||||
|
if (valueDate > targetDate){
|
||||||
|
if ((targetDate.getHours() % stepXAchsis) == 0){
|
||||||
|
cardChartString += targetValue + '^' + targetDate.getHours() + ':00' + '~';
|
||||||
|
} else {
|
||||||
|
cardChartString += targetValue + '~';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
targetValue = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cardChartString = cardChartString.substring(0,cardChartString.length-1);
|
||||||
|
if (existsState(targetDP) == false ) {
|
||||||
|
createState(targetDP, cardChartString, true, { type: 'string' });
|
||||||
|
} else {
|
||||||
|
setState(targetDP, cardChartString, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
78
ioBroker/Blockly/CardLChart_History.js
Normal file
78
ioBroker/Blockly/CardLChart_History.js
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
const sourceDP = 'alias.0.Wohnzimmer.Heizung.ACTUAL';
|
||||||
|
const targetDP = '0_userdata.0.Test.chartTest';
|
||||||
|
const numberOfHoursAgo = 24; // Period of time in hours which shall be visualized
|
||||||
|
const xAxisTicksEveryM = 60; // Time after x axis gets a tick in minutes
|
||||||
|
const xAxisLabelEveryM = 240; // Time after x axis is labeled in minutes
|
||||||
|
const historyInstance = 'history.0';
|
||||||
|
|
||||||
|
const Debug = false;
|
||||||
|
const maxX = 1420;
|
||||||
|
const limitMeasurements = 35;
|
||||||
|
|
||||||
|
createState(targetDP, "", {
|
||||||
|
name: 'SensorGrid',
|
||||||
|
desc: 'Sensor Values [~<time>:<value>]*',
|
||||||
|
type: 'string',
|
||||||
|
role: 'value',
|
||||||
|
});
|
||||||
|
|
||||||
|
on({id: sourceDP, change: "any"}, async function (obj) {
|
||||||
|
sendTo(historyInstance, 'getHistory', {
|
||||||
|
id: sourceDP,
|
||||||
|
options: {
|
||||||
|
start: Date.now() - (numberOfHoursAgo * 60 * 60 * 1000 ), //Time in ms: hours * 60m * 60s * 1000ms
|
||||||
|
end: Date.now(),
|
||||||
|
count: limitMeasurements,
|
||||||
|
limit: limitMeasurements,
|
||||||
|
aggregate: 'average'
|
||||||
|
}
|
||||||
|
}, function (result) {
|
||||||
|
var ticksAndLabels = ""
|
||||||
|
var coordinates = "";
|
||||||
|
var cardLChartString = "";
|
||||||
|
|
||||||
|
let ticksAndLabelsList = []
|
||||||
|
var date = new Date();
|
||||||
|
date.setMinutes(0, 0, 0);
|
||||||
|
var ts = Math.round(date.getTime() / 1000);
|
||||||
|
var tsYesterday = ts - (numberOfHoursAgo * 3600);
|
||||||
|
|
||||||
|
for (var x = tsYesterday, i = 0; x < ts; x += (xAxisTicksEveryM * 60), i += xAxisTicksEveryM)
|
||||||
|
{
|
||||||
|
if (i % xAxisLabelEveryM)
|
||||||
|
{
|
||||||
|
ticksAndLabelsList.push(i);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
var currentDate = new Date(x * 1000);
|
||||||
|
// Hours part from the timestamp
|
||||||
|
var hours = "0" + currentDate.getHours();
|
||||||
|
// Minutes part from the timestamp
|
||||||
|
var minutes = "0" + currentDate.getMinutes();
|
||||||
|
// Seconds part from the timestamp
|
||||||
|
var seconds = "0" + currentDate.getSeconds();
|
||||||
|
var formattedTime = hours.slice(-2) + ':' + minutes.slice(-2);
|
||||||
|
ticksAndLabelsList.push(String(i) + "^" + formattedTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ticksAndLabels = ticksAndLabelsList.join("+");
|
||||||
|
|
||||||
|
let list = [];
|
||||||
|
let offSetTime = Math.round(result.result[0].ts / 1000);
|
||||||
|
let counter = Math.round((result.result[result.result.length -1 ].ts / 1000 - offSetTime) / maxX);
|
||||||
|
for (var i = 0; i < result.result.length; i++)
|
||||||
|
{
|
||||||
|
var time = Math.round(((result.result[i].ts / 1000) - offSetTime) / counter);
|
||||||
|
var value = Math.round(result.result[i].val * 10);
|
||||||
|
if ((value != null) && (value != 0)){
|
||||||
|
list.push(time + ":" + value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
coordinates = list.join("~");
|
||||||
|
cardLChartString = ticksAndLabels + '~' + coordinates
|
||||||
|
setState(targetDP, cardLChartString, true);
|
||||||
|
|
||||||
|
if (Debug) console.log(cardLChartString);
|
||||||
|
});
|
||||||
|
});
|
||||||
130
ioBroker/Blockly/CardLChart_Influx2.ts
Normal file
130
ioBroker/Blockly/CardLChart_Influx2.ts
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
/**
|
||||||
|
* Dieses Script fragt eine influxDb ab, um Daten für die cardLcart (Liniendiagramm) zuberechnen und im richtigen Format bereitzustellen.
|
||||||
|
* Es erstellt automatisch einen Datenpunkt.
|
||||||
|
* Die Abfrage muss ggf. angepasst werden. Aktuell ermittelt sie Werte der letzten 24h, zu Stundenwerten zusammengefasst.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const Debug = false; // true für erweiterte Ausgaben im Log
|
||||||
|
|
||||||
|
const NSPanel_Path = '0_userdata.0.NSPanel.';
|
||||||
|
const Path = NSPanel_Path + 'Influx2NSPanel.cardLChart.';
|
||||||
|
const InfluxInstance = 'influxdb.0';
|
||||||
|
const influxDbBucket = 'storage_short';
|
||||||
|
const numberOfHoursAgo = 24;
|
||||||
|
const xAxisTicksEveryM = 60;
|
||||||
|
const xAxisLabelEveryM = 240;
|
||||||
|
//
|
||||||
|
|
||||||
|
const sensors : Record<string, Record <string, string>> = {};
|
||||||
|
/**
|
||||||
|
* Hier werden die Sensoren festgelegt nach flogendem Schema
|
||||||
|
*
|
||||||
|
* sensors[‘Datenpunkt(kompletter Pfad) des Messwertes'] = {'taget': 'Name des Datenpunkt für die Chartwerte', 'measurement': 'genutzter Alias in der Influxdb für den Messwert'};
|
||||||
|
*
|
||||||
|
* Wenn der Wert in der Datenbank keinen Alias hat bleibt der Wert 'measurement': weg.
|
||||||
|
* Jeder Messwert bekommt einen eigenen sensors[...] = {'target':....}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
sensors['netatmo-crawler.0.stationData.1.temperature'] = {'target':'AussenTemp', 'measurement':'wetter.temperatur'};
|
||||||
|
|
||||||
|
// ##### ab hier keine Änderungen mehr nötig #####
|
||||||
|
|
||||||
|
// create data source for NsPanel on script startup
|
||||||
|
Object.keys(sensors).forEach(async id => {
|
||||||
|
await generateDateAsync(id);
|
||||||
|
});
|
||||||
|
|
||||||
|
// then listen to the sensors and update the data source states accordingly
|
||||||
|
on({ id: Object.keys(sensors), change: 'any' }, async function (obj) {
|
||||||
|
if (!obj.id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await generateDateAsync(obj.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
//__________________________
|
||||||
|
// Beschreibe diese Funktion: Daten generieren
|
||||||
|
async function generateDateAsync(sensorId: string) {
|
||||||
|
let idMeasurement = sensors[sensorId].measurement;
|
||||||
|
if (idMeasurement =='' ||idMeasurement == undefined) {idMeasurement = sensorId};
|
||||||
|
const dataPointId:string = Path + sensors[sensorId].target +'.ACTUAL';
|
||||||
|
if (Debug) log(`(f) generateDateAsync: ${sensorId} ${dataPointId} > ${idMeasurement}`);
|
||||||
|
|
||||||
|
const query =[
|
||||||
|
'from(bucket: "' + influxDbBucket + '")',
|
||||||
|
'|> range(start: -' + numberOfHoursAgo + 'h)',
|
||||||
|
'|> filter(fn: (r) => r["_measurement"] == "' + idMeasurement + '")',
|
||||||
|
'|> filter(fn: (r) => r["_field"] == "value")',
|
||||||
|
'|> drop(columns: ["from", "ack", "q"])',
|
||||||
|
'|> aggregateWindow(every: 1h, fn: last, createEmpty: false)',
|
||||||
|
'|> map(fn: (r) => ({ r with _rtime: int(v: r._time) - int(v: r._start)}))',
|
||||||
|
'|> yield(name: "_result")'].join('');
|
||||||
|
|
||||||
|
if (Debug) console.log('Query: ' + query);
|
||||||
|
|
||||||
|
const result : any = await sendToAsync(InfluxInstance, 'query', query);
|
||||||
|
if (result.error) {
|
||||||
|
console.error(result.error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Debug) console.log(JSON.stringify(result));
|
||||||
|
const numResults = result.result.length;
|
||||||
|
let coordinates : string = '';
|
||||||
|
for (let r = 0; r < numResults; r++)
|
||||||
|
{
|
||||||
|
const list : string[] = [];
|
||||||
|
const numValues = result.result[r].length;
|
||||||
|
|
||||||
|
for (let i = 0; i < numValues; i++)
|
||||||
|
{
|
||||||
|
const time = Math.round(result.result[r][i]._rtime/1000/1000/1000/60);
|
||||||
|
const value = Math.round(result.result[r][i]._value * 10);
|
||||||
|
list.push(time + ":" + value);
|
||||||
|
}
|
||||||
|
|
||||||
|
coordinates = list.join("~");
|
||||||
|
if (Debug) console.log(coordinates);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ticksAndLabelsList : string[] = []
|
||||||
|
const date = new Date();
|
||||||
|
date.setMinutes(0, 0, 0);
|
||||||
|
const ts = Math.round(date.getTime() / 1000);
|
||||||
|
const tsYesterday = ts - (numberOfHoursAgo * 3600);
|
||||||
|
if (Debug) console.log('Iterate from ' + tsYesterday + ' to ' + ts + ' stepsize=' + (xAxisTicksEveryM * 60));
|
||||||
|
for (let x = tsYesterday, i = 0; x < ts; x += (xAxisTicksEveryM * 60), i += xAxisTicksEveryM)
|
||||||
|
{
|
||||||
|
if ((i % xAxisLabelEveryM))
|
||||||
|
ticksAndLabelsList.push('' + i);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const currentDate = new Date(x * 1000);
|
||||||
|
// Hours part from the timestamp
|
||||||
|
const hours = "0" + String(currentDate.getHours());
|
||||||
|
// Minutes part from the timestamp
|
||||||
|
const minutes = "0" + String(currentDate.getMinutes());
|
||||||
|
const formattedTime = hours.slice(-2) + ':' + minutes.slice(-2);
|
||||||
|
|
||||||
|
ticksAndLabelsList.push(String(i) + "^" + formattedTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Debug) console.log('Ticks & Label: ' + ticksAndLabelsList);
|
||||||
|
if (Debug) console.log('Coordinates: ' + coordinates);
|
||||||
|
await setOrCreate(dataPointId, ticksAndLabelsList.join("+") + '~' + coordinates, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//__________________________
|
||||||
|
// Beschreibe diese Funktion: Datenpunkte anlegen bzw. schreiben
|
||||||
|
async function setOrCreate(id : string, value : any, ack : boolean) {
|
||||||
|
if (!(await existsStateAsync(id))) {
|
||||||
|
await createStateAsync(id, value, {
|
||||||
|
name: id.split('.').reverse()[0],
|
||||||
|
desc: 'Sensor Values [~<time>:<value>]*',
|
||||||
|
type: 'string',
|
||||||
|
role: 'value',
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await setStateAsync(id, value, ack);
|
||||||
|
}
|
||||||
|
}
|
||||||
54
ioBroker/Blockly/CardPower.js
Normal file
54
ioBroker/Blockly/CardPower.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
* generate an JSON for display Power-Card on NSPanel
|
||||||
|
* Source: https://github.com/joBr99/nspanel-lovelace-ui/wiki/ioBroker-Card-Definitionen-(Seiten)#cardpower-ab-ts-script-v341
|
||||||
|
* Version: 0.1 - L4rs
|
||||||
|
*/
|
||||||
|
schedule("* * * * *", function () {
|
||||||
|
|
||||||
|
// Definition der Datenpunkte für das JSON der POWER-Card und der anzuzeigenden Leistungswerte
|
||||||
|
var powerCardJson = "0_userdata.0.NSPanel.Energie.PowerCard",
|
||||||
|
pwr1 = "", // Batterie
|
||||||
|
pwr2 = Math.round(getState("mqtt.0.SmartHome.Energie.PV.openDTU.114180710360.0.power").val), // Solar
|
||||||
|
pwr3 = "", // Wind
|
||||||
|
pwr4 = "", // Verbraucher
|
||||||
|
pwr5 = Math.round(getState("hm-rpc.0.MEQ0706303.1.POWER").val), // Stromnetz
|
||||||
|
pwr6 = 0, // Auto
|
||||||
|
pwrHome = Math.round(pwr5 - pwr2); // Berechnung des Energiefluss anstelle eines Datenpunktes
|
||||||
|
|
||||||
|
// Definition der Keys im JSON
|
||||||
|
var keys = ["id", "value", "unit", "icon", "iconColor", "speed"];
|
||||||
|
|
||||||
|
// Definition der "Kacheln", inkl. StandardIcon. Es können alle Icon aus dem Iconmapping genutzt werden.
|
||||||
|
// Kacheln die nicht genutzt werden sollen, müssen wie z.b. item1 formatiert sein
|
||||||
|
var home = [0, pwrHome, "W", "home-lightning-bolt-outline", 0]; // Icon home
|
||||||
|
var item1 = [1, pwr1, "", "", 0, ""]; // Icon battery-charging-60
|
||||||
|
var item2 = [2, pwr2, "W", "solar-power-variant-outline", 3, pwr2 > 0 ? -2 : 0]; // Icon solar-power-variant
|
||||||
|
var item3 = [3, pwr3, "", "", 0, ""]; // Icon wind-turbine
|
||||||
|
var item4 = [4, pwr4, "", "", 0, ""]; // Icon shape
|
||||||
|
var item5 = [5, pwr5, "W", "transmission-tower", 10, 10]; // Icon transmission-tower
|
||||||
|
var item6 = [6, pwr6, "kW", "car-electric-outline", 5, 0]; // Icon car
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JSON generieren und in den Datenpunkt schreiben,
|
||||||
|
*
|
||||||
|
* --- ab hier keine Änderungen mehr ---
|
||||||
|
*/
|
||||||
|
function func(tags, values) {
|
||||||
|
return Object.assign(
|
||||||
|
...tags.map((element, index) => ({ [element]: values[index] }))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(
|
||||||
|
powerCardJson,
|
||||||
|
JSON.stringify([
|
||||||
|
func(keys, home),
|
||||||
|
func(keys, item1),
|
||||||
|
func(keys, item2),
|
||||||
|
func(keys, item3),
|
||||||
|
func(keys, item4),
|
||||||
|
func(keys, item5),
|
||||||
|
func(keys, item6),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
});
|
||||||
46
ioBroker/Blockly/Countdown_Timer.ts
Normal file
46
ioBroker/Blockly/Countdown_Timer.ts
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
const dp_userdata: string = '0_userdata.0.NSPanel';
|
||||||
|
const dp_alias: string = 'alias.0.NSPanel';
|
||||||
|
|
||||||
|
// Der nachfolgende Datenpunkt muss manuell angelegt werden
|
||||||
|
const dpAction: string = '0_userdata.0.example_boolean'; // anpassen
|
||||||
|
|
||||||
|
const Debug = false;
|
||||||
|
|
||||||
|
let intervallCounter: any;
|
||||||
|
|
||||||
|
let sec_timer = getState(dp_userdata + '.Countdown.Time').val;
|
||||||
|
on({ id: dp_userdata + '.Countdown.State', change: 'ne' }, async (obj) => {
|
||||||
|
|
||||||
|
switch (obj.state.val) {
|
||||||
|
case 'active':
|
||||||
|
if (intervallCounter) { clearInterval(intervallCounter); intervallCounter = null; };
|
||||||
|
intervallCounter = setInterval(async () => {
|
||||||
|
if (getState(dp_userdata + '.Countdown.Time').val > 0) {
|
||||||
|
sec_timer = getState(dp_userdata + '.Countdown.Time').val;
|
||||||
|
setState(dp_userdata + '.Countdown.Time', (sec_timer - 1), false);
|
||||||
|
} else {
|
||||||
|
setState(dp_userdata + '.Countdown.Time', 0, false);
|
||||||
|
setState(dp_userdata + '.Countdown.State', 'idle', false);
|
||||||
|
// An dieser Stelle kann auch noch eine Meldung an Alexa oder Telegram, etc. erfolgen
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (intervallCounter) { clearInterval(intervallCounter); intervallCounter = null; };
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
async function Init_Datenpunkte() {
|
||||||
|
if (existsState(dp_alias + '.Countdown.ACTUAL') == false) {
|
||||||
|
await createStateAsync(dp_userdata + '.Countdown.Time', '0', { type: 'number'});
|
||||||
|
await createStateAsync(dp_userdata + '.Countdown.State', 'paused', { type: 'string' });
|
||||||
|
setObject(dp_alias + '.Countdown', { type: 'channel', common: { role: 'level.timer', name: 'Countdown' }, native: {} });
|
||||||
|
await createAliasAsync(dp_alias + '.Countdown.ACTUAL', dp_userdata + '.Countdown.Time', true, <iobJS.StateCommon>{ type: 'number', role: 'state', name: 'ACTUAL' });
|
||||||
|
await createAliasAsync(dp_alias + '.Countdown.STATE', dp_userdata + '.Countdown.State', true, <iobJS.StateCommon>{ type: 'string', role: 'state', name: 'STATE' });
|
||||||
|
log("<PageItem>{id: '"+ dp_alias + ".Countdown', name: 'Timer'}", 'info');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Init_Datenpunkte();
|
||||||
15587
ioBroker/DEV/NSPanelTs.ts
Normal file
15587
ioBroker/DEV/NSPanelTs.ts
Normal file
File diff suppressed because it is too large
Load Diff
BIN
ioBroker/HMI/nspanel-us-l-v4.5.0.HMI
Normal file
BIN
ioBroker/HMI/nspanel-us-l-v4.5.0.HMI
Normal file
Binary file not shown.
BIN
ioBroker/HMI/nspanel-us-p-v4.5.0.HMI
Normal file
BIN
ioBroker/HMI/nspanel-us-p-v4.5.0.HMI
Normal file
Binary file not shown.
BIN
ioBroker/HMI/nspanel-v4.5.0.HMI
Normal file
BIN
ioBroker/HMI/nspanel-v4.5.0.HMI
Normal file
Binary file not shown.
16698
ioBroker/NsPanelTs.ts
16698
ioBroker/NsPanelTs.ts
File diff suppressed because it is too large
Load Diff
@@ -1047,6 +1047,14 @@
|
|||||||
"zh-CN":"空闲",
|
"zh-CN":"空闲",
|
||||||
"zh-TW":"暫停"
|
"zh-TW":"暫停"
|
||||||
},
|
},
|
||||||
|
"on":{
|
||||||
|
"en-US":"On",
|
||||||
|
"de-DE":"Ein"
|
||||||
|
},
|
||||||
|
"off":{
|
||||||
|
"en-US":"Off",
|
||||||
|
"de-DE":"Aus"
|
||||||
|
},
|
||||||
"paused":{
|
"paused":{
|
||||||
"en-US":"Paused",
|
"en-US":"Paused",
|
||||||
"de-DE":"pausiert",
|
"de-DE":"pausiert",
|
||||||
@@ -2489,6 +2497,14 @@
|
|||||||
"vi-VN":"Mật khẩu",
|
"vi-VN":"Mật khẩu",
|
||||||
"zh-CN":"密码",
|
"zh-CN":"密码",
|
||||||
"zh-TW":"密碼"
|
"zh-TW":"密碼"
|
||||||
|
},
|
||||||
|
"Wlan enabled":{
|
||||||
|
"en-US":"Wlan enabled",
|
||||||
|
"de-DE":"Wlan aktiviert"
|
||||||
|
},
|
||||||
|
"Wlan disabled":{
|
||||||
|
"en-US":"Wlan disabled",
|
||||||
|
"de-DE":"Wlan deaktiviert"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"media":{
|
"media":{
|
||||||
@@ -2533,6 +2549,26 @@
|
|||||||
"zh-CN":"没有音乐可以控制",
|
"zh-CN":"没有音乐可以控制",
|
||||||
"zh-TW":"沒有音樂可以控制"
|
"zh-TW":"沒有音樂可以控制"
|
||||||
},
|
},
|
||||||
|
"on":{
|
||||||
|
"en-US":"On",
|
||||||
|
"de-DE":"An"
|
||||||
|
},
|
||||||
|
"off":{
|
||||||
|
"en-US":"Off",
|
||||||
|
"de-DE":"Aus"
|
||||||
|
},
|
||||||
|
"seek":{
|
||||||
|
"en-US":"Seek",
|
||||||
|
"de-DE":"Suchen"
|
||||||
|
},
|
||||||
|
"crossfade":{
|
||||||
|
"en-US":"Crossfade",
|
||||||
|
"de-DE":"Überblenden"
|
||||||
|
},
|
||||||
|
"tools":{
|
||||||
|
"en-US":"Tools",
|
||||||
|
"de-DE":"Tools"
|
||||||
|
},
|
||||||
"speaker":{
|
"speaker":{
|
||||||
"en-US":"Speakerlist",
|
"en-US":"Speakerlist",
|
||||||
"de-DE":"Wiedergabegeräte",
|
"de-DE":"Wiedergabegeräte",
|
||||||
|
|||||||
@@ -2693,5 +2693,21 @@
|
|||||||
"update_nextion_tft":{
|
"update_nextion_tft":{
|
||||||
"en-US":"Update Nextion TFT",
|
"en-US":"Update Nextion TFT",
|
||||||
"de-DE":"Nextion TFT Update"
|
"de-DE":"Nextion TFT Update"
|
||||||
|
},
|
||||||
|
"update_message":{
|
||||||
|
"en-US":"Update Notifications",
|
||||||
|
"de-DE":"Update Mitteilungen"
|
||||||
|
},
|
||||||
|
"scriptname":{
|
||||||
|
"en-US":"Script name",
|
||||||
|
"de-DE":"Skriptname"
|
||||||
|
},
|
||||||
|
"hiddencards_offon":{
|
||||||
|
"en-US":"hidden Cards (on/off)",
|
||||||
|
"de-DE":"ausgeblendete Seiten (an/aus)"
|
||||||
|
},
|
||||||
|
"easyview_layout":{
|
||||||
|
"en-US":"Easyview Layout",
|
||||||
|
"de-DE":"Einfaches Layout"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
28
ioBroker/tsconfig.json
Normal file
28
ioBroker/tsconfig.json
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"compileOnSave": true,
|
||||||
|
"compilerOptions": {
|
||||||
|
"noEmit": true,
|
||||||
|
"allowJs": true,
|
||||||
|
"checkJs": true,
|
||||||
|
"module": "commonjs",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"strict": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noImplicitAny": false,
|
||||||
|
"target": "ES2022",
|
||||||
|
"typeRoots": [
|
||||||
|
".iobroker/types",
|
||||||
|
"node_modules/@types"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"**/*.js",
|
||||||
|
"**/*.ts",
|
||||||
|
"./.iobroker/types/javascript.d.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules/**"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# https://developers.home-assistant.io/docs/add-ons/configuration#add-on-config
|
# https://developers.home-assistant.io/docs/add-ons/configuration#add-on-config
|
||||||
name: NSPanel Lovelace UI Addon
|
name: NSPanel Lovelace UI Addon
|
||||||
version: "4.7.54"
|
version: "4.7.80"
|
||||||
slug: nspanel-lovelace-ui
|
slug: nspanel-lovelace-ui
|
||||||
description: NSPanel Lovelace UI Addon
|
description: NSPanel Lovelace UI Addon
|
||||||
services:
|
services:
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ class HAEntity(panel_cards.Entity):
|
|||||||
self.state = data.get("state")
|
self.state = data.get("state")
|
||||||
self.attributes = data.get("attributes", [])
|
self.attributes = data.get("attributes", [])
|
||||||
else:
|
else:
|
||||||
|
self.state = "not found"
|
||||||
|
self.attributes = []
|
||||||
return "~text~iid.404~X~6666~not found~"
|
return "~text~iid.404~X~6666~not found~"
|
||||||
|
|
||||||
# HA Entities
|
# HA Entities
|
||||||
@@ -188,7 +190,7 @@ class HAEntity(panel_cards.Entity):
|
|||||||
icon_char = value
|
icon_char = value
|
||||||
case 'binary_sensor':
|
case 'binary_sensor':
|
||||||
device_class = self.attributes.get("device_class", "")
|
device_class = self.attributes.get("device_class", "")
|
||||||
value = get_translation(self.locale, f"backend.component.binary_sensor.state.{device_class}.{entity.state}")
|
value = get_translation(self.locale, f"backend.component.binary_sensor.state.{device_class}.{self.state}")
|
||||||
case 'weather':
|
case 'weather':
|
||||||
attr = self.config.get("attribute", "temperature")
|
attr = self.config.get("attribute", "temperature")
|
||||||
value = str(self.attributes.get(attr, self.state))
|
value = str(self.attributes.get(attr, self.state))
|
||||||
@@ -207,11 +209,11 @@ class HAEntity(panel_cards.Entity):
|
|||||||
forecast = libs.home_assistant.execute_script(
|
forecast = libs.home_assistant.execute_script(
|
||||||
entity_name=self.entity_id,
|
entity_name=self.entity_id,
|
||||||
domain='weather',
|
domain='weather',
|
||||||
service="get_forecast",
|
service="get_forecasts",
|
||||||
service_data={
|
service_data={
|
||||||
'type': forecast_type
|
'type': forecast_type
|
||||||
}
|
}
|
||||||
).get("forecast", [])
|
).get(self.entity_id,{}).get("forecast", [])
|
||||||
if len(forecast) > pos:
|
if len(forecast) > pos:
|
||||||
forcast_pos = forecast[pos]
|
forcast_pos = forecast[pos]
|
||||||
forcast_condition = forcast_pos.get("condition", "")
|
forcast_condition = forcast_pos.get("condition", "")
|
||||||
@@ -297,21 +299,19 @@ class EntitiesCard(HACard):
|
|||||||
result = f"{self.title}~{self.gen_nav()}"
|
result = f"{self.title}~{self.gen_nav()}"
|
||||||
for e in self.entities:
|
for e in self.entities:
|
||||||
result += e.render(cardType=self.type)
|
result += e.render(cardType=self.type)
|
||||||
libs.panel_cmd.entityUpd(self.panel.sendTopic, result)
|
libs.panel_cmd.entityUpd(self.panel.msg_out_queue, self.panel.sendTopic, result)
|
||||||
|
|
||||||
class QRCard(HACard):
|
class QRCard(HACard):
|
||||||
def __init__(self, locale, config, panel):
|
def __init__(self, locale, config, panel):
|
||||||
super().__init__(locale, config, panel)
|
super().__init__(locale, config, panel)
|
||||||
self.qrcode = config.get("qrCode", "https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
self.qrcode = config.get("qrCode", "https://www.youtube.com/watch?v=dQw4w9WgXcQ")
|
||||||
def render(self):
|
def render(self):
|
||||||
# TODO: Render QRCode as HomeAssistant Template
|
|
||||||
#qrcode = apis.ha_api.render_template(qrcode)
|
|
||||||
if self.qrcode.startswith("ha:"):
|
if self.qrcode.startswith("ha:"):
|
||||||
self.qrcode = libs.home_assistant.get_template(self.qrcode)[3:]
|
self.qrcode = libs.home_assistant.get_template(self.qrcode)[3:]
|
||||||
result = f"{self.title}~{self.gen_nav()}~{self.qrcode}"
|
result = f"{self.title}~{self.gen_nav()}~{self.qrcode}"
|
||||||
for e in self.entities:
|
for e in self.entities:
|
||||||
result += e.render()
|
result += e.render()
|
||||||
libs.panel_cmd.entityUpd(self.panel.sendTopic, result)
|
libs.panel_cmd.entityUpd(self.panel.msg_out_queue, self.panel.sendTopic, result)
|
||||||
|
|
||||||
class PowerCard(HACard):
|
class PowerCard(HACard):
|
||||||
def __init__(self, locale, config, panel):
|
def __init__(self, locale, config, panel):
|
||||||
@@ -329,7 +329,7 @@ class PowerCard(HACard):
|
|||||||
# if isinstance(speed, str):
|
# if isinstance(speed, str):
|
||||||
# speed = apis.ha_api.render_template(speed)
|
# speed = apis.ha_api.render_template(speed)
|
||||||
result += f"~{speed}"
|
result += f"~{speed}"
|
||||||
libs.panel_cmd.entityUpd(self.panel.sendTopic, result)
|
libs.panel_cmd.entityUpd(self.panel.msg_out_queue, self.panel.sendTopic, result)
|
||||||
|
|
||||||
class MediaCard(HACard):
|
class MediaCard(HACard):
|
||||||
def __init__(self, locale, config, panel):
|
def __init__(self, locale, config, panel):
|
||||||
@@ -366,7 +366,7 @@ class MediaCard(HACard):
|
|||||||
for e in self.entities[1:]:
|
for e in self.entities[1:]:
|
||||||
button_str += e.render()
|
button_str += e.render()
|
||||||
result = f"{self.title}~{self.gen_nav()}~{main_entity.entity_id}~{title}~~{author}~~{volume}~{iconplaypause}~{onoffbutton}~{shuffleBtn}{media_icon}{button_str}"
|
result = f"{self.title}~{self.gen_nav()}~{main_entity.entity_id}~{title}~~{author}~~{volume}~{iconplaypause}~{onoffbutton}~{shuffleBtn}{media_icon}{button_str}"
|
||||||
libs.panel_cmd.entityUpd(self.panel.sendTopic, result)
|
libs.panel_cmd.entityUpd(self.panel.msg_out_queue, self.panel.sendTopic, result)
|
||||||
|
|
||||||
class ClimateCard(HACard):
|
class ClimateCard(HACard):
|
||||||
def __init__(self, locale, config, panel):
|
def __init__(self, locale, config, panel):
|
||||||
@@ -375,9 +375,8 @@ class ClimateCard(HACard):
|
|||||||
def render(self):
|
def render(self):
|
||||||
main_entity = self.entities[0]
|
main_entity = self.entities[0]
|
||||||
|
|
||||||
#TODO: temp unit
|
temp_unit = self.panel.temp_unit
|
||||||
temp_unit = "celsius"
|
if temp_unit == "celsius":
|
||||||
if(temp_unit == "celsius"):
|
|
||||||
temperature_unit_icon = get_icon_char("temperature-celsius")
|
temperature_unit_icon = get_icon_char("temperature-celsius")
|
||||||
temperature_unit = "°C"
|
temperature_unit = "°C"
|
||||||
|
|
||||||
@@ -411,7 +410,12 @@ class ClimateCard(HACard):
|
|||||||
|
|
||||||
min_temp = int(main_entity.attributes.get("min_temp", 0)*10)
|
min_temp = int(main_entity.attributes.get("min_temp", 0)*10)
|
||||||
max_temp = int(main_entity.attributes.get("max_temp", 0)*10)
|
max_temp = int(main_entity.attributes.get("max_temp", 0)*10)
|
||||||
step_temp = int(main_entity.attributes.get("target_temp_step", 0.5)*10)
|
|
||||||
|
if temp_unit == "celsius":
|
||||||
|
step_default = 0.5
|
||||||
|
else:
|
||||||
|
step_default = 0.5
|
||||||
|
step_temp = int(main_entity.attributes.get("target_temp_step", step_default)*10)
|
||||||
icon_res_list = []
|
icon_res_list = []
|
||||||
icon_res = ""
|
icon_res = ""
|
||||||
|
|
||||||
@@ -460,8 +464,8 @@ class ClimateCard(HACard):
|
|||||||
if any(x in ["preset_modes", "swing_modes", "fan_modes"] for x in main_entity.attributes):
|
if any(x in ["preset_modes", "swing_modes", "fan_modes"] for x in main_entity.attributes):
|
||||||
detailPage = "0"
|
detailPage = "0"
|
||||||
|
|
||||||
result = f"{self.title}~{self.gen_nav()}~{main_entity.entity_id}~{current_temp} {temperature_unit}~{dest_temp}~{state_value}~{min_temp}~{max_temp}~{step_temp}{icon_res}~{currently_translation}~{state_translation}~{action_translation}~{temperature_unit_icon}~{dest_temp2}~{detailPage}"
|
result = f"{self.title}~{self.gen_nav()}~iid.{main_entity.iid}~{current_temp} {temperature_unit}~{dest_temp}~{state_value}~{min_temp}~{max_temp}~{step_temp}{icon_res}~{currently_translation}~{state_translation}~{action_translation}~{temperature_unit_icon}~{dest_temp2}~{detailPage}"
|
||||||
libs.panel_cmd.entityUpd(self.panel.sendTopic, result)
|
libs.panel_cmd.entityUpd(self.panel.msg_out_queue, self.panel.sendTopic, result)
|
||||||
|
|
||||||
class AlarmCard(HACard):
|
class AlarmCard(HACard):
|
||||||
def __init__(self, locale, config, panel):
|
def __init__(self, locale, config, panel):
|
||||||
@@ -471,6 +475,8 @@ class AlarmCard(HACard):
|
|||||||
main_entity = self.entities[0]
|
main_entity = self.entities[0]
|
||||||
main_entity.render()
|
main_entity.render()
|
||||||
|
|
||||||
|
print(main_entity.state)
|
||||||
|
|
||||||
icon = get_icon_char("shield-off")
|
icon = get_icon_char("shield-off")
|
||||||
color = rgb_dec565([255,255,255])
|
color = rgb_dec565([255,255,255])
|
||||||
supported_modes = []
|
supported_modes = []
|
||||||
@@ -531,7 +537,7 @@ class AlarmCard(HACard):
|
|||||||
if len(supported_modes) < 4:
|
if len(supported_modes) < 4:
|
||||||
arm_buttons += "~"*((4-len(supported_modes))*2)
|
arm_buttons += "~"*((4-len(supported_modes))*2)
|
||||||
result = f"{self.title}~{self.gen_nav()}~{main_entity.entity_id}{arm_buttons}~{icon}~{color}~{numpad}~{flashing}~{add_btn}"
|
result = f"{self.title}~{self.gen_nav()}~{main_entity.entity_id}{arm_buttons}~{icon}~{color}~{numpad}~{flashing}~{add_btn}"
|
||||||
libs.panel_cmd.entityUpd(self.panel.sendTopic, result)
|
libs.panel_cmd.entityUpd(self.panel.msg_out_queue, self.panel.sendTopic, result)
|
||||||
|
|
||||||
|
|
||||||
class UnlockCard(HACard):
|
class UnlockCard(HACard):
|
||||||
@@ -544,7 +550,7 @@ class UnlockCard(HACard):
|
|||||||
icon = get_icon_char("lock")
|
icon = get_icon_char("lock")
|
||||||
supported_modes = ["cardUnlock-unlock"]
|
supported_modes = ["cardUnlock-unlock"]
|
||||||
|
|
||||||
entity_id = self.config.get("entity")
|
entity_id = self.config.get("destination")
|
||||||
|
|
||||||
# add padding to arm buttons
|
# add padding to arm buttons
|
||||||
arm_buttons = ""
|
arm_buttons = ""
|
||||||
@@ -555,7 +561,7 @@ class UnlockCard(HACard):
|
|||||||
numpad = "enable"
|
numpad = "enable"
|
||||||
|
|
||||||
result = f"{self.title}~{self.gen_nav()}~{entity_id}{arm_buttons}~{icon}~{color}~{numpad}~disable~"
|
result = f"{self.title}~{self.gen_nav()}~{entity_id}{arm_buttons}~{icon}~{color}~{numpad}~disable~"
|
||||||
libs.panel_cmd.entityUpd(self.panel.sendTopic, result)
|
libs.panel_cmd.entityUpd(self.panel.msg_out_queue, self.panel.sendTopic, result)
|
||||||
|
|
||||||
class Screensaver(HACard):
|
class Screensaver(HACard):
|
||||||
def __init__(self, locale, config, panel):
|
def __init__(self, locale, config, panel):
|
||||||
@@ -583,7 +589,7 @@ class Screensaver(HACard):
|
|||||||
result = ""
|
result = ""
|
||||||
for e in self.entities:
|
for e in self.entities:
|
||||||
result += e.render(cardType=self.type)
|
result += e.render(cardType=self.type)
|
||||||
libs.panel_cmd.weatherUpdate(self.panel.sendTopic, result[1:])
|
libs.panel_cmd.weatherUpdate(self.panel.msg_out_queue, self.panel.sendTopic, result[1:])
|
||||||
|
|
||||||
statusUpdateResult = ""
|
statusUpdateResult = ""
|
||||||
icon1font = ""
|
icon1font = ""
|
||||||
@@ -601,7 +607,7 @@ class Screensaver(HACard):
|
|||||||
else:
|
else:
|
||||||
statusUpdateResult += "~~"
|
statusUpdateResult += "~~"
|
||||||
|
|
||||||
libs.panel_cmd.statusUpdate(self.panel.sendTopic, f"{statusUpdateResult}~{icon1font}~{icon2font}")
|
libs.panel_cmd.statusUpdate(self.panel.msg_out_queue, self.panel.sendTopic, f"{statusUpdateResult}~{icon1font}~{icon2font}")
|
||||||
|
|
||||||
|
|
||||||
def card_factory(locale, settings, panel):
|
def card_factory(locale, settings, panel):
|
||||||
@@ -625,7 +631,7 @@ def card_factory(locale, settings, panel):
|
|||||||
return "NotImplemented", None
|
return "NotImplemented", None
|
||||||
return card.iid, card
|
return card.iid, card
|
||||||
|
|
||||||
def detail_open(locale, detail_type, ha_entity_id, entity_id, sendTopic=None):
|
def detail_open(locale, detail_type, ha_entity_id, entity_id, msg_out_queue, sendTopic=None, options_list=None):
|
||||||
data = libs.home_assistant.get_entity_data(ha_entity_id)
|
data = libs.home_assistant.get_entity_data(ha_entity_id)
|
||||||
if data:
|
if data:
|
||||||
state = data.get("state")
|
state = data.get("state")
|
||||||
@@ -762,9 +768,51 @@ def detail_open(locale, detail_type, ha_entity_id, entity_id, sendTopic=None):
|
|||||||
|
|
||||||
return f'{entity_id}~~{icon_color}~{switch_val}~{speed}~{speedMax}~{speed_translation}~{preset_mode}~{preset_modes}'
|
return f'{entity_id}~~{icon_color}~{switch_val}~{speed}~{speedMax}~{speed_translation}~{preset_mode}~{preset_modes}'
|
||||||
case 'popupThermo' | 'climate':
|
case 'popupThermo' | 'climate':
|
||||||
print(f"not implemented {detail_type}")
|
icon_id = ha_icons.get_icon_ha("climate", state)
|
||||||
case 'popupInSel' | 'input_select' | 'select':
|
icon_color = ha_colors.get_entity_color("climate", state, attributes)
|
||||||
print(f"not implemented {detail_type}")
|
|
||||||
|
modes_out = ""
|
||||||
|
for mode in ["preset_modes", "swing_modes", "fan_modes"]:
|
||||||
|
heading = get_translation(locale, f"frontend.ui.card.climate.{mode[:-1]}")
|
||||||
|
cur_mode = attributes.get(mode[:-1], "")
|
||||||
|
modes = attributes.get(mode, [])
|
||||||
|
if modes is not None:
|
||||||
|
if mode == "preset_modes":
|
||||||
|
translated_modes = []
|
||||||
|
for elem in modes:
|
||||||
|
translated_modes.append(get_translation(locale, f"frontend.state_attributes.climate.preset_mode.{elem}"))
|
||||||
|
cur_mode = get_translation(locale, f"frontend.state_attributes.climate.preset_mode.{cur_mode}")
|
||||||
|
modes_res = "?".join(translated_modes)
|
||||||
|
else:
|
||||||
|
modes_res = "?".join(modes)
|
||||||
|
if modes:
|
||||||
|
modes_out += f"{heading}~{mode}~{cur_mode}~{modes_res}~"
|
||||||
|
|
||||||
|
return f"{entity_id}~{icon_id}~{icon_color}~{modes_out}"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
case 'popupInSel' | 'input_select' | 'select' | 'media_player':
|
||||||
|
hatype = ha_entity_id.split(".")[0]
|
||||||
|
options = []
|
||||||
|
icon_color = 0
|
||||||
|
icon_color = ha_colors.get_entity_color(detail_type, state, attributes)
|
||||||
|
state = state
|
||||||
|
if hatype in ["input_select", "select"]:
|
||||||
|
options = attributes.get("options", [])
|
||||||
|
elif hatype == "light":
|
||||||
|
if options_list is not None:
|
||||||
|
options = options_list
|
||||||
|
else:
|
||||||
|
options = attributes.get("effect_list", [])[:15]
|
||||||
|
state = attributes.get("effect")
|
||||||
|
elif hatype == "media_player":
|
||||||
|
state = attributes.get("source", "")
|
||||||
|
options = attributes.get("source_list", [])
|
||||||
|
options = "?".join(options)
|
||||||
|
return f"{entity_id}~~{icon_color}~{hatype}~{state}~{options}~"
|
||||||
|
|
||||||
|
|
||||||
case 'popupTimer' | 'timer':
|
case 'popupTimer' | 'timer':
|
||||||
icon_color = ha_colors.get_entity_color("timer", state, attributes)
|
icon_color = ha_colors.get_entity_color("timer", state, attributes)
|
||||||
if state in ["idle", "paused"]:
|
if state in ["idle", "paused"]:
|
||||||
@@ -787,8 +835,8 @@ def detail_open(locale, detail_type, ha_entity_id, entity_id, sendTopic=None):
|
|||||||
#update timer in a second
|
#update timer in a second
|
||||||
def update_time():
|
def update_time():
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
out = detail_open(locale, detail_type, ha_entity_id, entity_id, sendTopic=sendTopic)
|
out = detail_open(locale, detail_type, ha_entity_id, entity_id, msg_out_queue, sendTopic=sendTopic)
|
||||||
libs.panel_cmd.entityUpdateDetail(sendTopic, out)
|
libs.panel_cmd.entityUpdateDetail(msg_out_queue, sendTopic, out)
|
||||||
tt = threading.Thread(target=update_time, args=())
|
tt = threading.Thread(target=update_time, args=())
|
||||||
tt.daemon = True
|
tt.daemon = True
|
||||||
tt.start()
|
tt.start()
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ def wait_for_ha_cache():
|
|||||||
while time.time() < mustend:
|
while time.time() < mustend:
|
||||||
if len(libs.home_assistant.home_assistant_entity_state_cache) == 0:
|
if len(libs.home_assistant.home_assistant_entity_state_cache) == 0:
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
def calculate_dim_values(sleepTracking, sleepTrackingZones, sleepBrightness, screenBrightness, sleepOverride, return_involved_entities=False):
|
def calculate_dim_values(sleepTracking, sleepTrackingZones, sleepBrightness, screenBrightness, sleepOverride, return_involved_entities=False):
|
||||||
dimmode = 10
|
dimmode = 10
|
||||||
@@ -17,17 +18,34 @@ def calculate_dim_values(sleepTracking, sleepTrackingZones, sleepBrightness, scr
|
|||||||
if sleepBrightness:
|
if sleepBrightness:
|
||||||
if isinstance(sleepBrightness, int):
|
if isinstance(sleepBrightness, int):
|
||||||
dimmode = sleepBrightness
|
dimmode = sleepBrightness
|
||||||
|
elif isinstance(sleepBrightness, list):
|
||||||
|
logging.error("list style config for sleepBrightness no longer supported")
|
||||||
|
#elif sleepBrightness.startswith("ha:"):
|
||||||
|
# time.sleep(1)
|
||||||
|
# dimmode = int(float(libs.home_assistant.get_template(sleepBrightness)[3:]))
|
||||||
|
# involved_entities.extend(libs.home_assistant.get_template_listener_entities(sleepBrightness))
|
||||||
elif libs.home_assistant.is_existent(sleepBrightness):
|
elif libs.home_assistant.is_existent(sleepBrightness):
|
||||||
involved_entities.append(sleepBrightness)
|
involved_entities.append(sleepBrightness)
|
||||||
dimmode = int(float(libs.home_assistant.get_entity_data(sleepBrightness).get('state', 10)))
|
try:
|
||||||
|
dimmode = int(float(libs.home_assistant.get_entity_data(sleepBrightness).get('state', 10)))
|
||||||
|
except ValueError:
|
||||||
|
print("sleepBrightness entity invalid")
|
||||||
|
|
||||||
if screenBrightness:
|
if screenBrightness:
|
||||||
if isinstance(screenBrightness, int):
|
if isinstance(screenBrightness, int):
|
||||||
dimValueNormal = screenBrightness
|
dimValueNormal = screenBrightness
|
||||||
|
elif isinstance(screenBrightness, list):
|
||||||
|
logging.error("list style config for screenBrightness no longer supported")
|
||||||
|
#elif screenBrightness.startswith("ha:"):
|
||||||
|
# time.sleep(1)
|
||||||
|
# dimValueNormal = int(float(libs.home_assistant.get_template(screenBrightness)[3:]))
|
||||||
|
# involved_entities.extend(libs.home_assistant.get_template_listener_entities(screenBrightness))
|
||||||
elif libs.home_assistant.is_existent(screenBrightness):
|
elif libs.home_assistant.is_existent(screenBrightness):
|
||||||
involved_entities.append(screenBrightness)
|
involved_entities.append(screenBrightness)
|
||||||
dimValueNormal = int(float(libs.home_assistant.get_entity_data(screenBrightness).get('state', 100)))
|
try:
|
||||||
|
dimValueNormal = int(float(libs.home_assistant.get_entity_data(screenBrightness).get('state', 100)))
|
||||||
|
except ValueError:
|
||||||
|
print("screenBrightness entity invalid")
|
||||||
# force sleep brightness to zero in case sleepTracking is active
|
# force sleep brightness to zero in case sleepTracking is active
|
||||||
if sleepTracking:
|
if sleepTracking:
|
||||||
if libs.home_assistant.is_existent(sleepTracking):
|
if libs.home_assistant.is_existent(sleepTracking):
|
||||||
@@ -51,7 +69,7 @@ def calculate_dim_values(sleepTracking, sleepTrackingZones, sleepBrightness, scr
|
|||||||
else:
|
else:
|
||||||
return dimmode, dimValueNormal
|
return dimmode, dimValueNormal
|
||||||
|
|
||||||
def handle_buttons(entity_id, btype, value):
|
def handle_buttons(entity_id, btype, value, entity_config=None):
|
||||||
match btype:
|
match btype:
|
||||||
case 'button':
|
case 'button':
|
||||||
button_press(entity_id, value)
|
button_press(entity_id, value)
|
||||||
@@ -60,7 +78,7 @@ def handle_buttons(entity_id, btype, value):
|
|||||||
case 'number-set':
|
case 'number-set':
|
||||||
if entity_id.startswith('fan'):
|
if entity_id.startswith('fan'):
|
||||||
attr = libs.home_assistant.get_entity_data(entity_id).get('attributes', [])
|
attr = libs.home_assistant.get_entity_data(entity_id).get('attributes', [])
|
||||||
value = float(value) * float(attr.get(percentage_step, 0))
|
value = float(value) * float(attr.get('percentage_step', 0))
|
||||||
service_data = {
|
service_data = {
|
||||||
"value": int(value)
|
"value": int(value)
|
||||||
}
|
}
|
||||||
@@ -156,19 +174,20 @@ def handle_buttons(entity_id, btype, value):
|
|||||||
}
|
}
|
||||||
call_ha_service(entity_id, f"alarm_{btype}", service_data=service_data)
|
call_ha_service(entity_id, f"alarm_{btype}", service_data=service_data)
|
||||||
case 'mode-preset_modes' | 'mode-swing_modes' | 'mode-fan_modes':
|
case 'mode-preset_modes' | 'mode-swing_modes' | 'mode-fan_modes':
|
||||||
|
attr = libs.home_assistant.get_entity_data(entity_id).get('attributes', [])
|
||||||
mapping = {
|
mapping = {
|
||||||
'mode-preset_modes': 'preset_modes',
|
'mode-preset_modes': 'preset_modes',
|
||||||
'mode-swing_modes': 'swing_modes',
|
'mode-swing_modes': 'swing_modes',
|
||||||
'mode-fan_modes': 'fan_mode'
|
'mode-fan_modes': 'fan_modes'
|
||||||
}
|
}
|
||||||
if btype in mapping:
|
if btype in mapping:
|
||||||
modes = libs.home_assistant.get_entity_data(entity_id).get('attributes', []).get(mapping[btype], [])
|
modes = attr.get(mapping[btype], [])
|
||||||
if modes:
|
if modes:
|
||||||
mode = modes[int(value)]
|
mode = modes[int(value)]
|
||||||
service_data = {
|
service_data = {
|
||||||
mapping[btype]: mode
|
mapping[btype][:-1]: mode
|
||||||
}
|
}
|
||||||
call_ha_service(entity_id, f"set_{mapping[btype]}", service_data=service_data)
|
call_ha_service(entity_id, f"set_{mapping[btype][:-1]}", service_data=service_data)
|
||||||
case 'mode-input_select' | 'mode-select':
|
case 'mode-input_select' | 'mode-select':
|
||||||
options = libs.home_assistant.get_entity_data(entity_id).get('attributes', []).get("options", [])
|
options = libs.home_assistant.get_entity_data(entity_id).get('attributes', []).get("options", [])
|
||||||
if options:
|
if options:
|
||||||
@@ -186,7 +205,7 @@ def handle_buttons(entity_id, btype, value):
|
|||||||
}
|
}
|
||||||
call_ha_service(entity_id, "select_source", service_data=service_data)
|
call_ha_service(entity_id, "select_source", service_data=service_data)
|
||||||
case 'mode-light':
|
case 'mode-light':
|
||||||
options = libs.home_assistant.get_entity_data(entity_id).get('attributes', []).get("effect_list", [])
|
options = entity_config.get("effectList", libs.home_assistant.get_entity_data(entity_id).get('attributes', []).get("effect_list", []))
|
||||||
if options:
|
if options:
|
||||||
option = options[int(value)]
|
option = options[int(value)]
|
||||||
service_data = {
|
service_data = {
|
||||||
@@ -216,30 +235,6 @@ def handle_buttons(entity_id, btype, value):
|
|||||||
case _:
|
case _:
|
||||||
logging.error("Not implemented: %s", btype)
|
logging.error("Not implemented: %s", btype)
|
||||||
|
|
||||||
|
|
||||||
# # for cardUnlock
|
|
||||||
# if button_type == "cardUnlock-unlock":
|
|
||||||
# curCard = self._config.get_card_by_uuid(
|
|
||||||
# entity_id.replace('navigate.', ''))
|
|
||||||
# if curCard is not None:
|
|
||||||
# if int(curCard.raw_config.get("pin")) == int(value):
|
|
||||||
# dstCard = self._config.search_card(
|
|
||||||
# curCard.raw_config.get("destination"))
|
|
||||||
# if dstCard is not None:
|
|
||||||
# if dstCard.hidden:
|
|
||||||
# self._previous_cards.append(self._current_card)
|
|
||||||
# self._current_card = dstCard
|
|
||||||
# self._pages_gen.render_card(self._current_card)
|
|
||||||
|
|
||||||
# if button_type == "opnSensorNotify":
|
|
||||||
# msg = ""
|
|
||||||
# entity = apis.ha_api.get_entity(entity_id)
|
|
||||||
# if "open_sensors" in entity.attributes and entity.attributes.open_sensors is not None:
|
|
||||||
# for e in entity.attributes.open_sensors:
|
|
||||||
# msg += f"- {apis.ha_api.get_entity(e).attributes.friendly_name}\r\n"
|
|
||||||
# self._pages_gen.send_message_page(
|
|
||||||
# "opnSensorNotifyRes", "", msg, "", "")
|
|
||||||
|
|
||||||
def call_ha_service(entity_id, service, service_data = {}):
|
def call_ha_service(entity_id, service, service_data = {}):
|
||||||
etype = entity_id.split(".")[0]
|
etype = entity_id.split(".")[0]
|
||||||
libs.home_assistant.call_service(
|
libs.home_assistant.call_service(
|
||||||
|
|||||||
@@ -70,7 +70,8 @@ def on_message(ws, message):
|
|||||||
for template, template_cache_entry in template_cache.items():
|
for template, template_cache_entry in template_cache.items():
|
||||||
if entity_id in template_cache_entry.get("listener-entities", []):
|
if entity_id in template_cache_entry.get("listener-entities", []):
|
||||||
cache_template(template)
|
cache_template(template)
|
||||||
|
elif json_msg["type"] == "event" and json_msg["event"]["event_type"] == "esphome.nspanel.data":
|
||||||
|
nspanel_data_callback(json_msg["event"]["data"]["device_id"], json_msg["event"]["data"]["CustomRecv"])
|
||||||
elif json_msg["type"] == "result" and not json_msg["success"]:
|
elif json_msg["type"] == "result" and not json_msg["success"]:
|
||||||
logging.error("Failed result: ")
|
logging.error("Failed result: ")
|
||||||
logging.error(json_msg)
|
logging.error(json_msg)
|
||||||
@@ -143,6 +144,15 @@ def subscribe_to_events():
|
|||||||
}
|
}
|
||||||
send_message(json.dumps(msg))
|
send_message(json.dumps(msg))
|
||||||
|
|
||||||
|
def subscribe_to_nspanel_events(nsp_callback):
|
||||||
|
global next_id, nspanel_data_callback
|
||||||
|
nspanel_data_callback = nsp_callback
|
||||||
|
msg = {
|
||||||
|
"id": next_id,
|
||||||
|
"type": "subscribe_events",
|
||||||
|
"event_type": "esphome.nspanel.data"
|
||||||
|
}
|
||||||
|
send_message(json.dumps(msg))
|
||||||
|
|
||||||
def _get_all_states():
|
def _get_all_states():
|
||||||
global next_id, request_all_states_id
|
global next_id, request_all_states_id
|
||||||
@@ -158,6 +168,10 @@ def send_entity_update(entity_id):
|
|||||||
global on_ha_update
|
global on_ha_update
|
||||||
on_ha_update(entity_id)
|
on_ha_update(entity_id)
|
||||||
|
|
||||||
|
def nspanel_data_callback(device_id, msg):
|
||||||
|
global nspanel_data_callback
|
||||||
|
nspanel_data_callback(device_id, msg)
|
||||||
|
|
||||||
def call_service(entity_name: str, domain: str, service: str, service_data: dict) -> bool:
|
def call_service(entity_name: str, domain: str, service: str, service_data: dict) -> bool:
|
||||||
global next_id
|
global next_id
|
||||||
try:
|
try:
|
||||||
@@ -177,6 +191,22 @@ def call_service(entity_name: str, domain: str, service: str, service_data: dict
|
|||||||
logging.exception("Failed to call Home Assisatant service.")
|
logging.exception("Failed to call Home Assisatant service.")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def send_msg_to_panel(service: str, service_data: dict) -> bool:
|
||||||
|
global next_id
|
||||||
|
try:
|
||||||
|
msg = {
|
||||||
|
"id": next_id,
|
||||||
|
"type": "call_service",
|
||||||
|
"domain": "esphome",
|
||||||
|
"service": service,
|
||||||
|
"service_data": service_data,
|
||||||
|
}
|
||||||
|
send_message(json.dumps(msg))
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
logging.exception("Failed to call Home Assisatant service.")
|
||||||
|
return False
|
||||||
|
|
||||||
def execute_script(entity_name: str, domain: str, service: str, service_data: dict) -> str:
|
def execute_script(entity_name: str, domain: str, service: str, service_data: dict) -> str:
|
||||||
global next_id, response_buffer
|
global next_id, response_buffer
|
||||||
try:
|
try:
|
||||||
@@ -202,7 +232,7 @@ def execute_script(entity_name: str, domain: str, service: str, service_data: di
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
send_message(json.dumps(msg))
|
send_message(json.dumps(msg))
|
||||||
# busy waiting for response with a timeout of 0.2 seconds - maybe there's a better way of doing this
|
# busy waiting for response with a timeout of 0.4 seconds- maybe there's a better way of doing this
|
||||||
mustend = time.time() + 0.4
|
mustend = time.time() + 0.4
|
||||||
while time.time() < mustend:
|
while time.time() < mustend:
|
||||||
if response_buffer[call_id] == True:
|
if response_buffer[call_id] == True:
|
||||||
@@ -216,6 +246,8 @@ def execute_script(entity_name: str, domain: str, service: str, service_data: di
|
|||||||
return {}
|
return {}
|
||||||
|
|
||||||
def cache_template(template):
|
def cache_template(template):
|
||||||
|
if not template:
|
||||||
|
raise Exception("Invalid template")
|
||||||
global next_id, response_buffer
|
global next_id, response_buffer
|
||||||
try:
|
try:
|
||||||
call_id = next_id
|
call_id = next_id
|
||||||
@@ -243,6 +275,18 @@ def get_template(template):
|
|||||||
else:
|
else:
|
||||||
return template_cache.get(template, []).get("result", "404")
|
return template_cache.get(template, []).get("result", "404")
|
||||||
|
|
||||||
|
def get_template_listener_entities(template):
|
||||||
|
global template_cache
|
||||||
|
if template in template_cache:
|
||||||
|
return template_cache[template].get("listener-entities")
|
||||||
|
else:
|
||||||
|
mustend = time.time() + 0.5
|
||||||
|
while time.time() < mustend:
|
||||||
|
if template not in template_cache:
|
||||||
|
time.sleep(0.0001)
|
||||||
|
else:
|
||||||
|
return template_cache.get(template, []).get("listener-entities", "404")
|
||||||
|
|
||||||
def get_entity_data(entity_id: str):
|
def get_entity_data(entity_id: str):
|
||||||
if entity_id in home_assistant_entity_state_cache:
|
if entity_id in home_assistant_entity_state_cache:
|
||||||
return home_assistant_entity_state_cache[entity_id]
|
return home_assistant_entity_state_cache[entity_id]
|
||||||
|
|||||||
@@ -1,46 +1,47 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
def init(mqtt_client_from_manager):
|
def custom_send(msg_out_queue, topic, msg):
|
||||||
global mqtt_client
|
msg_out_queue.put((topic, msg))
|
||||||
mqtt_client = mqtt_client_from_manager
|
logging.debug("Sent Message to NsPanel (%s): %s", topic, msg)
|
||||||
|
|
||||||
|
|
||||||
def custom_send(topic, msg):
|
def page_type(msg_out_queue, topic, target_page):
|
||||||
global mqtt_client
|
if target_page == "cardUnlock":
|
||||||
mqtt_client.publish(topic, msg)
|
target_page = "cardAlarm"
|
||||||
logging.debug("Sent Message to NsPanel (%s): %s", topic, msg)
|
custom_send(msg_out_queue, topic, f"pageType~{target_page}")
|
||||||
|
|
||||||
|
|
||||||
def page_type(topic, target_page):
|
def send_time(msg_out_queue, topic, time, addTimeText=""):
|
||||||
if target_page == "cardUnlock":
|
custom_send(msg_out_queue, topic, f"time~{time}~{addTimeText}")
|
||||||
target_page = "cardAlarm"
|
|
||||||
custom_send(topic, f"pageType~{target_page}")
|
|
||||||
|
def send_date(msg_out_queue, topic, date):
|
||||||
|
custom_send(msg_out_queue, topic, f"date~{date}")
|
||||||
def send_time(topic, time, addTimeText=""):
|
|
||||||
custom_send(topic, f"time~{time}~{addTimeText}")
|
|
||||||
|
def entityUpd(msg_out_queue, topic, data):
|
||||||
|
custom_send(msg_out_queue, topic, f"entityUpd~{data}")
|
||||||
def send_date(topic, date):
|
|
||||||
custom_send(topic, f"date~{date}")
|
def weatherUpdate(msg_out_queue, topic, data):
|
||||||
|
custom_send(msg_out_queue, topic, f"weatherUpdate~{data}")
|
||||||
|
|
||||||
def entityUpd(topic, data):
|
def timeout(msg_out_queue, topic, timeout):
|
||||||
custom_send(topic, f"entityUpd~{data}")
|
custom_send(msg_out_queue, topic, f"timeout~{timeout}")
|
||||||
|
|
||||||
def weatherUpdate(topic, data):
|
def dimmode(msg_out_queue, topic, dimValue, dimValueNormal, backgroundColor, fontColor, featExperimentalSliders):
|
||||||
custom_send(topic, f"weatherUpdate~{data}")
|
if dimValue==dimValueNormal:
|
||||||
|
dimValue=dimValue-1
|
||||||
def timeout(topic, timeout):
|
custom_send(msg_out_queue, topic, f"dimmode~{dimValue}~{dimValueNormal}~{backgroundColor}~{fontColor}~{featExperimentalSliders}")
|
||||||
custom_send(topic, f"timeout~{timeout}")
|
|
||||||
|
def entityUpdateDetail(msg_out_queue, topic, data):
|
||||||
def dimmode(topic, dimValue, dimValueNormal, backgroundColor, fontColor, featExperimentalSliders):
|
custom_send(msg_out_queue, topic, f"entityUpdateDetail~{data}")
|
||||||
if dimValue==dimValueNormal:
|
|
||||||
dimValue=dimValue-1
|
def entityUpdateDetail2(msg_out_queue, topic, data):
|
||||||
custom_send(topic, f"dimmode~{dimValue}~{dimValueNormal}~{backgroundColor}~{fontColor}~{featExperimentalSliders}")
|
custom_send(msg_out_queue, topic, f"entityUpdateDetail2~{data}")
|
||||||
|
|
||||||
def entityUpdateDetail(topic, data):
|
def statusUpdate(msg_out_queue, topic, data):
|
||||||
custom_send(topic, f"entityUpdateDetail~{data}")
|
custom_send(msg_out_queue, topic, f"statusUpdate~{data}")
|
||||||
|
|
||||||
def statusUpdate(topic, data):
|
def send_message_page(msg_out_queue, topic, ident, heading, msg, b1, b2):
|
||||||
custom_send(topic, f"statusUpdate~{data}")
|
page_type(msg_out_queue, topic, "popupNotify")
|
||||||
|
custom_send(msg_out_queue, topic, f"entityUpdateDetail~{ident}~{heading}~65535~{b1}~65535~{b2}~65535~{msg}~65535~0")
|
||||||
@@ -1,224 +1,197 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import logging
|
import logging
|
||||||
import paho.mqtt.client as mqtt
|
import time
|
||||||
import time
|
import subprocess
|
||||||
import json
|
import libs.home_assistant
|
||||||
import subprocess
|
import libs.panel_cmd
|
||||||
import libs.home_assistant
|
import yaml
|
||||||
import libs.panel_cmd
|
from panel import LovelaceUIPanel
|
||||||
import yaml
|
import os
|
||||||
from uuid import getnode as get_mac
|
import threading
|
||||||
from panel import LovelaceUIPanel
|
from watchdog.events import FileSystemEventHandler
|
||||||
import os
|
from watchdog.observers import Observer
|
||||||
import threading
|
import signal
|
||||||
from watchdog.events import FileSystemEventHandler
|
import sys
|
||||||
from watchdog.observers import Observer
|
from queue import Queue
|
||||||
import signal
|
from mqtt import MqttManager
|
||||||
import sys
|
|
||||||
from queue import Queue
|
logging.getLogger("watchdog").propagate = False
|
||||||
|
|
||||||
logging.getLogger("watchdog").propagate = False
|
settings = {}
|
||||||
|
panels = {}
|
||||||
settings = {}
|
panel_in_queues = {}
|
||||||
panels = {}
|
panel_out_queue = Queue(maxsize=20)
|
||||||
panel_queues = {}
|
last_settings_file_mtime = 0
|
||||||
last_settings_file_mtime = 0
|
mqtt_connect_time = 0
|
||||||
mqtt_connect_time = 0
|
has_sent_reload_command = False
|
||||||
has_sent_reload_command = False
|
|
||||||
mqtt_client_name = "NSPanelLovelaceManager_" + str(get_mac())
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
client = mqtt.Client(mqtt_client_name)
|
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
def on_ha_update(entity_id):
|
||||||
|
global panel_in_queues
|
||||||
def on_connect(client, userdata, flags, rc):
|
# send HA updates to all panels
|
||||||
global settings
|
for queue in panel_in_queues.values():
|
||||||
logging.info("Connected to MQTT Server")
|
queue.put(("HA:", entity_id))
|
||||||
# subscribe to panelRecvTopic of each panel
|
|
||||||
for settings_panel in settings["nspanels"].values():
|
def on_ha_panel_event(device_id, msg):
|
||||||
client.subscribe(settings_panel["panelRecvTopic"])
|
global panel_in_queues
|
||||||
|
|
||||||
def on_ha_update(entity_id):
|
if device_id in panel_in_queues.keys():
|
||||||
global panel_queues
|
queue = panel_in_queues[device_id]
|
||||||
for queue in panel_queues.values():
|
queue.put(("MQTT:", msg))
|
||||||
queue.put(("HA:", entity_id))
|
|
||||||
|
def process_output_to_panel():
|
||||||
def on_message(client, userdata, msg):
|
while True:
|
||||||
global panel_queues
|
msg = panel_out_queue.get()
|
||||||
try:
|
|
||||||
if msg.payload.decode() == "":
|
#client.publish(msg[0], msg[1])
|
||||||
return
|
#apis.ha_api.call_service(service="esphome/" + self._api_panel_name + "_nspanelui_api_call", command=2, data=msg)
|
||||||
parts = msg.topic.split('/')
|
service = msg[0] + "_nspanelui_api_call"
|
||||||
if msg.topic in panel_queues.keys():
|
service_data = {
|
||||||
data = json.loads(msg.payload.decode('utf-8'))
|
"data": msg[1],
|
||||||
if "CustomRecv" in data:
|
"command":2
|
||||||
queue = panel_queues[msg.topic]
|
}
|
||||||
queue.put(("MQTT:", data["CustomRecv"]))
|
libs.home_assistant.send_msg_to_panel(
|
||||||
else:
|
service = service,
|
||||||
logging.debug("Received unhandled message on topic: %s", msg.topic)
|
service_data = service_data
|
||||||
|
)
|
||||||
except Exception: # pylint: disable=broad-exception-caught
|
|
||||||
logging.exception("Something went wrong during processing of message:")
|
|
||||||
try:
|
def connect():
|
||||||
logging.error(msg.payload.decode('utf-8'))
|
global settings, panel_out_queue
|
||||||
except: # pylint: disable=bare-except
|
if "mqtt_server" in settings and not "use_ha_api" in settings:
|
||||||
logging.error(
|
MqttManager(settings, panel_out_queue, panel_in_queues)
|
||||||
"Something went wrong when processing the exception message, couldn't decode payload to utf-8.")
|
else:
|
||||||
|
logging.info("MQTT values not configured, will not connect.")
|
||||||
def get_config_file():
|
|
||||||
CONFIG_FILE = os.getenv('CONFIG_FILE')
|
# MQTT Connected, start APIs if configured
|
||||||
if not CONFIG_FILE:
|
if settings["home_assistant_address"] != "" and settings["home_assistant_token"] != "":
|
||||||
CONFIG_FILE = './panels.yaml'
|
libs.home_assistant.init(settings, on_ha_update)
|
||||||
return CONFIG_FILE
|
libs.home_assistant.connect()
|
||||||
|
else:
|
||||||
def get_config(file):
|
logging.info("Home Assistant values not configured, will not connect.")
|
||||||
global settings
|
|
||||||
|
while not libs.home_assistant.ws_connected:
|
||||||
try:
|
time.sleep(1)
|
||||||
with open(file, 'r', encoding="utf8") as file:
|
if settings.get("use_ha_api"):
|
||||||
settings = yaml.safe_load(file)
|
libs.home_assistant.subscribe_to_nspanel_events(on_ha_panel_event)
|
||||||
except yaml.YAMLError as exc:
|
send_to_panel_thread = threading.Thread(target=process_output_to_panel, args=())
|
||||||
print ("Error while parsing YAML file:")
|
send_to_panel_thread.daemon = True
|
||||||
if hasattr(exc, 'problem_mark'):
|
send_to_panel_thread.start()
|
||||||
if exc.context != None:
|
|
||||||
print (' parser says\n' + str(exc.problem_mark) + '\n ' +
|
def setup_panels():
|
||||||
str(exc.problem) + ' ' + str(exc.context) +
|
global settings, panel_in_queues
|
||||||
'\nPlease correct data and retry.')
|
# Create NsPanel object
|
||||||
else:
|
for name, settings_panel in settings["nspanels"].items():
|
||||||
print (' parser says\n' + str(exc.problem_mark) + '\n ' +
|
if "timeZone" not in settings_panel:
|
||||||
str(exc.problem) + '\nPlease correct data and retry.')
|
settings_panel["timeZone"] = settings.get("timeZone", "Europe/Berlin")
|
||||||
else:
|
if "locale" not in settings_panel:
|
||||||
print ("Something went wrong while parsing yaml file")
|
settings_panel["timezone"] = settings.get("locale", "en_US")
|
||||||
return False
|
if "hiddenCards" not in settings_panel:
|
||||||
|
settings_panel["hiddenCards"] = settings.get("hiddenCards", [])
|
||||||
if not settings.get("mqtt_username"):
|
|
||||||
settings["mqtt_username"] = os.getenv('MQTT_USER')
|
msg_in_queue = Queue(maxsize=20)
|
||||||
if not settings.get("mqtt_password"):
|
panel_in_queues[settings_panel["panelRecvTopic"]] = msg_in_queue
|
||||||
settings["mqtt_password"] = os.getenv('MQTT_PASS')
|
panel_thread = threading.Thread(target=panel_thread_target, args=(msg_in_queue, name, settings_panel, panel_out_queue))
|
||||||
if not settings.get("mqtt_port"):
|
panel_thread.daemon = True
|
||||||
settings["mqtt_port"] = os.getenv('MQTT_PORT')
|
panel_thread.start()
|
||||||
if not settings.get("mqtt_server"):
|
|
||||||
settings["mqtt_server"] = os.getenv('MQTT_SERVER')
|
def panel_thread_target(queue_in, name, settings_panel, queue_out):
|
||||||
|
panel = LovelaceUIPanel(name, settings_panel, queue_out)
|
||||||
|
while True:
|
||||||
settings["is_addon"] = False
|
msg = queue_in.get()
|
||||||
|
if msg[0] == "MQTT:":
|
||||||
if not settings.get("home_assistant_token"):
|
panel.customrecv_event_callback(msg[1])
|
||||||
st = os.getenv('SUPERVISOR_TOKEN')
|
elif msg[0] == "HA:":
|
||||||
if st and "home_assistant_token" not in settings and "home_assistant_address" not in settings:
|
panel.ha_event_callback(msg[1])
|
||||||
settings["home_assistant_token"] = st
|
|
||||||
settings["home_assistant_address"] = "http://supervisor"
|
def get_config_file():
|
||||||
settings["is_addon"] = True
|
CONFIG_FILE = os.getenv('CONFIG_FILE')
|
||||||
return True
|
if not CONFIG_FILE:
|
||||||
|
CONFIG_FILE = './panels.yaml'
|
||||||
def connect():
|
return CONFIG_FILE
|
||||||
global settings, home_assistant, client
|
|
||||||
client.on_connect = on_connect
|
def get_config(file):
|
||||||
client.on_message = on_message
|
global settings
|
||||||
client.username_pw_set(
|
|
||||||
settings["mqtt_username"], settings["mqtt_password"])
|
try:
|
||||||
# Wait for connection
|
with open(file, 'r', encoding="utf8") as file:
|
||||||
connection_return_code = 0
|
settings = yaml.safe_load(file)
|
||||||
mqtt_server = settings["mqtt_server"]
|
except yaml.YAMLError as exc:
|
||||||
mqtt_port = int(settings["mqtt_port"])
|
print ("Error while parsing YAML file:")
|
||||||
logging.info("Connecting to %s:%i as %s",
|
if hasattr(exc, 'problem_mark'):
|
||||||
mqtt_server, mqtt_port, mqtt_client_name)
|
if exc.context != None:
|
||||||
while True:
|
print (' parser says\n' + str(exc.problem_mark) + '\n ' +
|
||||||
try:
|
str(exc.problem) + ' ' + str(exc.context) +
|
||||||
client.connect(mqtt_server, mqtt_port, 5)
|
'\nPlease correct data and retry.')
|
||||||
break # Connection call did not raise exception, connection is sucessfull
|
else:
|
||||||
except: # pylint: disable=bare-except
|
print (' parser says\n' + str(exc.problem_mark) + '\n ' +
|
||||||
logging.exception(
|
str(exc.problem) + '\nPlease correct data and retry.')
|
||||||
"Failed to connect to MQTT %s:%i. Will try again in 10 seconds. Code: %s", mqtt_server, mqtt_port, connection_return_code)
|
else:
|
||||||
time.sleep(10.)
|
print ("Something went wrong while parsing yaml file")
|
||||||
|
return False
|
||||||
# MQTT Connected, start APIs if configured
|
|
||||||
if settings["home_assistant_address"] != "" and settings["home_assistant_token"] != "":
|
if not settings.get("mqtt_username"):
|
||||||
libs.home_assistant.init(settings, on_ha_update)
|
settings["mqtt_username"] = os.getenv('MQTT_USER')
|
||||||
libs.home_assistant.connect()
|
if not settings.get("mqtt_password"):
|
||||||
else:
|
settings["mqtt_password"] = os.getenv('MQTT_PASS')
|
||||||
logging.info("Home Assistant values not configured, will not connect.")
|
if not settings.get("mqtt_port"):
|
||||||
|
settings["mqtt_port"] = os.getenv('MQTT_PORT')
|
||||||
libs.panel_cmd.init(client)
|
if not settings.get("mqtt_server"):
|
||||||
|
settings["mqtt_server"] = os.getenv('MQTT_SERVER')
|
||||||
setup_panels()
|
|
||||||
|
|
||||||
def loop():
|
settings["is_addon"] = False
|
||||||
global client
|
|
||||||
# Loop MQTT
|
if not settings.get("home_assistant_token"):
|
||||||
client.loop_forever()
|
st = os.getenv('SUPERVISOR_TOKEN')
|
||||||
|
if st and "home_assistant_token" not in settings and "home_assistant_address" not in settings:
|
||||||
def setup_panels():
|
settings["home_assistant_token"] = st
|
||||||
global settings, panel_queues
|
settings["home_assistant_address"] = "http://supervisor"
|
||||||
# Create NsPanel object
|
settings["is_addon"] = True
|
||||||
for name, settings_panel in settings["nspanels"].items():
|
return True
|
||||||
if "timeZone" not in settings_panel:
|
|
||||||
settings_panel["timeZone"] = settings.get("timeZone", "Europe/Berlin")
|
def config_watch():
|
||||||
if "locale" not in settings_panel:
|
class ConfigChangeEventHandler(FileSystemEventHandler):
|
||||||
settings_panel["timezone"] = settings.get("locale", "en_US")
|
def __init__(self, base_paths):
|
||||||
if "hiddenCards" not in settings_panel:
|
self.base_paths = base_paths
|
||||||
settings_panel["hiddenCards"] = settings.get("hiddenCards", [])
|
|
||||||
|
def dispatch(self, event):
|
||||||
#panels[name] = LovelaceUIPanel(name, settings_panel)
|
for base_path in self.base_paths:
|
||||||
|
if event.src_path.endswith(base_path):
|
||||||
mqtt_queue = Queue(maxsize=20)
|
super(ConfigChangeEventHandler, self).dispatch(event)
|
||||||
panel_queues[settings_panel["panelRecvTopic"]] = mqtt_queue
|
return
|
||||||
panel_thread = threading.Thread(target=panel_thread_target, args=(mqtt_queue, name, settings_panel))
|
|
||||||
panel_thread.daemon = True
|
def on_modified(self, event):
|
||||||
|
logging.info('Modification detected. Reloading panels.')
|
||||||
panel_thread.start()
|
pid = os.getpid()
|
||||||
|
os.kill(pid, signal.SIGTERM)
|
||||||
def panel_thread_target(queue, name, settings_panel):
|
|
||||||
panel = LovelaceUIPanel(name, settings_panel)
|
logging.info('Watching for changes in config file')
|
||||||
while True:
|
project_files = []
|
||||||
msg = queue.get()
|
project_files.append(get_config_file())
|
||||||
#print(msg)
|
handler = ConfigChangeEventHandler(project_files)
|
||||||
if msg[0] == "MQTT:":
|
observer = Observer()
|
||||||
panel.customrecv_event_callback(msg[1])
|
observer.schedule(handler, path=os.path.dirname(get_config_file()), recursive=True)
|
||||||
elif msg[0] == "HA:":
|
observer.start()
|
||||||
panel.ha_event_callback(msg[1])
|
while True:
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
def signal_handler(signum, frame):
|
||||||
|
logging.info(f"Received signal {signum}. Initiating restart...")
|
||||||
|
python = sys.executable
|
||||||
|
os.execl(python, python, *sys.argv)
|
||||||
|
|
||||||
def config_watch():
|
if __name__ == '__main__':
|
||||||
class ConfigChangeEventHandler(FileSystemEventHandler):
|
signal.signal(signal.SIGTERM, signal_handler)
|
||||||
def __init__(self, base_paths):
|
threading.Thread(target=config_watch).start()
|
||||||
self.base_paths = base_paths
|
if (get_config(get_config_file())):
|
||||||
|
connect()
|
||||||
def dispatch(self, event):
|
setup_panels()
|
||||||
for base_path in self.base_paths:
|
|
||||||
if event.src_path.endswith(base_path):
|
# main thread sleep forever
|
||||||
super(ConfigChangeEventHandler, self).dispatch(event)
|
while True:
|
||||||
return
|
time.sleep(100)
|
||||||
|
else:
|
||||||
def on_modified(self, event):
|
while True:
|
||||||
logging.info('Modification detected. Reloading panels.')
|
|
||||||
pid = os.getpid()
|
|
||||||
os.kill(pid, signal.SIGTERM)
|
|
||||||
|
|
||||||
logging.info('Watching for changes in config file')
|
|
||||||
project_files = []
|
|
||||||
project_files.append(get_config_file())
|
|
||||||
handler = ConfigChangeEventHandler(project_files)
|
|
||||||
observer = Observer()
|
|
||||||
observer.schedule(handler, path=os.path.dirname(get_config_file()), recursive=True)
|
|
||||||
observer.start()
|
|
||||||
while True:
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
def signal_handler(signum, frame):
|
|
||||||
logging.info(f"Received signal {signum}. Initiating restart...")
|
|
||||||
python = sys.executable
|
|
||||||
os.execl(python, python, *sys.argv)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
signal.signal(signal.SIGTERM, signal_handler)
|
|
||||||
threading.Thread(target=config_watch).start()
|
|
||||||
if (get_config(get_config_file())):
|
|
||||||
connect()
|
|
||||||
loop()
|
|
||||||
else:
|
|
||||||
while True:
|
|
||||||
time.sleep(100)
|
time.sleep(100)
|
||||||
68
nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/mqtt.py
Normal file
68
nspanel-lovelace-ui/rootfs/usr/bin/mqtt-manager/mqtt.py
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
from uuid import getnode as get_mac
|
||||||
|
import paho.mqtt.client as mqtt
|
||||||
|
import logging
|
||||||
|
import time
|
||||||
|
import json
|
||||||
|
import threading
|
||||||
|
|
||||||
|
|
||||||
|
class MqttManager:
|
||||||
|
def __init__(self, settings, msg_in_queue, msg_out_queue_list):
|
||||||
|
mqtt_client_name = "NSPanelLovelaceManager_" + str(get_mac())
|
||||||
|
self.client = mqtt.Client(mqtt_client_name)
|
||||||
|
self.msg_in_queue = msg_in_queue
|
||||||
|
self.msg_out_queue_list = msg_out_queue_list
|
||||||
|
self.settings = settings
|
||||||
|
|
||||||
|
self.client.on_connect = self.on_mqtt_connect
|
||||||
|
self.client.on_message = self.on_mqtt_message
|
||||||
|
self.client.username_pw_set(
|
||||||
|
settings["mqtt_username"], settings["mqtt_password"])
|
||||||
|
# Wait for connection
|
||||||
|
connection_return_code = 0
|
||||||
|
mqtt_server = settings["mqtt_server"]
|
||||||
|
mqtt_port = int(settings["mqtt_port"])
|
||||||
|
logging.info("Connecting to %s:%i as %s",
|
||||||
|
mqtt_server, mqtt_port, mqtt_client_name)
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
self.client.connect(mqtt_server, mqtt_port, 5)
|
||||||
|
break # Connection call did not raise exception, connection is sucessfull
|
||||||
|
except: # pylint: disable=bare-except
|
||||||
|
logging.exception(
|
||||||
|
"Failed to connect to MQTT %s:%i. Will try again in 10 seconds. Code: %s", mqtt_server, mqtt_port, connection_return_code)
|
||||||
|
time.sleep(10.)
|
||||||
|
self.client.loop_start()
|
||||||
|
process_thread = threading.Thread(target=self.process_in_queue, args=(self.client, self.msg_in_queue))
|
||||||
|
process_thread.daemon = True
|
||||||
|
process_thread.start()
|
||||||
|
|
||||||
|
def on_mqtt_connect(self, client, userdata, flags, rc):
|
||||||
|
logging.info("Connected to MQTT Server")
|
||||||
|
# subscribe to panelRecvTopic of each panel
|
||||||
|
for settings_panel in self.settings["nspanels"].values():
|
||||||
|
client.subscribe(settings_panel["panelRecvTopic"])
|
||||||
|
|
||||||
|
def on_mqtt_message(self, client, userdata, msg):
|
||||||
|
try:
|
||||||
|
if msg.payload.decode() == "":
|
||||||
|
return
|
||||||
|
if msg.topic in self.msg_out_queue_list.keys():
|
||||||
|
data = json.loads(msg.payload.decode('utf-8'))
|
||||||
|
if "CustomRecv" in data:
|
||||||
|
queue = self.msg_out_queue_list[msg.topic]
|
||||||
|
queue.put(("MQTT:", data["CustomRecv"]))
|
||||||
|
else:
|
||||||
|
logging.debug("Received unhandled message on topic: %s", msg.topic)
|
||||||
|
except Exception: # pylint: disable=broad-exception-caught
|
||||||
|
logging.exception("Something went wrong during processing of message:")
|
||||||
|
try:
|
||||||
|
logging.error(msg.payload.decode('utf-8'))
|
||||||
|
except: # pylint: disable=bare-except
|
||||||
|
logging.error(
|
||||||
|
"Something went wrong when processing the exception message, couldn't decode payload to utf-8.")
|
||||||
|
|
||||||
|
def process_in_queue(self, client, msg_in_queue):
|
||||||
|
while True:
|
||||||
|
msg = msg_in_queue.get()
|
||||||
|
client.publish(msg[0], msg[1])
|
||||||
@@ -7,18 +7,20 @@ from scheduler import Scheduler
|
|||||||
import scheduler.trigger as trigger
|
import scheduler.trigger as trigger
|
||||||
import time
|
import time
|
||||||
import babel.dates
|
import babel.dates
|
||||||
from ha_cards import Screensaver, EntitiesCard, card_factory, detail_open
|
from ha_cards import Screensaver, card_factory, detail_open
|
||||||
import ha_control
|
import ha_control
|
||||||
|
|
||||||
class LovelaceUIPanel:
|
class LovelaceUIPanel:
|
||||||
|
|
||||||
def __init__(self, name_panel, settings_panel):
|
def __init__(self, name_panel, settings_panel, msg_out_queue):
|
||||||
self.name = name_panel
|
self.name = name_panel
|
||||||
self.settings = settings_panel
|
self.settings = settings_panel
|
||||||
|
self.msg_out_queue = msg_out_queue
|
||||||
self.sendTopic = self.settings["panelSendTopic"]
|
self.sendTopic = self.settings["panelSendTopic"]
|
||||||
self.recvTopic = self.settings["panelRecvTopic"]
|
self.recvTopic = self.settings["panelRecvTopic"]
|
||||||
self.model = self.settings.get("model", "eu")
|
self.model = self.settings.get("model", "eu")
|
||||||
|
|
||||||
|
self.temp_unit = self.settings.get("temp_unit", "celsius")
|
||||||
|
|
||||||
self.current_card = None
|
self.current_card = None
|
||||||
self.privious_cards = []
|
self.privious_cards = []
|
||||||
@@ -65,7 +67,7 @@ class LovelaceUIPanel:
|
|||||||
self.schedule = Scheduler()
|
self.schedule = Scheduler()
|
||||||
self.schedule.minutely(datetime.time(second=0), self.update_time)
|
self.schedule.minutely(datetime.time(second=0), self.update_time)
|
||||||
self.schedule.hourly(datetime.time(
|
self.schedule.hourly(datetime.time(
|
||||||
minute=0, second=0), self.update_time)
|
minute=0, second=0), self.update_date)
|
||||||
schedule_thread = threading.Thread(target=self.schedule_thread_target)
|
schedule_thread = threading.Thread(target=self.schedule_thread_target)
|
||||||
schedule_thread.daemon = True
|
schedule_thread.daemon = True
|
||||||
schedule_thread.start()
|
schedule_thread.start()
|
||||||
@@ -74,6 +76,10 @@ class LovelaceUIPanel:
|
|||||||
ha_control.wait_for_ha_cache()
|
ha_control.wait_for_ha_cache()
|
||||||
|
|
||||||
#request templates on cards
|
#request templates on cards
|
||||||
|
if isinstance(self.settings.get("sleepBrightness",""), str) and self.settings.get("sleepBrightness", "").startswith("ha:"):
|
||||||
|
libs.home_assistant.cache_template(self.settings.get("sleepBrightness"))
|
||||||
|
if isinstance(self.settings.get("sleepBrightness",""), str) and self.settings.get("screenBrightness", "").startswith("ha:"):
|
||||||
|
libs.home_assistant.cache_template(self.settings.get("screenBrightness"))
|
||||||
for c in self.cards.values():
|
for c in self.cards.values():
|
||||||
if hasattr(c, "qrcode"):
|
if hasattr(c, "qrcode"):
|
||||||
if c.qrcode.startswith("ha:"):
|
if c.qrcode.startswith("ha:"):
|
||||||
@@ -94,7 +100,7 @@ class LovelaceUIPanel:
|
|||||||
for e in self.screensaver.entities:
|
for e in self.screensaver.entities:
|
||||||
e.prerender()
|
e.prerender()
|
||||||
|
|
||||||
libs.panel_cmd.page_type(self.sendTopic, "pageStartup")
|
libs.panel_cmd.page_type(self.msg_out_queue, self.sendTopic, "pageStartup")
|
||||||
|
|
||||||
|
|
||||||
def schedule_thread_target(self):
|
def schedule_thread_target(self):
|
||||||
@@ -106,13 +112,13 @@ class LovelaceUIPanel:
|
|||||||
use_timezone = tz.gettz(self.settings["timeZone"])
|
use_timezone = tz.gettz(self.settings["timeZone"])
|
||||||
time_string = datetime.datetime.now(
|
time_string = datetime.datetime.now(
|
||||||
use_timezone).strftime(self.settings["timeFormat"])
|
use_timezone).strftime(self.settings["timeFormat"])
|
||||||
libs.panel_cmd.send_time(self.sendTopic, time_string)
|
libs.panel_cmd.send_time(self.msg_out_queue, self.sendTopic, time_string)
|
||||||
|
|
||||||
def update_date(self):
|
def update_date(self):
|
||||||
dateformat = self.settings["dateFormat"]
|
dateformat = self.settings["dateFormat"]
|
||||||
date_string = babel.dates.format_date(
|
date_string = babel.dates.format_date(
|
||||||
datetime.datetime.now(), dateformat, locale=self.settings["locale"])
|
datetime.datetime.now(), dateformat, locale=self.settings["locale"])
|
||||||
libs.panel_cmd.send_date(self.sendTopic, date_string)
|
libs.panel_cmd.send_date(self.msg_out_queue, self.sendTopic, date_string)
|
||||||
|
|
||||||
def searchCard(self, iid):
|
def searchCard(self, iid):
|
||||||
if iid in self.navigate_keys:
|
if iid in self.navigate_keys:
|
||||||
@@ -129,13 +135,23 @@ class LovelaceUIPanel:
|
|||||||
|
|
||||||
# send update for detail popup in case it's open
|
# send update for detail popup in case it's open
|
||||||
etype = entity_id.split('.')[0]
|
etype = entity_id.split('.')[0]
|
||||||
if etype in ['light', 'timer', 'cover', 'input_select', 'select', 'fan']:
|
if etype in ['light', 'timer', 'cover', 'input_select', 'select', 'fan', 'climate']:
|
||||||
# figure out iid of entity
|
# figure out iid of entity
|
||||||
entity_id_iid = ""
|
entity_id_iid = ""
|
||||||
for e in self.current_card.get_iid_entities():
|
for e in self.current_card.entities:
|
||||||
if entity_id == e[1]:
|
if entity_id == e.entity_id:
|
||||||
entity_id_iid = f'iid.{e[0]}'
|
entity_id_iid = f'iid.{e.iid}'
|
||||||
libs.panel_cmd.entityUpdateDetail(self.sendTopic, detail_open(self.settings["locale"], etype, entity_id, entity_id_iid, sendTopic=self.sendTopic))
|
|
||||||
|
effectList = None
|
||||||
|
if etype=="light":
|
||||||
|
effectList = e.config.get("effectList")
|
||||||
|
if etype == 'light':
|
||||||
|
libs.panel_cmd.entityUpdateDetail2(self.msg_out_queue, self.sendTopic, detail_open(self.settings["locale"], "popupInSel", entity_id, entity_id_iid, self.msg_out_queue, sendTopic=self.sendTopic, options_list=effectList))
|
||||||
|
libs.panel_cmd.entityUpdateDetail(self.msg_out_queue, self.sendTopic, detail_open(self.settings["locale"], "popupLight", entity_id, entity_id_iid, self.msg_out_queue, sendTopic=self.sendTopic))
|
||||||
|
elif etype in ['input_select', 'media_player']:
|
||||||
|
libs.panel_cmd.entityUpdateDetail2(self.msg_out_queue, self.sendTopic, detail_open(self.settings["locale"], etype, entity_id, entity_id_iid, self.msg_out_queue, sendTopic=self.sendTopic))
|
||||||
|
else:
|
||||||
|
libs.panel_cmd.entityUpdateDetail(self.msg_out_queue, self.sendTopic, detail_open(self.settings["locale"], etype, entity_id, entity_id_iid, self.msg_out_queue, sendTopic=self.sendTopic))
|
||||||
|
|
||||||
involved_entities = ha_control.calculate_dim_values(
|
involved_entities = ha_control.calculate_dim_values(
|
||||||
self.settings.get("sleepTracking"),
|
self.settings.get("sleepTracking"),
|
||||||
@@ -150,16 +166,12 @@ class LovelaceUIPanel:
|
|||||||
|
|
||||||
|
|
||||||
def render_current_page(self, switchPages=False, requested=False):
|
def render_current_page(self, switchPages=False, requested=False):
|
||||||
|
if not self.current_card:
|
||||||
|
return
|
||||||
if switchPages:
|
if switchPages:
|
||||||
libs.panel_cmd.page_type(self.sendTopic, self.current_card.type)
|
libs.panel_cmd.page_type(self.msg_out_queue, self.sendTopic, self.current_card.type)
|
||||||
if requested:
|
if requested:
|
||||||
self.current_card.render()
|
self.current_card.render()
|
||||||
# send sleepTimeout
|
|
||||||
#sleepTimeout = self.settings.get("sleepTimeout", 20)
|
|
||||||
#if self.current_card.config.get("sleepTimeout"):
|
|
||||||
# sleepTimeout = self.current_card.config.get("sleepTimeout")
|
|
||||||
#libs.panel_cmd.timeout(self.sendTopic, sleepTimeout)
|
|
||||||
#self.dimmode()
|
|
||||||
|
|
||||||
def dimmode(self):
|
def dimmode(self):
|
||||||
# send dimmode
|
# send dimmode
|
||||||
@@ -178,8 +190,15 @@ class LovelaceUIPanel:
|
|||||||
backgroundColor = 0
|
backgroundColor = 0
|
||||||
fontColor = ""
|
fontColor = ""
|
||||||
featExperimentalSliders = self.settings.get("featExperimentalSliders", 0)
|
featExperimentalSliders = self.settings.get("featExperimentalSliders", 0)
|
||||||
libs.panel_cmd.dimmode(self.sendTopic, dimValue, dimValueNormal, backgroundColor, fontColor, featExperimentalSliders)
|
libs.panel_cmd.dimmode(self.msg_out_queue, self.sendTopic, dimValue, dimValueNormal, backgroundColor, fontColor, featExperimentalSliders)
|
||||||
|
|
||||||
|
def get_default_card(self):
|
||||||
|
defaultCard = self.settings.get("defaultCard")
|
||||||
|
if defaultCard and "." in defaultCard:
|
||||||
|
card = self.searchCard(defaultCard.split(".")[1])
|
||||||
|
if card:
|
||||||
|
return card
|
||||||
|
return list(self.cards.values())[0]
|
||||||
|
|
||||||
def customrecv_event_callback(self, msg):
|
def customrecv_event_callback(self, msg):
|
||||||
logging.debug("Recv Message from NsPanel (%s): %s", self.name, msg)
|
logging.debug("Recv Message from NsPanel (%s): %s", self.name, msg)
|
||||||
@@ -198,7 +217,7 @@ class LovelaceUIPanel:
|
|||||||
sleepTimeout = self.settings.get("sleepTimeout", 20)
|
sleepTimeout = self.settings.get("sleepTimeout", 20)
|
||||||
if self.current_card.config.get("sleepTimeout"):
|
if self.current_card.config.get("sleepTimeout"):
|
||||||
sleepTimeout = self.current_card.config.get("sleepTimeout")
|
sleepTimeout = self.current_card.config.get("sleepTimeout")
|
||||||
libs.panel_cmd.timeout(self.sendTopic, sleepTimeout)
|
libs.panel_cmd.timeout(self.msg_out_queue, self.sendTopic, sleepTimeout)
|
||||||
self.dimmode()
|
self.dimmode()
|
||||||
|
|
||||||
if msg[1] == "sleepReached":
|
if msg[1] == "sleepReached":
|
||||||
@@ -209,16 +228,22 @@ class LovelaceUIPanel:
|
|||||||
self.render_current_page(requested=True)
|
self.render_current_page(requested=True)
|
||||||
if msg[1] == "buttonPress2":
|
if msg[1] == "buttonPress2":
|
||||||
entity_id = msg[2]
|
entity_id = msg[2]
|
||||||
|
if entity_id == "":
|
||||||
|
return
|
||||||
btype = msg[3]
|
btype = msg[3]
|
||||||
value = msg[4] if len(msg) > 4 else None
|
value = msg[4] if len(msg) > 4 else None
|
||||||
if btype == "bExit":
|
if btype == "bExit":
|
||||||
if entity_id=="screensaver" and self.settings.get("screensaver").get("doubleTapToUnlock") and value == "1":
|
if entity_id in ["screensaver", "screensaver2"] and self.settings.get("screensaver").get("doubleTapToUnlock") and value == "1":
|
||||||
return
|
return
|
||||||
|
|
||||||
# in case privious_cards is empty add a default card
|
# in case privious_cards is empty add a default card
|
||||||
if len(self.privious_cards) == 0:
|
if len(self.privious_cards) == 0:
|
||||||
self.privious_cards.append(
|
self.privious_cards.append(self.get_default_card())
|
||||||
list(self.cards.values())[0]) # TODO: Impelement default card config
|
|
||||||
|
if self.settings.get("defaultCard") and entity_id in ["screensaver", "screensaver2"]:
|
||||||
|
logging.debug("Defaulting to card %s", self.settings.get("defaultCard"))
|
||||||
|
self.privious_cards = [self.get_default_card()]
|
||||||
|
|
||||||
self.current_card = self.privious_cards.pop()
|
self.current_card = self.privious_cards.pop()
|
||||||
self.render_current_page(switchPages=True)
|
self.render_current_page(switchPages=True)
|
||||||
return
|
return
|
||||||
@@ -226,8 +251,10 @@ class LovelaceUIPanel:
|
|||||||
# replace iid with real entity id
|
# replace iid with real entity id
|
||||||
if entity_id.startswith("iid."):
|
if entity_id.startswith("iid."):
|
||||||
iid = entity_id.split(".")[1]
|
iid = entity_id.split(".")[1]
|
||||||
if iid in self.entity_iids:
|
for e in self.current_card.entities:
|
||||||
entity_id = self.entity_iids[iid]
|
if e.iid == iid:
|
||||||
|
entity_id = e.entity_id
|
||||||
|
entity_config = e.config
|
||||||
|
|
||||||
match btype:
|
match btype:
|
||||||
case 'button':
|
case 'button':
|
||||||
@@ -236,8 +263,9 @@ class LovelaceUIPanel:
|
|||||||
case 'navigate':
|
case 'navigate':
|
||||||
card_iid = entity_id.split(".")[1]
|
card_iid = entity_id.split(".")[1]
|
||||||
if card_iid == "UP":
|
if card_iid == "UP":
|
||||||
|
if len(self.privious_cards) == 0:
|
||||||
|
self.privious_cards.append(self.get_default_card())
|
||||||
self.current_card = self.privious_cards.pop()
|
self.current_card = self.privious_cards.pop()
|
||||||
# TODO Handle privious_cards empty with default card
|
|
||||||
self.render_current_page(switchPages=True)
|
self.render_current_page(switchPages=True)
|
||||||
else:
|
else:
|
||||||
self.privious_cards.append(self.current_card)
|
self.privious_cards.append(self.current_card)
|
||||||
@@ -245,13 +273,15 @@ class LovelaceUIPanel:
|
|||||||
self.render_current_page(switchPages=True)
|
self.render_current_page(switchPages=True)
|
||||||
# send ha stuff to ha
|
# send ha stuff to ha
|
||||||
case _:
|
case _:
|
||||||
ha_control.handle_buttons(entity_id, btype, value)
|
ha_control.handle_buttons(entity_id, btype, value, entity_config=entity_config)
|
||||||
case 'cardUnlock-unlock':
|
case 'cardUnlock-unlock':
|
||||||
card_iid = entity_id.split(".")[1]
|
card_iid = entity_id.split(".")[1]
|
||||||
if int(self.current_card.config.get("pin")) == int(value):
|
if int(self.current_card.config.get("pin")) == int(value):
|
||||||
self.privious_cards.append(self.current_card)
|
self.privious_cards.append(self.current_card)
|
||||||
self.current_card = self.searchCard(card_iid)
|
self.current_card = self.searchCard(card_iid)
|
||||||
self.render_current_page(switchPages=True)
|
self.render_current_page(switchPages=True)
|
||||||
|
case 'mode-light':
|
||||||
|
ha_control.handle_buttons(entity_id, btype, value, entity_config=entity_config)
|
||||||
case _:
|
case _:
|
||||||
ha_control.handle_buttons(entity_id, btype, value)
|
ha_control.handle_buttons(entity_id, btype, value)
|
||||||
|
|
||||||
@@ -260,6 +290,15 @@ class LovelaceUIPanel:
|
|||||||
# replace iid with real entity id
|
# replace iid with real entity id
|
||||||
if entity_id.startswith("iid."):
|
if entity_id.startswith("iid."):
|
||||||
iid = entity_id.split(".")[1]
|
iid = entity_id.split(".")[1]
|
||||||
if iid in self.entity_iids:
|
for e in self.current_card.entities:
|
||||||
entity_id = self.entity_iids[iid]
|
if e.iid == iid:
|
||||||
libs.panel_cmd.entityUpdateDetail(self.sendTopic, detail_open(self.settings["locale"], msg[2], entity_id, msg[3], sendTopic=self.sendTopic))
|
entity_id = e.entity_id
|
||||||
|
effectList = None
|
||||||
|
if entity_id.startswith("light"):
|
||||||
|
effectList = e.config.get("effectList")
|
||||||
|
if msg[2] == "popupInSel": #entity_id.split(".")[0] in ['input_select', 'media_player']:
|
||||||
|
libs.panel_cmd.entityUpdateDetail2(self.msg_out_queue, self.sendTopic, detail_open(self.settings["locale"], msg[2], entity_id, msg[3], self.msg_out_queue, sendTopic=self.sendTopic, options_list=effectList))
|
||||||
|
else:
|
||||||
|
libs.panel_cmd.entityUpdateDetail(self.msg_out_queue, self.sendTopic, detail_open(self.settings["locale"], msg[2], entity_id, msg[3], self.msg_out_queue, sendTopic=self.sendTopic))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
paho-mqtt
|
paho-mqtt==1.6.1
|
||||||
pyyaml
|
pyyaml
|
||||||
websockets
|
websockets
|
||||||
websocket-client
|
websocket-client
|
||||||
@@ -7,4 +7,4 @@ python-dateutil
|
|||||||
scheduler
|
scheduler
|
||||||
babel
|
babel
|
||||||
watchdog
|
watchdog
|
||||||
jinja2
|
jinja2
|
||||||
|
|||||||
Reference in New Issue
Block a user