mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-09 09:19:51 +03:00
Merge remote-tracking branch 'origin/dev'
This commit is contained in:
2
.github/workflows/sonar_check.yml
vendored
2
.github/workflows/sonar_check.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
# if: github.repository_owner == 'emsesp'
|
||||
# if: github.repository == 'emsesp/EMS-ESP32'
|
||||
env:
|
||||
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory
|
||||
BUILD_WRAPPER_OUT_DIR: bw-output
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -53,8 +53,9 @@ interface/src/i18n/i18n-util.async.ts
|
||||
# sonar
|
||||
.scannerwork/
|
||||
sonar/
|
||||
build_wrapper_output_directory/
|
||||
bw-output/
|
||||
|
||||
# entity dump results
|
||||
# dump_entities.csv
|
||||
# dump_entities.xls*
|
||||
|
||||
|
||||
14
CHANGELOG.md
14
CHANGELOG.md
@@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
# [3.6.1] September 9 2023
|
||||
## [3.6.1] September 9 2023
|
||||
|
||||
## **IMPORTANT! BREAKING CHANGES**
|
||||
|
||||
@@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## Added
|
||||
|
||||
- show WiFi rssi in Network Status Page, show quality as color
|
||||
- Show WiFi rssi in Network Status Page, show quality as color
|
||||
|
||||
## Fixed
|
||||
|
||||
@@ -22,9 +22,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## Changed
|
||||
|
||||
- mqtt free mem check set to 60 kb
|
||||
- small cosmetic changes to Searching in Customization web page
|
||||
- updated to espressif32@6.4.0
|
||||
- MQTT free mem check set to 60 kb
|
||||
- Small cosmetic changes to Searching in Customization web page
|
||||
- Updated to espressif32@6.4.0
|
||||
|
||||
# [3.6.0] August 13 2023
|
||||
|
||||
@@ -36,7 +36,7 @@ There are breaking changes between 3.5.x and earlier versions of 3.6.0. Please r
|
||||
|
||||
## Added
|
||||
|
||||
- Workaround for better Domoticz MQTT intergration? [#904](https://github.com/emsesp/EMS-ESP32/issues/904)
|
||||
- Workaround for better Domoticz MQTT integration? [#904](https://github.com/emsesp/EMS-ESP32/issues/904)
|
||||
- Show MAC address without connecting to network enhancement [#933](https://github.com/emsesp/EMS-ESP32/issues/933)
|
||||
- Warn user in WebUI of unsaved changes [#911](https://github.com/emsesp/EMS-ESP32/issues/911)
|
||||
- Detect old Tado thermostat, device-id 0x19, no entities
|
||||
@@ -202,7 +202,7 @@ There are breaking changes between 3.5.x and earlier versions of 3.6.0. Please r
|
||||
|
||||
- WebUI optimizations, updated look&feel and better performance [#124](https://github.com/emsesp/EMS-ESP32/issues/124)
|
||||
- Auto refresh of WebUI after successful firmware upload [#178](https://github.com/emsesp/EMS-ESP32/issues/178)
|
||||
- New Customization Service in WebUI. First feature is the ability to enable/disabled Enitites (device values) from EMS devices [#206](https://github.com/emsesp/EMS-ESP32/issues/206)
|
||||
- New Customization Service in WebUI. First feature is the ability to enable/disabled Entities (device values) from EMS devices [#206](https://github.com/emsesp/EMS-ESP32/issues/206)
|
||||
- Option to disable Telnet Console [#209](https://github.com/emsesp/EMS-ESP32/issues/209)
|
||||
- Added Hide SSID, Max Clients and Preferred Channel to Access Point
|
||||
- Merged in MichaelDvP's changes like Fahrenheit conversion, publish single (for IOBroker) and a few other critical optimizations
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
# Changelog
|
||||
|
||||
## [3.6.1]
|
||||
## [3.6.2]
|
||||
|
||||
## **IMPORTANT! BREAKING CHANGES**
|
||||
|
||||
- `shower_data` MQTT topic shows duration is seconds (was previously a full english sentence)
|
||||
|
||||
## Added
|
||||
|
||||
- show WiFi rssi in Network Status Page, show quality as color
|
||||
- Power entities
|
||||
- Optional input of BSSID for AP connection
|
||||
- Return empty json if no entries in scheduler/custom/analogsnesor/temperaturesensor
|
||||
|
||||
## Fixed
|
||||
|
||||
- Issue in espMqttClient causing a memory leak when MQTT broker is disconnected due to network unavailability [#1264](https://github.com/emsesp/EMS-ESP32/issues/1264)
|
||||
- Using MQTT enum values correctly formatted in MQTT Discovery [#1280](https://github.com/emsesp/EMS-ESP32/issues/1280)
|
||||
- Wifi full scan to get strongest AP
|
||||
- Add missing dhw tags
|
||||
- Sending a dash/- to the Reset command doesn't return an error [#1308](https://github.com/emsesp/EMS-ESP32/discussions/1308)
|
||||
|
||||
## Changed
|
||||
|
||||
- mqtt free mem check set to 60 kb
|
||||
- small cosmetic changes to Searching in Customization web page
|
||||
- updated to espressif32@6.4.0
|
||||
- MQTT queue max 300 messages, check heap and maxAlloc
|
||||
- API call commands are logged as WARN in the log
|
||||
- Reset Command renamed to 'reset' in lowercase in EN
|
||||
|
||||
4
Makefile
4
Makefile
@@ -42,7 +42,7 @@ DEFINES += -DARDUINOJSON_ENABLE_STD_STRING=1 -DARDUINOJSON_ENABLE_PROGMEM=1 -DAR
|
||||
DEFINES += -DEMSESP_DEBUG -DEMSESP_STANDALONE -DEMSESP_TEST -D__linux__ -DEMC_RX_BUFFER_SIZE=1500
|
||||
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.6.0-dev\" -DEMSESP_DEFAULT_BOARD_PROFILE=\"S32\"
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# Sources & Files
|
||||
@@ -81,7 +81,7 @@ CPPFLAGS += -g3
|
||||
CPPFLAGS += -Os
|
||||
|
||||
CFLAGS += $(CPPFLAGS)
|
||||
CFLAGS += -Wall -Wextra -Werror -Wswitch-enum -Wno-unused-parameter -Wno-inconsistent-missing-override -Wno-missing-braces -Wno-unused-lambda-capture
|
||||
CFLAGS += -Wall -Wextra -Werror -Wswitch-enum -Wno-unused-parameter -Wno-inconsistent-missing-override -Wno-missing-braces -Wno-unused-lambda-capture -Wno-sign-compare
|
||||
|
||||
CXXFLAGS += $(CFLAGS) -MMD
|
||||
|
||||
|
||||
@@ -1583,8 +1583,8 @@ Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,bo
|
||||
Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,mintempsilent,min outside temp for silent mode,int (>=-126<=126),C,true,number.boiler_min_outside_temp_for_silent_mode,number.boiler_mintempsilent
|
||||
Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,tempparmode,outside temp parallel mode,int (>=-126<=126),C,true,number.boiler_outside_temp_parallel_mode,number.boiler_tempparmode
|
||||
Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,auxheatmix,aux heater mixing valve,int (>=-100<=100),%,false,sensor.boiler_aux_heater_mixing_valve,sensor.boiler_auxheatmix
|
||||
Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,tempdiffheat,temp diff TC3/TC0 heat,uint (>=3<=10),K,true,number.boiler_temp_diff_TC3/TC0_heat,number.boiler_tempdiffheat
|
||||
Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,tempdiffcool,temp diff TC3/TC0 cool,uint (>=3<=10),K,true,number.boiler_temp_diff_TC3/TC0_cool,number.boiler_tempdiffcool
|
||||
Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,tempdiffheat,temp diff TC3/TC0 heat,uint (>=2<=10),K,true,number.boiler_temp_diff_TC3/TC0_heat,number.boiler_tempdiffheat
|
||||
Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,tempdiffcool,temp diff TC3/TC0 cool,uint (>=2<=10),K,true,number.boiler_temp_diff_TC3/TC0_cool,number.boiler_tempdiffcool
|
||||
Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,vpcooling,valve/pump cooling,boolean, ,true,switch.boiler_valve/pump_cooling,switch.boiler_vpcooling
|
||||
Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,heatcable,heating cable,boolean, ,true,switch.boiler_heating_cable,switch.boiler_heatcable
|
||||
Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,vc0valve,VC0 valve,boolean, ,true,switch.boiler_VC0_valve,switch.boiler_vc0valve
|
||||
@@ -1768,8 +1768,8 @@ Geo 5xx,boiler,173,silentto,silent mode to,uint (>=0<=3810),minutes,true,number.
|
||||
Geo 5xx,boiler,173,mintempsilent,min outside temp for silent mode,int (>=-126<=126),C,true,number.boiler_min_outside_temp_for_silent_mode,number.boiler_mintempsilent
|
||||
Geo 5xx,boiler,173,tempparmode,outside temp parallel mode,int (>=-126<=126),C,true,number.boiler_outside_temp_parallel_mode,number.boiler_tempparmode
|
||||
Geo 5xx,boiler,173,auxheatmix,aux heater mixing valve,int (>=-100<=100),%,false,sensor.boiler_aux_heater_mixing_valve,sensor.boiler_auxheatmix
|
||||
Geo 5xx,boiler,173,tempdiffheat,temp diff TC3/TC0 heat,uint (>=3<=10),K,true,number.boiler_temp_diff_TC3/TC0_heat,number.boiler_tempdiffheat
|
||||
Geo 5xx,boiler,173,tempdiffcool,temp diff TC3/TC0 cool,uint (>=3<=10),K,true,number.boiler_temp_diff_TC3/TC0_cool,number.boiler_tempdiffcool
|
||||
Geo 5xx,boiler,173,tempdiffheat,temp diff TC3/TC0 heat,uint (>=2<=10),K,true,number.boiler_temp_diff_TC3/TC0_heat,number.boiler_tempdiffheat
|
||||
Geo 5xx,boiler,173,tempdiffcool,temp diff TC3/TC0 cool,uint (>=2<=10),K,true,number.boiler_temp_diff_TC3/TC0_cool,number.boiler_tempdiffcool
|
||||
Geo 5xx,boiler,173,vpcooling,valve/pump cooling,boolean, ,true,switch.boiler_valve/pump_cooling,switch.boiler_vpcooling
|
||||
Geo 5xx,boiler,173,heatcable,heating cable,boolean, ,true,switch.boiler_heating_cable,switch.boiler_heatcable
|
||||
Geo 5xx,boiler,173,vc0valve,VC0 valve,boolean, ,true,switch.boiler_VC0_valve,switch.boiler_vc0valve
|
||||
@@ -2635,8 +2635,9 @@ UI800,thermostat,4,noreducetemp,no reduce below temperature,int (>=-126<=126),C,
|
||||
UI800,thermostat,4,reducetemp,off/reduce switch temperature,int (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp
|
||||
UI800,thermostat,4,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio
|
||||
UI800,thermostat,4,cooling,cooling,boolean, ,true,switch.thermostat_hc1_cooling,switch.thermostat_hc1_cooling
|
||||
UI800,thermostat,4,coolingon,cooling,boolean, ,false,binary_sensor.thermostat_hc1_cooling,binary_sensor.thermostat_hc1_coolingon
|
||||
UI800,thermostat,4,hpmode,HP Mode,enum [heating\|cooling\|heating&cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode
|
||||
UI800,thermostat,4,dewoffset,dew point offset,uint (>=0<=254),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset
|
||||
UI800,thermostat,4,dewoffset,dew point offset,uint (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset
|
||||
UI800,thermostat,4,roomtempdiff,room temp difference,uint (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff
|
||||
UI800,thermostat,4,hpminflowtemp,HP min. flow temp.,uint (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp
|
||||
RC10,thermostat,65,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode
|
||||
@@ -2987,8 +2988,9 @@ RC200/CW100,thermostat,157,noreducetemp,no reduce below temperature,int (>=-126<
|
||||
RC200/CW100,thermostat,157,reducetemp,off/reduce switch temperature,int (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp
|
||||
RC200/CW100,thermostat,157,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio
|
||||
RC200/CW100,thermostat,157,cooling,cooling,boolean, ,true,switch.thermostat_hc1_cooling,switch.thermostat_hc1_cooling
|
||||
RC200/CW100,thermostat,157,coolingon,cooling,boolean, ,false,binary_sensor.thermostat_hc1_cooling,binary_sensor.thermostat_hc1_coolingon
|
||||
RC200/CW100,thermostat,157,hpmode,HP Mode,enum [heating\|cooling\|heating&cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode
|
||||
RC200/CW100,thermostat,157,dewoffset,dew point offset,uint (>=0<=254),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset
|
||||
RC200/CW100,thermostat,157,dewoffset,dew point offset,uint (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset
|
||||
RC200/CW100,thermostat,157,roomtempdiff,room temp difference,uint (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff
|
||||
RC200/CW100,thermostat,157,hpminflowtemp,HP min. flow temp.,uint (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp
|
||||
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode
|
||||
@@ -3057,8 +3059,9 @@ RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,noreducetem
|
||||
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,reducetemp,off/reduce switch temperature,int (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp
|
||||
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio
|
||||
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,cooling,cooling,boolean, ,true,switch.thermostat_hc1_cooling,switch.thermostat_hc1_cooling
|
||||
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,coolingon,cooling,boolean, ,false,binary_sensor.thermostat_hc1_cooling,binary_sensor.thermostat_hc1_coolingon
|
||||
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,hpmode,HP Mode,enum [heating\|cooling\|heating&cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode
|
||||
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,dewoffset,dew point offset,uint (>=0<=254),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset
|
||||
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,dewoffset,dew point offset,uint (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset
|
||||
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,roomtempdiff,room temp difference,uint (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff
|
||||
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,hpminflowtemp,HP min. flow temp.,uint (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp
|
||||
RC100/Moduline 1000/1010,thermostat,165,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode
|
||||
@@ -3127,8 +3130,9 @@ RC100/Moduline 1000/1010,thermostat,165,noreducetemp,no reduce below temperature
|
||||
RC100/Moduline 1000/1010,thermostat,165,reducetemp,off/reduce switch temperature,int (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp
|
||||
RC100/Moduline 1000/1010,thermostat,165,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio
|
||||
RC100/Moduline 1000/1010,thermostat,165,cooling,cooling,boolean, ,true,switch.thermostat_hc1_cooling,switch.thermostat_hc1_cooling
|
||||
RC100/Moduline 1000/1010,thermostat,165,coolingon,cooling,boolean, ,false,binary_sensor.thermostat_hc1_cooling,binary_sensor.thermostat_hc1_coolingon
|
||||
RC100/Moduline 1000/1010,thermostat,165,hpmode,HP Mode,enum [heating\|cooling\|heating&cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode
|
||||
RC100/Moduline 1000/1010,thermostat,165,dewoffset,dew point offset,uint (>=0<=254),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset
|
||||
RC100/Moduline 1000/1010,thermostat,165,dewoffset,dew point offset,uint (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset
|
||||
RC100/Moduline 1000/1010,thermostat,165,roomtempdiff,room temp difference,uint (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff
|
||||
RC100/Moduline 1000/1010,thermostat,165,hpminflowtemp,HP min. flow temp.,uint (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp
|
||||
Rego 2000/3000,thermostat,172,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode
|
||||
@@ -3197,8 +3201,9 @@ Rego 2000/3000,thermostat,172,noreducetemp,no reduce below temperature,int (>=-1
|
||||
Rego 2000/3000,thermostat,172,reducetemp,off/reduce switch temperature,int (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp
|
||||
Rego 2000/3000,thermostat,172,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio
|
||||
Rego 2000/3000,thermostat,172,cooling,cooling,boolean, ,true,switch.thermostat_hc1_cooling,switch.thermostat_hc1_cooling
|
||||
Rego 2000/3000,thermostat,172,coolingon,cooling,boolean, ,false,binary_sensor.thermostat_hc1_cooling,binary_sensor.thermostat_hc1_coolingon
|
||||
Rego 2000/3000,thermostat,172,hpmode,HP Mode,enum [heating\|cooling\|heating&cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode
|
||||
Rego 2000/3000,thermostat,172,dewoffset,dew point offset,uint (>=0<=254),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset
|
||||
Rego 2000/3000,thermostat,172,dewoffset,dew point offset,uint (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset
|
||||
Rego 2000/3000,thermostat,172,roomtempdiff,room temp difference,uint (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff
|
||||
Rego 2000/3000,thermostat,172,hpminflowtemp,HP min. flow temp.,uint (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp
|
||||
Comfort RF,thermostat,215,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode
|
||||
@@ -3294,8 +3299,9 @@ Rego 3000/UI800,thermostat,253,noreducetemp,no reduce below temperature,int (>=-
|
||||
Rego 3000/UI800,thermostat,253,reducetemp,off/reduce switch temperature,int (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp
|
||||
Rego 3000/UI800,thermostat,253,wwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_wwprio
|
||||
Rego 3000/UI800,thermostat,253,cooling,cooling,boolean, ,true,switch.thermostat_hc1_cooling,switch.thermostat_hc1_cooling
|
||||
Rego 3000/UI800,thermostat,253,coolingon,cooling,boolean, ,false,binary_sensor.thermostat_hc1_cooling,binary_sensor.thermostat_hc1_coolingon
|
||||
Rego 3000/UI800,thermostat,253,hpmode,HP Mode,enum [heating\|cooling\|heating&cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode
|
||||
Rego 3000/UI800,thermostat,253,dewoffset,dew point offset,uint (>=0<=254),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset
|
||||
Rego 3000/UI800,thermostat,253,dewoffset,dew point offset,uint (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset
|
||||
Rego 3000/UI800,thermostat,253,roomtempdiff,room temp difference,uint (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff
|
||||
Rego 3000/UI800,thermostat,253,hpminflowtemp,HP min. flow temp.,uint (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp
|
||||
ES72/RC20,thermostat,66,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -22,44 +22,42 @@
|
||||
"@alova/adapter-xhr": "^1.0.1",
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@mui/icons-material": "^5.14.8",
|
||||
"@mui/material": "^5.14.8",
|
||||
"@preact/compat": "^17.1.2",
|
||||
"@prefresh/vite": "^2.4.1",
|
||||
"@mui/icons-material": "^5.14.11",
|
||||
"@mui/material": "^5.14.11",
|
||||
"@table-library/react-table-library": "4.1.7",
|
||||
"@types/lodash-es": "^4.17.9",
|
||||
"@types/node": "^20.6.0",
|
||||
"@types/react": "^18.2.21",
|
||||
"@types/react-dom": "^18.2.7",
|
||||
"@types/node": "^20.8.0",
|
||||
"@types/react": "^18.2.24",
|
||||
"@types/react-dom": "^18.2.8",
|
||||
"@types/react-router-dom": "^5.3.3",
|
||||
"alova": "^2.11.1",
|
||||
"alova": "^2.13.1",
|
||||
"async-validator": "^4.2.5",
|
||||
"history": "^5.3.0",
|
||||
"jwt-decode": "^3.1.2",
|
||||
"lodash-es": "^4.17.21",
|
||||
"mime-types": "^2.1.35",
|
||||
"preact": "^10.17.1",
|
||||
"react": "latest",
|
||||
"react-dom": "latest",
|
||||
"react-dropzone": "^14.2.3",
|
||||
"react-icons": "^4.11.0",
|
||||
"react-router-dom": "^6.15.0",
|
||||
"react-router-dom": "^6.16.0",
|
||||
"react-toastify": "^9.1.3",
|
||||
"sockette": "^2.0.6",
|
||||
"typesafe-i18n": "^5.26.2",
|
||||
"typescript": "^5.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.22.17",
|
||||
"@babel/core": "^7.23.0",
|
||||
"@preact/compat": "^17.1.2",
|
||||
"@preact/preset-vite": "^2.5.0",
|
||||
"@types/babel__core": "^7",
|
||||
"@typescript-eslint/eslint-plugin": "^6.6.0",
|
||||
"@typescript-eslint/parser": "^6.6.0",
|
||||
"eslint": "^8.49.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.7.3",
|
||||
"@typescript-eslint/parser": "^6.7.3",
|
||||
"eslint": "^8.50.0",
|
||||
"eslint-config-airbnb": "^19.0.4",
|
||||
"eslint-config-airbnb-typescript": "^17.1.0",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
"eslint-import-resolver-typescript": "^3.6.0",
|
||||
"eslint-import-resolver-typescript": "^3.6.1",
|
||||
"eslint-plugin-autofix": "^1.1.0",
|
||||
"eslint-plugin-import": "^2.28.1",
|
||||
"eslint-plugin-jsx-a11y": "^6.7.1",
|
||||
@@ -67,12 +65,13 @@
|
||||
"eslint-plugin-react": "^7.33.2",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"preact": "^10.18.1",
|
||||
"prettier": "^3.0.3",
|
||||
"rollup-plugin-visualizer": "^5.9.2",
|
||||
"terser": "^5.19.4",
|
||||
"terser": "^5.20.0",
|
||||
"vite": "^4.4.9",
|
||||
"vite-plugin-svgr": "^3.2.0",
|
||||
"vite-tsconfig-paths": "^4.2.0"
|
||||
"vite-plugin-svgr": "^4.1.0",
|
||||
"vite-tsconfig-paths": "^4.2.1"
|
||||
},
|
||||
"packageManager": "yarn@3.4.1"
|
||||
}
|
||||
|
||||
@@ -26,6 +26,9 @@ const theme = responsiveFontSizes(
|
||||
},
|
||||
info: {
|
||||
main: '#607d8b' // blueGrey[500]
|
||||
},
|
||||
text: {
|
||||
disabled: '#eee' // white
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -15,15 +15,15 @@ import { PROJECT_NAME } from 'api/env';
|
||||
import { ValidatedPasswordField, ValidatedTextField } from 'components';
|
||||
import { AuthenticationContext } from 'contexts/authentication';
|
||||
|
||||
import { ReactComponent as DEflag } from 'i18n/DE.svg';
|
||||
import { ReactComponent as FRflag } from 'i18n/FR.svg';
|
||||
import { ReactComponent as GBflag } from 'i18n/GB.svg';
|
||||
import { ReactComponent as ITflag } from 'i18n/IT.svg';
|
||||
import { ReactComponent as NLflag } from 'i18n/NL.svg';
|
||||
import { ReactComponent as NOflag } from 'i18n/NO.svg';
|
||||
import { ReactComponent as PLflag } from 'i18n/PL.svg';
|
||||
import { ReactComponent as SVflag } from 'i18n/SV.svg';
|
||||
import { ReactComponent as TRflag } from 'i18n/TR.svg';
|
||||
import DEflag from 'i18n/DE.svg';
|
||||
import FRflag from 'i18n/FR.svg';
|
||||
import GBflag from 'i18n/GB.svg';
|
||||
import ITflag from 'i18n/IT.svg';
|
||||
import NLflag from 'i18n/NL.svg';
|
||||
import NOflag from 'i18n/NO.svg';
|
||||
import PLflag from 'i18n/PL.svg';
|
||||
import SVflag from 'i18n/SV.svg';
|
||||
import TRflag from 'i18n/TR.svg';
|
||||
import { I18nContext } from 'i18n/i18n-react';
|
||||
import { loadLocaleAsync } from 'i18n/i18n-util.async';
|
||||
import { onEnterCallback, updateValue } from 'utils';
|
||||
@@ -115,39 +115,39 @@ const SignIn: FC = () => {
|
||||
|
||||
<TextField name="locale" variant="outlined" value={locale} onChange={onLocaleSelected} size="small" select>
|
||||
<MenuItem key="de" value="de">
|
||||
<DEflag style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
<img src={DEflag} style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
DE
|
||||
</MenuItem>
|
||||
<MenuItem key="en" value="en">
|
||||
<GBflag style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
<img src={GBflag} style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
EN
|
||||
</MenuItem>
|
||||
<MenuItem key="fr" value="fr">
|
||||
<FRflag style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
<img src={FRflag} style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
FR
|
||||
</MenuItem>
|
||||
<MenuItem key="it" value="it">
|
||||
<ITflag style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
<img src={ITflag} style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
IT
|
||||
</MenuItem>
|
||||
<MenuItem key="nl" value="nl">
|
||||
<NLflag style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
<img src={NLflag} style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
NL
|
||||
</MenuItem>
|
||||
<MenuItem key="no" value="no">
|
||||
<NOflag style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
<img src={NOflag} style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
NO
|
||||
</MenuItem>
|
||||
<MenuItem key="pl" value="pl">
|
||||
<PLflag style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
<img src={PLflag} style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
PL
|
||||
</MenuItem>
|
||||
<MenuItem key="sv" value="sv">
|
||||
<SVflag style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
<img src={SVflag} style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
SV
|
||||
</MenuItem>
|
||||
<MenuItem key="tr" value="tr">
|
||||
<TRflag style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
<img src={TRflag} style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
TR
|
||||
</MenuItem>
|
||||
</TextField>
|
||||
|
||||
@@ -19,15 +19,15 @@ import type { Locales } from 'i18n/i18n-types';
|
||||
import type { FC, ChangeEventHandler } from 'react';
|
||||
import { AuthenticatedContext } from 'contexts/authentication';
|
||||
|
||||
import { ReactComponent as DEflag } from 'i18n/DE.svg';
|
||||
import { ReactComponent as FRflag } from 'i18n/FR.svg';
|
||||
import { ReactComponent as GBflag } from 'i18n/GB.svg';
|
||||
import { ReactComponent as ITflag } from 'i18n/IT.svg';
|
||||
import { ReactComponent as NLflag } from 'i18n/NL.svg';
|
||||
import { ReactComponent as NOflag } from 'i18n/NO.svg';
|
||||
import { ReactComponent as PLflag } from 'i18n/PL.svg';
|
||||
import { ReactComponent as SVflag } from 'i18n/SV.svg';
|
||||
import { ReactComponent as TRflag } from 'i18n/TR.svg';
|
||||
import DEflag from 'i18n/DE.svg';
|
||||
import FRflag from 'i18n/FR.svg';
|
||||
import GBflag from 'i18n/GB.svg';
|
||||
import ITflag from 'i18n/IT.svg';
|
||||
import NLflag from 'i18n/NL.svg';
|
||||
import NOflag from 'i18n/NO.svg';
|
||||
import PLflag from 'i18n/PL.svg';
|
||||
import SVflag from 'i18n/SV.svg';
|
||||
import TRflag from 'i18n/TR.svg';
|
||||
import { I18nContext } from 'i18n/i18n-react';
|
||||
import { loadLocaleAsync } from 'i18n/i18n-util.async';
|
||||
|
||||
@@ -75,39 +75,39 @@ const LayoutAuthMenu: FC = () => {
|
||||
select
|
||||
>
|
||||
<MenuItem key="de" value="de">
|
||||
<DEflag style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
<img src={DEflag} style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
DE
|
||||
</MenuItem>
|
||||
<MenuItem key="en" value="en">
|
||||
<GBflag style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
<img src={GBflag} style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
EN
|
||||
</MenuItem>
|
||||
<MenuItem key="fr" value="fr">
|
||||
<FRflag style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
<img src={FRflag} style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
FR
|
||||
</MenuItem>
|
||||
<MenuItem key="it" value="it">
|
||||
<ITflag style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
<img src={ITflag} style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
IT
|
||||
</MenuItem>
|
||||
<MenuItem key="nl" value="nl">
|
||||
<NLflag style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
<img src={NLflag} style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
NL
|
||||
</MenuItem>
|
||||
<MenuItem key="no" value="no">
|
||||
<NOflag style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
<img src={NOflag} style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
NO
|
||||
</MenuItem>
|
||||
<MenuItem key="pl" value="pl">
|
||||
<PLflag style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
<img src={PLflag} style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
PL
|
||||
</MenuItem>
|
||||
<MenuItem key="sv" value="sv">
|
||||
<SVflag style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
<img src={SVflag} style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
SV
|
||||
</MenuItem>
|
||||
<MenuItem key="tr" value="tr">
|
||||
<TRflag style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
<img src={TRflag} style={{ width: 16, verticalAlign: 'middle' }} />
|
||||
TR
|
||||
</MenuItem>
|
||||
</TextField>
|
||||
|
||||
@@ -82,7 +82,8 @@ const WiFiSettingsForm: FC = () => {
|
||||
if (selectedNetwork) {
|
||||
updateState('networkSettings', (current_data) => ({
|
||||
ssid: selectedNetwork.ssid,
|
||||
password: '',
|
||||
bssid: selectedNetwork.bssid,
|
||||
password: current_data ? current_data.password : '',
|
||||
hostname: current_data?.hostname,
|
||||
static_ip_config: false,
|
||||
enableIPv6: false,
|
||||
@@ -117,6 +118,12 @@ const WiFiSettingsForm: FC = () => {
|
||||
} catch (errors: any) {
|
||||
setFieldErrors(errors);
|
||||
}
|
||||
deselectNetwork();
|
||||
};
|
||||
|
||||
const setCancel = async () => {
|
||||
deselectNetwork();
|
||||
await loadData();
|
||||
};
|
||||
|
||||
const restart = async () => {
|
||||
@@ -139,10 +146,17 @@ const WiFiSettingsForm: FC = () => {
|
||||
</ListItemAvatar>
|
||||
<ListItemText
|
||||
primary={selectedNetwork.ssid}
|
||||
secondary={'Security: ' + networkSecurityMode(selectedNetwork) + ', Ch: ' + selectedNetwork.channel}
|
||||
secondary={
|
||||
'Security: ' +
|
||||
networkSecurityMode(selectedNetwork) +
|
||||
', Ch: ' +
|
||||
selectedNetwork.channel +
|
||||
', bssid: ' +
|
||||
selectedNetwork.bssid
|
||||
}
|
||||
/>
|
||||
<ListItemSecondaryAction>
|
||||
<IconButton onClick={deselectNetwork}>
|
||||
<IconButton onClick={setCancel}>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
</ListItemSecondaryAction>
|
||||
@@ -160,6 +174,16 @@ const WiFiSettingsForm: FC = () => {
|
||||
margin="normal"
|
||||
/>
|
||||
)}
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
name="bssid"
|
||||
label={'BSSID (' + LL.NETWORK_BLANK_BSSID() + ')'}
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
value={data.bssid}
|
||||
onChange={updateFormValue}
|
||||
margin="normal"
|
||||
/>
|
||||
{(!selectedNetwork || !isNetworkOpen(selectedNetwork)) && (
|
||||
<ValidatedPasswordField
|
||||
fieldErrors={fieldErrors}
|
||||
@@ -296,7 +320,7 @@ const WiFiSettingsForm: FC = () => {
|
||||
</MessageBox>
|
||||
)}
|
||||
|
||||
{!restartNeeded && dirtyFlags && dirtyFlags.length !== 0 && (
|
||||
{!restartNeeded && (selectedNetwork || (dirtyFlags && dirtyFlags.length !== 0)) && (
|
||||
<ButtonRow>
|
||||
<Button
|
||||
startIcon={<CancelIcon />}
|
||||
|
||||
@@ -65,7 +65,9 @@ const WiFiNetworkSelector: FC<WiFiNetworkSelectorProps> = ({ networkList }) => {
|
||||
</ListItemAvatar>
|
||||
<ListItemText
|
||||
primary={network.ssid}
|
||||
secondary={'Security: ' + networkSecurityMode(network) + ', Ch: ' + network.channel}
|
||||
secondary={
|
||||
'Security: ' + networkSecurityMode(network) + ', Ch: ' + network.channel + ', bssid: ' + network.bssid
|
||||
}
|
||||
/>
|
||||
<ListItemIcon>
|
||||
<Badge badgeContent={network.rssi + 'dBm'}>
|
||||
|
||||
@@ -282,6 +282,7 @@ const de: Translation = {
|
||||
NETWORK_SCANNER: 'Netzwerk Suche',
|
||||
NETWORK_NO_WIFI: 'Keine WiFi Netzwerke gefunden',
|
||||
NETWORK_BLANK_SSID: 'Freilassen um WiFi zu deaktivieren und ETH zu aktivieren',
|
||||
NETWORK_BLANK_BSSID: 'Freilassen um nur SSID für die Verbindung zu nutzen',
|
||||
TX_POWER: 'Tx Leistung',
|
||||
HOSTNAME: 'Hostname',
|
||||
NETWORK_DISABLE_SLEEP: 'Deaktiviere WiFi Schlafmodus',
|
||||
|
||||
@@ -282,6 +282,7 @@ const en: Translation = {
|
||||
NETWORK_SCANNER: 'Network Scanner',
|
||||
NETWORK_NO_WIFI: 'No WiFi networks found',
|
||||
NETWORK_BLANK_SSID: 'leave blank to disable WiFi and enable ETH',
|
||||
NETWORK_BLANK_BSSID: 'leave blank to use only SSID',
|
||||
TX_POWER: 'Tx Power',
|
||||
HOSTNAME: 'Hostname',
|
||||
NETWORK_DISABLE_SLEEP: 'Disable WiFi Sleep Mode',
|
||||
|
||||
@@ -282,6 +282,7 @@ const fr: Translation = {
|
||||
NETWORK_SCANNER: 'Scan réseau',
|
||||
NETWORK_NO_WIFI: 'Pas de réseau WiFi trouvé',
|
||||
NETWORK_BLANK_SSID: 'laisser vide pour désactiver le WiFi', // and enable ETH // TODO translate
|
||||
NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate
|
||||
TX_POWER: 'Puissance Tx',
|
||||
HOSTNAME: 'Nom d\'hôte',
|
||||
NETWORK_DISABLE_SLEEP: 'Désactiver le mode veille du WiFi',
|
||||
|
||||
@@ -284,6 +284,7 @@ const it: Translation = {
|
||||
NETWORK_SCANNER: 'Scansione Rete',
|
||||
NETWORK_NO_WIFI: 'Nessuana rete WiFi trovata',
|
||||
NETWORK_BLANK_SSID: 'lasciare vuoto per disattivare WiFi',
|
||||
NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate
|
||||
TX_POWER: 'Potenza Tx',
|
||||
HOSTNAME: 'Nome ospite',
|
||||
NETWORK_DISABLE_SLEEP: 'Disabilita la modalità sospensione Wi-Fi',
|
||||
|
||||
@@ -282,6 +282,7 @@ const nl: Translation = {
|
||||
NETWORK_SCANNER: 'Netwerk Scanner',
|
||||
NETWORK_NO_WIFI: 'Geen WiFi networken gevonden',
|
||||
NETWORK_BLANK_SSID: 'laat leeg om WiFi uit te schakelen',
|
||||
NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate
|
||||
TX_POWER: 'Tx Vermogen',
|
||||
HOSTNAME: 'Hostname',
|
||||
NETWORK_DISABLE_SLEEP: 'WiFi Sleep Mode uitzetten',
|
||||
|
||||
@@ -282,6 +282,7 @@ const no: Translation = {
|
||||
NETWORK_SCANNER: 'Nettverk Scanner',
|
||||
NETWORK_NO_WIFI: 'Ingen trådløse nett funnet',
|
||||
NETWORK_BLANK_SSID: 'la feltet være blankt for å deaktivisere trådløst nettverk', // TODO translate
|
||||
NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate
|
||||
TX_POWER: 'Tx Effekt',
|
||||
HOSTNAME: 'Hostname',
|
||||
NETWORK_DISABLE_SLEEP: 'Hindre at trådløst nettverk går i Sleep Mode',
|
||||
|
||||
@@ -282,6 +282,7 @@ const pl: BaseTranslation = {
|
||||
NETWORK_SCANNER: 'Skaner sieci WiFi',
|
||||
NETWORK_NO_WIFI: 'Brak sieci WiFi w zasięgu',
|
||||
NETWORK_BLANK_SSID: 'pozostaw puste aby wyłączyć WiFi', // and enable ETH // TODO translate
|
||||
NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate
|
||||
TX_POWER: 'Moc nadawania',
|
||||
HOSTNAME: 'Nazwa w sieci',
|
||||
NETWORK_DISABLE_SLEEP: 'Wyłącz tryb uśpienia WiFi',
|
||||
|
||||
@@ -282,6 +282,7 @@ const sv: Translation = {
|
||||
NETWORK_SCANNER: 'Hittade nätverk',
|
||||
NETWORK_NO_WIFI: 'Inga WiFi-nätverk hittades',
|
||||
NETWORK_BLANK_SSID: 'lämna blankt för att inaktivera WiFi', // and enable ETH // TODO translate
|
||||
NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate
|
||||
TX_POWER: 'Tx Effekt',
|
||||
HOSTNAME: 'Värdnamn',
|
||||
NETWORK_DISABLE_SLEEP: 'Inaktivera sömnläge',
|
||||
|
||||
@@ -282,6 +282,7 @@ const tr: Translation = {
|
||||
NETWORK_SCANNER: 'Ağ Tarayıcısı',
|
||||
NETWORK_NO_WIFI: 'Hiçbir Kablosuz Ağ bulunamadı',
|
||||
NETWORK_BLANK_SSID: 'Kablosuz ağı devre dışı bırakmak için boş bırakın', // TODO translate
|
||||
NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate
|
||||
TX_POWER: 'Aktarım gücü',
|
||||
HOSTNAME: 'Ana Makine Adı',
|
||||
NETWORK_DISABLE_SLEEP: 'Kablosuz uyku modunu devre dışına al',
|
||||
|
||||
@@ -30,16 +30,6 @@ import { updateValue } from 'utils';
|
||||
|
||||
import { validate } from 'validators';
|
||||
|
||||
// const dialogStyle = {
|
||||
// '& .MuiDialog-paper': {
|
||||
// borderRadius: '8px',
|
||||
// borderColor: '#565656',
|
||||
// borderStyle: 'solid',
|
||||
// borderWidth: '1px'
|
||||
// },
|
||||
// backdropFilter: 'blur(1px)'
|
||||
// };
|
||||
|
||||
type DashboardDevicesDialogProps = {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
@@ -124,7 +114,7 @@ const DashboardDevicesDialog = ({
|
||||
return (
|
||||
<Dialog sx={dialogStyle} open={open} onClose={close}>
|
||||
<DialogTitle>
|
||||
{selectedItem.v === '' && selectedItem.c ? LL.RUN_COMMAND() : writeable ? LL.CHANGE_VALUE() : LL.VALUE(0)}
|
||||
{selectedItem.v === '' && selectedItem.c ? LL.RUN_COMMAND() : writeable ? LL.CHANGE_VALUE() : LL.VALUE(1)}
|
||||
</DialogTitle>
|
||||
<DialogContent dividers>
|
||||
<Box color="warning.main" p={0} pl={0} pr={0} mt={0} mb={2}>
|
||||
|
||||
@@ -65,7 +65,9 @@ const SettingsCustomization: FC = () => {
|
||||
|
||||
const { data: devices } = useRequest(EMSESP.readDevices);
|
||||
|
||||
const { send: writeCustomEntities } = useRequest((data) => EMSESP.writeCustomEntities(data), { immediate: false });
|
||||
const { send: writeCustomizationEntities } = useRequest((data) => EMSESP.writeCustomizationEntities(data), {
|
||||
immediate: false
|
||||
});
|
||||
|
||||
const { send: readDeviceEntities, onSuccess: onSuccess } = useRequest((data) => EMSESP.readDeviceEntities(data), {
|
||||
initialData: [],
|
||||
@@ -312,7 +314,7 @@ const SettingsCustomization: FC = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
await writeCustomEntities({ id: devices?.devices[selectedDevice].i, entity_ids: masked_entities }).catch(
|
||||
await writeCustomizationEntities({ id: devices?.devices[selectedDevice].i, entity_ids: masked_entities }).catch(
|
||||
(error) => {
|
||||
if (error.message === 'Reboot required') {
|
||||
setRestartNeeded(true);
|
||||
|
||||
@@ -33,12 +33,12 @@ const SettingsEntities: FC = () => {
|
||||
data: entities,
|
||||
send: fetchEntities,
|
||||
error
|
||||
} = useRequest(EMSESP.readEntities, {
|
||||
} = useRequest(EMSESP.readCustomEntities, {
|
||||
initialData: [],
|
||||
force: true
|
||||
});
|
||||
|
||||
const { send: writeEntities } = useRequest((data) => EMSESP.writeEntities(data), { immediate: false });
|
||||
const { send: writeEntities } = useRequest((data) => EMSESP.writeCustomEntities(data), { immediate: false });
|
||||
|
||||
function hasEntityChanged(ei: EntityItem) {
|
||||
return (
|
||||
|
||||
@@ -62,7 +62,7 @@ export const readDeviceEntities = (id: number) =>
|
||||
});
|
||||
export const readDevices = () => alovaInstance.Get<Devices>('/rest/devices');
|
||||
export const resetCustomizations = () => alovaInstance.Post('/rest/resetCustomizations');
|
||||
export const writeCustomEntities = (data: any) => alovaInstance.Post('/rest/customEntities', data);
|
||||
export const writeCustomizationEntities = (data: any) => alovaInstance.Post('/rest/customizationEntities', data);
|
||||
|
||||
// SettingsScheduler
|
||||
export const readSchedule = () =>
|
||||
@@ -85,8 +85,8 @@ export const readSchedule = () =>
|
||||
export const writeSchedule = (data: any) => alovaInstance.Post('/rest/schedule', data);
|
||||
|
||||
// SettingsEntities
|
||||
export const readEntities = () =>
|
||||
alovaInstance.Get<EntityItem[]>('/rest/entities', {
|
||||
export const readCustomEntities = () =>
|
||||
alovaInstance.Get<EntityItem[]>('/rest/customentities', {
|
||||
name: 'entities',
|
||||
transformData(data: any) {
|
||||
return data.entities.map((ei: EntityItem) => ({
|
||||
@@ -104,4 +104,4 @@ export const readEntities = () =>
|
||||
}));
|
||||
}
|
||||
});
|
||||
export const writeEntities = (data: any) => alovaInstance.Post('/rest/entities', data);
|
||||
export const writeCustomEntities = (data: any) => alovaInstance.Post('/rest/customentities', data);
|
||||
|
||||
@@ -37,6 +37,7 @@ export interface NetworkStatus {
|
||||
|
||||
export interface NetworkSettings {
|
||||
ssid: string;
|
||||
bssid: string;
|
||||
password: string;
|
||||
hostname: string;
|
||||
static_ip_config: boolean;
|
||||
|
||||
@@ -5,6 +5,7 @@ import type { NetworkSettings } from 'types';
|
||||
export const createNetworkSettingsValidator = (networkSettings: NetworkSettings) =>
|
||||
new Schema({
|
||||
ssid: [{ type: 'string', max: 32, message: 'SSID must be 32 characters or less' }],
|
||||
bssid: [{ type: 'string', max: 17, message: 'BSSID must be 17 characters or empty' }],
|
||||
password: { type: 'string', max: 64, message: 'Password must be 64 characters or less' },
|
||||
hostname: [{ required: true, message: 'Hostname is required' }, HOSTNAME_VALIDATOR],
|
||||
...(networkSettings.static_ip_config && {
|
||||
|
||||
1283
interface/yarn.lock
1283
interface/yarn.lock
File diff suppressed because it is too large
Load Diff
@@ -129,8 +129,6 @@ bool MqttClient::connect() {
|
||||
_onError(0, Error::OUT_OF_MEMORY);
|
||||
}
|
||||
EMC_SEMAPHORE_GIVE();
|
||||
} else if (_state <= State::connected) { // already connected or connecting
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ void NetworkSettingsService::begin() {
|
||||
|
||||
WiFi.mode(WIFI_MODE_MAX);
|
||||
WiFi.mode(WIFI_MODE_NULL);
|
||||
WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN); // default is FAST_SCAN
|
||||
WiFi.setSortMethod(WIFI_CONNECT_AP_BY_SIGNAL); // is default, no need to set
|
||||
|
||||
WiFi.onEvent(std::bind(&NetworkSettingsService::WiFiEvent, this, _1));
|
||||
|
||||
@@ -58,25 +60,36 @@ void NetworkSettingsService::manageSTA() {
|
||||
if (_state.staticIPConfig) {
|
||||
WiFi.config(_state.localIP, _state.gatewayIP, _state.subnetMask, _state.dnsIP1, _state.dnsIP2); // configure for static IP
|
||||
}
|
||||
|
||||
WiFi.setHostname(_state.hostname.c_str()); // set hostname
|
||||
|
||||
// www.esp32.com/viewtopic.php?t=12055
|
||||
read([&](NetworkSettings & networkSettings) {
|
||||
if (networkSettings.bandwidth20) {
|
||||
esp_wifi_set_bandwidth((wifi_interface_t)ESP_IF_WIFI_STA, WIFI_BW_HT20);
|
||||
} else {
|
||||
esp_wifi_set_bandwidth((wifi_interface_t)ESP_IF_WIFI_STA, WIFI_BW_HT40);
|
||||
if (_state.bandwidth20) {
|
||||
esp_wifi_set_bandwidth((wifi_interface_t)ESP_IF_WIFI_STA, WIFI_BW_HT20);
|
||||
} else {
|
||||
esp_wifi_set_bandwidth((wifi_interface_t)ESP_IF_WIFI_STA, WIFI_BW_HT40);
|
||||
}
|
||||
if (_state.nosleep) {
|
||||
WiFi.setSleep(false); // turn off sleep - WIFI_PS_NONE
|
||||
}
|
||||
// attempt to connect to the network
|
||||
uint mac[6];
|
||||
if (!_state.bssid.isEmpty() && sscanf(_state.bssid.c_str(), "%X:%X:%X:%X:%X:%X", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]) == 6) {
|
||||
uint8_t mac1[6];
|
||||
for (uint8_t i = 0; i < 6; i++) {
|
||||
mac1[i] = (uint8_t)mac[i];
|
||||
}
|
||||
if (networkSettings.nosleep) {
|
||||
WiFi.setSleep(false); // turn off sleep - WIFI_PS_NONE
|
||||
}
|
||||
WiFi.begin(_state.ssid.c_str(), _state.password.c_str()); // attempt to connect to the network
|
||||
esp_wifi_set_max_tx_power(networkSettings.tx_power * 4); // set power after wifi is startet for C3
|
||||
});
|
||||
WiFi.begin(_state.ssid.c_str(), _state.password.c_str(), 0, mac1);
|
||||
} else {
|
||||
WiFi.begin(_state.ssid.c_str(), _state.password.c_str());
|
||||
}
|
||||
|
||||
// set power after wifi is startet, fixed value for C3_V1
|
||||
#ifdef BOARD_C3_MINI_V1
|
||||
// v1 needs this value, see https://github.com/emsesp/EMS-ESP32/pull/620#discussion_r993173979
|
||||
WiFi.setTxPower(WIFI_POWER_8_5dBm); // https://www.wemos.cc/en/latest/c3/c3_mini_1_0_0.html#about-wifi
|
||||
#else
|
||||
// esp_wifi_set_max_tx_power(_state.tx_power * 4);
|
||||
WiFi.setTxPower((wifi_power_t)(_state.tx_power * 4));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -89,4 +102,8 @@ void NetworkSettingsService::WiFiEvent(WiFiEvent_t event) {
|
||||
_stopping = false;
|
||||
}
|
||||
}
|
||||
// wait 3 seconds before reconnecting
|
||||
// if (event == ARDUINO_EVENT_WIFI_STA_DISCONNECTED) {
|
||||
// _lastConnectionAttempt = millis();
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ class NetworkSettings {
|
||||
public:
|
||||
// core wifi configuration
|
||||
String ssid;
|
||||
String bssid;
|
||||
String password;
|
||||
String hostname;
|
||||
bool staticIPConfig;
|
||||
@@ -52,6 +53,7 @@ class NetworkSettings {
|
||||
static void read(NetworkSettings & settings, JsonObject & root) {
|
||||
// connection settings
|
||||
root["ssid"] = settings.ssid;
|
||||
root["bssid"] = settings.bssid;
|
||||
root["password"] = settings.password;
|
||||
root["hostname"] = settings.hostname;
|
||||
root["static_ip_config"] = settings.staticIPConfig;
|
||||
@@ -75,6 +77,7 @@ class NetworkSettings {
|
||||
auto enableCORS = settings.enableCORS;
|
||||
auto CORSOrigin = settings.CORSOrigin;
|
||||
settings.ssid = root["ssid"] | FACTORY_WIFI_SSID;
|
||||
settings.bssid = root["bssid"] | "";
|
||||
settings.password = root["password"] | FACTORY_WIFI_PASSWORD;
|
||||
settings.hostname = root["hostname"] | FACTORY_WIFI_HOSTNAME;
|
||||
settings.staticIPConfig = root["static_ip_config"] | false;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include <RestartService.h>
|
||||
#include <esp_ota_ops.h>
|
||||
|
||||
#include "../../src/emsesp_stub.hpp"
|
||||
|
||||
using namespace std::placeholders; // for `_1` etc
|
||||
|
||||
RestartService::RestartService(AsyncWebServer * server, SecurityManager * securityManager) {
|
||||
@@ -11,6 +13,7 @@ RestartService::RestartService(AsyncWebServer * server, SecurityManager * securi
|
||||
}
|
||||
|
||||
void RestartService::restart(AsyncWebServerRequest * request) {
|
||||
emsesp::EMSESP::system_.store_nvs_values();
|
||||
request->onDisconnect(RestartService::restartNow);
|
||||
request->send(200);
|
||||
}
|
||||
@@ -19,6 +22,7 @@ void RestartService::partition(AsyncWebServerRequest * request) {
|
||||
const esp_partition_t * factory_partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL);
|
||||
if (factory_partition) {
|
||||
esp_ota_set_boot_partition(factory_partition);
|
||||
emsesp::EMSESP::system_.store_nvs_values();
|
||||
request->onDisconnect(RestartService::restartNow);
|
||||
request->send(200);
|
||||
return;
|
||||
@@ -35,6 +39,7 @@ void RestartService::partition(AsyncWebServerRequest * request) {
|
||||
return;
|
||||
}
|
||||
esp_ota_set_boot_partition(ota_partition);
|
||||
emsesp::EMSESP::system_.store_nvs_values();
|
||||
request->onDisconnect(RestartService::restartNow);
|
||||
request->send(200);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include <UploadFileService.h>
|
||||
#include <esp_ota_ops.h>
|
||||
|
||||
#include "../../src/emsesp_stub.hpp"
|
||||
|
||||
using namespace std::placeholders; // for `_1` etc
|
||||
|
||||
static bool is_firmware = false;
|
||||
@@ -112,6 +114,7 @@ void UploadFileService::uploadComplete(AsyncWebServerRequest * request) {
|
||||
// did we complete uploading a json file?
|
||||
if (request->_tempFile) {
|
||||
request->_tempFile.close(); // close the file handle as the upload is now done
|
||||
emsesp::EMSESP::system_.store_nvs_values();
|
||||
request->onDisconnect(RestartService::restartNow);
|
||||
AsyncWebServerResponse * response = request->beginResponse(200);
|
||||
request->send(response);
|
||||
@@ -121,6 +124,7 @@ void UploadFileService::uploadComplete(AsyncWebServerRequest * request) {
|
||||
// check if it was a firmware upgrade
|
||||
// if no error, send the success response as a JSON
|
||||
if (is_firmware && !request->_tempObject) {
|
||||
emsesp::EMSESP::system_.store_nvs_values();
|
||||
request->onDisconnect(RestartService::restartNow);
|
||||
AsyncWebServerResponse * response = request->beginResponse(200);
|
||||
request->send(response);
|
||||
|
||||
@@ -34,8 +34,7 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// #define IPAddress std::string
|
||||
// #define IPAddress String
|
||||
typedef double double_t;
|
||||
|
||||
#define ICACHE_FLASH_ATTR
|
||||
#define ICACHE_RAM_ATTR
|
||||
|
||||
82
lib_standalone/Preferences.h
Normal file
82
lib_standalone/Preferences.h
Normal file
@@ -0,0 +1,82 @@
|
||||
#ifndef _PREFERENCES_H_
|
||||
#define _PREFERENCES_H_
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
typedef enum { PT_I8, PT_U8, PT_I16, PT_U16, PT_I32, PT_U32, PT_I64, PT_U64, PT_STR, PT_BLOB, PT_INVALID } PreferenceType;
|
||||
|
||||
class Preferences {
|
||||
protected:
|
||||
uint32_t _handle;
|
||||
bool _started;
|
||||
bool _readOnly;
|
||||
|
||||
public:
|
||||
Preferences(){};
|
||||
~Preferences(){};
|
||||
|
||||
bool begin(const char * name, bool readOnly = false, const char * partition_label = NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool remove(const char * key) {
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t putChar(const char * key, int8_t value) {
|
||||
return 0;
|
||||
}
|
||||
size_t putUChar(const char * key, uint8_t value) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t putDouble(const char * key, double value) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t getUChar(const char * key, uint8_t defaultValue = 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
double getDouble(const char * key, double defaultValue = NAN) {
|
||||
return NAN;
|
||||
}
|
||||
|
||||
// unused
|
||||
|
||||
// void end();
|
||||
// bool clear();
|
||||
// size_t putShort(const char * key, int16_t value);
|
||||
// size_t putUShort(const char * key, uint16_t value);
|
||||
// size_t putInt(const char * key, int32_t value);
|
||||
// size_t putUInt(const char * key, uint32_t value);
|
||||
// size_t putLong(const char * key, int32_t value);
|
||||
// size_t putULong(const char * key, uint32_t value);
|
||||
// size_t putLong64(const char * key, int64_t value);
|
||||
// size_t putULong64(const char * key, uint64_t value);
|
||||
// size_t putFloat(const char * key, float_t value);
|
||||
// size_t putBool(const char * key, bool value);
|
||||
// size_t putString(const char * key, const char * value);
|
||||
// size_t putString(const char * key, String value);
|
||||
// size_t putBytes(const char * key, const void * value, size_t len);
|
||||
// bool isKey(const char * key);
|
||||
// PreferenceType getType(const char * key);
|
||||
// int8_t getChar(const char * key, int8_t defaultValue = 0);
|
||||
// int16_t getShort(const char * key, int16_t defaultValue = 0);
|
||||
// uint16_t getUShort(const char * key, uint16_t defaultValue = 0);
|
||||
// int32_t getInt(const char * key, int32_t defaultValue = 0);
|
||||
// uint32_t getUInt(const char * key, uint32_t defaultValue = 0);
|
||||
// int32_t getLong(const char * key, int32_t defaultValue = 0);
|
||||
// uint32_t getULong(const char * key, uint32_t defaultValue = 0);
|
||||
// int64_t getLong64(const char * key, int64_t defaultValue = 0);
|
||||
// uint64_t getULong64(const char * key, uint64_t defaultValue = 0);
|
||||
// float_t getFloat(const char * key, float_t defaultValue = NAN);
|
||||
// bool getBool(const char * key, bool defaultValue = false);
|
||||
// size_t getString(const char * key, char * value, size_t maxLen);
|
||||
// String getString(const char * key, String defaultValue = String());
|
||||
// size_t getBytesLength(const char * key);
|
||||
// size_t getBytes(const char * key, void * buf, size_t maxLen);
|
||||
// size_t freeEntries();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -299,7 +299,7 @@ const SIGN_IN_ENDPOINT = REST_ENDPOINT_ROOT + 'signIn';
|
||||
const GENERATE_TOKEN_ENDPOINT = REST_ENDPOINT_ROOT + 'generateToken';
|
||||
|
||||
let system_status = {
|
||||
emsesp_version: '3.7.0-demo',
|
||||
emsesp_version: '3.x-demo',
|
||||
esp_platform: 'ESP32',
|
||||
max_alloc_heap: 89,
|
||||
psram_size: 0,
|
||||
@@ -347,7 +347,7 @@ const EMSESP_BOARDPROFILE_ENDPOINT = REST_ENDPOINT_ROOT + 'boardProfile';
|
||||
const EMSESP_WRITE_VALUE_ENDPOINT = REST_ENDPOINT_ROOT + 'writeDeviceValue';
|
||||
const EMSESP_WRITE_SENSOR_ENDPOINT = REST_ENDPOINT_ROOT + 'writeTemperatureSensor';
|
||||
const EMSESP_WRITE_ANALOG_ENDPOINT = REST_ENDPOINT_ROOT + 'writeAnalogSensor';
|
||||
const EMSESP_CUSTOM_ENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'customEntities';
|
||||
const EMSESP_CUSTOMIZATION_ENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'customizationEntities';
|
||||
const EMSESP_RESET_CUSTOMIZATIONS_ENDPOINT = REST_ENDPOINT_ROOT + 'resetCustomizations';
|
||||
const EMSESP_WRITE_SCHEDULE_ENDPOINT = REST_ENDPOINT_ROOT + 'schedule';
|
||||
const EMSESP_WRITE_ENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'entities';
|
||||
@@ -2355,7 +2355,7 @@ function updateMask(entity, de, dd) {
|
||||
}
|
||||
}
|
||||
|
||||
rest_server.post(EMSESP_CUSTOM_ENTITIES_ENDPOINT, (req, res) => {
|
||||
rest_server.post(EMSESP_CUSTOMIZATION_ENTITIES_ENDPOINT, (req, res) => {
|
||||
const id = req.body.id;
|
||||
console.log('customization id = ' + id);
|
||||
console.log(req.body.entity_ids);
|
||||
@@ -2627,7 +2627,7 @@ rest_server.get(EMSESP_BOARDPROFILE_ENDPOINT, (req, res) => {
|
||||
// EMS-ESP API specific
|
||||
const emsesp_info = {
|
||||
System: {
|
||||
version: '3.7.0',
|
||||
version: '3.6.2',
|
||||
uptime: '001+06:40:34.018',
|
||||
'uptime (seconds)': 110434,
|
||||
freemem: 131,
|
||||
|
||||
@@ -17,10 +17,10 @@ core_build_flags =
|
||||
-D NDEBUG
|
||||
-D ARDUINO_ARCH_ESP32=1
|
||||
-D ESP32=1
|
||||
; -std=gnu++17
|
||||
-std=gnu++17
|
||||
|
||||
; core_unbuild_flags = -std=gnu++11
|
||||
core_unbuild_flags =
|
||||
core_unbuild_flags = -std=gnu++11
|
||||
; core_unbuild_flags =
|
||||
|
||||
; my_build_flags is set in pio_local.ini
|
||||
my_build_flags =
|
||||
@@ -39,7 +39,19 @@ unbuild_flags =
|
||||
${common.core_unbuild_flags}
|
||||
|
||||
[espressi32_base]
|
||||
platform = espressif32
|
||||
platform = espressif32@6.4.0
|
||||
framework = arduino
|
||||
build_flags = ${common.build_flags}
|
||||
build_unflags = ${common.unbuild_flags}
|
||||
extra_scripts =
|
||||
pre:scripts/build_interface.py
|
||||
scripts/rename_fw.py
|
||||
|
||||
[espressi32_base_tasmota]
|
||||
; use Tasmota's libary which removes some libs (like mbedtsl) and increases available heap
|
||||
; based on Core 2.0.12/ESP-IDF v4.4.5 https://github.com/espressif/arduino-esp32/releases/tag/2.0.12 use https://github.com/tasmota/platform-espressif32/archive/refs/tags/2023.09.00.zip
|
||||
; based on Core 2.0.13/ESP-IDF v4.4.5 https://github.com/espressif/arduino-esp32/releases/tag/2.0.13 use https://github.com/tasmota/platform-espressif32/releases/download/2023.09.01/platform-espressif32-2023.09.01.zip
|
||||
platform = https://github.com/tasmota/platform-espressif32/archive/refs/tags/2023.09.00.zip
|
||||
framework = arduino
|
||||
build_flags = ${common.build_flags}
|
||||
build_unflags = ${common.unbuild_flags}
|
||||
@@ -64,9 +76,7 @@ check_flags =
|
||||
; build for GitHub Actions CI
|
||||
; the Web interface is built seperately
|
||||
[env:ci]
|
||||
extends = espressi32_base
|
||||
; stay on platform 6.3.2 until heap issue is solved
|
||||
platform = espressif32@6.3.2
|
||||
extends = espressi32_base_tasmota
|
||||
extra_scripts = scripts/rename_fw.py
|
||||
board = esp32dev
|
||||
board_build.partitions = esp32_partition_4M.csv
|
||||
@@ -74,7 +84,6 @@ board_build.filesystem = littlefs
|
||||
build_flags = ${common.build_flags}
|
||||
build_unflags = ${common.unbuild_flags}
|
||||
|
||||
; for github Actions actually standard platform is buggy, use dev-platform
|
||||
[env:ci_s3]
|
||||
extends = espressi32_base
|
||||
extra_scripts = scripts/rename_fw.py
|
||||
@@ -86,34 +95,28 @@ build_flags = ${common.build_flags} -O2
|
||||
build_unflags = ${common.unbuild_flags}
|
||||
|
||||
[env:esp32_4M]
|
||||
extends = espressi32_base
|
||||
; stay on platform 6.3.2 until heap issue is solved
|
||||
platform = espressif32@6.3.2
|
||||
extends = espressi32_base_tasmota
|
||||
board = esp32dev
|
||||
board_upload.flash_size = 4MB
|
||||
board_build.partitions = esp32_partition_4M.csv
|
||||
build_flags = ${common.build_flags} -Os
|
||||
|
||||
[env:esp32_4Mplus]
|
||||
extends = espressi32_base
|
||||
; stay on platform 6.3.2 until heap issue is solved
|
||||
platform = espressif32@6.3.2
|
||||
extends = espressi32_base_tasmota
|
||||
board = esp32dev
|
||||
board_upload.flash_size = 4MB
|
||||
board_build.partitions = esp32_asym_partition_4M.csv
|
||||
build_flags = ${common.build_flags}
|
||||
|
||||
[env:esp32_16M]
|
||||
extends = espressi32_base
|
||||
; stay on platform 6.3.2 until heap issue is solved
|
||||
platform = espressif32@6.3.2
|
||||
extends = espressi32_base_tasmota
|
||||
board = esp32dev
|
||||
board_upload.flash_size = 16MB
|
||||
board_build.partitions = esp32_partition_16M.csv
|
||||
build_flags = ${common.build_flags}
|
||||
|
||||
[env:lolin_c3_mini]
|
||||
extends = espressi32_base
|
||||
extends = espressi32_base_tasmota
|
||||
board = lolin_c3_mini
|
||||
board_upload.flash_size = 4MB
|
||||
board_build.partitions = esp32_asym_partition_4M.csv
|
||||
@@ -122,14 +125,14 @@ build_flags = ${common.build_flags}
|
||||
; lolin C3 mini v1 needs special wifi init.
|
||||
; https://www.wemos.cc/en/latest/c3/c3_mini_1_0_0.html#about-wifi
|
||||
[env:lolin_c3_mini_v1]
|
||||
extends = espressi32_base
|
||||
extends = espressi32_base_tasmota
|
||||
board = lolin_c3_mini
|
||||
board_upload.flash_size = 4MB
|
||||
board_build.partitions = esp32_asym_partition_4M.csv
|
||||
build_flags = ${common.build_flags} -DBOARD_C3_MINI_V1
|
||||
|
||||
[env:lolin_s2_mini]
|
||||
extends = espressi32_base
|
||||
extends = espressi32_base_tasmota
|
||||
board = lolin_s2_mini
|
||||
board_upload.flash_size = 4MB
|
||||
board_build.partitions = esp32_asym_partition_4M.csv
|
||||
@@ -151,11 +154,11 @@ platform = native
|
||||
build_flags =
|
||||
-DARDUINOJSON_ENABLE_STD_STRING=1 -DARDUINOJSON_ENABLE_PROGMEM=1 -DARDUINOJSON_ENABLE_ARDUINO_STRING -DARDUINOJSON_USE_DOUBLE=0
|
||||
-DEMSESP_DEBUG -DEMSESP_STANDALONE -DEMSESP_TEST -D__linux__
|
||||
-DEMSESP_DEFAULT_LOCALE=\"en\" -DEMSESP_DEFAULT_TX_MODE=8 -DEMSESP_DEFAULT_VERSION=\"3.7.0-dev\" -DEMSESP_DEFAULT_BOARD_PROFILE=\"S32\"
|
||||
-DEMSESP_DEFAULT_LOCALE=\"en\" -DEMSESP_DEFAULT_TX_MODE=8 -DEMSESP_DEFAULT_VERSION=\"3.6.0-dev\" -DEMSESP_DEFAULT_BOARD_PROFILE=\"S32\"
|
||||
-lpthread
|
||||
-std=gnu++11 -Og -ggdb
|
||||
build_src_flags =
|
||||
-Wall -Wextra -Werror -Wswitch-enum -Wno-unused-parameter -Wno-inconsistent-missing-override -Wno-unused-lambda-capture
|
||||
-Wall -Wextra -Werror -Wswitch-enum -Wno-unused-parameter -Wno-inconsistent-missing-override -Wno-unused-lambda-capture -Wno-sign-compare
|
||||
-Wno-missing-braces
|
||||
-I./lib_standalone
|
||||
-I./lib/ArduinoJson/src
|
||||
|
||||
0
scripts/api_test.http
Normal file → Executable file
0
scripts/api_test.http
Normal file → Executable file
0
scripts/app-tls-size.py
Normal file → Executable file
0
scripts/app-tls-size.py
Normal file → Executable file
0
scripts/boot_app0.bin
Normal file → Executable file
0
scripts/boot_app0.bin
Normal file → Executable file
0
scripts/bootloader_dio_40m.bin
Normal file → Executable file
0
scripts/bootloader_dio_40m.bin
Normal file → Executable file
0
scripts/build_interface.py
Normal file → Executable file
0
scripts/build_interface.py
Normal file → Executable file
0
scripts/clang-format.py
Normal file → Executable file
0
scripts/clang-format.py
Normal file → Executable file
0
scripts/clang-tidy.py
Normal file → Executable file
0
scripts/clang-tidy.py
Normal file → Executable file
0
scripts/dump_entities.csv
Normal file
0
scripts/dump_entities.csv
Normal file
|
|
3
scripts/dump_entities.py
Normal file → Executable file
3
scripts/dump_entities.py
Normal file → Executable file
@@ -1,6 +1,7 @@
|
||||
# strips out lines between two markers
|
||||
# pipe a file into, for example:
|
||||
# make clean; make; echo "test dump" | ./emsesp | python3 ./scripts/dump_entities.py
|
||||
# make clean; make; echo "test entity_dump" | ./emsesp | python3 ./scripts/dump_entities.py > dump_entities.csv
|
||||
# see dump_entities.sh
|
||||
|
||||
import fileinput
|
||||
with fileinput.input() as f_input:
|
||||
|
||||
0
scripts/dump_entities.sh
Normal file → Executable file
0
scripts/dump_entities.sh
Normal file → Executable file
0
scripts/espota.py
Normal file → Executable file
0
scripts/espota.py
Normal file → Executable file
0
scripts/esptool.py
Normal file → Executable file
0
scripts/esptool.py
Normal file → Executable file
0
scripts/helpers.py
Normal file → Executable file
0
scripts/helpers.py
Normal file → Executable file
0
scripts/partitions.bin
Normal file → Executable file
0
scripts/partitions.bin
Normal file → Executable file
0
scripts/rename_fw.py
Normal file → Executable file
0
scripts/rename_fw.py
Normal file → Executable file
0
scripts/run_memory_test.py
Normal file → Executable file
0
scripts/run_memory_test.py
Normal file → Executable file
18
scripts/run_sonar.sh
Normal file → Executable file
18
scripts/run_sonar.sh
Normal file → Executable file
@@ -1,8 +1,16 @@
|
||||
#!/bin/sh
|
||||
|
||||
# make sure you add the soanr token here
|
||||
# export SONAR_TOKEN=""
|
||||
# This is an example file to run sonar from a Linux command line
|
||||
# Run from the root of the project like `./scripts/run_sonar.sh`
|
||||
# Follow the setup in Sonar for your prpject and make sure chmod 755 +x on all the files
|
||||
# and make sure you set the token in the shell like export SONAR_TOKEN="xxxxx"
|
||||
|
||||
make clean
|
||||
build-wrapper-linux-x86-64 --out-dir build_wrapper_output_directory make all
|
||||
sonar-scanner
|
||||
~/sonar/build-wrapper-linux-x86-64 --out-dir bw-output make all
|
||||
|
||||
~/sonar/sonar-scanner/bin/sonar-scanner \
|
||||
-Dsonar.organization=proddy \
|
||||
-Dsonar.projectKey=proddy_EMS-ESP32 \
|
||||
-Dsonar.projectName=EMS-ESP32 \
|
||||
-Dsonar.sources="./src, ./lib/framework" \
|
||||
-Dsonar.cfamily.build-wrapper-output=bw-output \
|
||||
-Dsonar.host.url=https://sonarcloud.io
|
||||
|
||||
0
scripts/upload_esp32.py
Normal file → Executable file
0
scripts/upload_esp32.py
Normal file → Executable file
0
scripts/upload_fw.py
Normal file → Executable file
0
scripts/upload_fw.py
Normal file → Executable file
@@ -1,9 +1,9 @@
|
||||
sonar.organization=emsesp
|
||||
sonar.projectKey=emsesp_EMS-ESP32
|
||||
sonar.projectName=EMS-ESP32
|
||||
sonar.projectVersion=3.7.0
|
||||
sonar.projectVersion=3.6.0
|
||||
sonar.sources=./src
|
||||
sonar.cfamily.build-wrapper-output=build_wrapper_output_directory
|
||||
sonar.cfamily.build-wrapper-output=bw-output
|
||||
sonar.sourceEncoding=UTF-8
|
||||
sonar.host.url=https://sonarcloud.io
|
||||
# sonar.cfamily.threads=4
|
||||
|
||||
@@ -160,6 +160,9 @@ void AnalogSensor::reload() {
|
||||
#endif
|
||||
sensor.polltime_ = 0;
|
||||
sensor.poll_ = digitalRead(sensor.gpio());
|
||||
if (double_t val = EMSESP::nvs_.getDouble(sensor.name().c_str(), 0)) {
|
||||
sensor.set_value(val);
|
||||
}
|
||||
publish_sensor(sensor);
|
||||
} else if (sensor.type() == AnalogType::TIMER || sensor.type() == AnalogType::RATE) {
|
||||
LOG_DEBUG("Adding analog Timer/Rate sensor on GPIO %02d", sensor.gpio());
|
||||
@@ -274,7 +277,8 @@ void AnalogSensor::measure() {
|
||||
} else if (!sensor.poll_) { // falling edge
|
||||
if (sensor.type() == AnalogType::COUNTER) {
|
||||
sensor.set_value(old_value + sensor.factor());
|
||||
} else if (sensor.type() == AnalogType::RATE) { // dafault uom: Hz (1/sec) with factor 1
|
||||
// EMSESP::nvs_.putDouble(sensor.name().c_str(), sensor.value());
|
||||
} else if (sensor.type() == AnalogType::RATE) { // default uom: Hz (1/sec) with factor 1
|
||||
sensor.set_value(sensor.factor() * 1000 / (sensor.polltime_ - sensor.last_polltime_));
|
||||
} else if (sensor.type() == AnalogType::TIMER) { // default seconds with factor 1
|
||||
sensor.set_value(sensor.factor() * (sensor.polltime_ - sensor.last_polltime_) / 1000);
|
||||
@@ -290,6 +294,25 @@ void AnalogSensor::measure() {
|
||||
}
|
||||
}
|
||||
}
|
||||
// store counter-values only every hour to reduce flash wear
|
||||
static uint8_t lastSaveHour = 0;
|
||||
time_t now = time(nullptr);
|
||||
tm * tm_ = localtime(&now);
|
||||
if (tm_->tm_hour != lastSaveHour) {
|
||||
lastSaveHour = tm_->tm_hour;
|
||||
store_counters();
|
||||
}
|
||||
}
|
||||
|
||||
// store counters to NVS, called every hour, on restart and update
|
||||
void AnalogSensor::store_counters() {
|
||||
for (auto & sensor : sensors_) {
|
||||
if (sensor.type() == AnalogType::COUNTER) {
|
||||
if (sensor.value() != EMSESP::nvs_.getDouble(sensor.name().c_str())) {
|
||||
EMSESP::nvs_.putDouble(sensor.name().c_str(), sensor.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnalogSensor::loop() {
|
||||
@@ -315,10 +338,14 @@ bool AnalogSensor::update(uint8_t gpio, const std::string & name, double offset,
|
||||
found_sensor = true; // found the record
|
||||
// see if it's marked for deletion
|
||||
if (deleted) {
|
||||
EMSESP::nvs_.remove(AnalogCustomization.name.c_str());
|
||||
LOG_DEBUG("Removing analog sensor GPIO %02d", gpio);
|
||||
settings.analogCustomizations.remove(AnalogCustomization);
|
||||
} else {
|
||||
// update existing record
|
||||
if (name != AnalogCustomization.name) {
|
||||
EMSESP::nvs_.remove(AnalogCustomization.name.c_str());
|
||||
}
|
||||
AnalogCustomization.name = name;
|
||||
AnalogCustomization.offset = offset;
|
||||
AnalogCustomization.factor = factor;
|
||||
@@ -598,7 +625,7 @@ void AnalogSensor::publish_values(const bool force) {
|
||||
// searches by name
|
||||
bool AnalogSensor::get_value_info(JsonObject & output, const char * cmd, const int8_t id) const {
|
||||
if (sensors_.empty()) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
// make a copy of the string command for parsing
|
||||
char command_s[30];
|
||||
@@ -656,10 +683,10 @@ bool AnalogSensor::get_value_info(JsonObject & output, const char * cmd, const i
|
||||
}
|
||||
|
||||
// creates JSON doc from values
|
||||
// returns false if there are no sensors
|
||||
// returns true if there are no sensors
|
||||
bool AnalogSensor::command_info(const char * value, const int8_t id, JsonObject & output) const {
|
||||
if (sensors_.empty()) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const auto & sensor : sensors_) {
|
||||
|
||||
@@ -23,10 +23,6 @@
|
||||
#include "mqtt.h"
|
||||
#include "console.h"
|
||||
|
||||
#ifndef EMSESP_STANDALONE
|
||||
#include "driver/adc.h"
|
||||
#endif
|
||||
|
||||
#include <uuid/log.h>
|
||||
|
||||
namespace emsesp {
|
||||
@@ -158,6 +154,7 @@ class AnalogSensor {
|
||||
|
||||
bool update(uint8_t gpio, const std::string & name, double offset, double factor, uint8_t uom, int8_t type, bool deleted = false);
|
||||
bool get_value_info(JsonObject & output, const char * cmd, const int8_t id) const;
|
||||
void store_counters();
|
||||
|
||||
#if defined(EMSESP_TEST)
|
||||
void test();
|
||||
|
||||
164
src/command.cpp
164
src/command.cpp
@@ -300,7 +300,7 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char *
|
||||
// see if there is a command registered
|
||||
auto cf = find_command(device_type, device_id, cmd);
|
||||
|
||||
// check if its a call to and end-point to a device
|
||||
// check if its a call to an end-point of a device
|
||||
// this is used to fetch the attributes of the device entity, or call a command directly
|
||||
bool single_command = (!value || !strlen(value));
|
||||
if (single_command) {
|
||||
@@ -315,58 +315,56 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char *
|
||||
}
|
||||
|
||||
// check if we have a matching command
|
||||
if (cf) {
|
||||
// check permissions
|
||||
if (cf->has_flags(CommandFlag::ADMIN_ONLY) && !is_admin) {
|
||||
output["message"] = "authentication failed";
|
||||
return CommandRet::NOT_ALLOWED; // command not allowed
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
std::string ro = EMSESP::system_.readonly_mode() ? "[readonly] " : "";
|
||||
|
||||
if ((value == nullptr) || (strlen(value) == 0)) {
|
||||
LOG_DEBUG(("%sCalling command %s"), ro.c_str(), info_s);
|
||||
} else {
|
||||
if (id > 0) {
|
||||
LOG_DEBUG(("%sCalling command %s with value %s and id %d on device 0x%02X"), ro.c_str(), info_s, value, id, device_id);
|
||||
} else {
|
||||
LOG_DEBUG(("%sCalling command %s with value %s"), ro.c_str(), info_s, value);
|
||||
}
|
||||
}
|
||||
|
||||
// call the function based on type
|
||||
if (cf->cmdfunction_json_) {
|
||||
return_code = ((cf->cmdfunction_json_)(value, id, output)) ? CommandRet::OK : CommandRet::ERROR;
|
||||
}
|
||||
|
||||
// check if read-only. This also checks for valid tags (e.g. heating circuits)
|
||||
if (cf->cmdfunction_) {
|
||||
if (!single_command && EMSESP::cmd_is_readonly(device_type, device_id, cmd, id)) {
|
||||
return_code = CommandRet::INVALID; // readonly or invalid hc
|
||||
} else {
|
||||
return_code = ((cf->cmdfunction_)(value, id)) ? CommandRet::OK : CommandRet::ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// report back
|
||||
if (return_code != CommandRet::OK) {
|
||||
return message(return_code, "callback function failed", output);
|
||||
}
|
||||
|
||||
return return_code;
|
||||
if (!cf) {
|
||||
// we didn't find the command, report error
|
||||
LOG_DEBUG("Command failed: invalid command '%s'", cmd ? cmd : "");
|
||||
return message(CommandRet::NOT_FOUND, "invalid command", output);
|
||||
}
|
||||
|
||||
// we didn't find the command and its not an endpoint, report error
|
||||
LOG_DEBUG("Command failed: invalid command '%s'", cmd ? cmd : "");
|
||||
return message(CommandRet::NOT_FOUND, "invalid command", output);
|
||||
// check permissions and abort if not authorized
|
||||
if (cf->has_flags(CommandFlag::ADMIN_ONLY) && !is_admin) {
|
||||
output["message"] = "authentication failed";
|
||||
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);
|
||||
}
|
||||
if ((value == nullptr) || (strlen(value) == 0)) {
|
||||
LOG_WARNING(("%sCalling command %s"), ro.c_str(), info_s);
|
||||
} else {
|
||||
if (id > 0) {
|
||||
LOG_WARNING(("%sCalling command %s with value %s and id %d on device 0x%02X"), ro.c_str(), info_s, value, id, device_id);
|
||||
} else {
|
||||
LOG_WARNING(("%sCalling command %s with value %s"), ro.c_str(), info_s, value);
|
||||
}
|
||||
}
|
||||
|
||||
// call the function based on type, either with a json package or no parameters
|
||||
if (cf->cmdfunction_json_) {
|
||||
// JSON
|
||||
return_code = ((cf->cmdfunction_json_)(value, id, output)) ? CommandRet::OK : CommandRet::ERROR;
|
||||
} else if (cf->cmdfunction_) {
|
||||
// Normal command
|
||||
if (!single_command && EMSESP::cmd_is_readonly(device_type, device_id, cmd, id)) {
|
||||
return_code = CommandRet::INVALID; // error on readonly or invalid hc
|
||||
} else {
|
||||
return_code = ((cf->cmdfunction_)(value, id)) ? CommandRet::OK : CommandRet::ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// report back. If not OK show output from error, other return the HTTP code
|
||||
if (return_code != CommandRet::OK) {
|
||||
return message(return_code, "callback function failed", output);
|
||||
}
|
||||
return return_code;
|
||||
}
|
||||
|
||||
// add a command to the list, which does not return json
|
||||
@@ -540,20 +538,21 @@ bool Command::device_has_commands(const uint8_t device_type) {
|
||||
return true; // we always have System
|
||||
}
|
||||
|
||||
// if there are no entries to scheduler/custom/temperaturesensor/analogsensor, don't error but return a message
|
||||
if (device_type == EMSdevice::DeviceType::SCHEDULER) {
|
||||
return EMSESP::webSchedulerService.has_commands();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (device_type == EMSdevice::DeviceType::CUSTOM) {
|
||||
return (EMSESP::webEntityService.count_entities() != 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (device_type == EMSdevice::DeviceType::TEMPERATURESENSOR) {
|
||||
return (EMSESP::temperaturesensor_.have_sensors());
|
||||
return EMSESP::sensor_enabled();
|
||||
}
|
||||
|
||||
if (device_type == EMSdevice::DeviceType::ANALOGSENSOR) {
|
||||
return (EMSESP::analogsensor_.have_sensors());
|
||||
return EMSESP::analog_enabled();
|
||||
}
|
||||
|
||||
for (const auto & emsdevice : EMSESP::emsdevices) {
|
||||
@@ -573,14 +572,12 @@ bool Command::device_has_commands(const uint8_t device_type) {
|
||||
// list sensors and EMS devices
|
||||
void Command::show_devices(uuid::console::Shell & shell) {
|
||||
shell.printf("%s ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SYSTEM));
|
||||
|
||||
if (EMSESP::webSchedulerService.has_commands()) {
|
||||
shell.printf("%s ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SCHEDULER));
|
||||
}
|
||||
if (EMSESP::temperaturesensor_.have_sensors()) {
|
||||
shell.printf("%s ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::CUSTOM));
|
||||
shell.printf("%s ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SCHEDULER));
|
||||
if (EMSESP::sensor_enabled()) {
|
||||
shell.printf("%s ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::TEMPERATURESENSOR));
|
||||
}
|
||||
if (EMSESP::analogsensor_.have_sensors()) {
|
||||
if (EMSESP::analog_enabled()) {
|
||||
shell.printf("%s ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::ANALOGSENSOR));
|
||||
}
|
||||
|
||||
@@ -608,40 +605,37 @@ void Command::show_all(uuid::console::Shell & shell) {
|
||||
show(shell, EMSdevice::DeviceType::SYSTEM, true);
|
||||
|
||||
// show Custom
|
||||
if (EMSESP::webEntityService.has_commands()) {
|
||||
shell.print(COLOR_BOLD_ON);
|
||||
shell.print(COLOR_YELLOW);
|
||||
shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::CUSTOM));
|
||||
shell.println(COLOR_RESET);
|
||||
shell.printf(" info: %slists all values %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_RED);
|
||||
shell.println(COLOR_RESET);
|
||||
shell.printf(" commands: %slists all commands %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_RED);
|
||||
shell.print(COLOR_RESET);
|
||||
show(shell, EMSdevice::DeviceType::CUSTOM, true);
|
||||
}
|
||||
shell.print(COLOR_BOLD_ON);
|
||||
shell.print(COLOR_YELLOW);
|
||||
shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::CUSTOM));
|
||||
shell.println(COLOR_RESET);
|
||||
shell.printf(" info: %slists all values %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_RED);
|
||||
shell.println(COLOR_RESET);
|
||||
shell.printf(" commands: %slists all commands %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_RED);
|
||||
shell.print(COLOR_RESET);
|
||||
show(shell, EMSdevice::DeviceType::CUSTOM, true);
|
||||
|
||||
// show scheduler
|
||||
if (EMSESP::webSchedulerService.has_commands()) {
|
||||
shell.print(COLOR_BOLD_ON);
|
||||
shell.print(COLOR_YELLOW);
|
||||
shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SCHEDULER));
|
||||
shell.println(COLOR_RESET);
|
||||
shell.printf(" info: %slists all values %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_RED);
|
||||
shell.println(COLOR_RESET);
|
||||
shell.printf(" commands: %slists all commands %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_RED);
|
||||
shell.print(COLOR_RESET);
|
||||
show(shell, EMSdevice::DeviceType::SCHEDULER, true);
|
||||
}
|
||||
shell.print(COLOR_BOLD_ON);
|
||||
shell.print(COLOR_YELLOW);
|
||||
shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SCHEDULER));
|
||||
shell.println(COLOR_RESET);
|
||||
shell.printf(" info: %slists all values %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_RED);
|
||||
shell.println(COLOR_RESET);
|
||||
shell.printf(" commands: %slists all commands %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_RED);
|
||||
shell.print(COLOR_RESET);
|
||||
show(shell, EMSdevice::DeviceType::SCHEDULER, true);
|
||||
|
||||
// show sensors
|
||||
if (EMSESP::temperaturesensor_.have_sensors()) {
|
||||
if (EMSESP::sensor_enabled()) {
|
||||
shell.print(COLOR_BOLD_ON);
|
||||
shell.print(COLOR_YELLOW);
|
||||
shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::TEMPERATURESENSOR));
|
||||
shell.print(COLOR_RESET);
|
||||
show(shell, EMSdevice::DeviceType::TEMPERATURESENSOR, true);
|
||||
}
|
||||
if (EMSESP::analogsensor_.have_sensors()) {
|
||||
|
||||
if (EMSESP::analog_enabled()) {
|
||||
shell.print(COLOR_BOLD_ON);
|
||||
shell.print(COLOR_YELLOW);
|
||||
shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::ANALOGSENSOR));
|
||||
|
||||
@@ -342,7 +342,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
||||
DeviceValueNumOp::DV_NUMOP_DIV60,
|
||||
FL_(upTimeCompCooling),
|
||||
DeviceValueUOM::MINUTES);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
||||
&upTimeCompWw_,
|
||||
DeviceValueType::TIME,
|
||||
DeviceValueNumOp::DV_NUMOP_DIV60,
|
||||
@@ -362,7 +362,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsTotal_, DeviceValueType::ULONG, FL_(nrgConsTotal), DeviceValueUOM::KWH);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompTotal_, DeviceValueType::ULONG, FL_(nrgConsCompTotal), DeviceValueUOM::KWH);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompHeating_, DeviceValueType::ULONG, FL_(nrgConsCompHeating), DeviceValueUOM::KWH);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompWw_, DeviceValueType::ULONG, FL_(nrgConsCompWw), DeviceValueUOM::KWH);
|
||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &nrgConsCompWw_, DeviceValueType::ULONG, FL_(nrgConsCompWw), DeviceValueUOM::KWH);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompCooling_, DeviceValueType::ULONG, FL_(nrgConsCompCooling), DeviceValueUOM::KWH);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompPool_, DeviceValueType::ULONG, FL_(nrgConsCompPool), DeviceValueUOM::KWH);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxElecHeatNrgConsTotal_, DeviceValueType::ULONG, FL_(auxElecHeatNrgConsTotal), DeviceValueUOM::KWH);
|
||||
@@ -371,11 +371,11 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
||||
DeviceValueType::ULONG,
|
||||
FL_(auxElecHeatNrgConsHeating),
|
||||
DeviceValueUOM::KWH);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxElecHeatNrgConsWW_, DeviceValueType::ULONG, FL_(auxElecHeatNrgConsWW), DeviceValueUOM::KWH);
|
||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &auxElecHeatNrgConsWW_, DeviceValueType::ULONG, FL_(auxElecHeatNrgConsWW), DeviceValueUOM::KWH);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxElecHeatNrgConsPool_, DeviceValueType::ULONG, FL_(auxElecHeatNrgConsPool), DeviceValueUOM::KWH);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppTotal_, DeviceValueType::ULONG, FL_(nrgSuppTotal), DeviceValueUOM::KWH);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppHeating_, DeviceValueType::ULONG, FL_(nrgSuppHeating), DeviceValueUOM::KWH);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppWw_, DeviceValueType::ULONG, FL_(nrgSuppWw), DeviceValueUOM::KWH);
|
||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &nrgSuppWw_, DeviceValueType::ULONG, FL_(nrgSuppWw), DeviceValueUOM::KWH);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppCooling_, DeviceValueType::ULONG, FL_(nrgSuppCooling), DeviceValueUOM::KWH);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppPool_, DeviceValueType::ULONG, FL_(nrgSuppPool), DeviceValueUOM::KWH);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpPower_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpPower), DeviceValueUOM::KW);
|
||||
@@ -383,7 +383,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpActivity_, DeviceValueType::ENUM, FL_(enum_hpactivity), FL_(hpActivity), DeviceValueUOM::NONE);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpHeatingOn_, DeviceValueType::BOOL, FL_(hpHeatingOn), DeviceValueUOM::NONE);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpCoolingOn_, DeviceValueType::BOOL, FL_(hpCoolingOn), DeviceValueUOM::NONE);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpWwOn_, DeviceValueType::BOOL, FL_(hpWwOn), DeviceValueUOM::NONE);
|
||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &hpWwOn_, DeviceValueType::BOOL, FL_(hpWwOn), DeviceValueUOM::NONE);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpPoolOn_, DeviceValueType::BOOL, FL_(hpPoolOn), DeviceValueUOM::NONE);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpBrinePumpSpd_, DeviceValueType::UINT, FL_(hpBrinePumpSpd), DeviceValueUOM::PERCENT);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpSwitchValve_, DeviceValueType::BOOL, FL_(hpSwitchValve), DeviceValueUOM::NONE);
|
||||
@@ -466,7 +466,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
||||
FL_(maxHeatHeat),
|
||||
DeviceValueUOM::NONE,
|
||||
MAKE_CF_CB(set_maxHeatHeat));
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
||||
&maxHeatDhw_,
|
||||
DeviceValueType::ENUM,
|
||||
FL_(enum_maxHeat),
|
||||
@@ -750,7 +750,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
||||
register_device_value(
|
||||
DeviceValueTAG::TAG_BOILER_DATA_WW, &wwMaxPower_, DeviceValueType::UINT, FL_(wwMaxPower), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_ww_maxpower), 0, 254);
|
||||
register_device_value(
|
||||
DeviceValueTAG::TAG_BOILER_DATA_WW, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_maxtemp), 0, 70);
|
||||
DeviceValueTAG::TAG_BOILER_DATA_WW, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_maxtemp), 0, 80);
|
||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
||||
&wwCircPump_,
|
||||
DeviceValueType::BOOL,
|
||||
@@ -849,6 +849,62 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
||||
EMSESP::send_read_request(0x15, device_id); // read maintenance data on start (only published on change)
|
||||
EMSESP::send_read_request(0x1C, device_id); // read maintenance status on start (only published on change)
|
||||
EMSESP::send_read_request(0xC2, device_id); // read last errorcode on start (only published on errors)
|
||||
|
||||
|
||||
if (model() != EMS_DEVICE_FLAG_HEATPUMP) {
|
||||
register_telegram_type(0x04, "UBAFactory", true, MAKE_PF_CB(process_UBAFactory));
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nomPower_, DeviceValueType::UINT, FL_(nomPower), DeviceValueUOM::KW, MAKE_CF_CB(set_nomPower));
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||
&nrgHeat_,
|
||||
DeviceValueType::ULONG,
|
||||
DeviceValueNumOp::DV_NUMOP_DIV100,
|
||||
FL_(nrgHeat),
|
||||
DeviceValueUOM::KWH,
|
||||
MAKE_CF_CB(set_nrgHeat),
|
||||
0,
|
||||
10000000UL);
|
||||
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
|
||||
&nrgWw_,
|
||||
DeviceValueType::ULONG,
|
||||
DeviceValueNumOp::DV_NUMOP_DIV100,
|
||||
FL_(nrgWw),
|
||||
DeviceValueUOM::KWH,
|
||||
MAKE_CF_CB(set_nrgWw),
|
||||
0,
|
||||
10000000UL);
|
||||
|
||||
nrgHeatF_ = EMSESP::nvs_.getDouble(FL_(nrgHeat)[0], 0);
|
||||
nrgWwF_ = EMSESP::nvs_.getDouble(FL_(nrgWw)[0], 0);
|
||||
nomPower_ = EMSESP::nvs_.getUChar(FL_(nomPower)[0], 0);
|
||||
if (nrgHeatF_ < 0 || nrgHeatF_ >= EMS_VALUE_ULLONG_NOTSET) {
|
||||
nrgHeatF_ = 0;
|
||||
}
|
||||
if (nrgWwF_ < 0 || nrgWwF_ >= EMS_VALUE_ULLONG_NOTSET) {
|
||||
nrgWwF_ = 0;
|
||||
}
|
||||
if (nomPower_ == EMS_VALUE_UINT_NOTSET) {
|
||||
nomPower_ = 0;
|
||||
}
|
||||
store_energy();
|
||||
// update/publish the values
|
||||
has_update(nrgHeat_, (uint32_t)(nrgHeatF_ + 0.5));
|
||||
has_update(nrgWw_, (uint32_t)(nrgWwF_ + 0.5));
|
||||
has_update(&nomPower_);
|
||||
}
|
||||
}
|
||||
|
||||
void Boiler::store_energy() {
|
||||
// only write if something is changed
|
||||
if (nrgHeatF_ != EMSESP::nvs_.getDouble(FL_(nrgHeat)[0])) {
|
||||
EMSESP::nvs_.putDouble(FL_(nrgHeat)[0], nrgHeatF_);
|
||||
}
|
||||
if (nrgWwF_ != EMSESP::nvs_.getDouble(FL_(nrgWw)[0])) {
|
||||
EMSESP::nvs_.putDouble(FL_(nrgWw)[0], nrgWwF_);
|
||||
}
|
||||
if (nomPower_ != EMSESP::nvs_.getUChar(FL_(nomPower)[0])) {
|
||||
EMSESP::nvs_.putUChar(FL_(nomPower)[0], nomPower_);
|
||||
}
|
||||
// LOG_DEBUG("energy values stored");
|
||||
}
|
||||
|
||||
// Check if hot tap water or heating is active
|
||||
@@ -894,6 +950,56 @@ void Boiler::check_active() {
|
||||
Mqtt::queue_publish(F_(tapwater_active), Helpers::render_boolean(s, b));
|
||||
EMSESP::tap_water_active(b); // let EMS-ESP know, used in the Shower class
|
||||
}
|
||||
|
||||
// calculate energy for boiler 0x08 from stored modulation an time in units of 0.01 Wh
|
||||
if (model() != EMS_DEVICE_FLAG_HEATPUMP) {
|
||||
// remember values from last call
|
||||
static uint32_t powLastReadTime_ = uuid::get_uptime();
|
||||
static uint8_t heatBurnPow = 0;
|
||||
static uint8_t wwBurnPow = 0;
|
||||
static uint8_t lastSaveHour = 0;
|
||||
// store in units of 0.01 kWh, resolution needed: 0.01 Wh = 0.01 Ws / 3600 = (% * kW * ms) / 3600
|
||||
nrgHeatF_ += ((double)((uint32_t)heatBurnPow * nomPower_ * (uuid::get_uptime() - powLastReadTime_)) / 3600) / 1000UL;
|
||||
nrgWwF_ += ((double)((uint32_t)wwBurnPow * nomPower_ * (uuid::get_uptime() - powLastReadTime_)) / 3600) / 1000UL;
|
||||
has_update(nrgHeat_, (uint32_t)(nrgHeatF_ + 0.5));
|
||||
has_update(nrgWw_, (uint32_t)(nrgWwF_ + 0.5));
|
||||
// check for store values
|
||||
time_t now = time(nullptr);
|
||||
tm * tm_ = localtime(&now);
|
||||
if (tm_->tm_hour != lastSaveHour) {
|
||||
lastSaveHour = tm_->tm_hour;
|
||||
store_energy();
|
||||
} else if (curBurnPow_ == 0 && (heatBurnPow + wwBurnPow) > 0) { // on burner switch off
|
||||
store_energy();
|
||||
}
|
||||
// store new modulation and time
|
||||
heatBurnPow = heatingActive_ ? curBurnPow_ : 0;
|
||||
wwBurnPow = tapwaterActive_ ? curBurnPow_ : 0;
|
||||
powLastReadTime_ = uuid::get_uptime();
|
||||
}
|
||||
}
|
||||
|
||||
// 0x04
|
||||
// boiler(0x08) -W-> Me(0x0B), ?(0x04), data: 13 96 09 81 00 64 64 35 05 64 5A 22 00 00 00 00 00 00 00 00 B7
|
||||
// offset 4 - nominal Power kW, could be zero, 5 - min. Burner, 6 - max. Burner
|
||||
void Boiler::process_UBAFactory(std::shared_ptr<const Telegram> telegram) {
|
||||
// check for all wanted info in telegram
|
||||
if (telegram->offset > 4 || telegram->offset + telegram->message_length < 7) {
|
||||
return;
|
||||
}
|
||||
toggle_fetch(telegram->type_id, false); // only read once
|
||||
uint8_t min, max, nomPower;
|
||||
telegram->read_value(nomPower, 4);
|
||||
telegram->read_value(min, 5);
|
||||
telegram->read_value(max, 6);
|
||||
// set the value only if no nvs-value is set
|
||||
if (nomPower > 0 && nomPower_ == 0) {
|
||||
has_update(nomPower_, nomPower);
|
||||
}
|
||||
set_minmax(&burnMinPower_, 0, max);
|
||||
set_minmax(&burnMaxPower_, min, max);
|
||||
set_minmax(&wwMaxPower_, min, max);
|
||||
set_minmax(&selBurnPow_, 0, max);
|
||||
}
|
||||
|
||||
// 0x18
|
||||
@@ -936,7 +1042,9 @@ void Boiler::process_UBAMonitorFast(std::shared_ptr<const Telegram> telegram) {
|
||||
|
||||
has_update(telegram, serviceCodeNumber_, 20);
|
||||
|
||||
check_active(); // do a quick check to see if the hot water or heating is active
|
||||
if (telegram->offset <= 4 && telegram->offset + telegram->message_length > 5) {
|
||||
check_active(); // do a quick check to see if the hot water or heating is active
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1075,7 +1183,9 @@ void Boiler::process_UBAMonitorFastPlus(std::shared_ptr<const Telegram> telegram
|
||||
boilerState_ |= state & 0x04 ? 0x02 : 0;
|
||||
}
|
||||
|
||||
check_active(); // do a quick check to see if the hot water or heating is active
|
||||
if (telegram->offset <= 10 && telegram->offset + telegram->message_length > 11) {
|
||||
check_active(); // do a quick check to see if the hot water or heating is active
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2231,7 +2341,9 @@ bool Boiler::set_reset(const char * value, const int8_t id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (num == 1) {
|
||||
if (num == 0) {
|
||||
return true; // dash
|
||||
} else if (num == 1) {
|
||||
// LOG_INFO("Reset boiler maintenance message");
|
||||
write_command(0x05, 0x08, 0xFF, 0x1C);
|
||||
has_update(&reset_);
|
||||
@@ -2642,4 +2754,43 @@ bool Boiler::set_wwAltOpPrio(const char * value, const int8_t id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// energy counters. Setting an invalid value does not update, but trigger a store.
|
||||
bool Boiler::set_nrgHeat(const char * value, const int8_t id) {
|
||||
float v;
|
||||
if (!Helpers::value2float(value, v)) {
|
||||
return false;
|
||||
}
|
||||
if (v >= 0) {
|
||||
nrgHeatF_ = v * 100;
|
||||
has_update(nrgHeat_, (uint32_t)(nrgHeatF_ + 0.5));
|
||||
}
|
||||
store_energy();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Boiler::set_nrgWw(const char * value, const int8_t id) {
|
||||
float v;
|
||||
if (!Helpers::value2float(value, v)) {
|
||||
return false;
|
||||
}
|
||||
if (v >= 0) {
|
||||
nrgWwF_ = v * 100;
|
||||
has_update(nrgWw_, (uint32_t)(nrgWwF_ + 0.5));
|
||||
}
|
||||
store_energy();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Boiler::set_nomPower(const char * value, const int8_t id) {
|
||||
int v;
|
||||
if (!Helpers::value2number(value, v)) {
|
||||
return false;
|
||||
}
|
||||
if (v > 0 && v < EMS_VALUE_UINT_NOTSET) {
|
||||
has_update(nomPower_, (uint8_t)v);
|
||||
}
|
||||
store_energy();
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
@@ -36,6 +36,7 @@ class Boiler : public EMSdevice {
|
||||
}
|
||||
|
||||
void check_active();
|
||||
void store_energy();
|
||||
|
||||
uint8_t boilerState_ = EMS_VALUE_UINT_NOTSET; // Boiler state flag - FOR INTERNAL USE
|
||||
|
||||
@@ -258,6 +259,13 @@ class Boiler : public EMSdevice {
|
||||
uint8_t keepWarmTemp_;
|
||||
uint8_t setReturnTemp_;
|
||||
|
||||
// special
|
||||
double nrgHeatF_;
|
||||
double nrgWwF_;
|
||||
uint32_t nrgHeat_;
|
||||
uint32_t nrgWw_;
|
||||
uint8_t nomPower_;
|
||||
|
||||
/*
|
||||
// Hybrid heatpump with telegram 0xBB is readable and writeable in boiler and thermostat
|
||||
// thermostat always overwrites settings in boiler
|
||||
@@ -272,6 +280,7 @@ class Boiler : public EMSdevice {
|
||||
uint8_t tempDiffBoiler_; // relative temperature degrees
|
||||
*/
|
||||
|
||||
void process_UBAFactory(std::shared_ptr<const Telegram> telegram);
|
||||
void process_UBAParameterWW(std::shared_ptr<const Telegram> telegram);
|
||||
void process_UBAMonitorFast(std::shared_ptr<const Telegram> telegram);
|
||||
void process_UBATotalUptime(std::shared_ptr<const Telegram> telegram);
|
||||
@@ -468,6 +477,10 @@ class Boiler : public EMSdevice {
|
||||
bool set_delayBoiler(const char * value, const int8_t id);
|
||||
bool set_tempDiffBoiler(const char * value, const int8_t id);
|
||||
*/
|
||||
|
||||
bool set_nrgHeat(const char * value, const int8_t id);
|
||||
bool set_nrgWw(const char * value, const int8_t id);
|
||||
bool set_nomPower(const char * value, const int8_t id);
|
||||
};
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
@@ -843,6 +843,7 @@ void Thermostat::process_RC35wwTimer(std::shared_ptr<const Telegram> telegram) {
|
||||
if (telegram->type_id != 0x38) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (telegram->message_length + telegram->offset >= 92 && telegram->offset <= 87) {
|
||||
char data[sizeof(wwVacation_)];
|
||||
snprintf(data,
|
||||
|
||||
@@ -488,7 +488,7 @@ void EMSdevice::add_device_value(uint8_t tag, // to b
|
||||
uint8_t uom, // unit of measure from DeviceValueUOM
|
||||
const cmd_function_p f, // command function pointer
|
||||
int16_t min, // min allowed value
|
||||
uint16_t max // max allowed value
|
||||
uint32_t max // max allowed value
|
||||
) {
|
||||
// initialize the device value depending on it's type
|
||||
// ignoring DeviceValueType::CMD and DeviceValueType::TIME
|
||||
@@ -605,7 +605,7 @@ void EMSdevice::register_device_value(uint8_t tag,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max) {
|
||||
uint32_t max) {
|
||||
// create a multi-list from the options
|
||||
add_device_value(tag, value_p, type, nullptr, options_single, 0, name, uom, f, min, max);
|
||||
};
|
||||
@@ -628,7 +628,7 @@ void EMSdevice::register_device_value(uint8_t tag,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max) {
|
||||
uint32_t max) {
|
||||
add_device_value(tag, value_p, type, nullptr, nullptr, numeric_operator, name, uom, f, min, max);
|
||||
}
|
||||
|
||||
@@ -645,7 +645,7 @@ void EMSdevice::register_device_value(uint8_t tag,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max) {
|
||||
uint32_t max) {
|
||||
add_device_value(tag, value_p, type, nullptr, nullptr, 0, name, uom, f, min, max);
|
||||
};
|
||||
|
||||
@@ -660,7 +660,7 @@ void EMSdevice::register_device_value(uint8_t tag,
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max) {
|
||||
uint32_t max) {
|
||||
add_device_value(tag, value_p, type, options, nullptr, 0, name, uom, f, min, max);
|
||||
}
|
||||
|
||||
@@ -713,6 +713,17 @@ bool EMSdevice::has_command(const void * value_p) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
// set min and max
|
||||
void EMSdevice::set_minmax(const void * value_p, int16_t min, uint32_t max) {
|
||||
for (auto & dv : devicevalues_) {
|
||||
if (dv.value_p == value_p) {
|
||||
dv.min = min;
|
||||
dv.max = max;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// publish a single value on change
|
||||
void EMSdevice::publish_value(void * value_p) const {
|
||||
if (!Mqtt::publish_single() || value_p == nullptr) {
|
||||
@@ -939,7 +950,7 @@ void EMSdevice::generate_values_web(JsonObject & output) {
|
||||
}
|
||||
|
||||
int16_t dv_set_min;
|
||||
uint16_t dv_set_max;
|
||||
uint32_t dv_set_max;
|
||||
if (dv.get_min_max(dv_set_min, dv_set_max)) {
|
||||
obj["m"] = dv_set_min;
|
||||
obj["x"] = dv_set_max;
|
||||
@@ -1033,7 +1044,7 @@ void EMSdevice::generate_values_web_customization(JsonArray & output) {
|
||||
if (dv.has_cmd && (obj["v"].is<float>() || obj["v"].is<int>())) {
|
||||
// set the min and max values if there are any and if entity has a value
|
||||
int16_t dv_set_min;
|
||||
uint16_t dv_set_max;
|
||||
uint32_t dv_set_max;
|
||||
if (dv.get_min_max(dv_set_min, dv_set_max)) {
|
||||
obj["mi"] = dv_set_min;
|
||||
obj["ma"] = dv_set_max;
|
||||
@@ -1059,7 +1070,7 @@ void EMSdevice::generate_values_web_customization(JsonArray & output) {
|
||||
});
|
||||
}
|
||||
|
||||
void EMSdevice::set_climate_minmax(uint8_t tag, int16_t min, uint16_t max) {
|
||||
void EMSdevice::set_climate_minmax(uint8_t tag, int16_t min, uint32_t max) {
|
||||
for (auto & dv : devicevalues_) {
|
||||
if (dv.tag == tag && (strcmp(dv.short_name, FL_(haclimate[0])) == 0)) {
|
||||
if (dv.min != min || dv.max != max) {
|
||||
@@ -1074,7 +1085,7 @@ void EMSdevice::set_climate_minmax(uint8_t tag, int16_t min, uint16_t max) {
|
||||
|
||||
// set mask per device entity based on the id which is prefixed with the 2 char hex mask value
|
||||
// returns true if the entity has a mask set (not 0 the default)
|
||||
void EMSdevice::setCustomEntity(const std::string & entity_id) {
|
||||
void EMSdevice::setCustomizationEntity(const std::string & entity_id) {
|
||||
for (auto & dv : devicevalues_) {
|
||||
char entity_name[70];
|
||||
if (dv.tag < DeviceValueTAG::TAG_HC1) {
|
||||
@@ -1126,7 +1137,7 @@ void EMSdevice::setCustomEntity(const std::string & entity_id) {
|
||||
}
|
||||
|
||||
// populate a string vector with entities that have masks set or have a custom name
|
||||
void EMSdevice::getCustomEntities(std::vector<std::string> & entity_ids) {
|
||||
void EMSdevice::getCustomizationEntities(std::vector<std::string> & entity_ids) {
|
||||
for (const auto & dv : devicevalues_) {
|
||||
char name[100];
|
||||
name[0] = '\0';
|
||||
@@ -1236,7 +1247,7 @@ void EMSdevice::dump_value_info() {
|
||||
|
||||
// min/max range
|
||||
int16_t dv_set_min;
|
||||
uint16_t dv_set_max;
|
||||
uint32_t dv_set_max;
|
||||
if (dv.get_min_max(dv_set_min, dv_set_max)) {
|
||||
Serial.print(" (>=");
|
||||
Serial.print(dv_set_min);
|
||||
@@ -1473,7 +1484,7 @@ bool EMSdevice::get_value_info(JsonObject & output, const char * cmd, const int8
|
||||
// set the min and max only for commands
|
||||
if (dv.has_cmd) {
|
||||
int16_t dv_set_min;
|
||||
uint16_t dv_set_max;
|
||||
uint32_t dv_set_max;
|
||||
if (dv.get_min_max(dv_set_min, dv_set_max)) {
|
||||
json["min"] = dv_set_min;
|
||||
json["max"] = dv_set_max;
|
||||
@@ -1671,7 +1682,7 @@ bool EMSdevice::generate_values(JsonObject & output, const uint8_t tag_filter, c
|
||||
if (v < dv.min) {
|
||||
dv.min = v;
|
||||
dv.remove_state(DeviceValueState::DV_HA_CONFIG_CREATED);
|
||||
} else if (v > dv.max) {
|
||||
} else if (v > 0 && (uint32_t)v > dv.max) {
|
||||
dv.max = v;
|
||||
dv.remove_state(DeviceValueState::DV_HA_CONFIG_CREATED);
|
||||
}
|
||||
|
||||
@@ -155,6 +155,22 @@ class EMSdevice {
|
||||
}
|
||||
}
|
||||
|
||||
inline void has_update(uint16_t & value, uint16_t newvalue) {
|
||||
if (value != newvalue) {
|
||||
value = newvalue;
|
||||
has_update_ = true;
|
||||
publish_value((void *)&value);
|
||||
}
|
||||
}
|
||||
|
||||
inline void has_update(uint32_t & value, uint32_t newvalue) {
|
||||
if (value != newvalue) {
|
||||
value = newvalue;
|
||||
has_update_ = true;
|
||||
publish_value((void *)&value);
|
||||
}
|
||||
}
|
||||
|
||||
inline void has_enumupdate(std::shared_ptr<const Telegram> telegram, uint8_t & value, const uint8_t index, int8_t s = 0) {
|
||||
if (telegram->read_enumvalue(value, index, s)) {
|
||||
has_update_ = true;
|
||||
@@ -190,9 +206,9 @@ class EMSdevice {
|
||||
void list_device_entries(JsonObject & output) const;
|
||||
void add_handlers_ignored(const uint16_t handler);
|
||||
|
||||
void set_climate_minmax(uint8_t tag, int16_t min, uint16_t max);
|
||||
void setCustomEntity(const std::string & entity_id);
|
||||
void getCustomEntities(std::vector<std::string> & entity_ids);
|
||||
void set_climate_minmax(uint8_t tag, int16_t min, uint32_t max);
|
||||
void setCustomizationEntity(const std::string & entity_id);
|
||||
void getCustomizationEntities(std::vector<std::string> & entity_ids);
|
||||
|
||||
void register_telegram_type(const uint16_t telegram_type_id, const char * telegram_type_name, bool fetch, const process_function_p cb);
|
||||
bool handle_telegram(std::shared_ptr<const Telegram> telegram);
|
||||
@@ -216,7 +232,7 @@ class EMSdevice {
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max);
|
||||
uint32_t max);
|
||||
|
||||
void register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
@@ -226,7 +242,7 @@ class EMSdevice {
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max);
|
||||
uint32_t max);
|
||||
|
||||
void
|
||||
register_device_value(uint8_t tag, void * value_p, uint8_t type, const char * const ** options, const char * const * name, uint8_t uom, const cmd_function_p f);
|
||||
@@ -249,7 +265,7 @@ class EMSdevice {
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max);
|
||||
uint32_t max);
|
||||
|
||||
// single list of options
|
||||
void register_device_value(uint8_t tag,
|
||||
@@ -269,14 +285,14 @@ class EMSdevice {
|
||||
uint8_t uom,
|
||||
const cmd_function_p f,
|
||||
int16_t min,
|
||||
uint16_t max);
|
||||
uint32_t max);
|
||||
|
||||
// no options, optional function f
|
||||
void register_device_value(uint8_t tag, void * value_p, uint8_t type, const char * const * name, uint8_t uom, const cmd_function_p f = nullptr);
|
||||
|
||||
// no options, with min/max
|
||||
void
|
||||
register_device_value(uint8_t tag, void * value_p, uint8_t type, const char * const * name, uint8_t uom, const cmd_function_p f, int16_t min, uint16_t max);
|
||||
register_device_value(uint8_t tag, void * value_p, uint8_t type, const char * const * name, uint8_t uom, const cmd_function_p f, int16_t min, uint32_t max);
|
||||
|
||||
void write_command(const uint16_t type_id, const uint8_t offset, uint8_t * message_data, const uint8_t message_length, const uint16_t validate_typeid) const;
|
||||
void write_command(const uint16_t type_id, const uint8_t offset, const uint8_t value, const uint16_t validate_typeid) const;
|
||||
@@ -287,6 +303,7 @@ class EMSdevice {
|
||||
bool is_readable(const void * value_p) const;
|
||||
bool is_readonly(const std::string & cmd, const int8_t id) const;
|
||||
bool has_command(const void * value_p) const;
|
||||
void set_minmax(const void * value_p, int16_t min, uint32_t max);
|
||||
void publish_value(void * value_p) const;
|
||||
void publish_all_values();
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ DeviceValue::DeviceValue(uint8_t device_type,
|
||||
uint8_t uom,
|
||||
bool has_cmd,
|
||||
int16_t min,
|
||||
uint16_t max,
|
||||
uint32_t max,
|
||||
uint8_t state)
|
||||
: device_type(device_type)
|
||||
, tag(tag)
|
||||
@@ -261,7 +261,7 @@ bool DeviceValue::has_tag() const {
|
||||
// converts to signed int, which means rounding to an whole integer
|
||||
// returns false if there is no min/max needed
|
||||
// Types BOOL, ENUM, STRING and CMD are not used
|
||||
bool DeviceValue::get_min_max(int16_t & dv_set_min, uint16_t & dv_set_max) {
|
||||
bool DeviceValue::get_min_max(int16_t & dv_set_min, uint32_t & dv_set_max) {
|
||||
uint8_t fahrenheit = !EMSESP::system_.fahrenheit() ? 0 : (uom == DeviceValueUOM::DEGREES) ? 2 : (uom == DeviceValueUOM::DEGREES_R) ? 1 : 0;
|
||||
|
||||
// if we have individual limits set already, just do the conversion
|
||||
@@ -327,7 +327,7 @@ bool DeviceValue::get_custom_min(int16_t & val) {
|
||||
bool has_min = (min_pos != std::string::npos);
|
||||
uint8_t fahrenheit = !EMSESP::system_.fahrenheit() ? 0 : (uom == DeviceValueUOM::DEGREES) ? 2 : (uom == DeviceValueUOM::DEGREES_R) ? 1 : 0;
|
||||
if (has_min) {
|
||||
int v = Helpers::atoint(custom_fullname.substr(min_pos + 1).c_str());
|
||||
int16_t v = Helpers::atoint(custom_fullname.substr(min_pos + 1).c_str());
|
||||
if (fahrenheit) {
|
||||
v = (v - (32 * (fahrenheit - 1))) / 1.8; // reset to °C
|
||||
}
|
||||
@@ -340,12 +340,12 @@ bool DeviceValue::get_custom_min(int16_t & val) {
|
||||
}
|
||||
|
||||
// extract custom max from custom_fullname
|
||||
bool DeviceValue::get_custom_max(uint16_t & val) {
|
||||
bool DeviceValue::get_custom_max(uint32_t & val) {
|
||||
auto max_pos = custom_fullname.find('<');
|
||||
bool has_max = (max_pos != std::string::npos);
|
||||
uint8_t fahrenheit = !EMSESP::system_.fahrenheit() ? 0 : (uom == DeviceValueUOM::DEGREES) ? 2 : (uom == DeviceValueUOM::DEGREES_R) ? 1 : 0;
|
||||
if (has_max) {
|
||||
int v = Helpers::atoint(custom_fullname.substr(max_pos + 1).c_str());
|
||||
int32_t v = Helpers::atoint(custom_fullname.substr(max_pos + 1).c_str());
|
||||
if (fahrenheit) {
|
||||
v = (v - (32 * (fahrenheit - 1))) / 1.8; // reset to °C
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ class DeviceValue {
|
||||
uint8_t uom; // DeviceValueUOM::*
|
||||
bool has_cmd; // true if there is a Console/MQTT command which matches the short_name
|
||||
int16_t min; // min range
|
||||
uint16_t max; // max range
|
||||
uint32_t max; // max range
|
||||
uint8_t state; // DeviceValueState::*
|
||||
|
||||
DeviceValue(uint8_t device_type,
|
||||
@@ -175,16 +175,16 @@ class DeviceValue {
|
||||
uint8_t uom,
|
||||
bool has_cmd,
|
||||
int16_t min,
|
||||
uint16_t max,
|
||||
uint32_t max,
|
||||
uint8_t state);
|
||||
|
||||
bool hasValue() const;
|
||||
bool has_tag() const;
|
||||
bool get_min_max(int16_t & dv_set_min, uint16_t & dv_set_max);
|
||||
bool get_min_max(int16_t & dv_set_min, uint32_t & dv_set_max);
|
||||
|
||||
void set_custom_minmax();
|
||||
bool get_custom_min(int16_t & val);
|
||||
bool get_custom_max(uint16_t & val);
|
||||
bool get_custom_max(uint32_t & val);
|
||||
std::string get_custom_fullname() const;
|
||||
std::string get_fullname() const;
|
||||
static std::string get_name(std::string & entity);
|
||||
|
||||
@@ -32,13 +32,13 @@ ESP8266React EMSESP::esp8266React(&webServer, &dummyFS);
|
||||
WebSettingsService EMSESP::webSettingsService = WebSettingsService(&webServer, &dummyFS, EMSESP::esp8266React.getSecurityManager());
|
||||
WebCustomizationService EMSESP::webCustomizationService = WebCustomizationService(&webServer, &dummyFS, EMSESP::esp8266React.getSecurityManager());
|
||||
WebSchedulerService EMSESP::webSchedulerService = WebSchedulerService(&webServer, &dummyFS, EMSESP::esp8266React.getSecurityManager());
|
||||
WebEntityService EMSESP::webEntityService = WebEntityService(&webServer, &dummyFS, EMSESP::esp8266React.getSecurityManager());
|
||||
WebCustomEntityService EMSESP::webCustomEntityService = WebCustomEntityService(&webServer, &dummyFS, EMSESP::esp8266React.getSecurityManager());
|
||||
#else
|
||||
ESP8266React EMSESP::esp8266React(&webServer, &LittleFS);
|
||||
WebSettingsService EMSESP::webSettingsService = WebSettingsService(&webServer, &LittleFS, EMSESP::esp8266React.getSecurityManager());
|
||||
WebCustomizationService EMSESP::webCustomizationService = WebCustomizationService(&webServer, &LittleFS, EMSESP::esp8266React.getSecurityManager());
|
||||
WebSchedulerService EMSESP::webSchedulerService = WebSchedulerService(&webServer, &LittleFS, EMSESP::esp8266React.getSecurityManager());
|
||||
WebEntityService EMSESP::webEntityService = WebEntityService(&webServer, &LittleFS, EMSESP::esp8266React.getSecurityManager());
|
||||
WebCustomEntityService EMSESP::webCustomEntityService = WebCustomEntityService(&webServer, &LittleFS, EMSESP::esp8266React.getSecurityManager());
|
||||
#endif
|
||||
|
||||
WebStatusService EMSESP::webStatusService = WebStatusService(&webServer, EMSESP::esp8266React.getSecurityManager());
|
||||
@@ -69,6 +69,7 @@ System EMSESP::system_; // core system services
|
||||
TemperatureSensor EMSESP::temperaturesensor_; // Temperature sensors
|
||||
AnalogSensor EMSESP::analogsensor_; // Analog sensors
|
||||
Shower EMSESP::shower_; // Shower logic
|
||||
Preferences EMSESP::nvs_; // NV Storage
|
||||
|
||||
// static/common variables
|
||||
uint16_t EMSESP::watch_id_ = WATCH_ID_NONE; // for when log is TRACE. 0 means no trace set
|
||||
@@ -481,7 +482,7 @@ void EMSESP::publish_all(bool force) {
|
||||
publish_device_values(EMSdevice::DeviceType::MIXER);
|
||||
publish_other_values(); // switch and heat pump, ...
|
||||
webSchedulerService.publish();
|
||||
webEntityService.publish();
|
||||
webCustomEntityService.publish();
|
||||
publish_sensor_values(true); // includes temperature and analog sensors
|
||||
system_.send_heartbeat();
|
||||
}
|
||||
@@ -514,7 +515,7 @@ void EMSESP::publish_all_loop() {
|
||||
case 5:
|
||||
publish_other_values(); // switch and heat pump
|
||||
webSchedulerService.publish(true);
|
||||
webEntityService.publish(true);
|
||||
webCustomEntityService.publish(true);
|
||||
break;
|
||||
case 6:
|
||||
publish_sensor_values(true, true);
|
||||
@@ -605,7 +606,7 @@ void EMSESP::publish_other_values() {
|
||||
// publish_device_values(EMSdevice::DeviceType::ALERT);
|
||||
// publish_device_values(EMSdevice::DeviceType::PUMP);
|
||||
// publish_device_values(EMSdevice::DeviceType::GENERIC);
|
||||
webEntityService.publish();
|
||||
webCustomEntityService.publish();
|
||||
}
|
||||
|
||||
// publish both the temperature and analog sensor values
|
||||
@@ -657,7 +658,8 @@ void EMSESP::publish_response(std::shared_ptr<const Telegram> telegram) {
|
||||
buffer = nullptr;
|
||||
}
|
||||
|
||||
// builds json with the detail of each value, for a specific EMS device type or the temperature sensor
|
||||
// builds json with the detail of each value,
|
||||
// for a specific EMS device type or the sensors, scheduler and custom entities
|
||||
bool EMSESP::get_device_value_info(JsonObject & root, const char * cmd, const int8_t id, const uint8_t devicetype) {
|
||||
for (const auto & emsdevice : emsdevices) {
|
||||
if (emsdevice->device_type() == devicetype) {
|
||||
@@ -684,7 +686,7 @@ bool EMSESP::get_device_value_info(JsonObject & root, const char * cmd, const in
|
||||
|
||||
// own entities
|
||||
if (devicetype == DeviceType::CUSTOM) {
|
||||
return EMSESP::webEntityService.get_value_info(root, cmd);
|
||||
return EMSESP::webCustomEntityService.get_value_info(root, cmd);
|
||||
}
|
||||
|
||||
char error[100];
|
||||
@@ -895,7 +897,7 @@ bool EMSESP::process_telegram(std::shared_ptr<const Telegram> telegram) {
|
||||
}
|
||||
|
||||
// Check for custom entities reding this telegram
|
||||
webEntityService.get_value(telegram);
|
||||
webCustomEntityService.get_value(telegram);
|
||||
|
||||
// check for common types, like the Version(0x02)
|
||||
if (telegram->type_id == EMSdevice::EMS_TYPE_VERSION) {
|
||||
@@ -1414,7 +1416,7 @@ void EMSESP::scheduled_fetch_values() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
webEntityService.fetch();
|
||||
webCustomEntityService.fetch();
|
||||
no = 0;
|
||||
}
|
||||
}
|
||||
@@ -1485,6 +1487,7 @@ void EMSESP::start() {
|
||||
system_.system_restart();
|
||||
};
|
||||
|
||||
nvs_.begin("ems-esp");
|
||||
webSettingsService.begin(); // load EMS-ESP Application settings...
|
||||
|
||||
// do any system upgrades
|
||||
@@ -1497,7 +1500,7 @@ void EMSESP::start() {
|
||||
|
||||
webCustomizationService.begin(); // load the customizations
|
||||
webSchedulerService.begin(); // load the scheduler events
|
||||
webEntityService.begin(); // load the custom telegram reads
|
||||
webCustomEntityService.begin(); // load the custom telegram reads
|
||||
|
||||
// start telnet service if it's enabled
|
||||
// default idle is 10 minutes, default write timeout is 0 (automatic)
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#ifndef EMSESP_STANDALONE
|
||||
#include <uuid/telnet.h>
|
||||
#endif
|
||||
#include <Preferences.h>
|
||||
|
||||
#include <ESP8266React.h>
|
||||
|
||||
@@ -46,7 +47,7 @@
|
||||
#include "web/WebSchedulerService.h"
|
||||
#include "web/WebAPIService.h"
|
||||
#include "web/WebLogService.h"
|
||||
#include "web/WebEntityService.h"
|
||||
#include "web/WebCustomEntityService.h"
|
||||
|
||||
#include "emsdevicevalue.h"
|
||||
#include "emsdevice.h"
|
||||
@@ -225,6 +226,7 @@ class EMSESP {
|
||||
static Shower shower_;
|
||||
static RxService rxservice_;
|
||||
static TxService txservice_;
|
||||
static Preferences nvs_;
|
||||
|
||||
// web controllers
|
||||
static ESP8266React esp8266React;
|
||||
@@ -235,7 +237,7 @@ class EMSESP {
|
||||
static WebLogService webLogService;
|
||||
static WebCustomizationService webCustomizationService;
|
||||
static WebSchedulerService webSchedulerService;
|
||||
static WebEntityService webEntityService;
|
||||
static WebCustomEntityService webCustomEntityService;
|
||||
|
||||
private:
|
||||
static std::string device_tostring(const uint8_t device_id);
|
||||
|
||||
@@ -345,7 +345,7 @@ char * Helpers::render_value(char * result, const uint32_t value, const int8_t f
|
||||
}
|
||||
result[0] = '\0';
|
||||
uint32_t new_value = fahrenheit ? format ? value * 1.8 + 32 * format * (fahrenheit - 1) : value * 1.8 + 32 * (fahrenheit - 1) : value;
|
||||
char s[10] = {0};
|
||||
char s[14] = {0};
|
||||
|
||||
#ifndef EMSESP_STANDALONE
|
||||
if (!format) {
|
||||
@@ -354,6 +354,9 @@ char * Helpers::render_value(char * result, const uint32_t value, const int8_t f
|
||||
strlcpy(result, ltoa(new_value / format, s, 10), sizeof(s));
|
||||
strlcat(result, ".", sizeof(s));
|
||||
strlcat(result, itoa(((new_value % format) * 10) / format, s, 10), sizeof(s));
|
||||
if (format == 100) {
|
||||
strlcat(result, itoa(new_value % 10, s, 10), sizeof(s));
|
||||
}
|
||||
} else {
|
||||
strlcpy(result, ltoa(new_value * format * -1, s, 10), sizeof(s));
|
||||
}
|
||||
|
||||
@@ -68,9 +68,9 @@ MAKE_WORD_TRANSLATION(watch_cmd, "watch incoming telegrams", "Watch auf eingehen
|
||||
MAKE_WORD_TRANSLATION(publish_cmd, "publish all to MQTT", "Publiziere MQTT", "publiceer alles naar MQTT", "", "opublikuj wszystko na MQTT", "Publiser alt til MQTT", "", "Hepsini MQTTye gönder", "pubblica tutto su MQTT") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(system_info_cmd, "show system status", "Zeige System-Status", "toon systeemstatus", "", "pokaż status systemu", "vis system status", "", "Sistem Durumunu Göster", "visualizza stati di sistema") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(schedule_cmd, "enable schedule item", "Aktiviere Zeitplan", "activeer tijdschema item", "", "aktywuj wybrany harmonogram", "", "", "program öğesini etkinleştir", "abilitare l'elemento programmato") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(entity_cmd, "set custom value on ems", "Sende eigene Entitäten zu EMS", "verstuur custom waarde naar EMS", "", "wyślij własną wartość na EMS", "", "", "", "imposta valori personalizzati su EMS") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(commands_response, "get response", "Hole Antwort", "Verzoek om antwoord", "", "", "", "", "") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(coldshot_cmd, "send a cold shot of water", "", "", "", "", "", "", "", "") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(entity_cmd, "set custom value on ems", "Sende eigene Entitäten zu EMS", "verstuur custom waarde naar EMS", "", "wyślij własną wartość na EMS", "", "", "emp üzerinde özel değer ayarla", "imposta valori personalizzati su EMS") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(commands_response, "get response","Hole Antwort","Verzoek om antwoord", "", "", "", "gelen cevap", "") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(coldshot_cmd, "send a cold shot of water", "", "", "", "", "", "", "soğuk su gönder", "") // TODO translate
|
||||
|
||||
// tags
|
||||
MAKE_WORD_TRANSLATION(tag_boiler_data_ww, "dhw", "WW", "dhw", "VV", "CWU", "dhw", "ecs", "SKS", "dhw")
|
||||
@@ -197,13 +197,13 @@ MAKE_WORD_TRANSLATION(deltaP4, "deltaP-4", "deltaP-4", "deltaP-4", "", "", "delt
|
||||
MAKE_WORD_TRANSLATION(none, "none", "keine", "geen", "ingen", "brak", "ingen", "aucun", "hiçbiri", "nessuno")
|
||||
MAKE_WORD_TRANSLATION(hot_water, "hot water", "Warmwasser", "warm water", "varmvatten", "c.w.u.", "varmtvann", "eau chaude", "sıcak su", "acqua calda")
|
||||
MAKE_WORD_TRANSLATION(pool, "pool", "Pool", "zwembad", "pool", "basen", "basseng", "piscine", "havuz", "piscina")
|
||||
MAKE_WORD_TRANSLATION(outside_temp_alt, "outside temperature alt.", "Außentemp. alternativ", "alternatieve buitentemperatuur", "Alternativ utomhustemp.", "temp. zewn. alternat.", "alternativ utendørstemp.", "température extérieure alternative", "alternatif dış sıcaklık", "temperatura esterna alternativa") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(outside_temp_par, "outside temperature parallel", "Außentemp. parallel", "buitentemperatuur parallel", "Parallell utomhustemp.", "temp. zewn. równoległa", "parallell utendørstemp.", "température extérieure parallèle", "paralel dış sıcaklık", "temperatura esterna parallela") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(hp_prefered, "heatpump prefered", "Wärmepumpe bevorzugt", "voorkeur warmtepomp", "Värmepump föredraget", "preferowana pompa ciepła", "varmepumpe prioritert", "pompe à chaleur préférée", "tercih edilen pompa", "pompa di calore preferita") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(boiler_only, "boiler only", "nur Kessel", "uitsluitend cv ketel", "Värmepanna enbart", "tylko kocioł", "kun kjele", "chaudière uniquement", "sadece kazan", "solo caldaia") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(reduced_output, "reduced output", "Reduzierte Leistung", "gereduceerde output", "Reducerad produktion", "zmniejszona wydajność", "redusert ytelse", "sortie réduite", "düşürülmüş çıkış", "riduzione uscita") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(switchoff, "switch off hp", "WP ausschalten", "WP uitschakelen", "Värmepump avstängd", "wyłącz pompę ciepła", "slå av varmepumpe", "éteindre la PAC", "ısı pompasını kapat", "spegnimento pompa calore") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(perm, "perm. reduced", "perm. reduziert", "permanent gereduceerd", "Permanent reducerad", "stale zmniejszona wydajność", "permanent redusert", "réduction permanente", "sürekli azaltılmış", "riduzione permanente") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(outside_temp_alt, "outside temperature alt.", "Außentemp. alternativ", "alternatieve buitentemperatuur", "Alternativ utomhustemp.", "temp. zewn. alternat.", "alternativ utendørstemp.", "température extérieure alternative", "alternatif dış sıcaklık", "temperatura esterna alternativa")
|
||||
MAKE_WORD_TRANSLATION(outside_temp_par, "outside temperature parallel", "Außentemp. parallel", "buitentemperatuur parallel", "Parallell utomhustemp.", "temp. zewn. równoległa", "parallell utendørstemp.", "température extérieure parallèle", "paralel dış sıcaklık", "temperatura esterna parallela")
|
||||
MAKE_WORD_TRANSLATION(hp_prefered, "heatpump prefered", "Wärmepumpe bevorzugt", "voorkeur warmtepomp", "Värmepump föredraget", "preferowana pompa ciepła", "varmepumpe prioritert", "pompe à chaleur préférée", "tercih edilen pompa", "pompa di calore preferita")
|
||||
MAKE_WORD_TRANSLATION(boiler_only, "boiler only", "nur Kessel", "uitsluitend cv ketel", "Värmepanna enbart", "tylko kocioł", "kun kjele", "chaudière uniquement", "sadece kazan", "solo caldaia")
|
||||
MAKE_WORD_TRANSLATION(reduced_output, "reduced output", "Reduzierte Leistung", "gereduceerde output", "Reducerad produktion", "zmniejszona wydajność", "redusert ytelse", "sortie réduite", "düşürülmüş çıkış", "riduzione uscita")
|
||||
MAKE_WORD_TRANSLATION(switchoff, "switch off hp", "WP ausschalten", "WP uitschakelen", "Värmepump avstängd", "wyłącz pompę ciepła", "slå av varmepumpe", "éteindre la PAC", "ısı pompasını kapat", "spegnimento pompa calore")
|
||||
MAKE_WORD_TRANSLATION(perm, "perm. reduced", "perm. reduziert", "permanent gereduceerd", "Permanent reducerad", "stale zmniejszona wydajność", "permanent redusert", "réduction permanente", "sürekli azaltılmış", "riduzione permanente")
|
||||
|
||||
// thermostat
|
||||
MAKE_WORD_TRANSLATION(seltemp, "selTemp", "Solltemperatur", "doeltemperatuur", "Börtemperatur", "temperatura zadana", "innstilt temperatur", "consigne température", "ayarlanmış sıcaklık", "temperatura di consegna")
|
||||
@@ -284,7 +284,7 @@ MAKE_TRANSLATION(haclimate, "haclimate", "Discovery current room temperature", "
|
||||
// Entity translations: tag, mqtt, en, de, nl, sv, pl, no, fr, tr, it
|
||||
// Boiler
|
||||
MAKE_TRANSLATION(wwtapactivated, "wwtapactivated", "turn on/off", "Durchlauferhitzer aktiv", "zet aan/uit", "på/av", "system przygotowywania", "Varmtvann active", "ecs activée", "aç/kapa", "commuta on/off")
|
||||
MAKE_TRANSLATION(reset, "reset", "Reset", "Reset", "Reset", "Nollställ", "kasowanie komunikatu", "nullstill", "reset", "Sıfırla", "Reset")
|
||||
MAKE_TRANSLATION(reset, "reset", "reset", "Reset", "Reset", "Nollställ", "kasowanie komunikatu", "nullstill", "reset", "Sıfırla", "Reset")
|
||||
MAKE_TRANSLATION(oilPreHeat, "oilpreheat", "oil preheating", "Ölvorwärmung", "Olie voorverwarming", "Förvärmning olja", "podgrzewanie oleju", "oljeforvarming", "préchauffage de l'huile", "Yakıt Ön ısıtma devrede", "preriscaldamento olio")
|
||||
MAKE_TRANSLATION(heatingActive, "heatingactive", "heating active", "Heizen aktiv", "Verwarming actief", "Uppvärmning aktiv", "c.o. aktywne", "oppvarming aktiv", "chauffage actif", "ısıtma devrede", "riscaldamento attivo")
|
||||
MAKE_TRANSLATION(tapwaterActive, "tapwateractive", "tapwater active", "Warmwasser aktiv", "Warm water actief", "Varmvatten aktiv", "c.w.u. aktywne", "varmtvann aktiv", "eau chaude active", "sıcak kullanım suyu devrede", "acqua calda attiva")
|
||||
@@ -450,19 +450,19 @@ MAKE_TRANSLATION(fossileFactor, "fossilefactor", "fossile energy factor", "Energ
|
||||
MAKE_TRANSLATION(electricFactor, "electricfactor", "electric energy factor", "Energiefaktor elektrisch", "Energiefactor electrisch", "Elektrisk energifaktor", "udział energii elektrycznej", "elektrisk energifaktor", "facteur énergie électrique", "elektrik enerjisi faktörü", "fattore energia elettrica")
|
||||
MAKE_TRANSLATION(delayBoiler, "delayboiler", "delay boiler support", "Verzögerungs-Option", "Vertragingsoptie", "Fördröjningsoption", "opcja opóźnienia", "Fördörjningsoption", "option retardement chaudière", "kazan desteğini ötele", "opzione ritardo caldaia")
|
||||
MAKE_TRANSLATION(tempDiffBoiler, "tempdiffboiler", "temp diff boiler support", "Temperaturdifferenz-Option", "Verschiltemperatuuroptie", "Temperaturskillnadsoption", "opcja różnicy temperatur", "temperatursforskjell kjele", "option différence température", "sıcaklık farkı kazan desteği", "opzione differenza temperatura")
|
||||
MAKE_TRANSLATION(lowNoiseMode, "lownoisemode", "low noise mode", "Geräuscharmer Betrieb", "Stil bedrijf", "Tyst läge", "tryb cichy", "stillemodus", "mode faible bruit", "düşük ses modu", "modalità a basso rumore") // TODO translate
|
||||
MAKE_TRANSLATION(lowNoiseStart, "lownoisestart", "low noise starttime", "Start geräuscharmer Betrieb", "Start stil bedrijf", "Tyst läge starttid", "początek trybu cichego", "stille modu starttid", "heure démarrage faible bruit", "düşük ses başlangıç", "ora di avvio a basso rumore") // TODO translate
|
||||
MAKE_TRANSLATION(lowNoiseStop, "lownoisestop", "low noise stoptime", "Stopp geräuscharmer Betrieb", "Stop stil bedrijf", "Tyst läge stopptid", "koniec trybu cichego", "stille modus stopptid", "heure arrêt faible bruit", "düşük ses bitiş", "ora di arresto funzionamento silenzioso") // TODO translate
|
||||
MAKE_TRANSLATION(energyPriceGas, "energypricegas", "energy price gas", "Energiepreis Gas", "Energieprijs gas", "Gaspris", "cena energii z gazu", "energipris gass", "prix énergie gaz", "gaz enerjisi fiyatı", "prezzo energia gas") // TODO translate
|
||||
MAKE_TRANSLATION(energyPriceEl, "energypriceel", "energy price electric", "Energiepreis Eletrizität", "energieprijs electriciteit", "Elpris", "cena energii elektrycznej", "strømpris", "prix énergie électrique", "elektrik enerjisi fiyatı", "prezzo energia elettrica") // TODO translate
|
||||
MAKE_TRANSLATION(energyPricePV, "energyfeedpv", "feed in PV", "PV Einspeisevergütung", "PV teruglevertarief", "PV Energi", "zasilanie energią PV", "strømpris PV", "alimentation PV", "giren güneş enerjisi", "energia fotovoltaico") // TODO translate
|
||||
MAKE_TRANSLATION(hybridDHW, "hybriddhw", "hybrid DHW", "Hybrid Warmwasser", "Hybride ww", "Hybridläge varmvatten", "hybrydowa c.w.u.", "hybridmodus varmtvann", "ecs hybride", "hibrit SKS", "ACS ibrida") // TODO translate
|
||||
MAKE_TRANSLATION(airPurgeMode, "airpurgemode", "air purge mode", "Luftspülung", "Luchtzuivering", "Luftreningsläge", "tryb oczyszczania powietrza", "luftsrensningsmodus", "mode purge air", "hava temizleme modu", "modalita spurgo aria") // TODO translate
|
||||
MAKE_TRANSLATION(heatPumpOutput, "heatpumpoutput", "heatpump output", "WP Leistung", "WP output", "Värmepumpseffekt", "moc wyjściowa pompy ciepła", "varmepumpeeffekt", "sortie pompe à chaleur", "ısı pompası çıkışı", "prestazione pompa calore") // TODO translate
|
||||
MAKE_TRANSLATION(coolingCircuit, "coolingcircuit", "cooling circuit", "Kühlkreislauf", "Koelcircuit", "Kylkrets", "obwód chłodzący", "kjølekrets", "circuit refroidissement", "soğutma devresi", "circuito raffreddante") // TODO translate
|
||||
MAKE_TRANSLATION(compStartMod, "compstartmod", "compressor start modulation", "Kompressor Startleistung", "Beginvermogen compressor", "Kompressor startmodulering", "początkowa modulacja sprężarki", "kompressor startmodulering", "modulation démarrage compresseur", "kazan başlangıç modülasyonu", "avvio modulazione compressore") // TODO translate
|
||||
MAKE_TRANSLATION(heatDrainPan, "heatdrainpan", "heat drain pan", "Wärmeausgleichsgefäß", "Vereffeningsvat", "Uppvärm. dränering", "zbiornik wyrównawczy ciepła", "oppvarming drenering", "bac récupération chaleur", "ısı tahliye tablası", "serbatoio scarico condensa") // TODO translate
|
||||
MAKE_TRANSLATION(heatCable, "heatcable", "heating cable", "Heizband", "heating cable", "värmekabel", "przewód grzejny", "varmekabel", "câble chauffant", "ısıtma kablosu", "cavo riscaldante") // TODO translate
|
||||
MAKE_TRANSLATION(lowNoiseMode, "lownoisemode", "low noise mode", "Geräuscharmer Betrieb", "Stil bedrijf", "Tyst läge", "tryb cichy", "stillemodus", "mode faible bruit", "düşük ses modu", "modalità a basso rumore")
|
||||
MAKE_TRANSLATION(lowNoiseStart, "lownoisestart", "low noise starttime", "Start geräuscharmer Betrieb", "Start stil bedrijf", "Tyst läge starttid", "początek trybu cichego", "stille modu starttid", "heure démarrage faible bruit", "düşük ses başlangıç", "ora di avvio a basso rumore")
|
||||
MAKE_TRANSLATION(lowNoiseStop, "lownoisestop", "low noise stoptime", "Stopp geräuscharmer Betrieb", "Stop stil bedrijf", "Tyst läge stopptid", "koniec trybu cichego", "stille modus stopptid", "heure arrêt faible bruit", "düşük ses bitiş", "ora di arresto funzionamento silenzioso")
|
||||
MAKE_TRANSLATION(energyPriceGas, "energypricegas", "energy price gas", "Energiepreis Gas", "Energieprijs gas", "Gaspris", "cena energii z gazu", "energipris gass", "prix énergie gaz", "gaz enerjisi fiyatı", "prezzo energia gas")
|
||||
MAKE_TRANSLATION(energyPriceEl, "energypriceel", "energy price electric", "Energiepreis Eletrizität", "energieprijs electriciteit", "Elpris", "cena energii elektrycznej", "strømpris", "prix énergie électrique", "elektrik enerjisi fiyatı", "prezzo energia elettrica")
|
||||
MAKE_TRANSLATION(energyPricePV, "energyfeedpv", "feed in PV", "PV Einspeisevergütung", "PV teruglevertarief", "PV Energi", "zasilanie energią PV", "strømpris PV", "alimentation PV", "giren güneş enerjisi", "energia fotovoltaico")
|
||||
MAKE_TRANSLATION(hybridDHW, "hybriddhw", "hybrid DHW", "Hybrid Warmwasser", "Hybride ww", "Hybridläge varmvatten", "hybrydowa c.w.u.", "hybridmodus varmtvann", "ecs hybride", "hibrit SKS", "ACS ibrida")
|
||||
MAKE_TRANSLATION(airPurgeMode, "airpurgemode", "air purge mode", "Luftspülung", "Luchtzuivering", "Luftreningsläge", "tryb oczyszczania powietrza", "luftsrensningsmodus", "mode purge air", "hava temizleme modu", "modalita spurgo aria")
|
||||
MAKE_TRANSLATION(heatPumpOutput, "heatpumpoutput", "heatpump output", "WP Leistung", "WP output", "Värmepumpseffekt", "moc wyjściowa pompy ciepła", "varmepumpeeffekt", "sortie pompe à chaleur", "ısı pompası çıkışı", "prestazione pompa calore")
|
||||
MAKE_TRANSLATION(coolingCircuit, "coolingcircuit", "cooling circuit", "Kühlkreislauf", "Koelcircuit", "Kylkrets", "obwód chłodzący", "kjølekrets", "circuit refroidissement", "soğutma devresi", "circuito raffreddante")
|
||||
MAKE_TRANSLATION(compStartMod, "compstartmod", "compressor start modulation", "Kompressor Startleistung", "Beginvermogen compressor", "Kompressor startmodulering", "początkowa modulacja sprężarki", "kompressor startmodulering", "modulation démarrage compresseur", "kazan başlangıç modülasyonu", "avvio modulazione compressore")
|
||||
MAKE_TRANSLATION(heatDrainPan, "heatdrainpan", "heat drain pan", "Wärmeausgleichsgefäß", "Vereffeningsvat", "Uppvärm. dränering", "zbiornik wyrównawczy ciepła", "oppvarming drenering", "bac récupération chaleur", "ısı tahliye tablası", "serbatoio scarico condensa")
|
||||
MAKE_TRANSLATION(heatCable, "heatcable", "heating cable", "Heizband", "heating cable", "värmekabel", "przewód grzejny", "varmekabel", "câble chauffant", "ısıtma kablosu", "cavo riscaldante")
|
||||
|
||||
// alternative heatsource AM200
|
||||
MAKE_TRANSLATION(aCylTopTemp, "cyltoptemp", "cylinder top temperature", "Speichertemperatur Oben", "Buffer temperatuur boven", "Cylindertemperatur Toppen", "temperatura na górze cylindra", "beredertemperatur topp", "température haut cylindre", "silindir üst yüzey sıcaklığı", "temperatura superiore accumulo")
|
||||
@@ -500,10 +500,15 @@ MAKE_TRANSLATION(blockTerm, "blockterm", "config of block terminal", "Konfig. Sp
|
||||
MAKE_TRANSLATION(blockHyst, "blockhyst", "hyst. for boiler block", "Hysterese Sperrmodus", "Hysterese blokeerterminal", "Hysteres Blockeringsmodul", "tryb blokowania histerezy", "hystrese blokkeringsmodus", "hyst. Blocage chaudière", "kazan blok geçikmesi", "modalità blocco isteresi")
|
||||
MAKE_TRANSLATION(releaseWait, "releasewait", "boiler release wait time", "Wartezeit Kessel-Freigabe", "Wachttijd ketel vrijgave", "Väntetid Frisläppning", "czas oczekiwania na zwolnienie kotła", "kjele frigjøringsventetid", "temps attente libération chaudière", "kazan tahliyesi bekleme süresi", "tempo di attesa sblocco caldaia")
|
||||
|
||||
// energy
|
||||
MAKE_TRANSLATION(nrgHeat, "nrgheat", "energy heating", "Energie Heizen", "", "", "", "", "", "ısıtma enerjisi", "") // TODO translate
|
||||
MAKE_TRANSLATION(nrgWw, "nrgww", "energy dhw", "Energie Warmwasser", "", "", "", "", "", "sıcak kullanım suyu enerjisi", "") // TODO translate
|
||||
MAKE_TRANSLATION(nomPower, "nompower", "nominal Power", "Brennerleistung", "", "", "", "", "", "nominal güç", "") // TODO translate
|
||||
|
||||
// HIU
|
||||
MAKE_TRANSLATION(netFlowTemp, "netflowtemp", "heat network flow temp", "System Vorlauftemperatur", "Netto aanvoertemperatuur", "", "", "", "", "", "temperatura di mandata della rete di riscaldamento")
|
||||
MAKE_TRANSLATION(cwFlowRate, "cwflowrate", "cold water flow rate", "Kaltwasser Durchfluss", "Stroomsnelheid koud water ", "", "", "", "", "", "portata acqua fredda")
|
||||
MAKE_TRANSLATION(keepWarmTemp, "keepwarmtemp", "keep warm temperature", "Warmhaltetemperatur", "Warmhoudtemperatuur", "", "", "", "", "", "mantenere la temperatura calda")
|
||||
MAKE_TRANSLATION(netFlowTemp, "netflowtemp", "heat network flow temp", "System Vorlauftemperatur", "Netto aanvoertemperatuur", "", "", "", "", "ısıtma şebekesi akış derecesi", "temperatura di mandata della rete di riscaldamento") // TODO translate
|
||||
MAKE_TRANSLATION(cwFlowRate, "cwflowrate", "cold water flow rate", "Kaltwasser Durchfluss", "Stroomsnelheid koud water ", "", "", "", "", "soğuk su akış hızı", "portata acqua fredda") // TODO translate
|
||||
MAKE_TRANSLATION(keepWarmTemp, "keepwarmtemp", "keep warm temperature","Warmhaltetemperatur", "Warmhoudtemperatuur", "", "", "", "", "sıcaklığı koruma derecesi", "mantenere la temperatura calda") // TODO translate
|
||||
|
||||
// the following are dhw for the boiler and automatically tagged with 'dhw'
|
||||
MAKE_TRANSLATION(wwSelTemp, "wwseltemp", "selected temperature", "gewählte Temperatur", "Geselecteerd temperatuur", "Vald Temperatur", "temperatura wyższa/komfort", "valgt temperatur", "température sélectionnée", "seçili sıcaklık", "temperatura selezionata")
|
||||
@@ -550,20 +555,20 @@ MAKE_TRANSLATION(wwOneTimeKey, "wwonetimekey", "one time key function", "Einmall
|
||||
MAKE_TRANSLATION(wwSolarTemp, "wwsolartemp", "solar boiler temperature", "Solarboiler Temperatur", "Zonneboiler temperatuur", "Solpanel Temp", "temperatura zasobnika solarnego", "solpaneltemp", "température chaudière solaire", "güneş enerjisi kazan sıcaklığı", "temperatura pannello solare")
|
||||
|
||||
// mqtt values / commands
|
||||
MAKE_TRANSLATION(switchtime, "switchtime", "program switchtime", "Programm Schaltzeit", "Programma schakeltijd", "Program Bytestid", "program czasowy", "programbyttetid", "heure commutation programme", "", "ora commutazione programmata") // TODO translate
|
||||
MAKE_TRANSLATION(switchtime1, "switchtime1", "own1 program switchtime", "Programm 1 Schaltzeit", "Schakeltijd programma 1", "Program 1 Bytestid", "program przełączania 1", "byttetidprogram 1", "heure de commutation programme 1", "", "ora commutazione programma 1") // TODO translate
|
||||
MAKE_TRANSLATION(switchtime2, "switchtime2", "own2 program switchtime", "Programm 2 Schaltzeit", "Schakeltijd programma 2", "Program 2 Bytestid", "program przełączania 2", "byttetid program 2", "heure de changement programme 2", "", "ora commutazione programma 2") // TODO translate
|
||||
MAKE_TRANSLATION(wwswitchtime, "wwswitchtime", "program switchtime", "Programm Schaltzeit", "Warm water programma schakeltijd", "Varmvattenprogram Bytestid", "program czasowy", "byttetid varmtvannsprogram", "heure commutation programme", "", "Tempo di commutazione del programma") // TODO translate
|
||||
MAKE_TRANSLATION(wwcircswitchtime, "wwcircswitchtime", "circulation program switchtime", "Zirculationsprogramm Schaltzeit", "Schakeltijd circulatieprogramma", "Cirkulationsprogram Bytestid", "program cyrkulacji", "byttetid sirkulasjonsprogram", "heure commutation programme circulation", "", "ora commutazione programma circolazione") // TODO translate
|
||||
MAKE_TRANSLATION(switchtime, "switchtime", "program switchtime", "Programm Schaltzeit", "Programma schakeltijd", "Program Bytestid", "program czasowy", "programbyttetid", "heure commutation programme", "program değiştirme süresi", "ora commutazione programmata")
|
||||
MAKE_TRANSLATION(switchtime1, "switchtime1", "own1 program switchtime", "Programm 1 Schaltzeit", "Schakeltijd programma 1", "Program 1 Bytestid", "program przełączania 1", "byttetidprogram 1", "heure de commutation programme 1", "program1 değiştirme süresi", "ora commutazione programma 1")
|
||||
MAKE_TRANSLATION(switchtime2, "switchtime2", "own2 program switchtime", "Programm 2 Schaltzeit", "Schakeltijd programma 2", "Program 2 Bytestid", "program przełączania 2", "byttetid program 2", "heure de changement programme 2", "program1 değiştirme süresi", "ora commutazione programma 2")
|
||||
MAKE_TRANSLATION(wwswitchtime, "wwswitchtime", "program switchtime", "Programm Schaltzeit", "Warm water programma schakeltijd", "Varmvattenprogram Bytestid", "program czasowy", "byttetid varmtvannsprogram", "heure commutation programme", "sıcak kullanıom suyu program değiştirme süresi", "Tempo di commutazione del programma")
|
||||
MAKE_TRANSLATION(wwcircswitchtime, "wwcircswitchtime", "circulation program switchtime", "Zirculationsprogramm Schaltzeit", "Schakeltijd circulatieprogramma", "Cirkulationsprogram Bytestid", "program cyrkulacji", "byttetid sirkulasjonsprogram", "heure commutation programme circulation", "sirkülasyon program değiştirme süresi", "ora commutazione programma circolazione")
|
||||
MAKE_TRANSLATION(dateTime, "datetime", "date/time", "Datum/Zeit", "Datum/Tijd", "Datum/Tid", "data i godzina", "dato/tid", "date/heure", "zaman/saat", "Data/Ora")
|
||||
MAKE_TRANSLATION(errorCode, "errorcode", "error code", "Fehlernummer", "Foutmeldingscode", "Felkod", "kod błędu", "feikode", "code erreur", "hata kodu", "codice errore")
|
||||
MAKE_TRANSLATION(ibaMainDisplay, "display", "display", "Anzeige", "Display", "Display", "wyświetlacz", "skjerm", "affichage", "ekran", "Display")
|
||||
MAKE_TRANSLATION(ibaLanguage, "language", "language", "Sprache", "Taal", "Sprak", "język", "språk", "langue", "dil", "Lingua")
|
||||
MAKE_TRANSLATION(ibaClockOffset, "clockoffset", "clock offset", "Uhrkorrektur", "Klokcorrectie", "Tidskorrigering", "korekta zegara", "tidskorrigering", "offset horloge", "saat farkı", "correzione orario")
|
||||
MAKE_TRANSLATION(ibaBuildingType, "building", "building type", "Gebäudetyp", "Type gebouw", "Byggnadstyp", "typ budynku", "bygningstype", "type bâtiment", "bina tipi", "tipo di edificio") // TODO translate
|
||||
MAKE_TRANSLATION(heatingPID, "heatingpid", "heating PID", "Heizungs-PID", "PID verwarming", "Uppvärmning PID", "PID ogrzewania", "oppvarmings PID", "PID chauffage", "PID ısınıyor", "PID-riscaldamento") // TODO translate
|
||||
MAKE_TRANSLATION(ibaCalIntTemperature, "intoffset", "internal temperature offset", "Korrektur interner Temperatur", "Offset interne temperatuur", "Korrigering interntemperatur", "korekta temperatury w pomieszczeniu", "Korrigering interntemperatur", "offset température interne", "iç sıcaklık artışı", "scostamento della temperatura interna") // TODO translate
|
||||
MAKE_TRANSLATION(ibaMinExtTemperature, "minexttemp", "minimal external temperature", "min. Aussentemperatur", "Min. buitentemperatuur", "Min Extern Temperatur", "minimalna miejscowa temperatura zewnętrzna", "minimal eksterntemperatur", "température extérieure minimale", "en düşük sış sıcaklık", "temperatura esterna minima") // TODO translate
|
||||
MAKE_TRANSLATION(ibaBuildingType, "building", "building type", "Gebäudetyp", "Type gebouw", "Byggnadstyp", "typ budynku", "bygningstype", "type bâtiment", "bina tipi", "tipo di edificio")
|
||||
MAKE_TRANSLATION(heatingPID, "heatingpid", "heating PID", "Heizungs-PID", "PID verwarming", "Uppvärmning PID", "PID ogrzewania", "oppvarmings PID", "PID chauffage", "PID ısınıyor", "PID-riscaldamento")
|
||||
MAKE_TRANSLATION(ibaCalIntTemperature, "intoffset", "internal temperature offset", "Korrektur interner Temperatur", "Offset interne temperatuur", "Korrigering interntemperatur", "korekta temperatury w pomieszczeniu", "Korrigering interntemperatur", "offset température interne", "iç sıcaklık artışı", "scostamento della temperatura interna")
|
||||
MAKE_TRANSLATION(ibaMinExtTemperature, "minexttemp", "minimal external temperature", "min. Aussentemperatur", "Min. buitentemperatuur", "Min Extern Temperatur", "minimalna miejscowa temperatura zewnętrzna", "minimal eksterntemperatur", "température extérieure minimale", "en düşük sış sıcaklık", "temperatura esterna minima")
|
||||
MAKE_TRANSLATION(backlight, "backlight", "key backlight", "Gegenlicht", "Toetsverlichting", "Bakgrundsbelysning", "podświetlenie klawiatury", "bakgrunnsbelysning", "rétroéclairage touches", "tuş takımı aydınlatması", "retroilluminazione dei tasti")
|
||||
MAKE_TRANSLATION(damping, "damping", "damping outdoor temperature", "Dämpfung der Außentemperatur", "Demping buitentemperatuur", "Utomhustemperatur dämpning", "tłumienie temperatury zewnętrznej", "demping av utetemperatur", "température extérieure minimale", "dış sıcaklığın sönümlenmesi", "smorzamento della temperatura esterna")
|
||||
MAKE_TRANSLATION(tempsensor1, "inttemp1", "temperature sensor 1", "Temperatursensor 1", "Temperatuursensor 1", "Temperatursensor 1", "czujnik temperatury 1", "temperatursensor 1", "sonde température 1", "sıcaklık sensörü 1", "sensore temperatura 1")
|
||||
@@ -576,13 +581,13 @@ MAKE_TRANSLATION(autodst, "autodst", "automatic change daylight saving time", "a
|
||||
MAKE_TRANSLATION(preheating, "preheating", "preheating in the clock program", "Vorheizen im Zeitprogramm", "Voorverwarming in het klokprogramma", "Förvärmning i tidsprogram", "podgrzewanie w programie czasowym", "forvarming i tidsprogram", "préchauffage dans programme horloge", "saat programında ön ısıtma", "preriscaldamento nel programma orologio")
|
||||
MAKE_TRANSLATION(offtemp, "offtemp", "temperature when mode is off", "Temperatur bei AUS", "Temperatuur bij UIT", "Temperatur Avslagen", "temperatura w trybie \"wył.\"", "temperatur avslått", "température lorsque mode désactivé", "mod kapalı iken sıcaklık", "temperatura quando la modalità è disattivata")
|
||||
MAKE_TRANSLATION(mixingvalves, "mixingvalves", "mixing valves", "Mischventile", "Mengkleppen", "Blandningsventiler", "zawory mieszające", "blandeventiler", "vannes mélange", "karışım vanaları", "valvole miscela")
|
||||
MAKE_TRANSLATION(pvEnableWw, "pvenableww", "enable raise dhw", "aktiviere Anhebung WW", "Verhoging WW activeren", "", "podwyższenie c.w.u. z PV", "aktivere hevet temperatur bereder", "", "", "abilitare aumento ACS") // TODO translate
|
||||
MAKE_TRANSLATION(pvRaiseHeat, "pvraiseheat", "raise heating with PV", "Anhebung Heizen mit PV", "Verwarmen met PV activeren", "", "podwyższenie grzania z PV", "heve varmen med solpanel", "", "", "Aumentare il riscaldamento con il solare") // TODO translate
|
||||
MAKE_TRANSLATION(pvLowerCool, "pvlowercool", "lower cooling with PV", "Kühlabsenkung mit PV", "Verlagen koeling met PV activeren", "", "obniżenie chłodzenia z PV", "nedre kjøling solpanel", "", "", "Riduzione del raffreddamento con il solare") // TODO translate
|
||||
MAKE_TRANSLATION(pvEnableWw, "pvenableww", "enable raise dhw", "aktiviere Anhebung WW", "Verhoging WW activeren", "", "podwyższenie c.w.u. z PV", "aktivere hevet temperatur bereder", "", "sıcak kullanım suyu yükseltmeyi etkinleştir", "abilitare aumento ACS") // TODO translate
|
||||
MAKE_TRANSLATION(pvRaiseHeat, "pvraiseheat", "raise heating with PV", "Anhebung Heizen mit PV", "Verwarmen met PV activeren", "", "podwyższenie grzania z PV", "heve varmen med solpanel", "", "ısıtmayı G.E. İle yükselt", "Aumentare il riscaldamento con il solare") // TODO translate
|
||||
MAKE_TRANSLATION(pvLowerCool, "pvlowercool", "lower cooling with PV", "Kühlabsenkung mit PV", "Verlagen koeling met PV activeren", "", "obniżenie chłodzenia z PV", "nedre kjøling solpanel", "", "soğutmayı G.E. İle düşür", "Riduzione del raffreddamento con il solare") // TODO translate
|
||||
// thermostat ww
|
||||
MAKE_TRANSLATION(wwMode, "wwmode", "mode", "Modus", "Modus", "Läge", "tryb pracy", "modus", "mode", "mod", "modalità")
|
||||
MAKE_TRANSLATION(wwSetTempLow, "wwsettemplow", "set low temperature", "untere Solltemperatur", "Onderste streeftemperatuur", "Nedre Börvärde", "zadana temperatura obniżona", "nedre settverdi", "réglage température basse", "hedef düşük sıcaklık", "imposta bassa temperatura")
|
||||
MAKE_TRANSLATION(wwWhenModeOff, "wwwhenmodeoff", "when thermostat mode off", "bei Thermostatmodus AUS", "Als Thermostaat op UIT", "när Termostatläge är AV", "gdy wyłączono na termostacie", "når modus er av", "lorsque mode thermostat off", "", "quando termostato modalita OFF")
|
||||
MAKE_TRANSLATION(wwWhenModeOff, "wwwhenmodeoff", "when thermostat mode off", "bei Thermostatmodus AUS", "Als Thermostaat op UIT", "när Termostatläge är AV", "gdy wyłączono na termostacie", "når modus er av", "lorsque mode thermostat off", "termostat modu kapalı olduğunda", "quando termostato modalita OFF")
|
||||
MAKE_TRANSLATION(wwExtra1, "wwextra1", "circuit 1 extra", "Kreis 1 Extra", "Circuit 1 extra", "Krets 1 Extra", "obieg dodatkowy 1", "ekstra krets 1", "circuit 1 extra", "devre 1 ekstra", "Circuito 1 extra")
|
||||
MAKE_TRANSLATION(wwExtra2, "wwextra2", "circuit 2 extra", "Kreis 2 Extra", "Circuit 2 extra", "Kets 2 Extra", "obieg dodatkowy 2", "ekstra krets 2", "circuit 2 extra", "devre 2 ekstra", "Circuito 2 extra")
|
||||
MAKE_TRANSLATION(wwCharge, "wwcharge", "charge", "Laden", "Laden", "Ladda", "grzanie", "lade", "charge", "doldurma", "carica")
|
||||
@@ -609,14 +614,14 @@ MAKE_TRANSLATION(nighttemp, "nighttemp", "night temperature", "Nachttemperatur",
|
||||
MAKE_TRANSLATION(nighttemp2, "nighttemp", "night temperature T1", "Nachttemperatur T1", "Nachttemperatuur T1", "Nattemperatur T1", "temperatura w nocy T1", "nattemperatur T1", "température nuit T1", "gece sıcaklığı T1", "temperatura notturna T1")
|
||||
MAKE_TRANSLATION(ecotemp, "ecotemp", "eco temperature", "eco Temperatur", "Temperatuur eco", "Eko-temperatur", "temperatura w trybie eko", "øko temperatur", "température éco", "eko sıcaklık", "Temperatura eco")
|
||||
MAKE_TRANSLATION(manualtemp, "manualtemp", "manual temperature", "manuelle Temperatur", "Temperatuur handmatig", "Temperatur Manuell", "temperatura ustawiona ręcznie", "manuell temperatur", "température manuelle", "manuel sıcaklık", "temperatura manuale")
|
||||
MAKE_TRANSLATION(tempautotemp, "tempautotemp", "temporary set temperature automode", "temporäre Solltemperatur", "Streeftemperatuur automodus tijdelijk", "Temporär Aktivering av Auto-läge", "zadana temperatura w pomieszczenia w trybie \"auto\" (tymczasowa)", "temporær valgt temp i automodus", "température temporaire mode automatique", "", "impostare temporaneamente temperatura automatica")
|
||||
MAKE_TRANSLATION(remoteseltemp, "remoteseltemp", "temporary set temperature from remote", "temporäre Solltemperatur Remote", "Temperatuur van afstandsbedieding", "Temperatur från fjärruppkoppling", "zadana zdalnie temperatura a pomieszczeniu (tymczasowa)", "temporær valgt temp fra fjernbetjening", "température temporaire depuis télécommande", "", "Temperatura temporanea da remoto")
|
||||
MAKE_TRANSLATION(tempautotemp, "tempautotemp", "temporary set temperature automode", "temporäre Solltemperatur", "Streeftemperatuur automodus tijdelijk", "Temporär Aktivering av Auto-läge", "zadana temperatura w pomieszczenia w trybie \"auto\" (tymczasowa)", "temporær valgt temp i automodus", "température temporaire mode automatique", "geçici ayarlı sıcaklık otomatik mod", "impostare temporaneamente temperatura automatica")
|
||||
MAKE_TRANSLATION(remoteseltemp, "remoteseltemp", "temporary set temperature from remote", "temporäre Solltemperatur Remote", "Temperatuur van afstandsbedieding", "Temperatur från fjärruppkoppling", "zadana zdalnie temperatura a pomieszczeniu (tymczasowa)", "temporær valgt temp fra fjernbetjening", "température temporaire depuis télécommande", "geçici ayarlı sıcaklık uzaktan", "Temperatura temporanea da remoto")
|
||||
MAKE_TRANSLATION(comforttemp, "comforttemp", "comfort temperature", "Komforttemperatur", "Comforttemperatuur", "Komforttemperatur", "temperatura w trybie komfort", "komforttemperatur", "température confort", "konfor sıcaklığı", "temperatura comfort")
|
||||
MAKE_TRANSLATION(summertemp, "summertemp", "summer temperature", "Sommertemperatur", "Zomertemperatuur", "Sommartemperatur", "temperatura przełączania lato/zima", "Sommertemperatur", "température été", "yaz sıcaklığı", "temperatura estiva")
|
||||
MAKE_TRANSLATION(designtemp, "designtemp", "design temperature", "Auslegungstemperatur", "Ontwerptemperatuur", "Design-temperatur", "temperatura projektowa", "designtemperatur", "température conception", "", "temperatura predefinita")
|
||||
MAKE_TRANSLATION(designtemp, "designtemp", "design temperature", "Auslegungstemperatur", "Ontwerptemperatuur", "Design-temperatur", "temperatura projektowa", "designtemperatur", "température conception", "özel sıcaklık", "temperatura predefinita")
|
||||
MAKE_TRANSLATION(offsettemp, "offsettemp", "offset temperature", "Temperaturanhebung", "Temperatuur offset", "Temperaturkorrigering", "korekta temperatury", "temperaturkorrigering", "température offset", "artış sıcaklığı", "aumento della temperatura")
|
||||
MAKE_TRANSLATION(minflowtemp, "minflowtemp", "min flow temperature", "min Vorlauftemperatur", "Minimale aanvoertemperatuur", "Min Flödestemperatur", "minimalna temperatura zasilania", "min turtemperatur", "température min flux", "minimun akış sıcaklığı", "temperatura minima di mandata") // TODO translate
|
||||
MAKE_TRANSLATION(maxflowtemp, "maxflowtemp", "max flow temperature", "max Vorlauftemperatur", "Maximale aanvoertemperatuur", "Max Flödestemperatur", "maksymalna temperatura zasilania", "maks turtemperatur", "température max flux", "maksimum akış sıcaklığı", "temperatura massima di mandata") // TODO translate
|
||||
MAKE_TRANSLATION(minflowtemp, "minflowtemp", "min flow temperature", "min Vorlauftemperatur", "Minimale aanvoertemperatuur", "Min Flödestemperatur", "minimalna temperatura zasilania", "min turtemperatur", "température min flux", "minimun akış sıcaklığı", "temperatura minima di mandata")
|
||||
MAKE_TRANSLATION(maxflowtemp, "maxflowtemp", "max flow temperature", "max Vorlauftemperatur", "Maximale aanvoertemperatuur", "Max Flödestemperatur", "maksymalna temperatura zasilania", "maks turtemperatur", "température max flux", "maksimum akış sıcaklığı", "temperatura massima di mandata")
|
||||
MAKE_TRANSLATION(roominfluence, "roominfluence", "room influence", "Raumeinfluss", "Ruimteinvloed", "Rumspåverkan", "wpływ pomieszczenia", "rominnflytelse", "influence pièce", "oda etkisi", "influenza della camera")
|
||||
MAKE_TRANSLATION(roominfl_factor, "roominflfactor", "room influence factor", "Raumeinflussfaktor", "Factor ruimteinvloed", "Rumspåverkansfaktor", "współczynnik wpływu pomieszczenia", "rominnflytelsesfaktor", "facteur d'influence pièce", "oda etkisi faktörü", "fattore influenza camera")
|
||||
MAKE_TRANSLATION(curroominfl, "curroominfl", "current room influence", "aktueller Raumeinfluss", "Huidige ruimteinvloed", "Aktuell Rumspåverkan", "aktualny wpływ pomieszczenia", "gjeldende rominnflytelse", "influence actuelle pièce", "güncel oda etkisi", "fattore corrente influenza camera")
|
||||
@@ -635,28 +640,29 @@ MAKE_TRANSLATION(party, "party", "party time", "Partyzeit", "Partytijd", "Partyt
|
||||
MAKE_TRANSLATION(holidaytemp, "holidaytemp", "holiday temperature", "Urlaubstemperatur", "Vakantietemperatuur", "Helgtemperatur", "temperatura w trybie urlopowym", "ferietemperatur", "température vacances", "tatil sıcaklığı", "temperatura festiva")
|
||||
MAKE_TRANSLATION(summermode, "summermode", "summer mode", "Sommerbetrieb", "Zomerbedrijf", "Sommarläge", "aktualny tryb lato/zima", "sommermodus", "mode été", "yaz modu", "funzionamento estivo")
|
||||
MAKE_TRANSLATION(holidaymode, "holidaymode", "holiday mode", "Urlaubsbetrieb", "Vakantiebedrijf", "Helgläge", "tryb urlopowy", "feriemodus", "mode vacances", "tatil modu", "modalita vacanze")
|
||||
MAKE_TRANSLATION(flowtempoffset, "flowtempoffset", "flow temperature offset for mixer", "Vorlauftemperaturanhebung", "Mixer aanvoertemperatuur offset", "Temperaturkorrigering Flödestemp. Blandningsventil", "korekta temperatury przepływu dla miksera", "temperaturkorrigering av blandingsventil", "décalage température de bascule pour mélangeur", "", "aumento della temperatura di ritorno")
|
||||
MAKE_TRANSLATION(reducemode, "reducemode", "reduce mode", "Absenkmodus", "Gereduceerde modus", "Reducerat Läge", "tryb zredukowany/obniżony", "redusert modus", "mode réduction", "", "modalità assente")
|
||||
MAKE_TRANSLATION(noreducetemp, "noreducetemp", "no reduce below temperature", "Durchheizen unter", "Reduceermodus onderbreken onder", "Inaktivera reducering under", "bez redukcji poniżej temperatury", "inaktiver redusert nedre temp", "pas de réduction en dessous température", "", "non ridurre temperatura sotto")
|
||||
MAKE_TRANSLATION(reducetemp, "reducetemp", "off/reduce switch temperature", "Absenkmodus unter", "Onderste afschakeltemperatuur", "Avslag/Reducera under", "tryb zredukowany poniżej temperatury", "nedre avstengningstemperatur", "arrêt/réduction température bascule", "", "interruttore riduzione temperatura")
|
||||
MAKE_TRANSLATION(vacreducetemp, "vacreducetemp", "vacations off/reduce switch temperature", "Urlaub Absenkmodus unter", "Vakantiemodus onderste afschakeltemperatuur", "Helg Avslag/Reducering under", "tryb urlopowy poniżej temperatury", "feriemodus nedre utkoblingstemperatur", "vacances – arrêt/réduction température bascule", "", "interruttore riduzione temperatura vacanze")
|
||||
MAKE_TRANSLATION(vacreducemode, "vacreducemode", "vacations reduce mode", "Urlaub Absenkmodus", "Vakantie afschakelmodus", "Helg reduceringsläge", "redukcja w trakcie urlopu", "ferieavstengningsmodus", "mode réduction vacances", "", "modalita riduzione vacanze")
|
||||
MAKE_TRANSLATION(flowtempoffset, "flowtempoffset", "flow temperature offset for mixer", "Vorlauftemperaturanhebung", "Mixer aanvoertemperatuur offset", "Temperaturkorrigering Flödestemp. Blandningsventil", "korekta temperatury przepływu dla miksera", "temperaturkorrigering av blandingsventil", "décalage température de bascule pour mélangeur", "karıştırıcı için akış sıcaklığı farkı", "aumento della temperatura di ritorno")
|
||||
MAKE_TRANSLATION(reducemode, "reducemode", "reduce mode", "Absenkmodus", "Gereduceerde modus", "Reducerat Läge", "tryb zredukowany/obniżony", "redusert modus", "mode réduction", "düşürme modu", "modalità assente")
|
||||
MAKE_TRANSLATION(noreducetemp, "noreducetemp", "no reduce below temperature", "Durchheizen unter", "Reduceermodus onderbreken onder", "Inaktivera reducering under", "bez redukcji poniżej temperatury", "inaktiver redusert nedre temp", "pas de réduction en dessous température", "bu sıcaklığın altına düşürme", "non ridurre temperatura sotto")
|
||||
MAKE_TRANSLATION(reducetemp, "reducetemp", "off/reduce switch temperature", "Absenkmodus unter", "Onderste afschakeltemperatuur", "Avslag/Reducera under", "tryb zredukowany poniżej temperatury", "nedre avstengningstemperatur", "arrêt/réduction température bascule", "sıcaklık kapama/düşürme modu", "interruttore riduzione temperatura")
|
||||
MAKE_TRANSLATION(vacreducetemp, "vacreducetemp", "vacations off/reduce switch temperature", "Urlaub Absenkmodus unter", "Vakantiemodus onderste afschakeltemperatuur", "Helg Avslag/Reducering under", "tryb urlopowy poniżej temperatury", "feriemodus nedre utkoblingstemperatur", "vacances – arrêt/réduction température bascule", "tatil sıcaklık kapama/düşürme modu", "interruttore riduzione temperatura vacanze")
|
||||
MAKE_TRANSLATION(vacreducemode, "vacreducemode", "vacations reduce mode", "Urlaub Absenkmodus", "Vakantie afschakelmodus", "Helg reduceringsläge", "redukcja w trakcie urlopu", "ferieavstengningsmodus", "mode réduction vacances", "tail düşürme modu", "modalita riduzione vacanze")
|
||||
MAKE_TRANSLATION(nofrostmode, "nofrostmode", "nofrost mode", "Frostschutz Modus", "Vorstbeveiligingsmodus", "Frostskyddsläge", "temperatura wiodąca dla ochrony przed zamarzaniem", "frostbeskyttelsesmodus", "mode protection gel", "donma koruması modu", "Modalità protezione antigelo")
|
||||
MAKE_TRANSLATION(remotetemp, "remotetemp", "room temperature from remote", "Raumtemperatur Remote", "Ruimtetemperatuur van afstandsbediening", "Rumstemperatur från fjärr", "temperatura w pomieszczeniu (z termostatu)", "romstemperatur fra fjernbetjening", "température pièce depuis télécommande", "", "temperatura ambiente da remoto")
|
||||
MAKE_TRANSLATION(remotetemp, "remotetemp", "room temperature from remote", "Raumtemperatur Remote", "Ruimtetemperatuur van afstandsbediening", "Rumstemperatur från fjärr", "temperatura w pomieszczeniu (z termostatu)", "romstemperatur fra fjernbetjening", "température pièce depuis télécommande", "uzaktan oda sıcaklığı", "temperatura ambiente da remoto")
|
||||
MAKE_TRANSLATION(remotehum, "remotehum", "room humidity from remote", "Raumfeuchte Remote", "", "", "", "", "", "uzaktan kumandadan oda nemi", "") // TODO translate
|
||||
MAKE_TRANSLATION(wwHolidays, "wwholidays", "holiday dates", "Feiertage", "Feestdagen", "Helgdagar", "dni świąteczne", "feriedager varmtvann", "dates vacances", "tatil günleri", "feste pubbliche")
|
||||
MAKE_TRANSLATION(wwVacations, "wwvacations", "vacation dates", "Urlaubstage", "Vakantiedagen", "Semesterdatum Varmvatten", "dni urlopowe", "ferie dato varmtvann", "dates vacances", "izin günleri", "date vacanze")
|
||||
MAKE_TRANSLATION(holidays, "holidays", "holiday dates", "Feiertage", "Feestdagen", "Helgdatum", "święta", "helligdager", "dates vacances", "tatil günleri", "date feste pubbliche")
|
||||
MAKE_TRANSLATION(vacations, "vacations", "vacation dates", "Urlaubstage", "Vakantiedagen", "Semesterdatum", "urlop", "feriedager", "dates vacances", "izin günleri", "date vacanze")
|
||||
MAKE_TRANSLATION(wwprio, "wwprio", "dhw priority", "WW-Vorrang", "Prioriteit warm water", "Prioritera Varmvatten", "priorytet dla c.w.u.", "prioroter varmtvann", "priorité ecs", "", "priorita acqua calda ")
|
||||
MAKE_TRANSLATION(wwprio, "wwprio", "dhw priority", "WW-Vorrang", "Prioriteit warm water", "Prioritera Varmvatten", "priorytet dla c.w.u.", "prioroter varmtvann", "priorité ecs", "sıcak kullanım suyu önceliği", "priorita acqua calda ")
|
||||
MAKE_TRANSLATION(nofrostmode1, "nofrostmode1", "nofrost mode", "Frostschutz", "Vorstbeveiligingsmodus", "Frostskyddsläge", "ochrona przed zamarzaniem", "frostbeskyttelse", "mode protection gel", "donma koruması modu 1", "modalita protezione antigelo")
|
||||
MAKE_TRANSLATION(reducehours, "reducehours", "duration for nighttemp", "Dauer Nachttemp.", "Duur nachtverlaging", "Timmar Nattsänkning", "czas trwania trybu nocnego", "timer nattsenkning", "durée température nuit", "gece sıcaklığı süresi", "durata temperatura notturna")
|
||||
MAKE_TRANSLATION(reduceminutes, "reduceminutes", "remaining time for nightmode", "Restzeit Nachttemp.", "Resterende tijd nachtverlaging", "Återstående Tid Nattläge", "czas do końca trybu nocnego", "gjenværende tid i nattstilling", "temps restant mode nuit", "gece modu için kalan süre", "temperatura notturna residua")
|
||||
MAKE_TRANSLATION(switchonoptimization, "switchonoptimization", "switch-on optimization", "Einschaltoptimierung", "Inschakeloptimalisering", "Växlingsoptimering", "optymalizacja załączania", "slå på optimalisering", "optimisation mise en marche", "", "ottimizzazione all'accensione")
|
||||
MAKE_TRANSLATION(switchonoptimization, "switchonoptimization", "switch-on optimization", "Einschaltoptimierung", "Inschakeloptimalisering", "Växlingsoptimering", "optymalizacja załączania", "slå på optimalisering", "optimisation mise en marche", "optimizasyonu aç", "ottimizzazione all'accensione")
|
||||
|
||||
MAKE_TRANSLATION(hpmode, "hpmode", "HP Mode", "WP Modus", "Modus warmtepomp", "", "", "", "", "", "Modalità Termopompa")
|
||||
MAKE_TRANSLATION(dewoffset, "dewoffset", "dew point offset", "Taupunkt Differenz", "Offset dauwpunt", "", "", "", "", "", "differenza del punto di rugiada")
|
||||
MAKE_TRANSLATION(roomtempdiff, "roomtempdiff", "room temp difference", "Raumtemperatur Differenz", "Verschiltemperatuur kamertemp", "", "", "", "", "", "differenza temperatura ambiente")
|
||||
MAKE_TRANSLATION(hpminflowtemp, "hpminflowtemp", "HP min. flow temp.", "WP minimale Vorlauftemperatur", "Minimale aanvoertemperatuur WP", "", "", "", "", "", "temperatura minima di mandata")
|
||||
MAKE_TRANSLATION(hpmode, "hpmode", "HP Mode", "WP Modus", "Modus warmtepomp", "", "", "", "", "yüksek güç modu", "Modalità Termopompa") // TODO translate
|
||||
MAKE_TRANSLATION(dewoffset, "dewoffset", "dew point offset", "Taupunkt Differenz", "Offset dauwpunt", "", "", "", "", "çiğ noktası göreli", "differenza del punto di rugiada") // TODO translate
|
||||
MAKE_TRANSLATION(roomtempdiff, "roomtempdiff", "room temp difference", "Raumtemperatur Differenz", "Verschiltemperatuur kamertemp", "", "", "", "", "oda sıcaklığı farkı", "differenza temperatura ambiente") // TODO translate
|
||||
MAKE_TRANSLATION(hpminflowtemp, "hpminflowtemp", "HP min. flow temp.", "WP minimale Vorlauftemperatur", "Minimale aanvoertemperatuur WP", "", "", "", "", "yüksek güç minimum akış sıcaklığı", "temperatura minima di mandata") // TODO translate
|
||||
MAKE_TRANSLATION(hpcooling, "cooling", "cooling", "Kühlen", "Koelen", "Kyler", "chłodzenie", "kjøling", "refroidissement", "soğuma", "raffreddamento")
|
||||
|
||||
// heatpump
|
||||
@@ -682,22 +688,22 @@ MAKE_TRANSLATION(poolShunt, "poolshunt", "pool shunt open/close (0% = pool / 100
|
||||
MAKE_TRANSLATION(hydrTemp, "hydrTemp", "hydraulic header temperature", "Verteilertemperatur", "Temperatuur open verdeler", "Fördelartemperatur", "temperatura kolektora hydraulicznego", "Fordelertemperatur", "température collecteur hydraulique", "hidrolik başlık sıcaklığı ", "temperatura del collettore")
|
||||
|
||||
// solar
|
||||
MAKE_TRANSLATION(cylMiddleTemp, "cylmiddletemp", "cylinder middle temperature (TS3)", "Speichertemperatur Mitte (TS3)", "Zonneboilertemperatuur midden (TS3)", "Cylindertemperatur Mitten (TS3)", "temperatura w środku zasobnika (TS3)", "beredertemperatur i midten (TS3)", "température moyenne cylindre (TS3)", "", "temperatura di conservazione media accumulo (TS3)")
|
||||
MAKE_TRANSLATION(retHeatAssist, "retheatassist", "return temperature heat assistance (TS4)", "Rücklaufanhebungs-Temp. (TS4)", "Retourtemperatuur verwarmingsassistentie (TS4)", "Returtemperatur värmestöd (TS4)", "temperatura powrotu wspomagania grzania (TS4)", "returtemperatur varmestøtte (TS4)", "température retour de assistance thermique (TS4)", "", "temperatura ritorno scambiatore (TS4)")
|
||||
MAKE_TRANSLATION(m1Valve, "heatassistvalve", "heat assistance valve (M1)", "Ventil Heizungsunterstützung (M1)", "Klep verwarmingsassistentie (M1)", "Uppvärmningsstöd Ventil (M1)", "zawór wspomagania grzania (M1)", "varmehjelpsventil (M1)", "vanne assistance thermique (M1)", "", "valvola scambiatore (M1)")
|
||||
MAKE_TRANSLATION(m1Power, "heatassistpower", "heat assistance valve power (M1)", "Ventilleistung Heizungsunterstützung (M1)", "Vermogen klep verwarmingsassistentie (M1)", "Uppvärmningsstöd Ventil Effekt (M1)", "moc zaworu wspomagania grzania (M1)", "varmehjelpsventileffekt (M1)", "puissance vanne assistance thermique (M1)", "", "potenza valvola scambiatore (M1)")
|
||||
MAKE_TRANSLATION(cylMiddleTemp, "cylmiddletemp", "cylinder middle temperature (TS3)", "Speichertemperatur Mitte (TS3)", "Zonneboilertemperatuur midden (TS3)", "Cylindertemperatur Mitten (TS3)", "temperatura w środku zasobnika (TS3)", "beredertemperatur i midten (TS3)", "température moyenne cylindre (TS3)", "orta depolama sıcaklığı (TS3)", "temperatura di conservazione media accumulo (TS3)")
|
||||
MAKE_TRANSLATION(retHeatAssist, "retheatassist", "return temperature heat assistance (TS4)", "Rücklaufanhebungs-Temp. (TS4)", "Retourtemperatuur verwarmingsassistentie (TS4)", "Returtemperatur värmestöd (TS4)", "temperatura powrotu wspomagania grzania (TS4)", "returtemperatur varmestøtte (TS4)", "température retour de assistance thermique (TS4)", "geri dönüş sıcaklığı artışı", "temperatura ritorno scambiatore (TS4)")
|
||||
MAKE_TRANSLATION(m1Valve, "heatassistvalve", "heat assistance valve (M1)", "Ventil Heizungsunterstützung (M1)", "Klep verwarmingsassistentie (M1)", "Uppvärmningsstöd Ventil (M1)", "zawór wspomagania grzania (M1)", "varmehjelpsventil (M1)", "vanne assistance thermique (M1)", "ısıtma yardım vanası (M1)", "valvola scambiatore (M1)")
|
||||
MAKE_TRANSLATION(m1Power, "heatassistpower", "heat assistance valve power (M1)", "Ventilleistung Heizungsunterstützung (M1)", "Vermogen klep verwarmingsassistentie (M1)", "Uppvärmningsstöd Ventil Effekt (M1)", "moc zaworu wspomagania grzania (M1)", "varmehjelpsventileffekt (M1)", "puissance vanne assistance thermique (M1)", "ısıtma yardım vanası gücü (M1)", "potenza valvola scambiatore (M1)")
|
||||
MAKE_TRANSLATION(pumpMinMod, "pumpminmod", "minimum pump modulation", "minimale Pumpenmodulation", "Minimale pompmodulatie", "Min Pumpmodulering", "minimalna modulacja pompy", "minimum pumpmodulering", "modulation minimale pompe", "minimum pompa modülasyonu", "modulazione minima pompa")
|
||||
MAKE_TRANSLATION(maxFlow, "maxflow", "maximum solar flow", "maximaler Durchfluss", "Maximale doorstroom solar", "Max Flöde Solpanel", "maksymalny przepływ solarów", "maks strømming solpanel ", "débit solaire maximum", "minimum güneş akışı", "portata massima solare")
|
||||
MAKE_TRANSLATION(solarPower, "solarpower", "actual solar power", "aktuelle Solarleistung", "Huidig solar vermogen", "Aktuellt Sol-effekt", "aktualna moc solarów", "aktuell soleffekt", "puissance solaire réelle", "gerçek güneş gücü", "potenza attuale solare")
|
||||
MAKE_TRANSLATION(solarPumpTurnonDiff, "turnondiff", "pump turn on difference", "Einschalthysterese Pumpe", "Inschakelhysterese pomp", "Aktiveringshysteres Pump", "histereza załączenia pompy", "slå på hysteresepumpe", "différence activation pompe", "", "isteresi di accensione pompa")
|
||||
MAKE_TRANSLATION(solarPumpTurnoffDiff, "turnoffdiff", "pump turn off difference", "Ausschalthysterese Pumpe", "Uitschakelhysterese pomp", "Avslagshysteres Pump", "histereza włączenia pompy", "slå av hysteresepumpe", "différence arrêt pompe", "", "isteresi di spegnimento pompa")
|
||||
MAKE_TRANSLATION(maxFlow, "maxflow", "maximum solar flow", "maximaler Durchfluss", "Maximale doorstroom solar", "Max Flöde Solpanel", "maksymalny przepływ solarów", "maks strømming solpanel ", "débit solaire maximum", "minimum G.E. akışı", "portata massima solare")
|
||||
MAKE_TRANSLATION(solarPower, "solarpower", "actual solar power", "aktuelle Solarleistung", "Huidig solar vermogen", "Aktuellt Sol-effekt", "aktualna moc solarów", "aktuell soleffekt", "puissance solaire réelle", "gerçek G.E. gücü", "potenza attuale solare")
|
||||
MAKE_TRANSLATION(solarPumpTurnonDiff, "turnondiff", "pump turn on difference", "Einschalthysterese Pumpe", "Inschakelhysterese pomp", "Aktiveringshysteres Pump", "histereza załączenia pompy", "slå på hysteresepumpe", "différence activation pompe", "pompa devreye alma farkı", "isteresi di accensione pompa")
|
||||
MAKE_TRANSLATION(solarPumpTurnoffDiff, "turnoffdiff", "pump turn off difference", "Ausschalthysterese Pumpe", "Uitschakelhysterese pomp", "Avslagshysteres Pump", "histereza włączenia pompy", "slå av hysteresepumpe", "différence arrêt pompe", "pompa kapama farkı", "isteresi di spegnimento pompa")
|
||||
MAKE_TRANSLATION(pump2MinMod, "pump2minmod", "minimum pump 2 modulation", "minimale Modulation Pumpe 2", "Minimale modulatie pomp 2", "Min Modulering Pump 2", "minimalna modulacja pompy 2", "minimum pumpmodulering 2", "modulation minimale pompe 2", "minimum pompa 2 modülasyonu", "modulazione minima pompa 2")
|
||||
MAKE_TRANSLATION(solarPump2TurnonDiff, "turnondiff2", "pump 2 turn on difference", "Einschalthysterese Pumpe 2", "Inschakelhysterese pomp 2", "Aktiveringshysteres Pump 2", "histereza załączenia pompy 2", "slå på hysteresepumpe 2", "différence activation pompe 2", "", "isteresi di accensione pompa 2")
|
||||
MAKE_TRANSLATION(solarPump2TurnoffDiff, "turnoffdiff2", "pump 2 turn off difference", "Ausschalthysterese Pumpe 2", "Uitschakelhysterese pomp 2", "Avslagshysteres Pump 2", "histereza wyłączenia pompy 2", "slå av hysteresepumpe 2", "différence arrêt pompe 2", "", "isteresi di spegnimento pompa")
|
||||
MAKE_TRANSLATION(solarPump2TurnonDiff, "turnondiff2", "pump 2 turn on difference", "Einschalthysterese Pumpe 2", "Inschakelhysterese pomp 2", "Aktiveringshysteres Pump 2", "histereza załączenia pompy 2", "slå på hysteresepumpe 2", "différence activation pompe 2", "pompa 2 devreye alma farkı", "isteresi di accensione pompa 2")
|
||||
MAKE_TRANSLATION(solarPump2TurnoffDiff, "turnoffdiff2", "pump 2 turn off difference", "Ausschalthysterese Pumpe 2", "Uitschakelhysterese pomp 2", "Avslagshysteres Pump 2", "histereza wyłączenia pompy 2", "slå av hysteresepumpe 2", "différence arrêt pompe 2", "pompa 2 kapama farkı", "isteresi di spegnimento pompa")
|
||||
MAKE_TRANSLATION(collectorTemp, "collectortemp", "collector temperature (TS1)", "Kollektortemperatur (TS1)", "Collectortemperatuur (TS1)", "Kollektor Temperatur (TS1)", "temperatura kolektora (TS1)", "kollektor temperatur (TS1)", "température collecteur (TS1)", "kollektör sıcaklığı (TS1)", "temperatura collettore (TS1)")
|
||||
MAKE_TRANSLATION(collector2Temp, "collector2temp", "collector 2 temperature (TS7)", "Kollector 2 Temperatur (TS7)", "Collector 2 temperatuur (TS7)", "Kollektor 2 Temperatur (TS7)", "temperatura kolektora 2 (TS7)", "kollektor 2 temperatur (TS7)", "température collecteur 2 (TS7)", "kollektör 2 sıcaklığı (TS2)", "temperatura collettore 2 (TS7)")
|
||||
MAKE_TRANSLATION(cylBottomTemp, "cylbottomtemp", "cylinder bottom temperature (TS2)", "Speicher Bodentemperatur (TS2)", "Bodemtemperatuur zonneboiler (TS2)", "Cylindertemperatur Botten (TS2)", "temperatura na spodzie zasobnika (TS2)", "beredertemp i bunn (TS2)", "température fond de cylindre (TS2)", "", "temperatura inferiore accumulo (TS2)")
|
||||
MAKE_TRANSLATION(cyl2BottomTemp, "cyl2bottomtemp", "second cylinder bottom temperature (TS5)", "2. Speicher Bodentemperatur (TS5)", "Bodemtemperatuur 2e boiler", "Sekundär Cylindertemperatur Botten (TS5)", "temperatura na spodzie drugiego zasobnika (TS5)", "skundær beredertemp i bunn (TS5)", "température fond de cylindre (TS5)", "", "temperatura inferiore 2° accumulo (TS5)")
|
||||
MAKE_TRANSLATION(cylBottomTemp, "cylbottomtemp", "cylinder bottom temperature (TS2)", "Speicher Bodentemperatur (TS2)", "Bodemtemperatuur zonneboiler (TS2)", "Cylindertemperatur Botten (TS2)", "temperatura na spodzie zasobnika (TS2)", "beredertemp i bunn (TS2)", "température fond de cylindre (TS2)", "alt depolama sıcaklığıc(TS2)", "temperatura inferiore accumulo (TS2)")
|
||||
MAKE_TRANSLATION(cyl2BottomTemp, "cyl2bottomtemp", "second cylinder bottom temperature (TS5)", "2. Speicher Bodentemperatur (TS5)", "Bodemtemperatuur 2e boiler", "Sekundär Cylindertemperatur Botten (TS5)", "temperatura na spodzie drugiego zasobnika (TS5)", "skundær beredertemp i bunn (TS5)", "température fond de cylindre (TS5)", "ikinci alt depolama sıcaklığıc(TS5)", "temperatura inferiore 2° accumulo (TS5)")
|
||||
MAKE_TRANSLATION(heatExchangerTemp, "heatexchangertemp", "heat exchanger temperature (TS6)", "wärmetauscher Temperatur (TS6)", "Temperatuur warmtewisselaar (TS6)", "Värmeväxlare Temperatur (TS6)", "temperatura wymiennika ciepła (TS6)", "Varmeveksler temperatur (TS6)", "température échangeur de chaleur (TS6)", "eşanjör sıcaklığı (TS6)", "temperatura scambiatore calore (TS6)")
|
||||
MAKE_TRANSLATION(collectorMaxTemp, "collectormaxtemp", "maximum collector temperature", "maximale Kollektortemperatur", "Maximale collectortemperatuur", "Max Kollektortemperatur", "maksymalna temperatura kolektora", "maks kollektortemperatur", "température max. collecteur", "maksimum kollektör sıcaklığı", " temperatura massima scambiatore calore")
|
||||
MAKE_TRANSLATION(collectorMinTemp, "collectormintemp", "minimum collector temperature", "minimale Kollektortemperatur", "Minimale collectortemperatuur", "Min Kollektortemperatur", "minimalna temperatura kolektora", "min kollektortemperatur", "température min. collecteur", "minimum kollektör sıcaklığı", "temperatura minima scambiatore calore")
|
||||
@@ -709,11 +715,11 @@ MAKE_TRANSLATION(solarPump2, "solarpump2", "pump 2 (PS4)", "Pumpe 2 (PS4)", "Pom
|
||||
MAKE_TRANSLATION(solarPump2Mod, "solarpump2mod", "pump 2 modulation (PS4)", "Pumpe 2 Modulation (PS4)", "Modulatie pomp 2 (PS4)", "Pump 2 Modulering (PS4)", "modulacja pompy solarnej 2 (PS4)", "solpumpe2modulering (PS4)", "modulation pompe solaire 2 (PS4)", "pompa2 modülasyonu(PS1)", "pompa modulazione 2 (PS4)")
|
||||
MAKE_TRANSLATION(valveStatus, "valvestatus", "valve status", "Ventilstatus", "Klepstatus", "Ventilstatus", "stan zaworu", "ventilstatus", "statut valve", "vana durumu", "stato valvola")
|
||||
MAKE_TRANSLATION(vs1Status, "vs1status", "valve status VS1", "Ventilstatus VS1", "Klepstatus VS1", "Ventilstatus VS1", "stan zaworu VS1", "ventilstatus VS1", "statut valve VS1", "vana durumu VS1", "stato valvola VS1")
|
||||
MAKE_TRANSLATION(cylHeated, "cylheated", "cyl heated", "Speichertemperatur erreicht", "Boilertemperatuur behaald", "Värmepanna Uppvärmd", "zasobnik został nagrzany", "bereder oppvarmt", "cylindre chauffé", "", "temperatura richiesta vaso accumulo raggiunta")
|
||||
MAKE_TRANSLATION(cylHeated, "cylheated", "cyl heated", "Speichertemperatur erreicht", "Boilertemperatuur behaald", "Värmepanna Uppvärmd", "zasobnik został nagrzany", "bereder oppvarmt", "cylindre chauffé", "depolama sıcakllığına ulaşıldı", "temperatura richiesta vaso accumulo raggiunta")
|
||||
MAKE_TRANSLATION(collectorShutdown, "collectorshutdown", "collector shutdown", "Kollektorabschaltung", "Collector afschakeling", "Kollektor Avstängning", "wyłączenie kolektora", "kollektor stengt", "arrêt collecteur", "kollektör kapalı", "spegnimento del collettore")
|
||||
MAKE_TRANSLATION(pumpWorkTime, "pumpworktime", "pump working time", "Pumpenlaufzeit", "Pomplooptijd", "Pump Drifttid", "czas pracy pompy", "driftstid pumpe", "durée fonctionnement pompe", "pompa çalışma süresi", "tempo funzionamento pompa")
|
||||
MAKE_TRANSLATION(pump2WorkTime, "pump2worktime", "pump 2 working time", "Pumpe 2 Laufzeit", "Looptijd pomp 2", "Pump 2 Drifttid", "czas pracy pompy 2", "driftstid pumpe2", "durée fonctionnement pompe 2", "pompa 2 çalışma süresi", "tempo funzionamento pompa 2")
|
||||
MAKE_TRANSLATION(m1WorkTime, "m1worktime", "differential control working time", "Differenzregelung Arbeitszeit", "Verschilregeling arbeidstijd", "Differentialreglering Drifttid", "czas pracy regulacji różnicowej", "differentialreguleringssrifttid", "durée fonctionnement contrôle différentiel", "", "controllo differenziale durata funzionamento")
|
||||
MAKE_TRANSLATION(m1WorkTime, "m1worktime", "differential control working time", "Differenzregelung Arbeitszeit", "Verschilregeling arbeidstijd", "Differentialreglering Drifttid", "czas pracy regulacji różnicowej", "differentialreguleringssrifttid", "durée fonctionnement contrôle différentiel", "çalışma saatlerinin farklı düzenlenmesi", "controllo differenziale durata funzionamento")
|
||||
MAKE_TRANSLATION(energyLastHour, "energylasthour", "energy last hour", "Energie letzte Std", "Energie laatste uur", "Energi Senaste Timmen", "energia w ciągu ostatniej godziny", "energi siste time", "énergie dernière heure", "son saat enerji", "Eenergia ultima ora")
|
||||
MAKE_TRANSLATION(energyTotal, "energytotal", "total energy", "Gesamtenergie", "Totale energie", "Total Energi", "energia całkowita", "total energi", "énergie totale", "toplam enerji", "energia totale")
|
||||
MAKE_TRANSLATION(energyToday, "energytoday", "total energy today", "Energie heute", "Energie vandaag", "Total Energi Idag", "energia całkowita dzisiaj", "total energi i dag", "énergie totale aujourd'hui", "bugün toplam enerji", "totale energia giornaliera")
|
||||
|
||||
24
src/mqtt.cpp
24
src/mqtt.cpp
@@ -594,12 +594,20 @@ bool Mqtt::queue_message(const uint8_t operation, const std::string & topic, con
|
||||
}
|
||||
// check free mem
|
||||
#ifndef EMSESP_STANDALONE
|
||||
if (ESP.getFreeHeap() < 60 * 1204) {
|
||||
if (ESP.getFreeHeap() < 60 * 1204 || ESP.getMaxAllocHeap() < 40 * 1024) {
|
||||
if (operation == Operation::PUBLISH) {
|
||||
mqtt_message_id_++;
|
||||
mqtt_publish_fails_++;
|
||||
}
|
||||
LOG_DEBUG("%s failed: low memory", operation == Operation::PUBLISH ? "Publish" : operation == Operation::SUBSCRIBE ? "Subscribe" : "Unsubscribe");
|
||||
LOG_WARNING("%s failed: low memory", operation == Operation::PUBLISH ? "Publish" : operation == Operation::SUBSCRIBE ? "Subscribe" : "Unsubscribe");
|
||||
return false; // quit
|
||||
}
|
||||
if (queuecount_ >= MQTT_QUEUE_MAX_SIZE) {
|
||||
if (operation == Operation::PUBLISH) {
|
||||
mqtt_message_id_++;
|
||||
mqtt_publish_fails_++;
|
||||
}
|
||||
LOG_WARNING("%s failed: queue full", operation == Operation::PUBLISH ? "Publish" : operation == Operation::SUBSCRIBE ? "Subscribe" : "Unsubscribe");
|
||||
return false; // quit
|
||||
}
|
||||
#endif
|
||||
@@ -737,7 +745,7 @@ bool Mqtt::publish_ha_sensor_config(DeviceValue & dv, const char * model, const
|
||||
|
||||
// calculate the min and max
|
||||
int16_t dv_set_min;
|
||||
uint16_t dv_set_max;
|
||||
uint32_t dv_set_max;
|
||||
(void)dv.get_min_max(dv_set_min, dv_set_max);
|
||||
|
||||
// determine if we're creating the command topics which we use special HA configs
|
||||
@@ -788,7 +796,7 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
||||
const char * const ** options,
|
||||
uint8_t options_size,
|
||||
const int16_t dv_set_min,
|
||||
const int16_t dv_set_max,
|
||||
const uint32_t dv_set_max,
|
||||
const int8_t num_op,
|
||||
const JsonObject & dev_json) {
|
||||
// ignore if name (fullname) is empty
|
||||
@@ -847,7 +855,7 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
||||
case DeviceValueType::UINT:
|
||||
case DeviceValueType::SHORT:
|
||||
case DeviceValueType::USHORT:
|
||||
case DeviceValueType::ULONG:
|
||||
// case DeviceValueType::ULONG:
|
||||
if (discovery_type() == discoveryType::HOMEASSISTANT) {
|
||||
// Home Assistant
|
||||
// number - https://www.home-assistant.io/integrations/number.mqtt
|
||||
@@ -866,6 +874,10 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
||||
// select - https://www.home-assistant.io/integrations/select.mqtt
|
||||
snprintf(topic, sizeof(topic), "select/%s", config_topic);
|
||||
break;
|
||||
case DeviceValueType::ULONG:
|
||||
snprintf(topic, sizeof(topic), "sensor/%s", config_topic);
|
||||
set_ha_classes = true;
|
||||
break;
|
||||
default:
|
||||
// plain old sensor
|
||||
snprintf(topic, sizeof(topic), "sensor/%s", config_topic);
|
||||
@@ -1127,7 +1139,7 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
||||
return queue_ha(topic, doc.as<JsonObject>());
|
||||
}
|
||||
|
||||
bool Mqtt::publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp, const bool remove, const int16_t min, const uint16_t max) {
|
||||
bool Mqtt::publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp, const bool remove, const int16_t min, const uint32_t max) {
|
||||
uint8_t hc_num = tag - DeviceValueTAG::TAG_HC1 + 1;
|
||||
|
||||
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||
|
||||
@@ -55,7 +55,8 @@ class Mqtt {
|
||||
enum Operation : uint8_t { PUBLISH, SUBSCRIBE, UNSUBSCRIBE };
|
||||
enum NestedFormat : uint8_t { NESTED = 1, SINGLE };
|
||||
|
||||
static constexpr uint8_t MQTT_TOPIC_MAX_SIZE = 128; // fixed, not a user setting anymore
|
||||
static constexpr uint8_t MQTT_TOPIC_MAX_SIZE = 128; // fixed, not a user setting anymore
|
||||
static constexpr uint16_t MQTT_QUEUE_MAX_SIZE = 300;
|
||||
|
||||
static void on_connect();
|
||||
static void on_disconnect(espMqttClientTypes::DisconnectReason reason);
|
||||
@@ -87,12 +88,12 @@ class Mqtt {
|
||||
const char * const ** options,
|
||||
uint8_t options_size,
|
||||
const int16_t dv_set_min,
|
||||
const int16_t dv_set_max,
|
||||
const uint32_t dv_set_max,
|
||||
const int8_t num_op,
|
||||
const JsonObject & dev_json);
|
||||
|
||||
static bool publish_system_ha_sensor_config(uint8_t type, const char * name, const char * entity, const uint8_t uom);
|
||||
static bool publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp, const bool remove = false, const int16_t min = 5, const uint16_t max = 30);
|
||||
static bool publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp, const bool remove = false, const int16_t min = 5, const uint32_t max = 30);
|
||||
|
||||
static void show_topic_handlers(uuid::console::Shell & shell, const uint8_t device_type);
|
||||
static void show_mqtt(uuid::console::Shell & shell);
|
||||
|
||||
@@ -231,9 +231,15 @@ bool System::command_watch(const char * value, const int8_t id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void System::store_nvs_values() {
|
||||
Command::call(EMSdevice::DeviceType::BOILER, "nompower", "-1"); // trigger a write
|
||||
EMSESP::analogsensor_.store_counters();
|
||||
}
|
||||
|
||||
// restart EMS-ESP
|
||||
void System::system_restart() {
|
||||
LOG_INFO("Restarting EMS-ESP...");
|
||||
store_nvs_values();
|
||||
Shell::loop_all();
|
||||
delay(1000); // wait a second
|
||||
#ifndef EMSESP_STANDALONE
|
||||
@@ -1031,7 +1037,7 @@ bool System::check_restore() {
|
||||
saveSettings(EMSESP_SCHEDULER_FILE, "Schedule", input);
|
||||
} else if (settings_type == "entities") {
|
||||
// it's a entity file, just replace it and there's no need to reboot
|
||||
saveSettings(EMSESP_ENTITY_FILE, "Entities", input);
|
||||
saveSettings(EMSESP_CUSTOMENTITY_FILE, "Entities", input);
|
||||
} else {
|
||||
LOG_ERROR("Unrecognized file uploaded");
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ class System {
|
||||
|
||||
std::string reset_reason(uint8_t cpu) const;
|
||||
|
||||
void store_nvs_values();
|
||||
void system_restart();
|
||||
void format(uuid::console::Shell & shell);
|
||||
void upload_status(bool in_progress);
|
||||
|
||||
@@ -360,10 +360,10 @@ bool TemperatureSensor::command_commands(const char * value, const int8_t id, Js
|
||||
}
|
||||
|
||||
// creates JSON doc from values
|
||||
// returns false if there are no sensors
|
||||
// returns true if there are no sensors
|
||||
bool TemperatureSensor::command_info(const char * value, const int8_t id, JsonObject & output) {
|
||||
if (sensors_.empty()) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const auto & sensor : sensors_) {
|
||||
@@ -389,7 +389,7 @@ bool TemperatureSensor::command_info(const char * value, const int8_t id, JsonOb
|
||||
// called from emsesp.cpp, similar to the emsdevice->get_value_info
|
||||
bool TemperatureSensor::get_value_info(JsonObject & output, const char * cmd, const int8_t id) {
|
||||
if (sensors_.empty()) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
// make a copy of the string command for parsing
|
||||
char command_s[30];
|
||||
@@ -576,7 +576,7 @@ TemperatureSensor::Sensor::Sensor(const uint8_t addr[])
|
||||
(unsigned int)(internal_id_ >> 48) & 0xFF,
|
||||
(unsigned int)(internal_id_ >> 32) & 0xFFFF,
|
||||
(unsigned int)(internal_id_ >> 16) & 0xFFFF,
|
||||
(unsigned int)(internal_id_) & 0xFFFF);
|
||||
(unsigned int)(internal_id_)&0xFFFF);
|
||||
id_ = std::string(id_s);
|
||||
name_ = std::string{}; // name (alias) is empty
|
||||
offset_ = 0; // 0 degrees offset
|
||||
|
||||
@@ -280,6 +280,21 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
ok = true;
|
||||
}
|
||||
|
||||
if (command == "custom_entities") {
|
||||
shell.printfln("custom entities...");
|
||||
run_test("general");
|
||||
|
||||
#ifdef EMSESP_STANDALONE
|
||||
AsyncWebServerRequest request;
|
||||
request.method(HTTP_GET);
|
||||
request.url("/api/custom");
|
||||
request.url("/api/custom/boiler_flowtemp");
|
||||
request.url("/api/custom/boiler_flowtemp2");
|
||||
EMSESP::webAPIService.webAPIService_get(&request);
|
||||
#endif
|
||||
ok = true;
|
||||
}
|
||||
|
||||
if (command == "coldshot") {
|
||||
shell.printfln("Testing coldshot...");
|
||||
run_test("general");
|
||||
@@ -734,7 +749,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
|
||||
if (emsdevice->unique_id() == 1) { // thermostat
|
||||
std::string a = "00hc1/seltemp|new name>5<52";
|
||||
emsdevice->setCustomEntity(a);
|
||||
emsdevice->setCustomizationEntity(a);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -760,7 +775,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
for (const auto & emsdevice : EMSESP::emsdevices) {
|
||||
if (emsdevice->unique_id() == 1) { // boiler
|
||||
std::string a = "07wwseltemp";
|
||||
emsdevice->setCustomEntity(a);
|
||||
emsdevice->setCustomizationEntity(a);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1030,7 +1045,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
|
||||
EMSESP::mqtt_.incoming("ems-esp/thermostat", "{\"cmd\":\"mode\",\"data\":\"heat\",\"id\":1}");
|
||||
|
||||
// MQTT bad tests
|
||||
// MQTT bad tests - these should all fail
|
||||
EMSESP::mqtt_.incoming("ems-esp/thermostate/mode", "auto"); // unknown device
|
||||
EMSESP::mqtt_.incoming("ems-esp/thermostat/modee", "auto"); // unknown command
|
||||
EMSESP::mqtt_.incoming("ems-esp/thermostat/mode/auto", "auto"); // invalid, not allowed
|
||||
@@ -1109,18 +1124,25 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
request.url("/rest/writeDeviceValue");
|
||||
EMSESP::webDataService.write_device_value(&request, json);
|
||||
|
||||
// write value from web - testing hc9/seltemp - should fail!
|
||||
char data7[] = "{\"id\":2,\"devicevalue\":{\"v\":\"55\",\"u\":1,\"n\":\"hc2 selected room temperature\",\"c\":\"hc9/seltemp\"}";
|
||||
// call reset command
|
||||
char data7[] = "{\"device\":\"boiler\", \"cmd\":\"reset\",\"value\":\"error\"}";
|
||||
deserializeJson(doc, data7);
|
||||
json = doc.as<JsonVariant>();
|
||||
request.url("/api");
|
||||
EMSESP::webAPIService.webAPIService_post(&request, json);
|
||||
|
||||
emsesp::EMSESP::logger().warning("* these next ones should fail *");
|
||||
|
||||
// write value from web - testing hc9/seltemp - should fail!
|
||||
char data8[] = "{\"id\":2,\"devicevalue\":{\"v\":\"55\",\"u\":1,\"n\":\"hc2 selected room temperature\",\"c\":\"hc9/seltemp\"}";
|
||||
deserializeJson(doc, data8);
|
||||
json = doc.as<JsonVariant>();
|
||||
request.url("/rest/writeDeviceValue");
|
||||
EMSESP::webDataService.write_device_value(&request, json);
|
||||
|
||||
// emsesp::EMSESP::logger().notice("*");
|
||||
|
||||
// should fail
|
||||
char data8[] = "{}";
|
||||
deserializeJson(doc, data8);
|
||||
// should fail!
|
||||
char data9[] = "{}";
|
||||
deserializeJson(doc, data9);
|
||||
json = doc.as<JsonVariant>();
|
||||
request.url("/api/thermostat/mode/auto");
|
||||
EMSESP::webAPIService.webAPIService_post(&request, json);
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
namespace emsesp {
|
||||
|
||||
// #define EMSESP_DEBUG_DEFAULT "general"
|
||||
#define EMSESP_DEBUG_DEFAULT "general"
|
||||
|
||||
// #define EMSESP_DEBUG_DEFAULT "thermostat"
|
||||
// #define EMSESP_DEBUG_DEFAULT "solar"
|
||||
@@ -54,7 +54,8 @@ namespace emsesp {
|
||||
// #define EMSESP_DEBUG_DEFAULT "custom"
|
||||
// #define EMSESP_DEBUG_DEFAULT "entity_dump"
|
||||
// #define EMSESP_DEBUG_DEFAULT "memory"
|
||||
#define EMSESP_DEBUG_DEFAULT "coldshot"
|
||||
// #define EMSESP_DEBUG_DEFAULT "coldshot"
|
||||
// #define EMSESP_DEBUG_DEFAULT "custom_entities"
|
||||
|
||||
class Test {
|
||||
public:
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define EMSESP_APP_VERSION "3.6.1"
|
||||
#define EMSESP_APP_VERSION "3.6.2"
|
||||
|
||||
@@ -127,11 +127,6 @@ void WebAPIService::parse(AsyncWebServerRequest * request, JsonObject & input) {
|
||||
}
|
||||
emsesp::EMSESP::logger().err(error);
|
||||
api_fails_++;
|
||||
} else {
|
||||
// if there was no json output from the call, default to the output message 'OK'.
|
||||
if (!output.size()) {
|
||||
output["message"] = "OK";
|
||||
}
|
||||
}
|
||||
|
||||
// if we're returning single values, just sent as plain text
|
||||
@@ -216,7 +211,7 @@ void WebAPIService::getEntities(AsyncWebServerRequest * request) {
|
||||
|
||||
root["type"] = "entities";
|
||||
|
||||
System::extractSettings(EMSESP_ENTITY_FILE, "Entities", root);
|
||||
System::extractSettings(EMSESP_CUSTOMENTITY_FILE, "Entities", root);
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
|
||||
@@ -22,13 +22,19 @@ namespace emsesp {
|
||||
|
||||
using namespace std::placeholders; // for `_1` etc
|
||||
|
||||
WebEntityService::WebEntityService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager)
|
||||
: _httpEndpoint(WebEntity::read, WebEntity::update, this, server, EMSESP_ENTITY_SERVICE_PATH, securityManager, AuthenticationPredicates::IS_AUTHENTICATED)
|
||||
, _fsPersistence(WebEntity::read, WebEntity::update, this, fs, EMSESP_ENTITY_FILE, FS_BUFFER_SIZE) {
|
||||
WebCustomEntityService::WebCustomEntityService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager)
|
||||
: _httpEndpoint(WebCustomEntity::read,
|
||||
WebCustomEntity::update,
|
||||
this,
|
||||
server,
|
||||
EMSESP_CUSTOMENTITY_SERVICE_PATH,
|
||||
securityManager,
|
||||
AuthenticationPredicates::IS_AUTHENTICATED)
|
||||
, _fsPersistence(WebCustomEntity::read, WebCustomEntity::update, this, fs, EMSESP_CUSTOMENTITY_FILE, FS_BUFFER_SIZE) {
|
||||
}
|
||||
|
||||
// load the settings when the service starts
|
||||
void WebEntityService::begin() {
|
||||
void WebCustomEntityService::begin() {
|
||||
_fsPersistence.readFromFS();
|
||||
EMSESP::logger().info("Starting Custom entity service");
|
||||
Mqtt::subscribe(EMSdevice::DeviceType::CUSTOM, "custom/#", nullptr); // use empty function callback
|
||||
@@ -36,10 +42,10 @@ void WebEntityService::begin() {
|
||||
|
||||
// this creates the entity file, saving it to the FS
|
||||
// and also calls when the Entity web page is refreshed
|
||||
void WebEntity::read(WebEntity & webEntity, JsonObject & root) {
|
||||
void WebCustomEntity::read(WebCustomEntity & webEntity, JsonObject & root) {
|
||||
JsonArray entity = root.createNestedArray("entities");
|
||||
uint8_t counter = 0;
|
||||
for (const EntityItem & entityItem : webEntity.entityItems) {
|
||||
for (const CustomEntityItem & entityItem : webEntity.customEntityItems) {
|
||||
JsonObject ei = entity.createNestedObject();
|
||||
ei["id"] = counter++; // id is only used to render the table and must be unique
|
||||
ei["device_id"] = entityItem.device_id;
|
||||
@@ -50,22 +56,38 @@ void WebEntity::read(WebEntity & webEntity, JsonObject & root) {
|
||||
ei["uom"] = entityItem.uom;
|
||||
ei["value_type"] = entityItem.value_type;
|
||||
ei["writeable"] = entityItem.writeable;
|
||||
EMSESP::webEntityService.render_value(ei, entityItem, true, true);
|
||||
EMSESP::webCustomEntityService.render_value(ei, entityItem, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
// call on initialization and also when the Entity web page is updated
|
||||
// this loads the data into the internal class
|
||||
StateUpdateResult WebEntity::update(JsonObject & root, WebEntity & webEntity) {
|
||||
for (EntityItem & entityItem : webEntity.entityItems) {
|
||||
StateUpdateResult WebCustomEntity::update(JsonObject & root, WebCustomEntity & webCustomEntity) {
|
||||
#ifdef EMSESP_STANDALONE
|
||||
// invoke some fake data for testing
|
||||
// clang-format off
|
||||
/* prettier-ignore */
|
||||
const char * json =
|
||||
"{\"entities\": [{\"id\":0,\"device_id\":8,\"type_id\":24,\"offset\":0,\"factor\":1,\"name\":\"boiler_flowtemp\",\"uom\":1,\"value_type\":1,\"writeable\":true}]}";
|
||||
// clang-format on
|
||||
StaticJsonDocument<500> doc;
|
||||
deserializeJson(doc, json);
|
||||
root = doc.as<JsonObject>();
|
||||
Serial.println(COLOR_BRIGHT_MAGENTA);
|
||||
Serial.print(" Using fake custom entity file: ");
|
||||
serializeJson(root, Serial);
|
||||
Serial.println(COLOR_RESET);
|
||||
#endif
|
||||
|
||||
for (CustomEntityItem & entityItem : webCustomEntity.customEntityItems) {
|
||||
Command::erase_command(EMSdevice::DeviceType::CUSTOM, entityItem.name.c_str());
|
||||
}
|
||||
webEntity.entityItems.clear();
|
||||
EMSESP::webEntityService.ha_reset();
|
||||
webCustomEntity.customEntityItems.clear();
|
||||
EMSESP::webCustomEntityService.ha_reset();
|
||||
|
||||
if (root["entities"].is<JsonArray>()) {
|
||||
for (const JsonObject ei : root["entities"].as<JsonArray>()) {
|
||||
auto entityItem = EntityItem();
|
||||
auto entityItem = CustomEntityItem();
|
||||
entityItem.device_id = ei["device_id"]; // send as numeric, will be converted to string in web
|
||||
entityItem.type_id = ei["type_id"];
|
||||
entityItem.offset = ei["offset"];
|
||||
@@ -91,13 +113,13 @@ StateUpdateResult WebEntity::update(JsonObject & root, WebEntity & webEntity) {
|
||||
if (entityItem.factor == 0) {
|
||||
entityItem.factor = 1;
|
||||
}
|
||||
webEntity.entityItems.push_back(entityItem); // add to list
|
||||
webCustomEntity.customEntityItems.push_back(entityItem); // add to list
|
||||
if (entityItem.writeable) {
|
||||
Command::add(
|
||||
EMSdevice::DeviceType::CUSTOM,
|
||||
webEntity.entityItems.back().name.c_str(),
|
||||
[webEntity](const char * value, const int8_t id) {
|
||||
return EMSESP::webEntityService.command_setvalue(value, webEntity.entityItems.back().name);
|
||||
webCustomEntity.customEntityItems.back().name.c_str(),
|
||||
[webCustomEntity](const char * value, const int8_t id) {
|
||||
return EMSESP::webCustomEntityService.command_setvalue(value, webCustomEntity.customEntityItems.back().name);
|
||||
},
|
||||
FL_(entity_cmd),
|
||||
CommandFlag::ADMIN_ONLY);
|
||||
@@ -108,9 +130,9 @@ StateUpdateResult WebEntity::update(JsonObject & root, WebEntity & webEntity) {
|
||||
}
|
||||
|
||||
// set value by api command
|
||||
bool WebEntityService::command_setvalue(const char * value, const std::string name) {
|
||||
EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; });
|
||||
for (EntityItem & entityItem : *entityItems) {
|
||||
bool WebCustomEntityService::command_setvalue(const char * value, const std::string name) {
|
||||
EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; });
|
||||
for (CustomEntityItem & entityItem : *customEntityItems) {
|
||||
if (Helpers::toLower(entityItem.name) == Helpers::toLower(name)) {
|
||||
if (entityItem.value_type == DeviceValueType::STRING) {
|
||||
char telegram[84];
|
||||
@@ -160,7 +182,7 @@ bool WebEntityService::command_setvalue(const char * value, const std::string na
|
||||
}
|
||||
|
||||
// output of a single value
|
||||
void WebEntityService::render_value(JsonObject & output, EntityItem entity, const bool useVal, const bool web) {
|
||||
void WebCustomEntityService::render_value(JsonObject & output, CustomEntityItem entity, const bool useVal, const bool web) {
|
||||
char payload[12];
|
||||
std::string name = useVal ? "value" : entity.name;
|
||||
switch (entity.value_type) {
|
||||
@@ -215,26 +237,29 @@ void WebEntityService::render_value(JsonObject & output, EntityItem entity, cons
|
||||
}
|
||||
|
||||
// process json output for info/commands and value_info
|
||||
bool WebEntityService::get_value_info(JsonObject & output, const char * cmd) {
|
||||
EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; });
|
||||
if (entityItems->size() == 0) {
|
||||
return false;
|
||||
}
|
||||
if (Helpers::toLower(cmd) == "commands") {
|
||||
output["info"] = "list all values";
|
||||
output["commands"] = "list all commands";
|
||||
for (const auto & entity : *entityItems) {
|
||||
bool WebCustomEntityService::get_value_info(JsonObject & output, const char * cmd) {
|
||||
EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; });
|
||||
if (Helpers::toLower(cmd) == F_(commands)) {
|
||||
output[F_(info)] = Helpers::translated_word(FL_(info_cmd));
|
||||
output[F_(commands)] = Helpers::translated_word(FL_(commands_cmd));
|
||||
for (const auto & entity : *customEntityItems) {
|
||||
output[entity.name] = "custom entitiy";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (strlen(cmd) == 0 || Helpers::toLower(cmd) == "values" || Helpers::toLower(cmd) == "info") {
|
||||
// if no entries, return empty json
|
||||
// https://github.com/emsesp/EMS-ESP32/issues/1297
|
||||
if (customEntityItems->size() == 0) {
|
||||
return true;
|
||||
}
|
||||
if (strlen(cmd) == 0 || Helpers::toLower(cmd) == F_(values) || Helpers::toLower(cmd) == F_(info)) {
|
||||
// list all names
|
||||
for (const EntityItem & entity : *entityItems) {
|
||||
for (const CustomEntityItem & entity : *customEntityItems) {
|
||||
render_value(output, entity);
|
||||
}
|
||||
return (output.size() != 0);
|
||||
}
|
||||
|
||||
char command_s[30];
|
||||
strlcpy(command_s, cmd, sizeof(command_s));
|
||||
char * attribute_s = nullptr;
|
||||
@@ -244,7 +269,8 @@ bool WebEntityService::get_value_info(JsonObject & output, const char * cmd) {
|
||||
*breakp = '\0';
|
||||
attribute_s = breakp + 1;
|
||||
}
|
||||
for (const auto & entity : *entityItems) {
|
||||
|
||||
for (const auto & entity : *customEntityItems) {
|
||||
if (Helpers::toLower(entity.name) == Helpers::toLower(command_s)) {
|
||||
output["name"] = entity.name;
|
||||
if (entity.uom > 0) {
|
||||
@@ -268,24 +294,28 @@ bool WebEntityService::get_value_info(JsonObject & output, const char * cmd) {
|
||||
JsonVariant data = output[attribute_s];
|
||||
output.clear();
|
||||
output["api_data"] = data;
|
||||
return true;
|
||||
} else {
|
||||
char error[100];
|
||||
snprintf(error, sizeof(error), "cannot find attribute %s in entity %s", attribute_s, command_s);
|
||||
output.clear();
|
||||
output["message"] = error;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (output.size()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
output["message"] = "unknown command";
|
||||
return false;
|
||||
}
|
||||
|
||||
// publish single value
|
||||
void WebEntityService::publish_single(const EntityItem & entity) {
|
||||
void WebCustomEntityService::publish_single(const CustomEntityItem & entity) {
|
||||
if (!Mqtt::enabled() || !Mqtt::publish_single()) {
|
||||
return;
|
||||
}
|
||||
@@ -302,19 +332,19 @@ void WebEntityService::publish_single(const EntityItem & entity) {
|
||||
}
|
||||
|
||||
// publish to Mqtt
|
||||
void WebEntityService::publish(const bool force) {
|
||||
void WebCustomEntityService::publish(const bool force) {
|
||||
if (force) {
|
||||
ha_registered_ = false;
|
||||
}
|
||||
if (!Mqtt::enabled()) {
|
||||
return;
|
||||
}
|
||||
EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; });
|
||||
if (entityItems->size() == 0) {
|
||||
EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; });
|
||||
if (customEntityItems->size() == 0) {
|
||||
return;
|
||||
}
|
||||
if (Mqtt::publish_single() && force) {
|
||||
for (const EntityItem & entityItem : *entityItems) {
|
||||
for (const CustomEntityItem & entityItem : *customEntityItems) {
|
||||
publish_single(entityItem);
|
||||
}
|
||||
}
|
||||
@@ -322,7 +352,7 @@ void WebEntityService::publish(const bool force) {
|
||||
DynamicJsonDocument doc(EMSESP_JSON_SIZE_XLARGE);
|
||||
JsonObject output = doc.to<JsonObject>();
|
||||
bool ha_created = ha_registered_;
|
||||
for (const EntityItem & entityItem : *entityItems) {
|
||||
for (const CustomEntityItem & entityItem : *customEntityItems) {
|
||||
render_value(output, entityItem);
|
||||
// create HA config
|
||||
if (Mqtt::ha_enabled() && !ha_registered_) {
|
||||
@@ -396,39 +426,39 @@ void WebEntityService::publish(const bool force) {
|
||||
}
|
||||
|
||||
// count only entities with valid value or command to show in dashboard
|
||||
uint8_t WebEntityService::count_entities() {
|
||||
EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; });
|
||||
if (entityItems->size() == 0) {
|
||||
uint8_t WebCustomEntityService::count_entities() {
|
||||
EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; });
|
||||
if (customEntityItems->size() == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
DynamicJsonDocument doc(EMSESP_JSON_SIZE_XLARGE);
|
||||
JsonObject output = doc.to<JsonObject>();
|
||||
uint8_t count = 0;
|
||||
for (const EntityItem & entity : *entityItems) {
|
||||
for (const CustomEntityItem & entity : *customEntityItems) {
|
||||
render_value(output, entity);
|
||||
count += (output.containsKey(entity.name) || entity.writeable) ? 1 : 0;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
uint8_t WebEntityService::has_commands() {
|
||||
EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; });
|
||||
uint8_t WebCustomEntityService::has_commands() {
|
||||
EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; });
|
||||
uint8_t count = 0;
|
||||
for (const EntityItem & entity : *entityItems) {
|
||||
for (const CustomEntityItem & entity : *customEntityItems) {
|
||||
count += entity.writeable ? 1 : 0;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
// send to dashboard, msgpack don't like serialized, use number
|
||||
void WebEntityService::generate_value_web(JsonObject & output) {
|
||||
EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; });
|
||||
void WebCustomEntityService::generate_value_web(JsonObject & output) {
|
||||
EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; });
|
||||
|
||||
output["label"] = (std::string) "Custom Entities";
|
||||
JsonArray data = output.createNestedArray("data");
|
||||
uint8_t index = 0;
|
||||
for (const EntityItem & entity : *entityItems) {
|
||||
for (const CustomEntityItem & entity : *customEntityItems) {
|
||||
JsonObject obj = data.createNestedObject(); // create the object, we know there is a value
|
||||
obj["id"] = "00" + entity.name;
|
||||
obj["u"] = entity.uom;
|
||||
@@ -493,10 +523,10 @@ void WebEntityService::generate_value_web(JsonObject & output) {
|
||||
}
|
||||
|
||||
// fetch telegram, called from emsesp::fetch
|
||||
void WebEntityService::fetch() {
|
||||
EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; });
|
||||
void WebCustomEntityService::fetch() {
|
||||
EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; });
|
||||
const uint8_t len[] = {1, 1, 1, 2, 2, 3, 3};
|
||||
for (auto & entity : *entityItems) {
|
||||
for (auto & entity : *customEntityItems) {
|
||||
EMSESP::send_read_request(entity.type_id,
|
||||
entity.device_id,
|
||||
entity.offset,
|
||||
@@ -506,12 +536,12 @@ void WebEntityService::fetch() {
|
||||
}
|
||||
|
||||
// called on process telegram, read from telegram
|
||||
bool WebEntityService::get_value(std::shared_ptr<const Telegram> telegram) {
|
||||
bool WebCustomEntityService::get_value(std::shared_ptr<const Telegram> telegram) {
|
||||
bool has_change = false;
|
||||
EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; });
|
||||
EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; });
|
||||
// read-length of BOOL, INT, UINT, SHORT, USHORT, ULONG, TIME
|
||||
const uint8_t len[] = {1, 1, 1, 2, 2, 3, 3};
|
||||
for (auto & entity : *entityItems) {
|
||||
for (auto & entity : *customEntityItems) {
|
||||
if (entity.value_type == DeviceValueType::STRING && telegram->type_id == entity.type_id && telegram->src == entity.device_id
|
||||
&& telegram->offset == entity.offset) {
|
||||
auto data = Helpers::data_to_hex(telegram->message_data, telegram->message_length);
|
||||
@@ -17,15 +17,15 @@
|
||||
*/
|
||||
#include "../telegram.h"
|
||||
|
||||
#ifndef WebEntityService_h
|
||||
#define WebEntityService_h
|
||||
#ifndef WebCustomEntityService_h
|
||||
#define WebCustomEntityService_h
|
||||
|
||||
#define EMSESP_ENTITY_FILE "/config/emsespEntity.json"
|
||||
#define EMSESP_ENTITY_SERVICE_PATH "/rest/entities" // GET and POST
|
||||
#define EMSESP_CUSTOMENTITY_FILE "/config/emsespEntity.json"
|
||||
#define EMSESP_CUSTOMENTITY_SERVICE_PATH "/rest/customentities" // GET and POST
|
||||
|
||||
namespace emsesp {
|
||||
|
||||
class EntityItem {
|
||||
class CustomEntityItem {
|
||||
public:
|
||||
uint8_t id;
|
||||
uint8_t device_id;
|
||||
@@ -40,26 +40,26 @@ class EntityItem {
|
||||
std::string data;
|
||||
};
|
||||
|
||||
class WebEntity {
|
||||
class WebCustomEntity {
|
||||
public:
|
||||
std::list<EntityItem> entityItems;
|
||||
std::list<CustomEntityItem> customEntityItems;
|
||||
|
||||
static void read(WebEntity & webEntity, JsonObject & root);
|
||||
static StateUpdateResult update(JsonObject & root, WebEntity & webEntity);
|
||||
static void read(WebCustomEntity & webEntity, JsonObject & root);
|
||||
static StateUpdateResult update(JsonObject & root, WebCustomEntity & webEntity);
|
||||
};
|
||||
|
||||
class WebEntityService : public StatefulService<WebEntity> {
|
||||
class WebCustomEntityService : public StatefulService<WebCustomEntity> {
|
||||
public:
|
||||
WebEntityService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager);
|
||||
WebCustomEntityService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager);
|
||||
|
||||
void begin();
|
||||
void publish_single(const EntityItem & entity);
|
||||
void publish_single(const CustomEntityItem & entity);
|
||||
void publish(const bool force = false);
|
||||
bool command_setvalue(const char * value, const std::string name);
|
||||
bool get_value_info(JsonObject & output, const char * cmd);
|
||||
bool get_value(std::shared_ptr<const Telegram> telegram);
|
||||
void fetch();
|
||||
void render_value(JsonObject & output, EntityItem entity, const bool useVal = false, const bool web = false);
|
||||
void render_value(JsonObject & output, CustomEntityItem entity, const bool useVal = false, const bool web = false);
|
||||
uint8_t count_entities();
|
||||
uint8_t has_commands();
|
||||
void generate_value_web(JsonObject & output);
|
||||
@@ -69,11 +69,11 @@ class WebEntityService : public StatefulService<WebEntity> {
|
||||
|
||||
|
||||
private:
|
||||
HttpEndpoint<WebEntity> _httpEndpoint;
|
||||
FSPersistence<WebEntity> _fsPersistence;
|
||||
HttpEndpoint<WebCustomEntity> _httpEndpoint;
|
||||
FSPersistence<WebCustomEntity> _fsPersistence;
|
||||
|
||||
std::list<EntityItem> * entityItems; // pointer to the list of entity items
|
||||
bool ha_registered_ = false;
|
||||
std::list<CustomEntityItem> * customEntityItems; // pointer to the list of entity items
|
||||
bool ha_registered_ = false;
|
||||
};
|
||||
|
||||
} // namespace emsesp
|
||||
@@ -31,8 +31,8 @@ WebCustomizationService::WebCustomizationService(AsyncWebServer * server, FS * f
|
||||
securityManager,
|
||||
AuthenticationPredicates::IS_AUTHENTICATED)
|
||||
, _fsPersistence(WebCustomization::read, WebCustomization::update, this, fs, EMSESP_CUSTOMIZATION_FILE)
|
||||
, _masked_entities_handler(CUSTOM_ENTITIES_PATH,
|
||||
securityManager->wrapCallback(std::bind(&WebCustomizationService::custom_entities, this, _1, _2),
|
||||
, _masked_entities_handler(CUSTOMIZATION_ENTITIES_PATH,
|
||||
securityManager->wrapCallback(std::bind(&WebCustomizationService::customization_entities, this, _1, _2),
|
||||
AuthenticationPredicates::IS_AUTHENTICATED)) {
|
||||
server->on(DEVICE_ENTITIES_PATH,
|
||||
HTTP_GET,
|
||||
@@ -54,10 +54,10 @@ WebCustomizationService::WebCustomizationService(AsyncWebServer * server, FS * f
|
||||
}
|
||||
|
||||
// this creates the customization file, saving it to the FS
|
||||
void WebCustomization::read(WebCustomization & settings, JsonObject & root) {
|
||||
void WebCustomization::read(WebCustomization & customizations, JsonObject & root) {
|
||||
// Temperature Sensor customization
|
||||
JsonArray sensorsJson = root.createNestedArray("ts");
|
||||
for (const SensorCustomization & sensor : settings.sensorCustomizations) {
|
||||
for (const SensorCustomization & sensor : customizations.sensorCustomizations) {
|
||||
JsonObject sensorJson = sensorsJson.createNestedObject();
|
||||
sensorJson["id"] = sensor.id; // ID of chip
|
||||
sensorJson["name"] = sensor.name; // n
|
||||
@@ -66,7 +66,7 @@ void WebCustomization::read(WebCustomization & settings, JsonObject & root) {
|
||||
|
||||
// Analog Sensor customization
|
||||
JsonArray analogJson = root.createNestedArray("as");
|
||||
for (const AnalogCustomization & sensor : settings.analogCustomizations) {
|
||||
for (const AnalogCustomization & sensor : customizations.analogCustomizations) {
|
||||
JsonObject sensorJson = analogJson.createNestedObject();
|
||||
sensorJson["gpio"] = sensor.gpio; // g
|
||||
sensorJson["name"] = sensor.name; // n
|
||||
@@ -78,7 +78,7 @@ void WebCustomization::read(WebCustomization & settings, JsonObject & root) {
|
||||
|
||||
// Masked entities customization
|
||||
JsonArray masked_entitiesJson = root.createNestedArray("masked_entities");
|
||||
for (const EntityCustomization & entityCustomization : settings.entityCustomizations) {
|
||||
for (const EntityCustomization & entityCustomization : customizations.entityCustomizations) {
|
||||
JsonObject entityJson = masked_entitiesJson.createNestedObject();
|
||||
entityJson["product_id"] = entityCustomization.product_id;
|
||||
entityJson["device_id"] = entityCustomization.device_id;
|
||||
@@ -93,24 +93,22 @@ void WebCustomization::read(WebCustomization & settings, JsonObject & root) {
|
||||
|
||||
// call on initialization and also when the page is saved via web UI
|
||||
// this loads the data into the internal class
|
||||
StateUpdateResult WebCustomization::update(JsonObject & root, WebCustomization & settings) {
|
||||
StateUpdateResult WebCustomization::update(JsonObject & root, WebCustomization & customizations) {
|
||||
#ifdef EMSESP_STANDALONE
|
||||
// invoke some fake data for testing
|
||||
const char * json = "{\"ts\":[],\"as\":[],\"masked_entities\":[{\"product_id\":123,\"device_id\":8,\"entity_ids\":[\"08heatingactive|my custom "
|
||||
"name for heating active\",\"08tapwateractive\"]}]}";
|
||||
|
||||
const char * json = "{\"ts\":[],\"as\":[],\"masked_entities\":[{\"product_id\":123,\"device_id\":8,\"entity_ids\":[\"08heatingactive|my custom "
|
||||
"name for heating active\",\"08tapwateractive\"]}]}";
|
||||
StaticJsonDocument<500> doc;
|
||||
deserializeJson(doc, json);
|
||||
root = doc.as<JsonObject>();
|
||||
|
||||
Serial.println(COLOR_BRIGHT_MAGENTA);
|
||||
Serial.print("Using custom file: ");
|
||||
Serial.print(" Using fake customization file: ");
|
||||
serializeJson(root, Serial);
|
||||
Serial.println(COLOR_RESET);
|
||||
#endif
|
||||
|
||||
// Temperature Sensor customization
|
||||
settings.sensorCustomizations.clear();
|
||||
customizations.sensorCustomizations.clear();
|
||||
if (root["ts"].is<JsonArray>()) {
|
||||
for (const JsonObject sensorJson : root["ts"].as<JsonArray>()) {
|
||||
// create each of the sensor, overwriting any previous settings
|
||||
@@ -118,12 +116,12 @@ StateUpdateResult WebCustomization::update(JsonObject & root, WebCustomization &
|
||||
sensor.id = sensorJson["id"].as<std::string>();
|
||||
sensor.name = sensorJson["name"].as<std::string>();
|
||||
sensor.offset = sensorJson["offset"];
|
||||
settings.sensorCustomizations.push_back(sensor); // add to list
|
||||
customizations.sensorCustomizations.push_back(sensor); // add to list
|
||||
}
|
||||
}
|
||||
|
||||
// Analog Sensor customization
|
||||
settings.analogCustomizations.clear();
|
||||
customizations.analogCustomizations.clear();
|
||||
if (root["as"].is<JsonArray>()) {
|
||||
for (const JsonObject analogJson : root["as"].as<JsonArray>()) {
|
||||
// create each of the sensor, overwriting any previous settings
|
||||
@@ -134,12 +132,12 @@ StateUpdateResult WebCustomization::update(JsonObject & root, WebCustomization &
|
||||
sensor.factor = analogJson["factor"];
|
||||
sensor.uom = analogJson["uom"];
|
||||
sensor.type = analogJson["type"];
|
||||
settings.analogCustomizations.push_back(sensor); // add to list
|
||||
customizations.analogCustomizations.push_back(sensor); // add to list
|
||||
}
|
||||
}
|
||||
|
||||
// load array of entities id's with masks, building up the object class
|
||||
settings.entityCustomizations.clear();
|
||||
customizations.entityCustomizations.clear();
|
||||
if (root["masked_entities"].is<JsonArray>()) {
|
||||
for (const JsonObject masked_entities : root["masked_entities"].as<JsonArray>()) {
|
||||
auto new_entry = EntityCustomization();
|
||||
@@ -152,7 +150,7 @@ StateUpdateResult WebCustomization::update(JsonObject & root, WebCustomization &
|
||||
}
|
||||
}
|
||||
|
||||
settings.entityCustomizations.push_back(new_entry); // save the new object
|
||||
customizations.entityCustomizations.push_back(new_entry); // save the new object
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,7 +234,7 @@ void WebCustomizationService::device_entities(AsyncWebServerRequest * request) {
|
||||
// takes a list of updated entities with new masks from the web UI
|
||||
// saves it in the customization service
|
||||
// and updates the entity list real-time
|
||||
void WebCustomizationService::custom_entities(AsyncWebServerRequest * request, JsonVariant & json) {
|
||||
void WebCustomizationService::customization_entities(AsyncWebServerRequest * request, JsonVariant & json) {
|
||||
bool need_reboot = false;
|
||||
if (json.is<JsonObject>()) {
|
||||
// find the device using the unique_id
|
||||
@@ -256,7 +254,7 @@ void WebCustomizationService::custom_entities(AsyncWebServerRequest * request, J
|
||||
entity_ids.push_back(id_s);
|
||||
need_reboot = true;
|
||||
} else {
|
||||
emsdevice->setCustomEntity(id_s);
|
||||
emsdevice->setCustomizationEntity(id_s);
|
||||
}
|
||||
// emsesp::EMSESP::logger().info(id.as<const char *>());
|
||||
}
|
||||
@@ -287,7 +285,7 @@ void WebCustomizationService::custom_entities(AsyncWebServerRequest * request, J
|
||||
}
|
||||
});
|
||||
// get list of entities that have masks set or a custom fullname
|
||||
emsdevice->getCustomEntities(entity_ids);
|
||||
emsdevice->getCustomizationEntities(entity_ids);
|
||||
|
||||
// Save the list to the customization file
|
||||
EMSESP::webCustomizationService.update(
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#define DEVICE_ENTITIES_PATH "/rest/deviceEntities"
|
||||
|
||||
// POST
|
||||
#define CUSTOM_ENTITIES_PATH "/rest/customEntities"
|
||||
#define CUSTOMIZATION_ENTITIES_PATH "/rest/customizationEntities"
|
||||
#define RESET_CUSTOMIZATION_SERVICE_PATH "/rest/resetCustomizations"
|
||||
|
||||
namespace emsesp {
|
||||
@@ -71,8 +71,8 @@ class WebCustomization {
|
||||
std::list<SensorCustomization> sensorCustomizations; // for sensor names and offsets
|
||||
std::list<AnalogCustomization> analogCustomizations; // for analog sensors
|
||||
std::list<EntityCustomization> entityCustomizations; // for a list of entities that have a special mask set
|
||||
static void read(WebCustomization & settings, JsonObject & root);
|
||||
static StateUpdateResult update(JsonObject & root, WebCustomization & settings);
|
||||
static void read(WebCustomization & customizations, JsonObject & root);
|
||||
static StateUpdateResult update(JsonObject & root, WebCustomization & customizations);
|
||||
};
|
||||
|
||||
class WebCustomizationService : public StatefulService<WebCustomization> {
|
||||
@@ -94,7 +94,7 @@ class WebCustomizationService : public StatefulService<WebCustomization> {
|
||||
void device_entities(AsyncWebServerRequest * request);
|
||||
|
||||
// POST
|
||||
void custom_entities(AsyncWebServerRequest * request, JsonVariant & json);
|
||||
void customization_entities(AsyncWebServerRequest * request, JsonVariant & json);
|
||||
void reset_customization(AsyncWebServerRequest * request); // command
|
||||
|
||||
AsyncCallbackJsonWebHandler _masked_entities_handler;
|
||||
|
||||
@@ -92,7 +92,7 @@ void WebDataService::core_data(AsyncWebServerRequest * request) {
|
||||
}
|
||||
|
||||
// add any custom entities
|
||||
if (EMSESP::webEntityService.count_entities()) {
|
||||
if (EMSESP::webCustomEntityService.count_entities()) {
|
||||
JsonObject obj = devices.createNestedObject();
|
||||
obj["id"] = 99; // the last unique id
|
||||
obj["tn"] = Helpers::translated_word(FL_(custom_device)); // translated device type name
|
||||
@@ -210,7 +210,7 @@ void WebDataService::device_data(AsyncWebServerRequest * request) {
|
||||
#ifndef EMSESP_STANDALONE
|
||||
if (id == 99) {
|
||||
JsonObject output = response->getRoot();
|
||||
EMSESP::webEntityService.generate_value_web(output);
|
||||
EMSESP::webCustomEntityService.generate_value_web(output);
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
return;
|
||||
@@ -251,7 +251,7 @@ void WebDataService::write_device_value(AsyncWebServerRequest * request, JsonVar
|
||||
return_code = Command::call(device_type, cmd, data.as<const char *>(), true, id, output);
|
||||
} else if (data.is<int>()) {
|
||||
char s[10];
|
||||
return_code = Command::call(device_type, cmd, Helpers::render_value(s, data.as<int16_t>(), 0), true, id, output);
|
||||
return_code = Command::call(device_type, cmd, Helpers::render_value(s, data.as<int>(), 0), true, id, output);
|
||||
} else if (data.is<float>()) {
|
||||
char s[10];
|
||||
return_code = Command::call(device_type, cmd, Helpers::render_value(s, data.as<float>(), 1), true, id, output);
|
||||
@@ -288,7 +288,7 @@ void WebDataService::write_device_value(AsyncWebServerRequest * request, JsonVar
|
||||
return_code = Command::call(device_type, cmd, data.as<const char *>(), true, id, output);
|
||||
} else if (data.is<int>()) {
|
||||
char s[10];
|
||||
return_code = Command::call(device_type, cmd, Helpers::render_value(s, data.as<int16_t>(), 0), true, id, output);
|
||||
return_code = Command::call(device_type, cmd, Helpers::render_value(s, data.as<int>(), 0), true, id, output);
|
||||
} else if (data.is<float>()) {
|
||||
char s[10];
|
||||
return_code = Command::call(device_type, cmd, Helpers::render_value(s, data.as<float>(), 1), true, id, output);
|
||||
|
||||
@@ -57,12 +57,13 @@ StateUpdateResult WebScheduler::update(JsonObject & root, WebScheduler & webSche
|
||||
#ifdef EMSESP_STANDALONE
|
||||
// invoke some fake data for testing
|
||||
const char * json =
|
||||
"{[{\"id\":1,\"active\":true,\"flags\":31,\"time\": \"07:30\",\"cmd\": \"hc1/mode\",\"value\": \"day\",\"name\": \"turn on central heating\"}]}";
|
||||
"{\"schedule\": [{\"id\":1,\"active\":true,\"flags\":31,\"time\": \"07:30\",\"cmd\": \"hc1mode\",\"value\": \"day\",\"name\": \"turn on "
|
||||
"central heating\"}]}";
|
||||
StaticJsonDocument<500> doc;
|
||||
deserializeJson(doc, json);
|
||||
root = doc.as<JsonObject>();
|
||||
Serial.println(COLOR_BRIGHT_MAGENTA);
|
||||
Serial.print("Using custom file: ");
|
||||
Serial.print(" Using fake scheduler file: ");
|
||||
serializeJson(root, Serial);
|
||||
Serial.println(COLOR_RESET);
|
||||
#endif
|
||||
@@ -132,12 +133,9 @@ bool WebSchedulerService::command_setvalue(const char * value, const std::string
|
||||
// process json output for info/commands and value_info
|
||||
bool WebSchedulerService::get_value_info(JsonObject & output, const char * cmd) {
|
||||
EMSESP::webSchedulerService.read([&](WebScheduler & webScheduler) { scheduleItems = &webScheduler.scheduleItems; });
|
||||
if (scheduleItems->size() == 0) {
|
||||
return false;
|
||||
}
|
||||
if (Helpers::toLower(cmd) == "commands") {
|
||||
output["info"] = "lists all values";
|
||||
output["commands"] = "lists all commands";
|
||||
if (Helpers::toLower(cmd) == F_(commands)) {
|
||||
output[F_(info)] = Helpers::translated_word(FL_(info_cmd));
|
||||
output[F_(commands)] = Helpers::translated_word(FL_(commands_cmd));
|
||||
for (const ScheduleItem & scheduleItem : *scheduleItems) {
|
||||
if (!scheduleItem.name.empty()) {
|
||||
output[scheduleItem.name] = "activate schedule";
|
||||
@@ -145,7 +143,10 @@ bool WebSchedulerService::get_value_info(JsonObject & output, const char * cmd)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (strlen(cmd) == 0 || Helpers::toLower(cmd) == "values" || Helpers::toLower(cmd) == "info") {
|
||||
if (scheduleItems->size() == 0) {
|
||||
return true;
|
||||
}
|
||||
if (strlen(cmd) == 0 || Helpers::toLower(cmd) == F_(values) || Helpers::toLower(cmd) == F_(info)) {
|
||||
// list all names
|
||||
for (const ScheduleItem & scheduleItem : *scheduleItems) {
|
||||
if (!scheduleItem.name.empty()) {
|
||||
|
||||
@@ -148,7 +148,7 @@ void WebStatusService::webStatusService(AsyncWebServerRequest * request) {
|
||||
statJson["f"] = EMSESP::txservice_.telegram_write_fail_count();
|
||||
statJson["q"] = EMSESP::txservice_.write_quality();
|
||||
|
||||
if (EMSESP::temperaturesensor_.sensor_enabled()) {
|
||||
if (EMSESP::sensor_enabled()) {
|
||||
statJson = statsJson.createNestedObject();
|
||||
statJson["id"] = 3;
|
||||
statJson["s"] = EMSESP::temperaturesensor_.reads();
|
||||
@@ -175,8 +175,9 @@ void WebStatusService::webStatusService(AsyncWebServerRequest * request) {
|
||||
statJson["id"] = 6;
|
||||
statJson["s"] = WebAPIService::api_count(); // + WebAPIService::api_fails();
|
||||
statJson["f"] = WebAPIService::api_fails();
|
||||
statJson["q"] =
|
||||
WebAPIService::api_count() == 0 ? 100 : 100 - (uint8_t)((100 * WebAPIService::api_fails()) / (WebAPIService::api_count() + WebAPIService::api_fails()));
|
||||
statJson["q"] = (WebAPIService::api_count() + WebAPIService::api_fails()) == 0
|
||||
? 100
|
||||
: 100 - (uint8_t)((100 * WebAPIService::api_fails()) / (WebAPIService::api_count() + WebAPIService::api_fails()));
|
||||
|
||||
#ifndef EMSESP_STANDALONE
|
||||
if (EMSESP::system_.syslog_enabled()) {
|
||||
@@ -184,7 +185,7 @@ void WebStatusService::webStatusService(AsyncWebServerRequest * request) {
|
||||
statJson["id"] = 7;
|
||||
statJson["s"] = EMSESP::system_.syslog_count();
|
||||
statJson["f"] = EMSESP::system_.syslog_fails();
|
||||
statJson["q"] = EMSESP::system_.syslog_count() == 0
|
||||
statJson["q"] = (EMSESP::system_.syslog_count() + EMSESP::system_.syslog_fails()) == 0
|
||||
? 100
|
||||
: 100 - (uint8_t)((100 * EMSESP::system_.syslog_fails()) / (EMSESP::system_.syslog_count() + EMSESP::system_.syslog_fails()));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user