This commit is contained in:
MichaelDvP
2024-11-07 18:37:23 +01:00
24 changed files with 266 additions and 232 deletions

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

@@ -0,0 +1,37 @@
name: 'pr_check'
on:
workflow_dispatch:
pull_request:
branches: dev
paths:
- '**.c'
- '**.cpp'
- '**.h'
- '**.hpp'
- '**.json'
- '**.py'
- '**.md'
- '.github/workflows/pr_check.yml'
jobs:
pre-release:
name: 'Automatic pre-release build'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install python 3.11
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install PlatformIO
run: |
pip install wheel
pip install -U platformio
- name: Build native
run: |
platformio run -e native

View File

@@ -10,13 +10,13 @@ For more details go to [www.emsesp.org](https://www.emsesp.org/).
- include HA "unit_of_meas", "stat_cla" and "dev_cla" attributes for Number sensors [#2149](https://github.com/emsesp/EMS-ESP32/issues/2149) - include HA "unit_of_meas", "stat_cla" and "dev_cla" attributes for Number sensors [#2149](https://github.com/emsesp/EMS-ESP32/issues/2149)
- Bosch CS6800i AW - Silent Mode + Electrical Power Reduction (HP) [#2147](https://github.com/emsesp/EMS-ESP32/issues/2147) - Bosch CS6800i AW - Silent Mode + Electrical Power Reduction (HP) [#2147](https://github.com/emsesp/EMS-ESP32/issues/2147)
- system commands for showertimer and showeralert [#2168](https://github.com/emsesp/EMS-ESP32/discussions/2168) - /api/system/showeralert and /api/system/showertimer [#2182](https://github.com/emsesp/EMS-ESP32/issues/2182)
## Fixed ## Fixed
- Modbus integration in 3.7.0 missing offset [#2148](https://github.com/emsesp/EMS-ESP32/issues/2148) - Modbus integration in 3.7.0 missing offset [#2148](https://github.com/emsesp/EMS-ESP32/issues/2148)
- fix changing TZ in NTPsettings without clearing enable+server, added DST support [#2142](https://github.com/emsesp/EMS-ESP32/issues/2142) - fix changing TZ in NTPsettings without clearing enable+server, added DST support [#2142](https://github.com/emsesp/EMS-ESP32/issues/2142)
- Support MQTT Discovery (AD) with Domoticz [#2177](https://github.com/emsesp/EMS-ESP32/issues/2177)
- wwExtra (dhw extra) changed from temperature reading to number
## Changed ## Changed
- MQTT discovery template to support Domoticz [#2138](https://github.com/emsesp/EMS-ESP32/discussions/2138)

View File

@@ -43,7 +43,7 @@ DEFINES += -DARDUINOJSON_ENABLE -DARDUINOJSON_ENABLE_ARDUINO_STRING -DARDUINOJSO
DEFINES += -DEMSESP_STANDALONE -DEMSESP_TEST -DEMSESP_DEBUG -DEMC_RX_BUFFER_SIZE=1500 DEFINES += -DEMSESP_STANDALONE -DEMSESP_TEST -DEMSESP_DEBUG -DEMC_RX_BUFFER_SIZE=1500
DEFINES += $(ARGS) DEFINES += $(ARGS)
DEFAULTS = -DEMSESP_DEFAULT_LOCALE=\"en\" -DEMSESP_DEFAULT_TX_MODE=8 -DEMSESP_DEFAULT_VERSION=\"3.7.0-dev\" -DEMSESP_DEFAULT_BOARD_PROFILE=\"S32\" DEFAULTS = -DEMSESP_DEFAULT_LOCALE=\"en\" -DEMSESP_DEFAULT_TX_MODE=8 -DEMSESP_DEFAULT_VERSION=\"3.7.1-dev\" -DEMSESP_DEFAULT_BOARD_PROFILE=\"S3\"
#---------------------------------------------------------------------- #----------------------------------------------------------------------
# Sources & Files # Sources & Files

View File

@@ -54,8 +54,6 @@ For a live demo go to [demo.emsesp.org](https://demo.emsesp.org). Pick a languag
EMS-ESP is a project created by [proddy](https://github.com/proddy) and owned and maintained by both [proddy](https://github.com/proddy) and [MichaelDvP](https://github.com/MichaelDvP) with support from [BBQKees Electronics](https://bbqkees-electronics.nl). EMS-ESP is a project created by [proddy](https://github.com/proddy) and owned and maintained by both [proddy](https://github.com/proddy) and [MichaelDvP](https://github.com/MichaelDvP) with support from [BBQKees Electronics](https://bbqkees-electronics.nl).
You can contact us using [this form](https://emsesp.org/Contact/).
If you like **EMS-ESP**, please give it a ✨ on GitHub, or even better fork it and contribute. You can also offer a small donation. This is an open-source project maintained by volunteers, and your support is greatly appreciated. If you like **EMS-ESP**, please give it a ✨ on GitHub, or even better fork it and contribute. You can also offer a small donation. This is an open-source project maintained by volunteers, and your support is greatly appreciated.
## **Libraries used** ## **Libraries used**

View File

@@ -4779,7 +4779,7 @@
| circmode | circulation pump mode | enum [off\|on\|auto\|own prog] | | true | DHW | 3 | 1 | 1 | | circmode | circulation pump mode | enum [off\|on\|auto\|own prog] | | true | DHW | 3 | 1 | 1 |
| chargeduration | charge duration | uint8 (>=0<=3810) | minutes | true | DHW | 4 | 1 | 15 | | chargeduration | charge duration | uint8 (>=0<=3810) | minutes | true | DHW | 4 | 1 | 15 |
| charge | charge | boolean | | true | DHW | 5 | 1 | 1 | | charge | charge | boolean | | true | DHW | 5 | 1 | 1 |
| extra | extra | uint8 (>=0<=254) | C | false | DHW | 6 | 1 | 1 | | extra | extra | uint8 (>=0<=254) | | false | DHW | 6 | 1 | 1 |
| disinfecting | disinfecting | boolean | | true | DHW | 7 | 1 | 1 | | disinfecting | disinfecting | boolean | | true | DHW | 7 | 1 | 1 |
| disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 8 | 1 | 1 | | disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 8 | 1 | 1 |
| disinfecttime | disinfection time | uint8 (>=0<=1431) | minutes | true | DHW | 9 | 1 | 15 | | disinfecttime | disinfection time | uint8 (>=0<=1431) | minutes | true | DHW | 9 | 1 | 15 |
@@ -4895,7 +4895,7 @@
| circmode | circulation pump mode | enum [off\|on\|auto\|own prog] | | true | DHW | 3 | 1 | 1 | | circmode | circulation pump mode | enum [off\|on\|auto\|own prog] | | true | DHW | 3 | 1 | 1 |
| chargeduration | charge duration | uint8 (>=0<=3810) | minutes | true | DHW | 4 | 1 | 15 | | chargeduration | charge duration | uint8 (>=0<=3810) | minutes | true | DHW | 4 | 1 | 15 |
| charge | charge | boolean | | true | DHW | 5 | 1 | 1 | | charge | charge | boolean | | true | DHW | 5 | 1 | 1 |
| extra | extra | uint8 (>=0<=254) | C | false | DHW | 6 | 1 | 1 | | extra | extra | uint8 (>=0<=254) | | false | DHW | 6 | 1 | 1 |
| disinfecting | disinfecting | boolean | | true | DHW | 7 | 1 | 1 | | disinfecting | disinfecting | boolean | | true | DHW | 7 | 1 | 1 |
| disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 8 | 1 | 1 | | disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 8 | 1 | 1 |
| disinfecttime | disinfection time | uint8 (>=0<=1431) | minutes | true | DHW | 9 | 1 | 15 | | disinfecttime | disinfection time | uint8 (>=0<=1431) | minutes | true | DHW | 9 | 1 | 15 |
@@ -5023,7 +5023,7 @@
| circmode | circulation pump mode | enum [off\|on\|auto\|own prog] | | true | DHW | 3 | 1 | 1 | | circmode | circulation pump mode | enum [off\|on\|auto\|own prog] | | true | DHW | 3 | 1 | 1 |
| chargeduration | charge duration | uint8 (>=0<=3810) | minutes | true | DHW | 4 | 1 | 15 | | chargeduration | charge duration | uint8 (>=0<=3810) | minutes | true | DHW | 4 | 1 | 15 |
| charge | charge | boolean | | true | DHW | 5 | 1 | 1 | | charge | charge | boolean | | true | DHW | 5 | 1 | 1 |
| extra | extra | uint8 (>=0<=254) | C | false | DHW | 6 | 1 | 1 | | extra | extra | uint8 (>=0<=254) | | false | DHW | 6 | 1 | 1 |
| disinfecting | disinfecting | boolean | | true | DHW | 7 | 1 | 1 | | disinfecting | disinfecting | boolean | | true | DHW | 7 | 1 | 1 |
| disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 8 | 1 | 1 | | disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 8 | 1 | 1 |
| disinfecttime | disinfection time | uint8 (>=0<=1431) | minutes | true | DHW | 9 | 1 | 15 | | disinfecttime | disinfection time | uint8 (>=0<=1431) | minutes | true | DHW | 9 | 1 | 15 |
@@ -5267,7 +5267,7 @@
| circmode | circulation pump mode | enum [off\|on\|auto\|own prog] | | true | DHW | 3 | 1 | 1 | | circmode | circulation pump mode | enum [off\|on\|auto\|own prog] | | true | DHW | 3 | 1 | 1 |
| chargeduration | charge duration | uint8 (>=0<=3810) | minutes | true | DHW | 4 | 1 | 15 | | chargeduration | charge duration | uint8 (>=0<=3810) | minutes | true | DHW | 4 | 1 | 15 |
| charge | charge | boolean | | true | DHW | 5 | 1 | 1 | | charge | charge | boolean | | true | DHW | 5 | 1 | 1 |
| extra | extra | uint8 (>=0<=254) | C | false | DHW | 6 | 1 | 1 | | extra | extra | uint8 (>=0<=254) | | false | DHW | 6 | 1 | 1 |
| disinfecting | disinfecting | boolean | | true | DHW | 7 | 1 | 1 | | disinfecting | disinfecting | boolean | | true | DHW | 7 | 1 | 1 |
| disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 8 | 1 | 1 | | disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 8 | 1 | 1 |
| disinfecttime | disinfection time | uint8 (>=0<=1431) | minutes | true | DHW | 9 | 1 | 15 | | disinfecttime | disinfection time | uint8 (>=0<=1431) | minutes | true | DHW | 9 | 1 | 15 |
@@ -5355,7 +5355,7 @@
| circmode | circulation pump mode | enum [off\|on\|auto\|own prog] | | true | DHW | 3 | 1 | 1 | | circmode | circulation pump mode | enum [off\|on\|auto\|own prog] | | true | DHW | 3 | 1 | 1 |
| chargeduration | charge duration | uint8 (>=0<=3810) | minutes | true | DHW | 4 | 1 | 15 | | chargeduration | charge duration | uint8 (>=0<=3810) | minutes | true | DHW | 4 | 1 | 15 |
| charge | charge | boolean | | true | DHW | 5 | 1 | 1 | | charge | charge | boolean | | true | DHW | 5 | 1 | 1 |
| extra | extra | uint8 (>=0<=254) | C | false | DHW | 6 | 1 | 1 | | extra | extra | uint8 (>=0<=254) | | false | DHW | 6 | 1 | 1 |
| disinfecting | disinfecting | boolean | | true | DHW | 7 | 1 | 1 | | disinfecting | disinfecting | boolean | | true | DHW | 7 | 1 | 1 |
| disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 8 | 1 | 1 | | disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 8 | 1 | 1 |
| disinfecttime | disinfection time | uint8 (>=0<=1431) | minutes | true | DHW | 9 | 1 | 15 | | disinfecttime | disinfection time | uint8 (>=0<=1431) | minutes | true | DHW | 9 | 1 | 15 |
@@ -5453,7 +5453,7 @@
| circmode | circulation pump mode | enum [off\|on\|auto\|own prog] | | true | DHW | 3 | 1 | 1 | | circmode | circulation pump mode | enum [off\|on\|auto\|own prog] | | true | DHW | 3 | 1 | 1 |
| chargeduration | charge duration | uint8 (>=0<=3810) | minutes | true | DHW | 4 | 1 | 15 | | chargeduration | charge duration | uint8 (>=0<=3810) | minutes | true | DHW | 4 | 1 | 15 |
| charge | charge | boolean | | true | DHW | 5 | 1 | 1 | | charge | charge | boolean | | true | DHW | 5 | 1 | 1 |
| extra | extra | uint8 (>=0<=254) | C | false | DHW | 6 | 1 | 1 | | extra | extra | uint8 (>=0<=254) | | false | DHW | 6 | 1 | 1 |
| disinfecting | disinfecting | boolean | | true | DHW | 7 | 1 | 1 | | disinfecting | disinfecting | boolean | | true | DHW | 7 | 1 | 1 |
| disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 8 | 1 | 1 | | disinfectday | disinfection day | enum [mo\|tu\|we\|th\|fr\|sa\|su\|all] | | true | DHW | 8 | 1 | 1 |
| disinfecttime | disinfection time | uint8 (>=0<=1431) | minutes | true | DHW | 9 | 1 | 15 | | disinfecttime | disinfection time | uint8 (>=0<=1431) | minutes | true | DHW | 9 | 1 | 15 |

View File

@@ -3438,7 +3438,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
"UI800, BC400",thermostat,4,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,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,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,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,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1 "UI800, BC400",thermostat,4,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1
"UI800, BC400",thermostat,4,extra,extra,uint8 (>=0<=254),C,false,sensor.thermostat_dhw_extra,sensor.thermostat_dhw_extra,6,9,1,6,1 "UI800, BC400",thermostat,4,extra,extra,uint8 (>=0<=254), ,false,sensor.thermostat_dhw_extra,sensor.thermostat_dhw_extra,6,9,1,6,1
"UI800, BC400",thermostat,4,disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,7,1 "UI800, BC400",thermostat,4,disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,7,1
"UI800, BC400",thermostat,4,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,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,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,disinfecttime,disinfection time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_disinfection_time,number.thermostat_dhw_disinfecttime,6,9,15,9,1
@@ -3807,7 +3807,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
"RC200, CW100, CR120, CR50",thermostat,157,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,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,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,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,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1 "RC200, CW100, CR120, CR50",thermostat,157,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1
"RC200, CW100, CR120, CR50",thermostat,157,extra,extra,uint8 (>=0<=254),C,false,sensor.thermostat_dhw_extra,sensor.thermostat_dhw_extra,6,9,1,6,1 "RC200, CW100, CR120, CR50",thermostat,157,extra,extra,uint8 (>=0<=254), ,false,sensor.thermostat_dhw_extra,sensor.thermostat_dhw_extra,6,9,1,6,1
"RC200, CW100, CR120, CR50",thermostat,157,disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,7,1 "RC200, CW100, CR120, CR50",thermostat,157,disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,7,1
"RC200, CW100, CR120, CR50",thermostat,157,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,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,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,disinfecttime,disinfection time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_disinfection_time,number.thermostat_dhw_disinfecttime,6,9,15,9,1
@@ -3891,7 +3891,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,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,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,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,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,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,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,extra,extra,uint8 (>=0<=254),C,false,sensor.thermostat_dhw_extra,sensor.thermostat_dhw_extra,6,9,1,6,1 "RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,extra,extra,uint8 (>=0<=254), ,false,sensor.thermostat_dhw_extra,sensor.thermostat_dhw_extra,6,9,1,6,1
"RC3*0, Moduline 3000/1010H, CW400, Sense II, HPC410",thermostat,158,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,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,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,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,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,disinfecttime,disinfection time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_disinfection_time,number.thermostat_dhw_disinfecttime,6,9,15,9,1
@@ -3975,7 +3975,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
"RC100, CR10, Moduline 1000/1010",thermostat,165,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 "RC100, CR10, Moduline 1000/1010",thermostat,165,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
"RC100, CR10, Moduline 1000/1010",thermostat,165,chargeduration,charge duration,uint8 (>=0<=3810),minutes,true,number.thermostat_dhw_charge_duration,number.thermostat_dhw_chargeduration,6,9,15,4,1 "RC100, CR10, Moduline 1000/1010",thermostat,165,chargeduration,charge duration,uint8 (>=0<=3810),minutes,true,number.thermostat_dhw_charge_duration,number.thermostat_dhw_chargeduration,6,9,15,4,1
"RC100, CR10, Moduline 1000/1010",thermostat,165,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1 "RC100, CR10, Moduline 1000/1010",thermostat,165,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1
"RC100, CR10, Moduline 1000/1010",thermostat,165,extra,extra,uint8 (>=0<=254),C,false,sensor.thermostat_dhw_extra,sensor.thermostat_dhw_extra,6,9,1,6,1 "RC100, CR10, Moduline 1000/1010",thermostat,165,extra,extra,uint8 (>=0<=254), ,false,sensor.thermostat_dhw_extra,sensor.thermostat_dhw_extra,6,9,1,6,1
"RC100, CR10, Moduline 1000/1010",thermostat,165,disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,7,1 "RC100, CR10, Moduline 1000/1010",thermostat,165,disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,7,1
"RC100, CR10, Moduline 1000/1010",thermostat,165,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 "RC100, CR10, Moduline 1000/1010",thermostat,165,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
"RC100, CR10, Moduline 1000/1010",thermostat,165,disinfecttime,disinfection time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_disinfection_time,number.thermostat_dhw_disinfecttime,6,9,15,9,1 "RC100, CR10, Moduline 1000/1010",thermostat,165,disinfecttime,disinfection time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_disinfection_time,number.thermostat_dhw_disinfecttime,6,9,15,9,1
@@ -4060,7 +4060,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
"Rego 2000/3000",thermostat,172,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,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,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,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,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1 "Rego 2000/3000",thermostat,172,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1
"Rego 2000/3000",thermostat,172,extra,extra,uint8 (>=0<=254),C,false,sensor.thermostat_dhw_extra,sensor.thermostat_dhw_extra,6,9,1,6,1 "Rego 2000/3000",thermostat,172,extra,extra,uint8 (>=0<=254), ,false,sensor.thermostat_dhw_extra,sensor.thermostat_dhw_extra,6,9,1,6,1
"Rego 2000/3000",thermostat,172,disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,7,1 "Rego 2000/3000",thermostat,172,disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,7,1
"Rego 2000/3000",thermostat,172,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,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,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,disinfecttime,disinfection time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_disinfection_time,number.thermostat_dhw_disinfecttime,6,9,15,9,1
@@ -4171,7 +4171,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
"Rego 3000, UI800, Logamatic BC400",thermostat,253,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,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,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,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,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1 "Rego 3000, UI800, Logamatic BC400",thermostat,253,charge,charge,boolean, ,true,switch.thermostat_dhw_charge,switch.thermostat_dhw_charge,6,9,1,5,1
"Rego 3000, UI800, Logamatic BC400",thermostat,253,extra,extra,uint8 (>=0<=254),C,false,sensor.thermostat_dhw_extra,sensor.thermostat_dhw_extra,6,9,1,6,1 "Rego 3000, UI800, Logamatic BC400",thermostat,253,extra,extra,uint8 (>=0<=254), ,false,sensor.thermostat_dhw_extra,sensor.thermostat_dhw_extra,6,9,1,6,1
"Rego 3000, UI800, Logamatic BC400",thermostat,253,disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,7,1 "Rego 3000, UI800, Logamatic BC400",thermostat,253,disinfecting,disinfecting,boolean, ,true,switch.thermostat_dhw_disinfecting,switch.thermostat_dhw_disinfecting,6,9,1,7,1
"Rego 3000, UI800, Logamatic BC400",thermostat,253,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,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,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,disinfecttime,disinfection time,uint8 (>=0<=1431),minutes,true,number.thermostat_dhw_disinfection_time,number.thermostat_dhw_disinfecttime,6,9,15,9,1
Can't render this file because it is too large.

View File

@@ -27,7 +27,7 @@
"@mui/icons-material": "^6.1.6", "@mui/icons-material": "^6.1.6",
"@mui/material": "^6.1.6", "@mui/material": "^6.1.6",
"@table-library/react-table-library": "4.1.7", "@table-library/react-table-library": "4.1.7",
"alova": "3.2.1", "alova": "3.2.2",
"async-validator": "^4.2.5", "async-validator": "^4.2.5",
"jwt-decode": "^4.0.0", "jwt-decode": "^4.0.0",
"mime-types": "^2.1.35", "mime-types": "^2.1.35",
@@ -35,7 +35,7 @@
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"react-icons": "^5.3.0", "react-icons": "^5.3.0",
"react-router-dom": "^6.27.0", "react-router-dom": "^6.28.0",
"react-toastify": "^10.0.6", "react-toastify": "^10.0.6",
"typesafe-i18n": "^5.26.2", "typesafe-i18n": "^5.26.2",
"typescript": "^5.6.3" "typescript": "^5.6.3"
@@ -47,21 +47,21 @@
"@preact/preset-vite": "^2.9.1", "@preact/preset-vite": "^2.9.1",
"@trivago/prettier-plugin-sort-imports": "^4.3.0", "@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@types/formidable": "^3", "@types/formidable": "^3",
"@types/node": "^22.8.7", "@types/node": "^22.9.0",
"@types/react": "^18.3.12", "@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1", "@types/react-dom": "^18.3.1",
"@types/react-router-dom": "^5.3.3", "@types/react-router-dom": "^5.3.3",
"concurrently": "^9.0.1", "concurrently": "^9.1.0",
"eslint": "^9.14.0", "eslint": "^9.14.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"formidable": "^3.5.2", "formidable": "^3.5.2",
"prettier": "^3.3.3", "prettier": "^3.3.3",
"rollup-plugin-visualizer": "^5.12.0", "rollup-plugin-visualizer": "^5.12.0",
"terser": "^5.36.0", "terser": "^5.36.0",
"typescript-eslint": "8.12.2", "typescript-eslint": "8.13.0",
"vite": "^5.4.10", "vite": "^5.4.10",
"vite-plugin-imagemin": "^0.6.1", "vite-plugin-imagemin": "^0.6.1",
"vite-tsconfig-paths": "^5.0.1" "vite-tsconfig-paths": "^5.1.0"
}, },
"packageManager": "yarn@4.5.1" "packageManager": "yarn@4.5.1"
} }

View File

@@ -107,7 +107,7 @@ const Dashboard = () => {
}, },
&:hover .td { &:hover .td {
background-color: #177ac9; background-color: #177ac9;
} },
`, `,
BaseCell: ` BaseCell: `
&:nth-of-type(2) { &:nth-of-type(2) {
@@ -185,18 +185,16 @@ const Dashboard = () => {
// if its a device (parent node) and has entities // if its a device (parent node) and has entities
if (di.nodes?.length) { if (di.nodes?.length) {
return ( return (
<> <span style={{ fontWeight: 'bold', fontSize: '14px' }}>
<span style="font-size: 14px"> <DeviceIcon type_id={di.t ?? 0} />
<DeviceIcon type_id={di.t ?? 0} /> &nbsp;&nbsp;{showType(di.n, di.t)}
&nbsp;&nbsp;{showType(di.n, di.t)}
</span>
<span style={{ color: 'lightblue' }}>&nbsp;({di.nodes?.length})</span> <span style={{ color: 'lightblue' }}>&nbsp;({di.nodes?.length})</span>
</> </span>
); );
} }
} }
if (di.dv) { if (di.dv) {
return <span style="color:lightgrey">{di.dv.id.slice(2)}</span>; return <span>{di.dv.id.slice(2)}</span>;
} }
}; };
@@ -250,10 +248,10 @@ const Dashboard = () => {
onChange={handleShowAll} onChange={handleShowAll}
> >
<ToggleButton value={true}> <ToggleButton value={true}>
<UnfoldMoreIcon sx={{ fontSize: 14 }} /> <UnfoldMoreIcon sx={{ fontSize: 18 }} />
</ToggleButton> </ToggleButton>
<ToggleButton value={false}> <ToggleButton value={false}>
<UnfoldLessIcon sx={{ fontSize: 14 }} /> <UnfoldLessIcon sx={{ fontSize: 18 }} />
</ToggleButton> </ToggleButton>
</ToggleButtonGroup> </ToggleButtonGroup>
</Grid> </Grid>
@@ -304,9 +302,7 @@ const Dashboard = () => {
title={formatValue(LL, di.dv?.v, di.dv?.u)} title={formatValue(LL, di.dv?.v, di.dv?.u)}
arrow arrow
> >
<span style={{ color: 'lightgrey' }}> <span>{formatValue(LL, di.dv?.v, di.dv?.u)}</span>
{formatValue(LL, di.dv?.v, di.dv?.u)}
</span>
</Tooltip> </Tooltip>
</Cell> </Cell>
@@ -314,10 +310,7 @@ const Dashboard = () => {
{me.admin && {me.admin &&
di.dv?.c && di.dv?.c &&
!hasMask(di.dv.id, DeviceEntityMask.DV_READONLY) && ( !hasMask(di.dv.id, DeviceEntityMask.DV_READONLY) && (
<IconButton <IconButton onClick={() => editDashboardValue(di)}>
size="small"
onClick={() => editDashboardValue(di)}
>
<EditIcon <EditIcon
color="primary" color="primary"
sx={{ fontSize: 16 }} sx={{ fontSize: 16 }}

View File

@@ -155,7 +155,6 @@ const Devices = () => {
} }
&.tr.tr-body.row-select.row-select-single-selected { &.tr.tr-body.row-select.row-select-single-selected {
background-color: #177ac9; background-color: #177ac9;
font-weight: normal;
} }
` `
}); });
@@ -169,11 +168,11 @@ const Devices = () => {
HeaderRow: ` HeaderRow: `
.th { .th {
padding: 8px; padding: 8px;
height: 36px;
`, `,
Row: ` Row: `
font-weight: bold;
&:hover .td { &:hover .td {
background-color: #177ac9; background-color: #177ac9;
` `
} }
]); ]);
@@ -216,7 +215,7 @@ const Devices = () => {
background-color: #303030; background-color: #303030;
}, },
&:hover .td { &:hover .td {
background-color: #177ac9; background-color: #177ac9;
} }
` `
} }
@@ -523,7 +522,7 @@ const Devices = () => {
<IconContext.Provider <IconContext.Provider
value={{ value={{
color: 'lightblue', color: 'lightblue',
size: '18', size: '16',
style: { verticalAlign: 'middle' } style: { verticalAlign: 'middle' }
}} }}
> >
@@ -574,7 +573,9 @@ const Devices = () => {
const deviceValueDialogClose = () => { const deviceValueDialogClose = () => {
setDeviceValueDialogOpen(false); setDeviceValueDialogOpen(false);
void sendDeviceData(selectedDevice); if (selectedDevice !== undefined) {
void sendDeviceData(selectedDevice);
}
}; };
const renderDeviceData = () => { const renderDeviceData = () => {

View File

@@ -261,16 +261,6 @@ const SystemLog = () => {
> >
{LL.EXPORT()} {LL.EXPORT()}
</Button> </Button>
{dirtyFlags && dirtyFlags.length !== 0 && (
<Button
startIcon={<WarningIcon color="warning" />}
variant="contained"
color="info"
onClick={saveSettings}
>
{LL.APPLY_CHANGES(dirtyFlags.length)}
</Button>
)}
</Grid> </Grid>
{readOpen ? ( {readOpen ? (
@@ -315,6 +305,19 @@ const SystemLog = () => {
)} )}
</> </>
)} )}
{dirtyFlags && dirtyFlags.length !== 0 && (
<Grid>
<Button
startIcon={<WarningIcon color="warning" />}
variant="contained"
color="info"
onClick={saveSettings}
>
{LL.APPLY_CHANGES(dirtyFlags.length)}
</Button>
</Grid>
)}
</Grid> </Grid>
<Box <Box

View File

@@ -1133,10 +1133,10 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@remix-run/router@npm:1.20.0": "@remix-run/router@npm:1.21.0":
version: 1.20.0 version: 1.21.0
resolution: "@remix-run/router@npm:1.20.0" resolution: "@remix-run/router@npm:1.21.0"
checksum: 10c0/2e017dea530717a6e93a16d478714c4c9165313a1c48e39172ec609bc20324ca6362e8ee2243602df6343644c9268d82a3f50f154d3bb8a17dddde6c37be6e83 checksum: 10c0/570792211c083a1c7146613b79cbb8e0d1e14f34e974052e060e7f9dcad38c800d80fe0a18bf42811bc278ab12c0e8fd62cfce649e905046c4e55bd5a09eafdc
languageName: node languageName: node
linkType: hard linkType: hard
@@ -1449,12 +1449,12 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/node@npm:^22.8.7": "@types/node@npm:^22.9.0":
version: 22.8.7 version: 22.9.0
resolution: "@types/node@npm:22.8.7" resolution: "@types/node@npm:22.9.0"
dependencies: dependencies:
undici-types: "npm:~6.19.8" undici-types: "npm:~6.19.8"
checksum: 10c0/14372885db80059ed6e92c320b2bcd8f7dc271698adce11f51aa0f424a3f82aa1749a4f66321b87043791b894346b2458d514cbb65ce70167c2fd8a78a124947 checksum: 10c0/3f46cbe0a49bab4ba30494025e4c8a6e699b98ac922857aa1f0209ce11a1313ee46e6808b8f13fe5b8b960a9d7796b77c8d542ad4e9810e85ef897d5593b5d51
languageName: node languageName: node
linkType: hard linkType: hard
@@ -1539,15 +1539,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/eslint-plugin@npm:8.12.2": "@typescript-eslint/eslint-plugin@npm:8.13.0":
version: 8.12.2 version: 8.13.0
resolution: "@typescript-eslint/eslint-plugin@npm:8.12.2" resolution: "@typescript-eslint/eslint-plugin@npm:8.13.0"
dependencies: dependencies:
"@eslint-community/regexpp": "npm:^4.10.0" "@eslint-community/regexpp": "npm:^4.10.0"
"@typescript-eslint/scope-manager": "npm:8.12.2" "@typescript-eslint/scope-manager": "npm:8.13.0"
"@typescript-eslint/type-utils": "npm:8.12.2" "@typescript-eslint/type-utils": "npm:8.13.0"
"@typescript-eslint/utils": "npm:8.12.2" "@typescript-eslint/utils": "npm:8.13.0"
"@typescript-eslint/visitor-keys": "npm:8.12.2" "@typescript-eslint/visitor-keys": "npm:8.13.0"
graphemer: "npm:^1.4.0" graphemer: "npm:^1.4.0"
ignore: "npm:^5.3.1" ignore: "npm:^5.3.1"
natural-compare: "npm:^1.4.0" natural-compare: "npm:^1.4.0"
@@ -1558,66 +1558,66 @@ __metadata:
peerDependenciesMeta: peerDependenciesMeta:
typescript: typescript:
optional: true optional: true
checksum: 10c0/0f9c0982bc652c723923d22944254cb7c96fbb972e375f4eb1b031a512e67abc83a335f4ba677cff2275e83a7a61d3937473a3939ae4aa9a5b52a5313f02fb75 checksum: 10c0/ee96515e9def17b0d1b8d568d4afcd21c5a8a1bc01bf2f30c4d1f396b41a2f49de3508f79c6231a137ca06943dd6933ac00032652190ab99a4e935ffef44df0b
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/parser@npm:8.12.2": "@typescript-eslint/parser@npm:8.13.0":
version: 8.12.2 version: 8.13.0
resolution: "@typescript-eslint/parser@npm:8.12.2" resolution: "@typescript-eslint/parser@npm:8.13.0"
dependencies: dependencies:
"@typescript-eslint/scope-manager": "npm:8.12.2" "@typescript-eslint/scope-manager": "npm:8.13.0"
"@typescript-eslint/types": "npm:8.12.2" "@typescript-eslint/types": "npm:8.13.0"
"@typescript-eslint/typescript-estree": "npm:8.12.2" "@typescript-eslint/typescript-estree": "npm:8.13.0"
"@typescript-eslint/visitor-keys": "npm:8.12.2" "@typescript-eslint/visitor-keys": "npm:8.13.0"
debug: "npm:^4.3.4" debug: "npm:^4.3.4"
peerDependencies: peerDependencies:
eslint: ^8.57.0 || ^9.0.0 eslint: ^8.57.0 || ^9.0.0
peerDependenciesMeta: peerDependenciesMeta:
typescript: typescript:
optional: true optional: true
checksum: 10c0/0d41f02e91045c5dca70e347731c74a4162ab567bedf3f7f69a2c3f152f629f2d1f96cf09188270c7df48e8a2d6193ccf177e636dcaa3e58cb85ba453c343d24 checksum: 10c0/fa04f6c417c0f72104e148f1d7ff53e04108d383550365a556fbfae5d2283484696235db522189e17bc49039946977078e324100cef991ca01f78704182624ad
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/scope-manager@npm:8.12.2": "@typescript-eslint/scope-manager@npm:8.13.0":
version: 8.12.2 version: 8.13.0
resolution: "@typescript-eslint/scope-manager@npm:8.12.2" resolution: "@typescript-eslint/scope-manager@npm:8.13.0"
dependencies: dependencies:
"@typescript-eslint/types": "npm:8.12.2" "@typescript-eslint/types": "npm:8.13.0"
"@typescript-eslint/visitor-keys": "npm:8.12.2" "@typescript-eslint/visitor-keys": "npm:8.13.0"
checksum: 10c0/e953838e9c1a55cc23c8ec5ecd0a7d447020ac8a1171bed248b6751fc3ec3910a5dad3497a63b660106844a4abeb17265b9a49ce2d0e29264213579b6cda20ab checksum: 10c0/1924b3e740e244d98f8a99740b4196d23ae3263303b387c66db94e140455a3132e603a130f3f70fc71e37f4bda5d0c0c67224ae3911908b097ef3f972c136be4
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/type-utils@npm:8.12.2": "@typescript-eslint/type-utils@npm:8.13.0":
version: 8.12.2 version: 8.13.0
resolution: "@typescript-eslint/type-utils@npm:8.12.2" resolution: "@typescript-eslint/type-utils@npm:8.13.0"
dependencies: dependencies:
"@typescript-eslint/typescript-estree": "npm:8.12.2" "@typescript-eslint/typescript-estree": "npm:8.13.0"
"@typescript-eslint/utils": "npm:8.12.2" "@typescript-eslint/utils": "npm:8.13.0"
debug: "npm:^4.3.4" debug: "npm:^4.3.4"
ts-api-utils: "npm:^1.3.0" ts-api-utils: "npm:^1.3.0"
peerDependenciesMeta: peerDependenciesMeta:
typescript: typescript:
optional: true optional: true
checksum: 10c0/88fb254acb022a6997a7335f1d9db54112f89a6f090afbf7c0ca52a6b70885391db7d6d40cf016084425f2899aaff49dac31e9df8cff12aae90c9c051eab69ff checksum: 10c0/65319084616f3aea3d9f8dfab30c9b0a70de7314b445805016fdf0d0e39fe073eef2813c3e16c3e1c6a40462ba8eecfdbb12ab1e8570c3407a1cccdb69d4bc8b
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/types@npm:8.12.2": "@typescript-eslint/types@npm:8.13.0":
version: 8.12.2 version: 8.13.0
resolution: "@typescript-eslint/types@npm:8.12.2" resolution: "@typescript-eslint/types@npm:8.13.0"
checksum: 10c0/7fdc26b349a4f0faa9e80683d425fe7a5761a50c76f2fad6ebdf30f1ef75443c06c158e17b2a529f70fc6d56560a130b4e59038b6e2f583c8cb54c1d0ab9cf73 checksum: 10c0/bd3f88b738a92b2222f388bcf831357ef8940a763c2c2eb1947767e1051dd2f8bee387020e8cf4c2309e4142353961b659abc2885e30679109a0488b0bfefc23
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/typescript-estree@npm:8.12.2": "@typescript-eslint/typescript-estree@npm:8.13.0":
version: 8.12.2 version: 8.13.0
resolution: "@typescript-eslint/typescript-estree@npm:8.12.2" resolution: "@typescript-eslint/typescript-estree@npm:8.13.0"
dependencies: dependencies:
"@typescript-eslint/types": "npm:8.12.2" "@typescript-eslint/types": "npm:8.13.0"
"@typescript-eslint/visitor-keys": "npm:8.12.2" "@typescript-eslint/visitor-keys": "npm:8.13.0"
debug: "npm:^4.3.4" debug: "npm:^4.3.4"
fast-glob: "npm:^3.3.2" fast-glob: "npm:^3.3.2"
is-glob: "npm:^4.0.3" is-glob: "npm:^4.0.3"
@@ -1627,31 +1627,31 @@ __metadata:
peerDependenciesMeta: peerDependenciesMeta:
typescript: typescript:
optional: true optional: true
checksum: 10c0/133db215be60c64bf9fb20d678aaf258b31d752380492474228946ba04f540210b371217414f56c37e61b04d77a451085c421ac9a19aca818b07ac67b7139b86 checksum: 10c0/2d45bc5ed4ac352bea927167ac28ef23bd13b6ae352ff50e85cddfdc4b06518f1dd4ae5f2495e30d6f62d247987677a4e807065d55829ba28963908a821dc96d
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/utils@npm:8.12.2": "@typescript-eslint/utils@npm:8.13.0":
version: 8.12.2 version: 8.13.0
resolution: "@typescript-eslint/utils@npm:8.12.2" resolution: "@typescript-eslint/utils@npm:8.13.0"
dependencies: dependencies:
"@eslint-community/eslint-utils": "npm:^4.4.0" "@eslint-community/eslint-utils": "npm:^4.4.0"
"@typescript-eslint/scope-manager": "npm:8.12.2" "@typescript-eslint/scope-manager": "npm:8.13.0"
"@typescript-eslint/types": "npm:8.12.2" "@typescript-eslint/types": "npm:8.13.0"
"@typescript-eslint/typescript-estree": "npm:8.12.2" "@typescript-eslint/typescript-estree": "npm:8.13.0"
peerDependencies: peerDependencies:
eslint: ^8.57.0 || ^9.0.0 eslint: ^8.57.0 || ^9.0.0
checksum: 10c0/c050637aca88e8a5a09c2cee20d667ee3dbf1efa5488a11eca14069b320447419db3f8a42b7d3598d9acaad3a109cb6017d0e32d782255641721a41e95b2be2f checksum: 10c0/3fc5a7184a949df5f5b64f6af039a1d21ef7fe15f3d88a5d485ccbb535746d18514751143993a5aee287228151be3e326baf8f899a0a0a93368f6f20857ffa6d
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/visitor-keys@npm:8.12.2": "@typescript-eslint/visitor-keys@npm:8.13.0":
version: 8.12.2 version: 8.13.0
resolution: "@typescript-eslint/visitor-keys@npm:8.12.2" resolution: "@typescript-eslint/visitor-keys@npm:8.13.0"
dependencies: dependencies:
"@typescript-eslint/types": "npm:8.12.2" "@typescript-eslint/types": "npm:8.13.0"
eslint-visitor-keys: "npm:^3.4.3" eslint-visitor-keys: "npm:^3.4.3"
checksum: 10c0/1f770d361bcb03ed028e5589824f6c7ba364da59fe8b982c2fed0878ad25890d80ebd6c72618ab5149317501964b7db106e20834179d4aa707a8cbffcca89d08 checksum: 10c0/50b35f3cf673aaed940613f0007f7c4558a89ebef15c49824e65b6f084b700fbf01b01a4e701e24bbe651297a39678645e739acd255255f1603867a84bef0383
languageName: node languageName: node
linkType: hard linkType: hard
@@ -1671,13 +1671,13 @@ __metadata:
"@table-library/react-table-library": "npm:4.1.7" "@table-library/react-table-library": "npm:4.1.7"
"@trivago/prettier-plugin-sort-imports": "npm:^4.3.0" "@trivago/prettier-plugin-sort-imports": "npm:^4.3.0"
"@types/formidable": "npm:^3" "@types/formidable": "npm:^3"
"@types/node": "npm:^22.8.7" "@types/node": "npm:^22.9.0"
"@types/react": "npm:^18.3.12" "@types/react": "npm:^18.3.12"
"@types/react-dom": "npm:^18.3.1" "@types/react-dom": "npm:^18.3.1"
"@types/react-router-dom": "npm:^5.3.3" "@types/react-router-dom": "npm:^5.3.3"
alova: "npm:3.2.1" alova: "npm:3.2.2"
async-validator: "npm:^4.2.5" async-validator: "npm:^4.2.5"
concurrently: "npm:^9.0.1" concurrently: "npm:^9.1.0"
eslint: "npm:^9.14.0" eslint: "npm:^9.14.0"
eslint-config-prettier: "npm:^9.1.0" eslint-config-prettier: "npm:^9.1.0"
formidable: "npm:^3.5.2" formidable: "npm:^3.5.2"
@@ -1688,16 +1688,16 @@ __metadata:
react: "npm:^18.3.1" react: "npm:^18.3.1"
react-dom: "npm:^18.3.1" react-dom: "npm:^18.3.1"
react-icons: "npm:^5.3.0" react-icons: "npm:^5.3.0"
react-router-dom: "npm:^6.27.0" react-router-dom: "npm:^6.28.0"
react-toastify: "npm:^10.0.6" react-toastify: "npm:^10.0.6"
rollup-plugin-visualizer: "npm:^5.12.0" rollup-plugin-visualizer: "npm:^5.12.0"
terser: "npm:^5.36.0" terser: "npm:^5.36.0"
typesafe-i18n: "npm:^5.26.2" typesafe-i18n: "npm:^5.26.2"
typescript: "npm:^5.6.3" typescript: "npm:^5.6.3"
typescript-eslint: "npm:8.12.2" typescript-eslint: "npm:8.13.0"
vite: "npm:^5.4.10" vite: "npm:^5.4.10"
vite-plugin-imagemin: "npm:^0.6.1" vite-plugin-imagemin: "npm:^0.6.1"
vite-tsconfig-paths: "npm:^5.0.1" vite-tsconfig-paths: "npm:^5.1.0"
languageName: unknown languageName: unknown
linkType: soft linkType: soft
@@ -1766,13 +1766,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"alova@npm:3.2.1": "alova@npm:3.2.2":
version: 3.2.1 version: 3.2.2
resolution: "alova@npm:3.2.1" resolution: "alova@npm:3.2.2"
dependencies: dependencies:
"@alova/shared": "npm:1.1.0" "@alova/shared": "npm:1.1.0"
rate-limiter-flexible: "npm:^5.0.3" rate-limiter-flexible: "npm:^5.0.3"
checksum: 10c0/9b15b1894a505bd15bf8fa67352addd72ebddf0b0134b5f96ba6c806e25afdfb565e53931d4ac12900559b9b4778557277350ddc37b8ff87e72030d9d84feddc checksum: 10c0/e01f827fd07e4e532b6d82fcd9e2ce6fe2866704f5e895085c7de63b00a9caaa2cf1dbf8537292d840a5f1903974f2e7296c16b0beda0bd375d1bdd68c17297e
languageName: node languageName: node
linkType: hard linkType: hard
@@ -2256,9 +2256,9 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"concurrently@npm:^9.0.1": "concurrently@npm:^9.1.0":
version: 9.0.1 version: 9.1.0
resolution: "concurrently@npm:9.0.1" resolution: "concurrently@npm:9.1.0"
dependencies: dependencies:
chalk: "npm:^4.1.2" chalk: "npm:^4.1.2"
lodash: "npm:^4.17.21" lodash: "npm:^4.17.21"
@@ -2270,7 +2270,7 @@ __metadata:
bin: bin:
conc: dist/bin/concurrently.js conc: dist/bin/concurrently.js
concurrently: dist/bin/concurrently.js concurrently: dist/bin/concurrently.js
checksum: 10c0/e2c3d3f3d1b1457ccd27e69f0d840ba4915d571fae4e1088498234ec1174fd547c127de0df6dbe5eb71b2df973b26a6fdc931a9e7e3658f25287ef2106bdb413 checksum: 10c0/f2f42f94dde508bfbaf47b5ac654db9e8a4bf07d3d7b6267dd058ae6f362eec677ae7c8ede398d081e5fd0d1de5811dc9a53e57d3f1f68e72ac6459db9e0896b
languageName: node languageName: node
linkType: hard linkType: hard
@@ -5750,27 +5750,27 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"react-router-dom@npm:^6.27.0": "react-router-dom@npm:^6.28.0":
version: 6.27.0 version: 6.28.0
resolution: "react-router-dom@npm:6.27.0" resolution: "react-router-dom@npm:6.28.0"
dependencies: dependencies:
"@remix-run/router": "npm:1.20.0" "@remix-run/router": "npm:1.21.0"
react-router: "npm:6.27.0" react-router: "npm:6.28.0"
peerDependencies: peerDependencies:
react: ">=16.8" react: ">=16.8"
react-dom: ">=16.8" react-dom: ">=16.8"
checksum: 10c0/7db48ffd0b387af0eed060ceaf42075d074e63fbd30f4cf60993526b3610883a9ff82615965001165ed69d2bf2f1bce05c594a21c8d0d845e7b9bf203201116e checksum: 10c0/e2930cf83e8c843a932b008c7ce11059fd83390502a433f0e41f192e3cb80081a621d069eeda7af3cf4bf74d7f8029f0141cdce741bca3f0af82d4bbbc7f7f10
languageName: node languageName: node
linkType: hard linkType: hard
"react-router@npm:6.27.0": "react-router@npm:6.28.0":
version: 6.27.0 version: 6.28.0
resolution: "react-router@npm:6.27.0" resolution: "react-router@npm:6.28.0"
dependencies: dependencies:
"@remix-run/router": "npm:1.20.0" "@remix-run/router": "npm:1.21.0"
peerDependencies: peerDependencies:
react: ">=16.8" react: ">=16.8"
checksum: 10c0/440d6ee00890cec92a0c2183164149fbb96363efccf52bb132a964f44e51aec2f4b5a0520c67f6f17faddaa4097090fd76f7efe58263947532fceeb11dd4cdf3 checksum: 10c0/b435510de78fd882bf6ca9800a73cd90cee418bd1d19efd91b8dcaebde36929bbb589e25d9f7eec24ceb84255e8d538bc1fe54e6ddb5c43c32798e2b720fa76d
languageName: node languageName: node
linkType: hard linkType: hard
@@ -6771,17 +6771,17 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"typescript-eslint@npm:8.12.2": "typescript-eslint@npm:8.13.0":
version: 8.12.2 version: 8.13.0
resolution: "typescript-eslint@npm:8.12.2" resolution: "typescript-eslint@npm:8.13.0"
dependencies: dependencies:
"@typescript-eslint/eslint-plugin": "npm:8.12.2" "@typescript-eslint/eslint-plugin": "npm:8.13.0"
"@typescript-eslint/parser": "npm:8.12.2" "@typescript-eslint/parser": "npm:8.13.0"
"@typescript-eslint/utils": "npm:8.12.2" "@typescript-eslint/utils": "npm:8.13.0"
peerDependenciesMeta: peerDependenciesMeta:
typescript: typescript:
optional: true optional: true
checksum: 10c0/8a80916204da1a056fa3776d7c69d3d21b9a242d8d2bea75ca32b25d86a0c0e28711fb185605024e463b311e582f693166950d6fe0f66f0969603214e190cbcc checksum: 10c0/a84958e7602360c4cb2e6227fd9aae19dd18cdf1a2cfd9ece2a81d54098f80454b5707e861e98547d0b2e5dae552b136aa6733b74f0dd743ca7bfe178083c441
languageName: node languageName: node
linkType: hard linkType: hard
@@ -6954,9 +6954,9 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"vite-tsconfig-paths@npm:^5.0.1": "vite-tsconfig-paths@npm:^5.1.0":
version: 5.0.1 version: 5.1.0
resolution: "vite-tsconfig-paths@npm:5.0.1" resolution: "vite-tsconfig-paths@npm:5.1.0"
dependencies: dependencies:
debug: "npm:^4.1.1" debug: "npm:^4.1.1"
globrex: "npm:^0.1.2" globrex: "npm:^0.1.2"
@@ -6966,7 +6966,7 @@ __metadata:
peerDependenciesMeta: peerDependenciesMeta:
vite: vite:
optional: true optional: true
checksum: 10c0/3c68a4d5df21ed4ef81749c20e91c5978989ed06bffc01688b3f1a0fe65951b461a68f0c017ad930a088cfe7a8cc04d0c8d955dfb8719d5edc7fb0ba9bf38a73 checksum: 10c0/fff3fc7ada55aa4cfd6cad5c6006a8eaf74df0cc1ed5e9282c0c479012c57095d391379cb1742c394711cbb3ee591c66e27838779d8388297bdf033aa6e57719
languageName: node languageName: node
linkType: hard linkType: hard

View File

@@ -22,10 +22,10 @@ const router = AutoRouter({
const REST_ENDPOINT_ROOT = '/rest/'; const REST_ENDPOINT_ROOT = '/rest/';
const API_ENDPOINT_ROOT = '/api/'; const API_ENDPOINT_ROOT = '/api/';
// HTTP HEADERS // HTTP HEADERS for msgpack
const headers = { const headers = {
'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Origin': '*',
'Content-type': 'application/json' 'Content-type': 'application/msgpack'
}; };
// GLOBAL VARIABLES // GLOBAL VARIABLES

View File

@@ -1363,4 +1363,6 @@ heattransfer
poolshunt poolshunt
poolshuntstatus poolshuntstatus
pooltemp pooltemp
stoptime stoptime
showertimer
showeralert

View File

@@ -533,7 +533,7 @@ void AnalogSensor::publish_values(const bool force) {
char val_obj[50]; char val_obj[50];
char val_cond[95]; char val_cond[95];
if (Mqtt::is_nested()) { if (Mqtt::is_nested()) {
snprintf(val_obj, sizeof(val_obj), "value_json['%02d'].value", sensor.gpio()); // TODO change for Domoticz snprintf(val_obj, sizeof(val_obj), "value_json['%02d']['value']", sensor.gpio());
snprintf(val_cond, sizeof(val_cond), "value_json['%02d'] is defined and %s is defined", sensor.gpio(), val_obj); snprintf(val_cond, sizeof(val_cond), "value_json['%02d'] is defined and %s is defined", sensor.gpio(), val_obj);
} else { } else {
snprintf(val_obj, sizeof(val_obj), "value_json['%s']", sensor.name().c_str()); snprintf(val_obj, sizeof(val_obj), "value_json['%s']", sensor.name().c_str());

View File

@@ -379,17 +379,6 @@ uint8_t Command::call(const uint8_t device_type, const char * command, const cha
return CommandRet::NOT_ALLOWED; // command not allowed return CommandRet::NOT_ALLOWED; // command not allowed
} }
// build up the log string for reporting back
// We send the log message as Warning so it appears in the log (debug is only enabled when compiling with DEBUG)
std::string ro = EMSESP::system_.readonly_mode() ? "[readonly] " : "";
auto description = Helpers::translated_word(cf->description_);
char info_s[100];
if (strlen(description)) {
snprintf(info_s, sizeof(info_s), "%s/%s (%s)", dname, cmd, description);
} else {
snprintf(info_s, sizeof(info_s), "%s/%s", dname, cmd);
}
// call the function based on command function type // call the function based on command function type
// commands return true or false only (bool) // commands return true or false only (bool)
uint8_t return_code = CommandRet::OK; uint8_t return_code = CommandRet::OK;
@@ -406,7 +395,7 @@ uint8_t Command::call(const uint8_t device_type, const char * command, const cha
} }
} }
// report back. If not OK show output from error, otherwise return the HTTP code // report back. If not OK show output from error, otherwise return the error code
if (return_code != CommandRet::OK) { if (return_code != CommandRet::OK) {
char error[100]; char error[100];
if (single_command) { if (single_command) {
@@ -418,6 +407,16 @@ uint8_t Command::call(const uint8_t device_type, const char * command, const cha
output["message"] = error; output["message"] = error;
LOG_WARNING(error); LOG_WARNING(error);
} else { } else {
// build up the log string for reporting back
// We send the log message as Warning so it appears in the log (debug is only enabled when compiling with DEBUG)
std::string ro = EMSESP::system_.readonly_mode() ? "[readonly] " : "";
auto description = Helpers::translated_word(cf->description_);
char info_s[100];
if (strlen(description)) {
snprintf(info_s, sizeof(info_s), "%s/%s (%s)", dname, cmd, description);
} else {
snprintf(info_s, sizeof(info_s), "%s/%s", dname, cmd);
}
if (single_command) { if (single_command) {
// log as DEBUG (TRACE) regardless if compiled with EMSESP_DEBUG // log as DEBUG (TRACE) regardless if compiled with EMSESP_DEBUG
logger_.debug("%sCalled command %s", ro.c_str(), info_s); logger_.debug("%sCalled command %s", ro.c_str(), info_s);

View File

@@ -52,11 +52,16 @@ using string_vector = std::vector<const char *>;
#define F_(string_name) (__pstr__##string_name) #define F_(string_name) (__pstr__##string_name)
#define FL_(list_name) (__pstr__L_##list_name) #define FL_(list_name) (__pstr__L_##list_name)
#if defined(EMSESP_TEST) || defined(EMSESP_EN_ONLY) #if defined(EMSESP_TEST)
// In testing just take one language (en) to save on Flash space // in Test mode use two languages (en & de) to save flash memory needed for the tests
#define MAKE_WORD_TRANSLATION(list_name, en, de, ...) static const char * const __pstr__L_##list_name[] = {de, nullptr};
#define MAKE_TRANSLATION(list_name, shortname, en, de, ...) static const char * const __pstr__L_##list_name[] = {shortname, de, nullptr};
#elif defined(EMSESP_EN_ONLY)
// EN only
#define MAKE_WORD_TRANSLATION(list_name, en, ...) static const char * const __pstr__L_##list_name[] = {en, nullptr}; #define MAKE_WORD_TRANSLATION(list_name, en, ...) static const char * const __pstr__L_##list_name[] = {en, nullptr};
#define MAKE_TRANSLATION(list_name, shortname, en, ...) static const char * const __pstr__L_##list_name[] = {shortname, en, nullptr}; #define MAKE_TRANSLATION(list_name, shortname, en, ...) static const char * const __pstr__L_##list_name[] = {shortname, en, nullptr};
#elif defined(EMSESP_DE_ONLY) #elif defined(EMSESP_DE_ONLY)
// EN + DE
#define MAKE_WORD_TRANSLATION(list_name, en, de, ...) static const char * const __pstr__L_##list_name[] = {de, nullptr}; #define MAKE_WORD_TRANSLATION(list_name, en, de, ...) static const char * const __pstr__L_##list_name[] = {de, nullptr};
#define MAKE_TRANSLATION(list_name, shortname, en, de, ...) static const char * const __pstr__L_##list_name[] = {shortname, de, nullptr}; #define MAKE_TRANSLATION(list_name, shortname, en, de, ...) static const char * const __pstr__L_##list_name[] = {shortname, de, nullptr};
#else #else

View File

@@ -4912,7 +4912,7 @@ void Thermostat::register_device_values_dhw(std::shared_ptr<Thermostat::DhwCircu
DeviceValueUOM::MINUTES, DeviceValueUOM::MINUTES,
MAKE_CF_CB(set_wwchargeduration)); MAKE_CF_CB(set_wwchargeduration));
register_device_value(tag, &dhw->wwCharge_, DeviceValueType::BOOL, FL_(wwCharge), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcharge)); register_device_value(tag, &dhw->wwCharge_, DeviceValueType::BOOL, FL_(wwCharge), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcharge));
register_device_value(tag, &dhw->wwExtra_, DeviceValueType::UINT8, FL_(wwExtra), DeviceValueUOM::DEGREES); register_device_value(tag, &dhw->wwExtra_, DeviceValueType::BOOL, FL_(wwExtra), DeviceValueUOM::NONE);
register_device_value(tag, &dhw->wwDisinfecting_, DeviceValueType::BOOL, FL_(wwDisinfecting), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfect)); register_device_value(tag, &dhw->wwDisinfecting_, DeviceValueType::BOOL, FL_(wwDisinfecting), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfect));
register_device_value( register_device_value(
tag, &dhw->wwDisinfectDay_, DeviceValueType::ENUM, FL_(enum_dayOfWeek), FL_(wwDisinfectDay), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfectDay)); tag, &dhw->wwDisinfectDay_, DeviceValueType::ENUM, FL_(enum_dayOfWeek), FL_(wwDisinfectDay), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwDisinfectDay));

View File

@@ -910,14 +910,14 @@ std::string EMSESP::pretty_telegram(std::shared_ptr<const Telegram> telegram) {
std::string str; std::string str;
str.reserve(200); str.reserve(200);
if (telegram->operation == Telegram::Operation::RX_READ) { if (telegram->operation == Telegram::Operation::RX_READ) {
str = src_name + "(" + Helpers::hextoa(src) + ") -R-> " + dest_name + "(" + Helpers::hextoa(dest) + "), " + type_name + "(" str = src_name + "(" + Helpers::hextoa(src) + ") -> " + dest_name + "(" + Helpers::hextoa(dest) + "), R, " + type_name + "("
+ Helpers::hextoa(telegram->type_id) + "), length: " + Helpers::itoa(telegram->message_data[0]) + Helpers::hextoa(telegram->type_id) + "), length: " + Helpers::itoa(telegram->message_data[0])
+ ((telegram->message_length > 1) ? ", data: " + Helpers::data_to_hex(telegram->message_data + 1, telegram->message_length - 1) : ""); + ((telegram->message_length > 1) ? ", data: " + Helpers::data_to_hex(telegram->message_data + 1, telegram->message_length - 1) : "");
} else if (telegram->dest == 0) { } else if (telegram->dest == 0) {
str = src_name + "(" + Helpers::hextoa(src) + ") -B-> " + dest_name + "(" + Helpers::hextoa(dest) + "), " + type_name + "(" str = src_name + "(" + Helpers::hextoa(src) + ") -> " + dest_name + "(" + Helpers::hextoa(dest) + "), B, " + type_name + "("
+ Helpers::hextoa(telegram->type_id) + "), data: " + telegram->to_string_message(); + Helpers::hextoa(telegram->type_id) + "), data: " + telegram->to_string_message();
} else { } else {
str = src_name + "(" + Helpers::hextoa(src) + ") -W-> " + dest_name + "(" + Helpers::hextoa(dest) + "), " + type_name + "(" str = src_name + "(" + Helpers::hextoa(src) + ") -> " + dest_name + "(" + Helpers::hextoa(dest) + "), W, " + type_name + "("
+ Helpers::hextoa(telegram->type_id) + "), data: " + telegram->to_string_message(); + Helpers::hextoa(telegram->type_id) + "), data: " + telegram->to_string_message();
} }
@@ -1016,13 +1016,14 @@ void EMSESP::process_version(std::shared_ptr<const Telegram> telegram) {
// some devices store the protocol type (HT3, Buderus) in the last byte // some devices store the protocol type (HT3, Buderus) in the last byte
uint8_t brand; uint8_t brand;
if (telegram->message_length >= 10) { if (telegram->message_length >= 10) {
brand = EMSdevice::decode_brand(telegram->message_data[9]); // TODO should be offset + 9? brand = EMSdevice::decode_brand(telegram->message_data[9]);
} else { } else {
brand = EMSdevice::Brand::NO_BRAND; // unknown brand = EMSdevice::Brand::NO_BRAND; // unknown
} }
// add it - will be overwritten if device already exists // add it - will be overwritten if device already exists
(void)add_device(device_id, product_id, version, brand); (void)add_device(device_id, product_id, version, brand);
// request the deviceName from telegram 0x01 // request the deviceName from telegram 0x01
send_read_request(EMSdevice::EMS_TYPE_NAME, device_id, 27); send_read_request(EMSdevice::EMS_TYPE_NAME, device_id, 27);
} }

View File

@@ -603,6 +603,10 @@ bool Helpers::value2bool(const char * value, bool & value_b) {
return true; // is a bool return true; // is a bool
} }
#ifdef EMSESP_STANDALONE
emsesp::EMSESP::logger().debug("Error. value2bool: %s is not a boolean", value);
#endif
return false; // not a bool return false; // not a bool
} }
@@ -764,7 +768,7 @@ uint8_t Helpers::count_items(const char * const ** list) {
// if force_en is true always take the EN non-translated word // if force_en is true always take the EN non-translated word
const char * Helpers::translated_word(const char * const * strings, const bool force_en) { const char * Helpers::translated_word(const char * const * strings, const bool force_en) {
uint8_t language_index = EMSESP::system_.language_index(); uint8_t language_index = EMSESP::system_.language_index();
uint8_t index = 0; uint8_t index = 0; // default en
if (!strings) { if (!strings) {
return ""; // no translations return ""; // no translations
@@ -774,6 +778,7 @@ const char * Helpers::translated_word(const char * const * strings, const bool f
if (!force_en && (Helpers::count_items(strings) >= language_index + 1 && strlen(strings[language_index]))) { if (!force_en && (Helpers::count_items(strings) >= language_index + 1 && strlen(strings[language_index]))) {
index = language_index; index = language_index;
} }
return strings[index]; return strings[index];
} }

View File

@@ -934,14 +934,13 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
char config_topic[70]; char config_topic[70];
snprintf(config_topic, sizeof(config_topic), "%s/%s_%s/config", mqtt_basename_.c_str(), device_name, entity_with_tag); snprintf(config_topic, sizeof(config_topic), "%s/%s_%s/config", mqtt_basename_.c_str(), device_name, entity_with_tag);
bool add_ha_classes = true; // default we'll add the "unit_of_meas", "stat_cla" and "dev_cla" attributes
// create the topic // create the topic
// depending on the type and whether the device entity is writable (a command) // depending on the type and whether the device entity is writable (i.e. a command)
// https://developers.home-assistant.io/docs/core/entity // https://developers.home-assistant.io/docs/core/entity
char topic[MQTT_TOPIC_MAX_SIZE]; char topic[MQTT_TOPIC_MAX_SIZE];
// if it's a command then we can use Number, Switch, Select or Text. Otherwise stick to Sensor topic[0] = '\0'; // nullify, making it empty
if (has_cmd) { if (has_cmd) {
// if it's a command then we can use Number, Switch, Select or Text. Otherwise stick to Sensor
switch (type) { switch (type) {
case DeviceValueType::INT8: case DeviceValueType::INT8:
case DeviceValueType::UINT8: case DeviceValueType::UINT8:
@@ -950,45 +949,40 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
case DeviceValueType::UINT24: case DeviceValueType::UINT24:
case DeviceValueType::UINT32: case DeviceValueType::UINT32:
// number - https://www.home-assistant.io/integrations/number.mqtt // number - https://www.home-assistant.io/integrations/number.mqtt
// older Domoticz does not support number, use sensor // older Domoticz does not support number, will default to Sensor
if (discovery_type() == discoveryType::HOMEASSISTANT || discovery_type() == discoveryType::DOMOTICZ_LATEST) { if (discovery_type() == discoveryType::HOMEASSISTANT || discovery_type() == discoveryType::DOMOTICZ_LATEST) {
snprintf(topic, sizeof(topic), "number/%s", config_topic); snprintf(topic, sizeof(topic), "number/%s", config_topic);
} else {
snprintf(topic, sizeof(topic), "sensor/%s", config_topic);
} }
break; break;
case DeviceValueType::BOOL: case DeviceValueType::BOOL:
// switch - https://www.home-assistant.io/integrations/switch.mqtt // switch - https://www.home-assistant.io/integrations/switch.mqtt
snprintf(topic, sizeof(topic), "switch/%s", config_topic); snprintf(topic, sizeof(topic), "switch/%s", config_topic);
add_ha_classes = false;
break; break;
case DeviceValueType::ENUM: case DeviceValueType::ENUM:
snprintf(topic, sizeof(topic), "select/%s", config_topic);
add_ha_classes = false;
break;
case DeviceValueType::CMD: // hardcoded commands are always ENUMS
// select - https://www.home-assistant.io/integrations/select.mqtt // select - https://www.home-assistant.io/integrations/select.mqtt
snprintf(topic, sizeof(topic), "select/%s", config_topic);
break;
case DeviceValueType::CMD:
if (uom == DeviceValueUOM::NONE) { if (uom == DeviceValueUOM::NONE) {
snprintf(topic, sizeof(topic), "select/%s", config_topic); snprintf(topic, sizeof(topic), "select/%s", config_topic); // hardcoded commands are always ENUMS
} else if (discovery_type() == discoveryType::HOMEASSISTANT || discovery_type() == discoveryType::DOMOTICZ_LATEST) { } else if (discovery_type() == discoveryType::HOMEASSISTANT || discovery_type() == discoveryType::DOMOTICZ_LATEST) {
snprintf(topic, sizeof(topic), "number/%s", config_topic); snprintf(topic, sizeof(topic), "number/%s", config_topic);
} else {
snprintf(topic, sizeof(topic), "sensor/%s", config_topic);
} }
add_ha_classes = false;
break; break;
case DeviceValueType::STRING: case DeviceValueType::STRING:
// text - https://www.home-assistant.io/integrations/text.mqtt // text - https://www.home-assistant.io/integrations/text.mqtt
snprintf(topic, sizeof(topic), "text/%s", config_topic); // e.g. set_datetime, set_holiday, set_wwswitchtime // Domoticz does not support text, will default to Sensor
add_ha_classes = false; if (discovery_type() == discoveryType::HOMEASSISTANT) {
snprintf(topic, sizeof(topic), "text/%s", config_topic); // e.g. set_datetime, set_holiday, set_wwswitchtime
}
break; break;
default: default:
// plain old sensor
snprintf(topic, sizeof(topic), "sensor/%s", config_topic);
break; break;
} }
} else { }
// it is not a command and a read-only sensor. Use then either sensor or binary_sensor
// if at this point we don't have a topic created yet, create a default sensor one. We always need a topic.
if (!strnlen(topic, sizeof(topic))) {
snprintf(topic, sizeof(topic), (type == DeviceValueType::BOOL) ? "binary_sensor/%s" : "sensor/%s", config_topic); // binary sensor (for booleans) snprintf(topic, sizeof(topic), (type == DeviceValueType::BOOL) ? "binary_sensor/%s" : "sensor/%s", config_topic); // binary sensor (for booleans)
} }
@@ -1054,21 +1048,6 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
doc["max"] = dv_set_max; doc["max"] = dv_set_max;
snprintf(sample_val, sizeof(sample_val), "%i", dv_set_min); snprintf(sample_val, sizeof(sample_val), "%i", dv_set_min);
} }
// set icons
// since these don't have a device class we need to add the icon ourselves
switch (uom) {
case DeviceValueUOM::DEGREES:
case DeviceValueUOM::DEGREES_R:
case DeviceValueUOM::K:
doc["ic"] = F_(icondegrees);
break;
case DeviceValueUOM::PERCENT:
doc["ic"] = F_(iconpercent);
break;
default:
break;
}
} }
// friendly name = <tag> <name> // friendly name = <tag> <name>
@@ -1129,26 +1108,23 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
// Domoticz doesn't support value templates, so we just use the value directly // Domoticz doesn't support value templates, so we just use the value directly
// Also omit the uom and other state classes // Also omit the uom and other state classes
doc["val_tpl"] = (std::string) "{{" + val_obj + "}}"; doc["val_tpl"] = (std::string) "{{" + val_obj + "}}";
// add_ha_classes = false; // don't add the classes, categories of uom (dev_cla, stat_cla)
} }
} }
// Add the state class, device class and sometimes the icon. // Add the state class, device class and an optional icon based on the uom
// Used only for read-only sensors like Sensor and Binary Sensor but also Numbers // first set the catagory for System entities
if (add_ha_classes) { // https://github.com/emsesp/EMS-ESP32/discussions/1459#discussioncomment-7694873
// first set the catagory for System entities if (device_type == EMSdevice::DeviceType::SYSTEM) {
// https://github.com/emsesp/EMS-ESP32/discussions/1459#discussioncomment-7694873 doc["ent_cat"] = "diagnostic"; // instead of config
if (device_type == EMSdevice::DeviceType::SYSTEM) {
doc["ent_cat"] = "diagnostic";
}
add_ha_uom(doc.as<JsonObject>(), type, uom, entity); // add the UoM, device and state class
} }
add_ha_uom(doc.as<JsonObject>(), type, uom, entity);
doc["dev"] = dev_json; doc["dev"] = dev_json;
return queue_ha(topic, doc.as<JsonObject>()); return queue_ha(topic, doc.as<JsonObject>());
} }
// Add the state class, device class and an optional icon based on the uom
void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, const char * entity) { void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, const char * entity) {
const char * dc_ha = "dev_cla"; // device class const char * dc_ha = "dev_cla"; // device class
const char * sc_ha = "stat_cla"; // state class const char * sc_ha = "stat_cla"; // state class
@@ -1169,16 +1145,19 @@ void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, con
} }
// set state and device class // set state and device class
// also icon, when there is no device class that sets one
switch (uom) { switch (uom) {
case DeviceValueUOM::DEGREES: case DeviceValueUOM::DEGREES:
case DeviceValueUOM::DEGREES_R: case DeviceValueUOM::DEGREES_R:
case DeviceValueUOM::K: case DeviceValueUOM::K:
doc[sc_ha] = F_(measurement); doc[sc_ha] = F_(measurement);
doc[dc_ha] = "temperature"; doc[dc_ha] = "temperature";
doc["ic"] = F_(icondegrees); // icon
break; break;
case DeviceValueUOM::PERCENT: case DeviceValueUOM::PERCENT:
doc[sc_ha] = F_(measurement); doc[sc_ha] = F_(measurement);
doc[dc_ha] = "power_factor"; doc[dc_ha] = "power_factor";
doc["ic"] = F_(iconpercent); // icon
break; break;
case DeviceValueUOM::SECONDS: case DeviceValueUOM::SECONDS:
case DeviceValueUOM::MINUTES: case DeviceValueUOM::MINUTES:
@@ -1256,8 +1235,6 @@ void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, con
} }
bool Mqtt::publish_ha_climate_config(const int8_t tag, const bool has_roomtemp, const bool remove, const int16_t min, const uint32_t max) { bool Mqtt::publish_ha_climate_config(const int8_t tag, const bool has_roomtemp, const bool remove, const int16_t min, const uint32_t max) {
// TODO: check if Domoticz supports climate via MQTT discovery, otherwise exit this function if (discovery_type() != discoveryType::HOMEASSISTANT
uint8_t hc_num = tag; uint8_t hc_num = tag;
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE]; char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];

