2922 Commits

Author SHA1 Message Date
Proddy
22eb5436ab Merge pull request #2709 from MichaelDvP/dev
some smaller fixes
2025-11-03 17:59:53 +01:00
MichaelDvP
d326d345f4 chore: update generated files 2025-11-03 10:53:17 +00:00
MichaelDvP
1de647e8a5 tcp stack 6k, move message shuntingYard to scheduler 2025-11-03 11:37:24 +01:00
MichaelDvP
c562b88b32 update pkg 2025-11-03 11:36:28 +01:00
MichaelDvP
f2dca2a90a dev24, fix syslog timestamp #2704 2025-11-02 17:45:14 +01:00
Proddy
0f1195de82 Merge pull request #2705 from auenkind/devcontainer
Add devcontainer config
2025-11-02 10:29:37 +01:00
David Neu
267042f74f add devcontainer config 2025-11-02 08:25:18 +00:00
MichaelDvP
ea9783dbfc use ems/ems+ telegrams for forceheatingoff, add fanspd #2702 2025-11-01 19:23:13 +01:00
MichaelDvP
9bc5bde3c2 fix maxflowtemp for convectors, coolingon as bit, nrg with decimals 2025-11-01 13:27:09 +01:00
Proddy
c203b8e6d2 Merge pull request #2697 from MichaelDvP/dev
solar ts8, ts16, set selflowtemp: write to ems+ and ems telegrams
2025-10-30 07:54:40 +01:00
MichaelDvP
c184a0af10 Merge branch 'dev' of https://github.com/MichaelDvP/EMS-ESP32 into dev 2025-10-29 10:48:32 +01:00
MichaelDvP
8a4e6d5ed5 fix selflowtemp, #2641 2025-10-29 10:46:46 +01:00
MichaelDvP
3ef6bf8681 chore: update generated files 2025-10-28 16:04:27 +00:00
MichaelDvP
1647a10b1b add solar TS16, TS8, #2690 2025-10-28 16:52:39 +01:00
Proddy
55b893362c Merge pull request #2696 from MichaelDvP/dev
remove cpu temperature for esp32
2025-10-27 19:36:06 +01:00
MichaelDvP
48f1928327 remove cpu temperature for esp32 2025-10-27 17:30:43 +01:00
Proddy
dc793f145d Merge pull request #2694 from MichaelDvP/dev
fix dashboard write #2693
2025-10-27 17:07:05 +01:00
MichaelDvP
77e0b7d89c fix dashboard write #2693 2025-10-27 11:08:04 +01:00
MichaelDvP
cec19860bc Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-10-27 11:04:28 +01:00
Proddy
898acb90d0 Merge pull request #2688 from proddy/dev
dont run if no C++ src files changed
2025-10-26 12:14:07 +01:00
proddy
a074ac732d dont run if no C++ src files changed 2025-10-26 12:12:37 +01:00
Proddy
c71526b95c Merge pull request #2687 from proddy/dev
ui design cleanup
2025-10-26 12:03:25 +01:00
proddy
f035e31dcf cosmetic improvements 2025-10-26 11:59:19 +01:00
proddy
35192b9dde optimized 2025-10-26 08:51:47 +01:00
Proddy
b5ac637231 Merge pull request #2685 from proddy/dev
small changes to make web tables prettier and consistent
2025-10-25 17:12:42 +02:00
proddy
4e0ef8b0e3 remove bold on select 2025-10-25 17:10:58 +02:00
proddy
c32ee4dfb5 consistent design between dashboard and device tables 2025-10-25 16:59:20 +02:00
proddy
accfeab6fa prettier menu items 2025-10-25 16:59:04 +02:00
proddy
d98f3cc8c5 python cleanup 2025-10-25 16:03:13 +02:00
proddy
342f238983 3.7.3-dev.23 2025-10-25 16:03:02 +02:00
proddy
73f8ea0fc5 lower case some texts 2025-10-25 16:02:50 +02:00
proddy
f2bd1ff575 added assumeChangesOnlyAffectDirectDependencies 2025-10-25 15:23:05 +02:00
proddy
b3ec23d6bd more optimizations, see if it makes a difference 2025-10-25 15:22:51 +02:00
proddy
1fc7fa4720 cache what we can 2025-10-25 15:22:29 +02:00
proddy
58ae058465 use memo and callbacks for reduced rendering vis caching 2025-10-25 15:21:59 +02:00
proddy
7ece395d1b smaller table for dialog 2025-10-25 14:49:14 +02:00
proddy
4bb876031e text change 2025-10-25 14:16:12 +02:00
proddy
e4f129db04 don't compile code when target is build_webUI 2025-10-25 14:15:03 +02:00
proddy
90038e08dc force a build for WebUI 2025-10-25 14:14:42 +02:00
proddy
4c30e930cf add building section 2025-10-25 14:14:25 +02:00
proddy
dd69e02f6b add memo cache, smaller toaster windows 2025-10-25 11:44:08 +02:00
MichaelDvP
f2ccf1953d Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-10-25 11:35:50 +02:00
proddy
0e133840c9 package update 2025-10-25 11:11:51 +02:00
proddy
e12b277472 typo 2025-10-25 11:11:38 +02:00
Proddy
dc7b1809c1 Merge pull request #2682 from emsesp/alert-autofix-40
Potential fix for code scanning alert no. 40: Workflow does not contain permissions
2025-10-25 11:01:00 +02:00
Proddy
8c2146ff55 Merge pull request #2683 from emsesp/alert-autofix-41
Potential fix for code scanning alert no. 41: Workflow does not contain permissions
2025-10-25 11:00:44 +02:00
Proddy
882d412409 Potential fix for code scanning alert no. 41: Workflow does not contain permissions
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2025-10-25 10:46:57 +02:00
Proddy
3f88a9469c Potential fix for code scanning alert no. 40: Workflow does not contain permissions
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2025-10-25 10:46:08 +02:00
Proddy
3ac7d43a81 Merge pull request #2681 from proddy/dev
CI/CD fixes
2025-10-25 10:38:43 +02:00
proddy
d12446b6d9 range fix 2025-10-25 10:36:55 +02:00
MichaelDvP
865fb3a967 typo 2025-10-25 10:31:45 +02:00
proddy
48538222b2 chore: update generated files 2025-10-25 08:30:43 +00:00
proddy
8d44f61517 auto-generated (will be overwritten) 2025-10-25 09:53:43 +02:00
proddy
0e4f6f4209 optimized scripts 2025-10-25 09:53:25 +02:00
proddy
a2823563bf rename post py file 2025-10-25 09:53:08 +02:00
proddy
353cdb324d run unit test on PR 2025-10-25 09:52:44 +02:00
proddy
216f799db1 update checkout 2025-10-25 09:52:35 +02:00
proddy
4d6f080263 modified the comments 2025-10-25 09:52:23 +02:00
MichaelDvP
b9d124618c chore: update generated files 2025-10-25 06:58:56 +00:00
MichaelDvP
ab5d9e8d36 add tags to modbus doc generate 2025-10-25 08:47:10 +02:00
Proddy
4cdeecd952 Merge pull request #2679 from MichaelDvP/dev
bosch texts to utf8, add entities #2669
2025-10-24 21:06:29 +02:00
MichaelDvP
59b3933cb6 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-10-24 18:15:35 +02:00
Proddy
179ddcb348 Merge pull request #2678 from proddy/dev
fix native/standalone
2025-10-24 18:15:03 +02:00
proddy
efa2c8fc4b rename native to standalone 2025-10-24 18:06:52 +02:00
proddy
c958c7d61a fix native 2025-10-24 18:05:12 +02:00
Proddy
35fca9c450 Merge pull request #2677 from proddy/dev
updates to version
2025-10-24 16:28:03 +02:00
proddy
61962fbc07 only build web with target -t build 2025-10-24 16:25:28 +02:00
proddy
39e724befe don't build web on each target 2025-10-24 16:25:15 +02:00
proddy
43bb77b095 optimizations using caching 2025-10-24 16:24:55 +02:00
proddy
28e1e46586 always build web first 2025-10-24 15:35:54 +02:00
proddy
2f5b879652 handle buildweb condition when its part of a pio chain 2025-10-24 15:33:50 +02:00
proddy
16930fe8ca add back for reference 2025-10-24 15:32:35 +02:00
proddy
1db1b6e524 package update 2025-10-24 15:31:57 +02:00
proddy
43eba7a010 show dialog with version information 2025-10-24 15:31:49 +02:00
MichaelDvP
49278bdea4 fix warning 2025-10-24 12:52:25 +02:00
MichaelDvP
2405e11af2 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-10-24 09:45:10 +02:00
MichaelDvP
23b6894484 dev.22 update changelog 2025-10-24 09:44:22 +02:00
proddy
a837c9398c updated 2025-10-24 09:40:41 +02:00
Proddy
ea484e15f9 Merge pull request #2676 from proddy/dev
remove
2025-10-23 23:18:34 +02:00
proddy
cce99a8b1d remove 2025-10-23 23:18:09 +02:00
Proddy
f29faafd78 Merge pull request #2675 from emsesp/alert-autofix-38
Potential fix for code scanning alert no. 38: Workflow does not contain permissions
2025-10-23 22:43:33 +02:00
Proddy
c3eafbcd85 Potential fix for code scanning alert no. 38: Workflow does not contain permissions
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2025-10-23 22:40:23 +02:00
Proddy
65e18ab4e2 Merge pull request #2674 from proddy/dev
use pio to update CSV files
2025-10-23 22:38:42 +02:00
proddy
8bb16ed3a7 update workflows to use new pio builds 2025-10-23 22:35:57 +02:00
proddy
e685284f72 chore: update generated files 2025-10-23 19:43:00 +00:00
proddy
86d2805642 package update (again) 2025-10-23 21:20:03 +02:00
proddy
29b98a15a4 revert test changes 2025-10-23 21:12:47 +02:00
proddy
ba9df92b12 chore: update generated files 2025-10-23 19:05:12 +00:00
proddy
0eac1c9bf9 force a test 2025-10-23 20:52:31 +02:00
proddy
515feb9f9e test auto-commit 2025-10-23 18:43:00 +02:00
proddy
0b84b79e1d Update workflow configurations and build scripts
- Modified GitHub workflow files for dev, stable, and test releases
- Updated platformio.ini and pio_local.ini_example configurations
- Enhanced build_interface.py script functionality
2025-10-23 18:37:14 +02:00
MichaelDvP
8fd129f4fe create src circuit for entity-list/modbus 2025-10-23 18:08:02 +02:00
proddy
ba334930fe replace auto-gen of XLS doc files and Modbus with python 2025-10-23 17:16:32 +02:00
proddy
982d64ddca remove tx/rx limits for standalone 2025-10-23 17:16:04 +02:00
proddy
3577300361 package update 2025-10-23 17:15:43 +02:00
proddy
0478e0ff7c auto-generated 2025-10-23 17:15:34 +02:00
proddy
c2cfd0a1b0 updated 2025-10-23 17:15:25 +02:00
MichaelDvP
637ba30df1 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-10-23 13:32:39 +02:00
MichaelDvP
fa8421b297 special char for servicecode 2025-10-23 13:31:42 +02:00
MichaelDvP
61c23a57d9 larger buffer for print handlers 2025-10-23 13:31:26 +02:00
Proddy
43f61fd2df Merge pull request #2672 from proddy/dev
rollback \n in console tests
2025-10-23 07:22:14 +02:00
proddy
85eed64fe9 rollback \n in console tests 2025-10-23 07:20:40 +02:00
Proddy
43634a4312 Merge pull request #2671 from proddy/dev
small fixes
2025-10-23 07:18:15 +02:00
proddy
9757db4438 fix, remove exit 2025-10-23 07:17:43 +02:00
proddy
17a2ba7f1a package update 2025-10-23 07:17:30 +02:00
proddy
03c7417888 auto-gen 2025-10-23 07:17:22 +02:00
Proddy
2b2c86ba5a Merge pull request #2665 from proddy/dev
optimize WebUI and finally remove lint warnings
2025-10-22 22:37:47 +02:00
proddy
2b2217e8ce updated 2025-10-22 22:24:37 +02:00
proddy
08d3e8bab6 package update 2025-10-22 22:24:31 +02:00
Proddy
ded3552873 Merge branch 'dev' into dev 2025-10-22 22:17:08 +02:00
proddy
9a7893e99f package update 2025-10-22 18:34:15 +02:00
proddy
307ef4e285 fix lint warnings 2025-10-22 18:34:00 +02:00
MichaelDvP
99b43b0379 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-10-22 17:45:40 +02:00
MichaelDvP
6fb8fbba18 convert latin1 chars to utf8 2025-10-22 17:24:20 +02:00
MichaelDvP
09c750e622 update pkg 2025-10-22 17:22:37 +02:00
proddy
f75deb3505 fix missing notification after save 2025-10-22 15:37:04 +02:00
proddy
6281f9cfe1 package update 2025-10-22 15:36:52 +02:00
MichaelDvP
b4f174f2f4 add entities from #2669 2025-10-22 12:54:38 +02:00
proddy
70810b5e71 formatting 2025-10-20 22:27:13 +02:00
proddy
82cc91cb63 fix lint warnings 2025-10-20 22:24:56 +02:00
proddy
48a3fc5656 fix broken fork URL 2025-10-20 22:24:48 +02:00
proddy
9d20eef12d fix warnings, correctly show abort text when cancelling 2025-10-20 22:20:30 +02:00
proddy
d59e183415 update eslint 2025-10-20 22:20:09 +02:00
proddy
50396a5def package update 2025-10-20 22:19:58 +02:00
proddy
ab92d07716 add REINSTALL 2025-10-20 22:19:49 +02:00
proddy
9172dd9181 embed css 2025-10-20 22:19:33 +02:00
proddy
0852502f52 show re-install firmware button 2025-10-20 22:19:19 +02:00
proddy
c3d066650c fix lint warnings 2025-10-20 22:19:05 +02:00
proddy
172e8d0028 fix msgpack 2025-10-20 22:18:55 +02:00
proddy
812c6ac475 optimized 2025-10-20 22:18:43 +02:00
Proddy
f7c1f0b0d0 Merge pull request #2666 from MichaelDvP/dev
some small fixes
2025-10-20 17:49:41 +02:00
MichaelDvP
125190a0ac formatting 2025-10-20 15:54:44 +02:00
MichaelDvP
35c7349e5c update test expected results 2025-10-20 12:07:49 +02:00
MichaelDvP
d7e916269d add missing modbus tags 2025-10-20 11:13:36 +02:00
MichaelDvP
f5f78182b6 fix display setting FW200 2025-10-20 11:12:58 +02:00
proddy
87bcd4598a 3.7.3-dev.21 2025-10-19 16:25:12 +02:00
proddy
21a814b5ec fix lint warnings 2025-10-19 16:24:52 +02:00
proddy
687d9a40c9 add lazy loading for components 2025-10-19 16:24:37 +02:00
proddy
9d01791fcb add useCallbacks for caching and speed 2025-10-19 16:24:17 +02:00
proddy
028afbe85d optimized 2025-10-19 16:23:53 +02:00
proddy
4bdea56d78 use Memo for caching 2025-10-19 16:23:34 +02:00
proddy
bf0737aab8 optimized 2025-10-19 16:23:09 +02:00
proddy
42d879a87b move catch-all path to end 2025-10-19 16:22:53 +02:00
proddy
79b5671533 remove aggressive compression 2025-10-19 16:22:21 +02:00
proddy
f48d67d9e7 optimize code for speed and size 2025-10-19 16:21:52 +02:00
proddy
16f7a454db use vector instead of dequeue for memory optimization 2025-10-19 16:10:15 +02:00
proddy
02b486ea80 updated dictionary 2025-10-19 16:09:56 +02:00
proddy
61d50e2c79 optimizations 2025-10-18 17:17:41 +02:00
proddy
a5af36e15b use 3.7.3 as latest version 2025-10-18 17:17:17 +02:00
proddy
e11ba9e657 formatting 2025-10-18 17:17:04 +02:00
proddy
878f0702b2 typo 2025-10-18 17:16:53 +02:00
proddy
fa711373f2 replace 9 with DeviceValueTAG::TAG_DHW1 2025-10-18 17:16:43 +02:00
proddy
e9a4a33942 auto-generated 2025-10-18 17:16:19 +02:00
proddy
f445f36eb1 extend CharToUpper for all languages 2025-10-18 17:16:10 +02:00
proddy
148124ef04 typo 2025-10-18 17:15:50 +02:00
proddy
27fbafbe62 add missing controller/datetime 2025-10-18 17:15:26 +02:00
proddy
a949673539 update packages 2025-10-18 17:15:07 +02:00
proddy
32193e3c62 optimizations 2025-10-18 17:14:53 +02:00
proddy
5f79f0848f auto-generated 2025-10-18 17:14:33 +02:00
proddy
4d91128aed update dictionary 2025-10-18 17:14:23 +02:00
MichaelDvP
6f1d507df9 SRC modes: off, manual auto 2025-10-18 09:08:05 +02:00
MichaelDvP
9b50306172 set ecodifftemp min to 4 degree 2025-10-18 09:07:10 +02:00
MichaelDvP
0fbc8e2420 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-10-17 11:14:30 +02:00
MichaelDvP
f0d162554b SRC plus: allow only ascii names, pkg update 2025-10-17 10:55:37 +02:00
MichaelDvP
d92361a8bb fix use after free 2025-10-17 10:41:32 +02:00
MichaelDvP
13bf2c44e7 publish connect device 2025-10-16 20:59:56 +02:00
Proddy
cd155ba680 Merge pull request #2660 from MichaelDvP/dev
add dhw modetype #2659, complete SRC plus entities
2025-10-16 16:07:47 +02:00
MichaelDvP
2a565dc677 fix standalone 2025-10-15 20:17:44 +02:00
MichaelDvP
9bf57c3e22 dev20, remove obj_id again 2025-10-15 15:09:22 +02:00
MichaelDvP
766281d8d2 add dhw modetype #2659 2025-10-15 14:32:44 +02:00
MichaelDvP
bd128072c0 fix childlock setting 2025-10-15 10:49:46 +02:00
MichaelDvP
88e4ba7ecf update pkg 2025-10-15 09:03:45 +02:00
MichaelDvP
96e5251050 typo 2025-10-15 07:58:14 +02:00
MichaelDvP
187b163ffd add testdata, use selRoomTemp for climate 2025-10-14 18:56:19 +02:00
MichaelDvP
9d04058984 add back obj_id for HA test 2025-10-14 08:30:52 +02:00
MichaelDvP
12b06aa657 fix mqtt climatefor SRC 2025-10-13 21:46:22 +02:00
MichaelDvP
47b3e4bf00 fix srcx/seltemp 2025-10-13 19:58:25 +02:00
MichaelDvP
f0f40bbcac fix src commands, icon 2025-10-13 08:46:22 +02:00
MichaelDvP
036e2917a5 SRC plus: mqtt subscribe, modbus 2025-10-12 11:35:24 +02:00
MichaelDvP
d294c418c1 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-10-11 10:12:20 +02:00
Proddy
40da7572cd Merge pull request #2656 from proddy/dev
fix NL translation - https://github.com/emsesp/EMS-ESP32/pull/2655
2025-10-11 07:44:42 +02:00
proddy
532dc66282 fix NL translation - https://github.com/emsesp/EMS-ESP32/pull/2655 2025-10-11 07:43:46 +02:00
MichaelDvP
8913f38fd0 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-10-10 19:25:18 +02:00
MichaelDvP
11782eef8b SRC #2636, add childlock, icons, fix long names 2025-10-09 13:25:09 +02:00
Proddy
b5f4eb6c62 Merge pull request #2652 from proddy/dev
fix HA obj_id/default_entity_id fix
2025-10-08 21:42:48 +02:00
proddy
ee4f58ce20 HA obj_id/default_entity_id fix - #2640 2025-10-08 21:38:56 +02:00
proddy
0fe0ee77b3 package update 2025-10-08 21:38:26 +02:00
Proddy
74e58aaa3d Merge pull request #2651 from MichaelDvP/dev
add SRC tags,no remote for Junkers_old
2025-10-08 16:49:18 +02:00
MichaelDvP
d39d6c7f1f Junkers old does not support remote thermostats 2025-10-08 12:03:21 +02:00
MichaelDvP
4043eaf271 add tag for SRC plus SingleRoomControllers 2025-10-08 12:02:55 +02:00
Proddy
73ac60a8b2 Merge pull request #2650 from proddy/dev
auto-update
2025-10-08 09:11:21 +02:00
proddy
1d6b283033 auto-gen files 2025-10-08 09:10:27 +02:00
proddy
08ca4e44e8 auto-update 2025-10-08 09:10:18 +02:00
Proddy
255c173469 Merge pull request #2647 from MichaelDvP/dev
fixes and additions, see description
2025-10-07 17:38:33 +02:00
MichaelDvP
aeee318cca skip frequ-measurement in standalone build 2025-10-07 12:38:19 +02:00
MichaelDvP
eb14e89c35 fix writing calIntTemp for remote thermostats #2646 2025-10-07 10:36:48 +02:00
MichaelDvP
8411ea6773 fix forceheatingoff ems+ 2025-10-07 09:35:53 +02:00
MichaelDvP
015110a72e changelog, dev19 2025-10-07 09:00:27 +02:00
MichaelDvP
dae345f359 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-10-07 08:15:07 +02:00
MichaelDvP
4cfd9b699c fix misuse of forceheatingoff 2025-10-07 07:23:27 +02:00
Proddy
bd6371fd9d Merge pull request #2630 from proddy/dev
API changes
2025-10-06 23:23:54 +02:00
proddy
7507596869 update tests 2025-10-06 22:17:38 +02:00
proddy
5d99bd923b remove comment 2025-10-06 22:17:32 +02:00
proddy
7402776248 fix string compare for value 2025-10-06 22:17:23 +02:00
proddy
8b5cc82df9 package update 2025-10-06 22:17:07 +02:00
MichaelDvP
7c5351f15f add Greenstar 2000 boiler #2645 2025-10-06 18:28:14 +02:00
MichaelDvP
b29f02e5dd remove scan deep 2025-10-06 18:22:12 +02:00
MichaelDvP
e9e7162bcd typos, update 2025-10-06 08:59:16 +02:00
proddy
b24aae9123 Merge branch 'dev' of https://github.com/proddy/EMS-ESP32 into dev 2025-10-05 21:18:29 +02:00
proddy
9dbd634322 reduce brightness of RGB LED (bbqkees request) 2025-10-05 21:18:28 +02:00
proddy
daffc94c7f add message api example 2025-10-05 20:09:43 +02:00
proddy
93de0e2f42 clear old sensors when testing standalone 2025-10-05 15:36:30 +02:00
proddy
145172b6e9 have system/message API parse logic via shuntingyard 2025-10-05 15:36:11 +02:00
proddy
c4a2f8bac8 don't check mqtt if not using 2025-10-05 15:35:34 +02:00
proddy
0c0c928efc init list 2025-10-05 15:35:17 +02:00
proddy
4d829b0b78 add nullptr check 2025-10-05 15:35:03 +02:00
proddy
01e7d9b027 add consts 2025-10-05 15:34:52 +02:00
proddy
439da1d1e9 add comment 2025-10-05 15:34:41 +02:00
proddy
ac45c17204 merge Michael's changes 2025-10-05 15:34:30 +02:00
proddy
cd24c7815b merge Michael's change 2025-10-05 15:33:55 +02:00
proddy
9665efbf38 add checks, add a const, clear old scheduler items when testing standalone 2025-10-05 15:33:37 +02:00
proddy
d8aafdbfd4 code cleaning 2025-10-05 15:33:01 +02:00
proddy
0c6aef5b60 clean up standalone tests 2025-10-05 15:32:38 +02:00
proddy
48a1bd0fe6 dev.18 2025-10-05 15:32:18 +02:00
proddy
44cfffe8a4 add 2 more tests 2025-10-05 15:32:09 +02:00
proddy
e75bf8871e update tests 2025-10-05 15:32:00 +02:00
proddy
22703f4100 bump asynctcp, increase asynctcp stack from 6 to 8KB 2025-10-05 15:31:39 +02:00
proddy
c066ab8400 update dictionary 2025-10-05 15:17:16 +02:00
proddy
4a0625e31c fix debug section for S3 2025-10-05 15:16:30 +02:00
proddy
9aaaba5bb7 package update 2025-10-05 15:16:16 +02:00
MichaelDvP
689a3a9a69 selflowtemp and forceheatingoff for ems+ telegrams (2E0 command) 2025-10-05 09:22:46 +02:00
MichaelDvP
391a312f0c add CR11 calinttemp 2025-10-05 07:45:24 +02:00
MichaelDvP
f782eac0cf rename HA dev_i, SRC: do not fetch inactive circuits, long names, HA climated 2025-10-02 11:49:53 +02:00
MichaelDvP
d88513d789 SRC thermostat test, update1 2025-09-30 08:48:56 +02:00
MichaelDvP
59d07e81d6 test SRC Plus implementation, #2636 2025-09-29 12:47:08 +02:00
MichaelDvP
419fe8ef5d dev 18, changelog 2025-09-26 08:47:48 +02:00
MichaelDvP
4cfcba18ee analogsensors pulse output #2624 and frequncy input #2631 2025-09-26 08:47:31 +02:00
MichaelDvP
b1d6ab3c96 ventilation bypass state from 0x55C, #1197 2025-09-26 08:46:11 +02:00
MichaelDvP
ae26754bc8 update pkg 2025-09-26 08:44:58 +02:00
MichaelDvP
61c3b47269 fix display partition name, remove double quotes in shuntingyard 2025-09-25 17:11:21 +02:00
proddy
50bedb2b39 some refactoring 2025-09-21 19:20:04 +02:00
proddy
13db83a6de support plain text POSTs to APIs 2025-09-21 19:19:25 +02:00
proddy
ec43a07866 add shuntingyard tests 2025-09-21 19:18:58 +02:00
proddy
fbc11b8ef8 update unit tests 2025-09-21 19:18:32 +02:00
proddy
f1c5a911f9 special checks for message command 2025-09-21 19:18:19 +02:00
proddy
76c0aa6be8 shuntingyard as a class library 2025-09-21 19:16:55 +02:00
proddy
61bf2332bb update words 2025-09-21 19:16:16 +02:00
proddy
39ca956e1f update libs 2025-09-21 19:16:05 +02:00
proddy
0683b77437 remove TODOs 2025-09-21 19:15:43 +02:00
proddy
5da2760dc6 fix sonar checks 2025-09-21 19:15:29 +02:00
proddy
3fabaf900f auto-update 2025-09-21 19:15:09 +02:00
MichaelDvP
b2a8738672 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-09-16 17:19:44 +02:00
MichaelDvP
c3b9c1ef98 revert commit 4b2468d61 to fix wifi issue with tasmota core 2025-09-16 14:52:30 +02:00
Proddy
aef6b6e92d Merge pull request #2620 from nename0/scheduler-nested-json
Nested JSON structured in Scheduler HTTP fetch
2025-09-11 13:14:37 +02:00
Proddy
dc46dac02a Merge pull request #2623 from MichaelDvP/dev
fix link, #2622
2025-09-09 15:56:40 +02:00
MichaelDvP
025c430611 fix link, #2622 2025-09-09 15:49:57 +02:00
nename0
995ab7233d Add "keys" for nested values in scheduler HTTP response 2025-09-07 11:50:38 +02:00
Proddy
1507989ca3 Merge pull request #2617 from MichaelDvP/dev 2025-09-02 17:13:27 +02:00
MichaelDvP
022e808b14 allow API post single value (with content-Type:application/json) 2025-09-02 12:12:26 +02:00
Proddy
9b604e9c78 Merge pull request #2615 from MichaelDvP/dev 2025-08-31 14:36:40 +02:00
MichaelDvP
cd3cc09386 fix board from fuse for S32S3 2025-08-30 09:54:07 +02:00
MichaelDvP
0df21a7843 do not mention fuse in board details 2025-08-29 10:45:48 +02:00
MichaelDvP
9225ad2ad9 workaround for platform 6.12 2025-08-29 09:06:32 +02:00
MichaelDvP
227b1ac59b revert to platform 6.11, GH action fails with 6.12 2025-08-28 10:53:19 +02:00
MichaelDvP
a9a6e32dd1 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-08-28 10:43:09 +02:00
MichaelDvP
3c4278029f BBQKees board settings/fuse, remove esp32 cpu temperature, dev17 2025-08-28 09:40:01 +02:00
MichaelDvP
3b4e09208e CR11 mode setting, FW200 display settings 2025-08-28 09:12:55 +02:00
Proddy
e9e0688737 Merge pull request #2614 from proddy/dev
lib updates
2025-08-28 07:27:43 +02:00
proddy
7bb1b7bb91 update library and re-gen files 2025-08-28 07:23:51 +02:00
proddy
4302bc9978 added dev-15 updates 2025-08-28 07:23:42 +02:00
proddy
60d884df88 auto-format 2025-08-28 07:23:26 +02:00
proddy
177c635bc1 add c6 (experimental), upgrade AsyncWebServer 2025-08-28 07:23:11 +02:00
Proddy
9a97c28bf0 Merge pull request #2613 from MichaelDvP/dev
dev16
2025-08-24 10:22:20 +02:00
MichaelDvP
deb87cf5d7 fix standalone 2025-08-23 19:25:59 +02:00
MichaelDvP
a50227638b fix boiler wwMaxPower and ww_disinfect, dev16 2025-08-18 17:34:16 +02:00
MichaelDvP
92b1515c8a update pkg 2025-08-14 07:52:12 +02:00
MichaelDvP
0c5cf0475c Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-08-05 18:45:10 +02:00
Proddy
f26e937514 Update sonar 2025-08-04 20:48:55 +02:00
Proddy
1e4ca8b57f Merge pull request #2603 from proddy/dev
small updates
2025-08-04 17:38:28 +02:00
proddy
4d88bbd28f package update 2025-08-04 17:36:35 +02:00
proddy
0ce110df9e add back factory reset after long button press - we missed in pull/1969 2025-08-04 17:36:30 +02:00
proddy
3759fc81ba asynctcp 3.4.7 2025-08-04 17:35:46 +02:00
MichaelDvP
7965ecd856 NTC parameters for E32V2.2 P2B 2025-08-04 10:30:40 +02:00
MichaelDvP
7b0169bb68 update to eModbus 1.7.4 2025-08-04 10:16:50 +02:00
MichaelDvP
f10f3d5305 esp32: some pins have no internal pullup 2025-08-04 10:15:59 +02:00
MichaelDvP
ed9e2704b0 syslog, changing level is not a fail 2025-08-04 10:15:15 +02:00
proddy
c47dd0e523 add option for Arduino Core 3.3 2025-08-03 10:57:09 +02:00
proddy
80c75bae77 package update 2025-08-03 10:56:56 +02:00
MichaelDvP
cfa973b08b fix standalone 2025-08-02 16:07:27 +02:00
MichaelDvP
83987b71e0 MM100 flow and pressure 2025-08-02 13:08:09 +02:00
MichaelDvP
a318f34988 update packages 2025-08-02 13:04:24 +02:00
MichaelDvP
5cc1660675 update AsyncTCP 3.4.7 2025-08-02 13:03:45 +02:00
MichaelDvP
8a48da38b8 revert to fetch mixer config 2025-07-31 18:56:17 +02:00
MichaelDvP
d514e67eb8 update pkg 2025-07-31 18:55:37 +02:00
MichaelDvP
69964482f8 AsyncTCP 3.4.6, check log queue for overflow 2025-07-31 18:55:23 +02:00
MichaelDvP
2aa691212c add command system/fuse/mfg, board E32V2.2, check systemvolatage >2.6V 2025-07-28 14:16:10 +02:00
MichaelDvP
c27134f185 fix gpio for core voltage detect 2025-07-23 20:39:24 +02:00
MichaelDvP
c8033692b1 update pkg 2025-07-23 20:36:22 +02:00
MichaelDvP
c537d0ab8b add gateway E32V3, autodetect by gpio39 core voltage 2025-07-23 18:47:33 +02:00
MichaelDvP
bee703eb1f test: fetch MM100 config only once 2025-07-23 11:56:27 +02:00
MichaelDvP
5d2bd6a2af set climate action cooling 2025-07-23 11:55:11 +02:00
MichaelDvP
67f0f40a8a Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-07-14 07:33:47 +02:00
Proddy
e796fbef7a Merge pull request #2594 from proddy/dev
bump to 3.7.3-dev.14
2025-07-10 21:01:13 +02:00
proddy
da7ef04741 3.7.3-dev.14 2025-07-10 21:00:14 +02:00
proddy
ddb318dfc6 package update 2025-07-10 20:59:36 +02:00
proddy
88643dc8e3 update 2025-07-10 20:59:31 +02:00
MichaelDvP
cf3854563d Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-07-10 12:12:28 +02:00
MichaelDvP
4b2468d616 some checks 2025-07-10 12:09:17 +02:00
Proddy
4b08aba9c4 Merge pull request #2593 from proddy/dev
minor updates and ESP32Async/AsyncTCP back to v3.4.2
2025-07-08 22:08:50 +02:00
proddy
0a18add447 show ems device details in MQTT HA screen 2025-07-08 22:05:45 +02:00
proddy
ca8d23ff3a package update 2025-07-08 22:05:28 +02:00
proddy
c7e833194f ESP32Async/AsyncTCP @ 3.4.2 2025-07-08 22:05:15 +02:00
Proddy
f63f658421 Merge pull request #2588 from misa1515/patch-25
Update locale_translations.h
2025-07-01 07:34:41 +02:00
misa1515
13fcf09470 Update locale_translations.h 2025-06-30 21:51:18 +02:00
Proddy
f560cbd60c Merge pull request #2587 from proddy/dev
package updates
2025-06-30 15:46:08 +02:00
proddy
38ead7e10f update arduinojson, espressif-platform and web packages 2025-06-30 15:42:38 +02:00
proddy
326bba9b42 package update 2025-06-29 13:39:36 +02:00
proddy
d9a18bf255 auto-gen 2025-06-29 13:39:31 +02:00
MichaelDvP
6c42cbfb4b make task cores configurable in platformio.ini 2025-06-28 13:00:53 +02:00
MichaelDvP
6691c81956 test for #2585 2025-06-25 17:46:38 +02:00
MichaelDvP
2f95ef305d roll back to asyncTCP 3.4.2, add CS6800 mixer 2025-06-25 13:33:44 +02:00
proddy
7afde0ce6e auto-update 2025-06-14 09:30:54 +02:00
proddy
f3cdafe7d0 ESPAsyncWebServer 3.7.8 support 2025-06-14 09:30:47 +02:00
Proddy
4bf23e1bda Merge pull request #2582 from MichaelDvP/dev
hybrid csh5800iG and fix crashes
2025-06-13 18:53:16 +02:00
MichaelDvP
aca66457f9 fixes crashs: revert to platform 6.10.0 2025-06-13 08:52:02 +02:00
MichaelDvP
121887bdce Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-06-11 11:35:29 +02:00
MichaelDvP
32d7cf4e9c fix possible crash 2025-06-11 11:35:01 +02:00
Proddy
3f8227e95e Merge pull request #2580 from proddy/dev
MQTT HA discovery refactoring
2025-06-10 21:59:25 +02:00
proddy
10d84261da add another version test for downgrading 2025-06-10 11:19:39 +02:00
proddy
51848d8347 auto translate 2025-06-10 11:19:26 +02:00
proddy
1c0669144f update docs 2025-06-10 11:19:16 +02:00
proddy
41a2ba6e5d fixes #2579 2025-06-09 16:07:26 +02:00
proddy
b6fe9e7569 package update 2025-06-09 16:07:00 +02:00
MichaelDvP
faa2c5f1aa set CS5800iG as gas boiler and HP, #2569 2025-06-07 11:57:53 +02:00
MichaelDvP
c71034ff12 analog counter save to nvs on command and update 2025-06-07 11:57:01 +02:00
proddy
71be615bbe add HP CS5800iG #2569 2025-06-06 17:24:11 +02:00
Proddy
ce53fd1d04 Merge pull request #2575 from proddy/dev
some minor fixes and updates
2025-06-05 19:31:29 +02:00
proddy
1772876f9e 3.7.3-dev.12 2025-06-05 19:31:04 +02:00
proddy
cd5dbebea9 package update 2025-06-05 19:30:47 +02:00
proddy
6c67b78a1c package update 2025-06-05 10:46:29 +02:00
proddy
9b4deb271b update async lib 2025-06-04 08:35:59 +02:00
proddy
0e9283af5c add test for hpmode over mqtt 2025-06-04 08:35:53 +02:00
proddy
58011700fe package update 2025-06-04 08:35:39 +02:00
proddy
079a08ff7b upercase mqtt 2025-06-01 21:34:09 +02:00
proddy
b64a55e460 https://github.com/emsesp/EMS-ESP32/discussions/2550 - publish sensor when interval is set to 0(auto) 2025-06-01 18:51:02 +02:00
proddy
2b7ef5b6ba AsyncTCP @ 3.4.3 2025-06-01 17:40:15 +02:00
proddy
d62eef4eca 3.7.3-dev.12 2025-06-01 12:48:56 +02:00
proddy
0f6d6e69f5 package update 2025-06-01 12:43:27 +02:00
proddy
97f689b8a7 add comment for reference 2025-06-01 12:41:52 +02:00
proddy
be9b4a070c remove duplicate no-watch 2025-06-01 12:41:27 +02:00
proddy
bc15dd4463 lib updates 2025-06-01 12:41:10 +02:00
proddy
1613caea86 MQTT Command Topic with slashes #2571 2025-06-01 12:40:53 +02:00
proddy
4b39ab76ab MQTT Command Topic with slashes #2571 2025-06-01 12:40:42 +02:00
Proddy
d04c882590 Merge pull request #2566 from proddy/dev
pnpm mods
2025-05-25 11:08:25 +02:00
proddy
a199bf21e1 pnpm mods 2025-05-25 11:07:11 +02:00
Proddy
3ae8722ece Merge branch 'emsesp:dev' into dev 2025-05-24 10:11:39 +02:00
Proddy
6a6cef57cf Merge pull request #2565 from MichaelDvP/dev
remove optimistic option #2551
2025-05-23 17:04:11 +02:00
MichaelDvP
090491aab6 remove optimistic option #2551 2025-05-23 07:42:21 +02:00
MichaelDvP
ca81a02a8c masked enums with single mask, update seltemp in advance 2025-05-23 07:41:43 +02:00
proddy
f64188bd5d update pkg 2025-05-22 22:08:45 +02:00
Proddy
d3e0f180c5 Merge pull request #2559 from emsesp/alert-autofix-36
Potential fix for code scanning alert no. 36: Workflow does not contain permissions
2025-05-18 21:26:38 +02:00
Proddy
3f4d87a1d2 Merge pull request #2560 from emsesp/alert-autofix-35
Potential fix for code scanning alert no. 35: Workflow does not contain permissions
2025-05-18 21:26:30 +02:00
Proddy
1d89e651a4 Merge pull request #2561 from emsesp/alert-autofix-34
Potential fix for code scanning alert no. 34: Workflow does not contain permissions
2025-05-18 21:26:24 +02:00
Proddy
fad67b4ef9 Potential fix for code scanning alert no. 34: Workflow does not contain permissions
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2025-05-18 18:25:34 +02:00
Proddy
ce1c22ee35 Potential fix for code scanning alert no. 35: Workflow does not contain permissions
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2025-05-18 18:25:10 +02:00
Proddy
169b5f34ea Potential fix for code scanning alert no. 36: Workflow does not contain permissions
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2025-05-18 18:24:36 +02:00
Proddy
131c03714f Merge pull request #2558 from proddy/dev
replace yarn with pnpm
2025-05-18 18:02:18 +02:00
proddy
024c4a0c21 replace yarn with pnpm 2025-05-18 18:00:46 +02:00
proddy
b0d111d86f test pnpm 2025-05-18 17:36:08 +02:00
proddy
faeef9c821 remove yarn 2025-05-18 17:36:01 +02:00
proddy
60a5b28a21 pnpm 2025-05-18 16:25:22 +02:00
proddy
f4b5cf04a0 update asyncweb mention 2025-05-18 16:24:02 +02:00
proddy
d69f26acac upgrade yarn to pnpm because why not 2025-05-18 15:53:38 +02:00
Proddy
2a50701107 Merge pull request #2557 from proddy/dev
mqtt tidy up and shower active fixed for HA
2025-05-18 11:48:59 +02:00
proddy
ab099c45b8 updated 2025-05-18 11:48:13 +02:00
proddy
47f21019a0 clean-up publish retain functions 2025-05-18 11:47:22 +02:00
proddy
5c473c2b3d shower active is shown in HA on EMS-ESP boot 2025-05-18 11:47:04 +02:00
proddy
9ddc587334 add comment 2025-05-18 11:46:45 +02:00
proddy
9b0a7a4872 AsyncTCP 3.4.1 2025-05-18 11:46:28 +02:00
Proddy
97528e9df6 Merge pull request #2556 from proddy/dev
minor updates
2025-05-17 11:17:47 +02:00
proddy
b797e1e2bb eslint update 2025-05-17 11:01:27 +02:00
proddy
bb52d35c99 add comments 2025-05-17 10:24:25 +02:00
proddy
4c9026e11a fix standalone osx 2025-05-16 19:34:54 +02:00
proddy
6cd4e8a5b6 run update_all 2025-05-16 09:22:58 +02:00
Proddy
dfe037a7d3 Merge pull request #2547 from vmonkey/patch-6
Small update-Czech
2025-05-16 08:03:20 +02:00
Proddy
b87622185d Merge pull request #2554 from MichaelDvP/dev
fixes and additions
2025-05-16 08:03:03 +02:00
MichaelDvP
0318f8156d fix standalone 2025-05-12 19:10:59 +02:00
MichaelDvP
0c03fa1308 mqtt publish_time sensors instead of temperature sensors 2025-05-12 16:49:33 +02:00
MichaelDvP
2d6e02171f Typo 2025-05-12 16:47:33 +02:00
MichaelDvP
2da312bf15 optimistic only for writable values 2025-05-12 16:29:36 +02:00
MichaelDvP
52f59a7b1d fix set chargeoptimization #2543 2025-05-12 08:00:14 +02:00
MichaelDvP
6c8624298c devices entity search case-independend, #2553 2025-05-11 18:47:21 +02:00
MichaelDvP
ce2d2fb867 search entities case independend #2553 2025-05-11 15:01:34 +02:00
MichaelDvP
ba2ad4e175 typo 2025-05-11 15:00:41 +02:00
MichaelDvP
b3320c3e48 ha optimistic, cs6800 changes, custom entity hide 2025-05-10 16:14:54 +02:00
MichaelDvP
dc1094b6ba show ntp connect in log 2025-05-10 13:36:40 +02:00
MichaelDvP
bb60568d83 update pkg 2025-05-10 13:36:11 +02:00
MichaelDvP
67b5c5dd26 chargeOptimization #2543, charging pump #2544 2025-05-06 19:14:31 +02:00
MichaelDvP
6866d5b7a9 update pkg 2025-05-05 18:29:06 +02:00
Marek Tyburec
b4e9af89ee Small update-Czech
Fix Czech grammar in dashboard
2025-05-04 07:12:32 +02:00
Proddy
775ed99b22 Merge pull request #2539 from proddy/dev
add back formidable to fix build without mock-api
2025-04-25 18:29:08 +02:00
proddy
2ec13273fd update lock file 2025-04-25 18:27:12 +02:00
proddy
a846b01103 auto-generate 2025-04-25 18:27:00 +02:00
proddy
6dffb08545 add back formidable 2025-04-25 18:26:52 +02:00
Proddy
16f7cc148d Merge pull request #2538 from MichaelDvP/dev
use messagetime in WebLogService::show() #2533
2025-04-25 18:18:24 +02:00
MichaelDvP
568431ada4 use messagetime in WebLogService::show() 2025-04-25 12:16:33 +02:00
Proddy
6034c1e5eb Merge pull request #2535 from MichaelDvP/dev
show console log with ISO date/time, #2533
2025-04-25 09:18:06 +02:00
MichaelDvP
e3566feefb show console log with ISO date/time, #2533 2025-04-25 08:05:15 +02:00
MichaelDvP
ea46c79278 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-04-24 10:25:16 +02:00
MichaelDvP
a02831e04e read only first error log message 2025-04-24 10:23:54 +02:00
MichaelDvP
3b8c973f2a fix debug message in console help 2025-04-24 10:23:34 +02:00
MichaelDvP
2c65936b3e update pkg 2025-04-24 10:23:11 +02:00
Proddy
bc04c34d58 Merge pull request #2532 from proddy/dev
add tests for custom commands
2025-04-23 21:43:38 +02:00
proddy
5047f1752e add tests for custom entities 2025-04-23 21:30:02 +02:00
proddy
1fa7a6c549 package update 2025-04-23 21:29:30 +02:00
MichaelDvP
f9ebe33a7d read thermostat errorlog 0xC0 on 0xBF 2025-04-23 09:36:00 +02:00
Proddy
e719dd963d Merge pull request #2530 from proddy/dev
updated libs and fix for domoticz discovery warnings
2025-04-22 16:08:16 +02:00
proddy
c6b0099581 domoticz warnings on custom entities - https://github.com/emsesp/EMS-ESP32/discussions/2408#discussioncomment-12896868 2025-04-22 16:07:22 +02:00
proddy
71726530c0 auto-generated 2025-04-22 16:06:49 +02:00
proddy
a749ecb298 ArduinoJson 7.4.1 and updated AsyncWS libs 2025-04-22 16:06:41 +02:00
proddy
7e963529c4 package update 2025-04-22 16:06:18 +02:00
Proddy
c76409cf3f Merge pull request #2529 from MichaelDvP/dev
dev.9: fix writing auxHeaterSource #2489
2025-04-22 11:05:34 +02:00
MichaelDvP
efd0872690 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-04-22 07:23:28 +02:00
MichaelDvP
57098b578f fix writing auxHeaterSource #2489 2025-04-22 06:58:23 +02:00
Proddy
6472e9e224 run at 1:30am 2025-04-21 09:06:37 +02:00
Proddy
026828efc7 Merge pull request #2528 from MichaelDvP/dev
fix GH build
2025-04-20 21:43:38 +02:00
MichaelDvP
fe6e9be4d3 fix GH build 2025-04-20 18:12:59 +02:00
Proddy
7745a6f9a1 Merge pull request #2527 from MichaelDvP/dev 2025-04-20 17:56:56 +02:00
MichaelDvP
c523a379fe add C6 telegram, fixes #1963 2025-04-20 17:07:30 +02:00
MichaelDvP
2854e9cbe9 IPM DHW module, fixes #2524 2025-04-20 17:03:03 +02:00
Proddy
4985f104c7 Merge pull request #2526 from proddy/dev
small changes
2025-04-19 12:54:28 +02:00
proddy
a0ea5f7ea1 clean-up unused packages 2025-04-19 12:52:58 +02:00
proddy
efc35d0594 update react-table-library for React 19 2025-04-19 11:46:42 +02:00
proddy
ccd6c6f8ad workarond for missing package 2025-04-19 09:08:35 +02:00
proddy
b426e0eb45 move NTP set time to Settings page 2025-04-18 16:19:07 +02:00
proddy
c53e1de569 update translations 2025-04-18 16:18:54 +02:00
proddy
8058e98748 update packages 2025-04-18 16:18:41 +02:00
proddy
ba419d09eb add Michael's https://github.com/emsesp/EMS-ESP32/pull/2522# 2025-04-18 16:18:08 +02:00
proddy
c701247652 auto-generate 2025-04-18 16:17:35 +02:00
proddy
12754d1c07 https://github.com/emsesp/EMS-ESP32/discussions/2523 2025-04-18 16:17:21 +02:00
Proddy
9a4daba31a Merge pull request #2521 from misa1515/patch-24
Update index.ts
2025-04-16 15:06:07 +02:00
misa1515
a2aa2dccdd Update index.ts 2025-04-15 21:46:19 +02:00
Proddy
25af51a8e8 Merge pull request #2517 from proddy/dev
update packages
2025-04-12 09:10:13 +02:00
proddy
ddc597ff03 update packages 2025-04-12 09:09:52 +02:00
Proddy
75310afd63 Merge pull request #2515 from MichaelDvP/dev
FB100 controls hc1, fixes #2510
2025-04-12 09:06:04 +02:00
MichaelDvP
3095323c93 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-04-10 12:57:40 +02:00
Proddy
4667718f12 Merge pull request #2513 from proddy/dev
arduinojson 7.4 and package update
2025-04-10 08:18:00 +02:00
proddy
2cb1c5d7e7 arduinojson 7.4 and package update 2025-04-10 08:16:33 +02:00
MichaelDvP
d7b9754ddb do not create hc on empty message 2025-04-09 17:38:58 +02:00
MichaelDvP
99b769626e check dv.hasValue for commands 2025-04-09 13:30:40 +02:00
MichaelDvP
70035b059c comment out HA config of shower timestamp 2025-04-08 17:59:01 +02:00
MichaelDvP
b252c2f95a FB100 controls hc1, fixes #2510 2025-04-08 17:53:06 +02:00
Proddy
baa4f2eb39 Merge pull request #2508 from proddy/dev
fixes #2507 - download based on tasmota builds
2025-04-05 10:56:03 +02:00
proddy
c7b970b5b0 auto-generated 2025-04-05 10:55:01 +02:00
proddy
3ed5b65191 fixes #2507 2025-04-05 10:54:55 +02:00
Proddy
6e01c00d46 Merge pull request #2506 from MichaelDvP/dev
remove wifi full scan
2025-04-04 10:30:23 +02:00
MichaelDvP
e72afc9065 remove wifi full scan, dev.6 2025-04-04 08:24:59 +02:00
MichaelDvP
de2f3e712d updte pkg 2025-04-04 08:20:00 +02:00
Proddy
cacb92cd47 Merge pull request #2504 from MichaelDvP/dev
some smaller fixes
2025-04-03 09:51:26 +02:00
MichaelDvP
3eb20fa700 add some HA config on mqtt reconnect 2025-04-02 17:49:22 +02:00
MichaelDvP
d35574d494 update pkg 2025-04-02 17:48:27 +02:00
MichaelDvP
3cb29220ab fetch first c0 telegram #2501 2025-04-01 18:58:59 +02:00
MichaelDvP
d91812ab8f add thermostat C0 message #2501 2025-04-01 12:41:21 +02:00
MichaelDvP
856f8efd25 update scheduler if there is pending change #2502 2025-04-01 12:34:02 +02:00
MichaelDvP
d32378ccd4 do not scan methode for arduino 3 2025-04-01 12:33:04 +02:00
MichaelDvP
f5006d1a11 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-03-31 10:50:23 +02:00
Proddy
c3468e6308 Merge pull request #2498 from proddy/dev
fixes #2497
2025-03-31 10:19:13 +02:00
proddy
9f4de56099 switch between dev and stable 2025-03-31 10:18:32 +02:00
proddy
78738de811 version update text changes 2025-03-31 10:18:21 +02:00
proddy
e64596ad61 updated comments 2025-03-31 10:17:33 +02:00
proddy
024357ae80 bump 3.7.3-dev.4 2025-03-31 10:17:19 +02:00
proddy
3f07d3b75f ignore local yarn 2025-03-31 10:17:05 +02:00
proddy
cb7c695c67 tidy up 2025-03-30 15:13:52 +02:00
proddy
912a764c2d package update 2025-03-30 15:13:40 +02:00
proddy
c9c0f55b64 remove optimizer 2025-03-30 15:13:15 +02:00
proddy
6991677cf9 improve version check, #1497 2025-03-30 14:51:59 +02:00
proddy
83330907cd added full tests for different version upgrades, both backend and webUI 2025-03-30 14:51:13 +02:00
proddy
3571998da3 rename version.h 2025-03-30 14:50:40 +02:00
MichaelDvP
77465ebe81 always show buttons for stable and dev 2025-03-30 14:11:02 +02:00
MichaelDvP
006e5493e2 reactivate wifi all channel scan 2025-03-30 14:09:02 +02:00
proddy
b29136433d 3.7.3 2025-03-30 10:18:45 +02:00
proddy
0347a4b8b0 fix possible out of scope warning 2025-03-30 10:18:38 +02:00
proddy
3330103a8d compile with IDF 5 2025-03-30 10:18:24 +02:00
proddy
0a02252fee move experimental IDF 5 to pio_local.ini 2025-03-30 10:17:44 +02:00
proddy
642f2116d2 testing Arduino Core v3.2.0 / ESP-IDF v5.4.1 2025-03-29 08:08:54 +01:00
proddy
7b8e45c2f7 package update 2025-03-29 08:05:53 +01:00
proddy
0f2244607f fixes #2497 - showFirmwareDialog() was missing argument 2025-03-28 17:23:46 +01:00
proddy
32ab9dda45 replace reset with restart 2025-03-28 17:22:36 +01:00
proddy
b6659b8586 auto-generate 2025-03-28 17:22:20 +01:00
proddy
5eb85066ef package update 2025-03-28 17:22:11 +01:00
proddy
9398fc72a0 update version check tests 2025-03-28 17:20:25 +01:00
MichaelDvP
1bcd453e3f fix version links for dev #2497 2025-03-28 16:46:49 +01:00
MichaelDvP
d405478a13 fix deviceName length (#2482), formatting 2025-03-28 09:39:38 +01:00
Proddy
c927e5f496 Merge pull request #2496 from MichaelDvP/dev
fix secure mqtt and add auxHeaterSource
2025-03-27 18:37:12 +01:00
MichaelDvP
c5dbd7452e add auxHeaterSource #2489 2025-03-27 17:23:42 +01:00
MichaelDvP
3a0b4ea587 fix switch to secure mqtt #2492 2025-03-27 13:57:59 +01:00
MichaelDvP
6f4cdb7122 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-03-27 07:50:12 +01:00
Proddy
b5d6757660 Merge pull request #2493 from proddy/dev
upgrade mui v7, fix makefile build
2025-03-26 22:09:56 +01:00
proddy
0dcde46296 upgrade mui v7, fix makefile build 2025-03-26 20:24:08 +01:00
Proddy
ac7e91beff Merge pull request #2491 from MichaelDvP/dev
fixes and additions
2025-03-26 18:42:19 +01:00
MichaelDvP
9ea1e2752d update pkg, Grid2->Grid 2025-03-26 17:30:33 +01:00
MichaelDvP
b5471aef94 fix typo in set_wwswitchtime, fixes #2490 2025-03-26 17:03:51 +01:00
MichaelDvP
f31329ceff fix dhw progMode, #2490 2025-03-26 07:16:08 +01:00
MichaelDvP
40d48f4407 add FLAG_HMC310, fix switchtimeWW 2025-03-25 18:13:43 +01:00
MichaelDvP
11b7e1f86e update pkg 2025-03-24 18:44:02 +01:00
MichaelDvP
e364a71eda Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-03-23 18:35:08 +01:00
Proddy
e006bebb86 Merge pull request #2488 from proddy/dev
rename github actions
2025-03-23 16:56:40 +01:00
proddy
fa3d42a1c7 rename github actions 2025-03-23 16:55:57 +01:00
Proddy
e435fd4391 Merge pull request #2487 from proddy/dev
clean-up
2025-03-23 15:46:17 +01:00
proddy
d42efb32ab clean-up 2025-03-23 15:45:53 +01:00
proddy
ad8f2dc823 add 2025-03-23 15:43:07 +01:00
Proddy
f2ff14f511 Merge pull request #2479 from proddy/dev
fix test data
2025-03-23 14:01:26 +01:00
proddy
e5e9d4c713 fix test data with led_type 2025-03-23 14:00:46 +01:00
proddy
4c5f93000b add led_type to comment 2025-03-23 14:00:35 +01:00
proddy
0c7301a020 TYPE has param 2025-03-23 14:00:20 +01:00
MichaelDvP
74c63bf17e set HMC310 to BC400 compatible 2025-03-23 10:07:22 +01:00
MichaelDvP
4564e0b828 fix printable chars in lastcode 2025-03-23 10:06:49 +01:00
Proddy
2ab9607989 Merge pull request #2478 from misa1515/patch-23
Update index.ts
2025-03-23 07:34:25 +01:00
misa1515
29d198b46d Update index.ts 2025-03-22 22:41:41 +01:00
MichaelDvP
8387ca0c07 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-03-22 11:59:04 +01:00
MichaelDvP
3796fb8027 add analog sensor NTC and RGB-Led, dev29 2025-03-22 11:41:37 +01:00
MichaelDvP
1da08633ec add scheduler random function (rnd(x) => random 0..x) 2025-03-22 11:41:00 +01:00
MichaelDvP
b097e372e4 update pkg and libs 2025-03-22 11:39:48 +01:00
Proddy
846776929e Merge pull request #2475 from proddy/dev
3.7.3-dev.0
2025-03-22 10:44:09 +01:00
proddy
6e1d56b8ee 3.7.3-dev.0 2025-03-22 10:43:44 +01:00
Proddy
32f7eb7299 Merge pull request #2474 from proddy/dev
update prepare for 3.7.2 stable
2025-03-22 10:09:17 +01:00
proddy
3fc9c3b56c update prepare for 3.7.2 stable 2025-03-22 10:07:58 +01:00
Proddy
e2e46543d2 Merge pull request #2472 from JokerGermany/own1-program-switchtime---german-translation
make switchtime more clear in the german translation
2025-03-22 09:51:15 +01:00
JokerGermany
a2b22198ec make switchtime more clear in the german translation
"Programmschaltzeit 1" don't make clear that "Eigen 1" is meant.
2025-03-21 10:20:57 +01:00
Proddy
642b59f729 Merge pull request #2471 from MichaelDvP/dev
add suprapur-o, fixes #2470
2025-03-20 16:46:48 +01:00
MichaelDvP
9e81de2164 add Suprapur-o, dev28 2025-03-20 11:45:04 +01:00
MichaelDvP
d44797db1d update libs 2025-03-20 11:44:37 +01:00
MichaelDvP
673ee3f79b update pkg 2025-03-20 11:44:23 +01:00
Proddy
38a8179544 Merge pull request #2469 from proddy/dev
update test
2025-03-15 13:49:19 +01:00
proddy
cfb59ac6a0 update test 2025-03-15 13:48:56 +01:00
Proddy
80c26e1adb Merge pull request #2468 from MichaelDvP/dev
shuntingYard support empty strings
2025-03-15 13:47:19 +01:00
MichaelDvP
d0de6e8d0f Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-03-15 13:38:13 +01:00
Proddy
68be7d00ff Merge pull request #2466 from proddy/dev
added new return code when processing commands
2025-03-15 13:02:38 +01:00
proddy
d3e6043911 replace with LOG_DEBUG 2025-03-15 13:01:42 +01:00
proddy
373895b36a test for NO_VALUE in prep for Michael's change 2025-03-15 13:01:29 +01:00
proddy
594e10dbe1 formatting 2025-03-15 13:01:14 +01:00
proddy
e3c5b462da formatting 2025-03-15 13:01:05 +01:00
proddy
8a1376b169 add test for NO_VALUE 2025-03-15 13:00:47 +01:00
proddy
900e26cf9f package update 2025-03-15 13:00:31 +01:00
MichaelDvP
071e81f29b shuntingYard work with empty strings 2025-03-15 12:03:42 +01:00
proddy
d1bd861ff0 default return code is OK 2025-03-13 22:46:25 +01:00
proddy
f5925dbb3b formatting 2025-03-13 22:46:15 +01:00
proddy
b1eedcb1d8 add new return code NO_VALUE 2025-03-13 22:46:04 +01:00
proddy
ed7a9f43de update tests 2025-03-13 22:45:26 +01:00
proddy
67885950ef package update 2025-03-13 22:44:45 +01:00
Proddy
74ddb771e9 Merge pull request #2464 from MichaelDvP/dev
bitmask for bool custom entities as hex value
2025-03-13 08:40:33 +01:00
MichaelDvP
584d0e0b48 shuntingYard string addition, add tohex() function 2025-03-13 07:45:37 +01:00
MichaelDvP
8d9ca33ea3 bitmask for bool custom entities as hex value 2025-03-12 09:23:00 +01:00
Proddy
f0eea1a6a3 Merge pull request #2461 from MichaelDvP/dev 2025-03-11 10:53:35 +01:00
MichaelDvP
79cc0377c0 fix sonar fail for special characters in strings (ascii>127) 2025-03-11 10:00:10 +01:00
Proddy
115cec08fa Merge pull request #2460 from MichaelDvP/dev 2025-03-11 09:23:38 +01:00
MichaelDvP
6df592c2b8 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-03-11 07:33:30 +01:00
MichaelDvP
f2b81489ba mixed case strings in scheduler, #2457 2025-03-11 07:33:23 +01:00
Proddy
0d8760219a Merge pull request #2459 from proddy/dev
package updates, fix auto-gen of csv files
2025-03-10 21:58:23 +01:00
proddy
e8e8d9c130 3.7.2-dev.27 2025-03-10 21:57:18 +01:00
proddy
8f712412f5 package update 2025-03-10 21:47:16 +01:00
proddy
f8ece46163 changed comment 2025-03-10 21:47:07 +01:00
proddy
cd8b1add54 formatting 2025-03-10 21:46:55 +01:00
proddy
1c415a9715 re-generated 2025-03-10 21:46:36 +01:00
proddy
e1e3601640 add newline to fix csv gen 2025-03-10 21:46:20 +01:00
MichaelDvP
c2f718b49a shuntingYard mixed case, only compare and commands converted to lower case 2025-03-10 19:42:16 +01:00
Proddy
cee1874689 Merge pull request #2458 from MichaelDvP/dev
fixes #2456, #2457, shuntingYard tests from #2452
2025-03-10 18:38:38 +01:00
MichaelDvP
57d172aac2 Merge branch 'support_nested_conditionals' of https://github.com/philwingfield/EMS-ESP32 into dev 2025-03-10 11:59:09 +01:00
wingphil
bb26900213 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into support_nested_conditionals 2025-03-10 10:11:21 +00:00
wingphil
9d1ee27533 Add test for nested conditionals without brackets 2025-03-10 10:09:44 +00:00
MichaelDvP
7fd735f667 rename remoteseltemp to cooltemp, fix #2456 2025-03-10 11:02:03 +01:00
MichaelDvP
2e79c3a5c6 enlarge tx queue (overflow in #2455) 2025-03-10 10:56:31 +01:00
MichaelDvP
d769999f10 shuntingYard get api-data lowerCase, fix #2457 2025-03-10 10:55:15 +01:00
MichaelDvP
bd93d26361 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-03-09 17:35:50 +01:00
MichaelDvP
72feefe709 allow brackets in conditions (idea from philwingfield) 2025-03-08 16:50:12 +01:00
Proddy
1d6c2c9664 Merge pull request #2453 from MichaelDvP/dev
fix lastcode #2438, heating/tapwater for heatpumps from activity #2450
2025-03-07 20:51:41 +01:00
MichaelDvP
85c78bc8e9 update pkg 2025-03-07 18:23:40 +01:00
MichaelDvP
18bdcfe050 fix lastcode #2438, heating/tapwater for heatpumps from activity #2450 2025-03-07 18:12:36 +01:00
wingphil
a6f77250b5 Format with clang 2025-03-07 17:08:05 +00:00
wingphil
9874ecde82 feat: Support nested conditionals in shuntingYard 2025-03-07 16:53:41 +00:00
MichaelDvP
584b8788be Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-03-07 16:42:56 +01:00
Proddy
7eb15652c7 Merge pull request #2449 from MichaelDvP/dev
fix #2446, pc0Flow for all boilers, fix #2411
2025-03-07 13:00:48 +01:00
MichaelDvP
2c28a607ba Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-03-06 16:44:45 +01:00
wingphil
45eca462e7 test: Move shuntingYard tests to new file 2025-03-06 14:07:51 +00:00
wingphil
4474868afc Add tests for inline conditionals, try to capture current behaviour 2025-03-06 13:59:20 +00:00
wingphil
6c6b5b060d test: Copy shuntingYard tests so that we can assert the output 2025-03-06 13:27:12 +00:00
Proddy
c03eb290d1 Merge pull request #2447 from philwingfield/fix_unit_tests
Fix console unit tests due to changed shell output
2025-03-05 19:38:41 +01:00
wingphil
de9bd44071 Merge branch 'fix_unit_tests' of https://github.com/philwingfield/EMS-ESP32 into fix_unit_tests 2025-03-05 16:16:13 +00:00
wingphil
b7458b0686 test: fix console unit tests due to changed shell output 2025-03-05 16:14:45 +00:00
wingphil
a660ec1afa test: fix console unit tests due to changed shell output 2025-03-05 16:13:20 +00:00
MichaelDvP
c4f6f01f7e fix #2446, pc0Flow for all boilers, fix #2411 2025-03-05 14:20:40 +01:00
Proddy
9f60560f2b Merge pull request #2445 from proddy/dev
upload translation - thanks mattreim
2025-03-04 22:11:34 +01:00
proddy
7b50f80cb8 upload translation - thanks mattreim 2025-03-04 22:09:42 +01:00
Proddy
656d275c56 Merge pull request #2444 from proddy/dev
move Version back to Status page
2025-03-04 20:58:06 +01:00
proddy
eca17f2b2c move Version back to Status page 2025-03-04 20:57:24 +01:00
Proddy
7f60279aa3 Merge pull request #2443 from proddy/dev
fix autofresh in web
2025-03-04 20:26:15 +01:00
proddy
5227fafa1b fix auto refresh (disable cache) 2025-03-04 20:24:55 +01:00
proddy
4991e2b7cd add upload to Version page 2025-03-04 20:24:27 +01:00
Proddy
34c514709a Merge pull request #2442 from MichaelDvP/dev 2025-03-04 07:55:22 +01:00
MichaelDvP
7dfedfeb10 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-03-04 07:36:53 +01:00
MichaelDvP
c8bf4cae17 typo 2025-03-04 07:36:31 +01:00
Proddy
2818e268b6 Merge pull request #2441 from proddy/dev
standalone console working
2025-03-03 21:01:25 +01:00
proddy
7a95c11f62 package update 2025-03-03 20:55:23 +01:00
proddy
d712b1cce9 command NOT_FOUND when not found 2025-03-03 15:13:04 +01:00
proddy
03fa92352b 3.7.2-dev.24 2025-03-03 15:12:42 +01:00
proddy
e121fdb47f fix shell standalone 2025-03-03 15:12:28 +01:00
proddy
c05793f64f package update 2025-03-03 15:12:19 +01:00
proddy
3836610d81 typo 2025-03-03 15:12:07 +01:00
MichaelDvP
c3f87cd321 fix CR10 #2437 2025-03-03 10:11:18 +01:00
Proddy
4d5a27f45e Merge pull request #2439 from proddy/dev
ESPAsyncWebServer @ 3.7.2
2025-03-02 21:39:54 +01:00
proddy
c37c1aaad5 size of log level box 2025-03-02 21:38:24 +01:00
proddy
110c0df6fb change test log message 2025-03-02 21:38:12 +01:00
proddy
04ac3be242 adjust cache 2025-03-02 17:44:53 +01:00
proddy
44c4ee8bc0 show device id in hex 2025-03-02 17:33:31 +01:00
proddy
57c4d550a3 ESPAsyncWebServer @ 3.7.2 2025-03-02 17:33:16 +01:00
Proddy
4bcb95eece Merge pull request #2436 from proddy/dev
show localized elapsed time in version
2025-03-02 15:21:47 +01:00
proddy
0a92d455c8 show localized elapsed time 2025-03-02 15:13:56 +01:00
proddy
edb30931ae remove days_Ago 2025-03-02 15:13:16 +01:00
proddy
d03ab7a16f formatting 2025-03-02 15:13:06 +01:00
proddy
ea9b6b3e00 removed unused file 2025-03-02 13:27:14 +01:00
proddy
bae6b600bd formatting 2025-03-02 13:27:04 +01:00
proddy
7eac920985 move build python script to scripts folder 2025-03-02 13:26:55 +01:00
Proddy
00c2b5992c Merge pull request #2435 from proddy/dev
minor changes
2025-03-02 09:46:55 +01:00
proddy
43d2fa1f00 remove duplicate log message 2025-03-02 09:23:37 +01:00
proddy
92d40d9287 reset search when closing pane 2025-03-02 09:23:15 +01:00
proddy
7a47a2090f fix message in testing devices 2025-03-02 09:22:59 +01:00
proddy
0d98491a97 suppress debug comment 2025-03-02 09:22:33 +01:00
Proddy
16cf16616e Merge pull request #2434 from proddy/dev
update libs
2025-03-01 22:37:42 +01:00
proddy
d9f56ef3ae ESP32Async/AsyncTCP @ 3.3.6 2025-03-01 22:35:14 +01:00
proddy
c8934af9bb update example 2025-03-01 22:17:18 +01:00
Proddy
cbacaa98d9 Merge pull request #2432 from proddy/dev
EMS-ESP-Modules.git @ 1.0.5
2025-03-01 10:54:30 +01:00
proddy
f1b6a0baf3 EMS-ESP-Modules.git @ 1.0.5 2025-03-01 10:54:05 +01:00
Proddy
4d15f48e2b Merge pull request #2431 from proddy/dev
prep for 3.7.2 stable
2025-03-01 10:45:28 +01:00
proddy
2ffd00e28a update dhw.mode with own_prog 2025-03-01 10:44:51 +01:00
proddy
8ef5be9a7f ArduinoJson @ 7.3.1 2025-03-01 10:44:13 +01:00
proddy
8769faeb83 package update 2025-03-01 10:44:03 +01:00
Proddy
cefbf2d4d6 Merge pull request #2430 from proddy/dev
#2427 links open in new window
2025-02-26 21:00:39 +01:00
proddy
bfd5082054 #2427 2025-02-26 20:58:21 +01:00
proddy
3d3a634d94 package update 2025-02-26 20:58:14 +01:00
Proddy
1cb078cd3c Merge pull request #2429 from misa1515/patch-22
Update locale_translations.h
2025-02-26 18:48:38 +01:00
Proddy
22683f5d12 Merge pull request #2428 from misa1515/patch-21
Update index.ts
2025-02-26 18:48:22 +01:00
misa1515
57b42aa7c2 Update locale_translations.h 2025-02-26 17:51:47 +01:00
misa1515
4a59743024 Update index.ts 2025-02-26 17:47:02 +01:00
Proddy
66cec18dee Merge pull request #2426 from proddy/dev
3.7.2-dev.23
2025-02-25 20:50:06 +01:00
proddy
ad71938fde Merge branch 'dev' of https://github.com/proddy/EMS-ESP32 into dev 2025-02-25 20:49:39 +01:00
proddy
d4155d6e9e 3.7.2-dev.23 2025-02-25 20:49:38 +01:00
Proddy
af6be4c6b1 Merge pull request #2425 from proddy/dev
new command 'set admin password'
2025-02-25 20:47:32 +01:00
proddy
cfbd0168c3 new command 'set admin password' 2025-02-25 20:46:43 +01:00
proddy
61b9bd7581 fix standalone board profile 2025-02-25 20:46:29 +01:00
proddy
4c7ad7124e package update 2025-02-25 20:46:18 +01:00
Proddy
0413314cfb Merge pull request #2424 from proddy/dev
fix weird bug where the total # entities would be incorrect
2025-02-24 22:19:46 +01:00
proddy
ab7cbe8ead show all entities, even if they are marked hidden 2025-02-24 22:18:41 +01:00
proddy
d1264828eb add comment 2025-02-24 22:18:24 +01:00
Proddy
76a317b5c0 Merge pull request #2423 from proddy/dev
add search to Devices webpage
2025-02-24 21:42:14 +01:00
proddy
ec11ae2ef7 add search 2025-02-24 21:38:14 +01:00
proddy
b857c6eb44 change color or num entities so its consistent 2025-02-24 21:37:56 +01:00
proddy
3f8add73ac adjust toast messages 2025-02-24 21:37:29 +01:00
proddy
08b0ddbb7f update packages 2025-02-24 21:37:13 +01:00
proddy
c44cb7e7fd add comments 2025-02-24 21:37:02 +01:00
Proddy
77ff61046e Merge pull request #2422 from MichaelDvP/dev
second fix #2410
2025-02-24 09:51:12 +01:00
MichaelDvP
a8eb06bef2 second fix #2410 2025-02-23 08:33:53 +01:00
Proddy
566b5c8ea5 Merge pull request #2420 from proddy/dev
collection of minor fixes
2025-02-22 13:40:40 +01:00
proddy
eeccd076a0 airbypass 2025-02-22 13:38:04 +01:00
proddy
f45ac9d0ef 3.7.2-dev.22 2025-02-22 13:37:55 +01:00
proddy
cdd9acddfa remove obsolete return_not_found() 2025-02-22 13:37:37 +01:00
proddy
e484f11d12 add test data and comments 2025-02-22 13:37:12 +01:00
proddy
19572f313a don't build web in standalone native 2025-02-22 13:36:45 +01:00
proddy
af9ad5d624 add test data for writing to analog sensor 2025-02-22 13:36:28 +01:00
proddy
8adca69140 update unit tests, add analogsensors 2025-02-22 13:36:12 +01:00
proddy
01710316ed add test for analogsensors 2025-02-22 13:36:00 +01:00
proddy
ab80c82a22 package update 2025-02-22 13:35:37 +01:00
proddy
dceafe65a7 formatting 2025-02-22 13:35:18 +01:00
proddy
4734a81fdb add airbypass 2025-02-22 13:35:08 +01:00
Proddy
a2c099e615 Merge pull request #2419 from MichaelDvP/dev
fix naming of bypass #2417
2025-02-22 11:26:16 +01:00
MichaelDvP
f9b88a1b6b fix naming of bypass #2417 2025-02-22 11:16:54 +01:00
Proddy
7f2b8cc971 Merge pull request #2416 from vmonkey/patch-5
Update CZ
2025-02-22 08:20:58 +01:00
Marek Tyburec
582fb3d72f Update CZ 2025-02-22 08:19:16 +01:00
Marek Tyburec
bf4fa74742 Update CZ 2025-02-22 08:17:07 +01:00
Proddy
c62b3b9864 Merge pull request #2415 from MichaelDvP/dev
fix dhw mode #2410
2025-02-21 21:50:16 +01:00
MichaelDvP
0ae9795d6b fix dhw mode #2410 2025-02-21 12:01:36 +01:00
Proddy
7488c31cd3 Merge pull request #2414 from proddy/dev
minor updates
2025-02-20 22:48:01 +01:00
proddy
dc0e634004 3.7.2-dev.21 2025-02-20 22:47:07 +01:00
proddy
57e7c0ae4f package update 2025-02-20 22:46:55 +01:00
proddy
7214acfa20 update ESPAsyncWebServer to 3.7.1 2025-02-20 22:46:48 +01:00
proddy
ff6d47bb9c spelling 2025-02-20 22:46:21 +01:00
proddy
81971ba53f fixes #2412 2025-02-20 22:46:10 +01:00
Proddy
a58f37e3eb Merge pull request #2407 from proddy/dev
fix showing version in dialog
2025-02-16 11:32:22 +01:00
proddy
09a746cf8e fix showing version in dialog 2025-02-16 11:31:49 +01:00
proddy
ea70119138 US spelling for favorite 2025-02-16 11:28:51 +01:00
Proddy
5a9c5b5e2d Merge pull request #2406 from MichaelDvP/dev
fix verify telegram-type
2025-02-16 11:24:09 +01:00
MichaelDvP
7fb09c5045 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-02-16 11:05:21 +01:00
MichaelDvP
705171f305 fix verify telegram-type 2025-02-16 11:04:19 +01:00
Proddy
400d1a5f1a Merge pull request #2405 from proddy/dev
re-generated files for 3.7.2-dev.20
2025-02-16 11:03:48 +01:00
proddy
c4855cc5f2 re-generated files for 3.7.2-dev.20 2025-02-16 11:02:41 +01:00
Proddy
1e4b487299 Merge pull request #2404 from MichaelDvP/dev
add vacation mode CR50 #2403
2025-02-16 10:48:13 +01:00
MichaelDvP
cbd883103e add vacation mode CR50 #2403 2025-02-16 09:05:44 +01:00
MichaelDvP
2ce12943cd update pkg 2025-02-16 08:42:23 +01:00
Proddy
4151a82b3b Merge pull request #2399 from proddy/dev
improvements to version checking
2025-02-09 20:18:00 +00:00
proddy
b871081ef1 show upgrades for both stable and dev releases 2025-02-09 20:13:52 +00:00
proddy
da51d1d7d9 comments on version tests 2025-02-09 20:13:10 +00:00
proddy
82dae30224 3.7.2-dev.19 2025-02-09 20:12:50 +00:00
proddy
1fdac2fdab package update 2025-02-09 20:12:36 +00:00
proddy
56b23e27d7 formating 2025-02-09 20:12:19 +00:00
Proddy
ba29aa62d3 Merge pull request #2398 from proddy/dev
updates
2025-02-08 22:34:35 +00:00
proddy
be2342285f update AsyncWS libs 2025-02-08 22:33:45 +00:00
proddy
5595c01221 update 2025-02-08 22:33:27 +00:00
proddy
133cddef5b exclude IDF 2025-02-08 22:33:20 +00:00
proddy
0fdba1f84d fix for OSX 2025-02-08 22:33:08 +00:00
proddy
e10ec26e79 update 2025-02-08 22:32:56 +00:00
proddy
ffbb397dba update version 2025-02-08 22:32:48 +00:00
Proddy
799076d0c4 Merge pull request #2396 from misa1515/patch-20
Update index.ts
2025-02-07 21:00:29 +01:00
misa1515
1fbd10df27 Update index.ts 2025-02-06 23:06:10 +01:00
Proddy
4a2f82f1e8 Merge pull request #2393 from mattreim/dev
Update German translation
2025-02-03 22:29:47 +01:00
mattreim
d913e4d90b Update German translation 2025-02-03 21:46:53 +01:00
Proddy
0958c29c9e Merge pull request #2392 from proddy/dev
translations in version webUI page
2025-02-03 20:47:21 +01:00
proddy
36e1c9f79d updates 2025-02-03 20:37:53 +01:00
proddy
8fedac53dd more translations 2025-02-03 20:35:17 +01:00
proddy
a1c6159fc5 package update 2025-02-03 20:35:09 +01:00
proddy
5b33acba5e auto-formatting 2025-02-03 20:34:56 +01:00
Proddy
4abaef2943 Merge pull request #2391 from MichaelDvP/dev
disable old led port when changing port, #2389
2025-02-03 12:20:04 +01:00
MichaelDvP
ad71773293 disable old led port when changing port, #2389 2025-02-03 09:18:41 +01:00
Proddy
5b07309939 Merge pull request #2390 from proddy/dev
fix system command read from crashing
2025-02-02 17:17:40 +01:00
proddy
7a044a1dcd don't use flag tautological-constant-out-of-range-compare 2025-02-02 17:17:03 +01:00
proddy
6507764157 use default icondegrees in HA 2025-02-02 17:16:47 +01:00
proddy
7dfa8fc883 command read with no args crashed EMS-ESP 2025-02-02 17:16:32 +01:00
proddy
6df7965bb2 bump version dev-18 2025-02-02 17:16:11 +01:00
Proddy
02a3dee764 Merge pull request #2388 from proddy/dev
minor changes
2025-02-02 13:34:25 +01:00
proddy
d5895f1710 add example lib_deps 2025-02-02 13:33:28 +01:00
proddy
2b90ad3f6d add example for allvalues 2025-02-02 13:29:35 +01:00
proddy
0bb61b4296 show error when action command fails 2025-02-02 13:29:18 +01:00
proddy
2378fb547c default values 2025-02-02 13:29:02 +01:00
proddy
a79ff3f417 stop flash when ems bus not yet connected 2025-02-02 13:28:55 +01:00
proddy
4bc93615c5 add space when showing error 2025-02-02 13:28:37 +01:00
proddy
685f0d93e5 add allvalues 2025-02-02 13:28:23 +01:00
proddy
1d7b6674bb remove allvalues 2025-02-02 13:28:15 +01:00
proddy
014405e451 package update 2025-02-02 13:28:02 +01:00
Proddy
aff3ca3ad3 Merge pull request #2382 from proddy/dev
remove flash from web dashboard, add tooltip component
2025-01-29 21:09:39 +01:00
Proddy
b723d09952 Merge branch 'emsesp:dev' into dev 2025-01-29 21:07:31 +01:00
Proddy
bfff842c82 Merge pull request #2381 from MichaelDvP/dev
ignore src==0 (#2378) and fix typo
2025-01-29 21:07:01 +01:00
proddy
ad7d21764d remove flash from dashboard 2025-01-29 21:04:01 +01:00
MichaelDvP
f2ae84b004 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-01-29 08:37:04 +01:00
MichaelDvP
a81956654e ignore src==0, fixes #2378 2025-01-29 08:36:03 +01:00
MichaelDvP
3cb662799f fix typo 2025-01-29 08:35:19 +01:00
Proddy
9188d03d61 Merge pull request #2380 from proddy/dev
tidy up dashboard text and alerts
2025-01-28 22:35:21 +01:00
proddy
3df2d36453 https://github.com/emsesp/EMS-ESP32/discussions/2377 2025-01-28 22:33:23 +01:00
Proddy
0ab7eb42e4 Merge pull request #2373 from proddy/dev
support entities api endpoint for multiple devices of same type
2025-01-26 14:56:31 +01:00
proddy
84d4fb37fa update 2025-01-26 14:54:38 +01:00
proddy
aa9b38da03 make makefile work for all platforms 2025-01-26 14:48:49 +01:00
proddy
8342867807 3.7.2-dev.16 2025-01-26 14:48:32 +01:00
proddy
d8cff865da tidy up flags 2025-01-26 14:45:40 +01:00
proddy
096f7e1c88 fix lint warnings 2025-01-26 14:45:33 +01:00
proddy
0608d847f5 update generated docs 2025-01-26 14:01:41 +01:00
proddy
b20360c2a5 update lock 2025-01-26 13:59:37 +01:00
proddy
59b5086cab no need for virtual functions 2025-01-26 13:57:06 +01:00
proddy
2e3024ab61 move all statics up 2025-01-26 13:56:50 +01:00
proddy
b5299719da replace emsesp_stub.h 2025-01-26 13:56:31 +01:00
proddy
2620f56e0d lint warnings 2025-01-26 13:30:53 +01:00
proddy
20b978c46c add lto flag 2025-01-26 13:30:29 +01:00
proddy
5c8a18df68 arduino 6.10.0 and lto flag 2025-01-26 13:30:20 +01:00
proddy
3464d6c324 add test for /api/thermostat/entities 2025-01-26 13:12:26 +01:00
proddy
eac0cc0521 prevent possible out of scope 2025-01-26 13:12:11 +01:00
proddy
0953d37303 support multi devices of same type 2025-01-25 13:31:05 +01:00
proddy
1d3fec2a95 changed text 2025-01-25 13:30:41 +01:00
proddy
61b374b7c0 changed comment 2025-01-25 13:30:30 +01:00
proddy
c47cc0d5f1 test multiple thermostats hc1 hc2 2025-01-25 13:30:14 +01:00
proddy
939882efbf auto-formatting 2025-01-25 13:30:03 +01:00
Proddy
f42cbf548e Merge pull request #2371 from proddy/dev
some minor changes
2025-01-25 08:43:28 +01:00
proddy
91075ace37 comment 2025-01-25 08:40:47 +01:00
proddy
de6405f8d1 neopixel to standalone to not break build 2025-01-25 08:35:35 +01:00
proddy
2ffcaf4a9e move async* libs 2025-01-25 08:35:17 +01:00
proddy
1bda62309b auto-formatting 2025-01-25 08:35:05 +01:00
proddy
83659e5da8 remove loading messages 2025-01-25 08:15:10 +01:00
proddy
a6e136561e show boot partitions 2025-01-25 08:15:02 +01:00
proddy
a75d7487fc Merge branch 'dev' of https://github.com/proddy/EMS-ESP32 into dev 2025-01-25 08:14:25 +01:00
proddy
31b0dd8d58 update packages 2025-01-25 08:12:55 +01:00
Proddy
696bd1f455 Merge branch 'emsesp:dev' into dev 2025-01-25 07:31:09 +01:00
Proddy
18355efde2 Merge pull request #2367 from misa1515/patch-18
Update locale_translations.h
2025-01-25 07:30:49 +01:00
Proddy
d5100134e4 Merge pull request #2368 from misa1515/patch-19
Update index.ts
2025-01-25 07:30:39 +01:00
Proddy
b932242e04 Merge pull request #2370 from MichaelDvP/dev
add RGB Led to board profile
2025-01-25 07:30:11 +01:00
MichaelDvP
73ccff3412 add RGB Led to board profile 2025-01-24 19:23:19 +01:00
MichaelDvP
e5f852a7ed fix C3 board settings 2025-01-24 19:22:49 +01:00
MichaelDvP
581f19462d don't show double log entries after startup 2025-01-24 19:22:20 +01:00
misa1515
eb59b37251 Update index.ts 2025-01-22 23:36:48 +01:00
misa1515
f3696f60cd Update locale_translations.h 2025-01-22 23:32:31 +01:00
proddy
6b4e21f5db remove duplicate wwCurFlow_ in HIU and HEATPUMP 2025-01-22 23:15:58 +01:00
proddy
3d4d5b7bbc show restarting before it actually restarts 2025-01-22 22:31:36 +01:00
proddy
e6f15681c0 use same ha_uom function to add uom, state and device class 2025-01-22 22:31:21 +01:00
proddy
5f52a646ff 3.7.2-dev.15 2025-01-22 22:30:38 +01:00
proddy
be4f9296a5 add board_build.app_partition_name = app0 2025-01-22 22:30:15 +01:00
proddy
c3181f589c minor change 2025-01-22 22:29:58 +01:00
proddy
872cd40f56 remove Loading... message 2025-01-22 22:29:40 +01:00
proddy
30b9de49bf revert back to default test 2025-01-22 22:29:27 +01:00
Proddy
8a91c6eb2f Merge pull request #2366 from proddy/dev
show progress bar when automatically installing firmware, fix modbus headers
2025-01-21 22:07:00 +01:00
proddy
243471e21d show progress bar when automatically installing firmware 2025-01-21 22:06:01 +01:00
proddy
b8f97ec94d 3.7.2-dev.14 2025-01-21 22:05:26 +01:00
proddy
8576a6f253 added for testing 2025-01-21 22:05:10 +01:00
proddy
b33e6ceca9 package update 2025-01-21 20:28:51 +01:00
proddy
8eaf7f32cd fix csv file generation for non modbus 2025-01-21 20:28:47 +01:00
Proddy
becdc8cef5 Merge pull request #2363 from proddy/dev
fix memory type for S3 so PSRAM is used, fix WebUI upload restarting
2025-01-20 21:05:14 +01:00
proddy
651688219c fix logic for uploading so it restarts 2025-01-20 21:03:52 +01:00
proddy
b9a4bb3511 3.7.2-dev.13 2025-01-20 21:03:29 +01:00
proddy
b318274129 fix memory type for S3 so PSRAM is used 2025-01-20 21:03:20 +01:00
Proddy
8b0e5ba8e7 Merge pull request #2362 from proddy/dev
introduce system status in WebUI for easier monitoring of tasks
2025-01-20 17:42:07 +01:00
proddy
4a9b74b311 include tag in entity_dump unless we're generating it for modbus 2025-01-20 12:57:00 +01:00
proddy
371b198eb6 update generated files 2025-01-20 12:56:23 +01:00
proddy
a6dfdb2c4c package update 2025-01-20 12:56:15 +01:00
proddy
3122c2b2a9 print tag in dump_entities.csv 2025-01-20 12:14:46 +01:00
proddy
9ac8d149fb use system status with standalone 2025-01-20 12:14:30 +01:00
proddy
91e1b0b3b8 added comment 2025-01-20 12:14:12 +01:00
proddy
01636ced88 update dictionary 2025-01-20 12:14:01 +01:00
proddy
53e587537f remove unused system status's 2025-01-20 12:13:51 +01:00
proddy
77eeacf121 remove duplicate 157 thermostat in standalone 2025-01-20 12:13:34 +01:00
proddy
a89c42d659 package update 2025-01-20 12:13:10 +01:00
proddy
ba4bc423f4 rename Restart Monitor 2025-01-20 12:13:00 +01:00
proddy
8cd341576d use await 2025-01-20 12:12:47 +01:00
proddy
006eae5862 introduce system status in WebUI for easier monitoring of tasks 2025-01-19 18:18:04 +01:00
Proddy
6e29de4463 Merge pull request #2361 from proddy/dev
include CPU temp in heartbeat MWTT topic for ESP32
2025-01-19 10:02:38 +01:00
proddy
92d816b990 include CPU temp in heartbeat MWTT topic for ESP32 2025-01-19 10:00:03 +01:00
proddy
37ad1968b5 formating 2025-01-19 09:59:39 +01:00
Proddy
01793dd4f6 Merge pull request #2360 from proddy/dev
implement CPU temp for ESP32
2025-01-18 16:13:29 +01:00
proddy
9a7f7fa1d5 updated 2025-01-18 16:12:59 +01:00
proddy
648675d002 auto-formatting 2025-01-18 16:10:44 +01:00
proddy
462d865fc9 implement CPU temp for ESP32 2025-01-18 16:08:26 +01:00
proddy
9f24851948 add comments 2025-01-18 16:08:04 +01:00
proddy
a5e5ec5098 transformNumFloat with default values 2025-01-18 16:07:57 +01:00
proddy
db90546bc3 transformNumFloat with default values 2025-01-18 16:07:41 +01:00
proddy
2d9ea3ee8d show CPU temp in C or F 2025-01-18 16:07:18 +01:00
proddy
4d3cafcf29 fix DASHBOARD_1 in DE 2025-01-18 16:07:05 +01:00
proddy
8685ffb1bf update Tasmota platform (for testing 3.x) 2025-01-18 16:06:54 +01:00
proddy
86408b3452 package update 2025-01-18 16:06:31 +01:00
Proddy
eab94f3b84 Merge pull request #2352 from proddy/dev
small collection of changes
2025-01-16 22:29:53 +01:00
proddy
9123dbcc9e 3.7.2-dev.11 2025-01-16 21:58:13 +01:00
proddy
ec6f426b06 remove comments 2025-01-16 21:57:53 +01:00
proddy
5482937332 detect browser language if non set 2025-01-16 21:55:51 +01:00
proddy
0b667703c2 update 2025-01-16 21:55:36 +01:00
proddy
c732c96fc2 re-gen files 2025-01-16 21:55:19 +01:00
proddy
e3d260429c formatting 2025-01-16 21:54:54 +01:00
proddy
77eb2c747b tidy up lang header 2025-01-16 21:54:38 +01:00
proddy
6853cd738f package update 2025-01-16 21:54:17 +01:00
proddy
d58776beab fix DASHBOARD_1 2025-01-16 21:53:57 +01:00
Proddy
94a7b1e438 Merge branch 'emsesp:dev' into dev 2025-01-16 16:32:09 +01:00
Proddy
c3f7540f74 Merge pull request #2356 from MichaelDvP/dev
prepare for modbus support AM200, #2354
2025-01-16 16:30:35 +01:00
MichaelDvP
4642a50f69 prepare for modbus support AM200 2025-01-16 09:48:11 +01:00
proddy
b23bcf3f0b message optional in MessageBox 2025-01-14 22:09:23 +01:00
proddy
570678e3d3 show message in Dashboard if no fav entities set 2025-01-14 21:44:56 +01:00
proddy
64a2f5eb11 gracefully close mqtt on restart 2025-01-14 19:03:30 +01:00
proddy
24fba8b382 add test for #2351 2025-01-14 19:03:12 +01:00
proddy
9339ef481a package update 2025-01-14 19:01:11 +01:00
proddy
075789b902 fix showing Active in NTP 2025-01-12 15:19:12 +01:00
Proddy
1dd1b47faf Merge pull request #2343 from proddy/dev
minor updates
2025-01-12 14:16:46 +01:00
proddy
525a164c69 include temp as HA sensor - #2346 2025-01-12 12:09:36 +01:00
proddy
b60f333edb use translation for is_required 2025-01-12 11:58:03 +01:00
proddy
2323fdfe56 update packages 2025-01-12 11:57:53 +01:00
proddy
9b7fed4d1f tidy up imports 2025-01-12 11:50:05 +01:00
proddy
67c59c9b4b modify settings based on board type 2025-01-12 11:49:52 +01:00
proddy
b5fea921e6 grey out modbus with explanation if no psram 2025-01-12 11:49:27 +01:00
proddy
eeb071afc6 3.7.2-dev.10 2025-01-12 08:57:53 +01:00
proddy
5669873101 don't echo wifi password after setting it 2025-01-11 21:11:03 +01:00
proddy
d371c9bc82 auto-formatting 2025-01-11 21:06:47 +01:00
proddy
153dd19fc6 don't auto-install if on Tasmota 2025-01-11 19:02:15 +01:00
proddy
ae258a75d9 simulate ESP32 and ESP32-S3 2025-01-11 19:01:53 +01:00
proddy
37c4be321f output also the flash size 2025-01-11 19:01:03 +01:00
proddy
c810d58064 changed comments, make sure S32 V2 is compiled with Tasmota 2025-01-11 19:00:47 +01:00
proddy
5a27817d11 updated example 2025-01-11 19:00:14 +01:00
proddy
4be2f9283d updated dictionary 2025-01-11 19:00:05 +01:00
proddy
a65162fbbc updated generated file 2025-01-11 18:59:49 +01:00
proddy
494cf3b6a8 package update 2025-01-11 18:59:39 +01:00
proddy
b900194402 package update 2025-01-11 18:59:30 +01:00
proddy
d6e72e72d7 auto-formatting 2025-01-11 18:59:10 +01:00
proddy
960baadeca changed text 2025-01-11 18:58:59 +01:00
proddy
ed92b37869 updated 2025-01-11 18:58:51 +01:00
proddy
1598809815 package update 2025-01-11 12:55:23 +01:00
Proddy
3131969fc1 Merge branch 'emsesp:dev' into dev 2025-01-10 18:11:40 +01:00
Proddy
fb44bc33b9 Merge pull request #2341 from MichaelDvP/dev
fix mqtt commands with base path #2339
2025-01-10 17:10:57 +01:00
MichaelDvP
59a806ac8c fix mqtt commands with base path #2339 2025-01-10 15:14:48 +01:00
proddy
6a2a27e47e mathieucarbou/ESPAsyncWebServer @ 3.6.0 2025-01-09 16:33:07 +01:00
Proddy
251d0af028 Merge branch 'emsesp:dev' into dev 2025-01-09 14:21:45 +01:00
Proddy
8fa800e2f7 Merge pull request #2338 from MichaelDvP/dev
small fixes and additions
2025-01-09 14:21:24 +01:00
MichaelDvP
df9d20ad88 disable WS queue, web log messages are already queued 2025-01-09 12:39:29 +01:00
MichaelDvP
c07754047d add solar influence #2212 2025-01-09 09:18:50 +01:00
MichaelDvP
9c00af317e Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-01-09 08:55:12 +01:00
MichaelDvP
d3d132ec45 unused id 2025-01-09 08:55:01 +01:00
MichaelDvP
7adba972e7 Don't show uom for empty string 2025-01-09 08:54:36 +01:00
proddy
d83399bd1f fix Make for OSX 2025-01-08 21:46:05 +01:00
proddy
4471da4aa9 update packages 2025-01-08 21:45:59 +01:00
Proddy
b3be1d9351 Merge pull request #2337 from proddy/dev
replace arduino platform 3.1.0 with previous 2.0.18
2025-01-08 20:20:01 +01:00
proddy
c6b8c2a630 3.7.2-dev.9 2025-01-08 20:17:28 +01:00
proddy
3f51c21dc7 tests for 4MB firmware upload 2025-01-08 20:17:20 +01:00
proddy
a8cdbc4fd6 tidy up directory listing 2025-01-08 20:16:59 +01:00
proddy
95e5babb13 package update 2025-01-08 20:16:48 +01:00
proddy
74cb23a8bb replace arduino platform 3.1.0 with previous 2.0.18 to see if it fixed #2333 2025-01-08 20:16:40 +01:00
Proddy
6be304f295 Merge pull request #2332 from proddy/dev
formatting upgrade button
2025-01-05 22:46:19 +01:00
proddy
e702b0b733 formatting upgrade button 2025-01-05 22:45:48 +01:00
Proddy
bfbd263c74 Merge pull request #2331 from proddy/dev
web UI small changes
2025-01-05 18:28:39 +01:00
proddy
472f922369 tidy up formatting, add a re-install option 2025-01-05 18:26:18 +01:00
proddy
b13c608ff3 formatting imports 2025-01-05 13:34:02 +01:00
proddy
5464909121 change icon size and use customizations icon 2025-01-05 13:32:54 +01:00
Proddy
d874b3f808 Merge pull request #2328 from proddy/dev
core update #2108
2025-01-04 15:07:01 +01:00
proddy
92108bc743 update comments 2025-01-04 14:59:41 +01:00
proddy
66ca1e52bb add local yarn files 2025-01-04 14:59:37 +01:00
proddy
3589094d06 update lock file 2025-01-04 14:59:13 +01:00
proddy
801ed6ef79 update dictionary 2025-01-04 14:59:03 +01:00
proddy
2547ae45a8 comment 2025-01-04 14:50:29 +01:00
proddy
93e4abe72d update packages 2025-01-04 14:13:51 +01:00
proddy
eb87651c47 merge #2108 2025-01-04 13:41:39 +01:00
Proddy
4138598db2 Merge pull request #2320 from misa1515/patch-16
Update locale_translations.h
2025-01-04 13:30:40 +01:00
Proddy
913bbd6e3b Merge pull request #2322 from misa1515/patch-17
Update index.ts
2025-01-01 21:46:39 +01:00
misa1515
d35881b05b Update index.ts 2025-01-01 21:35:02 +01:00
misa1515
33b54ccf12 Update locale_translations.h 2025-01-01 17:47:43 +01:00
Proddy
a8775b2200 Merge pull request #2317 from proddy/dev
cleanup yarn
2024-12-31 13:07:07 +01:00
proddy
6d3746222d updated 2024-12-31 13:06:16 +01:00
proddy
fe169ac80f formatting 2024-12-31 13:06:11 +01:00
proddy
83724e3d44 formatting 2024-12-31 13:05:59 +01:00
proddy
a4db3ef5c4 regenerate files 2024-12-31 13:05:49 +01:00
proddy
f8adad7865 cleanup yarn 2024-12-31 13:05:33 +01:00
proddy
12c094228e add comment 2024-12-31 13:05:07 +01:00
Proddy
902ea80807 Merge pull request #2311 from Sbried/dev
Updated unknown compressor stati "enum_hpactivity"
2024-12-31 12:44:57 +01:00
Proddy
73831d9ac6 Merge pull request #2316 from proddy/dev
fix underlines in Tab headers (webUI) and NL translations
2024-12-31 12:44:31 +01:00
proddy
6bfda79441 NL translations 2024-12-31 12:28:06 +01:00
proddy
112de78fc5 update packages 2024-12-31 12:16:27 +01:00
proddy
adbd2381e1 ignore dependencies 2024-12-31 12:16:16 +01:00
proddy
397f3f546e fix webUI tabs (underline) 2024-12-31 12:15:59 +01:00
Proddy
43d3c28e16 Merge pull request #2307 from ovenystas/fix-sv-translation-bug
fix: Sv translation bugs
2024-12-30 21:28:23 +01:00
Proddy
747a64b869 Merge pull request #2315 from MichaelDvP/dev
fix thermostat clock year, #2313
2024-12-30 21:27:04 +01:00
MichaelDvP
7c2e5560bd fix thermostat clock year, #2313 2024-12-30 19:28:46 +01:00
Sbried
9194db9f70 Updated unknown compressor stati "enum_hpactivity" 0, 5 and added status 7.
No idea what is the difference bewteen 4 (pool) and 5 (pool_heating).
2024-12-29 12:57:26 +01:00
Ove Nystås
fece00c0c6 fix: Sv translation bugs 2024-12-26 19:50:16 +01:00
Proddy
ba3ae5ea56 Merge pull request #2305 from MichaelDvP/dev
fixes #2288, #2299, #2295 (new  FLAG)
2024-12-23 15:29:04 +01:00
MichaelDvP
4c69c9e445 fix show ntp_time (as local time) 2024-12-23 13:03:59 +01:00
MichaelDvP
97925c47fd remove broken ntp_time 2024-12-23 12:12:25 +01:00
MichaelDvP
ad89fe15b1 fix seltep command for CR11 #2295 2024-12-23 09:09:36 +01:00
MichaelDvP
29035cabfe Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-12-22 15:59:18 +01:00
MichaelDvP
9b3d43d27f add min/max for #2288, own flag for CR11 #2295 2024-12-22 15:58:46 +01:00
Proddy
0b4f17473a Merge pull request #2303 from proddy/dev
show ntp time in status, use useInterval everywhere instead of alova'…
2024-12-21 16:31:23 +01:00
proddy
b0c29b57c7 show ntp time in status, use useInterval everywhere instead of alova's AutoRequest 2024-12-21 16:30:05 +01:00
Proddy
6d22f6aebf Merge pull request #2302 from proddy/dev
minor refresh
2024-12-20 17:49:39 +01:00
proddy
3e3e10e6a0 formatting 2024-12-20 17:48:14 +01:00
proddy
b854c777c8 update dictionary 2024-12-20 17:48:04 +01:00
proddy
b71fdd77e8 modbus update with c11 2024-12-20 17:47:56 +01:00
proddy
0f6f7cea19 vite update 2024-12-20 17:47:41 +01:00
Proddy
58beb092c2 Merge pull request #2301 from oliof/patch-1
Update CHANGELOG_LATEST.md
2024-12-20 12:15:41 +01:00
Harald Wagener
c3f200f73b Update CHANGELOG_LATEST.md
fix link to issue #2182
2024-12-20 10:41:37 +01:00
Proddy
98640c11b1 Merge pull request #2298 from MichaelDvP/dev
update for #2294 and #2295
2024-12-19 20:29:49 +01:00
MichaelDvP
d7904bdcaf set mode to manual for CR11, dont show remotetemp for non-master thermostats 2024-12-19 16:52:57 +01:00
MichaelDvP
ce05a94d58 update changelog, dev.6 2024-12-19 12:42:09 +01:00
MichaelDvP
c0ed62dc7a modbus: don't show not found errors in first minute 2024-12-19 12:24:46 +01:00
MichaelDvP
1557fa98b1 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-12-19 09:39:46 +01:00
MichaelDvP
81a530f153 add CR11 thermostat, #2295 2024-12-19 09:38:18 +01:00
Proddy
a4733c3e6a Merge pull request #2296 from proddy/dev
added EMS Device Ventilation module as test data
2024-12-18 21:29:29 +01:00
proddy
7851b8e94c type check 2024-12-18 21:25:22 +01:00
proddy
36838f7690 add example Ventilator to demo 2024-12-18 21:10:35 +01:00
proddy
fdd87d0757 update toastify 2024-12-18 21:10:19 +01:00
MichaelDvP
c8822aff64 fix modbus write for signed values 2024-12-18 13:44:24 +01:00
MichaelDvP
4b3205fc9c modbus publish emsesp-INT8 as modbus-int16, fix #2294 2024-12-18 12:55:53 +01:00
MichaelDvP
afc05ae9e8 update pkg, change for toastify 11 2024-12-18 12:53:55 +01:00
proddy
9c3044efa0 re-generated files 2024-12-16 21:49:37 +01:00
proddy
8caeb129c1 update 2024-12-16 21:49:28 +01:00
proddy
0427504f0e typo 2024-12-16 21:44:34 +01:00
proddy
4f11a7caa1 update dictionary 2024-12-16 21:44:27 +01:00
proddy
150695c185 formatting 2024-12-16 21:44:14 +01:00
proddy
3558591480 remove unused function 2024-12-16 21:43:56 +01:00
proddy
f7a24052c2 make makefile work for OSX 2024-12-16 21:38:06 +01:00
proddy
75c452486c update packages, add workaround for itty-router bug 2024-12-16 21:37:58 +01:00
Proddy
40cab6775c Merge pull request #2292 from ovenystas/add-sv-translations
Add, update and fix misspellings in Swedish translation
2024-12-15 11:20:02 +01:00
Ove Nystås
392829c7db Add, update and fix misspellings in Swedish translation 2024-12-15 00:41:36 +01:00
Proddy
4621c9d616 Merge pull request #2291 from MichaelDvP/dev
thermostat settings for #2290, #2288,#1957 (#2287)
2024-12-13 22:50:46 +01:00
MichaelDvP
006d664ec9 CW100 settings telegram 0x241, #2290 2024-12-13 15:58:06 +01:00
MichaelDvP
0cc9ac4dd8 add reduce threshold #2288, absent mode #1957 (#2287) 2024-12-13 10:14:44 +01:00
MichaelDvP
502096dc22 update pkg 2024-12-13 10:08:42 +01:00
Proddy
8c424c7a64 Merge pull request #2283 from misa1515/patch-15
Update locale_translations.h
2024-12-12 22:35:27 +01:00
misa1515
d7c118b88a Update locale_translations.h 2024-12-09 18:57:16 +01:00
misa1515
1fdb0b7516 Update locale_translations.h 2024-12-07 16:51:42 +01:00
Proddy
c2fc771756 Merge pull request #2280 from MichaelDvP/dev
small fixes and changes
2024-12-06 08:37:49 +01:00
MichaelDvP
6f759c5bc4 update changelog 2024-12-06 08:37:12 +01:00
MichaelDvP
facbbf1353 fix info command #2274, fix standanlone 2024-12-06 08:33:02 +01:00
MichaelDvP
a218c7a781 Add "duplicate" option to Custom Entities #2266 2024-12-05 19:27:04 +01:00
MichaelDvP
5f42709eab update asyncTCP to threadsafe 3.2.14, ems-esp v3.7.2-dev.4 2024-12-05 12:57:19 +01:00
MichaelDvP
5ec0f657a0 newer CT200 temperatures, #2277 2024-12-05 10:09:26 +01:00
MichaelDvP
812911ffbb version 2.7.2-dev.3 2024-12-04 18:28:40 +01:00
MichaelDvP
55235687ba change modbus timeout to seconds and default 300 sec, #2254 2024-12-04 18:28:13 +01:00
MichaelDvP
a970009d20 update eModbus to 1.7.2, #2254 2024-12-04 18:26:45 +01:00
MichaelDvP
4afc16e2cb modbus command path to api #2276 2024-12-04 18:25:31 +01:00
MichaelDvP
3772d72b43 pkg update 2024-12-03 18:17:42 +01:00
MichaelDvP
607f949638 fix render long numbers, #2267 2024-12-03 12:39:30 +01:00
Proddy
473cf7c8af Merge pull request #2275 from proddy/dev
minor updates
2024-12-02 22:12:29 +01:00
Proddy
e0909df06c Merge branch 'emsesp:dev' into dev 2024-12-02 22:11:40 +01:00
proddy
5fc606ef6d remove duplicate code segment, remove weblog # 2024-12-02 22:10:28 +01:00
proddy
a3032f4da7 update packages 2024-12-02 22:10:11 +01:00
proddy
7fdd65e8ca update dictionary 2024-12-02 22:10:05 +01:00
Proddy
dc6bf883f1 Merge pull request #2270 from mkurek/patch-1
Fix typo in polish ventilation translation
2024-12-02 21:45:16 +01:00
Proddy
ce5edd93b4 Merge pull request #2272 from MichaelDvP/dev
heatingtypes #2268, pretty telegram, service commands #2182
2024-12-02 21:44:23 +01:00
Mateusz Kurek
e36e6bec9c Fix typo in polish ventilation translation
prędjkość -> prędkość
2024-12-01 23:41:41 +01:00
MichaelDvP
c8fd08b6d2 changelog v3.7.2-dev.2 2024-12-01 18:06:35 +01:00
MichaelDvP
c0d693c1c8 add RC35 heatingtypes for remote room control, #2268 2024-12-01 18:06:09 +01:00
MichaelDvP
5d2a6e2898 pretty telegram with operation between src and dst 2024-12-01 17:56:23 +01:00
MichaelDvP
4547a5ceb0 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-12-01 17:11:47 +01:00
Proddy
76151c4395 Merge pull request #2265 from proddy/dev
fixes #2264 - tab links broken
2024-11-30 21:29:03 +01:00
proddy
481089b1b4 3.7.2-dev.1 2024-11-30 21:27:59 +01:00
proddy
463787b7f4 fixes #2264 2024-11-30 21:27:34 +01:00
proddy
e2258a1c43 package update 2024-11-30 21:27:22 +01:00
MichaelDvP
5528f29b6a Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-11-29 11:00:24 +01:00
MichaelDvP
e3861d54c9 remove command txMode, fix writeable camelCase names 2024-11-29 11:00:04 +01:00
Proddy
3368f2803c Merge pull request #2260 from proddy/dev
3.7.2-dev
2024-11-29 10:33:36 +01:00
proddy
6ca1d68d23 3.7.2-dev 2024-11-29 10:33:12 +01:00
Proddy
f3873e330d Merge pull request #2259 from proddy/dev
Preparing 3.7.1 release
2024-11-29 10:18:41 +01:00
proddy
be0aba1b59 cleaned lock file 2024-11-29 10:17:54 +01:00
proddy
321187d0d2 update unity test responses 2024-11-29 10:17:47 +01:00
proddy
1e5bc9dcc5 update versions to 3.7.1 stable 2024-11-29 10:17:36 +01:00
proddy
f769bbbe42 additonal step to build web 2024-11-29 10:17:22 +01:00
MichaelDvP
cf93081252 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-11-28 15:44:39 +01:00
MichaelDvP
30fca2a190 system commands withing command (api/mqtt/console), alternative to #2182 2024-11-28 15:40:42 +01:00
Proddy
b7654c7e33 Merge pull request #2258 from proddy/dev
minor changes
2024-11-28 15:01:36 +01:00
proddy
a3964102c9 add comment 2024-11-28 15:00:05 +01:00
proddy
727d9bdf2e add comment 2024-11-28 14:08:09 +01:00
proddy
4471c1fad6 minor tidy up 2024-11-28 12:19:09 +01:00
proddy
4de56af85a text changes for upload files 2024-11-28 11:22:30 +01:00
proddy
b11f9be5e7 script to update web as I'm lazy 2024-11-28 11:22:21 +01:00
proddy
272bb84a16 move back as link was broken in readme.md 2024-11-28 11:22:11 +01:00
Proddy
c0bffe4ccf Merge pull request #2256 from proddy/dev
bump version to test version checker
2024-11-28 10:49:14 +01:00
Proddy
92c32b1abb Merge branch 'emsesp:dev' into dev 2024-11-28 10:48:51 +01:00
proddy
35cf87d155 3.7.1-dev.13 2024-11-28 10:48:31 +01:00
proddy
4c7b8a1db1 update packages 2024-11-28 10:48:23 +01:00
Proddy
29990001b2 Merge pull request #2255 from proddy/dev
refactor version webUI screen, update readme
2024-11-27 11:08:01 +01:00
proddy
add9d12aca update image 2024-11-27 10:55:39 +01:00
proddy
a5b1742bca updated readme 2024-11-27 10:44:12 +01:00
proddy
676b164ce8 change log text to be in line with the other services 2024-11-27 10:44:05 +01:00
proddy
bb9315777a update packages 2024-11-27 10:43:48 +01:00
proddy
f11b9ee420 refactor version check 2024-11-26 13:32:30 +01:00
proddy
3ba0bb80e7 update example 2024-11-26 13:32:17 +01:00
Proddy
0850737208 Merge pull request #2251 from proddy/dev
show download button instead of dialog
2024-11-25 16:53:28 +01:00
proddy
c851b14d35 show download button instead of dialog 2024-11-25 16:52:49 +01:00
Proddy
e62bb101e2 Merge pull request #2250 from proddy/dev
updated modbus
2024-11-25 14:33:54 +01:00
proddy
4a0680ee4d updated modbus 2024-11-25 14:33:28 +01:00
Proddy
89ccaf1e26 Merge pull request #2249 from MichaelDvP/dev
Fix custom entity factor validator and add entities for #1996
2024-11-25 14:29:05 +01:00
MichaelDvP
eeef5a862a fix customentity factor validator 2024-11-25 13:54:35 +01:00
MichaelDvP
558f43813b Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-11-25 11:49:31 +01:00
Proddy
c59657ac3b Merge pull request #2248 from proddy/dev
fix Last Will (LWT) not set on MQTT Connect #2247
2024-11-25 11:49:08 +01:00
MichaelDvP
381e8de617 add entities for #1996 2024-11-25 11:49:08 +01:00
proddy
1ebbdbe557 use bar as breadcrumb divider 2024-11-25 11:48:22 +01:00
proddy
2751aca37a remove setWill() to inline 2024-11-25 09:31:21 +01:00
proddy
acebc03d69 fix Last Will (LWT) not set on MQTT Connect #2247 2024-11-25 00:56:15 +01:00
Proddy
a7a3207cca Merge pull request #2244 from proddy/dev
react-router upgrade and more tidy up
2024-11-24 13:09:33 +01:00
proddy
f5acf6c0a4 3.7.1-dev.11 2024-11-24 13:08:40 +01:00
proddy
d47b3b9276 add breadcrumb to navigation 2024-11-24 13:05:38 +01:00
proddy
5c60ea9c15 updated generated files 2024-11-24 12:14:16 +01:00
Proddy
aec887373e Merge branch 'emsesp:dev' into dev 2024-11-24 11:19:27 +01:00
Proddy
4e5ad82cff Merge pull request #2246 from MichaelDvP/dev
fix modbus #2245 and reorder #2220
2024-11-24 11:18:22 +01:00
MichaelDvP
7971d3bb93 fix modbus entity generation of SM100 water (map to dhw1) #2245 2024-11-24 10:13:17 +01:00
MichaelDvP
549f7e30db don't wait for TX-read when getting new poll 2024-11-23 18:48:28 +01:00
MichaelDvP
a5879d1995 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-11-23 18:38:19 +01:00
MichaelDvP
9e5d78a29c swap values #2220 2024-11-23 18:36:58 +01:00
proddy
0191a95416 dictionary update 2024-11-23 10:49:53 +01:00
proddy
2276490c67 formatting 2024-11-23 10:49:45 +01:00
proddy
d60e42a483 remove test 2024-11-23 10:49:31 +01:00
proddy
7b5b5bb5ee package updates 2024-11-23 10:49:24 +01:00
proddy
aef4c2245d remove bogus file 2024-11-23 10:49:11 +01:00
proddy
62f460163f react-router updates 2024-11-23 10:49:02 +01:00
proddy
7ddc2ccdad Merge branch 'dev' of https://github.com/proddy/EMS-ESP32 into dev 2024-11-22 16:29:33 +01:00
proddy
2437976aed reate-router 7.0.1 2024-11-22 16:29:31 +01:00
Proddy
b1b8a128d5 Merge pull request #2241 from proddy/dev
update dump telegrams CSV for Mixer
2024-11-22 12:28:00 +01:00
proddy
b9a0744433 Merge branch 'dev' of https://github.com/proddy/EMS-ESP32 into dev 2024-11-22 12:23:48 +01:00
proddy
7049aa8892 update dump telegrams CSV for Mixer 2024-11-22 12:22:14 +01:00
Proddy
dbd6d38176 Merge pull request #2239 from proddy/dev
version updates in files to 3.7.1
2024-11-22 11:45:34 +01:00
proddy
52b9e4650e 3.7.1-dev.10 2024-11-22 11:44:45 +01:00
proddy
4a3cb8c525 update to version 3.7.1 2024-11-22 11:44:02 +01:00
Proddy
3680fad909 Merge pull request #2238 from proddy/dev
comment cleanup
2024-11-22 11:08:37 +01:00
proddy
c80ec368a9 remove mentions of discontinued scripts 2024-11-22 11:03:17 +01:00
proddy
9fbb28ee33 lint warning fix 2024-11-22 11:02:52 +01:00
proddy
92ff32f8ba formatting 2024-11-22 11:02:17 +01:00
proddy
e974967903 update yarn & preact 2024-11-22 11:02:06 +01:00
Proddy
3752247d1c Merge pull request #2237 from proddy/dev
various minor fixes
2024-11-21 15:02:27 +01:00
proddy
82e470a425 remove underline in download link 2024-11-21 15:00:59 +01:00
proddy
a67de57249 comments 2024-11-21 14:57:52 +01:00
proddy
9157da3e0b add back fake Mixer for device entities xls 2024-11-21 14:57:46 +01:00
proddy
fe5cab66fb formatting 2024-11-21 14:57:27 +01:00
proddy
3402b6d2dd auto generated 2024-11-21 14:56:57 +01:00
Proddy
1255381420 Merge pull request #2235 from MichaelDvP/dev
modbus fixes
2024-11-21 09:45:06 +01:00
Proddy
a8f17ec1b3 Merge pull request #2236 from proddy/dev
update CSV files for docs.emsesp.org
2024-11-21 09:32:02 +01:00
proddy
05904d9de9 update csv 2024-11-21 09:29:19 +01:00
proddy
89ade2e107 update packages 2024-11-21 09:29:12 +01:00
MichaelDvP
ca5d631dfc csv and modbus water devices #2229 2024-11-21 08:56:01 +01:00
MichaelDvP
de7bd38850 dont show wifi reconnects on ethermnet #2230 2024-11-20 15:29:30 +01:00
MichaelDvP
aea9a4429d fix modbus multiple devices (mixer) #2229 2024-11-20 15:25:57 +01:00
Proddy
9f3d3c7a44 Merge pull request #2231 from misa1515/patch-14 2024-11-20 11:34:24 +01:00
misa1515
d7b59c2613 Update locale_translations.h 2024-11-20 10:28:38 +01:00
Proddy
269c68b945 Merge pull request #2227 from proddy/dev
text updates
2024-11-19 20:41:31 +01:00
proddy
fc32eb7f12 add missing DE translation 2024-11-19 20:40:37 +01:00
proddy
56efb15938 update packages 2024-11-19 20:40:25 +01:00
proddy
53c1f4ebb6 update spellings 2024-11-19 20:40:12 +01:00
Proddy
0b1f87b6ce Merge pull request #2224 from proddy/dev
fix standalone
2024-11-19 09:28:52 +01:00
proddy
6371a0d298 fix standalone, needs DE translation 2024-11-19 09:27:22 +01:00
proddy
757044dde9 update generated modbus 2024-11-19 09:26:53 +01:00
proddy
0abdd9e2c2 update modbus + csv 2024-11-19 09:26:41 +01:00
Proddy
b7548476ed Merge pull request #2222 from MichaelDvP/dev
fix #2216, add #2212, #2217
2024-11-19 09:08:41 +01:00
MichaelDvP
0fee98c4c2 remove ntp status from HA #2218 2024-11-19 08:58:36 +01:00
MichaelDvP
e3354b2a49 add start counters #2220 2024-11-19 08:20:01 +01:00
MichaelDvP
d06ea9590e show mqtt reconnects the same way as network reconnects (count disconnects) 2024-11-19 08:19:19 +01:00
MichaelDvP
e52f988261 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-11-19 07:31:51 +01:00
Proddy
a6b89cee58 Merge pull request #2221 from proddy/dev
memory tests
2024-11-18 19:35:41 +01:00
proddy
f840543f0f updated memory tests 2024-11-18 19:33:06 +01:00
proddy
c696974644 update packages 2024-11-18 19:31:37 +01:00
MichaelDvP
3ebb0225c8 fix memory leak #2216, dev.9 2024-11-18 18:38:46 +01:00
MichaelDvP
2508a30b79 add solar #2212, rename dhw/startshp #2217 2024-11-18 16:54:21 +01:00
proddy
056febda6c update memory tests 2024-11-18 13:28:52 +01:00
proddy
28c523af24 update 2024-11-18 13:28:45 +01:00
Proddy
09b8dcdb10 Merge pull request #2211 from proddy/dev
use new URLs for emsesp.org
2024-11-16 15:23:08 +01:00
proddy
3daf1145e0 use new URLs for emsesp.org 2024-11-16 15:22:28 +01:00
Proddy
da77d52585 Merge pull request #2208 from proddy/dev
Wifi Reconnect #2207
2024-11-16 14:57:10 +01:00
proddy
c628b4b5ac autoformatting 2024-11-16 14:55:39 +01:00
proddy
eea32f3027 default test 2024-11-16 14:50:48 +01:00
proddy
92e5433165 change comment 2024-11-16 14:48:23 +01:00
proddy
af41979fd1 auto generated 2024-11-16 14:48:17 +01:00
proddy
fd63428e6c update packages 2024-11-16 14:48:09 +01:00
proddy
a82b32ce97 wifi reconnects renaming 2024-11-16 14:48:01 +01:00
proddy
c3ee1991a9 fix for scrollbar 2024-11-16 14:47:19 +01:00
proddy
1f04c1fc2c fix customSupport for ArduinoJson 7.2.1 2024-11-16 14:47:07 +01:00
proddy
f071fd842b Modules 1.0.3 with ArduinoJson 7.2.1 2024-11-16 14:45:00 +01:00
proddy
b924d07447 upgrade to 7.2.1 2024-11-16 14:44:41 +01:00
proddy
87de5d1670 update 2024-11-16 14:44:29 +01:00
Proddy
4173d4d42a Merge branch 'emsesp:dev' into dev 2024-11-16 10:37:51 +01:00
Proddy
402f5600d3 Merge pull request #2210 from vmonkey/patch-4
Update CZ translation
2024-11-16 10:37:39 +01:00
vmonkey
268c582a86 Update CZ translation 2024-11-16 09:40:12 +01:00
proddy
346bcb977f don't default to su/admin when in Serial Console 2024-11-15 17:11:02 +01:00
proddy
4cf251f613 formatting 2024-11-15 16:47:37 +01:00
proddy
1db093e6f4 add back missing funciton for 2207 2024-11-15 16:06:49 +01:00
proddy
10ee8ef120 3.7.1-dev.8 2024-11-15 16:01:25 +01:00
proddy
b8a7c2750c remove NTP status 2024-11-15 16:01:18 +01:00
proddy
654c9c39ae #2207 2024-11-15 16:01:03 +01:00
proddy
c365055825 Track number of WiFi reconnects #2207 2024-11-15 16:00:51 +01:00
proddy
7a6670db0d fix nasty scroll bar appearing again 2024-11-15 15:58:10 +01:00
Proddy
0a46bcc14f Merge pull request #2205 from mattreim/dev 2024-11-15 09:34:39 +01:00
mattreim
ef9d889e3d Update translation 2024-11-14 21:59:42 +01:00
Proddy
a33d116bf2 Merge pull request #2203 from proddy/dev
use translations for version types
2024-11-14 21:15:44 +01:00
proddy
fa4dcdcc6b use version translations 2024-11-14 21:14:31 +01:00
proddy
5f11bb3bb0 formatting 2024-11-14 21:14:11 +01:00
Proddy
fdc3b19170 Merge pull request #2202 from MichaelDvP/dev
fix analog input pullup and counter on gpio 25/26, dac values on web #2201
2024-11-14 20:37:56 +01:00
MichaelDvP
e15f9dec5a show dac output on dashboard/sensors, fix dac pins for esp32s2 2024-11-14 18:41:18 +01:00
MichaelDvP
f8c279edb0 fix input pullup and counter on gpio 25/26, #2201 2024-11-14 17:15:17 +01:00
Proddy
bf21097745 Merge pull request #2199 from MichaelDvP/dev
fixes and additions for #2188, #2198, 2192, #2192, #2132
2024-11-14 15:06:10 +01:00
MichaelDvP
b6d2ab6adb update pkg 2024-11-14 12:44:01 +01:00
MichaelDvP
1811558069 fix read too many telegram parts, 3.7.1-dev.6 2024-11-14 12:27:38 +01:00
MichaelDvP
d899b58284 raw send priority, don't retry rejected telegrams 2024-11-14 07:48:28 +01:00
MichaelDvP
9e8faaab64 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-11-11 18:20:26 +01:00
MichaelDvP
5b1266a638 update pkg 2024-11-11 18:05:35 +01:00
MichaelDvP
52552de300 fix wrong dhw mapping, #2188 2024-11-11 17:51:43 +01:00
MichaelDvP
11fd81f25f add MX400, #2198 2024-11-11 17:50:12 +01:00
MichaelDvP
a8b93dd571 auxheaterstatus to auxheaterlevel, #2192 2024-11-11 17:49:45 +01:00
Proddy
9b91faba10 Merge pull request #2196 from misa1515/patch-13
Update locale_translations.h
2024-11-11 06:56:25 +01:00
misa1515
9b4ea2af94 Update locale_translations.h 2024-11-10 23:53:39 +01:00
MichaelDvP
c5a5b3b20c Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-11-10 17:42:02 +01:00
Proddy
68fceaab87 Merge pull request #2195 from proddy/dev
improve Version checking
2024-11-10 16:56:06 +01:00
proddy
6b3cb00917 #2190 2024-11-10 16:52:39 +01:00
proddy
00beb2a039 updates to firmware check UI 2024-11-10 00:37:14 +01:00
proddy
0927a2b44b update tests 2024-11-09 15:55:26 +01:00
proddy
b00f5dd8c0 improved version check - #2190 2024-11-09 15:08:36 +01:00
proddy
367260b143 package update 2024-11-09 15:08:04 +01:00
MichaelDvP
38efb0de67 workaround version update check #2190 2024-11-09 09:53:36 +01:00
MichaelDvP
df92e9253f check lastcode, fix #2189, allow setting silentfrom/to as hh:mm 2024-11-08 16:10:20 +01:00
MichaelDvP
afc2afbac0 heatpump uoms fix #2188 2024-11-08 16:08:53 +01:00
proddy
7b4cd5c4d1 remove comment 2024-11-07 21:30:24 +01:00
proddy
06fa541931 add Michaels solution to uom on Domoticz 2024-11-07 21:29:57 +01:00
proddy
7f5ab93644 formatting 2024-11-07 21:29:35 +01:00
proddy
c2e90e2710 fix standalone language order 2024-11-07 21:29:28 +01:00
proddy
fdf7ab1aa7 rename dump functions 2024-11-07 21:29:14 +01:00
proddy
e7334a2492 rebuild after wwextra change to bool 2024-11-07 21:28:47 +01:00
MichaelDvP
847c3ac2cd Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-11-07 18:37:23 +01:00
proddy
cce5c0d09e domoticz use "" for no-uom (https://github.com/emsesp/EMS-ESP32/issues/2177#issuecomment-2462320401) 2024-11-07 15:41:02 +01:00
Proddy
77330c99f4 Merge pull request #2187 from proddy/dev
fix lint warnings
2024-11-07 12:17:33 +01:00
proddy
a4c07b8472 fix liont warning 2024-11-07 12:17:08 +01:00
proddy
5dd644fe1c update router 2024-11-07 12:17:02 +01:00
Proddy
fc53917512 Merge pull request #2185 from proddy/dev
mainly MQTT fixes for Domoticz
2024-11-07 09:19:14 +01:00
proddy
8284627b1d remove link to contact form 2024-11-07 09:12:02 +01:00
proddy
f6f0c326ef wwextra bool 2024-11-07 09:11:54 +01:00
proddy
2780a5f148 remove paths-ignore, can't have both! 2024-11-06 20:44:01 +01:00
proddy
4785f78f28 move telegram type (read,write,broadcast) after the directional A->B for easier viewing 2024-11-06 20:36:15 +01:00
proddy
3720ac4e2f add comment and extra debug 2024-11-06 20:35:39 +01:00
proddy
5d3695f72c move log block to in condition 2024-11-06 20:35:15 +01:00
proddy
62dcfb3244 change default version to 3.7.1 2024-11-06 20:34:54 +01:00
proddy
64de164e9d standalone includes two languages for testing, en & de 2024-11-06 20:34:44 +01:00
proddy
aa065aa24e add test to change locale 2024-11-06 20:34:15 +01:00
proddy
bba0b76e3f align Accept Changes button 2024-11-06 20:34:05 +01:00
proddy
2623178a00 aligning table formatting and style 2024-11-06 20:33:04 +01:00
MichaelDvP
6ab3ce8b02 boilerstate from 0xE3 for heatpumps, fix #2132 2024-11-06 18:27:33 +01:00
proddy
b193b45f1f dont run Pull Release check on Web code 2024-11-06 14:42:39 +01:00
proddy
324f9d0686 prevent page rerender 2024-11-06 14:34:18 +01:00
proddy
e74af57c16 formatting 2024-11-06 14:34:07 +01:00
proddy
74b935c27f removed comment 2024-11-06 11:55:30 +01:00
proddy
f6964e360b wwExtra can be 0,1,2 - not degrees 2024-11-06 11:55:21 +01:00
proddy
e9441c40aa dev-4 updates 2024-11-06 11:55:03 +01:00
proddy
9da73ba04f Support MQTT Discovery (AD) with Domoticz #2177 2024-11-06 11:54:53 +01:00
proddy
2cd60883d2 add application/msgpack 2024-11-06 11:53:46 +01:00
proddy
6a0a3ea440 fix broken build 2024-11-06 11:53:32 +01:00
proddy
4a71059c7c updated dev-4 2024-11-06 11:53:24 +01:00
proddy
bed0f3674b 3.7.1-dev.4 2024-11-06 11:53:04 +01:00
proddy
7837bc1e30 break build if standalone doesnt compile 2024-11-06 11:51:53 +01:00
proddy
81d42c21e5 update packages 2024-11-06 11:50:58 +01:00
MichaelDvP
5777d7cb0a fix standalone 2024-11-06 09:26:26 +01:00
Proddy
9689f0a7da Merge pull request #2178 from MichaelDvP/dev
add commands for shower, small fixes
2024-11-06 08:50:11 +01:00
MichaelDvP
64a1e00501 commands showertimer, showeralert work instant and permanent, move to shower.cpp 2024-11-05 15:01:00 +01:00
MichaelDvP
fa630b9e64 add system commands showertimer, showeralert #2168 2024-11-05 08:54:05 +01:00
MichaelDvP
761ee9e7d0 fix topic for HA config default case 2024-11-05 08:42:28 +01:00
MichaelDvP
000a73156a formatting 2024-11-05 07:44:12 +01:00
MichaelDvP
086aef6ef2 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-11-04 15:06:23 +01:00
Proddy
94f822d39f Merge pull request #2175 from vmonkey/patch-3
Update web CZ translations
2024-11-04 14:05:26 +01:00
Proddy
ea4c1f92d3 Merge pull request #2176 from proddy/dev
use msgpack content-type - #2166
2024-11-04 12:00:25 +01:00
proddy
eb9e72e257 Merge branch 'dev' of https://github.com/proddy/EMS-ESP32 into dev 2024-11-04 11:59:20 +01:00
proddy
1d8e32ec74 use msgpack content-type - #2166 2024-11-04 11:59:18 +01:00
proddy
6cf4985a04 package update 2024-11-04 11:59:00 +01:00
vmonkey
3c44f89804 Update web CZ translations
Fix few typos and translations, translate developer mode
2024-11-04 08:28:30 +01:00
Proddy
993fa9fead Merge branch 'emsesp:dev' into dev 2024-11-03 23:41:21 +01:00
Proddy
bab44d58ff Merge pull request #2172 from vmonkey/patch-1
Update CZ translation
2024-11-03 23:40:57 +01:00
Proddy
5bfb65fa91 Merge pull request #2173 from vmonkey/patch-2
Update CZ translation (web)
2024-11-03 23:40:41 +01:00
vmonkey
197f943d63 Update CZ translation (web) 2024-11-03 14:08:55 +01:00
vmonkey
b6f932e019 Update CZ translation 2024-11-03 14:00:13 +01:00
proddy
6bbd7d6333 comments 2024-11-02 09:02:44 +01:00
proddy
98708f2293 package update 2024-11-02 09:02:38 +01:00
Proddy
df75e86bf4 Merge pull request #2163 from proddy/dev
add uom back for Domoticz
2024-11-01 13:05:03 +01:00
proddy
92041d5d3f add uom back for Domoticz 2024-11-01 13:04:32 +01:00
proddy
ed9e7f9e2f add new words to cspell dictionary 2024-10-31 23:29:47 +01:00
proddy
f9062463fd multi-thread compile 2024-10-31 23:29:34 +01:00
proddy
88b39be386 fix typos 2024-10-31 23:29:24 +01:00
proddy
5f13fcf744 show file size 2024-10-31 23:29:18 +01:00
proddy
e6e0e9700f update generated files 2024-10-31 23:29:07 +01:00
Proddy
1e1dfccbee Merge pull request #2160 from proddy/dev
value_json['%s']['%s'] for Domoticz (to test)
2024-10-31 22:29:56 +01:00
proddy
628f845b16 value_json['%s']['%s'] for Domoticz (to test) 2024-10-31 22:28:53 +01:00
proddy
2def5a237a added a comment 2024-10-31 22:28:27 +01:00
proddy
d6e66982fd 3.7.1-dev-2 2024-10-31 22:27:57 +01:00
proddy
a88f9070b9 package update 2024-10-31 22:27:25 +01:00
MichaelDvP
e430ecf85c don't count echos as errors also for remote thermostat emulation 2024-10-31 16:29:36 +01:00
Proddy
13dfc87c57 Merge pull request #2159 from proddy/dev
remove template logic for Domoticz -#2156
2024-10-31 12:13:37 +01:00
proddy
60ac6aa4ba remove template logic for Domoticz -https://github.com/emsesp/EMS-ESP32/discussions/2156 2024-10-31 12:13:05 +01:00
proddy
5a37517f08 package update 2024-10-31 12:11:17 +01:00
Proddy
30b7b6db34 Merge pull request #2158 from MichaelDvP/dev
small fixes, webinterface and log messages
2024-10-30 18:12:44 +01:00
Proddy
2df67c2d64 Merge pull request #2154 from proddy/dev
updates to 3.7.1
2024-10-30 18:10:40 +01:00
proddy
fd81dc9f5b rename temp file to pre_load.json 2024-10-30 18:09:02 +01:00
proddy
ef3862fff0 add comment 2024-10-30 18:08:48 +01:00
proddy
06bb5324f2 package update 2024-10-30 18:08:38 +01:00
proddy
38abe96fe1 add example data 2024-10-30 18:08:27 +01:00
MichaelDvP
5f1fa3f59b show dev releaseNotes 2024-10-30 17:39:15 +01:00
MichaelDvP
ba0f77e41b Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-10-30 16:50:56 +01:00
MichaelDvP
e28794c77a fix upgradeable for release version 2024-10-30 16:50:48 +01:00
MichaelDvP
3dd67acc8d fix changing TZ in NTPsettings without clearing enable+server 2024-10-30 16:48:32 +01:00
MichaelDvP
971e2869a2 log mention thermostat dst setting 2024-10-30 16:47:19 +01:00
proddy
83a49c1814 mention download.emsesp.org 2024-10-30 15:51:51 +01:00
proddy
11e398ad49 include yarn cjs 2024-10-30 15:33:35 +01:00
Proddy
4037e1db5a Merge branch 'emsesp:dev' into dev 2024-10-30 14:47:30 +01:00
Proddy
8bf97c067f Merge pull request #2157 from MichaelDvP/dev
thermostat time #2142, boiler power reduction #2147
2024-10-30 14:47:13 +01:00
proddy
f23e92bd2e package update 2024-10-30 11:19:23 +01:00
proddy
c8d22f72b3 add multi-platform favicons 2024-10-30 11:19:16 +01:00
proddy
4514ae2210 add comment 2024-10-30 11:19:06 +01:00
MichaelDvP
52adf6749e limit thermostat time set to 3 tries, check dst flag #2142 2024-10-29 11:43:50 +01:00
proddy
47599e632a package update 2024-10-29 11:30:10 +01:00
proddy
d527f4662d add TODO 2024-10-29 11:30:04 +01:00
MichaelDvP
29016b6342 fix check telegrams for remote 2024-10-29 09:28:11 +01:00
MichaelDvP
87210f947c Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-10-29 07:37:35 +01:00
Proddy
fcf8432325 Merge pull request #2150 from proddy/dev
minor fixes
2024-10-28 11:59:51 +01:00
proddy
a41ded6673 3.7.1-dev.1 2024-10-28 11:57:07 +01:00
proddy
7598290c5f add HA classes to Numbers - Missing attributes in MQTT Discovery Message #2149 2024-10-28 11:56:58 +01:00
proddy
eed676f521 add device model - #2073 2024-10-28 11:15:24 +01:00
proddy
6e9bc2d47a remove file 2024-10-28 11:13:12 +01:00
proddy
21acd900e5 fixes #2148 2024-10-28 11:13:05 +01:00
MichaelDvP
48ab1abf39 boiler (HP) power reduction #2147 2024-10-28 07:31:47 +01:00
MichaelDvP
b6053e9a7c set thermostat datetetime: max 3 tries 2024-10-27 15:16:12 +01:00
Proddy
65e0ae174a Merge pull request #2146 from proddy/dev
fix sonar warning
2024-10-27 14:59:41 +01:00
proddy
b2ffe8fe49 Merge branch 'dev' of https://github.com/proddy/EMS-ESP32 into dev 2024-10-27 14:58:25 +01:00
proddy
19a3632c04 fix sonar warning 2024-10-27 14:58:24 +01:00
Proddy
5325904050 Merge pull request #2145 from proddy/dev
fix lint/codacy warnings
2024-10-27 12:21:44 +01:00
proddy
944f94997b fix lint/codacy warnings 2024-10-27 12:21:19 +01:00
Proddy
1bb7d2f150 Merge pull request #2144 from proddy/dev
v3.7.1
2024-10-27 11:45:10 +01:00
proddy
20455fdc00 v3.7.1 2024-10-27 11:44:39 +01:00
Proddy
3cd67741d6 Merge pull request #2143 from proddy/dev
minor UI changes
2024-10-27 10:52:35 +01:00
proddy
4a4ea0e749 change text for customizations/rename 2024-10-27 10:48:11 +01:00
proddy
13a24e4d85 update test data 2024-10-27 10:47:51 +01:00
proddy
72a515faab formatting text 2024-10-27 10:47:39 +01:00
proddy
4fdf1d810e tidy up rename buttons 2024-10-27 10:47:23 +01:00
Proddy
d440e6dc9a Merge pull request #2141 from proddy/dev
prepare 3.7.0
2024-10-26 20:56:23 +02:00
proddy
8a12248bc5 auto generated 2024-10-26 20:52:46 +02:00
proddy
997b05528b bump version 2024-10-26 20:50:01 +02:00
proddy
8bb8dae763 auto generated 2024-10-26 20:49:54 +02:00
proddy
9eb71cfe95 enclose device name in quotes, as we now use commas and it breaks csv 2024-10-26 20:49:45 +02:00
proddy
21c6742725 change show commands text 2024-10-26 20:49:23 +02:00
proddy
1809ceb380 10 -> 11 languages supported 2024-10-26 20:49:12 +02:00
proddy
4a1b78636b updated scripts - adding missing entities to modbus 2024-10-26 20:48:53 +02:00
proddy
0521bbb66e test version to 3.7.0 2024-10-26 20:48:39 +02:00
proddy
0ab8692e36 updated 3.7.0 screenshots 2024-10-26 20:48:14 +02:00
proddy
5a659ff6c9 package update 2024-10-26 20:48:01 +02:00
proddy
fbc2e40fba change comments 2024-10-26 20:47:49 +02:00
proddy
e8e73e1b83 package update 2024-10-26 11:14:56 +02:00
Proddy
76af1b73c1 Merge pull request #2139 from MichaelDvP/dev
cz translation #2096, MH210 mapping #2138
2024-10-25 18:17:28 +02:00
MichaelDvP
108f91b44f map MH210 prod.248, id 0x20 as mixer, #2138 2024-10-25 17:40:03 +02:00
MichaelDvP
eaeecc2f84 update cz entity translations from @skylk 2024-10-25 17:38:58 +02:00
MichaelDvP
698ab4b72e update pkg 2024-10-25 17:38:05 +02:00
Proddy
b2c5a387bb Merge pull request #2134 from MichaelDvP/dev
16MB partitions
2024-10-24 09:25:51 +02:00
MichaelDvP
f901559499 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-10-24 08:02:42 +02:00
MichaelDvP
2d4fb09e0e partitions 16MB 2024-10-24 07:35:17 +02:00
MichaelDvP
c3ee89e8cd add CR10H 2024-10-24 07:34:45 +02:00
Proddy
33884a9c94 Merge pull request #2133 from proddy/dev
updates
2024-10-23 21:23:40 +02:00
proddy
0d43703f16 make unknown - #2124 2024-10-23 17:49:16 +02:00
proddy
d248d5cc21 add comment 2024-10-23 17:48:59 +02:00
proddy
03445377b5 update dictionary 2024-10-23 17:48:47 +02:00
proddy
bf1c2b8a6c update package 2024-10-23 17:48:39 +02:00
proddy
3535e4eeee remove debug line 2024-10-23 15:02:44 +02:00
Proddy
db86c564b3 Merge branch 'emsesp:dev' into dev 2024-10-23 10:24:12 +02:00
Proddy
003ab39c97 Merge pull request #2131 from MichaelDvP/dev
update changelog
2024-10-23 09:14:02 +02:00
MichaelDvP
5c3441aa88 update changelog 2024-10-23 08:42:06 +02:00
Proddy
2d0de0d976 Merge branch 'emsesp:dev' into dev 2024-10-22 22:08:38 +02:00
Proddy
16be0e1cbc Merge pull request #2129 from MichaelDvP/dev
scheduler functions #2115, uptime notset-value #2109, device custom name #2073
2024-10-22 22:08:10 +02:00
Proddy
68c924427e Merge pull request #2128 from mattreim/dev
i18n fullstops remove
2024-10-22 21:55:08 +02:00
MichaelDvP
a9d5133917 cz entitiy translations from #2096 2024-10-22 20:03:57 +02:00
mattreim
185188d964 i18n fullstops remove
There were still a few missing.
2024-10-22 18:37:39 +02:00
MichaelDvP
f12cbb1f32 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-10-22 18:36:13 +02:00
proddy
808385fb8a update spellings 2024-10-22 17:41:27 +02:00
Proddy
98b544d789 Merge pull request #2127 from proddy/dev
bump version to 3.7.0-dev.48
2024-10-22 17:36:08 +02:00
proddy
c85a8f80e5 Merge branch 'dev' of https://github.com/proddy/EMS-ESP32 into dev 2024-10-22 17:34:57 +02:00
proddy
9a19464eac bump version 2024-10-22 17:33:52 +02:00
Proddy
5f018310e3 Merge pull request #2126 from proddy/dev
fix version check in Settings page
2024-10-22 17:32:53 +02:00
proddy
94d4d13a47 add test data for checkUpgrade action 2024-10-22 17:31:58 +02:00
proddy
496b335780 check for empty param 2024-10-22 17:26:37 +02:00
proddy
747aabef0a comments 2024-10-22 17:26:30 +02:00
proddy
9d22609370 remove debug 2024-10-22 17:26:14 +02:00
proddy
ebe9dc8fa9 fullstops again 2024-10-22 17:25:53 +02:00
proddy
7e2f3f610f add missing fullstop 2024-10-22 17:25:37 +02:00
proddy
de64e95441 add more tests for actions 2024-10-22 17:25:22 +02:00
proddy
b610bcd4bb package update 2024-10-22 17:25:10 +02:00
Proddy
6094804e5b Merge pull request #2120 from proddy/dev
fix potential buffer overflow
2024-10-22 14:14:44 +02:00
proddy
4565e64f63 fix potential buffer overflow 2024-10-22 14:14:05 +02:00
Proddy
0a062b17da Merge pull request #2117 from proddy/dev
Developer Mode and send EMS Read Commands from WebUI - #2116
2024-10-22 13:57:01 +02:00
proddy
aa4fab7296 package update 2024-10-22 13:54:43 +02:00
proddy
bc17e2cd94 add version page, move off Status to Settings 2024-10-22 12:14:41 +02:00
proddy
f877aaa11d package update 2024-10-22 12:14:25 +02:00
proddy
1513e1cec5 add emsesp_version 2024-10-22 12:14:11 +02:00
proddy
10cffd5c6f remove all values 2024-10-22 12:13:44 +02:00
proddy
4e8771ead2 remove RELEASE_NOTES 2024-10-22 12:13:31 +02:00
MichaelDvP
614f05a286 read telegram 0x01 offset 27 device name 2024-10-22 08:01:04 +02:00
MichaelDvP
21b2fb46de read telegram set length to max 25/27 per telegram part 2024-10-22 07:59:13 +02:00
proddy
0dfcd10505 improved read cmd dialog 2024-10-21 23:28:10 +02:00
proddy
26aa55346a use data instead of value for apicall 2024-10-21 23:27:52 +02:00
proddy
f929a8e843 update read command test 2024-10-21 20:45:38 +02:00
proddy
5bb125545d fix eslint warnings 2024-10-21 20:45:32 +02:00
proddy
c6c4a5bfb7 use strlcpy for readCommand 2024-10-21 20:44:57 +02:00
proddy
697daeeefd package update 2024-10-21 20:44:18 +02:00
proddy
03d4e560e5 remove unused variables 2024-10-21 15:38:12 +02:00
proddy
8f35be4edf replace sstream 2024-10-21 15:35:13 +02:00
proddy
670a2bbb4a add fullstop to title 2024-10-21 13:50:28 +02:00
proddy
07d35fd19c remove json | false, as it will always default to false 2024-10-21 13:37:30 +02:00
proddy
120bdf653d update test data 2024-10-21 10:46:31 +02:00
proddy
21e6775182 remove Unity 2024-10-21 10:46:23 +02:00
proddy
8e48348d10 update comment 2024-10-21 10:46:15 +02:00
proddy
28ee4f0255 remove commented code 2024-10-21 10:33:03 +02:00
proddy
85d68129d8 banded rows 2024-10-21 10:32:52 +02:00
proddy
a049f063a1 move tests 2024-10-21 10:32:41 +02:00
proddy
4bd95b77c9 DE translation fix by @mattreim 2024-10-20 19:10:35 +02:00
proddy
adaa58c499 use developer mode 2024-10-20 19:07:29 +02:00
proddy
9320316041 German translation by @mattreim 2024-10-20 19:07:14 +02:00
proddy
a735db7e8f remove mention of extra_flags and EMSESP_DEFAULT_BOARD_PROFILE 2024-10-20 15:02:54 +02:00
proddy
3edbf68de0 typo in comment 2024-10-20 15:02:34 +02:00
proddy
d8f92e509a slow down log to every second 2024-10-20 15:02:25 +02:00
proddy
798e20a266 Call read commands from Web #2116 2024-10-20 15:02:11 +02:00
proddy
bd08b7e0e4 add Developer Mode and value to API Call 2024-10-20 15:01:08 +02:00
proddy
685dec4c8e change color of no data available 2024-10-20 15:00:38 +02:00
MichaelDvP
995b759230 EMS_VALUE_UINT32_NOTSET to 0xFFFFFF00 #2109 2024-10-20 14:30:26 +02:00
MichaelDvP
f816bbde62 add round, abs, int, etc. to scheduler shunting yard 2024-10-20 14:23:02 +02:00
Proddy
a130dabda5 Merge pull request #2112 from proddy/dev
update dump/export files
2024-10-19 12:15:38 +02:00
proddy
f60c692d59 update dumps 2024-10-19 12:14:59 +02:00
proddy
5f0d49e13b package update 2024-10-19 12:14:53 +02:00
Proddy
8bab7579ee Merge pull request #2107 from proddy/dev
dont show broken link if IMG cant be found
2024-10-17 14:04:19 +02:00
proddy
849610950f dont show broken link if IMG cant be found 2024-10-17 14:02:16 +02:00
proddy
fd7b823f52 auto formatting 2024-10-17 14:01:58 +02:00
Proddy
210637fde3 Merge pull request #2106 from proddy/dev
minor cleanup
2024-10-17 10:32:11 +02:00
proddy
5bae37275e package update 2024-10-17 10:27:21 +02:00
proddy
a801af1e89 maintain return type 2024-10-17 10:27:15 +02:00
Proddy
0292d55ccc Merge branch 'emsesp:dev' into dev 2024-10-17 09:17:46 +02:00
proddy
064b6ba53f Czech language 2024-10-17 00:02:15 +02:00
Proddy
c4f3046167 Merge pull request #2105 from proddy/dev
show dashboard nodes when there is data
2024-10-17 00:00:21 +02:00
proddy
7d93ecb949 show dashboard nodes when there is data 2024-10-16 23:59:34 +02:00
proddy
3f1c30c948 keep consistent messages, with fullstop at end 2024-10-16 21:54:03 +02:00
proddy
c7b565f033 package update 2024-10-16 21:53:34 +02:00
Proddy
96d37ea289 Merge pull request #2102 from suaveolent/patch-1 2024-10-15 19:27:40 +01:00
suaveolent
32aa4923dc Remove Logatherm from thermostat identifier 2024-10-15 20:14:22 +02:00
Proddy
9bdebb4960 Merge pull request #2100 from MichaelDvP/dev 2024-10-15 17:14:25 +01:00
MichaelDvP
19f983c657 formatting 2024-10-15 17:51:40 +02:00
MichaelDvP
dd8d4b29e5 add cz web translations, update pkg 2024-10-15 17:32:04 +02:00
Proddy
0f877b67de Merge pull request #2097 from mattreim/dev
Rename from "CUSTOMIZATIONS_HELP_5" and update slovak translation
2024-10-14 21:52:28 +01:00
mattreim
c06017ccf6 Update slovak (SoftVienka) translate
#2096
2024-10-14 22:44:06 +02:00
mattreim
aa741ae09b Rename from "CUSTOMIZATIONS_HELP_5"
If you choose to rename.
2024-10-14 22:36:31 +02:00
Proddy
5f35659fa7 Merge pull request #2094 from MichaelDvP/dev
fix empty scheduler on dashboard
2024-10-14 18:28:26 +01:00
MichaelDvP
2cb55be1cc Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-10-14 19:03:45 +02:00
MichaelDvP
6767ec7208 fix empty scheduler on dashboard 2024-10-14 19:03:30 +02:00
Proddy
f27916274a Merge pull request #2092 from proddy/dev
update version to 3.7.0-dev.45
2024-10-14 17:02:00 +01:00
proddy
b59681a939 bump to version 3.7.0-dev.45 2024-10-14 17:00:50 +01:00
proddy
216fcd4939 package update 2024-10-14 17:00:37 +01:00
Proddy
19d7e8dcd0 Merge pull request #2091 from MichaelDvP/dev
S3-Temperature, Thermostat dhw circuits
2024-10-14 16:41:52 +01:00
MichaelDvP
93f3583527 add boiler pumpOnTemp #2088 2024-10-14 15:50:42 +02:00
MichaelDvP
66f3c57c8e mqtt status retain, #2086 2024-10-14 13:37:37 +02:00
MichaelDvP
e44487b67f use deque for emsdevices 2024-10-14 13:34:58 +02:00
MichaelDvP
b9a8bbd1a9 fix digital_out active_low/high 2024-10-14 13:34:37 +02:00
MichaelDvP
f773f03c11 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-10-14 13:13:32 +02:00
Proddy
1435409540 Merge pull request #2089 from proddy/ft_dashboard
Ft dashboard - ui changes
2024-10-14 00:08:38 +01:00
Proddy
ee9682ae0a Merge pull request #7 from MichaelDvP/ft_dashboard
fix uom display for digital_out
2024-10-14 00:07:47 +01:00
proddy
6964620bd4 consistent hover effect in tables 2024-10-14 00:06:08 +01:00
proddy
079cae767c fix count 2024-10-13 23:13:55 +01:00
proddy
f66832c7f3 retain toggle in dashboard, refresh when new devices loaded 2024-10-13 22:45:34 +01:00
proddy
e71542d9aa formatting 2024-10-13 22:45:12 +01:00
Proddy
00dcdecc30 Merge pull request #2083 from proddy/ft_dashboard
Ft dashboard - #1958
2024-10-13 18:41:43 +01:00
proddy
3c1bfa0f3e formatting table 2024-10-13 18:40:57 +01:00
proddy
55bcc4410b fix dashboard/disabled analog sensors 2024-10-13 09:21:56 +01:00
proddy
e40d01ff87 package update 2024-10-13 09:21:39 +01:00
proddy
ed11260ffa don't include disabled analog sensors in dashboard 2024-10-13 00:09:54 +01:00
proddy
4ca7da684e add a test_analogsensor3 that is disabled 2024-10-13 00:09:43 +01:00
MichaelDvP
f0a2f4082c thermostat dhw circuits use offset only 2024-10-12 17:42:31 +02:00
proddy
801c1aedaa add TODOs for formatting reminders 2024-10-12 16:17:40 +01:00
proddy
67f7cc53b3 update sample test data 2024-10-12 16:17:12 +01:00
proddy
b78f6da35b add comment reminders 2024-10-12 16:15:08 +01:00
proddy
b251fa4f26 alova update 2024-10-12 10:43:52 +01:00
MichaelDvP
712c627bbd Merge branch 'ft_dashboard' of https://github.com/proddy/EMS-ESP32 into ft_dashboard 2024-10-12 09:34:34 +02:00
MichaelDvP
eb895b44ae fix uom display for digital_out 2024-10-12 09:34:19 +02:00
proddy
ebd7d86502 table formatting 2024-10-12 01:06:09 +01:00
proddy
4fac364600 table formatting, remove inner scrollbar 2024-10-11 22:01:13 +01:00
proddy
c79d5f2890 toast slide in from left so it doesnt obscure data 2024-10-11 22:00:57 +01:00
proddy
38f42445aa update test data for dashboard 2024-10-11 22:00:39 +01:00
Proddy
e36f6db59d Merge pull request #6 from MichaelDvP/ft_dashboard
small changes, use commands to change dashboard values
2024-10-11 20:46:11 +01:00
proddy
662df4c902 package update 2024-10-11 20:38:41 +01:00
MichaelDvP
33efb1a440 all dashboard changes uses commands 2024-10-11 20:14:10 +02:00
MichaelDvP
ef3d42b619 fix s3 board_build.extra_flags for USB serial 2024-10-11 19:51:39 +02:00
MichaelDvP
57f337ce22 fix board_build.extra_flags, (for serial USB) #2082 2024-10-11 15:50:45 +02:00
MichaelDvP
9304cc6e47 dhw circuit number only per offset 2024-10-11 15:44:05 +02:00
proddy
6d45dfb925 DE translations for Dashboard 2024-10-11 10:49:02 +01:00
proddy
d373309fea Implements back end for Dashboard - Feature: Dashboard showing all data (favourites, sensors, custom) #1958 2024-10-10 21:27:00 +01:00
proddy
a001a31401 use DeviceTypeUniqueID 2024-10-10 21:26:39 +01:00
proddy
31cfdc6604 support single scheduler item updates for Dashboard 2024-10-10 21:26:22 +01:00
proddy
37ac684d24 rename test temp sensors 2024-10-10 21:25:48 +01:00
proddy
e52753e83c rename DialogProps 2024-10-10 21:25:11 +01:00
proddy
9a6e84c68a replace DashboardData with array 2024-10-10 21:24:57 +01:00
proddy
b7e6552557 Dashboard - #1958 2024-10-10 21:24:32 +01:00
proddy
ca8ed2d1a5 added DeviceTypeUniqueID for Dashboard 2024-10-10 21:24:04 +01:00
proddy
a9b01e05c9 CTRL-D for console 2024-10-10 21:23:51 +01:00
proddy
5234a4477f 3.7.0-dev.44 2024-10-10 21:23:34 +01:00
proddy
c5257d7ccf ignore local package 2024-10-10 21:23:15 +01:00
proddy
0e451f0a82 rename test sensors 2024-10-10 21:22:49 +01:00
proddy
5a472cb6ee package update 2024-10-10 21:22:32 +01:00
proddy
594a48afed Dashboard data 2024-10-10 21:22:21 +01:00
proddy
03ae9735ef add test for Dashboard 2024-10-10 21:22:12 +01:00
proddy
87c9036b87 text for Dashboard 2024-10-10 21:21:57 +01:00
proddy
faa019863b DashboardItem[] 2024-10-10 21:21:45 +01:00
proddy
2bdd4afd23 support for unknown value and uom 2024-10-10 21:21:35 +01:00
proddy
d39fc8221e rename DevicesDialog 2024-10-10 21:21:19 +01:00
proddy
3203d03252 move Sensors to Modules 2024-10-10 21:20:49 +01:00
proddy
6b99fb0404 add icon for Scheduler 2024-10-10 21:20:36 +01:00
MichaelDvP
ffdcbac1e0 add PV max compressor power 2024-10-10 16:19:59 +02:00
MichaelDvP
e78b54dc23 add S3 temperature #2077 2024-10-10 13:19:12 +02:00
MichaelDvP
c4e9f3c328 fix dhw circuits #2079 2024-10-10 13:18:32 +02:00
MichaelDvP
6187378388 fix dhw circuit tset elegrams #2079 2024-10-10 09:53:52 +02:00
MichaelDvP
08f5c4b674 fix digital_out: active_low 2024-10-10 09:52:54 +02:00
MichaelDvP
1c3b1f5790 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-10-10 09:34:18 +02:00
proddy
1e7835787b package update 2024-10-09 09:04:40 +02:00
proddy
0881c574b2 reverse polarity if offset 0 2024-10-09 09:04:32 +02:00
proddy
63f35170c6 make all REMOVE and UPDATE buttons look the same 2024-10-08 22:55:23 +02:00
proddy
8e56cbfa63 fix data loading when dialog was open 2024-10-08 22:55:06 +02:00
proddy
81541d0323 added a standalone test 2024-10-08 22:54:39 +02:00
proddy
dbaefe4d50 added some comments 2024-10-08 22:54:24 +02:00
proddy
f94ac6b067 change CTRL-C to CTRL-S as pio monitor uses ctrl-c to exit 2024-10-08 22:54:01 +02:00
proddy
4611ed49b0 Dashboard implementation 2024-10-08 22:53:36 +02:00
proddy
fc0fd625d3 show error when using an invalid gpio in webUI 2024-10-08 22:52:05 +02:00
proddy
aa88c0793b more cleanup 2024-10-08 22:51:40 +02:00
proddy
8cbac95b99 3.7.0-dev.44 2024-10-08 22:51:26 +02:00
proddy
8b1015b706 add note about upload speeds on MacBooks 2024-10-08 22:51:14 +02:00
proddy
621f35b1d5 add Dashboard test in api3 2024-10-08 22:50:51 +02:00
proddy
e7d9978e02 package update 2024-10-08 22:50:37 +02:00
proddy
0c3a83d3b3 ignore mjs files 2024-10-08 22:50:28 +02:00
proddy
59c4866530 updated for Dashboard 2024-10-08 22:50:19 +02:00
proddy
1681d99238 replace data with nodes 2024-10-08 22:50:06 +02:00
proddy
5d69ce18a2 optimize with useMemo 2024-10-08 22:49:44 +02:00
proddy
87cea5865a optimize with useMemo 2024-10-08 22:49:29 +02:00
proddy
10c03a3f6b Merge branch 'dev' into ft_dashboard 2024-10-06 14:00:30 +02:00
Proddy
60ab5a3e42 tidy up device names
continuation from https://github.com/emsesp/EMS-ESP32/issues/2071
2024-10-06 09:02:55 +02:00
Proddy
95944aa7a6 Merge pull request #2070 from proddy/dev
sonar optimizations
2024-10-05 19:03:32 +02:00
proddy
da53d063e7 changed comments 2024-10-05 19:02:39 +02:00
proddy
90b2ba14c6 package update 2024-10-05 19:02:31 +02:00
proddy
ffbaff8028 updated 2024-10-05 19:02:21 +02:00
proddy
34fc9f3047 fixes #2071 2024-10-05 18:37:36 +02:00
proddy
812df3640b turn on test data 2024-10-05 16:28:28 +02:00
proddy
e501ac31f5 translations and finish writeDevice 2024-10-05 16:25:53 +02:00
proddy
4fde9e7c54 fix slowness 2024-10-04 15:41:58 +02:00
proddy
fd7d8ca532 enable write in dashboard 2024-10-04 13:32:42 +02:00
proddy
01db9db6ae update dashboard for analog 2024-10-03 21:09:50 +02:00
proddy
fb0d9454ef dashboard v.01 2024-10-03 18:06:46 +02:00
MichaelDvP
cd4d0f5abe check device active for fetching values 2024-10-03 13:23:19 +02:00
proddy
f9f87ddc0e add comment 2024-10-02 18:53:36 +02:00
proddy
fa4281cc63 package update 2024-10-02 18:53:23 +02:00
proddy
58ddee98f4 mock dashboard data 2024-10-02 18:53:08 +02:00
proddy
aac0a375c2 comment 2024-10-02 15:00:48 +02:00
proddy
2528e15a9c optimizations 2024-10-02 14:01:02 +02:00
proddy
5d1c007777 3.7.0-dev.43 2024-10-02 13:56:28 +02:00
proddy
7ea0caaab7 remove separate sonar tsconfig 2024-10-02 13:56:14 +02:00
proddy
f1800d9250 remove fixing yarn version 2024-10-02 13:55:59 +02:00
proddy
a541a56caa update lock file 2024-10-02 13:55:42 +02:00
proddy
50b22dd265 fix condition after adding a time 2024-10-02 13:55:34 +02:00
proddy
c3dd5e002a add comment 2024-10-02 13:55:09 +02:00
proddy
e0130affb7 link to sonarcloud 2024-10-02 13:55:00 +02:00
Proddy
8e6434cf7f sonarlint improvements 2024-10-02 13:32:51 +02:00
Proddy
1eaa16995b Merge pull request #2066 from proddy/dev
custom support page, action endpoint
2024-10-02 13:31:22 +02:00
proddy
8ccc708532 highlight upload box when dragging 2024-10-02 10:30:03 +02:00
proddy
4dee945632 fix HA warning, dont translate bool 2024-10-02 10:04:38 +02:00
proddy
91d6249ada add comments 2024-10-02 10:04:13 +02:00
proddy
52cd8fa3e8 smaller box 2024-10-02 09:30:53 +02:00
proddy
e5b98dadde code cleanup - sonarlint 2024-10-02 09:02:24 +02:00
proddy
465f14a113 package update 2024-10-02 08:54:57 +02:00
proddy
fe0d0bb11c remove data type 2024-10-02 08:54:31 +02:00
proddy
fc896914e9 sonarlint 2024-10-02 08:54:17 +02:00
proddy
eef130e229 more spacing after back arrow 2024-10-02 08:53:55 +02:00
proddy
88a01426c1 fix referer for external images 2024-10-01 09:56:32 +02:00
proddy
ed685d4a5e remove duplicate condition 2024-09-30 15:55:46 +02:00
proddy
c8603dcd81 merge all "show" commands into a single command 2024-09-30 15:28:05 +02:00
proddy
d728b1c116 move info/commands/values to top so its not repeated 2024-09-30 15:27:46 +02:00
proddy
b5203e11f0 Show Flash size in show system 2024-09-30 15:27:14 +02:00
proddy
23c2f0ceba add test img_url 2024-09-30 15:26:47 +02:00
proddy
30f491b434 fixes to https://github.com/emsesp/EMS-ESP32/pull/2066 2024-09-30 10:08:50 +02:00
proddy
d5aac1789e rename custom_support type to customSupport 2024-09-29 17:44:03 +02:00
proddy
670a5499dd use EMS-ESP-Modules.git@1.0.2 2024-09-29 16:42:09 +02:00
Proddy
2d011a899e Merge branch 'dev' into dev 2024-09-29 12:01:40 +02:00
proddy
ab040e120e move uploadURL as an action 2024-09-29 11:08:49 +02:00
Proddy
596872f5aa Merge pull request #2065 from MichaelDvP/dev
fix using NUMOP_MUL50 on webUI #2064, dev41
2024-09-29 09:48:24 +02:00
proddy
93066e4836 customSupport read file 2024-09-29 09:40:18 +02:00
proddy
c9dd2d4a72 move allvalues to new action endpoint 2024-09-29 09:17:11 +02:00
MichaelDvP
505aa1f945 fix using NUMOP_MUL50 on webUI #2064, dev41 2024-09-29 09:00:05 +02:00
proddy
a2e41d6d1e URL updates 2024-09-28 21:01:37 +02:00
Proddy
f096c1b632 Merge pull request #2063 from MichaelDvP/dev
fix rendering "-0.x" values (reported on discord)
2024-09-28 16:30:22 +02:00
MichaelDvP
77768f9bdc Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-09-28 12:22:21 +02:00
MichaelDvP
7c02894e02 fix rendering "-0.x" values (reported on discord) 2024-09-28 12:20:12 +02:00
Proddy
554425b727 Merge pull request #2061 from mattreim/dev
Update German translation
2024-09-28 09:44:00 +02:00
mattreim
6b0ad1f3f6 Update German translation 2024-09-27 17:39:19 +02:00
Proddy
243da8851c Merge pull request #2057 from proddy/dev
fixes #2056
2024-09-26 22:25:44 +02:00
proddy
68efcf3742 package update 2024-09-26 22:24:29 +02:00
proddy
b35abd744b minor issue: search in customizations only searches the english/original names (not the tranlated ones) #2056 2024-09-26 22:24:25 +02:00
Proddy
64fbc1e4aa Merge pull request #2055 from proddy/dev
#2054
2024-09-26 17:50:44 +02:00
proddy
6814f54e64 Feature: Custom Support info #2054 2024-09-26 17:44:46 +02:00
proddy
ccfbdfbd0f Gues mode in help #2054 2024-09-26 17:44:46 +02:00
proddy
00ca334fd3 update package 2024-09-26 17:44:46 +02:00
proddy
607f2cfa71 change 'show log' message 2024-09-26 17:44:46 +02:00
Proddy
bf46efd326 Merge pull request #2053 from MichaelDvP/dev
fix get attribute for second thermostat #2052
2024-09-26 17:27:25 +02:00
MichaelDvP
715f86b717 fix get attribute for second thermostat #2052 2024-09-26 15:51:24 +02:00
Proddy
ccd6b132cc Merge pull request #2051 from mattreim/dev
Update ButtonTooltip  translation
2024-09-26 07:48:40 +02:00
mattreim
e7dca3d2f4 Update ButtonTooltip translation 2024-09-25 22:57:11 +02:00
Proddy
d60cbc6a02 Merge pull request #2050 from MichaelDvP/dev
show emsesp-devices in system info, add common fields to value_info #2033
2024-09-25 20:00:34 +02:00
MichaelDvP
83d5b919d6 show emsesp-devices in system info, add common fields to value_info #2033 2024-09-25 18:47:09 +02:00
Proddy
9ca16bd2c8 Merge pull request #2049 from proddy/dev
package updates, python formatting
2024-09-25 17:33:36 +02:00
proddy
c48b7a9a5d show version on CTRL-C message 2024-09-25 17:32:43 +02:00
proddy
5cba925717 formatting 2024-09-25 17:32:31 +02:00
proddy
e802812fc6 update packages 2024-09-25 17:32:24 +02:00
Proddy
978799f3a7 Merge pull request #2048 from proddy/dev
package updates
2024-09-24 09:02:45 +02:00
proddy
7d38db705f update packages to avoid warnings 2024-09-24 09:01:45 +02:00
proddy
bf1979705b add sonarlint 2024-09-24 09:01:35 +02:00
Proddy
a79d176793 Merge pull request #2045 from proddy/dev
junkers summertime is DIV2
2024-09-23 11:09:08 +02:00
proddy
b9d7a6ac85 junkers summertime is DIV2 - fixes Thermostat FW100 wrong reading #2044 2024-09-23 11:08:36 +02:00
proddy
d61876298e 3.7.0-dev.39 2024-09-23 11:08:14 +02:00
Proddy
9787dfc0a0 Merge pull request #2043 from MichaelDvP/dev
fix api_data as command data
2024-09-22 21:38:05 +02:00
MichaelDvP
c248830042 fix api_data as command data 2024-09-22 17:40:39 +02:00
Proddy
6e22e69fec Merge pull request #2042 from proddy/dev
update console screenshots
2024-09-22 15:11:03 +02:00
proddy
cfe5cd9bff update console screenshots 2024-09-22 15:10:32 +02:00
Proddy
b8c6efffcd Merge pull request #2041 from proddy/dev
fix refreshing Module library
2024-09-22 14:30:42 +02:00
proddy
32739fe77b package update 2024-09-22 14:19:33 +02:00
Proddy
171cbd3bb1 Merge branch 'emsesp:dev' into dev 2024-09-22 14:18:47 +02:00
proddy
b0451024f8 fixes #2039 2024-09-22 14:17:47 +02:00
Proddy
c3aa64227e Merge pull request #2040 from xarbit/update_device_library
Update device library
2024-09-22 14:07:10 +02:00
Jason Scurtu
5e498cb0c2 add BOSCH Connect-Key K 30 RF 2024-09-22 11:47:09 +02:00
Jason Scurtu
a5a309ff09 update device family CS5800i/CS6800i/WLW176i 2024-09-22 11:32:28 +02:00
Proddy
82502e8222 Merge pull request #2037 from mheyse/add-modbus-registers
Modbus: add new entities
2024-09-21 23:57:06 +02:00
Proddy
c405f5b14f Merge pull request #2036 from MichaelDvP/dev
stack for scheduler 5k
2024-09-21 23:52:50 +02:00
mheyse
ad586f1101 Modbus: add new entities
- hpCurrPower
- hpPowerLimit
- pc0Flow
- pc1Flow
- pc1On
- pc1Rate
2024-09-21 16:53:00 +02:00
MichaelDvP
1c7186171e stack for scheduler 5k 2024-09-21 14:35:36 +02:00
Proddy
4905047177 Merge pull request #2035 from MichaelDvP/dev
some fixes
2024-09-21 08:34:27 +02:00
MichaelDvP
d2558708a0 shell call device/commands show info/values/commands 2024-09-20 16:03:08 +02:00
MichaelDvP
483a138f9d json type 2024-09-20 15:59:45 +02:00
MichaelDvP
c315463692 fix command name for custom entities 2024-09-20 14:14:37 +02:00
MichaelDvP
c2b52f731c customizations: tag not part of name, don't show Custom Entities as device 2024-09-20 13:30:47 +02:00
Proddy
cf9bd4d824 Merge pull request #2032 from proddy/dev
updated README
2024-09-20 09:12:03 +02:00
proddy
c34e59b540 updated feature list 2024-09-20 09:11:15 +02:00
proddy
6c61297449 fix seplling 2024-09-20 09:11:04 +02:00
proddy
c2db3c0bd6 package update 2024-09-20 09:10:54 +02:00
Proddy
6c2769fe08 Merge pull request #2031 from MichaelDvP/dev
add australian models #2030
2024-09-20 08:32:48 +02:00
MichaelDvP
748062d0e7 add australien modells #2030 2024-09-20 07:47:22 +02:00
Proddy
e292aa3e77 Merge pull request #2029 from proddy/dev
incorporated Michael's changes #2027
2024-09-19 18:39:21 +02:00
proddy
5b1493b940 incorporated Michael's changes https://github.com/emsesp/EMS-ESP32/pull/2027 2024-09-19 18:38:36 +02:00
proddy
e0130638c3 updated test results for 3.7.0 2024-09-19 18:37:33 +02:00
proddy
8762f9c64a updated text on how to run the unit tests 2024-09-19 18:37:21 +02:00
proddy
788efb1266 CTRL-C, not CTRL-L 2024-09-19 17:28:30 +02:00
Proddy
384eb9bd1f Merge pull request #2028 from proddy/dev
updated breaking change text
2024-09-19 14:50:56 +02:00
proddy
529b5d9321 updated breaking change text 2024-09-19 14:50:30 +02:00
Proddy
876a45d7a0 Merge pull request #2027 from proddy/dev
upgrade to ArduinoJson 7.2
2024-09-19 12:17:33 +02:00
proddy
cf1eae9426 ArduinoJson 7.2 upgrade 2024-09-19 12:15:19 +02:00
proddy
0ee1246865 package update 2024-09-19 12:14:47 +02:00
Proddy
3195f92276 Merge pull request #2024 from MichaelDvP/dev
few small changes
2024-09-18 09:55:46 +02:00
MichaelDvP
aca2ae88cc allow minutes only for clock input 2024-09-18 09:28:16 +02:00
MichaelDvP
3fa18e2984 german translation, see #2020 2024-09-18 09:09:43 +02:00
MichaelDvP
1235ea88b9 show ipv6 type also for wifi 2024-09-18 09:08:51 +02:00
Proddy
c30f821015 Merge pull request #2023 from proddy/dev
remove is_cmd from dump_telegrams
2024-09-17 16:02:29 +02:00
proddy
83744a96a6 remove is_cmd 2024-09-17 15:59:20 +02:00
proddy
f386fdaedd remove is_cmd 2024-09-17 15:58:42 +02:00
Proddy
fc163cc00d Merge pull request #2022 from proddy/dev
remove duplicate ctrl-c prompt in console
2024-09-17 14:13:39 +02:00
Proddy
9aadedd884 Merge branch 'emsesp:dev' into dev 2024-09-17 14:13:16 +02:00
proddy
64d4e4a2ac remove duplicate ctrl-c prompt 2024-09-17 14:12:52 +02:00
proddy
661a7cfde9 package update 2024-09-17 14:12:38 +02:00
Proddy
09753421d9 Merge pull request #2021 from proddy/dev
ipv6, comments, fix dumps
2024-09-17 11:21:38 +02:00
proddy
b3e749b10f check ipV6 fc & fd 2024-09-17 11:20:51 +02:00
proddy
869ba98d6e check for Eth boards with no PHY power-pin (-1) 2024-09-17 10:22:05 +02:00
proddy
7fe68d9db3 add comment about E32V2 2024-09-17 10:21:32 +02:00
proddy
b1795fec4d add Michael's IPv6 check 2024-09-17 10:21:22 +02:00
proddy
da08429ce8 update 2024-09-17 09:48:14 +02:00
proddy
a7bee4bf9a remove cmd 2024-09-17 09:42:24 +02:00
proddy
ade5cb79e3 dump telegrams doesnt need to show the cmd 2024-09-17 09:31:03 +02:00
proddy
6f556a9ebb package update 2024-09-17 09:30:46 +02:00
Proddy
1263df39ef Merge pull request #2019 from mattreim/dev
Update locale_translations.h
2024-09-16 23:43:17 +02:00
mattreim
c168ef93f4 Update locale_translations.h 2024-09-16 23:30:53 +02:00
Proddy
01e79aee4c Merge pull request #2018 from proddy/dev
network
2024-09-16 20:59:23 +02:00
proddy
0c72005ebb network checks - still checking 2024-09-16 16:21:53 +02:00
proddy
4af5484e16 network checks 2024-09-16 16:03:14 +02:00
proddy
f0974a552f make copy of bins for backwards compatibility with 3.6.x web version check 2024-09-16 16:03:14 +02:00
proddy
872e4117b0 update packages 2024-09-16 16:03:14 +02:00
proddy
cf49f1b398 update 2024-09-16 16:03:14 +02:00
Proddy
4a16af08b5 Merge branch 'emsesp:dev' into dev 2024-09-16 15:58:18 +02:00
Proddy
856f95769d Merge pull request #2017 from MichaelDvP/dev
fix for #2001 and #2011
2024-09-16 15:58:05 +02:00
MichaelDvP
8c1f67a779 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-09-16 13:48:18 +02:00
MichaelDvP
1c6464a4f3 pc0, pc1 flow, add uom l/h, fix #2001 2024-09-16 13:47:52 +02:00
MichaelDvP
a6ca1313ca roomifl_factor for FW120 to mul10, fix #2011 2024-09-16 13:45:59 +02:00
proddy
77b5e934a3 tidy up EMSESP_DEBUG 2024-09-15 18:09:15 +02:00
Proddy
3e9b18222b Merge pull request #2015 from mattreim/dev
Update locale_translations.h
2024-09-15 16:53:23 +02:00
mattreim
a80a5093d6 Update locale_translations.h 2024-09-15 13:39:33 +02:00
Proddy
865cd634f8 Merge pull request #2014 from proddy/dev
small changes
2024-09-15 12:35:18 +02:00
proddy
5cb4f48905 only show running partition which is boot on 1st install and then cycle between app0/app1 2024-09-15 12:34:31 +02:00
proddy
9234bfd34c add show command 2024-09-15 12:33:51 +02:00
proddy
d10e27c7c3 remove obsolete last_transmit 2024-09-15 12:33:42 +02:00
proddy
e54d9a6c32 minor std::string optimizations 2024-09-15 12:33:27 +02:00
proddy
9a20bf350a more checks 2024-09-15 12:32:35 +02:00
proddy
1bb33fbd3c package update 2024-09-15 12:32:28 +02:00
Proddy
2e4a2952f7 Merge pull request #2013 from mattreim/dev
Update locale_translations.h
2024-09-15 09:24:57 +02:00
mattreim
65b90b595b Update locale_translations.h 2024-09-14 23:50:56 +02:00
mattreim
35ffd9b2dc Update locale_translations.h 2024-09-14 15:54:58 +02:00
Proddy
1757f67bbc Merge pull request #2012 from mattreim/dev
Update locale_translations.h
2024-09-14 14:56:17 +02:00
mattreim
4881e95d28 Add "Betriebsart" 2024-09-14 14:27:06 +02:00
mattreim
e92fa7b85e Update locale_translations.h 2024-09-14 13:29:36 +02:00
Proddy
c73ac6cca9 Merge pull request #2010 from proddy/dev
update doc in prep for 3.7.0 release
2024-09-13 11:14:20 +02:00
proddy
3904b20ff9 update doc in prep for 3.7.0 release 2024-09-13 11:13:45 +02:00
Proddy
6b372402f6 Merge pull request #2009 from proddy/dev
merge endpoints
2024-09-13 10:06:29 +02:00
proddy
191edffe3c optimize endpoints, so re-use where possible 2024-09-13 10:03:11 +02:00
proddy
63a3152b91 remove unused useRequest 2024-09-13 10:02:19 +02:00
proddy
dd1ed08f7c remove .txt and .csv 2024-09-13 10:01:59 +02:00
proddy
003d78be9f update dictionary 2024-09-13 10:01:43 +02:00
proddy
68036f6467 3.7.0-dev.37 2024-09-13 10:01:29 +02:00
MichaelDvP
2578c052b3 compiles with pioarduino 2024-09-12 19:08:59 +02:00
Proddy
f0ff51af25 Merge pull request #2006 from proddy/dev
fix typos, optimize web log
2024-09-12 18:14:10 +02:00
proddy
fde425512e update pio example for upload params 2024-09-12 18:11:49 +02:00
proddy
b4712db4ae remove /rest/fetchLog 2024-09-12 17:54:17 +02:00
proddy
44644d522c auto scroll 2024-09-12 17:53:34 +02:00
Proddy
ddd2083de8 Merge branch 'emsesp:dev' into dev 2024-09-12 17:50:49 +02:00
Proddy
a417cf7136 Merge pull request #2008 from mattreim/dev
Update German translation
2024-09-12 17:50:32 +02:00
mattreim
26fbfd6671 Update German translation 2024-09-12 17:07:35 +02:00
proddy
9e5182e4b2 auto scroll translation 2024-09-12 16:06:26 +02:00
proddy
141c3a7b1e comment out REFRESH_SYNC 2024-09-12 16:06:17 +02:00
proddy
64c93bda6b remove fetchlog endpoint data 2024-09-12 16:06:04 +02:00
proddy
083041134b onError/onMessage changes 2024-09-12 16:05:45 +02:00
proddy
4c877e1ea1 package update 2024-09-12 16:04:56 +02:00
proddy
6c1fe40ef7 add back formidable 2024-09-12 12:02:29 +02:00
proddy
6e5ffa9920 package cleanup 2024-09-12 09:03:57 +02:00
proddy
92ee5c3c38 add new words to spell check 2024-09-12 08:57:10 +02:00
proddy
8091250397 remove unused packages 2024-09-12 08:57:02 +02:00
Proddy
8858820630 Merge branch 'emsesp:dev' into dev 2024-09-12 08:43:32 +02:00
Proddy
0572968530 Merge pull request #2007 from mattreim/dev
Update German translation[corrections]
2024-09-12 08:43:14 +02:00
mattreim
3c12f01cce Update German translation[corrections] 2024-09-12 00:54:24 +02:00
proddy
6ab70b2609 update sk 2024-09-11 23:00:29 +02:00
Proddy
86597e0ee0 Merge branch 'emsesp:dev' into dev 2024-09-11 22:57:21 +02:00
Proddy
ee355f44d7 Merge pull request #2005 from mattreim/dev
Update German translation
2024-09-11 22:57:05 +02:00
mattreim
0fe49528fa Update index.ts 2024-09-11 22:55:41 +02:00
proddy
061a5d4abf lowercase Me and All, so its same as device names 2024-09-11 22:33:47 +02:00
proddy
1eb4fd95d8 updated dev-35 2024-09-11 22:32:11 +02:00
proddy
b2fcce180f removed delay in TCP log transmision 2024-09-11 22:31:15 +02:00
proddy
59273027fb decreased wait time for log 2024-09-11 22:30:52 +02:00
proddy
57709d7dbb added auto scroll 2024-09-11 22:30:38 +02:00
proddy
1e3285b299 applied bugfix 2024-09-11 22:30:26 +02:00
proddy
76673d6694 updated 2024-09-11 22:30:12 +02:00
mattreim
b9924587d7 Update German translation 2024-09-11 22:13:53 +02:00
proddy
44ef7dd0bc fix all typos 2024-09-11 20:23:58 +02:00
proddy
426555bac6 remove comment 2024-09-11 15:28:05 +02:00
Proddy
694f1f01d9 Merge pull request #1991 from proddy/dev
some minor fixes
2024-09-11 15:04:15 +02:00
Proddy
9ba9ffcdf9 Merge branch 'dev' into dev 2024-09-11 15:03:03 +02:00
proddy
e3157907de change download buttons 2024-09-11 14:59:56 +02:00
proddy
55efaa2c9e spellcheck 2024-09-11 14:59:42 +02:00
proddy
5fc82c72f4 don't restart when upload error happens 2024-09-11 14:59:27 +02:00
proddy
5f1877f995 align with 3.7.0-dev.35 changes 2024-09-11 14:59:03 +02:00
Proddy
837bdf37e7 Merge pull request #2000 from mattreim/dev
Add Slovak(SoftVienka) & German translation to locale_translations/i18n
2024-09-11 14:51:29 +02:00
proddy
9368f78401 larger tx mode box size 2024-09-11 13:25:19 +02:00
proddy
3bb936784b update doc and pictures 2024-09-11 13:21:56 +02:00
proddy
a0d90fd78e package update 2024-09-11 13:21:47 +02:00
mattreim
74dff21706 Add Slovak(SoftVienka) & German translation to locale_translations/i18n 2024-09-11 12:18:19 +02:00
proddy
806e40cb31 remove nvs from board_profile 2024-09-11 09:04:45 +02:00
proddy
88c8155b05 tidy up 2024-09-11 08:50:33 +02:00
Proddy
532e36a9b0 Merge branch 'emsesp:dev' into dev 2024-09-10 15:27:16 +02:00
Proddy
fc5b0c762f Merge pull request #1998 from mattreim/dev
Update locale_translations.h
2024-09-10 14:02:59 +02:00
mattreim
ab943a4bbd Update locale_translations.h 2024-09-10 13:30:28 +02:00
proddy
cfb19328f0 fail back to S32 2024-09-10 11:25:11 +02:00
proddy
04dc0401b5 translated Restarting 2024-09-10 10:53:43 +02:00
proddy
cc14a87357 mention show log uses the log level defined in the web 2024-09-10 10:42:30 +02:00
proddy
b0114e9d68 formatting 2024-09-10 10:42:13 +02:00
proddy
49c0bb4f17 formatting 2024-09-10 10:24:37 +02:00
proddy
6c349d0304 formatting 2024-09-10 10:20:13 +02:00
proddy
79e2d6b4a5 formatting 2024-09-10 10:19:56 +02:00
proddy
ab40a21805 show log 2024-09-10 10:19:35 +02:00
proddy
c5e2402770 getter for ipv6 enabled 2024-09-10 10:19:04 +02:00
proddy
ef73994b08 show boot/running partition 2024-09-10 10:18:53 +02:00
proddy
f6c6359121 remove board profiles, handled in code now 2024-09-10 10:18:29 +02:00
proddy
39c7435c21 prevent ipv6 calling twice with Eth 2024-09-10 10:18:09 +02:00
Proddy
bb2ffca295 Merge branch 'emsesp:dev' into dev 2024-09-10 08:03:56 +02:00
Proddy
e1cbe557d2 Merge pull request #1995 from mattreim/dev 2024-09-09 22:18:42 +02:00
mattreim
95dfec8bf9 Update locale_translations.h 2024-09-09 21:56:50 +02:00
proddy
92904e5861 text change 2024-09-09 21:32:45 +02:00
Proddy
716d249719 Merge branch 'emsesp:dev' into dev 2024-09-09 21:23:54 +02:00
Proddy
a7c7fc31b5 Merge pull request #1994 from mattreim/dev
Update locale_translations.h
2024-09-09 21:23:32 +02:00
proddy
690a4c74c7 package update 2024-09-09 21:02:00 +02:00
proddy
bf5bcd6fd3 default to S32/S3 if ethernet not found and EMSESP_DEFAULT_BOARD_PROFILE not set (edge case) 2024-09-09 21:01:38 +02:00
mattreim
9daae873ea Update locale_translations.h 2024-09-09 20:59:05 +02:00
proddy
9ffc8665f4 update with log show command 2024-09-09 17:47:17 +02:00
proddy
b2b65365f2 react-router update 2024-09-09 17:46:22 +02:00
proddy
54d8c5ad8f tidy up TODOs 2024-09-09 17:46:13 +02:00
proddy
5fae9872e6 new command 'log show' to dump out last log messages. useful for serial when you've missed the startup messages 2024-09-09 17:29:55 +02:00
proddy
8617658169 set CORE_DEBUG_LEVEL to 0 to hide annoying littlefs warnings. Can be overridden by pio_local.ini 2024-09-09 17:12:59 +02:00
proddy
fc9372b2ec string casting 2024-09-09 16:41:23 +02:00
proddy
f51781ae77 console starts with DEBUG, less warning messages with standalone 2024-09-09 16:39:46 +02:00
proddy
2c8c8e3365 suppress log warnings when in standalone 2024-09-09 16:39:05 +02:00
proddy
69171f03e9 fix typo 2024-09-09 16:38:39 +02:00
proddy
b7703c46e6 start serial console on command, fix exit 2024-09-09 14:37:29 +02:00
proddy
ee87ee8c34 force web buffer to 25 during update for boards with no psram 2024-09-09 14:31:24 +02:00
proddy
2558513809 formatting 2024-09-09 14:30:55 +02:00
proddy
1e3c115b58 rename Reloading 2024-09-09 13:48:36 +02:00
proddy
6a43f20767 package update 2024-09-09 13:48:28 +02:00
proddy
f9295d9e22 text changes in updater 2024-09-09 11:37:20 +02:00
proddy
783c226d2a formatting 2024-09-09 11:37:02 +02:00
proddy
fbbf93bd28 re-order cflags 2024-09-09 09:33:43 +02:00
proddy
e71965c7d5 fix typos 2024-09-09 09:33:33 +02:00
proddy
577e429edb updated CSV files 2024-09-09 09:02:17 +02:00
proddy
df76340b6f make compile MacOSX 2024-09-09 08:55:17 +02:00
proddy
be6e189948 remove date/time from log, its already in the log 2024-09-09 08:41:57 +02:00
proddy
b57bf51afb change log message (not 'recognized new...') 2024-09-09 08:41:36 +02:00
proddy
fa614dcaca typo 2024-09-09 08:41:10 +02:00
proddy
99d97b2c7b updated auto-gen files 2024-09-09 08:40:51 +02:00
Proddy
5b8d0b9dda Merge branch 'emsesp:dev' into dev 2024-09-09 06:44:55 +02:00
Proddy
03a607fe83 Merge pull request #1992 from mattreim/dev
Update locale_translations.h
2024-09-09 06:44:37 +02:00
mattreim
e96a760fe6 Update locale_translations.h 2024-09-08 23:13:32 +02:00
proddy
30fb4fbad7 limit WebUI log to 25 if no psram 2024-09-08 20:05:24 +02:00
proddy
48fa6f149b add psram 2024-09-08 19:55:53 +02:00
proddy
0db3a9c632 add psram 2024-09-08 19:55:43 +02:00
proddy
859b218609 formatting 2024-09-08 19:55:34 +02:00
proddy
20a1a6f952 better scripting 2024-09-08 19:55:23 +02:00
proddy
ae98027ced only override board profile for BBQKees boards 2024-09-08 16:01:44 +02:00
proddy
8d9e594f1c 3.7.0-dev.35 2024-09-08 15:47:24 +02:00
proddy
1cceda2c49 re-factor update() to use the NVS boot param, which precedes over any manually set board profile 2024-09-08 15:46:38 +02:00
proddy
4fc10a1f6a text formatting 2024-09-08 15:44:49 +02:00
proddy
29c5881cf0 fix error when checking for FS. re-order events for cleaner logging 2024-09-08 15:44:13 +02:00
proddy
195c889e17 exclude vscode settings 2024-09-08 15:42:04 +02:00
proddy
5f4dd924ca fix incorrect board profile on s_16M_P 2024-09-08 15:41:47 +02:00
proddy
c69d870925 add test for long log messages 2024-09-08 15:41:18 +02:00
proddy
b5f571f2cb formatting 2024-09-08 15:41:07 +02:00
proddy
4f29221c39 package update 2024-09-08 15:40:58 +02:00
proddy
38bb7a195f show log colors like it does in the console/terminal 2024-09-08 15:40:49 +02:00
proddy
c6879ca1d5 ethernet may not be connected, so check if it exists in GPIO check 2024-09-08 10:27:30 +02:00
proddy
98fd43f8f2 formatting, text change 2024-09-08 10:26:50 +02:00
proddy
2c60b13022 formatting 2024-09-08 10:26:37 +02:00
Proddy
aa29b70cf1 Merge pull request #1988 from proddy/dev
fix standalone building
2024-09-07 13:28:21 +02:00
proddy
5544dc3b52 fix standalone building 2024-09-07 13:27:58 +02:00
proddy
8f6e2926c2 package update 2024-09-07 13:27:49 +02:00
Proddy
383c3d026a Merge pull request #1986 from mattreim/dev
Update locale_translations.h
2024-09-07 13:20:35 +02:00
Proddy
56d799b00a Merge pull request #1987 from proddy/dev
add more info to system/info and show system cmd
2024-09-07 10:23:07 +02:00
proddy
03127e5ff8 add more info to system/info and show system cmd 2024-09-07 10:22:27 +02:00
proddy
1b650dd118 add link to pio registry files so I remember where they are 2024-09-07 10:22:05 +02:00
proddy
b92973cec2 remove comment 2024-09-07 10:21:40 +02:00
proddy
2957cb2a81 restart after upload 2024-09-07 10:21:30 +02:00
proddy
2aee961f4d pacakge update 2024-09-07 10:21:17 +02:00
mattreim
649c3f0095 Update locale_translations.h 2024-09-06 23:30:37 +02:00
Proddy
e02fe4df32 Merge branch 'emsesp:dev' into dev 2024-09-06 18:47:46 +02:00
Proddy
32dec56703 Merge pull request #1985 from MichaelDvP/dev
add back command for remoteseltemp #1982
2024-09-06 18:47:11 +02:00
MichaelDvP
d31eb3d606 add back command for remoteseltemp #1982 2024-09-06 16:52:12 +02:00
proddy
8c29ccc153 show partition in `show system' 2024-09-06 16:32:18 +02:00
Proddy
d7a4f4af00 Merge pull request #1981 from proddy/dev
"show system" command shows NVS device details, so can be checked aft…
2024-09-06 00:45:19 +02:00
proddy
69b62e2be9 "show system" command shows NVS device details, so can be checked after flashing without going to the web 2024-09-06 00:44:18 +02:00
Proddy
581e027307 Merge pull request #1977 from mattreim/dev
Update English and German translation
2024-09-05 23:37:32 +02:00
Proddy
2450bf966b Merge pull request #1980 from proddy/dev
turn off wifi nosleep
2024-09-05 23:37:02 +02:00
Proddy
d3fe0422d0 Merge branch 'emsesp:dev' into dev 2024-09-05 23:36:34 +02:00
proddy
795fbabe02 3.7.0-dev.34 2024-09-05 23:36:06 +02:00
proddy
07f5a8090e fix compile error 2024-09-05 23:35:12 +02:00
proddy
42572977d4 turn off wifi nosleep 2024-09-05 23:35:04 +02:00
proddy
316c1d0912 package update 2024-09-05 23:34:51 +02:00
mattreim
3a032e4bb3 Update English and German translation 2024-09-05 15:20:45 +02:00
Proddy
2885629d8d Merge pull request #1975 from mattreim/dev
Update German translation
2024-09-04 21:51:20 +02:00
mattreim
da383864fd Update German translation 2024-09-04 21:38:27 +02:00
Proddy
de567649ab Update test_release.yml 2024-09-04 11:36:34 +02:00
Proddy
c9349e4167 Update tagged_release.yml 2024-09-04 11:35:29 +02:00
Proddy
16bfaedd90 Update pre_release.yml 2024-09-04 11:23:15 +02:00
Proddy
737c07d3d8 uses: "emsesp/GH-Automatic-Releases@<VERSION>" 2024-09-04 10:37:04 +02:00
Proddy
5d541b4c84 Merge pull request #1974 from proddy/dev
fix error with system filenames
2024-09-04 09:56:25 +02:00
proddy
6dfb83d90f update packages 2024-09-04 09:54:33 +02:00
proddy
21f53252fd fix name of system file 2024-09-04 09:54:23 +02:00
Proddy
e92b43e62b Merge branch 'emsesp:dev' into dev 2024-09-03 08:10:06 +02:00
Proddy
17489a63ff Merge pull request #1973 from mattreim/dev
Update German translation
2024-09-03 07:51:12 +02:00
mattreim
84dc41ff01 Update German translation 2024-09-02 22:02:57 +02:00
proddy
77c95d6300 don't show download link if on latest version 2024-09-02 11:37:00 +02:00
Proddy
082c7858dc Merge pull request #1972 from proddy/dev
change (c) header
2024-09-01 20:41:49 +02:00
proddy
c951877172 change (c) header 2024-09-01 20:41:27 +02:00
Proddy
71743d4dce Merge pull request #1969 from proddy/dev
autodetect, download and install firmware upgrades
2024-09-01 20:38:13 +02:00
proddy
6d020fa4d1 fix dev vs stable for 4MB downloads 2024-09-01 20:37:03 +02:00
proddy
b3a89ee8c9 add S32 2024-09-01 20:14:51 +02:00
proddy
4807e9749f package update 2024-09-01 20:14:20 +02:00
proddy
cbd38dbf15 fix upload_status 2024-09-01 14:17:37 +02:00
proddy
e1f5dbae81 don't install via URL if Tasmota build on 4MB without PSRAM, as SSL is needed 2024-09-01 14:13:30 +02:00
proddy
6504ac8cb7 make psram boolean 2024-09-01 14:12:54 +02:00
proddy
94f521e460 experimenting with loops 2024-09-01 13:45:01 +02:00
proddy
722e7f38fc rename upload status 2024-09-01 13:44:48 +02:00
proddy
dfdb6bca47 upload url test for 4MB Tasmota 2024-09-01 13:44:22 +02:00
proddy
0e5f0215f3 text change 2024-09-01 13:44:10 +02:00
proddy
53db93fe04 updated 2024-09-01 13:44:01 +02:00
proddy
1040e4fb8c add validation for # bytes in RAW 2024-09-01 12:29:38 +02:00
proddy
94d1aa56b1 use numberValue() to prevent web errors with integers 2024-09-01 12:29:23 +02:00
proddy
1d45a08668 support optional numbers 2024-09-01 12:28:45 +02:00
proddy
89854a45b5 add restart translations 2024-09-01 11:43:40 +02:00
proddy
4ff7e95b19 add missing board profiles 2024-09-01 11:08:50 +02:00
proddy
a257733b3d pio cleanup 2024-09-01 11:08:05 +02:00
proddy
689a326c89 fixes to restart 2024-09-01 11:07:52 +02:00
proddy
ccf4362bfc updated 2024-09-01 09:30:10 +02:00
proddy
8d6f0cc44c fix test 2024-09-01 09:29:34 +02:00
proddy
3699c76985 text formatting 2024-09-01 09:00:52 +02:00
proddy
3607d9f2ad auto-formatting 2024-08-31 16:25:49 +02:00
Proddy
c78777835c Merge branch 'emsesp:dev' into dev 2024-08-31 16:20:10 +02:00
Proddy
66fe96454f Merge pull request #1970 from mheyse/modbus-write-cmd
Modbus: Handle writes to CMD entities, extend tests
2024-08-31 16:19:56 +02:00
proddy
f68c61d229 remove unused import 2024-08-31 16:15:52 +02:00
proddy
a36e26b767 add note about translations 2024-08-31 16:15:41 +02:00
proddy
d9e4c58543 updated translations for restart 2024-08-31 16:13:47 +02:00
proddy
e023e74057 callRestart to doRestart 2024-08-31 16:13:31 +02:00
proddy
b787b975a2 add standlone connect (was in emsesp main class) 2024-08-31 16:13:17 +02:00
proddy
b3951e92a4 grid formatting 2024-08-31 16:12:57 +02:00
proddy
931827c526 refactored restart and format services to be non-blocking 2024-08-31 16:12:30 +02:00
proddy
382c46622d comment 2024-08-31 16:10:26 +02:00
proddy
e965ffc210 comment 2024-08-31 16:10:16 +02:00
proddy
9c83124424 debug tests for api's 2024-08-31 16:09:48 +02:00
proddy
0753fee385 replace restart/format endpoints with system calls 2024-08-31 16:09:22 +02:00
proddy
55a55cbfca add status to be used when uploading/restarting etc 2024-08-31 16:07:49 +02:00
proddy
71d90d6416 CANCEL button always in dark blue (secondary) color 2024-08-30 14:59:12 +02:00
proddy
35cb567b62 migrate deprecated Grid v5 to v6 (Grid2) 2024-08-30 14:55:24 +02:00
proddy
eff3e3f404 package update 2024-08-30 14:55:10 +02:00
proddy
7c3c5917db fixes to install 2024-08-30 14:54:30 +02:00
proddy
c0305ddf38 German translations 2024-08-30 11:21:35 +02:00
proddy
6cacc1473d add back immediate for SSE calls (Alova bug) 2024-08-30 11:21:26 +02:00
proddy
70642de2a6 remove Divider 2024-08-30 11:21:11 +02:00
proddy
5635268fd1 fix autoupdate in dialog 2024-08-30 11:21:03 +02:00
proddy
3f2d5bea67 formatting 2024-08-30 11:10:50 +02:00
proddy
4a6e85106a change colors of icon/text for user profile 2024-08-30 11:10:39 +02:00
proddy
ad386f7c8d only show blue icon for BBQKees boards 2024-08-30 11:10:22 +02:00
proddy
67c3a652b7 move has_partition and has_loader to hardware status 2024-08-30 11:10:06 +02:00
proddy
5d6830c7c6 package update 2024-08-30 11:09:48 +02:00
proddy
00bb31738e comments changed 2024-08-30 11:09:39 +02:00
proddy
5bafe6587c move has_partition and has_loader to hardware status 2024-08-30 11:09:31 +02:00
proddy
6d1e08d244 text changes 2024-08-30 11:09:14 +02:00
proddy
117b55cc16 tidy up restart 2024-08-30 11:09:05 +02:00
proddy
d2f6f8203f remove deprecated ListItemSecondaryAction 2024-08-30 11:08:00 +02:00
proddy
79ae51fbe5 HELP_OF to HELP 2024-08-30 11:07:44 +02:00
proddy
666f5626ea smaller spinner 2024-08-30 11:06:54 +02:00
proddy
21b75ef392 remove timeout 2024-08-30 11:06:44 +02:00
proddy
2ce728d03f comment change 2024-08-30 11:06:35 +02:00
mheyse
ffcd5b7100 Modbus: Handle writes to CMD entities, extend tests 2024-08-30 08:46:55 +02:00
proddy
41ec9162fd add partition text 2024-08-29 14:49:21 +02:00
proddy
908284177f remove deprecated component 2024-08-29 14:49:09 +02:00
proddy
19922ca9fb move the Get* endpoints to their right service classes 2024-08-29 13:53:27 +02:00
proddy
e2aabb1418 don't show warning when uploading using script 2024-08-29 13:52:58 +02:00
proddy
eafd659870 move shunting yard to main code folder 2024-08-29 13:52:36 +02:00
proddy
7aafe1fbbc improve comment 2024-08-29 13:52:20 +02:00
proddy
4188588ea0 remove uploads folder/directory 2024-08-29 13:52:12 +02:00
proddy
cdb8920db6 package update 2024-08-29 13:51:58 +02:00
proddy
1bf4e85fcb remove unneeded immediate param 2024-08-29 13:51:35 +02:00
proddy
fe50c9f6d0 autodetect, download and install firmware upgrades 2024-08-29 13:51:17 +02:00
Proddy
f1e6d5a331 Merge pull request #1967 from MichaelDvP/dev
fix close shell in native build #1966
2024-08-29 08:36:57 +02:00
MichaelDvP
58531815d0 fix close shell in native build #1966 2024-08-29 07:34:26 +02:00
MichaelDvP
0c4d0d0afb Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-08-27 16:09:40 +02:00
Proddy
3a5194cb6c Merge pull request #1956 from mattreim/dev
Fix for official release button [Translation]
2024-08-19 16:01:44 +02:00
mattreim
1cd547049e Fix for official release button
Sorry, I overlooked it.
2024-08-19 13:44:53 +02:00
Proddy
fb5c272899 Merge pull request #1954 from mattreim/dev
Add install button translation
2024-08-19 08:38:52 +02:00
mattreim
8b68f03dd9 Add install button translation 2024-08-18 19:14:07 +02:00
Proddy
f2d2e07325 Merge pull request #1952 from MichaelDvP/dev
fix read RC300WWtemp, #1950
2024-08-18 18:08:31 +02:00
MichaelDvP
4e016baca8 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-08-18 17:58:57 +02:00
Proddy
7f247e58e9 Merge pull request #1951 from proddy/dev
upload and install firmware automatically
2024-08-18 17:46:31 +02:00
MichaelDvP
3c16e95cee fix read RC300WWtemp, #1950 2024-08-18 16:47:14 +02:00
proddy
ff9f82aa6c immediately refresh sensors after closing dialog - making it more responsive. there was a lag when removing. 2024-08-18 16:45:45 +02:00
proddy
87ee50708b prevent annoying screen jump when rendering 2024-08-18 16:39:59 +02:00
proddy
405e23561f remove space 2024-08-18 16:39:43 +02:00
proddy
a7a93eb4f5 revert back hardcoded GH calls 2024-08-18 16:18:52 +02:00
proddy
119dcaa7fc make it work from web (thanks michael) 2024-08-18 16:17:03 +02:00
proddy
92a8a268a7 update firmware automatically - #1920 2024-08-18 13:18:07 +02:00
proddy
d9d854e456 formatting 2024-08-18 13:17:23 +02:00
proddy
47dc7346dc package update 2024-08-18 13:17:13 +02:00
proddy
cd5fb061aa added comments 2024-08-18 13:17:01 +02:00
Proddy
bfc712f365 Merge pull request #1949 from mattreim/dev
Add help translation
2024-08-17 17:01:45 +02:00
mattreim
67a21b25a8 Add help translation 2024-08-17 13:32:53 +02:00
Proddy
c7d721bb10 Merge pull request #1948 from proddy/dev
small improvements to upload
2024-08-17 12:40:30 +02:00
Proddy
5de696d7be Merge branch 'emsesp:dev' into dev 2024-08-17 12:39:58 +02:00
proddy
44477d8fcd revert github spam 2024-08-17 12:38:19 +02:00
proddy
f576ee4fe6 improvements https://github.com/emsesp/EMS-ESP32/pull/1931#issuecomment-2294803388 2024-08-17 12:37:11 +02:00
proddy
cf949a9c86 formatting 2024-08-17 12:36:22 +02:00
proddy
22ed193609 unused css 2024-08-17 12:36:09 +02:00
proddy
b2bcc67923 typo 2024-08-17 12:36:01 +02:00
proddy
7a1a5aad7e package update 2024-08-17 12:35:53 +02:00
Proddy
8eb2de5e76 Merge pull request #1941 from proddy/dev
correct firmware naming #1933
2024-08-16 20:03:09 +02:00
Proddy
32053ad0fd Merge pull request #1946 from MichaelDvP/dev
typo
2024-08-16 17:54:01 +02:00
MichaelDvP
6c6461dd9a typo 2024-08-16 17:42:33 +02:00
Proddy
8975c5fba2 Merge branch 'dev' into dev 2024-08-16 17:06:00 +02:00
proddy
1c86cc6799 remove default board profile from ci_s_4M 2024-08-16 16:52:37 +02:00
Proddy
dc7042c8fa Merge pull request #1945 from MichaelDvP/dev
add energy and meter for cooling #1940
2024-08-16 16:49:25 +02:00
MichaelDvP
388245ece9 add energy and meter for cooling #1940 2024-08-16 16:44:36 +02:00
proddy
bc8a840695 fix sonar compile 2024-08-16 16:14:07 +02:00
proddy
1d287b6e20 auto-formatting 2024-08-16 16:13:58 +02:00
Proddy
140aba52d1 Merge pull request #1939 from paludi/patch-1
add hint for manual workaround to preserve nrg values to CHANGELOG_LATEST.md
2024-08-16 15:45:03 +02:00
Proddy
d06465132c Merge pull request #1943 from mattreim/dev
Add German translation
2024-08-16 15:44:31 +02:00
Proddy
0a1743b99b Merge branch 'emsesp:dev' into dev 2024-08-16 15:33:49 +02:00
Proddy
a8895290bc Merge pull request #1942 from MichaelDvP/dev
some small fixes
2024-08-16 15:33:33 +02:00
mattreim
668334d139 Add German translation 2024-08-16 15:32:40 +02:00
proddy
aa8009019d ci_s_16M uses Tasmota 2024-08-16 15:29:21 +02:00
MichaelDvP
00e2808afe use fixed names for energies in nvs #1938 2024-08-16 14:58:58 +02:00
MichaelDvP
68ec48fa80 start scheduler conditions after 1 min 2024-08-16 14:57:29 +02:00
Proddy
2fad0df647 Merge branch 'emsesp:dev' into dev 2024-08-16 14:49:49 +02:00
proddy
bbbea027cb correct firmware naming #1933 2024-08-16 14:49:05 +02:00
MichaelDvP
ed0fcefc27 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-08-16 14:45:21 +02:00
Proddy
1672cc84ef Merge pull request #1931 from proddy/dev
Web changes #1920
2024-08-16 13:49:32 +02:00
proddy
5404537da8 move restarting to parent component - #1920 2024-08-16 13:48:28 +02:00
proddy
d3a7ab8fc1 formatting 2024-08-16 13:48:05 +02:00
proddy
1f8c966022 package update 2024-08-16 13:47:38 +02:00
proddy
0ff1de8baa special functions naming - #1920 2024-08-16 13:47:29 +02:00
proddy
7e0d568a5a code formatting 2024-08-16 13:47:08 +02:00
proddy
a3f69b64df fix autorefresh in open dialog - #1920 2024-08-16 13:46:57 +02:00
paludi
10dd117d0f Update CHANGELOG_LATEST.md
added hint to manually preserve value of dhw energy (nrgww)
2024-08-16 10:48:04 +02:00
proddy
1a6bfebf9b check file extension on drag/drop 2024-08-15 21:56:49 +02:00
proddy
500a398dd1 re-arrange application settings page - Updates to webUI #1920 2024-08-15 21:15:51 +02:00
proddy
d4d296a97e translations for drag&drop 2024-08-15 16:48:24 +02:00
proddy
07507eaeb6 show spinner when waiting for EMS to connect 2024-08-15 16:48:12 +02:00
proddy
b1d5d07cab reorder upload and download, fix minor issues 2024-08-15 16:23:21 +02:00
proddy
e0765f1c5b formatting 2024-08-15 12:27:50 +02:00
proddy
817b2d1ad7 add back drag & drop to upload 2024-08-15 12:14:14 +02:00
proddy
4e640a0abe updates to upload, move mock eventsource server into middleware 2024-08-15 09:59:08 +02:00
MichaelDvP
20b833b4ee scheduler/mqtt running assync with psram, sync without psram 2024-08-15 07:56:24 +02:00
proddy
5a058746bb update the upload 2024-08-14 18:53:52 +02:00
MichaelDvP
7dc4dc67f6 don't show factory partiton button if we are in factory 2024-08-13 08:03:22 +02:00
MichaelDvP
9a46db07d1 fix hex buffer length 2024-08-12 12:35:23 +02:00
proddy
d5fec4aec8 psram check #1933 2024-08-12 09:29:56 +02:00
MichaelDvP
b5d964c074 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-08-12 09:26:46 +02:00
MichaelDvP
9181b70394 checks for long raw custom entities #1934 2024-08-12 09:26:37 +02:00
MichaelDvP
8a409e8e9c restart dialog 2024-08-12 09:23:46 +02:00
proddy
f5968412a0 useAutoRequest tidy up 2024-08-11 10:40:11 +02:00
proddy
962d007d91 replace Refresh with Alova useAutoRequest() 2024-08-10 20:54:57 +02:00
Proddy
cde8ba0e9e Merge branch 'dev' into dev 2024-08-10 15:07:44 +02:00
proddy
5b60ec1836 move to emsesp.org 2024-08-10 15:06:16 +02:00
proddy
a842a3ee43 add back package manager 2024-08-10 13:41:06 +02:00
proddy
3c04bfadc9 remove cache 2024-08-10 13:19:17 +02:00
proddy
fd5e254a84 change package manager 2024-08-10 13:19:08 +02:00
proddy
53d0afb774 3.7.0-dev.31 2024-08-10 13:18:56 +02:00
proddy
a718f8ed0d Alova 3 now working 2024-08-10 11:39:31 +02:00
proddy
bb98042957 default Alova v2 2024-08-10 10:22:14 +02:00
proddy
efa9718081 fix return for app settings 2024-08-10 10:22:01 +02:00
proddy
681cdfb01e disable changing the board profile if its a fixed BBQKees one 2024-08-09 14:43:13 +02:00
proddy
251b0ea287 api refactoring 2024-08-09 14:35:33 +02:00
proddy
93ed502e57 fix appending 16M to S3 downloads 2024-08-09 10:45:48 +02:00
proddy
3d1fba1c30 fixes WiFi scan not working when EMS-ESP is an Access Point 2024-08-09 10:20:41 +02:00
proddy
3e7ce2025a package update 2024-08-09 09:31:48 +02:00
proddy
08f1915b4c prevent forcing caps when on mobile (ios) 2024-08-09 09:31:36 +02:00
proddy
5355c65da8 FC removal 2024-08-08 12:57:04 +02:00
proddy
3481a879c2 alova 3 2024-08-08 12:39:48 +02:00
Proddy
dc53ff42f6 Merge branch 'emsesp:dev' into dev 2024-08-07 09:30:51 +02:00
Proddy
f10d8757b8 Merge pull request #1928 from MichaelDvP/dev
do not close local shell #1926
2024-08-07 09:30:39 +02:00
Proddy
d807f2fa21 Merge branch 'emsesp:dev' into dev 2024-08-07 09:30:05 +02:00
proddy
46ab42531d native build updates 2024-08-07 09:16:58 +02:00
MichaelDvP
70b16149d0 read custom entity raw from fetched telegrams 2024-08-07 07:42:30 +02:00
MichaelDvP
0105338e29 do not close local shell #1926 2024-08-06 14:17:53 +02:00
proddy
7b6fe53e74 add console tests to Unity 2024-08-06 10:33:22 +02:00
proddy
3045144cc3 package update 2024-08-06 10:33:12 +02:00
Proddy
0e8655862e Merge pull request #1927 from mattreim/dev 2024-08-05 14:23:15 +02:00
mattreim
e8839b22b8 Add scheduler dialog to i18n 2024-08-05 13:53:30 +02:00
Proddy
968cd7de5f Merge branch 'emsesp:dev' into dev 2024-08-05 10:51:39 +02:00
proddy
66ed8a1e17 fixes #1926 - serial shell not working 2024-08-05 10:50:51 +02:00
Proddy
8e52af2338 Merge branch 'emsesp:dev' into dev 2024-08-05 07:00:45 +02:00
Proddy
38ae744a10 Merge pull request #1925 from mattreim/dev
Fix modules translation
2024-08-05 06:00:53 +02:00
mattreim
4ade5094f3 Fix modules translation 2024-08-05 01:57:24 +02:00
Proddy
a9bbbc025f Merge branch 'emsesp:dev' into dev 2024-08-04 22:03:59 +02:00
Proddy
aa807c3b78 Merge pull request #1924 from mattreim/dev
Add modules helper to i18n
2024-08-04 21:45:15 +02:00
mattreim
48dc9738b1 Add modules helper to i18n 2024-08-04 21:41:00 +02:00
Proddy
574f685d93 Merge pull request #1923 from mattreim/dev
Added more German translation and google translation to boiler pump characteristic
2024-08-04 20:17:18 +02:00
mattreim
01b63482bd Add google translation to boiler pump characteristic 2024-08-04 18:58:36 +02:00
mattreim
09d393d002 Added more German translation 2024-08-04 17:47:17 +02:00
Proddy
1f2f77b833 Merge pull request #1921 from MichaelDvP/dev
switchProgMode offset 13 to 19, increase length of raw custom entities
2024-08-04 16:15:34 +02:00
MichaelDvP
8d70dc7a02 custom entity RAW allow length up to 256 2024-08-04 16:07:57 +02:00
MichaelDvP
95c995f87a switchProgMode offset 13 to 19 2024-08-04 15:52:31 +02:00
Proddy
1a11aa50ac Merge pull request #1919 from MichaelDvP/dev
fix switchProgMode #1903
2024-08-04 14:58:33 +02:00
MichaelDvP
ebb327edf6 fix switchProgMode #1903 2024-08-04 10:44:29 +02:00
proddy
7751baf8bf upgrade alova to v3 2024-08-03 15:35:54 +02:00
Proddy
9a23d4e2b3 Merge pull request #1914 from proddy/dev
various changes, work in progress
2024-08-03 13:25:36 +02:00
Proddy
71183d81e5 Merge branch 'emsesp:dev' into dev 2024-08-03 13:24:54 +02:00
Proddy
276a19648e Merge pull request #1917 from MichaelDvP/dev
fix #1910 and small changes
2024-08-03 13:24:40 +02:00
proddy
5050d11555 add Unity unit tests 2024-08-03 13:22:24 +02:00
proddy
8f91394c75 add Michaels fix for circuits 2024-08-02 14:28:39 +02:00
proddy
2c21658de7 don't compile with DEBUG for tests 2024-08-02 14:24:23 +02:00
MichaelDvP
732949fdb8 fix api no dhw in boiler 2024-08-02 14:16:37 +02:00
proddy
2ec52cccf0 add test for thermostat multi-circuit 2024-08-02 14:16:14 +02:00
proddy
ce1c5671b4 add comments 2024-08-02 14:15:55 +02:00
MichaelDvP
ab587fa1b7 move 6x identical code to one function add_ha_bool 2024-08-02 12:44:47 +02:00
MichaelDvP
aeafb5f566 remove useless boiler setBurnPow and wrong wwsetpumppow #1910 2024-08-02 12:37:51 +02:00
proddy
60c1da327b compile all platforms 2024-08-02 12:34:07 +02:00
proddy
3159561cfb compile native on OSX 2024-08-02 12:20:09 +02:00
MichaelDvP
21c23e1fd8 remove useless http check 2024-08-02 12:04:17 +02:00
proddy
de582f2f61 added coverage to unit tests 2024-08-02 10:17:26 +02:00
proddy
a22ee0274b check BBQKees as mfg 2024-08-02 09:59:59 +02:00
proddy
69aa7275d8 surpress output when running Unity tests 2024-08-02 09:59:48 +02:00
proddy
57416bc817 remove __linux__ 2024-08-02 09:59:32 +02:00
proddy
7e8a4f72ef add comment 2024-08-02 09:59:22 +02:00
proddy
085314fba4 added one more test to test the tests while testing 2024-08-02 09:59:13 +02:00
Proddy
cd79e73693 Merge branch 'dev' into dev 2024-08-02 09:16:31 +02:00
Proddy
e109e383c0 Merge pull request #1913 from MichaelDvP/dev
fix sonar complains
2024-08-02 09:13:30 +02:00
MichaelDvP
cd992ff457 fix sonar complains 2024-08-02 08:42:32 +02:00
Proddy
d0b01812e6 Merge pull request #1912 from MichaelDvP/dev
scheduler: change to std::string
2024-08-02 08:30:30 +02:00
MichaelDvP
70e5b19223 scheduler: change to std::string 2024-08-02 08:20:10 +02:00
MichaelDvP
fb04bdf54c platform 6.8.1 2024-08-02 08:08:11 +02:00
MichaelDvP
f417cb991d all devices api default to /values 2024-08-02 08:07:55 +02:00
proddy
f47dd7b629 Merge branch 'dev' of https://github.com/proddy/EMS-ESP32 into dev 2024-08-01 22:19:38 +02:00
proddy
11d0335815 text changes and comments 2024-08-01 22:14:19 +02:00
proddy
b38ec2f25e support Unity testing 2024-08-01 22:13:52 +02:00
proddy
4ec5739b67 test on Windows 2024-08-01 22:12:33 +02:00
proddy
dac033e962 remove PrettyAsyncJsonResponse 2024-08-01 22:11:12 +02:00
Proddy
279d40636c Merge pull request #1907 from MichaelDvP/dev
refactor common commands
2024-08-01 19:25:54 +02:00
MichaelDvP
900b2bf340 scheduler, small fixes, allow commands in json get url 2024-08-01 18:52:26 +02:00
MichaelDvP
1b69c3ef4e platform 6.8.0 2024-08-01 18:42:21 +02:00
MichaelDvP
63ba0df07a update packages 2024-08-01 18:42:03 +02:00
MichaelDvP
49b7f99e81 allow call system allvalues [values|info|entities], increase TCP stack 2024-07-31 14:15:46 +02:00
MichaelDvP
a33733484c always default to values (incl. allvalues), fix typo, 2024-07-31 10:41:15 +02:00
MichaelDvP
95f0478fa7 add switchProgMode #1903 2024-07-30 15:18:01 +02:00
MichaelDvP
80aa1e65b7 refactor common commands #1897 2024-07-30 15:07:45 +02:00
MichaelDvP
d844e67239 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-07-29 07:38:19 +02:00
MichaelDvP
ee193c6366 read states of VC0, VW1, #1898 2024-07-29 07:37:57 +02:00
Proddy
ab06c53720 Merge pull request #1901 from proddy/dev
updates to scheduler web
2024-07-28 19:50:29 +02:00
proddy
a14d3b98e1 must have one button type selected 2024-07-28 11:02:51 +02:00
proddy
0fbba50b2f updates to scheduler web 2024-07-28 10:56:33 +02:00
Proddy
4b136fb7ee Merge pull request #1900 from proddy/dev
updates to scheduler web ui for #1893
2024-07-28 09:27:05 +02:00
proddy
f4781b91c2 fix bootloop with missing version 2024-07-28 09:26:02 +02:00
proddy
0edb5c0fd9 updates to scheduler for immediate commands #1893 2024-07-27 15:04:22 +02:00
proddy
008e2f0c7a package update 2024-07-27 15:03:37 +02:00
Proddy
0a7f3ae930 Merge pull request #1899 from MichaelDvP/dev
scheduler single and fixes
2024-07-26 21:47:39 +02:00
MichaelDvP
7703ca15dc Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-07-26 18:30:14 +02:00
MichaelDvP
a83bca995b typo 2024-07-26 18:23:37 +02:00
MichaelDvP
5b67060674 scheduler single action on command 2024-07-26 18:00:41 +02:00
MichaelDvP
1183db88b7 command executed only for commands without value, fix hcx custom names 2024-07-26 17:59:49 +02:00
MichaelDvP
dd7cce508f add system/values 2024-07-26 17:58:16 +02:00
MichaelDvP
a06b9d7268 clear response_id on tx_error 2024-07-26 17:58:00 +02:00
Proddy
8f082dfd68 Merge pull request #1895 from proddy/dev
some renaming, more logs
2024-07-26 13:33:03 +02:00
proddy
65a5eeee69 debug text changes 2024-07-26 13:25:44 +02:00
proddy
7a3300b8f8 rename console "Command executed" 2024-07-26 13:25:30 +02:00
proddy
78a0fc2091 add optional object to be included in error message 2024-07-26 13:25:19 +02:00
proddy
51783ab7a1 tidy up how paths are checked for API and MQTT 2024-07-26 13:25:02 +02:00
proddy
b3532bd372 remove version from payload 2024-07-26 13:24:40 +02:00
proddy
c947889e53 add test for mqtt via API 2024-07-26 13:24:28 +02:00
proddy
e169f27ade include psram in hardware status 2024-07-26 13:24:18 +02:00
proddy
3f6157d7a4 fetch hardware status on load, so we have the psram setting 2024-07-26 13:23:47 +02:00
proddy
ae7737e47b rename HardwareStatus to hardwareStatus 2024-07-26 13:23:23 +02:00
MichaelDvP
8adb35e47a response "" for empty, fix value for some cases 2024-07-25 17:58:38 +02:00
MichaelDvP
9c80c92f06 fix response for empty 2024-07-25 17:27:32 +02:00
MichaelDvP
9ba026934b Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-07-25 15:49:52 +02:00
Proddy
593593d3bb Merge pull request #1891 from proddy/dev
camelCase, added free_caps to webUI, renamed EMSESPStatus endpoint to Hardware
2024-07-25 15:20:03 +02:00
MichaelDvP
eb120f5b90 response to system send telegram, redetect device, not only update from database 2024-07-25 14:48:32 +02:00
proddy
4446c839d3 updated text for system info 2024-07-25 14:39:04 +02:00
MichaelDvP
c6e6b62435 fix mqtt-ssl 2024-07-25 14:33:15 +02:00
MichaelDvP
babf112a7a analogsensor default name fix 2024-07-25 14:32:55 +02:00
MichaelDvP
51d323a41d validators, names when editing sensors 2024-07-25 14:32:34 +02:00
MichaelDvP
cfecb390f9 scheduler task priority, add comments 2024-07-25 14:31:24 +02:00
MichaelDvP
bdfd40d230 cleanup, typos, formatting 2024-07-25 14:30:43 +02:00
proddy
89e95daaee fix typo freMem 2024-07-25 13:50:16 +02:00
proddy
2970065a4a add free_caps 2024-07-25 13:18:10 +02:00
proddy
9b20edf862 change back default test 2024-07-25 12:52:32 +02:00
proddy
141fa3c953 #1860 camelCase system/info 2024-07-25 12:52:22 +02:00
proddy
1eb903d228 show free caps in web 2024-07-25 12:51:51 +02:00
proddy
26e290a4ef package update 2024-07-25 12:51:35 +02:00
proddy
645d6a514c rename HardwareStatus 2024-07-25 12:51:25 +02:00
MichaelDvP
a8307bddbe Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-07-24 20:38:23 +02:00
MichaelDvP
5da56bc853 read_next checks 2024-07-24 20:33:19 +02:00
Proddy
1b666a07dc Merge pull request #1888 from proddy/dev
fix system command
2024-07-24 17:59:59 +02:00
proddy
d92f17c774 remove TODO 2024-07-24 17:59:32 +02:00
proddy
05ff54e5e5 log_info for command calls 2024-07-24 17:57:51 +02:00
MichaelDvP
b2873fb901 fix terminal read command 2024-07-24 17:22:39 +02:00
proddy
fa54cb6a48 more minor changes to clean up messaging 2024-07-24 13:22:34 +02:00
proddy
0054a89c38 add test for system commands - to see what is logged 2024-07-24 09:33:39 +02:00
proddy
5c2aa63842 bump to 3.7.0-dev.27 2024-07-23 23:07:52 +02:00
proddy
0cca9b7723 removed comment 2024-07-23 23:07:12 +02:00
proddy
93e4e4ba0d increase rx/tx queue when running standalone 2024-07-23 23:07:04 +02:00
proddy
70344ce832 rename deviceID - removing space 2024-07-23 23:06:46 +02:00
proddy
c4f4abf1bd remove compression 2024-07-23 23:06:16 +02:00
proddy
0028dbfb4f package update 2024-07-23 22:32:24 +02:00
proddy
ee87b75cf5 prevent 'call system test' crashing 2024-07-23 22:30:40 +02:00
proddy
89e9b14347 add values_cmd 2024-07-23 22:29:41 +02:00
proddy
fa24a6878e add values as a possible command 2024-07-23 22:29:30 +02:00
proddy
ada7b1740b handle attribute_s like we did with the other device classes 2024-07-23 20:48:52 +02:00
proddy
0e40acb90f formatting for logging in debug/standalone 2024-07-23 20:48:30 +02:00
proddy
ae9aaf327c text change 2024-07-23 20:48:15 +02:00
proddy
76418dd39d show message if there is no error message set 2024-07-23 20:48:06 +02:00
proddy
e30c2b673e more tests 2024-07-23 20:47:49 +02:00
Proddy
bcd1b90bc5 Merge branch 'emsesp:dev' into dev 2024-07-23 18:58:07 +02:00
proddy
baf381461f fix system commands - #1886 2024-07-23 18:57:50 +02:00
proddy
48b5970d28 text changes 2024-07-23 18:55:26 +02:00
proddy
0d0d0aa111 show attribute in log message 2024-07-23 18:54:17 +02:00
proddy
49ca42d683 updated tesst with system commands like send 2024-07-23 18:53:03 +02:00
proddy
ad561129a2 remove unused imports 2024-07-23 18:52:46 +02:00
proddy
0b8034a3d6 package update 2024-07-23 18:52:36 +02:00
MichaelDvP
bc7d848b9b fix 1886 raw telegram 2024-07-23 17:19:56 +02:00
MichaelDvP
39199e1701 clear command output if cf found 2024-07-23 17:18:54 +02:00
Proddy
dfe85b9ba7 Merge pull request #1885 from MichaelDvP/dev
fix command prefix parsing #1884
2024-07-23 10:49:11 +02:00
MichaelDvP
ed234f9fee Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-07-23 10:41:26 +02:00
Proddy
e90f80d690 Merge pull request #1883 from proddy/dev
refactor web file structure and seperate settings from status
2024-07-23 10:28:49 +02:00
MichaelDvP
6a9e073f03 fix command prefix parsing #1884 2024-07-23 10:12:40 +02:00
proddy
914b84de7d include local copy of module library for native compiling without dependencies 2024-07-23 10:07:49 +02:00
proddy
e98264d1a6 go back to local copy of ArduinoJson as a single header 2024-07-23 10:07:25 +02:00
proddy
641b4e5bf0 remove scan 2024-07-22 17:08:11 +02:00
proddy
77e5c6bf2c add message to log menu option 2024-07-22 15:01:20 +02:00
Proddy
60368a32c3 Merge branch 'emsesp:dev' into dev 2024-07-22 14:46:44 +02:00
proddy
53e9a062e8 refactor web file structure and seperate settings from status 2024-07-22 14:46:22 +02:00
Proddy
9c20e93b3c Merge pull request #1881 from proddy/dev
add back button
2024-07-21 19:14:44 +02:00
proddy
d0976cd660 add back button 2024-07-21 19:13:54 +02:00
Proddy
152b7bdee2 Merge pull request #1880 from proddy/dev
fix downloading of 16M firmware bins
2024-07-21 14:45:11 +02:00
proddy
7ef99f3dc0 remove obsolete include 2024-07-21 14:44:10 +02:00
proddy
217d2703f5 fix downloading of 16M builds 2024-07-21 14:42:47 +02:00
proddy
452b3be953 add comment 2024-07-21 14:42:31 +02:00
proddy
8a291bea61 add comment 2024-07-21 14:42:22 +02:00
Proddy
169e8be5ee Merge pull request #1879 from proddy/dev
fixes to api
2024-07-21 13:00:28 +02:00
proddy
62152825bd cleanup 2024-07-21 12:59:23 +02:00
proddy
2a9ebde829 fix unknown command being added to return json 2024-07-21 12:59:19 +02:00
proddy
006b38df27 make standalone compile 2024-07-21 12:58:42 +02:00
proddy
cb8e8cb1da update test 2024-07-21 12:58:28 +02:00
proddy
337d27a41c fix lint warnings 2024-07-21 12:57:51 +02:00
Proddy
55476a7828 Merge pull request #1877 from MichaelDvP/dev
schedule onChange optimize queue
2024-07-21 09:27:18 +02:00
MichaelDvP
74b009f658 schedule onChange optimize queue 2024-07-21 09:04:53 +02:00
Proddy
e4decb53b0 Merge pull request #1876 from MichaelDvP/dev
scheduler async, command use string, lowercase
2024-07-20 20:15:31 +02:00
MichaelDvP
4dd3a668df fix http.GetString 2024-07-20 19:10:20 +02:00
MichaelDvP
c21c0b5dd1 scheduler async, command use string, lowercase 2024-07-20 18:21:26 +02:00
Proddy
d35dd1a9c4 Merge pull request #1875 from proddy/dev
add test for URI in scheduler
2024-07-20 16:32:11 +02:00
proddy
74c4940971 add test for URI in scheduler 2024-07-20 16:31:40 +02:00
Proddy
87548f9322 Merge pull request #1874 from proddy/dev
web updates and scheduler
2024-07-20 15:49:55 +02:00
proddy
809c5c7ead scheduler http tests 2024-07-20 13:22:01 +02:00
proddy
353e1f4460 remove comments 2024-07-20 13:21:20 +02:00
proddy
f27eb05024 color log lines to match system log 2024-07-20 13:03:30 +02:00
proddy
6bdca66bfb rotate level 2024-07-20 13:03:17 +02:00
proddy
164c1f5542 add comment TODO 2024-07-20 11:45:02 +02:00
proddy
8838eae3fa package update 2024-07-20 11:44:51 +02:00
proddy
d3447694fa rename alphanumeric 2024-07-20 11:44:44 +02:00
proddy
27eb56aee8 scheduler command max 300 2024-07-20 11:44:31 +02:00
proddy
ac27096087 dont close dialog if clicking outside, also fix warning https://w3c.github.io/aria/#aria-hidden 2024-07-20 11:44:18 +02:00
Proddy
a0ba0e8af9 Merge pull request #1873 from MichaelDvP/dev
Scheduler web access and others
2024-07-20 09:47:17 +02:00
MichaelDvP
c3296ccf97 offset correction for next telegram 2024-07-19 19:57:13 +02:00
MichaelDvP
1a400bfd40 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-07-19 18:42:50 +02:00
MichaelDvP
58c48584ac fetch next telegram part for different offset 2024-07-19 18:40:24 +02:00
Proddy
5603360aab Merge pull request #1872 from proddy/dev
more minor changes
2024-07-19 13:51:37 +02:00
MichaelDvP
f7278ab3a9 v3.7.0-dev.26, changelog 2024-07-19 12:50:50 +02:00
MichaelDvP
3ad676235d update pkg 2024-07-19 12:45:40 +02:00
MichaelDvP
559caeb30f schedulder enhancement url json #1806 2024-07-19 12:45:27 +02:00
MichaelDvP
b857eedab8 add cooling parameters #1857 2024-07-19 12:27:24 +02:00
MichaelDvP
9ac1907e16 naming for RC220 #1871 2024-07-19 12:20:56 +02:00
proddy
9efd9f27fc add comment 2024-07-19 10:12:11 +02:00
proddy
d8c1a7e82d show brand in system/info 2024-07-19 10:12:03 +02:00
proddy
79e51ad71c package update 2024-07-19 10:11:45 +02:00
proddy
887cd33f5b change order of menu items, make all bus status clickable for bbqkees 2024-07-18 15:59:13 +02:00
proddy
7826f3b873 add HA API test 2024-07-18 15:00:38 +02:00
proddy
3af3d3f0d8 add comments 2024-07-18 15:00:25 +02:00
proddy
ce84aae950 removed obsolete files 2024-07-18 15:00:18 +02:00
Proddy
5b4d392640 Merge pull request #1869 from MichaelDvP/dev
add RT800 remote #1867, use ems_bus_id for raw telegrams if src is not set(0)
2024-07-18 14:54:15 +02:00
MichaelDvP
f5e2bbfdec Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-07-18 12:39:40 +02:00
Proddy
a7dcb32931 Merge pull request #1868 from proddy/dev
minor changes
2024-07-18 11:26:52 +02:00
Proddy
d135fa3a66 Merge branch 'dev' into dev 2024-07-18 11:26:44 +02:00
proddy
836f6bf5df remove TODO comment 2024-07-18 10:11:15 +02:00
proddy
581e3e6649 include version as HA sensor - https://github.com/tp1de/ioBroker.ems-esp/issues/84 2024-07-18 09:53:57 +02:00
proddy
48f48564e7 package update 2024-07-18 09:53:46 +02:00
proddy
7891b8abe5 update node 2024-07-17 09:15:12 +02:00
proddy
0c1db756c7 show unknown command in API output so its same as a log 2024-07-17 09:14:39 +02:00
proddy
f34f503b19 no need to check for duplicate EMS devices when showing commands 2024-07-17 09:14:20 +02:00
proddy
e2ce367478 fix left over testing 2024-07-17 09:14:04 +02:00
proddy
0c1c3c9b8d rename max alloc (largest free heap memory block) 2024-07-16 22:46:17 +02:00
proddy
31be3fb3c3 add icon for bbqkees boards 2024-07-16 20:56:32 +02:00
proddy
b31e035eeb text changes 2024-07-16 20:34:06 +02:00
proddy
fb0491d8ba some more refactoring around processing commands 2024-07-16 20:34:00 +02:00
proddy
95f6d57df4 include scheduler name so we can show it in log 2024-07-16 20:33:27 +02:00
proddy
51b24fe766 remove english description, lists to non-plural 2024-07-16 20:33:06 +02:00
proddy
83042e3560 update test for 2 thermostats 2024-07-16 20:32:41 +02:00
proddy
2e9e5b69be add comments 2024-07-16 20:32:31 +02:00
proddy
78e1ec483e package update 2024-07-16 20:32:17 +02:00
MichaelDvP
711d1dfe94 remote RT800 #1867 2024-07-16 19:09:59 +02:00
MichaelDvP
54a023d812 update packages 2024-07-16 19:08:05 +02:00
MichaelDvP
58aacc189f system/send: use busId if SRC is null 2024-07-16 13:57:03 +02:00
Proddy
af0e8db8ea Merge pull request #1866 from MichaelDvP/dev
fix value info for second thermostat
2024-07-15 23:26:40 +02:00
MichaelDvP
4755e685f4 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-07-15 22:12:42 +02:00
MichaelDvP
a3ef7fcf09 fix value info for second thermostat 2024-07-15 22:08:51 +02:00
Proddy
1afc21d565 Merge pull request #1865 from proddy/dev
moved Device model to Hardware Status page (was System Status)
2024-07-15 21:36:54 +02:00
Proddy
e15f0e7d6d Merge branch 'emsesp:dev' into dev 2024-07-15 21:35:46 +02:00
Proddy
4cfcb33b4f Merge pull request #1864 from MichaelDvP/dev
set `remotehum` as CMD
2024-07-15 21:35:30 +02:00
proddy
d0bb9aca3b rename System Status to Hardware Status 2024-07-15 21:31:11 +02:00
proddy
2d63320afb text changes, rename system status to hardware, added model 2024-07-15 21:17:02 +02:00
proddy
f04ab8e3c1 update packages 2024-07-15 20:59:27 +02:00
proddy
87b47c57bb add TODO reminders 2024-07-15 20:59:14 +02:00
proddy
16fa03fb48 default test back to general 2024-07-15 20:59:05 +02:00
proddy
6097c01d72 sort devices and change model 2024-07-15 20:58:53 +02:00
MichaelDvP
dae1d4e3a8 set remotehum as CMD 2024-07-15 19:52:56 +02:00
Proddy
686ed20222 Merge pull request #1863 from MichaelDvP/dev
add CMD to api/mqtt to show it in ioBroker, etc.
2024-07-15 11:42:41 +02:00
MichaelDvP
ce33ec4bd3 validate names lowerCase 2024-07-15 11:16:42 +02:00
MichaelDvP
5b143cd22a change order in "cannot find 'device' in 'command'" 2024-07-15 08:56:36 +02:00
MichaelDvP
4c6d396d70 analogsensor default name, validators 2024-07-15 08:10:21 +02:00
MichaelDvP
3d2912b998 check system/values lower case 2024-07-15 08:08:34 +02:00
MichaelDvP
46f674f0dc fix info/values command with circuit api/device/circuit/values 2024-07-15 08:07:43 +02:00
MichaelDvP
7727093767 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-07-15 07:13:30 +02:00
Proddy
96bb220b36 Merge pull request #1855 from proddy/dev
Implements Feature: message notification #1854
2024-07-14 23:46:16 +02:00
proddy
7fc2afc11b auto comments 2024-07-14 23:45:07 +02:00
proddy
5f1cc56939 remove obsolete file 2024-07-14 23:44:54 +02:00
proddy
10444473c9 clean make 2024-07-14 23:44:43 +02:00
proddy
301a1afd41 auto formatting 2024-07-14 23:23:43 +02:00
proddy
b35ff53d63 add TODO for BSSID 2024-07-14 23:22:55 +02:00
proddy
2c2ffe1555 show message if empty return from call command 2024-07-14 23:22:28 +02:00
proddy
d696da2ee8 change debug msg 2024-07-14 23:22:14 +02:00
proddy
a6b307442c fix layout on mobile 2024-07-13 16:21:56 +02:00
proddy
710a924cbe package update 2024-07-13 16:21:48 +02:00
proddy
fbe20fec41 optimize device_info 2024-07-12 15:20:48 +02:00
proddy
f839c07d23 full coverage for api tests 2024-07-12 15:20:37 +02:00
proddy
901b58220e update packages 2024-07-12 15:20:27 +02:00
proddy
c4ace6f877 fix typo 2024-07-11 17:02:33 +02:00
proddy
937e4890f7 fix typo 2024-07-11 17:02:23 +02:00
proddy
f3f5bbb460 add comment 2024-07-11 17:02:10 +02:00
proddy
a9d85748ef back to default test 2024-07-11 17:01:59 +02:00
proddy
d7ba360483 fixes for device_info 2024-07-11 16:29:37 +02:00
proddy
76675c79fb update test data for api3 2024-07-11 16:27:10 +02:00
proddy
fec76baea5 fix to compile on Mac OSX 2024-07-11 16:26:50 +02:00
proddy
2b7b8c1bd9 fix for compiling on Mac OSX Apple Silicon 2024-07-11 16:26:33 +02:00
proddy
d3d303cfc4 update to show problem and a change 2024-07-11 16:26:14 +02:00
proddy
3c64693275 fixes #1859 2024-07-11 11:03:32 +02:00
proddy
e1ecb78375 schedule name can be empty 2024-07-11 10:42:35 +02:00
proddy
0de73c8c85 package update 2024-07-11 10:42:23 +02:00
proddy
7e0e28f515 update dumps 2024-07-10 14:55:04 +02:00
proddy
4a2036d588 no need to append space, as strings can be quoted 2024-07-10 13:12:18 +02:00
proddy
7b80524a5a scheduler name can be empty 2024-07-10 13:11:57 +02:00
proddy
1da44afddb getBBQKeesGatewayDetails 2024-07-10 12:54:53 +02:00
proddy
154b1d5ec1 show if running debug mode in console 2024-07-10 12:53:47 +02:00
proddy
07c6f8993d show help when command not found 2024-07-10 12:53:30 +02:00
proddy
4f40a3d990 Show bbqkees model - #1815 2024-07-10 12:53:18 +02:00
MichaelDvP
c3ce0c1e2d send CMD value for number as NAN 2024-07-08 19:04:16 +02:00
MichaelDvP
3d7378a1a8 cmd info shows right type (number/enum), no value 2024-07-08 18:02:14 +02:00
proddy
6f0062be5c replace size with isNull for jsondoc. size() walks a linked-list to count the elements, so its time complexity is O(n). 2024-07-08 15:29:33 +02:00
proddy
4f9a32fb36 typo 2024-07-08 15:26:21 +02:00
proddy
f05a012ef3 concatenate all token strings - experimental 2024-07-08 14:57:26 +02:00
proddy
e4e1bc3c1e remove old debug statement 2024-07-08 14:56:57 +02:00
proddy
a902a24150 fix typo 2024-07-08 14:56:38 +02:00
proddy
bef664b6d6 show RSSI in standalone to test negative value with shuntingyard 2024-07-08 14:56:21 +02:00
proddy
9bda29044f formatting 2024-07-08 12:06:20 +02:00
proddy
b9c2c2ad59 update api tests 2024-07-08 12:06:03 +02:00
proddy
39b5aa6c8e formatting 2024-07-08 12:05:45 +02:00
proddy
94b0f21461 EMSESP_DEFAULT_PUBLISH_TIME_OTHER is 1 minute 2024-07-08 12:05:31 +02:00
proddy
1f106ac5f5 show DEBUG messages 2024-07-08 12:05:14 +02:00
proddy
8dbde11dd5 default publishing time for other (E.g. scheduler) is 60 seconds 2024-07-08 12:05:01 +02:00
proddy
30430844d3 name is optional 2024-07-08 12:04:34 +02:00
proddy
8dc2677c13 add DEBUG type 2024-07-08 12:04:23 +02:00
proddy
08efccf260 sort by flags (type), not name 2024-07-08 12:04:12 +02:00
MichaelDvP
d774591065 Scheduler name optional 2024-07-08 10:20:13 +02:00
MichaelDvP
2f66fec748 add CMD to api/mqtt to show it in ioBroker 2024-07-08 08:06:27 +02:00
proddy
e0d30bfca5 Feature: message notification #1854 2024-07-07 17:15:34 +02:00
proddy
acda3a254c ignore i18n files 2024-07-07 17:14:57 +02:00
Proddy
611f02f81b Merge pull request #1853 from mheyse/fix/modbus-test
Only include mocked modbus data structures in standalone builds.
2024-07-07 09:02:03 +02:00
mheyse
6a721808a4 Only include mocked modbus data structures in standalone builds. 2024-07-06 21:08:39 +02:00
Proddy
9cb6b800cb Merge pull request #1851 from proddy/dev
small change to make sure flags are set in Scheduler with a Timer
2024-07-06 19:27:46 +02:00
proddy
05cd1ef686 ensure flag is set before adding a timer 2024-07-06 19:26:38 +02:00
proddy
5eb56c3243 remove duplicate toast 2024-07-06 19:26:22 +02:00
Proddy
8a4218206d Merge pull request #1850 from MichaelDvP/dev
custom name null and fix HA CMD
2024-07-06 19:06:37 +02:00
MichaelDvP
ba3df3e3df fix cmd HA-mqtt 2024-07-06 17:55:06 +02:00
Proddy
dec7e2ec68 Merge pull request #1847 from proddy/dev
minor updates
2024-07-06 12:40:38 +02:00
proddy
7f0cbe7226 update eslint 2024-07-06 12:34:49 +02:00
proddy
2e6add0dac remove error, unused 2024-07-06 12:34:41 +02:00
proddy
c795eea436 rename partitionsname to partitionname 2024-07-06 12:20:12 +02:00
proddy
ca7373792d add /partition endpoint 2024-07-06 12:19:03 +02:00
proddy
fc4e1c0084 package update 2024-07-06 12:18:50 +02:00
proddy
e92b27c0bb re-order restart button 2024-07-06 12:18:43 +02:00
proddy
9d5eb11ba4 remove "event" from info topic 2024-07-06 12:18:31 +02:00
MichaelDvP
a2c5aebfd9 fix possible crash for custom_name==nullptr, dev.23 2024-07-06 12:06:33 +02:00
Proddy
af07572b1c Merge pull request #1846 from proddy/dev
default shower detect start time 3 minutes (was 2)
2024-07-05 15:19:32 +02:00
proddy
0dc125df4d default shower detect start time 3 minutes (was 2) 2024-07-05 15:19:10 +02:00
Proddy
fb517d2521 Merge pull request #1845 from proddy/dev
github action update for forks (sonar) and test data cleanup
2024-07-04 21:56:35 +02:00
Proddy
503f7e8fbb Merge branch 'emsesp:dev' into dev 2024-07-04 21:56:08 +02:00
proddy
6feae50ecd test data with more - to _ replacements for sensor IDs 2024-07-04 21:55:35 +02:00
proddy
cdac298d38 update test data 2024-07-04 21:55:18 +02:00
proddy
c82b64e257 see if it fixes adjust GitHub actions so they only run for ems-esp and not forks #513 2024-07-04 21:55:08 +02:00
Proddy
5f2e6280ac Merge pull request #1844 from MichaelDvP/dev
rename remote sensor to avoid conflict CMD/INT16 in api/thermostat
2024-07-04 18:11:56 +02:00
MichaelDvP
03c5f48208 rename remote sensor to avoid conflict CMD/INT16 in api/thermostat 2024-07-04 17:20:54 +02:00
Proddy
bab64a3ab3 Merge pull request #1843 from MichaelDvP/dev
remotetemp CMD, temperaturesensor id, controlsettings BC400, Boiler/HP
2024-07-04 16:52:18 +02:00
MichaelDvP
6d0e73cc4b show sensor in remote RC20 2024-07-04 16:15:40 +02:00
MichaelDvP
c527d006dd show Boiler/HP on web pages 2024-07-04 15:46:47 +02:00
MichaelDvP
81d97405f9 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-07-04 14:43:48 +02:00
MichaelDvP
827b7fc370 show RC20 roomtemp in remote 2024-07-04 14:15:36 +02:00
MichaelDvP
2b4b2881c9 changelog v3.7.0-dev.22 2024-07-04 13:47:13 +02:00
MichaelDvP
cee2d5ca31 change temperaturesensor id to underscore notation 2024-07-04 13:42:23 +02:00
MichaelDvP
147804b4b8 change remotetemp to CMD 2024-07-04 13:41:17 +02:00
MichaelDvP
a211f95758 control setting BC400 #1838 2024-07-04 13:02:05 +02:00
Proddy
6b6224dead Merge pull request #1840 from mheyse/fix/check-parameter-order
fix: nullptr linter error
2024-07-04 10:02:31 +02:00
mheyse
8c810f2276 fix nullptr linter error 2024-07-04 09:00:12 +02:00
Proddy
a0ca1ce87c Merge pull request #1839 from proddy/dev
minor updates for modbus
2024-07-03 22:40:54 +02:00
proddy
12a4942714 minor updates for modbus 2024-07-03 22:39:41 +02:00
Proddy
9277efd1d7 Merge pull request #1832 from mheyse/feat/modbus
feat: add Modbus support
2024-07-03 22:14:37 +02:00
mheyse
0c76a249e3 feat: add Modbus support 2024-07-03 15:27:37 +02:00
Proddy
217d90629a Merge pull request #1834 from proddy/dev
Allow device name to be customized
2024-07-03 13:29:44 +02:00
proddy
807804ca90 update tasmota for 4mb builds 2024-07-03 11:42:33 +02:00
proddy
307c196046 #1174 - include translated device type name in dropdown 2024-07-03 11:19:41 +02:00
proddy
0aa8e138b5 update package 2024-07-03 11:19:18 +02:00
proddy
03ef598b42 update package 2024-07-03 11:19:09 +02:00
proddy
86f6e0a2fd add TODO as reminder 2024-07-02 20:05:52 +02:00
proddy
3ae48f4d16 Feature: Allow device name to be customized #1174 2024-07-02 20:05:39 +02:00
proddy
46b79f4819 use name() function instead of name_ 2024-07-02 20:04:46 +02:00
proddy
20381e5e09 auto-formatting 2024-07-02 20:04:23 +02:00
proddy
259cba8aa9 load customization before loading devices 2024-07-02 20:04:11 +02:00
proddy
9a01feafd1 move DEBUG msg 2024-07-02 20:03:49 +02:00
proddy
ab24528582 bump dev.20 2024-07-02 20:03:37 +02:00
proddy
642f44daaa remove TODO 2024-07-02 20:03:25 +02:00
proddy
3309e8c3d6 remove TODO 2024-07-02 20:03:09 +02:00
proddy
c5c5651149 don't include type in name of device (in customization list) 2024-07-01 21:48:40 +02:00
proddy
a28db9369b add comment 2024-07-01 21:48:19 +02:00
proddy
a626ad4af1 add more test data 2024-07-01 21:48:05 +02:00
proddy
fcbd668d7a package update 2024-07-01 21:47:54 +02:00
proddy
2688ed0084 rename Device 2024-07-01 13:43:37 +02:00
Proddy
463fbd69c8 Merge pull request #1831 from proddy/dev
prep for modbus merge
2024-06-29 10:06:38 +01:00
proddy
2155c2e70f update for 3.7.0 2024-06-29 11:05:24 +02:00
proddy
47cbbba675 updates 2024-06-29 10:24:14 +02:00
Proddy
66470071f6 Merge pull request #1830 from MichaelDvP/dev
CR120 fixes #1779
2024-06-28 20:59:43 +01:00
MichaelDvP
e63090573a CR120: dhw modes off/comfort/auto 2024-06-28 17:51:58 +02:00
MichaelDvP
5a7da199ed fix manualtemp for CR120 #1779 2024-06-28 17:51:37 +02:00
Proddy
03e5834d59 Merge pull request #1802 from SLTKA/feature/pump-characteristic 2024-06-28 14:35:03 +01:00
Proddy
23fdfd4f26 Merge pull request #1829 from proddy/dev
ArduinoJson 7.1.0
2024-06-28 08:05:42 +01:00
Proddy
021cf8dd70 Merge branch 'emsesp:dev' into dev 2024-06-28 08:05:17 +01:00
proddy
3a6bbf57ae bump ArduinoJson to 7.1.0 2024-06-28 09:04:30 +02:00
proddy
430bbf9c46 package update (vite) 2024-06-28 09:04:19 +02:00
Proddy
ffb91ce997 Merge pull request #1828 from MichaelDvP/dev
fixes device redetction, command id -1 #1779
2024-06-28 07:48:58 +01:00
MichaelDvP
c74ebc8aae log text for command 2024-06-28 07:31:25 +02:00
MichaelDvP
69b6bcfaed Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-06-28 07:27:20 +02:00
MichaelDvP
b2b79734c1 don't update products with valid product-id 2024-06-28 07:25:06 +02:00
MichaelDvP
a9de8ec046 fix ommands with auto-id (-1) 2024-06-28 07:23:12 +02:00
Proddy
ae70ca2079 Merge pull request #1827 from proddy/dev 2024-06-27 15:12:23 +01:00
proddy
eebb8e68f7 match type - rename none to Disabled 2024-06-27 15:12:30 +02:00
proddy
407191b72c added comment 2024-06-27 15:12:06 +02:00
proddy
2097e8e271 remove TODO comments 2024-06-27 14:53:30 +02:00
proddy
139d32c431 stop crashing when ETH used and Analog Sensor is pin 21/SDA or 22/SCC (I2C conflict). Show when its a bad GPIO in log. 2024-06-27 14:52:48 +02:00
proddy
320035fd72 show which IP is for which when both ETH and Wifi and enabled 2024-06-27 14:51:40 +02:00
proddy
ccd4b8917f update packages 2024-06-27 14:51:17 +02:00
proddy
eccca23163 adding spelling to vscode check (optional) 2024-06-27 14:51:08 +02:00
Alexandr Yeskov
deedd49721 feat: Add support for Boiler Pump Characteristic
This adds support for pump characteristic and pump output settings
for 0xE6 type
2024-06-27 21:39:49 +10:00
Proddy
95915611b5 Merge pull request #1825 from MichaelDvP/dev
Scheduler fixes and additions
2024-06-27 08:14:34 +01:00
MichaelDvP
266a7a4e9b allow multiple instances of "?:" in a schedule 2024-06-27 08:28:38 +02:00
MichaelDvP
a46b9c60dd allow multiple onChange schedules with same trigger #1806 2024-06-27 08:27:16 +02:00
MichaelDvP
03513be144 add heatingactive/tapwateractive to onChange #1806 2024-06-27 08:26:16 +02:00
MichaelDvP
39014a2216 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-06-25 15:28:43 +02:00
MichaelDvP
e5a8fd7be4 german translation #1800 2024-06-25 15:28:05 +02:00
Proddy
a4ad8f551a Merge pull request #1821 from proddy/dev
minor changes
2024-06-25 09:53:21 +01:00
proddy
edaeafd619 don't run sonar on pulls 2024-06-25 10:51:08 +02:00
proddy
9a63307b33 updated for dev.18 2024-06-25 10:44:44 +02:00
proddy
18483558d4 lowercase Entities 2024-06-25 10:42:18 +02:00
proddy
2184fbb113 experiment with cache (again) 2024-06-25 10:42:05 +02:00
proddy
4ebd0657f4 include device data in export 2024-06-25 10:41:36 +02:00
Proddy
c7759a71b4 Merge pull request #1820 from proddy/dev
export DeviceValues and format Device Values window
2024-06-24 20:53:07 +01:00
proddy
e3b37e8220 rename GitHub 2024-06-24 21:49:29 +02:00
proddy
5f08e218ec formatting 2024-06-24 21:49:21 +02:00
proddy
26eb2a3b29 add button tooltip, also export json 2024-06-24 21:49:06 +02:00
proddy
03933edcae update packages 2024-06-24 21:48:21 +02:00
Proddy
e037c0753d Merge pull request #1819 from proddy/dev
fix shower duration
2024-06-23 10:39:33 +01:00
proddy
ef4588e3de auto formatting 2024-06-23 11:38:37 +02:00
proddy
79e784239b fix duration conversion from ms #1801 2024-06-23 11:36:38 +02:00
proddy
9d42684591 formatting 2024-06-23 11:36:02 +02:00
proddy
8c4e8f5fa6 add /rest test 2024-06-23 11:35:55 +02:00
Proddy
f417b6087b Merge pull request #1818 from MichaelDvP/dev
update pkg, fix changes-number, sort by name(required)
2024-06-23 09:38:46 +01:00
MichaelDvP
a07cc4fcc7 update pkg, fix changes-number, sort by name(required) 2024-06-22 20:00:50 +02:00
Proddy
402498d7cb Merge pull request #1817 from MichaelDvP/dev 2024-06-22 16:00:16 +01:00
MichaelDvP
78b38c2ee1 sonar warning 2024-06-22 15:12:44 +02:00
Proddy
9098689136 Merge pull request #1816 from MichaelDvP/dev 2024-06-22 13:17:13 +01:00
MichaelDvP
eba737a119 typo 2024-06-22 13:24:50 +02:00
MichaelDvP
02242a2568 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-06-22 12:36:43 +02:00
MichaelDvP
dc6b41a473 always use F_(devicename) 2024-06-22 12:34:25 +02:00
MichaelDvP
5ffd4d87fb fix timeout remote 2024-06-22 12:32:02 +02:00
MichaelDvP
bed7793dab multiple onChange and check one ? : sequence 2024-06-22 08:33:13 +02:00
Proddy
4b3d801312 Merge pull request #1814 from proddy/dev
minor cleanup, fix codacy
2024-06-21 13:52:32 +01:00
proddy
ddbd9dab79 remove columns 2024-06-21 13:50:12 +01:00
proddy
ec2acb60b3 formatting 2024-06-21 13:50:00 +01:00
proddy
999d08e485 formatting 2024-06-21 13:49:50 +01:00
proddy
2e2cf30c12 formatting 2024-06-21 13:49:17 +01:00
proddy
4754ea6211 fix codacy link 2024-06-21 13:48:56 +01:00
proddy
ae716b5caa update packages 2024-06-21 13:48:46 +01:00
proddy
50d8814f3b remove comments 2024-06-21 13:48:25 +01:00
Proddy
345c7378ad Merge pull request #1813 from MichaelDvP/dev
scheduler fixes, additions
2024-06-21 12:41:00 +01:00
MichaelDvP
649734df43 set default 00:00 for schedule time 2024-06-21 12:21:01 +02:00
MichaelDvP
a8adc26fc4 add unused cases for sonar scanner 2024-06-21 12:20:27 +02:00
MichaelDvP
920f24b45a add mock api example 2024-06-21 12:19:57 +02:00
MichaelDvP
3ff3e8a8cf system commands case independend, logic checks, small fixes 2024-06-21 11:03:33 +02:00
MichaelDvP
fb8deb41f9 remove string conversion 2024-06-21 08:28:07 +02:00
Proddy
74506e1775 Merge pull request #1812 from MichaelDvP/dev
scheduler conditions
2024-06-20 22:21:52 +01:00
MichaelDvP
0fc62b216a merge conditions, 3.7.0-dev.17 2024-06-20 22:08:47 +02:00
MichaelDvP
926a22d9ba Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev2 2024-06-20 21:49:00 +02:00
Proddy
d37e4d7e5f Merge pull request #1811 from MichaelDvP/dev
Make remote timeout editable #1774, dev-16
2024-06-20 20:36:08 +01:00
MichaelDvP
09bc8f42cc fix typo 2024-06-20 21:13:35 +02:00
MichaelDvP
1b09a301ba Make remotetimeout editable #1774, dev-16 2024-06-20 19:46:09 +02:00
Proddy
d8f989543e Merge pull request #1810 from proddy/dev
sonar fix, shower max duration
2024-06-20 17:15:18 +01:00
proddy
12701b2143 max shower min duration 6 minutes 2024-06-20 17:13:50 +01:00
proddy
a861649249 fix sonar (again!) 2024-06-20 17:13:38 +01:00
MichaelDvP
4a48e03552 update testrelease 2024-06-20 17:47:48 +02:00
MichaelDvP
c40625d658 Conditions, v3.7.0-test.15 2024-06-20 15:46:08 +02:00
MichaelDvP
6c111c7816 Scheduler conditions: allow system 2024-06-20 15:44:02 +02:00
MichaelDvP
95d404551c Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into feat_conditions 2024-06-20 14:51:56 +02:00
MichaelDvP
240137d3a2 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-06-20 14:51:23 +02:00
MichaelDvP
fbc3807daa update packages, arduino test 2024-06-20 14:50:25 +02:00
Proddy
6ffc466dff Merge pull request #1809 from proddy/dev
fix sonar again
2024-06-20 08:35:35 +01:00
proddy
8f1d5e4752 fix sonar again 2024-06-20 08:35:06 +01:00
Proddy
19c93e25ef Merge pull request #1807 from proddy/dev
#1801 shower_duration_min
2024-06-20 08:17:16 +01:00
proddy
fc54d6a289 dev15, update chngelog 2024-06-20 08:15:07 +01:00
proddy
1364fcca52 120 seconds for shower_min_duration 2024-06-19 20:08:03 +01:00
proddy
20beda740a shower_min_duration #1801 2024-06-19 18:18:00 +01:00
proddy
9a085c8961 remove unused pragma 2024-06-19 18:15:26 +01:00
proddy
e6ccee1bf2 update sonar 2024-06-19 18:14:44 +01:00
proddy
d975e1b6da use arduino 2.0.17, not 3.0.1 2024-06-19 18:14:26 +01:00
proddy
c9a8d6aeb0 update packages 2024-06-19 18:14:07 +01:00
MichaelDvP
b1750265aa back to arduino core 2.xx 2024-06-19 11:46:20 +02:00
MichaelDvP
03496acd22 back to arduino 2.xx 2024-06-19 11:38:07 +02:00
MichaelDvP
bae5a11264 schedule conditions chack numbers and strings, fix custom commands 2024-06-18 18:23:08 +02:00
Proddy
912826d20e Merge pull request #1805 from MichaelDvP/dev
add model() for CR120 for different modes
2024-06-17 18:51:25 +01:00
MichaelDvP
f76c5f6afe Merge branch 'dev' into feat_conditions 2024-06-17 16:00:26 +02:00
MichaelDvP
644a694ed2 add model() for CR120 for different modes 2024-06-17 16:00:01 +02:00
MichaelDvP
fc75824921 scheduler: onChange and conditions 2024-06-15 20:00:08 +02:00
Proddy
55316334d4 Merge pull request #1803 from MichaelDvP/dev
fix #1800
2024-06-15 16:31:10 +02:00
MichaelDvP
ffb7fd3f12 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-06-15 13:47:49 +02:00
Proddy
0b6f7527e5 Merge pull request #1799 from proddy/dev
add Makefile back so sonar tests run again
2024-06-14 23:19:18 +02:00
proddy
f94bbcaf39 remove obsolete file 2024-06-14 23:18:30 +02:00
proddy
c7b7952303 add Makefile back - needed for sonar 2024-06-14 23:18:19 +02:00
proddy
d9906b0da4 update packages 2024-06-14 23:17:45 +02:00
Proddy
9bfdb69012 Merge pull request #1798 from proddy/dev
formatting, fix MQTT HA
2024-06-14 12:33:44 +02:00
proddy
1c7c2a7f83 resolve lint warnings 2024-06-14 12:29:42 +02:00
proddy
ff49caaada make copy of state in creating HA's avty_json as string would go out of scope 2024-06-14 11:48:12 +02:00
proddy
13eee19981 update packages 2024-06-14 11:47:26 +02:00
proddy
3d335963b9 color restart button 2024-06-14 11:47:04 +02:00
proddy
9989a03993 remove base() as it's unused 2024-06-14 11:40:49 +02:00
proddy
c9148b574f default EMSESP_DEFAULT_ENTITY_FORMAT is 1 (SINGLE_SHORT) 2024-06-14 11:40:32 +02:00
Proddy
74e0123475 Merge pull request #1793 from proddy/dev
Modules
2024-06-13 22:20:25 +02:00
proddy
28abf579e8 process all modules before showing error 2024-06-13 21:11:49 +02:00
proddy
c044e1a221 dev.13 2024-06-13 21:11:31 +02:00
proddy
ce4957f087 update packages 2024-06-13 21:11:19 +02:00
proddy
53837e36b4 lint fixing 2024-06-12 20:57:50 +02:00
proddy
07dbe7d260 update packages 2024-06-12 10:24:23 +02:00
proddy
e56263eb51 update example 2024-06-12 10:23:52 +02:00
proddy
9e2b6a2963 rename standalone to native 2024-06-12 10:23:43 +02:00
proddy
b4a8d3c181 pull MAC from efuse 2024-06-12 10:23:26 +02:00
proddy
509c7ee900 text changes 2024-06-12 10:22:53 +02:00
proddy
9e1d9431c1 remove getMacAddress 2024-06-12 10:22:44 +02:00
proddy
b92607f0e9 use total for energyLastHour instead 2024-06-12 10:22:11 +02:00
proddy
dcb83989c8 removed as it's old 2024-06-12 10:21:39 +02:00
proddy
9331a6e7a1 fixes #1796 2024-06-12 08:44:55 +02:00
Proddy
caa6a0b7ae Merge pull request #1792 from proddy/feat_modules
Feat modules
2024-06-09 14:03:45 +02:00
proddy
8783267e18 updates to look & feel 2024-06-09 14:03:11 +02:00
Proddy
a1d61b4422 Merge branch 'emsesp:feat_modules' into feat_modules 2024-06-09 13:52:47 +02:00
proddy
924de1cd42 use framework-arduinoespressif32 3.0.1 2024-06-09 12:44:16 +02:00
Proddy
66ba2f3218 Merge pull request #1791 from proddy/feat_modules
Feat modules
2024-06-08 16:01:40 +02:00
Proddy
bc53c953e8 Merge branch 'emsesp:feat_modules' into feat_modules 2024-06-08 16:01:10 +02:00
proddy
9d64282c0b remove debug comment 2024-06-08 15:08:58 +02:00
proddy
8625d65fb6 update example 2024-06-08 15:08:48 +02:00
proddy
23fe7f6ad3 remove Restart 2024-06-08 15:08:40 +02:00
proddy
b7f3612738 adjust modules text 2024-06-08 15:08:31 +02:00
proddy
e9bba003af change title 2024-06-08 15:08:21 +02:00
proddy
fe17411406 default mqtt format is 3 (for 3.6) 2024-06-08 15:07:25 +02:00
Proddy
ec01dd7581 Merge pull request #1790 from proddy/feat_modules
Feat modules
2024-06-08 12:27:23 +02:00
proddy
6a734b9c61 add module license 2024-06-08 12:26:32 +02:00
MichaelDvP
0c6141e13b Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-06-05 19:36:46 +02:00
MichaelDvP
cb844e0b92 fix mode init 2024-06-05 19:35:47 +02:00
MichaelDvP
1883c98b39 fix raw telegram write from other id 2024-06-05 19:31:46 +02:00
proddy
69d0cba893 ClientPosixIPAddress 2024-06-04 21:19:58 +02:00
proddy
7f1dbbcb94 update to 1.7.0 2024-06-04 21:19:48 +02:00
proddy
26ac0057a5 replace IPAddress with MQTT library one 2024-06-04 21:19:34 +02:00
Proddy
d63bab5982 Merge pull request #1788 from proddy/feat_modules
Feat modules
2024-06-04 17:21:36 +02:00
proddy
d3690bb51b remove makefile 2024-06-04 17:20:28 +02:00
proddy
d327ae25c5 cleanup 2024-06-04 17:20:14 +02:00
MichaelDvP
a2ba88fe26 add CR120 as name to device-lib 2024-05-31 17:21:54 +02:00
Proddy
354e9154c5 Merge pull request #1785 from proddy/feat_modules
Feat modules
2024-05-31 06:04:56 +02:00
proddy
fffb6d6072 update changelog 2024-05-31 06:04:13 +02:00
proddy
07034824d6 Merge remote-tracking branch 'origin/dev' into feat_modules 2024-05-31 05:59:30 +02:00
Proddy
c8300a7a12 Merge pull request #1783 from MichaelDvP/dev
dev12, fixes #1774 (change timeout #1680 to 24h) and #1779
2024-05-30 22:04:17 +02:00
Proddy
9b983a8069 Merge pull request #1784 from proddy/feat_modules
Feat modules
2024-05-30 22:03:53 +02:00
Proddy
00528c8c6d Merge branch 'emsesp:feat_modules' into feat_modules 2024-05-30 22:03:35 +02:00
proddy
0184f77246 Merge branch 'feat_modules' of https://github.com/proddy/EMS-ESP32 into feat_modules 2024-05-30 22:02:35 +02:00
proddy
6f9633ae9a recommend restart 2024-05-30 22:01:54 +02:00
proddy
abfe6f0cbd add debug notes 2024-05-30 22:01:40 +02:00
proddy
826559c2a1 add comments 2024-05-30 22:01:27 +02:00
Proddy
49bd11dd57 Merge pull request #1782 from proddy/feat_modules
Feat modules - add web
2024-05-30 18:24:07 +02:00
Proddy
44abbcbc22 Merge branch 'emsesp:feat_modules' into feat_modules 2024-05-30 18:23:35 +02:00
proddy
cfe8235cee add web for Modules 2024-05-30 18:16:31 +02:00
MichaelDvP
845e6f4527 fix set mode 2024-05-30 15:01:10 +02:00
MichaelDvP
93a9e5da1d changelog, v3.7.0-dev.12 2024-05-30 12:22:11 +02:00
MichaelDvP
f942aec67b seltemp for CR120 thermostat, #1779 2024-05-30 12:21:32 +02:00
MichaelDvP
5fc6678d0b set remottemp timeout to one day, #1774, #1680 2024-05-30 12:01:20 +02:00
Proddy
b9fa689829 Merge pull request #1780 from proddy/feat_modules
Feat modules
2024-05-29 22:24:40 +02:00
proddy
fb6b8813c7 add web page for modules 2024-05-29 22:23:01 +02:00
proddy
3fa42be6d4 update core 3.0 2024-05-29 22:22:54 +02:00
proddy
5daa76649b add comment 2024-05-29 22:22:39 +02:00
proddy
fdad5973c3 rename setup() to start() for module 2024-05-28 12:10:10 +02:00
proddy
4cce16b168 remove arduinojson defines 2024-05-28 12:06:02 +02:00
proddy
5fceca38d9 add module's loop to loop() 2024-05-27 22:16:10 +02:00
proddy
38d22fd587 update comments 2024-05-27 22:15:53 +02:00
proddy
bb1d2d6680 getMacAddress() 2024-05-27 22:15:33 +02:00
proddy
bcb78ee4d2 add getMacAddress, used in Modules 2024-05-27 22:15:21 +02:00
proddy
b0d3a2204a update to use external Modules 2024-05-27 22:15:08 +02:00
proddy
29da1b646a use online version of ArduinoJson 2024-05-27 22:14:53 +02:00
proddy
20063d48ed update modules 2024-05-26 16:06:18 +02:00
Proddy
8ffed9fab7 Merge pull request #1769 from proddy/dev
small updates
2024-05-18 09:35:30 +02:00
Proddy
c8b0e07203 Merge branch 'emsesp:dev' into dev 2024-05-18 09:35:02 +02:00
proddy
98fbb2b926 fix type in setAuthentication 2024-05-18 09:33:03 +02:00
proddy
bd42b4539e update espressif v3 target 2024-05-18 09:32:42 +02:00
proddy
4975771f28 add comment 2024-05-18 09:32:18 +02:00
proddy
dd7456cdd5 espressif32@6.7.0 2024-05-18 08:56:34 +02:00
proddy
2cfdd12168 bump to 3.7.0-dev.11 2024-05-18 08:56:23 +02:00
proddy
e00284deb1 package update 2024-05-18 08:56:09 +02:00
proddy
43476f41df typesafe format for numbers 2024-05-18 08:55:59 +02:00
proddy
e87ad5db2d don't render list if no device selected 2024-05-18 08:55:39 +02:00
proddy
825d8b57a4 summerTemp to 45 - #1767 2024-05-18 08:55:20 +02:00
Proddy
ab9241376b Merge pull request #1763 from MichaelDvP/dev
fix missing vacation date #1712
2024-05-14 11:52:13 +02:00
MichaelDvP
0f13449548 fix missing vacation date #1712 2024-05-14 07:37:04 +02:00
Proddy
0b498633d3 Merge pull request #1762 from MichaelDvP/dev
fix timout switchoff #1680
2024-05-13 08:01:28 +02:00
MichaelDvP
f080107d86 fix timout switchoff #1680 2024-05-13 07:15:12 +02:00
Proddy
9acaf41564 Merge pull request #1761 from Bingo2023/patch-1 2024-05-10 18:23:23 +02:00
Bingo2023
d1f14ac298 #1443
#1443
2024-05-10 16:29:31 +02:00
Proddy
f8050f3638 Merge pull request #1759 from MichaelDvP/dev 2024-05-10 15:15:39 +02:00
MichaelDvP
4f6399f35e timeout 3h for remote temperature #1680 2024-05-10 14:45:05 +02:00
Proddy
24af84f27c Merge pull request #1753 from proddy/dev
add corepack to tagged release
2024-05-08 20:43:05 +02:00
proddy
c481bc78dc add corepack to tagged release 2024-05-08 20:42:01 +02:00
Proddy
11e887553d Update pre_release.yml 2024-05-08 20:30:46 +02:00
Proddy
ff3dad26db Merge pull request #1752 from proddy/dev
enable corepack
2024-05-08 20:26:58 +02:00
proddy
708b7f384d enable corepack 2024-05-08 20:26:18 +02:00
Proddy
24dc7489da Merge pull request #1751 from proddy/dev
add back commented web build (was mistake)
2024-05-08 20:11:09 +02:00
proddy
7a4476d302 add back commented web build (was mistake) 2024-05-08 20:10:34 +02:00
Proddy
2e1b57dcdd Merge pull request #1750 from proddy/dev
yarn updates
2024-05-08 19:59:42 +02:00
proddy
52c045e839 update packages 2024-05-08 19:58:53 +02:00
proddy
2f015d940f tidy up yarn 2024-05-08 11:19:37 +02:00
proddy
c5f88daa29 remove unused icon 2024-05-08 11:19:25 +02:00
proddy
e279de4474 update example 2024-05-08 11:19:01 +02:00
Proddy
660bc633da Merge pull request #1748 from MichaelDvP/dev
dhw tag in HA format 3.4, fix #1747
2024-05-07 17:37:15 +02:00
MichaelDvP
b51b751e53 dhw tag in HA format 3.4, fix #1747 2024-05-07 17:20:39 +02:00
Proddy
3bd0567f52 Merge pull request #1746 from MichaelDvP/dev
ipv6 permanent, shutdown command (fixed)
2024-05-07 10:14:05 +02:00
MichaelDvP
bbe4d35f26 update yarn-4.2.1 2024-05-07 07:22:16 +02:00
MichaelDvP
de16f9a585 fix crash on shutdown command register 2024-05-06 21:55:36 +02:00
MichaelDvP
628083101c Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-05-06 16:51:27 +02:00
MichaelDvP
39b2148609 make shutdown to type:CMD 2024-05-06 13:48:19 +02:00
MichaelDvP
4f40e2457a permanent enable IPv6 support 2024-05-06 13:47:51 +02:00
MichaelDvP
fa6649d57e heap check for HA mqtt-configs, debug-log the numbers of configs sent. 2024-05-06 12:46:05 +02:00
Proddy
9f4aef6d40 Merge pull request #1743 from proddy/dev
move esp status from settings page
2024-05-05 17:53:21 +02:00
proddy
837d70e79d rename Application Settings 2024-05-05 17:16:59 +02:00
proddy
4a1319d95a move esp status to under status (not in settings) 2024-05-05 17:16:31 +02:00
proddy
24c7238a8b updated example 2024-05-05 17:16:06 +02:00
Proddy
d829850fc9 Merge pull request #1742 from proddy/dev
move restart button to System menu
2024-05-05 13:02:03 +02:00
proddy
e87de4bd17 add back babel-core 2024-05-05 13:01:18 +02:00
proddy
85c249db2a move restart to system 2024-05-05 12:58:45 +02:00
proddy
d45fa55f66 remove blur 2024-05-05 12:58:34 +02:00
Proddy
8084b9141d Merge pull request #1741 from MichaelDvP/dev
rego holiday and fix command with command as value, dev-10
2024-05-05 09:52:07 +02:00
MichaelDvP
f44bd81fd9 fix command with command as value, #1740 2024-05-05 09:15:54 +02:00
MichaelDvP
2bd14e5648 v3.7.0-dev.10 2024-05-04 19:39:24 +02:00
MichaelDvP
8c627a2ade Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-05-04 19:39:00 +02:00
Proddy
43777f4a15 Merge pull request #1739 from proddy/dev
Remove OTA feature #1738
2024-05-04 18:56:57 +02:00
proddy
98839015fa updated screenshot with removed ota 2024-05-04 14:32:17 +02:00
proddy
dabb958f06 Remove OTA feature #1738 2024-05-04 14:19:19 +02:00
proddy
6537abedb9 formatting 2024-05-04 14:18:47 +02:00
proddy
42cbacd07c add comments 2024-05-04 14:18:27 +02:00
proddy
2112f1916f formatting 2024-05-04 14:17:35 +02:00
proddy
a2e2cf7f75 add test for signin 2024-05-04 14:17:16 +02:00
proddy
f14523d7aa add python venv 2024-05-04 14:16:53 +02:00
proddy
a58706ef41 formatting 2024-05-04 14:16:16 +02:00
proddy
5af16b7b7e formatting 2024-05-04 14:16:04 +02:00
proddy
71eea5abb3 add comment to source of library 2024-05-04 14:15:48 +02:00
proddy
e8241e580b package update 2024-05-04 14:15:32 +02:00
MichaelDvP
9a2d635c62 fix date format 2024-05-04 13:32:04 +02:00
MichaelDvP
e84bf9a181 add rego3000 holiday, dev9, update pkg 2024-05-04 12:49:33 +02:00
Proddy
8c88c2ec38 Merge pull request #1736 from MichaelDvP/dev
some more id/tag changes
2024-05-03 14:01:20 +02:00
MichaelDvP
f54b6959ab tagged_cmd use const string & 2024-05-03 11:53:09 +02:00
MichaelDvP
1fa6da8eff avoid compiler warning, add back RC30 pause/party 2024-05-03 11:52:24 +02:00
MichaelDvP
ee2fded5de cleanup id/tag 2024-05-03 11:51:29 +02:00
Proddy
35ee3776ca Merge pull request #1733 from MichaelDvP/dev
fix show commands, add hp input states
2024-05-03 09:44:27 +02:00
MichaelDvP
7cec0e58a1 fix length of vacation string 2024-05-03 09:37:50 +02:00
MichaelDvP
476c8de82f update packages 2024-05-03 08:31:43 +02:00
MichaelDvP
3a772a0dbf sync tag and id, add RC30 vacation #1712 2024-05-03 08:31:20 +02:00
MichaelDvP
d056846eb0 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-05-02 13:52:35 +02:00
MichaelDvP
65d9c2d5d3 remove redundant dhw suffixes, add to HA v3.6 compatibility modes, dev8 2024-05-02 12:00:16 +02:00
MichaelDvP
0598f0d679 add hp input states #1723 2024-05-02 11:14:50 +02:00
MichaelDvP
961f61d48d fix show commands/api/<device>/commands, rename CommandFlags 2024-05-02 08:57:55 +02:00
Proddy
cce76c1769 Merge pull request #1731 from proddy/dev
fix unbuild flag
2024-05-01 22:29:34 +02:00
proddy
dc68258e8c fix compile unbuild flags 2024-05-01 22:28:52 +02:00
proddy
d5675e24e7 formatting 2024-05-01 22:27:12 +02:00
proddy
ad73fba36e package update 2024-05-01 22:27:04 +02:00
Proddy
14af4a0680 Merge pull request #1730 from MichaelDvP/dev
fix thermostat dhw commands #1692
2024-04-30 14:38:29 +02:00
MichaelDvP
1af43a8397 fix thermostat dhw commands 2024-04-30 13:10:01 +02:00
Proddy
9ed554bef7 Merge pull request #1729 from proddy/dev
Dump Telegrams - #1728
2024-04-29 20:59:16 +02:00
proddy
5f77fd7f40 remove is_received from dump 2024-04-29 20:57:56 +02:00
proddy
dcedd75ea1 package update 2024-04-29 20:57:45 +02:00
proddy
543cfc921e https://github.com/emsesp/EMS-ESP32/issues/1728 2024-04-29 20:31:16 +02:00
proddy
c12c7845bf update with 3.7.0-dev.7 2024-04-29 20:30:37 +02:00
proddy
34d2f7fa27 package update 2024-04-29 20:23:21 +02:00
proddy
74c672afab remove comment 2024-04-29 20:08:15 +02:00
Proddy
5da07db42d Merge pull request #1727 from MichaelDvP/dev
fix compile for S3
2024-04-29 16:58:38 +02:00
MichaelDvP
b6db8767e5 fix compile for S3 2024-04-29 15:35:53 +02:00
Proddy
dfe56618f2 Merge pull request #1726 from MichaelDvP/dev
Compile with arduino 3.0
2024-04-29 14:11:06 +02:00
MichaelDvP
0e69ffa7bf set hc->control on command, don't wait for verify 2024-04-29 14:02:32 +02:00
MichaelDvP
b034bd05e8 Compile with arduino 3.0 2024-04-29 13:53:00 +02:00
Proddy
abbf2e091b Merge pull request #1722 from proddy/dev
small changes
2024-04-29 13:09:30 +02:00
proddy
0b8d8eb7a0 fix https://github.com/emsesp/EMS-ESP32/pull/1722#discussion_r1582823521 2024-04-29 13:09:12 +02:00
proddy
87f05df375 Rego3000 https://github.com/emsesp/EMS-ESP32/issues/1692 2024-04-28 14:39:23 +02:00
proddy
80915cb7b2 rename auxElecHeatNrgConsWw (code only) 2024-04-28 14:38:41 +02:00
proddy
7199fae4fa rename auxElecHeatNrgConsWw 2024-04-28 14:38:16 +02:00
proddy
9e72bef480 show help text for add command 2024-04-28 14:38:01 +02:00
proddy
ecc625cca4 add target for latest Arduino v3 RC1 2024-04-27 14:00:05 +02:00
proddy
9b47cf0e0e add ipv6 support for arduino v3 2024-04-27 13:59:43 +02:00
proddy
e43b7dec1b added back prettierignore so vscode can find it 2024-04-27 13:01:22 +02:00
proddy
b149fb2e4d update packages 2024-04-27 13:01:04 +02:00
proddy
c07dc899de added LanguageSelector 2024-04-27 13:00:32 +02:00
proddy
9252093fb6 cleaned up formatting 2024-04-27 13:00:11 +02:00
Proddy
13e7a53e5e Merge pull request #1721 from proddy/dev
progress bar and PL fixes
2024-04-26 20:40:25 +02:00
proddy
7973c3d4a8 rollback PL translations for User type 2024-04-26 20:39:37 +02:00
Proddy
444bd67f07 Merge branch 'emsesp:dev' into dev 2024-04-26 20:33:59 +02:00
Proddy
aeb10aa6ab Merge pull request #1718 from pswid/dev
Polish translation update
2024-04-26 20:33:47 +02:00
proddy
56c9d3c265 bump 2024-04-26 20:33:08 +02:00
proddy
f2a6b861aa upload progress changes 2024-04-26 20:30:02 +02:00
Proddy
611f37bf2c Merge pull request #1719 from MichaelDvP/dev
Thermostat dhw, mqtt, ..
2024-04-26 12:37:53 +02:00
MichaelDvP
ed6a4ea1c1 thermostat hc check remove redundant code 2024-04-26 10:43:34 +02:00
MichaelDvP
13db893e4a Use warning level for scheduler command fails 2024-04-26 10:12:03 +02:00
MichaelDvP
3627dff3a1 update packages, alova 2.20.2 2024-04-26 10:11:13 +02:00
pswid
a3b0e37060 Polish translation update 2024-04-26 09:11:16 +02:00
MichaelDvP
a5f8a900b6 HA discovery topics for dhw compatibilty modes 2024-04-25 19:07:13 +02:00
MichaelDvP
6cc912fd5e fix val_tpl for 3wayvalve #1716 2024-04-25 18:14:31 +02:00
MichaelDvP
8b781da564 HA mqtt format multi with v3.6 compatiblity 2024-04-25 16:14:07 +02:00
MichaelDvP
634ee24a66 add stat_cla to temperaturesensor #1713 2024-04-25 16:12:36 +02:00
MichaelDvP
4f9a2fe1aa HA mqtt compatible setting 2024-04-25 14:32:42 +02:00
MichaelDvP
21488ad95a register thermostat dhw circuits dynamic 2024-04-25 14:32:19 +02:00
MichaelDvP
a28c2441a0 formatting 2024-04-25 14:31:47 +02:00
MichaelDvP
c4d2060cd9 update pkg 2024-04-25 14:31:26 +02:00
Proddy
3270139b01 Merge pull request #1711 from MichaelDvP/dev
small fixes, check second dhw circuit
2024-04-24 13:51:42 +02:00
MichaelDvP
696cfc0415 fix burnpower min>max, #1703 2024-04-24 07:56:29 +02:00
MichaelDvP
5ec68b85d2 add meters for gasboiler 2024-04-24 07:55:25 +02:00
MichaelDvP
355ff5656a fix auxheaterStatus #1160 2024-04-24 07:36:54 +02:00
MichaelDvP
85492781bc fix missing values (bool/enum/string) in dashboard 2024-04-23 15:26:38 +02:00
MichaelDvP
28347fd0a4 Read RC300 dhw2 circuit only if active 2024-04-23 08:50:14 +02:00
Proddy
b893b5d609 Merge pull request #1707 from MichaelDvP/dev
Rename DeviceValueTypes, add UINT32 for custom entities #1706
2024-04-22 19:06:36 +02:00
MichaelDvP
0dcd0bad68 add UINT32 to HA 2024-04-22 13:27:50 +02:00
MichaelDvP
d166b05c3c Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-04-22 13:14:24 +02:00
Proddy
01cd3c3587 Merge pull request #1705 from proddy/dev
web formatting
2024-04-21 21:53:04 +02:00
MichaelDvP
1027d403c5 update packages 2024-04-21 20:16:09 +02:00
MichaelDvP
719cd46a21 Rename DeviceValueTypes, add UINT32 for custom entities #1706 2024-04-21 20:14:39 +02:00
Proddy
66570e6f46 Merge branch 'dev' into dev 2024-04-21 15:29:19 +02:00
Proddy
cafa1cbc90 Merge pull request #1698 from MichaelDvP/dev
dhw circuits, fixes for remote, new entities
2024-04-21 15:11:03 +02:00
proddy
ac39a46442 formatting 2024-04-21 15:10:22 +02:00
proddy
befa487482 use alova 2.19.2 since 2.20 breaks upload progress bar 2024-04-21 15:10:10 +02:00
proddy
43606e151a dont format i18n files 2024-04-21 15:09:32 +02:00
MichaelDvP
0eb04b9027 fix coldshot command with dhw tag, restart coldshot timer 2024-04-21 10:39:17 +02:00
MichaelDvP
8c7b0a674f check fetch for custom entities for multibyte split 2024-04-21 10:37:41 +02:00
MichaelDvP
ed317902ca custom min/max have priority #1703 2024-04-21 10:36:36 +02:00
proddy
8bcfd9b86f remove admin authentication on log 2024-04-20 21:50:30 +02:00
proddy
b68805e078 rename Customize to Module 2024-04-20 20:51:43 +02:00
proddy
9dc91f2d69 new linting, make sure code is type safe 2024-04-20 20:46:01 +02:00
MichaelDvP
037175f7b0 show incomplete Rx with crc 2024-04-19 09:25:50 +02:00
MichaelDvP
010ca2f2ab fix log entry shower duration 2024-04-19 09:25:16 +02:00
MichaelDvP
37ce3047cb show telegram read length in log decimal 2024-04-18 09:27:56 +02:00
MichaelDvP
0114899944 fix incompletes when using remote emulation 2024-04-17 08:27:38 +02:00
proddy
ae7cd23758 package update 2024-04-15 22:11:22 +02:00
proddy
1966a68638 always show devices even in test 2024-04-15 22:11:22 +02:00
MichaelDvP
c58baf3fec fix typo 7F->F7 2024-04-15 14:05:42 +02:00
MichaelDvP
c60254b624 add back poll-ack for remote, add F7-02 reply 2024-04-15 12:32:23 +02:00
MichaelDvP
4d400bd7ce no poll-ack for remote thermostat 2024-04-15 09:08:05 +02:00
MichaelDvP
3c5790639e improve uart break timing 2024-04-14 17:08:01 +02:00
MichaelDvP
7b1845ed2e add fan example comment 2024-04-14 16:23:48 +02:00
MichaelDvP
e2569f5317 formatting, add heatpump shutdown 2024-04-13 18:16:10 +02:00
MichaelDvP
605c61cd29 changelog, ver 3.7.0-dev3 2024-04-13 16:50:50 +02:00
MichaelDvP
7e6ebb217a log telegrams F7/F9 with data in reads 2024-04-12 15:18:18 +02:00
MichaelDvP
6a16027e16 remote default to RC200, boiler reset command 2024-04-12 13:07:53 +02:00
MichaelDvP
fc1b7becce remote send interval 15 sec 2024-04-12 11:35:29 +02:00
MichaelDvP
8774ca5f7f fix multiple remotes, add RC100 2024-04-12 10:35:48 +02:00
MichaelDvP
adebc15939 Merge branch 'dev' into dev2 2024-04-12 09:13:32 +02:00
MichaelDvP
0df53b3856 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-04-12 09:10:11 +02:00
MichaelDvP
52704039ca remote emulation type for different hcs 2024-04-12 09:09:02 +02:00
MichaelDvP
d0f7d4ebbc test for +1691 2024-04-12 08:55:55 +02:00
MichaelDvP
8c6a45493b fix typo 2024-04-12 08:51:25 +02:00
Proddy
e095f6bd97 Merge pull request #1694 from proddy/dev
web testing cleanup + Tasmota Arduino Core 2.0.15 with IPv6 support, based on IDF 4.4.7 / core 2.0.15
2024-04-11 22:08:47 +02:00
proddy
0881262f4c package update 2024-04-11 22:07:11 +02:00
proddy
8080989005 Tasmota Arduino Core 2.0.15 with IPv6 support, based on IDF 4.4.7 / core 2.0.15 2024-04-11 22:06:55 +02:00
proddy
bfbc77c92e add standalone test for web uploading - https://github.com/emsesp/EMS-ESP32/issues/1564 2024-04-07 15:50:19 +02:00
MichaelDvP
5cda8f599b MM100 set telegram to 0x2CD,.. test for #1679 2024-04-03 18:23:53 +02:00
Proddy
85c8b663b1 Merge pull request #1685 from proddy/dev
fix test data (wrong icons in web)
2024-04-02 21:09:28 +02:00
proddy
f0f65c65dc fix test data (wrong icons) 2024-04-02 21:08:37 +02:00
proddy
e9e3594ee4 update packages 2024-04-02 21:08:28 +02:00
MichaelDvP
8c0d0c4468 shower wwtapactivated to dhw/tapactivated 2024-04-02 18:51:10 +02:00
MichaelDvP
f111c75e19 fix typo in api/mqtt command restart [partition] 2024-04-02 17:31:34 +02:00
MichaelDvP
6dde6580f3 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2024-03-31 18:22:21 +02:00
MichaelDvP
f21279056a DHW tags/nests for all devices, remove ww prefix from mqtt 2024-03-31 18:22:02 +02:00
Proddy
3359f87177 Merge pull request #1683 from proddy/dev
updated screenshots, faster log sync
2024-03-31 15:50:10 +02:00
proddy
09401c0524 3.7.0-dev.2 2024-03-31 15:49:09 +02:00
proddy
3135496f30 updated with latest devices 2024-03-31 15:48:25 +02:00
proddy
a28fd1484b mention 120 devices 2024-03-31 15:48:17 +02:00
proddy
4b4d7e40f0 updated screenshots for 3.7.x 2024-03-31 15:48:06 +02:00
proddy
bd78c07c80 remove splitVendorChunkPlugin 2024-03-31 15:22:36 +02:00
proddy
46c4dc8925 decrease sync time for log - Fix missing log entries in web #1652 2024-03-31 15:22:18 +02:00
Proddy
e02a731237 Merge pull request #1682 from proddy/dev
minor changes
2024-03-30 18:58:59 +01:00
proddy
2604368cf8 auto-formatting 2024-03-30 18:57:35 +01:00
proddy
9822aa6e13 update packages, add back eventstream testing 2024-03-30 18:57:20 +01:00
proddy
d8ff9da733 formatting 2024-03-30 18:56:40 +01:00
proddy
09e5231735 add translations 2024-03-30 18:56:23 +01:00
proddy
5ae837e9eb add translations 2024-03-30 18:56:16 +01:00
proddy
a3511724f3 remove initiating ES multiple times, may fix the collisions on slow networks 2024-03-30 18:56:10 +01:00
proddy
d9a5232293 add translations 2024-03-30 18:55:28 +01:00
proddy
b25cb244c0 remove ws 2024-03-30 18:54:53 +01:00
proddy
7bff76e553 added missing translations 2024-03-30 18:54:37 +01:00
proddy
90eda9f996 make standalone compile 2024-03-27 19:49:20 +05:30
proddy
52f605b118 lower ram when compiling multiple jobs 2024-03-27 19:49:09 +05:30
proddy
c7c17a4617 package update 2024-03-27 19:48:52 +05:30
proddy
973ee2fd43 3.7.0-dev.1 2024-03-27 19:48:37 +05:30
Proddy
cd2afd02be Merge pull request #1675 from MichaelDvP/dev2
update sk-language
2024-03-27 18:59:41 +05:30
MichaelDvP
07f8f9e704 update sk-language 2024-03-27 12:49:04 +01:00
Proddy
b7b09a8c93 Merge pull request #1674 from MichaelDvP/dev2
fix sk-language #1673, update pkg
2024-03-27 17:11:03 +05:30
MichaelDvP
8628bfa983 fix sk-language, update pkg 2024-03-27 11:34:49 +01:00
Proddy
8ef8eeb9ec Merge pull request #1672 from MichaelDvP/dev2
dev2 3.7.0-test, merge all changes from dev
2024-03-24 17:35:09 +01:00
MichaelDvP
765ddb6702 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev2 2024-03-24 10:03:20 +01:00
Proddy
6cab020241 Merge pull request #1670 from proddy/dev
fix minor lint warnings
2024-03-24 09:45:53 +01:00
proddy
cf489f7632 fix minor lint warnings 2024-03-24 09:45:12 +01:00
MichaelDvP
6943913d30 make factory partition default on 16M systems 2024-03-24 09:06:28 +01:00
MichaelDvP
c5eaebc4b4 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev2 2024-03-24 08:38:07 +01:00
Proddy
6905abf9f4 Merge pull request #1669 from proddy/dev
sync issues
2024-03-23 22:11:15 +01:00
proddy
ef3b8a308f update node 2024-03-23 22:07:04 +01:00
Proddy
8a66c056d8 Merge branch 'emsesp:dev' into dev 2024-03-23 19:24:29 +01:00
proddy
7967754024 3.7.0 2024-03-23 19:24:06 +01:00
Proddy
800528f843 Merge pull request #1667 from proddy/dev
changes to web layout (status and settings)
2024-03-23 19:18:59 +01:00
Proddy
a6a60215d4 Merge branch 'dev' into dev 2024-03-23 19:18:54 +01:00
proddy
0deaafb9ce fix NTP icons, add AP 2024-03-23 17:16:45 +01:00
proddy
2ab50bd0a2 fix incorrect link when clicking on version 2024-03-22 17:06:42 +01:00
proddy
ecb82bd48b tidy up 2024-03-22 17:03:10 +01:00
proddy
5592d18e1f button border is consistent across screens 2024-03-22 17:02:02 +01:00
proddy
bcfcc7690f fix uptime in seconds 2024-03-22 17:01:47 +01:00
proddy
a2fa2515b3 updates to backend to match new frontend - #1665 2024-03-22 16:25:18 +01:00
proddy
c8e7eb3657 always show bus status even if offline - #1666 2024-03-22 16:23:08 +01:00
proddy
24ea975575 added status and renamed components 2024-03-20 23:57:19 +01:00
proddy
863bc04c21 status screen updates 2024-03-19 23:25:31 +01:00
proddy
217b424320 updates to settng page 2024-03-18 21:59:11 +01:00
proddy
e022c34fe7 fix read-only access 2024-03-18 13:25:17 +01:00
proddy
1af103d5ee updates to web pages 2024-03-17 23:23:09 +01:00
proddy
20ddbeb709 rename User defined entities to 'Custom entities' 2024-03-17 19:08:50 +01:00
proddy
e1ad7d3c01 add vscode settings.json back in 2024-03-17 19:08:31 +01:00
proddy
8f7c65c9b5 update packages 2024-03-17 19:08:11 +01:00
proddy
9bf7fbfb2e #1665 2024-03-17 19:08:03 +01:00
MichaelDvP
fbfaea6b56 Merge branch 'dev' into dev2 2024-03-15 17:43:08 +01:00
MichaelDvP
21207f88f3 update packages 2024-03-15 17:06:36 +01:00
MichaelDvP
7ba330176a update packages 2024-03-07 11:38:00 +01:00
MichaelDvP
ab9caeba9c roomctrl: disable rf_sensor, set type with controlmode 2024-03-07 11:37:31 +01:00
MichaelDvP
7a5eeaa88a weblog refresh_sync to 80 ms 2024-03-07 11:12:26 +01:00
Proddy
bb3550810d Merge pull request #1647 from MichaelDvP/dev2
update testbuild to latest dev change
2024-03-02 10:54:20 +01:00
MichaelDvP
f77fb12c80 revert uart change, event.size not set for break. 2024-03-02 10:41:15 +01:00
MichaelDvP
f1342e4d62 Merge branch 'dev' into dev2 2024-02-29 15:06:05 +01:00
MichaelDvP
d09abc1b49 back to platform 24.01.00 2024-02-27 16:17:50 +01:00
Proddy
8c4fc495a3 Merge pull request #1639 from MichaelDvP/dev2
merge dev changes/fixes, new entities, env for N32R8 chip, fix custom board profile on boot
2024-02-27 08:26:58 +01:00
MichaelDvP
d8b77fc056 Merge branch 'dev' into dev2 2024-02-27 07:58:21 +01:00
MichaelDvP
a359618cca v.test.16, update changelog 2024-02-26 14:59:36 +01:00
MichaelDvP
20165a528d heatpump dhw stop temperatures #1624 2024-02-26 14:59:05 +01:00
MichaelDvP
3a23dae178 show in info and use for mqtt: heap_caps_get_free_size, #1622 2024-02-26 14:58:23 +01:00
MichaelDvP
e50d4fafb5 Slovak language fix #1636 2024-02-26 14:56:49 +01:00
MichaelDvP
673b4c2881 add env and partition for devKitC-1-N32R8, #1635 2024-02-26 14:56:18 +01:00
MichaelDvP
b676c4d164 fix thermostat wwc2 commands 2024-02-25 13:54:06 +01:00
MichaelDvP
40716f9c55 add RC300 wwc2 entities 2024-02-25 10:51:08 +01:00
MichaelDvP
df0210bfac update packages 2024-02-25 10:50:31 +01:00
MichaelDvP
41ac8120d0 16M partitions, second nvs 2024-02-24 18:32:20 +01:00
MichaelDvP
6a66c7def7 fix custom board profile on boot 2024-02-24 18:31:39 +01:00
MichaelDvP
3b0b6d75a7 uart check break first 2024-02-24 18:31:09 +01:00
MichaelDvP
292ed242c4 AsyncTCP queue 32 2024-02-24 18:30:38 +01:00
MichaelDvP
bb670e97ff add platform to system_info 2024-02-24 18:30:08 +01:00
MichaelDvP
87542fb9df update packages 2024-02-24 09:47:34 +01:00
Proddy
df982e3ea9 Merge pull request #1632 from MichaelDvP/dev2
update to all dev changes
2024-02-23 19:13:32 +01:00
MichaelDvP
222aaca218 store relais states in nvs 2024-02-23 10:00:15 +01:00
MichaelDvP
8a56c599e6 uart-isr to iram 2024-02-23 09:57:53 +01:00
MichaelDvP
003d3740af partitions: nvs: 20k, fs: 1M 2024-02-23 09:57:34 +01:00
MichaelDvP
74342ba654 Merge branch 'dev' into dev2 2024-02-23 08:56:43 +01:00
MichaelDvP
0010f71a3c uart in iram 2024-02-19 09:56:54 +01:00
MichaelDvP
38a546d6f7 remotetemp with RC200 v32.02, version as 10 byte telegram., fix #1622 2024-02-17 18:32:29 +01:00
MichaelDvP
4346de27b6 remote thermostat 30 sec interval, update packages 2024-02-16 13:41:30 +01:00
MichaelDvP
d797c3371b Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev2 2024-02-15 09:08:01 +01:00
MichaelDvP
ce33fa6535 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev2 2024-02-10 17:25:50 +01:00
MichaelDvP
c2be9b210e GPIO check, typo and missing platform 2024-02-10 14:35:53 +01:00
MichaelDvP
464341c2cb DHW meter for heatpump #1609, test remote RF sensor 2024-02-09 09:13:55 +01:00
MichaelDvP
f765d7c31b update packages 2024-02-09 09:02:26 +01:00
MichaelDvP
72b64a0c30 arduino 3.0 adapt for tasmota <=2024.01.10, not compatble with new IP6Address 2024-02-08 21:42:13 +01:00
MichaelDvP
2b88fec2ee check valid pins for board_profile and analog 2024-02-08 18:52:27 +01:00
MichaelDvP
119b2b9514 RC100H emulation version and telegrams 2024-02-08 18:51:45 +01:00
MichaelDvP
4f406e8d33 update packages 2024-02-08 18:47:46 +01:00
MichaelDvP
0d80f58ea6 AsyncWebServer arduino3.0 compatible 2024-02-08 18:39:15 +01:00
MichaelDvP
6c7a3ad68c update esp32 platform 2024-02-08 17:42:35 +01:00
MichaelDvP
52a8b20c54 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev2 2024-02-06 19:30:24 +01:00
MichaelDvP
5213382246 add #1609 dhw energy meter and some thermostat junkers settings 2024-02-06 19:25:14 +01:00
MichaelDvP
0b452ddd39 use FB10 telegram 0x123, ack writes 2024-02-05 13:24:35 +01:00
MichaelDvP
355c7cbd92 fix ht3-reply 2024-02-05 08:52:29 +01:00
MichaelDvP
6564e444ab thermostat emulation check ht3 adddress 2024-02-05 07:33:52 +01:00
MichaelDvP
51b0a0ae5b Junkers FB10 telegram-id 2024-02-04 20:14:21 +01:00
MichaelDvP
faa888ff36 remote emulation FB10, #1602 2024-02-04 14:38:34 +01:00
MichaelDvP
b834c8fd89 Merge branch 'dev' into dev2 2024-02-03 18:38:34 +01:00
Proddy
ef47ee62a3 Merge pull request #1592 from MichaelDvP/dev2
update dev2 to latest dev changes
2024-01-30 20:38:49 +01:00
MichaelDvP
5532d20657 update packages 2024-01-30 07:47:42 +01:00
MichaelDvP
b7ce69ee2d map RFM200/T1RF to connect/extension 2024-01-30 07:42:57 +01:00
MichaelDvP
00b3525503 show sensor command commands 2024-01-30 07:41:49 +01:00
MichaelDvP
1065c9eec9 translations 2024-01-30 07:41:17 +01:00
MichaelDvP
8d3dd9d8e9 Merge branch 'dev' into dev2 2024-01-30 07:31:00 +01:00
MichaelDvP
ce6e89338f reset wait_validate 2024-01-28 12:15:16 +01:00
MichaelDvP
52bb6b8218 Merge branch 'dev' into dev2 2024-01-28 11:35:43 +01:00
MichaelDvP
5748bd4074 Merge branch 'dev' of https://github.com/MichaelDvP/EMS-ESP32 into dev 2024-01-28 11:31:42 +01:00
MichaelDvP
542246c142 hpPressure telegram 2024-01-28 09:03:22 +01:00
MichaelDvP
31bea94d9c fetch mixer 0x2CC 2024-01-28 08:41:02 +01:00
MichaelDvP
5669deeb80 fix jsonvariant in command 2024-01-28 08:40:38 +01:00
MichaelDvP
1042298541 add brackets to make logic clear 2024-01-24 11:10:16 +01:00
MichaelDvP
6aca61deee typo, telegram name for pretty telegram 2024-01-24 07:44:20 +01:00
MichaelDvP
9266454f82 rework process telegram 2024-01-23 13:47:28 +01:00
Proddy
89da6d5851 Merge pull request #1574 from MichaelDvP/dev2
Update dev2 to latest changes of dev
2024-01-21 10:18:10 +01:00
MichaelDvP
1491f283a8 update packages 2024-01-21 09:35:26 +01:00
MichaelDvP
a8c3b21ee6 Merge branch 'dev' into dev2 2024-01-21 09:35:16 +01:00
MichaelDvP
e88ede2d8b typo 2024-01-20 08:29:17 +01:00
MichaelDvP
6c398109f4 Mixer set message to 0x2CD, .. 2024-01-14 10:20:54 +01:00
MichaelDvP
74691ce34a roomctrl RC200 version with 2.id 2024-01-13 15:43:31 +01:00
MichaelDvP
ef6ac3848f mixer telegram 0x2CC, #1554 2024-01-13 15:36:01 +01:00
MichaelDvP
5c490834cf fix telegram length check of remote 2024-01-13 13:25:25 +01:00
MichaelDvP
7b4f76d51d remote type depends on control setting 2024-01-12 10:42:16 +01:00
MichaelDvP
16010b2223 remote use RC200 for hc3/4 2024-01-12 09:50:21 +01:00
MichaelDvP
ea2d5b77c0 use RC100H again for remote 2024-01-11 18:24:46 +01:00
MichaelDvP
81b0b77e2b type-ids RemoteCorrection/Batterie device dependend 2024-01-11 17:34:24 +01:00
MichaelDvP
af1209cb04 fix roomctrl for hc>1 2024-01-11 07:55:07 +01:00
MichaelDvP
b6ec8e14ec remote emulation RC200 for hc3/4 instead of RC100H 2024-01-10 18:32:23 +01:00
MichaelDvP
63cf4bdc21 remote thermostat for hc3 at 0x1A 2024-01-09 10:51:59 +01:00
MichaelDvP
8ddc167f93 Merge branch 'dev' into dev2 2024-01-08 11:26:17 +01:00
MichaelDvP
54d2f38841 Merge branch 'dev2' of https://github.com/emsesp/EMS-ESP32 into dev2 2024-01-08 11:26:07 +01:00
Proddy
f25ab5f293 Merge pull request #1543 from MichaelDvP/dev2
Update dev2 to latest changes from dev
2024-01-06 17:13:03 +01:00
MichaelDvP
025f43953a Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev2 2024-01-06 16:36:01 +01:00
MichaelDvP
e8217b68a5 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev2 2024-01-04 11:53:38 +01:00
MichaelDvP
ebfe487a3a add Bosch C1200 boiler id 12 2024-01-04 11:43:49 +01:00
MichaelDvP
ce34567939 another test wwComfort 2024-01-04 11:43:29 +01:00
MichaelDvP
a81695e973 Merge branch 'dev2' of https://github.com/emsesp/EMS-ESP32 into dev2 2024-01-03 08:04:42 +01:00
MichaelDvP
8d1a36c669 wwcomfort on ems+ 2024-01-03 08:04:20 +01:00
Proddy
77700c4873 Merge pull request #1525 from Bingo2023/dev2
Dev2 - corrected mode control for HA (including translations).
2023-12-28 07:48:01 +01:00
Bingo2023
d035a29f24 // corrected mode control for HA (including translations).
modified:   src/mqtt.cpp
2023-12-23 14:14:20 +01:00
Bingo2023
4c51b90663 modified: src/mqtt.cpp 2023-12-22 20:02:12 +01:00
MichaelDvP
ddd1f5de5b Merge branch 'dev' into dev2 2023-12-19 18:35:10 +01:00
MichaelDvP
e2544947f7 sk-translation 2023-12-18 10:47:58 +01:00
MichaelDvP
854a39fe6b ethernet working with arduino_3.0 2023-12-17 12:35:07 +01:00
MichaelDvP
a684a46404 Merge branch 'dev' into dev2 2023-12-14 07:59:01 +01:00
Proddy
b29c36d01d Merge pull request #1500 from MichaelDvP/dev2
Testbild keep up to date with dev
2023-12-13 11:52:18 +01:00
MichaelDvP
a0e1894262 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev2 2023-12-13 07:24:06 +01:00
MichaelDvP
29a3e79804 Merge branch 'dev' into dev2 2023-12-12 14:41:31 +01:00
MichaelDvP
72f4d00cb3 Merge branch 'dev' into dev2 2023-12-09 15:41:03 +01:00
MichaelDvP
8453422c9c Merge branch 'dev' into dev2 2023-12-08 19:15:41 +01:00
Proddy
d81b833951 Merge pull request #1490 from MichaelDvP/dev2
fix RC300 mode, #1488
2023-12-08 11:53:36 +01:00
MichaelDvP
510602e117 fix RC300 mode, #1488 2023-12-08 11:34:20 +01:00
Proddy
4008883627 Merge pull request #1482 from MichaelDvP/dev2
Testbuild
2023-12-04 20:28:49 +01:00
MichaelDvP
4081a55207 Merge branch 'dev' into dev2 2023-12-04 17:39:29 +01:00
MichaelDvP
1845d5060a add hpMaxPower 2023-12-04 17:11:40 +01:00
MichaelDvP
ad577eaa2a Merge branch 'dev' into dev2 2023-12-03 18:24:06 +01:00
MichaelDvP
0d4607a922 send "step" as string 2023-11-29 11:55:27 +01:00
MichaelDvP
067100d375 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev2 2023-11-29 07:12:41 +01:00
MichaelDvP
9118cd7c5b init for second exhaustTemp value (test.0c) 2023-11-28 17:54:47 +01:00
MichaelDvP
8b0cf599f4 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev2 2023-11-27 07:34:24 +01:00
MichaelDvP
7d6bb6b9c8 add meter heating 0x4AF, offset 24 2023-11-26 11:06:28 +01:00
MichaelDvP
2a6fedc6b3 hetpump energy meters, sync with HP id 0x08 2023-11-26 09:11:46 +01:00
MichaelDvP
e3a7e9fe33 Merge branch 'dev' into dev2 2023-11-26 09:03:58 +01:00
MichaelDvP
548fdd823b version 2023-11-25 15:50:42 +01:00
MichaelDvP
2b486ffa36 revert package update 2023-11-24 13:23:33 +01:00
MichaelDvP
c3f9d9ddd6 Merge branch 'dev2' of https://github.com/MichaelDvP/EMS-ESP32 into dev2 2023-11-24 10:44:44 +01:00
MichaelDvP
740f3b4ef7 Merge branch 'dev' into dev2 2023-11-24 10:28:38 +01:00
MichaelDvP
932a496f47 revert to react-router-dom 6.19.0 to fix tab-routing-issue 2023-11-24 10:15:34 +01:00
MichaelDvP
60beeddb66 HIU heating/tapwater-active, always use EMSdevice:: for flags 2023-11-23 17:30:38 +01:00
MichaelDvP
c61c34f10e HIU heating/tapwater-active, always use EMSdevice:: for flags 2023-11-23 17:24:40 +01:00
MichaelDvP
96a04da1ff add settings for #1389 2023-11-23 15:27:38 +01:00
MichaelDvP
bd8472b34e fix settings for EMS boilers 2023-11-23 15:26:00 +01:00
MichaelDvP
09228e4637 update MqttClient 2023-11-23 09:23:04 +01:00
MichaelDvP
40a79c51ce add EMS_DEVICE_FLAG_BC400, sort wwmodes #1452 2023-11-22 19:45:06 +01:00
MichaelDvP
2edfe0f42c add hpPumpMode #1449 2023-11-22 07:37:40 +01:00
MichaelDvP
a2eb8dfe83 update packages 2023-11-22 07:37:32 +01:00
MichaelDvP
4c60545057 Merge branch 'dev' into dev2 2023-11-22 07:10:31 +01:00
MichaelDvP
d06b3285bd Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2023-11-21 21:58:59 +01:00
MichaelDvP
4dcfe8e0f6 get mode for seltemp, fix #1450 2023-11-21 21:58:10 +01:00
MichaelDvP
42e679d5ba Merge branch 'dev2' of https://github.com/emsesp/EMS-ESP32 into dev 2023-11-21 11:32:31 +01:00
MichaelDvP
4db1c7dfca add boostmode/time #1446 2023-11-21 11:25:25 +01:00
MichaelDvP
64fb84dd54 Merge branch 'dev' into dev2 2023-11-21 11:24:04 +01:00
MichaelDvP
a17a9b71a2 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev2 2023-11-18 13:49:53 +01:00
MichaelDvP
0a10e78bfd Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev2 2023-11-16 09:14:25 +01:00
MichaelDvP
50777bd681 temporary fix for values/info command 2023-11-15 19:11:59 +01:00
Proddy
2f5558c311 Merge pull request #1429 from proddy/dev2
in sync with dev
2023-11-15 18:23:19 +01:00
Proddy
21c3fe5d8e in sync with dev 2023-11-15 18:22:12 +01:00
MichaelDvP
acb453bd4b fix water: retValve and circ time control 2023-11-15 18:13:43 +01:00
MichaelDvP
9c6b9a5359 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev2 2023-11-15 11:27:19 +01:00
MichaelDvP
0d07a9e50c add some water entities 2023-11-15 11:26:45 +01:00
MichaelDvP
f9e1940c7b fix crash on entering wrong day for switchtime 2023-11-14 18:11:32 +01:00
MichaelDvP
72c0625823 Merge branch 'dev2x' into dev2 2023-11-14 10:57:43 +01:00
MichaelDvP
6926f6fd0b Merge branch 'dev2' of https://github.com/emsesp/EMS-ESP32 into dev2 2023-11-14 10:07:19 +01:00
MichaelDvP
e30c476e5c Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev2 2023-11-13 19:52:50 +01:00
MichaelDvP
509122bf4b fix RC300 wwdisinfectTime 2023-11-13 19:29:03 +01:00
MichaelDvP
84fab951ba fix RC300 summertemp, mode 2023-11-13 18:01:14 +01:00
MichaelDvP
f34be2a884 test for fixing #1420 2023-11-13 13:59:30 +01:00
MichaelDvP
bed1650350 Merge branch 'dev2x' into dev2 2023-11-13 13:57:05 +01:00
MichaelDvP
1f8a477939 RC300/BC400 mode setting 2023-11-13 13:54:13 +01:00
MichaelDvP
6699d9ad80 Merge branch 'dev2x' into dev2 2023-11-12 14:32:03 +01:00
MichaelDvP
253eb72dbf Merge branch 'dev2x' into dev2 2023-11-12 13:55:14 +01:00
MichaelDvP
fe772f85bf Merge branch 'dev2x' into dev2 2023-11-12 11:42:18 +01:00
MichaelDvP
0e55caf721 Merge branch 'dev2x' into dev2 2023-11-11 14:36:04 +01:00
MichaelDvP
434ef2b333 Merge branch 'dev2x' into dev2 2023-11-11 14:33:19 +01:00
MichaelDvP
e0ab208c52 fix retTemp, #1334 2023-11-11 14:10:49 +01:00
MichaelDvP
5b1f3d266e Merge branch 'dev2' of https://github.com/emsesp/EMS-ESP32 into dev2 2023-11-11 13:52:22 +01:00
MichaelDvP
4c83f5fe60 sort water entities 2023-11-11 13:47:32 +01:00
MichaelDvP
2f658a9a14 add boiler wwSelTempEcoplus 2023-11-08 14:18:28 +01:00
MichaelDvP
c3f487eced update packages 2023-11-07 12:49:46 +01:00
MichaelDvP
a8a12dd1f8 check second servicecode-char for nonascii 0xF0. 2023-11-07 11:44:37 +01:00
MichaelDvP
7f7e3c47ec Merge branch 'dev' of https://github.com/proddy/EMS-ESP32 into dev2 2023-11-07 07:20:08 +01:00
MichaelDvP
eafeb5c5d2 Merge branch 'dev2' of https://github.com/proddy/EMS-ESP32 into dev2 2023-11-07 07:15:43 +01:00
MichaelDvP
caca8bf802 fix 4-way-valve enum 2023-11-07 07:10:49 +01:00
MichaelDvP
338091578b wwEcoPlus, rename some water entities 2023-11-07 07:06:05 +01:00
MichaelDvP
188bfa4525 add hp 4-way valve 2023-11-05 15:57:02 +01:00
MichaelDvP
037a9848bc version 3.6.3-dev.6c 2023-11-05 14:24:39 +01:00
MichaelDvP
b6543169de boiler add input states, remove redundant activity states 2023-11-05 14:23:40 +01:00
MichaelDvP
14b3b058fe remove unused water values temp_2, temp_6 2023-11-05 14:22:37 +01:00
MichaelDvP
fa4763309d merge pl translations 2023-11-05 14:21:56 +01:00
MichaelDvP
adcc59642c cleanup publishing 2023-11-05 14:20:13 +01:00
MichaelDvP
d18fd4948c update packages 2023-11-05 14:19:46 +01:00
MichaelDvP
4e4258f9dc enlarge tx queue to 100 2023-11-04 18:56:49 +01:00
MichaelDvP
ab6cf78822 warning in log on tx-queue overflow 2023-11-04 18:17:33 +01:00
MichaelDvP
d105c18bf7 fix typos, double entities, publish time water 2023-11-04 17:00:33 +01:00
MichaelDvP
6bbf4e4778 Merge branch 'dev2' of https://github.com/emsesp/EMS-ESP32 into dev2 2023-11-04 15:25:50 +01:00
MichaelDvP
3101f5e6ae move dhw entities from mixer/solar to new water device, add pool device 2023-11-04 15:24:43 +01:00
724 changed files with 79129 additions and 65929 deletions

View File

@@ -0,0 +1,27 @@
{
"name": "EMS-ESP Devcontainer",
"image": "mcr.microsoft.com/devcontainers/typescript-node:1-22-bookworm",
"features": {
"ghcr.io/devcontainers/features/node:1": {},
"ghcr.io/devcontainers-extra/features/pnpm:2": {},
"ghcr.io/devcontainers/features/python:1": {},
"ghcr.io/shyim/devcontainers-features/bun:0": {}
},
"forwardPorts": [
3000,
3080
],
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "cd mock-api && pnpm install && cd .. && cd interface && pnpm install",
// Configure tool-specific properties.
"customizations": {
"vscode": {
"extensions": [
"platformio.platformio-ide"
]
}
}
}

132
.github/CODE_OF_CONDUCT.md vendored Normal file
View File

@@ -0,0 +1,132 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0].
Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available
at [https://www.contributor-covenant.org/translations][translations].
[homepage]: https://www.contributor-covenant.org
[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations

View File

@@ -1,32 +1,32 @@
---
name: Problem Report
name: Problem Report/Change Request
about: Create a Report to help us improve
---
<!-- Thanks for reporting a problem for this project. READ THIS FIRST:
<!-- Thanks for reporting an issue for this project. READ THIS FIRST:
Please DO NOT OPEN AN ISSUE if your EMS-ESP version is not the latest from the dev branch, please update your device before submitting your issue. Your problem might already be solved. The latest precompiled binaries of EMS-ESP can be downloaded from https://github.com/emsesp/EMS-ESP32/releases/tag/latest
Please DO NOT OPEN AN ISSUE if your EMS-ESP version is not the latest from the dev branch, please update your device before submitting your issue. Your issue might already be solved. The latest precompiled binaries of EMS-ESP can be downloaded from https://github.com/emsesp/EMS-ESP32/releases/tag/latest
Please take a few minutes to complete the requested information below.
-->
### PROBLEM DESCRIPTION
### DESCRIPTION
_A clear and concise description of what the problem is._
_A clear and concise description of what the problem is or the change requested._
### REQUESTED INFORMATION
_Make sure your have performed every step and checked the applicable boxes before submitting your issue. Thank you!_
- [ ] Searched the problem in [issues](https://github.com/emsesp/EMS-ESP32/issues)
- [ ] Searched the problem in [discussions](https://github.com/emsesp/EMS-ESP32/discussions)
- [ ] Searched the problem in the [docs](https://emsesp.github.io/docs/Troubleshooting/)
- [ ] Searched the problem in the [chat](https://discord.gg/3J3GgnzpyT)
- [ ] Provide the output of http://ems-esp.local/api/system :
- [ ] Searched the issue in [issues](https://github.com/emsesp/EMS-ESP32/issues)
- [ ] Searched the issue in [discussions](https://github.com/emsesp/EMS-ESP32/discussions)
- [ ] Searched the issue in the [docs](https://docs.emsesp.org/Troubleshooting/)
- [ ] Searched the issue in the [chat](https://discord.gg/3J3GgnzpyT)
- [ ] Provide the System information in the area below, taken from `http://<IP>/api/system`
```lua
System information output here:
```json
Paste System information here....
```
@@ -41,10 +41,10 @@ _A clear and concise description of what you expected to happen._
### SCREENSHOTS
_If applicable, add screenshots to help explain your problem._
_If applicable, add screenshots to help explain your issue._
### ADDITIONAL CONTEXT
_Add any other context about the problem here._
_Add any other context about the issue here._
**(Please, remember to close the issue when the problem has been addressed)**
**(Please remember to close the issue when it has been addressed)**

View File

@@ -1,7 +1,7 @@
blank_issues_enabled: false
contact_links:
- name: EMS-ESP Docs
url: https://emsesp.github.io/docs/
url: https://docs.emsesp.org
about: All the information related to EMS-ESP.
- name: EMS-ESP Discussions and Support
url: https://github.com/emsesp/EMS-ESP32/discussions

1
.github/SUPPORT.md vendored Normal file
View File

@@ -0,0 +1 @@
# Support

101
.github/workflows/dev_release.yml vendored Normal file
View File

@@ -0,0 +1,101 @@
name: 'Build dev release'
on:
workflow_dispatch:
push:
paths:
- 'src/emsesp_version.h'
branches:
- 'dev'
permissions:
contents: write
jobs:
pre-release:
name: 'Build Dev Release'
runs-on: ubuntu-latest
steps:
- name: Install python 3.13
uses: actions/setup-python@v6
with:
python-version: '3.13'
- name: Install Node.js 24
uses: actions/setup-node@v6
with:
node-version: 24
- name: Checkout repository
uses: actions/checkout@v5
- name: Enable Corepack
run: corepack enable pnpm
- name: Get the EMS-ESP version
id: build_info
run: |
version=`grep -E '^#define EMSESP_APP_VERSION' ./src/emsesp_version.h | awk -F'"' '{print $2}'`
echo "VERSION=$version" >> $GITHUB_OUTPUT
- name: Install PlatformIO
run: |
python -m pip install --upgrade pip
pip install -U platformio
python -m pip install intelhex
- name: Build webUI
run: |
platformio run -e build_webUI
- name: Build modbus
run: |
platformio run -e build_modbus
- name: Build standalone
run: |
platformio run -e build_standalone
- name: Build all PIO target environments, from default_envs
run: |
platformio run
- name: Commit the generated files
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "chore: update generated files"
- name: Configure Git
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
- name: Check for changes and commit
run: |
if [ -n "$(git status --porcelain)" ]; then
echo "Changes detected, committing..."
git add .
git commit -m "Auto-commit build artifacts and configuration updates
- Updated build configurations
- Generated build artifacts
- Version: ${{steps.build_info.outputs.VERSION}}"
echo "Pushing changes to repository..."
git push origin dev
else
echo "No changes to commit"
fi
- name: Create GitHub Release
id: 'automatic_releases'
uses: emsesp/action-automatic-releases@v1.0.0
with:
repo_token: '${{ secrets.GITHUB_TOKEN }}'
title: Development Build v${{steps.build_info.outputs.VERSION}}
automatic_release_tag: 'latest'
prerelease: true
files: |
CHANGELOG_LATEST.md
./build/firmware/*.*

View File

@@ -1,4 +1,4 @@
name: 'github-releases-to-discord'
name: 'Publish releases to discord'
on:
release:
@@ -7,10 +7,13 @@ on:
jobs:
github-releases-to-discord:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Github Releases To Discord
uses: actions/checkout@v5
- name: GitHub Releases To Discord
uses: SethCohen/github-releases-to-discord@v1.13.1
with:
webhook_url: ${{ secrets.WEBHOOK_URL }}

32
.github/workflows/pr_check.yml vendored Normal file
View File

@@ -0,0 +1,32 @@
name: 'Pre-check on PR'
permissions:
contents: read
on:
workflow_dispatch:
pull_request:
branches: dev
paths:
- 'src/**'
jobs:
pre-release:
name: 'Automatic pre-release build'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Install python 3.13
uses: actions/setup-python@v6
with:
python-version: '3.13'
- name: Install PlatformIO
run: |
pip install wheel
pip install -U platformio
- name: Run unit tests
run: |
platformio run -e native-test -t exec

View File

@@ -1,65 +0,0 @@
name: 'pre-release'
on:
workflow_dispatch:
push:
branches:
- 'dev'
jobs:
pre-release:
name: 'Automatic pre-release build'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: '3.11'
- uses: actions/setup-node@v3
with:
node-version: '18'
- name: Get EMS-ESP source code and version
id: build_info
run: |
version=`grep -E '^#define EMSESP_APP_VERSION' ./src/version.h | awk -F'"' '{print $2}'`
echo "VERSION=$version" >> $GITHUB_OUTPUT
- name: Install PlatformIO
run: |
python -m pip install --upgrade pip
pip install -U platformio
- name: Build WebUI
run: |
cd interface
yarn install
yarn typesafe-i18n --no-watch
sed -i "s/= 'pl'/= 'en'/" ./src/i18n/i18n-util.ts
yarn build
yarn webUI
- name: Build firmware
run: |
platformio run -e ci
- name: Build S3 firmware
run: |
platformio run -e ci_s3
- name: Build E32V2 firmware
run: |
platformio run -e ci_16M
- name: Create a GH Release
id: 'automatic_releases'
uses: 'marvinpinto/action-automatic-releases@latest'
with:
repo_token: '${{ secrets.GITHUB_TOKEN }}'
title: Development Build v${{steps.build_info.outputs.VERSION}}
automatic_release_tag: 'latest'
prerelease: true
files: |
CHANGELOG_LATEST.md
./build/firmware/*.*

View File

@@ -1,30 +1,33 @@
# see https://github.com/marketplace/actions/sonarcloud-scan-for-c-and-c#usage
name: Sonar Check
permissions:
contents: read
on:
push:
branches:
- dev
pull_request:
types: [opened, synchronize, reopened]
paths:
- 'src/**'
jobs:
build:
name: Build and analyze
if: github.repository == 'emsesp/EMS-ESP32'
runs-on: ubuntu-latest
# if: github.repository_owner == 'emsesp'
# if: github.repository == 'emsesp/EMS-ESP32'
env:
BUILD_WRAPPER_OUT_DIR: bw-output
steps:
- uses: actions/checkout@v4
- name: Checkout repository
uses: actions/checkout@v5
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Install sonar-scanner and build-wrapper
uses: SonarSource/sonarcloud-github-c-cpp@v2
- name: Run build-wrapper
run: |
build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} make all
- name: Run sonar-scanner
fetch-depth: 0
- name: Install Build Wrapper
uses: SonarSource/sonarqube-scan-action/install-build-wrapper@master
- name: Run Build Wrapper
run: build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} make all
- name: SonarQube Scan
uses: SonarSource/sonarqube-scan-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: |
sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"

63
.github/workflows/stable_release.yml vendored Normal file
View File

@@ -0,0 +1,63 @@
name: 'Build stable release'
permissions:
contents: write
on:
workflow_dispatch:
push:
tags:
- 'v*'
jobs:
tagged-release:
name: 'Build Stable Release'
runs-on: ubuntu-latest
steps:
- name: Install python 3.13
uses: actions/setup-python@v6
with:
python-version: '3.13'
- name: Install Node.js 24
uses: actions/setup-node@v6
with:
node-version: 24
- name: Checkout repository
uses: actions/checkout@v5
- name: Enable Corepack
run: corepack enable pnpm
- name: Install PlatformIO
run: |
python -m pip install --upgrade pip
pip install -U platformio
python -m pip install intelhex
- name: Build webUI
run: |
platformio run -e build_webUI
- name: Build modbus
run: |
platformio run -e build_modbus
- name: Build standalone
run: |
platformio run -e build_standalone
- name: Build all PIO target environments, from default_envs
run: |
platformio run
- name: Create GitHub Release
uses: emsesp/action-automatic-releases@v1.0.0
with:
repo_token: '${{ secrets.GITHUB_TOKEN }}'
prerelease: false
files: |
CHANGELOG.md
./build/firmware/*.*

27
.github/workflows/stale_issues.yml vendored Normal file
View File

@@ -0,0 +1,27 @@
name: "Mark or close stale issues and PRs"
permissions:
contents: read
issues: write
pull-requests: write
on:
schedule:
- cron: "30 1 * * *"
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v10
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 30
days-before-close: 5
stale-issue-message: "This issue is stale because it has been open 30 days with no activity. Remove stale label or comment otherwise this will be closed in 5 days."
stale-pr-message: "This PR has been automatically marked as stale because there has been no activity in last 30 days. It will be closed if no further activity occurs. Thank you for your contributions."
close-issue-message: "This issue was closed because it has been stalled for 5 days with no activity."
close-pr-message: "This PR was automatically closed because of being stale."
stale-pr-label: "stale"
stale-issue-label: "stale"
exempt-issue-labels: "bug,enhancement,pinned,security"
exempt-pr-labels: "bug,enhancement,pinned,security"

View File

@@ -1,53 +0,0 @@
name: 'tagged-release'
on:
push:
tags:
- 'v*'
jobs:
tagged-release:
name: 'Tagged Release'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: '3.11'
- uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install PlatformIO
run: |
python -m pip install --upgrade pip
pip install -U platformio
platformio upgrade
pio pkg update
- name: Build WebUI
run: |
cd interface
yarn install
yarn typesafe-i18n --no-watch
sed -i "s/= 'pl'/= 'en'/" ./src/i18n/i18n-util.ts
yarn build
yarn webUI
- name: Build firmware
run: |
platformio run -e ci
- name: Build S3 firmware
run: |
platformio run -e ci_s3
- name: Release
uses: 'marvinpinto/action-automatic-releases@latest'
with:
repo_token: '${{ secrets.GITHUB_TOKEN }}'
prerelease: false
files: |
CHANGELOG.md
./build/firmware/*.*

View File

@@ -1,56 +1,69 @@
name: 'test-release'
name: 'Build test release'
on:
workflow_dispatch:
push:
branches:
- 'dev2'
- 'test'
permissions:
contents: read
jobs:
pre-release:
name: 'Automatic test-release build'
name: 'Build Test Release'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: '3.11'
- uses: actions/setup-node@v3
with:
node-version: '18'
- name: Get EMS-ESP source code and version
- name: Install python 3.13
uses: actions/setup-python@v6
with:
python-version: '3.13'
- name: Install Node.js 24
uses: actions/setup-node@v6
with:
node-version: 24
- name: Checkout repository
uses: actions/checkout@v5
- name: Enable Corepack
run: corepack enable pnpm
- name: Get the EMS-ESP version
id: build_info
run: |
version=`grep -E '^#define EMSESP_APP_VERSION' ./src/version.h | awk -F'"' '{print $2}'`
version=`grep -E '^#define EMSESP_APP_VERSION' ./src/emsesp_version.h | awk -F'"' '{print $2}'`
echo "VERSION=$version" >> $GITHUB_OUTPUT
- name: Install PlatformIO
run: |
python -m pip install --upgrade pip
pip install -U platformio
python -m pip install intelhex
- name: Build WebUI
- name: Build webUI
run: |
cd interface
yarn install
yarn typesafe-i18n --no-watch
sed -i "s/= 'pl'/= 'en'/" ./src/i18n/i18n-util.ts
yarn build
yarn webUI
platformio run -e build_webUI
- name: Build firmware
- name: Build modbus
run: |
platformio run -e ci
platformio run -e build_modbus
- name: Build S3 firmware
- name: Build standalone
run: |
platformio run -e ci_s3
platformio run -e build_standalone
- name: Build all PIO target environments, from default_envs
run: |
platformio run
- name: Create a GH Release
- name: Create GitHub Release
id: 'automatic_releases'
uses: 'marvinpinto/action-automatic-releases@latest'
uses: emsesp/action-automatic-releases@v1.0.0
with:
repo_token: '${{ secrets.GITHUB_TOKEN }}'
title: Test Build v${{steps.build_info.outputs.VERSION}}
@@ -59,3 +72,4 @@ jobs:
files: |
CHANGELOG_LATEST.md
./build/firmware/*.*

54
.gitignore vendored
View File

@@ -1,5 +1,8 @@
# vscode
.vscode/*
.vscode/c_cpp_properties.json
.vscode/extensions.json
.vscode/launch.json
.vscode/settings.json
# c++ compiling
.clang_complete
@@ -9,17 +12,15 @@ cppcheck.out.xml
# platformio
.pio
pio_local.ini
*_old
# OS specific
.DS_Store
*Thumbs.db
# web specfic
# web specific
build/
dist/
/data/www
/lib/framework/WWWData.h
/interface/build
node_modules
/interface/.eslintcache
@@ -27,21 +28,10 @@ stats.html
*.sln
*.sw?
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
yarn.lock
interface/analyse.html
analyse.html
interface/vite.config.ts.timestamp*
# scripts
test.sh
scripts/run.sh
scripts/__pycache__
scripts/stackdmp.txt
*.local
src/ESP32React/WWWData.h
# i18n generated files
interface/src/i18n/i18n-react.tsx
@@ -50,11 +40,37 @@ interface/src/i18n/i18n-util.ts
interface/src/i18n/i18n-util.sync.ts
interface/src/i18n/i18n-util.async.ts
# scripts
test.sh
scripts/run.sh
scripts/__pycache__
scripts/stackdmp.txt
# sonar
.scannerwork/
sonar/
bw-output/
# testing
# standalone executable for testing
emsesp
interface/tsconfig.tsbuildinfo
# python virtual environment
venv/
# cspell
words-found-verbose.txt
# sonarlint
compile_commands.json
# pioarduino + hybrid
managed_components
dependencies.lock
CMakeLists.txt
.dummy/*
logs/*
sdkconfig.*
sdkconfig_tasmota_esp32
pnpm-lock.yaml
package.json

6
.markdownlint.json Normal file
View File

@@ -0,0 +1,6 @@
{
"MD033": false,
"MD013": false,
"MD045": false,
"MD041": false
}

6
.prettierignore Normal file
View File

@@ -0,0 +1,6 @@
*/node_modules/
build/
dist/*
interface/src/i18n/*
.typesafe-i18n.json

View File

@@ -1,8 +1,13 @@
{
"plugins": ["@trivago/prettier-plugin-sort-imports"],
"trailingComma": "none",
"tabWidth": 2,
"semi": true,
"singleQuote": true,
"printWidth": 120,
"bracketSpacing": true
}
"printWidth": 85,
"bracketSpacing": true,
"importOrder": ["^react", "^@mui/(.*)$", "^api*/(.*)$", "<THIRD_PARTY_MODULES>", "^[./]"],
"importOrderSeparation": true,
"importOrderSortSpecifiers": true,
"importOrderGroupNamespaceSpecifiers": true
}

View File

@@ -0,0 +1,4 @@
{
"sonarCloudOrganization": "emsesp",
"projectKey": "emsesp_EMS-ESP32"
}

View File

@@ -1,10 +0,0 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}

101
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,101 @@
{
"search.exclude": {
"**/.yarn": true,
"**/.pnp.*": true
},
"editor.codeActionsOnSave": {
"source.fixAll": "explicit"
},
"eslint.validate": [
"typescript"
],
"eslint.codeActionsOnSave.rules": null,
"eslint.nodePath": "interface/.yarn/sdks",
"eslint.workingDirectories": ["interface"],
"prettier.prettierPath": "",
"typescript.enablePromptUseWorkspaceTsdk": true,
"files.associations": {
"*.tsx": "typescriptreact",
"*.tcc": "cpp",
"optional": "cpp",
"istream": "cpp",
"ostream": "cpp",
"ratio": "cpp",
"system_error": "cpp",
"array": "cpp",
"functional": "cpp",
"regex": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"string": "cpp",
"string_view": "cpp",
"atomic": "cpp",
"bitset": "cpp",
"cctype": "cpp",
"chrono": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"condition_variable": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"list": "cpp",
"unordered_map": "cpp",
"unordered_set": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"iterator": "cpp",
"map": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"random": "cpp",
"set": "cpp",
"fstream": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"limits": "cpp",
"mutex": "cpp",
"new": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"thread": "cpp",
"cinttypes": "cpp",
"typeinfo": "cpp"
},
"todo-tree.filtering.excludeGlobs": [
"**/vendor/**",
"**/node_modules/**",
"**/dist/**",
"**/bower_components/**",
"**/build/**",
"**/.vscode/**",
"**/.github/**",
"**/_output/**",
"**/*.min.*",
"**/*.map",
"**/ArduinoJson/**"
],
"cSpell.enableFiletypes": [
"ini",
"makefile"
],
"typescript.preferences.preferTypeOnlyAutoImports": true,
"sonarlint.pathToCompileCommands": "${workspaceFolder}/compile_commands.json",
"sonarlint.connectedMode.project": {
"connectionId": "emsesp",
"projectKey": "emsesp_EMS-ESP32"
}
}

View File

@@ -5,6 +5,214 @@ 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/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [3.7.2] 22 March 2025
## Added
- change enum_heatingtype for remote control [#2268](https://github.com/emsesp/EMS-ESP32/issues/2268)
- system service commands [#2182](https://github.com/emsesp/EMS-ESP32/issues/2182)
- read 0x02A5 for thermostat CT200 [#2277](https://github.com/emsesp/EMS-ESP32/issues/2277)
- add "duplicate" option to Custom Entities [#2266](https://github.com/emsesp/EMS-ESP32/discussion/2266)
- mask bits for bool custom entities
- thermostat `reduce threshold` [#2288](https://github.com/emsesp/EMS-ESP32/issues/2288)
- thermostat `absent` [#1957](https://github.com/emsesp/EMS-ESP32/issues/1957)
- CR11 thermostat [#2295](https://github.com/emsesp/EMS-ESP32/issues/2295)
- Show ESP32's CPU temp in Hardware Status
- vacation mode for the CR50 [#2403](https://github.com/emsesp/EMS-ESP32/issues/2403)
- new Console command "set admin password" to set WebUI admin password
- support nested conditions in scheduler [#2451](https://github.com/emsesp/EMS-ESP32/issues/2451)
- allow mixed case in scheduler expressions [#2457](https://github.com/emsesp/EMS-ESP32/issues/2457)
- Suprapur-o [#2470](https://github.com/emsesp/EMS-ESP32/issues/2470)
## Fixed
- long numbers of custom entities [#2267](https://github.com/emsesp/EMS-ESP32/issues/2267)
- modbus command path to `api/` [#2276](https://github.com/emsesp/EMS-ESP32/issues/2276)
- info command for devices without entity-commands [#2274](https://github.com/emsesp/EMS-ESP32/issues/2274)
- CW100 settings telegram 0x241 [#2290](https://github.com/emsesp/EMS-ESP32/issues/2290)
- modbus signed 8bit values [#2294](https://github.com/emsesp/EMS-ESP32/issues/2294)
- thermostat date [#2313](https://github.com/emsesp/EMS-ESP32/issues/2313)
- Updated unknown compressor stati "enum_hpactivity" [#2311](https://github.com/emsesp/EMS-ESP32/pull/2311)
- Underline Tab headers in WebUI
- console unit tests fixed due to changed shell output
- tx-queue overflow in some heatpump systems [#2455](https://github.com/emsesp/EMS-ESP32/issues/2455)
## Changed
- show operation in pretty telegram between src and dst [#2263](https://github.com/emsesp/EMS-ESP32/discussions/2263)
- update eModbus to 1.7.2 [#2254](https://github.com/emsesp/EMS-ESP32/issues/2254)
- modbus timeout default to 300 sec, change setting from ms to sec [#2254](https://github.com/emsesp/EMS-ESP32/issues/2254)
- update AsyncTCP and ESPAsyncWebServer to latest versions
- update Arduino pio platform to 3.10.0 and optimized flash using build flags
- Version checker in WebUI improved
- rename `remoteseltemp` to `cooltemp` [#2456](https://github.com/emsesp/EMS-ESP32/issues/2456)
## [3.7.1] 29 November 2024
## Added
- include HA "unit_of_meas", "stat_cla" and "dev_cla" attributes for Number sensors [#2149](https://github.com/emsesp/EMS-ESP32/issues/2149)
- Bosch CS6800i AW - Silent Mode + Electrical Power Reduction (HP) [#2147](https://github.com/emsesp/EMS-ESP32/issues/2147)
- `/api/system/showeralert` and `/api/system/showertimer` [#2182](https://github.com/emsesp/EMS-ESP32/issues/2182)
- MX400 [#2198](https://github.com/emsesp/EMS-ESP32/issues/2198)
- SM200 values [#2212](https://github.com/emsesp/EMS-ESP32/discussions/2212)
## Fixed
- Modbus integration in 3.7.0 missing offset [#2148](https://github.com/emsesp/EMS-ESP32/issues/2148)
- fix changing TZ in NTPsettings without clearing enable+server, added DST support [#2142](https://github.com/emsesp/EMS-ESP32/issues/2142)
- Support MQTT Discovery (AD) with Domoticz [#2177](https://github.com/emsesp/EMS-ESP32/issues/2177)
- wwExtra (dhw extra) changed from temperature reading to number
- auxheaterstatus [#2192](https://github.com/emsesp/EMS-ESP32/issues/2192)
- lastCode character check [#2189](https://github.com/emsesp/EMS-ESP32/issues/2189)
- reading too many telegram parts
- heatpump cost UOMs [#2188](https://github.com/emsesp/EMS-ESP32/issues/2188)
- analog dac output and inputs on dac pins [#2201](https://github.com/emsesp/EMS-ESP32/discussions/2201)
- api memory leak [#2216](https://github.com/emsesp/EMS-ESP32/issues/2216)
- modbus multiple mixers [#2229](https://github.com/emsesp/EMS-ESP32/issues/2229)
- Last Will (LWT) not set on MQTT Connect [#2247](https://github.com/emsesp/EMS-ESP32/issues/2247)
## Changed
- name of wwstarts2 [#2217](https://github.com/emsesp/EMS-ESP32/discussions/2217)
## [3.7.0] 27 October 2024
## **IMPORTANT! BREAKING CHANGES with 3.6.5**
- "ww" and "wwc" has been renamed to "dhw". It is nested JSON object in both the MQTT and API outputs. The old prefix has also been removed from MQTT topics ([#1634](https://github.com/emsesp/EMS-ESP32/issues/1634)). This will impact historical data in home automation systems like Home Assistant and IOBroker. To preserve the current value of dhw energy (was previously nrgww) refer to this issue [#1938](https://github.com/emsesp/EMS-ESP32/issues/1938).
- dhw entities from the MM100/SM100 have been moved under a new Device called 'water'.
- The automatically generated temperature sensor ID has replaced dashes (`-`) with underscores (`_`) to be compatible with Home Assistant.
- `api/system/info` has it's JSON key names changed to camelCase syntax.
For more details go to [docs.emsesp.org](https://docs.emsesp.org/).
## Added
- some more entities for dhw with SM100 module
- thermostat second dhw circuit [#1634](https://github.com/emsesp/EMS-ESP32/issues/1634)
- remote thermostat emulation for RC100H, RC200 and FB10 [#1287](https://github.com/emsesp/EMS-ESP32/discussions/1287), [#1602](https://github.com/emsesp/EMS-ESP32/discussions/1602), [#1551](https://github.com/emsesp/EMS-ESP32/discussions/1551)
- heatpump dhw stop temperatures [#1624](https://github.com/emsesp/EMS-ESP32/issues/1624)
- reset history [#1695](https://github.com/emsesp/EMS-ESP32/issues/1695)
- heatpump entities `fan` and `shutdown` [#1690](https://github.com/emsesp/EMS-ESP32/discussions/1690)
- mqtt HA-mode 3 for v3.6 compatible HA entities, set on update v3.6->v3.7
- HP input states [#1723](https://github.com/emsesp/EMS-ESP32/discussions/1723)
- holiday settings for rego 3000 [#1735](https://github.com/emsesp/EMS-ESP32/issues/1735)
- Added scripts for OTA (scripts/upload.py and upload_cli.py) [#1738](https://github.com/emsesp/EMS-ESP32/issues/1738)
- timeout for remote thermostat emulation [#1680](https://github.com/emsesp/EMS-ESP32/discussions/1680), [#1774](https://github.com/emsesp/EMS-ESP32/issues/1774)
- CR120 thermostat as own model() [#1779](https://github.com/emsesp/EMS-ESP32/discussions/1779)
- modules - external linkable module library [#1778](https://github.com/emsesp/EMS-ESP32/issues/1778)
- scheduler onChange and Conditions [#1806](https://github.com/emsesp/EMS-ESP32/issues/1806)
- make remote control timeout editable [#1774](https://github.com/emsesp/EMS-ESP32/issues/1774)
- added extra pump characteristics (mode and pressure for EMS+) by @SLTKA [#1802](https://github.com/emsesp/EMS-ESP32/pull/1802)
- allow device name to be customized [#1174](https://github.com/emsesp/EMS-ESP32/issues/1174)
- Modbus support by @mheyse [#1744](https://github.com/emsesp/EMS-ESP32/issues/1744)
- System Message command [#1854](https://github.com/emsesp/EMS-ESP32/issues/1854)
- scheduler can use web get/post for values and commands [#1806](https://github.com/emsesp/EMS-ESP32/issues/1806)
- RT800 remote emulation [#1867](https://github.com/emsesp/EMS-ESP32/issues/1867)
- RC310 cooling parameters [#1857](https://github.com/emsesp/EMS-ESP32/issues/1857)
- command `api/device/entities` [#1897](https://github.com/emsesp/EMS-ESP32/issues/1897)
- switchprogmode [#1903](https://github.com/emsesp/EMS-ESP32/discussions/1903)
- autodetect and download firmware upgrades via the WebUI
- command 'show log' that lists out the current weblog buffer, showing last messages.
- default web log buffer to 25 lines for ESP32s with no PSRAM
- try and determine correct board profile if none is set during boot
- auto Scroll in WebLog UI - reduced delay so incoming logs are faster
- uploading custom support info, shown to Guest users in Help page [#2054](https://github.com/emsesp/EMS-ESP32/issues/2054)
- feature: Dashboard showing all data (favorites, sensors, custom) [#1958](https://github.com/emsesp/EMS-ESP32/issues/1958)
- entity for low-temperature boilers pump start temp (pumpOnTemp) #2088 [#2088](https://github.com/emsesp/EMS-ESP32/issues/2088)
- internal ESP32 temperature sensor on the S3 [#2077](https://github.com/emsesp/EMS-ESP32/issues/2077)
- MQTT status topic (used in connect and last will) set to Retain [#2086](https://github.com/emsesp/EMS-ESP32/discussions/2086)
- Czech language [2096](https://github.com/emsesp/EMS-ESP32/issues/2096)
- Developer Mode and send EMS Read Commands from WebUI [#2116](https://github.com/emsesp/EMS-ESP32/issues/2116)
- Scheduler functions [#2115](https://github.com/emsesp/EMS-ESP32/issues/2115)
- Set device custom name from telegram 0x01 [#2073](https://github.com/emsesp/EMS-ESP32/issues/2073)
## Fixed
- remote thermostat emulation for RC200 on Rego2000/3000 thermostats [#1691](https://github.com/emsesp/EMS-ESP32/discussions/1691)
- log shows data for F7/F9 requests
- Detection of LittleFS for factory setting wasn't working
- Check for bad GPIOs with Ethernet before the ethernet is initialized
- Show values with factor 50 on webUI [#2064](https://github.com/emsesp/EMS-ESP32/issues/2064)
- Rendering of values between -1 and 0
- Value for 32bit times not-set [#2109](https://github.com/emsesp/EMS-ESP32/issues/2109)
## Changed
- use flag for BC400 compatible thermostats, manage different mode settings
- use factory partition for 16M flash
- store digital out states to nvs
- Refresh UI - moving settings to one location [#1665](https://github.com/emsesp/EMS-ESP32/issues/1665)
- rename DeviceValueTypes, add UINT32 for custom entities
- dynamic register dhw circuits for thermostat
- removed OTA feature [#1738](https://github.com/emsesp/EMS-ESP32/issues/1738)
- added shower min duration [#1801](https://github.com/emsesp/EMS-ESP32/issues/1801)
- Include TXT file along with the generated CSV for Device Data export/download
- thermostat/remotetemp as command [#1835](https://github.com/emsesp/EMS-ESP32/discussions/1835)
- temperaturesensor id notation with underscore [#1794](https://github.com/emsesp/EMS-ESP32/discussions/1794)
- Change key-names in JSON to be compliant and consistent [#1860](https://github.com/emsesp/EMS-ESP32/issues/1860)
- Updates to webUI [#1920](https://github.com/emsesp/EMS-ESP32/issues/1920)
- Correct firmware naming #1933 [#1933](https://github.com/emsesp/EMS-ESP32/issues/1933)
- Don't start Serial console if not connected to a Serial port. Will initiate manually after a CTRL-C/CTRL-S
- WebLog UI matches color schema of the terminal console correctly
- Updated Web libraries, ArduinoJson
- Help page doesn't show detailed tech info if the user is not 'admin' role [#2054](https://github.com/emsesp/EMS-ESP32/issues/2054)
- removed system command `allvalues` and moved to an action called `export`
- Show ems-esp internal devices in device list of system/info
- Scheduler and mqtt run async on systems with psram
- Show IPv6 address type (local/global/ula) in log
## [3.6.5] March 23 2024
## **IMPORTANT! BREAKING CHANGES**
- The Wifi Tx Power setting in Network Settings will be reset to Auto
## Added
- thermostat boost mode and boost time [#1446](https://github.com/emsesp/EMS-ESP32/issues/1446)
- heatpump energy meters [#1463](https://github.com/emsesp/EMS-ESP32/issues/1463)
- heatpump max power [#1475](https://github.com/emsesp/EMS-ESP32/issues/1475)
- checkbox for MQTT-TLS enable [#1474](https://github.com/emsesp/EMS-ESP32/issues/1474)
- added SK (Slovak) language. Thanks @misa1515
- CPU info [#1497](https://github.com/emsesp/EMS-ESP32/pull/1497)
- Show network hostname in Web UI under Network Status
- Improved HA Discovery so each section (EMS device, Scheduler, Analog, Temperature, Custom, Shower) have their own section
- boiler Bosch C1200W, id 12, [#1536](https://github.com/emsesp/EMS-ESP32/issues/1536)
- mixer MM100 telegram 0x2CC [#1554](https://github.com/emsesp/EMS-ESP32/issues/1554)
- boiler hpSetDiffPressure [#1563](https://github.com/emsesp/EMS-ESP32/issues/1563)
- custom variables [#1423](https://github.com/emsesp/EMS-ESP32/issues/1423)
- weather compensation [#1642](https://github.com/emsesp/EMS-ESP32/issues/1642)
- env and partitions for DevKitC-1-N32R8 [#1635](https://github.com/emsesp/EMS-ESP32/discussions/1635)
- command `restart partitionname` and button long press to start with other partition [#1657](https://github.com/emsesp/EMS-ESP32/issues/1657)
- command `set service <mqtt|ota|ntp|ap> <enable|disable>` [#1663](https://github.com/emsesp/EMS-ESP32/issues/1663)
## Fixed
- exhaust temperature for some boilers
- add back boil2hyst [#1477](https://github.com/emsesp/EMS-ESP32/issues/1477)
- subscribed MQTT topics not detecting changes by EMS-ESP [#1494](https://github.com/emsesp/EMS-ESP32/issues/1494)
- changed HA name and grouping to be consistent [#1528](https://github.com/emsesp/EMS-ESP32/issues/1528)
- MQTT autodiscovery in Domoticz not working [#1360](https://github.com/emsesp/EMS-ESP32/issues/1528)
- dhw comfort for new ems+, [#1495](https://github.com/emsesp/EMS-ESP32/issues/1495)
- added writeable icon to Web's Custom Entity page for each entity shown in the table
- Wifi Tx Power not adjusted [#1614](https://github.com/emsesp/EMS-ESP32/issues/1614)
- MQTT discovery of custom entity doesn't consider type of data [#1587](https://github.com/emsesp/EMS-ESP32/issues/1587)
- WiFi TxPower wasn't correctly used. Added an 'Auto' setting, which is the default.
- dns w/wo IPv6 [#1644](https://github.com/emsesp/EMS-ESP32/issues/1644)
## Changed
- HA don't set entity_category to Diagnostic/Configuration for EMS entities [#1459](https://github.com/emsesp/EMS-ESP32/discussions/1459)
- upgraded ArduinoJson to 7.0.0 #1538 and then 7.0.2
- small changes to the API for analog and temperature sensors
- Length of mqtt Broker adress [#1619](https://github.com/emsesp/EMS-ESP32/issues/1619)
- C++ optimizations - see <https://github.com/emsesp/EMS-ESP32/pull/1615>
- Send MQTT heartbeat immediately after connection [#1628](https://github.com/emsesp/EMS-ESP32/issues/1628)
- 16MB partitions with second nvs, larger FS, Coredump, optional factory partition
- stop fetching empty telegrams after 5 min
## [3.6.4] November 24 2023
## **IMPORTANT! BREAKING CHANGES**

View File

@@ -1,51 +1,59 @@
# Changelog
## [3.6.5]
For more details go to [docs.emsesp.org](https://docs.emsesp.org/).
## **IMPORTANT! BREAKING CHANGES**
- The Wifi Tx Power setting in Network Settings will be reset to Auto
## [3.7.3]
## Added
- thermostat boost mode and boost time [#1446](https://github.com/emsesp/EMS-ESP32/issues/1446)
- heatpump energy meters [#1463](https://github.com/emsesp/EMS-ESP32/issues/1463)
- heatpump max power [#1475](https://github.com/emsesp/EMS-ESP32/issues/1475)
- checkbox for MQTT-TLS enable [#1474](https://github.com/emsesp/EMS-ESP32/issues/1474)
- added SK (Slovak) language. Thanks @misa1515
- CPU info [#1497](https://github.com/emsesp/EMS-ESP32/pull/1497)
- Show network hostname in Web UI under Network Status
- Improved HA Discovery so each section (EMS device, Scheduler, Analog, Temperature, Custom, Shower) have their own section
- boiler Bosch C1200W, id 12, [#1536](https://github.com/emsesp/EMS-ESP32/issues/1536)
- mixer MM100 telegram 0x2CC [#1554](https://github.com/emsesp/EMS-ESP32/issues/1554)
- boiler hpSetDiffPressure [#1563](https://github.com/emsesp/EMS-ESP32/issues/1563)
- custom variables [#1423](https://github.com/emsesp/EMS-ESP32/issues/1423)
- weather compensation [#1642](https://github.com/emsesp/EMS-ESP32/issues/1642)
- env and partitions for DevKitC-1-N32R8 [#1635](https://github.com/emsesp/EMS-ESP32/discussions/1635)
- command `restart partitionname` and button long press to start with other partition [#1657](https://github.com/emsesp/EMS-ESP32/issues/1657)
- command `set service <mqtt|ota|ntp|ap> <enable|disable>` [#1663](https://github.com/emsesp/EMS-ESP32/issues/1663)
- analogsensor types: NTC and RGB-Led
- Flag for HMC310 [#2465](https://github.com/emsesp/EMS-ESP32/issues/2465)
- boiler auxheatersource [#2489](https://github.com/emsesp/EMS-ESP32/discussions/2489)
- thermostat last error for RC100/300 [#2501](https://github.com/emsesp/EMS-ESP32/issues/2501)
- boiler 0xC6 telegram [#1963](https://github.com/emsesp/EMS-ESP32/issues/1963)
- CS6800i changes [#2448](https://github.com/emsesp/EMS-ESP32/issues/2448), [#2449](https://github.com/emsesp/EMS-ESP32/issues/2449)
- charging pump [#2544](https://github.com/emsesp/EMS-ESP32/issues/2544)
- hybrid CSH5800iG [#2569](https://github.com/emsesp/EMS-ESP32/issues/2569)
- add EMS Device details to Home Assistant MQTT Discovery
- disinfection command [#2601](https://github.com/emsesp/EMS-ESP32/issues/2601)
- added new board profile for upcoming BBQKees E32V2.2
- set differential pressure entity in Mixer device
- set set climate action cooling/heating in HA [#2583](https://github.com/emsesp/EMS-ESP32/issues/2583)
- Internal sensors of E32V2_2
- FW200 display options [#2610](https://github.com/emsesp/EMS-ESP32/discussions/2610)
- CR11 mode settings OFF/MANUAL depends on selTemp [#2437](https://github.com/emsesp/EMS-ESP32/issues/2437)
- Fuse settings for BBQKees boards
- Analogsensors for pulse output [#2624](https://github.com/emsesp/EMS-ESP32/discussions/2624)
- Analogsensors frequency input [#2631](https://github.com/emsesp/EMS-ESP32/discussions/2631)
- SRC plus thermostats [#2636](https://github.com/emsesp/EMS-ESP32/issues/2636)
- Greenstar 2000 [#2645](https://github.com/emsesp/EMS-ESP32/issues/2645)
- RC3xx `dhw modetype` [#2659](https://github.com/emsesp/EMS-ESP32/discussions/2659)
- new boiler entities VR0,VR1, compressor speed [#2669](https://github.com/emsesp/EMS-ESP32/issues/2669)
- solar temperature TS16 [#2690](https://github.com/emsesp/EMS-ESP32/issues/2690)
## Fixed
- exhaust temperature for some boilers
- add back boil2hyst [#1477](https://github.com/emsesp/EMS-ESP32/issues/1477)
- subscribed MQTT topics not detecting changes by EMS-ESP [#1494](https://github.com/emsesp/EMS-ESP32/issues/1494)
- changed HA name and grouping to be consistent [#1528](https://github.com/emsesp/EMS-ESP32/issues/1528)
- MQTT autodiscovery in Domoticz not working [#1360](https://github.com/emsesp/EMS-ESP32/issues/1528)
- dhw comfort for new ems+, [#1495](https://github.com/emsesp/EMS-ESP32/issues/1495)
- added writeable icon to Web's Custom Entity page for each entity shown in the table
- Wifi Tx Power not adjusted [#1614](https://github.com/emsesp/EMS-ESP32/issues/1614)
- MQTT discovery of custom entity doesn't consider type of data [#1587](https://github.com/emsesp/EMS-ESP32/issues/1587)
- WiFi TxPower wasn't correctly used. Added an 'Auto' setting, which is the default.
- dns w/wo IPv6 [#1644](https://github.com/emsesp/EMS-ESP32/issues/1644)
- dhw/switchtime [#2490](https://github.com/emsesp/EMS-ESP32/issues/2490)
- switch to secure mqtt [#2492](https://github.com/emsesp/EMS-ESP32/issues/2492)
- update link buttons [#2497](https://github.com/emsesp/EMS-ESP32/issues/2497)
- refresh scheduler states [#2502](https://github.com/emsesp/EMS-ESP32/discussions/2502)
- also rebuild HA config on mqtt connect for scheduler, custom and shower
- FB100 controls the hc, not the master [#2510](https://github.com/emsesp/EMS-ESP32/issues/2510)
- IPM DHW module, [#2524](https://github.com/emsesp/EMS-ESP32/issues/2524)
- charge optimization [#2543](https://github.com/emsesp/EMS-ESP32/issues/2543)
- shower active state retained, shows correctly in HA
- MQTT Command Topic with slashes [#2571](https://github.com/emsesp/EMS-ESP32/issues/2571)
- Add pulsed water meter input to V1.3 gateway with Lilygo S3 [#2550](https://github.com/emsesp/EMS-ESP32/issues/2550)
- fix missing long 10-second press of Button to perform a factory reset
- fix wwMaxPower on Junkers ZBS14 [#2609](https://github.com/emsesp/EMS-ESP32/issues/2609)
- ventilation bypass state from telegram 0x55C [#1197](https://github.com/emsesp/EMS-ESP32/issues/1197)
- set selflowtemp for ems+ boilers [#2641](https://github.com/emsesp/EMS-ESP32/discussions/2641)
- syslog timestamp [#2704](https://github.com/emsesp/EMS-ESP32/issues/2704)
## Changed
- HA don't set entity_category to Diagnostic/Configuration for EMS entities [#1459](https://github.com/emsesp/EMS-ESP32/discussions/1459)
- upgraded ArduinoJson to 7.0.0 #1538 and then 7.0.2
- small changes to the API for analog and temperature sensors
- Length of mqtt Broker adress [#1619](https://github.com/emsesp/EMS-ESP32/issues/1619)
- C++ optimizations - see <https://github.com/emsesp/EMS-ESP32/pull/1615>
- Send MQTT heartbeat immediately after connection [#1628](https://github.com/emsesp/EMS-ESP32/issues/1628)
- 16MB partitions with second nvs, larger FS, Coredump, optional factory partition
- stop fetching empty telegrams after 5 min
- show console log with ISO date/time [#2533](https://github.com/emsesp/EMS-ESP32/discussions/2533)
- remove ESP32 CPU temperature
- updated core libraries like AsyncTCP, AsyncWebServer and Modbus
- remove command `scan deep`
- ignore repeated `forceheatingoff` commands [#2641](https://github.com/emsesp/EMS-ESP32/discussions/2641)

View File

@@ -6,7 +6,7 @@ Everybody is welcome and invited to contribute to the EMS-ESP Project by:
- providing Pull Requests (Features, Fixes, suggestions)
- testing new released features and report issues on your EMS equipment
- contributing to missing [documentation](https://emsesp.github.io/docs)
- contributing to missing [documentation](https://docs.emsesp.org)
This document describes rules that are in effect for this repository, meant for handling issues by contributors in the issue tracker and PRs.
@@ -69,7 +69,7 @@ Format: `<type>(<scope>): <subject>`
## Example
```
```text
feat: add hat wobble
^--^ ^------------^
| |
@@ -96,7 +96,7 @@ References:
## Contributor License Agreement (CLA)
```
```text
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I

128
Makefile
View File

@@ -2,8 +2,39 @@
# GNUMakefile for EMS-ESP
#
NUMJOBS=${NUMJOBS:-" -j4 "}
MAKEFLAGS+="j "
_mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
I := $(patsubst %/,%,$(dir $(_mkfile_path)))
ifneq ($(words $(MAKECMDGOALS)),1)
.DEFAULT_GOAL = all
%:
@$(MAKE) $@ --no-print-directory -rRf $(firstword $(MAKEFILE_LIST))
else
ifndef ECHO
T := $(shell $(MAKE) $(MAKECMDGOALS) --no-print-directory \
-nrRf $(firstword $(MAKEFILE_LIST)) \
ECHO="COUNTTHIS" | grep -c "COUNTTHIS")
N := x
C = $(words $N)$(eval N := x $N)
ECHO = python3 $(I)/scripts/echo_progress.py --stepno=$C --nsteps=$T
endif
# Optimize parallel build configuration
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
EXTRA_CPPFLAGS = -D LINUX
JOBS ?= $(shell nproc)
endif
ifeq ($(UNAME_S),Darwin)
EXTRA_CPPFLAGS = -D OSX -Wno-tautological-constant-out-of-range-compare
JOBS ?= $(shell sysctl -n hw.ncpu)
endif
# Set optimal parallel build settings
MAKEFLAGS += -j$(JOBS) -l$(shell echo $$(($(JOBS) * 2)))
# $(info Number of jobs: $(JOBS))
#----------------------------------------------------------------------
# Project Structure
#----------------------------------------------------------------------
@@ -13,36 +44,29 @@ MAKEFLAGS+="j "
# INCLUDES is a list of directories containing header files
# LIBRARIES is a list of directories containing libraries, this must be the top level containing include and lib
#----------------------------------------------------------------------
#TARGET := $(notdir $(CURDIR))
TARGET := emsesp
BUILD := build
SOURCES := src src/* lib_standalone lib/uuid-common/src lib/uuid-console/src lib/uuid-log/src src/devices lib/ArduinoJson/src lib/PButton lib/semver lib/espMqttClient/src lib/espMqttClient/src/*
INCLUDES := src lib_standalone lib/espMqttClient/src lib/espMqttClient/src/Transport lib/ArduinoJson/src lib/uuid-common/src lib/uuid-console/src lib/uuid-log/src lib/uuid-telnet/src lib/uuid-syslog/src lib/semver lib/* src/devices
SOURCES := src/core src/devices src/web src/test lib_standalone lib/semver lib/espMqttClient/src lib/espMqttClient/src/* lib/ArduinoJson/src lib/uuid-common/src lib/uuid-console/src lib/uuid-log/src lib/PButton
INCLUDES := src/core src/devices src/web src/test lib/* lib_standalone lib/semver lib/espMqttClient/src lib/espMqttClient/src/Transport lib/ArduinoJson/src lib/uuid-common/src lib/uuid-console/src lib/uuid-log/src lib/uuid-telnet/src lib/uuid-syslog/src
LIBRARIES :=
CPPCHECK = cppcheck
# CHECKFLAGS = -q --force --std=c++17
CHECKFLAGS = -q --force --std=c++11
CHECKFLAGS = -q --force --std=gnu++17
#----------------------------------------------------------------------
# Languages Standard
#----------------------------------------------------------------------
C_STANDARD := -std=c17
# CXX_STANDARD := -std=c++17
CXX_STANDARD := -std=gnu++11
# C_STANDARD := -std=c11
# CXX_STANDARD := -std=c++11
CXX_STANDARD := -std=gnu++17
#----------------------------------------------------------------------
# Defined Symbols
#----------------------------------------------------------------------
DEFINES += -DARDUINOJSON_ENABLE_STD_STRING=1 -DARDUINOJSON_ENABLE_PROGMEM=1 -DARDUINOJSON_ENABLE_ARDUINO_STRING -DARDUINOJSON_USE_DOUBLE=0
DEFINES += -DEMSESP_DEBUG -DEMSESP_STANDALONE -DEMSESP_TEST -D__linux__ -DEMC_RX_BUFFER_SIZE=1500
DEFINES += -DARDUINOJSON_ENABLE -DARDUINOJSON_ENABLE_ARDUINO_STRING -DARDUINOJSON_USE_DOUBLE=0
DEFINES += -DEMSESP_STANDALONE -DEMSESP_TEST -DEMSESP_DEBUG -DEMC_RX_BUFFER_SIZE=1500
DEFINES += $(ARGS)
DEFAULTS = -DEMSESP_DEFAULT_LOCALE=\"en\" -DEMSESP_DEFAULT_TX_MODE=8 -DEMSESP_DEFAULT_VERSION=\"3.6.5-dev\" -DEMSESP_DEFAULT_BOARD_PROFILE=\"S32\"
DEFAULTS = -DEMSESP_DEFAULT_LOCALE=\"en\" -DEMSESP_DEFAULT_TX_MODE=8 -DEMSESP_DEFAULT_VERSION=\"3.7.3-dev\" -DEMSESP_DEFAULT_BOARD_PROFILE=\"S32S3\"
#----------------------------------------------------------------------
# Sources & Files
@@ -50,16 +74,21 @@ DEFAULTS = -DEMSESP_DEFAULT_LOCALE=\"en\" -DEMSESP_DEFAULT_TX_MODE=8 -DEMSESP_DE
OUTPUT := $(CURDIR)/$(TARGET)
SYMBOLS := $(CURDIR)/$(BUILD)/$(TARGET).out
CSOURCES := $(foreach dir,$(SOURCES),$(wildcard $(dir)/*.c))
CXXSOURCES := $(foreach dir,$(SOURCES),$(wildcard $(dir)/*.cpp))
# Optimize source discovery - use shell find for better performance
CSOURCES := $(shell find $(SOURCES) -name "*.c" 2>/dev/null)
CXXSOURCES := $(shell find $(SOURCES) -name "*.cpp" 2>/dev/null)
OBJS := $(patsubst %,$(BUILD)/%.o,$(basename $(CSOURCES)) $(basename $(CXXSOURCES)) )
DEPS := $(patsubst %,$(BUILD)/%.d,$(basename $(CSOURCES)) $(basename $(CXXSOURCES)) )
OBJS := $(patsubst %,$(BUILD)/%.o,$(basename $(CSOURCES)) $(basename $(CXXSOURCES)))
DEPS := $(patsubst %,$(BUILD)/%.d,$(basename $(CSOURCES)) $(basename $(CXXSOURCES)))
INCLUDE += $(addprefix -I,$(foreach dir,$(INCLUDES), $(wildcard $(dir))))
INCLUDE += $(addprefix -I,$(foreach dir,$(LIBRARIES),$(wildcard $(dir)/include)))
# Optimize include path discovery
INCLUDE_DIRS := $(shell find $(INCLUDES) -type d 2>/dev/null)
LIBRARY_INCLUDES := $(shell find $(LIBRARIES) -name "include" -type d 2>/dev/null)
INCLUDE += $(addprefix -I,$(INCLUDE_DIRS) $(LIBRARY_INCLUDES))
LDLIBS += $(addprefix -L,$(foreach dir,$(LIBRARIES),$(wildcard $(dir)/lib)))
# Optimize library path discovery
LIBRARY_DIRS := $(shell find $(LIBRARIES) -name "lib" -type d 2>/dev/null)
LDLIBS += $(addprefix -L,$(LIBRARY_DIRS))
#----------------------------------------------------------------------
# Compiler & Linker
@@ -76,14 +105,18 @@ CXX := /usr/bin/g++
# LDFLAGS Linker Flags
#----------------------------------------------------------------------
CPPFLAGS += $(DEFINES) $(DEFAULTS) $(INCLUDE)
CPPFLAGS += -ggdb
CPPFLAGS += -g3
CPPFLAGS += -Os
CPPFLAGS += -ggdb -g3 -MMD
CPPFLAGS += -flto=auto
CPPFLAGS += -Wall -Wextra -Werror -Wswitch-enum
CPPFLAGS += -Wno-unused-parameter -Wno-missing-braces -Wno-vla-cxx-extension
CPPFLAGS += -ffunction-sections -fdata-sections -fno-exceptions -fno-rtti -fno-threadsafe-statics
CPPFLAGS += -Os -DNDEBUG
CPPFLAGS += $(EXTRA_CPPFLAGS)
CFLAGS += $(CPPFLAGS)
CFLAGS += -Wall -Wextra -Werror -Wswitch-enum -Wno-unused-parameter -Wno-inconsistent-missing-override -Wno-missing-braces -Wno-unused-lambda-capture -Wno-sign-compare
CXXFLAGS += $(CFLAGS) -MMD
CXXFLAGS += $(CPPFLAGS)
LDFLAGS =
#----------------------------------------------------------------------
# Compiler & Linker Commands
@@ -98,7 +131,8 @@ else
LD := $(CXX)
endif
#DEPFLAGS += -MF $(BUILD)/$*.d
# Dependency file generation
DEPFLAGS += -MF $(BUILD)/$*.d -MT $@
LINK.o = $(LD) $(LDFLAGS) $(LDLIBS) $^ -o $@
COMPILE.c = $(CC) $(C_STANDARD) $(CFLAGS) $(DEPFLAGS) -c $< -o $@
@@ -115,7 +149,10 @@ COMPILE.cpp = $(CXX) $(CXX_STANDARD) $(CXXFLAGS) $(DEPFLAGS) -c $< -o $@
.SUFFIXES:
.INTERMEDIATE:
.PRECIOUS: $(OBJS) $(DEPS)
.PHONY: all clean help
.PHONY: all clean help cppcheck run
# Enable second expansion for more flexible rules
.SECONDEXPANSION:
#----------------------------------------------------------------------
# Targets
@@ -124,23 +161,26 @@ COMPILE.cpp = $(CXX) $(CXX_STANDARD) $(CXXFLAGS) $(DEPFLAGS) -c $< -o $@
.SILENT: $(OUTPUT)
all: $(OUTPUT)
@$(ECHO) Build complete.
$(OUTPUT): $(OBJS)
@mkdir -p $(@D)
@$(ECHO) Linking $@
$(LINK.o)
$(SYMBOLS.out)
$(BUILD)/%.o: %.c
@mkdir -p $(@D)
$(COMPILE.c)
@$(ECHO) Compiling $@
@$(COMPILE.c)
$(BUILD)/%.o: %.cpp
@mkdir -p $(@D)
$(COMPILE.cpp)
@$(ECHO) Compiling $@
@$(COMPILE.cpp)
$(BUILD)/%.o: %.s
@mkdir -p $(@D)
$(COMPILE.s)
@$(COMPILE.s)
cppcheck: $(SOURCES)
$(CPPCHECK) $(CHECKFLAGS) $^
@@ -149,11 +189,21 @@ run: $(OUTPUT)
@$<
.PHONY: clean
clean:
@$(RM) -rf $(BUILD) $(OUTPUT)
help:
@echo available targets: all run clean
@echo $(OUTPUT)
@echo "Available targets:"
@echo " all - Build the project (default)"
@echo " run - Build and run the executable"
@echo " clean - Remove build artifacts"
@echo " cppcheck - Run static analysis"
@echo " help - Show this help message"
@echo ""
@echo "Output: $(OUTPUT)"
@echo "Jobs: $(JOBS)"
-include $(DEPS)
-include $(DEPS)
endif

111
README.md
View File

@@ -1,55 +1,102 @@
# ![logo](media/EMS-ESP_logo_dark.png)
<div align="center">
<p align="center">
<a href="#">
<img src="https://raw.githubusercontent.com/emsesp/EMS-ESP32/dev/media/favicon/android-chrome-512x512.png" height="100px" />
</a>
</p>
</div>
<h1 align="center">EMS-ESP</h1>
<p align="center">
<a href="https://emsesp.org">
<img src="https://img.shields.io/badge/Website-0077b5?style=for-the-badge&logo=googlehome&logoColor=white" alt="Website" />
</a>
<a href="https://github.com/emsesp/EMS-ESP32/blob/dev/CONTRIBUTING.md">
<img src="https://img.shields.io/badge/Contribute-ff4785?style=for-the-badge&logo=git&logoColor=white" alt="Contribute" />
</a>
<a href="https://docs.emsesp.org">
<img src="https://img.shields.io/badge/Documentation-0077b5?style=for-the-badge&logo=googledocs&logoColor=white" alt="Guides" />
</a>
<a href="https://discord.gg/3J3GgnzpyT">
<img src="https://img.shields.io/badge/Discord-7289da?style=for-the-badge&logo=discord&logoColor=white" alt="Discord" />
</a>
<a href="https://github.com/emsesp/EMS-ESP32/blob/main/CHANGELOG.md">
<img src="https://img.shields.io/badge/Changelog-6c5ce7?style=for-the-badge&logo=git&logoColor=white" alt="Changelog" />
</a>
</p>
[![version](https://img.shields.io/github/release/emsesp/EMS-ESP32.svg?label=Latest%20Release)](https://github.com/emsesp/EMS-ESP32/blob/main/CHANGELOG.md)
[![release-date](https://img.shields.io/github/release-date/emsesp/EMS-ESP32.svg?label=Released)](https://github.com/emsesp/EMS-ESP32/commits/main)
[![license](https://img.shields.io/github/license/emsesp/EMS-ESP32.svg)](LICENSE)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=emsesp_EMS-ESP32&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=emsesp_EMS-ESP32)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/9441142f49424ef891e8f5251866ee6b)](https://www.codacy.com/gh/emsesp/EMS-ESP32/dashboard?utm_source=github.com&utm_medium=referral&utm_content=emsesp/EMS-ESP32&utm_campaign=Badge_Grade)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/9441142f49424ef891e8f5251866ee6b)](https://app.codacy.com/gh/emsesp/EMS-ESP32/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
[![downloads](https://img.shields.io/github/downloads/emsesp/EMS-ESP32/total.svg)](https://github.com/emsesp/EMS-ESP32/releases)
[![chat](https://img.shields.io/discord/816637840644505620.svg?style=flat-square&color=blueviolet)](https://discord.gg/3J3GgnzpyT)
[![GitHub stars](https://img.shields.io/github/stars/emsesp/EMS-ESP32.svg?style=social&label=Star)](https://github.com/emsesp/EMS-ESP32/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/emsesp/EMS-ESP32.svg?style=social&label=Fork)](https://github.com/emsesp/EMS-ES32P/network)
[![GitHub forks](https://img.shields.io/github/forks/emsesp/EMS-ESP32.svg?style=social&label=Fork)](https://github.com/emsesp/EMS-ESP32/network)
[![donate](https://img.shields.io/badge/donate-PayPal-blue.svg)](https://www.paypal.com/paypalme/prderbyshire/2)
**EMS-ESP** is an open-source firmware for the Espressif ESP32 microcontroller that communicates with **EMS** (Energy Management System) based equipment from manufacturers like Bosch, Buderus, Nefit, Junkers, Worcester and Sieger. It requires a small gateway circuit to interface with the EMS bus which can be purchased from <https://bbqkees-electronics.nl> or custom built.
**EMS-ESP** is an open-source firmware for the Espressif ESP32 microcontroller to communicate with **EMS** (Energy Management System) compatible equipment from manufacturers such as Bosch, Buderus, Nefit, Junkers, Worcester, Sieger, elm.leblanc and iVT.
## **Features**
It requires a small circuit to interface with the EMS bus which can be purchased from <https://bbqkees-electronics.nl> or custom built.
- A multi-user, multi-language secure web interface to change settings and monitor incoming data
- A console, accessible via Serial and Telnet for more advanced monitoring
- Native support for Home Assistant, Domoticz and openHAB via [MQTT Discovery](https://www.home-assistant.io/docs/mqtt/discovery/)
- Can run standalone as an independent WiFi Access Point or join an existing WiFi network
- Easy first-time configuration via a web Captive Portal
- Support for more than [110+ EMS devices](https://emsesp.github.io/docs/All-Devices/) (boilers, thermostats, solar modules, mixer modules, heat pumps, gateways, switches, heat sources)
## 📦&nbsp; **Key Features**
## **Documentation**
- Compatible with EMS, EMS+, EMS2, EMS Plus, Logamatic EMS, Junkers 2-wire, Heatronic 3 and 4
- Supporting over 120 different EMS compatible devices such as thermostats, boilers, heat pumps, mixing units, solar modules, connect modules, ventilation units, switches and more
- Easy to add external Temperature and Analog sensors that are attached to GPIO pins on the ESP32 board
- A multi-user, multi-language web interface to change settings and monitor incoming data
- A simple to use console, accessible via Serial/USB or Telnet for advanced operations and detailed monitoring
- Native integration with Home Assistant, Domoticz, openHAB and Modbus
- Easy setup and install with automatic updates
- Simulation of remote thermostats
- Localized in 11 languages, and customizable to rename any device or sensor
- Extendable by adding own custom EMS entities
- Expandable via adding user-built external modules
- A powerful Scheduler to automate tasks and trigger events based data changes
- A Notification service to alert you of important events
For the complete documentation on how to install, configure and get support visit the [EMS-ESP Wiki](https://emsesp.github.io/docs).
## 🚀&nbsp; **Installing**
## **Support**
Head over to [download.emsesp.org](https://download.emsesp.org) for instructions on how to install EMS-ESP. There is also further details on which boards are supported in [this section](https://docs.emsesp.org/Installing/) of the documentation.
## 📋&nbsp; **Documentation**
Visit [emsesp.org](https://docs.emsesp.org) for more details on how to install and configure EMS-ESP. There is also a collection of Frequently Asked Questions and Troubleshooting tips with example customizations from the community.
## 💬&nbsp; **Getting Support**
To chat with the community reach out on our [Discord Server](https://discord.gg/3J3GgnzpyT).
If you like **EMS-ESP**, please give it a star, or fork it and contribute or offer a small donation!
If you find an issue or have a request, see [how to request support](https://docs.emsesp.org/Support/) on how to submit a bug report or feature request.
## **Demo**
## 🎥&nbsp; **Live Demo**
For a live demo of the Web UI click [here](https://ems-esp.derbyshire.nl) and log in with any username/password.
For a live demo go to [demo.emsesp.org](https://demo.emsesp.org). Pick a language from the sign on page and log in with any username or password. Note not all features are operational as it's based on static data.
## **Contributors**
## 💖&nbsp; **Contributors**
EMS-ESP is a project owned and maintained by [proddy](https://github.com/proddy) and [MichaelDvP](https://github.com/MichaelDvP).
EMS-ESP is a project created by [proddy](https://github.com/proddy) and owned and maintained by both [proddy](https://github.com/proddy) and [MichaelDvP](https://github.com/MichaelDvP) with support from [BBQKees Electronics](https://bbqkees-electronics.nl).
## **Libraries used**
If you like **EMS-ESP**, please give it a ✨ on GitHub, or even better fork it and contribute. You can also offer a small donation. This is an open-source project maintained by volunteers, and your support is greatly appreciated.
- [esp8266-react](https://github.com/rjwats/esp8266-react) by @rjwats for the framework that provides the core of the Web UI
- [uuid-\*](https://github.com/nomis/mcu-uuid-console) from @nomis. The console, syslog, telnet and logging are based off these open source libraries
- [ArduinoJson](https://github.com/bblanchon/ArduinoJson) for all the JSON
- [espMqttClient](https://github.com/bertmelis/espMqttClient) for the MQTT client, with custom modifications from @MichaelDvP and @proddy
- ESPAsyncWebServer and AsyncTCP for the Web server and TCP backends, with custom modifications for performance
## 📦&nbsp; **Building**
## **License**
To build the web interface only, run `platformio run -e build_webUI`. This will install the necessary dependencies and build the web interface and also create the embedded code used need to build the firmware. You can run the web interface locally by going to the `interface` directory and running `pnpm standalone`.
To build the firmware, run `platformio run`. This will build the firmware for all ESP32 modules and place the binaries in the `build/firmware` folder. If you want to configure the build for a single platform create a local `pio_local.ni` file in the root directory (see example in `pio_local.ini_example`).
## 📢&nbsp; **Libraries used**
- [esp8266-react](https://github.com/rjwats/esp8266-react) originally by @rjwats for the core framework that provides the Web UI, which has been heavily modified
- [uuid-\*](https://github.com/nomis/mcu-uuid-console) from @nomis. The console, syslog, telnet and logging are based off these awesome open source libraries
- [ArduinoJson](https://github.com/bblanchon/ArduinoJson) for all the JSON processing
- [espMqttClient](https://github.com/bertmelis/espMqttClient) for the MQTT client
- [ESPAsyncWebServer](https://github.com/ESP32Async/ESPAsyncWebServer) and [AsyncTCP](https://github.com/ESP32Async/AsyncTCP) for the Web server
## 📜&nbsp; **License**
This program is licensed under GPL-3.0
@@ -59,14 +106,14 @@ This program is licensed under GPL-3.0
| | |
| ---------------------------------- | -------------------------------- |
| <img src="media/web_settings.png"> | <img src="media/web_status.png"> |
| <img src="media/web_devices.png"> | <img src="media/web_mqtt.png"> |
| <img src="media/web_edit.png"> | <img src="media/web_log.png"> |
| ![Web Settings](media/web_settings.png) | ![Web Status](media/web_status.png) |
| ![Web Devices](media/web_devices.png) | ![Web MQTT](media/web_mqtt.png) |
| ![Web Edit](media/web_edit.png) | ![Web Log](media/web_log.png) |
### Telnet Console
<img src="media/console0.png" width=80% height=80%>
![Console](media/console0.png)
### In Home Assistant
### Home Assistant
<img src="media/ha_lovelace.png" width=80% height=80%>
![Home Assistant](media/ha_lovelace.png)

45
boards/c3_mini_4M.json Normal file
View File

@@ -0,0 +1,45 @@
{
"build": {
"arduino": {
"ldscript": "esp32c3_out.ld"
},
"core": "esp32",
"extra_flags": [
"-DTASMOTA_SDK",
"-DARDUINO_LOLIN_C3_MINI",
"-DARDUINO_USB_MODE=1",
"-DARDUINO_USB_CDC_ON_BOOT=1"
],
"f_cpu": "160000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [
[
"0X303A",
"0x1001"
]
],
"mcu": "esp32c3",
"variant": "lolin_c3_mini"
},
"connectivity": [
"wifi"
],
"debug": {
"openocd_target": "esp32c3.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "WEMOS LOLIN C3 Mini",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://www.wemos.cc/en/latest/c3/c3_mini.html",
"vendor": "WEMOS"
}

34
boards/esp32dev.json Normal file
View File

@@ -0,0 +1,34 @@
{
"build": {
"core": "esp32",
"f_cpu": "240000000L",
"f_flash": "40000000L",
"flash_mode": "dio",
"mcu": "esp32",
"variant": "esp32"
},
"connectivity": [
"wifi",
"ethernet"
],
"debug": {
"openocd_board": "esp32.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "Espressif ESP32 Dev Module",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 327680,
"maximum_size": 16777216,
"require_upload_port": true,
"speed": 460800
},
"download": {
"speed": 230400
},
"url": "https://en.wikipedia.org/wiki/ESP32",
"vendor": "Espressif"
}

47
boards/s2_4M_P.json Normal file
View File

@@ -0,0 +1,47 @@
{
"build": {
"arduino": {
"ldscript": "esp32s2_out.ld"
},
"core": "esp32",
"extra_flags": [
"-DBOARD_HAS_PSRAM",
"-DTASMOTA_SDK",
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DARDUINO_USB_MODE=0"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dio",
"hwids": [
[
"0X303A",
"0x80C2"
]
],
"mcu": "esp32s2",
"variant": "lolin_s2_mini"
},
"connectivity": [
"wifi"
],
"debug": {
"openocd_target": "esp32s2.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "WEMOS LOLIN S2 Mini",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"use_1200bps_touch": true,
"wait_for_upload_port": true,
"require_upload_port": true,
"speed": 921600
},
"url": "https://www.wemos.cc/en/latest/s2/s2_mini.html",
"vendor": "WEMOS"
}

44
boards/s3_16M_P.json Normal file
View File

@@ -0,0 +1,44 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"memory_type": "qio_opi"
},
"core": "esp32",
"extra_flags": [
"-DBOARD_HAS_PSRAM",
"-DARDUINO_USB_MODE=1",
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=1"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"mcu": "esp32s3",
"variant": "esp32s3"
},
"connectivity": [
"wifi"
],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "Espressif ESP32-S3 16M Flash OPI PSRAM, 4608KB Code/OTA, 2MB FS",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 327680,
"maximum_size": 16777216,
"require_upload_port": true,
"speed": 460800
},
"download": {
"speed": 230400
},
"url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/",
"vendor": "Espressif"
}

37
boards/s3_32M_P.json Normal file
View File

@@ -0,0 +1,37 @@
{
"build": {
"arduino":{
"memory_type": "opi_opi"
},
"core": "esp32",
"extra_flags": "-DBOARD_HAS_PSRAM",
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "opi",
"mcu": "esp32s3",
"variant": "esp32s3"
},
"connectivity": [
"wifi"
],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "Espressif ESP32-S3 32M Flash OPI PSRAM, 4608KB Code/OTA, 2MB FS",
"upload": {
"flash_size": "32MB",
"maximum_ram_size": 327680,
"maximum_size": 16777216,
"require_upload_port": true,
"speed": 460800
},
"download": {
"speed": 230400
},
"url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/",
"vendor": "Espressif"
}

35
boards/s_16M.json Normal file
View File

@@ -0,0 +1,35 @@
{
"build": {
"core": "esp32",
"extra_flags": "-DTASMOTA_SDK",
"f_cpu": "240000000L",
"f_flash": "40000000L",
"flash_mode": "dio",
"mcu": "esp32",
"variant": "esp32"
},
"connectivity": [
"wifi",
"ethernet"
],
"debug": {
"openocd_target": "esp32.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "Espressif ESP32 16M Flash, 4608KB Code/OTA, 2MB FS",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 327680,
"maximum_size": 16777216,
"require_upload_port": true,
"speed": 460800
},
"download": {
"speed": 230400
},
"url": "https://en.wikipedia.org/wiki/ESP32",
"vendor": "Espressif"
}

35
boards/s_16M_P.json Normal file
View File

@@ -0,0 +1,35 @@
{
"build": {
"core": "esp32",
"extra_flags": "-DBOARD_HAS_PSRAM",
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dio",
"mcu": "esp32",
"variant": "esp32"
},
"connectivity": [
"wifi",
"ethernet"
],
"debug": {
"openocd_target": "esp32.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "Espressif ESP32 16M Flash DIO PSRAM, 4608KB Code/OTA, 2MB FS",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 327680,
"maximum_size": 16777216,
"require_upload_port": true,
"speed": 460800
},
"download": {
"speed": 230400
},
"url": "https://en.wikipedia.org/wiki/ESP32",
"vendor": "Espressif"
}

34
boards/s_4M.json Normal file
View File

@@ -0,0 +1,34 @@
{
"build": {
"core": "esp32",
"extra_flags": "-DTASMOTA_SDK",
"f_cpu": "240000000L",
"f_flash": "40000000L",
"flash_mode": "dio",
"mcu": "esp32",
"variant": "esp32"
},
"connectivity": [
"wifi"
],
"debug": {
"openocd_target": "esp32.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "Tasmota ESP32 4M Flash, 4608KB Code/OTA, 2MB FS",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"download": {
"speed": 230400
},
"url": "https://en.wikipedia.org/wiki/ESP32",
"vendor": "Espressif"
}

View File

@@ -0,0 +1,48 @@
{
"build": {
"core": "esp32",
"extra_flags": [
"-DARDUINO_XIAO_ESP32C6",
"-DARDUINO_USB_MODE=1",
"-DARDUINO_USB_CDC_ON_BOOT=1"
],
"f_cpu": "160000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [
[
"0x2886",
"0x0046"
],
[
"0x303a",
"0x1001"
]
],
"mcu": "esp32c6",
"variant": "XIAO_ESP32C6"
},
"connectivity": [
"wifi",
"bluetooth",
"zigbee",
"thread"
],
"debug": {
"openocd_target": "esp32c6.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "Seeed Studio XIAO ESP32C6",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://wiki.seeedstudio.com/XIAO_ESP32C6_Getting_Started/",
"vendor": "Seeed Studio"
}

39
cspell.json Normal file
View File

@@ -0,0 +1,39 @@
{
"$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json",
"version": "0.2",
"dictionaryDefinitions": [
{
"name": "project-words",
"path": "./project-words.txt",
"addWords": true
}
],
"dictionaries": ["project-words"],
"ignorePaths": [
"node_modules",
"compile_commands.json",
"WWWData.h", "**/venv/**",
"lib/eModbus",
"lib/ESPAsyncWebServer",
"lib/espMqttClient",
"analyse.html",
"dist",
"**/*.csv",
"**/*.md",
"**/*.py",
"locale_translations.h",
"TZ.tsx",
"**/*.txt",
"build/**",
"**/i18n/**",
"/project-words.txt",
"Makefile",
"**/*.ini",
"**/*.json",
"src/core/modbus_entity_parameters.hpp",
"sdkconfig.*",
"managed_components/**",
"pnpm-*.yaml",
"vite.config.ts"
]
}

85
data/pre_load.json Normal file
View File

@@ -0,0 +1,85 @@
{
"type": "settings",
"Network": {
"ssid": "my_wifi_ssid",
"bssid": "",
"password": "my_wifi_password",
"hostname": "ems-esp"
},
"AP": {
"provision_mode": 2,
"ssid": "ems-esp",
"password": "ems-esp-neo",
"channel": 1,
"ssid_hidden": false,
"max_clients": 4,
"local_ip": "192.168.4.1",
"gateway_ip": "192.168.4.1",
"subnet_mask": "255.255.255.0"
},
"MQTT": {
"enableTLS": false,
"rootCA": "",
"enabled": false,
"host": "127.0.0.1",
"port": 1883,
"base": "ems-esp",
"username": "username",
"password": "password",
"client_id": "ems-esp",
"entity_format": 1,
"publish_time_boiler": 10,
"publish_time_thermostat": 10,
"publish_time_solar": 10,
"publish_time_mixer": 10,
"publish_time_water": 10,
"publish_time_other": 60,
"publish_time_sensor": 10,
"publish_time_heartbeat": 60,
"mqtt_qos": 0,
"mqtt_retain": false,
"ha_enabled": false,
"nested_format": 1,
"discovery_prefix": "homeassistant",
"discovery_type": 0,
"publish_single": false,
"publish_single2cmd": false,
"send_response": false
},
"NTP": {
"enabled": true,
"server": "time.google.com",
"tz_label": "Europe/Amsterdam",
"tz_format": "CET-1CEST,M3.5.0,M10.5.0/3"
},
"Security": {
"jwt_secret": "ems-esp-neo",
"users": [
{
"username": "admin",
"password": "admin",
"admin": true
},
{
"username": "guest",
"password": "guest",
"admin": false
}
]
},
"Settings": {
"board_profile": "S3",
"locale": "en",
"tx_mode": 1,
"ems_bus_id": 11,
"boiler_heatingoff": false,
"hide_led": true,
"telnet_enabled": true,
"notoken_api": false,
"analog_enabled": true,
"fahrenheit": false,
"bool_format": 1,
"bool_dashboard": 1,
"enum_format": 1
}
}

File diff suppressed because it is too large Load Diff

5809
docs/dump_entities.csv Normal file

File diff suppressed because it is too large Load Diff

231
docs/dump_telegrams.csv Normal file
View File

@@ -0,0 +1,231 @@
telegram_type_id,name,is_fetched
0x04,UBAFactory,fetched
0x06,RCTime,
0x0A,EasyMonitor,fetched
0x10,UBAErrorMessage1,
0x11,UBAErrorMessage2,
0x12,RCErrorMessage,
0x13,RCErrorMessage2,
0x14,UBATotalUptime,fetched
0x15,UBAMaintenanceData,
0x16,UBAParameters,fetched
0x18,UBAMonitorFast,
0x19,UBAMonitorSlow,
0x1A,UBASetPoints,
0x1C,UBAMaintenanceStatus,
0x1E,HydrTemp,
0x23,JunkersSetMixer,fetched
0x27,UBASettingsWW,fetched
0x28,WeatherComp,fetched
0x2A,MC110Status,
0x2E,Meters,
0x33,UBAParameterWW,fetched
0x34,UBAMonitorWW,
0x35,UBAFlags,
0x37,WWSettings,fetched
0x38,WWTimer,fetched
0x39,WWCircTimer,fetched
0x3A,RC30WWSettings,fetched
0x3B,Energy,
0x3D,RC35Set,
0x3E,RC35Monitor,
0x3F,RC35Timer,
0x40,RC30Temp,
0x41,RC30Monitor,
0x42,RC35Timer2,
0x47,RC35Set,
0x48,RC35Monitor,
0x49,RC35Timer,
0x4C,RC35Timer2,
0x51,RC35Set,
0x52,RC35Monitor,
0x53,RC35Timer,
0x56,RC35Timer2,
0x5B,RC35Set,
0x5C,RC35Monitor,
0x5D,RC35Timer,
0x60,RC35Timer2,
0x96,SM10Config,fetched
0x97,SM10Monitor,
0x9C,WM10MonitorMessage,
0x9D,WM10SetMessage,
0xA2,RCError,
0xA3,RCOutdoorTemp,
0xA5,IBASettings,fetched
0xA7,RC30Set,
0xA9,RC30Vacation,fetched
0xAA,MMConfigMessage,fetched
0xAB,MMStatusMessage,
0xAC,MMSetMessage,
0xAF,RC20Remote,
0xB0,RC10Set,
0xB1,RC10Monitor,
0xBB,HybridSettings,fetched
0xBF,ErrorMessage,
0xC0,RCErrorMessage,
0xC2,UBAErrorMessage3,
0xC6,UBAErrorMessage3,
0xD1,UBAOutdoorTemp,
0xE3,UBAMonitorSlowPlus2,
0xE4,UBAMonitorFastPlus,
0xE5,UBAMonitorSlowPlus,
0xE6,UBAParametersPlus,fetched
0xE9,UBAMonitorWWPlus,
0xEA,UBAParameterWWPlus,fetched
0x0101,ISM1Set,fetched
0x0103,ISM1StatusMessage,fetched
0x0104,ISM2StatusMessage,
0x010C,IPMStatusMessage,
0x011E,JunkersDisp,fetched
0x012E,HPEnergy1,
0x013B,HPEnergy2,
0x0165,JunkersSet,
0x0166,JunkersSet,
0x0167,JunkersSet,
0x0168,JunkersSet,
0x016E,Absent,fetched
0x016F,JunkersMonitor,
0x0170,JunkersMonitor,
0x0171,JunkersMonitor,
0x0172,JunkersMonitor,
0x0179,JunkersSet,
0x017A,JunkersSet,
0x017B,JunkersSet,
0x017C,JunkersSet,
0x01D3,JunkersDhw,fetched
0x023A,RC300OutdoorTemp,fetched
0x023E,PVSettings,fetched
0x0240,RC300Settings,fetched
0x0241,RC300Settings,fetched
0x0267,RC300Floordry,
0x0269,RC300Holiday,fetched
0x0291,HPMode,fetched
0x0292,HPMode,fetched
0x0293,HPMode,fetched
0x0294,HPMode,fetched
0x029B,RC300Curves,
0x029C,RC300Curves,
0x029D,RC300Curves,
0x029E,RC300Curves,
0x029F,RC300Curves,
0x02A0,RC300Curves,
0x02A1,RC300Curves,
0x02A2,RC300Curves,
0x02A5,RC300Monitor,
0x02A6,RC300Monitor,
0x02A7,RC300Monitor,
0x02A8,RC300Monitor,
0x02A9,RC300Monitor,
0x02AA,RC300Monitor,
0x02AB,RC300Monitor,
0x02AC,RC300Monitor,
0x02AF,RC300Summer,
0x02B0,RC300Summer,
0x02B1,RC300Summer,
0x02B2,RC300Summer,
0x02B3,RC300Summer,
0x02B4,RC300Summer,
0x02B5,RC300Summer,
0x02B6,RC300Summer,
0x02B9,RC300Set,
0x02BA,RC300Set,
0x02BB,RC300Set,
0x02BC,RC300Set,
0x02BD,RC300Set,
0x02BE,RC300Set,
0x02BF,RC300Set,
0x02C0,RC300Set,
0x02CC,HPPressure,fetched
0x02CD,MMPLUSConfigMessage,fetched
0x02CE,RC300Set2,
0x02D0,RC300Set2,
0x02D2,RC300Set2,
0x02D6,HPPump2,fetched
0x02D7,MMPLUSStatusMessage,
0x02E0,UBASetPoints,
0x02F5,RC300WWmode,fetched
0x02F6,RC300WW2mode,fetched
0x0313,MMPLUSConfigMessage_WWC,fetched
0x031B,RC300WWtemp,fetched
0x031D,RC300WWmode2,
0x031E,RC300WWmode2,
0x0331,MMPLUSStatusMessage_WWC,
0x0358,SM100SystemConfig,fetched
0x035A,SM100CircuitConfig,fetched
0x035C,SM100HeatAssist,fetched
0x035D,SM100Circuit2Config,fetched
0x035F,SM100Config1,fetched
0x0361,SM100Differential,fetched
0x0362,SM100Monitor,
0x0363,SM100Monitor2,
0x0364,SM100Status,
0x0366,SM100Config,
0x036A,SM100Status2,
0x0380,SM100CollectorConfig,fetched
0x038E,SM100Energy,fetched
0x0391,SM100Time,fetched
0x043F,CRHolidays,fetched
0x0467,HPSet,
0x0468,HPSet,
0x0469,HPSet,
0x046A,HPSet,
0x0471,RC300Summer2,
0x0472,RC300Summer2,
0x0473,RC300Summer2,
0x0474,RC300Summer2,
0x0475,RC300Summer2,
0x0476,RC300Summer2,
0x0477,RC300Summer2,
0x0478,RC300Summer2,
0x047B,HP2,
0x0484,HPSilentMode,fetched
0x0485,HpCooling,fetched
0x0486,HpInConfig,fetched
0x0488,HPValve,fetched
0x048A,HpPool,fetched
0x048B,HPPumps,fetched
0x048D,HpPower,fetched
0x048F,HpTemperatures,
0x0491,HPAdditionalHeater,fetched
0x0492,HpHeaterConfig,fetched
0x0494,UBAEnergySupplied,
0x0495,UBAInformation,
0x0499,HPDhwSettings,fetched
0x049C,HPSettings2,fetched
0x049D,HPSettings3,fetched
0x04A2,HpInput,fetched
0x04A5,HPFan,fetched
0x04A7,HPPowerLimit,fetched
0x04AA,HPPower2,fetched
0x04AE,HPEnergy,fetched
0x04AF,HPMeters,fetched
0x055C,VentilationSet,fetched
0x056B,VentilationMode,fetched
0x0583,VentilationMonitor,
0x0585,Blowerspeed,
0x0587,Bypass,
0x05BA,HpPoolStatus,fetched
0x05D9,Airquality,
0x0772,HIUSettings,
0x0779,HIUMonitor,
0x07A5,SM100wwCirc,fetched
0x07A6,SM100wwParam,fetched
0x07AA,SM100wwStatus,
0x07AB,SM100wwCommand,
0x07AC,SM100wwParam1,
0x07AD,SM100ValveStatus,
0x07AE,SM100wwKeepWarm,fetched
0x07D6,SM100wwTemperature,
0x07E0,SM100wwStatus2,fetched
0x0935,EM100SetMessage,fetched
0x0936,EM100OutMessage,
0x0937,EM100TempMessage,
0x0938,EM100InputMessage,
0x0939,EM100MonitorMessage,
0x093A,EM100ConfigMessage,
0x0998,HPSettings,fetched
0x0999,HPFunctionTest,fetched
0x099A,HPStarts,
0x099B,HPFlowTemp,
0x099C,HPComp,
0x09A0,HPTemperature,
1 telegram_type_id name is_fetched
2 0x04 UBAFactory fetched
3 0x06 RCTime
4 0x0A EasyMonitor fetched
5 0x10 UBAErrorMessage1
6 0x11 UBAErrorMessage2
7 0x12 RCErrorMessage
8 0x13 RCErrorMessage2
9 0x14 UBATotalUptime fetched
10 0x15 UBAMaintenanceData
11 0x16 UBAParameters fetched
12 0x18 UBAMonitorFast
13 0x19 UBAMonitorSlow
14 0x1A UBASetPoints
15 0x1C UBAMaintenanceStatus
16 0x1E HydrTemp
17 0x23 JunkersSetMixer fetched
18 0x27 UBASettingsWW fetched
19 0x28 WeatherComp fetched
20 0x2A MC110Status
21 0x2E Meters
22 0x33 UBAParameterWW fetched
23 0x34 UBAMonitorWW
24 0x35 UBAFlags
25 0x37 WWSettings fetched
26 0x38 WWTimer fetched
27 0x39 WWCircTimer fetched
28 0x3A RC30WWSettings fetched
29 0x3B Energy
30 0x3D RC35Set
31 0x3E RC35Monitor
32 0x3F RC35Timer
33 0x40 RC30Temp
34 0x41 RC30Monitor
35 0x42 RC35Timer2
36 0x47 RC35Set
37 0x48 RC35Monitor
38 0x49 RC35Timer
39 0x4C RC35Timer2
40 0x51 RC35Set
41 0x52 RC35Monitor
42 0x53 RC35Timer
43 0x56 RC35Timer2
44 0x5B RC35Set
45 0x5C RC35Monitor
46 0x5D RC35Timer
47 0x60 RC35Timer2
48 0x96 SM10Config fetched
49 0x97 SM10Monitor
50 0x9C WM10MonitorMessage
51 0x9D WM10SetMessage
52 0xA2 RCError
53 0xA3 RCOutdoorTemp
54 0xA5 IBASettings fetched
55 0xA7 RC30Set
56 0xA9 RC30Vacation fetched
57 0xAA MMConfigMessage fetched
58 0xAB MMStatusMessage
59 0xAC MMSetMessage
60 0xAF RC20Remote
61 0xB0 RC10Set
62 0xB1 RC10Monitor
63 0xBB HybridSettings fetched
64 0xBF ErrorMessage
65 0xC0 RCErrorMessage
66 0xC2 UBAErrorMessage3
67 0xC6 UBAErrorMessage3
68 0xD1 UBAOutdoorTemp
69 0xE3 UBAMonitorSlowPlus2
70 0xE4 UBAMonitorFastPlus
71 0xE5 UBAMonitorSlowPlus
72 0xE6 UBAParametersPlus fetched
73 0xE9 UBAMonitorWWPlus
74 0xEA UBAParameterWWPlus fetched
75 0x0101 ISM1Set fetched
76 0x0103 ISM1StatusMessage fetched
77 0x0104 ISM2StatusMessage
78 0x010C IPMStatusMessage
79 0x011E JunkersDisp fetched
80 0x012E HPEnergy1
81 0x013B HPEnergy2
82 0x0165 JunkersSet
83 0x0166 JunkersSet
84 0x0167 JunkersSet
85 0x0168 JunkersSet
86 0x016E Absent fetched
87 0x016F JunkersMonitor
88 0x0170 JunkersMonitor
89 0x0171 JunkersMonitor
90 0x0172 JunkersMonitor
91 0x0179 JunkersSet
92 0x017A JunkersSet
93 0x017B JunkersSet
94 0x017C JunkersSet
95 0x01D3 JunkersDhw fetched
96 0x023A RC300OutdoorTemp fetched
97 0x023E PVSettings fetched
98 0x0240 RC300Settings fetched
99 0x0241 RC300Settings fetched
100 0x0267 RC300Floordry
101 0x0269 RC300Holiday fetched
102 0x0291 HPMode fetched
103 0x0292 HPMode fetched
104 0x0293 HPMode fetched
105 0x0294 HPMode fetched
106 0x029B RC300Curves
107 0x029C RC300Curves
108 0x029D RC300Curves
109 0x029E RC300Curves
110 0x029F RC300Curves
111 0x02A0 RC300Curves
112 0x02A1 RC300Curves
113 0x02A2 RC300Curves
114 0x02A5 RC300Monitor
115 0x02A6 RC300Monitor
116 0x02A7 RC300Monitor
117 0x02A8 RC300Monitor
118 0x02A9 RC300Monitor
119 0x02AA RC300Monitor
120 0x02AB RC300Monitor
121 0x02AC RC300Monitor
122 0x02AF RC300Summer
123 0x02B0 RC300Summer
124 0x02B1 RC300Summer
125 0x02B2 RC300Summer
126 0x02B3 RC300Summer
127 0x02B4 RC300Summer
128 0x02B5 RC300Summer
129 0x02B6 RC300Summer
130 0x02B9 RC300Set
131 0x02BA RC300Set
132 0x02BB RC300Set
133 0x02BC RC300Set
134 0x02BD RC300Set
135 0x02BE RC300Set
136 0x02BF RC300Set
137 0x02C0 RC300Set
138 0x02CC HPPressure fetched
139 0x02CD MMPLUSConfigMessage fetched
140 0x02CE RC300Set2
141 0x02D0 RC300Set2
142 0x02D2 RC300Set2
143 0x02D6 HPPump2 fetched
144 0x02D7 MMPLUSStatusMessage
145 0x02E0 UBASetPoints
146 0x02F5 RC300WWmode fetched
147 0x02F6 RC300WW2mode fetched
148 0x0313 MMPLUSConfigMessage_WWC fetched
149 0x031B RC300WWtemp fetched
150 0x031D RC300WWmode2
151 0x031E RC300WWmode2
152 0x0331 MMPLUSStatusMessage_WWC
153 0x0358 SM100SystemConfig fetched
154 0x035A SM100CircuitConfig fetched
155 0x035C SM100HeatAssist fetched
156 0x035D SM100Circuit2Config fetched
157 0x035F SM100Config1 fetched
158 0x0361 SM100Differential fetched
159 0x0362 SM100Monitor
160 0x0363 SM100Monitor2
161 0x0364 SM100Status
162 0x0366 SM100Config
163 0x036A SM100Status2
164 0x0380 SM100CollectorConfig fetched
165 0x038E SM100Energy fetched
166 0x0391 SM100Time fetched
167 0x043F CRHolidays fetched
168 0x0467 HPSet
169 0x0468 HPSet
170 0x0469 HPSet
171 0x046A HPSet
172 0x0471 RC300Summer2
173 0x0472 RC300Summer2
174 0x0473 RC300Summer2
175 0x0474 RC300Summer2
176 0x0475 RC300Summer2
177 0x0476 RC300Summer2
178 0x0477 RC300Summer2
179 0x0478 RC300Summer2
180 0x047B HP2
181 0x0484 HPSilentMode fetched
182 0x0485 HpCooling fetched
183 0x0486 HpInConfig fetched
184 0x0488 HPValve fetched
185 0x048A HpPool fetched
186 0x048B HPPumps fetched
187 0x048D HpPower fetched
188 0x048F HpTemperatures
189 0x0491 HPAdditionalHeater fetched
190 0x0492 HpHeaterConfig fetched
191 0x0494 UBAEnergySupplied
192 0x0495 UBAInformation
193 0x0499 HPDhwSettings fetched
194 0x049C HPSettings2 fetched
195 0x049D HPSettings3 fetched
196 0x04A2 HpInput fetched
197 0x04A5 HPFan fetched
198 0x04A7 HPPowerLimit fetched
199 0x04AA HPPower2 fetched
200 0x04AE HPEnergy fetched
201 0x04AF HPMeters fetched
202 0x055C VentilationSet fetched
203 0x056B VentilationMode fetched
204 0x0583 VentilationMonitor
205 0x0585 Blowerspeed
206 0x0587 Bypass
207 0x05BA HpPoolStatus fetched
208 0x05D9 Airquality
209 0x0772 HIUSettings
210 0x0779 HIUMonitor
211 0x07A5 SM100wwCirc fetched
212 0x07A6 SM100wwParam fetched
213 0x07AA SM100wwStatus
214 0x07AB SM100wwCommand
215 0x07AC SM100wwParam1
216 0x07AD SM100ValveStatus
217 0x07AE SM100wwKeepWarm fetched
218 0x07D6 SM100wwTemperature
219 0x07E0 SM100wwStatus2 fetched
220 0x0935 EM100SetMessage fetched
221 0x0936 EM100OutMessage
222 0x0937 EM100TempMessage
223 0x0938 EM100InputMessage
224 0x0939 EM100MonitorMessage
225 0x093A EM100ConfigMessage
226 0x0998 HPSettings fetched
227 0x0999 HPFunctionTest fetched
228 0x099A HPStarts
229 0x099B HPFlowTemp
230 0x099C HPComp
231 0x09A0 HPTemperature

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +0,0 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x005000,
otadata, data, ota, , 0x002000,
app0, app, ota_0, , 0x5D0000,
app1, app, ota_1, , 0x5D0000,
nvs1, data, nvs, , 0x040000,
spiffs, data, spiffs, , 0x400000,
coredump, data, coredump,, 0x010000,
1 # Name Type SubType Offset Size Flags
2 nvs data nvs 0x9000 0x005000
3 otadata data ota 0x002000
4 app0 app ota_0 0x5D0000
5 app1 app ota_1 0x5D0000
6 nvs1 data nvs 0x040000
7 spiffs data spiffs 0x400000
8 coredump data coredump 0x010000

View File

@@ -25,11 +25,6 @@ build_flags =
-D FACTORY_NTP_TIME_ZONE_FORMAT=\"CET-1CEST,M3.5.0,M10.5.0/3\"
-D FACTORY_NTP_SERVER=\"time.google.com\"
; OTA settings
-D FACTORY_OTA_PORT=8266
-D FACTORY_OTA_PASSWORD=\"ems-esp-neo\"
-D FACTORY_OTA_ENABLED=false
; MQTT settings
-D FACTORY_MQTT_ENABLED=false
-D FACTORY_MQTT_HOST=\"\"

View File

@@ -1,12 +0,0 @@
node_modules/
build/
dist/
.yarn/
.prettierrc
.eslintrc*
env.d.ts
progmem-generator.js
unpack.ts
vite.config.ts
package.json

View File

@@ -1,108 +0,0 @@
{
"env": {
"browser": true,
"es6": true
},
"extends": [
"eslint:recommended",
// "airbnb/hooks",
// "airbnb-typescript",
"plugin:react/recommended",
"plugin:react/jsx-runtime",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking",
"plugin:prettier/recommended",
"plugin:import/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": "latest",
"sourceType": "module",
"tsconfigRootDir": ".",
"project": ["tsconfig.json"]
},
"plugins": ["react", "@typescript-eslint", "autofix", "react-hooks"],
"settings": {
"import/resolver": {
"typescript": {
"project": "./tsconfig.json"
}
},
"react": {
"version": "18.x"
}
},
"rules": {
"object-shorthand": "error",
"no-console": "warn",
"@typescript-eslint/consistent-type-definitions": ["off", "type"],
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-unsafe-call": "off",
"@typescript-eslint/no-unsafe-enum-comparison": "off",
"@typescript-eslint/no-unsafe-assignment": "off",
"@typescript-eslint/no-unsafe-return": "off",
"@typescript-eslint/no-unsafe-member-access": "off",
"@typescript-eslint/naming-convention": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unsafe-argument": "off",
"@typescript-eslint/restrict-plus-operands": "off",
"@typescript-eslint/no-unused-expressions": "off",
"@typescript-eslint/no-implied-eval": "off",
"@typescript-eslint/no-misused-promises": "off",
"arrow-body-style": ["error", "as-needed"],
"react-hooks/exhaustive-deps": "warn",
"@typescript-eslint/consistent-type-imports": [
"error",
{
"prefer": "type-imports"
}
],
"import/order": [
"warn",
{
"groups": ["builtin", "external", "parent", "sibling", "index", "object", "type"],
"pathGroups": [
{
"pattern": "@/**/**",
"group": "parent",
"position": "before"
}
],
"alphabetize": { "order": "asc" }
}
],
// "autofix/no-unused-vars": [
// "error",
// {
// "argsIgnorePattern": "^_",
// "ignoreRestSiblings": true,
// "destructuredArrayIgnorePattern": "^_"
// }
// ],
"react/self-closing-comp": [
"error",
{
"component": true,
"html": true
}
],
"@typescript-eslint/ban-types": [
"error",
{
"extendDefaults": true,
"types": {
"{}": false
}
}
],
"prettier/prettier": [
"error",
{
"endOfLine": "auto"
}
]
}
}

View File

@@ -1,7 +0,0 @@
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions

View File

@@ -1,6 +1,7 @@
node_modules/
build/
dist/
src/i18n/*
.prettierrc
.yarn/
.typesafe-i18n.json
.typesafe-i18n.json

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +0,0 @@
compressionLevel: mixed
enableGlobalCache: false
nodeLinker: node-modules
yarnPath: .yarn/releases/yarn-4.1.1.cjs

View File

@@ -0,0 +1,43 @@
// @ts-check
import eslint from '@eslint/js';
import prettierConfig from 'eslint-config-prettier';
import tseslint from 'typescript-eslint';
export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.recommendedTypeChecked,
prettierConfig,
{
languageOptions: {
parserOptions: {
project: true
}
}
},
{
ignores: [
'dist/*',
'*.mjs',
'build/*',
'*.js',
'**/*.cjs',
'**/unpack.ts',
'i18n*.*'
]
},
{
rules: {
'@typescript-eslint/no-unsafe-enum-comparison': 'off',
'@typescript-eslint/no-unused-expressions': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-misused-promises': [
'error',
{
checksVoidReturn: false
}
]
}
}
);

View File

@@ -1,78 +1,68 @@
{
"name": "EMS-ESP",
"version": "3.6.5",
"description": "build EMS-ESP WebUI",
"homepage": "https://emsesp.github.io/docs",
"author": "proddy",
"version": "3.7.3",
"description": "EMS-ESP WebUI",
"homepage": "https://emsesp.org",
"author": "proddy, emsesp.org",
"license": "MIT",
"private": true,
"type": "module",
"scripts": {
"preinstall": "npx only-allow pnpm",
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"build-hosted": "typesafe-i18n --no-watch && vite build --mode hosted",
"preview-standalone": "typesafe-i18n --no-watch && vite build && concurrently -c \"auto\" \"npm:mock-api\" \"vite preview\"",
"mock-api": "bun --watch ../mock-api/server.ts",
"old_mock-api": "bun --watch ../mock-api/server.js",
"standalone": "concurrently -c \"auto\" \"typesafe-i18n\" \"npm:mock-api\" \"vite\"",
"old_standalone": "concurrently -c \"auto\" \"typesafe-i18n\" \"npm:old_mock-api\" \"vite\"",
"build-hosted": "typesafe-i18n && vite build --mode hosted",
"preview-standalone": "typesafe-i18n --no-watch && vite build && concurrently -c \"auto\" \"pnpm:mock-rest\" \"vite preview\"",
"mock-rest": "bun --watch ../mock-api/restServer.ts",
"standalone": "concurrently -c \"auto\" \"typesafe-i18n\" \"pnpm:mock-rest\" \"vite\"",
"typesafe-i18n": "typesafe-i18n --no-watch",
"webUI": "node progmem-generator.js",
"format": "prettier --write '**/*.{ts,tsx,js,css,json,md}'",
"lint": "eslint . --cache --fix"
"format": "prettier -l -w '**/*.{ts,tsx,js,css,json,md}'",
"lint": "eslint . --fix",
"standalone-devcontainer": "concurrently -c \"auto\" \"typesafe-i18n\" \"pnpm:mock-rest\" \"vite --host\""
},
"dependencies": {
"@alova/adapter-xhr": "^1.0.3",
"@babel/core": "^7.24.3",
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.0",
"@mui/icons-material": "^5.15.14",
"@mui/material": "^5.15.14",
"@table-library/react-table-library": "4.1.7",
"@types/imagemin": "^8.0.5",
"@types/lodash-es": "^4.17.12",
"@types/node": "^20.11.30",
"@types/react": "^18.2.69",
"@types/react-dom": "^18.2.22",
"@types/react-router-dom": "^5.3.3",
"alova": "^2.18.0",
"@alova/adapter-xhr": "2.2.1",
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@mui/icons-material": "^7.3.4",
"@mui/material": "^7.3.4",
"@table-library/react-table-library": "4.1.15",
"alova": "3.3.4",
"async-validator": "^4.2.5",
"history": "^5.3.0",
"formidable": "^3.5.4",
"jwt-decode": "^4.0.0",
"lodash-es": "^4.17.21",
"mime-types": "^2.1.35",
"react": "latest",
"react-dom": "latest",
"react-dropzone": "^14.2.3",
"react-icons": "^5.0.1",
"react-router-dom": "^6.22.3",
"react-toastify": "^10.0.5",
"sockette": "^2.0.6",
"magic-string": "^0.30.21",
"mime-types": "^3.0.1",
"preact": "^10.27.2",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"react-icons": "^5.5.0",
"react-router": "^7.9.5",
"react-toastify": "^11.0.5",
"typesafe-i18n": "^5.26.2",
"typescript": "^5.4.3"
"typescript": "^5.9.3"
},
"devDependencies": {
"@preact/compat": "^17.1.2",
"@preact/preset-vite": "^2.8.2",
"@typescript-eslint/eslint-plugin": "^7.3.1",
"@typescript-eslint/parser": "^7.3.1",
"concurrently": "^8.2.2",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-autofix": "^1.1.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-jsx-a11y": "^6.8.0",
"eslint-plugin-prettier": "alpha",
"eslint-plugin-react": "^7.34.1",
"eslint-plugin-react-hooks": "^4.6.0",
"preact": "^10.20.1",
"prettier": "^3.2.5",
"rollup-plugin-visualizer": "^5.12.0",
"terser": "^5.29.2",
"vite": "^5.2.4",
"@babel/core": "^7.28.5",
"@eslint/js": "^9.39.0",
"@preact/compat": "^18.3.1",
"@preact/preset-vite": "^2.10.2",
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
"@types/node": "^24.10.0",
"@types/react": "^19.2.2",
"@types/react-dom": "^19.2.2",
"concurrently": "^9.2.1",
"eslint": "^9.39.0",
"eslint-config-prettier": "^10.1.8",
"prettier": "^3.6.2",
"rollup-plugin-visualizer": "^6.0.5",
"terser": "^5.44.0",
"typescript-eslint": "^8.46.2",
"vite": "^7.1.12",
"vite-plugin-imagemin": "^0.6.1",
"vite-tsconfig-paths": "^4.3.2"
"vite-tsconfig-paths": "^5.1.4"
},
"packageManager": "yarn@4.1.1"
"packageManager": "pnpm@10.20.0"
}

6056
interface/pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
onlyBuiltDependencies:
- cwebp-bin
- esbuild
- gifsicle
- jpegtran-bin
- mozjpeg
- optipng-bin
- pngquant-bin

View File

@@ -1,80 +1,94 @@
import { readdirSync, existsSync, unlinkSync, readFileSync, createWriteStream } from 'fs';
import { resolve, relative, sep } from 'path';
import zlib from 'zlib';
import mime from 'mime-types';
import crypto from 'crypto';
import {
createWriteStream,
existsSync,
readFileSync,
readdirSync,
statSync,
unlinkSync
} from 'fs';
import mime from 'mime-types';
import { relative, resolve, sep } from 'path';
import zlib from 'zlib';
const ARDUINO_INCLUDES = '#include <Arduino.h>\n\n';
const INDENT = ' ';
const outputPath = '../lib/framework/WWWData.h';
const outputPath = '../src/ESP32React/WWWData.h';
const sourcePath = './dist';
const bytesPerLine = 20;
var totalSize = 0;
let totalSize = 0;
let bundleStats = {
js: { count: 0, uncompressed: 0, compressed: 0 },
css: { count: 0, uncompressed: 0, compressed: 0 },
html: { count: 0, uncompressed: 0, compressed: 0 },
svg: { count: 0, uncompressed: 0, compressed: 0 },
other: { count: 0, uncompressed: 0, compressed: 0 }
};
const generateWWWClass = () =>
`typedef std::function<void(const char * uri, const String & contentType, const uint8_t * content, size_t len, const String & hash)> RouteRegistrationHandler;
// Total size is ${totalSize} bytes
const generateWWWClass =
() => `typedef std::function<void(const char * uri, const String & contentType, const uint8_t * content, size_t len, const String & hash)> RouteRegistrationHandler;
// Bundle Statistics:
// - Total compressed size: ${(totalSize / 1000).toFixed(1)} KB
// - Total uncompressed size: ${(Object.values(bundleStats).reduce((sum, stat) => sum + stat.uncompressed, 0) / 1000).toFixed(1)} KB
// - Compression ratio: ${(((Object.values(bundleStats).reduce((sum, stat) => sum + stat.uncompressed, 0) - totalSize) / Object.values(bundleStats).reduce((sum, stat) => sum + stat.uncompressed, 0)) * 100).toFixed(1)}%
// - Generated on: ${new Date().toISOString()}
class WWWData {
${indent}public:
${indent.repeat(2)}static void registerRoutes(RouteRegistrationHandler handler) {
${fileInfo
.map(
(file) =>
`${indent.repeat(3)}handler("${file.uri}", "${file.mimeType}", ${file.variable}, ${file.size}, "${file.hash}");`
)
.join('\n')}
${indent.repeat(2)}}
${INDENT}public:
${INDENT.repeat(2)}static void registerRoutes(RouteRegistrationHandler handler) {
${fileInfo.map((f) => `${INDENT.repeat(3)}handler("${f.uri}", "${f.mimeType}", ${f.variable}, ${f.size}, "${f.hash}");`).join('\n')}
${INDENT.repeat(2)}}
};
`;
function getFilesSync(dir, files = []) {
const getFilesSync = (dir, files = []) => {
readdirSync(dir, { withFileTypes: true }).forEach((entry) => {
const entryPath = resolve(dir, entry.name);
if (entry.isDirectory()) {
getFilesSync(entryPath, files);
} else {
files.push(entryPath);
}
entry.isDirectory() ? getFilesSync(entryPath, files) : files.push(entryPath);
});
return files;
}
};
function cleanAndOpen(path) {
if (existsSync(path)) {
unlinkSync(path);
}
const cleanAndOpen = (path) => {
existsSync(path) && unlinkSync(path);
return createWriteStream(path, { flags: 'w+' });
}
};
const getFileType = (filePath) => {
const ext = filePath.split('.').pop().toLowerCase();
if (ext === 'js') return 'js';
if (ext === 'css') return 'css';
if (ext === 'html') return 'html';
if (ext === 'svg') return 'svg';
return 'other';
};
const writeFile = (relativeFilePath, buffer) => {
const variable = 'ESP_REACT_DATA_' + fileInfo.length;
const variable = `ESP_REACT_DATA_${fileInfo.length}`;
const mimeType = mime.lookup(relativeFilePath);
var size = 0;
writeStream.write('const uint8_t ' + variable + '[] = {');
// const zipBuffer = zlib.brotliCompressSync(buffer, { quality: 1 });
const zipBuffer = zlib.gzipSync(buffer, { level: 9 });
const fileType = getFileType(relativeFilePath);
let size = 0;
writeStream.write(`const uint8_t ${variable}[] = {`);
// create sha
const hashSum = crypto.createHash('sha256');
hashSum.update(zipBuffer);
const hash = hashSum.digest('hex');
const zipBuffer = zlib.gzipSync(buffer, { level: 9 });
const hash = crypto.createHash('sha256').update(zipBuffer).digest('hex');
zipBuffer.forEach((b) => {
if (!(size % bytesPerLine)) {
writeStream.write('\n');
writeStream.write(indent);
writeStream.write('\n' + INDENT);
}
writeStream.write('0x' + ('00' + b.toString(16).toUpperCase()).slice(-2) + ',');
writeStream.write('0x' + b.toString(16).toUpperCase().padStart(2, '0') + ',');
size++;
});
if (size % bytesPerLine) {
writeStream.write('\n');
}
size % bytesPerLine && writeStream.write('\n');
writeStream.write('};\n\n');
// Update bundle statistics
bundleStats[fileType].count++;
bundleStats[fileType].uncompressed += buffer.length;
bundleStats[fileType].compressed += zipBuffer.length;
fileInfo.push({
uri: '/' + relativeFilePath.replace(sep, '/'),
mimeType,
@@ -83,32 +97,52 @@ const writeFile = (relativeFilePath, buffer) => {
hash
});
// console.log(relativeFilePath + ' (size ' + size + ' bytes)');
totalSize += size;
};
// start
console.log('Generating ' + outputPath + ' from ' + sourcePath);
const includes = ARDUINO_INCLUDES;
const indent = INDENT;
console.log(`Generating ${outputPath} from ${sourcePath}`);
const fileInfo = [];
const writeStream = cleanAndOpen(resolve(outputPath));
// includes
writeStream.write(includes);
writeStream.write(ARDUINO_INCLUDES);
// process static files
const buildPath = resolve(sourcePath);
for (const filePath of getFilesSync(buildPath)) {
const readStream = readFileSync(filePath);
const relativeFilePath = relative(buildPath, filePath);
writeFile(relativeFilePath, readStream);
writeFile(relative(buildPath, filePath), readFileSync(filePath));
}
// add class
writeStream.write(generateWWWClass());
// end
writeStream.end();
console.log('Total size: ' + totalSize / 1000 + ' KB');
// Calculate and display bundle statistics
const totalUncompressed = Object.values(bundleStats).reduce(
(sum, stat) => sum + stat.uncompressed,
0
);
const totalCompressed = Object.values(bundleStats).reduce(
(sum, stat) => sum + stat.compressed,
0
);
const compressionRatio = (
((totalUncompressed - totalCompressed) / totalUncompressed) *
100
).toFixed(1);
console.log('\n📊 Bundle Size Analysis:');
console.log('='.repeat(50));
console.log(`Total compressed size: ${(totalSize / 1000).toFixed(1)} KB`);
console.log(`Total uncompressed size: ${(totalUncompressed / 1000).toFixed(1)} KB`);
console.log(`Compression ratio: ${compressionRatio}%`);
console.log('\n📁 File Type Breakdown:');
Object.entries(bundleStats).forEach(([type, stats]) => {
if (stats.count > 0) {
const ratio = (
((stats.uncompressed - stats.compressed) / stats.uncompressed) *
100
).toFixed(1);
console.log(
`${type.toUpperCase().padEnd(4)}: ${stats.count} files, ${(stats.uncompressed / 1000).toFixed(1)} KB → ${(stats.compressed / 1000).toFixed(1)} KB (${ratio}% compression)`
);
}
});
console.log('='.repeat(50));

View File

@@ -1,5 +1,6 @@
/*
* Uses font-size 400 (normal) only and Latin (plus extra unicode chars) to keep flash memory to a minimum
* Uses font-weight 400 (normal) only, no bold, and Latin with a few extra unicode chars.
* This is to keep flash memory to a minimum
* View fonts on https://fonts.google.com/
* Download woff2 using e.g. https://fonts.googleapis.com/css2?family=Lato or https://fonts.googleapis.com/css2?family=Roboto
*/
@@ -12,7 +13,9 @@
local('Roboto'),
local('Roboto-Regular'),
url(../fonts/re.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0104-0107, U+0118-0119, U+011E-011F, U+0130-0131, U+0141-0144, U+0152-0153, U+015A-015B,
U+015E-015F, U+0179-017C, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193,
U+2212, U+2215, U+FEFF, U+FFFD;
unicode-range:
U+0000-00FF, U+0104-0107, U+0118-0119, U+011E-011F, U+0130-0131, U+0141-0144,
U+0152-0153, U+015A-015B, U+015E-015F, U+0179-017C, U+02BB-02BC, U+02C6, U+02DA,
U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
U+FEFF, U+FFFD;
}

View File

@@ -1,49 +1,79 @@
import { useEffect, useState } from 'react';
import { ToastContainer, Slide } from 'react-toastify';
import { memo, useCallback, useEffect, useMemo, useState } from 'react';
import { ToastContainer, Zoom } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.min.css';
import { localStorageDetector } from 'typesafe-i18n/detectors';
import type { FC } from 'react';
import AppRouting from 'AppRouting';
import CustomTheme from 'CustomTheme';
import TypesafeI18n from 'i18n/i18n-react';
import { detectLocale } from 'i18n/i18n-util';
import type { Locales } from 'i18n/i18n-types';
import { loadLocaleAsync } from 'i18n/i18n-util.async';
import { detectLocale, navigatorDetector } from 'typesafe-i18n/detectors';
const detectedLocale = detectLocale(localStorageDetector);
// Memoize available locales to prevent recreation on every render
const AVAILABLE_LOCALES = [
'de',
'en',
'it',
'fr',
'nl',
'no',
'pl',
'sk',
'sv',
'tr',
'cz'
] as Locales[];
const App: FC = () => {
const App = memo(() => {
const [wasLoaded, setWasLoaded] = useState(false);
const [locale, setLocale] = useState<Locales>('en');
// Memoize locale initialization to prevent unnecessary re-runs
const initializeLocale = useCallback(async () => {
const browserLocale = detectLocale('en', AVAILABLE_LOCALES, navigatorDetector);
const newLocale = (localStorage.getItem('lang') || browserLocale) as Locales;
localStorage.setItem('lang', newLocale);
setLocale(newLocale);
await loadLocaleAsync(newLocale);
setWasLoaded(true);
}, []);
useEffect(() => {
void loadLocaleAsync(detectedLocale).then(() => setWasLoaded(true));
}, []);
void initializeLocale();
}, [initializeLocale]);
// Memoize toast container props to prevent recreation
const toastContainerProps = useMemo(
() => ({
position: 'bottom-left' as const,
autoClose: 3000,
hideProgressBar: false,
newestOnTop: false,
closeOnClick: true,
rtl: false,
pauseOnFocusLoss: true,
draggable: false,
pauseOnHover: false,
transition: Zoom,
closeButton: false,
theme: 'dark' as const,
toastStyle: {
border: '1px solid #177ac9',
width: 'fit-content'
}
}),
[]
);
if (!wasLoaded) return null;
return (
<TypesafeI18n locale={detectedLocale}>
<TypesafeI18n locale={locale}>
<CustomTheme>
<AppRouting />
<ToastContainer
position="bottom-left"
autoClose={3000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick={true}
rtl={false}
pauseOnFocusLoss={false}
draggable={false}
pauseOnHover={false}
transition={Slide}
closeButton={false}
theme="light"
/>
<ToastContainer {...toastContainerProps} />
</CustomTheme>
</TypesafeI18n>
);
};
});
export default App;

View File

@@ -1,14 +1,10 @@
import { useContext, useEffect } from 'react';
import { Route, Routes, Navigate, useLocation } from 'react-router-dom';
import { Navigate, Route, Routes } from 'react-router';
import { toast } from 'react-toastify';
import type { FC } from 'react';
import AuthenticatedRouting from 'AuthenticatedRouting';
import SignIn from 'SignIn';
import { RequireAuthenticated, RequireUnauthenticated } from 'components';
import { Authentication, AuthenticationContext } from 'contexts/authentication';
import { useI18nContext } from 'i18n/i18n-react';
@@ -17,7 +13,7 @@ interface SecurityRedirectProps {
signOut?: boolean;
}
const RootRedirect: FC<SecurityRedirectProps> = ({ message, signOut }) => {
const RootRedirect = ({ message, signOut }: SecurityRedirectProps) => {
const authenticationContext = useContext(AuthenticationContext);
useEffect(() => {
signOut && authenticationContext.signOut(false);
@@ -26,29 +22,20 @@ const RootRedirect: FC<SecurityRedirectProps> = ({ message, signOut }) => {
return <Navigate to="/" />;
};
export const RemoveTrailingSlashes = () => {
const location = useLocation();
return (
location.pathname.match('/.*/$') && (
<Navigate
to={{
pathname: location.pathname.replace(/\/+$/, ''),
search: location.search
}}
/>
)
);
};
const AppRouting: FC = () => {
const AppRouting = () => {
const { LL } = useI18nContext();
return (
<Authentication>
<RemoveTrailingSlashes />
<Routes>
<Route path="/unauthorized" element={<RootRedirect message={LL.PLEASE_SIGNIN()} signOut />} />
<Route path="/fileUpdated" element={<RootRedirect message={LL.UPLOAD_SUCCESSFUL()} />} />
<Route
path="/unauthorized"
element={<RootRedirect message={LL.PLEASE_SIGNIN()} signOut />}
/>
<Route
path="/fileUpdated"
element={<RootRedirect message={LL.UPLOAD_SUCCESSFUL()} />}
/>
<Route
path="/"
element={

View File

@@ -1,64 +1,77 @@
import { Navigate, Routes, Route } from 'react-router-dom';
import Dashboard from './project/Dashboard';
import Help from './project/Help';
import Settings from './project/Settings';
import type { FC } from 'react';
import { useContext } from 'react';
import { Navigate, Route, Routes } from 'react-router';
import { Layout, RequireAdmin } from 'components';
import AccessPoint from 'framework/ap/AccessPoint';
import Mqtt from 'framework/mqtt/Mqtt';
import NetworkConnection from 'framework/network/NetworkConnection';
import NetworkTime from 'framework/ntp/NetworkTime';
import Security from 'framework/security/Security';
import System from 'framework/system/System';
import CustomEntities from 'app/main/CustomEntities';
import Customizations from 'app/main/Customizations';
import Dashboard from 'app/main/Dashboard';
import Devices from 'app/main/Devices';
import Help from 'app/main/Help';
import Modules from 'app/main/Modules';
import Scheduler from 'app/main/Scheduler';
import Sensors from 'app/main/Sensors';
import APSettings from 'app/settings/APSettings';
import ApplicationSettings from 'app/settings/ApplicationSettings';
import DownloadUpload from 'app/settings/DownloadUpload';
import MqttSettings from 'app/settings/MqttSettings';
import NTPSettings from 'app/settings/NTPSettings';
import Settings from 'app/settings/Settings';
import Network from 'app/settings/network/Network';
import Security from 'app/settings/security/Security';
import APStatus from 'app/status/APStatus';
import Activity from 'app/status/Activity';
import HardwareStatus from 'app/status/HardwareStatus';
import MqttStatus from 'app/status/MqttStatus';
import NTPStatus from 'app/status/NTPStatus';
import NetworkStatus from 'app/status/NetworkStatus';
import Status from 'app/status/Status';
import SystemLog from 'app/status/SystemLog';
import Version from 'app/status/Version';
import { Layout } from 'components';
import { AuthenticatedContext } from 'contexts/authentication';
const AuthenticatedRouting: FC = () => (
// const location = useLocation();
// const navigate = useNavigate();
// const handleApiResponseError = useCallback(
// (error: AxiosError) => {
// if (error.response && error.response.status === 401) {
// AuthenticationApi.storeLoginRedirect(location);
// navigate('/unauthorized');
// }
// return Promise.reject(error);
// },
// [location, navigate]
// );
// useEffect(() => {
// const axiosHandlerId = AXIOS.interceptors.response.use((response) => response, handleApiResponseError);
// return () => AXIOS.interceptors.response.eject(axiosHandlerId);
// }, [handleApiResponseError]);
const AuthenticatedRouting = () => {
const { me } = useContext(AuthenticatedContext);
return (
<Layout>
<Routes>
<Route path="/dashboard/*" element={<Dashboard />} />
<Route path="/devices/*" element={<Devices />} />
<Route path="/sensors/*" element={<Sensors />} />
<Route path="/help/*" element={<Help />} />
<Layout>
<Routes>
<Route path="/dashboard/*" element={<Dashboard />} />
<Route
path="/settings/*"
element={
<RequireAdmin>
<Settings />
</RequireAdmin>
}
/>
<Route path="/help/*" element={<Help />} />
<Route path="/status/*" element={<Status />} />
<Route path="/status/hardwarestatus/*" element={<HardwareStatus />} />
<Route path="/status/activity" element={<Activity />} />
<Route path="/status/log" element={<SystemLog />} />
<Route path="/status/mqtt" element={<MqttStatus />} />
<Route path="/status/ntp" element={<NTPStatus />} />
<Route path="/status/ap" element={<APStatus />} />
<Route path="/status/network" element={<NetworkStatus />} />
<Route path="/status/version" element={<Version />} />
<Route path="/network/*" element={<NetworkConnection />} />
<Route path="/ap/*" element={<AccessPoint />} />
<Route path="/ntp/*" element={<NetworkTime />} />
<Route path="/mqtt/*" element={<Mqtt />} />
<Route
path="/security/*"
element={
<RequireAdmin>
<Security />
</RequireAdmin>
}
/>
<Route path="/system/*" element={<System />} />
<Route path="/*" element={<Navigate to="/" />} />
</Routes>
</Layout>
);
{me.admin && (
<>
<Route path="/settings" element={<Settings />} />
<Route path="/settings/application" element={<ApplicationSettings />} />
<Route path="/settings/mqtt" element={<MqttSettings />} />
<Route path="/settings/ntp" element={<NTPSettings />} />
<Route path="/settings/ap" element={<APSettings />} />
<Route path="/settings/modules" element={<Modules />} />
<Route path="/settings/downloadUpload" element={<DownloadUpload />} />
<Route path="/settings/network/*" element={<Network />} />
<Route path="/settings/security/*" element={<Security />} />
<Route path="/customizations" element={<Customizations />} />
<Route path="/scheduler" element={<Scheduler />} />
<Route path="/customentities" element={<CustomEntities />} />
</>
)}
<Route path="/*" element={<Navigate to="/" />} />
</Routes>
</Layout>
);
};
export default AuthenticatedRouting;

View File

@@ -1,19 +1,27 @@
import { CssBaseline } from '@mui/material';
import { createTheme, responsiveFontSizes, ThemeProvider } from '@mui/material/styles';
import { memo } from 'react';
import type { FC } from 'react';
import {
CssBaseline,
ThemeProvider,
responsiveFontSizes,
tooltipClasses
} from '@mui/material';
import { createTheme } from '@mui/material/styles';
import type { RequiredChildrenProps } from 'utils';
// Memoize dialog style to prevent recreation
export const dialogStyle = {
'& .MuiDialog-paper': {
borderRadius: '8px',
borderColor: '#565656',
borderStyle: 'solid',
borderWidth: '1px'
},
backdropFilter: 'blur(1px)'
};
}
} as const;
// Memoize theme creation to prevent recreation
const theme = responsiveFontSizes(
createTheme({
typography: {
@@ -30,15 +38,45 @@ const theme = responsiveFontSizes(
text: {
disabled: '#eee' // white
}
},
components: {
MuiListItemText: {
styleOverrides: {
primary: {
fontSize: 14
},
secondary: {
color: '#9e9e9e' // grey[500]
}
}
},
MuiTooltip: {
defaultProps: {
placement: 'top',
arrow: true
},
styleOverrides: {
tooltip: {
padding: '4px 8px',
fontSize: 10,
color: 'rgba(0, 0, 0, 0.87)',
backgroundColor: '#4caf50', // MUI success.main default color
boxShadow: '0px 2px 8px rgba(0, 0, 0, 0.15)',
[`& .${tooltipClasses.arrow}`]: {
color: '#4caf50'
}
}
}
}
}
})
);
const CustomTheme: FC<RequiredChildrenProps> = ({ children }) => (
const CustomTheme: FC<RequiredChildrenProps> = memo(({ children }) => (
<ThemeProvider theme={theme}>
<CssBaseline />
{children}
</ThemeProvider>
);
));
export default CustomTheme;

View File

@@ -1,38 +1,28 @@
import ForwardIcon from '@mui/icons-material/Forward';
import { Box, Paper, Typography, MenuItem, TextField, Button } from '@mui/material';
import { useRequest } from 'alova';
import { useContext, useState } from 'react';
import { toast } from 'react-toastify';
import ForwardIcon from '@mui/icons-material/Forward';
import { Box, Button, Paper, Typography } from '@mui/material';
import * as AuthenticationApi from 'components/routing/authentication';
import { useRequest } from 'alova/client';
import type { ValidateFieldsError } from 'async-validator';
import type { Locales } from 'i18n/i18n-types';
import type { ChangeEventHandler, FC } from 'react';
import type { SignInRequest } from 'types';
import * as AuthenticationApi from 'api/authentication';
import { PROJECT_NAME } from 'api/env';
import { ValidatedPasswordField, ValidatedTextField } from 'components';
import {
LanguageSelector,
ValidatedPasswordField,
ValidatedTextField
} from 'components';
import { AuthenticationContext } from 'contexts/authentication';
import DEflag from 'i18n/DE.svg';
import FRflag from 'i18n/FR.svg';
import GBflag from 'i18n/GB.svg';
import ITflag from 'i18n/IT.svg';
import NLflag from 'i18n/NL.svg';
import NOflag from 'i18n/NO.svg';
import PLflag from 'i18n/PL.svg';
import SKflag from 'i18n/SK.svg';
import SVflag from 'i18n/SV.svg';
import TRflag from 'i18n/TR.svg';
import { I18nContext } from 'i18n/i18n-react';
import { loadLocaleAsync } from 'i18n/i18n-util.async';
import { PROJECT_NAME } from 'env';
import { useI18nContext } from 'i18n/i18n-react';
import type { SignInRequest } from 'types';
import { onEnterCallback, updateValue } from 'utils';
import { SIGN_IN_REQUEST_VALIDATOR, validate } from 'validators';
const SignIn: FC = () => {
const SignIn = () => {
const authenticationContext = useContext(AuthenticationContext);
const { LL, setLocale, locale } = useContext(I18nContext);
const { LL } = useI18nContext();
const [signInRequest, setSignInRequest] = useState<SignInRequest>({
username: '',
@@ -41,11 +31,12 @@ const SignIn: FC = () => {
const [processing, setProcessing] = useState<boolean>(false);
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
const { send: callSignIn, onSuccess } = useRequest((request: SignInRequest) => AuthenticationApi.signIn(request), {
immediate: false
});
onSuccess((response) => {
const { send: callSignIn } = useRequest(
(request: SignInRequest) => AuthenticationApi.signIn(request),
{
immediate: false
}
).onSuccess((response) => {
if (response.data) {
authenticationContext.signIn(response.data.access_token);
}
@@ -54,7 +45,7 @@ const SignIn: FC = () => {
const updateLoginRequestValue = updateValue(setSignInRequest);
const signIn = async () => {
await callSignIn(signInRequest).catch((event) => {
await callSignIn(signInRequest).catch((event: Error) => {
if (event.message === 'Unauthorized') {
toast.warning(LL.INVALID_LOGIN());
} else {
@@ -72,21 +63,14 @@ const SignIn: FC = () => {
try {
await validate(SIGN_IN_REQUEST_VALIDATOR, signInRequest);
await signIn();
} catch (errors: any) {
setFieldErrors(errors);
} catch (error) {
setFieldErrors(error as ValidateFieldsError);
setProcessing(false);
}
};
const submitOnEnter = onEnterCallback(signIn);
const onLocaleSelected: ChangeEventHandler<HTMLInputElement> = async ({ target }) => {
const loc = target.value as Locales;
localStorage.setItem('lang', loc);
await loadLocaleAsync(loc);
setLocale(loc);
};
return (
<Box
display="flex"
@@ -110,52 +94,11 @@ const SignIn: FC = () => {
>
<Typography variant="h4">{PROJECT_NAME}</Typography>
<TextField name="locale" variant="outlined" value={locale} onChange={onLocaleSelected} size="small" select>
<MenuItem key="de" value="de">
<img src={DEflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;DE
</MenuItem>
<MenuItem key="en" value="en">
<img src={GBflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;EN
</MenuItem>
<MenuItem key="fr" value="fr">
<img src={FRflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;FR
</MenuItem>
<MenuItem key="it" value="it">
<img src={ITflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;IT
</MenuItem>
<MenuItem key="nl" value="nl">
<img src={NLflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;NL
</MenuItem>
<MenuItem key="no" value="no">
<img src={NOflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;NO
</MenuItem>
<MenuItem key="pl" value="pl">
<img src={PLflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;PL
</MenuItem>
<MenuItem key="sk" value="sk">
<img src={SKflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;SK
</MenuItem>
<MenuItem key="sv" value="sv">
<img src={SVflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;SV
</MenuItem>
<MenuItem key="tr" value="tr">
<img src={TRflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;TR
</MenuItem>
</TextField>
<LanguageSelector />
<Box display="flex" flexDirection="column" alignItems="center">
<ValidatedTextField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
disabled={processing}
sx={{
width: 240
@@ -166,9 +109,15 @@ const SignIn: FC = () => {
onChange={updateLoginRequestValue}
margin="normal"
variant="outlined"
slotProps={{
input: {
autoCapitalize: 'none',
autoCorrect: 'off'
}
}}
/>
<ValidatedPasswordField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
disabled={processing}
sx={{
width: 240
@@ -182,7 +131,13 @@ const SignIn: FC = () => {
/>
</Box>
<Button variant="contained" color="primary" sx={{ mt: 2 }} onClick={validateAndSignIn} disabled={processing}>
<Button
variant="contained"
color="primary"
sx={{ mt: 2 }}
onClick={validateAndSignIn}
disabled={processing}
>
<ForwardIcon sx={{ mr: 1 }} />
{LL.SIGN_IN()}
</Button>

View File

@@ -1,7 +1,9 @@
import type { APSettingsType, APStatusType } from 'types';
import { alovaInstance } from './endpoints';
import type { APSettings, APStatus } from 'types';
export const readAPStatus = () => alovaInstance.Get<APStatus>('/rest/apStatus');
export const readAPSettings = () => alovaInstance.Get<APSettings>('/rest/apSettings');
export const updateAPSettings = (data: APSettings) => alovaInstance.Post<APSettings>('/rest/apSettings', data);
export const readAPStatus = () => alovaInstance.Get<APStatusType>('/rest/apStatus');
export const readAPSettings = () =>
alovaInstance.Get<APSettingsType>('/rest/apSettings');
export const updateAPSettings = (data: APSettingsType) =>
alovaInstance.Post<APSettingsType>('/rest/apSettings', data);

155
interface/src/api/app.ts Normal file
View File

@@ -0,0 +1,155 @@
import { alovaInstance } from 'api/endpoints';
import type {
APIcall,
Action,
Activity,
CoreData,
DashboardData,
DeviceData,
DeviceEntity,
Entities,
EntityItem,
ModuleItem,
Modules,
Schedule,
ScheduleItem,
SensorData,
Settings,
WriteAnalogSensor,
WriteTemperatureSensor
} from '../app/main/types';
// Dashboard
export const readDashboard = () =>
alovaInstance.Get<DashboardData>('/rest/dashboardData', {
responseType: 'arraybuffer' // uses msgpack
});
// Devices
export const readCoreData = () => alovaInstance.Get<CoreData>(`/rest/coreData`);
export const readDeviceData = (id: number) =>
alovaInstance.Get<DeviceData>('/rest/deviceData', {
// alovaInstance.Get<DeviceData>(`/rest/deviceData/${id}`, {
params: { id },
responseType: 'arraybuffer' // uses msgpack
});
export const writeDeviceValue = (data: { id: number; c: string; v: unknown }) =>
alovaInstance.Post('/rest/writeDeviceValue', data);
// Application Settings
export const readSettings = () => alovaInstance.Get<Settings>('/rest/settings');
export const writeSettings = (data: Settings) =>
alovaInstance.Post('/rest/settings', data);
export const getBoardProfile = (boardProfile: string) =>
alovaInstance.Get('/rest/boardProfile', {
params: { boardProfile }
});
// Sensors
export const readSensorData = () =>
alovaInstance.Get<SensorData>('/rest/sensorData');
export const writeTemperatureSensor = (ts: WriteTemperatureSensor) =>
alovaInstance.Post('/rest/writeTemperatureSensor', ts);
export const writeAnalogSensor = (as: WriteAnalogSensor) =>
alovaInstance.Post('/rest/writeAnalogSensor', as);
// Activity
export const readActivity = () => alovaInstance.Get<Activity>('/rest/activity');
// API
export const API = (apiCall: APIcall) => alovaInstance.Post('/api', apiCall);
// Generic action
export const callAction = (action: Action) =>
alovaInstance.Post('/rest/action', action);
// SettingsCustomization
export const readDeviceEntities = (id: number) =>
// alovaInstance.Get<DeviceEntity[]>(`/rest/deviceEntities/${id}`, {
alovaInstance.Get<DeviceEntity[]>(`/rest/deviceEntities`, {
params: { id },
responseType: 'arraybuffer',
// @ts-expect-error - exactOptionalPropertyTypes compatibility issue
transform(data) {
return (data as DeviceEntity[]).map((de: DeviceEntity) => ({
...de,
o_m: de.m,
o_cn: de.cn,
o_mi: de.mi,
o_ma: de.ma
}));
}
});
export const resetCustomizations = () =>
alovaInstance.Post('/rest/resetCustomizations');
export const writeCustomizationEntities = (data: {
id: number;
entity_ids: string[];
}) => alovaInstance.Post('/rest/customizationEntities', data);
export const writeDeviceName = (data: { id: number; name: string }) =>
alovaInstance.Post('/rest/writeDeviceName', data);
// SettingsScheduler
export const readSchedule = () =>
alovaInstance.Get<ScheduleItem[]>('/rest/schedule', {
// @ts-expect-error - exactOptionalPropertyTypes compatibility issue
transform(data) {
return (data as Schedule).schedule.map((si: ScheduleItem) => ({
...si,
o_id: si.id,
o_active: si.active,
o_deleted: si.deleted,
o_flags: si.flags,
o_time: si.time,
o_cmd: si.cmd,
o_value: si.value,
o_name: si.name
}));
}
});
export const writeSchedule = (data: Schedule) =>
alovaInstance.Post('/rest/schedule', data);
// Modules
export const readModules = () =>
alovaInstance.Get<ModuleItem[]>('/rest/modules', {
transform(data) {
return (data as Modules).modules.map((mi: ModuleItem) => ({
...mi,
o_enabled: mi.enabled,
o_license: mi.license
}));
}
});
export const writeModules = (data: {
key: string;
enabled: boolean;
license: string;
}) => alovaInstance.Post('/rest/modules', data);
// CustomEntities
export const readCustomEntities = () =>
alovaInstance.Get<EntityItem[]>('/rest/customEntities', {
// @ts-expect-error - exactOptionalPropertyTypes compatibility issue
transform(data) {
return (data as Entities).entities.map((ei: EntityItem) => ({
...ei,
o_id: ei.id,
o_ram: ei.ram,
o_device_id: ei.device_id,
o_type_id: ei.type_id,
o_offset: ei.offset,
o_factor: ei.factor,
o_uom: ei.uom,
o_value_type: ei.value_type,
o_name: ei.name,
o_writeable: ei.writeable,
o_value: ei.value,
o_deleted: ei.deleted,
o_hide: ei.hide
}));
}
});
export const writeCustomEntities = (data: Entities) =>
alovaInstance.Post('/rest/customEntities', data);

View File

@@ -1,33 +1,36 @@
import { xhrRequestAdapter } from '@alova/adapter-xhr';
import { type AlovaXHRResponse, xhrRequestAdapter } from '@alova/adapter-xhr';
import { createAlova } from 'alova';
import ReactHook from 'alova/react';
import { unpack } from '../api/unpack';
import { unpack } from './unpack';
export const ACCESS_TOKEN = 'access_token';
const host = window.location.host;
export const WEB_SOCKET_ROOT = 'ws://' + host + '/ws/';
export const EVENT_SOURCE_ROOT = 'http://' + host + '/es/';
export const alovaInstance = createAlova({
statesHook: ReactHook,
timeout: 3000, // 3 seconds but throwing a timeout error
localCache: null,
// localCache: {
// timeout: 3000, // 3 seconds before throwing a timeout error, default is 0 = none
cacheFor: null, // disable cache
// cacheFor: {
// GET: {
// mode: 'placeholder', // see https://alova.js.org/learning/response-cache/#cache-replaceholder-mode
// expire: 2000
// mode: 'memory',
// expire: 60 * 10 * 1000 // 60 seconds in cache
// }
// },
requestAdapter: xhrRequestAdapter(),
beforeRequest(method) {
if (localStorage.getItem(ACCESS_TOKEN)) {
method.config.headers.Authorization = 'Bearer ' + localStorage.getItem(ACCESS_TOKEN);
method.config.headers.Authorization =
'Bearer ' + localStorage.getItem(ACCESS_TOKEN);
}
// for simulating very slow networks
// return new Promise((resolve) => {
// const random = 3000 + Math.random() * 2000;
// setTimeout(resolve, Math.floor(random));
// });
},
responded: {
onSuccess: async (response) => {
onSuccess: async (response: AlovaXHRResponse) => {
// if (response.status === 202) {
// throw new Error('Wait'); // wifi scan in progress
// } else
@@ -38,9 +41,9 @@ export const alovaInstance = createAlova({
} else if (response.status >= 400) {
throw new Error(response.statusText);
}
const data = await response.data;
const data: ArrayBuffer = (await response.data) as ArrayBuffer;
if (response.data instanceof ArrayBuffer) {
return unpack(data);
return unpack(data) as ArrayBuffer;
}
return data;
}
@@ -54,7 +57,10 @@ export const alovaInstance = createAlova({
});
export const alovaInstanceGH = createAlova({
baseURL: 'https://api.github.com/repos/emsesp/EMS-ESP32/releases',
baseURL:
process.env.NODE_ENV === 'development'
? '/gh'
: 'https://api.github.com/repos/emsesp/EMS-ESP32/releases',
statesHook: ReactHook,
requestAdapter: xhrRequestAdapter()
});

View File

@@ -1,6 +1,10 @@
import { alovaInstance } from './endpoints';
import type { MqttSettings, MqttStatus } from 'types';
import type { MqttSettingsType, MqttStatusType } from 'types';
export const readMqttStatus = () => alovaInstance.Get<MqttStatus>('/rest/mqttStatus');
export const readMqttSettings = () => alovaInstance.Get<MqttSettings>('/rest/mqttSettings');
export const updateMqttSettings = (data: MqttSettings) => alovaInstance.Post<MqttSettings>('/rest/mqttSettings', data);
import { alovaInstance } from './endpoints';
export const readMqttStatus = () =>
alovaInstance.Get<MqttStatusType>('/rest/mqttStatus');
export const readMqttSettings = () =>
alovaInstance.Get<MqttSettingsType>('/rest/mqttSettings');
export const updateMqttSettings = (data: MqttSettingsType) =>
alovaInstance.Post<MqttSettingsType>('/rest/mqttSettings', data);

View File

@@ -1,15 +1,15 @@
import type { NetworkSettingsType, NetworkStatusType, WiFiNetworkList } from 'types';
import { alovaInstance } from './endpoints';
import type { WiFiNetworkList, NetworkSettings, NetworkStatus } from 'types';
export const readNetworkStatus = () => alovaInstance.Get<NetworkStatus>('/rest/networkStatus');
export const readNetworkStatus = () =>
alovaInstance.Get<NetworkStatusType>('/rest/networkStatus');
export const scanNetworks = () => alovaInstance.Get('/rest/scanNetworks');
export const listNetworks = () =>
alovaInstance.Get<WiFiNetworkList>('/rest/listNetworks', {
name: 'listNetworks',
timeout: 20000 // timeout 20 seconds
timeout: 20000 // 20 seconds
});
export const readNetworkSettings = () =>
alovaInstance.Get<NetworkSettings>('/rest/networkSettings', { name: 'networkSettings' });
export const updateNetworkSettings = (wifiSettings: NetworkSettings) =>
alovaInstance.Post<NetworkSettings>('/rest/networkSettings', wifiSettings);
alovaInstance.Get<NetworkSettingsType>('/rest/networkSettings');
export const updateNetworkSettings = (wifiSettings: NetworkSettingsType) =>
alovaInstance.Post<NetworkSettingsType>('/rest/networkSettings', wifiSettings);

View File

@@ -1,11 +1,14 @@
import type { NTPSettingsType, NTPStatusType, Time } from 'types';
import { alovaInstance } from './endpoints';
import type { NTPSettings, NTPStatus, Time } from 'types';
export const readNTPStatus = () => alovaInstance.Get<NTPStatus>('/rest/ntpStatus');
export const readNTPStatus = () =>
alovaInstance.Get<NTPStatusType>('/rest/ntpStatus');
export const readNTPSettings = () =>
alovaInstance.Get<NTPSettings>('/rest/ntpSettings', {
name: 'ntpSettings'
});
export const updateNTPSettings = (data: NTPSettings) => alovaInstance.Post<NTPSettings>('/rest/ntpSettings', data);
alovaInstance.Get<NTPSettingsType>('/rest/ntpSettings', {});
export const updateNTPSettings = (data: NTPSettingsType) =>
alovaInstance.Post<NTPSettingsType>('/rest/ntpSettings', data);
export const updateTime = (data: Time) => alovaInstance.Post<Time>('/rest/time', data);
export const updateTime = (data: Time) =>
alovaInstance.Post<Time>('/rest/time', data);

View File

@@ -1,10 +1,11 @@
import type { SecuritySettingsType, Token } from 'types';
import { alovaInstance } from './endpoints';
import type { SecuritySettings, Token } from 'types';
export const readSecuritySettings = () =>
alovaInstance.Get<SecuritySettingsType>('/rest/securitySettings');
export const readSecuritySettings = () => alovaInstance.Get<SecuritySettings>('/rest/securitySettings');
export const updateSecuritySettings = (securitySettings: SecuritySettings) =>
export const updateSecuritySettings = (securitySettings: SecuritySettingsType) =>
alovaInstance.Post('/rest/securitySettings', securitySettings);
export const generateToken = (username?: string) =>

View File

@@ -1,34 +1,38 @@
import type { LogSettings, SystemStatus } from 'types';
import { alovaInstance, alovaInstanceGH } from './endpoints';
import type { OTASettings, SystemStatus, LogSettings } from 'types';
// SystemStatus - also used to ping in Restart monitor for pinging
export const readSystemStatus = () => alovaInstance.Get<SystemStatus>('/rest/systemStatus');
// commands
export const restart = () => alovaInstance.Post('/rest/restart');
export const partition = () => alovaInstance.Post('/rest/partition');
export const factoryReset = () => alovaInstance.Post('/rest/factoryReset');
// OTA
export const readOTASettings = () => alovaInstance.Get<OTASettings>(`/rest/otaSettings`);
export const updateOTASettings = (data: any) => alovaInstance.Post('/rest/otaSettings', data);
// systemStatus - also used to ping in System Monitor for pinging
export const readSystemStatus = () =>
alovaInstance.Get<SystemStatus>('/rest/systemStatus');
// SystemLog
export const readLogSettings = () => alovaInstance.Get<LogSettings>(`/rest/logSettings`);
export const updateLogSettings = (data: any) => alovaInstance.Post('/rest/logSettings', data);
export const fetchLog = () => alovaInstance.Post('/rest/fetchLog');
export const readLogSettings = () =>
alovaInstance.Get<LogSettings>(`/rest/logSettings`);
export const updateLogSettings = (data: LogSettings) =>
alovaInstance.Post('/rest/logSettings', data);
export const fetchLogES = () => alovaInstance.Get('/es/log');
// Get versions from github
// Get versions from GitHub
// cache for 10 minutes to stop getting the IP blocked by GitHub
export const getStableVersion = () =>
alovaInstanceGH.Get('latest', {
transformData(response: any) {
return response.data.name.substring(1);
cacheFor: 60 * 10 * 1000,
transform(response: { data: { name: string; published_at: string } }) {
return {
name: response.data.name.substring(1),
published_at: response.data.published_at
};
}
});
export const getDevVersion = () =>
alovaInstanceGH.Get('tags/latest', {
transformData(response: any) {
return response.data.name.split(/\s+/).splice(-1)[0].substring(1);
cacheFor: 60 * 10 * 1000,
transform(response: { data: { name: string; published_at: string } }) {
return {
name: response.data.name.split(/\s+/).splice(-1)[0]?.substring(1) || '',
published_at: response.data.published_at
};
}
});
@@ -36,7 +40,6 @@ export const uploadFile = (file: File) => {
const formData = new FormData();
formData.append('file', file);
return alovaInstance.Post('/rest/uploadFile', formData, {
timeout: 60000, // override timeout for uploading firmware - 1 minute
enableUpload: true
timeout: 60000 // override timeout for uploading firmware - 1 minute
});
};

View File

@@ -1,44 +1,42 @@
let decoder;
// @ts-nocheck - Optimized MessagePack unpacking library for EMS-ESP32
let decoder,
src,
srcEnd,
position = 0,
strings = [],
stringPosition = 0,
currentUnpackr = {},
currentStructures,
srcString,
srcStringStart = 0,
srcStringEnd = 0,
bundledStrings,
referenceMap,
dataView;
const EMPTY_ARRAY = [],
currentExtensions = [];
const defaultOptions = { useRecords: false, mapsAsObjects: true };
try {
decoder = new TextDecoder();
} catch (error) {}
let src;
let srcEnd;
let position = 0;
const EMPTY_ARRAY = [];
let strings = EMPTY_ARRAY;
let stringPosition = 0;
let currentUnpackr = {};
let currentStructures;
let srcString;
let srcStringStart = 0;
let srcStringEnd = 0;
let bundledStrings;
let referenceMap;
const currentExtensions = [];
let dataView;
const defaultOptions = {
useRecords: false,
mapsAsObjects: true
};
export class C1Type {}
export const C1 = new C1Type();
class C1Type {}
const C1 = new C1Type();
C1.name = 'MessagePack 0xC1';
let sequentialMode = false;
let inlineObjectReadThreshold = 2;
let readStruct, onLoadedStructures, onSaveState;
// no-eval build
let sequentialMode = false,
inlineObjectReadThreshold = 2,
readStruct,
onLoadedStructures,
onSaveState;
try {
new Function('');
} catch (error) {
// if eval variants are not supported, do not create inline object readers ever
inlineObjectReadThreshold = Infinity;
}
export class Unpackr {
constructor(options) {
if (options) {
if (options.useRecords === false && options.mapsAsObjects === undefined) options.mapsAsObjects = true;
if (options.useRecords === false && options.mapsAsObjects === undefined)
options.mapsAsObjects = true;
if (options.sequential && options.trusted !== false) {
options.trusted = true;
if (!options.structures && options.useRecords != false) {
@@ -46,28 +44,28 @@ export class Unpackr {
if (!options.maxSharedStructures) options.maxSharedStructures = 0;
}
}
if (options.structures) options.structures.sharedLength = options.structures.length;
if (options.structures)
options.structures.sharedLength = options.structures.length;
else if (options.getStructures) {
(options.structures = []).uninitialized = true; // this is what we use to denote an uninitialized structures
(options.structures = []).uninitialized = true;
options.structures.sharedLength = 0;
}
if (options.int64AsNumber) {
options.int64AsType = 'number';
}
if (options.int64AsNumber) options.int64AsType = 'number';
}
Object.assign(this, options);
}
unpack(source, options?: any) {
if (src) {
// re-entrant execution, save the state and restore it after we do this unpack
return saveState(() => {
clearSource();
return this ? this.unpack(source, options) : Unpackr.prototype.unpack.call(defaultOptions, source, options);
return this
? this.unpack(source, options)
: Unpackr.prototype.unpack.call(defaultOptions, source, options);
});
}
if (!source.buffer && source.constructor === ArrayBuffer)
source = typeof Buffer !== 'undefined' ? Buffer.from(source) : new Uint8Array(source);
source =
typeof Buffer !== 'undefined' ? Buffer.from(source) : new Uint8Array(source);
if (typeof options === 'object') {
srcEnd = options.end || source.length;
position = options.start || 0;
@@ -81,19 +79,23 @@ export class Unpackr {
strings = EMPTY_ARRAY;
bundledStrings = null;
src = source;
// this provides cached access to the data view for a buffer if it is getting reused, which is a recommend
// technique for getting data from a database where it can be copied into an existing buffer instead of creating
// new ones
try {
dataView =
source.dataView || (source.dataView = new DataView(source.buffer, source.byteOffset, source.byteLength));
source.dataView ||
(source.dataView = new DataView(
source.buffer,
source.byteOffset,
source.byteLength
));
} catch (error) {
// if it doesn't have a buffer, maybe it is the wrong type of object
src = null;
if (source instanceof Uint8Array) throw error;
throw new Error(
'Source must be a Uint8Array or Buffer but was a ' +
(source && typeof source == 'object' ? source.constructor.name : typeof source)
(source && typeof source == 'object'
? source.constructor.name
: typeof source)
);
}
if (this instanceof Unpackr) {
@@ -117,7 +119,9 @@ export class Unpackr {
try {
sequentialMode = true;
const size = source.length;
const value = this ? this.unpack(source, size) : defaultUnpackr.unpack(source, size);
const value = this
? this.unpack(source, size)
: defaultUnpackr.unpack(source, size);
if (forEach) {
if (forEach(value) === false) return;
while (position < size) {
@@ -145,9 +149,11 @@ export class Unpackr {
}
_mergeStructures(loadedStructures, existingStructures) {
if (onLoadedStructures) loadedStructures = onLoadedStructures.call(this, loadedStructures);
if (onLoadedStructures)
loadedStructures = onLoadedStructures.call(this, loadedStructures);
loadedStructures = loadedStructures || [];
if (Object.isFrozen(loadedStructures)) loadedStructures = loadedStructures.map((structure) => structure.slice(0));
if (Object.isFrozen(loadedStructures))
loadedStructures = loadedStructures.map((structure) => structure.slice(0));
for (let i = 0, l = loadedStructures.length; i < l; i++) {
const structure = loadedStructures[i];
if (structure) {
@@ -162,7 +168,8 @@ export class Unpackr {
const existing = existingStructures[id];
if (existing) {
if (structure)
(loadedStructures.restoreStructures || (loadedStructures.restoreStructures = []))[id] = structure;
(loadedStructures.restoreStructures ||
(loadedStructures.restoreStructures = []))[id] = structure;
loadedStructures[id] = existing;
}
}
@@ -174,17 +181,23 @@ export class Unpackr {
return this.unpack(source, end);
}
}
export function getPosition() {
function getPosition() {
return position;
}
export function checkedRead(options: any) {
function checkedRead(options: any) {
try {
if (!currentUnpackr.trusted && !sequentialMode) {
const sharedLength = currentStructures.sharedLength || 0;
if (sharedLength < currentStructures.length) currentStructures.length = sharedLength;
if (sharedLength < currentStructures.length)
currentStructures.length = sharedLength;
}
let result;
if (currentUnpackr.randomAccessStructure && src[position] < 0x40 && src[position] >= 0x20 && readStruct) {
if (
currentUnpackr.randomAccessStructure &&
src[position] < 0x40 &&
src[position] >= 0x20 &&
readStruct
) {
result = readStruct(src, position, srcEnd, currentUnpackr);
src = null; // dispose of this so that recursive unpack calls don't save state
if (!(options && options.lazy) && result) result = result.toJSON();
@@ -198,7 +211,8 @@ export function checkedRead(options: any) {
if (position == srcEnd) {
// finished reading this source, cleanup references
if (currentStructures && currentStructures.restoreStructures) restoreStructures();
if (currentStructures && currentStructures.restoreStructures)
restoreStructures();
currentStructures = null;
src = null;
if (referenceMap) referenceMap = null;
@@ -208,10 +222,9 @@ export function checkedRead(options: any) {
} else if (!sequentialMode) {
let jsonView;
try {
jsonView = JSON.stringify(result, (_, value) => (typeof value === 'bigint' ? `${value}n` : value)).slice(
0,
100
);
jsonView = JSON.stringify(result, (_, value) =>
typeof value === 'bigint' ? `${value}n` : value
).slice(0, 100);
} catch (error) {
jsonView = '(JSON view not available ' + error + ')';
}
@@ -220,9 +233,14 @@ export function checkedRead(options: any) {
// else more to read, but we are reading sequentially, so don't clear source yet
return result;
} catch (error) {
if (currentStructures && currentStructures.restoreStructures) restoreStructures();
if (currentStructures && currentStructures.restoreStructures)
restoreStructures();
clearSource();
if (error instanceof RangeError || error.message.startsWith('Unexpected end of buffer') || position > srcEnd) {
if (
error instanceof RangeError ||
error.message.startsWith('Unexpected end of buffer') ||
position > srcEnd
) {
error.incomplete = true;
}
throw error;
@@ -236,14 +254,15 @@ function restoreStructures() {
currentStructures.restoreStructures = null;
}
export function read() {
function read() {
let token = src[position++];
if (token < 0xa0) {
if (token < 0x80) {
if (token < 0x40) return token;
else {
const structure =
currentStructures[token & 0x3f] || (currentUnpackr.getStructures && loadStructures()[token & 0x3f]);
currentStructures[token & 0x3f] ||
(currentUnpackr.getStructures && loadStructures()[token & 0x3f]);
if (structure) {
if (!structure.read) {
structure.read = createStructureReader(structure, token & 0x3f);
@@ -282,7 +301,10 @@ export function read() {
// fixstr
const length = token - 0xa0;
if (srcStringEnd >= position) {
return srcString.slice(position - srcStringStart, (position += length) - srcStringStart);
return srcString.slice(
position - srcStringStart,
(position += length) - srcStringStart
);
}
if (srcStringEnd == 0 && srcEnd < 140) {
// for small blocks, avoiding the overhead of the extract call is helpful
@@ -298,8 +320,16 @@ export function read() {
case 0xc1:
if (bundledStrings) {
value = read(); // followed by the length of the string in characters (not bytes!)
if (value > 0) return bundledStrings[1].slice(bundledStrings.position1, (bundledStrings.position1 += value));
else return bundledStrings[0].slice(bundledStrings.position0, (bundledStrings.position0 -= value));
if (value > 0)
return bundledStrings[1].slice(
bundledStrings.position1,
(bundledStrings.position1 += value)
);
else
return bundledStrings[0].slice(
bundledStrings.position0,
(bundledStrings.position0 -= value)
);
}
return C1; // "never-used", return special object to denote that
case 0xc2:
@@ -338,7 +368,8 @@ export function read() {
value = dataView.getFloat32(position);
if (currentUnpackr.useFloat32 > 2) {
// this does rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
const multiplier = mult10[((src[position] & 0x7f) << 1) | (src[position + 1] >> 7)];
const multiplier =
mult10[((src[position] & 0x7f) << 1) | (src[position + 1] >> 7)];
position += 4;
return ((multiplier * value + (value > 0 ? 0.5 : -0.5)) >> 0) / multiplier;
}
@@ -391,7 +422,8 @@ export function read() {
value = dataView.getBigInt64(position).toString();
} else if (currentUnpackr.int64AsType === 'auto') {
value = dataView.getBigInt64(position);
if (value >= BigInt(-2) << BigInt(52) && value <= BigInt(2) << BigInt(52)) value = Number(value);
if (value >= BigInt(-2) << BigInt(52) && value <= BigInt(2) << BigInt(52))
value = Number(value);
} else value = dataView.getBigInt64(position);
position += 8;
return value;
@@ -433,7 +465,10 @@ export function read() {
// str 8
value = src[position++];
if (srcStringEnd >= position) {
return srcString.slice(position - srcStringStart, (position += value) - srcStringStart);
return srcString.slice(
position - srcStringStart,
(position += value) - srcStringStart
);
}
return readString8(value);
case 0xda:
@@ -441,7 +476,10 @@ export function read() {
value = dataView.getUint16(position);
position += 2;
if (srcStringEnd >= position) {
return srcString.slice(position - srcStringStart, (position += value) - srcStringStart);
return srcString.slice(
position - srcStringStart,
(position += value) - srcStringStart
);
}
return readString16(value);
case 0xdb:
@@ -449,7 +487,10 @@ export function read() {
value = dataView.getUint32(position);
position += 4;
if (srcStringEnd >= position) {
return srcString.slice(position - srcStringStart, (position += value) - srcStringStart);
return srcString.slice(
position - srcStringStart,
(position += value) - srcStringStart
);
}
return readString32(value);
case 0xdc:
@@ -504,7 +545,8 @@ function createStructureReader(structure, firstId) {
.join(',') +
'})}'
)(read));
if (structure.highByte === 0) structure.read = createSecondByteReader(firstId, structure.read);
if (structure.highByte === 0)
structure.read = createSecondByteReader(firstId, structure.read);
return readObject(); // second byte is already read, if there is one so immediately read object
}
const object = {};
@@ -527,7 +569,8 @@ const createSecondByteReader = (firstId, read0) =>
function () {
const highByte = src[position++];
if (highByte === 0) return read0();
const id = firstId < 32 ? -(firstId + (highByte << 5)) : firstId + (highByte << 5);
const id =
firstId < 32 ? -(firstId + (highByte << 5)) : firstId + (highByte << 5);
const structure = currentStructures[id] || loadStructures()[id];
if (!structure) {
throw new Error('Record id is not defined for ' + id);
@@ -536,22 +579,24 @@ const createSecondByteReader = (firstId, read0) =>
return structure.read();
};
export function loadStructures() {
function loadStructures() {
const loadedStructures = saveState(() => {
// save the state in case getStructures modifies our buffer
src = null;
return currentUnpackr.getStructures();
});
return (currentStructures = currentUnpackr._mergeStructures(loadedStructures, currentStructures));
return (currentStructures = currentUnpackr._mergeStructures(
loadedStructures,
currentStructures
));
}
var readFixedString = readStringJS;
var readString8 = readStringJS;
var readString16 = readStringJS;
var readString32 = readStringJS;
export let isNativeAccelerationEnabled = false;
export function setExtractor(extractStrings) {
let isNativeAccelerationEnabled = false;
function setExtractor(extractStrings) {
isNativeAccelerationEnabled = true;
readFixedString = readString(1);
readString8 = readString(2);
@@ -563,7 +608,11 @@ export function setExtractor(extractStrings) {
if (string == null) {
if (bundledStrings) return readStringJS(length);
const byteOffset = src.byteOffset;
const extraction = extractStrings(position - headerLength + byteOffset, srcEnd + byteOffset, src.buffer);
const extraction = extractStrings(
position - headerLength + byteOffset,
srcEnd + byteOffset,
src.buffer
);
if (typeof extraction == 'string') {
string = extraction;
strings = EMPTY_ARRAY;
@@ -593,7 +642,8 @@ function readStringJS(length) {
if (length < 16) {
if ((result = shortStringInJS(length))) return result;
}
if (length > 64 && decoder) return decoder.decode(src.subarray(position, (position += length)));
if (length > 64 && decoder)
return decoder.decode(src.subarray(position, (position += length)));
const end = position + length;
const units = [];
result = '';
@@ -616,7 +666,8 @@ function readStringJS(length) {
const byte2 = src[position++] & 0x3f;
const byte3 = src[position++] & 0x3f;
const byte4 = src[position++] & 0x3f;
let unit = ((byte1 & 0x07) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4;
let unit =
((byte1 & 0x07) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4;
if (unit > 0xffff) {
unit -= 0x10000;
units.push(((unit >>> 10) & 0x3ff) | 0xd800);
@@ -639,7 +690,7 @@ function readStringJS(length) {
return result;
}
export function readString(source, start, length) {
function readString(source, start, length) {
const existingSrc = src;
src = source;
position = start;
@@ -810,7 +861,8 @@ function shortStringInJS(length) {
position -= 14;
return;
}
if (length < 15) return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m, n);
if (length < 15)
return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m, n);
const o = src[position++];
if ((o & 0x80) > 0) {
position -= 15;
@@ -862,14 +914,17 @@ function readExt(length) {
const type = src[position++];
if (currentExtensions[type]) {
let end;
return currentExtensions[type](src.subarray(position, (end = position += length)), (readPosition) => {
position = readPosition;
try {
return read();
} finally {
position = end;
return currentExtensions[type](
src.subarray(position, (end = position += length)),
(readPosition) => {
position = readPosition;
try {
return read();
} finally {
position = end;
}
}
});
);
} else throw new Error('Unknown extension type ' + type);
}
@@ -881,14 +936,20 @@ function readKey() {
length = length - 0xa0;
if (srcStringEnd >= position)
// if it has been extracted, must use it (and faster anyway)
return srcString.slice(position - srcStringStart, (position += length) - srcStringStart);
return srcString.slice(
position - srcStringStart,
(position += length) - srcStringStart
);
else if (!(srcStringEnd == 0 && srcEnd < 180)) return readFixedString(length);
} else {
// not cacheable, go back and do a standard read
position--;
return read().toString();
}
const key = ((length << 5) ^ (length > 1 ? dataView.getUint16(position) : length > 0 ? src[position] : 0)) & 0xfff;
const key =
((length << 5) ^
(length > 1 ? dataView.getUint16(position) : length > 0 ? src[position] : 0)) &
0xfff;
let entry = keyCache[key];
let checkPosition = position;
let end = position + length - 3;
@@ -947,7 +1008,8 @@ const recordDefinition = (id, highByte) => {
}
const existingStructure = currentStructures[id];
if (existingStructure && existingStructure.isShared) {
(currentStructures.restoreStructures || (currentStructures.restoreStructures = []))[id] = existingStructure;
(currentStructures.restoreStructures ||
(currentStructures.restoreStructures = []))[id] = existingStructure;
}
currentStructures[id] = structure;
structure.read = createStructureReader(structure, firstByte);
@@ -992,7 +1054,7 @@ currentExtensions[0x70] = (data) => {
currentExtensions[0x73] = () => new Set(read());
export const typedArrays = [
const typedArrays = [
'Int8',
'Uint8',
'Uint8Clamped',
@@ -1009,7 +1071,8 @@ export const typedArrays = [
currentExtensions[0x74] = (data) => {
const typeCode = data[0];
const typedArrayName = typedArrays[typeCode];
if (!typedArrayName) throw new Error('Could not find typed array for code ' + typeCode);
if (!typedArrayName)
throw new Error('Could not find typed array for code ' + typeCode);
// we have to always slice/copy here to get a new ArrayBuffer that is word/byte aligned
return new glbl[typedArrayName](Uint8Array.prototype.slice.call(data, 1).buffer);
};
@@ -1033,11 +1096,20 @@ currentExtensions[0x62] = (data) => {
currentExtensions[0xff] = (data) => {
// 32-bit date extension
if (data.length == 4) return new Date((data[0] * 0x1000000 + (data[1] << 16) + (data[2] << 8) + data[3]) * 1000);
if (data.length == 4)
return new Date(
(data[0] * 0x1000000 + (data[1] << 16) + (data[2] << 8) + data[3]) * 1000
);
else if (data.length == 8)
return new Date(
((data[0] << 22) + (data[1] << 14) + (data[2] << 6) + (data[3] >> 2)) / 1000000 +
((data[3] & 0x3) * 0x100000000 + data[4] * 0x1000000 + (data[5] << 16) + (data[6] << 8) + data[7]) * 1000
((data[0] << 22) + (data[1] << 14) + (data[2] << 6) + (data[3] >> 2)) /
1000000 +
((data[3] & 0x3) * 0x100000000 +
data[4] * 0x1000000 +
(data[5] << 16) +
(data[6] << 8) +
data[7]) *
1000
);
else if (data.length == 12)
return new Date(
@@ -1070,7 +1142,10 @@ function saveState(callback) {
const savedSrc = new Uint8Array(src.slice(0, srcEnd)); // we copy the data in case it changes while external data is processed
const savedStructures = currentStructures;
const savedStructuresContents = currentStructures.slice(0, currentStructures.length);
const savedStructuresContents = currentStructures.slice(
0,
currentStructures.length
);
const savedPackr = currentUnpackr;
const savedSequentialMode = sequentialMode;
const value = callback();
@@ -1091,41 +1166,20 @@ function saveState(callback) {
dataView = new DataView(src.buffer, src.byteOffset, src.byteLength);
return value;
}
export function clearSource() {
function clearSource() {
src = null;
referenceMap = null;
currentStructures = null;
}
export function addExtension(extension) {
function addExtension(extension) {
if (extension.unpack) currentExtensions[extension.type] = extension.unpack;
else currentExtensions[extension.type] = extension;
}
export const mult10 = new Array(147); // this is a table matching binary exponents to the multiplier to determine significant digit rounding
const mult10 = new Array(147);
for (let i = 0; i < 256; i++) {
mult10[i] = +('1e' + Math.floor(45.15 - i * 0.30103));
}
export const Decoder = Unpackr;
var defaultUnpackr = new Unpackr({ useRecords: false });
const defaultUnpackr = new Unpackr({ useRecords: false });
export const unpack = defaultUnpackr.unpack;
export const unpackMultiple = defaultUnpackr.unpackMultiple;
export const decode = defaultUnpackr.unpack;
export const FLOAT32_OPTIONS = {
NEVER: 0,
ALWAYS: 1,
DECIMAL_ROUND: 3,
DECIMAL_FIT: 4
};
const f32Array = new Float32Array(1);
const u8Array = new Uint8Array(f32Array.buffer, 0, 4);
export function roundFloat32(float32Number) {
f32Array[0] = float32Number;
const multiplier = mult10[((u8Array[3] & 0x7f) << 1) | (u8Array[2] >> 7)];
return ((multiplier * float32Number + (float32Number > 0 ? 0.5 : -0.5)) >> 0) / multiplier;
}
export function setReadStruct(updatedReadStruct, loadedStructs, saveState) {
readStruct = updatedReadStruct;
onLoadedStructures = loadedStructs;
onSaveState = saveState;
}

View File

@@ -1,29 +1,41 @@
import { useCallback, useState } from 'react';
import { useBlocker } from 'react-router';
import { toast } from 'react-toastify';
import AddIcon from '@mui/icons-material/Add';
import CancelIcon from '@mui/icons-material/Cancel';
import EditOutlinedIcon from '@mui/icons-material/EditOutlined';
import RefreshIcon from '@mui/icons-material/Refresh';
import WarningIcon from '@mui/icons-material/Warning';
import { Button, Typography, Box } from '@mui/material';
import { Table, Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table';
import { Box, Button, Typography } from '@mui/material';
import {
Body,
Cell,
Header,
HeaderCell,
HeaderRow,
Row,
Table
} from '@table-library/react-table-library/table';
import { useTheme } from '@table-library/react-table-library/theme';
// eslint-disable-next-line import/named
import { updateState, useRequest } from 'alova';
import { useState, useCallback } from 'react';
import { useBlocker } from 'react-router-dom';
import { toast } from 'react-toastify';
import SettingsCustomEntitiesDialog from './SettingsCustomEntitiesDialog';
import * as EMSESP from './api';
import { DeviceValueTypeNames, DeviceValueUOM_s } from './types';
import { entityItemValidation } from './validators';
import type { EntityItem } from './types';
import type { FC } from 'react';
import { ButtonRow, FormLoader, SectionContent, BlockNavigation } from 'components';
import { updateState, useRequest } from 'alova/client';
import {
BlockNavigation,
ButtonRow,
FormLoader,
SectionContent,
useLayoutTitle
} from 'components';
import { useI18nContext } from 'i18n/i18n-react';
import { useInterval } from 'utils';
const SettingsCustomEntities: FC = () => {
import { readCustomEntities, writeCustomEntities } from '../../api/app';
import SettingsCustomEntitiesDialog from './CustomEntitiesDialog';
import { DeviceValueTypeNames, DeviceValueUOM_s } from './types';
import type { Entities, EntityItem } from './types';
import { entityItemValidation } from './validators';
const CustomEntities = () => {
const { LL } = useI18nContext();
const [numChanges, setNumChanges] = useState<number>(0);
const blocker = useBlocker(numChanges !== 0);
@@ -31,16 +43,26 @@ const SettingsCustomEntities: FC = () => {
const [creating, setCreating] = useState<boolean>(false);
const [dialogOpen, setDialogOpen] = useState<boolean>(false);
useLayoutTitle(LL.CUSTOM_ENTITIES(0));
const {
data: entities,
send: fetchEntities,
error
} = useRequest(EMSESP.readCustomEntities, {
initialData: [],
force: true
} = useRequest(readCustomEntities, {
initialData: []
});
const { send: writeEntities } = useRequest((data) => EMSESP.writeCustomEntities(data), { immediate: false });
useInterval(() => {
if (!dialogOpen && !numChanges) {
void fetchEntities();
}
});
const { send: writeEntities } = useRequest(
(data: Entities) => writeCustomEntities(data),
{ immediate: false }
);
function hasEntityChanged(ei: EntityItem) {
return (
@@ -54,6 +76,7 @@ const SettingsCustomEntities: FC = () => {
ei.factor !== ei.o_factor ||
ei.value_type !== ei.o_value_type ||
ei.writeable !== ei.o_writeable ||
ei.hide !== ei.o_hide ||
ei.deleted !== ei.o_deleted ||
(ei.value || '') !== (ei.o_value || '')
);
@@ -61,7 +84,7 @@ const SettingsCustomEntities: FC = () => {
const entity_theme = useTheme({
Table: `
--data-table-library_grid-template-columns: repeat(1, minmax(60px, 1fr)) minmax(80px, auto) 80px 80px 80px 90px;
--data-table-library_grid-template-columns: repeat(1, minmax(60px, 1fr)) minmax(80px, auto) 80px 80px 80px 120px;
`,
BaseRow: `
font-size: 14px;
@@ -103,15 +126,10 @@ const SettingsCustomEntities: FC = () => {
position: relative;
cursor: pointer;
.td {
border-top: 1px solid #565656;
border-bottom: 1px solid #565656;
}
&:hover .td {
border-top: 1px solid #177ac9;
border-bottom: 1px solid #177ac9;
}
&:nth-of-type(odd) .td {
background-color: #303030;
background-color: #177ac9;
}
`
});
@@ -119,8 +137,8 @@ const SettingsCustomEntities: FC = () => {
const saveEntities = async () => {
await writeEntities({
entities: entities
.filter((ei) => !ei.deleted)
.map((condensed_ei) => ({
.filter((ei: EntityItem) => !ei.deleted)
.map((condensed_ei: EntityItem) => ({
id: condensed_ei.id,
ram: condensed_ei.ram,
name: condensed_ei.name,
@@ -130,6 +148,7 @@ const SettingsCustomEntities: FC = () => {
factor: condensed_ei.factor,
uom: condensed_ei.uom,
writeable: condensed_ei.writeable,
hide: condensed_ei.hide,
value_type: condensed_ei.value_type,
value: condensed_ei.value
}))
@@ -137,8 +156,8 @@ const SettingsCustomEntities: FC = () => {
.then(() => {
toast.success(LL.ENTITIES_UPDATED());
})
.catch((err) => {
toast.error(err.message);
.catch((error: Error) => {
toast.error(error.message);
})
.finally(async () => {
await fetchEntities();
@@ -164,16 +183,40 @@ const SettingsCustomEntities: FC = () => {
const onDialogSave = (updatedItem: EntityItem) => {
setDialogOpen(false);
updateState('entities', (data) => {
void updateState(readCustomEntities(), (data: EntityItem[]) => {
const new_data = creating
? [...data.filter((ei) => creating || ei.o_id !== updatedItem.o_id), updatedItem]
: data.map((ei) => (ei.id === updatedItem.id ? { ...ei, ...updatedItem } : ei));
? [
...data.filter((ei) => creating || ei.o_id !== updatedItem.o_id),
updatedItem
]
: data.map((ei) =>
ei.id === updatedItem.id ? { ...ei, ...updatedItem } : ei
);
setNumChanges(new_data.filter((ei) => hasEntityChanged(ei)).length);
return new_data;
});
};
const onDialogDup = (item: EntityItem) => {
setCreating(true);
setSelectedEntityItem({
id: Math.floor(Math.random() * (Math.floor(200) - 100) + 100),
name: item.name + '_',
ram: item.ram,
device_id: item.device_id,
type_id: item.type_id,
offset: item.offset,
factor: item.factor,
uom: item.uom,
value_type: item.value_type,
writeable: item.writeable,
deleted: false,
hide: item.hide,
value: item.value
});
setDialogOpen(true);
};
const addEntityItem = () => {
setCreating(true);
setSelectedEntityItem({
@@ -188,17 +231,19 @@ const SettingsCustomEntities: FC = () => {
value_type: 0,
writeable: false,
deleted: false,
hide: false,
value: ''
});
setDialogOpen(true);
};
function formatValue(value: any, uom: number) {
return value === undefined || uom === undefined
function formatValue(value: unknown, uom: number) {
return value === undefined
? ''
: typeof value === 'number'
? new Intl.NumberFormat().format(value) + (uom === 0 ? '' : ' ' + DeviceValueUOM_s[uom])
: value;
? new Intl.NumberFormat().format(value) +
(uom === 0 ? '' : ' ' + DeviceValueUOM_s[uom])
: (value as string) + (uom === 0 ? '' : ' ' + DeviceValueUOM_s[uom]);
}
function showHex(value: number, digit: number) {
@@ -207,12 +252,22 @@ const SettingsCustomEntities: FC = () => {
const renderEntity = () => {
if (!entities) {
return <FormLoader onRetry={fetchEntities} errorMessage={error?.message} />;
return (
<FormLoader onRetry={fetchEntities} errorMessage={error?.message || ''} />
);
}
return (
<Table data={{ nodes: entities.filter((ei) => !ei.deleted) }} theme={entity_theme} layout={{ custom: true }}>
{(tableList: any) => (
<Table
data={{
nodes: entities
.filter((ei: EntityItem) => !ei.deleted)
.sort((a: EntityItem, b: EntityItem) => a.name.localeCompare(b.name))
}}
theme={entity_theme}
layout={{ custom: true }}
>
{(tableList: EntityItem[]) => (
<>
<Header>
<HeaderRow>
@@ -220,8 +275,8 @@ const SettingsCustomEntities: FC = () => {
<HeaderCell stiff>{LL.ID_OF(LL.DEVICE())}</HeaderCell>
<HeaderCell stiff>{LL.ID_OF(LL.TYPE(1))}</HeaderCell>
<HeaderCell stiff>{LL.OFFSET()}</HeaderCell>
<HeaderCell stiff>{LL.TYPE(1)}</HeaderCell>
<HeaderCell stiff>{LL.VALUE(1)}</HeaderCell>
<HeaderCell stiff>{LL.TYPE(0)}</HeaderCell>
<HeaderCell stiff>{LL.VALUE(0)}</HeaderCell>
</HeaderRow>
</Header>
<Body>
@@ -229,12 +284,18 @@ const SettingsCustomEntities: FC = () => {
<Row key={ei.name} item={ei} onClick={() => editEntityItem(ei)}>
<Cell>
{ei.name}&nbsp;
{ei.writeable && <EditOutlinedIcon color="primary" sx={{ fontSize: 12 }} />}
{ei.writeable && (
<EditOutlinedIcon color="primary" sx={{ fontSize: 12 }} />
)}
</Cell>
<Cell>
{ei.ram === 1 ? '' : showHex(ei.device_id as number, 2)}
</Cell>
<Cell>{ei.ram === 1 ? '' : showHex(ei.device_id as number, 2)}</Cell>
<Cell>{ei.ram === 1 ? '' : showHex(ei.type_id as number, 3)}</Cell>
<Cell>{ei.ram === 1 ? '' : ei.offset}</Cell>
<Cell>{ei.ram === 1 ? 'RAM' : DeviceValueTypeNames[ei.value_type]}</Cell>
<Cell>
{ei.ram === 1 ? 'RAM' : DeviceValueTypeNames[ei.value_type]}
</Cell>
<Cell>{formatValue(ei.value, ei.uom)}</Cell>
</Row>
))}
@@ -246,10 +307,10 @@ const SettingsCustomEntities: FC = () => {
};
return (
<SectionContent title={LL.CUSTOM_ENTITIES(0)} titleGutter>
<SectionContent>
{blocker ? <BlockNavigation blocker={blocker} /> : null}
<Box mb={2} color="warning.main">
<Typography variant="body2">{LL.ENTITIES_HELP_1()}</Typography>
<Typography variant="body1">{LL.ENTITIES_HELP_1()}.</Typography>
</Box>
{renderEntity()}
@@ -260,16 +321,22 @@ const SettingsCustomEntities: FC = () => {
creating={creating}
onClose={onDialogClose}
onSave={onDialogSave}
onDup={onDialogDup}
selectedItem={selectedEntityItem}
validator={entityItemValidation()}
validator={entityItemValidation(entities, selectedEntityItem)}
/>
)}
<Box display="flex" flexWrap="wrap">
<Box mt={2} display="flex" flexWrap="wrap">
<Box flexGrow={1}>
{numChanges > 0 && (
<ButtonRow>
<Button startIcon={<CancelIcon />} variant="outlined" onClick={onDialogCancel} color="secondary">
<Button
startIcon={<CancelIcon />}
variant="outlined"
onClick={onDialogCancel}
color="secondary"
>
{LL.CANCEL()}
</Button>
<Button
@@ -284,18 +351,18 @@ const SettingsCustomEntities: FC = () => {
)}
</Box>
<Box flexWrap="nowrap" whiteSpace="nowrap">
<ButtonRow>
<Button startIcon={<RefreshIcon />} variant="outlined" color="secondary" onClick={fetchEntities}>
{LL.REFRESH()}
</Button>
<Button startIcon={<AddIcon />} variant="outlined" color="primary" onClick={addEntityItem}>
{LL.ADD(0)}
</Button>
</ButtonRow>
<Button
startIcon={<AddIcon />}
variant="outlined"
color="primary"
onClick={addEntityItem}
>
{LL.ADD(0)}
</Button>
</Box>
</Box>
</SectionContent>
);
};
export default SettingsCustomEntities;
export default CustomEntities;

View File

@@ -0,0 +1,434 @@
import { useEffect, useState } from 'react';
import AddIcon from '@mui/icons-material/Add';
import CancelIcon from '@mui/icons-material/Cancel';
import CommentsDisabledOutlinedIcon from '@mui/icons-material/CommentsDisabledOutlined';
import DoneIcon from '@mui/icons-material/Done';
import EditOffOutlinedIcon from '@mui/icons-material/EditOffOutlined';
import EditOutlinedIcon from '@mui/icons-material/EditOutlined';
import InsertCommentOutlinedIcon from '@mui/icons-material/InsertCommentOutlined';
import RemoveIcon from '@mui/icons-material/RemoveCircleOutline';
import {
Box,
Button,
Checkbox,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
Grid,
InputAdornment,
MenuItem,
TextField
} from '@mui/material';
import { dialogStyle } from 'CustomTheme';
import type Schema from 'async-validator';
import type { ValidateFieldsError } from 'async-validator';
import { BlockFormControlLabel, ValidatedTextField } from 'components';
import { useI18nContext } from 'i18n/i18n-react';
import { numberValue, updateValue } from 'utils';
import { validate } from 'validators';
import { DeviceValueType, DeviceValueTypeNames, DeviceValueUOM_s } from './types';
import type { EntityItem } from './types';
interface CustomEntitiesDialogProps {
open: boolean;
creating: boolean;
onClose: () => void;
onSave: (ei: EntityItem) => void;
onDup: (ei: EntityItem) => void;
selectedItem: EntityItem;
validator: Schema;
}
const CustomEntitiesDialog = ({
open,
creating,
onClose,
onSave,
onDup,
selectedItem,
validator
}: CustomEntitiesDialogProps) => {
const { LL } = useI18nContext();
const [editItem, setEditItem] = useState<EntityItem>(selectedItem);
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
const updateFormValue = updateValue(setEditItem);
useEffect(() => {
if (open) {
setFieldErrors(undefined);
setEditItem(selectedItem);
// convert to hex strings straight away
setEditItem({
...selectedItem,
device_id: selectedItem.device_id.toString(16).toUpperCase(),
type_id: selectedItem.type_id.toString(16).toUpperCase(),
factor:
selectedItem.value_type === DeviceValueType.BOOL
? selectedItem.factor.toString(16).toUpperCase()
: selectedItem.factor
});
}
}, [open, selectedItem]);
const handleClose = (
_event: React.SyntheticEvent,
reason: 'backdropClick' | 'escapeKeyDown'
) => {
if (reason !== 'backdropClick') {
onClose();
}
};
const save = async () => {
try {
setFieldErrors(undefined);
await validate(validator, editItem);
if (typeof editItem.device_id === 'string') {
editItem.device_id = parseInt(editItem.device_id, 16);
}
if (typeof editItem.type_id === 'string') {
editItem.type_id = parseInt(editItem.type_id, 16);
}
if (
editItem.value_type === DeviceValueType.BOOL &&
typeof editItem.factor === 'string'
) {
editItem.factor = parseInt(editItem.factor, 16);
}
onSave(editItem);
} catch (error) {
setFieldErrors(error as ValidateFieldsError);
}
};
const remove = () => {
editItem.deleted = true;
onSave(editItem);
};
const dup = () => {
onDup(editItem);
};
return (
<Dialog sx={dialogStyle} open={open} onClose={handleClose}>
<DialogTitle>
{creating ? LL.ADD(1) + ' ' + LL.NEW(1) : LL.EDIT()}&nbsp;{LL.ENTITY()}
</DialogTitle>
<DialogContent dividers>
<Box display="flex" flexWrap="wrap" mb={1}>
<Box flexWrap="nowrap" whiteSpace="nowrap" />
</Box>
<Grid container spacing={2} rowSpacing={0}>
<Grid size={12}>
<ValidatedTextField
fieldErrors={fieldErrors || {}}
name="name"
label={LL.NAME(0)}
value={editItem.name}
margin="normal"
fullWidth
onChange={updateFormValue}
/>
</Grid>
<Grid mt={3}>
<BlockFormControlLabel
control={
<Checkbox
icon={<InsertCommentOutlinedIcon htmlColor="white" />}
checkedIcon={<CommentsDisabledOutlinedIcon color="primary" />}
checked={editItem.hide}
onChange={updateFormValue}
name="hide"
/>
}
label="API/MQTT"
/>
</Grid>
<Grid>
<TextField
name="ram"
label={LL.VALUE(0) + ' ' + LL.TYPE(1)}
value={editItem.ram}
variant="outlined"
onChange={updateFormValue}
margin="normal"
fullWidth
select
>
<MenuItem value={0}>EMS-{LL.VALUE(1)}</MenuItem>
<MenuItem value={1}>RAM-{LL.VALUE(1)}</MenuItem>
</TextField>
</Grid>
{editItem.ram === 1 && (
<>
<Grid>
<TextField
name="value"
label={LL.DEFAULT(0) + ' ' + LL.VALUE(0)}
type="string"
value={editItem.value as string}
variant="outlined"
onChange={updateFormValue}
fullWidth
margin="normal"
/>
</Grid>
<Grid>
<TextField
name="uom"
label={LL.UNIT()}
value={editItem.uom}
margin="normal"
onChange={updateFormValue}
select
>
{DeviceValueUOM_s.map((val, i) => (
<MenuItem key={val} value={i}>
{val}
</MenuItem>
))}
</TextField>
</Grid>
</>
)}
{editItem.ram === 0 && (
<>
<Grid mt={3}>
<BlockFormControlLabel
control={
<Checkbox
icon={<EditOffOutlinedIcon color="primary" />}
checkedIcon={<EditOutlinedIcon htmlColor="white" />}
checked={editItem.writeable}
onChange={updateFormValue}
name="writeable"
/>
}
label={LL.WRITEABLE()}
/>
</Grid>
<Grid>
<ValidatedTextField
fieldErrors={fieldErrors || {}}
name="device_id"
label={LL.ID_OF(LL.DEVICE())}
margin="normal"
sx={{ width: '11ch' }}
type="string"
value={editItem.device_id as string}
onChange={updateFormValue}
slotProps={{
input: {
startAdornment: (
<InputAdornment position="start">0x</InputAdornment>
)
},
htmlInput: { style: { textTransform: 'uppercase' } }
}}
/>
</Grid>
<Grid>
<ValidatedTextField
fieldErrors={fieldErrors || {}}
name="type_id"
label={LL.ID_OF(LL.TYPE(1))}
margin="normal"
sx={{ width: '11ch' }}
type="string"
value={editItem.type_id as string}
onChange={updateFormValue}
slotProps={{
input: {
startAdornment: (
<InputAdornment position="start">0x</InputAdornment>
)
},
htmlInput: { style: { textTransform: 'uppercase' } }
}}
/>
</Grid>
<Grid>
<ValidatedTextField
fieldErrors={fieldErrors || {}}
name="offset"
label={LL.OFFSET()}
margin="normal"
sx={{ width: '11ch' }}
type="number"
value={numberValue(editItem.offset)}
onChange={updateFormValue}
/>
</Grid>
<Grid>
<TextField
name="value_type"
label={LL.VALUE(0) + ' ' + LL.TYPE(1)}
value={editItem.value_type}
variant="outlined"
sx={{ width: '11ch' }}
onChange={updateFormValue}
margin="normal"
select
>
<MenuItem value={DeviceValueType.BOOL}>
{DeviceValueTypeNames[DeviceValueType.BOOL]}
</MenuItem>
<MenuItem value={DeviceValueType.INT8}>
{DeviceValueTypeNames[DeviceValueType.INT8]}
</MenuItem>
<MenuItem value={DeviceValueType.UINT8}>
{DeviceValueTypeNames[DeviceValueType.UINT8]}
</MenuItem>
<MenuItem value={DeviceValueType.INT16}>
{DeviceValueTypeNames[DeviceValueType.INT16]}
</MenuItem>
<MenuItem value={DeviceValueType.UINT16}>
{DeviceValueTypeNames[DeviceValueType.UINT16]}
</MenuItem>
<MenuItem value={DeviceValueType.UINT24}>
{DeviceValueTypeNames[DeviceValueType.UINT24]}
</MenuItem>
<MenuItem value={DeviceValueType.TIME}>
{DeviceValueTypeNames[DeviceValueType.TIME]}
</MenuItem>
<MenuItem value={DeviceValueType.UINT32}>
{DeviceValueTypeNames[DeviceValueType.UINT32]}
</MenuItem>
<MenuItem value={DeviceValueType.STRING}>
{DeviceValueTypeNames[DeviceValueType.STRING]}
</MenuItem>
</TextField>
</Grid>
{editItem.value_type !== DeviceValueType.BOOL &&
editItem.value_type !== DeviceValueType.STRING && (
<>
<Grid>
<TextField
name="factor"
label={LL.FACTOR()}
value={numberValue(editItem.factor as number)}
variant="outlined"
onChange={updateFormValue}
sx={{ width: '11ch' }}
margin="normal"
type="number"
slotProps={{
htmlInput: { step: '0.001' }
}}
/>
</Grid>
<Grid>
<TextField
name="uom"
label={LL.UNIT()}
value={editItem.uom}
margin="normal"
sx={{ width: '11ch' }}
onChange={updateFormValue}
select
>
{DeviceValueUOM_s.map((val, i) => (
<MenuItem key={val} value={i}>
{val}
</MenuItem>
))}
</TextField>
</Grid>
</>
)}
{editItem.value_type === DeviceValueType.STRING &&
editItem.device_id !== '0' && (
<Grid>
<ValidatedTextField
fieldErrors={fieldErrors || {}}
name="factor"
label={LL.BYTES()}
value={numberValue(editItem.factor as number)}
sx={{ width: '11ch' }}
variant="outlined"
onChange={updateFormValue}
margin="normal"
type="number"
slotProps={{
htmlInput: { step: '1', min: '1', max: '255' }
}}
/>
</Grid>
)}
{editItem.value_type === DeviceValueType.BOOL && (
<Grid>
<ValidatedTextField
fieldErrors={fieldErrors || {}}
name="factor"
label={LL.BITMASK()}
value={editItem.factor as string}
sx={{ width: '11ch' }}
variant="outlined"
onChange={updateFormValue}
margin="normal"
type="string"
slotProps={{
input: {
startAdornment: (
<InputAdornment position="start">0x</InputAdornment>
)
},
htmlInput: { style: { textTransform: 'uppercase' } }
}}
/>
</Grid>
)}
</>
)}
</Grid>
</DialogContent>
<DialogActions>
{!creating && (
<Box flexGrow={1}>
<Button
startIcon={<RemoveIcon />}
variant="outlined"
color="warning"
onClick={remove}
>
{LL.REMOVE()}
</Button>
<Button
sx={{ ml: 1 }}
startIcon={<AddIcon />}
variant="outlined"
color="primary"
onClick={dup}
>
{LL.DUPLICATE()}
</Button>
</Box>
)}
<Button
startIcon={<CancelIcon />}
variant="outlined"
onClick={onClose}
color="secondary"
>
{LL.CANCEL()}
</Button>
<Button
startIcon={creating ? <AddIcon /> : <DoneIcon />}
variant="outlined"
onClick={save}
color="primary"
>
{creating ? LL.ADD(0) : LL.UPDATE()}
</Button>
</DialogActions>
</Dialog>
);
};
export default CustomEntitiesDialog;

View File

@@ -1,50 +1,70 @@
import { useCallback, useEffect, useState } from 'react';
import { useBlocker, useLocation } from 'react-router';
import { toast } from 'react-toastify';
import CancelIcon from '@mui/icons-material/Cancel';
import EditIcon from '@mui/icons-material/Edit';
import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew';
import SaveIcon from '@mui/icons-material/Save';
import SearchIcon from '@mui/icons-material/Search';
import SettingsBackupRestoreIcon from '@mui/icons-material/SettingsBackupRestore';
import WarningIcon from '@mui/icons-material/Warning';
import {
Button,
Typography,
Box,
MenuItem,
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
Grid,
InputAdornment,
Link,
MenuItem,
TextField,
ToggleButton,
ToggleButtonGroup,
Grid,
TextField,
Link,
InputAdornment
Typography
} from '@mui/material';
import { Table, Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table';
import { useTheme } from '@table-library/react-table-library/theme';
import { useRequest } from 'alova';
import { useState, useEffect, useCallback } from 'react';
import { useBlocker, useLocation } from 'react-router-dom';
import { toast } from 'react-toastify';
import {
Body,
Cell,
Header,
HeaderCell,
HeaderRow,
Row,
Table
} from '@table-library/react-table-library/table';
import { useTheme } from '@table-library/react-table-library/theme';
import { dialogStyle } from 'CustomTheme';
import { useRequest } from 'alova/client';
import SystemMonitor from 'app/status/SystemMonitor';
import {
BlockNavigation,
ButtonRow,
MessageBox,
SectionContent,
useLayoutTitle
} from 'components';
import { useI18nContext } from 'i18n/i18n-react';
import {
API,
readCoreData,
readDeviceEntities,
resetCustomizations,
writeCustomizationEntities,
writeDeviceName
} from '../../api/app';
import SettingsCustomizationsDialog from './CustomizationsDialog';
import EntityMaskToggle from './EntityMaskToggle';
import OptionIcon from './OptionIcon';
import SettingsCustomizationDialog from './SettingsCustomizationDialog';
import * as EMSESP from './api';
import { DeviceEntityMask } from './types';
import type { DeviceShort, DeviceEntity } from './types';
import type { FC } from 'react';
import { dialogStyle } from 'CustomTheme';
import * as SystemApi from 'api/system';
import { ButtonRow, SectionContent, MessageBox, BlockNavigation } from 'components';
import RestartMonitor from 'framework/system/RestartMonitor';
import { useI18nContext } from 'i18n/i18n-react';
import type { APIcall, Device, DeviceEntity } from './types';
export const APIURL = window.location.origin + '/api/';
const SettingsCustomization: FC = () => {
const Customizations = () => {
const { LL } = useI18nContext();
const [numChanges, setNumChanges] = useState<number>(0);
const blocker = useBlocker(numChanges !== 0);
@@ -57,38 +77,81 @@ const SettingsCustomization: FC = () => {
const [search, setSearch] = useState('');
const [selectedDeviceEntity, setSelectedDeviceEntity] = useState<DeviceEntity>();
const [dialogOpen, setDialogOpen] = useState<boolean>(false);
const [rename, setRename] = useState<boolean>(false);
// fetch devices first
const { data: devices } = useRequest(EMSESP.readDevices);
useLayoutTitle(LL.CUSTOMIZATIONS());
// const { state } = useLocation();
const [selectedDevice, setSelectedDevice] = useState<number>(useLocation().state || -1);
// fetch devices first from coreData
const { data: devices, send: fetchCoreData } = useRequest(readCoreData);
const { send: sendAPI } = useRequest((data: APIcall) => API(data), {
immediate: false
});
const [selectedDevice, setSelectedDevice] = useState<number>(
Number(useLocation().state) || -1
);
const [selectedDeviceTypeNameURL, setSelectedDeviceTypeNameURL] =
useState<string>(''); // needed for API URL
const [selectedDeviceName, setSelectedDeviceName] = useState<string>('');
const { send: resetCustomizations } = useRequest(EMSESP.resetCustomizations(), {
const { send: sendResetCustomizations } = useRequest(resetCustomizations(), {
immediate: false
});
const { send: writeCustomizationEntities } = useRequest((data) => EMSESP.writeCustomizationEntities(data), {
immediate: false
});
const { send: sendDeviceName } = useRequest(
(data: { id: number; name: string }) => writeDeviceName(data),
{
immediate: false
}
);
const { send: readDeviceEntities, onSuccess: onSuccess } = useRequest((data) => EMSESP.readDeviceEntities(data), {
initialData: [],
immediate: false
});
const { send: sendCustomizationEntities } = useRequest(
(data: { id: number; entity_ids: string[] }) => writeCustomizationEntities(data),
{
immediate: false
}
);
const setOriginalSettings = (data: DeviceEntity[]) => {
setDeviceEntities(data.map((de) => ({ ...de, o_m: de.m, o_cn: de.cn, o_mi: de.mi, o_ma: de.ma })));
};
onSuccess((event) => {
const { send: sendDeviceEntities } = useRequest(
(data: number) => readDeviceEntities(data),
{
initialData: [],
immediate: false
}
).onSuccess((event) => {
setOriginalSettings(event.data);
});
const { send: restartCommand } = useRequest(SystemApi.restart(), {
immediate: false
});
const setOriginalSettings = (data: DeviceEntity[]) => {
setDeviceEntities(
data.map((de) => {
const result: DeviceEntity = {
...de,
o_m: de.m
};
if (de.cn !== undefined) {
result.o_cn = de.cn;
}
if (de.mi !== undefined) {
result.o_mi = de.mi;
}
if (de.ma !== undefined) {
result.o_ma = de.ma;
}
return result;
})
);
};
const doRestart = async () => {
setRestarting(true);
await sendAPI({ device: 'system', cmd: 'restart', id: 0 }).catch(
(error: Error) => {
toast.error(error.message);
}
);
};
const entities_theme = useTheme({
Table: `
@@ -136,10 +199,7 @@ const SettingsCustomization: FC = () => {
}
&:hover .td {
border-top: 1px solid #177ac9;
border-bottom: 1px solid #177ac9;
}
&:nth-of-type(odd) .td {
background-color: #303030;
background-color: #177ac9;
}
`,
Cell: `
@@ -159,7 +219,12 @@ const SettingsCustomization: FC = () => {
});
function hasEntityChanged(de: DeviceEntity) {
return (de?.cn || '') !== (de?.o_cn || '') || de.m !== de.o_m || de.ma !== de.o_ma || de.mi !== de.o_mi;
return (
(de?.cn || '') !== (de?.o_cn || '') ||
de.m !== de.o_m ||
de.ma !== de.o_ma ||
de.mi !== de.o_mi
);
}
useEffect(() => {
@@ -182,28 +247,24 @@ const SettingsCustomization: FC = () => {
useEffect(() => {
if (devices && selectedDevice !== -1) {
void readDeviceEntities(selectedDevice);
const id = devices.devices.findIndex((d) => d.i === selectedDevice);
if (id === -1) {
void sendDeviceEntities(selectedDevice);
const index = devices.devices.findIndex((d) => d.id === selectedDevice);
if (index === -1) {
setSelectedDevice(-1);
setSelectedDeviceName('');
setSelectedDeviceTypeNameURL('');
} else {
setSelectedDeviceName(devices.devices[id].tn || '');
const device = devices.devices[index];
if (device) {
setSelectedDeviceTypeNameURL(device.url || '');
setSelectedDeviceName(device.n);
}
setNumChanges(0);
setRestartNeeded(false);
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [devices, selectedDevice]);
const restart = async () => {
await restartCommand().catch((error) => {
toast.error(error.message);
});
setRestarting(true);
};
function formatValue(value: any) {
function formatValue(value: unknown) {
if (typeof value === 'number') {
return new Intl.NumberFormat().format(value);
} else if (value === undefined) {
@@ -211,12 +272,21 @@ const SettingsCustomization: FC = () => {
} else if (typeof value === 'boolean') {
return value ? 'true' : 'false';
}
return value;
return value as string;
}
const formatName = (de: DeviceEntity, withShortname: boolean) =>
(de.n && de.n[0] === '!' ? LL.COMMAND(1) + ': ' + de.n.slice(1) : de.cn && de.cn !== '' ? de.cn : de.n) +
(withShortname ? ' ' + de.id : '');
(de.n && de.n[0] === '!'
? de.t
? LL.COMMAND(1) + ': ' + de.t + ' ' + de.n.slice(1)
: LL.COMMAND(1) + ': ' + de.n.slice(1)
: de.cn && de.cn !== ''
? de.t
? de.t + ' ' + de.cn
: de.cn
: de.t
? de.t + ' ' + de.n
: de.n) + (withShortname ? ' ' + de.id : '');
const getMaskNumber = (newMask: string[]) => {
let new_mask = 0;
@@ -247,7 +317,8 @@ const SettingsCustomization: FC = () => {
};
const filter_entity = (de: DeviceEntity) =>
(de.m & selectedFilters || !selectedFilters) && formatName(de, true).includes(search.toLocaleLowerCase());
(de.m & selectedFilters || !selectedFilters) &&
formatName(de, true).toLowerCase().includes(search.toLowerCase());
const maskDisabled = (set: boolean) => {
setDeviceEntities(
@@ -256,8 +327,14 @@ const SettingsCustomization: FC = () => {
return {
...de,
m: set
? de.m | (DeviceEntityMask.DV_API_MQTT_EXCLUDE | DeviceEntityMask.DV_WEB_EXCLUDE)
: de.m & ~(DeviceEntityMask.DV_API_MQTT_EXCLUDE | DeviceEntityMask.DV_WEB_EXCLUDE)
? de.m |
(DeviceEntityMask.DV_API_MQTT_EXCLUDE |
DeviceEntityMask.DV_WEB_EXCLUDE)
: de.m &
~(
DeviceEntityMask.DV_API_MQTT_EXCLUDE |
DeviceEntityMask.DV_WEB_EXCLUDE
)
};
} else {
return de;
@@ -268,10 +345,10 @@ const SettingsCustomization: FC = () => {
const resetCustomization = async () => {
try {
await resetCustomizations();
await sendResetCustomizations();
toast.info(LL.CUSTOMIZATIONS_RESTART());
} catch (error) {
toast.error(error.message);
toast.error((error as Error).message);
} finally {
setConfirmReset(false);
}
@@ -282,7 +359,11 @@ const SettingsCustomization: FC = () => {
};
const updateDeviceEntity = (updatedItem: DeviceEntity) => {
setDeviceEntities(deviceEntities?.map((de) => (de.id === updatedItem.id ? { ...de, ...updatedItem } : de)));
setDeviceEntities(
deviceEntities?.map((de) =>
de.id === updatedItem.id ? { ...de, ...updatedItem } : de
)
);
};
const onDialogSave = (updatedItem: DeviceEntity) => {
@@ -324,42 +405,110 @@ const SettingsCustomization: FC = () => {
return;
}
await writeCustomizationEntities({ id: selectedDevice, entity_ids: masked_entities }).catch((error) => {
if (error.message === 'Reboot required') {
setRestartNeeded(true);
} else {
toast.error(error.message);
}
});
setOriginalSettings(deviceEntities);
await sendCustomizationEntities({
id: selectedDevice,
entity_ids: masked_entities
})
.then(() => {
toast.success(LL.CUSTOMIZATIONS_SAVED());
})
.catch((error: Error) => {
if (error.message === 'Reboot required') {
setRestartNeeded(true);
} else {
toast.error(error.message);
}
})
.finally(() => {
setOriginalSettings(deviceEntities);
});
}
};
const renameDevice = async () => {
await sendDeviceName({ id: selectedDevice, name: selectedDeviceName })
.then(() => {
toast.success(LL.UPDATED_OF(LL.NAME(1)));
})
.catch(() => {
toast.error(LL.UPDATE_OF(LL.NAME(1)) + ' ' + LL.FAILED(1));
})
.finally(async () => {
setRename(false);
await fetchCoreData();
});
};
const renderDeviceList = () => (
<>
<Box mb={1} color="warning.main">
<Typography variant="body2">{LL.CUSTOMIZATIONS_HELP_1()}.</Typography>
<Typography variant="body1">{LL.CUSTOMIZATIONS_HELP_1()}.</Typography>
</Box>
<Box display="flex" flexWrap="wrap" alignItems="center" gap={2}>
{rename ? (
<TextField
name="device"
label={LL.EMS_DEVICE()}
fullWidth
variant="outlined"
value={selectedDeviceName}
onChange={(e) => setSelectedDeviceName(e.target.value)}
margin="normal"
/>
) : (
<TextField
name="device"
label={LL.EMS_DEVICE()}
variant="outlined"
value={selectedDevice}
disabled={numChanges !== 0}
onChange={(e) => setSelectedDevice(parseInt(e.target.value))}
margin="normal"
style={{ minWidth: '50%' }}
select
>
<MenuItem disabled key={-1} value={-1}>
{LL.SELECT_DEVICE()}...
</MenuItem>
{devices.devices.map(
(device: Device) =>
device.id < 90 && (
<MenuItem key={device.id} value={device.id}>
{device.n}&nbsp;({device.tn})
</MenuItem>
)
)}
</TextField>
)}
{selectedDevice !== -1 &&
(rename ? (
<>
<Button
startIcon={<CancelIcon />}
variant="outlined"
color="secondary"
onClick={() => setRename(false)}
>
{LL.CANCEL()}
</Button>
<Button
startIcon={<SaveIcon />}
variant="outlined"
onClick={() => renameDevice()}
>
{LL.RENAME()}
</Button>
</>
) : (
<Button
startIcon={<EditIcon />}
variant="outlined"
onClick={() => setRename(true)}
>
{LL.RENAME()}
</Button>
))}
</Box>
<TextField
name="device"
label={LL.EMS_DEVICE()}
variant="outlined"
fullWidth
value={selectedDevice}
disabled={numChanges !== 0}
onChange={(e) => setSelectedDevice(parseInt(e.target.value))}
margin="normal"
select
>
<MenuItem disabled key={-1} value={-1}>
{LL.SELECT_DEVICE()}...
</MenuItem>
{devices.devices.map((device: DeviceShort) => (
<MenuItem key={device.i} value={device.i}>
{device.s}
</MenuItem>
))}
</TextField>
</>
);
@@ -370,15 +519,27 @@ const SettingsCustomization: FC = () => {
<>
<Box color="warning.main">
<Typography variant="body2" mt={1}>
<OptionIcon type="favorite" isSet={true} />={LL.CUSTOMIZATIONS_HELP_2()}&nbsp;&nbsp;
<OptionIcon type="readonly" isSet={true} />={LL.CUSTOMIZATIONS_HELP_3()}&nbsp;&nbsp;
<OptionIcon type="api_mqtt_exclude" isSet={true} />={LL.CUSTOMIZATIONS_HELP_4()}&nbsp;&nbsp;
<OptionIcon type="web_exclude" isSet={true} />={LL.CUSTOMIZATIONS_HELP_5()}&nbsp;&nbsp;
<OptionIcon type="favorite" isSet={true} />={LL.CUSTOMIZATIONS_HELP_2()}
&nbsp;&nbsp;
<OptionIcon type="readonly" isSet={true} />={LL.CUSTOMIZATIONS_HELP_3()}
&nbsp;&nbsp;
<OptionIcon type="api_mqtt_exclude" isSet={true} />=
{LL.CUSTOMIZATIONS_HELP_4()}&nbsp;&nbsp;
<OptionIcon type="web_exclude" isSet={true} />=
{LL.CUSTOMIZATIONS_HELP_5()}&nbsp;&nbsp;
<OptionIcon type="deleted" isSet={true} />={LL.CUSTOMIZATIONS_HELP_6()}
</Typography>
</Box>
<Grid container mb={1} mt={0} spacing={1} direction="row" justifyContent="flex-start" alignItems="center">
<Grid item xs={2}>
<Grid
container
mb={1}
mt={0}
spacing={2}
direction="row"
justifyContent="flex-start"
alignItems="center"
>
<Grid>
<TextField
size="small"
variant="outlined"
@@ -386,21 +547,23 @@ const SettingsCustomization: FC = () => {
onChange={(event) => {
setSearch(event.target.value);
}}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<SearchIcon color="primary" sx={{ fontSize: 16 }} />
</InputAdornment>
)
slotProps={{
input: {
startAdornment: (
<InputAdornment position="start">
<SearchIcon color="primary" sx={{ fontSize: 16 }} />
</InputAdornment>
)
}
}}
/>
</Grid>
<Grid item>
<Grid>
<ToggleButtonGroup
size="small"
color="secondary"
value={getMaskString(selectedFilters)}
onChange={(event, mask) => {
onChange={(_, mask: string[]) => {
setSelectedFilters(getMaskNumber(mask));
}}
>
@@ -421,7 +584,7 @@ const SettingsCustomization: FC = () => {
</ToggleButton>
</ToggleButtonGroup>
</Grid>
<Grid item>
<Grid>
<Button
size="small"
sx={{ fontSize: 10 }}
@@ -434,7 +597,7 @@ const SettingsCustomization: FC = () => {
<OptionIcon type="web_exclude" isSet={false} />
</Button>
</Grid>
<Grid item>
<Grid>
<Button
size="small"
sx={{ fontSize: 10 }}
@@ -447,14 +610,19 @@ const SettingsCustomization: FC = () => {
<OptionIcon type="web_exclude" isSet={true} />
</Button>
</Grid>
<Grid item>
<Typography variant="subtitle2" color="primary">
{LL.SHOWING()}&nbsp;{shown_data.length}/{deviceEntities.length}&nbsp;{LL.ENTITIES(deviceEntities.length)}
<Grid>
<Typography variant="subtitle2" color="grey">
{LL.SHOWING()}&nbsp;{shown_data.length}/{deviceEntities.length}
&nbsp;{LL.ENTITIES(deviceEntities.length)}
</Typography>
</Grid>
</Grid>
<Table data={{ nodes: shown_data }} theme={entities_theme} layout={{ custom: true }}>
{(tableList: any) => (
<Table
data={{ nodes: shown_data }}
theme={entities_theme}
layout={{ custom: true }}
>
{(tableList: DeviceEntity[]) => (
<>
<Header>
<HeaderRow>
@@ -473,13 +641,20 @@ const SettingsCustomization: FC = () => {
</Cell>
<Cell>
{formatName(de, false)}&nbsp;(
<Link target="_blank" href={APIURL + selectedDeviceName + '/' + de.id}>
<Link
target="_blank"
href={APIURL + selectedDeviceTypeNameURL + '/' + de.id}
>
{de.id}
</Link>
)
</Cell>
<Cell>{!(de.m & DeviceEntityMask.DV_READONLY) && formatValue(de.mi)}</Cell>
<Cell>{!(de.m & DeviceEntityMask.DV_READONLY) && formatValue(de.ma)}</Cell>
<Cell>
{!(de.m & DeviceEntityMask.DV_READONLY) && formatValue(de.mi)}
</Cell>
<Cell>
{!(de.m & DeviceEntityMask.DV_READONLY) && formatValue(de.ma)}
</Cell>
<Cell>{formatValue(de.v)}</Cell>
</Row>
))}
@@ -492,14 +667,28 @@ const SettingsCustomization: FC = () => {
};
const renderResetDialog = () => (
<Dialog sx={dialogStyle} open={confirmReset} onClose={() => setConfirmReset(false)}>
<Dialog
sx={dialogStyle}
open={confirmReset}
onClose={() => setConfirmReset(false)}
>
<DialogTitle>{LL.RESET(1)}</DialogTitle>
<DialogContent dividers>{LL.CUSTOMIZATIONS_RESET()}</DialogContent>
<DialogActions>
<Button startIcon={<CancelIcon />} variant="outlined" onClick={() => setConfirmReset(false)} color="secondary">
<Button
startIcon={<CancelIcon />}
variant="outlined"
onClick={() => setConfirmReset(false)}
color="secondary"
>
{LL.CANCEL()}
</Button>
<Button startIcon={<SettingsBackupRestoreIcon />} variant="outlined" onClick={resetCustomization} color="error">
<Button
startIcon={<SettingsBackupRestoreIcon />}
variant="outlined"
onClick={resetCustomization}
color="error"
>
{LL.RESET(0)}
</Button>
</DialogActions>
@@ -508,19 +697,20 @@ const SettingsCustomization: FC = () => {
const renderContent = () => (
<>
<Typography sx={{ pt: 2, pb: 2 }} variant="h6" color="primary">
{LL.DEVICE_ENTITIES()}
</Typography>
{devices && renderDeviceList()}
{deviceEntities && renderDeviceData()}
{restartNeeded && (
{selectedDevice !== -1 && !rename && renderDeviceData()}
{restartNeeded ? (
<MessageBox my={2} level="warning" message={LL.RESTART_TEXT(0)}>
<Button startIcon={<PowerSettingsNewIcon />} variant="contained" color="error" onClick={restart}>
<Button
startIcon={<PowerSettingsNewIcon />}
variant="contained"
color="error"
onClick={doRestart}
>
{LL.RESTART()}
</Button>
</MessageBox>
)}
{!restartNeeded && (
) : (
<Box display="flex" flexWrap="wrap">
<Box flexGrow={1}>
{numChanges !== 0 && (
@@ -529,7 +719,7 @@ const SettingsCustomization: FC = () => {
startIcon={<CancelIcon />}
variant="outlined"
color="secondary"
onClick={() => devices && readDeviceEntities(selectedDevice)}
onClick={() => devices && sendDeviceEntities(selectedDevice)}
>
{LL.CANCEL()}
</Button>
@@ -544,16 +734,18 @@ const SettingsCustomization: FC = () => {
</ButtonRow>
)}
</Box>
<ButtonRow>
<Button
startIcon={<SettingsBackupRestoreIcon />}
variant="outlined"
color="error"
onClick={() => setConfirmReset(true)}
>
{LL.RESET(0)}
</Button>
</ButtonRow>
{!rename && (
<ButtonRow mt={1}>
<Button
startIcon={<SettingsBackupRestoreIcon />}
variant="outlined"
color="error"
onClick={() => setConfirmReset(true)}
>
{LL.RESET(0)}
</Button>
</ButtonRow>
)}
</Box>
)}
{renderResetDialog()}
@@ -561,11 +753,11 @@ const SettingsCustomization: FC = () => {
);
return (
<SectionContent title={LL.CUSTOMIZATIONS()} titleGutter>
<SectionContent>
{blocker ? <BlockNavigation blocker={blocker} /> : null}
{restarting ? <RestartMonitor /> : renderContent()}
{restarting ? <SystemMonitor /> : renderContent()}
{selectedDeviceEntity && (
<SettingsCustomizationDialog
<SettingsCustomizationsDialog
open={dialogOpen}
onClose={onDialogClose}
onSave={onDialogSave}
@@ -576,4 +768,4 @@ const SettingsCustomization: FC = () => {
);
};
export default SettingsCustomization;
export default Customizations;

View File

@@ -1,7 +1,8 @@
import { useEffect, useState } from 'react';
import CancelIcon from '@mui/icons-material/Cancel';
import CloseIcon from '@mui/icons-material/Close';
import DoneIcon from '@mui/icons-material/Done';
import {
Box,
Button,
@@ -13,25 +14,28 @@ import {
TextField,
Typography
} from '@mui/material';
import { useEffect, useState } from 'react';
import { dialogStyle } from 'CustomTheme';
import { useI18nContext } from 'i18n/i18n-react';
import { numberValue, updateValue } from 'utils';
import EntityMaskToggle from './EntityMaskToggle';
import { DeviceEntityMask } from './types';
import type { DeviceEntity } from './types';
import { dialogStyle } from 'CustomTheme';
import { useI18nContext } from 'i18n/i18n-react';
import { updateValue } from 'utils';
type SettingsCustomizationDialogProps = {
interface SettingsCustomizationsDialogProps {
open: boolean;
onClose: () => void;
onSave: (di: DeviceEntity) => void;
selectedItem: DeviceEntity;
};
}
const SettingsCustomizationDialog = ({ open, onClose, onSave, selectedItem }: SettingsCustomizationDialogProps) => {
const CustomizationsDialog = ({
open,
onClose,
onSave,
selectedItem
}: SettingsCustomizationsDialogProps) => {
const { LL } = useI18nContext();
const [editItem, setEditItem] = useState<DeviceEntity>(selectedItem);
const [error, setError] = useState<boolean>(false);
@@ -39,7 +43,9 @@ const SettingsCustomizationDialog = ({ open, onClose, onSave, selectedItem }: Se
const updateFormValue = updateValue(setEditItem);
const isWriteableNumber =
typeof editItem.v === 'number' && editItem.w && !(editItem.m & DeviceEntityMask.DV_READONLY);
typeof editItem.v === 'number' &&
editItem.w &&
!(editItem.m & DeviceEntityMask.DV_READONLY);
useEffect(() => {
if (open) {
@@ -48,12 +54,22 @@ const SettingsCustomizationDialog = ({ open, onClose, onSave, selectedItem }: Se
}
}, [open, selectedItem]);
const close = () => {
onClose();
const handleClose = (
_event: React.SyntheticEvent,
reason: 'backdropClick' | 'escapeKeyDown'
) => {
if (reason !== 'backdropClick') {
onClose();
}
};
const save = () => {
if (isWriteableNumber && editItem.mi && editItem.ma && editItem.mi > editItem?.ma) {
if (
isWriteableNumber &&
editItem.mi &&
editItem.ma &&
editItem.mi > editItem?.ma
) {
setError(true);
} else {
onSave(editItem);
@@ -65,10 +81,10 @@ const SettingsCustomizationDialog = ({ open, onClose, onSave, selectedItem }: Se
};
return (
<Dialog sx={dialogStyle} open={open} onClose={close}>
<Dialog sx={dialogStyle} open={open} onClose={handleClose}>
<DialogTitle>{LL.EDIT() + ' ' + LL.ENTITY()}</DialogTitle>
<DialogContent dividers>
<Grid container direction="row">
<Grid container>
<Typography variant="body2" color="warning.main">
{LL.ID_OF(LL.ENTITY())}:&nbsp;
</Typography>
@@ -98,35 +114,34 @@ const SettingsCustomizationDialog = ({ open, onClose, onSave, selectedItem }: Se
<Box mt={1} mb={2}>
<EntityMaskToggle onUpdate={updateDeviceEntity} de={editItem} />
</Box>
<Grid container spacing={1}>
<Grid item>
<Grid container spacing={2}>
<Grid>
<TextField
name="cn"
label={LL.NEW_NAME_OF(LL.ENTITY())}
value={editItem.cn}
autoFocus
sx={{ width: '30ch' }}
onChange={updateFormValue}
/>
</Grid>
{isWriteableNumber && (
<>
<Grid item>
<Grid>
<TextField
name="mi"
label={LL.MIN()}
value={editItem.mi}
sx={{ width: '8ch' }}
value={numberValue(editItem.mi)}
sx={{ width: '11ch' }}
type="number"
onChange={updateFormValue}
/>
</Grid>
<Grid item>
<Grid>
<TextField
name="ma"
label={LL.MAX()}
value={editItem.ma}
sx={{ width: '8ch' }}
value={numberValue(editItem.ma)}
sx={{ width: '11ch' }}
type="number"
onChange={updateFormValue}
/>
@@ -141,10 +156,20 @@ const SettingsCustomizationDialog = ({ open, onClose, onSave, selectedItem }: Se
)}
</DialogContent>
<DialogActions>
<Button startIcon={<CancelIcon />} variant="outlined" onClick={close} color="secondary">
<Button
startIcon={<CancelIcon />}
variant="outlined"
onClick={onClose}
color="secondary"
>
{LL.CANCEL()}
</Button>
<Button startIcon={<DoneIcon />} variant="outlined" onClick={save} color="primary">
<Button
startIcon={<DoneIcon />}
variant="outlined"
onClick={save}
color="primary"
>
{LL.UPDATE()}
</Button>
</DialogActions>
@@ -152,4 +177,4 @@ const SettingsCustomizationDialog = ({ open, onClose, onSave, selectedItem }: Se
);
};
export default SettingsCustomizationDialog;
export default CustomizationsDialog;

View File

@@ -0,0 +1,415 @@
import { memo, useCallback, useContext, useEffect, useMemo, useState } from 'react';
import { IconContext } from 'react-icons/lib';
import { Link } from 'react-router';
import { toast } from 'react-toastify';
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
import EditIcon from '@mui/icons-material/Edit';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
import UnfoldLessIcon from '@mui/icons-material/UnfoldLess';
import UnfoldMoreIcon from '@mui/icons-material/UnfoldMore';
import {
Box,
IconButton,
ToggleButton,
ToggleButtonGroup,
Tooltip,
Typography
} from '@mui/material';
import { Body, Cell, Row, Table } from '@table-library/react-table-library/table';
import { useTheme } from '@table-library/react-table-library/theme';
import { CellTree, useTree } from '@table-library/react-table-library/tree';
import { useRequest } from 'alova/client';
import {
ButtonTooltip,
FormLoader,
MessageBox,
SectionContent,
useLayoutTitle
} from 'components';
import { AuthenticatedContext } from 'contexts/authentication';
import { useI18nContext } from 'i18n/i18n-react';
import { useInterval, usePersistState } from 'utils';
import { readDashboard, writeDeviceValue } from '../../api/app';
import DeviceIcon from './DeviceIcon';
import DevicesDialog from './DevicesDialog';
import { formatValue } from './deviceValue';
import {
type DashboardItem,
DeviceEntityMask,
DeviceType,
type DeviceValue
} from './types';
import { deviceValueItemValidation } from './validators';
const Dashboard = memo(() => {
const { LL } = useI18nContext();
const { me } = useContext(AuthenticatedContext);
useLayoutTitle(LL.DASHBOARD());
const [showAll, setShowAll] = usePersistState(true, 'showAll');
const [deviceValueDialogOpen, setDeviceValueDialogOpen] = useState<boolean>(false);
const [parentNodes, setParentNodes] = useState<number>(0);
const [selectedDashboardItem, setSelectedDashboardItem] =
useState<DashboardItem>();
const {
data,
send: fetchDashboard,
error
} = useRequest(readDashboard, {
initialData: { connected: true, nodes: [] }
}).onSuccess((event) => {
if (event.data.nodes.length !== parentNodes) {
setParentNodes(event.data.nodes.length); // count number of parents/devices
}
});
const { loading: submitting, send: sendDeviceValue } = useRequest(
(data: { id: number; c: string; v: unknown }) => writeDeviceValue(data),
{
immediate: false
}
);
const deviceValueDialogSave = useCallback(
async (devicevalue: DeviceValue) => {
if (!selectedDashboardItem) {
return;
}
const id = selectedDashboardItem.parentNode.id; // this is the parent ID
await sendDeviceValue({ id, c: devicevalue.c ?? '', v: devicevalue.v })
.then(() => {
toast.success(LL.WRITE_CMD_SENT());
})
.catch((error: Error) => {
toast.error(error.message);
})
.finally(() => {
setDeviceValueDialogOpen(false);
setSelectedDashboardItem(undefined);
});
},
[selectedDashboardItem, sendDeviceValue, LL]
);
const dashboard_theme = useMemo(
() =>
useTheme({
Table: `
--data-table-library_grid-template-columns: minmax(80px, auto) 120px 32px;
`,
BaseRow: `
font-size: 14px;
.td {
height: 28px;
}
`,
Row: `
cursor: pointer;
background-color: #1e1e1e;
&:nth-of-type(odd) .td {
background-color: #303030;
},
&:hover .td {
background-color: #177ac9;
},
`,
BaseCell: `
&:nth-of-type(2) {
text-align: right;
}
&:nth-of-type(3) {
text-align: right;
}
`
}),
[]
);
const tree = useTree(
{ nodes: data.nodes },
{
onChange: () => {} // not used but needed
},
{
treeIcon: {
margin: '4px',
iconDefault: null,
iconRight: (
<ChevronRightIcon
sx={{ fontSize: 16, verticalAlign: 'middle' }}
color="info"
/>
),
iconDown: (
<ExpandMoreIcon
sx={{ fontSize: 16, verticalAlign: 'middle' }}
color="info"
/>
)
},
indentation: 45
}
);
useInterval(() => {
if (!deviceValueDialogOpen) {
void fetchDashboard();
}
});
const nodeIds = useMemo(
() => data.nodes.map((item: DashboardItem) => item.id),
[data.nodes]
);
useEffect(() => {
showAll
? tree.fns.onAddAll(nodeIds) // expand tree
: tree.fns.onRemoveAll(); // collapse tree
}, [parentNodes]);
const showType = useCallback(
(n?: string, t?: number) => {
// if we have a name show it
if (n) {
return n;
}
if (t) {
// otherwise pick translation based on type
switch (t) {
case DeviceType.CUSTOM:
return LL.CUSTOM_ENTITIES(0);
case DeviceType.ANALOGSENSOR:
return LL.ANALOG_SENSORS();
case DeviceType.TEMPERATURESENSOR:
return LL.TEMP_SENSORS();
case DeviceType.SCHEDULER:
return LL.SCHEDULER();
default:
break;
}
}
return '';
},
[LL]
);
const showName = useCallback(
(di: DashboardItem) => {
if (di.id < 100) {
// if its a device (parent node) and has entities
if (di.nodes?.length) {
return (
<span style={{ fontSize: '15px' }}>
<DeviceIcon type_id={di.t ?? 0} />
&nbsp;&nbsp;{showType(di.n, di.t)}
<span style={{ color: 'lightblue' }}>&nbsp;({di.nodes?.length})</span>
</span>
);
}
}
if (di.dv) {
return <span>{di.dv.id.slice(2)}</span>;
}
return null;
},
[showType]
);
const hasMask = useCallback(
(id: string, mask: number) => (parseInt(id.slice(0, 2), 16) & mask) === mask,
[]
);
const editDashboardValue = useCallback(
(di: DashboardItem) => {
if (me.admin && di.dv?.c) {
setSelectedDashboardItem(di);
setDeviceValueDialogOpen(true);
}
},
[me.admin]
);
const handleShowAll = (
_event: React.MouseEvent<HTMLElement>,
toggle: boolean | null
) => {
if (toggle !== null) {
tree.fns.onToggleAll({});
setShowAll(toggle);
}
};
const hasFavEntities = useMemo(
() => data.nodes.filter((item: DashboardItem) => item.id <= 90).length,
[data.nodes]
);
const renderContent = () => {
if (!data) {
return (
<FormLoader onRetry={fetchDashboard} errorMessage={error?.message || ''} />
);
}
return (
<>
{!data.connected && (
<MessageBox mb={2} level="error" message={LL.EMS_BUS_WARNING()} />
)}
{data.connected && data.nodes.length > 0 && !hasFavEntities && (
<MessageBox mb={2} level="warning">
<Typography>
{LL.NO_DATA_1()}&nbsp;
<Link to="/customizations" style={{ color: 'white' }}>
{LL.CUSTOMIZATIONS()}
</Link>
&nbsp;{LL.NO_DATA_2()}&nbsp;
{LL.NO_DATA_3()}&nbsp;
<Link to="/devices" style={{ color: 'white' }}>
{LL.DEVICES()}
</Link>
.
</Typography>
</MessageBox>
)}
{data.nodes.length > 0 && (
<>
<Box
display="flex"
justifyContent="flex-end"
flexWrap="nowrap"
whiteSpace="nowrap"
>
<ToggleButtonGroup
size="small"
color="primary"
value={showAll}
exclusive
onChange={handleShowAll}
>
<ButtonTooltip title={LL.ALLVALUES()}>
<ToggleButton value={true}>
<UnfoldMoreIcon sx={{ fontSize: 18 }} />
</ToggleButton>
</ButtonTooltip>
<ButtonTooltip title={LL.COMPACT()}>
<ToggleButton value={false}>
<UnfoldLessIcon sx={{ fontSize: 18 }} />
</ToggleButton>
</ButtonTooltip>
</ToggleButtonGroup>
<Tooltip title={LL.DASHBOARD_1()}>
<HelpOutlineIcon
sx={{
ml: 1,
mt: 1,
fontSize: 20,
verticalAlign: 'middle'
}}
color="primary"
/>
</Tooltip>
</Box>
<Box mt={1} justifyContent="center" flexDirection="column">
<IconContext.Provider
value={{
color: 'lightblue',
size: '18',
style: { verticalAlign: 'middle' }
}}
>
<Table
data={{ nodes: data.nodes }}
theme={dashboard_theme}
layout={{ custom: true }}
tree={tree}
>
{(tableList: DashboardItem[]) => (
<Body>
{tableList.map((di: DashboardItem) => (
<Row
key={di.id}
item={di}
onClick={() => editDashboardValue(di)}
>
{di.id > 99 ? (
<>
<Cell>{showName(di)}</Cell>
<Cell>
<ButtonTooltip
title={formatValue(LL, di.dv?.v, di.dv?.u)}
>
<span>{formatValue(LL, di.dv?.v, di.dv?.u)}</span>
</ButtonTooltip>
</Cell>
<Cell>
{me.admin &&
di.dv?.c &&
!hasMask(
di.dv.id,
DeviceEntityMask.DV_READONLY
) && (
<IconButton
size="small"
onClick={() => editDashboardValue(di)}
>
<EditIcon
color="primary"
sx={{ fontSize: 16 }}
/>
</IconButton>
)}
</Cell>
</>
) : (
<>
<CellTree item={di}>{showName(di)}</CellTree>
<Cell />
<Cell />
</>
)}
</Row>
))}
</Body>
)}
</Table>
</IconContext.Provider>
</Box>
</>
)}
</>
);
};
return (
<SectionContent>
{renderContent()}
{selectedDashboardItem && selectedDashboardItem.dv && (
<DevicesDialog
open={deviceValueDialogOpen}
onClose={() => setDeviceValueDialogOpen(false)}
onSave={deviceValueDialogSave}
selectedItem={selectedDashboardItem.dv}
writeable={true}
validator={deviceValueItemValidation(selectedDashboardItem.dv)}
progress={submitting}
/>
)}
</SectionContent>
);
});
export default Dashboard;

View File

@@ -0,0 +1,53 @@
import { AiOutlineAlert, AiOutlineControl, AiOutlineGateway } from 'react-icons/ai';
import { CgSmartHomeBoiler } from 'react-icons/cg';
import { FaSolarPanel } from 'react-icons/fa';
import { GiHeatHaze, GiTap } from 'react-icons/gi';
import { MdPlaylistAdd } from 'react-icons/md';
import { MdMoreTime } from 'react-icons/md';
import {
MdOutlineDevices,
MdOutlinePool,
MdOutlineSensors,
MdThermostatAuto
} from 'react-icons/md';
import { PiFan, PiGauge } from 'react-icons/pi';
import { TiFlowSwitch, TiThermometer } from 'react-icons/ti';
import { VscVmConnect } from 'react-icons/vsc';
import type { SvgIconProps } from '@mui/material';
import { DeviceType } from './types';
const deviceIconLookup: {
[key in DeviceType]: React.ComponentType<SvgIconProps> | undefined;
} = {
[DeviceType.TEMPERATURESENSOR]: TiThermometer,
[DeviceType.ANALOGSENSOR]: PiGauge,
[DeviceType.BOILER]: CgSmartHomeBoiler,
[DeviceType.HEATSOURCE]: CgSmartHomeBoiler,
[DeviceType.THERMOSTAT]: MdThermostatAuto,
[DeviceType.MIXER]: AiOutlineControl,
[DeviceType.SOLAR]: FaSolarPanel,
[DeviceType.HEATPUMP]: GiHeatHaze,
[DeviceType.GATEWAY]: AiOutlineGateway,
[DeviceType.SWITCH]: TiFlowSwitch,
[DeviceType.CONTROLLER]: VscVmConnect,
[DeviceType.CONNECT]: VscVmConnect,
[DeviceType.ALERT]: AiOutlineAlert,
[DeviceType.EXTENSION]: MdOutlineDevices,
[DeviceType.WATER]: GiTap,
[DeviceType.POOL]: MdOutlinePool,
[DeviceType.CUSTOM]: MdPlaylistAdd,
[DeviceType.UNKNOWN]: MdOutlineSensors,
[DeviceType.SYSTEM]: undefined,
[DeviceType.SCHEDULER]: MdMoreTime,
[DeviceType.GENERIC]: MdOutlineSensors,
[DeviceType.VENTILATION]: PiFan
};
const DeviceIcon = ({ type_id }: { type_id: DeviceType }) => {
const Icon = deviceIconLookup[type_id];
return Icon ? <Icon /> : null;
};
export default DeviceIcon;

View File

@@ -0,0 +1,833 @@
import {
memo,
useCallback,
useContext,
useEffect,
useLayoutEffect,
useMemo,
useState
} from 'react';
import { IconContext } from 'react-icons';
import { useNavigate } from 'react-router';
import { toast } from 'react-toastify';
import CommentsDisabledOutlinedIcon from '@mui/icons-material/CommentsDisabledOutlined';
import ConstructionIcon from '@mui/icons-material/Construction';
import EditIcon from '@mui/icons-material/Edit';
import EditOffOutlinedIcon from '@mui/icons-material/EditOffOutlined';
import DownloadIcon from '@mui/icons-material/GetApp';
import HighlightOffIcon from '@mui/icons-material/HighlightOff';
import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';
import KeyboardArrowDownOutlinedIcon from '@mui/icons-material/KeyboardArrowDownOutlined';
import KeyboardArrowUpOutlinedIcon from '@mui/icons-material/KeyboardArrowUpOutlined';
import PlayArrowIcon from '@mui/icons-material/PlayArrow';
import SearchIcon from '@mui/icons-material/Search';
import StarIcon from '@mui/icons-material/Star';
import StarBorderOutlinedIcon from '@mui/icons-material/StarBorderOutlined';
import UnfoldMoreOutlinedIcon from '@mui/icons-material/UnfoldMoreOutlined';
import {
Box,
Button,
CircularProgress,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
Grid,
IconButton,
InputAdornment,
List,
ListItem,
ListItemText,
TextField,
ToggleButton,
Typography
} from '@mui/material';
import { useRowSelect } from '@table-library/react-table-library/select';
import { SortToggleType, useSort } from '@table-library/react-table-library/sort';
import {
Body,
Cell,
Header,
HeaderCell,
HeaderRow,
Row,
Table
} from '@table-library/react-table-library/table';
import { useTheme } from '@table-library/react-table-library/theme';
import type { Action, State } from '@table-library/react-table-library/types/common';
import { dialogStyle } from 'CustomTheme';
import { useRequest } from 'alova/client';
import {
ButtonTooltip,
MessageBox,
SectionContent,
useLayoutTitle
} from 'components';
import { AuthenticatedContext } from 'contexts/authentication';
import { useI18nContext } from 'i18n/i18n-react';
import { useInterval } from 'utils';
import { readCoreData, readDeviceData, writeDeviceValue } from '../../api/app';
import DeviceIcon from './DeviceIcon';
import DevicesDialog from './DevicesDialog';
import { formatValue } from './deviceValue';
import { DeviceEntityMask, DeviceType, DeviceValueUOM_s } from './types';
import type { Device, DeviceValue } from './types';
import { deviceValueItemValidation } from './validators';
const Devices = memo(() => {
const { LL } = useI18nContext();
const { me } = useContext(AuthenticatedContext);
const [size, setSize] = useState([0, 0]);
const [selectedDeviceValue, setSelectedDeviceValue] = useState<DeviceValue>();
const [onlyFav, setOnlyFav] = useState(false);
const [deviceValueDialogOpen, setDeviceValueDialogOpen] = useState(false);
const [showDeviceInfo, setShowDeviceInfo] = useState(false);
const [selectedDevice, setSelectedDevice] = useState<number>();
const [search, setSearch] = useState('');
const navigate = useNavigate();
useLayoutTitle(LL.DEVICES());
const { data: coreData, send: sendCoreData } = useRequest(() => readCoreData(), {
initialData: {
connected: true,
devices: []
}
});
const { data: deviceData, send: sendDeviceData } = useRequest(
(id: number) => readDeviceData(id),
{
initialData: {
nodes: []
},
immediate: false
}
);
const { loading: submitting, send: sendDeviceValue } = useRequest(
(data: { id: number; c: string; v: unknown }) => writeDeviceValue(data),
{
immediate: false
}
);
useLayoutEffect(() => {
function updateSize() {
setSize([window.innerWidth, window.innerHeight]);
}
window.addEventListener('resize', updateSize);
updateSize();
return () => window.removeEventListener('resize', updateSize);
}, []);
const leftOffset = () => {
const devicesWindow = document.getElementById('devices-window');
if (!devicesWindow) {
return 0;
}
const clientRect = devicesWindow.getBoundingClientRect();
const left = clientRect.left;
const right = clientRect.right;
if (!left || !right) {
return 0;
}
return left + (right - left < 400 ? 0 : 200);
};
const common_theme = useMemo(
() =>
useTheme({
BaseRow: `
font-size: 14px;
`,
HeaderRow: `
text-transform: uppercase;
background-color: black;
color: #90CAF9;
.th {
border-bottom: 1px solid #565656;
}
`,
Row: `
cursor: pointer;
background-color: #1E1E1E;
.td {
padding: 8px;
}
&.tr.tr-body.row-select.row-select-single-selected {
background-color: #177ac9;
}
`
}),
[]
);
const device_theme = useMemo(
() =>
useTheme([
common_theme,
{
BaseRow: `
font-size: 15px;
.td {
height: 28px;
}
`,
Table: `
--data-table-library_grid-template-columns: repeat(1, minmax(0, 1fr)) 130px;
`,
HeaderRow: `
.th {
padding: 8px;
`,
Row: `
&:nth-of-type(odd) .td {
background-color: #303030;
},
&:hover .td {
background-color: #177ac9;
},
`
}
]),
[common_theme]
);
const data_theme = useMemo(
() =>
useTheme([
common_theme,
{
Table: `
--data-table-library_grid-template-columns: minmax(200px, auto) minmax(150px, auto) 40px;
height: auto;
max-height: 100%;
overflow-y: scroll;
::-webkit-scrollbar {
display:none;
}
`,
BaseRow: `
.td {
height: 32px;
}
`,
BaseCell: `
&:nth-of-type(1) {
border-left: 1px solid #177ac9;
},
&:nth-of-type(2) {
text-align: right;
},
&:nth-of-type(3) {
border-right: 1px solid #177ac9;
}
`,
HeaderRow: `
.th {
border-top: 1px solid #565656;
}
`,
Row: `
&:nth-of-type(odd) .td {
background-color: #303030;
},
&:hover .td {
background-color: #177ac9;
}
`
}
]),
[common_theme]
);
const getSortIcon = (state: State, sortKey: unknown) => {
if (state.sortKey === sortKey && state.reverse) {
return <KeyboardArrowDownOutlinedIcon />;
}
if (state.sortKey === sortKey && !state.reverse) {
return <KeyboardArrowUpOutlinedIcon />;
}
return <UnfoldMoreOutlinedIcon />;
};
const dv_sort = useSort(
{ nodes: deviceData.nodes },
{},
{
sortIcon: {
iconDefault: <UnfoldMoreOutlinedIcon />,
iconUp: <KeyboardArrowUpOutlinedIcon />,
iconDown: <KeyboardArrowDownOutlinedIcon />
},
sortToggleType: SortToggleType.AlternateWithReset,
sortFns: {
NAME: (array) =>
array.sort((a, b) =>
a.id.toString().slice(2).localeCompare(b.id.toString().slice(2))
),
VALUE: (array) =>
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
array.sort((a, b) => a.v.toString().localeCompare(b.v.toString()))
}
}
);
async function onSelectChange(action: Action, state: State) {
setSelectedDevice(state.id as number);
if (action.type === 'ADD_BY_ID_EXCLUSIVELY') {
await sendDeviceData(state.id as number);
}
}
const device_select = useRowSelect(
{ nodes: coreData.devices },
{
onChange: onSelectChange
}
);
const resetDeviceSelect = () => {
device_select.fns.onRemoveAll();
setSearch('');
};
const escFunction = useCallback(
(event: KeyboardEvent) => {
if (event.key === 'Escape') {
if (device_select) {
device_select.fns.onRemoveAll();
}
}
},
[device_select]
);
useEffect(() => {
document.addEventListener('keydown', escFunction);
return () => {
document.removeEventListener('keydown', escFunction);
};
}, [escFunction]);
const customize = () => {
if (selectedDevice === 99) {
void navigate('/customentities');
} else {
void navigate('/customizations', { state: selectedDevice });
}
};
const escapeCsvCell = (cell: string) => {
if (cell == null) {
return '';
}
const sc = cell.toString().trim();
if (sc === '' || sc === '""') {
return sc;
}
if (
sc.includes('"') ||
sc.includes(';') ||
sc.includes('\n') ||
sc.includes('\r')
) {
return '"' + sc.replace(/"/g, '""') + '"';
}
return sc;
};
const hasMask = useCallback(
(id: string, mask: number) => (parseInt(id.slice(0, 2), 16) & mask) === mask,
[]
);
const handleDownloadCsv = () => {
const deviceIndex = coreData.devices.findIndex(
(d: Device) => d.id === device_select.state.id
);
if (deviceIndex === -1) {
return;
}
const selectedDevice = coreData.devices[deviceIndex];
if (!selectedDevice) {
return;
}
const filename = selectedDevice.tn + '_' + selectedDevice.n;
const columns = [
{
accessor: (dv: DeviceValue) => dv.id.slice(2),
name: LL.ENTITY_NAME(0)
},
{
accessor: (dv: DeviceValue) =>
typeof dv.v === 'number' ? new Intl.NumberFormat().format(dv.v) : dv.v,
name: LL.VALUE(0)
},
{
accessor: (dv: DeviceValue) =>
dv.u !== undefined && DeviceValueUOM_s[dv.u]
? DeviceValueUOM_s[dv.u]?.replace(/[^a-zA-Z0-9]/g, '')
: '',
name: 'UoM'
},
{
accessor: (dv: DeviceValue) =>
dv.c && !hasMask(dv.id, DeviceEntityMask.DV_READONLY) ? 'yes' : 'no',
name: LL.WRITEABLE()
},
{
accessor: (dv: DeviceValue) =>
dv.h
? dv.h
: dv.l
? dv.l.join(' | ')
: dv.m !== undefined && dv.x !== undefined
? dv.m + ', ' + dv.x
: '',
name: 'Range'
}
];
const data = onlyFav
? deviceData.nodes.filter((dv: DeviceValue) =>
hasMask(dv.id, DeviceEntityMask.DV_FAVORITE)
)
: deviceData.nodes;
const csvData = data.reduce(
(csvString: string, rowItem: DeviceValue) =>
csvString +
columns
.map(({ accessor }: { accessor: (dv: DeviceValue) => unknown }) =>
escapeCsvCell(accessor(rowItem) as string)
)
.join(';') +
'\r\n',
columns.map(({ name }: { name: string }) => escapeCsvCell(name)).join(';') +
'\r\n'
);
const downloadBlob = (blob: Blob) => {
const downloadLink = document.createElement('a');
downloadLink.download = filename;
downloadLink.href = window.URL.createObjectURL(blob);
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
};
const device = { ...{ device: coreData.devices[deviceIndex] }, ...deviceData };
downloadBlob(
new Blob([JSON.stringify(device, null, 2)], {
type: 'text;charset:utf-8'
})
);
downloadBlob(new Blob([csvData], { type: 'text/csv;charset:utf-8' }));
};
useInterval(() => {
if (!deviceValueDialogOpen) {
selectedDevice ? void sendDeviceData(selectedDevice) : void sendCoreData();
}
});
const deviceValueDialogSave = async (devicevalue: DeviceValue) => {
const id = Number(device_select.state.id);
await sendDeviceValue({ id, c: devicevalue.c ?? '', v: devicevalue.v })
.then(() => {
toast.success(LL.WRITE_CMD_SENT());
})
.catch((error: Error) => {
toast.error(error.message);
})
.finally(async () => {
setDeviceValueDialogOpen(false);
await sendDeviceData(id);
setSelectedDeviceValue(undefined);
});
};
const renderDeviceDetails = () => {
if (showDeviceInfo) {
const deviceIndex = coreData.devices.findIndex(
(d: Device) => d.id === device_select.state.id
);
if (deviceIndex === -1) {
return null;
}
const deviceDetails = coreData.devices[deviceIndex];
if (!deviceDetails) {
return null;
}
return (
<Dialog
sx={dialogStyle}
open={showDeviceInfo}
onClose={() => setShowDeviceInfo(false)}
>
<DialogTitle>{LL.DEVICE_DETAILS()}</DialogTitle>
<DialogContent dividers>
<List dense={true}>
<ListItem>
<ListItemText primary={LL.TYPE(0)} secondary={deviceDetails.tn} />
</ListItem>
<ListItem>
<ListItemText primary={LL.NAME(0)} secondary={deviceDetails.n} />
</ListItem>
{deviceDetails.t !== DeviceType.CUSTOM && (
<>
<ListItem>
<ListItemText primary={LL.BRAND()} secondary={deviceDetails.b} />
</ListItem>
<ListItem>
<ListItemText
primary={LL.ID_OF(LL.DEVICE())}
secondary={
'0x' +
('00' + deviceDetails.d.toString(16).toUpperCase()).slice(-2)
}
/>
</ListItem>
<ListItem>
<ListItemText
primary={LL.ID_OF(LL.PRODUCT())}
secondary={deviceDetails.p}
/>
</ListItem>
<ListItem>
<ListItemText
primary={LL.VERSION()}
secondary={deviceDetails.v}
/>
</ListItem>
</>
)}
</List>
</DialogContent>
<DialogActions>
<Button
variant="outlined"
onClick={() => setShowDeviceInfo(false)}
color="secondary"
>
{LL.CLOSE()}
</Button>
</DialogActions>
</Dialog>
);
}
return null;
};
const renderCoreData = () => (
<>
<Box justifyContent="center" flexDirection="column">
<IconContext.Provider
value={{
color: 'lightblue',
size: '18',
style: { verticalAlign: 'middle' }
}}
>
{!coreData.connected && (
<MessageBox my={2} level="error" message={LL.EMS_BUS_WARNING()} />
)}
{coreData.connected && (
<Table
data={{ nodes: coreData.devices }}
select={device_select}
theme={device_theme}
layout={{ custom: true }}
>
{(tableList: Device[]) => (
<>
<Header>
<HeaderRow>
<HeaderCell resize>{LL.DESCRIPTION()}</HeaderCell>
<HeaderCell stiff>{LL.TYPE(0)}</HeaderCell>
</HeaderRow>
</Header>
<Body>
{tableList.length === 0 && (
<CircularProgress sx={{ margin: 1 }} size={18} />
)}
{tableList.map((device: Device) => (
<Row key={device.id} item={device}>
<Cell>
<DeviceIcon type_id={device.t} />
&nbsp;&nbsp;
{device.n}
<span style={{ color: 'lightblue' }}>
&nbsp;&nbsp;({device.e})
</span>
</Cell>
<Cell stiff>{device.tn}</Cell>
</Row>
))}
</Body>
</>
)}
</Table>
)}
</IconContext.Provider>
</Box>
</>
);
const deviceValueDialogClose = () => {
setDeviceValueDialogOpen(false);
if (selectedDevice !== undefined) {
void sendDeviceData(selectedDevice);
}
};
const renderDeviceData = () => {
if (!selectedDevice) {
return;
}
const showDeviceValue = useCallback((dv: DeviceValue) => {
setSelectedDeviceValue(dv);
setDeviceValueDialogOpen(true);
}, []);
const renderNameCell = useCallback(
(dv: DeviceValue) => (
<>
{dv.id.slice(2)}&nbsp;
{hasMask(dv.id, DeviceEntityMask.DV_FAVORITE) && (
<StarIcon color="primary" sx={{ fontSize: 12 }} />
)}
{hasMask(dv.id, DeviceEntityMask.DV_READONLY) && (
<EditOffOutlinedIcon color="primary" sx={{ fontSize: 12 }} />
)}
{hasMask(dv.id, DeviceEntityMask.DV_API_MQTT_EXCLUDE) && (
<CommentsDisabledOutlinedIcon color="primary" sx={{ fontSize: 12 }} />
)}
</>
),
[hasMask]
);
const shown_data = useMemo(() => {
if (onlyFav) {
return deviceData.nodes.filter(
(dv: DeviceValue) =>
hasMask(dv.id, DeviceEntityMask.DV_FAVORITE) &&
dv.id.slice(2).toLowerCase().includes(search.toLowerCase())
);
}
return deviceData.nodes.filter((dv: DeviceValue) =>
dv.id.slice(2).toLowerCase().includes(search.toLowerCase())
);
}, [deviceData.nodes, onlyFav, search]);
const deviceIndex = coreData.devices.findIndex(
(d: Device) => d.id === device_select.state.id
);
if (deviceIndex === -1) {
return;
}
const deviceInfo = coreData.devices[deviceIndex];
if (!deviceInfo) {
return;
}
const [, height] = size;
return (
<Box
sx={{
backgroundColor: 'black',
position: 'absolute',
left: () => leftOffset(),
right: 0,
bottom: 0,
top: 64,
zIndex: 'modal',
maxHeight: () => (height || 0) - 126,
border: '1px solid #177ac9'
}}
>
<Box sx={{ p: 1 }}>
<Grid container justifyContent="space-between">
<Typography noWrap variant="subtitle1" color="warning.main">
{deviceInfo.n}&nbsp;(
{deviceInfo.tn})
</Typography>
<Grid justifyContent="flex-end">
<ButtonTooltip title={LL.CLOSE()}>
<IconButton onClick={resetDeviceSelect}>
<HighlightOffIcon color="primary" sx={{ fontSize: 18 }} />
</IconButton>
</ButtonTooltip>
</Grid>
</Grid>
<TextField
size="small"
variant="outlined"
sx={{ width: '22ch' }}
placeholder={LL.SEARCH()}
onChange={(event) => {
setSearch(event.target.value);
}}
slotProps={{
input: {
startAdornment: (
<InputAdornment position="start">
<SearchIcon color="primary" sx={{ fontSize: 16 }} />
</InputAdornment>
)
}
}}
/>
<ButtonTooltip title={LL.DEVICE_DETAILS()}>
<IconButton onClick={() => setShowDeviceInfo(true)}>
<InfoOutlinedIcon color="primary" sx={{ fontSize: 18 }} />
</IconButton>
</ButtonTooltip>
{me.admin && (
<ButtonTooltip title={LL.CUSTOMIZATIONS()}>
<IconButton onClick={customize}>
<ConstructionIcon color="primary" sx={{ fontSize: 18 }} />
</IconButton>
</ButtonTooltip>
)}
<ButtonTooltip title={LL.EXPORT()}>
<IconButton onClick={handleDownloadCsv}>
<DownloadIcon color="primary" sx={{ fontSize: 18 }} />
</IconButton>
</ButtonTooltip>
<ButtonTooltip title={LL.FAVORITES()}>
<ToggleButton
value="1"
size="small"
selected={onlyFav}
onChange={() => {
setOnlyFav(!onlyFav);
}}
>
{onlyFav ? (
<StarIcon color="primary" sx={{ fontSize: 18 }} />
) : (
<StarBorderOutlinedIcon color="primary" sx={{ fontSize: 18 }} />
)}{' '}
</ToggleButton>
</ButtonTooltip>
<span style={{ color: 'grey', fontSize: '12px' }}>
&nbsp;
{LL.SHOWING() +
' ' +
shown_data.length +
'/' +
deviceInfo.e +
' ' +
LL.ENTITIES(shown_data.length)}
</span>
</Box>
<Table
data={{ nodes: shown_data }}
theme={data_theme}
sort={dv_sort}
layout={{ custom: true, fixedHeader: true }}
>
{(tableList: DeviceValue[]) => (
<>
<Header>
<HeaderRow>
<HeaderCell resize>
<Button
fullWidth
style={{ fontSize: '14px', justifyContent: 'flex-start' }}
endIcon={getSortIcon(dv_sort.state, 'NAME')}
onClick={() => dv_sort.fns.onToggleSort({ sortKey: 'NAME' })}
>
{LL.ENTITY_NAME(0)}
</Button>
</HeaderCell>
<HeaderCell resize>
<Button
fullWidth
style={{ fontSize: '14px', justifyContent: 'flex-end' }}
endIcon={getSortIcon(dv_sort.state, 'VALUE')}
onClick={() => dv_sort.fns.onToggleSort({ sortKey: 'VALUE' })}
>
{LL.VALUE(0)}
</Button>
</HeaderCell>
<HeaderCell stiff />
</HeaderRow>
</Header>
<Body>
{tableList.map((dv: DeviceValue) => (
<Row key={dv.id} item={dv} onClick={() => showDeviceValue(dv)}>
<Cell>{renderNameCell(dv)}</Cell>
<Cell>{formatValue(LL, dv.v, dv.u)}</Cell>
<Cell stiff>
{me.admin &&
dv.c &&
!hasMask(dv.id, DeviceEntityMask.DV_READONLY) && (
<IconButton
size="small"
onClick={() => showDeviceValue(dv)}
>
{dv.v === '' ? (
<PlayArrowIcon color="primary" sx={{ fontSize: 16 }} />
) : (
<EditIcon color="primary" sx={{ fontSize: 16 }} />
)}
</IconButton>
)}
</Cell>
</Row>
))}
</Body>
</>
)}
</Table>
</Box>
);
};
return (
<SectionContent id="devices-window">
{renderCoreData()}
{renderDeviceData()}
{renderDeviceDetails()}
{selectedDeviceValue && (
<DevicesDialog
open={deviceValueDialogOpen}
onClose={deviceValueDialogClose}
onSave={deviceValueDialogSave}
selectedItem={selectedDeviceValue}
writeable={
selectedDeviceValue.c !== undefined &&
!hasMask(selectedDeviceValue.id, DeviceEntityMask.DV_READONLY)
}
validator={deviceValueItemValidation(selectedDeviceValue)}
progress={submitting}
/>
)}
</SectionContent>
);
});
export default Devices;

View File

@@ -1,36 +1,35 @@
import { useEffect, useState } from 'react';
import CancelIcon from '@mui/icons-material/Cancel';
import WarningIcon from '@mui/icons-material/Warning';
import {
Box,
Button,
CircularProgress,
Dialog,
DialogTitle,
DialogContent,
DialogActions,
DialogContent,
DialogTitle,
FormHelperText,
Grid,
InputAdornment,
MenuItem,
TextField,
FormHelperText,
Grid,
Box,
Typography,
CircularProgress
Typography
} from '@mui/material';
import { useState, useEffect } from 'react';
import { dialogStyle } from 'CustomTheme';
import type Schema from 'async-validator';
import type { ValidateFieldsError } from 'async-validator';
import { ValidatedTextField } from 'components';
import { useI18nContext } from 'i18n/i18n-react';
import { numberValue, updateValue } from 'utils';
import { validate } from 'validators';
import { DeviceValueUOM, DeviceValueUOM_s } from './types';
import type { DeviceValue } from './types';
import type Schema from 'async-validator';
import type { ValidateFieldsError } from 'async-validator';
import { dialogStyle } from 'CustomTheme';
import { ValidatedTextField } from 'components';
import { useI18nContext } from 'i18n/i18n-react';
import { updateValue, numberValue } from 'utils';
import { validate } from 'validators';
type DashboardDevicesDialogProps = {
interface DevicesDialogProps {
open: boolean;
onClose: () => void;
onSave: (as: DeviceValue) => void;
@@ -38,9 +37,9 @@ type DashboardDevicesDialogProps = {
writeable: boolean;
validator: Schema;
progress: boolean;
};
}
const DashboardDevicesDialog = ({
const DevicesDialog = ({
open,
onClose,
onSave,
@@ -48,7 +47,7 @@ const DashboardDevicesDialog = ({
writeable,
validator,
progress
}: DashboardDevicesDialogProps) => {
}: DevicesDialogProps) => {
const { LL } = useI18nContext();
const [editItem, setEditItem] = useState<DeviceValue>(selectedItem);
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
@@ -71,12 +70,15 @@ const DashboardDevicesDialog = ({
setFieldErrors(undefined);
await validate(validator, editItem);
onSave(editItem);
} catch (errors: any) {
setFieldErrors(errors);
} catch (error) {
setFieldErrors(error as ValidateFieldsError);
}
};
const setUom = (uom: number) => {
const setUom = (uom?: DeviceValueUOM) => {
if (uom === undefined) {
return;
}
switch (uom) {
case DeviceValueUOM.HOURS:
return LL.HOURS();
@@ -103,21 +105,24 @@ const DashboardDevicesDialog = ({
return (
<Dialog sx={dialogStyle} open={open} onClose={close}>
<DialogTitle>
{selectedItem.v === '' && selectedItem.c ? LL.RUN_COMMAND() : writeable ? LL.CHANGE_VALUE() : LL.VALUE(1)}
{selectedItem.v === '' && selectedItem.c
? LL.RUN_COMMAND()
: writeable
? LL.CHANGE_VALUE()
: LL.VALUE(0)}
</DialogTitle>
<DialogContent dividers>
<Box color="warning.main" p={0} pl={0} pr={0} mt={0} mb={2}>
<Typography variant="body2">{editItem.id.slice(2)}</Typography>
</Box>
<Grid>
<Grid item>
<Grid container>
<Grid size={12}>
{editItem.l ? (
<TextField
name="v"
label={LL.VALUE(1)}
// label={LL.VALUE(0)}
value={editItem.v}
disabled={!writeable}
autoFocus
sx={{ width: '30ch' }}
select
onChange={updateFormValue}
@@ -130,36 +135,43 @@ const DashboardDevicesDialog = ({
</TextField>
) : editItem.s || editItem.u !== DeviceValueUOM.NONE ? (
<ValidatedTextField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
name="v"
label={LL.VALUE(1)}
value={numberValue(Math.round(editItem.v * 10) / 10)}
label={LL.VALUE(0)}
value={numberValue(Math.round((editItem.v as number) * 10) / 10)}
autoFocus
disabled={!writeable}
type="number"
sx={{ width: '30ch' }}
onChange={updateFormValue}
inputProps={editItem.s ? { min: editItem.m, max: editItem.x, step: editItem.s } : {}}
InputProps={{
startAdornment: <InputAdornment position="start">{setUom(editItem.u)}</InputAdornment>
slotProps={{
htmlInput: editItem.s
? { min: editItem.m, max: editItem.x, step: editItem.s }
: {},
input: {
startAdornment: (
<InputAdornment position="start">
{setUom(editItem.u)}
</InputAdornment>
)
}
}}
/>
) : (
<ValidatedTextField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
name="v"
label={LL.VALUE(1)}
label={LL.VALUE(0)}
value={editItem.v}
disabled={!writeable}
autoFocus
sx={{ width: '30ch' }}
multiline={editItem.u ? false : true}
multiline={!editItem.u}
onChange={updateFormValue}
/>
)}
</Grid>
{writeable && (
<Grid item>
<Grid>
<FormHelperText>{showHelperText(editItem)}</FormHelperText>
</Grid>
)}
@@ -176,10 +188,20 @@ const DashboardDevicesDialog = ({
position: 'relative'
}}
>
<Button startIcon={<CancelIcon />} variant="outlined" onClick={close} color="secondary">
<Button
startIcon={<CancelIcon />}
variant="outlined"
onClick={close}
color="secondary"
>
{LL.CANCEL()}
</Button>
<Button startIcon={<WarningIcon color="warning" />} variant="contained" onClick={save} color="info">
<Button
startIcon={<WarningIcon color="warning" />}
variant="outlined"
onClick={save}
color="primary"
>
{selectedItem.v === '' && selectedItem.c ? LL.EXECUTE() : LL.UPDATE()}
</Button>
{progress && (
@@ -204,4 +226,4 @@ const DashboardDevicesDialog = ({
);
};
export default DashboardDevicesDialog;
export default DevicesDialog;

View File

@@ -1,12 +1,13 @@
import { ToggleButton, ToggleButtonGroup } from '@mui/material';
import OptionIcon from './OptionIcon';
import { DeviceEntityMask } from './types';
import type { DeviceEntity } from './types';
type EntityMaskToggleProps = {
interface EntityMaskToggleProps {
onUpdate: (de: DeviceEntity) => void;
de: DeviceEntity;
};
}
const EntityMaskToggle = ({ onUpdate, de }: EntityMaskToggleProps) => {
const getMaskNumber = (newMask: string[]) => {
@@ -42,7 +43,7 @@ const EntityMaskToggle = ({ onUpdate, de }: EntityMaskToggleProps) => {
size="small"
color="secondary"
value={getMaskString(de.m)}
onChange={(event, mask) => {
onChange={(_event, mask: string[]) => {
de.m = getMaskNumber(mask);
if (de.n === '' && de.m & DeviceEntityMask.DV_READONLY) {
de.m = de.m | DeviceEntityMask.DV_WEB_EXCLUDE;
@@ -54,25 +55,46 @@ const EntityMaskToggle = ({ onUpdate, de }: EntityMaskToggleProps) => {
}}
>
<ToggleButton value="8" disabled={(de.m & 0x81) !== 0 || de.n === undefined}>
<OptionIcon type="favorite" isSet={(de.m & DeviceEntityMask.DV_FAVORITE) === DeviceEntityMask.DV_FAVORITE} />
<OptionIcon
type="favorite"
isSet={
(de.m & DeviceEntityMask.DV_FAVORITE) === DeviceEntityMask.DV_FAVORITE
}
/>
</ToggleButton>
<ToggleButton value="4" disabled={!de.w || (de.m & 0x83) >= 3}>
<OptionIcon type="readonly" isSet={(de.m & DeviceEntityMask.DV_READONLY) === DeviceEntityMask.DV_READONLY} />
<OptionIcon
type="readonly"
isSet={
(de.m & DeviceEntityMask.DV_READONLY) === DeviceEntityMask.DV_READONLY
}
/>
</ToggleButton>
<ToggleButton value="2" disabled={de.n === '' || (de.m & 0x80) !== 0}>
<OptionIcon
type="api_mqtt_exclude"
isSet={(de.m & DeviceEntityMask.DV_API_MQTT_EXCLUDE) === DeviceEntityMask.DV_API_MQTT_EXCLUDE}
isSet={
(de.m & DeviceEntityMask.DV_API_MQTT_EXCLUDE) ===
DeviceEntityMask.DV_API_MQTT_EXCLUDE
}
/>
</ToggleButton>
<ToggleButton value="1" disabled={de.n === undefined || (de.m & 0x80) !== 0}>
<OptionIcon
type="web_exclude"
isSet={(de.m & DeviceEntityMask.DV_WEB_EXCLUDE) === DeviceEntityMask.DV_WEB_EXCLUDE}
isSet={
(de.m & DeviceEntityMask.DV_WEB_EXCLUDE) ===
DeviceEntityMask.DV_WEB_EXCLUDE
}
/>
</ToggleButton>
<ToggleButton value="128">
<OptionIcon type="deleted" isSet={(de.m & DeviceEntityMask.DV_DELETED) === DeviceEntityMask.DV_DELETED} />
<OptionIcon
type="deleted"
isSet={
(de.m & DeviceEntityMask.DV_DELETED) === DeviceEntityMask.DV_DELETED
}
/>
</ToggleButton>
</ToggleButtonGroup>
);

View File

@@ -0,0 +1,184 @@
import { useContext, useState } from 'react';
import { toast } from 'react-toastify';
import CommentIcon from '@mui/icons-material/CommentTwoTone';
import DownloadIcon from '@mui/icons-material/GetApp';
import GitHubIcon from '@mui/icons-material/GitHub';
import MenuBookIcon from '@mui/icons-material/MenuBookTwoTone';
import {
Avatar,
Box,
Button,
Divider,
Link,
List,
ListItem,
ListItemAvatar,
ListItemButton,
ListItemText,
Stack,
Typography
} from '@mui/material';
import { useRequest } from 'alova/client';
import { SectionContent, useLayoutTitle } from 'components';
import { AuthenticatedContext } from 'contexts/authentication';
import { useI18nContext } from 'i18n/i18n-react';
import { saveFile } from 'utils';
import { API, callAction } from '../../api/app';
import type { APIcall } from './types';
const Help = () => {
const { LL } = useI18nContext();
useLayoutTitle(LL.HELP());
const { me } = useContext(AuthenticatedContext);
const [customSupportIMG, setCustomSupportIMG] = useState<string | null>(null);
const [customSupportHTML, setCustomSupportHTML] = useState<string | null>(null);
const [notFound, setNotFound] = useState<boolean>(false);
useRequest(() => callAction({ action: 'getCustomSupport' })).onSuccess((event) => {
if (event && event.data && Object.keys(event.data).length !== 0) {
const data = (event.data as { Support: { img_url?: string; html?: string[] } })
.Support;
if (data.img_url) {
setCustomSupportIMG(data.img_url);
}
if (data.html) {
setCustomSupportHTML(data.html.join('<br/>'));
}
}
});
const { send: sendAPI } = useRequest((data: APIcall) => API(data), {
immediate: false
})
.onSuccess((event) => {
saveFile(event.data, 'system_info', '.json');
toast.info(LL.DOWNLOAD_SUCCESSFUL());
})
.onError((error) => {
toast.error(String(error.error?.message || 'An error occurred'));
});
return (
<SectionContent>
{customSupportHTML && (
<Stack
padding={1}
mb={2}
direction="row"
divider={<Divider orientation="vertical" flexItem />}
sx={{
borderRadius: 3,
border: '1px solid lightblue',
justifyContent: 'space-evenly',
alignItems: 'center'
}}
>
<Typography variant="subtitle1">
<div dangerouslySetInnerHTML={{ __html: customSupportHTML }} />
</Typography>
<Box
component="img"
referrerPolicy="no-referrer"
sx={{
maxHeight: { xs: 100, md: 250 }
}}
onError={() => setNotFound(true)}
src={
notFound
? ''
: customSupportIMG ||
'https://docs.emsesp.org/_media/images/installer.jpeg'
}
/>
</Stack>
)}
{me.admin && (
<List>
<ListItem>
<ListItemButton
component="a"
target="_blank"
rel="noreferrer"
href="https://docs.emsesp.org"
>
<ListItemAvatar>
<Avatar sx={{ bgcolor: '#72caf9' }}>
<MenuBookIcon />
</Avatar>
</ListItemAvatar>
<ListItemText primary={LL.HELP_INFORMATION_1()} />
</ListItemButton>
</ListItem>
<ListItem>
<ListItemButton
component="a"
target="_blank"
rel="noreferrer"
href="https://discord.gg/3J3GgnzpyT"
>
<ListItemAvatar>
<Avatar sx={{ bgcolor: '#72caf9' }}>
<CommentIcon />
</Avatar>
</ListItemAvatar>
<ListItemText primary={LL.HELP_INFORMATION_2()} />
</ListItemButton>
</ListItem>
<ListItem>
<ListItemButton
component="a"
target="_blank"
rel="noreferrer"
href="https://github.com/emsesp/EMS-ESP32/issues/new/choose"
>
<ListItemAvatar>
<Avatar sx={{ bgcolor: '#72caf9' }}>
<GitHubIcon />
</Avatar>
</ListItemAvatar>
<ListItemText primary={LL.HELP_INFORMATION_3()} />
</ListItemButton>
</ListItem>
</List>
)}
<Box p={2} color="warning.main">
<Typography mb={1} variant="body1">
{LL.HELP_INFORMATION_4()}.
</Typography>
<Button
startIcon={<DownloadIcon />}
variant="outlined"
color="primary"
onClick={() => sendAPI({ device: 'system', cmd: 'info', id: 0 })}
>
{LL.SUPPORT_INFORMATION(0)}
</Button>
</Box>
<Divider sx={{ mt: 4 }} />
<Typography color="white" variant="subtitle1" align="center" mt={1}>
&copy;&nbsp;
<Link
target="_blank"
rel="noreferrer"
href="https://emsesp.org"
color="primary"
>
{'emsesp.org'}
</Link>
</Typography>
</SectionContent>
);
};
export default Help;

View File

@@ -0,0 +1,273 @@
import { useCallback, useState } from 'react';
import { useBlocker } from 'react-router';
import { toast } from 'react-toastify';
import CancelIcon from '@mui/icons-material/Cancel';
import CircleIcon from '@mui/icons-material/Circle';
import WarningIcon from '@mui/icons-material/Warning';
import { Box, Button, Typography } from '@mui/material';
import {
Body,
Cell,
Header,
HeaderCell,
HeaderRow,
Row,
Table
} from '@table-library/react-table-library/table';
import { useTheme } from '@table-library/react-table-library/theme';
import { updateState, useRequest } from 'alova/client';
import {
BlockNavigation,
ButtonRow,
FormLoader,
SectionContent,
useLayoutTitle
} from 'components';
import { useI18nContext } from 'i18n/i18n-react';
import { readModules, writeModules } from '../../api/app';
import ModulesDialog from './ModulesDialog';
import type { ModuleItem } from './types';
const Modules = () => {
const { LL } = useI18nContext();
const [numChanges, setNumChanges] = useState<number>(0);
const blocker = useBlocker(numChanges !== 0);
const [selectedModuleItem, setSelectedModuleItem] = useState<ModuleItem>();
const [dialogOpen, setDialogOpen] = useState<boolean>(false);
useLayoutTitle(LL.MODULES());
const {
data: modules,
send: fetchModules,
error
} = useRequest(readModules, {
initialData: []
});
const { send: updateModules } = useRequest(
(data: { key: string; enabled: boolean; license: string }) => writeModules(data),
{
immediate: false
}
);
const modules_theme = useTheme({
Table: `
--data-table-library_grid-template-columns: 48px 180px 120px 100px repeat(1, minmax(160px, 1fr)) 180px;
`,
BaseRow: `
font-size: 14px;
.td {
height: 32px;
}
`,
BaseCell: `
&:nth-of-type(1) {
text-align: center;
}
`,
HeaderRow: `
text-transform: uppercase;
background-color: black;
color: #90CAF9;
.th {
border-bottom: 1px solid #565656;
height: 36px;
}
`,
Row: `
background-color: #1e1e1e;
position: relative;
cursor: pointer;
.td {
border-top: 1px solid #565656;
border-bottom: 1px solid #565656;
}
&:hover .td {
border-top: 1px solid #177ac9;
border-bottom: 1px solid #177ac9;
}
&:nth-of-type(odd) .td {
background-color: #303030;
}
`
});
const onDialogClose = () => {
setDialogOpen(false);
};
const onDialogSave = (updatedItem: ModuleItem) => {
setDialogOpen(false);
updateModuleItem(updatedItem);
};
const editModuleItem = useCallback((mi: ModuleItem) => {
setSelectedModuleItem(mi);
setDialogOpen(true);
}, []);
const onCancel = async () => {
await fetchModules().then(() => {
setNumChanges(0);
});
};
function hasModulesChanged(mi: ModuleItem) {
return mi.enabled !== mi.o_enabled || mi.license !== mi.o_license;
}
const updateModuleItem = (updatedItem: ModuleItem) => {
void updateState(readModules(), (data: ModuleItem[]) => {
const new_data = data.map((mi) =>
mi.id === updatedItem.id ? { ...mi, ...updatedItem } : mi
);
setNumChanges(new_data.filter((mi) => hasModulesChanged(mi)).length);
return new_data;
});
};
const saveModules = async () => {
await Promise.all(
modules.map((condensed_mi: ModuleItem) =>
updateModules({
key: condensed_mi.key,
enabled: condensed_mi.enabled,
license: condensed_mi.license
})
)
)
.then(() => {
toast.success(LL.MODULES_UPDATED());
})
.catch((error: Error) => {
toast.error(error.message);
})
.finally(async () => {
await fetchModules();
setNumChanges(0);
});
};
const renderContent = () => {
if (!modules) {
return (
<FormLoader onRetry={fetchModules} errorMessage={error?.message || ''} />
);
}
if (modules.length === 0) {
return (
<Typography variant="body2" color="error">
{LL.MODULES_NONE()}
</Typography>
);
}
const colorStatus = (status: number) => {
if (status === 1) {
return <div style={{ color: 'red' }}>Pending Activation</div>;
}
return <div style={{ color: '#00FF7F' }}>Activated</div>;
};
return (
<>
<Box mb={2} color="warning.main">
<Typography variant="body1">{LL.MODULES_DESCRIPTION()}.</Typography>
</Box>
<Table
data={{ nodes: modules }}
theme={modules_theme}
layout={{ custom: true }}
>
{(tableList: ModuleItem[]) => (
<>
<Header>
<HeaderRow>
<HeaderCell />
<HeaderCell>{LL.NAME(0)}</HeaderCell>
<HeaderCell>Author</HeaderCell>
<HeaderCell>{LL.VERSION()}</HeaderCell>
<HeaderCell>Message</HeaderCell>
<HeaderCell>{LL.STATUS_OF('')}</HeaderCell>
</HeaderRow>
</Header>
<Body>
{tableList.map((mi: ModuleItem) => (
<Row key={mi.id} item={mi} onClick={() => editModuleItem(mi)}>
<Cell stiff>
{mi.enabled ? (
<CircleIcon
color="success"
sx={{ fontSize: 16, verticalAlign: 'middle' }}
/>
) : (
<CircleIcon
color="error"
sx={{ fontSize: 16, verticalAlign: 'middle' }}
/>
)}
</Cell>
<Cell>{mi.name}</Cell>
<Cell>{mi.author}</Cell>
<Cell>{mi.version}</Cell>
<Cell>{mi.message}</Cell>
<Cell>{colorStatus(mi.status)}</Cell>
</Row>
))}
</Body>
</>
)}
</Table>
<Box mt={1} display="flex" flexWrap="wrap">
<Box flexGrow={1}>
{numChanges !== 0 && (
<ButtonRow>
<Button
startIcon={<CancelIcon />}
variant="outlined"
onClick={onCancel}
color="secondary"
>
{LL.CANCEL()}
</Button>
<Button
startIcon={<WarningIcon color="warning" />}
variant="contained"
color="info"
onClick={saveModules}
>
{LL.APPLY_CHANGES(numChanges)}
</Button>
</ButtonRow>
)}
</Box>
</Box>
</>
);
};
return (
<SectionContent>
{blocker ? <BlockNavigation blocker={blocker} /> : null}
{renderContent()}
{selectedModuleItem && (
<ModulesDialog
open={dialogOpen}
onClose={onDialogClose}
onSave={onDialogSave}
selectedItem={selectedModuleItem}
/>
)}
</SectionContent>
);
};
export default Modules;

View File

@@ -0,0 +1,106 @@
import { useEffect, useState } from 'react';
import CancelIcon from '@mui/icons-material/Cancel';
import DoneIcon from '@mui/icons-material/Done';
import {
Box,
Button,
Checkbox,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
Grid,
TextField
} from '@mui/material';
import { dialogStyle } from 'CustomTheme';
import { BlockFormControlLabel } from 'components';
import { useI18nContext } from 'i18n/i18n-react';
import { updateValue } from 'utils';
import type { ModuleItem } from './types';
interface ModulesDialogProps {
open: boolean;
onClose: () => void;
onSave: (mi: ModuleItem) => void;
selectedItem: ModuleItem;
}
const ModulesDialog = ({
open,
onClose,
onSave,
selectedItem
}: ModulesDialogProps) => {
const { LL } = useI18nContext();
const [editItem, setEditItem] = useState<ModuleItem>(selectedItem);
const updateFormValue = updateValue(setEditItem);
useEffect(() => {
if (open) {
setEditItem(selectedItem);
}
}, [open, selectedItem]);
const close = () => {
onClose();
};
const save = () => {
onSave(editItem);
};
return (
<Dialog sx={dialogStyle} fullWidth maxWidth="xs" open={open} onClose={onClose}>
<DialogTitle>{LL.EDIT() + ' ' + editItem.key}</DialogTitle>
<DialogContent dividers>
<Grid container>
<BlockFormControlLabel
control={
<Checkbox
checked={editItem.enabled}
onChange={updateFormValue}
name="enabled"
/>
}
label="Enabled"
/>
</Grid>
<Box mt={2} mb={1}>
<TextField
name="license"
label="License Key"
multiline
rows={6}
fullWidth
value={editItem.license}
onChange={updateFormValue}
/>
</Box>
</DialogContent>
<DialogActions>
<Button
startIcon={<CancelIcon />}
variant="outlined"
onClick={close}
color="secondary"
>
{LL.CANCEL()}
</Button>
<Button
startIcon={<DoneIcon />}
variant="outlined"
onClick={save}
color="primary"
>
{LL.UPDATE()}
</Button>
</DialogActions>
</Dialog>
);
};
export default ModulesDialog;

View File

@@ -3,20 +3,26 @@ import DeleteForeverIcon from '@mui/icons-material/DeleteForever';
import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline';
import EditOffOutlinedIcon from '@mui/icons-material/EditOffOutlined';
import EditOutlinedIcon from '@mui/icons-material/EditOutlined';
import InsertCommentOutlinedIcon from '@mui/icons-material/InsertCommentOutlined';
import StarIcon from '@mui/icons-material/Star';
import StarOutlineIcon from '@mui/icons-material/StarOutline';
import VisibilityOffOutlinedIcon from '@mui/icons-material/VisibilityOffOutlined';
import VisibilityOutlinedIcon from '@mui/icons-material/VisibilityOutlined';
import type { SvgIconProps } from '@mui/material';
import type { FC } from 'react';
type OptionType = 'deleted' | 'readonly' | 'web_exclude' | 'api_mqtt_exclude' | 'favorite';
type OptionType =
| 'deleted'
| 'readonly'
| 'web_exclude'
| 'api_mqtt_exclude'
| 'favorite';
const OPTION_ICONS: { [type in OptionType]: [React.ComponentType<SvgIconProps>, React.ComponentType<SvgIconProps>] } = {
const OPTION_ICONS: {
[type in OptionType]: [
React.ComponentType<SvgIconProps>,
React.ComponentType<SvgIconProps>
];
} = {
deleted: [DeleteForeverIcon, DeleteOutlineIcon],
readonly: [EditOffOutlinedIcon, EditOutlinedIcon],
web_exclude: [VisibilityOffOutlinedIcon, VisibilityOutlinedIcon],
@@ -24,12 +30,7 @@ const OPTION_ICONS: { [type in OptionType]: [React.ComponentType<SvgIconProps>,
favorite: [StarIcon, StarOutlineIcon]
};
interface OptionIconProps {
type: OptionType;
isSet: boolean;
}
const OptionIcon: FC<OptionIconProps> = ({ type, isSet }) => {
const OptionIcon = ({ type, isSet }: { type: OptionType; isSet: boolean }) => {
const Icon = OPTION_ICONS[type][isSet ? 0 : 1];
return isSet ? (
<Icon color="primary" sx={{ fontSize: 16, verticalAlign: 'middle' }} />

View File

@@ -1,28 +1,41 @@
import { useCallback, useEffect, useState } from 'react';
import { useBlocker } from 'react-router';
import { toast } from 'react-toastify';
import AddIcon from '@mui/icons-material/Add';
import CancelIcon from '@mui/icons-material/Cancel';
import CircleIcon from '@mui/icons-material/Circle';
import WarningIcon from '@mui/icons-material/Warning';
import { Box, Button, Divider, Stack, Typography } from '@mui/material';
import { Box, Typography, Divider, Stack, Button } from '@mui/material';
import { Table, Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table';
import {
Body,
Cell,
Header,
HeaderCell,
HeaderRow,
Row,
Table
} from '@table-library/react-table-library/table';
import { useTheme } from '@table-library/react-table-library/theme';
// eslint-disable-next-line import/named
import { updateState, useRequest } from 'alova';
import { useState, useEffect, useCallback } from 'react';
import { useBlocker } from 'react-router-dom';
import { toast } from 'react-toastify';
import SettingsSchedulerDialog from './SettingsSchedulerDialog';
import * as EMSESP from './api';
import { ScheduleFlag } from './types';
import { schedulerItemValidation } from './validators';
import type { ScheduleItem } from './types';
import type { FC } from 'react';
import { ButtonRow, FormLoader, SectionContent, BlockNavigation } from 'components';
import { updateState, useRequest } from 'alova/client';
import {
BlockNavigation,
ButtonRow,
FormLoader,
SectionContent,
useLayoutTitle
} from 'components';
import { useI18nContext } from 'i18n/i18n-react';
import { useInterval } from 'utils';
const SettingsScheduler: FC = () => {
import { readSchedule, writeSchedule } from '../../api/app';
import SettingsSchedulerDialog from './SchedulerDialog';
import { ScheduleFlag } from './types';
import type { Schedule, ScheduleItem } from './types';
import { schedulerItemValidation } from './validators';
const Scheduler = () => {
const { LL, locale } = useI18nContext();
const [numChanges, setNumChanges] = useState<number>(0);
const blocker = useBlocker(numChanges !== 0);
@@ -31,16 +44,22 @@ const SettingsScheduler: FC = () => {
const [creating, setCreating] = useState<boolean>(false);
const [dialogOpen, setDialogOpen] = useState<boolean>(false);
useLayoutTitle(LL.SCHEDULER());
const {
data: schedule,
send: fetchSchedule,
error
} = useRequest(EMSESP.readSchedule, {
initialData: [],
force: true
} = useRequest(readSchedule, {
initialData: []
});
const { send: writeSchedule } = useRequest((data) => EMSESP.writeSchedule(data), { immediate: false });
const { send: updateSchedule } = useRequest(
(data: Schedule) => writeSchedule(data),
{
immediate: false
}
);
function hasScheduleChanged(si: ScheduleItem) {
return (
@@ -55,8 +74,17 @@ const SettingsScheduler: FC = () => {
);
}
useInterval(() => {
if (numChanges === 0) {
void fetchSchedule();
}
});
useEffect(() => {
const formatter = new Intl.DateTimeFormat(locale, { weekday: 'short', timeZone: 'UTC' });
const formatter = new Intl.DateTimeFormat(locale, {
weekday: 'short',
timeZone: 'UTC'
});
const days = [1, 2, 3, 4, 5, 6, 7].map((day) => {
const dd = day < 10 ? `0${day}` : day;
return new Date(`2017-01-${dd}T00:00:00+00:00`);
@@ -66,7 +94,7 @@ const SettingsScheduler: FC = () => {
const schedule_theme = useTheme({
Table: `
--data-table-library_grid-template-columns: 36px 324px 50px 192px repeat(1, minmax(100px, 1fr)) 160px;
--data-table-library_grid-template-columns: 36px 210px 100px 192px repeat(1, minmax(100px, 1fr)) 160px;
`,
BaseRow: `
font-size: 14px;
@@ -96,24 +124,19 @@ const SettingsScheduler: FC = () => {
position: relative;
cursor: pointer;
.td {
border-top: 1px solid #565656;
border-bottom: 1px solid #565656;
}
&:hover .td {
border-top: 1px solid #177ac9;
border-bottom: 1px solid #177ac9;
}
&:nth-of-type(odd) .td {
background-color: #303030;
background-color: #177ac9;
}
`
});
const saveSchedule = async () => {
await writeSchedule({
await updateSchedule({
schedule: schedule
.filter((si) => !si.deleted)
.map((condensed_si) => ({
.filter((si: ScheduleItem) => !si.deleted)
.map((condensed_si: ScheduleItem) => ({
id: condensed_si.id,
active: condensed_si.active,
flags: condensed_si.flags,
@@ -126,8 +149,8 @@ const SettingsScheduler: FC = () => {
.then(() => {
toast.success(LL.SCHEDULE_UPDATED());
})
.catch((err) => {
toast.error(err.message);
.catch((error: Error) => {
toast.error(error.message);
})
.finally(async () => {
await fetchSchedule();
@@ -139,6 +162,9 @@ const SettingsScheduler: FC = () => {
setCreating(false);
setSelectedScheduleItem(si);
setDialogOpen(true);
if (si.o_name === undefined) {
si.o_name = si.name;
}
}, []);
const onDialogClose = () => {
@@ -153,12 +179,18 @@ const SettingsScheduler: FC = () => {
const onDialogSave = (updatedItem: ScheduleItem) => {
setDialogOpen(false);
updateState('schedule', (data) => {
void updateState(readSchedule(), (data: ScheduleItem[]) => {
const new_data = creating
? [...data.filter((si) => creating || si.o_id !== updatedItem.o_id), updatedItem]
: data.map((si) => (si.id === updatedItem.id ? { ...si, ...updatedItem } : si));
? [
...data.filter((si) => creating || si.o_id !== updatedItem.o_id),
updatedItem
]
: data.map((si) =>
si.id === updatedItem.id ? { ...si, ...updatedItem } : si
);
setNumChanges(new_data.filter((si) => hasScheduleChanged(si)).length);
return new_data;
});
};
@@ -169,8 +201,8 @@ const SettingsScheduler: FC = () => {
id: Math.floor(Math.random() * (Math.floor(200) - 100) + 100),
active: false,
deleted: false,
flags: 0,
time: '12:00',
flags: ScheduleFlag.SCHEDULE_DAY,
time: '',
cmd: '',
value: '',
name: ''
@@ -180,35 +212,62 @@ const SettingsScheduler: FC = () => {
const renderSchedule = () => {
if (!schedule) {
return <FormLoader onRetry={fetchSchedule} errorMessage={error?.message} />;
return (
<FormLoader onRetry={fetchSchedule} errorMessage={error?.message || ''} />
);
}
const dayBox = (si: ScheduleItem, flag: number) => (
<>
<Box>
<Typography sx={{ fontSize: 11 }} color={(si.flags & flag) === flag ? 'primary' : 'grey'}>
{flag === ScheduleFlag.SCHEDULE_TIMER ? LL.TIMER(0) : dow[Math.log(flag) / Math.log(2)]}
<Typography
sx={{ fontSize: 11 }}
color={(si.flags & flag) === flag ? 'primary' : 'grey'}
>
{dow[Math.log(flag) / Math.log(2)]}
</Typography>
</Box>
<Divider orientation="vertical" flexItem />
</>
);
const scheduleType = (si: ScheduleItem) => (
<Box>
<Typography sx={{ fontSize: 11 }} color="primary">
{si.flags === ScheduleFlag.SCHEDULE_IMMEDIATE ? (
<>Immediate</>
) : si.flags === ScheduleFlag.SCHEDULE_TIMER ? (
<>Timer</>
) : si.flags === ScheduleFlag.SCHEDULE_CONDITION ? (
<>Condition</>
) : si.flags === ScheduleFlag.SCHEDULE_ONCHANGE ? (
<>On Change</>
) : (
<></>
)}
</Typography>
</Box>
);
return (
<Table
data={{ nodes: schedule.filter((si) => !si.deleted).sort((a, b) => a.time.localeCompare(b.time)) }}
data={{
nodes: schedule
.filter((si: ScheduleItem) => !si.deleted)
.sort((a: ScheduleItem, b: ScheduleItem) => a.flags - b.flags)
}}
theme={schedule_theme}
layout={{ custom: true }}
>
{(tableList: any) => (
{(tableList: ScheduleItem[]) => (
<>
<Header>
<HeaderRow>
<HeaderCell />
<HeaderCell stiff>{LL.SCHEDULE(0)}</HeaderCell>
<HeaderCell stiff>{LL.TIME(0)}</HeaderCell>
<HeaderCell stiff>{LL.TIME(0)}/Cond.</HeaderCell>
<HeaderCell stiff>{LL.COMMAND(0)}</HeaderCell>
<HeaderCell stiff>{LL.VALUE(1)}</HeaderCell>
<HeaderCell stiff>{LL.VALUE(0)}</HeaderCell>
<HeaderCell stiff>{LL.NAME(0)}</HeaderCell>
</HeaderRow>
</Header>
@@ -217,22 +276,33 @@ const SettingsScheduler: FC = () => {
<Row key={si.id} item={si} onClick={() => editScheduleItem(si)}>
<Cell stiff>
{si.active ? (
<CircleIcon color="success" sx={{ fontSize: 16, verticalAlign: 'middle' }} />
<CircleIcon
color="success"
sx={{ fontSize: 16, verticalAlign: 'middle' }}
/>
) : (
<CircleIcon color="error" sx={{ fontSize: 16, verticalAlign: 'middle' }} />
<CircleIcon
color="error"
sx={{ fontSize: 16, verticalAlign: 'middle' }}
/>
)}
</Cell>
<Cell stiff>
<Stack spacing={1} direction="row">
<Stack spacing={0.5} direction="row">
<Divider orientation="vertical" flexItem />
{dayBox(si, ScheduleFlag.SCHEDULE_MON)}
{dayBox(si, ScheduleFlag.SCHEDULE_TUE)}
{dayBox(si, ScheduleFlag.SCHEDULE_WED)}
{dayBox(si, ScheduleFlag.SCHEDULE_THU)}
{dayBox(si, ScheduleFlag.SCHEDULE_FRI)}
{dayBox(si, ScheduleFlag.SCHEDULE_SAT)}
{dayBox(si, ScheduleFlag.SCHEDULE_SUN)}
{dayBox(si, ScheduleFlag.SCHEDULE_TIMER)}
{si.flags > 127 ? (
scheduleType(si)
) : (
<>
{dayBox(si, ScheduleFlag.SCHEDULE_MON)}
{dayBox(si, ScheduleFlag.SCHEDULE_TUE)}
{dayBox(si, ScheduleFlag.SCHEDULE_WED)}
{dayBox(si, ScheduleFlag.SCHEDULE_THU)}
{dayBox(si, ScheduleFlag.SCHEDULE_FRI)}
{dayBox(si, ScheduleFlag.SCHEDULE_SAT)}
{dayBox(si, ScheduleFlag.SCHEDULE_SUN)}
</>
)}
</Stack>
</Cell>
<Cell>{si.time}</Cell>
@@ -249,10 +319,10 @@ const SettingsScheduler: FC = () => {
};
return (
<SectionContent title={LL.SCHEDULER()} titleGutter>
<SectionContent>
{blocker ? <BlockNavigation blocker={blocker} /> : null}
<Box mb={2} color="warning.main">
<Typography variant="body2">{LL.SCHEDULER_HELP_1()}</Typography>
<Typography variant="body1">{LL.SCHEDULER_HELP_1()}.</Typography>
</Box>
{renderSchedule()}
@@ -272,7 +342,12 @@ const SettingsScheduler: FC = () => {
<Box flexGrow={1}>
{numChanges !== 0 && (
<ButtonRow>
<Button startIcon={<CancelIcon />} variant="outlined" onClick={onDialogCancel} color="secondary">
<Button
startIcon={<CancelIcon />}
variant="outlined"
onClick={onDialogCancel}
color="secondary"
>
{LL.CANCEL()}
</Button>
<Button
@@ -288,7 +363,12 @@ const SettingsScheduler: FC = () => {
</Box>
<Box flexWrap="nowrap" whiteSpace="nowrap">
<ButtonRow>
<Button startIcon={<AddIcon />} variant="outlined" color="secondary" onClick={addScheduleItem}>
<Button
startIcon={<AddIcon />}
variant="outlined"
color="primary"
onClick={addScheduleItem}
>
{LL.ADD(0)}
</Button>
</ButtonRow>
@@ -298,4 +378,4 @@ const SettingsScheduler: FC = () => {
);
};
export default SettingsScheduler;
export default Scheduler;

View File

@@ -0,0 +1,404 @@
import { useEffect, useState } from 'react';
import AddIcon from '@mui/icons-material/Add';
import CancelIcon from '@mui/icons-material/Cancel';
import DoneIcon from '@mui/icons-material/Done';
import PlayArrowIcon from '@mui/icons-material/PlayArrow';
import RemoveIcon from '@mui/icons-material/RemoveCircleOutline';
import {
Box,
Button,
Checkbox,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
Grid,
TextField,
ToggleButton,
ToggleButtonGroup,
Typography
} from '@mui/material';
import { dialogStyle } from 'CustomTheme';
import type Schema from 'async-validator';
import type { ValidateFieldsError } from 'async-validator';
import { BlockFormControlLabel, ValidatedTextField } from 'components';
import { useI18nContext } from 'i18n/i18n-react';
import { updateValue } from 'utils';
import { validate } from 'validators';
import { ScheduleFlag } from './types';
import type { ScheduleItem } from './types';
interface SchedulerDialogProps {
open: boolean;
creating: boolean;
onClose: () => void;
onSave: (ei: ScheduleItem) => void;
selectedItem: ScheduleItem;
validator: Schema;
dow: string[];
}
const SchedulerDialog = ({
open,
creating,
onClose,
onSave,
selectedItem,
validator,
dow
}: SchedulerDialogProps) => {
const { LL } = useI18nContext();
const [editItem, setEditItem] = useState<ScheduleItem>(selectedItem);
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
const [scheduleType, setScheduleType] = useState<ScheduleFlag>();
const updateFormValue = updateValue(setEditItem);
useEffect(() => {
if (open) {
setFieldErrors(undefined);
setEditItem(selectedItem);
// set the flags based on type when page is loaded...
// 0-127 is day schedule
// 128 is timer
// 129 is on change
// 130 is on condition
// 132 is immediate
setScheduleType(
selectedItem.flags < 128 ? ScheduleFlag.SCHEDULE_DAY : selectedItem.flags
);
}
}, [open, selectedItem]);
const save = async () => {
try {
setFieldErrors(undefined);
await validate(validator, editItem);
onSave(editItem);
} catch (error) {
setFieldErrors(error as ValidateFieldsError);
}
};
const saveandactivate = async () => {
editItem.active = true;
try {
setFieldErrors(undefined);
await validate(validator, editItem);
onSave(editItem);
} catch (error) {
setFieldErrors(error as ValidateFieldsError);
}
};
const remove = () => {
editItem.deleted = true;
onSave(editItem);
};
const getFlagDOWnumber = (newFlag: string[]) => {
let new_flag = 0;
for (const entry of newFlag) {
new_flag |= Number(entry);
}
return new_flag & 127;
};
const getFlagDOWstring = (f: number) => {
const new_flags: string[] = [];
if ((f & 129) === 1) {
new_flags.push('1');
}
if ((f & 130) === 2) {
new_flags.push('2');
}
if ((f & 4) === 4) {
new_flags.push('4');
}
if ((f & 8) === 8) {
new_flags.push('8');
}
if ((f & 16) === 16) {
new_flags.push('16');
}
if ((f & 32) === 32) {
new_flags.push('32');
}
if ((f & 64) === 64) {
new_flags.push('64');
}
return new_flags;
};
const showDOW = (si: ScheduleItem, flag: number) => (
<Typography
sx={{ fontSize: 10 }}
color={(si.flags & flag) === flag ? 'primary' : 'grey'}
>
{dow[Math.log(flag) / Math.log(2)]}
</Typography>
);
const handleClose = (
_event: React.SyntheticEvent,
reason: 'backdropClick' | 'escapeKeyDown'
) => {
if (reason !== 'backdropClick') {
onClose();
}
};
return (
<Dialog sx={dialogStyle} open={open} onClose={handleClose}>
<DialogTitle>
{creating ? LL.ADD(1) + ' ' + LL.NEW(0) : LL.EDIT()}&nbsp;
{LL.SCHEDULE(1)}
</DialogTitle>
<DialogContent dividers>
<ToggleButtonGroup
size="small"
color="secondary"
value={scheduleType}
exclusive
disabled={!creating}
onChange={(_event, flag: ScheduleFlag) => {
if (flag !== null) {
setFieldErrors(undefined); // clear any validation errors
setScheduleType(flag);
// wipe the time field when changing the schedule type
setEditItem({ ...editItem, time: '' });
// set the flags based on type
// 0-127 is day schedule
// 128 is timer
// 129 is on change
// 130 is on condition
// 132 is immediate
setEditItem(
flag === ScheduleFlag.SCHEDULE_DAY
? { ...editItem, flags: 0 }
: { ...editItem, flags: flag }
);
}
}}
>
<ToggleButton value={ScheduleFlag.SCHEDULE_DAY}>
<Typography
sx={{ fontSize: 10 }}
color={scheduleType === ScheduleFlag.SCHEDULE_DAY ? 'primary' : 'grey'}
>
{LL.SCHEDULE(0)}
</Typography>
</ToggleButton>
<ToggleButton value={ScheduleFlag.SCHEDULE_TIMER}>
<Typography
sx={{ fontSize: 10 }}
color={
scheduleType === ScheduleFlag.SCHEDULE_TIMER ? 'primary' : 'grey'
}
>
{LL.TIMER(0)}
</Typography>
</ToggleButton>
<ToggleButton value={ScheduleFlag.SCHEDULE_ONCHANGE}>
<Typography
sx={{ fontSize: 10 }}
color={
scheduleType === ScheduleFlag.SCHEDULE_ONCHANGE ? 'primary' : 'grey'
}
>
{LL.ONCHANGE()}
</Typography>
</ToggleButton>
<ToggleButton value={ScheduleFlag.SCHEDULE_CONDITION}>
<Typography
sx={{ fontSize: 10 }}
color={
scheduleType === ScheduleFlag.SCHEDULE_CONDITION ? 'primary' : 'grey'
}
>
{LL.CONDITION()}
</Typography>
</ToggleButton>
<ToggleButton value={ScheduleFlag.SCHEDULE_IMMEDIATE}>
<Typography
sx={{ fontSize: 10 }}
color={
scheduleType === ScheduleFlag.SCHEDULE_IMMEDIATE ? 'primary' : 'grey'
}
>
{LL.IMMEDIATE()}
</Typography>
</ToggleButton>
</ToggleButtonGroup>
{scheduleType === ScheduleFlag.SCHEDULE_DAY && (
<ToggleButtonGroup
size="small"
color="secondary"
value={getFlagDOWstring(editItem.flags)}
onChange={(_event, flag: string[]) => {
setEditItem({ ...editItem, flags: getFlagDOWnumber(flag) });
}}
>
<ToggleButton value="2">
{showDOW(editItem, ScheduleFlag.SCHEDULE_MON)}
</ToggleButton>
<ToggleButton value="4">
{showDOW(editItem, ScheduleFlag.SCHEDULE_TUE)}
</ToggleButton>
<ToggleButton value="8">
{showDOW(editItem, ScheduleFlag.SCHEDULE_WED)}
</ToggleButton>
<ToggleButton value="16">
{showDOW(editItem, ScheduleFlag.SCHEDULE_THU)}
</ToggleButton>
<ToggleButton value="32">
{showDOW(editItem, ScheduleFlag.SCHEDULE_FRI)}
</ToggleButton>
<ToggleButton value="64">
{showDOW(editItem, ScheduleFlag.SCHEDULE_SAT)}
</ToggleButton>
<ToggleButton value="1">
{showDOW(editItem, ScheduleFlag.SCHEDULE_SUN)}
</ToggleButton>
</ToggleButtonGroup>
)}
{scheduleType !== ScheduleFlag.SCHEDULE_IMMEDIATE && (
<>
<Grid container>
<BlockFormControlLabel
control={
<Checkbox
checked={editItem.active}
onChange={updateFormValue}
name="active"
/>
}
label={LL.ACTIVE()}
/>
</Grid>
<Grid container>
{scheduleType === ScheduleFlag.SCHEDULE_DAY ||
scheduleType === ScheduleFlag.SCHEDULE_TIMER ? (
<>
<TextField
name="time"
type="time"
label={
scheduleType === ScheduleFlag.SCHEDULE_TIMER
? LL.TIMER(1)
: LL.TIME(1)
}
value={editItem.time === '' ? '00:00' : editItem.time}
margin="normal"
onChange={updateFormValue}
/>
{scheduleType === ScheduleFlag.SCHEDULE_TIMER && (
<Box color="warning.main" ml={2} mt={4}>
<Typography variant="body2">
{LL.SCHEDULER_HELP_2()}
</Typography>
</Box>
)}
</>
) : (
<TextField
name="time"
label={
scheduleType === ScheduleFlag.SCHEDULE_CONDITION
? LL.CONDITION()
: scheduleType === ScheduleFlag.SCHEDULE_ONCHANGE
? LL.ONCHANGE()
: LL.IMMEDIATE()
}
multiline
fullWidth
value={editItem.time === '00:00' ? '' : editItem.time}
margin="normal"
onChange={updateFormValue}
/>
)}
</Grid>
</>
)}
<ValidatedTextField
fieldErrors={fieldErrors || {}}
name="cmd"
label={LL.COMMAND(0)}
multiline
fullWidth
value={editItem.cmd}
margin="normal"
onChange={updateFormValue}
/>
<TextField
name="value"
label={LL.VALUE(0)}
multiline
margin="normal"
fullWidth
value={editItem.value}
onChange={updateFormValue}
/>
<ValidatedTextField
fieldErrors={fieldErrors || {}}
name="name"
label={LL.NAME(0) + ' (' + LL.OPTIONAL() + ')'}
value={editItem.name}
fullWidth
margin="normal"
onChange={updateFormValue}
/>
</DialogContent>
<DialogActions>
{!creating && (
<Box flexGrow={1}>
<Button
startIcon={<RemoveIcon />}
variant="outlined"
color="warning"
onClick={remove}
>
{LL.REMOVE()}
</Button>
</Box>
)}
<Button
startIcon={<CancelIcon />}
variant="outlined"
onClick={onClose}
color="secondary"
>
{LL.CANCEL()}
</Button>
<Button
startIcon={creating ? <AddIcon /> : <DoneIcon />}
variant="outlined"
onClick={save}
color="primary"
>
{creating ? LL.ADD(0) : LL.UPDATE()}
</Button>
{scheduleType === ScheduleFlag.SCHEDULE_IMMEDIATE && editItem.cmd !== '' && (
<Button
startIcon={<PlayArrowIcon />}
variant="outlined"
onClick={saveandactivate}
color="success"
>
{LL.EXECUTE()}
</Button>
)}
</DialogActions>
</Dialog>
);
};
export default SchedulerDialog;

View File

@@ -1,58 +1,97 @@
import { useContext, useState } from 'react';
import { toast } from 'react-toastify';
import AddCircleOutlineOutlinedIcon from '@mui/icons-material/AddCircleOutlineOutlined';
import KeyboardArrowDownOutlinedIcon from '@mui/icons-material/KeyboardArrowDownOutlined';
import KeyboardArrowUpOutlinedIcon from '@mui/icons-material/KeyboardArrowUpOutlined';
import RefreshIcon from '@mui/icons-material/Refresh';
import UnfoldMoreOutlinedIcon from '@mui/icons-material/UnfoldMoreOutlined';
import { Button, Typography, Box } from '@mui/material';
import { useSort, SortToggleType } from '@table-library/react-table-library/sort';
import { Table, Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table';
import { Box, Button, Typography } from '@mui/material';
import { SortToggleType, useSort } from '@table-library/react-table-library/sort';
import {
Body,
Cell,
Header,
HeaderCell,
HeaderRow,
Row,
Table
} from '@table-library/react-table-library/table';
import { useTheme } from '@table-library/react-table-library/theme';
import { useRequest } from 'alova';
import { useState, useContext, useEffect } from 'react';
import { toast } from 'react-toastify';
import DashboardSensorsAnalogDialog from './DashboardSensorsAnalogDialog';
import DashboardSensorsTemperatureDialog from './DashboardSensorsTemperatureDialog';
import * as EMSESP from './api';
import { DeviceValueUOM, DeviceValueUOM_s, AnalogTypeNames, AnalogType } from './types';
import { temperatureSensorItemValidation, analogSensorItemValidation } from './validators';
import type { TemperatureSensor, AnalogSensor } from './types';
import type { FC } from 'react';
import { ButtonRow, SectionContent } from 'components';
import type { State } from '@table-library/react-table-library/types/common';
import { useRequest } from 'alova/client';
import { SectionContent, useLayoutTitle } from 'components';
import { AuthenticatedContext } from 'contexts/authentication';
import { useI18nContext } from 'i18n/i18n-react';
import { useInterval } from 'utils';
const DashboardSensors: FC = () => {
import {
readSensorData,
writeAnalogSensor,
writeTemperatureSensor
} from '../../api/app';
import DashboardSensorsAnalogDialog from './SensorsAnalogDialog';
import DashboardSensorsTemperatureDialog from './SensorsTemperatureDialog';
import {
AnalogType,
AnalogTypeNames,
DeviceValueUOM,
DeviceValueUOM_s
} from './types';
import type {
AnalogSensor,
TemperatureSensor,
WriteAnalogSensor,
WriteTemperatureSensor
} from './types';
import {
analogSensorItemValidation,
temperatureSensorItemValidation
} from './validators';
const Sensors = () => {
const { LL } = useI18nContext();
const { me } = useContext(AuthenticatedContext);
const [selectedTemperatureSensor, setSelectedTemperatureSensor] = useState<TemperatureSensor>();
const [selectedTemperatureSensor, setSelectedTemperatureSensor] =
useState<TemperatureSensor>();
const [selectedAnalogSensor, setSelectedAnalogSensor] = useState<AnalogSensor>();
const [temperatureDialogOpen, setTemperatureDialogOpen] = useState<boolean>(false);
const [analogDialogOpen, setAnalogDialogOpen] = useState<boolean>(false);
const [creating, setCreating] = useState<boolean>(false);
const { data: sensorData, send: fetchSensorData } = useRequest(() => EMSESP.readSensorData(), {
initialData: {
ts: [],
as: [],
analog_enabled: false,
platform: 'ESP32'
const { data: sensorData, send: fetchSensorData } = useRequest(
() => readSensorData(),
{
initialData: {
ts: [],
as: [],
analog_enabled: false,
platform: 'ESP32'
}
}
);
const { send: sendTemperatureSensor } = useRequest(
(data: WriteTemperatureSensor) => writeTemperatureSensor(data),
{
immediate: false
}
);
const { send: sendAnalogSensor } = useRequest(
(data: WriteAnalogSensor) => writeAnalogSensor(data),
{
immediate: false
}
);
useInterval(() => {
if (!temperatureDialogOpen && !analogDialogOpen) {
void fetchSensorData();
}
});
const { send: writeTemperatureSensor } = useRequest((data) => EMSESP.writeTemperatureSensor(data), {
immediate: false
});
const { send: writeAnalogSensor } = useRequest((data) => EMSESP.writeAnalogSensor(data), {
immediate: false
});
const isAdmin = me.admin;
const common_theme = useTheme({
BaseRow: `
font-size: 14px;
@@ -66,8 +105,6 @@ const DashboardSensors: FC = () => {
color: #90CAF9;
.th {
border-bottom: 1px solid #565656;
}
.th {
height: 36px;
}
`,
@@ -77,19 +114,10 @@ const DashboardSensors: FC = () => {
cursor: pointer;
.td {
padding: 8px;
border-top: 1px solid #565656;
border-bottom: 1px solid #565656;
}
&.tr.tr-body.row-select.row-select-single-selected {
background-color: #3d4752;
font-weight: normal;
}
&:hover .td {
border-top: 1px solid #177ac9;
border-bottom: 1px solid #177ac9;
}
&:nth-of-type(odd) .td {
background-color: #303030;
background-color: #177ac9;
}
`,
Cell: `
@@ -117,7 +145,57 @@ const DashboardSensors: FC = () => {
}
]);
const getSortIcon = (state: any, sortKey: any) => {
const RenderTemperatureSensors = () => (
<Table
data={{ nodes: sensorData.ts }}
theme={temperature_theme}
sort={temperature_sort}
layout={{ custom: true }}
>
{(tableList: TemperatureSensor[]) => (
<>
<Header>
<HeaderRow>
<HeaderCell resize>
<Button
fullWidth
style={{ fontSize: '14px', justifyContent: 'flex-start' }}
endIcon={getSortIcon(temperature_sort.state, 'NAME')}
onClick={() =>
temperature_sort.fns.onToggleSort({ sortKey: 'NAME' })
}
>
{LL.NAME(0)}
</Button>
</HeaderCell>
<HeaderCell stiff>
<Button
fullWidth
style={{ fontSize: '14px', justifyContent: 'flex-end' }}
endIcon={getSortIcon(temperature_sort.state, 'VALUE')}
onClick={() =>
temperature_sort.fns.onToggleSort({ sortKey: 'VALUE' })
}
>
{LL.VALUE(0)}
</Button>
</HeaderCell>
</HeaderRow>
</Header>
<Body>
{tableList.map((ts: TemperatureSensor) => (
<Row key={ts.id} item={ts} onClick={() => updateTemperatureSensor(ts)}>
<Cell>{ts.n}</Cell>
<Cell>{formatValue(ts.t, ts.u)}</Cell>
</Row>
))}
</Body>
</>
)}
</Table>
);
const getSortIcon = (state: State, sortKey: unknown) => {
if (state.sortKey === sortKey && state.reverse) {
return <KeyboardArrowDownOutlinedIcon />;
}
@@ -139,6 +217,7 @@ const DashboardSensors: FC = () => {
sortToggleType: SortToggleType.AlternateWithReset,
sortFns: {
GPIO: (array) => array.sort((a, b) => a.g - b.g),
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
NAME: (array) => array.sort((a, b) => a.n.localeCompare(b.n)),
TYPE: (array) => array.sort((a, b) => a.t - b.t),
VALUE: (array) => array.sort((a, b) => a.v - b.v)
@@ -157,18 +236,14 @@ const DashboardSensors: FC = () => {
},
sortToggleType: SortToggleType.AlternateWithReset,
sortFns: {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
NAME: (array) => array.sort((a, b) => a.n.localeCompare(b.n)),
VALUE: (array) => array.sort((a, b) => a.t - b.t)
}
}
);
useEffect(() => {
const timer = setInterval(() => fetchSensorData(), 30000);
return () => {
clearInterval(timer);
};
});
useLayoutTitle(LL.SENSORS());
const formatDurationMin = (duration_min: number) => {
const days = Math.trunc((duration_min * 60000) / 86400000);
@@ -188,10 +263,13 @@ const DashboardSensors: FC = () => {
return formatted;
};
function formatValue(value: any, uom: number) {
function formatValue(value: unknown, uom: DeviceValueUOM) {
if (value === undefined) {
return '';
}
if (typeof value !== 'number') {
return value as string;
}
switch (uom) {
case DeviceValueUOM.HOURS:
return value ? formatDurationMin(value * 60) : LL.NUM_HOURS({ num: 0 });
@@ -200,10 +278,7 @@ const DashboardSensors: FC = () => {
case DeviceValueUOM.SECONDS:
return LL.NUM_SECONDS({ num: value });
case DeviceValueUOM.NONE:
if (typeof value === 'number') {
return new Intl.NumberFormat().format(value);
}
return value;
return new Intl.NumberFormat().format(value);
case DeviceValueUOM.DEGREES:
case DeviceValueUOM.DEGREES_R:
case DeviceValueUOM.FAHRENHEIT:
@@ -220,7 +295,8 @@ const DashboardSensors: FC = () => {
}
const updateTemperatureSensor = (ts: TemperatureSensor) => {
if (isAdmin) {
if (me.admin) {
ts.o_n = ts.n;
setSelectedTemperatureSensor(ts);
setTemperatureDialogOpen(true);
}
@@ -228,26 +304,28 @@ const DashboardSensors: FC = () => {
const onTemperatureDialogClose = () => {
setTemperatureDialogOpen(false);
void fetchSensorData();
};
const onTemperatureDialogSave = async (ts: TemperatureSensor) => {
await writeTemperatureSensor({ id: ts.id, name: ts.n, offset: ts.o })
await sendTemperatureSensor({ id: ts.id, name: ts.n, offset: ts.o })
.then(() => {
toast.success(LL.UPDATED_OF(LL.SENSOR(1)));
})
.catch(() => {
toast.error(LL.UPDATE_OF(LL.SENSOR(2)) + ' ' + LL.FAILED(1));
})
.finally(async () => {
.finally(() => {
setTemperatureDialogOpen(false);
setSelectedTemperatureSensor(undefined);
await fetchSensorData();
void fetchSensorData();
});
};
const updateAnalogSensor = (as: AnalogSensor) => {
if (isAdmin) {
if (me.admin) {
setCreating(false);
as.o_n = as.n;
setSelectedAnalogSensor(as);
setAnalogDialogOpen(true);
}
@@ -255,6 +333,7 @@ const DashboardSensors: FC = () => {
const onAnalogDialogClose = () => {
setAnalogDialogOpen(false);
void fetchSensorData();
};
const addAnalogSensor = () => {
@@ -268,13 +347,14 @@ const DashboardSensors: FC = () => {
o: 0,
t: 0,
f: 1,
d: false
d: false,
o_n: ''
});
setAnalogDialogOpen(true);
};
const onAnalogDialogSave = async (as: AnalogSensor) => {
await writeAnalogSensor({
await sendAnalogSensor({
id: as.id,
gpio: as.g,
name: as.n,
@@ -290,57 +370,21 @@ const DashboardSensors: FC = () => {
.catch(() => {
toast.error(LL.UPDATE_OF(LL.ANALOG_SENSOR(5)) + ' ' + LL.FAILED(1));
})
.finally(async () => {
.finally(() => {
setAnalogDialogOpen(false);
setSelectedAnalogSensor(undefined);
await fetchSensorData();
void fetchSensorData();
});
};
const RenderTemperatureSensors = () => (
<Table data={{ nodes: sensorData.ts }} theme={temperature_theme} sort={temperature_sort} layout={{ custom: true }}>
{(tableList: any) => (
<>
<Header>
<HeaderRow>
<HeaderCell resize>
<Button
fullWidth
style={{ fontSize: '14px', justifyContent: 'flex-start' }}
endIcon={getSortIcon(temperature_sort.state, 'NAME')}
onClick={() => temperature_sort.fns.onToggleSort({ sortKey: 'NAME' })}
>
{LL.NAME(0)}
</Button>
</HeaderCell>
<HeaderCell stiff>
<Button
fullWidth
style={{ fontSize: '14px', justifyContent: 'flex-end' }}
endIcon={getSortIcon(temperature_sort.state, 'VALUE')}
onClick={() => temperature_sort.fns.onToggleSort({ sortKey: 'VALUE' })}
>
{LL.VALUE(0)}
</Button>
</HeaderCell>
</HeaderRow>
</Header>
<Body>
{tableList.map((ts: TemperatureSensor) => (
<Row key={ts.id} item={ts} onClick={() => updateTemperatureSensor(ts)}>
<Cell>{ts.n}</Cell>
<Cell>{formatValue(ts.t, ts.u)}</Cell>
</Row>
))}
</Body>
</>
)}
</Table>
);
const RenderAnalogSensors = () => (
<Table data={{ nodes: sensorData.as }} theme={analog_theme} sort={analog_sort} layout={{ custom: true }}>
{(tableList: any) => (
<Table
data={{ nodes: sensorData.as }}
theme={analog_theme}
sort={analog_sort}
layout={{ custom: true }}
>
{(tableList: AnalogSensor[]) => (
<>
<Header>
<HeaderRow>
@@ -392,7 +436,9 @@ const DashboardSensors: FC = () => {
<Cell stiff>{a.g}</Cell>
<Cell>{a.n}</Cell>
<Cell stiff>{AnalogTypeNames[a.t]} </Cell>
{a.t === AnalogType.DIGITAL_OUT || a.t === AnalogType.DIGITAL_IN ? (
{(a.t === AnalogType.DIGITAL_OUT && a.g !== 25 && a.g !== 26) ||
a.t === AnalogType.DIGITAL_IN ||
a.t === AnalogType.PULSE ? (
<Cell stiff>{a.v ? LL.ON() : LL.OFF()}</Cell>
) : (
<Cell stiff>{a.t ? formatValue(a.v, a.u) : ''}</Cell>
@@ -406,65 +452,56 @@ const DashboardSensors: FC = () => {
);
return (
<SectionContent title={LL.SENSOR_DATA()} titleGutter>
{sensorData.ts.length > 0 && (
<>
<Typography sx={{ pt: 2, pb: 1 }} variant="h6" color="secondary">
{LL.TEMP_SENSORS()}
</Typography>
<RenderTemperatureSensors />
{selectedTemperatureSensor && (
<DashboardSensorsTemperatureDialog
open={temperatureDialogOpen}
onClose={onTemperatureDialogClose}
onSave={onTemperatureDialogSave}
selectedItem={selectedTemperatureSensor}
validator={temperatureSensorItemValidation()}
/>
<SectionContent>
<Typography sx={{ pb: 1 }} variant="h6" color="secondary">
{LL.TEMP_SENSORS()}
</Typography>
<RenderTemperatureSensors />
{selectedTemperatureSensor && (
<DashboardSensorsTemperatureDialog
open={temperatureDialogOpen}
onClose={onTemperatureDialogClose}
onSave={onTemperatureDialogSave}
selectedItem={selectedTemperatureSensor}
validator={temperatureSensorItemValidation(
sensorData.ts,
selectedTemperatureSensor
)}
</>
/>
)}
{sensorData?.analog_enabled === true && (
<>
<Typography sx={{ pt: 4, pb: 1 }} variant="h6" color="secondary">
{LL.ANALOG_SENSORS()}
</Typography>
<RenderAnalogSensors />
{selectedAnalogSensor && (
<DashboardSensorsAnalogDialog
open={analogDialogOpen}
onClose={onAnalogDialogClose}
onSave={onAnalogDialogSave}
creating={creating}
selectedItem={selectedAnalogSensor}
validator={analogSensorItemValidation(sensorData.as, creating, sensorData.platform)}
/>
<Typography sx={{ pt: 4, pb: 1 }} variant="h6" color="secondary">
{LL.ANALOG_SENSORS()}
</Typography>
<RenderAnalogSensors />
{selectedAnalogSensor && (
<DashboardSensorsAnalogDialog
open={analogDialogOpen}
onClose={onAnalogDialogClose}
onSave={onAnalogDialogSave}
creating={creating}
selectedItem={selectedAnalogSensor}
validator={analogSensorItemValidation(
sensorData.as,
selectedAnalogSensor,
creating,
sensorData.platform
)}
</>
/>
)}
<ButtonRow>
<Box mt={2} display="flex" flexWrap="wrap">
<Box flexGrow={1}>
<Button startIcon={<RefreshIcon />} variant="outlined" color="secondary" onClick={fetchSensorData}>
{LL.REFRESH()}
</Button>
</Box>
{sensorData?.analog_enabled === true && (
<Button
variant="outlined"
color="primary"
startIcon={<AddCircleOutlineOutlinedIcon />}
onClick={addAnalogSensor}
>
{LL.ADD(0) + ' ' + LL.ANALOG_SENSOR(1)}
</Button>
)}
{sensorData?.analog_enabled === true && me.admin && (
<Box mt={2} display="flex" flexWrap="wrap" justifyContent="flex-end">
<Button
variant="outlined"
color="primary"
startIcon={<AddCircleOutlineOutlinedIcon />}
onClick={addAnalogSensor}
>
{LL.ADD(0)}
</Button>
</Box>
</ButtonRow>
)}
</SectionContent>
);
};
export default DashboardSensors;
export default Sensors;

View File

@@ -0,0 +1,428 @@
import { useEffect, useState } from 'react';
import CancelIcon from '@mui/icons-material/Cancel';
import RemoveIcon from '@mui/icons-material/RemoveCircleOutline';
import WarningIcon from '@mui/icons-material/Warning';
import {
Box,
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
Grid,
InputAdornment,
MenuItem,
TextField,
Typography
} from '@mui/material';
import { dialogStyle } from 'CustomTheme';
import type Schema from 'async-validator';
import type { ValidateFieldsError } from 'async-validator';
import { ValidatedTextField } from 'components';
import { useI18nContext } from 'i18n/i18n-react';
import { numberValue, updateValue } from 'utils';
import { validate } from 'validators';
import { AnalogType, AnalogTypeNames, DeviceValueUOM_s } from './types';
import type { AnalogSensor } from './types';
interface DashboardSensorsAnalogDialogProps {
open: boolean;
onClose: () => void;
onSave: (as: AnalogSensor) => void;
creating: boolean;
selectedItem: AnalogSensor;
validator: Schema;
}
const SensorsAnalogDialog = ({
open,
onClose,
onSave,
creating,
selectedItem,
validator
}: DashboardSensorsAnalogDialogProps) => {
const { LL } = useI18nContext();
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
const [editItem, setEditItem] = useState<AnalogSensor>(selectedItem);
const updateFormValue = updateValue(setEditItem);
useEffect(() => {
if (open) {
setFieldErrors(undefined);
setEditItem(selectedItem);
}
}, [open, selectedItem]);
const handleClose = (
_event: React.SyntheticEvent,
reason: 'backdropClick' | 'escapeKeyDown'
) => {
if (reason !== 'backdropClick') {
onClose();
}
};
const save = async () => {
try {
setFieldErrors(undefined);
await validate(validator, editItem);
onSave(editItem);
} catch (error) {
setFieldErrors(error as ValidateFieldsError);
}
};
const remove = () => {
editItem.d = true;
onSave(editItem);
};
return (
<Dialog sx={dialogStyle} open={open} onClose={handleClose}>
<DialogTitle>
{creating ? LL.ADD(1) + ' ' + LL.NEW(0) : LL.EDIT()}&nbsp;
{LL.ANALOG_SENSOR(0)}
</DialogTitle>
<DialogContent dividers>
<Grid container spacing={2}>
<Grid>
<ValidatedTextField
fieldErrors={fieldErrors || {}}
name="g"
label="GPIO"
sx={{ width: '11ch' }}
value={numberValue(editItem.g)}
type="number"
variant="outlined"
onChange={updateFormValue}
/>
</Grid>
{creating && (
<Grid>
<Box color="warning.main" mt={2}>
<Typography variant="body2">{LL.WARN_GPIO()}</Typography>
</Box>
</Grid>
)}
<Grid>
<ValidatedTextField
fieldErrors={fieldErrors || {}}
name="n"
label={LL.NAME(0)}
value={editItem.n}
fullWidth
variant="outlined"
onChange={updateFormValue}
/>
</Grid>
<Grid>
<TextField
name="t"
label={LL.TYPE(0)}
value={editItem.t}
fullWidth
select
onChange={updateFormValue}
>
{AnalogTypeNames.map((val, i) => (
<MenuItem key={val} value={i}>
{val}
</MenuItem>
))}
</TextField>
</Grid>
{((editItem.t >= AnalogType.COUNTER && editItem.t <= AnalogType.RATE) ||
(editItem.t >= AnalogType.FREQ_0 &&
editItem.t <= AnalogType.FREQ_2)) && (
<Grid>
<TextField
name="u"
label={LL.UNIT()}
value={editItem.u}
sx={{ width: '15ch' }}
select
onChange={updateFormValue}
>
{DeviceValueUOM_s.map((val, i) => (
<MenuItem key={val} value={i}>
{val}
</MenuItem>
))}
</TextField>
</Grid>
)}
{editItem.t === AnalogType.ADC && (
<Grid>
<TextField
name="o"
label={LL.OFFSET()}
value={numberValue(editItem.o)}
type="number"
sx={{ width: '11ch' }}
variant="outlined"
onChange={updateFormValue}
slotProps={{
input: {
startAdornment: (
<InputAdornment position="start">mV</InputAdornment>
)
},
htmlInput: { min: '0', max: '3300', step: '1' }
}}
/>
</Grid>
)}
{editItem.t === AnalogType.NTC && (
<Grid>
<TextField
name="o"
label={LL.OFFSET()}
value={numberValue(editItem.o)}
sx={{ width: '11ch' }}
type="number"
variant="outlined"
onChange={updateFormValue}
slotProps={{
input: {
startAdornment: (
<InputAdornment position="start">°C</InputAdornment>
)
},
htmlInput: { min: '-20', max: '20', step: '0.1' }
}}
/>
</Grid>
)}
{editItem.t === AnalogType.COUNTER && (
<Grid>
<TextField
name="o"
label={LL.STARTVALUE()}
value={numberValue(editItem.o)}
type="number"
sx={{ width: '11ch' }}
variant="outlined"
onChange={updateFormValue}
slotProps={{
htmlInput: { step: '0.001' }
}}
/>
</Grid>
)}
{editItem.t === AnalogType.RGB && (
<Grid>
<TextField
name="o"
label={'RGB ' + LL.VALUE(0)}
value={numberValue(editItem.o)}
type="number"
sx={{ width: '11ch' }}
variant="outlined"
onChange={updateFormValue}
/>
</Grid>
)}
{editItem.t >= AnalogType.COUNTER && editItem.t <= AnalogType.RATE && (
<Grid>
<TextField
name="f"
label={LL.FACTOR()}
value={numberValue(editItem.f)}
sx={{ width: '11ch' }}
type="number"
variant="outlined"
onChange={updateFormValue}
slotProps={{
htmlInput: { step: '0.001' }
}}
/>
</Grid>
)}
{editItem.t === AnalogType.DIGITAL_OUT &&
(editItem.g === 25 || editItem.g === 26) && (
<Grid>
<TextField
name="o"
label={LL.VALUE(0)}
value={numberValue(editItem.o)}
sx={{ width: '11ch' }}
type="number"
variant="outlined"
onChange={updateFormValue}
slotProps={{
htmlInput: { min: '0', max: '255', step: '1' }
}}
/>
</Grid>
)}
{editItem.t === AnalogType.DIGITAL_OUT &&
editItem.g !== 25 &&
editItem.g !== 26 && (
<>
<Grid>
<TextField
name="o"
label={LL.VALUE(0)}
value={numberValue(editItem.o)}
select
variant="outlined"
onChange={updateFormValue}
>
<MenuItem value={0}>{LL.OFF()}</MenuItem>
<MenuItem value={1}>{LL.ON()}</MenuItem>
</TextField>
</Grid>
<Grid>
<TextField
name="f"
label={LL.POLARITY()}
value={editItem.f}
sx={{ width: '15ch' }}
select
onChange={updateFormValue}
>
<MenuItem value={1}>{LL.ACTIVEHIGH()}</MenuItem>
<MenuItem value={-1}>{LL.ACTIVELOW()}</MenuItem>
</TextField>
</Grid>
<Grid>
<TextField
name="u"
label={LL.STARTVALUE()}
sx={{ width: '15ch' }}
value={editItem.u}
select
onChange={updateFormValue}
>
<MenuItem value={0}>{LL.UNCHANGED()}</MenuItem>
<MenuItem value={1}>
{LL.ALWAYS()}&nbsp;{LL.OFF()}
</MenuItem>
<MenuItem value={2}>
{LL.ALWAYS()}&nbsp;{LL.ON()}
</MenuItem>
</TextField>
</Grid>
</>
)}
{(editItem.t === AnalogType.PWM_0 ||
editItem.t === AnalogType.PWM_1 ||
editItem.t === AnalogType.PWM_2) && (
<>
<Grid>
<TextField
name="f"
label={LL.FREQ()}
value={numberValue(editItem.f)}
type="number"
variant="outlined"
sx={{ width: '11ch' }}
onChange={updateFormValue}
slotProps={{
input: {
startAdornment: (
<InputAdornment position="start">Hz</InputAdornment>
)
},
htmlInput: { min: '1', max: '5000', step: '1' }
}}
/>
</Grid>
<Grid>
<TextField
name="o"
label={LL.DUTY_CYCLE()}
value={numberValue(editItem.o)}
type="number"
sx={{ width: '11ch' }}
variant="outlined"
onChange={updateFormValue}
slotProps={{
input: {
startAdornment: (
<InputAdornment position="start">%</InputAdornment>
)
},
htmlInput: { min: '0', max: '100', step: '0.1' }
}}
/>
</Grid>
</>
)}
{editItem.t === AnalogType.PULSE && (
<>
<Grid>
<TextField
name="o"
label={LL.POLARITY()}
value={editItem.o}
sx={{ width: '11ch' }}
select
onChange={updateFormValue}
>
<MenuItem value={0}>{LL.ACTIVEHIGH()}</MenuItem>
<MenuItem value={1}>{LL.ACTIVELOW()}</MenuItem>
</TextField>
</Grid>
<Grid>
<TextField
name="f"
label="Pulse"
value={numberValue(editItem.f)}
type="number"
sx={{ width: '15ch' }}
variant="outlined"
onChange={updateFormValue}
slotProps={{
input: {
startAdornment: (
<InputAdornment position="start">s</InputAdornment>
)
},
htmlInput: { min: '0', max: '10000', step: '0.1' }
}}
/>
</Grid>
</>
)}
</Grid>
</DialogContent>
<DialogActions>
{!creating && (
<Box flexGrow={1} sx={{ '& button': { mt: 0 } }}>
<Button
startIcon={<RemoveIcon />}
variant="outlined"
color="warning"
onClick={remove}
>
{LL.REMOVE()}
</Button>
</Box>
)}
<Button
startIcon={<CancelIcon />}
variant="outlined"
onClick={onClose}
color="secondary"
>
{LL.CANCEL()}
</Button>
<Button
startIcon={<WarningIcon color="warning" />}
variant="outlined"
onClick={save}
color="primary"
>
{creating ? LL.ADD(0) : LL.UPDATE()}
</Button>
</DialogActions>
</Dialog>
);
};
export default SensorsAnalogDialog;

View File

@@ -1,46 +1,45 @@
import { useEffect, useState } from 'react';
import CancelIcon from '@mui/icons-material/Cancel';
import WarningIcon from '@mui/icons-material/Warning';
import {
Button,
Typography,
Box,
Button,
Dialog,
DialogTitle,
DialogContent,
DialogActions,
InputAdornment,
DialogContent,
DialogTitle,
Grid,
TextField
InputAdornment,
TextField,
Typography
} from '@mui/material';
import { useState, useEffect } from 'react';
import type { TemperatureSensor } from './types';
import { dialogStyle } from 'CustomTheme';
import type Schema from 'async-validator';
import type { ValidateFieldsError } from 'async-validator';
import { dialogStyle } from 'CustomTheme';
import { ValidatedTextField } from 'components';
import { useI18nContext } from 'i18n/i18n-react';
import { numberValue, updateValue } from 'utils';
import { validate } from 'validators';
type DashboardSensorsTemperatureDialogProps = {
import type { TemperatureSensor } from './types';
interface SensorsTemperatureDialogProps {
open: boolean;
onClose: () => void;
onSave: (ts: TemperatureSensor) => void;
selectedItem: TemperatureSensor;
validator: Schema;
};
}
const DashboardSensorsTemperatureDialog = ({
const SensorsTemperatureDialog = ({
open,
onClose,
onSave,
selectedItem,
validator
}: DashboardSensorsTemperatureDialogProps) => {
}: SensorsTemperatureDialogProps) => {
const { LL } = useI18nContext();
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
const [editItem, setEditItem] = useState<TemperatureSensor>(selectedItem);
@@ -53,8 +52,13 @@ const DashboardSensorsTemperatureDialog = ({
}
}, [open, selectedItem]);
const close = () => {
onClose();
const handleClose = (
_event: React.SyntheticEvent,
reason: 'backdropClick' | 'escapeKeyDown'
) => {
if (reason !== 'backdropClick') {
onClose();
}
};
const save = async () => {
@@ -62,13 +66,13 @@ const DashboardSensorsTemperatureDialog = ({
setFieldErrors(undefined);
await validate(validator, editItem);
onSave(editItem);
} catch (errors: any) {
setFieldErrors(errors);
} catch (error) {
setFieldErrors(error as ValidateFieldsError);
}
};
return (
<Dialog sx={dialogStyle} open={open} onClose={close}>
<Dialog sx={dialogStyle} open={open} onClose={handleClose}>
<DialogTitle>
{LL.EDIT()}&nbsp;{LL.TEMP_SENSOR()}
</DialogTitle>
@@ -78,40 +82,53 @@ const DashboardSensorsTemperatureDialog = ({
{LL.ID_OF(LL.SENSOR(0))}: {editItem.id}
</Typography>
</Box>
<Grid container spacing={1}>
<Grid item>
<Grid container spacing={2}>
<Grid>
<ValidatedTextField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
name="n"
label={LL.NAME(0)}
value={editItem.n}
autoFocus
sx={{ width: '30ch' }}
onChange={updateFormValue}
/>
</Grid>
<Grid item>
<Grid>
<TextField
name="o"
label={LL.OFFSET()}
value={numberValue(editItem.o)}
sx={{ width: '12ch' }}
sx={{ width: '11ch' }}
type="number"
variant="outlined"
onChange={updateFormValue}
inputProps={{ min: '-5', max: '5', step: '0.1' }}
InputProps={{
startAdornment: <InputAdornment position="start">°C</InputAdornment>
slotProps={{
input: {
startAdornment: (
<InputAdornment position="start">°C</InputAdornment>
)
},
htmlInput: { min: '-5', max: '5', step: '0.1' }
}}
/>
</Grid>
</Grid>
</DialogContent>
<DialogActions>
<Button startIcon={<CancelIcon />} variant="outlined" onClick={close} color="secondary">
<Button
startIcon={<CancelIcon />}
variant="outlined"
onClick={onClose}
color="secondary"
>
{LL.CANCEL()}
</Button>
<Button startIcon={<WarningIcon color="warning" />} variant="contained" onClick={save} color="info">
<Button
startIcon={<WarningIcon color="warning" />}
variant="outlined"
onClick={save}
color="primary"
>
{LL.UPDATE()}
</Button>
</DialogActions>
@@ -119,4 +136,4 @@ const DashboardSensorsTemperatureDialog = ({
);
};
export default DashboardSensorsTemperatureDialog;
export default SensorsTemperatureDialog;

View File

@@ -1,6 +1,7 @@
import { DeviceValueUOM, DeviceValueUOM_s } from './types';
import type { TranslationFunctions } from 'i18n/i18n-types';
import { DeviceValueUOM, DeviceValueUOM_s } from './types';
const formatDurationMin = (LL: TranslationFunctions, duration_min: number) => {
const days = Math.trunc((duration_min * 60000) / 86400000);
const hours = Math.trunc((duration_min * 60000) / 3600000) % 24;
@@ -24,10 +25,23 @@ const formatDurationMin = (LL: TranslationFunctions, duration_min: number) => {
return formatted;
};
export function formatValue(LL: TranslationFunctions, value: any, uom: number) {
if (value === undefined) {
return '';
export function formatValue(
LL: TranslationFunctions,
value?: unknown,
uom?: DeviceValueUOM
) {
if (typeof value !== 'number' || uom === undefined || value === undefined) {
if (value === undefined || typeof value === 'boolean') {
return '';
}
return (
(value as string) +
(value === '' || uom === undefined || uom === 0
? ''
: ' ' + DeviceValueUOM_s[uom])
);
}
switch (uom) {
case DeviceValueUOM.HOURS:
return value ? formatDurationMin(LL, value * 60) : LL.NUM_HOURS({ num: 0 });
@@ -36,10 +50,7 @@ export function formatValue(LL: TranslationFunctions, value: any, uom: number) {
case DeviceValueUOM.SECONDS:
return LL.NUM_SECONDS({ num: value });
case DeviceValueUOM.NONE:
if (typeof value === 'number') {
return new Intl.NumberFormat().format(value);
}
return value;
return new Intl.NumberFormat().format(value);
case DeviceValueUOM.DEGREES:
case DeviceValueUOM.DEGREES_R:
case DeviceValueUOM.FAHRENHEIT:

View File

@@ -8,16 +8,20 @@ export interface Settings {
syslog_host: string;
syslog_port: number;
boiler_heatingoff: boolean;
remote_timeout_en: boolean;
remote_timeout: number;
shower_timer: boolean;
shower_alert: boolean;
shower_alert_coldshot: number;
shower_alert_trigger: number;
shower_min_duration: number;
rx_gpio: number;
tx_gpio: number;
telnet_enabled: boolean;
dallas_gpio: number;
dallas_parasite: boolean;
led_gpio: number;
led_type: number;
hide_led: boolean;
low_clock: boolean;
notoken_api: boolean;
@@ -35,6 +39,11 @@ export interface Settings {
eth_phy_addr: number;
eth_clock_mode: number;
platform: string;
modbus_enabled: boolean;
modbus_port: number;
modbus_max_clients: number;
modbus_timeout: number;
developer_mode: boolean;
}
export enum busConnectionStatus {
@@ -50,13 +59,7 @@ export interface Stat {
q: number; // quality
}
export interface Status {
status: busConnectionStatus;
tx_mode: number;
uptime: number;
num_devices: number;
num_sensors: number;
num_analogs: number;
export interface Activity {
stats: Stat[];
}
@@ -69,7 +72,8 @@ export interface Device {
d: number; // deviceid
p: number; // productid
v: string; // version
e: number; // entities
e: number; // total number of entities
url?: string; // lowercase type name used in API URL
}
export interface TemperatureSensor {
@@ -78,6 +82,7 @@ export interface TemperatureSensor {
t?: number; // temp, optional
o: number; // offset
u: number; // uom
o_n?: string;
}
export interface AnalogSensor {
@@ -90,6 +95,7 @@ export interface AnalogSensor {
f: number;
t: number;
d: boolean; // deleted flag
o_n?: string;
}
export interface WriteTemperatureSensor {
@@ -110,23 +116,23 @@ export interface CoreData {
devices: Device[];
}
export interface DeviceShort {
i: number; // id
d?: number; // deviceid
p?: number; // productid
s: string; // shortname
t?: number; // device type id
tn?: string; // device type internal name
export interface DashboardItem {
id: number; // unique index
t?: number; // type from DeviceType
n?: string; // name, optional
dv?: DeviceValue; // device value, optional
nodes?: DashboardItem[]; // children nodes, optional
}
export interface Devices {
devices: DeviceShort[];
export interface DashboardData {
connected: boolean; // true if connected to EMS bus
nodes: DashboardItem[];
}
export interface DeviceValue {
id: string; // index, contains mask+name
v: any; // value, Number or String
u: number; // uom
v?: unknown; // value, Number, String or Boolean - can be undefined
u?: number; // uom, optional
c?: string; // command, optional
l?: string[]; // list, optional
h?: string; // help text, optional
@@ -134,16 +140,18 @@ export interface DeviceValue {
m?: number; // min, optional
x?: number; // max, optional
}
export interface DeviceData {
data: DeviceValue[];
nodes: DeviceValue[];
}
export interface DeviceEntity {
id: string; // shortname
v?: any; // value, in any format, optional
v?: unknown; // value, in any format, optional
n?: string; // fullname, optional
cn?: string; // custom fullname, optional
m: number; // mask
t?: string; // tag for name
m: DeviceEntityMask; // mask
w: boolean; // writeable
mi?: number; // min value
ma?: number; // max value
@@ -178,7 +186,10 @@ export enum DeviceValueUOM {
KMIN,
K,
VOLTS,
MBAR
MBAR,
LH,
CTKWH,
HZ
}
export const DeviceValueUOM_s = [
@@ -206,45 +217,59 @@ export const DeviceValueUOM_s = [
'K*min',
'K',
'V',
'mbar'
'mbar',
'l/h',
'ct/kWh',
'Hz'
];
export enum AnalogType {
REMOVED = -1,
NOTUSED = 0,
DIGITAL_IN,
COUNTER,
ADC,
TIMER,
RATE,
DIGITAL_OUT,
PWM_0,
PWM_1,
PWM_2
DIGITAL_IN = 1,
COUNTER = 2,
ADC = 3,
TIMER = 4,
RATE = 5,
DIGITAL_OUT = 6,
PWM_0 = 7,
PWM_1 = 8,
PWM_2 = 9,
NTC = 10,
RGB = 11,
PULSE = 12,
FREQ_0 = 13,
FREQ_1 = 14,
FREQ_2 = 15
}
export const AnalogTypeNames = [
'(disabled)',
'Digital In',
'Counter',
'ADC',
'ADC In',
'Timer',
'Rate',
'Digital Out',
'PWM 0',
'PWM 1',
'PWM 2'
'PWM 2',
'NTC Temp.',
'RGB Led',
'Pulse',
'Freq 0',
'Freq 1',
'Freq 2'
];
type BoardProfiles = {
[name: string]: string;
};
type BoardProfiles = Record<string, string>;
export const BOARD_PROFILES: BoardProfiles = {
S32: 'BBQKees Gateway S32',
S32S3: 'BBQKees Gateway S3',
E32: 'BBQKees Gateway E32',
E32V2: 'BBQKees Gateway E32 V2',
E32V2_2: 'BBQKees Gateway E32 V2.2',
NODEMCU: 'NodeMCU 32S',
'MH-ET': 'MH-ET Live D1 Mini',
LOLIN: 'Lolin D32',
@@ -258,6 +283,7 @@ export const BOARD_PROFILES: BoardProfiles = {
export interface BoardProfile {
board_profile: string;
led_gpio: number;
led_type: number;
dallas_gpio: number;
rx_gpio: number;
tx_gpio: number;
@@ -270,9 +296,16 @@ export interface BoardProfile {
export interface APIcall {
device: string;
entity: string;
id: any;
cmd: string;
id: number;
data?: string; // optional
}
export interface Action {
action: string;
param?: string; // optional
}
export interface WriteAnalogSensor {
id: number;
gpio: number;
@@ -296,12 +329,12 @@ export enum DeviceEntityMask {
export interface ScheduleItem {
id: number; // unique index
active: boolean;
deleted?: boolean; // optional
deleted?: boolean;
flags: number;
time: string;
time: string; // also used for Condition and On Change
cmd: string;
value: string;
name: string; // optional
name: string; // can be empty
o_id?: number;
o_active?: boolean;
o_deleted?: boolean;
@@ -312,6 +345,28 @@ export interface ScheduleItem {
o_name?: string;
}
export interface Schedule {
schedule: ScheduleItem[];
}
export interface ModuleItem {
id: number; // unique index
key: string;
name: string;
author: string;
version: string;
status: number;
message: string;
enabled: boolean;
license: string;
o_enabled?: boolean;
o_license?: string;
}
export interface Modules {
modules: ModuleItem[];
}
export enum ScheduleFlag {
SCHEDULE_SUN = 1,
SCHEDULE_MON = 2,
@@ -320,7 +375,12 @@ export enum ScheduleFlag {
SCHEDULE_THU = 16,
SCHEDULE_FRI = 32,
SCHEDULE_SAT = 64,
SCHEDULE_TIMER = 128
// types...
SCHEDULE_DAY = 0, // no bits set
SCHEDULE_TIMER = 128, // bit 8
SCHEDULE_ONCHANGE = 129, // bit 1
SCHEDULE_CONDITION = 130, // bit 2
SCHEDULE_IMMEDIATE = 132 // bit 3
}
export interface EntityItem {
@@ -330,11 +390,12 @@ export interface EntityItem {
device_id: number | string;
type_id: number | string;
offset: number;
factor: number;
factor: number | string;
uom: number;
value_type: number;
value?: any;
value?: unknown;
writeable: boolean;
hide: boolean;
deleted?: boolean;
o_id?: number;
o_ram?: number;
@@ -342,12 +403,13 @@ export interface EntityItem {
o_device_id?: number | string;
o_type_id?: number | string;
o_offset?: number;
o_factor?: number;
o_factor?: number | string;
o_uom?: number;
o_value_type?: number;
o_deleted?: boolean;
o_writeable?: boolean;
o_value?: any;
o_value?: unknown;
o_hide?: boolean;
}
export interface Entities {
@@ -357,9 +419,10 @@ export interface Entities {
// matches emsdevice.h DeviceType
export const enum DeviceType {
SYSTEM = 0,
TEMPERATURESENSOR,
ANALOGSENSOR,
SCHEDULER,
TEMPERATURESENSOR = 1,
ANALOGSENSOR = 2,
SCHEDULER = 3,
CUSTOM = 4,
BOILER,
THERMOSTAT,
MIXER,
@@ -373,33 +436,36 @@ export const enum DeviceType {
EXTENSION,
GENERIC,
HEATSOURCE,
CUSTOM,
VENTILATION,
WATER,
POOL,
UNKNOWN
}
// matches emsdevicevalue.h
export const enum DeviceValueType {
BOOL,
INT,
UINT,
SHORT,
USHORT,
ULONG,
TIME, // same as ULONG (32 bits)
INT8,
UINT8,
INT16,
UINT16,
UINT24,
TIME, // same as UINT24
UINT32,
ENUM,
STRING,
STRING, // RAW
CMD
}
export const DeviceValueTypeNames = [
//
'BOOL',
'INT',
'UINT',
'SHORT',
'USHORT',
'ULONG',
'INT8',
'UINT8',
'INT16',
'UINT16',
'UINT24',
'TIME',
'UINT32',
'ENUM',
'RAW',
'CMD'

View File

@@ -0,0 +1,501 @@
import Schema from 'async-validator';
import type { InternalRuleItem } from 'async-validator';
import { IP_OR_HOSTNAME_VALIDATOR } from 'validators/shared';
import type {
AnalogSensor,
DeviceValue,
EntityItem,
ScheduleItem,
Settings,
TemperatureSensor
} from './types';
export const GPIO_VALIDATOR = {
validator(
_rule: InternalRuleItem,
value: number,
callback: (error?: string) => void
) {
if (
value &&
(value === 1 ||
(value >= 6 && value <= 11) ||
value === 20 ||
value === 24 ||
(value >= 28 && value <= 31) ||
value > 40 ||
value < 0)
) {
callback('Must be an valid GPIO port');
} else {
callback();
}
}
};
export const GPIO_VALIDATORR = {
validator(
_rule: InternalRuleItem,
value: number,
callback: (error?: string) => void
) {
if (
value &&
(value === 1 ||
(value >= 6 && value <= 11) ||
(value >= 16 && value <= 17) ||
value === 20 ||
value === 24 ||
(value >= 28 && value <= 31) ||
value > 40 ||
value < 0)
) {
callback('Must be an valid GPIO port');
} else {
callback();
}
}
};
export const GPIO_VALIDATORC3 = {
validator(
_rule: InternalRuleItem,
value: number,
callback: (error?: string) => void
) {
if (value && ((value >= 11 && value <= 19) || value > 21 || value < 0)) {
callback('Must be an valid GPIO port');
} else {
callback();
}
}
};
export const GPIO_VALIDATORS2 = {
validator(
_rule: InternalRuleItem,
value: number,
callback: (error?: string) => void
) {
if (
value &&
((value >= 19 && value <= 20) ||
(value >= 22 && value <= 32) ||
value > 40 ||
value < 0)
) {
callback('Must be an valid GPIO port');
} else {
callback();
}
}
};
export const GPIO_VALIDATORS3 = {
validator(
_rule: InternalRuleItem,
value: number,
callback: (error?: string) => void
) {
if (
value &&
((value >= 19 && value <= 20) ||
(value >= 22 && value <= 37) ||
(value >= 39 && value <= 42) ||
value > 48 ||
value < 0)
) {
callback('Must be an valid GPIO port');
} else {
callback();
}
}
};
export const createSettingsValidator = (settings: Settings) =>
new Schema({
...(settings.board_profile === 'CUSTOM' &&
settings.platform === 'ESP32' && {
led_gpio: [
{ required: true, message: 'LED GPIO is required' },
GPIO_VALIDATOR
],
dallas_gpio: [
{ required: true, message: 'GPIO is required' },
GPIO_VALIDATOR
],
pbutton_gpio: [
{ required: true, message: 'Button GPIO is required' },
GPIO_VALIDATOR
],
tx_gpio: [
{ required: true, message: 'Tx GPIO is required' },
GPIO_VALIDATOR
],
rx_gpio: [{ required: true, message: 'Rx GPIO is required' }, GPIO_VALIDATOR]
}),
...(settings.board_profile === 'CUSTOM' &&
settings.platform === 'ESP32C3' && {
led_gpio: [
{ required: true, message: 'LED GPIO is required' },
GPIO_VALIDATORC3
],
dallas_gpio: [
{ required: true, message: 'GPIO is required' },
GPIO_VALIDATORC3
],
pbutton_gpio: [
{ required: true, message: 'Button GPIO is required' },
GPIO_VALIDATORC3
],
tx_gpio: [
{ required: true, message: 'Tx GPIO is required' },
GPIO_VALIDATORC3
],
rx_gpio: [
{ required: true, message: 'Rx GPIO is required' },
GPIO_VALIDATORC3
]
}),
...(settings.board_profile === 'CUSTOM' &&
settings.platform === 'ESP32S2' && {
led_gpio: [
{ required: true, message: 'LED GPIO is required' },
GPIO_VALIDATORS2
],
dallas_gpio: [
{ required: true, message: 'GPIO is required' },
GPIO_VALIDATORS2
],
pbutton_gpio: [
{ required: true, message: 'Button GPIO is required' },
GPIO_VALIDATORS2
],
tx_gpio: [
{ required: true, message: 'Tx GPIO is required' },
GPIO_VALIDATORS2
],
rx_gpio: [
{ required: true, message: 'Rx GPIO is required' },
GPIO_VALIDATORS2
]
}),
...(settings.board_profile === 'CUSTOM' &&
settings.platform === 'ESP32S3' && {
led_gpio: [
{ required: true, message: 'LED GPIO is required' },
GPIO_VALIDATORS3
],
dallas_gpio: [
{ required: true, message: 'GPIO is required' },
GPIO_VALIDATORS3
],
pbutton_gpio: [
{ required: true, message: 'Button GPIO is required' },
GPIO_VALIDATORS3
],
tx_gpio: [
{ required: true, message: 'Tx GPIO is required' },
GPIO_VALIDATORS3
],
rx_gpio: [
{ required: true, message: 'Rx GPIO is required' },
GPIO_VALIDATORS3
]
}),
...(settings.syslog_enabled && {
syslog_host: [
{ required: true, message: 'Host is required' },
IP_OR_HOSTNAME_VALIDATOR
],
syslog_port: [
{ required: true, message: 'Port is required' },
{ type: 'number', min: 0, max: 65535, message: 'Invalid Port' }
],
syslog_mark_interval: [
{ required: true, message: 'Mark interval is required' },
{ type: 'number', min: 0, max: 10, message: 'Must be between 0 and 10' }
]
}),
...(settings.modbus_enabled && {
modbus_max_clients: [
{ required: true, message: 'Max clients is required' },
{ type: 'number', min: 0, max: 50, message: 'Invalid number' }
],
modbus_port: [
{ required: true, message: 'Port is required' },
{ type: 'number', min: 0, max: 65535, message: 'Invalid Port' }
],
modbus_timeout: [
{ required: true, message: 'Timeout is required' },
{
type: 'number',
min: 100,
max: 20000,
message: 'Must be between 100 and 20000'
}
]
}),
...(settings.shower_timer && {
shower_min_duration: [
{
type: 'number',
min: 10,
max: 360,
message: 'Time must be between 10 and 360 seconds'
}
]
}),
...(settings.shower_alert && {
shower_alert_trigger: [
{
type: 'number',
min: 1,
max: 20,
message: 'Time must be between 1 and 20 minutes'
}
],
shower_alert_coldshot: [
{
type: 'number',
min: 1,
max: 10,
message: 'Time must be between 1 and 10 seconds'
}
]
}),
...(settings.remote_timeout_en && {
remote_timeout: [
{
type: 'number',
min: 1,
max: 240,
message: 'Timeout must be between 1 and 240 hours'
}
]
})
});
export const uniqueNameValidator = (schedule: ScheduleItem[], o_name?: string) => ({
validator(
_rule: InternalRuleItem,
name: string,
callback: (error?: string) => void
) {
if (
name !== '' &&
(o_name === undefined || o_name.toLowerCase() !== name.toLowerCase()) &&
schedule.find((si) => si.name.toLowerCase() === name.toLowerCase())
) {
callback('Name already in use');
} else {
callback();
}
}
});
export const schedulerItemValidation = (
schedule: ScheduleItem[],
scheduleItem: ScheduleItem
) =>
new Schema({
name: [
{
type: 'string',
pattern: /^[a-zA-Z0-9_]{0,19}$/,
message: "Must be <20 characters: alphanumeric or '_'"
},
...[uniqueNameValidator(schedule, scheduleItem.o_name)]
],
cmd: [
{ required: true, message: 'Command is required' },
{
type: 'string',
min: 1,
max: 300,
message: 'Command must be 1-300 characters'
}
]
});
export const uniqueCustomNameValidator = (
entity: EntityItem[],
o_name?: string
) => ({
validator(
_rule: InternalRuleItem,
name: string,
callback: (error?: string) => void
) {
if (
(o_name === undefined || o_name.toLowerCase() !== name.toLowerCase()) &&
entity.find((ei) => ei.name.toLowerCase() === name.toLowerCase())
) {
callback('Name already in use');
} else {
callback();
}
}
});
export const entityItemValidation = (entity: EntityItem[], entityItem: EntityItem) =>
new Schema({
name: [
{ required: true, message: 'Name is required' },
{
type: 'string',
pattern: /^[a-zA-Z0-9_]{1,19}$/,
message: "Must be <20 characters: alphanumeric or '_'"
},
...[uniqueCustomNameValidator(entity, entityItem.o_name)]
],
device_id: [
{
validator(
_rule: InternalRuleItem,
value: string,
callback: (error?: string) => void
) {
if (isNaN(parseInt(value, 16))) {
callback('Is required and must be in hex format');
}
callback();
}
}
],
type_id: [
{
validator(
_rule: InternalRuleItem,
value: string,
callback: (error?: string) => void
) {
if (isNaN(parseInt(value, 16))) {
callback('Is required and must be in hex format');
}
callback();
}
}
],
offset: [
{ required: true, message: 'Offset is required' },
{ type: 'number', min: 0, max: 255, message: 'Must be between 0 and 255' }
],
factor: [{ required: true, message: 'is required' }]
});
export const uniqueTemperatureNameValidator = (
sensors: TemperatureSensor[],
o_name?: string
) => ({
validator(_rule: InternalRuleItem, n: string, callback: (error?: string) => void) {
if (
(o_name === undefined || o_name.toLowerCase() !== n.toLowerCase()) &&
n !== '' &&
sensors.find((ts) => ts.n.toLowerCase() === n.toLowerCase())
) {
callback('Name already in use');
} else {
callback();
}
}
});
export const temperatureSensorItemValidation = (
sensors: TemperatureSensor[],
sensor: TemperatureSensor
) =>
new Schema({
n: [
{
type: 'string',
pattern: /^[a-zA-Z0-9_]{0,19}$/,
message: "Must be <20 characters: alphanumeric or '_'"
},
...[uniqueTemperatureNameValidator(sensors, sensor.o_n)]
]
});
export const isGPIOUniqueValidator = (sensors: AnalogSensor[]) => ({
validator(
_rule: InternalRuleItem,
gpio: number,
callback: (error?: string) => void
) {
if (sensors.find((as) => as.g === gpio)) {
callback('GPIO already in use');
} else {
callback();
}
}
});
export const uniqueAnalogNameValidator = (
sensors: AnalogSensor[],
o_name?: string
) => ({
validator(_rule: InternalRuleItem, n: string, callback: (error?: string) => void) {
if (
(o_name === undefined || o_name.toLowerCase() !== n.toLowerCase()) &&
n !== '' &&
sensors.find((as) => as.n.toLowerCase() === n.toLowerCase())
) {
callback('Name already in use');
} else {
callback();
}
}
});
export const analogSensorItemValidation = (
sensors: AnalogSensor[],
sensor: AnalogSensor,
creating: boolean,
platform: string
) =>
new Schema({
n: [
{
type: 'string',
pattern: /^[a-zA-Z0-9_]{0,19}$/,
message: "Must be <20 characters: alphanumeric or '_'"
},
...[uniqueAnalogNameValidator(sensors, sensor.o_n)]
],
g: [
{ required: true, message: 'GPIO is required' },
platform === 'ESP32S3'
? GPIO_VALIDATORS3
: platform === 'ESP32S2'
? GPIO_VALIDATORS2
: platform === 'ESP32C3'
? GPIO_VALIDATORC3
: GPIO_VALIDATOR,
...(creating ? [isGPIOUniqueValidator(sensors)] : [])
]
});
export const deviceValueItemValidation = (dv: DeviceValue) =>
new Schema({
v: [
{ required: true, message: 'Value is required' },
{
validator(
_rule: InternalRuleItem,
value: unknown,
callback: (error?: string) => void
) {
if (
typeof value === 'number' &&
dv.m &&
dv.x &&
(value < dv.m || value > dv.x)
) {
callback('Value out of range');
}
callback();
}
}
]
});

View File

@@ -1,33 +1,33 @@
import { useState } from 'react';
import CancelIcon from '@mui/icons-material/Cancel';
import WarningIcon from '@mui/icons-material/Warning';
import { Button, Checkbox, MenuItem } from '@mui/material';
import { range } from 'lodash-es';
import { useState } from 'react';
import type { ValidateFieldsError } from 'async-validator';
import type { FC } from 'react';
import type { APSettings } from 'types';
import * as APApi from 'api/ap';
import type { ValidateFieldsError } from 'async-validator';
import {
BlockFormControlLabel,
BlockNavigation,
ButtonRow,
FormLoader,
SectionContent,
ValidatedPasswordField,
ValidatedTextField,
BlockNavigation
useLayoutTitle
} from 'components';
import { useI18nContext } from 'i18n/i18n-react';
import type { APSettingsType } from 'types';
import { APProvisionMode } from 'types';
import { numberValue, updateValueDirty, useRest } from 'utils';
import { createAPSettingsValidator, validate } from 'validators';
export const isAPEnabled = ({ provision_mode }: APSettings) =>
provision_mode === APProvisionMode.AP_MODE_ALWAYS || provision_mode === APProvisionMode.AP_MODE_DISCONNECTED;
export const isAPEnabled = ({ provision_mode }: APSettingsType) =>
provision_mode === APProvisionMode.AP_MODE_ALWAYS ||
provision_mode === APProvisionMode.AP_MODE_DISCONNECTED;
const APSettingsForm: FC = () => {
const APSettings = () => {
const {
loadData,
saving,
@@ -39,20 +39,27 @@ const APSettingsForm: FC = () => {
blocker,
saveData,
errorMessage
} = useRest<APSettings>({
} = useRest<APSettingsType>({
read: APApi.readAPSettings,
update: APApi.updateAPSettings
});
const { LL } = useI18nContext();
useLayoutTitle(LL.ACCESS_POINT(0));
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
const updateFormValue = updateValueDirty(origData, dirtyFlags, setDirtyFlags, updateDataValue);
const updateFormValue = updateValueDirty(
origData,
dirtyFlags,
setDirtyFlags,
updateDataValue as (value: unknown) => void
);
const content = () => {
if (!data) {
return <FormLoader onRetry={loadData} errorMessage={errorMessage} />;
return <FormLoader onRetry={loadData} errorMessage={errorMessage || ''} />;
}
const validateAndSubmit = async () => {
@@ -60,15 +67,20 @@ const APSettingsForm: FC = () => {
setFieldErrors(undefined);
await validate(createAPSettingsValidator(data), data);
await saveData();
} catch (errors: any) {
setFieldErrors(errors);
} catch (error) {
setFieldErrors(error as ValidateFieldsError);
}
};
// no lodash - https://asleepace.com/blog/typescript-range-without-a-loop/
function range(a: number, b: number): number[] {
return a < b ? [a, ...range(a + 1, b)] : [b];
}
return (
<>
<ValidatedTextField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
name="provision_mode"
label={LL.AP_PROVIDE() + '...'}
value={data.provision_mode}
@@ -78,14 +90,20 @@ const APSettingsForm: FC = () => {
onChange={updateFormValue}
margin="normal"
>
<MenuItem value={APProvisionMode.AP_MODE_ALWAYS}>{LL.AP_PROVIDE_TEXT_1()}</MenuItem>
<MenuItem value={APProvisionMode.AP_MODE_DISCONNECTED}>{LL.AP_PROVIDE_TEXT_2()}</MenuItem>
<MenuItem value={APProvisionMode.AP_NEVER}>{LL.AP_PROVIDE_TEXT_3()}</MenuItem>
<MenuItem value={APProvisionMode.AP_MODE_ALWAYS}>
{LL.AP_PROVIDE_TEXT_1()}
</MenuItem>
<MenuItem value={APProvisionMode.AP_MODE_DISCONNECTED}>
{LL.AP_PROVIDE_TEXT_2()}
</MenuItem>
<MenuItem value={APProvisionMode.AP_NEVER}>
{LL.AP_PROVIDE_TEXT_3()}
</MenuItem>
</ValidatedTextField>
{isAPEnabled(data) && (
<>
<ValidatedTextField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
name="ssid"
label={LL.ACCESS_POINT(2) + ' SSID'}
fullWidth
@@ -95,7 +113,7 @@ const APSettingsForm: FC = () => {
margin="normal"
/>
<ValidatedPasswordField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
name="password"
label={LL.ACCESS_POINT(2) + ' ' + LL.PASSWORD()}
fullWidth
@@ -105,7 +123,7 @@ const APSettingsForm: FC = () => {
margin="normal"
/>
<ValidatedTextField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
name="channel"
label={LL.AP_PREFERRED_CHANNEL()}
value={numberValue(data.channel)}
@@ -123,11 +141,17 @@ const APSettingsForm: FC = () => {
))}
</ValidatedTextField>
<BlockFormControlLabel
control={<Checkbox name="ssid_hidden" checked={data.ssid_hidden} onChange={updateFormValue} />}
control={
<Checkbox
name="ssid_hidden"
checked={data.ssid_hidden}
onChange={updateFormValue}
/>
}
label={LL.AP_HIDE_SSID()}
/>
<ValidatedTextField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
name="max_clients"
label={LL.AP_MAX_CLIENTS()}
value={numberValue(data.max_clients)}
@@ -145,7 +169,7 @@ const APSettingsForm: FC = () => {
))}
</ValidatedTextField>
<ValidatedTextField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
name="local_ip"
label={LL.AP_LOCAL_IP()}
fullWidth
@@ -155,7 +179,7 @@ const APSettingsForm: FC = () => {
margin="normal"
/>
<ValidatedTextField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
name="gateway_ip"
label={LL.NETWORK_GATEWAY()}
fullWidth
@@ -165,7 +189,7 @@ const APSettingsForm: FC = () => {
margin="normal"
/>
<ValidatedTextField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
name="subnet_mask"
label={LL.NETWORK_SUBNET()}
fullWidth
@@ -182,7 +206,7 @@ const APSettingsForm: FC = () => {
startIcon={<CancelIcon />}
disabled={saving}
variant="outlined"
color="primary"
color="secondary"
type="submit"
onClick={loadData}
>
@@ -205,11 +229,11 @@ const APSettingsForm: FC = () => {
};
return (
<SectionContent title={LL.SETTINGS_OF(LL.ACCESS_POINT(1))} titleGutter>
<SectionContent>
{blocker ? <BlockNavigation blocker={blocker} /> : null}
{content()}
</SectionContent>
);
};
export default APSettingsForm;
export default APSettings;

View File

@@ -0,0 +1,139 @@
import { useState } from 'react';
import { toast } from 'react-toastify';
import DownloadIcon from '@mui/icons-material/GetApp';
import { Box, Button, Grid, Typography } from '@mui/material';
import * as SystemApi from 'api/system';
import { API, callAction } from 'api/app';
import { useRequest } from 'alova/client';
import type { APIcall } from 'app/main/types';
import SystemMonitor from 'app/status/SystemMonitor';
import {
FormLoader,
SectionContent,
SingleUpload,
useLayoutTitle
} from 'components';
import { useI18nContext } from 'i18n/i18n-react';
import { saveFile } from 'utils';
const DownloadUpload = () => {
const { LL } = useI18nContext();
const [restarting, setRestarting] = useState<boolean>(false);
const { send: sendExportData } = useRequest(
(type: string) => callAction({ action: 'export', param: type }),
{
immediate: false
}
)
.onSuccess((event) => {
saveFile(event.data, event.args[0], '.json');
toast.info(LL.DOWNLOAD_SUCCESSFUL());
})
.onError((error) => {
toast.error(String(error.error?.message || 'An error occurred'));
});
const { send: sendAPI } = useRequest((data: APIcall) => API(data), {
immediate: false
});
const { data, send: loadData, error } = useRequest(SystemApi.readSystemStatus);
const doRestart = async () => {
setRestarting(true);
await sendAPI({ device: 'system', cmd: 'restart', id: 0 }).catch(
(error: Error) => {
toast.error(error.message);
}
);
};
useLayoutTitle(LL.DOWNLOAD_UPLOAD());
const content = () => {
if (!data) {
return <FormLoader onRetry={loadData} errorMessage={error?.message || ''} />;
}
return (
<>
<Typography sx={{ pb: 2 }} variant="h6" color="primary">
{LL.DOWNLOAD(0)}
</Typography>
<Typography mb={1} variant="body1" color="warning">
{LL.DOWNLOAD_SETTINGS_TEXT()}.
</Typography>
<Grid container spacing={1}>
<Button
sx={{ ml: 2 }}
startIcon={<DownloadIcon />}
variant="outlined"
color="primary"
onClick={() => sendExportData('settings')}
>
{LL.SETTINGS_OF(LL.APPLICATION())}
</Button>
<Button
sx={{ ml: 2 }}
startIcon={<DownloadIcon />}
variant="outlined"
color="primary"
onClick={() => sendExportData('customizations')}
>
{LL.CUSTOMIZATIONS()}
</Button>
<Button
sx={{ ml: 2 }}
startIcon={<DownloadIcon />}
variant="outlined"
color="primary"
onClick={() => sendExportData('entities')}
>
{LL.CUSTOM_ENTITIES(0)}
</Button>
<Button
sx={{ ml: 2 }}
startIcon={<DownloadIcon />}
variant="outlined"
color="primary"
onClick={() => sendExportData('schedule')}
>
{LL.SCHEDULE(0)}
</Button>
</Grid>
<Button
sx={{ ml: 2, mt: 2 }}
startIcon={<DownloadIcon />}
variant="outlined"
color="primary"
onClick={() => sendExportData('allvalues')}
>
{LL.ALLVALUES()}
</Button>
<Typography sx={{ pt: 2, pb: 2 }} variant="h6" color="primary">
{LL.UPLOAD()}
</Typography>
<Box color="warning.main" sx={{ pb: 2 }}>
<Typography variant="body1">{LL.UPLOAD_TEXT()}.</Typography>
</Box>
<SingleUpload text={LL.UPLOAD_DRAG()} doRestart={doRestart} />
</>
);
};
return (
<SectionContent>{restarting ? <SystemMonitor /> : content()}</SectionContent>
);
};
export default DownloadUpload;

View File

@@ -1,27 +1,36 @@
import { useState } from 'react';
import CancelIcon from '@mui/icons-material/Cancel';
import WarningIcon from '@mui/icons-material/Warning';
import { Button, Checkbox, MenuItem, Grid, Typography, InputAdornment, TextField } from '@mui/material';
import { useState } from 'react';
import type { ValidateFieldsError } from 'async-validator';
import type { FC } from 'react';
import {
Button,
Checkbox,
Grid,
InputAdornment,
MenuItem,
TextField,
Typography
} from '@mui/material';
import type { MqttSettings } from 'types';
import * as MqttApi from 'api/mqtt';
import type { ValidateFieldsError } from 'async-validator';
import {
BlockFormControlLabel,
BlockNavigation,
ButtonRow,
FormLoader,
SectionContent,
ValidatedPasswordField,
ValidatedTextField,
BlockNavigation
useLayoutTitle
} from 'components';
import { useI18nContext } from 'i18n/i18n-react';
import type { MqttSettingsType } from 'types';
import { numberValue, updateValueDirty, useRest } from 'utils';
import { createMqttSettingsValidator, validate } from 'validators';
const MqttSettingsForm: FC = () => {
const MqttSettings = () => {
const {
loadData,
saving,
@@ -33,20 +42,30 @@ const MqttSettingsForm: FC = () => {
blocker,
saveData,
errorMessage
} = useRest<MqttSettings>({
} = useRest<MqttSettingsType>({
read: MqttApi.readMqttSettings,
update: MqttApi.updateMqttSettings
});
const { LL } = useI18nContext();
useLayoutTitle('MQTT');
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
const updateFormValue = updateValueDirty(origData, dirtyFlags, setDirtyFlags, updateDataValue);
const updateFormValue = updateValueDirty(
origData,
dirtyFlags,
setDirtyFlags,
updateDataValue as (value: unknown) => void
);
const SecondsInputProps = {
endAdornment: <InputAdornment position="end">{LL.SECONDS()}</InputAdornment>
};
const content = () => {
if (!data) {
return <FormLoader onRetry={loadData} errorMessage={errorMessage} />;
return <FormLoader onRetry={loadData} errorMessage={errorMessage || ''} />;
}
const validateAndSubmit = async () => {
@@ -54,24 +73,29 @@ const MqttSettingsForm: FC = () => {
setFieldErrors(undefined);
await validate(createMqttSettingsValidator(data), data);
await saveData();
} catch (errors: any) {
setFieldErrors(errors);
} catch (error) {
setFieldErrors(error as ValidateFieldsError);
}
};
return (
<>
<BlockFormControlLabel
control={<Checkbox name="enabled" checked={data.enabled} onChange={updateFormValue} />}
control={
<Checkbox
name="enabled"
checked={data.enabled}
onChange={updateFormValue}
/>
}
label={LL.ENABLE_MQTT()}
/>
<Grid container spacing={1} direction="row" justifyContent="flex-start" alignItems="flex-start">
<Grid item xs={12} sm={6}>
<Grid container spacing={2} rowSpacing={0}>
<Grid>
<ValidatedTextField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
name="host"
label={LL.ADDRESS_OF(LL.BROKER())}
fullWidth
multiline
variant="outlined"
value={data.host}
@@ -79,12 +103,11 @@ const MqttSettingsForm: FC = () => {
margin="normal"
/>
</Grid>
<Grid item xs={12} sm={6}>
<Grid>
<ValidatedTextField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
name="port"
label="Port"
fullWidth
variant="outlined"
value={numberValue(data.port)}
type="number"
@@ -92,60 +115,55 @@ const MqttSettingsForm: FC = () => {
margin="normal"
/>
</Grid>
<Grid item xs={12} sm={6}>
<Grid>
<ValidatedTextField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
name="base"
label={LL.BASE_TOPIC()}
fullWidth
variant="outlined"
value={data.base}
onChange={updateFormValue}
margin="normal"
/>
</Grid>
<Grid item xs={12} sm={6}>
<Grid>
<TextField
name="client_id"
label={LL.ID_OF(LL.CLIENT()) + ' (' + LL.OPTIONAL() + ')'}
fullWidth
variant="outlined"
value={data.client_id}
onChange={updateFormValue}
margin="normal"
/>
</Grid>
<Grid item xs={12} sm={6}>
<Grid>
<TextField
name="username"
label={LL.USERNAME(0)}
fullWidth
variant="outlined"
value={data.username}
onChange={updateFormValue}
margin="normal"
/>
</Grid>
<Grid item xs={12} sm={6}>
<Grid>
<ValidatedPasswordField
name="password"
label={LL.PASSWORD()}
fullWidth
variant="outlined"
value={data.password}
onChange={updateFormValue}
margin="normal"
/>
</Grid>
<Grid item xs={12} sm={6}>
<Grid>
<ValidatedTextField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
name="keep_alive"
label="Keep Alive"
InputProps={{
endAdornment: <InputAdornment position="end">{LL.SECONDS()}</InputAdornment>
slotProps={{
input: SecondsInputProps
}}
fullWidth
variant="outlined"
value={numberValue(data.keep_alive)}
type="number"
@@ -153,12 +171,11 @@ const MqttSettingsForm: FC = () => {
margin="normal"
/>
</Grid>
<Grid item xs={12} sm={6}>
<Grid>
<TextField
name="mqtt_qos"
label="QoS"
value={data.mqtt_qos}
fullWidth
variant="outlined"
onChange={updateFormValue}
margin="normal"
@@ -172,7 +189,13 @@ const MqttSettingsForm: FC = () => {
</Grid>
{data.enableTLS !== undefined && (
<BlockFormControlLabel
control={<Checkbox name="enableTLS" checked={data.enableTLS} onChange={updateFormValue} />}
control={
<Checkbox
name="enableTLS"
checked={data.enableTLS}
onChange={updateFormValue}
/>
}
label={LL.ENABLE_TLS()}
/>
)}
@@ -180,23 +203,32 @@ const MqttSettingsForm: FC = () => {
<ValidatedPasswordField
name="rootCA"
label={LL.CERT()}
fullWidth
variant="outlined"
value={data.rootCA}
onChange={updateFormValue}
margin="normal"
/>
)}
<BlockFormControlLabel
control={<Checkbox name="clean_session" checked={data.clean_session} onChange={updateFormValue} />}
control={
<Checkbox
name="clean_session"
checked={data.clean_session}
onChange={updateFormValue}
/>
}
label={LL.MQTT_CLEAN_SESSION()}
/>
<BlockFormControlLabel
control={<Checkbox name="mqtt_retain" checked={data.mqtt_retain} onChange={updateFormValue} />}
control={
<Checkbox
name="mqtt_retain"
checked={data.mqtt_retain}
onChange={updateFormValue}
/>
}
label={LL.MQTT_RETAIN_FLAG()}
/>
<Typography sx={{ pt: 2 }} variant="h6" color="primary">
{LL.FORMATTING()}
</Typography>
@@ -204,7 +236,6 @@ const MqttSettingsForm: FC = () => {
name="nested_format"
label={LL.MQTT_FORMAT()}
value={data.nested_format}
fullWidth
variant="outlined"
onChange={updateFormValue}
margin="normal"
@@ -214,113 +245,121 @@ const MqttSettingsForm: FC = () => {
<MenuItem value={2}>{LL.MQTT_NEST_2()}</MenuItem>
</TextField>
<BlockFormControlLabel
control={<Checkbox name="send_response" checked={data.send_response} onChange={updateFormValue} />}
control={
<Checkbox
name="send_response"
checked={data.send_response}
onChange={updateFormValue}
/>
}
label={LL.MQTT_RESPONSE()}
/>
{!data.ha_enabled && (
<Grid
container
rowSpacing={-1}
spacing={1}
direction="row"
justifyContent="flex-start"
alignItems="flex-start"
>
<Grid item>
<Grid container spacing={2} rowSpacing={0}>
<Grid>
<BlockFormControlLabel
control={
<Checkbox
name="publish_single"
checked={data.publish_single}
onChange={updateFormValue}
disabled={data.ha_enabled}
/>
}
label={LL.MQTT_PUBLISH_TEXT_1()}
/>
</Grid>
{data.publish_single && (
<Grid>
<BlockFormControlLabel
control={<Checkbox name="publish_single" checked={data.publish_single} onChange={updateFormValue} />}
label={LL.MQTT_PUBLISH_TEXT_1()}
control={
<Checkbox
name="publish_single2cmd"
checked={data.publish_single2cmd}
onChange={updateFormValue}
/>
}
label={LL.MQTT_PUBLISH_TEXT_2()}
/>
</Grid>
{data.publish_single && (
<Grid item>
<BlockFormControlLabel
control={
<Checkbox name="publish_single2cmd" checked={data.publish_single2cmd} onChange={updateFormValue} />
}
label={LL.MQTT_PUBLISH_TEXT_2()}
)}
</Grid>
<Grid container spacing={2} rowSpacing={0}>
<Grid>
<BlockFormControlLabel
control={
<Checkbox
name="ha_enabled"
checked={data.ha_enabled}
onChange={updateFormValue}
disabled={data.publish_single}
/>
}
label={LL.MQTT_PUBLISH_TEXT_3()}
/>
</Grid>
{data.ha_enabled && (
<Grid container spacing={2} rowSpacing={0}>
<Grid>
<TextField
name="discovery_type"
label={LL.MQTT_PUBLISH_TEXT_5()}
value={data.discovery_type}
variant="outlined"
onChange={updateFormValue}
margin="normal"
select
>
<MenuItem value={0}>Home Assistant</MenuItem>
<MenuItem value={1}>Domoticz</MenuItem>
<MenuItem value={2}>Domoticz (latest)</MenuItem>
</TextField>
</Grid>
<Grid>
<TextField
name="discovery_prefix"
label={LL.MQTT_PUBLISH_TEXT_4()}
variant="outlined"
value={data.discovery_prefix}
onChange={updateFormValue}
margin="normal"
/>
</Grid>
)}
</Grid>
)}
{!data.publish_single && (
<Grid container spacing={1} direction="row" justifyContent="flex-start" alignItems="flex-start">
<Grid item>
<BlockFormControlLabel
control={<Checkbox name="ha_enabled" checked={data.ha_enabled} onChange={updateFormValue} />}
label={LL.MQTT_PUBLISH_TEXT_3()}
/>
</Grid>
{data.ha_enabled && (
<Grid
container
sx={{ pl: 1 }}
spacing={1}
direction="row"
justifyContent="flex-start"
alignItems="flex-start"
>
<Grid item xs={12} sm={6} md={4}>
<TextField
name="discovery_type"
label={LL.MQTT_PUBLISH_TEXT_5()}
value={data.discovery_type}
fullWidth
variant="outlined"
onChange={updateFormValue}
margin="normal"
select
>
<MenuItem value={0}>Home Assistant</MenuItem>
<MenuItem value={1}>Domoticz</MenuItem>
<MenuItem value={2}>Domoticz (latest)</MenuItem>
</TextField>
</Grid>
<Grid item xs={12} sm={6} md={4}>
<TextField
name="discovery_prefix"
label={LL.MQTT_PUBLISH_TEXT_4()}
fullWidth
variant="outlined"
value={data.discovery_prefix}
onChange={updateFormValue}
margin="normal"
/>
</Grid>
<Grid item xs={12} sm={6} md={4}>
<TextField
name="entity_format"
label={LL.MQTT_ENTITY_FORMAT()}
value={data.entity_format}
fullWidth
variant="outlined"
onChange={updateFormValue}
margin="normal"
select
>
<MenuItem value={0}>{LL.MQTT_ENTITY_FORMAT_0()}</MenuItem>
<MenuItem value={1}>{LL.MQTT_ENTITY_FORMAT_1()}</MenuItem>
<MenuItem value={2}>{LL.MQTT_ENTITY_FORMAT_2()}</MenuItem>
</TextField>
</Grid>
<Grid>
<TextField
name="entity_format"
label={LL.MQTT_ENTITY_FORMAT()}
value={data.entity_format}
variant="outlined"
onChange={updateFormValue}
margin="normal"
select
>
<MenuItem value={0}>{LL.MQTT_ENTITY_FORMAT_0()}</MenuItem>
<MenuItem value={3}>
{LL.MQTT_ENTITY_FORMAT_1()}&nbsp;(v3.6)
</MenuItem>
<MenuItem value={4}>
{LL.MQTT_ENTITY_FORMAT_2()}&nbsp;(v3.6)
</MenuItem>
<MenuItem value={1}>{LL.MQTT_ENTITY_FORMAT_1()}</MenuItem>
<MenuItem value={2}>{LL.MQTT_ENTITY_FORMAT_2()}</MenuItem>
</TextField>
</Grid>
)}
</Grid>
)}
</Grid>
)}
</Grid>
<Typography sx={{ pt: 2 }} variant="h6" color="primary">
{LL.MQTT_PUBLISH_INTERVALS()}&nbsp;(0=auto)
</Typography>
<Grid container spacing={1} direction="row" justifyContent="flex-start" alignItems="flex-start">
<Grid item xs={12} sm={6} md={4}>
<Grid container spacing={2} rowSpacing={0}>
<Grid>
<ValidatedTextField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
name="publish_time_heartbeat"
label="Heartbeat"
InputProps={{
endAdornment: <InputAdornment position="end">{LL.SECONDS()}</InputAdornment>
slotProps={{
input: SecondsInputProps
}}
fullWidth
variant="outlined"
value={numberValue(data.publish_time_heartbeat)}
type="number"
@@ -328,105 +367,112 @@ const MqttSettingsForm: FC = () => {
margin="normal"
/>
</Grid>
<Grid item xs={12} sm={6} md={4}>
<Grid>
<TextField
name="publish_time_boiler"
label={LL.MQTT_INT_BOILER()}
InputProps={{
endAdornment: <InputAdornment position="end">{LL.SECONDS()}</InputAdornment>
}}
fullWidth
variant="outlined"
value={numberValue(data.publish_time_boiler)}
type="number"
onChange={updateFormValue}
margin="normal"
slotProps={{
input: SecondsInputProps
}}
/>
</Grid>
<Grid item xs={12} sm={6} md={4}>
<Grid>
<TextField
name="publish_time_thermostat"
label={LL.MQTT_INT_THERMOSTATS()}
InputProps={{
endAdornment: <InputAdornment position="end">{LL.SECONDS()}</InputAdornment>
}}
fullWidth
variant="outlined"
value={numberValue(data.publish_time_thermostat)}
type="number"
onChange={updateFormValue}
margin="normal"
slotProps={{
input: SecondsInputProps
}}
/>
</Grid>
<Grid item xs={12} sm={6} md={4}>
<Grid>
<TextField
name="publish_time_solar"
label={LL.MQTT_INT_SOLAR()}
InputProps={{
endAdornment: <InputAdornment position="end">{LL.SECONDS()}</InputAdornment>
}}
fullWidth
variant="outlined"
value={numberValue(data.publish_time_solar)}
type="number"
onChange={updateFormValue}
margin="normal"
slotProps={{
input: SecondsInputProps
}}
/>
</Grid>
<Grid item xs={12} sm={6} md={4}>
<Grid>
<TextField
name="publish_time_mixer"
label={LL.MQTT_INT_MIXER()}
InputProps={{
endAdornment: <InputAdornment position="end">{LL.SECONDS()}</InputAdornment>
}}
fullWidth
variant="outlined"
value={numberValue(data.publish_time_mixer)}
type="number"
onChange={updateFormValue}
margin="normal"
slotProps={{
input: SecondsInputProps
}}
/>
</Grid>
<Grid item xs={12} sm={6} md={4}>
<Grid>
<TextField
name="publish_time_water"
label={LL.MQTT_INT_WATER()}
variant="outlined"
value={numberValue(data.publish_time_water)}
type="number"
onChange={updateFormValue}
margin="normal"
slotProps={{
input: SecondsInputProps
}}
/>
</Grid>
<Grid>
<TextField
name="publish_time_sensor"
label={LL.TEMP_SENSORS()}
InputProps={{
endAdornment: <InputAdornment position="end">{LL.SECONDS()}</InputAdornment>
}}
fullWidth
label={LL.SENSORS()}
variant="outlined"
value={numberValue(data.publish_time_sensor)}
type="number"
onChange={updateFormValue}
margin="normal"
slotProps={{
input: SecondsInputProps
}}
/>
</Grid>
<Grid item xs={12} sm={6} md={4}>
<Grid>
<TextField
name="publish_time_other"
InputProps={{
endAdornment: <InputAdornment position="end">{LL.SECONDS()}</InputAdornment>
}}
label={LL.DEFAULT(0)}
fullWidth
variant="outlined"
value={numberValue(data.publish_time_other)}
type="number"
onChange={updateFormValue}
margin="normal"
slotProps={{
input: SecondsInputProps
}}
/>
</Grid>
</Grid>
{dirtyFlags && dirtyFlags.length !== 0 && (
<ButtonRow>
<Button
startIcon={<CancelIcon />}
disabled={saving}
variant="outlined"
color="primary"
color="secondary"
type="submit"
onClick={loadData}
>
@@ -449,11 +495,11 @@ const MqttSettingsForm: FC = () => {
};
return (
<SectionContent title={LL.SETTINGS_OF('MQTT')} titleGutter>
<SectionContent>
{blocker ? <BlockNavigation blocker={blocker} /> : null}
{content()}
</SectionContent>
);
};
export default MqttSettingsForm;
export default MqttSettings;

View File

@@ -0,0 +1,271 @@
import { useState } from 'react';
import { toast } from 'react-toastify';
import AccessTimeIcon from '@mui/icons-material/AccessTime';
import CancelIcon from '@mui/icons-material/Cancel';
import WarningIcon from '@mui/icons-material/Warning';
import {
Box,
Button,
Checkbox,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
MenuItem,
TextField,
Typography
} from '@mui/material';
import * as NTPApi from 'api/ntp';
import { readNTPSettings } from 'api/ntp';
import { dialogStyle } from 'CustomTheme';
import { useRequest } from 'alova/client';
import { updateState } from 'alova/client';
import type { ValidateFieldsError } from 'async-validator';
import {
BlockFormControlLabel,
BlockNavigation,
ButtonRow,
FormLoader,
SectionContent,
ValidatedTextField,
useLayoutTitle
} from 'components';
import { useI18nContext } from 'i18n/i18n-react';
import type { NTPSettingsType, Time } from 'types';
import { formatLocalDateTime, updateValueDirty, useRest } from 'utils';
import { validate } from 'validators';
import { NTP_SETTINGS_VALIDATOR } from 'validators/ntp';
import { TIME_ZONES, selectedTimeZone, timeZoneSelectItems } from './TZ';
const NTPSettings = () => {
const {
loadData,
saving,
data,
updateDataValue,
origData,
dirtyFlags,
setDirtyFlags,
blocker,
saveData,
errorMessage
} = useRest<NTPSettingsType>({
read: NTPApi.readNTPSettings,
update: NTPApi.updateNTPSettings
});
const { LL } = useI18nContext();
useLayoutTitle('NTP');
const [localTime, setLocalTime] = useState<string>('');
const [settingTime, setSettingTime] = useState<boolean>(false);
const [processing, setProcessing] = useState<boolean>(false);
const { send: updateTime } = useRequest(
(local_time: Time) => NTPApi.updateTime(local_time),
{
immediate: false
}
);
const updateFormValue = updateValueDirty(
origData,
dirtyFlags,
setDirtyFlags,
updateDataValue as (value: unknown) => void
);
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
const updateLocalTime = (event: React.ChangeEvent<HTMLInputElement>) =>
setLocalTime(event.target.value);
const openSetTime = () => {
setLocalTime(formatLocalDateTime(new Date()));
setSettingTime(true);
};
const configureTime = async () => {
setProcessing(true);
await updateTime({ local_time: formatLocalDateTime(new Date(localTime)) })
.then(async () => {
toast.success(LL.TIME_SET());
setSettingTime(false);
await loadData();
})
.catch(() => {
toast.error(LL.PROBLEM_UPDATING());
})
.finally(() => {
setProcessing(false);
});
};
const renderSetTimeDialog = () => (
<Dialog
sx={dialogStyle}
open={settingTime}
onClose={() => setSettingTime(false)}
>
<DialogTitle>{LL.SET_TIME(1)}</DialogTitle>
<DialogContent dividers>
<Box color="warning.main" p={0} pl={0} pr={0} mt={0} mb={2}>
<Typography variant="body2">{LL.SET_TIME_TEXT()}</Typography>
</Box>
<TextField
label={LL.LOCAL_TIME(0)}
type="datetime-local"
value={localTime}
onChange={updateLocalTime}
disabled={processing}
fullWidth
slotProps={{
inputLabel: {
shrink: true
}
}}
/>
</DialogContent>
<DialogActions>
<Button
startIcon={<CancelIcon />}
variant="outlined"
onClick={() => setSettingTime(false)}
color="secondary"
>
{LL.CANCEL()}
</Button>
<Button
startIcon={<AccessTimeIcon />}
variant="outlined"
onClick={configureTime}
disabled={processing}
color="primary"
>
{LL.UPDATE()}
</Button>
</DialogActions>
</Dialog>
);
const content = () => {
if (!data) {
return <FormLoader onRetry={loadData} errorMessage={errorMessage || ''} />;
}
const validateAndSubmit = async () => {
try {
setFieldErrors(undefined);
await validate(NTP_SETTINGS_VALIDATOR, data);
await saveData();
} catch (error) {
setFieldErrors(error as ValidateFieldsError);
}
};
const changeTimeZone = (event: React.ChangeEvent<HTMLInputElement>) => {
void updateState(readNTPSettings(), (settings: NTPSettingsType) => ({
...settings,
tz_label: event.target.value,
tz_format: TIME_ZONES[event.target.value]
}));
updateFormValue(event);
};
return (
<>
<BlockFormControlLabel
control={
<Checkbox
name="enabled"
checked={data.enabled}
onChange={updateFormValue}
/>
}
label={LL.ENABLE_NTP()}
/>
<ValidatedTextField
fieldErrors={fieldErrors || {}}
name="server"
label={LL.NTP_SERVER()}
fullWidth
variant="outlined"
value={data.server}
onChange={updateFormValue}
margin="normal"
/>
<ValidatedTextField
fieldErrors={fieldErrors || {}}
name="tz_label"
label={LL.TIME_ZONE()}
fullWidth
variant="outlined"
value={selectedTimeZone(data.tz_label, data.tz_format)}
onChange={changeTimeZone}
margin="normal"
select
>
<MenuItem disabled>{LL.TIME_ZONE()}...</MenuItem>
{timeZoneSelectItems()}
</ValidatedTextField>
<Box display="flex" flexWrap="wrap">
{!data.enabled && !dirtyFlags.length && (
<Box flexWrap="nowrap" whiteSpace="nowrap">
<ButtonRow>
<Button
onClick={openSetTime}
variant="outlined"
color="primary"
startIcon={<AccessTimeIcon />}
>
{LL.SET_TIME(0)}
</Button>
</ButtonRow>
</Box>
)}
</Box>
{renderSetTimeDialog()}
{dirtyFlags && dirtyFlags.length !== 0 && (
<ButtonRow>
<Button
startIcon={<CancelIcon />}
disabled={saving}
variant="outlined"
color="secondary"
type="submit"
onClick={loadData}
>
{LL.CANCEL()}
</Button>
<Button
startIcon={<WarningIcon color="warning" />}
disabled={saving}
variant="contained"
color="info"
type="submit"
onClick={validateAndSubmit}
>
{LL.APPLY_CHANGES(dirtyFlags.length)}
</Button>
</ButtonRow>
)}
</>
);
};
return (
<SectionContent>
{blocker ? <BlockNavigation blocker={blocker} /> : null}
{content()}
</SectionContent>
);
};
export default NTPSettings;

View File

@@ -0,0 +1,169 @@
import { useState } from 'react';
import AccessTimeIcon from '@mui/icons-material/AccessTime';
import CancelIcon from '@mui/icons-material/Cancel';
import DeviceHubIcon from '@mui/icons-material/DeviceHub';
import ImportExportIcon from '@mui/icons-material/ImportExport';
import LockIcon from '@mui/icons-material/Lock';
import SettingsBackupRestoreIcon from '@mui/icons-material/SettingsBackupRestore';
import SettingsEthernetIcon from '@mui/icons-material/SettingsEthernet';
import SettingsInputAntennaIcon from '@mui/icons-material/SettingsInputAntenna';
import TuneIcon from '@mui/icons-material/Tune';
import ViewModuleIcon from '@mui/icons-material/ViewModule';
import {
Box,
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
Divider,
List
} from '@mui/material';
import { API } from 'api/app';
import { dialogStyle } from 'CustomTheme';
import { useRequest } from 'alova/client';
import type { APIcall } from 'app/main/types';
import { SectionContent, useLayoutTitle } from 'components';
import ListMenuItem from 'components/layout/ListMenuItem';
import { useI18nContext } from 'i18n/i18n-react';
const Settings = () => {
const { LL } = useI18nContext();
useLayoutTitle(LL.SETTINGS(0));
const [confirmFactoryReset, setConfirmFactoryReset] = useState<boolean>(false);
const { send: sendAPI } = useRequest((data: APIcall) => API(data), {
immediate: false
});
const doFormat = async () => {
await sendAPI({ device: 'system', cmd: 'format', id: 0 }).then(() => {
setConfirmFactoryReset(false);
});
};
const renderFactoryResetDialog = () => (
<Dialog
sx={dialogStyle}
open={confirmFactoryReset}
onClose={() => setConfirmFactoryReset(false)}
>
<DialogTitle>{LL.FACTORY_RESET()}</DialogTitle>
<DialogContent dividers>{LL.SYSTEM_FACTORY_TEXT_DIALOG()}</DialogContent>
<DialogActions>
<Button
startIcon={<CancelIcon />}
variant="outlined"
onClick={() => setConfirmFactoryReset(false)}
color="secondary"
>
{LL.CANCEL()}
</Button>
<Button
startIcon={<SettingsBackupRestoreIcon />}
variant="outlined"
onClick={doFormat}
color="error"
>
{LL.FACTORY_RESET()}
</Button>
</DialogActions>
</Dialog>
);
return (
<SectionContent>
<List>
<ListMenuItem
icon={TuneIcon}
bgcolor="#134ba2"
label={LL.APPLICATION()}
text={LL.APPLICATION_SETTINGS_1()}
to="application"
/>
<ListMenuItem
icon={SettingsEthernetIcon}
bgcolor="#40828f"
label={LL.NETWORK(0)}
text={LL.CONFIGURE(LL.SETTINGS_OF(LL.NETWORK(1)))}
to="network"
/>
<ListMenuItem
icon={SettingsInputAntennaIcon}
bgcolor="#5f9a5f"
label={LL.ACCESS_POINT(0)}
text={LL.CONFIGURE(LL.ACCESS_POINT(1))}
to="ap"
/>
<ListMenuItem
icon={AccessTimeIcon}
bgcolor="#c5572c"
label="NTP"
text={LL.CONFIGURE(LL.LOCAL_TIME(1))}
to="ntp"
/>
<ListMenuItem
icon={DeviceHubIcon}
bgcolor="#68374d"
label="MQTT"
text={LL.CONFIGURE('MQTT')}
to="mqtt"
/>
<ListMenuItem
icon={LockIcon}
label={LL.SECURITY(0)}
text={LL.SECURITY_1()}
to="security"
/>
<ListMenuItem
icon={ViewModuleIcon}
bgcolor="#efc34b"
label={LL.MODULES()}
text={LL.MODULES_1()}
to="modules"
/>
<ListMenuItem
icon={ImportExportIcon}
bgcolor="#5d89f7"
label={LL.DOWNLOAD_UPLOAD()}
text={LL.DOWNLOAD_UPLOAD_1()}
to="downloadUpload"
/>
</List>
{renderFactoryResetDialog()}
<Divider />
<Box
mt={2}
display="flex"
justifyContent="flex-end"
flexWrap="nowrap"
whiteSpace="nowrap"
>
<Button
startIcon={<SettingsBackupRestoreIcon />}
variant="outlined"
onClick={() => setConfirmFactoryReset(true)}
color="error"
>
{LL.FACTORY_RESET()}
</Button>
</Box>
</SectionContent>
);
};
export default Settings;

View File

@@ -1,8 +1,6 @@
import { MenuItem } from '@mui/material';
type TimeZones = {
[name: string]: string;
};
type TimeZones = Record<string, string>;
export const TIME_ZONES: TimeZones = {
'Africa/Abidjan': 'GMT0',

View File

@@ -0,0 +1,83 @@
import { useCallback, useState } from 'react';
import {
Navigate,
Route,
Routes,
matchRoutes,
useLocation,
useNavigate
} from 'react-router';
import { Tab } from '@mui/material';
import { RouterTabs, useLayoutTitle } from 'components';
import { useI18nContext } from 'i18n/i18n-react';
import type { WiFiNetwork } from 'types';
import NetworkSettings from './NetworkSettings';
import { WiFiConnectionContext } from './WiFiConnectionContext';
import WiFiNetworkScanner from './WiFiNetworkScanner';
const Network = () => {
const { LL } = useI18nContext();
useLayoutTitle(LL.NETWORK(0));
// this also works!
// const routerTab = useMatch(`settings/network/:path/*`)?.pathname || false;
const matchedRoutes = matchRoutes(
[
{
path: '/settings/network/settings',
element: <NetworkSettings />,
dog: 'woof'
},
{ path: '/settings/network/scan', element: <WiFiNetworkScanner /> }
],
useLocation()
);
const routerTab = matchedRoutes?.[0]?.route.path || false;
const navigate = useNavigate();
const [selectedNetwork, setSelectedNetwork] = useState<WiFiNetwork>();
const selectNetwork = useCallback(
(network: WiFiNetwork) => {
setSelectedNetwork(network);
void navigate('/settings/network/settings');
},
[navigate]
);
const deselectNetwork = useCallback(() => {
setSelectedNetwork(undefined);
}, []);
return (
<WiFiConnectionContext.Provider
value={{
...(selectedNetwork && { selectedNetwork }),
selectNetwork,
deselectNetwork
}}
>
<RouterTabs value={routerTab}>
<Tab
value="/settings/network/settings"
label={LL.SETTINGS_OF(LL.NETWORK(1))}
/>
<Tab value="/settings/network/scan" label={LL.NETWORK_SCAN()} />
</RouterTabs>
<Routes>
<Route path="scan" element={<WiFiNetworkScanner />} />
<Route path="settings" element={<NetworkSettings />} />
<Route
path="*"
element={<Navigate replace to="/settings/network/settings" />}
/>
</Routes>
</WiFiConnectionContext.Provider>
);
};
export default Network;

View File

@@ -1,3 +1,6 @@
import { useContext, useEffect, useState } from 'react';
import { toast } from 'react-toastify';
import CancelIcon from '@mui/icons-material/Cancel';
import DeleteIcon from '@mui/icons-material/Delete';
import LockIcon from '@mui/icons-material/Lock';
@@ -12,43 +15,39 @@ import {
List,
ListItem,
ListItemAvatar,
ListItemSecondaryAction,
ListItemText,
Typography,
MenuItem,
TextField,
MenuItem
Typography
} from '@mui/material';
// eslint-disable-next-line import/named
import { updateState, useRequest } from 'alova';
import { useContext, useEffect, useState } from 'react';
import { toast } from 'react-toastify';
import RestartMonitor from '../system/RestartMonitor';
import { WiFiConnectionContext } from './WiFiConnectionContext';
import { isNetworkOpen, networkSecurityMode } from './WiFiNetworkSelector';
import type { ValidateFieldsError } from 'async-validator';
import type { FC } from 'react';
import type { NetworkSettings } from 'types';
import * as NetworkApi from 'api/network';
import * as SystemApi from 'api/system';
import { API } from 'api/app';
import { updateState, useRequest } from 'alova/client';
import type { APIcall } from 'app/main/types';
import type { ValidateFieldsError } from 'async-validator';
import {
BlockFormControlLabel,
BlockNavigation,
ButtonRow,
FormLoader,
MessageBox,
SectionContent,
ValidatedPasswordField,
ValidatedTextField,
MessageBox,
BlockNavigation
ValidatedTextField
} from 'components';
import { useI18nContext } from 'i18n/i18n-react';
import type { NetworkSettingsType } from 'types';
import { updateValueDirty, useRest } from 'utils';
import { validate } from 'validators';
import { createNetworkSettingsValidator } from 'validators/network';
const WiFiSettingsForm: FC = () => {
import SystemMonitor from '../../status/SystemMonitor';
import { WiFiConnectionContext } from './WiFiConnectionContext';
import { isNetworkOpen, networkSecurityMode } from './WiFiNetworkSelector';
const NetworkSettings = () => {
const { LL } = useI18nContext();
const { selectedNetwork, deselectNetwork } = useContext(WiFiConnectionContext);
@@ -68,38 +67,45 @@ const WiFiSettingsForm: FC = () => {
saveData,
errorMessage,
restartNeeded
} = useRest<NetworkSettings>({
} = useRest<NetworkSettingsType>({
read: NetworkApi.readNetworkSettings,
update: NetworkApi.updateNetworkSettings
});
const { send: restartCommand } = useRequest(SystemApi.restart(), {
const { send: sendAPI } = useRequest((data: APIcall) => API(data), {
immediate: false
});
useEffect(() => {
if (!initialized && data) {
if (selectedNetwork) {
updateState('networkSettings', (current_data) => ({
ssid: selectedNetwork.ssid,
bssid: selectedNetwork.bssid,
password: current_data ? current_data.password : '',
hostname: current_data?.hostname,
static_ip_config: false,
enableIPv6: false,
bandwidth20: false,
tx_power: 0,
nosleep: false,
enableMDNS: true,
enableCORS: false,
CORSOrigin: '*'
}));
void updateState(
NetworkApi.readNetworkSettings(),
(current_data: NetworkSettingsType) => ({
ssid: selectedNetwork.ssid,
bssid: selectedNetwork.bssid,
password: current_data ? current_data.password : '',
hostname: current_data?.hostname,
static_ip_config: false,
bandwidth20: false,
tx_power: 0,
nosleep: false,
enableMDNS: true,
enableCORS: false,
CORSOrigin: '*'
})
);
}
setInitialized(true);
}
}, [initialized, setInitialized, data, selectedNetwork]);
const updateFormValue = updateValueDirty(origData, dirtyFlags, setDirtyFlags, updateDataValue);
const updateFormValue = updateValueDirty(
origData,
dirtyFlags,
setDirtyFlags,
updateDataValue as (value: unknown) => void
);
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
@@ -107,7 +113,7 @@ const WiFiSettingsForm: FC = () => {
const content = () => {
if (!data) {
return <FormLoader onRetry={loadData} errorMessage={errorMessage} />;
return <FormLoader onRetry={loadData} errorMessage={errorMessage || ''} />;
}
const validateAndSubmit = async () => {
@@ -115,8 +121,8 @@ const WiFiSettingsForm: FC = () => {
setFieldErrors(undefined);
await validate(createNetworkSettingsValidator(data), data);
await saveData();
} catch (errors: any) {
setFieldErrors(errors);
} catch (error) {
setFieldErrors(error as ValidateFieldsError);
}
deselectNetwork();
};
@@ -126,23 +132,27 @@ const WiFiSettingsForm: FC = () => {
await loadData();
};
const restart = async () => {
await restartCommand().catch((error) => {
toast.error(error.message);
});
const doRestart = async () => {
setRestarting(true);
await sendAPI({ device: 'system', cmd: 'restart', id: 0 }).catch(
(error: Error) => {
toast.error(error.message);
}
);
};
return (
<>
<Typography sx={{ pt: 2 }} variant="h6" color="primary">
<Typography variant="h6" color="primary">
WiFi
</Typography>
{selectedNetwork ? (
<List>
<ListItem>
<ListItemAvatar>
<Avatar>{isNetworkOpen(selectedNetwork) ? <LockOpenIcon /> : <LockIcon />}</Avatar>
<Avatar>
{isNetworkOpen(selectedNetwork) ? <LockOpenIcon /> : <LockIcon />}
</Avatar>
</ListItemAvatar>
<ListItemText
primary={selectedNetwork.ssid}
@@ -155,16 +165,14 @@ const WiFiSettingsForm: FC = () => {
selectedNetwork.bssid
}
/>
<ListItemSecondaryAction>
<IconButton onClick={setCancel}>
<DeleteIcon />
</IconButton>
</ListItemSecondaryAction>
<IconButton onClick={setCancel}>
<DeleteIcon />
</IconButton>
</ListItem>
</List>
) : (
<ValidatedTextField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
name="ssid"
label={'SSID (' + LL.NETWORK_BLANK_SSID() + ')'}
fullWidth
@@ -175,7 +183,7 @@ const WiFiSettingsForm: FC = () => {
/>
)}
<ValidatedTextField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
name="bssid"
label={'BSSID (' + LL.NETWORK_BLANK_BSSID() + ')'}
fullWidth
@@ -186,7 +194,7 @@ const WiFiSettingsForm: FC = () => {
/>
{(!selectedNetwork || !isNetworkOpen(selectedNetwork)) && (
<ValidatedPasswordField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
name="password"
label={LL.PASSWORD()}
fullWidth
@@ -220,18 +228,30 @@ const WiFiSettingsForm: FC = () => {
<MenuItem value={8}>2 dBm</MenuItem>
</TextField>
<BlockFormControlLabel
control={<Checkbox name="nosleep" checked={data.nosleep} onChange={updateFormValue} />}
control={
<Checkbox
name="nosleep"
checked={data.nosleep}
onChange={updateFormValue}
/>
}
label={LL.NETWORK_DISABLE_SLEEP()}
/>
<BlockFormControlLabel
control={<Checkbox name="bandwidth20" checked={data.bandwidth20} onChange={updateFormValue} />}
control={
<Checkbox
name="bandwidth20"
checked={data.bandwidth20}
onChange={updateFormValue}
/>
}
label={LL.NETWORK_LOW_BAND()}
/>
<Typography sx={{ pt: 2 }} variant="h6" color="primary">
{LL.GENERAL_OPTIONS()}
</Typography>
<ValidatedTextField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
name="hostname"
label={LL.HOSTNAME()}
fullWidth
@@ -241,11 +261,23 @@ const WiFiSettingsForm: FC = () => {
margin="normal"
/>
<BlockFormControlLabel
control={<Checkbox name="enableMDNS" checked={data.enableMDNS} onChange={updateFormValue} />}
control={
<Checkbox
name="enableMDNS"
checked={data.enableMDNS}
onChange={updateFormValue}
/>
}
label={LL.NETWORK_USE_DNS()}
/>
<BlockFormControlLabel
control={<Checkbox name="enableCORS" checked={data.enableCORS} onChange={updateFormValue} />}
control={
<Checkbox
name="enableCORS"
checked={data.enableCORS}
onChange={updateFormValue}
/>
}
label={LL.NETWORK_ENABLE_CORS()}
/>
{data.enableCORS && (
@@ -259,20 +291,20 @@ const WiFiSettingsForm: FC = () => {
margin="normal"
/>
)}
{data.enableIPv6 !== undefined && (
<BlockFormControlLabel
control={<Checkbox name="enableIPv6" checked={data.enableIPv6} onChange={updateFormValue} />}
label={LL.NETWORK_ENABLE_IPV6()}
/>
)}
<BlockFormControlLabel
control={<Checkbox name="static_ip_config" checked={data.static_ip_config} onChange={updateFormValue} />}
control={
<Checkbox
name="static_ip_config"
checked={data.static_ip_config}
onChange={updateFormValue}
/>
}
label={LL.NETWORK_FIXED_IP()}
/>
{data.static_ip_config && (
<>
<ValidatedTextField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
name="local_ip"
label={LL.AP_LOCAL_IP()}
fullWidth
@@ -282,7 +314,7 @@ const WiFiSettingsForm: FC = () => {
margin="normal"
/>
<ValidatedTextField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
name="gateway_ip"
label={LL.NETWORK_GATEWAY()}
fullWidth
@@ -292,7 +324,7 @@ const WiFiSettingsForm: FC = () => {
margin="normal"
/>
<ValidatedTextField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
name="subnet_mask"
label={LL.NETWORK_SUBNET()}
fullWidth
@@ -302,7 +334,7 @@ const WiFiSettingsForm: FC = () => {
margin="normal"
/>
<ValidatedTextField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
name="dns_ip_1"
label="DNS #1"
fullWidth
@@ -312,7 +344,7 @@ const WiFiSettingsForm: FC = () => {
margin="normal"
/>
<ValidatedTextField
fieldErrors={fieldErrors}
fieldErrors={fieldErrors || {}}
name="dns_ip_2"
label="DNS #2"
fullWidth
@@ -325,46 +357,52 @@ const WiFiSettingsForm: FC = () => {
)}
{restartNeeded && (
<MessageBox my={2} level="warning" message={LL.RESTART_TEXT(0)}>
<Button startIcon={<PowerSettingsNewIcon />} variant="contained" color="error" onClick={restart}>
<Button
startIcon={<PowerSettingsNewIcon />}
variant="contained"
color="error"
onClick={doRestart}
>
{LL.RESTART()}
</Button>
</MessageBox>
)}
{!restartNeeded && (selectedNetwork || (dirtyFlags && dirtyFlags.length !== 0)) && (
<ButtonRow>
<Button
startIcon={<CancelIcon />}
disabled={saving}
variant="outlined"
color="primary"
type="submit"
onClick={loadData}
>
{LL.CANCEL()}
</Button>
<Button
startIcon={<WarningIcon color="warning" />}
disabled={saving}
variant="contained"
color="info"
type="submit"
onClick={validateAndSubmit}
>
{LL.APPLY_CHANGES(dirtyFlags.length)}
</Button>
</ButtonRow>
)}
{!restartNeeded &&
(selectedNetwork || (dirtyFlags && dirtyFlags.length !== 0)) && (
<ButtonRow>
<Button
startIcon={<CancelIcon />}
disabled={saving}
variant="outlined"
color="secondary"
type="submit"
onClick={loadData}
>
{LL.CANCEL()}
</Button>
<Button
startIcon={<WarningIcon color="warning" />}
disabled={saving}
variant="contained"
color="info"
type="submit"
onClick={validateAndSubmit}
>
{LL.APPLY_CHANGES(dirtyFlags.length)}
</Button>
</ButtonRow>
)}
</>
);
};
return (
<SectionContent title={LL.SETTINGS_OF(LL.NETWORK(1))} titleGutter>
<SectionContent>
{blocker ? <BlockNavigation blocker={blocker} /> : null}
{restarting ? <RestartMonitor /> : content()}
{restarting ? <SystemMonitor /> : content()}
</SectionContent>
);
};
export default WiFiSettingsForm;
export default NetworkSettings;

View File

@@ -1,4 +1,5 @@
import { createContext } from 'react';
import type { WiFiNetwork } from 'types';
export interface WiFiConnectionContextValue {
@@ -8,4 +9,6 @@ export interface WiFiConnectionContextValue {
}
const WiFiConnectionContextDefaultValue = {} as WiFiConnectionContextValue;
export const WiFiConnectionContext = createContext(WiFiConnectionContextDefaultValue);
export const WiFiConnectionContext = createContext(
WiFiConnectionContextDefaultValue
);

Some files were not shown because too many files have changed in this diff Show More