822 Commits

Author SHA1 Message Date
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
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
328 changed files with 32492 additions and 39346 deletions

View File

@@ -1,55 +1,64 @@
name: 'pre-release' name: 'Build dev release'
on: on:
workflow_dispatch: workflow_dispatch:
push: push:
paths:
- 'src/emsesp_version.h'
branches: branches:
- 'dev' - 'dev'
permissions:
contents: write
jobs: jobs:
pre-release: pre-release:
name: 'Automatic pre-release build' name: 'Build Dev Release'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Enable Corepack
run: corepack enable
- name: Install python 3.11 - name: Install python 3.13
uses: actions/setup-python@v5 uses: actions/setup-python@v5
with: with:
python-version: '3.11' python-version: '3.13'
- name: Install Node.js 20 - name: Install Node.js 22
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: '20.x' node-version: 22
- name: Get EMS-ESP version - name: Checkout repository
uses: actions/checkout@v4
- name: Enable Corepack
run: corepack enable pnpm
- name: Get the EMS-ESP version
id: build_info id: build_info
run: | run: |
version=`grep -E '^#define EMSESP_APP_VERSION' ./src/version.h | awk -F'"' '{print $2}'` version=`grep -E '^#define EMSESP_APP_VERSION' ./src/emsesp_version.h | awk -F'"' '{print $2}'`
echo "VERSION=$version" >> $GITHUB_OUTPUT echo "VERSION=$version" >> $GITHUB_OUTPUT
- name: Install PlatformIO - name: Install PlatformIO
run: | run: |
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install -U platformio pip install -U platformio
python -m pip install intelhex
- name: Build WebUI - name: Build the WebUI
run: | run: |
cd interface cd interface
yarn install pnpm install
yarn typesafe-i18n --no-watch pnpm typesafe-i18n --no-watch
sed -i "s/= 'pl'/= 'en'/" ./src/i18n/i18n-util.ts sed -i "s/= 'pl'/= 'en'/" ./src/i18n/i18n-util.ts
yarn build pnpm build
yarn webUI pnpm webUI
- name: Build all PIO target environments from default_envs - name: Build all PIO target environments
run: | run: |
platformio run platformio run
env:
NO_BUILD_WEBUI: true
- name: Create GitHub Release - name: Create GitHub Release
id: 'automatic_releases' id: 'automatic_releases'

View File

@@ -1,4 +1,4 @@
name: 'github-releases-to-discord' name: 'Publish releases to discord'
on: on:
release: release:

View File

@@ -1,4 +1,4 @@
name: 'pr_check' name: 'Pre-check on PR'
on: on:
workflow_dispatch: workflow_dispatch:

View File

@@ -20,15 +20,12 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Install Build Wrapper
- name: Install sonar-scanner and build-wrapper uses: SonarSource/sonarqube-scan-action/install-build-wrapper@master
uses: SonarSource/sonarcloud-github-c-cpp@v2 - name: Run Build Wrapper
run: build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} make all
- name: Run build-wrapper - name: SonarQube Scan
run: build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} make all uses: SonarSource/sonarqube-scan-action@master
- name: Run sonar-scanner
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: sonar-scanner --define sonar.cfamily.compile-commands="${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json"

View File

@@ -1,4 +1,7 @@
name: 'tagged-release' name: 'Build stable release'
permissions:
contents: write
on: on:
workflow_dispatch: workflow_dispatch:
@@ -8,42 +11,46 @@ on:
jobs: jobs:
tagged-release: tagged-release:
name: 'Tagged Release' name: 'Build Stable Release'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Enable Corepack - name: Install python 3.13
run: corepack enable
- name: Install python 3.11
uses: actions/setup-python@v5 uses: actions/setup-python@v5
with: with:
python-version: '3.11' python-version: '3.13'
- name: Install Node.js 20 - name: Install Node.js 22
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: '20.x' node-version: 22
- name: Checkout repository
uses: actions/checkout@v4
- name: Enable Corepack
run: corepack enable pnpm
- name: Install PlatformIO - name: Install PlatformIO
run: | run: |
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install -U platformio pip install -U platformio
python -m pip install intelhex
- name: Build WebUI - name: Build the WebUI
run: | run: |
cd interface cd interface
yarn install pnpm install
yarn typesafe-i18n --no-watch pnpm typesafe-i18n --no-watch
sed -i "s/= 'pl'/= 'en'/" ./src/i18n/i18n-util.ts sed -i "s/= 'pl'/= 'en'/" ./src/i18n/i18n-util.ts
yarn build pnpm build
yarn webUI pnpm webUI
- name: Build all PIO target environments from default_envs - name: Build all PIO target environments
run: | run: |
platformio run platformio run
env:
NO_BUILD_WEBUI: true
- name: Create GitHub Release - name: Create GitHub Release
uses: emsesp/action-automatic-releases@v1.0.0 uses: emsesp/action-automatic-releases@v1.0.0

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

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

View File

@@ -1,4 +1,4 @@
name: 'test-release' name: 'Build test release'
on: on:
workflow_dispatch: workflow_dispatch:
@@ -6,41 +6,60 @@ on:
branches: branches:
- 'dev2' - 'dev2'
permissions:
contents: read
jobs: jobs:
pre-release: pre-release:
name: 'Automatic test-release build' name: 'Build Test Release'
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions:
contents: write
steps: steps:
- uses: actions/checkout@v4
- name: Enable Corepack - name: Install python 3.13
run: corepack enable uses: actions/setup-python@v5
- uses: actions/setup-python@v5
with: with:
python-version: '3.11' python-version: '3.13'
- name: Use Node.js 20.x
- name: Install Node.js 22
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: '20.x' node-version: 22
- name: Get EMS-ESP source code and version
- name: Checkout repository
uses: actions/checkout@v4
- name: Enable Corepack
run: corepack enable pnpm
- name: Get the EMS-ESP version
id: build_info id: build_info
run: | run: |
version=`grep -E '^#define EMSESP_APP_VERSION' ./src/version.h | awk -F'"' '{print $2}'` version=`grep -E '^#define EMSESP_APP_VERSION' ./src/emsesp_version.h | awk -F'"' '{print $2}'`
echo "VERSION=$version" >> $GITHUB_OUTPUT echo "VERSION=$version" >> $GITHUB_OUTPUT
- name: Install PlatformIO - name: Install PlatformIO
run: | run: |
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install -U platformio pip install -U platformio
- name: Build WebUI python -m pip install intelhex
- name: Build the WebUI
run: | run: |
cd interface cd interface
yarn install pnpm install
yarn typesafe-i18n --no-watch pnpm typesafe-i18n --no-watch
sed -i "s/= 'pl'/= 'en'/" ./src/i18n/i18n-util.ts sed -i "s/= 'pl'/= 'en'/" ./src/i18n/i18n-util.ts
yarn build pnpm build
yarn webUI pnpm webUI
- name: Build all target environments from default_envs
- name: Build all target environments
run: | run: |
platformio run platformio run
env:
NO_BUILD_WEBUI: true
- name: Create GitHub Release - name: Create GitHub Release
id: 'automatic_releases' id: 'automatic_releases'
uses: emsesp/action-automatic-releases@v1.0.0 uses: emsesp/action-automatic-releases@v1.0.0
@@ -52,3 +71,4 @@ jobs:
files: | files: |
CHANGELOG_LATEST.md CHANGELOG_LATEST.md
./build/firmware/*.* ./build/firmware/*.*

16
.gitignore vendored
View File

@@ -12,17 +12,15 @@ cppcheck.out.xml
# platformio # platformio
.pio .pio
pio_local.ini pio_local.ini
*_old
# OS specific # OS specific
.DS_Store .DS_Store
*Thumbs.db *Thumbs.db
# web specfic # web specific
build/ build/
dist/ dist/
/data/www /data/www
/lib/framework/WWWData.h
/interface/build /interface/build
node_modules node_modules
/interface/.eslintcache /interface/.eslintcache
@@ -30,11 +28,10 @@ stats.html
*.sln *.sln
*.sw? *.sw?
.pnp.* .pnp.*
*/.yarn/cache/*
*/.yarn/install-state.gz
analyse.html analyse.html
interface/vite.config.ts.timestamp* interface/vite.config.ts.timestamp*
*.local *.local
src/ESP32React/WWWData.h
# i18n generated files # i18n generated files
interface/src/i18n/i18n-react.tsx interface/src/i18n/i18n-react.tsx
@@ -66,3 +63,12 @@ words-found-verbose.txt
# sonarlint # sonarlint
compile_commands.json compile_commands.json
# pioarduino + hybrid
managed_components
dependencies.lock
CMakeLists.txt
.dummy/*
logs/*
sdkconfig.*
sdkconfig_tasmota_esp32

View File

@@ -5,6 +5,77 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [3.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 ## [3.7.0] 27 October 2024
## **IMPORTANT! BREAKING CHANGES with 3.6.5** ## **IMPORTANT! BREAKING CHANGES with 3.6.5**

View File

@@ -2,33 +2,54 @@
For more details go to [docs.emsesp.org](https://docs.emsesp.org/). For more details go to [docs.emsesp.org](https://docs.emsesp.org/).
## [3.7.1] ## [3.7.3]
## **IMPORTANT! BREAKING CHANGES since v3.7.0**
## Added ## Added
- include HA "unit_of_meas", "stat_cla" and "dev_cla" attributes for Number sensors [#2149](https://github.com/emsesp/EMS-ESP32/issues/2149) - analogsensor types: NTC and RGB-Led
- Bosch CS6800i AW - Silent Mode + Electrical Power Reduction (HP) [#2147](https://github.com/emsesp/EMS-ESP32/issues/2147) - Flag for HMC310 [#2465](https://github.com/emsesp/EMS-ESP32/issues/2465)
- `/api/system/showeralert` and `/api/system/showertimer` [#2182](https://github.com/emsesp/EMS-ESP32/issues/2182) - boiler auxheatersource [#2489](https://github.com/emsesp/EMS-ESP32/discussions/2489)
- MX400 [#2198](https://github.com/emsesp/EMS-ESP32/issues/2198) - thermostat last error for RC100/300 [#2501](https://github.com/emsesp/EMS-ESP32/issues/2501)
- SM200 values [#2212](https://github.com/emsesp/EMS-ESP32/discussions/2212) - boiler 0xC6 telegram [#1963](https://github.com/emsesp/EMS-ESP32/issues/1963)
- CS6800i changes [#2448](https://github.com/emsesp/EMS-ESP32/issues/2448), [#2449](https://github.com/emsesp/EMS-ESP32/issues/2449)
- charging pump [#2544](https://github.com/emsesp/EMS-ESP32/issues/2544)
- hybrid CSH5800iG [#2569](https://github.com/emsesp/EMS-ESP32/issues/2569)
- add EMS Device details to Home Assistant MQTT Discovery
- disinfection command [#2601](https://github.com/emsesp/EMS-ESP32/issues/2601)
- added new board profile for upcoming BBQKees E32V2.2
- set differential pressure entity in Mixer device
- set set climate action cooling/heating in HA [#2583](https://github.com/emsesp/EMS-ESP32/issues/2583)
- Internal sensors of E32V2_2
- FW200 display options [#2610](https://github.com/emsesp/EMS-ESP32/discussions/2610)
- CR11 mode settings OFF/MANUAL depends on selTemp [#2437](https://github.com/emsesp/EMS-ESP32/issues/2437)
- Fuse settings for BBQKees boards
- Analogsensors for pulse output [#2624](https://github.com/emsesp/EMS-ESP32/discussions/2624)
- Analogsensors frequency input [#2631](https://github.com/emsesp/EMS-ESP32/discussions/2631)
- SRC plus thermostats [#2636](https://github.com/emsesp/EMS-ESP32/issues/2636)
- Greenstar 2000 [#2645](https://github.com/emsesp/EMS-ESP32/issues/2645)
## Fixed ## Fixed
- Modbus integration in 3.7.0 missing offset [#2148](https://github.com/emsesp/EMS-ESP32/issues/2148) - dhw/switchtime [#2490](https://github.com/emsesp/EMS-ESP32/issues/2490)
- fix changing TZ in NTPsettings without clearing enable+server, added DST support [#2142](https://github.com/emsesp/EMS-ESP32/issues/2142) - switch to secure mqtt [#2492](https://github.com/emsesp/EMS-ESP32/issues/2492)
- Support MQTT Discovery (AD) with Domoticz [#2177](https://github.com/emsesp/EMS-ESP32/issues/2177) - update link buttons [#2497](https://github.com/emsesp/EMS-ESP32/issues/2497)
- wwExtra (dhw extra) changed from temperature reading to number - refresh scheduler states [#2502](https://github.com/emsesp/EMS-ESP32/discussions/2502)
- auxheaterstatus [#2192](https://github.com/emsesp/EMS-ESP32/issues/2192) - also rebuild HA config on mqtt connect for scheduler, custom and shower
- lastCode character check [#2189](https://github.com/emsesp/EMS-ESP32/issues/2189) - FB100 controls the hc, not the master [#2510](https://github.com/emsesp/EMS-ESP32/issues/2510)
- reading too many telegram parts - IPM DHW module, [#2524](https://github.com/emsesp/EMS-ESP32/issues/2524)
- heatpump cost UOMs [#2188](https://github.com/emsesp/EMS-ESP32/issues/2188) - charge optimization [#2543](https://github.com/emsesp/EMS-ESP32/issues/2543)
- analog dac output and inputs on dac pins [#2201](https://github.com/emsesp/EMS-ESP32/discussions/2201) - shower active state retained, shows correctly in HA
- api memory leak [#2216](https://github.com/emsesp/EMS-ESP32/issues/2216) - MQTT Command Topic with slashes [#2571](https://github.com/emsesp/EMS-ESP32/issues/2571)
- modbus multiple mixers [#2229](https://github.com/emsesp/EMS-ESP32/issues/2229) - Add pulsed water meter input to V1.3 gateway with Lilygo S3 [#2550](https://github.com/emsesp/EMS-ESP32/issues/2550)
- Last Will (LWT) not set on MQTT Connect [#2247](https://github.com/emsesp/EMS-ESP32/issues/2247) - fix missing long 10-second press of Button to perform a factory reset
- fix wwMaxPower on Junkers ZBS14 [#2609](https://github.com/emsesp/EMS-ESP32/issues/2609)
- ventilation bypass state from telegram 0x55C [#1197](https://github.com/emsesp/EMS-ESP32/issues/1197)
- set selflowtemp for ems+ boilers [#2641](https://github.com/emsesp/EMS-ESP32/discussions/2641)
## Changed ## Changed
- name of wwstarts2 [#2217](https://github.com/emsesp/EMS-ESP32/discussions/2217) - 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

@@ -16,13 +16,23 @@ T := $(shell $(MAKE) $(MAKECMDGOALS) --no-print-directory \
ECHO="COUNTTHIS" | grep -c "COUNTTHIS") ECHO="COUNTTHIS" | grep -c "COUNTTHIS")
N := x N := x
C = $(words $N)$(eval N := x $N) C = $(words $N)$(eval N := x $N)
ECHO = python $(I)/echo_progress.py --stepno=$C --nsteps=$T ECHO = python3 $(I)/scripts/echo_progress.py --stepno=$C --nsteps=$T
endif endif
# number of parallel compiles # determine number of parallel compiles based on OS
JOBS ?= $(shell nproc) 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
MAKEFLAGS += -j $(JOBS) -l $(JOBS) MAKEFLAGS += -j $(JOBS) -l $(JOBS)
# $(info Number of jobs: $(JOBS))
#---------------------------------------------------------------------- #----------------------------------------------------------------------
# Project Structure # Project Structure
#---------------------------------------------------------------------- #----------------------------------------------------------------------
@@ -32,26 +42,20 @@ MAKEFLAGS += -j $(JOBS) -l $(JOBS)
# INCLUDES is a list of directories containing header files # 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 # LIBRARIES is a list of directories containing libraries, this must be the top level containing include and lib
#---------------------------------------------------------------------- #----------------------------------------------------------------------
#TARGET := $(notdir $(CURDIR))
TARGET := emsesp TARGET := emsesp
BUILD := build 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/* 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 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 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 := LIBRARIES :=
CPPCHECK = cppcheck CPPCHECK = cppcheck
# CHECKFLAGS = -q --force --std=c++17 CHECKFLAGS = -q --force --std=gnu++17
CHECKFLAGS = -q --force --std=c++11
#---------------------------------------------------------------------- #----------------------------------------------------------------------
# Languages Standard # Languages Standard
#---------------------------------------------------------------------- #----------------------------------------------------------------------
C_STANDARD := -std=c17 C_STANDARD := -std=c17
CXX_STANDARD := -std=gnu++14 CXX_STANDARD := -std=gnu++17
# C_STANDARD := -std=c11
# CXX_STANDARD := -std=c++11
#---------------------------------------------------------------------- #----------------------------------------------------------------------
# Defined Symbols # Defined Symbols
@@ -60,7 +64,7 @@ DEFINES += -DARDUINOJSON_ENABLE -DARDUINOJSON_ENABLE_ARDUINO_STRING -DARDUINOJSO
DEFINES += -DEMSESP_STANDALONE -DEMSESP_TEST -DEMSESP_DEBUG -DEMC_RX_BUFFER_SIZE=1500 DEFINES += -DEMSESP_STANDALONE -DEMSESP_TEST -DEMSESP_DEBUG -DEMC_RX_BUFFER_SIZE=1500
DEFINES += $(ARGS) DEFINES += $(ARGS)
DEFAULTS = -DEMSESP_DEFAULT_LOCALE=\"en\" -DEMSESP_DEFAULT_TX_MODE=8 -DEMSESP_DEFAULT_VERSION=\"3.7.1-dev\" -DEMSESP_DEFAULT_BOARD_PROFILE=\"S3\" DEFAULTS = -DEMSESP_DEFAULT_LOCALE=\"en\" -DEMSESP_DEFAULT_TX_MODE=8 -DEMSESP_DEFAULT_VERSION=\"3.7.3-dev\" -DEMSESP_DEFAULT_BOARD_PROFILE=\"S32S3\"
#---------------------------------------------------------------------- #----------------------------------------------------------------------
# Sources & Files # Sources & Files
@@ -94,14 +98,16 @@ CXX := /usr/bin/g++
# LDFLAGS Linker Flags # LDFLAGS Linker Flags
#---------------------------------------------------------------------- #----------------------------------------------------------------------
CPPFLAGS += $(DEFINES) $(DEFAULTS) $(INCLUDE) CPPFLAGS += $(DEFINES) $(DEFAULTS) $(INCLUDE)
CPPFLAGS += -ggdb CPPFLAGS += -ggdb -g3 -MMD
CPPFLAGS += -g3 CPPFLAGS += -flto=auto -fno-lto
CPPFLAGS += -Os CPPFLAGS += -Wall -Wextra -Werror -Wswitch-enum
CPPFLAGS += -Wno-unused-parameter -Wno-missing-braces -Wno-vla-cxx-extension
CPPFLAGS += $(EXTRA_CPPFLAGS)
CFLAGS += $(CPPFLAGS) CFLAGS += $(CPPFLAGS)
CFLAGS += -Wall -Wextra -Werror -Wswitch-enum CXXFLAGS += $(CPPFLAGS)
CFLAGS += -Wno-tautological-constant-out-of-range-compare -Wno-unused-parameter -Wno-inconsistent-missing-override -Wno-missing-braces -Wno-unused-lambda-capture -Wno-sign-compare LDFLAGS =
CXXFLAGS += $(CFLAGS) -MMD
#---------------------------------------------------------------------- #----------------------------------------------------------------------
# Compiler & Linker Commands # Compiler & Linker Commands
@@ -142,7 +148,7 @@ COMPILE.cpp = $(CXX) $(CXX_STANDARD) $(CXXFLAGS) $(DEPFLAGS) -c $< -o $@
.SILENT: $(OUTPUT) .SILENT: $(OUTPUT)
all: $(OUTPUT) all: $(OUTPUT)
@$(ECHO) All done @$(ECHO) Build complete.
$(OUTPUT): $(OBJS) $(OUTPUT): $(OBJS)
@mkdir -p $(@D) @mkdir -p $(@D)

View File

@@ -60,7 +60,7 @@ It requires a small circuit to interface with the EMS bus which can be purchased
## 🚀&nbsp; **Installing** ## 🚀&nbsp; **Installing**
Head over to [download.emsesp.org](https://download.emsesp.org) for instructions on how to install EMS-ESP. There is also further details on which boards are supported in [this section](https://docs.emsesp.org/Getting-Started/#first-time-install) of the documentation. Head over to [download.emsesp.org](https://download.emsesp.org) for instructions on how to install EMS-ESP. There is also further details on which boards are supported in [this section](https://docs.emsesp.org/Installing/) of the documentation.
## 📋&nbsp; **Documentation** ## 📋&nbsp; **Documentation**
@@ -88,7 +88,7 @@ If you like **EMS-ESP**, please give it a ✨ on GitHub, or even better fork it
- [uuid-\*](https://github.com/nomis/mcu-uuid-console) from @nomis. The console, syslog, telnet and logging are based off these awesome open source libraries - [uuid-\*](https://github.com/nomis/mcu-uuid-console) from @nomis. The console, syslog, telnet and logging are based off these awesome open source libraries
- [ArduinoJson](https://github.com/bblanchon/ArduinoJson) for all the JSON processing - [ArduinoJson](https://github.com/bblanchon/ArduinoJson) for all the JSON processing
- [espMqttClient](https://github.com/bertmelis/espMqttClient) for the MQTT client - [espMqttClient](https://github.com/bertmelis/espMqttClient) for the MQTT client
- ESPAsyncWebServer and AsyncTCP for the Web server and TCP backends, with custom modifications for performance - [ESPAsyncWebServer](https://github.com/ESP32Async/ESPAsyncWebServer) and [AsyncTCP](https://github.com/ESP32Async/AsyncTCP) for the Web server and TCP backends
## 📜&nbsp; **License** ## 📜&nbsp; **License**

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"
}

View File

@@ -28,6 +28,11 @@
"**/i18n/**", "**/i18n/**",
"/project-words.txt", "/project-words.txt",
"Makefile", "Makefile",
"src/modbus_entity_parameters.hpp" "**/*.ini",
"**/*.json",
"src/core/modbus_entity_parameters.hpp",
"sdkconfig.*",
"managed_components/**",
"pnpm-*.yaml"
] ]
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -13,9 +13,9 @@ telegram_type_id,name,is_fetched
0x19,UBAMonitorSlow, 0x19,UBAMonitorSlow,
0x1A,UBASetPoints, 0x1A,UBASetPoints,
0x1C,UBAMaintenanceStatus, 0x1C,UBAMaintenanceStatus,
0x1E,WM10TempMessage, 0x1E,HydrTemp,
0x23,JunkersSetMixer,fetched 0x23,JunkersSetMixer,fetched
0x26,UBASettingsWW,fetched 0x27,UBASettingsWW,fetched
0x28,WeatherComp,fetched 0x28,WeatherComp,fetched
0x2A,MC110Status, 0x2A,MC110Status,
0x2E,Meters, 0x2E,Meters,
@@ -29,7 +29,7 @@ telegram_type_id,name,is_fetched
0x3B,Energy, 0x3B,Energy,
0x3D,RC35Set, 0x3D,RC35Set,
0x3E,RC35Monitor, 0x3E,RC35Monitor,
0x3F,RC30Timer, 0x3F,RC35Timer,
0x40,RC30Temp, 0x40,RC30Temp,
0x41,RC30Monitor, 0x41,RC30Monitor,
0x42,RC35Timer2, 0x42,RC35Timer2,
@@ -62,7 +62,9 @@ telegram_type_id,name,is_fetched
0xB1,RC10Monitor, 0xB1,RC10Monitor,
0xBB,HybridSettings,fetched 0xBB,HybridSettings,fetched
0xBF,ErrorMessage, 0xBF,ErrorMessage,
0xC0,RCErrorMessage,
0xC2,UBAErrorMessage3, 0xC2,UBAErrorMessage3,
0xC6,UBAErrorMessage3,
0xD1,UBAOutdoorTemp, 0xD1,UBAOutdoorTemp,
0xE3,UBAMonitorSlowPlus2, 0xE3,UBAMonitorSlowPlus2,
0xE4,UBAMonitorFastPlus, 0xE4,UBAMonitorFastPlus,
@@ -74,13 +76,14 @@ telegram_type_id,name,is_fetched
0x0103,ISM1StatusMessage,fetched 0x0103,ISM1StatusMessage,fetched
0x0104,ISM2StatusMessage, 0x0104,ISM2StatusMessage,
0x010C,IPMStatusMessage, 0x010C,IPMStatusMessage,
0x011E,IPMTempMessage, 0x011E,JunkersDisp,fetched
0x012E,HPEnergy1, 0x012E,HPEnergy1,
0x013B,HPEnergy2, 0x013B,HPEnergy2,
0x0165,JunkersSet, 0x0165,JunkersSet,
0x0166,JunkersSet, 0x0166,JunkersSet,
0x0167,JunkersSet, 0x0167,JunkersSet,
0x0168,JunkersSet, 0x0168,JunkersSet,
0x016E,Absent,fetched
0x016F,JunkersMonitor, 0x016F,JunkersMonitor,
0x0170,JunkersMonitor, 0x0170,JunkersMonitor,
0x0171,JunkersMonitor, 0x0171,JunkersMonitor,
@@ -93,8 +96,9 @@ telegram_type_id,name,is_fetched
0x023A,RC300OutdoorTemp,fetched 0x023A,RC300OutdoorTemp,fetched
0x023E,PVSettings,fetched 0x023E,PVSettings,fetched
0x0240,RC300Settings,fetched 0x0240,RC300Settings,fetched
0x0241,RC300Settings,fetched
0x0267,RC300Floordry, 0x0267,RC300Floordry,
0x0269,RC300Holiday1,fetched 0x0269,RC300Holiday,fetched
0x0291,HPMode,fetched 0x0291,HPMode,fetched
0x0292,HPMode,fetched 0x0292,HPMode,fetched
0x0293,HPMode,fetched 0x0293,HPMode,fetched
@@ -109,7 +113,7 @@ telegram_type_id,name,is_fetched
0x02A2,RC300Curves, 0x02A2,RC300Curves,
0x02A5,RC300Monitor, 0x02A5,RC300Monitor,
0x02A6,RC300Monitor, 0x02A6,RC300Monitor,
0x02A7,CRFMonitor, 0x02A7,RC300Monitor,
0x02A8,RC300Monitor, 0x02A8,RC300Monitor,
0x02A9,RC300Monitor, 0x02A9,RC300Monitor,
0x02AA,RC300Monitor, 0x02AA,RC300Monitor,
@@ -138,6 +142,7 @@ telegram_type_id,name,is_fetched
0x02D2,RC300Set2, 0x02D2,RC300Set2,
0x02D6,HPPump2,fetched 0x02D6,HPPump2,fetched
0x02D7,MMPLUSStatusMessage, 0x02D7,MMPLUSStatusMessage,
0x02E0,UBASetPoints,
0x02F5,RC300WWmode,fetched 0x02F5,RC300WWmode,fetched
0x02F6,RC300WW2mode,fetched 0x02F6,RC300WW2mode,fetched
0x0313,MMPLUSConfigMessage_WWC,fetched 0x0313,MMPLUSConfigMessage_WWC,fetched
@@ -159,6 +164,7 @@ telegram_type_id,name,is_fetched
0x0380,SM100CollectorConfig,fetched 0x0380,SM100CollectorConfig,fetched
0x038E,SM100Energy,fetched 0x038E,SM100Energy,fetched
0x0391,SM100Time,fetched 0x0391,SM100Time,fetched
0x043F,CRHolidays,fetched
0x0467,HPSet, 0x0467,HPSet,
0x0468,HPSet, 0x0468,HPSet,
0x0469,HPSet, 0x0469,HPSet,
@@ -193,6 +199,7 @@ telegram_type_id,name,is_fetched
0x04AA,HPPower2,fetched 0x04AA,HPPower2,fetched
0x04AE,HPEnergy,fetched 0x04AE,HPEnergy,fetched
0x04AF,HPMeters,fetched 0x04AF,HPMeters,fetched
0x055C,VentilationSet,fetched
0x056B,VentilationMode,fetched 0x056B,VentilationMode,fetched
0x0583,VentilationMonitor, 0x0583,VentilationMonitor,
0x0585,Blowerspeed, 0x0585,Blowerspeed,
1 telegram_type_id name is_fetched
13 0x19 UBAMonitorSlow
14 0x1A UBASetPoints
15 0x1C UBAMaintenanceStatus
16 0x1E WM10TempMessage HydrTemp
17 0x23 JunkersSetMixer fetched
18 0x26 0x27 UBASettingsWW fetched
19 0x28 WeatherComp fetched
20 0x2A MC110Status
21 0x2E Meters
29 0x3B Energy
30 0x3D RC35Set
31 0x3E RC35Monitor
32 0x3F RC30Timer RC35Timer
33 0x40 RC30Temp
34 0x41 RC30Monitor
35 0x42 RC35Timer2
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
76 0x0103 ISM1StatusMessage fetched
77 0x0104 ISM2StatusMessage
78 0x010C IPMStatusMessage
79 0x011E IPMTempMessage 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
96 0x023A RC300OutdoorTemp fetched
97 0x023E PVSettings fetched
98 0x0240 RC300Settings fetched
99 0x0241 RC300Settings fetched
100 0x0267 RC300Floordry
101 0x0269 RC300Holiday1 RC300Holiday fetched
102 0x0291 HPMode fetched
103 0x0292 HPMode fetched
104 0x0293 HPMode fetched
113 0x02A2 RC300Curves
114 0x02A5 RC300Monitor
115 0x02A6 RC300Monitor
116 0x02A7 CRFMonitor RC300Monitor
117 0x02A8 RC300Monitor
118 0x02A9 RC300Monitor
119 0x02AA RC300Monitor
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
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
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

View File

@@ -1,28 +0,0 @@
"""
Print makefile progress
From https://stackoverflow.com/questions/451413/make-makefile-progress-indication
"""
import argparse
import math
import sys
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--stepno", type=int, required=True)
parser.add_argument("--nsteps", type=int, required=True)
parser.add_argument("remainder", nargs=argparse.REMAINDER)
args = parser.parse_args()
nchars = int(math.log(args.nsteps, 10)) + 1
fmt_str = "[{:Xd}/{:Xd}]({:6.2f}%)".replace("X", str(nchars))
progress = 100 * args.stepno / args.nsteps
sys.stdout.write(fmt_str.format(args.stepno, args.nsteps, progress))
for item in args.remainder:
sys.stdout.write(" ")
sys.stdout.write(item)
sys.stdout.write("\n")
if __name__ == "__main__":
main()

View File

@@ -1,4 +0,0 @@
/.yarn/** linguist-vendored
/.yarn/releases/* binary
/.yarn/plugins/**/* binary
/.pnp.* binary linguist-generated

View File

