mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2026-05-09 15:35:51 +00:00
Compare commits
819 Commits
v3.7.2
...
74e58aaa3d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74e58aaa3d | ||
|
|
d39d6c7f1f | ||
|
|
4043eaf271 | ||
|
|
73ac60a8b2 | ||
|
|
1d6b283033 | ||
|
|
08ca4e44e8 | ||
|
|
255c173469 | ||
|
|
aeee318cca | ||
|
|
eb14e89c35 | ||
|
|
8411ea6773 | ||
|
|
015110a72e | ||
|
|
dae345f359 | ||
|
|
4cfd9b699c | ||
|
|
bd6371fd9d | ||
|
|
7507596869 | ||
|
|
5d99bd923b | ||
|
|
7402776248 | ||
|
|
8b5cc82df9 | ||
|
|
7c5351f15f | ||
|
|
b29f02e5dd | ||
|
|
e9e7162bcd | ||
|
|
b24aae9123 | ||
|
|
9dbd634322 | ||
|
|
daffc94c7f | ||
|
|
93de0e2f42 | ||
|
|
145172b6e9 | ||
|
|
c4a2f8bac8 | ||
|
|
0c0c928efc | ||
|
|
4d829b0b78 | ||
|
|
01e7d9b027 | ||
|
|
439da1d1e9 | ||
|
|
ac45c17204 | ||
|
|
cd24c7815b | ||
|
|
9665efbf38 | ||
|
|
d8aafdbfd4 | ||
|
|
0c6aef5b60 | ||
|
|
48a1bd0fe6 | ||
|
|
44cfffe8a4 | ||
|
|
e75bf8871e | ||
|
|
22703f4100 | ||
|
|
c066ab8400 | ||
|
|
4a0625e31c | ||
|
|
9aaaba5bb7 | ||
|
|
689a3a9a69 | ||
|
|
391a312f0c | ||
|
|
f782eac0cf | ||
|
|
d88513d789 | ||
|
|
59d07e81d6 | ||
|
|
419fe8ef5d | ||
|
|
4cfcba18ee | ||
|
|
b1d6ab3c96 | ||
|
|
ae26754bc8 | ||
|
|
61c3b47269 | ||
|
|
50bedb2b39 | ||
|
|
13db83a6de | ||
|
|
ec43a07866 | ||
|
|
fbc11b8ef8 | ||
|
|
f1c5a911f9 | ||
|
|
76c0aa6be8 | ||
|
|
61bf2332bb | ||
|
|
39ca956e1f | ||
|
|
0683b77437 | ||
|
|
5da2760dc6 | ||
|
|
3fabaf900f | ||
|
|
b2a8738672 | ||
|
|
c3b9c1ef98 | ||
|
|
aef6b6e92d | ||
|
|
dc46dac02a | ||
|
|
025c430611 | ||
|
|
995ab7233d | ||
|
|
1507989ca3 | ||
|
|
022e808b14 | ||
|
|
9b604e9c78 | ||
|
|
cd3cc09386 | ||
|
|
0df21a7843 | ||
|
|
9225ad2ad9 | ||
|
|
227b1ac59b | ||
|
|
a9a6e32dd1 | ||
|
|
3c4278029f | ||
|
|
3b4e09208e | ||
|
|
e9e0688737 | ||
|
|
7bb1b7bb91 | ||
|
|
4302bc9978 | ||
|
|
60d884df88 | ||
|
|
177c635bc1 | ||
|
|
9a97c28bf0 | ||
|
|
deb87cf5d7 | ||
|
|
a50227638b | ||
|
|
92b1515c8a | ||
|
|
0c5cf0475c | ||
|
|
f26e937514 | ||
|
|
1e4ca8b57f | ||
|
|
4d88bbd28f | ||
|
|
0ce110df9e | ||
|
|
3759fc81ba | ||
|
|
7965ecd856 | ||
|
|
7b0169bb68 | ||
|
|
f10f3d5305 | ||
|
|
ed9e2704b0 | ||
|
|
c47dd0e523 | ||
|
|
80c75bae77 | ||
|
|
cfa973b08b | ||
|
|
83987b71e0 | ||
|
|
a318f34988 | ||
|
|
5cc1660675 | ||
|
|
8a48da38b8 | ||
|
|
d514e67eb8 | ||
|
|
69964482f8 | ||
|
|
2aa691212c | ||
|
|
c27134f185 | ||
|
|
c8033692b1 | ||
|
|
c537d0ab8b | ||
|
|
bee703eb1f | ||
|
|
5d2bd6a2af | ||
|
|
67f0f40a8a | ||
|
|
e796fbef7a | ||
|
|
da7ef04741 | ||
|
|
ddb318dfc6 | ||
|
|
88643dc8e3 | ||
|
|
cf3854563d | ||
|
|
4b2468d616 | ||
|
|
4b08aba9c4 | ||
|
|
0a18add447 | ||
|
|
ca8d23ff3a | ||
|
|
c7e833194f | ||
|
|
f63f658421 | ||
|
|
13fcf09470 | ||
|
|
f560cbd60c | ||
|
|
38ead7e10f | ||
|
|
326bba9b42 | ||
|
|
d9a18bf255 | ||
|
|
6c42cbfb4b | ||
|
|
6691c81956 | ||
|
|
2f95ef305d | ||
|
|
7afde0ce6e | ||
|
|
f3cdafe7d0 | ||
|
|
4bf23e1bda | ||
|
|
aca66457f9 | ||
|
|
121887bdce | ||
|
|
32d7cf4e9c | ||
|
|
3f8227e95e | ||
|
|
10d84261da | ||
|
|
51848d8347 | ||
|
|
1c0669144f | ||
|
|
41a2ba6e5d | ||
|
|
b6fe9e7569 | ||
|
|
faa2c5f1aa | ||
|
|
c71034ff12 | ||
|
|
71be615bbe | ||
|
|
ce53fd1d04 | ||
|
|
1772876f9e | ||
|
|
cd5dbebea9 | ||
|
|
6c67b78a1c | ||
|
|
9b4deb271b | ||
|
|
0e9283af5c | ||
|
|
58011700fe | ||
|
|
079a08ff7b | ||
|
|
b64a55e460 | ||
|
|
2b7ef5b6ba | ||
|
|
d62eef4eca | ||
|
|
0f6d6e69f5 | ||
|
|
97f689b8a7 | ||
|
|
be9b4a070c | ||
|
|
bc15dd4463 | ||
|
|
1613caea86 | ||
|
|
4b39ab76ab | ||
|
|
d04c882590 | ||
|
|
a199bf21e1 | ||
|
|
3ae8722ece | ||
|
|
6a6cef57cf | ||
|
|
090491aab6 | ||
|
|
ca81a02a8c | ||
|
|
f64188bd5d | ||
|
|
d3e0f180c5 | ||
|
|
3f4d87a1d2 | ||
|
|
1d89e651a4 | ||
|
|
fad67b4ef9 | ||
|
|
ce1c22ee35 | ||
|
|
169b5f34ea | ||
|
|
131c03714f | ||
|
|
024c4a0c21 | ||
|
|
b0d111d86f | ||
|
|
faeef9c821 | ||
|
|
60a5b28a21 | ||
|
|
f4b5cf04a0 | ||
|
|
d69f26acac | ||
|
|
2a50701107 | ||
|
|
ab099c45b8 | ||
|
|
47f21019a0 | ||
|
|
5c473c2b3d | ||
|
|
9ddc587334 | ||
|
|
9b0a7a4872 | ||
|
|
97528e9df6 | ||
|
|
b797e1e2bb | ||
|
|
bb52d35c99 | ||
|
|
4c9026e11a | ||
|
|
6cd4e8a5b6 | ||
|
|
dfe037a7d3 | ||
|
|
b87622185d | ||
|
|
0318f8156d | ||
|
|
0c03fa1308 | ||
|
|
2d6e02171f | ||
|
|
2da312bf15 | ||
|
|
52f59a7b1d | ||
|
|
6c8624298c | ||
|
|
ce2d2fb867 | ||
|
|
ba2ad4e175 | ||
|
|
b3320c3e48 | ||
|
|
dc1094b6ba | ||
|
|
bb60568d83 | ||
|
|
67b5c5dd26 | ||
|
|
6866d5b7a9 | ||
|
|
b4e9af89ee | ||
|
|
775ed99b22 | ||
|
|
2ec13273fd | ||
|
|
a846b01103 | ||
|
|
6dffb08545 | ||
|
|
16f7cc148d | ||
|
|
568431ada4 | ||
|
|
6034c1e5eb | ||
|
|
e3566feefb | ||
|
|
ea46c79278 | ||
|
|
a02831e04e | ||
|
|
3b8c973f2a | ||
|
|
2c65936b3e | ||
|
|
bc04c34d58 | ||
|
|
5047f1752e | ||
|
|
1fa7a6c549 | ||
|
|
f9ebe33a7d | ||
|
|
e719dd963d | ||
|
|
c6b0099581 | ||
|
|
71726530c0 | ||
|
|
a749ecb298 | ||
|
|
7e963529c4 | ||
|
|
c76409cf3f | ||
|
|
efd0872690 | ||
|
|
57098b578f | ||
|
|
6472e9e224 | ||
|
|
026828efc7 | ||
|
|
fe6e9be4d3 | ||
|
|
7745a6f9a1 | ||
|
|
c523a379fe | ||
|
|
2854e9cbe9 | ||
|
|
4985f104c7 | ||
|
|
a0ea5f7ea1 | ||
|
|
efc35d0594 | ||
|
|
ccd6c6f8ad | ||
|
|
b426e0eb45 | ||
|
|
c53e1de569 | ||
|
|
8058e98748 | ||
|
|
ba419d09eb | ||
|
|
c701247652 | ||
|
|
12754d1c07 | ||
|
|
9a4daba31a | ||
|
|
a2aa2dccdd | ||
|
|
25af51a8e8 | ||
|
|
ddc597ff03 | ||
|
|
75310afd63 | ||
|
|
3095323c93 | ||
|
|
4667718f12 | ||
|
|
2cb1c5d7e7 | ||
|
|
d7b9754ddb | ||
|
|
99b769626e | ||
|
|
70035b059c | ||
|
|
b252c2f95a | ||
|
|
baa4f2eb39 | ||
|
|
c7b970b5b0 | ||
|
|
3ed5b65191 | ||
|
|
6e01c00d46 | ||
|
|
e72afc9065 | ||
|
|
de2f3e712d | ||
|
|
cacb92cd47 | ||
|
|
3eb20fa700 | ||
|
|
d35574d494 | ||
|
|
3cb29220ab | ||
|
|
d91812ab8f | ||
|
|
856f8efd25 | ||
|
|
d32378ccd4 | ||
|
|
f5006d1a11 | ||
|
|
c3468e6308 | ||
|
|
9f4de56099 | ||
|
|
78738de811 | ||
|
|
e64596ad61 | ||
|
|
024357ae80 | ||
|
|
3f07d3b75f | ||
|
|
cb7c695c67 | ||
|
|
912a764c2d | ||
|
|
c9c0f55b64 | ||
|
|
6991677cf9 | ||
|
|
83330907cd | ||
|
|
3571998da3 | ||
|
|
77465ebe81 | ||
|
|
006e5493e2 | ||
|
|
b29136433d | ||
|
|
0347a4b8b0 | ||
|
|
3330103a8d | ||
|
|
0a02252fee | ||
|
|
642f2116d2 | ||
|
|
7b8e45c2f7 | ||
|
|
0f2244607f | ||
|
|
32ab9dda45 | ||
|
|
b6659b8586 | ||
|
|
5eb85066ef | ||
|
|
9398fc72a0 | ||
|
|
1bcd453e3f | ||
|
|
d405478a13 | ||
|
|
c927e5f496 | ||
|
|
c5dbd7452e | ||
|
|
3a0b4ea587 | ||
|
|
6f4cdb7122 | ||
|
|
b5d6757660 | ||
|
|
0dcde46296 | ||
|
|
ac7e91beff | ||
|
|
9ea1e2752d | ||
|
|
b5471aef94 | ||
|
|
f31329ceff | ||
|
|
40d48f4407 | ||
|
|
11b7e1f86e | ||
|
|
e364a71eda | ||
|
|
e006bebb86 | ||
|
|
fa3d42a1c7 | ||
|
|
e435fd4391 | ||
|
|
d42efb32ab | ||
|
|
ad8f2dc823 | ||
|
|
f2ff14f511 | ||
|
|
e5e9d4c713 | ||
|
|
4c5f93000b | ||
|
|
0c7301a020 | ||
|
|
74c63bf17e | ||
|
|
4564e0b828 | ||
|
|
2ab9607989 | ||
|
|
29d198b46d | ||
|
|
8387ca0c07 | ||
|
|
3796fb8027 | ||
|
|
1da08633ec | ||
|
|
b097e372e4 | ||
|
|
846776929e | ||
|
|
6e1d56b8ee | ||
|
|
32f7eb7299 | ||
|
|
3fc9c3b56c | ||
|
|
e2e46543d2 | ||
|
|
a2b22198ec | ||
|
|
642b59f729 | ||
|
|
9e81de2164 | ||
|
|
d44797db1d | ||
|
|
673ee3f79b | ||
|
|
38a8179544 | ||
|
|
cfb59ac6a0 | ||
|
|
80c26e1adb | ||
|
|
d0de6e8d0f | ||
|
|
68be7d00ff | ||
|
|
d3e6043911 | ||
|
|
373895b36a | ||
|
|
594e10dbe1 | ||
|
|
e3c5b462da | ||
|
|
8a1376b169 | ||
|
|
900e26cf9f | ||
|
|
071e81f29b | ||
|
|
d1bd861ff0 | ||
|
|
f5925dbb3b | ||
|
|
b1eedcb1d8 | ||
|
|
ed7a9f43de | ||
|
|
67885950ef | ||
|
|
74ddb771e9 | ||
|
|
584d0e0b48 | ||
|
|
8d9ca33ea3 | ||
|
|
f0eea1a6a3 | ||
|
|
79cc0377c0 | ||
|
|
115cec08fa | ||
|
|
6df592c2b8 | ||
|
|
f2b81489ba | ||
|
|
0d8760219a | ||
|
|
e8e8d9c130 | ||
|
|
8f712412f5 | ||
|
|
f8ece46163 | ||
|
|
cd8b1add54 | ||
|
|
1c415a9715 | ||
|
|
e1e3601640 | ||
|
|
c2f718b49a | ||
|
|
cee1874689 | ||
|
|
57d172aac2 | ||
|
|
bb26900213 | ||
|
|
9d1ee27533 | ||
|
|
7fd735f667 | ||
|
|
2e79c3a5c6 | ||
|
|
d769999f10 | ||
|
|
bd93d26361 | ||
|
|
72feefe709 | ||
|
|
1d6c2c9664 | ||
|
|
85c78bc8e9 | ||
|
|
18bdcfe050 | ||
|
|
a6f77250b5 | ||
|
|
9874ecde82 | ||
|
|
584b8788be | ||
|
|
7eb15652c7 | ||
|
|
2c28a607ba | ||
|
|
45eca462e7 | ||
|
|
4474868afc | ||
|
|
6c6b5b060d | ||
|
|
c03eb290d1 | ||
|
|
de9bd44071 | ||
|
|
b7458b0686 | ||
|
|
a660ec1afa | ||
|
|
c4f6f01f7e | ||
|
|
9f60560f2b | ||
|
|
7b50f80cb8 | ||
|
|
656d275c56 | ||
|
|
eca17f2b2c | ||
|
|
7f60279aa3 | ||
|
|
5227fafa1b | ||
|
|
4991e2b7cd | ||
|
|
34c514709a | ||
|
|
7dfedfeb10 | ||
|
|
c8bf4cae17 | ||
|
|
2818e268b6 | ||
|
|
7a95c11f62 | ||
|
|
d712b1cce9 | ||
|
|
03fa92352b | ||
|
|
e121fdb47f | ||
|
|
c05793f64f | ||
|
|
3836610d81 | ||
|
|
c3f87cd321 | ||
|
|
4d5a27f45e | ||
|
|
c37c1aaad5 | ||
|
|
110c0df6fb | ||
|
|
04ac3be242 | ||
|
|
44c4ee8bc0 | ||
|
|
57c4d550a3 | ||
|
|
4bcb95eece | ||
|
|
0a92d455c8 | ||
|
|
edb30931ae | ||
|
|
d03ab7a16f | ||
|
|
ea9b6b3e00 | ||
|
|
bae6b600bd | ||
|
|
7eac920985 | ||
|
|
00c2b5992c | ||
|
|
43d2fa1f00 | ||
|
|
92d40d9287 | ||
|
|
7a47a2090f | ||
|
|
0d98491a97 | ||
|
|
16cf16616e | ||
|
|
d9f56ef3ae | ||
|
|
c8934af9bb | ||
|
|
cbacaa98d9 | ||
|
|
f1b6a0baf3 | ||
|
|
4d15f48e2b | ||
|
|
2ffd00e28a | ||
|
|
8ef5be9a7f | ||
|
|
8769faeb83 | ||
|
|
cefbf2d4d6 | ||
|
|
bfd5082054 | ||
|
|
3d3a634d94 | ||
|
|
1cb078cd3c | ||
|
|
22683f5d12 | ||
|
|
57b42aa7c2 | ||
|
|
4a59743024 | ||
|
|
66cec18dee | ||
|
|
ad71938fde | ||
|
|
d4155d6e9e | ||
|
|
af6be4c6b1 | ||
|
|
cfbd0168c3 | ||
|
|
61b9bd7581 | ||
|
|
4c7ad7124e | ||
|
|
0413314cfb | ||
|
|
ab7cbe8ead | ||
|
|
d1264828eb | ||
|
|
76a317b5c0 | ||
|
|
ec11ae2ef7 | ||
|
|
b857c6eb44 | ||
|
|
3f8add73ac | ||
|
|
08b0ddbb7f | ||
|
|
c44cb7e7fd | ||
|
|
77ff61046e | ||
|
|
a8eb06bef2 | ||
|
|
566b5c8ea5 | ||
|
|
eeccd076a0 | ||
|
|
f45ac9d0ef | ||
|
|
cdd9acddfa | ||
|
|
e484f11d12 | ||
|
|
19572f313a | ||
|
|
af9ad5d624 | ||
|
|
8adca69140 | ||
|
|
01710316ed | ||
|
|
ab80c82a22 | ||
|
|
dceafe65a7 | ||
|
|
4734a81fdb | ||
|
|
a2c099e615 | ||
|
|
f9b88a1b6b | ||
|
|
7f2b8cc971 | ||
|
|
582fb3d72f | ||
|
|
bf4fa74742 | ||
|
|
c62b3b9864 | ||
|
|
0ae9795d6b | ||
|
|
7488c31cd3 | ||
|
|
dc0e634004 | ||
|
|
57e7c0ae4f | ||
|
|
7214acfa20 | ||
|
|
ff6d47bb9c | ||
|
|
81971ba53f | ||
|
|
a58f37e3eb | ||
|
|
09a746cf8e | ||
|
|
ea70119138 | ||
|
|
5a9c5b5e2d | ||
|
|
7fb09c5045 | ||
|
|
705171f305 | ||
|
|
400d1a5f1a | ||
|
|
c4855cc5f2 | ||
|
|
1e4b487299 | ||
|
|
cbd883103e | ||
|
|
2ce12943cd | ||
|
|
4151a82b3b | ||
|
|
b871081ef1 | ||
|
|
da51d1d7d9 | ||
|
|
82dae30224 | ||
|
|
1fdac2fdab | ||
|
|
56b23e27d7 | ||
|
|
ba29aa62d3 | ||
|
|
be2342285f | ||
|
|
5595c01221 | ||
|
|
133cddef5b | ||
|
|
0fdba1f84d | ||
|
|
e10ec26e79 | ||
|
|
ffbb397dba | ||
|
|
799076d0c4 | ||
|
|
1fbd10df27 | ||
|
|
4a2f82f1e8 | ||
|
|
d913e4d90b | ||
|
|
0958c29c9e | ||
|
|
36e1c9f79d | ||
|
|
8fedac53dd | ||
|
|
a1c6159fc5 | ||
|
|
5b33acba5e | ||
|
|
4abaef2943 | ||
|
|
ad71773293 | ||
|
|
5b07309939 | ||
|
|
7a044a1dcd | ||
|
|
6507764157 | ||
|
|
7dfa8fc883 | ||
|
|
6df7965bb2 | ||
|
|
02a3dee764 | ||
|
|
d5895f1710 | ||
|
|
2b90ad3f6d | ||
|
|
0bb61b4296 | ||
|
|
2378fb547c | ||
|
|
a79ff3f417 | ||
|
|
4bc93615c5 | ||
|
|
685f0d93e5 | ||
|
|
1d7b6674bb | ||
|
|
014405e451 | ||
|
|
aff3ca3ad3 | ||
|
|
b723d09952 | ||
|
|
bfff842c82 | ||
|
|
ad7d21764d | ||
|
|
f2ae84b004 | ||
|
|
a81956654e | ||
|
|
3cb662799f | ||
|
|
9188d03d61 | ||
|
|
3df2d36453 | ||
|
|
0ab7eb42e4 | ||
|
|
84d4fb37fa | ||
|
|
aa9b38da03 | ||
|
|
8342867807 | ||
|
|
d8cff865da | ||
|
|
096f7e1c88 | ||
|
|
0608d847f5 | ||
|
|
b20360c2a5 | ||
|
|
59b5086cab | ||
|
|
2e3024ab61 | ||
|
|
b5299719da | ||
|
|
2620f56e0d | ||
|
|
20b978c46c | ||
|
|
5c8a18df68 | ||
|
|
3464d6c324 | ||
|
|
eac0cc0521 | ||
|
|
0953d37303 | ||
|
|
1d3fec2a95 | ||
|
|
61b374b7c0 | ||
|
|
c47cc0d5f1 | ||
|
|
939882efbf | ||
|
|
f42cbf548e | ||
|
|
91075ace37 | ||
|
|
de6405f8d1 | ||
|
|
2ffcaf4a9e | ||
|
|
1bda62309b | ||
|
|
83659e5da8 | ||
|
|
a6e136561e | ||
|
|
a75d7487fc | ||
|
|
31b0dd8d58 | ||
|
|
696bd1f455 | ||
|
|
18355efde2 | ||
|
|
d5100134e4 | ||
|
|
b932242e04 | ||
|
|
73ccff3412 | ||
|
|
e5f852a7ed | ||
|
|
581f19462d | ||
|
|
eb59b37251 | ||
|
|
f3696f60cd | ||
|
|
6b4e21f5db | ||
|
|
3d4d5b7bbc | ||
|
|
e6f15681c0 | ||
|
|
5f52a646ff | ||
|
|
be4f9296a5 | ||
|
|
c3181f589c | ||
|
|
872cd40f56 | ||
|
|
30b9de49bf | ||
|
|
8a91c6eb2f | ||
|
|
243471e21d | ||
|
|
b8f97ec94d | ||
|
|
8576a6f253 | ||
|
|
b33e6ceca9 | ||
|
|
8eaf7f32cd | ||
|
|
becdc8cef5 | ||
|
|
651688219c | ||
|
|
b9a4bb3511 | ||
|
|
b318274129 | ||
|
|
8b0e5ba8e7 | ||
|
|
4a9b74b311 | ||
|
|
371b198eb6 | ||
|
|
a6dfdb2c4c | ||
|
|
3122c2b2a9 | ||
|
|
9ac8d149fb | ||
|
|
91e1b0b3b8 | ||
|
|
01636ced88 | ||
|
|
53e587537f | ||
|
|
77eeacf121 | ||
|
|
a89c42d659 | ||
|
|
ba4bc423f4 | ||
|
|
8cd341576d | ||
|
|
006eae5862 | ||
|
|
6e29de4463 | ||
|
|
92d816b990 | ||
|
|
37ad1968b5 | ||
|
|
01793dd4f6 | ||
|
|
9a7f7fa1d5 | ||
|
|
648675d002 | ||
|
|
462d865fc9 | ||
|
|
9f24851948 | ||
|
|
a5e5ec5098 | ||
|
|
db90546bc3 | ||
|
|
2d9ea3ee8d | ||
|
|
4d3cafcf29 | ||
|
|
8685ffb1bf | ||
|
|
86408b3452 | ||
|
|
eab94f3b84 | ||
|
|
9123dbcc9e | ||
|
|
ec6f426b06 | ||
|
|
5482937332 | ||
|
|
0b667703c2 | ||
|
|
c732c96fc2 | ||
|
|
e3d260429c | ||
|
|
77eb2c747b | ||
|
|
6853cd738f | ||
|
|
d58776beab | ||
|
|
94a7b1e438 | ||
|
|
c3f7540f74 | ||
|
|
4642a50f69 | ||
|
|
b23bcf3f0b | ||
|
|
570678e3d3 | ||
|
|
64a2f5eb11 | ||
|
|
24fba8b382 | ||
|
|
9339ef481a | ||
|
|
075789b902 | ||
|
|
1dd1b47faf | ||
|
|
525a164c69 | ||
|
|
b60f333edb | ||
|
|
2323fdfe56 | ||
|
|
9b7fed4d1f | ||
|
|
67c59c9b4b | ||
|
|
b5fea921e6 | ||
|
|
eeb071afc6 | ||
|
|
5669873101 | ||
|
|
d371c9bc82 | ||
|
|
153dd19fc6 | ||
|
|
ae258a75d9 | ||
|
|
37c4be321f | ||
|
|
c810d58064 | ||
|
|
5a27817d11 | ||
|
|
4be2f9283d | ||
|
|
a65162fbbc | ||
|
|
494cf3b6a8 | ||
|
|
b900194402 | ||
|
|
d6e72e72d7 | ||
|
|
960baadeca | ||
|
|
ed92b37869 | ||
|
|
1598809815 | ||
|
|
3131969fc1 | ||
|
|
fb44bc33b9 | ||
|
|
59a806ac8c | ||
|
|
6a2a27e47e | ||
|
|
251d0af028 | ||
|
|
8fa800e2f7 | ||
|
|
df9d20ad88 | ||
|
|
c07754047d | ||
|
|
9c00af317e | ||
|
|
d3d132ec45 | ||
|
|
7adba972e7 | ||
|
|
d83399bd1f | ||
|
|
4471da4aa9 | ||
|
|
b3be1d9351 | ||
|
|
c6b8c2a630 | ||
|
|
3f51c21dc7 | ||
|
|
a8cdbc4fd6 | ||
|
|
95e5babb13 | ||
|
|
74cb23a8bb | ||
|
|
6be304f295 | ||
|
|
e702b0b733 | ||
|
|
bfbd263c74 | ||
|
|
472f922369 | ||
|
|
b13c608ff3 | ||
|
|
5464909121 | ||
|
|
d874b3f808 | ||
|
|
92108bc743 | ||
|
|
66ca1e52bb | ||
|
|
3589094d06 | ||
|
|
801ed6ef79 | ||
|
|
2547ae45a8 | ||
|
|
93e4abe72d | ||
|
|
eb87651c47 | ||
|
|
4138598db2 | ||
|
|
913bbd6e3b | ||
|
|
d35881b05b | ||
|
|
33b54ccf12 | ||
|
|
a8775b2200 | ||
|
|
6d3746222d | ||
|
|
fe169ac80f | ||
|
|
83724e3d44 | ||
|
|
a4db3ef5c4 | ||
|
|
f8adad7865 | ||
|
|
12c094228e | ||
|
|
902ea80807 | ||
|
|
73831d9ac6 | ||
|
|
6bfda79441 | ||
|
|
112de78fc5 | ||
|
|
adbd2381e1 | ||
|
|
397f3f546e | ||
|
|
43d3c28e16 | ||
|
|
747a64b869 | ||
|
|
7c2e5560bd | ||
|
|
9194db9f70 | ||
|
|
fece00c0c6 | ||
|
|
ba3ae5ea56 | ||
|
|
4c69c9e445 | ||
|
|
97925c47fd | ||
|
|
ad89fe15b1 | ||
|
|
29035cabfe | ||
|
|
9b3d43d27f | ||
|
|
0b4f17473a | ||
|
|
b0c29b57c7 | ||
|
|
6d22f6aebf | ||
|
|
3e3e10e6a0 | ||
|
|
b854c777c8 | ||
|
|
b71fdd77e8 | ||
|
|
0f6f7cea19 | ||
|
|
58beb092c2 | ||
|
|
c3f200f73b | ||
|
|
98640c11b1 | ||
|
|
d7904bdcaf | ||
|
|
ce05a94d58 | ||
|
|
c0ed62dc7a | ||
|
|
1557fa98b1 | ||
|
|
81a530f153 | ||
|
|
a4733c3e6a | ||
|
|
7851b8e94c | ||
|
|
36838f7690 | ||
|
|
fdd87d0757 | ||
|
|
c8822aff64 | ||
|
|
4b3205fc9c | ||
|
|
afc05ae9e8 | ||
|
|
9c3044efa0 | ||
|
|
8caeb129c1 | ||
|
|
0427504f0e | ||
|
|
4f11a7caa1 | ||
|
|
150695c185 | ||
|
|
3558591480 | ||
|
|
f7a24052c2 | ||
|
|
75c452486c | ||
|
|
40cab6775c | ||
|
|
392829c7db | ||
|
|
4621c9d616 | ||
|
|
006d664ec9 | ||
|
|
0cc9ac4dd8 | ||
|
|
502096dc22 | ||
|
|
8c424c7a64 | ||
|
|
d7c118b88a | ||
|
|
1fdb0b7516 | ||
|
|
c2fc771756 | ||
|
|
6f759c5bc4 | ||
|
|
facbbf1353 | ||
|
|
a218c7a781 | ||
|
|
5f42709eab | ||
|
|
5ec0f657a0 | ||
|
|
812911ffbb | ||
|
|
55235687ba | ||
|
|
a970009d20 | ||
|
|
4afc16e2cb | ||
|
|
3772d72b43 | ||
|
|
607f949638 | ||
|
|
473cf7c8af | ||
|
|
e0909df06c | ||
|
|
5fc606ef6d | ||
|
|
a3032f4da7 | ||
|
|
7fdd65e8ca | ||
|
|
dc6bf883f1 | ||
|
|
ce5edd93b4 | ||
|
|
e36e6bec9c | ||
|
|
c8fd08b6d2 | ||
|
|
c0d693c1c8 | ||
|
|
5d2a6e2898 | ||
|
|
4547a5ceb0 | ||
|
|
76151c4395 | ||
|
|
481089b1b4 | ||
|
|
463787b7f4 | ||
|
|
e2258a1c43 | ||
|
|
5528f29b6a | ||
|
|
e3861d54c9 | ||
|
|
3368f2803c | ||
|
|
6ca1d68d23 | ||
|
|
cf93081252 | ||
|
|
30fca2a190 |
@@ -1,53 +1,60 @@
|
|||||||
name: 'pre-release'
|
name: 'Build dev release'
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
|
paths:
|
||||||
|
- 'src/emsesp_version.h'
|
||||||
branches:
|
branches:
|
||||||
- 'dev'
|
- 'dev'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
pre-release:
|
pre-release:
|
||||||
name: 'Automatic pre-release build'
|
name: 'Build Dev Release'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
|
- name: Install python 3.13
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: '3.13'
|
||||||
|
|
||||||
|
- name: Install Node.js 22
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 22
|
||||||
|
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Enable Corepack
|
- name: Enable Corepack
|
||||||
run: corepack enable
|
run: corepack enable pnpm
|
||||||
|
|
||||||
- name: Install python 3.11
|
- name: Get the EMS-ESP version
|
||||||
uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: '3.11'
|
|
||||||
|
|
||||||
- name: Install Node.js 20
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: '20.x'
|
|
||||||
|
|
||||||
- name: Get EMS-ESP version
|
|
||||||
id: build_info
|
id: build_info
|
||||||
run: |
|
run: |
|
||||||
version=`grep -E '^#define EMSESP_APP_VERSION' ./src/version.h | awk -F'"' '{print $2}'`
|
version=`grep -E '^#define EMSESP_APP_VERSION' ./src/emsesp_version.h | awk -F'"' '{print $2}'`
|
||||||
echo "VERSION=$version" >> $GITHUB_OUTPUT
|
echo "VERSION=$version" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Install PlatformIO
|
- name: Install PlatformIO
|
||||||
run: |
|
run: |
|
||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
pip install -U platformio
|
pip install -U platformio
|
||||||
|
python -m pip install intelhex
|
||||||
|
|
||||||
- name: Build WebUI
|
- name: Build the WebUI
|
||||||
run: |
|
run: |
|
||||||
cd interface
|
cd interface
|
||||||
yarn install
|
pnpm install
|
||||||
yarn typesafe-i18n --no-watch
|
pnpm typesafe-i18n --no-watch
|
||||||
sed -i "s/= 'pl'/= 'en'/" ./src/i18n/i18n-util.ts
|
sed -i "s/= 'pl'/= 'en'/" ./src/i18n/i18n-util.ts
|
||||||
yarn build
|
pnpm build
|
||||||
yarn webUI
|
pnpm webUI
|
||||||
|
|
||||||
- name: Build all PIO target environments from default_envs
|
- name: Build all PIO target environments
|
||||||
run: |
|
run: |
|
||||||
platformio run
|
platformio run
|
||||||
env:
|
env:
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
name: 'github-releases-to-discord'
|
name: 'Publish releases to discord'
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
|
||||||
release:
|
release:
|
||||||
types: [published]
|
types: [published]
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/pr_check.yml
vendored
2
.github/workflows/pr_check.yml
vendored
@@ -1,4 +1,4 @@
|
|||||||
name: 'pr_check'
|
name: 'Pre-check on PR'
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|||||||
17
.github/workflows/sonar_check.yml
vendored
17
.github/workflows/sonar_check.yml
vendored
@@ -20,15 +20,12 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
- name: Install Build Wrapper
|
||||||
- name: Install sonar-scanner and build-wrapper
|
uses: SonarSource/sonarqube-scan-action/install-build-wrapper@master
|
||||||
uses: SonarSource/sonarcloud-github-c-cpp@v2
|
- name: Run Build Wrapper
|
||||||
|
run: build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} make all
|
||||||
- name: Run build-wrapper
|
- name: SonarQube Scan
|
||||||
run: build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} make all
|
uses: SonarSource/sonarqube-scan-action@master
|
||||||
|
|
||||||
- name: Run sonar-scanner
|
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||||
run: sonar-scanner --define sonar.cfamily.compile-commands="${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json"
|
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
name: 'tagged-release'
|
name: 'Build stable release'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
@@ -8,40 +11,42 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
tagged-release:
|
tagged-release:
|
||||||
name: 'Tagged Release'
|
name: 'Build Stable Release'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
|
- name: Install python 3.13
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: '3.13'
|
||||||
|
|
||||||
|
- name: Install Node.js 22
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 22
|
||||||
|
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Enable Corepack
|
- name: Enable Corepack
|
||||||
run: corepack enable
|
run: corepack enable pnpm
|
||||||
|
|
||||||
- name: Install python 3.11
|
|
||||||
uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: '3.11'
|
|
||||||
|
|
||||||
- name: Install Node.js 20
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: '20.x'
|
|
||||||
|
|
||||||
- name: Install PlatformIO
|
- name: Install PlatformIO
|
||||||
run: |
|
run: |
|
||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
pip install -U platformio
|
pip install -U platformio
|
||||||
|
python -m pip install intelhex
|
||||||
|
|
||||||
- name: Build WebUI
|
- name: Build the WebUI
|
||||||
run: |
|
run: |
|
||||||
cd interface
|
cd interface
|
||||||
yarn install
|
pnpm install
|
||||||
yarn typesafe-i18n --no-watch
|
pnpm typesafe-i18n --no-watch
|
||||||
sed -i "s/= 'pl'/= 'en'/" ./src/i18n/i18n-util.ts
|
sed -i "s/= 'pl'/= 'en'/" ./src/i18n/i18n-util.ts
|
||||||
yarn build
|
pnpm build
|
||||||
yarn webUI
|
pnpm webUI
|
||||||
|
|
||||||
- name: Build all PIO target environments from default_envs
|
- name: Build all PIO target environments
|
||||||
run: |
|
run: |
|
||||||
platformio run
|
platformio run
|
||||||
env:
|
env:
|
||||||
23
.github/workflows/stale_issues.yml
vendored
Normal file
23
.github/workflows/stale_issues.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
name: "Mark or close stale issues and PRs"
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "30 1 * * *"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
stale:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/stale@v9
|
||||||
|
with:
|
||||||
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
days-before-stale: 30
|
||||||
|
days-before-close: 5
|
||||||
|
stale-issue-message: "This issue is stale because it has been open 30 days with no activity. Remove stale label or comment otherwise this will be closed in 5 days."
|
||||||
|
stale-pr-message: "This PR has been automatically marked as stale because there has been no activity in last 30 days. It will be closed if no further activity occurs. Thank you for your contributions."
|
||||||
|
close-issue-message: "This issue was closed because it has been stalled for 5 days with no activity."
|
||||||
|
close-pr-message: "This PR was automatically closed because of being stale."
|
||||||
|
stale-pr-label: "stale"
|
||||||
|
stale-issue-label: "stale"
|
||||||
|
exempt-issue-labels: "bug,enhancement,pinned,security"
|
||||||
|
exempt-pr-labels: "bug,enhancement,pinned,security"
|
||||||
45
.github/workflows/test_release.yml
vendored
45
.github/workflows/test_release.yml
vendored
@@ -1,4 +1,4 @@
|
|||||||
name: 'test-release'
|
name: 'Build test release'
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
@@ -6,46 +6,55 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- 'dev2'
|
- 'dev2'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
pre-release:
|
pre-release:
|
||||||
name: 'Automatic test-release build'
|
name: 'Build Test Release'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Enable Corepack
|
- name: Install python 3.13
|
||||||
run: corepack enable
|
uses: actions/setup-python@v5
|
||||||
|
|
||||||
- uses: actions/setup-python@v5
|
|
||||||
with:
|
with:
|
||||||
python-version: '3.11'
|
python-version: '3.13'
|
||||||
|
|
||||||
- name: Use Node.js 20.x
|
- name: Install Node.js 22
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: '20.x'
|
node-version: 22
|
||||||
|
|
||||||
- name: Get EMS-ESP source code and version
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Enable Corepack
|
||||||
|
run: corepack enable pnpm
|
||||||
|
|
||||||
|
- name: Get the EMS-ESP version
|
||||||
id: build_info
|
id: build_info
|
||||||
run: |
|
run: |
|
||||||
version=`grep -E '^#define EMSESP_APP_VERSION' ./src/version.h | awk -F'"' '{print $2}'`
|
version=`grep -E '^#define EMSESP_APP_VERSION' ./src/emsesp_version.h | awk -F'"' '{print $2}'`
|
||||||
echo "VERSION=$version" >> $GITHUB_OUTPUT
|
echo "VERSION=$version" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Install PlatformIO
|
- name: Install PlatformIO
|
||||||
run: |
|
run: |
|
||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
pip install -U platformio
|
pip install -U platformio
|
||||||
|
python -m pip install intelhex
|
||||||
|
|
||||||
- name: Build WebUI
|
- name: Build the WebUI
|
||||||
run: |
|
run: |
|
||||||
cd interface
|
cd interface
|
||||||
yarn install
|
pnpm install
|
||||||
yarn typesafe-i18n --no-watch
|
pnpm typesafe-i18n --no-watch
|
||||||
sed -i "s/= 'pl'/= 'en'/" ./src/i18n/i18n-util.ts
|
sed -i "s/= 'pl'/= 'en'/" ./src/i18n/i18n-util.ts
|
||||||
yarn build
|
pnpm build
|
||||||
yarn webUI
|
pnpm webUI
|
||||||
|
|
||||||
- name: Build all target environments from default_envs
|
- name: Build all target environments
|
||||||
run: |
|
run: |
|
||||||
platformio run
|
platformio run
|
||||||
env:
|
env:
|
||||||
|
|||||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -28,14 +28,10 @@ stats.html
|
|||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
.pnp.*
|
.pnp.*
|
||||||
*/.yarn/cache/*
|
|
||||||
*/.yarn/install-state.gz
|
|
||||||
analyse.html
|
analyse.html
|
||||||
interface/vite.config.ts.timestamp*
|
interface/vite.config.ts.timestamp*
|
||||||
*.local
|
*.local
|
||||||
src/ESP32React/WWWData.h
|
src/ESP32React/WWWData.h
|
||||||
.yarn/*
|
|
||||||
.yarnrc.yml
|
|
||||||
|
|
||||||
# i18n generated files
|
# i18n generated files
|
||||||
interface/src/i18n/i18n-react.tsx
|
interface/src/i18n/i18n-react.tsx
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ For more details go to [docs.emsesp.org](https://docs.emsesp.org/).
|
|||||||
|
|
||||||
## **IMPORTANT! BREAKING CHANGES**
|
## **IMPORTANT! BREAKING CHANGES**
|
||||||
|
|
||||||
Writeable Text entities have moved from type `sensor` to `text` in Home Assistant to make them also editable within an HA dashboard. Examples are `datetime`, `holidays`, `switchtime`, `vacations`, `maintenancedate`. You will need to manually remove any old discovery topics from your MQTT broker using an application like MQTT Explorer.
|
Writeable Text entities have moved from type `sensor` to `text` in Home Assistant to make them also editable within an HA dashboard. Examples are `datetime`, `holidays`, `switchtime`, `vacations`, `maintenancedate`... You will need to manually remove any old discovery topics from your MQTT broker using an application like MQTT Explorer.
|
||||||
|
|
||||||
## Added
|
## Added
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1,55 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
For more details go to [docs.emsesp.org](https://docs.emsesp.org/).
|
||||||
|
|
||||||
|
## [3.7.3]
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- analogsensor types: NTC and RGB-Led
|
||||||
|
- Flag for HMC310 [#2465](https://github.com/emsesp/EMS-ESP32/issues/2465)
|
||||||
|
- boiler auxheatersource [#2489](https://github.com/emsesp/EMS-ESP32/discussions/2489)
|
||||||
|
- thermostat last error for RC100/300 [#2501](https://github.com/emsesp/EMS-ESP32/issues/2501)
|
||||||
|
- boiler 0xC6 telegram [#1963](https://github.com/emsesp/EMS-ESP32/issues/1963)
|
||||||
|
- CS6800i changes [#2448](https://github.com/emsesp/EMS-ESP32/issues/2448), [#2449](https://github.com/emsesp/EMS-ESP32/issues/2449)
|
||||||
|
- charging pump [#2544](https://github.com/emsesp/EMS-ESP32/issues/2544)
|
||||||
|
- hybrid CSH5800iG [#2569](https://github.com/emsesp/EMS-ESP32/issues/2569)
|
||||||
|
- add EMS Device details to Home Assistant MQTT Discovery
|
||||||
|
- disinfection command [#2601](https://github.com/emsesp/EMS-ESP32/issues/2601)
|
||||||
|
- added new board profile for upcoming BBQKees E32V2.2
|
||||||
|
- set differential pressure entity in Mixer device
|
||||||
|
- set set climate action cooling/heating in HA [#2583](https://github.com/emsesp/EMS-ESP32/issues/2583)
|
||||||
|
- Internal sensors of E32V2_2
|
||||||
|
- FW200 display options [#2610](https://github.com/emsesp/EMS-ESP32/discussions/2610)
|
||||||
|
- CR11 mode settings OFF/MANUAL depends on selTemp [#2437](https://github.com/emsesp/EMS-ESP32/issues/2437)
|
||||||
|
- Fuse settings for BBQKees boards
|
||||||
|
- Analogsensors for pulse output [#2624](https://github.com/emsesp/EMS-ESP32/discussions/2624)
|
||||||
|
- Analogsensors frequency input [#2631](https://github.com/emsesp/EMS-ESP32/discussions/2631)
|
||||||
|
- SRC plus thermostats [#2636](https://github.com/emsesp/EMS-ESP32/issues/2636)
|
||||||
|
- Greenstar 2000 [#2645](https://github.com/emsesp/EMS-ESP32/issues/2645)
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- dhw/switchtime [#2490](https://github.com/emsesp/EMS-ESP32/issues/2490)
|
||||||
|
- switch to secure mqtt [#2492](https://github.com/emsesp/EMS-ESP32/issues/2492)
|
||||||
|
- update link buttons [#2497](https://github.com/emsesp/EMS-ESP32/issues/2497)
|
||||||
|
- refresh scheduler states [#2502](https://github.com/emsesp/EMS-ESP32/discussions/2502)
|
||||||
|
- also rebuild HA config on mqtt connect for scheduler, custom and shower
|
||||||
|
- FB100 controls the hc, not the master [#2510](https://github.com/emsesp/EMS-ESP32/issues/2510)
|
||||||
|
- IPM DHW module, [#2524](https://github.com/emsesp/EMS-ESP32/issues/2524)
|
||||||
|
- charge optimization [#2543](https://github.com/emsesp/EMS-ESP32/issues/2543)
|
||||||
|
- shower active state retained, shows correctly in HA
|
||||||
|
- MQTT Command Topic with slashes [#2571](https://github.com/emsesp/EMS-ESP32/issues/2571)
|
||||||
|
- Add pulsed water meter input to V1.3 gateway with Lilygo S3 [#2550](https://github.com/emsesp/EMS-ESP32/issues/2550)
|
||||||
|
- fix missing long 10-second press of Button to perform a factory reset
|
||||||
|
- fix wwMaxPower on Junkers ZBS14 [#2609](https://github.com/emsesp/EMS-ESP32/issues/2609)
|
||||||
|
- ventilation bypass state from telegram 0x55C [#1197](https://github.com/emsesp/EMS-ESP32/issues/1197)
|
||||||
|
- set selflowtemp for ems+ boilers [#2641](https://github.com/emsesp/EMS-ESP32/discussions/2641)
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- show console log with ISO date/time [#2533](https://github.com/emsesp/EMS-ESP32/discussions/2533)
|
||||||
|
- remove ESP32 CPU temperature
|
||||||
|
- updated core libraries like AsyncTCP, AsyncWebServer and Modbus
|
||||||
|
- remove command `scan deep`
|
||||||
|
- ignore repeated `forceheatingoff` commands [#2641](https://github.com/emsesp/EMS-ESP32/discussions/2641)
|
||||||
|
|||||||
9
Makefile
9
Makefile
@@ -98,13 +98,10 @@ CXX := /usr/bin/g++
|
|||||||
# LDFLAGS Linker Flags
|
# LDFLAGS Linker Flags
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
CPPFLAGS += $(DEFINES) $(DEFAULTS) $(INCLUDE)
|
CPPFLAGS += $(DEFINES) $(DEFAULTS) $(INCLUDE)
|
||||||
CPPFLAGS += -ggdb -g3 -O3
|
CPPFLAGS += -ggdb -g3 -MMD
|
||||||
CPPFLAGS += -MMD
|
|
||||||
CPPFLAGS += -flto=auto -fno-lto
|
CPPFLAGS += -flto=auto -fno-lto
|
||||||
CPPFLAGS += -Wall -Wextra -Werror
|
CPPFLAGS += -Wall -Wextra -Werror -Wswitch-enum
|
||||||
CPPFLAGS += -Wswitch-enum
|
CPPFLAGS += -Wno-unused-parameter -Wno-missing-braces -Wno-vla-cxx-extension
|
||||||
CPPFLAGS += -Wno-unused-parameter
|
|
||||||
CPPFLAGS += -Wno-missing-braces
|
|
||||||
|
|
||||||
CPPFLAGS += $(EXTRA_CPPFLAGS)
|
CPPFLAGS += $(EXTRA_CPPFLAGS)
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ It requires a small circuit to interface with the EMS bus which can be purchased
|
|||||||
|
|
||||||
## 🚀 **Installing**
|
## 🚀 **Installing**
|
||||||
|
|
||||||
Head over to [download.emsesp.org](https://download.emsesp.org) for instructions on how to install EMS-ESP. There is also further details on which boards are supported in [this section](https://docs.emsesp.org/Getting-Started/#first-time-install) of the documentation.
|
Head over to [download.emsesp.org](https://download.emsesp.org) for instructions on how to install EMS-ESP. There is also further details on which boards are supported in [this section](https://docs.emsesp.org/Installing/) of the documentation.
|
||||||
|
|
||||||
## 📋 **Documentation**
|
## 📋 **Documentation**
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ If you like **EMS-ESP**, please give it a ✨ on GitHub, or even better fork it
|
|||||||
- [uuid-\*](https://github.com/nomis/mcu-uuid-console) from @nomis. The console, syslog, telnet and logging are based off these awesome open source libraries
|
- [uuid-\*](https://github.com/nomis/mcu-uuid-console) from @nomis. The console, syslog, telnet and logging are based off these awesome open source libraries
|
||||||
- [ArduinoJson](https://github.com/bblanchon/ArduinoJson) for all the JSON processing
|
- [ArduinoJson](https://github.com/bblanchon/ArduinoJson) for all the JSON processing
|
||||||
- [espMqttClient](https://github.com/bertmelis/espMqttClient) for the MQTT client
|
- [espMqttClient](https://github.com/bertmelis/espMqttClient) for the MQTT client
|
||||||
- ESPAsyncWebServer and AsyncTCP for the Web server and TCP backends, with custom modifications for performance
|
- [ESPAsyncWebServer](https://github.com/ESP32Async/ESPAsyncWebServer) and [AsyncTCP](https://github.com/ESP32Async/AsyncTCP) for the Web server and TCP backends
|
||||||
|
|
||||||
## 📜 **License**
|
## 📜 **License**
|
||||||
|
|
||||||
|
|||||||
48
boards/seeed_xiao_esp32c6.json
Normal file
48
boards/seeed_xiao_esp32c6.json
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
{
|
||||||
|
"build": {
|
||||||
|
"core": "esp32",
|
||||||
|
"extra_flags": [
|
||||||
|
"-DARDUINO_XIAO_ESP32C6",
|
||||||
|
"-DARDUINO_USB_MODE=1",
|
||||||
|
"-DARDUINO_USB_CDC_ON_BOOT=1"
|
||||||
|
],
|
||||||
|
"f_cpu": "160000000L",
|
||||||
|
"f_flash": "80000000L",
|
||||||
|
"flash_mode": "qio",
|
||||||
|
"hwids": [
|
||||||
|
[
|
||||||
|
"0x2886",
|
||||||
|
"0x0046"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"0x303a",
|
||||||
|
"0x1001"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"mcu": "esp32c6",
|
||||||
|
"variant": "XIAO_ESP32C6"
|
||||||
|
},
|
||||||
|
"connectivity": [
|
||||||
|
"wifi",
|
||||||
|
"bluetooth",
|
||||||
|
"zigbee",
|
||||||
|
"thread"
|
||||||
|
],
|
||||||
|
"debug": {
|
||||||
|
"openocd_target": "esp32c6.cfg"
|
||||||
|
},
|
||||||
|
"frameworks": [
|
||||||
|
"arduino",
|
||||||
|
"espidf"
|
||||||
|
],
|
||||||
|
"name": "Seeed Studio XIAO ESP32C6",
|
||||||
|
"upload": {
|
||||||
|
"flash_size": "4MB",
|
||||||
|
"maximum_ram_size": 327680,
|
||||||
|
"maximum_size": 4194304,
|
||||||
|
"require_upload_port": true,
|
||||||
|
"speed": 460800
|
||||||
|
},
|
||||||
|
"url": "https://wiki.seeedstudio.com/XIAO_ESP32C6_Getting_Started/",
|
||||||
|
"vendor": "Seeed Studio"
|
||||||
|
}
|
||||||
@@ -32,6 +32,7 @@
|
|||||||
"**/*.json",
|
"**/*.json",
|
||||||
"src/core/modbus_entity_parameters.hpp",
|
"src/core/modbus_entity_parameters.hpp",
|
||||||
"sdkconfig.*",
|
"sdkconfig.*",
|
||||||
"managed_components/**"
|
"managed_components/**",
|
||||||
|
"pnpm-*.yaml"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -13,9 +13,9 @@ telegram_type_id,name,is_fetched
|
|||||||
0x19,UBAMonitorSlow,
|
0x19,UBAMonitorSlow,
|
||||||
0x1A,UBASetPoints,
|
0x1A,UBASetPoints,
|
||||||
0x1C,UBAMaintenanceStatus,
|
0x1C,UBAMaintenanceStatus,
|
||||||
0x1E,WM10TempMessage,
|
0x1E,HydrTemp,
|
||||||
0x23,JunkersSetMixer,fetched
|
0x23,JunkersSetMixer,fetched
|
||||||
0x26,UBASettingsWW,fetched
|
0x27,UBASettingsWW,fetched
|
||||||
0x28,WeatherComp,fetched
|
0x28,WeatherComp,fetched
|
||||||
0x2A,MC110Status,
|
0x2A,MC110Status,
|
||||||
0x2E,Meters,
|
0x2E,Meters,
|
||||||
@@ -62,7 +62,9 @@ telegram_type_id,name,is_fetched
|
|||||||
0xB1,RC10Monitor,
|
0xB1,RC10Monitor,
|
||||||
0xBB,HybridSettings,fetched
|
0xBB,HybridSettings,fetched
|
||||||
0xBF,ErrorMessage,
|
0xBF,ErrorMessage,
|
||||||
|
0xC0,RCErrorMessage,
|
||||||
0xC2,UBAErrorMessage3,
|
0xC2,UBAErrorMessage3,
|
||||||
|
0xC6,UBAErrorMessage3,
|
||||||
0xD1,UBAOutdoorTemp,
|
0xD1,UBAOutdoorTemp,
|
||||||
0xE3,UBAMonitorSlowPlus2,
|
0xE3,UBAMonitorSlowPlus2,
|
||||||
0xE4,UBAMonitorFastPlus,
|
0xE4,UBAMonitorFastPlus,
|
||||||
@@ -74,7 +76,7 @@ telegram_type_id,name,is_fetched
|
|||||||
0x0103,ISM1StatusMessage,fetched
|
0x0103,ISM1StatusMessage,fetched
|
||||||
0x0104,ISM2StatusMessage,
|
0x0104,ISM2StatusMessage,
|
||||||
0x010C,IPMStatusMessage,
|
0x010C,IPMStatusMessage,
|
||||||
0x011E,IPMTempMessage,
|
0x011E,JunkersDisp,fetched
|
||||||
0x012E,HPEnergy1,
|
0x012E,HPEnergy1,
|
||||||
0x013B,HPEnergy2,
|
0x013B,HPEnergy2,
|
||||||
0x0165,JunkersSet,
|
0x0165,JunkersSet,
|
||||||
@@ -109,9 +111,9 @@ telegram_type_id,name,is_fetched
|
|||||||
0x02A0,RC300Curves,
|
0x02A0,RC300Curves,
|
||||||
0x02A1,RC300Curves,
|
0x02A1,RC300Curves,
|
||||||
0x02A2,RC300Curves,
|
0x02A2,RC300Curves,
|
||||||
0x02A5,RC300Monitor,fetched
|
0x02A5,RC300Monitor,
|
||||||
0x02A6,RC300Monitor,
|
0x02A6,RC300Monitor,
|
||||||
0x02A7,CRFMonitor,
|
0x02A7,RC300Monitor,
|
||||||
0x02A8,RC300Monitor,
|
0x02A8,RC300Monitor,
|
||||||
0x02A9,RC300Monitor,
|
0x02A9,RC300Monitor,
|
||||||
0x02AA,RC300Monitor,
|
0x02AA,RC300Monitor,
|
||||||
@@ -140,6 +142,7 @@ telegram_type_id,name,is_fetched
|
|||||||
0x02D2,RC300Set2,
|
0x02D2,RC300Set2,
|
||||||
0x02D6,HPPump2,fetched
|
0x02D6,HPPump2,fetched
|
||||||
0x02D7,MMPLUSStatusMessage,
|
0x02D7,MMPLUSStatusMessage,
|
||||||
|
0x02E0,UBASetPoints,
|
||||||
0x02F5,RC300WWmode,fetched
|
0x02F5,RC300WWmode,fetched
|
||||||
0x02F6,RC300WW2mode,fetched
|
0x02F6,RC300WW2mode,fetched
|
||||||
0x0313,MMPLUSConfigMessage_WWC,fetched
|
0x0313,MMPLUSConfigMessage_WWC,fetched
|
||||||
@@ -196,6 +199,7 @@ telegram_type_id,name,is_fetched
|
|||||||
0x04AA,HPPower2,fetched
|
0x04AA,HPPower2,fetched
|
||||||
0x04AE,HPEnergy,fetched
|
0x04AE,HPEnergy,fetched
|
||||||
0x04AF,HPMeters,fetched
|
0x04AF,HPMeters,fetched
|
||||||
|
0x055C,VentilationSet,fetched
|
||||||
0x056B,VentilationMode,fetched
|
0x056B,VentilationMode,fetched
|
||||||
0x0583,VentilationMonitor,
|
0x0583,VentilationMonitor,
|
||||||
0x0585,Blowerspeed,
|
0x0585,Blowerspeed,
|
||||||
|
|||||||
|
4
interface/.gitattributes
vendored
4
interface/.gitattributes
vendored
@@ -1,4 +0,0 @@
|
|||||||
/.yarn/** linguist-vendored
|
|
||||||
/.yarn/releases/* binary
|
|
||||||
/.yarn/plugins/**/* binary
|
|
||||||
/.pnp.* binary linguist-generated
|
|
||||||
@@ -4,5 +4,4 @@ dist/
|
|||||||
src/i18n/*
|
src/i18n/*
|
||||||
|
|
||||||
.prettierrc
|
.prettierrc
|
||||||
.yarn/
|
|
||||||
.typesafe-i18n.json
|
.typesafe-i18n.json
|
||||||
935
interface/.yarn/releases/yarn-4.7.0.cjs
vendored
935
interface/.yarn/releases/yarn-4.7.0.cjs
vendored
File diff suppressed because one or more lines are too long
@@ -1,3 +0,0 @@
|
|||||||
nodeLinker: node-modules
|
|
||||||
|
|
||||||
yarnPath: .yarn/releases/yarn-4.7.0.cjs
|
|
||||||
@@ -8,59 +8,60 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"preinstall": "npx only-allow pnpm",
|
||||||
"dev": "vite dev",
|
"dev": "vite dev",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"build-hosted": "typesafe-i18n --no-watch && vite build --mode hosted",
|
"build-hosted": "typesafe-i18n && vite build --mode hosted",
|
||||||
"preview-standalone": "typesafe-i18n --no-watch && vite build && concurrently -c \"auto\" \"yarn:mock-rest\" \"vite preview\"",
|
"preview-standalone": "typesafe-i18n --no-watch && vite build && concurrently -c \"auto\" \"pnpm:mock-rest\" \"vite preview\"",
|
||||||
"mock-rest": "bun --watch ../mock-api/rest_server.ts",
|
"mock-rest": "bun --watch ../mock-api/restServer.ts",
|
||||||
"standalone": "concurrently -c \"auto\" \"typesafe-i18n\" \"yarn:mock-rest\" \"vite\"",
|
"standalone": "concurrently -c \"auto\" \"typesafe-i18n\" \"pnpm:mock-rest\" \"vite\"",
|
||||||
"typesafe-i18n": "typesafe-i18n --no-watch",
|
"typesafe-i18n": "typesafe-i18n --no-watch",
|
||||||
"webUI": "node progmem-generator.js",
|
"webUI": "node progmem-generator.js",
|
||||||
"format": "prettier -l -w '**/*.{ts,tsx,js,css,json,md}'",
|
"format": "prettier -l -w '**/*.{ts,tsx,js,css,json,md}'",
|
||||||
"lint": "eslint . --fix"
|
"lint": "eslint . --fix"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@alova/adapter-xhr": "2.1.1",
|
"@alova/adapter-xhr": "2.2.1",
|
||||||
"@emotion/react": "^11.14.0",
|
"@emotion/react": "^11.14.0",
|
||||||
"@emotion/styled": "^11.14.0",
|
"@emotion/styled": "^11.14.1",
|
||||||
"@mui/icons-material": "^6.4.8",
|
"@mui/icons-material": "^7.3.4",
|
||||||
"@mui/material": "^6.4.8",
|
"@mui/material": "^7.3.4",
|
||||||
"@table-library/react-table-library": "4.1.12",
|
"@table-library/react-table-library": "4.1.15",
|
||||||
"alova": "3.2.10",
|
"alova": "3.3.4",
|
||||||
"async-validator": "^4.2.5",
|
"async-validator": "^4.2.5",
|
||||||
|
"formidable": "^3.5.4",
|
||||||
"jwt-decode": "^4.0.0",
|
"jwt-decode": "^4.0.0",
|
||||||
"mime-types": "^2.1.35",
|
"magic-string": "^0.30.19",
|
||||||
"preact": "^10.26.4",
|
"mime-types": "^3.0.1",
|
||||||
"react": "^19.0.0",
|
"preact": "^10.27.2",
|
||||||
"react-dom": "^19.0.0",
|
"react": "^19.2.0",
|
||||||
|
"react-dom": "^19.2.0",
|
||||||
"react-icons": "^5.5.0",
|
"react-icons": "^5.5.0",
|
||||||
"react-router": "^7.4.0",
|
"react-router": "^7.9.3",
|
||||||
"react-toastify": "^11.0.5",
|
"react-toastify": "^11.0.5",
|
||||||
"typesafe-i18n": "^5.26.2",
|
"typesafe-i18n": "^5.26.2",
|
||||||
"typescript": "^5.8.2"
|
"typescript": "^5.9.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.26.10",
|
"@babel/core": "^7.28.4",
|
||||||
"@eslint/js": "^9.23.0",
|
"@eslint/js": "^9.37.0",
|
||||||
"@preact/compat": "^18.3.1",
|
"@preact/compat": "^18.3.1",
|
||||||
"@preact/preset-vite": "^2.10.1",
|
"@preact/preset-vite": "^2.10.2",
|
||||||
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
|
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
|
||||||
"@types/formidable": "^3",
|
"@types/node": "^24.7.0",
|
||||||
"@types/node": "^22.13.11",
|
"@types/react": "^19.2.2",
|
||||||
"@types/react": "^19.0.12",
|
"@types/react-dom": "^19.2.1",
|
||||||
"@types/react-dom": "^19.0.4",
|
"concurrently": "^9.2.1",
|
||||||
"concurrently": "^9.1.2",
|
"eslint": "^9.37.0",
|
||||||
"eslint": "^9.23.0",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-config-prettier": "^10.1.1",
|
"prettier": "^3.6.2",
|
||||||
"formidable": "^3.5.2",
|
"rollup-plugin-visualizer": "^6.0.4",
|
||||||
"prettier": "^3.5.3",
|
"terser": "^5.44.0",
|
||||||
"rollup-plugin-visualizer": "^5.14.0",
|
"typescript-eslint": "^8.46.0",
|
||||||
"terser": "^5.39.0",
|
"vite": "^7.1.9",
|
||||||
"typescript-eslint": "8.27.0",
|
|
||||||
"vite": "^6.2.2",
|
|
||||||
"vite-plugin-imagemin": "^0.6.1",
|
"vite-plugin-imagemin": "^0.6.1",
|
||||||
"vite-tsconfig-paths": "^5.1.4"
|
"vite-tsconfig-paths": "^5.1.4"
|
||||||
},
|
},
|
||||||
"packageManager": "yarn@4.7.0"
|
"packageManager": "pnpm@10.18.1+sha512.77a884a165cbba2d8d1c19e3b4880eee6d2fcabd0d879121e282196b80042351d5eb3ca0935fa599da1dc51265cc68816ad2bddd2a2de5ea9fdf92adbec7cd34"
|
||||||
}
|
}
|
||||||
|
|||||||
6057
interface/pnpm-lock.yaml
generated
Normal file
6057
interface/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
8
interface/pnpm-workspace.yaml
Normal file
8
interface/pnpm-workspace.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
onlyBuiltDependencies:
|
||||||
|
- cwebp-bin
|
||||||
|
- esbuild
|
||||||
|
- gifsicle
|
||||||
|
- jpegtran-bin
|
||||||
|
- mozjpeg
|
||||||
|
- optipng-bin
|
||||||
|
- pngquant-bin
|
||||||
@@ -143,7 +143,8 @@ export const readCustomEntities = () =>
|
|||||||
o_name: ei.name,
|
o_name: ei.name,
|
||||||
o_writeable: ei.writeable,
|
o_writeable: ei.writeable,
|
||||||
o_value: ei.value,
|
o_value: ei.value,
|
||||||
o_deleted: ei.deleted
|
o_deleted: ei.deleted,
|
||||||
|
o_hide: ei.hide
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ const CustomEntities = () => {
|
|||||||
ei.factor !== ei.o_factor ||
|
ei.factor !== ei.o_factor ||
|
||||||
ei.value_type !== ei.o_value_type ||
|
ei.value_type !== ei.o_value_type ||
|
||||||
ei.writeable !== ei.o_writeable ||
|
ei.writeable !== ei.o_writeable ||
|
||||||
|
ei.hide !== ei.o_hide ||
|
||||||
ei.deleted !== ei.o_deleted ||
|
ei.deleted !== ei.o_deleted ||
|
||||||
(ei.value || '') !== (ei.o_value || '')
|
(ei.value || '') !== (ei.o_value || '')
|
||||||
);
|
);
|
||||||
@@ -147,6 +148,7 @@ const CustomEntities = () => {
|
|||||||
factor: condensed_ei.factor,
|
factor: condensed_ei.factor,
|
||||||
uom: condensed_ei.uom,
|
uom: condensed_ei.uom,
|
||||||
writeable: condensed_ei.writeable,
|
writeable: condensed_ei.writeable,
|
||||||
|
hide: condensed_ei.hide,
|
||||||
value_type: condensed_ei.value_type,
|
value_type: condensed_ei.value_type,
|
||||||
value: condensed_ei.value
|
value: condensed_ei.value
|
||||||
}))
|
}))
|
||||||
@@ -209,6 +211,7 @@ const CustomEntities = () => {
|
|||||||
value_type: item.value_type,
|
value_type: item.value_type,
|
||||||
writeable: item.writeable,
|
writeable: item.writeable,
|
||||||
deleted: false,
|
deleted: false,
|
||||||
|
hide: item.hide,
|
||||||
value: item.value
|
value: item.value
|
||||||
});
|
});
|
||||||
setDialogOpen(true);
|
setDialogOpen(true);
|
||||||
|
|||||||
@@ -2,7 +2,11 @@ import { useEffect, useState } from 'react';
|
|||||||
|
|
||||||
import AddIcon from '@mui/icons-material/Add';
|
import AddIcon from '@mui/icons-material/Add';
|
||||||
import CancelIcon from '@mui/icons-material/Cancel';
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
|
import CommentsDisabledOutlinedIcon from '@mui/icons-material/CommentsDisabledOutlined';
|
||||||
import DoneIcon from '@mui/icons-material/Done';
|
import DoneIcon from '@mui/icons-material/Done';
|
||||||
|
import EditOffOutlinedIcon from '@mui/icons-material/EditOffOutlined';
|
||||||
|
import EditOutlinedIcon from '@mui/icons-material/EditOutlined';
|
||||||
|
import InsertCommentOutlinedIcon from '@mui/icons-material/InsertCommentOutlined';
|
||||||
import RemoveIcon from '@mui/icons-material/RemoveCircleOutline';
|
import RemoveIcon from '@mui/icons-material/RemoveCircleOutline';
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
@@ -12,7 +16,7 @@ import {
|
|||||||
DialogActions,
|
DialogActions,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
Grid2 as Grid,
|
Grid,
|
||||||
InputAdornment,
|
InputAdornment,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
TextField
|
TextField
|
||||||
@@ -128,6 +132,20 @@ const CustomEntitiesDialog = ({
|
|||||||
onChange={updateFormValue}
|
onChange={updateFormValue}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<Grid mt={3}>
|
||||||
|
<BlockFormControlLabel
|
||||||
|
control={
|
||||||
|
<Checkbox
|
||||||
|
icon={<InsertCommentOutlinedIcon htmlColor="white" />}
|
||||||
|
checkedIcon={<CommentsDisabledOutlinedIcon color="primary" />}
|
||||||
|
checked={editItem.hide}
|
||||||
|
onChange={updateFormValue}
|
||||||
|
name="hide"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label="API/MQTT"
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
<Grid>
|
<Grid>
|
||||||
<TextField
|
<TextField
|
||||||
name="ram"
|
name="ram"
|
||||||
@@ -177,10 +195,12 @@ const CustomEntitiesDialog = ({
|
|||||||
)}
|
)}
|
||||||
{editItem.ram === 0 && (
|
{editItem.ram === 0 && (
|
||||||
<>
|
<>
|
||||||
<Grid mt={3} size={9}>
|
<Grid mt={3}>
|
||||||
<BlockFormControlLabel
|
<BlockFormControlLabel
|
||||||
control={
|
control={
|
||||||
<Checkbox
|
<Checkbox
|
||||||
|
icon={<EditOffOutlinedIcon color="primary" />}
|
||||||
|
checkedIcon={<EditOutlinedIcon htmlColor="white" />}
|
||||||
checked={editItem.writeable}
|
checked={editItem.writeable}
|
||||||
onChange={updateFormValue}
|
onChange={updateFormValue}
|
||||||
name="writeable"
|
name="writeable"
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import {
|
|||||||
DialogActions,
|
DialogActions,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
Grid2 as Grid,
|
Grid,
|
||||||
InputAdornment,
|
InputAdornment,
|
||||||
Link,
|
Link,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
@@ -306,7 +306,7 @@ const Customizations = () => {
|
|||||||
|
|
||||||
const filter_entity = (de: DeviceEntity) =>
|
const filter_entity = (de: DeviceEntity) =>
|
||||||
(de.m & selectedFilters || !selectedFilters) &&
|
(de.m & selectedFilters || !selectedFilters) &&
|
||||||
formatName(de, true).includes(search);
|
formatName(de, true).toLowerCase().includes(search.toLowerCase());
|
||||||
|
|
||||||
const maskDisabled = (set: boolean) => {
|
const maskDisabled = (set: boolean) => {
|
||||||
setDeviceEntities(
|
setDeviceEntities(
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
DialogActions,
|
DialogActions,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
Grid2 as Grid,
|
Grid,
|
||||||
TextField,
|
TextField,
|
||||||
Typography
|
Typography
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import {
|
|||||||
DialogActions,
|
DialogActions,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
Grid2 as Grid,
|
Grid,
|
||||||
IconButton,
|
IconButton,
|
||||||
InputAdornment,
|
InputAdornment,
|
||||||
List,
|
List,
|
||||||
@@ -600,9 +600,11 @@ const Devices = () => {
|
|||||||
? deviceData.nodes.filter(
|
? deviceData.nodes.filter(
|
||||||
(dv) =>
|
(dv) =>
|
||||||
hasMask(dv.id, DeviceEntityMask.DV_FAVORITE) &&
|
hasMask(dv.id, DeviceEntityMask.DV_FAVORITE) &&
|
||||||
dv.id.slice(2).includes(search)
|
dv.id.slice(2).toLowerCase().includes(search.toLowerCase())
|
||||||
)
|
)
|
||||||
: deviceData.nodes.filter((dv) => dv.id.slice(2).includes(search));
|
: deviceData.nodes.filter((dv) =>
|
||||||
|
dv.id.slice(2).toLowerCase().includes(search.toLowerCase())
|
||||||
|
);
|
||||||
|
|
||||||
const deviceIndex = coreData.devices.findIndex(
|
const deviceIndex = coreData.devices.findIndex(
|
||||||
(d) => d.id === device_select.state.id
|
(d) => d.id === device_select.state.id
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import {
|
|||||||
DialogContent,
|
DialogContent,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
FormHelperText,
|
FormHelperText,
|
||||||
Grid2 as Grid,
|
Grid,
|
||||||
InputAdornment,
|
InputAdornment,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
TextField,
|
TextField,
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ const Help = () => {
|
|||||||
|
|
||||||
useRequest(() => callAction({ action: 'getCustomSupport' })).onSuccess((event) => {
|
useRequest(() => callAction({ action: 'getCustomSupport' })).onSuccess((event) => {
|
||||||
if (event && event.data && Object.keys(event.data).length !== 0) {
|
if (event && event.data && Object.keys(event.data).length !== 0) {
|
||||||
const data = event.data.Support;
|
const data = (event.data as { Support: { img_url?: string; html?: string[] } })
|
||||||
|
.Support;
|
||||||
if (data.img_url) {
|
if (data.img_url) {
|
||||||
setCustomSupportIMG(data.img_url);
|
setCustomSupportIMG(data.img_url);
|
||||||
}
|
}
|
||||||
@@ -59,7 +60,7 @@ const Help = () => {
|
|||||||
toast.info(LL.DOWNLOAD_SUCCESSFUL());
|
toast.info(LL.DOWNLOAD_SUCCESSFUL());
|
||||||
})
|
})
|
||||||
.onError((error) => {
|
.onError((error) => {
|
||||||
toast.error(error.message);
|
toast.error(String(error.error?.message || 'An error occurred'));
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
DialogActions,
|
DialogActions,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
Grid2 as Grid,
|
Grid,
|
||||||
TextField
|
TextField
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import {
|
|||||||
useLayoutTitle
|
useLayoutTitle
|
||||||
} from 'components';
|
} from 'components';
|
||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
import { useInterval } from 'utils';
|
||||||
|
|
||||||
import { readSchedule, writeSchedule } from '../../api/app';
|
import { readSchedule, writeSchedule } from '../../api/app';
|
||||||
import SettingsSchedulerDialog from './SchedulerDialog';
|
import SettingsSchedulerDialog from './SchedulerDialog';
|
||||||
@@ -73,6 +74,12 @@ const Scheduler = () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useInterval(() => {
|
||||||
|
if (numChanges === 0) {
|
||||||
|
void fetchSchedule();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const formatter = new Intl.DateTimeFormat(locale, {
|
const formatter = new Intl.DateTimeFormat(locale, {
|
||||||
weekday: 'short',
|
weekday: 'short',
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
DialogActions,
|
DialogActions,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
Grid2 as Grid,
|
Grid,
|
||||||
TextField,
|
TextField,
|
||||||
ToggleButton,
|
ToggleButton,
|
||||||
ToggleButtonGroup,
|
ToggleButtonGroup,
|
||||||
|
|||||||
@@ -439,7 +439,8 @@ const Sensors = () => {
|
|||||||
<Cell>{a.n}</Cell>
|
<Cell>{a.n}</Cell>
|
||||||
<Cell stiff>{AnalogTypeNames[a.t]} </Cell>
|
<Cell stiff>{AnalogTypeNames[a.t]} </Cell>
|
||||||
{(a.t === AnalogType.DIGITAL_OUT && a.g !== 25 && a.g !== 26) ||
|
{(a.t === AnalogType.DIGITAL_OUT && a.g !== 25 && a.g !== 26) ||
|
||||||
a.t === AnalogType.DIGITAL_IN ? (
|
a.t === AnalogType.DIGITAL_IN ||
|
||||||
|
a.t === AnalogType.PULSE ? (
|
||||||
<Cell stiff>{a.v ? LL.ON() : LL.OFF()}</Cell>
|
<Cell stiff>{a.v ? LL.ON() : LL.OFF()}</Cell>
|
||||||
) : (
|
) : (
|
||||||
<Cell stiff>{a.t ? formatValue(a.v, a.u) : ''}</Cell>
|
<Cell stiff>{a.t ? formatValue(a.v, a.u) : ''}</Cell>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
DialogActions,
|
DialogActions,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
Grid2 as Grid,
|
Grid,
|
||||||
InputAdornment,
|
InputAdornment,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
TextField,
|
TextField,
|
||||||
@@ -132,7 +132,9 @@ const SensorsAnalogDialog = ({
|
|||||||
))}
|
))}
|
||||||
</TextField>
|
</TextField>
|
||||||
</Grid>
|
</Grid>
|
||||||
{editItem.t >= AnalogType.COUNTER && editItem.t <= AnalogType.RATE && (
|
{((editItem.t >= AnalogType.COUNTER && editItem.t <= AnalogType.RATE) ||
|
||||||
|
(editItem.t >= AnalogType.FREQ_0 &&
|
||||||
|
editItem.t <= AnalogType.FREQ_2)) && (
|
||||||
<Grid>
|
<Grid>
|
||||||
<TextField
|
<TextField
|
||||||
name="u"
|
name="u"
|
||||||
@@ -171,6 +173,27 @@ const SensorsAnalogDialog = ({
|
|||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
)}
|
)}
|
||||||
|
{editItem.t === AnalogType.NTC && (
|
||||||
|
<Grid>
|
||||||
|
<TextField
|
||||||
|
name="o"
|
||||||
|
label={LL.OFFSET()}
|
||||||
|
value={numberValue(editItem.o)}
|
||||||
|
sx={{ width: '11ch' }}
|
||||||
|
type="number"
|
||||||
|
variant="outlined"
|
||||||
|
onChange={updateFormValue}
|
||||||
|
slotProps={{
|
||||||
|
input: {
|
||||||
|
startAdornment: (
|
||||||
|
<InputAdornment position="start">°C</InputAdornment>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
htmlInput: { min: '-20', max: '20', step: '0.1' }
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
)}
|
||||||
{editItem.t === AnalogType.COUNTER && (
|
{editItem.t === AnalogType.COUNTER && (
|
||||||
<Grid>
|
<Grid>
|
||||||
<TextField
|
<TextField
|
||||||
@@ -187,6 +210,19 @@ const SensorsAnalogDialog = ({
|
|||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
)}
|
)}
|
||||||
|
{editItem.t === AnalogType.RGB && (
|
||||||
|
<Grid>
|
||||||
|
<TextField
|
||||||
|
name="o"
|
||||||
|
label={'RGB ' + LL.VALUE(0)}
|
||||||
|
value={numberValue(editItem.o)}
|
||||||
|
type="number"
|
||||||
|
sx={{ width: '11ch' }}
|
||||||
|
variant="outlined"
|
||||||
|
onChange={updateFormValue}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
)}
|
||||||
{editItem.t >= AnalogType.COUNTER && editItem.t <= AnalogType.RATE && (
|
{editItem.t >= AnalogType.COUNTER && editItem.t <= AnalogType.RATE && (
|
||||||
<Grid>
|
<Grid>
|
||||||
<TextField
|
<TextField
|
||||||
@@ -314,6 +350,42 @@ const SensorsAnalogDialog = ({
|
|||||||
</Grid>
|
</Grid>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
{editItem.t === AnalogType.PULSE && (
|
||||||
|
<>
|
||||||
|
<Grid>
|
||||||
|
<TextField
|
||||||
|
name="o"
|
||||||
|
label={LL.POLARITY()}
|
||||||
|
value={editItem.o}
|
||||||
|
sx={{ width: '11ch' }}
|
||||||
|
select
|
||||||
|
onChange={updateFormValue}
|
||||||
|
>
|
||||||
|
<MenuItem value={0}>{LL.ACTIVEHIGH()}</MenuItem>
|
||||||
|
<MenuItem value={1}>{LL.ACTIVELOW()}</MenuItem>
|
||||||
|
</TextField>
|
||||||
|
</Grid>
|
||||||
|
<Grid>
|
||||||
|
<TextField
|
||||||
|
name="f"
|
||||||
|
label="Pulse"
|
||||||
|
value={numberValue(editItem.f)}
|
||||||
|
type="number"
|
||||||
|
sx={{ width: '15ch' }}
|
||||||
|
variant="outlined"
|
||||||
|
onChange={updateFormValue}
|
||||||
|
slotProps={{
|
||||||
|
input: {
|
||||||
|
startAdornment: (
|
||||||
|
<InputAdornment position="start">s</InputAdornment>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
htmlInput: { min: '0', max: '10000', step: '0.1' }
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</Grid>
|
</Grid>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
DialogActions,
|
DialogActions,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
Grid2 as Grid,
|
Grid,
|
||||||
InputAdornment,
|
InputAdornment,
|
||||||
TextField,
|
TextField,
|
||||||
Typography
|
Typography
|
||||||
|
|||||||
@@ -188,7 +188,8 @@ export enum DeviceValueUOM {
|
|||||||
VOLTS,
|
VOLTS,
|
||||||
MBAR,
|
MBAR,
|
||||||
LH,
|
LH,
|
||||||
CTKWH
|
CTKWH,
|
||||||
|
HZ
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DeviceValueUOM_s = [
|
export const DeviceValueUOM_s = [
|
||||||
@@ -218,7 +219,8 @@ export const DeviceValueUOM_s = [
|
|||||||
'V',
|
'V',
|
||||||
'mbar',
|
'mbar',
|
||||||
'l/h',
|
'l/h',
|
||||||
'ct/kWh'
|
'ct/kWh',
|
||||||
|
'Hz'
|
||||||
];
|
];
|
||||||
|
|
||||||
export enum AnalogType {
|
export enum AnalogType {
|
||||||
@@ -232,20 +234,32 @@ export enum AnalogType {
|
|||||||
DIGITAL_OUT = 6,
|
DIGITAL_OUT = 6,
|
||||||
PWM_0 = 7,
|
PWM_0 = 7,
|
||||||
PWM_1 = 8,
|
PWM_1 = 8,
|
||||||
PWM_2 = 9
|
PWM_2 = 9,
|
||||||
|
NTC = 10,
|
||||||
|
RGB = 11,
|
||||||
|
PULSE = 12,
|
||||||
|
FREQ_0 = 13,
|
||||||
|
FREQ_1 = 14,
|
||||||
|
FREQ_2 = 15
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AnalogTypeNames = [
|
export const AnalogTypeNames = [
|
||||||
'(disabled)',
|
'(disabled)',
|
||||||
'Digital In',
|
'Digital In',
|
||||||
'Counter',
|
'Counter',
|
||||||
'ADC',
|
'ADC In',
|
||||||
'Timer',
|
'Timer',
|
||||||
'Rate',
|
'Rate',
|
||||||
'Digital Out',
|
'Digital Out',
|
||||||
'PWM 0',
|
'PWM 0',
|
||||||
'PWM 1',
|
'PWM 1',
|
||||||
'PWM 2'
|
'PWM 2',
|
||||||
|
'NTC Temp.',
|
||||||
|
'RGB Led',
|
||||||
|
'Pulse',
|
||||||
|
'Freq 0',
|
||||||
|
'Freq 1',
|
||||||
|
'Freq 2'
|
||||||
];
|
];
|
||||||
|
|
||||||
type BoardProfiles = Record<string, string>;
|
type BoardProfiles = Record<string, string>;
|
||||||
@@ -255,6 +269,7 @@ export const BOARD_PROFILES: BoardProfiles = {
|
|||||||
S32S3: 'BBQKees Gateway S3',
|
S32S3: 'BBQKees Gateway S3',
|
||||||
E32: 'BBQKees Gateway E32',
|
E32: 'BBQKees Gateway E32',
|
||||||
E32V2: 'BBQKees Gateway E32 V2',
|
E32V2: 'BBQKees Gateway E32 V2',
|
||||||
|
E32V2_2: 'BBQKees Gateway E32 V2.2',
|
||||||
NODEMCU: 'NodeMCU 32S',
|
NODEMCU: 'NodeMCU 32S',
|
||||||
'MH-ET': 'MH-ET Live D1 Mini',
|
'MH-ET': 'MH-ET Live D1 Mini',
|
||||||
LOLIN: 'Lolin D32',
|
LOLIN: 'Lolin D32',
|
||||||
@@ -380,6 +395,7 @@ export interface EntityItem {
|
|||||||
value_type: number;
|
value_type: number;
|
||||||
value?: unknown;
|
value?: unknown;
|
||||||
writeable: boolean;
|
writeable: boolean;
|
||||||
|
hide: boolean;
|
||||||
deleted?: boolean;
|
deleted?: boolean;
|
||||||
o_id?: number;
|
o_id?: number;
|
||||||
o_ram?: number;
|
o_ram?: number;
|
||||||
@@ -393,6 +409,7 @@ export interface EntityItem {
|
|||||||
o_deleted?: boolean;
|
o_deleted?: boolean;
|
||||||
o_writeable?: boolean;
|
o_writeable?: boolean;
|
||||||
o_value?: unknown;
|
o_value?: unknown;
|
||||||
|
o_hide?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Entities {
|
export interface Entities {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
Divider,
|
Divider,
|
||||||
Grid2 as Grid,
|
Grid,
|
||||||
InputAdornment,
|
InputAdornment,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
TextField,
|
TextField,
|
||||||
@@ -554,7 +554,7 @@ const ApplicationSettings = () => {
|
|||||||
<Grid>
|
<Grid>
|
||||||
<TextField
|
<TextField
|
||||||
name="led_type"
|
name="led_type"
|
||||||
label={'LED ' + LL.TYPE()}
|
label={'LED ' + LL.TYPE(0)}
|
||||||
value={data.led_type}
|
value={data.led_type}
|
||||||
fullWidth
|
fullWidth
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { useState } from 'react';
|
|||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
import DownloadIcon from '@mui/icons-material/GetApp';
|
import DownloadIcon from '@mui/icons-material/GetApp';
|
||||||
import { Box, Button, Grid2 as Grid, Typography } from '@mui/material';
|
import { Box, Button, Grid, Typography } from '@mui/material';
|
||||||
|
|
||||||
import * as SystemApi from 'api/system';
|
import * as SystemApi from 'api/system';
|
||||||
import { API, callAction } from 'api/app';
|
import { API, callAction } from 'api/app';
|
||||||
@@ -35,7 +35,7 @@ const DownloadUpload = () => {
|
|||||||
toast.info(LL.DOWNLOAD_SUCCESSFUL());
|
toast.info(LL.DOWNLOAD_SUCCESSFUL());
|
||||||
})
|
})
|
||||||
.onError((error) => {
|
.onError((error) => {
|
||||||
toast.error(error.message);
|
toast.error(String(error.error?.message || 'An error occurred'));
|
||||||
});
|
});
|
||||||
|
|
||||||
const { send: sendAPI } = useRequest((data: APIcall) => API(data), {
|
const { send: sendAPI } = useRequest((data: APIcall) => API(data), {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import WarningIcon from '@mui/icons-material/Warning';
|
|||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
Grid2 as Grid,
|
Grid,
|
||||||
InputAdornment,
|
InputAdornment,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
TextField,
|
TextField,
|
||||||
@@ -254,102 +254,100 @@ const MqttSettings = () => {
|
|||||||
}
|
}
|
||||||
label={LL.MQTT_RESPONSE()}
|
label={LL.MQTT_RESPONSE()}
|
||||||
/>
|
/>
|
||||||
{!data.ha_enabled && (
|
<Grid container spacing={2} rowSpacing={0}>
|
||||||
<Grid container spacing={2} rowSpacing={0}>
|
<Grid>
|
||||||
|
<BlockFormControlLabel
|
||||||
|
control={
|
||||||
|
<Checkbox
|
||||||
|
name="publish_single"
|
||||||
|
checked={data.publish_single}
|
||||||
|
onChange={updateFormValue}
|
||||||
|
disabled={data.ha_enabled}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label={LL.MQTT_PUBLISH_TEXT_1()}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
{data.publish_single && (
|
||||||
<Grid>
|
<Grid>
|
||||||
<BlockFormControlLabel
|
<BlockFormControlLabel
|
||||||
control={
|
control={
|
||||||
<Checkbox
|
<Checkbox
|
||||||
name="publish_single"
|
name="publish_single2cmd"
|
||||||
checked={data.publish_single}
|
checked={data.publish_single2cmd}
|
||||||
onChange={updateFormValue}
|
onChange={updateFormValue}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
label={LL.MQTT_PUBLISH_TEXT_1()}
|
label={LL.MQTT_PUBLISH_TEXT_2()}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
{data.publish_single && (
|
)}
|
||||||
|
</Grid>
|
||||||
|
<Grid container spacing={2} rowSpacing={0}>
|
||||||
|
<Grid>
|
||||||
|
<BlockFormControlLabel
|
||||||
|
control={
|
||||||
|
<Checkbox
|
||||||
|
name="ha_enabled"
|
||||||
|
checked={data.ha_enabled}
|
||||||
|
onChange={updateFormValue}
|
||||||
|
disabled={data.publish_single}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label={LL.MQTT_PUBLISH_TEXT_3()}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
{data.ha_enabled && (
|
||||||
|
<Grid container spacing={2} rowSpacing={0}>
|
||||||
<Grid>
|
<Grid>
|
||||||
<BlockFormControlLabel
|
<TextField
|
||||||
control={
|
name="discovery_type"
|
||||||
<Checkbox
|
label={LL.MQTT_PUBLISH_TEXT_5()}
|
||||||
name="publish_single2cmd"
|
value={data.discovery_type}
|
||||||
checked={data.publish_single2cmd}
|
variant="outlined"
|
||||||
onChange={updateFormValue}
|
onChange={updateFormValue}
|
||||||
/>
|
margin="normal"
|
||||||
}
|
select
|
||||||
label={LL.MQTT_PUBLISH_TEXT_2()}
|
>
|
||||||
|
<MenuItem value={0}>Home Assistant</MenuItem>
|
||||||
|
<MenuItem value={1}>Domoticz</MenuItem>
|
||||||
|
<MenuItem value={2}>Domoticz (latest)</MenuItem>
|
||||||
|
</TextField>
|
||||||
|
</Grid>
|
||||||
|
<Grid>
|
||||||
|
<TextField
|
||||||
|
name="discovery_prefix"
|
||||||
|
label={LL.MQTT_PUBLISH_TEXT_4()}
|
||||||
|
variant="outlined"
|
||||||
|
value={data.discovery_prefix}
|
||||||
|
onChange={updateFormValue}
|
||||||
|
margin="normal"
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
)}
|
<Grid>
|
||||||
</Grid>
|
<TextField
|
||||||
)}
|
name="entity_format"
|
||||||
{!data.publish_single && (
|
label={LL.MQTT_ENTITY_FORMAT()}
|
||||||
<Grid container spacing={2} rowSpacing={0}>
|
value={data.entity_format}
|
||||||
<Grid>
|
variant="outlined"
|
||||||
<BlockFormControlLabel
|
onChange={updateFormValue}
|
||||||
control={
|
margin="normal"
|
||||||
<Checkbox
|
select
|
||||||
name="ha_enabled"
|
>
|
||||||
checked={data.ha_enabled}
|
<MenuItem value={0}>{LL.MQTT_ENTITY_FORMAT_0()}</MenuItem>
|
||||||
onChange={updateFormValue}
|
<MenuItem value={3}>
|
||||||
/>
|
{LL.MQTT_ENTITY_FORMAT_1()} (v3.6)
|
||||||
}
|
</MenuItem>
|
||||||
label={LL.MQTT_PUBLISH_TEXT_3()}
|
<MenuItem value={4}>
|
||||||
/>
|
{LL.MQTT_ENTITY_FORMAT_2()} (v3.6)
|
||||||
</Grid>
|
</MenuItem>
|
||||||
{data.ha_enabled && (
|
<MenuItem value={1}>{LL.MQTT_ENTITY_FORMAT_1()}</MenuItem>
|
||||||
<Grid container spacing={2} rowSpacing={0}>
|
<MenuItem value={2}>{LL.MQTT_ENTITY_FORMAT_2()}</MenuItem>
|
||||||
<Grid>
|
</TextField>
|
||||||
<TextField
|
|
||||||
name="discovery_type"
|
|
||||||
label={LL.MQTT_PUBLISH_TEXT_5()}
|
|
||||||
value={data.discovery_type}
|
|
||||||
variant="outlined"
|
|
||||||
onChange={updateFormValue}
|
|
||||||
margin="normal"
|
|
||||||
select
|
|
||||||
>
|
|
||||||
<MenuItem value={0}>Home Assistant</MenuItem>
|
|
||||||
<MenuItem value={1}>Domoticz</MenuItem>
|
|
||||||
<MenuItem value={2}>Domoticz (latest)</MenuItem>
|
|
||||||
</TextField>
|
|
||||||
</Grid>
|
|
||||||
<Grid>
|
|
||||||
<TextField
|
|
||||||
name="discovery_prefix"
|
|
||||||
label={LL.MQTT_PUBLISH_TEXT_4()}
|
|
||||||
variant="outlined"
|
|
||||||
value={data.discovery_prefix}
|
|
||||||
onChange={updateFormValue}
|
|
||||||
margin="normal"
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
<Grid>
|
|
||||||
<TextField
|
|
||||||
name="entity_format"
|
|
||||||
label={LL.MQTT_ENTITY_FORMAT()}
|
|
||||||
value={data.entity_format}
|
|
||||||
variant="outlined"
|
|
||||||
onChange={updateFormValue}
|
|
||||||
margin="normal"
|
|
||||||
select
|
|
||||||
>
|
|
||||||
<MenuItem value={0}>{LL.MQTT_ENTITY_FORMAT_0()}</MenuItem>
|
|
||||||
<MenuItem value={3}>
|
|
||||||
{LL.MQTT_ENTITY_FORMAT_1()} (v3.6)
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem value={4}>
|
|
||||||
{LL.MQTT_ENTITY_FORMAT_2()} (v3.6)
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem value={1}>{LL.MQTT_ENTITY_FORMAT_1()}</MenuItem>
|
|
||||||
<MenuItem value={2}>{LL.MQTT_ENTITY_FORMAT_2()}</MenuItem>
|
|
||||||
</TextField>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
)}
|
</Grid>
|
||||||
</Grid>
|
)}
|
||||||
)}
|
</Grid>
|
||||||
<Typography sx={{ pt: 2 }} variant="h6" color="primary">
|
<Typography sx={{ pt: 2 }} variant="h6" color="primary">
|
||||||
{LL.MQTT_PUBLISH_INTERVALS()} (0=auto)
|
{LL.MQTT_PUBLISH_INTERVALS()} (0=auto)
|
||||||
</Typography>
|
</Typography>
|
||||||
@@ -442,7 +440,7 @@ const MqttSettings = () => {
|
|||||||
<Grid>
|
<Grid>
|
||||||
<TextField
|
<TextField
|
||||||
name="publish_time_sensor"
|
name="publish_time_sensor"
|
||||||
label={LL.TEMP_SENSORS()}
|
label={LL.SENSORS()}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
value={numberValue(data.publish_time_sensor)}
|
value={numberValue(data.publish_time_sensor)}
|
||||||
type="number"
|
type="number"
|
||||||
|
|||||||
@@ -1,12 +1,27 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
|
import AccessTimeIcon from '@mui/icons-material/AccessTime';
|
||||||
import CancelIcon from '@mui/icons-material/Cancel';
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
import WarningIcon from '@mui/icons-material/Warning';
|
import WarningIcon from '@mui/icons-material/Warning';
|
||||||
import { Button, Checkbox, MenuItem } from '@mui/material';
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
Checkbox,
|
||||||
|
Dialog,
|
||||||
|
DialogActions,
|
||||||
|
DialogContent,
|
||||||
|
DialogTitle,
|
||||||
|
MenuItem,
|
||||||
|
TextField,
|
||||||
|
Typography
|
||||||
|
} from '@mui/material';
|
||||||
|
|
||||||
import * as NTPApi from 'api/ntp';
|
import * as NTPApi from 'api/ntp';
|
||||||
import { readNTPSettings } from 'api/ntp';
|
import { readNTPSettings } from 'api/ntp';
|
||||||
|
|
||||||
|
import { dialogStyle } from 'CustomTheme';
|
||||||
|
import { useRequest } from 'alova/client';
|
||||||
import { updateState } from 'alova/client';
|
import { updateState } from 'alova/client';
|
||||||
import type { ValidateFieldsError } from 'async-validator';
|
import type { ValidateFieldsError } from 'async-validator';
|
||||||
import {
|
import {
|
||||||
@@ -19,8 +34,8 @@ import {
|
|||||||
useLayoutTitle
|
useLayoutTitle
|
||||||
} from 'components';
|
} from 'components';
|
||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import type { NTPSettingsType } from 'types';
|
import type { NTPSettingsType, Time } from 'types';
|
||||||
import { updateValueDirty, useRest } from 'utils';
|
import { formatLocalDateTime, updateValueDirty, useRest } from 'utils';
|
||||||
import { validate } from 'validators';
|
import { validate } from 'validators';
|
||||||
import { NTP_SETTINGS_VALIDATOR } from 'validators/ntp';
|
import { NTP_SETTINGS_VALIDATOR } from 'validators/ntp';
|
||||||
|
|
||||||
@@ -46,6 +61,17 @@ const NTPSettings = () => {
|
|||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
useLayoutTitle('NTP');
|
useLayoutTitle('NTP');
|
||||||
|
|
||||||
|
const [localTime, setLocalTime] = useState<string>('');
|
||||||
|
const [settingTime, setSettingTime] = useState<boolean>(false);
|
||||||
|
const [processing, setProcessing] = useState<boolean>(false);
|
||||||
|
|
||||||
|
const { send: updateTime } = useRequest(
|
||||||
|
(local_time: Time) => NTPApi.updateTime(local_time),
|
||||||
|
{
|
||||||
|
immediate: false
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const updateFormValue = updateValueDirty(
|
const updateFormValue = updateValueDirty(
|
||||||
origData,
|
origData,
|
||||||
dirtyFlags,
|
dirtyFlags,
|
||||||
@@ -55,6 +81,78 @@ const NTPSettings = () => {
|
|||||||
|
|
||||||
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
|
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
|
||||||
|
|
||||||
|
const updateLocalTime = (event: React.ChangeEvent<HTMLInputElement>) =>
|
||||||
|
setLocalTime(event.target.value);
|
||||||
|
|
||||||
|
const openSetTime = () => {
|
||||||
|
setLocalTime(formatLocalDateTime(new Date()));
|
||||||
|
setSettingTime(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const configureTime = async () => {
|
||||||
|
setProcessing(true);
|
||||||
|
|
||||||
|
await updateTime({ local_time: formatLocalDateTime(new Date(localTime)) })
|
||||||
|
.then(async () => {
|
||||||
|
toast.success(LL.TIME_SET());
|
||||||
|
setSettingTime(false);
|
||||||
|
await loadData();
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
toast.error(LL.PROBLEM_UPDATING());
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setProcessing(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderSetTimeDialog = () => (
|
||||||
|
<Dialog
|
||||||
|
sx={dialogStyle}
|
||||||
|
open={settingTime}
|
||||||
|
onClose={() => setSettingTime(false)}
|
||||||
|
>
|
||||||
|
<DialogTitle>{LL.SET_TIME(1)}</DialogTitle>
|
||||||
|
<DialogContent dividers>
|
||||||
|
<Box color="warning.main" p={0} pl={0} pr={0} mt={0} mb={2}>
|
||||||
|
<Typography variant="body2">{LL.SET_TIME_TEXT()}</Typography>
|
||||||
|
</Box>
|
||||||
|
<TextField
|
||||||
|
label={LL.LOCAL_TIME(0)}
|
||||||
|
type="datetime-local"
|
||||||
|
value={localTime}
|
||||||
|
onChange={updateLocalTime}
|
||||||
|
disabled={processing}
|
||||||
|
fullWidth
|
||||||
|
slotProps={{
|
||||||
|
inputLabel: {
|
||||||
|
shrink: true
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button
|
||||||
|
startIcon={<CancelIcon />}
|
||||||
|
variant="outlined"
|
||||||
|
onClick={() => setSettingTime(false)}
|
||||||
|
color="secondary"
|
||||||
|
>
|
||||||
|
{LL.CANCEL()}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
startIcon={<AccessTimeIcon />}
|
||||||
|
variant="outlined"
|
||||||
|
onClick={configureTime}
|
||||||
|
disabled={processing}
|
||||||
|
color="primary"
|
||||||
|
>
|
||||||
|
{LL.UPDATE()}
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
|
||||||
const content = () => {
|
const content = () => {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return <FormLoader onRetry={loadData} errorMessage={errorMessage} />;
|
return <FormLoader onRetry={loadData} errorMessage={errorMessage} />;
|
||||||
@@ -115,6 +213,25 @@ const NTPSettings = () => {
|
|||||||
<MenuItem disabled>{LL.TIME_ZONE()}...</MenuItem>
|
<MenuItem disabled>{LL.TIME_ZONE()}...</MenuItem>
|
||||||
{timeZoneSelectItems()}
|
{timeZoneSelectItems()}
|
||||||
</ValidatedTextField>
|
</ValidatedTextField>
|
||||||
|
|
||||||
|
<Box display="flex" flexWrap="wrap">
|
||||||
|
{!data.enabled && !dirtyFlags.length && (
|
||||||
|
<Box flexWrap="nowrap" whiteSpace="nowrap">
|
||||||
|
<ButtonRow>
|
||||||
|
<Button
|
||||||
|
onClick={openSetTime}
|
||||||
|
variant="outlined"
|
||||||
|
color="primary"
|
||||||
|
startIcon={<AccessTimeIcon />}
|
||||||
|
>
|
||||||
|
{LL.SET_TIME(0)}
|
||||||
|
</Button>
|
||||||
|
</ButtonRow>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
{renderSetTimeDialog()}
|
||||||
|
|
||||||
{dirtyFlags && dirtyFlags.length !== 0 && (
|
{dirtyFlags && dirtyFlags.length !== 0 && (
|
||||||
<ButtonRow>
|
<ButtonRow>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -1,40 +1,27 @@
|
|||||||
import { useState } from 'react';
|
|
||||||
import { toast } from 'react-toastify';
|
|
||||||
|
|
||||||
import AccessTimeIcon from '@mui/icons-material/AccessTime';
|
import AccessTimeIcon from '@mui/icons-material/AccessTime';
|
||||||
import CancelIcon from '@mui/icons-material/Cancel';
|
|
||||||
import DnsIcon from '@mui/icons-material/Dns';
|
import DnsIcon from '@mui/icons-material/Dns';
|
||||||
import SwapVerticalCircleIcon from '@mui/icons-material/SwapVerticalCircle';
|
import SwapVerticalCircleIcon from '@mui/icons-material/SwapVerticalCircle';
|
||||||
import UpdateIcon from '@mui/icons-material/Update';
|
import UpdateIcon from '@mui/icons-material/Update';
|
||||||
import {
|
import {
|
||||||
Avatar,
|
Avatar,
|
||||||
Box,
|
|
||||||
Button,
|
|
||||||
Dialog,
|
|
||||||
DialogActions,
|
|
||||||
DialogContent,
|
|
||||||
DialogTitle,
|
|
||||||
Divider,
|
Divider,
|
||||||
List,
|
List,
|
||||||
ListItem,
|
ListItem,
|
||||||
ListItemAvatar,
|
ListItemAvatar,
|
||||||
ListItemText,
|
ListItemText,
|
||||||
TextField,
|
|
||||||
Typography,
|
|
||||||
useTheme
|
useTheme
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import type { Theme } from '@mui/material';
|
import type { Theme } from '@mui/material';
|
||||||
|
|
||||||
import * as NTPApi from 'api/ntp';
|
import * as NTPApi from 'api/ntp';
|
||||||
|
|
||||||
import { dialogStyle } from 'CustomTheme';
|
|
||||||
import { useRequest } from 'alova/client';
|
import { useRequest } from 'alova/client';
|
||||||
import { ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components';
|
import { FormLoader, SectionContent, useLayoutTitle } from 'components';
|
||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import type { NTPStatusType, Time } from 'types';
|
import type { NTPStatusType } from 'types';
|
||||||
import { NTPSyncStatus } from 'types';
|
import { NTPSyncStatus } from 'types';
|
||||||
import { useInterval } from 'utils';
|
import { useInterval } from 'utils';
|
||||||
import { formatDateTime, formatLocalDateTime } from 'utils';
|
import { formatDateTime } from 'utils';
|
||||||
|
|
||||||
const NTPStatus = () => {
|
const NTPStatus = () => {
|
||||||
const { data, send: loadData, error } = useRequest(NTPApi.readNTPStatus);
|
const { data, send: loadData, error } = useRequest(NTPApi.readNTPStatus);
|
||||||
@@ -43,24 +30,11 @@ const NTPStatus = () => {
|
|||||||
void loadData();
|
void loadData();
|
||||||
});
|
});
|
||||||
|
|
||||||
const [localTime, setLocalTime] = useState<string>('');
|
|
||||||
const [settingTime, setSettingTime] = useState<boolean>(false);
|
|
||||||
const [processing, setProcessing] = useState<boolean>(false);
|
|
||||||
|
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
useLayoutTitle('NTP');
|
useLayoutTitle('NTP');
|
||||||
|
|
||||||
const { send: updateTime } = useRequest(
|
|
||||||
(local_time: Time) => NTPApi.updateTime(local_time),
|
|
||||||
{
|
|
||||||
immediate: false
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
NTPApi.updateTime;
|
NTPApi.updateTime;
|
||||||
|
|
||||||
const isNtpActive = ({ status }: NTPStatusType) =>
|
|
||||||
status === NTPSyncStatus.NTP_ACTIVE;
|
|
||||||
const isNtpEnabled = ({ status }: NTPStatusType) =>
|
const isNtpEnabled = ({ status }: NTPStatusType) =>
|
||||||
status !== NTPSyncStatus.NTP_DISABLED;
|
status !== NTPSyncStatus.NTP_DISABLED;
|
||||||
|
|
||||||
@@ -77,14 +51,6 @@ const NTPStatus = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateLocalTime = (event: React.ChangeEvent<HTMLInputElement>) =>
|
|
||||||
setLocalTime(event.target.value);
|
|
||||||
|
|
||||||
const openSetTime = () => {
|
|
||||||
setLocalTime(formatLocalDateTime(new Date()));
|
|
||||||
setSettingTime(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const ntpStatus = ({ status }: NTPStatusType) => {
|
const ntpStatus = ({ status }: NTPStatusType) => {
|
||||||
@@ -100,70 +66,6 @@ const NTPStatus = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const configureTime = async () => {
|
|
||||||
setProcessing(true);
|
|
||||||
|
|
||||||
await updateTime({ local_time: formatLocalDateTime(new Date(localTime)) })
|
|
||||||
.then(async () => {
|
|
||||||
toast.success(LL.TIME_SET());
|
|
||||||
setSettingTime(false);
|
|
||||||
await loadData();
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
toast.error(LL.PROBLEM_UPDATING());
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
setProcessing(false);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const renderSetTimeDialog = () => (
|
|
||||||
<Dialog
|
|
||||||
sx={dialogStyle}
|
|
||||||
open={settingTime}
|
|
||||||
onClose={() => setSettingTime(false)}
|
|
||||||
>
|
|
||||||
<DialogTitle>{LL.SET_TIME(1)}</DialogTitle>
|
|
||||||
<DialogContent dividers>
|
|
||||||
<Box color="warning.main" p={0} pl={0} pr={0} mt={0} mb={2}>
|
|
||||||
<Typography variant="body2">{LL.SET_TIME_TEXT()}</Typography>
|
|
||||||
</Box>
|
|
||||||
<TextField
|
|
||||||
label={LL.LOCAL_TIME(0)}
|
|
||||||
type="datetime-local"
|
|
||||||
value={localTime}
|
|
||||||
onChange={updateLocalTime}
|
|
||||||
disabled={processing}
|
|
||||||
fullWidth
|
|
||||||
slotProps={{
|
|
||||||
inputLabel: {
|
|
||||||
shrink: true
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</DialogContent>
|
|
||||||
<DialogActions>
|
|
||||||
<Button
|
|
||||||
startIcon={<CancelIcon />}
|
|
||||||
variant="outlined"
|
|
||||||
onClick={() => setSettingTime(false)}
|
|
||||||
color="secondary"
|
|
||||||
>
|
|
||||||
{LL.CANCEL()}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
startIcon={<AccessTimeIcon />}
|
|
||||||
variant="outlined"
|
|
||||||
onClick={configureTime}
|
|
||||||
disabled={processing}
|
|
||||||
color="primary"
|
|
||||||
>
|
|
||||||
{LL.UPDATE()}
|
|
||||||
</Button>
|
|
||||||
</DialogActions>
|
|
||||||
</Dialog>
|
|
||||||
);
|
|
||||||
|
|
||||||
const content = () => {
|
const content = () => {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return <FormLoader onRetry={loadData} errorMessage={error?.message} />;
|
return <FormLoader onRetry={loadData} errorMessage={error?.message} />;
|
||||||
@@ -219,23 +121,6 @@ const NTPStatus = () => {
|
|||||||
</ListItem>
|
</ListItem>
|
||||||
<Divider variant="inset" component="li" />
|
<Divider variant="inset" component="li" />
|
||||||
</List>
|
</List>
|
||||||
<Box display="flex" flexWrap="wrap">
|
|
||||||
{data && !isNtpActive(data) && (
|
|
||||||
<Box flexWrap="nowrap" whiteSpace="nowrap">
|
|
||||||
<ButtonRow>
|
|
||||||
<Button
|
|
||||||
onClick={openSetTime}
|
|
||||||
variant="outlined"
|
|
||||||
color="primary"
|
|
||||||
startIcon={<AccessTimeIcon />}
|
|
||||||
>
|
|
||||||
{LL.SET_TIME(0)}
|
|
||||||
</Button>
|
|
||||||
</ButtonRow>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
{renderSetTimeDialog()}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
Grid2 as Grid,
|
Grid,
|
||||||
IconButton,
|
IconButton,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
TextField,
|
TextField,
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ const SystemMonitor = () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.onError((error) => {
|
.onError((error) => {
|
||||||
setErrorMessage(error.message);
|
setErrorMessage(String(error.error?.message || 'An error occurred'));
|
||||||
});
|
});
|
||||||
|
|
||||||
useInterval(() => {
|
useInterval(() => {
|
||||||
@@ -97,7 +97,7 @@ const SystemMonitor = () => {
|
|||||||
color="error"
|
color="error"
|
||||||
onClick={onCancel}
|
onClick={onCancel}
|
||||||
>
|
>
|
||||||
{LL.RESET(0)}
|
{LL.RESTART()}
|
||||||
</Button>
|
</Button>
|
||||||
</MessageBox>
|
</MessageBox>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ import { useContext, useEffect, useState } from 'react';
|
|||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
import CancelIcon from '@mui/icons-material/Cancel';
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
|
import CloseIcon from '@mui/icons-material/Close';
|
||||||
import CheckIcon from '@mui/icons-material/Done';
|
import CheckIcon from '@mui/icons-material/Done';
|
||||||
import DownloadIcon from '@mui/icons-material/GetApp';
|
import DownloadIcon from '@mui/icons-material/GetApp';
|
||||||
import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';
|
|
||||||
import WarningIcon from '@mui/icons-material/Warning';
|
import WarningIcon from '@mui/icons-material/Warning';
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
@@ -15,7 +15,7 @@ import {
|
|||||||
DialogContent,
|
DialogContent,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
FormControlLabel,
|
FormControlLabel,
|
||||||
Grid2 as Grid,
|
Grid,
|
||||||
Link,
|
Link,
|
||||||
Typography
|
Typography
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
@@ -44,7 +44,10 @@ const Version = () => {
|
|||||||
const [restarting, setRestarting] = useState<boolean>(false);
|
const [restarting, setRestarting] = useState<boolean>(false);
|
||||||
const [openInstallDialog, setOpenInstallDialog] = useState<boolean>(false);
|
const [openInstallDialog, setOpenInstallDialog] = useState<boolean>(false);
|
||||||
const [usingDevVersion, setUsingDevVersion] = useState<boolean>(false);
|
const [usingDevVersion, setUsingDevVersion] = useState<boolean>(false);
|
||||||
const [upgradeAvailable, setUpgradeAvailable] = useState<boolean>(false);
|
const [fetchDevVersion, setFetchDevVersion] = useState<boolean>(false);
|
||||||
|
const [devUpgradeAvailable, setDevUpgradeAvailable] = useState<boolean>(false);
|
||||||
|
const [stableUpgradeAvailable, setStableUpgradeAvailable] =
|
||||||
|
useState<boolean>(false);
|
||||||
const [internetLive, setInternetLive] = useState<boolean>(false);
|
const [internetLive, setInternetLive] = useState<boolean>(false);
|
||||||
const [downloadOnly, setDownloadOnly] = useState<boolean>(false);
|
const [downloadOnly, setDownloadOnly] = useState<boolean>(false);
|
||||||
|
|
||||||
@@ -62,8 +65,13 @@ const Version = () => {
|
|||||||
immediate: false
|
immediate: false
|
||||||
}
|
}
|
||||||
).onSuccess((event) => {
|
).onSuccess((event) => {
|
||||||
const data = event.data as { emsesp_version: string; upgradeable: boolean };
|
const data = event.data as {
|
||||||
setUpgradeAvailable(data.upgradeable);
|
emsesp_version: string;
|
||||||
|
dev_upgradeable: boolean;
|
||||||
|
stable_upgradeable: boolean;
|
||||||
|
};
|
||||||
|
setDevUpgradeAvailable(data.dev_upgradeable);
|
||||||
|
setStableUpgradeAvailable(data.stable_upgradeable);
|
||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -71,7 +79,7 @@ const Version = () => {
|
|||||||
send: loadData,
|
send: loadData,
|
||||||
error
|
error
|
||||||
} = useRequest(SystemApi.readSystemStatus).onSuccess((event) => {
|
} = useRequest(SystemApi.readSystemStatus).onSuccess((event) => {
|
||||||
// older version of EMS-ESP on 4MB boards, can't use OTA because of SSL support in HttpClient
|
// older version of EMS-ESP using ESP32 (not S3) and no PSRAM, can't use OTA because of SSL support in HttpClient
|
||||||
if (event.data.arduino_version.startsWith('Tasmota')) {
|
if (event.data.arduino_version.startsWith('Tasmota')) {
|
||||||
setDownloadOnly(true);
|
setDownloadOnly(true);
|
||||||
}
|
}
|
||||||
@@ -138,20 +146,21 @@ const Version = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getBinURL = () => {
|
const getBinURL = (showingDev: boolean) => {
|
||||||
if (!internetLive) {
|
if (!internetLive) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
const filename =
|
const filename =
|
||||||
'EMS-ESP-' +
|
'EMS-ESP-' +
|
||||||
(usingDevVersion ? latestDevVersion.name : latestVersion.name).replaceAll(
|
(showingDev ? latestDevVersion.name : latestVersion.name).replaceAll(
|
||||||
'.',
|
'.',
|
||||||
'_'
|
'_'
|
||||||
) +
|
) +
|
||||||
'-' +
|
'-' +
|
||||||
getPlatform() +
|
getPlatform() +
|
||||||
'.bin';
|
'.bin';
|
||||||
return usingDevVersion
|
return showingDev
|
||||||
? DEV_URL + filename
|
? DEV_URL + filename
|
||||||
: STABLE_URL + 'v' + latestVersion.name + '/' + filename;
|
: STABLE_URL + 'v' + latestVersion.name + '/' + filename;
|
||||||
};
|
};
|
||||||
@@ -172,100 +181,112 @@ const Version = () => {
|
|||||||
|
|
||||||
useLayoutTitle('EMS-ESP Firmware');
|
useLayoutTitle('EMS-ESP Firmware');
|
||||||
|
|
||||||
const renderInstallDialog = () => (
|
const renderInstallDialog = () => {
|
||||||
<Dialog
|
const binURL = getBinURL(fetchDevVersion);
|
||||||
sx={dialogStyle}
|
|
||||||
open={openInstallDialog}
|
|
||||||
onClose={() => closeInstallDialog()}
|
|
||||||
>
|
|
||||||
<DialogTitle>
|
|
||||||
{LL.INSTALL() +
|
|
||||||
' ' +
|
|
||||||
(usingDevVersion ? LL.DEVELOPMENT() : LL.STABLE()) +
|
|
||||||
' Firmware'}
|
|
||||||
</DialogTitle>
|
|
||||||
<DialogContent dividers>
|
|
||||||
<Typography mb={2}>
|
|
||||||
{LL.INSTALL_VERSION(
|
|
||||||
usingDevVersion ? latestDevVersion?.name : latestVersion?.name
|
|
||||||
)}
|
|
||||||
</Typography>
|
|
||||||
</DialogContent>
|
|
||||||
<DialogActions>
|
|
||||||
<Button
|
|
||||||
startIcon={<CancelIcon />}
|
|
||||||
variant="outlined"
|
|
||||||
onClick={() => closeInstallDialog()}
|
|
||||||
color="secondary"
|
|
||||||
>
|
|
||||||
{LL.CANCEL()}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
startIcon={<DownloadIcon />}
|
|
||||||
variant="outlined"
|
|
||||||
onClick={() => closeInstallDialog()}
|
|
||||||
color="primary"
|
|
||||||
>
|
|
||||||
<Link underline="none" target="_blank" href={getBinURL()} color="primary">
|
|
||||||
{LL.DOWNLOAD(1)}
|
|
||||||
</Link>
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
startIcon={<WarningIcon color="warning" />}
|
|
||||||
variant="outlined"
|
|
||||||
onClick={() => installFirmwareURL(getBinURL())}
|
|
||||||
color="primary"
|
|
||||||
>
|
|
||||||
{LL.INSTALL()}
|
|
||||||
</Button>
|
|
||||||
</DialogActions>
|
|
||||||
</Dialog>
|
|
||||||
);
|
|
||||||
|
|
||||||
const showFirmwareDialog = (useDevVersion?: boolean) => {
|
return (
|
||||||
setUsingDevVersion(useDevVersion || usingDevVersion);
|
<Dialog
|
||||||
|
sx={dialogStyle}
|
||||||
|
open={openInstallDialog}
|
||||||
|
onClose={() => closeInstallDialog()}
|
||||||
|
>
|
||||||
|
<DialogTitle>
|
||||||
|
{LL.UPDATE() +
|
||||||
|
' ' +
|
||||||
|
(fetchDevVersion ? LL.DEVELOPMENT() : LL.STABLE()) +
|
||||||
|
' Firmware'}
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogContent dividers>
|
||||||
|
<Typography mb={2}>
|
||||||
|
{LL.INSTALL_VERSION(
|
||||||
|
downloadOnly ? LL.DOWNLOAD(1) : LL.INSTALL(),
|
||||||
|
fetchDevVersion ? latestDevVersion?.name : latestVersion?.name
|
||||||
|
)}
|
||||||
|
</Typography>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button
|
||||||
|
startIcon={<CancelIcon />}
|
||||||
|
variant="outlined"
|
||||||
|
onClick={() => closeInstallDialog()}
|
||||||
|
color="secondary"
|
||||||
|
>
|
||||||
|
{LL.CANCEL()}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
startIcon={<DownloadIcon />}
|
||||||
|
variant="outlined"
|
||||||
|
onClick={() => closeInstallDialog()}
|
||||||
|
color="primary"
|
||||||
|
>
|
||||||
|
<Link underline="none" target="_blank" href={binURL} color="primary">
|
||||||
|
{LL.DOWNLOAD(0)}
|
||||||
|
</Link>
|
||||||
|
</Button>
|
||||||
|
{!downloadOnly && (
|
||||||
|
<Button
|
||||||
|
startIcon={<WarningIcon color="warning" />}
|
||||||
|
variant="outlined"
|
||||||
|
onClick={() => installFirmwareURL(binURL)}
|
||||||
|
color="primary"
|
||||||
|
>
|
||||||
|
{LL.INSTALL()}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const showFirmwareDialog = (useDevVersion: boolean) => {
|
||||||
|
setFetchDevVersion(useDevVersion);
|
||||||
setOpenInstallDialog(true);
|
setOpenInstallDialog(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const closeInstallDialog = () => {
|
const closeInstallDialog = () => {
|
||||||
setOpenInstallDialog(false);
|
setOpenInstallDialog(false);
|
||||||
setUsingDevVersion(data.emsesp_version.includes('dev'));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const showButtons = (showDev?: boolean) => {
|
const showButtons = (showingDev: boolean) => {
|
||||||
if (!me.admin) {
|
const choice = showingDev
|
||||||
return;
|
? !usingDevVersion
|
||||||
|
? LL.SWITCH_RELEASE_TYPE(LL.DEVELOPMENT())
|
||||||
|
: devUpgradeAvailable
|
||||||
|
? LL.UPDATE_AVAILABLE()
|
||||||
|
: undefined
|
||||||
|
: usingDevVersion
|
||||||
|
? LL.SWITCH_RELEASE_TYPE(LL.STABLE())
|
||||||
|
: stableUpgradeAvailable
|
||||||
|
? LL.UPDATE_AVAILABLE()
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
if (!choice) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<CheckIcon
|
||||||
|
color="success"
|
||||||
|
sx={{ verticalAlign: 'middle', ml: 0.5, mr: 0.5 }}
|
||||||
|
/>
|
||||||
|
<span style={{ color: '#66bb6a', fontSize: '0.8em' }}>
|
||||||
|
{LL.LATEST_VERSION(usingDevVersion ? LL.DEVELOPMENT() : LL.STABLE())}
|
||||||
|
</span>
|
||||||
|
</>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (downloadOnly) {
|
if (!me.admin) {
|
||||||
return (
|
return;
|
||||||
<Button
|
|
||||||
sx={{ ml: 2 }}
|
|
||||||
startIcon={<DownloadIcon />}
|
|
||||||
variant="outlined"
|
|
||||||
onClick={() => setOpenInstallDialog(false)}
|
|
||||||
color="warning"
|
|
||||||
size="small"
|
|
||||||
>
|
|
||||||
<Link underline="none" target="_blank" href={getBinURL()} color="warning">
|
|
||||||
{LL.DOWNLOAD(1)}
|
|
||||||
</Link>
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
sx={{ ml: 2 }}
|
sx={{ ml: 2 }}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
color="warning"
|
color={choice === LL.UPDATE_AVAILABLE() ? 'success' : 'warning'}
|
||||||
size="small"
|
size="small"
|
||||||
onClick={() => showFirmwareDialog()}
|
onClick={() => showFirmwareDialog(showingDev)}
|
||||||
>
|
>
|
||||||
{upgradeAvailable || (!usingDevVersion && showDev)
|
{choice}
|
||||||
? LL.UPGRADE()
|
|
||||||
: LL.REINSTALL()}
|
|
||||||
…
|
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -314,7 +335,25 @@ const Version = () => {
|
|||||||
<Typography>
|
<Typography>
|
||||||
{getPlatform()}
|
{getPlatform()}
|
||||||
<Typography variant="caption">
|
<Typography variant="caption">
|
||||||
({data.psram ? '+PSRAM' : '-PSRAM'})
|
(
|
||||||
|
{data.psram ? (
|
||||||
|
<CheckIcon
|
||||||
|
color="success"
|
||||||
|
sx={{
|
||||||
|
fontSize: '1.5em',
|
||||||
|
verticalAlign: 'middle'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<CloseIcon
|
||||||
|
color="error"
|
||||||
|
sx={{
|
||||||
|
fontSize: '1.5em',
|
||||||
|
verticalAlign: 'middle'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
PSRAM)
|
||||||
</Typography>
|
</Typography>
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -395,7 +434,7 @@ const Version = () => {
|
|||||||
{formatTimeAgo(new Date(latestVersion.published_at))})
|
{formatTimeAgo(new Date(latestVersion.published_at))})
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
{!usingDevVersion && showButtons(false)}
|
{showButtons(false)}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
@@ -417,24 +456,6 @@ const Version = () => {
|
|||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
{upgradeAvailable ? (
|
|
||||||
<Typography mt={2} color="warning">
|
|
||||||
<InfoOutlinedIcon
|
|
||||||
color="warning"
|
|
||||||
sx={{ verticalAlign: 'middle', mr: 2 }}
|
|
||||||
/>
|
|
||||||
{LL.UPGRADE_AVAILABLE()}
|
|
||||||
</Typography>
|
|
||||||
) : (
|
|
||||||
<Typography mt={2} color="success">
|
|
||||||
<CheckIcon
|
|
||||||
color="success"
|
|
||||||
sx={{ verticalAlign: 'middle', mr: 2 }}
|
|
||||||
/>
|
|
||||||
{LL.LATEST_VERSION()}
|
|
||||||
</Typography>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<Typography mt={2} color="warning">
|
<Typography mt={2} color="warning">
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ export function getStorage() {
|
|||||||
|
|
||||||
export function storeLoginRedirect(location?: H.Location) {
|
export function storeLoginRedirect(location?: H.Location) {
|
||||||
if (location) {
|
if (location) {
|
||||||
getStorage().setItem(SIGN_IN_PATHNAME, location.pathname);
|
getStorage().setItem(SIGN_IN_PATHNAME, location.pathname as string);
|
||||||
getStorage().setItem(SIGN_IN_SEARCH, location.search);
|
getStorage().setItem(SIGN_IN_SEARCH, location.search as string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ const cz: Translation = {
|
|||||||
COMPACT: 'Kompaktní',
|
COMPACT: 'Kompaktní',
|
||||||
DOWNLOAD_SETTINGS_TEXT: 'Vytvořte zálohu svého nastavení a konfigurace',
|
DOWNLOAD_SETTINGS_TEXT: 'Vytvořte zálohu svého nastavení a konfigurace',
|
||||||
UPLOAD_TEXT: 'Nahrajte nový soubor firmwaru (.bin) nebo záložní soubor (.json)',
|
UPLOAD_TEXT: 'Nahrajte nový soubor firmwaru (.bin) nebo záložní soubor (.json)',
|
||||||
UPLOAD_DROP_TEXT: 'Drop a firmware .bin file or click here', // TODO translate
|
UPLOAD_DROP_TEXT: 'Přetáhněte soubor sem nebo klikněte pro výběr',
|
||||||
ERROR: 'Neočekávaná chyba, zkuste to prosím znovu',
|
ERROR: 'Neočekávaná chyba, zkuste to prosím znovu',
|
||||||
TIME_SET: 'Čas nastaven',
|
TIME_SET: 'Čas nastaven',
|
||||||
MANAGE_USERS: 'Spravovat uživatele',
|
MANAGE_USERS: 'Spravovat uživatele',
|
||||||
@@ -331,28 +331,27 @@ const cz: Translation = {
|
|||||||
ALLVALUES: 'Všechny hodnoty',
|
ALLVALUES: 'Všechny hodnoty',
|
||||||
SPECIAL_FUNCTIONS: 'Speciální funkce',
|
SPECIAL_FUNCTIONS: 'Speciální funkce',
|
||||||
WAIT_FIRMWARE: 'Firmware se nahrává a instaluje',
|
WAIT_FIRMWARE: 'Firmware se nahrává a instaluje',
|
||||||
INSTALL_VERSION: 'Tímto se instalovat verze {0}. Jste si jistí?',
|
INSTALL_VERSION: 'Tímto se {0} verze {1}. Jste si jistí?',
|
||||||
UPGRADE_AVAILABLE: 'Je k dispozici aktualizace firmwaru!',
|
UPDATE_AVAILABLE: 'aktualizace dostupná',
|
||||||
LATEST_VERSION: 'Používáte nejnovější verzi firmwaru',
|
LATEST_VERSION: 'Používáte nejnovější verzi {0}firmwaru',
|
||||||
PLEASE_WAIT: 'Prosím čekejte',
|
PLEASE_WAIT: 'Prosím čekejte',
|
||||||
RESTARTING_PRE: 'Inicializace',
|
RESTARTING_PRE: 'Inicializace',
|
||||||
RESTARTING_POST: 'Příprava',
|
RESTARTING_POST: 'Příprava',
|
||||||
AUTO_SCROLL: 'Automatické rolování',
|
AUTO_SCROLL: 'Automatické rolování',
|
||||||
DASHBOARD: 'Dashboard',
|
DASHBOARD: 'Dashboard',
|
||||||
DEVELOPER_MODE: 'Režim vývojáře',
|
DEVELOPER_MODE: 'Režim vývojáře',
|
||||||
BYTES: 'Bytes', // TODO translate
|
BYTES: 'Bajty',
|
||||||
BITMASK: 'Bit Mask',// TODO translate
|
BITMASK: 'Bit Mask',
|
||||||
DUPLICATE: 'Duplikát',
|
DUPLICATE: 'Duplikát',
|
||||||
UPGRADE: 'Upgrade',
|
|
||||||
DASHBOARD_1: 'Všechny aktivní entity EMS jsou označené jako oblíbené. Všechny vlastní entity, harmonogramy a externí sensory jsou zobrazeny níže.',
|
DASHBOARD_1: 'Všechny aktivní entity EMS jsou označené jako oblíbené. Všechny vlastní entity, harmonogramy a externí sensory jsou zobrazeny níže.',
|
||||||
NO_DATA_1: 'Nebyly nalezeny žádné oblíbené entity. Použijte',
|
NO_DATA_1: 'Nebyly nalezeny žádné oblíbené entity. Použijte modul',
|
||||||
NO_DATA_2: 'modul sloužící k jejich výběru.',
|
NO_DATA_2: 'pro jejich výběr.',
|
||||||
NO_DATA_3: 'Pro zobrazení všech dostupných entit navštivte',
|
NO_DATA_3: 'Pro zobrazení všech dostupných entit navštivte stránku',
|
||||||
THIS_VERSION: 'Tato verze',
|
THIS_VERSION: 'Tato verze',
|
||||||
PLATFORM: 'Platforma',
|
PLATFORM: 'Platforma',
|
||||||
RELEASE_TYPE: 'Typ sestavení',
|
RELEASE_TYPE: 'Typ sestavení',
|
||||||
REINSTALL: 'Přeinstalovat',
|
|
||||||
INTERNET_CONNECTION_REQUIRED: 'Pro automatickou kontrolu a instalaci aktualizací je třeba internetové připojení',
|
INTERNET_CONNECTION_REQUIRED: 'Pro automatickou kontrolu a instalaci aktualizací je třeba internetové připojení',
|
||||||
|
SWITCH_RELEASE_TYPE: 'Přepnout na {0} verzi'
|
||||||
};
|
};
|
||||||
|
|
||||||
export default cz;
|
export default cz;
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ const de: Translation = {
|
|||||||
CANCEL: 'Abbrechen',
|
CANCEL: 'Abbrechen',
|
||||||
RESET: 'Zurücksetzen',
|
RESET: 'Zurücksetzen',
|
||||||
APPLY_CHANGES: 'Änderungen anwenden ({0})',
|
APPLY_CHANGES: 'Änderungen anwenden ({0})',
|
||||||
UPDATE: 'Update',
|
UPDATE: 'Aktualisieren',
|
||||||
EXECUTE: 'Ausführen',
|
EXECUTE: 'Ausführen',
|
||||||
REMOVE: 'Entfernen',
|
REMOVE: 'Entfernen',
|
||||||
PROBLEM_UPDATING: 'Problem beim Aktualisieren',
|
PROBLEM_UPDATING: 'Problem beim Aktualisieren',
|
||||||
@@ -160,7 +160,7 @@ const de: Translation = {
|
|||||||
HELP_INFORMATION_3: 'Um neue Funktionen anzufragen oder Fehler zu melden, eröffnen Sie ein Issue auf GitHub',
|
HELP_INFORMATION_3: 'Um neue Funktionen anzufragen oder Fehler zu melden, eröffnen Sie ein Issue auf GitHub',
|
||||||
HELP_INFORMATION_4: 'Bitte laden Sie die Systemdetails und hängen Sie sie an das Support-Issue an',
|
HELP_INFORMATION_4: 'Bitte laden Sie die Systemdetails und hängen Sie sie an das Support-Issue an',
|
||||||
UPLOAD: 'Hochladen',
|
UPLOAD: 'Hochladen',
|
||||||
DOWNLOAD: '{{H|h|h}}erunterladen',
|
DOWNLOAD: '{{Herunterladen|heruntergeladen|}}',
|
||||||
INSTALL: 'Installieren',
|
INSTALL: 'Installieren',
|
||||||
ABORTED: 'abgebrochen',
|
ABORTED: 'abgebrochen',
|
||||||
FAILED: 'gescheitert',
|
FAILED: 'gescheitert',
|
||||||
@@ -331,9 +331,9 @@ const de: Translation = {
|
|||||||
ALLVALUES: 'Alle Werte',
|
ALLVALUES: 'Alle Werte',
|
||||||
SPECIAL_FUNCTIONS: 'Sonderfunktionen',
|
SPECIAL_FUNCTIONS: 'Sonderfunktionen',
|
||||||
WAIT_FIRMWARE: 'Die Firmware wird hochgeladen und installiert.',
|
WAIT_FIRMWARE: 'Die Firmware wird hochgeladen und installiert.',
|
||||||
INSTALL_VERSION: 'Dadurch wird die Version {0} heruntergeladen. Sind Sie sicher?',
|
INSTALL_VERSION: 'Dadurch wird die Version {1} {0}. Sind Sie sicher?',
|
||||||
UPGRADE_AVAILABLE: 'Es ist ein Firmware-Upgrade verfügbar.',
|
UPDATE_AVAILABLE: 'Firmware-Update verfügbar',
|
||||||
LATEST_VERSION: 'Sie verwenden die neueste Firmware-Version',
|
LATEST_VERSION: 'Sie verwenden die neueste {0} Firmware-Version',
|
||||||
PLEASE_WAIT: 'Bitte warten',
|
PLEASE_WAIT: 'Bitte warten',
|
||||||
RESTARTING_PRE: 'Initialisierung',
|
RESTARTING_PRE: 'Initialisierung',
|
||||||
RESTARTING_POST: 'Vorbereitung',
|
RESTARTING_POST: 'Vorbereitung',
|
||||||
@@ -343,7 +343,6 @@ const de: Translation = {
|
|||||||
BYTES: 'Bytes',
|
BYTES: 'Bytes',
|
||||||
BITMASK: 'Bit Maske',
|
BITMASK: 'Bit Maske',
|
||||||
DUPLICATE: 'Kopieren',
|
DUPLICATE: 'Kopieren',
|
||||||
UPGRADE: 'Aktualisieren',
|
|
||||||
DASHBOARD_1: 'Alle EMS-Entitäten, die aktiv und als Favorit markiert sind, sowie alle benutzerdefinierten Entitäten, Zeitpläne und externen Sensordaten werden unten angezeigt.',
|
DASHBOARD_1: 'Alle EMS-Entitäten, die aktiv und als Favorit markiert sind, sowie alle benutzerdefinierten Entitäten, Zeitpläne und externen Sensordaten werden unten angezeigt.',
|
||||||
NO_DATA_1: 'Keine favorisierten EMS-Entitäten gefunden! Verwenden Sie das Modul',
|
NO_DATA_1: 'Keine favorisierten EMS-Entitäten gefunden! Verwenden Sie das Modul',
|
||||||
NO_DATA_2: ', um sie zu markieren.',
|
NO_DATA_2: ', um sie zu markieren.',
|
||||||
@@ -351,8 +350,8 @@ const de: Translation = {
|
|||||||
THIS_VERSION: 'Diese Version',
|
THIS_VERSION: 'Diese Version',
|
||||||
PLATFORM: 'Plattform',
|
PLATFORM: 'Plattform',
|
||||||
RELEASE_TYPE: 'Release Typ',
|
RELEASE_TYPE: 'Release Typ',
|
||||||
REINSTALL: 'Neu installieren',
|
INTERNET_CONNECTION_REQUIRED: 'Für die automatische Versionsprüfung und Aktualisierung ist eine Internetverbindung erforderlich',
|
||||||
INTERNET_CONNECTION_REQUIRED: 'Internetverbindung erforderlich für automatische Version-Überprüfung und -Aktualisierung',
|
SWITCH_RELEASE_TYPE: 'Zum {0}-Release wechseln'
|
||||||
};
|
};
|
||||||
|
|
||||||
export default de;
|
export default de;
|
||||||
|
|||||||
@@ -331,9 +331,9 @@ const en: Translation = {
|
|||||||
ALLVALUES: 'All Values',
|
ALLVALUES: 'All Values',
|
||||||
SPECIAL_FUNCTIONS: 'Special Functions',
|
SPECIAL_FUNCTIONS: 'Special Functions',
|
||||||
WAIT_FIRMWARE: 'Firmware is uploading and installing',
|
WAIT_FIRMWARE: 'Firmware is uploading and installing',
|
||||||
INSTALL_VERSION: 'This will install version {0}. Are you sure?',
|
INSTALL_VERSION: 'This will {0} version {1}. Are you sure?',
|
||||||
UPGRADE_AVAILABLE: 'There is a firmware upgrade available!',
|
UPDATE_AVAILABLE: 'update available',
|
||||||
LATEST_VERSION: 'You are using the latest firmware version',
|
LATEST_VERSION: 'You are using the latest {0} firmware version',
|
||||||
PLEASE_WAIT: 'Please wait',
|
PLEASE_WAIT: 'Please wait',
|
||||||
RESTARTING_PRE: 'Initializing',
|
RESTARTING_PRE: 'Initializing',
|
||||||
RESTARTING_POST: 'Preparing',
|
RESTARTING_POST: 'Preparing',
|
||||||
@@ -344,15 +344,14 @@ const en: Translation = {
|
|||||||
BYTES: 'Bytes',
|
BYTES: 'Bytes',
|
||||||
BITMASK: 'Bit Mask',
|
BITMASK: 'Bit Mask',
|
||||||
DUPLICATE: 'Duplicate',
|
DUPLICATE: 'Duplicate',
|
||||||
UPGRADE: 'Upgrade',
|
|
||||||
NO_DATA_1: 'No favorite EMS entities found yet. Use the',
|
NO_DATA_1: 'No favorite EMS entities found yet. Use the',
|
||||||
NO_DATA_2: 'module to mark them.',
|
NO_DATA_2: 'module to mark them.',
|
||||||
NO_DATA_3: 'To see all available entities go to',
|
NO_DATA_3: 'To see all available entities go to',
|
||||||
THIS_VERSION: 'This Version',
|
THIS_VERSION: 'This Version',
|
||||||
PLATFORM: 'Platform',
|
PLATFORM: 'Platform',
|
||||||
RELEASE_TYPE: 'Release Type',
|
RELEASE_TYPE: 'Release Type',
|
||||||
REINSTALL: 'Re-install',
|
|
||||||
INTERNET_CONNECTION_REQUIRED: 'Internet connection required for automatic version checking and upgrading',
|
INTERNET_CONNECTION_REQUIRED: 'Internet connection required for automatic version checking and upgrading',
|
||||||
|
SWITCH_RELEASE_TYPE: 'Switch to {0} release'
|
||||||
};
|
};
|
||||||
|
|
||||||
export default en;
|
export default en;
|
||||||
|
|||||||
@@ -41,9 +41,9 @@ const fr: Translation = {
|
|||||||
CHANGE_VALUE: 'Changer la valeur',
|
CHANGE_VALUE: 'Changer la valeur',
|
||||||
CANCEL: 'Annuler',
|
CANCEL: 'Annuler',
|
||||||
RESET: 'Réinitialiser',
|
RESET: 'Réinitialiser',
|
||||||
APPLY_CHANGES: 'Apply Changes ({0})', // TODO translate
|
APPLY_CHANGES: 'Appliquer les changements ({0})',
|
||||||
UPDATE: 'Update', // TODO translate
|
UPDATE: 'Update',
|
||||||
EXECUTE: 'Execute', // TODO translate
|
EXECUTE: 'Execute',
|
||||||
REMOVE: 'Enlever',
|
REMOVE: 'Enlever',
|
||||||
PROBLEM_UPDATING: 'Problème lors de la mise à jour',
|
PROBLEM_UPDATING: 'Problème lors de la mise à jour',
|
||||||
PROBLEM_LOADING: 'Problème lors du chargement',
|
PROBLEM_LOADING: 'Problème lors du chargement',
|
||||||
@@ -66,13 +66,13 @@ const fr: Translation = {
|
|||||||
TEMP_SENSOR: 'Capteur de température',
|
TEMP_SENSOR: 'Capteur de température',
|
||||||
TEMP_SENSORS: 'Capteurs de température',
|
TEMP_SENSORS: 'Capteurs de température',
|
||||||
WRITE_CMD_SENT: 'Envoyer la commande sent',
|
WRITE_CMD_SENT: 'Envoyer la commande sent',
|
||||||
EMS_BUS_WARNING: 'Bus EMS déconnecté. Si ce message persiste après quelques secondes, vérifiez les paramètres et la configuration de la carte.',
|
EMS_BUS_WARNING: 'Bus EMS déconnecté. Si ce message persiste après quelques secondes, vérifiez les paramètres et la configuration de la carte.',
|
||||||
EMS_BUS_SCANNING: 'Scan des appareils EMS...',
|
EMS_BUS_SCANNING: 'Scan des appareils EMS...',
|
||||||
CONNECTED: 'Connecté',
|
CONNECTED: 'Connecté',
|
||||||
TX_ISSUES: 'Problèmes de transmission (Tx) - Essayez un autre mode Tx',
|
TX_ISSUES: 'Problèmes de transmission (Tx) - Essayez un autre mode Tx',
|
||||||
DISCONNECTED: 'Déconnecté',
|
DISCONNECTED: 'Déconnecté',
|
||||||
EMS_SCAN: 'Etes-vous sûr de vouloir lancer un scan complet du bus EMS ?',
|
EMS_SCAN: 'Etes-vous sûr de vouloir lancer un scan complet du bus EMS ?',
|
||||||
DATA_TRAFFIC: 'Data Traffic', // TODO translate
|
DATA_TRAFFIC: 'Traffic des données',
|
||||||
EMS_DEVICE: 'Appareils EMS',
|
EMS_DEVICE: 'Appareils EMS',
|
||||||
SUCCESS: 'SUCCÈS',
|
SUCCESS: 'SUCCÈS',
|
||||||
FAIL: 'ÉCHEC',
|
FAIL: 'ÉCHEC',
|
||||||
@@ -114,9 +114,9 @@ const fr: Translation = {
|
|||||||
BYPASS_TOKEN: "Contourner l'autorisation du jeton d'accès sur les appels API",
|
BYPASS_TOKEN: "Contourner l'autorisation du jeton d'accès sur les appels API",
|
||||||
READONLY: 'Activer le mode lecture uniquement (bloque toutes les commandes EMS sortantes en écriture Tx)',
|
READONLY: 'Activer le mode lecture uniquement (bloque toutes les commandes EMS sortantes en écriture Tx)',
|
||||||
UNDERCLOCK_CPU: 'Underclock du CPU',
|
UNDERCLOCK_CPU: 'Underclock du CPU',
|
||||||
HEATINGOFF: 'Start boiler with forced heating off', // TODO translate
|
HEATINGOFF: 'Démarrer le chauffage avec le chauffage forcé éteint',
|
||||||
REMOTE_TIMEOUT: 'Remote timeout',
|
REMOTE_TIMEOUT: 'Remote timeout',
|
||||||
REMOTE_TIMEOUT_EN: 'Disable remote on missing room temperature', // TODO translate
|
REMOTE_TIMEOUT_EN: 'Disable remote on missing room temperature',
|
||||||
MIN_DURATION: 'Wait time',
|
MIN_DURATION: 'Wait time',
|
||||||
ENABLE_SHOWER_TIMER: 'Activer la minuterie de la douche',
|
ENABLE_SHOWER_TIMER: 'Activer la minuterie de la douche',
|
||||||
ENABLE_SHOWER_ALERT: 'Activer les alertes de durée de douche',
|
ENABLE_SHOWER_ALERT: 'Activer les alertes de durée de douche',
|
||||||
@@ -148,7 +148,7 @@ const fr: Translation = {
|
|||||||
CUSTOMIZATIONS_HELP_3: "désactiver l'action d'écriture",
|
CUSTOMIZATIONS_HELP_3: "désactiver l'action d'écriture",
|
||||||
CUSTOMIZATIONS_HELP_4: "exclure de MQTT et de l'API",
|
CUSTOMIZATIONS_HELP_4: "exclure de MQTT et de l'API",
|
||||||
CUSTOMIZATIONS_HELP_5: 'cacher des appareils',
|
CUSTOMIZATIONS_HELP_5: 'cacher des appareils',
|
||||||
CUSTOMIZATIONS_HELP_6: 'remove from memory', // TODO translate
|
CUSTOMIZATIONS_HELP_6: 'supprimer de la mémoire',
|
||||||
SELECT_DEVICE: 'Sélectionnez un appareil',
|
SELECT_DEVICE: 'Sélectionnez un appareil',
|
||||||
SET_ALL: 'tout régler',
|
SET_ALL: 'tout régler',
|
||||||
OPTIONS: 'Options',
|
OPTIONS: 'Options',
|
||||||
@@ -168,14 +168,14 @@ const fr: Translation = {
|
|||||||
SYSTEM: 'Système',
|
SYSTEM: 'Système',
|
||||||
LOG_OF: '{0} Log',
|
LOG_OF: '{0} Log',
|
||||||
STATUS_OF: 'Statut {0}',
|
STATUS_OF: 'Statut {0}',
|
||||||
DOWNLOAD_UPLOAD: 'Download/Upload', // TODO translate
|
DOWNLOAD_UPLOAD: 'Télécharger/Mettre à jour',
|
||||||
CLOSE: 'Fermer',
|
CLOSE: 'Fermer',
|
||||||
USE: 'Utiliser',
|
USE: 'Utiliser',
|
||||||
FACTORY_RESET: 'Réinitialisation',
|
FACTORY_RESET: 'Réinitialisation',
|
||||||
SYSTEM_FACTORY_TEXT: "L'appareil a été réinitialisé et va maintenant redémarrer",
|
SYSTEM_FACTORY_TEXT: "L'appareil a été réinitialisé et va maintenant redémarrer",
|
||||||
SYSTEM_FACTORY_TEXT_DIALOG: "Êtes-vous sûr de vouloir réinitialiser l'appareil à ses paramètres d'usine ?",
|
SYSTEM_FACTORY_TEXT_DIALOG: "Êtes-vous sûr de vouloir réinitialiser l'appareil à ses paramètres d'usine ?",
|
||||||
AVAILABLE_VERSION: 'Latest Available Versions', // TODO translate
|
AVAILABLE_VERSION: 'Versions disponibles',
|
||||||
STABLE: 'Stable', // TODO translate
|
STABLE: 'Stable',
|
||||||
DEVELOPMENT: 'Développement',
|
DEVELOPMENT: 'Développement',
|
||||||
UPTIME: 'Durée de fonctionnement du système',
|
UPTIME: 'Durée de fonctionnement du système',
|
||||||
FREE_MEMORY: 'Libre Memory',
|
FREE_MEMORY: 'Libre Memory',
|
||||||
@@ -185,9 +185,9 @@ const fr: Translation = {
|
|||||||
FILESYSTEM: 'File System (Utilisée / Libre)',
|
FILESYSTEM: 'File System (Utilisée / Libre)',
|
||||||
BUFFER_SIZE: 'Max taille du buffer',
|
BUFFER_SIZE: 'Max taille du buffer',
|
||||||
COMPACT: 'Compact',
|
COMPACT: 'Compact',
|
||||||
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
|
DOWNLOAD_SETTINGS_TEXT: 'Créer une sauvegarde de vos paramètres et configurations',
|
||||||
UPLOAD_TEXT: 'Upload a new firmware file (.bin) or a backup file (.json)', // TODO translate
|
UPLOAD_TEXT: 'Télécharger un nouveau fichier firmware (.bin) ou une sauvegarde (.json)',
|
||||||
UPLOAD_DROP_TEXT: 'Drop a firmware .bin file or click here', // TODO translate
|
UPLOAD_DROP_TEXT: 'Drop a firmware .bin file or click here',
|
||||||
ERROR: 'Erreur inattendue, veuillez réessayer',
|
ERROR: 'Erreur inattendue, veuillez réessayer',
|
||||||
TIME_SET: 'Time set',
|
TIME_SET: 'Time set',
|
||||||
MANAGE_USERS: 'Gérer les utilisateurs',
|
MANAGE_USERS: 'Gérer les utilisateurs',
|
||||||
@@ -217,7 +217,7 @@ const fr: Translation = {
|
|||||||
MQTT_PUBLISH_TEXT_2: 'Publier vers des topics de commande (ioBroker)',
|
MQTT_PUBLISH_TEXT_2: 'Publier vers des topics de commande (ioBroker)',
|
||||||
MQTT_PUBLISH_TEXT_3: 'Activer la découverte MQTT',
|
MQTT_PUBLISH_TEXT_3: 'Activer la découverte MQTT',
|
||||||
MQTT_PUBLISH_TEXT_4: 'Préfixe pour les topics découverte',
|
MQTT_PUBLISH_TEXT_4: 'Préfixe pour les topics découverte',
|
||||||
MQTT_PUBLISH_TEXT_5: 'Discovery type', // TODO translate
|
MQTT_PUBLISH_TEXT_5: 'Type de découverte',
|
||||||
MQTT_PUBLISH_INTERVALS: 'Intervalles de publication',
|
MQTT_PUBLISH_INTERVALS: 'Intervalles de publication',
|
||||||
MQTT_INT_BOILER: 'Chaudières et pompes à chaleur',
|
MQTT_INT_BOILER: 'Chaudières et pompes à chaleur',
|
||||||
MQTT_INT_THERMOSTATS: 'Thermostats',
|
MQTT_INT_THERMOSTATS: 'Thermostats',
|
||||||
@@ -226,10 +226,10 @@ const fr: Translation = {
|
|||||||
MQTT_INT_WATER: 'Modules eau',
|
MQTT_INT_WATER: 'Modules eau',
|
||||||
MQTT_QUEUE: 'Queue MQTT',
|
MQTT_QUEUE: 'Queue MQTT',
|
||||||
DEFAULT: 'Défaut',
|
DEFAULT: 'Défaut',
|
||||||
MQTT_ENTITY_FORMAT: 'Entity ID format', // TODO translate
|
MQTT_ENTITY_FORMAT: 'Format de l\'ID de l\'entité',
|
||||||
MQTT_ENTITY_FORMAT_0: 'Single instance, long name (v3.4)', // TODO translate
|
MQTT_ENTITY_FORMAT_0: 'Instance unique, nom long (v3.4)',
|
||||||
MQTT_ENTITY_FORMAT_1: 'Single instance, short name', // TODO translate
|
MQTT_ENTITY_FORMAT_1: 'Instance unique, nom court',
|
||||||
MQTT_ENTITY_FORMAT_2: 'Multiple instances, short name', // TODO translate
|
MQTT_ENTITY_FORMAT_2: 'Instances multiples, nom court',
|
||||||
MQTT_CLEAN_SESSION: 'Flag Clean Session',
|
MQTT_CLEAN_SESSION: 'Flag Clean Session',
|
||||||
MQTT_RETAIN_FLAG: 'Toujours activer le Retain Flag',
|
MQTT_RETAIN_FLAG: 'Toujours activer le Retain Flag',
|
||||||
INACTIVE: 'Inactif',
|
INACTIVE: 'Inactif',
|
||||||
@@ -260,7 +260,7 @@ const fr: Translation = {
|
|||||||
NETWORK_SCANNER: 'Scan réseau',
|
NETWORK_SCANNER: 'Scan réseau',
|
||||||
NETWORK_NO_WIFI: 'Pas de réseau WiFi trouvé',
|
NETWORK_NO_WIFI: 'Pas de réseau WiFi trouvé',
|
||||||
NETWORK_BLANK_SSID: 'laisser vide pour désactiver le WiFi',
|
NETWORK_BLANK_SSID: 'laisser vide pour désactiver le WiFi',
|
||||||
NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate
|
NETWORK_BLANK_BSSID: 'laisser vide pour utiliser uniquement le SSID',
|
||||||
TX_POWER: 'Puissance Tx',
|
TX_POWER: 'Puissance Tx',
|
||||||
HOSTNAME: "Nom d'hôte",
|
HOSTNAME: "Nom d'hôte",
|
||||||
NETWORK_DISABLE_SLEEP: 'Désactiver le mode veille du WiFi',
|
NETWORK_DISABLE_SLEEP: 'Désactiver le mode veille du WiFi',
|
||||||
@@ -280,79 +280,78 @@ const fr: Translation = {
|
|||||||
ENTITY: 'entité',
|
ENTITY: 'entité',
|
||||||
MIN: 'min',
|
MIN: 'min',
|
||||||
MAX: 'max',
|
MAX: 'max',
|
||||||
BLOCK_NAVIGATE_1: 'You have unsaved changes', // TODO translate
|
BLOCK_NAVIGATE_1: 'Vous avez des modifications non enregistrées',
|
||||||
BLOCK_NAVIGATE_2: 'If you navigate to a different page, your unsaved changes will be lost. Are you sure you want to leave this page?', // TODO translate
|
BLOCK_NAVIGATE_2: 'Si vous naviguez vers une autre page, vos modifications non enregistrées seront perdues. Êtes-vous sûr de vouloir quitter cette page ?',
|
||||||
STAY: 'Stay', // TODO translate
|
STAY: 'Rester',
|
||||||
LEAVE: 'Leave', // TODO translate
|
LEAVE: 'Quitter',
|
||||||
SCHEDULER: 'Scheduler', // TODO translate
|
SCHEDULER: 'Scheduler',
|
||||||
SCHEDULER_HELP_1: 'Automate commands by adding scheduled events below. Set a unique Name to enable/disable activation via API/MQTT', // TODO translate
|
SCHEDULER_HELP_1: 'Automatiser les commandes en ajoutant des événements programmés ci-dessous. Définissez un nom unique pour activer/désactiver l\'activation via API/MQTT',
|
||||||
SCHEDULER_HELP_2: 'Use 00:00 to trigger once on start-up', // TODO translate
|
SCHEDULER_HELP_2: 'Utiliser 00:00 pour déclencher une fois au démarrage',
|
||||||
SCHEDULE: 'Schedule', // TODO translate
|
SCHEDULE: 'Programme',
|
||||||
TIME: 'Time', // TODO translate
|
TIME: 'Temps',
|
||||||
TIMER: 'Timer', // TODO translate
|
TIMER: 'Minuteur',
|
||||||
ONCHANGE: 'Sur le changement', // TODO translate
|
ONCHANGE: 'Sur le changement',
|
||||||
CONDITION: 'Condition', // TODO translate
|
CONDITION: 'Condition',
|
||||||
IMMEDIATE: 'Immédiate', // TODO translate
|
IMMEDIATE: 'Immédiat',
|
||||||
SCHEDULE_UPDATED: 'Schedule updated', // TODO translate
|
SCHEDULE_UPDATED: 'Programme mis à jour',
|
||||||
SCHEDULE_TIMER_1: 'on startup', // TODO translate
|
SCHEDULE_TIMER_1: 'au démarrage',
|
||||||
SCHEDULE_TIMER_2: 'every minute', // TODO translate
|
SCHEDULE_TIMER_2: 'toutes les minutes',
|
||||||
SCHEDULE_TIMER_3: 'every hour', // TODO translate
|
SCHEDULE_TIMER_3: 'toutes les heures',
|
||||||
CUSTOM_ENTITIES: 'Custom Entities', // TODO translate
|
CUSTOM_ENTITIES: 'Entités personnalisées',
|
||||||
ENTITIES_HELP_1: 'Fetch custom entities from the EMS bus', // TODO translate
|
ENTITIES_HELP_1: 'Récupérer les entités personnalisées du bus EMS',
|
||||||
ENTITIES_UPDATED: 'Entities Updated', // TODO translate
|
ENTITIES_UPDATED: 'Entités mises à jour',
|
||||||
WRITEABLE: 'Writeable', // TODO translate
|
WRITEABLE: 'Écriture',
|
||||||
SHOWING: 'Showing', // TODO translate
|
SHOWING: 'Affichage',
|
||||||
SEARCH: 'Search', // TODO translate
|
SEARCH: 'Rechercher',
|
||||||
CERT: 'TLS root certificate (leave blank for insecure)', // TODO translate
|
CERT: 'Certificat racine TLS (laisser vide pour l\'insecurité)',
|
||||||
ENABLE_TLS: 'Activer TLS',
|
ENABLE_TLS: 'Activer TLS',
|
||||||
ON: 'On', // TODO translate
|
ON: 'On',
|
||||||
OFF: 'Off', // TODO translate
|
OFF: 'Off',
|
||||||
POLARITY: 'Polarity', // TODO translate
|
POLARITY: 'Polarity',
|
||||||
ACTIVEHIGH: 'Active High', // TODO translate
|
ACTIVEHIGH: 'Actif haut',
|
||||||
ACTIVELOW: 'Active Low', // TODO translate
|
ACTIVELOW: 'Actif bas',
|
||||||
UNCHANGED: 'Unchanged', // TODO translate
|
UNCHANGED: 'Inchangé',
|
||||||
ALWAYS: 'Always', // TODO translate
|
ALWAYS: 'Toujours',
|
||||||
ACTIVITY: 'Activity', // TODO translate
|
ACTIVITY: 'Activité',
|
||||||
CONFIGURE: 'Configure {0}', // TODO translate
|
CONFIGURE: 'Configurer {0}',
|
||||||
SYSTEM_MEMORY: 'System Memory', // TODO translate
|
SYSTEM_MEMORY: 'Mémoire système',
|
||||||
APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate
|
APPLICATION_SETTINGS_1: 'Modifier les paramètres de l\'application EMS-ESP',
|
||||||
SECURITY_1: 'Add or remove users', // TODO translate
|
SECURITY_1: 'Ajouter ou supprimer des utilisateurs',
|
||||||
DOWNLOAD_UPLOAD_1: 'Download and Upload Settings and Firmware', // TODO translate
|
DOWNLOAD_UPLOAD_1: 'Télécharger et mettre à jour les paramètres et le firmware',
|
||||||
MODULES: 'Module', // TODO translate
|
MODULES: 'Module',
|
||||||
MODULES_1: 'Activer ou désactiver les modules externes',
|
MODULES_1: 'Activer ou désactiver les modules externes',
|
||||||
MODULES_UPDATED: 'Modules updated', // TODO translate
|
MODULES_UPDATED: 'Modules mis à jour',
|
||||||
MODULES_DESCRIPTION: 'Click on the Module to activate or de-activate EMS-ESP library modules', // TODO translate
|
MODULES_DESCRIPTION: 'Cliquer sur le module pour activer ou désactiver les modules EMS-ESP',
|
||||||
MODULES_NONE: 'No external modules detected', // TODO translate
|
MODULES_NONE: 'Aucun module externe détecté',
|
||||||
RENAME: 'Rename', // TODO translate
|
RENAME: 'Renommer',
|
||||||
ENABLE_MODBUS: 'Activer Modbus',
|
ENABLE_MODBUS: 'Activer Modbus',
|
||||||
VIEW_LOG: 'View log to diagnose issues', // TODO translate
|
VIEW_LOG: 'Voir le journal pour diagnostiquer les problèmes',
|
||||||
UPLOAD_DRAG: 'drag and drop a file here or click to select one', // TODO translate
|
UPLOAD_DRAG: 'glisser-déposer un fichier ici ou cliquer pour en sélectionner un',
|
||||||
SERVICES: 'Services', // TODO translate
|
SERVICES: 'Services',
|
||||||
ALLVALUES: 'All Values', // TODO translate
|
ALLVALUES: 'Toutes les valeurs',
|
||||||
SPECIAL_FUNCTIONS: 'Special Functions',
|
SPECIAL_FUNCTIONS: 'Fonctions spéciales',
|
||||||
WAIT_FIRMWARE: 'Firmware is uploading and installing', // TODO translate
|
WAIT_FIRMWARE: 'Firmware en cours de téléchargement et d\'installation',
|
||||||
INSTALL_VERSION: 'This will install version {0}. Are you sure?', // TODO translate
|
INSTALL_VERSION: 'Cela va {0} la version {1}. Êtes-vous sûr ?',
|
||||||
UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate
|
UPDATE_AVAILABLE: 'mise à jour disponible',
|
||||||
LATEST_VERSION: 'You are using the latest firmware version', // TODO translate
|
LATEST_VERSION: 'Vous utilisez la dernière version {0} du firmware',
|
||||||
PLEASE_WAIT: 'Please wait', // TODO translate
|
PLEASE_WAIT: 'Veuillez patienter',
|
||||||
RESTARTING_PRE: 'Initializing', // TODO translate
|
RESTARTING_PRE: 'Initialisation',
|
||||||
RESTARTING_POST: 'Preparing', // TODO translate
|
RESTARTING_POST: 'Préparation',
|
||||||
AUTO_SCROLL: 'Auto Scroll', // TODO translate
|
AUTO_SCROLL: 'Défilement automatique',
|
||||||
DASHBOARD: 'Dashboard', // TODO translate
|
DASHBOARD: 'Tableau de bord',
|
||||||
DEVELOPER_MODE: 'Developer Mode', // TODO translate
|
DEVELOPER_MODE: 'Mode développeur',
|
||||||
BYTES: 'Bytes', // TODO translate
|
BYTES: 'Octets',
|
||||||
BITMASK: 'Bit Mask',// TODO translate
|
BITMASK: 'Masque de bits',
|
||||||
DUPLICATE: 'Duplicate', // TODO translate
|
DUPLICATE: 'Dupliquer',
|
||||||
UPGRADE: 'Upgrade', // TODO translate
|
DASHBOARD_1: 'Toutes les entités EMS actives et marquées comme favoris, plus toutes les entités personnalisées, les programmes et les données des capteurs externes sont affichées ci-dessous.',
|
||||||
DASHBOARD_1: 'All EMS entities that are active and marked as Favorite, plus all Custom Entities, Schedules and external Sensors data are displayed below.', // TODO translate
|
NO_DATA_1: 'Aucune entité EMS favorite trouvée. Utilisez le',
|
||||||
NO_DATA_1: 'No favorite EMS entities found yet. Use the', // TODO translate
|
NO_DATA_2: 'module pour les marquer.',
|
||||||
NO_DATA_2: 'module to mark them.', // TODO translate
|
NO_DATA_3: 'Pour voir toutes les entités disponibles, aller à',
|
||||||
NO_DATA_3: 'To see all available entities go to', // TODO translate
|
THIS_VERSION: 'Cette version',
|
||||||
THIS_VERSION: 'This Version', // TODO translate
|
PLATFORM: 'Plateforme',
|
||||||
PLATFORM: 'Platform', // TODO translate
|
RELEASE_TYPE: 'Type de version',
|
||||||
RELEASE_TYPE: 'Release Type', // TODO translate
|
INTERNET_CONNECTION_REQUIRED: 'Connexion Internet requise pour la vérification automatique des versions et la mise à niveau',
|
||||||
REINSTALL: 'Re-install', // TODO translate
|
SWITCH_RELEASE_TYPE: 'Passer à la version {0}'
|
||||||
INTERNET_CONNECTION_REQUIRED: 'Internet connection required for automatic version checking and upgrading',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default fr;
|
export default fr;
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ const it: Translation = {
|
|||||||
TX_ISSUES: 'Problema di Tx - prova una modalità differente',
|
TX_ISSUES: 'Problema di Tx - prova una modalità differente',
|
||||||
DISCONNECTED: 'Disconnesso',
|
DISCONNECTED: 'Disconnesso',
|
||||||
EMS_SCAN: 'Sei sicuro di voler iniziare una scansione completa del bus EMS ?',
|
EMS_SCAN: 'Sei sicuro di voler iniziare una scansione completa del bus EMS ?',
|
||||||
DATA_TRAFFIC: 'Data Traffic', // TODO translate
|
DATA_TRAFFIC: 'Traffico dati',
|
||||||
EMS_DEVICE: 'Dispositivo EMS ',
|
EMS_DEVICE: 'Dispositivo EMS ',
|
||||||
SUCCESS: 'SUCCESSO',
|
SUCCESS: 'SUCCESSO',
|
||||||
FAIL: 'FALLITO',
|
FAIL: 'FALLITO',
|
||||||
@@ -115,7 +115,7 @@ const it: Translation = {
|
|||||||
READONLY: 'Abilita modalità sola-lettura (blocca tutti i comandi di scrittura EMS Tx in uscita)',
|
READONLY: 'Abilita modalità sola-lettura (blocca tutti i comandi di scrittura EMS Tx in uscita)',
|
||||||
UNDERCLOCK_CPU: 'Abbassa velocità della CPU',
|
UNDERCLOCK_CPU: 'Abbassa velocità della CPU',
|
||||||
REMOTE_TIMEOUT: 'Remote timeout',
|
REMOTE_TIMEOUT: 'Remote timeout',
|
||||||
REMOTE_TIMEOUT_EN: 'Disable remote on missing room temperature', // TODO translate
|
REMOTE_TIMEOUT_EN: 'Disabilitare il telecomando in caso di temperatura ambiente mancante',
|
||||||
HEATINGOFF: 'Avviamento caldaia con riscaldamento forzato spento',
|
HEATINGOFF: 'Avviamento caldaia con riscaldamento forzato spento',
|
||||||
MIN_DURATION: 'Wait time',
|
MIN_DURATION: 'Wait time',
|
||||||
ENABLE_SHOWER_TIMER: 'Abilita timer doccia',
|
ENABLE_SHOWER_TIMER: 'Abilita timer doccia',
|
||||||
@@ -174,8 +174,8 @@ const it: Translation = {
|
|||||||
FACTORY_RESET: 'Impostazioni di fabbrica',
|
FACTORY_RESET: 'Impostazioni di fabbrica',
|
||||||
SYSTEM_FACTORY_TEXT: 'Il dispositivo è stato ripristinato alle impostazioni di fabbrica e ora verrà riavviato',
|
SYSTEM_FACTORY_TEXT: 'Il dispositivo è stato ripristinato alle impostazioni di fabbrica e ora verrà riavviato',
|
||||||
SYSTEM_FACTORY_TEXT_DIALOG: 'Sei sicuro di voler ripristinare il dispositivo alle impostazioni di fabbrica??',
|
SYSTEM_FACTORY_TEXT_DIALOG: 'Sei sicuro di voler ripristinare il dispositivo alle impostazioni di fabbrica??',
|
||||||
AVAILABLE_VERSION: 'Latest Available Versions', // TODO translate
|
AVAILABLE_VERSION: 'Versioni disponibili',
|
||||||
STABLE: 'Stable', // TODO translate
|
STABLE: 'Stabile',
|
||||||
DEVELOPMENT: 'Sviluppo',
|
DEVELOPMENT: 'Sviluppo',
|
||||||
UPTIME: 'Tempo di attività del sistema',
|
UPTIME: 'Tempo di attività del sistema',
|
||||||
FREE_MEMORY: 'Free Memory',
|
FREE_MEMORY: 'Free Memory',
|
||||||
@@ -184,10 +184,10 @@ const it: Translation = {
|
|||||||
APPSIZE: 'Applicazione (Partizione: Usata / Libera)',
|
APPSIZE: 'Applicazione (Partizione: Usata / Libera)',
|
||||||
FILESYSTEM: 'Memoria Sistema (Usata / Libera)',
|
FILESYSTEM: 'Memoria Sistema (Usata / Libera)',
|
||||||
BUFFER_SIZE: 'Max Buffer Size',
|
BUFFER_SIZE: 'Max Buffer Size',
|
||||||
COMPACT: 'Compact',
|
COMPACT: 'Compatto',
|
||||||
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
|
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings',
|
||||||
UPLOAD_TEXT: 'Upload a new firmware file (.bin) or a backup file (.json)', // TODO translate
|
UPLOAD_TEXT: 'Upload a new firmware file (.bin) or a backup file (.json)',
|
||||||
UPLOAD_DROP_TEXT: 'Drop a firmware .bin file or click here', // TODO translate
|
UPLOAD_DROP_TEXT: 'Drop a firmware .bin file or click here',
|
||||||
ERROR: 'Errore Inaspettato, prego tenta ancora',
|
ERROR: 'Errore Inaspettato, prego tenta ancora',
|
||||||
TIME_SET: 'Imposta Ora',
|
TIME_SET: 'Imposta Ora',
|
||||||
MANAGE_USERS: 'Gestione Utenti',
|
MANAGE_USERS: 'Gestione Utenti',
|
||||||
@@ -260,7 +260,7 @@ const it: Translation = {
|
|||||||
NETWORK_SCANNER: 'Scansione Rete',
|
NETWORK_SCANNER: 'Scansione Rete',
|
||||||
NETWORK_NO_WIFI: 'Nessuana rete WiFi trovata',
|
NETWORK_NO_WIFI: 'Nessuana rete WiFi trovata',
|
||||||
NETWORK_BLANK_SSID: 'lasciare vuoto per disattivare WiFi',
|
NETWORK_BLANK_SSID: 'lasciare vuoto per disattivare WiFi',
|
||||||
NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate
|
NETWORK_BLANK_BSSID: 'lasciare vuoto per usare solo SSID',
|
||||||
TX_POWER: 'Potenza Tx',
|
TX_POWER: 'Potenza Tx',
|
||||||
HOSTNAME: 'Nome ospite',
|
HOSTNAME: 'Nome ospite',
|
||||||
NETWORK_DISABLE_SLEEP: 'Disabilita la modalità sospensione Wi-Fi',
|
NETWORK_DISABLE_SLEEP: 'Disabilita la modalità sospensione Wi-Fi',
|
||||||
@@ -303,56 +303,55 @@ const it: Translation = {
|
|||||||
WRITEABLE: 'Scrivibile',
|
WRITEABLE: 'Scrivibile',
|
||||||
SHOWING: 'Visualizza',
|
SHOWING: 'Visualizza',
|
||||||
SEARCH: 'Ricerca',
|
SEARCH: 'Ricerca',
|
||||||
CERT: 'TLS root certificate (leave blank for insecure)', // TODO translate
|
CERT: 'Certificato radice TLS (lasciare vuoto per l\'insecure)',
|
||||||
ENABLE_TLS: 'Abilita TLS',
|
ENABLE_TLS: 'Abilita TLS',
|
||||||
ON: 'On', // TODO translate
|
ON: 'On',
|
||||||
OFF: 'Off', // TODO translate
|
OFF: 'Off',
|
||||||
POLARITY: 'Polarity', // TODO translate
|
POLARITY: 'Polarity',
|
||||||
ACTIVEHIGH: 'Active High', // TODO translate
|
ACTIVEHIGH: 'Active High',
|
||||||
ACTIVELOW: 'Active Low', // TODO translate
|
ACTIVELOW: 'Active Low',
|
||||||
UNCHANGED: 'Unchanged', // TODO translate
|
UNCHANGED: 'Unchanged',
|
||||||
ALWAYS: 'Always', // TODO translate
|
ALWAYS: 'Always',
|
||||||
ACTIVITY: 'Activity', // TODO translate
|
ACTIVITY: 'Activity',
|
||||||
CONFIGURE: 'Configure {0}', // TODO translate
|
CONFIGURE: 'Configure {0}',
|
||||||
SYSTEM_MEMORY: 'System Memory', // TODO translate
|
SYSTEM_MEMORY: 'System Memory',
|
||||||
APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate
|
APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings',
|
||||||
SECURITY_1: 'Add or remove users', // TODO translate
|
SECURITY_1: 'Add or remove users',
|
||||||
DOWNLOAD_UPLOAD_1: 'Download and Upload Settings and Firmware', // TODO translate
|
DOWNLOAD_UPLOAD_1: 'Download and Upload Settings and Firmware',
|
||||||
MODULES: 'Module', // TODO translate
|
MODULES: 'Module',
|
||||||
MODULES_1: 'Attiva o disattiva i moduli esterni', // TODO translate
|
MODULES_1: 'Attiva o disattiva i moduli esterni',
|
||||||
MODULES_UPDATED: 'Modules updated', // TODO translate
|
MODULES_UPDATED: 'Modules updated',
|
||||||
MODULES_DESCRIPTION: 'Click on the Module to activate or de-activate EMS-ESP library modules', // TODO translate
|
MODULES_DESCRIPTION: 'Click on the Module to activate or de-activate EMS-ESP library modules',
|
||||||
MODULES_NONE: 'No external modules detected', // TODO translate
|
MODULES_NONE: 'No external modules detected',
|
||||||
RENAME: 'Rename', // TODO translate
|
RENAME: 'Rename',
|
||||||
ENABLE_MODBUS: 'Abilita Modbus',
|
ENABLE_MODBUS: 'Abilita Modbus',
|
||||||
VIEW_LOG: 'View log to diagnose issues', // TODO translate
|
VIEW_LOG: 'Visualizza log per diagnosticare problemi',
|
||||||
UPLOAD_DRAG: 'drag and drop a file here or click to select one', // TODO translate
|
UPLOAD_DRAG: 'trascina e rilascia un file qui o clicca per selezionare uno',
|
||||||
SERVICES: 'Services', // TODO translate
|
SERVICES: 'Servizi',
|
||||||
ALLVALUES: 'All Values', // TODO translate
|
ALLVALUES: 'Tutti i valori',
|
||||||
SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate
|
SPECIAL_FUNCTIONS: 'Funzioni speciali',
|
||||||
WAIT_FIRMWARE: 'Firmware is uploading and installing', // TODO translate
|
WAIT_FIRMWARE: 'Firmware è in upload e installazione',
|
||||||
INSTALL_VERSION: 'This will install version {0}. Are you sure?', // TODO translate
|
INSTALL_VERSION: 'Questo installerà la versione {1} {0}. Sei sicuro?',
|
||||||
UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate
|
UPDATE_AVAILABLE: 'aggiornamento disponibile',
|
||||||
LATEST_VERSION: 'You are using the latest firmware version', // TODO translate
|
LATEST_VERSION: 'Stai usando la versione più recente del firmware {0}',
|
||||||
PLEASE_WAIT: 'Please wait', // TODO translate
|
PLEASE_WAIT: 'Attendere',
|
||||||
RESTARTING_PRE: 'Initializing', // TODO translate
|
RESTARTING_PRE: 'Inizializzazione',
|
||||||
RESTARTING_POST: 'Preparing', // TODO translate
|
RESTARTING_POST: 'Preparazione',
|
||||||
AUTO_SCROLL: 'Auto Scroll', // TODO translate
|
AUTO_SCROLL: 'Scorrimento automatico',
|
||||||
DASHBOARD: 'Dashboard', // TODO translate
|
DASHBOARD: 'Pannello di controllo',
|
||||||
DEVELOPER_MODE: 'Developer Mode', // TODO translate
|
DEVELOPER_MODE: 'Modalità sviluppatore',
|
||||||
BYTES: 'Bytes', // TODO translate
|
BYTES: 'Byte',
|
||||||
BITMASK: 'Bit Mask',// TODO translate
|
BITMASK: 'Bitmask',
|
||||||
DUPLICATE: 'Duplicate', // TODO translate
|
DUPLICATE: 'Duplicato',
|
||||||
UPGRADE: 'Upgrade', // TODO translate
|
DASHBOARD_1: 'Tutte le entità EMS che sono attive e marcate come preferite, più tutte le entità personalizzate, piani di programmazione e dati dei sensori esterni sono visualizzati di seguito.',
|
||||||
DASHBOARD_1: 'All EMS entities that are active and marked as Favorite, plus all Custom Entities, Schedules and external Sensors data are displayed below.', // TODO translate
|
NO_DATA_1: 'Nessuna entità EMS preferita trovata. Usa il',
|
||||||
NO_DATA_1: 'No favorite EMS entities found yet. Use the', // TODO translate
|
NO_DATA_2: 'modulo per marcarle.',
|
||||||
NO_DATA_2: 'module to mark them.', // TODO translate
|
NO_DATA_3: 'Per vedere tutte le entità disponibili vai a',
|
||||||
NO_DATA_3: 'To see all available entities go to', // TODO translate
|
THIS_VERSION: 'Questa versione',
|
||||||
THIS_VERSION: 'This Version', // TODO translate
|
PLATFORM: 'Piattaforma',
|
||||||
PLATFORM: 'Platform', // TODO translate
|
RELEASE_TYPE: 'Tipo di rilascio',
|
||||||
RELEASE_TYPE: 'Release Type', // TODO translate
|
INTERNET_CONNECTION_REQUIRED: 'Connessione internet richiesta per il controllo automatico delle versioni e l\'aggiornamento',
|
||||||
REINSTALL: 'Re-install', // TODO translate
|
SWITCH_RELEASE_TYPE: 'Cambia in {0} rilascio'
|
||||||
INTERNET_CONNECTION_REQUIRED: 'Internet connection required for automatic version checking and upgrading',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default it;
|
export default it;
|
||||||
|
|||||||
@@ -331,19 +331,18 @@ const nl: Translation = {
|
|||||||
ALLVALUES: 'All waarden',
|
ALLVALUES: 'All waarden',
|
||||||
SPECIAL_FUNCTIONS: 'Speciale functies',
|
SPECIAL_FUNCTIONS: 'Speciale functies',
|
||||||
WAIT_FIRMWARE: 'Firmware wordt geüpload en geïnstalleerd',
|
WAIT_FIRMWARE: 'Firmware wordt geüpload en geïnstalleerd',
|
||||||
INSTALL_VERSION: 'Hiermee wordt versie {0} geïnstalleerd. Weet je het zeker?',
|
INSTALL_VERSION: 'Hiermee wordt versie {1} {0}. Weet je het zeker?',
|
||||||
UPGRADE_AVAILABLE: 'Er is een firmware-upgrade beschikbaar!',
|
UPDATE_AVAILABLE: 'update beschikbaar',
|
||||||
LATEST_VERSION: 'U gebruikt de nieuwste firmwareversie',
|
LATEST_VERSION: 'U gebruikt de nieuwste {0} firmwareversie',
|
||||||
PLEASE_WAIT: 'Een ogenblik geduld',
|
PLEASE_WAIT: 'Een ogenblik geduld',
|
||||||
RESTARTING_PRE: 'Initialiseren',
|
RESTARTING_PRE: 'Initialiseren',
|
||||||
RESTARTING_POST: 'Voorbereiding',
|
RESTARTING_POST: 'Voorbereiding',
|
||||||
AUTO_SCROLL: 'Automatisch Scrollen',
|
AUTO_SCROLL: 'Automatisch Scrollen',
|
||||||
DASHBOARD: 'Dashboard',
|
DASHBOARD: 'Dashboard',
|
||||||
DEVELOPER_MODE: 'Ontwikkelaarsmodus',
|
DEVELOPER_MODE: 'Ontwikkelaarsmodus',
|
||||||
BYTES: 'Bytes', // TODO translate
|
BYTES: 'Bytes',
|
||||||
BITMASK: 'Bit Mask',// TODO translate
|
BITMASK: 'Bit Mask',
|
||||||
DUPLICATE: 'Duplicaat',
|
DUPLICATE: 'Duplicaat',
|
||||||
UPGRADE: 'Upgraden',
|
|
||||||
DASHBOARD_1: 'Alle EMS-entiteiten die actief zijn en als favoriet zijn gemarkeerd, plus alle aangepaste entiteiten en externe sensorgegevens worden hieronder weergegeven.',
|
DASHBOARD_1: 'Alle EMS-entiteiten die actief zijn en als favoriet zijn gemarkeerd, plus alle aangepaste entiteiten en externe sensorgegevens worden hieronder weergegeven.',
|
||||||
NO_DATA_1: 'Er zijn nog geen favoriete EMS-entiteiten gevonden. Gebruik de',
|
NO_DATA_1: 'Er zijn nog geen favoriete EMS-entiteiten gevonden. Gebruik de',
|
||||||
NO_DATA_2: 'module om ze te markeren.',
|
NO_DATA_2: 'module om ze te markeren.',
|
||||||
@@ -351,8 +350,8 @@ const nl: Translation = {
|
|||||||
THIS_VERSION: 'Deze Versie',
|
THIS_VERSION: 'Deze Versie',
|
||||||
PLATFORM: 'Platform',
|
PLATFORM: 'Platform',
|
||||||
RELEASE_TYPE: 'Release Typ',
|
RELEASE_TYPE: 'Release Typ',
|
||||||
REINSTALL: 'Opnieuw Installeren',
|
|
||||||
INTERNET_CONNECTION_REQUIRED: 'Internetverbinding vereist voor automatische versiecontrole en -upgrade',
|
INTERNET_CONNECTION_REQUIRED: 'Internetverbinding vereist voor automatische versiecontrole en -upgrade',
|
||||||
|
SWITCH_RELEASE_TYPE: 'Switch naar {0} release'
|
||||||
};
|
};
|
||||||
|
|
||||||
export default nl;
|
export default nl;
|
||||||
@@ -43,7 +43,7 @@ const no: Translation = {
|
|||||||
RESET: 'Nullstill',
|
RESET: 'Nullstill',
|
||||||
APPLY_CHANGES: 'Utfør endringer({0})',
|
APPLY_CHANGES: 'Utfør endringer({0})',
|
||||||
UPDATE: 'Oppdater',
|
UPDATE: 'Oppdater',
|
||||||
EXECUTE: 'Execute', // TODO translate
|
EXECUTE: 'Utfør',
|
||||||
REMOVE: 'Fjern',
|
REMOVE: 'Fjern',
|
||||||
PROBLEM_UPDATING: 'Problem med oppdatering',
|
PROBLEM_UPDATING: 'Problem med oppdatering',
|
||||||
PROBLEM_LOADING: 'Problem med opplasting',
|
PROBLEM_LOADING: 'Problem med opplasting',
|
||||||
@@ -72,7 +72,7 @@ const no: Translation = {
|
|||||||
TX_ISSUES: 'Tx problemer - prøv en annen Tx Modus',
|
TX_ISSUES: 'Tx problemer - prøv en annen Tx Modus',
|
||||||
DISCONNECTED: 'Frakoblet',
|
DISCONNECTED: 'Frakoblet',
|
||||||
EMS_SCAN: 'Er du sikker på du vil starte full søking av EMS bussen?',
|
EMS_SCAN: 'Er du sikker på du vil starte full søking av EMS bussen?',
|
||||||
DATA_TRAFFIC: 'Data Traffic', // TODO translate
|
DATA_TRAFFIC: 'Data trafikk',
|
||||||
EMS_DEVICE: 'EMS Enhet',
|
EMS_DEVICE: 'EMS Enhet',
|
||||||
SUCCESS: 'VELLYKKET',
|
SUCCESS: 'VELLYKKET',
|
||||||
FAIL: 'MISLYKKET',
|
FAIL: 'MISLYKKET',
|
||||||
@@ -115,9 +115,9 @@ const no: Translation = {
|
|||||||
READONLY: 'Aktiver read-only modus (blokker all EMS Tx Skriving)',
|
READONLY: 'Aktiver read-only modus (blokker all EMS Tx Skriving)',
|
||||||
UNDERCLOCK_CPU: 'Underklokking av prosessorhastighet',
|
UNDERCLOCK_CPU: 'Underklokking av prosessorhastighet',
|
||||||
REMOTE_TIMEOUT: 'Remote timeout',
|
REMOTE_TIMEOUT: 'Remote timeout',
|
||||||
REMOTE_TIMEOUT_EN: 'Disable remote control on missing room temperature', // TODO translate
|
REMOTE_TIMEOUT_EN: 'Deaktiver fjernstyring på manglende romtemperatur',
|
||||||
HEATINGOFF: 'Start boiler with forced heating off', // TODO translate
|
HEATINGOFF: 'Start kjele med tvingt oppvarming av',
|
||||||
MIN_DURATION: 'Wait time',
|
MIN_DURATION: 'Ventetid',
|
||||||
ENABLE_SHOWER_TIMER: 'Aktiver Dusjtimer',
|
ENABLE_SHOWER_TIMER: 'Aktiver Dusjtimer',
|
||||||
ENABLE_SHOWER_ALERT: 'Aktiver Dusj-varsling',
|
ENABLE_SHOWER_ALERT: 'Aktiver Dusj-varsling',
|
||||||
TRIGGER_TIME: 'Aktiveringstid',
|
TRIGGER_TIME: 'Aktiveringstid',
|
||||||
@@ -174,9 +174,9 @@ const no: Translation = {
|
|||||||
FACTORY_RESET: 'Sett tilbake til fabrikkinstilling',
|
FACTORY_RESET: 'Sett tilbake til fabrikkinstilling',
|
||||||
SYSTEM_FACTORY_TEXT: 'Enhet har blitt satt tilbake til fabrikkinstilling og vil restarte',
|
SYSTEM_FACTORY_TEXT: 'Enhet har blitt satt tilbake til fabrikkinstilling og vil restarte',
|
||||||
SYSTEM_FACTORY_TEXT_DIALOG: 'Er du sikker på at du vil resette enheten til fabrikkinstillinger?',
|
SYSTEM_FACTORY_TEXT_DIALOG: 'Er du sikker på at du vil resette enheten til fabrikkinstillinger?',
|
||||||
AVAILABLE_VERSION: 'Latest Available Versions', // TODO translate
|
AVAILABLE_VERSION: 'Tilgjengelige versjoner',
|
||||||
STABLE: 'Stable', // TODO translate
|
STABLE: 'Stabil',
|
||||||
DEVELOPMENT: 'Development',
|
DEVELOPMENT: 'Utvikling',
|
||||||
UPTIME: 'System Oppetid',
|
UPTIME: 'System Oppetid',
|
||||||
FREE_MEMORY: 'Ledig Memory',
|
FREE_MEMORY: 'Ledig Memory',
|
||||||
PSRAM: 'PSRAM (Størrelse / Ledig)',
|
PSRAM: 'PSRAM (Størrelse / Ledig)',
|
||||||
@@ -185,9 +185,9 @@ const no: Translation = {
|
|||||||
FILESYSTEM: 'File System (Brukt / Ledig)',
|
FILESYSTEM: 'File System (Brukt / Ledig)',
|
||||||
BUFFER_SIZE: 'Max Buffer Størrelse',
|
BUFFER_SIZE: 'Max Buffer Størrelse',
|
||||||
COMPACT: 'Komprimere',
|
COMPACT: 'Komprimere',
|
||||||
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
|
DOWNLOAD_SETTINGS_TEXT: 'Lag en sikkerhetskopi av dine konfigurasjon og innstillinger',
|
||||||
UPLOAD_TEXT: 'Upload a new firmware file (.bin) or a backup file (.json)', // TODO translate
|
UPLOAD_TEXT: 'Last opp en ny firmware fil (.bin) eller en sikkerhetskopi fil (.json)',
|
||||||
UPLOAD_DROP_TEXT: 'Drop a firmware .bin file or click here', // TODO translate
|
UPLOAD_DROP_TEXT: 'Dropp en firmware fil (.bin) eller klikk her',
|
||||||
ERROR: 'Ukjent feil, prøv igjen',
|
ERROR: 'Ukjent feil, prøv igjen',
|
||||||
TIME_SET: 'Still in tid',
|
TIME_SET: 'Still in tid',
|
||||||
MANAGE_USERS: 'Administrer Brukere',
|
MANAGE_USERS: 'Administrer Brukere',
|
||||||
@@ -223,7 +223,7 @@ const no: Translation = {
|
|||||||
MQTT_INT_THERMOSTATS: 'Termostat',
|
MQTT_INT_THERMOSTATS: 'Termostat',
|
||||||
MQTT_INT_SOLAR: 'Solpaneler',
|
MQTT_INT_SOLAR: 'Solpaneler',
|
||||||
MQTT_INT_MIXER: 'Blandeventil',
|
MQTT_INT_MIXER: 'Blandeventil',
|
||||||
MQTT_INT_WATER: 'Water Modules', // TODO translate
|
MQTT_INT_WATER: 'Vannmoduler',
|
||||||
MQTT_QUEUE: 'MQTT Queue',
|
MQTT_QUEUE: 'MQTT Queue',
|
||||||
DEFAULT: 'Standard',
|
DEFAULT: 'Standard',
|
||||||
MQTT_ENTITY_FORMAT: 'Enhets ID format',
|
MQTT_ENTITY_FORMAT: 'Enhets ID format',
|
||||||
@@ -260,7 +260,7 @@ const no: Translation = {
|
|||||||
NETWORK_SCANNER: 'Nettverk Scanner',
|
NETWORK_SCANNER: 'Nettverk Scanner',
|
||||||
NETWORK_NO_WIFI: 'Ingen trådløse nett funnet',
|
NETWORK_NO_WIFI: 'Ingen trådløse nett funnet',
|
||||||
NETWORK_BLANK_SSID: 'la feltet være blankt for å deaktivisere trådløst nettverk',
|
NETWORK_BLANK_SSID: 'la feltet være blankt for å deaktivisere trådløst nettverk',
|
||||||
NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate
|
NETWORK_BLANK_BSSID: 'la feltet være blankt for å bruke kun SSID',
|
||||||
TX_POWER: 'Tx Effekt',
|
TX_POWER: 'Tx Effekt',
|
||||||
HOSTNAME: 'Hostname',
|
HOSTNAME: 'Hostname',
|
||||||
NETWORK_DISABLE_SLEEP: 'Hindre at trådløst nettverk går i Sleep Mode',
|
NETWORK_DISABLE_SLEEP: 'Hindre at trådløst nettverk går i Sleep Mode',
|
||||||
@@ -297,62 +297,61 @@ const no: Translation = {
|
|||||||
SCHEDULE_TIMER_1: 'ved oppstart',
|
SCHEDULE_TIMER_1: 'ved oppstart',
|
||||||
SCHEDULE_TIMER_2: 'hvert minutt',
|
SCHEDULE_TIMER_2: 'hvert minutt',
|
||||||
SCHEDULE_TIMER_3: 'hver time',
|
SCHEDULE_TIMER_3: 'hver time',
|
||||||
CUSTOM_ENTITIES: 'Custom Entities', // TODO translate
|
CUSTOM_ENTITIES: 'Personlige entiteter',
|
||||||
ENTITIES_HELP_1: 'Fetch custom entities from the EMS bus', // TODO translate
|
ENTITIES_HELP_1: 'Hent personlige entiteter fra EMS bussen',
|
||||||
ENTITIES_UPDATED: 'Entities Updated', // TODO translate
|
ENTITIES_UPDATED: 'Entiteter oppdatert',
|
||||||
WRITEABLE: 'Writeable', // TODO translate
|
WRITEABLE: 'Skrivbar',
|
||||||
SHOWING: 'Showing', // TODO translate
|
SHOWING: 'Viser',
|
||||||
SEARCH: 'Search', // TODO translate
|
SEARCH: 'Søk',
|
||||||
CERT: 'TLS root certificate (leave blank for insecure)', // TODO translate
|
CERT: 'TLS rot sertifikat (la feltet stå blankt for usikkert)',
|
||||||
ENABLE_TLS: 'Aktiviser TLS',
|
ENABLE_TLS: 'Aktiviser TLS',
|
||||||
ON: 'On', // TODO translate
|
ON: 'På',
|
||||||
OFF: 'Off', // TODO translate
|
OFF: 'Av',
|
||||||
POLARITY: 'Polarity', // TODO translate
|
POLARITY: 'Polarity',
|
||||||
ACTIVEHIGH: 'Active High', // TODO translate
|
ACTIVEHIGH: 'Active High',
|
||||||
ACTIVELOW: 'Active Low', // TODO translate
|
ACTIVELOW: 'Active Low',
|
||||||
UNCHANGED: 'Unchanged', // TODO translate
|
UNCHANGED: 'Unchanged',
|
||||||
ALWAYS: 'Always', // TODO translate
|
ALWAYS: 'Always',
|
||||||
ACTIVITY: 'Activity', // TODO translate
|
ACTIVITY: 'Aktivitet',
|
||||||
CONFIGURE: 'Configure {0}', // TODO translate
|
CONFIGURE: 'Konfigurer {0}',
|
||||||
SYSTEM_MEMORY: 'System Memory', // TODO translate
|
SYSTEM_MEMORY: 'System Memory',
|
||||||
APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate
|
APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings',
|
||||||
SECURITY_1: 'Add or remove users', // TODO translate
|
SECURITY_1: 'Add or remove users',
|
||||||
DOWNLOAD_UPLOAD_1: 'Download and Upload Settings and Firmware', // TODO translate
|
DOWNLOAD_UPLOAD_1: 'Download and Upload Settings and Firmware',
|
||||||
MODULES: 'Module', // TODO translate
|
MODULES: 'Modul',
|
||||||
MODULES_1: 'Aktiver eller deaktiver eksterne moduler',
|
MODULES_1: 'Aktiver eller deaktiver eksterne moduler',
|
||||||
MODULES_UPDATED: 'Modules updated', // TODO translate
|
MODULES_UPDATED: 'Moduler oppdatert',
|
||||||
MODULES_DESCRIPTION: 'Click on the Module to activate or de-activate EMS-ESP library modules', // TODO translate
|
MODULES_DESCRIPTION: 'Klikk på modulen for å aktivere eller deaktivere EMS-ESP biblioteksmoduler',
|
||||||
MODULES_NONE: 'No external modules detected', // TODO translate
|
MODULES_NONE: 'Ingen eksterne moduler funnet',
|
||||||
RENAME: 'Rename', // TODO translate
|
RENAME: 'Gi nytt navn',
|
||||||
ENABLE_MODBUS: 'Aktiver Modbus',
|
ENABLE_MODBUS: 'Aktiver Modbus',
|
||||||
VIEW_LOG: 'View log to diagnose issues', // TODO translate
|
VIEW_LOG: 'Se logg for å diagnostisere problemer',
|
||||||
UPLOAD_DRAG: 'drag and drop a file here or click to select one', // TODO translate
|
UPLOAD_DRAG: 'dra og slippe en fil her eller klikk for å velge en',
|
||||||
SERVICES: 'Services', // TODO translate
|
SERVICES: 'Tjenester',
|
||||||
ALLVALUES: 'All Values', // TODO translate
|
ALLVALUES: 'Alle verdier',
|
||||||
SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate
|
SPECIAL_FUNCTIONS: 'Spesielle funksjoner',
|
||||||
WAIT_FIRMWARE: 'Firmware is uploading and installing', // TODO translate
|
WAIT_FIRMWARE: 'Firmware er i opplasting og installasjon',
|
||||||
INSTALL_VERSION: 'This will install version {0}. Are you sure?', // TODO translate
|
INSTALL_VERSION: 'Dette vil {0} versjon {1}. Er du sikker?',
|
||||||
UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate
|
UPDATE_AVAILABLE: 'oppdatering tilgjengelig',
|
||||||
LATEST_VERSION: 'You are using the latest firmware version', // TODO translate
|
LATEST_VERSION: 'Du bruker den nyeste {0} firmware versjonen',
|
||||||
PLEASE_WAIT: 'Please wait', // TODO translate
|
PLEASE_WAIT: 'Vennligst vent',
|
||||||
RESTARTING_PRE: 'Initializing', // TODO translate
|
RESTARTING_PRE: 'Initialiserer',
|
||||||
RESTARTING_POST: 'Preparing', // TODO translate
|
RESTARTING_POST: 'Forbereder',
|
||||||
AUTO_SCROLL: 'Auto Scroll', // TODO translate
|
AUTO_SCROLL: 'Automatisk rulling',
|
||||||
DASHBOARD: 'Dashboard', // TODO translate
|
DASHBOARD: 'Dashboard',
|
||||||
DEVELOPER_MODE: 'Developer Mode', // TODO translate
|
DEVELOPER_MODE: 'Utvikler modus',
|
||||||
BYTES: 'Bytes', // TODO translate
|
BYTES: 'Bytes',
|
||||||
BITMASK: 'Bit Mask',// TODO translate
|
BITMASK: 'Bitmask',
|
||||||
DUPLICATE: 'Duplicate', // TODO translate
|
DUPLICATE: 'Duplikat',
|
||||||
UPGRADE: 'Upgrade', // TODO translate
|
DASHBOARD_1: 'Alle EMS enheter som er aktive og merket som favoritt, pluss alle personlige enheter, planlegg og eksterne sensor data er vist nedenfor.',
|
||||||
DASHBOARD_1: 'All EMS entities that are active and marked as Favorite, plus all Custom Entities, Schedules and external Sensors data are displayed below.', // TODO translate
|
NO_DATA_1: 'Ingen favoritte EMS enheter funnet enda. Bruk',
|
||||||
NO_DATA_1: 'No favorite EMS entities found yet. Use the', // TODO translate
|
NO_DATA_2: 'modul for å markere dem.',
|
||||||
NO_DATA_2: 'module to mark them.', // TODO translate
|
NO_DATA_3: 'For å se alle tilgjengelige enheter, gå til',
|
||||||
NO_DATA_3: 'To see all available entities go to', // TODO translate
|
THIS_VERSION: 'Denne versjonen',
|
||||||
THIS_VERSION: 'This Version', // TODO translate
|
PLATFORM: 'Plattform',
|
||||||
PLATFORM: 'Platform', // TODO translate
|
RELEASE_TYPE: 'Utgivelses type',
|
||||||
RELEASE_TYPE: 'Release Type', // TODO translate
|
INTERNET_CONNECTION_REQUIRED: 'Internettilkobling kreves for automatisk versjonskontroll og oppgradering',
|
||||||
REINSTALL: 'Re-install', // TODO translate
|
SWITCH_RELEASE_TYPE: 'Bytt til {0} utgivelse'
|
||||||
INTERNET_CONNECTION_REQUIRED: 'Internet connection required for automatic version checking and upgrading',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default no;
|
export default no;
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ const pl: BaseTranslation = {
|
|||||||
TX_ISSUES: 'problem z zapisem na magistralę EMS, spróbuj wybrać inny "Tryb transmisji (Tx)"',
|
TX_ISSUES: 'problem z zapisem na magistralę EMS, spróbuj wybrać inny "Tryb transmisji (Tx)"',
|
||||||
DISCONNECTED: 'brak połączenia',
|
DISCONNECTED: 'brak połączenia',
|
||||||
EMS_SCAN: 'Czy na pewno wykonać pełne skanowanie magistrali EMS?',
|
EMS_SCAN: 'Czy na pewno wykonać pełne skanowanie magistrali EMS?',
|
||||||
DATA_TRAFFIC: 'Data Traffic', // TODO translate
|
DATA_TRAFFIC: 'Ruch Danych',
|
||||||
EMS_DEVICE: 'Urządzenie EMS',
|
EMS_DEVICE: 'Urządzenie EMS',
|
||||||
SUCCESS: 'Udane',
|
SUCCESS: 'Udane',
|
||||||
FAIL: 'Nieudane',
|
FAIL: 'Nieudane',
|
||||||
@@ -115,7 +115,7 @@ const pl: BaseTranslation = {
|
|||||||
READONLY: 'Tryb pracy "tylko do odczytu" (blokuje wszystkie komendy zapisu na magistralę EMS)',
|
READONLY: 'Tryb pracy "tylko do odczytu" (blokuje wszystkie komendy zapisu na magistralę EMS)',
|
||||||
UNDERCLOCK_CPU: 'Obniż taktowanie CPU',
|
UNDERCLOCK_CPU: 'Obniż taktowanie CPU',
|
||||||
REMOTE_TIMEOUT: 'Remote timeout',
|
REMOTE_TIMEOUT: 'Remote timeout',
|
||||||
REMOTE_TIMEOUT_EN: 'Disable remote control on missing room temperature', // TODO translate
|
REMOTE_TIMEOUT_EN: 'Wyłącz kontrolę zdalną przy braku temperatury pomieszczenia',
|
||||||
HEATINGOFF: 'Uruchom kocioł z wymuszonym wyłączonym grzaniem',
|
HEATINGOFF: 'Uruchom kocioł z wymuszonym wyłączonym grzaniem',
|
||||||
MIN_DURATION: 'Wait time',
|
MIN_DURATION: 'Wait time',
|
||||||
ENABLE_SHOWER_TIMER: 'Aktywuj minutnik prysznica',
|
ENABLE_SHOWER_TIMER: 'Aktywuj minutnik prysznica',
|
||||||
@@ -174,9 +174,9 @@ const pl: BaseTranslation = {
|
|||||||
FACTORY_RESET: 'Ustawienia fabryczne',
|
FACTORY_RESET: 'Ustawienia fabryczne',
|
||||||
SYSTEM_FACTORY_TEXT: 'Interfejs EMS-ESP został przywrócony do ustawień fabrycznych i zostanie teraz ponownie uruchomiony.',
|
SYSTEM_FACTORY_TEXT: 'Interfejs EMS-ESP został przywrócony do ustawień fabrycznych i zostanie teraz ponownie uruchomiony.',
|
||||||
SYSTEM_FACTORY_TEXT_DIALOG: 'Na pewno chcesz przywrócić ustawienia fabryczne interfejsu EMS-ESP?',
|
SYSTEM_FACTORY_TEXT_DIALOG: 'Na pewno chcesz przywrócić ustawienia fabryczne interfejsu EMS-ESP?',
|
||||||
AVAILABLE_VERSION: 'Latest Available Versions', // TODO translate
|
AVAILABLE_VERSION: 'Najnowsze dostępne wersje',
|
||||||
STABLE: 'Stable', // TODO translate
|
STABLE: 'Stabilna',
|
||||||
DEVELOPMENT: 'Testowe',
|
DEVELOPMENT: 'Testowa',
|
||||||
UPTIME: 'Czas działania systemu',
|
UPTIME: 'Czas działania systemu',
|
||||||
FREE_MEMORY: 'Wolne Memory',
|
FREE_MEMORY: 'Wolne Memory',
|
||||||
PSRAM: 'PSRAM (rozmiar / wolne)',
|
PSRAM: 'PSRAM (rozmiar / wolne)',
|
||||||
@@ -185,9 +185,9 @@ const pl: BaseTranslation = {
|
|||||||
FILESYSTEM: 'System plików (wykorzystane / wolne)',
|
FILESYSTEM: 'System plików (wykorzystane / wolne)',
|
||||||
BUFFER_SIZE: 'Maksymalna pojemność bufora (ilość wpisów)',
|
BUFFER_SIZE: 'Maksymalna pojemność bufora (ilość wpisów)',
|
||||||
COMPACT: 'Kompaktowy',
|
COMPACT: 'Kompaktowy',
|
||||||
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
|
DOWNLOAD_SETTINGS_TEXT: 'Utwórz kopię swoich ustawień i konfiguracji',
|
||||||
UPLOAD_TEXT: 'Upload a new firmware file (.bin) or a backup file (.json)', // TODO translate
|
UPLOAD_TEXT: 'Wgraj nowy plik firmware (.bin) lub kopię ustawień (.json)',
|
||||||
UPLOAD_DROP_TEXT: 'Drop a firmware .bin file or click here', // TODO translate
|
UPLOAD_DROP_TEXT: 'Upuść plik firmware .bin lub kliknij tutaj',
|
||||||
ERROR: 'Nieoczekiwany błąd, spróbuj ponownie!',
|
ERROR: 'Nieoczekiwany błąd, spróbuj ponownie!',
|
||||||
TIME_SET: 'Zegar został ustawiony.',
|
TIME_SET: 'Zegar został ustawiony.',
|
||||||
MANAGE_USERS: 'Zarządzanie użytkownikami',
|
MANAGE_USERS: 'Zarządzanie użytkownikami',
|
||||||
@@ -318,41 +318,40 @@ const pl: BaseTranslation = {
|
|||||||
APPLICATION_SETTINGS_1: 'Modyfikacja ustawień aplikacji EMS-ESP',
|
APPLICATION_SETTINGS_1: 'Modyfikacja ustawień aplikacji EMS-ESP',
|
||||||
SECURITY_1: 'Dodawanie i usuwanie użytkowników',
|
SECURITY_1: 'Dodawanie i usuwanie użytkowników',
|
||||||
DOWNLOAD_UPLOAD_1: 'Pobieranie/wysyłanie ustawień i firmware',
|
DOWNLOAD_UPLOAD_1: 'Pobieranie/wysyłanie ustawień i firmware',
|
||||||
MODULES: 'Module', // TODO translate
|
MODULES: 'Moduł',
|
||||||
MODULES_1: 'Aktywuj lub dezaktywuj moduły zewnętrzne',
|
MODULES_1: 'Aktywuj lub dezaktywuj moduły zewnętrzne',
|
||||||
MODULES_UPDATED: 'Modules updated', // TODO translate
|
MODULES_UPDATED: 'Zaktualizowano moduły',
|
||||||
MODULES_DESCRIPTION: 'Click on the Module to activate or de-activate EMS-ESP library modules', // TODO translate
|
MODULES_DESCRIPTION: 'Kliknij na moduł aby aktywować lub dezaktywować bibliotekę modułów EMS-ESP',
|
||||||
MODULES_NONE: 'No external modules detected', // TODO translate
|
MODULES_NONE: 'Brak wykrytych modułów zewnętrznych',
|
||||||
RENAME: 'Rename', // TODO translate
|
RENAME: 'Zmień nazwę',
|
||||||
ENABLE_MODBUS: 'Aktywuj Modbus',
|
ENABLE_MODBUS: 'Aktywuj Modbus',
|
||||||
VIEW_LOG: 'View log to diagnose issues', // TODO translate
|
VIEW_LOG: 'Zdiagnozuj problemy',
|
||||||
UPLOAD_DRAG: 'drag and drop a file here or click to select one', // TODO translate
|
UPLOAD_DRAG: 'przeciągnij i upuść plik lub kliknij tutaj',
|
||||||
SERVICES: 'Services', // TODO translate
|
SERVICES: 'Usługi',
|
||||||
ALLVALUES: 'All Values', // TODO translate
|
ALLVALUES: 'Wszystkie wartości',
|
||||||
SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate
|
SPECIAL_FUNCTIONS: 'Specjalne funkcje',
|
||||||
WAIT_FIRMWARE: 'Firmware is uploading and installing', // TODO translate
|
WAIT_FIRMWARE: 'Firma jest wysyłana i instaluje się',
|
||||||
INSTALL_VERSION: 'This will install version {0}. Are you sure?', // TODO translate
|
INSTALL_VERSION: 'To zainstaluje wersję {1} {0}. Jesteś pewny?',
|
||||||
UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate
|
UPDATE_AVAILABLE: 'aktualizacja dostępna',
|
||||||
LATEST_VERSION: 'You are using the latest firmware version', // TODO translate
|
LATEST_VERSION: 'Jesteś używając najnowszej wersji firmware {0}',
|
||||||
PLEASE_WAIT: 'Please wait', // TODO translate
|
PLEASE_WAIT: 'Proszę czekać',
|
||||||
RESTARTING_PRE: 'Initializing', // TODO translate
|
RESTARTING_PRE: 'Inicjalizacja',
|
||||||
RESTARTING_POST: 'Preparing', // TODO translate
|
RESTARTING_POST: 'Przygotowanie',
|
||||||
AUTO_SCROLL: 'Auto Scroll', // TODO translate
|
AUTO_SCROLL: 'Auto Scroll',
|
||||||
DASHBOARD: 'Dashboard', // TODO translate
|
DASHBOARD: 'Pulpit',
|
||||||
DEVELOPER_MODE: 'Developer Mode', // TODO translate
|
DEVELOPER_MODE: 'Tryb programisty',
|
||||||
BYTES: 'Bytes', // TODO translate
|
BYTES: 'Bajty',
|
||||||
BITMASK: 'Bit Mask',// TODO translate
|
BITMASK: 'Bit Mask',
|
||||||
DUPLICATE: 'Duplicate', // TODO translate
|
DUPLICATE: 'Duplicate',
|
||||||
UPGRADE: 'Upgrade', // TODO translate
|
DASHBOARD_1: 'All EMS entities that are active and marked as Favorite, plus all Custom Entities, Schedules and external Sensors data are displayed below.',
|
||||||
DASHBOARD_1: 'All EMS entities that are active and marked as Favorite, plus all Custom Entities, Schedules and external Sensors data are displayed below.', // TODO translate
|
NO_DATA_1: 'Brak ulubionych encji EMS. Użyj',
|
||||||
NO_DATA_1: 'No favorite EMS entities found yet. Use the', // TODO translate
|
NO_DATA_2: 'moduł do ich oznaczenia.',
|
||||||
NO_DATA_2: 'module to mark them.', // TODO translate
|
NO_DATA_3: 'Aby zobaczyć wszystkie dostępne encje przejdź do',
|
||||||
NO_DATA_3: 'To see all available entities go to', // TODO translate
|
THIS_VERSION: 'Ta wersja',
|
||||||
THIS_VERSION: 'This Version', // TODO translate
|
PLATFORM: 'Platforma',
|
||||||
PLATFORM: 'Platform', // TODO translate
|
RELEASE_TYPE: 'Typ wydania',
|
||||||
RELEASE_TYPE: 'Release Type', // TODO translate
|
INTERNET_CONNECTION_REQUIRED: 'Połączenie internetowe jest wymagane do automatycznej kontroli wersji i aktualizacji',
|
||||||
REINSTALL: 'Re-install', // TODO translate
|
SWITCH_RELEASE_TYPE: 'Zmień na {0} wydanie'
|
||||||
INTERNET_CONNECTION_REQUIRED: 'Internet connection required for automatic version checking and upgrading', // TODO translate
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default pl;
|
export default pl;
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ const sk: Translation = {
|
|||||||
NAME: 'Názov',
|
NAME: 'Názov',
|
||||||
CUSTOMIZATIONS_RESET: 'Naozaj chcete odstrániť všetky prispôsobenia vrátane vlastných nastavení snímačov teploty a analógových snímačov?',
|
CUSTOMIZATIONS_RESET: 'Naozaj chcete odstrániť všetky prispôsobenia vrátane vlastných nastavení snímačov teploty a analógových snímačov?',
|
||||||
SUPPORT_INFORMATION: 'Informácie pre podporu',
|
SUPPORT_INFORMATION: 'Informácie pre podporu',
|
||||||
HELP_INFORMATION_1: 'Navštívte online wiki, kde nájdete pokyny na konfiguráciu EMS-ESP',
|
HELP_INFORMATION_1: 'Navštívte online wiki, kde nájdete pokyny na konfiguráciu EMS-ESP',
|
||||||
HELP_INFORMATION_2: 'Pre živý komunitný chat sa pripojte na náš Discord server',
|
HELP_INFORMATION_2: 'Pre živý komunitný chat sa pripojte na náš Discord server',
|
||||||
HELP_INFORMATION_3: 'Ak chcete požiadať o funkciu alebo nahlásiť chybu',
|
HELP_INFORMATION_3: 'Ak chcete požiadať o funkciu alebo nahlásiť chybu',
|
||||||
HELP_INFORMATION_4: 'nezabudnite si stiahnuť a pripojiť informácie o vašom systéme, aby ste mohli rýchlejšie reagovať pri nahlasovaní problému',
|
HELP_INFORMATION_4: 'nezabudnite si stiahnuť a pripojiť informácie o vašom systéme, aby ste mohli rýchlejšie reagovať pri nahlasovaní problému',
|
||||||
@@ -187,7 +187,7 @@ const sk: Translation = {
|
|||||||
COMPACT: 'Kompaktné',
|
COMPACT: 'Kompaktné',
|
||||||
DOWNLOAD_SETTINGS_TEXT: 'Vytvorte zálohu svojej konfigurácie a nastavení',
|
DOWNLOAD_SETTINGS_TEXT: 'Vytvorte zálohu svojej konfigurácie a nastavení',
|
||||||
UPLOAD_TEXT: 'Nahrajte nový súbor firmvéru (.bin) alebo súbor zálohy (.json)',
|
UPLOAD_TEXT: 'Nahrajte nový súbor firmvéru (.bin) alebo súbor zálohy (.json)',
|
||||||
UPLOAD_DROP_TEXT: 'Drop a firmware .bin file or click here', // TODO translate
|
UPLOAD_DROP_TEXT: 'Presuňte súbor .bin firmvéru alebo kliknite sem',
|
||||||
ERROR: 'Neočakávaná chyba, prosím skúste to znova',
|
ERROR: 'Neočakávaná chyba, prosím skúste to znova',
|
||||||
TIME_SET: 'Nastavený čas',
|
TIME_SET: 'Nastavený čas',
|
||||||
MANAGE_USERS: 'Správa používateľov',
|
MANAGE_USERS: 'Správa používateľov',
|
||||||
@@ -331,19 +331,18 @@ const sk: Translation = {
|
|||||||
ALLVALUES: 'Všetky hodnoty',
|
ALLVALUES: 'Všetky hodnoty',
|
||||||
SPECIAL_FUNCTIONS: 'Špeciálne funkcie',
|
SPECIAL_FUNCTIONS: 'Špeciálne funkcie',
|
||||||
WAIT_FIRMWARE: 'Firmvér sa nahráva a inštaluje',
|
WAIT_FIRMWARE: 'Firmvér sa nahráva a inštaluje',
|
||||||
INSTALL_VERSION: 'Týmto sa inštalovať verzia {0}. Si si istý?',
|
INSTALL_VERSION: 'Týmto sa {0} verzia {1}. Si si istý?',
|
||||||
UPGRADE_AVAILABLE: 'K dispozícii je aktualizácia firmvéru!',
|
UPDATE_AVAILABLE: 'dostupná aktualizácia',
|
||||||
LATEST_VERSION: 'Používate poslednú verziu firmvéru',
|
LATEST_VERSION: 'Používate poslednú {0} verziu firmvéru',
|
||||||
PLEASE_WAIT: 'Čakajte prosím',
|
PLEASE_WAIT: 'Čakajte prosím',
|
||||||
RESTARTING_PRE: 'Prebieha inicializácia',
|
RESTARTING_PRE: 'Prebieha inicializácia',
|
||||||
RESTARTING_POST: 'Príprava',
|
RESTARTING_POST: 'Príprava',
|
||||||
AUTO_SCROLL: 'Automatické rolovanie',
|
AUTO_SCROLL: 'Automatické rolovanie',
|
||||||
DASHBOARD: 'Panel',
|
DASHBOARD: 'Panel',
|
||||||
DEVELOPER_MODE: 'Režim vývojára',
|
DEVELOPER_MODE: 'Režim vývojára',
|
||||||
BYTES: 'Bytes', // TODO translate
|
BYTES: 'Bytov',
|
||||||
BITMASK: 'Bit Mask',// TODO translate
|
BITMASK: 'Bitová maska',
|
||||||
DUPLICATE: 'Duplicitné',
|
DUPLICATE: 'Duplicitné',
|
||||||
UPGRADE: 'Inovovať',
|
|
||||||
DASHBOARD_1: 'Všetky entity EMS, ktoré sú aktívne a označené ako obľúbené, plus všetky vlastné entity, plány a údaje externých senzorov sú zobrazené nižšie.',
|
DASHBOARD_1: 'Všetky entity EMS, ktoré sú aktívne a označené ako obľúbené, plus všetky vlastné entity, plány a údaje externých senzorov sú zobrazené nižšie.',
|
||||||
NO_DATA_1: 'Nenašli sa žiadne obľúbené entity EMS. Použite',
|
NO_DATA_1: 'Nenašli sa žiadne obľúbené entity EMS. Použite',
|
||||||
NO_DATA_2: 'modul na ich označenie.',
|
NO_DATA_2: 'modul na ich označenie.',
|
||||||
@@ -351,8 +350,8 @@ const sk: Translation = {
|
|||||||
THIS_VERSION: 'Táto verzia',
|
THIS_VERSION: 'Táto verzia',
|
||||||
PLATFORM: 'Platforma',
|
PLATFORM: 'Platforma',
|
||||||
RELEASE_TYPE: 'Typ vydania',
|
RELEASE_TYPE: 'Typ vydania',
|
||||||
REINSTALL: 'Preinštalovať',
|
|
||||||
INTERNET_CONNECTION_REQUIRED: 'Internetové pripojenie je potrebné pre automatickú kontrolu a aktualizáciu',
|
INTERNET_CONNECTION_REQUIRED: 'Internetové pripojenie je potrebné pre automatickú kontrolu a aktualizáciu',
|
||||||
|
SWITCH_RELEASE_TYPE: 'Prepnúť na {0} verziu'
|
||||||
};
|
};
|
||||||
|
|
||||||
export default sk;
|
export default sk;
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ const sv: Translation = {
|
|||||||
COMPACT: 'Komprimerad',
|
COMPACT: 'Komprimerad',
|
||||||
DOWNLOAD_SETTINGS_TEXT: 'Skapa en säkerhetskopia av din konfiguration och inställningar',
|
DOWNLOAD_SETTINGS_TEXT: 'Skapa en säkerhetskopia av din konfiguration och inställningar',
|
||||||
UPLOAD_TEXT: 'Ladda upp en ny firmwarefil (.bin) eller en säkerhetskopiafil (.json)',
|
UPLOAD_TEXT: 'Ladda upp en ny firmwarefil (.bin) eller en säkerhetskopiafil (.json)',
|
||||||
UPLOAD_DROP_TEXT: 'Drop a firmware .bin file or click here', // TODO translate
|
UPLOAD_DROP_TEXT: 'Droppa en firmware .bin fil eller klicka här',
|
||||||
ERROR: 'Okänt fel, var god försök igen',
|
ERROR: 'Okänt fel, var god försök igen',
|
||||||
TIME_SET: 'Ställ in tid',
|
TIME_SET: 'Ställ in tid',
|
||||||
MANAGE_USERS: 'Användare',
|
MANAGE_USERS: 'Användare',
|
||||||
@@ -331,28 +331,27 @@ const sv: Translation = {
|
|||||||
ALLVALUES: 'Alla värden',
|
ALLVALUES: 'Alla värden',
|
||||||
SPECIAL_FUNCTIONS: 'Specialfunktioner',
|
SPECIAL_FUNCTIONS: 'Specialfunktioner',
|
||||||
WAIT_FIRMWARE: 'Firmware laddas upp och installeras',
|
WAIT_FIRMWARE: 'Firmware laddas upp och installeras',
|
||||||
INSTALL_VERSION: 'Det här kommer installera version {0}. Är du säker?',
|
INSTALL_VERSION: 'Det här kommer {0} version {1}. Är du säker?',
|
||||||
UPGRADE_AVAILABLE: 'Det finns en tillgänglig firmwareupgradering!',
|
UPDATE_AVAILABLE: 'uppdatering tillgänglig',
|
||||||
LATEST_VERSION: 'Du använder den senaste firmwareversionen.',
|
LATEST_VERSION: 'Du använder den senaste {0} firmwareversionen.',
|
||||||
PLEASE_WAIT: 'Var god vänta',
|
PLEASE_WAIT: 'Var god vänta',
|
||||||
RESTARTING_PRE: 'Initialiserar',
|
RESTARTING_PRE: 'Initialiserar',
|
||||||
RESTARTING_POST: 'Förbereder',
|
RESTARTING_POST: 'Förbereder',
|
||||||
AUTO_SCROLL: 'Autoskrolla',
|
AUTO_SCROLL: 'Autoskrolla',
|
||||||
DASHBOARD: 'Kontrollpanel',
|
DASHBOARD: 'Kontrollpanel',
|
||||||
DEVELOPER_MODE: 'Utvecklarläge',
|
DEVELOPER_MODE: 'Utvecklarläge',
|
||||||
BYTES: 'Bytes', // TODO translate
|
BYTES: 'Bytes',
|
||||||
BITMASK: 'Bit Mask',// TODO translate
|
BITMASK: 'Bitmask',
|
||||||
DUPLICATE: 'Dublett',
|
DUPLICATE: 'Dublett',
|
||||||
UPGRADE: 'Uppgradera',
|
DASHBOARD_1: 'Alla EMS-enheter som är aktiva och markerade som favorit, plus alla anpassade entiteter, scheman och externa sensor-data visas nedan.',
|
||||||
DASHBOARD_1: 'All EMS entities that are active and marked as Favorite, plus all Custom Entities, Schedules and external Sensors data are displayed below.', // TODO translate
|
NO_DATA_1: 'Inga favorit EMS enheter hittade än. Använd',
|
||||||
NO_DATA_1: 'No favorite EMS entities found yet. Use the', // TODO translate
|
NO_DATA_2: 'modul för att markera dem.',
|
||||||
NO_DATA_2: 'module to mark them.', // TODO translate
|
NO_DATA_3: 'För att se alla tillgängliga enheter, gå till',
|
||||||
NO_DATA_3: 'To see all available entities go to', // TODO translate
|
THIS_VERSION: 'Denna version',
|
||||||
THIS_VERSION: 'This Version', // TODO translate
|
PLATFORM: 'Plattform',
|
||||||
PLATFORM: 'Platform', // TODO translate
|
RELEASE_TYPE: 'Utgivelsestyp',
|
||||||
RELEASE_TYPE: 'Release Type', // TODO translate
|
|
||||||
REINSTALL: 'Re-install', // TODO translate
|
|
||||||
INTERNET_CONNECTION_REQUIRED: 'Internetanslutning krävs för automatisk version kontroll och uppdatering',
|
INTERNET_CONNECTION_REQUIRED: 'Internetanslutning krävs för automatisk version kontroll och uppdatering',
|
||||||
|
SWITCH_RELEASE_TYPE: 'Byt till {0} utgåva'
|
||||||
};
|
};
|
||||||
|
|
||||||
export default sv;
|
export default sv;
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ const tr: Translation = {
|
|||||||
RESET: 'Reset',
|
RESET: 'Reset',
|
||||||
APPLY_CHANGES: 'Apply Changes ({0})',
|
APPLY_CHANGES: 'Apply Changes ({0})',
|
||||||
UPDATE: 'Update',
|
UPDATE: 'Update',
|
||||||
EXECUTE: 'Execute', // TODO translate
|
EXECUTE: 'Uygulamak',
|
||||||
REMOVE: 'Kaldır',
|
REMOVE: 'Kaldır',
|
||||||
PROBLEM_UPDATING: 'Güncelleme Sorunu',
|
PROBLEM_UPDATING: 'Güncelleme Sorunu',
|
||||||
PROBLEM_LOADING: 'Yükleme Sorunu',
|
PROBLEM_LOADING: 'Yükleme Sorunu',
|
||||||
@@ -72,7 +72,7 @@ const tr: Translation = {
|
|||||||
TX_ISSUES: 'Tx sorunu - başka bir Tx Modu deneyin',
|
TX_ISSUES: 'Tx sorunu - başka bir Tx Modu deneyin',
|
||||||
DISCONNECTED: 'Bağlantı kesildi',
|
DISCONNECTED: 'Bağlantı kesildi',
|
||||||
EMS_SCAN: 'EMS Hattında tam bir cihaz taraması başlatmak istediğinizden emin misiniz?',
|
EMS_SCAN: 'EMS Hattında tam bir cihaz taraması başlatmak istediğinizden emin misiniz?',
|
||||||
DATA_TRAFFIC: 'Data Traffic', // TODO translate
|
DATA_TRAFFIC: 'Veri trafiği',
|
||||||
EMS_DEVICE: 'EMS Cihazı',
|
EMS_DEVICE: 'EMS Cihazı',
|
||||||
SUCCESS: 'BAŞARILI',
|
SUCCESS: 'BAŞARILI',
|
||||||
FAIL: 'HATA',
|
FAIL: 'HATA',
|
||||||
@@ -115,8 +115,8 @@ const tr: Translation = {
|
|||||||
READONLY: 'Salt okunur modu devreye al (bütün giden EMS Tx Yazma komutlarını engeller)',
|
READONLY: 'Salt okunur modu devreye al (bütün giden EMS Tx Yazma komutlarını engeller)',
|
||||||
UNDERCLOCK_CPU: 'İşlemci hızını düşür',
|
UNDERCLOCK_CPU: 'İşlemci hızını düşür',
|
||||||
REMOTE_TIMEOUT: 'Remote timeout',
|
REMOTE_TIMEOUT: 'Remote timeout',
|
||||||
REMOTE_TIMEOUT_EN: 'Disable remote on missing room temperature', // TODO translate
|
REMOTE_TIMEOUT_EN: 'Disable remote on missing room temperature',
|
||||||
HEATINGOFF: 'Start boiler with forced heating off', // TODO translate
|
HEATINGOFF: 'Start boiler with forced heating off',
|
||||||
MIN_DURATION: 'Wait time',
|
MIN_DURATION: 'Wait time',
|
||||||
ENABLE_SHOWER_TIMER: 'Duş Sayacını Devreye Al',
|
ENABLE_SHOWER_TIMER: 'Duş Sayacını Devreye Al',
|
||||||
ENABLE_SHOWER_ALERT: 'Duş Alarmını Devreye Al',
|
ENABLE_SHOWER_ALERT: 'Duş Alarmını Devreye Al',
|
||||||
@@ -174,8 +174,8 @@ const tr: Translation = {
|
|||||||
FACTORY_RESET: 'Fabrika ayarına dönme',
|
FACTORY_RESET: 'Fabrika ayarına dönme',
|
||||||
SYSTEM_FACTORY_TEXT: 'Cihaz fabrika ayarlarına döndü ve şimdi yendiden başlatılacak',
|
SYSTEM_FACTORY_TEXT: 'Cihaz fabrika ayarlarına döndü ve şimdi yendiden başlatılacak',
|
||||||
SYSTEM_FACTORY_TEXT_DIALOG: 'Cihazı fabrika ayarlarına döndürmek istediğinize emin misiniz?',
|
SYSTEM_FACTORY_TEXT_DIALOG: 'Cihazı fabrika ayarlarına döndürmek istediğinize emin misiniz?',
|
||||||
AVAILABLE_VERSION: 'Latest Available Versions', // TODO translate
|
AVAILABLE_VERSION: 'En son kullanılabilir sürümler',
|
||||||
STABLE: 'Stable', // TODO translate
|
STABLE: 'Kararlı',
|
||||||
DEVELOPMENT: 'Geliştirme',
|
DEVELOPMENT: 'Geliştirme',
|
||||||
UPTIME: 'Sistem Çalışma Süresi',
|
UPTIME: 'Sistem Çalışma Süresi',
|
||||||
FREE_MEMORY: 'Yığın Memory',
|
FREE_MEMORY: 'Yığın Memory',
|
||||||
@@ -185,9 +185,9 @@ const tr: Translation = {
|
|||||||
FILESYSTEM: 'Dosya Sistemi (Kullanılmış / Boş)',
|
FILESYSTEM: 'Dosya Sistemi (Kullanılmış / Boş)',
|
||||||
BUFFER_SIZE: 'En fazla bellek boyutu',
|
BUFFER_SIZE: 'En fazla bellek boyutu',
|
||||||
COMPACT: 'Sıkışık',
|
COMPACT: 'Sıkışık',
|
||||||
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
|
DOWNLOAD_SETTINGS_TEXT: 'Yapılandırma ve ayarlarınızın yedekleme yapın',
|
||||||
UPLOAD_TEXT: 'Upload a new firmware file (.bin) or a backup file (.json)', // TODO translate
|
UPLOAD_TEXT: 'Yeni bir firmware dosyası (.bin) veya yedek dosyası (.json) yükle',
|
||||||
UPLOAD_DROP_TEXT: 'Drop a firmware .bin file or click here', // TODO translate
|
UPLOAD_DROP_TEXT: 'Bir firmware .bin dosyası veya buraya tıklayın',
|
||||||
ERROR: 'Beklenemedik hata, lütfen tekrar deneyin.',
|
ERROR: 'Beklenemedik hata, lütfen tekrar deneyin.',
|
||||||
TIME_SET: 'Zaman ayarı',
|
TIME_SET: 'Zaman ayarı',
|
||||||
MANAGE_USERS: 'Kullanıcıları yönet',
|
MANAGE_USERS: 'Kullanıcıları yönet',
|
||||||
@@ -223,7 +223,7 @@ const tr: Translation = {
|
|||||||
MQTT_INT_THERMOSTATS: 'Termostatlar',
|
MQTT_INT_THERMOSTATS: 'Termostatlar',
|
||||||
MQTT_INT_SOLAR: 'Güneş Enerjisi Modülleri',
|
MQTT_INT_SOLAR: 'Güneş Enerjisi Modülleri',
|
||||||
MQTT_INT_MIXER: 'Karışım Modülleri',
|
MQTT_INT_MIXER: 'Karışım Modülleri',
|
||||||
MQTT_INT_WATER: 'Water Modules', // TODO translate
|
MQTT_INT_WATER: 'Su Modülleri',
|
||||||
MQTT_QUEUE: 'MQTT Sırası',
|
MQTT_QUEUE: 'MQTT Sırası',
|
||||||
DEFAULT: 'Varsayılan',
|
DEFAULT: 'Varsayılan',
|
||||||
MQTT_ENTITY_FORMAT: 'Varlık Kimlik biçimi',
|
MQTT_ENTITY_FORMAT: 'Varlık Kimlik biçimi',
|
||||||
@@ -260,7 +260,7 @@ const tr: Translation = {
|
|||||||
NETWORK_SCANNER: 'Ağ Tarayıcısı',
|
NETWORK_SCANNER: 'Ağ Tarayıcısı',
|
||||||
NETWORK_NO_WIFI: 'Hiçbir Kablosuz Ağ bulunamadı',
|
NETWORK_NO_WIFI: 'Hiçbir Kablosuz Ağ bulunamadı',
|
||||||
NETWORK_BLANK_SSID: 'Kablosuz ağı devre dışı bırakmak için boş bırakın',
|
NETWORK_BLANK_SSID: 'Kablosuz ağı devre dışı bırakmak için boş bırakın',
|
||||||
NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate
|
NETWORK_BLANK_BSSID: 'sadece SSID kullanmak için boş bırakın',
|
||||||
TX_POWER: 'Aktarım gücü',
|
TX_POWER: 'Aktarım gücü',
|
||||||
HOSTNAME: 'Ana Makine Adı',
|
HOSTNAME: 'Ana Makine Adı',
|
||||||
NETWORK_DISABLE_SLEEP: 'Kablosuz uyku modunu devre dışına al',
|
NETWORK_DISABLE_SLEEP: 'Kablosuz uyku modunu devre dışına al',
|
||||||
@@ -280,79 +280,78 @@ const tr: Translation = {
|
|||||||
ENTITY: 'varlık',
|
ENTITY: 'varlık',
|
||||||
MIN: 'min',
|
MIN: 'min',
|
||||||
MAX: 'maks',
|
MAX: 'maks',
|
||||||
BLOCK_NAVIGATE_1: 'You have unsaved changes', // TODO translate
|
BLOCK_NAVIGATE_1: 'Değiştirilmişleriniz var',
|
||||||
BLOCK_NAVIGATE_2: 'If you navigate to a different page, your unsaved changes will be lost. Are you sure you want to leave this page?', // TODO translate
|
BLOCK_NAVIGATE_2: 'Farklı bir sayfaya geçerseniz değiştirilmişleriniz kaybolacak. Bu sayfadan çıkmak istediğinize emin misiniz?',
|
||||||
STAY: 'Stay', // TODO translate
|
STAY: 'Kal',
|
||||||
LEAVE: 'Leave', // TODO translate
|
LEAVE: 'Çık',
|
||||||
SCHEDULER: 'Scheduler', // TODO translate
|
SCHEDULER: 'Zamanlayıcı',
|
||||||
SCHEDULER_HELP_1: 'Automate commands by adding scheduled events below. Set a unique Name to enable/disable activation via API/MQTT', // TODO translate
|
SCHEDULER_HELP_1: 'Komutları zamanlayarak otomatikleştirin. Benzersiz bir ad belirtin API/MQTT aracılığıyla etkinleştirmek/devre dışı bırakma',
|
||||||
SCHEDULER_HELP_2: 'Use 00:00 to trigger once on start-up', // TODO translate
|
SCHEDULER_HELP_2: 'Başlangıçta bir kere tetiklemek için 00:00 kullanın',
|
||||||
SCHEDULE: 'Schedule', // TODO translate
|
SCHEDULE: 'Zamanlama',
|
||||||
TIME: 'Time', // TODO translate
|
TIME: 'Zaman',
|
||||||
TIMER: 'Timer', // TODO translate
|
TIMER: 'Zamanlayıcı',
|
||||||
ONCHANGE: 'Değişimde',
|
ONCHANGE: 'Değişimde',
|
||||||
CONDITION: 'Durum', // TODO translate
|
CONDITION: 'Durum',
|
||||||
IMMEDIATE: 'hemen', // TODO translate
|
IMMEDIATE: 'hemen',
|
||||||
SCHEDULE_UPDATED: 'Schedule updated', // TODO translate
|
SCHEDULE_UPDATED: 'Zamanlama güncellendi',
|
||||||
SCHEDULE_TIMER_1: 'on startup', // TODO translate
|
SCHEDULE_TIMER_1: 'Başlangıçta',
|
||||||
SCHEDULE_TIMER_2: 'every minute', // TODO translate
|
SCHEDULE_TIMER_2: 'her dakikada',
|
||||||
SCHEDULE_TIMER_3: 'every hour', // TODO translate
|
SCHEDULE_TIMER_3: 'her saatte',
|
||||||
CUSTOM_ENTITIES: 'Custom Entities', // TODO translate
|
CUSTOM_ENTITIES: 'Özel Varlıklar',
|
||||||
ENTITIES_HELP_1: 'Fetch custom entities from the EMS bus', // TODO translate
|
ENTITIES_HELP_1: 'Özel varlıkları EMS hattından alın',
|
||||||
ENTITIES_UPDATED: 'Entities Updated', // TODO translate
|
ENTITIES_UPDATED: 'Varlıklar güncellendi',
|
||||||
WRITEABLE: 'Writeable', // TODO translate
|
WRITEABLE: 'Yazılabilir',
|
||||||
SHOWING: 'Showing', // TODO translate
|
SHOWING: 'Görüntüleniyor',
|
||||||
SEARCH: 'Search', // TODO translate
|
SEARCH: 'Ara',
|
||||||
CERT: 'TLS root certificate (leave blank for insecure)',
|
CERT: 'TLS kök sertifikası (güvenli olmayan için boş bırakın)',
|
||||||
ENABLE_TLS: 'TLS deveye al',
|
ENABLE_TLS: 'TLS deveye al',
|
||||||
ON: 'On', // TODO translate
|
ON: 'On',
|
||||||
OFF: 'Off', // TODO translate
|
OFF: 'Off',
|
||||||
POLARITY: 'Polarity', // TODO translate
|
POLARITY: 'Polarity',
|
||||||
ACTIVEHIGH: 'Active High', // TODO translate
|
ACTIVEHIGH: 'Aktif Yüksek',
|
||||||
ACTIVELOW: 'Active Low', // TODO translate
|
ACTIVELOW: 'Aktif Düşük',
|
||||||
UNCHANGED: 'Unchanged', // TODO translate
|
UNCHANGED: 'Değiştirilmedi',
|
||||||
ALWAYS: 'Always', // TODO translate
|
ALWAYS: 'Her zaman',
|
||||||
ACTIVITY: 'Activity', // TODO translate
|
ACTIVITY: 'Faaliyet',
|
||||||
CONFIGURE: 'Configure {0}', // TODO translate
|
CONFIGURE: 'Yapılandır {0}',
|
||||||
SYSTEM_MEMORY: 'System Memory', // TODO translate
|
SYSTEM_MEMORY: 'Sistem Belleği',
|
||||||
APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate
|
APPLICATION_SETTINGS_1: 'EMS-ESP Uygulama Ayarlarını Değiştir',
|
||||||
SECURITY_1: 'Add or remove users', // TODO translate
|
SECURITY_1: 'Kullanıcıları ekle veya kaldır',
|
||||||
DOWNLOAD_UPLOAD_1: 'Download and Upload Settings and Firmware', // TODO translate
|
DOWNLOAD_UPLOAD_1: 'Ayarları ve firmware dosyasını indir ve yükle',
|
||||||
MODULES: 'Module', // TODO translate
|
MODULES: 'Modül',
|
||||||
MODULES_1: 'Harici modülleri etkinleştirin veya devre dışı bırakın',
|
MODULES_1: 'Harici modülleri etkinleştirin veya devre dışı bırakın',
|
||||||
MODULES_UPDATED: 'Modules updated', // TODO translate
|
MODULES_UPDATED: 'Modülleri güncellendi',
|
||||||
MODULES_DESCRIPTION: 'Click on the Module to activate or de-activate EMS-ESP library modules', // TODO translate
|
MODULES_DESCRIPTION: 'Modüle tıklayarak etkinleştirin veya devre dışı bırakın EMS-ESP kütüphane modülleri',
|
||||||
MODULES_NONE: 'No external modules detected', // TODO translate
|
MODULES_NONE: 'Hiçbir harici modül tespit edilmedi',
|
||||||
RENAME: 'Rename', // TODO translate
|
RENAME: 'Yeniden Adlandır',
|
||||||
ENABLE_MODBUS: 'Enable Modbus', // TODO translate
|
ENABLE_MODBUS: 'Modbus\'ı etkinleştir',
|
||||||
VIEW_LOG: 'View log to diagnose issues', // TODO translate
|
VIEW_LOG: 'Sorunu tanımlamak için günlüğü görüntüleyin',
|
||||||
UPLOAD_DRAG: 'drag and drop a file here or click to select one', // TODO translate
|
UPLOAD_DRAG: 'Bir dosya buraya sürükleyip bırakın veya seçmek için tıklayın',
|
||||||
SERVICES: 'Services', // TODO translate
|
SERVICES: 'Hizmetler',
|
||||||
ALLVALUES: 'All Values', // TODO translate
|
ALLVALUES: 'Tüm Değerler',
|
||||||
SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate
|
SPECIAL_FUNCTIONS: 'Özel Fonksiyonlar',
|
||||||
WAIT_FIRMWARE: 'Firmware is uploading and installing', // TODO translate
|
WAIT_FIRMWARE: 'Firmware yükleniyor ve yükleniyor',
|
||||||
INSTALL_VERSION: 'This will install version {0}. Are you sure?', // TODO translate
|
INSTALL_VERSION: 'Bu {0} sürümü {1} yükleyecek. Emin misiniz?',
|
||||||
UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate
|
UPDATE_AVAILABLE: 'güncellendi!',
|
||||||
LATEST_VERSION: 'You are using the latest firmware version.', // TODO translate
|
LATEST_VERSION: 'En son {0} firmware sürümünü kullanıyorsunuz.',
|
||||||
PLEASE_WAIT: 'Please wait', // TODO translate
|
PLEASE_WAIT: 'Lütfen bekleyin',
|
||||||
RESTARTING_PRE: 'Initializing', // TODO translate
|
RESTARTING_PRE: 'Başlatılıyor',
|
||||||
RESTARTING_POST: 'Preparing', // TODO translate
|
RESTARTING_POST: 'Hazırlanıyor',
|
||||||
AUTO_SCROLL: 'Auto Scroll', // TODO translate
|
AUTO_SCROLL: 'Otomatik kaydırma',
|
||||||
DASHBOARD: 'Dashboard', // TODO translate
|
DASHBOARD: 'Kontrol Paneli',
|
||||||
DEVELOPER_MODE: 'Developer Mode', // TODO translate
|
DEVELOPER_MODE: 'Geliştirici Modu',
|
||||||
BYTES: 'Bytes', // TODO translate
|
BYTES: 'Bayt',
|
||||||
BITMASK: 'Bit Mask',// TODO translate
|
BITMASK: 'Bit Maskesi',
|
||||||
DUPLICATE: 'Duplicate', // TODO translate
|
DUPLICATE: 'Çift',
|
||||||
UPGRADE: 'Upgrade', // TODO translate
|
DASHBOARD_1: 'Tüm aktif ve Favori olarak işaretlenmiş EMS varlıkları, artı tüm özel varlıklar, zamanlayıcılar ve harici sensör verileri aşağıda görüntüleniyor.',
|
||||||
DASHBOARD_1: 'All EMS entities that are active and marked as Favorite, plus all Custom Entities, Schedules and external Sensors data are displayed below.', // TODO translate
|
NO_DATA_1: 'Henüz bir favori EMS varlığı bulunamadı. Kullanın',
|
||||||
NO_DATA_1: 'No favorite EMS entities found yet. Use the', // TODO translate
|
NO_DATA_2: 'modülünü kullanın.',
|
||||||
NO_DATA_2: 'module to mark them.', // TODO translate
|
NO_DATA_3: 'Tüm kullanılabilir varlıkları görmek için git',
|
||||||
NO_DATA_3: 'To see all available entities go to', // TODO translate
|
THIS_VERSION: 'Bu Sürüm',
|
||||||
THIS_VERSION: 'This Version', // TODO translate
|
PLATFORM: 'Platforma',
|
||||||
PLATFORM: 'Platform', // TODO translate
|
RELEASE_TYPE: 'Sürüm Tipi',
|
||||||
RELEASE_TYPE: 'Release Type', // TODO translate
|
INTERNET_CONNECTION_REQUIRED: 'Otomatik sürüm kontrolü ve güncelleme için internet bağlantısı gereklidir',
|
||||||
REINSTALL: 'Re-install', // TODO translate
|
SWITCH_RELEASE_TYPE: '{0} sürümüne geç'
|
||||||
INTERNET_CONNECTION_REQUIRED: 'Internet connection required for automatic version checking and upgrading', // TODO translate
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default tr;
|
export default tr;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import preact from '@preact/preset-vite';
|
import preact from '@preact/preset-vite';
|
||||||
import { visualizer } from 'rollup-plugin-visualizer';
|
import { visualizer } from 'rollup-plugin-visualizer';
|
||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
import viteImagemin from 'vite-plugin-imagemin';
|
// import viteImagemin from 'vite-plugin-imagemin';
|
||||||
import viteTsconfigPaths from 'vite-tsconfig-paths';
|
import viteTsconfigPaths from 'vite-tsconfig-paths';
|
||||||
|
|
||||||
import mockServer from '../mock-api/mockServer.js';
|
import mockServer from '../mock-api/mockServer.js';
|
||||||
@@ -43,37 +43,37 @@ export default defineConfig(({ command, mode }) => {
|
|||||||
plugins: [
|
plugins: [
|
||||||
preact(),
|
preact(),
|
||||||
viteTsconfigPaths(),
|
viteTsconfigPaths(),
|
||||||
{
|
// {
|
||||||
...viteImagemin({
|
// ...viteImagemin({
|
||||||
verbose: false,
|
// verbose: false,
|
||||||
gifsicle: {
|
// gifsicle: {
|
||||||
optimizationLevel: 7,
|
// optimizationLevel: 7,
|
||||||
interlaced: false
|
// interlaced: false
|
||||||
},
|
// },
|
||||||
optipng: {
|
// optipng: {
|
||||||
optimizationLevel: 7
|
// optimizationLevel: 7
|
||||||
},
|
// },
|
||||||
mozjpeg: {
|
// mozjpeg: {
|
||||||
quality: 20
|
// quality: 20
|
||||||
},
|
// },
|
||||||
pngquant: {
|
// pngquant: {
|
||||||
quality: [0.8, 0.9],
|
// quality: [0.8, 0.9],
|
||||||
speed: 4
|
// speed: 4
|
||||||
},
|
// },
|
||||||
svgo: {
|
// svgo: {
|
||||||
plugins: [
|
// plugins: [
|
||||||
{
|
// {
|
||||||
name: 'removeViewBox'
|
// name: 'removeViewBox'
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
name: 'removeEmptyAttrs',
|
// name: 'removeEmptyAttrs',
|
||||||
active: false
|
// active: false
|
||||||
}
|
// }
|
||||||
]
|
// ]
|
||||||
}
|
// }
|
||||||
}),
|
// }),
|
||||||
enforce: 'pre'
|
// enforce: 'pre'
|
||||||
},
|
// },
|
||||||
visualizer({
|
visualizer({
|
||||||
template: 'treemap', // or sunburst
|
template: 'treemap', // or sunburst
|
||||||
open: false,
|
open: false,
|
||||||
@@ -108,7 +108,6 @@ export default defineConfig(({ command, mode }) => {
|
|||||||
keep_fnames: false,
|
keep_fnames: false,
|
||||||
ie8: false,
|
ie8: false,
|
||||||
module: false,
|
module: false,
|
||||||
nameCache: null,
|
|
||||||
safari10: false,
|
safari10: false,
|
||||||
toplevel: false
|
toplevel: false
|
||||||
},
|
},
|
||||||
|
|||||||
7077
interface/yarn.lock
7077
interface/yarn.lock
File diff suppressed because it is too large
Load Diff
@@ -54,7 +54,15 @@ bool PButton::init(uint8_t pin, bool pullMode) {
|
|||||||
pullMode_ = pullMode; // 1=HIGH (pullup) 0=LOW (pulldown)
|
pullMode_ = pullMode; // 1=HIGH (pullup) 0=LOW (pulldown)
|
||||||
|
|
||||||
#if defined(ESP32)
|
#if defined(ESP32)
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
|
if (pin_ == 34 || pin_ == 35 || pin_ == 36 || pin_ == 39) {
|
||||||
|
pinMode(pin_, INPUT);
|
||||||
|
} else {
|
||||||
|
pinMode(pin_, pullMode ? INPUT_PULLUP : INPUT_PULLDOWN);
|
||||||
|
}
|
||||||
|
#else
|
||||||
pinMode(pin_, pullMode ? INPUT_PULLUP : INPUT_PULLDOWN);
|
pinMode(pin_, pullMode ? INPUT_PULLUP : INPUT_PULLDOWN);
|
||||||
|
#endif
|
||||||
#else // esp8266 and standalone
|
#else // esp8266 and standalone
|
||||||
pinMode(pin_, pullMode ? INPUT_PULLUP : INPUT);
|
pinMode(pin_, pullMode ? INPUT_PULLUP : INPUT);
|
||||||
#endif
|
#endif
|
||||||
@@ -93,7 +101,15 @@ bool PButton::check(void) {
|
|||||||
|
|
||||||
// make sure the pin is still input
|
// make sure the pin is still input
|
||||||
#if defined(ESP32)
|
#if defined(ESP32)
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
|
if (pin_ == 34 || pin_ == 35 || pin_ == 36 || pin_ == 39) {
|
||||||
|
pinMode(pin_, INPUT);
|
||||||
|
} else {
|
||||||
|
pinMode(pin_, pullMode_ ? INPUT_PULLUP : INPUT_PULLDOWN);
|
||||||
|
}
|
||||||
|
#else
|
||||||
pinMode(pin_, pullMode_ ? INPUT_PULLUP : INPUT_PULLDOWN);
|
pinMode(pin_, pullMode_ ? INPUT_PULLUP : INPUT_PULLDOWN);
|
||||||
|
#endif
|
||||||
#else // esp8266 and standalone
|
#else // esp8266 and standalone
|
||||||
pinMode(pin_, pullMode_ ? INPUT_PULLUP : INPUT);
|
pinMode(pin_, pullMode_ ? INPUT_PULLUP : INPUT);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
9
lib/eModbus/library.properties
Normal file
9
lib/eModbus/library.properties
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
name=eModbus
|
||||||
|
version=1.7.4
|
||||||
|
author=bertmelis,Miq1 <miq1@gmx.de>
|
||||||
|
maintainer=Miq1 <miq1@gmx.de>
|
||||||
|
sentence=eModbus provides Modbus RTU, ASCII and TCP functions for ESP32.
|
||||||
|
paragraph=This library is non-blocking for the program using it. Modbus requests and responses will be returned to user-supplied callback functions. All Modbus function codes are supported implicitly, the codes specified by the Modbus specs are parameter-checked.
|
||||||
|
category=Communication
|
||||||
|
url=https://github.com/eModbus/eModbus
|
||||||
|
architectures=esp32,FreeRTOS
|
||||||
@@ -47,6 +47,8 @@ CoilData::~CoilData() {
|
|||||||
|
|
||||||
// Assignment operator
|
// Assignment operator
|
||||||
CoilData& CoilData::operator=(const CoilData& m) {
|
CoilData& CoilData::operator=(const CoilData& m) {
|
||||||
|
// Avoid self-assignment
|
||||||
|
if (this == &m) return *this;
|
||||||
// Remove old data
|
// Remove old data
|
||||||
if (CDbuffer) {
|
if (CDbuffer) {
|
||||||
delete CDbuffer;
|
delete CDbuffer;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include "ModbusClient.h"
|
#include "ModbusClient.h"
|
||||||
|
#include "ModbusServer.h"
|
||||||
#include "ModbusClientTCP.h" // Needed for client.setTarget()
|
#include "ModbusClientTCP.h" // Needed for client.setTarget()
|
||||||
#include "RTUutils.h" // Needed for RTScallback
|
#include "RTUutils.h" // Needed for RTScallback
|
||||||
|
|
||||||
@@ -29,7 +30,7 @@ public:
|
|||||||
ModbusBridge();
|
ModbusBridge();
|
||||||
|
|
||||||
// Constructors for the RTU variant. Parameters as are for ModbusServerRTU
|
// Constructors for the RTU variant. Parameters as are for ModbusServerRTU
|
||||||
ModbusBridge(uint32_t timeout, int rtsPin = -1);
|
explicit ModbusBridge(uint32_t timeout, int rtsPin = -1);
|
||||||
ModbusBridge(uint32_t timeout, RTScallback rts);
|
ModbusBridge(uint32_t timeout, RTScallback rts);
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
@@ -230,42 +231,56 @@ ModbusMessage ModbusBridge<SERVERCLASS>::bridgeWorker(ModbusMessage msg) {
|
|||||||
uint8_t aliasID = msg.getServerID();
|
uint8_t aliasID = msg.getServerID();
|
||||||
uint8_t functionCode = msg.getFunctionCode();
|
uint8_t functionCode = msg.getFunctionCode();
|
||||||
ModbusMessage response;
|
ModbusMessage response;
|
||||||
|
bool foundServer = false;
|
||||||
|
uint8_t usableID = 255;
|
||||||
|
|
||||||
// Find the (alias) serverID
|
// Find the (alias) serverID
|
||||||
if (servers.find(aliasID) != servers.end()) {
|
if (servers.find(aliasID) != servers.end()) {
|
||||||
|
foundServer = true;
|
||||||
|
usableID = aliasID;
|
||||||
|
} else {
|
||||||
|
if (servers.find(ANY_SERVER) != servers.end()) {
|
||||||
|
foundServer = true;
|
||||||
|
usableID = ANY_SERVER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (foundServer) {
|
||||||
// Found it. We may use servers[aliasID] now without allocating a new map slot
|
// Found it. We may use servers[aliasID] now without allocating a new map slot
|
||||||
|
|
||||||
// Request filter hook to be called here
|
// Request filter hook to be called here
|
||||||
if (servers[aliasID]->requestFilter) {
|
if (servers[usableID]->requestFilter) {
|
||||||
LOG_D("Calling request filter\n");
|
LOG_D("Calling request filter\n");
|
||||||
msg = servers[aliasID]->requestFilter(msg);
|
msg = servers[usableID]->requestFilter(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set real target server ID
|
// Set real target server ID
|
||||||
msg.setServerID(servers[aliasID]->serverID);
|
if (servers[usableID]->serverID != ANY_SERVER) {
|
||||||
|
msg.setServerID(servers[usableID]->serverID);
|
||||||
// Issue the request
|
|
||||||
LOG_D("Request (%02X/%02X) sent\n", servers[aliasID]->serverID, msg.getFunctionCode());
|
|
||||||
// TCP servers have a target host/port that needs to be set in the client
|
|
||||||
if (servers[aliasID]->serverType == TCP_SERVER) {
|
|
||||||
response = reinterpret_cast<ModbusClientTCP *>(servers[aliasID]->client)->syncRequestMT(msg, (uint32_t)millis(), servers[aliasID]->host, servers[aliasID]->port);
|
|
||||||
} else {
|
|
||||||
response = servers[aliasID]->client->syncRequestM(msg, (uint32_t)millis());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Response filter hook to be called here
|
// Issue the request
|
||||||
if (servers[aliasID]->responseFilter) {
|
LOG_D("Request (%02X/%02X) sent\n", servers[usableID]->serverID, msg.getFunctionCode());
|
||||||
LOG_D("Calling response filter\n");
|
// TCP servers have a target host/port that needs to be set in the client
|
||||||
response = servers[aliasID]->responseFilter(response);
|
if (servers[usableID]->serverType == TCP_SERVER) {
|
||||||
|
response = reinterpret_cast<ModbusClientTCP *>(servers[usableID]->client)->syncRequestMT(msg, (uint32_t)micros(), servers[usableID]->host, servers[usableID]->port);
|
||||||
|
} else {
|
||||||
|
response = servers[usableID]->client->syncRequestM(msg, (uint32_t)micros());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-set the requested server ID and function code (may have been modified by filters)
|
// Re-set the requested server ID and function code (may have been modified by filters)
|
||||||
response.setServerID(aliasID);
|
response.setServerID(aliasID);
|
||||||
|
|
||||||
if (response.getError() != SUCCESS) {
|
if (response.getError() != SUCCESS) {
|
||||||
response.setFunctionCode(functionCode | 0x80);
|
response.setFunctionCode(functionCode | 0x80);
|
||||||
} else {
|
} else {
|
||||||
response.setFunctionCode(functionCode);
|
response.setFunctionCode(functionCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Response filter hook to be called here
|
||||||
|
if (servers[usableID]->responseFilter) {
|
||||||
|
LOG_D("Calling response filter\n");
|
||||||
|
response = servers[usableID]->responseFilter(response);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// If we get here, something has gone wrong internally. We send back an error response anyway.
|
// If we get here, something has gone wrong internally. We send back an error response anyway.
|
||||||
response.setError(aliasID, functionCode, INVALID_SERVER);
|
response.setError(aliasID, functionCode, INVALID_SERVER);
|
||||||
|
|||||||
@@ -21,6 +21,13 @@ ModbusClient::ModbusClient() :
|
|||||||
onError(nullptr),
|
onError(nullptr),
|
||||||
onResponse(nullptr) { instanceCounter++; }
|
onResponse(nullptr) { instanceCounter++; }
|
||||||
|
|
||||||
|
// Default destructor: reduce number of clients by one
|
||||||
|
ModbusClient::~ModbusClient() {
|
||||||
|
if (instanceCounter) {
|
||||||
|
instanceCounter--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// onDataHandler: register callback for data responses
|
// onDataHandler: register callback for data responses
|
||||||
bool ModbusClient::onDataHandler(MBOnData handler) {
|
bool ModbusClient::onDataHandler(MBOnData handler) {
|
||||||
if (onData) {
|
if (onData) {
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ public:
|
|||||||
uint32_t getMessageCount(); // Informative: return number of messages created
|
uint32_t getMessageCount(); // Informative: return number of messages created
|
||||||
uint32_t getErrorCount(); // Informative: return number of errors received
|
uint32_t getErrorCount(); // Informative: return number of errors received
|
||||||
void resetCounts(); // Set both message and error counts to zero
|
void resetCounts(); // Set both message and error counts to zero
|
||||||
inline Error addRequest(ModbusMessage m, uint32_t token) { return addRequestM(m, token); }
|
inline Error addRequest(const ModbusMessage& m, uint32_t token) { return addRequestM(m, token); }
|
||||||
inline ModbusMessage syncRequest(ModbusMessage m, uint32_t token) { return syncRequestM(m, token); }
|
inline ModbusMessage syncRequest(const ModbusMessage& m, uint32_t token) { return syncRequestM(m, token); }
|
||||||
|
|
||||||
// Template function to generate syncRequest functions as long as there is a
|
// Template function to generate syncRequest functions as long as there is a
|
||||||
// matching ModbusMessage::setMessage() call
|
// matching ModbusMessage::setMessage() call
|
||||||
@@ -85,7 +85,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
ModbusClient(); // Default constructor
|
ModbusClient(); // Default constructor
|
||||||
virtual void isInstance() = 0; // Make class abstract
|
virtual ~ModbusClient(); // Destructor
|
||||||
ModbusMessage waitSync(uint8_t serverID, uint8_t functionCode, uint32_t token); // wait for syncRequest response to arrive
|
ModbusMessage waitSync(uint8_t serverID, uint8_t functionCode, uint32_t token); // wait for syncRequest response to arrive
|
||||||
// Virtual addRequest variant needed internally. All others done by template!
|
// Virtual addRequest variant needed internally. All others done by template!
|
||||||
virtual Error addRequestM(ModbusMessage msg, uint32_t token) = 0;
|
virtual Error addRequestM(ModbusMessage msg, uint32_t token) = 0;
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ void ModbusClientRTU::doBegin(uint32_t baudRate, int coreID, uint32_t userInterv
|
|||||||
char taskName[18];
|
char taskName[18];
|
||||||
snprintf(taskName, 18, "Modbus%02XRTU", instanceCounter);
|
snprintf(taskName, 18, "Modbus%02XRTU", instanceCounter);
|
||||||
// Start task to handle the queue
|
// Start task to handle the queue
|
||||||
xTaskCreatePinnedToCore((TaskFunction_t)&handleConnection, taskName, CLIENT_TASK_STACK, this, 6, &worker, coreID >= 0 ? coreID : NULL);
|
xTaskCreatePinnedToCore((TaskFunction_t)&handleConnection, taskName, CLIENT_TASK_STACK, this, 6, &worker, coreID >= 0 ? coreID : tskNO_AFFINITY);
|
||||||
|
|
||||||
LOG_D("Client task %d started. Interval=%d\n", (uint32_t)worker, MR_interval);
|
LOG_D("Client task %d started. Interval=%d\n", (uint32_t)worker, MR_interval);
|
||||||
}
|
}
|
||||||
@@ -151,6 +151,7 @@ void ModbusClientRTU::clearQueue()
|
|||||||
{
|
{
|
||||||
std::queue<RequestEntry> empty;
|
std::queue<RequestEntry> empty;
|
||||||
LOCK_GUARD(lockGuard, qLock);
|
LOCK_GUARD(lockGuard, qLock);
|
||||||
|
// Empty queue
|
||||||
std::swap(requests, empty);
|
std::swap(requests, empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,8 +343,11 @@ void ModbusClientRTU::handleConnection(ModbusClientRTU *instance) {
|
|||||||
{
|
{
|
||||||
// Safely lock the queue
|
// Safely lock the queue
|
||||||
LOCK_GUARD(lockGuard, instance->qLock);
|
LOCK_GUARD(lockGuard, instance->qLock);
|
||||||
// Remove the front queue entry
|
|
||||||
instance->requests.pop();
|
// Remove the front queue entry if the queue is not empty
|
||||||
|
if (!instance->requests.empty()) {
|
||||||
|
instance->requests.pop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
delay(1);
|
delay(1);
|
||||||
|
|||||||
@@ -67,15 +67,15 @@ protected:
|
|||||||
uint32_t token;
|
uint32_t token;
|
||||||
ModbusMessage msg;
|
ModbusMessage msg;
|
||||||
bool isSyncRequest;
|
bool isSyncRequest;
|
||||||
RequestEntry(uint32_t t, ModbusMessage m, bool syncReq = false) :
|
RequestEntry(uint32_t t, const ModbusMessage& m, bool syncReq = false) :
|
||||||
token(t),
|
token(t),
|
||||||
msg(m),
|
msg(m),
|
||||||
isSyncRequest(syncReq) {}
|
isSyncRequest(syncReq) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Base addRequest and syncRequest must be present
|
// Base addRequest and syncRequest must be present
|
||||||
Error addRequestM(ModbusMessage msg, uint32_t token);
|
Error addRequestM(ModbusMessage msg, uint32_t token) override;
|
||||||
ModbusMessage syncRequestM(ModbusMessage msg, uint32_t token);
|
ModbusMessage syncRequestM(ModbusMessage msg, uint32_t token) override;
|
||||||
|
|
||||||
// addToQueue: send freshly created request to queue
|
// addToQueue: send freshly created request to queue
|
||||||
bool addToQueue(uint32_t token, ModbusMessage msg, bool syncReq = false);
|
bool addToQueue(uint32_t token, ModbusMessage msg, bool syncReq = false);
|
||||||
@@ -89,7 +89,6 @@ protected:
|
|||||||
// start background task
|
// start background task
|
||||||
void doBegin(uint32_t baudRate, int coreID, uint32_t userInterval);
|
void doBegin(uint32_t baudRate, int coreID, uint32_t userInterval);
|
||||||
|
|
||||||
void isInstance() { return; } // make class instantiable
|
|
||||||
queue<RequestEntry> requests; // Queue to hold requests to be processed
|
queue<RequestEntry> requests; // Queue to hold requests to be processed
|
||||||
#if USE_MUTEX
|
#if USE_MUTEX
|
||||||
mutex qLock; // Mutex to protect queue
|
mutex qLock; // Mutex to protect queue
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ ModbusClientTCP::ModbusClientTCP(Client& client, uint16_t queueLimit) :
|
|||||||
MT_target(IPAddress(0, 0, 0, 0), 0, DEFAULTTIMEOUT, TARGETHOSTINTERVAL),
|
MT_target(IPAddress(0, 0, 0, 0), 0, DEFAULTTIMEOUT, TARGETHOSTINTERVAL),
|
||||||
MT_defaultTimeout(DEFAULTTIMEOUT),
|
MT_defaultTimeout(DEFAULTTIMEOUT),
|
||||||
MT_defaultInterval(TARGETHOSTINTERVAL),
|
MT_defaultInterval(TARGETHOSTINTERVAL),
|
||||||
MT_qLimit(queueLimit)
|
MT_qLimit(queueLimit),
|
||||||
|
MT_timeoutsToClose(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
// Alternative Constructor takes reference to Client (EthernetClient or WiFiClient) plus initial target host
|
// Alternative Constructor takes reference to Client (EthernetClient or WiFiClient) plus initial target host
|
||||||
@@ -29,7 +30,8 @@ ModbusClientTCP::ModbusClientTCP(Client& client, IPAddress host, uint16_t port,
|
|||||||
MT_target(host, port, DEFAULTTIMEOUT, TARGETHOSTINTERVAL),
|
MT_target(host, port, DEFAULTTIMEOUT, TARGETHOSTINTERVAL),
|
||||||
MT_defaultTimeout(DEFAULTTIMEOUT),
|
MT_defaultTimeout(DEFAULTTIMEOUT),
|
||||||
MT_defaultInterval(TARGETHOSTINTERVAL),
|
MT_defaultInterval(TARGETHOSTINTERVAL),
|
||||||
MT_qLimit(queueLimit)
|
MT_qLimit(queueLimit),
|
||||||
|
MT_timeoutsToClose(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
// Destructor: clean up queue, task etc.
|
// Destructor: clean up queue, task etc.
|
||||||
@@ -64,7 +66,7 @@ void ModbusClientTCP::end() {
|
|||||||
// begin: start worker task
|
// begin: start worker task
|
||||||
#if IS_LINUX
|
#if IS_LINUX
|
||||||
void *ModbusClientTCP::pHandle(void *p) {
|
void *ModbusClientTCP::pHandle(void *p) {
|
||||||
handleConnection((ModbusClientTCP *)p);
|
handleConnection(static_cast<ModbusClientTCP *>(p));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -84,7 +86,7 @@ void ModbusClientTCP::begin(int coreID) {
|
|||||||
char taskName[18];
|
char taskName[18];
|
||||||
snprintf(taskName, 18, "Modbus%02XTCP", instanceCounter);
|
snprintf(taskName, 18, "Modbus%02XTCP", instanceCounter);
|
||||||
// Start task to handle the queue
|
// Start task to handle the queue
|
||||||
xTaskCreatePinnedToCore((TaskFunction_t)&handleConnection, taskName, CLIENT_TASK_STACK, this, 5, &worker, coreID >= 0 ? coreID : NULL);
|
xTaskCreatePinnedToCore((TaskFunction_t)&handleConnection, taskName, CLIENT_TASK_STACK, this, 5, &worker, coreID >= 0 ? coreID : tskNO_AFFINITY);
|
||||||
LOG_D("TCP client worker %s started\n", taskName);
|
LOG_D("TCP client worker %s started\n", taskName);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
@@ -119,9 +121,25 @@ uint32_t ModbusClientTCP::pendingRequests() {
|
|||||||
void ModbusClientTCP::clearQueue() {
|
void ModbusClientTCP::clearQueue() {
|
||||||
std::queue<RequestEntry *> empty;
|
std::queue<RequestEntry *> empty;
|
||||||
LOCK_GUARD(lockGuard, qLock);
|
LOCK_GUARD(lockGuard, qLock);
|
||||||
|
// Delete queue entries if still on the queue
|
||||||
|
while (!requests.empty()) {
|
||||||
|
RequestEntry *re = requests.front();
|
||||||
|
delete re;
|
||||||
|
requests.pop();
|
||||||
|
}
|
||||||
|
// Now flush the queue
|
||||||
std::swap(requests, empty);
|
std::swap(requests, empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set number of timeouts to tolerate before a connection is forcibly closed.
|
||||||
|
// 0: never, 1..255: desired number
|
||||||
|
// Returns previous value.
|
||||||
|
uint8_t ModbusClientTCP::closeConnectionOnTimeouts(uint8_t n) {
|
||||||
|
uint8_t oldValue = MT_timeoutsToClose;
|
||||||
|
MT_timeoutsToClose = n;
|
||||||
|
return oldValue;
|
||||||
|
}
|
||||||
|
|
||||||
// Base addRequest for preformatted ModbusMessage and last set target
|
// Base addRequest for preformatted ModbusMessage and last set target
|
||||||
Error ModbusClientTCP::addRequestM(ModbusMessage msg, uint32_t token) {
|
Error ModbusClientTCP::addRequestM(ModbusMessage msg, uint32_t token) {
|
||||||
Error rc = SUCCESS; // Return value
|
Error rc = SUCCESS; // Return value
|
||||||
@@ -225,6 +243,7 @@ bool ModbusClientTCP::addToQueue(uint32_t token, ModbusMessage request, TargetHo
|
|||||||
void ModbusClientTCP::handleConnection(ModbusClientTCP *instance) {
|
void ModbusClientTCP::handleConnection(ModbusClientTCP *instance) {
|
||||||
bool doNotPop;
|
bool doNotPop;
|
||||||
unsigned long lastRequest = millis();
|
unsigned long lastRequest = millis();
|
||||||
|
uint16_t timeoutCount = 0; // Run time counter of consecutive timeouts.
|
||||||
|
|
||||||
// Loop forever - or until task is killed
|
// Loop forever - or until task is killed
|
||||||
while (1) {
|
while (1) {
|
||||||
@@ -273,6 +292,8 @@ void ModbusClientTCP::handleConnection(ModbusClientTCP *instance) {
|
|||||||
// Did we get a normal response?
|
// Did we get a normal response?
|
||||||
if (response.getError()==SUCCESS) {
|
if (response.getError()==SUCCESS) {
|
||||||
LOG_D("Data response.\n");
|
LOG_D("Data response.\n");
|
||||||
|
// Reset timeout counter
|
||||||
|
timeoutCount = 0;
|
||||||
// Yes. Is it a synchronous request?
|
// Yes. Is it a synchronous request?
|
||||||
if (request->isSyncRequest) {
|
if (request->isSyncRequest) {
|
||||||
// Yes. Put the response into the response map
|
// Yes. Put the response into the response map
|
||||||
@@ -299,6 +320,25 @@ void ModbusClientTCP::handleConnection(ModbusClientTCP *instance) {
|
|||||||
LOCK_GUARD(responseCnt, instance->countAccessM);
|
LOCK_GUARD(responseCnt, instance->countAccessM);
|
||||||
instance->errorCount++;
|
instance->errorCount++;
|
||||||
}
|
}
|
||||||
|
// Is it a TIMEOUT and do we need to track it?
|
||||||
|
if (response.getError()==TIMEOUT && instance->MT_timeoutsToClose) {
|
||||||
|
LOG_D("Checking timeout sequence\n");
|
||||||
|
// Yes. First count timeout conter up
|
||||||
|
timeoutCount++;
|
||||||
|
// Is the count above the limit?
|
||||||
|
if (timeoutCount > instance->MT_timeoutsToClose) {
|
||||||
|
LOG_D("Timeouts: %d exceeding limit (%d), closing connection\n",
|
||||||
|
timeoutCount, instance->MT_timeoutsToClose);
|
||||||
|
// Yes. We need to cut the connection
|
||||||
|
instance->MT_client.stop();
|
||||||
|
delay(1);
|
||||||
|
// reset timeout count
|
||||||
|
timeoutCount = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No TIMEOUT or no limit: reset timeout count
|
||||||
|
timeoutCount = 0;
|
||||||
|
}
|
||||||
// Is it a synchronous request?
|
// Is it a synchronous request?
|
||||||
if (request->isSyncRequest) {
|
if (request->isSyncRequest) {
|
||||||
// Yes. Put the response into the response map
|
// Yes. Put the response into the response map
|
||||||
@@ -345,8 +385,11 @@ void ModbusClientTCP::handleConnection(ModbusClientTCP *instance) {
|
|||||||
{
|
{
|
||||||
// Safely lock the queue
|
// Safely lock the queue
|
||||||
LOCK_GUARD(lockGuard, instance->qLock);
|
LOCK_GUARD(lockGuard, instance->qLock);
|
||||||
// Remove the front queue entry
|
|
||||||
instance->requests.pop();
|
// Remove the front queue entry if the queue is not empty
|
||||||
|
if (!instance->requests.empty()) {
|
||||||
|
instance->requests.pop();
|
||||||
|
}
|
||||||
// Delete request
|
// Delete request
|
||||||
delete request;
|
delete request;
|
||||||
LOG_D("Request popped from queue.\n");
|
LOG_D("Request popped from queue.\n");
|
||||||
|
|||||||
@@ -50,6 +50,11 @@ public:
|
|||||||
// Remove all pending request from queue
|
// Remove all pending request from queue
|
||||||
void clearQueue();
|
void clearQueue();
|
||||||
|
|
||||||
|
// Set number of timeouts to tolerate before a connection is forcibly closed.
|
||||||
|
// 0: never, 1..255: desired number
|
||||||
|
// Returns previous value.
|
||||||
|
uint8_t closeConnectionOnTimeouts(uint8_t n=3);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// class describing a target server
|
// class describing a target server
|
||||||
struct TargetHost {
|
struct TargetHost {
|
||||||
@@ -58,7 +63,7 @@ protected:
|
|||||||
uint32_t timeout; // Time in ms waiting for a response
|
uint32_t timeout; // Time in ms waiting for a response
|
||||||
uint32_t interval; // Time in ms to wait between requests
|
uint32_t interval; // Time in ms to wait between requests
|
||||||
|
|
||||||
inline TargetHost& operator=(TargetHost& t) {
|
inline TargetHost& operator=(const TargetHost& t) {
|
||||||
host = t.host;
|
host = t.host;
|
||||||
port = t.port;
|
port = t.port;
|
||||||
timeout = t.timeout;
|
timeout = t.timeout;
|
||||||
@@ -66,7 +71,7 @@ protected:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline TargetHost(TargetHost& t) :
|
inline TargetHost(const TargetHost& t) :
|
||||||
host(t.host),
|
host(t.host),
|
||||||
port(t.port),
|
port(t.port),
|
||||||
timeout(t.timeout),
|
timeout(t.timeout),
|
||||||
@@ -86,13 +91,13 @@ protected:
|
|||||||
interval(interval)
|
interval(interval)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
inline bool operator==(TargetHost& t) {
|
inline bool operator==(const TargetHost& t) {
|
||||||
if (host != t.host) return false;
|
if (host != t.host) return false;
|
||||||
if (port != t.port) return false;
|
if (port != t.port) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator!=(TargetHost& t) {
|
inline bool operator!=(const TargetHost& t) {
|
||||||
if (host != t.host) return true;
|
if (host != t.host) return true;
|
||||||
if (port != t.port) return true;
|
if (port != t.port) return true;
|
||||||
return false;
|
return false;
|
||||||
@@ -135,7 +140,7 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint8_t headRoom[6]; // Buffer to hold MSB-first TCP header
|
uint8_t headRoom[6] = {0,0,0,0,0,0}; // Buffer to hold MSB-first TCP header
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RequestEntry {
|
struct RequestEntry {
|
||||||
@@ -144,7 +149,7 @@ protected:
|
|||||||
TargetHost target;
|
TargetHost target;
|
||||||
ModbusTCPhead head;
|
ModbusTCPhead head;
|
||||||
bool isSyncRequest;
|
bool isSyncRequest;
|
||||||
RequestEntry(uint32_t t, ModbusMessage m, TargetHost tg, bool syncReq = false) :
|
RequestEntry(uint32_t t, const ModbusMessage& m, TargetHost tg, bool syncReq = false) :
|
||||||
token(t),
|
token(t),
|
||||||
msg(m),
|
msg(m),
|
||||||
target(tg),
|
target(tg),
|
||||||
@@ -153,8 +158,8 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Base addRequest and syncRequest must be present
|
// Base addRequest and syncRequest must be present
|
||||||
Error addRequestM(ModbusMessage msg, uint32_t token);
|
Error addRequestM(ModbusMessage msg, uint32_t token) override;
|
||||||
ModbusMessage syncRequestM(ModbusMessage msg, uint32_t token);
|
ModbusMessage syncRequestM(ModbusMessage msg, uint32_t token) override;
|
||||||
// TCP-specific addition "...MT()" including adhoc target - used by bridge
|
// TCP-specific addition "...MT()" including adhoc target - used by bridge
|
||||||
Error addRequestMT(ModbusMessage msg, uint32_t token, IPAddress targetHost, uint16_t targetPort);
|
Error addRequestMT(ModbusMessage msg, uint32_t token, IPAddress targetHost, uint16_t targetPort);
|
||||||
ModbusMessage syncRequestMT(ModbusMessage msg, uint32_t token, IPAddress targetHost, uint16_t targetPort);
|
ModbusMessage syncRequestMT(ModbusMessage msg, uint32_t token, IPAddress targetHost, uint16_t targetPort);
|
||||||
@@ -174,7 +179,6 @@ protected:
|
|||||||
// receive: get response via Client connection
|
// receive: get response via Client connection
|
||||||
ModbusMessage receive(RequestEntry *request);
|
ModbusMessage receive(RequestEntry *request);
|
||||||
|
|
||||||
void isInstance() { return; } // make class instantiable
|
|
||||||
queue<RequestEntry *> requests; // Queue to hold requests to be processed
|
queue<RequestEntry *> requests; // Queue to hold requests to be processed
|
||||||
#if USE_MUTEX
|
#if USE_MUTEX
|
||||||
mutex qLock; // Mutex to protect queue
|
mutex qLock; // Mutex to protect queue
|
||||||
@@ -185,6 +189,8 @@ protected:
|
|||||||
uint32_t MT_defaultTimeout; // Standard timeout value taken if no dedicated was set
|
uint32_t MT_defaultTimeout; // Standard timeout value taken if no dedicated was set
|
||||||
uint32_t MT_defaultInterval; // Standard interval value taken if no dedicated was set
|
uint32_t MT_defaultInterval; // Standard interval value taken if no dedicated was set
|
||||||
uint16_t MT_qLimit; // Maximum number of requests to accept in queue
|
uint16_t MT_qLimit; // Maximum number of requests to accept in queue
|
||||||
|
uint8_t MT_timeoutsToClose; // 0: disregard, 1-255: number of timeouts to tolerate before
|
||||||
|
// forcibly closing a connection.
|
||||||
|
|
||||||
// Let any ModbusBridge class use protected members
|
// Let any ModbusBridge class use protected members
|
||||||
template<typename SERVERCLASS> friend class ModbusBridge;
|
template<typename SERVERCLASS> friend class ModbusBridge;
|
||||||
|
|||||||
@@ -223,19 +223,17 @@ void onAck(size_t len, uint32_t time) {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
void ModbusClientTCPasync::onPacket(uint8_t* data, size_t length) {
|
void ModbusClientTCPasync::onPacket(uint8_t* data, size_t length) {
|
||||||
LOG_D("packet received (len:%d)\n", length);
|
LOG_D("packet received (len:%u)\n", length);
|
||||||
// reset idle timeout
|
// reset idle timeout
|
||||||
MTA_lastActivity = millis();
|
MTA_lastActivity = millis();
|
||||||
|
|
||||||
if (length) {
|
if (length) {
|
||||||
LOG_D("parsing (len:%d)\n", length + 1);
|
LOG_D("parsing (len:%u)\n", length + 1);
|
||||||
}
|
}
|
||||||
while (length > 0) {
|
while (length > 0) {
|
||||||
RequestEntry* request = nullptr;
|
RequestEntry* request = nullptr;
|
||||||
ModbusMessage* response = nullptr;
|
ModbusMessage* response = nullptr;
|
||||||
uint16_t transactionID = 0;
|
uint16_t transactionID = 0;
|
||||||
uint16_t protocolID = 0;
|
|
||||||
uint16_t messageLength = 0;
|
|
||||||
bool isOkay = false;
|
bool isOkay = false;
|
||||||
|
|
||||||
// 1. Check for valid modbus message
|
// 1. Check for valid modbus message
|
||||||
@@ -244,8 +242,8 @@ void ModbusClientTCPasync::onPacket(uint8_t* data, size_t length) {
|
|||||||
// total message should fit MBAP plus remaining bytes (in data[4], data[5])
|
// total message should fit MBAP plus remaining bytes (in data[4], data[5])
|
||||||
if (length > 6) {
|
if (length > 6) {
|
||||||
transactionID = (data[0] << 8) | data[1];
|
transactionID = (data[0] << 8) | data[1];
|
||||||
protocolID = (data[2] << 8) | data[3];
|
uint16_t protocolID = (data[2] << 8) | data[3];
|
||||||
messageLength = (data[4] << 8) | data[5];
|
uint16_t messageLength = (data[4] << 8) | data[5];
|
||||||
if (protocolID == 0 &&
|
if (protocolID == 0 &&
|
||||||
length >= (uint32_t)messageLength + 6 &&
|
length >= (uint32_t)messageLength + 6 &&
|
||||||
messageLength < 256) {
|
messageLength < 256) {
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ protected:
|
|||||||
return headRoom;
|
return headRoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ModbusTCPhead& operator= (ModbusTCPhead& t) {
|
inline ModbusTCPhead& operator= (const ModbusTCPhead& t) {
|
||||||
transactionID = t.transactionID;
|
transactionID = t.transactionID;
|
||||||
protocolID = t.protocolID;
|
protocolID = t.protocolID;
|
||||||
len = t.len;
|
len = t.len;
|
||||||
@@ -91,7 +91,7 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint8_t headRoom[6]; // Buffer to hold MSB-first TCP header
|
uint8_t headRoom[6] = {0,0,0,0,0,0}; // Buffer to hold MSB-first TCP header
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RequestEntry {
|
struct RequestEntry {
|
||||||
@@ -100,7 +100,7 @@ protected:
|
|||||||
ModbusTCPhead head;
|
ModbusTCPhead head;
|
||||||
uint32_t sentTime;
|
uint32_t sentTime;
|
||||||
bool isSyncRequest;
|
bool isSyncRequest;
|
||||||
RequestEntry(uint32_t t, ModbusMessage m, bool syncReq = false) :
|
RequestEntry(uint32_t t, const ModbusMessage& m, bool syncReq = false) :
|
||||||
token(t),
|
token(t),
|
||||||
msg(m),
|
msg(m),
|
||||||
head(ModbusTCPhead()),
|
head(ModbusTCPhead()),
|
||||||
@@ -109,8 +109,8 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Base addRequest and syncRequest both must be present
|
// Base addRequest and syncRequest both must be present
|
||||||
Error addRequestM(ModbusMessage msg, uint32_t token);
|
Error addRequestM(ModbusMessage msg, uint32_t token) override;
|
||||||
ModbusMessage syncRequestM(ModbusMessage msg, uint32_t token);
|
ModbusMessage syncRequestM(ModbusMessage msg, uint32_t token) override;
|
||||||
|
|
||||||
// addToQueue: send freshly created request to queue
|
// addToQueue: send freshly created request to queue
|
||||||
bool addToQueue(int32_t token, ModbusMessage request, bool syncReq = false);
|
bool addToQueue(int32_t token, ModbusMessage request, bool syncReq = false);
|
||||||
@@ -121,8 +121,6 @@ protected:
|
|||||||
// receive: get response via Client connection
|
// receive: get response via Client connection
|
||||||
// TCPResponse* receive(uint8_t* data, size_t length);
|
// TCPResponse* receive(uint8_t* data, size_t length);
|
||||||
|
|
||||||
void isInstance() { return; } // make class instantiable
|
|
||||||
|
|
||||||
// TCP handling code, all static taking a class instancs as param
|
// TCP handling code, all static taking a class instancs as param
|
||||||
void onConnected();
|
void onConnected();
|
||||||
void onDisconnected();
|
void onDisconnected();
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#undef LOCAL_LOG_LEVEL
|
#undef LOCAL_LOG_LEVEL
|
||||||
// #define LOCAL_LOG_LEVEL LOG_LEVEL_ERROR
|
// #define LOCAL_LOG_LEVEL LOG_LEVEL_ERROR
|
||||||
#include "Logging.h"
|
#include "Logging.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
// Default Constructor - takes optional size of MM_data to allocate memory
|
// Default Constructor - takes optional size of MM_data to allocate memory
|
||||||
ModbusMessage::ModbusMessage(uint16_t dataLen) {
|
ModbusMessage::ModbusMessage(uint16_t dataLen) {
|
||||||
@@ -146,21 +147,19 @@ void ModbusMessage::setServerID(uint8_t serverID) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ModbusMessage::setFunctionCode(uint8_t FC) {
|
void ModbusMessage::setFunctionCode(uint8_t FC) {
|
||||||
// We accept here that [0], [1] may allocate bytes!
|
if (MM_data.size() < 2) {
|
||||||
if (MM_data.empty()) {
|
MM_data.resize(2); // Resize to at least 2 to ensure indices 0 and 1 are valid
|
||||||
MM_data.reserve(3); // At least an error message should fit
|
MM_data[0] = 0; // Optional: Invalid server ID as a placeholder
|
||||||
}
|
}
|
||||||
// No serverID set yet? use a 0 to initialize it to an error-generating value
|
MM_data[1] = FC; // Safely set the function code
|
||||||
if (MM_data.size() < 2) MM_data[0] = 0; // intentional invalid server ID!
|
|
||||||
MM_data[1] = FC;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add() variant to copy a buffer into MM_data. Returns updated size
|
// add() variant to copy a buffer into MM_data. Returns updated size
|
||||||
uint16_t ModbusMessage::add(const uint8_t *arrayOfBytes, uint16_t count) {
|
uint16_t ModbusMessage::add(const uint8_t *arrayOfBytes, uint16_t count) {
|
||||||
|
uint16_t originalSize = MM_data.size();
|
||||||
|
MM_data.resize(originalSize + count);
|
||||||
// Copy it
|
// Copy it
|
||||||
while (count--) {
|
std::copy(arrayOfBytes, arrayOfBytes + count, MM_data.begin() + originalSize);
|
||||||
MM_data.push_back(*arrayOfBytes++);
|
|
||||||
}
|
|
||||||
// Return updated size (logical length of message so far)
|
// Return updated size (logical length of message so far)
|
||||||
return MM_data.size();
|
return MM_data.size();
|
||||||
}
|
}
|
||||||
@@ -181,7 +180,7 @@ uint8_t ModbusMessage::determineFloatOrder() {
|
|||||||
uint32_t i = 77230; // int value to go into a float without rounding error
|
uint32_t i = 77230; // int value to go into a float without rounding error
|
||||||
float f = i; // assign it
|
float f = i; // assign it
|
||||||
uint8_t *b = (uint8_t *)&f; // Pointer to bytes of f
|
uint8_t *b = (uint8_t *)&f; // Pointer to bytes of f
|
||||||
uint8_t expect[floatSize] = { 0x47, 0x96, 0xd7, 0x00 }; // IEEE754 representation
|
const uint8_t expect[floatSize] = { 0x47, 0x96, 0xd7, 0x00 }; // IEEE754 representation
|
||||||
uint8_t matches = 0; // number of bytes successfully matched
|
uint8_t matches = 0; // number of bytes successfully matched
|
||||||
|
|
||||||
// Loop over the bytes of the expected sequence
|
// Loop over the bytes of the expected sequence
|
||||||
@@ -225,7 +224,7 @@ uint8_t ModbusMessage::determineDoubleOrder() {
|
|||||||
uint64_t i = 5791007487489389; // int64 value to go into a double without rounding error
|
uint64_t i = 5791007487489389; // int64 value to go into a double without rounding error
|
||||||
double f = i; // assign it
|
double f = i; // assign it
|
||||||
uint8_t *b = (uint8_t *)&f; // Pointer to bytes of f
|
uint8_t *b = (uint8_t *)&f; // Pointer to bytes of f
|
||||||
uint8_t expect[doubleSize] = { 0x43, 0x34, 0x92, 0xE4, 0x00, 0x2E, 0xF5, 0x6D }; // IEEE754 representation
|
const uint8_t expect[doubleSize] = { 0x43, 0x34, 0x92, 0xE4, 0x00, 0x2E, 0xF5, 0x6D }; // IEEE754 representation
|
||||||
uint8_t matches = 0; // number of bytes successfully matched
|
uint8_t matches = 0; // number of bytes successfully matched
|
||||||
|
|
||||||
// Loop over the bytes of the expected sequence
|
// Loop over the bytes of the expected sequence
|
||||||
@@ -306,10 +305,7 @@ double ModbusMessage::swapDouble(double& f, int swapRule) {
|
|||||||
|
|
||||||
// add() variant for a vector of uint8_t
|
// add() variant for a vector of uint8_t
|
||||||
uint16_t ModbusMessage::add(vector<uint8_t> v) {
|
uint16_t ModbusMessage::add(vector<uint8_t> v) {
|
||||||
for (auto& b: v) {
|
return add(v.data(), v.size());
|
||||||
MM_data.push_back(b);
|
|
||||||
}
|
|
||||||
return MM_data.size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add() variants for float and double values
|
// add() variants for float and double values
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ MBSworker ModbusServer::getWorker(uint8_t serverID, uint8_t functionCode) {
|
|||||||
svmap = workerMap.find(ANY_SERVER);
|
svmap = workerMap.find(ANY_SERVER);
|
||||||
if (svmap != workerMap.end()) {
|
if (svmap != workerMap.end()) {
|
||||||
serverFound = true;
|
serverFound = true;
|
||||||
serverID = ANY_SERVER;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Did we find a serverID?
|
// Did we find a serverID?
|
||||||
@@ -49,7 +48,6 @@ MBSworker ModbusServer::getWorker(uint8_t serverID, uint8_t functionCode) {
|
|||||||
if (fcmap != svmap->second.end()) {
|
if (fcmap != svmap->second.end()) {
|
||||||
// Yes. Return the function pointer for it.
|
// Yes. Return the function pointer for it.
|
||||||
functionCodeFound = true;
|
functionCodeFound = true;
|
||||||
functionCode = ANY_FUNCTION_CODE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (functionCodeFound) {
|
if (functionCodeFound) {
|
||||||
@@ -104,6 +102,11 @@ bool ModbusServer::isServerFor(uint8_t serverID) {
|
|||||||
// Is there one?
|
// Is there one?
|
||||||
if (svmap != workerMap.end()) {
|
if (svmap != workerMap.end()) {
|
||||||
return true;
|
return true;
|
||||||
|
} else {
|
||||||
|
svmap = workerMap.find(ANY_SERVER);
|
||||||
|
if (svmap != workerMap.end()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,15 +68,12 @@ protected:
|
|||||||
ModbusServer();
|
ModbusServer();
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
~ModbusServer();
|
virtual ~ModbusServer();
|
||||||
|
|
||||||
// Prevent copy construction or assignment
|
// Prevent copy construction or assignment
|
||||||
ModbusServer(ModbusServer& other) = delete;
|
ModbusServer(ModbusServer& other) = delete;
|
||||||
ModbusServer& operator=(ModbusServer& other) = delete;
|
ModbusServer& operator=(ModbusServer& other) = delete;
|
||||||
|
|
||||||
// Virtual function to prevent this class being instantiated
|
|
||||||
virtual void isInstance() = 0;
|
|
||||||
|
|
||||||
std::map<uint8_t, std::map<uint8_t, MBSworker>> workerMap; // map on serverID->functionCode->worker function
|
std::map<uint8_t, std::map<uint8_t, MBSworker>> workerMap; // map on serverID->functionCode->worker function
|
||||||
uint32_t messageCount; // Number of Requests processed
|
uint32_t messageCount; // Number of Requests processed
|
||||||
uint32_t errorCount; // Number of errors responded
|
uint32_t errorCount; // Number of errors responded
|
||||||
|
|||||||
@@ -15,8 +15,8 @@
|
|||||||
// Create own non-virtual EthernetServer class
|
// Create own non-virtual EthernetServer class
|
||||||
class EthernetServerEM : public EthernetServer {
|
class EthernetServerEM : public EthernetServer {
|
||||||
public:
|
public:
|
||||||
EthernetServerEM(uint16_t port) : EthernetServer(port) { }
|
explicit EthernetServerEM(uint16_t port) : EthernetServer(port) { }
|
||||||
void begin(uint16_t port = 0) { }
|
void begin(uint16_t port = 0) override { }
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "ModbusServerTCPtemp.h"
|
#include "ModbusServerTCPtemp.h"
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ void ModbusServerRTU::doBegin(uint32_t baudRate, int coreID, uint32_t userInterv
|
|||||||
snprintf(taskName, 18, "MBsrv%02XRTU", instanceCounter);
|
snprintf(taskName, 18, "MBsrv%02XRTU", instanceCounter);
|
||||||
|
|
||||||
// Start task to handle the client
|
// Start task to handle the client
|
||||||
xTaskCreatePinnedToCore((TaskFunction_t)&serve, taskName, SERVER_TASK_STACK, this, 8, &serverTask, coreID >= 0 ? coreID : NULL);
|
xTaskCreatePinnedToCore((TaskFunction_t)&serve, taskName, SERVER_TASK_STACK, this, 8, &serverTask, coreID >= 0 ? coreID : tskNO_AFFINITY);
|
||||||
|
|
||||||
LOG_D("Server task %d started. Interval=%d\n", (uint32_t)serverTask, MSRinterval);
|
LOG_D("Server task %d started. Interval=%d\n", (uint32_t)serverTask, MSRinterval);
|
||||||
}
|
}
|
||||||
@@ -126,6 +126,12 @@ bool ModbusServerRTU::isModbusASCII() {
|
|||||||
return MSRuseASCII;
|
return MSRuseASCII;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set timeout
|
||||||
|
void ModbusServerRTU::setModbusTimeout(unsigned long timeout)
|
||||||
|
{
|
||||||
|
serverTimeout = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
// Toggle skipping of leading 0x00 byte
|
// Toggle skipping of leading 0x00 byte
|
||||||
void ModbusServerRTU::skipLeading0x00(bool onOff) {
|
void ModbusServerRTU::skipLeading0x00(bool onOff) {
|
||||||
MSRskipLeadingZeroByte = onOff;
|
MSRskipLeadingZeroByte = onOff;
|
||||||
@@ -231,8 +237,8 @@ void ModbusServerRTU::serve(ModbusServerRTU *myServer) {
|
|||||||
response = m;
|
response = m;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// No callback. Is at least the serverID valid and no broadcast?
|
// No callback. Is at least the serverID valid?
|
||||||
if (myServer->isServerFor(request[0]) && request[0] != 0x00) {
|
if (myServer->isServerFor(request[0])) {
|
||||||
// Yes. Send back a ILLEGAL_FUNCTION error
|
// Yes. Send back a ILLEGAL_FUNCTION error
|
||||||
response.setError(request.getServerID(), request.getFunctionCode(), ILLEGAL_FUNCTION);
|
response.setError(request.getServerID(), request.getFunctionCode(), ILLEGAL_FUNCTION);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,9 @@ public:
|
|||||||
// Inquire protocol mode
|
// Inquire protocol mode
|
||||||
bool isModbusASCII();
|
bool isModbusASCII();
|
||||||
|
|
||||||
|
// set timeout
|
||||||
|
void setModbusTimeout(unsigned long timeout);
|
||||||
|
|
||||||
// Toggle skipping of leading 0x00 byte
|
// Toggle skipping of leading 0x00 byte
|
||||||
void skipLeading0x00(bool onOff = true);
|
void skipLeading0x00(bool onOff = true);
|
||||||
|
|
||||||
@@ -61,8 +64,6 @@ protected:
|
|||||||
ModbusServerRTU(ModbusServerRTU& m) = delete;
|
ModbusServerRTU(ModbusServerRTU& m) = delete;
|
||||||
ModbusServerRTU& operator=(ModbusServerRTU& m) = delete;
|
ModbusServerRTU& operator=(ModbusServerRTU& m) = delete;
|
||||||
|
|
||||||
inline void isInstance() { } // Make class instantiable
|
|
||||||
|
|
||||||
// internal common begin function
|
// internal common begin function
|
||||||
void doBegin(uint32_t baudRate, int coreID, uint32_t userInterval);
|
void doBegin(uint32_t baudRate, int coreID, uint32_t userInterval);
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ ModbusServerTCPasync::mb_client::~mb_client() {
|
|||||||
|
|
||||||
void ModbusServerTCPasync::mb_client::onData(uint8_t* data, size_t len) {
|
void ModbusServerTCPasync::mb_client::onData(uint8_t* data, size_t len) {
|
||||||
lastActiveTime = millis();
|
lastActiveTime = millis();
|
||||||
LOG_D("data len %d\n", len);
|
LOG_D("data len %u\n", len);
|
||||||
|
|
||||||
Error error = SUCCESS;
|
Error error = SUCCESS;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
@@ -250,7 +250,7 @@ void ModbusServerTCPasync::onClientConnect(AsyncClient* client) {
|
|||||||
LOCK_GUARD(lock1, cListLock);
|
LOCK_GUARD(lock1, cListLock);
|
||||||
if (clients.size() < maxNoClients) {
|
if (clients.size() < maxNoClients) {
|
||||||
clients.emplace_back(new mb_client(this, client));
|
clients.emplace_back(new mb_client(this, client));
|
||||||
LOG_D("nr clients: %d\n", clients.size());
|
LOG_D("nr clients: %u\n", clients.size());
|
||||||
} else {
|
} else {
|
||||||
LOG_D("max number of clients reached, closing new\n");
|
LOG_D("max number of clients reached, closing new\n");
|
||||||
client->close(true);
|
client->close(true);
|
||||||
@@ -264,5 +264,5 @@ void ModbusServerTCPasync::onClientDisconnect(mb_client* client) {
|
|||||||
clients.remove_if([client](mb_client* i) { return i->client == client->client; });
|
clients.remove_if([client](mb_client* i) { return i->client == client->client; });
|
||||||
// delete client itself
|
// delete client itself
|
||||||
delete client;
|
delete client;
|
||||||
LOG_D("nr clients: %d\n", clients.size());
|
LOG_D("nr clients: %u\n", clients.size());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,6 @@ class ModbusServerTCPasync : public ModbusServer {
|
|||||||
bool isRunning();
|
bool isRunning();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
inline void isInstance() { }
|
|
||||||
void onClientConnect(AsyncClient* client);
|
void onClientConnect(AsyncClient* client);
|
||||||
void onClientDisconnect(mb_client* client);
|
void onClientDisconnect(mb_client* client);
|
||||||
|
|
||||||
|
|||||||
@@ -44,8 +44,6 @@ protected:
|
|||||||
ModbusServerTCP(ModbusServerTCP& m) = delete;
|
ModbusServerTCP(ModbusServerTCP& m) = delete;
|
||||||
ModbusServerTCP& operator=(ModbusServerTCP& m) = delete;
|
ModbusServerTCP& operator=(ModbusServerTCP& m) = delete;
|
||||||
|
|
||||||
inline void isInstance() { }
|
|
||||||
|
|
||||||
uint8_t numClients;
|
uint8_t numClients;
|
||||||
TaskHandle_t serverTask;
|
TaskHandle_t serverTask;
|
||||||
uint16_t serverPort;
|
uint16_t serverPort;
|
||||||
@@ -159,7 +157,7 @@ template <typename ST, typename CT>
|
|||||||
snprintf(taskName, 18, "MBserve%04X", port);
|
snprintf(taskName, 18, "MBserve%04X", port);
|
||||||
|
|
||||||
// Start task to handle the client
|
// Start task to handle the client
|
||||||
xTaskCreatePinnedToCore((TaskFunction_t)&serve, taskName, SERVER_TASK_STACK, this, 5, &serverTask, coreID >= 0 ? coreID : NULL);
|
xTaskCreatePinnedToCore((TaskFunction_t)&serve, taskName, SERVER_TASK_STACK, this, 5, &serverTask, coreID >= 0 ? coreID : tskNO_AFFINITY);
|
||||||
LOG_D("Server task %s started (%d).\n", taskName, (uint32_t)serverTask);
|
LOG_D("Server task %s started (%d).\n", taskName, (uint32_t)serverTask);
|
||||||
|
|
||||||
// Wait two seconds for it to establish
|
// Wait two seconds for it to establish
|
||||||
@@ -206,7 +204,7 @@ bool ModbusServerTCP<ST, CT>::accept(CT& client, uint32_t timeout, int coreID) {
|
|||||||
snprintf(taskName, 18, "MBsrv%02Xclnt", i);
|
snprintf(taskName, 18, "MBsrv%02Xclnt", i);
|
||||||
|
|
||||||
// Start task to handle the client
|
// Start task to handle the client
|
||||||
xTaskCreatePinnedToCore((TaskFunction_t)&worker, taskName, SERVER_TASK_STACK, clients[i], 5, &clients[i]->task, coreID >= 0 ? coreID : NULL);
|
xTaskCreatePinnedToCore((TaskFunction_t)&worker, taskName, SERVER_TASK_STACK, clients[i], 5, &clients[i]->task, coreID >= 0 ? coreID : tskNO_AFFINITY);
|
||||||
LOG_D("Started client %d task %d\n", i, (uint32_t)(clients[i]->task));
|
LOG_D("Started client %d task %d\n", i, (uint32_t)(clients[i]->task));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -109,8 +109,8 @@ const uint8_t swapTables[8][8] = {
|
|||||||
enum FCType : uint8_t {
|
enum FCType : uint8_t {
|
||||||
FC01_TYPE, // Two uint16_t parameters (FC 0x01, 0x02, 0x03, 0x04, 0x05, 0x06)
|
FC01_TYPE, // Two uint16_t parameters (FC 0x01, 0x02, 0x03, 0x04, 0x05, 0x06)
|
||||||
FC07_TYPE, // no additional parameter (FCs 0x07, 0x0b, 0x0c, 0x11)
|
FC07_TYPE, // no additional parameter (FCs 0x07, 0x0b, 0x0c, 0x11)
|
||||||
FC0F_TYPE, // two uint16_t parameters, a uint8_t length byte and a uint16_t* pointer to array of bytes (FC 0x0f)
|
FC0F_TYPE, // two uint16_t parameters, a uint8_t length byte and a uint8_t* pointer to array of bytes (FC 0x0f)
|
||||||
FC10_TYPE, // two uint16_t parameters, a uint8_t length byte and a uint8_t* pointer to array of words (FC 0x10)
|
FC10_TYPE, // two uint16_t parameters, a uint8_t length byte and a uint16_t* pointer to array of words (FC 0x10)
|
||||||
FC16_TYPE, // three uint16_t parameters (FC 0x16)
|
FC16_TYPE, // three uint16_t parameters (FC 0x16)
|
||||||
FC18_TYPE, // one uint16_t parameter (FC 0x18)
|
FC18_TYPE, // one uint16_t parameter (FC 0x18)
|
||||||
FCGENERIC, // for FCs not yet explicitly coded (or too complex)
|
FCGENERIC, // for FCs not yet explicitly coded (or too complex)
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
// MIT license - see license.md for details
|
// MIT license - see license.md for details
|
||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
#if HAS_FREERTOS
|
||||||
#include "ModbusMessage.h"
|
#include "ModbusMessage.h"
|
||||||
#include "RTUutils.h"
|
#include "RTUutils.h"
|
||||||
#undef LOCAL_LOG_LEVEL
|
#undef LOCAL_LOG_LEVEL
|
||||||
// #define LOCAL_LOG_LEVEL LOG_LEVEL_VERBOSE
|
// #define LOCAL_LOG_LEVEL LOG_LEVEL_VERBOSE
|
||||||
#include "Logging.h"
|
#include "Logging.h"
|
||||||
|
|
||||||
#if HAS_FREERTOS
|
|
||||||
// calcCRC: calculate Modbus CRC16 on a given array of bytes
|
// calcCRC: calculate Modbus CRC16 on a given array of bytes
|
||||||
uint16_t RTUutils::calcCRC(const uint8_t *data, uint16_t len) {
|
uint16_t RTUutils::calcCRC(const uint8_t *data, uint16_t len) {
|
||||||
// CRC16 pre-calculated tables
|
// CRC16 pre-calculated tables
|
||||||
@@ -57,10 +57,9 @@ uint16_t RTUutils::calcCRC(const uint8_t *data, uint16_t len) {
|
|||||||
|
|
||||||
uint8_t crcHi = 0xFF;
|
uint8_t crcHi = 0xFF;
|
||||||
uint8_t crcLo = 0xFF;
|
uint8_t crcLo = 0xFF;
|
||||||
uint8_t index;
|
|
||||||
|
|
||||||
while (len--) {
|
while (len--) {
|
||||||
index = crcLo ^ *data++;
|
uint8_t index = crcLo ^ *data++;
|
||||||
crcLo = crcHi ^ crcHiTable[index];
|
crcLo = crcHi ^ crcHiTable[index];
|
||||||
crcHi = crcLoTable[index];
|
crcHi = crcLoTable[index];
|
||||||
}
|
}
|
||||||
@@ -464,4 +463,5 @@ const char RTUutils::ASCIIread[] = {
|
|||||||
const char RTUutils::ASCIIwrite[] = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
const char RTUutils::ASCIIwrite[] = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||||
0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46
|
0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -5,9 +5,6 @@
|
|||||||
#ifndef _RTU_UTILS_H
|
#ifndef _RTU_UTILS_H
|
||||||
#define _RTU_UTILS_H
|
#define _RTU_UTILS_H
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#if NEED_UART_PATCH
|
|
||||||
#include <soc/uart_struct.h>
|
|
||||||
#endif
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "Stream.h"
|
#include "Stream.h"
|
||||||
#include "ModbusTypeDefs.h"
|
#include "ModbusTypeDefs.h"
|
||||||
@@ -52,11 +49,13 @@ public:
|
|||||||
// RTSauto: dummy callback for auto half duplex RS485 boards
|
// RTSauto: dummy callback for auto half duplex RS485 boards
|
||||||
inline static void RTSauto(bool level) { return; } // NOLINT
|
inline static void RTSauto(bool level) { return; } // NOLINT
|
||||||
|
|
||||||
|
#if HAS_FREERTOS
|
||||||
// Necessary preparations for a HardwareSerial
|
// Necessary preparations for a HardwareSerial
|
||||||
static void prepareHardwareSerial(HardwareSerial& s, uint16_t bufferSize = 260) {
|
static void prepareHardwareSerial(HardwareSerial& s, uint16_t bufferSize = 260) {
|
||||||
s.setRxBufferSize(bufferSize);
|
s.setRxBufferSize(bufferSize);
|
||||||
s.setTxBufferSize(bufferSize);
|
s.setTxBufferSize(bufferSize);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Printable characters for ASCII protocol: 012345678ABCDEF
|
// Printable characters for ASCII protocol: 012345678ABCDEF
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
#define HAS_FREERTOS 1
|
#define HAS_FREERTOS 1
|
||||||
#define HAS_ETHERNET 1
|
#define HAS_ETHERNET 1
|
||||||
#define IS_LINUX 0
|
#define IS_LINUX 0
|
||||||
#define NEED_UART_PATCH 1
|
|
||||||
const unsigned int SERVER_TASK_STACK = 4096;
|
const unsigned int SERVER_TASK_STACK = 4096;
|
||||||
const unsigned int CLIENT_TASK_STACK = 4096;
|
const unsigned int CLIENT_TASK_STACK = 4096;
|
||||||
|
|
||||||
@@ -23,7 +22,6 @@ const unsigned int CLIENT_TASK_STACK = 4096;
|
|||||||
#define HAS_FREERTOS 0
|
#define HAS_FREERTOS 0
|
||||||
#define HAS_ETHERNET 0
|
#define HAS_ETHERNET 0
|
||||||
#define IS_LINUX 0
|
#define IS_LINUX 0
|
||||||
#define NEED_UART_PATCH 0
|
|
||||||
|
|
||||||
/* === LINUX DEFINITIONS AND MACROS === */
|
/* === LINUX DEFINITIONS AND MACROS === */
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
@@ -31,7 +29,6 @@ const unsigned int CLIENT_TASK_STACK = 4096;
|
|||||||
#define HAS_FREERTOS 0
|
#define HAS_FREERTOS 0
|
||||||
#define HAS_ETHERNET 0
|
#define HAS_ETHERNET 0
|
||||||
#define IS_LINUX 1
|
#define IS_LINUX 1
|
||||||
#define NEED_UART_PATCH 0
|
|
||||||
#include <cstdio> // for printf()
|
#include <cstdio> // for printf()
|
||||||
#include <cstring> // for memcpy(), strlen() etc.
|
#include <cstring> // for memcpy(), strlen() etc.
|
||||||
#include <cinttypes> // for uint32_t etc.
|
#include <cinttypes> // for uint32_t etc.
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ MqttClient::MqttClient(espMqttClientTypes::UseInternalTask useInternalTask, uint
|
|||||||
|
|
||||||
MqttClient::~MqttClient() {
|
MqttClient::~MqttClient() {
|
||||||
disconnect(true);
|
disconnect(true);
|
||||||
_clearQueue(2);
|
clearQueue(true);
|
||||||
#if defined(ARDUINO_ARCH_ESP32)
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
vSemaphoreDelete(_xSemaphore);
|
vSemaphoreDelete(_xSemaphore);
|
||||||
if (_useInternalTask == espMqttClientTypes::UseInternalTask::YES) {
|
if (_useInternalTask == espMqttClientTypes::UseInternalTask::YES) {
|
||||||
|
|||||||
@@ -106,7 +106,15 @@ void Shell::output_logs() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
print(uuid::log::format_timestamp_ms(message.content_->uptime_ms, 3));
|
time_t offset = time(nullptr) - uuid::get_uptime_sec();
|
||||||
|
if (offset < 1500000000L) {
|
||||||
|
print(uuid::log::format_timestamp_ms(message.content_->uptime_ms, 3));
|
||||||
|
} else {
|
||||||
|
time_t t1 = offset + (time_t)(message.content_->uptime_ms / 1000);
|
||||||
|
char timestr[25];
|
||||||
|
strftime(timestr, 25, "%FT%T", localtime(&t1));
|
||||||
|
printf("%s.%03d", timestr, (uint16_t)(message.content_->uptime_ms % 1000));
|
||||||
|
}
|
||||||
printf(" %c %lu: [%s] ", uuid::log::format_level_char(message.content_->level), message.id_, message.content_->name);
|
printf(" %c %lu: [%s] ", uuid::log::format_level_char(message.content_->level), message.id_, message.content_->name);
|
||||||
|
|
||||||
if ((message.content_->level == uuid::log::Level::ERR) || (message.content_->level == uuid::log::Level::WARNING)) {
|
if ((message.content_->level == uuid::log::Level::ERR) || (message.content_->level == uuid::log::Level::WARNING)) {
|
||||||
|
|||||||
@@ -122,7 +122,6 @@ void SyslogService::remove_queued_messages(uuid::log::Level level) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log_message_id_ -= offset;
|
log_message_id_ -= offset;
|
||||||
log_message_fails_ += offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyslogService::log_level(uuid::log::Level level) {
|
void SyslogService::log_level(uuid::log::Level level) {
|
||||||
|
|||||||
@@ -147,5 +147,6 @@ double ledcSetup(uint8_t chan, double freq, uint8_t bit_num) {
|
|||||||
void ledcAttachPin(uint8_t pin, uint8_t chan) {};
|
void ledcAttachPin(uint8_t pin, uint8_t chan) {};
|
||||||
void ledcWrite(uint8_t chan, uint32_t duty) {};
|
void ledcWrite(uint8_t chan, uint32_t duty) {};
|
||||||
void neopixelWrite(uint8_t pin, uint8_t red_val, uint8_t green_val, uint8_t blue_val) {};
|
void neopixelWrite(uint8_t pin, uint8_t red_val, uint8_t green_val, uint8_t blue_val) {};
|
||||||
|
void rgbLedWrite(uint8_t pin, uint8_t red_val, uint8_t green_val, uint8_t blue_val) {};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -72,6 +72,7 @@ double ledcSetup(uint8_t chan, double freq, uint8_t bit_num);
|
|||||||
void ledcAttachPin(uint8_t pin, uint8_t chan);
|
void ledcAttachPin(uint8_t pin, uint8_t chan);
|
||||||
void ledcWrite(uint8_t chan, uint32_t duty);
|
void ledcWrite(uint8_t chan, uint32_t duty);
|
||||||
void neopixelWrite(uint8_t pin, uint8_t red_val, uint8_t green_val, uint8_t blue_val);
|
void neopixelWrite(uint8_t pin, uint8_t red_val, uint8_t green_val, uint8_t blue_val);
|
||||||
|
void rgbLedWrite(uint8_t pin, uint8_t red_val, uint8_t green_val, uint8_t blue_val);
|
||||||
|
|
||||||
#define PROGMEM
|
#define PROGMEM
|
||||||
#define PGM_P const char *
|
#define PGM_P const char *
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -75,8 +75,8 @@ class DummySettings {
|
|||||||
uint8_t provisionMode = 0;
|
uint8_t provisionMode = 0;
|
||||||
uint32_t publish_time_water = 0;
|
uint32_t publish_time_water = 0;
|
||||||
|
|
||||||
static void read(DummySettings & settings, JsonObject root) {};
|
static void read(DummySettings & settings, JsonObject root){};
|
||||||
static void read(DummySettings & settings) {};
|
static void read(DummySettings & settings){};
|
||||||
|
|
||||||
static StateUpdateResult update(JsonObject root, DummySettings & settings) {
|
static StateUpdateResult update(JsonObject root, DummySettings & settings) {
|
||||||
return StateUpdateResult::CHANGED;
|
return StateUpdateResult::CHANGED;
|
||||||
@@ -85,7 +85,7 @@ class DummySettings {
|
|||||||
|
|
||||||
class DummySettingsService : public StatefulService<DummySettings> {
|
class DummySettingsService : public StatefulService<DummySettings> {
|
||||||
public:
|
public:
|
||||||
DummySettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager) {};
|
DummySettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager){};
|
||||||
|
|
||||||
void begin();
|
void begin();
|
||||||
void loop();
|
void loop();
|
||||||
@@ -101,12 +101,12 @@ class ESP32React {
|
|||||||
public:
|
public:
|
||||||
ESP32React(AsyncWebServer * server, FS * fs)
|
ESP32React(AsyncWebServer * server, FS * fs)
|
||||||
: _settings(server, fs, nullptr)
|
: _settings(server, fs, nullptr)
|
||||||
, _securitySettingsService(server, fs) {};
|
, _securitySettingsService(server, fs){};
|
||||||
|
|
||||||
void begin() {
|
void begin() {
|
||||||
_mqttClient = new espMqttClient();
|
_mqttClient = new espMqttClient();
|
||||||
};
|
};
|
||||||
void loop() {};
|
void loop(){};
|
||||||
|
|
||||||
SecurityManager * getSecurityManager() {
|
SecurityManager * getSecurityManager() {
|
||||||
return &_securitySettingsService;
|
return &_securitySettingsService;
|
||||||
|
|||||||
@@ -243,6 +243,9 @@ class AsyncWebServer {
|
|||||||
void on(const char * uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest) {};
|
void on(const char * uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest) {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef SSE_MAX_QUEUED_MESSAGES
|
||||||
|
#define SSE_MAX_QUEUED_MESSAGES 32
|
||||||
|
#endif
|
||||||
|
|
||||||
class AsyncEventSource : public AsyncWebHandler {
|
class AsyncEventSource : public AsyncWebHandler {
|
||||||
public:
|
public:
|
||||||
@@ -252,6 +255,9 @@ class AsyncEventSource : public AsyncWebHandler {
|
|||||||
size_t count() const {
|
size_t count() const {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
size_t avgPacketsWaiting() const {
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
void send(const char * message, const char * event = NULL, uint32_t id = 0, uint32_t reconnect = 0) {};
|
void send(const char * message, const char * event = NULL, uint32_t id = 0, uint32_t reconnect = 0) {};
|
||||||
};
|
};
|
||||||
|
|||||||
4
mock-api/.gitattributes
vendored
4
mock-api/.gitattributes
vendored
@@ -1,4 +0,0 @@
|
|||||||
/.yarn/** linguist-vendored
|
|
||||||
/.yarn/releases/* binary
|
|
||||||
/.yarn/plugins/**/* binary
|
|
||||||
/.pnp.* binary linguist-generated
|
|
||||||
935
mock-api/.yarn/releases/yarn-4.7.0.cjs
vendored
935
mock-api/.yarn/releases/yarn-4.7.0.cjs
vendored
File diff suppressed because one or more lines are too long
@@ -1,3 +0,0 @@
|
|||||||
nodeLinker: node-modules
|
|
||||||
|
|
||||||
yarnPath: .yarn/releases/yarn-4.7.0.cjs
|
|
||||||
@@ -3,10 +3,11 @@ When developing and testing the web interface, it's handy not to bother with re-
|
|||||||
# prerequisites
|
# prerequisites
|
||||||
|
|
||||||
- Install the latest LTS of NodeJS
|
- Install the latest LTS of NodeJS
|
||||||
- Install yarn (`npm install -g yarn`)
|
- install corepack `npm install -g corepack@latest` and `orepack enable`
|
||||||
|
- Install pnpm (`corepack use pnpm@latest-10` on linux or `winget install -e --id pnpm.pnpm` on windows). See <https://pnpm.io/installation>
|
||||||
- Install bun (<https://bun.sh/docs/installation>)
|
- Install bun (<https://bun.sh/docs/installation>)
|
||||||
- type `yarn` from this `mock-api` folder to build
|
- type `pnpm install` from this `mock-api` folder to build
|
||||||
|
|
||||||
# To run
|
# To run
|
||||||
|
|
||||||
- `yarn standalone` from the main `interface` folder and then navigate to <http://localhost:3000>
|
- `pnpm standalone` from the main `interface` folder and then navigate to <http://localhost:3000>
|
||||||
|
|||||||
@@ -5,15 +5,15 @@
|
|||||||
"author": "proddy, emsesp.org",
|
"author": "proddy, emsesp.org",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"mock-rest": "bun --watch rest_server.ts",
|
"mock-rest": "bun --watch restServer.ts",
|
||||||
"format": "prettier -l -w '**/*.{ts,tsx,js,css,json,md}'"
|
"format": "prettier -l -w '**/*.{ts,tsx,js,css,json,md}'"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@msgpack/msgpack": "^3.1.1",
|
"@msgpack/msgpack": "^3.1.2",
|
||||||
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
|
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
|
||||||
"formidable": "^3.5.2",
|
"formidable": "^3.5.4",
|
||||||
"itty-router": "^5.0.18",
|
"itty-router": "^5.0.22",
|
||||||
"prettier": "^3.5.3"
|
"prettier": "^3.6.2"
|
||||||
},
|
},
|
||||||
"packageManager": "yarn@4.7.0"
|
"packageManager": "pnpm@10.18.1+sha512.77a884a165cbba2d8d1c19e3b4880eee6d2fcabd0d879121e282196b80042351d5eb3ca0935fa599da1dc51265cc68816ad2bddd2a2de5ea9fdf92adbec7cd34"
|
||||||
}
|
}
|
||||||
|
|||||||
279
mock-api/pnpm-lock.yaml
generated
Normal file
279
mock-api/pnpm-lock.yaml
generated
Normal file
@@ -0,0 +1,279 @@
|
|||||||
|
lockfileVersion: '9.0'
|
||||||
|
|
||||||
|
settings:
|
||||||
|
autoInstallPeers: true
|
||||||
|
excludeLinksFromLockfile: false
|
||||||
|
|
||||||
|
importers:
|
||||||
|
|
||||||
|
.:
|
||||||
|
dependencies:
|
||||||
|
'@msgpack/msgpack':
|
||||||
|
specifier: ^3.1.2
|
||||||
|
version: 3.1.2
|
||||||
|
'@trivago/prettier-plugin-sort-imports':
|
||||||
|
specifier: ^5.2.2
|
||||||
|
version: 5.2.2(prettier@3.6.2)
|
||||||
|
formidable:
|
||||||
|
specifier: ^3.5.4
|
||||||
|
version: 3.5.4
|
||||||
|
itty-router:
|
||||||
|
specifier: ^5.0.22
|
||||||
|
version: 5.0.22
|
||||||
|
prettier:
|
||||||
|
specifier: ^3.6.2
|
||||||
|
version: 3.6.2
|
||||||
|
|
||||||
|
packages:
|
||||||
|
|
||||||
|
'@babel/code-frame@7.27.1':
|
||||||
|
resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
|
'@babel/generator@7.28.3':
|
||||||
|
resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
|
'@babel/helper-globals@7.28.0':
|
||||||
|
resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
|
'@babel/helper-string-parser@7.27.1':
|
||||||
|
resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
|
'@babel/helper-validator-identifier@7.27.1':
|
||||||
|
resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
|
'@babel/parser@7.28.4':
|
||||||
|
resolution: {integrity: sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==}
|
||||||
|
engines: {node: '>=6.0.0'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
|
'@babel/template@7.27.2':
|
||||||
|
resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
|
'@babel/traverse@7.28.4':
|
||||||
|
resolution: {integrity: sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
|
'@babel/types@7.28.4':
|
||||||
|
resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
|
'@jridgewell/gen-mapping@0.3.13':
|
||||||
|
resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
|
||||||
|
|
||||||
|
'@jridgewell/resolve-uri@3.1.2':
|
||||||
|
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
|
||||||
|
engines: {node: '>=6.0.0'}
|
||||||
|
|
||||||
|
'@jridgewell/sourcemap-codec@1.5.5':
|
||||||
|
resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
|
||||||
|
|
||||||
|
'@jridgewell/trace-mapping@0.3.31':
|
||||||
|
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
|
||||||
|
|
||||||
|
'@msgpack/msgpack@3.1.2':
|
||||||
|
resolution: {integrity: sha512-JEW4DEtBzfe8HvUYecLU9e6+XJnKDlUAIve8FvPzF3Kzs6Xo/KuZkZJsDH0wJXl/qEZbeeE7edxDNY3kMs39hQ==}
|
||||||
|
engines: {node: '>= 18'}
|
||||||
|
|
||||||
|
'@noble/hashes@1.8.0':
|
||||||
|
resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==}
|
||||||
|
engines: {node: ^14.21.3 || >=16}
|
||||||
|
|
||||||
|
'@paralleldrive/cuid2@2.2.2':
|
||||||
|
resolution: {integrity: sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==}
|
||||||
|
|
||||||
|
'@trivago/prettier-plugin-sort-imports@5.2.2':
|
||||||
|
resolution: {integrity: sha512-fYDQA9e6yTNmA13TLVSA+WMQRc5Bn/c0EUBditUHNfMMxN7M82c38b1kEggVE3pLpZ0FwkwJkUEKMiOi52JXFA==}
|
||||||
|
engines: {node: '>18.12'}
|
||||||
|
peerDependencies:
|
||||||
|
'@vue/compiler-sfc': 3.x
|
||||||
|
prettier: 2.x - 3.x
|
||||||
|
prettier-plugin-svelte: 3.x
|
||||||
|
svelte: 4.x || 5.x
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@vue/compiler-sfc':
|
||||||
|
optional: true
|
||||||
|
prettier-plugin-svelte:
|
||||||
|
optional: true
|
||||||
|
svelte:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
asap@2.0.6:
|
||||||
|
resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==}
|
||||||
|
|
||||||
|
debug@4.4.3:
|
||||||
|
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
|
||||||
|
engines: {node: '>=6.0'}
|
||||||
|
peerDependencies:
|
||||||
|
supports-color: '*'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
supports-color:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
dezalgo@1.0.4:
|
||||||
|
resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==}
|
||||||
|
|
||||||
|
formidable@3.5.4:
|
||||||
|
resolution: {integrity: sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==}
|
||||||
|
engines: {node: '>=14.0.0'}
|
||||||
|
|
||||||
|
itty-router@5.0.22:
|
||||||
|
resolution: {integrity: sha512-9hmdGErWdYDOurGYxSbqLhy4EFReIwk71hMZTJ5b+zfa2zjMNV1ftFno2b8VjAQvX615gNB8Qxbl9JMRqHnIVA==}
|
||||||
|
|
||||||
|
javascript-natural-sort@0.7.1:
|
||||||
|
resolution: {integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==}
|
||||||
|
|
||||||
|
js-tokens@4.0.0:
|
||||||
|
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||||
|
|
||||||
|
jsesc@3.1.0:
|
||||||
|
resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
|
lodash@4.17.21:
|
||||||
|
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
|
||||||
|
|
||||||
|
ms@2.1.3:
|
||||||
|
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||||
|
|
||||||
|
once@1.4.0:
|
||||||
|
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
|
||||||
|
|
||||||
|
picocolors@1.1.1:
|
||||||
|
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
||||||
|
|
||||||
|
prettier@3.6.2:
|
||||||
|
resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==}
|
||||||
|
engines: {node: '>=14'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
|
wrappy@1.0.2:
|
||||||
|
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||||
|
|
||||||
|
snapshots:
|
||||||
|
|
||||||
|
'@babel/code-frame@7.27.1':
|
||||||
|
dependencies:
|
||||||
|
'@babel/helper-validator-identifier': 7.27.1
|
||||||
|
js-tokens: 4.0.0
|
||||||
|
picocolors: 1.1.1
|
||||||
|
|
||||||
|
'@babel/generator@7.28.3':
|
||||||
|
dependencies:
|
||||||
|
'@babel/parser': 7.28.4
|
||||||
|
'@babel/types': 7.28.4
|
||||||
|
'@jridgewell/gen-mapping': 0.3.13
|
||||||
|
'@jridgewell/trace-mapping': 0.3.31
|
||||||
|
jsesc: 3.1.0
|
||||||
|
|
||||||
|
'@babel/helper-globals@7.28.0': {}
|
||||||
|
|
||||||
|
'@babel/helper-string-parser@7.27.1': {}
|
||||||
|
|
||||||
|
'@babel/helper-validator-identifier@7.27.1': {}
|
||||||
|
|
||||||
|
'@babel/parser@7.28.4':
|
||||||
|
dependencies:
|
||||||
|
'@babel/types': 7.28.4
|
||||||
|
|
||||||
|
'@babel/template@7.27.2':
|
||||||
|
dependencies:
|
||||||
|
'@babel/code-frame': 7.27.1
|
||||||
|
'@babel/parser': 7.28.4
|
||||||
|
'@babel/types': 7.28.4
|
||||||
|
|
||||||
|
'@babel/traverse@7.28.4':
|
||||||
|
dependencies:
|
||||||
|
'@babel/code-frame': 7.27.1
|
||||||
|
'@babel/generator': 7.28.3
|
||||||
|
'@babel/helper-globals': 7.28.0
|
||||||
|
'@babel/parser': 7.28.4
|
||||||
|
'@babel/template': 7.27.2
|
||||||
|
'@babel/types': 7.28.4
|
||||||
|
debug: 4.4.3
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@babel/types@7.28.4':
|
||||||
|
dependencies:
|
||||||
|
'@babel/helper-string-parser': 7.27.1
|
||||||
|
'@babel/helper-validator-identifier': 7.27.1
|
||||||
|
|
||||||
|
'@jridgewell/gen-mapping@0.3.13':
|
||||||
|
dependencies:
|
||||||
|
'@jridgewell/sourcemap-codec': 1.5.5
|
||||||
|
'@jridgewell/trace-mapping': 0.3.31
|
||||||
|
|
||||||
|
'@jridgewell/resolve-uri@3.1.2': {}
|
||||||
|
|
||||||
|
'@jridgewell/sourcemap-codec@1.5.5': {}
|
||||||
|
|
||||||
|
'@jridgewell/trace-mapping@0.3.31':
|
||||||
|
dependencies:
|
||||||
|
'@jridgewell/resolve-uri': 3.1.2
|
||||||
|
'@jridgewell/sourcemap-codec': 1.5.5
|
||||||
|
|
||||||
|
'@msgpack/msgpack@3.1.2': {}
|
||||||
|
|
||||||
|
'@noble/hashes@1.8.0': {}
|
||||||
|
|
||||||
|
'@paralleldrive/cuid2@2.2.2':
|
||||||
|
dependencies:
|
||||||
|
'@noble/hashes': 1.8.0
|
||||||
|
|
||||||
|
'@trivago/prettier-plugin-sort-imports@5.2.2(prettier@3.6.2)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/generator': 7.28.3
|
||||||
|
'@babel/parser': 7.28.4
|
||||||
|
'@babel/traverse': 7.28.4
|
||||||
|
'@babel/types': 7.28.4
|
||||||
|
javascript-natural-sort: 0.7.1
|
||||||
|
lodash: 4.17.21
|
||||||
|
prettier: 3.6.2
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
asap@2.0.6: {}
|
||||||
|
|
||||||
|
debug@4.4.3:
|
||||||
|
dependencies:
|
||||||
|
ms: 2.1.3
|
||||||
|
|
||||||
|
dezalgo@1.0.4:
|
||||||
|
dependencies:
|
||||||
|
asap: 2.0.6
|
||||||
|
wrappy: 1.0.2
|
||||||
|
|
||||||
|
formidable@3.5.4:
|
||||||
|
dependencies:
|
||||||
|
'@paralleldrive/cuid2': 2.2.2
|
||||||
|
dezalgo: 1.0.4
|
||||||
|
once: 1.4.0
|
||||||
|
|
||||||
|
itty-router@5.0.22: {}
|
||||||
|
|
||||||
|
javascript-natural-sort@0.7.1: {}
|
||||||
|
|
||||||
|
js-tokens@4.0.0: {}
|
||||||
|
|
||||||
|
jsesc@3.1.0: {}
|
||||||
|
|
||||||
|
lodash@4.17.21: {}
|
||||||
|
|
||||||
|
ms@2.1.3: {}
|
||||||
|
|
||||||
|
once@1.4.0:
|
||||||
|
dependencies:
|
||||||
|
wrappy: 1.0.2
|
||||||
|
|
||||||
|
picocolors@1.1.1: {}
|
||||||
|
|
||||||
|
prettier@3.6.2: {}
|
||||||
|
|
||||||
|
wrappy@1.0.2: {}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user