mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-31 04:19:15 +03:00
Compare commits
2093 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e7a8d356df | ||
|
|
afe22aed6d | ||
|
|
5de18abaf9 | ||
|
|
7657016f0d | ||
|
|
d89681a0ef | ||
| 318e3ed463 | |||
| 70896f6c92 | |||
|
|
5ed30a7253 | ||
|
|
e3121a2467 | ||
|
|
a71e6088ca | ||
|
|
f46e75786a | ||
| d255efaefb | |||
| f1ecf3d191 | |||
| 2002a6b45f | |||
|
|
18012bd57a | ||
|
|
acf7732c3c | ||
|
|
7be2d41547 | ||
|
|
7b9da809f5 | ||
|
|
22629d0117 | ||
|
|
42b2d9085a | ||
|
|
4195c383ee | ||
| f948741ae5 | |||
| 0b31c8a8c9 | |||
| 49c90d20c3 | |||
| fe9d9827db | |||
| 1a79776bfb | |||
| 6194169990 | |||
| 4b98abfa53 | |||
| 33d449d892 | |||
| d11f69b08d | |||
| 892e6d32ab | |||
| bdb8c29d8f | |||
| b0d1ec9465 | |||
| 2a518bce5d | |||
| bc548a1719 | |||
| fbdcb6ee42 | |||
| 060373ec31 | |||
| 6dbfa4669b | |||
| d417f96248 | |||
| d30408c395 | |||
| e9cc823ebf | |||
| 9b54a179e5 | |||
| 1ead6a7e02 | |||
| ce1b8e4716 | |||
|
|
444bd6c201 | ||
|
|
ff7a3550d2 | ||
|
|
17dadf5745 | ||
|
|
3a2ac1666b | ||
|
|
692a36bf37 | ||
|
|
efc4da0bb6 | ||
|
|
1928806cae | ||
|
|
940f68a90f | ||
|
|
6765f265ac | ||
|
|
f5ba827488 | ||
|
|
769d6fc7f1 | ||
|
|
fc50947ff3 | ||
|
|
d8cb3e9b07 | ||
|
|
37d9c2224a | ||
|
|
4c949528b8 | ||
|
|
9dca608181 | ||
|
|
9beb86d775 | ||
|
|
f254fbe7aa | ||
|
|
7627874766 | ||
|
|
4bd168494f | ||
|
|
8925239e46 | ||
|
|
104bfbf092 | ||
|
|
78742d90a1 | ||
| a7a02db13d | |||
|
|
27f2e67e8e | ||
|
|
67a6eba882 | ||
|
|
36ea71c270 | ||
|
|
4ef929bb23 | ||
|
|
33d19bea97 | ||
|
|
9cbf5f0b38 | ||
|
|
e988481404 | ||
| 2e8a7f111c | |||
|
|
9d32b0c33d | ||
|
|
9b620fda5e | ||
|
|
dccdf4af66 | ||
|
|
95b9dc3d2d | ||
|
|
e3d3bca68e | ||
|
|
05ea75aa0a | ||
|
|
229dc89a7c | ||
|
|
10b1adb5a5 | ||
|
|
959315b86e | ||
|
|
9a1e92d747 | ||
|
|
6094c621af | ||
|
|
d337dea1b8 | ||
|
|
68d653902c | ||
|
|
f214140cea | ||
|
|
a6e4617b30 | ||
|
|
130dd038c6 | ||
|
|
9904b561d9 | ||
|
|
3791fe29ad | ||
|
|
96b8311579 | ||
|
|
79c1810be8 | ||
|
|
24430de25f | ||
|
|
2397d1c018 | ||
|
|
fce887d10b | ||
|
|
18cd043ea8 | ||
|
|
c086c71728 | ||
|
|
0f8fa70a56 | ||
|
|
025bf94abc | ||
|
|
68fea2ae37 | ||
|
|
a844d08ebf | ||
|
|
5e801e7789 | ||
|
|
322925fa5a | ||
|
|
889eb5f85b | ||
|
|
64b4e67dcd | ||
|
|
463fc61649 | ||
|
|
0bd525401b | ||
|
|
a122de9b5d | ||
|
|
a1079a0764 | ||
|
|
17949a56da | ||
|
|
f3ebfb363a | ||
|
|
64ce8b052d | ||
|
|
1a2de8521c | ||
|
|
5f3845457a | ||
|
|
d726e661c0 | ||
|
|
247cb51169 | ||
|
|
3aaeb760da | ||
|
|
13d0b514a3 | ||
|
|
3a17e0c57c | ||
|
|
d392858cb1 | ||
|
|
6820460915 | ||
|
|
d6e4ac232f | ||
|
|
8136d47cbd | ||
|
|
cfe1f04bdd | ||
|
|
e9403b275c | ||
|
|
509363fc4d | ||
|
|
dbad34b42c | ||
|
|
dc87331c4b | ||
|
|
7f18bcd622 | ||
|
|
d63f1bb5bf | ||
|
|
af0f782f07 | ||
|
|
b9c07b809f | ||
|
|
a1ab70fc07 | ||
|
|
596eb9cad4 | ||
|
|
b32abb5a28 | ||
|
|
d6a24b1837 | ||
|
|
3919e5a0ab | ||
| d3d01f1ae6 | |||
| 6a288bb002 | |||
| edd498d1c9 | |||
| ed7037f280 | |||
| 320dd2f68f | |||
|
|
a693f69fdd | ||
|
|
d2a55af97e | ||
|
|
94bfc4ec61 | ||
|
|
0a9a1b9387 | ||
|
|
794d51187e | ||
|
|
ae455446ca | ||
|
|
26bd69a224 | ||
|
|
eff916a7b5 | ||
|
|
a8ff7a4350 | ||
|
|
1ba4126e03 | ||
|
|
27788b611a | ||
|
|
a439fdffae | ||
|
|
04ffe7fc5d | ||
|
|
8927557e06 | ||
|
|
3e4345e06c | ||
| 2696ffbb67 | |||
|
|
2eec5d2982 | ||
|
|
ac20905220 | ||
| 6605108052 | |||
|
|
fcfcc27863 | ||
|
|
cf50538dba | ||
| be18ef6875 | |||
|
|
4fe14beb6d | ||
|
|
9c3ad06c6f | ||
|
|
d95907a839 | ||
|
|
7a1fad9855 | ||
|
|
604cb96776 | ||
|
|
b25398bff4 | ||
|
|
9776f821d3 | ||
|
|
8c98a387a2 | ||
|
|
bc62abded0 | ||
|
|
403535b8d6 | ||
|
|
cf099b0db6 | ||
|
|
b228603158 | ||
|
|
d00eabbe0a | ||
|
|
d2865118f4 | ||
|
|
ab0d5f40e2 | ||
|
|
8aecb4b001 | ||
|
|
a63ca6e5c2 | ||
|
|
bf7725566b | ||
|
|
b348629b0b | ||
|
|
8e7d2d6a14 | ||
|
|
0baf03fccf | ||
|
|
43887e7408 | ||
|
|
b4919bddd6 | ||
|
|
15de2955fb | ||
| 94239e51cc | |||
| 8bb3348f39 | |||
| 3900062fb2 | |||
| 02d1ddc7b4 | |||
| a228c3456f | |||
|
|
d05137b4d4 | ||
|
|
64099655ec | ||
|
|
d3f15dac37 | ||
|
|
cae0a7a19c | ||
|
|
ccca92e276 | ||
| 915fd9eb3d | |||
| e259c5d203 | |||
| 709316e53e | |||
|
|
896af8bbe8 | ||
|
|
eff1c77864 | ||
| d5e8639a67 | |||
| 398ce07d57 | |||
| c706ea0f68 | |||
| e904ac1741 | |||
| 047c0fc5cc | |||
| e43bfd9080 | |||
| 9c394f77ab | |||
| 223a6add12 | |||
| 02cf1547a8 | |||
| e0ec19c5f7 | |||
| 9da0260a94 | |||
| d442588ac4 | |||
| cbbd2dc12f | |||
| e7e900eb4c | |||
| 6a8ad1ea09 | |||
| 145d53acfb | |||
| 79fe2d29d2 | |||
| 111529375c | |||
| 959d8a8503 | |||
|
|
ae8fb2c4c1 | ||
|
|
2f70055e4e | ||
| a751d36ddf | |||
| 67118f5c8f | |||
|
|
f2fc5f1885 | ||
| 32f82880eb | |||
|
|
0e9d8b905b | ||
|
|
94c591d9d8 | ||
| 7ec6319dcd | |||
| 4b268bbcf2 | |||
| 0112326f02 | |||
| 99af99cfcc | |||
| 906b828dcc | |||
|
|
7fe92efbe7 | ||
|
|
f2d49a31de | ||
|
|
2c53e28b9a | ||
|
|
794497ed47 | ||
|
|
6c865eabd3 | ||
|
|
6dda19ae9c | ||
|
|
d98ded42da | ||
|
|
620a29a41a | ||
|
|
348d305e42 | ||
|
|
70a536a399 | ||
|
|
d947a8be97 | ||
|
|
ee72108f73 | ||
|
|
c061143273 | ||
|
|
ef5a2aca9b | ||
|
|
2235d5aa38 | ||
|
|
1d5ea5361a | ||
| 4987648895 | |||
|
|
5079235c82 | ||
|
|
ee9f2457ab | ||
| 04b2608000 | |||
|
|
f553279c8b | ||
|
|
3758070575 | ||
|
|
76ac0ed540 | ||
|
|
b9e5c4378d | ||
|
|
4f7eaff3b5 | ||
| 0dd3c7e07f | |||
| f2738c6e3d | |||
| 96b982082a | |||
| 3d2efea1c9 | |||
| 4e11b01c78 | |||
| 561245a5e5 | |||
| d53b197a53 | |||
| 9dec0ab11d | |||
|
|
5ac04807e8 | ||
|
|
cffc6dbab5 | ||
|
|
1448fa4750 | ||
|
|
e5781dc424 | ||
|
|
5f1a9b23e5 | ||
|
|
8ae5c07302 | ||
|
|
88964eb198 | ||
|
|
aa464365e5 | ||
|
|
f068d8c10b | ||
|
|
40122a2b21 | ||
|
|
8cd131bda2 | ||
|
|
b2e12bc36d | ||
| 06bf5aa39f | |||
|
|
b3662a7aa8 | ||
|
|
125684f63b | ||
| cc4496d2d1 | |||
| 77c9a9d7df | |||
| 546606b341 | |||
| 4fb6698de6 | |||
| 38be938f36 | |||
|
|
eeffa8b309 | ||
|
|
8b4c95998b | ||
|
|
0cb564e3d5 | ||
|
|
a6a5bc3ea1 | ||
|
|
f965e7bc9f | ||
|
|
abbb023b6a | ||
| d1c6e0e04f | |||
| 4474d98d59 | |||
|
|
9a790276ad | ||
|
|
70973cae19 | ||
| 4a8a05a065 | |||
| a0806034bb | |||
|
|
a5636d3461 | ||
| 6ca8764efd | |||
|
|
ffc4ac1ac1 | ||
|
|
aaf91922d0 | ||
|
|
f2528eb72a | ||
|
|
4ec079ea80 | ||
|
|
2ced506404 | ||
|
|
218e53a813 | ||
|
|
35b184c2a3 | ||
|
|
eedba5d4b8 | ||
|
|
51ff037098 | ||
| 49cd22a5dd | |||
|
|
400d29bcf8 | ||
|
|
59d7821040 | ||
|
|
0afb996af0 | ||
|
|
8ac6866e82 | ||
|
|
7a0710e946 | ||
|
|
61608edd32 | ||
|
|
1a574e37cd | ||
|
|
dc69633454 | ||
|
|
876ca9b378 | ||
|
|
e79263b9a5 | ||
|
|
8f457c6aa1 | ||
|
|
eebb736018 | ||
|
|
cc4989761b | ||
|
|
2141c83283 | ||
|
|
324df4169c | ||
|
|
d4413fbe31 | ||
|
|
ae8ca2b00a | ||
|
|
7ce6839c10 | ||
|
|
6b4ff97be2 | ||
|
|
abc9ebf27e | ||
|
|
9fc42652bf | ||
|
|
144d80f945 | ||
|
|
928b5a7d5c | ||
|
|
0d3e6ee829 | ||
|
|
8efd1a1578 | ||
|
|
a3ec0681da | ||
|
|
15776fc6a7 | ||
|
|
c89c084c80 | ||
|
|
164f3be998 | ||
| e82df3f575 | |||
| 6b875d2cda | |||
| 3990bc6e11 | |||
| 9c1f41ce3b | |||
| 0e2825d069 | |||
| 7b4bf9d4f7 | |||
| be57ad295f | |||
| ac7ccde2e3 | |||
| 9ece70ffed | |||
| 9b1fed1b22 | |||
| 888803b7bd | |||
| ad87416eeb | |||
| 8428fe15b2 | |||
|
|
0b3289a0ea | ||
|
|
e35225e7be | ||
|
|
9eb6122fe1 | ||
|
|
2e3506d67c | ||
|
|
e7dade0b8f | ||
|
|
3607fc911f | ||
|
|
71972b6177 | ||
|
|
173981fca7 | ||
|
|
8209fb98f6 | ||
|
|
57ac9738dd | ||
|
|
5757c35b83 | ||
|
|
1910667876 | ||
|
|
4d1699fd7d | ||
|
|
e0b7dcb46b | ||
|
|
27974a1ffd | ||
|
|
1036802114 | ||
|
|
ef42b03bb8 | ||
|
|
d4333ca807 | ||
|
|
eac446aa48 | ||
|
|
621a4d2f01 | ||
|
|
dec76ed367 | ||
|
|
428b8f166b | ||
|
|
d518f31582 | ||
|
|
c3a1f46b3a | ||
|
|
649bceaca6 | ||
|
|
6f863663b2 | ||
|
|
34b8227bec | ||
| 26e8104510 | |||
|
|
660591dc60 | ||
|
|
eb171b2128 | ||
|
|
264c1c3c71 | ||
| 8d053204bb | |||
| 34eb56588c | |||
| c02687aa05 | |||
| 680a342a64 | |||
| 7a00131813 | |||
| 09e4b4e877 | |||
| a0751f20f7 | |||
| 6db1ef5bfd | |||
| 160321ced0 | |||
|
|
eae29bd680 | ||
|
|
137a5a43b8 | ||
|
|
e47eb4969a | ||
|
|
0e679f132d | ||
|
|
aec78a4d03 | ||
|
|
d391bbbd63 | ||
|
|
8c8a070fbb | ||
|
|
37cd897257 | ||
|
|
cafe008f7d | ||
|
|
07c0bb166b | ||
|
|
2edb067369 | ||
|
|
1a239f1f02 | ||
|
|
c76306faf5 | ||
|
|
082496997c | ||
|
|
34c6213100 | ||
|
|
9bb40e3846 | ||
|
|
fc3dfc389f | ||
|
|
d9bfacba3c | ||
|
|
0b83a72dc4 | ||
|
|
44fab264eb | ||
|
|
ed50bd8c44 | ||
|
|
7c0ffe7af5 | ||
|
|
0eb6494772 | ||
|
|
97288a1f21 | ||
|
|
4e9ef86393 | ||
|
|
11c7e50f83 | ||
|
|
022829f494 | ||
|
|
6cd40fceee | ||
|
|
8eb719ea6c | ||
|
|
668bbbff87 | ||
|
|
307786f087 | ||
|
|
e48d13faae | ||
|
|
98a5f5f5a3 | ||
|
|
48ccdd7e86 | ||
|
|
32d61805fa | ||
|
|
2a275cc1a5 | ||
|
|
b3a426bdc4 | ||
|
|
fe9789fc52 | ||
|
|
014f450761 | ||
|
|
d4bdcc13ff | ||
|
|
63be5b5aac | ||
|
|
848bbaab96 | ||
|
|
319dc8d6ce | ||
| dab8d5323c | |||
|
|
6892beeb38 | ||
|
|
1019143d0d | ||
|
|
5195e71eb1 | ||
|
|
cd62326845 | ||
|
|
7ec9b6e2a6 | ||
|
|
d774612fbb | ||
|
|
123412285d | ||
|
|
81099f3727 | ||
|
|
6c7c81f2c2 | ||
|
|
6d2dc1a454 | ||
|
|
16d935964b | ||
|
|
a7a4a34737 | ||
|
|
e6b19233b7 | ||
|
|
5003f9a684 | ||
|
|
bd902c51e1 | ||
|
|
4bcc00b1e5 | ||
|
|
016fedfe25 | ||
|
|
b9fc5e3f04 | ||
|
|
70f51b9a70 | ||
|
|
4731dca6a9 | ||
|
|
e7843fe16d | ||
|
|
bd721965ca | ||
|
|
5d38442eba | ||
|
|
a4dae52b1c | ||
|
|
7178745482 | ||
|
|
de74bc8d7f | ||
|
|
2def3f2825 | ||
|
|
fbe7b1cf02 | ||
|
|
93dfa8ee83 | ||
|
|
5715da0baa | ||
| a1d053c37d | |||
| 646128b999 | |||
| 67a432d7ad | |||
|
|
357dd39a11 | ||
|
|
34010801ef | ||
|
|
3212fc914c | ||
|
|
0513326776 | ||
|
|
c1ec63d155 | ||
|
|
fab1e15168 | ||
|
|
85ee98d312 | ||
|
|
6a23c635a1 | ||
|
|
adda80feb1 | ||
|
|
3bd8d34b97 | ||
|
|
4ed4f240a6 | ||
|
|
5bc4471424 | ||
|
|
8f95eec4b0 | ||
|
|
840cd56c1d | ||
|
|
6fe5e97ea0 | ||
|
|
89e8c1fdcc | ||
|
|
768669a635 | ||
|
|
af0f7a219b | ||
|
|
cb969e75b9 | ||
|
|
0cb0bbf39c | ||
|
|
a502c0fac8 | ||
|
|
dde2bc1be6 | ||
|
|
447471c6d0 | ||
|
|
d669cb4143 | ||
| 521ee0a4bd | |||
| c276be820b | |||
| 88d61e7efa | |||
| aef7613fdf | |||
| 44891aa2e8 | |||
| 45c575b755 | |||
| 965b340e5c | |||
| fe0c49b5a2 | |||
| 68585ad4b6 | |||
|
|
9ab5933460 | ||
|
|
aaee76b969 | ||
|
|
35ba1fe376 | ||
|
|
b09fea39e7 | ||
|
|
62991f8d8e | ||
|
|
52c3a88f3c | ||
|
|
1971e32b5f | ||
|
|
1b42083f43 | ||
|
|
415fe9c5b3 | ||
|
|
5d9deb8e95 | ||
| 32d124e9fe | |||
| 2745648638 | |||
| 1ffc02c6f8 | |||
| 11a4a53132 | |||
|
|
c9e8692b68 | ||
|
|
0e31e9ac9a | ||
|
|
d4b601d206 | ||
|
|
7c2631800a | ||
|
|
3ebc144747 | ||
|
|
b9196f2241 | ||
|
|
ea51c7ae68 | ||
|
|
ed6d0a253a | ||
|
|
309d974b73 | ||
|
|
ada197331d | ||
| 8260bef3d4 | |||
| 9c418a0646 | |||
| 081ec36045 | |||
|
|
bb1359adab | ||
|
|
107cb85a98 | ||
| 16f20fcee5 | |||
| 42c8941848 | |||
|
|
d0c2952bb2 | ||
|
|
8fdc9822aa | ||
|
|
ee3e19d68f | ||
| 4ffa3958fb | |||
| 37e9f98ce2 | |||
| 427782958c | |||
|
|
a94a4c3f23 | ||
|
|
392b7ba894 | ||
|
|
3e3388284c | ||
|
|
e680ed6bc9 | ||
|
|
e6d05fd578 | ||
|
|
8751d188c8 | ||
|
|
af6c975704 | ||
|
|
57a5bb6df2 | ||
|
|
9e49ece90f | ||
|
|
cf66b2a482 | ||
|
|
b3705b6924 | ||
|
|
3b1eb07d74 | ||
|
|
f8de34fb97 | ||
|
|
dab33bc71c | ||
| 589502a273 | |||
| c078c81636 | |||
| 6fb06e2314 | |||
| 1792d2e3f7 | |||
| b146c75389 | |||
| 7b9a742264 | |||
| 45c0f6a39a | |||
| b7a3bebd36 | |||
| bdff41a4b0 | |||
| 8825a2996e | |||
| 1dff39eecf | |||
| 3e49a24d07 | |||
| ac25014552 | |||
| 1d04aae9e9 | |||
| 0dbcba4409 | |||
| be9b1f7910 | |||
| 80b40373dd | |||
| 58bba94f01 | |||
|
|
b71af2fce1 | ||
| d2c9810cb2 | |||
| 62ae53739e | |||
| b02137dfa6 | |||
| 1534647cce | |||
| b1675fff3a | |||
| 0e0ccf6625 | |||
| 6b44f83098 | |||
| cc27d8a170 | |||
|
|
0b6d7ac112 | ||
|
|
311a379e1a | ||
|
|
4342269e44 | ||
|
|
80f8a917cd | ||
|
|
eeff84201d | ||
|
|
4a93fd09dc | ||
| 46ce8a7b5e | |||
|
|
6610e67825 | ||
|
|
57cf6e1063 | ||
| 219d6e3f6b | |||
| 293f0369f9 | |||
| ce856e4f12 | |||
|
|
c82197c71d | ||
|
|
471a9d94bf | ||
|
|
ac77b8fb4a | ||
|
|
c64a2e7793 | ||
|
|
50228f3ea7 | ||
| 45748cd67f | |||
| a68b143e54 | |||
| 30a0754823 | |||
| 0e6a83089d | |||
| 35829ede3b | |||
| 057a95a434 | |||
| edf966f66b | |||
| ff84a18fd0 | |||
| 4f7923e7aa | |||
| 946979bafe | |||
| 50a4759063 | |||
|
|
b7430f87e8 | ||
| d6b3d2dc68 | |||
| b19b51d2bf | |||
| f4071e42dc | |||
| 5f884e16af | |||
| e0df67ccee | |||
| 2c89974a6a | |||
| 37fc18cdfd | |||
| 2b71aad6f4 | |||
| 6e14411cc4 | |||
| 907c6046b1 | |||
| edbb563c53 | |||
| 0f25b97ba1 | |||
| e774eec72f | |||
| 827f2c1230 | |||
| 1cbe0394ef | |||
| a0b8f4067d | |||
| 113a7c7388 | |||
| a184216908 | |||
| 6374e8506d | |||
| 65049852d6 | |||
| d45fc0ed1e | |||
| f53a7341d8 | |||
| bd4244bef3 | |||
| 7709116734 | |||
| e10bfaa4b5 | |||
| a27b937c9c | |||
| aae0331415 | |||
| 0f9a185163 | |||
| a3b99a9e8d | |||
| 1189b7c289 | |||
| e0b8613c99 | |||
| 41bb91ff1d | |||
| d242268bb2 | |||
| 399060b5d4 | |||
| 44cc52bb50 | |||
| 08116d84c7 | |||
| aad28b04bc | |||
|
|
e89b4d98d1 | ||
| dc0a21e1cf | |||
| c362c5e0bc | |||
| 21a8e00449 | |||
| 762ea280b0 | |||
| 6bc3355cbe | |||
| e10dd9a569 | |||
| ebb8b9747d | |||
| 7f73f464ea | |||
| e8064e5b1a | |||
| 6aae5ec88c | |||
| 5bb0e61088 | |||
| a036c87897 | |||
| d7560cb788 | |||
| 1f3e490d10 | |||
|
|
a77a093a79 | ||
| 479b0fcfdd | |||
| 5f886baa2c | |||
| ce4fbbc1db | |||
| b4b8e6b89b | |||
|
|
3e24bf61e0 | ||
|
|
987461ed28 | ||
|
|
ee27987085 | ||
|
|
821aeb5ad2 | ||
| 51909624af | |||
| 33bc338449 | |||
| b2d4d211c7 | |||
| 5a9ee8ac6e | |||
| 7c050b0492 | |||
| 9871963cbb | |||
| 8d6ab1ee8a | |||
| 5db3a4281c | |||
|
|
e51312dd56 | ||
|
|
ef0477c99a | ||
|
|
e9cd61d246 | ||
|
|
e2719b8b4e | ||
|
|
2db14ed21a | ||
|
|
d2a615c9e5 | ||
|
|
cdcebc4736 | ||
|
|
dbee4f48f0 | ||
|
|
4894b578c4 | ||
|
|
66729fa1dc | ||
|
|
fc6d159f5d | ||
|
|
00780b998b | ||
|
|
062771871c | ||
|
|
2013b2822d | ||
|
|
11fdd5ee00 | ||
|
|
7d9129d3fd | ||
|
|
61721b36b1 | ||
|
|
cdbf97cf42 | ||
|
|
8cde47b8ce | ||
|
|
e53bbcc7d8 | ||
|
|
afb7ce9951 | ||
|
|
33a9861a8f | ||
|
|
89b95a75eb | ||
|
|
11bc2dc2f8 | ||
|
|
f146db165e | ||
|
|
6d5297456b | ||
|
|
a705cbf54d | ||
|
|
08ffc74e8d | ||
|
|
3285a70a88 | ||
| 4d1ef99939 | |||
|
|
1ca0b20179 | ||
|
|
8afb6fdb12 | ||
|
|
35f8424d56 | ||
|
|
84b70e5617 | ||
|
|
cb50965c3b | ||
|
|
2c61580157 | ||
|
|
9436af94df | ||
| d4c2eeb752 | |||
|
|
68efbbd060 | ||
|
|
3e95049ce9 | ||
|
|
1d11cc10cc | ||
| a5f27717fb | |||
| 69fb1ed969 | |||
|
|
83d4f305e4 | ||
|
|
c47225809c | ||
|
|
eb5352fcc2 | ||
|
|
d6ef9c4b65 | ||
|
|
985bb97d93 | ||
|
|
374073267c | ||
| 02752be0b2 | |||
| 3d504b01dd | |||
| aac0086c23 | |||
| ae389b770e | |||
| 5dce817580 | |||
| 1f8bb4aa6e | |||
| 1a575e0f61 | |||
| 0a25a06eb2 | |||
|
|
0d2fe420f5 | ||
| 8d5d284e02 | |||
|
|
863103b3f9 | ||
|
|
c9d0d0360f | ||
|
|
636bd8773f | ||
| 8507aaf1e6 | |||
| 41311e4e0c | |||
| be7c8c54f1 | |||
| 2dd9cf8720 | |||
|
|
6da7171f88 | ||
|
|
96d623f53b | ||
|
|
452805f2fe | ||
|
|
b49c4ecb1a | ||
|
|
6339db7a69 | ||
| f539435216 | |||
| 267408fc77 | |||
| 4dba35d08e | |||
| 3e7780a4e0 | |||
| 3668874154 | |||
| a619bab167 | |||
| 24f23955b8 | |||
| 34716d2e9e | |||
| 45dea185c5 | |||
| 02b2ef77a0 | |||
| 4606f49df0 | |||
| 9ad3ea9a35 | |||
| 4c7b14bcc8 | |||
| 5f8be4295c | |||
| d6460f43a2 | |||
| 4db49060de | |||
| 0237cc20a3 | |||
|
|
e7e415c489 | ||
| 466fad0525 | |||
| dda99a53bb | |||
| 8d269d50b0 | |||
| 4170c7d3e4 | |||
| 267ceb619d | |||
| 16c5342ace | |||
| 8b4d5eddbc | |||
| 497c402597 | |||
| 270c15c10f | |||
| 32a04e48f3 | |||
| c4ca01484b | |||
| 5bd898aa6b | |||
| 667d0952ba | |||
| 2fc5340e97 | |||
| 2925b13bd1 | |||
| 4534214f48 | |||
| 2899f53d4b | |||
| ca0d9a4a5d | |||
| 875cc933b3 | |||
| c276f4e5e8 | |||
| 2bf726b617 | |||
| c02e50452a | |||
| b07436742b | |||
| 0b2c0df326 | |||
| 8523a278db | |||
| 3564c43512 | |||
| cc69fde50d | |||
| 83c472117c | |||
| 04bbcc983a | |||
| 15da6dd973 | |||
| 67e9c160ea | |||
| a7f49cdd5b | |||
| 72c8321695 | |||
| 5c5c36e25d | |||
| 67c9340f0f | |||
| 706b3a1b5c | |||
| 0a787df79f | |||
| 3850402d47 | |||
| fcf83c3f0d | |||
| 4cf666402c | |||
| 868c7bf4f2 | |||
| b8f403f1f1 | |||
| fc07462b64 | |||
|
|
bd48be3786 | ||
| ce23ab180f | |||
| 3cef0bb1d3 | |||
| 32f09cd8e4 | |||
| 898af53970 | |||
| fb427751f2 | |||
| d91ffc4e25 | |||
| 96c99ef5ac | |||
| 27416945a2 | |||
| 94c156f123 | |||
| d9788f96bd | |||
| 4ddbd97999 | |||
| 7dc21ee914 | |||
| a292f17285 | |||
| dfd24dc1f6 | |||
| 305a5f5ccb | |||
| 593bebd0de | |||
| 8a4ca7a6ae | |||
| 2f375f1ddc | |||
| b347c5c0fb | |||
| f528952137 | |||
| a8642ac915 | |||
| 08db9bd9e3 | |||
| 31beaa9c90 | |||
| cf041494c4 | |||
| 01d6b0904a | |||
| dca907dbaa | |||
| e5a6a7a0c4 | |||
| 480e20a62e | |||
| 728fcb385e | |||
| d2485228eb | |||
| 1501b5660e | |||
| c403755dd5 | |||
| 97fd2565ec | |||
| b89610ae0a | |||
| 538257208d | |||
| 55c0cfd718 | |||
| 2078ecd17b | |||
| b143b5a66b | |||
| ccfb04d4a7 | |||
| dafe486784 | |||
| 6f5caec540 | |||
| 7f5ebb768d | |||
|
|
cc92500008 | ||
| f480295d0c | |||
| 2a27b1d9bf | |||
| cce9f2197a | |||
| b8e76e19b8 | |||
| c89127c067 | |||
| 6c0a456fd0 | |||
|
|
f3389c4721 | ||
| 82112e876f | |||
| f763e27b1c | |||
| 0ec28b8545 | |||
| 01ec7de9d2 | |||
| 9326cc0aff | |||
|
|
0080854a53 | ||
|
|
051550ad47 | ||
| 0e44ba1a3e | |||
|
|
85bf00ac01 | ||
|
|
6912d5f68d | ||
|
|
2c7adf468b | ||
|
|
b61cfca3ed | ||
| 3af9b457de | |||
| eb1cf42807 | |||
| 1726dafb18 | |||
| cc28b45851 | |||
| 0553503e1c | |||
| f9ddffba71 | |||
| 3581d133d4 | |||
|
|
c1283bc5b2 | ||
|
|
1668ab8aa8 | ||
|
|
caff040a91 | ||
|
|
db69c96ea0 | ||
|
|
fe30d7c27d | ||
|
|
8287bb9ebb | ||
|
|
00665e7f2b | ||
|
|
645e90379c | ||
|
|
6e0392ac03 | ||
|
|
5812d98ff9 | ||
| 76b5565773 | |||
| 9e4ebd2a5e | |||
| 111486c7c3 | |||
|
|
b44e7c3ae0 | ||
|
|
dfa060895e | ||
|
|
5e9ae3f9dc | ||
| 7c4f983e51 | |||
| 8af8f40335 | |||
| 2fc6b0b59a | |||
| bc26f77e5c | |||
| c860898231 | |||
| 10103cbe0a | |||
| a9fc941c9b | |||
| 8a1e36f4ff | |||
| e3ec40dec2 | |||
| f32b05dd5b | |||
| c9a386c01b | |||
| 6ef9d2fe99 | |||
| c41bf277ec | |||
| 9e204da127 | |||
| 4cc46a777a | |||
| 1a605e1135 | |||
| d3fb354a1e | |||
| b8b5dc9114 | |||
| 34753586eb | |||
| 5e45b29c2f | |||
| 079dd7af1e | |||
| 7659b3a700 | |||
| 084a0473fa | |||
| 6b47aac021 | |||
| d78458d85a | |||
| 615c645aaf | |||
|
|
a4b54ccff7 | ||
|
|
31b83e8380 | ||
| ebc9c10bcd | |||
| 7def6d0543 | |||
| 98812e7470 | |||
| 8aad1ba87d | |||
|
|
51dff491a9 | ||
| cb35653d36 | |||
| 7c4f1a2851 | |||
|
|
8f708b9c13 | ||
|
|
27e30ab0ff | ||
|
|
1ef029ddd5 | ||
|
|
cacfae9435 | ||
|
|
a6fb2bd619 | ||
|
|
1625455594 | ||
|
|
7ac2e96c7b | ||
|
|
73ea994ffe | ||
|
|
085b79a2fd | ||
|
|
af2b015dea | ||
|
|
adfeb9ef55 | ||
|
|
ffbb30de41 | ||
|
|
06bd15c246 | ||
|
|
06819441e5 | ||
| 4053a22a03 | |||
| a518051558 | |||
|
|
62ff324139 | ||
|
|
f92291c545 | ||
|
|
dc573e35af | ||
|
|
bbe9737974 | ||
|
|
a3c4edfc67 | ||
|
|
6de053a84c | ||
|
|
1dd1958abc | ||
|
|
e809c92c64 | ||
|
|
d426746733 | ||
|
|
e688c95c59 | ||
|
|
c091f1b4cc | ||
|
|
c75d6dd66d | ||
|
|
a3e76ebfb1 | ||
|
|
bdf8b6a1e7 | ||
|
|
909e28c36a | ||
|
|
b5b56fe00e | ||
|
|
e7e174de10 | ||
|
|
c7477872a8 | ||
|
|
100477444c | ||
|
|
b1fe6af04d | ||
|
|
8a3d061bd7 | ||
|
|
02843daca1 | ||
|
|
45a3caf67e | ||
|
|
0a165026eb | ||
|
|
f7e459cab4 | ||
|
|
3eb2d40596 | ||
|
|
e1b4ffa574 | ||
|
|
2f2e2d9755 | ||
| 1bcf206dcc | |||
| f07e938d67 | |||
| 2a89b8cb42 | |||
| 504b77139a | |||
| 1449a13e4c | |||
| c8dbb6e13f | |||
| cd72802542 | |||
| fd219e3191 | |||
| 2c7dcf6928 | |||
|
|
75b36b67ae | ||
|
|
c24dde3098 | ||
|
|
d4539169ea | ||
|
|
aae21f4a78 | ||
| d78e03176f | |||
| 1fee3ca538 | |||
| 1761a3e353 | |||
| 818824c378 | |||
|
|
8ce79687bc | ||
|
|
49dde6031a | ||
| 5532ef7dfb | |||
| e84375418f | |||
| 8737528d83 | |||
| b5b1e2c5cf | |||
| 5ef81840eb | |||
| f8649e3a7e | |||
|
|
0a1d606149 | ||
|
|
cd2cebaeb8 | ||
|
|
5036fbc2fe | ||
|
|
e8731b413e | ||
|
|
d121414e65 | ||
|
|
9c5624eddf | ||
|
|
039a36a59d | ||
|
|
8340ae2a0f | ||
|
|
fff7c976a9 | ||
|
|
5e8120086b | ||
|
|
89ddd0fbe3 | ||
|
|
f769b74c7f | ||
|
|
a89c91c708 | ||
|
|
5da6b61b36 | ||
| 6ee4927ea8 | |||
| 3e00ca3920 | |||
|
|
12ef79c558 | ||
| 5acd080fe0 | |||
| a535a66ca7 | |||
| e8cc488119 | |||
| 9355953bae | |||
| 2e07c5b031 | |||
| 62ab3dc2de | |||
| dd5efcdc48 | |||
| 52c184f439 | |||
| 90e8d4eaf4 | |||
| e391bee0ca | |||
| 5ec718e68b | |||
| 2757c12a40 | |||
| 03bc656084 | |||
| 0d7304e297 | |||
| ed2eb6cfb7 | |||
| 9403a150ff | |||
| a010859c06 | |||
| 80607c593b | |||
| 63c84c12b8 | |||
| 26e39aa6a9 | |||
| 25843260c7 | |||
| 0c23cd78dd | |||
|
|
258d7b764b | ||
|
|
b153b51bba | ||
|
|
e8526f0e1a | ||
| 8665c1f64a | |||
| 401de56631 | |||
| 850ef2440d | |||
| 9f6f521c8d | |||
|
|
9ac0ab0b5a | ||
|
|
00118c026d | ||
|
|
1b873555ad | ||
| 7402d7915b | |||
| 71b94318eb | |||
|
|
a2d5a6f5e1 | ||
| df95f8bae2 | |||
| 0dac2b0528 | |||
|
|
51f6ceba1e | ||
|
|
0889425943 | ||
|
|
d947e9da71 | ||
| 1c5de5b92e | |||
| bea3ff3300 | |||
| ae5eec49e9 | |||
| 52f6877ef7 | |||
| 03fdd6cc8b | |||
|
|
1200861b1d | ||
|
|
03000298a4 | ||
|
|
4b4816a264 | ||
|
|
88d5ac513e | ||
|
|
199c6ac46b | ||
| e17260628e | |||
|
|
e823207627 | ||
| 0f869ebf39 | |||
|
|
c610f006be | ||
| 138f246139 | |||
| 79a44b165e | |||
| d31e5de95a | |||
| a2a10909f6 | |||
| 801ac643c3 | |||
| 12d1ed2dee | |||
| 63226d4795 | |||
| 16680ff513 | |||
|
|
fe54a14ef3 | ||
| fc521d9875 | |||
| af6289693c | |||
| cc1938b165 | |||
|
|
064e1b10ff | ||
|
|
5febce0e5c | ||
|
|
318ddc67da | ||
|
|
d4f11f2d08 | ||
|
|
a4ea3e9280 | ||
|
|
162f4de45e | ||
|
|
e3fc7a7416 | ||
|
|
f65e16f674 | ||
|
|
4bce800e1d | ||
|
|
28d3f4fc63 | ||
|
|
31f2fec13b | ||
|
|
68774cec5f | ||
|
|
a4b7eb00d7 | ||
|
|
6822bdf532 | ||
|
|
78760f6507 | ||
|
|
71c4fb5651 | ||
|
|
f90176879f | ||
|
|
bc545cc958 | ||
|
|
3ec0071527 | ||
|
|
b63d163432 | ||
|
|
1dc7e4f9ea | ||
|
|
9784b455e7 | ||
|
|
bfaf586981 | ||
|
|
5deb974b4e | ||
| 875b7616ab | |||
| 06472912e8 | |||
|
|
d3cb26af30 | ||
|
|
92dbc1c786 | ||
| 9d841b1f57 | |||
| c0f9a0890b | |||
| d22741d9f6 | |||
| 2f22ac31f8 | |||
|
|
c3f37fcf11 | ||
|
|
99e2fcfcb8 | ||
| f7849894e5 | |||
| aa3ba13859 | |||
|
|
004476b049 | ||
|
|
d779c4bd80 | ||
|
|
cf8e7206f4 | ||
| 6c8ac6a2c8 | |||
| 62d6cc586a | |||
| 4ed7996309 | |||
| 5aef309154 | |||
| 2bf63798e5 | |||
| 8809bad02d | |||
| 3fb10eeef4 | |||
|
|
65b4302270 | ||
|
|
5249c794d1 | ||
|
|
cb463a0dd1 | ||
|
|
e11fc59af9 | ||
|
|
6b1265d6b8 | ||
|
|
b458758a54 | ||
|
|
ff5b9e8a9b | ||
|
|
6ea71ec43e | ||
|
|
85f8deb12a | ||
|
|
dfd85d88cb | ||
| ef94ea9037 | |||
| 9ea209669f | |||
| 2dc80bb4b8 | |||
| 1fcec9ba80 | |||
|
|
22433ef65d | ||
|
|
1f9f746149 | ||
|
|
72b54eb5bb | ||
|
|
d22580aac9 | ||
|
|
ca95a4528d | ||
|
|
027dc16ba1 | ||
|
|
8011609092 | ||
|
|
68d0dd4aad | ||
| ff3ee66b0d | |||
| 0a8f43c7d2 | |||
| 47ee98352c | |||
| e1341a532f | |||
| ca3cc0e840 | |||
| 3be301ca89 | |||
| 699531bada | |||
| 34c33692f5 | |||
|
|
67004284c4 | ||
|
|
35da88080d | ||
| c78b45159d | |||
| 6e4d8777d4 | |||
| 2a757dfb4d | |||
| 610cc8f862 | |||
| 799aff3383 | |||
|
|
1ddc3aab9c | ||
|
|
542cf86941 | ||
|
|
97ac17c466 | ||
|
|
125eaa78ec | ||
|
|
ee38878961 | ||
|
|
ace3d14261 | ||
|
|
6d4b899fc0 | ||
| 0dc05a14d4 | |||
| 5e66391520 | |||
| 986c061caf | |||
| 2028564c63 | |||
| 39ff16512e | |||
| 6b582cb2bd | |||
| 4acad424a6 | |||
| 41286083b7 | |||
| 755625cc35 | |||
| 31b0e0d786 | |||
| d26ec6b6e5 | |||
| 3622847995 | |||
| 0e31f7c112 | |||
| 029d505806 | |||
| efcda0218a | |||
| 504c9dfbbb | |||
| 844ea052d7 | |||
| a8d4e0a303 | |||
| aaf7702f55 | |||
| 5020816b89 | |||
| 52a96f1542 | |||
| 107dcf4c74 | |||
| 74decadee5 | |||
| 72c36a25a7 | |||
| 1e947eb48d | |||
| 671765d32e | |||
| 4ca8115154 | |||
| 4ce71dfcfd | |||
| 0938e57583 | |||
| 6b9b5ec9dc | |||
| b9e3461c72 | |||
| a0e2973bda | |||
| e3072ce887 | |||
| cbd9a4de8d | |||
| 67148de250 | |||
| 29a2762788 | |||
| 85289144bc | |||
| f4a1ff70ca | |||
| 0aab5dcbed | |||
| 8f0b50a6f3 | |||
| fe64723ecd | |||
| 879a67de6f | |||
| 1d782fd0d7 | |||
| 7846279379 | |||
| 5e5890b961 | |||
| 65d898ae82 | |||
| 4cc9077327 | |||
| a3c5a803ca | |||
| e45aed2da8 | |||
| 8bbea0c2cb | |||
| bdaf6c1832 | |||
| 83c5d74d7a | |||
| 790c289183 | |||
| 26a1aca9dd | |||
| e9d5eef5e3 | |||
| db3fddb622 | |||
| b09086b4b3 | |||
| 691b1187e7 | |||
| 8eb3fd5ae6 | |||
| 26fd968782 | |||
| 17982a9e70 | |||
| 336a4c7e52 | |||
| dc8b472c0d | |||
| 8914e06cd2 | |||
| 628ac413f9 | |||
| cd8ce5ff0b | |||
| 7d71c78170 | |||
| 2b67fb9588 | |||
| 4c315fdb12 | |||
| 0f685a5f49 | |||
| c658343e7f | |||
| 900ff95429 | |||
| 878e71bb36 | |||
| f140bbc8cc | |||
| 115d22b914 | |||
| 094bb44ed6 | |||
| 934173f8cc | |||
| ba824456d4 | |||
| 3434f8bd82 | |||
| 8c8ea24ea3 | |||
| df9b507102 | |||
| 65eb81ed81 | |||
| af4543b3b5 | |||
| fd60bd6eb3 | |||
| 2f9569c3e6 | |||
| 0d596da39f | |||
| f563a773e1 | |||
| 39c83aa328 | |||
| 2a8eb84836 | |||
| 8ae2983ba7 | |||
| 0451aca0d5 | |||
| fe7b1f6a39 | |||
| 613d60256a | |||
| cf6fd585c3 | |||
|
|
185a949a80 | ||
|
|
617ce425f4 | ||
|
|
c2bb0e17f4 | ||
|
|
cbe3ee7886 | ||
| 4000cc1144 | |||
| 8499424138 | |||
| fb04592f8b | |||
| 2fa40c4eff | |||
|
|
ebe2e9cbdd | ||
| 93b6014c55 | |||
| 75a96508b2 | |||
| c453a98685 | |||
| d9e111470a | |||
|
|
f1b8b07584 | ||
| 4f57e965cb | |||
| 2bca458f0c | |||
| 9880e9d169 | |||
| 0ae8fd1e38 | |||
| 42c1cd3e57 | |||
| 1ac32e6711 | |||
|
|
3f0b1b3d6a | ||
| 3704988d9b | |||
|
|
9d956113b5 | ||
|
|
c3529d1a10 | ||
| afeb741dfe | |||
| cf188070d5 | |||
| 0975a4eb7d | |||
|
|
69ea305324 | ||
|
|
080de83be7 | ||
|
|
7ec426114f | ||
|
|
28add9cb25 | ||
| 39c5e98ca6 | |||
| 520d27f8d8 | |||
|
|
c50e0606e4 | ||
| e6824dde8b | |||
| c51afa80af | |||
|
|
40e43dee0a | ||
| 3ce94f044b | |||
| 5d0d3274c5 | |||
|
|
11e56dbe1d | ||
| d047ebf453 | |||
| f5de7299ec | |||
| c024ef6673 | |||
|
|
6a3f8542c5 | ||
| 5da9a141a9 | |||
| 6d7c734f46 | |||
| 9ca63882af | |||
| fc7eb8acc9 | |||
|
|
9639b3eb88 | ||
| 798897962e | |||
| 24a66b0ca4 | |||
| 08dd59fe16 | |||
|
|
cc20801daa | ||
|
|
dad46c8c9c | ||
| bb33fccb47 | |||
| 2507c76b10 | |||
|
|
a384acebcc | ||
|
|
1e482da574 | ||
| 8c8ac1d800 | |||
|
|
1dfab33e4c | ||
|
|
c565767260 | ||
| a2bb357a75 | |||
| be662dd497 | |||
|
|
23ae779b48 | ||
|
|
56a1c3fb0e | ||
| f8356a9e29 | |||
| b938cbdcf0 | |||
|
|
7acb6e0bc6 | ||
| 729c126405 | |||
| a69e048da9 | |||
| 3a9775df5d | |||
| 14ea31c705 | |||
|
|
1ee6991590 | ||
|
|
69d46815cd | ||
| df6d328cc4 | |||
| bd4753f2c9 | |||
|
|
a4648fd075 | ||
|
|
993b2b25fd | ||
|
|
f4f93a32db | ||
| 5a96d39012 | |||
| 9fe7adb151 | |||
| 905d137341 | |||
|
|
cce5726390 | ||
|
|
27dfc24d4c | ||
| 7c48ca6c5a | |||
| 16a778269c | |||
|
|
6f2c9d76ca | ||
|
|
3926c67601 | ||
|
|
fd128f71f2 | ||
|
|
2366e027b9 | ||
|
|
bd30cbdde2 | ||
| c728d7b90c | |||
| 52db75b8d5 | |||
| 0e25a78c23 | |||
|
|
5110c609c3 | ||
|
|
218a0408a5 | ||
|
|
fa2d8bd15f | ||
|
|
c04efee622 | ||
|
|
dca800e424 | ||
|
|
afe64d4c4a | ||
|
|
7ff73236a7 | ||
| 1e612e3910 | |||
|
|
f5afc00c32 | ||
|
|
709c4fb961 | ||
| cafac8b76e | |||
| c144a3ae1e | |||
| 5c8221f86f | |||
| da845b7ecb | |||
|
|
fbec3827e2 | ||
|
|
2ecfe839f8 | ||
| 0b4f771c48 | |||
|
|
5cdcb0f0e6 | ||
|
|
15c55c2df6 | ||
|
|
caa2102eff | ||
|
|
ed78401762 | ||
|
|
09bbd96a63 | ||
|
|
38acd7f569 | ||
|
|
8d86bb222a | ||
|
|
02a087ccdd | ||
|
|
a3c3e4055a | ||
|
|
c728d34f03 | ||
|
|
01428f4531 | ||
|
|
429e1fbfb3 | ||
|
|
45c5681dc6 | ||
|
|
57bd78ad90 | ||
|
|
a423b81b07 | ||
|
|
9b5a87bbcf | ||
|
|
d9ab7ed1b7 | ||
|
|
fafbae3f07 | ||
|
|
dc90df8a2d | ||
|
|
11cd4744b5 | ||
| ce7d461b77 | |||
| ca0fb25a30 | |||
| 8b83e1649c | |||
| 73bff64a54 | |||
|
|
f2f94ba071 | ||
| 71fdf081a2 | |||
|
|
6966a66ef0 | ||
|
|
c51286ffc0 | ||
| 34252302a9 | |||
|
|
0540ea5b04 | ||
|
|
bd1d25d79a | ||
|
|
a2f5927172 | ||
|
|
e376693028 | ||
|
|
692099a814 | ||
|
|
a01dbc3d0a | ||
| 6bdc3d11f0 | |||
| dca2a51843 | |||
| b2e20f6760 | |||
|
|
ad9679314c | ||
|
|
d0e291a9cb | ||
| 5f076d50e8 | |||
| a745d61e03 | |||
| 3898234c6d | |||
| 6373f36eb5 | |||
| e06be18432 | |||
| d19ebe8bfc | |||
| 5b8c579396 | |||
| 3b743a768d | |||
| fabe47bed4 | |||
| ac0d82f74e | |||
| d5909c1c72 | |||
| 66d1fffefa | |||
|
|
757c9d4e1d | ||
| 3bcdf8d8b5 | |||
| 0128a8966a | |||
| 9ca620ada4 | |||
| 4eae1055e7 | |||
| 71dcd0626b | |||
|
|
9ec724ccff | ||
|
|
c2b2997952 | ||
|
|
0eab9ec7d8 | ||
|
|
b9d8443724 | ||
|
|
5c6b50f40a | ||
|
|
01690b1b3e | ||
|
|
c85824f67f | ||
|
|
5ec1e59957 | ||
|
|
70edd92238 | ||
|
|
ec93e1de04 | ||
|
|
553bc4e00d | ||
|
|
3353194e2f | ||
|
|
719929445a | ||
|
|
1b4380dd2f | ||
|
|
9d56087973 | ||
|
|
eca80d7dba | ||
|
|
9f05eccb26 | ||
|
|
6318fb4af0 | ||
|
|
90c35e3a36 | ||
|
|
f893a3623d | ||
|
|
c4a3dec67c | ||
|
|
8229e0b116 | ||
|
|
221ad5f5d4 | ||
|
|
003c130eef | ||
|
|
5bdecdda04 | ||
|
|
629d7b798f | ||
|
|
a4fa6ad389 | ||
|
|
3abad88fc3 | ||
|
|
b43bfd378b | ||
| 694bac8c77 | |||
|
|
ce7cd1a680 | ||
|
|
775d7a11ad | ||
|
|
ee322ce185 | ||
|
|
cc5b6d9907 | ||
|
|
5e70aa90cf | ||
|
|
46be36aa69 | ||
| c8bd073cf8 | |||
| db36e79058 | |||
| b79233d6fb | |||
| 02436d53d5 | |||
|
|
1637b76739 | ||
| 6e1f34136f | |||
|
|
f01fea9bac | ||
|
|
7f5b78b695 | ||
|
|
a9c07e8865 | ||
|
|
ccead93da4 | ||
|
|
cb97fc7477 | ||
|
|
dd775eb454 | ||
|
|
a4a8c75206 | ||
|
|
ea68905f4e | ||
|
|
b6c714bec8 | ||
|
|
2f4a280dcf | ||
|
|
063e818c87 | ||
|
|
e6e3497c40 | ||
|
|
a18552c4f4 | ||
|
|
d4f9069f6f | ||
|
|
6f8d88d155 | ||
|
|
1fda00d5ca | ||
|
|
efd461b8e6 | ||
|
|
6336cb5248 | ||
|
|
18bb63ec8c | ||
|
|
0d21f693c3 | ||
|
|
3e558175f9 | ||
|
|
b2ad5102d1 | ||
|
|
a353e65ed9 | ||
|
|
9397bac72e | ||
|
|
be35992c84 | ||
|
|
4a7b130b26 | ||
|
|
2bf86e7092 | ||
|
|
bec09df96f | ||
|
|
7bd8a4bac7 | ||
|
|
954192e5f9 | ||
|
|
11120a873f | ||
|
|
875f5009c2 | ||
|
|
dbe11162e5 | ||
|
|
756363397b | ||
|
|
d73657d39a | ||
|
|
a19a12c7d4 | ||
|
|
401aaa727e | ||
|
|
9d0841df99 | ||
|
|
940a5a7ee9 | ||
|
|
667b30dcf9 | ||
|
|
44ccbe7ed7 | ||
|
|
7147e041b4 | ||
|
|
f20486517b | ||
|
|
0262fa985b | ||
|
|
5f605a8e7c | ||
|
|
d18463bfe1 | ||
|
|
7a76ddcc93 | ||
|
|
d208bbd426 | ||
|
|
24a9d55ea0 | ||
|
|
5e9b15e7de | ||
|
|
1ed5c81eb7 | ||
|
|
70add780bd | ||
|
|
02a2e42ece | ||
|
|
01b0a7d53e | ||
|
|
b0b8203fec | ||
|
|
a5d2650507 | ||
|
|
16cecfb353 | ||
|
|
329d1cd382 | ||
|
|
d3046a921f | ||
|
|
6868e94971 | ||
|
|
cc72c766ea | ||
|
|
d6e396bd7c | ||
|
|
e7f503da8f | ||
|
|
cecf83357a | ||
|
|
15b55a1c83 | ||
|
|
959332b65d | ||
|
|
618b2b5275 | ||
|
|
f7a97c2d36 | ||
|
|
715d20c21f | ||
|
|
b8a8290928 | ||
|
|
7486ba7438 | ||
|
|
2a79a5880f | ||
|
|
1af7687064 | ||
|
|
f8307dcb5e | ||
|
|
2573e73b3a | ||
|
|
eae59e3947 | ||
|
|
413eabd87e | ||
|
|
eec67b8bc2 | ||
|
|
2e04a980cc | ||
|
|
752e09a71d | ||
|
|
bd6fa0fc37 | ||
|
|
7218411e34 | ||
|
|
e3c8ca57a2 | ||
|
|
5029ea62ce | ||
|
|
c6d3b8b91f | ||
|
|
060d44eb74 | ||
|
|
cceb43e8ad | ||
|
|
08d3ab8754 | ||
|
|
2fce26ff29 | ||
|
|
2d974dc9b9 | ||
|
|
b6c5f50123 | ||
|
|
b077d31e83 | ||
|
|
5ff0e8a5c1 | ||
|
|
3f5d7e8b6e | ||
|
|
421f3fcb9a | ||
|
|
74c31e30ea | ||
|
|
60a292a2f5 | ||
|
|
cbf0d372c9 | ||
|
|
e1b96cd287 | ||
|
|
0b5d7236aa | ||
|
|
bce8723ecf | ||
|
|
b7fcedb6c3 | ||
|
|
54cb92d2bb | ||
|
|
6902d57be2 | ||
|
|
57c12e43f1 | ||
|
|
c72af8650b | ||
|
|
a68dfb37fc | ||
|
|
3cdd8fc2b9 | ||
|
|
a4ae02736c | ||
|
|
e822414187 | ||
|
|
4e630fd0b0 | ||
|
|
988fb94c52 | ||
|
|
9906fade9a | ||
|
|
4cf68f417f | ||
|
|
05f726e378 | ||
|
|
75a7d4e16a | ||
|
|
691126a2d0 | ||
|
|
5eb3c6d3a3 | ||
|
|
bf9855aa60 | ||
|
|
50c616c61b | ||
|
|
2d2148d2c4 | ||
|
|
6ae001232d | ||
|
|
965b09cc78 | ||
|
|
a8534c4a73 | ||
|
|
401564a778 | ||
|
|
673bfe6b6b | ||
|
|
f8d574d15a | ||
|
|
e39806e0ac | ||
|
|
0fa7876b80 | ||
|
|
7eac8dde3b | ||
|
|
746ecc9c7a | ||
|
|
dad08c1686 | ||
|
|
e0bb6d58e8 | ||
|
|
a30dc04055 | ||
|
|
454922b8b4 | ||
|
|
02c363f1d6 | ||
|
|
d20f30d5e9 | ||
|
|
ddc3a92c15 | ||
|
|
e33ec57a1e | ||
|
|
7e4f852bf1 | ||
|
|
1a097ff2b7 | ||
|
|
99134cb6fd | ||
|
|
5955743426 | ||
|
|
5c664594af | ||
|
|
0df63ba642 | ||
|
|
d9672d17b0 | ||
|
|
c5772f8451 | ||
|
|
1df87f8986 | ||
|
|
3417d0c915 | ||
|
|
f4e917afba | ||
|
|
2aa3b56e85 | ||
|
|
e60d5eb62f | ||
|
|
6573b2c145 | ||
|
|
017c6f6234 | ||
|
|
305b3f32d6 | ||
|
|
5280a8914f | ||
|
|
cab8aff562 | ||
|
|
4711af6589 | ||
|
|
fe029a624c | ||
|
|
17162a2d85 | ||
|
|
433d28a785 | ||
|
|
19f728e209 | ||
|
|
07b75afb94 | ||
|
|
916116bbc4 | ||
|
|
9ac72f14e0 | ||
|
|
eddb2eb289 | ||
|
|
5f9d9ec48e | ||
|
|
0d6d1a7f6c | ||
|
|
a467117df9 | ||
|
|
0bb028229a | ||
|
|
ce383fe7fe | ||
|
|
2e240def88 | ||
|
|
245475ae99 | ||
|
|
c4df80e904 | ||
|
|
d5826b7038 | ||
|
|
8f08459a5a | ||
|
|
2fc82c3311 | ||
|
|
078c4389b5 | ||
|
|
9934690d0a | ||
|
|
b8a9f9b6b3 | ||
|
|
9fd88ffae1 | ||
|
|
9a7f6c5b05 | ||
|
|
ef01d08053 | ||
|
|
9a8061a84d | ||
|
|
e9820efff9 | ||
|
|
b2385bbc4c | ||
|
|
3e5d9770a1 | ||
|
|
71468599fe | ||
|
|
71c8fec27b | ||
|
|
f487a691fb | ||
|
|
d17112b3ff | ||
|
|
81866043bc | ||
|
|
253a9a5ae5 | ||
|
|
5c774c29bd | ||
|
|
6205f6959c | ||
|
|
6e44f76385 | ||
|
|
8dd4d8491c | ||
|
|
4436991205 | ||
|
|
d15cf619f1 | ||
|
|
9a2bdb54d1 | ||
|
|
7043855e3d | ||
|
|
49f11841be | ||
|
|
e88718ada0 | ||
|
|
0fc7cccda7 | ||
|
|
38924e4ed3 | ||
|
|
70c34d3d8d | ||
|
|
4f9763334b | ||
|
|
b2e9d90686 | ||
|
|
ceb516ddbe | ||
|
|
06df1f17b6 | ||
|
|
a20c2b8564 | ||
|
|
3c3a4a33ca | ||
|
|
28c24562bc | ||
|
|
d0ef8ec82e | ||
|
|
452110225d | ||
|
|
bdc9cd9b31 | ||
|
|
6cd60c9eef | ||
|
|
3e9da81b8c | ||
|
|
2e73eac2f1 | ||
|
|
6f45148d75 | ||
|
|
3766a744f4 | ||
|
|
94d93d3be6 | ||
|
|
d6aab0cf94 | ||
|
|
6135f3322e | ||
|
|
b53e7d15a4 | ||
|
|
7daa49083b | ||
|
|
68dc9c7bb3 | ||
|
|
b5cf1fd347 | ||
|
|
22f44afa1e | ||
|
|
964abc9f0c | ||
|
|
dfae6ebf09 | ||
|
|
50ad50efb2 | ||
|
|
96f160fc88 | ||
|
|
8bfba7ab4a | ||
|
|
6d52a181f0 | ||
|
|
044dd6294e | ||
|
|
c2baece068 | ||
|
|
9d6ec18bb2 | ||
|
|
50a5d51281 | ||
|
|
709a1fe1f7 | ||
|
|
1f46226a46 | ||
|
|
8cd84a09e2 | ||
|
|
e52437b828 | ||
|
|
1f69019bb3 | ||
|
|
2cad740fc6 | ||
|
|
aec1d50732 | ||
|
|
8817c532f4 | ||
|
|
3d42b96676 | ||
|
|
9845f010fd | ||
|
|
c02abefb43 | ||
|
|
aba00d9a70 | ||
|
|
0efae6949d | ||
|
|
777a04b901 | ||
|
|
50590bc90e | ||
|
|
0bfc876c65 | ||
|
|
518a0e0404 | ||
|
|
245db32e0b | ||
|
|
24de398a32 | ||
|
|
b2163c7626 | ||
|
|
d96aea8eef | ||
|
|
1126575822 | ||
|
|
8445dd3b0c | ||
|
|
b7a98e19d2 | ||
|
|
ff12345b12 | ||
|
|
0385beccdd | ||
|
|
f3a6add753 | ||
|
|
e984768a8d | ||
|
|
fb218fea76 | ||
|
|
600e66c345 | ||
|
|
29e5a55ad3 | ||
|
|
a5171f1178 | ||
|
|
a18f95d4e5 | ||
|
|
6064b9eac9 | ||
|
|
c389792081 | ||
|
|
7f0993f33b | ||
|
|
56e98e27f6 | ||
|
|
bea7afd057 | ||
|
|
cfd9d5baa0 | ||
|
|
b43fd9e389 | ||
|
|
92371f01da | ||
|
|
5b72a9b37f | ||
|
|
d2855270cf | ||
|
|
8778de1ffd | ||
|
|
281f338f97 | ||
|
|
d3ad04eae6 | ||
|
|
74b526e2f1 | ||
|
|
6426959060 | ||
|
|
cd9a6c98fa | ||
|
|
3bafbb88df | ||
|
|
eaef10aee2 | ||
|
|
d9556f5b31 | ||
|
|
a1eb94c4b3 | ||
|
|
5b6128ca21 | ||
|
|
65456398ac | ||
|
|
23fc8ec469 | ||
|
|
3607c26ae0 | ||
|
|
54841d59cf | ||
|
|
8bf136373c | ||
|
|
716aa697dc | ||
|
|
12cdefd531 | ||
|
|
19bc027083 | ||
|
|
1e4206f31d | ||
|
|
d6cb8b8d9a | ||
|
|
7472863b05 | ||
|
|
8a80d509c7 | ||
|
|
a77784abc7 | ||
|
|
52b8d971d8 | ||
|
|
65175e3663 | ||
|
|
9619a17abf | ||
|
|
3d1f1ec524 | ||
|
|
734f3e1b36 | ||
|
|
b66b4ab947 | ||
|
|
0598a20beb | ||
|
|
16b2498d6a | ||
|
|
716dfd095d | ||
|
|
e23481eef2 | ||
|
|
d6f5506812 | ||
|
|
8568e945a4 | ||
|
|
0a212e0933 | ||
|
|
fc91a60bab | ||
|
|
e0a83189d9 | ||
|
|
fe35633d23 | ||
|
|
251f7ee83f | ||
|
|
c960e5c5e5 | ||
|
|
807a6855e4 | ||
|
|
bac9396e9a | ||
|
|
dcbc928896 | ||
|
|
d8dfe7f60c | ||
|
|
e505eb9b6e | ||
|
|
799118d763 | ||
|
|
a258c8c1b6 | ||
|
|
26b5c173a2 | ||
|
|
551b35ff4f | ||
|
|
eea82a7edb | ||
|
|
26b211dc07 | ||
|
|
ab65cda820 | ||
|
|
89fed305c8 | ||
|
|
93c6b05238 | ||
|
|
8a07b7cbd7 | ||
|
|
4a57cf69d1 | ||
|
|
2e8ea582d2 | ||
|
|
70096c71c8 | ||
|
|
26383c0a19 | ||
|
|
a8e7799011 | ||
|
|
a9fc6f73f5 | ||
|
|
e66b49ddc3 | ||
|
|
3816711f04 | ||
|
|
0005760774 | ||
|
|
86ee523182 | ||
|
|
01248f41da | ||
|
|
786468e0b9 | ||
|
|
490a2f1f5b | ||
|
|
61f1ad64a1 | ||
|
|
25d58d3471 | ||
|
|
b1ca2ad511 | ||
|
|
8219cf3271 | ||
|
|
21e7297035 | ||
|
|
3ab75bcea6 | ||
|
|
eb6c06c8e9 | ||
|
|
0c1a1940d2 | ||
|
|
c473f616b6 | ||
|
|
74a7c8f528 | ||
|
|
f16d336575 | ||
|
|
ffc5e6c894 | ||
|
|
90e6822d3b | ||
|
|
e3f3ae7664 | ||
|
|
abbfcec92c | ||
|
|
7f7bad305c | ||
|
|
532925756f | ||
|
|
b1318de1dc | ||
|
|
c11983003b | ||
|
|
ce7c550410 | ||
|
|
e44d2dc793 | ||
|
|
82b1fb6846 | ||
|
|
0485feeabe | ||
|
|
e0d0e30e93 | ||
|
|
0ebe372848 | ||
|
|
e32097f563 | ||
|
|
10975cc8df | ||
|
|
1fa2add718 | ||
|
|
6c8be73d3a | ||
|
|
b2c8437c05 | ||
|
|
ef6930350e | ||
|
|
7ec3c05e6c | ||
|
|
b95a56d3a5 | ||
|
|
b512c0258d | ||
|
|
33ebb36aec | ||
|
|
8d31bcb5dd | ||
|
|
78fb96d50d | ||
|
|
6c969a2455 | ||
|
|
8df3ab8946 | ||
|
|
b2496bbc9f | ||
|
|
614b456b24 | ||
|
|
feab9e9afd | ||
|
|
924b6a1e84 | ||
|
|
f4a5bc0218 | ||
|
|
217cdfc080 | ||
|
|
b0fe94ddd4 | ||
|
|
6831c49a13 | ||
|
|
715ae0584a | ||
|
|
3dab9e484f | ||
|
|
1eac8a2f0e | ||
|
|
2434602d78 | ||
|
|
854d5f42e5 | ||
|
|
7806aa1ae8 | ||
|
|
98d59615a3 | ||
|
|
7134c07f60 | ||
|
|
9fa3ec05c2 | ||
|
|
832e6a36f1 | ||
|
|
5aa6f9482f | ||
|
|
bcbec5a9d8 | ||
|
|
2e66c93814 | ||
|
|
e04bb7bb78 | ||
|
|
110fc167a1 | ||
|
|
be60311f35 | ||
|
|
bdd9f1d3bd | ||
|
|
291373fe6f | ||
|
|
b653ce1e87 | ||
|
|
4aa0dc39b9 | ||
|
|
f7f4e176b2 | ||
|
|
62d0355a1e | ||
|
|
9b94aef8ca | ||
|
|
3dc49f66a8 | ||
|
|
d96ba8cb2c | ||
|
|
2dfca14478 | ||
|
|
b6eedca37e | ||
|
|
d7e6e0e9b8 | ||
|
|
9e291bfc9c | ||
|
|
7ac0691347 | ||
|
|
eb2881ee0a | ||
|
|
39a3cb04ed | ||
|
|
e561f82b02 | ||
|
|
00fd9f9bb9 | ||
|
|
b51ec4d0e2 | ||
|
|
e60269ed1e | ||
|
|
0f0d2ea209 | ||
|
|
5faa708c83 | ||
|
|
3ece57fc18 | ||
|
|
f75f0b5a50 | ||
|
|
9add7c9e8e | ||
|
|
5de838beb8 | ||
|
|
b7899aa059 | ||
|
|
c0b7cdddf8 | ||
|
|
d802758b6f | ||
|
|
a13dda46ca | ||
|
|
a73747c3dc | ||
|
|
e9a8e44a7a | ||
|
|
cd6008435e | ||
|
|
6277d2a9db | ||
|
|
d0c6d34f4a | ||
|
|
428efff8d5 | ||
|
|
7330849262 | ||
|
|
3dfee0eabe | ||
|
|
b6d346f779 | ||
|
|
a1bd008867 | ||
|
|
1264f12314 | ||
|
|
7c61ff2810 | ||
|
|
5ed1c23c62 | ||
|
|
b50e1c9791 | ||
|
|
baba0b77b2 | ||
|
|
3daa517c7e | ||
|
|
6618e6fa7e | ||
|
|
688a769798 | ||
|
|
a25288ef79 | ||
|
|
5643804d77 | ||
|
|
90a342bc27 | ||
|
|
c4dfdee7e5 | ||
|
|
a422c72565 | ||
|
|
2c3efd6309 | ||
|
|
e400de1e1c | ||
|
|
cc3c17dfb2 | ||
|
|
f9933ea55e | ||
|
|
59f65abda8 | ||
|
|
7dd13b7fcf | ||
|
|
f54cac95bb | ||
|
|
cb9c0efac6 | ||
|
|
06bbecd0bb | ||
|
|
dfeb25a8fa | ||
|
|
ecd124dacc | ||
|
|
6e97ec5845 | ||
|
|
e375cca3dc | ||
|
|
8f76cbac74 | ||
|
|
b50911ddcf | ||
|
|
8f395ccc8a | ||
|
|
fea662aed2 | ||
|
|
f7e3515c82 | ||
|
|
1bfe58766d | ||
|
|
274678f17a | ||
|
|
059b08fb8b | ||
|
|
f638de4139 | ||
|
|
8cdc271c48 | ||
|
|
092bec7dde | ||
|
|
4967f66238 | ||
|
|
3a3d27492b | ||
|
|
4013a21262 | ||
|
|
eba3b80076 | ||
|
|
c9c8fc0a31 | ||
|
|
cba45d7893 | ||
|
|
2769a8883f | ||
|
|
e2e6256aa0 | ||
|
|
b9f0564f28 | ||
|
|
b53660d4bf | ||
|
|
2333006b76 | ||
|
|
f2aabd0349 | ||
|
|
63e34bf2e2 | ||
|
|
9a5172e4a6 | ||
|
|
c670d0cb58 | ||
|
|
4e478c9d2a | ||
|
|
40688130fd | ||
|
|
62e11ff7fc | ||
|
|
179ab2c3bf | ||
|
|
91359fa9c4 | ||
|
|
de0696b81a | ||
|
|
aeedbdef92 | ||
|
|
bba7487374 | ||
|
|
f7d4b9abc9 | ||
|
|
45e96da169 | ||
|
|
ac6f51af7b | ||
|
|
72989f3dfb | ||
|
|
c7b87508a1 | ||
|
|
704afcdcd2 | ||
|
|
6fbd555474 | ||
|
|
91fffe83d1 | ||
|
|
cffd80d125 | ||
|
|
93fd7f6e16 | ||
|
|
fb62ae7a4b | ||
|
|
c4feb99e8d | ||
|
|
db5b8d7258 | ||
|
|
52599fe02c | ||
|
|
de5a9c01d0 | ||
|
|
df9d70ce77 | ||
|
|
652eaa99d0 | ||
|
|
93d128b9b4 | ||
|
|
98db017502 | ||
|
|
6f310e5e07 | ||
|
|
ece010976e | ||
|
|
cbb821167b | ||
|
|
465c393db4 | ||
|
|
7f2981d4e9 | ||
|
|
66d3754cc4 | ||
|
|
734edf522d | ||
|
|
8ec105d0b2 | ||
|
|
b044497c8e | ||
|
|
817a3e5898 | ||
|
|
446809355b | ||
|
|
48ba3c99dd | ||
|
|
e6637dcd69 | ||
|
|
2a45769caf | ||
|
|
2edba7baba | ||
|
|
02855b5ab9 | ||
|
|
15aa8c8539 | ||
|
|
aa1ad777c9 | ||
|
|
5494f61267 | ||
|
|
5bec53e6c2 | ||
|
|
86e18f1e99 | ||
|
|
c16b61c82b | ||
|
|
509ee7da0b | ||
|
|
3e5eed24c6 | ||
|
|
03f0d563ee | ||
|
|
2bc3c44b64 | ||
|
|
44dec6aece | ||
|
|
61b0c4b6b8 | ||
|
|
a154f3cd15 | ||
|
|
cf182b2fe7 | ||
|
|
996af08d6e | ||
|
|
130a7fef0b | ||
|
|
99a17e4a0c | ||
|
|
0e074e68ca | ||
|
|
df5525bc7a | ||
|
|
70cb7164ce | ||
|
|
fc567c2f4a | ||
|
|
ec76321206 | ||
|
|
bf75e9f4b7 | ||
|
|
3ea2509b6d | ||
|
|
07f439b900 | ||
|
|
ae64d8f8ff | ||
|
|
58bbfec87f | ||
|
|
4442b46603 | ||
|
|
a31c303c23 | ||
|
|
ac5b7e5775 | ||
|
|
696c51b113 | ||
|
|
990bd6fb47 | ||
|
|
285a898ba9 | ||
|
|
ba30af5182 | ||
|
|
5250049e08 | ||
|
|
c7ba7fecbc | ||
|
|
abfc847793 | ||
|
|
7d1c0268f5 | ||
|
|
b6145695cc | ||
|
|
0cf60ab214 | ||
|
|
a038960a4c | ||
|
|
cb2361c248 | ||
|
|
b799a48c8a | ||
|
|
9a775cd9d4 | ||
|
|
96e207676f | ||
|
|
ef92865886 | ||
|
|
857177b5b7 | ||
|
|
5fcb68ac65 | ||
|
|
8138893210 | ||
|
|
e1ef489706 | ||
|
|
e2f8aaf505 | ||
|
|
60e2ada31a | ||
|
|
0064e557f1 | ||
|
|
f8a50e09b7 | ||
|
|
a6117db46e | ||
|
|
ec187af09d | ||
|
|
7bc5be8db5 | ||
|
|
a29a8b246c | ||
|
|
8d16ae9188 |
55
.github/workflows/build_iotm.yml
vendored
Normal file
55
.github/workflows/build_iotm.yml
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
env:
|
||||
BOARDS: '["esp8266_4mb", "esp8266_16mb", "esp32_4mb3f", "esp32c3m_4mb", "esp32s2_4mb", "esp32s3_16mb"]'
|
||||
|
||||
name: Build Firmware
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
generate-matrix:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
matrix: ${{ steps.set_matrix.outputs.json }}
|
||||
steps:
|
||||
- name: Prepare matrix JSON Object
|
||||
id: set_matrix
|
||||
uses: nickofthyme/object-remap@v2.0.0
|
||||
with:
|
||||
__case: kebab
|
||||
board: ${{ env.BOARDS }}
|
||||
|
||||
build:
|
||||
needs: [ generate-matrix ]
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix: ${{ fromJSON(needs.generate-matrix.outputs.matrix) }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: 'ver4dev'
|
||||
- name: Run PrepareProject.py -b ${{ matrix.board }}
|
||||
run: python3 ./PrepareProject.py -b ${{ matrix.board }}
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install platformio
|
||||
- name: Run PlatformIO
|
||||
if: always()
|
||||
run: platformio run
|
||||
- name: Build FS
|
||||
if: always()
|
||||
run: platformio run -t buildfs --disable-auto-clean
|
||||
- name: Rearrange Artifacts
|
||||
run: |
|
||||
mkdir -p artifacts/${{ matrix.board }}
|
||||
find .pio/build/${{ matrix.board }} -name "*.bin" -exec mv {} artifacts/${{ matrix.board }} \;
|
||||
working-directory: ${{ github.workspace }}
|
||||
- name: Attach artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: firmware-${{ matrix.board }}-${{ github.run_number }}
|
||||
path: artifacts/${{ matrix.board }}
|
||||
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
.pio
|
||||
.vscode
|
||||
10
.vscode/extensions.json
vendored
Normal file
10
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
"ms-vscode.cpptools-extension-pack"
|
||||
]
|
||||
}
|
||||
582
Cmd.ino
582
Cmd.ino
@@ -1,582 +0,0 @@
|
||||
void CMD_init() {
|
||||
|
||||
sCmd.addCommand("button", button);
|
||||
sCmd.addCommand("buttonSet", buttonSet);
|
||||
sCmd.addCommand("pinSet", pinSet);
|
||||
|
||||
sCmd.addCommand("pwm", pwm);
|
||||
sCmd.addCommand("pwmSet", pwmSet);
|
||||
|
||||
sCmd.addCommand("switch", switch_);
|
||||
|
||||
sCmd.addCommand("analog", analog);
|
||||
sCmd.addCommand("level", level);
|
||||
sCmd.addCommand("dallas", dallas);
|
||||
|
||||
sCmd.addCommand("dhtT", dhtT);
|
||||
sCmd.addCommand("dhtH", dhtH);
|
||||
sCmd.addCommand("dhtPerception", dhtPerception);
|
||||
sCmd.addCommand("dhtComfort", dhtComfort);
|
||||
|
||||
sCmd.addCommand("logging", logging);
|
||||
|
||||
sCmd.addCommand("inputDigit", inputDigit);
|
||||
sCmd.addCommand("digitSet", digitSet);
|
||||
|
||||
sCmd.addCommand("inputTime", inputTime);
|
||||
sCmd.addCommand("timeSet", timeSet);
|
||||
|
||||
sCmd.addCommand("timerStart", timerStart);
|
||||
sCmd.addCommand("timerStop", timerStop);
|
||||
|
||||
sCmd.addCommand("text", text);
|
||||
sCmd.addCommand("textSet", textSet);
|
||||
|
||||
|
||||
sCmd.addCommand("mqtt", mqttOrderSend);
|
||||
sCmd.addCommand("http", httpOrderSend);
|
||||
sCmd.addCommand("push", pushControl);
|
||||
|
||||
|
||||
handle_time_init();
|
||||
|
||||
//======новые виджеты ver2.0=======//
|
||||
/*
|
||||
sCmd.addCommand("inputText", inputText);
|
||||
sCmd.addCommand("inputTextSet", inputTextSet);
|
||||
|
||||
sCmd.addCommand("inputTime", inputTime);
|
||||
sCmd.addCommand("inputTimeSet", inputTimeSet);
|
||||
|
||||
sCmd.addCommand("inputDate", inputDate);
|
||||
sCmd.addCommand("inputDateSet", inputDateSet);
|
||||
|
||||
sCmd.addCommand("inputDate", inputDate);
|
||||
|
||||
//sCmd.addCommand("inputDropdown", inputDropdown);
|
||||
*/
|
||||
//=================================//
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==========================================================================================================
|
||||
//==========================================Модуль кнопок===================================================
|
||||
void button() {
|
||||
|
||||
String button_number = sCmd.next();
|
||||
String button_param = sCmd.next();
|
||||
String viget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String start_state = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
|
||||
jsonWrite(optionJson, "button_param" + button_number, button_param);
|
||||
jsonWrite(configJson, "buttonSet" + button_number, start_state);
|
||||
|
||||
if (isDigitStr (button_param)) {
|
||||
pinMode(button_param.toInt(), OUTPUT);
|
||||
digitalWrite(button_param.toInt(), start_state.toInt());
|
||||
}
|
||||
|
||||
if (button_param == "scenario") {
|
||||
jsonWrite(configSetup, "scenario", start_state);
|
||||
Scenario_init();
|
||||
saveConfig();
|
||||
}
|
||||
|
||||
if (button_param.indexOf("line") != -1) {
|
||||
String str = button_param;
|
||||
while (str.length() != 0) {
|
||||
if (str == "") return;
|
||||
String tmp = selectToMarker (str, ","); //line1,
|
||||
String number = deleteBeforeDelimiter(tmp, "e"); //1,
|
||||
number.replace(",", "");
|
||||
Serial.println(number);
|
||||
int number_int = number.toInt();
|
||||
scenario_line_status[number_int] = start_state.toInt();
|
||||
str = deleteBeforeDelimiter(str, ",");
|
||||
}
|
||||
}
|
||||
createViget (viget_name, page_name, page_number, "vigets/viget.toggle.json", "buttonSet" + button_number);
|
||||
}
|
||||
|
||||
void buttonSet() {
|
||||
|
||||
String button_number = sCmd.next();
|
||||
String button_state = sCmd.next();
|
||||
String button_param = jsonRead(optionJson, "button_param" + button_number);
|
||||
|
||||
if (button_param != "na" || button_param != "scenario" || button_param.indexOf("line") != -1) {
|
||||
digitalWrite(button_param.toInt(), button_state.toInt());
|
||||
}
|
||||
|
||||
if (button_param == "scenario") {
|
||||
jsonWrite(configSetup, "scenario", button_state);
|
||||
Scenario_init();
|
||||
saveConfig();
|
||||
}
|
||||
|
||||
if (button_param.indexOf("line") != -1) {
|
||||
String str = button_param;
|
||||
while (str.length() != 0) {
|
||||
if (str == "") return;
|
||||
String tmp = selectToMarker (str, ","); //line1,
|
||||
String number = deleteBeforeDelimiter(tmp, "e"); //1,
|
||||
number.replace(",", "");
|
||||
Serial.println(number);
|
||||
int number_int = number.toInt();
|
||||
scenario_line_status[number_int] = button_state.toInt();
|
||||
str = deleteBeforeDelimiter(str, ",");
|
||||
}
|
||||
}
|
||||
|
||||
eventGen ("buttonSet", button_number);
|
||||
|
||||
jsonWrite(configJson, "buttonSet" + button_number, button_state);
|
||||
sendSTATUS("buttonSet" + button_number, button_state);
|
||||
}
|
||||
|
||||
void pinSet() {
|
||||
|
||||
String pin_number = sCmd.next();
|
||||
String pin_state = sCmd.next();
|
||||
pinMode(pin_number.toInt(), OUTPUT);
|
||||
digitalWrite(pin_number.toInt(), pin_state.toInt());
|
||||
|
||||
}
|
||||
//==================================================================================================================
|
||||
//==========================================Модуль управления ШИМ===================================================
|
||||
void pwm() {
|
||||
|
||||
static boolean flag = true;
|
||||
String pwm_number = sCmd.next();
|
||||
String pwm_pin = sCmd.next();
|
||||
String viget_name = sCmd.next();
|
||||
viget_name.replace("#", " ");
|
||||
String page_name = sCmd.next();
|
||||
String start_state = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
|
||||
|
||||
uint8_t pwm_pin_int = pwm_pin.toInt();
|
||||
jsonWrite(optionJson, "pwm_pin" + pwm_number, pwm_pin);
|
||||
pinMode(pwm_pin_int, INPUT);
|
||||
analogWrite(pwm_pin_int, start_state.toInt());
|
||||
jsonWrite(configJson, "pwmSet" + pwm_number, start_state);
|
||||
|
||||
createViget (viget_name, page_name, page_number, "vigets/viget.range.json", "pwmSet" + pwm_number);
|
||||
}
|
||||
|
||||
void pwmSet() {
|
||||
|
||||
String pwm_number = sCmd.next();
|
||||
String pwm_state = sCmd.next();
|
||||
int pwm_state_int = pwm_state.toInt();
|
||||
|
||||
int pin = jsonReadtoInt(optionJson, "pwm_pin" + pwm_number);
|
||||
analogWrite(pin, pwm_state_int);
|
||||
|
||||
eventGen ("pwmSet", pwm_number);
|
||||
|
||||
jsonWrite(configJson, "pwmSet" + pwm_number, pwm_state);
|
||||
sendSTATUS("pwmSet" + pwm_number, pwm_state);
|
||||
}
|
||||
//==================================================================================================================
|
||||
//==========================================Модуль физической кнопки================================================
|
||||
void switch_ () {
|
||||
|
||||
String switch_number = sCmd.next();
|
||||
String switch_pin = sCmd.next();
|
||||
String switch_delay = sCmd.next();
|
||||
|
||||
buttons[switch_number.toInt()].attach(switch_pin.toInt());
|
||||
buttons[switch_number.toInt()].interval(switch_delay.toInt());
|
||||
but[switch_number.toInt()] = true;
|
||||
}
|
||||
|
||||
void handleButton() {
|
||||
|
||||
static uint8_t switch_number = 1;
|
||||
|
||||
if (but[switch_number]) {
|
||||
buttons[switch_number].update();
|
||||
if (buttons[switch_number].fell()) {
|
||||
|
||||
eventGen ("switchSet", String(switch_number));
|
||||
|
||||
jsonWrite(configJson, "switchSet" + String(switch_number), "1");
|
||||
}
|
||||
if (buttons[switch_number].rose()) {
|
||||
|
||||
eventGen ("switchSet", String(switch_number));
|
||||
|
||||
jsonWrite(configJson, "switchSet" + String(switch_number), "0");
|
||||
}
|
||||
}
|
||||
switch_number++;
|
||||
if (switch_number == NUM_BUTTONS) switch_number = 0;
|
||||
}
|
||||
|
||||
//=====================================================================================================================================
|
||||
//=========================================Добавление окна ввода цифры=================================================================
|
||||
void inputDigit() {
|
||||
String value_name = sCmd.next();
|
||||
String number = value_name.substring(5);
|
||||
String viget_name = sCmd.next();
|
||||
viget_name.replace("#", " ");
|
||||
String page_name = sCmd.next();
|
||||
page_name.replace("#", " ");
|
||||
String start_state = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
jsonWrite(configJson, "digitSet" + number, start_state);
|
||||
createViget (viget_name, page_name, page_number, "vigets/viget.inputNum.json", "digitSet" + number);
|
||||
}
|
||||
void digitSet() {
|
||||
String number = sCmd.next();
|
||||
String value = sCmd.next();
|
||||
jsonWrite(configJson, "digitSet" + number, value);
|
||||
sendSTATUS("digitSet" + number, value);
|
||||
}
|
||||
//=====================================================================================================================================
|
||||
//=========================================Добавление окна ввода времени===============================================================
|
||||
void inputTime() {
|
||||
String value_name = sCmd.next();
|
||||
String number = value_name.substring(4);
|
||||
String viget_name = sCmd.next();
|
||||
viget_name.replace("#", " ");
|
||||
String page_name = sCmd.next();
|
||||
page_name.replace("#", " ");
|
||||
String start_state = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
start_state.replace(":", ".");
|
||||
jsonWrite(configJson, "timeSet" + number, start_state);
|
||||
start_state.replace(".", ":");
|
||||
createViget (viget_name, page_name, page_number, "vigets/viget.inputTime.json", "timeSet" + number);
|
||||
}
|
||||
void timeSet() {
|
||||
String number = sCmd.next();
|
||||
String value = sCmd.next();
|
||||
value.replace(":", ".");
|
||||
jsonWrite(configJson, "timeSet" + number, value);
|
||||
value.replace(".", ":");
|
||||
sendSTATUS("timeSet" + number, value);
|
||||
}
|
||||
|
||||
//=====================================================================================================================================
|
||||
//=========================================Добавление текстового виджета============================================================
|
||||
void text() {
|
||||
|
||||
String number = sCmd.next();
|
||||
String viget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
|
||||
createViget (viget_name, page_name, page_number, "vigets/viget.anydata.json", "textSet" + number);
|
||||
}
|
||||
|
||||
|
||||
void textSet() {
|
||||
|
||||
String number = sCmd.next();
|
||||
String text = sCmd.next();
|
||||
text.replace("_", " ");
|
||||
|
||||
if (text.indexOf("-time") >= 0) {
|
||||
text.replace("-time", "");
|
||||
String time = GetTime();
|
||||
time.replace(":", ".");
|
||||
text = GetDataDigital() + " " + time + " " + text;
|
||||
}
|
||||
|
||||
jsonWrite(configJson, "textSet" + number, text);
|
||||
sendSTATUS("textSet" + number, text);
|
||||
}
|
||||
|
||||
void handle_time_init() {
|
||||
ts.add(TIME, 1000, [&](void*) {
|
||||
|
||||
String tmp = GetTimeWOsec();
|
||||
tmp.replace(":", ".");
|
||||
jsonWrite(configJson, "timenowSet", tmp);
|
||||
eventGen ("timenowSet", "");
|
||||
|
||||
}, nullptr, true);
|
||||
}
|
||||
//====================================================================================================================================================
|
||||
/*
|
||||
void inputText() {
|
||||
String number = sCmd.next();
|
||||
String viget_name = sCmd.next();
|
||||
viget_name.replace("#", " ");
|
||||
String page_name = sCmd.next();
|
||||
page_name.replace("#", " ");
|
||||
String start_state = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
jsonWrite(configJson, "inputTextSet" + number, start_state);
|
||||
createViget (viget_name, page_name, page_number, "vigets/viget.inputText.json", "inputTextSet" + number);
|
||||
}
|
||||
void inputTextSet() {
|
||||
String number = sCmd.next();
|
||||
String value = sCmd.next();
|
||||
jsonWrite(configJson, "inputTextSet" + number, value);
|
||||
sendSTATUS("inputTextSet" + number, value);
|
||||
}
|
||||
|
||||
void inputTime() {
|
||||
String number = sCmd.next();
|
||||
String viget_name = sCmd.next();
|
||||
viget_name.replace("#", " ");
|
||||
String page_name = sCmd.next();
|
||||
page_name.replace("#", " ");
|
||||
String start_state = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
jsonWrite(configJson, "inputTimeSet" + number, start_state);
|
||||
createViget (viget_name, page_name, page_number, "vigets/viget.inputTime.json", "inputTimeSet" + number);
|
||||
}
|
||||
void inputTimeSet() {
|
||||
String number = sCmd.next();
|
||||
String value = sCmd.next();
|
||||
value.replace(":", ".");
|
||||
jsonWrite(configJson, "inputTimeSet" + number, value);
|
||||
value.replace(".", ":");
|
||||
sendSTATUS("inputTimeSet" + number, value);
|
||||
}
|
||||
|
||||
|
||||
void inputDate() {
|
||||
String number = sCmd.next();
|
||||
String viget_name = sCmd.next();
|
||||
viget_name.replace("#", " ");
|
||||
String page_name = sCmd.next();
|
||||
page_name.replace("#", " ");
|
||||
String start_state = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
jsonWrite(configJson, "inputDateSet" + number, start_state);
|
||||
createViget (viget_name, page_name, page_number, "vigets/viget.inputDate.json", "inputDateSet" + number);
|
||||
}
|
||||
void inputDateSet() {
|
||||
String number = sCmd.next();
|
||||
String value = sCmd.next();
|
||||
jsonWrite(configJson, "inputDateSet" + number, value);
|
||||
sendSTATUS("inputDateSet" + number, value);
|
||||
}
|
||||
*/
|
||||
//=================================================Глобальные команды удаленного управления===========================================================
|
||||
|
||||
void mqttOrderSend() {
|
||||
|
||||
String id = sCmd.next();
|
||||
String order = sCmd.next();
|
||||
|
||||
String all_line = prefix + "/" + id + "/order";
|
||||
//Serial.print(all_line);
|
||||
//Serial.print("->");
|
||||
//Serial.println(order);
|
||||
int send_status = client.publish (all_line.c_str(), order.c_str(), false);
|
||||
}
|
||||
|
||||
void httpOrderSend() {
|
||||
|
||||
String ip = sCmd.next();
|
||||
String order = sCmd.next();
|
||||
order.replace("_", "%20");
|
||||
String url = "http://" + ip + "/cmd?command=" + order;
|
||||
getURL(url);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==============================================================================================================================
|
||||
//============================выполнение команд (в лупе) по очереди из строки order=============================================
|
||||
void handleCMD_loop() {
|
||||
|
||||
if (order_loop != "") {
|
||||
|
||||
String tmp = selectToMarker(order_loop, ","); //выделяем из страки order первую команду rel 5 1,
|
||||
sCmd.readStr(tmp); //выполняем первую команду
|
||||
Serial.println("[ORDER] => " + order_loop);
|
||||
order_loop = deleteBeforeDelimiter(order_loop, ","); //осекаем выполненную команду
|
||||
}
|
||||
}
|
||||
|
||||
//=============================выполнение команд (через период) по очереди из строки order=======================================
|
||||
/*void handleCMD_ticker() {
|
||||
|
||||
ts.add(CMD, CMD_update_int, [&](void*) {
|
||||
if (!busy) {
|
||||
if (order_ticker != "") {
|
||||
|
||||
String tmp = selectToMarker(order_ticker, ","); //выделяем из страки order первую команду pus title body
|
||||
if (tmp != "no_command") sCmd.readStr(tmp); //выполняем первую команду
|
||||
Serial.println("order_ticker => " + order_ticker);
|
||||
order_ticker = deleteBeforeDelimiter(order_ticker, ","); //осекаем выполненную команду
|
||||
}
|
||||
}
|
||||
}, nullptr, true);
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
//=======================================================================================================================================
|
||||
//=======================================================================================================================================
|
||||
void txtExecution(String file) {
|
||||
|
||||
String command_all = readFile(file, 2048) + "\r\n"; //2048
|
||||
|
||||
command_all.replace("\r\n", "\n");
|
||||
command_all.replace("\r", "\n");
|
||||
|
||||
while (command_all.length() != 0) {
|
||||
|
||||
String tmp = selectToMarker (command_all, "\n");
|
||||
//if (tmp.indexOf("//") < 0)
|
||||
sCmd.readStr(tmp);
|
||||
command_all = deleteBeforeDelimiter(command_all, "\n");
|
||||
}
|
||||
}
|
||||
void stringExecution(String str) {
|
||||
|
||||
String command_all = str + "\r\n"; //"\r\n"
|
||||
|
||||
command_all.replace("\r\n", "\n");
|
||||
command_all.replace("\r", "\n");
|
||||
|
||||
while (command_all.length() != 0) {
|
||||
|
||||
String tmp = selectToMarker (command_all, "\n");
|
||||
//if (tmp.indexOf("//") < 0)
|
||||
sCmd.readStr(tmp);
|
||||
command_all = deleteBeforeDelimiter(command_all, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================================================================
|
||||
//===============================================Создание виджетов=======================================================
|
||||
|
||||
void createViget (String viget_name, String page_name, String page_number, String file, String topic) {
|
||||
|
||||
String viget;
|
||||
viget = readFile(file, 1024);
|
||||
|
||||
if (viget == "Failed") return;
|
||||
if (viget == "Large") return;
|
||||
|
||||
viget_name.replace("#", " ");
|
||||
page_name.replace("#", " ");
|
||||
|
||||
jsonWrite(viget, "page", page_name);
|
||||
jsonWrite(viget, "order", page_number);
|
||||
jsonWrite(viget, "descr", viget_name);
|
||||
jsonWrite(viget, "topic", prex + "/" + topic);
|
||||
all_vigets += viget + "\r\n";
|
||||
viget = "";
|
||||
}
|
||||
|
||||
/*
|
||||
void createViget (String viget_name, String page_name, String page_number, String file, String topic, String key, String value) {
|
||||
|
||||
String viget;
|
||||
viget = readFile(file, 1024);
|
||||
|
||||
if (viget == "Failed") return;
|
||||
if (viget == "Large") return;
|
||||
|
||||
viget_name.replace("#", " ");
|
||||
page_name.replace("#", " ");
|
||||
|
||||
value.replace("#", " ");
|
||||
|
||||
viget = vidgetConfigWrite(viget, key, value);
|
||||
|
||||
jsonWrite(viget, "page", page_name);
|
||||
jsonWrite(viget, "pageId", page_number);
|
||||
jsonWrite(viget, "descr", viget_name);
|
||||
jsonWrite(viget, "topic", prex + "/" + topic);
|
||||
|
||||
all_vigets += viget + "\r\n";
|
||||
viget = "";
|
||||
}
|
||||
|
||||
void createViget (String viget_name, String page_name, String page_number, String file, String topic, String key, String value, String key2, String value2) {
|
||||
|
||||
String viget;
|
||||
viget = readFile(file, 1024);
|
||||
|
||||
if (viget == "Failed") return;
|
||||
if (viget == "Large") return;
|
||||
|
||||
viget_name.replace("#", " ");
|
||||
page_name.replace("#", " ");
|
||||
|
||||
value.replace("#", " ");
|
||||
|
||||
viget = vidgetConfigWrite(viget, key, value);
|
||||
viget = vidgetConfigWrite(viget, key2, value2);
|
||||
|
||||
jsonWrite(viget, "page", page_name);
|
||||
jsonWrite(viget, "pageId", page_number);
|
||||
jsonWrite(viget, "descr", viget_name);
|
||||
jsonWrite(viget, "topic", prex + "/" + topic);
|
||||
|
||||
all_vigets += viget + "\r\n";
|
||||
viget = "";
|
||||
}
|
||||
*/
|
||||
String vidgetConfigWrite(String viget, String key, String value) {
|
||||
|
||||
if (viget == "") return "";
|
||||
if (viget == "{}") return "";
|
||||
int psn1 = viget.indexOf("{");
|
||||
if (psn1 != -1) {
|
||||
psn1 = viget.indexOf("{", psn1 + 1);
|
||||
if (psn1 != -1) {
|
||||
int psn2 = viget.indexOf("}", psn1);
|
||||
String WigetConfig = viget.substring(psn1, psn2) + "}";
|
||||
jsonWrite(WigetConfig, key, value);
|
||||
String part1 = viget.substring(0, psn1);
|
||||
viget = part1 + WigetConfig + "}";
|
||||
return viget;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//============разное
|
||||
|
||||
/*
|
||||
void delAlert() {
|
||||
|
||||
String alert_id = sCmd.next();
|
||||
delViget(alert_id);
|
||||
sendAllWigets();
|
||||
}
|
||||
|
||||
|
||||
void delViget(String text_in_viget) {
|
||||
String viget = all_vigets;
|
||||
while (viget.length() != 0) {
|
||||
String tmp = selectToMarkerPlus (viget, "\r\n", 2);
|
||||
if (tmp.indexOf(text_in_viget) > 0) {
|
||||
|
||||
all_vigets.replace(tmp, "");
|
||||
//Serial.println(all_vigets);
|
||||
|
||||
viget = deleteBeforeDelimiter(viget, "\r\n");
|
||||
} else {
|
||||
viget = deleteBeforeDelimiter(viget, "\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
BIN
ESP32FS.rar
BIN
ESP32FS.rar
Binary file not shown.
BIN
ESP8266FS.rar
BIN
ESP8266FS.rar
Binary file not shown.
72
Init.ino
72
Init.ino
@@ -1,72 +0,0 @@
|
||||
void All_init() {
|
||||
|
||||
server.on("/all_modules_init", HTTP_GET, [](AsyncWebServerRequest * request) {
|
||||
Device_init();
|
||||
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
|
||||
});
|
||||
|
||||
|
||||
server.on("/scenario", HTTP_GET, [](AsyncWebServerRequest * request) {
|
||||
if (request->hasArg("status")) {
|
||||
jsonWrite(configSetup, "scenario", request->getParam("status")->value());
|
||||
}
|
||||
saveConfig();
|
||||
Scenario_init();
|
||||
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
|
||||
});
|
||||
|
||||
server.on("/cleanlog", HTTP_GET, [](AsyncWebServerRequest * request) {
|
||||
SPIFFS.remove("/log.analog.txt");
|
||||
SPIFFS.remove("/log.dallas.txt");
|
||||
SPIFFS.remove("/log.level.txt");
|
||||
SPIFFS.remove("/log.ph.txt");
|
||||
SPIFFS.remove("/log.txt");
|
||||
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
|
||||
});
|
||||
|
||||
Device_init();
|
||||
Scenario_init();
|
||||
Timer_countdown_init();
|
||||
}
|
||||
|
||||
void Device_init() {
|
||||
|
||||
//SENSORS-SECTION
|
||||
ts.remove(ANALOG_);
|
||||
ts.remove(LEVEL);
|
||||
ts.remove(DALLAS);
|
||||
ts.remove(DHTT);
|
||||
ts.remove(DHTH);
|
||||
//================
|
||||
|
||||
all_vigets = "";
|
||||
txtExecution("firmware.config.txt");
|
||||
//outcoming_date();
|
||||
}
|
||||
//-------------------------------сценарии-----------------------------------------------------
|
||||
|
||||
void Scenario_init() {
|
||||
if (jsonRead(configSetup, "scenario") == "1") {
|
||||
scenario = readFile("firmware.scenario.txt", 2048);
|
||||
}
|
||||
}
|
||||
|
||||
void up_time() {
|
||||
uint32_t ss = millis() / 1000;
|
||||
uint32_t mm = ss / 60;
|
||||
uint32_t hh = mm / 60;
|
||||
uint32_t dd = hh / 24;
|
||||
|
||||
if (mm != 0) {
|
||||
Serial.println(String(mm) + " min");
|
||||
jsonWrite(configJson, "uptime", String(mm) + " min");
|
||||
}
|
||||
if (hh != 0) {
|
||||
Serial.println(String(hh) + " hours");
|
||||
jsonWrite(configJson, "uptime", String(hh) + " hours");
|
||||
}
|
||||
if (dd != 0) {
|
||||
Serial.println(String(dd) + " days");
|
||||
jsonWrite(configJson, "uptime", String(dd) + " days");
|
||||
}
|
||||
}
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Dmitry Borisenko
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
293
PrepareProject.py
Normal file
293
PrepareProject.py
Normal file
@@ -0,0 +1,293 @@
|
||||
# PrepareProject.py - инструмент для подготовки проекта к компиляции.
|
||||
# Необходимо вызвать при изменении персональных настроек или состава модулей.
|
||||
#
|
||||
# При отсутствии файла с персональными настройками, myProfile.json будет создан автоматически
|
||||
# python PrepareProject.py
|
||||
#
|
||||
# Если myProfile.json уже существует, можно запустить PrepareProject.py с параметром -u или --update для обновления списка модулей.
|
||||
# Данная функция будет полезна для разработчиков при добавлении модуля в папку src/modules
|
||||
# python PrepareProject.py --update
|
||||
# python PrepareProject.py -u
|
||||
#
|
||||
# Возможно использовать несколько вариантов персональных настроек и уточнять имя файла при запуске с использованием параметра -p или -profile
|
||||
# python PrepareProject.py --profile <ИмяФайла>
|
||||
# python PrepareProject.py -p <ИмяФайла>
|
||||
#
|
||||
# Используя параметры -b или --board <board_name> можно уточнить для какой платы нужно подготовить проект
|
||||
#
|
||||
# поддерживаемые контроллеры (профили):
|
||||
# esp8266_4mb
|
||||
# esp8266_16mb
|
||||
# esp32_4mb
|
||||
# esp32cam_4mb
|
||||
# esp32_16mb
|
||||
# esp32s2_4mb
|
||||
# esp8266_1mb
|
||||
# esp8266_1mb_ota
|
||||
# esp8285_1mb
|
||||
# esp8285_1mb_ota
|
||||
# esp8266_2mb
|
||||
# esp8266_2mb_ota
|
||||
|
||||
|
||||
import configparser
|
||||
import os, json, sys, getopt
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
|
||||
|
||||
config = configparser.ConfigParser() # создаём объекта парсера INI
|
||||
|
||||
def printHelp():
|
||||
print('''Usage:
|
||||
PrepareProject.py
|
||||
-p --profile <file.json_in_root_folder>
|
||||
-u --update
|
||||
-h --help
|
||||
-b --board <board_name>''')
|
||||
with open('myProfile.json', "r", encoding='utf-8') as read_file:
|
||||
profJson = json.load(read_file)
|
||||
print ('')
|
||||
print ('Choose a board from the list:')
|
||||
# print(profJson['projectProp']['platformio']['comments_default_envs'])
|
||||
print (' ', end='')
|
||||
cnt = 0
|
||||
for envs in profJson['projectProp']['platformio']['envs']:
|
||||
if cnt == 5:
|
||||
cnt = 0
|
||||
print('')
|
||||
print(' ', end='')
|
||||
print(envs['name'] + ', ', end='')
|
||||
cnt = cnt + 1
|
||||
|
||||
|
||||
def updateModulesInProfile(profJson):
|
||||
profJson["modules"] = {}
|
||||
for root,d_names,f_names in os.walk("src/modules"):
|
||||
for fname in f_names:
|
||||
if fname == "modinfo.json":
|
||||
with open(os.path.join(root, fname), "r", encoding='utf-8') as read_file:
|
||||
modinfoJson = json.load(read_file)
|
||||
# проверяем есть ли уже узловой элемент и если нет, то создаем
|
||||
if not modinfoJson['menuSection'] in profJson["modules"]:
|
||||
listFromFirstElement = {modinfoJson['menuSection']: []}
|
||||
listFromFirstElement.update(profJson["modules"])
|
||||
profJson["modules"] = listFromFirstElement
|
||||
# добавляем информацию о модуле в узловой элемент
|
||||
profJson["modules"][modinfoJson['menuSection']].append({
|
||||
'path': os.path.normpath(root).replace("\\", "/"),
|
||||
'active': modinfoJson['defActive']
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
update = False # признак необходимости обновить список модулей
|
||||
profile = 'myProfile.json' # имя профиля. Будет заменено из консоли, если указано при старте
|
||||
selectDevice = '' # имя платы для которой хотим собрать, если её указали к командной строке -b <board>
|
||||
|
||||
argv = sys.argv[1:]
|
||||
try:
|
||||
opts, args = getopt.getopt(argv, 'hp:ub:', ['help', 'profile=', 'update', 'board='])
|
||||
except getopt.GetoptError:
|
||||
print('Ошибка обработки параметров!')
|
||||
printHelp()
|
||||
sys.exit(2)
|
||||
|
||||
for opt, arg in opts:
|
||||
if opt in ("-h", "--help"):
|
||||
printHelp()
|
||||
sys.exit()
|
||||
elif opt in ("-p", "--profile"):
|
||||
print('Загрузка профиля из файла:' + arg)
|
||||
profile = arg
|
||||
elif opt in ("-u", "--update"):
|
||||
print('Создание новой конфигурации по исходным файлам!')
|
||||
update = True
|
||||
elif opt in ("-b", "--board"):
|
||||
print('Создание профиля для платы:' + arg)
|
||||
selectDevice = arg
|
||||
|
||||
if Path(profile).is_file():
|
||||
# подтягиваем уже существующий профиль
|
||||
with open(profile, "r", encoding='utf-8') as read_file:
|
||||
profJson = json.load(read_file)
|
||||
# если хотим обновить список модулей в существующем профиле
|
||||
if update:
|
||||
updateModulesInProfile(profJson)
|
||||
|
||||
# sortedListNames = sorted(profJson["modules"])
|
||||
# sortedModules = {}
|
||||
# for sortedModulName in sortedList:
|
||||
|
||||
# print(profJson)
|
||||
|
||||
with open(profile, "w", encoding='utf-8') as write_file:
|
||||
json.dump(profJson, write_file, ensure_ascii=False, indent=4, sort_keys=False)
|
||||
else:
|
||||
# если файла нет - создаем по образу настроек из проекта
|
||||
profJson = json.loads('{}')
|
||||
# копируем параметры IOTM из settings.json в новый профиль
|
||||
with open("data_svelte/settings.json", "r", encoding='utf-8') as read_file:
|
||||
profJson['iotmSettings'] = json.load(read_file)
|
||||
# устанавливаем параметры сборки
|
||||
profJson['projectProp'] = {
|
||||
'platformio': {
|
||||
'default_envs': 'esp8266_4mb'
|
||||
}
|
||||
}
|
||||
# загружаем список модулей для сборки
|
||||
updateModulesInProfile(profJson)
|
||||
# сохраняем новый профиль
|
||||
with open(profile, "w", encoding='utf-8') as write_file:
|
||||
json.dump(profJson, write_file, ensure_ascii=False, indent=4, sort_keys=False)
|
||||
|
||||
deviceName = ''
|
||||
if selectDevice == '':
|
||||
# определяем какое устройство используется в профиле
|
||||
deviceName = profJson['projectProp']['platformio']['default_envs']
|
||||
else:
|
||||
for envs in profJson['projectProp']['platformio']['envs']:
|
||||
if envs['name'] == selectDevice:
|
||||
deviceName = selectDevice
|
||||
if deviceName == '':
|
||||
deviceName = profJson['projectProp']['platformio']['default_envs']
|
||||
print(f"\x1b[1;31;31m Board ", selectDevice, " not found in ",profile,"!!! Use ",deviceName," \x1b[0m")
|
||||
|
||||
# заполняем папку /data файлами прошивки в зависимости от устройства
|
||||
if deviceName == 'esp8266_1mb_ota' or deviceName == 'esp8285_1mb_ota' or deviceName == 'esp8266_2mb_ota':
|
||||
shutil.copytree("data_lite", "data_svelte", symlinks=False, ignore=None, ignore_dangling_symlinks=False, dirs_exist_ok=True)
|
||||
else:
|
||||
shutil.copytree("data_full", "data_svelte", symlinks=False, ignore=None, ignore_dangling_symlinks=False, dirs_exist_ok=True)
|
||||
|
||||
deviceType = 'esp32*'
|
||||
if not 'esp32' in deviceName:
|
||||
deviceType = 'esp82*'
|
||||
if 'bk72' in deviceName:
|
||||
deviceType = 'bk72*'
|
||||
# генерируем файлы проекта на основе подготовленного профиля
|
||||
# заполняем конфигурационный файл прошивки параметрами из профиля
|
||||
with open("data_svelte/settings.json", "r", encoding='utf-8') as read_file:
|
||||
iotmJson = json.load(read_file)
|
||||
for key, value in profJson['iotmSettings'].items():
|
||||
iotmJson[key] = value
|
||||
with open("data_svelte/settings.json", "w", encoding='utf-8') as write_file:
|
||||
json.dump(iotmJson, write_file, ensure_ascii=False, indent=4, sort_keys=False)
|
||||
|
||||
|
||||
|
||||
# собираем меню прошивки из модулей
|
||||
# параллельно формируем список имен активных модулей
|
||||
# параллельно собираем необходимые активным модулям библиотеки для включения в компиляцию для текущего типа устройства (esp8266_4m, esp32_4mb, esp8266_1m, esp8266_1m_ota)
|
||||
activeModulesName = [] # список имен активных модулей
|
||||
allLibs = "" # подборка всех библиотек необходимых модулям для дальнейшей записи в конфигурацию platformio
|
||||
allDefs = "\n" # для каждого модуля создаем глобальный define
|
||||
itemsCount = 1
|
||||
includeDirs = "" # подборка путей ко всем модулям для дальнейшей записи в конфигурацию platformio
|
||||
itemsJson = json.loads('[{"name": "Выберите элемент", "num": 0}]')
|
||||
for section, modules in profJson['modules'].items():
|
||||
itemsJson.append({"header": section})
|
||||
for module in modules:
|
||||
if module['active']:
|
||||
with open(module['path'] + "/modinfo.json", "r", encoding='utf-8') as read_file:
|
||||
moduleJson = json.load(read_file)
|
||||
if 'moduleDefines' in moduleJson['about']:
|
||||
allDefs = allDefs + "\n".join("-D" + d for d in moduleJson['about']['moduleDefines'])
|
||||
if deviceName in moduleJson['usedLibs']: # проверяем поддерживает ли модуль текущее устройство
|
||||
if not 'exclude' in moduleJson['usedLibs'][deviceName]: # смотрим не нужно ли исключить данный модуль из указанной платы deviceName
|
||||
activeModulesName.append(moduleJson['about']['moduleName']) # запоминаем имена для использования на след шагах
|
||||
includeDirs = includeDirs + "\n+<" + module['path'].replace("src/", "") + ">" # запоминаем пути к модулям для компиляции
|
||||
for libPath in moduleJson['usedLibs'][deviceName]: # запоминаем библиотеки необходимые модулю для текущей платы
|
||||
allLibs = allLibs + "\n" + libPath
|
||||
for configItemsJson in moduleJson['configItem']:
|
||||
configItemsJson['num'] = itemsCount
|
||||
configItemsJson['name'] = str(itemsCount) + ". " + configItemsJson['name']
|
||||
itemsCount = itemsCount + 1
|
||||
configItemsJson['moduleName'] = moduleJson['about']['moduleName']
|
||||
itemsJson.append(configItemsJson)
|
||||
else: # В первую очередь ищем по имени deviceName, чтобы для данной платы можно было уточнить либы. Если не нашли плату по имени в usedLibs пробуем найти её по типу deviceType
|
||||
if deviceType in moduleJson['usedLibs']: # проверяем поддерживает ли модуль текущее устройство
|
||||
activeModulesName.append(moduleJson['about']['moduleName']) # запоминаем имена для использования на след шагах
|
||||
includeDirs = includeDirs + "\n+<" + module['path'].replace("src/", "") + ">" # запоминаем пути к модулям для компиляции
|
||||
for libPath in moduleJson['usedLibs'][deviceType]: # запоминаем библиотеки необходимые модулю для текущей платы
|
||||
allLibs = allLibs + "\n" + libPath
|
||||
for configItemsJson in moduleJson['configItem']:
|
||||
configItemsJson['num'] = itemsCount
|
||||
configItemsJson['name'] = str(itemsCount) + ". " + configItemsJson['name']
|
||||
itemsCount = itemsCount + 1
|
||||
itemsJson.append(configItemsJson)
|
||||
configItemsJson['moduleName'] = moduleJson['about']['moduleName']
|
||||
|
||||
with open("data_svelte/items.json", "w", encoding='utf-8') as write_file:
|
||||
json.dump(itemsJson, write_file, ensure_ascii=False, indent=4, sort_keys=False)
|
||||
|
||||
|
||||
# учитываем вызовы модулей в API.cpp
|
||||
allAPI_head = ""
|
||||
allAPI_exec = ""
|
||||
for activModuleName in activeModulesName:
|
||||
allAPI_head = allAPI_head + "\nvoid* getAPI_" + activModuleName + "(String subtype, String params);"
|
||||
allAPI_exec = allAPI_exec + "\nif ((tmpAPI = getAPI_" + activModuleName + "(subtype, params)) != nullptr) foundAPI = tmpAPI;"
|
||||
apicpp = '#include "ESPConfiguration.h"\n'
|
||||
apicpp = apicpp + allAPI_head
|
||||
apicpp = apicpp + '\n\nvoid* getAPI(String subtype, String params) {\nvoid* tmpAPI; void* foundAPI = nullptr;'
|
||||
apicpp = apicpp + allAPI_exec
|
||||
apicpp = apicpp + '\nreturn foundAPI;\n}'
|
||||
with open('src/modules/API.cpp', 'w') as f:
|
||||
f.write(apicpp)
|
||||
|
||||
# корректируем параметры platformio
|
||||
# собираем пути всех отключенных модулей для исключения их из процесса компиляции
|
||||
# excludeDirs = ""
|
||||
# for root,d_names,f_names in os.walk("src\\modules"):
|
||||
# for fname in f_names:
|
||||
# if fname == "modinfo.json":
|
||||
# with open(root + "\\" + fname, "r", encoding='utf-8') as read_file:
|
||||
# modinfoJson = json.load(read_file)
|
||||
# if not modinfoJson['about']['moduleName'] in activeModulesName:
|
||||
# excludeDirs = excludeDirs + "\n-<" + root.replace("src\\", "") + ">"
|
||||
|
||||
# фиксируем изменения в platformio.ini
|
||||
config.clear()
|
||||
config.read("platformio.ini")
|
||||
config["env:" + deviceName + "_fromitems"]["lib_deps"] = allLibs
|
||||
config["env:" + deviceName + "_fromitems"]["build_src_filter"] = includeDirs
|
||||
config["env:" + deviceName + "_fromitems"]["build_flags"] = allDefs
|
||||
config["platformio"]["default_envs"] = deviceName
|
||||
if "${env:" + deviceName + "_fromitems.build_flags}" not in config["env:" + deviceName]["build_flags"]:
|
||||
config["env:" + deviceName]["build_flags"] += "\n${env:" + deviceName + "_fromitems.build_flags}"
|
||||
# config["platformio"]["data_dir"] = profJson['projectProp']['platformio']['data_dir']
|
||||
with open("platformio.ini", 'w') as configFile:
|
||||
config.write(configFile)
|
||||
|
||||
|
||||
# сохраняем часть применяемого профиля в папку data_svelte для загрузки на контроллер и дальнейшего переиспользования
|
||||
print(f"Saving profile {profile} in /data_svelte/flashProfile.json")
|
||||
shortProfJson = json.loads('{}')
|
||||
shortProfJson['projectProp'] = {
|
||||
'platformio': {
|
||||
'default_envs': deviceName
|
||||
}
|
||||
}
|
||||
shortProfJson['modules'] = profJson['modules']
|
||||
with open("data_svelte/flashProfile.json", "w", encoding='utf-8') as write_file:
|
||||
json.dump(shortProfJson, write_file, ensure_ascii=False, indent=4, sort_keys=False)
|
||||
|
||||
|
||||
# import ctypes # An included library with Python install.
|
||||
# if update:
|
||||
# ctypes.windll.user32.MessageBoxW(0, "Модули профиля " + profile + " обновлены, а сам профиль применен, можно запускать компиляцию и прошивку.", "Операция завершена.", 0)
|
||||
# else:
|
||||
# ctypes.windll.user32.MessageBoxW(0, "Профиль " + profile + " применен, можно запускать компиляцию и прошивку.", "Операция завершена.", 0)
|
||||
|
||||
if update:
|
||||
shutil.copy(profile, "compilerProfile.json")
|
||||
print(f"\x1b[1;31;42m Profile modules " + profile + " updated, profile applied, you can run compilation and firmware.\x1b[0m")
|
||||
|
||||
else:
|
||||
print(f"\x1b[1;31;42m Profile ", profile, " applied, you can run compilation and firmware.\x1b[0m")
|
||||
|
||||
# print(f"\x1b[1;32;41m Операция завершена. \x1b[0m")
|
||||
|
||||
|
||||
37
PrepareServer.py
Normal file
37
PrepareServer.py
Normal file
@@ -0,0 +1,37 @@
|
||||
# подготавливаем папку для локального сервера обновлений
|
||||
# для этого компилируем проект и получаем бинарные файлы:
|
||||
# firmware.bin, littlefs.bin, partitions.bin и ver.json
|
||||
|
||||
import shutil
|
||||
import configparser
|
||||
import os, json, sys, getopt
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def copyFileIfExist(fileName, deviceName):
|
||||
srcFilePath = ".pio/build/" + deviceName + "/" + fileName
|
||||
dstFilePath = "iotm/" + deviceName + "/400/" + fileName
|
||||
if Path(srcFilePath).is_file():
|
||||
print("Ok...... \"" + srcFilePath + "\" на месте!")
|
||||
Path(dstFilePath).parent.mkdir(parents=True, exist_ok=True)
|
||||
shutil.copy(srcFilePath, dstFilePath)
|
||||
return True
|
||||
else:
|
||||
print("Error...... \"" + srcFilePath + "\" НЕ существует!")
|
||||
return False
|
||||
|
||||
|
||||
config = configparser.ConfigParser() # создаём объекта парсера INI
|
||||
config.read("platformio.ini")
|
||||
deviceName = config["platformio"]["default_envs"]
|
||||
|
||||
homeDir = os.path.expanduser('~')
|
||||
os.system(homeDir + "/.platformio/penv/Scripts/pio run")
|
||||
os.system(homeDir + "/.platformio/penv/Scripts/pio run -t buildfs --disable-auto-clean")
|
||||
|
||||
if copyFileIfExist("firmware.bin", deviceName) and copyFileIfExist("littlefs.bin", deviceName):
|
||||
copyFileIfExist("partitions.bin", deviceName)
|
||||
versionsJson = json.loads('{"' + deviceName + '": {"0": "400"}}')
|
||||
with open("iotm/ver.json", "w", encoding='utf-8') as write_file:
|
||||
json.dump(versionsJson, write_file, ensure_ascii=False, indent=4, sort_keys=False)
|
||||
print(f"\x1b[1;31;42m Сервер для обновления 'по воздуху' для " + deviceName + " подготовлен. Не забудьте установить расширение Live Server, запустить его и прописать в ESP IP вашего компьютера. Подробнее смотрите в WIKI: https://iotmanager.org/wiki.\x1b[0m")
|
||||
15
README.md
Normal file
15
README.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# IoTManager
|
||||
|
||||
This is a smart home based on esp8266 and esp32 microcontrollers. These microcontrollers gained their popularity due to their low cost. Each such microcontroller is able to connect to your home wifi router. They can be purchased at any robotics store or on aliexpress, there are also ready-made devices based on them. This microcontroller has a certain number of pins on which digital signals are generated. Various peripheral devices can be connected to it: sensors, relays, stepper motors, servo drives, etc.
|
||||
|
||||
Our firmware allows you to receive data from all these devices and manage them. The iot manager app available for ios and android is used to display the data. In order to connect devices and the application, a special mqtt server is needed, in other words, an mqtt broker. All devices are first connected to a wifi router, and then to this mqtt broker, the application is also connected to it. As a result, through the application you can manage devices from anywhere in the world, monitor sensor readings, build graphs and much more. Broker mqtt can be used in the cloud, such as wqtt.ru, or your own, raised, for example, on a single-board computer raspberry pi. There is also a second way to manage devices, it works even when you do not have the Internet - control through a web browser. All your devices will be available on one page. Both methods, through the application or through the web, work simultaneously with full mutual synchronization.
|
||||
|
||||
To achieve your goal, you only need three things:
|
||||
|
||||
1. Buy an esp microcontroller
|
||||
2. Download the app
|
||||
3. Get a cloud broker
|
||||
|
||||
If remote control and the application are not needed, then the last step can be omitted.
|
||||
|
||||
The logic of each device is configured using scripts. They are needed in order to teach the device to carry out your invented algorithms. You can assign any reaction to any action. The temperature has risen - the device will turn off the heater. Humidity has fallen and the level in the tank is more than 10% - the device will start watering, if not, it will send you a telegram notification that there is not enough water. These are just a few examples. Scenarios are created by you, and their flexibility will allow you to fulfill your every desire.
|
||||
98
Scenario.ino
98
Scenario.ino
@@ -1,98 +0,0 @@
|
||||
void handleScenario() {
|
||||
|
||||
if (jsonRead(configSetup, "scenario") == "1") {
|
||||
if ((jsonRead(optionJson, "scenario_status") != "")) {
|
||||
int i = 0;
|
||||
String str = scenario; //читаем переменную с сценариями (то что из файла на странице)
|
||||
str += "\n";
|
||||
str.replace("\r\n", "\n");
|
||||
str.replace("\r", "\n");
|
||||
while (str.length() != 0) {
|
||||
//-----------------------------------------------------------------------------------------------------------------------
|
||||
String tmp = selectToMarker (str, "end"); //выделяем первый сценарий из файла вместе с командами
|
||||
if (tmp == "") return;
|
||||
i++;
|
||||
|
||||
if (scenario_line_status[i] == 1) {
|
||||
//Serial.println(i);
|
||||
String condition = selectToMarker (tmp, "\n"); //выделяем первую строку самого сценария button1 = 1 (условие)
|
||||
String param_name = selectFromMarkerToMarker(condition, " " , 0);
|
||||
param_name = add_set(param_name); //из первой страки берем имя параметра button1 и вставляем в него Set и получаем buttonSet1
|
||||
if (param_name.indexOf("timenow") != -1){
|
||||
param_name = param_name + "Set";
|
||||
}
|
||||
String order = jsonRead(optionJson, "scenario_status"); //читаем весь файл событий
|
||||
String param = selectToMarker (order, ","); //читаем первое событие из файла событий
|
||||
if (param_name == param) { //если поступившее событие равно событию заданному buttonSet1 в файле начинаем его обработку
|
||||
|
||||
String sign = selectFromMarkerToMarker(condition, " " , 1); //читаем знак (=)
|
||||
String value = selectFromMarkerToMarker(condition, " " , 2); //читаем значение (1)
|
||||
if (value.indexOf("digit") != -1) {
|
||||
value = add_set(value);
|
||||
value = jsonRead(configJson, value);
|
||||
}
|
||||
if (value.indexOf("time") != -1) {
|
||||
value = add_set(value);
|
||||
value = jsonRead(configJson, value);
|
||||
}
|
||||
boolean flag = false; //если одно из значений совпало то только тогда начинаем выполнять комнады
|
||||
if (sign == "=") {
|
||||
if (jsonRead(configJson, param_name) == value) flag = true;
|
||||
}
|
||||
if (sign == "!=") {
|
||||
if (jsonRead(configJson, param_name) != value) flag = true;
|
||||
}
|
||||
if (sign == "<") {
|
||||
if (jsonRead(configJson, param_name).toInt() < value.toInt()) flag = true;
|
||||
}
|
||||
if (sign == ">") {
|
||||
if (jsonRead(configJson, param_name).toInt() > value.toInt()) flag = true;
|
||||
}
|
||||
if (sign == ">=") {
|
||||
if (jsonRead(configJson, param_name).toInt() >= value.toInt()) flag = true;
|
||||
}
|
||||
if (sign == "<=") {
|
||||
if (jsonRead(configJson, param_name).toInt() <= value.toInt()) flag = true;
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
tmp = deleteBeforeDelimiter(tmp, "\n"); //удаляем строку самого сценария оставляя только команды
|
||||
stringExecution(tmp); //выполняем все команды
|
||||
|
||||
Serial.println("[SCENARIO] '" + condition + "'");
|
||||
//Serial.println(" " + tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
str = deleteBeforeDelimiter(str, "end\n"); //удаляем первый сценарий
|
||||
//-----------------------------------------------------------------------------------------------------------------------
|
||||
}
|
||||
String tmp2 = jsonRead(optionJson, "scenario_status"); //читаем файл событий
|
||||
tmp2 = deleteBeforeDelimiter(tmp2, ","); //удаляем выполненное событие
|
||||
jsonWrite(optionJson, "scenario_status", tmp2); //записываем обновленный файл событий
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void eventGen (String event_name, String number) { //событие выглядит как имя плюс set плюс номер: button+Set+1
|
||||
|
||||
if (jsonRead(configSetup, "scenario") == "1") {
|
||||
String tmp = jsonRead(optionJson, "scenario_status") ; //генерирование события
|
||||
//Serial.println(event_name);
|
||||
jsonWrite(optionJson, "scenario_status", tmp + event_name + number + ",");
|
||||
}
|
||||
}
|
||||
|
||||
String add_set(String param_name) {
|
||||
String num1 = param_name.substring(param_name.length() - 1);
|
||||
String num2 = param_name.substring(param_name.length() - 2, param_name.length() - 1);
|
||||
if (isDigitStr(num1) && isDigitStr(num2)) {
|
||||
param_name = param_name.substring(0, param_name.length() - 2) + "Set" + num2 + num1;
|
||||
} else {
|
||||
if (isDigitStr(num1)) {
|
||||
param_name = param_name.substring(0, param_name.length() - 1) + "Set" + num1;
|
||||
}
|
||||
}
|
||||
return param_name;
|
||||
}
|
||||
400
Sensors.ino
400
Sensors.ino
@@ -1,400 +0,0 @@
|
||||
//===============================================================================================================================
|
||||
//=========================================Модуль аналогового сенсора============================================================
|
||||
void analog() {
|
||||
String pin = sCmd.next();
|
||||
String viget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String type = sCmd.next();
|
||||
String analog_start = sCmd.next();
|
||||
String analog_end = sCmd.next();
|
||||
String analog_start_out = sCmd.next();
|
||||
String analog_end_out = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
jsonWrite(optionJson, "analog_start", analog_start);
|
||||
jsonWrite(optionJson, "analog_end", analog_end);
|
||||
jsonWrite(optionJson, "analog_start_out", analog_start_out);
|
||||
jsonWrite(optionJson, "analog_end_out", analog_end_out);
|
||||
choose_viget_and_create(viget_name, page_name, page_number, type, "analog");
|
||||
ts.add(ANALOG_, analog_update_int, [&](void*) {
|
||||
static int analog_old;
|
||||
#ifdef ESP32
|
||||
//int pin_int = pin.toInt();
|
||||
int analog_in;// = analogRead(pin_int);
|
||||
#endif
|
||||
#ifdef ESP8266
|
||||
int analog_in = analogRead(A0);
|
||||
#endif
|
||||
jsonWrite(configJson, "analog_in", analog_in);
|
||||
int analog = map(analog_in,
|
||||
jsonReadtoInt(optionJson, "analog_start") ,
|
||||
jsonReadtoInt(optionJson, "analog_end"),
|
||||
jsonReadtoInt(optionJson, "analog_start_out"),
|
||||
jsonReadtoInt(optionJson, "analog_end_out"));
|
||||
jsonWrite(configJson, "analog", analog);
|
||||
// if (analog_old != analog) {
|
||||
eventGen ("analog", "");
|
||||
sendSTATUS("analog", String(analog));
|
||||
if (client.connected()) {
|
||||
Serial.println("[i] sensor analog send date " + String(analog));
|
||||
}
|
||||
// }
|
||||
analog_old = analog;
|
||||
}, nullptr, true);
|
||||
}
|
||||
|
||||
//===================================================================================================================================
|
||||
//=========================================Модуль измерения уровня в баке============================================================
|
||||
void level() {
|
||||
String viget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String type = sCmd.next();
|
||||
String empty_level = sCmd.next();
|
||||
String full_level = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
jsonWrite(optionJson, "empty_level", empty_level);
|
||||
jsonWrite(optionJson, "full_level", full_level);
|
||||
pinMode(14, OUTPUT);
|
||||
pinMode(12, INPUT);
|
||||
choose_viget_and_create(viget_name, page_name, page_number, type, "level");
|
||||
ts.add(LEVEL, tank_level_shooting_interval, [&](void*) {
|
||||
long duration_;
|
||||
int distance_cm;
|
||||
int level;
|
||||
static int level_old; //переменная static сохраняет свое значение между вызовами функции
|
||||
static int counter;
|
||||
digitalWrite(14, LOW);
|
||||
delayMicroseconds(2);
|
||||
digitalWrite(14, HIGH);
|
||||
delayMicroseconds(10);
|
||||
digitalWrite(14, LOW);
|
||||
duration_ = pulseIn(12, HIGH, 30000); // 3000 µs = 50cm // 30000 µs = 5 m
|
||||
distance_cm = duration_ / 29 / 2;
|
||||
distance_cm = medianFilter.filtered(distance_cm);//отсечение промахов медианным фильтром
|
||||
counter++;
|
||||
if (counter > tank_level_times_to_send) {
|
||||
counter = 0;
|
||||
jsonWrite(configJson, "level_in", distance_cm);
|
||||
level = map(distance_cm,
|
||||
jsonReadtoInt(optionJson, "empty_level"),
|
||||
jsonReadtoInt(optionJson, "full_level"), 0, 100);
|
||||
//jsonWrite(configJson, "level", level);
|
||||
//if (level_old != level) {
|
||||
eventGen ("level", "");
|
||||
sendSTATUS("level", String(level));
|
||||
if (client.connected()) {
|
||||
Serial.println("[i] sensor tank level send date " + String(level));
|
||||
}
|
||||
//}
|
||||
level_old = level;
|
||||
}
|
||||
}, nullptr, true);
|
||||
}
|
||||
|
||||
//==========================================================================================================================================
|
||||
//=========================================Модуль температурного сенсора ds18b20============================================================
|
||||
void dallas() {
|
||||
String pin = sCmd.next();
|
||||
String viget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String type = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
oneWire = new OneWire((uint8_t) pin.toInt());
|
||||
sensors.setOneWire(oneWire);
|
||||
sensors.begin();
|
||||
sensors.setResolution(12);
|
||||
choose_viget_and_create(viget_name, page_name, page_number, type, "dallas");
|
||||
ts.add(DALLAS, temp_update_int, [&](void*) {
|
||||
float temp = 0;
|
||||
static float temp_old;
|
||||
sensors.requestTemperatures();
|
||||
temp = sensors.getTempCByIndex(0);
|
||||
jsonWrite(configJson, "dallas", String(temp));
|
||||
//if (temp_old != temp) {
|
||||
eventGen ("dallas", "");
|
||||
sendSTATUS("dallas", String(temp));
|
||||
if (client.connected()) {
|
||||
Serial.println("[i] sensor dallas send date " + String(temp));
|
||||
}
|
||||
//}
|
||||
temp_old = temp;
|
||||
}, nullptr, true);
|
||||
}
|
||||
|
||||
|
||||
//======================================================================================================================
|
||||
//=========================================Модуль сенсоров DHT==========================================================
|
||||
void dhtT() {
|
||||
String sensor_type = sCmd.next();
|
||||
String pin = sCmd.next();
|
||||
String viget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String type = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
if (sensor_type == "DHT11") {
|
||||
dht.setup(pin.toInt(), DHTesp::DHT11);
|
||||
}
|
||||
if (sensor_type == "DHT22") {
|
||||
dht.setup(pin.toInt(), DHTesp::DHT22);
|
||||
}
|
||||
choose_viget_and_create(viget_name, page_name, page_number, type, "dhtT");
|
||||
ts.add(DHTT, dhtT_update_int + dht.getMinimumSamplingPeriod(), [&](void*) {
|
||||
float value = 0;
|
||||
static float value_old;
|
||||
value = dht.getTemperature();
|
||||
jsonWrite(configJson, "dhtT", String(value));
|
||||
//if (value_old != value) {
|
||||
eventGen ("dhtT", "");
|
||||
sendSTATUS("dhtT", String(value));
|
||||
if (client.connected()) {
|
||||
Serial.println("[i] sensor dhtT send date " + String(value));
|
||||
}
|
||||
//}
|
||||
value_old = value;
|
||||
}, nullptr, true);
|
||||
}
|
||||
|
||||
|
||||
void dhtH() {
|
||||
String sensor_type = sCmd.next();
|
||||
String pin = sCmd.next();
|
||||
String viget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String type = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
if (sensor_type == "DHT11") {
|
||||
dht.setup(pin.toInt(), DHTesp::DHT11);
|
||||
}
|
||||
if (sensor_type == "DHT22") {
|
||||
dht.setup(pin.toInt(), DHTesp::DHT22);
|
||||
}
|
||||
choose_viget_and_create(viget_name, page_name, page_number, type, "dhtH");
|
||||
ts.add(DHTH, dhtH_update_int + dht.getMinimumSamplingPeriod(), [&](void*) {
|
||||
int value = 0;
|
||||
static int value_old;
|
||||
value = dht.getHumidity();
|
||||
jsonWrite(configJson, "dhtH", String(value));
|
||||
//if (value_old != value) {
|
||||
eventGen ("dhtH", "");
|
||||
sendSTATUS("dhtH", String(value));
|
||||
if (client.connected()) {
|
||||
Serial.println("[i] sensor dhtH send date " + String(value));
|
||||
}
|
||||
//}
|
||||
value_old = value;
|
||||
}, nullptr, true);
|
||||
}
|
||||
|
||||
void dhtPerception() {
|
||||
String viget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
choose_viget_and_create(viget_name, page_name, page_number, "any-data", "dhtPerception");
|
||||
ts.add(DHTP, dhtPerception_update_int, [&](void*) {
|
||||
byte value;
|
||||
ComfortState cf;
|
||||
value = dht.computePerception(jsonRead(configJson, "dhtT").toFloat(), jsonRead(configJson, "dhtH").toInt(), false);
|
||||
String final_line = perception(value);
|
||||
jsonWrite(configJson, "dhtPerception", final_line);
|
||||
eventGen ("dhtPerception", "");
|
||||
sendSTATUS("dhtPerception", final_line);
|
||||
if (client.connected()) {
|
||||
Serial.println("[i] sensor dhtPerception send date " + final_line);
|
||||
}
|
||||
}, nullptr, true);
|
||||
}
|
||||
|
||||
String perception(byte value) {
|
||||
if (value == 0) return "Сухой воздух";
|
||||
if (value == 1) return "Комфортно";
|
||||
if (value == 2) return "Уютно";
|
||||
if (value == 3) return "Хорошо";
|
||||
if (value == 4) return "Неудобно";
|
||||
if (value == 5) return "Довольно неудобно";
|
||||
if (value == 6) return "Очень неудобно";
|
||||
if (value == 7) return "Сильно неудобно, полный звиздец";
|
||||
}
|
||||
|
||||
|
||||
void dhtComfort() {
|
||||
String viget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
choose_viget_and_create(viget_name, page_name, page_number, "any-data", "dhtComfort");
|
||||
ts.add(DHTC, dhtComfort_update_int, [&](void*) {
|
||||
float value;
|
||||
ComfortState cf;
|
||||
value = dht.getComfortRatio(cf, jsonRead(configJson, "dhtT").toFloat(), jsonRead(configJson, "dhtH").toInt(), false);
|
||||
String comfortStatus;
|
||||
switch (cf) {
|
||||
case Comfort_OK:
|
||||
comfortStatus = "Отлично";
|
||||
break;
|
||||
case Comfort_TooHot:
|
||||
comfortStatus = "Очень жарко";
|
||||
break;
|
||||
case Comfort_TooCold:
|
||||
comfortStatus = "Очень холодно";
|
||||
break;
|
||||
case Comfort_TooDry:
|
||||
comfortStatus = "Очень сухо";
|
||||
break;
|
||||
case Comfort_TooHumid:
|
||||
comfortStatus = "Очень влажно";
|
||||
break;
|
||||
case Comfort_HotAndHumid:
|
||||
comfortStatus = "Жарко и влажно";
|
||||
break;
|
||||
case Comfort_HotAndDry:
|
||||
comfortStatus = "Жарко и сухо";
|
||||
break;
|
||||
case Comfort_ColdAndHumid:
|
||||
comfortStatus = "Холодно и влажно";
|
||||
break;
|
||||
case Comfort_ColdAndDry:
|
||||
comfortStatus = "Холодно и сухо";
|
||||
break;
|
||||
default:
|
||||
comfortStatus = "Неизвестно";
|
||||
break;
|
||||
};
|
||||
String final_line = comfortStatus;
|
||||
jsonWrite(configJson, "dhtComfort", final_line);
|
||||
eventGen ("dhtComfort", "");
|
||||
sendSTATUS("dhtComfort", final_line);
|
||||
if (client.connected()) {
|
||||
Serial.println("[i] sensor dhtComfort send date " + final_line);
|
||||
}
|
||||
}, nullptr, true);
|
||||
}
|
||||
|
||||
void dhtDewPoint() {
|
||||
String viget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
choose_viget_and_create(viget_name, page_name, page_number, "any-data", "dhtPerception");
|
||||
ts.add(DHTP, dhtPerception_update_int, [&](void*) {
|
||||
byte value;
|
||||
ComfortState cf;
|
||||
value = dht.computePerception(jsonRead(configJson, "dhtT").toFloat(), jsonRead(configJson, "dhtH").toInt(), false);
|
||||
String final_line = perception(value);
|
||||
jsonWrite(configJson, "dhtPerception", final_line);
|
||||
eventGen ("dhtPerception", "");
|
||||
sendSTATUS("dhtPerception", final_line);
|
||||
if (client.connected()) {
|
||||
Serial.println("[i] sensor dhtPerception send date " + final_line);
|
||||
}
|
||||
}, nullptr, true);
|
||||
}
|
||||
|
||||
|
||||
void choose_viget_and_create(String viget_name, String page_name, String page_number, String type, String topik) {
|
||||
|
||||
if (type == "any-data") createViget (viget_name, page_name, page_number, "vigets/viget.anydata.json", topik);
|
||||
if (type == "progress-line") createViget (viget_name, page_name, page_number, "vigets/viget.progressL.json", topik);
|
||||
if (type == "progress-round") createViget (viget_name, page_name, page_number, "vigets/viget.progressR.json", topik);
|
||||
|
||||
|
||||
}
|
||||
//======================================================================================================================
|
||||
//===============================================Логирование============================================================
|
||||
|
||||
void logging() {
|
||||
|
||||
static boolean flag = true;
|
||||
|
||||
String sensor_name = sCmd.next();
|
||||
String period_min = sCmd.next();
|
||||
String maxCount = sCmd.next();
|
||||
String viget_name = sCmd.next();
|
||||
viget_name.replace("#", " ");
|
||||
String page_name = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
|
||||
if (sensor_name == "analog") jsonWrite(optionJson, "analog_logging_count", maxCount);
|
||||
if (sensor_name == "level") jsonWrite(optionJson, "level_logging_count", maxCount);
|
||||
if (sensor_name == "dallas") jsonWrite(optionJson, "dallas_logging_count", maxCount);
|
||||
if (sensor_name == "ph") jsonWrite(optionJson, "ph_logging_count", maxCount);
|
||||
/*
|
||||
if (sensor_name == "analog") createViget (viget_name, page_name, page_number, "vigets/viget.chart.json", "loganalog", "maxCount", maxCount);
|
||||
if (sensor_name == "level") createViget (viget_name, page_name, page_number, "vigets/viget.chart.json", "loglevel", "maxCount", maxCount);
|
||||
if (sensor_name == "dallas") createViget (viget_name, page_name, page_number, "vigets/viget.chart.json", "logdallas", "maxCount", maxCount);
|
||||
if (sensor_name == "ph") createViget (viget_name, page_name, page_number, "vigets/viget.chart.json", "logph", "maxCount", maxCount);
|
||||
*/
|
||||
if (sensor_name == "analog") {
|
||||
flagLoggingAnalog = true;
|
||||
ts.remove(ANALOG_LOG);
|
||||
ts.add(ANALOG_LOG, period_min.toInt() * 1000 * 60, [&](void*) {
|
||||
deleteOldDate("log.analog.txt", jsonReadtoInt(optionJson, "analog_logging_count"), jsonRead(configJson, "analog"), false);
|
||||
}, nullptr, true);
|
||||
}
|
||||
|
||||
if (sensor_name == "level") {
|
||||
flagLoggingLevel = true;
|
||||
ts.remove(LEVEL_LOG);
|
||||
ts.add(LEVEL_LOG, period_min.toInt() * 1000 * 60, [&](void*) {
|
||||
deleteOldDate("log.level.txt", jsonReadtoInt(optionJson, "level_logging_count"), jsonRead(configJson, "level"), false);
|
||||
}, nullptr, true);
|
||||
}
|
||||
|
||||
if (sensor_name == "dallas") {
|
||||
flagLoggingDallas = true;
|
||||
ts.remove(DALLAS_LOG);
|
||||
ts.add(DALLAS_LOG, period_min.toInt() * 1000 * 60, [&](void*) {
|
||||
deleteOldDate("log.dallas.txt", jsonReadtoInt(optionJson, "dallas_logging_count"), jsonRead(configJson, "dallas"), false);
|
||||
}, nullptr, true);
|
||||
}
|
||||
|
||||
if (sensor_name == "ph") {
|
||||
flagLoggingPh = true;
|
||||
ts.remove(PH_LOG);
|
||||
ts.add(PH_LOG, period_min.toInt() * 1000 * 60, [&](void*) {
|
||||
deleteOldDate("log.ph.txt", jsonReadtoInt(optionJson, "ph_logging_count"), jsonRead(configJson, "ph"), false);
|
||||
}, nullptr, true);
|
||||
}
|
||||
}
|
||||
|
||||
void deleteOldDate(String file, int seted_number_of_lines, String date_to_add, boolean date_time) {
|
||||
|
||||
String current_time;
|
||||
|
||||
if (date_time) {
|
||||
current_time = GetDataDigital() + " " + GetTimeWOsec();
|
||||
current_time.replace(".", "");
|
||||
current_time.replace(":", "");
|
||||
} else {
|
||||
current_time = "";
|
||||
}
|
||||
|
||||
String log_date = readFile(file, 5000);
|
||||
getMemoryLoad("[i] after logging procedure");
|
||||
|
||||
//предел количества строк 255
|
||||
|
||||
log_date.replace("\r\n", "\n");
|
||||
log_date.replace("\r", "\n");
|
||||
|
||||
int current_number_of_lines = count(log_date, "\n");
|
||||
Serial.println("[i] in log file " + file + " " + current_number_of_lines + " lines");
|
||||
|
||||
|
||||
if (current_number_of_lines > seted_number_of_lines + 1) {
|
||||
SPIFFS.remove("/" + file);
|
||||
current_number_of_lines = 0;
|
||||
}
|
||||
if (current_number_of_lines == 0) {
|
||||
SPIFFS.remove("/" + file);
|
||||
current_number_of_lines = 0;
|
||||
}
|
||||
if (current_number_of_lines > seted_number_of_lines) {
|
||||
log_date = deleteBeforeDelimiter(log_date, "\n");
|
||||
log_date += current_time + " " + date_to_add + "\n";
|
||||
writeFile(file, log_date);
|
||||
|
||||
} else {
|
||||
if (date_time) {
|
||||
addFile(file, current_time + " " + date_to_add);
|
||||
} else {
|
||||
addFile(file, date_to_add);
|
||||
}
|
||||
}
|
||||
}
|
||||
108
Time.ino
108
Time.ino
@@ -1,108 +0,0 @@
|
||||
void Time_Init() {
|
||||
server.on("/timeZone", HTTP_GET, [](AsyncWebServerRequest * request) {
|
||||
if (request->hasArg("timezone")) {
|
||||
jsonWrite(configSetup, "timezone", request->getParam("timezone")->value());
|
||||
}
|
||||
saveConfig();
|
||||
reconfigTime();
|
||||
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
|
||||
});
|
||||
reconfigTime();
|
||||
}
|
||||
|
||||
void reconfigTime() {
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
|
||||
configTime(jsonRead(configSetup, "timezone").toInt() * 3600, 0, ntpServer);
|
||||
|
||||
int i = 0;
|
||||
Serial.println("[i]Awaiting for time ");
|
||||
|
||||
#ifdef ESP32
|
||||
struct tm timeinfo;
|
||||
while (!getLocalTime(&timeinfo) && i <= 4) {
|
||||
Serial.print(".");
|
||||
i++;
|
||||
delay(1000);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ESP8266
|
||||
// while (!time(nullptr) && i < 4) {
|
||||
// Serial.print(".");
|
||||
// i++;
|
||||
delay(2000);
|
||||
// }
|
||||
#endif
|
||||
|
||||
Serial.print("Time = ");
|
||||
Serial.print(GetDataDigital());
|
||||
Serial.print(" ");
|
||||
Serial.println(GetTime());
|
||||
|
||||
} else {
|
||||
Serial.println("[E] Get time impossible, no wifi connection");
|
||||
}
|
||||
}
|
||||
|
||||
// Получение текущего времени
|
||||
String GetTime() {
|
||||
time_t now = time(nullptr); // получаем время с помощью библиотеки time.h
|
||||
String Time = ""; // Строка для результатов времени
|
||||
Time += ctime(&now); // Преобразуем время в строку формата Thu Jan 19 00:55:35 2017
|
||||
int i = Time.indexOf(":"); //Ишем позицию первого символа :
|
||||
Time = Time.substring(i - 2, i + 6); // Выделяем из строки 2 символа перед символом : и 6 символов после
|
||||
return Time; // Возврашаем полученное время
|
||||
}
|
||||
|
||||
String GetTimeWOsec() {
|
||||
time_t now = time(nullptr); // получаем время с помощью библиотеки time.h
|
||||
String Time = ""; // Строка для результатов времени
|
||||
Time += ctime(&now); // Преобразуем время в строку формата Thu Jan 19 00:55:35 2017
|
||||
int i = Time.indexOf(":"); //Ишем позицию первого символа :
|
||||
Time = Time.substring(i - 2, i + 3); // Выделяем из строки 2 символа перед символом : и 6 символов после
|
||||
return Time; // Возврашаем полученное время
|
||||
}
|
||||
|
||||
// Получение даты
|
||||
String GetDate() {
|
||||
time_t now = time(nullptr); // получаем время с помощью библиотеки time.h
|
||||
String Data = ""; // Строка для результатов времени
|
||||
Data += ctime(&now); // Преобразуем время в строку формата Thu Jan 19 00:55:35 2017
|
||||
Data.replace("\n", "");
|
||||
uint8_t i = Data.lastIndexOf(" "); //Ишем позицию последнего символа пробел
|
||||
String Time = Data.substring(i - 8, i + 1); // Выделяем время и пробел
|
||||
Data.replace(Time, ""); // Удаляем из строки 8 символов времени и пробел
|
||||
return Data; // Возврашаем полученную дату
|
||||
}
|
||||
|
||||
String GetDataDigital() {
|
||||
String date = GetDate();
|
||||
|
||||
date = deleteBeforeDelimiter(date, " ");
|
||||
|
||||
date.replace("Jan", "01");
|
||||
date.replace("Feb", "02");
|
||||
date.replace("Mar", "03");
|
||||
date.replace("Apr", "04");
|
||||
date.replace("May", "05");
|
||||
date.replace("Jun", "06");
|
||||
date.replace("Jul", "07");
|
||||
date.replace("Aug", "08");
|
||||
date.replace("Sep", "09");
|
||||
date.replace("Oct", "10");
|
||||
date.replace("Nov", "11");
|
||||
date.replace("Dec", "12");
|
||||
|
||||
String month = date.substring(0, 2);
|
||||
String day = date.substring(3, 5);
|
||||
String year = date.substring(8, 10);
|
||||
|
||||
String out = day;
|
||||
out += ".";
|
||||
out += month;
|
||||
out += ".";
|
||||
out += year;
|
||||
|
||||
return out;
|
||||
}
|
||||
185
Timers.ino
185
Timers.ino
@@ -1,185 +0,0 @@
|
||||
//================================================================================================================
|
||||
//=========================================Таймера=================================================================
|
||||
void Timer_countdown_init() {
|
||||
|
||||
ts.add(TIMER_COUNTDOWN, 1000, [&](void*) {
|
||||
|
||||
String old_line = jsonRead(optionJson, "timers");
|
||||
|
||||
|
||||
if (old_line != "") {
|
||||
|
||||
Serial.println(old_line);
|
||||
|
||||
int i = 0;
|
||||
|
||||
do {
|
||||
|
||||
String timer = selectFromMarkerToMarker(old_line, "," , i);
|
||||
// Serial.print("timer no " + String (i) + ": ");
|
||||
// Serial.println(timer);
|
||||
if (timer == "not found" || timer == "") return;
|
||||
int number = selectToMarker (timer, ":").toInt();
|
||||
int time = readTimer(number);
|
||||
if (time == 0) {
|
||||
|
||||
delTimer (String (number));
|
||||
|
||||
jsonWrite(configJson, "timerSet" + String(number), "0");
|
||||
|
||||
eventGen ("timerSet", String(number));
|
||||
|
||||
} else {
|
||||
time--;
|
||||
addTimer(String (number), String (time));
|
||||
}
|
||||
i++;
|
||||
} while (i <= 9);
|
||||
|
||||
}
|
||||
}, nullptr, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void timerStart() {
|
||||
|
||||
String number = sCmd.next();
|
||||
String period_of_time = sCmd.next();
|
||||
String type = sCmd.next();
|
||||
|
||||
if (period_of_time.indexOf("digit") != -1) {
|
||||
period_of_time = add_set(period_of_time);
|
||||
period_of_time = jsonRead(configJson, period_of_time);
|
||||
}
|
||||
|
||||
if (type == "sec") period_of_time = period_of_time;
|
||||
if (type == "min") period_of_time = String(period_of_time.toInt() * 60);
|
||||
if (type == "hours") period_of_time = String(period_of_time.toInt() * 60 * 60);
|
||||
|
||||
addTimer(number, period_of_time);
|
||||
jsonWrite(configJson, "timerSet" + number, "1");
|
||||
}
|
||||
void addTimer(String number, String time) {
|
||||
|
||||
String tmp = jsonRead(optionJson, "timers"); //1:60,2:120,
|
||||
String new_timer = number + ":" + time;
|
||||
int psn1 = tmp.indexOf(number + ":"); //0 ищем позицию таймера который надо заменить
|
||||
|
||||
if (psn1 != -1) { //если он есть
|
||||
|
||||
int psn2 = tmp.indexOf(",", psn1); //4 от этой позиции находим позицию запятой
|
||||
|
||||
String timer = tmp.substring(psn1, psn2); //1:60 выделяем таймер который надо заменить
|
||||
///tmp.replace(timer, new_timer); //заменяем таймер на новый (во всей стороке)
|
||||
tmp.replace(timer + ",", "");
|
||||
tmp += new_timer + ",";
|
||||
|
||||
} else { //если его нет
|
||||
tmp += new_timer + ",";
|
||||
}
|
||||
jsonWrite(optionJson, "timers", tmp);
|
||||
//Serial.println("ura");
|
||||
}
|
||||
|
||||
|
||||
void timerStop() {
|
||||
|
||||
String number = sCmd.next();
|
||||
delTimer(number);
|
||||
|
||||
}
|
||||
void delTimer (String number) {
|
||||
|
||||
String tmp = jsonRead(optionJson, "timers"); //1:60,2:120,
|
||||
int psn1 = tmp.indexOf(number + ":"); //0 ищем позицию таймера который надо удалить
|
||||
|
||||
if (psn1 != -1) { //если он есть
|
||||
int psn2 = tmp.indexOf(",", psn1); //4 от этой позиции находим позицию запятой
|
||||
String timer = tmp.substring(psn1, psn2) + ","; //1:60, выделяем таймер который надо удалить
|
||||
tmp.replace(timer, ""); //удаляем таймер
|
||||
jsonWrite(optionJson, "timers", tmp);
|
||||
}
|
||||
}
|
||||
|
||||
int readTimer(int number) {
|
||||
|
||||
String tmp = jsonRead(optionJson, "timers"); //1:60,2:120,
|
||||
|
||||
int psn1 = tmp.indexOf(String(number) + ":"); //0 ищем позицию таймера который надо прочитать
|
||||
|
||||
String timer;
|
||||
|
||||
if (psn1 != -1) { //если он есть
|
||||
int psn2 = tmp.indexOf(",", psn1); //4 от этой позиции находим позицию запятой
|
||||
timer = tmp.substring(psn1, psn2); //1:60 выделяем таймер который надо прочитать
|
||||
timer = deleteBeforeDelimiter(timer, ":");
|
||||
}
|
||||
return timer.toInt();
|
||||
}
|
||||
|
||||
/*void timer() {
|
||||
|
||||
String seted_time = sCmd.next();
|
||||
String order = sCmd.next();
|
||||
order.replace("_", " ");
|
||||
if (seted_time == current_time) {
|
||||
|
||||
order_loop += order + ",";
|
||||
|
||||
}
|
||||
}*/
|
||||
|
||||
//------------------------------таймеры------------------------------------------------------
|
||||
void time() {
|
||||
|
||||
String time_number = sCmd.next();
|
||||
String time = sCmd.next();
|
||||
|
||||
String time_to_add = time_number + "-" + time;
|
||||
|
||||
String replace_line = jsonRead(optionJson, "times") ;
|
||||
int psn1 = replace_line.indexOf(time_number + "-") ; //ищем позицию времени которое надо заменить
|
||||
|
||||
if (psn1 != -1) { //если оно есть
|
||||
|
||||
int psn2 = replace_line.indexOf(",", psn1); //от этой позиции находим позицию запятой
|
||||
|
||||
String timer = replace_line.substring(psn1, psn2); //выделяем таймер который надо заменить
|
||||
///tmp.replace(timer, new_timer); //заменяем таймер на новый (во всей стороке)
|
||||
replace_line.replace(timer + ",", "");
|
||||
replace_line += time_to_add + ",";
|
||||
|
||||
} else { //если его нет
|
||||
replace_line += time_to_add + ",";
|
||||
}
|
||||
|
||||
|
||||
jsonWrite(optionJson, "times", replace_line);
|
||||
|
||||
jsonWrite(configJson, "timeSet" + time_number, "1");
|
||||
|
||||
ts.add(TIMERS, 1000, [&](void*) {
|
||||
|
||||
current_time = GetTime();
|
||||
Serial.println(current_time);
|
||||
|
||||
String seted_times = jsonRead(optionJson, "times");
|
||||
|
||||
while (seted_times.length() != 0) {
|
||||
String tmp = selectToMarker (seted_times, ",");
|
||||
|
||||
String time_number = selectToMarker(tmp, "-");
|
||||
String seted_time = deleteBeforeDelimiter(tmp, "-");
|
||||
|
||||
Serial.println(seted_time);
|
||||
|
||||
if (current_time == seted_time) {
|
||||
jsonWrite(configJson, "timeSet" + time_number, "0");
|
||||
eventGen ("timeSet", time_number);
|
||||
}
|
||||
|
||||
seted_times = deleteBeforeDelimiter(seted_times, ",");
|
||||
}
|
||||
}, nullptr, true);
|
||||
}
|
||||
221
Web_server.ino
221
Web_server.ino
@@ -1,221 +0,0 @@
|
||||
void Web_server_init() {
|
||||
|
||||
//========================================OTA============================================
|
||||
#ifdef OTA_enable
|
||||
//Send OTA events to the browser
|
||||
ArduinoOTA.onStart([]() {
|
||||
events.send("Update Start", "ota");
|
||||
});
|
||||
|
||||
ArduinoOTA.onEnd([]() {
|
||||
events.send("Update End", "ota");
|
||||
});
|
||||
|
||||
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
|
||||
char p[32];
|
||||
sprintf(p, "Progress: %u%%\n", (progress / (total / 100)));
|
||||
events.send(p, "ota");
|
||||
});
|
||||
|
||||
ArduinoOTA.onError([](ota_error_t error) {
|
||||
if (error == OTA_AUTH_ERROR) events.send("Auth Failed", "ota");
|
||||
else if (error == OTA_BEGIN_ERROR) events.send("Begin Failed", "ota");
|
||||
else if (error == OTA_CONNECT_ERROR) events.send("Connect Failed", "ota");
|
||||
else if (error == OTA_RECEIVE_ERROR) events.send("Recieve Failed", "ota");
|
||||
else if (error == OTA_END_ERROR) events.send("End Failed", "ota");
|
||||
});
|
||||
ArduinoOTA.setHostname(hostName);
|
||||
|
||||
ArduinoOTA.begin();
|
||||
#endif
|
||||
//========================================MDNS============================================
|
||||
#ifdef MDNS_enable
|
||||
MDNS.addService("http", "tcp", 80);
|
||||
#endif
|
||||
|
||||
//SPIFFS.begin();
|
||||
|
||||
//========================================WS============================================
|
||||
#ifdef WS_enable
|
||||
ws.onEvent(onWsEvent);
|
||||
server.addHandler(&ws);
|
||||
|
||||
events.onConnect([](AsyncEventSourceClient * client) {
|
||||
client->send("hello!", NULL, millis(), 1000);
|
||||
});
|
||||
|
||||
server.addHandler(&events);
|
||||
#endif
|
||||
//======================================================================================
|
||||
|
||||
#ifdef ESP32
|
||||
server.addHandler(new SPIFFSEditor(SPIFFS, jsonRead(configSetup, "web_login").c_str(), jsonRead(configSetup, "web_pass").c_str()));
|
||||
#elif defined(ESP8266)
|
||||
server.addHandler(new SPIFFSEditor(jsonRead(configSetup, "web_login").c_str(), jsonRead(configSetup, "web_pass").c_str()));
|
||||
#endif
|
||||
|
||||
server.on("/heap", HTTP_GET, [](AsyncWebServerRequest * request) {
|
||||
request->send(200, "text/plain", String(ESP.getFreeHeap()));
|
||||
});
|
||||
|
||||
|
||||
server.serveStatic("/css/", SPIFFS, "/css/").setCacheControl("max-age=31536000");
|
||||
server.serveStatic("/js/", SPIFFS, "/js/").setCacheControl("max-age=31536000");
|
||||
server.serveStatic("/", SPIFFS, "/favicon.ico").setCacheControl("max-age=31536000");
|
||||
|
||||
server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm")
|
||||
.setAuthentication(jsonRead(configSetup, "web_login").c_str(), jsonRead(configSetup, "web_pass").c_str());
|
||||
|
||||
|
||||
server.onNotFound([](AsyncWebServerRequest * request) {
|
||||
Serial.printf("NOT_FOUND: ");
|
||||
if (request->method() == HTTP_GET)
|
||||
Serial.printf("GET");
|
||||
else if (request->method() == HTTP_POST)
|
||||
Serial.printf("POST");
|
||||
else if (request->method() == HTTP_DELETE)
|
||||
Serial.printf("DELETE");
|
||||
else if (request->method() == HTTP_PUT)
|
||||
Serial.printf("PUT");
|
||||
else if (request->method() == HTTP_PATCH)
|
||||
Serial.printf("PATCH");
|
||||
else if (request->method() == HTTP_HEAD)
|
||||
Serial.printf("HEAD");
|
||||
else if (request->method() == HTTP_OPTIONS)
|
||||
Serial.printf("OPTIONS");
|
||||
else
|
||||
Serial.printf("UNKNOWN");
|
||||
Serial.printf(" http://%s%s\n", request->host().c_str(), request->url().c_str());
|
||||
|
||||
if (request->contentLength()) {
|
||||
Serial.printf("_CONTENT_TYPE: %s\n", request->contentType().c_str());
|
||||
Serial.printf("_CONTENT_LENGTH: %u\n", request->contentLength());
|
||||
}
|
||||
|
||||
int headers = request->headers();
|
||||
int i;
|
||||
for (i = 0; i < headers; i++) {
|
||||
AsyncWebHeader* h = request->getHeader(i);
|
||||
Serial.printf("_HEADER[%s]: %s\n", h->name().c_str(), h->value().c_str());
|
||||
}
|
||||
|
||||
int params = request->params();
|
||||
for (i = 0; i < params; i++) {
|
||||
AsyncWebParameter* p = request->getParam(i);
|
||||
if (p->isFile()) {
|
||||
Serial.printf("_FILE[%s]: %s, size: %u\n", p->name().c_str(), p->value().c_str(), p->size());
|
||||
} else if (p->isPost()) {
|
||||
Serial.printf("_POST[%s]: %s\n", p->name().c_str(), p->value().c_str());
|
||||
} else {
|
||||
Serial.printf("_GET[%s]: %s\n", p->name().c_str(), p->value().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
request->send(404);
|
||||
});
|
||||
server.onFileUpload([](AsyncWebServerRequest * request, const String & filename, size_t index, uint8_t *data, size_t len, bool final) {
|
||||
if (!index)
|
||||
Serial.printf("UploadStart: %s\n", filename.c_str());
|
||||
Serial.printf("%s", (const char*)data);
|
||||
if (final)
|
||||
Serial.printf("UploadEnd: %s (%u)\n", filename.c_str(), index + len);
|
||||
});
|
||||
server.onRequestBody([](AsyncWebServerRequest * request, uint8_t *data, size_t len, size_t index, size_t total) {
|
||||
if (!index)
|
||||
Serial.printf("BodyStart: %u\n", total);
|
||||
Serial.printf("%s", (const char*)data);
|
||||
if (index + len == total)
|
||||
Serial.printf("BodyEnd: %u\n", total);
|
||||
});
|
||||
|
||||
server.begin();
|
||||
|
||||
//=============================Устанавливаем реакции на запросы к серверу============================
|
||||
|
||||
// --------------------Выдаем данные configJson //config.live.json - динамические данные
|
||||
server.on("/config.live.json", HTTP_GET, [](AsyncWebServerRequest * request) {
|
||||
request->send(200, "application/json", configJson);
|
||||
});
|
||||
// --------------------Выдаем данные optionJson //config.option.json - данные не являющиеся событиями
|
||||
server.on("/config.option.json", HTTP_GET, [](AsyncWebServerRequest * request) {
|
||||
request->send(200, "application/json", optionJson);
|
||||
});
|
||||
// -------------------Выдаем данные configSetup //config.setup.json - для хранения постоянных данных
|
||||
server.on("/config.setup.json", HTTP_GET, [](AsyncWebServerRequest * request) {
|
||||
request->send(200, "application/json", configSetup);
|
||||
});
|
||||
}
|
||||
//========================================WS=========================================================================================
|
||||
#ifdef WS_enable
|
||||
void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len) {
|
||||
if (type == WS_EVT_CONNECT) {
|
||||
Serial.printf("ws[%s][%u] connect\n", server->url(), client->id());
|
||||
client->printf(configJson.c_str(), client->id());
|
||||
client->ping();
|
||||
} else if (type == WS_EVT_DISCONNECT) {
|
||||
Serial.printf("ws[%s][%u] disconnect\n", server->url(), client->id());
|
||||
} else if (type == WS_EVT_ERROR) {
|
||||
Serial.printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t*)arg), (char*)data);
|
||||
} else if (type == WS_EVT_PONG) {
|
||||
Serial.printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len) ? (char*)data : "");
|
||||
} else if (type == WS_EVT_DATA) {
|
||||
AwsFrameInfo * info = (AwsFrameInfo*)arg;
|
||||
String msg = "";
|
||||
if (info->final && info->index == 0 && info->len == len) {
|
||||
//the whole message is in a single frame and we got all of it's data
|
||||
Serial.printf("ws[%s][%u] %s-message[%llu]: ", server->url(), client->id(), (info->opcode == WS_TEXT) ? "text" : "binary", info->len);
|
||||
|
||||
if (info->opcode == WS_TEXT) {
|
||||
for (size_t i = 0; i < info->len; i++) {
|
||||
msg += (char) data[i];
|
||||
}
|
||||
} else {
|
||||
char buff[3];
|
||||
for (size_t i = 0; i < info->len; i++) {
|
||||
sprintf(buff, "%02x ", (uint8_t) data[i]);
|
||||
msg += buff ;
|
||||
}
|
||||
}
|
||||
Serial.printf("%s\n", msg.c_str());
|
||||
|
||||
if (info->opcode == WS_TEXT)
|
||||
client->text("{}");
|
||||
else
|
||||
client->binary("{}");
|
||||
} else {
|
||||
//message is comprised of multiple frames or the frame is split into multiple packets
|
||||
if (info->index == 0) {
|
||||
if (info->num == 0)
|
||||
Serial.printf("ws[%s][%u] %s-message start\n", server->url(), client->id(), (info->message_opcode == WS_TEXT) ? "text" : "binary");
|
||||
Serial.printf("ws[%s][%u] frame[%u] start[%llu]\n", server->url(), client->id(), info->num, info->len);
|
||||
}
|
||||
|
||||
Serial.printf("ws[%s][%u] frame[%u] %s[%llu - %llu]: ", server->url(), client->id(), info->num, (info->message_opcode == WS_TEXT) ? "text" : "binary", info->index, info->index + len);
|
||||
|
||||
if (info->opcode == WS_TEXT) {
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
msg += (char) data[i];
|
||||
}
|
||||
} else {
|
||||
char buff[3];
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
sprintf(buff, "%02x ", (uint8_t) data[i]);
|
||||
msg += buff ;
|
||||
}
|
||||
}
|
||||
Serial.printf("%s\n", msg.c_str());
|
||||
|
||||
if ((info->index + len) == info->len) {
|
||||
Serial.printf("ws[%s][%u] frame[%u] end[%llu]\n", server->url(), client->id(), info->num, info->len);
|
||||
if (info->final) {
|
||||
Serial.printf("ws[%s][%u] %s-message end\n", server->url(), client->id(), (info->message_opcode == WS_TEXT) ? "text" : "binary");
|
||||
if (info->message_opcode == WS_TEXT)
|
||||
client->text("I got your text message");
|
||||
else
|
||||
client->binary("I got your binary message");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
162
WiFi.ino
162
WiFi.ino
@@ -1,162 +0,0 @@
|
||||
void WIFI_init() {
|
||||
|
||||
// --------------------Получаем ssid password со страницы
|
||||
server.on("/ssid", HTTP_GET, [](AsyncWebServerRequest * request) {
|
||||
if (request->hasArg("ssid")) {
|
||||
jsonWrite(configSetup, "ssid", request->getParam("ssid")->value());
|
||||
}
|
||||
if (request->hasArg("password")) {
|
||||
jsonWrite(configSetup, "password", request->getParam("password")->value());
|
||||
}
|
||||
saveConfig(); // Функция сохранения данных во Flash
|
||||
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
|
||||
});
|
||||
// --------------------Получаем ssidAP passwordAP со страницы
|
||||
server.on("/ssidap", HTTP_GET, [](AsyncWebServerRequest * request) {
|
||||
if (request->hasArg("ssidAP")) {
|
||||
jsonWrite(configSetup, "ssidAP", request->getParam("ssidAP")->value());
|
||||
}
|
||||
if (request->hasArg("passwordAP")) {
|
||||
jsonWrite(configSetup, "passwordAP", request->getParam("passwordAP")->value());
|
||||
}
|
||||
saveConfig(); // Функция сохранения данных во Flash
|
||||
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
|
||||
});
|
||||
|
||||
// --------------------Получаем логин и пароль для web со страницы
|
||||
server.on("/web", HTTP_GET, [](AsyncWebServerRequest * request) {
|
||||
if (request->hasArg("web_login")) {
|
||||
jsonWrite(configSetup, "web_login", request->getParam("web_login")->value());
|
||||
}
|
||||
if (request->hasArg("web_pass")) {
|
||||
jsonWrite(configSetup, "web_pass", request->getParam("web_pass")->value());
|
||||
}
|
||||
saveConfig(); // Функция сохранения данных во Flash
|
||||
//Web_server_init();
|
||||
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
|
||||
});
|
||||
|
||||
server.on("/restart", HTTP_GET, [](AsyncWebServerRequest * request) {
|
||||
if (request->hasArg("device")) {
|
||||
if (request->getParam("device")->value() == "ok") ESP.restart();
|
||||
}
|
||||
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
|
||||
});
|
||||
|
||||
|
||||
// Попытка подключения к точке доступа
|
||||
|
||||
WiFi.mode(WIFI_STA);
|
||||
|
||||
byte tries = 20;
|
||||
String _ssid = jsonRead(configSetup, "ssid");
|
||||
String _password = jsonRead(configSetup, "password");
|
||||
//WiFi.persistent(false);
|
||||
|
||||
if (_ssid == "" && _password == "") {
|
||||
WiFi.begin();
|
||||
}
|
||||
else {
|
||||
WiFi.begin(_ssid.c_str(), _password.c_str());
|
||||
}
|
||||
// Делаем проверку подключения до тех пор пока счетчик tries
|
||||
// не станет равен нулю или не получим подключение
|
||||
while (--tries && WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
if (WiFi.status() == WL_CONNECT_FAILED) {
|
||||
Serial.println("[E] password is not correct");
|
||||
tries = 1;
|
||||
jsonWrite(optionJson, "pass_status", 1);
|
||||
}
|
||||
Serial.print(".");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
if (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
// Если не удалось подключиться запускаем в режиме AP
|
||||
Serial.println("");
|
||||
// WiFi.disconnect(true);
|
||||
StartAPMode();
|
||||
|
||||
}
|
||||
else {
|
||||
// Иначе удалось подключиться отправляем сообщение
|
||||
// о подключении и выводим адрес IP
|
||||
Serial.println("");
|
||||
Serial.println("[V] WiFi connected");
|
||||
Serial.print("[V] IP address: ");
|
||||
Serial.print(WiFi.localIP());
|
||||
Serial.println("");
|
||||
jsonWrite(configJson, "ip", WiFi.localIP().toString());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool StartAPMode() {
|
||||
Serial.println("WiFi up AP");
|
||||
WiFi.disconnect();
|
||||
|
||||
WiFi.mode(WIFI_AP);
|
||||
|
||||
String _ssidAP = jsonRead(configSetup, "ssidAP");
|
||||
String _passwordAP = jsonRead(configSetup, "passwordAP");
|
||||
WiFi.softAP(_ssidAP.c_str(), _passwordAP.c_str());
|
||||
IPAddress myIP = WiFi.softAPIP();
|
||||
Serial.print("AP IP address: ");
|
||||
Serial.println(myIP);
|
||||
|
||||
if (jsonReadtoInt(optionJson, "pass_status") != 1) {
|
||||
ts.add(ROUTER_SEARCHING, 10 * 1000, [&](void*) {
|
||||
Serial.println("->try find router");
|
||||
if (RouterFind(jsonRead(configSetup, "ssid"))) {
|
||||
ts.remove(ROUTER_SEARCHING);
|
||||
WIFI_init();
|
||||
MQTT_init();
|
||||
}
|
||||
}, nullptr, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
boolean RouterFind(String ssid) {
|
||||
int n = WiFi.scanComplete ();
|
||||
Serial.println("n = " + String(n));
|
||||
if (n == -2) { //Сканирование не было запущено, запускаем
|
||||
Serial.println("[WIFI][i] scanning has not been triggered, starting scanning");
|
||||
WiFi.scanNetworks (true, false); //async, show_hidden
|
||||
return false;
|
||||
}
|
||||
if (n == -1) { //Сканирование все еще выполняется
|
||||
Serial.println("[WIFI][i] scanning still in progress");
|
||||
return false;
|
||||
}
|
||||
if (n == 0) { //Сканирование все еще выполняется
|
||||
Serial.println("[WIFI][i] no any wifi sations, starting scanning");
|
||||
WiFi.scanNetworks (true, false);
|
||||
return false;
|
||||
}
|
||||
if (n > 0) {
|
||||
for (int i = 0; i <= n; i++) {
|
||||
if (WiFi.SSID (i) == ssid) {
|
||||
WiFi.scanDelete();
|
||||
return true;
|
||||
} else {
|
||||
Serial.print(i);
|
||||
Serial.print(")");
|
||||
Serial.print(ssid);
|
||||
Serial.print("<=>");
|
||||
if (i == n) {
|
||||
Serial.print(WiFi.SSID(i));
|
||||
Serial.println("; ");
|
||||
} else {
|
||||
Serial.print(WiFi.SSID(i));
|
||||
Serial.print("; ");
|
||||
}
|
||||
}
|
||||
}
|
||||
WiFi.scanDelete();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
BIN
bin/esp32bootloader/boot_app0.bin
Normal file
BIN
bin/esp32bootloader/boot_app0.bin
Normal file
Binary file not shown.
BIN
bin/esp32bootloader/bootloader_qio_80m.bin
Normal file
BIN
bin/esp32bootloader/bootloader_qio_80m.bin
Normal file
Binary file not shown.
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
const char* local_root_ca1 = \
|
||||
"-----BEGIN CERTIFICATE-----\n" \
|
||||
"MIIFdDCCBFygAwIBAgIQJ2buVutJ846r13Ci/ITeIjANBgkqhkiG9w0BAQwFADBv\n" \
|
||||
"MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk\n" \
|
||||
"ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF\n" \
|
||||
"eHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFow\n" \
|
||||
"gYUxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO\n" \
|
||||
"BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMSswKQYD\n" \
|
||||
"VQQDEyJDT01PRE8gUlNBIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkq\n" \
|
||||
"hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAkehUktIKVrGsDSTdxc9EZ3SZKzejfSNw\n" \
|
||||
"AHG8U9/E+ioSj0t/EFa9n3Byt2F/yUsPF6c947AEYe7/EZfH9IY+Cvo+XPmT5jR6\n" \
|
||||
"2RRr55yzhaCCenavcZDX7P0N+pxs+t+wgvQUfvm+xKYvT3+Zf7X8Z0NyvQwA1onr\n" \
|
||||
"ayzT7Y+YHBSrfuXjbvzYqOSSJNpDa2K4Vf3qwbxstovzDo2a5JtsaZn4eEgwRdWt\n" \
|
||||
"4Q08RWD8MpZRJ7xnw8outmvqRsfHIKCxH2XeSAi6pE6p8oNGN4Tr6MyBSENnTnIq\n" \
|
||||
"m1y9TBsoilwie7SrmNnu4FGDwwlGTm0+mfqVF9p8M1dBPI1R7Qu2XK8sYxrfV8g/\n" \
|
||||
"vOldxJuvRZnio1oktLqpVj3Pb6r/SVi+8Kj/9Lit6Tf7urj0Czr56ENCHonYhMsT\n" \
|
||||
"8dm74YlguIwoVqwUHZwK53Hrzw7dPamWoUi9PPevtQ0iTMARgexWO/bTouJbt7IE\n" \
|
||||
"IlKVgJNp6I5MZfGRAy1wdALqi2cVKWlSArvX31BqVUa/oKMoYX9w0MOiqiwhqkfO\n" \
|
||||
"KJwGRXa/ghgntNWutMtQ5mv0TIZxMOmm3xaG4Nj/QN370EKIf6MzOi5cHkERgWPO\n" \
|
||||
"GHFrK+ymircxXDpqR+DDeVnWIBqv8mqYqnK8V0rSS527EPywTEHl7R09XiidnMy/\n" \
|
||||
"s1Hap0flhFMCAwEAAaOB9DCB8TAfBgNVHSMEGDAWgBStvZh6NLQm9/rEJlTvA73g\n" \
|
||||
"JMtUGjAdBgNVHQ4EFgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQD\n" \
|
||||
"AgGGMA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0gBAowCDAGBgRVHSAAMEQGA1UdHwQ9\n" \
|
||||
"MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9BZGRUcnVzdEV4dGVy\n" \
|
||||
"bmFsQ0FSb290LmNybDA1BggrBgEFBQcBAQQpMCcwJQYIKwYBBQUHMAGGGWh0dHA6\n" \
|
||||
"Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJKoZIhvcNAQEMBQADggEBAGS/g/FfmoXQ\n" \
|
||||
"zbihKVcN6Fr30ek+8nYEbvFScLsePP9NDXRqzIGCJdPDoCpdTPW6i6FtxFQJdcfj\n" \
|
||||
"Jw5dhHk3QBN39bSsHNA7qxcS1u80GH4r6XnTq1dFDK8o+tDb5VCViLvfhVdpfZLY\n" \
|
||||
"Uspzgb8c8+a4bmYRBbMelC1/kZWSWfFMzqORcUx8Rww7Cxn2obFshj5cqsQugsv5\n" \
|
||||
"B5a6SE2Q8pTIqXOi6wZ7I53eovNNVZ96YUWYGGjHXkBrI/V5eu+MtWuLt29G9Hvx\n" \
|
||||
"PUsE2JOAWVrgQSQdso8VYFhH2+9uRv0V9dlfmrPb2LjkQLPNlzmuhbsdjrzch5vR\n" \
|
||||
"pu/xO28QOG8=\n" \
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
const char* local_root_ca2 = \
|
||||
"-----BEGIN CERTIFICATE-----\n" \
|
||||
"MIIGCDCCA/CgAwIBAgIQKy5u6tl1NmwUim7bo3yMBzANBgkqhkiG9w0BAQwFADCB\n" \
|
||||
"hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G\n" \
|
||||
"A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV\n" \
|
||||
"BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTQwMjEy\n" \
|
||||
"MDAwMDAwWhcNMjkwMjExMjM1OTU5WjCBkDELMAkGA1UEBhMCR0IxGzAZBgNVBAgT\n" \
|
||||
"EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR\n" \
|
||||
"Q09NT0RPIENBIExpbWl0ZWQxNjA0BgNVBAMTLUNPTU9ETyBSU0EgRG9tYWluIFZh\n" \
|
||||
"bGlkYXRpb24gU2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP\n" \
|
||||
"ADCCAQoCggEBAI7CAhnhoFmk6zg1jSz9AdDTScBkxwtiBUUWOqigwAwCfx3M28Sh\n" \
|
||||
"bXcDow+G+eMGnD4LgYqbSRutA776S9uMIO3Vzl5ljj4Nr0zCsLdFXlIvNN5IJGS0\n" \
|
||||
"Qa4Al/e+Z96e0HqnU4A7fK31llVvl0cKfIWLIpeNs4TgllfQcBhglo/uLQeTnaG6\n" \
|
||||
"ytHNe+nEKpooIZFNb5JPJaXyejXdJtxGpdCsWTWM/06RQ1A/WZMebFEh7lgUq/51\n" \
|
||||
"UHg+TLAchhP6a5i84DuUHoVS3AOTJBhuyydRReZw3iVDpA3hSqXttn7IzW3uLh0n\n" \
|
||||
"c13cRTCAquOyQQuvvUSH2rnlG51/ruWFgqUCAwEAAaOCAWUwggFhMB8GA1UdIwQY\n" \
|
||||
"MBaAFLuvfgI9+qbxPISOre44mOzZMjLUMB0GA1UdDgQWBBSQr2o6lFoL2JDqElZz\n" \
|
||||
"30O0Oija5zAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNV\n" \
|
||||
"HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGwYDVR0gBBQwEjAGBgRVHSAAMAgG\n" \
|
||||
"BmeBDAECATBMBgNVHR8ERTBDMEGgP6A9hjtodHRwOi8vY3JsLmNvbW9kb2NhLmNv\n" \
|
||||
"bS9DT01PRE9SU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDBxBggrBgEFBQcB\n" \
|
||||
"AQRlMGMwOwYIKwYBBQUHMAKGL2h0dHA6Ly9jcnQuY29tb2RvY2EuY29tL0NPTU9E\n" \
|
||||
"T1JTQUFkZFRydXN0Q0EuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21v\n" \
|
||||
"ZG9jYS5jb20wDQYJKoZIhvcNAQEMBQADggIBAE4rdk+SHGI2ibp3wScF9BzWRJ2p\n" \
|
||||
"mj6q1WZmAT7qSeaiNbz69t2Vjpk1mA42GHWx3d1Qcnyu3HeIzg/3kCDKo2cuH1Z/\n" \
|
||||
"e+FE6kKVxF0NAVBGFfKBiVlsit2M8RKhjTpCipj4SzR7JzsItG8kO3KdY3RYPBps\n" \
|
||||
"P0/HEZrIqPW1N+8QRcZs2eBelSaz662jue5/DJpmNXMyYE7l3YphLG5SEXdoltMY\n" \
|
||||
"dVEVABt0iN3hxzgEQyjpFv3ZBdRdRydg1vs4O2xyopT4Qhrf7W8GjEXCBgCq5Ojc\n" \
|
||||
"2bXhc3js9iPc0d1sjhqPpepUfJa3w/5Vjo1JXvxku88+vZbrac2/4EjxYoIQ5QxG\n" \
|
||||
"V/Iz2tDIY+3GH5QFlkoakdH368+PUq4NCNk+qKBR6cGHdNXJ93SrLlP7u3r7l+L4\n" \
|
||||
"HyaPs9Kg4DdbKDsx5Q5XLVq4rXmsXiBmGqW5prU5wfWYQ//u+aen/e7KJD2AFsQX\n" \
|
||||
"j4rBYKEMrltDR5FL1ZoXX/nUh8HCjLfn4g8wGTeGrODcQgPmlKidrv0PJFGUzpII\n" \
|
||||
"0fxQ8ANAe4hZ7Q7drNJ3gjTcBpUC2JD5Leo31Rpg0Gcg19hCC0Wvgmje3WYkN5Ap\n" \
|
||||
"lBlGGSW4gNfL1IYoakRwJiNiqZ+Gb7+6kHDSVneFeO/qJakXzlByjAA6quPbYzSf\n" \
|
||||
"+AZxAeKCINT+b72x\n" \
|
||||
"-----END CERTIFICATE-----\n";
|
||||
*/
|
||||
515
compilerProfile.json
Normal file
515
compilerProfile.json
Normal file
@@ -0,0 +1,515 @@
|
||||
{
|
||||
"iotmSettings": {
|
||||
"name": "IoTmanagerVer4",
|
||||
"apssid": "IoTmanager",
|
||||
"appass": "",
|
||||
"routerssid": "iot",
|
||||
"routerpass": "hostel3333",
|
||||
"timezone": 2,
|
||||
"ntp": "pool.ntp.org",
|
||||
"weblogin": "admin",
|
||||
"webpass": "admin",
|
||||
"mqttServer": "",
|
||||
"mqttPort": 8021,
|
||||
"mqttPrefix": "/risenew",
|
||||
"mqttUser": "rise",
|
||||
"mqttPass": "3hostel3",
|
||||
"serverip": "http://iotmanager.org",
|
||||
"log": 0,
|
||||
"mqttin": 0,
|
||||
"pinSCL": 0,
|
||||
"pinSDA": 0,
|
||||
"i2cFreq": 100000,
|
||||
"wg": "group1"
|
||||
},
|
||||
"projectProp": {
|
||||
"platformio": {
|
||||
"default_envs": "esp8266_4mb",
|
||||
"comments_default_envs": "choose from: esp8266_4mb or esp32_4mb or esp32cam_4mb or esp32s2_4mb or esp32_4mb3f or esp32s3_16mb or esp32c3m_4mb or esp8266_1mb or esp8266_1mb_ota or esp8285_1mb or esp8285_1mb_ota",
|
||||
"envs": [
|
||||
{
|
||||
"name": "esp8266_4mb",
|
||||
"firmware": "0x00000",
|
||||
"littlefs": "0x300000"
|
||||
},
|
||||
{
|
||||
"name": "esp8266_16mb",
|
||||
"firmware": "0x00000",
|
||||
"littlefs": "0x200000"
|
||||
},
|
||||
{
|
||||
"name": "esp32_4mb",
|
||||
"boot_app0": "0xe000",
|
||||
"bootloader_qio_80m": "0x1000",
|
||||
"firmware": "0x10000",
|
||||
"partitions": "0x8000",
|
||||
"littlefs": "0x290000"
|
||||
},
|
||||
{
|
||||
"name": "esp32_4mb3f",
|
||||
"boot_app0": "0xe000",
|
||||
"bootloader_qio_80m": "0x1000",
|
||||
"firmware": "0x10000",
|
||||
"partitions": "0x8000",
|
||||
"littlefs": "0x310000"
|
||||
},
|
||||
{
|
||||
"name": "esp32cam_4mb",
|
||||
"boot_app0": "0xe000",
|
||||
"bootloader_qio_80m": "0x1000",
|
||||
"firmware": "0x10000",
|
||||
"partitions": "0x8000",
|
||||
"littlefs": "0x310000"
|
||||
},
|
||||
{
|
||||
"name": "esp32_16mb",
|
||||
"boot_app0": "0xe000",
|
||||
"bootloader_qio_80m": "0x1000",
|
||||
"firmware": "0x10000",
|
||||
"partitions": "0x8000",
|
||||
"littlefs": "0x910000"
|
||||
},
|
||||
{
|
||||
"name": "esp8266_1mb",
|
||||
"firmware": "0x00000000",
|
||||
"littlefs": "0x000bb000"
|
||||
},
|
||||
{
|
||||
"name": "esp8266_1mb_ota",
|
||||
"firmware": "0x00000000",
|
||||
"littlefs": "0x000eb000"
|
||||
},
|
||||
{
|
||||
"name": "esp8266_2mb",
|
||||
"firmware": "0x00000000",
|
||||
"littlefs": "0x00100000"
|
||||
},
|
||||
{
|
||||
"name": "esp8266_2mb_ota",
|
||||
"firmware": "0x00000000",
|
||||
"littlefs": "0x001c0000"
|
||||
},
|
||||
{
|
||||
"name": "esp8285_1mb",
|
||||
"firmware": "0x00000000",
|
||||
"littlefs": "0x000bb000"
|
||||
},
|
||||
{
|
||||
"name": "esp8285_1mb_ota",
|
||||
"firmware": "0x00000000",
|
||||
"littlefs": "0x000eb000"
|
||||
},
|
||||
{
|
||||
"name": "esp32s2_4mb",
|
||||
"boot_app0": "0xe000",
|
||||
"bootloader_qio_80m": "0x1000",
|
||||
"firmware": "0x10000",
|
||||
"partitions": "0x8000",
|
||||
"littlefs": "0x290000"
|
||||
},
|
||||
{
|
||||
"name": "esp32c3m_4mb",
|
||||
"boot_app0": "0xe000",
|
||||
"bootloader_qio_80m": "0x1000",
|
||||
"firmware": "0x10000",
|
||||
"partitions": "0x8000",
|
||||
"littlefs": "0x310000"
|
||||
},
|
||||
{
|
||||
"name": "esp32s3_16mb",
|
||||
"boot_app0": "0xe000",
|
||||
"bootloader_qio_80m": "0x1000",
|
||||
"firmware": "0x10000",
|
||||
"partitions": "0x8000",
|
||||
"littlefs": "0x910000"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"modules": {
|
||||
"virtual_elments": [
|
||||
{
|
||||
"path": "src/modules/virtual/Benchmark",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/Cron",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/GoogleSheet",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/Loging",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/LogingDaily",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/Math",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/owmWeather",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/Ping",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/Timer",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/Variable",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/VButton",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/Weather",
|
||||
"active": false
|
||||
}
|
||||
],
|
||||
"sensors": [
|
||||
{
|
||||
"path": "src/modules/exec/Pcf8591",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/A02Distance",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Acs712",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ads1115",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/AhtXX",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/AnalogAdc",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/BH_1750",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/BL0937",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ble",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ble_part1",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ble_part2",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Bme280",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Bmp280",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Dht1122",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ds18b20",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/DS2401",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Emon",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/EnergyMon485",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/ExampleModule",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/ExternalMQTT",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/FreqMeter",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/GY21",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Hdc1080",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Hx710",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Hx711",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Impulse",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ina219",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ina226",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/IoTWiegand",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/ld2410",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Max6675",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Mhz19",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/MQgas",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ntc",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Pzem004t",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Pzem004t_v2",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/RCswitch",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/RTC",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/S8",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Scd40",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Sds011",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Sgp30",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Sht20",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Sht30",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Sonar",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/UART",
|
||||
"active": true
|
||||
}
|
||||
],
|
||||
"executive_devices": [
|
||||
{
|
||||
"path": "src/modules/exec/AnalogBtn",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/BrokerMQTT",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/ButtonIn",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/ButtonOut",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Buzzer",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Enconder",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/EspCam",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Ftp",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/HttpGet",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/IoTServo",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Mcp23008",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Mcp23017",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Mp3",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Multitouch",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/MySensors",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Pcf8574",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Pwm32",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Pwm8266",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/SDcard",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/SIM800",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/SmartBoiler",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/SysExt",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Telegram",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/TelegramLT",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Telegram_v2",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Thermostat",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ds2423",
|
||||
"active": false
|
||||
}
|
||||
],
|
||||
"screens": [
|
||||
{
|
||||
"path": "src/modules/display/DwinI",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/Lcd2004",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/Nextion",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/NextionUpload",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/Oled128",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/Oled64",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/Smi2_m",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/TM16XX",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/Ws2812b",
|
||||
"active": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
/*.js.gz
|
||||
/.exclude.files
|
||||
@@ -1 +0,0 @@
|
||||
{"SSDP":"MODULES","chipID":"905542-1458415","ssidAP":"WiFi","passwordAP":"","ssid":"rise","password":"hostel3333","timezone":3,"mqttServer":"m12.cloudmqtt.com","mqttPort":14053,"mqttUser":"lbscvzuj","mqttPass":"bLxlveOgaF8F","scenario":"1","timers":"0","pushingbox_id":"v7C133E426B0C69E","web_login":"admin","web_pass":"admin"}
|
||||
@@ -1 +0,0 @@
|
||||
{"SSDP":"MODULES","chipID":"905542-1458415","ssidAP":"WiFi","passwordAP":"","ssid":"your_ssid","password":"your_pass","timezone":3,"mqttServer":"","mqttPort":0,"mqttUser":"","mqttPass":"","scenario":"1","timers":"0","pushingbox_id":"","web_login":"admin","web_pass":"admin"}
|
||||
@@ -1,148 +0,0 @@
|
||||
{
|
||||
"configs": [
|
||||
|
||||
"/config.live.json",
|
||||
"/config.setup.json",
|
||||
"/config.option.json"
|
||||
],
|
||||
"class":"col-sm-offset-1 col-sm-10",
|
||||
"content": [
|
||||
{
|
||||
"type": "h5",
|
||||
"title": "{{SSDP}}",
|
||||
"class":"alert-warning"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Device ID: {{chipID}}"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "IP address: {{ip}}"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Uptime: {{uptime}}"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "h2",
|
||||
"title": "Конфигурация устройства"
|
||||
},
|
||||
{
|
||||
"type":"file",
|
||||
"state":"firmware.config.txt",
|
||||
"style":"width:100%;height:400px",
|
||||
"title": "Сохранить",
|
||||
"action": "/all_modules_init",
|
||||
"class":"btn btn-block btn-success"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Инструкция",
|
||||
"action": "https://github.com/DmitryBorisenko33/esp8266_iot-manager_modules_firmware/wiki/Instruction",
|
||||
"class": "btn btn-block btn-primary"
|
||||
},
|
||||
{
|
||||
"type": "h2",
|
||||
"title": "Сценарии"
|
||||
},
|
||||
{
|
||||
"type": "checkbox",
|
||||
"name":"scenario",
|
||||
"title": "Включить сценарии",
|
||||
"action": "/scenario?status=[[scenario]]",
|
||||
"state": "{{scenario}}"
|
||||
},
|
||||
{
|
||||
"type": "h6",
|
||||
"title": ""
|
||||
},
|
||||
{
|
||||
"type":"file",
|
||||
"state":"firmware.scenario.txt",
|
||||
"style":"width:100%;height:400px",
|
||||
"title": "Сохранить и включить",
|
||||
"action": "/scenario?status=1",
|
||||
"class":"btn btn-block btn-success"
|
||||
},
|
||||
{
|
||||
"type": "h2",
|
||||
"title": "Данные модулей"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Модуль уровня воды (level)",
|
||||
"style": "width:100%"
|
||||
},
|
||||
|
||||
{
|
||||
"type": "h6",
|
||||
"title": "Расстояние от датчика до воды: {{level_in}} см"
|
||||
},
|
||||
{
|
||||
"type": "h6",
|
||||
"title": " Заполнение бака: {{level}} %"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Модуль аналогового входа (analog)",
|
||||
"style": "width:100%"
|
||||
},
|
||||
{
|
||||
"type": "h6",
|
||||
"title": "Прочитанное значение: {{analog_in}}"
|
||||
},
|
||||
{
|
||||
"type": "h6",
|
||||
"title": "Преобразованное значение: {{analog}}"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Модуль температурного датчика (dallas)",
|
||||
"style": "width:100%"
|
||||
},
|
||||
{
|
||||
"type": "h6",
|
||||
"title": "Текущее значение: {{dallas}} °C"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Модуль pH сенсора от df robot (ph)",
|
||||
"style": "width:100%"
|
||||
},
|
||||
{
|
||||
"type": "h6",
|
||||
"title": "Текущее значение: {{ph}}"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Очистить все логи",
|
||||
"action": "/cleanlog",
|
||||
"class": "btn btn-block btn-success"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Главная",
|
||||
"action": "/page.htm?index",
|
||||
"class": "btn btn-block btn-danger btn-sm"
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
572
data/edit.htm
572
data/edit.htm
@@ -1,572 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>ESP Editor</title>
|
||||
<style type="text/css" media="screen">
|
||||
.contextMenu{z-index:300;position:absolute;left:5px;border:1px solid #444;background-color:#f5f5f5;display:none;box-shadow:0 0 10px rgba(0,0,0,.4);font-size:12px;font-family:sans-serif;font-weight:bold}
|
||||
.contextMenu ul{list-style:none;top:0;left:0;margin:0;padding:0}
|
||||
.contextMenu li{position:relative;min-width:60px;cursor:pointer}
|
||||
.contextMenu span{color:#444;display:inline-block;padding:6px}
|
||||
.contextMenu li:hover{background:#444}
|
||||
.contextMenu li:hover span{color:#EEE}
|
||||
.css-treeview ul,.css-treeview li{padding:0;margin:0;list-style:none}
|
||||
.css-treeview input{position:absolute;opacity:0}
|
||||
.css-treeview{font:normal 11px Verdana,Arial,Sans-serif;-moz-user-select:none;-webkit-user-select:none;user-select:none}
|
||||
.css-treeview span{color:#00f;cursor:pointer}
|
||||
.css-treeview span:hover{text-decoration:underline}
|
||||
.css-treeview input+label+ul{margin:0 0 0 22px}
|
||||
.css-treeview input ~ ul{display:none}
|
||||
.css-treeview label,.css-treeview label::before{cursor:pointer}
|
||||
.css-treeview input:disabled+label{cursor:default;opacity:.6}
|
||||
.css-treeview input:checked:not(:disabled) ~ ul{display:block}
|
||||
.css-treeview label,.css-treeview label::before{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAACgCAYAAAAFOewUAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAApxJREFUeNrslM1u00AQgGdthyalFFOK+ClIIKQKyqUVQvTEE3DmAhLwAhU8QZoH4A2Q2gMSFace4MCtJ8SPBFwAkRuiHKpA6sRN/Lu7zG5i14kctaUqRGhGXnu9O/Pt7MzsMiklvF+9t2kWTDvyIrAsA0aKRRi1T0C/hJ4LUbt5/8rNpWVlp8RSr9J40b48fxFaTQ9+ft8EZ6MJYb0Ok+dnYGpmPgXwKIAvLx8vYXc5GdMAQJgQEkpjRTh36TS2U+DWW/D17WuYgm8pwJyY1npZsZKOxImOV1I/h4+O6vEg5GCZBpgmA6hX8wHKUHDRBXQYicQ4rlc3Tf0VMs8DHBS864F2YFspjgUYjKX/Az3gsdQd2eeBHwmdGWXHcgBGSkZXOXohcEXebRoQcAgjqediNY+AVyu3Z3sAKqfKoGMsewBeEIOPgQxxPJIjcGH6qtL/0AdADzKGnuuD+2tLK7Q8DhHHbOBW+KEzcHLuYc82MkEUekLiwuvVH+guQBQzOG4XdAb8EOcRcqQvDkY2iCLuxECJ43JobMXoutqGgDa2T7UqLKwt9KRyuxKVByqVXXqIoCCUCAqhUOioTWC7G4TQEOD0APy2/7G2Xpu1J4+lxeQ4TXBbITDpoVelRN/BVFbwu5oMMJUBhoXy5tmdRcMwymP2OLQaLjx9/vnBo6V3K6izATmSnMa0Dq7ferIohJhr1p01zrlz49rZF4OMs8JkX23vVQzYp+wbYGV/KpXKjvspl8tsIKCrMNAYFxj2GKS5ZWxg4ewKsJfaGMIY5KXqPz8LBBj6+yDvVP79+yDp/9F9oIx3OisHWwe7Oal0HxCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgwD8E/BZgAP0qhKj3rXO7AAAAAElFTkSuQmCC") no-repeat}
|
||||
.css-treeview label,.css-treeview span,.css-treeview label::before{display:inline-block;height:16px;line-height:16px;vertical-align:middle}
|
||||
.css-treeview label{background-position:18px 0}
|
||||
.css-treeview label::before{content:"";width:16px;margin:0 22px 0 0;vertical-align:middle;background-position:0 -32px}
|
||||
.css-treeview input:checked+label::before{background-position:0 -16px}
|
||||
@media screen and (-webkit-min-device-pixel-ratio:0){.css-treeview{-webkit-animation:webkit-adjacent-element-selector-bugfix infinite 1s}@-webkit-keyframes webkit-adjacent-element-selector-bugfix{from{padding:0}to{padding:0}}}
|
||||
#uploader{position:absolute;top:0;right:0;left:0;height:28px;line-height:24px;padding-left:10px;background-color:#444;color:#EEE}#tree{position:absolute;top:28px;bottom:0;left:0;width:200px;padding:8px}
|
||||
#editor,#preview{position:absolute;top:28px;right:0;bottom:0;left:200px}
|
||||
#preview{background-color:#EEE;padding:5px}
|
||||
</style>
|
||||
<script>
|
||||
|
||||
var urlXXX = 'http://192.168.211.181';//bolt
|
||||
if (window.location.search.substring(1).split("=")[1]) {
|
||||
urlXXX = 'http://'+window.location.search.substring(1).split("=")[1];
|
||||
} else {
|
||||
urlXXX = 'http://'+window.location.hostname;
|
||||
}
|
||||
|
||||
function createFileUploader(element, tree, editor){
|
||||
var xmlHttp;
|
||||
var input = document.createElement("input");
|
||||
input.type = "file";
|
||||
input.multiple = false;
|
||||
input.name = "data";
|
||||
document.getElementById(element).appendChild(input);
|
||||
var path = document.createElement("input");
|
||||
path.id = "upload-path";
|
||||
path.type = "text";
|
||||
path.name = "path";
|
||||
path.defaultValue = "/";
|
||||
document.getElementById(element).appendChild(path);
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = 'Upload';
|
||||
document.getElementById(element).appendChild(button);
|
||||
var mkdir = document.createElement("button");
|
||||
mkdir.innerHTML = 'MkDir';
|
||||
document.getElementById(element).appendChild(mkdir);
|
||||
var mkfile = document.createElement("button");
|
||||
mkfile.innerHTML = 'MkFile';
|
||||
document.getElementById(element).appendChild(mkfile);
|
||||
|
||||
function httpPostProcessRequest(){
|
||||
if (xmlHttp.readyState == 4){
|
||||
if(xmlHttp.status != 200) alert("ERROR["+xmlHttp.status+"]: "+xmlHttp.responseText);
|
||||
else {
|
||||
tree.refreshPath(path.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
function createPath(p){
|
||||
xmlHttp = new XMLHttpRequest();
|
||||
xmlHttp.onreadystatechange = httpPostProcessRequest;
|
||||
var formData = new FormData();
|
||||
formData.append("path", p);
|
||||
xmlHttp.open("PUT", urlXXX+"/edit");
|
||||
xmlHttp.send(formData);
|
||||
}
|
||||
|
||||
mkfile.onclick = function(e){
|
||||
if(path.value.indexOf(".") === -1) return;
|
||||
createPath(path.value);
|
||||
editor.loadUrl(path.value);
|
||||
};
|
||||
mkdir.onclick = function(e){
|
||||
if(path.value.length < 2) return;
|
||||
var dir = path.value
|
||||
if(dir.indexOf(".") !== -1){
|
||||
if(dir.lastIndexOf("/") === 0) return;
|
||||
dir = dir.substring(0, dir.lastIndexOf("/"));
|
||||
}
|
||||
createPath(dir);
|
||||
};
|
||||
button.onclick = function(e){
|
||||
if(input.files.length === 0){
|
||||
return;
|
||||
}
|
||||
xmlHttp = new XMLHttpRequest();
|
||||
xmlHttp.onreadystatechange = httpPostProcessRequest;
|
||||
var formData = new FormData();
|
||||
formData.append("data", input.files[0], path.value);
|
||||
xmlHttp.open("POST", urlXXX+"/edit");
|
||||
xmlHttp.send(formData);
|
||||
}
|
||||
input.onchange = function(e){
|
||||
if(input.files.length === 0) return;
|
||||
var filename = input.files[0].name;
|
||||
var ext = /(?:\.([^.]+))?$/.exec(filename)[1];
|
||||
var name = /(.*)\.[^.]+$/.exec(filename)[1];
|
||||
if(typeof name !== undefined){
|
||||
//1197 bolt if(name.length > 8) name = name.substring(0, 8);
|
||||
filename = name;
|
||||
}
|
||||
if(typeof ext !== undefined){
|
||||
if(ext === "html") ext = "htm";
|
||||
else if(ext === "jpeg") ext = "jpg";
|
||||
filename = filename + "." + ext;
|
||||
}
|
||||
if(path.value === "/" || path.value.lastIndexOf("/") === 0){
|
||||
path.value = "/"+filename;
|
||||
} else {
|
||||
path.value = path.value.substring(0, path.value.lastIndexOf("/")+1)+filename;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createTree(element, editor){
|
||||
var preview = document.getElementById("preview");
|
||||
var treeRoot = document.createElement("div");
|
||||
treeRoot.className = "css-treeview";
|
||||
document.getElementById(element).appendChild(treeRoot);
|
||||
|
||||
function loadDownload(path){
|
||||
document.getElementById('download-frame').src = path+"?download=true";
|
||||
}
|
||||
|
||||
function loadPreview(path){
|
||||
document.getElementById("editor").style.display = "none";
|
||||
preview.style.display = "block";
|
||||
preview.innerHTML = '<img src="'+ urlXXX +path+'" style="max-width:100%; max-height:100%; margin:auto; display:block;" />';
|
||||
}
|
||||
|
||||
function fillFolderMenu(el, path){
|
||||
var list = document.createElement("ul");
|
||||
el.appendChild(list);
|
||||
var action = document.createElement("li");
|
||||
list.appendChild(action);
|
||||
var isChecked = document.getElementById(path).checked;
|
||||
var expnd = document.createElement("li");
|
||||
list.appendChild(expnd);
|
||||
if(isChecked){
|
||||
expnd.innerHTML = "<span>Collapse</span>";
|
||||
expnd.onclick = function(e){
|
||||
document.getElementById(path).checked = false;
|
||||
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
|
||||
};
|
||||
var refrsh = document.createElement("li");
|
||||
list.appendChild(refrsh);
|
||||
refrsh.innerHTML = "<span>Refresh</span>";
|
||||
refrsh.onclick = function(e){
|
||||
var leaf = document.getElementById(path).parentNode;
|
||||
if(leaf.childNodes.length == 3) leaf.removeChild(leaf.childNodes[2]);
|
||||
httpGet(leaf, path);
|
||||
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
|
||||
};
|
||||
} else {
|
||||
expnd.innerHTML = "<span>Expand</span>";
|
||||
expnd.onclick = function(e){
|
||||
document.getElementById(path).checked = true;
|
||||
var leaf = document.getElementById(path).parentNode;
|
||||
if(leaf.childNodes.length == 3) leaf.removeChild(leaf.childNodes[2]);
|
||||
httpGet(leaf, path);
|
||||
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
|
||||
};
|
||||
}
|
||||
var upload = document.createElement("li");
|
||||
list.appendChild(upload);
|
||||
upload.innerHTML = "<span>Upload</span>";
|
||||
upload.onclick = function(e){
|
||||
var pathEl = document.getElementById("upload-path");
|
||||
if(pathEl){
|
||||
var subPath = pathEl.value;
|
||||
if(subPath.lastIndexOf("/") < 1) pathEl.value = path+subPath;
|
||||
else pathEl.value = path.substring(subPath.lastIndexOf("/"))+subPath;
|
||||
}
|
||||
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
|
||||
};
|
||||
var delFile = document.createElement("li");
|
||||
list.appendChild(delFile);
|
||||
delFile.innerHTML = "<span>Delete</span>";
|
||||
delFile.onclick = function(e){
|
||||
httpDelete(path);
|
||||
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
|
||||
};
|
||||
}
|
||||
|
||||
function fillFileMenu(el, path){
|
||||
var list = document.createElement("ul");
|
||||
el.appendChild(list);
|
||||
var action = document.createElement("li");
|
||||
list.appendChild(action);
|
||||
if(isTextFile(path)){
|
||||
action.innerHTML = "<span>Edit</span>";
|
||||
action.onclick = function(e){
|
||||
editor.loadUrl(path);
|
||||
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
|
||||
};
|
||||
} else if(isImageFile(path)){
|
||||
action.innerHTML = "<span>Preview</span>";
|
||||
action.onclick = function(e){
|
||||
loadPreview(path);
|
||||
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
|
||||
};
|
||||
}
|
||||
var download = document.createElement("li");
|
||||
list.appendChild(download);
|
||||
download.innerHTML = "<span>Download</span>";
|
||||
download.onclick = function(e){
|
||||
loadDownload(path);
|
||||
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
|
||||
};
|
||||
var delFile = document.createElement("li");
|
||||
list.appendChild(delFile);
|
||||
delFile.innerHTML = "<span>Delete</span>";
|
||||
delFile.onclick = function(e){
|
||||
httpDelete(path);
|
||||
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
|
||||
};
|
||||
}
|
||||
|
||||
function showContextMenu(e, path, isfile){
|
||||
var divContext = document.createElement("div");
|
||||
var scrollTop = document.body.scrollTop ? document.body.scrollTop : document.documentElement.scrollTop;
|
||||
var scrollLeft = document.body.scrollLeft ? document.body.scrollLeft : document.documentElement.scrollLeft;
|
||||
var left = e.clientX + scrollLeft;
|
||||
var top = e.clientY + scrollTop;
|
||||
divContext.className = 'contextMenu';
|
||||
divContext.style.display = 'block';
|
||||
divContext.style.left = left + 'px';
|
||||
divContext.style.top = top + 'px';
|
||||
if(isfile) fillFileMenu(divContext, path);
|
||||
else fillFolderMenu(divContext, path);
|
||||
document.body.appendChild(divContext);
|
||||
var width = divContext.offsetWidth;
|
||||
var height = divContext.offsetHeight;
|
||||
divContext.onmouseout = function(e){
|
||||
if(e.clientX < left || e.clientX > (left + width) || e.clientY < top || e.clientY > (top + height)){
|
||||
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(divContext);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function createTreeLeaf(path, name, size){
|
||||
var leaf = document.createElement("li");
|
||||
leaf.id = (((path == "/")?"":path)+"/"+name).toLowerCase();
|
||||
var label = document.createElement("span");
|
||||
label.textContent = name.toLowerCase();
|
||||
leaf.appendChild(label);
|
||||
leaf.onclick = function(e){
|
||||
if(isTextFile(leaf.id)){
|
||||
editor.loadUrl(leaf.id);
|
||||
} else if(isImageFile(leaf.id)){
|
||||
loadPreview(leaf.id);
|
||||
}
|
||||
};
|
||||
leaf.oncontextmenu = function(e){
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
showContextMenu(e, leaf.id, true);
|
||||
};
|
||||
return leaf;
|
||||
}
|
||||
|
||||
function createTreeBranch(path, name, disabled){
|
||||
var leaf = document.createElement("li");
|
||||
var check = document.createElement("input");
|
||||
check.type = "checkbox";
|
||||
check.id = (((path == "/")?"":path)+"/"+name).toLowerCase();
|
||||
if(typeof disabled !== "undefined" && disabled) check.disabled = "disabled";
|
||||
leaf.appendChild(check);
|
||||
var label = document.createElement("label");
|
||||
label.for = check.id;
|
||||
label.textContent = name.toLowerCase();
|
||||
leaf.appendChild(label);
|
||||
check.onchange = function(e){
|
||||
if(check.checked){
|
||||
if(leaf.childNodes.length == 3) leaf.removeChild(leaf.childNodes[2]);
|
||||
httpGet(leaf, check.id);
|
||||
}
|
||||
};
|
||||
label.onclick = function(e){
|
||||
if(!check.checked){
|
||||
check.checked = true;
|
||||
if(leaf.childNodes.length == 3) leaf.removeChild(leaf.childNodes[2]);
|
||||
httpGet(leaf, check.id);
|
||||
} else {
|
||||
check.checked = false;
|
||||
}
|
||||
};
|
||||
leaf.oncontextmenu = function(e){
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
showContextMenu(e, check.id, false);
|
||||
}
|
||||
return leaf;
|
||||
}
|
||||
|
||||
function addList(parent, path, items){
|
||||
var list = document.createElement("ul");
|
||||
parent.appendChild(list);
|
||||
var ll = items.length;
|
||||
//Сортировка файлов
|
||||
items.sort(function(a,b){return (a.name < b.name) ? 1 : ((b.name < a.name) ? -1 : 0);});
|
||||
for(var i = 0; i < ll; i++){
|
||||
var item = items[i];
|
||||
var itemEl;
|
||||
if(item.type === "file"){
|
||||
itemEl = createTreeLeaf(path, item.name, item.size);
|
||||
} else {
|
||||
itemEl = createTreeBranch(path, item.name);
|
||||
}
|
||||
list.appendChild(itemEl);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function isTextFile(path){
|
||||
var ext = /(?:\.([^.]+))?$/.exec(path)[1];
|
||||
if(typeof ext !== undefined){
|
||||
switch(ext){
|
||||
case "txt":
|
||||
case "htm":
|
||||
case "html":
|
||||
case "js":
|
||||
case "json":
|
||||
case "c":
|
||||
case "h":
|
||||
case "cpp":
|
||||
case "css":
|
||||
case "xml":
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isImageFile(path){
|
||||
var ext = /(?:\.([^.]+))?$/.exec(path)[1];
|
||||
if(typeof ext !== undefined){
|
||||
switch(ext){
|
||||
case "png":
|
||||
case "jpg":
|
||||
case "gif":
|
||||
case "ico":
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
this.refreshPath = function(path){
|
||||
if(path.lastIndexOf('/') < 1){
|
||||
path = '/';
|
||||
treeRoot.removeChild(treeRoot.childNodes[0]);
|
||||
httpGet(treeRoot, "/");
|
||||
} else {
|
||||
path = path.substring(0, path.lastIndexOf('/'));
|
||||
var leaf = document.getElementById(path).parentNode;
|
||||
if(leaf.childNodes.length == 3) leaf.removeChild(leaf.childNodes[2]);
|
||||
httpGet(leaf, path);
|
||||
}
|
||||
};
|
||||
|
||||
function delCb(path){
|
||||
return function(){
|
||||
if (xmlHttp.readyState == 4){
|
||||
if(xmlHttp.status != 200){
|
||||
alert("ERROR["+xmlHttp.status+"]: "+xmlHttp.responseText);
|
||||
} else {
|
||||
if(path.lastIndexOf('/') < 1){
|
||||
path = '/';
|
||||
treeRoot.removeChild(treeRoot.childNodes[0]);
|
||||
httpGet(treeRoot, "/");
|
||||
} else {
|
||||
path = path.substring(0, path.lastIndexOf('/'));
|
||||
var leaf = document.getElementById(path).parentNode;
|
||||
if(leaf.childNodes.length == 3) leaf.removeChild(leaf.childNodes[2]);
|
||||
httpGet(leaf, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function httpDelete(filename){
|
||||
xmlHttp = new XMLHttpRequest();
|
||||
xmlHttp.onreadystatechange = delCb(filename);
|
||||
var formData = new FormData();
|
||||
formData.append("path", filename);
|
||||
xmlHttp.open("DELETE", urlXXX+"/edit");
|
||||
xmlHttp.send(formData);
|
||||
}
|
||||
|
||||
function getCb(parent, path){
|
||||
return function(){
|
||||
if (xmlHttp.readyState == 4){
|
||||
//clear loading
|
||||
if(xmlHttp.status == 200) addList(parent, path, JSON.parse(xmlHttp.responseText));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function httpGet(parent, path){
|
||||
xmlHttp = new XMLHttpRequest(parent, path);
|
||||
xmlHttp.onreadystatechange = getCb(parent, path);
|
||||
//Для отключения кэша random() иначе будут старые данные
|
||||
xmlHttp.open("GET", urlXXX+"/edit?list=" + path +"&rand="+Math.random(), true);
|
||||
xmlHttp.send(null);
|
||||
//start loading
|
||||
}
|
||||
|
||||
httpGet(treeRoot, "/");
|
||||
return this;
|
||||
}
|
||||
|
||||
function createEditor(element, file, lang, theme, type){
|
||||
function getLangFromFilename(filename){
|
||||
var lang = "plain";
|
||||
var ext = /(?:\.([^.]+))?$/.exec(filename)[1];
|
||||
if(typeof ext !== undefined){
|
||||
switch(ext){
|
||||
case "txt": lang = "plain"; break;
|
||||
case "htm": lang = "html"; break;
|
||||
case "js": lang = "javascript"; break;
|
||||
case "c": lang = "c_cpp"; break;
|
||||
case "cpp": lang = "c_cpp"; break;
|
||||
case "css":
|
||||
case "scss":
|
||||
case "php":
|
||||
case "html":
|
||||
case "json":
|
||||
case "xml":
|
||||
lang = ext;
|
||||
}
|
||||
}
|
||||
return lang;
|
||||
}
|
||||
|
||||
if(typeof file === "undefined") file = "/index.htm";
|
||||
|
||||
if(typeof lang === "undefined"){
|
||||
lang = getLangFromFilename(file);
|
||||
}
|
||||
|
||||
if(typeof theme === "undefined") theme = "textmate";
|
||||
|
||||
if(typeof type === "undefined"){
|
||||
type = "text/"+lang;
|
||||
if(lang === "c_cpp") type = "text/plain";
|
||||
}
|
||||
|
||||
var xmlHttp = null;
|
||||
var editor = ace.edit(element);
|
||||
|
||||
//post
|
||||
function httpPostProcessRequest(){
|
||||
if (xmlHttp.readyState == 4){
|
||||
if(xmlHttp.status != 200) alert("ERROR["+xmlHttp.status+"]: "+xmlHttp.responseText);
|
||||
}
|
||||
}
|
||||
function httpPost(filename, data, type){
|
||||
xmlHttp = new XMLHttpRequest();
|
||||
xmlHttp.onreadystatechange = httpPostProcessRequest;
|
||||
var formData = new FormData();
|
||||
formData.append("data", new Blob([data], { type: type }), filename);
|
||||
xmlHttp.open("POST", urlXXX + "/edit");
|
||||
xmlHttp.send(formData);
|
||||
}
|
||||
//get
|
||||
function httpGetProcessRequest(){
|
||||
if (xmlHttp.readyState == 4){
|
||||
document.getElementById("preview").style.display = "none";
|
||||
document.getElementById("editor").style.display = "block";
|
||||
if(xmlHttp.status == 200) editor.setValue(xmlHttp.responseText);
|
||||
else editor.setValue("");
|
||||
editor.clearSelection();
|
||||
}
|
||||
}
|
||||
function httpGet(theUrl){
|
||||
xmlHttp = new XMLHttpRequest();
|
||||
xmlHttp.onreadystatechange = httpGetProcessRequest;
|
||||
if (theUrl.indexOf("/") == 0)
|
||||
theUrl = urlXXX + theUrl;//bolt
|
||||
xmlHttp.open("GET", theUrl+"?rand="+Math.random(), true);
|
||||
xmlHttp.send(null);
|
||||
}
|
||||
|
||||
if(lang !== "plain") editor.getSession().setMode("ace/mode/"+lang);
|
||||
editor.setTheme("ace/theme/"+theme);
|
||||
editor.$blockScrolling = Infinity;
|
||||
editor.getSession().setUseSoftTabs(true);
|
||||
editor.getSession().setTabSize(2);
|
||||
editor.setHighlightActiveLine(true);
|
||||
editor.setShowPrintMargin(false);
|
||||
editor.commands.addCommand({
|
||||
name: 'saveCommand',
|
||||
bindKey: {win: 'Ctrl-S', mac: 'Command-S'},
|
||||
exec: function(editor) {
|
||||
httpPost(file, editor.getValue()+"", type);
|
||||
},
|
||||
readOnly: false
|
||||
});
|
||||
editor.commands.addCommand({
|
||||
name: 'undoCommand',
|
||||
bindKey: {win: 'Ctrl-Z', mac: 'Command-Z'},
|
||||
exec: function(editor) {
|
||||
editor.getSession().getUndoManager().undo(false);
|
||||
},
|
||||
readOnly: false
|
||||
});
|
||||
editor.commands.addCommand({
|
||||
name: 'redoCommand',
|
||||
bindKey: {win: 'Ctrl-Shift-Z', mac: 'Command-Shift-Z'},
|
||||
exec: function(editor) {
|
||||
editor.getSession().getUndoManager().redo(false);
|
||||
},
|
||||
readOnly: false
|
||||
});
|
||||
httpGet(file);
|
||||
editor.loadUrl = function(filename){
|
||||
file = filename;
|
||||
lang = getLangFromFilename(file);
|
||||
type = "text/"+lang;
|
||||
if(lang !== "plain") editor.getSession().setMode("ace/mode/"+lang);
|
||||
httpGet(file);
|
||||
}
|
||||
return editor;
|
||||
}
|
||||
function onBodyLoad(){
|
||||
var vars = {};
|
||||
// var s = "http://192.168.211.180/edit/index.htm";
|
||||
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) { vars[key] = value; });
|
||||
// var parts = s.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) { vars[key] = value; });
|
||||
if (typeof vars.url !== "undefined" && vars.url != "")
|
||||
urlXXX = "http://" + vars.url;/**/
|
||||
var editor = createEditor("editor", vars.file, vars.lang, vars.theme);
|
||||
var tree = createTree("tree", editor);
|
||||
createFileUploader("uploader", tree, editor);
|
||||
};
|
||||
</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.6/ace.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script>
|
||||
(function() {
|
||||
window.require(["ace/ace"], function(a) {
|
||||
a && a.config.init(true);
|
||||
if (!window.ace)
|
||||
window.ace = a;
|
||||
for (var key in a) if (a.hasOwnProperty(key))
|
||||
window.ace[key] = a[key];
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body onload="onBodyLoad();">
|
||||
<div id="uploader"></div>
|
||||
<div id="tree"></div>
|
||||
<div id="editor"></div>
|
||||
<div id="preview" style="display:none;"></div>
|
||||
<iframe id=download-frame style='display:none;'></iframe>
|
||||
</body>
|
||||
</html>
|
||||
BIN
data/favicon.ico
BIN
data/favicon.ico
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -1,29 +0,0 @@
|
||||
button 1 na Включить#все Реле 0 1
|
||||
button 2 13 Прихожая Реле 0 2
|
||||
button 3 14 Кухня Реле 0 3
|
||||
pwm 1 3 Яркость#коредор: Реле 1023 4
|
||||
pwm 2 4 Яркость#ванная: Реле 510 5
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//analog 0 Аналоговый#вход,#% Датчики progress-round 1 1024 1 1024 6
|
||||
inputDigit digit1 При#скольки#включить? Датчики 10 7
|
||||
inputDigit digit2 При#скольки#выключить? Датчики 0 8
|
||||
button 4 na Нагреватель Датчики 0 9
|
||||
//dallas 2 Водонагреватель,#t°C Датчики any-data 10
|
||||
dhtT DHT11 2 Температура#DHT,#t°C Датчики any-data 11
|
||||
dhtH DHT11 2 Влажность#DHT,#% Датчики any-data 12
|
||||
dhtComfort Степень#комфорта: Датчики 12
|
||||
dhtPerception Восприятие: Датчики 13
|
||||
//level Вода#в#баке,#% Датчики any-data 125 20 14
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
button 5 na Вкл#обратный#таймер Таймеры 0 15
|
||||
inputDigit digit3 Через#сколько#секунд#включить? Таймеры 5 16
|
||||
button 6 na Включится#по#таймеру Таймеры 0 17
|
||||
inputTime time1 Во#сколько#включить? Таймеры 20.30 18
|
||||
button 7 5 Включится#по#таймеру Таймеры 0 19
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
switch 1 0 20
|
||||
textSet 1 неопределено
|
||||
text 1 Квартира Двери 22
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
button 8 scenario Вкл#выкл#все#сценарии Сценарии 1 23
|
||||
button 9 line1,line2, Вкл#выкл#выбранные#сценарии Сценарии 1 24
|
||||
@@ -1,32 +0,0 @@
|
||||
button1 = 1
|
||||
buttonSet 2 1
|
||||
buttonSet 3 1
|
||||
pwmSet 2 1024
|
||||
end
|
||||
button1 = 0
|
||||
buttonSet 2 0
|
||||
buttonSet 3 0
|
||||
pwmSet 2 0
|
||||
end
|
||||
analog > digit1
|
||||
buttonSet 4 1
|
||||
end
|
||||
analog < digit2
|
||||
buttonSet 4 0
|
||||
end
|
||||
button5 = 1
|
||||
timerStart 1 digit3 sec
|
||||
end
|
||||
timer1 = 0
|
||||
buttonSet 6 1
|
||||
end
|
||||
timenow = time1
|
||||
buttonSet 7 1
|
||||
end
|
||||
switch1 = 1
|
||||
textSet 1 закрыто-time
|
||||
push закрыто вход
|
||||
end
|
||||
switch1 = 0
|
||||
textSet 1 открыто-time
|
||||
end
|
||||
@@ -1,75 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<!--
|
||||
Web Developer: Renats Kevrels (ex. Zozula)
|
||||
Site: http://www.onclick.lv
|
||||
Contact: info [at] onclick.lv
|
||||
Skype: renat2985
|
||||
Twitter: @Ramzies
|
||||
Facebook: http://www.facebook.com/renat2985
|
||||
GitHub: https://github.com/renat2985
|
||||
From: Latvia, Valmiera
|
||||
-->
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
||||
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico">
|
||||
<script defer src="js/build.chart.js?v07.04.2018" charset="utf-8"></script>
|
||||
<!-- <link rel="stylesheet" type="text/css" href="css/chartist.min.css">
|
||||
<script src="js/chartist.min.js" charset="utf-8"></script>
|
||||
<script type="text/javascript" src="js/chart.js"></script> -->
|
||||
<link rel="stylesheet" type="text/css" href="css/build.css?v07.04.2018">
|
||||
<!-- <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/style.css"> -->
|
||||
<script defer type="text/javascript" src="js/function.js?v07.04.2018"></script>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title></title>
|
||||
<script type="text/javascript">
|
||||
var jsonResponse;
|
||||
|
||||
//function selectTextareaLine(tarea,lineNum) {
|
||||
// lineNum--;
|
||||
// var lines = tarea.value.split("\n");
|
||||
// var startPos = 0, endPos = tarea.value.length;
|
||||
// for(var x = 0; x < lines.length; x++) {
|
||||
// if(x == lineNum) {break;}
|
||||
// startPos += (lines[x].length+1);
|
||||
// }
|
||||
// var endPos = lines[lineNum].length+startPos;
|
||||
// if(typeof(tarea.selectionStart) != "undefined") {
|
||||
// tarea.focus();
|
||||
// tarea.selectionStart = startPos;
|
||||
// tarea.selectionEnd = endPos;
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
//}
|
||||
|
||||
window.onload = function() {
|
||||
setContent('first');
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container loader-bg">
|
||||
|
||||
<ul id="url-content" class="hidden" onclick="document.getElementById('content').style.zIndex=0;"></ul>
|
||||
<div id="headers"></div>
|
||||
<div class="row hidden" id="container_column">
|
||||
<h1 id="title"></h1>
|
||||
<div id="content" onclick="this.style.zIndex=10"></div>
|
||||
</div>
|
||||
<div id="footer"></div>
|
||||
<div id="edit-content" class="hidden" onclick="document.getElementById('content').style.zIndex=0;">
|
||||
<a target="_blank" style="position:fixed;right:0;color:#000;" href="https://github.com/tretyakovsa/Sonoff_WiFi_switch/wiki/%D0%92%D0%BE%D0%B7%D0%BC%D0%BE%D0%B6%D0%BD%D0%BE%D1%81%D1%82%D0%B8-page.htm%3F*" title="Github wiki"><i class="help-img"></i>wiki</a>
|
||||
<textarea class="form-control" onkeyup="isValidJson(this.value,'edit-json')" spellcheck="false" id="edit-json"></textarea>
|
||||
<div id="error-json"></div>
|
||||
<div class="btn-group btn-block">
|
||||
<input class="btn btn-success" style="width:40%" id="edit-view" onclick="setContent('edit');this.value='Loading...';html('url-content', ' ');" value="View" type="button">
|
||||
<input class="btn btn-danger" style="width:40%" id="edit-save" onclick="var urlPages=window.location.search.substring(1).split('&')[0];httpDelete('/'+urlPages+'.json.gz');send_request_edit(this, val('edit-json'),(urlPages?urlPages:'index')+'.json');toggle('edit-content');toggle('url-content');" value="Save" type="button">
|
||||
<a class="btn btn-info" style="width:20%" href="#" id="download-json" download="" title="Save to PC"><i class="download-img"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
@@ -1,62 +0,0 @@
|
||||
{
|
||||
"configs": [
|
||||
"/config.live.json",
|
||||
"/config.setup.json"
|
||||
],
|
||||
"title": "Главная",
|
||||
"class": "col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6",
|
||||
"content": [
|
||||
{
|
||||
"type": "h5",
|
||||
"title": "{{SSDP}}",
|
||||
"class": "alert-warning"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Device ID: {{chipID}}"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "IP address: {{ip}}"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Конфигурация устройства",
|
||||
"action": "/page.htm?configuration",
|
||||
"class": "btn btn-block btn-primary"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Конфигурация WIFI",
|
||||
"action": "/page.htm?setup",
|
||||
"class": "btn btn-block btn-success"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Конфигурация MQTT",
|
||||
"action": "/page.htm?mqtt",
|
||||
"class": "btn btn-block btn-success"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Конфигурация push",
|
||||
"action": "/page.htm?pushingbox",
|
||||
"class": "btn btn-block btn-success"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Скачать приложение IoT Manager для android",
|
||||
"action": "https://play.google.com/store/apps/details?id=ru.esp8266.iotmanager",
|
||||
"class": "btn btn-block btn-warning"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Скачать приложение IoT Manager для iphone",
|
||||
"action": "https://apps.apple.com/ru/app/iot-manager/id1155934877",
|
||||
"class": "btn btn-block btn-warning"
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,79 +0,0 @@
|
||||
{
|
||||
"configs": [
|
||||
"/config.setup.json"
|
||||
],
|
||||
"class":"col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6",
|
||||
"content": [
|
||||
{
|
||||
"type": "h5",
|
||||
"title": "{{SSDP}}",
|
||||
"class":"alert-warning"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Server name:"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "",
|
||||
"name":"1",
|
||||
"state": "{{mqttServer}}"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Port:"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "",
|
||||
"name":"2",
|
||||
"state": "{{mqttPort}}"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "User name:"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "",
|
||||
"name":"3",
|
||||
"state": "{{mqttUser}}"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Password:"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "",
|
||||
"name":"4",
|
||||
"state": "{{mqttPass}}"
|
||||
},
|
||||
{
|
||||
"type":"h3",
|
||||
"name":"my-block",
|
||||
"style":"position:fixed;top:30%;left:50%;width:400px;margin-left:-200px;text-align:center;",
|
||||
"class":"hidden"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title":"Сохранить",
|
||||
"action": "mqttSave?mqttServer=[[1]]&mqttPort=[[2]]&mqttUser=[[3]]&mqttPass=[[4]]",
|
||||
"response":"[[my-block]]",
|
||||
"class": "btn btn-block btn-success",
|
||||
"style": "width:100%;display:inline"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Перезагрузить устройство",
|
||||
"action": "javascript:if(confirm(renameBlock(jsonResponse,'Перезагрузить?'))){send_request(this,'/restart?device=ok');}",
|
||||
"class": "btn btn-block btn-warning"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Главная",
|
||||
"action": "/page.htm?index",
|
||||
"class": "btn btn-block btn-danger btn-sm"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
data/page.htm.gz
BIN
data/page.htm.gz
Binary file not shown.
@@ -1,92 +0,0 @@
|
||||
{
|
||||
"configs": [
|
||||
"/config.setup.json"
|
||||
],
|
||||
"class":"col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6",
|
||||
"content": [
|
||||
{
|
||||
"type": "h5",
|
||||
"title": "{{SSDP}}",
|
||||
"class":"alert-warning"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Host name:"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "",
|
||||
"name":"1",
|
||||
"state": "{{pushHost}}"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Port:"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "",
|
||||
"name":"2",
|
||||
"state": "{{pushPort}}"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Fingerprint:"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "",
|
||||
"name":"3",
|
||||
"state": "{{pushFingerprint}}"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Access Token:"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "",
|
||||
"name":"4",
|
||||
"state": "{{pushAccessToken}}"
|
||||
},
|
||||
{
|
||||
"type":"h3",
|
||||
"name":"my-block",
|
||||
"style":"position:fixed;top:30%;left:50%;width:400px;margin-left:-200px;text-align:center;",
|
||||
"class":"hidden"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title":"Сохранить и проверить соединение",
|
||||
"action": "pushDate?pushHost=[[1]]&pushPort=[[2]]&pushFingerprint=[[3]]&pushAccessToken=[[4]]",
|
||||
"response":"[[my-block]]",
|
||||
"class": "btn btn-block btn-success",
|
||||
"style": "width:100%;display:inline"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "checkbox",
|
||||
"name":"start-push",
|
||||
"title": "Отправлять push при включении устройства",
|
||||
"action": "startPush?status=[[start-push]]",
|
||||
"state": "{{startPush}}"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Перезагрузить устройство",
|
||||
"action": "javascript:if(confirm(renameBlock(jsonResponse,'Перезагрузить?'))){send_request(this,'/restart?device=ok');}",
|
||||
"class": "btn btn-block btn-warning"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Главная",
|
||||
"action": "/page.htm?index",
|
||||
"class": "btn btn-block btn-danger btn-sm"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
{
|
||||
"configs": [
|
||||
"/config.setup.json"
|
||||
],
|
||||
"class":"col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6",
|
||||
"content": [
|
||||
{
|
||||
"type": "h5",
|
||||
"title": "{{SSDP}}",
|
||||
"class":"alert-warning"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Device id:"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "",
|
||||
"name":"1",
|
||||
"state": "{{pushingbox_id}}"
|
||||
},
|
||||
|
||||
{
|
||||
"type": "button",
|
||||
"title":"Сохранить",
|
||||
"action": "pushingboxDate?pushingbox_id=[[1]]",
|
||||
"class": "btn btn-block btn-success",
|
||||
"style": "width:100%;display:inline"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Перезагрузить устройство",
|
||||
"action": "javascript:if(confirm(renameBlock(jsonResponse,'Перезагрузить?'))){send_request(this,'/restart?device=ok');}",
|
||||
"class": "btn btn-block btn-warning"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Главная",
|
||||
"action": "/page.htm?index",
|
||||
"class": "btn btn-block btn-danger btn-sm"
|
||||
}
|
||||
]
|
||||
}
|
||||
149
data/setup.json
149
data/setup.json
@@ -1,149 +0,0 @@
|
||||
{
|
||||
"configs": [
|
||||
"/config.setup.json"
|
||||
],
|
||||
"title": "Конфигурация",
|
||||
"class":"col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6",
|
||||
"content": [
|
||||
{
|
||||
"type": "h5",
|
||||
"title": "{{SSDP}}",
|
||||
"class":"alert-warning"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Главная",
|
||||
"action": "/",
|
||||
"class": "btn btn-block btn-danger"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "h2",
|
||||
"title": "Имя устройства"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "Имя устройства",
|
||||
"name":"ssdp",
|
||||
"state": "{{SSDP}}",
|
||||
"pattern": "[0-9a-zA-Zа-яА-Я.\\- ]{1,20}"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "Сохранить",
|
||||
"action": "ssdp?ssdp=[[ssdp]]",
|
||||
"class": "btn btn-block btn-success"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "h2",
|
||||
"title": "Подключение к Wi-Fi роутеру"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title":"Сеть",
|
||||
"name":"ssid",
|
||||
"state": "{{ssid}}"
|
||||
},
|
||||
{
|
||||
"type": "password",
|
||||
"title": "Введите пароль",
|
||||
"name":"ssidPass",
|
||||
"state": "{{password}}",
|
||||
"pattern": ".{8,20}"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "Сохранить",
|
||||
"class": "btn btn-block btn-success",
|
||||
"action": "ssid?ssid=[[ssid]]&password=[[ssidPass]]"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "h2",
|
||||
"title": "Точка доступа"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "Имя WI-FI сети",
|
||||
"name":"ssidap",
|
||||
"state": "{{ssidAP}}",
|
||||
"pattern": ".{1,20}"
|
||||
},
|
||||
{
|
||||
"type": "password",
|
||||
"title": "Пароль",
|
||||
"name":"ssidApPass",
|
||||
"state": "{{passwordAP}}",
|
||||
"pattern": ".{8,20}"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "Сохранить",
|
||||
"action": "ssidap?ssidAP=[[ssidap]]&passwordAP=[[ssidApPass]]",
|
||||
"class": "btn btn-block btn-success"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "h2",
|
||||
"title": "Логин и пароль web interface"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "Логин",
|
||||
"name":"web-login",
|
||||
"state": "{{web_login}}",
|
||||
"pattern": ".{1,20}"
|
||||
},
|
||||
{
|
||||
"type": "password",
|
||||
"title": "Пароль",
|
||||
"name":"web-pass",
|
||||
"state": "{{web_pass}}",
|
||||
"pattern": ".{1,20}"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "Сохранить",
|
||||
"action": "web?web_login=[[web-login]]&web_pass=[[web-pass]]",
|
||||
"class": "btn btn-block btn-success"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "h2",
|
||||
"title": "Временная зона"
|
||||
},
|
||||
{
|
||||
"type": "input",
|
||||
"title": "Логин",
|
||||
"name":"time-zone",
|
||||
"state": "{{timezone}}",
|
||||
"pattern": ".{1,20}"
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"title": "Сохранить",
|
||||
"action": "timeZone?timezone=[[time-zone]]",
|
||||
"class": "btn btn-block btn-success"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Перезагрузить устройство",
|
||||
"action": "javascript:if(confirm(renameBlock(jsonResponse,'Перезагрузить?'))){send_request(this,'/restart?device=ok');}",
|
||||
"class": "btn btn-block btn-warning"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
{
|
||||
"configs": [
|
||||
|
||||
"/config.live.json",
|
||||
"/config.option.json",
|
||||
"/config.setup.json",
|
||||
"/lang/lang.ru.json",
|
||||
"socket {{ip}}:81/"
|
||||
|
||||
],
|
||||
"title": "Главная",
|
||||
"class":"col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6",
|
||||
"content": [
|
||||
{
|
||||
"type": "h5",
|
||||
"title": "{{SSDP}}",
|
||||
"class":"alert-warning"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Module tank level:",
|
||||
"style": "width:80%;float:left;"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "{{module_tank_level_s}}",
|
||||
"style": "width:20%;float:right;"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Module analog:",
|
||||
"style": "width:80%;float:left;"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "{{module_analog_s}}",
|
||||
"style": "width:20%;float:right;"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "Module ds18b20:",
|
||||
"style": "width:80%;float:left;"
|
||||
},
|
||||
{
|
||||
"type": "h4",
|
||||
"title": "{{module_ds18b20_s}}",
|
||||
"style": "width:20%;float:right;"
|
||||
},
|
||||
{
|
||||
"type": "link",
|
||||
"title": "Главная",
|
||||
"action": "/page.htm?index",
|
||||
"class": "btn btn-block btn-danger btn-sm",
|
||||
"style": "width:100%;float:right;"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"widget" : "anydata",
|
||||
"after" : "",
|
||||
"icon" : ""
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"widget" : "input",
|
||||
"color" : "blue",
|
||||
"type" : "number"
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"widget" : "input",
|
||||
"size" : "small",
|
||||
"color" : "orange",
|
||||
"type" : "text"
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"widget" : "input",
|
||||
"color" : "blue",
|
||||
"type" : "time"
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"widget" : "input",
|
||||
"size" : "small",
|
||||
"color" : "orange",
|
||||
"type" : "date"
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"widget" : "progress-line",
|
||||
"icon" : "sunny",
|
||||
"descrColor" : "",
|
||||
"color" : "",
|
||||
"max" : "100",
|
||||
"background" : "",
|
||||
"stroke" : "10",
|
||||
"disabled" : "",
|
||||
"before" : "",
|
||||
"after" : ""
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"widget" : "progress-round",
|
||||
"descrColor" : "",
|
||||
"max" : "100",
|
||||
"stroke" : "20",
|
||||
"color" : "#45ccce",
|
||||
"background": "#777",
|
||||
"before" : "",
|
||||
"semicircle" : "1",
|
||||
"after" : ""
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"widget" : "range",
|
||||
"descrColor": "red",
|
||||
"after" : "%",
|
||||
"k" : 0.0977,
|
||||
"min" : 0,
|
||||
"max" : 100,
|
||||
"debounce": 500
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"widget" : "select",
|
||||
"size" : "small",
|
||||
"fill" : "outline",
|
||||
"options" : "["Zero item", "First item", "Second item"]",
|
||||
"status" : 2
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"widget" : "toggle",
|
||||
"icon" : "",
|
||||
"iconOff" : ""
|
||||
}
|
||||
Binary file not shown.
BIN
data_full/build/bundle.css.gz
Normal file
BIN
data_full/build/bundle.css.gz
Normal file
Binary file not shown.
BIN
data_full/build/bundle.js.gz
Normal file
BIN
data_full/build/bundle.js.gz
Normal file
Binary file not shown.
BIN
data_full/favicon.ico
Normal file
BIN
data_full/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
16
data_full/index.html
Normal file
16
data_full/index.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
|
||||
<title>IoT Manager 4.6.2</title>
|
||||
|
||||
<link rel="icon" type="image/png" href="/favicon.ico" />
|
||||
<link rel="stylesheet" href="/build/bundle.css?4550" />
|
||||
|
||||
<script defer src="/build/bundle.js?4550"></script>
|
||||
</head>
|
||||
|
||||
<body></body>
|
||||
</html>
|
||||
0
data_lite/build/bundle.css.gz
Normal file
0
data_lite/build/bundle.css.gz
Normal file
0
data_lite/build/bundle.js.gz
Normal file
0
data_lite/build/bundle.js.gz
Normal file
0
data_lite/favicon.ico
Normal file
0
data_lite/favicon.ico
Normal file
47
data_lite/index.html
Normal file
47
data_lite/index.html
Normal file
@@ -0,0 +1,47 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
|
||||
<title>IoT Manager 4.4.3</title>
|
||||
<link rel="icon" type="image/png" href="/favicon.ico" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://iotmanager.org/esp01ota/build/bundle.css?450"
|
||||
/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
let script = document.createElement("script");
|
||||
script.src = "https://iotmanager.org/esp01ota/build/bundle.js?450";
|
||||
script.onload = execute;
|
||||
document.head.append(script);
|
||||
script.onerror = error;
|
||||
function error() {
|
||||
console.log("ошибка при загрузке ресурса");
|
||||
}
|
||||
function execute() {
|
||||
console.log("скрипт загружен");
|
||||
document.getElementById("my-form").style.display = "none";
|
||||
}
|
||||
</script>
|
||||
<div style="display: flex; align-items: center; justify-content: center">
|
||||
<form method="GET" action="http://192.168.4.1/set" id="my-form">
|
||||
<br /><br />
|
||||
<h1>Настройка WiFi</h1>
|
||||
<br />
|
||||
<div>
|
||||
<input name="routerssid" type="text" placeholder="WIFI" />
|
||||
</div>
|
||||
<br />
|
||||
<div>
|
||||
<input name="routerpass" placeholder="Password" />
|
||||
</div>
|
||||
<br /><br />
|
||||
<input type="submit" value="сохранить" />
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
BIN
data_svelte/build/bundle.css.gz
Normal file
BIN
data_svelte/build/bundle.css.gz
Normal file
Binary file not shown.
BIN
data_svelte/build/bundle.js.gz
Normal file
BIN
data_svelte/build/bundle.js.gz
Normal file
Binary file not shown.
1
data_svelte/config.json
Normal file
1
data_svelte/config.json
Normal file
@@ -0,0 +1 @@
|
||||
[]
|
||||
0
data_svelte/dev_conf.txt
Normal file
0
data_svelte/dev_conf.txt
Normal file
BIN
data_svelte/edit.htm.gz
Normal file
BIN
data_svelte/edit.htm.gz
Normal file
Binary file not shown.
BIN
data_svelte/favicon.ico
Normal file
BIN
data_svelte/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
393
data_svelte/flashProfile.json
Normal file
393
data_svelte/flashProfile.json
Normal file
@@ -0,0 +1,393 @@
|
||||
{
|
||||
"projectProp": {
|
||||
"platformio": {
|
||||
"default_envs": "esp8266_4mb"
|
||||
}
|
||||
},
|
||||
"modules": {
|
||||
"virtual_elments": [
|
||||
{
|
||||
"path": "src/modules/virtual/Benchmark",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/Cron",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/GoogleSheet",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/Loging",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/LogingDaily",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/Math",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/owmWeather",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/Ping",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/Timer",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/Variable",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/VButton",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/virtual/Weather",
|
||||
"active": false
|
||||
}
|
||||
],
|
||||
"sensors": [
|
||||
{
|
||||
"path": "src/modules/exec/Pcf8591",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/A02Distance",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Acs712",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ads1115",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/AhtXX",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/AnalogAdc",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/BH_1750",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/BL0937",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ble",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ble_part1",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ble_part2",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Bme280",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Bmp280",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Dht1122",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ds18b20",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/DS2401",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Emon",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/EnergyMon485",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/ExampleModule",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/ExternalMQTT",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/FreqMeter",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/GY21",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Hdc1080",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Hx710",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Hx711",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Impulse",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ina219",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ina226",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/IoTWiegand",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/ld2410",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Max6675",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Mhz19",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/MQgas",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ntc",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Pzem004t",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Pzem004t_v2",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/RCswitch",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/RTC",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/S8",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Scd40",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Sds011",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Sgp30",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Sht20",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Sht30",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Sonar",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/UART",
|
||||
"active": true
|
||||
}
|
||||
],
|
||||
"executive_devices": [
|
||||
{
|
||||
"path": "src/modules/exec/AnalogBtn",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/BrokerMQTT",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/ButtonIn",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/ButtonOut",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Buzzer",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Enconder",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/EspCam",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Ftp",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/HttpGet",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/IoTServo",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Mcp23008",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Mcp23017",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Mp3",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Multitouch",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/MySensors",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Pcf8574",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Pwm32",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Pwm8266",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/SDcard",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/SIM800",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/SmartBoiler",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/SysExt",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Telegram",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/TelegramLT",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Telegram_v2",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Thermostat",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/sensors/Ds2423",
|
||||
"active": false
|
||||
}
|
||||
],
|
||||
"screens": [
|
||||
{
|
||||
"path": "src/modules/display/DwinI",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/Lcd2004",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/Nextion",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/NextionUpload",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/Oled128",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/Oled64",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/Smi2_m",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/TM16XX",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/Ws2812b",
|
||||
"active": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
16
data_svelte/index.html
Normal file
16
data_svelte/index.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
|
||||
<title>IoT Manager 4.6.2</title>
|
||||
|
||||
<link rel="icon" type="image/png" href="/favicon.ico" />
|
||||
<link rel="stylesheet" href="/build/bundle.css?4550" />
|
||||
|
||||
<script defer src="/build/bundle.js?4550"></script>
|
||||
</head>
|
||||
|
||||
<body></body>
|
||||
</html>
|
||||
1094
data_svelte/items.json
Normal file
1094
data_svelte/items.json
Normal file
File diff suppressed because it is too large
Load Diff
1
data_svelte/layout.json
Normal file
1
data_svelte/layout.json
Normal file
@@ -0,0 +1 @@
|
||||
[]
|
||||
1
data_svelte/ota.json
Normal file
1
data_svelte/ota.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
0
data_svelte/scenario.txt
Normal file
0
data_svelte/scenario.txt
Normal file
28
data_svelte/settings.json
Normal file
28
data_svelte/settings.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "IoTmanagerVer4",
|
||||
"apssid": "IoTmanager",
|
||||
"appass": "",
|
||||
"routerssid": "iot",
|
||||
"routerpass": "hostel3333",
|
||||
"timezone": 2,
|
||||
"ntp": "pool.ntp.org",
|
||||
"weblogin": "admin",
|
||||
"webpass": "admin",
|
||||
"mqttServer": "",
|
||||
"mqttPort": 8021,
|
||||
"mqttPrefix": "/risenew",
|
||||
"mqttUser": "rise",
|
||||
"mqttPass": "3hostel3",
|
||||
"serverip": "http://iotmanager.org",
|
||||
"serverlocal": "http://192.168.1.2:5500",
|
||||
"log": 0,
|
||||
"mqttin": 0,
|
||||
"i2c": 0,
|
||||
"pinSCL": 0,
|
||||
"pinSDA": 0,
|
||||
"i2cFreq": 100000,
|
||||
"wg": "group1",
|
||||
"debugTraceMsgTlgrm": 1,
|
||||
"udps": 1,
|
||||
"settings_": ""
|
||||
}
|
||||
3
data_svelte/values.json
Normal file
3
data_svelte/values.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
|
||||
}
|
||||
369
data_svelte/widgets.json
Normal file
369
data_svelte/widgets.json
Normal file
@@ -0,0 +1,369 @@
|
||||
[
|
||||
{
|
||||
"name": "anydataRed",
|
||||
"label": "Сообщение1",
|
||||
"widget": "anydata",
|
||||
"icon": "body",
|
||||
"color": "red",
|
||||
"descrColor": "red"
|
||||
},
|
||||
{
|
||||
"name": "anydataDgr",
|
||||
"label": "Сообщение2",
|
||||
"widget": "anydata",
|
||||
"after": "",
|
||||
"color": "red",
|
||||
"icon": "walk"
|
||||
},
|
||||
{
|
||||
"name": "anydataDef",
|
||||
"label": "Текст",
|
||||
"widget": "anydata",
|
||||
"after": "",
|
||||
"icon": ""
|
||||
},
|
||||
{
|
||||
"name": "anydataVlt",
|
||||
"label": "Вольты",
|
||||
"widget": "anydata",
|
||||
"after": "V",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydataAmp",
|
||||
"label": "Амперы",
|
||||
"widget": "anydata",
|
||||
"after": "A",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydataWt",
|
||||
"label": "Ватты",
|
||||
"widget": "anydata",
|
||||
"after": "Wt",
|
||||
"icon": "speedometer",
|
||||
"color": [
|
||||
{
|
||||
"level": 0,
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"level": 200,
|
||||
"value": "#009933"
|
||||
},
|
||||
{
|
||||
"level": 2000,
|
||||
"value": "#FF9900"
|
||||
},
|
||||
{
|
||||
"level": 4000,
|
||||
"value": "red"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "anydataWth",
|
||||
"label": "Энергия",
|
||||
"widget": "anydata",
|
||||
"after": "kWh",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydataHtz",
|
||||
"label": "Герцы",
|
||||
"widget": "anydata",
|
||||
"after": "Hz",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydataTmp",
|
||||
"label": "Температура",
|
||||
"widget": "anydata",
|
||||
"after": "°С",
|
||||
"icon": "thermometer",
|
||||
"font": "OCR A Std",
|
||||
"color": [
|
||||
{
|
||||
"level": -20,
|
||||
"value": "#0000CC"
|
||||
},
|
||||
{
|
||||
"level": -10,
|
||||
"value": "#0000CC"
|
||||
},
|
||||
{
|
||||
"level": 0,
|
||||
"value": "#0000CC"
|
||||
},
|
||||
{
|
||||
"level": 12,
|
||||
"value": "#3366FF"
|
||||
},
|
||||
{
|
||||
"level": 16,
|
||||
"value": "#33CCFF"
|
||||
},
|
||||
{
|
||||
"level": 18,
|
||||
"value": "#009933"
|
||||
},
|
||||
{
|
||||
"level": 30,
|
||||
"value": "#FF9900"
|
||||
},
|
||||
{
|
||||
"level": 40,
|
||||
"value": "red"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "anydataMm",
|
||||
"label": "Давление",
|
||||
"widget": "anydata",
|
||||
"after": "mm",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydataHum",
|
||||
"label": "Влажность",
|
||||
"widget": "anydata",
|
||||
"after": "%",
|
||||
"icon": "water",
|
||||
"color": "#88AADF"
|
||||
},
|
||||
{
|
||||
"name": "anydataTm",
|
||||
"label": "Время",
|
||||
"widget": "anydata",
|
||||
"after": "",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "button",
|
||||
"label": "Кнопка",
|
||||
"widget": "btn",
|
||||
"size": "large",
|
||||
"color": "green",
|
||||
"send": "test"
|
||||
},
|
||||
{
|
||||
"name": "toggle",
|
||||
"label": "Переключатель",
|
||||
"widget": "toggle",
|
||||
"icon": "",
|
||||
"iconOff": ""
|
||||
},
|
||||
{
|
||||
"name": "chart1",
|
||||
"label": "График без точек",
|
||||
"widget": "chart",
|
||||
"dateFormat": "HH:mm",
|
||||
"maxCount": 86400,
|
||||
"pointRadius": 0
|
||||
},
|
||||
{
|
||||
"name": "chart2",
|
||||
"label": "График с точками",
|
||||
"widget": "chart",
|
||||
"maxCount": 86400,
|
||||
"dateFormat": "HH:mm"
|
||||
},
|
||||
{
|
||||
"name": "chart3",
|
||||
"label": "График Дневной",
|
||||
"widget": "chart",
|
||||
"dateFormat": "DD.MM.YYYY",
|
||||
"maxCount": 86400,
|
||||
"type": "bar"
|
||||
},
|
||||
{
|
||||
"name": "chart4",
|
||||
"label": "График Часовой",
|
||||
"widget": "chart",
|
||||
"dateFormat": "HH:mm",
|
||||
"maxCount": 3600,
|
||||
"type": "bar"
|
||||
},
|
||||
{
|
||||
"name": "chart5",
|
||||
"label": "График двойной",
|
||||
"widget": "chart",
|
||||
"series": [
|
||||
"Температура, С",
|
||||
"Влажность, %"
|
||||
],
|
||||
"dateFormat": "HH:mm",
|
||||
"maxCount": 86400,
|
||||
"pointRadius": 0
|
||||
},
|
||||
{
|
||||
"name": "chart6",
|
||||
"label": "График тройной",
|
||||
"widget": "chart",
|
||||
"series": [
|
||||
"Температура, С",
|
||||
"Влажность, %",
|
||||
"Давление, кПа"
|
||||
],
|
||||
"dateFormat": "HH:mm",
|
||||
"maxCount": 86400,
|
||||
"pointRadius": 0
|
||||
},
|
||||
{
|
||||
"name": "fillgauge",
|
||||
"label": "Бочка",
|
||||
"widget": "fillgauge",
|
||||
"circleColor": "#00FFFF",
|
||||
"textColor": "#FFFFFF",
|
||||
"waveTextColor": "#000000",
|
||||
"waveColor": "#00FFFF"
|
||||
},
|
||||
{
|
||||
"name": "inputDate",
|
||||
"label": "Ввод даты",
|
||||
"widget": "input",
|
||||
"size": "small",
|
||||
"color": "orange",
|
||||
"type": "date"
|
||||
},
|
||||
{
|
||||
"name": "inputDgt",
|
||||
"label": "Ввод числа",
|
||||
"widget": "input",
|
||||
"color": "blue",
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"name": "inputTxt",
|
||||
"label": "Ввод текста",
|
||||
"widget": "input",
|
||||
"size": "small",
|
||||
"color": "orange",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"name": "inputTm",
|
||||
"label": "Ввод времени",
|
||||
"widget": "input",
|
||||
"color": "blue",
|
||||
"type": "time"
|
||||
},
|
||||
{
|
||||
"name": "progressLine",
|
||||
"label": "Статус линия",
|
||||
"widget": "progress-line",
|
||||
"icon": "sunny",
|
||||
"max": "100",
|
||||
"stroke": "10"
|
||||
},
|
||||
{
|
||||
"name": "progressRound",
|
||||
"label": "Статус круг",
|
||||
"widget": "progress-round",
|
||||
"max": "100",
|
||||
"stroke": "20",
|
||||
"color": "#45ccce",
|
||||
"background": "#777",
|
||||
"semicircle": "1"
|
||||
},
|
||||
{
|
||||
"name": "range",
|
||||
"label": "Ползунок",
|
||||
"widget": "range",
|
||||
"descrColor": "red",
|
||||
"after": "%",
|
||||
"k": 0.0977,
|
||||
"min": 0,
|
||||
"max": 100,
|
||||
"debounce": 500
|
||||
},
|
||||
{
|
||||
"name": "rangeServo",
|
||||
"label": "Ползунок (Servo)",
|
||||
"widget": "range",
|
||||
"descrColor": "red",
|
||||
"after": "°",
|
||||
"k": 1,
|
||||
"min": 0,
|
||||
"max": 180,
|
||||
"debounce": 500
|
||||
},
|
||||
{
|
||||
"name": "select",
|
||||
"label": "Выпадающий",
|
||||
"widget": "select",
|
||||
"options": [
|
||||
"Выключен",
|
||||
"Включен"
|
||||
],
|
||||
"status": 0
|
||||
},
|
||||
{
|
||||
"name": "anydataPpm",
|
||||
"label": "PPM",
|
||||
"widget": "anydata",
|
||||
"after": "ppm",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydatamAmp",
|
||||
"label": "миллиАмперы",
|
||||
"widget": "anydata",
|
||||
"after": "mAmp",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydatamVlt",
|
||||
"label": "миллиВольты",
|
||||
"widget": "anydata",
|
||||
"after": "mVlt",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydatamWt",
|
||||
"label": "миллиВатты",
|
||||
"widget": "anydata",
|
||||
"after": "mWt",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydataCm",
|
||||
"label": "Сантиметры",
|
||||
"widget": "anydata",
|
||||
"after": "cm",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydataLiter",
|
||||
"label": "Литры",
|
||||
"widget": "anydata",
|
||||
"after": "ltr",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydataSpeed",
|
||||
"label": "мерты в секунду",
|
||||
"widget": "anydata",
|
||||
"after": "m/s",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydataСorner",
|
||||
"label": "угол градусов",
|
||||
"widget": "anydata",
|
||||
"after": "°",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "anydataBar",
|
||||
"label": "давление Bar",
|
||||
"widget": "anydata",
|
||||
"after": "Kg/cm²",
|
||||
"icon": "speedometer"
|
||||
},
|
||||
{
|
||||
"name": "nil",
|
||||
"label": "Без виджета"
|
||||
}
|
||||
]
|
||||
197
dependencies/WiFiClientSecure/WiFiClientSecure.cpp
vendored
197
dependencies/WiFiClientSecure/WiFiClientSecure.cpp
vendored
@@ -1,197 +0,0 @@
|
||||
/*
|
||||
WiFiClientSecure.cpp - Client Secure class for ESP32
|
||||
Copyright (c) 2016 Hristo Gochkov All right reserved.
|
||||
Additions Copyright (C) 2017 Evandro Luis Copercini.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "WiFiClientSecure.h"
|
||||
#include <lwip/sockets.h>
|
||||
#include <lwip/netdb.h>
|
||||
#include <errno.h>
|
||||
|
||||
#undef connect
|
||||
#undef write
|
||||
#undef read
|
||||
|
||||
|
||||
WiFiClientSecure::WiFiClientSecure()
|
||||
{
|
||||
_connected = false;
|
||||
|
||||
sslclient = new sslclient_context;
|
||||
ssl_init(sslclient);
|
||||
sslclient->socket = -1;
|
||||
|
||||
_CA_cert = NULL;
|
||||
_cert = NULL;
|
||||
_private_key = NULL;
|
||||
next = NULL;
|
||||
}
|
||||
|
||||
|
||||
WiFiClientSecure::WiFiClientSecure(int sock)
|
||||
{
|
||||
_connected = false;
|
||||
|
||||
sslclient = new sslclient_context;
|
||||
ssl_init(sslclient);
|
||||
sslclient->socket = sock;
|
||||
|
||||
if (sock >= 0) {
|
||||
_connected = true;
|
||||
}
|
||||
|
||||
_CA_cert = NULL;
|
||||
_cert = NULL;
|
||||
_private_key = NULL;
|
||||
next = NULL;
|
||||
}
|
||||
|
||||
WiFiClientSecure::~WiFiClientSecure()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
WiFiClientSecure &WiFiClientSecure::operator=(const WiFiClientSecure &other)
|
||||
{
|
||||
stop();
|
||||
sslclient->socket = other.sslclient->socket;
|
||||
_connected = other._connected;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void WiFiClientSecure::stop()
|
||||
{
|
||||
if (sslclient->socket >= 0) {
|
||||
close(sslclient->socket);
|
||||
sslclient->socket = -1;
|
||||
_connected = false;
|
||||
}
|
||||
stop_ssl_socket(sslclient, _CA_cert, _cert, _private_key);
|
||||
}
|
||||
|
||||
int WiFiClientSecure::connect(IPAddress ip, uint16_t port)
|
||||
{
|
||||
return connect(ip, port, _CA_cert, _cert, _private_key);
|
||||
}
|
||||
|
||||
int WiFiClientSecure::connect(const char *host, uint16_t port)
|
||||
{
|
||||
return connect(host, port, _CA_cert, _cert, _private_key);
|
||||
}
|
||||
|
||||
int WiFiClientSecure::connect(IPAddress ip, uint16_t port, const char *_CA_cert, const char *_cert, const char *_private_key)
|
||||
{
|
||||
int ret = start_ssl_client(sslclient, ip, port, _CA_cert, _cert, _private_key);
|
||||
if (ret < 0) {
|
||||
log_e("lwip_connect_r: %d", errno);
|
||||
stop();
|
||||
return 0;
|
||||
}
|
||||
_connected = true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int WiFiClientSecure::connect(const char *host, uint16_t port, const char *_CA_cert, const char *_cert, const char *_private_key)
|
||||
{
|
||||
struct hostent *server;
|
||||
server = gethostbyname(host);
|
||||
if (server == NULL) {
|
||||
return 0;
|
||||
}
|
||||
IPAddress srv((const uint8_t *)(server->h_addr));
|
||||
return connect(srv, port, _CA_cert, _cert, _private_key);
|
||||
}
|
||||
|
||||
|
||||
size_t WiFiClientSecure::write(uint8_t data)
|
||||
{
|
||||
return write(&data, 1);
|
||||
}
|
||||
|
||||
int WiFiClientSecure::read()
|
||||
{
|
||||
uint8_t data = 0;
|
||||
int res = read(&data, 1);
|
||||
if (res < 0) {
|
||||
return res;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
size_t WiFiClientSecure::write(const uint8_t *buf, size_t size)
|
||||
{
|
||||
if (!_connected) {
|
||||
return 0;
|
||||
}
|
||||
int res = send_ssl_data(sslclient, buf, size);
|
||||
if (res < 0) {
|
||||
|
||||
stop();
|
||||
res = 0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int WiFiClientSecure::read(uint8_t *buf, size_t size)
|
||||
{
|
||||
if (!available()) {
|
||||
return -1;
|
||||
}
|
||||
int res = get_ssl_receive(sslclient, buf, size);
|
||||
if (res < 0) {
|
||||
|
||||
stop();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int WiFiClientSecure::available()
|
||||
{
|
||||
if (!_connected) {
|
||||
return 0;
|
||||
}
|
||||
int res = data_to_read(sslclient);
|
||||
if (res < 0 ) {
|
||||
stop();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
uint8_t WiFiClientSecure::connected()
|
||||
{
|
||||
uint8_t dummy = 0;
|
||||
read(&dummy, 0);
|
||||
|
||||
return _connected;
|
||||
}
|
||||
|
||||
void WiFiClientSecure::setCACert (const char *rootCA)
|
||||
{
|
||||
_CA_cert = rootCA;
|
||||
}
|
||||
|
||||
void WiFiClientSecure::setCertificate (const char *client_ca)
|
||||
{
|
||||
_cert = client_ca;
|
||||
}
|
||||
|
||||
void WiFiClientSecure::setPrivateKey (const char *private_key)
|
||||
{
|
||||
_private_key = private_key;
|
||||
}
|
||||
|
||||
92
dependencies/WiFiClientSecure/WiFiClientSecure.h
vendored
92
dependencies/WiFiClientSecure/WiFiClientSecure.h
vendored
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
WiFiClientSecure.h - Base class that provides Client SSL to ESP32
|
||||
Copyright (c) 2011 Adrian McEwen. All right reserved.
|
||||
Additions Copyright (C) 2017 Evandro Luis Copercini.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef WiFiClientSecure_h
|
||||
#define WiFiClientSecure_h
|
||||
#include "Arduino.h"
|
||||
#include "IPAddress.h"
|
||||
#include <WiFi.h>
|
||||
#include "ssl_client.h"
|
||||
|
||||
class WiFiClientSecure : public Client
|
||||
{
|
||||
protected:
|
||||
bool _connected;
|
||||
sslclient_context *sslclient;
|
||||
|
||||
const char *_CA_cert;
|
||||
const char *_cert;
|
||||
const char *_private_key;
|
||||
|
||||
public:
|
||||
WiFiClientSecure *next;
|
||||
WiFiClientSecure();
|
||||
WiFiClientSecure(int socket);
|
||||
~WiFiClientSecure();
|
||||
int connect(IPAddress ip, uint16_t port);
|
||||
int connect(const char *host, uint16_t port);
|
||||
int connect(IPAddress ip, uint16_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key);
|
||||
int connect(const char *host, uint16_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key);
|
||||
size_t write(uint8_t data);
|
||||
size_t write(const uint8_t *buf, size_t size);
|
||||
int available();
|
||||
int read();
|
||||
int read(uint8_t *buf, size_t size);
|
||||
int peek()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
void flush() {}
|
||||
void stop();
|
||||
uint8_t connected();
|
||||
|
||||
void setCACert(const char *rootCA);
|
||||
void setCertificate(const char *client_ca);
|
||||
void setPrivateKey (const char *private_key);
|
||||
|
||||
operator bool()
|
||||
{
|
||||
return connected();
|
||||
}
|
||||
WiFiClientSecure &operator=(const WiFiClientSecure &other);
|
||||
bool operator==(const bool value)
|
||||
{
|
||||
return bool() == value;
|
||||
}
|
||||
bool operator!=(const bool value)
|
||||
{
|
||||
return bool() != value;
|
||||
}
|
||||
bool operator==(const WiFiClientSecure &);
|
||||
bool operator!=(const WiFiClientSecure &rhs)
|
||||
{
|
||||
return !this->operator==(rhs);
|
||||
};
|
||||
|
||||
int socket()
|
||||
{
|
||||
return sslclient->socket = -1;
|
||||
}
|
||||
|
||||
//friend class WiFiServer;
|
||||
using Print::write;
|
||||
};
|
||||
|
||||
#endif /* _WIFICLIENT_H_ */
|
||||
261
dependencies/WiFiClientSecure/ssl_client.cpp
vendored
261
dependencies/WiFiClientSecure/ssl_client.cpp
vendored
@@ -1,261 +0,0 @@
|
||||
/* Provide SSL/TLS functions to ESP32 with Arduino IDE
|
||||
*
|
||||
* Adapted from the ssl_client1 example of mbedtls.
|
||||
*
|
||||
* Original Copyright (C) 2006-2015, ARM Limited, All Rights Reserved, Apache 2.0 License.
|
||||
* Additions Copyright (C) 2017 Evandro Luis Copercini, Apache 2.0 License.
|
||||
*/
|
||||
|
||||
#include "Arduino.h"
|
||||
#include <esp32-hal-log.h>
|
||||
#include <lwip/sockets.h>
|
||||
#include <lwip/err.h>
|
||||
#include <lwip/sockets.h>
|
||||
#include <lwip/sys.h>
|
||||
#include <lwip/netdb.h>
|
||||
#include "ssl_client.h"
|
||||
|
||||
const char *pers = "esp32-tls";
|
||||
|
||||
static int handle_error(int err)
|
||||
{
|
||||
#ifdef MBEDTLS_ERROR_C
|
||||
char error_buf[100];
|
||||
mbedtls_strerror(err, error_buf, 100);
|
||||
log_e("%s", error_buf);
|
||||
#endif
|
||||
log_e("MbedTLS message code: %d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
void ssl_init(sslclient_context *ssl_client)
|
||||
{
|
||||
mbedtls_ssl_init(&ssl_client->ssl_ctx);
|
||||
mbedtls_ssl_config_init(&ssl_client->ssl_conf);
|
||||
mbedtls_ctr_drbg_init(&ssl_client->drbg_ctx);
|
||||
}
|
||||
|
||||
|
||||
int start_ssl_client(sslclient_context *ssl_client, uint32_t ipAddress, uint32_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key)
|
||||
{
|
||||
char buf[512];
|
||||
int ret, flags, timeout;
|
||||
int enable = 1;
|
||||
log_i("Free heap before TLS %u", xPortGetFreeHeapSize());
|
||||
|
||||
log_i("Starting socket");
|
||||
ssl_client->socket = -1;
|
||||
|
||||
ssl_client->socket = lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (ssl_client->socket < 0) {
|
||||
log_e("ERROR opening socket");
|
||||
return ssl_client->socket;
|
||||
}
|
||||
|
||||
struct sockaddr_in serv_addr;
|
||||
memset(&serv_addr, 0, sizeof(serv_addr));
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_addr.s_addr = ipAddress;
|
||||
serv_addr.sin_port = htons(port);
|
||||
|
||||
if (lwip_connect(ssl_client->socket, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == 0) {
|
||||
timeout = 30000;
|
||||
lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
|
||||
lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
|
||||
lwip_setsockopt(ssl_client->socket, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable));
|
||||
lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable));
|
||||
} else {
|
||||
log_e("Connect to Server failed!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fcntl( ssl_client->socket, F_SETFL, fcntl( ssl_client->socket, F_GETFL, 0 ) | O_NONBLOCK );
|
||||
|
||||
log_i("Seeding the random number generator");
|
||||
mbedtls_entropy_init(&ssl_client->entropy_ctx);
|
||||
|
||||
ret = mbedtls_ctr_drbg_seed(&ssl_client->drbg_ctx, mbedtls_entropy_func,
|
||||
&ssl_client->entropy_ctx, (const unsigned char *) pers, strlen(pers));
|
||||
if (ret < 0) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
|
||||
log_i("Setting up the SSL/TLS structure...");
|
||||
|
||||
if ((ret = mbedtls_ssl_config_defaults(&ssl_client->ssl_conf,
|
||||
MBEDTLS_SSL_IS_CLIENT,
|
||||
MBEDTLS_SSL_TRANSPORT_STREAM,
|
||||
MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
|
||||
/* MBEDTLS_SSL_VERIFY_REQUIRED if a CA certificate is defined on Arduino IDE and
|
||||
MBEDTLS_SSL_VERIFY_NONE if not.
|
||||
*/
|
||||
if (rootCABuff != NULL) {
|
||||
log_i("Loading CA cert");
|
||||
mbedtls_x509_crt_init(&ssl_client->ca_cert);
|
||||
mbedtls_ssl_conf_authmode(&ssl_client->ssl_conf, MBEDTLS_SSL_VERIFY_REQUIRED);
|
||||
ret = mbedtls_x509_crt_parse(&ssl_client->ca_cert, (const unsigned char *)rootCABuff, strlen(rootCABuff) + 1);
|
||||
mbedtls_ssl_conf_ca_chain(&ssl_client->ssl_conf, &ssl_client->ca_cert, NULL);
|
||||
//mbedtls_ssl_conf_verify(&ssl_client->ssl_ctx, my_verify, NULL );
|
||||
if (ret < 0) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
} else {
|
||||
mbedtls_ssl_conf_authmode(&ssl_client->ssl_conf, MBEDTLS_SSL_VERIFY_NONE);
|
||||
log_i("WARNING: Use certificates for a more secure communication!");
|
||||
}
|
||||
|
||||
if (cli_cert != NULL && cli_key != NULL) {
|
||||
mbedtls_x509_crt_init(&ssl_client->client_cert);
|
||||
mbedtls_pk_init(&ssl_client->client_key);
|
||||
|
||||
log_i("Loading CRT cert");
|
||||
|
||||
ret = mbedtls_x509_crt_parse(&ssl_client->client_cert, (const unsigned char *)cli_cert, strlen(cli_cert) + 1);
|
||||
if (ret < 0) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
|
||||
log_i("Loading private key");
|
||||
ret = mbedtls_pk_parse_key(&ssl_client->client_key, (const unsigned char *)cli_key, strlen(cli_key) + 1, NULL, 0);
|
||||
|
||||
if (ret != 0) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_own_cert(&ssl_client->ssl_conf, &ssl_client->client_cert, &ssl_client->client_key);
|
||||
}
|
||||
|
||||
/*
|
||||
// TODO: implement match CN verification
|
||||
|
||||
log_i("Setting hostname for TLS session...");
|
||||
|
||||
// Hostname set here should match CN in server certificate
|
||||
if((ret = mbedtls_ssl_set_hostname(&ssl_client->ssl_ctx, host)) != 0)
|
||||
{
|
||||
return handle_error(ret);
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
mbedtls_ssl_conf_rng(&ssl_client->ssl_conf, mbedtls_ctr_drbg_random, &ssl_client->drbg_ctx);
|
||||
|
||||
if ((ret = mbedtls_ssl_setup(&ssl_client->ssl_ctx, &ssl_client->ssl_conf)) != 0) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
|
||||
mbedtls_ssl_set_bio(&ssl_client->ssl_ctx, &ssl_client->socket, mbedtls_net_send, mbedtls_net_recv, NULL );
|
||||
|
||||
log_i("Performing the SSL/TLS handshake...");
|
||||
|
||||
while ((ret = mbedtls_ssl_handshake(&ssl_client->ssl_ctx)) != 0) {
|
||||
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret != -76) { //workaround for bug: https://github.com/espressif/esp-idf/issues/434
|
||||
return handle_error(ret);
|
||||
}
|
||||
delay(10);
|
||||
vPortYield();
|
||||
}
|
||||
|
||||
|
||||
if (cli_cert != NULL && cli_key != NULL) {
|
||||
log_i("Protocol is %s Ciphersuite is %s", mbedtls_ssl_get_version(&ssl_client->ssl_ctx), mbedtls_ssl_get_ciphersuite(&ssl_client->ssl_ctx));
|
||||
if ((ret = mbedtls_ssl_get_record_expansion(&ssl_client->ssl_ctx)) >= 0) {
|
||||
log_i("Record expansion is %d", ret);
|
||||
} else {
|
||||
log_i("Record expansion is unknown (compression)");
|
||||
}
|
||||
}
|
||||
|
||||
log_i("Verifying peer X.509 certificate...");
|
||||
|
||||
if ((flags = mbedtls_ssl_get_verify_result(&ssl_client->ssl_ctx)) != 0) {
|
||||
log_e("Failed to verify peer certificate!");
|
||||
bzero(buf, sizeof(buf));
|
||||
mbedtls_x509_crt_verify_info(buf, sizeof(buf), " ! ", flags);
|
||||
log_e("verification info: %s", buf);
|
||||
stop_ssl_socket(ssl_client, rootCABuff, cli_cert, cli_key); //It's not safe continue.
|
||||
return handle_error(ret);
|
||||
} else {
|
||||
log_i("Certificate verified.");
|
||||
}
|
||||
|
||||
log_i("Free heap after TLS %u", xPortGetFreeHeapSize());
|
||||
|
||||
return ssl_client->socket;
|
||||
}
|
||||
|
||||
|
||||
void stop_ssl_socket(sslclient_context *ssl_client, const char *rootCABuff, const char *cli_cert, const char *cli_key)
|
||||
{
|
||||
log_i("Cleaning SSL connection.");
|
||||
|
||||
if (ssl_client->socket >= 0) {
|
||||
close(ssl_client->socket);
|
||||
ssl_client->socket = -1;
|
||||
}
|
||||
|
||||
mbedtls_ssl_free(&ssl_client->ssl_ctx);
|
||||
mbedtls_ssl_config_free(&ssl_client->ssl_conf);
|
||||
mbedtls_ctr_drbg_free(&ssl_client->drbg_ctx);
|
||||
mbedtls_entropy_free(&ssl_client->entropy_ctx);
|
||||
|
||||
if (rootCABuff != NULL) {
|
||||
mbedtls_x509_crt_free(&ssl_client->ca_cert);
|
||||
}
|
||||
|
||||
if (cli_cert != NULL) {
|
||||
mbedtls_x509_crt_free(&ssl_client->client_cert);
|
||||
}
|
||||
|
||||
if (cli_key != NULL) {
|
||||
mbedtls_pk_free(&ssl_client->client_key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int data_to_read(sslclient_context *ssl_client)
|
||||
{
|
||||
int ret, res;
|
||||
ret = mbedtls_ssl_read(&ssl_client->ssl_ctx, NULL, 0);
|
||||
//log_e("RET: %i",ret); //for low level debug
|
||||
res = mbedtls_ssl_get_bytes_avail(&ssl_client->ssl_ctx);
|
||||
//log_e("RES: %i",res);
|
||||
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret < 0 && ret != -76) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int send_ssl_data(sslclient_context *ssl_client, const uint8_t *data, uint16_t len)
|
||||
{
|
||||
//log_i("Writing HTTP request..."); //for low level debug
|
||||
int ret = -1;
|
||||
|
||||
while ((ret = mbedtls_ssl_write(&ssl_client->ssl_ctx, data, len)) <= 0) {
|
||||
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret != -76) {
|
||||
return handle_error(ret);
|
||||
}
|
||||
}
|
||||
|
||||
len = ret;
|
||||
//log_i("%d bytes written", len); //for low level debug
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int get_ssl_receive(sslclient_context *ssl_client, uint8_t *data, int length)
|
||||
{
|
||||
//log_i( "Reading HTTP response..."); //for low level debug
|
||||
int ret = -1;
|
||||
|
||||
ret = mbedtls_ssl_read(&ssl_client->ssl_ctx, data, length);
|
||||
|
||||
//log_i( "%d bytes readed", ret); //for low level debug
|
||||
return ret;
|
||||
}
|
||||
37
dependencies/WiFiClientSecure/ssl_client.h
vendored
37
dependencies/WiFiClientSecure/ssl_client.h
vendored
@@ -1,37 +0,0 @@
|
||||
/* Provide SSL/TLS functions to ESP32 with Arduino IDE
|
||||
* by Evandro Copercini - 2017 - Apache 2.0 License
|
||||
*/
|
||||
|
||||
#ifndef ARD_SSL_H
|
||||
#define ARD_SSL_H
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/net.h"
|
||||
#include "mbedtls/debug.h"
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "mbedtls/error.h"
|
||||
|
||||
typedef struct sslclient_context {
|
||||
int socket;
|
||||
mbedtls_net_context net_ctx;
|
||||
mbedtls_ssl_context ssl_ctx;
|
||||
mbedtls_ssl_config ssl_conf;
|
||||
|
||||
mbedtls_ctr_drbg_context drbg_ctx;
|
||||
mbedtls_entropy_context entropy_ctx;
|
||||
|
||||
mbedtls_x509_crt ca_cert;
|
||||
mbedtls_x509_crt client_cert;
|
||||
mbedtls_pk_context client_key;
|
||||
} sslclient_context;
|
||||
|
||||
|
||||
void ssl_init(sslclient_context *ssl_client);
|
||||
int start_ssl_client(sslclient_context *ssl_client, uint32_t ipAddress, uint32_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key);
|
||||
void stop_ssl_socket(sslclient_context *ssl_client, const char *rootCABuff, const char *cli_cert, const char *cli_key);
|
||||
int data_to_read(sslclient_context *ssl_client);
|
||||
int send_ssl_data(sslclient_context *ssl_client, const uint8_t *data, uint16_t len);
|
||||
int get_ssl_receive(sslclient_context *ssl_client, uint8_t *data, int length);
|
||||
|
||||
#endif
|
||||
@@ -1,81 +0,0 @@
|
||||
#include "set.h"
|
||||
|
||||
void setup() {
|
||||
|
||||
Serial.begin(115200);
|
||||
Serial.setDebugOutput(true);
|
||||
Serial.println("--------------started----------------");
|
||||
//--------------------------------------------------------------
|
||||
SPIFFS.begin();
|
||||
configSetup = readFile("config.json", 4096);
|
||||
Serial.println(configSetup);
|
||||
jsonWrite(configJson, "SSDP", jsonRead(configSetup, "SSDP"));
|
||||
jsonWrite(configJson, "lang", jsonRead(configSetup, "lang"));
|
||||
Serial.println("SPIFFS_init");
|
||||
|
||||
#ifdef ESP32
|
||||
uint32_t chipID_u = ESP.getEfuseMac();
|
||||
chipID = String(chipID_u);
|
||||
jsonWrite(configSetup, "chipID", chipID);
|
||||
#endif
|
||||
|
||||
#ifdef ESP8266
|
||||
chipID = String( ESP.getChipId() ) + "-" + String( ESP.getFlashChipId());
|
||||
jsonWrite(configSetup, "chipID", chipID);
|
||||
Serial.setDebugOutput(0);
|
||||
#endif
|
||||
|
||||
prex = prefix + "/" + chipID;
|
||||
Serial.println(chipID);
|
||||
//--------------------------------------------------------------
|
||||
CMD_init();
|
||||
Serial.println("[V] CMD_init");
|
||||
//--------------------------------------------------------------
|
||||
All_init();
|
||||
Serial.println("[V] All_init");
|
||||
//--------------------------------------------------------------
|
||||
WIFI_init();
|
||||
Serial.println("[V] WIFI_init");
|
||||
//--------------------------------------------------------------
|
||||
Web_server_init();
|
||||
Serial.println("[V] Web_server_init");
|
||||
//--------------------------------------------------------------
|
||||
Time_Init();
|
||||
Serial.println("[V] Time_Init");
|
||||
//--------------------------------------------------------------
|
||||
MQTT_init();
|
||||
Serial.println("[V] MQTT_init");
|
||||
//--------------------------------------------------------------
|
||||
Push_init();
|
||||
Serial.println("[V] Push_init");
|
||||
|
||||
|
||||
getMemoryLoad("[i] After loading");
|
||||
|
||||
|
||||
ts.add(TEST, 5000, [&](void*) {
|
||||
|
||||
up_time();
|
||||
|
||||
}, nullptr, true);
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
#ifdef OTA_enable
|
||||
ArduinoOTA.handle();
|
||||
#endif
|
||||
|
||||
#ifdef WS_enable
|
||||
ws.cleanupClients();
|
||||
#endif
|
||||
|
||||
handleMQTT();
|
||||
|
||||
handleCMD_loop();
|
||||
handleButton();
|
||||
handleScenario();
|
||||
|
||||
ts.update();
|
||||
}
|
||||
12
include/AsyncWebServer.h
Normal file
12
include/AsyncWebServer.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include "Global.h"
|
||||
#ifdef ASYNC_WEB_SERVER
|
||||
void asyncWebServerInit();
|
||||
#endif
|
||||
|
||||
#ifdef ASYNC_WEB_SOCKETS
|
||||
extern AsyncWebSocket ws;
|
||||
extern AsyncEventSource events;
|
||||
void asyncWebSocketsInit();
|
||||
void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len);
|
||||
#endif
|
||||
7
include/Buffers.h
Normal file
7
include/Buffers.h
Normal file
@@ -0,0 +1,7 @@
|
||||
//#pragma once
|
||||
//#include "Global.h"
|
||||
//#include "MqttClient.h"
|
||||
|
||||
//void eventGen2(String eventName, String eventValue);
|
||||
//extern void spaceCmdExecute(String &cmdStr);
|
||||
//extern String getValueJson(String &key);
|
||||
80
include/BuildTime.h
Normal file
80
include/BuildTime.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
Парсинг и получение даты и времени компиляции из __DATE__ и __TIME__
|
||||
Документация:
|
||||
GitHub: https://github.com/GyverLibs/buildTime
|
||||
Константы времени компиляции:
|
||||
BUILD_YEAR - год
|
||||
BUILD_MONTH - месяц
|
||||
BUILD_DAY - день
|
||||
BUILD_HOUR - час
|
||||
BUILD_MIN - минута
|
||||
BUILD_SEC - секунда
|
||||
|
||||
Исходник http://qaru.site/questions/186859/how-to-use-date-and-time-predefined-macros-in-as-two-integers-then-stringify
|
||||
AlexGyver, alex@alexgyver.ru
|
||||
https://alexgyver.ru/
|
||||
MIT License
|
||||
|
||||
Версии:
|
||||
v1.0 - релиз
|
||||
*/
|
||||
|
||||
#ifndef buildTime_h
|
||||
#define buildTime_h
|
||||
// Example of __DATE__ string: "Jul 27 2012"
|
||||
// 01234567890
|
||||
|
||||
#define BUILD_YEAR_CH0 (__DATE__[7] - '0')
|
||||
#define BUILD_YEAR_CH1 (__DATE__[8] - '0')
|
||||
#define BUILD_YEAR_CH2 (__DATE__[9] - '0')
|
||||
#define BUILD_YEAR_CH3 (__DATE__[10] - '0')
|
||||
#define BUILD_YEAR (BUILD_YEAR_CH0 * 1000 + BUILD_YEAR_CH1 * 100 + BUILD_YEAR_CH2 * 10 + BUILD_YEAR_CH3)
|
||||
|
||||
#define BUILD_MONTH_IS_JAN (__DATE__[0] == 'J' && __DATE__[1] == 'a' && __DATE__[2] == 'n')
|
||||
#define BUILD_MONTH_IS_FEB (__DATE__[0] == 'F')
|
||||
#define BUILD_MONTH_IS_MAR (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'r')
|
||||
#define BUILD_MONTH_IS_APR (__DATE__[0] == 'A' && __DATE__[1] == 'p')
|
||||
#define BUILD_MONTH_IS_MAY (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'y')
|
||||
#define BUILD_MONTH_IS_JUN (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'n')
|
||||
#define BUILD_MONTH_IS_JUL (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'l')
|
||||
#define BUILD_MONTH_IS_AUG (__DATE__[0] == 'A' && __DATE__[1] == 'u')
|
||||
#define BUILD_MONTH_IS_SEP (__DATE__[0] == 'S')
|
||||
#define BUILD_MONTH_IS_OCT (__DATE__[0] == 'O')
|
||||
#define BUILD_MONTH_IS_NOV (__DATE__[0] == 'N')
|
||||
#define BUILD_MONTH_IS_DEC (__DATE__[0] == 'D')
|
||||
|
||||
#define BUILD_MONTH \
|
||||
( \
|
||||
(BUILD_MONTH_IS_JAN) ? 1 : (BUILD_MONTH_IS_FEB) ? 2 \
|
||||
: (BUILD_MONTH_IS_MAR) ? 3 \
|
||||
: (BUILD_MONTH_IS_APR) ? 4 \
|
||||
: (BUILD_MONTH_IS_MAY) ? 5 \
|
||||
: (BUILD_MONTH_IS_JUN) ? 6 \
|
||||
: (BUILD_MONTH_IS_JUL) ? 7 \
|
||||
: (BUILD_MONTH_IS_AUG) ? 8 \
|
||||
: (BUILD_MONTH_IS_SEP) ? 9 \
|
||||
: (BUILD_MONTH_IS_OCT) ? 10 \
|
||||
: (BUILD_MONTH_IS_NOV) ? 11 \
|
||||
: (BUILD_MONTH_IS_DEC) ? 12 \
|
||||
: /* error default */ '?')
|
||||
|
||||
#define BUILD_DAY_CH0 (((__DATE__[4] >= '0') ? (__DATE__[4]) : '0') - '0')
|
||||
#define BUILD_DAY_CH1 (__DATE__[5] - '0')
|
||||
#define BUILD_DAY (BUILD_DAY_CH0 * 10 + BUILD_DAY_CH1)
|
||||
|
||||
// Example of __TIME__ string: "21:06:19"
|
||||
// 01234567
|
||||
|
||||
#define BUILD_HOUR_CH0 (__TIME__[0] - '0')
|
||||
#define BUILD_HOUR_CH1 (__TIME__[1] - '0')
|
||||
#define BUILD_HOUR (BUILD_HOUR_CH0 * 10 + BUILD_HOUR_CH1)
|
||||
|
||||
#define BUILD_MIN_CH0 (__TIME__[3] - '0')
|
||||
#define BUILD_MIN_CH1 (__TIME__[4] - '0')
|
||||
#define BUILD_MIN (BUILD_MIN_CH0 * 10 + BUILD_MIN_CH1)
|
||||
|
||||
#define BUILD_SEC_CH0 (__TIME__[6] - '0')
|
||||
#define BUILD_SEC_CH1 (__TIME__[7] - '0')
|
||||
#define BUILD_SEC (BUILD_SEC_CH0 * 10 + BUILD_SEC_CH1)
|
||||
|
||||
#endif
|
||||
153
include/Const.h
Normal file
153
include/Const.h
Normal file
@@ -0,0 +1,153 @@
|
||||
#pragma once
|
||||
#include "BuildTime.h"
|
||||
|
||||
// Версия прошивки
|
||||
|
||||
#define FIRMWARE_VERSION 462
|
||||
|
||||
#ifdef esp8266_1mb_ota
|
||||
#define FIRMWARE_NAME "esp8266_1mb_ota"
|
||||
#endif
|
||||
|
||||
#ifdef esp8266_1mb
|
||||
#define FIRMWARE_NAME "esp8266_1mb"
|
||||
#endif
|
||||
|
||||
#ifdef esp8266_2mb
|
||||
#define FIRMWARE_NAME "esp8266_2mb"
|
||||
#endif
|
||||
|
||||
#ifdef esp8266_2mb_ota
|
||||
#define FIRMWARE_NAME "esp8266_2mb_ota"
|
||||
#endif
|
||||
|
||||
#ifdef esp8266_4mb
|
||||
#define FIRMWARE_NAME "esp8266_4mb"
|
||||
#endif
|
||||
|
||||
#ifdef esp8266_16mb
|
||||
#define FIRMWARE_NAME "esp8266_16mb"
|
||||
#endif
|
||||
|
||||
#ifdef esp32_4mb
|
||||
#define FIRMWARE_NAME "esp32_4mb"
|
||||
#endif
|
||||
|
||||
#ifdef esp32_4mb3f
|
||||
#define FIRMWARE_NAME "esp32_4mb3f"
|
||||
#endif
|
||||
|
||||
#ifdef esp32cam_4mb
|
||||
#define FIRMWARE_NAME "esp32cam_4mb"
|
||||
#endif
|
||||
|
||||
#ifdef esp32_16mb
|
||||
#define FIRMWARE_NAME "esp32_16mb"
|
||||
#endif
|
||||
|
||||
#ifdef esp32s2_4mb
|
||||
#define FIRMWARE_NAME "esp32s2_4mb"
|
||||
#endif
|
||||
|
||||
#ifdef esp32c3m_4mb
|
||||
#define FIRMWARE_NAME "esp32c3m_4mb"
|
||||
#endif
|
||||
|
||||
#ifdef esp32s3_16mb
|
||||
#define FIRMWARE_NAME "esp32s3_16mb"
|
||||
#endif
|
||||
|
||||
#ifdef bk7231n
|
||||
#define FIRMWARE_NAME "bk7231n"
|
||||
#endif
|
||||
|
||||
#ifdef esp32c6_4mb
|
||||
#define FIRMWARE_NAME "esp32c6_4mb"
|
||||
#endif
|
||||
|
||||
#ifdef esp32c6_8mb
|
||||
#define FIRMWARE_NAME "esp32c6_8mb"
|
||||
#endif
|
||||
|
||||
#ifdef esp32_wifirep
|
||||
#define FIRMWARE_NAME "esp32_wifirep"
|
||||
#endif
|
||||
// Размер буфера json
|
||||
#define JSON_BUFFER_SIZE 4096 // держим 2 кб не меняем
|
||||
|
||||
/*
|
||||
WEB_SOCKETS_FRAME_SIZE создан для того что бы не загружать оперативку.
|
||||
Эта технология передаёт в сокеты большие файлы по частям.
|
||||
Чем меньше этот фрейм тем теоретически лучше.
|
||||
Но и сильно малый он тоже быть не должен.
|
||||
Я опытным путём установил что размер 1024 является оптимальным. Можно так же поставить 2048
|
||||
*/
|
||||
#define WEB_SOCKETS_FRAME_SIZE 1024
|
||||
|
||||
// #define LOOP_DEBUG
|
||||
|
||||
// выбор сервера
|
||||
// #define ASYNC_WEB_SERVER
|
||||
// #define ASYNC_WEB_SOCKETS
|
||||
#define STANDARD_WEB_SERVER
|
||||
#define STANDARD_WEB_SOCKETS
|
||||
|
||||
//#ifndef LIBRETINY
|
||||
#define UDP_ENABLED
|
||||
//#endif
|
||||
// #define REST_FILE_OPERATIONS
|
||||
|
||||
#define MQTT_RECONNECT_INTERVAL 20000
|
||||
|
||||
#define TELEMETRY_UPDATE_INTERVAL_MIN 60
|
||||
|
||||
#define USE_LITTLEFS true
|
||||
|
||||
#define START_DATETIME 1661990400 // 01.09.2022 00:00:00 константа для сокращения unix time
|
||||
|
||||
#define MIN_DATETIME 1575158400
|
||||
#define LEAP_YEAR(Y) (((1970 + Y) > 0) && !((1970 + Y) % 4) && (((1970 + Y) % 100) || !((1970 + Y) % 400)))
|
||||
|
||||
#ifdef LIBRETINY
|
||||
//#define WIFI_ASYNC
|
||||
#endif
|
||||
|
||||
#if defined(ESP32) && !defined(esp32_wifirep)
|
||||
#define WIFI_ASYNC
|
||||
#endif
|
||||
|
||||
// задачи таскера
|
||||
enum TimerTask_t {
|
||||
WIFI_SCAN,
|
||||
WIFI_MQTT_CONNECTION_CHECK,
|
||||
#ifdef WIFI_ASYNC
|
||||
WIFI_CONN,
|
||||
#endif
|
||||
TIME,
|
||||
// TIME_SYNC, // не используется
|
||||
// UPTIME, // не используется
|
||||
UDPt, // UDPP
|
||||
TIMES, // периодические секундные проверки
|
||||
PTASK,
|
||||
ST,
|
||||
PiWS,
|
||||
END
|
||||
};
|
||||
|
||||
// задачи которые надо протащить через loop // не используется
|
||||
// enum NotAsyncActions {
|
||||
// do_ZERO,
|
||||
// do_MQTTPARAMSCHANGED,
|
||||
// do_LAST,
|
||||
// };
|
||||
|
||||
// состояния обновления
|
||||
enum UpdateStates { UPDATE_COMPLETED, UPDATE_FAILED, PATH_ERROR };
|
||||
|
||||
enum distination {
|
||||
TO_MQTT,
|
||||
TO_WS,
|
||||
TO_MQTT_WS
|
||||
};
|
||||
|
||||
// #define WS_BROADCAST -1 // не используется
|
||||
34
include/DebugTrace.h
Normal file
34
include/DebugTrace.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
// В папке toolchchain с которым собирались
|
||||
// (Для esp32 например %%USERPROFILE%/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin)
|
||||
// из командной строки Windows (cmd) запустить файл c параметрами:
|
||||
// xtensa-esp32-elf-addr2line.exe -pfiaC -e Путь_к_файлу/firmware.elf Стэк_адресов_из_сообщения
|
||||
// %%USERPROFILE%/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin xtensa-esp32-elf-addr2line.exe -pfiaC -e .pio/build/esp32_4mb3f/firmware.elf Стэк_адресов
|
||||
#include "Global.h"
|
||||
#if defined(ESP32) && !defined(esp32c3m_4mb) && !defined(esp32c6_4mb) && !defined(esp32c6_8mb)
|
||||
#define RESTART_DEBUG_INFO
|
||||
#endif
|
||||
#if defined(RESTART_DEBUG_INFO)
|
||||
#define CONFIG_RESTART_DEBUG_STACK_DEPTH 15
|
||||
typedef struct {
|
||||
size_t heap_total;
|
||||
size_t heap_free;
|
||||
size_t heap_free_min;
|
||||
time_t heap_min_time;
|
||||
uint32_t backtrace[CONFIG_RESTART_DEBUG_STACK_DEPTH];
|
||||
} re_restart_debug_t;
|
||||
__NOINIT_ATTR static int8_t bootloop_panic_count;
|
||||
|
||||
void IRAM_ATTR debugUpdate();
|
||||
#endif // RESTART_DEBUG_INFO
|
||||
|
||||
|
||||
|
||||
extern "C" void __real_esp_panic_handler(void*);
|
||||
void printDebugTrace();
|
||||
void sendDebugTraceAndFreeMemory(bool);
|
||||
|
||||
void startWatchDog();
|
||||
//extern "C" bool verifyRollbackLater();
|
||||
void verifyFirmware();
|
||||
20
include/DeviceList.h
Normal file
20
include/DeviceList.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
#include "Global.h"
|
||||
|
||||
#if defined (ESP8266) || defined(LIBRETINY)
|
||||
// эта библиотека встроена в ядро
|
||||
#include "ESPAsyncUDP.h"
|
||||
#elif defined(ESP32)
|
||||
#include "AsyncUDP.h"
|
||||
#endif
|
||||
#ifndef LIBRETINY
|
||||
extern AsyncUDP asyncUdp;
|
||||
#endif
|
||||
|
||||
extern const String getThisDevice();
|
||||
extern void addThisDeviceToList();
|
||||
extern void udpListningInit();
|
||||
extern void udpBroadcastInit();
|
||||
extern String uint8tToString(uint8_t* data, size_t len);
|
||||
extern void udpPacketParse(String& data);
|
||||
extern void jsonMergeArrays(String& existJson, String& incJson);
|
||||
9
include/ESPConfiguration.h
Normal file
9
include/ESPConfiguration.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
|
||||
extern std::list<IoTItem*> IoTItems; // вектор ссылок базового класса IoTItem - список всех запущенных сенсоров
|
||||
|
||||
extern void configure(String path);
|
||||
void clearConfigure();
|
||||
// extern IoTItem* myIoTItem; // экономим память, используется в одном месте
|
||||
64
include/EspFileSystem.h
Normal file
64
include/EspFileSystem.h
Normal file
@@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
#include "Global.h"
|
||||
#ifdef ESP32
|
||||
#include <rom/spi_flash.h>
|
||||
#if USE_LITTLEFS
|
||||
#include <LittleFS.h>
|
||||
#define FileFS LittleFS
|
||||
#define FS_NAME "LittleFS_32"
|
||||
#define CONFIG_LITTLEFS_SPIFFS_COMPAT 1
|
||||
#else
|
||||
#include <SPIFFS.h>
|
||||
extern FS* filesystem;
|
||||
#define FileFS SPIFFS
|
||||
#define FS_NAME "SPIFFS_32"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(LIBRETINY)
|
||||
#include <FS.h>
|
||||
|
||||
#include "LittleFS.h"
|
||||
|
||||
#define FileFS LittleFS
|
||||
#define FS_NAME "LittleFS_LT"
|
||||
#define FILE_READ "r"
|
||||
#define FILE_WRITE "w"
|
||||
#define FILE_APPEND "a"
|
||||
#endif
|
||||
|
||||
#ifdef ESP8266
|
||||
#if USE_LITTLEFS
|
||||
#include "LittleFS.h"
|
||||
extern FS LittleFS;
|
||||
using littlefs_impl::LittleFSConfig;
|
||||
extern FS* filesystem;
|
||||
#define FileFS LittleFS
|
||||
#define FS_NAME "LittleFS_8266"
|
||||
#define FILE_READ "r"
|
||||
#define FILE_WRITE "w"
|
||||
#define FILE_APPEND "a"
|
||||
#else
|
||||
extern FS* filesystem;
|
||||
#define FileFS SPIFFS
|
||||
#define FS_NAME "SPIFFS_8266"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern bool fileSystemInit();
|
||||
extern void globalVarsSync();
|
||||
|
||||
// extern String getParamsJson();
|
||||
|
||||
extern void syncSettingsFlashJson();
|
||||
void resetSettingsFlashByPanic();
|
||||
extern void syncValuesFlashJson();
|
||||
|
||||
extern const String getChipId();
|
||||
extern void setChipId();
|
||||
extern const String getUniqueId(const char* name);
|
||||
extern uint32_t ESP_getChipId(void);
|
||||
extern uint32_t ESP_getFlashChipId(void);
|
||||
extern const String getMacAddress();
|
||||
extern const String getWebVersion();
|
||||
extern uint32_t getFlashChipIdNew();
|
||||
8
include/EventsAndOrders.h
Normal file
8
include/EventsAndOrders.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include "Global.h"
|
||||
|
||||
extern void generateOrder(const String& id, const String& value);
|
||||
extern void handleOrder();
|
||||
|
||||
extern void generateEvent(const String& id, const String& value);
|
||||
extern void handleEvent();
|
||||
177
include/Global.h
Normal file
177
include/Global.h
Normal file
@@ -0,0 +1,177 @@
|
||||
#pragma once
|
||||
// константы
|
||||
#include "Const.h"
|
||||
|
||||
// внешние глобальные директории
|
||||
#include <Arduino.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <TickerScheduler.h>
|
||||
#include <PubSubClient.h>
|
||||
#include <list>
|
||||
|
||||
#ifdef LIBRETINY
|
||||
#include <Update.h>
|
||||
#include <vector>
|
||||
#include <typedef.h>
|
||||
#ifdef STANDARD_WEB_SERVER
|
||||
#include <WebServer.h>
|
||||
#endif
|
||||
#include <HTTPClient.h>
|
||||
#endif
|
||||
|
||||
#ifdef ESP32
|
||||
#include "WiFi.h"
|
||||
#include <HTTPClient.h>
|
||||
#include <HTTPUpdate.h>
|
||||
#endif
|
||||
|
||||
#ifdef ESP8266
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266httpUpdate.h>
|
||||
#endif
|
||||
|
||||
#ifdef ASYNC_WEB_SERVER
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include "AsyncWebServer.h"
|
||||
#endif
|
||||
|
||||
#ifdef STANDARD_WEB_SERVER
|
||||
#ifdef ESP8266
|
||||
#include <ESP8266WebServer.h>
|
||||
#include <ESP8266HTTPUpdateServer.h>
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
#include <WebServer.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef STANDARD_WEB_SOCKETS
|
||||
#include <WebSocketsServer.h>
|
||||
#ifdef ESP8266
|
||||
#include <Hash.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <FS.h>
|
||||
|
||||
// внутренние глобальные директории проекта
|
||||
#include "utils/FileUtils.h"
|
||||
#include "utils/JsonUtils.h"
|
||||
#include "utils/SerialPrint.h"
|
||||
#include "utils/StringUtils.h"
|
||||
#include "PeriodicTasks.h"
|
||||
#include "classes/IoTGpio.h"
|
||||
#include "classes/IoTDiscovery.h"
|
||||
/*********************************************************************************************************************
|
||||
*****************************************глобальные объекты классов***************************************************
|
||||
**********************************************************************************************************************/
|
||||
extern IoTGpio IoTgpio;
|
||||
#ifdef mod_RtcDriver
|
||||
extern IoTItem* rtcItem;
|
||||
#endif
|
||||
//extern IoTItem* camItem;
|
||||
extern IoTItem* tlgrmItem;
|
||||
extern IoTBench* benchLoadItem;
|
||||
extern IoTBench* benchTaskItem;
|
||||
extern IoTDiscovery* HADiscovery;
|
||||
extern IoTDiscovery* HOMEdDiscovery;
|
||||
|
||||
|
||||
extern TickerScheduler ts;
|
||||
extern WiFiClient espClient;
|
||||
extern PubSubClient mqtt;
|
||||
|
||||
#ifdef ASYNC_WEB_SERVER
|
||||
extern AsyncWebServer server;
|
||||
#endif
|
||||
|
||||
#ifdef STANDARD_WEB_SERVER
|
||||
#ifdef ESP8266
|
||||
extern ESP8266WebServer HTTP;
|
||||
extern ESP8266HTTPUpdateServer httpUpdater;
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
extern WebServer HTTP;
|
||||
#endif
|
||||
#ifdef LIBRETINY
|
||||
extern WebServer HTTP;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef STANDARD_WEB_SOCKETS
|
||||
extern WebSocketsServer standWebSocket;
|
||||
#endif
|
||||
|
||||
/*********************************************************************************************************************
|
||||
***********************************************глобальные переменные**************************************************
|
||||
**********************************************************************************************************************/
|
||||
extern String settingsFlashJson;
|
||||
extern String valuesFlashJson;
|
||||
extern String errorsHeapJson;
|
||||
extern bool needSaveValues;
|
||||
|
||||
// buf
|
||||
extern String orderBuf;
|
||||
extern String eventBuf;
|
||||
extern String mysensorBuf;
|
||||
|
||||
// wifi
|
||||
extern String ssidListHeapJson;
|
||||
|
||||
extern String devListHeapJson;
|
||||
extern String thisDeviceJson;
|
||||
|
||||
// Mqtt
|
||||
extern String mqttServer;
|
||||
extern int mqttPort;
|
||||
extern String mqttPrefix;
|
||||
extern String mqttUser;
|
||||
extern String mqttPass;
|
||||
extern String nameId;
|
||||
|
||||
extern unsigned long mqttUptime;
|
||||
extern unsigned long flashWriteNumber;
|
||||
|
||||
extern unsigned long wifiUptime;
|
||||
|
||||
extern bool udpReceivingData;
|
||||
|
||||
extern String mqttRootDevice;
|
||||
extern String chipId;
|
||||
extern String prex;
|
||||
extern String all_widgets;
|
||||
extern String scenario;
|
||||
|
||||
// Time
|
||||
struct Time_t {
|
||||
uint8_t second;
|
||||
uint8_t minute;
|
||||
uint8_t hour;
|
||||
uint8_t day_of_week;
|
||||
uint8_t day_of_month;
|
||||
uint8_t month;
|
||||
uint16_t day_of_year;
|
||||
uint16_t year;
|
||||
unsigned long days;
|
||||
unsigned long valid;
|
||||
};
|
||||
|
||||
extern unsigned long unixTime;
|
||||
extern unsigned long unixTimeShort;
|
||||
extern String prevDate;
|
||||
extern bool firstTimeInit;
|
||||
|
||||
extern bool isTimeSynch;
|
||||
extern Time_t _time_local;
|
||||
extern Time_t _time_utc;
|
||||
extern bool _time_isTrust;
|
||||
|
||||
#define WEBSOCKETS_CLIENT_MAX 5
|
||||
extern int8_t ws_clients[WEBSOCKETS_CLIENT_MAX];
|
||||
// extern unsigned long loopPeriod;
|
||||
|
||||
// extern DynamicJsonDocument settingsFlashJsonDoc;
|
||||
// extern DynamicJsonDocument paramsFlashJsonDoc;
|
||||
// extern DynamicJsonDocument paramsHeapJsonDoc;
|
||||
|
||||
void scanI2C();
|
||||
16
include/Main.h
Normal file
16
include/Main.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
//
|
||||
#include "EspFileSystem.h"
|
||||
#include "Global.h"
|
||||
#include "utils/WiFiUtils.h"
|
||||
#include "AsyncWebServer.h"
|
||||
#include "StandWebServer.h"
|
||||
#include "classes/NotAsync.h"
|
||||
#include "ESPConfiguration.h"
|
||||
#include "MqttClient.h"
|
||||
#include "WsServer.h"
|
||||
#include "DeviceList.h"
|
||||
#include "PeriodicTasks.h"
|
||||
#include "classes/IoTScenario.h"
|
||||
#include "EventsAndOrders.h"
|
||||
#include "NTP.h"
|
||||
38
include/MqttClient.h
Normal file
38
include/MqttClient.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
#include "Const.h"
|
||||
#include "classes/NotAsync.h"
|
||||
#include "Global.h"
|
||||
#include "utils/WiFiUtils.h"
|
||||
#include "EventsAndOrders.h"
|
||||
|
||||
void mqttInit();
|
||||
void selectBroker();
|
||||
void getMqttData();
|
||||
void getMqttData2();
|
||||
bool isSecondBrokerSet();
|
||||
boolean mqttConnect();
|
||||
void mqttReconnect();
|
||||
void mqttLoop();
|
||||
void mqttSubscribe();
|
||||
bool mqttIsConnect();
|
||||
|
||||
boolean publish(const String& topic, const String& data);
|
||||
boolean publishData(const String& topic, const String& data);
|
||||
boolean publishChartMqtt(const String& topic, const String& data);
|
||||
boolean publishJsonMqtt(const String& topic, const String& json);
|
||||
boolean publishStatusMqtt(const String& topic, const String& data);
|
||||
boolean publishEvent(const String& topic, const String& data);
|
||||
void mqttSubscribeExternal(String topic, bool usePrefix = false);
|
||||
|
||||
bool publishChartFileToMqtt(String path, String id, int maxCount);
|
||||
|
||||
void publishWidgets();
|
||||
|
||||
void mqttCallback(char* topic, uint8_t* payload, size_t length);
|
||||
//void handleMqttStatus(bool send);
|
||||
void handleMqttStatus(bool send, int state = -1);
|
||||
|
||||
const String getStateStr(int e);
|
||||
|
||||
void mqttUptimeCalc();
|
||||
void wifiUptimeCalc();
|
||||
20
include/NTP.h
Normal file
20
include/NTP.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
#include "Arduino.h"
|
||||
#include "Global.h"
|
||||
|
||||
static const uint8_t days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||
|
||||
extern void breakEpochToTime(unsigned long epoch, Time_t& tm);
|
||||
extern void ntpInit();
|
||||
extern time_t getSystemTime();
|
||||
extern void synchTime();
|
||||
extern bool onDayChange();
|
||||
extern const String getTimeLocal_hhmm();
|
||||
extern const String getTimeLocal_hhmmss();
|
||||
extern const String getDateTimeDotFormated();
|
||||
extern const String getTodayDateDotFormated();
|
||||
extern unsigned long strDateToUnix(String date);
|
||||
extern const String getDateTimeDotFormatedFromUnix(unsigned long unixTime);
|
||||
extern const String getTimeDotFormatedFromUnix(unsigned long unixTime);
|
||||
extern unsigned long gmtTimeToLocal(unsigned long gmtTimestamp);
|
||||
extern const String getDateDotFormatedFromUnix(unsigned long unixTime);
|
||||
14
include/PeriodicTasks.h
Normal file
14
include/PeriodicTasks.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include "Global.h"
|
||||
#include "WsServer.h"
|
||||
#include "utils/TimeUtils.h"
|
||||
|
||||
#ifdef ESP32
|
||||
#include <rom/rtc.h>
|
||||
#endif
|
||||
|
||||
extern void periodicTasksInit();
|
||||
extern void printGlobalVarSize();
|
||||
|
||||
extern String ESP_getResetReason(void);
|
||||
extern String ESP32GetResetReason(uint32_t cpu_no);
|
||||
24
include/StandWebServer.h
Normal file
24
include/StandWebServer.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include "Global.h"
|
||||
|
||||
#ifdef STANDARD_WEB_SERVER
|
||||
extern void standWebServerInit();
|
||||
extern bool handleFileRead(String path);
|
||||
//extern String getContentType(String filename);
|
||||
//#ifdef REST_FILE_OPERATIONS
|
||||
extern void handleFileUpload();
|
||||
extern void handleFileDelete();
|
||||
extern void handleFileCreate();
|
||||
extern void handleLocalOTA();
|
||||
extern void handleUpdateOTA();
|
||||
extern void handleCors();
|
||||
extern void handleLocalOTA_Handler();
|
||||
extern void handleFileList();
|
||||
//void printDirectory(File dir, String& out);
|
||||
extern void handleStatus();
|
||||
extern void handleGetEdit();
|
||||
extern void replyOK ();
|
||||
extern void handleNotFound ();
|
||||
|
||||
//#endif
|
||||
#endif
|
||||
28
include/UpgradeFirm.h
Normal file
28
include/UpgradeFirm.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
#include "Global.h"
|
||||
// #include "Upgrade.h"
|
||||
#ifdef ESP8266
|
||||
// #include "ESP8266.h"
|
||||
#elif ESP32
|
||||
#include <HTTPUpdate.h>
|
||||
#endif
|
||||
|
||||
struct updateFirm {
|
||||
String settingsFlashJson;
|
||||
String configJson;
|
||||
String layoutJson;
|
||||
String scenarioTxt;
|
||||
String chartsData;
|
||||
};
|
||||
|
||||
extern void upgradeInit();
|
||||
extern void getLastVersion();
|
||||
extern void upgrade_firmware(int type, String path);
|
||||
extern bool upgradeFS(String path);
|
||||
extern bool upgradeBuild(String path);
|
||||
extern void restartEsp();
|
||||
|
||||
extern const String getBinPath();
|
||||
extern void putUserDataToRam();
|
||||
extern void saveUserDataToFlash();
|
||||
extern void saveUpdeteStatus(String key, int val);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user