@@ -4,5 +4,4 @@ dist/
src/i18n/* src/i18n/*
.prettierrc .prettierrc
.yarn/ .typesafe-i18n.json
.typesafe-i18n.json

File diff suppressed because one or more lines are too long

View File

@@ -1,3 +0,0 @@
nodeLinker: node-modules
yarnPath: .yarn/releases/yarn-4.5.3.cjs

View File

@@ -1,6 +1,6 @@
{ {
"name": "EMS-ESP", "name": "EMS-ESP",
"version": "3.7.1", "version": "3.7.2",
"description": "EMS-ESP WebUI", "description": "EMS-ESP WebUI",
"homepage": "https://emsesp.org", "homepage": "https://emsesp.org",
"author": "proddy, emsesp.org", "author": "proddy, emsesp.org",
@@ -8,59 +8,60 @@
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {
"preinstall": "npx only-allow pnpm",
"dev": "vite dev", "dev": "vite dev",
"build": "vite build", "build": "vite build",
"preview": "vite preview", "preview": "vite preview",
"build-hosted": "typesafe-i18n --no-watch && vite build --mode hosted", "build-hosted": "typesafe-i18n && vite build --mode hosted",
"preview-standalone": "typesafe-i18n --no-watch && vite build && concurrently -c \"auto\" \"yarn:mock-rest\" \"vite preview\"", "preview-standalone": "typesafe-i18n --no-watch && vite build && concurrently -c \"auto\" \"pnpm:mock-rest\" \"vite preview\"",
"mock-rest": "bun --watch ../mock-api/rest_server.ts", "mock-rest": "bun --watch ../mock-api/restServer.ts",
"standalone": "concurrently -c \"auto\" \"typesafe-i18n\" \"yarn:mock-rest\" \"vite\"", "standalone": "concurrently -c \"auto\" \"typesafe-i18n\" \"pnpm:mock-rest\" \"vite\"",
"typesafe-i18n": "typesafe-i18n --no-watch", "typesafe-i18n": "typesafe-i18n --no-watch",
"webUI": "node progmem-generator.js", "webUI": "node progmem-generator.js",
"format": "prettier -l -w '**/*.{ts,tsx,js,css,json,md}'", "format": "prettier -l -w '**/*.{ts,tsx,js,css,json,md}'",
"lint": "eslint . --fix" "lint": "eslint . --fix"
}, },
"dependencies": { "dependencies": {
"@alova/adapter-xhr": "2.0.10", "@alova/adapter-xhr": "2.2.1",
"@emotion/react": "^11.13.5", "@emotion/react": "^11.14.0",
"@emotion/styled": "^11.13.5", "@emotion/styled": "^11.14.1",
"@mui/icons-material": "^6.1.9", "@mui/icons-material": "^7.3.4",
"@mui/material": "^6.1.9", "@mui/material": "^7.3.4",
"@table-library/react-table-library": "4.1.7", "@table-library/react-table-library": "4.1.15",
"alova": "3.2.5", "alova": "3.3.4",
"async-validator": "^4.2.5", "async-validator": "^4.2.5",
"formidable": "^3.5.4",
"jwt-decode": "^4.0.0", "jwt-decode": "^4.0.0",
"mime-types": "^2.1.35", "magic-string": "^0.30.19",
"preact": "^10.25.0", "mime-types": "^3.0.1",
"react": "^18.3.1", "preact": "^10.27.2",
"react-dom": "^18.3.1", "react": "^19.2.0",
"react-icons": "^5.3.0", "react-dom": "^19.2.0",
"react-router": "^7.0.1", "react-icons": "^5.5.0",
"react-toastify": "^10.0.6", "react-router": "^7.9.4",
"react-toastify": "^11.0.5",
"typesafe-i18n": "^5.26.2", "typesafe-i18n": "^5.26.2",
"typescript": "^5.7.2" "typescript": "^5.9.3"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.26.0", "@babel/core": "^7.28.4",
"@eslint/js": "^9.15.0", "@eslint/js": "^9.37.0",
"@preact/compat": "^18.3.1", "@preact/compat": "^18.3.1",
"@preact/preset-vite": "^2.9.2", "@preact/preset-vite": "^2.10.2",
"@trivago/prettier-plugin-sort-imports": "^4.3.0", "@trivago/prettier-plugin-sort-imports": "^5.2.2",
"@types/formidable": "^3", "@types/node": "^24.7.0",
"@types/node": "^22.10.1", "@types/react": "^19.2.2",
"@types/react": "^18.3.12", "@types/react-dom": "^19.2.1",
"@types/react-dom": "^18.3.1", "concurrently": "^9.2.1",
"concurrently": "^9.1.0", "eslint": "^9.37.0",
"eslint": "^9.15.0", "eslint-config-prettier": "^10.1.8",
"eslint-config-prettier": "^9.1.0", "prettier": "^3.6.2",
"formidable": "^3.5.2", "rollup-plugin-visualizer": "^6.0.4",
"prettier": "^3.4.1", "terser": "^5.44.0",
"rollup-plugin-visualizer": "^5.12.0", "typescript-eslint": "^8.46.0",
"terser": "^5.36.0", "vite": "^7.1.9",
"typescript-eslint": "8.16.0",
"vite": "^6.0.1",
"vite-plugin-imagemin": "^0.6.1", "vite-plugin-imagemin": "^0.6.1",
"vite-tsconfig-paths": "^5.1.3" "vite-tsconfig-paths": "^5.1.4"
}, },
"packageManager": "yarn@4.5.3" "packageManager": "pnpm@10.18.1+sha512.77a884a165cbba2d8d1c19e3b4880eee6d2fcabd0d879121e282196b80042351d5eb3ca0935fa599da1dc51265cc68816ad2bddd2a2de5ea9fdf92adbec7cd34"
} }

6057
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

@@ -12,7 +12,7 @@ import zlib from 'zlib';
const ARDUINO_INCLUDES = '#include <Arduino.h>\n\n'; const ARDUINO_INCLUDES = '#include <Arduino.h>\n\n';
const INDENT = ' '; const INDENT = ' ';
const outputPath = '../lib/framework/WWWData.h'; const outputPath = '../src/ESP32React/WWWData.h';
const sourcePath = './dist'; const sourcePath = './dist';
const bytesPerLine = 20; const bytesPerLine = 20;
var totalSize = 0; var totalSize = 0;

View File

@@ -13,8 +13,9 @@
local('Roboto'), local('Roboto'),
local('Roboto-Regular'), local('Roboto-Regular'),
url(../fonts/re.woff2) format('woff2'); url(../fonts/re.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0104-0107, U+0118-0119, U+011E-011F, U+0130-0131, unicode-range:
U+0141-0144, U+0152-0153, U+015A-015B, U+015E-015F, U+0179-017C, U+02BB-02BC, U+0000-00FF, U+0104-0107, U+0118-0119, U+011E-011F, U+0130-0131, U+0141-0144,
U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+0152-0153, U+015A-015B, U+015E-015F, U+0179-017C, U+02BB-02BC, U+02C6, U+02DA,
U+2212, U+2215, U+FEFF, U+FFFD; 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,27 +1,44 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { Slide, ToastContainer } from 'react-toastify'; import { ToastContainer, Zoom } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.min.css';
import AppRouting from 'AppRouting'; import AppRouting from 'AppRouting';
import CustomTheme from 'CustomTheme'; import CustomTheme from 'CustomTheme';
import TypesafeI18n from 'i18n/i18n-react'; 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 { loadLocaleAsync } from 'i18n/i18n-util.async';
import { localStorageDetector } from 'typesafe-i18n/detectors'; import { detectLocale, navigatorDetector } from 'typesafe-i18n/detectors';
const detectedLocale = detectLocale(localStorageDetector); const availableLocales = [
'de',
'en',
'it',
'fr',
'nl',
'no',
'pl',
'sk',
'sv',
'tr',
'cz'
];
const App = () => { const App = () => {
const [wasLoaded, setWasLoaded] = useState(false); const [wasLoaded, setWasLoaded] = useState(false);
const [locale, setLocale] = useState<Locales>('en');
useEffect(() => { useEffect(() => {
void loadLocaleAsync(detectedLocale).then(() => setWasLoaded(true)); // determine locale, take from session if set other default to browser language
const browserLocale = detectLocale('en', availableLocales, navigatorDetector);
const newLocale = (localStorage.getItem('lang') || browserLocale) as Locales;
localStorage.setItem('lang', newLocale);
setLocale(newLocale);
void loadLocaleAsync(newLocale).then(() => setWasLoaded(true));
}, []); }, []);
if (!wasLoaded) return null; if (!wasLoaded) return null;
return ( return (
<TypesafeI18n locale={detectedLocale}> <TypesafeI18n locale={locale}>
<CustomTheme> <CustomTheme>
<AppRouting /> <AppRouting />
<ToastContainer <ToastContainer
@@ -29,14 +46,17 @@ const App = () => {
autoClose={3000} autoClose={3000}
hideProgressBar={false} hideProgressBar={false}
newestOnTop={false} newestOnTop={false}
closeOnClick={true} closeOnClick
rtl={false} rtl={false}
pauseOnFocusLoss={false} pauseOnFocusLoss
draggable={false} draggable={false}
pauseOnHover={false} pauseOnHover={false}
transition={Slide} transition={Zoom}
closeButton={false} closeButton={false}
theme="light" theme="dark"
toastStyle={{
border: '1px solid #177ac9'
}}
/> />
</CustomTheme> </CustomTheme>
</TypesafeI18n> </TypesafeI18n>

View File

@@ -15,7 +15,6 @@ import DownloadUpload from 'app/settings/DownloadUpload';
import MqttSettings from 'app/settings/MqttSettings'; import MqttSettings from 'app/settings/MqttSettings';
import NTPSettings from 'app/settings/NTPSettings'; import NTPSettings from 'app/settings/NTPSettings';
import Settings from 'app/settings/Settings'; import Settings from 'app/settings/Settings';
import Version from 'app/settings/Version';
import Network from 'app/settings/network/Network'; import Network from 'app/settings/network/Network';
import Security from 'app/settings/security/Security'; import Security from 'app/settings/security/Security';
import APStatus from 'app/status/APStatus'; import APStatus from 'app/status/APStatus';
@@ -26,6 +25,7 @@ import NTPStatus from 'app/status/NTPStatus';
import NetworkStatus from 'app/status/NetworkStatus'; import NetworkStatus from 'app/status/NetworkStatus';
import Status from 'app/status/Status'; import Status from 'app/status/Status';
import SystemLog from 'app/status/SystemLog'; import SystemLog from 'app/status/SystemLog';
import Version from 'app/status/Version';
import { Layout } from 'components'; import { Layout } from 'components';
import { AuthenticatedContext } from 'contexts/authentication'; import { AuthenticatedContext } from 'contexts/authentication';
@@ -48,17 +48,17 @@ const AuthenticatedRouting = () => {
<Route path="/status/ntp" element={<NTPStatus />} /> <Route path="/status/ntp" element={<NTPStatus />} />
<Route path="/status/ap" element={<APStatus />} /> <Route path="/status/ap" element={<APStatus />} />
<Route path="/status/network" element={<NetworkStatus />} /> <Route path="/status/network" element={<NetworkStatus />} />
<Route path="/status/version" element={<Version />} />
{me.admin && ( {me.admin && (
<> <>
<Route path="/settings" element={<Settings />} /> <Route path="/settings" element={<Settings />} />
<Route path="/settings/version" element={<Version />} />
<Route path="/settings/application" element={<ApplicationSettings />} /> <Route path="/settings/application" element={<ApplicationSettings />} />
<Route path="/settings/mqtt" element={<MqttSettings />} /> <Route path="/settings/mqtt" element={<MqttSettings />} />
<Route path="/settings/ntp" element={<NTPSettings />} /> <Route path="/settings/ntp" element={<NTPSettings />} />
<Route path="/settings/ap" element={<APSettings />} /> <Route path="/settings/ap" element={<APSettings />} />
<Route path="/settings/modules" element={<Modules />} /> <Route path="/settings/modules" element={<Modules />} />
<Route path="/settings/upload" element={<DownloadUpload />} /> <Route path="/settings/downloadUpload" element={<DownloadUpload />} />
<Route path="/settings/network/*" element={<Network />} /> <Route path="/settings/network/*" element={<Network />} />
<Route path="/settings/security/*" element={<Security />} /> <Route path="/settings/security/*" element={<Security />} />

View File

@@ -1,11 +1,7 @@
import type { FC } from 'react'; import type { FC } from 'react';
import { CssBaseline } from '@mui/material'; import { CssBaseline, ThemeProvider, responsiveFontSizes } from '@mui/material';
import { import { createTheme } from '@mui/material/styles';
ThemeProvider,
createTheme,
responsiveFontSizes
} from '@mui/material/styles';
import type { RequiredChildrenProps } from 'utils'; import type { RequiredChildrenProps } from 'utils';

View File

@@ -5,7 +5,7 @@ import type {
Action, Action,
Activity, Activity,
CoreData, CoreData,
DashboardItem, DashboardData,
DeviceData, DeviceData,
DeviceEntity, DeviceEntity,
Entities, Entities,
@@ -22,7 +22,7 @@ import type {
// Dashboard // Dashboard
export const readDashboard = () => export const readDashboard = () =>
alovaInstance.Get<DashboardItem[]>('/rest/dashboardData', { alovaInstance.Get<DashboardData>('/rest/dashboardData', {
responseType: 'arraybuffer' // uses msgpack responseType: 'arraybuffer' // uses msgpack
}); });
@@ -143,7 +143,8 @@ export const readCustomEntities = () =>
o_name: ei.name, o_name: ei.name,
o_writeable: ei.writeable, o_writeable: ei.writeable,
o_value: ei.value, o_value: ei.value,
o_deleted: ei.deleted o_deleted: ei.deleted,
o_hide: ei.hide
})); }));
} }
}); });

View File

@@ -22,7 +22,7 @@ export const alovaInstance = createAlova({
method.config.headers.Authorization = method.config.headers.Authorization =
'Bearer ' + localStorage.getItem(ACCESS_TOKEN); 'Bearer ' + localStorage.getItem(ACCESS_TOKEN);
} }
// for simulating vrey slow networks // for simulating very slow networks
// return new Promise((resolve) => { // return new Promise((resolve) => {
// const random = 3000 + Math.random() * 2000; // const random = 3000 + Math.random() * 2000;
// setTimeout(resolve, Math.floor(random)); // setTimeout(resolve, Math.floor(random));

View File

@@ -2,7 +2,7 @@ import type { LogSettings, SystemStatus } from 'types';
import { alovaInstance, alovaInstanceGH } from './endpoints'; import { alovaInstance, alovaInstanceGH } from './endpoints';
// systemStatus - also used to ping in Restart monitor for pinging // systemStatus - also used to ping in System Monitor for pinging
export const readSystemStatus = () => export const readSystemStatus = () =>
alovaInstance.Get<SystemStatus>('/rest/systemStatus'); alovaInstance.Get<SystemStatus>('/rest/systemStatus');
@@ -14,16 +14,25 @@ export const updateLogSettings = (data: LogSettings) =>
export const fetchLogES = () => alovaInstance.Get('/es/log'); 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 = () => export const getStableVersion = () =>
alovaInstanceGH.Get('latest', { alovaInstanceGH.Get('latest', {
transform(response: { data: { name: string } }) { cacheFor: 60 * 10 * 1000,
return response.data.name.substring(1); transform(response: { data: { name: string; published_at: string } }) {
return {
name: response.data.name.substring(1),
published_at: response.data.published_at
};
} }
}); });
export const getDevVersion = () => export const getDevVersion = () =>
alovaInstanceGH.Get('tags/latest', { alovaInstanceGH.Get('tags/latest', {
transform(response: { data: { name: string } }) { cacheFor: 60 * 10 * 1000,
return response.data.name.split(/\s+/).splice(-1)[0].substring(1); 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
};
} }
}); });

View File

@@ -57,7 +57,7 @@ const CustomEntities = () => {
if (!dialogOpen && !numChanges) { if (!dialogOpen && !numChanges) {
void fetchEntities(); void fetchEntities();
} }
}, 3000); });
const { send: writeEntities } = useRequest( const { send: writeEntities } = useRequest(
(data: Entities) => writeCustomEntities(data), (data: Entities) => writeCustomEntities(data),
@@ -76,6 +76,7 @@ const CustomEntities = () => {
ei.factor !== ei.o_factor || ei.factor !== ei.o_factor ||
ei.value_type !== ei.o_value_type || ei.value_type !== ei.o_value_type ||
ei.writeable !== ei.o_writeable || ei.writeable !== ei.o_writeable ||
ei.hide !== ei.o_hide ||
ei.deleted !== ei.o_deleted || ei.deleted !== ei.o_deleted ||
(ei.value || '') !== (ei.o_value || '') (ei.value || '') !== (ei.o_value || '')
); );
@@ -83,7 +84,7 @@ const CustomEntities = () => {
const entity_theme = useTheme({ const entity_theme = useTheme({
Table: ` 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: ` BaseRow: `
font-size: 14px; font-size: 14px;
@@ -147,6 +148,7 @@ const CustomEntities = () => {
factor: condensed_ei.factor, factor: condensed_ei.factor,
uom: condensed_ei.uom, uom: condensed_ei.uom,
writeable: condensed_ei.writeable, writeable: condensed_ei.writeable,
hide: condensed_ei.hide,
value_type: condensed_ei.value_type, value_type: condensed_ei.value_type,
value: condensed_ei.value value: condensed_ei.value
})) }))
@@ -195,6 +197,26 @@ const CustomEntities = () => {
}); });
}; };
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 = () => { const addEntityItem = () => {
setCreating(true); setCreating(true);
setSelectedEntityItem({ setSelectedEntityItem({
@@ -220,7 +242,7 @@ const CustomEntities = () => {
: typeof value === 'number' : typeof value === 'number'
? new Intl.NumberFormat().format(value) + ? new Intl.NumberFormat().format(value) +
(uom === 0 ? '' : ' ' + DeviceValueUOM_s[uom]) (uom === 0 ? '' : ' ' + DeviceValueUOM_s[uom])
: (value as string); : (value as string) + (uom === 0 ? '' : ' ' + DeviceValueUOM_s[uom]);
} }
function showHex(value: number, digit: number) { function showHex(value: number, digit: number) {
@@ -296,6 +318,7 @@ const CustomEntities = () => {
creating={creating} creating={creating}
onClose={onDialogClose} onClose={onDialogClose}
onSave={onDialogSave} onSave={onDialogSave}
onDup={onDialogDup}
selectedItem={selectedEntityItem} selectedItem={selectedEntityItem}
validator={entityItemValidation(entities, selectedEntityItem)} validator={entityItemValidation(entities, selectedEntityItem)}
/> />

View File

@@ -2,7 +2,11 @@ import { useEffect, useState } from 'react';
import AddIcon from '@mui/icons-material/Add'; import AddIcon from '@mui/icons-material/Add';
import CancelIcon from '@mui/icons-material/Cancel'; import CancelIcon from '@mui/icons-material/Cancel';
import CommentsDisabledOutlinedIcon from '@mui/icons-material/CommentsDisabledOutlined';
import DoneIcon from '@mui/icons-material/Done'; import DoneIcon from '@mui/icons-material/Done';
import EditOffOutlinedIcon from '@mui/icons-material/EditOffOutlined';
import EditOutlinedIcon from '@mui/icons-material/EditOutlined';
import InsertCommentOutlinedIcon from '@mui/icons-material/InsertCommentOutlined';
import RemoveIcon from '@mui/icons-material/RemoveCircleOutline'; import RemoveIcon from '@mui/icons-material/RemoveCircleOutline';
import { import {
Box, Box,
@@ -12,11 +16,11 @@ import {
DialogActions, DialogActions,
DialogContent, DialogContent,
DialogTitle, DialogTitle,
Grid,
InputAdornment, InputAdornment,
MenuItem, MenuItem,
TextField TextField
} from '@mui/material'; } from '@mui/material';
import Grid from '@mui/material/Grid2';
import { dialogStyle } from 'CustomTheme'; import { dialogStyle } from 'CustomTheme';
import type Schema from 'async-validator'; import type Schema from 'async-validator';
@@ -34,6 +38,7 @@ interface CustomEntitiesDialogProps {
creating: boolean; creating: boolean;
onClose: () => void; onClose: () => void;
onSave: (ei: EntityItem) => void; onSave: (ei: EntityItem) => void;
onDup: (ei: EntityItem) => void;
selectedItem: EntityItem; selectedItem: EntityItem;
validator: Schema; validator: Schema;
} }
@@ -43,6 +48,7 @@ const CustomEntitiesDialog = ({
creating, creating,
onClose, onClose,
onSave, onSave,
onDup,
selectedItem, selectedItem,
validator validator
}: CustomEntitiesDialogProps) => { }: CustomEntitiesDialogProps) => {
@@ -59,7 +65,11 @@ const CustomEntitiesDialog = ({
setEditItem({ setEditItem({
...selectedItem, ...selectedItem,
device_id: selectedItem.device_id.toString(16).toUpperCase(), device_id: selectedItem.device_id.toString(16).toUpperCase(),
type_id: selectedItem.type_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]); }, [open, selectedItem]);
@@ -80,6 +90,12 @@ const CustomEntitiesDialog = ({
if (typeof editItem.type_id === 'string') { if (typeof editItem.type_id === 'string') {
editItem.type_id = parseInt(editItem.type_id, 16); 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); onSave(editItem);
} catch (error) { } catch (error) {
setFieldErrors(error as ValidateFieldsError); setFieldErrors(error as ValidateFieldsError);
@@ -91,6 +107,10 @@ const CustomEntitiesDialog = ({
onSave(editItem); onSave(editItem);
}; };
const dup = () => {
onDup(editItem);
};
return ( return (
<Dialog sx={dialogStyle} open={open} onClose={handleClose}> <Dialog sx={dialogStyle} open={open} onClose={handleClose}>
<DialogTitle> <DialogTitle>
@@ -112,6 +132,20 @@ const CustomEntitiesDialog = ({
onChange={updateFormValue} onChange={updateFormValue}
/> />
</Grid> </Grid>
<Grid mt={3}>
<BlockFormControlLabel
control={
<Checkbox
icon={<InsertCommentOutlinedIcon htmlColor="white" />}
checkedIcon={<CommentsDisabledOutlinedIcon color="primary" />}
checked={editItem.hide}
onChange={updateFormValue}
name="hide"
/>
}
label="API/MQTT"
/>
</Grid>
<Grid> <Grid>
<TextField <TextField
name="ram" name="ram"
@@ -128,25 +162,45 @@ const CustomEntitiesDialog = ({
</TextField> </TextField>
</Grid> </Grid>
{editItem.ram === 1 && ( {editItem.ram === 1 && (
<Grid> <>
<TextField <Grid>
name="value" <TextField
label={LL.DEFAULT(0) + ' ' + LL.VALUE(0)} name="value"
type="string" label={LL.DEFAULT(0) + ' ' + LL.VALUE(0)}
value={editItem.value as string} type="string"
variant="outlined" value={editItem.value as string}
onChange={updateFormValue} variant="outlined"
fullWidth onChange={updateFormValue}
margin="normal" fullWidth
/> margin="normal"
</Grid> />
</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 && ( {editItem.ram === 0 && (
<> <>
<Grid mt={3} size={9}> <Grid mt={3}>
<BlockFormControlLabel <BlockFormControlLabel
control={ control={
<Checkbox <Checkbox
icon={<EditOffOutlinedIcon color="primary" />}
checkedIcon={<EditOutlinedIcon htmlColor="white" />}
checked={editItem.writeable} checked={editItem.writeable}
onChange={updateFormValue} onChange={updateFormValue}
name="writeable" name="writeable"
@@ -255,7 +309,7 @@ const CustomEntitiesDialog = ({
<TextField <TextField
name="factor" name="factor"
label={LL.FACTOR()} label={LL.FACTOR()}
value={numberValue(editItem.factor)} value={numberValue(editItem.factor as number)}
variant="outlined" variant="outlined"
onChange={updateFormValue} onChange={updateFormValue}
sx={{ width: '11ch' }} sx={{ width: '11ch' }}
@@ -291,16 +345,42 @@ const CustomEntitiesDialog = ({
<ValidatedTextField <ValidatedTextField
fieldErrors={fieldErrors} fieldErrors={fieldErrors}
name="factor" name="factor"
label="Bytes" label={LL.BYTES()}
value={numberValue(editItem.factor)} value={numberValue(editItem.factor as number)}
sx={{ width: '11ch' }} sx={{ width: '11ch' }}
variant="outlined" variant="outlined"
onChange={updateFormValue} onChange={updateFormValue}
margin="normal" margin="normal"
type="number" type="number"
slotProps={{
htmlInput: { step: '1', min: '1', max: '255' }
}}
/> />
</Grid> </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> </Grid>
@@ -316,6 +396,15 @@ const CustomEntitiesDialog = ({
> >
{LL.REMOVE()} {LL.REMOVE()}
</Button> </Button>
<Button
sx={{ ml: 1 }}
startIcon={<AddIcon />}
variant="outlined"
color="primary"
onClick={dup}
>
{LL.DUPLICATE()}
</Button>
</Box> </Box>
)} )}
<Button <Button

View File

@@ -16,6 +16,7 @@ import {
DialogActions, DialogActions,
DialogContent, DialogContent,
DialogTitle, DialogTitle,
Grid,
InputAdornment, InputAdornment,
Link, Link,
MenuItem, MenuItem,
@@ -24,7 +25,6 @@ import {
ToggleButtonGroup, ToggleButtonGroup,
Typography Typography
} from '@mui/material'; } from '@mui/material';
import Grid from '@mui/material/Grid2';
import { import {
Body, Body,
@@ -38,7 +38,7 @@ import {
import { useTheme } from '@table-library/react-table-library/theme'; import { useTheme } from '@table-library/react-table-library/theme';
import { dialogStyle } from 'CustomTheme'; import { dialogStyle } from 'CustomTheme';
import { useRequest } from 'alova/client'; import { useRequest } from 'alova/client';
import RestartMonitor from 'app/status/RestartMonitor'; import SystemMonitor from 'app/status/SystemMonitor';
import { import {
BlockNavigation, BlockNavigation,
ButtonRow, ButtonRow,
@@ -306,7 +306,7 @@ const Customizations = () => {
const filter_entity = (de: DeviceEntity) => const filter_entity = (de: DeviceEntity) =>
(de.m & selectedFilters || !selectedFilters) && (de.m & selectedFilters || !selectedFilters) &&
formatName(de, true).includes(search); formatName(de, true).toLowerCase().includes(search.toLowerCase());
const maskDisabled = (set: boolean) => { const maskDisabled = (set: boolean) => {
setDeviceEntities( setDeviceEntities(
@@ -593,7 +593,7 @@ const Customizations = () => {
</Button> </Button>
</Grid> </Grid>
<Grid> <Grid>
<Typography variant="subtitle2" color="primary"> <Typography variant="subtitle2" color="grey">
{LL.SHOWING()}&nbsp;{shown_data.length}/{deviceEntities.length} {LL.SHOWING()}&nbsp;{shown_data.length}/{deviceEntities.length}
&nbsp;{LL.ENTITIES(deviceEntities.length)} &nbsp;{LL.ENTITIES(deviceEntities.length)}
</Typography> </Typography>
@@ -737,7 +737,7 @@ const Customizations = () => {
return ( return (
<SectionContent> <SectionContent>
{blocker ? <BlockNavigation blocker={blocker} /> : null} {blocker ? <BlockNavigation blocker={blocker} /> : null}
{restarting ? <RestartMonitor /> : renderContent()} {restarting ? <SystemMonitor /> : renderContent()}
{selectedDeviceEntity && ( {selectedDeviceEntity && (
<SettingsCustomizationsDialog <SettingsCustomizationsDialog
open={dialogOpen} open={dialogOpen}

View File

@@ -10,10 +10,10 @@ import {
DialogActions, DialogActions,
DialogContent, DialogContent,
DialogTitle, DialogTitle,
Grid,
TextField, TextField,
Typography Typography
} from '@mui/material'; } from '@mui/material';
import Grid from '@mui/material/Grid2';
import { dialogStyle } from 'CustomTheme'; import { dialogStyle } from 'CustomTheme';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';

View File

@@ -1,10 +1,12 @@
import { useContext, useEffect, useState } from 'react'; import { useContext, useEffect, useState } from 'react';
import { IconContext } from 'react-icons/lib'; import { IconContext } from 'react-icons/lib';
import { Link } from 'react-router';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import ChevronRightIcon from '@mui/icons-material/ChevronRight'; import ChevronRightIcon from '@mui/icons-material/ChevronRight';
import EditIcon from '@mui/icons-material/Edit'; import EditIcon from '@mui/icons-material/Edit';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
import UnfoldLessIcon from '@mui/icons-material/UnfoldLess'; import UnfoldLessIcon from '@mui/icons-material/UnfoldLess';
import UnfoldMoreIcon from '@mui/icons-material/UnfoldMore'; import UnfoldMoreIcon from '@mui/icons-material/UnfoldMore';
import { import {
@@ -12,16 +14,20 @@ import {
IconButton, IconButton,
ToggleButton, ToggleButton,
ToggleButtonGroup, ToggleButtonGroup,
Tooltip,
Typography Typography
} from '@mui/material'; } from '@mui/material';
import Grid from '@mui/material/Grid2';
import { Body, Cell, Row, Table } from '@table-library/react-table-library/table'; import { Body, Cell, Row, Table } from '@table-library/react-table-library/table';
import { useTheme } from '@table-library/react-table-library/theme'; import { useTheme } from '@table-library/react-table-library/theme';
import { CellTree, useTree } from '@table-library/react-table-library/tree'; import { CellTree, useTree } from '@table-library/react-table-library/tree';
import { useRequest } from 'alova/client'; import { useRequest } from 'alova/client';
import { FormLoader, SectionContent, useLayoutTitle } from 'components'; import {
ButtonTooltip,
FormLoader,
MessageBox,
SectionContent,
useLayoutTitle
} from 'components';
import { AuthenticatedContext } from 'contexts/authentication'; import { AuthenticatedContext } from 'contexts/authentication';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';
import { useInterval, usePersistState } from 'utils'; import { useInterval, usePersistState } from 'utils';
@@ -54,13 +60,12 @@ const Dashboard = () => {
const { const {
data, data,
send: fetchDashboard, send: fetchDashboard,
error, error
loading
} = useRequest(readDashboard, { } = useRequest(readDashboard, {
initialData: [] initialData: { connected: true, nodes: [] }
}).onSuccess((event) => { }).onSuccess((event) => {
if (event.data.length !== parentNodes) { if (event.data.nodes.length !== parentNodes) {
setParentNodes(event.data.length); // count number of parents/devices setParentNodes(event.data.nodes.length); // count number of parents/devices
} }
}); });
@@ -120,7 +125,7 @@ const Dashboard = () => {
}); });
const tree = useTree( const tree = useTree(
{ nodes: data }, { nodes: data.nodes },
{ {
onChange: undefined // not used but needed onChange: undefined // not used but needed
}, },
@@ -149,11 +154,11 @@ const Dashboard = () => {
if (!deviceValueDialogOpen) { if (!deviceValueDialogOpen) {
void fetchDashboard(); void fetchDashboard();
} }
}, 3000); });
useEffect(() => { useEffect(() => {
showAll showAll
? tree.fns.onAddAll(data.map((item: DashboardItem) => item.id)) // expand tree ? tree.fns.onAddAll(data.nodes.map((item: DashboardItem) => item.id)) // expand tree
: tree.fns.onRemoveAll(); // collapse tree : tree.fns.onRemoveAll(); // collapse tree
}, [parentNodes]); }, [parentNodes]);
@@ -223,120 +228,133 @@ const Dashboard = () => {
return <FormLoader onRetry={fetchDashboard} errorMessage={error?.message} />; return <FormLoader onRetry={fetchDashboard} errorMessage={error?.message} />;
} }
const hasFavEntities = data.nodes.filter(
(item: DashboardItem) => item.id <= 90
).length;
return ( return (
<> <>
<Box {!data.connected && (
sx={{ <MessageBox mb={2} level="error" message={LL.EMS_BUS_WARNING()} />
backgroundColor: 'black', )}
pt: 1,
pl: 2
}}
>
<Grid container spacing={0} justifyContent="flex-start">
<Grid size={11}>
<Typography mb={2} variant="body1" color="warning">
{LL.DASHBOARD_1()}.
</Typography>
</Grid>
<Grid size={1} alignItems="end"> {data.connected && data.nodes.length > 0 && !hasFavEntities && (
<ToggleButtonGroup <MessageBox mb={2} level="warning">
color="primary" <Typography>
size="small" {LL.NO_DATA_1()}&nbsp;
value={showAll} <Link to="/customizations" style={{ color: 'white' }}>
exclusive {LL.CUSTOMIZATIONS()}
onChange={handleShowAll} </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 && (
<>
<ToggleButtonGroup
color="primary"
size="small"
value={showAll}
exclusive
onChange={handleShowAll}
>
<ButtonTooltip title={LL.ALLVALUES()} arrow>
<ToggleButton value={true}> <ToggleButton value={true}>
<UnfoldMoreIcon sx={{ fontSize: 18 }} /> <UnfoldMoreIcon sx={{ fontSize: 18 }} />
</ToggleButton> </ToggleButton>
</ButtonTooltip>
<ButtonTooltip title={LL.COMPACT()} arrow>
<ToggleButton value={false}> <ToggleButton value={false}>
<UnfoldLessIcon sx={{ fontSize: 18 }} /> <UnfoldLessIcon sx={{ fontSize: 18 }} />
</ToggleButton> </ToggleButton>
</ToggleButtonGroup> </ButtonTooltip>
</Grid> </ToggleButtonGroup>
</Grid> <ButtonTooltip title={LL.DASHBOARD_1()} arrow>
</Box> <HelpOutlineIcon color="primary" sx={{ ml: 1, fontSize: 20 }} />
</ButtonTooltip>
<Box <Box
padding={1} padding={1}
justifyContent="center" justifyContent="center"
flexDirection="column" flexDirection="column"
sx={{ sx={{
borderRadius: 1, borderRadius: 1,
border: '1px solid grey' border: '1px solid grey'
}} }}
> >
<IconContext.Provider <IconContext.Provider
value={{ value={{
color: 'lightblue', color: 'lightblue',
size: '16', size: '18',
style: { verticalAlign: 'middle' } style: { verticalAlign: 'middle' }
}} }}
>
{!loading && data.length === 0 ? (
<Typography variant="subtitle2" color="secondary">
{LL.NO_DATA()}
</Typography>
) : (
<Table
data={{ nodes: data }}
theme={dashboard_theme}
layout={{ custom: true }}
tree={tree}
> >
{(tableList: DashboardItem[]) => ( <Table
<Body> data={{ nodes: data.nodes }}
{tableList.map((di: DashboardItem) => ( theme={dashboard_theme}
<Row layout={{ custom: true }}
key={di.id} tree={tree}
item={di} >
onClick={() => editDashboardValue(di)} {(tableList: DashboardItem[]) => (
> <Body>
{di.id > 99 ? ( {tableList.map((di: DashboardItem) => (
<> <Row
<Cell>{showName(di)}</Cell> key={di.id}
<Cell> item={di}
<Tooltip onClick={() => editDashboardValue(di)}
placement="left" >
title={formatValue(LL, di.dv?.v, di.dv?.u)} {di.id > 99 ? (
arrow <>
> <Cell>{showName(di)}</Cell>
<span>{formatValue(LL, di.dv?.v, di.dv?.u)}</span> <Cell>
</Tooltip> <ButtonTooltip
</Cell> title={formatValue(LL, di.dv?.v, di.dv?.u)}
>
<span>{formatValue(LL, di.dv?.v, di.dv?.u)}</span>
</ButtonTooltip>
</Cell>
<Cell> <Cell>
{me.admin && {me.admin &&
di.dv?.c && di.dv?.c &&
!hasMask(di.dv.id, DeviceEntityMask.DV_READONLY) && ( !hasMask(
<IconButton di.dv.id,
size="small" DeviceEntityMask.DV_READONLY
onClick={() => editDashboardValue(di)} ) && (
> <IconButton
<EditIcon size="small"
color="primary" onClick={() => editDashboardValue(di)}
sx={{ fontSize: 16 }} >
/> <EditIcon
</IconButton> color="primary"
)} sx={{ fontSize: 16 }}
</Cell> />
</> </IconButton>
) : ( )}
<> </Cell>
<CellTree item={di}>{showName(di)}</CellTree> </>
<Cell /> ) : (
<Cell /> <>
</> <CellTree item={di}>{showName(di)}</CellTree>
)} <Cell />
</Row> <Cell />
))} </>
</Body> )}
)} </Row>
</Table> ))}
)} </Body>
</IconContext.Provider> )}
</Box> </Table>
</IconContext.Provider>
</Box>
</>
)}
</> </>
); );
}; };

View File

@@ -10,15 +10,16 @@ import { useNavigate } from 'react-router';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import CommentsDisabledOutlinedIcon from '@mui/icons-material/CommentsDisabledOutlined'; import CommentsDisabledOutlinedIcon from '@mui/icons-material/CommentsDisabledOutlined';
import ConstructionIcon from '@mui/icons-material/Construction';
import EditIcon from '@mui/icons-material/Edit'; import EditIcon from '@mui/icons-material/Edit';
import EditOffOutlinedIcon from '@mui/icons-material/EditOffOutlined'; import EditOffOutlinedIcon from '@mui/icons-material/EditOffOutlined';
import FormatListNumberedIcon from '@mui/icons-material/FormatListNumbered';
import DownloadIcon from '@mui/icons-material/GetApp'; import DownloadIcon from '@mui/icons-material/GetApp';
import HighlightOffIcon from '@mui/icons-material/HighlightOff'; import HighlightOffIcon from '@mui/icons-material/HighlightOff';
import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'; import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';
import KeyboardArrowDownOutlinedIcon from '@mui/icons-material/KeyboardArrowDownOutlined'; import KeyboardArrowDownOutlinedIcon from '@mui/icons-material/KeyboardArrowDownOutlined';
import KeyboardArrowUpOutlinedIcon from '@mui/icons-material/KeyboardArrowUpOutlined'; import KeyboardArrowUpOutlinedIcon from '@mui/icons-material/KeyboardArrowUpOutlined';
import PlayArrowIcon from '@mui/icons-material/PlayArrow'; import PlayArrowIcon from '@mui/icons-material/PlayArrow';
import SearchIcon from '@mui/icons-material/Search';
import StarIcon from '@mui/icons-material/Star'; import StarIcon from '@mui/icons-material/Star';
import StarBorderOutlinedIcon from '@mui/icons-material/StarBorderOutlined'; import StarBorderOutlinedIcon from '@mui/icons-material/StarBorderOutlined';
import UnfoldMoreOutlinedIcon from '@mui/icons-material/UnfoldMoreOutlined'; import UnfoldMoreOutlinedIcon from '@mui/icons-material/UnfoldMoreOutlined';
@@ -30,17 +31,16 @@ import {
DialogActions, DialogActions,
DialogContent, DialogContent,
DialogTitle, DialogTitle,
Grid,
IconButton, IconButton,
InputAdornment,
List, List,
ListItem, ListItem,
ListItemText, ListItemText,
Tooltip, TextField,
type TooltipProps, ToggleButton,
Typography, Typography
styled,
tooltipClasses
} from '@mui/material'; } from '@mui/material';
import Grid from '@mui/material/Grid2';
import { useRowSelect } from '@table-library/react-table-library/select'; import { useRowSelect } from '@table-library/react-table-library/select';
import { SortToggleType, useSort } from '@table-library/react-table-library/sort'; import { SortToggleType, useSort } from '@table-library/react-table-library/sort';
@@ -57,7 +57,12 @@ import { useTheme } from '@table-library/react-table-library/theme';
import type { Action, State } from '@table-library/react-table-library/types/common'; import type { Action, State } from '@table-library/react-table-library/types/common';
import { dialogStyle } from 'CustomTheme'; import { dialogStyle } from 'CustomTheme';
import { useRequest } from 'alova/client'; import { useRequest } from 'alova/client';
import { MessageBox, SectionContent, useLayoutTitle } from 'components'; import {
ButtonTooltip,
MessageBox,
SectionContent,
useLayoutTitle
} from 'components';
import { AuthenticatedContext } from 'contexts/authentication'; import { AuthenticatedContext } from 'contexts/authentication';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';
import { useInterval } from 'utils'; import { useInterval } from 'utils';
@@ -80,6 +85,7 @@ const Devices = () => {
const [deviceValueDialogOpen, setDeviceValueDialogOpen] = useState(false); const [deviceValueDialogOpen, setDeviceValueDialogOpen] = useState(false);
const [showDeviceInfo, setShowDeviceInfo] = useState(false); const [showDeviceInfo, setShowDeviceInfo] = useState(false);
const [selectedDevice, setSelectedDevice] = useState<number>(); const [selectedDevice, setSelectedDevice] = useState<number>();
const [search, setSearch] = useState('');
const navigate = useNavigate(); const navigate = useNavigate();
@@ -221,20 +227,6 @@ const Devices = () => {
} }
]); ]);
const ButtonTooltip = styled(({ className, ...props }: TooltipProps) => (
<Tooltip {...props} arrow classes={{ popper: className }} />
))(({ theme }) => ({
[`& .${tooltipClasses.arrow}`]: {
color: theme.palette.success.main
},
[`& .${tooltipClasses.tooltip}`]: {
backgroundColor: theme.palette.success.main,
color: 'rgba(0, 0, 0, 0.87)',
boxShadow: theme.shadows[1],
fontSize: 10
}
}));
const getSortIcon = (state: State, sortKey: unknown) => { const getSortIcon = (state: State, sortKey: unknown) => {
if (state.sortKey === sortKey && state.reverse) { if (state.sortKey === sortKey && state.reverse) {
return <KeyboardArrowDownOutlinedIcon />; return <KeyboardArrowDownOutlinedIcon />;
@@ -284,6 +276,7 @@ const Devices = () => {
const resetDeviceSelect = () => { const resetDeviceSelect = () => {
device_select.fns.onRemoveAll(); device_select.fns.onRemoveAll();
setSearch('');
}; };
const escFunction = useCallback( const escFunction = useCallback(
@@ -419,7 +412,7 @@ const Devices = () => {
if (!deviceValueDialogOpen) { if (!deviceValueDialogOpen) {
selectedDevice ? void sendDeviceData(selectedDevice) : void sendCoreData(); selectedDevice ? void sendDeviceData(selectedDevice) : void sendCoreData();
} }
}, 3000); });
const deviceValueDialogSave = async (devicevalue: DeviceValue) => { const deviceValueDialogSave = async (devicevalue: DeviceValue) => {
const id = Number(device_select.state.id); const id = Number(device_select.state.id);
@@ -522,7 +515,7 @@ const Devices = () => {
<IconContext.Provider <IconContext.Provider
value={{ value={{
color: 'lightblue', color: 'lightblue',
size: '16', size: '18',
style: { verticalAlign: 'middle' } style: { verticalAlign: 'middle' }
}} }}
> >
@@ -604,8 +597,14 @@ const Devices = () => {
); );
const shown_data = onlyFav const shown_data = onlyFav
? deviceData.nodes.filter((dv) => hasMask(dv.id, DeviceEntityMask.DV_FAVORITE)) ? deviceData.nodes.filter(
: deviceData.nodes; (dv) =>
hasMask(dv.id, DeviceEntityMask.DV_FAVORITE) &&
dv.id.slice(2).toLowerCase().includes(search.toLowerCase())
)
: deviceData.nodes.filter((dv) =>
dv.id.slice(2).toLowerCase().includes(search.toLowerCase())
);
const deviceIndex = coreData.devices.findIndex( const deviceIndex = coreData.devices.findIndex(
(d) => d.id === device_select.state.id (d) => d.id === device_select.state.id
@@ -628,56 +627,84 @@ const Devices = () => {
border: '1px solid #177ac9' border: '1px solid #177ac9'
}} }}
> >
<Box sx={{ border: '1px solid #177ac9' }}> <Box sx={{ p: 1 }}>
<Typography noWrap variant="subtitle1" color="warning.main" sx={{ ml: 1 }}>
{coreData.devices[deviceIndex].n}&nbsp;(
{coreData.devices[deviceIndex].tn})
</Typography>
<Grid container justifyContent="space-between"> <Grid container justifyContent="space-between">
<Typography sx={{ ml: 1 }} variant="subtitle2" color="grey"> <Typography noWrap variant="subtitle1" color="warning.main">
{LL.SHOWING() + {coreData.devices[deviceIndex].n}&nbsp;(
' ' + {coreData.devices[deviceIndex].tn})
shown_data.length +
'/' +
coreData.devices[deviceIndex].e +
' ' +
LL.ENTITIES(shown_data.length)}
<ButtonTooltip title="Info">
<IconButton onClick={() => setShowDeviceInfo(true)}>
<InfoOutlinedIcon color="primary" sx={{ fontSize: 18 }} />
</IconButton>
</ButtonTooltip>
{me.admin && (
<ButtonTooltip title={LL.CUSTOMIZATIONS()}>
<IconButton onClick={customize}>
<FormatListNumberedIcon 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()}>
<IconButton onClick={() => setOnlyFav(!onlyFav)}>
{onlyFav ? (
<StarIcon color="primary" sx={{ fontSize: 18 }} />
) : (
<StarBorderOutlinedIcon color="primary" sx={{ fontSize: 18 }} />
)}
</IconButton>
</ButtonTooltip>
</Typography> </Typography>
<Grid justifyContent="flex-end"> <Grid justifyContent="flex-end">
<ButtonTooltip title={LL.CANCEL()}> <ButtonTooltip title={LL.CLOSE()}>
<IconButton onClick={resetDeviceSelect}> <IconButton onClick={resetDeviceSelect}>
<HighlightOffIcon color="primary" sx={{ fontSize: 18 }} /> <HighlightOffIcon color="primary" sx={{ fontSize: 18 }} />
</IconButton> </IconButton>
</ButtonTooltip> </ButtonTooltip>
</Grid> </Grid>
</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 +
'/' +
coreData.devices[deviceIndex].e +
' ' +
LL.ENTITIES(shown_data.length)}
</span>
</Box> </Box>
<Table <Table

View File

@@ -11,12 +11,12 @@ import {
DialogContent, DialogContent,
DialogTitle, DialogTitle,
FormHelperText, FormHelperText,
Grid,
InputAdornment, InputAdornment,
MenuItem, MenuItem,
TextField, TextField,
Typography Typography
} from '@mui/material'; } from '@mui/material';
import Grid from '@mui/material/Grid2';
import { dialogStyle } from 'CustomTheme'; import { dialogStyle } from 'CustomTheme';
import type Schema from 'async-validator'; import type Schema from 'async-validator';

View File

@@ -41,7 +41,8 @@ const Help = () => {
useRequest(() => callAction({ action: 'getCustomSupport' })).onSuccess((event) => { useRequest(() => callAction({ action: 'getCustomSupport' })).onSuccess((event) => {
if (event && event.data && Object.keys(event.data).length !== 0) { if (event && event.data && Object.keys(event.data).length !== 0) {
const data = event.data.Support; const data = (event.data as { Support: { img_url?: string; html?: string[] } })
.Support;
if (data.img_url) { if (data.img_url) {
setCustomSupportIMG(data.img_url); setCustomSupportIMG(data.img_url);
} }
@@ -51,20 +52,6 @@ const Help = () => {
} }
}); });
// const { send: sendExportAllValues } = useRequest(
// () => callAction({ action: 'export', param: 'allvalues' }),
// {
// immediate: false
// }
// )
// .onSuccess((event) => {
// saveFile(event.data, 'allvalues', '.txt');
// toast.info(LL.DOWNLOAD_SUCCESSFUL());
// })
// .onError((error) => {
// toast.error(error.message);
// });
const { send: sendAPI } = useRequest((data: APIcall) => API(data), { const { send: sendAPI } = useRequest((data: APIcall) => API(data), {
immediate: false immediate: false
}) })
@@ -73,7 +60,7 @@ const Help = () => {
toast.info(LL.DOWNLOAD_SUCCESSFUL()); toast.info(LL.DOWNLOAD_SUCCESSFUL());
}) })
.onError((error) => { .onError((error) => {
toast.error(error.message); toast.error(String(error.error?.message || 'An error occurred'));
}); });
return ( return (
@@ -114,7 +101,12 @@ const Help = () => {
{me.admin && ( {me.admin && (
<List sx={{ borderRadius: 3, border: '2px solid grey' }}> <List sx={{ borderRadius: 3, border: '2px solid grey' }}>
<ListItem> <ListItem>
<ListItemButton component="a" href="https://docs.emsesp.org"> <ListItemButton
component="a"
target="_blank"
rel="noreferrer"
href="https://docs.emsesp.org"
>
<ListItemAvatar> <ListItemAvatar>
<Avatar sx={{ bgcolor: '#72caf9' }}> <Avatar sx={{ bgcolor: '#72caf9' }}>
<MenuBookIcon /> <MenuBookIcon />
@@ -125,7 +117,12 @@ const Help = () => {
</ListItem> </ListItem>
<ListItem> <ListItem>
<ListItemButton component="a" href="https://discord.gg/3J3GgnzpyT"> <ListItemButton
component="a"
target="_blank"
rel="noreferrer"
href="https://discord.gg/3J3GgnzpyT"
>
<ListItemAvatar> <ListItemAvatar>
<Avatar sx={{ bgcolor: '#72caf9' }}> <Avatar sx={{ bgcolor: '#72caf9' }}>
<CommentIcon /> <CommentIcon />
@@ -138,6 +135,8 @@ const Help = () => {
<ListItem> <ListItem>
<ListItemButton <ListItemButton
component="a" component="a"
target="_blank"
rel="noreferrer"
href="https://github.com/emsesp/EMS-ESP32/issues/new/choose" href="https://github.com/emsesp/EMS-ESP32/issues/new/choose"
> >
<ListItemAvatar> <ListItemAvatar>
@@ -165,21 +164,16 @@ const Help = () => {
</Button> </Button>
</Box> </Box>
{/* <Button
sx={{ ml: 2 }}
startIcon={<DownloadIcon />}
variant="outlined"
color="primary"
onClick={() => sendExportAllValues()}
>
{LL.DOWNLOAD(1)}&nbsp;{LL.ALLVALUES()}
</Button> */}
<Divider sx={{ mt: 4 }} /> <Divider sx={{ mt: 4 }} />
<Typography color="white" variant="subtitle1" align="center" mt={1}> <Typography color="white" variant="subtitle1" align="center" mt={1}>
&copy;&nbsp; &copy;&nbsp;
<Link target="_blank" href="https://emsesp.org" color="primary"> <Link
target="_blank"
rel="noreferrer"
href="https://emsesp.org"
color="primary"
>
{'emsesp.org'} {'emsesp.org'}
</Link> </Link>
</Typography> </Typography>