View File

@@ -52,12 +52,17 @@
namespace emsesp { namespace emsesp {
// Languages supported. Note: the order is important and must match locale_translations.h // Languages supported. Note: the order is important
#if defined(EMSESP_TEST) || defined(EMSESP_EN_ONLY) // and must match locale_translations.h and common.h
// in Debug mode use one language (en) to save flash memory needed for the tests #if defined(EMSESP_TEST)
// in Test mode use two languages (en & de) to save flash memory needed for the tests
const char * const languages[] = {EMSESP_LOCALE_EN, EMSESP_LOCALE_DE};
#elif defined(EMSESP_EN_ONLY)
// EN only
const char * const languages[] = {EMSESP_LOCALE_EN}; const char * const languages[] = {EMSESP_LOCALE_EN};
#elif defined(EMSESP_DE_ONLY) #elif defined(EMSESP_DE_ONLY)
const char * const languages[] = {EMSESP_LOCALE_DE}; // EN + DE
const char * const languages[] = {EMSESP_LOCALE_EN, EMSESP_LOCALE_DE};
#else #else
const char * const languages[] = {EMSESP_LOCALE_EN, const char * const languages[] = {EMSESP_LOCALE_EN,
EMSESP_LOCALE_DE, EMSESP_LOCALE_DE,
@@ -92,7 +97,7 @@ uint8_t System::language_index() {
return i; return i;
} }
} }
return 0; // EN return 0; // EN only
} }
// send raw to ems // send raw to ems

