mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2026-05-08 23:15:52 +00:00
Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev
This commit is contained in:
@@ -69,7 +69,7 @@ Format: `<type>(<scope>): <subject>`
|
||||
|
||||
## Example
|
||||
|
||||
```
|
||||
```text
|
||||
feat: add hat wobble
|
||||
^--^ ^------------^
|
||||
| |
|
||||
@@ -96,7 +96,7 @@ References:
|
||||
|
||||
## Contributor License Agreement (CLA)
|
||||
|
||||
```
|
||||
```text
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
[](https://discord.gg/3J3GgnzpyT)
|
||||
|
||||
[](https://github.com/emsesp/EMS-ESP32/stargazers)
|
||||
[](https://github.com/emsesp/EMS-ES32P/network)
|
||||
[](https://github.com/emsesp/EMS-ESP32/network)
|
||||
[](https://www.paypal.com/paypalme/prderbyshire/2)
|
||||
|
||||
**EMS-ESP** is an open-source firmware for the Espressif ESP32 microcontroller to communicate with **EMS** (Energy Management System) compatible equipment from manufacturers such as Bosch, Buderus, Nefit, Junkers, Worcester, Sieger, elm.leblanc and iVT.
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
"src/core/modbus_entity_parameters.hpp",
|
||||
"sdkconfig.*",
|
||||
"managed_components/**",
|
||||
"pnpm-*.yaml"
|
||||
"pnpm-*.yaml",
|
||||
"vite.config.ts"
|
||||
]
|
||||
}
|
||||
@@ -421,8 +421,8 @@
|
||||
| dhw.comfoff | comfort switch off | uint8 (>=15<=65) | C | true | DHW | 18 | 1 | 1 |
|
||||
| dhw.ecooff | eco switch off | uint8 (>=15<=65) | C | true | DHW | 19 | 1 | 1 |
|
||||
| dhw.ecoplusoff | eco+ switch off | uint8 (>=48<=63) | C | true | DHW | 20 | 1 | 1 |
|
||||
| dhw.comfdiff | comfort diff | uint8 (>=6<=12) | K | true | DHW | 21 | 1 | 1 |
|
||||
| dhw.ecodiff | eco diff | uint8 (>=6<=12) | K | true | DHW | 22 | 1 | 1 |
|
||||
| dhw.comfdiff | comfort diff | uint8 (>=4<=12) | K | true | DHW | 21 | 1 | 1 |
|
||||
| dhw.ecodiff | eco diff | uint8 (>=4<=12) | K | true | DHW | 22 | 1 | 1 |
|
||||
| dhw.ecoplusdiff | eco+ diff | uint8 (>=6<=12) | K | true | DHW | 23 | 1 | 1 |
|
||||
| dhw.comfstop | comfort stop temp | uint8 (>=0<=254) | C | true | DHW | 24 | 1 | 1 |
|
||||
| dhw.ecostop | eco stop temp | uint8 (>=0<=254) | C | true | DHW | 25 | 1 | 1 |
|
||||
@@ -1704,8 +1704,8 @@
|
||||
| dhw.comfoff | comfort switch off | uint8 (>=15<=65) | C | true | DHW | 18 | 1 | 1 |
|
||||
| dhw.ecooff | eco switch off | uint8 (>=15<=65) | C | true | DHW | 19 | 1 | 1 |
|
||||
| dhw.ecoplusoff | eco+ switch off | uint8 (>=48<=63) | C | true | DHW | 20 | 1 | 1 |
|
||||
| dhw.comfdiff | comfort diff | uint8 (>=6<=12) | K | true | DHW | 21 | 1 | 1 |
|
||||
| dhw.ecodiff | eco diff | uint8 (>=6<=12) | K | true | DHW | 22 | 1 | 1 |
|
||||
| dhw.comfdiff | comfort diff | uint8 (>=4<=12) | K | true | DHW | 21 | 1 | 1 |
|
||||
| dhw.ecodiff | eco diff | uint8 (>=4<=12) | K | true | DHW | 22 | 1 | 1 |
|
||||
| dhw.ecoplusdiff | eco+ diff | uint8 (>=6<=12) | K | true | DHW | 23 | 1 | 1 |
|
||||
| dhw.comfstop | comfort stop temp | uint8 (>=0<=254) | C | true | DHW | 24 | 1 | 1 |
|
||||
| dhw.ecostop | eco stop temp | uint8 (>=0<=254) | C | true | DHW | 25 | 1 | 1 |
|
||||
@@ -2273,8 +2273,8 @@
|
||||
| dhw.comfoff | comfort switch off | uint8 (>=15<=65) | C | true | DHW | 18 | 1 | 1 |
|
||||
| dhw.ecooff | eco switch off | uint8 (>=15<=65) | C | true | DHW | 19 | 1 | 1 |
|
||||
| dhw.ecoplusoff | eco+ switch off | uint8 (>=48<=63) | C | true | DHW | 20 | 1 | 1 |
|
||||
| dhw.comfdiff | comfort diff | uint8 (>=6<=12) | K | true | DHW | 21 | 1 | 1 |
|
||||
| dhw.ecodiff | eco diff | uint8 (>=6<=12) | K | true | DHW | 22 | 1 | 1 |
|
||||
| dhw.comfdiff | comfort diff | uint8 (>=4<=12) | K | true | DHW | 21 | 1 | 1 |
|
||||
| dhw.ecodiff | eco diff | uint8 (>=4<=12) | K | true | DHW | 22 | 1 | 1 |
|
||||
| dhw.ecoplusdiff | eco+ diff | uint8 (>=6<=12) | K | true | DHW | 23 | 1 | 1 |
|
||||
| dhw.comfstop | comfort stop temp | uint8 (>=0<=254) | C | true | DHW | 24 | 1 | 1 |
|
||||
| dhw.ecostop | eco stop temp | uint8 (>=0<=254) | C | true | DHW | 25 | 1 | 1 |
|
||||
@@ -3967,6 +3967,13 @@
|
||||
| nrgheat | energy heating | uint24 (>=0<=10000000) | kWh | true | DEVICE_DATA | 85 | 2 | 1/100 |
|
||||
| dhw.nrg | energy | uint24 (>=0<=10000000) | kWh | true | DHW | 0 | 2 | 1/100 |
|
||||
|
||||
## Devices of type *connect*
|
||||
### MX400
|
||||
| shortname | fullname | type | uom | writeable | tag type | register offset | register count | scale factor |
|
||||
|-|-|-|-|-|-|-|-|-|
|
||||
| datetime | date/time | string | | false | DEVICE_DATA | 0 | 13 | 1 |
|
||||
| outdoortemp | outside temperature | int16 (>=-3199<=3199) | C | false | DEVICE_DATA | 13 | 1 | 1/10 |
|
||||
|
||||
## Devices of type *controller*
|
||||
### Rego 3000
|
||||
| shortname | fullname | type | uom | writeable | tag type | register offset | register count | scale factor |
|
||||
@@ -4704,18 +4711,18 @@
|
||||
| hc1.switchtime1 | own1 program switchtime | string | | true | HC | 91 | 8 | 1 |
|
||||
| hc1.switchtime2 | own2 program switchtime | string | | true | HC | 99 | 8 | 1 |
|
||||
| dhw.mode | operating mode | enum [off\|on\|auto] | | true | DHW | 0 | 1 | 1 |
|
||||
| dhw.circmode | circulation pump mode | enum [off\|on\|auto] | | true | DHW | 3 | 1 | 1 |
|
||||
| dhw.progmode | program | enum [std prog\|own prog] | | true | DHW | 12 | 1 | 1 |
|
||||
| dhw.circprog | circulation program | enum [std prog\|own prog] | | true | DHW | 13 | 1 | 1 |
|
||||
| dhw.disinfecting | disinfecting | boolean | | true | DHW | 7 | 1 | 1 |
|
||||
| dhw.disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 8 | 1 | 1 |
|
||||
| dhw.disinfecthour | disinfection hour | uint8 (>=0<=23) | | true | DHW | 14 | 1 | 1 |
|
||||
| dhw.maxtemp | maximum temperature | uint8 (>=0<=254) | C | true | DHW | 15 | 1 | 1 |
|
||||
| dhw.onetimekey | one time key function | boolean | | true | DHW | 16 | 1 | 1 |
|
||||
| dhw.switchtime | program switchtime | string | | true | DHW | 17 | 8 | 1 |
|
||||
| dhw.circswitchtime | circulation program switchtime | string | | true | DHW | 25 | 8 | 1 |
|
||||
| dhw.holidays | holiday dates | string | | true | DHW | 33 | 13 | 1 |
|
||||
| dhw.vacations | vacation dates | string | | true | DHW | 46 | 13 | 1 |
|
||||
| dhw.circmode | circulation pump mode | enum [off\|on\|auto] | | true | DHW | 4 | 1 | 1 |
|
||||
| dhw.progmode | program | enum [std prog\|own prog] | | true | DHW | 13 | 1 | 1 |
|
||||
| dhw.circprog | circulation program | enum [std prog\|own prog] | | true | DHW | 14 | 1 | 1 |
|
||||
| dhw.disinfecting | disinfecting | boolean | | true | DHW | 8 | 1 | 1 |
|
||||
| dhw.disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 9 | 1 | 1 |
|
||||
| dhw.disinfecthour | disinfection hour | uint8 (>=0<=23) | | true | DHW | 15 | 1 | 1 |
|
||||
| dhw.maxtemp | maximum temperature | uint8 (>=0<=254) | C | true | DHW | 16 | 1 | 1 |
|
||||
| dhw.onetimekey | one time key function | boolean | | true | DHW | 17 | 1 | 1 |
|
||||
| dhw.switchtime | program switchtime | string | | true | DHW | 18 | 8 | 1 |
|
||||
| dhw.circswitchtime | circulation program switchtime | string | | true | DHW | 26 | 8 | 1 |
|
||||
| dhw.holidays | holiday dates | string | | true | DHW | 34 | 13 | 1 |
|
||||
| dhw.vacations | vacation dates | string | | true | DHW | 47 | 13 | 1 |
|
||||
|
||||
### ES79
|
||||
| shortname | fullname | type | uom | writeable | tag type | register offset | register count | scale factor |
|
||||
@@ -4770,18 +4777,18 @@
|
||||
| hc1.switchtime1 | own1 program switchtime | string | | true | HC | 91 | 8 | 1 |
|
||||
| hc1.switchtime2 | own2 program switchtime | string | | true | HC | 99 | 8 | 1 |
|
||||
| dhw.mode | operating mode | enum [off\|on\|auto] | | true | DHW | 0 | 1 | 1 |
|
||||
| dhw.circmode | circulation pump mode | enum [off\|on\|auto] | | true | DHW | 3 | 1 | 1 |
|
||||
| dhw.progmode | program | enum [std prog\|own prog] | | true | DHW | 12 | 1 | 1 |
|
||||
| dhw.circprog | circulation program | enum [std prog\|own prog] | | true | DHW | 13 | 1 | 1 |
|
||||
| dhw.disinfecting | disinfecting | boolean | | true | DHW | 7 | 1 | 1 |
|
||||
| dhw.disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 8 | 1 | 1 |
|
||||
| dhw.disinfecthour | disinfection hour | uint8 (>=0<=23) | | true | DHW | 14 | 1 | 1 |
|
||||
| dhw.maxtemp | maximum temperature | uint8 (>=60<=80) | C | true | DHW | 15 | 1 | 1 |
|
||||
| dhw.onetimekey | one time key function | boolean | | true | DHW | 16 | 1 | 1 |
|
||||
| dhw.switchtime | program switchtime | string | | true | DHW | 17 | 8 | 1 |
|
||||
| dhw.circswitchtime | circulation program switchtime | string | | true | DHW | 25 | 8 | 1 |
|
||||
| dhw.holidays | holiday dates | string | | true | DHW | 33 | 13 | 1 |
|
||||
| dhw.vacations | vacation dates | string | | true | DHW | 46 | 13 | 1 |
|
||||
| dhw.circmode | circulation pump mode | enum [off\|on\|auto] | | true | DHW | 4 | 1 | 1 |
|
||||
| dhw.progmode | program | enum [std prog\|own prog] | | true | DHW | 13 | 1 | 1 |
|
||||
| dhw.circprog | circulation program | enum [std prog\|own prog] | | true | DHW | 14 | 1 | 1 |
|
||||
| dhw.disinfecting | disinfecting | boolean | | true | DHW | 8 | 1 | 1 |
|
||||
| dhw.disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 9 | 1 | 1 |
|
||||
| dhw.disinfecthour | disinfection hour | uint8 (>=0<=23) | | true | DHW | 15 | 1 | 1 |
|
||||
| dhw.maxtemp | maximum temperature | uint8 (>=60<=80) | C | true | DHW | 16 | 1 | 1 |
|
||||
| dhw.onetimekey | one time key function | boolean | | true | DHW | 17 | 1 | 1 |
|
||||
| dhw.switchtime | program switchtime | string | | true | DHW | 18 | 8 | 1 |
|
||||
| dhw.circswitchtime | circulation program switchtime | string | | true | DHW | 26 | 8 | 1 |
|
||||
| dhw.holidays | holiday dates | string | | true | DHW | 34 | 13 | 1 |
|
||||
| dhw.vacations | vacation dates | string | | true | DHW | 47 | 13 | 1 |
|
||||
|
||||
### EasyControl, CT200
|
||||
| shortname | fullname | type | uom | writeable | tag type | register offset | register count | scale factor |
|
||||
@@ -4832,7 +4839,7 @@
|
||||
| hc1.roominflfactor | room influence factor | uint8 (>=0<=100) | % | true | HC | 14 | 1 | 10 |
|
||||
| hc1.heatingtype | heating type | enum [off\|heatingcurve\|radiator\|convector\|floor] | | true | HC | 19 | 1 | 1 |
|
||||
| hc1.controlmode | control mode | enum [off\|unmixed\|unmixed IPM\|mixed IPM] | | true | HC | 25 | 1 | 1 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 5 | 1 | 1 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 6 | 1 | 1 |
|
||||
|
||||
### FB100
|
||||
| shortname | fullname | type | uom | writeable | tag type | register offset | register count | scale factor |
|
||||
@@ -4873,7 +4880,7 @@
|
||||
| hc1.roominflfactor | room influence factor | uint8 (>=0<=100) | % | true | HC | 14 | 1 | 10 |
|
||||
| hc1.heatingtype | heating type | enum [off\|heatingcurve\|radiator\|convector\|floor] | | true | HC | 19 | 1 | 1 |
|
||||
| hc1.controlmode | control mode | enum [off\|unmixed\|unmixed IPM\|mixed IPM] | | true | HC | 25 | 1 | 1 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 5 | 1 | 1 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 6 | 1 | 1 |
|
||||
|
||||
### FR10
|
||||
| shortname | fullname | type | uom | writeable | tag type | register offset | register count | scale factor |
|
||||
@@ -4912,7 +4919,7 @@
|
||||
| hc1.roominflfactor | room influence factor | uint8 (>=0<=100) | % | true | HC | 14 | 1 | 10 |
|
||||
| hc1.heatingtype | heating type | enum [off\|heatingcurve\|radiator\|convector\|floor] | | true | HC | 19 | 1 | 1 |
|
||||
| hc1.controlmode | control mode | enum [off\|unmixed\|unmixed IPM\|mixed IPM] | | true | HC | 25 | 1 | 1 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 5 | 1 | 1 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 6 | 1 | 1 |
|
||||
|
||||
### FR100
|
||||
| shortname | fullname | type | uom | writeable | tag type | register offset | register count | scale factor |
|
||||
@@ -4951,7 +4958,7 @@
|
||||
| hc1.roominflfactor | room influence factor | uint8 (>=0<=100) | % | true | HC | 14 | 1 | 10 |
|
||||
| hc1.heatingtype | heating type | enum [off\|heatingcurve\|radiator\|convector\|floor] | | true | HC | 19 | 1 | 1 |
|
||||
| hc1.controlmode | control mode | enum [off\|unmixed\|unmixed IPM\|mixed IPM] | | true | HC | 25 | 1 | 1 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 5 | 1 | 1 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 6 | 1 | 1 |
|
||||
|
||||
### FR110
|
||||
| shortname | fullname | type | uom | writeable | tag type | register offset | register count | scale factor |
|
||||
@@ -4990,7 +4997,7 @@
|
||||
| hc1.roominflfactor | room influence factor | uint8 (>=0<=100) | % | true | HC | 14 | 1 | 10 |
|
||||
| hc1.heatingtype | heating type | enum [off\|heatingcurve\|radiator\|convector\|floor] | | true | HC | 19 | 1 | 1 |
|
||||
| hc1.controlmode | control mode | enum [off\|unmixed\|unmixed IPM\|mixed IPM] | | true | HC | 25 | 1 | 1 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 5 | 1 | 1 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 6 | 1 | 1 |
|
||||
|
||||
### FR120
|
||||
| shortname | fullname | type | uom | writeable | tag type | register offset | register count | scale factor |
|
||||
@@ -5029,7 +5036,7 @@
|
||||
| hc1.roominflfactor | room influence factor | uint8 (>=0<=100) | % | true | HC | 14 | 1 | 10 |
|
||||
| hc1.heatingtype | heating type | enum [off\|heatingcurve\|radiator\|convector\|floor] | | true | HC | 19 | 1 | 1 |
|
||||
| hc1.controlmode | control mode | enum [off\|unmixed\|unmixed IPM\|mixed IPM] | | true | HC | 25 | 1 | 1 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 5 | 1 | 1 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 6 | 1 | 1 |
|
||||
|
||||
### FR50
|
||||
| shortname | fullname | type | uom | writeable | tag type | register offset | register count | scale factor |
|
||||
@@ -5068,7 +5075,7 @@
|
||||
| hc1.roominflfactor | room influence factor | uint8 (>=0<=100) | % | true | HC | 14 | 1 | 10 |
|
||||
| hc1.heatingtype | heating type | enum [off\|heatingcurve\|radiator\|convector\|floor] | | true | HC | 19 | 1 | 1 |
|
||||
| hc1.controlmode | control mode | enum [off\|unmixed\|unmixed IPM\|mixed IPM] | | true | HC | 25 | 1 | 1 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 5 | 1 | 1 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 6 | 1 | 1 |
|
||||
|
||||
### FW100
|
||||
| shortname | fullname | type | uom | writeable | tag type | register offset | register count | scale factor |
|
||||
@@ -5109,7 +5116,7 @@
|
||||
| hc1.roominflfactor | room influence factor | uint8 (>=0<=100) | % | true | HC | 14 | 1 | 10 |
|
||||
| hc1.heatingtype | heating type | enum [off\|heatingcurve\|radiator\|convector\|floor] | | true | HC | 19 | 1 | 1 |
|
||||
| hc1.controlmode | control mode | enum [off\|unmixed\|unmixed IPM\|mixed IPM] | | true | HC | 25 | 1 | 1 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 5 | 1 | 1 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 6 | 1 | 1 |
|
||||
|
||||
### FW120
|
||||
| shortname | fullname | type | uom | writeable | tag type | register offset | register count | scale factor |
|
||||
@@ -5150,7 +5157,7 @@
|
||||
| hc1.roominflfactor | room influence factor | uint8 (>=0<=100) | % | true | HC | 14 | 1 | 10 |
|
||||
| hc1.heatingtype | heating type | enum [off\|heatingcurve\|radiator\|convector\|floor] | | true | HC | 19 | 1 | 1 |
|
||||
| hc1.controlmode | control mode | enum [off\|unmixed\|unmixed IPM\|mixed IPM] | | true | HC | 25 | 1 | 1 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 5 | 1 | 1 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 6 | 1 | 1 |
|
||||
|
||||
### FW200
|
||||
| shortname | fullname | type | uom | writeable | tag type | register offset | register count | scale factor |
|
||||
@@ -5191,7 +5198,7 @@
|
||||
| hc1.roominflfactor | room influence factor | uint8 (>=0<=100) | % | true | HC | 14 | 1 | 10 |
|
||||
| hc1.heatingtype | heating type | enum [off\|heatingcurve\|radiator\|convector\|floor] | | true | HC | 19 | 1 | 1 |
|
||||
| hc1.controlmode | control mode | enum [off\|unmixed\|unmixed IPM\|mixed IPM] | | true | HC | 25 | 1 | 1 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 5 | 1 | 1 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 6 | 1 | 1 |
|
||||
|
||||
### FW500
|
||||
| shortname | fullname | type | uom | writeable | tag type | register offset | register count | scale factor |
|
||||
@@ -5232,7 +5239,7 @@
|
||||
| hc1.roominflfactor | room influence factor | uint8 (>=0<=100) | % | true | HC | 14 | 1 | 10 |
|
||||
| hc1.heatingtype | heating type | enum [off\|heatingcurve\|radiator\|convector\|floor] | | true | HC | 19 | 1 | 1 |
|
||||
| hc1.controlmode | control mode | enum [off\|unmixed\|unmixed IPM\|mixed IPM] | | true | HC | 25 | 1 | 1 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 5 | 1 | 1 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 6 | 1 | 1 |
|
||||
|
||||
### Logamatic TC100, Moduline Easy
|
||||
| shortname | fullname | type | uom | writeable | tag type | register offset | register count | scale factor |
|
||||
@@ -5303,10 +5310,10 @@
|
||||
| hc1.manualtemp | manual temperature | uint8 (>=0<=127) | C | true | HC | 6 | 1 | 1/2 |
|
||||
| hc1.offtemp | temperature when mode is off | uint8 (>=0<=127) | C | true | HC | 107 | 1 | 1/2 |
|
||||
| dhw.mode | operating mode | enum [on\|off\|auto] | | true | DHW | 0 | 1 | 1 |
|
||||
| dhw.whenmodeoff | when thermostat mode off | boolean | | true | DHW | 59 | 1 | 1 |
|
||||
| dhw.disinfecting | disinfecting | boolean | | true | DHW | 7 | 1 | 1 |
|
||||
| dhw.disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 8 | 1 | 1 |
|
||||
| dhw.disinfecthour | disinfection hour | uint8 (>=0<=23) | | true | DHW | 14 | 1 | 1 |
|
||||
| dhw.whenmodeoff | when thermostat mode off | boolean | | true | DHW | 60 | 1 | 1 |
|
||||
| dhw.disinfecting | disinfecting | boolean | | true | DHW | 8 | 1 | 1 |
|
||||
| dhw.disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 9 | 1 | 1 |
|
||||
| dhw.disinfecthour | disinfection hour | uint8 (>=0<=23) | | true | DHW | 15 | 1 | 1 |
|
||||
|
||||
### RC10
|
||||
| shortname | fullname | type | uom | writeable | tag type | register offset | register count | scale factor |
|
||||
@@ -5487,17 +5494,18 @@
|
||||
| hc1.solarinfl | solar influence | uint8 (>=-5<=4294967295) | C | true | HC | 54 | 1 | 1 |
|
||||
| hc1.currsolarinfl | curent solar influence | uint8 (>=0<=25) | C | false | HC | 55 | 1 | 1/10 |
|
||||
| dhw.mode | operating mode | enum [off\|on\|auto] | | true | DHW | 0 | 1 | 1 |
|
||||
| dhw.settemp | set temperature | uint8 (>=0<=254) | C | true | DHW | 1 | 1 | 1 |
|
||||
| dhw.settemplow | set low temperature | uint8 (>=0<=254) | C | true | DHW | 2 | 1 | 1 |
|
||||
| dhw.circmode | circulation pump mode | enum [off\|on\|auto\|own prog] | | true | DHW | 3 | 1 | 1 |
|
||||
| dhw.chargeduration | charge duration | uint8 (>=0<=3810) | minutes | true | DHW | 4 | 1 | 15 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 5 | 1 | 1 |
|
||||
| dhw.extra | extra | boolean | | false | DHW | 6 | 1 | 1 |
|
||||
| dhw.disinfecting | disinfecting | boolean | | true | DHW | 7 | 1 | 1 |
|
||||
| dhw.disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 8 | 1 | 1 |
|
||||
| dhw.disinfecttime | disinfection time | uint8 (>=0<=1431) | minutes | true | DHW | 9 | 1 | 15 |
|
||||
| dhw.dailyheating | daily heating | boolean | | true | DHW | 10 | 1 | 1 |
|
||||
| dhw.dailyheattime | daily heating time | uint8 (>=0<=1431) | minutes | true | DHW | 11 | 1 | 15 |
|
||||
| dhw.modetype | mode type | enum [off\|eco\|comfort\|eco+] | | false | DHW | 1 | 1 | 1 |
|
||||
| dhw.settemp | set temperature | uint8 (>=0<=254) | C | true | DHW | 2 | 1 | 1 |
|
||||
| dhw.settemplow | set low temperature | uint8 (>=0<=254) | C | true | DHW | 3 | 1 | 1 |
|
||||
| dhw.circmode | circulation pump mode | enum [off\|on\|auto\|own prog] | | true | DHW | 4 | 1 | 1 |
|
||||
| dhw.chargeduration | charge duration | uint8 (>=0<=3810) | minutes | true | DHW | 5 | 1 | 15 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 6 | 1 | 1 |
|
||||
| dhw.extra | extra | boolean | | false | DHW | 7 | 1 | 1 |
|
||||
| dhw.disinfecting | disinfecting | boolean | | true | DHW | 8 | 1 | 1 |
|
||||
| dhw.disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 9 | 1 | 1 |
|
||||
| dhw.disinfecttime | disinfection time | uint8 (>=0<=1431) | minutes | true | DHW | 10 | 1 | 15 |
|
||||
| dhw.dailyheating | daily heating | boolean | | true | DHW | 11 | 1 | 1 |
|
||||
| dhw.dailyheattime | daily heating time | uint8 (>=0<=1431) | minutes | true | DHW | 12 | 1 | 15 |
|
||||
|
||||
### RC20RF
|
||||
| shortname | fullname | type | uom | writeable | tag type | register offset | register count | scale factor |
|
||||
@@ -5621,17 +5629,18 @@
|
||||
| hc1.solarinfl | solar influence | uint8 (>=-5<=4294967295) | C | true | HC | 54 | 1 | 1 |
|
||||
| hc1.currsolarinfl | curent solar influence | uint8 (>=0<=25) | C | false | HC | 55 | 1 | 1/10 |
|
||||
| dhw.mode | operating mode | enum [off\|normal\|comfort\|auto\|own prog] | | true | DHW | 0 | 1 | 1 |
|
||||
| dhw.settemp | set temperature | uint8 (>=0<=254) | C | true | DHW | 1 | 1 | 1 |
|
||||
| dhw.settemplow | set low temperature | uint8 (>=0<=254) | C | true | DHW | 2 | 1 | 1 |
|
||||
| dhw.circmode | circulation pump mode | enum [off\|on\|auto\|own prog] | | true | DHW | 3 | 1 | 1 |
|
||||
| dhw.chargeduration | charge duration | uint8 (>=0<=3810) | minutes | true | DHW | 4 | 1 | 15 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 5 | 1 | 1 |
|
||||
| dhw.extra | extra | boolean | | false | DHW | 6 | 1 | 1 |
|
||||
| dhw.disinfecting | disinfecting | boolean | | true | DHW | 7 | 1 | 1 |
|
||||
| dhw.disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 8 | 1 | 1 |
|
||||
| dhw.disinfecttime | disinfection time | uint8 (>=0<=1431) | minutes | true | DHW | 9 | 1 | 15 |
|
||||
| dhw.dailyheating | daily heating | boolean | | true | DHW | 10 | 1 | 1 |
|
||||
| dhw.dailyheattime | daily heating time | uint8 (>=0<=1431) | minutes | true | DHW | 11 | 1 | 15 |
|
||||
| dhw.modetype | mode type | enum [off\|eco\|comfort\|eco+] | | false | DHW | 1 | 1 | 1 |
|
||||
| dhw.settemp | set temperature | uint8 (>=0<=254) | C | true | DHW | 2 | 1 | 1 |
|
||||
| dhw.settemplow | set low temperature | uint8 (>=0<=254) | C | true | DHW | 3 | 1 | 1 |
|
||||
| dhw.circmode | circulation pump mode | enum [off\|on\|auto\|own prog] | | true | DHW | 4 | 1 | 1 |
|
||||
| dhw.chargeduration | charge duration | uint8 (>=0<=3810) | minutes | true | DHW | 5 | 1 | 15 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 6 | 1 | 1 |
|
||||
| dhw.extra | extra | boolean | | false | DHW | 7 | 1 | 1 |
|
||||
| dhw.disinfecting | disinfecting | boolean | | true | DHW | 8 | 1 | 1 |
|
||||
| dhw.disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 9 | 1 | 1 |
|
||||
| dhw.disinfecttime | disinfection time | uint8 (>=0<=1431) | minutes | true | DHW | 10 | 1 | 15 |
|
||||
| dhw.dailyheating | daily heating | boolean | | true | DHW | 11 | 1 | 1 |
|
||||
| dhw.dailyheattime | daily heating time | uint8 (>=0<=1431) | minutes | true | DHW | 12 | 1 | 15 |
|
||||
|
||||
### RC30
|
||||
| shortname | fullname | type | uom | writeable | tag type | register offset | register count | scale factor |
|
||||
@@ -5689,18 +5698,18 @@
|
||||
| hc1.switchtime1 | own1 program switchtime | string | | true | HC | 91 | 8 | 1 |
|
||||
| hc1.switchtime2 | own2 program switchtime | string | | true | HC | 99 | 8 | 1 |
|
||||
| dhw.mode | operating mode | enum [off\|on\|auto] | | true | DHW | 0 | 1 | 1 |
|
||||
| dhw.circmode | circulation pump mode | enum [off\|on\|auto] | | true | DHW | 3 | 1 | 1 |
|
||||
| dhw.progmode | program | enum [std prog\|own prog] | | true | DHW | 12 | 1 | 1 |
|
||||
| dhw.circprog | circulation program | enum [std prog\|own prog] | | true | DHW | 13 | 1 | 1 |
|
||||
| dhw.disinfecting | disinfecting | boolean | | true | DHW | 7 | 1 | 1 |
|
||||
| dhw.disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 8 | 1 | 1 |
|
||||
| dhw.disinfecthour | disinfection hour | uint8 (>=0<=23) | | true | DHW | 14 | 1 | 1 |
|
||||
| dhw.maxtemp | maximum temperature | uint8 (>=0<=254) | C | true | DHW | 15 | 1 | 1 |
|
||||
| dhw.onetimekey | one time key function | boolean | | true | DHW | 16 | 1 | 1 |
|
||||
| dhw.switchtime | program switchtime | string | | true | DHW | 17 | 8 | 1 |
|
||||
| dhw.circswitchtime | circulation program switchtime | string | | true | DHW | 25 | 8 | 1 |
|
||||
| dhw.holidays | holiday dates | string | | true | DHW | 33 | 13 | 1 |
|
||||
| dhw.vacations | vacation dates | string | | true | DHW | 46 | 13 | 1 |
|
||||
| dhw.circmode | circulation pump mode | enum [off\|on\|auto] | | true | DHW | 4 | 1 | 1 |
|
||||
| dhw.progmode | program | enum [std prog\|own prog] | | true | DHW | 13 | 1 | 1 |
|
||||
| dhw.circprog | circulation program | enum [std prog\|own prog] | | true | DHW | 14 | 1 | 1 |
|
||||
| dhw.disinfecting | disinfecting | boolean | | true | DHW | 8 | 1 | 1 |
|
||||
| dhw.disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 9 | 1 | 1 |
|
||||
| dhw.disinfecthour | disinfection hour | uint8 (>=0<=23) | | true | DHW | 15 | 1 | 1 |
|
||||
| dhw.maxtemp | maximum temperature | uint8 (>=0<=254) | C | true | DHW | 16 | 1 | 1 |
|
||||
| dhw.onetimekey | one time key function | boolean | | true | DHW | 17 | 1 | 1 |
|
||||
| dhw.switchtime | program switchtime | string | | true | DHW | 18 | 8 | 1 |
|
||||
| dhw.circswitchtime | circulation program switchtime | string | | true | DHW | 26 | 8 | 1 |
|
||||
| dhw.holidays | holiday dates | string | | true | DHW | 34 | 13 | 1 |
|
||||
| dhw.vacations | vacation dates | string | | true | DHW | 47 | 13 | 1 |
|
||||
|
||||
### RC35
|
||||
| shortname | fullname | type | uom | writeable | tag type | register offset | register count | scale factor |
|
||||
@@ -5755,18 +5764,18 @@
|
||||
| hc1.switchtime1 | own1 program switchtime | string | | true | HC | 91 | 8 | 1 |
|
||||
| hc1.switchtime2 | own2 program switchtime | string | | true | HC | 99 | 8 | 1 |
|
||||
| dhw.mode | operating mode | enum [off\|on\|auto] | | true | DHW | 0 | 1 | 1 |
|
||||
| dhw.circmode | circulation pump mode | enum [off\|on\|auto] | | true | DHW | 3 | 1 | 1 |
|
||||
| dhw.progmode | program | enum [std prog\|own prog] | | true | DHW | 12 | 1 | 1 |
|
||||
| dhw.circprog | circulation program | enum [std prog\|own prog] | | true | DHW | 13 | 1 | 1 |
|
||||
| dhw.disinfecting | disinfecting | boolean | | true | DHW | 7 | 1 | 1 |
|
||||
| dhw.disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 8 | 1 | 1 |
|
||||
| dhw.disinfecthour | disinfection hour | uint8 (>=0<=23) | | true | DHW | 14 | 1 | 1 |
|
||||
| dhw.maxtemp | maximum temperature | uint8 (>=60<=80) | C | true | DHW | 15 | 1 | 1 |
|
||||
| dhw.onetimekey | one time key function | boolean | | true | DHW | 16 | 1 | 1 |
|
||||
| dhw.switchtime | program switchtime | string | | true | DHW | 17 | 8 | 1 |
|
||||
| dhw.circswitchtime | circulation program switchtime | string | | true | DHW | 25 | 8 | 1 |
|
||||
| dhw.holidays | holiday dates | string | | true | DHW | 33 | 13 | 1 |
|
||||
| dhw.vacations | vacation dates | string | | true | DHW | 46 | 13 | 1 |
|
||||
| dhw.circmode | circulation pump mode | enum [off\|on\|auto] | | true | DHW | 4 | 1 | 1 |
|
||||
| dhw.progmode | program | enum [std prog\|own prog] | | true | DHW | 13 | 1 | 1 |
|
||||
| dhw.circprog | circulation program | enum [std prog\|own prog] | | true | DHW | 14 | 1 | 1 |
|
||||
| dhw.disinfecting | disinfecting | boolean | | true | DHW | 8 | 1 | 1 |
|
||||
| dhw.disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 9 | 1 | 1 |
|
||||
| dhw.disinfecthour | disinfection hour | uint8 (>=0<=23) | | true | DHW | 15 | 1 | 1 |
|
||||
| dhw.maxtemp | maximum temperature | uint8 (>=60<=80) | C | true | DHW | 16 | 1 | 1 |
|
||||
| dhw.onetimekey | one time key function | boolean | | true | DHW | 17 | 1 | 1 |
|
||||
| dhw.switchtime | program switchtime | string | | true | DHW | 18 | 8 | 1 |
|
||||
| dhw.circswitchtime | circulation program switchtime | string | | true | DHW | 26 | 8 | 1 |
|
||||
| dhw.holidays | holiday dates | string | | true | DHW | 34 | 13 | 1 |
|
||||
| dhw.vacations | vacation dates | string | | true | DHW | 47 | 13 | 1 |
|
||||
|
||||
### RFM20 Remote
|
||||
| shortname | fullname | type | uom | writeable | tag type | register offset | register count | scale factor |
|
||||
@@ -5871,17 +5880,18 @@
|
||||
| hc1.solarinfl | solar influence | uint8 (>=-5<=4294967295) | C | true | HC | 54 | 1 | 1 |
|
||||
| hc1.currsolarinfl | curent solar influence | uint8 (>=0<=25) | C | false | HC | 55 | 1 | 1/10 |
|
||||
| dhw.mode | operating mode | enum [normal\|comfort\|eco+] | | true | DHW | 0 | 1 | 1 |
|
||||
| dhw.settemp | set temperature | uint8 (>=0<=254) | C | true | DHW | 1 | 1 | 1 |
|
||||
| dhw.settemplow | set low temperature | uint8 (>=0<=254) | C | true | DHW | 2 | 1 | 1 |
|
||||
| dhw.circmode | circulation pump mode | enum [off\|on\|auto\|own prog] | | true | DHW | 3 | 1 | 1 |
|
||||
| dhw.chargeduration | charge duration | uint8 (>=0<=3810) | minutes | true | DHW | 4 | 1 | 15 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 5 | 1 | 1 |
|
||||
| dhw.extra | extra | boolean | | false | DHW | 6 | 1 | 1 |
|
||||
| dhw.disinfecting | disinfecting | boolean | | true | DHW | 7 | 1 | 1 |
|
||||
| dhw.disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 8 | 1 | 1 |
|
||||
| dhw.disinfecttime | disinfection time | uint8 (>=0<=1431) | minutes | true | DHW | 9 | 1 | 15 |
|
||||
| dhw.dailyheating | daily heating | boolean | | true | DHW | 10 | 1 | 1 |
|
||||
| dhw.dailyheattime | daily heating time | uint8 (>=0<=1431) | minutes | true | DHW | 11 | 1 | 15 |
|
||||
| dhw.modetype | mode type | enum [off\|eco\|comfort\|eco+] | | false | DHW | 1 | 1 | 1 |
|
||||
| dhw.settemp | set temperature | uint8 (>=0<=254) | C | true | DHW | 2 | 1 | 1 |
|
||||
| dhw.settemplow | set low temperature | uint8 (>=0<=254) | C | true | DHW | 3 | 1 | 1 |
|
||||
| dhw.circmode | circulation pump mode | enum [off\|on\|auto\|own prog] | | true | DHW | 4 | 1 | 1 |
|
||||
| dhw.chargeduration | charge duration | uint8 (>=0<=3810) | minutes | true | DHW | 5 | 1 | 15 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 6 | 1 | 1 |
|
||||
| dhw.extra | extra | boolean | | false | DHW | 7 | 1 | 1 |
|
||||
| dhw.disinfecting | disinfecting | boolean | | true | DHW | 8 | 1 | 1 |
|
||||
| dhw.disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 9 | 1 | 1 |
|
||||
| dhw.disinfecttime | disinfection time | uint8 (>=0<=1431) | minutes | true | DHW | 10 | 1 | 15 |
|
||||
| dhw.dailyheating | daily heating | boolean | | true | DHW | 11 | 1 | 1 |
|
||||
| dhw.dailyheattime | daily heating time | uint8 (>=0<=1431) | minutes | true | DHW | 12 | 1 | 15 |
|
||||
|
||||
### Rego 3000, UI800, Logamatic BC400
|
||||
| shortname | fullname | type | uom | writeable | tag type | register offset | register count | scale factor |
|
||||
@@ -5965,17 +5975,18 @@
|
||||
| hc1.solarinfl | solar influence | uint8 (>=-5<=4294967295) | C | true | HC | 54 | 1 | 1 |
|
||||
| hc1.currsolarinfl | curent solar influence | uint8 (>=0<=25) | C | false | HC | 55 | 1 | 1/10 |
|
||||
| dhw.mode | operating mode | enum [off\|eco+\|eco\|comfort\|auto] | | true | DHW | 0 | 1 | 1 |
|
||||
| dhw.settemp | set temperature | uint8 (>=0<=254) | C | true | DHW | 1 | 1 | 1 |
|
||||
| dhw.settemplow | set low temperature | uint8 (>=0<=254) | C | true | DHW | 2 | 1 | 1 |
|
||||
| dhw.circmode | circulation pump mode | enum [off\|on\|auto\|own prog] | | true | DHW | 3 | 1 | 1 |
|
||||
| dhw.chargeduration | charge duration | uint8 (>=0<=3810) | minutes | true | DHW | 4 | 1 | 15 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 5 | 1 | 1 |
|
||||
| dhw.extra | extra | boolean | | false | DHW | 6 | 1 | 1 |
|
||||
| dhw.disinfecting | disinfecting | boolean | | true | DHW | 7 | 1 | 1 |
|
||||
| dhw.disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 8 | 1 | 1 |
|
||||
| dhw.disinfecttime | disinfection time | uint8 (>=0<=1431) | minutes | true | DHW | 9 | 1 | 15 |
|
||||
| dhw.dailyheating | daily heating | boolean | | true | DHW | 10 | 1 | 1 |
|
||||
| dhw.dailyheattime | daily heating time | uint8 (>=0<=1431) | minutes | true | DHW | 11 | 1 | 15 |
|
||||
| dhw.modetype | mode type | enum [off\|eco\|comfort\|eco+] | | false | DHW | 1 | 1 | 1 |
|
||||
| dhw.settemp | set temperature | uint8 (>=0<=254) | C | true | DHW | 2 | 1 | 1 |
|
||||
| dhw.settemplow | set low temperature | uint8 (>=0<=254) | C | true | DHW | 3 | 1 | 1 |
|
||||
| dhw.circmode | circulation pump mode | enum [off\|on\|auto\|own prog] | | true | DHW | 4 | 1 | 1 |
|
||||
| dhw.chargeduration | charge duration | uint8 (>=0<=3810) | minutes | true | DHW | 5 | 1 | 15 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 6 | 1 | 1 |
|
||||
| dhw.extra | extra | boolean | | false | DHW | 7 | 1 | 1 |
|
||||
| dhw.disinfecting | disinfecting | boolean | | true | DHW | 8 | 1 | 1 |
|
||||
| dhw.disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 9 | 1 | 1 |
|
||||
| dhw.disinfecttime | disinfection time | uint8 (>=0<=1431) | minutes | true | DHW | 10 | 1 | 15 |
|
||||
| dhw.dailyheating | daily heating | boolean | | true | DHW | 11 | 1 | 1 |
|
||||
| dhw.dailyheattime | daily heating time | uint8 (>=0<=1431) | minutes | true | DHW | 12 | 1 | 15 |
|
||||
|
||||
### TR120RF, CR20RF
|
||||
| shortname | fullname | type | uom | writeable | tag type | register offset | register count | scale factor |
|
||||
@@ -6069,17 +6080,18 @@
|
||||
| hc1.solarinfl | solar influence | uint8 (>=-5<=4294967295) | C | true | HC | 54 | 1 | 1 |
|
||||
| hc1.currsolarinfl | curent solar influence | uint8 (>=0<=25) | C | false | HC | 55 | 1 | 1/10 |
|
||||
| dhw.mode | operating mode | enum [off\|eco+\|eco\|comfort\|auto] | | true | DHW | 0 | 1 | 1 |
|
||||
| dhw.settemp | set temperature | uint8 (>=0<=254) | C | true | DHW | 1 | 1 | 1 |
|
||||
| dhw.settemplow | set low temperature | uint8 (>=0<=254) | C | true | DHW | 2 | 1 | 1 |
|
||||
| dhw.circmode | circulation pump mode | enum [off\|on\|auto\|own prog] | | true | DHW | 3 | 1 | 1 |
|
||||
| dhw.chargeduration | charge duration | uint8 (>=0<=3810) | minutes | true | DHW | 4 | 1 | 15 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 5 | 1 | 1 |
|
||||
| dhw.extra | extra | boolean | | false | DHW | 6 | 1 | 1 |
|
||||
| dhw.disinfecting | disinfecting | boolean | | true | DHW | 7 | 1 | 1 |
|
||||
| dhw.disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 8 | 1 | 1 |
|
||||
| dhw.disinfecttime | disinfection time | uint8 (>=0<=1431) | minutes | true | DHW | 9 | 1 | 15 |
|
||||
| dhw.dailyheating | daily heating | boolean | | true | DHW | 10 | 1 | 1 |
|
||||
| dhw.dailyheattime | daily heating time | uint8 (>=0<=1431) | minutes | true | DHW | 11 | 1 | 15 |
|
||||
| dhw.modetype | mode type | enum [off\|eco\|comfort\|eco+] | | false | DHW | 1 | 1 | 1 |
|
||||
| dhw.settemp | set temperature | uint8 (>=0<=254) | C | true | DHW | 2 | 1 | 1 |
|
||||
| dhw.settemplow | set low temperature | uint8 (>=0<=254) | C | true | DHW | 3 | 1 | 1 |
|
||||
| dhw.circmode | circulation pump mode | enum [off\|on\|auto\|own prog] | | true | DHW | 4 | 1 | 1 |
|
||||
| dhw.chargeduration | charge duration | uint8 (>=0<=3810) | minutes | true | DHW | 5 | 1 | 15 |
|
||||
| dhw.charge | charge | boolean | | true | DHW | 6 | 1 | 1 |
|
||||
| dhw.extra | extra | boolean | | false | DHW | 7 | 1 | 1 |
|
||||
| dhw.disinfecting | disinfecting | boolean | | true | DHW | 8 | 1 | 1 |
|
||||
| dhw.disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 9 | 1 | 1 |
|
||||
| dhw.disinfecttime | disinfection time | uint8 (>=0<=1431) | minutes | true | DHW | 10 | 1 | 15 |
|
||||
| dhw.dailyheating | daily heating | boolean | | true | DHW | 11 | 1 | 1 |
|
||||
| dhw.dailyheattime | daily heating time | uint8 (>=0<=1431) | minutes | true | DHW | 12 | 1 | 15 |
|
||||
|
||||
## Devices of type *ventilation*
|
||||
### HRV176, HRV156, 5000c, MV200
|
||||
|
||||
@@ -160,8 +160,8 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"CS5800i, CS6800i, WLW176i, WLW186i",boiler,8,dhw.comfoff,comfort switch off,uint8 (>=15<=65),C,true,number.boiler_dhw_comfort_switch_off,number.boiler_dhw_comfoff,5,9,1,18,1
|
||||
"CS5800i, CS6800i, WLW176i, WLW186i",boiler,8,dhw.ecooff,eco switch off,uint8 (>=15<=65),C,true,number.boiler_dhw_eco_switch_off,number.boiler_dhw_ecooff,5,9,1,19,1
|
||||
"CS5800i, CS6800i, WLW176i, WLW186i",boiler,8,dhw.ecoplusoff,eco+ switch off,uint8 (>=48<=63),C,true,number.boiler_dhw_eco+_switch_off,number.boiler_dhw_ecoplusoff,5,9,1,20,1
|
||||
"CS5800i, CS6800i, WLW176i, WLW186i",boiler,8,dhw.comfdiff,comfort diff,uint8 (>=6<=12),K,true,number.boiler_dhw_comfort_diff,number.boiler_dhw_comfdiff,5,9,1,21,1
|
||||
"CS5800i, CS6800i, WLW176i, WLW186i",boiler,8,dhw.ecodiff,eco diff,uint8 (>=6<=12),K,true,number.boiler_dhw_eco_diff,number.boiler_dhw_ecodiff,5,9,1,22,1
|
||||
"CS5800i, CS6800i, WLW176i, WLW186i",boiler,8,dhw.comfdiff,comfort diff,uint8 (>=4<=12),K,true,number.boiler_dhw_comfort_diff,number.boiler_dhw_comfdiff,5,9,1,21,1
|
||||
"CS5800i, CS6800i, WLW176i, WLW186i",boiler,8,dhw.ecodiff,eco diff,uint8 (>=4<=12),K,true,number.boiler_dhw_eco_diff,number.boiler_dhw_ecodiff,5,9,1,22,1
|
||||
"CS5800i, CS6800i, WLW176i, WLW186i",boiler,8,dhw.ecoplusdiff,eco+ diff,uint8 (>=6<=12),K,true,number.boiler_dhw_eco+_diff,number.boiler_dhw_ecoplusdiff,5,9,1,23,1
|
||||
"CS5800i, CS6800i, WLW176i, WLW186i",boiler,8,dhw.comfstop,comfort stop temp,uint8 (>=0<=254),C,true,number.boiler_dhw_comfort_stop_temp,number.boiler_dhw_comfstop,5,9,1,24,1
|
||||
"CS5800i, CS6800i, WLW176i, WLW186i",boiler,8,dhw.ecostop,eco stop temp,uint8 (>=0<=254),C,true,number.boiler_dhw_eco_stop_temp,number.boiler_dhw_ecostop,5,9,1,25,1
|
||||
@@ -2668,8 +2668,8 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,dhw.comfoff,comfort switch off,uint8 (>=15<=65),C,true,number.boiler_dhw_comfort_switch_off,number.boiler_dhw_comfoff,5,9,1,18,1
|
||||
"Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,dhw.ecooff,eco switch off,uint8 (>=15<=65),C,true,number.boiler_dhw_eco_switch_off,number.boiler_dhw_ecooff,5,9,1,19,1
|
||||
"Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,dhw.ecoplusoff,eco+ switch off,uint8 (>=48<=63),C,true,number.boiler_dhw_eco+_switch_off,number.boiler_dhw_ecoplusoff,5,9,1,20,1
|
||||
"Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,dhw.comfdiff,comfort diff,uint8 (>=6<=12),K,true,number.boiler_dhw_comfort_diff,number.boiler_dhw_comfdiff,5,9,1,21,1
|
||||
"Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,dhw.ecodiff,eco diff,uint8 (>=6<=12),K,true,number.boiler_dhw_eco_diff,number.boiler_dhw_ecodiff,5,9,1,22,1
|
||||
"Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,dhw.comfdiff,comfort diff,uint8 (>=4<=12),K,true,number.boiler_dhw_comfort_diff,number.boiler_dhw_comfdiff,5,9,1,21,1
|
||||
"Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,dhw.ecodiff,eco diff,uint8 (>=4<=12),K,true,number.boiler_dhw_eco_diff,number.boiler_dhw_ecodiff,5,9,1,22,1
|
||||
"Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,dhw.ecoplusdiff,eco+ diff,uint8 (>=6<=12),K,true,number.boiler_dhw_eco+_diff,number.boiler_dhw_ecoplusdiff,5,9,1,23,1
|
||||
"Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,dhw.comfstop,comfort stop temp,uint8 (>=0<=254),C,true,number.boiler_dhw_comfort_stop_temp,number.boiler_dhw_comfstop,5,9,1,24,1
|
||||
"Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,dhw.ecostop,eco stop temp,uint8 (>=0<=254),C,true,number.boiler_dhw_eco_stop_temp,number.boiler_dhw_ecostop,5,9,1,25,1
|
||||
@@ -2876,8 +2876,8 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"Geo 5xx",boiler,173,dhw.comfoff,comfort switch off,uint8 (>=15<=65),C,true,number.boiler_dhw_comfort_switch_off,number.boiler_dhw_comfoff,5,9,1,18,1
|
||||
"Geo 5xx",boiler,173,dhw.ecooff,eco switch off,uint8 (>=15<=65),C,true,number.boiler_dhw_eco_switch_off,number.boiler_dhw_ecooff,5,9,1,19,1
|
||||
"Geo 5xx",boiler,173,dhw.ecoplusoff,eco+ switch off,uint8 (>=48<=63),C,true,number.boiler_dhw_eco+_switch_off,number.boiler_dhw_ecoplusoff,5,9,1,20,1
|
||||
"Geo 5xx",boiler,173,dhw.comfdiff,comfort diff,uint8 (>=6<=12),K,true,number.boiler_dhw_comfort_diff,number.boiler_dhw_comfdiff,5,9,1,21,1
|
||||
"Geo 5xx",boiler,173,dhw.ecodiff,eco diff,uint8 (>=6<=12),K,true,number.boiler_dhw_eco_diff,number.boiler_dhw_ecodiff,5,9,1,22,1
|
||||
"Geo 5xx",boiler,173,dhw.comfdiff,comfort diff,uint8 (>=4<=12),K,true,number.boiler_dhw_comfort_diff,number.boiler_dhw_comfdiff,5,9,1,21,1
|
||||
"Geo 5xx",boiler,173,dhw.ecodiff,eco diff,uint8 (>=4<=12),K,true,number.boiler_dhw_eco_diff,number.boiler_dhw_ecodiff,5,9,1,22,1
|
||||
"Geo 5xx",boiler,173,dhw.ecoplusdiff,eco+ diff,uint8 (>=6<=12),K,true,number.boiler_dhw_eco+_diff,number.boiler_dhw_ecoplusdiff,5,9,1,23,1
|
||||
"Geo 5xx",boiler,173,dhw.comfstop,comfort stop temp,uint8 (>=0<=254),C,true,number.boiler_dhw_comfort_stop_temp,number.boiler_dhw_comfstop,5,9,1,24,1
|
||||
"Geo 5xx",boiler,173,dhw.ecostop,eco stop temp,uint8 (>=0<=254),C,true,number.boiler_dhw_eco_stop_temp,number.boiler_dhw_ecostop,5,9,1,25,1
|
||||
@@ -3914,17 +3914,18 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"UI800, BC400",thermostat,4,hc1.solarinfl,solar influence,uint8 (>=-5<=4294967295),C,true,number.thermostat_hc1_solar_influence,number.thermostat_hc1_solarinfl,6,1,1,54,1
|
||||
"UI800, BC400",thermostat,4,hc1.currsolarinfl,curent solar influence,uint8 (>=0<=25),C,false,sensor.thermostat_hc1_curent_solar_influence,sensor.thermostat_hc1_currsolarinfl,6,1,1/10,55,1
|
||||
"UI800, BC400",thermostat,4,dhw.mode,operating mode,enum [off\|eco+\|eco\|comfort\|auto], ,true,select.thermostat_dhw_operating_mode,select.thermostat_dhw_mode,6,9,1,0,1
|
||||
"UI800, BC400",thermostat,4,dhw.settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp,6,9,1,1,1
|
||||
"UI800, BC400",thermostat,4,dhw.settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow,6,9,1,2,1
|
||||
"UI800, BC400",thermostat,4,dhw.circmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode,6,9,1,3,1
|
||||
"UI800, BC400",thermostat,4,dhw.chargeduration,charge duration,uint8 (>=0<=3810),minutes,true,number.thermostat_dhw_charge_duration,number.thermostat_dhw_chargeduration,6,9,15,4,1
|
||||
"UI800, BC400",thermostat,4,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1
|
||||
"UI800, BC400",thermostat,4,dhw.extra,extra,boolean, ,false,binary_sensor.thermostat_dhw_extra,binary_sensor.thermostat_dhw_extra,6,9,1,6,1
|
||||
"UI800, BC400",thermostat,4,dhw.disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,7,1
|
||||
"UI800, BC400",thermostat,4,dhw.disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday,6,9,1,8,1
|
||||
"UI800, BC400",thermostat,4,dhw.disinfecttime,disinfection time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_disinfection_time,number.thermostat_dhw_disinfecttime,6,9,15,9,1
|
||||
"UI800, BC400",thermostat,4,dhw.dailyheating,daily heating,boolean, ,true,switch.thermostat_dhw_daily_heating,switch.thermostat_dhw_dailyheating,6,9,1,10,1
|
||||
"UI800, BC400",thermostat,4,dhw.dailyheattime,daily heating time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_daily_heating_time,number.thermostat_dhw_dailyheattime,6,9,15,11,1
|
||||
"UI800, BC400",thermostat,4,dhw.modetype,mode type,enum [off\|eco\|comfort\|eco+], ,false,sensor.thermostat_dhw_mode_type,sensor.thermostat_dhw_modetype,6,9,1,1,1
|
||||
"UI800, BC400",thermostat,4,dhw.settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp,6,9,1,2,1
|
||||
"UI800, BC400",thermostat,4,dhw.settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow,6,9,1,3,1
|
||||
"UI800, BC400",thermostat,4,dhw.circmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode,6,9,1,4,1
|
||||
"UI800, BC400",thermostat,4,dhw.chargeduration,charge duration,uint8 (>=0<=3810),minutes,true,number.thermostat_dhw_charge_duration,number.thermostat_dhw_chargeduration,6,9,15,5,1
|
||||
"UI800, BC400",thermostat,4,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,6,1
|
||||
"UI800, BC400",thermostat,4,dhw.extra,extra,boolean, ,false,binary_sensor.thermostat_dhw_extra,binary_sensor.thermostat_dhw_extra,6,9,1,7,1
|
||||
"UI800, BC400",thermostat,4,dhw.disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,8,1
|
||||
"UI800, BC400",thermostat,4,dhw.disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday,6,9,1,9,1
|
||||
"UI800, BC400",thermostat,4,dhw.disinfecttime,disinfection time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_disinfection_time,number.thermostat_dhw_disinfecttime,6,9,15,10,1
|
||||
"UI800, BC400",thermostat,4,dhw.dailyheating,daily heating,boolean, ,true,switch.thermostat_dhw_daily_heating,switch.thermostat_dhw_dailyheating,6,9,1,11,1
|
||||
"UI800, BC400",thermostat,4,dhw.dailyheattime,daily heating time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_daily_heating_time,number.thermostat_dhw_dailyheattime,6,9,15,12,1
|
||||
"CR11",thermostat,10,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8
|
||||
"CR11",thermostat,10,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25
|
||||
"CR11",thermostat,10,hc1.seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp,6,1,1/2,0,1
|
||||
@@ -4004,18 +4005,18 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"RC30",thermostat,67,hc1.switchtime1,own1 program switchtime,string, ,true,sensor.thermostat_hc1_own1_program_switchtime,sensor.thermostat_hc1_switchtime1,6,1,1,91,8
|
||||
"RC30",thermostat,67,hc1.switchtime2,own2 program switchtime,string, ,true,sensor.thermostat_hc1_own2_program_switchtime,sensor.thermostat_hc1_switchtime2,6,1,1,99,8
|
||||
"RC30",thermostat,67,dhw.mode,operating mode,enum [off\|on\|auto], ,true,select.thermostat_dhw_operating_mode,select.thermostat_dhw_mode,6,9,1,0,1
|
||||
"RC30",thermostat,67,dhw.circmode,circulation pump mode,enum [off\|on\|auto], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode,6,9,1,3,1
|
||||
"RC30",thermostat,67,dhw.progmode,program,enum [std prog\|own prog], ,true,select.thermostat_dhw_program,select.thermostat_dhw_progmode,6,9,1,12,1
|
||||
"RC30",thermostat,67,dhw.circprog,circulation program,enum [std prog\|own prog], ,true,select.thermostat_dhw_circulation_program,select.thermostat_dhw_circprog,6,9,1,13,1
|
||||
"RC30",thermostat,67,dhw.disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,7,1
|
||||
"RC30",thermostat,67,dhw.disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday,6,9,1,8,1
|
||||
"RC30",thermostat,67,dhw.disinfecthour,disinfection hour,uint8 (>=0<=23), ,true,number.thermostat_dhw_disinfection_hour,number.thermostat_dhw_disinfecthour,6,9,1,14,1
|
||||
"RC30",thermostat,67,dhw.maxtemp,maximum temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_maximum_temperature,number.thermostat_dhw_maxtemp,6,9,1,15,1
|
||||
"RC30",thermostat,67,dhw.onetimekey,one time key function,boolean, ,true,switch.thermostat_dhw_one_time_key_function,switch.thermostat_dhw_onetimekey,6,9,1,16,1
|
||||
"RC30",thermostat,67,dhw.switchtime,program switchtime,string, ,true,sensor.thermostat_dhw_program_switchtime,sensor.thermostat_dhw_switchtime,6,9,1,17,8
|
||||
"RC30",thermostat,67,dhw.circswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_dhw_circulation_program_switchtime,sensor.thermostat_dhw_circswitchtime,6,9,1,25,8
|
||||
"RC30",thermostat,67,dhw.holidays,holiday dates,string, ,true,sensor.thermostat_dhw_holiday_dates,sensor.thermostat_dhw_holidays,6,9,1,33,13
|
||||
"RC30",thermostat,67,dhw.vacations,vacation dates,string, ,true,sensor.thermostat_dhw_vacation_dates,sensor.thermostat_dhw_vacations,6,9,1,46,13
|
||||
"RC30",thermostat,67,dhw.circmode,circulation pump mode,enum [off\|on\|auto], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode,6,9,1,4,1
|
||||
"RC30",thermostat,67,dhw.progmode,program,enum [std prog\|own prog], ,true,select.thermostat_dhw_program,select.thermostat_dhw_progmode,6,9,1,13,1
|
||||
"RC30",thermostat,67,dhw.circprog,circulation program,enum [std prog\|own prog], ,true,select.thermostat_dhw_circulation_program,select.thermostat_dhw_circprog,6,9,1,14,1
|
||||
"RC30",thermostat,67,dhw.disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,8,1
|
||||
"RC30",thermostat,67,dhw.disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday,6,9,1,9,1
|
||||
"RC30",thermostat,67,dhw.disinfecthour,disinfection hour,uint8 (>=0<=23), ,true,number.thermostat_dhw_disinfection_hour,number.thermostat_dhw_disinfecthour,6,9,1,15,1
|
||||
"RC30",thermostat,67,dhw.maxtemp,maximum temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_maximum_temperature,number.thermostat_dhw_maxtemp,6,9,1,16,1
|
||||
"RC30",thermostat,67,dhw.onetimekey,one time key function,boolean, ,true,switch.thermostat_dhw_one_time_key_function,switch.thermostat_dhw_onetimekey,6,9,1,17,1
|
||||
"RC30",thermostat,67,dhw.switchtime,program switchtime,string, ,true,sensor.thermostat_dhw_program_switchtime,sensor.thermostat_dhw_switchtime,6,9,1,18,8
|
||||
"RC30",thermostat,67,dhw.circswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_dhw_circulation_program_switchtime,sensor.thermostat_dhw_circswitchtime,6,9,1,26,8
|
||||
"RC30",thermostat,67,dhw.holidays,holiday dates,string, ,true,sensor.thermostat_dhw_holiday_dates,sensor.thermostat_dhw_holidays,6,9,1,34,13
|
||||
"RC30",thermostat,67,dhw.vacations,vacation dates,string, ,true,sensor.thermostat_dhw_vacation_dates,sensor.thermostat_dhw_vacations,6,9,1,47,13
|
||||
"RC20, Moduline 300",thermostat,77,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8
|
||||
"RC20, Moduline 300",thermostat,77,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25
|
||||
"RC20, Moduline 300",thermostat,77,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13
|
||||
@@ -4068,10 +4069,10 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"Moduline 400",thermostat,78,hc1.manualtemp,manual temperature,uint8 (>=0<=127),C,true,number.thermostat_hc1_manual_temperature,number.thermostat_hc1_manualtemp,6,1,1/2,6,1
|
||||
"Moduline 400",thermostat,78,hc1.offtemp,temperature when mode is off,uint8 (>=0<=127),C,true,number.thermostat_hc1_temperature_when_mode_is_off,number.thermostat_hc1_offtemp,6,1,1/2,107,1
|
||||
"Moduline 400",thermostat,78,dhw.mode,operating mode,enum [on\|off\|auto], ,true,select.thermostat_dhw_operating_mode,select.thermostat_dhw_mode,6,9,1,0,1
|
||||
"Moduline 400",thermostat,78,dhw.whenmodeoff,when thermostat mode off,boolean, ,true,switch.thermostat_dhw_when_thermostat_mode_off,switch.thermostat_dhw_whenmodeoff,6,9,1,59,1
|
||||
"Moduline 400",thermostat,78,dhw.disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,7,1
|
||||
"Moduline 400",thermostat,78,dhw.disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday,6,9,1,8,1
|
||||
"Moduline 400",thermostat,78,dhw.disinfecthour,disinfection hour,uint8 (>=0<=23), ,true,number.thermostat_dhw_disinfection_hour,number.thermostat_dhw_disinfecthour,6,9,1,14,1
|
||||
"Moduline 400",thermostat,78,dhw.whenmodeoff,when thermostat mode off,boolean, ,true,switch.thermostat_dhw_when_thermostat_mode_off,switch.thermostat_dhw_whenmodeoff,6,9,1,60,1
|
||||
"Moduline 400",thermostat,78,dhw.disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,8,1
|
||||
"Moduline 400",thermostat,78,dhw.disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday,6,9,1,9,1
|
||||
"Moduline 400",thermostat,78,dhw.disinfecthour,disinfection hour,uint8 (>=0<=23), ,true,number.thermostat_dhw_disinfection_hour,number.thermostat_dhw_disinfecthour,6,9,1,15,1
|
||||
"RC10, Moduline 100",thermostat,79,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8
|
||||
"RC10, Moduline 100",thermostat,79,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25
|
||||
"RC10, Moduline 100",thermostat,79,intoffset,internal temperature offset,int8 (>=-12<=12),C,true,number.thermostat_internal_temperature_offset,number.thermostat_intoffset,6,0,1/10,46,1
|
||||
@@ -4150,18 +4151,18 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"RC35",thermostat,86,hc1.switchtime1,own1 program switchtime,string, ,true,sensor.thermostat_hc1_own1_program_switchtime,sensor.thermostat_hc1_switchtime1,6,1,1,91,8
|
||||
"RC35",thermostat,86,hc1.switchtime2,own2 program switchtime,string, ,true,sensor.thermostat_hc1_own2_program_switchtime,sensor.thermostat_hc1_switchtime2,6,1,1,99,8
|
||||
"RC35",thermostat,86,dhw.mode,operating mode,enum [off\|on\|auto], ,true,select.thermostat_dhw_operating_mode,select.thermostat_dhw_mode,6,9,1,0,1
|
||||
"RC35",thermostat,86,dhw.circmode,circulation pump mode,enum [off\|on\|auto], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode,6,9,1,3,1
|
||||
"RC35",thermostat,86,dhw.progmode,program,enum [std prog\|own prog], ,true,select.thermostat_dhw_program,select.thermostat_dhw_progmode,6,9,1,12,1
|
||||
"RC35",thermostat,86,dhw.circprog,circulation program,enum [std prog\|own prog], ,true,select.thermostat_dhw_circulation_program,select.thermostat_dhw_circprog,6,9,1,13,1
|
||||
"RC35",thermostat,86,dhw.disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,7,1
|
||||
"RC35",thermostat,86,dhw.disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday,6,9,1,8,1
|
||||
"RC35",thermostat,86,dhw.disinfecthour,disinfection hour,uint8 (>=0<=23), ,true,number.thermostat_dhw_disinfection_hour,number.thermostat_dhw_disinfecthour,6,9,1,14,1
|
||||
"RC35",thermostat,86,dhw.maxtemp,maximum temperature,uint8 (>=60<=80),C,true,number.thermostat_dhw_maximum_temperature,number.thermostat_dhw_maxtemp,6,9,1,15,1
|
||||
"RC35",thermostat,86,dhw.onetimekey,one time key function,boolean, ,true,switch.thermostat_dhw_one_time_key_function,switch.thermostat_dhw_onetimekey,6,9,1,16,1
|
||||
"RC35",thermostat,86,dhw.switchtime,program switchtime,string, ,true,sensor.thermostat_dhw_program_switchtime,sensor.thermostat_dhw_switchtime,6,9,1,17,8
|
||||
"RC35",thermostat,86,dhw.circswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_dhw_circulation_program_switchtime,sensor.thermostat_dhw_circswitchtime,6,9,1,25,8
|
||||
"RC35",thermostat,86,dhw.holidays,holiday dates,string, ,true,sensor.thermostat_dhw_holiday_dates,sensor.thermostat_dhw_holidays,6,9,1,33,13
|
||||
"RC35",thermostat,86,dhw.vacations,vacation dates,string, ,true,sensor.thermostat_dhw_vacation_dates,sensor.thermostat_dhw_vacations,6,9,1,46,13
|
||||
"RC35",thermostat,86,dhw.circmode,circulation pump mode,enum [off\|on\|auto], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode,6,9,1,4,1
|
||||
"RC35",thermostat,86,dhw.progmode,program,enum [std prog\|own prog], ,true,select.thermostat_dhw_program,select.thermostat_dhw_progmode,6,9,1,13,1
|
||||
"RC35",thermostat,86,dhw.circprog,circulation program,enum [std prog\|own prog], ,true,select.thermostat_dhw_circulation_program,select.thermostat_dhw_circprog,6,9,1,14,1
|
||||
"RC35",thermostat,86,dhw.disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,8,1
|
||||
"RC35",thermostat,86,dhw.disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday,6,9,1,9,1
|
||||
"RC35",thermostat,86,dhw.disinfecthour,disinfection hour,uint8 (>=0<=23), ,true,number.thermostat_dhw_disinfection_hour,number.thermostat_dhw_disinfecthour,6,9,1,15,1
|
||||
"RC35",thermostat,86,dhw.maxtemp,maximum temperature,uint8 (>=60<=80),C,true,number.thermostat_dhw_maximum_temperature,number.thermostat_dhw_maxtemp,6,9,1,16,1
|
||||
"RC35",thermostat,86,dhw.onetimekey,one time key function,boolean, ,true,switch.thermostat_dhw_one_time_key_function,switch.thermostat_dhw_onetimekey,6,9,1,17,1
|
||||
"RC35",thermostat,86,dhw.switchtime,program switchtime,string, ,true,sensor.thermostat_dhw_program_switchtime,sensor.thermostat_dhw_switchtime,6,9,1,18,8
|
||||
"RC35",thermostat,86,dhw.circswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_dhw_circulation_program_switchtime,sensor.thermostat_dhw_circswitchtime,6,9,1,26,8
|
||||
"RC35",thermostat,86,dhw.holidays,holiday dates,string, ,true,sensor.thermostat_dhw_holiday_dates,sensor.thermostat_dhw_holidays,6,9,1,34,13
|
||||
"RC35",thermostat,86,dhw.vacations,vacation dates,string, ,true,sensor.thermostat_dhw_vacation_dates,sensor.thermostat_dhw_vacations,6,9,1,47,13
|
||||
"RC10, Moduline 100",thermostat,90,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8
|
||||
"RC10, Moduline 100",thermostat,90,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25
|
||||
"RC10, Moduline 100",thermostat,90,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13
|
||||
@@ -4296,17 +4297,18 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,hc1.solarinfl,solar influence,uint8 (>=-5<=4294967295),C,true,number.thermostat_hc1_solar_influence,number.thermostat_hc1_solarinfl,6,1,1,54,1
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,hc1.currsolarinfl,curent solar influence,uint8 (>=0<=25),C,false,sensor.thermostat_hc1_curent_solar_influence,sensor.thermostat_hc1_currsolarinfl,6,1,1/10,55,1
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,dhw.mode,operating mode,enum [off\|on\|auto], ,true,select.thermostat_dhw_operating_mode,select.thermostat_dhw_mode,6,9,1,0,1
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,dhw.settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp,6,9,1,1,1
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,dhw.settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow,6,9,1,2,1
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,dhw.circmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode,6,9,1,3,1
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,dhw.chargeduration,charge duration,uint8 (>=0<=3810),minutes,true,number.thermostat_dhw_charge_duration,number.thermostat_dhw_chargeduration,6,9,15,4,1
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,dhw.extra,extra,boolean, ,false,binary_sensor.thermostat_dhw_extra,binary_sensor.thermostat_dhw_extra,6,9,1,6,1
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,dhw.disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,7,1
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,dhw.disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday,6,9,1,8,1
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,dhw.disinfecttime,disinfection time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_disinfection_time,number.thermostat_dhw_disinfecttime,6,9,15,9,1
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,dhw.dailyheating,daily heating,boolean, ,true,switch.thermostat_dhw_daily_heating,switch.thermostat_dhw_dailyheating,6,9,1,10,1
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,dhw.dailyheattime,daily heating time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_daily_heating_time,number.thermostat_dhw_dailyheattime,6,9,15,11,1
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,dhw.modetype,mode type,enum [off\|eco\|comfort\|eco+], ,false,sensor.thermostat_dhw_mode_type,sensor.thermostat_dhw_modetype,6,9,1,1,1
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,dhw.settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp,6,9,1,2,1
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,dhw.settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow,6,9,1,3,1
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,dhw.circmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode,6,9,1,4,1
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,dhw.chargeduration,charge duration,uint8 (>=0<=3810),minutes,true,number.thermostat_dhw_charge_duration,number.thermostat_dhw_chargeduration,6,9,15,5,1
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,6,1
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,dhw.extra,extra,boolean, ,false,binary_sensor.thermostat_dhw_extra,binary_sensor.thermostat_dhw_extra,6,9,1,7,1
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,dhw.disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,8,1
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,dhw.disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday,6,9,1,9,1
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,dhw.disinfecttime,disinfection time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_disinfection_time,number.thermostat_dhw_disinfecttime,6,9,15,10,1
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,dhw.dailyheating,daily heating,boolean, ,true,switch.thermostat_dhw_daily_heating,switch.thermostat_dhw_dailyheating,6,9,1,11,1
|
||||
"RC200, CW100, CR120, CR50",thermostat,157,dhw.dailyheattime,daily heating time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_daily_heating_time,number.thermostat_dhw_dailyheattime,6,9,15,12,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13
|
||||
@@ -4386,17 +4388,18 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,hc1.solarinfl,solar influence,uint8 (>=-5<=4294967295),C,true,number.thermostat_hc1_solar_influence,number.thermostat_hc1_solarinfl,6,1,1,54,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,hc1.currsolarinfl,curent solar influence,uint8 (>=0<=25),C,false,sensor.thermostat_hc1_curent_solar_influence,sensor.thermostat_hc1_currsolarinfl,6,1,1/10,55,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,dhw.mode,operating mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_dhw_operating_mode,select.thermostat_dhw_mode,6,9,1,0,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,dhw.settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp,6,9,1,1,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,dhw.settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow,6,9,1,2,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,dhw.circmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode,6,9,1,3,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,dhw.chargeduration,charge duration,uint8 (>=0<=3810),minutes,true,number.thermostat_dhw_charge_duration,number.thermostat_dhw_chargeduration,6,9,15,4,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,dhw.extra,extra,boolean, ,false,binary_sensor.thermostat_dhw_extra,binary_sensor.thermostat_dhw_extra,6,9,1,6,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,dhw.disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,7,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,dhw.disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday,6,9,1,8,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,dhw.disinfecttime,disinfection time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_disinfection_time,number.thermostat_dhw_disinfecttime,6,9,15,9,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,dhw.dailyheating,daily heating,boolean, ,true,switch.thermostat_dhw_daily_heating,switch.thermostat_dhw_dailyheating,6,9,1,10,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,dhw.dailyheattime,daily heating time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_daily_heating_time,number.thermostat_dhw_dailyheattime,6,9,15,11,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,dhw.modetype,mode type,enum [off\|eco\|comfort\|eco+], ,false,sensor.thermostat_dhw_mode_type,sensor.thermostat_dhw_modetype,6,9,1,1,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,dhw.settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp,6,9,1,2,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,dhw.settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow,6,9,1,3,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,dhw.circmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode,6,9,1,4,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,dhw.chargeduration,charge duration,uint8 (>=0<=3810),minutes,true,number.thermostat_dhw_charge_duration,number.thermostat_dhw_chargeduration,6,9,15,5,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,6,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,dhw.extra,extra,boolean, ,false,binary_sensor.thermostat_dhw_extra,binary_sensor.thermostat_dhw_extra,6,9,1,7,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,dhw.disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,8,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,dhw.disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday,6,9,1,9,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,dhw.disinfecttime,disinfection time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_disinfection_time,number.thermostat_dhw_disinfecttime,6,9,15,10,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,dhw.dailyheating,daily heating,boolean, ,true,switch.thermostat_dhw_daily_heating,switch.thermostat_dhw_dailyheating,6,9,1,11,1
|
||||
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,dhw.dailyheattime,daily heating time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_daily_heating_time,number.thermostat_dhw_dailyheattime,6,9,15,12,1
|
||||
"RC100, CR10, Moduline 1000/1010",thermostat,165,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8
|
||||
"RC100, CR10, Moduline 1000/1010",thermostat,165,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25
|
||||
"RC100, CR10, Moduline 1000/1010",thermostat,165,hc1.seltemp,selected room temperature,int16 (>=0<=30),C,true,number.thermostat_hc1_selected_room_temperature,number.thermostat_hc1_seltemp,6,1,1/2,0,1
|
||||
@@ -4485,17 +4488,18 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"Rego 2000/3000",thermostat,172,hc1.solarinfl,solar influence,uint8 (>=-5<=4294967295),C,true,number.thermostat_hc1_solar_influence,number.thermostat_hc1_solarinfl,6,1,1,54,1
|
||||
"Rego 2000/3000",thermostat,172,hc1.currsolarinfl,curent solar influence,uint8 (>=0<=25),C,false,sensor.thermostat_hc1_curent_solar_influence,sensor.thermostat_hc1_currsolarinfl,6,1,1/10,55,1
|
||||
"Rego 2000/3000",thermostat,172,dhw.mode,operating mode,enum [normal\|comfort\|eco+], ,true,select.thermostat_dhw_operating_mode,select.thermostat_dhw_mode,6,9,1,0,1
|
||||
"Rego 2000/3000",thermostat,172,dhw.settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp,6,9,1,1,1
|
||||
"Rego 2000/3000",thermostat,172,dhw.settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow,6,9,1,2,1
|
||||
"Rego 2000/3000",thermostat,172,dhw.circmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode,6,9,1,3,1
|
||||
"Rego 2000/3000",thermostat,172,dhw.chargeduration,charge duration,uint8 (>=0<=3810),minutes,true,number.thermostat_dhw_charge_duration,number.thermostat_dhw_chargeduration,6,9,15,4,1
|
||||
"Rego 2000/3000",thermostat,172,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1
|
||||
"Rego 2000/3000",thermostat,172,dhw.extra,extra,boolean, ,false,binary_sensor.thermostat_dhw_extra,binary_sensor.thermostat_dhw_extra,6,9,1,6,1
|
||||
"Rego 2000/3000",thermostat,172,dhw.disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,7,1
|
||||
"Rego 2000/3000",thermostat,172,dhw.disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday,6,9,1,8,1
|
||||
"Rego 2000/3000",thermostat,172,dhw.disinfecttime,disinfection time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_disinfection_time,number.thermostat_dhw_disinfecttime,6,9,15,9,1
|
||||
"Rego 2000/3000",thermostat,172,dhw.dailyheating,daily heating,boolean, ,true,switch.thermostat_dhw_daily_heating,switch.thermostat_dhw_dailyheating,6,9,1,10,1
|
||||
"Rego 2000/3000",thermostat,172,dhw.dailyheattime,daily heating time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_daily_heating_time,number.thermostat_dhw_dailyheattime,6,9,15,11,1
|
||||
"Rego 2000/3000",thermostat,172,dhw.modetype,mode type,enum [off\|eco\|comfort\|eco+], ,false,sensor.thermostat_dhw_mode_type,sensor.thermostat_dhw_modetype,6,9,1,1,1
|
||||
"Rego 2000/3000",thermostat,172,dhw.settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp,6,9,1,2,1
|
||||
"Rego 2000/3000",thermostat,172,dhw.settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow,6,9,1,3,1
|
||||
"Rego 2000/3000",thermostat,172,dhw.circmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode,6,9,1,4,1
|
||||
"Rego 2000/3000",thermostat,172,dhw.chargeduration,charge duration,uint8 (>=0<=3810),minutes,true,number.thermostat_dhw_charge_duration,number.thermostat_dhw_chargeduration,6,9,15,5,1
|
||||
"Rego 2000/3000",thermostat,172,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,6,1
|
||||
"Rego 2000/3000",thermostat,172,dhw.extra,extra,boolean, ,false,binary_sensor.thermostat_dhw_extra,binary_sensor.thermostat_dhw_extra,6,9,1,7,1
|
||||
"Rego 2000/3000",thermostat,172,dhw.disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,8,1
|
||||
"Rego 2000/3000",thermostat,172,dhw.disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday,6,9,1,9,1
|
||||
"Rego 2000/3000",thermostat,172,dhw.disinfecttime,disinfection time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_disinfection_time,number.thermostat_dhw_disinfecttime,6,9,15,10,1
|
||||
"Rego 2000/3000",thermostat,172,dhw.dailyheating,daily heating,boolean, ,true,switch.thermostat_dhw_daily_heating,switch.thermostat_dhw_dailyheating,6,9,1,11,1
|
||||
"Rego 2000/3000",thermostat,172,dhw.dailyheattime,daily heating time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_daily_heating_time,number.thermostat_dhw_dailyheattime,6,9,15,12,1
|
||||
"Comfort RF",thermostat,215,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8
|
||||
"Comfort RF",thermostat,215,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25
|
||||
"Comfort RF",thermostat,215,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13
|
||||
@@ -4602,17 +4606,18 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,hc1.solarinfl,solar influence,uint8 (>=-5<=4294967295),C,true,number.thermostat_hc1_solar_influence,number.thermostat_hc1_solarinfl,6,1,1,54,1
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,hc1.currsolarinfl,curent solar influence,uint8 (>=0<=25),C,false,sensor.thermostat_hc1_curent_solar_influence,sensor.thermostat_hc1_currsolarinfl,6,1,1/10,55,1
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,dhw.mode,operating mode,enum [off\|eco+\|eco\|comfort\|auto], ,true,select.thermostat_dhw_operating_mode,select.thermostat_dhw_mode,6,9,1,0,1
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,dhw.settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp,6,9,1,1,1
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,dhw.settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow,6,9,1,2,1
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,dhw.circmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode,6,9,1,3,1
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,dhw.chargeduration,charge duration,uint8 (>=0<=3810),minutes,true,number.thermostat_dhw_charge_duration,number.thermostat_dhw_chargeduration,6,9,15,4,1
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,dhw.extra,extra,boolean, ,false,binary_sensor.thermostat_dhw_extra,binary_sensor.thermostat_dhw_extra,6,9,1,6,1
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,dhw.disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,7,1
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,dhw.disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday,6,9,1,8,1
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,dhw.disinfecttime,disinfection time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_disinfection_time,number.thermostat_dhw_disinfecttime,6,9,15,9,1
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,dhw.dailyheating,daily heating,boolean, ,true,switch.thermostat_dhw_daily_heating,switch.thermostat_dhw_dailyheating,6,9,1,10,1
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,dhw.dailyheattime,daily heating time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_daily_heating_time,number.thermostat_dhw_dailyheattime,6,9,15,11,1
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,dhw.modetype,mode type,enum [off\|eco\|comfort\|eco+], ,false,sensor.thermostat_dhw_mode_type,sensor.thermostat_dhw_modetype,6,9,1,1,1
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,dhw.settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp,6,9,1,2,1
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,dhw.settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow,6,9,1,3,1
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,dhw.circmode,circulation pump mode,enum [off\|on\|auto\|own prog], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode,6,9,1,4,1
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,dhw.chargeduration,charge duration,uint8 (>=0<=3810),minutes,true,number.thermostat_dhw_charge_duration,number.thermostat_dhw_chargeduration,6,9,15,5,1
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,6,1
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,dhw.extra,extra,boolean, ,false,binary_sensor.thermostat_dhw_extra,binary_sensor.thermostat_dhw_extra,6,9,1,7,1
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,dhw.disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,8,1
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,dhw.disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday,6,9,1,9,1
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,dhw.disinfecttime,disinfection time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_disinfection_time,number.thermostat_dhw_disinfecttime,6,9,15,10,1
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,dhw.dailyheating,daily heating,boolean, ,true,switch.thermostat_dhw_daily_heating,switch.thermostat_dhw_dailyheating,6,9,1,11,1
|
||||
"Rego 3000, UI800, Logamatic BC400",thermostat,253,dhw.dailyheattime,daily heating time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_daily_heating_time,number.thermostat_dhw_dailyheattime,6,9,15,12,1
|
||||
"ES72, RC20",thermostat,66,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8
|
||||
"ES72, RC20",thermostat,66,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25
|
||||
"ES72, RC20",thermostat,66,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13
|
||||
@@ -4684,18 +4689,18 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"ES73",thermostat,76,hc1.switchtime1,own1 program switchtime,string, ,true,sensor.thermostat_hc1_own1_program_switchtime,sensor.thermostat_hc1_switchtime1,6,1,1,91,8
|
||||
"ES73",thermostat,76,hc1.switchtime2,own2 program switchtime,string, ,true,sensor.thermostat_hc1_own2_program_switchtime,sensor.thermostat_hc1_switchtime2,6,1,1,99,8
|
||||
"ES73",thermostat,76,dhw.mode,operating mode,enum [off\|on\|auto], ,true,select.thermostat_dhw_operating_mode,select.thermostat_dhw_mode,6,9,1,0,1
|
||||
"ES73",thermostat,76,dhw.circmode,circulation pump mode,enum [off\|on\|auto], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode,6,9,1,3,1
|
||||
"ES73",thermostat,76,dhw.progmode,program,enum [std prog\|own prog], ,true,select.thermostat_dhw_program,select.thermostat_dhw_progmode,6,9,1,12,1
|
||||
"ES73",thermostat,76,dhw.circprog,circulation program,enum [std prog\|own prog], ,true,select.thermostat_dhw_circulation_program,select.thermostat_dhw_circprog,6,9,1,13,1
|
||||
"ES73",thermostat,76,dhw.disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,7,1
|
||||
"ES73",thermostat,76,dhw.disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday,6,9,1,8,1
|
||||
"ES73",thermostat,76,dhw.disinfecthour,disinfection hour,uint8 (>=0<=23), ,true,number.thermostat_dhw_disinfection_hour,number.thermostat_dhw_disinfecthour,6,9,1,14,1
|
||||
"ES73",thermostat,76,dhw.maxtemp,maximum temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_maximum_temperature,number.thermostat_dhw_maxtemp,6,9,1,15,1
|
||||
"ES73",thermostat,76,dhw.onetimekey,one time key function,boolean, ,true,switch.thermostat_dhw_one_time_key_function,switch.thermostat_dhw_onetimekey,6,9,1,16,1
|
||||
"ES73",thermostat,76,dhw.switchtime,program switchtime,string, ,true,sensor.thermostat_dhw_program_switchtime,sensor.thermostat_dhw_switchtime,6,9,1,17,8
|
||||
"ES73",thermostat,76,dhw.circswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_dhw_circulation_program_switchtime,sensor.thermostat_dhw_circswitchtime,6,9,1,25,8
|
||||
"ES73",thermostat,76,dhw.holidays,holiday dates,string, ,true,sensor.thermostat_dhw_holiday_dates,sensor.thermostat_dhw_holidays,6,9,1,33,13
|
||||
"ES73",thermostat,76,dhw.vacations,vacation dates,string, ,true,sensor.thermostat_dhw_vacation_dates,sensor.thermostat_dhw_vacations,6,9,1,46,13
|
||||
"ES73",thermostat,76,dhw.circmode,circulation pump mode,enum [off\|on\|auto], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode,6,9,1,4,1
|
||||
"ES73",thermostat,76,dhw.progmode,program,enum [std prog\|own prog], ,true,select.thermostat_dhw_program,select.thermostat_dhw_progmode,6,9,1,13,1
|
||||
"ES73",thermostat,76,dhw.circprog,circulation program,enum [std prog\|own prog], ,true,select.thermostat_dhw_circulation_program,select.thermostat_dhw_circprog,6,9,1,14,1
|
||||
"ES73",thermostat,76,dhw.disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,8,1
|
||||
"ES73",thermostat,76,dhw.disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday,6,9,1,9,1
|
||||
"ES73",thermostat,76,dhw.disinfecthour,disinfection hour,uint8 (>=0<=23), ,true,number.thermostat_dhw_disinfection_hour,number.thermostat_dhw_disinfecthour,6,9,1,15,1
|
||||
"ES73",thermostat,76,dhw.maxtemp,maximum temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_maximum_temperature,number.thermostat_dhw_maxtemp,6,9,1,16,1
|
||||
"ES73",thermostat,76,dhw.onetimekey,one time key function,boolean, ,true,switch.thermostat_dhw_one_time_key_function,switch.thermostat_dhw_onetimekey,6,9,1,17,1
|
||||
"ES73",thermostat,76,dhw.switchtime,program switchtime,string, ,true,sensor.thermostat_dhw_program_switchtime,sensor.thermostat_dhw_switchtime,6,9,1,18,8
|
||||
"ES73",thermostat,76,dhw.circswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_dhw_circulation_program_switchtime,sensor.thermostat_dhw_circswitchtime,6,9,1,26,8
|
||||
"ES73",thermostat,76,dhw.holidays,holiday dates,string, ,true,sensor.thermostat_dhw_holiday_dates,sensor.thermostat_dhw_holidays,6,9,1,34,13
|
||||
"ES73",thermostat,76,dhw.vacations,vacation dates,string, ,true,sensor.thermostat_dhw_vacation_dates,sensor.thermostat_dhw_vacations,6,9,1,47,13
|
||||
"ES72, RC20",thermostat,113,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8
|
||||
"ES72, RC20",thermostat,113,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25
|
||||
"ES72, RC20",thermostat,113,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13
|
||||
@@ -4764,18 +4769,18 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"ES79",thermostat,156,hc1.switchtime1,own1 program switchtime,string, ,true,sensor.thermostat_hc1_own1_program_switchtime,sensor.thermostat_hc1_switchtime1,6,1,1,91,8
|
||||
"ES79",thermostat,156,hc1.switchtime2,own2 program switchtime,string, ,true,sensor.thermostat_hc1_own2_program_switchtime,sensor.thermostat_hc1_switchtime2,6,1,1,99,8
|
||||
"ES79",thermostat,156,dhw.mode,operating mode,enum [off\|on\|auto], ,true,select.thermostat_dhw_operating_mode,select.thermostat_dhw_mode,6,9,1,0,1
|
||||
"ES79",thermostat,156,dhw.circmode,circulation pump mode,enum [off\|on\|auto], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode,6,9,1,3,1
|
||||
"ES79",thermostat,156,dhw.progmode,program,enum [std prog\|own prog], ,true,select.thermostat_dhw_program,select.thermostat_dhw_progmode,6,9,1,12,1
|
||||
"ES79",thermostat,156,dhw.circprog,circulation program,enum [std prog\|own prog], ,true,select.thermostat_dhw_circulation_program,select.thermostat_dhw_circprog,6,9,1,13,1
|
||||
"ES79",thermostat,156,dhw.disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,7,1
|
||||
"ES79",thermostat,156,dhw.disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday,6,9,1,8,1
|
||||
"ES79",thermostat,156,dhw.disinfecthour,disinfection hour,uint8 (>=0<=23), ,true,number.thermostat_dhw_disinfection_hour,number.thermostat_dhw_disinfecthour,6,9,1,14,1
|
||||
"ES79",thermostat,156,dhw.maxtemp,maximum temperature,uint8 (>=60<=80),C,true,number.thermostat_dhw_maximum_temperature,number.thermostat_dhw_maxtemp,6,9,1,15,1
|
||||
"ES79",thermostat,156,dhw.onetimekey,one time key function,boolean, ,true,switch.thermostat_dhw_one_time_key_function,switch.thermostat_dhw_onetimekey,6,9,1,16,1
|
||||
"ES79",thermostat,156,dhw.switchtime,program switchtime,string, ,true,sensor.thermostat_dhw_program_switchtime,sensor.thermostat_dhw_switchtime,6,9,1,17,8
|
||||
"ES79",thermostat,156,dhw.circswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_dhw_circulation_program_switchtime,sensor.thermostat_dhw_circswitchtime,6,9,1,25,8
|
||||
"ES79",thermostat,156,dhw.holidays,holiday dates,string, ,true,sensor.thermostat_dhw_holiday_dates,sensor.thermostat_dhw_holidays,6,9,1,33,13
|
||||
"ES79",thermostat,156,dhw.vacations,vacation dates,string, ,true,sensor.thermostat_dhw_vacation_dates,sensor.thermostat_dhw_vacations,6,9,1,46,13
|
||||
"ES79",thermostat,156,dhw.circmode,circulation pump mode,enum [off\|on\|auto], ,true,select.thermostat_dhw_circulation_pump_mode,select.thermostat_dhw_circmode,6,9,1,4,1
|
||||
"ES79",thermostat,156,dhw.progmode,program,enum [std prog\|own prog], ,true,select.thermostat_dhw_program,select.thermostat_dhw_progmode,6,9,1,13,1
|
||||
"ES79",thermostat,156,dhw.circprog,circulation program,enum [std prog\|own prog], ,true,select.thermostat_dhw_circulation_program,select.thermostat_dhw_circprog,6,9,1,14,1
|
||||
"ES79",thermostat,156,dhw.disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,8,1
|
||||
"ES79",thermostat,156,dhw.disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|su\|all], ,true,select.thermostat_dhw_disinfection_day,select.thermostat_dhw_disinfectday,6,9,1,9,1
|
||||
"ES79",thermostat,156,dhw.disinfecthour,disinfection hour,uint8 (>=0<=23), ,true,number.thermostat_dhw_disinfection_hour,number.thermostat_dhw_disinfecthour,6,9,1,15,1
|
||||
"ES79",thermostat,156,dhw.maxtemp,maximum temperature,uint8 (>=60<=80),C,true,number.thermostat_dhw_maximum_temperature,number.thermostat_dhw_maxtemp,6,9,1,16,1
|
||||
"ES79",thermostat,156,dhw.onetimekey,one time key function,boolean, ,true,switch.thermostat_dhw_one_time_key_function,switch.thermostat_dhw_onetimekey,6,9,1,17,1
|
||||
"ES79",thermostat,156,dhw.switchtime,program switchtime,string, ,true,sensor.thermostat_dhw_program_switchtime,sensor.thermostat_dhw_switchtime,6,9,1,18,8
|
||||
"ES79",thermostat,156,dhw.circswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_dhw_circulation_program_switchtime,sensor.thermostat_dhw_circswitchtime,6,9,1,26,8
|
||||
"ES79",thermostat,156,dhw.holidays,holiday dates,string, ,true,sensor.thermostat_dhw_holiday_dates,sensor.thermostat_dhw_holidays,6,9,1,34,13
|
||||
"ES79",thermostat,156,dhw.vacations,vacation dates,string, ,true,sensor.thermostat_dhw_vacation_dates,sensor.thermostat_dhw_vacations,6,9,1,47,13
|
||||
"FW100",thermostat,105,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8
|
||||
"FW100",thermostat,105,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25
|
||||
"FW100",thermostat,105,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13
|
||||
@@ -4812,7 +4817,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"FW100",thermostat,105,hc1.roominflfactor,room influence factor,uint8 (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor,6,1,10,14,1
|
||||
"FW100",thermostat,105,hc1.heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype,6,1,1,19,1
|
||||
"FW100",thermostat,105,hc1.controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode,6,1,1,25,1
|
||||
"FW100",thermostat,105,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1
|
||||
"FW100",thermostat,105,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,6,1
|
||||
"FW200",thermostat,106,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8
|
||||
"FW200",thermostat,106,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25
|
||||
"FW200",thermostat,106,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13
|
||||
@@ -4849,7 +4854,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"FW200",thermostat,106,hc1.roominflfactor,room influence factor,uint8 (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor,6,1,10,14,1
|
||||
"FW200",thermostat,106,hc1.heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype,6,1,1,19,1
|
||||
"FW200",thermostat,106,hc1.controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode,6,1,1,25,1
|
||||
"FW200",thermostat,106,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1
|
||||
"FW200",thermostat,106,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,6,1
|
||||
"FR100",thermostat,107,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8
|
||||
"FR100",thermostat,107,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25
|
||||
"FR100",thermostat,107,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13
|
||||
@@ -4884,7 +4889,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"FR100",thermostat,107,hc1.roominflfactor,room influence factor,uint8 (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor,6,1,10,14,1
|
||||
"FR100",thermostat,107,hc1.heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype,6,1,1,19,1
|
||||
"FR100",thermostat,107,hc1.controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode,6,1,1,25,1
|
||||
"FR100",thermostat,107,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1
|
||||
"FR100",thermostat,107,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,6,1
|
||||
"FR110",thermostat,108,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8
|
||||
"FR110",thermostat,108,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25
|
||||
"FR110",thermostat,108,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13
|
||||
@@ -4919,7 +4924,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"FR110",thermostat,108,hc1.roominflfactor,room influence factor,uint8 (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor,6,1,10,14,1
|
||||
"FR110",thermostat,108,hc1.heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype,6,1,1,19,1
|
||||
"FR110",thermostat,108,hc1.controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode,6,1,1,25,1
|
||||
"FR110",thermostat,108,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1
|
||||
"FR110",thermostat,108,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,6,1
|
||||
"FB10",thermostat,109,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8
|
||||
"FB10",thermostat,109,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25
|
||||
"FB10",thermostat,109,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13
|
||||
@@ -4956,7 +4961,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"FB10",thermostat,109,hc1.roominflfactor,room influence factor,uint8 (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor,6,1,10,14,1
|
||||
"FB10",thermostat,109,hc1.heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype,6,1,1,19,1
|
||||
"FB10",thermostat,109,hc1.controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode,6,1,1,25,1
|
||||
"FB10",thermostat,109,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1
|
||||
"FB10",thermostat,109,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,6,1
|
||||
"FB100",thermostat,110,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8
|
||||
"FB100",thermostat,110,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25
|
||||
"FB100",thermostat,110,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13
|
||||
@@ -4993,7 +4998,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"FB100",thermostat,110,hc1.roominflfactor,room influence factor,uint8 (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor,6,1,10,14,1
|
||||
"FB100",thermostat,110,hc1.heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype,6,1,1,19,1
|
||||
"FB100",thermostat,110,hc1.controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode,6,1,1,25,1
|
||||
"FB100",thermostat,110,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1
|
||||
"FB100",thermostat,110,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,6,1
|
||||
"FR10",thermostat,111,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8
|
||||
"FR10",thermostat,111,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25
|
||||
"FR10",thermostat,111,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13
|
||||
@@ -5028,7 +5033,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"FR10",thermostat,111,hc1.roominflfactor,room influence factor,uint8 (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor,6,1,10,14,1
|
||||
"FR10",thermostat,111,hc1.heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype,6,1,1,19,1
|
||||
"FR10",thermostat,111,hc1.controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode,6,1,1,25,1
|
||||
"FR10",thermostat,111,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1
|
||||
"FR10",thermostat,111,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,6,1
|
||||
"FW500",thermostat,116,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8
|
||||
"FW500",thermostat,116,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25
|
||||
"FW500",thermostat,116,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13
|
||||
@@ -5065,7 +5070,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"FW500",thermostat,116,hc1.roominflfactor,room influence factor,uint8 (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor,6,1,10,14,1
|
||||
"FW500",thermostat,116,hc1.heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype,6,1,1,19,1
|
||||
"FW500",thermostat,116,hc1.controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode,6,1,1,25,1
|
||||
"FW500",thermostat,116,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1
|
||||
"FW500",thermostat,116,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,6,1
|
||||
"FR50",thermostat,147,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8
|
||||
"FR50",thermostat,147,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25
|
||||
"FR50",thermostat,147,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13
|
||||
@@ -5100,7 +5105,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"FR50",thermostat,147,hc1.roominflfactor,room influence factor,uint8 (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor,6,1,10,14,1
|
||||
"FR50",thermostat,147,hc1.heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype,6,1,1,19,1
|
||||
"FR50",thermostat,147,hc1.controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode,6,1,1,25,1
|
||||
"FR50",thermostat,147,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1
|
||||
"FR50",thermostat,147,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,6,1
|
||||
"FR120",thermostat,191,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8
|
||||
"FR120",thermostat,191,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25
|
||||
"FR120",thermostat,191,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13
|
||||
@@ -5135,7 +5140,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"FR120",thermostat,191,hc1.roominflfactor,room influence factor,uint8 (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor,6,1,10,14,1
|
||||
"FR120",thermostat,191,hc1.heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype,6,1,1,19,1
|
||||
"FR120",thermostat,191,hc1.controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode,6,1,1,25,1
|
||||
"FR120",thermostat,191,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1
|
||||
"FR120",thermostat,191,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,6,1
|
||||
"FW120",thermostat,192,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8
|
||||
"FW120",thermostat,192,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25
|
||||
"FW120",thermostat,192,datetime,date/time,string, ,true,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13
|
||||
@@ -5172,7 +5177,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"FW120",thermostat,192,hc1.roominflfactor,room influence factor,uint8 (>=0<=100),%,true,number.thermostat_hc1_room_influence_factor,number.thermostat_hc1_roominflfactor,6,1,10,14,1
|
||||
"FW120",thermostat,192,hc1.heatingtype,heating type,enum [off\|heatingcurve\|radiator\|convector\|floor], ,true,select.thermostat_hc1_heating_type,select.thermostat_hc1_heatingtype,6,1,1,19,1
|
||||
"FW120",thermostat,192,hc1.controlmode,control mode,enum [off\|unmixed\|unmixed IPM\|mixed IPM], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode,6,1,1,25,1
|
||||
"FW120",thermostat,192,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1
|
||||
"FW120",thermostat,192,dhw.charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,6,1
|
||||
"RT800, RC220",thermostat,3,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8
|
||||
"RT800, RC220",thermostat,3,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25
|
||||
"RT800, RC220",thermostat,3,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13
|
||||
@@ -5621,6 +5626,8 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
|
||||
"WM10",switch,71,flowtemphc,flow temperature (TC1),uint16 (>=0<=3199),C,false,sensor.switch_flow_temperature_(TC1),sensor.switch_flowtemphc,11,0,1/10,1,1
|
||||
"WM10",switch,71,status,status,int8 (>=-126<=126), ,false,sensor.switch_status,sensor.switch_status,11,0,1,2,1
|
||||
"Rego 3000",controller,240,datetime,date/time,string, ,false,sensor.controller_date/time,sensor.controller_datetime,12,0,1,0,13
|
||||
"MX400",connect,17,datetime,date/time,string, ,false,sensor.connect_date/time,sensor.connect_datetime,13,0,1,0,13
|
||||
"MX400",connect,17,outdoortemp,outside temperature,int16 (>=-3199<=3199),C,false,sensor.connect_outside_temperature,sensor.connect_outdoortemp,13,0,1/10,13,1
|
||||
"EM10",alert,74,setflowtemp,set flow temperature,uint8 (>=0<=254),C,false,sensor.alert_set_flow_temperature,sensor.alert_setflowtemp,14,0,1,0,1
|
||||
"EM10",alert,74,setburnpow,burner set power,uint8 (>=0<=100),%,false,sensor.alert_burner_set_power,sensor.alert_setburnpow,14,0,1,1,1
|
||||
"EM10, EM100",extension,243,flowtempvf,flow temperature in header (T0/Vf),int16 (>=-3199<=3199),C,false,sensor.extension_flow_temperature_in_header_(T0/Vf),sensor.extension_flowtempvf,15,0,1/10,0,1
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -10,8 +10,7 @@ export default tseslint.config(
|
||||
{
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
project: true,
|
||||
tsconfigRootDir: import.meta.dirname
|
||||
project: true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "EMS-ESP",
|
||||
"version": "3.7.2",
|
||||
"version": "3.7.3",
|
||||
"description": "EMS-ESP WebUI",
|
||||
"homepage": "https://emsesp.org",
|
||||
"author": "proddy, emsesp.org",
|
||||
@@ -63,5 +63,5 @@
|
||||
"vite-plugin-imagemin": "^0.6.1",
|
||||
"vite-tsconfig-paths": "^5.1.4"
|
||||
},
|
||||
"packageManager": "pnpm@10.19.0"
|
||||
"packageManager": "pnpm@10.19.0+sha512.c9fc7236e92adf5c8af42fd5bf1612df99c2ceb62f27047032f4720b33f8eacdde311865e91c411f2774f618d82f320808ecb51718bfa82c060c4ba7c76a32b8"
|
||||
}
|
||||
|
||||
8
interface/pnpm-lock.yaml
generated
8
interface/pnpm-lock.yaml
generated
@@ -1324,8 +1324,8 @@ packages:
|
||||
duplexer3@0.1.5:
|
||||
resolution: {integrity: sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==}
|
||||
|
||||
electron-to-chromium@1.5.238:
|
||||
resolution: {integrity: sha512-khBdc+w/Gv+cS8e/Pbnaw/FXcBUeKrRVik9IxfXtgREOWyJhR4tj43n3amkVogJ/yeQUqzkrZcFhtIxIdqmmcQ==}
|
||||
electron-to-chromium@1.5.239:
|
||||
resolution: {integrity: sha512-1y5w0Zsq39MSPmEjHjbizvhYoTaulVtivpxkp5q5kaPmQtsK6/2nvAzGRxNMS9DoYySp9PkW0MAQDwU1m764mg==}
|
||||
|
||||
emoji-regex@8.0.0:
|
||||
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
|
||||
@@ -3995,7 +3995,7 @@ snapshots:
|
||||
dependencies:
|
||||
baseline-browser-mapping: 2.8.19
|
||||
caniuse-lite: 1.0.30001751
|
||||
electron-to-chromium: 1.5.238
|
||||
electron-to-chromium: 1.5.239
|
||||
node-releases: 2.0.26
|
||||
update-browserslist-db: 1.1.4(browserslist@4.27.0)
|
||||
|
||||
@@ -4340,7 +4340,7 @@ snapshots:
|
||||
|
||||
duplexer3@0.1.5: {}
|
||||
|
||||
electron-to-chromium@1.5.238: {}
|
||||
electron-to-chromium@1.5.239: {}
|
||||
|
||||
emoji-regex@8.0.0: {}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
existsSync,
|
||||
readFileSync,
|
||||
readdirSync,
|
||||
statSync,
|
||||
unlinkSync
|
||||
} from 'fs';
|
||||
import mime from 'mime-types';
|
||||
@@ -15,67 +16,79 @@ const INDENT = ' ';
|
||||
const outputPath = '../src/ESP32React/WWWData.h';
|
||||
const sourcePath = './dist';
|
||||
const bytesPerLine = 20;
|
||||
var totalSize = 0;
|
||||
let totalSize = 0;
|
||||
let bundleStats = {
|
||||
js: { count: 0, uncompressed: 0, compressed: 0 },
|
||||
css: { count: 0, uncompressed: 0, compressed: 0 },
|
||||
html: { count: 0, uncompressed: 0, compressed: 0 },
|
||||
svg: { count: 0, uncompressed: 0, compressed: 0 },
|
||||
other: { count: 0, uncompressed: 0, compressed: 0 }
|
||||
};
|
||||
|
||||
const generateWWWClass = () =>
|
||||
`typedef std::function<void(const char * uri, const String & contentType, const uint8_t * content, size_t len, const String & hash)> RouteRegistrationHandler;
|
||||
// Total size is ${totalSize} bytes
|
||||
const generateWWWClass =
|
||||
() => `typedef std::function<void(const char * uri, const String & contentType, const uint8_t * content, size_t len, const String & hash)> RouteRegistrationHandler;
|
||||
// Bundle Statistics:
|
||||
// - Total compressed size: ${(totalSize / 1000).toFixed(1)} KB
|
||||
// - Total uncompressed size: ${(Object.values(bundleStats).reduce((sum, stat) => sum + stat.uncompressed, 0) / 1000).toFixed(1)} KB
|
||||
// - Compression ratio: ${(((Object.values(bundleStats).reduce((sum, stat) => sum + stat.uncompressed, 0) - totalSize) / Object.values(bundleStats).reduce((sum, stat) => sum + stat.uncompressed, 0)) * 100).toFixed(1)}%
|
||||
// - Generated on: ${new Date().toISOString()}
|
||||
|
||||
class WWWData {
|
||||
${indent}public:
|
||||
${indent.repeat(2)}static void registerRoutes(RouteRegistrationHandler handler) {
|
||||
${fileInfo.map((file) => `${indent.repeat(3)}handler("${file.uri}", "${file.mimeType}", ${file.variable}, ${file.size}, "${file.hash}");`).join('\n')}
|
||||
${indent.repeat(2)}}
|
||||
${INDENT}public:
|
||||
${INDENT.repeat(2)}static void registerRoutes(RouteRegistrationHandler handler) {
|
||||
${fileInfo.map((f) => `${INDENT.repeat(3)}handler("${f.uri}", "${f.mimeType}", ${f.variable}, ${f.size}, "${f.hash}");`).join('\n')}
|
||||
${INDENT.repeat(2)}}
|
||||
};
|
||||
`;
|
||||
|
||||
function getFilesSync(dir, files = []) {
|
||||
const getFilesSync = (dir, files = []) => {
|
||||
readdirSync(dir, { withFileTypes: true }).forEach((entry) => {
|
||||
const entryPath = resolve(dir, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
getFilesSync(entryPath, files);
|
||||
} else {
|
||||
files.push(entryPath);
|
||||
}
|
||||
entry.isDirectory() ? getFilesSync(entryPath, files) : files.push(entryPath);
|
||||
});
|
||||
return files;
|
||||
}
|
||||
};
|
||||
|
||||
function cleanAndOpen(path) {
|
||||
if (existsSync(path)) {
|
||||
unlinkSync(path);
|
||||
}
|
||||
const cleanAndOpen = (path) => {
|
||||
existsSync(path) && unlinkSync(path);
|
||||
return createWriteStream(path, { flags: 'w+' });
|
||||
}
|
||||
};
|
||||
|
||||
const getFileType = (filePath) => {
|
||||
const ext = filePath.split('.').pop().toLowerCase();
|
||||
if (ext === 'js') return 'js';
|
||||
if (ext === 'css') return 'css';
|
||||
if (ext === 'html') return 'html';
|
||||
if (ext === 'svg') return 'svg';
|
||||
return 'other';
|
||||
};
|
||||
|
||||
const writeFile = (relativeFilePath, buffer) => {
|
||||
const variable = 'ESP_REACT_DATA_' + fileInfo.length;
|
||||
const variable = `ESP_REACT_DATA_${fileInfo.length}`;
|
||||
const mimeType = mime.lookup(relativeFilePath);
|
||||
var size = 0;
|
||||
writeStream.write('const uint8_t ' + variable + '[] = {');
|
||||
// const zipBuffer = zlib.brotliCompressSync(buffer, { quality: 1 });
|
||||
const zipBuffer = zlib.gzipSync(buffer, { level: 9 });
|
||||
const fileType = getFileType(relativeFilePath);
|
||||
let size = 0;
|
||||
writeStream.write(`const uint8_t ${variable}[] = {`);
|
||||
|
||||
// create sha
|
||||
const hashSum = crypto.createHash('sha256');
|
||||
hashSum.update(zipBuffer);
|
||||
const hash = hashSum.digest('hex');
|
||||
const zipBuffer = zlib.gzipSync(buffer, { level: 9 });
|
||||
const hash = crypto.createHash('sha256').update(zipBuffer).digest('hex');
|
||||
|
||||
zipBuffer.forEach((b) => {
|
||||
if (!(size % bytesPerLine)) {
|
||||
writeStream.write('\n');
|
||||
writeStream.write(indent);
|
||||
writeStream.write('\n' + INDENT);
|
||||
}
|
||||
writeStream.write('0x' + ('00' + b.toString(16).toUpperCase()).slice(-2) + ',');
|
||||
writeStream.write('0x' + b.toString(16).toUpperCase().padStart(2, '0') + ',');
|
||||
size++;
|
||||
});
|
||||
|
||||
if (size % bytesPerLine) {
|
||||
writeStream.write('\n');
|
||||
}
|
||||
|
||||
size % bytesPerLine && writeStream.write('\n');
|
||||
writeStream.write('};\n\n');
|
||||
|
||||
// Update bundle statistics
|
||||
bundleStats[fileType].count++;
|
||||
bundleStats[fileType].uncompressed += buffer.length;
|
||||
bundleStats[fileType].compressed += zipBuffer.length;
|
||||
|
||||
fileInfo.push({
|
||||
uri: '/' + relativeFilePath.replace(sep, '/'),
|
||||
mimeType,
|
||||
@@ -84,32 +97,52 @@ const writeFile = (relativeFilePath, buffer) => {
|
||||
hash
|
||||
});
|
||||
|
||||
// console.log(relativeFilePath + ' (size ' + size + ' bytes)');
|
||||
totalSize += size;
|
||||
};
|
||||
|
||||
// start
|
||||
console.log('Generating ' + outputPath + ' from ' + sourcePath);
|
||||
const includes = ARDUINO_INCLUDES;
|
||||
const indent = INDENT;
|
||||
console.log(`Generating ${outputPath} from ${sourcePath}`);
|
||||
const fileInfo = [];
|
||||
const writeStream = cleanAndOpen(resolve(outputPath));
|
||||
|
||||
// includes
|
||||
writeStream.write(includes);
|
||||
writeStream.write(ARDUINO_INCLUDES);
|
||||
|
||||
// process static files
|
||||
const buildPath = resolve(sourcePath);
|
||||
for (const filePath of getFilesSync(buildPath)) {
|
||||
const readStream = readFileSync(filePath);
|
||||
const relativeFilePath = relative(buildPath, filePath);
|
||||
writeFile(relativeFilePath, readStream);
|
||||
writeFile(relative(buildPath, filePath), readFileSync(filePath));
|
||||
}
|
||||
|
||||
// add class
|
||||
writeStream.write(generateWWWClass());
|
||||
|
||||
// end
|
||||
writeStream.end();
|
||||
|
||||
console.log('Total size: ' + totalSize / 1000 + ' KB');
|
||||
// Calculate and display bundle statistics
|
||||
const totalUncompressed = Object.values(bundleStats).reduce(
|
||||
(sum, stat) => sum + stat.uncompressed,
|
||||
0
|
||||
);
|
||||
const totalCompressed = Object.values(bundleStats).reduce(
|
||||
(sum, stat) => sum + stat.compressed,
|
||||
0
|
||||
);
|
||||
const compressionRatio = (
|
||||
((totalUncompressed - totalCompressed) / totalUncompressed) *
|
||||
100
|
||||
).toFixed(1);
|
||||
|
||||
console.log('\n📊 Bundle Size Analysis:');
|
||||
console.log('='.repeat(50));
|
||||
console.log(`Total compressed size: ${(totalSize / 1000).toFixed(1)} KB`);
|
||||
console.log(`Total uncompressed size: ${(totalUncompressed / 1000).toFixed(1)} KB`);
|
||||
console.log(`Compression ratio: ${compressionRatio}%`);
|
||||
console.log('\n📁 File Type Breakdown:');
|
||||
Object.entries(bundleStats).forEach(([type, stats]) => {
|
||||
if (stats.count > 0) {
|
||||
const ratio = (
|
||||
((stats.uncompressed - stats.compressed) / stats.uncompressed) *
|
||||
100
|
||||
).toFixed(1);
|
||||
console.log(
|
||||
`${type.toUpperCase().padEnd(4)}: ${stats.count} files, ${(stats.uncompressed / 1000).toFixed(1)} KB → ${(stats.compressed / 1000).toFixed(1)} KB (${ratio}% compression)`
|
||||
);
|
||||
}
|
||||
});
|
||||
console.log('='.repeat(50));
|
||||
|
||||
@@ -37,10 +37,9 @@ const AuthenticatedRouting = () => {
|
||||
<Route path="/dashboard/*" element={<Dashboard />} />
|
||||
<Route path="/devices/*" element={<Devices />} />
|
||||
<Route path="/sensors/*" element={<Sensors />} />
|
||||
<Route path="/status/*" element={<Status />} />
|
||||
<Route path="/help/*" element={<Help />} />
|
||||
<Route path="/*" element={<Navigate to="/" />} />
|
||||
|
||||
<Route path="/status/*" element={<Status />} />
|
||||
<Route path="/status/hardwarestatus/*" element={<HardwareStatus />} />
|
||||
<Route path="/status/activity" element={<Activity />} />
|
||||
<Route path="/status/log" element={<SystemLog />} />
|
||||
@@ -68,6 +67,8 @@ const AuthenticatedRouting = () => {
|
||||
<Route path="/customentities" element={<CustomEntities />} />
|
||||
</>
|
||||
)}
|
||||
|
||||
<Route path="/*" element={<Navigate to="/" />} />
|
||||
</Routes>
|
||||
</Layout>
|
||||
);
|
||||
|
||||
@@ -98,7 +98,7 @@ const SignIn = () => {
|
||||
|
||||
<Box display="flex" flexDirection="column" alignItems="center">
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
disabled={processing}
|
||||
sx={{
|
||||
width: 240
|
||||
@@ -117,7 +117,7 @@ const SignIn = () => {
|
||||
}}
|
||||
/>
|
||||
<ValidatedPasswordField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
disabled={processing}
|
||||
sx={{
|
||||
width: 240
|
||||
|
||||
@@ -70,6 +70,7 @@ export const readDeviceEntities = (id: number) =>
|
||||
alovaInstance.Get<DeviceEntity[]>(`/rest/deviceEntities`, {
|
||||
params: { id },
|
||||
responseType: 'arraybuffer',
|
||||
// @ts-expect-error - exactOptionalPropertyTypes compatibility issue
|
||||
transform(data) {
|
||||
return (data as DeviceEntity[]).map((de: DeviceEntity) => ({
|
||||
...de,
|
||||
@@ -92,6 +93,7 @@ export const writeDeviceName = (data: { id: number; name: string }) =>
|
||||
// SettingsScheduler
|
||||
export const readSchedule = () =>
|
||||
alovaInstance.Get<ScheduleItem[]>('/rest/schedule', {
|
||||
// @ts-expect-error - exactOptionalPropertyTypes compatibility issue
|
||||
transform(data) {
|
||||
return (data as Schedule).schedule.map((si: ScheduleItem) => ({
|
||||
...si,
|
||||
@@ -129,6 +131,7 @@ export const writeModules = (data: {
|
||||
// CustomEntities
|
||||
export const readCustomEntities = () =>
|
||||
alovaInstance.Get<EntityItem[]>('/rest/customEntities', {
|
||||
// @ts-expect-error - exactOptionalPropertyTypes compatibility issue
|
||||
transform(data) {
|
||||
return (data as Entities).entities.map((ei: EntityItem) => ({
|
||||
...ei,
|
||||
|
||||
@@ -30,7 +30,7 @@ export const getDevVersion = () =>
|
||||
cacheFor: 60 * 10 * 1000,
|
||||
transform(response: { data: { name: string; published_at: string } }) {
|
||||
return {
|
||||
name: response.data.name.split(/\s+/).splice(-1)[0].substring(1),
|
||||
name: response.data.name.split(/\s+/).splice(-1)[0]?.substring(1) || '',
|
||||
published_at: response.data.published_at
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,40 +1,37 @@
|
||||
let decoder;
|
||||
// @ts-nocheck - Optimized MessagePack unpacking library for EMS-ESP32
|
||||
let decoder,
|
||||
src,
|
||||
srcEnd,
|
||||
position = 0,
|
||||
strings = [],
|
||||
stringPosition = 0,
|
||||
currentUnpackr = {},
|
||||
currentStructures,
|
||||
srcString,
|
||||
srcStringStart = 0,
|
||||
srcStringEnd = 0,
|
||||
bundledStrings,
|
||||
referenceMap,
|
||||
dataView;
|
||||
const EMPTY_ARRAY = [],
|
||||
currentExtensions = [];
|
||||
const defaultOptions = { useRecords: false, mapsAsObjects: true };
|
||||
try {
|
||||
decoder = new TextDecoder();
|
||||
} catch (error) {}
|
||||
let src;
|
||||
let srcEnd;
|
||||
let position = 0;
|
||||
const EMPTY_ARRAY = [];
|
||||
let strings = EMPTY_ARRAY;
|
||||
let stringPosition = 0;
|
||||
let currentUnpackr = {};
|
||||
let currentStructures;
|
||||
let srcString;
|
||||
let srcStringStart = 0;
|
||||
let srcStringEnd = 0;
|
||||
let bundledStrings;
|
||||
let referenceMap;
|
||||
const currentExtensions = [];
|
||||
let dataView;
|
||||
const defaultOptions = {
|
||||
useRecords: false,
|
||||
mapsAsObjects: true
|
||||
};
|
||||
export class C1Type {}
|
||||
export const C1 = new C1Type();
|
||||
class C1Type {}
|
||||
const C1 = new C1Type();
|
||||
C1.name = 'MessagePack 0xC1';
|
||||
let sequentialMode = false;
|
||||
let inlineObjectReadThreshold = 2;
|
||||
let readStruct, onLoadedStructures, onSaveState;
|
||||
// no-eval build
|
||||
let sequentialMode = false,
|
||||
inlineObjectReadThreshold = 2,
|
||||
readStruct,
|
||||
onLoadedStructures,
|
||||
onSaveState;
|
||||
try {
|
||||
new Function('');
|
||||
} catch (error) {
|
||||
// if eval variants are not supported, do not create inline object readers ever
|
||||
inlineObjectReadThreshold = Infinity;
|
||||
}
|
||||
|
||||
export class Unpackr {
|
||||
constructor(options) {
|
||||
if (options) {
|
||||
@@ -50,19 +47,15 @@ export class Unpackr {
|
||||
if (options.structures)
|
||||
options.structures.sharedLength = options.structures.length;
|
||||
else if (options.getStructures) {
|
||||
(options.structures = []).uninitialized = true; // this is what we use to denote an uninitialized structures
|
||||
(options.structures = []).uninitialized = true;
|
||||
options.structures.sharedLength = 0;
|
||||
}
|
||||
if (options.int64AsNumber) {
|
||||
options.int64AsType = 'number';
|
||||
}
|
||||
if (options.int64AsNumber) options.int64AsType = 'number';
|
||||
}
|
||||
Object.assign(this, options);
|
||||
}
|
||||
|
||||
unpack(source, options?: any) {
|
||||
if (src) {
|
||||
// re-entrant execution, save the state and restore it after we do this unpack
|
||||
return saveState(() => {
|
||||
clearSource();
|
||||
return this
|
||||
@@ -86,9 +79,6 @@ export class Unpackr {
|
||||
strings = EMPTY_ARRAY;
|
||||
bundledStrings = null;
|
||||
src = source;
|
||||
// this provides cached access to the data view for a buffer if it is getting reused, which is a recommend
|
||||
// technique for getting data from a database where it can be copied into an existing buffer instead of creating
|
||||
// new ones
|
||||
try {
|
||||
dataView =
|
||||
source.dataView ||
|
||||
@@ -191,10 +181,10 @@ export class Unpackr {
|
||||
return this.unpack(source, end);
|
||||
}
|
||||
}
|
||||
export function getPosition() {
|
||||
function getPosition() {
|
||||
return position;
|
||||
}
|
||||
export function checkedRead(options: any) {
|
||||
function checkedRead(options: any) {
|
||||
try {
|
||||
if (!currentUnpackr.trusted && !sequentialMode) {
|
||||
const sharedLength = currentStructures.sharedLength || 0;
|
||||
@@ -264,7 +254,7 @@ function restoreStructures() {
|
||||
currentStructures.restoreStructures = null;
|
||||
}
|
||||
|
||||
export function read() {
|
||||
function read() {
|
||||
let token = src[position++];
|
||||
if (token < 0xa0) {
|
||||
if (token < 0x80) {
|
||||
@@ -589,7 +579,7 @@ const createSecondByteReader = (firstId, read0) =>
|
||||
return structure.read();
|
||||
};
|
||||
|
||||
export function loadStructures() {
|
||||
function loadStructures() {
|
||||
const loadedStructures = saveState(() => {
|
||||
// save the state in case getStructures modifies our buffer
|
||||
src = null;
|
||||
@@ -605,9 +595,8 @@ var readFixedString = readStringJS;
|
||||
var readString8 = readStringJS;
|
||||
var readString16 = readStringJS;
|
||||
var readString32 = readStringJS;
|
||||
export let isNativeAccelerationEnabled = false;
|
||||
|
||||
export function setExtractor(extractStrings) {
|
||||
let isNativeAccelerationEnabled = false;
|
||||
function setExtractor(extractStrings) {
|
||||
isNativeAccelerationEnabled = true;
|
||||
readFixedString = readString(1);
|
||||
readString8 = readString(2);
|
||||
@@ -701,7 +690,7 @@ function readStringJS(length) {
|
||||
|
||||
return result;
|
||||
}
|
||||
export function readString(source, start, length) {
|
||||
function readString(source, start, length) {
|
||||
const existingSrc = src;
|
||||
src = source;
|
||||
position = start;
|
||||
@@ -1065,7 +1054,7 @@ currentExtensions[0x70] = (data) => {
|
||||
|
||||
currentExtensions[0x73] = () => new Set(read());
|
||||
|
||||
export const typedArrays = [
|
||||
const typedArrays = [
|
||||
'Int8',
|
||||
'Uint8',
|
||||
'Uint8Clamped',
|
||||
@@ -1177,44 +1166,20 @@ function saveState(callback) {
|
||||
dataView = new DataView(src.buffer, src.byteOffset, src.byteLength);
|
||||
return value;
|
||||
}
|
||||
export function clearSource() {
|
||||
function clearSource() {
|
||||
src = null;
|
||||
referenceMap = null;
|
||||
currentStructures = null;
|
||||
}
|
||||
|
||||
export function addExtension(extension) {
|
||||
function addExtension(extension) {
|
||||
if (extension.unpack) currentExtensions[extension.type] = extension.unpack;
|
||||
else currentExtensions[extension.type] = extension;
|
||||
}
|
||||
|
||||
export const mult10 = new Array(147); // this is a table matching binary exponents to the multiplier to determine significant digit rounding
|
||||
const mult10 = new Array(147);
|
||||
for (let i = 0; i < 256; i++) {
|
||||
mult10[i] = +('1e' + Math.floor(45.15 - i * 0.30103));
|
||||
}
|
||||
export const Decoder = Unpackr;
|
||||
var defaultUnpackr = new Unpackr({ useRecords: false });
|
||||
const defaultUnpackr = new Unpackr({ useRecords: false });
|
||||
export const unpack = defaultUnpackr.unpack;
|
||||
export const unpackMultiple = defaultUnpackr.unpackMultiple;
|
||||
export const decode = defaultUnpackr.unpack;
|
||||
export const FLOAT32_OPTIONS = {
|
||||
NEVER: 0,
|
||||
ALWAYS: 1,
|
||||
DECIMAL_ROUND: 3,
|
||||
DECIMAL_FIT: 4
|
||||
};
|
||||
const f32Array = new Float32Array(1);
|
||||
const u8Array = new Uint8Array(f32Array.buffer, 0, 4);
|
||||
export function roundFloat32(float32Number) {
|
||||
f32Array[0] = float32Number;
|
||||
const multiplier = mult10[((u8Array[3] & 0x7f) << 1) | (u8Array[2] >> 7)];
|
||||
return (
|
||||
((multiplier * float32Number + (float32Number > 0 ? 0.5 : -0.5)) >> 0) /
|
||||
multiplier
|
||||
);
|
||||
}
|
||||
export function setReadStruct(updatedReadStruct, loadedStructs, saveState) {
|
||||
readStruct = updatedReadStruct;
|
||||
onLoadedStructures = loadedStructs;
|
||||
onSaveState = saveState;
|
||||
}
|
||||
|
||||
@@ -137,8 +137,8 @@ const CustomEntities = () => {
|
||||
const saveEntities = async () => {
|
||||
await writeEntities({
|
||||
entities: entities
|
||||
.filter((ei) => !ei.deleted)
|
||||
.map((condensed_ei) => ({
|
||||
.filter((ei: EntityItem) => !ei.deleted)
|
||||
.map((condensed_ei: EntityItem) => ({
|
||||
id: condensed_ei.id,
|
||||
ram: condensed_ei.ram,
|
||||
name: condensed_ei.name,
|
||||
@@ -231,6 +231,7 @@ const CustomEntities = () => {
|
||||
value_type: 0,
|
||||
writeable: false,
|
||||
deleted: false,
|
||||
hide: false,
|
||||
value: ''
|
||||
});
|
||||
setDialogOpen(true);
|
||||
@@ -251,15 +252,17 @@ const CustomEntities = () => {
|
||||
|
||||
const renderEntity = () => {
|
||||
if (!entities) {
|
||||
return <FormLoader onRetry={fetchEntities} errorMessage={error?.message} />;
|
||||
return (
|
||||
<FormLoader onRetry={fetchEntities} errorMessage={error?.message || ''} />
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Table
|
||||
data={{
|
||||
nodes: entities
|
||||
.filter((ei) => !ei.deleted)
|
||||
.sort((a, b) => a.name.localeCompare(b.name))
|
||||
.filter((ei: EntityItem) => !ei.deleted)
|
||||
.sort((a: EntityItem, b: EntityItem) => a.name.localeCompare(b.name))
|
||||
}}
|
||||
theme={entity_theme}
|
||||
layout={{ custom: true }}
|
||||
|
||||
@@ -74,7 +74,10 @@ const CustomEntitiesDialog = ({
|
||||
}
|
||||
}, [open, selectedItem]);
|
||||
|
||||
const handleClose = (_event, reason: 'backdropClick' | 'escapeKeyDown') => {
|
||||
const handleClose = (
|
||||
_event: React.SyntheticEvent,
|
||||
reason: 'backdropClick' | 'escapeKeyDown'
|
||||
) => {
|
||||
if (reason !== 'backdropClick') {
|
||||
onClose();
|
||||
}
|
||||
@@ -123,7 +126,7 @@ const CustomEntitiesDialog = ({
|
||||
<Grid container spacing={2} rowSpacing={0}>
|
||||
<Grid size={12}>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="name"
|
||||
label={LL.NAME(0)}
|
||||
value={editItem.name}
|
||||
@@ -211,7 +214,7 @@ const CustomEntitiesDialog = ({
|
||||
</Grid>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="device_id"
|
||||
label={LL.ID_OF(LL.DEVICE())}
|
||||
margin="normal"
|
||||
@@ -231,7 +234,7 @@ const CustomEntitiesDialog = ({
|
||||
</Grid>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="type_id"
|
||||
label={LL.ID_OF(LL.TYPE(1))}
|
||||
margin="normal"
|
||||
@@ -251,7 +254,7 @@ const CustomEntitiesDialog = ({
|
||||
</Grid>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="offset"
|
||||
label={LL.OFFSET()}
|
||||
margin="normal"
|
||||
@@ -343,7 +346,7 @@ const CustomEntitiesDialog = ({
|
||||
editItem.device_id !== '0' && (
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="factor"
|
||||
label={LL.BYTES()}
|
||||
value={numberValue(editItem.factor as number)}
|
||||
@@ -361,7 +364,7 @@ const CustomEntitiesDialog = ({
|
||||
{editItem.value_type === DeviceValueType.BOOL && (
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="factor"
|
||||
label={LL.BITMASK()}
|
||||
value={editItem.factor as string}
|
||||
|
||||
@@ -125,13 +125,22 @@ const Customizations = () => {
|
||||
|
||||
const setOriginalSettings = (data: DeviceEntity[]) => {
|
||||
setDeviceEntities(
|
||||
data.map((de) => ({
|
||||
...de,
|
||||
o_m: de.m,
|
||||
o_cn: de.cn,
|
||||
o_mi: de.mi,
|
||||
o_ma: de.ma
|
||||
}))
|
||||
data.map((de) => {
|
||||
const result: DeviceEntity = {
|
||||
...de,
|
||||
o_m: de.m
|
||||
};
|
||||
if (de.cn !== undefined) {
|
||||
result.o_cn = de.cn;
|
||||
}
|
||||
if (de.mi !== undefined) {
|
||||
result.o_mi = de.mi;
|
||||
}
|
||||
if (de.ma !== undefined) {
|
||||
result.o_ma = de.ma;
|
||||
}
|
||||
return result;
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
@@ -244,8 +253,11 @@ const Customizations = () => {
|
||||
setSelectedDevice(-1);
|
||||
setSelectedDeviceTypeNameURL('');
|
||||
} else {
|
||||
setSelectedDeviceTypeNameURL(devices.devices[index].url || '');
|
||||
setSelectedDeviceName(devices.devices[index].n);
|
||||
const device = devices.devices[index];
|
||||
if (device) {
|
||||
setSelectedDeviceTypeNameURL(device.url || '');
|
||||
setSelectedDeviceName(device.n);
|
||||
}
|
||||
setNumChanges(0);
|
||||
setRestartNeeded(false);
|
||||
}
|
||||
@@ -396,14 +408,20 @@ const Customizations = () => {
|
||||
await sendCustomizationEntities({
|
||||
id: selectedDevice,
|
||||
entity_ids: masked_entities
|
||||
}).catch((error: Error) => {
|
||||
if (error.message === 'Reboot required') {
|
||||
setRestartNeeded(true);
|
||||
} else {
|
||||
toast.error(error.message);
|
||||
}
|
||||
});
|
||||
setOriginalSettings(deviceEntities);
|
||||
})
|
||||
.then(() => {
|
||||
toast.success(LL.CUSTOMIZATIONS_SAVED());
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
if (error.message === 'Reboot required') {
|
||||
setRestartNeeded(true);
|
||||
} else {
|
||||
toast.error(error.message);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
setOriginalSettings(deviceEntities);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -545,7 +563,7 @@ const Customizations = () => {
|
||||
size="small"
|
||||
color="secondary"
|
||||
value={getMaskString(selectedFilters)}
|
||||
onChange={(event, mask: string[]) => {
|
||||
onChange={(_, mask: string[]) => {
|
||||
setSelectedFilters(getMaskNumber(mask));
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -54,7 +54,10 @@ const CustomizationsDialog = ({
|
||||
}
|
||||
}, [open, selectedItem]);
|
||||
|
||||
const handleClose = (_event, reason: 'backdropClick' | 'escapeKeyDown') => {
|
||||
const handleClose = (
|
||||
_event: React.SyntheticEvent,
|
||||
reason: 'backdropClick' | 'escapeKeyDown'
|
||||
) => {
|
||||
if (reason !== 'backdropClick') {
|
||||
onClose();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useContext, useEffect, useState } from 'react';
|
||||
import { useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
||||
import { IconContext } from 'react-icons/lib';
|
||||
import { Link } from 'react-router';
|
||||
import { toast } from 'react-toastify';
|
||||
@@ -76,35 +76,40 @@ const Dashboard = () => {
|
||||
}
|
||||
);
|
||||
|
||||
const deviceValueDialogSave = async (devicevalue: DeviceValue) => {
|
||||
if (!selectedDashboardItem) {
|
||||
return;
|
||||
}
|
||||
const id = selectedDashboardItem.parentNode.id; // this is the parent ID
|
||||
await sendDeviceValue({ id, c: devicevalue.c ?? '', v: devicevalue.v })
|
||||
.then(() => {
|
||||
toast.success(LL.WRITE_CMD_SENT());
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
toast.error(error.message);
|
||||
})
|
||||
.finally(() => {
|
||||
setDeviceValueDialogOpen(false);
|
||||
setSelectedDashboardItem(undefined);
|
||||
});
|
||||
};
|
||||
const deviceValueDialogSave = useCallback(
|
||||
async (devicevalue: DeviceValue) => {
|
||||
if (!selectedDashboardItem) {
|
||||
return;
|
||||
}
|
||||
const id = selectedDashboardItem.id; // this is the parent ID
|
||||
await sendDeviceValue({ id, c: devicevalue.c ?? '', v: devicevalue.v })
|
||||
.then(() => {
|
||||
toast.success(LL.WRITE_CMD_SENT());
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
toast.error(error.message);
|
||||
})
|
||||
.finally(() => {
|
||||
setDeviceValueDialogOpen(false);
|
||||
setSelectedDashboardItem(undefined);
|
||||
});
|
||||
},
|
||||
[selectedDashboardItem, sendDeviceValue, LL]
|
||||
);
|
||||
|
||||
const dashboard_theme = useTheme({
|
||||
Table: `
|
||||
const dashboard_theme = useMemo(
|
||||
() =>
|
||||
useTheme({
|
||||
Table: `
|
||||
--data-table-library_grid-template-columns: minmax(80px, auto) 120px 32px;
|
||||
`,
|
||||
BaseRow: `
|
||||
BaseRow: `
|
||||
font-size: 14px;
|
||||
.td {
|
||||
height: 28px;
|
||||
}
|
||||
`,
|
||||
Row: `
|
||||
Row: `
|
||||
cursor: pointer;
|
||||
background-color: #1e1e1e;
|
||||
&:nth-of-type(odd) .td {
|
||||
@@ -114,7 +119,7 @@ const Dashboard = () => {
|
||||
background-color: #177ac9;
|
||||
},
|
||||
`,
|
||||
BaseCell: `
|
||||
BaseCell: `
|
||||
&:nth-of-type(2) {
|
||||
text-align: right;
|
||||
}
|
||||
@@ -122,12 +127,14 @@ const Dashboard = () => {
|
||||
text-align: right;
|
||||
}
|
||||
`
|
||||
});
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
const tree = useTree(
|
||||
{ nodes: data.nodes },
|
||||
{
|
||||
onChange: undefined // not used but needed
|
||||
onChange: () => {} // not used but needed
|
||||
},
|
||||
{
|
||||
treeIcon: {
|
||||
@@ -162,28 +169,31 @@ const Dashboard = () => {
|
||||
: tree.fns.onRemoveAll(); // collapse tree
|
||||
}, [parentNodes]);
|
||||
|
||||
const showType = (n?: string, t?: number) => {
|
||||
// if we have a name show it
|
||||
if (n) {
|
||||
return n;
|
||||
}
|
||||
if (t) {
|
||||
// otherwise pick translation based on type
|
||||
switch (t) {
|
||||
case DeviceType.CUSTOM:
|
||||
return LL.CUSTOM_ENTITIES(0);
|
||||
case DeviceType.ANALOGSENSOR:
|
||||
return LL.ANALOG_SENSORS();
|
||||
case DeviceType.TEMPERATURESENSOR:
|
||||
return LL.TEMP_SENSORS();
|
||||
case DeviceType.SCHEDULER:
|
||||
return LL.SCHEDULER();
|
||||
default:
|
||||
break;
|
||||
const showType = useCallback(
|
||||
(n?: string, t?: number) => {
|
||||
// if we have a name show it
|
||||
if (n) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
};
|
||||
if (t) {
|
||||
// otherwise pick translation based on type
|
||||
switch (t) {
|
||||
case DeviceType.CUSTOM:
|
||||
return LL.CUSTOM_ENTITIES(0);
|
||||
case DeviceType.ANALOGSENSOR:
|
||||
return LL.ANALOG_SENSORS();
|
||||
case DeviceType.TEMPERATURESENSOR:
|
||||
return LL.TEMP_SENSORS();
|
||||
case DeviceType.SCHEDULER:
|
||||
return LL.SCHEDULER();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
},
|
||||
[LL]
|
||||
);
|
||||
|
||||
const showName = (di: DashboardItem) => {
|
||||
if (di.id < 100) {
|
||||
@@ -201,20 +211,24 @@ const Dashboard = () => {
|
||||
if (di.dv) {
|
||||
return <span>{di.dv.id.slice(2)}</span>;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const hasMask = (id: string, mask: number) =>
|
||||
(parseInt(id.slice(0, 2), 16) & mask) === mask;
|
||||
|
||||
const editDashboardValue = (di: DashboardItem) => {
|
||||
if (me.admin && di.dv?.c) {
|
||||
setSelectedDashboardItem(di);
|
||||
setDeviceValueDialogOpen(true);
|
||||
}
|
||||
};
|
||||
const editDashboardValue = useCallback(
|
||||
(di: DashboardItem) => {
|
||||
if (me.admin && di.dv?.c) {
|
||||
setSelectedDashboardItem(di);
|
||||
setDeviceValueDialogOpen(true);
|
||||
}
|
||||
},
|
||||
[me.admin]
|
||||
);
|
||||
|
||||
const handleShowAll = (
|
||||
event: React.MouseEvent<HTMLElement>,
|
||||
_event: React.MouseEvent<HTMLElement>,
|
||||
toggle: boolean | null
|
||||
) => {
|
||||
if (toggle !== null) {
|
||||
@@ -225,7 +239,9 @@ const Dashboard = () => {
|
||||
|
||||
const renderContent = () => {
|
||||
if (!data) {
|
||||
return <FormLoader onRetry={fetchDashboard} errorMessage={error?.message} />;
|
||||
return (
|
||||
<FormLoader onRetry={fetchDashboard} errorMessage={error?.message || ''} />
|
||||
);
|
||||
}
|
||||
|
||||
const hasFavEntities = data.nodes.filter(
|
||||
|
||||
@@ -329,13 +329,16 @@ const Devices = () => {
|
||||
|
||||
const handleDownloadCsv = () => {
|
||||
const deviceIndex = coreData.devices.findIndex(
|
||||
(d) => d.id === device_select.state.id
|
||||
(d: Device) => d.id === device_select.state.id
|
||||
);
|
||||
if (deviceIndex === -1) {
|
||||
return;
|
||||
}
|
||||
const filename =
|
||||
coreData.devices[deviceIndex].tn + '_' + coreData.devices[deviceIndex].n;
|
||||
const selectedDevice = coreData.devices[deviceIndex];
|
||||
if (!selectedDevice) {
|
||||
return;
|
||||
}
|
||||
const filename = selectedDevice.tn + '_' + selectedDevice.n;
|
||||
|
||||
const columns = [
|
||||
{
|
||||
@@ -350,7 +353,7 @@ const Devices = () => {
|
||||
{
|
||||
accessor: (dv: DeviceValue) =>
|
||||
dv.u !== undefined && DeviceValueUOM_s[dv.u]
|
||||
? DeviceValueUOM_s[dv.u].replace(/[^a-zA-Z0-9]/g, '')
|
||||
? DeviceValueUOM_s[dv.u]?.replace(/[^a-zA-Z0-9]/g, '')
|
||||
: '',
|
||||
name: 'UoM'
|
||||
},
|
||||
@@ -373,7 +376,9 @@ const Devices = () => {
|
||||
];
|
||||
|
||||
const data = onlyFav
|
||||
? deviceData.nodes.filter((dv) => hasMask(dv.id, DeviceEntityMask.DV_FAVORITE))
|
||||
? deviceData.nodes.filter((dv: DeviceValue) =>
|
||||
hasMask(dv.id, DeviceEntityMask.DV_FAVORITE)
|
||||
)
|
||||
: deviceData.nodes;
|
||||
|
||||
const csvData = data.reduce(
|
||||
@@ -433,10 +438,14 @@ const Devices = () => {
|
||||
const renderDeviceDetails = () => {
|
||||
if (showDeviceInfo) {
|
||||
const deviceIndex = coreData.devices.findIndex(
|
||||
(d) => d.id === device_select.state.id
|
||||
(d: Device) => d.id === device_select.state.id
|
||||
);
|
||||
if (deviceIndex === -1) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
const deviceDetails = coreData.devices[deviceIndex];
|
||||
if (!deviceDetails) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -449,47 +458,35 @@ const Devices = () => {
|
||||
<DialogContent dividers>
|
||||
<List dense={true}>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary={LL.TYPE(0)}
|
||||
secondary={coreData.devices[deviceIndex].tn}
|
||||
/>
|
||||
<ListItemText primary={LL.TYPE(0)} secondary={deviceDetails.tn} />
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary={LL.NAME(0)}
|
||||
secondary={coreData.devices[deviceIndex].n}
|
||||
/>
|
||||
<ListItemText primary={LL.NAME(0)} secondary={deviceDetails.n} />
|
||||
</ListItem>
|
||||
{coreData.devices[deviceIndex].t !== DeviceType.CUSTOM && (
|
||||
{deviceDetails.t !== DeviceType.CUSTOM && (
|
||||
<>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary={LL.BRAND()}
|
||||
secondary={coreData.devices[deviceIndex].b}
|
||||
/>
|
||||
<ListItemText primary={LL.BRAND()} secondary={deviceDetails.b} />
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary={LL.ID_OF(LL.DEVICE())}
|
||||
secondary={
|
||||
'0x' +
|
||||
(
|
||||
'00' +
|
||||
coreData.devices[deviceIndex].d.toString(16).toUpperCase()
|
||||
).slice(-2)
|
||||
('00' + deviceDetails.d.toString(16).toUpperCase()).slice(-2)
|
||||
}
|
||||
/>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary={LL.ID_OF(LL.PRODUCT())}
|
||||
secondary={coreData.devices[deviceIndex].p}
|
||||
secondary={deviceDetails.p}
|
||||
/>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary={LL.VERSION()}
|
||||
secondary={coreData.devices[deviceIndex].v}
|
||||
secondary={deviceDetails.v}
|
||||
/>
|
||||
</ListItem>
|
||||
</>
|
||||
@@ -508,6 +505,7 @@ const Devices = () => {
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const renderCoreData = () => (
|
||||
@@ -598,21 +596,26 @@ const Devices = () => {
|
||||
|
||||
const shown_data = onlyFav
|
||||
? deviceData.nodes.filter(
|
||||
(dv) =>
|
||||
(dv: DeviceValue) =>
|
||||
hasMask(dv.id, DeviceEntityMask.DV_FAVORITE) &&
|
||||
dv.id.slice(2).toLowerCase().includes(search.toLowerCase())
|
||||
)
|
||||
: deviceData.nodes.filter((dv) =>
|
||||
: deviceData.nodes.filter((dv: DeviceValue) =>
|
||||
dv.id.slice(2).toLowerCase().includes(search.toLowerCase())
|
||||
);
|
||||
|
||||
const deviceIndex = coreData.devices.findIndex(
|
||||
(d) => d.id === device_select.state.id
|
||||
(d: Device) => d.id === device_select.state.id
|
||||
);
|
||||
if (deviceIndex === -1) {
|
||||
return;
|
||||
}
|
||||
const deviceInfo = coreData.devices[deviceIndex];
|
||||
if (!deviceInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
const [, height] = size;
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
@@ -623,15 +626,15 @@ const Devices = () => {
|
||||
bottom: 0,
|
||||
top: 64,
|
||||
zIndex: 'modal',
|
||||
maxHeight: () => size[1] - 126,
|
||||
maxHeight: () => (height || 0) - 126,
|
||||
border: '1px solid #177ac9'
|
||||
}}
|
||||
>
|
||||
<Box sx={{ p: 1 }}>
|
||||
<Grid container justifyContent="space-between">
|
||||
<Typography noWrap variant="subtitle1" color="warning.main">
|
||||
{coreData.devices[deviceIndex].n} (
|
||||
{coreData.devices[deviceIndex].tn})
|
||||
{deviceInfo.n} (
|
||||
{deviceInfo.tn})
|
||||
</Typography>
|
||||
<Grid justifyContent="flex-end">
|
||||
<ButtonTooltip title={LL.CLOSE()}>
|
||||
@@ -701,7 +704,7 @@ const Devices = () => {
|
||||
' ' +
|
||||
shown_data.length +
|
||||
'/' +
|
||||
coreData.devices[deviceIndex].e +
|
||||
deviceInfo.e +
|
||||
' ' +
|
||||
LL.ENTITIES(shown_data.length)}
|
||||
</span>
|
||||
|
||||
@@ -120,7 +120,7 @@ const DevicesDialog = ({
|
||||
{editItem.l ? (
|
||||
<TextField
|
||||
name="v"
|
||||
label={LL.VALUE(0)}
|
||||
// label={LL.VALUE(0)}
|
||||
value={editItem.v}
|
||||
disabled={!writeable}
|
||||
sx={{ width: '30ch' }}
|
||||
@@ -135,7 +135,7 @@ const DevicesDialog = ({
|
||||
</TextField>
|
||||
) : editItem.s || editItem.u !== DeviceValueUOM.NONE ? (
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="v"
|
||||
label={LL.VALUE(0)}
|
||||
value={numberValue(Math.round((editItem.v as number) * 10) / 10)}
|
||||
@@ -159,7 +159,7 @@ const DevicesDialog = ({
|
||||
/>
|
||||
) : (
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="v"
|
||||
label={LL.VALUE(0)}
|
||||
value={editItem.v}
|
||||
|
||||
@@ -43,7 +43,7 @@ const EntityMaskToggle = ({ onUpdate, de }: EntityMaskToggleProps) => {
|
||||
size="small"
|
||||
color="secondary"
|
||||
value={getMaskString(de.m)}
|
||||
onChange={(event, mask: string[]) => {
|
||||
onChange={(_event, mask: string[]) => {
|
||||
de.m = getMaskNumber(mask);
|
||||
if (de.n === '' && de.m & DeviceEntityMask.DV_READONLY) {
|
||||
de.m = de.m | DeviceEntityMask.DV_WEB_EXCLUDE;
|
||||
|
||||
@@ -133,13 +133,15 @@ const Modules = () => {
|
||||
};
|
||||
|
||||
const saveModules = async () => {
|
||||
await updateModules({
|
||||
modules: modules.map((condensed_mi) => ({
|
||||
key: condensed_mi.key,
|
||||
enabled: condensed_mi.enabled,
|
||||
license: condensed_mi.license
|
||||
}))
|
||||
})
|
||||
await Promise.all(
|
||||
modules.map((condensed_mi: ModuleItem) =>
|
||||
updateModules({
|
||||
key: condensed_mi.key,
|
||||
enabled: condensed_mi.enabled,
|
||||
license: condensed_mi.license
|
||||
})
|
||||
)
|
||||
)
|
||||
.then(() => {
|
||||
toast.success(LL.MODULES_UPDATED());
|
||||
})
|
||||
@@ -154,7 +156,9 @@ const Modules = () => {
|
||||
|
||||
const renderContent = () => {
|
||||
if (!modules) {
|
||||
return <FormLoader onRetry={fetchModules} errorMessage={error?.message} />;
|
||||
return (
|
||||
<FormLoader onRetry={fetchModules} errorMessage={error?.message || ''} />
|
||||
);
|
||||
}
|
||||
|
||||
if (modules.length === 0) {
|
||||
|
||||
@@ -135,8 +135,8 @@ const Scheduler = () => {
|
||||
const saveSchedule = async () => {
|
||||
await updateSchedule({
|
||||
schedule: schedule
|
||||
.filter((si) => !si.deleted)
|
||||
.map((condensed_si) => ({
|
||||
.filter((si: ScheduleItem) => !si.deleted)
|
||||
.map((condensed_si: ScheduleItem) => ({
|
||||
id: condensed_si.id,
|
||||
active: condensed_si.active,
|
||||
flags: condensed_si.flags,
|
||||
@@ -212,7 +212,9 @@ const Scheduler = () => {
|
||||
|
||||
const renderSchedule = () => {
|
||||
if (!schedule) {
|
||||
return <FormLoader onRetry={fetchSchedule} errorMessage={error?.message} />;
|
||||
return (
|
||||
<FormLoader onRetry={fetchSchedule} errorMessage={error?.message || ''} />
|
||||
);
|
||||
}
|
||||
|
||||
const dayBox = (si: ScheduleItem, flag: number) => (
|
||||
@@ -251,8 +253,8 @@ const Scheduler = () => {
|
||||
<Table
|
||||
data={{
|
||||
nodes: schedule
|
||||
.filter((si) => !si.deleted)
|
||||
.sort((a, b) => a.flags - b.flags)
|
||||
.filter((si: ScheduleItem) => !si.deleted)
|
||||
.sort((a: ScheduleItem, b: ScheduleItem) => a.flags - b.flags)
|
||||
}}
|
||||
theme={schedule_theme}
|
||||
layout={{ custom: true }}
|
||||
|
||||
@@ -144,7 +144,10 @@ const SchedulerDialog = ({
|
||||
</Typography>
|
||||
);
|
||||
|
||||
const handleClose = (_event, reason: 'backdropClick' | 'escapeKeyDown') => {
|
||||
const handleClose = (
|
||||
_event: React.SyntheticEvent,
|
||||
reason: 'backdropClick' | 'escapeKeyDown'
|
||||
) => {
|
||||
if (reason !== 'backdropClick') {
|
||||
onClose();
|
||||
}
|
||||
@@ -325,7 +328,7 @@ const SchedulerDialog = ({
|
||||
</>
|
||||
)}
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="cmd"
|
||||
label={LL.COMMAND(0)}
|
||||
multiline
|
||||
@@ -344,7 +347,7 @@ const SchedulerDialog = ({
|
||||
onChange={updateFormValue}
|
||||
/>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="name"
|
||||
label={LL.NAME(0) + ' (' + LL.OPTIONAL() + ')'}
|
||||
value={editItem.name}
|
||||
|
||||
@@ -57,7 +57,10 @@ const SensorsAnalogDialog = ({
|
||||
}
|
||||
}, [open, selectedItem]);
|
||||
|
||||
const handleClose = (_event, reason: 'backdropClick' | 'escapeKeyDown') => {
|
||||
const handleClose = (
|
||||
_event: React.SyntheticEvent,
|
||||
reason: 'backdropClick' | 'escapeKeyDown'
|
||||
) => {
|
||||
if (reason !== 'backdropClick') {
|
||||
onClose();
|
||||
}
|
||||
@@ -88,7 +91,7 @@ const SensorsAnalogDialog = ({
|
||||
<Grid container spacing={2}>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="g"
|
||||
label="GPIO"
|
||||
sx={{ width: '11ch' }}
|
||||
@@ -107,7 +110,7 @@ const SensorsAnalogDialog = ({
|
||||
)}
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="n"
|
||||
label={LL.NAME(0)}
|
||||
value={editItem.n}
|
||||
|
||||
@@ -52,7 +52,10 @@ const SensorsTemperatureDialog = ({
|
||||
}
|
||||
}, [open, selectedItem]);
|
||||
|
||||
const handleClose = (_event, reason: 'backdropClick' | 'escapeKeyDown') => {
|
||||
const handleClose = (
|
||||
_event: React.SyntheticEvent,
|
||||
reason: 'backdropClick' | 'escapeKeyDown'
|
||||
) => {
|
||||
if (reason !== 'backdropClick') {
|
||||
onClose();
|
||||
}
|
||||
@@ -82,7 +85,7 @@ const SensorsTemperatureDialog = ({
|
||||
<Grid container spacing={2}>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="n"
|
||||
label={LL.NAME(0)}
|
||||
value={editItem.n}
|
||||
|
||||
@@ -13,7 +13,7 @@ import type {
|
||||
|
||||
export const GPIO_VALIDATOR = {
|
||||
validator(
|
||||
rule: InternalRuleItem,
|
||||
_rule: InternalRuleItem,
|
||||
value: number,
|
||||
callback: (error?: string) => void
|
||||
) {
|
||||
@@ -36,7 +36,7 @@ export const GPIO_VALIDATOR = {
|
||||
|
||||
export const GPIO_VALIDATORR = {
|
||||
validator(
|
||||
rule: InternalRuleItem,
|
||||
_rule: InternalRuleItem,
|
||||
value: number,
|
||||
callback: (error?: string) => void
|
||||
) {
|
||||
@@ -60,7 +60,7 @@ export const GPIO_VALIDATORR = {
|
||||
|
||||
export const GPIO_VALIDATORC3 = {
|
||||
validator(
|
||||
rule: InternalRuleItem,
|
||||
_rule: InternalRuleItem,
|
||||
value: number,
|
||||
callback: (error?: string) => void
|
||||
) {
|
||||
@@ -74,7 +74,7 @@ export const GPIO_VALIDATORC3 = {
|
||||
|
||||
export const GPIO_VALIDATORS2 = {
|
||||
validator(
|
||||
rule: InternalRuleItem,
|
||||
_rule: InternalRuleItem,
|
||||
value: number,
|
||||
callback: (error?: string) => void
|
||||
) {
|
||||
@@ -94,7 +94,7 @@ export const GPIO_VALIDATORS2 = {
|
||||
|
||||
export const GPIO_VALIDATORS3 = {
|
||||
validator(
|
||||
rule: InternalRuleItem,
|
||||
_rule: InternalRuleItem,
|
||||
value: number,
|
||||
callback: (error?: string) => void
|
||||
) {
|
||||
@@ -279,7 +279,7 @@ export const createSettingsValidator = (settings: Settings) =>
|
||||
|
||||
export const uniqueNameValidator = (schedule: ScheduleItem[], o_name?: string) => ({
|
||||
validator(
|
||||
rule: InternalRuleItem,
|
||||
_rule: InternalRuleItem,
|
||||
name: string,
|
||||
callback: (error?: string) => void
|
||||
) {
|
||||
@@ -324,7 +324,7 @@ export const uniqueCustomNameValidator = (
|
||||
o_name?: string
|
||||
) => ({
|
||||
validator(
|
||||
rule: InternalRuleItem,
|
||||
_rule: InternalRuleItem,
|
||||
name: string,
|
||||
callback: (error?: string) => void
|
||||
) {
|
||||
@@ -353,7 +353,7 @@ export const entityItemValidation = (entity: EntityItem[], entityItem: EntityIte
|
||||
device_id: [
|
||||
{
|
||||
validator(
|
||||
rule: InternalRuleItem,
|
||||
_rule: InternalRuleItem,
|
||||
value: string,
|
||||
callback: (error?: string) => void
|
||||
) {
|
||||
@@ -367,7 +367,7 @@ export const entityItemValidation = (entity: EntityItem[], entityItem: EntityIte
|
||||
type_id: [
|
||||
{
|
||||
validator(
|
||||
rule: InternalRuleItem,
|
||||
_rule: InternalRuleItem,
|
||||
value: string,
|
||||
callback: (error?: string) => void
|
||||
) {
|
||||
@@ -389,7 +389,7 @@ export const uniqueTemperatureNameValidator = (
|
||||
sensors: TemperatureSensor[],
|
||||
o_name?: string
|
||||
) => ({
|
||||
validator(rule: InternalRuleItem, n: string, callback: (error?: string) => void) {
|
||||
validator(_rule: InternalRuleItem, n: string, callback: (error?: string) => void) {
|
||||
if (
|
||||
(o_name === undefined || o_name.toLowerCase() !== n.toLowerCase()) &&
|
||||
n !== '' &&
|
||||
@@ -419,7 +419,7 @@ export const temperatureSensorItemValidation = (
|
||||
|
||||
export const isGPIOUniqueValidator = (sensors: AnalogSensor[]) => ({
|
||||
validator(
|
||||
rule: InternalRuleItem,
|
||||
_rule: InternalRuleItem,
|
||||
gpio: number,
|
||||
callback: (error?: string) => void
|
||||
) {
|
||||
@@ -435,7 +435,7 @@ export const uniqueAnalogNameValidator = (
|
||||
sensors: AnalogSensor[],
|
||||
o_name?: string
|
||||
) => ({
|
||||
validator(rule: InternalRuleItem, n: string, callback: (error?: string) => void) {
|
||||
validator(_rule: InternalRuleItem, n: string, callback: (error?: string) => void) {
|
||||
if (
|
||||
(o_name === undefined || o_name.toLowerCase() !== n.toLowerCase()) &&
|
||||
n !== '' &&
|
||||
@@ -482,7 +482,7 @@ export const deviceValueItemValidation = (dv: DeviceValue) =>
|
||||
{ required: true, message: 'Value is required' },
|
||||
{
|
||||
validator(
|
||||
rule: InternalRuleItem,
|
||||
_rule: InternalRuleItem,
|
||||
value: unknown,
|
||||
callback: (error?: string) => void
|
||||
) {
|
||||
|
||||
@@ -54,12 +54,12 @@ const APSettings = () => {
|
||||
origData,
|
||||
dirtyFlags,
|
||||
setDirtyFlags,
|
||||
updateDataValue
|
||||
updateDataValue as (value: unknown) => void
|
||||
);
|
||||
|
||||
const content = () => {
|
||||
if (!data) {
|
||||
return <FormLoader onRetry={loadData} errorMessage={errorMessage} />;
|
||||
return <FormLoader onRetry={loadData} errorMessage={errorMessage || ''} />;
|
||||
}
|
||||
|
||||
const validateAndSubmit = async () => {
|
||||
@@ -80,7 +80,7 @@ const APSettings = () => {
|
||||
return (
|
||||
<>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="provision_mode"
|
||||
label={LL.AP_PROVIDE() + '...'}
|
||||
value={data.provision_mode}
|
||||
@@ -103,7 +103,7 @@ const APSettings = () => {
|
||||
{isAPEnabled(data) && (
|
||||
<>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="ssid"
|
||||
label={LL.ACCESS_POINT(2) + ' SSID'}
|
||||
fullWidth
|
||||
@@ -113,7 +113,7 @@ const APSettings = () => {
|
||||
margin="normal"
|
||||
/>
|
||||
<ValidatedPasswordField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="password"
|
||||
label={LL.ACCESS_POINT(2) + ' ' + LL.PASSWORD()}
|
||||
fullWidth
|
||||
@@ -123,7 +123,7 @@ const APSettings = () => {
|
||||
margin="normal"
|
||||
/>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="channel"
|
||||
label={LL.AP_PREFERRED_CHANNEL()}
|
||||
value={numberValue(data.channel)}
|
||||
@@ -151,7 +151,7 @@ const APSettings = () => {
|
||||
label={LL.AP_HIDE_SSID()}
|
||||
/>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="max_clients"
|
||||
label={LL.AP_MAX_CLIENTS()}
|
||||
value={numberValue(data.max_clients)}
|
||||
@@ -169,7 +169,7 @@ const APSettings = () => {
|
||||
))}
|
||||
</ValidatedTextField>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="local_ip"
|
||||
label={LL.AP_LOCAL_IP()}
|
||||
fullWidth
|
||||
@@ -179,7 +179,7 @@ const APSettings = () => {
|
||||
margin="normal"
|
||||
/>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="gateway_ip"
|
||||
label={LL.NETWORK_GATEWAY()}
|
||||
fullWidth
|
||||
@@ -189,7 +189,7 @@ const APSettings = () => {
|
||||
margin="normal"
|
||||
/>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="subnet_mask"
|
||||
label={LL.NETWORK_SUBNET()}
|
||||
fullWidth
|
||||
|
||||
@@ -75,7 +75,7 @@ const ApplicationSettings = () => {
|
||||
origData,
|
||||
dirtyFlags,
|
||||
setDirtyFlags,
|
||||
updateDataValue
|
||||
updateDataValue as (value: unknown) => void
|
||||
);
|
||||
|
||||
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
|
||||
@@ -135,7 +135,7 @@ const ApplicationSettings = () => {
|
||||
|
||||
const content = () => {
|
||||
if (!data || !hardwareData) {
|
||||
return <FormLoader onRetry={loadData} errorMessage={errorMessage} />;
|
||||
return <FormLoader onRetry={loadData} errorMessage={errorMessage || ''} />;
|
||||
}
|
||||
|
||||
const validateAndSubmit = async () => {
|
||||
@@ -219,7 +219,7 @@ const ApplicationSettings = () => {
|
||||
<Grid container spacing={2} rowSpacing={0}>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="modbus_max_clients"
|
||||
label={LL.AP_MAX_CLIENTS()}
|
||||
variant="outlined"
|
||||
@@ -231,7 +231,7 @@ const ApplicationSettings = () => {
|
||||
</Grid>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="modbus_port"
|
||||
label="Port"
|
||||
variant="outlined"
|
||||
@@ -243,7 +243,7 @@ const ApplicationSettings = () => {
|
||||
</Grid>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="modbus_timeout"
|
||||
label="Timeout"
|
||||
slotProps={{
|
||||
@@ -273,7 +273,7 @@ const ApplicationSettings = () => {
|
||||
<Grid container spacing={2} rowSpacing={0}>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="syslog_host"
|
||||
label="Host"
|
||||
variant="outlined"
|
||||
@@ -284,7 +284,7 @@ const ApplicationSettings = () => {
|
||||
</Grid>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="syslog_port"
|
||||
label="Port"
|
||||
variant="outlined"
|
||||
@@ -315,7 +315,7 @@ const ApplicationSettings = () => {
|
||||
</Grid>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="syslog_mark_interval"
|
||||
label={LL.MARK_INTERVAL()}
|
||||
slotProps={{
|
||||
@@ -485,7 +485,7 @@ const ApplicationSettings = () => {
|
||||
<Grid container spacing={2} rowSpacing={0}>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="rx_gpio"
|
||||
label={LL.GPIO_OF('Rx')}
|
||||
fullWidth
|
||||
@@ -498,7 +498,7 @@ const ApplicationSettings = () => {
|
||||
</Grid>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="tx_gpio"
|
||||
label={LL.GPIO_OF('Tx')}
|
||||
fullWidth
|
||||
@@ -511,7 +511,7 @@ const ApplicationSettings = () => {
|
||||
</Grid>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="pbutton_gpio"
|
||||
label={LL.GPIO_OF(LL.BUTTON())}
|
||||
fullWidth
|
||||
@@ -524,7 +524,7 @@ const ApplicationSettings = () => {
|
||||
</Grid>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="dallas_gpio"
|
||||
label={
|
||||
LL.GPIO_OF(LL.TEMPERATURE()) + ' (0=' + LL.DISABLED(1) + ')'
|
||||
@@ -539,7 +539,7 @@ const ApplicationSettings = () => {
|
||||
</Grid>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="led_gpio"
|
||||
label={LL.GPIO_OF('LED') + ' (0=' + LL.DISABLED(1) + ')'}
|
||||
fullWidth
|
||||
@@ -743,7 +743,7 @@ const ApplicationSettings = () => {
|
||||
{data.remote_timeout_en && (
|
||||
<Box mt={2}>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="remote_timeout"
|
||||
label={LL.REMOTE_TIMEOUT()}
|
||||
slotProps={{
|
||||
@@ -783,7 +783,7 @@ const ApplicationSettings = () => {
|
||||
{data.shower_timer && (
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="shower_min_duration"
|
||||
label={LL.MIN_DURATION()}
|
||||
slotProps={{
|
||||
@@ -801,7 +801,7 @@ const ApplicationSettings = () => {
|
||||
<>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="shower_alert_trigger"
|
||||
label={LL.TRIGGER_TIME()}
|
||||
slotProps={{
|
||||
@@ -817,7 +817,7 @@ const ApplicationSettings = () => {
|
||||
</Grid>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="shower_alert_coldshot"
|
||||
label={LL.COLD_SHOT_DURATION()}
|
||||
slotProps={{
|
||||
|
||||
@@ -57,7 +57,7 @@ const DownloadUpload = () => {
|
||||
|
||||
const content = () => {
|
||||
if (!data) {
|
||||
return <FormLoader onRetry={loadData} errorMessage={error?.message} />;
|
||||
return <FormLoader onRetry={loadData} errorMessage={error?.message || ''} />;
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -56,7 +56,7 @@ const MqttSettings = () => {
|
||||
origData,
|
||||
dirtyFlags,
|
||||
setDirtyFlags,
|
||||
updateDataValue
|
||||
updateDataValue as (value: unknown) => void
|
||||
);
|
||||
|
||||
const SecondsInputProps = {
|
||||
@@ -65,7 +65,7 @@ const MqttSettings = () => {
|
||||
|
||||
const content = () => {
|
||||
if (!data) {
|
||||
return <FormLoader onRetry={loadData} errorMessage={errorMessage} />;
|
||||
return <FormLoader onRetry={loadData} errorMessage={errorMessage || ''} />;
|
||||
}
|
||||
|
||||
const validateAndSubmit = async () => {
|
||||
@@ -93,7 +93,7 @@ const MqttSettings = () => {
|
||||
<Grid container spacing={2} rowSpacing={0}>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="host"
|
||||
label={LL.ADDRESS_OF(LL.BROKER())}
|
||||
multiline
|
||||
@@ -105,7 +105,7 @@ const MqttSettings = () => {
|
||||
</Grid>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="port"
|
||||
label="Port"
|
||||
variant="outlined"
|
||||
@@ -117,7 +117,7 @@ const MqttSettings = () => {
|
||||
</Grid>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="base"
|
||||
label={LL.BASE_TOPIC()}
|
||||
variant="outlined"
|
||||
@@ -158,7 +158,7 @@ const MqttSettings = () => {
|
||||
</Grid>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="keep_alive"
|
||||
label="Keep Alive"
|
||||
slotProps={{
|
||||
@@ -354,7 +354,7 @@ const MqttSettings = () => {
|
||||
<Grid container spacing={2} rowSpacing={0}>
|
||||
<Grid>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="publish_time_heartbeat"
|
||||
label="Heartbeat"
|
||||
slotProps={{
|
||||
|
||||
@@ -76,7 +76,7 @@ const NTPSettings = () => {
|
||||
origData,
|
||||
dirtyFlags,
|
||||
setDirtyFlags,
|
||||
updateDataValue
|
||||
updateDataValue as (value: unknown) => void
|
||||
);
|
||||
|
||||
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
|
||||
@@ -155,7 +155,7 @@ const NTPSettings = () => {
|
||||
|
||||
const content = () => {
|
||||
if (!data) {
|
||||
return <FormLoader onRetry={loadData} errorMessage={errorMessage} />;
|
||||
return <FormLoader onRetry={loadData} errorMessage={errorMessage || ''} />;
|
||||
}
|
||||
|
||||
const validateAndSubmit = async () => {
|
||||
@@ -190,7 +190,7 @@ const NTPSettings = () => {
|
||||
label={LL.ENABLE_NTP()}
|
||||
/>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="server"
|
||||
label={LL.NTP_SERVER()}
|
||||
fullWidth
|
||||
@@ -200,7 +200,7 @@ const NTPSettings = () => {
|
||||
margin="normal"
|
||||
/>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="tz_label"
|
||||
label={LL.TIME_ZONE()}
|
||||
fullWidth
|
||||
|
||||
@@ -35,7 +35,7 @@ const Network = () => {
|
||||
],
|
||||
useLocation()
|
||||
);
|
||||
const routerTab = matchedRoutes?.[0].route.path || false;
|
||||
const routerTab = matchedRoutes?.[0]?.route.path || false;
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
@@ -56,7 +56,7 @@ const Network = () => {
|
||||
return (
|
||||
<WiFiConnectionContext.Provider
|
||||
value={{
|
||||
selectedNetwork,
|
||||
...(selectedNetwork && { selectedNetwork }),
|
||||
selectNetwork,
|
||||
deselectNetwork
|
||||
}}
|
||||
|
||||
@@ -104,7 +104,7 @@ const NetworkSettings = () => {
|
||||
origData,
|
||||
dirtyFlags,
|
||||
setDirtyFlags,
|
||||
updateDataValue
|
||||
updateDataValue as (value: unknown) => void
|
||||
);
|
||||
|
||||
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
|
||||
@@ -113,7 +113,7 @@ const NetworkSettings = () => {
|
||||
|
||||
const content = () => {
|
||||
if (!data) {
|
||||
return <FormLoader onRetry={loadData} errorMessage={errorMessage} />;
|
||||
return <FormLoader onRetry={loadData} errorMessage={errorMessage || ''} />;
|
||||
}
|
||||
|
||||
const validateAndSubmit = async () => {
|
||||
@@ -172,7 +172,7 @@ const NetworkSettings = () => {
|
||||
</List>
|
||||
) : (
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="ssid"
|
||||
label={'SSID (' + LL.NETWORK_BLANK_SSID() + ')'}
|
||||
fullWidth
|
||||
@@ -183,7 +183,7 @@ const NetworkSettings = () => {
|
||||
/>
|
||||
)}
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="bssid"
|
||||
label={'BSSID (' + LL.NETWORK_BLANK_BSSID() + ')'}
|
||||
fullWidth
|
||||
@@ -194,7 +194,7 @@ const NetworkSettings = () => {
|
||||
/>
|
||||
{(!selectedNetwork || !isNetworkOpen(selectedNetwork)) && (
|
||||
<ValidatedPasswordField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="password"
|
||||
label={LL.PASSWORD()}
|
||||
fullWidth
|
||||
@@ -251,7 +251,7 @@ const NetworkSettings = () => {
|
||||
{LL.GENERAL_OPTIONS()}
|
||||
</Typography>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="hostname"
|
||||
label={LL.HOSTNAME()}
|
||||
fullWidth
|
||||
@@ -304,7 +304,7 @@ const NetworkSettings = () => {
|
||||
{data.static_ip_config && (
|
||||
<>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="local_ip"
|
||||
label={LL.AP_LOCAL_IP()}
|
||||
fullWidth
|
||||
@@ -314,7 +314,7 @@ const NetworkSettings = () => {
|
||||
margin="normal"
|
||||
/>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="gateway_ip"
|
||||
label={LL.NETWORK_GATEWAY()}
|
||||
fullWidth
|
||||
@@ -324,7 +324,7 @@ const NetworkSettings = () => {
|
||||
margin="normal"
|
||||
/>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="subnet_mask"
|
||||
label={LL.NETWORK_SUBNET()}
|
||||
fullWidth
|
||||
@@ -334,7 +334,7 @@ const NetworkSettings = () => {
|
||||
margin="normal"
|
||||
/>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="dns_ip_1"
|
||||
label="DNS #1"
|
||||
fullWidth
|
||||
@@ -344,7 +344,7 @@ const NetworkSettings = () => {
|
||||
margin="normal"
|
||||
/>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="dns_ip_2"
|
||||
label="DNS #2"
|
||||
fullWidth
|
||||
|
||||
@@ -50,9 +50,7 @@ const WiFiNetworkScanner = () => {
|
||||
|
||||
const renderNetworkScanner = () => {
|
||||
if (!networkList) {
|
||||
return (
|
||||
<FormLoader message={LL.SCANNING() + '...'} errorMessage={errorMessage} />
|
||||
);
|
||||
return <FormLoader errorMessage={errorMessage || ''} />;
|
||||
}
|
||||
return <WiFiNetworkSelector networkList={networkList} />;
|
||||
};
|
||||
|
||||
@@ -97,7 +97,7 @@ const ManageUsers = () => {
|
||||
|
||||
const content = () => {
|
||||
if (!data) {
|
||||
return <FormLoader onRetry={loadData} errorMessage={errorMessage} />;
|
||||
return <FormLoader onRetry={loadData} errorMessage={errorMessage || ''} />;
|
||||
}
|
||||
|
||||
const noAdminConfigured = () => !data.users.find((u) => u.admin);
|
||||
@@ -260,15 +260,20 @@ const ManageUsers = () => {
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<GenerateToken username={generatingToken} onClose={closeGenerateToken} />
|
||||
<User
|
||||
user={user}
|
||||
setUser={setUser}
|
||||
creating={creating}
|
||||
onDoneEditing={doneEditingUser}
|
||||
onCancelEditing={cancelEditingUser}
|
||||
validator={createUserValidator(data.users, creating)}
|
||||
<GenerateToken
|
||||
username={generatingToken || ''}
|
||||
onClose={closeGenerateToken}
|
||||
/>
|
||||
{user && (
|
||||
<User
|
||||
user={user}
|
||||
setUser={setUser}
|
||||
creating={creating}
|
||||
onDoneEditing={doneEditingUser}
|
||||
onCancelEditing={cancelEditingUser}
|
||||
validator={createUserValidator(data.users, creating)}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@ const Security = () => {
|
||||
],
|
||||
useLocation()
|
||||
);
|
||||
const routerTab = matchedRoutes?.[0].route.path || false;
|
||||
const routerTab = matchedRoutes?.[0]?.route.path || false;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -47,12 +47,12 @@ const SecuritySettings = () => {
|
||||
origData,
|
||||
dirtyFlags,
|
||||
setDirtyFlags,
|
||||
updateDataValue
|
||||
updateDataValue as (value: unknown) => void
|
||||
);
|
||||
|
||||
const content = () => {
|
||||
if (!data) {
|
||||
return <FormLoader onRetry={loadData} errorMessage={errorMessage} />;
|
||||
return <FormLoader onRetry={loadData} errorMessage={errorMessage || ''} />;
|
||||
}
|
||||
|
||||
const validateAndSubmit = async () => {
|
||||
@@ -69,7 +69,7 @@ const SecuritySettings = () => {
|
||||
return (
|
||||
<>
|
||||
<ValidatedPasswordField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="jwt_secret"
|
||||
label={LL.SU_PASSWORD()}
|
||||
fullWidth
|
||||
|
||||
@@ -82,7 +82,7 @@ const User: FC<UserFormProps> = ({
|
||||
</DialogTitle>
|
||||
<DialogContent dividers>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="username"
|
||||
label={LL.USERNAME(1)}
|
||||
fullWidth
|
||||
@@ -93,7 +93,7 @@ const User: FC<UserFormProps> = ({
|
||||
margin="normal"
|
||||
/>
|
||||
<ValidatedPasswordField
|
||||
fieldErrors={fieldErrors}
|
||||
fieldErrors={fieldErrors || {}}
|
||||
name="password"
|
||||
label={LL.PASSWORD()}
|
||||
fullWidth
|
||||
|
||||
@@ -61,7 +61,7 @@ const APStatus = () => {
|
||||
|
||||
const content = () => {
|
||||
if (!data) {
|
||||
return <FormLoader onRetry={loadData} errorMessage={error?.message} />;
|
||||
return <FormLoader onRetry={loadData} errorMessage={error?.message || ''} />;
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -67,7 +67,8 @@ const SystemActivity = () => {
|
||||
});
|
||||
|
||||
const showName = (id: number) => {
|
||||
const name: keyof Translation['STATUS_NAMES'] = id;
|
||||
const name: keyof Translation['STATUS_NAMES'] =
|
||||
id.toString() as keyof Translation['STATUS_NAMES'];
|
||||
return LL.STATUS_NAMES[name]();
|
||||
};
|
||||
|
||||
@@ -87,7 +88,7 @@ const SystemActivity = () => {
|
||||
|
||||
const content = () => {
|
||||
if (!data) {
|
||||
return <FormLoader onRetry={loadData} errorMessage={error?.message} />;
|
||||
return <FormLoader onRetry={loadData} errorMessage={error?.message || ''} />;
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -41,7 +41,7 @@ const HardwareStatus = () => {
|
||||
|
||||
const content = () => {
|
||||
if (!data) {
|
||||
return <FormLoader onRetry={loadData} errorMessage={error?.message} />;
|
||||
return <FormLoader onRetry={loadData} errorMessage={error?.message || ''} />;
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -99,7 +99,7 @@ const MqttStatus = () => {
|
||||
|
||||
const content = () => {
|
||||
if (!data) {
|
||||
return <FormLoader onRetry={loadData} errorMessage={error?.message} />;
|
||||
return <FormLoader onRetry={loadData} errorMessage={error?.message || ''} />;
|
||||
}
|
||||
|
||||
const renderConnectionStatus = () => (
|
||||
|
||||
@@ -68,7 +68,7 @@ const NTPStatus = () => {
|
||||
|
||||
const content = () => {
|
||||
if (!data) {
|
||||
return <FormLoader onRetry={loadData} errorMessage={error?.message} />;
|
||||
return <FormLoader onRetry={loadData} errorMessage={error?.message || ''} />;
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -120,7 +120,7 @@ const NetworkStatus = () => {
|
||||
|
||||
const content = () => {
|
||||
if (!data) {
|
||||
return <FormLoader onRetry={loadData} errorMessage={error?.message} />;
|
||||
return <FormLoader onRetry={loadData} errorMessage={error?.message || ''} />;
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -248,7 +248,7 @@ const SystemStatus = () => {
|
||||
|
||||
const content = () => {
|
||||
if (!data || !LL) {
|
||||
return <FormLoader onRetry={loadData} errorMessage={error?.message} />;
|
||||
return <FormLoader onRetry={loadData} errorMessage={error?.message || ''} />;
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -31,13 +31,14 @@ import type { LogEntry, LogSettings } from 'types';
|
||||
import { LogLevel } from 'types';
|
||||
import { updateValueDirty, useRest } from 'utils';
|
||||
|
||||
const TextColors = {
|
||||
const TextColors: Record<LogLevel, string> = {
|
||||
[LogLevel.ERROR]: '#ff0000', // red
|
||||
[LogLevel.WARNING]: '#ff0000', // red
|
||||
[LogLevel.NOTICE]: '#ffffff', // white
|
||||
[LogLevel.INFO]: '#ffcc00', // yellow
|
||||
[LogLevel.DEBUG]: '#00ffff', // cyan
|
||||
[LogLevel.TRACE]: '#00ffff' // cyan
|
||||
[LogLevel.TRACE]: '#00ffff', // cyan
|
||||
[LogLevel.ALL]: '#ffffff' // white
|
||||
};
|
||||
|
||||
const LogEntryLine = styled('span')(
|
||||
@@ -109,7 +110,7 @@ const SystemLog = () => {
|
||||
origData,
|
||||
dirtyFlags,
|
||||
setDirtyFlags,
|
||||
updateDataValue
|
||||
updateDataValue as (value: unknown) => void
|
||||
);
|
||||
|
||||
useSSE(fetchLogES, {
|
||||
@@ -190,7 +191,7 @@ const SystemLog = () => {
|
||||
|
||||
const content = () => {
|
||||
if (!data) {
|
||||
return <FormLoader onRetry={loadData} errorMessage={errorMessage} />;
|
||||
return <FormLoader onRetry={loadData} errorMessage={errorMessage || ''} />;
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -110,7 +110,7 @@ const Version = () => {
|
||||
}, [latestVersion, latestDevVersion]);
|
||||
|
||||
const rtf = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });
|
||||
const DIVISIONS = [
|
||||
const DIVISIONS: Array<{ amount: number; name: string }> = [
|
||||
{ amount: 60, name: 'seconds' },
|
||||
{ amount: 60, name: 'minutes' },
|
||||
{ amount: 24, name: 'hours' },
|
||||
@@ -119,18 +119,21 @@ const Version = () => {
|
||||
{ amount: 12, name: 'months' },
|
||||
{ amount: Number.POSITIVE_INFINITY, name: 'years' }
|
||||
];
|
||||
function formatTimeAgo(date) {
|
||||
function formatTimeAgo(date: 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) {
|
||||
if (division && Math.abs(duration) < division.amount) {
|
||||
return rtf.format(
|
||||
Math.round(duration),
|
||||
division.name as Intl.RelativeTimeFormatUnit
|
||||
);
|
||||
}
|
||||
duration /= division.amount;
|
||||
if (division) {
|
||||
duration /= division.amount;
|
||||
}
|
||||
}
|
||||
return rtf.format(0, 'seconds');
|
||||
}
|
||||
|
||||
const { send: sendAPI } = useRequest((data: APIcall) => API(data), {
|
||||
@@ -270,6 +273,14 @@ const Version = () => {
|
||||
<span style={{ color: '#66bb6a', fontSize: '0.8em' }}>
|
||||
{LL.LATEST_VERSION(usingDevVersion ? LL.DEVELOPMENT() : LL.STABLE())}
|
||||
</span>
|
||||
<Button
|
||||
sx={{ ml: 2 }}
|
||||
variant="outlined"
|
||||
size="small"
|
||||
onClick={() => showFirmwareDialog(showingDev)}
|
||||
>
|
||||
{LL.REINSTALL()}
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -293,7 +304,7 @@ const Version = () => {
|
||||
|
||||
const content = () => {
|
||||
if (!data) {
|
||||
return <FormLoader onRetry={loadData} errorMessage={error?.message} />;
|
||||
return <FormLoader onRetry={loadData} errorMessage={error?.message || ''} />;
|
||||
}
|
||||
|
||||
const isDev = data.emsesp_version.includes('dev');
|
||||
|
||||
@@ -1,26 +1,24 @@
|
||||
import type { FC } from 'react';
|
||||
import { memo } from 'react';
|
||||
|
||||
import { Box } from '@mui/material';
|
||||
import type { BoxProps } from '@mui/material';
|
||||
|
||||
const ButtonRow: FC<BoxProps> = ({ children, ...rest }) => (
|
||||
const ButtonRow = memo<BoxProps>(({ children, ...rest }) => (
|
||||
<Box
|
||||
sx={{
|
||||
'& button, & a, & .MuiCard-root': {
|
||||
mt: 2,
|
||||
mx: 0.6,
|
||||
'&:last-child': {
|
||||
mr: 0
|
||||
},
|
||||
'&:first-of-type': {
|
||||
ml: 0
|
||||
}
|
||||
'&:last-child': { mr: 0 },
|
||||
'&:first-of-type': { ml: 0 }
|
||||
}
|
||||
}}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
);
|
||||
));
|
||||
|
||||
ButtonRow.displayName = 'ButtonRow';
|
||||
|
||||
export default ButtonRow;
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import { Tooltip, type TooltipProps, styled, tooltipClasses } from '@mui/material';
|
||||
|
||||
export const ButtonTooltip = styled(({ className, ...props }: TooltipProps) => (
|
||||
<Tooltip {...props} placement="top" arrow classes={{ popper: className }} />
|
||||
<Tooltip
|
||||
{...props}
|
||||
placement="top"
|
||||
arrow
|
||||
classes={{ ...(className && { popper: className }) }}
|
||||
/>
|
||||
))(({ theme }) => ({
|
||||
[`& .${tooltipClasses.arrow}`]: {
|
||||
color: theme.palette.success.main
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
// Optimized exports - use direct exports to reduce bundle size
|
||||
export { default as SectionContent } from './SectionContent';
|
||||
export { default as ButtonRow } from './ButtonRow';
|
||||
export { default as MessageBox } from './MessageBox';
|
||||
export { default as ButtonTooltip } from './ButtonTooltip';
|
||||
|
||||
// Re-export sub-modules
|
||||
export * from './inputs';
|
||||
export * from './layout';
|
||||
export * from './loading';
|
||||
export * from './routing';
|
||||
export * from './upload';
|
||||
export { default as SectionContent } from './SectionContent';
|
||||
export { default as ButtonRow } from './ButtonRow';
|
||||
export { default as MessageBox } from './MessageBox';
|
||||
|
||||
// Specific routing exports
|
||||
export { default as BlockNavigation } from './routing/BlockNavigation';
|
||||
export { default as ButtonTooltip } from './ButtonTooltip';
|
||||
|
||||
@@ -16,14 +16,14 @@ const ValidatedTextField: FC<ValidatedTextFieldProps> = ({
|
||||
fieldErrors,
|
||||
...rest
|
||||
}) => {
|
||||
const errors = fieldErrors && fieldErrors[rest.name];
|
||||
const renderErrors = () =>
|
||||
errors &&
|
||||
errors.map((e) => <FormHelperText key={e.message}>{e.message}</FormHelperText>);
|
||||
const errors = fieldErrors?.[rest.name];
|
||||
|
||||
return (
|
||||
<>
|
||||
<TextField error={!!errors} {...rest} />
|
||||
{renderErrors()}
|
||||
{errors?.map((e) => (
|
||||
<FormHelperText key={e.message}>{e.message}</FormHelperText>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -23,7 +23,12 @@ const LayoutMenuItem = ({
|
||||
const selected = routeMatches(to, pathname);
|
||||
|
||||
return (
|
||||
<ListItemButton component={Link} to={to} disabled={disabled} selected={selected}>
|
||||
<ListItemButton
|
||||
component={Link}
|
||||
to={to}
|
||||
disabled={disabled || false}
|
||||
selected={selected}
|
||||
>
|
||||
<ListItemIcon sx={{ color: selected ? '#90caf9' : '#9e9e9e' }}>
|
||||
<Icon />
|
||||
</ListItemIcon>
|
||||
|
||||
@@ -58,12 +58,22 @@ const LayoutMenuItem = ({
|
||||
}
|
||||
>
|
||||
<ListItemButton component={Link} to={to}>
|
||||
<RenderIcon icon={icon} bgcolor={bgcolor} label={label} text={text} />
|
||||
<RenderIcon
|
||||
icon={icon}
|
||||
{...(bgcolor && { bgcolor })}
|
||||
label={label}
|
||||
text={text}
|
||||
/>
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
) : (
|
||||
<ListItem>
|
||||
<RenderIcon icon={icon} bgcolor={bgcolor} label={label} text={text} />
|
||||
<RenderIcon
|
||||
icon={icon}
|
||||
{...(bgcolor && { bgcolor })}
|
||||
label={label}
|
||||
text={text}
|
||||
/>
|
||||
</ListItem>
|
||||
)}
|
||||
</>
|
||||
|
||||
20
interface/src/components/loading/LazyLoader.tsx
Normal file
20
interface/src/components/loading/LazyLoader.tsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import { Box, CircularProgress } from '@mui/material';
|
||||
|
||||
const LazyLoader = () => (
|
||||
<Box
|
||||
display="flex"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
minHeight="200px"
|
||||
sx={{
|
||||
backgroundColor: 'background.default',
|
||||
borderRadius: 1,
|
||||
border: '1px solid',
|
||||
borderColor: 'divider'
|
||||
}}
|
||||
>
|
||||
<CircularProgress size={40} />
|
||||
</Box>
|
||||
);
|
||||
|
||||
export default LazyLoader;
|
||||
@@ -1,2 +1,3 @@
|
||||
export { default as LoadingSpinner } from './LoadingSpinner';
|
||||
export { default as FormLoader } from './FormLoader';
|
||||
export { default as LazyLoader } from './LazyLoader';
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { Path } from 'react-router';
|
||||
|
||||
import type * as H from 'history';
|
||||
import { jwtDecode } from 'jwt-decode';
|
||||
import type { Me, SignInRequest, SignInResponse } from 'types';
|
||||
|
||||
@@ -18,10 +17,10 @@ export function getStorage() {
|
||||
return localStorage || sessionStorage;
|
||||
}
|
||||
|
||||
export function storeLoginRedirect(location?: H.Location) {
|
||||
export function storeLoginRedirect(location?: { pathname: string; search: string }) {
|
||||
if (location) {
|
||||
getStorage().setItem(SIGN_IN_PATHNAME, location.pathname as string);
|
||||
getStorage().setItem(SIGN_IN_SEARCH, location.search as string);
|
||||
getStorage().setItem(SIGN_IN_PATHNAME, location.pathname);
|
||||
getStorage().setItem(SIGN_IN_SEARCH, location.search);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +35,7 @@ export function fetchLoginRedirect(): Partial<Path> {
|
||||
clearLoginRedirect();
|
||||
return {
|
||||
pathname: signInPathname || `/dashboard`,
|
||||
search: (signInPathname && signInSearch) || undefined
|
||||
...(signInPathname && signInSearch && { search: signInSearch })
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,59 @@
|
||||
// Code inspired by Prince Azubuike from https://medium.com/@dprincecoder/creating-a-drag-and-drop-file-upload-component-in-react-a-step-by-step-guide-4d93b6cc21e0
|
||||
import { type ChangeEvent, useRef, useState } from 'react';
|
||||
import {
|
||||
type ChangeEvent,
|
||||
type DragEvent,
|
||||
type MouseEvent,
|
||||
useRef,
|
||||
useState
|
||||
} from 'react';
|
||||
|
||||
import CancelIcon from '@mui/icons-material/Cancel';
|
||||
import CloudUploadIcon from '@mui/icons-material/CloudUpload';
|
||||
import UploadIcon from '@mui/icons-material/Upload';
|
||||
import { Box, Button } from '@mui/material';
|
||||
import { Box, Button, Typography, styled } from '@mui/material';
|
||||
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
|
||||
import './dragNdrop.css';
|
||||
const DocumentUploader = styled(Box)<{ active?: boolean }>(({ theme, active }) => ({
|
||||
border: `2px dashed ${active ? '#6dc24b' : '#4282fe'}`,
|
||||
backgroundColor: '#2e3339',
|
||||
padding: theme.spacing(1.25),
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
position: 'relative',
|
||||
borderRadius: theme.spacing(1),
|
||||
cursor: 'pointer',
|
||||
minHeight: '120px',
|
||||
transition: 'border-color 0.2s ease-in-out'
|
||||
}));
|
||||
|
||||
const DragNdrop = ({ text, onFileSelected }) => {
|
||||
const UploadInfo = styled(Box)({
|
||||
display: 'flex',
|
||||
alignItems: 'center'
|
||||
});
|
||||
|
||||
const FileInfo = styled(Box)({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
width: '100%',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center'
|
||||
});
|
||||
|
||||
const FileName = styled(Typography)(({ theme }) => ({
|
||||
fontSize: '14px',
|
||||
color: '#6dc24b',
|
||||
margin: theme.spacing(1, 0)
|
||||
}));
|
||||
|
||||
interface DragNdropProps {
|
||||
text: string;
|
||||
onFileSelected: (file: File) => void;
|
||||
}
|
||||
|
||||
const DragNdrop = ({ text, onFileSelected }: DragNdropProps) => {
|
||||
const [file, setFile] = useState<File>();
|
||||
const [dragged, setDragged] = useState(false);
|
||||
const inputRef = useRef<HTMLInputElement | null>(null);
|
||||
@@ -28,14 +71,17 @@ const DragNdrop = ({ text, onFileSelected }) => {
|
||||
};
|
||||
|
||||
const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||
if (!e.target.files) {
|
||||
if (!e.target.files || e.target.files.length === 0) {
|
||||
return;
|
||||
}
|
||||
checkFileExtension(e.target.files[0]);
|
||||
const selectedFile = e.target.files[0];
|
||||
if (selectedFile) {
|
||||
checkFileExtension(selectedFile);
|
||||
}
|
||||
e.target.value = ''; // this is to allow the same file to be selected again
|
||||
};
|
||||
|
||||
const handleDrop = (event) => {
|
||||
const handleDrop = (event: DragEvent<HTMLDivElement>) => {
|
||||
event.preventDefault();
|
||||
const droppedFiles = event.dataTransfer.files;
|
||||
if (droppedFiles.length > 0) {
|
||||
@@ -43,38 +89,40 @@ const DragNdrop = ({ text, onFileSelected }) => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleRemoveFile = (event) => {
|
||||
const handleRemoveFile = (event: MouseEvent<HTMLButtonElement>) => {
|
||||
event.stopPropagation();
|
||||
setFile(undefined);
|
||||
setDragged(false);
|
||||
};
|
||||
|
||||
const handleUploadClick = (event) => {
|
||||
const handleUploadClick = (event: MouseEvent<HTMLButtonElement>) => {
|
||||
event.stopPropagation();
|
||||
onFileSelected(file);
|
||||
if (file) {
|
||||
onFileSelected(file);
|
||||
}
|
||||
};
|
||||
|
||||
const handleBrowseClick = () => {
|
||||
inputRef.current?.click();
|
||||
};
|
||||
|
||||
const handleDragOver = (event) => {
|
||||
const handleDragOver = (event: DragEvent<HTMLDivElement>) => {
|
||||
event.preventDefault(); // prevent file from being opened
|
||||
setDragged(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`document-uploader ${file || dragged ? 'active' : ''}`}
|
||||
<DocumentUploader
|
||||
active={!!(file || dragged)}
|
||||
onDrop={handleDrop}
|
||||
onDragOver={handleDragOver}
|
||||
onDragLeave={() => setDragged(false)}
|
||||
onClick={handleBrowseClick}
|
||||
>
|
||||
<div className="upload-info">
|
||||
<UploadInfo>
|
||||
<CloudUploadIcon sx={{ marginRight: 4 }} color="primary" fontSize="large" />
|
||||
<p>{text}</p>
|
||||
</div>
|
||||
<Typography>{text}</Typography>
|
||||
</UploadInfo>
|
||||
|
||||
<input
|
||||
type="file"
|
||||
@@ -88,9 +136,9 @@ const DragNdrop = ({ text, onFileSelected }) => {
|
||||
|
||||
{file && (
|
||||
<>
|
||||
<div className="file-info">
|
||||
<p>{file.name}</p>
|
||||
</div>
|
||||
<FileInfo>
|
||||
<FileName>{file.name}</FileName>
|
||||
</FileInfo>
|
||||
<Box>
|
||||
<Button
|
||||
startIcon={<CancelIcon />}
|
||||
@@ -112,7 +160,7 @@ const DragNdrop = ({ text, onFileSelected }) => {
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</DocumentUploader>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -12,7 +12,12 @@ import { useI18nContext } from 'i18n/i18n-react';
|
||||
import DragNdrop from './DragNdrop';
|
||||
import { LinearProgressWithLabel } from './LinearProgressWithLabel';
|
||||
|
||||
const SingleUpload = ({ text, doRestart }) => {
|
||||
interface SingleUploadProps {
|
||||
text: string;
|
||||
doRestart: () => void;
|
||||
}
|
||||
|
||||
const SingleUpload = ({ text, doRestart }: SingleUploadProps) => {
|
||||
const [md5, setMd5] = useState<string>();
|
||||
const [file, setFile] = useState<File>();
|
||||
const { LL } = useI18nContext();
|
||||
@@ -25,8 +30,8 @@ const SingleUpload = ({ text, doRestart }) => {
|
||||
} = useRequest(SystemApi.uploadFile, {
|
||||
immediate: false
|
||||
}).onSuccess(({ data }) => {
|
||||
if (data) {
|
||||
setMd5(data.md5 as string);
|
||||
if (data && typeof data === 'object' && 'md5' in data) {
|
||||
setMd5((data as { md5: string }).md5);
|
||||
toast.success(LL.UPLOAD() + ' MD5 ' + LL.SUCCESSFUL());
|
||||
setFile(undefined);
|
||||
} else {
|
||||
@@ -34,16 +39,19 @@ const SingleUpload = ({ text, doRestart }) => {
|
||||
}
|
||||
});
|
||||
|
||||
useEffect(async () => {
|
||||
if (file) {
|
||||
await sendUpload(file).catch((error: Error) => {
|
||||
if (error.message === 'The user aborted a request') {
|
||||
toast.warning(LL.UPLOAD() + ' ' + LL.ABORTED());
|
||||
} else {
|
||||
toast.warning('Invalid file extension or incompatible bin file');
|
||||
}
|
||||
});
|
||||
}
|
||||
useEffect(() => {
|
||||
const uploadFile = async () => {
|
||||
if (file) {
|
||||
await sendUpload(file).catch((error: Error) => {
|
||||
if (error.message.includes('The user aborted a request')) {
|
||||
toast.warning(LL.UPLOAD() + ' ' + LL.ABORTED());
|
||||
} else {
|
||||
toast.warning('Invalid file extension or incompatible bin file');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
void uploadFile();
|
||||
}, [file]);
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
.document-uploader {
|
||||
border: 2px dashed #4282fe;
|
||||
background-color: #2e3339;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
|
||||
&.active {
|
||||
border-color: #6dc24b;
|
||||
}
|
||||
|
||||
.upload-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.file-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
p {
|
||||
font-size: 14px;
|
||||
color: #6dc24b;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -69,7 +69,12 @@ const Authentication: FC<RequiredChildrenProps> = ({ children }) => {
|
||||
|
||||
// cache object to prevent re-renders
|
||||
const obj = useMemo(
|
||||
() => ({ signIn, signOut, me, refresh }),
|
||||
() => ({
|
||||
signIn,
|
||||
signOut,
|
||||
refresh,
|
||||
...(me && { me })
|
||||
}),
|
||||
[signIn, signOut, me, refresh]
|
||||
);
|
||||
|
||||
|
||||
@@ -162,6 +162,7 @@ const cz: Translation = {
|
||||
UPLOAD: 'Nahrát',
|
||||
DOWNLOAD: '{{S|s|s}}táhnout',
|
||||
INSTALL: 'Instalovat',
|
||||
REINSTALL: 'Znovu instalovat',
|
||||
ABORTED: 'přerušeno',
|
||||
FAILED: 'neúspěšné',
|
||||
SUCCESSFUL: 'úspěšné',
|
||||
|
||||
@@ -162,6 +162,7 @@ const de: Translation = {
|
||||
UPLOAD: 'Hochladen',
|
||||
DOWNLOAD: '{{Herunterladen|heruntergeladen|}}',
|
||||
INSTALL: 'Installieren',
|
||||
REINSTALL: 'Neu installieren',
|
||||
ABORTED: 'abgebrochen',
|
||||
FAILED: 'gescheitert',
|
||||
SUCCESSFUL: 'erfolgreich',
|
||||
|
||||
@@ -162,6 +162,7 @@ const en: Translation = {
|
||||
UPLOAD: 'Upload',
|
||||
DOWNLOAD: '{{D|d|d}}ownload',
|
||||
INSTALL: 'Install',
|
||||
REINSTALL: 'Reinstall',
|
||||
ABORTED: 'aborted',
|
||||
FAILED: 'failed',
|
||||
SUCCESSFUL: 'successful',
|
||||
|
||||
@@ -162,6 +162,7 @@ const fr: Translation = {
|
||||
UPLOAD: 'Upload',
|
||||
DOWNLOAD: '{{D|d|d}}ownload',
|
||||
INSTALL: 'Installer',
|
||||
REINSTALL: 'Réinstaller',
|
||||
ABORTED: 'annulé',
|
||||
FAILED: 'échoué',
|
||||
SUCCESSFUL: 'réussi',
|
||||
|
||||
@@ -162,6 +162,7 @@ const it: Translation = {
|
||||
UPLOAD: 'Carica',
|
||||
DOWNLOAD: 'Scarica',
|
||||
INSTALL: 'Installare {0}',
|
||||
REINSTALL: 'Riavviare',
|
||||
ABORTED: 'Annullato',
|
||||
FAILED: 'Fallito',
|
||||
SUCCESSFUL: 'Riuscito',
|
||||
|
||||
@@ -162,6 +162,7 @@ const nl: Translation = {
|
||||
UPLOAD: 'Upload',
|
||||
DOWNLOAD: '{{D|d|d}}ownload',
|
||||
INSTALL: 'Installeren',
|
||||
REINSTALL: 'Opnieuw installeren',
|
||||
ABORTED: 'afgebroken',
|
||||
FAILED: 'mislukt',
|
||||
SUCCESSFUL: 'successvol',
|
||||
|
||||
@@ -162,6 +162,7 @@ const no: Translation = {
|
||||
UPLOAD: 'Opplasning',
|
||||
DOWNLOAD: '{{N|n|n}}edlasting',
|
||||
INSTALL: 'Installer',
|
||||
REINSTALL: 'Ominstaller',
|
||||
ABORTED: 'avbrutt',
|
||||
FAILED: 'feilet',
|
||||
SUCCESSFUL: 'vellykket',
|
||||
|
||||
@@ -162,6 +162,7 @@ const pl: BaseTranslation = {
|
||||
UPLOAD: 'Wysyłanie',
|
||||
DOWNLOAD: '{{P|p||P}}obier{{anie|z||z}}',
|
||||
INSTALL: 'Zainstalować',
|
||||
REINSTALL: 'Zainstalować ponownie',
|
||||
ABORTED: 'zostało przerwane!',
|
||||
FAILED: 'nie powiodł{{o|a|}} się!',
|
||||
SUCCESSFUL: 'powiodło się.',
|
||||
|
||||
@@ -162,6 +162,7 @@ const sk: Translation = {
|
||||
UPLOAD: 'Nahrať',
|
||||
DOWNLOAD: '{{S|s|s}}tiahnuť',
|
||||
INSTALL: 'Inštalovať',
|
||||
REINSTALL: 'Inštalovať znova',
|
||||
ABORTED: 'zrušené',
|
||||
FAILED: 'chybné',
|
||||
SUCCESSFUL: 'úspešné',
|
||||
|
||||
@@ -162,6 +162,7 @@ const sv: Translation = {
|
||||
UPLOAD: 'Uppladdning',
|
||||
DOWNLOAD: '{{N|n|n}}edladdning',
|
||||
INSTALL: 'Installera',
|
||||
REINSTALL: 'Återinstallera',
|
||||
ABORTED: 'Avbruten',
|
||||
FAILED: 'Misslyckades',
|
||||
SUCCESSFUL: 'Lyckades',
|
||||
|
||||
@@ -162,6 +162,7 @@ const tr: Translation = {
|
||||
UPLOAD: 'Yükleme',
|
||||
DOWNLOAD: '{{İ|i|i}}İndirme',
|
||||
INSTALL: 'Düzenlemek',
|
||||
REINSTALL: 'Yeniden düzenlemek',
|
||||
ABORTED: 'iptal edildi',
|
||||
FAILED: 'başarısız',
|
||||
SUCCESSFUL: 'başarılı',
|
||||
|
||||
@@ -13,7 +13,7 @@ const router = createBrowserRouter(
|
||||
createRoutesFromElements(<Route path="/*" element={<App />} />)
|
||||
);
|
||||
|
||||
createRoot(document.getElementById('root') as HTMLElement).render(
|
||||
createRoot(document.getElementById('root')!).render(
|
||||
<StrictMode>
|
||||
<RouterProvider router={router} />
|
||||
</StrictMode>
|
||||
|
||||
@@ -29,10 +29,10 @@ export const updateValue =
|
||||
|
||||
export const updateValueDirty =
|
||||
(
|
||||
origData,
|
||||
origData: unknown,
|
||||
dirtyFlags: string[],
|
||||
setDirtyFlags: React.Dispatch<React.SetStateAction<string[]>>,
|
||||
updateDataValue: (unknown) => void
|
||||
updateDataValue: (value: unknown) => void
|
||||
) =>
|
||||
(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const updated_value = extractEventValue(event);
|
||||
|
||||
@@ -1,31 +1,108 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
// Target modern browsers for better performance
|
||||
"target": "ES2022",
|
||||
"useDefineForClassFields": true,
|
||||
"lib": ["DOM", "DOM.Iterable", "ESNext"],
|
||||
"types": ["node"],
|
||||
|
||||
// Optimized library selection
|
||||
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||
"types": ["node", "vite/client"],
|
||||
|
||||
// JavaScript handling
|
||||
"allowJs": false,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": false,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"composite": true,
|
||||
"checkJs": false,
|
||||
|
||||
// Module system optimized for Vite
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"esModuleInterop": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
|
||||
// Emit configuration
|
||||
"noEmit": true,
|
||||
"useUnknownInCatchVariables": false,
|
||||
"declaration": false,
|
||||
"declarationMap": false,
|
||||
"sourceMap": false,
|
||||
|
||||
// React/JSX configuration
|
||||
"jsx": "react-jsx",
|
||||
"noImplicitAny": false,
|
||||
"baseUrl": "src",
|
||||
"jsxImportSource": "react",
|
||||
|
||||
// Strict type checking for better code quality
|
||||
"strict": true,
|
||||
"noImplicitAny": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true,
|
||||
"strictBindCallApply": true,
|
||||
"strictPropertyInitialization": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"exactOptionalPropertyTypes": true,
|
||||
|
||||
// Additional checks
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"useUnknownInCatchVariables": true,
|
||||
|
||||
// Performance optimizations
|
||||
"skipLibCheck": true,
|
||||
"skipDefaultLibCheck": true,
|
||||
"incremental": true,
|
||||
"tsBuildInfoFile": ".tsbuildinfo",
|
||||
|
||||
// Path mapping for cleaner imports
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@": ["src"],
|
||||
"@/*": ["src/*"]
|
||||
"@/*": ["src/*"],
|
||||
"@/components/*": ["src/components/*"],
|
||||
"@/utils/*": ["src/utils/*"],
|
||||
"@/types/*": ["src/types/*"],
|
||||
"@/hooks/*": ["src/hooks/*"],
|
||||
"@/services/*": ["src/services/*"],
|
||||
"@/assets/*": ["src/assets/*"],
|
||||
// Support for bare imports from src directory
|
||||
"App": ["src/App"],
|
||||
"AppRouting": ["src/AppRouting"],
|
||||
"CustomTheme": ["src/CustomTheme"],
|
||||
"SignIn": ["src/SignIn"],
|
||||
"AuthenticatedRouting": ["src/AuthenticatedRouting"],
|
||||
"env": ["src/env"],
|
||||
"components": ["src/components"],
|
||||
"contexts": ["src/contexts"],
|
||||
"i18n": ["src/i18n"],
|
||||
"utils": ["src/utils"],
|
||||
"validators": ["src/validators"],
|
||||
"types": ["src/types"],
|
||||
"api": ["src/api"],
|
||||
"app": ["src/app"],
|
||||
// Wildcard patterns for subdirectories
|
||||
"components/*": ["src/components/*"],
|
||||
"contexts/*": ["src/contexts/*"],
|
||||
"i18n/*": ["src/i18n/*"],
|
||||
"utils/*": ["src/utils/*"],
|
||||
"validators/*": ["src/validators/*"],
|
||||
"types/*": ["src/types/*"],
|
||||
"api/*": ["src/api/*"],
|
||||
"app/*": ["src/app/*"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*", "vite.config.ts"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
"include": ["src/**/*", "vite.config.ts", "progmem-generator.js"],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"dist",
|
||||
"build",
|
||||
".tsbuildinfo",
|
||||
"**/*.test.ts",
|
||||
"**/*.test.tsx",
|
||||
"**/*.spec.ts",
|
||||
"**/*.spec.tsx"
|
||||
],
|
||||
"ts-node": {
|
||||
"esm": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,130 +1,331 @@
|
||||
import preact from '@preact/preset-vite';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { visualizer } from 'rollup-plugin-visualizer';
|
||||
import { defineConfig } from 'vite';
|
||||
// import viteImagemin from 'vite-plugin-imagemin';
|
||||
import { Plugin } from 'vite';
|
||||
import viteImagemin from 'vite-plugin-imagemin';
|
||||
import viteTsconfigPaths from 'vite-tsconfig-paths';
|
||||
import zlib from 'zlib';
|
||||
|
||||
// @ts-expect-error - mock server doesn't have type declarations
|
||||
import mockServer from '../mock-api/mockServer.js';
|
||||
|
||||
export default defineConfig(({ command, mode }) => {
|
||||
if (command === 'serve') {
|
||||
console.log('Preparing for standalone build with server, mode=' + mode);
|
||||
return {
|
||||
plugins: [preact(), viteTsconfigPaths(), mockServer()],
|
||||
server: {
|
||||
open: true,
|
||||
port: mode == 'production' ? 4173 : 3000,
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://localhost:3080',
|
||||
changeOrigin: true,
|
||||
secure: false
|
||||
},
|
||||
'/rest': 'http://localhost:3080',
|
||||
'/gh': 'http://localhost:3080' // mock for GitHub API
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (mode === 'hosted') {
|
||||
console.log('Preparing for hosted build');
|
||||
return {
|
||||
plugins: [preact(), viteTsconfigPaths()],
|
||||
build: {
|
||||
chunkSizeWarningLimit: 1024
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
console.log('Preparing for production, optimized build');
|
||||
|
||||
// Plugin to display bundle size information
|
||||
const bundleSizeReporter = (): Plugin => {
|
||||
return {
|
||||
plugins: [
|
||||
preact(),
|
||||
viteTsconfigPaths(),
|
||||
// {
|
||||
// ...viteImagemin({
|
||||
// verbose: false,
|
||||
// gifsicle: {
|
||||
// optimizationLevel: 7,
|
||||
// interlaced: false
|
||||
// },
|
||||
// optipng: {
|
||||
// optimizationLevel: 7
|
||||
// },
|
||||
// mozjpeg: {
|
||||
// quality: 20
|
||||
// },
|
||||
// pngquant: {
|
||||
// quality: [0.8, 0.9],
|
||||
// speed: 4
|
||||
// },
|
||||
// svgo: {
|
||||
// plugins: [
|
||||
// {
|
||||
// name: 'removeViewBox'
|
||||
// },
|
||||
// {
|
||||
// name: 'removeEmptyAttrs',
|
||||
// active: false
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// }),
|
||||
// enforce: 'pre'
|
||||
// },
|
||||
visualizer({
|
||||
template: 'treemap', // or sunburst
|
||||
open: false,
|
||||
gzipSize: true,
|
||||
brotliSize: true,
|
||||
filename: '../analyse.html' // will be saved in project's root
|
||||
})
|
||||
],
|
||||
name: 'bundle-size-reporter',
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
writeBundle(options: any, bundle: any) {
|
||||
console.log('\n📦 Bundle Size Report:');
|
||||
console.log('='.repeat(50));
|
||||
|
||||
build: {
|
||||
// target: 'es2022',
|
||||
chunkSizeWarningLimit: 1024,
|
||||
minify: 'terser',
|
||||
terserOptions: {
|
||||
compress: {
|
||||
passes: 4,
|
||||
arrows: true,
|
||||
drop_console: true,
|
||||
drop_debugger: true,
|
||||
sequences: true
|
||||
},
|
||||
mangle: {
|
||||
// toplevel: true
|
||||
// module: true
|
||||
// properties: {
|
||||
// regex: /^_/
|
||||
// }
|
||||
},
|
||||
ecma: 5,
|
||||
enclose: false,
|
||||
keep_classnames: false,
|
||||
keep_fnames: false,
|
||||
ie8: false,
|
||||
module: false,
|
||||
safari10: false,
|
||||
toplevel: false
|
||||
},
|
||||
let totalSize = 0;
|
||||
const files: Array<{ name: string; size: number; gzipSize?: number }> = [];
|
||||
|
||||
rollupOptions: {
|
||||
output: {
|
||||
manualChunks(id: string) {
|
||||
if (id.includes('node_modules')) {
|
||||
// creating a chunk to react routes deps. Reducing the vendor chunk size
|
||||
if (id.includes('react-router')) {
|
||||
return '@react-router';
|
||||
}
|
||||
return 'vendor';
|
||||
}
|
||||
for (const [fileName, chunk] of Object.entries(
|
||||
bundle as Record<string, unknown>
|
||||
)) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
if ((chunk as any).type === 'chunk' || (chunk as any).type === 'asset') {
|
||||
const filePath = path.join((options.dir as string) || 'dist', fileName);
|
||||
let size = 0;
|
||||
let gzipSize = 0;
|
||||
|
||||
try {
|
||||
const stats = fs.statSync(filePath);
|
||||
size = stats.size;
|
||||
totalSize += size;
|
||||
|
||||
// Calculate gzip size
|
||||
const fileContent = fs.readFileSync(filePath);
|
||||
gzipSize = zlib.gzipSync(fileContent).length;
|
||||
|
||||
files.push({
|
||||
name: fileName,
|
||||
size,
|
||||
gzipSize
|
||||
});
|
||||
} catch (error) {
|
||||
console.warn(`Could not read file ${fileName}:`, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort files by size (largest first)
|
||||
files.sort((a, b) => b.size - a.size);
|
||||
|
||||
// Display individual file sizes
|
||||
files.forEach((file) => {
|
||||
const sizeKB = (file.size / 1024).toFixed(2);
|
||||
const gzipKB = file.gzipSize ? (file.gzipSize / 1024).toFixed(2) : 'N/A';
|
||||
console.log(
|
||||
`📄 ${file.name.padEnd(30)} ${sizeKB.padStart(8)} KB (${gzipKB} KB gzipped)`
|
||||
);
|
||||
});
|
||||
|
||||
console.log('='.repeat(50));
|
||||
console.log(`📊 Total Bundle Size: ${(totalSize / 1024).toFixed(2)} KB`);
|
||||
|
||||
// Calculate and display gzip total
|
||||
const totalGzipSize = files.reduce(
|
||||
(sum, file) => sum + (file.gzipSize || 0),
|
||||
0
|
||||
);
|
||||
console.log(`🗜️ Total Gzipped Size: ${(totalGzipSize / 1024).toFixed(2)} KB`);
|
||||
|
||||
// Show compression ratio
|
||||
const compressionRatio = (
|
||||
((totalSize - totalGzipSize) / totalSize) *
|
||||
100
|
||||
).toFixed(1);
|
||||
console.log(`📈 Compression Ratio: ${compressionRatio}%`);
|
||||
|
||||
console.log('='.repeat(50));
|
||||
}
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
export default defineConfig(
|
||||
({ command, mode }: { command: string; mode: string }) => {
|
||||
if (command === 'serve') {
|
||||
console.log('Preparing for standalone build with server, mode=' + mode);
|
||||
return {
|
||||
plugins: [
|
||||
preact({
|
||||
// Keep dev tools enabled for development
|
||||
devToolsEnabled: true,
|
||||
prefreshEnabled: true
|
||||
}),
|
||||
viteTsconfigPaths(),
|
||||
bundleSizeReporter(), // Add bundle size reporting
|
||||
mockServer()
|
||||
],
|
||||
server: {
|
||||
open: true,
|
||||
port: mode == 'production' ? 4173 : 3000,
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://localhost:3080',
|
||||
changeOrigin: true,
|
||||
secure: false
|
||||
},
|
||||
'/rest': 'http://localhost:3080',
|
||||
'/gh': 'http://localhost:3080' // mock for GitHub API
|
||||
}
|
||||
},
|
||||
// Optimize development builds
|
||||
build: {
|
||||
target: 'es2020',
|
||||
minify: false, // Disable minification for faster dev builds
|
||||
sourcemap: true // Enable source maps for debugging
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (mode === 'hosted') {
|
||||
console.log('Preparing for hosted build');
|
||||
return {
|
||||
plugins: [
|
||||
preact({
|
||||
// Enable Preact optimizations for hosted build
|
||||
devToolsEnabled: false,
|
||||
prefreshEnabled: false
|
||||
}),
|
||||
viteTsconfigPaths(),
|
||||
bundleSizeReporter() // Add bundle size reporting
|
||||
],
|
||||
build: {
|
||||
target: 'es2020',
|
||||
chunkSizeWarningLimit: 512,
|
||||
minify: 'terser',
|
||||
cssMinify: true,
|
||||
assetsInlineLimit: 4096,
|
||||
terserOptions: {
|
||||
compress: {
|
||||
passes: 3,
|
||||
drop_console: true,
|
||||
drop_debugger: true,
|
||||
dead_code: true,
|
||||
unused: true
|
||||
},
|
||||
mangle: {
|
||||
toplevel: true
|
||||
},
|
||||
ecma: 2020
|
||||
},
|
||||
rollupOptions: {
|
||||
treeshake: {
|
||||
moduleSideEffects: false
|
||||
},
|
||||
output: {
|
||||
manualChunks(id: string) {
|
||||
if (id.includes('node_modules')) {
|
||||
if (id.includes('preact')) {
|
||||
return '@preact';
|
||||
}
|
||||
return 'vendor';
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
console.log('Preparing for production, optimized build');
|
||||
|
||||
return {
|
||||
plugins: [
|
||||
preact({
|
||||
// Enable Preact optimizations
|
||||
devToolsEnabled: false,
|
||||
prefreshEnabled: false
|
||||
}),
|
||||
viteTsconfigPaths(),
|
||||
// Enable image optimization for size reduction
|
||||
{
|
||||
...viteImagemin({
|
||||
verbose: false,
|
||||
gifsicle: {
|
||||
optimizationLevel: 7,
|
||||
interlaced: false
|
||||
},
|
||||
optipng: {
|
||||
optimizationLevel: 7
|
||||
},
|
||||
mozjpeg: {
|
||||
quality: 20
|
||||
},
|
||||
pngquant: {
|
||||
quality: [0.8, 0.9],
|
||||
speed: 4
|
||||
},
|
||||
svgo: {
|
||||
plugins: [
|
||||
{
|
||||
name: 'removeViewBox'
|
||||
},
|
||||
{
|
||||
name: 'removeEmptyAttrs',
|
||||
active: false
|
||||
}
|
||||
]
|
||||
}
|
||||
}),
|
||||
enforce: 'pre'
|
||||
},
|
||||
visualizer({
|
||||
template: 'treemap', // or sunburst
|
||||
open: false,
|
||||
gzipSize: true,
|
||||
brotliSize: true,
|
||||
filename: '../analyse.html' // will be saved in project's root
|
||||
}),
|
||||
bundleSizeReporter() // Add bundle size reporting
|
||||
],
|
||||
|
||||
build: {
|
||||
// Target modern browsers for smaller bundles
|
||||
target: 'es2020',
|
||||
chunkSizeWarningLimit: 512,
|
||||
minify: 'terser',
|
||||
// Enable CSS minification
|
||||
cssMinify: true,
|
||||
// Optimize asset handling
|
||||
assetsInlineLimit: 4096, // Inline small assets
|
||||
terserOptions: {
|
||||
compress: {
|
||||
passes: 6,
|
||||
arrows: true,
|
||||
drop_console: true,
|
||||
drop_debugger: true,
|
||||
sequences: true
|
||||
// Additional aggressive compression options
|
||||
// dead_code: true,
|
||||
// hoist_funs: true,
|
||||
// hoist_vars: true,
|
||||
// if_return: true,
|
||||
// join_vars: true,
|
||||
// loops: true,
|
||||
// pure_getters: true,
|
||||
// reduce_vars: true,
|
||||
// side_effects: false,
|
||||
// switches: true,
|
||||
// unsafe: true,
|
||||
// unsafe_arrows: true,
|
||||
// unsafe_comps: true,
|
||||
// unsafe_Function: true,
|
||||
// unsafe_math: true,
|
||||
// unsafe_proto: true,
|
||||
// unsafe_regexp: true,
|
||||
// unsafe_undefined: true,
|
||||
// unused: true
|
||||
},
|
||||
mangle: {
|
||||
toplevel: true, // Enable top-level mangling
|
||||
module: true // Enable module mangling
|
||||
// properties: {
|
||||
// regex: /^_/ // Mangle properties starting with _
|
||||
// }
|
||||
},
|
||||
ecma: 2020, // Updated to modern ECMAScript
|
||||
enclose: false,
|
||||
keep_classnames: false,
|
||||
keep_fnames: false,
|
||||
ie8: false,
|
||||
module: false,
|
||||
safari10: false,
|
||||
toplevel: true // Enable top-level optimization
|
||||
},
|
||||
|
||||
rollupOptions: {
|
||||
// Enable tree shaking
|
||||
treeshake: {
|
||||
moduleSideEffects: false,
|
||||
propertyReadSideEffects: false,
|
||||
tryCatchDeoptimization: false
|
||||
},
|
||||
output: {
|
||||
// Optimize chunk naming for better caching
|
||||
chunkFileNames: 'assets/[name]-[hash].js',
|
||||
entryFileNames: 'assets/[name]-[hash].js',
|
||||
assetFileNames: 'assets/[name]-[hash].[ext]',
|
||||
manualChunks(id: string) {
|
||||
if (id.includes('node_modules')) {
|
||||
// More granular chunk splitting for better caching
|
||||
if (id.includes('react-router')) {
|
||||
return '@react-router';
|
||||
}
|
||||
if (id.includes('preact')) {
|
||||
return '@preact';
|
||||
}
|
||||
if (id.includes('uuid')) {
|
||||
return '@uuid';
|
||||
}
|
||||
if (id.includes('axios') || id.includes('fetch')) {
|
||||
return '@http';
|
||||
}
|
||||
if (id.includes('lodash') || id.includes('ramda')) {
|
||||
return '@utils';
|
||||
}
|
||||
return 'vendor';
|
||||
}
|
||||
// Split large application modules
|
||||
if (id.includes('components/')) {
|
||||
return 'components';
|
||||
}
|
||||
if (id.includes('pages/') || id.includes('routes/')) {
|
||||
return 'pages';
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
// Enable source maps for debugging (optional)
|
||||
sourcemap: false // Disable for production to save space
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1,33 +1,24 @@
|
||||
// used to simulate
|
||||
// - file uploads
|
||||
// - EventSource (SSE) for log messages
|
||||
// Mock server for development
|
||||
// Simulates file uploads and EventSource (SSE) for log messages
|
||||
import formidable from 'formidable';
|
||||
|
||||
function pad(number) {
|
||||
let r = String(number);
|
||||
if (r.length === 1) {
|
||||
r = '0' + r;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
// Optimized padding function
|
||||
const pad = (number) => String(number).padStart(2, '0');
|
||||
|
||||
// e.g. 2024-03-29 07:02:37.856
|
||||
Date.prototype.toISOString = function () {
|
||||
return (
|
||||
this.getUTCFullYear() +
|
||||
'-' +
|
||||
pad(this.getUTCMonth() + 1) +
|
||||
'-' +
|
||||
pad(this.getUTCDate()) +
|
||||
' ' +
|
||||
pad(this.getUTCHours()) +
|
||||
':' +
|
||||
pad(this.getUTCMinutes()) +
|
||||
':' +
|
||||
pad(this.getUTCSeconds()) +
|
||||
'.' +
|
||||
String((this.getUTCMilliseconds() / 1000).toFixed(3)).slice(2, 5)
|
||||
// Cached date formatter to avoid prototype pollution
|
||||
const formatDate = (date) => {
|
||||
const year = date.getUTCFullYear();
|
||||
const month = pad(date.getUTCMonth() + 1);
|
||||
const day = pad(date.getUTCDate());
|
||||
const hours = pad(date.getUTCHours());
|
||||
const minutes = pad(date.getUTCMinutes());
|
||||
const seconds = pad(date.getUTCSeconds());
|
||||
const milliseconds = String((date.getUTCMilliseconds() / 1000).toFixed(3)).slice(
|
||||
2,
|
||||
5
|
||||
);
|
||||
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${milliseconds}`;
|
||||
};
|
||||
|
||||
export default () => {
|
||||
@@ -35,97 +26,129 @@ export default () => {
|
||||
name: 'vite:mockserver',
|
||||
configureServer: async (server) => {
|
||||
server.middlewares.use(async (req, res, next) => {
|
||||
// catch any file uploads
|
||||
// Handle file uploads
|
||||
if (req.url.startsWith('/rest/uploadFile')) {
|
||||
// show progress
|
||||
const fileSize = parseInt(req.headers['content-length'] || '0', 10);
|
||||
let progress = 0;
|
||||
const file_size = req.headers['content-length'];
|
||||
console.log('File size: ' + file_size);
|
||||
req.on('data', async (chunk) => {
|
||||
|
||||
// Track upload progress
|
||||
req.on('data', (chunk) => {
|
||||
progress += chunk.length;
|
||||
const percentage = (progress / file_size) * 100;
|
||||
console.log(`Progress: ${Math.round(percentage)}%`);
|
||||
// await new Promise((resolve) => setTimeout(() => resolve(), 3000)); // slow it down
|
||||
if (fileSize > 0) {
|
||||
const percentage = Math.round((progress / fileSize) * 100);
|
||||
console.log(`Upload progress: ${percentage}%`);
|
||||
}
|
||||
});
|
||||
|
||||
const form = formidable({});
|
||||
let fields;
|
||||
let files;
|
||||
try {
|
||||
[fields, files] = await form.parse(req);
|
||||
} catch (err) {
|
||||
console.error('Not json form content');
|
||||
res.writeHead(err.httpCode || 400, {
|
||||
'Content-Type': 'text/plain'
|
||||
const form = formidable({
|
||||
maxFileSize: 50 * 1024 * 1024, // 50MB limit
|
||||
keepExtensions: true
|
||||
});
|
||||
res.end(String(err));
|
||||
return;
|
||||
}
|
||||
|
||||
// only process when we have a file
|
||||
if (Object.keys(files).length > 0) {
|
||||
const uploaded_file = files.file[0];
|
||||
const file_name = uploaded_file.originalFilename;
|
||||
const file_extension = file_name.substring(
|
||||
file_name.lastIndexOf('.') + 1
|
||||
const [fields, files] = await form.parse(req);
|
||||
|
||||
if (Object.keys(files).length === 0) {
|
||||
res.statusCode = 400;
|
||||
res.end('No file uploaded');
|
||||
return;
|
||||
}
|
||||
|
||||
const uploadedFile = files.file[0];
|
||||
const fileName = uploadedFile.originalFilename;
|
||||
const fileExtension = fileName
|
||||
.substring(fileName.lastIndexOf('.') + 1)
|
||||
.toLowerCase();
|
||||
|
||||
console.log(
|
||||
`File uploaded: ${fileName} (${fileExtension}, ${fileSize} bytes)`
|
||||
);
|
||||
|
||||
console.log('Filename: ' + file_name);
|
||||
console.log('Extension: ' + file_extension);
|
||||
console.log('File size: ' + file_size);
|
||||
// Validate file extension
|
||||
const validExtensions = new Set(['bin', 'json', 'md5']);
|
||||
if (!validExtensions.has(fileExtension)) {
|
||||
res.statusCode = 406;
|
||||
res.end('Invalid file extension');
|
||||
return;
|
||||
}
|
||||
|
||||
if (file_extension === 'bin' || file_extension === 'json') {
|
||||
console.log('File uploaded successfully!');
|
||||
} else if (file_extension === 'md5') {
|
||||
console.log('MD5 hash generated successfully!');
|
||||
// Handle different file types
|
||||
if (fileExtension === 'md5') {
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.end(
|
||||
JSON.stringify({
|
||||
md5: 'ef4304fc4d9025a58dcf25d71c882d2c'
|
||||
})
|
||||
);
|
||||
} else {
|
||||
res.statusCode = 406;
|
||||
console.log('Invalid file extension!');
|
||||
console.log('File uploaded successfully!');
|
||||
res.end();
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Upload error:', err.message);
|
||||
res.statusCode = err.httpCode || 400;
|
||||
res.setHeader('Content-Type', 'text/plain');
|
||||
res.end(err.message);
|
||||
}
|
||||
|
||||
res.end();
|
||||
}
|
||||
|
||||
// SSE Eventsource
|
||||
// Handle Server-Sent Events (SSE) for log streaming
|
||||
else if (req.url.startsWith('/es/log')) {
|
||||
// Set SSE headers
|
||||
res.writeHead(200, {
|
||||
Connection: 'keep-alive',
|
||||
'Cache-Control': 'no-cache',
|
||||
'Content-Type': 'text/event-stream'
|
||||
'Content-Type': 'text/event-stream',
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Access-Control-Allow-Headers': 'Cache-Control'
|
||||
});
|
||||
|
||||
let count = 0;
|
||||
const interval = setInterval(() => {
|
||||
let message = 'message #' + count;
|
||||
if (count % 6 === 1) {
|
||||
let messageCount = 0;
|
||||
const logLevels = [3, 4, 5, 6, 7, 8]; // Different log levels
|
||||
const logNames = ['system', 'ems', 'wifi', 'mqtt', 'ntp', 'api'];
|
||||
|
||||
const sendLogMessage = () => {
|
||||
const level = logLevels[messageCount % logLevels.length];
|
||||
const name = logNames[messageCount % logNames.length];
|
||||
let message = `Log message #${messageCount}`;
|
||||
|
||||
// Add long message every 6th message
|
||||
if (messageCount % 6 === 1) {
|
||||
message +=
|
||||
' that is a long message that will be wrapped, to test if it gets truncated';
|
||||
' - This is a longer message to test text wrapping and truncation behavior in the UI';
|
||||
}
|
||||
const data = {
|
||||
t: new Date().toISOString(),
|
||||
l: 3 + (count % 6),
|
||||
i: count,
|
||||
n: 'system',
|
||||
|
||||
const logData = {
|
||||
t: formatDate(new Date()),
|
||||
l: level,
|
||||
i: messageCount,
|
||||
n: name,
|
||||
m: message
|
||||
};
|
||||
count++;
|
||||
res.write(`data: ${JSON.stringify(data)}\n\n`);
|
||||
}, 1000);
|
||||
|
||||
// if client closes connection
|
||||
res.on('close', () => {
|
||||
console.log('Closing ES connection');
|
||||
res.write(`data: ${JSON.stringify(logData)}\n\n`);
|
||||
messageCount++;
|
||||
};
|
||||
|
||||
// Send initial message
|
||||
sendLogMessage();
|
||||
|
||||
// Set up interval for periodic messages
|
||||
const interval = setInterval(sendLogMessage, 1000);
|
||||
|
||||
// Clean up on connection close
|
||||
const cleanup = () => {
|
||||
console.log('SSE connection closed');
|
||||
clearInterval(interval);
|
||||
res.end();
|
||||
});
|
||||
if (!res.destroyed) {
|
||||
res.end();
|
||||
}
|
||||
};
|
||||
|
||||
res.on('close', cleanup);
|
||||
res.on('error', cleanup);
|
||||
} else {
|
||||
next(); // move on to the next middleware function in chain
|
||||
next(); // Continue to next middleware
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mock-api",
|
||||
"version": "3.7.2",
|
||||
"version": "3.7.3",
|
||||
"description": "mock api for EMS-ESP",
|
||||
"author": "proddy, emsesp.org",
|
||||
"license": "MIT",
|
||||
@@ -15,5 +15,5 @@
|
||||
"itty-router": "^5.0.22",
|
||||
"prettier": "^3.6.2"
|
||||
},
|
||||
"packageManager": "pnpm@10.18.1+sha512.77a884a165cbba2d8d1c19e3b4880eee6d2fcabd0d879121e282196b80042351d5eb3ca0935fa599da1dc51265cc68816ad2bddd2a2de5ea9fdf92adbec7cd34"
|
||||
"packageManager": "pnpm@10.19.0+sha512.c9fc7236e92adf5c8af42fd5bf1612df99c2ceb62f27047032f4720b33f8eacdde311865e91c411f2774f618d82f320808ecb51718bfa82c060c4ba7c76a32b8"
|
||||
}
|
||||
|
||||
@@ -116,17 +116,15 @@ let system_status = {
|
||||
let DEV_VERSION_IS_UPGRADEABLE: boolean;
|
||||
let STABLE_VERSION_IS_UPGRADEABLE: boolean;
|
||||
let THIS_VERSION: string;
|
||||
let version_test: number;
|
||||
|
||||
let LATEST_STABLE_VERSION = '3.7.2';
|
||||
let LATEST_DEV_VERSION = '3.7.3-dev.6';
|
||||
|
||||
// scenarios for testing versioning
|
||||
version_test = 0; // on latest stable, or switch to dev
|
||||
// version_test = 1; // on latest dev, or switch back to stable
|
||||
// version_test = 2; // upgrade an older stable to latest stable or switch to latest dev
|
||||
// version_test = 3; // upgrade dev to latest, or switch to stable
|
||||
// version_test = 4; // downgrade to an older dev, or switch back to stable
|
||||
let version_test = 0; // on latest stable, or switch to dev
|
||||
// let version_test = 1; // on latest dev, or switch back to stable
|
||||
// let version_test = 2; // upgrade an older stable to latest stable or switch to latest dev
|
||||
// let version_test = 3; // upgrade dev to latest, or switch to stable
|
||||
// let version_test = 4; // downgrade to an older dev, or switch back to stable
|
||||
|
||||
switch (version_test as number) {
|
||||
case 0:
|
||||
@@ -4380,78 +4378,124 @@ router
|
||||
|
||||
function deviceData(id: number) {
|
||||
if (id == 1) {
|
||||
return new Response(encoder.encode(emsesp_devicedata_1), { headers });
|
||||
return new Response(encoder.encode(emsesp_devicedata_1) as BodyInit, {
|
||||
headers
|
||||
});
|
||||
}
|
||||
if (id == 2) {
|
||||
return new Response(encoder.encode(emsesp_devicedata_2), { headers });
|
||||
return new Response(encoder.encode(emsesp_devicedata_2) as BodyInit, {
|
||||
headers
|
||||
});
|
||||
}
|
||||
if (id == 3) {
|
||||
return new Response(encoder.encode(emsesp_devicedata_3), { headers });
|
||||
return new Response(encoder.encode(emsesp_devicedata_3) as BodyInit, {
|
||||
headers
|
||||
});
|
||||
}
|
||||
if (id == 4) {
|
||||
return new Response(encoder.encode(emsesp_devicedata_4), { headers });
|
||||
return new Response(encoder.encode(emsesp_devicedata_4) as BodyInit, {
|
||||
headers
|
||||
});
|
||||
}
|
||||
if (id == 5) {
|
||||
return new Response(encoder.encode(emsesp_devicedata_5), { headers });
|
||||
return new Response(encoder.encode(emsesp_devicedata_5) as BodyInit, {
|
||||
headers
|
||||
});
|
||||
}
|
||||
if (id == 6) {
|
||||
return new Response(encoder.encode(emsesp_devicedata_6), { headers });
|
||||
return new Response(encoder.encode(emsesp_devicedata_6) as BodyInit, {
|
||||
headers
|
||||
});
|
||||
}
|
||||
if (id == 7) {
|
||||
return new Response(encoder.encode(emsesp_devicedata_7), { headers });
|
||||
return new Response(encoder.encode(emsesp_devicedata_7) as BodyInit, {
|
||||
headers
|
||||
});
|
||||
}
|
||||
if (id == 8) {
|
||||
// test changing the selected flow temp on a Bosch Compress 7000i AW Heat Pump (Boiler/HP)
|
||||
emsesp_devicedata_8.nodes[4].v = Math.floor(Math.random() * 100);
|
||||
return new Response(encoder.encode(emsesp_devicedata_8), { headers });
|
||||
return new Response(encoder.encode(emsesp_devicedata_8) as BodyInit, {
|
||||
headers
|
||||
});
|
||||
}
|
||||
if (id == 9) {
|
||||
return new Response(encoder.encode(emsesp_devicedata_9), { headers });
|
||||
return new Response(encoder.encode(emsesp_devicedata_9) as BodyInit, {
|
||||
headers
|
||||
});
|
||||
}
|
||||
if (id == 10) {
|
||||
return new Response(encoder.encode(emsesp_devicedata_10), { headers });
|
||||
return new Response(encoder.encode(emsesp_devicedata_10) as BodyInit, {
|
||||
headers
|
||||
});
|
||||
}
|
||||
if (id == 11) {
|
||||
return new Response(encoder.encode(emsesp_devicedata_11), { headers });
|
||||
return new Response(encoder.encode(emsesp_devicedata_11) as BodyInit, {
|
||||
headers
|
||||
});
|
||||
}
|
||||
if (id == 99) {
|
||||
return new Response(encoder.encode(emsesp_devicedata_99), { headers });
|
||||
return new Response(encoder.encode(emsesp_devicedata_99) as BodyInit, {
|
||||
headers
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function deviceEntities(id: number) {
|
||||
if (id == 1) {
|
||||
return new Response(encoder.encode(emsesp_deviceentities_1), { headers });
|
||||
return new Response(encoder.encode(emsesp_deviceentities_1) as BodyInit, {
|
||||
headers
|
||||
});
|
||||
}
|
||||
if (id == 2) {
|
||||
return new Response(encoder.encode(emsesp_deviceentities_2), { headers });
|
||||
return new Response(encoder.encode(emsesp_deviceentities_2) as BodyInit, {
|
||||
headers
|
||||
});
|
||||
}
|
||||
if (id == 3) {
|
||||
return new Response(encoder.encode(emsesp_deviceentities_3), { headers });
|
||||
return new Response(encoder.encode(emsesp_deviceentities_3) as BodyInit, {
|
||||
headers
|
||||
});
|
||||
}
|
||||
if (id == 4) {
|
||||
return new Response(encoder.encode(emsesp_deviceentities_4), { headers });
|
||||
return new Response(encoder.encode(emsesp_deviceentities_4) as BodyInit, {
|
||||
headers
|
||||
});
|
||||
}
|
||||
if (id == 5) {
|
||||
return new Response(encoder.encode(emsesp_deviceentities_5), { headers });
|
||||
return new Response(encoder.encode(emsesp_deviceentities_5) as BodyInit, {
|
||||
headers
|
||||
});
|
||||
}
|
||||
if (id == 6) {
|
||||
return new Response(encoder.encode(emsesp_deviceentities_6), { headers });
|
||||
return new Response(encoder.encode(emsesp_deviceentities_6) as BodyInit, {
|
||||
headers
|
||||
});
|
||||
}
|
||||
if (id == 7) {
|
||||
return new Response(encoder.encode(emsesp_deviceentities_7), { headers });
|
||||
return new Response(encoder.encode(emsesp_deviceentities_7) as BodyInit, {
|
||||
headers
|
||||
});
|
||||
}
|
||||
if (id == 8) {
|
||||
return new Response(encoder.encode(emsesp_deviceentities_8), { headers });
|
||||
return new Response(encoder.encode(emsesp_deviceentities_8) as BodyInit, {
|
||||
headers
|
||||
});
|
||||
}
|
||||
if (id == 9) {
|
||||
return new Response(encoder.encode(emsesp_deviceentities_9), { headers });
|
||||
return new Response(encoder.encode(emsesp_deviceentities_9) as BodyInit, {
|
||||
headers
|
||||
});
|
||||
}
|
||||
if (id == 10) {
|
||||
return new Response(encoder.encode(emsesp_deviceentities_10), { headers });
|
||||
return new Response(encoder.encode(emsesp_deviceentities_10) as BodyInit, {
|
||||
headers
|
||||
});
|
||||
}
|
||||
// not found, return empty
|
||||
return new Response(encoder.encode(emsesp_deviceentities_none), { headers });
|
||||
return new Response(encoder.encode(emsesp_deviceentities_none) as BodyInit, {
|
||||
headers
|
||||
});
|
||||
}
|
||||
|
||||
// prepare dashboard data
|
||||
@@ -4558,65 +4602,63 @@ router
|
||||
}
|
||||
|
||||
// add temperature sensor data. no command c
|
||||
let sensor_data: any[] = [];
|
||||
sensor_data = emsesp_sensordata.ts.map((item, index) => ({
|
||||
id: DeviceTypeUniqueID.TEMPERATURESENSOR_UID * 100 + index,
|
||||
dv: {
|
||||
id: '00' + item.n,
|
||||
v: item.t, // value is called t in ts (temperature)
|
||||
u: item.u
|
||||
}
|
||||
}));
|
||||
dashboard_object = {
|
||||
id: DeviceTypeUniqueID.TEMPERATURESENSOR_UID,
|
||||
t: DeviceType.TEMPERATURESENSOR,
|
||||
nodes: sensor_data
|
||||
};
|
||||
// only add to dashboard if we have values
|
||||
if ((dashboard_object.nodes ?? []).length > 0) {
|
||||
if (emsesp_sensordata.ts.length > 0) {
|
||||
const sensor_data = emsesp_sensordata.ts.map((item, index) => ({
|
||||
id: DeviceTypeUniqueID.TEMPERATURESENSOR_UID * 100 + index,
|
||||
dv: {
|
||||
id: '00' + item.n,
|
||||
v: item.t, // value is called t in ts (temperature)
|
||||
u: item.u
|
||||
}
|
||||
}));
|
||||
dashboard_object = {
|
||||
id: DeviceTypeUniqueID.TEMPERATURESENSOR_UID,
|
||||
t: DeviceType.TEMPERATURESENSOR,
|
||||
nodes: sensor_data
|
||||
};
|
||||
dashboard_nodes.push(dashboard_object);
|
||||
}
|
||||
|
||||
// add analog sensor data. no command c
|
||||
// remove disabled sensors first (t = 0)
|
||||
sensor_data = emsesp_sensordata.as.filter((item) => item.t !== 0);
|
||||
sensor_data = sensor_data.map((item, index) => ({
|
||||
id: DeviceTypeUniqueID.ANALOGSENSOR_UID * 100 + index,
|
||||
dv: {
|
||||
id: '00' + item.n,
|
||||
v: item.v,
|
||||
u: item.u
|
||||
}
|
||||
}));
|
||||
dashboard_object = {
|
||||
id: DeviceTypeUniqueID.ANALOGSENSOR_UID,
|
||||
t: DeviceType.ANALOGSENSOR,
|
||||
nodes: sensor_data
|
||||
};
|
||||
// only add to dashboard if we have values
|
||||
if ((dashboard_object.nodes ?? []).length > 0) {
|
||||
// remove disabled sensors first (t = 0) and create data in one pass
|
||||
const enabledAnalogSensors = emsesp_sensordata.as.filter(
|
||||
(item) => item.t !== 0
|
||||
);
|
||||
if (enabledAnalogSensors.length > 0) {
|
||||
const sensor_data = enabledAnalogSensors.map((item, index) => ({
|
||||
id: DeviceTypeUniqueID.ANALOGSENSOR_UID * 100 + index,
|
||||
dv: {
|
||||
id: '00' + item.n,
|
||||
v: item.v,
|
||||
u: item.u
|
||||
}
|
||||
}));
|
||||
dashboard_object = {
|
||||
id: DeviceTypeUniqueID.ANALOGSENSOR_UID,
|
||||
t: DeviceType.ANALOGSENSOR,
|
||||
nodes: sensor_data
|
||||
};
|
||||
dashboard_nodes.push(dashboard_object);
|
||||
}
|
||||
|
||||
// add the scheduler data
|
||||
// filter emsesp_schedule with only if it has a name
|
||||
let scheduler_data = emsesp_schedule.schedule.filter((item) => item.name);
|
||||
let scheduler_data2 = scheduler_data.map((item, index) => ({
|
||||
id: DeviceTypeUniqueID.SCHEDULER_UID * 100 + index,
|
||||
dv: {
|
||||
id: '00' + item.name,
|
||||
v: item.active ? 'on' : 'off',
|
||||
c: item.name,
|
||||
l: ['off', 'on']
|
||||
}
|
||||
}));
|
||||
dashboard_object = {
|
||||
id: DeviceTypeUniqueID.SCHEDULER_UID,
|
||||
t: DeviceType.SCHEDULER,
|
||||
nodes: scheduler_data2
|
||||
};
|
||||
// only add to dashboard if we have values
|
||||
if ((dashboard_object.nodes ?? []).length > 0) {
|
||||
// filter emsesp_schedule with only if it has a name and create data in one pass
|
||||
const namedSchedules = emsesp_schedule.schedule.filter((item) => item.name);
|
||||
if (namedSchedules.length > 0) {
|
||||
const scheduler_data = namedSchedules.map((item, index) => ({
|
||||
id: DeviceTypeUniqueID.SCHEDULER_UID * 100 + index,
|
||||
dv: {
|
||||
id: '00' + item.name,
|
||||
v: item.active ? 'on' : 'off',
|
||||
c: item.name,
|
||||
l: ['off', 'on']
|
||||
}
|
||||
}));
|
||||
dashboard_object = {
|
||||
id: DeviceTypeUniqueID.SCHEDULER_UID,
|
||||
t: DeviceType.SCHEDULER,
|
||||
nodes: scheduler_data
|
||||
};
|
||||
dashboard_nodes.push(dashboard_object);
|
||||
}
|
||||
} else {
|
||||
@@ -4660,8 +4702,12 @@ router
|
||||
};
|
||||
// console.log('dashboardData: ', dashboardData);
|
||||
|
||||
// Clear references to help with garbage collection
|
||||
dashboard_nodes = [];
|
||||
dashboard_object = {};
|
||||
|
||||
// return dashboard_data; // if not using msgpack
|
||||
return new Response(encoder.encode(dashboardData), { headers }); // msgpack it
|
||||
return new Response(encoder.encode(dashboardData) as BodyInit, { headers }); // msgpack it
|
||||
})
|
||||
|
||||
// Customizations
|
||||
@@ -4852,10 +4898,12 @@ router
|
||||
} else {
|
||||
if (as.deleted) {
|
||||
emsesp_sensordata.as[objIndex].d = true;
|
||||
var filtered = emsesp_sensordata.as.filter(function (value, index, arr) {
|
||||
return !value.d;
|
||||
});
|
||||
emsesp_sensordata.as = filtered;
|
||||
// Remove deleted items in-place to avoid creating new arrays
|
||||
for (let i = emsesp_sensordata.as.length - 1; i >= 0; i--) {
|
||||
if (emsesp_sensordata.as[i].d) {
|
||||
emsesp_sensordata.as.splice(i, 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
emsesp_sensordata.as[objIndex].n = as.name;
|
||||
emsesp_sensordata.as[objIndex].f = as.factor;
|
||||
|
||||
@@ -197,7 +197,7 @@ extra_scripts =
|
||||
build_flags =
|
||||
-DARDUINOJSON_ENABLE_ARDUINO_STRING=1
|
||||
-DEMSESP_STANDALONE -DEMSESP_TEST
|
||||
-DEMSESP_DEFAULT_LOCALE=\"en\" -DEMSESP_DEFAULT_TX_MODE=8 -DEMSESP_DEFAULT_VERSION=\"3.7.2-dev.0\" -DEMSESP_DEFAULT_BOARD_PROFILE=\"S32\"
|
||||
-DEMSESP_DEFAULT_LOCALE=\"en\" -DEMSESP_DEFAULT_TX_MODE=8 -DEMSESP_DEFAULT_VERSION=\"3.7.3-dev.0\" -DEMSESP_DEFAULT_BOARD_PROFILE=\"S32\"
|
||||
-std=gnu++17 -Og -ggdb
|
||||
build_unflags = -std=gnu++11 -std=gnu++14
|
||||
build_type = debug
|
||||
|
||||
@@ -1426,3 +1426,11 @@ Roomparams
|
||||
Roomdata
|
||||
Roomschedule
|
||||
dewtemp
|
||||
chefhat
|
||||
sofasingle
|
||||
bowlmix
|
||||
bedsingle
|
||||
beddouble
|
||||
teddybear
|
||||
washingmachine
|
||||
switchprogram
|
||||
@@ -211,7 +211,7 @@ for entity in entities:
|
||||
|
||||
if int(entity["modbus count"]) <= 0:
|
||||
raise Exception('Entity "' + entity_dev_name + ' (' + entity_shortname + ')' +
|
||||
'" does not have a size - string sizes need to be added manually to update_modbus_registers.py/string_sizes')
|
||||
'" does not have a size - string sizes need to be added manually to update_modbus_registers.py/string_sizes[]')
|
||||
|
||||
# if entity["modbus count"] == "0":
|
||||
# print("ignoring " + entity_dev_name + " - it has a register length of zero")
|
||||
|
||||
@@ -203,7 +203,7 @@
|
||||
{163, DeviceType::WATER, "SM100, MS100", DeviceFlags::EMS_DEVICE_FLAG_SM100},
|
||||
{164, DeviceType::WATER, "SM200, MS200", DeviceFlags::EMS_DEVICE_FLAG_SM100},
|
||||
{248, DeviceType::MIXER, "HM210", DeviceFlags::EMS_DEVICE_FLAG_MMPLUS},
|
||||
{17, DeviceType::CONNECT, "MX400", DeviceFlags::EMS_DEVICE_FLAG_NONE} // 0x50 Wirelss Base
|
||||
{17, DeviceType::CONNECT, "MX400", DeviceFlags::EMS_DEVICE_FLAG_NONE} // 0x50 Wireless Base
|
||||
// {157, DeviceType::THERMOSTAT, "RC120", DeviceFlags::EMS_DEVICE_FLAG_CR120}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -29,22 +29,22 @@ static_assert(uuid::console::thread_safe, "uuid-console must be thread-safe");
|
||||
namespace emsesp {
|
||||
|
||||
// Static member definitions
|
||||
std::deque<std::unique_ptr<EMSdevice>> EMSESP::emsdevices{};
|
||||
std::vector<EMSESP::Device_record> EMSESP::device_library_;
|
||||
uuid::log::Logger EMSESP::logger_{F_(emsesp), uuid::log::Facility::KERN};
|
||||
uint16_t EMSESP::watch_id_ = WATCH_ID_NONE;
|
||||
uint8_t EMSESP::watch_ = 0;
|
||||
uint16_t EMSESP::read_id_ = WATCH_ID_NONE;
|
||||
bool EMSESP::read_next_ = false;
|
||||
uint16_t EMSESP::publish_id_ = 0;
|
||||
uint16_t EMSESP::response_id_ = 0;
|
||||
bool EMSESP::tap_water_active_ = false;
|
||||
uint8_t EMSESP::publish_all_idx_ = 0;
|
||||
uint8_t EMSESP::unique_id_count_ = 0;
|
||||
bool EMSESP::trace_raw_ = false;
|
||||
uint16_t EMSESP::wait_validate_ = 0;
|
||||
bool EMSESP::wait_km_ = false;
|
||||
uint32_t EMSESP::last_fetch_ = 0;
|
||||
std::vector<std::unique_ptr<EMSdevice>> EMSESP::emsdevices{};
|
||||
std::vector<EMSESP::Device_record> EMSESP::device_library_;
|
||||
uuid::log::Logger EMSESP::logger_{F_(emsesp), uuid::log::Facility::KERN};
|
||||
uint16_t EMSESP::watch_id_ = WATCH_ID_NONE;
|
||||
uint8_t EMSESP::watch_ = 0;
|
||||
uint16_t EMSESP::read_id_ = WATCH_ID_NONE;
|
||||
bool EMSESP::read_next_ = false;
|
||||
uint16_t EMSESP::publish_id_ = 0;
|
||||
uint16_t EMSESP::response_id_ = 0;
|
||||
bool EMSESP::tap_water_active_ = false;
|
||||
uint8_t EMSESP::publish_all_idx_ = 0;
|
||||
uint8_t EMSESP::unique_id_count_ = 0;
|
||||
bool EMSESP::trace_raw_ = false;
|
||||
uint16_t EMSESP::wait_validate_ = 0;
|
||||
bool EMSESP::wait_km_ = false;
|
||||
uint32_t EMSESP::last_fetch_ = 0;
|
||||
|
||||
AsyncWebServer webServer(80);
|
||||
|
||||
|
||||
@@ -222,7 +222,7 @@ class EMSESP {
|
||||
static void scan_devices();
|
||||
static void clear_all_devices();
|
||||
|
||||
static std::deque<std::unique_ptr<EMSdevice>> emsdevices;
|
||||
static std::vector<std::unique_ptr<EMSdevice>> emsdevices;
|
||||
|
||||
// services
|
||||
static Mqtt mqtt_;
|
||||
|
||||
@@ -787,8 +787,8 @@ std::string Helpers::toUpper(std::string const & s) {
|
||||
}
|
||||
|
||||
// capitalizes one UTF-8 character in char array
|
||||
// works with Latin1 (1 byte), Polish amd some other (2 bytes) characters
|
||||
// TODO add special characters that occur in other supported languages
|
||||
// works with Latin1 (1 byte), Polish and other (2 bytes) characters
|
||||
// supports special characters for all 11 supported languages: EN, DE, NL, SV, PL, NO, FR, TR, IT, SK, CZ
|
||||
#if defined(EMSESP_STANDALONE)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wtype-limits"
|
||||
@@ -803,23 +803,77 @@ void Helpers::CharToUpperUTF8(char * c) {
|
||||
if ((p_v >= (char)0xA0) && (p_v <= (char)0xBE)) {
|
||||
*p -= 0x20;
|
||||
}
|
||||
// Additional special characters for supported languages
|
||||
switch (p_v) {
|
||||
case (char)0xA0: // à -> À
|
||||
case (char)0xA1: // á -> Á
|
||||
case (char)0xA2: // â -> Â
|
||||
case (char)0xA3: // ã -> Ã
|
||||
case (char)0xA4: // ä -> Ä (German, Swedish)
|
||||
case (char)0xA5: // å -> Å (Swedish, Norwegian)
|
||||
case (char)0xA6: // æ -> Æ (Norwegian)
|
||||
case (char)0xA7: // ç -> Ç (French, Turkish)
|
||||
case (char)0xA8: // è -> È (French, Italian)
|
||||
case (char)0xA9: // é -> É (French, Italian)
|
||||
case (char)0xAA: // ê -> Ê (French)
|
||||
case (char)0xAB: // ë -> Ë (French)
|
||||
case (char)0xAC: // ì -> Ì (Italian)
|
||||
case (char)0xAD: // í -> Í (Slovak, Czech)
|
||||
case (char)0xAE: // î -> Î (French)
|
||||
case (char)0xAF: // ï -> Ï (French)
|
||||
case (char)0xB0: // ð -> Ð (Icelandic)
|
||||
case (char)0xB1: // ñ -> Ñ (Spanish)
|
||||
case (char)0xB2: // ò -> Ò (Italian)
|
||||
case (char)0xB3: // ó -> Ó (Slovak, Czech)
|
||||
case (char)0xB4: // ô -> Ô (French, Slovak)
|
||||
case (char)0xB5: // õ -> Õ (Portuguese)
|
||||
case (char)0xB6: // ö -> Ö (German, Swedish, Turkish)
|
||||
case (char)0xB8: // ø -> Ø (Norwegian)
|
||||
case (char)0xB9: // ù -> Ù (French, Italian)
|
||||
case (char)0xBA: // ú -> Ú (Slovak, Czech)
|
||||
case (char)0xBB: // û -> Û (French)
|
||||
case (char)0xBC: // ü -> Ü (German, French, Turkish)
|
||||
case (char)0xBD: // ý -> Ý (Slovak, Czech)
|
||||
case (char)0xBE: // þ -> Þ (Icelandic)
|
||||
case (char)0xBF: // ÿ -> Ÿ (French)
|
||||
*p -= 0x20;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case (char)0xC4:
|
||||
switch (p_v) {
|
||||
case (char)0x85: //ą (0xC4,0x85) -> Ą (0xC4,0x84)
|
||||
case (char)0x87: //ć (0xC4,0x87) -> Ć (0xC4,0x86)
|
||||
case (char)0x99: //ę (0xC4,0x99) -> Ę (0xC4,0x98)
|
||||
case (char)0x85: //ą (0xC4,0x85) -> Ą (0xC4,0x84) (Polish)
|
||||
case (char)0x87: //ć (0xC4,0x87) -> Ć (0xC4,0x86) (Polish)
|
||||
case (char)0x8D: //č (0xC4,0x8D) -> Č (0xC4,0x8C) (Slovak, Czech)
|
||||
case (char)0x8F: //ď (0xC4,0x8F) -> Ď (0xC4,0x8E) (Slovak, Czech)
|
||||
case (char)0x9F: //ğ (0xC4,0x9F) -> Ğ (0xC4,0x9E) (Turkish)
|
||||
case (char)0x99: //ę (0xC4,0x99) -> Ę (0xC4,0x98) (Polish)
|
||||
case (char)0x9B: //ě (0xC4,0x9B) -> Ě (0xC4,0x9A) (Czech)
|
||||
case (char)0xAF: //ı (0xC4,0xAF) -> I (0xC4,0xAE) (Turkish)
|
||||
case (char)0xB1: //ı (0xC4,0xB1) -> I (0xC4,0xB0) (Turkish)
|
||||
case (char)0xB3: //ij (0xC4,0xB3) -> IJ (0xC4,0xB2) (Dutch)
|
||||
*p -= 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case (char)0xC5:
|
||||
switch (p_v) {
|
||||
case (char)0x82: //ł (0xC5,0x82) -> Ł (0xC5,0x81)
|
||||
case (char)0x84: //ń (0xC5,0x84) -> Ń (0xC5,0x83)
|
||||
case (char)0x9B: //ś (0xC5,0x9B) -> Ś (0xC5,0x9A)
|
||||
case (char)0xBA: //ź (0xC5,0xBA) -> Ź (0xC5,0xB9)
|
||||
case (char)0xBC: //ż (0xC5,0xBC) -> Ż (0xC5,0xBB)
|
||||
case (char)0x81: //ł (0xC5,0x81) -> Ł (0xC5,0x80) (Polish)
|
||||
case (char)0x82: //ł (0xC5,0x82) -> Ł (0xC5,0x81) (Polish)
|
||||
case (char)0x83: //ń (0xC5,0x83) -> Ń (0xC5,0x82) (Polish)
|
||||
case (char)0x84: //ń (0xC5,0x84) -> Ń (0xC5,0x83) (Polish)
|
||||
case (char)0x88: //ň (0xC5,0x88) -> Ň (0xC5,0x87) (Slovak, Czech)
|
||||
case (char)0x95: //ŕ (0xC5,0x95) -> Ŕ (0xC5,0x94) (Slovak)
|
||||
case (char)0x99: //ř (0xC5,0x99) -> Ř (0xC5,0x98) (Czech)
|
||||
case (char)0x9A: //ś (0xC5,0x9A) -> Ś (0xC5,0x99) (Polish)
|
||||
case (char)0x9B: //ś (0xC5,0x9B) -> Ś (0xC5,0x9A) (Polish)
|
||||
case (char)0x9F: //ş (0xC5,0x9F) -> Ş (0xC5,0x9E) (Turkish)
|
||||
case (char)0xA1: //š (0xC5,0xA1) -> Š (0xC5,0xA0) (Slovak, Czech)
|
||||
case (char)0xA5: //ť (0xC5,0xA5) -> Ť (0xC5,0xA4) (Slovak, Czech)
|
||||
case (char)0xAF: //ů (0xC5,0xAF) -> Ů (0xC5,0xAE) (Czech)
|
||||
case (char)0xBA: //ź (0xC5,0xBA) -> Ź (0xC5,0xB9) (Polish)
|
||||
case (char)0xBC: //ż (0xC5,0xBC) -> Ż (0xC5,0xBB) (Polish)
|
||||
case (char)0xBE: //ž (0xC5,0xBE) -> Ž (0xC5,0xBD) (Slovak, Czech)
|
||||
*p -= 1;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -378,27 +378,28 @@ const std::initializer_list<Modbus::EntityModbusInfo> Modbus::modbus_register_ma
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(roomsensor), 199, 1), // roomsensor
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(heatup), 200, 1), // heatup
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(mode), 0, 1), // mode
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwSetTemp), 1, 1), // settemp
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwSetTempLow), 2, 1), // settemplow
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwCircMode), 3, 1), // circmode
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwChargeDuration), 4, 1), // chargeduration
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwCharge), 5, 1), // charge
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwExtra), 6, 1), // extra
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwDisinfecting), 7, 1), // disinfecting
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwDisinfectDay), 8, 1), // disinfectday
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwDisinfectTime), 9, 1), // disinfecttime
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwDailyHeating), 10, 1), // dailyheating
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwDailyHeatTime), 11, 1), // dailyheattime
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwProgMode), 12, 1), // progmode
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwCircProg), 13, 1), // circprog
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwDisinfectHour), 14, 1), // disinfecthour
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwMaxTemp), 15, 1), // maxtemp
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwOneTimeKey), 16, 1), // onetimekey
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(switchtime), 17, 8), // switchtime
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwcircswitchtime), 25, 8), // circswitchtime
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(holidays), 33, 13), // holidays
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(vacations), 46, 13), // vacations
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwWhenModeOff), 59, 1), // whenmodeoff
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(modetype), 1, 1), // modetype
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwSetTemp), 2, 1), // settemp
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwSetTempLow), 3, 1), // settemplow
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwCircMode), 4, 1), // circmode
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwChargeDuration), 5, 1), // chargeduration
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwCharge), 6, 1), // charge
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwExtra), 7, 1), // extra
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwDisinfecting), 8, 1), // disinfecting
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwDisinfectDay), 9, 1), // disinfectday
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwDisinfectTime), 10, 1), // disinfecttime
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwDailyHeating), 11, 1), // dailyheating
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwDailyHeatTime), 12, 1), // dailyheattime
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwProgMode), 13, 1), // progmode
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwCircProg), 14, 1), // circprog
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwDisinfectHour), 15, 1), // disinfecthour
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwMaxTemp), 16, 1), // maxtemp
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwOneTimeKey), 17, 1), // onetimekey
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(switchtime), 18, 8), // switchtime
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwcircswitchtime), 26, 8), // circswitchtime
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(holidays), 34, 13), // holidays
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(vacations), 47, 13), // vacations
|
||||
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwWhenModeOff), 60, 1), // whenmodeoff
|
||||
REGISTER_MAPPING(dt::MIXER, TAG_TYPE_HC, FL_(flowTempHc), 0, 1), // flowtemphc
|
||||
REGISTER_MAPPING(dt::MIXER, TAG_TYPE_HC, FL_(valveStatus), 1, 1), // valvestatus
|
||||
REGISTER_MAPPING(dt::MIXER, TAG_TYPE_HC, FL_(flowSetTemp), 2, 1), // flowsettemp
|
||||
@@ -523,6 +524,8 @@ const std::initializer_list<Modbus::EntityModbusInfo> Modbus::modbus_register_ma
|
||||
REGISTER_MAPPING(dt::SWITCH, TAG_TYPE_DEVICE_DATA, FL_(flowTempHc), 1, 1), // flowtemphc
|
||||
REGISTER_MAPPING(dt::SWITCH, TAG_TYPE_DEVICE_DATA, FL_(status), 2, 1), // status
|
||||
REGISTER_MAPPING(dt::CONTROLLER, TAG_TYPE_DEVICE_DATA, FL_(dateTime), 0, 13), // datetime
|
||||
REGISTER_MAPPING(dt::CONNECT, TAG_TYPE_DEVICE_DATA, FL_(dateTime), 0, 13), // datetime
|
||||
REGISTER_MAPPING(dt::CONNECT, TAG_TYPE_DEVICE_DATA, FL_(outdoorTemp), 13, 1), // outdoortemp
|
||||
REGISTER_MAPPING(dt::ALERT, TAG_TYPE_DEVICE_DATA, FL_(setFlowTemp), 0, 1), // setflowtemp
|
||||
REGISTER_MAPPING(dt::ALERT, TAG_TYPE_DEVICE_DATA, FL_(setBurnPow), 1, 1), // setburnpow
|
||||
REGISTER_MAPPING(dt::EXTENSION, TAG_TYPE_DEVICE_DATA, FL_(flowTempVf), 0, 1), // flowtempvf
|
||||
|
||||
@@ -151,7 +151,7 @@ void Shower::loop() {
|
||||
// turn off hot water to send a shot of cold
|
||||
void Shower::shower_alert_start() {
|
||||
LOG_DEBUG("Shower Alert started");
|
||||
(void)Command::call(EMSdevice::DeviceType::BOILER, "tapactivated", "false", 9);
|
||||
(void)Command::call(EMSdevice::DeviceType::BOILER, "tapactivated", "false", DeviceValueTAG::TAG_DHW1);
|
||||
doing_cold_shot_ = true;
|
||||
force_coldshot = false;
|
||||
alert_timer_start_ = uuid::get_uptime_sec(); // timer starts now
|
||||
@@ -161,7 +161,7 @@ void Shower::shower_alert_start() {
|
||||
void Shower::shower_alert_stop() {
|
||||
if (doing_cold_shot_) {
|
||||
LOG_DEBUG("Shower Alert stopped");
|
||||
(void)Command::call(EMSdevice::DeviceType::BOILER, "tapactivated", "true", 9);
|
||||
(void)Command::call(EMSdevice::DeviceType::BOILER, "tapactivated", "true", DeviceValueTAG::TAG_DHW1);
|
||||
doing_cold_shot_ = false;
|
||||
force_coldshot = false;
|
||||
next_alert_ += shower_alert_trigger_;
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "shuntingYard.h"
|
||||
|
||||
// find tokens
|
||||
// find tokens - optimized to reduce string allocations
|
||||
std::deque<Token> exprToTokens(const std::string & expr) {
|
||||
std::deque<Token> tokens;
|
||||
|
||||
@@ -40,13 +40,14 @@ std::deque<Token> exprToTokens(const std::string & expr) {
|
||||
if (*p) {
|
||||
++p;
|
||||
}
|
||||
auto s = std::string(b, p);
|
||||
auto n = s.find("\"\"");
|
||||
while (n != std::string::npos) {
|
||||
s.erase(n, 2);
|
||||
// Use string_view to avoid unnecessary string copies
|
||||
std::string_view s(b, p - b);
|
||||
auto n = s.find("\"\"");
|
||||
while (n != std::string_view::npos) {
|
||||
s.remove_prefix(n + 2);
|
||||
n = s.find("\"\"");
|
||||
}
|
||||
tokens.emplace_back(Token::Type::String, s, -3);
|
||||
tokens.emplace_back(Token::Type::String, std::string(s), -3);
|
||||
if (*p == '\0') {
|
||||
--p;
|
||||
}
|
||||
@@ -225,11 +226,14 @@ std::deque<Token> exprToTokens(const std::string & expr) {
|
||||
return tokens;
|
||||
}
|
||||
|
||||
// sort tokens to RPN form
|
||||
// sort tokens to RPN form - optimized for memory usage
|
||||
std::deque<Token> shuntingYard(const std::deque<Token> & tokens) {
|
||||
std::deque<Token> queue;
|
||||
std::vector<Token> stack;
|
||||
|
||||
// Reserve space for vector to reduce reallocations
|
||||
stack.reserve(tokens.size() / 2);
|
||||
|
||||
// While there are tokens to be read:
|
||||
for (auto const & token : tokens) {
|
||||
// Read a token
|
||||
|
||||
@@ -135,7 +135,7 @@ void Connect::process_roomThermostat(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(rc->dewtemp_, dt);
|
||||
}
|
||||
|
||||
// gateway(0x48) W gateway(0x50), ?(0x0B42), data: 01 // icon in ofset 0
|
||||
// gateway(0x48) W gateway(0x50), ?(0x0B42), data: 01 // icon in offset 0
|
||||
// gateway(0x48) W gateway(0x50), ?(0x0B42), data: 00 4B 00 FC 00 63 00 68 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 (offset 1)
|
||||
void Connect::process_roomThermostatName(std::shared_ptr<const Telegram> telegram) {
|
||||
auto rc = room_circuit(telegram->type_id - 0xB3D);
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define EMSESP_APP_VERSION "3.7.3-dev.20"
|
||||
#define EMSESP_APP_VERSION "3.7.3-dev.21"
|
||||
|
||||
@@ -263,8 +263,8 @@ bool Test::test(const std::string & cmd, int8_t id1, int8_t id2) {
|
||||
if (cmd == "src") {
|
||||
EMSESP::logger().notice("Adding SRC plus thermostat...");
|
||||
|
||||
add_device(0x50, 17); // MX400 module
|
||||
uart_telegram("50 00 FF 00 0A DD 00 E6 36 2A"); // monitor, temperatures
|
||||
add_device(0x50, 17); // MX400 module
|
||||
uart_telegram("50 00 FF 00 0A DD 00 E6 36 2A"); // monitor, temperatures
|
||||
uart_telegram("50 00 FF 00 0A B5 00 FF 00 24 01 FF 24 00"); // mode, childlock
|
||||
// switchprogram
|
||||
uart_telegram("50 00 FF 00 0A 65 2A 00 3C 2A FF FF 2A FF FF 2A FF FF 2A FF FF 2A FF FF");
|
||||
@@ -764,7 +764,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
test("boiler");
|
||||
|
||||
// device type, command, data
|
||||
Command::call(EMSdevice::DeviceType::BOILER, "tapactivated", "false", 9);
|
||||
Command::call(EMSdevice::DeviceType::BOILER, "tapactivated", "false", DeviceValueTAG::TAG_DHW1);
|
||||
ok = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -318,7 +318,7 @@ const char * run_console_command(const char * command) {
|
||||
}
|
||||
|
||||
void console_test1() {
|
||||
auto expected_response = "Log level: DEBUG\n";
|
||||
auto expected_response = "Log level: DEBUG";
|
||||
TEST_ASSERT_EQUAL_STRING(expected_response, run_console_command("log"));
|
||||
}
|
||||
|
||||
@@ -329,7 +329,7 @@ void console_test2() {
|
||||
|
||||
void console_test3() {
|
||||
// test bad command
|
||||
auto expected_response = "Bad syntax. Check arguments.\n";
|
||||
auto expected_response = "Bad syntax. Check arguments.";
|
||||
TEST_ASSERT_EQUAL_STRING(expected_response, run_console_command("call thermostat mode bad"));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user