View File

@@ -10,9 +10,9 @@ import {
DialogActions, DialogActions,
DialogContent, DialogContent,
DialogTitle, DialogTitle,
Grid,
TextField TextField
} from '@mui/material'; } from '@mui/material';
import Grid from '@mui/material/Grid2';
import { dialogStyle } from 'CustomTheme'; import { dialogStyle } from 'CustomTheme';
import { BlockFormControlLabel } from 'components'; import { BlockFormControlLabel } from 'components';

View File

@@ -27,6 +27,7 @@ import {
useLayoutTitle useLayoutTitle
} from 'components'; } from 'components';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';
import { useInterval } from 'utils';
import { readSchedule, writeSchedule } from '../../api/app'; import { readSchedule, writeSchedule } from '../../api/app';
import SettingsSchedulerDialog from './SchedulerDialog'; import SettingsSchedulerDialog from './SchedulerDialog';
@@ -73,6 +74,12 @@ const Scheduler = () => {
); );
} }
useInterval(() => {
if (numChanges === 0) {
void fetchSchedule();
}
});
useEffect(() => { useEffect(() => {
const formatter = new Intl.DateTimeFormat(locale, { const formatter = new Intl.DateTimeFormat(locale, {
weekday: 'short', weekday: 'short',

View File

@@ -13,12 +13,12 @@ import {
DialogActions, DialogActions,
DialogContent, DialogContent,
DialogTitle, DialogTitle,
Grid,
TextField, TextField,
ToggleButton, ToggleButton,
ToggleButtonGroup, ToggleButtonGroup,
Typography Typography
} from '@mui/material'; } from '@mui/material';
import Grid from '@mui/material/Grid2';
import { dialogStyle } from 'CustomTheme'; import { dialogStyle } from 'CustomTheme';
import type Schema from 'async-validator'; import type Schema from 'async-validator';

View File

@@ -90,7 +90,7 @@ const Sensors = () => {
if (!temperatureDialogOpen && !analogDialogOpen) { if (!temperatureDialogOpen && !analogDialogOpen) {
void fetchSensorData(); void fetchSensorData();
} }
}, 3000); });
const common_theme = useTheme({ const common_theme = useTheme({
BaseRow: ` BaseRow: `
@@ -439,7 +439,8 @@ const Sensors = () => {
<Cell>{a.n}</Cell> <Cell>{a.n}</Cell>
<Cell stiff>{AnalogTypeNames[a.t]} </Cell> <Cell stiff>{AnalogTypeNames[a.t]} </Cell>
{(a.t === AnalogType.DIGITAL_OUT && a.g !== 25 && a.g !== 26) || {(a.t === AnalogType.DIGITAL_OUT && a.g !== 25 && a.g !== 26) ||
a.t === AnalogType.DIGITAL_IN ? ( a.t === AnalogType.DIGITAL_IN ||
a.t === AnalogType.PULSE ? (
<Cell stiff>{a.v ? LL.ON() : LL.OFF()}</Cell> <Cell stiff>{a.v ? LL.ON() : LL.OFF()}</Cell>
) : ( ) : (
<Cell stiff>{a.t ? formatValue(a.v, a.u) : ''}</Cell> <Cell stiff>{a.t ? formatValue(a.v, a.u) : ''}</Cell>

View File

@@ -10,12 +10,12 @@ import {
DialogActions, DialogActions,
DialogContent, DialogContent,
DialogTitle, DialogTitle,
Grid,
InputAdornment, InputAdornment,
MenuItem, MenuItem,
TextField, TextField,
Typography Typography
} from '@mui/material'; } from '@mui/material';
import Grid from '@mui/material/Grid2';
import { dialogStyle } from 'CustomTheme'; import { dialogStyle } from 'CustomTheme';
import type Schema from 'async-validator'; import type Schema from 'async-validator';
@@ -132,7 +132,9 @@ const SensorsAnalogDialog = ({
))} ))}
</TextField> </TextField>
</Grid> </Grid>
{editItem.t >= AnalogType.COUNTER && editItem.t <= AnalogType.RATE && ( {((editItem.t >= AnalogType.COUNTER && editItem.t <= AnalogType.RATE) ||
(editItem.t >= AnalogType.FREQ_0 &&
editItem.t <= AnalogType.FREQ_2)) && (
<Grid> <Grid>
<TextField <TextField
name="u" name="u"
@@ -171,6 +173,27 @@ const SensorsAnalogDialog = ({
/> />
</Grid> </Grid>
)} )}
{editItem.t === AnalogType.NTC && (
<Grid>
<TextField
name="o"
label={LL.OFFSET()}
value={numberValue(editItem.o)}
sx={{ width: '11ch' }}
type="number"
variant="outlined"
onChange={updateFormValue}
slotProps={{
input: {
startAdornment: (
<InputAdornment position="start">°C</InputAdornment>
)
},
htmlInput: { min: '-20', max: '20', step: '0.1' }
}}
/>
</Grid>
)}
{editItem.t === AnalogType.COUNTER && ( {editItem.t === AnalogType.COUNTER && (
<Grid> <Grid>
<TextField <TextField
@@ -187,6 +210,19 @@ const SensorsAnalogDialog = ({
/> />
</Grid> </Grid>
)} )}
{editItem.t === AnalogType.RGB && (
<Grid>
<TextField
name="o"
label={'RGB ' + LL.VALUE(0)}
value={numberValue(editItem.o)}
type="number"
sx={{ width: '11ch' }}
variant="outlined"
onChange={updateFormValue}
/>
</Grid>
)}
{editItem.t >= AnalogType.COUNTER && editItem.t <= AnalogType.RATE && ( {editItem.t >= AnalogType.COUNTER && editItem.t <= AnalogType.RATE && (
<Grid> <Grid>
<TextField <TextField
@@ -314,6 +350,42 @@ const SensorsAnalogDialog = ({
</Grid> </Grid>
</> </>
)} )}
{editItem.t === AnalogType.PULSE && (
<>
<Grid>
<TextField
name="o"
label={LL.POLARITY()}
value={editItem.o}
sx={{ width: '11ch' }}
select
onChange={updateFormValue}
>
<MenuItem value={0}>{LL.ACTIVEHIGH()}</MenuItem>
<MenuItem value={1}>{LL.ACTIVELOW()}</MenuItem>
</TextField>
</Grid>
<Grid>
<TextField
name="f"
label="Pulse"
value={numberValue(editItem.f)}
type="number"
sx={{ width: '15ch' }}
variant="outlined"
onChange={updateFormValue}
slotProps={{
input: {
startAdornment: (
<InputAdornment position="start">s</InputAdornment>
)
},
htmlInput: { min: '0', max: '10000', step: '0.1' }
}}
/>
</Grid>
</>
)}
</Grid> </Grid>
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>

View File

@@ -9,11 +9,11 @@ import {
DialogActions, DialogActions,
DialogContent, DialogContent,
DialogTitle, DialogTitle,
Grid,
InputAdornment, InputAdornment,
TextField, TextField,
Typography Typography
} from '@mui/material'; } from '@mui/material';
import Grid from '@mui/material/Grid2';
import { dialogStyle } from 'CustomTheme'; import { dialogStyle } from 'CustomTheme';
import type Schema from 'async-validator'; import type Schema from 'async-validator';

View File

@@ -34,7 +34,12 @@ export function formatValue(
if (value === undefined || typeof value === 'boolean') { if (value === undefined || typeof value === 'boolean') {
return ''; return '';
} }
return value as string; return (
(value as string) +
(value === '' || uom === undefined || uom === 0
? ''
: ' ' + DeviceValueUOM_s[uom])
);
} }
switch (uom) { switch (uom) {

View File

@@ -21,6 +21,7 @@ export interface Settings {
dallas_gpio: number; dallas_gpio: number;
dallas_parasite: boolean; dallas_parasite: boolean;
led_gpio: number; led_gpio: number;
led_type: number;
hide_led: boolean; hide_led: boolean;
low_clock: boolean; low_clock: boolean;
notoken_api: boolean; notoken_api: boolean;
@@ -71,7 +72,7 @@ export interface Device {
d: number; // deviceid d: number; // deviceid
p: number; // productid p: number; // productid
v: string; // version v: string; // version
e: number; // entities e: number; // total number of entities
url?: string; // lowercase type name used in API URL url?: string; // lowercase type name used in API URL
} }
@@ -123,6 +124,11 @@ export interface DashboardItem {
nodes?: DashboardItem[]; // children nodes, optional nodes?: DashboardItem[]; // children nodes, optional
} }
export interface DashboardData {
connected: boolean; // true if connected to EMS bus
nodes: DashboardItem[];
}
export interface DeviceValue { export interface DeviceValue {
id: string; // index, contains mask+name id: string; // index, contains mask+name
v?: unknown; // value, Number, String or Boolean - can be undefined v?: unknown; // value, Number, String or Boolean - can be undefined
@@ -182,7 +188,8 @@ export enum DeviceValueUOM {
VOLTS, VOLTS,
MBAR, MBAR,
LH, LH,
CTKWH CTKWH,
HZ
} }
export const DeviceValueUOM_s = [ export const DeviceValueUOM_s = [
@@ -212,7 +219,8 @@ export const DeviceValueUOM_s = [
'V', 'V',
'mbar', 'mbar',
'l/h', 'l/h',
'ct/kWh' 'ct/kWh',
'Hz'
]; ];
export enum AnalogType { export enum AnalogType {
@@ -226,20 +234,32 @@ export enum AnalogType {
DIGITAL_OUT = 6, DIGITAL_OUT = 6,
PWM_0 = 7, PWM_0 = 7,
PWM_1 = 8, PWM_1 = 8,
PWM_2 = 9 PWM_2 = 9,
NTC = 10,
RGB = 11,
PULSE = 12,
FREQ_0 = 13,
FREQ_1 = 14,
FREQ_2 = 15
} }
export const AnalogTypeNames = [ export const AnalogTypeNames = [
'(disabled)', '(disabled)',
'Digital In', 'Digital In',
'Counter', 'Counter',
'ADC', 'ADC In',
'Timer', 'Timer',
'Rate', 'Rate',
'Digital Out', 'Digital Out',
'PWM 0', 'PWM 0',
'PWM 1', 'PWM 1',
'PWM 2' 'PWM 2',
'NTC Temp.',
'RGB Led',
'Pulse',
'Freq 0',
'Freq 1',
'Freq 2'
]; ];
type BoardProfiles = Record<string, string>; type BoardProfiles = Record<string, string>;
@@ -249,6 +269,7 @@ export const BOARD_PROFILES: BoardProfiles = {
S32S3: 'BBQKees Gateway S3', S32S3: 'BBQKees Gateway S3',
E32: 'BBQKees Gateway E32', E32: 'BBQKees Gateway E32',
E32V2: 'BBQKees Gateway E32 V2', E32V2: 'BBQKees Gateway E32 V2',
E32V2_2: 'BBQKees Gateway E32 V2.2',
NODEMCU: 'NodeMCU 32S', NODEMCU: 'NodeMCU 32S',
'MH-ET': 'MH-ET Live D1 Mini', 'MH-ET': 'MH-ET Live D1 Mini',
LOLIN: 'Lolin D32', LOLIN: 'Lolin D32',
@@ -262,6 +283,7 @@ export const BOARD_PROFILES: BoardProfiles = {
export interface BoardProfile { export interface BoardProfile {
board_profile: string; board_profile: string;
led_gpio: number; led_gpio: number;
led_type: number;
dallas_gpio: number; dallas_gpio: number;
rx_gpio: number; rx_gpio: number;
tx_gpio: number; tx_gpio: number;
@@ -368,11 +390,12 @@ export interface EntityItem {
device_id: number | string; device_id: number | string;
type_id: number | string; type_id: number | string;
offset: number; offset: number;
factor: number; factor: number | string;
uom: number; uom: number;
value_type: number; value_type: number;
value?: unknown; value?: unknown;
writeable: boolean; writeable: boolean;
hide: boolean;
deleted?: boolean; deleted?: boolean;
o_id?: number; o_id?: number;
o_ram?: number; o_ram?: number;
@@ -380,12 +403,13 @@ export interface EntityItem {
o_device_id?: number | string; o_device_id?: number | string;
o_type_id?: number | string; o_type_id?: number | string;
o_offset?: number; o_offset?: number;
o_factor?: number; o_factor?: number | string;
o_uom?: number; o_uom?: number;
o_value_type?: number; o_value_type?: number;
o_deleted?: boolean; o_deleted?: boolean;
o_writeable?: boolean; o_writeable?: boolean;
o_value?: unknown; o_value?: unknown;
o_hide?: boolean;
} }
export interface Entities { export interface Entities {

View File

@@ -382,10 +382,7 @@ export const entityItemValidation = (entity: EntityItem[], entityItem: EntityIte
{ required: true, message: 'Offset is required' }, { required: true, message: 'Offset is required' },
{ type: 'number', min: 0, max: 255, message: 'Must be between 0 and 255' } { type: 'number', min: 0, max: 255, message: 'Must be between 0 and 255' }
], ],
factor: [ factor: [{ required: true, message: 'is required' }]
{ required: true, message: 'is required' },
{ type: 'number', message: 'Must be a number' }
]
}); });
export const uniqueTemperatureNameValidator = ( export const uniqueTemperatureNameValidator = (

View File

@@ -9,17 +9,17 @@ import {
Button, Button,
Checkbox, Checkbox,
Divider, Divider,
Grid,
InputAdornment, InputAdornment,
MenuItem, MenuItem,
TextField, TextField,
Typography Typography
} from '@mui/material'; } from '@mui/material';
import Grid from '@mui/material/Grid2';
import { readSystemStatus } from 'api/system'; import { readSystemStatus } from 'api/system';
import { useRequest } from 'alova/client'; import { useRequest } from 'alova/client';
import RestartMonitor from 'app/status/RestartMonitor'; import SystemMonitor from 'app/status/SystemMonitor';
import type { ValidateFieldsError } from 'async-validator'; import type { ValidateFieldsError } from 'async-validator';
import { import {
BlockFormControlLabel, BlockFormControlLabel,
@@ -126,9 +126,6 @@ const ApplicationSettings = () => {
const SecondsInputProps = { const SecondsInputProps = {
endAdornment: <InputAdornment position="end">{LL.SECONDS()}</InputAdornment> endAdornment: <InputAdornment position="end">{LL.SECONDS()}</InputAdornment>
}; };
const MilliSecondsInputProps = {
endAdornment: <InputAdornment position="end">ms</InputAdornment>
};
const MinutesInputProps = { const MinutesInputProps = {
endAdornment: <InputAdornment position="end">{LL.MINUTES()}</InputAdornment> endAdornment: <InputAdornment position="end">{LL.MINUTES()}</InputAdornment>
}; };
@@ -207,7 +204,16 @@ const ApplicationSettings = () => {
disabled={!hardwareData.psram} disabled={!hardwareData.psram}
/> />
} }
label={LL.ENABLE_MODBUS()} label={
<Typography color={!hardwareData.psram ? 'grey' : 'default'}>
{LL.ENABLE_MODBUS()}
{!hardwareData.psram && (
<Typography variant="caption">
&nbsp; &#40;{LL.IS_REQUIRED('PSRAM')}&#41;
</Typography>
)}
</Typography>
}
/> />
{data.modbus_enabled && ( {data.modbus_enabled && (
<Grid container spacing={2} rowSpacing={0}> <Grid container spacing={2} rowSpacing={0}>
@@ -241,7 +247,7 @@ const ApplicationSettings = () => {
name="modbus_timeout" name="modbus_timeout"
label="Timeout" label="Timeout"
slotProps={{ slotProps={{
input: MilliSecondsInputProps input: SecondsInputProps
}} }}
variant="outlined" variant="outlined"
value={numberValue(data.modbus_timeout)} value={numberValue(data.modbus_timeout)}
@@ -544,6 +550,23 @@ const ApplicationSettings = () => {
margin="normal" margin="normal"
/> />
</Grid> </Grid>
{data.led_gpio !== 0 && (
<Grid>
<TextField
name="led_type"
label={'LED ' + LL.TYPE(0)}
value={data.led_type}
fullWidth
variant="outlined"
onChange={updateFormValue}
margin="normal"
select
>
<MenuItem value={0}>LED</MenuItem>
<MenuItem value={1}>RGB-LED</MenuItem>
</TextField>
</Grid>
)}
<Grid> <Grid>
<TextField <TextField
name="phy_type" name="phy_type"
@@ -853,7 +876,7 @@ const ApplicationSettings = () => {
return ( return (
<SectionContent> <SectionContent>
{blocker ? <BlockNavigation blocker={blocker} /> : null} {blocker ? <BlockNavigation blocker={blocker} /> : null}
{restarting ? <RestartMonitor /> : content()} {restarting ? <SystemMonitor /> : content()}
</SectionContent> </SectionContent>
); );
}; };

View File

@@ -2,15 +2,14 @@ import { useState } from 'react';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import DownloadIcon from '@mui/icons-material/GetApp'; import DownloadIcon from '@mui/icons-material/GetApp';
import { Box, Button, Typography } from '@mui/material'; import { Box, Button, Grid, Typography } from '@mui/material';
import Grid from '@mui/material/Grid2';
import * as SystemApi from 'api/system'; import * as SystemApi from 'api/system';
import { API, callAction } from 'api/app'; import { API, callAction } from 'api/app';
import { useRequest } from 'alova/client'; import { useRequest } from 'alova/client';
import type { APIcall } from 'app/main/types'; import type { APIcall } from 'app/main/types';
import RestartMonitor from 'app/status/RestartMonitor'; import SystemMonitor from 'app/status/SystemMonitor';
import { import {
FormLoader, FormLoader,
SectionContent, SectionContent,
@@ -36,7 +35,7 @@ const DownloadUpload = () => {
toast.info(LL.DOWNLOAD_SUCCESSFUL()); toast.info(LL.DOWNLOAD_SUCCESSFUL());
}) })
.onError((error) => { .onError((error) => {
toast.error(error.message); toast.error(String(error.error?.message || 'An error occurred'));
}); });
const { send: sendAPI } = useRequest((data: APIcall) => API(data), { const { send: sendAPI } = useRequest((data: APIcall) => API(data), {
@@ -109,6 +108,15 @@ const DownloadUpload = () => {
{LL.SCHEDULE(0)} {LL.SCHEDULE(0)}
</Button> </Button>
</Grid> </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"> <Typography sx={{ pt: 2, pb: 2 }} variant="h6" color="primary">
{LL.UPLOAD()} {LL.UPLOAD()}
@@ -118,13 +126,13 @@ const DownloadUpload = () => {
<Typography variant="body1">{LL.UPLOAD_TEXT()}.</Typography> <Typography variant="body1">{LL.UPLOAD_TEXT()}.</Typography>
</Box> </Box>
<SingleUpload doRestart={doRestart} /> <SingleUpload text={LL.UPLOAD_DRAG()} doRestart={doRestart} />
</> </>
); );
}; };
return ( return (
<SectionContent>{restarting ? <RestartMonitor /> : content()}</SectionContent> <SectionContent>{restarting ? <SystemMonitor /> : content()}</SectionContent>
); );
}; };

View File

@@ -5,12 +5,12 @@ import WarningIcon from '@mui/icons-material/Warning';
import { import {
Button, Button,
Checkbox, Checkbox,
Grid,
InputAdornment, InputAdornment,
MenuItem, MenuItem,
TextField, TextField,
Typography Typography
} from '@mui/material'; } from '@mui/material';
import Grid from '@mui/material/Grid2';
import * as MqttApi from 'api/mqtt'; import * as MqttApi from 'api/mqtt';
@@ -254,102 +254,100 @@ const MqttSettings = () => {
} }
label={LL.MQTT_RESPONSE()} label={LL.MQTT_RESPONSE()}
/> />
{!data.ha_enabled && ( <Grid container spacing={2} rowSpacing={0}>
<Grid container spacing={2} rowSpacing={0}> <Grid>
<BlockFormControlLabel
control={
<Checkbox
name="publish_single"
checked={data.publish_single}
onChange={updateFormValue}
disabled={data.ha_enabled}
/>
}
label={LL.MQTT_PUBLISH_TEXT_1()}
/>
</Grid>
{data.publish_single && (
<Grid> <Grid>
<BlockFormControlLabel <BlockFormControlLabel
control={ control={
<Checkbox <Checkbox
name="publish_single" name="publish_single2cmd"
checked={data.publish_single} checked={data.publish_single2cmd}
onChange={updateFormValue} onChange={updateFormValue}
/> />
} }
label={LL.MQTT_PUBLISH_TEXT_1()} label={LL.MQTT_PUBLISH_TEXT_2()}
/> />
</Grid> </Grid>
{data.publish_single && ( )}
</Grid>
<Grid container spacing={2} rowSpacing={0}>
<Grid>
<BlockFormControlLabel
control={
<Checkbox
name="ha_enabled"
checked={data.ha_enabled}
onChange={updateFormValue}
disabled={data.publish_single}
/>
}
label={LL.MQTT_PUBLISH_TEXT_3()}
/>
</Grid>
{data.ha_enabled && (
<Grid container spacing={2} rowSpacing={0}>
<Grid> <Grid>
<BlockFormControlLabel <TextField
control={ name="discovery_type"
<Checkbox label={LL.MQTT_PUBLISH_TEXT_5()}
name="publish_single2cmd" value={data.discovery_type}
checked={data.publish_single2cmd} variant="outlined"
onChange={updateFormValue} onChange={updateFormValue}
/> margin="normal"
} select
label={LL.MQTT_PUBLISH_TEXT_2()} >
<MenuItem value={0}>Home Assistant</MenuItem>
<MenuItem value={1}>Domoticz</MenuItem>
<MenuItem value={2}>Domoticz (latest)</MenuItem>
</TextField>
</Grid>
<Grid>
<TextField
name="discovery_prefix"
label={LL.MQTT_PUBLISH_TEXT_4()}
variant="outlined"
value={data.discovery_prefix}
onChange={updateFormValue}
margin="normal"
/> />
</Grid> </Grid>
)} <Grid>
</Grid> <TextField
)} name="entity_format"
{!data.publish_single && ( label={LL.MQTT_ENTITY_FORMAT()}
<Grid container spacing={2} rowSpacing={0}> value={data.entity_format}
<Grid> variant="outlined"
<BlockFormControlLabel onChange={updateFormValue}
control={ margin="normal"
<Checkbox select
name="ha_enabled" >
checked={data.ha_enabled} <MenuItem value={0}>{LL.MQTT_ENTITY_FORMAT_0()}</MenuItem>
onChange={updateFormValue} <MenuItem value={3}>
/> {LL.MQTT_ENTITY_FORMAT_1()}&nbsp;(v3.6)
} </MenuItem>
label={LL.MQTT_PUBLISH_TEXT_3()} <MenuItem value={4}>
/> {LL.MQTT_ENTITY_FORMAT_2()}&nbsp;(v3.6)
</Grid> </MenuItem>
{data.ha_enabled && ( <MenuItem value={1}>{LL.MQTT_ENTITY_FORMAT_1()}</MenuItem>
<Grid container spacing={2} rowSpacing={0}> <MenuItem value={2}>{LL.MQTT_ENTITY_FORMAT_2()}</MenuItem>
<Grid> </TextField>
<TextField
name="discovery_type"
label={LL.MQTT_PUBLISH_TEXT_5()}
value={data.discovery_type}
variant="outlined"
onChange={updateFormValue}
margin="normal"
select
>
<MenuItem value={0}>Home Assistant</MenuItem>
<MenuItem value={1}>Domoticz</MenuItem>
<MenuItem value={2}>Domoticz (latest)</MenuItem>
</TextField>
</Grid>
<Grid>
<TextField
name="discovery_prefix"
label={LL.MQTT_PUBLISH_TEXT_4()}
variant="outlined"
value={data.discovery_prefix}
onChange={updateFormValue}
margin="normal"
/>
</Grid>
<Grid>
<TextField
name="entity_format"
label={LL.MQTT_ENTITY_FORMAT()}
value={data.entity_format}
variant="outlined"
onChange={updateFormValue}
margin="normal"
select
>
<MenuItem value={0}>{LL.MQTT_ENTITY_FORMAT_0()}</MenuItem>
<MenuItem value={3}>
{LL.MQTT_ENTITY_FORMAT_1()}&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>
</Grid> )}
)} </Grid>
<Typography sx={{ pt: 2 }} variant="h6" color="primary"> <Typography sx={{ pt: 2 }} variant="h6" color="primary">
{LL.MQTT_PUBLISH_INTERVALS()}&nbsp;(0=auto) {LL.MQTT_PUBLISH_INTERVALS()}&nbsp;(0=auto)
</Typography> </Typography>
@@ -442,7 +440,7 @@ const MqttSettings = () => {
<Grid> <Grid>
<TextField <TextField
name="publish_time_sensor" name="publish_time_sensor"
label={LL.TEMP_SENSORS()} label={LL.SENSORS()}
variant="outlined" variant="outlined"
value={numberValue(data.publish_time_sensor)} value={numberValue(data.publish_time_sensor)}
type="number" type="number"

View File

@@ -1,12 +1,27 @@
import { useState } from 'react'; import { useState } from 'react';
import { toast } from 'react-toastify';
import AccessTimeIcon from '@mui/icons-material/AccessTime';
import CancelIcon from '@mui/icons-material/Cancel'; import CancelIcon from '@mui/icons-material/Cancel';
import WarningIcon from '@mui/icons-material/Warning'; import WarningIcon from '@mui/icons-material/Warning';
import { Button, Checkbox, MenuItem } from '@mui/material'; import {
Box,
Button,
Checkbox,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
MenuItem,
TextField,
Typography
} from '@mui/material';
import * as NTPApi from 'api/ntp'; import * as NTPApi from 'api/ntp';
import { readNTPSettings } from 'api/ntp'; import { readNTPSettings } from 'api/ntp';
import { dialogStyle } from 'CustomTheme';
import { useRequest } from 'alova/client';
import { updateState } from 'alova/client'; import { updateState } from 'alova/client';
import type { ValidateFieldsError } from 'async-validator'; import type { ValidateFieldsError } from 'async-validator';
import { import {
@@ -19,8 +34,8 @@ import {
useLayoutTitle useLayoutTitle
} from 'components'; } from 'components';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';
import type { NTPSettingsType } from 'types'; import type { NTPSettingsType, Time } from 'types';
import { updateValueDirty, useRest } from 'utils'; import { formatLocalDateTime, updateValueDirty, useRest } from 'utils';
import { validate } from 'validators'; import { validate } from 'validators';
import { NTP_SETTINGS_VALIDATOR } from 'validators/ntp'; import { NTP_SETTINGS_VALIDATOR } from 'validators/ntp';
@@ -46,6 +61,17 @@ const NTPSettings = () => {
const { LL } = useI18nContext(); const { LL } = useI18nContext();
useLayoutTitle('NTP'); useLayoutTitle('NTP');
const [localTime, setLocalTime] = useState<string>('');
const [settingTime, setSettingTime] = useState<boolean>(false);
const [processing, setProcessing] = useState<boolean>(false);
const { send: updateTime } = useRequest(
(local_time: Time) => NTPApi.updateTime(local_time),
{
immediate: false
}
);
const updateFormValue = updateValueDirty( const updateFormValue = updateValueDirty(
origData, origData,
dirtyFlags, dirtyFlags,
@@ -55,6 +81,78 @@ const NTPSettings = () => {
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>(); const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
const updateLocalTime = (event: React.ChangeEvent<HTMLInputElement>) =>
setLocalTime(event.target.value);
const openSetTime = () => {
setLocalTime(formatLocalDateTime(new Date()));
setSettingTime(true);
};
const configureTime = async () => {
setProcessing(true);
await updateTime({ local_time: formatLocalDateTime(new Date(localTime)) })
.then(async () => {
toast.success(LL.TIME_SET());
setSettingTime(false);
await loadData();
})
.catch(() => {
toast.error(LL.PROBLEM_UPDATING());
})
.finally(() => {
setProcessing(false);
});
};
const renderSetTimeDialog = () => (
<Dialog
sx={dialogStyle}
open={settingTime}
onClose={() => setSettingTime(false)}
>
<DialogTitle>{LL.SET_TIME(1)}</DialogTitle>
<DialogContent dividers>
<Box color="warning.main" p={0} pl={0} pr={0} mt={0} mb={2}>
<Typography variant="body2">{LL.SET_TIME_TEXT()}</Typography>
</Box>
<TextField
label={LL.LOCAL_TIME(0)}
type="datetime-local"
value={localTime}
onChange={updateLocalTime}
disabled={processing}
fullWidth
slotProps={{
inputLabel: {
shrink: true
}
}}
/>
</DialogContent>
<DialogActions>
<Button
startIcon={<CancelIcon />}
variant="outlined"
onClick={() => setSettingTime(false)}
color="secondary"
>
{LL.CANCEL()}
</Button>
<Button
startIcon={<AccessTimeIcon />}
variant="outlined"
onClick={configureTime}
disabled={processing}
color="primary"
>
{LL.UPDATE()}
</Button>
</DialogActions>
</Dialog>
);
const content = () => { const content = () => {
if (!data) { if (!data) {
return <FormLoader onRetry={loadData} errorMessage={errorMessage} />; return <FormLoader onRetry={loadData} errorMessage={errorMessage} />;
@@ -115,6 +213,25 @@ const NTPSettings = () => {
<MenuItem disabled>{LL.TIME_ZONE()}...</MenuItem> <MenuItem disabled>{LL.TIME_ZONE()}...</MenuItem>
{timeZoneSelectItems()} {timeZoneSelectItems()}
</ValidatedTextField> </ValidatedTextField>
<Box display="flex" flexWrap="wrap">
{!data.enabled && !dirtyFlags.length && (
<Box flexWrap="nowrap" whiteSpace="nowrap">
<ButtonRow>
<Button
onClick={openSetTime}
variant="outlined"
color="primary"
startIcon={<AccessTimeIcon />}
>
{LL.SET_TIME(0)}
</Button>
</ButtonRow>
</Box>
)}
</Box>
{renderSetTimeDialog()}
{dirtyFlags && dirtyFlags.length !== 0 && ( {dirtyFlags && dirtyFlags.length !== 0 && (
<ButtonRow> <ButtonRow>
<Button <Button

View File

@@ -1,7 +1,6 @@
import { useState } from 'react'; import { useState } from 'react';
import AccessTimeIcon from '@mui/icons-material/AccessTime'; import AccessTimeIcon from '@mui/icons-material/AccessTime';
import BuildIcon from '@mui/icons-material/Build';
import CancelIcon from '@mui/icons-material/Cancel'; import CancelIcon from '@mui/icons-material/Cancel';
import DeviceHubIcon from '@mui/icons-material/DeviceHub'; import DeviceHubIcon from '@mui/icons-material/DeviceHub';
import ImportExportIcon from '@mui/icons-material/ImportExport'; import ImportExportIcon from '@mui/icons-material/ImportExport';
@@ -21,7 +20,7 @@ import {
List List
} from '@mui/material'; } from '@mui/material';
import { API, callAction } from 'api/app'; import { API } from 'api/app';
import { dialogStyle } from 'CustomTheme'; import { dialogStyle } from 'CustomTheme';
import { useRequest } from 'alova/client'; import { useRequest } from 'alova/client';
@@ -40,11 +39,6 @@ const Settings = () => {
immediate: false immediate: false
}); });
// call checkUpgrade with no param to fetch EMS-ESP version
const { data } = useRequest(() => callAction({ action: 'checkUpgrade' }), {
initialData: { emsesp_version: '...' }
});
const doFormat = async () => { const doFormat = async () => {
await sendAPI({ device: 'system', cmd: 'format', id: 0 }).then(() => { await sendAPI({ device: 'system', cmd: 'format', id: 0 }).then(() => {
setConfirmFactoryReset(false); setConfirmFactoryReset(false);
@@ -83,14 +77,6 @@ const Settings = () => {
const content = () => ( const content = () => (
<> <>
<List sx={{ borderRadius: 3, border: '2px solid grey' }}> <List sx={{ borderRadius: 3, border: '2px solid grey' }}>
<ListMenuItem
icon={BuildIcon}
bgcolor="#72caf9"
label="EMS-ESP Firmware"
text={'v' + data.emsesp_version}
to="version"
/>
<ListMenuItem <ListMenuItem
icon={TuneIcon} icon={TuneIcon}
bgcolor="#134ba2" bgcolor="#134ba2"
@@ -151,7 +137,7 @@ const Settings = () => {
bgcolor="#5d89f7" bgcolor="#5d89f7"
label={LL.DOWNLOAD_UPLOAD()} label={LL.DOWNLOAD_UPLOAD()}
text={LL.DOWNLOAD_UPLOAD_1()} text={LL.DOWNLOAD_UPLOAD_1()}
to="upload" to="downloadUpload"
/> />
</List> </List>

View File

@@ -1,344 +0,0 @@
import { useEffect, useState } from 'react';
import { toast } from 'react-toastify';
import CancelIcon from '@mui/icons-material/Cancel';
import CheckIcon from '@mui/icons-material/Done';
import DownloadIcon from '@mui/icons-material/GetApp';
import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';
import WarningIcon from '@mui/icons-material/Warning';
import {
Box,
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
Link,
Typography
} from '@mui/material';
import Grid from '@mui/material/Grid2';
import * as SystemApi from 'api/system';
import { callAction } from 'api/app';
import { getDevVersion, getStableVersion } from 'api/system';
import { dialogStyle } from 'CustomTheme';
import { useRequest } from 'alova/client';
import RestartMonitor from 'app/status/RestartMonitor';
import { FormLoader, SectionContent, useLayoutTitle } from 'components';
import { useI18nContext } from 'i18n/i18n-react';
const Version = () => {
const { LL } = useI18nContext();
const [restarting, setRestarting] = useState<boolean>(false);
const [openInstallDialog, setOpenInstallDialog] = useState<boolean>(false);
const [usingDevVersion, setUsingDevVersion] = useState<boolean>(false);
const [upgradeAvailable, setUpgradeAvailable] = useState<boolean>(false);
const [internetLive, setInternetLive] = useState<boolean>(false);
const [downloadOnly, setDownloadOnly] = useState<boolean>(false);
const STABLE_URL = 'https://github.com/emsesp/EMS-ESP32/releases/download/';
const STABLE_RELNOTES_URL =
'https://github.com/emsesp/EMS-ESP32/blob/main/CHANGELOG.md';
const DEV_URL = 'https://github.com/emsesp/EMS-ESP32/releases/download/latest/';
const DEV_RELNOTES_URL =
'https://github.com/emsesp/EMS-ESP32/blob/dev/CHANGELOG_LATEST.md';
const { send: sendCheckUpgrade } = useRequest(
(versions: string) => callAction({ action: 'checkUpgrade', param: versions }),
{
immediate: false
}
).onSuccess((event) => {
const data = event.data as { emsesp_version: string; upgradeable: boolean };
setUpgradeAvailable(data.upgradeable);
});
const {
data: data,
send: loadData,
error
} = useRequest(SystemApi.readSystemStatus).onSuccess((event) => {
// older version of EMS-ESP didn't have the psram set, so we can't do an OTA upgrade
setDownloadOnly(event.data.psram === undefined);
setUsingDevVersion(event.data.emsesp_version.includes('dev'));
});
const { send: sendUploadURL } = useRequest(
(url: string) => callAction({ action: 'uploadURL', param: url }),
{
immediate: false
}
);
// called immediately to get the latest versions on page load
const { data: latestVersion } = useRequest(getStableVersion);
const { data: latestDevVersion } = useRequest(getDevVersion);
useEffect(() => {
if (latestVersion && latestDevVersion) {
sendCheckUpgrade(latestDevVersion + ',' + latestVersion)
.catch((error: Error) => {
toast.error('Failed to check for upgrades: ' + error.message);
})
.finally(() => {
setInternetLive(true);
});
}
}, [latestVersion, latestDevVersion]);
const getBinURL = () => {
if (!latestVersion || !latestDevVersion) {
return '';
}
const filename =
'EMS-ESP-' +
(usingDevVersion ? latestDevVersion : latestVersion).replaceAll('.', '_') +
'-' +
getPlatform() +
'.bin';
return usingDevVersion
? DEV_URL + filename
: STABLE_URL + 'v' + latestVersion + '/' + filename;
};
const getPlatform = () => {
return (
[data.esp_platform, data.flash_chip_size >= 16384 ? '16MB' : '4MB'].join('-') +
(data.psram ? '+' : '')
);
};
const installFirmwareURL = async (url: string) => {
await sendUploadURL(url).catch((error: Error) => {
toast.error(error.message);
});
setRestarting(true);
};
useLayoutTitle('EMS-ESP Firmware');
const renderInstallDialog = () => (
<Dialog
sx={dialogStyle}
open={openInstallDialog}
onClose={() => closeInstallDialog()}
>
<DialogTitle>
{LL.INSTALL() +
' ' +
(usingDevVersion ? LL.DEVELOPMENT() : LL.STABLE()) +
' Firmware'}
</DialogTitle>
<DialogContent dividers>
<Typography mb={2}>
{LL.INSTALL_VERSION(usingDevVersion ? latestDevVersion : latestVersion)}
</Typography>
</DialogContent>
<DialogActions>
<Button
startIcon={<CancelIcon />}
variant="outlined"
onClick={() => closeInstallDialog()}
color="secondary"
>
{LL.CANCEL()}
</Button>
<Button
startIcon={<DownloadIcon />}
variant="outlined"
onClick={() => closeInstallDialog()}
color="primary"
>
<Link underline="none" target="_blank" href={getBinURL()} color="primary">
{LL.DOWNLOAD(1)}
</Link>
</Button>
<Button
startIcon={<WarningIcon color="warning" />}
variant="outlined"
onClick={() => installFirmwareURL(getBinURL())}
color="primary"
>
{LL.INSTALL()}
</Button>
</DialogActions>
</Dialog>
);
const showFirmwareDialog = (useDevVersion?: boolean) => {
setUsingDevVersion(useDevVersion || usingDevVersion);
setOpenInstallDialog(true);
};
const closeInstallDialog = () => {
setOpenInstallDialog(false);
setUsingDevVersion(data.emsesp_version.includes('dev'));
};
const switchToDev = () => {
setUsingDevVersion(true);
setUpgradeAvailable(true);
};
const showButtons = () => {
if (!upgradeAvailable) {
return;
}
if (downloadOnly) {
return (
<Button
startIcon={<DownloadIcon />}
variant="outlined"
onClick={() => setOpenInstallDialog(false)}
color="warning"
size="small"
sx={{ ml: 2 }}
>
<Link underline="none" target="_blank" href={getBinURL()} color="warning">
{LL.DOWNLOAD(1)}
</Link>
</Button>
);
}
return (
<Button
sx={{ ml: 2 }}
variant="outlined"
color="warning"
size="small"
onClick={() => showFirmwareDialog()}
>
{LL.UPGRADE()}&hellip;
</Button>
);
};
const content = () => {
if (!data) {
return <FormLoader onRetry={loadData} errorMessage={error?.message} />;
}
return (
<>
<Box p={2} border="1px solid grey" borderRadius={2}>
<Typography sx={{ pb: 2 }} variant="h6" color="primary">
Firmware Version
</Typography>
<Grid container spacing={4}>
<Grid mb={1}>
<Typography mb={1} color="secondary">
{LL.VERSION()}
</Typography>
<Typography mb={1} color="secondary">
Platform
</Typography>
<Typography mb={1} color="secondary">
Release Type
</Typography>
</Grid>
<Grid mb={1}>
<Typography mb={1}>
{data.emsesp_version}
{data.build_flags && (
<Typography variant="caption">
&nbsp; &#40;{data.build_flags}&#41;
</Typography>
)}
</Typography>
<Typography mb={1}>{getPlatform()}</Typography>
<Typography mb={1}>
{data.emsesp_version.includes('dev')
? LL.DEVELOPMENT()
: LL.STABLE()}
</Typography>
</Grid>
</Grid>
<Typography sx={{ pb: 2 }} variant="h6" color="primary">
{LL.AVAILABLE_VERSION()}
</Typography>
{internetLive ? (
<>
<Grid container spacing={4}>
<Grid mb={1}>
<Typography mb={1} color="secondary">
{LL.STABLE()}
</Typography>
<Typography mb={1} color="secondary">
{LL.DEVELOPMENT()}
</Typography>
</Grid>
<Grid mb={1}>
<Typography mb={1}>
{latestVersion}&nbsp;&nbsp;
<Link target="_blank" href={STABLE_RELNOTES_URL} color="primary">
(changelog)
</Link>
{!usingDevVersion && showButtons()}
</Typography>
<Typography mb={1}>
{latestDevVersion}&nbsp;&nbsp;
<Link target="_blank" href={DEV_RELNOTES_URL} color="primary">
(changelog)
</Link>
{usingDevVersion && showButtons()}
</Typography>
</Grid>
</Grid>
{upgradeAvailable ? (
<Typography color="warning">
<InfoOutlinedIcon
color="warning"
sx={{ verticalAlign: 'middle', mr: 2 }}
/>
{LL.UPGRADE_AVAILABLE()}
</Typography>
) : (
<Typography color="success">
<CheckIcon
color="success"
sx={{ verticalAlign: 'middle', mr: 2 }}
/>
{LL.LATEST_VERSION()}
</Typography>
)}
{!data.emsesp_version.includes('dev') && !usingDevVersion && (
<Typography variant="caption">
<Button
sx={{ mt: 2 }}
variant="outlined"
color="primary"
size="small"
onClick={() => switchToDev()}
>
{LL.SWITCH_DEV()}
</Button>
</Typography>
)}
</>
) : (
<Typography mb={1} color="warning">
<WarningIcon color="warning" sx={{ verticalAlign: 'middle', mr: 2 }} />
device cannot access internet
</Typography>
)}
{renderInstallDialog()}
</Box>
</>
);
};
return (
<SectionContent>{restarting ? <RestartMonitor /> : content()}</SectionContent>
);
};
export default Version;

View File

@@ -1,9 +1,16 @@
import { useCallback, useState } from 'react'; import { useCallback, useState } from 'react';
import { Navigate, Route, Routes, useNavigate } from 'react-router'; import {
Navigate,
Route,
Routes,
matchRoutes,
useLocation,
useNavigate
} from 'react-router';
import { Tab } from '@mui/material'; import { Tab } from '@mui/material';
import { RouterTabs, useLayoutTitle, useRouterTab } from 'components'; import { RouterTabs, useLayoutTitle } from 'components';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';
import type { WiFiNetwork } from 'types'; import type { WiFiNetwork } from 'types';
@@ -15,7 +22,20 @@ const Network = () => {
const { LL } = useI18nContext(); const { LL } = useI18nContext();
useLayoutTitle(LL.NETWORK(0)); useLayoutTitle(LL.NETWORK(0));
const { routerTab } = useRouterTab(); // 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 navigate = useNavigate();
@@ -24,7 +44,7 @@ const Network = () => {
const selectNetwork = useCallback( const selectNetwork = useCallback(
(network: WiFiNetwork) => { (network: WiFiNetwork) => {
setSelectedNetwork(network); setSelectedNetwork(network);
void navigate('/settings'); void navigate('/settings/network/settings');
}, },
[navigate] [navigate]
); );
@@ -42,13 +62,19 @@ const Network = () => {
}} }}
> >
<RouterTabs value={routerTab}> <RouterTabs value={routerTab}>
<Tab value="settings" label={LL.SETTINGS_OF(LL.NETWORK(1))} /> <Tab
<Tab value="scan" label={LL.NETWORK_SCAN()} /> value="/settings/network/settings"
label={LL.SETTINGS_OF(LL.NETWORK(1))}
/>
<Tab value="/settings/network/scan" label={LL.NETWORK_SCAN()} />
</RouterTabs> </RouterTabs>
<Routes> <Routes>
<Route path="scan" element={<WiFiNetworkScanner />} /> <Route path="scan" element={<WiFiNetworkScanner />} />
<Route path="settings" element={<NetworkSettings />} /> <Route path="settings" element={<NetworkSettings />} />
<Route path="*" element={<Navigate replace to="settings" />} /> <Route
path="*"
element={<Navigate replace to="/settings/network/settings" />}
/>
</Routes> </Routes>
</WiFiConnectionContext.Provider> </WiFiConnectionContext.Provider>
); );

View File

@@ -43,7 +43,7 @@ import { updateValueDirty, useRest } from 'utils';
import { validate } from 'validators'; import { validate } from 'validators';
import { createNetworkSettingsValidator } from 'validators/network'; import { createNetworkSettingsValidator } from 'validators/network';
import RestartMonitor from '../../status/RestartMonitor'; import SystemMonitor from '../../status/SystemMonitor';
import { WiFiConnectionContext } from './WiFiConnectionContext'; import { WiFiConnectionContext } from './WiFiConnectionContext';
import { isNetworkOpen, networkSecurityMode } from './WiFiNetworkSelector'; import { isNetworkOpen, networkSecurityMode } from './WiFiNetworkSelector';
@@ -400,7 +400,7 @@ const NetworkSettings = () => {
return ( return (
<SectionContent> <SectionContent>
{blocker ? <BlockNavigation blocker={blocker} /> : null} {blocker ? <BlockNavigation blocker={blocker} /> : null}
{restarting ? <RestartMonitor /> : content()} {restarting ? <SystemMonitor /> : content()}
</SectionContent> </SectionContent>
); );
}; };

View File

@@ -1,8 +1,8 @@
import { Navigate, Route, Routes } from 'react-router'; import { Navigate, Route, Routes, matchRoutes, useLocation } from 'react-router';
import { Tab } from '@mui/material'; import { Tab } from '@mui/material';
import { RouterTabs, useLayoutTitle, useRouterTab } from 'components'; import { RouterTabs, useLayoutTitle } from 'components';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';
import ManageUsers from './ManageUsers'; import ManageUsers from './ManageUsers';
@@ -12,18 +12,31 @@ const Security = () => {
const { LL } = useI18nContext(); const { LL } = useI18nContext();
useLayoutTitle(LL.SECURITY(0)); useLayoutTitle(LL.SECURITY(0));
const { routerTab } = useRouterTab(); const matchedRoutes = matchRoutes(
[
{ path: '/settings/security/settings', element: <ManageUsers />, dog: 'woof' },
{ path: '/settings/security/users', element: <SecuritySettings /> }
],
useLocation()
);
const routerTab = matchedRoutes?.[0].route.path || false;
return ( return (
<> <>
<RouterTabs value={routerTab}> <RouterTabs value={routerTab}>
<Tab value="settings" label={LL.SETTINGS_OF(LL.SECURITY(1))} /> <Tab
<Tab value="users" label={LL.MANAGE_USERS()} /> value="/settings/security/settings"
label={LL.SETTINGS_OF(LL.SECURITY(1))}
/>
<Tab value="/settings/security/users" label={LL.MANAGE_USERS()} />
</RouterTabs> </RouterTabs>
<Routes> <Routes>
<Route path="users" element={<ManageUsers />} /> <Route path="users" element={<ManageUsers />} />
<Route path="settings" element={<SecuritySettings />} /> <Route path="settings" element={<SecuritySettings />} />
<Route path="*" element={<Navigate replace to="settings" />} /> <Route
path="*"
element={<Navigate replace to="/settings/security/settings" />}
/>
</Routes> </Routes>
</> </>
); );

View File

@@ -14,11 +14,12 @@ import type { Theme } from '@mui/material';
import * as APApi from 'api/ap'; import * as APApi from 'api/ap';
import { useAutoRequest } from 'alova/client'; import { useRequest } from 'alova/client';
import { FormLoader, SectionContent, useLayoutTitle } from 'components'; import { FormLoader, SectionContent, useLayoutTitle } from 'components';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';
import type { APStatusType } from 'types'; import type { APStatusType } from 'types';
import { APNetworkStatus } from 'types'; import { APNetworkStatus } from 'types';
import { useInterval } from 'utils';
export const apStatusHighlight = ({ status }: APStatusType, theme: Theme) => { export const apStatusHighlight = ({ status }: APStatusType, theme: Theme) => {
switch (status) { switch (status) {
@@ -34,11 +35,11 @@ export const apStatusHighlight = ({ status }: APStatusType, theme: Theme) => {
}; };
const APStatus = () => { const APStatus = () => {
const { const { data, send: loadData, error } = useRequest(APApi.readAPStatus);
data,
send: loadData, useInterval(() => {
error void loadData();
} = useAutoRequest(APApi.readAPStatus, { pollingTime: 3000 }); });
const { LL } = useI18nContext(); const { LL } = useI18nContext();
useLayoutTitle(LL.ACCESS_POINT(0)); useLayoutTitle(LL.ACCESS_POINT(0));

View File

@@ -8,20 +8,21 @@ import {
Table Table
} from '@table-library/react-table-library/table'; } from '@table-library/react-table-library/table';
import { useTheme as tableTheme } from '@table-library/react-table-library/theme'; import { useTheme as tableTheme } from '@table-library/react-table-library/theme';
import { useAutoRequest } from 'alova/client'; import { useRequest } from 'alova/client';
import { FormLoader, SectionContent, useLayoutTitle } from 'components'; import { FormLoader, SectionContent, useLayoutTitle } from 'components';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';
import type { Translation } from 'i18n/i18n-types'; import type { Translation } from 'i18n/i18n-types';
import { useInterval } from 'utils';
import { readActivity } from '../../api/app'; import { readActivity } from '../../api/app';
import type { Stat } from '../main/types'; import type { Stat } from '../main/types';
const SystemActivity = () => { const SystemActivity = () => {
const { const { data, send: loadData, error } = useRequest(readActivity);
data,
send: loadData, useInterval(() => {
error void loadData();
} = useAutoRequest(readActivity, { pollingTime: 3000 }); });
const { LL } = useI18nContext(); const { LL } = useI18nContext();

View File

@@ -17,9 +17,10 @@ import {
import * as SystemApi from 'api/system'; import * as SystemApi from 'api/system';
import { useAutoRequest } from 'alova/client'; import { useRequest } from 'alova/client';
import { FormLoader, SectionContent, useLayoutTitle } from 'components'; import { FormLoader, SectionContent, useLayoutTitle } from 'components';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';
import { useInterval } from 'utils';
import BBQKeesIcon from './bbqkees.svg'; import BBQKeesIcon from './bbqkees.svg';
@@ -32,11 +33,11 @@ const HardwareStatus = () => {
useLayoutTitle(LL.HARDWARE()); useLayoutTitle(LL.HARDWARE());
const { const { data, send: loadData, error } = useRequest(SystemApi.readSystemStatus);
data,
send: loadData, useInterval(() => {
error void loadData();
} = useAutoRequest(SystemApi.readSystemStatus, { pollingTime: 3000 }); });
const content = () => { const content = () => {
if (!data) { if (!data) {
@@ -98,7 +99,13 @@ const HardwareStatus = () => {
' @ ' + ' @ ' +
data.cpu_freq_mhz + data.cpu_freq_mhz +
' Mhz' + ' Mhz' +
(data.temperature ? ', T: ' + data.temperature + ' °C' : '') // bit of a hack : if the CPU temp is higher than 90 (=32 Fahrenheit if using Celsius), show F, otherwise C
(data.temperature
? ', T: ' +
data.temperature +
' °' +
(data.temperature > 90 ? 'F' : 'C')
: '')
} }
/> />
</ListItem> </ListItem>

View File

@@ -15,11 +15,12 @@ import type { Theme } from '@mui/material';
import * as MqttApi from 'api/mqtt'; import * as MqttApi from 'api/mqtt';
import { useAutoRequest } from 'alova/client'; import { useRequest } from 'alova/client';
import { FormLoader, SectionContent, useLayoutTitle } from 'components'; import { FormLoader, SectionContent, useLayoutTitle } from 'components';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';
import type { MqttStatusType } from 'types'; import type { MqttStatusType } from 'types';
import { MqttDisconnectReason } from 'types'; import { MqttDisconnectReason } from 'types';
import { useInterval } from 'utils';
export const mqttStatusHighlight = ( export const mqttStatusHighlight = (
{ enabled, connected }: MqttStatusType, { enabled, connected }: MqttStatusType,
@@ -54,11 +55,11 @@ export const mqttQueueHighlight = (
}; };
const MqttStatus = () => { const MqttStatus = () => {
const { const { data, send: loadData, error } = useRequest(MqttApi.readMqttStatus);
data,
send: loadData, useInterval(() => {
error void loadData();
} = useAutoRequest(MqttApi.readMqttStatus, { pollingTime: 3000 }); });
const { LL } = useI18nContext(); const { LL } = useI18nContext();
useLayoutTitle('MQTT'); useLayoutTitle('MQTT');

View File

@@ -1,65 +1,40 @@
import { useState } from 'react';
import { toast } from 'react-toastify';
import AccessTimeIcon from '@mui/icons-material/AccessTime'; import AccessTimeIcon from '@mui/icons-material/AccessTime';
import CancelIcon from '@mui/icons-material/Cancel';
import DnsIcon from '@mui/icons-material/Dns'; import DnsIcon from '@mui/icons-material/Dns';
import SwapVerticalCircleIcon from '@mui/icons-material/SwapVerticalCircle'; import SwapVerticalCircleIcon from '@mui/icons-material/SwapVerticalCircle';
import UpdateIcon from '@mui/icons-material/Update'; import UpdateIcon from '@mui/icons-material/Update';
import { import {
Avatar, Avatar,
Box,
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
Divider, Divider,
List, List,
ListItem, ListItem,
ListItemAvatar, ListItemAvatar,
ListItemText, ListItemText,
TextField,
Typography,
useTheme useTheme
} from '@mui/material'; } from '@mui/material';
import type { Theme } from '@mui/material'; import type { Theme } from '@mui/material';
import * as NTPApi from 'api/ntp'; import * as NTPApi from 'api/ntp';
import { dialogStyle } from 'CustomTheme'; import { useRequest } from 'alova/client';
import { useAutoRequest, useRequest } from 'alova/client'; import { FormLoader, SectionContent, useLayoutTitle } from 'components';
import { ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';
import type { NTPStatusType, Time } from 'types'; import type { NTPStatusType } from 'types';
import { NTPSyncStatus } from 'types'; import { NTPSyncStatus } from 'types';
import { formatDateTime, formatLocalDateTime } from 'utils'; import { useInterval } from 'utils';
import { formatDateTime } from 'utils';
const NTPStatus = () => { const NTPStatus = () => {
const { const { data, send: loadData, error } = useRequest(NTPApi.readNTPStatus);
data,
send: loadData,
error
} = useAutoRequest(NTPApi.readNTPStatus, { pollingTime: 3000 });
const [localTime, setLocalTime] = useState<string>(''); useInterval(() => {
const [settingTime, setSettingTime] = useState<boolean>(false); void loadData();
const [processing, setProcessing] = useState<boolean>(false); });
const { LL } = useI18nContext(); const { LL } = useI18nContext();
useLayoutTitle('NTP'); useLayoutTitle('NTP');
const { send: updateTime } = useRequest(
(local_time: Time) => NTPApi.updateTime(local_time),
{
immediate: false
}
);
NTPApi.updateTime; NTPApi.updateTime;
const isNtpActive = ({ status }: NTPStatusType) =>
status === NTPSyncStatus.NTP_ACTIVE;
const isNtpEnabled = ({ status }: NTPStatusType) => const isNtpEnabled = ({ status }: NTPStatusType) =>
status !== NTPSyncStatus.NTP_DISABLED; status !== NTPSyncStatus.NTP_DISABLED;
@@ -76,14 +51,6 @@ const NTPStatus = () => {
} }
}; };
const updateLocalTime = (event: React.ChangeEvent<HTMLInputElement>) =>
setLocalTime(event.target.value);
const openSetTime = () => {
setLocalTime(formatLocalDateTime(new Date()));
setSettingTime(true);
};
const theme = useTheme(); const theme = useTheme();
const ntpStatus = ({ status }: NTPStatusType) => { const ntpStatus = ({ status }: NTPStatusType) => {
@@ -99,70 +66,6 @@ const NTPStatus = () => {
} }
}; };
const configureTime = async () => {
setProcessing(true);
await updateTime({ local_time: formatLocalDateTime(new Date(localTime)) })
.then(async () => {
toast.success(LL.TIME_SET());
setSettingTime(false);
await loadData();
})
.catch(() => {
toast.error(LL.PROBLEM_UPDATING());
})
.finally(() => {
setProcessing(false);
});
};
const renderSetTimeDialog = () => (
<Dialog
sx={dialogStyle}
open={settingTime}
onClose={() => setSettingTime(false)}
>
<DialogTitle>{LL.SET_TIME(1)}</DialogTitle>
<DialogContent dividers>
<Box color="warning.main" p={0} pl={0} pr={0} mt={0} mb={2}>
<Typography variant="body2">{LL.SET_TIME_TEXT()}</Typography>
</Box>
<TextField
label={LL.LOCAL_TIME(0)}
type="datetime-local"
value={localTime}
onChange={updateLocalTime}
disabled={processing}
fullWidth
slotProps={{
inputLabel: {
shrink: true
}
}}
/>
</DialogContent>
<DialogActions>
<Button
startIcon={<CancelIcon />}
variant="outlined"
onClick={() => setSettingTime(false)}
color="secondary"
>
{LL.CANCEL()}
</Button>
<Button
startIcon={<AccessTimeIcon />}
variant="outlined"
onClick={configureTime}
disabled={processing}
color="primary"
>
{LL.UPDATE()}
</Button>
</DialogActions>
</Dialog>
);
const content = () => { const content = () => {
if (!data) { if (!data) {
return <FormLoader onRetry={loadData} errorMessage={error?.message} />; return <FormLoader onRetry={loadData} errorMessage={error?.message} />;
@@ -218,23 +121,6 @@ const NTPStatus = () => {
</ListItem> </ListItem>
<Divider variant="inset" component="li" /> <Divider variant="inset" component="li" />
</List> </List>
<Box display="flex" flexWrap="wrap">
{data && !isNtpActive(data) && (
<Box flexWrap="nowrap" whiteSpace="nowrap">
<ButtonRow>
<Button
onClick={openSetTime}
variant="outlined"
color="primary"
startIcon={<AccessTimeIcon />}
>
{LL.SET_TIME(0)}
</Button>
</ButtonRow>
</Box>
)}
</Box>
{renderSetTimeDialog()}
</> </>
); );
}; };

View File

@@ -18,11 +18,12 @@ import type { Theme } from '@mui/material';
import * as NetworkApi from 'api/network'; import * as NetworkApi from 'api/network';
import { useAutoRequest } from 'alova/client'; import { useRequest } from 'alova/client';
import { FormLoader, SectionContent, useLayoutTitle } from 'components'; import { FormLoader, SectionContent, useLayoutTitle } from 'components';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';
import type { NetworkStatusType } from 'types'; import type { NetworkStatusType } from 'types';
import { NetworkConnectionStatus } from 'types'; import { NetworkConnectionStatus } from 'types';
import { useInterval } from 'utils';
const isConnected = ({ status }: NetworkStatusType) => const isConnected = ({ status }: NetworkStatusType) =>
status === NetworkConnectionStatus.WIFI_STATUS_CONNECTED || status === NetworkConnectionStatus.WIFI_STATUS_CONNECTED ||
@@ -81,11 +82,11 @@ const IPs = (status: NetworkStatusType) => {
}; };
const NetworkStatus = () => { const NetworkStatus = () => {
const { const { data, send: loadData, error } = useRequest(NetworkApi.readNetworkStatus);
data,
send: loadData, useInterval(() => {
error void loadData();
} = useAutoRequest(NetworkApi.readNetworkStatus, { pollingTime: 3000 }); });
const { LL } = useI18nContext(); const { LL } = useI18nContext();
useLayoutTitle(LL.NETWORK(1)); useLayoutTitle(LL.NETWORK(1));

View File

@@ -1,81 +0,0 @@
import { useState } from 'react';
import {
Box,
CircularProgress,
Dialog,
DialogContent,
Typography
} from '@mui/material';
import { readSystemStatus } from 'api/system';
import { dialogStyle } from 'CustomTheme';
import { useAutoRequest } from 'alova/client';
import MessageBox from 'components/MessageBox';
import { useI18nContext } from 'i18n/i18n-react';
const RestartMonitor = () => {
const [errorMessage, setErrorMessage] = useState<string>();
const { LL } = useI18nContext();
let count = 0;
const { data } = useAutoRequest(readSystemStatus, {
pollingTime: 1000,
force: true,
initialData: { status: 'Getting ready...' },
async middleware(_, next) {
if (count++ >= 1) {
// skip first request (1 second) to allow AsyncWS to send its response
await next();
}
}
})
.onSuccess((event) => {
if (event.data.status === 'ready' || event.data.status === undefined) {
document.location.href = '/';
}
})
.onError((error) => {
setErrorMessage(error.message);
});
return (
<Dialog fullWidth={true} sx={dialogStyle} open={true}>
<DialogContent dividers>
<Box m={0} py={0} display="flex" alignItems="center" flexDirection="column">
<Typography
color="secondary"
variant="h6"
fontWeight={400}
textAlign="center"
>
{data?.status === 'uploading'
? LL.WAIT_FIRMWARE()
: data?.status === 'restarting'
? LL.APPLICATION_RESTARTING()
: data?.status === 'ready'
? LL.RESTARTING_PRE()
: LL.RESTARTING_POST()}
&hellip;
</Typography>
<Typography mt={2} variant="h6" fontWeight={400} textAlign="center">
{LL.PLEASE_WAIT()}
</Typography>
{errorMessage ? (
<MessageBox my={2} level="error" message={errorMessage} />
) : (
<Box py={2}>
<CircularProgress size={32} />
</Box>
)}
</Box>
</DialogContent>
</Dialog>
);
};
export default RestartMonitor;

View File

@@ -2,6 +2,7 @@ import { useContext, useState } from 'react';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import AccessTimeIcon from '@mui/icons-material/AccessTime'; import AccessTimeIcon from '@mui/icons-material/AccessTime';
import BuildIcon from '@mui/icons-material/Build';
import CancelIcon from '@mui/icons-material/Cancel'; import CancelIcon from '@mui/icons-material/Cancel';
import DeviceHubIcon from '@mui/icons-material/DeviceHub'; import DeviceHubIcon from '@mui/icons-material/DeviceHub';
import DirectionsBusIcon from '@mui/icons-material/DirectionsBus'; import DirectionsBusIcon from '@mui/icons-material/DirectionsBus';
@@ -30,15 +31,17 @@ import { API } from 'api/app';
import { readSystemStatus } from 'api/system'; import { readSystemStatus } from 'api/system';
import { dialogStyle } from 'CustomTheme'; import { dialogStyle } from 'CustomTheme';
import { useAutoRequest, useRequest } from 'alova/client'; import { useRequest } from 'alova/client';
import { type APIcall, busConnectionStatus } from 'app/main/types'; import { type APIcall, busConnectionStatus } from 'app/main/types';
import { FormLoader, SectionContent, useLayoutTitle } from 'components'; import { FormLoader, SectionContent, useLayoutTitle } from 'components';
import ListMenuItem from 'components/layout/ListMenuItem'; import ListMenuItem from 'components/layout/ListMenuItem';
import { AuthenticatedContext } from 'contexts/authentication'; import { AuthenticatedContext } from 'contexts/authentication';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';
import { NTPSyncStatus, NetworkConnectionStatus } from 'types'; import { NTPSyncStatus, NetworkConnectionStatus } from 'types';
import { useInterval } from 'utils';
import { formatDateTime } from 'utils/time';
import RestartMonitor from './RestartMonitor'; import SystemMonitor from './SystemMonitor';
const SystemStatus = () => { const SystemStatus = () => {
const { LL } = useI18nContext(); const { LL } = useI18nContext();
@@ -58,9 +61,8 @@ const SystemStatus = () => {
data, data,
send: loadData, send: loadData,
error error
} = useAutoRequest(readSystemStatus, { } = useRequest(readSystemStatus, {
initialData: [], initialData: [],
pollingTime: 3000,
async middleware(_, next) { async middleware(_, next) {
if (!restarting) { if (!restarting) {
await next(); await next();
@@ -68,6 +70,10 @@ const SystemStatus = () => {
} }
}); });
useInterval(() => {
void loadData();
});
const theme = useTheme(); const theme = useTheme();
const formatDurationSec = (duration_sec: number) => { const formatDurationSec = (duration_sec: number) => {
@@ -134,7 +140,12 @@ const SystemStatus = () => {
case NTPSyncStatus.NTP_INACTIVE: case NTPSyncStatus.NTP_INACTIVE:
return LL.INACTIVE(0); return LL.INACTIVE(0);
case NTPSyncStatus.NTP_ACTIVE: case NTPSyncStatus.NTP_ACTIVE:
return LL.ACTIVE(); return (
LL.ACTIVE() +
(data.ntp_time !== undefined
? ' (' + formatDateTime(data.ntp_time) + ')'
: '')
);
default: default:
return LL.UNKNOWN(); return LL.UNKNOWN();
} }
@@ -243,6 +254,14 @@ const SystemStatus = () => {
return ( return (
<> <>
<List sx={{ borderRadius: 3, border: '2px solid grey' }}> <List sx={{ borderRadius: 3, border: '2px solid grey' }}>
<ListMenuItem
icon={BuildIcon}
bgcolor="#72caf9"
label="EMS-ESP Firmware"
text={'v' + data.emsesp_version}
to="version"
/>
<ListItem> <ListItem>
<ListItemAvatar> <ListItemAvatar>
<Avatar sx={{ bgcolor: '#c5572c', color: 'white' }}> <Avatar sx={{ bgcolor: '#c5572c', color: 'white' }}>
@@ -301,7 +320,7 @@ const SystemStatus = () => {
icon={DeviceHubIcon} icon={DeviceHubIcon}
bgcolor={activeHighlight(data.mqtt_status)} bgcolor={activeHighlight(data.mqtt_status)}
label="MQTT" label="MQTT"
text={data.mqtt_status ? LL.ACTIVE() : LL.INACTIVE(0)} text={data.mqtt_status ? LL.CONNECTED(0) : LL.INACTIVE(0)}
to="/status/mqtt" to="/status/mqtt"
/> />
@@ -339,7 +358,7 @@ const SystemStatus = () => {
}; };
return ( return (
<SectionContent>{restarting ? <RestartMonitor /> : content()}</SectionContent> <SectionContent>{restarting ? <SystemMonitor /> : content()}</SectionContent>
); );
}; };

View File

@@ -8,12 +8,12 @@ import {
Box, Box,
Button, Button,
Checkbox, Checkbox,
Grid,
IconButton, IconButton,
MenuItem, MenuItem,
TextField, TextField,
styled styled
} from '@mui/material'; } from '@mui/material';
import Grid from '@mui/material/Grid2';
import { API } from 'api/app'; import { API } from 'api/app';
import { fetchLogES, readLogSettings, updateLogSettings } from 'api/system'; import { fetchLogES, readLogSettings, updateLogSettings } from 'api/system';
@@ -101,6 +101,7 @@ const SystemLog = () => {
const [readOpen, setReadOpen] = useState(false); const [readOpen, setReadOpen] = useState(false);
const [logEntries, setLogEntries] = useState<LogEntry[]>([]); const [logEntries, setLogEntries] = useState<LogEntry[]>([]);
const [autoscroll, setAutoscroll] = useState(true); const [autoscroll, setAutoscroll] = useState(true);
const [lastId, setLastId] = useState<number>(-1);
const ALPHA_NUMERIC_DASH_REGEX = /^[a-fA-F0-9 ]+$/; const ALPHA_NUMERIC_DASH_REGEX = /^[a-fA-F0-9 ]+$/;
@@ -115,10 +116,13 @@ const SystemLog = () => {
immediate: true, immediate: true,
interceptByGlobalResponded: false interceptByGlobalResponded: false
}) })
.onMessage((message: { id: number; data: string }) => { .onMessage((message: { data: string }) => {
const rawData = message.data; const rawData = message.data;
const logentry = JSON.parse(rawData) as LogEntry; const logentry = JSON.parse(rawData) as LogEntry;
setLogEntries((log) => [...log, logentry]); if (lastId < logentry.i) {
setLogEntries((log) => [...log, logentry]);
setLastId(logentry.i);
}
}) })
.onError(() => { .onError(() => {
toast.error('No connection to Log service'); toast.error('No connection to Log service');
@@ -197,7 +201,7 @@ const SystemLog = () => {
name="level" name="level"
label={LL.LOG_LEVEL()} label={LL.LOG_LEVEL()}
value={data.level} value={data.level}
sx={{ width: '10ch' }} sx={{ width: '14ch' }}
variant="outlined" variant="outlined"
onChange={updateFormValue} onChange={updateFormValue}
margin="normal" margin="normal"

View File

@@ -0,0 +1,125 @@
import { useState } from 'react';
import CancelIcon from '@mui/icons-material/Cancel';
import { Box, Button, Dialog, DialogContent, Typography } from '@mui/material';
import { callAction } from 'api/app';
import { readSystemStatus } from 'api/system';
import { dialogStyle } from 'CustomTheme';
import { useRequest } from 'alova/client';
import MessageBox from 'components/MessageBox';
import { useI18nContext } from 'i18n/i18n-react';
import { SystemStatusCodes } from 'types';
import { useInterval } from 'utils';
import { LinearProgressWithLabel } from '../../components/upload/LinearProgressWithLabel';
const SystemMonitor = () => {
const [errorMessage, setErrorMessage] = useState<string>();
const { LL } = useI18nContext();
let count = 0;
const { send: setSystemStatus } = useRequest(
(status: string) => callAction({ action: 'systemStatus', param: status }),
{
immediate: false
}
);
const { data, send } = useRequest(readSystemStatus, {
force: true,
async middleware(_, next) {
if (count++ >= 1) {
// skip first request (1 second) to allow AsyncWS to send its response
await next();
}
}
})
.onSuccess((event) => {
if (
event.data.status === SystemStatusCodes.SYSTEM_STATUS_NORMAL ||
event.data.status === undefined
) {
document.location.href = '/';
} else if (
event.data.status === SystemStatusCodes.SYSTEM_STATUS_ERROR_UPLOAD
) {
setErrorMessage('Please check system logs for possible causes');
}
})
.onError((error) => {
setErrorMessage(String(error.error?.message || 'An error occurred'));
});
useInterval(() => {
void send();
}, 1000); // check every 1 second
const onCancel = async () => {
setErrorMessage(undefined);
await setSystemStatus(
SystemStatusCodes.SYSTEM_STATUS_NORMAL as unknown as string
);
document.location.href = '/';
};
return (
<Dialog fullWidth={true} sx={dialogStyle} open={true}>
<DialogContent dividers>
<Box m={0} py={0} display="flex" alignItems="center" flexDirection="column">
<Typography
color="secondary"
variant="h6"
fontWeight={400}
textAlign="center"
>
{data?.status >= SystemStatusCodes.SYSTEM_STATUS_UPLOADING
? LL.WAIT_FIRMWARE()
: data?.status === SystemStatusCodes.SYSTEM_STATUS_PENDING_RESTART
? LL.APPLICATION_RESTARTING()
: data?.status === SystemStatusCodes.SYSTEM_STATUS_NORMAL
? LL.RESTARTING_PRE()
: data?.status === SystemStatusCodes.SYSTEM_STATUS_ERROR_UPLOAD
? 'Upload Failed'
: LL.RESTARTING_POST()}
</Typography>
{errorMessage ? (
<MessageBox my={2} level="error" message={errorMessage}>
<Button
size="small"
sx={{ ml: 2 }}
startIcon={<CancelIcon />}
variant="contained"
color="error"
onClick={onCancel}
>
{LL.RESTART()}
</Button>
</MessageBox>
) : (
<>
<Typography mt={2} variant="h6" fontWeight={400} textAlign="center">
{LL.PLEASE_WAIT()}&hellip;
</Typography>
{data && data.status >= SystemStatusCodes.SYSTEM_STATUS_UPLOADING && (
<Box width="100%" pl={2} pr={2} py={2}>
<LinearProgressWithLabel
value={Math.round(
data?.status - SystemStatusCodes.SYSTEM_STATUS_UPLOADING
)}
/>
</Box>
)}
</>
)}
</Box>
</DialogContent>
</Dialog>
);
};
export default SystemMonitor;

View File

@@ -0,0 +1,485 @@
import { useContext, useEffect, useState } from 'react';
import { toast } from 'react-toastify';
import CancelIcon from '@mui/icons-material/Cancel';
import CloseIcon from '@mui/icons-material/Close';
import CheckIcon from '@mui/icons-material/Done';
import DownloadIcon from '@mui/icons-material/GetApp';
import WarningIcon from '@mui/icons-material/Warning';
import {
Box,
Button,
Checkbox,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
FormControlLabel,
Grid,
Link,
Typography
} from '@mui/material';
import * as SystemApi from 'api/system';
import { API, callAction } from 'api/app';
import { getDevVersion, getStableVersion } from 'api/system';
import { dialogStyle } from 'CustomTheme';
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 { AuthenticatedContext } from 'contexts/authentication';
import { useI18nContext } from 'i18n/i18n-react';
const Version = () => {
const { LL, locale } = useI18nContext();
const { me } = useContext(AuthenticatedContext);
const [restarting, setRestarting] = useState<boolean>(false);
const [openInstallDialog, setOpenInstallDialog] = useState<boolean>(false);
const [usingDevVersion, setUsingDevVersion] = useState<boolean>(false);
const [fetchDevVersion, setFetchDevVersion] = useState<boolean>(false);
const [devUpgradeAvailable, setDevUpgradeAvailable] = useState<boolean>(false);
const [stableUpgradeAvailable, setStableUpgradeAvailable] =
useState<boolean>(false);
const [internetLive, setInternetLive] = useState<boolean>(false);
const [downloadOnly, setDownloadOnly] = useState<boolean>(false);
const STABLE_URL = 'https://github.com/emsesp/EMS-ESP32/releases/download/';
const STABLE_RELNOTES_URL =
'https://github.com/emsesp/EMS-ESP32/blob/main/CHANGELOG.md';
const DEV_URL = 'https://github.com/emsesp/EMS-ESP32/releases/download/latest/';
const DEV_RELNOTES_URL =
'https://github.com/emsesp/EMS-ESP32/blob/dev/CHANGELOG_LATEST.md';
const { send: sendCheckUpgrade } = useRequest(
(versions: string) => callAction({ action: 'checkUpgrade', param: versions }),
{
immediate: false
}
).onSuccess((event) => {
const data = event.data as {
emsesp_version: string;
dev_upgradeable: boolean;
stable_upgradeable: boolean;
};
setDevUpgradeAvailable(data.dev_upgradeable);
setStableUpgradeAvailable(data.stable_upgradeable);
});
const {
data: data,
send: loadData,
error
} = useRequest(SystemApi.readSystemStatus).onSuccess((event) => {
// older version of EMS-ESP using ESP32 (not S3) and no PSRAM, can't use OTA because of SSL support in HttpClient
if (event.data.arduino_version.startsWith('Tasmota')) {
setDownloadOnly(true);
}
setUsingDevVersion(event.data.emsesp_version.includes('dev'));
});
const { send: sendUploadURL } = useRequest(
(url: string) => callAction({ action: 'uploadURL', param: url }),
{
immediate: false
}
);
// called immediately to get the latest versions on page load
const { data: latestVersion } = useRequest(getStableVersion);
const { data: latestDevVersion } = useRequest(getDevVersion);
useEffect(() => {
if (latestVersion && latestDevVersion) {
sendCheckUpgrade(latestDevVersion.name + ',' + latestVersion.name)
.catch((error: Error) => {
toast.error('Failed to check for upgrades: ' + error.message);
})
.finally(() => {
setInternetLive(true);
});
}
}, [latestVersion, latestDevVersion]);
const rtf = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });
const DIVISIONS = [
{ amount: 60, name: 'seconds' },
{ amount: 60, name: 'minutes' },
{ amount: 24, name: 'hours' },
{ amount: 7, name: 'days' },
{ amount: 4.34524, name: 'weeks' },
{ amount: 12, name: 'months' },
{ amount: Number.POSITIVE_INFINITY, name: 'years' }
];
function formatTimeAgo(date) {
let duration = (date.getTime() - new Date().getTime()) / 1000;
for (let i = 0; i < DIVISIONS.length; i++) {
const division = DIVISIONS[i];
if (Math.abs(duration) < division.amount) {
return rtf.format(
Math.round(duration),
division.name as Intl.RelativeTimeFormatUnit
);
}
duration /= division.amount;
}
}
const { send: sendAPI } = useRequest((data: APIcall) => API(data), {
immediate: false
});
const doRestart = async () => {
setRestarting(true);
await sendAPI({ device: 'system', cmd: 'restart', id: 0 }).catch(
(error: Error) => {
toast.error(error.message);
}
);
};
const getBinURL = (showingDev: boolean) => {
if (!internetLive) {
return '';
}
const filename =
'EMS-ESP-' +
(showingDev ? latestDevVersion.name : latestVersion.name).replaceAll(
'.',
'_'
) +
'-' +
getPlatform() +
'.bin';
return showingDev
? DEV_URL + filename
: STABLE_URL + 'v' + latestVersion.name + '/' + filename;
};
const getPlatform = () => {
return (
[data.esp_platform, data.flash_chip_size >= 16384 ? '16MB' : '4MB'].join('-') +
(data.psram ? '+' : '')
);
};
const installFirmwareURL = async (url: string) => {
await sendUploadURL(url).catch((error: Error) => {
toast.error(error.message);
});
setRestarting(true);
};
useLayoutTitle('EMS-ESP Firmware');
const renderInstallDialog = () => {
const binURL = getBinURL(fetchDevVersion);
return (
<Dialog
sx={dialogStyle}
open={openInstallDialog}
onClose={() => closeInstallDialog()}
>
<DialogTitle>
{LL.UPDATE() +
' ' +
(fetchDevVersion ? LL.DEVELOPMENT() : LL.STABLE()) +
' Firmware'}
</DialogTitle>
<DialogContent dividers>
<Typography mb={2}>
{LL.INSTALL_VERSION(
downloadOnly ? LL.DOWNLOAD(1) : LL.INSTALL(),
fetchDevVersion ? latestDevVersion?.name : latestVersion?.name
)}
</Typography>
</DialogContent>
<DialogActions>
<Button
startIcon={<CancelIcon />}
variant="outlined"
onClick={() => closeInstallDialog()}
color="secondary"
>
{LL.CANCEL()}
</Button>
<Button
startIcon={<DownloadIcon />}
variant="outlined"
onClick={() => closeInstallDialog()}
color="primary"
>
<Link underline="none" target="_blank" href={binURL} color="primary">
{LL.DOWNLOAD(0)}
</Link>
</Button>
{!downloadOnly && (
<Button
startIcon={<WarningIcon color="warning" />}
variant="outlined"
onClick={() => installFirmwareURL(binURL)}
color="primary"
>
{LL.INSTALL()}
</Button>
)}
</DialogActions>
</Dialog>
);
};
const showFirmwareDialog = (useDevVersion: boolean) => {
setFetchDevVersion(useDevVersion);
setOpenInstallDialog(true);
};
const closeInstallDialog = () => {
setOpenInstallDialog(false);
};
const showButtons = (showingDev: boolean) => {
const choice = showingDev
? !usingDevVersion
? LL.SWITCH_RELEASE_TYPE(LL.DEVELOPMENT())
: devUpgradeAvailable
? LL.UPDATE_AVAILABLE()
: undefined
: usingDevVersion
? LL.SWITCH_RELEASE_TYPE(LL.STABLE())
: stableUpgradeAvailable
? LL.UPDATE_AVAILABLE()
: undefined;
if (!choice) {
return (
<>
<CheckIcon
color="success"
sx={{ verticalAlign: 'middle', ml: 0.5, mr: 0.5 }}
/>
<span style={{ color: '#66bb6a', fontSize: '0.8em' }}>
{LL.LATEST_VERSION(usingDevVersion ? LL.DEVELOPMENT() : LL.STABLE())}
</span>
</>
);
}
if (!me.admin) {
return;
}
return (
<Button
sx={{ ml: 2 }}
variant="outlined"
color={choice === LL.UPDATE_AVAILABLE() ? 'success' : 'warning'}
size="small"
onClick={() => showFirmwareDialog(showingDev)}
>
{choice}
</Button>
);
};
const content = () => {
if (!data) {
return <FormLoader onRetry={loadData} errorMessage={error?.message} />;
}
const isDev = data.emsesp_version.includes('dev');
return (
<>
<Box p={2} border="1px solid grey" borderRadius={2}>
<Typography mb={2} variant="h6" color="primary">
{LL.THIS_VERSION()}
</Typography>
<Grid
container
direction="row"
rowSpacing={1}
sx={{
justifyContent: 'flex-start',
alignItems: 'baseline'
}}
>
<Grid size={{ xs: 4, md: 2 }}>
<Typography color="secondary">{LL.VERSION()}</Typography>
</Grid>
<Grid size={{ xs: 8, md: 10 }}>
<Typography>
{data.emsesp_version}
{data.build_flags && (
<Typography variant="caption">
&nbsp; &#40;{data.build_flags}&#41;
</Typography>
)}
</Typography>
</Grid>
<Grid size={{ xs: 4, md: 2 }}>
<Typography color="secondary">{LL.PLATFORM()}</Typography>
</Grid>
<Grid size={{ xs: 8, md: 10 }}>
<Typography>
{getPlatform()}
<Typography variant="caption">
&nbsp; &#40;
{data.psram ? (
<CheckIcon
color="success"
sx={{
fontSize: '1.5em',
verticalAlign: 'middle'
}}
/>
) : (
<CloseIcon
color="error"
sx={{
fontSize: '1.5em',
verticalAlign: 'middle'
}}
/>
)}
PSRAM&#41;
</Typography>
</Typography>
</Grid>
<Grid size={{ xs: 4, md: 2 }}>
<Typography color="secondary">{LL.RELEASE_TYPE()}</Typography>
</Grid>
<Grid size={{ xs: 8, md: 10 }}>
<FormControlLabel
disabled={!isDev}
control={
<Checkbox
sx={{
'&.Mui-checked': {
color: 'lightblue'
}
}}
/>
}
slotProps={{
typography: {
color: 'grey'
}
}}
checked={!isDev}
label={LL.STABLE()}
sx={{ '& .MuiSvgIcon-root': { fontSize: 16 } }}
/>
<FormControlLabel
disabled={isDev}
control={
<Checkbox
sx={{
'&.Mui-checked': {
color: 'lightblue'
}
}}
/>
}
slotProps={{
typography: {
color: 'grey'
}
}}
checked={isDev}
label={LL.DEVELOPMENT()}
sx={{ '& .MuiSvgIcon-root': { fontSize: 16 } }}
/>
</Grid>
</Grid>
{internetLive ? (
<>
<Typography mt={2} mb={2} variant="h6" color="primary">
{LL.AVAILABLE_VERSION()}
</Typography>
<Grid
container
direction="row"
rowSpacing={1}
sx={{
justifyContent: 'flex-start',
alignItems: 'baseline'
}}
>
<Grid size={{ xs: 4, md: 2 }}>
<Typography color="secondary">{LL.STABLE()}</Typography>
</Grid>
<Grid size={{ xs: 8, md: 10 }}>
<Typography>
<Link target="_blank" href={STABLE_RELNOTES_URL} color="primary">
{latestVersion.name}
</Link>
{latestVersion.published_at && (
<Typography component="span" variant="caption">
&nbsp;(
{formatTimeAgo(new Date(latestVersion.published_at))})
</Typography>
)}
{showButtons(false)}
</Typography>
</Grid>
<Grid size={{ xs: 4, md: 2 }}>
<Typography color="secondary">{LL.DEVELOPMENT()}</Typography>
</Grid>
<Grid size={{ xs: 8, md: 10 }}>
<Typography>
<Link target="_blank" href={DEV_RELNOTES_URL} color="primary">
{latestDevVersion.name}
</Link>
{latestDevVersion.published_at && (
<Typography component="span" variant="caption">
&nbsp;(
{formatTimeAgo(new Date(latestDevVersion.published_at))})
</Typography>
)}
{showButtons(true)}
</Typography>
</Grid>
</Grid>
</>
) : (
<Typography mt={2} color="warning">
<WarningIcon color="warning" sx={{ verticalAlign: 'middle', mr: 2 }} />
{LL.INTERNET_CONNECTION_REQUIRED()}
</Typography>
)}
{me.admin && (
<>
{renderInstallDialog()}
<Typography sx={{ pt: 2, pb: 2 }} variant="h6" color="primary">
{LL.UPLOAD()}
</Typography>
<SingleUpload text={LL.UPLOAD_DROP_TEXT()} doRestart={doRestart} />
</>
)}
</Box>
</>
);
};
return (
<SectionContent>{restarting ? <SystemMonitor /> : content()}</SectionContent>
);
};
export default Version;

View File

@@ -0,0 +1,17 @@
import { Tooltip, type TooltipProps, styled, tooltipClasses } from '@mui/material';
export const ButtonTooltip = styled(({ className, ...props }: TooltipProps) => (
<Tooltip {...props} placement="top" arrow classes={{ popper: className }} />
))(({ theme }) => ({
[`& .${tooltipClasses.arrow}`]: {
color: theme.palette.success.main
},
[`& .${tooltipClasses.tooltip}`]: {
backgroundColor: theme.palette.success.main,
color: 'rgba(0, 0, 0, 0.87)',
boxShadow: theme.shadows[1],
fontSize: 10
}
}));
export default ButtonTooltip;

View File

@@ -11,7 +11,7 @@ type MessageBoxLevel = 'warning' | 'success' | 'info' | 'error';
export interface MessageBoxProps extends BoxProps { export interface MessageBoxProps extends BoxProps {
level: MessageBoxLevel; level: MessageBoxLevel;
message: string; message?: string;
} }
const LEVEL_ICONS: { const LEVEL_ICONS: {
@@ -53,8 +53,8 @@ const MessageBox: FC<MessageBoxProps> = ({
{...rest} {...rest}
> >
<Icon /> <Icon />
<Typography sx={{ ml: 2, flexGrow: 1 }} variant="body1"> <Typography sx={{ ml: 2 }} variant="body1">
{message} {message ?? ''}
</Typography> </Typography>
{children} {children}
</Box> </Box>

View File

@@ -7,3 +7,4 @@ export { default as SectionContent } from './SectionContent';
export { default as ButtonRow } from './ButtonRow'; export { default as ButtonRow } from './ButtonRow';
export { default as MessageBox } from './MessageBox'; export { default as MessageBox } from './MessageBox';
export { default as BlockNavigation } from './routing/BlockNavigation'; export { default as BlockNavigation } from './routing/BlockNavigation';
export { default as ButtonTooltip } from './ButtonTooltip';

View File

@@ -73,11 +73,6 @@ const LayoutMenu = () => {
> >
<ListItemText <ListItemText
primary={LL.MODULES()} primary={LL.MODULES()}
primaryTypographyProps={{
fontWeight: '600',
mb: '2px',
color: 'lightblue'
}}
// secondary={ // secondary={
// LL.CUSTOMIZATIONS() + // LL.CUSTOMIZATIONS() +
// ', ' + // ', ' +
@@ -92,6 +87,13 @@ const LayoutMenu = () => {
// color: menuOpen ? 'rgba(0,0,0,0)' : 'rgba(255,255,255,0.5)' // color: menuOpen ? 'rgba(0,0,0,0)' : 'rgba(255,255,255,0.5)'
// }} // }}
sx={{ my: 0 }} sx={{ my: 0 }}
slotProps={{
primary: {
fontWeight: '600',
mb: '2px',
color: 'lightblue'
}
}}
/> />
<KeyboardArrowDown <KeyboardArrowDown
sx={{ sx={{
@@ -132,7 +134,6 @@ const LayoutMenu = () => {
)} )}
</Box> </Box>
</List> </List>
<List style={{ marginTop: `auto` }}> <List style={{ marginTop: `auto` }}>
<LayoutMenuItem <LayoutMenuItem
icon={AssessmentIcon} icon={AssessmentIcon}
@@ -158,7 +159,6 @@ const LayoutMenu = () => {
</ListItemButton> </ListItemButton>
</ListItem> </ListItem>
</List> </List>
<Popover <Popover
id={id} id={id}
open={open} open={open}

View File

@@ -1,20 +1,15 @@
import RefreshIcon from '@mui/icons-material/Refresh'; import RefreshIcon from '@mui/icons-material/Refresh';
import { Box, Button, CircularProgress, Typography } from '@mui/material'; import { Box, Button, CircularProgress } from '@mui/material';
import { MessageBox } from 'components'; import { MessageBox } from 'components';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';
interface FormLoaderProps { interface FormLoaderProps {
message?: string;
errorMessage?: string; errorMessage?: string;
onRetry?: () => void; onRetry?: () => void;
} }
const FormLoader = ({ const FormLoader = ({ errorMessage, onRetry }: FormLoaderProps) => {
errorMessage,
onRetry,
message = 'Loading…'
}: FormLoaderProps) => {
const { LL } = useI18nContext(); const { LL } = useI18nContext();
if (errorMessage) { if (errorMessage) {
@@ -22,6 +17,7 @@ const FormLoader = ({
<MessageBox my={2} level="error" message={errorMessage}> <MessageBox my={2} level="error" message={errorMessage}>
{onRetry && ( {onRetry && (
<Button <Button
sx={{ ml: 2 }}
startIcon={<RefreshIcon />} startIcon={<RefreshIcon />}
variant="contained" variant="contained"
color="error" color="error"
@@ -38,9 +34,6 @@ const FormLoader = ({
<Box py={2}> <Box py={2}>
<CircularProgress size={100} /> <CircularProgress size={100} />
</Box> </Box>
<Typography variant="h6" fontWeight={400} textAlign="center">
{message}
</Typography>
</Box> </Box>
); );
}; };

View File

@@ -1,15 +1,11 @@
import { Box, CircularProgress, Typography } from '@mui/material'; import { Box, CircularProgress } from '@mui/material';
import type { Theme } from '@mui/material'; import type { Theme } from '@mui/material';
import { useI18nContext } from 'i18n/i18n-react';
interface LoadingSpinnerProps { interface LoadingSpinnerProps {
height?: number | string; height?: number | string;
} }
const LoadingSpinner = ({ height = '100%' }: LoadingSpinnerProps) => { const LoadingSpinner = ({ height = '100%' }: LoadingSpinnerProps) => {
const { LL } = useI18nContext();
return ( return (
<Box <Box
display="flex" display="flex"
@@ -26,9 +22,6 @@ const LoadingSpinner = ({ height = '100%' }: LoadingSpinnerProps) => {
})} })}
size={100} size={100}
/> />
<Typography variant="h4" color="textSecondary">
{LL.LOADING()}&hellip;
</Typography>
</Box> </Box>
); );
}; };

View File

@@ -20,8 +20,8 @@ export function getStorage() {
export function storeLoginRedirect(location?: H.Location) { export function storeLoginRedirect(location?: H.Location) {
if (location) { if (location) {
getStorage().setItem(SIGN_IN_PATHNAME, location.pathname); getStorage().setItem(SIGN_IN_PATHNAME, location.pathname as string);
getStorage().setItem(SIGN_IN_SEARCH, location.search); getStorage().setItem(SIGN_IN_SEARCH, location.search as string);
} }
} }

View File

@@ -2,5 +2,3 @@ export { default as RouterTabs } from './RouterTabs';
export { default as RequireAdmin } from './RequireAdmin'; export { default as RequireAdmin } from './RequireAdmin';
export { default as RequireAuthenticated } from './RequireAuthenticated'; export { default as RequireAuthenticated } from './RequireAuthenticated';
export { default as RequireUnauthenticated } from './RequireUnauthenticated'; export { default as RequireUnauthenticated } from './RequireUnauthenticated';
export * from './useRouterTab';

View File

@@ -1,8 +0,0 @@
import { useMatch, useResolvedPath } from 'react-router';
export const useRouterTab = () => {
const routerTabPathMatch = useMatch(useResolvedPath(':tab').pathname);
const routerTab = routerTabPathMatch?.params?.tab || false;
return { routerTab } as const;
};

View File

@@ -10,7 +10,7 @@ import { useI18nContext } from 'i18n/i18n-react';
import './dragNdrop.css'; import './dragNdrop.css';
const DragNdrop = ({ onFileSelected }) => { const DragNdrop = ({ text, onFileSelected }) => {
const [file, setFile] = useState<File>(); const [file, setFile] = useState<File>();
const [dragged, setDragged] = useState(false); const [dragged, setDragged] = useState(false);
const inputRef = useRef<HTMLInputElement | null>(null); const inputRef = useRef<HTMLInputElement | null>(null);
@@ -73,7 +73,7 @@ const DragNdrop = ({ onFileSelected }) => {
> >
<div className="upload-info"> <div className="upload-info">
<CloudUploadIcon sx={{ marginRight: 4 }} color="primary" fontSize="large" /> <CloudUploadIcon sx={{ marginRight: 4 }} color="primary" fontSize="large" />
<p>{LL.UPLOAD_DRAG()}</p> <p>{text}</p>
</div> </div>
<input <input

View File

@@ -0,0 +1,23 @@
import {
Box,
LinearProgress,
type LinearProgressProps,
Typography
} from '@mui/material';
export function LinearProgressWithLabel(
props: LinearProgressProps & { value: number }
) {
return (
<Box sx={{ display: 'flex', alignItems: 'center' }}>
<Box sx={{ width: '100%', mr: 1 }}>
<LinearProgress variant="determinate" {...props} />
</Box>
<Box sx={{ minWidth: 35 }}>
<Typography variant="body2" color="text.secondary">{`${Math.round(
props.value
)}%`}</Typography>
</Box>
</Box>
);
}

View File

@@ -2,13 +2,7 @@ import { useEffect, useState } from 'react';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import CancelIcon from '@mui/icons-material/Cancel'; import CancelIcon from '@mui/icons-material/Cancel';
import { import { Box, Button, Typography } from '@mui/material';
Box,
Button,
LinearProgress,
type LinearProgressProps,
Typography
} from '@mui/material';
import * as SystemApi from 'api/system'; import * as SystemApi from 'api/system';
@@ -16,23 +10,9 @@ import { useRequest } from 'alova/client';
import { useI18nContext } from 'i18n/i18n-react'; import { useI18nContext } from 'i18n/i18n-react';
import DragNdrop from './DragNdrop'; import DragNdrop from './DragNdrop';
import { LinearProgressWithLabel } from './LinearProgressWithLabel';
function LinearProgressWithLabel(props: LinearProgressProps & { value: number }) { const SingleUpload = ({ text, doRestart }) => {
return (
<Box sx={{ display: 'flex', alignItems: 'center' }}>
<Box sx={{ width: '100%', mr: 1 }}>
<LinearProgress variant="determinate" {...props} />
</Box>
<Box sx={{ minWidth: 35 }}>
<Typography variant="body2" color="text.secondary">{`${Math.round(
props.value
)}%`}</Typography>
</Box>
</Box>
);
}
const SingleUpload = ({ doRestart }) => {
const [md5, setMd5] = useState<string>(); const [md5, setMd5] = useState<string>();
const [file, setFile] = useState<File>(); const [file, setFile] = useState<File>();
const { LL } = useI18nContext(); const { LL } = useI18nContext();
@@ -93,7 +73,7 @@ const SingleUpload = ({ doRestart }) => {
</Button> </Button>
</> </>
) : ( ) : (
<DragNdrop onFileSelected={setFile} /> <DragNdrop text={text} onFileSelected={setFile} />
)} )}
{md5 && ( {md5 && (

View File

@@ -187,7 +187,7 @@ const cz: Translation = {
COMPACT: 'Kompaktní', COMPACT: 'Kompaktní',
DOWNLOAD_SETTINGS_TEXT: 'Vytvořte zálohu svého nastavení a konfigurace', DOWNLOAD_SETTINGS_TEXT: 'Vytvořte zálohu svého nastavení a konfigurace',
UPLOAD_TEXT: 'Nahrajte nový soubor firmwaru (.bin) nebo záložní soubor (.json)', UPLOAD_TEXT: 'Nahrajte nový soubor firmwaru (.bin) nebo záložní soubor (.json)',
UPLOAD_DROP_TEXT: 'Přetáhněte soubor nebo klikněte sem', UPLOAD_DROP_TEXT: 'Přetáhněte soubor sem nebo klikněte pro výběr',
ERROR: 'Neočekávaná chyba, zkuste to prosím znovu', ERROR: 'Neočekávaná chyba, zkuste to prosím znovu',
TIME_SET: 'Čas nastaven', TIME_SET: 'Čas nastaven',
MANAGE_USERS: 'Spravovat uživatele', MANAGE_USERS: 'Spravovat uživatele',
@@ -331,19 +331,27 @@ const cz: Translation = {
ALLVALUES: 'Všechny hodnoty', ALLVALUES: 'Všechny hodnoty',
SPECIAL_FUNCTIONS: 'Speciální funkce', SPECIAL_FUNCTIONS: 'Speciální funkce',
WAIT_FIRMWARE: 'Firmware se nahrává a instaluje', WAIT_FIRMWARE: 'Firmware se nahrává a instaluje',
INSTALL_VERSION: 'Tímto se instalovat verze {0}. Jste si jistí?', INSTALL_VERSION: 'Tímto se {0} verze {1}. Jste si jistí?',
SWITCH_DEV: 'přepnout na vývojovou verzi', UPDATE_AVAILABLE: 'aktualizace dostupná',
UPGRADE_AVAILABLE: 'Je k dispozici aktualizace firmwaru!', LATEST_VERSION: 'Používáte nejnovější verzi {0}firmwaru',
LATEST_VERSION: 'Používáte nejnovější verzi firmwaru.',
PLEASE_WAIT: 'Prosím čekejte', PLEASE_WAIT: 'Prosím čekejte',
RESTARTING_PRE: 'Inicializace', RESTARTING_PRE: 'Inicializace',
RESTARTING_POST: 'Příprava', RESTARTING_POST: 'Příprava',
AUTO_SCROLL: 'Automatické rolování', AUTO_SCROLL: 'Automatické rolování',
DASHBOARD: 'Dashboard', DASHBOARD: 'Dashboard',
NO_DATA: 'Žádná data nejsou k dispozici',
DASHBOARD_1: 'Přizpůsobte si dashboard označením EMS entit jako Oblíbené pomocí modulu Přizpůsobení',
DEVELOPER_MODE: 'Režim vývojáře', DEVELOPER_MODE: 'Režim vývojáře',
UPGRADE: 'Upgrade' // TODO translate BYTES: 'Bajty',
BITMASK: 'Bit Mask',
DUPLICATE: 'Duplikát',
DASHBOARD_1: 'Všechny aktivní entity EMS jsou označené jako oblíbené. Všechny vlastní entity, harmonogramy a externí sensory jsou zobrazeny níže.',
NO_DATA_1: 'Nebyly nalezeny žádné oblíbené entity. Použijte modul',
NO_DATA_2: 'pro jejich výběr.',
NO_DATA_3: 'Pro zobrazení všech dostupných entit navštivte stránku',
THIS_VERSION: 'Tato verze',
PLATFORM: 'Platforma',
RELEASE_TYPE: 'Typ sestavení',
INTERNET_CONNECTION_REQUIRED: 'Pro automatickou kontrolu a instalaci aktualizací je třeba internetové připojení',
SWITCH_RELEASE_TYPE: 'Přepnout na {0} verzi'
}; };
export default cz; export default cz;

View File

@@ -42,7 +42,7 @@ const de: Translation = {
CANCEL: 'Abbrechen', CANCEL: 'Abbrechen',
RESET: 'Zurücksetzen', RESET: 'Zurücksetzen',
APPLY_CHANGES: 'Änderungen anwenden ({0})', APPLY_CHANGES: 'Änderungen anwenden ({0})',
UPDATE: 'Update', UPDATE: 'Aktualisieren',
EXECUTE: 'Ausführen', EXECUTE: 'Ausführen',
REMOVE: 'Entfernen', REMOVE: 'Entfernen',
PROBLEM_UPDATING: 'Problem beim Aktualisieren', PROBLEM_UPDATING: 'Problem beim Aktualisieren',
@@ -160,7 +160,7 @@ const de: Translation = {
HELP_INFORMATION_3: 'Um neue Funktionen anzufragen oder Fehler zu melden, eröffnen Sie ein Issue auf GitHub', HELP_INFORMATION_3: 'Um neue Funktionen anzufragen oder Fehler zu melden, eröffnen Sie ein Issue auf GitHub',
HELP_INFORMATION_4: 'Bitte laden Sie die Systemdetails und hängen Sie sie an das Support-Issue an', HELP_INFORMATION_4: 'Bitte laden Sie die Systemdetails und hängen Sie sie an das Support-Issue an',
UPLOAD: 'Hochladen', UPLOAD: 'Hochladen',
DOWNLOAD: '{{H|h|h}}erunterladen', DOWNLOAD: '{{Herunterladen|heruntergeladen|}}',
INSTALL: 'Installieren', INSTALL: 'Installieren',
ABORTED: 'abgebrochen', ABORTED: 'abgebrochen',
FAILED: 'gescheitert', FAILED: 'gescheitert',
@@ -187,7 +187,7 @@ const de: Translation = {
COMPACT: 'Kompakte Darstellung', COMPACT: 'Kompakte Darstellung',
DOWNLOAD_SETTINGS_TEXT: 'Erstellen Sie eine Sicherung Ihrer Konfigurationen und Einstellungen', DOWNLOAD_SETTINGS_TEXT: 'Erstellen Sie eine Sicherung Ihrer Konfigurationen und Einstellungen',
UPLOAD_TEXT: 'Laden Sie eine neue Firmware-Datei (.bin) oder eine Sicherungsdatei (.json) hoch', UPLOAD_TEXT: 'Laden Sie eine neue Firmware-Datei (.bin) oder eine Sicherungsdatei (.json) hoch',
UPLOAD_DROP_TEXT: 'Klicken Sie hier, oder ziehen Sie eine Datei hierher.', UPLOAD_DROP_TEXT: 'Legen Sie eine Firmware-Datei (.bin) ab oder klicken Sie hier',
ERROR: 'Unerwarteter Fehler, bitte versuchen Sie es erneut.', ERROR: 'Unerwarteter Fehler, bitte versuchen Sie es erneut.',
TIME_SET: 'Zeit gesetzt', TIME_SET: 'Zeit gesetzt',
MANAGE_USERS: 'Nutzerverwaltung', MANAGE_USERS: 'Nutzerverwaltung',
@@ -331,19 +331,27 @@ const de: Translation = {
ALLVALUES: 'Alle Werte', ALLVALUES: 'Alle Werte',
SPECIAL_FUNCTIONS: 'Sonderfunktionen', SPECIAL_FUNCTIONS: 'Sonderfunktionen',
WAIT_FIRMWARE: 'Die Firmware wird hochgeladen und installiert.', WAIT_FIRMWARE: 'Die Firmware wird hochgeladen und installiert.',
INSTALL_VERSION: 'Dadurch wird die Version {0} heruntergeladen. Sind Sie sicher?', INSTALL_VERSION: 'Dadurch wird die Version {1} {0}. Sind Sie sicher?',
SWITCH_DEV: 'Wechseln Sie zur Entwicklungsversion!', UPDATE_AVAILABLE: 'Firmware-Update verfügbar',
UPGRADE_AVAILABLE: 'Es ist ein Firmware-Upgrade verfügbar.', LATEST_VERSION: 'Sie verwenden die neueste {0} Firmware-Version',
LATEST_VERSION: 'Sie verwenden die neueste Firmware-Version.',
PLEASE_WAIT: 'Bitte warten', PLEASE_WAIT: 'Bitte warten',
RESTARTING_PRE: 'Initialisierung', RESTARTING_PRE: 'Initialisierung',
RESTARTING_POST: 'Vorbereitung', RESTARTING_POST: 'Vorbereitung',
AUTO_SCROLL: 'Automatisches Scrollen', AUTO_SCROLL: 'Automatisches Scrollen',
DASHBOARD: 'Dashboard', DASHBOARD: 'Dashboard',
NO_DATA: 'Keine Daten verfügbar',
DASHBOARD_1: 'Passen Sie Ihr Dashboard an, indem Sie EMS-Entitäten mithilfe des Moduls „Anpassungen“ als Favorit markieren',
DEVELOPER_MODE: 'Entwicklermodus', DEVELOPER_MODE: 'Entwicklermodus',
UPGRADE: 'Upgrade' // TODO translate BYTES: 'Bytes',
BITMASK: 'Bit Maske',
DUPLICATE: 'Kopieren',
DASHBOARD_1: 'Alle EMS-Entitäten, die aktiv und als Favorit markiert sind, sowie alle benutzerdefinierten Entitäten, Zeitpläne und externen Sensordaten werden unten angezeigt.',
NO_DATA_1: 'Keine favorisierten EMS-Entitäten gefunden! Verwenden Sie das Modul',
NO_DATA_2: ', um sie zu markieren.',
NO_DATA_3: 'Um alle verfügbaren Entitäten anzuzeigen, gehen Sie zu',
THIS_VERSION: 'Diese Version',
PLATFORM: 'Plattform',
RELEASE_TYPE: 'Release Typ',
INTERNET_CONNECTION_REQUIRED: 'Für die automatische Versionsprüfung und Aktualisierung ist eine Internetverbindung erforderlich',
SWITCH_RELEASE_TYPE: 'Zum {0}-Release wechseln'
}; };
export default de; export default de;

View File

@@ -187,7 +187,7 @@ const en: Translation = {
COMPACT: 'Compact', COMPACT: 'Compact',
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings',
UPLOAD_TEXT: 'Upload a new firmware file (.bin) or a backup file (.json)', UPLOAD_TEXT: 'Upload a new firmware file (.bin) or a backup file (.json)',
UPLOAD_DROP_TEXT: 'Drop file or click here', UPLOAD_DROP_TEXT: 'Drop a firmware .bin file or click here',
ERROR: 'Unexpected Error, please try again', ERROR: 'Unexpected Error, please try again',
TIME_SET: 'Time set', TIME_SET: 'Time set',
MANAGE_USERS: 'Manage Users', MANAGE_USERS: 'Manage Users',
@@ -331,19 +331,27 @@ const en: Translation = {
ALLVALUES: 'All Values', ALLVALUES: 'All Values',
SPECIAL_FUNCTIONS: 'Special Functions', SPECIAL_FUNCTIONS: 'Special Functions',
WAIT_FIRMWARE: 'Firmware is uploading and installing', WAIT_FIRMWARE: 'Firmware is uploading and installing',
INSTALL_VERSION: 'This will install version {0}. Are you sure?', INSTALL_VERSION: 'This will {0} version {1}. Are you sure?',
SWITCH_DEV: 'switch to the development version', UPDATE_AVAILABLE: 'update available',
UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', LATEST_VERSION: 'You are using the latest {0} firmware version',
LATEST_VERSION: 'You are using the latest firmware version.',
PLEASE_WAIT: 'Please wait', PLEASE_WAIT: 'Please wait',
RESTARTING_PRE: 'Initializing', RESTARTING_PRE: 'Initializing',
RESTARTING_POST: 'Preparing', RESTARTING_POST: 'Preparing',
AUTO_SCROLL: 'Auto Scroll', AUTO_SCROLL: 'Auto Scroll',
DASHBOARD: 'Dashboard', DASHBOARD: 'Dashboard',
NO_DATA: 'No data available', DASHBOARD_1: 'All EMS entities that are active and marked as Favorite, plus all Custom Entities, Schedules and external Sensors data are displayed below.',
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module',
DEVELOPER_MODE: 'Developer Mode', DEVELOPER_MODE: 'Developer Mode',
UPGRADE: 'Upgrade' BYTES: 'Bytes',
BITMASK: 'Bit Mask',
DUPLICATE: 'Duplicate',
NO_DATA_1: 'No favorite EMS entities found yet. Use the',
NO_DATA_2: 'module to mark them.',
NO_DATA_3: 'To see all available entities go to',
THIS_VERSION: 'This Version',
PLATFORM: 'Platform',
RELEASE_TYPE: 'Release Type',
INTERNET_CONNECTION_REQUIRED: 'Internet connection required for automatic version checking and upgrading',
SWITCH_RELEASE_TYPE: 'Switch to {0} release'
}; };
export default en; export default en;

View File

@@ -41,9 +41,9 @@ const fr: Translation = {
CHANGE_VALUE: 'Changer la valeur', CHANGE_VALUE: 'Changer la valeur',
CANCEL: 'Annuler', CANCEL: 'Annuler',
RESET: 'Réinitialiser', RESET: 'Réinitialiser',
APPLY_CHANGES: 'Apply Changes ({0})', // TODO translate APPLY_CHANGES: 'Appliquer les changements ({0})',
UPDATE: 'Update', // TODO translate UPDATE: 'Update',
EXECUTE: 'Execute', // TODO translate EXECUTE: 'Execute',
REMOVE: 'Enlever', REMOVE: 'Enlever',
PROBLEM_UPDATING: 'Problème lors de la mise à jour', PROBLEM_UPDATING: 'Problème lors de la mise à jour',
PROBLEM_LOADING: 'Problème lors du chargement', PROBLEM_LOADING: 'Problème lors du chargement',
@@ -66,13 +66,13 @@ const fr: Translation = {
TEMP_SENSOR: 'Capteur de température', TEMP_SENSOR: 'Capteur de température',
TEMP_SENSORS: 'Capteurs de température', TEMP_SENSORS: 'Capteurs de température',
WRITE_CMD_SENT: 'Envoyer la commande sent', WRITE_CMD_SENT: 'Envoyer la commande sent',
EMS_BUS_WARNING: 'Bus EMS déconnecté. Si ce message persiste après quelques secondes, vérifiez les paramètres et la configuration de la carte.', EMS_BUS_WARNING: 'Bus EMS déconnecté. Si ce message persiste après quelques secondes, vérifiez les paramètres et la configuration de la carte.',
EMS_BUS_SCANNING: 'Scan des appareils EMS...', EMS_BUS_SCANNING: 'Scan des appareils EMS...',
CONNECTED: 'Connecté', CONNECTED: 'Connecté',
TX_ISSUES: 'Problèmes de transmission (Tx) - Essayez un autre mode Tx', TX_ISSUES: 'Problèmes de transmission (Tx) - Essayez un autre mode Tx',
DISCONNECTED: 'Déconnecté', DISCONNECTED: 'Déconnecté',
EMS_SCAN: 'Etes-vous sûr de vouloir lancer un scan complet du bus EMS ?', EMS_SCAN: 'Etes-vous sûr de vouloir lancer un scan complet du bus EMS ?',
DATA_TRAFFIC: 'Data Traffic', // TODO translate DATA_TRAFFIC: 'Traffic des données',
EMS_DEVICE: 'Appareils EMS', EMS_DEVICE: 'Appareils EMS',
SUCCESS: 'SUCCÈS', SUCCESS: 'SUCCÈS',
FAIL: 'ÉCHEC', FAIL: 'ÉCHEC',
@@ -114,9 +114,9 @@ const fr: Translation = {
BYPASS_TOKEN: "Contourner l'autorisation du jeton d'accès sur les appels API", BYPASS_TOKEN: "Contourner l'autorisation du jeton d'accès sur les appels API",
READONLY: 'Activer le mode lecture uniquement (bloque toutes les commandes EMS sortantes en écriture Tx)', READONLY: 'Activer le mode lecture uniquement (bloque toutes les commandes EMS sortantes en écriture Tx)',
UNDERCLOCK_CPU: 'Underclock du CPU', UNDERCLOCK_CPU: 'Underclock du CPU',
HEATINGOFF: 'Start boiler with forced heating off', // TODO translate HEATINGOFF: 'Démarrer le chauffage avec le chauffage forcé éteint',
REMOTE_TIMEOUT: 'Remote timeout', REMOTE_TIMEOUT: 'Remote timeout',
REMOTE_TIMEOUT_EN: 'Disable remote on missing room temperature', // TODO translate REMOTE_TIMEOUT_EN: 'Disable remote on missing room temperature',
MIN_DURATION: 'Wait time', MIN_DURATION: 'Wait time',
ENABLE_SHOWER_TIMER: 'Activer la minuterie de la douche', ENABLE_SHOWER_TIMER: 'Activer la minuterie de la douche',
ENABLE_SHOWER_ALERT: 'Activer les alertes de durée de douche', ENABLE_SHOWER_ALERT: 'Activer les alertes de durée de douche',
@@ -148,7 +148,7 @@ const fr: Translation = {
CUSTOMIZATIONS_HELP_3: "désactiver l'action d'écriture", CUSTOMIZATIONS_HELP_3: "désactiver l'action d'écriture",
CUSTOMIZATIONS_HELP_4: "exclure de MQTT et de l'API", CUSTOMIZATIONS_HELP_4: "exclure de MQTT et de l'API",
CUSTOMIZATIONS_HELP_5: 'cacher des appareils', CUSTOMIZATIONS_HELP_5: 'cacher des appareils',
CUSTOMIZATIONS_HELP_6: 'remove from memory', // TODO translate CUSTOMIZATIONS_HELP_6: 'supprimer de la mémoire',
SELECT_DEVICE: 'Sélectionnez un appareil', SELECT_DEVICE: 'Sélectionnez un appareil',
SET_ALL: 'tout régler', SET_ALL: 'tout régler',
OPTIONS: 'Options', OPTIONS: 'Options',
@@ -168,14 +168,14 @@ const fr: Translation = {
SYSTEM: 'Système', SYSTEM: 'Système',
LOG_OF: '{0} Log', LOG_OF: '{0} Log',
STATUS_OF: 'Statut {0}', STATUS_OF: 'Statut {0}',
DOWNLOAD_UPLOAD: 'Download/Upload', // TODO translate DOWNLOAD_UPLOAD: 'Télécharger/Mettre à jour',
CLOSE: 'Fermer', CLOSE: 'Fermer',
USE: 'Utiliser', USE: 'Utiliser',
FACTORY_RESET: 'Réinitialisation', FACTORY_RESET: 'Réinitialisation',
SYSTEM_FACTORY_TEXT: "L'appareil a été réinitialisé et va maintenant redémarrer", SYSTEM_FACTORY_TEXT: "L'appareil a été réinitialisé et va maintenant redémarrer",
SYSTEM_FACTORY_TEXT_DIALOG: "Êtes-vous sûr de vouloir réinitialiser l'appareil à ses paramètres d'usine ?", SYSTEM_FACTORY_TEXT_DIALOG: "Êtes-vous sûr de vouloir réinitialiser l'appareil à ses paramètres d'usine ?",
AVAILABLE_VERSION: 'Latest Available Versions', // TODO translate AVAILABLE_VERSION: 'Versions disponibles',
STABLE: 'Stable', // TODO translate STABLE: 'Stable',
DEVELOPMENT: 'Développement', DEVELOPMENT: 'Développement',
UPTIME: 'Durée de fonctionnement du système', UPTIME: 'Durée de fonctionnement du système',
FREE_MEMORY: 'Libre Memory', FREE_MEMORY: 'Libre Memory',
@@ -185,9 +185,9 @@ const fr: Translation = {
FILESYSTEM: 'File System (Utilisée / Libre)', FILESYSTEM: 'File System (Utilisée / Libre)',
BUFFER_SIZE: 'Max taille du buffer', BUFFER_SIZE: 'Max taille du buffer',
COMPACT: 'Compact', COMPACT: 'Compact',
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate DOWNLOAD_SETTINGS_TEXT: 'Créer une sauvegarde de vos paramètres et configurations',
UPLOAD_TEXT: 'Upload a new firmware file (.bin) or a backup file (.json)', // TODO translate UPLOAD_TEXT: 'Télécharger un nouveau fichier firmware (.bin) ou une sauvegarde (.json)',
UPLOAD_DROP_TEXT: 'Déposer le fichier ou cliquer ici', UPLOAD_DROP_TEXT: 'Drop a firmware .bin file or click here',
ERROR: 'Erreur inattendue, veuillez réessayer', ERROR: 'Erreur inattendue, veuillez réessayer',
TIME_SET: 'Time set', TIME_SET: 'Time set',
MANAGE_USERS: 'Gérer les utilisateurs', MANAGE_USERS: 'Gérer les utilisateurs',
@@ -217,7 +217,7 @@ const fr: Translation = {
MQTT_PUBLISH_TEXT_2: 'Publier vers des topics de commande (ioBroker)', MQTT_PUBLISH_TEXT_2: 'Publier vers des topics de commande (ioBroker)',
MQTT_PUBLISH_TEXT_3: 'Activer la découverte MQTT', MQTT_PUBLISH_TEXT_3: 'Activer la découverte MQTT',
MQTT_PUBLISH_TEXT_4: 'Préfixe pour les topics découverte', MQTT_PUBLISH_TEXT_4: 'Préfixe pour les topics découverte',
MQTT_PUBLISH_TEXT_5: 'Discovery type', // TODO translate MQTT_PUBLISH_TEXT_5: 'Type de découverte',
MQTT_PUBLISH_INTERVALS: 'Intervalles de publication', MQTT_PUBLISH_INTERVALS: 'Intervalles de publication',
MQTT_INT_BOILER: 'Chaudières et pompes à chaleur', MQTT_INT_BOILER: 'Chaudières et pompes à chaleur',
MQTT_INT_THERMOSTATS: 'Thermostats', MQTT_INT_THERMOSTATS: 'Thermostats',
@@ -226,10 +226,10 @@ const fr: Translation = {
MQTT_INT_WATER: 'Modules eau', MQTT_INT_WATER: 'Modules eau',
MQTT_QUEUE: 'Queue MQTT', MQTT_QUEUE: 'Queue MQTT',
DEFAULT: 'Défaut', DEFAULT: 'Défaut',
MQTT_ENTITY_FORMAT: 'Entity ID format', // TODO translate MQTT_ENTITY_FORMAT: 'Format de l\'ID de l\'entité',
MQTT_ENTITY_FORMAT_0: 'Single instance, long name (v3.4)', // TODO translate MQTT_ENTITY_FORMAT_0: 'Instance unique, nom long (v3.4)',
MQTT_ENTITY_FORMAT_1: 'Single instance, short name', // TODO translate MQTT_ENTITY_FORMAT_1: 'Instance unique, nom court',
MQTT_ENTITY_FORMAT_2: 'Multiple instances, short name', // TODO translate MQTT_ENTITY_FORMAT_2: 'Instances multiples, nom court',
MQTT_CLEAN_SESSION: 'Flag Clean Session', MQTT_CLEAN_SESSION: 'Flag Clean Session',
MQTT_RETAIN_FLAG: 'Toujours activer le Retain Flag', MQTT_RETAIN_FLAG: 'Toujours activer le Retain Flag',
INACTIVE: 'Inactif', INACTIVE: 'Inactif',
@@ -260,7 +260,7 @@ const fr: Translation = {
NETWORK_SCANNER: 'Scan réseau', NETWORK_SCANNER: 'Scan réseau',
NETWORK_NO_WIFI: 'Pas de réseau WiFi trouvé', NETWORK_NO_WIFI: 'Pas de réseau WiFi trouvé',
NETWORK_BLANK_SSID: 'laisser vide pour désactiver le WiFi', NETWORK_BLANK_SSID: 'laisser vide pour désactiver le WiFi',
NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate NETWORK_BLANK_BSSID: 'laisser vide pour utiliser uniquement le SSID',
TX_POWER: 'Puissance Tx', TX_POWER: 'Puissance Tx',
HOSTNAME: "Nom d'hôte", HOSTNAME: "Nom d'hôte",
NETWORK_DISABLE_SLEEP: 'Désactiver le mode veille du WiFi', NETWORK_DISABLE_SLEEP: 'Désactiver le mode veille du WiFi',
@@ -280,70 +280,78 @@ const fr: Translation = {
ENTITY: 'entité', ENTITY: 'entité',
MIN: 'min', MIN: 'min',
MAX: 'max', MAX: 'max',
BLOCK_NAVIGATE_1: 'You have unsaved changes', // TODO translate BLOCK_NAVIGATE_1: 'Vous avez des modifications non enregistrées',
BLOCK_NAVIGATE_2: 'If you navigate to a different page, your unsaved changes will be lost. Are you sure you want to leave this page?', // TODO translate BLOCK_NAVIGATE_2: 'Si vous naviguez vers une autre page, vos modifications non enregistrées seront perdues. Êtes-vous sûr de vouloir quitter cette page ?',
STAY: 'Stay', // TODO translate STAY: 'Rester',
LEAVE: 'Leave', // TODO translate LEAVE: 'Quitter',
SCHEDULER: 'Scheduler', // TODO translate SCHEDULER: 'Scheduler',
SCHEDULER_HELP_1: 'Automate commands by adding scheduled events below. Set a unique Name to enable/disable activation via API/MQTT', // TODO translate SCHEDULER_HELP_1: 'Automatiser les commandes en ajoutant des événements programmés ci-dessous. Définissez un nom unique pour activer/désactiver l\'activation via API/MQTT',
SCHEDULER_HELP_2: 'Use 00:00 to trigger once on start-up', // TODO translate SCHEDULER_HELP_2: 'Utiliser 00:00 pour déclencher une fois au démarrage',
SCHEDULE: 'Schedule', // TODO translate SCHEDULE: 'Programme',
TIME: 'Time', // TODO translate TIME: 'Temps',
TIMER: 'Timer', // TODO translate TIMER: 'Minuteur',
ONCHANGE: 'Sur le changement', // TODO translate ONCHANGE: 'Sur le changement',
CONDITION: 'Condition', // TODO translate CONDITION: 'Condition',
IMMEDIATE: 'Immédiate', // TODO translate IMMEDIATE: 'Immédiat',
SCHEDULE_UPDATED: 'Schedule updated', // TODO translate SCHEDULE_UPDATED: 'Programme mis à jour',
SCHEDULE_TIMER_1: 'on startup', // TODO translate SCHEDULE_TIMER_1: 'au démarrage',
SCHEDULE_TIMER_2: 'every minute', // TODO translate SCHEDULE_TIMER_2: 'toutes les minutes',
SCHEDULE_TIMER_3: 'every hour', // TODO translate SCHEDULE_TIMER_3: 'toutes les heures',
CUSTOM_ENTITIES: 'Custom Entities', // TODO translate CUSTOM_ENTITIES: 'Entités personnalisées',
ENTITIES_HELP_1: 'Fetch custom entities from the EMS bus', // TODO translate ENTITIES_HELP_1: 'Récupérer les entités personnalisées du bus EMS',
ENTITIES_UPDATED: 'Entities Updated', // TODO translate ENTITIES_UPDATED: 'Entités mises à jour',
WRITEABLE: 'Writeable', // TODO translate WRITEABLE: 'Écriture',
SHOWING: 'Showing', // TODO translate SHOWING: 'Affichage',
SEARCH: 'Search', // TODO translate SEARCH: 'Rechercher',
CERT: 'TLS root certificate (leave blank for insecure)', // TODO translate CERT: 'Certificat racine TLS (laisser vide pour l\'insecurité)',
ENABLE_TLS: 'Activer TLS', ENABLE_TLS: 'Activer TLS',
ON: 'On', // TODO translate ON: 'On',
OFF: 'Off', // TODO translate OFF: 'Off',
POLARITY: 'Polarity', // TODO translate POLARITY: 'Polarity',
ACTIVEHIGH: 'Active High', // TODO translate ACTIVEHIGH: 'Actif haut',
ACTIVELOW: 'Active Low', // TODO translate ACTIVELOW: 'Actif bas',
UNCHANGED: 'Unchanged', // TODO translate UNCHANGED: 'Inchangé',
ALWAYS: 'Always', // TODO translate ALWAYS: 'Toujours',
ACTIVITY: 'Activity', // TODO translate ACTIVITY: 'Activité',
CONFIGURE: 'Configure {0}', // TODO translate CONFIGURE: 'Configurer {0}',
SYSTEM_MEMORY: 'System Memory', // TODO translate SYSTEM_MEMORY: 'Mémoire système',
APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate APPLICATION_SETTINGS_1: 'Modifier les paramètres de l\'application EMS-ESP',
SECURITY_1: 'Add or remove users', // TODO translate SECURITY_1: 'Ajouter ou supprimer des utilisateurs',
DOWNLOAD_UPLOAD_1: 'Download and Upload Settings and Firmware', // TODO translate DOWNLOAD_UPLOAD_1: 'Télécharger et mettre à jour les paramètres et le firmware',
MODULES: 'Module', // TODO translate MODULES: 'Module',
MODULES_1: 'Activer ou désactiver les modules externes', MODULES_1: 'Activer ou désactiver les modules externes',
MODULES_UPDATED: 'Modules updated', // TODO translate MODULES_UPDATED: 'Modules mis à jour',
MODULES_DESCRIPTION: 'Click on the Module to activate or de-activate EMS-ESP library modules', // TODO translate MODULES_DESCRIPTION: 'Cliquer sur le module pour activer ou désactiver les modules EMS-ESP',
MODULES_NONE: 'No external modules detected', // TODO translate MODULES_NONE: 'Aucun module externe détecté',
RENAME: 'Rename', // TODO translate RENAME: 'Renommer',
ENABLE_MODBUS: 'Activer Modbus', ENABLE_MODBUS: 'Activer Modbus',
VIEW_LOG: 'View log to diagnose issues', // TODO translate VIEW_LOG: 'Voir le journal pour diagnostiquer les problèmes',
UPLOAD_DRAG: 'drag and drop a file here or click to select one', // TODO translate UPLOAD_DRAG: 'glisser-déposer un fichier ici ou cliquer pour en sélectionner un',
SERVICES: 'Services', // TODO translate SERVICES: 'Services',
ALLVALUES: 'All Values', // TODO translate ALLVALUES: 'Toutes les valeurs',
SPECIAL_FUNCTIONS: 'Special Functions', SPECIAL_FUNCTIONS: 'Fonctions spéciales',
WAIT_FIRMWARE: 'Firmware is uploading and installing', // TODO translate WAIT_FIRMWARE: 'Firmware en cours de téléchargement et d\'installation',
INSTALL_VERSION: 'This will install version {0}. Are you sure?', // TODO translate INSTALL_VERSION: 'Cela va {0} la version {1}. Êtes-vous sûr ?',
SWITCH_DEV: 'switch to the development version', // TODO translate UPDATE_AVAILABLE: 'mise à jour disponible',
UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate LATEST_VERSION: 'Vous utilisez la dernière version {0} du firmware',
LATEST_VERSION: 'You are using the latest firmware version.', // TODO translate PLEASE_WAIT: 'Veuillez patienter',
PLEASE_WAIT: 'Please wait', // TODO translate RESTARTING_PRE: 'Initialisation',
RESTARTING_PRE: 'Initializing', // TODO translate RESTARTING_POST: 'Préparation',
RESTARTING_POST: 'Preparing', // TODO translate AUTO_SCROLL: 'Défilement automatique',
AUTO_SCROLL: 'Auto Scroll', // TODO translate DASHBOARD: 'Tableau de bord',
DASHBOARD: 'Dashboard', // TODO translate DEVELOPER_MODE: 'Mode développeur',
NO_DATA: 'No data available', // TODO translate BYTES: 'Octets',
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate BITMASK: 'Masque de bits',
DEVELOPER_MODE: 'Developer Mode', // TODO translate DUPLICATE: 'Dupliquer',
UPGRADE: 'Upgrade' // TODO translate DASHBOARD_1: 'Toutes les entités EMS actives et marquées comme favoris, plus toutes les entités personnalisées, les programmes et les données des capteurs externes sont affichées ci-dessous.',
NO_DATA_1: 'Aucune entité EMS favorite trouvée. Utilisez le',
NO_DATA_2: 'module pour les marquer.',
NO_DATA_3: 'Pour voir toutes les entités disponibles, aller à',
THIS_VERSION: 'Cette version',
PLATFORM: 'Plateforme',
RELEASE_TYPE: 'Type de version',
INTERNET_CONNECTION_REQUIRED: 'Connexion Internet requise pour la vérification automatique des versions et la mise à niveau',
SWITCH_RELEASE_TYPE: 'Passer à la version {0}'
}; };
export default fr; export default fr;

View File

@@ -72,7 +72,7 @@ const it: Translation = {
TX_ISSUES: 'Problema di Tx - prova una modalità differente', TX_ISSUES: 'Problema di Tx - prova una modalità differente',
DISCONNECTED: 'Disconnesso', DISCONNECTED: 'Disconnesso',
EMS_SCAN: 'Sei sicuro di voler iniziare una scansione completa del bus EMS ?', EMS_SCAN: 'Sei sicuro di voler iniziare una scansione completa del bus EMS ?',
DATA_TRAFFIC: 'Data Traffic', // TODO translate DATA_TRAFFIC: 'Traffico dati',
EMS_DEVICE: 'Dispositivo EMS ', EMS_DEVICE: 'Dispositivo EMS ',
SUCCESS: 'SUCCESSO', SUCCESS: 'SUCCESSO',
FAIL: 'FALLITO', FAIL: 'FALLITO',
@@ -115,7 +115,7 @@ const it: Translation = {
READONLY: 'Abilita modalità sola-lettura (blocca tutti i comandi di scrittura EMS Tx in uscita)', READONLY: 'Abilita modalità sola-lettura (blocca tutti i comandi di scrittura EMS Tx in uscita)',
UNDERCLOCK_CPU: 'Abbassa velocità della CPU', UNDERCLOCK_CPU: 'Abbassa velocità della CPU',
REMOTE_TIMEOUT: 'Remote timeout', REMOTE_TIMEOUT: 'Remote timeout',
REMOTE_TIMEOUT_EN: 'Disable remote on missing room temperature', // TODO translate REMOTE_TIMEOUT_EN: 'Disabilitare il telecomando in caso di temperatura ambiente mancante',
HEATINGOFF: 'Avviamento caldaia con riscaldamento forzato spento', HEATINGOFF: 'Avviamento caldaia con riscaldamento forzato spento',
MIN_DURATION: 'Wait time', MIN_DURATION: 'Wait time',
ENABLE_SHOWER_TIMER: 'Abilita timer doccia', ENABLE_SHOWER_TIMER: 'Abilita timer doccia',
@@ -174,8 +174,8 @@ const it: Translation = {
FACTORY_RESET: 'Impostazioni di fabbrica', FACTORY_RESET: 'Impostazioni di fabbrica',
SYSTEM_FACTORY_TEXT: 'Il dispositivo è stato ripristinato alle impostazioni di fabbrica e ora verrà riavviato', SYSTEM_FACTORY_TEXT: 'Il dispositivo è stato ripristinato alle impostazioni di fabbrica e ora verrà riavviato',
SYSTEM_FACTORY_TEXT_DIALOG: 'Sei sicuro di voler ripristinare il dispositivo alle impostazioni di fabbrica??', SYSTEM_FACTORY_TEXT_DIALOG: 'Sei sicuro di voler ripristinare il dispositivo alle impostazioni di fabbrica??',
AVAILABLE_VERSION: 'Latest Available Versions', // TODO translate AVAILABLE_VERSION: 'Versioni disponibili',
STABLE: 'Stable', // TODO translate STABLE: 'Stabile',
DEVELOPMENT: 'Sviluppo', DEVELOPMENT: 'Sviluppo',
UPTIME: 'Tempo di attività del sistema', UPTIME: 'Tempo di attività del sistema',
FREE_MEMORY: 'Free Memory', FREE_MEMORY: 'Free Memory',
@@ -184,10 +184,10 @@ const it: Translation = {
APPSIZE: 'Applicazione (Partizione: Usata / Libera)', APPSIZE: 'Applicazione (Partizione: Usata / Libera)',
FILESYSTEM: 'Memoria Sistema (Usata / Libera)', FILESYSTEM: 'Memoria Sistema (Usata / Libera)',
BUFFER_SIZE: 'Max Buffer Size', BUFFER_SIZE: 'Max Buffer Size',
COMPACT: 'Compact', COMPACT: 'Compatto',
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings',
UPLOAD_TEXT: 'Upload a new firmware file (.bin) or a backup file (.json)', // TODO translate UPLOAD_TEXT: 'Upload a new firmware file (.bin) or a backup file (.json)',
UPLOAD_DROP_TEXT: 'Trascina il file o clicca qui', UPLOAD_DROP_TEXT: 'Drop a firmware .bin file or click here',
ERROR: 'Errore Inaspettato, prego tenta ancora', ERROR: 'Errore Inaspettato, prego tenta ancora',
TIME_SET: 'Imposta Ora', TIME_SET: 'Imposta Ora',
MANAGE_USERS: 'Gestione Utenti', MANAGE_USERS: 'Gestione Utenti',
@@ -260,7 +260,7 @@ const it: Translation = {
NETWORK_SCANNER: 'Scansione Rete', NETWORK_SCANNER: 'Scansione Rete',
NETWORK_NO_WIFI: 'Nessuana rete WiFi trovata', NETWORK_NO_WIFI: 'Nessuana rete WiFi trovata',
NETWORK_BLANK_SSID: 'lasciare vuoto per disattivare WiFi', NETWORK_BLANK_SSID: 'lasciare vuoto per disattivare WiFi',
NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate NETWORK_BLANK_BSSID: 'lasciare vuoto per usare solo SSID',
TX_POWER: 'Potenza Tx', TX_POWER: 'Potenza Tx',
HOSTNAME: 'Nome ospite', HOSTNAME: 'Nome ospite',
NETWORK_DISABLE_SLEEP: 'Disabilita la modalità sospensione Wi-Fi', NETWORK_DISABLE_SLEEP: 'Disabilita la modalità sospensione Wi-Fi',
@@ -303,47 +303,55 @@ const it: Translation = {
WRITEABLE: 'Scrivibile', WRITEABLE: 'Scrivibile',
SHOWING: 'Visualizza', SHOWING: 'Visualizza',
SEARCH: 'Ricerca', SEARCH: 'Ricerca',
CERT: 'TLS root certificate (leave blank for insecure)', // TODO translate CERT: 'Certificato radice TLS (lasciare vuoto per l\'insecure)',
ENABLE_TLS: 'Abilita TLS', ENABLE_TLS: 'Abilita TLS',
ON: 'On', // TODO translate ON: 'On',
OFF: 'Off', // TODO translate OFF: 'Off',
POLARITY: 'Polarity', // TODO translate POLARITY: 'Polarity',
ACTIVEHIGH: 'Active High', // TODO translate ACTIVEHIGH: 'Active High',
ACTIVELOW: 'Active Low', // TODO translate ACTIVELOW: 'Active Low',
UNCHANGED: 'Unchanged', // TODO translate UNCHANGED: 'Unchanged',
ALWAYS: 'Always', // TODO translate ALWAYS: 'Always',
ACTIVITY: 'Activity', // TODO translate ACTIVITY: 'Activity',
CONFIGURE: 'Configure {0}', // TODO translate CONFIGURE: 'Configure {0}',
SYSTEM_MEMORY: 'System Memory', // TODO translate SYSTEM_MEMORY: 'System Memory',
APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings',
SECURITY_1: 'Add or remove users', // TODO translate SECURITY_1: 'Add or remove users',
DOWNLOAD_UPLOAD_1: 'Download and Upload Settings and Firmware', // TODO translate DOWNLOAD_UPLOAD_1: 'Download and Upload Settings and Firmware',
MODULES: 'Module', // TODO translate MODULES: 'Module',
MODULES_1: 'Attiva o disattiva i moduli esterni', // TODO translate MODULES_1: 'Attiva o disattiva i moduli esterni',
MODULES_UPDATED: 'Modules updated', // TODO translate MODULES_UPDATED: 'Modules updated',
MODULES_DESCRIPTION: 'Click on the Module to activate or de-activate EMS-ESP library modules', // TODO translate MODULES_DESCRIPTION: 'Click on the Module to activate or de-activate EMS-ESP library modules',
MODULES_NONE: 'No external modules detected', // TODO translate MODULES_NONE: 'No external modules detected',
RENAME: 'Rename', // TODO translate RENAME: 'Rename',
ENABLE_MODBUS: 'Abilita Modbus', ENABLE_MODBUS: 'Abilita Modbus',
VIEW_LOG: 'View log to diagnose issues', // TODO translate VIEW_LOG: 'Visualizza log per diagnosticare problemi',
UPLOAD_DRAG: 'drag and drop a file here or click to select one', // TODO translate UPLOAD_DRAG: 'trascina e rilascia un file qui o clicca per selezionare uno',
SERVICES: 'Services', // TODO translate SERVICES: 'Servizi',
ALLVALUES: 'All Values', // TODO translate ALLVALUES: 'Tutti i valori',
SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate SPECIAL_FUNCTIONS: 'Funzioni speciali',
WAIT_FIRMWARE: 'Firmware is uploading and installing', // TODO translate WAIT_FIRMWARE: 'Firmware è in upload e installazione',
INSTALL_VERSION: 'This will install version {0}. Are you sure?', // TODO translate INSTALL_VERSION: 'Questo installerà la versione {1} {0}. Sei sicuro?',
SWITCH_DEV: 'switch to the development version', // TODO translate UPDATE_AVAILABLE: 'aggiornamento disponibile',
UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate LATEST_VERSION: 'Stai usando la versione più recente del firmware {0}',
LATEST_VERSION: 'You are using the latest firmware version.', // TODO translate PLEASE_WAIT: 'Attendere',
PLEASE_WAIT: 'Please wait', // TODO translate RESTARTING_PRE: 'Inizializzazione',
RESTARTING_PRE: 'Initializing', // TODO translate RESTARTING_POST: 'Preparazione',
RESTARTING_POST: 'Preparing', // TODO translate AUTO_SCROLL: 'Scorrimento automatico',
AUTO_SCROLL: 'Auto Scroll', // TODO translate DASHBOARD: 'Pannello di controllo',
DASHBOARD: 'Dashboard', // TODO translate DEVELOPER_MODE: 'Modalità sviluppatore',
NO_DATA: 'No data available', // TODO translate BYTES: 'Byte',
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate BITMASK: 'Bitmask',
DEVELOPER_MODE: 'Developer Mode', // TODO translate DUPLICATE: 'Duplicato',
UPGRADE: 'Upgrade' // TODO translate DASHBOARD_1: 'Tutte le entità EMS che sono attive e marcate come preferite, più tutte le entità personalizzate, piani di programmazione e dati dei sensori esterni sono visualizzati di seguito.',
NO_DATA_1: 'Nessuna entità EMS preferita trovata. Usa il',
NO_DATA_2: 'modulo per marcarle.',
NO_DATA_3: 'Per vedere tutte le entità disponibili vai a',
THIS_VERSION: 'Questa versione',
PLATFORM: 'Piattaforma',
RELEASE_TYPE: 'Tipo di rilascio',
INTERNET_CONNECTION_REQUIRED: 'Connessione internet richiesta per il controllo automatico delle versioni e l\'aggiornamento',
SWITCH_RELEASE_TYPE: 'Cambia in {0} rilascio'
}; };
export default it; export default it;

View File

@@ -72,7 +72,7 @@ const nl: Translation = {
TX_ISSUES: 'Tx bus probleem. Probeer een andere Tx verzendmodus', TX_ISSUES: 'Tx bus probleem. Probeer een andere Tx verzendmodus',
DISCONNECTED: 'Niet verbonden', DISCONNECTED: 'Niet verbonden',
EMS_SCAN: 'Weet je zeker dat je een volledige EMS bus scan uit wilt voeren?', EMS_SCAN: 'Weet je zeker dat je een volledige EMS bus scan uit wilt voeren?',
DATA_TRAFFIC: 'Data Traffic', // TODO translate DATA_TRAFFIC: 'Dataverkeer',
EMS_DEVICE: 'EMS Apparaat', EMS_DEVICE: 'EMS Apparaat',
SUCCESS: 'SUCCESS', SUCCESS: 'SUCCESS',
FAIL: 'MISLUKT', FAIL: 'MISLUKT',
@@ -115,7 +115,7 @@ const nl: Translation = {
READONLY: 'Activeer read-only modus (blokkeert alle outgaande EMS Tx schrijf commandos)', READONLY: 'Activeer read-only modus (blokkeert alle outgaande EMS Tx schrijf commandos)',
UNDERCLOCK_CPU: 'Underclock CPU snelheid', UNDERCLOCK_CPU: 'Underclock CPU snelheid',
REMOTE_TIMEOUT: 'Remote timeout', REMOTE_TIMEOUT: 'Remote timeout',
REMOTE_TIMEOUT_EN: 'Disable remote on missing room temperature', // TODO translate REMOTE_TIMEOUT_EN: 'Schakel de afstandsbediening uit bij ontbrekende kamertemperatuur',
HEATINGOFF: 'Start ketel met geforceerde verwarming uit', HEATINGOFF: 'Start ketel met geforceerde verwarming uit',
MIN_DURATION: 'Wait time', MIN_DURATION: 'Wait time',
ENABLE_SHOWER_TIMER: 'Activeer Douche Timer (tijdmeting)', ENABLE_SHOWER_TIMER: 'Activeer Douche Timer (tijdmeting)',
@@ -174,7 +174,7 @@ const nl: Translation = {
FACTORY_RESET: 'Fabrieksinstellingen', FACTORY_RESET: 'Fabrieksinstellingen',
SYSTEM_FACTORY_TEXT: 'Gateway is gereset en start nu weer op met fabrieksinstellingen', SYSTEM_FACTORY_TEXT: 'Gateway is gereset en start nu weer op met fabrieksinstellingen',
SYSTEM_FACTORY_TEXT_DIALOG: 'Weet je zeker dat je een reset naar fabrieksinstellingen uit wilt voeren?', SYSTEM_FACTORY_TEXT_DIALOG: 'Weet je zeker dat je een reset naar fabrieksinstellingen uit wilt voeren?',
AVAILABLE_VERSION: 'Latest Available Versions', // TODO translate AVAILABLE_VERSION: 'Nieuwste beschikbare versies',
STABLE: 'Stable', STABLE: 'Stable',
DEVELOPMENT: 'Development', DEVELOPMENT: 'Development',
UPTIME: 'Systeem Uptime', UPTIME: 'Systeem Uptime',
@@ -185,9 +185,9 @@ const nl: Translation = {
FILESYSTEM: 'File System (Used / Free)', FILESYSTEM: 'File System (Used / Free)',
BUFFER_SIZE: 'Max Buffer Size', BUFFER_SIZE: 'Max Buffer Size',
COMPACT: 'Compact', COMPACT: 'Compact',
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate DOWNLOAD_SETTINGS_TEXT: 'Maak een back-up van uw configuratie en instellingen',
UPLOAD_TEXT: 'Upload a new firmware file (.bin) or a backup file (.json)', // TODO translate UPLOAD_TEXT: 'Upload een nieuw firmwarebestand (.bin) of een back-upbestand (.json)',
UPLOAD_DROP_TEXT: 'Sleep bestand hierheen of klik hier', UPLOAD_DROP_TEXT: 'Sleep en firmware .bin bestand hierheen of klik hier',
ERROR: 'Onverwachte fout, probeer opnieuw', ERROR: 'Onverwachte fout, probeer opnieuw',
TIME_SET: 'Tijd ingesteld', TIME_SET: 'Tijd ingesteld',
MANAGE_USERS: 'Beheer Gebruikers', MANAGE_USERS: 'Beheer Gebruikers',
@@ -273,7 +273,7 @@ const nl: Translation = {
NETWORK_SUBNET: 'Subnetmasker', NETWORK_SUBNET: 'Subnetmasker',
NETWORK_DNS: 'DNS Servers', NETWORK_DNS: 'DNS Servers',
ADDRESS_OF: '{0} Address', ADDRESS_OF: '{0} Address',
ADMINISTRATOR: 'Administrator', ADMINISTRATOR: 'Administrator',
GUEST: 'Gast', GUEST: 'Gast',
NEW: 'Nieuwe', NEW: 'Nieuwe',
NEW_NAME_OF: 'Hernoem {0}', NEW_NAME_OF: 'Hernoem {0}',
@@ -319,31 +319,39 @@ const nl: Translation = {
SECURITY_1: 'Gebruikers toevoegen of verwijderen', SECURITY_1: 'Gebruikers toevoegen of verwijderen',
DOWNLOAD_UPLOAD_1: 'Download en upload instellingen en firmware', DOWNLOAD_UPLOAD_1: 'Download en upload instellingen en firmware',
MODULES: 'Module', MODULES: 'Module',
MODULES_1: 'Externe modules activeren of deactiveren', // TODO translate MODULES_1: 'Externe modules activeren of deactiveren',
MODULES_UPDATED: 'Modules geüpdatet', MODULES_UPDATED: 'Modules geüpdatet',
MODULES_DESCRIPTION: 'Klik op de module om EMS-ESP library modules te activeren of te deactiveren', MODULES_DESCRIPTION: 'Klik op de module om EMS-ESP library modules te activeren of te deactiveren',
MODULES_NONE: 'Geen externe modules gedetecteerd', MODULES_NONE: 'Geen externe modules gedetecteerd',
RENAME: 'Hernoemen', RENAME: 'Hernoemen',
ENABLE_MODBUS: 'Activeer Modbus', ENABLE_MODBUS: 'Activeer Modbus',
VIEW_LOG: 'View log to diagnose issues', // TODO translate VIEW_LOG: 'Log weergeven om problemen te diagnosticeren',
UPLOAD_DRAG: 'drag and drop a file here or click to select one', // TODO translate UPLOAD_DRAG: 'sleep hier een bestand en zet het neer of klik om er een te selecteren',
SERVICES: 'Services', // TODO translate SERVICES: 'Services',
ALLVALUES: 'All Values', // TODO translate ALLVALUES: 'All waarden',
SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate SPECIAL_FUNCTIONS: 'Speciale functies',
WAIT_FIRMWARE: 'Firmware is uploading and installing', // TODO translate WAIT_FIRMWARE: 'Firmware wordt geüpload en geïnstalleerd',
INSTALL_VERSION: 'This will install version {0}. Are you sure?', // TODO translate INSTALL_VERSION: 'Hiermee wordt versie {1} {0}. Weet je het zeker?',
SWITCH_DEV: 'switch to the development version', // TODO translate UPDATE_AVAILABLE: 'update beschikbaar',
UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate LATEST_VERSION: 'U gebruikt de nieuwste {0} firmwareversie',
LATEST_VERSION: 'You are using the latest firmware version.', // TODO translate PLEASE_WAIT: 'Een ogenblik geduld',
PLEASE_WAIT: 'Please wait', // TODO translate RESTARTING_PRE: 'Initialiseren',
RESTARTING_PRE: 'Initializing', // TODO translate RESTARTING_POST: 'Voorbereiding',
RESTARTING_POST: 'Preparing', // TODO translate AUTO_SCROLL: 'Automatisch Scrollen',
AUTO_SCROLL: 'Auto Scroll', // TODO translate DASHBOARD: 'Dashboard',
DASHBOARD: 'Dashboard', // TODO translate DEVELOPER_MODE: 'Ontwikkelaarsmodus',
NO_DATA: 'No data available', // TODO translate BYTES: 'Bytes',
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate BITMASK: 'Bit Mask',
DEVELOPER_MODE: 'Developer Mode', // TODO translate DUPLICATE: 'Duplicaat',
UPGRADE: 'Upgrade' // TODO translate DASHBOARD_1: 'Alle EMS-entiteiten die actief zijn en als favoriet zijn gemarkeerd, plus alle aangepaste entiteiten en externe sensorgegevens worden hieronder weergegeven.',
NO_DATA_1: 'Er zijn nog geen favoriete EMS-entiteiten gevonden. Gebruik de',
NO_DATA_2: 'module om ze te markeren.',
NO_DATA_3: 'Om alle beschikbare entiteiten te zien, ga naar',
THIS_VERSION: 'Deze Versie',
PLATFORM: 'Platform',
RELEASE_TYPE: 'Release Typ',
INTERNET_CONNECTION_REQUIRED: 'Internetverbinding vereist voor automatische versiecontrole en -upgrade',
SWITCH_RELEASE_TYPE: 'Switch naar {0} release'
}; };
export default nl; export default nl;

View File

@@ -43,7 +43,7 @@ const no: Translation = {
RESET: 'Nullstill', RESET: 'Nullstill',
APPLY_CHANGES: 'Utfør endringer({0})', APPLY_CHANGES: 'Utfør endringer({0})',
UPDATE: 'Oppdater', UPDATE: 'Oppdater',
EXECUTE: 'Execute', // TODO translate EXECUTE: 'Utfør',
REMOVE: 'Fjern', REMOVE: 'Fjern',
PROBLEM_UPDATING: 'Problem med oppdatering', PROBLEM_UPDATING: 'Problem med oppdatering',
PROBLEM_LOADING: 'Problem med opplasting', PROBLEM_LOADING: 'Problem med opplasting',
@@ -72,7 +72,7 @@ const no: Translation = {
TX_ISSUES: 'Tx problemer - prøv en annen Tx Modus', TX_ISSUES: 'Tx problemer - prøv en annen Tx Modus',
DISCONNECTED: 'Frakoblet', DISCONNECTED: 'Frakoblet',
EMS_SCAN: 'Er du sikker på du vil starte full søking av EMS bussen?', EMS_SCAN: 'Er du sikker på du vil starte full søking av EMS bussen?',
DATA_TRAFFIC: 'Data Traffic', // TODO translate DATA_TRAFFIC: 'Data trafikk',
EMS_DEVICE: 'EMS Enhet', EMS_DEVICE: 'EMS Enhet',
SUCCESS: 'VELLYKKET', SUCCESS: 'VELLYKKET',
FAIL: 'MISLYKKET', FAIL: 'MISLYKKET',
@@ -115,9 +115,9 @@ const no: Translation = {
READONLY: 'Aktiver read-only modus (blokker all EMS Tx Skriving)', READONLY: 'Aktiver read-only modus (blokker all EMS Tx Skriving)',
UNDERCLOCK_CPU: 'Underklokking av prosessorhastighet', UNDERCLOCK_CPU: 'Underklokking av prosessorhastighet',
REMOTE_TIMEOUT: 'Remote timeout', REMOTE_TIMEOUT: 'Remote timeout',
REMOTE_TIMEOUT_EN: 'Disable remote control on missing room temperature', // TODO translate REMOTE_TIMEOUT_EN: 'Deaktiver fjernstyring på manglende romtemperatur',
HEATINGOFF: 'Start boiler with forced heating off', // TODO translate HEATINGOFF: 'Start kjele med tvingt oppvarming av',
MIN_DURATION: 'Wait time', MIN_DURATION: 'Ventetid',
ENABLE_SHOWER_TIMER: 'Aktiver Dusjtimer', ENABLE_SHOWER_TIMER: 'Aktiver Dusjtimer',
ENABLE_SHOWER_ALERT: 'Aktiver Dusj-varsling', ENABLE_SHOWER_ALERT: 'Aktiver Dusj-varsling',
TRIGGER_TIME: 'Aktiveringstid', TRIGGER_TIME: 'Aktiveringstid',
@@ -174,9 +174,9 @@ const no: Translation = {
FACTORY_RESET: 'Sett tilbake til fabrikkinstilling', FACTORY_RESET: 'Sett tilbake til fabrikkinstilling',
SYSTEM_FACTORY_TEXT: 'Enhet har blitt satt tilbake til fabrikkinstilling og vil restarte', SYSTEM_FACTORY_TEXT: 'Enhet har blitt satt tilbake til fabrikkinstilling og vil restarte',
SYSTEM_FACTORY_TEXT_DIALOG: 'Er du sikker på at du vil resette enheten til fabrikkinstillinger?', SYSTEM_FACTORY_TEXT_DIALOG: 'Er du sikker på at du vil resette enheten til fabrikkinstillinger?',
AVAILABLE_VERSION: 'Latest Available Versions', // TODO translate AVAILABLE_VERSION: 'Tilgjengelige versjoner',
STABLE: 'Stable', // TODO translate STABLE: 'Stabil',
DEVELOPMENT: 'Development', DEVELOPMENT: 'Utvikling',
UPTIME: 'System Oppetid', UPTIME: 'System Oppetid',
FREE_MEMORY: 'Ledig Memory', FREE_MEMORY: 'Ledig Memory',
PSRAM: 'PSRAM (Størrelse / Ledig)', PSRAM: 'PSRAM (Størrelse / Ledig)',
@@ -185,9 +185,9 @@ const no: Translation = {
FILESYSTEM: 'File System (Brukt / Ledig)', FILESYSTEM: 'File System (Brukt / Ledig)',
BUFFER_SIZE: 'Max Buffer Størrelse', BUFFER_SIZE: 'Max Buffer Størrelse',
COMPACT: 'Komprimere', COMPACT: 'Komprimere',
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate DOWNLOAD_SETTINGS_TEXT: 'Lag en sikkerhetskopi av dine konfigurasjon og innstillinger',
UPLOAD_TEXT: 'Upload a new firmware file (.bin) or a backup file (.json)', // TODO translate UPLOAD_TEXT: 'Last opp en ny firmware fil (.bin) eller en sikkerhetskopi fil (.json)',
UPLOAD_DROP_TEXT: 'Slipp fil eller klikk her', UPLOAD_DROP_TEXT: 'Dropp en firmware fil (.bin) eller klikk her',
ERROR: 'Ukjent feil, prøv igjen', ERROR: 'Ukjent feil, prøv igjen',
TIME_SET: 'Still in tid', TIME_SET: 'Still in tid',
MANAGE_USERS: 'Administrer Brukere', MANAGE_USERS: 'Administrer Brukere',
@@ -223,7 +223,7 @@ const no: Translation = {
MQTT_INT_THERMOSTATS: 'Termostat', MQTT_INT_THERMOSTATS: 'Termostat',
MQTT_INT_SOLAR: 'Solpaneler', MQTT_INT_SOLAR: 'Solpaneler',
MQTT_INT_MIXER: 'Blandeventil', MQTT_INT_MIXER: 'Blandeventil',
MQTT_INT_WATER: 'Water Modules', // TODO translate MQTT_INT_WATER: 'Vannmoduler',
MQTT_QUEUE: 'MQTT Queue', MQTT_QUEUE: 'MQTT Queue',
DEFAULT: 'Standard', DEFAULT: 'Standard',
MQTT_ENTITY_FORMAT: 'Enhets ID format', MQTT_ENTITY_FORMAT: 'Enhets ID format',
@@ -260,7 +260,7 @@ const no: Translation = {
NETWORK_SCANNER: 'Nettverk Scanner', NETWORK_SCANNER: 'Nettverk Scanner',
NETWORK_NO_WIFI: 'Ingen trådløse nett funnet', NETWORK_NO_WIFI: 'Ingen trådløse nett funnet',
NETWORK_BLANK_SSID: 'la feltet være blankt for å deaktivisere trådløst nettverk', NETWORK_BLANK_SSID: 'la feltet være blankt for å deaktivisere trådløst nettverk',
NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate NETWORK_BLANK_BSSID: 'la feltet være blankt for å bruke kun SSID',
TX_POWER: 'Tx Effekt', TX_POWER: 'Tx Effekt',
HOSTNAME: 'Hostname', HOSTNAME: 'Hostname',
NETWORK_DISABLE_SLEEP: 'Hindre at trådløst nettverk går i Sleep Mode', NETWORK_DISABLE_SLEEP: 'Hindre at trådløst nettverk går i Sleep Mode',
@@ -297,53 +297,61 @@ const no: Translation = {
SCHEDULE_TIMER_1: 'ved oppstart', SCHEDULE_TIMER_1: 'ved oppstart',
SCHEDULE_TIMER_2: 'hvert minutt', SCHEDULE_TIMER_2: 'hvert minutt',
SCHEDULE_TIMER_3: 'hver time', SCHEDULE_TIMER_3: 'hver time',
CUSTOM_ENTITIES: 'Custom Entities', // TODO translate CUSTOM_ENTITIES: 'Personlige entiteter',
ENTITIES_HELP_1: 'Fetch custom entities from the EMS bus', // TODO translate ENTITIES_HELP_1: 'Hent personlige entiteter fra EMS bussen',
ENTITIES_UPDATED: 'Entities Updated', // TODO translate ENTITIES_UPDATED: 'Entiteter oppdatert',
WRITEABLE: 'Writeable', // TODO translate WRITEABLE: 'Skrivbar',
SHOWING: 'Showing', // TODO translate SHOWING: 'Viser',
SEARCH: 'Search', // TODO translate SEARCH: 'Søk',
CERT: 'TLS root certificate (leave blank for insecure)', // TODO translate CERT: 'TLS rot sertifikat (la feltet stå blankt for usikkert)',
ENABLE_TLS: 'Aktiviser TLS', ENABLE_TLS: 'Aktiviser TLS',
ON: 'On', // TODO translate ON: '',
OFF: 'Off', // TODO translate OFF: 'Av',
POLARITY: 'Polarity', // TODO translate POLARITY: 'Polarity',
ACTIVEHIGH: 'Active High', // TODO translate ACTIVEHIGH: 'Active High',
ACTIVELOW: 'Active Low', // TODO translate ACTIVELOW: 'Active Low',
UNCHANGED: 'Unchanged', // TODO translate UNCHANGED: 'Unchanged',
ALWAYS: 'Always', // TODO translate ALWAYS: 'Always',
ACTIVITY: 'Activity', // TODO translate ACTIVITY: 'Aktivitet',
CONFIGURE: 'Configure {0}', // TODO translate CONFIGURE: 'Konfigurer {0}',
SYSTEM_MEMORY: 'System Memory', // TODO translate SYSTEM_MEMORY: 'System Memory',
APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings',
SECURITY_1: 'Add or remove users', // TODO translate SECURITY_1: 'Add or remove users',
DOWNLOAD_UPLOAD_1: 'Download and Upload Settings and Firmware', // TODO translate DOWNLOAD_UPLOAD_1: 'Download and Upload Settings and Firmware',
MODULES: 'Module', // TODO translate MODULES: 'Modul',
MODULES_1: 'Aktiver eller deaktiver eksterne moduler', MODULES_1: 'Aktiver eller deaktiver eksterne moduler',
MODULES_UPDATED: 'Modules updated', // TODO translate MODULES_UPDATED: 'Moduler oppdatert',
MODULES_DESCRIPTION: 'Click on the Module to activate or de-activate EMS-ESP library modules', // TODO translate MODULES_DESCRIPTION: 'Klikk på modulen for å aktivere eller deaktivere EMS-ESP biblioteksmoduler',
MODULES_NONE: 'No external modules detected', // TODO translate MODULES_NONE: 'Ingen eksterne moduler funnet',
RENAME: 'Rename', // TODO translate RENAME: 'Gi nytt navn',
ENABLE_MODBUS: 'Aktiver Modbus', ENABLE_MODBUS: 'Aktiver Modbus',
VIEW_LOG: 'View log to diagnose issues', // TODO translate VIEW_LOG: 'Se logg for å diagnostisere problemer',
UPLOAD_DRAG: 'drag and drop a file here or click to select one', // TODO translate UPLOAD_DRAG: 'dra og slippe en fil her eller klikk for å velge en',
SERVICES: 'Services', // TODO translate SERVICES: 'Tjenester',
ALLVALUES: 'All Values', // TODO translate ALLVALUES: 'Alle verdier',
SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate SPECIAL_FUNCTIONS: 'Spesielle funksjoner',
WAIT_FIRMWARE: 'Firmware is uploading and installing', // TODO translate WAIT_FIRMWARE: 'Firmware er i opplasting og installasjon',
INSTALL_VERSION: 'This will install version {0}. Are you sure?', // TODO translate INSTALL_VERSION: 'Dette vil {0} versjon {1}. Er du sikker?',
SWITCH_DEV: 'switch to the development version', // TODO translate UPDATE_AVAILABLE: 'oppdatering tilgjengelig',
UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate LATEST_VERSION: 'Du bruker den nyeste {0} firmware versjonen',
LATEST_VERSION: 'You are using the latest firmware version.', // TODO translate PLEASE_WAIT: 'Vennligst vent',
PLEASE_WAIT: 'Please wait', // TODO translate RESTARTING_PRE: 'Initialiserer',
RESTARTING_PRE: 'Initializing', // TODO translate RESTARTING_POST: 'Forbereder',
RESTARTING_POST: 'Preparing', // TODO translate AUTO_SCROLL: 'Automatisk rulling',
AUTO_SCROLL: 'Auto Scroll', // TODO translate DASHBOARD: 'Dashboard',
DASHBOARD: 'Dashboard', // TODO translate DEVELOPER_MODE: 'Utvikler modus',
NO_DATA: 'No data available', // TODO translate BYTES: 'Bytes',
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate BITMASK: 'Bitmask',
DEVELOPER_MODE: 'Developer Mode', // TODO translate DUPLICATE: 'Duplikat',
UPGRADE: 'Upgrade' // TODO translate DASHBOARD_1: 'Alle EMS enheter som er aktive og merket som favoritt, pluss alle personlige enheter, planlegg og eksterne sensor data er vist nedenfor.',
NO_DATA_1: 'Ingen favoritte EMS enheter funnet enda. Bruk',
NO_DATA_2: 'modul for å markere dem.',
NO_DATA_3: 'For å se alle tilgjengelige enheter, gå til',
THIS_VERSION: 'Denne versjonen',
PLATFORM: 'Plattform',
RELEASE_TYPE: 'Utgivelses type',
INTERNET_CONNECTION_REQUIRED: 'Internettilkobling kreves for automatisk versjonskontroll og oppgradering',
SWITCH_RELEASE_TYPE: 'Bytt til {0} utgivelse'
}; };
export default no; export default no;

View File

@@ -72,7 +72,7 @@ const pl: BaseTranslation = {
TX_ISSUES: 'problem z zapisem na magistralę EMS, spróbuj wybrać inny "Tryb transmisji (Tx)"', TX_ISSUES: 'problem z zapisem na magistralę EMS, spróbuj wybrać inny "Tryb transmisji (Tx)"',
DISCONNECTED: 'brak połączenia', DISCONNECTED: 'brak połączenia',
EMS_SCAN: 'Czy na pewno wykonać pełne skanowanie magistrali EMS?', EMS_SCAN: 'Czy na pewno wykonać pełne skanowanie magistrali EMS?',
DATA_TRAFFIC: 'Data Traffic', // TODO translate DATA_TRAFFIC: 'Ruch Danych',
EMS_DEVICE: 'Urządzenie EMS', EMS_DEVICE: 'Urządzenie EMS',
SUCCESS: 'Udane', SUCCESS: 'Udane',
FAIL: 'Nieudane', FAIL: 'Nieudane',
@@ -115,7 +115,7 @@ const pl: BaseTranslation = {
READONLY: 'Tryb pracy "tylko do odczytu" (blokuje wszystkie komendy zapisu na magistralę EMS)', READONLY: 'Tryb pracy "tylko do odczytu" (blokuje wszystkie komendy zapisu na magistralę EMS)',
UNDERCLOCK_CPU: 'Obniż taktowanie CPU', UNDERCLOCK_CPU: 'Obniż taktowanie CPU',
REMOTE_TIMEOUT: 'Remote timeout', REMOTE_TIMEOUT: 'Remote timeout',
REMOTE_TIMEOUT_EN: 'Disable remote control on missing room temperature', // TODO translate REMOTE_TIMEOUT_EN: 'Wyłącz kontrolę zdalną przy braku temperatury pomieszczenia',
HEATINGOFF: 'Uruchom kocioł z wymuszonym wyłączonym grzaniem', HEATINGOFF: 'Uruchom kocioł z wymuszonym wyłączonym grzaniem',
MIN_DURATION: 'Wait time', MIN_DURATION: 'Wait time',
ENABLE_SHOWER_TIMER: 'Aktywuj minutnik prysznica', ENABLE_SHOWER_TIMER: 'Aktywuj minutnik prysznica',
@@ -174,9 +174,9 @@ const pl: BaseTranslation = {
FACTORY_RESET: 'Ustawienia fabryczne', FACTORY_RESET: 'Ustawienia fabryczne',
SYSTEM_FACTORY_TEXT: 'Interfejs EMS-ESP został przywrócony do ustawień fabrycznych i zostanie teraz ponownie uruchomiony.', SYSTEM_FACTORY_TEXT: 'Interfejs EMS-ESP został przywrócony do ustawień fabrycznych i zostanie teraz ponownie uruchomiony.',
SYSTEM_FACTORY_TEXT_DIALOG: 'Na pewno chcesz przywrócić ustawienia fabryczne interfejsu EMS-ESP?', SYSTEM_FACTORY_TEXT_DIALOG: 'Na pewno chcesz przywrócić ustawienia fabryczne interfejsu EMS-ESP?',
AVAILABLE_VERSION: 'Latest Available Versions', // TODO translate AVAILABLE_VERSION: 'Najnowsze dostępne wersje',
STABLE: 'Stable', // TODO translate STABLE: 'Stabilna',
DEVELOPMENT: 'Testowe', DEVELOPMENT: 'Testowa',
UPTIME: 'Czas działania systemu', UPTIME: 'Czas działania systemu',
FREE_MEMORY: 'Wolne Memory', FREE_MEMORY: 'Wolne Memory',
PSRAM: 'PSRAM (rozmiar / wolne)', PSRAM: 'PSRAM (rozmiar / wolne)',
@@ -185,9 +185,9 @@ const pl: BaseTranslation = {
FILESYSTEM: 'System plików (wykorzystane / wolne)', FILESYSTEM: 'System plików (wykorzystane / wolne)',
BUFFER_SIZE: 'Maksymalna pojemność bufora (ilość wpisów)', BUFFER_SIZE: 'Maksymalna pojemność bufora (ilość wpisów)',
COMPACT: 'Kompaktowy', COMPACT: 'Kompaktowy',
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate DOWNLOAD_SETTINGS_TEXT: 'Utwórz kopię swoich ustawień i konfiguracji',
UPLOAD_TEXT: 'Upload a new firmware file (.bin) or a backup file (.json)', // TODO translate UPLOAD_TEXT: 'Wgraj nowy plik firmware (.bin) lub kopię ustawień (.json)',
UPLOAD_DROP_TEXT: 'Przeciągnij tutaj plik lub kliknij', UPLOAD_DROP_TEXT: 'Upuść plik firmware .bin lub kliknij tutaj',
ERROR: 'Nieoczekiwany błąd, spróbuj ponownie!', ERROR: 'Nieoczekiwany błąd, spróbuj ponownie!',
TIME_SET: 'Zegar został ustawiony.', TIME_SET: 'Zegar został ustawiony.',
MANAGE_USERS: 'Zarządzanie użytkownikami', MANAGE_USERS: 'Zarządzanie użytkownikami',
@@ -318,32 +318,40 @@ const pl: BaseTranslation = {
APPLICATION_SETTINGS_1: 'Modyfikacja ustawień aplikacji EMS-ESP', APPLICATION_SETTINGS_1: 'Modyfikacja ustawień aplikacji EMS-ESP',
SECURITY_1: 'Dodawanie i usuwanie użytkowników', SECURITY_1: 'Dodawanie i usuwanie użytkowników',
DOWNLOAD_UPLOAD_1: 'Pobieranie/wysyłanie ustawień i firmware', DOWNLOAD_UPLOAD_1: 'Pobieranie/wysyłanie ustawień i firmware',
MODULES: 'Module', // TODO translate MODULES: 'Moduł',
MODULES_1: 'Aktywuj lub dezaktywuj moduły zewnętrzne', MODULES_1: 'Aktywuj lub dezaktywuj moduły zewnętrzne',
MODULES_UPDATED: 'Modules updated', // TODO translate MODULES_UPDATED: 'Zaktualizowano moduły',
MODULES_DESCRIPTION: 'Click on the Module to activate or de-activate EMS-ESP library modules', // TODO translate MODULES_DESCRIPTION: 'Kliknij na moduł aby aktywować lub dezaktywować bibliotekę modułów EMS-ESP',
MODULES_NONE: 'No external modules detected', // TODO translate MODULES_NONE: 'Brak wykrytych modułów zewnętrznych',
RENAME: 'Rename', // TODO translate RENAME: 'Zmień nazwę',
ENABLE_MODBUS: 'Aktywuj Modbus', ENABLE_MODBUS: 'Aktywuj Modbus',
VIEW_LOG: 'View log to diagnose issues', // TODO translate VIEW_LOG: 'Zdiagnozuj problemy',
UPLOAD_DRAG: 'drag and drop a file here or click to select one', // TODO translate UPLOAD_DRAG: 'przeciągnij i upuść plik lub kliknij tutaj',
SERVICES: 'Services', // TODO translate SERVICES: 'Usługi',
ALLVALUES: 'All Values', // TODO translate ALLVALUES: 'Wszystkie wartości',
SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate SPECIAL_FUNCTIONS: 'Specjalne funkcje',
WAIT_FIRMWARE: 'Firmware is uploading and installing', // TODO translate WAIT_FIRMWARE: 'Firma jest wysyłana i instaluje się',
INSTALL_VERSION: 'This will install version {0}. Are you sure?', // TODO translate INSTALL_VERSION: 'To zainstaluje wersję {1} {0}. Jesteś pewny?',
SWITCH_DEV: 'switch to the development version', // TODO translate UPDATE_AVAILABLE: 'aktualizacja dostępna',
UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate LATEST_VERSION: 'Jesteś używając najnowszej wersji firmware {0}',
LATEST_VERSION: 'You are using the latest firmware version.', // TODO translate PLEASE_WAIT: 'Proszę czekać',
PLEASE_WAIT: 'Please wait', // TODO translate RESTARTING_PRE: 'Inicjalizacja',
RESTARTING_PRE: 'Initializing', // TODO translate RESTARTING_POST: 'Przygotowanie',
RESTARTING_POST: 'Preparing', // TODO translate AUTO_SCROLL: 'Auto Scroll',
AUTO_SCROLL: 'Auto Scroll', // TODO translate DASHBOARD: 'Pulpit',
DASHBOARD: 'Dashboard', // TODO translate DEVELOPER_MODE: 'Tryb programisty',
NO_DATA: 'No data available', // TODO translate BYTES: 'Bajty',
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate BITMASK: 'Bit Mask',
DEVELOPER_MODE: 'Developer Mode', // TODO translate DUPLICATE: 'Duplicate',
UPGRADE: 'Upgrade' // TODO translate DASHBOARD_1: 'All EMS entities that are active and marked as Favorite, plus all Custom Entities, Schedules and external Sensors data are displayed below.',
NO_DATA_1: 'Brak ulubionych encji EMS. Użyj',
NO_DATA_2: 'moduł do ich oznaczenia.',
NO_DATA_3: 'Aby zobaczyć wszystkie dostępne encje przejdź do',
THIS_VERSION: 'Ta wersja',
PLATFORM: 'Platforma',
RELEASE_TYPE: 'Typ wydania',
INTERNET_CONNECTION_REQUIRED: 'Połączenie internetowe jest wymagane do automatycznej kontroli wersji i aktualizacji',
SWITCH_RELEASE_TYPE: 'Zmień na {0} wydanie'
}; };
export default pl; export default pl;

View File

@@ -57,7 +57,7 @@ const sk: Translation = {
OFFSET: 'Ofset', OFFSET: 'Ofset',
FACTOR: 'Faktor', FACTOR: 'Faktor',
FREQ: 'Frekvencia', FREQ: 'Frekvencia',
DUTY_CYCLE: 'Duty Cycle', DUTY_CYCLE: 'Pracovný cyklus',
UNIT: 'UoM', UNIT: 'UoM',
STARTVALUE: 'Počiatočná hodnota', STARTVALUE: 'Počiatočná hodnota',
WARN_GPIO: 'Upozornenie: Buďte opatrní pri priraďovaní GPIO!', WARN_GPIO: 'Upozornenie: Buďte opatrní pri priraďovaní GPIO!',
@@ -75,7 +75,7 @@ const sk: Translation = {
DATA_TRAFFIC: 'Dátová prevádzka', DATA_TRAFFIC: 'Dátová prevádzka',
EMS_DEVICE: 'EMS zariadenie', EMS_DEVICE: 'EMS zariadenie',
SUCCESS: 'ÚSPEŠNÉ', SUCCESS: 'ÚSPEŠNÉ',
FAIL: 'ZLÝHANIE', FAIL: 'ZLYHANIE',
QUALITY: 'KVALITA', QUALITY: 'KVALITA',
SCAN: 'Scan', SCAN: 'Scan',
STATUS_NAMES: [ STATUS_NAMES: [
@@ -114,10 +114,10 @@ const sk: Translation = {
BYPASS_TOKEN: 'Vynechajte autorizáciu prístupového tokenu pri volaniach API', BYPASS_TOKEN: 'Vynechajte autorizáciu prístupového tokenu pri volaniach API',
READONLY: 'Povoliť režim len na čítanie (blokuje všetky odchádzajúce príkazy EMS Tx Write)', READONLY: 'Povoliť režim len na čítanie (blokuje všetky odchádzajúce príkazy EMS Tx Write)',
UNDERCLOCK_CPU: 'Podtaktovanie rýchlosti procesora', UNDERCLOCK_CPU: 'Podtaktovanie rýchlosti procesora',
REMOTE_TIMEOUT: 'Remote timeout', REMOTE_TIMEOUT: 'Vzdialený časový limit',
REMOTE_TIMEOUT_EN: 'Disable remote on missing room temperature', // TODO translate REMOTE_TIMEOUT_EN: 'Deaktivujte diaľkové ovládanie pri chýbajúcej teplote v miestnosti',
HEATINGOFF: 'Spustiť kotol s vynúteným vykurovaním', HEATINGOFF: 'Spustiť kotol s vynúteným vykurovaním',
MIN_DURATION: 'Wait time', MIN_DURATION: 'Čakacia doba',
ENABLE_SHOWER_TIMER: 'Povoliť časovač sprchovania', ENABLE_SHOWER_TIMER: 'Povoliť časovač sprchovania',
ENABLE_SHOWER_ALERT: 'Povoliť upozornenie na sprchu', ENABLE_SHOWER_ALERT: 'Povoliť upozornenie na sprchu',
TRIGGER_TIME: 'Čas spustenia', TRIGGER_TIME: 'Čas spustenia',
@@ -127,7 +127,7 @@ const sk: Translation = {
BOOLEAN_FORMAT_API: 'Boolean formát API/MQTT', BOOLEAN_FORMAT_API: 'Boolean formát API/MQTT',
ENUM_FORMAT: 'Enum formát API/MQTT', ENUM_FORMAT: 'Enum formát API/MQTT',
INDEX: 'Index', INDEX: 'Index',
ENABLE_PARASITE: 'Povoliť 1-wire parazité napájanie DS18B20', ENABLE_PARASITE: 'Povoliť 1-wire parazitné napájanie DS18B20',
LOGGING: 'Logovanie', LOGGING: 'Logovanie',
LOG_HEX: 'Záznam telegramov EMS v hexadecimálnej sústave', LOG_HEX: 'Záznam telegramov EMS v hexadecimálnej sústave',
ENABLE_SYSLOG: 'Povoliť Syslog', ENABLE_SYSLOG: 'Povoliť Syslog',
@@ -155,7 +155,7 @@ const sk: Translation = {
NAME: 'Názov', NAME: 'Názov',
CUSTOMIZATIONS_RESET: 'Naozaj chcete odstrániť všetky prispôsobenia vrátane vlastných nastavení snímačov teploty a analógových snímačov?', CUSTOMIZATIONS_RESET: 'Naozaj chcete odstrániť všetky prispôsobenia vrátane vlastných nastavení snímačov teploty a analógových snímačov?',
SUPPORT_INFORMATION: 'Informácie pre podporu', SUPPORT_INFORMATION: 'Informácie pre podporu',
HELP_INFORMATION_1: 'Navštívte online wiki, kde nájdete pokyny na konfiguráciu EMS-ESP', HELP_INFORMATION_1: 'Navštívte online wiki, kde nájdete pokyny na konfiguráciu EMS-ESP',
HELP_INFORMATION_2: 'Pre živý komunitný chat sa pripojte na náš Discord server', HELP_INFORMATION_2: 'Pre živý komunitný chat sa pripojte na náš Discord server',
HELP_INFORMATION_3: 'Ak chcete požiadať o funkciu alebo nahlásiť chybu', HELP_INFORMATION_3: 'Ak chcete požiadať o funkciu alebo nahlásiť chybu',
HELP_INFORMATION_4: 'nezabudnite si stiahnuť a pripojiť informácie o vašom systéme, aby ste mohli rýchlejšie reagovať pri nahlasovaní problému', HELP_INFORMATION_4: 'nezabudnite si stiahnuť a pripojiť informácie o vašom systéme, aby ste mohli rýchlejšie reagovať pri nahlasovaní problému',
@@ -174,20 +174,20 @@ const sk: Translation = {
FACTORY_RESET: 'Továrenské nastavenia', FACTORY_RESET: 'Továrenské nastavenia',
SYSTEM_FACTORY_TEXT: 'Zariadenie bolo obnovené z výroby a teraz sa reštartuje', SYSTEM_FACTORY_TEXT: 'Zariadenie bolo obnovené z výroby a teraz sa reštartuje',
SYSTEM_FACTORY_TEXT_DIALOG: 'Naozaj chcete resetovať EMS-ESP na predvolené výrobné nastavenia?', SYSTEM_FACTORY_TEXT_DIALOG: 'Naozaj chcete resetovať EMS-ESP na predvolené výrobné nastavenia?',
AVAILABLE_VERSION: 'Latest Available Versions', // TODO translate AVAILABLE_VERSION: 'Najnovšie dostupné verzie',
STABLE: 'Stabilná', STABLE: 'Stabilná',
DEVELOPMENT: 'Vývojárska', DEVELOPMENT: 'Vývojárska',
UPTIME: 'Beh systému', UPTIME: 'Beh systému',
FREE_MEMORY: 'Voľné Memory', FREE_MEMORY: 'Voľná pamäť',
PSRAM: 'PSRAM (Veľkosť / Voľné)', PSRAM: 'PSRAM (Veľkosť / Voľné)',
FLASH: 'Flash chip (Veľkosť , Rýchlosť)', FLASH: 'Flash chip (Veľkosť , Rýchlosť)',
APPSIZE: 'Applikácia (Oddiel: Použité / Voľné)', APPSIZE: 'Aplikácia (Oddiel: Použité / Voľné)',
FILESYSTEM: 'Súborový systém (Použité / Voľné)', FILESYSTEM: 'Súborový systém (Použité / Voľné)',
BUFFER_SIZE: 'Buffer-max.veľkosť', BUFFER_SIZE: 'Buffer-max. veľkosť',
COMPACT: 'Kompaktné', COMPACT: 'Kompaktné',
DOWNLOAD_SETTINGS_TEXT: 'Vytvorte zálohu svojej konfigurácie a nastavení', DOWNLOAD_SETTINGS_TEXT: 'Vytvorte zálohu svojej konfigurácie a nastavení',
UPLOAD_TEXT: 'Nahrajte nový súbor firmvéru (.bin) alebo súbor zálohy (.json)', UPLOAD_TEXT: 'Nahrajte nový súbor firmvéru (.bin) alebo súbor zálohy (.json)',
UPLOAD_DROP_TEXT: 'Potiahnúť a pripnúť súbor alebo kliknúť sem', UPLOAD_DROP_TEXT: 'Presuňte súbor .bin firmvéru alebo kliknite sem',
ERROR: 'Neočakávaná chyba, prosím skúste to znova', ERROR: 'Neočakávaná chyba, prosím skúste to znova',
TIME_SET: 'Nastavený čas', TIME_SET: 'Nastavený čas',
MANAGE_USERS: 'Správa používateľov', MANAGE_USERS: 'Správa používateľov',
@@ -313,17 +313,17 @@ const sk: Translation = {
UNCHANGED: 'Nezmenené', UNCHANGED: 'Nezmenené',
ALWAYS: 'Vždy', ALWAYS: 'Vždy',
ACTIVITY: 'Aktivita', ACTIVITY: 'Aktivita',
CONFIGURE: 'Konfiguracia {0}', CONFIGURE: 'Konfigurácia {0}',
SYSTEM_MEMORY: 'Systémová pamäť', SYSTEM_MEMORY: 'Systémová pamäť',
APPLICATION_SETTINGS_1: 'Zmeniť nastavenia aplikácie EMS-ESP', APPLICATION_SETTINGS_1: 'Zmeniť nastavenia aplikácie EMS-ESP',
SECURITY_1: 'Pridať, alebo odstrániť použivateľov', SECURITY_1: 'Pridať, alebo odstrániť používateľov',
DOWNLOAD_UPLOAD_1: 'Stiahnúť a nahrať nastavenia a firmware', DOWNLOAD_UPLOAD_1: 'Stiahnuť a nahrať nastavenia a firmware',
MODULES: 'Moduly', MODULES: 'Moduly',
MODULES_1: 'Aktivujte alebo deaktivujte externé moduly', MODULES_1: 'Aktivujte alebo deaktivujte externé moduly',
MODULES_UPDATED: 'Aktualizované moduly', MODULES_UPDATED: 'Aktualizované moduly',
MODULES_DESCRIPTION: 'Kliknutím na modul aktivujete alebo deaktivujete moduly knižnice EMS-ESP', MODULES_DESCRIPTION: 'Kliknutím na modul aktivujete alebo deaktivujete moduly knižnice EMS-ESP',
MODULES_NONE: 'Neboli zistené žiadne externé moduly', MODULES_NONE: 'Neboli zistené žiadne externé moduly',
RENAME: 'Premenovať', RENAME: 'Premenovať',
ENABLE_MODBUS: 'Povoliť Modbus', ENABLE_MODBUS: 'Povoliť Modbus',
VIEW_LOG: 'Zobrazte log na diagnostiku problémov', VIEW_LOG: 'Zobrazte log na diagnostiku problémov',
UPLOAD_DRAG: 'presuňte sem súbor alebo ho kliknutím vyberte', UPLOAD_DRAG: 'presuňte sem súbor alebo ho kliknutím vyberte',
@@ -331,19 +331,27 @@ const sk: Translation = {
ALLVALUES: 'Všetky hodnoty', ALLVALUES: 'Všetky hodnoty',
SPECIAL_FUNCTIONS: 'Špeciálne funkcie', SPECIAL_FUNCTIONS: 'Špeciálne funkcie',
WAIT_FIRMWARE: 'Firmvér sa nahráva a inštaluje', WAIT_FIRMWARE: 'Firmvér sa nahráva a inštaluje',
INSTALL_VERSION: 'Týmto sa inštalovať verzia {0}. Si si istý?', INSTALL_VERSION: 'Týmto sa {0} verzia {1}. Si si istý?',
SWITCH_DEV: 'prejsť na vývojovú verziu', UPDATE_AVAILABLE: 'dostupná aktualizácia',
UPGRADE_AVAILABLE: 'K dispozícii je aktualizácia firmvéru!', LATEST_VERSION: 'Používate poslednú {0} verziu firmvéru',
LATEST_VERSION: 'Používate poslednú verziu firmvéru.',
PLEASE_WAIT: 'Čakajte prosím', PLEASE_WAIT: 'Čakajte prosím',
RESTARTING_PRE: 'Prebieha inicializácia', RESTARTING_PRE: 'Prebieha inicializácia',
RESTARTING_POST: 'Príprava', RESTARTING_POST: 'Príprava',
AUTO_SCROLL: 'Automatické rolovanie', AUTO_SCROLL: 'Automatické rolovanie',
DASHBOARD: 'Panel', DASHBOARD: 'Panel',
NO_DATA: 'Nie sú k dispozícii žiadne údaje', DEVELOPER_MODE: 'Režim vývojára',
DASHBOARD_1: 'Prispôsobte si svoj informačný panel tak, že označíte entity EMS ako Obľúbené pomocou modulu Prispôsobenia', BYTES: 'Bytov',
DEVELOPER_MODE: 'Developer Mode', // TODO translate BITMASK: 'Bitová maska',
UPGRADE: 'Upgrade' // TODO translate DUPLICATE: 'Duplicitné',
DASHBOARD_1: 'Všetky entity EMS, ktoré sú aktívne a označené ako obľúbené, plus všetky vlastné entity, plány a údaje externých senzorov sú zobrazené nižšie.',
NO_DATA_1: 'Nenašli sa žiadne obľúbené entity EMS. Použite',
NO_DATA_2: 'modul na ich označenie.',
NO_DATA_3: 'Ak chcete zobraziť všetky dostupné entity, prejdite na',
THIS_VERSION: 'Táto verzia',
PLATFORM: 'Platforma',
RELEASE_TYPE: 'Typ vydania',
INTERNET_CONNECTION_REQUIRED: 'Internetové pripojenie je potrebné pre automatickú kontrolu a aktualizáciu',
SWITCH_RELEASE_TYPE: 'Prepnúť na {0} verziu'
}; };
export default sk; export default sk;

View File

@@ -5,8 +5,8 @@ const sv: Translation = {
RETRY: 'Försök igen', RETRY: 'Försök igen',
LOADING: 'Laddar', LOADING: 'Laddar',
IS_REQUIRED: '{0} Krävs', IS_REQUIRED: '{0} Krävs',
SIGN_IN: 'Logga In', SIGN_IN: 'Logga in',
SIGN_OUT: 'Logga Ut', SIGN_OUT: 'Logga ut',
USERNAME: 'Användarnamn', USERNAME: 'Användarnamn',
PASSWORD: 'Lösenord', PASSWORD: 'Lösenord',
SU_PASSWORD: 'su Lösenord', SU_PASSWORD: 'su Lösenord',
@@ -29,7 +29,7 @@ const sv: Translation = {
FAVORITES: "Favoriter", FAVORITES: "Favoriter",
DEVICE_DETAILS: 'Enhetsdetaljer', DEVICE_DETAILS: 'Enhetsdetaljer',
ID_OF: '{0}-ID', ID_OF: '{0}-ID',
DEVICE: 'Enhets', DEVICE: 'Enhet',
PRODUCT: 'Produkt', PRODUCT: 'Produkt',
VERSION: 'Version', VERSION: 'Version',
BRAND: 'Fabrikat', BRAND: 'Fabrikat',
@@ -37,28 +37,28 @@ const sv: Translation = {
VALUE: '{{värde|Värde}}', VALUE: '{{värde|Värde}}',
DEVICES: 'Enheter', DEVICES: 'Enheter',
SENSORS: 'Sensorer', SENSORS: 'Sensorer',
RUN_COMMAND: 'Kör Kommando', RUN_COMMAND: 'Kör kommando',
CHANGE_VALUE: 'Ändra Värde', CHANGE_VALUE: 'Ändra värde',
CANCEL: 'Avbryt', CANCEL: 'Avbryt',
RESET: 'Nollställ', RESET: 'Nollställ',
APPLY_CHANGES: 'Apply Changes ({0})', // TODO translate APPLY_CHANGES: 'Utför ändringar ({0})',
UPDATE: 'Update', // TODO translate UPDATE: 'Uppdatera',
EXECUTE: 'Execute', // TODO translate EXECUTE: 'Utför',
REMOVE: 'Ta bort', REMOVE: 'Ta bort',
PROBLEM_UPDATING: 'Problem vid uppdatering', PROBLEM_UPDATING: 'Problem vid uppdatering',
PROBLEM_LOADING: 'Problem vid hämtning', PROBLEM_LOADING: 'Problem vid hämtning',
ANALOG_SENSOR: 'Analog Sensor', ANALOG_SENSOR: 'analog sensor',
ANALOG_SENSORS: 'Analoga Sensorer', ANALOG_SENSORS: 'Analoga sensorer',
SETTINGS: 'Inställningar', SETTINGS: 'Inställningar',
UPDATED_OF: '{0} Uppdaterad', UPDATED_OF: '{0} Uppdaterad',
UPDATE_OF: '{0} Uppdatera', UPDATE_OF: '{0} Uppdatera',
REMOVED_OF: '{0} Raderad', REMOVED_OF: '{0} Raderad',
DELETION_OF: '{0} Radering', DELETION_OF: '{0} Radering',
OFFSET: 'Kompensering', OFFSET: 'Offset',
FACTOR: 'Faktor', FACTOR: 'Faktor',
FREQ: 'Frekvens', FREQ: 'Frekvens',
DUTY_CYCLE: 'Duty Cycle', DUTY_CYCLE: 'Pulskvot',
UNIT: 'UoM', UNIT: 'Måttenhet',
STARTVALUE: 'Startvärde', STARTVALUE: 'Startvärde',
WARN_GPIO: 'Varning: Var försiktig vid aktivering av GPIO!', WARN_GPIO: 'Varning: Var försiktig vid aktivering av GPIO!',
EDIT: 'Ändra', EDIT: 'Ändra',
@@ -71,9 +71,9 @@ const sv: Translation = {
CONNECTED: 'Ansluten', CONNECTED: 'Ansluten',
TX_ISSUES: 'Sändfel - Prova ett annat TX-läge', TX_ISSUES: 'Sändfel - Prova ett annat TX-läge',
DISCONNECTED: 'Nedkopplad', DISCONNECTED: 'Nedkopplad',
EMS_SCAN: 'Är du säker att du vill initiera en full genomsökning av EMS-bussen?', EMS_SCAN: 'Är du säker att du vill starta en full genomsökning av EMS-bussen?',
DATA_TRAFFIC: 'Data Traffic', // TODO translate DATA_TRAFFIC: 'Datatrafik',
EMS_DEVICE: 'EMS Enhet', EMS_DEVICE: 'EMS enhet',
SUCCESS: 'Lyckades', SUCCESS: 'Lyckades',
FAIL: 'Misslyckades', FAIL: 'Misslyckades',
QUALITY: 'Kvalitet', QUALITY: 'Kvalitet',
@@ -92,8 +92,8 @@ const sv: Translation = {
NUM_SECONDS: '{num} sekund{{er}}', NUM_SECONDS: '{num} sekund{{er}}',
NUM_HOURS: '{num} timmar', NUM_HOURS: '{num} timmar',
NUM_MINUTES: '{num} minut{{er}}', NUM_MINUTES: '{num} minut{{er}}',
APPLICATION: 'Apliká', APPLICATION: 'Applikation',
CUSTOMIZATIONS: 'Anpassningr', CUSTOMIZATIONS: 'Anpassningar',
APPLICATION_RESTARTING: 'EMS-ESP startar om', APPLICATION_RESTARTING: 'EMS-ESP startar om',
BOARD_PROFILE: 'Hårdvarutyp', BOARD_PROFILE: 'Hårdvarutyp',
CUSTOM: 'Anpassa', CUSTOM: 'Anpassa',
@@ -105,34 +105,34 @@ const sv: Translation = {
TX_MODE: 'EMS Tx-läge', TX_MODE: 'EMS Tx-läge',
HARDWARE: 'Hårdvara', HARDWARE: 'Hårdvara',
EMS_BUS: '{{BUSS|EMS-BUSS}}', EMS_BUS: '{{BUSS|EMS-BUSS}}',
GENERAL_OPTIONS: 'Allmänna Inställningar', GENERAL_OPTIONS: 'Allmänna inställningar',
LANGUAGE_ENTITIES: 'Språk (för entiteter)', LANGUAGE_ENTITIES: 'Språk (för entiteter)',
HIDE_LED: 'Inaktivera LED', HIDE_LED: 'Inaktivera LED',
ENABLE_TELNET: 'Aktivera Telnet', ENABLE_TELNET: 'Aktivera Telnet',
ENABLE_ANALOG: 'Aktivera Analoga Sensorer', ENABLE_ANALOG: 'Aktivera Analoga Sensorer',
CONVERT_FAHRENHEIT: 'Konvertera temperaturer till Fahrenheit', CONVERT_FAHRENHEIT: 'Konvertera temperaturer till Fahrenheit',
BYPASS_TOKEN: 'Inaktivera Token-autensiering för API-anrop', BYPASS_TOKEN: 'Inaktivera Token-autentisiering för API-anrop',
READONLY: 'Aktivera read-only (blockerar alla utgående skrivkommandon mot EMS-bussen)', READONLY: 'Aktivera skrivskydd (blockerar alla utgående skrivkommandon mot EMS-bussen)',
UNDERCLOCK_CPU: 'Nedklocka Processorhastighet', UNDERCLOCK_CPU: 'Nedklocka Processorhastighet',
REMOTE_TIMEOUT: 'Remote timeout', REMOTE_TIMEOUT: 'Remote timeout',
REMOTE_TIMEOUT_EN: 'Disable remote on missing room temperature', // TODO translate REMOTE_TIMEOUT_EN: 'Deaktivera remote vid missad rumstemperatur',
HEATINGOFF: 'Start boiler with forced heating off', // TODO translate HEATINGOFF: 'Starta värmepump/panna med forcerad värme avstängd',
MIN_DURATION: 'Wait time', MIN_DURATION: 'Väntetid',
ENABLE_SHOWER_TIMER: 'Aktivera Dusch-timer', ENABLE_SHOWER_TIMER: 'Aktivera Dusch-timer',
ENABLE_SHOWER_ALERT: 'Aktivera Dusch-varning', ENABLE_SHOWER_ALERT: 'Aktivera Dusch-varning',
TRIGGER_TIME: 'Aktiveringstid', TRIGGER_TIME: 'Aktiveringstid',
COLD_SHOT_DURATION: 'Längd på kalldusch', COLD_SHOT_DURATION: 'Längd på kalldusch',
FORMATTING_OPTIONS: 'Formatteringsalternativ', FORMATTING_OPTIONS: 'Formateringsalternativ',
BOOLEAN_FORMAT_DASHBOARD: 'Bool-format Kontrollpanel', BOOLEAN_FORMAT_DASHBOARD: 'Bool-format Kontrollpanel',
BOOLEAN_FORMAT_API: 'Bool-format API/MQTT', BOOLEAN_FORMAT_API: 'Bool-format API/MQTT',
ENUM_FORMAT: 'Enum-format API/MQTT', ENUM_FORMAT: 'Enum-format API/MQTT',
INDEX: 'Index', INDEX: 'Index',
ENABLE_PARASITE: 'Aktivera 1-wire parasitström', ENABLE_PARASITE: 'Aktivera 1-wire parasitström',
LOGGING: 'Loggning', LOGGING: 'Loggning',
LOG_HEX: 'Logga EMS-telegram i hexadecimal', LOG_HEX: 'Logga EMS-telegram i hexadecimalformat',
ENABLE_SYSLOG: 'Aktivera Syslog', ENABLE_SYSLOG: 'Aktivera Syslog',
LOG_LEVEL: 'Loggnivå', LOG_LEVEL: 'Loggnivå',
MARK_INTERVAL: 'Markerings-interval', MARK_INTERVAL: 'Markeringsintervall',
SECONDS: 'sekunder', SECONDS: 'sekunder',
MINUTES: 'minuter', MINUTES: 'minuter',
HOURS: 'timmar', HOURS: 'timmar',
@@ -140,25 +140,25 @@ const sv: Translation = {
RESTART_TEXT: 'EMS-ESP kräver en omstart för att applicera förändrade systeminställningar', RESTART_TEXT: 'EMS-ESP kräver en omstart för att applicera förändrade systeminställningar',
RESTART_CONFIRM: 'Är du säker på att du vill starta om EMS-ESP?', RESTART_CONFIRM: 'Är du säker på att du vill starta om EMS-ESP?',
COMMAND: 'Kommando', COMMAND: 'Kommando',
CUSTOMIZATIONS_RESTART: 'Alla anpassningr har raderats. Startar om...', CUSTOMIZATIONS_RESTART: 'Alla anpassningar har raderats. Startar om...',
CUSTOMIZATIONS_FULL: 'Antal valda enheter för högt. Vänligen spara i mindre antal åt gången.', CUSTOMIZATIONS_FULL: 'För många valda enheter. Vänligen spara ett mindre antal åt gången.',
CUSTOMIZATIONS_SAVED: 'Anpassningar sparade', CUSTOMIZATIONS_SAVED: 'Anpassningarna är sparade',
CUSTOMIZATIONS_HELP_1: 'Välj en enhet och anpassa underenheter med hjälp av alternativen', CUSTOMIZATIONS_HELP_1: 'Välj en enhet och anpassa entiteter med hjälp av alternativen',
CUSTOMIZATIONS_HELP_2: 'Favorit', CUSTOMIZATIONS_HELP_2: 'Favorit',
CUSTOMIZATIONS_HELP_3: 'Inaktivera skrivningar', CUSTOMIZATIONS_HELP_3: 'Skrivskyddad',
CUSTOMIZATIONS_HELP_4: 'Exkludera från MQTT & API', CUSTOMIZATIONS_HELP_4: 'Exkludera från MQTT & API',
CUSTOMIZATIONS_HELP_5: 'dölj från enheter', CUSTOMIZATIONS_HELP_5: 'Dölj under Enheter',
CUSTOMIZATIONS_HELP_6: 'remove from memory', CUSTOMIZATIONS_HELP_6: 'Ta bort',
SELECT_DEVICE: 'Välj en enhet', SELECT_DEVICE: 'Välj en enhet',
SET_ALL: 'ställ in alla', SET_ALL: 'ställ in alla',
OPTIONS: 'Alternativ', OPTIONS: 'Alternativ',
NAME: 'Namn', NAME: 'Namn',
CUSTOMIZATIONS_RESET: 'Är du säker på att du vill ta bort alla anpassningar inklusive inställningar för Temperatur och Analoga sensorer?', CUSTOMIZATIONS_RESET: 'Är du säker på att du vill ta bort alla anpassningar, inklusive inställningar för Temperatursensorer och Analoga sensorer?',
SUPPORT_INFORMATION: 'Supportinformation', SUPPORT_INFORMATION: 'Supportinformation',
HELP_INFORMATION_1: 'Besök Wikin för instruktioner för hur du kan konfigurera EMS-ESP', HELP_INFORMATION_1: 'Besök Wikin för instruktioner om hur du kan konfigurera EMS-ESP',
HELP_INFORMATION_2: 'För community-support besök vår Discord-server', HELP_INFORMATION_2: 'För community-support besök vår Discord-server',
HELP_INFORMATION_3: 'Önska en ny funktion eller rapportera en bugg', HELP_INFORMATION_3: 'Önska en ny funktion eller rapportera en bugg',
HELP_INFORMATION_4: 'Bifoga din systeminformation för snabbare hantering när du rapporterar ett problem', HELP_INFORMATION_4: 'Bifoga din supportinformation för snabbare hantering när du rapporterar ett problem',
UPLOAD: 'Uppladdning', UPLOAD: 'Uppladdning',
DOWNLOAD: '{{N|n|n}}edladdning', DOWNLOAD: '{{N|n|n}}edladdning',
INSTALL: 'Installera', INSTALL: 'Installera',
@@ -168,90 +168,90 @@ const sv: Translation = {
SYSTEM: 'System', SYSTEM: 'System',
LOG_OF: '{0} Logg', LOG_OF: '{0} Logg',
STATUS_OF: '{0} Status', STATUS_OF: '{0} Status',
DOWNLOAD_UPLOAD: 'Nedladdning/Upp', DOWNLOAD_UPLOAD: 'Nedladdning/Uppladdning',
CLOSE: 'Stäng', CLOSE: 'Stäng',
USE: 'Använd', USE: 'Använd',
FACTORY_RESET: 'Fabriksåterställning', FACTORY_RESET: 'Fabriksåterställning',
SYSTEM_FACTORY_TEXT: 'Enheten har blivit fabriksåterställd och startar nu om', SYSTEM_FACTORY_TEXT: 'Enheten har blivit fabriksåterställd och startar nu om',
SYSTEM_FACTORY_TEXT_DIALOG: 'Är du säker att du vill fabriksåterställa enheten?', SYSTEM_FACTORY_TEXT_DIALOG: 'Är du säker att du vill fabriksåterställa enheten?',
AVAILABLE_VERSION: 'Latest Available Versions', // TODO translate AVAILABLE_VERSION: 'Senaste tillgängliga versioner',
STABLE: 'Stable', // TODO translate STABLE: 'Stabil',
DEVELOPMENT: 'Utveckling', DEVELOPMENT: 'Utveckling',
UPTIME: 'Systemets Upptid', UPTIME: 'Systemets upptid',
FREE_MEMORY: 'Ledigt Memory', FREE_MEMORY: 'Ledigt minne',
PSRAM: 'PSRAM (Storlek / Ledigt)', PSRAM: 'PSRAM (Storlek / Ledigt)',
FLASH: 'Flashminne (Storlek , Hastighet)', FLASH: 'Flashminne (Storlek , Hastighet)',
APPSIZE: 'Applikationer (Partition: Använt / Ledigt)', APPSIZE: 'Applikationer (Partition: Använt / Ledigt)',
FILESYSTEM: 'Filsystem (Använt / Ledigt)', FILESYSTEM: 'Filsystem (Använt / Ledigt)',
BUFFER_SIZE: 'Max Bufferstorlek', BUFFER_SIZE: 'Max bufferstorlek',
COMPACT: 'Komprimera', COMPACT: 'Komprimerad',
DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate DOWNLOAD_SETTINGS_TEXT: 'Skapa en säkerhetskopia av din konfiguration och inställningar',
UPLOAD_TEXT: 'Upload a new firmware file (.bin) or a backup file (.json)', // TODO translate UPLOAD_TEXT: 'Ladda upp en ny firmwarefil (.bin) eller en säkerhetskopiafil (.json)',
UPLOAD_DROP_TEXT: 'Släpp fil eller klicka här', UPLOAD_DROP_TEXT: 'Droppa en firmware .bin fil eller klicka här',
ERROR: 'Okänt Fel, var god försök igen', ERROR: 'Okänt fel, var god försök igen',
TIME_SET: 'Ställ in tid', TIME_SET: 'Ställ in tid',
MANAGE_USERS: 'Användare', MANAGE_USERS: 'Användare',
IS_ADMIN: 'Admin', IS_ADMIN: 'Administratör',
USER_WARNING: 'Du måste ha minst en admin konfigurerad', USER_WARNING: 'Du måste ha minst en administratör konfigurerad',
ADD: 'Lägg till', ADD: 'Lägg till',
ACCESS_TOKEN_FOR: 'Access Token för', ACCESS_TOKEN_FOR: 'Access Token för',
ACCESS_TOKEN_TEXT: 'Nedan Token används med REST API-anrop som kräver auktorisering. Den kan skickas med antingen som en Bearer token i Authorization-headern eller i access_token URL query-parametern.', ACCESS_TOKEN_TEXT: 'Nedan Token används med REST API-anrop som kräver auktorisering. Den kan skickas med antingen som en Bearer token i Authorization-headern eller i access_token URL query-parametern.',
GENERATING_TOKEN: 'Genererar token', GENERATING_TOKEN: 'Genererar token',
USER: 'Användare', USER: 'Användare',
MODIFY: 'Ändra', MODIFY: 'Ändra',
SU_TEXT: 'SU-användarens (super user) lösenord används för att signera autensierings-tokens samt för att aktivera administratörsprivilegier i Console-läge', SU_TEXT: 'SU-användarens (super user) lösenord används för att signera autentisierings-tokens samt för att aktivera administratörsprivilegier i Console-läge',
NOT_ENABLED: 'Ej aktiv', NOT_ENABLED: 'Ej aktiv',
ERRORS_OF: '{0} fel', ERRORS_OF: '{0} fel',
DISCONNECT_REASON: 'Anledning till nedkoppling', DISCONNECT_REASON: 'Anledning till nedkoppling',
ENABLE_MQTT: 'Aktivera MQTT', ENABLE_MQTT: 'Aktivera MQTT',
BROKER: 'Broker', BROKER: 'Broker',
CLIENT: 'Client', CLIENT: 'Klient',
BASE_TOPIC: 'Base', BASE_TOPIC: 'Bas-topic',
OPTIONAL: 'valfritt', OPTIONAL: 'valfritt',
FORMATTING: 'Formatering', FORMATTING: 'Formatering',
MQTT_FORMAT: 'Topic/Payload Format', MQTT_FORMAT: 'Topic/Payload format',
MQTT_NEST_1: 'Nestlat i en topic.', MQTT_NEST_1: 'Nästlat i en topic.',
MQTT_NEST_2: 'Som individuella topics', MQTT_NEST_2: 'Som individuella topics',
MQTT_RESPONSE: 'Publish-kommando som ett `response` topic', MQTT_RESPONSE: 'Publish-kommando som ett `response` topic',
MQTT_PUBLISH_TEXT_1: 'Publicera single value topics vid värdeförändring', MQTT_PUBLISH_TEXT_1: 'Publicera single value topics vid värdeförändring',
MQTT_PUBLISH_TEXT_2: 'Publicera till kommando-topics (ioBroker)', MQTT_PUBLISH_TEXT_2: 'Publicera till kommando-topics (ioBroker)',
MQTT_PUBLISH_TEXT_3: 'Aktivera MQTT Discovery', MQTT_PUBLISH_TEXT_3: 'Aktivera MQTT Discovery',
MQTT_PUBLISH_TEXT_4: 'Prefix för Discovery topics', MQTT_PUBLISH_TEXT_4: 'Prefix för Discovery topics',
MQTT_PUBLISH_TEXT_5: 'Discovery type', // TODO translate MQTT_PUBLISH_TEXT_5: 'Discoverytyp',
MQTT_PUBLISH_INTERVALS: 'Publiceringsintervall', MQTT_PUBLISH_INTERVALS: 'Publiceringsintervall',
MQTT_INT_BOILER: 'Värmepump/panna', MQTT_INT_BOILER: 'Värmepump/panna',
MQTT_INT_THERMOSTATS: 'Termostater', MQTT_INT_THERMOSTATS: 'Termostater',
MQTT_INT_SOLAR: 'Solpaneler', MQTT_INT_SOLAR: 'Solpaneler',
MQTT_INT_MIXER: 'Blandningsventiler', MQTT_INT_MIXER: 'Blandningsventiler',
MQTT_INT_WATER: 'Water Modules', // TODO translate MQTT_INT_WATER: 'Varmvattenmoduler',
MQTT_QUEUE: 'MQTT-kö', MQTT_QUEUE: 'MQTT-kö',
DEFAULT: 'Standard', DEFAULT: 'Standard',
MQTT_ENTITY_FORMAT: 'Entitets-ID format', MQTT_ENTITY_FORMAT: 'Entitets-ID format',
MQTT_ENTITY_FORMAT_0: 'Singel-instans, långt namn(v3.4)', MQTT_ENTITY_FORMAT_0: 'Singel-instans, långt namn(v3.4)',
MQTT_ENTITY_FORMAT_1: 'Singel-instans, kort name', MQTT_ENTITY_FORMAT_1: 'Singel-instans, kort namn',
MQTT_ENTITY_FORMAT_2: 'Multi-instans, kort name', MQTT_ENTITY_FORMAT_2: 'Multi-instans, kort namn',
MQTT_CLEAN_SESSION: 'Använd "Clean Session"-flaggan', MQTT_CLEAN_SESSION: 'Använd "Clean Session"-flaggan',
MQTT_RETAIN_FLAG: 'Använd "Always Retain"-flaggan', MQTT_RETAIN_FLAG: 'Använd "Always Retain"-flaggan',
INACTIVE: 'Inaktiv', INACTIVE: 'Inaktiv',
ACTIVE: 'Aktiv', ACTIVE: 'Aktiv',
UNKNOWN: 'Okänt', UNKNOWN: 'Okänt',
SET_TIME: 'Ställ in klockan', SET_TIME: 'Ställ in klockan',
SET_TIME_TEXT: 'Ange lokal datum och tid nedan för att ställa in klockan', SET_TIME_TEXT: 'Ange lokalt datum och tid nedan för att ställa in klockan',
LOCAL_TIME: 'Tid (lokal)', LOCAL_TIME: 'Tid (lokal)',
UTC_TIME: 'Tid (UTC)', UTC_TIME: 'Tid (UTC)',
ENABLE_NTP: 'Aktivera NTP', ENABLE_NTP: 'Aktivera NTP',
NTP_SERVER: 'NTP-server', NTP_SERVER: 'NTP-server',
TIME_ZONE: 'Tidszon', TIME_ZONE: 'Tidszon',
ACCESS_POINT: 'Accesspunkt', ACCESS_POINT: 'Accesspunkt',
AP_PROVIDE: 'Aktivera Accesspunkt', AP_PROVIDE: 'Aktivera accesspunkt',
AP_PROVIDE_TEXT_1: 'alltid', AP_PROVIDE_TEXT_1: 'alltid',
AP_PROVIDE_TEXT_2: 'när WiFi är nedkopplat', AP_PROVIDE_TEXT_2: 'när WiFi är nedkopplat',
AP_PROVIDE_TEXT_3: 'aldrig', AP_PROVIDE_TEXT_3: 'aldrig',
AP_PREFERRED_CHANNEL: 'Kanal', AP_PREFERRED_CHANNEL: 'Kanal',
AP_HIDE_SSID: 'Göm SSID', AP_HIDE_SSID: 'Göm SSID',
AP_CLIENTS: 'AP-klienter', AP_CLIENTS: 'AP-klienter',
AP_MAX_CLIENTS: 'Max Klienter', AP_MAX_CLIENTS: 'Max antal klienter',
AP_LOCAL_IP: 'Lokalt IP', AP_LOCAL_IP: 'Lokal IP-adress',
NETWORK_SCAN: 'Sök efter WiFi-nätverk', NETWORK_SCAN: 'Sök efter WiFi-nätverk',
IDLE: 'Vilande', IDLE: 'Vilande',
LOST: 'Förlorad', LOST: 'Förlorad',
@@ -260,90 +260,98 @@ const sv: Translation = {
NETWORK_SCANNER: 'Hittade nätverk', NETWORK_SCANNER: 'Hittade nätverk',
NETWORK_NO_WIFI: 'Inga WiFi-nätverk hittades', NETWORK_NO_WIFI: 'Inga WiFi-nätverk hittades',
NETWORK_BLANK_SSID: 'lämna blankt för att inaktivera WiFi', NETWORK_BLANK_SSID: 'lämna blankt för att inaktivera WiFi',
NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate NETWORK_BLANK_BSSID: 'lämna blankt för att bara använda SSID',
TX_POWER: 'Tx Effekt', TX_POWER: 'Tx effekt',
HOSTNAME: 'Värdnamn', HOSTNAME: 'Värdnamn',
NETWORK_DISABLE_SLEEP: 'Inaktivera sömnläge', NETWORK_DISABLE_SLEEP: 'Inaktivera sovläge',
NETWORK_LOW_BAND: 'Använd lägre bandbredd', NETWORK_LOW_BAND: 'Använd lägre bandbredd',
NETWORK_USE_DNS: 'Aktivera mDNS-tjänsten', NETWORK_USE_DNS: 'Aktivera mDNS-tjänsten',
NETWORK_ENABLE_CORS: 'Aktivera CORS', NETWORK_ENABLE_CORS: 'Aktivera CORS',
NETWORK_CORS_ORIGIN: 'CORS origin', NETWORK_CORS_ORIGIN: 'CORS origin',
NETWORK_FIXED_IP: 'Använd statiskt IP', NETWORK_FIXED_IP: 'Använd statisk IP-adress',
NETWORK_GATEWAY: 'Gateway', NETWORK_GATEWAY: 'Gateway',
NETWORK_SUBNET: 'Subnätmask', NETWORK_SUBNET: 'Subnätmask',
NETWORK_DNS: 'DNS-Server', NETWORK_DNS: 'DNS-Server',
ADDRESS_OF: '{0} Adress', ADDRESS_OF: '{0} Adress',
ADMINISTRATOR: 'Administrator', ADMINISTRATOR: 'Administratör',
GUEST: 'Gäst', GUEST: 'Gäst',
NEW: 'Ny', NEW: 'ny',
NEW_NAME_OF: 'Byt namn {0}', NEW_NAME_OF: 'Byt namn {0}',
ENTITY: 'Entitet', ENTITY: 'Entitet',
MIN: 'min', MIN: 'min',
MAX: 'max', MAX: 'max',
BLOCK_NAVIGATE_1: 'You have unsaved changes', // TODO translate BLOCK_NAVIGATE_1: 'Du har osparade ändringar',
BLOCK_NAVIGATE_2: 'If you navigate to a different page, your unsaved changes will be lost. Are you sure you want to leave this page?', // TODO translate BLOCK_NAVIGATE_2: 'Om du navigerar till en annan sida, kommer dina osparade ändringar förloras. Är du säker på att du vill lämna den här sidan?',
STAY: 'Stay', // TODO translate STAY: 'Stanna',
LEAVE: 'Leave', // TODO translate LEAVE: 'Lämna',
SCHEDULER: 'Scheduler', // TODO translate SCHEDULER: 'Schemaläggning',
SCHEDULER_HELP_1: 'Automate commands by adding scheduled events below. Set a unique Name to enable/disable activation via API/MQTT', // TODO translate SCHEDULER_HELP_1: 'Automatisera kommandon genom att lägga till schemahändelser nedan. Ange ett unikt namn för att aktivera/avaktivera aktivering via API/MQTT',
SCHEDULER_HELP_2: 'Use 00:00 to trigger once on start-up', // TODO translate SCHEDULER_HELP_2: 'Använd 00:00 för att trigga en gång vid uppstart',
SCHEDULE: 'Schedule', // TODO translate SCHEDULE: 'schema',
TIME: 'Time', // TODO translate TIME: 'Tid',
TIMER: 'Timer', // TODO translate TIMER: 'Timer',
ONCHANGE: ' förändring', ONCHANGE: 'Vid förändring',
CONDITION: 'Skick', CONDITION: 'Villkor',
IMMEDIATE: 'Omedelbar', IMMEDIATE: 'Omedelbar',
SCHEDULE_UPDATED: 'Schedule updated', // TODO translate SCHEDULE_UPDATED: 'Schema uppdaterat',
SCHEDULE_TIMER_1: 'on startup', // TODO translate SCHEDULE_TIMER_1: 'vid uppstart',
SCHEDULE_TIMER_2: 'every minute', // TODO translate SCHEDULE_TIMER_2: 'varje minut',
SCHEDULE_TIMER_3: 'every hour', // TODO translate SCHEDULE_TIMER_3: 'varje timme',
CUSTOM_ENTITIES: 'Custom Entities', // TODO translate CUSTOM_ENTITIES: 'Anpassade entiteter',
ENTITIES_HELP_1: 'Fetch custom entities from the EMS bus', // TODO translate ENTITIES_HELP_1: 'Hämta anpassade entiteter från EMS bussen',
ENTITIES_UPDATED: 'Entities Updated', // TODO translate ENTITIES_UPDATED: 'Entiteter uppdaterade',
WRITEABLE: 'Writeable', // TODO translate WRITEABLE: 'Skrivbara',
SHOWING: 'Showing', // TODO translate SHOWING: 'Visar',
SEARCH: 'Search', // TODO translate SEARCH: 'Sök',
CERT: 'TLS root certificate (leave blank for insecure)', // TODO translate CERT: 'TLS rotcertifikat (lämna blankt för ingen säkerhet)',
ENABLE_TLS: 'Aktivera TLS', ENABLE_TLS: 'Aktivera TLS',
ON: 'On', // TODO translate ON: '',
OFF: 'Off', // TODO translate OFF: 'Av',
POLARITY: 'Polarity', // TODO translate POLARITY: 'Polaritet',
ACTIVEHIGH: 'Active High', // TODO translate ACTIVEHIGH: 'Aktivt hög',
ACTIVELOW: 'Active Low', // TODO translate ACTIVELOW: 'Aktivt låg',
UNCHANGED: 'Unchanged', // TODO translate UNCHANGED: 'Oändrad',
ALWAYS: 'Always', // TODO translate ALWAYS: 'Alltid',
ACTIVITY: 'Activity', // TODO translate ACTIVITY: 'Aktivitet',
CONFIGURE: 'Configure {0}', // TODO translate CONFIGURE: 'Konfigurera {0}',
SYSTEM_MEMORY: 'System Memory', // TODO translate SYSTEM_MEMORY: 'Systemminne',
APPLICATION_SETTINGS_1: 'Modify EMS-ESP Application Settings', // TODO translate APPLICATION_SETTINGS_1: 'Ändra EMS-ESP Applikationsinställningar',
SECURITY_1: 'Add or remove users', // TODO translate SECURITY_1: 'Lägg till eller ta bort användare',
DOWNLOAD_UPLOAD_1: 'Download and Upload Settings and Firmware', // TODO translate DOWNLOAD_UPLOAD_1: 'Ladda ner eller ladda upp inställningar och firmware',
MODULES: 'Module', // TODO translate MODULES: 'Moduler',
MODULES_1: 'Aktivera eller avaktivera externa moduler', MODULES_1: 'Aktivera eller avaktivera externa moduler',
MODULES_UPDATED: 'Modules updated', // TODO translate MODULES_UPDATED: 'Moduler updaterade',
MODULES_DESCRIPTION: 'Click on the Module to activate or de-activate EMS-ESP library modules', // TODO translate MODULES_DESCRIPTION: 'Klicka på modulen för att aktivera eller deaktivera EMS-ESP moduler',
MODULES_NONE: 'No external modules detected', // TODO translate MODULES_NONE: 'Inga externa moduler upptäckta',
RENAME: 'Rename', // TODO translate RENAME: 'Byt namn',
ENABLE_MODBUS: 'Aktivera Modbus', ENABLE_MODBUS: 'Aktivera Modbus',
VIEW_LOG: 'View log to diagnose issues', // TODO translate VIEW_LOG: 'Titta i loggen för att felsöka problem',
UPLOAD_DRAG: 'drag and drop a file here or click to select one', // TODO translate UPLOAD_DRAG: 'dra och släpp en fil här eller klicka för att välja en',
SERVICES: 'Services', // TODO translate SERVICES: 'Tjänster',
ALLVALUES: 'All Values', // TODO translate ALLVALUES: 'Alla värden',
SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate SPECIAL_FUNCTIONS: 'Specialfunktioner',
WAIT_FIRMWARE: 'Firmware is uploading and installing', // TODO translate WAIT_FIRMWARE: 'Firmware laddas upp och installeras',
INSTALL_VERSION: 'This will install version {0}. Are you sure?', // TODO translate INSTALL_VERSION: 'Det här kommer {0} version {1}. Är du säker?',
SWITCH_DEV: 'switch to the development version', // TODO translate UPDATE_AVAILABLE: 'uppdatering tillgänglig',
UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate LATEST_VERSION: 'Du använder den senaste {0} firmwareversionen.',
LATEST_VERSION: 'You are using the latest firmware version.', // TODO translate PLEASE_WAIT: 'Var god vänta',
PLEASE_WAIT: 'Please wait', // TODO translate RESTARTING_PRE: 'Initialiserar',
RESTARTING_PRE: 'Initializing', // TODO translate RESTARTING_POST: 'Förbereder',
RESTARTING_POST: 'Preparing', // TODO translate AUTO_SCROLL: 'Autoskrolla',
AUTO_SCROLL: 'Auto Scroll', // TODO translate DASHBOARD: 'Kontrollpanel',
DASHBOARD: 'Dashboard', // TODO translate DEVELOPER_MODE: 'Utvecklarläge',
NO_DATA: 'No data available', // TODO translate BYTES: 'Bytes',
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate BITMASK: 'Bitmask',
DEVELOPER_MODE: 'Developer Mode', // TODO translate DUPLICATE: 'Dublett',
UPGRADE: 'Upgrade' // TODO translate DASHBOARD_1: 'Alla EMS-enheter som är aktiva och markerade som favorit, plus alla anpassade entiteter, scheman och externa sensor-data visas nedan.',
NO_DATA_1: 'Inga favorit EMS enheter hittade än. Använd',
NO_DATA_2: 'modul för att markera dem.',
NO_DATA_3: 'För att se alla tillgängliga enheter, gå till',
THIS_VERSION: 'Denna version',
PLATFORM: 'Plattform',
RELEASE_TYPE: 'Utgivelsestyp',
INTERNET_CONNECTION_REQUIRED: 'Internetanslutning krävs för automatisk version kontroll och uppdatering',
SWITCH_RELEASE_TYPE: 'Byt till {0} utgåva'
}; };
export default sv; export default sv;

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