View File

@@ -482,7 +482,7 @@ void TemperatureSensor::publish_values(const bool force) {
char val_obj[70]; char val_obj[70];
char val_cond[170]; char val_cond[170];
if (Mqtt::is_nested()) { if (Mqtt::is_nested()) {
snprintf(val_obj, sizeof(val_obj), "value_json['%s'].temp", sensor.id().c_str()); // TODO change for Domoticz snprintf(val_obj, sizeof(val_obj), "value_json['%s']['temp']", sensor.id().c_str());
snprintf(val_cond, sizeof(val_cond), "value_json['%s'] is defined and %s is defined", sensor.id().c_str(), val_obj); snprintf(val_cond, sizeof(val_cond), "value_json['%s'] is defined and %s is defined", sensor.id().c_str(), val_obj);
} else { } else {
snprintf(val_obj, sizeof(val_obj), "value_json['%s']", sensor.name().c_str()); snprintf(val_obj, sizeof(val_obj), "value_json['%s']", sensor.name().c_str());

View File

@@ -307,7 +307,15 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
} }
shell.printfln("Testing Adding a device (product_id %d), with all values...", id2); shell.printfln("Testing Adding a device (product_id %d), with all values...", id2);
test("add", id1, id2); test("add", id1, id2);
shell.invoke_command("show values"); shell.invoke_command("show devices");
ok = true;
}
// set the language
if (command == "locale") {
shell.printfln("Testing setting locale to %s", id1_s.c_str());
EMSESP::system_.locale(id1_s.c_str());
shell.invoke_command("show");
ok = true; ok = true;
} }

View File

@@ -1 +1 @@
#define EMSESP_APP_VERSION "3.7.1-dev.3" #define EMSESP_APP_VERSION "3.7.1-dev.4"