mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 15:59:52 +03:00
Compare commits
432 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b65866217a | ||
|
|
611e3b1243 | ||
|
|
84d3d42306 | ||
|
|
61e2739ef7 | ||
|
|
a3391afd27 | ||
|
|
ce9b7d1468 | ||
|
|
1b86314a14 | ||
|
|
b2a0519f83 | ||
|
|
3dec4bda8c | ||
|
|
5de529cbb2 | ||
|
|
4fd1d8e08a | ||
|
|
0847ccc602 | ||
|
|
969803569e | ||
|
|
6532abd870 | ||
|
|
07dabb4ceb | ||
|
|
1c6a683015 | ||
|
|
bb38458ac4 | ||
|
|
53de2ca25b | ||
|
|
5a9122f8be | ||
|
|
dc84f91044 | ||
|
|
4be6626470 | ||
|
|
7e4494aae1 | ||
|
|
50e54e6a1c | ||
|
|
30b111b986 | ||
|
|
a63f2e6131 | ||
|
|
51d487b938 | ||
|
|
96180c837d | ||
|
|
da20cf1ed2 | ||
|
|
bffad5e3c8 | ||
|
|
74287ebb99 | ||
|
|
8b40c92f7e | ||
|
|
5f6033cac1 | ||
|
|
24582407d4 | ||
|
|
22c9e3ee1f | ||
|
|
cb2c898b7e | ||
|
|
c0bf623266 | ||
|
|
18f22d3951 | ||
|
|
e2dad610b0 | ||
|
|
5ed3cbee2e | ||
|
|
27712badb6 | ||
|
|
72c032adff | ||
|
|
7197df9812 | ||
|
|
898e2e5f21 | ||
|
|
cde3b7541f | ||
|
|
822f55497e | ||
|
|
7c16870294 | ||
|
|
e368f422f4 | ||
|
|
9d9ac4ed9e | ||
|
|
d7576ebda1 | ||
|
|
fd810ff01c | ||
|
|
999a05f7ff | ||
|
|
a19f2f19c5 | ||
|
|
f54ccd40e6 | ||
|
|
5893487d4a | ||
|
|
3c8e20d4e4 | ||
|
|
bf68a5523b | ||
|
|
9c5c27152c | ||
|
|
c229371c68 | ||
|
|
805cef68a2 | ||
|
|
09addcb975 | ||
|
|
409d382ff9 | ||
|
|
27bfc14438 | ||
|
|
6c20a5f4f9 | ||
|
|
ffd61a9f67 | ||
|
|
4f2da0347c | ||
|
|
3c13c144d5 | ||
|
|
d4eaedef3d | ||
|
|
a8f1892d48 | ||
|
|
e347ac5742 | ||
|
|
5f2a9b093d | ||
|
|
e821e8d082 | ||
|
|
05f56be2d8 | ||
|
|
88f78f6541 | ||
|
|
234533f241 | ||
|
|
b1f72b0e3e | ||
|
|
a3022f6f20 | ||
|
|
95f7583511 | ||
|
|
578ba386e6 | ||
|
|
df7be9d11e | ||
|
|
72a59917fb | ||
|
|
9406c76e55 | ||
|
|
ea550b1656 | ||
|
|
d20741c0f0 | ||
|
|
91b7fd59d1 | ||
|
|
95e81ad824 | ||
|
|
316832fc4f | ||
|
|
23b6d81c47 | ||
|
|
8284520733 | ||
|
|
57f53818e1 | ||
|
|
7bca3fb2ed | ||
|
|
ae4a1358af | ||
|
|
95e3a11a11 | ||
|
|
f1a859c650 | ||
|
|
8d9fd95e85 | ||
|
|
452921d198 | ||
|
|
3e0f6f55fb | ||
|
|
0e480bbd94 | ||
|
|
7a079d866f | ||
|
|
af2710125e | ||
|
|
fb3de2e36d | ||
|
|
bf40222105 | ||
|
|
e1419edb15 | ||
|
|
131b936a69 | ||
|
|
5850a82d80 | ||
|
|
b76b6be3d1 | ||
|
|
b8f69eeaa8 | ||
|
|
d78fb53845 | ||
|
|
54889fec41 | ||
|
|
2c5c4d6e04 | ||
|
|
e6a44c9c82 | ||
|
|
7cba52d77e | ||
|
|
a79a67e4b2 | ||
|
|
01bace4048 | ||
|
|
d5f8419157 | ||
|
|
40a7026d4c | ||
|
|
47cb296cc4 | ||
|
|
be27033d41 | ||
|
|
3001a2d66f | ||
|
|
becaff0711 | ||
|
|
aaab9f409f | ||
|
|
068bb5cbeb | ||
|
|
337c07d7bc | ||
|
|
c387f65b4a | ||
|
|
df13081f97 | ||
|
|
50f6d0ab26 | ||
|
|
fb7bafdb87 | ||
|
|
b3472c3919 | ||
|
|
4f47712d52 | ||
|
|
547ccb96c9 | ||
|
|
7f3ff434ea | ||
|
|
aad4b0ade3 | ||
|
|
d587f44ec9 | ||
|
|
f30d3cf637 | ||
|
|
8fed47f39b | ||
|
|
48cedbd0fb | ||
|
|
752530a381 | ||
|
|
45fc6daa4a | ||
|
|
e17ce9c3b5 | ||
|
|
2657b9d1a5 | ||
|
|
b77a56ade2 | ||
|
|
4d5f588748 | ||
|
|
6582ba6317 | ||
|
|
b3453d9d02 | ||
|
|
e4b73140c8 | ||
|
|
235f789228 | ||
|
|
c029cf79f7 | ||
|
|
0b796a85a8 | ||
|
|
d8191f79a4 | ||
|
|
6a259f7cca | ||
|
|
22a2b92022 | ||
|
|
25616ae3b4 | ||
|
|
372aee30cd | ||
|
|
0c5023323a | ||
|
|
2d1126b9e4 | ||
|
|
3ecf92fa41 | ||
|
|
50befd8991 | ||
|
|
676268d7af | ||
|
|
f2457a7050 | ||
|
|
ded90dc4ce | ||
|
|
cddadcfae2 | ||
|
|
3113d392ac | ||
|
|
6433d5f744 | ||
|
|
f42c265714 | ||
|
|
d6711ac850 | ||
|
|
9d7c2de1d5 | ||
|
|
b1e1c44e77 | ||
|
|
85f54dd210 | ||
|
|
eea32ad134 | ||
|
|
4f24035082 | ||
|
|
0b0b1d9ca4 | ||
|
|
98828ed848 | ||
|
|
7b0f7cd32c | ||
|
|
67cb778039 | ||
|
|
9f49afae0a | ||
|
|
49c7c7aa2d | ||
|
|
42d89d1d10 | ||
|
|
24fae0d03e | ||
|
|
2c337f1d03 | ||
|
|
fcc521d5ed | ||
|
|
91005876eb | ||
|
|
da5b4aa79d | ||
|
|
ced440392b | ||
|
|
33d7ba1fda | ||
|
|
a6095fc305 | ||
|
|
84cc964a7a | ||
|
|
9e856b28a9 | ||
|
|
9378fdf2b6 | ||
|
|
6a134dda1f | ||
|
|
4f927ee571 | ||
|
|
b111869422 | ||
|
|
89a249eae4 | ||
|
|
7942d52843 | ||
|
|
b6310302d2 | ||
|
|
87774e73e1 | ||
|
|
548b5ff4a1 | ||
|
|
80fedf3fa3 | ||
|
|
8523cdffa3 | ||
|
|
29f2335935 | ||
|
|
eba6324d18 | ||
|
|
c3874d7c95 | ||
|
|
3086342d2b | ||
|
|
f836209249 | ||
|
|
d4b06cf0c0 | ||
|
|
54199affc1 | ||
|
|
4d88c6a90b | ||
|
|
906813b8f5 | ||
|
|
30d1e7ecb4 | ||
|
|
8fab4e29bf | ||
|
|
252554ea87 | ||
|
|
ba3d49172c | ||
|
|
6ef8ff757a | ||
|
|
fcc2c0b3de | ||
|
|
16e390f849 | ||
|
|
a31cf53863 | ||
|
|
09d8a6360b | ||
|
|
b1f59d4727 | ||
|
|
d8add7edcb | ||
|
|
1a71921fd6 | ||
|
|
6d12fff4fe | ||
|
|
769301c804 | ||
|
|
6a828e9ca5 | ||
|
|
2516d2d6de | ||
|
|
e92a3ad025 | ||
|
|
5686094151 | ||
|
|
915749dd69 | ||
|
|
258bc2b544 | ||
|
|
a9748f5b46 | ||
|
|
56f1c7946e | ||
|
|
88a427578f | ||
|
|
0ebd9e1fe1 | ||
|
|
bea0b4ba01 | ||
|
|
f8bee9b5c5 | ||
|
|
500e089b97 | ||
|
|
2adef52abf | ||
|
|
e01bfe1bdf | ||
|
|
418b1b3d68 | ||
|
|
401929d992 | ||
|
|
ee34dd72f7 | ||
|
|
b214d7a662 | ||
|
|
079a40cd32 | ||
|
|
adebea1561 | ||
|
|
28bf7c3225 | ||
|
|
78b2efd148 | ||
|
|
11590061a3 | ||
|
|
09847ee33c | ||
|
|
db34785be0 | ||
|
|
538a9cf642 | ||
|
|
d0346e436a | ||
|
|
442202d978 | ||
|
|
3b2a89d9f4 | ||
|
|
0bf366ac75 | ||
|
|
c62e73d21e | ||
|
|
2889899bfd | ||
|
|
f18ac2e48b | ||
|
|
1d259d14c8 | ||
|
|
b8c07e31cf | ||
|
|
3f27ed7b18 | ||
|
|
d7678b340f | ||
|
|
b697356465 | ||
|
|
1b9a2f21d2 | ||
|
|
e26451fcc0 | ||
|
|
17db542775 | ||
|
|
dd865a2db5 | ||
|
|
834c7cb87f | ||
|
|
a9a015cb5b | ||
|
|
94a71998a7 | ||
|
|
aa212924bc | ||
|
|
edef2f1bf6 | ||
|
|
912f53762e | ||
|
|
02c04c8f41 | ||
|
|
3ad90a6e34 | ||
|
|
0f83870db0 | ||
|
|
7529f3a73e | ||
|
|
77d559ac8c | ||
|
|
1311cad913 | ||
|
|
4d1ba9bede | ||
|
|
6b07651ed3 | ||
|
|
50ddfc0437 | ||
|
|
c0ac485772 | ||
|
|
8d4ae6971d | ||
|
|
88d0dfee2d | ||
|
|
551a479c6b | ||
|
|
3f85541c9a | ||
|
|
74cdb610d8 | ||
|
|
165dd3b418 | ||
|
|
7421f3e345 | ||
|
|
d00559bcd5 | ||
|
|
9774051fab | ||
|
|
c50692bae0 | ||
|
|
6348283001 | ||
|
|
1cbd34d94e | ||
|
|
f9d768a7a7 | ||
|
|
6c1bfccfaf | ||
|
|
2ca0a0c634 | ||
|
|
30ce3f1dc3 | ||
|
|
15541c52ce | ||
|
|
20c3e8c7bd | ||
|
|
59797fb89c | ||
|
|
849cc85398 | ||
|
|
dd318a1c8e | ||
|
|
2edf2a4231 | ||
|
|
d58ee1e693 | ||
|
|
088cb7fe40 | ||
|
|
38498a5587 | ||
|
|
6e3b30b03c | ||
|
|
4e9cf72816 | ||
|
|
7eb1f061b7 | ||
|
|
5e4f5916f2 | ||
|
|
1450737d94 | ||
|
|
bfd20e559e | ||
|
|
98a7932dee | ||
|
|
19e26d0d64 | ||
|
|
1715218864 | ||
|
|
e503c6cd79 | ||
|
|
9515e3d00b | ||
|
|
53e25ae213 | ||
|
|
4863ecc329 | ||
|
|
b5892f5b5e | ||
|
|
d16502c872 | ||
|
|
e29fb9ba8a | ||
|
|
2ee0411582 | ||
|
|
f210466cb1 | ||
|
|
6af28b1c29 | ||
|
|
049be2484e | ||
|
|
8f438e8045 | ||
|
|
a8382dd6ce | ||
|
|
c55385d6d8 | ||
|
|
87e6691433 | ||
|
|
aa9ba65f70 | ||
|
|
39fef48915 | ||
|
|
362fead7e8 | ||
|
|
e809ed3743 | ||
|
|
dc8c322b42 | ||
|
|
c5688ab632 | ||
|
|
d5d75eee63 | ||
|
|
6ec16733c3 | ||
|
|
ce2b2658ad | ||
|
|
3a866b1aea | ||
|
|
1cf938e16a | ||
|
|
1df427366f | ||
|
|
f97cdcb4d6 | ||
|
|
15c682cd1e | ||
|
|
008983be26 | ||
|
|
2f01000665 | ||
|
|
616955daef | ||
|
|
e22b191a48 | ||
|
|
8930c52ada | ||
|
|
6d94335079 | ||
|
|
f2e0b193af | ||
|
|
5b55902cd9 | ||
|
|
694f647a2c | ||
|
|
fc1cb00523 | ||
|
|
2fda59d7db | ||
|
|
a95837404a | ||
|
|
c6db2a1adf | ||
|
|
f6d22732a0 | ||
|
|
220a69938f | ||
|
|
d438866864 | ||
|
|
2e0ed9ce9f | ||
|
|
5de3b69e2c | ||
|
|
dfd6798377 | ||
|
|
074ae2a5a1 | ||
|
|
77f6a18075 | ||
|
|
0762d9e124 | ||
|
|
37dae04715 | ||
|
|
f299a7ad14 | ||
|
|
ba295385ab | ||
|
|
33adf518ae | ||
|
|
93885d0dd5 | ||
|
|
747cda79db | ||
|
|
f3cfc38adc | ||
|
|
dd3a0a706d | ||
|
|
37d001e7b5 | ||
|
|
add09e5a1c | ||
|
|
561d1c0e55 | ||
|
|
239ba335b1 | ||
|
|
ec83123090 | ||
|
|
4f6d5164a4 | ||
|
|
ae1e2eccd2 | ||
|
|
d7bc821bbe | ||
|
|
f8579f7c96 | ||
|
|
046a9ef6f2 | ||
|
|
64e15542a2 | ||
|
|
7dec674452 | ||
|
|
0f48d3e72c | ||
|
|
1f793c49ae | ||
|
|
e581539cf9 | ||
|
|
736eee79df | ||
|
|
7a0fe3819b | ||
|
|
65c9bf7e52 | ||
|
|
1e61b5670e | ||
|
|
6c2bae6296 | ||
|
|
358d6010b0 | ||
|
|
82978a25c5 | ||
|
|
3519696bae | ||
|
|
bd33df2cc7 | ||
|
|
5f44eb14ad | ||
|
|
fb94cf953a | ||
|
|
d7486218bc | ||
|
|
59913cdc4b | ||
|
|
2d7449aeba | ||
|
|
3ea53a8012 | ||
|
|
48cd12ec3d | ||
|
|
7c71ed2dc6 | ||
|
|
24d8ccc52f | ||
|
|
05cd96f2be | ||
|
|
75795ab1e9 | ||
|
|
bb1602f179 | ||
|
|
ac268f0f73 | ||
|
|
d924567e5f | ||
|
|
109d8df782 | ||
|
|
0aaa35098d | ||
|
|
6f57beab28 | ||
|
|
5b26e27834 | ||
|
|
8429f650aa | ||
|
|
3eb2202117 | ||
|
|
c217a40710 | ||
|
|
4a7308c5bb | ||
|
|
5fba51103e | ||
|
|
95a9808f35 | ||
|
|
c09e180c48 | ||
|
|
b09b650c1d | ||
|
|
44a41b963d | ||
|
|
0510189f54 | ||
|
|
16b3cf764d | ||
|
|
c634c39874 | ||
|
|
ae0846e877 | ||
|
|
40e7e1b418 | ||
|
|
e2a5853dde | ||
|
|
e419e67cb0 | ||
|
|
3356a4ce14 | ||
|
|
26a4347155 |
152
.clang-tidy
Normal file
152
.clang-tidy
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
---
|
||||||
|
Checks: >-
|
||||||
|
*,
|
||||||
|
-abseil-*,
|
||||||
|
-android-*,
|
||||||
|
-boost-*,
|
||||||
|
-bugprone-branch-clone,
|
||||||
|
-bugprone-narrowing-conversions,
|
||||||
|
-bugprone-signed-char-misuse,
|
||||||
|
-bugprone-too-small-loop-variable,
|
||||||
|
-cert-dcl50-cpp,
|
||||||
|
-cert-err58-cpp,
|
||||||
|
-cert-oop57-cpp,
|
||||||
|
-cert-str34-c,
|
||||||
|
-clang-analyzer-optin.cplusplus.UninitializedObject,
|
||||||
|
-clang-analyzer-osx.*,
|
||||||
|
-clang-diagnostic-delete-abstract-non-virtual-dtor,
|
||||||
|
-clang-diagnostic-delete-non-abstract-non-virtual-dtor,
|
||||||
|
-clang-diagnostic-shadow-field,
|
||||||
|
-clang-diagnostic-sign-compare,
|
||||||
|
-clang-diagnostic-unused-variable,
|
||||||
|
-clang-diagnostic-unused-const-variable,
|
||||||
|
-cppcoreguidelines-avoid-c-arrays,
|
||||||
|
-cppcoreguidelines-avoid-goto,
|
||||||
|
-cppcoreguidelines-avoid-magic-numbers,
|
||||||
|
-cppcoreguidelines-init-variables,
|
||||||
|
-cppcoreguidelines-macro-usage,
|
||||||
|
-cppcoreguidelines-narrowing-conversions,
|
||||||
|
-cppcoreguidelines-non-private-member-variables-in-classes,
|
||||||
|
-cppcoreguidelines-owning-memory,
|
||||||
|
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
|
||||||
|
-cppcoreguidelines-pro-bounds-constant-array-index,
|
||||||
|
-cppcoreguidelines-pro-bounds-pointer-arithmetic,
|
||||||
|
-cppcoreguidelines-pro-type-const-cast,
|
||||||
|
-cppcoreguidelines-pro-type-cstyle-cast,
|
||||||
|
-cppcoreguidelines-pro-type-member-init,
|
||||||
|
-cppcoreguidelines-pro-type-reinterpret-cast,
|
||||||
|
-cppcoreguidelines-pro-type-static-cast-downcast,
|
||||||
|
-cppcoreguidelines-pro-type-union-access,
|
||||||
|
-cppcoreguidelines-pro-type-vararg,
|
||||||
|
-cppcoreguidelines-special-member-functions,
|
||||||
|
-fuchsia-default-arguments,
|
||||||
|
-fuchsia-multiple-inheritance,
|
||||||
|
-fuchsia-overloaded-operator,
|
||||||
|
-fuchsia-statically-constructed-objects,
|
||||||
|
-fuchsia-default-arguments-declarations,
|
||||||
|
-fuchsia-default-arguments-calls,
|
||||||
|
-google-build-using-namespace,
|
||||||
|
-google-explicit-constructor,
|
||||||
|
-google-readability-braces-around-statements,
|
||||||
|
-google-readability-casting,
|
||||||
|
-google-readability-todo,
|
||||||
|
-google-runtime-references,
|
||||||
|
-hicpp-*,
|
||||||
|
-llvm-else-after-return,
|
||||||
|
-llvm-header-guard,
|
||||||
|
-llvm-include-order,
|
||||||
|
-llvm-qualified-auto,
|
||||||
|
-llvmlibc-*,
|
||||||
|
-misc-non-private-member-variables-in-classes,
|
||||||
|
-misc-no-recursion,
|
||||||
|
-misc-unused-parameters,
|
||||||
|
-modernize-avoid-c-arrays,
|
||||||
|
-modernize-return-braced-init-list,
|
||||||
|
-modernize-use-auto,
|
||||||
|
-modernize-use-default-member-init,
|
||||||
|
-modernize-use-equals-default,
|
||||||
|
-modernize-use-trailing-return-type,
|
||||||
|
-mpi-*,
|
||||||
|
-objc-*,
|
||||||
|
-readability-braces-around-statements,
|
||||||
|
-readability-const-return-type,
|
||||||
|
-readability-convert-member-functions-to-static,
|
||||||
|
-readability-else-after-return,
|
||||||
|
-readability-implicit-bool-conversion,
|
||||||
|
-readability-isolate-declaration,
|
||||||
|
-readability-magic-numbers,
|
||||||
|
-readability-make-member-function-const,
|
||||||
|
-readability-named-parameter,
|
||||||
|
-readability-qualified-auto,
|
||||||
|
-readability-redundant-access-specifiers,
|
||||||
|
-readability-redundant-member-init,
|
||||||
|
-readability-redundant-string-init,
|
||||||
|
-readability-uppercase-literal-suffix,
|
||||||
|
-readability-use-anyofallof,
|
||||||
|
-warnings-as-errors
|
||||||
|
WarningsAsErrors: '*'
|
||||||
|
AnalyzeTemporaryDtors: false
|
||||||
|
FormatStyle: google
|
||||||
|
CheckOptions:
|
||||||
|
- key: google-readability-braces-around-statements.ShortStatementLines
|
||||||
|
value: '1'
|
||||||
|
- key: google-readability-function-size.StatementThreshold
|
||||||
|
value: '800'
|
||||||
|
- key: google-readability-namespace-comments.ShortNamespaceLines
|
||||||
|
value: '10'
|
||||||
|
- key: google-readability-namespace-comments.SpacesBeforeComments
|
||||||
|
value: '2'
|
||||||
|
- key: modernize-loop-convert.MaxCopySize
|
||||||
|
value: '16'
|
||||||
|
- key: modernize-loop-convert.MinConfidence
|
||||||
|
value: reasonable
|
||||||
|
- key: modernize-loop-convert.NamingStyle
|
||||||
|
value: CamelCase
|
||||||
|
- key: modernize-pass-by-value.IncludeStyle
|
||||||
|
value: llvm
|
||||||
|
- key: modernize-replace-auto-ptr.IncludeStyle
|
||||||
|
value: llvm
|
||||||
|
- key: modernize-use-nullptr.NullMacros
|
||||||
|
value: 'NULL'
|
||||||
|
- key: readability-identifier-naming.LocalVariableCase
|
||||||
|
value: 'lower_case'
|
||||||
|
- key: readability-identifier-naming.ClassCase
|
||||||
|
value: 'CamelCase'
|
||||||
|
- key: readability-identifier-naming.StructCase
|
||||||
|
value: 'CamelCase'
|
||||||
|
- key: readability-identifier-naming.EnumCase
|
||||||
|
value: 'CamelCase'
|
||||||
|
- key: readability-identifier-naming.EnumConstantCase
|
||||||
|
value: 'UPPER_CASE'
|
||||||
|
- key: readability-identifier-naming.StaticConstantCase
|
||||||
|
value: 'UPPER_CASE'
|
||||||
|
- key: readability-identifier-naming.StaticVariableCase
|
||||||
|
value: 'UPPER_CASE'
|
||||||
|
- key: readability-identifier-naming.GlobalConstantCase
|
||||||
|
value: 'UPPER_CASE'
|
||||||
|
- key: readability-identifier-naming.ParameterCase
|
||||||
|
value: 'lower_case'
|
||||||
|
- key: readability-identifier-naming.PrivateMemberPrefix
|
||||||
|
value: 'NO_PRIVATE_MEMBERS_ALWAYS_USE_PROTECTED'
|
||||||
|
- key: readability-identifier-naming.PrivateMethodPrefix
|
||||||
|
value: 'NO_PRIVATE_METHODS_ALWAYS_USE_PROTECTED'
|
||||||
|
- key: readability-identifier-naming.ClassMemberCase
|
||||||
|
value: 'lower_case'
|
||||||
|
- key: readability-identifier-naming.ClassMemberCase
|
||||||
|
value: 'lower_case'
|
||||||
|
- key: readability-identifier-naming.ProtectedMemberCase
|
||||||
|
value: 'lower_case'
|
||||||
|
- key: readability-identifier-naming.ProtectedMemberSuffix
|
||||||
|
value: '_'
|
||||||
|
- key: readability-identifier-naming.FunctionCase
|
||||||
|
value: 'lower_case'
|
||||||
|
- key: readability-identifier-naming.ClassMethodCase
|
||||||
|
value: 'lower_case'
|
||||||
|
- key: readability-identifier-naming.ProtectedMethodCase
|
||||||
|
value: 'lower_case'
|
||||||
|
- key: readability-identifier-naming.ProtectedMethodSuffix
|
||||||
|
value: '_'
|
||||||
|
- key: readability-identifier-naming.VirtualMethodCase
|
||||||
|
value: 'lower_case'
|
||||||
|
- key: readability-identifier-naming.VirtualMethodSuffix
|
||||||
|
value: ''
|
||||||
2
.github/workflows/pre_release.yml
vendored
2
.github/workflows/pre_release.yml
vendored
@@ -48,7 +48,7 @@ jobs:
|
|||||||
uses: "marvinpinto/action-automatic-releases@latest"
|
uses: "marvinpinto/action-automatic-releases@latest"
|
||||||
with:
|
with:
|
||||||
repo_token: "${{ secrets.GITHUB_TOKEN }}"
|
repo_token: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
title: ESP32 Development Build v${{steps.build_info.outputs.version}}
|
title: Development Build v${{steps.build_info.outputs.version}}
|
||||||
automatic_release_tag: "latest"
|
automatic_release_tag: "latest"
|
||||||
prerelease: true
|
prerelease: true
|
||||||
files: |
|
files: |
|
||||||
|
|||||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -27,4 +27,6 @@ emsesp
|
|||||||
/interface/build
|
/interface/build
|
||||||
node_modules
|
node_modules
|
||||||
/interface/.eslintcache
|
/interface/.eslintcache
|
||||||
|
test.sh
|
||||||
|
scripts/__pycache__
|
||||||
|
.temp
|
||||||
|
|||||||
123
CHANGELOG.md
123
CHANGELOG.md
@@ -5,10 +5,129 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
# [3.1.1] June 26 2021
|
# Changelog
|
||||||
|
|
||||||
|
# [3.3.0] November 28 2021
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- Add system commands for syslog level and watch [#98](https://github.com/emsesp/EMS-ESP32/issues/98)
|
||||||
|
- Added pool data to telegrams 0x494 & 0x495 [#102](https://github.com/emsesp/EMS-ESP32/issues/102)
|
||||||
|
- Add RC300 second summermode telegram [#108](https://github.com/emsesp/EMS-ESP32/issues/108)
|
||||||
|
- Add support for the RC25 thermostat [#106](https://github.com/emsesp/EMS-ESP32/issues/106)
|
||||||
|
- Add new command 'entities' for a device, e.g. http://ems-esp/api/boiler/entities to show the shortname, description and HA Entity name (if HA enabled) [#116](https://github.com/emsesp/EMS-ESP32/issues/116)
|
||||||
|
- Support for Junkers program and remote (fb10/fb110) temperature
|
||||||
|
- Home Assistant `state_class` attribute for Wh, kWh, W and KW [#129](https://github.com/emsesp/EMS-ESP32/issues/129)
|
||||||
|
- Add current room influence for RC300 [#136](https://github.com/emsesp/EMS-ESP32/issues/136)
|
||||||
|
- Added Home Assistant device_class to sensor entities
|
||||||
|
- Added another Buderus RC10 thermostat with Product ID 65 [#160](https://github.com/emsesp/EMS-ESP32/issues/160)
|
||||||
|
- Added support for mDNS [#161](https://github.com/emsesp/EMS-ESP32/issues/161)
|
||||||
|
- Added last system ESP32 reset code to log (and `system info` output)
|
||||||
|
- Firmware Checker in WebUI [#168](https://github.com/emsesp/EMS-ESP32/issues/168)
|
||||||
|
- Added new MQTT setting for enabling 'response' topic
|
||||||
|
- Support for non-standard Thermostats like Tado [#174](https://github.com/emsesp/EMS-ESP32/issues/174)
|
||||||
|
- Include MQTT connection status in 'api/system/info'
|
||||||
|
- Include Network status in 'api/system/info' and also the MQTT topic `info` [#202](https://github.com/emsesp/EMS-ESP32/issues/202)
|
||||||
|
- Added Ethernet PHY module as an option in the Board Profile [#210](https://github.com/emsesp/EMS-ESP32/issues/210)
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- MQTT reconnecting after WiFi reconnect [#99](https://github.com/emsesp/EMS-ESP32/issues/99)
|
||||||
|
- Manually Controlling Solar Circuit [#107](https://github.com/emsesp/EMS-ESP32/issues/107)
|
||||||
|
- Fix thermostat commands not defaulting to the master thermostat [#110](https://github.com/emsesp/EMS-ESP32/issues/110)
|
||||||
|
- Enlarge parse-buffer for long names like `cylinderpumpmodulation`
|
||||||
|
- MQTT not subscribing to all device entities [#166](https://github.com/emsesp/EMS-ESP32/issues/166)
|
||||||
|
- Help fix issues with WebUI unable to fully load UI over Ethernet [#177](https://github.com/emsesp/EMS-ESP32/issues/177)
|
||||||
|
- Shower alert never reset after limit reached when enabled [(PR #185)]
|
||||||
|
- Remove HA entity entries when a device value goes dormant [#196](https://github.com/emsesp/EMS-ESP32/issues/196)
|
||||||
|
- deciphering last error code dates on 0xC2 telegram [#204](https://github.com/emsesp/EMS-ESP32/issues/204)
|
||||||
|
|
||||||
## Changed
|
## Changed
|
||||||
|
|
||||||
|
- Syslog BOM only for utf-8 messages [#91](https://github.com/emsesp/EMS-ESP32/issues/91)
|
||||||
|
- Check for KM200 by device-id 0x48, remove tx-delay [#90](https://github.com/emsesp/EMS-ESP32/issues/90)
|
||||||
|
- rename `fastheatupfactor` to `fastheatup` and add percent [#122](https://github.com/emsesp/EMS-ESP32/issues/122)
|
||||||
|
- "unit" renamed to "uom" in API call to recall a Device Value
|
||||||
|
- initial backend React changes to replace the class components (HOCs) with React Hooks
|
||||||
|
- Use program-names instead of numbers
|
||||||
|
- Boiler's maintenancemessage always published in MQTT (to prevent HA missing entity)
|
||||||
|
- Unit of Measure 'times' added to MQTT Fails, Rx fails, Rx received, Tx fails, Tx reads & Tx writes
|
||||||
|
- Improved API. Restful HTTP API works in the same way as MQTT calls
|
||||||
|
- Removed settings for MQTT subscribe format [#173](https://github.com/emsesp/EMS-ESP32/issues/173)
|
||||||
|
- Improve Nefit Moduline 200 functionality [#183](https://github.com/emsesp/EMS-ESP32/issues/183)
|
||||||
|
- `status` in the MQTT heartbeat renamed to `bus_status`
|
||||||
|
- Layout changes in the WebUI, showing stripped table rows in Dashboard
|
||||||
|
- Alternative font for log window [#219](https://github.com/emsesp/EMS-ESP32/issues/219)
|
||||||
|
|
||||||
|
## **BREAKING CHANGES**
|
||||||
|
|
||||||
|
- API: "unit" renamed to "uom" in API call to recall a Device Value
|
||||||
|
- HA: `sensor.boiler_boiler_temperature` renamed to `sensor.actual_boiler_temperature`
|
||||||
|
- HA: `binary_sensor.boiler_ww_disinfecting` renamed to `binary_sensor.boiler_ww_disinfection`
|
||||||
|
- HA: # removed from counts in MQTT Fails, Rx fails, Rx received, Tx fails, Tx reads & Tx writes
|
||||||
|
- `txread` renamed to `txreads` and `txwrite` renamed to `txwrites` in MQTT heartbeat payload
|
||||||
|
- 'dallas sensors' in api/system/info moved to the "System" section. Renamed "uptime (seconds)" and "reset reason"
|
||||||
|
- `status` in the MQTT heartbeat renamed to `bus_status`
|
||||||
|
|
||||||
|
# [3.2.1] August 8 2021
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- json body in API can now take device, name, cmd, hc and id
|
||||||
|
- added example of how to use API directly to control values from Home Assistant
|
||||||
|
- API calls are shown in debug log (For troubleshooting)
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- fixed issue with Home Assistant entity naming where boiler's ww was duplicated in entity name
|
||||||
|
- fixed issue where wwSetTemp was written too instead of wwSelTemp
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- fixed case on mqtt names, like 'wwtankmiddletemp'
|
||||||
|
- renamed Product ID to 'EMS Product ID' in Home Assistant
|
||||||
|
- removed brackets around tags, e.g. (hc1) selected room temperature" is now just "hc1 selected room temperature"
|
||||||
|
|
||||||
|
# [3.2.0] August 6 2021
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- support for IPv6 (web/api/mqtt, not syslog yet) [#83](https://github.com/emsesp/EMS-ESP32/issues/83)
|
||||||
|
- System Log in Web UI will show current time if the NTP Service is enabled [#82](https://github.com/emsesp/EMS-ESP32/issues/82)
|
||||||
|
- Network settings for Tx-power, WiFi-bandwidth, WiFi-sleepmode [#83](https://github.com/emsesp/EMS-ESP32/issues/83)
|
||||||
|
- optional low CPU clockrate (160 MHz) [#83](https://github.com/emsesp/EMS-ESP32/issues/83)
|
||||||
|
- select format for enumerated values in web
|
||||||
|
- settings for water hysteresis on/off
|
||||||
|
- dallas sensor name editable. `sensorname` console-command, replace sensorid with a unique name [#84](https://github.com/emsesp/EMS-ESP32/issues/84)
|
||||||
|
- 'restart' system command. Can be invoked via API with authentication. [#87](https://github.com/emsesp/EMS-ESP32/issues/87)
|
||||||
|
- add Download button in Web UI for log
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- set mode allow numbers
|
||||||
|
- Junkers thermostat shows mode as selected by set_mode
|
||||||
|
- HA thermostat mode if bool-format: numbers is selected
|
||||||
|
- Web UI System Log sometimes skipped a few log messages when watching real-time
|
||||||
|
- fix wwactivated [#89](https://github.com/emsesp/EMS-ESP32/issues/89)
|
||||||
|
- don't show commands (like reset) as Device values in the Web or Console
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- removed Rx echo failures counting as incomplete telegrams. Bad telegrams show as Warning and not Errors. [#80](https://github.com/emsesp/EMS-ESP32/issues/80)
|
||||||
|
- add upload_sec to `api/system/info` and removed # from some names to keep consistent with MQTT heartbeat
|
||||||
|
- added debug target to PlatformIO build to help hunt down system crashes
|
||||||
|
- enumerated values always start at zero
|
||||||
|
- maintenance settings for time/date as extra setting
|
||||||
|
- move api/mqtt formats to `settings`, add `enum format`
|
||||||
|
- UI improvements for editing Dallas Sensor details
|
||||||
|
- RESTful GET commands can also require authentication (via bearer access token) for better security
|
||||||
|
- Updated AsyncMqttClient to 0.9.0 and ArduinoJson to 6.18.3
|
||||||
|
- Download buttons for settings and info under the Help tab
|
||||||
|
|
||||||
|
# [3.1.1] June 26 2021
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
- new command called `commands` which lists all available commands. `ems-esp/api/{device}/commands`
|
- new command called `commands` which lists all available commands. `ems-esp/api/{device}/commands`
|
||||||
- More Home Assistant icons to match the UOMs
|
- More Home Assistant icons to match the UOMs
|
||||||
- new API. Using secure access tokens and OpenAPI standard. See `doc/EMS-ESP32 API.md` and [#50](https://github.com/emsesp/EMS-ESP32/issues/50)
|
- new API. Using secure access tokens and OpenAPI standard. See `doc/EMS-ESP32 API.md` and [#50](https://github.com/emsesp/EMS-ESP32/issues/50)
|
||||||
@@ -29,7 +148,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
# [3.1.0] May 4 2021
|
# [3.1.0] May 4 2021
|
||||||
|
|
||||||
## Changed
|
## Added
|
||||||
|
|
||||||
- Mock API to simulate an ESP, for testing web
|
- Mock API to simulate an ESP, for testing web
|
||||||
- Able to write values from the Web UI
|
- Able to write values from the Web UI
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
# Changelog
|
|
||||||
|
|
||||||
## Added
|
|
||||||
|
|
||||||
## Fixed
|
|
||||||
|
|
||||||
## Changed
|
|
||||||
|
|
||||||
## Removed
|
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ This document describes rules that are in effect for this repository, meant for
|
|||||||
6. Issues with feature requests should be discussed for viability/desirability.
|
6. Issues with feature requests should be discussed for viability/desirability.
|
||||||
7. Feature requests or changes that are meant to address a very specific/limited use case, especially if at the expense of increased code complexity, may be denied, or may be required to be redesigned, generalized, or simplified.
|
7. Feature requests or changes that are meant to address a very specific/limited use case, especially if at the expense of increased code complexity, may be denied, or may be required to be redesigned, generalized, or simplified.
|
||||||
8. Feature requests that are not accompanied by a PR:
|
8. Feature requests that are not accompanied by a PR:
|
||||||
* could be closed immediately (denied).
|
- could be closed immediately (denied).
|
||||||
* could be closed after some predetermined period of time (left as candidate for somebody to pick up).
|
- could be closed after some predetermined period of time (left as candidate for somebody to pick up).
|
||||||
9. In some cases, feedback may be requested from the issue reporter, either as additional info for clarification, additional testing, or other. If no feedback is provided, the issue may be closed by a contributor or after 40 days by the STALE bot.
|
9. In some cases, feedback may be requested from the issue reporter, either as additional info for clarification, additional testing, or other. If no feedback is provided, the issue may be closed by a contributor or after 40 days by the STALE bot.
|
||||||
|
|
||||||
## Pull requests
|
## Pull requests
|
||||||
@@ -49,17 +49,17 @@ The process is straight-forward.
|
|||||||
- Create a Pull Request against the [**dev**](https://github.com/emsesp/EMS-ESP32/tree/dev) branch of EMS-ESP.
|
- Create a Pull Request against the [**dev**](https://github.com/emsesp/EMS-ESP32/tree/dev) branch of EMS-ESP.
|
||||||
|
|
||||||
1. All pull requests must be done against the dev branch.
|
1. All pull requests must be done against the dev branch.
|
||||||
2. Make sure code is formatting per the `.clang-format`
|
2. Make sure code is formatting per the `.clang-format`.
|
||||||
3. Only relevant files should be touched (Also beware if your editor has auto-formatting feature enabled).
|
3. Make sure any new code is clearly commented explaining what the function/logic does.
|
||||||
4. Only one feature/fix should be added per PR.
|
4. Only relevant files should be touched (Also beware if your editor has auto-formatting feature enabled).
|
||||||
5. PRs that don't compile (fail in CI Tests) or cause coding errors will not be merged. Please fix the issue. Same goes for PRs that are raised against older commit in dev - you might need to rebase and resolve conflicts.
|
5. Only one feature/fix should be added per PR.
|
||||||
6. All pull requests should undergo peer review by at least one contributor other than the creator, excepts for the owner.
|
6. PRs that don't compile (fail in CI Tests) or cause coding errors will not be merged. Please fix the issue. Same goes for PRs that are raised against older commit in dev - you might need to rebase and resolve conflicts.
|
||||||
7. All pull requests should consider updates to the documentation.
|
7. All pull requests should undergo peer review by at least one contributor other than the creator, excepts for the owner.
|
||||||
8. Pull requests that address an outstanding issue, particularly an issue deemed to be severe, should be given priority.
|
8. All pull requests should consider updates to the documentation.
|
||||||
9. If a PR is accepted, then it should undergo review and updated based on the feedback provided, then merged.
|
9. Pull requests that address an outstanding issue, particularly an issue deemed to be severe, should be given priority.
|
||||||
10. By submitting a PR, it is needed to use the provided PR template and check all boxes, performing the required tasks and accepting the CLA.
|
10. If a PR is accepted, then it should undergo review and updated based on the feedback provided, then merged.
|
||||||
11. Pull requests that don't meet the above will be denied and closed.
|
11. By submitting a PR, it is needed to use the provided PR template and check all boxes, performing the required tasks and accepting the CLA.
|
||||||
|
12. Pull requests that don't meet the above will be denied and closed.
|
||||||
|
|
||||||
## Semantic Commit Messages
|
## Semantic Commit Messages
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ More Examples:
|
|||||||
|
|
||||||
References:
|
References:
|
||||||
|
|
||||||
- https://www.conventionalcommits.org/
|
- <https://www.conventionalcommits.org/>
|
||||||
|
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ CXX_STANDARD := -std=c++11
|
|||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
# Defined Symbols
|
# Defined Symbols
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
DEFINES += -DARDUINOJSON_ENABLE_STD_STRING=1 -DARDUINOJSON_ENABLE_ARDUINO_STRING -DEMSESP_DEBUG -DEMSESP_STANDALONE -DEMSESP_DEFAULT_BOARD_PROFILE=\"LOLIN\"
|
DEFINES += -DARDUINOJSON_ENABLE_STD_STRING=1 -DARDUINOJSON_ENABLE_ARDUINO_STRING -DARDUINOJSON_USE_DOUBLE -DEMSESP_DEBUG -DEMSESP_STANDALONE -DEMSESP_DEFAULT_BOARD_PROFILE=\"LOLIN\"
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
# Sources & Files
|
# Sources & Files
|
||||||
@@ -72,9 +72,9 @@ CPPFLAGS += -g3
|
|||||||
CPPFLAGS += -Os
|
CPPFLAGS += -Os
|
||||||
|
|
||||||
CFLAGS += $(CPPFLAGS)
|
CFLAGS += $(CPPFLAGS)
|
||||||
# CFLAGS += -Wall
|
CFLAGS += -Wall
|
||||||
# CFLAGS += -Wno-unused -Wno-restrict
|
CFLAGS += -Wno-unused -Wno-restrict
|
||||||
# CFLAGS += -Wextra
|
CFLAGS += -Wextra
|
||||||
|
|
||||||
CXXFLAGS += $(CFLAGS) -MMD
|
CXXFLAGS += $(CFLAGS) -MMD
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# Name, Type, SubType, Offset, Size, Flags
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
nvs, data, nvs, 0x9000, 0x5000,
|
nvs, data, nvs, 0x9000, 0x5000,
|
||||||
otadata, data, ota, 0xe000, 0x2000,
|
otadata, data, ota, 0xE000, 0x2000,
|
||||||
app0, app, ota_0, 0x10000, 0x1F0000,
|
app0, app, ota_0, 0x10000, 0x1F0000,
|
||||||
app1, app, ota_1, 0x200000, 0x1F0000,
|
app1, app, ota_1, 0x200000, 0x1F0000,
|
||||||
spiffs, data, spiffs, 0x3F0000, 0x10000,
|
spiffs, data, spiffs, 0x3F0000, 0x10000,
|
||||||
|
|||||||
|
5
esp32_partition_debug.csv
Normal file
5
esp32_partition_debug.csv
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
|
nvs, data, nvs, 0x9000, 0x5000,
|
||||||
|
otadata, data, ota, 0xE000, 0x2000,
|
||||||
|
app0, app, ota_0, 0x10000, 0x210000,
|
||||||
|
spiffs, data, spiffs, 0x220000, 0x10000,
|
||||||
|
325
interface/package-lock.json
generated
325
interface/package-lock.json
generated
@@ -8,13 +8,13 @@
|
|||||||
"name": "emsesp-react",
|
"name": "emsesp-react",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@material-ui/core": "^4.11.4",
|
"@material-ui/core": "^4.12.3",
|
||||||
"@material-ui/icons": "^4.11.2",
|
"@material-ui/icons": "^4.11.2",
|
||||||
"@msgpack/msgpack": "^2.7.0",
|
"@msgpack/msgpack": "^2.7.0",
|
||||||
"@types/lodash": "^4.14.168",
|
"@types/lodash": "^4.14.172",
|
||||||
"@types/node": "^15.0.1",
|
"@types/node": "^12.20.20",
|
||||||
"@types/react": "^17.0.4",
|
"@types/react": "^17.0.19",
|
||||||
"@types/react-dom": "^17.0.3",
|
"@types/react-dom": "^17.0.9",
|
||||||
"@types/react-material-ui-form-validator": "^2.1.0",
|
"@types/react-material-ui-form-validator": "^2.1.0",
|
||||||
"@types/react-router": "^5.1.13",
|
"@types/react-router": "^5.1.13",
|
||||||
"@types/react-router-dom": "^5.1.7",
|
"@types/react-router-dom": "^5.1.7",
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
"react-scripts": "4.0.3",
|
"react-scripts": "4.0.3",
|
||||||
"sockette": "^2.0.6",
|
"sockette": "^2.0.6",
|
||||||
"typescript": "4.2.4",
|
"typescript": "4.3.5",
|
||||||
"zlib": "^1.0.5"
|
"zlib": "^1.0.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -2050,13 +2050,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@material-ui/core": {
|
"node_modules/@material-ui/core": {
|
||||||
"version": "4.11.4",
|
"version": "4.12.3",
|
||||||
"resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.11.4.tgz",
|
"resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.12.3.tgz",
|
||||||
"integrity": "sha512-oqb+lJ2Dl9HXI9orc6/aN8ZIAMkeThufA5iZELf2LQeBn2NtjVilF5D2w7e9RpntAzDb4jK5DsVhkfOvFY/8fg==",
|
"integrity": "sha512-sdpgI/PL56QVsEJldwEe4FFaFTLUqN+rd7sSZiRCdx2E/C7z5yK0y/khAWVBH24tXwto7I1hCzNWfJGZIYJKnw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.4.4",
|
"@babel/runtime": "^7.4.4",
|
||||||
"@material-ui/styles": "^4.11.4",
|
"@material-ui/styles": "^4.11.4",
|
||||||
"@material-ui/system": "^4.11.3",
|
"@material-ui/system": "^4.12.1",
|
||||||
"@material-ui/types": "5.1.0",
|
"@material-ui/types": "5.1.0",
|
||||||
"@material-ui/utils": "^4.11.2",
|
"@material-ui/utils": "^4.11.2",
|
||||||
"@types/react-transition-group": "^4.2.0",
|
"@types/react-transition-group": "^4.2.0",
|
||||||
@@ -2137,9 +2137,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@material-ui/system": {
|
"node_modules/@material-ui/system": {
|
||||||
"version": "4.11.3",
|
"version": "4.12.1",
|
||||||
"resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.11.3.tgz",
|
"resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.12.1.tgz",
|
||||||
"integrity": "sha512-SY7otguNGol41Mu2Sg6KbBP1ZRFIbFLHGK81y4KYbsV2yIcaEPOmsCK6zwWlp+2yTV3J/VwT6oSBARtGIVdXPw==",
|
"integrity": "sha512-lUdzs4q9kEXZGhbN7BptyiS1rLNHe6kG9o8Y307HCvF4sQxbCgpL2qi+gUk+yI8a2DNk48gISEQxoxpgph0xIw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.4.4",
|
"@babel/runtime": "^7.4.4",
|
||||||
"@material-ui/utils": "^4.11.2",
|
"@material-ui/utils": "^4.11.2",
|
||||||
@@ -2148,6 +2148,20 @@
|
|||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8.0.0"
|
"node": ">=8.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/material-ui"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "^16.8.6 || ^17.0.0",
|
||||||
|
"react": "^16.8.0 || ^17.0.0",
|
||||||
|
"react-dom": "^16.8.0 || ^17.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@material-ui/types": {
|
"node_modules/@material-ui/types": {
|
||||||
@@ -2639,9 +2653,9 @@
|
|||||||
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4="
|
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4="
|
||||||
},
|
},
|
||||||
"node_modules/@types/lodash": {
|
"node_modules/@types/lodash": {
|
||||||
"version": "4.14.168",
|
"version": "4.14.173",
|
||||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz",
|
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.173.tgz",
|
||||||
"integrity": "sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q=="
|
"integrity": "sha512-vv0CAYoaEjCw/mLy96GBTnRoZrSxkGE0BKzKimdR8P3OzrNYNvBgtW7p055A+E8C31vXNUhWKoFCbhq7gbyhFg=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/material-ui": {
|
"node_modules/@types/material-ui": {
|
||||||
"version": "0.21.8",
|
"version": "0.21.8",
|
||||||
@@ -2658,9 +2672,9 @@
|
|||||||
"integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA=="
|
"integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "15.0.1",
|
"version": "12.20.25",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.25.tgz",
|
||||||
"integrity": "sha512-TMkXt0Ck1y0KKsGr9gJtWGjttxlZnnvDtphxUOSd0bfaR6Q1jle+sPvrzNR1urqYTWMinoKvjKfXUGsumaO1PA=="
|
"integrity": "sha512-hcTWqk7DR/HrN9Xe7AlJwuCaL13Vcd9/g/T54YrJz4Q3ESM5mr33YCzW2bOfzSIc3aZMeGBvbLGvgN6mIJ0I5Q=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/normalize-package-data": {
|
"node_modules/@types/normalize-package-data": {
|
||||||
"version": "2.4.0",
|
"version": "2.4.0",
|
||||||
@@ -2688,9 +2702,9 @@
|
|||||||
"integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug=="
|
"integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/react": {
|
"node_modules/@types/react": {
|
||||||
"version": "17.0.4",
|
"version": "17.0.22",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.22.tgz",
|
||||||
"integrity": "sha512-onz2BqScSFMoTRdJUZUDD/7xrusM8hBA2Fktk2qgaTYPCgPvWnDEgkrOs8hhPUf2jfcIXkJ5yK6VfYormJS3Jw==",
|
"integrity": "sha512-kq/BMeaAVLJM6Pynh8C2rnr/drCK+/5ksH0ch9asz+8FW3DscYCIEFtCeYTFeIx/ubvOsMXmRfy7qEJ76gM96A==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/prop-types": "*",
|
"@types/prop-types": "*",
|
||||||
"@types/scheduler": "*",
|
"@types/scheduler": "*",
|
||||||
@@ -2706,9 +2720,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/react-dom": {
|
"node_modules/@types/react-dom": {
|
||||||
"version": "17.0.3",
|
"version": "17.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.9.tgz",
|
||||||
"integrity": "sha512-4NnJbCeWE+8YBzupn/YrJxZ8VnjcJq5iR1laqQ1vkpQgBiA7bwk0Rp24fxsdNinzJY2U+HHS4dJJDPdoMjdJ7w==",
|
"integrity": "sha512-wIvGxLfgpVDSAMH5utdL9Ngm5Owu0VsGmldro3ORLXV8CShrL8awVj06NuEXFQ5xyaYfdca7Sgbk/50Ri1GdPg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/react": "*"
|
"@types/react": "*"
|
||||||
}
|
}
|
||||||
@@ -4339,6 +4353,15 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/bindings": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"file-uri-to-path": "1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/bluebird": {
|
"node_modules/bluebird": {
|
||||||
"version": "3.7.2",
|
"version": "3.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
|
||||||
@@ -4764,9 +4787,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/cacheable-request/node_modules/normalize-url": {
|
"node_modules/cacheable-request/node_modules/normalize-url": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz",
|
||||||
"integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
|
"integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
@@ -8419,6 +8442,12 @@
|
|||||||
"node": ">= 10"
|
"node": ">= 10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/file-uri-to-path": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"node_modules/filesize": {
|
"node_modules/filesize": {
|
||||||
"version": "6.1.0",
|
"version": "6.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz",
|
||||||
@@ -8860,6 +8889,19 @@
|
|||||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
||||||
},
|
},
|
||||||
|
"node_modules/fsevents": {
|
||||||
|
"version": "2.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||||
|
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/function-bind": {
|
"node_modules/function-bind": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||||
@@ -13252,6 +13294,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz",
|
||||||
"integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE="
|
"integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE="
|
||||||
},
|
},
|
||||||
|
"node_modules/nan": {
|
||||||
|
"version": "2.15.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz",
|
||||||
|
"integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"node_modules/nanoid": {
|
"node_modules/nanoid": {
|
||||||
"version": "3.1.23",
|
"version": "3.1.23",
|
||||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz",
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz",
|
||||||
@@ -14247,9 +14295,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/path-parse": {
|
"node_modules/path-parse": {
|
||||||
"version": "1.0.6",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||||
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
|
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
|
||||||
},
|
},
|
||||||
"node_modules/path-to-regexp": {
|
"node_modules/path-to-regexp": {
|
||||||
"version": "0.1.7",
|
"version": "0.1.7",
|
||||||
@@ -14499,9 +14547,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/postcss": {
|
"node_modules/postcss": {
|
||||||
"version": "7.0.35",
|
"version": "7.0.36",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
|
||||||
"integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
|
"integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chalk": "^2.4.2",
|
"chalk": "^2.4.2",
|
||||||
"source-map": "^0.6.1",
|
"source-map": "^0.6.1",
|
||||||
@@ -14509,6 +14557,10 @@
|
|||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/postcss/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/postcss-attribute-case-insensitive": {
|
"node_modules/postcss-attribute-case-insensitive": {
|
||||||
@@ -16948,9 +17000,9 @@
|
|||||||
"integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo="
|
"integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo="
|
||||||
},
|
},
|
||||||
"node_modules/resolve-url-loader": {
|
"node_modules/resolve-url-loader": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.4.tgz",
|
||||||
"integrity": "sha512-WbDSNFiKPPLem1ln+EVTE+bFUBdTTytfQZWbmghroaFNFaAVmGq0Saqw6F/306CwgPXsGwXVxbODE+3xAo/YbA==",
|
"integrity": "sha512-D3sQ04o0eeQEySLrcz4DsX3saHfsr8/N6tfhblxgZKXxMT2Louargg12oGNfoTRLV09GXhVUe5/qgA5vdgNigg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"adjust-sourcemap-loader": "3.0.0",
|
"adjust-sourcemap-loader": "3.0.0",
|
||||||
"camelcase": "5.3.1",
|
"camelcase": "5.3.1",
|
||||||
@@ -16958,7 +17010,7 @@
|
|||||||
"convert-source-map": "1.7.0",
|
"convert-source-map": "1.7.0",
|
||||||
"es6-iterator": "2.0.3",
|
"es6-iterator": "2.0.3",
|
||||||
"loader-utils": "1.2.3",
|
"loader-utils": "1.2.3",
|
||||||
"postcss": "7.0.21",
|
"postcss": "7.0.36",
|
||||||
"rework": "1.0.1",
|
"rework": "1.0.1",
|
||||||
"rework-visit": "1.0.0",
|
"rework-visit": "1.0.0",
|
||||||
"source-map": "0.6.1"
|
"source-map": "0.6.1"
|
||||||
@@ -17007,19 +17059,6 @@
|
|||||||
"node": ">=4.0.0"
|
"node": ">=4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/resolve-url-loader/node_modules/postcss": {
|
|
||||||
"version": "7.0.21",
|
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.21.tgz",
|
|
||||||
"integrity": "sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"chalk": "^2.4.2",
|
|
||||||
"source-map": "^0.6.1",
|
|
||||||
"supports-color": "^6.1.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/resolve-url-loader/node_modules/source-map": {
|
"node_modules/resolve-url-loader/node_modules/source-map": {
|
||||||
"version": "0.6.1",
|
"version": "0.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||||
@@ -17028,17 +17067,6 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/resolve-url-loader/node_modules/supports-color": {
|
|
||||||
"version": "6.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
|
|
||||||
"integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"has-flag": "^3.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/responselike": {
|
"node_modules/responselike": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
|
||||||
@@ -18669,9 +18697,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tar": {
|
"node_modules/tar": {
|
||||||
"version": "6.1.0",
|
"version": "6.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
|
||||||
"integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==",
|
"integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chownr": "^2.0.0",
|
"chownr": "^2.0.0",
|
||||||
"fs-minipass": "^2.0.0",
|
"fs-minipass": "^2.0.0",
|
||||||
@@ -19249,9 +19277,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "4.2.4",
|
"version": "4.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz",
|
||||||
"integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==",
|
"integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==",
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
@@ -19570,9 +19598,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/url-parse": {
|
"node_modules/url-parse": {
|
||||||
"version": "1.5.1",
|
"version": "1.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz",
|
||||||
"integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==",
|
"integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"querystringify": "^2.1.1",
|
"querystringify": "^2.1.1",
|
||||||
"requires-port": "^1.0.0"
|
"requires-port": "^1.0.0"
|
||||||
@@ -20086,6 +20114,24 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/webpack-dev-server/node_modules/fsevents": {
|
||||||
|
"version": "1.2.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
|
||||||
|
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
|
||||||
|
"deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"bindings": "^1.5.0",
|
||||||
|
"nan": "^2.12.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/webpack-dev-server/node_modules/glob-parent": {
|
"node_modules/webpack-dev-server/node_modules/glob-parent": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
|
||||||
@@ -23150,13 +23196,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@material-ui/core": {
|
"@material-ui/core": {
|
||||||
"version": "4.11.4",
|
"version": "4.12.3",
|
||||||
"resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.11.4.tgz",
|
"resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.12.3.tgz",
|
||||||
"integrity": "sha512-oqb+lJ2Dl9HXI9orc6/aN8ZIAMkeThufA5iZELf2LQeBn2NtjVilF5D2w7e9RpntAzDb4jK5DsVhkfOvFY/8fg==",
|
"integrity": "sha512-sdpgI/PL56QVsEJldwEe4FFaFTLUqN+rd7sSZiRCdx2E/C7z5yK0y/khAWVBH24tXwto7I1hCzNWfJGZIYJKnw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.4.4",
|
"@babel/runtime": "^7.4.4",
|
||||||
"@material-ui/styles": "^4.11.4",
|
"@material-ui/styles": "^4.11.4",
|
||||||
"@material-ui/system": "^4.11.3",
|
"@material-ui/system": "^4.12.1",
|
||||||
"@material-ui/types": "5.1.0",
|
"@material-ui/types": "5.1.0",
|
||||||
"@material-ui/utils": "^4.11.2",
|
"@material-ui/utils": "^4.11.2",
|
||||||
"@types/react-transition-group": "^4.2.0",
|
"@types/react-transition-group": "^4.2.0",
|
||||||
@@ -23200,9 +23246,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@material-ui/system": {
|
"@material-ui/system": {
|
||||||
"version": "4.11.3",
|
"version": "4.12.1",
|
||||||
"resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.11.3.tgz",
|
"resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.12.1.tgz",
|
||||||
"integrity": "sha512-SY7otguNGol41Mu2Sg6KbBP1ZRFIbFLHGK81y4KYbsV2yIcaEPOmsCK6zwWlp+2yTV3J/VwT6oSBARtGIVdXPw==",
|
"integrity": "sha512-lUdzs4q9kEXZGhbN7BptyiS1rLNHe6kG9o8Y307HCvF4sQxbCgpL2qi+gUk+yI8a2DNk48gISEQxoxpgph0xIw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.4.4",
|
"@babel/runtime": "^7.4.4",
|
||||||
"@material-ui/utils": "^4.11.2",
|
"@material-ui/utils": "^4.11.2",
|
||||||
@@ -23611,9 +23657,9 @@
|
|||||||
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4="
|
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4="
|
||||||
},
|
},
|
||||||
"@types/lodash": {
|
"@types/lodash": {
|
||||||
"version": "4.14.168",
|
"version": "4.14.173",
|
||||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz",
|
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.173.tgz",
|
||||||
"integrity": "sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q=="
|
"integrity": "sha512-vv0CAYoaEjCw/mLy96GBTnRoZrSxkGE0BKzKimdR8P3OzrNYNvBgtW7p055A+E8C31vXNUhWKoFCbhq7gbyhFg=="
|
||||||
},
|
},
|
||||||
"@types/material-ui": {
|
"@types/material-ui": {
|
||||||
"version": "0.21.8",
|
"version": "0.21.8",
|
||||||
@@ -23630,9 +23676,9 @@
|
|||||||
"integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA=="
|
"integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA=="
|
||||||
},
|
},
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "15.0.1",
|
"version": "12.20.25",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.25.tgz",
|
||||||
"integrity": "sha512-TMkXt0Ck1y0KKsGr9gJtWGjttxlZnnvDtphxUOSd0bfaR6Q1jle+sPvrzNR1urqYTWMinoKvjKfXUGsumaO1PA=="
|
"integrity": "sha512-hcTWqk7DR/HrN9Xe7AlJwuCaL13Vcd9/g/T54YrJz4Q3ESM5mr33YCzW2bOfzSIc3aZMeGBvbLGvgN6mIJ0I5Q=="
|
||||||
},
|
},
|
||||||
"@types/normalize-package-data": {
|
"@types/normalize-package-data": {
|
||||||
"version": "2.4.0",
|
"version": "2.4.0",
|
||||||
@@ -23660,9 +23706,9 @@
|
|||||||
"integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug=="
|
"integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug=="
|
||||||
},
|
},
|
||||||
"@types/react": {
|
"@types/react": {
|
||||||
"version": "17.0.4",
|
"version": "17.0.22",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.22.tgz",
|
||||||
"integrity": "sha512-onz2BqScSFMoTRdJUZUDD/7xrusM8hBA2Fktk2qgaTYPCgPvWnDEgkrOs8hhPUf2jfcIXkJ5yK6VfYormJS3Jw==",
|
"integrity": "sha512-kq/BMeaAVLJM6Pynh8C2rnr/drCK+/5ksH0ch9asz+8FW3DscYCIEFtCeYTFeIx/ubvOsMXmRfy7qEJ76gM96A==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/prop-types": "*",
|
"@types/prop-types": "*",
|
||||||
"@types/scheduler": "*",
|
"@types/scheduler": "*",
|
||||||
@@ -23685,9 +23731,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@types/react-dom": {
|
"@types/react-dom": {
|
||||||
"version": "17.0.3",
|
"version": "17.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.9.tgz",
|
||||||
"integrity": "sha512-4NnJbCeWE+8YBzupn/YrJxZ8VnjcJq5iR1laqQ1vkpQgBiA7bwk0Rp24fxsdNinzJY2U+HHS4dJJDPdoMjdJ7w==",
|
"integrity": "sha512-wIvGxLfgpVDSAMH5utdL9Ngm5Owu0VsGmldro3ORLXV8CShrL8awVj06NuEXFQ5xyaYfdca7Sgbk/50Ri1GdPg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/react": "*"
|
"@types/react": "*"
|
||||||
}
|
}
|
||||||
@@ -25105,6 +25151,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
|
||||||
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA=="
|
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA=="
|
||||||
},
|
},
|
||||||
|
"bindings": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"file-uri-to-path": "1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"bluebird": {
|
"bluebird": {
|
||||||
"version": "3.7.2",
|
"version": "3.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
|
||||||
@@ -25476,9 +25531,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"normalize-url": {
|
"normalize-url": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz",
|
||||||
"integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
|
"integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28464,6 +28519,12 @@
|
|||||||
"tslib": "^2.0.3"
|
"tslib": "^2.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"file-uri-to-path": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"filesize": {
|
"filesize": {
|
||||||
"version": "6.1.0",
|
"version": "6.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz",
|
||||||
@@ -28843,6 +28904,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
||||||
},
|
},
|
||||||
|
"fsevents": {
|
||||||
|
"version": "2.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||||
|
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"function-bind": {
|
"function-bind": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||||
@@ -32383,6 +32450,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz",
|
||||||
"integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE="
|
"integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE="
|
||||||
},
|
},
|
||||||
|
"nan": {
|
||||||
|
"version": "2.15.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz",
|
||||||
|
"integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"nanoid": {
|
"nanoid": {
|
||||||
"version": "3.1.23",
|
"version": "3.1.23",
|
||||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz",
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz",
|
||||||
@@ -33197,9 +33270,9 @@
|
|||||||
"integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
|
"integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
|
||||||
},
|
},
|
||||||
"path-parse": {
|
"path-parse": {
|
||||||
"version": "1.0.6",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||||
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
|
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
|
||||||
},
|
},
|
||||||
"path-to-regexp": {
|
"path-to-regexp": {
|
||||||
"version": "0.1.7",
|
"version": "0.1.7",
|
||||||
@@ -33389,9 +33462,9 @@
|
|||||||
"integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs="
|
"integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs="
|
||||||
},
|
},
|
||||||
"postcss": {
|
"postcss": {
|
||||||
"version": "7.0.35",
|
"version": "7.0.36",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
|
||||||
"integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
|
"integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"chalk": "^2.4.2",
|
"chalk": "^2.4.2",
|
||||||
"source-map": "^0.6.1",
|
"source-map": "^0.6.1",
|
||||||
@@ -35421,9 +35494,9 @@
|
|||||||
"integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo="
|
"integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo="
|
||||||
},
|
},
|
||||||
"resolve-url-loader": {
|
"resolve-url-loader": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.4.tgz",
|
||||||
"integrity": "sha512-WbDSNFiKPPLem1ln+EVTE+bFUBdTTytfQZWbmghroaFNFaAVmGq0Saqw6F/306CwgPXsGwXVxbODE+3xAo/YbA==",
|
"integrity": "sha512-D3sQ04o0eeQEySLrcz4DsX3saHfsr8/N6tfhblxgZKXxMT2Louargg12oGNfoTRLV09GXhVUe5/qgA5vdgNigg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"adjust-sourcemap-loader": "3.0.0",
|
"adjust-sourcemap-loader": "3.0.0",
|
||||||
"camelcase": "5.3.1",
|
"camelcase": "5.3.1",
|
||||||
@@ -35431,7 +35504,7 @@
|
|||||||
"convert-source-map": "1.7.0",
|
"convert-source-map": "1.7.0",
|
||||||
"es6-iterator": "2.0.3",
|
"es6-iterator": "2.0.3",
|
||||||
"loader-utils": "1.2.3",
|
"loader-utils": "1.2.3",
|
||||||
"postcss": "7.0.21",
|
"postcss": "7.0.36",
|
||||||
"rework": "1.0.1",
|
"rework": "1.0.1",
|
||||||
"rework-visit": "1.0.0",
|
"rework-visit": "1.0.0",
|
||||||
"source-map": "0.6.1"
|
"source-map": "0.6.1"
|
||||||
@@ -35465,28 +35538,10 @@
|
|||||||
"json5": "^1.0.1"
|
"json5": "^1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"postcss": {
|
|
||||||
"version": "7.0.21",
|
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.21.tgz",
|
|
||||||
"integrity": "sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ==",
|
|
||||||
"requires": {
|
|
||||||
"chalk": "^2.4.2",
|
|
||||||
"source-map": "^0.6.1",
|
|
||||||
"supports-color": "^6.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"source-map": {
|
"source-map": {
|
||||||
"version": "0.6.1",
|
"version": "0.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
|
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
|
||||||
},
|
|
||||||
"supports-color": {
|
|
||||||
"version": "6.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
|
|
||||||
"integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
|
|
||||||
"requires": {
|
|
||||||
"has-flag": "^3.0.0"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -36905,9 +36960,9 @@
|
|||||||
"integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA=="
|
"integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA=="
|
||||||
},
|
},
|
||||||
"tar": {
|
"tar": {
|
||||||
"version": "6.1.0",
|
"version": "6.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
|
||||||
"integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==",
|
"integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"chownr": "^2.0.0",
|
"chownr": "^2.0.0",
|
||||||
"fs-minipass": "^2.0.0",
|
"fs-minipass": "^2.0.0",
|
||||||
@@ -37376,9 +37431,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"typescript": {
|
"typescript": {
|
||||||
"version": "4.2.4",
|
"version": "4.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz",
|
||||||
"integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg=="
|
"integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA=="
|
||||||
},
|
},
|
||||||
"unbox-primitive": {
|
"unbox-primitive": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
@@ -37647,9 +37702,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"url-parse": {
|
"url-parse": {
|
||||||
"version": "1.5.1",
|
"version": "1.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz",
|
||||||
"integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==",
|
"integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"querystringify": "^2.1.1",
|
"querystringify": "^2.1.1",
|
||||||
"requires-port": "^1.0.0"
|
"requires-port": "^1.0.0"
|
||||||
@@ -38299,6 +38354,16 @@
|
|||||||
"locate-path": "^3.0.0"
|
"locate-path": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"fsevents": {
|
||||||
|
"version": "1.2.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
|
||||||
|
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"bindings": "^1.5.0",
|
||||||
|
"nan": "^2.12.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"glob-parent": {
|
"glob-parent": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@material-ui/core": "^4.11.4",
|
"@material-ui/core": "^4.12.3",
|
||||||
"@material-ui/icons": "^4.11.2",
|
"@material-ui/icons": "^4.11.2",
|
||||||
"@msgpack/msgpack": "^2.7.0",
|
"@msgpack/msgpack": "^2.7.0",
|
||||||
"@types/lodash": "^4.14.168",
|
"@types/lodash": "^4.14.172",
|
||||||
"@types/node": "^15.0.1",
|
"@types/node": "^12.20.20",
|
||||||
"@types/react": "^17.0.4",
|
"@types/react": "^17.0.19",
|
||||||
"@types/react-dom": "^17.0.3",
|
"@types/react-dom": "^17.0.9",
|
||||||
"@types/react-material-ui-form-validator": "^2.1.0",
|
"@types/react-material-ui-form-validator": "^2.1.0",
|
||||||
"@types/react-router": "^5.1.13",
|
"@types/react-router": "^5.1.13",
|
||||||
"@types/react-router-dom": "^5.1.7",
|
"@types/react-router-dom": "^5.1.7",
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
"react-scripts": "4.0.3",
|
"react-scripts": "4.0.3",
|
||||||
"sockette": "^2.0.6",
|
"sockette": "^2.0.6",
|
||||||
"typescript": "4.2.4",
|
"typescript": "4.3.5",
|
||||||
"zlib": "^1.0.5"
|
"zlib": "^1.0.5"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ import { Component } from 'react';
|
|||||||
import { CssBaseline } from '@material-ui/core';
|
import { CssBaseline } from '@material-ui/core';
|
||||||
import {
|
import {
|
||||||
MuiThemeProvider,
|
MuiThemeProvider,
|
||||||
createMuiTheme,
|
createTheme,
|
||||||
StylesProvider
|
StylesProvider
|
||||||
} from '@material-ui/core/styles';
|
} from '@material-ui/core/styles';
|
||||||
import { blueGrey, orange, red, green } from '@material-ui/core/colors';
|
import { blueGrey, orange, red, green } from '@material-ui/core/colors';
|
||||||
|
|
||||||
const theme = createMuiTheme({
|
const theme = createTheme({
|
||||||
palette: {
|
palette: {
|
||||||
type: 'dark',
|
type: 'dark',
|
||||||
primary: {
|
primary: {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ export const PROJECT_PATH = process.env.REACT_APP_PROJECT_PATH!;
|
|||||||
export const ENDPOINT_ROOT = calculateEndpointRoot('/rest/');
|
export const ENDPOINT_ROOT = calculateEndpointRoot('/rest/');
|
||||||
export const WEB_SOCKET_ROOT = calculateWebSocketRoot('/ws/');
|
export const WEB_SOCKET_ROOT = calculateWebSocketRoot('/ws/');
|
||||||
export const EVENT_SOURCE_ROOT = calculateEndpointRoot('/es/');
|
export const EVENT_SOURCE_ROOT = calculateEndpointRoot('/es/');
|
||||||
|
export const API_ENDPOINT_ROOT = calculateEndpointRoot('/api/');
|
||||||
|
|
||||||
function calculateEndpointRoot(endpointPath: string) {
|
function calculateEndpointRoot(endpointPath: string) {
|
||||||
const httpRoot = process.env.REACT_APP_HTTP_ROOT;
|
const httpRoot = process.env.REACT_APP_HTTP_ROOT;
|
||||||
|
|||||||
@@ -22,25 +22,13 @@ interface UnauthenticatedRouteProps
|
|||||||
| React.ComponentType<any>;
|
| React.ComponentType<any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
type RenderComponent = (props: RouteComponentProps<any>) => React.ReactNode;
|
|
||||||
|
|
||||||
class UnauthenticatedRoute extends Route<UnauthenticatedRouteProps> {
|
class UnauthenticatedRoute extends Route<UnauthenticatedRouteProps> {
|
||||||
public render() {
|
public render() {
|
||||||
const {
|
const { authenticationContext, features, ...rest } = this.props;
|
||||||
authenticationContext,
|
|
||||||
component: Component,
|
|
||||||
features,
|
|
||||||
...rest
|
|
||||||
} = this.props;
|
|
||||||
const renderComponent: RenderComponent = (props) => {
|
|
||||||
if (authenticationContext.me) {
|
if (authenticationContext.me) {
|
||||||
return <Redirect to={Authentication.fetchLoginRedirect(features)} />;
|
return <Redirect to={Authentication.fetchLoginRedirect(features)} />;
|
||||||
}
|
}
|
||||||
if (Component) {
|
return <Route {...rest} />;
|
||||||
return <Component {...props} />;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return <Route {...rest} render={renderComponent} />;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
56
interface/src/components/FormLoader.tsx
Normal file
56
interface/src/components/FormLoader.tsx
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
|
||||||
|
import { makeStyles, Theme, createStyles } from '@material-ui/core/styles';
|
||||||
|
import { Button, LinearProgress, Typography } from '@material-ui/core';
|
||||||
|
|
||||||
|
const useStyles = makeStyles((theme: Theme) =>
|
||||||
|
createStyles({
|
||||||
|
loadingSettings: {
|
||||||
|
margin: theme.spacing(0.5)
|
||||||
|
},
|
||||||
|
loadingSettingsDetails: {
|
||||||
|
margin: theme.spacing(4),
|
||||||
|
textAlign: 'center'
|
||||||
|
},
|
||||||
|
button: {
|
||||||
|
marginRight: theme.spacing(2),
|
||||||
|
marginTop: theme.spacing(2)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
interface FormLoaderProps {
|
||||||
|
errorMessage?: string;
|
||||||
|
loadData: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FormLoader: FC<FormLoaderProps> = ({ errorMessage, loadData }) => {
|
||||||
|
const classes = useStyles();
|
||||||
|
if (errorMessage) {
|
||||||
|
return (
|
||||||
|
<div className={classes.loadingSettings}>
|
||||||
|
<Typography variant="h6" className={classes.loadingSettingsDetails}>
|
||||||
|
{errorMessage}
|
||||||
|
</Typography>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
className={classes.button}
|
||||||
|
onClick={loadData}
|
||||||
|
>
|
||||||
|
Retry
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div className={classes.loadingSettings}>
|
||||||
|
<LinearProgress className={classes.loadingSettingsDetails} />
|
||||||
|
<Typography variant="h6" className={classes.loadingSettingsDetails}>
|
||||||
|
Loading…
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FormLoader;
|
||||||
@@ -5,6 +5,7 @@ export { default as HighlightAvatar } from './HighlightAvatar';
|
|||||||
export { default as MenuAppBar } from './MenuAppBar';
|
export { default as MenuAppBar } from './MenuAppBar';
|
||||||
export { default as PasswordValidator } from './PasswordValidator';
|
export { default as PasswordValidator } from './PasswordValidator';
|
||||||
export { default as RestFormLoader } from './RestFormLoader';
|
export { default as RestFormLoader } from './RestFormLoader';
|
||||||
|
export { default as FormLoader } from './FormLoader';
|
||||||
export { default as SectionContent } from './SectionContent';
|
export { default as SectionContent } from './SectionContent';
|
||||||
export { default as WebSocketFormLoader } from './WebSocketFormLoader';
|
export { default as WebSocketFormLoader } from './WebSocketFormLoader';
|
||||||
export { default as ErrorButton } from './ErrorButton';
|
export { default as ErrorButton } from './ErrorButton';
|
||||||
|
|||||||
@@ -1,58 +1,31 @@
|
|||||||
import { Component } from 'react';
|
import { FC } from 'react';
|
||||||
|
|
||||||
import { Features } from './types';
|
|
||||||
import { FeaturesContext } from './FeaturesContext';
|
|
||||||
import FullScreenLoading from '../components/FullScreenLoading';
|
import FullScreenLoading from '../components/FullScreenLoading';
|
||||||
import ApplicationError from '../components/ApplicationError';
|
import ApplicationError from '../components/ApplicationError';
|
||||||
import { FEATURES_ENDPOINT } from '../api';
|
import { FEATURES_ENDPOINT } from '../api';
|
||||||
|
import { useRest } from '../hooks';
|
||||||
|
|
||||||
interface FeaturesWrapperState {
|
import { Features } from './types';
|
||||||
features?: Features;
|
import { FeaturesContext } from './FeaturesContext';
|
||||||
error?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
class FeaturesWrapper extends Component<{}, FeaturesWrapperState> {
|
const FeaturesWrapper: FC = ({ children }) => {
|
||||||
state: FeaturesWrapperState = {};
|
const { data: features, errorMessage: error } = useRest<Features>({
|
||||||
|
endpoint: FEATURES_ENDPOINT
|
||||||
componentDidMount() {
|
|
||||||
this.fetchFeaturesDetails();
|
|
||||||
}
|
|
||||||
|
|
||||||
fetchFeaturesDetails = () => {
|
|
||||||
fetch(FEATURES_ENDPOINT)
|
|
||||||
.then((response) => {
|
|
||||||
if (response.status === 200) {
|
|
||||||
return response.json();
|
|
||||||
} else {
|
|
||||||
throw Error('Unexpected status code: ' + response.status);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then((features) => {
|
|
||||||
this.setState({ features });
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
this.setState({ error: error.message });
|
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { features, error } = this.state;
|
|
||||||
if (features) {
|
if (features) {
|
||||||
return (
|
return (
|
||||||
<FeaturesContext.Provider
|
<FeaturesContext.Provider value={{ features }}>
|
||||||
value={{
|
{children}
|
||||||
features
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{this.props.children}
|
|
||||||
</FeaturesContext.Provider>
|
</FeaturesContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
return <ApplicationError error={error} />;
|
return <ApplicationError error={error} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <FullScreenLoading />;
|
return <FullScreenLoading />;
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|
||||||
export default FeaturesWrapper;
|
export default FeaturesWrapper;
|
||||||
|
|||||||
2
interface/src/hooks/index.ts
Normal file
2
interface/src/hooks/index.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export { default as useRest } from './useRest';
|
||||||
|
export { default as useAuthorizedRest } from './useAuthorizedRest';
|
||||||
12
interface/src/hooks/useAuthorizedRest.ts
Normal file
12
interface/src/hooks/useAuthorizedRest.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { redirectingAuthorizedFetch } from '../authentication';
|
||||||
|
import useRest, { RestRequestOptions } from './useRest';
|
||||||
|
|
||||||
|
const useAuthorizedRest = <D>({
|
||||||
|
endpoint
|
||||||
|
}: Omit<RestRequestOptions, 'fetchFunction'>) =>
|
||||||
|
useRest<D>({
|
||||||
|
endpoint,
|
||||||
|
fetchFunction: redirectingAuthorizedFetch
|
||||||
|
});
|
||||||
|
|
||||||
|
export default useAuthorizedRest;
|
||||||
79
interface/src/hooks/useRest.ts
Normal file
79
interface/src/hooks/useRest.ts
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
|
import { useSnackbar } from 'notistack';
|
||||||
|
|
||||||
|
export interface RestRequestOptions {
|
||||||
|
endpoint: string;
|
||||||
|
fetchFunction?: typeof fetch;
|
||||||
|
}
|
||||||
|
|
||||||
|
const useRest = <D>({
|
||||||
|
endpoint,
|
||||||
|
fetchFunction = fetch
|
||||||
|
}: RestRequestOptions) => {
|
||||||
|
const { enqueueSnackbar } = useSnackbar();
|
||||||
|
|
||||||
|
const [saving, setSaving] = useState<boolean>(false);
|
||||||
|
const [data, setData] = useState<D>();
|
||||||
|
const [errorMessage, setErrorMessage] = useState<string>();
|
||||||
|
|
||||||
|
const handleError = useCallback(
|
||||||
|
(error: any) => {
|
||||||
|
const errorMessage = error.message || 'Unknown error';
|
||||||
|
enqueueSnackbar('Problem fetching: ' + errorMessage, {
|
||||||
|
variant: 'error'
|
||||||
|
});
|
||||||
|
setErrorMessage(errorMessage);
|
||||||
|
},
|
||||||
|
[enqueueSnackbar]
|
||||||
|
);
|
||||||
|
|
||||||
|
const loadData = useCallback(async () => {
|
||||||
|
setData(undefined);
|
||||||
|
setErrorMessage(undefined);
|
||||||
|
try {
|
||||||
|
const response = await fetchFunction(endpoint);
|
||||||
|
if (response.status !== 200) {
|
||||||
|
throw Error('Invalid status code: ' + response.status);
|
||||||
|
}
|
||||||
|
setData(await response.json());
|
||||||
|
} catch (error) {
|
||||||
|
handleError(error);
|
||||||
|
}
|
||||||
|
}, [handleError, fetchFunction, endpoint]);
|
||||||
|
|
||||||
|
const save = useCallback(
|
||||||
|
async (data: D) => {
|
||||||
|
setSaving(true);
|
||||||
|
setErrorMessage(undefined);
|
||||||
|
try {
|
||||||
|
const response = await fetchFunction(endpoint, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (response.status !== 200) {
|
||||||
|
throw Error('Invalid status code: ' + response.status);
|
||||||
|
}
|
||||||
|
enqueueSnackbar('Update successful.', { variant: 'success' });
|
||||||
|
setData(await response.json());
|
||||||
|
} catch (error) {
|
||||||
|
handleError(error);
|
||||||
|
} finally {
|
||||||
|
setSaving(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[enqueueSnackbar, handleError, fetchFunction, endpoint]
|
||||||
|
);
|
||||||
|
|
||||||
|
const saveData = () => data && save(data);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadData();
|
||||||
|
}, [loadData]);
|
||||||
|
|
||||||
|
return { loadData, saveData, saving, setData, data, errorMessage } as const;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useRest;
|
||||||
@@ -109,7 +109,7 @@ class MqttSettingsForm extends React.Component<MqttSettingsFormProps> {
|
|||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
name="client_id"
|
name="client_id"
|
||||||
label="Client ID (optional)"
|
label="Client ID"
|
||||||
fullWidth
|
fullWidth
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
value={data.client_id}
|
value={data.client_id}
|
||||||
@@ -159,7 +159,7 @@ class MqttSettingsForm extends React.Component<MqttSettingsFormProps> {
|
|||||||
value="clean_session"
|
value="clean_session"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
label="Clean Session"
|
label="Set Clean Session"
|
||||||
/>
|
/>
|
||||||
<BlockFormControlLabel
|
<BlockFormControlLabel
|
||||||
control={
|
control={
|
||||||
@@ -169,7 +169,7 @@ class MqttSettingsForm extends React.Component<MqttSettingsFormProps> {
|
|||||||
value="mqtt_retain"
|
value="mqtt_retain"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
label="Retain Flag"
|
label="Use Retain Flag"
|
||||||
/>
|
/>
|
||||||
<br></br>
|
<br></br>
|
||||||
<Typography variant="h6" color="primary">
|
<Typography variant="h6" color="primary">
|
||||||
@@ -184,48 +184,19 @@ class MqttSettingsForm extends React.Component<MqttSettingsFormProps> {
|
|||||||
onChange={handleValueChange('nested_format')}
|
onChange={handleValueChange('nested_format')}
|
||||||
margin="normal"
|
margin="normal"
|
||||||
>
|
>
|
||||||
<MenuItem value={1}>nested on a single topic</MenuItem>
|
<MenuItem value={1}>Nested on a single topic</MenuItem>
|
||||||
<MenuItem value={2}>as individual topics</MenuItem>
|
<MenuItem value={2}>As individual topics</MenuItem>
|
||||||
</SelectValidator>
|
|
||||||
<SelectValidator
|
|
||||||
name="dallas_format"
|
|
||||||
label="Dallas Sensor Payload Grouping"
|
|
||||||
value={data.dallas_format}
|
|
||||||
fullWidth
|
|
||||||
variant="outlined"
|
|
||||||
onChange={handleValueChange('dallas_format')}
|
|
||||||
margin="normal"
|
|
||||||
>
|
|
||||||
<MenuItem value={1}>by Sensor ID</MenuItem>
|
|
||||||
<MenuItem value={2}>by Number</MenuItem>
|
|
||||||
</SelectValidator>
|
|
||||||
<SelectValidator
|
|
||||||
name="bool_format"
|
|
||||||
label="Boolean Format"
|
|
||||||
value={data.bool_format}
|
|
||||||
fullWidth
|
|
||||||
variant="outlined"
|
|
||||||
onChange={handleValueChange('bool_format')}
|
|
||||||
margin="normal"
|
|
||||||
>
|
|
||||||
<MenuItem value={1}>"on"/"off"</MenuItem>
|
|
||||||
<MenuItem value={2}>true/false</MenuItem>
|
|
||||||
<MenuItem value={3}>1/0</MenuItem>
|
|
||||||
<MenuItem value={4}>"ON"/"OFF"</MenuItem>
|
|
||||||
</SelectValidator>
|
|
||||||
<SelectValidator
|
|
||||||
name="subscribe_format"
|
|
||||||
label="Subscribe Format"
|
|
||||||
value={data.subscribe_format}
|
|
||||||
fullWidth
|
|
||||||
variant="outlined"
|
|
||||||
onChange={handleValueChange('subscribe_format')}
|
|
||||||
margin="normal"
|
|
||||||
>
|
|
||||||
<MenuItem value={0}>general device topic</MenuItem>
|
|
||||||
<MenuItem value={1}>individual topics, main heating circuit</MenuItem>
|
|
||||||
<MenuItem value={2}>individual topics, all heating circuits</MenuItem>
|
|
||||||
</SelectValidator>
|
</SelectValidator>
|
||||||
|
<BlockFormControlLabel
|
||||||
|
control={
|
||||||
|
<Checkbox
|
||||||
|
checked={data.send_response}
|
||||||
|
onChange={handleValueChange('send_response')}
|
||||||
|
value="send_response"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label="Publish command output to a 'response' topic"
|
||||||
|
/>
|
||||||
<BlockFormControlLabel
|
<BlockFormControlLabel
|
||||||
control={
|
control={
|
||||||
<Checkbox
|
<Checkbox
|
||||||
@@ -246,9 +217,9 @@ class MqttSettingsForm extends React.Component<MqttSettingsFormProps> {
|
|||||||
onChange={handleValueChange('ha_climate_format')}
|
onChange={handleValueChange('ha_climate_format')}
|
||||||
margin="normal"
|
margin="normal"
|
||||||
>
|
>
|
||||||
<MenuItem value={1}>use Current temperature (default)</MenuItem>
|
<MenuItem value={1}>Use Current temperature</MenuItem>
|
||||||
<MenuItem value={2}>use Setpoint temperature</MenuItem>
|
<MenuItem value={2}>Use Setpoint temperature</MenuItem>
|
||||||
<MenuItem value={3}>Fix to 0</MenuItem>
|
<MenuItem value={3}>Always set to 0</MenuItem>
|
||||||
</SelectValidator>
|
</SelectValidator>
|
||||||
)}
|
)}
|
||||||
<br></br>
|
<br></br>
|
||||||
|
|||||||
@@ -34,12 +34,10 @@ export interface MqttSettings {
|
|||||||
publish_time_mixer: number;
|
publish_time_mixer: number;
|
||||||
publish_time_other: number;
|
publish_time_other: number;
|
||||||
publish_time_sensor: number;
|
publish_time_sensor: number;
|
||||||
dallas_format: number;
|
|
||||||
bool_format: number;
|
|
||||||
mqtt_qos: number;
|
mqtt_qos: number;
|
||||||
mqtt_retain: boolean;
|
mqtt_retain: boolean;
|
||||||
ha_enabled: boolean;
|
ha_enabled: boolean;
|
||||||
ha_climate_format: number;
|
ha_climate_format: number;
|
||||||
nested_format: number;
|
nested_format: number;
|
||||||
subscribe_format: number;
|
send_response: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,11 @@ class NetworkSettingsForm extends React.Component<NetworkStatusFormProps> {
|
|||||||
ssid: selectedNetwork.ssid,
|
ssid: selectedNetwork.ssid,
|
||||||
password: '',
|
password: '',
|
||||||
hostname: props.data.hostname,
|
hostname: props.data.hostname,
|
||||||
static_ip_config: false
|
static_ip_config: false,
|
||||||
|
enableIPv6: false,
|
||||||
|
bandwidth20: false,
|
||||||
|
tx_power: 20,
|
||||||
|
nosleep: false
|
||||||
};
|
};
|
||||||
props.setData(networkSettings);
|
props.setData(networkSettings);
|
||||||
}
|
}
|
||||||
@@ -145,6 +149,53 @@ class NetworkSettingsForm extends React.Component<NetworkStatusFormProps> {
|
|||||||
onChange={handleValueChange('hostname')}
|
onChange={handleValueChange('hostname')}
|
||||||
margin="normal"
|
margin="normal"
|
||||||
/>
|
/>
|
||||||
|
<TextValidator
|
||||||
|
validators={['required', 'isNumber', 'minNumber:0', 'maxNumber:20']}
|
||||||
|
errorMessages={[
|
||||||
|
'Tx Power is required',
|
||||||
|
'Must be a number',
|
||||||
|
'Must be greater than 0dBm ',
|
||||||
|
'Max value is 20dBm'
|
||||||
|
]}
|
||||||
|
name="tx_power"
|
||||||
|
label="WiFi Tx Power (dBm)"
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
value={data.tx_power}
|
||||||
|
type="number"
|
||||||
|
onChange={handleValueChange('tx_power')}
|
||||||
|
margin="normal"
|
||||||
|
/>
|
||||||
|
<BlockFormControlLabel
|
||||||
|
control={
|
||||||
|
<Checkbox
|
||||||
|
value="enableIPv6"
|
||||||
|
checked={data.enableIPv6}
|
||||||
|
onChange={handleValueChange('enableIPv6')}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label="Enable IPv6 support"
|
||||||
|
/>
|
||||||
|
<BlockFormControlLabel
|
||||||
|
control={
|
||||||
|
<Checkbox
|
||||||
|
value="bandwidth20"
|
||||||
|
checked={data.bandwidth20}
|
||||||
|
onChange={handleValueChange('bandwidth20')}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label="Use Lower WiFi Bandwidth"
|
||||||
|
/>
|
||||||
|
<BlockFormControlLabel
|
||||||
|
control={
|
||||||
|
<Checkbox
|
||||||
|
value="nosleep"
|
||||||
|
checked={data.nosleep}
|
||||||
|
onChange={handleValueChange('nosleep')}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label="Disable WiFi Sleep Mode"
|
||||||
|
/>
|
||||||
<BlockFormControlLabel
|
<BlockFormControlLabel
|
||||||
control={
|
control={
|
||||||
<Checkbox
|
<Checkbox
|
||||||
@@ -153,7 +204,7 @@ class NetworkSettingsForm extends React.Component<NetworkStatusFormProps> {
|
|||||||
onChange={handleValueChange('static_ip_config')}
|
onChange={handleValueChange('static_ip_config')}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
label="Static IP Config"
|
label="Use Static IPs"
|
||||||
/>
|
/>
|
||||||
{data.static_ip_config && (
|
{data.static_ip_config && (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
|
|||||||
@@ -40,7 +40,22 @@ class NetworkStatusForm extends Component<NetworkStatusFormProps> {
|
|||||||
if (!status.dns_ip_1) {
|
if (!status.dns_ip_1) {
|
||||||
return 'none';
|
return 'none';
|
||||||
}
|
}
|
||||||
return status.dns_ip_1 + (status.dns_ip_2 ? ',' + status.dns_ip_2 : '');
|
if (!status.dns_ip_2 || status.dns_ip_2 === '0.0.0.0') {
|
||||||
|
return status.dns_ip_1;
|
||||||
|
}
|
||||||
|
return status.dns_ip_1 + ', ' + status.dns_ip_2;
|
||||||
|
}
|
||||||
|
IPs(status: NetworkStatus) {
|
||||||
|
if (
|
||||||
|
!status.local_ipv6 ||
|
||||||
|
status.local_ipv6 === '0000:0000:0000:0000:0000:0000:0000:0000'
|
||||||
|
) {
|
||||||
|
return status.local_ip;
|
||||||
|
}
|
||||||
|
if (!status.local_ip || status.local_ip === '0.0.0.0') {
|
||||||
|
return status.local_ipv6;
|
||||||
|
}
|
||||||
|
return status.local_ip + ', ' + status.local_ipv6;
|
||||||
}
|
}
|
||||||
|
|
||||||
createListItems() {
|
createListItems() {
|
||||||
@@ -77,7 +92,7 @@ class NetworkStatusForm extends Component<NetworkStatusFormProps> {
|
|||||||
<ListItemAvatar>
|
<ListItemAvatar>
|
||||||
<Avatar>IP</Avatar>
|
<Avatar>IP</Avatar>
|
||||||
</ListItemAvatar>
|
</ListItemAvatar>
|
||||||
<ListItemText primary="IP Address" secondary={data.local_ip} />
|
<ListItemText primary="IP Address" secondary={this.IPs(data)} />
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<Divider variant="inset" component="li" />
|
<Divider variant="inset" component="li" />
|
||||||
<ListItem>
|
<ListItem>
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ export enum WiFiEncryptionType {
|
|||||||
export interface NetworkStatus {
|
export interface NetworkStatus {
|
||||||
status: NetworkConnectionStatus;
|
status: NetworkConnectionStatus;
|
||||||
local_ip: string;
|
local_ip: string;
|
||||||
|
local_ipv6: string;
|
||||||
mac_address: string;
|
mac_address: string;
|
||||||
rssi: number;
|
rssi: number;
|
||||||
ssid: string;
|
ssid: string;
|
||||||
@@ -37,6 +38,10 @@ export interface NetworkSettings {
|
|||||||
password: string;
|
password: string;
|
||||||
hostname: string;
|
hostname: string;
|
||||||
static_ip_config: boolean;
|
static_ip_config: boolean;
|
||||||
|
enableIPv6: boolean;
|
||||||
|
bandwidth20: boolean;
|
||||||
|
nosleep: boolean;
|
||||||
|
tx_power: number;
|
||||||
local_ip?: string;
|
local_ip?: string;
|
||||||
gateway_ip?: string;
|
gateway_ip?: string;
|
||||||
subnet_mask?: string;
|
subnet_mask?: string;
|
||||||
|
|||||||
@@ -10,9 +10,7 @@ export const BOARD_PROFILES: BoardProfiles = {
|
|||||||
NODEMCU: 'NodeMCU 32S',
|
NODEMCU: 'NodeMCU 32S',
|
||||||
'MH-ET': 'MH-ET Live D1 Mini',
|
'MH-ET': 'MH-ET Live D1 Mini',
|
||||||
LOLIN: 'Lolin D32',
|
LOLIN: 'Lolin D32',
|
||||||
OLIMEX: 'Olimex ESP32-EVB',
|
OLIMEX: 'Olimex ESP32-EVB'
|
||||||
TLK110: 'Generic Ethernet (TLK110)',
|
|
||||||
LAN8720: 'Generic Ethernet (LAN8720)'
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export function boardProfileSelectItems() {
|
export function boardProfileSelectItems() {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { MenuAppBar } from '../components';
|
|||||||
import { AuthenticatedRoute } from '../authentication';
|
import { AuthenticatedRoute } from '../authentication';
|
||||||
|
|
||||||
import EMSESPStatusController from './EMSESPStatusController';
|
import EMSESPStatusController from './EMSESPStatusController';
|
||||||
import EMSESPDevicesController from './EMSESPDevicesController';
|
import EMSESPDataController from './EMSESPDataController';
|
||||||
import EMSESPHelp from './EMSESPHelp';
|
import EMSESPHelp from './EMSESPHelp';
|
||||||
|
|
||||||
class EMSESP extends Component<RouteComponentProps> {
|
class EMSESP extends Component<RouteComponentProps> {
|
||||||
@@ -24,18 +24,15 @@ class EMSESP extends Component<RouteComponentProps> {
|
|||||||
onChange={(e, path) => this.handleTabChange(path)}
|
onChange={(e, path) => this.handleTabChange(path)}
|
||||||
variant="fullWidth"
|
variant="fullWidth"
|
||||||
>
|
>
|
||||||
<Tab
|
<Tab value={`/${PROJECT_PATH}/data`} label="Devices & Sensors" />
|
||||||
value={`/${PROJECT_PATH}/devices`}
|
|
||||||
label="Devices & Sensors"
|
|
||||||
/>
|
|
||||||
<Tab value={`/${PROJECT_PATH}/status`} label="EMS Status" />
|
<Tab value={`/${PROJECT_PATH}/status`} label="EMS Status" />
|
||||||
<Tab value={`/${PROJECT_PATH}/help`} label="EMS-ESP Help" />
|
<Tab value={`/${PROJECT_PATH}/help`} label="EMS-ESP Help" />
|
||||||
</Tabs>
|
</Tabs>
|
||||||
<Switch>
|
<Switch>
|
||||||
<AuthenticatedRoute
|
<AuthenticatedRoute
|
||||||
exact
|
exact
|
||||||
path={`/${PROJECT_PATH}/devices`}
|
path={`/${PROJECT_PATH}/data`}
|
||||||
component={EMSESPDevicesController}
|
component={EMSESPDataController}
|
||||||
/>
|
/>
|
||||||
<AuthenticatedRoute
|
<AuthenticatedRoute
|
||||||
exact
|
exact
|
||||||
@@ -47,7 +44,7 @@ class EMSESP extends Component<RouteComponentProps> {
|
|||||||
path={`/${PROJECT_PATH}/help`}
|
path={`/${PROJECT_PATH}/help`}
|
||||||
component={EMSESPHelp}
|
component={EMSESPHelp}
|
||||||
/>
|
/>
|
||||||
<Redirect to={`/${PROJECT_PATH}/devices`} />
|
<Redirect to={`/${PROJECT_PATH}/data`} />
|
||||||
</Switch>
|
</Switch>
|
||||||
</MenuAppBar>
|
</MenuAppBar>
|
||||||
);
|
);
|
||||||
|
|||||||
35
interface/src/project/EMSESPDataController.tsx
Normal file
35
interface/src/project/EMSESPDataController.tsx
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
|
import {
|
||||||
|
restController,
|
||||||
|
RestControllerProps,
|
||||||
|
RestFormLoader,
|
||||||
|
SectionContent
|
||||||
|
} from '../components';
|
||||||
|
|
||||||
|
import { ENDPOINT_ROOT } from '../api';
|
||||||
|
import EMSESPDataForm from './EMSESPDataForm';
|
||||||
|
import { EMSESPData } from './EMSESPtypes';
|
||||||
|
|
||||||
|
export const EMSESP_DATA_ENDPOINT = ENDPOINT_ROOT + 'data';
|
||||||
|
|
||||||
|
type EMSESPDataControllerProps = RestControllerProps<EMSESPData>;
|
||||||
|
|
||||||
|
class EMSESPDataController extends Component<EMSESPDataControllerProps> {
|
||||||
|
componentDidMount() {
|
||||||
|
this.props.loadData();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<SectionContent title="Devices & Sensors">
|
||||||
|
<RestFormLoader
|
||||||
|
{...this.props}
|
||||||
|
render={(formProps) => <EMSESPDataForm {...formProps} />}
|
||||||
|
/>
|
||||||
|
</SectionContent>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default restController(EMSESP_DATA_ENDPOINT, EMSESPDataController);
|
||||||
@@ -40,35 +40,51 @@ import {
|
|||||||
import { RestFormProps, FormButton, extractEventValue } from '../components';
|
import { RestFormProps, FormButton, extractEventValue } from '../components';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
EMSESPDevices,
|
EMSESPData,
|
||||||
EMSESPDeviceData,
|
EMSESPDeviceData,
|
||||||
Device,
|
Device,
|
||||||
DeviceValue,
|
DeviceValue,
|
||||||
DeviceValueUOM,
|
DeviceValueUOM,
|
||||||
DeviceValueUOM_s
|
DeviceValueUOM_s,
|
||||||
|
Sensor
|
||||||
} from './EMSESPtypes';
|
} from './EMSESPtypes';
|
||||||
|
|
||||||
import ValueForm from './ValueForm';
|
import ValueForm from './ValueForm';
|
||||||
|
import SensorForm from './SensorForm';
|
||||||
|
|
||||||
import { ENDPOINT_ROOT } from '../api';
|
import { ENDPOINT_ROOT } from '../api';
|
||||||
|
|
||||||
export const SCANDEVICES_ENDPOINT = ENDPOINT_ROOT + 'scanDevices';
|
export const SCANDEVICES_ENDPOINT = ENDPOINT_ROOT + 'scanDevices';
|
||||||
export const DEVICE_DATA_ENDPOINT = ENDPOINT_ROOT + 'deviceData';
|
export const DEVICE_DATA_ENDPOINT = ENDPOINT_ROOT + 'deviceData';
|
||||||
export const WRITE_VALUE_ENDPOINT = ENDPOINT_ROOT + 'writeValue';
|
export const WRITE_VALUE_ENDPOINT = ENDPOINT_ROOT + 'writeValue';
|
||||||
|
export const WRITE_SENSOR_ENDPOINT = ENDPOINT_ROOT + 'writeSensor';
|
||||||
|
|
||||||
const StyledTableCell = withStyles((theme: Theme) =>
|
const StyledTableRow = withStyles((theme: Theme) =>
|
||||||
createStyles({
|
createStyles({
|
||||||
head: {
|
root: {
|
||||||
backgroundColor: theme.palette.common.black,
|
'&:nth-child(even)': {
|
||||||
color: theme.palette.common.white
|
backgroundColor: '#4e4e4e'
|
||||||
},
|
},
|
||||||
body: {
|
'&:hover': {
|
||||||
fontSize: 14
|
backgroundColor: theme.palette.info.light
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
selected: {
|
||||||
|
backgroundColor: theme.palette.common.white
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
)(TableCell);
|
)(TableRow);
|
||||||
|
|
||||||
const CustomTooltip = withStyles((theme: Theme) => ({
|
const StyledTableRowHeader = withStyles((theme: Theme) =>
|
||||||
|
createStyles({
|
||||||
|
head: {
|
||||||
|
backgroundColor: theme.palette.common.black
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)(TableRow);
|
||||||
|
|
||||||
|
const StyledTooltip = withStyles((theme: Theme) => ({
|
||||||
tooltip: {
|
tooltip: {
|
||||||
backgroundColor: theme.palette.secondary.main,
|
backgroundColor: theme.palette.secondary.main,
|
||||||
color: 'white',
|
color: 'white',
|
||||||
@@ -79,27 +95,31 @@ const CustomTooltip = withStyles((theme: Theme) => ({
|
|||||||
}))(Tooltip);
|
}))(Tooltip);
|
||||||
|
|
||||||
function compareDevices(a: Device, b: Device) {
|
function compareDevices(a: Device, b: Device) {
|
||||||
if (a.type < b.type) {
|
if (a.t < b.t) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (a.type > b.type) {
|
if (a.t > b.t) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface EMSESPDevicesFormState {
|
interface EMSESPDataFormState {
|
||||||
confirmScanDevices: boolean;
|
confirmScanDevices: boolean;
|
||||||
processing: boolean;
|
processing: boolean;
|
||||||
deviceData?: EMSESPDeviceData;
|
deviceData?: EMSESPDeviceData;
|
||||||
selectedDevice?: number;
|
selectedDevice?: number;
|
||||||
edit_devicevalue?: DeviceValue;
|
edit_devicevalue?: DeviceValue;
|
||||||
|
edit_Sensor?: Sensor;
|
||||||
}
|
}
|
||||||
|
|
||||||
type EMSESPDevicesFormProps = RestFormProps<EMSESPDevices> &
|
type EMSESPDataFormProps = RestFormProps<EMSESPData> &
|
||||||
AuthenticatedContextProps &
|
AuthenticatedContextProps &
|
||||||
WithWidthProps;
|
WithWidthProps;
|
||||||
|
|
||||||
|
const pluralize = (count: number, noun: string, suffix = 's') =>
|
||||||
|
` ${Intl.NumberFormat().format(count)} ${noun}${count !== 1 ? suffix : ''} `;
|
||||||
|
|
||||||
export const formatDuration = (duration_min: number) => {
|
export const formatDuration = (duration_min: number) => {
|
||||||
const { days, hours, minutes } = parseMilliseconds(duration_min * 60000);
|
const { days, hours, minutes } = parseMilliseconds(duration_min * 60000);
|
||||||
let formatted = '';
|
let formatted = '';
|
||||||
@@ -115,9 +135,6 @@ export const formatDuration = (duration_min: number) => {
|
|||||||
return formatted;
|
return formatted;
|
||||||
};
|
};
|
||||||
|
|
||||||
const pluralize = (count: number, noun: string, suffix = 's') =>
|
|
||||||
` ${count} ${noun}${count !== 1 ? suffix : ''} `;
|
|
||||||
|
|
||||||
function formatValue(value: any, uom: number) {
|
function formatValue(value: any, uom: number) {
|
||||||
switch (uom) {
|
switch (uom) {
|
||||||
case DeviceValueUOM.HOURS:
|
case DeviceValueUOM.HOURS:
|
||||||
@@ -125,11 +142,22 @@ function formatValue(value: any, uom: number) {
|
|||||||
case DeviceValueUOM.MINUTES:
|
case DeviceValueUOM.MINUTES:
|
||||||
return value ? formatDuration(value) : '0 minutes';
|
return value ? formatDuration(value) : '0 minutes';
|
||||||
case DeviceValueUOM.NONE:
|
case DeviceValueUOM.NONE:
|
||||||
return value;
|
if (typeof value === 'number') {
|
||||||
case DeviceValueUOM.NUM:
|
|
||||||
return new Intl.NumberFormat().format(value);
|
return new Intl.NumberFormat().format(value);
|
||||||
case DeviceValueUOM.BOOLEAN:
|
}
|
||||||
return value ? 'on' : 'off';
|
return value;
|
||||||
|
case DeviceValueUOM.DEGREES:
|
||||||
|
// always show with one decimal place
|
||||||
|
return (
|
||||||
|
new Intl.NumberFormat(undefined, {
|
||||||
|
minimumFractionDigits: 1
|
||||||
|
}).format(value) +
|
||||||
|
' ' +
|
||||||
|
DeviceValueUOM_s[uom]
|
||||||
|
);
|
||||||
|
case DeviceValueUOM.TIMES:
|
||||||
|
case DeviceValueUOM.SECONDS:
|
||||||
|
return pluralize(value, DeviceValueUOM_s[uom]);
|
||||||
default:
|
default:
|
||||||
return (
|
return (
|
||||||
new Intl.NumberFormat().format(value) + ' ' + DeviceValueUOM_s[uom]
|
new Intl.NumberFormat().format(value) + ' ' + DeviceValueUOM_s[uom]
|
||||||
@@ -137,16 +165,16 @@ function formatValue(value: any, uom: number) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class EMSESPDevicesForm extends Component<
|
class EMSESPDataForm extends Component<
|
||||||
EMSESPDevicesFormProps,
|
EMSESPDataFormProps,
|
||||||
EMSESPDevicesFormState
|
EMSESPDataFormState
|
||||||
> {
|
> {
|
||||||
state: EMSESPDevicesFormState = {
|
state: EMSESPDataFormState = {
|
||||||
confirmScanDevices: false,
|
confirmScanDevices: false,
|
||||||
processing: false
|
processing: false
|
||||||
};
|
};
|
||||||
|
|
||||||
handleValueChange = (name: keyof DeviceValue) => (
|
handleDeviceValueChange = (name: keyof DeviceValue) => (
|
||||||
event: React.ChangeEvent<HTMLInputElement>
|
event: React.ChangeEvent<HTMLInputElement>
|
||||||
) => {
|
) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
@@ -157,11 +185,11 @@ class EMSESPDevicesForm extends Component<
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
cancelEditingValue = () => {
|
cancelEditingDeviceValue = () => {
|
||||||
this.setState({ edit_devicevalue: undefined });
|
this.setState({ edit_devicevalue: undefined });
|
||||||
};
|
};
|
||||||
|
|
||||||
doneEditingValue = () => {
|
doneEditingDeviceValue = () => {
|
||||||
const { edit_devicevalue, selectedDevice } = this.state;
|
const { edit_devicevalue, selectedDevice } = this.state;
|
||||||
|
|
||||||
redirectingAuthorizedFetch(WRITE_VALUE_ENDPOINT, {
|
redirectingAuthorizedFetch(WRITE_VALUE_ENDPOINT, {
|
||||||
@@ -179,6 +207,7 @@ class EMSESPDevicesForm extends Component<
|
|||||||
this.props.enqueueSnackbar('Write command sent to device', {
|
this.props.enqueueSnackbar('Write command sent to device', {
|
||||||
variant: 'success'
|
variant: 'success'
|
||||||
});
|
});
|
||||||
|
this.handleRowClick(selectedDevice);
|
||||||
} else if (response.status === 204) {
|
} else if (response.status === 204) {
|
||||||
this.props.enqueueSnackbar('Write command failed', {
|
this.props.enqueueSnackbar('Write command failed', {
|
||||||
variant: 'error'
|
variant: 'error'
|
||||||
@@ -203,7 +232,77 @@ class EMSESPDevicesForm extends Component<
|
|||||||
};
|
};
|
||||||
|
|
||||||
sendCommand = (dv: DeviceValue) => {
|
sendCommand = (dv: DeviceValue) => {
|
||||||
|
if (dv.c && this.props.authenticatedContext.me.admin) {
|
||||||
this.setState({ edit_devicevalue: dv });
|
this.setState({ edit_devicevalue: dv });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
handleSensorChange = (name: keyof Sensor) => (
|
||||||
|
event: React.ChangeEvent<HTMLInputElement>
|
||||||
|
) => {
|
||||||
|
this.setState({
|
||||||
|
edit_Sensor: {
|
||||||
|
...this.state.edit_Sensor!,
|
||||||
|
[name]: extractEventValue(event)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
cancelEditingSensor = () => {
|
||||||
|
this.setState({ edit_Sensor: undefined });
|
||||||
|
};
|
||||||
|
|
||||||
|
doneEditingSensor = () => {
|
||||||
|
const { edit_Sensor } = this.state;
|
||||||
|
|
||||||
|
redirectingAuthorizedFetch(WRITE_SENSOR_ENDPOINT, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({
|
||||||
|
// because input field with type=number doens't like negative values, force it here
|
||||||
|
sensor: {
|
||||||
|
no: edit_Sensor?.n, // no
|
||||||
|
id: edit_Sensor?.i, // id
|
||||||
|
temp: edit_Sensor?.t, // temp
|
||||||
|
offset: Number(edit_Sensor?.o) // offset
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
this.props.enqueueSnackbar('Sensor updated', {
|
||||||
|
variant: 'success'
|
||||||
|
});
|
||||||
|
this.props.loadData();
|
||||||
|
} else if (response.status === 204) {
|
||||||
|
this.props.enqueueSnackbar('Sensor change failed', {
|
||||||
|
variant: 'error'
|
||||||
|
});
|
||||||
|
} else if (response.status === 403) {
|
||||||
|
this.props.enqueueSnackbar('Write access denied', {
|
||||||
|
variant: 'error'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
throw Error('Unexpected response code: ' + response.status);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.props.enqueueSnackbar(error.message || 'Problem writing value', {
|
||||||
|
variant: 'error'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (edit_Sensor) {
|
||||||
|
this.setState({ edit_Sensor: undefined });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
sendSensor = (sn: Sensor) => {
|
||||||
|
if (this.props.authenticatedContext.me.admin) {
|
||||||
|
this.setState({ edit_Sensor: sn });
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
noDevices = () => {
|
noDevices = () => {
|
||||||
@@ -218,7 +317,7 @@ class EMSESPDevicesForm extends Component<
|
|||||||
return (this.state.deviceData?.data || []).length === 0;
|
return (this.state.deviceData?.data || []).length === 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
renderDeviceItems() {
|
renderDevices() {
|
||||||
const { width, data } = this.props;
|
const { width, data } = this.props;
|
||||||
return (
|
return (
|
||||||
<TableContainer>
|
<TableContainer>
|
||||||
@@ -229,26 +328,24 @@ class EMSESPDevicesForm extends Component<
|
|||||||
{!this.noDevices() && (
|
{!this.noDevices() && (
|
||||||
<Table
|
<Table
|
||||||
size="small"
|
size="small"
|
||||||
padding={isWidthDown('xs', width!) ? 'none' : 'default'}
|
padding={isWidthDown('xs', width!) ? 'none' : 'normal'}
|
||||||
>
|
>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{data.devices.sort(compareDevices).map((device) => (
|
{data.devices.sort(compareDevices).map((device) => (
|
||||||
<TableRow
|
<TableRow
|
||||||
hover
|
hover
|
||||||
key={device.id}
|
key={device.i}
|
||||||
onClick={() => this.handleRowClick(device)}
|
onClick={() => this.handleRowClick(device.i)}
|
||||||
>
|
>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<CustomTooltip
|
<StyledTooltip
|
||||||
title={
|
title={
|
||||||
'DeviceID:0x' +
|
'DeviceID:0x' +
|
||||||
(
|
('00' + device.d.toString(16).toUpperCase()).slice(-2) +
|
||||||
'00' + device.deviceid.toString(16).toUpperCase()
|
|
||||||
).slice(-2) +
|
|
||||||
' ProductID:' +
|
' ProductID:' +
|
||||||
device.productid +
|
device.p +
|
||||||
' Version:' +
|
' Version:' +
|
||||||
device.version
|
device.v
|
||||||
}
|
}
|
||||||
placement="right-end"
|
placement="right-end"
|
||||||
>
|
>
|
||||||
@@ -257,12 +354,12 @@ class EMSESPDevicesForm extends Component<
|
|||||||
size="small"
|
size="small"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
>
|
>
|
||||||
{device.type}
|
{device.t}
|
||||||
</Button>
|
</Button>
|
||||||
</CustomTooltip>
|
</StyledTooltip>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="right">
|
<TableCell align="right">
|
||||||
{device.brand + ' ' + device.name}{' '}
|
{device.b + ' ' + device.n}{' '}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
@@ -287,34 +384,48 @@ class EMSESPDevicesForm extends Component<
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderSensorItems() {
|
renderSensorData() {
|
||||||
const { data } = this.props;
|
const { data } = this.props;
|
||||||
|
const me = this.props.authenticatedContext.me;
|
||||||
return (
|
return (
|
||||||
<TableContainer>
|
<TableContainer>
|
||||||
<p></p>
|
<p></p>
|
||||||
<Typography variant="h6" color="primary" paragraph>
|
<Typography variant="h6" color="primary" paragraph>
|
||||||
Dallas Sensors
|
Sensors
|
||||||
</Typography>
|
</Typography>
|
||||||
{!this.noSensors() && (
|
{!this.noSensors() && (
|
||||||
<Table size="small" padding="default">
|
<Table size="small" padding="normal">
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<StyledTableRowHeader>
|
||||||
<StyledTableCell>Sensor #</StyledTableCell>
|
<TableCell padding="checkbox" style={{ width: 18 }}></TableCell>
|
||||||
<StyledTableCell align="center">ID</StyledTableCell>
|
<TableCell>Dallas Sensor #</TableCell>
|
||||||
<StyledTableCell align="right">Temperature</StyledTableCell>
|
<TableCell align="left">ID / Name</TableCell>
|
||||||
</TableRow>
|
<TableCell align="right">Temperature</TableCell>
|
||||||
|
</StyledTableRowHeader>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{data.sensors.map((sensorData) => (
|
{data.sensors.map((sensorData) => (
|
||||||
<TableRow key={sensorData.no}>
|
<StyledTableRow
|
||||||
|
key={sensorData.n}
|
||||||
|
onClick={() => this.sendSensor(sensorData)}
|
||||||
|
>
|
||||||
|
<TableCell padding="checkbox">
|
||||||
|
{me.admin && (
|
||||||
|
<StyledTooltip title="edit" placement="left-end">
|
||||||
|
<IconButton edge="start" size="small" aria-label="Edit">
|
||||||
|
<EditIcon color="primary" fontSize="small" />
|
||||||
|
</IconButton>
|
||||||
|
</StyledTooltip>
|
||||||
|
)}
|
||||||
|
</TableCell>
|
||||||
<TableCell component="th" scope="row">
|
<TableCell component="th" scope="row">
|
||||||
{sensorData.no}
|
{sensorData.n}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="center">{sensorData.id}</TableCell>
|
<TableCell align="left">{sensorData.i}</TableCell>
|
||||||
<TableCell align="right">
|
<TableCell align="right">
|
||||||
{formatValue(sensorData.temp, DeviceValueUOM.DEGREES)}
|
{formatValue(sensorData.t, DeviceValueUOM.DEGREES)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</StyledTableRow>
|
||||||
))}
|
))}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
@@ -322,7 +433,7 @@ class EMSESPDevicesForm extends Component<
|
|||||||
{this.noSensors() && (
|
{this.noSensors() && (
|
||||||
<Box color="warning.main" p={0} mt={0} mb={0}>
|
<Box color="warning.main" p={0} mt={0} mb={0}>
|
||||||
<Typography variant="body1">
|
<Typography variant="body1">
|
||||||
<i>no external temperature sensors were detected</i>
|
<i>no Dallas temperature sensors were detected</i>
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
@@ -330,6 +441,37 @@ class EMSESPDevicesForm extends Component<
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderAnalogData() {
|
||||||
|
const { data } = this.props;
|
||||||
|
return (
|
||||||
|
<TableContainer>
|
||||||
|
<p></p>
|
||||||
|
{data.analog > 0 && (
|
||||||
|
<Table size="small" padding="normal">
|
||||||
|
<TableHead>
|
||||||
|
<StyledTableRowHeader>
|
||||||
|
<TableCell padding="normal" style={{ width: 18 }}></TableCell>
|
||||||
|
<TableCell>Sensor Type</TableCell>
|
||||||
|
<TableCell align="right">Value</TableCell>
|
||||||
|
</StyledTableRowHeader>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell padding="normal"> </TableCell>
|
||||||
|
<TableCell component="th" scope="row">
|
||||||
|
Analog Input
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="right">
|
||||||
|
{formatValue(data.analog, DeviceValueUOM.MV)}
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
)}
|
||||||
|
</TableContainer>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
renderScanDevicesDialog() {
|
renderScanDevicesDialog() {
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
@@ -396,10 +538,10 @@ class EMSESPDevicesForm extends Component<
|
|||||||
};
|
};
|
||||||
|
|
||||||
handleRowClick = (device: any) => {
|
handleRowClick = (device: any) => {
|
||||||
this.setState({ selectedDevice: device.id, deviceData: undefined });
|
this.setState({ selectedDevice: device, deviceData: undefined });
|
||||||
redirectingAuthorizedFetch(DEVICE_DATA_ENDPOINT, {
|
redirectingAuthorizedFetch(DEVICE_DATA_ENDPOINT, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify({ id: device.id }),
|
body: JSON.stringify({ id: device }),
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
}
|
}
|
||||||
@@ -426,7 +568,6 @@ class EMSESPDevicesForm extends Component<
|
|||||||
renderDeviceData() {
|
renderDeviceData() {
|
||||||
const { deviceData } = this.state;
|
const { deviceData } = this.state;
|
||||||
const { width } = this.props;
|
const { width } = this.props;
|
||||||
const me = this.props.authenticatedContext.me;
|
|
||||||
|
|
||||||
if (this.noDevices()) {
|
if (this.noDevices()) {
|
||||||
return;
|
return;
|
||||||
@@ -441,22 +582,24 @@ class EMSESPDevicesForm extends Component<
|
|||||||
<p></p>
|
<p></p>
|
||||||
<Box bgcolor="info.main" p={1} mt={1} mb={1}>
|
<Box bgcolor="info.main" p={1} mt={1} mb={1}>
|
||||||
<Typography variant="body1" color="initial">
|
<Typography variant="body1" color="initial">
|
||||||
{deviceData.name}
|
{deviceData.type} Data
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
{!this.noDeviceData() && (
|
{!this.noDeviceData() && (
|
||||||
<TableContainer>
|
<TableContainer>
|
||||||
<Table
|
<Table
|
||||||
size="small"
|
size="small"
|
||||||
padding={isWidthDown('xs', width!) ? 'none' : 'default'}
|
padding={isWidthDown('xs', width!) ? 'none' : 'normal'}
|
||||||
>
|
>
|
||||||
<TableHead></TableHead>
|
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{deviceData.data.map((item, i) => (
|
{deviceData.data.map((item, i) => (
|
||||||
<TableRow hover key={i}>
|
<StyledTableRow
|
||||||
|
key={i}
|
||||||
|
onClick={() => this.sendCommand(item)}
|
||||||
|
>
|
||||||
<TableCell padding="checkbox" style={{ width: 18 }}>
|
<TableCell padding="checkbox" style={{ width: 18 }}>
|
||||||
{item.c && me.admin && (
|
{item.c && this.props.authenticatedContext.me.admin && (
|
||||||
<CustomTooltip
|
<StyledTooltip
|
||||||
title="change value"
|
title="change value"
|
||||||
placement="left-end"
|
placement="left-end"
|
||||||
>
|
>
|
||||||
@@ -464,11 +607,10 @@ class EMSESPDevicesForm extends Component<
|
|||||||
edge="start"
|
edge="start"
|
||||||
size="small"
|
size="small"
|
||||||
aria-label="Edit"
|
aria-label="Edit"
|
||||||
onClick={() => this.sendCommand(item)}
|
|
||||||
>
|
>
|
||||||
<EditIcon color="primary" fontSize="small" />
|
<EditIcon color="primary" fontSize="small" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</CustomTooltip>
|
</StyledTooltip>
|
||||||
)}
|
)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell padding="none" component="th" scope="row">
|
<TableCell padding="none" component="th" scope="row">
|
||||||
@@ -477,7 +619,7 @@ class EMSESPDevicesForm extends Component<
|
|||||||
<TableCell padding="none" align="right">
|
<TableCell padding="none" align="right">
|
||||||
{formatValue(item.v, item.u)}
|
{formatValue(item.v, item.u)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</StyledTableRow>
|
||||||
))}
|
))}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
@@ -486,7 +628,7 @@ class EMSESPDevicesForm extends Component<
|
|||||||
{this.noDeviceData() && (
|
{this.noDeviceData() && (
|
||||||
<Box color="warning.main" p={0} mt={0} mb={0}>
|
<Box color="warning.main" p={0} mt={0} mb={0}>
|
||||||
<Typography variant="body1">
|
<Typography variant="body1">
|
||||||
<i>No data available for this device</i>
|
<i>no data available for this device</i>
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
@@ -495,13 +637,14 @@ class EMSESPDevicesForm extends Component<
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { edit_devicevalue } = this.state;
|
const { edit_devicevalue, edit_Sensor } = this.state;
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<br></br>
|
<br></br>
|
||||||
{this.renderDeviceItems()}
|
{this.renderDevices()}
|
||||||
{this.renderDeviceData()}
|
{this.renderDeviceData()}
|
||||||
{this.renderSensorItems()}
|
{this.renderSensorData()}
|
||||||
|
{this.renderAnalogData()}
|
||||||
<br></br>
|
<br></br>
|
||||||
<Box display="flex" flexWrap="wrap">
|
<Box display="flex" flexWrap="wrap">
|
||||||
<Box flexGrow={1} padding={1}>
|
<Box flexGrow={1} padding={1}>
|
||||||
@@ -528,9 +671,17 @@ class EMSESPDevicesForm extends Component<
|
|||||||
{edit_devicevalue && (
|
{edit_devicevalue && (
|
||||||
<ValueForm
|
<ValueForm
|
||||||
devicevalue={edit_devicevalue}
|
devicevalue={edit_devicevalue}
|
||||||
onDoneEditing={this.doneEditingValue}
|
onDoneEditing={this.doneEditingDeviceValue}
|
||||||
onCancelEditing={this.cancelEditingValue}
|
onCancelEditing={this.cancelEditingDeviceValue}
|
||||||
handleValueChange={this.handleValueChange}
|
handleValueChange={this.handleDeviceValueChange}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{edit_Sensor && (
|
||||||
|
<SensorForm
|
||||||
|
sensor={edit_Sensor}
|
||||||
|
onDoneEditing={this.doneEditingSensor}
|
||||||
|
onCancelEditing={this.cancelEditingSensor}
|
||||||
|
handleSensorChange={this.handleSensorChange}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
@@ -538,4 +689,4 @@ class EMSESPDevicesForm extends Component<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withAuthenticatedContext(withWidth()(EMSESPDevicesForm));
|
export default withAuthenticatedContext(withWidth()(EMSESPDataForm));
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
import React, { Component } from 'react';
|
|
||||||
|
|
||||||
import {
|
|
||||||
restController,
|
|
||||||
RestControllerProps,
|
|
||||||
RestFormLoader,
|
|
||||||
SectionContent
|
|
||||||
} from '../components';
|
|
||||||
|
|
||||||
import { ENDPOINT_ROOT } from '../api';
|
|
||||||
import EMSESPDevicesForm from './EMSESPDevicesForm';
|
|
||||||
import { EMSESPDevices } from './EMSESPtypes';
|
|
||||||
|
|
||||||
export const EMSESP_DEVICES_ENDPOINT = ENDPOINT_ROOT + 'allDevices';
|
|
||||||
|
|
||||||
type EMSESPDevicesControllerProps = RestControllerProps<EMSESPDevices>;
|
|
||||||
|
|
||||||
class EMSESPDevicesController extends Component<EMSESPDevicesControllerProps> {
|
|
||||||
componentDidMount() {
|
|
||||||
this.props.loadData();
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<SectionContent title="Devices & Sensors">
|
|
||||||
<RestFormLoader
|
|
||||||
{...this.props}
|
|
||||||
render={(formProps) => <EMSESPDevicesForm {...formProps} />}
|
|
||||||
/>
|
|
||||||
</SectionContent>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default restController(EMSESP_DEVICES_ENDPOINT, EMSESPDevicesController);
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { Component } from 'react';
|
import { Component } from 'react';
|
||||||
import {
|
import {
|
||||||
Typography,
|
Typography,
|
||||||
Box,
|
Box,
|
||||||
@@ -14,14 +14,40 @@ import CommentIcon from '@material-ui/icons/CommentTwoTone';
|
|||||||
import MenuBookIcon from '@material-ui/icons/MenuBookTwoTone';
|
import MenuBookIcon from '@material-ui/icons/MenuBookTwoTone';
|
||||||
import GitHubIcon from '@material-ui/icons/GitHub';
|
import GitHubIcon from '@material-ui/icons/GitHub';
|
||||||
import StarIcon from '@material-ui/icons/Star';
|
import StarIcon from '@material-ui/icons/Star';
|
||||||
import ImportExportIcon from '@material-ui/icons/ImportExport';
|
import DownloadIcon from '@material-ui/icons/GetApp';
|
||||||
import BugReportIcon from '@material-ui/icons/BugReportTwoTone';
|
|
||||||
|
|
||||||
export const WebAPISystemSettings =
|
import { FormButton } from '../components';
|
||||||
window.location.origin + '/api/system/settings';
|
|
||||||
export const WebAPISystemInfo = window.location.origin + '/api/system/info';
|
import { API_ENDPOINT_ROOT } from '../api';
|
||||||
|
|
||||||
|
import { redirectingAuthorizedFetch } from '../authentication';
|
||||||
|
|
||||||
class EMSESPHelp extends Component {
|
class EMSESPHelp extends Component {
|
||||||
|
onDownload = (endpoint: string) => {
|
||||||
|
redirectingAuthorizedFetch(API_ENDPOINT_ROOT + 'system/' + endpoint)
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
throw Error(
|
||||||
|
'Device returned unexpected response code: ' + response.status
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.then((json) => {
|
||||||
|
const a = document.createElement('a');
|
||||||
|
const filename = 'emsesp_system_' + endpoint + '.txt';
|
||||||
|
a.href = URL.createObjectURL(
|
||||||
|
new Blob([JSON.stringify(json, null, 2)], {
|
||||||
|
type: 'text/plain'
|
||||||
|
})
|
||||||
|
);
|
||||||
|
a.setAttribute('download', filename);
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
document.body.removeChild(a);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<SectionContent title="EMS-ESP Help" titleGutter>
|
<SectionContent title="EMS-ESP Help" titleGutter>
|
||||||
@@ -31,9 +57,9 @@ class EMSESPHelp extends Component {
|
|||||||
<MenuBookIcon />
|
<MenuBookIcon />
|
||||||
</ListItemAvatar>
|
</ListItemAvatar>
|
||||||
<ListItemText>
|
<ListItemText>
|
||||||
For the latest news and updates go to the{' '}
|
For help and information on the latest updates visit the{' '}
|
||||||
<Link href="https://emsesp.github.io/docs" color="primary">
|
<Link href="https://emsesp.github.io/docs" color="primary">
|
||||||
{'official documentation'} website
|
{'online documentation'}
|
||||||
</Link>
|
</Link>
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
@@ -55,41 +81,36 @@ class EMSESPHelp extends Component {
|
|||||||
<GitHubIcon />
|
<GitHubIcon />
|
||||||
</ListItemAvatar>
|
</ListItemAvatar>
|
||||||
<ListItemText>
|
<ListItemText>
|
||||||
To report an issue or feature request go to{' '}
|
To report an issue or request a feature go to{' '}
|
||||||
<Link
|
<Link
|
||||||
href="https://github.com/emsesp/EMS-ESP32/issues/new/choose"
|
href="https://github.com/emsesp/EMS-ESP32/issues/new/choose"
|
||||||
color="primary"
|
color="primary"
|
||||||
>
|
>
|
||||||
{'click here'}
|
{'GitHub'}
|
||||||
</Link>
|
|
||||||
</ListItemText>
|
|
||||||
</ListItem>
|
|
||||||
|
|
||||||
<ListItem>
|
|
||||||
<ListItemAvatar>
|
|
||||||
<ImportExportIcon />
|
|
||||||
</ListItemAvatar>
|
|
||||||
<ListItemText>
|
|
||||||
To export your system settings{' '}
|
|
||||||
<Link target="_blank" href={WebAPISystemSettings} color="primary">
|
|
||||||
{'click here'}
|
|
||||||
</Link>
|
|
||||||
</ListItemText>
|
|
||||||
</ListItem>
|
|
||||||
|
|
||||||
<ListItem>
|
|
||||||
<ListItemAvatar>
|
|
||||||
<BugReportIcon />
|
|
||||||
</ListItemAvatar>
|
|
||||||
<ListItemText>
|
|
||||||
To export the current status of EMS-ESP{' '}
|
|
||||||
<Link target="_blank" href={WebAPISystemInfo} color="primary">
|
|
||||||
{'click here'}
|
|
||||||
</Link>
|
</Link>
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</List>
|
</List>
|
||||||
|
|
||||||
|
<Box flexWrap="none" padding={1} whiteSpace="nowrap">
|
||||||
|
<FormButton
|
||||||
|
startIcon={<DownloadIcon />}
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
onClick={() => this.onDownload('info')}
|
||||||
|
>
|
||||||
|
download system info
|
||||||
|
</FormButton>
|
||||||
|
<FormButton
|
||||||
|
startIcon={<DownloadIcon />}
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
onClick={() => this.onDownload('settings')}
|
||||||
|
>
|
||||||
|
download all settings
|
||||||
|
</FormButton>
|
||||||
|
</Box>
|
||||||
|
|
||||||
<Box bgcolor="info.main" border={1} p={3} mt={1} mb={0}>
|
<Box bgcolor="info.main" border={1} p={3} mt={1} mb={0}>
|
||||||
<Typography variant="h6">
|
<Typography variant="h6">
|
||||||
EMS-ESP is free and open-source.
|
EMS-ESP is free and open-source.
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import {
|
|||||||
BlockFormControlLabel
|
BlockFormControlLabel
|
||||||
} from '../components';
|
} from '../components';
|
||||||
|
|
||||||
import { isIP, optional } from '../validators';
|
import { isIPv4, optional, isHostname, or } from '../validators';
|
||||||
|
|
||||||
import { EMSESPSettings } from './EMSESPtypes';
|
import { EMSESPSettings } from './EMSESPtypes';
|
||||||
|
|
||||||
@@ -55,7 +55,10 @@ class EMSESPSettingsForm extends Component<EMSESPSettingsFormProps> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
ValidatorForm.addValidationRule('isOptionalIP', optional(isIP));
|
ValidatorForm.addValidationRule(
|
||||||
|
'isOptionalIPorHost',
|
||||||
|
optional(or(isIPv4, isHostname))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
changeBoardProfile = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
changeBoardProfile = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
||||||
@@ -90,6 +93,7 @@ class EMSESPSettingsForm extends Component<EMSESPSettingsFormProps> {
|
|||||||
rx_gpio: json.rx_gpio,
|
rx_gpio: json.rx_gpio,
|
||||||
tx_gpio: json.tx_gpio,
|
tx_gpio: json.tx_gpio,
|
||||||
pbutton_gpio: json.pbutton_gpio,
|
pbutton_gpio: json.pbutton_gpio,
|
||||||
|
phy_type: json.phy_type,
|
||||||
board_profile: event.target.value
|
board_profile: event.target.value
|
||||||
});
|
});
|
||||||
this.setState({ processing: false });
|
this.setState({ processing: false });
|
||||||
@@ -109,15 +113,17 @@ class EMSESPSettingsForm extends Component<EMSESPSettingsFormProps> {
|
|||||||
<ValidatorForm onSubmit={saveData}>
|
<ValidatorForm onSubmit={saveData}>
|
||||||
<Box bgcolor="info.main" p={2} mt={2} mb={2}>
|
<Box bgcolor="info.main" p={2} mt={2} mb={2}>
|
||||||
<Typography variant="body1">
|
<Typography variant="body1">
|
||||||
Adjust any of the EMS-ESP settings here. For help refer to the{' '}
|
<i>
|
||||||
|
visit the
|
||||||
<Link
|
<Link
|
||||||
target="_blank"
|
target="_blank"
|
||||||
href="https://emsesp.github.io/docs/#/Configure-firmware32?id=ems-esp-settings"
|
href="https://emsesp.github.io/docs/#/Configure-firmware?id=ems-esp-settings"
|
||||||
color="primary"
|
color="primary"
|
||||||
>
|
>
|
||||||
{'online documentation'}
|
{'online documentation'}
|
||||||
</Link>
|
</Link>
|
||||||
.
|
for details explaining each setting
|
||||||
|
</i>
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
@@ -130,7 +136,7 @@ class EMSESPSettingsForm extends Component<EMSESPSettingsFormProps> {
|
|||||||
container
|
container
|
||||||
spacing={1}
|
spacing={1}
|
||||||
direction="row"
|
direction="row"
|
||||||
justify="flex-start"
|
justifyContent="flex-start"
|
||||||
alignItems="flex-start"
|
alignItems="flex-start"
|
||||||
>
|
>
|
||||||
<Grid item xs={5}>
|
<Grid item xs={5}>
|
||||||
@@ -167,30 +173,6 @@ class EMSESPSettingsForm extends Component<EMSESPSettingsFormProps> {
|
|||||||
<MenuItem value={0x12}>Alarm Module (0x12)</MenuItem>
|
<MenuItem value={0x12}>Alarm Module (0x12)</MenuItem>
|
||||||
</SelectValidator>
|
</SelectValidator>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={6}>
|
|
||||||
<TextValidator
|
|
||||||
validators={[
|
|
||||||
'required',
|
|
||||||
'isNumber',
|
|
||||||
'minNumber:0',
|
|
||||||
'maxNumber:120'
|
|
||||||
]}
|
|
||||||
errorMessages={[
|
|
||||||
'Tx delay is required',
|
|
||||||
'Must be a number',
|
|
||||||
'Must be 0 or higher',
|
|
||||||
'Max value is 120'
|
|
||||||
]}
|
|
||||||
name="tx_delay"
|
|
||||||
label="Tx start delay (seconds)"
|
|
||||||
fullWidth
|
|
||||||
variant="outlined"
|
|
||||||
value={data.tx_delay}
|
|
||||||
type="number"
|
|
||||||
onChange={handleValueChange('tx_delay')}
|
|
||||||
margin="normal"
|
|
||||||
/>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<br></br>
|
<br></br>
|
||||||
@@ -202,7 +184,7 @@ class EMSESPSettingsForm extends Component<EMSESPSettingsFormProps> {
|
|||||||
<Typography variant="body2">
|
<Typography variant="body2">
|
||||||
<i>
|
<i>
|
||||||
Select a pre-configured board layout to automatically set the GPIO
|
Select a pre-configured board layout to automatically set the GPIO
|
||||||
pins, or set your own custom configuration
|
pins. Select "Custom..." to view or manually edit the values.
|
||||||
</i>
|
</i>
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -227,7 +209,7 @@ class EMSESPSettingsForm extends Component<EMSESPSettingsFormProps> {
|
|||||||
container
|
container
|
||||||
spacing={1}
|
spacing={1}
|
||||||
direction="row"
|
direction="row"
|
||||||
justify="flex-start"
|
justifyContent="flex-start"
|
||||||
alignItems="flex-start"
|
alignItems="flex-start"
|
||||||
>
|
>
|
||||||
<Grid item xs={4}>
|
<Grid item xs={4}>
|
||||||
@@ -325,7 +307,7 @@ class EMSESPSettingsForm extends Component<EMSESPSettingsFormProps> {
|
|||||||
'Not a valid GPIO'
|
'Not a valid GPIO'
|
||||||
]}
|
]}
|
||||||
name="dallas_gpio"
|
name="dallas_gpio"
|
||||||
label="Dallas GPIO (0=none)"
|
label="Dallas GPIO (0=disabled)"
|
||||||
fullWidth
|
fullWidth
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
value={data.dallas_gpio}
|
value={data.dallas_gpio}
|
||||||
@@ -351,7 +333,7 @@ class EMSESPSettingsForm extends Component<EMSESPSettingsFormProps> {
|
|||||||
'Not a valid GPIO'
|
'Not a valid GPIO'
|
||||||
]}
|
]}
|
||||||
name="led_gpio"
|
name="led_gpio"
|
||||||
label="LED GPIO (0=none)"
|
label="LED GPIO (0=disabled)"
|
||||||
fullWidth
|
fullWidth
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
value={data.led_gpio}
|
value={data.led_gpio}
|
||||||
@@ -360,12 +342,27 @@ class EMSESPSettingsForm extends Component<EMSESPSettingsFormProps> {
|
|||||||
margin="normal"
|
margin="normal"
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<Grid item xs={4}>
|
||||||
|
<SelectValidator
|
||||||
|
name="phy_type"
|
||||||
|
label="PHY Module Type"
|
||||||
|
value={data.phy_type}
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
onChange={handleValueChange('phy_type')}
|
||||||
|
margin="normal"
|
||||||
|
>
|
||||||
|
<MenuItem value={0}>No Ethernet</MenuItem>
|
||||||
|
<MenuItem value={1}>LAN8720</MenuItem>
|
||||||
|
<MenuItem value={2}>TLK110</MenuItem>
|
||||||
|
</SelectValidator>
|
||||||
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<br></br>
|
<br></br>
|
||||||
<Typography variant="h6" color="primary">
|
<Typography variant="h6" color="primary">
|
||||||
Options
|
General Options
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
{data.led_gpio !== 0 && (
|
{data.led_gpio !== 0 && (
|
||||||
@@ -390,20 +387,10 @@ class EMSESPSettingsForm extends Component<EMSESPSettingsFormProps> {
|
|||||||
value="dallas_parasite"
|
value="dallas_parasite"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
label="Enable Dallas parasite mode"
|
label="Use Dallas Sensor parasite power"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<BlockFormControlLabel
|
|
||||||
control={
|
|
||||||
<Checkbox
|
|
||||||
checked={data.notoken_api}
|
|
||||||
onChange={handleValueChange('notoken_api')}
|
|
||||||
value="notoken_api"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label="Bypass Access Token authorization on API calls"
|
|
||||||
/>
|
|
||||||
<BlockFormControlLabel
|
<BlockFormControlLabel
|
||||||
control={
|
control={
|
||||||
<Checkbox
|
<Checkbox
|
||||||
@@ -414,11 +401,31 @@ class EMSESPSettingsForm extends Component<EMSESPSettingsFormProps> {
|
|||||||
}
|
}
|
||||||
label="Enable ADC"
|
label="Enable ADC"
|
||||||
/>
|
/>
|
||||||
|
<BlockFormControlLabel
|
||||||
|
control={
|
||||||
|
<Checkbox
|
||||||
|
checked={data.low_clock}
|
||||||
|
onChange={handleValueChange('low_clock')}
|
||||||
|
value="low_clock"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label="Run at a lower CPU clock speed"
|
||||||
|
/>
|
||||||
|
<BlockFormControlLabel
|
||||||
|
control={
|
||||||
|
<Checkbox
|
||||||
|
checked={data.notoken_api}
|
||||||
|
onChange={handleValueChange('notoken_api')}
|
||||||
|
value="notoken_api"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label="Bypass Access Token authorization on API calls"
|
||||||
|
/>
|
||||||
<Grid
|
<Grid
|
||||||
container
|
container
|
||||||
spacing={0}
|
spacing={0}
|
||||||
direction="row"
|
direction="row"
|
||||||
justify="flex-start"
|
justifyContent="flex-start"
|
||||||
alignItems="flex-start"
|
alignItems="flex-start"
|
||||||
>
|
>
|
||||||
<BlockFormControlLabel
|
<BlockFormControlLabel
|
||||||
@@ -443,6 +450,65 @@ class EMSESPSettingsForm extends Component<EMSESPSettingsFormProps> {
|
|||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
<br></br>
|
||||||
|
<Typography variant="h6" color="primary">
|
||||||
|
Formatting Options
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Grid
|
||||||
|
container
|
||||||
|
spacing={1}
|
||||||
|
direction="row"
|
||||||
|
justifyContent="flex-start"
|
||||||
|
alignItems="flex-start"
|
||||||
|
>
|
||||||
|
<Grid item xs={4}>
|
||||||
|
<SelectValidator
|
||||||
|
name="bool_format"
|
||||||
|
label="Boolean Format"
|
||||||
|
value={data.bool_format}
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
onChange={handleValueChange('bool_format')}
|
||||||
|
margin="normal"
|
||||||
|
>
|
||||||
|
<MenuItem value={1}>"on"/"off"</MenuItem>
|
||||||
|
<MenuItem value={2}>"ON"/"OFF"</MenuItem>
|
||||||
|
<MenuItem value={3}>true/false</MenuItem>
|
||||||
|
<MenuItem value={4}>1/0</MenuItem>
|
||||||
|
</SelectValidator>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={4}>
|
||||||
|
<SelectValidator
|
||||||
|
name="enum_format"
|
||||||
|
label="Enum Format"
|
||||||
|
value={data.enum_format}
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
onChange={handleValueChange('enum_format')}
|
||||||
|
margin="normal"
|
||||||
|
>
|
||||||
|
<MenuItem value={1}>Text</MenuItem>
|
||||||
|
<MenuItem value={2}>Number</MenuItem>
|
||||||
|
</SelectValidator>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={4}>
|
||||||
|
<SelectValidator
|
||||||
|
name="dallas_format"
|
||||||
|
label="Dallas Sensor Format"
|
||||||
|
value={data.dallas_format}
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
onChange={handleValueChange('dallas_format')}
|
||||||
|
margin="normal"
|
||||||
|
>
|
||||||
|
<MenuItem value={1}>ID</MenuItem>
|
||||||
|
<MenuItem value={2}>Number</MenuItem>
|
||||||
|
<MenuItem value={3}>Name</MenuItem>
|
||||||
|
</SelectValidator>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<br></br>
|
<br></br>
|
||||||
<Typography variant="h6" color="primary">
|
<Typography variant="h6" color="primary">
|
||||||
Syslog
|
Syslog
|
||||||
@@ -464,15 +530,15 @@ class EMSESPSettingsForm extends Component<EMSESPSettingsFormProps> {
|
|||||||
container
|
container
|
||||||
spacing={1}
|
spacing={1}
|
||||||
direction="row"
|
direction="row"
|
||||||
justify="flex-start"
|
justifyContent="flex-start"
|
||||||
alignItems="flex-start"
|
alignItems="flex-start"
|
||||||
>
|
>
|
||||||
<Grid item xs={5}>
|
<Grid item xs={5}>
|
||||||
<TextValidator
|
<TextValidator
|
||||||
validators={['isOptionalIP']}
|
validators={['isOptionalIPorHost']}
|
||||||
errorMessages={['Not a valid IP address']}
|
errorMessages={['Not a valid IPv4 address or hostname']}
|
||||||
name="syslog_host"
|
name="syslog_host"
|
||||||
label="IP"
|
label="Host"
|
||||||
fullWidth
|
fullWidth
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
value={data.syslog_host}
|
value={data.syslog_host}
|
||||||
@@ -537,7 +603,7 @@ class EMSESPSettingsForm extends Component<EMSESPSettingsFormProps> {
|
|||||||
'Max value is 10'
|
'Max value is 10'
|
||||||
]}
|
]}
|
||||||
name="syslog_mark_interval"
|
name="syslog_mark_interval"
|
||||||
label="Mark Interval seconds (0=off)"
|
label="Mark Interval (seconds, 0=off)"
|
||||||
fullWidth
|
fullWidth
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
value={data.syslog_mark_interval}
|
value={data.syslog_mark_interval}
|
||||||
@@ -554,7 +620,7 @@ class EMSESPSettingsForm extends Component<EMSESPSettingsFormProps> {
|
|||||||
value="trace_raw"
|
value="trace_raw"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
label="Output EMS telegrams in raw format"
|
label="Output EMS telegrams as hexadecimal bytes"
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -58,18 +58,18 @@ class EMSESPStatusForm extends Component<EMSESPStatusFormProps> {
|
|||||||
<TableContainer>
|
<TableContainer>
|
||||||
<Table
|
<Table
|
||||||
size="small"
|
size="small"
|
||||||
padding={isWidthDown('xs', width!) ? 'none' : 'default'}
|
padding={isWidthDown('xs', width!) ? 'none' : 'normal'}
|
||||||
>
|
>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell># Telegrams Received</TableCell>
|
<TableCell>Telegrams Received</TableCell>
|
||||||
<TableCell align="right">
|
<TableCell align="right">
|
||||||
{formatNumber(data.rx_received)} (quality{' '}
|
{formatNumber(data.rx_received)} (quality{' '}
|
||||||
{data.rx_quality}%)
|
{data.rx_quality}%)
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell># Telegrams Sent</TableCell>
|
<TableCell>Telegrams Sent</TableCell>
|
||||||
<TableCell align="right">
|
<TableCell align="right">
|
||||||
{formatNumber(data.tx_sent)} (quality {data.tx_quality}
|
{formatNumber(data.tx_sent)} (quality {data.tx_quality}
|
||||||
%)
|
%)
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
export interface EMSESPSettings {
|
export interface EMSESPSettings {
|
||||||
tx_mode: number;
|
tx_mode: number;
|
||||||
tx_delay: number;
|
|
||||||
ems_bus_id: number;
|
ems_bus_id: number;
|
||||||
syslog_enabled: boolean;
|
syslog_enabled: boolean;
|
||||||
syslog_level: number;
|
syslog_level: number;
|
||||||
@@ -12,15 +11,20 @@ export interface EMSESPSettings {
|
|||||||
shower_alert: boolean;
|
shower_alert: boolean;
|
||||||
rx_gpio: number;
|
rx_gpio: number;
|
||||||
tx_gpio: number;
|
tx_gpio: number;
|
||||||
|
phy_type: number;
|
||||||
dallas_gpio: number;
|
dallas_gpio: number;
|
||||||
dallas_parasite: boolean;
|
dallas_parasite: boolean;
|
||||||
led_gpio: number;
|
led_gpio: number;
|
||||||
hide_led: boolean;
|
hide_led: boolean;
|
||||||
|
low_clock: boolean;
|
||||||
notoken_api: boolean;
|
notoken_api: boolean;
|
||||||
analog_enabled: boolean;
|
analog_enabled: boolean;
|
||||||
pbutton_gpio: number;
|
pbutton_gpio: number;
|
||||||
trace_raw: boolean;
|
trace_raw: boolean;
|
||||||
board_profile: string;
|
board_profile: string;
|
||||||
|
bool_format: number;
|
||||||
|
dallas_format: number;
|
||||||
|
enum_format: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum busConnectionStatus {
|
export enum busConnectionStatus {
|
||||||
@@ -38,35 +42,38 @@ export interface EMSESPStatus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface Device {
|
export interface Device {
|
||||||
id: number;
|
i: number; // id
|
||||||
type: string;
|
t: string; // type
|
||||||
brand: string;
|
b: string; // brand
|
||||||
name: string;
|
n: string; // name
|
||||||
deviceid: number;
|
d: number; // deviceid
|
||||||
productid: number;
|
p: number; // productid
|
||||||
version: string;
|
v: string; // version
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Sensor {
|
export interface Sensor {
|
||||||
no: number;
|
n: number; // np
|
||||||
id: string;
|
i: string; // id
|
||||||
temp: string;
|
t: number; // temp
|
||||||
|
o: number; // offset
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EMSESPDevices {
|
export interface EMSESPData {
|
||||||
devices: Device[];
|
devices: Device[];
|
||||||
sensors: Sensor[];
|
sensors: Sensor[];
|
||||||
|
analog: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DeviceValue {
|
export interface DeviceValue {
|
||||||
v: any;
|
v: any; // value, in any format
|
||||||
u: number;
|
u: number; // uom
|
||||||
n: string;
|
n: string; // name
|
||||||
c: string;
|
c: string; // command
|
||||||
|
l: string[]; // list
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EMSESPDeviceData {
|
export interface EMSESPDeviceData {
|
||||||
name: string;
|
type: string;
|
||||||
data: DeviceValue[];
|
data: DeviceValue[];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,8 +93,9 @@ export enum DeviceValueUOM {
|
|||||||
KB,
|
KB,
|
||||||
SECONDS,
|
SECONDS,
|
||||||
DBM,
|
DBM,
|
||||||
NUM,
|
MV,
|
||||||
BOOLEAN
|
TIMES,
|
||||||
|
OCLOCK
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DeviceValueUOM_s = [
|
export const DeviceValueUOM_s = [
|
||||||
@@ -104,8 +112,9 @@ export const DeviceValueUOM_s = [
|
|||||||
'kW',
|
'kW',
|
||||||
'W',
|
'W',
|
||||||
'KB',
|
'KB',
|
||||||
'seconds',
|
'second',
|
||||||
'dBm',
|
'dBm',
|
||||||
'number',
|
'mV',
|
||||||
'on/off'
|
'time',
|
||||||
|
"o'clock"
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class ProjectMenu extends Component<ProjectProps> {
|
|||||||
to="/ems-esp/"
|
to="/ems-esp/"
|
||||||
selected={
|
selected={
|
||||||
path.startsWith('/ems-esp/status') ||
|
path.startsWith('/ems-esp/status') ||
|
||||||
path.startsWith('/ems-esp/devices') ||
|
path.startsWith('/ems-esp/data') ||
|
||||||
path.startsWith('/ems-esp/help')
|
path.startsWith('/ems-esp/help')
|
||||||
}
|
}
|
||||||
button
|
button
|
||||||
|
|||||||
101
interface/src/project/SensorForm.tsx
Normal file
101
interface/src/project/SensorForm.tsx
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
import React, { RefObject } from 'react';
|
||||||
|
import { ValidatorForm, TextValidator } from 'react-material-ui-form-validator';
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogTitle,
|
||||||
|
DialogContent,
|
||||||
|
DialogActions
|
||||||
|
} from '@material-ui/core';
|
||||||
|
|
||||||
|
import { FormButton } from '../components';
|
||||||
|
import { Sensor } from './EMSESPtypes';
|
||||||
|
|
||||||
|
interface SensorFormProps {
|
||||||
|
sensor: Sensor;
|
||||||
|
onDoneEditing: () => void;
|
||||||
|
onCancelEditing: () => void;
|
||||||
|
handleSensorChange: (
|
||||||
|
data: keyof Sensor
|
||||||
|
) => (event: React.ChangeEvent<HTMLInputElement>) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
class SensorForm extends React.Component<SensorFormProps> {
|
||||||
|
formRef: RefObject<any> = React.createRef();
|
||||||
|
|
||||||
|
submit = () => {
|
||||||
|
this.formRef.current.submit();
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
sensor,
|
||||||
|
handleSensorChange,
|
||||||
|
onDoneEditing,
|
||||||
|
onCancelEditing
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ValidatorForm onSubmit={onDoneEditing} ref={this.formRef}>
|
||||||
|
<Dialog
|
||||||
|
maxWidth="xs"
|
||||||
|
onClose={onCancelEditing}
|
||||||
|
aria-labelledby="user-form-dialog-title"
|
||||||
|
open
|
||||||
|
>
|
||||||
|
<DialogTitle id="user-form-dialog-title">
|
||||||
|
Editing Sensor #{sensor.n}
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogContent dividers>
|
||||||
|
<TextValidator
|
||||||
|
validators={['matchRegexp:^([a-zA-Z0-9_.-]{0,19})$']}
|
||||||
|
errorMessages={['Not a valid name']}
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
value={sensor.i}
|
||||||
|
onChange={handleSensorChange('i')}
|
||||||
|
margin="normal"
|
||||||
|
label="Name"
|
||||||
|
name="id"
|
||||||
|
/>
|
||||||
|
<TextValidator
|
||||||
|
validators={['isFloat', 'minFloat:-5', 'maxFloat:5']}
|
||||||
|
errorMessages={[
|
||||||
|
'Must be a number',
|
||||||
|
'Must be greater than -5',
|
||||||
|
'Max value is +5'
|
||||||
|
]}
|
||||||
|
label="Custom Offset (°C)"
|
||||||
|
name="offset"
|
||||||
|
type="number"
|
||||||
|
value={sensor.o}
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
InputProps={{ inputProps: { min: '-5', max: '5', step: '0.1' } }}
|
||||||
|
margin="normal"
|
||||||
|
onChange={handleSensorChange('o')}
|
||||||
|
/>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<FormButton
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
onClick={onCancelEditing}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</FormButton>
|
||||||
|
<FormButton
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
type="submit"
|
||||||
|
onClick={this.submit}
|
||||||
|
>
|
||||||
|
Done
|
||||||
|
</FormButton>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
</ValidatorForm>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SensorForm;
|
||||||
@@ -15,7 +15,7 @@ import {
|
|||||||
} from '@material-ui/core';
|
} from '@material-ui/core';
|
||||||
|
|
||||||
import { FormButton } from '../components';
|
import { FormButton } from '../components';
|
||||||
import { DeviceValue, DeviceValueUOM, DeviceValueUOM_s } from './EMSESPtypes';
|
import { DeviceValue, DeviceValueUOM_s } from './EMSESPtypes';
|
||||||
|
|
||||||
interface ValueFormProps {
|
interface ValueFormProps {
|
||||||
devicevalue: DeviceValue;
|
devicevalue: DeviceValue;
|
||||||
@@ -25,7 +25,6 @@ interface ValueFormProps {
|
|||||||
data: keyof DeviceValue
|
data: keyof DeviceValue
|
||||||
) => (event: React.ChangeEvent<HTMLInputElement>) => void;
|
) => (event: React.ChangeEvent<HTMLInputElement>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ValueForm extends React.Component<ValueFormProps> {
|
class ValueForm extends React.Component<ValueFormProps> {
|
||||||
formRef: RefObject<any> = React.createRef();
|
formRef: RefObject<any> = React.createRef();
|
||||||
|
|
||||||
@@ -51,25 +50,7 @@ class ValueForm extends React.Component<ValueFormProps> {
|
|||||||
>
|
>
|
||||||
<DialogTitle id="user-form-dialog-title">Change Value</DialogTitle>
|
<DialogTitle id="user-form-dialog-title">Change Value</DialogTitle>
|
||||||
<DialogContent dividers>
|
<DialogContent dividers>
|
||||||
{devicevalue.u !== DeviceValueUOM.BOOLEAN && (
|
{devicevalue.l && (
|
||||||
<OutlinedInput
|
|
||||||
id="outlined-adornment-value"
|
|
||||||
value={devicevalue.v}
|
|
||||||
autoFocus
|
|
||||||
fullWidth
|
|
||||||
onChange={handleValueChange('v')}
|
|
||||||
endAdornment={
|
|
||||||
<InputAdornment position="end">
|
|
||||||
{DeviceValueUOM_s[devicevalue.u]}
|
|
||||||
</InputAdornment>
|
|
||||||
}
|
|
||||||
aria-describedby="outlined-value-helper-text"
|
|
||||||
inputProps={{
|
|
||||||
'aria-label': 'value'
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{devicevalue.u === DeviceValueUOM.BOOLEAN && (
|
|
||||||
<TextField
|
<TextField
|
||||||
id="outlined-select-value"
|
id="outlined-select-value"
|
||||||
select
|
select
|
||||||
@@ -79,13 +60,26 @@ class ValueForm extends React.Component<ValueFormProps> {
|
|||||||
onChange={handleValueChange('v')}
|
onChange={handleValueChange('v')}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
>
|
>
|
||||||
<MenuItem value="true">on</MenuItem>
|
{devicevalue.l.map((val) => (
|
||||||
<MenuItem value="false">off</MenuItem>
|
<MenuItem value={val}>{val}</MenuItem>
|
||||||
|
))}
|
||||||
</TextField>
|
</TextField>
|
||||||
)}
|
)}
|
||||||
<FormHelperText id="outlined-value-helper-text">
|
{!devicevalue.l && (
|
||||||
{devicevalue.n}
|
<OutlinedInput
|
||||||
</FormHelperText>
|
id="value"
|
||||||
|
value={devicevalue.v}
|
||||||
|
autoFocus
|
||||||
|
fullWidth
|
||||||
|
onChange={handleValueChange('v')}
|
||||||
|
endAdornment={
|
||||||
|
<InputAdornment position="end">
|
||||||
|
{DeviceValueUOM_s[devicevalue.u]}
|
||||||
|
</InputAdornment>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<FormHelperText>{devicevalue.n}</FormHelperText>
|
||||||
<Box color="warning.main" p={0} pl={0} pr={0} mt={4} mb={0}>
|
<Box color="warning.main" p={0} pl={0} pr={0} mt={4} mb={0}>
|
||||||
<Typography variant="body2">
|
<Typography variant="body2">
|
||||||
<i>
|
<i>
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ class GenerateToken extends React.Component<
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then((generatedToken) => {
|
.then((generatedToken) => {
|
||||||
// console.log(generatedToken);
|
|
||||||
this.setState({ token: generatedToken.token });
|
this.setState({ token: generatedToken.token });
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ class ManageUsersForm extends React.Component<
|
|||||||
<ValidatorForm onSubmit={this.onSubmit}>
|
<ValidatorForm onSubmit={this.onSubmit}>
|
||||||
<Table
|
<Table
|
||||||
size="small"
|
size="small"
|
||||||
padding={isWidthDown('xs', width!) ? 'none' : 'default'}
|
padding={isWidthDown('xs', width!) ? 'none' : 'normal'}
|
||||||
>
|
>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
@@ -197,7 +197,7 @@ class ManageUsersForm extends React.Component<
|
|||||||
<TableFooter>
|
<TableFooter>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell colSpan={2} />
|
<TableCell colSpan={2} />
|
||||||
<TableCell align="center" padding="default">
|
<TableCell align="center" padding="normal">
|
||||||
<Button
|
<Button
|
||||||
startIcon={<PersonAddIcon />}
|
startIcon={<PersonAddIcon />}
|
||||||
variant="contained"
|
variant="contained"
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import { useWindowSize } from '../components';
|
|||||||
|
|
||||||
interface LogEventConsoleProps {
|
interface LogEventConsoleProps {
|
||||||
events: LogEvent[];
|
events: LogEvent[];
|
||||||
|
compact: boolean;
|
||||||
|
level: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Offsets {
|
interface Offsets {
|
||||||
@@ -32,8 +34,8 @@ const useStyles = makeStyles((theme: Theme) => ({
|
|||||||
},
|
},
|
||||||
entry: {
|
entry: {
|
||||||
color: '#bbbbbb',
|
color: '#bbbbbb',
|
||||||
fontFamily: 'Courier New, monospace',
|
fontFamily: 'monospace',
|
||||||
fontSize: '13px',
|
fontSize: '14px',
|
||||||
letterSpacing: 'normal',
|
letterSpacing: 'normal',
|
||||||
whiteSpace: 'nowrap'
|
whiteSpace: 'nowrap'
|
||||||
},
|
},
|
||||||
@@ -63,7 +65,7 @@ const useStyles = makeStyles((theme: Theme) => ({
|
|||||||
const LogEventConsole: FC<LogEventConsoleProps> = (props) => {
|
const LogEventConsole: FC<LogEventConsoleProps> = (props) => {
|
||||||
useWindowSize();
|
useWindowSize();
|
||||||
const classes = useStyles({ topOffset, leftOffset });
|
const classes = useStyles({ topOffset, leftOffset });
|
||||||
const { events } = props;
|
const { events, compact } = props;
|
||||||
|
|
||||||
const styleLevel = (level: LogLevel) => {
|
const styleLevel = (level: LogLevel) => {
|
||||||
switch (level) {
|
switch (level) {
|
||||||
@@ -103,23 +105,34 @@ const LogEventConsole: FC<LogEventConsoleProps> = (props) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const paddedLevelLabel = (level: LogLevel) => {
|
const paddedLevelLabel = (level: LogLevel, compact: boolean) => {
|
||||||
const label = levelLabel(level);
|
const label = levelLabel(level);
|
||||||
return label.padStart(8, '\xa0');
|
return compact ? ' ' + label[0] : label.padStart(8, '\xa0');
|
||||||
};
|
};
|
||||||
|
|
||||||
const paddedNameLabel = (name: string) => {
|
const paddedNameLabel = (name: string, compact: boolean) => {
|
||||||
const label = '[' + name + ']';
|
const label = '[' + name + ']';
|
||||||
return label.padStart(8, '\xa0');
|
return compact ? label : label.padEnd(12, '\xa0');
|
||||||
|
};
|
||||||
|
|
||||||
|
const paddedIDLabel = (id: number, compact: boolean) => {
|
||||||
|
const label = id + ':';
|
||||||
|
return compact ? label : label.padEnd(7, '\xa0');
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box id="log-window" className={classes.console}>
|
<Box id="log-window" className={classes.console}>
|
||||||
{events.map((e) => (
|
{events.map((e) => (
|
||||||
<div className={classes.entry}>
|
<div className={classes.entry} key={e.i}>
|
||||||
<span>{e.t}</span>
|
<span>{e.t}</span>
|
||||||
<span className={styleLevel(e.l)}>{paddedLevelLabel(e.l)} </span>
|
{compact && <span>{paddedLevelLabel(e.l, compact)} </span>}
|
||||||
<span>{paddedNameLabel(e.n)} </span>
|
{!compact && (
|
||||||
|
<span className={styleLevel(e.l)}>
|
||||||
|
{paddedLevelLabel(e.l, compact)}{' '}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
<span>{paddedIDLabel(e.i, compact)} </span>
|
||||||
|
<span>{paddedNameLabel(e.n, compact)} </span>
|
||||||
<span>{e.m}</span>
|
<span>{e.m}</span>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -3,22 +3,38 @@ import { Component } from 'react';
|
|||||||
import {
|
import {
|
||||||
restController,
|
restController,
|
||||||
RestControllerProps,
|
RestControllerProps,
|
||||||
RestFormLoader,
|
SectionContent,
|
||||||
SectionContent
|
BlockFormControlLabel
|
||||||
} from '../components';
|
} from '../components';
|
||||||
|
|
||||||
import { addAccessTokenParameter } from '../authentication';
|
import {
|
||||||
|
ValidatorForm,
|
||||||
|
SelectValidator
|
||||||
|
} from 'react-material-ui-form-validator';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Grid,
|
||||||
|
Slider,
|
||||||
|
FormLabel,
|
||||||
|
Checkbox,
|
||||||
|
MenuItem,
|
||||||
|
Button
|
||||||
|
} from '@material-ui/core';
|
||||||
|
|
||||||
|
import {
|
||||||
|
addAccessTokenParameter,
|
||||||
|
redirectingAuthorizedFetch
|
||||||
|
} from '../authentication';
|
||||||
|
|
||||||
|
import DownloadIcon from '@material-ui/icons/GetApp';
|
||||||
|
|
||||||
import { ENDPOINT_ROOT, EVENT_SOURCE_ROOT } from '../api';
|
import { ENDPOINT_ROOT, EVENT_SOURCE_ROOT } from '../api';
|
||||||
export const FETCH_LOG_ENDPOINT = ENDPOINT_ROOT + 'fetchLog';
|
export const FETCH_LOG_ENDPOINT = ENDPOINT_ROOT + 'fetchLog';
|
||||||
export const LOG_SETTINGS_ENDPOINT = ENDPOINT_ROOT + 'logSettings';
|
export const LOG_SETTINGS_ENDPOINT = ENDPOINT_ROOT + 'logSettings';
|
||||||
|
|
||||||
export const LOG_EVENT_EVENT_SOURCE_URL = EVENT_SOURCE_ROOT + 'log';
|
export const LOG_EVENT_EVENT_SOURCE_URL = EVENT_SOURCE_ROOT + 'log';
|
||||||
|
|
||||||
import LogEventForm from './LogEventForm';
|
|
||||||
import LogEventConsole from './LogEventConsole';
|
import LogEventConsole from './LogEventConsole';
|
||||||
|
import { LogEvent, LogSettings, LogLevel } from './types';
|
||||||
import { LogEvent, LogSettings } from './types';
|
|
||||||
|
|
||||||
import { Decoder } from '@msgpack/msgpack';
|
import { Decoder } from '@msgpack/msgpack';
|
||||||
const decoder = new Decoder();
|
const decoder = new Decoder();
|
||||||
@@ -26,6 +42,10 @@ const decoder = new Decoder();
|
|||||||
interface LogEventControllerState {
|
interface LogEventControllerState {
|
||||||
eventSource?: EventSource;
|
eventSource?: EventSource;
|
||||||
events: LogEvent[];
|
events: LogEvent[];
|
||||||
|
compact: boolean;
|
||||||
|
level: number;
|
||||||
|
max_messages: number;
|
||||||
|
last_id: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
type LogEventControllerProps = RestControllerProps<LogSettings>;
|
type LogEventControllerProps = RestControllerProps<LogSettings>;
|
||||||
@@ -40,12 +60,16 @@ class LogEventController extends Component<
|
|||||||
constructor(props: LogEventControllerProps) {
|
constructor(props: LogEventControllerProps) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
events: []
|
events: [],
|
||||||
|
compact: false,
|
||||||
|
level: 6,
|
||||||
|
max_messages: 25,
|
||||||
|
last_id: 0
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.loadData();
|
this.fetchValues();
|
||||||
this.fetchLog();
|
this.fetchLog();
|
||||||
this.configureEventSource();
|
this.configureEventSource();
|
||||||
}
|
}
|
||||||
@@ -59,6 +83,20 @@ class LogEventController extends Component<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
changeCompact = (
|
||||||
|
event: React.ChangeEvent<HTMLInputElement>,
|
||||||
|
checked: boolean
|
||||||
|
) => {
|
||||||
|
this.setState({
|
||||||
|
compact: checked
|
||||||
|
});
|
||||||
|
this.send_data(
|
||||||
|
this.state.level,
|
||||||
|
this.state.max_messages,
|
||||||
|
checked as boolean
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
fetchLog = () => {
|
fetchLog = () => {
|
||||||
fetch(FETCH_LOG_ENDPOINT)
|
fetch(FETCH_LOG_ENDPOINT)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
@@ -78,6 +116,29 @@ class LogEventController extends Component<
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fetchValues = () => {
|
||||||
|
redirectingAuthorizedFetch(LOG_SETTINGS_ENDPOINT)
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
throw Error('Unexpected status code: ' + response.status);
|
||||||
|
})
|
||||||
|
.then((json) => {
|
||||||
|
this.setState({
|
||||||
|
level: json.level,
|
||||||
|
max_messages: json.max_messages,
|
||||||
|
compact: json.compact
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
const errorMessage = error.message || 'Unknown error';
|
||||||
|
this.props.enqueueSnackbar('Problem fetching: ' + errorMessage, {
|
||||||
|
variant: 'error'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
configureEventSource = () => {
|
configureEventSource = () => {
|
||||||
this.eventSource = new EventSource(
|
this.eventSource = new EventSource(
|
||||||
addAccessTokenParameter(LOG_EVENT_EVENT_SOURCE_URL)
|
addAccessTokenParameter(LOG_EVENT_EVENT_SOURCE_URL)
|
||||||
@@ -98,18 +159,183 @@ class LogEventController extends Component<
|
|||||||
const rawData = event.data;
|
const rawData = event.data;
|
||||||
if (typeof rawData === 'string' || rawData instanceof String) {
|
if (typeof rawData === 'string' || rawData instanceof String) {
|
||||||
const event = JSON.parse(rawData as string) as LogEvent;
|
const event = JSON.parse(rawData as string) as LogEvent;
|
||||||
|
if (event.i > this.state.last_id) {
|
||||||
|
this.setState({ last_id: event.i });
|
||||||
this.setState((state) => ({ events: [...state.events, event] }));
|
this.setState((state) => ({ events: [...state.events, event] }));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
changeMaxMessages = (
|
||||||
|
event: React.ChangeEvent<{}>,
|
||||||
|
value: number | number[]
|
||||||
|
) => {
|
||||||
|
this.setState({
|
||||||
|
max_messages: value as number
|
||||||
|
});
|
||||||
|
this.send_data(this.state.level, value as number, this.state.compact);
|
||||||
|
};
|
||||||
|
|
||||||
|
changeLevel = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
||||||
|
this.setState({
|
||||||
|
level: parseInt(event.target.value)
|
||||||
|
});
|
||||||
|
this.send_data(
|
||||||
|
parseInt(event.target.value),
|
||||||
|
this.state.max_messages,
|
||||||
|
this.state.compact
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
send_data = (level: number, max_messages: number, compact: boolean) => {
|
||||||
|
redirectingAuthorizedFetch(LOG_SETTINGS_ENDPOINT, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({
|
||||||
|
level: level,
|
||||||
|
max_messages: max_messages,
|
||||||
|
compact: compact
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status !== 200) {
|
||||||
|
throw Error('Unexpected response code: ' + response.status);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.props.enqueueSnackbar(
|
||||||
|
error.message || 'Problem applying log settings',
|
||||||
|
{ variant: 'warning' }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
levelLabel = (level: LogLevel) => {
|
||||||
|
switch (level) {
|
||||||
|
case LogLevel.ERROR:
|
||||||
|
return 'E';
|
||||||
|
case LogLevel.WARNING:
|
||||||
|
return 'W';
|
||||||
|
case LogLevel.NOTICE:
|
||||||
|
return 'N';
|
||||||
|
case LogLevel.INFO:
|
||||||
|
return 'I';
|
||||||
|
case LogLevel.DEBUG:
|
||||||
|
return 'D';
|
||||||
|
case LogLevel.TRACE:
|
||||||
|
return 'T';
|
||||||
|
default:
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onDownload = () => {
|
||||||
|
const { events } = this.state;
|
||||||
|
let result = '';
|
||||||
|
for (const i in events) {
|
||||||
|
result +=
|
||||||
|
events[i].t +
|
||||||
|
' ' +
|
||||||
|
this.levelLabel(events[i].l) +
|
||||||
|
' ' +
|
||||||
|
events[i].i +
|
||||||
|
': [' +
|
||||||
|
events[i].n +
|
||||||
|
'] ' +
|
||||||
|
events[i].m +
|
||||||
|
'\n';
|
||||||
|
}
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.setAttribute(
|
||||||
|
'href',
|
||||||
|
'data:text/plain;charset=utf-8,' + encodeURIComponent(result)
|
||||||
|
);
|
||||||
|
a.setAttribute('download', 'log.txt');
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
document.body.removeChild(a);
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const { saveData } = this.props;
|
||||||
return (
|
return (
|
||||||
<SectionContent title="System Log" id="log-window">
|
<SectionContent title="System Log" id="log-window">
|
||||||
<RestFormLoader
|
<ValidatorForm onSubmit={saveData}>
|
||||||
{...this.props}
|
<Grid
|
||||||
render={(formProps) => <LogEventForm {...formProps} />}
|
container
|
||||||
|
spacing={3}
|
||||||
|
direction="row"
|
||||||
|
justifyContent="flex-start"
|
||||||
|
alignItems="center"
|
||||||
|
>
|
||||||
|
<Grid item xs={2}>
|
||||||
|
<SelectValidator
|
||||||
|
name="level"
|
||||||
|
label="Log Level"
|
||||||
|
value={this.state.level}
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
onChange={this.changeLevel}
|
||||||
|
margin="normal"
|
||||||
|
>
|
||||||
|
<MenuItem value={3}>ERROR</MenuItem>
|
||||||
|
<MenuItem value={4}>WARNING</MenuItem>
|
||||||
|
<MenuItem value={5}>NOTICE</MenuItem>
|
||||||
|
<MenuItem value={6}>INFO</MenuItem>
|
||||||
|
<MenuItem value={7}>DEBUG</MenuItem>
|
||||||
|
<MenuItem value={8}>ALL</MenuItem>
|
||||||
|
</SelectValidator>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={2}>
|
||||||
|
<FormLabel>Buffer size</FormLabel>
|
||||||
|
<Slider
|
||||||
|
value={this.state.max_messages}
|
||||||
|
valueLabelDisplay="auto"
|
||||||
|
name="max_messages"
|
||||||
|
marks={[
|
||||||
|
{ value: 25, label: '25' },
|
||||||
|
{ value: 50, label: '50' },
|
||||||
|
{ value: 75, label: '75' },
|
||||||
|
{ value: 100, label: '100' }
|
||||||
|
]}
|
||||||
|
step={25}
|
||||||
|
min={25}
|
||||||
|
max={100}
|
||||||
|
onChange={this.changeMaxMessages}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={4}>
|
||||||
|
<BlockFormControlLabel
|
||||||
|
control={
|
||||||
|
<Checkbox
|
||||||
|
checked={this.state.compact}
|
||||||
|
onChange={this.changeCompact}
|
||||||
|
value="compact"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label="Compact Layout"
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid item md>
|
||||||
|
<Button
|
||||||
|
startIcon={<DownloadIcon />}
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
onClick={this.onDownload}
|
||||||
|
>
|
||||||
|
Download
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</ValidatorForm>
|
||||||
|
|
||||||
|
<LogEventConsole
|
||||||
|
level={this.state.level}
|
||||||
|
compact={this.state.compact}
|
||||||
|
events={this.state.events}
|
||||||
/>
|
/>
|
||||||
<LogEventConsole events={this.state.events} />
|
|
||||||
</SectionContent>
|
</SectionContent>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,107 +0,0 @@
|
|||||||
import { Component } from 'react';
|
|
||||||
|
|
||||||
import {
|
|
||||||
ValidatorForm,
|
|
||||||
SelectValidator
|
|
||||||
} from 'react-material-ui-form-validator';
|
|
||||||
|
|
||||||
import { Typography, Grid } from '@material-ui/core';
|
|
||||||
|
|
||||||
import MenuItem from '@material-ui/core/MenuItem';
|
|
||||||
|
|
||||||
import {
|
|
||||||
redirectingAuthorizedFetch,
|
|
||||||
withAuthenticatedContext,
|
|
||||||
AuthenticatedContextProps
|
|
||||||
} from '../authentication';
|
|
||||||
|
|
||||||
import { RestFormProps } from '../components';
|
|
||||||
import { LogSettings } from './types';
|
|
||||||
|
|
||||||
import { ENDPOINT_ROOT } from '../api';
|
|
||||||
export const LOG_SETTINGS_ENDPOINT = ENDPOINT_ROOT + 'logSettings';
|
|
||||||
|
|
||||||
type LogEventFormProps = AuthenticatedContextProps & RestFormProps<LogSettings>;
|
|
||||||
|
|
||||||
class LogEventForm extends Component<LogEventFormProps> {
|
|
||||||
changeLevel = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
|
||||||
const { data, setData } = this.props;
|
|
||||||
setData({
|
|
||||||
...data,
|
|
||||||
level: parseInt(event.target.value)
|
|
||||||
});
|
|
||||||
|
|
||||||
redirectingAuthorizedFetch(LOG_SETTINGS_ENDPOINT, {
|
|
||||||
method: 'POST',
|
|
||||||
body: JSON.stringify({ level: event.target.value }),
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
if (response.status === 200) {
|
|
||||||
return response.json();
|
|
||||||
}
|
|
||||||
throw Error('Unexpected response code: ' + response.status);
|
|
||||||
})
|
|
||||||
.then((json) => {
|
|
||||||
this.props.enqueueSnackbar('Log settings changed', {
|
|
||||||
variant: 'success'
|
|
||||||
});
|
|
||||||
setData({
|
|
||||||
...data,
|
|
||||||
level: json.level
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
this.props.enqueueSnackbar(
|
|
||||||
error.message || 'Problem changing log settings',
|
|
||||||
{ variant: 'warning' }
|
|
||||||
);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { data, saveData } = this.props;
|
|
||||||
return (
|
|
||||||
<ValidatorForm onSubmit={saveData}>
|
|
||||||
<Grid
|
|
||||||
container
|
|
||||||
spacing={0}
|
|
||||||
direction="row"
|
|
||||||
justify="flex-start"
|
|
||||||
alignItems="center"
|
|
||||||
>
|
|
||||||
<Grid item xs={2}>
|
|
||||||
<SelectValidator
|
|
||||||
name="level"
|
|
||||||
label="Log Level"
|
|
||||||
value={data.level}
|
|
||||||
variant="outlined"
|
|
||||||
onChange={this.changeLevel}
|
|
||||||
margin="normal"
|
|
||||||
>
|
|
||||||
<MenuItem value={-1}>OFF</MenuItem>
|
|
||||||
<MenuItem value={3}>ERROR</MenuItem>
|
|
||||||
<MenuItem value={4}>WARNING</MenuItem>
|
|
||||||
<MenuItem value={5}>NOTICE</MenuItem>
|
|
||||||
<MenuItem value={6}>INFO</MenuItem>
|
|
||||||
<MenuItem value={7}>DEBUG</MenuItem>
|
|
||||||
<MenuItem value={8}>ALL</MenuItem>
|
|
||||||
</SelectValidator>
|
|
||||||
</Grid>
|
|
||||||
<Grid item md>
|
|
||||||
<Typography color="primary" variant="body2">
|
|
||||||
<i>
|
|
||||||
(the last {data.max_messages} messages are buffered and new log
|
|
||||||
events are shown in real time)
|
|
||||||
</i>
|
|
||||||
</Typography>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</ValidatorForm>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default withAuthenticatedContext(LogEventForm);
|
|
||||||
@@ -33,15 +33,19 @@ import {
|
|||||||
AuthenticatedContextProps,
|
AuthenticatedContextProps,
|
||||||
withAuthenticatedContext
|
withAuthenticatedContext
|
||||||
} from '../authentication';
|
} from '../authentication';
|
||||||
|
|
||||||
import { RestFormProps, FormButton, ErrorButton } from '../components';
|
import { RestFormProps, FormButton, ErrorButton } from '../components';
|
||||||
import { FACTORY_RESET_ENDPOINT, RESTART_ENDPOINT } from '../api';
|
import { FACTORY_RESET_ENDPOINT, RESTART_ENDPOINT } from '../api';
|
||||||
|
|
||||||
import { SystemStatus, EspPlatform } from './types';
|
import { SystemStatus, EspPlatform } from './types';
|
||||||
|
|
||||||
|
import VersionCheck from './VersionCheck';
|
||||||
|
|
||||||
interface SystemStatusFormState {
|
interface SystemStatusFormState {
|
||||||
confirmRestart: boolean;
|
confirmRestart: boolean;
|
||||||
confirmFactoryReset: boolean;
|
confirmFactoryReset: boolean;
|
||||||
processing: boolean;
|
processing: boolean;
|
||||||
|
currentVersion?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
type SystemStatusFormProps = AuthenticatedContextProps &
|
type SystemStatusFormProps = AuthenticatedContextProps &
|
||||||
@@ -61,6 +65,16 @@ class SystemStatusForm extends Component<
|
|||||||
processing: false
|
processing: false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onVersionCheck = (version: string) => {
|
||||||
|
this.setState({ currentVersion: version });
|
||||||
|
};
|
||||||
|
|
||||||
|
closeVersionCheck = () => {
|
||||||
|
this.setState({
|
||||||
|
currentVersion: undefined
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
createListItems() {
|
createListItems() {
|
||||||
const { data } = this.props;
|
const { data } = this.props;
|
||||||
return (
|
return (
|
||||||
@@ -75,7 +89,14 @@ class SystemStatusForm extends Component<
|
|||||||
primary="EMS-ESP Version"
|
primary="EMS-ESP Version"
|
||||||
secondary={'v' + data.emsesp_version}
|
secondary={'v' + data.emsesp_version}
|
||||||
/>
|
/>
|
||||||
|
<Button
|
||||||
|
color="primary"
|
||||||
|
onClick={() => this.onVersionCheck(data.emsesp_version)}
|
||||||
|
>
|
||||||
|
Check for updates
|
||||||
|
</Button>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
<Divider variant="inset" component="li" />
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<ListItemAvatar>
|
<ListItemAvatar>
|
||||||
<Avatar>
|
<Avatar>
|
||||||
@@ -304,9 +325,16 @@ class SystemStatusForm extends Component<
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const me = this.props.authenticatedContext.me;
|
const me = this.props.authenticatedContext.me;
|
||||||
|
const { currentVersion } = this.state;
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<List>{this.createListItems()}</List>
|
<List>{this.createListItems()}</List>
|
||||||
|
{currentVersion && (
|
||||||
|
<VersionCheck
|
||||||
|
currentVersion={currentVersion}
|
||||||
|
onClose={this.closeVersionCheck}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<Box display="flex" flexWrap="wrap">
|
<Box display="flex" flexWrap="wrap">
|
||||||
<Box flexGrow={1} padding={1}>
|
<Box flexGrow={1} padding={1}>
|
||||||
<FormButton
|
<FormButton
|
||||||
|
|||||||
211
interface/src/system/VersionCheck.tsx
Normal file
211
interface/src/system/VersionCheck.tsx
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
import React, { Fragment } from 'react';
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogTitle,
|
||||||
|
DialogContent,
|
||||||
|
DialogActions,
|
||||||
|
Box,
|
||||||
|
Link,
|
||||||
|
LinearProgress,
|
||||||
|
Typography
|
||||||
|
} from '@material-ui/core';
|
||||||
|
|
||||||
|
import { FormButton } from '../components';
|
||||||
|
import { withSnackbar, WithSnackbarProps } from 'notistack';
|
||||||
|
|
||||||
|
export const VERSIONCHECK_ENDPOINT =
|
||||||
|
'https://api.github.com/repos/emsesp/EMS-ESP32/releases/latest';
|
||||||
|
|
||||||
|
export const VERSIONCHECK_DEV_ENDPOINT =
|
||||||
|
'https://api.github.com/repos/emsesp/EMS-ESP32/releases/tags/latest';
|
||||||
|
|
||||||
|
export const uploadURL = window.location.origin + '/system/upload';
|
||||||
|
|
||||||
|
interface VersionCheckProps extends WithSnackbarProps {
|
||||||
|
currentVersion: string;
|
||||||
|
onClose: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface VersionCheckState {
|
||||||
|
latestVersion?: string;
|
||||||
|
latestVersionUrl?: string;
|
||||||
|
latestVersionChangelog?: string;
|
||||||
|
latestDevVersion?: string;
|
||||||
|
latestDevVersionUrl?: string;
|
||||||
|
latestDevVersionChangelog?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
class VersionCheck extends React.Component<
|
||||||
|
VersionCheckProps,
|
||||||
|
VersionCheckState
|
||||||
|
> {
|
||||||
|
state: VersionCheckState = {};
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
fetch(VERSIONCHECK_ENDPOINT)
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
return response.json();
|
||||||
|
} else {
|
||||||
|
throw Error(
|
||||||
|
'Unable to get version information. Check internet connection. (' +
|
||||||
|
response.status +
|
||||||
|
')'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
this.setState({
|
||||||
|
latestVersion: data.name,
|
||||||
|
latestVersionUrl: data.assets[1].browser_download_url,
|
||||||
|
latestVersionChangelog: data.html_url
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.props.enqueueSnackbar(
|
||||||
|
error.message || 'Problem getting response',
|
||||||
|
{ variant: 'error' }
|
||||||
|
);
|
||||||
|
this.setState({ latestVersion: undefined });
|
||||||
|
this.props.onClose();
|
||||||
|
});
|
||||||
|
|
||||||
|
fetch(VERSIONCHECK_DEV_ENDPOINT)
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
return response.json();
|
||||||
|
} else {
|
||||||
|
throw Error(
|
||||||
|
'Unable to get version information. Check internet connection. (' +
|
||||||
|
response.status +
|
||||||
|
')'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
this.setState({
|
||||||
|
latestDevVersion: data.name.split(/\s+/).splice(-1),
|
||||||
|
latestDevVersionUrl: data.assets[1].browser_download_url,
|
||||||
|
latestDevVersionChangelog: data.assets[0].browser_download_url
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.props.enqueueSnackbar(
|
||||||
|
error.message || 'Problem getting response',
|
||||||
|
{ variant: 'error' }
|
||||||
|
);
|
||||||
|
this.setState({ latestDevVersion: undefined });
|
||||||
|
this.props.onClose();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { onClose, currentVersion } = this.props;
|
||||||
|
const {
|
||||||
|
latestVersion,
|
||||||
|
latestVersionUrl,
|
||||||
|
latestDevVersion,
|
||||||
|
latestDevVersionUrl,
|
||||||
|
latestVersionChangelog,
|
||||||
|
latestDevVersionChangelog
|
||||||
|
} = this.state;
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
onClose={onClose}
|
||||||
|
aria-labelledby="version-check-dialog-title"
|
||||||
|
open
|
||||||
|
fullWidth
|
||||||
|
maxWidth="sm"
|
||||||
|
>
|
||||||
|
<DialogTitle id="version-check-dialog-title">
|
||||||
|
Firmware Update Check
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogContent dividers>
|
||||||
|
{latestVersion ? (
|
||||||
|
<Fragment>
|
||||||
|
<Box
|
||||||
|
bgcolor="primary.main"
|
||||||
|
color="primary.contrastText"
|
||||||
|
p={2}
|
||||||
|
mt={2}
|
||||||
|
mb={2}
|
||||||
|
>
|
||||||
|
<Typography variant="body1">
|
||||||
|
You are currently running EMS-ESP version{' '}
|
||||||
|
<b>v{currentVersion}</b>
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<Box mt={2} mb={2}>
|
||||||
|
The latest <u>stable</u> version is <b>{latestVersion}</b>
|
||||||
|
(
|
||||||
|
<Link
|
||||||
|
target="_blank"
|
||||||
|
href={latestVersionChangelog}
|
||||||
|
color="primary"
|
||||||
|
>
|
||||||
|
{'release notes'}
|
||||||
|
</Link>
|
||||||
|
) (
|
||||||
|
<Link target="_blank" href={latestVersionUrl} color="primary">
|
||||||
|
{'download'}
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
</Box>
|
||||||
|
<Box mt={2} mb={2}>
|
||||||
|
The latest <u>development</u> version is
|
||||||
|
<b>{latestDevVersion}</b>
|
||||||
|
(
|
||||||
|
<Link
|
||||||
|
target="_blank"
|
||||||
|
href={latestDevVersionChangelog}
|
||||||
|
color="primary"
|
||||||
|
>
|
||||||
|
{'release notes'}
|
||||||
|
</Link>
|
||||||
|
) (
|
||||||
|
<Link
|
||||||
|
target="_blank"
|
||||||
|
href={latestDevVersionUrl}
|
||||||
|
color="primary"
|
||||||
|
>
|
||||||
|
{'download'}
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
</Box>
|
||||||
|
<Box color="warning.main" p={0} pl={0} pr={0} mt={4} mb={0}>
|
||||||
|
<Typography variant="body2">
|
||||||
|
<i>
|
||||||
|
Use
|
||||||
|
<Link target="_blank" href={uploadURL} color="primary">
|
||||||
|
{'UPLOAD FIRMWARE'}
|
||||||
|
</Link>
|
||||||
|
to install any new firmware versions.
|
||||||
|
</i>
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</Fragment>
|
||||||
|
) : (
|
||||||
|
<Box m={4} textAlign="center">
|
||||||
|
<LinearProgress />
|
||||||
|
<Typography variant="h6">
|
||||||
|
Fetching version details…
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<FormButton
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
type="submit"
|
||||||
|
onClick={onClose}
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</FormButton>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withSnackbar(VersionCheck);
|
||||||
@@ -50,6 +50,7 @@ export enum LogLevel {
|
|||||||
export interface LogEvent {
|
export interface LogEvent {
|
||||||
t: string;
|
t: string;
|
||||||
l: LogLevel;
|
l: LogLevel;
|
||||||
|
i: number;
|
||||||
n: string;
|
n: string;
|
||||||
m: string;
|
m: string;
|
||||||
}
|
}
|
||||||
@@ -57,4 +58,5 @@ export interface LogEvent {
|
|||||||
export interface LogSettings {
|
export interface LogSettings {
|
||||||
level: LogLevel;
|
level: LogLevel;
|
||||||
max_messages: number;
|
max_messages: number;
|
||||||
|
compact: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
33
interface/src/utils/binding.ts
Normal file
33
interface/src/utils/binding.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
type UpdateEntity<S> = (state: (prevState: Readonly<S>) => S) => void;
|
||||||
|
|
||||||
|
export const extractEventValue = (
|
||||||
|
event: React.ChangeEvent<HTMLInputElement>
|
||||||
|
) => {
|
||||||
|
switch (event.target.type) {
|
||||||
|
case 'number':
|
||||||
|
return event.target.valueAsNumber;
|
||||||
|
case 'checkbox':
|
||||||
|
return event.target.checked;
|
||||||
|
default:
|
||||||
|
return event.target.value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateValue = <S>(updateEntity: UpdateEntity<S>) => (
|
||||||
|
event: React.ChangeEvent<HTMLInputElement>
|
||||||
|
) => {
|
||||||
|
updateEntity((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
[event.target.name]: extractEventValue(event)
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateBooleanValue = <S>(updateEntity: UpdateEntity<S>) => (
|
||||||
|
name: string,
|
||||||
|
value?: boolean
|
||||||
|
) => {
|
||||||
|
updateEntity((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
[name]: value
|
||||||
|
}));
|
||||||
|
};
|
||||||
1
interface/src/utils/index.ts
Normal file
1
interface/src/utils/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from './binding';
|
||||||
@@ -3,3 +3,4 @@ export { default as isIP } from './isIP';
|
|||||||
export { default as optional } from './optional';
|
export { default as optional } from './optional';
|
||||||
export { default as or } from './or';
|
export { default as or } from './or';
|
||||||
export { default as isPath } from './isPath';
|
export { default as isPath } from './isPath';
|
||||||
|
export { default as isIPv4 } from './isIPv4';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
const ipAddressRegexp = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
|
const ipAddressRegexp = /((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$))/;
|
||||||
|
|
||||||
export default function isIp(ipAddress: string) {
|
export default function isIp(ipAddress: string) {
|
||||||
return ipAddressRegexp.test(ipAddress);
|
return ipAddressRegexp.test(ipAddress);
|
||||||
|
|||||||
5
interface/src/validators/isIPv4.ts
Normal file
5
interface/src/validators/isIPv4.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
const ipv4AddressRegexp = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
|
||||||
|
|
||||||
|
export default function isIpv4(ipAddress: string) {
|
||||||
|
return ipv4AddressRegexp.test(ipAddress);
|
||||||
|
}
|
||||||
@@ -1,6 +1,39 @@
|
|||||||
ArduinoJson: change log
|
ArduinoJson: change log
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
|
v6.18.4 (2021-09-06)
|
||||||
|
-------
|
||||||
|
|
||||||
|
* Fixed error `'dummy' may be used uninitialized` on GCC 11
|
||||||
|
* Fixed error `expected unqualified-id before 'const'` on GCC 11 (issue #1622)
|
||||||
|
* Filter: exact match takes precedence over wildcard (issue #1628)
|
||||||
|
* Fixed deserialization of `\u0000` (issue #1646)
|
||||||
|
|
||||||
|
v6.18.3 (2021-07-27)
|
||||||
|
-------
|
||||||
|
|
||||||
|
* Changed return type of `convertToJson()` and `Converter<T>::toJson()` to `void`
|
||||||
|
* Added `as<std::string_view>()` and `is<std::string_view>()`
|
||||||
|
|
||||||
|
v6.18.2 (2021-07-19)
|
||||||
|
-------
|
||||||
|
|
||||||
|
* Removed a symlink because the Arduino Library Specification forbids it
|
||||||
|
|
||||||
|
v6.18.1 (2021-07-03)
|
||||||
|
-------
|
||||||
|
|
||||||
|
* Fixed support for `volatile float` and `volatile double` (issue #1557)
|
||||||
|
* Fixed error `[Pe070]: incomplete type is not allowed` on IAR (issue #1560)
|
||||||
|
* Fixed `serializeJson(doc, String)` when allocation fails (issue #1572)
|
||||||
|
* Fixed clang-tidy warnings (issue #1574, PR #1577 by @armandas)
|
||||||
|
* Added fake class `InvalidConversion<T1,T2>` to easily identify invalid conversions (issue #1585)
|
||||||
|
* Added support for `std::string_view` (issue #1578, PR #1554 by @0xFEEDC0DE64)
|
||||||
|
* Fixed warning `definition of implicit copy constructor for 'MsgPackDeserializer' is deprecated because it has a user-declared copy assignment operator`
|
||||||
|
* Added `JsonArray::clear()` (issue #1597)
|
||||||
|
* Fixed `JsonVariant::as<unsigned>()` (issue #1601)
|
||||||
|
* Added support for ESP-IDF component build (PR #1562 by @qt1, PR #1599 by @andreaskuster)
|
||||||
|
|
||||||
v6.18.0 (2021-05-05)
|
v6.18.0 (2021-05-05)
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
[](https://www.ardu-badge.com/ArduinoJson/6.18.0)
|
[](https://www.ardu-badge.com/ArduinoJson/6.18.4)
|
||||||
[](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A6.x)
|
[](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A6.x)
|
||||||
[](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x)
|
[](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x)
|
||||||
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson)
|
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson)
|
||||||
@@ -33,15 +33,15 @@ ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things).
|
|||||||
* [Optionally works without heap memory (zero malloc)](https://arduinojson.org/v6/api/staticjsondocument/?utm_source=github&utm_medium=readme)
|
* [Optionally works without heap memory (zero malloc)](https://arduinojson.org/v6/api/staticjsondocument/?utm_source=github&utm_medium=readme)
|
||||||
* Deduplicates strings
|
* Deduplicates strings
|
||||||
* Versatile
|
* Versatile
|
||||||
* [Supports custom allocators (to use external RAM chip, for example)](https://arduinojson.org/v6/how-to/use-external-ram-on-esp32/?utm_source=github&utm_medium=readme)
|
* Supports [custom allocators (to use external RAM chip, for example)](https://arduinojson.org/v6/how-to/use-external-ram-on-esp32/?utm_source=github&utm_medium=readme)
|
||||||
* Supports [Arduino's `String`](https://arduinojson.org/v6/api/config/enable_arduino_string/?utm_source=github&utm_medium=readme) and [STL's `std::string`](https://arduinojson.org/v6/api/config/enable_std_string/?utm_source=github&utm_medium=readme)
|
* Supports [`String`](https://arduinojson.org/v6/api/config/enable_arduino_string/?utm_source=github&utm_medium=readme), [`std::string`](https://arduinojson.org/v6/api/config/enable_std_string/?utm_source=github&utm_medium=readme) and [`std::string_view`](https://arduinojson.org/v6/api/config/enable_string_view/?utm_source=github&utm_medium=readme)
|
||||||
* Supports [Arduino's `Stream`](https://arduinojson.org/v6/api/config/enable_arduino_stream/?utm_source=github&utm_medium=readme) and [STL's `std::istream`/`std::ostream`](https://arduinojson.org/v6/api/config/enable_std_stream/?utm_source=github&utm_medium=readme)
|
* Supports [`Stream`](https://arduinojson.org/v6/api/config/enable_arduino_stream/?utm_source=github&utm_medium=readme) and [`std::istream`/`std::ostream`](https://arduinojson.org/v6/api/config/enable_std_stream/?utm_source=github&utm_medium=readme)
|
||||||
* [Supports Flash strings](https://arduinojson.org/v6/api/config/enable_progmem/?utm_source=github&utm_medium=readme)
|
* Supports [Flash strings](https://arduinojson.org/v6/api/config/enable_progmem/?utm_source=github&utm_medium=readme)
|
||||||
* Supports [custom readers](https://arduinojson.org/v6/api/json/deserializejson/?utm_source=github&utm_medium=readme#custom-reader) and [custom writers](https://arduinojson.org/v6/api/json/serializejson/?utm_source=github&utm_medium=readme#custom-writer)
|
* Supports [custom readers](https://arduinojson.org/v6/api/json/deserializejson/?utm_source=github&utm_medium=readme#custom-reader) and [custom writers](https://arduinojson.org/v6/api/json/serializejson/?utm_source=github&utm_medium=readme#custom-writer)
|
||||||
* Supports custom converters
|
* Supports [custom converters](https://arduinojson.org/news/2021/05/04/version-6-18-0/?utm_source=github&utm_medium=readme)
|
||||||
* Portable
|
* Portable
|
||||||
* Usable on any C++ project (not limited to Arduino)
|
* Usable on any C++ project (not limited to Arduino)
|
||||||
* Compatible with C++98
|
* Compatible with C++98, C++11, C++14 and C++17
|
||||||
* Zero warnings with `-Wall -Wextra -pedantic` and `/W4`
|
* Zero warnings with `-Wall -Wextra -pedantic` and `/W4`
|
||||||
* [Header-only library](https://en.wikipedia.org/wiki/Header-only)
|
* [Header-only library](https://en.wikipedia.org/wiki/Header-only)
|
||||||
* Works with virtually any board
|
* Works with virtually any board
|
||||||
@@ -78,18 +78,20 @@ ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things).
|
|||||||
* [Unit test coverage close to 100%](https://coveralls.io/github/bblanchon/ArduinoJson?branch=6.x)
|
* [Unit test coverage close to 100%](https://coveralls.io/github/bblanchon/ArduinoJson?branch=6.x)
|
||||||
* Continuously tested on
|
* Continuously tested on
|
||||||
* [Visual Studio 2010, 2012, 2013, 2015, 2017, 2019](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x)
|
* [Visual Studio 2010, 2012, 2013, 2015, 2017, 2019](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x)
|
||||||
* [GCC 4.4, 4.6, 4.7, 4.8, 4.9, 5, 6, 7, 8, 9, 10](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22)
|
* [GCC 4.4, 4.6, 4.7, 4.8, 4.9, 5, 6, 7, 8, 9, 10, 11](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22)
|
||||||
* [Clang 3.5, 3.6, 3.7, 3.8, 3.9, 4.0, 5.0, 6.0, 7, 8, 9, 10](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22)
|
* [Clang 3.5, 3.6, 3.7, 3.8, 3.9, 4.0, 5.0, 6.0, 7, 8, 9, 10](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22)
|
||||||
* [Continuously fuzzed with Google OSS Fuzz](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson)
|
* [Continuously fuzzed with Google OSS Fuzz](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson)
|
||||||
|
* Passes all default checks of [clang-tidy](https://releases.llvm.org/10.0.0/tools/clang/tools/extra/docs/clang-tidy/)
|
||||||
* Well documented
|
* Well documented
|
||||||
* [Tutorials](https://arduinojson.org/v6/doc/deserialization/?utm_source=github&utm_medium=readme)
|
* [Tutorials](https://arduinojson.org/v6/doc/deserialization/?utm_source=github&utm_medium=readme)
|
||||||
* [Examples](https://arduinojson.org/v6/example/?utm_source=github&utm_medium=readme)
|
* [Examples](https://arduinojson.org/v6/example/?utm_source=github&utm_medium=readme)
|
||||||
* [How-tos](https://arduinojson.org/v6/example/?utm_source=github&utm_medium=readme)
|
* [How-tos](https://arduinojson.org/v6/example/?utm_source=github&utm_medium=readme)
|
||||||
* [FAQ](https://arduinojson.org/v6/faq/?utm_source=github&utm_medium=readme)
|
* [FAQ](https://arduinojson.org/v6/faq/?utm_source=github&utm_medium=readme)
|
||||||
|
* [Troubleshooter](https://arduinojson.org/v6/troubleshooter/?utm_source=github&utm_medium=readme)
|
||||||
* [Book](https://arduinojson.org/book/?utm_source=github&utm_medium=readme)
|
* [Book](https://arduinojson.org/book/?utm_source=github&utm_medium=readme)
|
||||||
* [Changelog](CHANGELOG.md)
|
* [Changelog](CHANGELOG.md)
|
||||||
* Vibrant user community
|
* Vibrant user community
|
||||||
* Most popular of all Arduino libraries on [GitHub](https://github.com/search?o=desc&q=arduino+library&s=stars&type=Repositories) and [PlatformIO](https://platformio.org/lib/search)
|
* Most popular of all Arduino libraries on [GitHub](https://github.com/search?o=desc&q=arduino+library&s=stars&type=Repositories)
|
||||||
* [Used in hundreds of projects](https://www.hackster.io/search?i=projects&q=arduinojson)
|
* [Used in hundreds of projects](https://www.hackster.io/search?i=projects&q=arduinojson)
|
||||||
* [Responsive support](https://github.com/bblanchon/ArduinoJson/issues?q=is%3Aissue+is%3Aclosed)
|
* [Responsive support](https://github.com/bblanchon/ArduinoJson/issues?q=is%3Aissue+is%3Aclosed)
|
||||||
|
|
||||||
@@ -132,9 +134,11 @@ serializeJson(doc, Serial);
|
|||||||
|
|
||||||
See the [tutorial on arduinojson.org](https://arduinojson.org/doc/encoding/?utm_source=github&utm_medium=readme)
|
See the [tutorial on arduinojson.org](https://arduinojson.org/doc/encoding/?utm_source=github&utm_medium=readme)
|
||||||
|
|
||||||
## Support the project
|
## Support the project ❤️
|
||||||
|
|
||||||
Do you like this library? Please [star this project on GitHub](https://github.com/bblanchon/ArduinoJson/stargazers)!
|
Do you like this library?
|
||||||
|
Please [star this project on GitHub](https://github.com/bblanchon/ArduinoJson/stargazers)!
|
||||||
|
|
||||||
What? You don't like it but you *love* it?
|
What? You don't like it but you *love* it?
|
||||||
We don't take donations anymore, but [we sell a book](https://arduinojson.org/book/?utm_source=github&utm_medium=readme), so you can help and learn at the same time.
|
You can support the project by [purchasing my book](https://arduinojson.org/book/?utm_source=github&utm_medium=readme).
|
||||||
|
Alternatively, you can make a recurring donation via [GitHub Sponsors](https://github.com/sponsors/bblanchon).
|
||||||
|
|||||||
@@ -161,14 +161,20 @@ class ArrayRef : public ArrayRefBase<CollectionData>,
|
|||||||
_data->removeElement(index);
|
_data->removeElement(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clear() const {
|
||||||
|
if (!_data)
|
||||||
|
return;
|
||||||
|
_data->clear();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MemoryPool* _pool;
|
MemoryPool* _pool;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct Converter<ArrayConstRef> {
|
struct Converter<ArrayConstRef> {
|
||||||
static bool toJson(VariantConstRef src, VariantRef dst) {
|
static void toJson(VariantConstRef src, VariantRef dst) {
|
||||||
return variantCopyFrom(getData(dst), getData(src), getPool(dst));
|
variantCopyFrom(getData(dst), getData(src), getPool(dst));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ArrayConstRef fromJson(VariantConstRef src) {
|
static ArrayConstRef fromJson(VariantConstRef src) {
|
||||||
@@ -183,8 +189,8 @@ struct Converter<ArrayConstRef> {
|
|||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct Converter<ArrayRef> {
|
struct Converter<ArrayRef> {
|
||||||
static bool toJson(VariantConstRef src, VariantRef dst) {
|
static void toJson(VariantConstRef src, VariantRef dst) {
|
||||||
return variantCopyFrom(getData(dst), getData(src), getPool(dst));
|
variantCopyFrom(getData(dst), getData(src), getPool(dst));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ArrayRef fromJson(VariantRef src) {
|
static ArrayRef fromJson(VariantRef src) {
|
||||||
@@ -193,6 +199,8 @@ struct Converter<ArrayRef> {
|
|||||||
return ArrayRef(pool, data != 0 ? data->asArray() : 0);
|
return ArrayRef(pool, data != 0 ? data->asArray() : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static InvalidConversion<VariantConstRef, ArrayRef> fromJson(VariantConstRef);
|
||||||
|
|
||||||
static bool checkJson(VariantConstRef) {
|
static bool checkJson(VariantConstRef) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -178,8 +178,8 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
|
|||||||
return _array.getOrAddElement(_index);
|
return _array.getOrAddElement(_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
friend bool convertToJson(const this_type& src, VariantRef dst) {
|
friend void convertToJson(const this_type& src, VariantRef dst) {
|
||||||
return dst.set(src.getUpstreamElement());
|
dst.set(src.getUpstreamElement());
|
||||||
}
|
}
|
||||||
|
|
||||||
TArray _array;
|
TArray _array;
|
||||||
|
|||||||
@@ -62,9 +62,9 @@ inline bool CollectionData::copyFrom(const CollectionData& src,
|
|||||||
VariantData* var;
|
VariantData* var;
|
||||||
if (s->key() != 0) {
|
if (s->key() != 0) {
|
||||||
if (s->ownsKey())
|
if (s->ownsKey())
|
||||||
var = addMember(RamStringAdapter(s->key()), pool);
|
var = addMember(adaptString(const_cast<char*>(s->key())), pool);
|
||||||
else
|
else
|
||||||
var = addMember(ConstRamStringAdapter(s->key()), pool);
|
var = addMember(adaptString(s->key()), pool);
|
||||||
} else {
|
} else {
|
||||||
var = addElement(pool);
|
var = addElement(pool);
|
||||||
}
|
}
|
||||||
@@ -107,7 +107,7 @@ template <typename TAdaptedString>
|
|||||||
inline VariantSlot* CollectionData::getSlot(TAdaptedString key) const {
|
inline VariantSlot* CollectionData::getSlot(TAdaptedString key) const {
|
||||||
VariantSlot* slot = _head;
|
VariantSlot* slot = _head;
|
||||||
while (slot) {
|
while (slot) {
|
||||||
if (key.equals(slot->key()))
|
if (key.compare(slot->key()) == 0)
|
||||||
break;
|
break;
|
||||||
slot = slot->next();
|
slot = slot->next();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,14 +6,20 @@
|
|||||||
|
|
||||||
#if __cplusplus >= 201103L
|
#if __cplusplus >= 201103L
|
||||||
# define ARDUINOJSON_HAS_LONG_LONG 1
|
# define ARDUINOJSON_HAS_LONG_LONG 1
|
||||||
#define ARDUINOJSON_HAS_NULLPTR 1
|
|
||||||
# define ARDUINOJSON_HAS_RVALUE_REFERENCES 1
|
# define ARDUINOJSON_HAS_RVALUE_REFERENCES 1
|
||||||
#else
|
#else
|
||||||
# define ARDUINOJSON_HAS_LONG_LONG 0
|
# define ARDUINOJSON_HAS_LONG_LONG 0
|
||||||
#define ARDUINOJSON_HAS_NULLPTR 0
|
|
||||||
# define ARDUINOJSON_HAS_RVALUE_REFERENCES 0
|
# define ARDUINOJSON_HAS_RVALUE_REFERENCES 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef ARDUINOJSON_HAS_NULLPTR
|
||||||
|
# if __cplusplus >= 201103L
|
||||||
|
# define ARDUINOJSON_HAS_NULLPTR 1
|
||||||
|
# else
|
||||||
|
# define ARDUINOJSON_HAS_NULLPTR 0
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !ARDUINOJSON_HAS_LONG_LONG
|
#if defined(_MSC_VER) && !ARDUINOJSON_HAS_LONG_LONG
|
||||||
# define ARDUINOJSON_HAS_INT64 1
|
# define ARDUINOJSON_HAS_INT64 1
|
||||||
#else
|
#else
|
||||||
@@ -56,6 +62,17 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef ARDUINOJSON_ENABLE_STRING_VIEW
|
||||||
|
# ifdef __has_include
|
||||||
|
# if __has_include(<string_view>) && __cplusplus >= 201703L
|
||||||
|
# define ARDUINOJSON_ENABLE_STRING_VIEW 1
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#ifndef ARDUINOJSON_ENABLE_STRING_VIEW
|
||||||
|
# define ARDUINOJSON_ENABLE_STRING_VIEW 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ARDUINOJSON_EMBEDDED_MODE
|
#if ARDUINOJSON_EMBEDDED_MODE
|
||||||
|
|
||||||
// Store floats by default to reduce the memory usage (issue #134)
|
// Store floats by default to reduce the memory usage (issue #134)
|
||||||
@@ -213,7 +230,8 @@
|
|||||||
|
|
||||||
#ifndef ARDUINOJSON_LITTLE_ENDIAN
|
#ifndef ARDUINOJSON_LITTLE_ENDIAN
|
||||||
# if defined(_MSC_VER) || \
|
# if defined(_MSC_VER) || \
|
||||||
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \
|
(defined(__BYTE_ORDER__) && \
|
||||||
|
__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \
|
||||||
defined(__LITTLE_ENDIAN__) || defined(__i386) || defined(__x86_64)
|
defined(__LITTLE_ENDIAN__) || defined(__i386) || defined(__x86_64)
|
||||||
# define ARDUINOJSON_LITTLE_ENDIAN 1
|
# define ARDUINOJSON_LITTLE_ENDIAN 1
|
||||||
# else
|
# else
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ class Filter {
|
|||||||
Filter operator[](const TKey& key) const {
|
Filter operator[](const TKey& key) const {
|
||||||
if (_variant == true) // "true" means "allow recursively"
|
if (_variant == true) // "true" means "allow recursively"
|
||||||
return *this;
|
return *this;
|
||||||
else
|
VariantConstRef member = _variant[key];
|
||||||
return Filter(_variant[key] | _variant["*"]);
|
return Filter(member.isNull() ? _variant["*"] : member);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ struct Reader {
|
|||||||
Reader(TSource& source) : _source(&source) {}
|
Reader(TSource& source) : _source(&source) {}
|
||||||
|
|
||||||
int read() {
|
int read() {
|
||||||
return _source->read();
|
return _source->read(); // Error here? You passed an unsupported input type
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t readBytes(char* buffer, size_t length) {
|
size_t readBytes(char* buffer, size_t length) {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class JsonDocument : public Visitable {
|
|||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
_pool.clear();
|
_pool.clear();
|
||||||
_data.setNull();
|
_data.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@@ -304,15 +304,15 @@ class JsonDocument : public Visitable {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
JsonDocument() : _pool(0, 0) {
|
JsonDocument() : _pool(0, 0) {
|
||||||
_data.setNull();
|
_data.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonDocument(MemoryPool pool) : _pool(pool) {
|
JsonDocument(MemoryPool pool) : _pool(pool) {
|
||||||
_data.setNull();
|
_data.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonDocument(char* buf, size_t capa) : _pool(buf, capa) {
|
JsonDocument(char* buf, size_t capa) : _pool(buf, capa) {
|
||||||
_data.setNull();
|
_data.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
~JsonDocument() {}
|
~JsonDocument() {}
|
||||||
@@ -337,8 +337,8 @@ class JsonDocument : public Visitable {
|
|||||||
JsonDocument& operator=(const JsonDocument&);
|
JsonDocument& operator=(const JsonDocument&);
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool convertToJson(const JsonDocument& src, VariantRef dst) {
|
inline void convertToJson(const JsonDocument& src, VariantRef dst) {
|
||||||
return dst.set(src.as<VariantConstRef>());
|
dst.set(src.as<VariantConstRef>());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -45,7 +45,8 @@ class Latch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TReader _reader;
|
TReader _reader;
|
||||||
char _current;
|
char _current; // NOLINT(clang-analyzer-optin.cplusplus.UninitializedObject)
|
||||||
|
// Not initialized in constructor (+10 bytes on AVR)
|
||||||
bool _loaded;
|
bool _loaded;
|
||||||
#if ARDUINOJSON_DEBUG
|
#if ARDUINOJSON_DEBUG
|
||||||
bool _ended;
|
bool _ended;
|
||||||
|
|||||||
@@ -155,7 +155,6 @@ class TextFormatter {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
CountingDecorator<TWriter> _writer;
|
CountingDecorator<TWriter> _writer;
|
||||||
size_t _length;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TextFormatter &operator=(const TextFormatter &); // cannot be assigned
|
TextFormatter &operator=(const TextFormatter &); // cannot be assigned
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ inline bool isLowSurrogate(uint16_t codeunit) {
|
|||||||
|
|
||||||
class Codepoint {
|
class Codepoint {
|
||||||
public:
|
public:
|
||||||
Codepoint() : _highSurrogate(0) {}
|
Codepoint() : _highSurrogate(0), _codepoint(0) {}
|
||||||
|
|
||||||
bool append(uint16_t codeunit) {
|
bool append(uint16_t codeunit) {
|
||||||
if (isHighSurrogate(codeunit)) {
|
if (isHighSurrogate(codeunit)) {
|
||||||
|
|||||||
@@ -13,14 +13,14 @@ template <typename TStringBuilder>
|
|||||||
inline void encodeCodepoint(uint32_t codepoint32, TStringBuilder& str) {
|
inline void encodeCodepoint(uint32_t codepoint32, TStringBuilder& str) {
|
||||||
// this function was optimize for code size on AVR
|
// this function was optimize for code size on AVR
|
||||||
|
|
||||||
|
if (codepoint32 < 0x80) {
|
||||||
|
str.append(char(codepoint32));
|
||||||
|
} else {
|
||||||
// a buffer to store the string in reverse
|
// a buffer to store the string in reverse
|
||||||
char buf[5];
|
char buf[5];
|
||||||
char* p = buf;
|
char* p = buf;
|
||||||
|
|
||||||
*(p++) = 0;
|
*(p++) = 0;
|
||||||
if (codepoint32 < 0x80) {
|
|
||||||
*(p++) = char((codepoint32));
|
|
||||||
} else {
|
|
||||||
*(p++) = char((codepoint32 | 0x80) & 0xBF);
|
*(p++) = char((codepoint32 | 0x80) & 0xBF);
|
||||||
uint16_t codepoint16 = uint16_t(codepoint32 >> 6);
|
uint16_t codepoint16 = uint16_t(codepoint32 >> 6);
|
||||||
if (codepoint16 < 0x20) { // 0x800
|
if (codepoint16 < 0x20) { // 0x800
|
||||||
@@ -36,11 +36,11 @@ inline void encodeCodepoint(uint32_t codepoint32, TStringBuilder& str) {
|
|||||||
*(p++) = char(codepoint16 | 0xF0);
|
*(p++) = char(codepoint16 | 0xF0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
while (*(--p)) {
|
while (*(--p)) {
|
||||||
str.append(*p);
|
str.append(*p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} // namespace Utf8
|
} // namespace Utf8
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <ArduinoJson/Memory/Alignment.hpp>
|
#include <ArduinoJson/Memory/Alignment.hpp>
|
||||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||||
#include <ArduinoJson/Polyfills/mpl/max.hpp>
|
#include <ArduinoJson/Polyfills/mpl/max.hpp>
|
||||||
|
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantSlot.hpp>
|
#include <ArduinoJson/Variant/VariantSlot.hpp>
|
||||||
|
|
||||||
#include <string.h> // memmove
|
#include <string.h> // memmove
|
||||||
@@ -37,7 +38,8 @@ class MemoryPool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void* buffer() {
|
void* buffer() {
|
||||||
return _begin;
|
return _begin; // NOLINT(clang-analyzer-unix.Malloc)
|
||||||
|
// movePointers() alters this pointer
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the capacity of the memoryPool in bytes
|
// Gets the capacity of the memoryPool in bytes
|
||||||
@@ -63,7 +65,7 @@ class MemoryPool {
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
|
#if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
|
||||||
const char* existingCopy = findString(str.begin());
|
const char* existingCopy = findString(str);
|
||||||
if (existingCopy)
|
if (existingCopy)
|
||||||
return existingCopy;
|
return existingCopy;
|
||||||
#endif
|
#endif
|
||||||
@@ -85,7 +87,7 @@ class MemoryPool {
|
|||||||
|
|
||||||
const char* saveStringFromFreeZone(size_t len) {
|
const char* saveStringFromFreeZone(size_t len) {
|
||||||
#if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
|
#if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
|
||||||
const char* dup = findString(_left);
|
const char* dup = findString(adaptString(_left));
|
||||||
if (dup)
|
if (dup)
|
||||||
return dup;
|
return dup;
|
||||||
#endif
|
#endif
|
||||||
@@ -162,16 +164,11 @@ class MemoryPool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
|
#if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
|
||||||
template <typename TIterator>
|
template <typename TAdaptedString>
|
||||||
const char* findString(TIterator str) {
|
const char* findString(const TAdaptedString& str) {
|
||||||
for (char* next = _begin; next < _left; ++next) {
|
for (char* next = _begin; next < _left; ++next) {
|
||||||
char* begin = next;
|
if (str.compare(next) == 0)
|
||||||
|
return next;
|
||||||
// try to match
|
|
||||||
for (TIterator it = str; *it == *next; ++it) {
|
|
||||||
if (*next++ == 0)
|
|
||||||
return begin;
|
|
||||||
}
|
|
||||||
|
|
||||||
// jump to next terminator
|
// jump to next terminator
|
||||||
while (*next) ++next;
|
while (*next) ++next;
|
||||||
|
|||||||
@@ -16,31 +16,30 @@ namespace ARDUINOJSON_NAMESPACE {
|
|||||||
template <typename TReader, typename TStringStorage>
|
template <typename TReader, typename TStringStorage>
|
||||||
class MsgPackDeserializer {
|
class MsgPackDeserializer {
|
||||||
public:
|
public:
|
||||||
MsgPackDeserializer(MemoryPool & pool, TReader reader, TStringStorage stringStorage)
|
MsgPackDeserializer(MemoryPool &pool, TReader reader,
|
||||||
: _pool(&pool)
|
TStringStorage stringStorage)
|
||||||
, _reader(reader)
|
: _pool(&pool),
|
||||||
, _stringStorage(stringStorage)
|
_reader(reader),
|
||||||
, _error(DeserializationError::Ok)
|
_stringStorage(stringStorage),
|
||||||
, _foundSomething(false) {
|
_error(DeserializationError::Ok),
|
||||||
}
|
_foundSomething(false) {}
|
||||||
|
|
||||||
template <typename TFilter>
|
template <typename TFilter>
|
||||||
DeserializationError parse(VariantData & variant, TFilter filter, NestingLimit nestingLimit) {
|
DeserializationError parse(VariantData &variant, TFilter filter,
|
||||||
|
NestingLimit nestingLimit) {
|
||||||
parseVariant(&variant, filter, nestingLimit);
|
parseVariant(&variant, filter, nestingLimit);
|
||||||
return _foundSomething ? _error : DeserializationError::EmptyInput;
|
return _foundSomething ? _error : DeserializationError::EmptyInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Prevent VS warning "assignment operator could not be generated"
|
|
||||||
MsgPackDeserializer & operator=(const MsgPackDeserializer &);
|
|
||||||
|
|
||||||
bool invalidInput() {
|
bool invalidInput() {
|
||||||
_error = DeserializationError::InvalidInput;
|
_error = DeserializationError::InvalidInput;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TFilter>
|
template <typename TFilter>
|
||||||
bool parseVariant(VariantData * variant, TFilter filter, NestingLimit nestingLimit) {
|
bool parseVariant(VariantData *variant, TFilter filter,
|
||||||
|
NestingLimit nestingLimit) {
|
||||||
uint8_t code = 0;
|
uint8_t code = 0;
|
||||||
if (!readByte(code))
|
if (!readByte(code))
|
||||||
return false;
|
return false;
|
||||||
@@ -270,7 +269,8 @@ class MsgPackDeserializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename enable_if<sizeof(T) == 4, bool>::type readFloat(VariantData * variant) {
|
typename enable_if<sizeof(T) == 4, bool>::type readFloat(
|
||||||
|
VariantData *variant) {
|
||||||
T value;
|
T value;
|
||||||
if (!readBytes(value))
|
if (!readBytes(value))
|
||||||
return false;
|
return false;
|
||||||
@@ -280,7 +280,8 @@ class MsgPackDeserializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename enable_if<sizeof(T) == 8, bool>::type readDouble(VariantData * variant) {
|
typename enable_if<sizeof(T) == 8, bool>::type readDouble(
|
||||||
|
VariantData *variant) {
|
||||||
T value;
|
T value;
|
||||||
if (!readBytes(value))
|
if (!readBytes(value))
|
||||||
return false;
|
return false;
|
||||||
@@ -290,7 +291,8 @@ class MsgPackDeserializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename enable_if<sizeof(T) == 4, bool>::type readDouble(VariantData * variant) {
|
typename enable_if<sizeof(T) == 4, bool>::type readDouble(
|
||||||
|
VariantData *variant) {
|
||||||
uint8_t i[8]; // input is 8 bytes
|
uint8_t i[8]; // input is 8 bytes
|
||||||
T value; // output is 4 bytes
|
T value; // output is 4 bytes
|
||||||
uint8_t *o = reinterpret_cast<uint8_t *>(&value);
|
uint8_t *o = reinterpret_cast<uint8_t *>(&value);
|
||||||
@@ -329,7 +331,8 @@ class MsgPackDeserializer {
|
|||||||
bool readString(VariantData *variant, size_t n) {
|
bool readString(VariantData *variant, size_t n) {
|
||||||
if (!readString(n))
|
if (!readString(n))
|
||||||
return false;
|
return false;
|
||||||
variant->setStringPointer(_stringStorage.save(), typename TStringStorage::storage_policy());
|
variant->setStringPointer(_stringStorage.save(),
|
||||||
|
typename TStringStorage::storage_policy());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,7 +354,8 @@ class MsgPackDeserializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename TSize, typename TFilter>
|
template <typename TSize, typename TFilter>
|
||||||
bool readArray(VariantData * variant, TFilter filter, NestingLimit nestingLimit) {
|
bool readArray(VariantData *variant, TFilter filter,
|
||||||
|
NestingLimit nestingLimit) {
|
||||||
TSize size;
|
TSize size;
|
||||||
if (!readInteger(size))
|
if (!readInteger(size))
|
||||||
return false;
|
return false;
|
||||||
@@ -359,7 +363,8 @@ class MsgPackDeserializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename TFilter>
|
template <typename TFilter>
|
||||||
bool readArray(VariantData * variant, size_t n, TFilter filter, NestingLimit nestingLimit) {
|
bool readArray(VariantData *variant, size_t n, TFilter filter,
|
||||||
|
NestingLimit nestingLimit) {
|
||||||
if (nestingLimit.reached()) {
|
if (nestingLimit.reached()) {
|
||||||
_error = DeserializationError::TooDeep;
|
_error = DeserializationError::TooDeep;
|
||||||
return false;
|
return false;
|
||||||
@@ -392,7 +397,8 @@ class MsgPackDeserializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename TSize, typename TFilter>
|
template <typename TSize, typename TFilter>
|
||||||
bool readObject(VariantData * variant, TFilter filter, NestingLimit nestingLimit) {
|
bool readObject(VariantData *variant, TFilter filter,
|
||||||
|
NestingLimit nestingLimit) {
|
||||||
TSize size;
|
TSize size;
|
||||||
if (!readInteger(size))
|
if (!readInteger(size))
|
||||||
return false;
|
return false;
|
||||||
@@ -400,7 +406,8 @@ class MsgPackDeserializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename TFilter>
|
template <typename TFilter>
|
||||||
bool readObject(VariantData * variant, size_t n, TFilter filter, NestingLimit nestingLimit) {
|
bool readObject(VariantData *variant, size_t n, TFilter filter,
|
||||||
|
NestingLimit nestingLimit) {
|
||||||
if (nestingLimit.reached()) {
|
if (nestingLimit.reached()) {
|
||||||
_error = DeserializationError::TooDeep;
|
_error = DeserializationError::TooDeep;
|
||||||
return false;
|
return false;
|
||||||
@@ -484,17 +491,24 @@ class MsgPackDeserializer {
|
|||||||
//
|
//
|
||||||
// ... = NestingLimit
|
// ... = NestingLimit
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
DeserializationError deserializeMsgPack(JsonDocument & doc, const TString & input, NestingLimit nestingLimit = NestingLimit()) {
|
DeserializationError deserializeMsgPack(
|
||||||
return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, AllowAllFilter());
|
JsonDocument &doc, const TString &input,
|
||||||
|
NestingLimit nestingLimit = NestingLimit()) {
|
||||||
|
return deserialize<MsgPackDeserializer>(doc, input, nestingLimit,
|
||||||
|
AllowAllFilter());
|
||||||
}
|
}
|
||||||
// ... = Filter, NestingLimit
|
// ... = Filter, NestingLimit
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
DeserializationError deserializeMsgPack(JsonDocument & doc, const TString & input, Filter filter, NestingLimit nestingLimit = NestingLimit()) {
|
DeserializationError deserializeMsgPack(
|
||||||
|
JsonDocument &doc, const TString &input, Filter filter,
|
||||||
|
NestingLimit nestingLimit = NestingLimit()) {
|
||||||
return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter);
|
return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter);
|
||||||
}
|
}
|
||||||
// ... = NestingLimit, Filter
|
// ... = NestingLimit, Filter
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
DeserializationError deserializeMsgPack(JsonDocument & doc, const TString & input, NestingLimit nestingLimit, Filter filter) {
|
DeserializationError deserializeMsgPack(JsonDocument &doc, const TString &input,
|
||||||
|
NestingLimit nestingLimit,
|
||||||
|
Filter filter) {
|
||||||
return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter);
|
return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -503,17 +517,24 @@ DeserializationError deserializeMsgPack(JsonDocument & doc, const TString & inpu
|
|||||||
//
|
//
|
||||||
// ... = NestingLimit
|
// ... = NestingLimit
|
||||||
template <typename TStream>
|
template <typename TStream>
|
||||||
DeserializationError deserializeMsgPack(JsonDocument & doc, TStream & input, NestingLimit nestingLimit = NestingLimit()) {
|
DeserializationError deserializeMsgPack(
|
||||||
return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, AllowAllFilter());
|
JsonDocument &doc, TStream &input,
|
||||||
|
NestingLimit nestingLimit = NestingLimit()) {
|
||||||
|
return deserialize<MsgPackDeserializer>(doc, input, nestingLimit,
|
||||||
|
AllowAllFilter());
|
||||||
}
|
}
|
||||||
// ... = Filter, NestingLimit
|
// ... = Filter, NestingLimit
|
||||||
template <typename TStream>
|
template <typename TStream>
|
||||||
DeserializationError deserializeMsgPack(JsonDocument & doc, TStream & input, Filter filter, NestingLimit nestingLimit = NestingLimit()) {
|
DeserializationError deserializeMsgPack(
|
||||||
|
JsonDocument &doc, TStream &input, Filter filter,
|
||||||
|
NestingLimit nestingLimit = NestingLimit()) {
|
||||||
return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter);
|
return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter);
|
||||||
}
|
}
|
||||||
// ... = NestingLimit, Filter
|
// ... = NestingLimit, Filter
|
||||||
template <typename TStream>
|
template <typename TStream>
|
||||||
DeserializationError deserializeMsgPack(JsonDocument & doc, TStream & input, NestingLimit nestingLimit, Filter filter) {
|
DeserializationError deserializeMsgPack(JsonDocument &doc, TStream &input,
|
||||||
|
NestingLimit nestingLimit,
|
||||||
|
Filter filter) {
|
||||||
return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter);
|
return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -522,17 +543,24 @@ DeserializationError deserializeMsgPack(JsonDocument & doc, TStream & input, Nes
|
|||||||
//
|
//
|
||||||
// ... = NestingLimit
|
// ... = NestingLimit
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
DeserializationError deserializeMsgPack(JsonDocument & doc, TChar * input, NestingLimit nestingLimit = NestingLimit()) {
|
DeserializationError deserializeMsgPack(
|
||||||
return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, AllowAllFilter());
|
JsonDocument &doc, TChar *input,
|
||||||
|
NestingLimit nestingLimit = NestingLimit()) {
|
||||||
|
return deserialize<MsgPackDeserializer>(doc, input, nestingLimit,
|
||||||
|
AllowAllFilter());
|
||||||
}
|
}
|
||||||
// ... = Filter, NestingLimit
|
// ... = Filter, NestingLimit
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
DeserializationError deserializeMsgPack(JsonDocument & doc, TChar * input, Filter filter, NestingLimit nestingLimit = NestingLimit()) {
|
DeserializationError deserializeMsgPack(
|
||||||
|
JsonDocument &doc, TChar *input, Filter filter,
|
||||||
|
NestingLimit nestingLimit = NestingLimit()) {
|
||||||
return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter);
|
return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter);
|
||||||
}
|
}
|
||||||
// ... = NestingLimit, Filter
|
// ... = NestingLimit, Filter
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
DeserializationError deserializeMsgPack(JsonDocument & doc, TChar * input, NestingLimit nestingLimit, Filter filter) {
|
DeserializationError deserializeMsgPack(JsonDocument &doc, TChar *input,
|
||||||
|
NestingLimit nestingLimit,
|
||||||
|
Filter filter) {
|
||||||
return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter);
|
return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,18 +569,28 @@ DeserializationError deserializeMsgPack(JsonDocument & doc, TChar * input, Nesti
|
|||||||
//
|
//
|
||||||
// ... = NestingLimit
|
// ... = NestingLimit
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
DeserializationError deserializeMsgPack(JsonDocument & doc, TChar * input, size_t inputSize, NestingLimit nestingLimit = NestingLimit()) {
|
DeserializationError deserializeMsgPack(
|
||||||
return deserialize<MsgPackDeserializer>(doc, input, inputSize, nestingLimit, AllowAllFilter());
|
JsonDocument &doc, TChar *input, size_t inputSize,
|
||||||
|
NestingLimit nestingLimit = NestingLimit()) {
|
||||||
|
return deserialize<MsgPackDeserializer>(doc, input, inputSize, nestingLimit,
|
||||||
|
AllowAllFilter());
|
||||||
}
|
}
|
||||||
// ... = Filter, NestingLimit
|
// ... = Filter, NestingLimit
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
DeserializationError deserializeMsgPack(JsonDocument & doc, TChar * input, size_t inputSize, Filter filter, NestingLimit nestingLimit = NestingLimit()) {
|
DeserializationError deserializeMsgPack(
|
||||||
return deserialize<MsgPackDeserializer>(doc, input, inputSize, nestingLimit, filter);
|
JsonDocument &doc, TChar *input, size_t inputSize, Filter filter,
|
||||||
|
NestingLimit nestingLimit = NestingLimit()) {
|
||||||
|
return deserialize<MsgPackDeserializer>(doc, input, inputSize, nestingLimit,
|
||||||
|
filter);
|
||||||
}
|
}
|
||||||
// ... = NestingLimit, Filter
|
// ... = NestingLimit, Filter
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
DeserializationError deserializeMsgPack(JsonDocument & doc, TChar * input, size_t inputSize, NestingLimit nestingLimit, Filter filter) {
|
DeserializationError deserializeMsgPack(JsonDocument &doc, TChar *input,
|
||||||
return deserialize<MsgPackDeserializer>(doc, input, inputSize, nestingLimit, filter);
|
size_t inputSize,
|
||||||
|
NestingLimit nestingLimit,
|
||||||
|
Filter filter) {
|
||||||
|
return deserialize<MsgPackDeserializer>(doc, input, inputSize, nestingLimit,
|
||||||
|
filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -16,9 +16,9 @@
|
|||||||
ARDUINOJSON_VERSION_MINOR, \
|
ARDUINOJSON_VERSION_MINOR, \
|
||||||
ARDUINOJSON_VERSION_REVISION), \
|
ARDUINOJSON_VERSION_REVISION), \
|
||||||
_, \
|
_, \
|
||||||
ARDUINOJSON_HEX_DIGIT(ARDUINOJSON_ENABLE_PROGMEM, \
|
ARDUINOJSON_HEX_DIGIT( \
|
||||||
ARDUINOJSON_USE_LONG_LONG, ARDUINOJSON_USE_DOUBLE, \
|
ARDUINOJSON_ENABLE_PROGMEM, ARDUINOJSON_USE_LONG_LONG, \
|
||||||
ARDUINOJSON_ENABLE_STRING_DEDUPLICATION), \
|
ARDUINOJSON_USE_DOUBLE, ARDUINOJSON_ENABLE_STRING_DEDUPLICATION), \
|
||||||
ARDUINOJSON_HEX_DIGIT( \
|
ARDUINOJSON_HEX_DIGIT( \
|
||||||
ARDUINOJSON_ENABLE_NAN, ARDUINOJSON_ENABLE_INFINITY, \
|
ARDUINOJSON_ENABLE_NAN, ARDUINOJSON_ENABLE_INFINITY, \
|
||||||
ARDUINOJSON_ENABLE_COMMENTS, ARDUINOJSON_DECODE_UNICODE))
|
ARDUINOJSON_ENABLE_COMMENTS, ARDUINOJSON_DECODE_UNICODE))
|
||||||
|
|||||||
@@ -71,9 +71,23 @@ canConvertNumber(TIn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// int32 -> uint32
|
// int32 -> uint32
|
||||||
|
// int32 -> uint64
|
||||||
template <typename TOut, typename TIn>
|
template <typename TOut, typename TIn>
|
||||||
typename enable_if<is_integral<TIn>::value && is_signed<TIn>::value &&
|
typename enable_if<is_integral<TIn>::value && is_signed<TIn>::value &&
|
||||||
is_integral<TOut>::value && is_unsigned<TOut>::value,
|
is_integral<TOut>::value && is_unsigned<TOut>::value &&
|
||||||
|
sizeof(TOut) >= sizeof(TIn),
|
||||||
|
bool>::type
|
||||||
|
canConvertNumber(TIn value) {
|
||||||
|
if (value < 0)
|
||||||
|
return false;
|
||||||
|
return TOut(value) <= numeric_limits<TOut>::highest();
|
||||||
|
}
|
||||||
|
|
||||||
|
// int32 -> uint16
|
||||||
|
template <typename TOut, typename TIn>
|
||||||
|
typename enable_if<is_integral<TIn>::value && is_signed<TIn>::value &&
|
||||||
|
is_integral<TOut>::value && is_unsigned<TOut>::value &&
|
||||||
|
sizeof(TOut) < sizeof(TIn),
|
||||||
bool>::type
|
bool>::type
|
||||||
canConvertNumber(TIn value) {
|
canConvertNumber(TIn value) {
|
||||||
if (value < 0)
|
if (value < 0)
|
||||||
|
|||||||
@@ -187,8 +187,8 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
|
|||||||
return _object.getOrAddMember(_key);
|
return _object.getOrAddMember(_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
friend bool convertToJson(const this_type &src, VariantRef dst) {
|
friend void convertToJson(const this_type &src, VariantRef dst) {
|
||||||
return dst.set(src.getUpstreamMember());
|
dst.set(src.getUpstreamMember());
|
||||||
}
|
}
|
||||||
|
|
||||||
TObject _object;
|
TObject _object;
|
||||||
|
|||||||
@@ -239,8 +239,8 @@ class ObjectRef : public ObjectRefBase<CollectionData>,
|
|||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct Converter<ObjectConstRef> {
|
struct Converter<ObjectConstRef> {
|
||||||
static bool toJson(VariantConstRef src, VariantRef dst) {
|
static void toJson(VariantConstRef src, VariantRef dst) {
|
||||||
return variantCopyFrom(getData(dst), getData(src), getPool(dst));
|
variantCopyFrom(getData(dst), getData(src), getPool(dst));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ObjectConstRef fromJson(VariantConstRef src) {
|
static ObjectConstRef fromJson(VariantConstRef src) {
|
||||||
@@ -255,8 +255,8 @@ struct Converter<ObjectConstRef> {
|
|||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct Converter<ObjectRef> {
|
struct Converter<ObjectRef> {
|
||||||
static bool toJson(VariantConstRef src, VariantRef dst) {
|
static void toJson(VariantConstRef src, VariantRef dst) {
|
||||||
return variantCopyFrom(getData(dst), getData(src), getPool(dst));
|
variantCopyFrom(getData(dst), getData(src), getPool(dst));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ObjectRef fromJson(VariantRef src) {
|
static ObjectRef fromJson(VariantRef src) {
|
||||||
@@ -265,6 +265,9 @@ struct Converter<ObjectRef> {
|
|||||||
return ObjectRef(pool, data != 0 ? data->asObject() : 0);
|
return ObjectRef(pool, data != 0 ? data->asObject() : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static InvalidConversion<VariantConstRef, ObjectRef> fromJson(
|
||||||
|
VariantConstRef);
|
||||||
|
|
||||||
static bool checkJson(VariantConstRef) {
|
static bool checkJson(VariantConstRef) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,5 +20,6 @@
|
|||||||
#include "type_traits/is_signed.hpp"
|
#include "type_traits/is_signed.hpp"
|
||||||
#include "type_traits/is_unsigned.hpp"
|
#include "type_traits/is_unsigned.hpp"
|
||||||
#include "type_traits/make_unsigned.hpp"
|
#include "type_traits/make_unsigned.hpp"
|
||||||
|
#include "type_traits/make_void.hpp"
|
||||||
#include "type_traits/remove_const.hpp"
|
#include "type_traits/remove_const.hpp"
|
||||||
#include "type_traits/remove_reference.hpp"
|
#include "type_traits/remove_reference.hpp"
|
||||||
|
|||||||
@@ -5,15 +5,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "integral_constant.hpp"
|
#include "integral_constant.hpp"
|
||||||
|
#include "is_same.hpp"
|
||||||
|
#include "remove_cv.hpp"
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename>
|
template <class T>
|
||||||
struct is_floating_point : false_type {};
|
struct is_floating_point
|
||||||
|
: integral_constant<
|
||||||
|
bool, //
|
||||||
|
is_same<float, typename remove_cv<T>::type>::value ||
|
||||||
|
is_same<double, typename remove_cv<T>::type>::value> {};
|
||||||
|
|
||||||
template <>
|
|
||||||
struct is_floating_point<float> : true_type {};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct is_floating_point<double> : true_type {};
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -5,29 +5,33 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Configuration.hpp>
|
#include <ArduinoJson/Configuration.hpp>
|
||||||
|
|
||||||
|
#include "integral_constant.hpp"
|
||||||
#include "is_same.hpp"
|
#include "is_same.hpp"
|
||||||
|
#include "remove_cv.hpp"
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
// A meta-function that returns true if T is an integral type.
|
// clang-format off
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_integral {
|
struct is_integral : integral_constant<bool,
|
||||||
static const bool value =
|
is_same<typename remove_cv<T>::type, signed char>::value ||
|
||||||
is_same<T, signed char>::value || is_same<T, unsigned char>::value ||
|
is_same<typename remove_cv<T>::type, unsigned char>::value ||
|
||||||
is_same<T, signed short>::value || is_same<T, unsigned short>::value ||
|
is_same<typename remove_cv<T>::type, signed short>::value ||
|
||||||
is_same<T, signed int>::value || is_same<T, unsigned int>::value ||
|
is_same<typename remove_cv<T>::type, unsigned short>::value ||
|
||||||
is_same<T, signed long>::value || is_same<T, unsigned long>::value ||
|
is_same<typename remove_cv<T>::type, signed int>::value ||
|
||||||
|
is_same<typename remove_cv<T>::type, unsigned int>::value ||
|
||||||
|
is_same<typename remove_cv<T>::type, signed long>::value ||
|
||||||
|
is_same<typename remove_cv<T>::type, unsigned long>::value ||
|
||||||
#if ARDUINOJSON_HAS_LONG_LONG
|
#if ARDUINOJSON_HAS_LONG_LONG
|
||||||
is_same<T, signed long long>::value ||
|
is_same<typename remove_cv<T>::type, signed long long>::value ||
|
||||||
is_same<T, unsigned long long>::value ||
|
is_same<typename remove_cv<T>::type, unsigned long long>::value ||
|
||||||
#endif
|
#endif
|
||||||
#if ARDUINOJSON_HAS_INT64
|
#if ARDUINOJSON_HAS_INT64
|
||||||
is_same<T, signed __int64>::value ||
|
is_same<typename remove_cv<T>::type, signed __int64>::value ||
|
||||||
is_same<T, unsigned __int64>::value ||
|
is_same<typename remove_cv<T>::type, unsigned __int64>::value ||
|
||||||
#endif
|
#endif
|
||||||
is_same<T, char>::value || is_same<T, bool>::value;
|
is_same<typename remove_cv<T>::type, char>::value ||
|
||||||
};
|
is_same<typename remove_cv<T>::type, bool>::value> {};
|
||||||
|
// clang-format on
|
||||||
template <typename T>
|
|
||||||
struct is_integral<const T> : is_integral<T> {};
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -5,39 +5,26 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "integral_constant.hpp"
|
#include "integral_constant.hpp"
|
||||||
|
#include "is_same.hpp"
|
||||||
|
#include "remove_cv.hpp"
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename>
|
// clang-format off
|
||||||
struct is_signed : false_type {};
|
template <typename T>
|
||||||
|
struct is_signed : integral_constant<bool,
|
||||||
template <>
|
is_same<typename remove_cv<T>::type, char>::value ||
|
||||||
struct is_signed<char> : true_type {};
|
is_same<typename remove_cv<T>::type, signed char>::value ||
|
||||||
|
is_same<typename remove_cv<T>::type, signed short>::value ||
|
||||||
template <>
|
is_same<typename remove_cv<T>::type, signed int>::value ||
|
||||||
struct is_signed<signed char> : true_type {};
|
is_same<typename remove_cv<T>::type, signed long>::value ||
|
||||||
|
|
||||||
template <>
|
|
||||||
struct is_signed<signed short> : true_type {};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct is_signed<signed int> : true_type {};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct is_signed<signed long> : true_type {};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct is_signed<float> : true_type {};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct is_signed<double> : true_type {};
|
|
||||||
|
|
||||||
#if ARDUINOJSON_HAS_LONG_LONG
|
#if ARDUINOJSON_HAS_LONG_LONG
|
||||||
template <>
|
is_same<typename remove_cv<T>::type, signed long long>::value ||
|
||||||
struct is_signed<signed long long> : true_type {};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ARDUINOJSON_HAS_INT64
|
#if ARDUINOJSON_HAS_INT64
|
||||||
template <>
|
is_same<typename remove_cv<T>::type, signed __int64>::value ||
|
||||||
struct is_signed<signed __int64> : true_type {};
|
|
||||||
#endif
|
#endif
|
||||||
|
is_same<typename remove_cv<T>::type, float>::value ||
|
||||||
|
is_same<typename remove_cv<T>::type, double>::value> {};
|
||||||
|
// clang-format on
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -5,33 +5,24 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "integral_constant.hpp"
|
#include "integral_constant.hpp"
|
||||||
|
#include "is_same.hpp"
|
||||||
|
#include "remove_cv.hpp"
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename>
|
// clang-format off
|
||||||
struct is_unsigned : false_type {};
|
template <typename T>
|
||||||
|
struct is_unsigned : integral_constant<bool,
|
||||||
template <>
|
is_same<typename remove_cv<T>::type, unsigned char>::value ||
|
||||||
struct is_unsigned<bool> : true_type {};
|
is_same<typename remove_cv<T>::type, unsigned short>::value ||
|
||||||
|
is_same<typename remove_cv<T>::type, unsigned int>::value ||
|
||||||
template <>
|
is_same<typename remove_cv<T>::type, unsigned long>::value ||
|
||||||
struct is_unsigned<unsigned char> : true_type {};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct is_unsigned<unsigned short> : true_type {};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct is_unsigned<unsigned int> : true_type {};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct is_unsigned<unsigned long> : true_type {};
|
|
||||||
|
|
||||||
#if ARDUINOJSON_HAS_INT64
|
#if ARDUINOJSON_HAS_INT64
|
||||||
template <>
|
is_same<typename remove_cv<T>::type, unsigned __int64>::value ||
|
||||||
struct is_unsigned<unsigned __int64> : true_type {};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ARDUINOJSON_HAS_LONG_LONG
|
#if ARDUINOJSON_HAS_LONG_LONG
|
||||||
template <>
|
is_same<typename remove_cv<T>::type, unsigned long long>::value ||
|
||||||
struct is_unsigned<unsigned long long> : true_type {};
|
|
||||||
#endif
|
#endif
|
||||||
|
is_same<typename remove_cv<T>::type, bool>::value> {};
|
||||||
|
// clang-format on
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
// ArduinoJson - https://arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2021
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
|
template <class = void>
|
||||||
|
struct make_void {
|
||||||
|
typedef void type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
// ArduinoJson - https://arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2021
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
|
||||||
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct remove_cv {
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
template <typename T>
|
||||||
|
struct remove_cv<const T> {
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
template <typename T>
|
||||||
|
struct remove_cv<volatile T> {
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
template <typename T>
|
||||||
|
struct remove_cv<const volatile T> {
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
@@ -22,10 +22,10 @@ class Writer< ::String, void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t write(uint8_t c) {
|
size_t write(uint8_t c) {
|
||||||
ARDUINOJSON_ASSERT(_size < bufferCapacity);
|
|
||||||
_buffer[_size++] = static_cast<char>(c);
|
|
||||||
if (_size + 1 >= bufferCapacity)
|
if (_size + 1 >= bufferCapacity)
|
||||||
flush();
|
if (flush() != 0)
|
||||||
|
return 0;
|
||||||
|
_buffer[_size++] = static_cast<char>(c);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,14 +36,15 @@ class Writer< ::String, void> {
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
size_t flush() {
|
||||||
void flush() {
|
|
||||||
ARDUINOJSON_ASSERT(_size < bufferCapacity);
|
ARDUINOJSON_ASSERT(_size < bufferCapacity);
|
||||||
_buffer[_size] = 0;
|
_buffer[_size] = 0;
|
||||||
*_destination += _buffer;
|
if (_destination->concat(_buffer))
|
||||||
_size = 0;
|
_size = 0;
|
||||||
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
::String *_destination;
|
::String *_destination;
|
||||||
char _buffer[bufferCapacity];
|
char _buffer[bufferCapacity];
|
||||||
size_t _size;
|
size_t _size;
|
||||||
|
|||||||
@@ -55,8 +55,12 @@ class StringCopier {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
MemoryPool* _pool;
|
MemoryPool* _pool;
|
||||||
|
|
||||||
|
// These fields aren't initialized by the constructor but startString()
|
||||||
|
//
|
||||||
|
// NOLINTNEXTLINE(clang-analyzer-optin.cplusplus.UninitializedObject)
|
||||||
char* _ptr;
|
char* _ptr;
|
||||||
size_t _size;
|
// NOLINTNEXTLINE(clang-analyzer-optin.cplusplus.UninitializedObject)
|
||||||
size_t _capacity;
|
size_t _size, _capacity;
|
||||||
};
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -7,14 +7,15 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
#include <ArduinoJson/Polyfills/safe_strcmp.hpp>
|
#include <ArduinoJson/Polyfills/safe_strcmp.hpp>
|
||||||
#include <ArduinoJson/Strings/IsString.hpp>
|
|
||||||
#include <ArduinoJson/Strings/StoragePolicy.hpp>
|
#include <ArduinoJson/Strings/StoragePolicy.hpp>
|
||||||
|
#include <ArduinoJson/Strings/StringAdapter.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
class ArduinoStringAdapter {
|
template <>
|
||||||
|
class StringAdapter< ::String> {
|
||||||
public:
|
public:
|
||||||
ArduinoStringAdapter(const ::String& str) : _str(&str) {}
|
StringAdapter(const ::String& str) : _str(&str) {}
|
||||||
|
|
||||||
void copyTo(char* p, size_t n) const {
|
void copyTo(char* p, size_t n) const {
|
||||||
memcpy(p, _str->c_str(), n);
|
memcpy(p, _str->c_str(), n);
|
||||||
@@ -31,18 +32,10 @@ class ArduinoStringAdapter {
|
|||||||
return safe_strcmp(me, other);
|
return safe_strcmp(me, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool equals(const char* expected) const {
|
|
||||||
return compare(expected) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size() const {
|
size_t size() const {
|
||||||
return _str->length();
|
return _str->length();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* begin() const {
|
|
||||||
return _str->c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef storage_policies::store_by_copy storage_policy;
|
typedef storage_policies::store_by_copy storage_policy;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -50,13 +43,9 @@ class ArduinoStringAdapter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct IsString< ::String> : true_type {};
|
class StringAdapter< ::StringSumHelper> : public StringAdapter< ::String> {
|
||||||
|
public:
|
||||||
template <>
|
StringAdapter(const ::String& s) : StringAdapter< ::String>(s) {}
|
||||||
struct IsString< ::StringSumHelper> : true_type {};
|
};
|
||||||
|
|
||||||
inline ArduinoStringAdapter adaptString(const ::String& str) {
|
|
||||||
return ArduinoStringAdapter(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
@@ -8,23 +8,20 @@
|
|||||||
#include <string.h> // strcmp
|
#include <string.h> // strcmp
|
||||||
|
|
||||||
#include <ArduinoJson/Polyfills/safe_strcmp.hpp>
|
#include <ArduinoJson/Polyfills/safe_strcmp.hpp>
|
||||||
#include <ArduinoJson/Strings/IsString.hpp>
|
|
||||||
#include <ArduinoJson/Strings/StoragePolicy.hpp>
|
#include <ArduinoJson/Strings/StoragePolicy.hpp>
|
||||||
|
#include <ArduinoJson/Strings/StringAdapter.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
class ConstRamStringAdapter {
|
template <>
|
||||||
|
class StringAdapter<const char*> {
|
||||||
public:
|
public:
|
||||||
ConstRamStringAdapter(const char* str = 0) : _str(str) {}
|
StringAdapter(const char* str = 0) : _str(str) {}
|
||||||
|
|
||||||
int compare(const char* other) const {
|
int compare(const char* other) const {
|
||||||
return safe_strcmp(_str, other);
|
return safe_strcmp(_str, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool equals(const char* expected) const {
|
|
||||||
return compare(expected) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isNull() const {
|
bool isNull() const {
|
||||||
return !_str;
|
return !_str;
|
||||||
}
|
}
|
||||||
@@ -39,24 +36,16 @@ class ConstRamStringAdapter {
|
|||||||
return _str;
|
return _str;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* begin() const {
|
|
||||||
return _str;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef storage_policies::store_by_address storage_policy;
|
typedef storage_policies::store_by_address storage_policy;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const char* _str;
|
const char* _str;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
|
||||||
struct IsString<const char*> : true_type {};
|
|
||||||
|
|
||||||
template <int N>
|
template <int N>
|
||||||
struct IsString<const char[N]> : true_type {};
|
class StringAdapter<const char[N]> : public StringAdapter<const char*> {
|
||||||
|
public:
|
||||||
inline ConstRamStringAdapter adaptString(const char* str) {
|
StringAdapter(const char* s) : StringAdapter<const char*>(s) {}
|
||||||
return ConstRamStringAdapter(str);
|
};
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
@@ -5,15 +5,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Polyfills/pgmspace.hpp>
|
#include <ArduinoJson/Polyfills/pgmspace.hpp>
|
||||||
#include <ArduinoJson/Strings/FlashStringIterator.hpp>
|
|
||||||
#include <ArduinoJson/Strings/IsString.hpp>
|
|
||||||
#include <ArduinoJson/Strings/StoragePolicy.hpp>
|
#include <ArduinoJson/Strings/StoragePolicy.hpp>
|
||||||
|
#include <ArduinoJson/Strings/StringAdapter.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
class FlashStringAdapter {
|
template <>
|
||||||
|
class StringAdapter<const __FlashStringHelper*> {
|
||||||
public:
|
public:
|
||||||
FlashStringAdapter(const __FlashStringHelper* str) : _str(str) {}
|
StringAdapter(const __FlashStringHelper* str) : _str(str) {}
|
||||||
|
|
||||||
int compare(const char* other) const {
|
int compare(const char* other) const {
|
||||||
if (!other && !_str)
|
if (!other && !_str)
|
||||||
@@ -25,10 +25,6 @@ class FlashStringAdapter {
|
|||||||
return -strcmp_P(other, reinterpret_cast<const char*>(_str));
|
return -strcmp_P(other, reinterpret_cast<const char*>(_str));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool equals(const char* expected) const {
|
|
||||||
return compare(expected) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isNull() const {
|
bool isNull() const {
|
||||||
return !_str;
|
return !_str;
|
||||||
}
|
}
|
||||||
@@ -43,20 +39,10 @@ class FlashStringAdapter {
|
|||||||
return strlen_P(reinterpret_cast<const char*>(_str));
|
return strlen_P(reinterpret_cast<const char*>(_str));
|
||||||
}
|
}
|
||||||
|
|
||||||
FlashStringIterator begin() const {
|
|
||||||
return FlashStringIterator(_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef storage_policies::store_by_copy storage_policy;
|
typedef storage_policies::store_by_copy storage_policy;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const __FlashStringHelper* _str;
|
const __FlashStringHelper* _str;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline FlashStringAdapter adaptString(const __FlashStringHelper* str) {
|
|
||||||
return FlashStringAdapter(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct IsString<const __FlashStringHelper*> : true_type {};
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
// ArduinoJson - https://arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2021
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ArduinoJson/Strings/Adapters/RamStringAdapter.hpp>
|
||||||
|
#include <ArduinoJson/Strings/String.hpp>
|
||||||
|
|
||||||
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class StringAdapter<String> : public StringAdapter<char*> {
|
||||||
|
public:
|
||||||
|
StringAdapter(const String& str)
|
||||||
|
: StringAdapter<char*>(str.c_str()), _isStatic(str.isStatic()) {}
|
||||||
|
|
||||||
|
bool isStatic() const {
|
||||||
|
return _isStatic;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef storage_policies::decide_at_runtime storage_policy;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _isStatic;
|
||||||
|
};
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
// ArduinoJson - https://arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2021
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||||
|
#include <ArduinoJson/Strings/StoragePolicy.hpp>
|
||||||
|
#include <ArduinoJson/Strings/StringAdapter.hpp>
|
||||||
|
|
||||||
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
|
template <typename TChar>
|
||||||
|
class StringAdapter<TChar*, false,
|
||||||
|
typename enable_if<sizeof(TChar) == 1 &&
|
||||||
|
!is_same<TChar, void>::value>::type>
|
||||||
|
: public StringAdapter<const char*> {
|
||||||
|
public:
|
||||||
|
StringAdapter(const TChar* str)
|
||||||
|
: StringAdapter<const char*>(reinterpret_cast<const char*>(str)) {}
|
||||||
|
|
||||||
|
void copyTo(char* p, size_t n) const {
|
||||||
|
memcpy(p, _str, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef ARDUINOJSON_NAMESPACE::storage_policies::store_by_copy storage_policy;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
@@ -5,15 +5,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
#include <ArduinoJson/Strings/FlashStringIterator.hpp>
|
|
||||||
#include <ArduinoJson/Strings/IsString.hpp>
|
|
||||||
#include <ArduinoJson/Strings/StoragePolicy.hpp>
|
#include <ArduinoJson/Strings/StoragePolicy.hpp>
|
||||||
|
#include <ArduinoJson/Strings/StringAdapter.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
class SizedFlashStringAdapter {
|
template <>
|
||||||
|
class StringAdapter<const __FlashStringHelper*, true> {
|
||||||
public:
|
public:
|
||||||
SizedFlashStringAdapter(const __FlashStringHelper* str, size_t sz)
|
StringAdapter(const __FlashStringHelper* str, size_t sz)
|
||||||
: _str(str), _size(sz) {}
|
: _str(str), _size(sz) {}
|
||||||
|
|
||||||
int compare(const char* other) const {
|
int compare(const char* other) const {
|
||||||
@@ -26,10 +26,6 @@ class SizedFlashStringAdapter {
|
|||||||
return -strncmp_P(other, reinterpret_cast<const char*>(_str), _size);
|
return -strncmp_P(other, reinterpret_cast<const char*>(_str), _size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool equals(const char* expected) const {
|
|
||||||
return compare(expected) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isNull() const {
|
bool isNull() const {
|
||||||
return !_str;
|
return !_str;
|
||||||
}
|
}
|
||||||
@@ -42,10 +38,6 @@ class SizedFlashStringAdapter {
|
|||||||
return _size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
FlashStringIterator begin() const {
|
|
||||||
return FlashStringIterator(_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef storage_policies::store_by_copy storage_policy;
|
typedef storage_policies::store_by_copy storage_policy;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -53,8 +45,4 @@ class SizedFlashStringAdapter {
|
|||||||
size_t _size;
|
size_t _size;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline SizedFlashStringAdapter adaptString(const __FlashStringHelper* str,
|
|
||||||
size_t sz) {
|
|
||||||
return SizedFlashStringAdapter(str, sz);
|
|
||||||
}
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
@@ -5,25 +5,22 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
#include <ArduinoJson/Strings/IsString.hpp>
|
|
||||||
#include <ArduinoJson/Strings/StoragePolicy.hpp>
|
#include <ArduinoJson/Strings/StoragePolicy.hpp>
|
||||||
|
#include <ArduinoJson/Strings/StringAdapter.hpp>
|
||||||
|
|
||||||
#include <string.h> // strcmp
|
#include <string.h> // strcmp
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
class SizedRamStringAdapter {
|
template <typename TChar>
|
||||||
|
class StringAdapter<TChar*, true> {
|
||||||
public:
|
public:
|
||||||
SizedRamStringAdapter(const char* str, size_t n) : _str(str), _size(n) {}
|
StringAdapter(const char* str, size_t n) : _str(str), _size(n) {}
|
||||||
|
|
||||||
int compare(const char* other) const {
|
int compare(const char* other) const {
|
||||||
return safe_strncmp(_str, other, _size);
|
return safe_strncmp(_str, other, _size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool equals(const char* expected) const {
|
|
||||||
return compare(expected) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isNull() const {
|
bool isNull() const {
|
||||||
return !_str;
|
return !_str;
|
||||||
}
|
}
|
||||||
@@ -36,10 +33,6 @@ class SizedRamStringAdapter {
|
|||||||
return _size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* begin() const {
|
|
||||||
return _str;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef storage_policies::store_by_copy storage_policy;
|
typedef storage_policies::store_by_copy storage_policy;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -47,9 +40,4 @@ class SizedRamStringAdapter {
|
|||||||
size_t _size;
|
size_t _size;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename TChar>
|
|
||||||
inline SizedRamStringAdapter adaptString(const TChar* str, size_t size) {
|
|
||||||
return SizedRamStringAdapter(reinterpret_cast<const char*>(str), size);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
// ArduinoJson - https://arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2021
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
#include <ArduinoJson/Strings/StoragePolicy.hpp>
|
||||||
|
#include <ArduinoJson/Strings/StringAdapter.hpp>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
|
template <typename TCharTraits, typename TAllocator>
|
||||||
|
class StringAdapter<std::basic_string<char, TCharTraits, TAllocator> > {
|
||||||
|
public:
|
||||||
|
typedef std::basic_string<char, TCharTraits, TAllocator> string_type;
|
||||||
|
|
||||||
|
StringAdapter(const string_type& str) : _str(&str) {}
|
||||||
|
|
||||||
|
void copyTo(char* p, size_t n) const {
|
||||||
|
memcpy(p, _str->c_str(), n);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isNull() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int compare(const char* other) const {
|
||||||
|
if (!other)
|
||||||
|
return 1;
|
||||||
|
return _str->compare(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const {
|
||||||
|
return _str->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef storage_policies::store_by_copy storage_policy;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const string_type* _str;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
// ArduinoJson - https://arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2021
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
#include <ArduinoJson/Strings/StoragePolicy.hpp>
|
||||||
|
#include <ArduinoJson/Strings/StringAdapter.hpp>
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class StringAdapter<std::string_view> {
|
||||||
|
public:
|
||||||
|
StringAdapter(std::string_view str) : _str(str) {}
|
||||||
|
|
||||||
|
void copyTo(char* p, size_t n) const {
|
||||||
|
memcpy(p, _str.data(), n);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isNull() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int compare(const char* other) const {
|
||||||
|
if (!other)
|
||||||
|
return 1;
|
||||||
|
return _str.compare(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const {
|
||||||
|
return _str.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef storage_policies::store_by_copy storage_policy;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string_view _str;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
// ArduinoJson - https://arduinojson.org
|
|
||||||
// Copyright Benoit Blanchon 2014-2021
|
|
||||||
// MIT License
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
|
||||||
|
|
||||||
class FlashStringIterator {
|
|
||||||
public:
|
|
||||||
explicit FlashStringIterator(const __FlashStringHelper* ptr)
|
|
||||||
: _ptr(reinterpret_cast<const char*>(ptr)) {}
|
|
||||||
|
|
||||||
explicit FlashStringIterator(const char* ptr) : _ptr(ptr) {}
|
|
||||||
|
|
||||||
FlashStringIterator operator+(ptrdiff_t d) const {
|
|
||||||
return FlashStringIterator(_ptr + d);
|
|
||||||
}
|
|
||||||
|
|
||||||
ptrdiff_t operator-(FlashStringIterator other) const {
|
|
||||||
return _ptr - other._ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
FlashStringIterator operator++(int) {
|
|
||||||
return FlashStringIterator(_ptr++);
|
|
||||||
}
|
|
||||||
|
|
||||||
FlashStringIterator operator++() {
|
|
||||||
return FlashStringIterator(++_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(FlashStringIterator other) const {
|
|
||||||
return _ptr != other._ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
char operator*() const {
|
|
||||||
return char(pgm_read_byte(_ptr));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const char* _ptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
// ArduinoJson - https://arduinojson.org
|
|
||||||
// Copyright Benoit Blanchon 2014-2021
|
|
||||||
// MIT License
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
|
||||||
template <typename>
|
|
||||||
struct IsString : false_type {};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct IsString<const T> : IsString<T> {};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct IsString<T&> : IsString<T> {};
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
// ArduinoJson - https://arduinojson.org
|
|
||||||
// Copyright Benoit Blanchon 2014-2021
|
|
||||||
// MIT License
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <ArduinoJson/Strings/ConstRamStringAdapter.hpp>
|
|
||||||
#include <ArduinoJson/Strings/IsString.hpp>
|
|
||||||
#include <ArduinoJson/Strings/StoragePolicy.hpp>
|
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
|
||||||
|
|
||||||
class RamStringAdapter : public ConstRamStringAdapter {
|
|
||||||
public:
|
|
||||||
RamStringAdapter(const char* str) : ConstRamStringAdapter(str) {}
|
|
||||||
|
|
||||||
void copyTo(char* p, size_t n) const {
|
|
||||||
memcpy(p, _str, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef ARDUINOJSON_NAMESPACE::storage_policies::store_by_copy storage_policy;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename TChar>
|
|
||||||
inline RamStringAdapter adaptString(const TChar* str) {
|
|
||||||
return RamStringAdapter(reinterpret_cast<const char*>(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline RamStringAdapter adaptString(char* str) {
|
|
||||||
return RamStringAdapter(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TChar>
|
|
||||||
struct IsString<TChar*> {
|
|
||||||
static const bool value = sizeof(TChar) == 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct IsString<void*> {
|
|
||||||
static const bool value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
// ArduinoJson - https://arduinojson.org
|
|
||||||
// Copyright Benoit Blanchon 2014-2021
|
|
||||||
// MIT License
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
|
||||||
#include <ArduinoJson/Strings/IsString.hpp>
|
|
||||||
#include <ArduinoJson/Strings/StoragePolicy.hpp>
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
|
||||||
|
|
||||||
template <typename TString>
|
|
||||||
class StdStringAdapter {
|
|
||||||
public:
|
|
||||||
StdStringAdapter(const TString& str) : _str(&str) {}
|
|
||||||
|
|
||||||
void copyTo(char* p, size_t n) const {
|
|
||||||
memcpy(p, _str->c_str(), n);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isNull() const {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int compare(const char* other) const {
|
|
||||||
if (!other)
|
|
||||||
return 1;
|
|
||||||
return _str->compare(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool equals(const char* expected) const {
|
|
||||||
if (!expected)
|
|
||||||
return false;
|
|
||||||
return *_str == expected;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size() const {
|
|
||||||
return _str->size();
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* begin() const {
|
|
||||||
return _str->c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef storage_policies::store_by_copy storage_policy;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const TString* _str;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename TCharTraits, typename TAllocator>
|
|
||||||
struct IsString<std::basic_string<char, TCharTraits, TAllocator> > : true_type {
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename TCharTraits, typename TAllocator>
|
|
||||||
inline StdStringAdapter<std::basic_string<char, TCharTraits, TAllocator> >
|
|
||||||
adaptString(const std::basic_string<char, TCharTraits, TAllocator>& str) {
|
|
||||||
return StdStringAdapter<std::basic_string<char, TCharTraits, TAllocator> >(
|
|
||||||
str);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
|
||||||
@@ -4,10 +4,6 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Strings/ConstRamStringAdapter.hpp>
|
|
||||||
#include <ArduinoJson/Strings/IsString.hpp>
|
|
||||||
#include <ArduinoJson/Strings/StoragePolicy.hpp>
|
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
class String {
|
class String {
|
||||||
@@ -53,25 +49,4 @@ class String {
|
|||||||
bool _isStatic;
|
bool _isStatic;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StringAdapter : public RamStringAdapter {
|
|
||||||
public:
|
|
||||||
StringAdapter(const String& str)
|
|
||||||
: RamStringAdapter(str.c_str()), _isStatic(str.isStatic()) {}
|
|
||||||
|
|
||||||
bool isStatic() const {
|
|
||||||
return _isStatic;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef storage_policies::decide_at_runtime storage_policy;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool _isStatic;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct IsString<String> : true_type {};
|
|
||||||
|
|
||||||
inline StringAdapter adaptString(const String& str) {
|
|
||||||
return StringAdapter(str);
|
|
||||||
}
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
32
lib/ArduinoJson/src/ArduinoJson/Strings/StringAdapter.hpp
Normal file
32
lib/ArduinoJson/src/ArduinoJson/Strings/StringAdapter.hpp
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
// ArduinoJson - https://arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2021
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||||
|
|
||||||
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
|
template <typename T, bool bounded = false, typename Enable = void>
|
||||||
|
class StringAdapter;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline StringAdapter<T, false> adaptString(const T& str) {
|
||||||
|
return StringAdapter<T, false>(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline StringAdapter<T, true> adaptString(const T& str, size_t sz) {
|
||||||
|
return StringAdapter<T, true>(str, sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename Enable = void>
|
||||||
|
struct IsString : false_type {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct IsString<
|
||||||
|
T, typename make_void<typename StringAdapter<T>::storage_policy>::type>
|
||||||
|
: true_type {};
|
||||||
|
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
@@ -4,19 +4,24 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Strings/ConstRamStringAdapter.hpp>
|
#include <ArduinoJson/Strings/Adapters/ConstRamStringAdapter.hpp>
|
||||||
#include <ArduinoJson/Strings/RamStringAdapter.hpp>
|
#include <ArduinoJson/Strings/Adapters/JsonStringAdapter.hpp>
|
||||||
#include <ArduinoJson/Strings/SizedRamStringAdapter.hpp>
|
#include <ArduinoJson/Strings/Adapters/RamStringAdapter.hpp>
|
||||||
|
#include <ArduinoJson/Strings/Adapters/SizedRamStringAdapter.hpp>
|
||||||
|
|
||||||
#if ARDUINOJSON_ENABLE_STD_STRING
|
#if ARDUINOJSON_ENABLE_STD_STRING
|
||||||
#include <ArduinoJson/Strings/StdStringAdapter.hpp>
|
# include <ArduinoJson/Strings/Adapters/StdStringAdapter.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ARDUINOJSON_ENABLE_STRING_VIEW
|
||||||
|
# include <ArduinoJson/Strings/Adapters/StringViewAdapter.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
|
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
|
||||||
#include <ArduinoJson/Strings/ArduinoStringAdapter.hpp>
|
# include <ArduinoJson/Strings/Adapters/ArduinoStringAdapter.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ARDUINOJSON_ENABLE_PROGMEM
|
#if ARDUINOJSON_ENABLE_PROGMEM
|
||||||
#include <ArduinoJson/Strings/FlashStringAdapter.hpp>
|
# include <ArduinoJson/Strings/Adapters/FlashStringAdapter.hpp>
|
||||||
#include <ArduinoJson/Strings/SizedFlashStringAdapter.hpp>
|
# include <ArduinoJson/Strings/Adapters/SizedFlashStringAdapter.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -9,4 +9,9 @@ namespace ARDUINOJSON_NAMESPACE {
|
|||||||
template <typename T, typename Enable = void>
|
template <typename T, typename Enable = void>
|
||||||
struct Converter;
|
struct Converter;
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
template <typename T1, typename T2>
|
||||||
|
class InvalidConversion; // Error here? See https://arduinojson.org/v6/invalid-conversion/
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ namespace ARDUINOJSON_NAMESPACE {
|
|||||||
|
|
||||||
template <typename T, typename Enable>
|
template <typename T, typename Enable>
|
||||||
struct Converter {
|
struct Converter {
|
||||||
static bool toJson(const T& src, VariantRef dst) {
|
static void toJson(const T& src, VariantRef dst) {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
return convertToJson(src, dst); // Error here? See https://arduinojson.org/v6/unsupported-set/
|
convertToJson(src, dst); // Error here? See https://arduinojson.org/v6/unsupported-set/
|
||||||
// clang-format on
|
// clang-format on
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ struct Converter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool checkJson(VariantConstRef src) {
|
static bool checkJson(VariantConstRef src) {
|
||||||
T dummy;
|
T dummy = T();
|
||||||
// clang-format off
|
// clang-format off
|
||||||
return canConvertFromJson(src, dummy); // Error here? See https://arduinojson.org/v6/unsupported-is/
|
return canConvertFromJson(src, dummy); // Error here? See https://arduinojson.org/v6/unsupported-is/
|
||||||
// clang-format on
|
// clang-format on
|
||||||
@@ -38,13 +38,11 @@ template <typename T>
|
|||||||
struct Converter<
|
struct Converter<
|
||||||
T, typename enable_if<is_integral<T>::value && !is_same<bool, T>::value &&
|
T, typename enable_if<is_integral<T>::value && !is_same<bool, T>::value &&
|
||||||
!is_same<char, T>::value>::type> {
|
!is_same<char, T>::value>::type> {
|
||||||
static bool toJson(T src, VariantRef dst) {
|
static void toJson(T src, VariantRef dst) {
|
||||||
VariantData* data = getData(dst);
|
VariantData* data = getData(dst);
|
||||||
ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
|
ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
|
||||||
if (!data)
|
if (data)
|
||||||
return false;
|
|
||||||
data->setInteger(src);
|
data->setInteger(src);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static T fromJson(VariantConstRef src) {
|
static T fromJson(VariantConstRef src) {
|
||||||
@@ -61,8 +59,8 @@ struct Converter<
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct Converter<T, typename enable_if<is_enum<T>::value>::type> {
|
struct Converter<T, typename enable_if<is_enum<T>::value>::type> {
|
||||||
static bool toJson(T src, VariantRef dst) {
|
static void toJson(T src, VariantRef dst) {
|
||||||
return dst.set(static_cast<Integer>(src));
|
dst.set(static_cast<Integer>(src));
|
||||||
}
|
}
|
||||||
|
|
||||||
static T fromJson(VariantConstRef src) {
|
static T fromJson(VariantConstRef src) {
|
||||||
@@ -78,12 +76,10 @@ struct Converter<T, typename enable_if<is_enum<T>::value>::type> {
|
|||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct Converter<bool> {
|
struct Converter<bool> {
|
||||||
static bool toJson(bool src, VariantRef dst) {
|
static void toJson(bool src, VariantRef dst) {
|
||||||
VariantData* data = getData(dst);
|
VariantData* data = getData(dst);
|
||||||
if (!data)
|
if (data)
|
||||||
return false;
|
|
||||||
data->setBoolean(src);
|
data->setBoolean(src);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool fromJson(VariantConstRef src) {
|
static bool fromJson(VariantConstRef src) {
|
||||||
@@ -99,12 +95,10 @@ struct Converter<bool> {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct Converter<T, typename enable_if<is_floating_point<T>::value>::type> {
|
struct Converter<T, typename enable_if<is_floating_point<T>::value>::type> {
|
||||||
static bool toJson(T src, VariantRef dst) {
|
static void toJson(T src, VariantRef dst) {
|
||||||
VariantData* data = getData(dst);
|
VariantData* data = getData(dst);
|
||||||
if (!data)
|
if (data)
|
||||||
return false;
|
|
||||||
data->setFloat(static_cast<Float>(src));
|
data->setFloat(static_cast<Float>(src));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static T fromJson(VariantConstRef src) {
|
static T fromJson(VariantConstRef src) {
|
||||||
@@ -120,8 +114,8 @@ struct Converter<T, typename enable_if<is_floating_point<T>::value>::type> {
|
|||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct Converter<const char*> {
|
struct Converter<const char*> {
|
||||||
static bool toJson(const char* src, VariantRef dst) {
|
static void toJson(const char* src, VariantRef dst) {
|
||||||
return variantSetString(getData(dst), adaptString(src), getPool(dst));
|
variantSetString(getData(dst), adaptString(src), getPool(dst));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* fromJson(VariantConstRef src) {
|
static const char* fromJson(VariantConstRef src) {
|
||||||
@@ -163,12 +157,10 @@ canConvertFromJson(VariantConstRef src, const T&) {
|
|||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct Converter<SerializedValue<const char*> > {
|
struct Converter<SerializedValue<const char*> > {
|
||||||
static bool toJson(SerializedValue<const char*> src, VariantRef dst) {
|
static void toJson(SerializedValue<const char*> src, VariantRef dst) {
|
||||||
VariantData* data = getData(dst);
|
VariantData* data = getData(dst);
|
||||||
if (!data)
|
if (data)
|
||||||
return false;
|
|
||||||
data->setLinkedRaw(src);
|
data->setLinkedRaw(src);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -178,10 +170,11 @@ struct Converter<SerializedValue<const char*> > {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
struct Converter<SerializedValue<T>,
|
struct Converter<SerializedValue<T>,
|
||||||
typename enable_if<!is_same<const char*, T>::value>::type> {
|
typename enable_if<!is_same<const char*, T>::value>::type> {
|
||||||
static bool toJson(SerializedValue<T> src, VariantRef dst) {
|
static void toJson(SerializedValue<T> src, VariantRef dst) {
|
||||||
VariantData* data = getData(dst);
|
VariantData* data = getData(dst);
|
||||||
MemoryPool* pool = getPool(dst);
|
MemoryPool* pool = getPool(dst);
|
||||||
return data != 0 && data->setOwnedRaw(src, pool);
|
if (data)
|
||||||
|
data->setOwnedRaw(src, pool);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -189,9 +182,8 @@ struct Converter<SerializedValue<T>,
|
|||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct Converter<decltype(nullptr)> {
|
struct Converter<decltype(nullptr)> {
|
||||||
static bool toJson(decltype(nullptr), VariantRef dst) {
|
static void toJson(decltype(nullptr), VariantRef dst) {
|
||||||
variantSetNull(getData(dst));
|
variantSetNull(getData(dst));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
static decltype(nullptr) fromJson(VariantConstRef) {
|
static decltype(nullptr) fromJson(VariantConstRef) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -247,20 +239,33 @@ class MemoryPoolPrint : public Print {
|
|||||||
size_t _capacity;
|
size_t _capacity;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool convertToJson(const ::Printable& src, VariantRef dst) {
|
inline void convertToJson(const ::Printable& src, VariantRef dst) {
|
||||||
MemoryPool* pool = getPool(dst);
|
MemoryPool* pool = getPool(dst);
|
||||||
VariantData* data = getData(dst);
|
VariantData* data = getData(dst);
|
||||||
if (!pool || !data)
|
if (!pool || !data)
|
||||||
return false;
|
return;
|
||||||
MemoryPoolPrint print(pool);
|
MemoryPoolPrint print(pool);
|
||||||
src.printTo(print);
|
src.printTo(print);
|
||||||
if (print.overflowed()) {
|
if (print.overflowed()) {
|
||||||
pool->markAsOverflowed();
|
pool->markAsOverflowed();
|
||||||
data->setNull();
|
data->setNull();
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
data->setStringPointer(print.c_str(), storage_policies::store_by_copy());
|
data->setStringPointer(print.c_str(), storage_policies::store_by_copy());
|
||||||
return true;
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ARDUINOJSON_ENABLE_STRING_VIEW
|
||||||
|
|
||||||
|
inline void convertFromJson(VariantConstRef src, std::string_view& dst) {
|
||||||
|
const char* str = src.as<const char*>();
|
||||||
|
if (str) // the standard doesn't allow passing null to the constructor
|
||||||
|
dst = std::string_view(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool canConvertFromJson(VariantConstRef src, const std::string_view&) {
|
||||||
|
return src.is<const char*>();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#include <ArduinoJson/Misc/Visitable.hpp>
|
#include <ArduinoJson/Misc/Visitable.hpp>
|
||||||
#include <ArduinoJson/Numbers/arithmeticCompare.hpp>
|
#include <ArduinoJson/Numbers/arithmeticCompare.hpp>
|
||||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||||
#include <ArduinoJson/Strings/IsString.hpp>
|
#include <ArduinoJson/Strings/StringAdapter.hpp>
|
||||||
#include <ArduinoJson/Variant/Visitor.hpp>
|
#include <ArduinoJson/Variant/Visitor.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
//
|
|
||||||
enum {
|
enum {
|
||||||
VALUE_MASK = 0x7F,
|
VALUE_MASK = 0x7F,
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include <ArduinoJson/Memory/MemoryPool.hpp>
|
#include <ArduinoJson/Memory/MemoryPool.hpp>
|
||||||
#include <ArduinoJson/Misc/SerializedValue.hpp>
|
#include <ArduinoJson/Misc/SerializedValue.hpp>
|
||||||
#include <ArduinoJson/Numbers/convertNumber.hpp>
|
#include <ArduinoJson/Numbers/convertNumber.hpp>
|
||||||
#include <ArduinoJson/Strings/RamStringAdapter.hpp>
|
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantContent.hpp>
|
#include <ArduinoJson/Variant/VariantContent.hpp>
|
||||||
|
|
||||||
// VariantData can't have a constructor (to be a POD), so we have no way to fix
|
// VariantData can't have a constructor (to be a POD), so we have no way to fix
|
||||||
@@ -33,7 +33,7 @@ class VariantData {
|
|||||||
// - no virtual
|
// - no virtual
|
||||||
// - no inheritance
|
// - no inheritance
|
||||||
void init() {
|
void init() {
|
||||||
_flags = 0;
|
_flags = VALUE_IS_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TVisitor>
|
template <typename TVisitor>
|
||||||
@@ -103,7 +103,8 @@ class VariantData {
|
|||||||
case VALUE_IS_OBJECT:
|
case VALUE_IS_OBJECT:
|
||||||
return toObject().copyFrom(src._content.asCollection, pool);
|
return toObject().copyFrom(src._content.asCollection, pool);
|
||||||
case VALUE_IS_OWNED_STRING:
|
case VALUE_IS_OWNED_STRING:
|
||||||
return setString(RamStringAdapter(src._content.asString), pool);
|
return setString(adaptString(const_cast<char *>(src._content.asString)),
|
||||||
|
pool);
|
||||||
case VALUE_IS_OWNED_RAW:
|
case VALUE_IS_OWNED_RAW:
|
||||||
return setOwnedRaw(
|
return setOwnedRaw(
|
||||||
serialized(src._content.asRaw.data, src._content.asRaw.size), pool);
|
serialized(src._content.asRaw.data, src._content.asRaw.size), pool);
|
||||||
|
|||||||
@@ -140,4 +140,9 @@ inline VariantConstRef operator|(VariantConstRef preferedValue,
|
|||||||
VariantConstRef defaultValue) {
|
VariantConstRef defaultValue) {
|
||||||
return preferedValue ? preferedValue : defaultValue;
|
return preferedValue ? preferedValue : defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Out of class definition to avoid #1560
|
||||||
|
inline bool VariantRef::set(char value) const {
|
||||||
|
return set<signed char>(value);
|
||||||
|
}
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user