Merge pull request #1991 from proddy/dev

some minor fixes
This commit is contained in:
Proddy
2024-09-11 15:04:15 +02:00
committed by GitHub
60 changed files with 1045 additions and 903 deletions

View File

@@ -10,6 +10,7 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: GitHub Releases To Discord - name: GitHub Releases To Discord
uses: SethCohen/github-releases-to-discord@v1.13.1 uses: SethCohen/github-releases-to-discord@v1.13.1
with: with:

View File

@@ -11,25 +11,33 @@ jobs:
name: 'Automatic pre-release build' name: 'Automatic pre-release build'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - name: Checkout repository
uses: actions/checkout@v4
- name: Enable Corepack - name: Enable Corepack
run: corepack enable run: corepack enable
- uses: actions/setup-python@v5
- name: Install python 3.11
uses: actions/setup-python@v5
with: with:
python-version: '3.11' python-version: '3.11'
- name: Use Node.js 20.x
- name: Install Node.js 20
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: '20.x' node-version: '20.x'
- name: Get EMS-ESP source code and version
- name: Get EMS-ESP version
id: build_info id: build_info
run: | run: |
version=`grep -E '^#define EMSESP_APP_VERSION' ./src/version.h | awk -F'"' '{print $2}'` version=`grep -E '^#define EMSESP_APP_VERSION' ./src/version.h | awk -F'"' '{print $2}'`
echo "VERSION=$version" >> $GITHUB_OUTPUT echo "VERSION=$version" >> $GITHUB_OUTPUT
- name: Install PlatformIO - name: Install PlatformIO
run: | run: |
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install -U platformio pip install -U platformio
- name: Build WebUI - name: Build WebUI
run: | run: |
cd interface cd interface
@@ -38,9 +46,11 @@ jobs:
sed -i "s/= 'pl'/= 'en'/" ./src/i18n/i18n-util.ts sed -i "s/= 'pl'/= 'en'/" ./src/i18n/i18n-util.ts
yarn build yarn build
yarn webUI yarn webUI
- name: Build all target environments from default_envs
- name: Build all PIO target environments from default_envs
run: | run: |
platformio run platformio run
- name: Create GitHub Release - name: Create GitHub Release
id: 'automatic_releases' id: 'automatic_releases'
uses: emsesp/action-automatic-releases@v1.0.0 uses: emsesp/action-automatic-releases@v1.0.0

View File

@@ -16,13 +16,17 @@ jobs:
env: env:
BUILD_WRAPPER_OUT_DIR: bw-output BUILD_WRAPPER_OUT_DIR: bw-output
steps: steps:
- uses: actions/checkout@v4 - name: Checkout repository
uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Install sonar-scanner and build-wrapper - name: Install sonar-scanner and build-wrapper
uses: SonarSource/sonarcloud-github-c-cpp@v2 uses: SonarSource/sonarcloud-github-c-cpp@v2
- name: Run build-wrapper - name: Run build-wrapper
run: build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} make all run: build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} make all
- name: Run sonar-scanner - name: Run sonar-scanner
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -11,22 +11,27 @@ jobs:
name: 'Tagged Release' name: 'Tagged Release'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - name: Checkout repository
uses: actions/checkout@v4
- name: Enable Corepack - name: Enable Corepack
run: corepack enable run: corepack enable
- uses: actions/setup-python@v5
- name: Install python 3.11
uses: actions/setup-python@v5
with: with:
python-version: '3.11' python-version: '3.11'
- name: Use Node.js 20.x
- name: Install Node.js 20
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: '20.x' node-version: '20.x'
- name: Install PlatformIO - name: Install PlatformIO
run: | run: |
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install -U platformio pip install -U platformio
platformio upgrade
pio pkg update
- name: Build WebUI - name: Build WebUI
run: | run: |
cd interface cd interface
@@ -35,9 +40,11 @@ jobs:
sed -i "s/= 'pl'/= 'en'/" ./src/i18n/i18n-util.ts sed -i "s/= 'pl'/= 'en'/" ./src/i18n/i18n-util.ts
yarn build yarn build
yarn webUI yarn webUI
- name: Build all target environments from default_envs
- name: Build all PIO target environments from default_envs
run: | run: |
platformio run platformio run
- name: Create GitHub Release - name: Create GitHub Release
uses: emsesp/action-automatic-releases@v1.0.0 uses: emsesp/action-automatic-releases@v1.0.0
with: with:

2
.gitignore vendored
View File

@@ -2,7 +2,7 @@
.vscode/c_cpp_properties.json .vscode/c_cpp_properties.json
.vscode/extensions.json .vscode/extensions.json
.vscode/launch.json .vscode/launch.json
#.vscode/settings.json .vscode/settings.json
# c++ compiling # c++ compiling
.clang_complete .clang_complete

View File

@@ -89,7 +89,8 @@
"**/ArduinoJson/**" "**/ArduinoJson/**"
], ],
"cSpell.enableFiletypes": [ "cSpell.enableFiletypes": [
"!typescript" "ini",
"makefile"
], ],
"typescript.preferences.preferTypeOnlyAutoImports": true "typescript.preferences.preferTypeOnlyAutoImports": true
} }

View File

@@ -35,12 +35,17 @@
- RC310 cooling parameters [#1857](https://github.com/emsesp/EMS-ESP32/issues/1857) - RC310 cooling parameters [#1857](https://github.com/emsesp/EMS-ESP32/issues/1857)
- command `api/device/entities` [#1897](https://github.com/emsesp/EMS-ESP32/issues/1897) - command `api/device/entities` [#1897](https://github.com/emsesp/EMS-ESP32/issues/1897)
- switchprogmode [#1903]<https://github.com/emsesp/EMS-ESP32/discussions/1903> - switchprogmode [#1903]<https://github.com/emsesp/EMS-ESP32/discussions/1903>
- Autodetect and download firmware upgrades - Autodetect and download firmware upgrades via the WebUI
- command 'show log' that lists out the current weblog buffer, showing last messages.
- default web log buffer to 25 lines for ESP32s with no PSRAM
- Try and determine correct board profile if none is set
## Fixed ## Fixed
- remote thermostat emulation for RC200 on Rego2000/3000 thermostats [#1691](https://github.com/emsesp/EMS-ESP32/discussions/1691) - remote thermostat emulation for RC200 on Rego2000/3000 thermostats [#1691](https://github.com/emsesp/EMS-ESP32/discussions/1691)
- log shows data for F7/F9 requests - log shows data for F7/F9 requests
- Detection of LittleFS for factory setting wasn't working
- Check for bad GPIOs with Ethernet before the ethernet is initialized
## Changed ## Changed
@@ -58,4 +63,5 @@
- Change key-names in JSON to be compliant and consistent [#1860](https://github.com/emsesp/EMS-ESP32/issues/1860) - Change key-names in JSON to be compliant and consistent [#1860](https://github.com/emsesp/EMS-ESP32/issues/1860)
- Updates to webUI [#1920](https://github.com/emsesp/EMS-ESP32/issues/1920) - Updates to webUI [#1920](https://github.com/emsesp/EMS-ESP32/issues/1920)
- Correct firmware naming #1933 [#1933](https://github.com/emsesp/EMS-ESP32/issues/1933) - Correct firmware naming #1933 [#1933](https://github.com/emsesp/EMS-ESP32/issues/1933)
- Don't start Serial console if not connected to a Serial port. Will initiate manually after a CTRL-C
- WebLog UI matches color schema of the terminal console correctly

View File

@@ -81,8 +81,8 @@ CPPFLAGS += -g3
CPPFLAGS += -Os CPPFLAGS += -Os
CFLAGS += $(CPPFLAGS) CFLAGS += $(CPPFLAGS)
CFLAGS += -Wall -Wextra -Werror -Wswitch-enum -Wno-unused-parameter -Wno-inconsistent-missing-override -Wno-missing-braces -Wno-unused-lambda-capture -Wno-sign-compare CFLAGS += -Wall -Wextra -Werror -Wswitch-enum
CFLAGS += -Wno-tautological-constant-out-of-range-compare -Wno-unused-parameter -Wno-inconsistent-missing-override -Wno-missing-braces -Wno-unused-lambda-capture -Wno-sign-compare
CXXFLAGS += $(CFLAGS) -MMD CXXFLAGS += $(CFLAGS) -MMD
#---------------------------------------------------------------------- #----------------------------------------------------------------------

View File

@@ -23,9 +23,13 @@
- Easy first-time configuration via a web Captive Portal - Easy first-time configuration via a web Captive Portal
- Support for more than [120+ EMS devices](https://emsesp.org/All-Devices/) (boilers, thermostats, solar modules, mixer modules, heat pumps, gateways, switches, heat sources) - Support for more than [120+ EMS devices](https://emsesp.org/All-Devices/) (boilers, thermostats, solar modules, mixer modules, heat pumps, gateways, switches, heat sources)
## **Installing**
Go to [install.emsesp.org](https://install.emsesp.org) or look at the documentation link below on the different ways to install EMS-ESP.
## **Documentation** ## **Documentation**
For the complete documentation on how to install, configure and get support visit the [EMS-ESP Wiki](https://emsesp.org). For the complete documentation on how to install, configure and get support visit the [documentation at emsesp.org](https://emsesp.org).
## **Support** ## **Support**
@@ -35,7 +39,7 @@ If you like **EMS-ESP**, please give it a star, or fork it and contribute or off
## **Demo** ## **Demo**
For a live demo of the Web UI click [here](https://demo.emsesp.org) and log in with any username/password. For a live demo of the Web UI click [demo.emsesp.org](https://demo.emsesp.org) and log in with any username/password, and change the language to English.
## **Contributors ✨** ## **Contributors ✨**
@@ -67,6 +71,6 @@ This program is licensed under GPL-3.0
![Console](media/console0.png) ![Console](media/console0.png)
### In Home Assistant ### Home Assistant
![Home Assistant](media/ha_lovelace.png) ![Home Assistant](media/ha_lovelace.png)

View File

@@ -40,12 +40,12 @@ CS6800i/WLW176i,boiler,8,emergencytemp,emergency temperature,uint8 (>=15<=70),C,
CS6800i/WLW176i,boiler,8,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal,5,0,1/100,80,2 CS6800i/WLW176i,boiler,8,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal,5,0,1/100,80,2
CS6800i/WLW176i,boiler,8,nrg,energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_dhw_energy,sensor.boiler_dhw_nrg,5,9,1/100,0,2 CS6800i/WLW176i,boiler,8,nrg,energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_dhw_energy,sensor.boiler_dhw_nrg,5,9,1/100,0,2
CS6800i/WLW176i,boiler,8,nrgheat,energy heating,uint24 (>=0<=167772),kWh,false,sensor.boiler_energy_heating,sensor.boiler_nrgheat,5,0,1/100,82,2 CS6800i/WLW176i,boiler,8,nrgheat,energy heating,uint24 (>=0<=167772),kWh,false,sensor.boiler_energy_heating,sensor.boiler_nrgheat,5,0,1/100,82,2
CS6800i/WLW176i,boiler,8,nrgcool,energy cooling,uint24 (>=0<=167772),kWh,false,sensor.boiler_energy_cooling,sensor.boiler_nrgcool,5,0,1/100,-1,2 CS6800i/WLW176i,boiler,8,nrgcool,energy cooling,uint24 (>=0<=167772),kWh,false,sensor.boiler_energy_cooling,sensor.boiler_nrgcool,5,0,1/100,264,2
CS6800i/WLW176i,boiler,8,metertotal,meter total,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_total,sensor.boiler_metertotal,5,0,1/100,84,2 CS6800i/WLW176i,boiler,8,metertotal,meter total,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_total,sensor.boiler_metertotal,5,0,1/100,84,2
CS6800i/WLW176i,boiler,8,metercomp,meter compressor,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_compressor,sensor.boiler_metercomp,5,0,1/100,86,2 CS6800i/WLW176i,boiler,8,metercomp,meter compressor,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_compressor,sensor.boiler_metercomp,5,0,1/100,86,2
CS6800i/WLW176i,boiler,8,metereheat,meter e-heater,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_e-heater,sensor.boiler_metereheat,5,0,1/100,88,2 CS6800i/WLW176i,boiler,8,metereheat,meter e-heater,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_e-heater,sensor.boiler_metereheat,5,0,1/100,88,2
CS6800i/WLW176i,boiler,8,meterheat,meter heating,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat,5,0,1/100,90,2 CS6800i/WLW176i,boiler,8,meterheat,meter heating,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat,5,0,1/100,90,2
CS6800i/WLW176i,boiler,8,metercool,meter cooling,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_cooling,sensor.boiler_metercool,5,0,1/100,-1,2 CS6800i/WLW176i,boiler,8,metercool,meter cooling,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_cooling,sensor.boiler_metercool,5,0,1/100,266,2
CS6800i/WLW176i,boiler,8,meter,meter,uint24 (>=0<=167772),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meter,5,9,1/100,2,2 CS6800i/WLW176i,boiler,8,meter,meter,uint24 (>=0<=167772),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meter,5,9,1/100,2,2
CS6800i/WLW176i,boiler,8,uptimetotal,heatpump total uptime,time (>=0<=279620),minutes,false,sensor.boiler_heatpump_total_uptime,sensor.boiler_uptimetotal,5,0,1/60,92,2 CS6800i/WLW176i,boiler,8,uptimetotal,heatpump total uptime,time (>=0<=279620),minutes,false,sensor.boiler_heatpump_total_uptime,sensor.boiler_uptimetotal,5,0,1/60,92,2
CS6800i/WLW176i,boiler,8,uptimecontrol,total operating time heat,time (>=0<=279620),minutes,false,sensor.boiler_total_operating_time_heat,sensor.boiler_uptimecontrol,5,0,1/60,94,2 CS6800i/WLW176i,boiler,8,uptimecontrol,total operating time heat,time (>=0<=279620),minutes,false,sensor.boiler_total_operating_time_heat,sensor.boiler_uptimecontrol,5,0,1/60,94,2
@@ -2090,12 +2090,12 @@ 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,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal,5,0,1/100,80,2 Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal,5,0,1/100,80,2
Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrg,energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_dhw_energy,sensor.boiler_dhw_nrg,5,9,1/100,0,2 Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrg,energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_dhw_energy,sensor.boiler_dhw_nrg,5,9,1/100,0,2
Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgheat,energy heating,uint24 (>=0<=167772),kWh,false,sensor.boiler_energy_heating,sensor.boiler_nrgheat,5,0,1/100,82,2 Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgheat,energy heating,uint24 (>=0<=167772),kWh,false,sensor.boiler_energy_heating,sensor.boiler_nrgheat,5,0,1/100,82,2
Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgcool,energy cooling,uint24 (>=0<=167772),kWh,false,sensor.boiler_energy_cooling,sensor.boiler_nrgcool,5,0,1/100,-1,2 Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,nrgcool,energy cooling,uint24 (>=0<=167772),kWh,false,sensor.boiler_energy_cooling,sensor.boiler_nrgcool,5,0,1/100,264,2
Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,metertotal,meter total,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_total,sensor.boiler_metertotal,5,0,1/100,84,2 Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,metertotal,meter total,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_total,sensor.boiler_metertotal,5,0,1/100,84,2
Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,metercomp,meter compressor,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_compressor,sensor.boiler_metercomp,5,0,1/100,86,2 Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,metercomp,meter compressor,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_compressor,sensor.boiler_metercomp,5,0,1/100,86,2
Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,metereheat,meter e-heater,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_e-heater,sensor.boiler_metereheat,5,0,1/100,88,2 Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,metereheat,meter e-heater,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_e-heater,sensor.boiler_metereheat,5,0,1/100,88,2
Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,meterheat,meter heating,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat,5,0,1/100,90,2 Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,meterheat,meter heating,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat,5,0,1/100,90,2
Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,metercool,meter cooling,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_cooling,sensor.boiler_metercool,5,0,1/100,-1,2 Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,metercool,meter cooling,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_cooling,sensor.boiler_metercool,5,0,1/100,266,2
Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,meter,meter,uint24 (>=0<=167772),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meter,5,9,1/100,2,2 Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,meter,meter,uint24 (>=0<=167772),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meter,5,9,1/100,2,2
Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,uptimetotal,heatpump total uptime,time (>=0<=279620),minutes,false,sensor.boiler_heatpump_total_uptime,sensor.boiler_uptimetotal,5,0,1/60,92,2 Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,uptimetotal,heatpump total uptime,time (>=0<=279620),minutes,false,sensor.boiler_heatpump_total_uptime,sensor.boiler_uptimetotal,5,0,1/60,92,2
Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,uptimecontrol,total operating time heat,time (>=0<=279620),minutes,false,sensor.boiler_total_operating_time_heat,sensor.boiler_uptimecontrol,5,0,1/60,94,2 Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i,boiler,172,uptimecontrol,total operating time heat,time (>=0<=279620),minutes,false,sensor.boiler_total_operating_time_heat,sensor.boiler_uptimecontrol,5,0,1/60,94,2
@@ -2287,12 +2287,12 @@ Geo 5xx,boiler,173,emergencytemp,emergency temperature,uint8 (>=15<=70),C,true,n
Geo 5xx,boiler,173,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal,5,0,1/100,80,2 Geo 5xx,boiler,173,nrgtotal,total energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_total_energy,sensor.boiler_nrgtotal,5,0,1/100,80,2
Geo 5xx,boiler,173,nrg,energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_dhw_energy,sensor.boiler_dhw_nrg,5,9,1/100,0,2 Geo 5xx,boiler,173,nrg,energy,uint24 (>=0<=167772),kWh,false,sensor.boiler_dhw_energy,sensor.boiler_dhw_nrg,5,9,1/100,0,2
Geo 5xx,boiler,173,nrgheat,energy heating,uint24 (>=0<=167772),kWh,false,sensor.boiler_energy_heating,sensor.boiler_nrgheat,5,0,1/100,82,2 Geo 5xx,boiler,173,nrgheat,energy heating,uint24 (>=0<=167772),kWh,false,sensor.boiler_energy_heating,sensor.boiler_nrgheat,5,0,1/100,82,2
Geo 5xx,boiler,173,nrgcool,energy cooling,uint24 (>=0<=167772),kWh,false,sensor.boiler_energy_cooling,sensor.boiler_nrgcool,5,0,1/100,-1,2 Geo 5xx,boiler,173,nrgcool,energy cooling,uint24 (>=0<=167772),kWh,false,sensor.boiler_energy_cooling,sensor.boiler_nrgcool,5,0,1/100,264,2
Geo 5xx,boiler,173,metertotal,meter total,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_total,sensor.boiler_metertotal,5,0,1/100,84,2 Geo 5xx,boiler,173,metertotal,meter total,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_total,sensor.boiler_metertotal,5,0,1/100,84,2
Geo 5xx,boiler,173,metercomp,meter compressor,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_compressor,sensor.boiler_metercomp,5,0,1/100,86,2 Geo 5xx,boiler,173,metercomp,meter compressor,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_compressor,sensor.boiler_metercomp,5,0,1/100,86,2
Geo 5xx,boiler,173,metereheat,meter e-heater,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_e-heater,sensor.boiler_metereheat,5,0,1/100,88,2 Geo 5xx,boiler,173,metereheat,meter e-heater,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_e-heater,sensor.boiler_metereheat,5,0,1/100,88,2
Geo 5xx,boiler,173,meterheat,meter heating,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat,5,0,1/100,90,2 Geo 5xx,boiler,173,meterheat,meter heating,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_heating,sensor.boiler_meterheat,5,0,1/100,90,2
Geo 5xx,boiler,173,metercool,meter cooling,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_cooling,sensor.boiler_metercool,5,0,1/100,-1,2 Geo 5xx,boiler,173,metercool,meter cooling,uint24 (>=0<=167772),kWh,false,sensor.boiler_meter_cooling,sensor.boiler_metercool,5,0,1/100,266,2
Geo 5xx,boiler,173,meter,meter,uint24 (>=0<=167772),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meter,5,9,1/100,2,2 Geo 5xx,boiler,173,meter,meter,uint24 (>=0<=167772),kWh,false,sensor.boiler_dhw_meter,sensor.boiler_dhw_meter,5,9,1/100,2,2
Geo 5xx,boiler,173,uptimetotal,heatpump total uptime,time (>=0<=279620),minutes,false,sensor.boiler_heatpump_total_uptime,sensor.boiler_uptimetotal,5,0,1/60,92,2 Geo 5xx,boiler,173,uptimetotal,heatpump total uptime,time (>=0<=279620),minutes,false,sensor.boiler_heatpump_total_uptime,sensor.boiler_uptimetotal,5,0,1/60,92,2
Geo 5xx,boiler,173,uptimecontrol,total operating time heat,time (>=0<=279620),minutes,false,sensor.boiler_total_operating_time_heat,sensor.boiler_uptimecontrol,5,0,1/60,94,2 Geo 5xx,boiler,173,uptimecontrol,total operating time heat,time (>=0<=279620),minutes,false,sensor.boiler_total_operating_time_heat,sensor.boiler_uptimecontrol,5,0,1/60,94,2
@@ -3355,16 +3355,16 @@ UI800/BC400,thermostat,4,hpoperatingstate,heatpump operating state,enum [heating
UI800/BC400,thermostat,4,controlmode,control mode,enum [weather compensated\|outside basepoint\|n/a\|room\|power\|constant], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode,6,1,1,24,1 UI800/BC400,thermostat,4,controlmode,control mode,enum [weather compensated\|outside basepoint\|n/a\|room\|power\|constant], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode,6,1,1,24,1
UI800/BC400,thermostat,4,program,program,enum [prog 1\|prog 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program,6,1,1,25,1 UI800/BC400,thermostat,4,program,program,enum [prog 1\|prog 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program,6,1,1,25,1
UI800/BC400,thermostat,4,tempautotemp,temporary set temperature automode,int8 (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp,6,1,1/2,26,1 UI800/BC400,thermostat,4,tempautotemp,temporary set temperature automode,int8 (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp,6,1,1/2,26,1
UI800/BC400,thermostat,4,remoteseltemp,temporary set temperature from remote,int8 (>=-63<=63),C,false,sensor.thermostat_hc1_temporary_set_temperature_from_remote,sensor.thermostat_hc1_remoteseltemp,6,1,1/2,27,1 UI800/BC400,thermostat,4,remoteseltemp,temporary set temperature from remote,int8 (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_from_remote,number.thermostat_hc1_remoteseltemp,6,1,1/2,27,1
UI800/BC400,thermostat,4,fastheatup,fast heatup,uint8 (>=0<=100),%,true,number.thermostat_hc1_fast_heatup,number.thermostat_hc1_fastheatup,6,1,1,28,1 UI800/BC400,thermostat,4,fastheatup,fast heatup,uint8 (>=0<=100),%,true,number.thermostat_hc1_fast_heatup,number.thermostat_hc1_fastheatup,6,1,1,28,1
UI800/BC400,thermostat,4,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization,6,1,1,29,1 UI800/BC400,thermostat,4,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization,6,1,1,29,1
UI800/BC400,thermostat,4,reducemode,reduce mode,enum [outdoor\|room\|reduce], ,true,select.thermostat_hc1_reduce_mode,select.thermostat_hc1_reducemode,6,1,1,30,1 UI800/BC400,thermostat,4,reducemode,reduce mode,enum [outdoor\|room\|reduce], ,true,select.thermostat_hc1_reduce_mode,select.thermostat_hc1_reducemode,6,1,1,30,1
UI800/BC400,thermostat,4,noreducetemp,no reduce below temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp,6,1,1,31,1 UI800/BC400,thermostat,4,noreducetemp,no reduce below temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp,6,1,1,31,1
UI800/BC400,thermostat,4,reducetemp,off/reduce switch temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp,6,1,1,32,1 UI800/BC400,thermostat,4,reducetemp,off/reduce switch temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp,6,1,1,32,1
UI800/BC400,thermostat,4,dhwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_dhwprio,6,1,1,33,1 UI800/BC400,thermostat,4,dhwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_dhwprio,6,1,1,33,1
UI800/BC400,thermostat,4,cooling,cooling,boolean, ,true,switch.thermostat_hc1_cooling,switch.thermostat_hc1_cooling,6,1,1,34,1 UI800/BC400,thermostat,4,hpcooling,hp cooling,boolean, ,true,switch.thermostat_hc1_hp_cooling,switch.thermostat_hc1_hpcooling,6,1,1,34,1
UI800/BC400,thermostat,4,coolingon,cooling,boolean, ,false,binary_sensor.thermostat_hc1_cooling,binary_sensor.thermostat_hc1_coolingon,6,1,1,35,1 UI800/BC400,thermostat,4,coolingon,cooling on,boolean, ,false,binary_sensor.thermostat_hc1_cooling_on,binary_sensor.thermostat_hc1_coolingon,6,1,1,35,1
UI800/BC400,thermostat,4,hpmode,HP Mode,enum [heating\|cooling\|heating&cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode,6,1,1,36,1 UI800/BC400,thermostat,4,hpmode,HP Mode,enum [heating\|cooling\|heating & cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode,6,1,1,36,1
UI800/BC400,thermostat,4,dewoffset,dew point offset,uint8 (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset,6,1,1,37,1 UI800/BC400,thermostat,4,dewoffset,dew point offset,uint8 (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset,6,1,1,37,1
UI800/BC400,thermostat,4,roomtempdiff,room temp difference,uint8 (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff,6,1,1,38,1 UI800/BC400,thermostat,4,roomtempdiff,room temp difference,uint8 (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff,6,1,1,38,1
UI800/BC400,thermostat,4,hpminflowtemp,HP min. flow temp.,uint8 (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp,6,1,1,39,1 UI800/BC400,thermostat,4,hpminflowtemp,HP min. flow temp.,uint8 (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp,6,1,1,39,1
@@ -3376,10 +3376,10 @@ UI800/BC400,thermostat,4,heatoffdelay,heat-off delay,uint8 (>=1<=48),hours,true,
UI800/BC400,thermostat,4,instantstart,instant start,uint8 (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart,6,1,1,45,1 UI800/BC400,thermostat,4,instantstart,instant start,uint8 (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart,6,1,1,45,1
UI800/BC400,thermostat,4,boost,boost mode,boolean, ,true,switch.thermostat_hc1_boost_mode,switch.thermostat_hc1_boost,6,1,1,46,1 UI800/BC400,thermostat,4,boost,boost mode,boolean, ,true,switch.thermostat_hc1_boost_mode,switch.thermostat_hc1_boost,6,1,1,46,1
UI800/BC400,thermostat,4,boosttime,boost time,uint8 (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime,6,1,1,47,1 UI800/BC400,thermostat,4,boosttime,boost time,uint8 (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime,6,1,1,47,1
UI800/BC400,thermostat,4,coolstart,cooling starttemp,uint8 (>=20<=35),C,true,number.thermostat_hc1_cooling_starttemp,number.thermostat_hc1_coolstart,6,1,1,-1,1 UI800/BC400,thermostat,4,coolstart,cooling starttemp,uint8 (>=20<=35),C,true,number.thermostat_hc1_cooling_starttemp,number.thermostat_hc1_coolstart,6,1,1,193,1
UI800/BC400,thermostat,4,coolondelay,cooling on delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_on_delay,number.thermostat_hc1_coolondelay,6,1,1,-1,1 UI800/BC400,thermostat,4,coolondelay,cooling on delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_on_delay,number.thermostat_hc1_coolondelay,6,1,1,194,1
UI800/BC400,thermostat,4,cooloffdelay,cooling off delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_off_delay,number.thermostat_hc1_cooloffdelay,6,1,1,-1,1 UI800/BC400,thermostat,4,cooloffdelay,cooling off delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_off_delay,number.thermostat_hc1_cooloffdelay,6,1,1,195,1
UI800/BC400,thermostat,4,switchprogmode,switch program mode,enum [level\|absolute], ,true,select.thermostat_hc1_switch_program_mode,select.thermostat_hc1_switchprogmode,6,1,1,-1,1 UI800/BC400,thermostat,4,switchprogmode,switch program mode,enum [level\|absolute], ,true,select.thermostat_hc1_switch_program_mode,select.thermostat_hc1_switchprogmode,6,1,1,196,1
UI800/BC400,thermostat,4,mode,mode,enum [off\|eco+\|eco\|comfort\|auto], ,true,select.thermostat_dhw_mode,select.thermostat_dhw_mode,6,9,1,0,1 UI800/BC400,thermostat,4,mode,mode,enum [off\|eco+\|eco\|comfort\|auto], ,true,select.thermostat_dhw_mode,select.thermostat_dhw_mode,6,9,1,0,1
UI800/BC400,thermostat,4,settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp,6,9,1,1,1 UI800/BC400,thermostat,4,settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp,6,9,1,1,1
UI800/BC400,thermostat,4,settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow,6,9,1,2,1 UI800/BC400,thermostat,4,settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow,6,9,1,2,1
@@ -3471,7 +3471,7 @@ RC30,thermostat,67,disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|s
RC30,thermostat,67,disinfecthour,disinfection hour,uint8 (>=0<=23), ,true,number.thermostat_dhw_disinfection_hour,number.thermostat_dhw_disinfecthour,6,9,1,14,1 RC30,thermostat,67,disinfecthour,disinfection hour,uint8 (>=0<=23), ,true,number.thermostat_dhw_disinfection_hour,number.thermostat_dhw_disinfecthour,6,9,1,14,1
RC30,thermostat,67,maxtemp,maximum temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_maximum_temperature,number.thermostat_dhw_maxtemp,6,9,1,15,1 RC30,thermostat,67,maxtemp,maximum temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_maximum_temperature,number.thermostat_dhw_maxtemp,6,9,1,15,1
RC30,thermostat,67,onetimekey,one time key function,boolean, ,true,switch.thermostat_dhw_one_time_key_function,switch.thermostat_dhw_onetimekey,6,9,1,16,1 RC30,thermostat,67,onetimekey,one time key function,boolean, ,true,switch.thermostat_dhw_one_time_key_function,switch.thermostat_dhw_onetimekey,6,9,1,16,1
RC30,thermostat,67,switchtime,program switchtime,string, ,true,sensor.thermostat_dhw_program_switchtime,sensor.thermostat_dhw_switchtime,6,9,1,17,8 RC30,thermostat,67,switchtimeWW,program switchtime warm water,string, ,true,sensor.thermostat_dhw_program_switchtime_warm_water,sensor.thermostat_dhw_switchtimeWW,6,9,1,17,8
RC30,thermostat,67,circswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_dhw_circulation_program_switchtime,sensor.thermostat_dhw_circswitchtime,6,9,1,25,8 RC30,thermostat,67,circswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_dhw_circulation_program_switchtime,sensor.thermostat_dhw_circswitchtime,6,9,1,25,8
RC30,thermostat,67,holidays,holiday dates,string, ,true,sensor.thermostat_dhw_holiday_dates,sensor.thermostat_dhw_holidays,6,9,1,33,13 RC30,thermostat,67,holidays,holiday dates,string, ,true,sensor.thermostat_dhw_holiday_dates,sensor.thermostat_dhw_holidays,6,9,1,33,13
RC30,thermostat,67,vacations,vacation dates,string, ,true,sensor.thermostat_dhw_vacation_dates,sensor.thermostat_dhw_vacations,6,9,1,46,13 RC30,thermostat,67,vacations,vacation dates,string, ,true,sensor.thermostat_dhw_vacation_dates,sensor.thermostat_dhw_vacations,6,9,1,46,13
@@ -3488,7 +3488,7 @@ RC20/Moduline 300,thermostat,77,daytemp2,day temperature T2,uint8 (>=0<=127),C,t
RC20/Moduline 300,thermostat,77,daytemp3,day temperature T3,uint8 (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T3,number.thermostat_hc1_daytemp3,6,1,1/2,101,1 RC20/Moduline 300,thermostat,77,daytemp3,day temperature T3,uint8 (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T3,number.thermostat_hc1_daytemp3,6,1,1/2,101,1
RC20/Moduline 300,thermostat,77,daytemp4,day temperature T4,uint8 (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T4,number.thermostat_hc1_daytemp4,6,1,1/2,102,1 RC20/Moduline 300,thermostat,77,daytemp4,day temperature T4,uint8 (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T4,number.thermostat_hc1_daytemp4,6,1,1/2,102,1
RC20/Moduline 300,thermostat,77,nighttemp,night temperature T1,uint8 (>=0<=127),C,true,number.thermostat_hc1_night_temperature_T1,number.thermostat_hc1_nighttemp,6,1,1/2,49,1 RC20/Moduline 300,thermostat,77,nighttemp,night temperature T1,uint8 (>=0<=127),C,true,number.thermostat_hc1_night_temperature_T1,number.thermostat_hc1_nighttemp,6,1,1/2,49,1
RC20/Moduline 300,thermostat,77,switchtime,program switchtime,string, ,true,sensor.thermostat_hc1_program_switchtime,sensor.thermostat_hc1_switchtime,6,1,1,103,8 RC20/Moduline 300,thermostat,77,switchtime,program switchtime,string, ,true,sensor.thermostat_hc1_program_switchtime,sensor.thermostat_hc1_switchtime,6,1,1,197,8
Moduline 400,thermostat,78,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8 Moduline 400,thermostat,78,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8
Moduline 400,thermostat,78,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25 Moduline 400,thermostat,78,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25
Moduline 400,thermostat,78,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13 Moduline 400,thermostat,78,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13
@@ -3617,7 +3617,7 @@ RC35,thermostat,86,disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|s
RC35,thermostat,86,disinfecthour,disinfection hour,uint8 (>=0<=23), ,true,number.thermostat_dhw_disinfection_hour,number.thermostat_dhw_disinfecthour,6,9,1,14,1 RC35,thermostat,86,disinfecthour,disinfection hour,uint8 (>=0<=23), ,true,number.thermostat_dhw_disinfection_hour,number.thermostat_dhw_disinfecthour,6,9,1,14,1
RC35,thermostat,86,maxtemp,maximum temperature,uint8 (>=60<=80),C,true,number.thermostat_dhw_maximum_temperature,number.thermostat_dhw_maxtemp,6,9,1,15,1 RC35,thermostat,86,maxtemp,maximum temperature,uint8 (>=60<=80),C,true,number.thermostat_dhw_maximum_temperature,number.thermostat_dhw_maxtemp,6,9,1,15,1
RC35,thermostat,86,onetimekey,one time key function,boolean, ,true,switch.thermostat_dhw_one_time_key_function,switch.thermostat_dhw_onetimekey,6,9,1,16,1 RC35,thermostat,86,onetimekey,one time key function,boolean, ,true,switch.thermostat_dhw_one_time_key_function,switch.thermostat_dhw_onetimekey,6,9,1,16,1
RC35,thermostat,86,switchtime,program switchtime,string, ,true,sensor.thermostat_dhw_program_switchtime,sensor.thermostat_dhw_switchtime,6,9,1,17,8 RC35,thermostat,86,switchtimeWW,program switchtime warm water,string, ,true,sensor.thermostat_dhw_program_switchtime_warm_water,sensor.thermostat_dhw_switchtimeWW,6,9,1,17,8
RC35,thermostat,86,circswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_dhw_circulation_program_switchtime,sensor.thermostat_dhw_circswitchtime,6,9,1,25,8 RC35,thermostat,86,circswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_dhw_circulation_program_switchtime,sensor.thermostat_dhw_circswitchtime,6,9,1,25,8
RC35,thermostat,86,holidays,holiday dates,string, ,true,sensor.thermostat_dhw_holiday_dates,sensor.thermostat_dhw_holidays,6,9,1,33,13 RC35,thermostat,86,holidays,holiday dates,string, ,true,sensor.thermostat_dhw_holiday_dates,sensor.thermostat_dhw_holidays,6,9,1,33,13
RC35,thermostat,86,vacations,vacation dates,string, ,true,sensor.thermostat_dhw_vacation_dates,sensor.thermostat_dhw_vacations,6,9,1,46,13 RC35,thermostat,86,vacations,vacation dates,string, ,true,sensor.thermostat_dhw_vacation_dates,sensor.thermostat_dhw_vacations,6,9,1,46,13
@@ -3652,7 +3652,7 @@ RC20RF,thermostat,93,daytemp2,day temperature T2,uint8 (>=0<=127),C,true,number.
RC20RF,thermostat,93,daytemp3,day temperature T3,uint8 (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T3,number.thermostat_hc1_daytemp3,6,1,1/2,101,1 RC20RF,thermostat,93,daytemp3,day temperature T3,uint8 (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T3,number.thermostat_hc1_daytemp3,6,1,1/2,101,1
RC20RF,thermostat,93,daytemp4,day temperature T4,uint8 (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T4,number.thermostat_hc1_daytemp4,6,1,1/2,102,1 RC20RF,thermostat,93,daytemp4,day temperature T4,uint8 (>=0<=127),C,true,number.thermostat_hc1_day_temperature_T4,number.thermostat_hc1_daytemp4,6,1,1/2,102,1
RC20RF,thermostat,93,nighttemp,night temperature T1,uint8 (>=0<=127),C,true,number.thermostat_hc1_night_temperature_T1,number.thermostat_hc1_nighttemp,6,1,1/2,49,1 RC20RF,thermostat,93,nighttemp,night temperature T1,uint8 (>=0<=127),C,true,number.thermostat_hc1_night_temperature_T1,number.thermostat_hc1_nighttemp,6,1,1/2,49,1
RC20RF,thermostat,93,switchtime,program switchtime,string, ,true,sensor.thermostat_hc1_program_switchtime,sensor.thermostat_hc1_switchtime,6,1,1,103,8 RC20RF,thermostat,93,switchtime,program switchtime,string, ,true,sensor.thermostat_hc1_program_switchtime,sensor.thermostat_hc1_switchtime,6,1,1,197,8
RFM20 Remote,thermostat,94,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8 RFM20 Remote,thermostat,94,errorcode,error code,string, ,false,sensor.thermostat_error_code,sensor.thermostat_errorcode,6,0,1,0,8
RFM20 Remote,thermostat,94,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25 RFM20 Remote,thermostat,94,lastcode,last error code,string, ,false,sensor.thermostat_last_error_code,sensor.thermostat_lastcode,6,0,1,8,25
RFM20 Remote,thermostat,94,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13 RFM20 Remote,thermostat,94,datetime,date/time,string, ,false,sensor.thermostat_date/time,sensor.thermostat_datetime,6,0,1,33,13
@@ -3724,16 +3724,16 @@ RC200/CW100/CR120,thermostat,157,hpoperatingstate,heatpump operating state,enum
RC200/CW100/CR120,thermostat,157,controlmode,control mode,enum [optimized\|simple\|n/a\|room\|power], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode,6,1,1,24,1 RC200/CW100/CR120,thermostat,157,controlmode,control mode,enum [optimized\|simple\|n/a\|room\|power], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode,6,1,1,24,1
RC200/CW100/CR120,thermostat,157,program,program,enum [prog 1\|prog 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program,6,1,1,25,1 RC200/CW100/CR120,thermostat,157,program,program,enum [prog 1\|prog 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program,6,1,1,25,1
RC200/CW100/CR120,thermostat,157,tempautotemp,temporary set temperature automode,int8 (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp,6,1,1/2,26,1 RC200/CW100/CR120,thermostat,157,tempautotemp,temporary set temperature automode,int8 (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp,6,1,1/2,26,1
RC200/CW100/CR120,thermostat,157,remoteseltemp,temporary set temperature from remote,int8 (>=-63<=63),C,false,sensor.thermostat_hc1_temporary_set_temperature_from_remote,sensor.thermostat_hc1_remoteseltemp,6,1,1/2,27,1 RC200/CW100/CR120,thermostat,157,remoteseltemp,temporary set temperature from remote,int8 (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_from_remote,number.thermostat_hc1_remoteseltemp,6,1,1/2,27,1
RC200/CW100/CR120,thermostat,157,fastheatup,fast heatup,uint8 (>=0<=100),%,true,number.thermostat_hc1_fast_heatup,number.thermostat_hc1_fastheatup,6,1,1,28,1 RC200/CW100/CR120,thermostat,157,fastheatup,fast heatup,uint8 (>=0<=100),%,true,number.thermostat_hc1_fast_heatup,number.thermostat_hc1_fastheatup,6,1,1,28,1
RC200/CW100/CR120,thermostat,157,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization,6,1,1,29,1 RC200/CW100/CR120,thermostat,157,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization,6,1,1,29,1
RC200/CW100/CR120,thermostat,157,reducemode,reduce mode,enum [outdoor\|room\|reduce], ,true,select.thermostat_hc1_reduce_mode,select.thermostat_hc1_reducemode,6,1,1,30,1 RC200/CW100/CR120,thermostat,157,reducemode,reduce mode,enum [outdoor\|room\|reduce], ,true,select.thermostat_hc1_reduce_mode,select.thermostat_hc1_reducemode,6,1,1,30,1
RC200/CW100/CR120,thermostat,157,noreducetemp,no reduce below temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp,6,1,1,31,1 RC200/CW100/CR120,thermostat,157,noreducetemp,no reduce below temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp,6,1,1,31,1
RC200/CW100/CR120,thermostat,157,reducetemp,off/reduce switch temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp,6,1,1,32,1 RC200/CW100/CR120,thermostat,157,reducetemp,off/reduce switch temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp,6,1,1,32,1
RC200/CW100/CR120,thermostat,157,dhwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_dhwprio,6,1,1,33,1 RC200/CW100/CR120,thermostat,157,dhwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_dhwprio,6,1,1,33,1
RC200/CW100/CR120,thermostat,157,cooling,cooling,boolean, ,true,switch.thermostat_hc1_cooling,switch.thermostat_hc1_cooling,6,1,1,34,1 RC200/CW100/CR120,thermostat,157,hpcooling,hp cooling,boolean, ,true,switch.thermostat_hc1_hp_cooling,switch.thermostat_hc1_hpcooling,6,1,1,34,1
RC200/CW100/CR120,thermostat,157,coolingon,cooling,boolean, ,false,binary_sensor.thermostat_hc1_cooling,binary_sensor.thermostat_hc1_coolingon,6,1,1,35,1 RC200/CW100/CR120,thermostat,157,coolingon,cooling on,boolean, ,false,binary_sensor.thermostat_hc1_cooling_on,binary_sensor.thermostat_hc1_coolingon,6,1,1,35,1
RC200/CW100/CR120,thermostat,157,hpmode,HP Mode,enum [heating\|cooling\|heating&cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode,6,1,1,36,1 RC200/CW100/CR120,thermostat,157,hpmode,HP Mode,enum [heating\|cooling\|heating & cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode,6,1,1,36,1
RC200/CW100/CR120,thermostat,157,dewoffset,dew point offset,uint8 (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset,6,1,1,37,1 RC200/CW100/CR120,thermostat,157,dewoffset,dew point offset,uint8 (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset,6,1,1,37,1
RC200/CW100/CR120,thermostat,157,roomtempdiff,room temp difference,uint8 (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff,6,1,1,38,1 RC200/CW100/CR120,thermostat,157,roomtempdiff,room temp difference,uint8 (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff,6,1,1,38,1
RC200/CW100/CR120,thermostat,157,hpminflowtemp,HP min. flow temp.,uint8 (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp,6,1,1,39,1 RC200/CW100/CR120,thermostat,157,hpminflowtemp,HP min. flow temp.,uint8 (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp,6,1,1,39,1
@@ -3745,10 +3745,10 @@ RC200/CW100/CR120,thermostat,157,heatoffdelay,heat-off delay,uint8 (>=1<=48),hou
RC200/CW100/CR120,thermostat,157,instantstart,instant start,uint8 (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart,6,1,1,45,1 RC200/CW100/CR120,thermostat,157,instantstart,instant start,uint8 (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart,6,1,1,45,1
RC200/CW100/CR120,thermostat,157,boost,boost mode,boolean, ,true,switch.thermostat_hc1_boost_mode,switch.thermostat_hc1_boost,6,1,1,46,1 RC200/CW100/CR120,thermostat,157,boost,boost mode,boolean, ,true,switch.thermostat_hc1_boost_mode,switch.thermostat_hc1_boost,6,1,1,46,1
RC200/CW100/CR120,thermostat,157,boosttime,boost time,uint8 (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime,6,1,1,47,1 RC200/CW100/CR120,thermostat,157,boosttime,boost time,uint8 (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime,6,1,1,47,1
RC200/CW100/CR120,thermostat,157,coolstart,cooling starttemp,uint8 (>=20<=35),C,true,number.thermostat_hc1_cooling_starttemp,number.thermostat_hc1_coolstart,6,1,1,-1,1 RC200/CW100/CR120,thermostat,157,coolstart,cooling starttemp,uint8 (>=20<=35),C,true,number.thermostat_hc1_cooling_starttemp,number.thermostat_hc1_coolstart,6,1,1,193,1
RC200/CW100/CR120,thermostat,157,coolondelay,cooling on delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_on_delay,number.thermostat_hc1_coolondelay,6,1,1,-1,1 RC200/CW100/CR120,thermostat,157,coolondelay,cooling on delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_on_delay,number.thermostat_hc1_coolondelay,6,1,1,194,1
RC200/CW100/CR120,thermostat,157,cooloffdelay,cooling off delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_off_delay,number.thermostat_hc1_cooloffdelay,6,1,1,-1,1 RC200/CW100/CR120,thermostat,157,cooloffdelay,cooling off delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_off_delay,number.thermostat_hc1_cooloffdelay,6,1,1,195,1
RC200/CW100/CR120,thermostat,157,switchprogmode,switch program mode,enum [level\|absolute], ,true,select.thermostat_hc1_switch_program_mode,select.thermostat_hc1_switchprogmode,6,1,1,-1,1 RC200/CW100/CR120,thermostat,157,switchprogmode,switch program mode,enum [level\|absolute], ,true,select.thermostat_hc1_switch_program_mode,select.thermostat_hc1_switchprogmode,6,1,1,196,1
RC200/CW100/CR120,thermostat,157,mode,mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_dhw_mode,select.thermostat_dhw_mode,6,9,1,0,1 RC200/CW100/CR120,thermostat,157,mode,mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_dhw_mode,select.thermostat_dhw_mode,6,9,1,0,1
RC200/CW100/CR120,thermostat,157,settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp,6,9,1,1,1 RC200/CW100/CR120,thermostat,157,settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp,6,9,1,1,1
RC200/CW100/CR120,thermostat,157,settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow,6,9,1,2,1 RC200/CW100/CR120,thermostat,157,settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow,6,9,1,2,1
@@ -3808,16 +3808,16 @@ RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,hpoperating
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,controlmode,control mode,enum [weather compensated\|outside basepoint\|n/a\|room\|power\|constant], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode,6,1,1,24,1 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,controlmode,control mode,enum [weather compensated\|outside basepoint\|n/a\|room\|power\|constant], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode,6,1,1,24,1
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,program,program,enum [prog 1\|prog 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program,6,1,1,25,1 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,program,program,enum [prog 1\|prog 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program,6,1,1,25,1
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,tempautotemp,temporary set temperature automode,int8 (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp,6,1,1/2,26,1 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,tempautotemp,temporary set temperature automode,int8 (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp,6,1,1/2,26,1
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,remoteseltemp,temporary set temperature from remote,int8 (>=-63<=63),C,false,sensor.thermostat_hc1_temporary_set_temperature_from_remote,sensor.thermostat_hc1_remoteseltemp,6,1,1/2,27,1 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,remoteseltemp,temporary set temperature from remote,int8 (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_from_remote,number.thermostat_hc1_remoteseltemp,6,1,1/2,27,1
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,fastheatup,fast heatup,uint8 (>=0<=100),%,true,number.thermostat_hc1_fast_heatup,number.thermostat_hc1_fastheatup,6,1,1,28,1 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,fastheatup,fast heatup,uint8 (>=0<=100),%,true,number.thermostat_hc1_fast_heatup,number.thermostat_hc1_fastheatup,6,1,1,28,1
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization,6,1,1,29,1 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization,6,1,1,29,1
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,reducemode,reduce mode,enum [outdoor\|room\|reduce], ,true,select.thermostat_hc1_reduce_mode,select.thermostat_hc1_reducemode,6,1,1,30,1 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,reducemode,reduce mode,enum [outdoor\|room\|reduce], ,true,select.thermostat_hc1_reduce_mode,select.thermostat_hc1_reducemode,6,1,1,30,1
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,noreducetemp,no reduce below temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp,6,1,1,31,1 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,noreducetemp,no reduce below temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp,6,1,1,31,1
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,reducetemp,off/reduce switch temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp,6,1,1,32,1 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,reducetemp,off/reduce switch temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp,6,1,1,32,1
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,dhwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_dhwprio,6,1,1,33,1 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,dhwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_dhwprio,6,1,1,33,1
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,cooling,cooling,boolean, ,true,switch.thermostat_hc1_cooling,switch.thermostat_hc1_cooling,6,1,1,34,1 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,hpcooling,hp cooling,boolean, ,true,switch.thermostat_hc1_hp_cooling,switch.thermostat_hc1_hpcooling,6,1,1,34,1
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,6,1,1,35,1 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,coolingon,cooling on,boolean, ,false,binary_sensor.thermostat_hc1_cooling_on,binary_sensor.thermostat_hc1_coolingon,6,1,1,35,1
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,6,1,1,36,1 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,6,1,1,36,1
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,dewoffset,dew point offset,uint8 (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset,6,1,1,37,1 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,dewoffset,dew point offset,uint8 (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset,6,1,1,37,1
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,roomtempdiff,room temp difference,uint8 (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff,6,1,1,38,1 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,roomtempdiff,room temp difference,uint8 (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff,6,1,1,38,1
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,hpminflowtemp,HP min. flow temp.,uint8 (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp,6,1,1,39,1 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,hpminflowtemp,HP min. flow temp.,uint8 (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp,6,1,1,39,1
@@ -3829,10 +3829,10 @@ RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,heatoffdela
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,instantstart,instant start,uint8 (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart,6,1,1,45,1 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,instantstart,instant start,uint8 (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart,6,1,1,45,1
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,boost,boost mode,boolean, ,true,switch.thermostat_hc1_boost_mode,switch.thermostat_hc1_boost,6,1,1,46,1 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,boost,boost mode,boolean, ,true,switch.thermostat_hc1_boost_mode,switch.thermostat_hc1_boost,6,1,1,46,1
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,boosttime,boost time,uint8 (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime,6,1,1,47,1 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,boosttime,boost time,uint8 (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime,6,1,1,47,1
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,coolstart,cooling starttemp,uint8 (>=20<=35),C,true,number.thermostat_hc1_cooling_starttemp,number.thermostat_hc1_coolstart,6,1,1,-1,1 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,coolstart,cooling starttemp,uint8 (>=20<=35),C,true,number.thermostat_hc1_cooling_starttemp,number.thermostat_hc1_coolstart,6,1,1,193,1
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,coolondelay,cooling on delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_on_delay,number.thermostat_hc1_coolondelay,6,1,1,-1,1 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,coolondelay,cooling on delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_on_delay,number.thermostat_hc1_coolondelay,6,1,1,194,1
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,cooloffdelay,cooling off delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_off_delay,number.thermostat_hc1_cooloffdelay,6,1,1,-1,1 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,cooloffdelay,cooling off delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_off_delay,number.thermostat_hc1_cooloffdelay,6,1,1,195,1
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,switchprogmode,switch program mode,enum [level\|absolute], ,true,select.thermostat_hc1_switch_program_mode,select.thermostat_hc1_switchprogmode,6,1,1,-1,1 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,switchprogmode,switch program mode,enum [level\|absolute], ,true,select.thermostat_hc1_switch_program_mode,select.thermostat_hc1_switchprogmode,6,1,1,196,1
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,mode,mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_dhw_mode,select.thermostat_dhw_mode,6,9,1,0,1 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,mode,mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_dhw_mode,select.thermostat_dhw_mode,6,9,1,0,1
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp,6,9,1,1,1 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp,6,9,1,1,1
RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow,6,9,1,2,1 RC300/RC310/Moduline 3000/1010H/CW400/Sense II/HPC410,thermostat,158,settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow,6,9,1,2,1
@@ -3892,16 +3892,16 @@ RC100/Moduline 1000/1010,thermostat,165,hpoperatingstate,heatpump operating stat
RC100/Moduline 1000/1010,thermostat,165,controlmode,control mode,enum [optimized\|simple\|n/a\|room\|power], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode,6,1,1,24,1 RC100/Moduline 1000/1010,thermostat,165,controlmode,control mode,enum [optimized\|simple\|n/a\|room\|power], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode,6,1,1,24,1
RC100/Moduline 1000/1010,thermostat,165,program,program,enum [prog 1\|prog 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program,6,1,1,25,1 RC100/Moduline 1000/1010,thermostat,165,program,program,enum [prog 1\|prog 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program,6,1,1,25,1
RC100/Moduline 1000/1010,thermostat,165,tempautotemp,temporary set temperature automode,int8 (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp,6,1,1/2,26,1 RC100/Moduline 1000/1010,thermostat,165,tempautotemp,temporary set temperature automode,int8 (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp,6,1,1/2,26,1
RC100/Moduline 1000/1010,thermostat,165,remoteseltemp,temporary set temperature from remote,int8 (>=-63<=63),C,false,sensor.thermostat_hc1_temporary_set_temperature_from_remote,sensor.thermostat_hc1_remoteseltemp,6,1,1/2,27,1 RC100/Moduline 1000/1010,thermostat,165,remoteseltemp,temporary set temperature from remote,int8 (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_from_remote,number.thermostat_hc1_remoteseltemp,6,1,1/2,27,1
RC100/Moduline 1000/1010,thermostat,165,fastheatup,fast heatup,uint8 (>=0<=100),%,true,number.thermostat_hc1_fast_heatup,number.thermostat_hc1_fastheatup,6,1,1,28,1 RC100/Moduline 1000/1010,thermostat,165,fastheatup,fast heatup,uint8 (>=0<=100),%,true,number.thermostat_hc1_fast_heatup,number.thermostat_hc1_fastheatup,6,1,1,28,1
RC100/Moduline 1000/1010,thermostat,165,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization,6,1,1,29,1 RC100/Moduline 1000/1010,thermostat,165,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization,6,1,1,29,1
RC100/Moduline 1000/1010,thermostat,165,reducemode,reduce mode,enum [outdoor\|room\|reduce], ,true,select.thermostat_hc1_reduce_mode,select.thermostat_hc1_reducemode,6,1,1,30,1 RC100/Moduline 1000/1010,thermostat,165,reducemode,reduce mode,enum [outdoor\|room\|reduce], ,true,select.thermostat_hc1_reduce_mode,select.thermostat_hc1_reducemode,6,1,1,30,1
RC100/Moduline 1000/1010,thermostat,165,noreducetemp,no reduce below temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp,6,1,1,31,1 RC100/Moduline 1000/1010,thermostat,165,noreducetemp,no reduce below temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp,6,1,1,31,1
RC100/Moduline 1000/1010,thermostat,165,reducetemp,off/reduce switch temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp,6,1,1,32,1 RC100/Moduline 1000/1010,thermostat,165,reducetemp,off/reduce switch temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp,6,1,1,32,1
RC100/Moduline 1000/1010,thermostat,165,dhwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_dhwprio,6,1,1,33,1 RC100/Moduline 1000/1010,thermostat,165,dhwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_dhwprio,6,1,1,33,1
RC100/Moduline 1000/1010,thermostat,165,cooling,cooling,boolean, ,true,switch.thermostat_hc1_cooling,switch.thermostat_hc1_cooling,6,1,1,34,1 RC100/Moduline 1000/1010,thermostat,165,hpcooling,hp cooling,boolean, ,true,switch.thermostat_hc1_hp_cooling,switch.thermostat_hc1_hpcooling,6,1,1,34,1
RC100/Moduline 1000/1010,thermostat,165,coolingon,cooling,boolean, ,false,binary_sensor.thermostat_hc1_cooling,binary_sensor.thermostat_hc1_coolingon,6,1,1,35,1 RC100/Moduline 1000/1010,thermostat,165,coolingon,cooling on,boolean, ,false,binary_sensor.thermostat_hc1_cooling_on,binary_sensor.thermostat_hc1_coolingon,6,1,1,35,1
RC100/Moduline 1000/1010,thermostat,165,hpmode,HP Mode,enum [heating\|cooling\|heating&cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode,6,1,1,36,1 RC100/Moduline 1000/1010,thermostat,165,hpmode,HP Mode,enum [heating\|cooling\|heating & cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode,6,1,1,36,1
RC100/Moduline 1000/1010,thermostat,165,dewoffset,dew point offset,uint8 (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset,6,1,1,37,1 RC100/Moduline 1000/1010,thermostat,165,dewoffset,dew point offset,uint8 (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset,6,1,1,37,1
RC100/Moduline 1000/1010,thermostat,165,roomtempdiff,room temp difference,uint8 (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff,6,1,1,38,1 RC100/Moduline 1000/1010,thermostat,165,roomtempdiff,room temp difference,uint8 (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff,6,1,1,38,1
RC100/Moduline 1000/1010,thermostat,165,hpminflowtemp,HP min. flow temp.,uint8 (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp,6,1,1,39,1 RC100/Moduline 1000/1010,thermostat,165,hpminflowtemp,HP min. flow temp.,uint8 (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp,6,1,1,39,1
@@ -3913,10 +3913,10 @@ RC100/Moduline 1000/1010,thermostat,165,heatoffdelay,heat-off delay,uint8 (>=1<=
RC100/Moduline 1000/1010,thermostat,165,instantstart,instant start,uint8 (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart,6,1,1,45,1 RC100/Moduline 1000/1010,thermostat,165,instantstart,instant start,uint8 (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart,6,1,1,45,1
RC100/Moduline 1000/1010,thermostat,165,boost,boost mode,boolean, ,true,switch.thermostat_hc1_boost_mode,switch.thermostat_hc1_boost,6,1,1,46,1 RC100/Moduline 1000/1010,thermostat,165,boost,boost mode,boolean, ,true,switch.thermostat_hc1_boost_mode,switch.thermostat_hc1_boost,6,1,1,46,1
RC100/Moduline 1000/1010,thermostat,165,boosttime,boost time,uint8 (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime,6,1,1,47,1 RC100/Moduline 1000/1010,thermostat,165,boosttime,boost time,uint8 (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime,6,1,1,47,1
RC100/Moduline 1000/1010,thermostat,165,coolstart,cooling starttemp,uint8 (>=20<=35),C,true,number.thermostat_hc1_cooling_starttemp,number.thermostat_hc1_coolstart,6,1,1,-1,1 RC100/Moduline 1000/1010,thermostat,165,coolstart,cooling starttemp,uint8 (>=20<=35),C,true,number.thermostat_hc1_cooling_starttemp,number.thermostat_hc1_coolstart,6,1,1,193,1
RC100/Moduline 1000/1010,thermostat,165,coolondelay,cooling on delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_on_delay,number.thermostat_hc1_coolondelay,6,1,1,-1,1 RC100/Moduline 1000/1010,thermostat,165,coolondelay,cooling on delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_on_delay,number.thermostat_hc1_coolondelay,6,1,1,194,1
RC100/Moduline 1000/1010,thermostat,165,cooloffdelay,cooling off delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_off_delay,number.thermostat_hc1_cooloffdelay,6,1,1,-1,1 RC100/Moduline 1000/1010,thermostat,165,cooloffdelay,cooling off delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_off_delay,number.thermostat_hc1_cooloffdelay,6,1,1,195,1
RC100/Moduline 1000/1010,thermostat,165,switchprogmode,switch program mode,enum [level\|absolute], ,true,select.thermostat_hc1_switch_program_mode,select.thermostat_hc1_switchprogmode,6,1,1,-1,1 RC100/Moduline 1000/1010,thermostat,165,switchprogmode,switch program mode,enum [level\|absolute], ,true,select.thermostat_hc1_switch_program_mode,select.thermostat_hc1_switchprogmode,6,1,1,196,1
RC100/Moduline 1000/1010,thermostat,165,mode,mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_dhw_mode,select.thermostat_dhw_mode,6,9,1,0,1 RC100/Moduline 1000/1010,thermostat,165,mode,mode,enum [off\|normal\|comfort\|auto\|own prog], ,true,select.thermostat_dhw_mode,select.thermostat_dhw_mode,6,9,1,0,1
RC100/Moduline 1000/1010,thermostat,165,settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp,6,9,1,1,1 RC100/Moduline 1000/1010,thermostat,165,settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp,6,9,1,1,1
RC100/Moduline 1000/1010,thermostat,165,settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow,6,9,1,2,1 RC100/Moduline 1000/1010,thermostat,165,settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow,6,9,1,2,1
@@ -3977,16 +3977,16 @@ Rego 2000/3000,thermostat,172,hpoperatingstate,heatpump operating state,enum [he
Rego 2000/3000,thermostat,172,controlmode,control mode,enum [weather compensated\|outside basepoint\|n/a\|room\|power\|constant], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode,6,1,1,24,1 Rego 2000/3000,thermostat,172,controlmode,control mode,enum [weather compensated\|outside basepoint\|n/a\|room\|power\|constant], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode,6,1,1,24,1
Rego 2000/3000,thermostat,172,program,program,enum [prog 1\|prog 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program,6,1,1,25,1 Rego 2000/3000,thermostat,172,program,program,enum [prog 1\|prog 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program,6,1,1,25,1
Rego 2000/3000,thermostat,172,tempautotemp,temporary set temperature automode,int8 (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp,6,1,1/2,26,1 Rego 2000/3000,thermostat,172,tempautotemp,temporary set temperature automode,int8 (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp,6,1,1/2,26,1
Rego 2000/3000,thermostat,172,remoteseltemp,temporary set temperature from remote,int8 (>=-63<=63),C,false,sensor.thermostat_hc1_temporary_set_temperature_from_remote,sensor.thermostat_hc1_remoteseltemp,6,1,1/2,27,1 Rego 2000/3000,thermostat,172,remoteseltemp,temporary set temperature from remote,int8 (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_from_remote,number.thermostat_hc1_remoteseltemp,6,1,1/2,27,1
Rego 2000/3000,thermostat,172,fastheatup,fast heatup,uint8 (>=0<=100),%,true,number.thermostat_hc1_fast_heatup,number.thermostat_hc1_fastheatup,6,1,1,28,1 Rego 2000/3000,thermostat,172,fastheatup,fast heatup,uint8 (>=0<=100),%,true,number.thermostat_hc1_fast_heatup,number.thermostat_hc1_fastheatup,6,1,1,28,1
Rego 2000/3000,thermostat,172,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization,6,1,1,29,1 Rego 2000/3000,thermostat,172,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization,6,1,1,29,1
Rego 2000/3000,thermostat,172,reducemode,reduce mode,enum [outdoor\|room\|reduce], ,true,select.thermostat_hc1_reduce_mode,select.thermostat_hc1_reducemode,6,1,1,30,1 Rego 2000/3000,thermostat,172,reducemode,reduce mode,enum [outdoor\|room\|reduce], ,true,select.thermostat_hc1_reduce_mode,select.thermostat_hc1_reducemode,6,1,1,30,1
Rego 2000/3000,thermostat,172,noreducetemp,no reduce below temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp,6,1,1,31,1 Rego 2000/3000,thermostat,172,noreducetemp,no reduce below temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp,6,1,1,31,1
Rego 2000/3000,thermostat,172,reducetemp,off/reduce switch temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp,6,1,1,32,1 Rego 2000/3000,thermostat,172,reducetemp,off/reduce switch temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp,6,1,1,32,1
Rego 2000/3000,thermostat,172,dhwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_dhwprio,6,1,1,33,1 Rego 2000/3000,thermostat,172,dhwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_dhwprio,6,1,1,33,1
Rego 2000/3000,thermostat,172,cooling,cooling,boolean, ,true,switch.thermostat_hc1_cooling,switch.thermostat_hc1_cooling,6,1,1,34,1 Rego 2000/3000,thermostat,172,hpcooling,hp cooling,boolean, ,true,switch.thermostat_hc1_hp_cooling,switch.thermostat_hc1_hpcooling,6,1,1,34,1
Rego 2000/3000,thermostat,172,coolingon,cooling,boolean, ,false,binary_sensor.thermostat_hc1_cooling,binary_sensor.thermostat_hc1_coolingon,6,1,1,35,1 Rego 2000/3000,thermostat,172,coolingon,cooling on,boolean, ,false,binary_sensor.thermostat_hc1_cooling_on,binary_sensor.thermostat_hc1_coolingon,6,1,1,35,1
Rego 2000/3000,thermostat,172,hpmode,HP Mode,enum [heating\|cooling\|heating&cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode,6,1,1,36,1 Rego 2000/3000,thermostat,172,hpmode,HP Mode,enum [heating\|cooling\|heating & cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode,6,1,1,36,1
Rego 2000/3000,thermostat,172,dewoffset,dew point offset,uint8 (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset,6,1,1,37,1 Rego 2000/3000,thermostat,172,dewoffset,dew point offset,uint8 (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset,6,1,1,37,1
Rego 2000/3000,thermostat,172,roomtempdiff,room temp difference,uint8 (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff,6,1,1,38,1 Rego 2000/3000,thermostat,172,roomtempdiff,room temp difference,uint8 (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff,6,1,1,38,1
Rego 2000/3000,thermostat,172,hpminflowtemp,HP min. flow temp.,uint8 (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp,6,1,1,39,1 Rego 2000/3000,thermostat,172,hpminflowtemp,HP min. flow temp.,uint8 (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp,6,1,1,39,1
@@ -3998,10 +3998,10 @@ Rego 2000/3000,thermostat,172,heatoffdelay,heat-off delay,uint8 (>=1<=48),hours,
Rego 2000/3000,thermostat,172,instantstart,instant start,uint8 (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart,6,1,1,45,1 Rego 2000/3000,thermostat,172,instantstart,instant start,uint8 (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart,6,1,1,45,1
Rego 2000/3000,thermostat,172,boost,boost mode,boolean, ,true,switch.thermostat_hc1_boost_mode,switch.thermostat_hc1_boost,6,1,1,46,1 Rego 2000/3000,thermostat,172,boost,boost mode,boolean, ,true,switch.thermostat_hc1_boost_mode,switch.thermostat_hc1_boost,6,1,1,46,1
Rego 2000/3000,thermostat,172,boosttime,boost time,uint8 (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime,6,1,1,47,1 Rego 2000/3000,thermostat,172,boosttime,boost time,uint8 (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime,6,1,1,47,1
Rego 2000/3000,thermostat,172,coolstart,cooling starttemp,uint8 (>=20<=35),C,true,number.thermostat_hc1_cooling_starttemp,number.thermostat_hc1_coolstart,6,1,1,-1,1 Rego 2000/3000,thermostat,172,coolstart,cooling starttemp,uint8 (>=20<=35),C,true,number.thermostat_hc1_cooling_starttemp,number.thermostat_hc1_coolstart,6,1,1,193,1
Rego 2000/3000,thermostat,172,coolondelay,cooling on delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_on_delay,number.thermostat_hc1_coolondelay,6,1,1,-1,1 Rego 2000/3000,thermostat,172,coolondelay,cooling on delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_on_delay,number.thermostat_hc1_coolondelay,6,1,1,194,1
Rego 2000/3000,thermostat,172,cooloffdelay,cooling off delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_off_delay,number.thermostat_hc1_cooloffdelay,6,1,1,-1,1 Rego 2000/3000,thermostat,172,cooloffdelay,cooling off delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_off_delay,number.thermostat_hc1_cooloffdelay,6,1,1,195,1
Rego 2000/3000,thermostat,172,switchprogmode,switch program mode,enum [level\|absolute], ,true,select.thermostat_hc1_switch_program_mode,select.thermostat_hc1_switchprogmode,6,1,1,-1,1 Rego 2000/3000,thermostat,172,switchprogmode,switch program mode,enum [level\|absolute], ,true,select.thermostat_hc1_switch_program_mode,select.thermostat_hc1_switchprogmode,6,1,1,196,1
Rego 2000/3000,thermostat,172,mode,mode,enum [normal\|comfort\|eco+], ,true,select.thermostat_dhw_mode,select.thermostat_dhw_mode,6,9,1,0,1 Rego 2000/3000,thermostat,172,mode,mode,enum [normal\|comfort\|eco+], ,true,select.thermostat_dhw_mode,select.thermostat_dhw_mode,6,9,1,0,1
Rego 2000/3000,thermostat,172,settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp,6,9,1,1,1 Rego 2000/3000,thermostat,172,settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp,6,9,1,1,1
Rego 2000/3000,thermostat,172,settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow,6,9,1,2,1 Rego 2000/3000,thermostat,172,settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow,6,9,1,2,1
@@ -4088,16 +4088,16 @@ Rego 3000/UI800/WSW196i/BC400,thermostat,253,hpoperatingstate,heatpump operating
Rego 3000/UI800/WSW196i/BC400,thermostat,253,controlmode,control mode,enum [weather compensated\|outside basepoint\|n/a\|room\|power\|constant], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode,6,1,1,24,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,controlmode,control mode,enum [weather compensated\|outside basepoint\|n/a\|room\|power\|constant], ,true,select.thermostat_hc1_control_mode,select.thermostat_hc1_controlmode,6,1,1,24,1
Rego 3000/UI800/WSW196i/BC400,thermostat,253,program,program,enum [prog 1\|prog 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program,6,1,1,25,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,program,program,enum [prog 1\|prog 2], ,true,select.thermostat_hc1_program,select.thermostat_hc1_program,6,1,1,25,1
Rego 3000/UI800/WSW196i/BC400,thermostat,253,tempautotemp,temporary set temperature automode,int8 (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp,6,1,1/2,26,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,tempautotemp,temporary set temperature automode,int8 (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_automode,number.thermostat_hc1_tempautotemp,6,1,1/2,26,1
Rego 3000/UI800/WSW196i/BC400,thermostat,253,remoteseltemp,temporary set temperature from remote,int8 (>=-63<=63),C,false,sensor.thermostat_hc1_temporary_set_temperature_from_remote,sensor.thermostat_hc1_remoteseltemp,6,1,1/2,27,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,remoteseltemp,temporary set temperature from remote,int8 (>=-1<=30),C,true,number.thermostat_hc1_temporary_set_temperature_from_remote,number.thermostat_hc1_remoteseltemp,6,1,1/2,27,1
Rego 3000/UI800/WSW196i/BC400,thermostat,253,fastheatup,fast heatup,uint8 (>=0<=100),%,true,number.thermostat_hc1_fast_heatup,number.thermostat_hc1_fastheatup,6,1,1,28,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,fastheatup,fast heatup,uint8 (>=0<=100),%,true,number.thermostat_hc1_fast_heatup,number.thermostat_hc1_fastheatup,6,1,1,28,1
Rego 3000/UI800/WSW196i/BC400,thermostat,253,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization,6,1,1,29,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,switchonoptimization,switch-on optimization,boolean, ,true,switch.thermostat_hc1_switch-on_optimization,switch.thermostat_hc1_switchonoptimization,6,1,1,29,1
Rego 3000/UI800/WSW196i/BC400,thermostat,253,reducemode,reduce mode,enum [outdoor\|room\|reduce], ,true,select.thermostat_hc1_reduce_mode,select.thermostat_hc1_reducemode,6,1,1,30,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,reducemode,reduce mode,enum [outdoor\|room\|reduce], ,true,select.thermostat_hc1_reduce_mode,select.thermostat_hc1_reducemode,6,1,1,30,1
Rego 3000/UI800/WSW196i/BC400,thermostat,253,noreducetemp,no reduce below temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp,6,1,1,31,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,noreducetemp,no reduce below temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_no_reduce_below_temperature,number.thermostat_hc1_noreducetemp,6,1,1,31,1
Rego 3000/UI800/WSW196i/BC400,thermostat,253,reducetemp,off/reduce switch temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp,6,1,1,32,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,reducetemp,off/reduce switch temperature,int8 (>=-126<=126),C,true,number.thermostat_hc1_off/reduce_switch_temperature,number.thermostat_hc1_reducetemp,6,1,1,32,1
Rego 3000/UI800/WSW196i/BC400,thermostat,253,dhwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_dhwprio,6,1,1,33,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,dhwprio,dhw priority,boolean, ,true,switch.thermostat_hc1_dhw_priority,switch.thermostat_hc1_dhwprio,6,1,1,33,1
Rego 3000/UI800/WSW196i/BC400,thermostat,253,cooling,cooling,boolean, ,true,switch.thermostat_hc1_cooling,switch.thermostat_hc1_cooling,6,1,1,34,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,hpcooling,hp cooling,boolean, ,true,switch.thermostat_hc1_hp_cooling,switch.thermostat_hc1_hpcooling,6,1,1,34,1
Rego 3000/UI800/WSW196i/BC400,thermostat,253,coolingon,cooling,boolean, ,false,binary_sensor.thermostat_hc1_cooling,binary_sensor.thermostat_hc1_coolingon,6,1,1,35,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,coolingon,cooling on,boolean, ,false,binary_sensor.thermostat_hc1_cooling_on,binary_sensor.thermostat_hc1_coolingon,6,1,1,35,1
Rego 3000/UI800/WSW196i/BC400,thermostat,253,hpmode,HP Mode,enum [heating\|cooling\|heating&cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode,6,1,1,36,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,hpmode,HP Mode,enum [heating\|cooling\|heating & cooling], ,true,select.thermostat_hc1_HP_Mode,select.thermostat_hc1_hpmode,6,1,1,36,1
Rego 3000/UI800/WSW196i/BC400,thermostat,253,dewoffset,dew point offset,uint8 (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset,6,1,1,37,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,dewoffset,dew point offset,uint8 (>=2<=10),K,true,number.thermostat_hc1_dew_point_offset,number.thermostat_hc1_dewoffset,6,1,1,37,1
Rego 3000/UI800/WSW196i/BC400,thermostat,253,roomtempdiff,room temp difference,uint8 (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff,6,1,1,38,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,roomtempdiff,room temp difference,uint8 (>=0<=254),K,true,number.thermostat_hc1_room_temp_difference,number.thermostat_hc1_roomtempdiff,6,1,1,38,1
Rego 3000/UI800/WSW196i/BC400,thermostat,253,hpminflowtemp,HP min. flow temp.,uint8 (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp,6,1,1,39,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,hpminflowtemp,HP min. flow temp.,uint8 (>=0<=254),C,true,number.thermostat_hc1_HP_min._flow_temp.,number.thermostat_hc1_hpminflowtemp,6,1,1,39,1
@@ -4109,10 +4109,10 @@ Rego 3000/UI800/WSW196i/BC400,thermostat,253,heatoffdelay,heat-off delay,uint8 (
Rego 3000/UI800/WSW196i/BC400,thermostat,253,instantstart,instant start,uint8 (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart,6,1,1,45,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,instantstart,instant start,uint8 (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart,6,1,1,45,1
Rego 3000/UI800/WSW196i/BC400,thermostat,253,boost,boost mode,boolean, ,true,switch.thermostat_hc1_boost_mode,switch.thermostat_hc1_boost,6,1,1,46,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,boost,boost mode,boolean, ,true,switch.thermostat_hc1_boost_mode,switch.thermostat_hc1_boost,6,1,1,46,1
Rego 3000/UI800/WSW196i/BC400,thermostat,253,boosttime,boost time,uint8 (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime,6,1,1,47,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,boosttime,boost time,uint8 (>=0<=254),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime,6,1,1,47,1
Rego 3000/UI800/WSW196i/BC400,thermostat,253,coolstart,cooling starttemp,uint8 (>=20<=35),C,true,number.thermostat_hc1_cooling_starttemp,number.thermostat_hc1_coolstart,6,1,1,-1,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,coolstart,cooling starttemp,uint8 (>=20<=35),C,true,number.thermostat_hc1_cooling_starttemp,number.thermostat_hc1_coolstart,6,1,1,193,1
Rego 3000/UI800/WSW196i/BC400,thermostat,253,coolondelay,cooling on delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_on_delay,number.thermostat_hc1_coolondelay,6,1,1,-1,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,coolondelay,cooling on delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_on_delay,number.thermostat_hc1_coolondelay,6,1,1,194,1
Rego 3000/UI800/WSW196i/BC400,thermostat,253,cooloffdelay,cooling off delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_off_delay,number.thermostat_hc1_cooloffdelay,6,1,1,-1,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,cooloffdelay,cooling off delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_off_delay,number.thermostat_hc1_cooloffdelay,6,1,1,195,1
Rego 3000/UI800/WSW196i/BC400,thermostat,253,switchprogmode,switch program mode,enum [level\|absolute], ,true,select.thermostat_hc1_switch_program_mode,select.thermostat_hc1_switchprogmode,6,1,1,-1,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,switchprogmode,switch program mode,enum [level\|absolute], ,true,select.thermostat_hc1_switch_program_mode,select.thermostat_hc1_switchprogmode,6,1,1,196,1
Rego 3000/UI800/WSW196i/BC400,thermostat,253,mode,mode,enum [off\|eco+\|eco\|comfort\|auto], ,true,select.thermostat_dhw_mode,select.thermostat_dhw_mode,6,9,1,0,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,mode,mode,enum [off\|eco+\|eco\|comfort\|auto], ,true,select.thermostat_dhw_mode,select.thermostat_dhw_mode,6,9,1,0,1
Rego 3000/UI800/WSW196i/BC400,thermostat,253,settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp,6,9,1,1,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,settemp,set temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_temperature,number.thermostat_dhw_settemp,6,9,1,1,1
Rego 3000/UI800/WSW196i/BC400,thermostat,253,settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow,6,9,1,2,1 Rego 3000/UI800/WSW196i/BC400,thermostat,253,settemplow,set low temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_set_low_temperature,number.thermostat_dhw_settemplow,6,9,1,2,1
@@ -4204,7 +4204,7 @@ ES73,thermostat,76,disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|s
ES73,thermostat,76,disinfecthour,disinfection hour,uint8 (>=0<=23), ,true,number.thermostat_dhw_disinfection_hour,number.thermostat_dhw_disinfecthour,6,9,1,14,1 ES73,thermostat,76,disinfecthour,disinfection hour,uint8 (>=0<=23), ,true,number.thermostat_dhw_disinfection_hour,number.thermostat_dhw_disinfecthour,6,9,1,14,1
ES73,thermostat,76,maxtemp,maximum temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_maximum_temperature,number.thermostat_dhw_maxtemp,6,9,1,15,1 ES73,thermostat,76,maxtemp,maximum temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_maximum_temperature,number.thermostat_dhw_maxtemp,6,9,1,15,1
ES73,thermostat,76,onetimekey,one time key function,boolean, ,true,switch.thermostat_dhw_one_time_key_function,switch.thermostat_dhw_onetimekey,6,9,1,16,1 ES73,thermostat,76,onetimekey,one time key function,boolean, ,true,switch.thermostat_dhw_one_time_key_function,switch.thermostat_dhw_onetimekey,6,9,1,16,1
ES73,thermostat,76,switchtime,program switchtime,string, ,true,sensor.thermostat_dhw_program_switchtime,sensor.thermostat_dhw_switchtime,6,9,1,17,8 ES73,thermostat,76,switchtimeWW,program switchtime warm water,string, ,true,sensor.thermostat_dhw_program_switchtime_warm_water,sensor.thermostat_dhw_switchtimeWW,6,9,1,17,8
ES73,thermostat,76,circswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_dhw_circulation_program_switchtime,sensor.thermostat_dhw_circswitchtime,6,9,1,25,8 ES73,thermostat,76,circswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_dhw_circulation_program_switchtime,sensor.thermostat_dhw_circswitchtime,6,9,1,25,8
ES73,thermostat,76,holidays,holiday dates,string, ,true,sensor.thermostat_dhw_holiday_dates,sensor.thermostat_dhw_holidays,6,9,1,33,13 ES73,thermostat,76,holidays,holiday dates,string, ,true,sensor.thermostat_dhw_holiday_dates,sensor.thermostat_dhw_holidays,6,9,1,33,13
ES73,thermostat,76,vacations,vacation dates,string, ,true,sensor.thermostat_dhw_vacation_dates,sensor.thermostat_dhw_vacations,6,9,1,46,13 ES73,thermostat,76,vacations,vacation dates,string, ,true,sensor.thermostat_dhw_vacation_dates,sensor.thermostat_dhw_vacations,6,9,1,46,13
@@ -4284,7 +4284,7 @@ ES79,thermostat,156,disinfectday,disinfection day,enum [mo\|tu\|we\|th\|fr\|sa\|
ES79,thermostat,156,disinfecthour,disinfection hour,uint8 (>=0<=23), ,true,number.thermostat_dhw_disinfection_hour,number.thermostat_dhw_disinfecthour,6,9,1,14,1 ES79,thermostat,156,disinfecthour,disinfection hour,uint8 (>=0<=23), ,true,number.thermostat_dhw_disinfection_hour,number.thermostat_dhw_disinfecthour,6,9,1,14,1
ES79,thermostat,156,maxtemp,maximum temperature,uint8 (>=60<=80),C,true,number.thermostat_dhw_maximum_temperature,number.thermostat_dhw_maxtemp,6,9,1,15,1 ES79,thermostat,156,maxtemp,maximum temperature,uint8 (>=60<=80),C,true,number.thermostat_dhw_maximum_temperature,number.thermostat_dhw_maxtemp,6,9,1,15,1
ES79,thermostat,156,onetimekey,one time key function,boolean, ,true,switch.thermostat_dhw_one_time_key_function,switch.thermostat_dhw_onetimekey,6,9,1,16,1 ES79,thermostat,156,onetimekey,one time key function,boolean, ,true,switch.thermostat_dhw_one_time_key_function,switch.thermostat_dhw_onetimekey,6,9,1,16,1
ES79,thermostat,156,switchtime,program switchtime,string, ,true,sensor.thermostat_dhw_program_switchtime,sensor.thermostat_dhw_switchtime,6,9,1,17,8 ES79,thermostat,156,switchtimeWW,program switchtime warm water,string, ,true,sensor.thermostat_dhw_program_switchtime_warm_water,sensor.thermostat_dhw_switchtimeWW,6,9,1,17,8
ES79,thermostat,156,circswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_dhw_circulation_program_switchtime,sensor.thermostat_dhw_circswitchtime,6,9,1,25,8 ES79,thermostat,156,circswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_dhw_circulation_program_switchtime,sensor.thermostat_dhw_circswitchtime,6,9,1,25,8
ES79,thermostat,156,holidays,holiday dates,string, ,true,sensor.thermostat_dhw_holiday_dates,sensor.thermostat_dhw_holidays,6,9,1,33,13 ES79,thermostat,156,holidays,holiday dates,string, ,true,sensor.thermostat_dhw_holiday_dates,sensor.thermostat_dhw_holidays,6,9,1,33,13
ES79,thermostat,156,vacations,vacation dates,string, ,true,sensor.thermostat_dhw_vacation_dates,sensor.thermostat_dhw_vacations,6,9,1,46,13 ES79,thermostat,156,vacations,vacation dates,string, ,true,sensor.thermostat_dhw_vacation_dates,sensor.thermostat_dhw_vacations,6,9,1,46,13
@@ -4808,8 +4808,8 @@ SM50,solar,162,externalcyl,external cylinder,boolean, ,true,switch.solar_externa
SM50,solar,162,thermaldisinfect,thermal disinfection,boolean, ,true,switch.solar_thermal_disinfection,switch.solar_thermaldisinfect,8,0,1,41,1 SM50,solar,162,thermaldisinfect,thermal disinfection,boolean, ,true,switch.solar_thermal_disinfection,switch.solar_thermaldisinfect,8,0,1,41,1
SM50,solar,162,heatmetering,heatmetering,boolean, ,true,switch.solar_heatmetering,switch.solar_heatmetering,8,0,1,42,1 SM50,solar,162,heatmetering,heatmetering,boolean, ,true,switch.solar_heatmetering,switch.solar_heatmetering,8,0,1,42,1
SM50,solar,162,activated,activated,boolean, ,true,switch.solar_activated,switch.solar_activated,8,0,1,43,1 SM50,solar,162,activated,activated,boolean, ,true,switch.solar_activated,switch.solar_activated,8,0,1,43,1
SM50,solar,162,solarpumpmode,pump mode,enum [constant\|pwm\|analog], ,true,select.solar_pump_mode,select.solar_solarpumpmode,8,0,1,44,1 SM50,solar,162,solarpumpmode,solar pump mode,enum [constant\|pwm\|analog], ,true,select.solar_solar_pump_mode,select.solar_solarpumpmode,8,0,1,44,1
SM50,solar,162,pumpkick,pump kick,boolean, ,true,switch.solar_pump_kick,switch.solar_pumpkick,8,0,1,45,1 SM50,solar,162,solarpumpkick,solar pump kick,boolean, ,true,switch.solar_solar_pump_kick,switch.solar_solarpumpkick,8,0,1,45,1
SM50,solar,162,plainwatermode,plain water mode,boolean, ,true,switch.solar_plain_water_mode,switch.solar_plainwatermode,8,0,1,46,1 SM50,solar,162,plainwatermode,plain water mode,boolean, ,true,switch.solar_plain_water_mode,switch.solar_plainwatermode,8,0,1,46,1
SM50,solar,162,doublematchflow,doublematchflow,boolean, ,true,switch.solar_doublematchflow,switch.solar_doublematchflow,8,0,1,47,1 SM50,solar,162,doublematchflow,doublematchflow,boolean, ,true,switch.solar_doublematchflow,switch.solar_doublematchflow,8,0,1,47,1
SM50,solar,162,pump2minmod,minimum pump 2 modulation,uint8 (>=0<=100),%,true,number.solar_minimum_pump_2_modulation,number.solar_pump2minmod,8,0,1,48,1 SM50,solar,162,pump2minmod,minimum pump 2 modulation,uint8 (>=0<=100),%,true,number.solar_minimum_pump_2_modulation,number.solar_pump2minmod,8,0,1,48,1
@@ -4862,8 +4862,8 @@ SM100/MS100,solar,163,externalcyl,external cylinder,boolean, ,true,switch.solar_
SM100/MS100,solar,163,thermaldisinfect,thermal disinfection,boolean, ,true,switch.solar_thermal_disinfection,switch.solar_thermaldisinfect,8,0,1,41,1 SM100/MS100,solar,163,thermaldisinfect,thermal disinfection,boolean, ,true,switch.solar_thermal_disinfection,switch.solar_thermaldisinfect,8,0,1,41,1
SM100/MS100,solar,163,heatmetering,heatmetering,boolean, ,true,switch.solar_heatmetering,switch.solar_heatmetering,8,0,1,42,1 SM100/MS100,solar,163,heatmetering,heatmetering,boolean, ,true,switch.solar_heatmetering,switch.solar_heatmetering,8,0,1,42,1
SM100/MS100,solar,163,activated,activated,boolean, ,true,switch.solar_activated,switch.solar_activated,8,0,1,43,1 SM100/MS100,solar,163,activated,activated,boolean, ,true,switch.solar_activated,switch.solar_activated,8,0,1,43,1
SM100/MS100,solar,163,solarpumpmode,pump mode,enum [constant\|pwm\|analog], ,true,select.solar_pump_mode,select.solar_solarpumpmode,8,0,1,44,1 SM100/MS100,solar,163,solarpumpmode,solar pump mode,enum [constant\|pwm\|analog], ,true,select.solar_solar_pump_mode,select.solar_solarpumpmode,8,0,1,44,1
SM100/MS100,solar,163,pumpkick,pump kick,boolean, ,true,switch.solar_pump_kick,switch.solar_pumpkick,8,0,1,45,1 SM100/MS100,solar,163,solarpumpkick,solar pump kick,boolean, ,true,switch.solar_solar_pump_kick,switch.solar_solarpumpkick,8,0,1,45,1
SM100/MS100,solar,163,plainwatermode,plain water mode,boolean, ,true,switch.solar_plain_water_mode,switch.solar_plainwatermode,8,0,1,46,1 SM100/MS100,solar,163,plainwatermode,plain water mode,boolean, ,true,switch.solar_plain_water_mode,switch.solar_plainwatermode,8,0,1,46,1
SM100/MS100,solar,163,doublematchflow,doublematchflow,boolean, ,true,switch.solar_doublematchflow,switch.solar_doublematchflow,8,0,1,47,1 SM100/MS100,solar,163,doublematchflow,doublematchflow,boolean, ,true,switch.solar_doublematchflow,switch.solar_doublematchflow,8,0,1,47,1
SM100/MS100,solar,163,pump2minmod,minimum pump 2 modulation,uint8 (>=0<=100),%,true,number.solar_minimum_pump_2_modulation,number.solar_pump2minmod,8,0,1,48,1 SM100/MS100,solar,163,pump2minmod,minimum pump 2 modulation,uint8 (>=0<=100),%,true,number.solar_minimum_pump_2_modulation,number.solar_pump2minmod,8,0,1,48,1
@@ -4916,8 +4916,8 @@ SM200/MS200,solar,164,externalcyl,external cylinder,boolean, ,true,switch.solar_
SM200/MS200,solar,164,thermaldisinfect,thermal disinfection,boolean, ,true,switch.solar_thermal_disinfection,switch.solar_thermaldisinfect,8,0,1,41,1 SM200/MS200,solar,164,thermaldisinfect,thermal disinfection,boolean, ,true,switch.solar_thermal_disinfection,switch.solar_thermaldisinfect,8,0,1,41,1
SM200/MS200,solar,164,heatmetering,heatmetering,boolean, ,true,switch.solar_heatmetering,switch.solar_heatmetering,8,0,1,42,1 SM200/MS200,solar,164,heatmetering,heatmetering,boolean, ,true,switch.solar_heatmetering,switch.solar_heatmetering,8,0,1,42,1
SM200/MS200,solar,164,activated,activated,boolean, ,true,switch.solar_activated,switch.solar_activated,8,0,1,43,1 SM200/MS200,solar,164,activated,activated,boolean, ,true,switch.solar_activated,switch.solar_activated,8,0,1,43,1
SM200/MS200,solar,164,solarpumpmode,pump mode,enum [constant\|pwm\|analog], ,true,select.solar_pump_mode,select.solar_solarpumpmode,8,0,1,44,1 SM200/MS200,solar,164,solarpumpmode,solar pump mode,enum [constant\|pwm\|analog], ,true,select.solar_solar_pump_mode,select.solar_solarpumpmode,8,0,1,44,1
SM200/MS200,solar,164,pumpkick,pump kick,boolean, ,true,switch.solar_pump_kick,switch.solar_pumpkick,8,0,1,45,1 SM200/MS200,solar,164,solarpumpkick,solar pump kick,boolean, ,true,switch.solar_solar_pump_kick,switch.solar_solarpumpkick,8,0,1,45,1
SM200/MS200,solar,164,plainwatermode,plain water mode,boolean, ,true,switch.solar_plain_water_mode,switch.solar_plainwatermode,8,0,1,46,1 SM200/MS200,solar,164,plainwatermode,plain water mode,boolean, ,true,switch.solar_plain_water_mode,switch.solar_plainwatermode,8,0,1,46,1
SM200/MS200,solar,164,doublematchflow,doublematchflow,boolean, ,true,switch.solar_doublematchflow,switch.solar_doublematchflow,8,0,1,47,1 SM200/MS200,solar,164,doublematchflow,doublematchflow,boolean, ,true,switch.solar_doublematchflow,switch.solar_doublematchflow,8,0,1,47,1
SM200/MS200,solar,164,pump2minmod,minimum pump 2 modulation,uint8 (>=0<=100),%,true,number.solar_minimum_pump_2_modulation,number.solar_pump2minmod,8,0,1,48,1 SM200/MS200,solar,164,pump2minmod,minimum pump 2 modulation,uint8 (>=0<=100),%,true,number.solar_minimum_pump_2_modulation,number.solar_pump2minmod,8,0,1,48,1
Can't render this file because it is too large.

View File

@@ -105,10 +105,10 @@ telegram_type_id,name,is_fetched,is_cmd
0x02A0,RC300Curves, ,cmd 0x02A0,RC300Curves, ,cmd
0x02A1,RC300Curves, ,cmd 0x02A1,RC300Curves, ,cmd
0x02A2,RC300Curves, ,cmd 0x02A2,RC300Curves, ,cmd
0x02A5,CRFMonitor, ,cmd 0x02A5,RC300Monitor, ,cmd
0x02A6,RC300Monitor, ,cmd 0x02A6,RC300Monitor, ,cmd
0x02A7,RC300Monitor, ,cmd 0x02A7,RC300Monitor, ,cmd
0x02A8,RC300Monitor, ,cmd 0x02A8,CRFMonitor, ,cmd
0x02A9,RC300Monitor, ,cmd 0x02A9,RC300Monitor, ,cmd
0x02AA,RC300Monitor, ,cmd 0x02AA,RC300Monitor, ,cmd
0x02AB,RC300Monitor, ,cmd 0x02AB,RC300Monitor, ,cmd
@@ -129,7 +129,7 @@ telegram_type_id,name,is_fetched,is_cmd
0x02BE,RC300Set, ,cmd 0x02BE,RC300Set, ,cmd
0x02BF,RC300Set, ,cmd 0x02BF,RC300Set, ,cmd
0x02C0,RC300Set, ,cmd 0x02C0,RC300Set, ,cmd
0x02CC,RC300Set2, ,cmd 0x02CC,HPPressure,fetched,cmd
0x02CD,MMPLUSConfigMessage,fetched,cmd 0x02CD,MMPLUSConfigMessage,fetched,cmd
0x02CE,RC300Set2, ,cmd 0x02CE,RC300Set2, ,cmd
0x02D0,RC300Set2, ,cmd 0x02D0,RC300Set2, ,cmd
1 telegram_type_id name is_fetched is_cmd
105 0x02A0 RC300Curves cmd
106 0x02A1 RC300Curves cmd
107 0x02A2 RC300Curves cmd
108 0x02A5 CRFMonitor RC300Monitor cmd
109 0x02A6 RC300Monitor cmd
110 0x02A7 RC300Monitor cmd
111 0x02A8 RC300Monitor CRFMonitor cmd
112 0x02A9 RC300Monitor cmd
113 0x02AA RC300Monitor cmd
114 0x02AB RC300Monitor cmd
129 0x02BE RC300Set cmd
130 0x02BF RC300Set cmd
131 0x02C0 RC300Set cmd
132 0x02CC RC300Set2 HPPressure fetched cmd
133 0x02CD MMPLUSConfigMessage fetched cmd
134 0x02CE RC300Set2 cmd
135 0x02D0 RC300Set2 cmd

View File

@@ -35,10 +35,10 @@
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"react-icons": "^5.3.0", "react-icons": "^5.3.0",
"react-router-dom": "^6.26.1", "react-router-dom": "^6.26.2",
"react-toastify": "^10.0.5", "react-toastify": "^10.0.5",
"typesafe-i18n": "^5.26.2", "typesafe-i18n": "^5.26.2",
"typescript": "^5.5.4" "typescript": "^5.6.2"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.25.2", "@babel/core": "^7.25.2",
@@ -52,15 +52,15 @@
"@types/react": "^18.3.5", "@types/react": "^18.3.5",
"@types/react-dom": "^18.3.0", "@types/react-dom": "^18.3.0",
"@types/react-router-dom": "^5.3.3", "@types/react-router-dom": "^5.3.3",
"concurrently": "^8.2.2", "concurrently": "^9.0.0",
"eslint": "^9.10.0", "eslint": "^9.10.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"formidable": "^3.5.1", "formidable": "^3.5.1",
"prettier": "^3.3.3", "prettier": "^3.3.3",
"rollup-plugin-visualizer": "^5.12.0", "rollup-plugin-visualizer": "^5.12.0",
"terser": "^5.31.6", "terser": "^5.32.0",
"typescript-eslint": "8.4.0", "typescript-eslint": "8.5.0",
"vite": "^5.4.3", "vite": "^5.4.4",
"vite-plugin-imagemin": "^0.6.1", "vite-plugin-imagemin": "^0.6.1",
"vite-tsconfig-paths": "^5.0.1" "vite-tsconfig-paths": "^5.0.1"
}, },

View File

@@ -102,7 +102,7 @@ const Help = () => {
color="primary" color="primary"
onClick={() => callAPI('system', 'info')} onClick={() => callAPI('system', 'info')}
> >
{LL.SUPPORT_INFORMATION(0)} {LL.DOWNLOAD(1)}&nbsp;{LL.SUPPORT_INFORMATION(0)}
</Button> </Button>
</Box> </Box>
@@ -113,24 +113,24 @@ const Help = () => {
color="primary" color="primary"
onClick={() => callAPI('system', 'allvalues')} onClick={() => callAPI('system', 'allvalues')}
> >
{LL.ALLVALUES()} {LL.DOWNLOAD(1)}&nbsp;{LL.ALLVALUES()}
</Button> </Button>
<Box border={1} p={1} mt={4}> <Box sx={{ p: 2, mt: 4, border: '1px dashed orange' }}>
<Typography align="center" variant="subtitle1" color="orange"> <Typography align="center" variant="subtitle1">
<b>{LL.HELP_INFORMATION_5()}</b> {LL.HELP_INFORMATION_5()}
</Typography> </Typography>
<Typography align="center"> <Typography align="center" mt={1}>
<Link <Link
target="_blank" target="_blank"
href="https://github.com/emsesp/EMS-ESP32" href="https://github.com/emsesp/EMS-ESP32"
color="primary" color="primary"
> >
{'github.com/emsesp/EMS-ESP32'} {'https://github.com/emsesp/EMS-ESP32'}
</Link> </Link>
</Typography> </Typography>
<Typography color="white" variant="subtitle2" align="center"> <Typography color="white" variant="subtitle1" align="center">
@proddy @MichaelDvP &copy;&nbsp;emsesp.org
</Typography> </Typography>
</Box> </Box>
</SectionContent> </SectionContent>

View File

@@ -613,10 +613,10 @@ const ApplicationSettings = () => {
name="tx_mode" name="tx_mode"
label={LL.TX_MODE()} label={LL.TX_MODE()}
value={data.tx_mode} value={data.tx_mode}
fullWidth
variant="outlined" variant="outlined"
onChange={updateFormValue} onChange={updateFormValue}
margin="normal" margin="normal"
sx={{ width: '15ch' }}
select select
> >
<MenuItem value={1}>EMS</MenuItem> <MenuItem value={1}>EMS</MenuItem>

View File

@@ -15,6 +15,7 @@ import {
Link, Link,
Typography Typography
} from '@mui/material'; } from '@mui/material';
import Grid from '@mui/material/Grid2';
import * as SystemApi from 'api/system'; import * as SystemApi from 'api/system';
import { import {
@@ -291,34 +292,11 @@ const DownloadUpload = () => {
<Typography sx={{ pb: 2 }} variant="h6" color="primary"> <Typography sx={{ pb: 2 }} variant="h6" color="primary">
{LL.DOWNLOAD(0)} {LL.DOWNLOAD(0)}
</Typography> </Typography>
<Box color="warning.main">
<Typography mb={1} variant="body2">
{LL.HELP_INFORMATION_4()}
</Typography>
<Button
sx={{ ml: 2 }}
startIcon={<DownloadIcon />}
variant="outlined"
color="primary"
onClick={() => callAPIandSave('system', 'info')}
>
{LL.SUPPORT_INFORMATION(0)}
</Button>
<Button
sx={{ ml: 2 }}
startIcon={<DownloadIcon />}
variant="outlined"
color="primary"
onClick={() => callAPIandSave('system', 'allvalues')}
>
{LL.ALLVALUES()}
</Button>
</Box>
<Box color="warning.main"> <Typography mb={1} variant="body2" color="warning">
<Typography mt={2} mb={1} variant="body2"> {LL.DOWNLOAD_SETTINGS_TEXT()}
{LL.DOWNLOAD_SETTINGS_TEXT()} </Typography>
</Typography> <Grid container spacing={1}>
<Button <Button
sx={{ ml: 2 }} sx={{ ml: 2 }}
startIcon={<DownloadIcon />} startIcon={<DownloadIcon />}
@@ -326,14 +304,9 @@ const DownloadUpload = () => {
color="primary" color="primary"
onClick={downloadSettings} onClick={downloadSettings}
> >
{LL.SETTINGS_OF('')} {LL.DOWNLOAD(1)}&nbsp;{LL.SETTINGS_OF(LL.APPLICATION())}
</Button> </Button>
</Box>
<Box color="warning.main">
<Typography mt={2} mb={1} variant="body2">
{LL.DOWNLOAD_CUSTOMIZATION_TEXT()}
</Typography>
<Button <Button
sx={{ ml: 2 }} sx={{ ml: 2 }}
startIcon={<DownloadIcon />} startIcon={<DownloadIcon />}
@@ -341,7 +314,7 @@ const DownloadUpload = () => {
color="primary" color="primary"
onClick={downloadCustomizations} onClick={downloadCustomizations}
> >
{LL.CUSTOMIZATIONS()} {LL.DOWNLOAD(1)}&nbsp;{LL.CUSTOMIZATIONS()}
</Button> </Button>
<Button <Button
sx={{ ml: 2 }} sx={{ ml: 2 }}
@@ -350,13 +323,8 @@ const DownloadUpload = () => {
color="primary" color="primary"
onClick={downloadEntities} onClick={downloadEntities}
> >
{LL.CUSTOM_ENTITIES(0)} {LL.DOWNLOAD(1)}&nbsp;{LL.CUSTOM_ENTITIES(0)}
</Button> </Button>
<Box color="warning.main">
<Typography mt={2} mb={1} variant="body2">
{LL.DOWNLOAD_SCHEDULE_TEXT()}
</Typography>
</Box>
<Button <Button
sx={{ ml: 2 }} sx={{ ml: 2 }}
startIcon={<DownloadIcon />} startIcon={<DownloadIcon />}
@@ -364,15 +332,24 @@ const DownloadUpload = () => {
color="primary" color="primary"
onClick={downloadSchedule} onClick={downloadSchedule}
> >
{LL.SCHEDULE(0)} {LL.DOWNLOAD(1)}&nbsp;{LL.SCHEDULE(0)}
</Button> </Button>
</Grid>
<Typography sx={{ pt: 2, pb: 2 }} variant="h6" color="primary">
{LL.UPLOAD()}
</Typography>
<Box color="warning.main" sx={{ pb: 2 }}>
<Typography variant="body2">{LL.UPLOAD_TEXT()}</Typography>
</Box> </Box>
<Box color="warning.main"> <SingleUpload doRestart={doRestart} />
<Typography mt={2} variant="body2">
{LL.EMS_ESP_VER()} <Typography sx={{ pt: 2 }} variant="h6" color="primary">
</Typography> {LL.EMS_ESP_VER()}
</Box> </Typography>
<Box p={2} mt={2} border="1px solid grey" borderRadius={2}> <Box p={2} mt={2} border="1px solid grey" borderRadius={2}>
<Typography> <Typography>
<b>{LL.VERSION() + ':'}</b>&nbsp;{data.emsesp_version} <b>{LL.VERSION() + ':'}</b>&nbsp;{data.emsesp_version}
@@ -430,16 +407,6 @@ const DownloadUpload = () => {
{renderUploadDialog()} {renderUploadDialog()}
</Box> </Box>
<Typography sx={{ pt: 2, pb: 2 }} variant="h6" color="primary">
{LL.UPLOAD()}
</Typography>
<Box color="warning.main" sx={{ pb: 2 }}>
<Typography variant="body2">{LL.UPLOAD_TEXT()}</Typography>
</Box>
<SingleUpload doRestart={doRestart} />
</> </>
); );
}; };

View File

@@ -59,9 +59,10 @@ const RestartMonitor = () => {
: data?.status === 'ready' : data?.status === 'ready'
? LL.RESTARTING_PRE() ? LL.RESTARTING_PRE()
: LL.RESTARTING_POST()} : LL.RESTARTING_POST()}
&hellip;
</Typography> </Typography>
<Typography mt={2} variant="h6" fontWeight={400} textAlign="center"> <Typography mt={2} variant="h6" fontWeight={400} textAlign="center">
{LL.PLEASE_WAIT()}&hellip; {LL.PLEASE_WAIT()}
</Typography> </Typography>
{errorMessage ? ( {errorMessage ? (

View File

@@ -6,8 +6,12 @@ import WarningIcon from '@mui/icons-material/Warning';
import { Box, Button, Checkbox, MenuItem, TextField, styled } from '@mui/material'; import { Box, Button, Checkbox, MenuItem, TextField, styled } from '@mui/material';
import Grid from '@mui/material/Grid2'; import Grid from '@mui/material/Grid2';
import * as SystemApi from 'api/system'; import {
import { fetchLogES } from 'api/system'; fetchLog,
fetchLogES,
readLogSettings,
updateLogSettings
} from 'api/system';
import { useRequest, useSSE } from 'alova/client'; import { useRequest, useSSE } from 'alova/client';
import { import {
@@ -22,20 +26,18 @@ import type { LogEntry, LogSettings } from 'types';
import { LogLevel } from 'types'; import { LogLevel } from 'types';
import { updateValueDirty, useRest } from 'utils'; import { updateValueDirty, useRest } from 'utils';
const ButtonTextColors = { const TextColors = {
[LogLevel.ERROR]: '#ff0000', // red [LogLevel.ERROR]: '#ff0000', // red
[LogLevel.WARNING]: '#ffcc00', // yellow [LogLevel.WARNING]: '#ff0000', // red
[LogLevel.NOTICE]: '#ffffff', // white [LogLevel.NOTICE]: '#ffffff', // white
[LogLevel.INFO]: '#ffffff', // yellow [LogLevel.INFO]: '#ffcc00', // yellow
[LogLevel.DEBUG]: '#00ffff', // cyan [LogLevel.DEBUG]: '#00ffff', // cyan
[LogLevel.TRACE]: '#00ffff' // cyan [LogLevel.TRACE]: '#00ffff' // cyan
}; };
const LogEntryLine = styled('div')( const LogEntryLine = styled('span')(
({ details: { level } }: { details: { level: LogLevel } }) => ({ ({ details: { level } }: { details: { level: LogLevel } }) => ({
color: ButtonTextColors[level], color: TextColors[level]
font: '14px monospace',
whiteSpace: 'nowrap'
}) })
); );
@@ -79,8 +81,8 @@ const SystemLog = () => {
saveData, saveData,
errorMessage errorMessage
} = useRest<LogSettings>({ } = useRest<LogSettings>({
read: SystemApi.readLogSettings, read: readLogSettings,
update: SystemApi.updateLogSettings update: updateLogSettings
}); });
const [logEntries, setLogEntries] = useState<LogEntry[]>([]); const [logEntries, setLogEntries] = useState<LogEntry[]>([]);
@@ -114,7 +116,7 @@ const SystemLog = () => {
}); });
// called on page load to reset pointer and fetch all log entries // called on page load to reset pointer and fetch all log entries
useRequest(SystemApi.fetchLog()); useRequest(fetchLog());
const paddedLevelLabel = (level: LogLevel) => { const paddedLevelLabel = (level: LogLevel) => {
const label = levelLabel(level); const label = levelLabel(level);
@@ -190,23 +192,25 @@ const SystemLog = () => {
<MenuItem value={9}>ALL</MenuItem> <MenuItem value={9}>ALL</MenuItem>
</TextField> </TextField>
</Grid> </Grid>
<Grid size={2}> {data.psram && (
<TextField <Grid size={2}>
name="max_messages" <TextField
label={LL.BUFFER_SIZE()} name="max_messages"
value={data.max_messages} label={LL.BUFFER_SIZE()}
fullWidth value={data.max_messages}
variant="outlined" fullWidth
onChange={updateFormValue} variant="outlined"
margin="normal" onChange={updateFormValue}
select margin="normal"
> select
<MenuItem value={25}>25</MenuItem> >
<MenuItem value={50}>50</MenuItem> <MenuItem value={25}>25</MenuItem>
<MenuItem value={75}>75</MenuItem> <MenuItem value={50}>50</MenuItem>
<MenuItem value={100}>100</MenuItem> <MenuItem value={75}>75</MenuItem>
</TextField> <MenuItem value={100}>100</MenuItem>
</Grid> </TextField>
</Grid>
)}
<Grid> <Grid>
<BlockFormControlLabel <BlockFormControlLabel
control={ control={
@@ -251,14 +255,17 @@ const SystemLog = () => {
}} }}
> >
{logEntries.map((e) => ( {logEntries.map((e) => (
<LogEntryLine details={{ level: e.l }} key={e.i}> <div style={{ font: '14px monospace', whiteSpace: 'nowrap' }}>
<span>{e.t}</span> <span>{e.t}</span>
<span>{paddedLevelLabel(e.l)}&nbsp;</span> <span>{paddedLevelLabel(e.l)}&nbsp;</span>
<span>{paddedIDLabel(e.i)} </span> <span>{paddedIDLabel(e.i)} </span>
<span>{paddedNameLabel(e.n)} </span> <span>{paddedNameLabel(e.n)} </span>
<span>{e.m}</span> <LogEntryLine details={{ level: e.l }} key={e.i}>
</LogEntryLine> {e.m}
</LogEntryLine>
</div>
))} ))}
<div ref={ref} /> <div ref={ref} />
</Box> </Box>
</> </>

View File

@@ -44,7 +44,7 @@ const SingleUpload = ({ doRestart }) => {
abort: cancelUpload abort: cancelUpload
} = useRequest(SystemApi.uploadFile, { } = useRequest(SystemApi.uploadFile, {
immediate: false immediate: false
}).onComplete(({ data }) => { }).onSuccess(({ data }) => {
if (data) { if (data) {
setMd5(data.md5 as string); setMd5(data.md5 as string);
toast.success(LL.UPLOAD() + ' MD5 ' + LL.SUCCESSFUL()); toast.success(LL.UPLOAD() + ' MD5 ' + LL.SUCCESSFUL());
@@ -59,10 +59,8 @@ const SingleUpload = ({ doRestart }) => {
await sendUpload(file).catch((error: Error) => { await sendUpload(file).catch((error: Error) => {
if (error.message === 'The user aborted a request') { if (error.message === 'The user aborted a request') {
toast.warning(LL.UPLOAD() + ' ' + LL.ABORTED()); toast.warning(LL.UPLOAD() + ' ' + LL.ABORTED());
} else if (error.message === 'Network Error') {
toast.warning('Invalid file extension or incompatible bin file');
} else { } else {
toast.error(error.message); toast.warning('Invalid file extension or incompatible bin file');
} }
}); });
} }

View File

@@ -177,7 +177,7 @@ const de: Translation = {
STABLE: 'Stabil', STABLE: 'Stabil',
DEVELOPMENT: 'Entwicklung', DEVELOPMENT: 'Entwicklung',
RELEASE_NOTES: 'Versionshinweise', RELEASE_NOTES: 'Versionshinweise',
EMS_ESP_VER: 'EMS-ESP Version', EMS_ESP_VER: 'Firmware Version', // TODO translate
UPTIME: 'Systembetriebszeit', UPTIME: 'Systembetriebszeit',
FREE_MEMORY: 'Freier RAM Speicher', FREE_MEMORY: 'Freier RAM Speicher',
PSRAM: 'PSRAM (Größe / Frei)', PSRAM: 'PSRAM (Größe / Frei)',
@@ -186,10 +186,8 @@ const de: Translation = {
FILESYSTEM: 'Dateisystem (Genutzt / Frei)', FILESYSTEM: 'Dateisystem (Genutzt / Frei)',
BUFFER_SIZE: 'max. Puffergröße', BUFFER_SIZE: 'max. Puffergröße',
COMPACT: 'Kompakte Darstellung', COMPACT: 'Kompakte Darstellung',
DOWNLOAD_CUSTOMIZATION_TEXT: 'Herunterladen der individuellen Entitätsanpassungen', DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
DOWNLOAD_SCHEDULE_TEXT: 'Herunterladen geplanter Befehle', UPLOAD_TEXT: 'Upload a new firmware (.bin) file or a backup file (.json)', // TODO translate
DOWNLOAD_SETTINGS_TEXT: 'Herunterladen der Anwendungseinstellungen. Vorsicht beim Teilen der Einstellungen, da sie Passwörter und andere sensible Daten enthalten',
UPLOAD_TEXT: 'Hochladen von neuer Firmware (.bin), Geräte- oder Entitätseinstellungen (.json), zur optionalen Validitätsprüfung zuerst die (.md5) Datei hochladen',
UPLOAD_DROP_TEXT: 'Klicken Sie hier, oder ziehen Sie eine Datei hierher', UPLOAD_DROP_TEXT: 'Klicken Sie hier, oder ziehen Sie eine Datei hierher',
ERROR: 'Unerwarteter Fehler, bitte versuchen Sie es erneut', ERROR: 'Unerwarteter Fehler, bitte versuchen Sie es erneut',
TIME_SET: 'Zeit gesetzt', TIME_SET: 'Zeit gesetzt',
@@ -340,7 +338,7 @@ const de: Translation = {
LATEST_VERSION: 'Sie verwenden die neueste Firmware-Version.', LATEST_VERSION: 'Sie verwenden die neueste Firmware-Version.',
PLEASE_WAIT: 'Bitte warten', PLEASE_WAIT: 'Bitte warten',
RESTARTING_PRE: 'Initialisierung', RESTARTING_PRE: 'Initialisierung',
RESTARTING_POST: 'Neuladen' RESTARTING_POST: 'Vorbereitung'
}; };
export default de; export default de;

View File

@@ -177,7 +177,7 @@ const en: Translation = {
STABLE: 'Stable', STABLE: 'Stable',
DEVELOPMENT: 'Development', DEVELOPMENT: 'Development',
RELEASE_NOTES: 'release notes', RELEASE_NOTES: 'release notes',
EMS_ESP_VER: 'EMS-ESP Version', EMS_ESP_VER: 'Firmware Version', // TODO translate
UPTIME: 'System Uptime', UPTIME: 'System Uptime',
FREE_MEMORY: 'Free Memory', FREE_MEMORY: 'Free Memory',
PSRAM: 'PSRAM (Size / Free)', PSRAM: 'PSRAM (Size / Free)',
@@ -186,10 +186,8 @@ const en: Translation = {
FILESYSTEM: 'File System (Used / Free)', FILESYSTEM: 'File System (Used / Free)',
BUFFER_SIZE: 'Max Buffer Size', BUFFER_SIZE: 'Max Buffer Size',
COMPACT: 'Compact', COMPACT: 'Compact',
DOWNLOAD_CUSTOMIZATION_TEXT: 'Download the entity customizations', DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
DOWNLOAD_SCHEDULE_TEXT: 'Download Scheduler Events', UPLOAD_TEXT: 'Upload a new firmware (.bin) file or a backup file (.json)',
DOWNLOAD_SETTINGS_TEXT: 'Download the application settings. Be careful when sharing your settings as this file contains passwords and other sensitive system information',
UPLOAD_TEXT: 'Upload a new firmware (.bin) file, settings or customizations (.json) file below, for optional validation upload (.md5) first',
UPLOAD_DROP_TEXT: 'Drop file or click here', UPLOAD_DROP_TEXT: 'Drop file or click here',
ERROR: 'Unexpected Error, please try again', ERROR: 'Unexpected Error, please try again',
TIME_SET: 'Time set', TIME_SET: 'Time set',
@@ -334,13 +332,13 @@ const en: Translation = {
ALLVALUES: 'All Values', ALLVALUES: 'All Values',
SPECIAL_FUNCTIONS: 'Special Functions', SPECIAL_FUNCTIONS: 'Special Functions',
WAIT_FIRMWARE: 'Firmware is uploading and installing', WAIT_FIRMWARE: 'Firmware is uploading and installing',
INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', INSTALL_VERSION: 'This will install version {0}. Are you sure?',
SWITCH_DEV: 'switch to the development version', SWITCH_DEV: 'switch to the development version',
UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', UPGRADE_AVAILABLE: 'There is a firmware upgrade available!',
LATEST_VERSION: 'You are using the latest firmware version.', LATEST_VERSION: 'You are using the latest firmware version.',
PLEASE_WAIT: 'Please wait', PLEASE_WAIT: 'Please wait',
RESTARTING_PRE: 'Initializing', RESTARTING_PRE: 'Initializing',
RESTARTING_POST: 'Reloading' RESTARTING_POST: 'Preparing'
}; };
export default en; export default en;

View File

@@ -177,7 +177,7 @@ const fr: Translation = {
STABLE: 'Stable', // TODO translate STABLE: 'Stable', // TODO translate
DEVELOPMENT: 'Développement', DEVELOPMENT: 'Développement',
RELEASE_NOTES: 'notes de version', RELEASE_NOTES: 'notes de version',
EMS_ESP_VER: 'Version EMS-ESP', EMS_ESP_VER: 'Firmware Version', // TODO translate
UPTIME: 'Durée de fonctionnement du système', UPTIME: 'Durée de fonctionnement du système',
FREE_MEMORY: 'Libre Memory', FREE_MEMORY: 'Libre Memory',
PSRAM: 'PSRAM (Taille / Libre)', PSRAM: 'PSRAM (Taille / Libre)',
@@ -186,10 +186,8 @@ const fr: Translation = {
FILESYSTEM: 'File System (Utilisée / Libre)', FILESYSTEM: 'File System (Utilisée / Libre)',
BUFFER_SIZE: 'Max taille du buffer', BUFFER_SIZE: 'Max taille du buffer',
COMPACT: 'Compact', COMPACT: 'Compact',
DOWNLOAD_CUSTOMIZATION_TEXT: "Télécharger les personnalisations d'entités", DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
DOWNLOAD_SCHEDULE_TEXT: 'Download Scheduler Events', // TODO translate UPLOAD_TEXT: 'Upload a new firmware (.bin) file or a backup file (.json)', // TODO translate
DOWNLOAD_SETTINGS_TEXT: "Téléchargez les paramètres de l'application. Soyez prudent lorsque vous partagez vos paramètres car ce fichier contient des mots de passe et d'autres informations système sensibles.",
UPLOAD_TEXT: "Téléchargez un nouveau fichier de firmware (.bin), un fichier de paramètres ou de personnalisations (.json) ci-dessous, pour une validation optionnelle téléchargez d'abord un fichier (.md5)",
UPLOAD_DROP_TEXT: 'Déposer le fichier ou cliquer ici', UPLOAD_DROP_TEXT: 'Déposer le fichier ou cliquer ici',
ERROR: 'Erreur inattendue, veuillez réessayer', ERROR: 'Erreur inattendue, veuillez réessayer',
TIME_SET: 'Time set', TIME_SET: 'Time set',
@@ -334,13 +332,13 @@ const fr: Translation = {
ALLVALUES: 'All Values', // TODO translate ALLVALUES: 'All Values', // TODO translate
SPECIAL_FUNCTIONS: 'Special Functions', SPECIAL_FUNCTIONS: 'Special Functions',
WAIT_FIRMWARE: 'Firmware is uploading and installing', // TODO translate WAIT_FIRMWARE: 'Firmware is uploading and installing', // TODO translate
INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate INSTALL_VERSION: 'This will install version {0}. Are you sure?', // TODO translate
SWITCH_DEV: 'switch to the development version', // TODO translate SWITCH_DEV: 'switch to the development version', // TODO translate
UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate
LATEST_VERSION: 'You are using the latest firmware version.', // TODO translate // TODO translate LATEST_VERSION: 'You are using the latest firmware version.', // TODO translate // TODO translate
PLEASE_WAIT: 'Please wait', // TODO translate PLEASE_WAIT: 'Please wait', // TODO translate
RESTARTING_PRE: 'Initializing', // TODO translate RESTARTING_PRE: 'Initializing', // TODO translate
RESTARTING_POST: 'Reloading' // TODO translate RESTARTING_POST: 'Preparing' // TODO translate
}; };
export default fr; export default fr;

View File

@@ -177,7 +177,7 @@ const it: Translation = {
STABLE: 'Stable', // TODO translate STABLE: 'Stable', // TODO translate
DEVELOPMENT: 'Sviluppo', DEVELOPMENT: 'Sviluppo',
RELEASE_NOTES: 'note rilascio', RELEASE_NOTES: 'note rilascio',
EMS_ESP_VER: 'Versione EMS-ESP', EMS_ESP_VER: 'Versione Firmware',
UPTIME: 'Tempo di attività del sistema', UPTIME: 'Tempo di attività del sistema',
FREE_MEMORY: 'Free Memory', FREE_MEMORY: 'Free Memory',
PSRAM: 'PSRAM (Size / Free)', PSRAM: 'PSRAM (Size / Free)',
@@ -186,10 +186,8 @@ const it: Translation = {
FILESYSTEM: 'Memoria Sistema (Usata / Libera)', FILESYSTEM: 'Memoria Sistema (Usata / Libera)',
BUFFER_SIZE: 'Max Buffer Size', BUFFER_SIZE: 'Max Buffer Size',
COMPACT: 'Compact', COMPACT: 'Compact',
DOWNLOAD_CUSTOMIZATION_TEXT: 'Scarica personalizzazioni entità', DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
DOWNLOAD_SCHEDULE_TEXT: 'Download Scheduler Events', UPLOAD_TEXT: 'Upload a new firmware (.bin) file or a backup file (.json)', // TODO translate
DOWNLOAD_SETTINGS_TEXT: 'Scarica le impostazioni dell applicazione. Fai attenzione quando condividi le tue impostazioni poiché questo file contiene password e altre informazioni di sistema riservate',
UPLOAD_TEXT: 'Carica un nuovo file firmware (.bin) , file delle impostazioni o delle personalizzazioni (.json) di seguito, per un opzione di convalida scaricare dapprima un file "*.MD5" ',
UPLOAD_DROP_TEXT: 'Trascina il file o clicca qui', UPLOAD_DROP_TEXT: 'Trascina il file o clicca qui',
ERROR: 'Errore Inaspettato, prego tenta ancora', ERROR: 'Errore Inaspettato, prego tenta ancora',
TIME_SET: 'Imposta Ora', TIME_SET: 'Imposta Ora',
@@ -334,13 +332,13 @@ const it: Translation = {
ALLVALUES: 'All Values', // TODO translate ALLVALUES: 'All Values', // TODO translate
SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate
WAIT_FIRMWARE: 'Firmware is uploading and installing', // TODO translate WAIT_FIRMWARE: 'Firmware is uploading and installing', // TODO translate
INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate INSTALL_VERSION: 'This will install version {0}. Are you sure?', // TODO translate
SWITCH_DEV: 'switch to the development version', // TODO translate SWITCH_DEV: 'switch to the development version', // TODO translate
UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate
LATEST_VERSION: 'You are using the latest firmware version.', // TODO translate LATEST_VERSION: 'You are using the latest firmware version.', // TODO translate
PLEASE_WAIT: 'Please wait', // TODO translate PLEASE_WAIT: 'Please wait', // TODO translate
RESTARTING_PRE: 'Initializing', // TODO translate RESTARTING_PRE: 'Initializing', // TODO translate
RESTARTING_POST: 'Reloading' // TODO translate RESTARTING_POST: 'Preparing' // TODO translate
}; };
export default it; export default it;

View File

@@ -177,7 +177,7 @@ const nl: Translation = {
STABLE: 'Stable', STABLE: 'Stable',
DEVELOPMENT: 'Development', DEVELOPMENT: 'Development',
RELEASE_NOTES: 'release notes', RELEASE_NOTES: 'release notes',
EMS_ESP_VER: 'EMS-ESP Versie', EMS_ESP_VER: 'Firmware Versie',
UPTIME: 'Systeem Uptime', UPTIME: 'Systeem Uptime',
FREE_MEMORY: 'Free Memory', FREE_MEMORY: 'Free Memory',
PSRAM: 'PSRAM (Size / Free)', PSRAM: 'PSRAM (Size / Free)',
@@ -186,10 +186,8 @@ const nl: Translation = {
FILESYSTEM: 'File System (Used / Free)', FILESYSTEM: 'File System (Used / Free)',
BUFFER_SIZE: 'Max Buffer Size', BUFFER_SIZE: 'Max Buffer Size',
COMPACT: 'Compact', COMPACT: 'Compact',
DOWNLOAD_CUSTOMIZATION_TEXT: 'Download alle custom instellingen', DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
DOWNLOAD_SCHEDULE_TEXT: 'Download Scheduler Events', UPLOAD_TEXT: 'Upload a new firmware (.bin) file or a backup file (.json)', // TODO translate
DOWNLOAD_SETTINGS_TEXT: 'Download de applicatie settings. Wees voorzichting met het delen van dit bestand want het bevat o.a. de wachtwoorden in plain text',
UPLOAD_TEXT: 'Upload een nieuwe firmware (.bin) file, instellingen of custom instellingen (.json) bestand hieronder',
UPLOAD_DROP_TEXT: 'Sleep bestand hierheen of klik hier', UPLOAD_DROP_TEXT: 'Sleep bestand hierheen of klik hier',
ERROR: 'Onverwachte fout, probeer opnieuw', ERROR: 'Onverwachte fout, probeer opnieuw',
TIME_SET: 'Tijd ingesteld', TIME_SET: 'Tijd ingesteld',
@@ -334,13 +332,13 @@ const nl: Translation = {
ALLVALUES: 'All Values', // TODO translate ALLVALUES: 'All Values', // TODO translate
SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate
WAIT_FIRMWARE: 'Firmware is uploading and installing', // TODO translate WAIT_FIRMWARE: 'Firmware is uploading and installing', // TODO translate
INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate INSTALL_VERSION: 'This will install version {0}. Are you sure?', // TODO translate
SWITCH_DEV: 'switch to the development version', // TODO translate SWITCH_DEV: 'switch to the development version', // TODO translate
UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate
LATEST_VERSION: 'You are using the latest firmware version.', // TODO translate LATEST_VERSION: 'You are using the latest firmware version.', // TODO translate
PLEASE_WAIT: 'Please wait', // TODO translate PLEASE_WAIT: 'Please wait', // TODO translate
RESTARTING_PRE: 'Initializing', // TODO translate RESTARTING_PRE: 'Initializing', // TODO translate
RESTARTING_POST: 'Reloading' // TODO translate RESTARTING_POST: 'Preparing' // TODO translate
}; };
export default nl; export default nl;

View File

@@ -177,7 +177,7 @@ const no: Translation = {
STABLE: 'Stable', // TODO translate STABLE: 'Stable', // TODO translate
DEVELOPMENT: 'Development', DEVELOPMENT: 'Development',
RELEASE_NOTES: 'release notes', RELEASE_NOTES: 'release notes',
EMS_ESP_VER: 'EMS-ESP Version', EMS_ESP_VER: 'Firmware Version', // TODO translate
UPTIME: 'System Oppetid', UPTIME: 'System Oppetid',
FREE_MEMORY: 'Ledig Memory', FREE_MEMORY: 'Ledig Memory',
PSRAM: 'PSRAM (Størrelse / Ledig)', PSRAM: 'PSRAM (Størrelse / Ledig)',
@@ -186,10 +186,8 @@ const no: Translation = {
FILESYSTEM: 'File System (Brukt / Ledig)', FILESYSTEM: 'File System (Brukt / Ledig)',
BUFFER_SIZE: 'Max Buffer Størrelse', BUFFER_SIZE: 'Max Buffer Størrelse',
COMPACT: 'Komprimere', COMPACT: 'Komprimere',
DOWNLOAD_CUSTOMIZATION_TEXT: 'Last ned objektstilpasninger', DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
DOWNLOAD_SCHEDULE_TEXT: 'Last ned planlagte oppgaver', UPLOAD_TEXT: 'Upload a new firmware (.bin) file or a backup file (.json)', // TODO translate
DOWNLOAD_SETTINGS_TEXT: 'Last ned applikasjonskonfigurasjon. Vær varsom med å dele fila da den inneholder passord og annen sensitiv system informasjon',
UPLOAD_TEXT: 'Last opp en ny firmware (.bin) fil, innstillinger eller tilpassninger (.json) fil nedenfor',
UPLOAD_DROP_TEXT: 'Slipp fil eller klikk her', UPLOAD_DROP_TEXT: 'Slipp fil eller klikk her',
ERROR: 'Ukjent feil, prøv igjen', ERROR: 'Ukjent feil, prøv igjen',
TIME_SET: 'Still in tid', TIME_SET: 'Still in tid',
@@ -334,13 +332,13 @@ const no: Translation = {
ALLVALUES: 'All Values', // TODO translate ALLVALUES: 'All Values', // TODO translate
SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate
WAIT_FIRMWARE: 'Firmware is uploading and installing', // TODO translate WAIT_FIRMWARE: 'Firmware is uploading and installing', // TODO translate
INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate INSTALL_VERSION: 'This will install version {0}. Are you sure?', // TODO translate
SWITCH_DEV: 'switch to the development version', // TODO translate SWITCH_DEV: 'switch to the development version', // TODO translate
UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate
LATEST_VERSION: 'You are using the latest firmware version.', // TODO translate LATEST_VERSION: 'You are using the latest firmware version.', // TODO translate
PLEASE_WAIT: 'Please wait', // TODO translate PLEASE_WAIT: 'Please wait', // TODO translate
RESTARTING_PRE: 'Initializing', // TODO translate RESTARTING_PRE: 'Initializing', // TODO translate
RESTARTING_POST: 'Reloading' // TODO translate RESTARTING_POST: 'Preparing' // TODO translate
}; };
export default no; export default no;

View File

@@ -177,7 +177,7 @@ const pl: BaseTranslation = {
STABLE: 'Stable', // TODO translate STABLE: 'Stable', // TODO translate
DEVELOPMENT: 'Testowe', DEVELOPMENT: 'Testowe',
RELEASE_NOTES: 'lista zmian', RELEASE_NOTES: 'lista zmian',
EMS_ESP_VER: 'Wersja EMS-ESP', EMS_ESP_VER: 'Wersja Firmware',
UPTIME: 'Czas działania systemu', UPTIME: 'Czas działania systemu',
FREE_MEMORY: 'Wolne Memory', // TODO translate FREE_MEMORY: 'Wolne Memory', // TODO translate
PSRAM: 'PSRAM (rozmiar / wolne)', PSRAM: 'PSRAM (rozmiar / wolne)',
@@ -186,10 +186,8 @@ const pl: BaseTranslation = {
FILESYSTEM: 'System plików (wykorzystane / wolne)', FILESYSTEM: 'System plików (wykorzystane / wolne)',
BUFFER_SIZE: 'Maksymalna pojemność bufora (ilość wpisów)', BUFFER_SIZE: 'Maksymalna pojemność bufora (ilość wpisów)',
COMPACT: 'Kompaktowy', COMPACT: 'Kompaktowy',
DOWNLOAD_CUSTOMIZATION_TEXT: 'Pobierz personalizacje.', DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
DOWNLOAD_SCHEDULE_TEXT: 'Pobierz harmonogram zdarzeń.', UPLOAD_TEXT: 'Upload a new firmware (.bin) file or a backup file (.json)', // TODO translate
DOWNLOAD_SETTINGS_TEXT: 'Pobierz ustawienia aplikacji. Uwaga! Plik z ustawieniami zawiera hasła oraz inne wrażliwe informacje systemowe! Nie udostepniaj go pochopnie!',
UPLOAD_TEXT: 'Wyślij firmware (.bin), ustawienia lub personalizacje (.json). Opcjonalnie, wyślij wcześniej plik walidacji z sumą kontrolną (.md5).',
UPLOAD_DROP_TEXT: 'Przeciągnij tutaj plik lub kliknij', UPLOAD_DROP_TEXT: 'Przeciągnij tutaj plik lub kliknij',
ERROR: 'Nieoczekiwany błąd, spróbuj ponownie!', ERROR: 'Nieoczekiwany błąd, spróbuj ponownie!',
TIME_SET: 'Zegar został ustawiony.', TIME_SET: 'Zegar został ustawiony.',
@@ -334,13 +332,13 @@ const pl: BaseTranslation = {
ALLVALUES: 'All Values', // TODO translate ALLVALUES: 'All Values', // TODO translate
SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate
WAIT_FIRMWARE: 'Firmware is uploading and installing', // TODO translate WAIT_FIRMWARE: 'Firmware is uploading and installing', // TODO translate
INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate INSTALL_VERSION: 'This will install version {0}. Are you sure?', // TODO translate
SWITCH_DEV: 'switch to the development version', // TODO translate SWITCH_DEV: 'switch to the development version', // TODO translate
UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate
LATEST_VERSION: 'You are using the latest firmware version.', // TODO translate LATEST_VERSION: 'You are using the latest firmware version.', // TODO translate
PLEASE_WAIT: 'Please wait', // TODO translate PLEASE_WAIT: 'Please wait', // TODO translate
RESTARTING_PRE: 'Initializing', // TODO translate RESTARTING_PRE: 'Initializing', // TODO translate
RESTARTING_POST: 'Reloading' // TODO translate RESTARTING_POST: 'Preparing' // TODO translate
}; };
export default pl; export default pl;

View File

@@ -177,19 +177,17 @@ const sk: Translation = {
STABLE: 'Stabilná', // TODO translate STABLE: 'Stabilná', // TODO translate
DEVELOPMENT: 'Vývojárska', DEVELOPMENT: 'Vývojárska',
RELEASE_NOTES: 'poznámky k verzii', RELEASE_NOTES: 'poznámky k verzii',
EMS_ESP_VER: 'EMS-ESP verzia', EMS_ESP_VER: 'Firmware verzia',
UPTIME: 'Beh systému', UPTIME: 'Beh systému',
FREE_MEMORY: 'Voľná pamäť', // TODO translate FREE_MEMORY: 'Voľné Memory',
PSRAM: 'PSRAM (Veľkosť / Voľné)', PSRAM: 'PSRAM (Veľkosť / Voľné)',
FLASH: 'Flash chip (Veľkosť , Rýchlosť)', FLASH: 'Flash chip (Veľkosť , Rýchlosť)',
APPSIZE: 'Applikácia (Oddiel: Použité / Voľné)', APPSIZE: 'Applikácia (Oddiel: Použité / Voľné)',
FILESYSTEM: 'Súborový systém (Použité / Voľné)', FILESYSTEM: 'Súborový systém (Použité / Voľné)',
BUFFER_SIZE: 'Buffer-max.veľkosť', BUFFER_SIZE: 'Buffer-max.veľkosť',
COMPACT: 'Kompaktné', COMPACT: 'Kompaktné',
DOWNLOAD_CUSTOMIZATION_TEXT: 'Stiahnutie prispôsobení entity', DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
DOWNLOAD_SCHEDULE_TEXT: 'Stiahnutie plánovača udalostí', UPLOAD_TEXT: 'Upload a new firmware (.bin) file or a backup file (.json)', // TODO translate
DOWNLOAD_SETTINGS_TEXT: 'Stiahnite si nastavenia aplikácie. Pri zdieľaní nastavení buďte opatrní, pretože tento súbor obsahuje heslá a iné citlivé systémové informácie.',
UPLOAD_TEXT: 'Najskôr nahrajte nový súbor firmvéru (.bin), nastavenia alebo prispôsobenia (.json), pre voliteľné overenie nahrajte súbor (.md5)',
UPLOAD_DROP_TEXT: 'Potiahnúť a pripnúť súbor alebo kliknúť sem', UPLOAD_DROP_TEXT: 'Potiahnúť a pripnúť súbor alebo kliknúť sem',
ERROR: 'Neočakávaná chyba, prosím skúste to znova', ERROR: 'Neočakávaná chyba, prosím skúste to znova',
TIME_SET: 'Nastavený čas', TIME_SET: 'Nastavený čas',

View File

@@ -177,7 +177,7 @@ const sv: Translation = {
STABLE: 'Stable', // TODO translate STABLE: 'Stable', // TODO translate
DEVELOPMENT: 'Utveckling', DEVELOPMENT: 'Utveckling',
RELEASE_NOTES: 'release-logg', RELEASE_NOTES: 'release-logg',
EMS_ESP_VER: 'EMS-ESP Version', EMS_ESP_VER: 'Firmware Version', // TODO translate
UPTIME: 'Systemets Upptid', UPTIME: 'Systemets Upptid',
FREE_MEMORY: 'Ledigt Memory', FREE_MEMORY: 'Ledigt Memory',
PSRAM: 'PSRAM (Storlek / Ledigt)', PSRAM: 'PSRAM (Storlek / Ledigt)',
@@ -186,10 +186,8 @@ const sv: Translation = {
FILESYSTEM: 'Filsystem (Använt / Ledigt)', FILESYSTEM: 'Filsystem (Använt / Ledigt)',
BUFFER_SIZE: 'Max Bufferstorlek', BUFFER_SIZE: 'Max Bufferstorlek',
COMPACT: 'Komprimera', COMPACT: 'Komprimera',
DOWNLOAD_CUSTOMIZATION_TEXT: 'Ladda ner entitetsanpassningar', DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
DOWNLOAD_SCHEDULE_TEXT: 'Download Scheduler Events', // TODO translate UPLOAD_TEXT: 'Upload a new firmware (.bin) file or a backup file (.json)', // TODO translate
DOWNLOAD_SETTINGS_TEXT: 'Ladda ner applikationsinställningar. Var försiktig om du delar dina iställlningar då de innehåller lösenord och annan känslig systeminformation',
UPLOAD_TEXT: 'Ladda upp ett nytt firmware (.bin), inställningar eller anpassningar (.json) nedan',
UPLOAD_DROP_TEXT: 'Släpp fil eller klicka här', UPLOAD_DROP_TEXT: 'Släpp fil eller klicka här',
ERROR: 'Okänt Fel, var god försök igen', ERROR: 'Okänt Fel, var god försök igen',
TIME_SET: 'Ställ in tid', TIME_SET: 'Ställ in tid',
@@ -334,13 +332,13 @@ const sv: Translation = {
ALLVALUES: 'All Values', // TODO translate ALLVALUES: 'All Values', // TODO translate
SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate
WAIT_FIRMWARE: 'Firmware is uploading and installing', // TODO translate WAIT_FIRMWARE: 'Firmware is uploading and installing', // TODO translate
INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate INSTALL_VERSION: 'This will install version {0}. Are you sure?', // TODO translate
SWITCH_DEV: 'switch to the development version', // TODO translate SWITCH_DEV: 'switch to the development version', // TODO translate
UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate
LATEST_VERSION: 'You are using the latest firmware version.', // TODO translate LATEST_VERSION: 'You are using the latest firmware version.', // TODO translate
PLEASE_WAIT: 'Please wait', // TODO translate PLEASE_WAIT: 'Please wait', // TODO translate
RESTARTING_PRE: 'Initializing', // TODO translate RESTARTING_PRE: 'Initializing', // TODO translate
RESTARTING_POST: 'Reloading' // TODO translate RESTARTING_POST: 'Preparing' // TODO translate
}; };
export default sv; export default sv;

View File

@@ -177,19 +177,17 @@ const tr: Translation = {
STABLE: 'Stable', // TODO translate STABLE: 'Stable', // TODO translate
DEVELOPMENT: 'Geliştirme', DEVELOPMENT: 'Geliştirme',
RELEASE_NOTES: 'yayınlanma notları', RELEASE_NOTES: 'yayınlanma notları',
EMS_ESP_VER: 'EMS-ESP Sürümü', EMS_ESP_VER: 'Firmware Sürümü',
UPTIME: 'Sistem Çalışma Süresi', UPTIME: 'Sistem Çalışma Süresi',
FREE_MEMORY: 'Yığın Memory', // TODO translate FREE_MEMORY: 'Yığın Memory',
PSRAM: 'PSRAM (Boyut / Boş)', PSRAM: 'PSRAM (Boyut / Boş)',
FLASH: 'Flash Çipi (Boyut , Hız)', FLASH: 'Flash Çipi (Boyut , Hız)',
APPSIZE: 'Uygulama (Bölme: Kullanılmış / Boş)', APPSIZE: 'Uygulama (Bölme: Kullanılmış / Boş)',
FILESYSTEM: 'Dosya Sistemi (Kullanılmış / Boş)', FILESYSTEM: 'Dosya Sistemi (Kullanılmış / Boş)',
BUFFER_SIZE: 'En fazla bellek boyutu', BUFFER_SIZE: 'En fazla bellek boyutu',
COMPACT: 'Sıkışık', COMPACT: 'Sıkışık',
DOWNLOAD_CUSTOMIZATION_TEXT: 'Varlık özelleştirmelerini indir', DOWNLOAD_SETTINGS_TEXT: 'Create a backup of your configuration and settings', // TODO translate
DOWNLOAD_SCHEDULE_TEXT: 'Download Scheduler Events', // TODO translate UPLOAD_TEXT: 'Upload a new firmware (.bin) file or a backup file (.json)', // TODO translate
DOWNLOAD_SETTINGS_TEXT: 'Uygulama ayarlarını indir. Bu dosya hassas sistem bilgileri ve şifrelerinizi içerdiğinden ayarlarınızı paylaşırken dikkatli olun',
UPLOAD_TEXT: 'Yeni bir bellenim(.bin) dosyası yükleyin, ayarlar ve özelleştirmeler(.json) dosyası aşağıda, sçenekli denetim yüklemesi(.md5) için önce',
UPLOAD_DROP_TEXT: 'Buraya tıklayın yada dosyayı sürükleyip bırakın', UPLOAD_DROP_TEXT: 'Buraya tıklayın yada dosyayı sürükleyip bırakın',
ERROR: 'Beklenemedik hata, lütfen tekrar deneyin.', ERROR: 'Beklenemedik hata, lütfen tekrar deneyin.',
TIME_SET: 'Zaman ayarı', TIME_SET: 'Zaman ayarı',
@@ -334,13 +332,13 @@ const tr: Translation = {
ALLVALUES: 'All Values', // TODO translate ALLVALUES: 'All Values', // TODO translate
SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate SPECIAL_FUNCTIONS: 'Special Functions', // TODO translate
WAIT_FIRMWARE: 'Firmware is uploading and installing', // TODO translate WAIT_FIRMWARE: 'Firmware is uploading and installing', // TODO translate
INSTALL_VERSION: 'This will install vesion {0}. Are you sure?', // TODO translate INSTALL_VERSION: 'This will install version {0}. Are you sure?', // TODO translate
SWITCH_DEV: 'switch to the development version', // TODO translate SWITCH_DEV: 'switch to the development version', // TODO translate
UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate UPGRADE_AVAILABLE: 'There is a firmware upgrade available!', // TODO translate
LATEST_VERSION: 'You are using the latest firmware version.', // TODO translate LATEST_VERSION: 'You are using the latest firmware version.', // TODO translate
PLEASE_WAIT: 'Please wait', // TODO translate PLEASE_WAIT: 'Please wait', // TODO translate
RESTARTING_PRE: 'Initializing', // TODO translate RESTARTING_PRE: 'Initializing', // TODO translate
RESTARTING_POST: 'Reloading' // TODO translate RESTARTING_POST: 'Preparing' // TODO translate
}; };
export default tr; export default tr;

View File

@@ -70,4 +70,5 @@ export interface LogSettings {
level: number; level: number;
max_messages: number; max_messages: number;
compact: boolean; compact: boolean;
psram: boolean;
} }

View File

@@ -287,7 +287,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.7": "@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.7":
version: 7.25.0 version: 7.25.0
resolution: "@babel/runtime@npm:7.25.0" resolution: "@babel/runtime@npm:7.25.0"
dependencies: dependencies:
@@ -1145,10 +1145,10 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@remix-run/router@npm:1.19.1": "@remix-run/router@npm:1.19.2":
version: 1.19.1 version: 1.19.2
resolution: "@remix-run/router@npm:1.19.1" resolution: "@remix-run/router@npm:1.19.2"
checksum: 10c0/9101fc96646e5107b6b0ef248d4c93bd965590c37ac02d35bcc57d1902467db7fc6eeec0a1fb97d0ce5bc96fae58e75239555e44a983239a61badba18e82d3b8 checksum: 10c0/ac7fc813350686705f2c29219e70e1e299d9a8e3b301e9e81f7e84f578c40c6462b590cf0d78863bac40dbc325b68c71ae070f4a1465793d1d1971b619618295
languageName: node languageName: node
linkType: hard linkType: hard
@@ -1595,15 +1595,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/eslint-plugin@npm:8.4.0": "@typescript-eslint/eslint-plugin@npm:8.5.0":
version: 8.4.0 version: 8.5.0
resolution: "@typescript-eslint/eslint-plugin@npm:8.4.0" resolution: "@typescript-eslint/eslint-plugin@npm:8.5.0"
dependencies: dependencies:
"@eslint-community/regexpp": "npm:^4.10.0" "@eslint-community/regexpp": "npm:^4.10.0"
"@typescript-eslint/scope-manager": "npm:8.4.0" "@typescript-eslint/scope-manager": "npm:8.5.0"
"@typescript-eslint/type-utils": "npm:8.4.0" "@typescript-eslint/type-utils": "npm:8.5.0"
"@typescript-eslint/utils": "npm:8.4.0" "@typescript-eslint/utils": "npm:8.5.0"
"@typescript-eslint/visitor-keys": "npm:8.4.0" "@typescript-eslint/visitor-keys": "npm:8.5.0"
graphemer: "npm:^1.4.0" graphemer: "npm:^1.4.0"
ignore: "npm:^5.3.1" ignore: "npm:^5.3.1"
natural-compare: "npm:^1.4.0" natural-compare: "npm:^1.4.0"
@@ -1614,66 +1614,66 @@ __metadata:
peerDependenciesMeta: peerDependenciesMeta:
typescript: typescript:
optional: true optional: true
checksum: 10c0/c75e9bb176e9e0277c9f9c4c006bc2c31ac91984e555de1390a9bbe876e3b6787d59d96015b3f0cd083fd22c814aea4ed4858910d3afdd24d64ab79815da31e5 checksum: 10c0/69ae7067e03d2d8d442e69d668235bdafd63b07229d0be27025eaad8aa468b5af8ac54627021e0e3a060df04ed1c39d1327a0b11469ac72405b52b74a79f402b
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/parser@npm:8.4.0": "@typescript-eslint/parser@npm:8.5.0":
version: 8.4.0 version: 8.5.0
resolution: "@typescript-eslint/parser@npm:8.4.0" resolution: "@typescript-eslint/parser@npm:8.5.0"
dependencies: dependencies:
"@typescript-eslint/scope-manager": "npm:8.4.0" "@typescript-eslint/scope-manager": "npm:8.5.0"
"@typescript-eslint/types": "npm:8.4.0" "@typescript-eslint/types": "npm:8.5.0"
"@typescript-eslint/typescript-estree": "npm:8.4.0" "@typescript-eslint/typescript-estree": "npm:8.5.0"
"@typescript-eslint/visitor-keys": "npm:8.4.0" "@typescript-eslint/visitor-keys": "npm:8.5.0"
debug: "npm:^4.3.4" debug: "npm:^4.3.4"
peerDependencies: peerDependencies:
eslint: ^8.57.0 || ^9.0.0 eslint: ^8.57.0 || ^9.0.0
peerDependenciesMeta: peerDependenciesMeta:
typescript: typescript:
optional: true optional: true
checksum: 10c0/19f3358e5bc4bbad693183eefe1a90ea64be054a934bc2c8a972ff4738b94580b55ad4955af5797db42298628caa59b3ba3f9fd960582b5fc2c836da3a4578a5 checksum: 10c0/509fdd605b86c7d025928f20e1035712c2fc268c34b1af84248ed0b53d699034f19caf98e085c5c758d3025e29939dd12eea427c72cae9e5ea79274364851f0a
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/scope-manager@npm:8.4.0": "@typescript-eslint/scope-manager@npm:8.5.0":
version: 8.4.0 version: 8.5.0
resolution: "@typescript-eslint/scope-manager@npm:8.4.0" resolution: "@typescript-eslint/scope-manager@npm:8.5.0"
dependencies: dependencies:
"@typescript-eslint/types": "npm:8.4.0" "@typescript-eslint/types": "npm:8.5.0"
"@typescript-eslint/visitor-keys": "npm:8.4.0" "@typescript-eslint/visitor-keys": "npm:8.5.0"
checksum: 10c0/95188c663df7db106529c6b93c4c7c61647ed34ab6dd48114e41ddf49140ff606c5501ce2ae451a988ec49b5d3874ea96ff212fc102802327b10affd2ff80a37 checksum: 10c0/868602f9324a6e15fcae017acd3b0832e9f2c8c8cd315667df37c2e7c765cda5fba7c4bede931f32cc04819ba97cf74a5fddb085c6f1c7993f1fb085ba126422
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/type-utils@npm:8.4.0": "@typescript-eslint/type-utils@npm:8.5.0":
version: 8.4.0 version: 8.5.0
resolution: "@typescript-eslint/type-utils@npm:8.4.0" resolution: "@typescript-eslint/type-utils@npm:8.5.0"
dependencies: dependencies:
"@typescript-eslint/typescript-estree": "npm:8.4.0" "@typescript-eslint/typescript-estree": "npm:8.5.0"
"@typescript-eslint/utils": "npm:8.4.0" "@typescript-eslint/utils": "npm:8.5.0"
debug: "npm:^4.3.4" debug: "npm:^4.3.4"
ts-api-utils: "npm:^1.3.0" ts-api-utils: "npm:^1.3.0"
peerDependenciesMeta: peerDependenciesMeta:
typescript: typescript:
optional: true optional: true
checksum: 10c0/ae51100594d9ca61c7577b5aed0bd10c1959725df5c38cd9653eed1fd3dbdfff9146b6e48f3409994b4c8d781b9d95025c36b30f73a5a1b3dbdee6d142cecc87 checksum: 10c0/675d3e41f938d16e9268fd33764a4e16b12a4a9817e61d5e2508a07fe6783c69ce9d05facc61822b5647c71d767929618ed37b8b93f423f7c2ccb62cfeb4343b
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/types@npm:8.4.0": "@typescript-eslint/types@npm:8.5.0":
version: 8.4.0 version: 8.5.0
resolution: "@typescript-eslint/types@npm:8.4.0" resolution: "@typescript-eslint/types@npm:8.5.0"
checksum: 10c0/15e09ced84827c349553530a31822f06ae5bad456c03d561b7d0c64b6ad9b5d7ca795e030bd93e65d5a2cd41bfde36ed08dcd2ff9feaa8b60a67080827f47ecb checksum: 10c0/f0b666b5c001b9779bfd9e4c7d031843d07264429d5bcf5d636f26f96cd5d949a33f5d6a645b8d74b93daf565a468476a6a4935dd7135a200250fb03acbe4988
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/typescript-estree@npm:8.4.0": "@typescript-eslint/typescript-estree@npm:8.5.0":
version: 8.4.0 version: 8.5.0
resolution: "@typescript-eslint/typescript-estree@npm:8.4.0" resolution: "@typescript-eslint/typescript-estree@npm:8.5.0"
dependencies: dependencies:
"@typescript-eslint/types": "npm:8.4.0" "@typescript-eslint/types": "npm:8.5.0"
"@typescript-eslint/visitor-keys": "npm:8.4.0" "@typescript-eslint/visitor-keys": "npm:8.5.0"
debug: "npm:^4.3.4" debug: "npm:^4.3.4"
fast-glob: "npm:^3.3.2" fast-glob: "npm:^3.3.2"
is-glob: "npm:^4.0.3" is-glob: "npm:^4.0.3"
@@ -1683,31 +1683,31 @@ __metadata:
peerDependenciesMeta: peerDependenciesMeta:
typescript: typescript:
optional: true optional: true
checksum: 10c0/170702b024121cff9268f53de8054796b0ce025f9a78d6f2bc850a360e5f3f7032ba3ee9d4b7392726308273a5f3ade5ab31b1788b504b514bc15afc07302b37 checksum: 10c0/f62f03d0c5dc57b2b54dbe1cbd027966f774f241279655f46c64145abb54b765176a0cd40447583ba56ada306181da9a82e39b777c78128e105e4ea98c609350
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/utils@npm:8.4.0": "@typescript-eslint/utils@npm:8.5.0":
version: 8.4.0 version: 8.5.0
resolution: "@typescript-eslint/utils@npm:8.4.0" resolution: "@typescript-eslint/utils@npm:8.5.0"
dependencies: dependencies:
"@eslint-community/eslint-utils": "npm:^4.4.0" "@eslint-community/eslint-utils": "npm:^4.4.0"
"@typescript-eslint/scope-manager": "npm:8.4.0" "@typescript-eslint/scope-manager": "npm:8.5.0"
"@typescript-eslint/types": "npm:8.4.0" "@typescript-eslint/types": "npm:8.5.0"
"@typescript-eslint/typescript-estree": "npm:8.4.0" "@typescript-eslint/typescript-estree": "npm:8.5.0"
peerDependencies: peerDependencies:
eslint: ^8.57.0 || ^9.0.0 eslint: ^8.57.0 || ^9.0.0
checksum: 10c0/8c9c36b3aa23f9bcc28cc4b10f0fa2996f1bc6cdd75135f08c2ef734baa30dbd2a8b92f344b90518e1fd07a486936734789fc7e90b780221a7707dad8e9c9364 checksum: 10c0/0cb0bfdaf0da79d13c0d0379478eb14b5825d235873bc7181e70c4f6297fa1c74431ef730cbc2912fe1814dd8d46c6515ce22b39c57e8f03c337aa152fd49a4e
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/visitor-keys@npm:8.4.0": "@typescript-eslint/visitor-keys@npm:8.5.0":
version: 8.4.0 version: 8.5.0
resolution: "@typescript-eslint/visitor-keys@npm:8.4.0" resolution: "@typescript-eslint/visitor-keys@npm:8.5.0"
dependencies: dependencies:
"@typescript-eslint/types": "npm:8.4.0" "@typescript-eslint/types": "npm:8.5.0"
eslint-visitor-keys: "npm:^3.4.3" eslint-visitor-keys: "npm:^3.4.3"
checksum: 10c0/339199b7fbb9ac83b530d03ab25f6bc5ceb688c9cd0ae460112cd14ee78ca7284a845aef5620cdf70170980123475ec875e85ebf595c60255ba3c0d6fe48c714 checksum: 10c0/8b9e81968ad36e8af18ac17b63c4e0764612451ca085676c939b723549052243f63577d2706bc2da48174f11bf47587ab47e6e0b7c5b28d9f3c1ef7b9aad322d
languageName: node languageName: node
linkType: hard linkType: hard
@@ -1734,7 +1734,7 @@ __metadata:
"@types/react-router-dom": "npm:^5.3.3" "@types/react-router-dom": "npm:^5.3.3"
alova: "npm:3.0.16" alova: "npm:3.0.16"
async-validator: "npm:^4.2.5" async-validator: "npm:^4.2.5"
concurrently: "npm:^8.2.2" concurrently: "npm:^9.0.0"
eslint: "npm:^9.10.0" eslint: "npm:^9.10.0"
eslint-config-prettier: "npm:^9.1.0" eslint-config-prettier: "npm:^9.1.0"
formidable: "npm:^3.5.1" formidable: "npm:^3.5.1"
@@ -1745,14 +1745,14 @@ __metadata:
react: "npm:^18.3.1" react: "npm:^18.3.1"
react-dom: "npm:^18.3.1" react-dom: "npm:^18.3.1"
react-icons: "npm:^5.3.0" react-icons: "npm:^5.3.0"
react-router-dom: "npm:^6.26.1" react-router-dom: "npm:^6.26.2"
react-toastify: "npm:^10.0.5" react-toastify: "npm:^10.0.5"
rollup-plugin-visualizer: "npm:^5.12.0" rollup-plugin-visualizer: "npm:^5.12.0"
terser: "npm:^5.31.6" terser: "npm:^5.32.0"
typesafe-i18n: "npm:^5.26.2" typesafe-i18n: "npm:^5.26.2"
typescript: "npm:^5.5.4" typescript: "npm:^5.6.2"
typescript-eslint: "npm:8.4.0" typescript-eslint: "npm:8.5.0"
vite: "npm:^5.4.3" vite: "npm:^5.4.4"
vite-plugin-imagemin: "npm:^0.6.1" vite-plugin-imagemin: "npm:^0.6.1"
vite-tsconfig-paths: "npm:^5.0.1" vite-tsconfig-paths: "npm:^5.0.1"
languageName: unknown languageName: unknown
@@ -2340,23 +2340,21 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"concurrently@npm:^8.2.2": "concurrently@npm:^9.0.0":
version: 8.2.2 version: 9.0.0
resolution: "concurrently@npm:8.2.2" resolution: "concurrently@npm:9.0.0"
dependencies: dependencies:
chalk: "npm:^4.1.2" chalk: "npm:^4.1.2"
date-fns: "npm:^2.30.0"
lodash: "npm:^4.17.21" lodash: "npm:^4.17.21"
rxjs: "npm:^7.8.1" rxjs: "npm:^7.8.1"
shell-quote: "npm:^1.8.1" shell-quote: "npm:^1.8.1"
spawn-command: "npm:0.0.2"
supports-color: "npm:^8.1.1" supports-color: "npm:^8.1.1"
tree-kill: "npm:^1.2.2" tree-kill: "npm:^1.2.2"
yargs: "npm:^17.7.2" yargs: "npm:^17.7.2"
bin: bin:
conc: dist/bin/concurrently.js conc: dist/bin/concurrently.js
concurrently: dist/bin/concurrently.js concurrently: dist/bin/concurrently.js
checksum: 10c0/0e9683196fe9c071d944345d21d8f34aa6c0cc50c0dd897e95619f2f1c9eb4871dca851b2569da17888235b7335b4c821ca19deed35bebcd9a131ee5d247f34c checksum: 10c0/65251009f4540c25eda0d5b2f367ba8755eac83db2ce562802132160e9241c5cd755228b18c330ea29ccd5b0a033302da8a670d724e89fe462c26253e3046f2e
languageName: node languageName: node
linkType: hard linkType: hard
@@ -2535,15 +2533,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"date-fns@npm:^2.30.0":
version: 2.30.0
resolution: "date-fns@npm:2.30.0"
dependencies:
"@babel/runtime": "npm:^7.21.0"
checksum: 10c0/e4b521fbf22bc8c3db332bbfb7b094fd3e7627de0259a9d17c7551e2d2702608a7307a449206065916538e384f37b181565447ce2637ae09828427aed9cb5581
languageName: node
linkType: hard
"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4": "debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4":
version: 4.3.6 version: 4.3.6
resolution: "debug@npm:4.3.6" resolution: "debug@npm:4.3.6"
@@ -5831,27 +5820,27 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"react-router-dom@npm:^6.26.1": "react-router-dom@npm:^6.26.2":
version: 6.26.1 version: 6.26.2
resolution: "react-router-dom@npm:6.26.1" resolution: "react-router-dom@npm:6.26.2"
dependencies: dependencies:
"@remix-run/router": "npm:1.19.1" "@remix-run/router": "npm:1.19.2"
react-router: "npm:6.26.1" react-router: "npm:6.26.2"
peerDependencies: peerDependencies:
react: ">=16.8" react: ">=16.8"
react-dom: ">=16.8" react-dom: ">=16.8"
checksum: 10c0/9d9d8ed54d1c95497c6fa35a6ab46992efeccf1cfc6f0f6089c6c9b040af3eae09568fbb80c690bae08051a955d92d7aa3a0e730f626eb69285114993d31d430 checksum: 10c0/7515128a98eef0a6b2bf354ef9dfefad03556a06be00fa9220eda6526aaada8a42f294911083473d7ced6d7128c3088bd193218bbb3d62593f9f4f7053781c23
languageName: node languageName: node
linkType: hard linkType: hard
"react-router@npm:6.26.1": "react-router@npm:6.26.2":
version: 6.26.1 version: 6.26.2
resolution: "react-router@npm:6.26.1" resolution: "react-router@npm:6.26.2"
dependencies: dependencies:
"@remix-run/router": "npm:1.19.1" "@remix-run/router": "npm:1.19.2"
peerDependencies: peerDependencies:
react: ">=16.8" react: ">=16.8"
checksum: 10c0/463078e740462b42bb5ba8004448f33fc9e63778f432a4ed55c57b93c5b519e25fb17913ee8435b0fda33c6b9f75df8ef6fcb2c3a4f8db84fb546d202e29aa51 checksum: 10c0/0d15a39b419c99fb5ccad76388bfc4ee2b01323b3b1b694595a9f9ea28e1fbeea25486b5398f5d3d93922f5c6a9aa751b6bb27419488d85279f6ca5ff9e0a6bb
languageName: node languageName: node
linkType: hard linkType: hard
@@ -6395,13 +6384,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"spawn-command@npm:0.0.2":
version: 0.0.2
resolution: "spawn-command@npm:0.0.2"
checksum: 10c0/b22f2d71239e6e628a400831861ba747750bbb40c0a53323754cf7b84330b73d81e40ff1f9055e6d1971818679510208a9302e13d9ff3b32feb67e74d7a1b3ef
languageName: node
linkType: hard
"spdx-correct@npm:^3.0.0": "spdx-correct@npm:^3.0.0":
version: 3.2.0 version: 3.2.0
resolution: "spdx-correct@npm:3.2.0" resolution: "spdx-correct@npm:3.2.0"
@@ -6719,9 +6701,9 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"terser@npm:^5.31.6": "terser@npm:^5.32.0":
version: 5.31.6 version: 5.32.0
resolution: "terser@npm:5.31.6" resolution: "terser@npm:5.32.0"
dependencies: dependencies:
"@jridgewell/source-map": "npm:^0.3.3" "@jridgewell/source-map": "npm:^0.3.3"
acorn: "npm:^8.8.2" acorn: "npm:^8.8.2"
@@ -6729,7 +6711,7 @@ __metadata:
source-map-support: "npm:~0.5.20" source-map-support: "npm:~0.5.20"
bin: bin:
terser: bin/terser terser: bin/terser
checksum: 10c0/b17d02b65a52a5041430572b3c514475820f5e7590fa93773c0f5b4be601ccf3f6d745bf5a79f3ee58187cf85edf61c24ddf4345783839fccb44c9c8fa9b427e checksum: 10c0/94daae4881258eb7d09abd46378e23d11ee46caa507b2fb26c5595c7e490914be734e0de38c50041dc38fae5fca24de11badf042dfbbfc1d336ed117335c420a
languageName: node languageName: node
linkType: hard linkType: hard
@@ -6868,37 +6850,37 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"typescript-eslint@npm:8.4.0": "typescript-eslint@npm:8.5.0":
version: 8.4.0 version: 8.5.0
resolution: "typescript-eslint@npm:8.4.0" resolution: "typescript-eslint@npm:8.5.0"
dependencies: dependencies:
"@typescript-eslint/eslint-plugin": "npm:8.4.0" "@typescript-eslint/eslint-plugin": "npm:8.5.0"
"@typescript-eslint/parser": "npm:8.4.0" "@typescript-eslint/parser": "npm:8.5.0"
"@typescript-eslint/utils": "npm:8.4.0" "@typescript-eslint/utils": "npm:8.5.0"
peerDependenciesMeta: peerDependenciesMeta:
typescript: typescript:
optional: true optional: true
checksum: 10c0/266ef73fdc1f7fa19228b8653d61ad143261ccd35f7d5d647092ed0e1512de2d4e3d1b9e1f2520658708cc0c1d7925c4ec97f23440c180a3bf1716e81d65123f checksum: 10c0/dd92e8f5fb50bb05810a1a37a4bbb6f60761295b121f6118bc027686ebc1b3ba9e4248ab5223ed4753e1320ef6329dd2e53e8160fa4463264277f307fefefd62
languageName: node languageName: node
linkType: hard linkType: hard
"typescript@npm:^5.5.4": "typescript@npm:^5.6.2":
version: 5.5.4 version: 5.6.2
resolution: "typescript@npm:5.5.4" resolution: "typescript@npm:5.6.2"
bin: bin:
tsc: bin/tsc tsc: bin/tsc
tsserver: bin/tsserver tsserver: bin/tsserver
checksum: 10c0/422be60f89e661eab29ac488c974b6cc0a660fb2228003b297c3d10c32c90f3bcffc1009b43876a082515a3c376b1eefcce823d6e78982e6878408b9a923199c checksum: 10c0/3ed8297a8c7c56b7fec282532503d1ac795239d06e7c4966b42d4330c6cf433a170b53bcf93a130a7f14ccc5235de5560df4f1045eb7f3550b46ebed16d3c5e5
languageName: node languageName: node
linkType: hard linkType: hard
"typescript@patch:typescript@npm%3A^5.5.4#optional!builtin<compat/typescript>": "typescript@patch:typescript@npm%3A^5.6.2#optional!builtin<compat/typescript>":
version: 5.5.4 version: 5.6.2
resolution: "typescript@patch:typescript@npm%3A5.5.4#optional!builtin<compat/typescript>::version=5.5.4&hash=379a07" resolution: "typescript@patch:typescript@npm%3A5.6.2#optional!builtin<compat/typescript>::version=5.6.2&hash=74658d"
bin: bin:
tsc: bin/tsc tsc: bin/tsc
tsserver: bin/tsserver tsserver: bin/tsserver
checksum: 10c0/73409d7b9196a5a1217b3aaad929bf76294d3ce7d6e9766dd880ece296ee91cf7d7db6b16c6c6c630ee5096eccde726c0ef17c7dfa52b01a243e57ae1f09ef07 checksum: 10c0/e6c1662e4852e22fe4bbdca471dca3e3edc74f6f1df043135c44a18a7902037023ccb0abdfb754595ca9028df8920f2f8492c00fc3cbb4309079aae8b7de71cd
languageName: node languageName: node
linkType: hard linkType: hard
@@ -7074,9 +7056,9 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"vite@npm:^5.4.3": "vite@npm:^5.4.4":
version: 5.4.3 version: 5.4.4
resolution: "vite@npm:5.4.3" resolution: "vite@npm:5.4.4"
dependencies: dependencies:
esbuild: "npm:^0.21.3" esbuild: "npm:^0.21.3"
fsevents: "npm:~2.3.3" fsevents: "npm:~2.3.3"
@@ -7113,7 +7095,7 @@ __metadata:
optional: true optional: true
bin: bin:
vite: bin/vite.js vite: bin/vite.js
checksum: 10c0/7afe601bcba82f81980c718fc171ba8f0c45e3bffaeb7ef831b64b84e396f963c3c87818b74da4c8e817d1bce1c179f1efae3bcb14d2e94b4eb635071722c8f2 checksum: 10c0/2752e7dd5584ea7cc057742e8f5cbf2f2bd3a2bceb8794fbd3d52f1e88d362b5ac7f1c70be7a3d01b3d768320c8a8ad0df287fd72f253bf040423c36c67a3e89
languageName: node languageName: node
linkType: hard linkType: hard

View File

@@ -7,210 +7,213 @@
// #undef LOCAL_LOG_LEVEL // #undef LOCAL_LOG_LEVEL
#include "Logging.h" #include "Logging.h"
ModbusClientTCPasync::ModbusClientTCPasync(IPAddress address, uint16_t port, uint16_t queueLimit) : ModbusClientTCPasync::ModbusClientTCPasync(IPAddress address, uint16_t port, uint16_t queueLimit)
ModbusClient(), : ModbusClient()
txQueue(), , txQueue()
rxQueue(), , rxQueue()
MTA_client(), , MTA_client()
MTA_timeout(DEFAULTTIMEOUT), , MTA_timeout(DEFAULTTIMEOUT)
MTA_idleTimeout(DEFAULTIDLETIME), , MTA_idleTimeout(DEFAULTIDLETIME)
MTA_qLimit(queueLimit), , MTA_qLimit(queueLimit)
MTA_maxInflightRequests(queueLimit), , MTA_maxInflightRequests(queueLimit)
MTA_lastActivity(0), , MTA_lastActivity(0)
MTA_state(DISCONNECTED), , MTA_state(DISCONNECTED)
MTA_host(address), , MTA_host(address)
MTA_port(port) , MTA_port(port) {
{ // attach all handlers on async tcp events
// attach all handlers on async tcp events MTA_client.onConnect([](void * i, AsyncClient * c) { (static_cast<ModbusClientTCPasync *>(i))->onConnected(); }, this);
MTA_client.onConnect([](void* i, AsyncClient* c) { (static_cast<ModbusClientTCPasync*>(i))->onConnected(); }, this); MTA_client.onDisconnect([](void * i, AsyncClient * c) { (static_cast<ModbusClientTCPasync *>(i))->onDisconnected(); }, this);
MTA_client.onDisconnect([](void* i, AsyncClient* c) { (static_cast<ModbusClientTCPasync*>(i))->onDisconnected(); }, this); MTA_client.onError([](void * i, AsyncClient * c, int8_t error) { (static_cast<ModbusClientTCPasync *>(i))->onACError(c, error); }, this);
MTA_client.onError([](void* i, AsyncClient* c, int8_t error) { (static_cast<ModbusClientTCPasync*>(i))->onACError(c, error); }, this); // MTA_client.onTimeout([](void* i, AsyncClient* c, uint32_t time) { (static_cast<ModbusClientTCPasync*>(i))->onTimeout(time); }, this);
// MTA_client.onTimeout([](void* i, AsyncClient* c, uint32_t time) { (static_cast<ModbusClientTCPasync*>(i))->onTimeout(time); }, this); // MTA_client.onAck([](void* i, AsyncClient* c, size_t len, uint32_t time) { (static_cast<ModbusClientTCPasync*>(i))->onAck(len, time); }, this);
// MTA_client.onAck([](void* i, AsyncClient* c, size_t len, uint32_t time) { (static_cast<ModbusClientTCPasync*>(i))->onAck(len, time); }, this); MTA_client.onData([](void * i,
MTA_client.onData([](void* i, AsyncClient* c, void* data, size_t len) { (static_cast<ModbusClientTCPasync*>(i))->onPacket(static_cast<uint8_t*>(data), len); }, this); AsyncClient * c,
MTA_client.onPoll([](void* i, AsyncClient* c) { (static_cast<ModbusClientTCPasync*>(i))->onPoll(); }, this); void * data,
size_t len) { (static_cast<ModbusClientTCPasync *>(i))->onPacket(static_cast<uint8_t *>(data), len); },
this);
MTA_client.onPoll([](void * i, AsyncClient * c) { (static_cast<ModbusClientTCPasync *>(i))->onPoll(); }, this);
// disable nagle algorithm ref Modbus spec // disable nagle algorithm ref Modbus spec
MTA_client.setNoDelay(true); MTA_client.setNoDelay(true);
} }
// Destructor: clean up queue, task etc. // Destructor: clean up queue, task etc.
ModbusClientTCPasync::~ModbusClientTCPasync() { ModbusClientTCPasync::~ModbusClientTCPasync() {
// Clean up queue // Clean up queue
{ {
// Safely lock access // Safely lock access
LOCK_GUARD(lock1, qLock); LOCK_GUARD(lock1, qLock);
LOCK_GUARD(lock2, sLock); LOCK_GUARD(lock2, sLock);
// Delete all elements from queues // Delete all elements from queues
while (!txQueue.empty()) { while (!txQueue.empty()) {
delete txQueue.front(); delete txQueue.front();
txQueue.pop_front(); txQueue.pop_front();
}
for (auto it = rxQueue.cbegin(); it != rxQueue.cend(); /* no increment */) {
delete it->second;
it = rxQueue.erase(it);
}
} }
for (auto it = rxQueue.cbegin(); it != rxQueue.cend();/* no increment */) { // force close client
delete it->second; MTA_client.close(true);
it = rxQueue.erase(it);
}
}
// force close client
MTA_client.close(true);
} }
// optionally manually connect to modbus server. Otherwise connection will be made upon first request // optionally manually connect to modbus server. Otherwise connection will be made upon first request
void ModbusClientTCPasync::connect() { void ModbusClientTCPasync::connect() {
LOG_D("connecting\n"); LOG_D("connecting\n");
LOCK_GUARD(lock1, sLock); LOCK_GUARD(lock1, sLock);
// only connect if disconnected // only connect if disconnected
if (MTA_state == DISCONNECTED) { if (MTA_state == DISCONNECTED) {
MTA_state = CONNECTING; MTA_state = CONNECTING;
MTA_client.connect(MTA_host, MTA_port); MTA_client.connect(MTA_host, MTA_port);
} }
} }
// connect to another modbus server. // connect to another modbus server.
void ModbusClientTCPasync::connect(IPAddress host, uint16_t port) { void ModbusClientTCPasync::connect(IPAddress host, uint16_t port) {
// First disconnect, if connected // First disconnect, if connected
disconnect(true); disconnect(true);
// Set new host and port // Set new host and port
MTA_host = host; MTA_host = host;
MTA_port = port; MTA_port = port;
connect(); connect();
} }
// manually disconnect from modbus server. Connection will also auto close after idle time // manually disconnect from modbus server. Connection will also auto close after idle time
void ModbusClientTCPasync::disconnect(bool force) { void ModbusClientTCPasync::disconnect(bool force) {
LOG_D("disconnecting\n"); LOG_D("disconnecting\n");
MTA_client.close(force); MTA_client.close(force);
} }
// Set timeout value // Set timeout value
void ModbusClientTCPasync::setTimeout(uint32_t timeout) { void ModbusClientTCPasync::setTimeout(uint32_t timeout) {
MTA_timeout = timeout; MTA_timeout = timeout;
} }
// Set idle timeout value (time before connection auto closes after being idle) // Set idle timeout value (time before connection auto closes after being idle)
void ModbusClientTCPasync::setIdleTimeout(uint32_t timeout) { void ModbusClientTCPasync::setIdleTimeout(uint32_t timeout) {
MTA_idleTimeout = timeout; MTA_idleTimeout = timeout;
} }
void ModbusClientTCPasync::setMaxInflightRequests(uint32_t maxInflightRequests) { void ModbusClientTCPasync::setMaxInflightRequests(uint32_t maxInflightRequests) {
MTA_maxInflightRequests = maxInflightRequests; MTA_maxInflightRequests = maxInflightRequests;
} }
// Remove all pending request from queue // Remove all pending request from queue
void ModbusClientTCPasync::clearQueue() void ModbusClientTCPasync::clearQueue() {
{ LOCK_GUARD(lock1, qLock);
LOCK_GUARD(lock1, qLock); LOCK_GUARD(lock2, sLock);
LOCK_GUARD(lock2, sLock); // Delete all elements from queues
// Delete all elements from queues while (!txQueue.empty()) {
while (!txQueue.empty()) { delete txQueue.front();
delete txQueue.front(); txQueue.pop_front();
txQueue.pop_front(); }
}
} }
// Base addRequest for preformatted ModbusMessage and last set target // Base addRequest for preformatted ModbusMessage and last set target
Error ModbusClientTCPasync::addRequestM(ModbusMessage msg, uint32_t token) { Error ModbusClientTCPasync::addRequestM(ModbusMessage msg, uint32_t token) {
Error rc = SUCCESS; // Return value Error rc = SUCCESS; // Return value
// Add it to the queue, if valid // Add it to the queue, if valid
if (msg) { if (msg) {
// Queue add successful? // Queue add successful?
if (!addToQueue(token, msg)) { if (!addToQueue(token, msg)) {
// No. Return error after deleting the allocated request. // No. Return error after deleting the allocated request.
rc = REQUEST_QUEUE_FULL; rc = REQUEST_QUEUE_FULL;
}
} }
}
LOG_D("Add TCP request result: %02X\n", rc); LOG_D("Add TCP request result: %02X\n", rc);
return rc; return rc;
} }
// Base syncRequest follows the same pattern // Base syncRequest follows the same pattern
ModbusMessage ModbusClientTCPasync::syncRequestM(ModbusMessage msg, uint32_t token) { ModbusMessage ModbusClientTCPasync::syncRequestM(ModbusMessage msg, uint32_t token) {
ModbusMessage response; ModbusMessage response;
if (msg) { if (msg) {
// Queue add successful? // Queue add successful?
if (!addToQueue(token, msg, true)) { if (!addToQueue(token, msg, true)) {
// No. Return error after deleting the allocated request. // No. Return error after deleting the allocated request.
response.setError(msg.getServerID(), msg.getFunctionCode(), REQUEST_QUEUE_FULL); response.setError(msg.getServerID(), msg.getFunctionCode(), REQUEST_QUEUE_FULL);
} else {
// Request is queued - wait for the result.
response = waitSync(msg.getServerID(), msg.getFunctionCode(), token);
}
} else { } else {
// Request is queued - wait for the result. response.setError(msg.getServerID(), msg.getFunctionCode(), EMPTY_MESSAGE);
response = waitSync(msg.getServerID(), msg.getFunctionCode(), token);
} }
} else { return response;
response.setError(msg.getServerID(), msg.getFunctionCode(), EMPTY_MESSAGE);
}
return response;
} }
// addToQueue: send freshly created request to queue // addToQueue: send freshly created request to queue
bool ModbusClientTCPasync::addToQueue(int32_t token, ModbusMessage request, bool syncReq) { bool ModbusClientTCPasync::addToQueue(int32_t token, ModbusMessage request, bool syncReq) {
// Did we get one? // Did we get one?
if (request) { if (request) {
LOCK_GUARD(lock1, qLock); LOCK_GUARD(lock1, qLock);
if (txQueue.size() + rxQueue.size() < MTA_qLimit) { if (txQueue.size() + rxQueue.size() < MTA_qLimit) {
HEXDUMP_V("Enqueue", request.data(), request.size()); HEXDUMP_V("Enqueue", request.data(), request.size());
RequestEntry *re = new RequestEntry(token, request, syncReq); RequestEntry * re = new RequestEntry(token, request, syncReq);
if (!re) return false; //TODO: proper error returning in case allocation fails if (!re)
// inject proper transactionID return false; // TODO proper error returning in case allocation fails
re->head.transactionID = messageCount++; // inject proper transactionID
re->head.len = request.size(); re->head.transactionID = messageCount++;
// if we're already connected, try to send and push to rxQueue re->head.len = request.size();
// or else push to txQueue and (re)connect // if we're already connected, try to send and push to rxQueue
if (MTA_state == CONNECTED && send(re)) { // or else push to txQueue and (re)connect
re->sentTime = millis(); if (MTA_state == CONNECTED && send(re)) {
rxQueue[re->head.transactionID] = re; re->sentTime = millis();
} else { rxQueue[re->head.transactionID] = re;
txQueue.push_back(re); } else {
if (MTA_state == DISCONNECTED) { txQueue.push_back(re);
connect(); if (MTA_state == DISCONNECTED) {
connect();
}
}
return true;
} }
} LOG_E("queue is full\n");
return true;
} }
LOG_E("queue is full\n"); return false;
}
return false;
} }
void ModbusClientTCPasync::onConnected() { void ModbusClientTCPasync::onConnected() {
LOG_D("connected\n"); LOG_D("connected\n");
LOCK_GUARD(lock1, sLock); LOCK_GUARD(lock1, sLock);
MTA_state = CONNECTED; MTA_state = CONNECTED;
MTA_lastActivity = millis(); MTA_lastActivity = millis();
// from now on onPoll will be called every 500 msec // from now on onPoll will be called every 500 msec
} }
void ModbusClientTCPasync::onDisconnected() { void ModbusClientTCPasync::onDisconnected() {
LOG_D("disconnected\n"); LOG_D("disconnected\n");
LOCK_GUARD(lock1, sLock); LOCK_GUARD(lock1, sLock);
MTA_state = DISCONNECTED; MTA_state = DISCONNECTED;
// empty queue on disconnect, calling errorcode on every waiting request // empty queue on disconnect, calling errorcode on every waiting request
LOCK_GUARD(lock2, qLock); LOCK_GUARD(lock2, qLock);
while (!txQueue.empty()) { while (!txQueue.empty()) {
RequestEntry* r = txQueue.front(); RequestEntry * r = txQueue.front();
if (onError) { if (onError) {
onError(IP_CONNECTION_FAILED, r->token); onError(IP_CONNECTION_FAILED, r->token);
}
delete r;
txQueue.pop_front();
} }
delete r; while (!rxQueue.empty()) {
txQueue.pop_front(); RequestEntry * r = rxQueue.begin()->second;
} if (onError) {
while (!rxQueue.empty()) { onError(IP_CONNECTION_FAILED, r->token);
RequestEntry *r = rxQueue.begin()->second; }
if (onError) { delete r;
onError(IP_CONNECTION_FAILED, r->token); rxQueue.erase(rxQueue.begin());
} }
delete r;
rxQueue.erase(rxQueue.begin());
}
} }
void ModbusClientTCPasync::onACError(AsyncClient* c, int8_t error) { void ModbusClientTCPasync::onACError(AsyncClient * c, int8_t error) {
// onDisconnect will alse be called, so nothing to do here // onDisconnect will alse be called, so nothing to do here
LOG_W("TCP error: %s\n", c->errorToString(error)); LOG_W("TCP error: %s\n", c->errorToString(error));
} }
/* /*
@@ -222,180 +225,178 @@ void onAck(size_t len, uint32_t time) {
// assuming we don't need this // assuming we don't need this
} }
*/ */
void ModbusClientTCPasync::onPacket(uint8_t* data, size_t length) { void ModbusClientTCPasync::onPacket(uint8_t * data, size_t length) {
LOG_D("packet received (len:%d)\n", length); LOG_D("packet received (len:%d)\n", length);
// reset idle timeout // reset idle timeout
MTA_lastActivity = millis(); MTA_lastActivity = millis();
if (length) { if (length) {
LOG_D("parsing (len:%d)\n", length + 1); LOG_D("parsing (len:%d)\n", length + 1);
}
while (length > 0) {
RequestEntry* request = nullptr;
ModbusMessage* response = nullptr;
uint16_t transactionID = 0;
uint16_t protocolID = 0;
uint16_t messageLength = 0;
bool isOkay = false;
// 1. Check for valid modbus message
// MBAP header is 6 bytes, we can't do anything with less
// total message should fit MBAP plus remaining bytes (in data[4], data[5])
if (length > 6) {
transactionID = (data[0] << 8) | data[1];
protocolID = (data[2] << 8) | data[3];
messageLength = (data[4] << 8) | data[5];
if (protocolID == 0 &&
length >= (uint32_t)messageLength + 6 &&
messageLength < 256) {
response = new ModbusMessage(messageLength);
response->add(&data[6], messageLength);
LOG_D("packet validated (len:%d)\n", messageLength);
// on next iteration: adjust remaining length and pointer to data
length -= 6 + messageLength;
data += 6 + messageLength;
isOkay = true;
}
} }
while (length > 0) {
RequestEntry * request = nullptr;
ModbusMessage * response = nullptr;
uint16_t transactionID = 0;
uint16_t protocolID = 0;
uint16_t messageLength = 0;
bool isOkay = false;
if (!isOkay) { // 1. Check for valid modbus message
// invalid packet, abort function
LOG_W("packet invalid\n");
return;
} else {
// 2. we got a valid response, match with a request
LOCK_GUARD(lock1, qLock);
auto i = rxQueue.find(transactionID);
if (i != rxQueue.end()) {
// found it, handle it and stop iterating
request = i->second;
i = rxQueue.erase(i);
LOG_D("matched request\n");
} else {
// TCP packet did not yield valid modbus response, abort function
LOG_W("no matching request found\n");
return;
}
}
// 3. we have a valid request and a valid response, call appropriate callback // MBAP header is 6 bytes, we can't do anything with less
if (request) { // total message should fit MBAP plus remaining bytes (in data[4], data[5])
// compare request with response if (length > 6) {
Error error = SUCCESS; transactionID = (data[0] << 8) | data[1];
if (request->msg.getFunctionCode() != (response->getFunctionCode() & 0x7F)) { protocolID = (data[2] << 8) | data[3];
error = FC_MISMATCH; messageLength = (data[4] << 8) | data[5];
} else if (request->msg.getServerID() != response->getServerID()) { if (protocolID == 0 && length >= (uint32_t)messageLength + 6 && messageLength < 256) {
error = SERVER_ID_MISMATCH; response = new ModbusMessage(messageLength);
} else { response->add(&data[6], messageLength);
error = response->getError(); LOG_D("packet validated (len:%d)\n", messageLength);
}
if (error != SUCCESS) { // on next iteration: adjust remaining length and pointer to data
LOCK_GUARD(errorCntLock, countAccessM); length -= 6 + messageLength;
errorCount++; data += 6 + messageLength;
} isOkay = true;
}
if (request->isSyncRequest) {
{
LOCK_GUARD(sL ,syncRespM);
syncResponse[request->token] = *response;
} }
} else if (onResponse) {
onResponse(*response, request->token); if (!isOkay) {
} else { // invalid packet, abort function
if (error == SUCCESS) { LOG_W("packet invalid\n");
if (onData) { return;
onData(*response, request->token);
}
} else { } else {
if (onError) { // 2. we got a valid response, match with a request
onError(response->getError(), request->token); LOCK_GUARD(lock1, qLock);
} auto i = rxQueue.find(transactionID);
if (i != rxQueue.end()) {
// found it, handle it and stop iterating
request = i->second;
i = rxQueue.erase(i);
LOG_D("matched request\n");
} else {
// TCP packet did not yield valid modbus response, abort function
LOG_W("no matching request found\n");
return;
}
} }
}
delete request;
}
delete response;
} // end processing of incoming data // 3. we have a valid request and a valid response, call appropriate callback
if (request) {
// compare request with response
Error error = SUCCESS;
if (request->msg.getFunctionCode() != (response->getFunctionCode() & 0x7F)) {
error = FC_MISMATCH;
} else if (request->msg.getServerID() != response->getServerID()) {
error = SERVER_ID_MISMATCH;
} else {
error = response->getError();
}
// check if we have to send the next request if (error != SUCCESS) {
LOCK_GUARD(lock1, qLock); LOCK_GUARD(errorCntLock, countAccessM);
handleSendingQueue(); errorCount++;
}
if (request->isSyncRequest) {
{
LOCK_GUARD(sL, syncRespM);
syncResponse[request->token] = *response;
}
} else if (onResponse) {
onResponse(*response, request->token);
} else {
if (error == SUCCESS) {
if (onData) {
onData(*response, request->token);
}
} else {
if (onError) {
onError(response->getError(), request->token);
}
}
}
delete request;
}
delete response;
} // end processing of incoming data
// check if we have to send the next request
LOCK_GUARD(lock1, qLock);
handleSendingQueue();
} }
void ModbusClientTCPasync::onPoll() { void ModbusClientTCPasync::onPoll() {
{ {
LOCK_GUARD(lock1, qLock); LOCK_GUARD(lock1, qLock);
// try to send whatever is waiting // try to send whatever is waiting
handleSendingQueue(); handleSendingQueue();
// next check if timeout has struck for oldest request // next check if timeout has struck for oldest request
if (!rxQueue.empty()) { if (!rxQueue.empty()) {
RequestEntry* request = rxQueue.begin()->second; RequestEntry * request = rxQueue.begin()->second;
if (millis() - request->sentTime > MTA_timeout) { if (millis() - request->sentTime > MTA_timeout) {
LOG_D("request timeouts (now:%lu-sent:%u)\n", millis(), request->sentTime); LOG_D("request timeouts (now:%lu-sent:%u)\n", millis(), request->sentTime);
// oldest element timeouts, call onError and clean up // oldest element timeouts, call onError and clean up
if (onError) { if (onError) {
// Handle timeout error // Handle timeout error
onError(TIMEOUT, request->token); onError(TIMEOUT, request->token);
} }
delete request; delete request;
rxQueue.erase(rxQueue.begin()); rxQueue.erase(rxQueue.begin());
}
}
} // end lockguard scope
// if nothing happened during idle timeout, gracefully close connection
if (millis() - MTA_lastActivity > MTA_idleTimeout) {
disconnect();
} }
}
} // end lockguard scope
// if nothing happened during idle timeout, gracefully close connection
if (millis() - MTA_lastActivity > MTA_idleTimeout) {
disconnect();
}
} }
void ModbusClientTCPasync::handleSendingQueue() { void ModbusClientTCPasync::handleSendingQueue() {
// ATTENTION: This method does not have a lock guard. // ATTENTION: This method does not have a lock guard.
// Calling sites must assure shared resources are protected // Calling sites must assure shared resources are protected
// by mutex. // by mutex.
// try to send everything we have waiting // try to send everything we have waiting
std::list<RequestEntry*>::iterator it = txQueue.begin(); std::list<RequestEntry *>::iterator it = txQueue.begin();
while (it != txQueue.end()) { while (it != txQueue.end()) {
// get the actual element // get the actual element
if (send(*it)) { if (send(*it)) {
// after sending, update timeout value, add to other queue and remove from this queue // after sending, update timeout value, add to other queue and remove from this queue
(*it)->sentTime = millis(); (*it)->sentTime = millis();
rxQueue[(*it)->head.transactionID] = (*it); // push request to other queue rxQueue[(*it)->head.transactionID] = (*it); // push request to other queue
it = txQueue.erase(it); // remove from toSend queue and point i to next request it = txQueue.erase(it); // remove from toSend queue and point i to next request
} else { } else {
// sending didn't succeed, try next request // sending didn't succeed, try next request
++it; ++it;
}
} }
}
} }
bool ModbusClientTCPasync::send(RequestEntry* re) { bool ModbusClientTCPasync::send(RequestEntry * re) {
// ATTENTION: This method does not have a lock guard. // ATTENTION: This method does not have a lock guard.
// Calling sites must assure shared resources are protected // Calling sites must assure shared resources are protected
// by mutex. // by mutex.
if (rxQueue.size() >= MTA_maxInflightRequests) { if (rxQueue.size() >= MTA_maxInflightRequests) {
return false;
}
// check if TCP client is able to send
if (MTA_client.space() > ((uint32_t)re->msg.size() + 6)) {
// Write TCP header first
MTA_client.add(reinterpret_cast<const char *>((const uint8_t *)(re->head)), 6, ASYNC_WRITE_FLAG_COPY);
// Request comes next
MTA_client.add(reinterpret_cast<const char *>(re->msg.data()), re->msg.size(), ASYNC_WRITE_FLAG_COPY);
// done
MTA_client.send();
LOG_D("request sent (msgid:%d)\n", re->head.transactionID);
return true;
}
return false; return false;
}
// check if TCP client is able to send
if (MTA_client.space() > ((uint32_t)re->msg.size() + 6)) {
// Write TCP header first
MTA_client.add(reinterpret_cast<const char *>((const uint8_t *)(re->head)), 6, ASYNC_WRITE_FLAG_COPY);
// Request comes next
MTA_client.add(reinterpret_cast<const char*>(re->msg.data()), re->msg.size(), ASYNC_WRITE_FLAG_COPY);
// done
MTA_client.send();
LOG_D("request sent (msgid:%d)\n", re->head.transactionID);
return true;
}
return false;
} }

View File

@@ -42,7 +42,7 @@ class FSPersistence {
// hard-coded emergency defaults are now applied. // hard-coded emergency defaults are now applied.
#ifdef EMSESP_DEBUG #ifdef EMSESP_DEBUG
Serial.println(); Serial.println();
Serial.printf("Applying defaults to %s ", _filePath); Serial.printf("Applying defaults to %s", _filePath);
Serial.println(); Serial.println();
#endif #endif
applyDefaults(); applyDefaults();

View File

@@ -354,31 +354,39 @@ void NetworkSettingsService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info)
setWiFiPowerOnRSSI(); setWiFiPowerOnRSSI();
} }
#if ESP_IDF_VERSION_MAJOR < 5 #if ESP_IDF_VERSION_MAJOR < 5
WiFi.enableIpV6(); WiFi.enableIpV6(); // force ipv6
#endif #endif
break; break;
case ARDUINO_EVENT_ETH_CONNECTED: case ARDUINO_EVENT_ETH_CONNECTED:
#if ESP_IDF_VERSION_MAJOR < 5 #if ESP_IDF_VERSION_MAJOR < 5
ETH.enableIpV6(); ETH.enableIpV6(); // force ipv6
#endif #endif
break; break;
// IPv6 specific // IPv6 specific
case ARDUINO_EVENT_WIFI_STA_GOT_IP6: case ARDUINO_EVENT_WIFI_STA_GOT_IP6:
case ARDUINO_EVENT_ETH_GOT_IP6:
#if !TASMOTA_SDK && ESP_IDF_VERSION_MAJOR < 5 #if !TASMOTA_SDK && ESP_IDF_VERSION_MAJOR < 5
if (emsesp::EMSESP::system_.ethernet_connected()) { emsesp::EMSESP::logger().info("Local IPv6 (WiFi)=%s", WiFi.localIPv6().toString().c_str());
emsesp::EMSESP::logger().info("Local IPv6=%s", ETH.localIPv6().toString().c_str());
} else {
emsesp::EMSESP::logger().info("Local IPv6=%s", WiFi.localIPv6().toString().c_str());
}
#else #else
emsesp::EMSESP::logger().info("Local IPv6=%s", IPAddress(IPv6, (uint8_t *)info.got_ip6.ip6_info.ip.addr, 0).toString().c_str()); emsesp::EMSESP::logger().info("Local IPv6=%s", IPAddress(IPv6, (uint8_t *)info.got_ip6.ip6_info.ip.addr, 0).toString().c_str());
#endif #endif
emsesp::EMSESP::system_.has_ipv6(true); emsesp::EMSESP::system_.has_ipv6(true);
break; break;
// IPv6 specific
// This a bug in arduino where this is triggered twice, so we prevent it
case ARDUINO_EVENT_ETH_GOT_IP6:
if (!emsesp::EMSESP::system_.has_ipv6()) {
#if !TASMOTA_SDK && ESP_IDF_VERSION_MAJOR < 5
emsesp::EMSESP::logger().info("Local IPv6 (Eth)=%s", ETH.localIPv6().toString().c_str());
#else
emsesp::EMSESP::logger().info("Local IPv6=%s", IPAddress(IPv6, (uint8_t *)info.got_ip6.ip6_info.ip.addr, 0).toString().c_str());
#endif
emsesp::EMSESP::system_.has_ipv6(true);
}
break;
default: default:
break; break;
} }

View File

@@ -85,11 +85,7 @@ void Shell::stop() {
blocking_data->stop_ = true; blocking_data->stop_ = true;
} else { } else {
#if defined(EMSESP_STANDALONE)
if (running()) { if (running()) {
#else
if (running() && !has_flags(CommandFlags::LOCAL)) { // do not close local shell
#endif
stopped_ = true; stopped_ = true;
stopped(); stopped();
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 258 KiB

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 52 KiB

View File

@@ -1,3 +1,6 @@
// used to simulate
// - file uploads
// - EventSource (SSE) for log messages
import formidable from 'formidable'; import formidable from 'formidable';
function pad(number) { function pad(number) {
@@ -81,7 +84,7 @@ export default () => {
}) })
); );
} else { } else {
res.statusCode = 400; res.statusCode = 406;
console.log('Invalid file extension!'); console.log('Invalid file extension!');
} }
} }
@@ -99,15 +102,21 @@ export default () => {
let count = 0; let count = 0;
const interval = setInterval(() => { const interval = setInterval(() => {
let message = 'message #' + count;
if (count % 6 === 1) {
message +=
' with a long message that will be wrapped, to see if it stays one a single line';
}
const data = { const data = {
t: new Date().toISOString(), t: new Date().toISOString(),
l: 3 + (count % 6), l: 3 + (count % 6),
i: count, i: count,
n: 'system', n: 'system',
m: 'message #' + count++ m: message
}; };
count++;
res.write(`data: ${JSON.stringify(data)}\n\n`); res.write(`data: ${JSON.stringify(data)}\n\n`);
}, 1000); }, 800);
// if client closes connection // if client closes connection
res.on('close', () => { res.on('close', () => {

View File

@@ -124,7 +124,8 @@ const LOG_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'logSettings';
let log_settings = { let log_settings = {
level: 6, level: 6,
max_messages: 50, max_messages: 50,
compact: true compact: true,
psram: true
}; };
const FETCH_LOG_ENDPOINT = REST_ENDPOINT_ROOT + 'fetchLog'; const FETCH_LOG_ENDPOINT = REST_ENDPOINT_ROOT + 'fetchLog';

View File

@@ -33,11 +33,12 @@ build_flags =
-D CONFIG_ASYNC_TCP_STACK_SIZE=6144 -D CONFIG_ASYNC_TCP_STACK_SIZE=6144
-D CONFIG_ASYNC_TCP_QUEUE=32 -D CONFIG_ASYNC_TCP_QUEUE=32
-D CONFIG_ASYNC_TCP_TASK_PRIORITY=10 -D CONFIG_ASYNC_TCP_TASK_PRIORITY=10
-D CORE_DEBUG_LEVEL=0
unbuild_flags = unbuild_flags =
${common.core_unbuild_flags} ${common.core_unbuild_flags}
[espressi32_base] [espressif32_base]
platform = espressif32@6.8.1 platform = espressif32@6.8.1
framework = arduino framework = arduino
board_build.filesystem = littlefs board_build.filesystem = littlefs
@@ -49,7 +50,7 @@ extra_scripts =
pre:scripts/build_interface.py pre:scripts/build_interface.py
scripts/rename_fw.py scripts/rename_fw.py
[espressi32_base_tasmota] [espressif32_base_tasmota]
; use Tasmota's library for 4MB variants ; use Tasmota's library for 4MB variants
; it removes some unused libs (like mbedtsl, so no WiFi_secure.h) and increases available heap ; it removes some unused libs (like mbedtsl, so no WiFi_secure.h) and increases available heap
; Tasmota Arduino Core 2.0.18 with IPv6 support, based on IDF 4.4.8 ; Tasmota Arduino Core 2.0.18 with IPv6 support, based on IDF 4.4.8
@@ -81,75 +82,72 @@ lib_deps =
; ;
; builds for GitHub Actions CI ; builds for GitHub Actions CI
; We don't set EMSESP_DEFAULT_BOARD_PROFILE and let the code determine the board type. e.g. with board_build.extra_flags = '-DEMSESP_DEFAULT_BOARD_PROFILE="S32"'
; ;
; the Web interface is built seperately during the GH Action so is skipped (not included in extra_scripts) ; the Web interface is built separately during the GH Action script, so skipped on these targets
; ;
[env:ci_s_4M] [env:ci_s_4M]
; 4MB ESP32 - using Tasmota - no SSL, no PSRAM - like the BBQKees older S32 models ; 4MB ESP32 - using Tasmota - no SSL, no PSRAM - like the BBQKees older S32 and E32 models
extends = espressi32_base_tasmota extends = espressif32_base_tasmota
extra_scripts = scripts/rename_fw.py extra_scripts = scripts/rename_fw.py
board = esp32dev board = esp32dev
board_upload.flash_size = 4MB board_upload.flash_size = 4MB
board_build.partitions = esp32_partition_4M.csv board_build.partitions = esp32_partition_4M.csv
board_build.extra_flags = '-DEMSESP_DEFAULT_BOARD_PROFILE="S32"'
[env:ci_s_16M] [env:ci_s_16M]
; 16MB ESP32 - using Tasmota - no SSL, no PSRAM - like the BBQKees older S32 models ; 16MB ESP32 - using Tasmota - no SSL, no PSRAM - like the BBQKees some later S32 models
extends = espressi32_base_tasmota extends = espressif32_base_tasmota
extra_scripts = scripts/rename_fw.py extra_scripts = scripts/rename_fw.py
board = esp32dev board = esp32dev
board_upload.flash_size = 16MB board_upload.flash_size = 16MB
board_build.partitions = esp32_partition_16M.csv board_build.partitions = esp32_partition_16M.csv
board_build.extra_flags = '-DEMSESP_DEFAULT_BOARD_PROFILE="S32"'
[env:ci_s_16M_P] [env:ci_s_16M_P]
; 16MB ESP32 - with PSRAM - like BBQKees E32V2 ; 16MB ESP32 - with PSRAM - like BBQKees E32V2
extends = espressi32_base extends = espressif32_base
extra_scripts = scripts/rename_fw.py extra_scripts = scripts/rename_fw.py
board = esp32dev board = esp32dev
board_upload.flash_size = 16MB board_upload.flash_size = 16MB
board_build.partitions = esp32_partition_16M.csv board_build.partitions = esp32_partition_16M.csv
board_build.extra_flags = -DBOARD_HAS_PSRAM '-DEMSESP_DEFAULT_BOARD_PROFILE="E32V2"' board_build.extra_flags = -DBOARD_HAS_PSRAM
[env:ci_s3_16M_P] [env:ci_s3_16M_P]
; 16MB ESP32-S3 - with PSRAM - like BBQKees S3 ; 16MB ESP32-S3 - with PSRAM - like BBQKees S3
extends = espressi32_base extends = espressif32_base
extra_scripts = scripts/rename_fw.py extra_scripts = scripts/rename_fw.py
board = lolin_s3 board = lolin_s3
board_build.f_cpu = 240000000L board_build.f_cpu = 240000000L
board_upload.flash_size = 16MB board_upload.flash_size = 16MB
board_build.partitions = esp32_partition_16M.csv board_build.partitions = esp32_partition_16M.csv
board_build.extra_flags = -DBOARD_HAS_PSRAM '-DEMSESP_DEFAULT_BOARD_PROFILE="S32S3"' board_build.extra_flags = -DBOARD_HAS_PSRAM
; ;
; Direct builds ; Direct builds
; ;
; For board params see jsonb files in https://github.com/platformio/platform-espressif32/tree/master/boards ; For board params see json files in https://github.com/platformio/platform-espressif32/tree/master/boards
; ;
[env:s_4M] [env:s_4M]
extends = espressi32_base_tasmota extends = espressif32_base_tasmota
board = esp32dev board = esp32dev
board_upload.flash_size = 4MB board_upload.flash_size = 4MB
board_build.partitions = esp32_partition_4M.csv board_build.partitions = esp32_partition_4M.csv
board_build.extra_flags = '-DEMSESP_DEFAULT_BOARD_PROFILE="S32"'
[env:s_asym_4M] [env:s_asym_4M]
extends = espressi32_base_tasmota extends = espressif32_base_tasmota
board = esp32dev board = esp32dev
board_upload.flash_size = 4MB board_upload.flash_size = 4MB
board_build.partitions = esp32_asym_partition_4M.csv board_build.partitions = esp32_asym_partition_4M.csv
board_build.extra_flags = '-DEMSESP_DEFAULT_BOARD_PROFILE="S32"'
[env:s_16M_P] [env:s_16M_P]
extends = espressi32_base extends = espressif32_base
board = esp32dev board = esp32dev
board_upload.flash_size = 16MB board_upload.flash_size = 16MB
board_build.partitions = esp32_partition_16M.csv board_build.partitions = esp32_partition_16M.csv
board_build.extra_flags = -DBOARD_HAS_PSRAM '-DEMSESP_DEFAULT_BOARD_PROFILE="S32"' board_build.extra_flags = -DBOARD_HAS_PSRAM
[env:c3_mini_4M] [env:c3_mini_4M]
extends = espressi32_base_tasmota extends = espressif32_base_tasmota
board = lolin_c3_mini board = lolin_c3_mini
board_upload.flash_size = 4MB board_upload.flash_size = 4MB
board_build.partitions = esp32_partition_4M.csv board_build.partitions = esp32_partition_4M.csv
@@ -158,14 +156,14 @@ board_build.extra_flags = '-DEMSESP_DEFAULT_BOARD_PROFILE="C3MINI"'
; lolin C3 mini v1 needs special wifi init. ; lolin C3 mini v1 needs special wifi init.
; https://www.wemos.cc/en/latest/c3/c3_mini_1_0_0.html#about-wifi ; https://www.wemos.cc/en/latest/c3/c3_mini_1_0_0.html#about-wifi
[env:c3_miniv1_4M] [env:c3_miniv1_4M]
extends = espressi32_base_tasmota extends = espressif32_base_tasmota
board = lolin_c3_mini board = lolin_c3_mini
board_upload.flash_size = 4MB board_upload.flash_size = 4MB
board_build.partitions = esp32_partition_4M.csv board_build.partitions = esp32_partition_4M.csv
board_build.extra_flags = -DBOARD_C3_MINI_V1 '-DEMSESP_DEFAULT_BOARD_PROFILE="C3MINI"' board_build.extra_flags = -DBOARD_C3_MINI_V1 '-DEMSESP_DEFAULT_BOARD_PROFILE="C3MINI"'
[env:s2_4M] [env:s2_4M]
extends = espressi32_base_tasmota extends = espressif32_base_tasmota
board = lolin_s2_mini board = lolin_s2_mini
board_upload.flash_size = 4MB board_upload.flash_size = 4MB
board_build.partitions = esp32_partition_4M.csv board_build.partitions = esp32_partition_4M.csv
@@ -173,28 +171,28 @@ board_build.extra_flags = '-DEMSESP_DEFAULT_BOARD_PROFILE="S2MINI"'
; https://github.com/platformio/platform-espressif32/blob/master/boards/lolin_s3.json ; https://github.com/platformio/platform-espressif32/blob/master/boards/lolin_s3.json
[env:s3_16M_P] [env:s3_16M_P]
extends = espressi32_base extends = espressif32_base
board = lolin_s3 board = lolin_s3
board_upload.use_1200bps_touch = false board_upload.use_1200bps_touch = false
board_upload.wait_for_upload_port = false board_upload.wait_for_upload_port = false
board_upload.flash_size = 16MB board_upload.flash_size = 16MB
board_build.partitions = esp32_partition_16M.csv board_build.partitions = esp32_partition_16M.csv
board_build.extra_flags = -DBOARD_HAS_PSRAM '-DEMSESP_DEFAULT_BOARD_PROFILE="S32S3"' board_build.extra_flags = -DBOARD_HAS_PSRAM
[env:s3_32M_P] [env:s3_32M_P]
extends = espressi32_base extends = espressif32_base
board = lolin_s3 board = lolin_s3
board_build.arduino.memory_type: opi_opi board_build.arduino.memory_type: opi_opi
board_build.flash_mode = opi board_build.flash_mode = opi
board_upload.flash_size = 32MB board_upload.flash_size = 32MB
board_build.partitions = esp32_partition_32M.csv board_build.partitions = esp32_partition_32M.csv
board_build.extra_flags = -DBOARD_HAS_PSRAM '-DEMSESP_DEFAULT_BOARD_PROFILE="S32S3"' board_build.extra_flags = -DBOARD_HAS_PSRAM
; ;
; Building and testing natively, standalone without an ESP32. ; Building and testing natively, standalone without an ESP32.
; See https://docs.platformio.org/en/latest/platforms/native.html ; See https://docs.platformio.org/en/latest/platforms/native.html
; ;
; It will generate an executbale which when run will show the EMS-ESP Console where you can run tests using the `test` command. ; It will generate an executable which when run will show the EMS-ESP Console where you can run tests using the `test` command.
; ;
; See https://docs.platformio.org/en/latest/core/installation/shell-commands.html#piocore-install-shell-commands ; See https://docs.platformio.org/en/latest/core/installation/shell-commands.html#piocore-install-shell-commands
; ;
@@ -203,8 +201,8 @@ board_build.extra_flags = -DBOARD_HAS_PSRAM '-DEMSESP_DEFAULT_BOARD_PROFILE="S32
; to build and run on Windows, it needs winsock for the console input so: ; to build and run on Windows, it needs winsock for the console input so:
; - For the first time, install Msys2 (https://www.msys2.org/) and the GCC compiler with `run pacman -S mingw-w64-ucrt-x86_64-gcc` ; - For the first time, install Msys2 (https://www.msys2.org/) and the GCC compiler with `run pacman -S mingw-w64-ucrt-x86_64-gcc`
; - Then, build with `pio run -e native` to create the program.exe file ; - Then, build with `pio run -e native` to create the program.exe file
; - run by calling the executable from the Mysys shell e.g. `C:/msys64/msys2_shell.cmd -defterm -here -no-start -ucrt64 -c /d/dev/proddy/EMS-ESP32/.pio/build/native/program.exe` ; - run by calling the executable from the Mysys shell e.g. `C:/msys64/msys2_shell.cmd -defterm -here -no-start -ucrt64 -c <location>/.pio/build/native/program.exe`
; - or integrate into Windows Terminal https://www.msys2.org/docs/terminals/ ; - or use with Windows Terminal https://www.msys2.org/docs/terminals/
; ;
[env:native] [env:native]
platform = native platform = native
@@ -243,7 +241,7 @@ lib_ignore = Module EMS-ESP-Modules
; unit tests ; unit tests
; pio run -e native-test -t exec ; pio run -e native-test -t exec
; works on Linux, Windows, and MacOS ; works on Linux, Windows, and MacOS
; to auto generate the API exepected test results, compile with -DEMSESP_UNITY_CREATE and capture the output, and paste into the test_api.cpp file ; to update the test results, compile with -DEMSESP_UNITY_CREATE, run and capture the output and then paste this into the test_api.cpp file
[env:native-test] [env:native-test]
platform = native platform = native
test_build_src = true test_build_src = true

View File

@@ -29,6 +29,7 @@ void AnalogSensor::start() {
if (!analog_enabled_) { if (!analog_enabled_) {
return; return;
} }
analogSetAttenuation(ADC_2_5db); // for all channels 1.5V analogSetAttenuation(ADC_2_5db); // for all channels 1.5V
LOG_INFO("Starting Analog Sensor service"); LOG_INFO("Starting Analog Sensor service");
@@ -135,9 +136,9 @@ void AnalogSensor::reload(bool get_nvs) {
// first check if the GPIO is valid. If not, force set it to disabled // first check if the GPIO is valid. If not, force set it to disabled
if (!System::is_valid_gpio(sensor.gpio())) { if (!System::is_valid_gpio(sensor.gpio())) {
LOG_WARNING("Bad GPIO %d for Sensor %s", sensor.gpio(), sensor.name().c_str()); LOG_WARNING("Bad GPIO %d for Sensor %s. Disabling.", sensor.gpio(), sensor.name().c_str());
sensor.set_type(AnalogType::NOTUSED); sensor.set_type(AnalogType::NOTUSED);
continue; continue; // skip this loop pass
} }
if (sensor.type() == AnalogType::ADC) { if (sensor.type() == AnalogType::ADC) {
@@ -260,6 +261,7 @@ void AnalogSensor::measure() {
sensor.sum_ = (sensor.sum_ * 511) / 512 + a; sensor.sum_ = (sensor.sum_ * 511) / 512 + a;
sensor.analog_ = sensor.sum_ / 512; sensor.analog_ = sensor.sum_ / 512;
} }
// detect change with little hysteresis on raw mV value // detect change with little hysteresis on raw mV value
if (sensor.last_reading_ + 1 < sensor.analog_ || sensor.last_reading_ > sensor.analog_ + 1) { if (sensor.last_reading_ + 1 < sensor.analog_ || sensor.last_reading_ > sensor.analog_ + 1) {
sensor.set_value(((int32_t)sensor.analog_ - sensor.offset()) * sensor.factor()); sensor.set_value(((int32_t)sensor.analog_ - sensor.offset()) * sensor.factor());
@@ -300,6 +302,7 @@ void AnalogSensor::measure() {
sensor.last_polltime_ = sensor.polltime_; sensor.last_polltime_ = sensor.polltime_;
} }
} }
// see if there is a change and increment # reads // see if there is a change and increment # reads
if (old_value != sensor.value()) { if (old_value != sensor.value()) {
sensorreads_++; sensorreads_++;
@@ -308,6 +311,7 @@ void AnalogSensor::measure() {
} }
} }
} }
// store counter-values only every hour to reduce flash wear // store counter-values only every hour to reduce flash wear
static uint8_t lastSaveHour = 0; static uint8_t lastSaveHour = 0;
time_t now = time(nullptr); time_t now = time(nullptr);

View File

@@ -68,7 +68,7 @@ static std::vector<std::string> log_level_autocomplete(Shell & shell, const std:
} }
static void setup_commands(std::shared_ptr<Commands> & commands) { static void setup_commands(std::shared_ptr<Commands> & commands) {
// log, exit, help // exit, help, log
commands->add_command(ShellContext::MAIN, CommandFlags::USER, {F_(exit)}, EMSESPShell::main_exit_function); commands->add_command(ShellContext::MAIN, CommandFlags::USER, {F_(exit)}, EMSESPShell::main_exit_function);
commands->add_command(ShellContext::MAIN, CommandFlags::USER, {F_(help)}, EMSESPShell::main_help_function); commands->add_command(ShellContext::MAIN, CommandFlags::USER, {F_(help)}, EMSESPShell::main_help_function);
commands->add_command(ShellContext::MAIN, CommandFlags::USER, {F_(log)}, {F_(log_level_optional)}, console_log_level, log_level_autocomplete); commands->add_command(ShellContext::MAIN, CommandFlags::USER, {F_(log)}, {F_(log_level_optional)}, console_log_level, log_level_autocomplete);
@@ -91,6 +91,10 @@ static void setup_commands(std::shared_ptr<Commands> & commands) {
string_vector{F_(show), F_(devices)}, string_vector{F_(show), F_(devices)},
[](Shell & shell, const std::vector<std::string> & arguments) { to_app(shell).show_devices(shell); }); [](Shell & shell, const std::vector<std::string> & arguments) { to_app(shell).show_devices(shell); });
commands->add_command(ShellContext::MAIN, CommandFlags::USER, string_vector{F_(show), F_(log)}, [](Shell & shell, const std::vector<std::string> & arguments) {
to_app(shell).webLogService.show(shell);
});
commands->add_command(ShellContext::MAIN, CommandFlags::USER, string_vector{F_(show), F_(ems)}, [](Shell & shell, const std::vector<std::string> & arguments) { commands->add_command(ShellContext::MAIN, CommandFlags::USER, string_vector{F_(show), F_(ems)}, [](Shell & shell, const std::vector<std::string> & arguments) {
to_app(shell).show_ems(shell); to_app(shell).show_ems(shell);
@@ -269,7 +273,7 @@ static void setup_commands(std::shared_ptr<Commands> & commands) {
ShellContext::MAIN, ShellContext::MAIN,
CommandFlags::ADMIN, CommandFlags::ADMIN,
string_vector{F_(set), F_(board_profile)}, string_vector{F_(set), F_(board_profile)},
string_vector{F_(name_mandatory), F_(nvs_optional)}, string_vector{F_(name_mandatory)},
[](Shell & shell, const std::vector<std::string> & arguments) { [](Shell & shell, const std::vector<std::string> & arguments) {
std::vector<int8_t> data; // led, dallas, rx, tx, button, phy_type, eth_power, eth_phy_addr, eth_clock_mode std::vector<int8_t> data; // led, dallas, rx, tx, button, phy_type, eth_power, eth_phy_addr, eth_clock_mode
std::string board_profile = Helpers::toUpper(arguments.front()); std::string board_profile = Helpers::toUpper(arguments.front());
@@ -277,9 +281,7 @@ static void setup_commands(std::shared_ptr<Commands> & commands) {
shell.println("Invalid board profile (S32, E32, E32V2, MH-ET, NODEMCU, LOLIN, OLIMEX, OLIMEXPOE, C3MINI, S2MINI, S3MINI, S32S3, CUSTOM)"); shell.println("Invalid board profile (S32, E32, E32V2, MH-ET, NODEMCU, LOLIN, OLIMEX, OLIMEXPOE, C3MINI, S2MINI, S3MINI, S32S3, CUSTOM)");
return; return;
} }
if (arguments.size() == 2 && Helpers::toLower(arguments.back()) == "nvs") {
to_app(shell).nvs_.putString("boot", board_profile.c_str());
}
to_app(shell).webSettingsService.update([&](WebSettings & settings) { to_app(shell).webSettingsService.update([&](WebSettings & settings) {
settings.board_profile = board_profile.c_str(); settings.board_profile = board_profile.c_str();
settings.led_gpio = data[0]; settings.led_gpio = data[0];
@@ -686,7 +688,11 @@ void EMSESPShell::end_of_transmission() {
void EMSESPShell::main_help_function(Shell & shell, const std::vector<std::string> & arguments) { void EMSESPShell::main_help_function(Shell & shell, const std::vector<std::string> & arguments) {
shell.println(); shell.println();
#ifndef EMSESP_DEBUG
shell.printfln("%s%sEMS-ESP version %s%s", COLOR_BRIGHT_GREEN, COLOR_BOLD_ON, EMSESP_APP_VERSION, COLOR_RESET); shell.printfln("%s%sEMS-ESP version %s%s", COLOR_BRIGHT_GREEN, COLOR_BOLD_ON, EMSESP_APP_VERSION, COLOR_RESET);
#else
shell.printfln("%s%sEMS-ESP version %s%s (DEBUG)", COLOR_BRIGHT_GREEN, COLOR_BOLD_ON, EMSESP_APP_VERSION, COLOR_RESET);
#endif
shell.println(); shell.println();
shell.print_all_available_commands(); shell.print_all_available_commands();
} }
@@ -695,7 +701,7 @@ void EMSESPShell::main_exit_function(Shell & shell, const std::vector<std::strin
shell.stop(); shell.stop();
} }
// **** EMSESPConsole ***** // **** EMSESPConsole Class *****
#ifndef EMSESP_STANDALONE #ifndef EMSESP_STANDALONE
std::vector<bool> EMSESPConsole::ptys_; std::vector<bool> EMSESPConsole::ptys_;

View File

@@ -1341,7 +1341,7 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const
fetch_device_values(device_id); // go and fetch its device entity data fetch_device_values(device_id); // go and fetch its device entity data
// Print to LOG showing we've added a new device // Print to LOG showing we've added a new device
LOG_INFO("Recognized new %s with deviceID 0x%02X", EMSdevice::device_type_2_device_name(device_type), device_id); LOG_INFO("Detected EMS device: %s (0x%02X)", EMSdevice::device_type_2_device_name(device_type), device_id);
// register the MQTT subscribe topic for this device // register the MQTT subscribe topic for this device
// except for connect, controller and gateway // except for connect, controller and gateway
@@ -1541,68 +1541,69 @@ void EMSESP::start() {
#ifndef EMSESP_STANDALONE #ifndef EMSESP_STANDALONE
system_.PSram(ESP.getPsramSize()); system_.PSram(ESP.getPsramSize());
#endif #endif
// don't need shell if running unit tests
#ifndef EMSESP_UNITY
// Serial console's shell
serial_console_.begin(SERIAL_CONSOLE_BAUD_RATE); serial_console_.begin(SERIAL_CONSOLE_BAUD_RATE);
shell_ = std::make_shared<EMSESPConsole>(*this, serial_console_, true);
shell_->maximum_log_messages(100); // always start a serial console if we're running standalone, except if we're running unit tests
shell_->start(); #if defined(EMSESP_STANDALONE) || defined(EMSESP_DEBUG)
#if defined(EMSESP_DEBUG) #ifndef EMSESP_UNITY
shell_->log_level(uuid::log::Level::DEBUG); start_serial_console();
#else
shell_->log_level(uuid::log::Level::TRACE);
#endif
#if defined(EMSESP_STANDALONE)
shell_->add_flags(CommandFlags::ADMIN); // always start in su/admin mode when running tests
#endif #endif
#endif #endif
// start the file system // start the file system
#ifndef EMSESP_STANDALONE #ifndef EMSESP_STANDALONE
if (!LittleFS.begin(true)) { if (!LittleFS.begin(true)) {
LOG_INFO("LittleFS Mount Failed. Using default settings."); LOG_ERROR("LittleFS Mount Failed");
return; return;
} }
#endif #endif
// do a quick scan of the filesystem to see if we have a /config folder // do a quick scan of the filesystem to see if we a settings file in the /config folder
// so we know if this is a new install or not // so we know if this is a new factory install or not
#ifndef EMSESP_STANDALONE #ifndef EMSESP_STANDALONE
File root = LittleFS.open(EMSESP_FS_CONFIG_DIRECTORY); File root = LittleFS.open(EMSESP_SETTINGS_FILE);
bool factory_settings = !root; bool factory_settings = !root;
if (!root) { if (!root) {
LOG_INFO("No config found, assuming factory settings"); LOG_WARNING("No settings found on filesystem. Using factory settings.");
} }
root.close(); root.close();
#else #else
bool factory_settings = false; bool factory_settings = false;
#endif #endif
webLogService.begin(); // start web log service. now we can start capturing logs to the web log // start web log service. now we can start capturing logs to the web log
webLogService.begin();
esp8266React.begin(); // loads core system services settings (network, mqtt, ap, ntp etc) // loads core system services settings (network, mqtt, ap, ntp etc)
esp8266React.begin();
if (!nvs_.begin("ems-esp", false, "nvs1")) { // try bigger nvs partition on 16M flash first
nvs_.begin("ems-esp", false, "nvs"); // fallback to small nvs
}
LOG_DEBUG("NVS device information: %s", system_.getBBQKeesGatewayDetails().c_str());
#ifndef EMSESP_STANDALONE #ifndef EMSESP_STANDALONE
LOG_INFO("Booting EMS-ESP version %s from %s partition", EMSESP_APP_VERSION, esp_ota_get_running_partition()->label); // welcome message LOG_INFO("Booting EMS-ESP version %s from %s/%s partition",
EMSESP_APP_VERSION,
esp_ota_get_boot_partition()->label,
esp_ota_get_running_partition()->label); // welcome message
#else #else
LOG_INFO("Booting EMS-ESP version %s", EMSESP_APP_VERSION); // welcome message LOG_INFO("Booting EMS-ESP version %s", EMSESP_APP_VERSION); // welcome message
#endif #endif
LOG_DEBUG("System is running in Debug mode"); LOG_DEBUG("System is running in Debug mode");
LOG_INFO("Last system reset reason Core0: %s, Core1: %s", system_.reset_reason(0).c_str(), system_.reset_reason(1).c_str()); LOG_INFO("Last system reset reason Core0: %s, Core1: %s", system_.reset_reason(0).c_str(), system_.reset_reason(1).c_str());
// see if we're restoring a settings file // see if we're restoring a settings file
#ifndef EMSESP_STANDALONE
if (system_.check_restore()) { if (system_.check_restore()) {
LOG_WARNING("System needs a restart to apply new settings. Please wait."); LOG_WARNING("EMS-ESP will restart to apply new settings. Please wait.");
system_.system_restart(); system_.system_restart();
}; };
#endif
webSettingsService.begin(); // load EMS-ESP Application settings... if (!nvs_.begin("ems-esp", false, "nvs1")) { // try bigger nvs partition on 16M flash first
nvs_.begin("ems-esp", false, "nvs"); // fallback to small nvs
}
LOG_DEBUG("NVS device information: %s", system_.getBBQKeesGatewayDetails().isEmpty() ? "not set" : system_.getBBQKeesGatewayDetails().c_str());
webSettingsService.begin(); // load EMS-ESP Application settings
// do any system upgrades // do any system upgrades
if (system_.check_upgrade(factory_settings)) { if (system_.check_upgrade(factory_settings)) {
@@ -1653,11 +1654,11 @@ void EMSESP::start() {
// main loop calling all services // main loop calling all services
void EMSESP::loop() { void EMSESP::loop() {
esp8266React.loop(); // web services esp8266React.loop(); // web services
system_.loop(); // does LED and checks system health, and syslog service system_.loop(); // does LED and checks system health, and syslog service
static bool upload_status = true; // ready for any OTA uploads
// if we're doing an OTA upload, skip everything except from console refresh // if we're doing an OTA upload, skip everything except from console refresh
static bool upload_status = true; // ready for any OTA uploads
if (!system_.upload_isrunning()) { if (!system_.upload_isrunning()) {
// service loops // service loops
webLogService.loop(); // log in Web UI webLogService.loop(); // log in Web UI
@@ -1688,13 +1689,54 @@ void EMSESP::loop() {
if (system_.telnet_enabled()) { if (system_.telnet_enabled()) {
telnet_.loop(); telnet_.loop();
} }
#else
if (!shell_->running()) {
::exit(0);
}
#endif #endif
Shell::loop_all(); Shell::loop_all();
static bool show_prompt = true;
// user has to ctrl-c to create a serial console stream, exit command will close it
// this is to save around 2kb of heap memory
if (shell_) {
if (!shell_->running()) {
shell_.reset();
#ifdef EMSESP_STANDALONE
::exit(0); // kill session
#endif
shell_prompt();
}
} else {
if (show_prompt) {
shell_prompt();
show_prompt = false; // only show it once
}
int c = serial_console_.read();
if (c != -1) {
show_prompt = true;
}
if (c == '\x03' || c == '\x0C') {
start_serial_console();
}
}
}
void EMSESP::start_serial_console() {
shell_ = std::make_shared<EMSESPConsole>(*this, serial_console_, true);
shell_->maximum_log_messages(100);
shell_->add_flags(CommandFlags::ADMIN); // always start in su/admin mode when running tests
shell_->start();
#if defined(EMSESP_DEBUG)
shell_->log_level(uuid::log::Level::DEBUG);
#else
shell_->log_level(uuid::log::Level::TRACE);
#endif
}
void EMSESP::shell_prompt() {
#ifndef EMSESP_STANDALONE
serial_console_.println();
serial_console_.println("Press CTRL-C to activate this serial console");
#endif
} }
} // namespace emsesp } // namespace emsesp

View File

@@ -252,6 +252,9 @@ class EMSESP {
static void publish_response(std::shared_ptr<const Telegram> telegram); static void publish_response(std::shared_ptr<const Telegram> telegram);
static void publish_all_loop(); static void publish_all_loop();
void shell_prompt();
void start_serial_console();
static constexpr uint32_t EMS_FETCH_FREQUENCY = 60000; // check every minute static constexpr uint32_t EMS_FETCH_FREQUENCY = 60000; // check every minute
static constexpr uint8_t EMS_WAIT_KM_TIMEOUT = 60; // wait one minute static constexpr uint8_t EMS_WAIT_KM_TIMEOUT = 60; // wait one minute

View File

@@ -147,7 +147,6 @@ MAKE_WORD_CUSTOM(sensorid_optional, "[sensor ID]")
MAKE_WORD_CUSTOM(id_optional, "[id|hc]") MAKE_WORD_CUSTOM(id_optional, "[id|hc]")
MAKE_WORD_CUSTOM(partitionname_optional, "[partitionname]") MAKE_WORD_CUSTOM(partitionname_optional, "[partitionname]")
MAKE_WORD_CUSTOM(data_optional, "[data]") MAKE_WORD_CUSTOM(data_optional, "[data]")
MAKE_WORD_CUSTOM(nvs_optional, "[nvs]")
MAKE_WORD_CUSTOM(offset_optional, "[offset]") MAKE_WORD_CUSTOM(offset_optional, "[offset]")
MAKE_WORD_CUSTOM(length_optional, "[length]") MAKE_WORD_CUSTOM(length_optional, "[length]")
MAKE_WORD_CUSTOM(typeid_mandatory, "<type ID>") MAKE_WORD_CUSTOM(typeid_mandatory, "<type ID>")

View File

@@ -1,6 +1,5 @@
/** /**
* TODO: * TODO: verwendete libs in readme hinzufügen
* - verwendete libs in readme hinzufügen
*/ */
#include "modbus.h" #include "modbus.h"
#include "modbus_entity_parameters.hpp" #include "modbus_entity_parameters.hpp"

View File

@@ -37,8 +37,6 @@ const std::initializer_list<Modbus::EntityModbusInfo> Modbus::modbus_register_ma
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pumpMode), 18, 1), // pumpmode REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pumpMode), 18, 1), // pumpmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pumpCharacter), 19, 1), // pumpcharacter REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pumpCharacter), 19, 1), // pumpcharacter
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pumpDelay), 20, 1), // pumpdelay REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pumpDelay), 20, 1), // pumpdelay
// REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(setFlowTemp), 21, 1), // setflowtemp
// REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(setBurnPow), 22, 1), // setburnpow
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(selBurnPow), 23, 1), // selburnpow REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(selBurnPow), 23, 1), // selburnpow
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curBurnPow), 24, 1), // curburnpow REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curBurnPow), 24, 1), // curburnpow
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnStarts), 25, 2), // burnstarts REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnStarts), 25, 2), // burnstarts
@@ -183,6 +181,8 @@ const std::initializer_list<Modbus::EntityModbusInfo> Modbus::modbus_register_ma
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(keepWarmTemp), 261, 1), // keepwarmtemp REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(keepWarmTemp), 261, 1), // keepwarmtemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(setReturnTemp), 262, 1), // setreturntemp REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(setReturnTemp), 262, 1), // setreturntemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatingOn), 263, 1), // heating REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatingOn), 263, 1), // heating
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nrgCool), 264, 2), // nrgcool
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(meterCool), 266, 2), // metercool
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(nrgWw), 0, 2), // nrg REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(nrgWw), 0, 2), // nrg
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(meterWw), 2, 2), // meter REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(meterWw), 2, 2), // meter
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(upTimeCompWw), 4, 2), // uptimecomp REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(upTimeCompWw), 4, 2), // uptimecomp
@@ -239,7 +239,6 @@ const std::initializer_list<Modbus::EntityModbusInfo> Modbus::modbus_register_ma
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(wwTempOK), 60, 1), // tempok REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(wwTempOK), 60, 1), // tempok
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(wwActive), 61, 1), // active REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(wwActive), 61, 1), // active
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(ww3wayValve), 62, 1), // 3wayvalve REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(ww3wayValve), 62, 1), // 3wayvalve
// REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(wwSetPumpPower), 63, 1), // setpumppower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(wwMixerTemp), 64, 1), // mixertemp REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(wwMixerTemp), 64, 1), // mixertemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(cylMiddleTemp), 65, 1), // cylmiddletemp REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(cylMiddleTemp), 65, 1), // cylmiddletemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(wwStarts), 66, 2), // starts REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(wwStarts), 66, 2), // starts
@@ -313,7 +312,7 @@ const std::initializer_list<Modbus::EntityModbusInfo> Modbus::modbus_register_ma
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(noreducetemp), 31, 1), // noreducetemp REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(noreducetemp), 31, 1), // noreducetemp
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(reducetemp), 32, 1), // reducetemp REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(reducetemp), 32, 1), // reducetemp
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(wwprio), 33, 1), // dhwprio REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(wwprio), 33, 1), // dhwprio
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(hpcooling), 34, 1), // cooling REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(hpcooling), 34, 1), // hpcooling
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(coolingOn), 35, 1), // coolingon REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(coolingOn), 35, 1), // coolingon
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(hpmode), 36, 1), // hpmode REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(hpmode), 36, 1), // hpmode
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(dewoffset), 37, 1), // dewoffset REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(dewoffset), 37, 1), // dewoffset
@@ -344,7 +343,6 @@ const std::initializer_list<Modbus::EntityModbusInfo> Modbus::modbus_register_ma
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(daylowtemp), 100, 1), // daytemp2 REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(daylowtemp), 100, 1), // daytemp2
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(daymidtemp), 101, 1), // daytemp3 REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(daymidtemp), 101, 1), // daytemp3
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(dayhightemp), 102, 1), // daytemp4 REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(dayhightemp), 102, 1), // daytemp4
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(wwswitchtime), 103, 8), // switchtime
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(vacations1), 111, 11), // vacations1 REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(vacations1), 111, 11), // vacations1
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(vacations2), 122, 11), // vacations2 REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(vacations2), 122, 11), // vacations2
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(vacations3), 133, 11), // vacations3 REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(vacations3), 133, 11), // vacations3
@@ -357,6 +355,11 @@ const std::initializer_list<Modbus::EntityModbusInfo> Modbus::modbus_register_ma
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(heattemp), 190, 1), // heattemp REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(heattemp), 190, 1), // heattemp
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(roomsensor), 191, 1), // roomsensor REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(roomsensor), 191, 1), // roomsensor
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(heatup), 192, 1), // heatup REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(heatup), 192, 1), // heatup
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(coolstart), 193, 1), // coolstart
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(coolondelay), 194, 1), // coolondelay
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(cooloffdelay), 195, 1), // cooloffdelay
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(switchProgMode), 196, 1), // switchprogmode
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_HC, FL_(switchtime), 197, 8), // switchtime
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(mode), 0, 1), // mode REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(mode), 0, 1), // mode
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwSetTemp), 1, 1), // settemp REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwSetTemp), 1, 1), // settemp
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwSetTempLow), 2, 1), // settemplow REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwSetTempLow), 2, 1), // settemplow
@@ -374,7 +377,7 @@ const std::initializer_list<Modbus::EntityModbusInfo> Modbus::modbus_register_ma
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwDisinfectHour), 14, 1), // disinfecthour REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwDisinfectHour), 14, 1), // disinfecthour
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwMaxTemp), 15, 1), // maxtemp REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwMaxTemp), 15, 1), // maxtemp
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwOneTimeKey), 16, 1), // onetimekey REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwOneTimeKey), 16, 1), // onetimekey
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwswitchtime), 17, 8), // switchtime REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwswitchtime), 17, 8), // switchtimeWW
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwcircswitchtime), 25, 8), // circswitchtime REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwcircswitchtime), 25, 8), // circswitchtime
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(holidays), 33, 13), // holidays REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(holidays), 33, 13), // holidays
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(vacations), 46, 13), // vacations REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(vacations), 46, 13), // vacations
@@ -433,7 +436,7 @@ const std::initializer_list<Modbus::EntityModbusInfo> Modbus::modbus_register_ma
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(heatMetering), 42, 1), // heatmetering REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(heatMetering), 42, 1), // heatmetering
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(activated), 43, 1), // activated REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(activated), 43, 1), // activated
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(solarPumpMode), 44, 1), // solarpumpmode REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(solarPumpMode), 44, 1), // solarpumpmode
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(solarPumpKick), 45, 1), // pumpkick REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(solarPumpKick), 45, 1), // solarpumpkick
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(plainWaterMode), 46, 1), // plainwatermode REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(plainWaterMode), 46, 1), // plainwatermode
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(doubleMatchFlow), 47, 1), // doublematchflow REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(doubleMatchFlow), 47, 1), // doublematchflow
REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(pump2MinMod), 48, 1), // pump2minmod REGISTER_MAPPING(dt::SOLAR, TAG_TYPE_DEVICE_DATA, FL_(pump2MinMod), 48, 1), // pump2minmod

View File

@@ -106,18 +106,19 @@ void Shower::loop() {
// duration in seconds // duration in seconds
doc["duration"] = duration_; // seconds doc["duration"] = duration_; // seconds
time_t now = time(nullptr); // time_t now = time(nullptr);
// if NTP enabled, publish timestamp // // if NTP enabled, publish timestamp
if (now > 1576800000) { // year 2020 // if (now > 1576800000) { // year 2020
// doc["timestamp_s"] = now; // if needed, in seconds // // doc["timestamp_s"] = now; // if needed, in seconds
tm * tm_ = localtime(&now); // tm * tm_ = localtime(&now);
char dt[25]; // char dt[25];
strftime(dt, sizeof(dt), "%FT%T%z", tm_); // strftime(dt, sizeof(dt), "%FT%T%z", tm_);
doc["timestamp"] = dt; // doc["timestamp"] = dt;
LOG_INFO("shower finished %s (duration %lu s)", dt, duration_); // LOG_INFO("Shower finished %s (duration %lus)", dt, duration_);
} else { // } else {
LOG_INFO("shower finished (duration %lu s)", duration_); // LOG_INFO("Shower finished (duration %lus)", duration_);
} // }
LOG_INFO("Shower finished (duration %lus)", duration_);
Mqtt::queue_publish("shower_data", doc.as<JsonObject>()); Mqtt::queue_publish("shower_data", doc.as<JsonObject>());
} }
} }
@@ -210,7 +211,7 @@ void Shower::set_shower_state(bool state, bool force) {
ha_configdone_ = Mqtt::queue_ha(topic, doc.as<JsonObject>()); // publish the config payload with retain flag ha_configdone_ = Mqtt::queue_ha(topic, doc.as<JsonObject>()); // publish the config payload with retain flag
// //
// shower duaration // shower duration
// //
doc.clear(); doc.clear();

View File

@@ -466,8 +466,8 @@ bool System::is_valid_gpio(uint8_t pin, bool has_psram) {
return false; // bad pin return false; // bad pin
} }
// extra check for pins 21 and 22 (I2C) when ethernet is enabled // extra check for pins 21 and 22 (I2C) when ethernet is onboard
if ((EMSESP::system_.ethernet_connected()) && (pin >= 21 && pin <= 22)) { if ((EMSESP::system_.ethernet_connected() || EMSESP::system_.phy_type_ != PHY_type::PHY_TYPE_NONE) && (pin >= 21 && pin <= 22)) {
return false; // bad pin return false; // bad pin
} }
return true; return true;
@@ -540,6 +540,7 @@ void System::button_init(bool refresh) {
reload_settings(); reload_settings();
} }
#ifndef EMSESP_STANDALONE
if (!is_valid_gpio(pbutton_gpio_)) { if (!is_valid_gpio(pbutton_gpio_)) {
LOG_WARNING("Invalid button GPIO. Check config."); LOG_WARNING("Invalid button GPIO. Check config.");
myPButton_.init(255, HIGH); // disable myPButton_.init(255, HIGH); // disable
@@ -555,6 +556,7 @@ void System::button_init(bool refresh) {
myPButton_.onDblClick(BUTTON_DblClickDelay, button_OnDblClick); myPButton_.onDblClick(BUTTON_DblClickDelay, button_OnDblClick);
myPButton_.onLongPress(BUTTON_LongPressDelay, button_OnLongPress); myPButton_.onLongPress(BUTTON_LongPressDelay, button_OnLongPress);
myPButton_.onVLongPress(BUTTON_VLongPressDelay, button_OnVLongPress); myPButton_.onVLongPress(BUTTON_VLongPressDelay, button_OnVLongPress);
#endif
} }
// set the LED to on or off when in normal operating mode // set the LED to on or off when in normal operating mode
@@ -997,7 +999,7 @@ void System::show_system(uuid::console::Shell & shell) {
#ifndef EMSESP_STANDALONE #ifndef EMSESP_STANDALONE
shell.printfln(" Platform: %s (%s)", EMSESP_PLATFORM, ESP.getChipModel()); shell.printfln(" Platform: %s (%s)", EMSESP_PLATFORM, ESP.getChipModel());
shell.printfln(" Model: %s", getBBQKeesGatewayDetails().c_str()); shell.printfln(" Model: %s", getBBQKeesGatewayDetails().c_str());
shell.printfln(" Partition Boot/Running: %s/%s", esp_ota_get_boot_partition()->label, esp_ota_get_running_partition()->label); shell.printfln(" Partition boot/running: %s/%s", esp_ota_get_boot_partition()->label, esp_ota_get_running_partition()->label);
#endif #endif
shell.printfln(" Language: %s", locale().c_str()); shell.printfln(" Language: %s", locale().c_str());
shell.printfln(" Board profile: %s", board_profile().c_str()); shell.printfln(" Board profile: %s", board_profile().c_str());
@@ -1022,11 +1024,6 @@ void System::show_system(uuid::console::Shell & shell) {
shell.println(); shell.println();
shell.println("Network:"); shell.println("Network:");
// show ethernet mac address if we have an eth controller present
if (eth_present_) {
shell.printfln(" Ethernet MAC address: %s", ETH.macAddress().c_str());
}
switch (WiFi.status()) { switch (WiFi.status()) {
case WL_IDLE_STATUS: case WL_IDLE_STATUS:
shell.printfln(" Status: Idle"); shell.printfln(" Status: Idle");
@@ -1086,7 +1083,7 @@ void System::show_system(uuid::console::Shell & shell) {
// show Ethernet if connected // show Ethernet if connected
if (ethernet_connected_) { if (ethernet_connected_) {
shell.println(); shell.println();
shell.printfln(" Status: Ethernet connected"); shell.printfln(" Ethernet Status: connected");
shell.printfln(" Ethernet MAC address: %s", ETH.macAddress().c_str()); shell.printfln(" Ethernet MAC address: %s", ETH.macAddress().c_str());
shell.printfln(" Hostname: %s", ETH.getHostname()); shell.printfln(" Hostname: %s", ETH.getHostname());
shell.printfln(" IPv4 address: %s/%s", uuid::printable_to_string(ETH.localIP()).c_str(), uuid::printable_to_string(ETH.subnetMask()).c_str()); shell.printfln(" IPv4 address: %s/%s", uuid::printable_to_string(ETH.localIP()).c_str(), uuid::printable_to_string(ETH.subnetMask()).c_str());
@@ -1196,7 +1193,7 @@ bool System::check_upgrade(bool factory_settings) {
version::Semver200_version settings_version(settingsVersion); version::Semver200_version settings_version(settingsVersion);
if (!missing_version) { if (!missing_version) {
LOG_DEBUG("Checking version upgrade (settings file is v%d.%d.%d-%s)", LOG_DEBUG("Checking for version upgrades (settings file has v%d.%d.%d-%s)",
settings_version.major(), settings_version.major(),
settings_version.minor(), settings_version.minor(),
settings_version.patch(), settings_version.patch(),
@@ -1213,46 +1210,69 @@ bool System::check_upgrade(bool factory_settings) {
// compare versions // compare versions
if (this_version > settings_version) { if (this_version > settings_version) {
// need upgrade // we need to do an upgrade
LOG_NOTICE("Upgrading to version %d.%d.%d-%s", this_version.major(), this_version.minor(), this_version.patch(), this_version.prerelease().c_str()); if (missing_version) {
LOG_NOTICE("Upgrading to version %d.%d.%d-%s", this_version.major(), this_version.minor(), this_version.patch(), this_version.prerelease().c_str());
} else {
LOG_NOTICE("Upgrading from version %d.%d.%d-%s to %d.%d.%d-%s",
settings_version.major(),
settings_version.minor(),
settings_version.patch(),
settings_version.prerelease().c_str(),
this_version.major(),
this_version.minor(),
this_version.patch(),
this_version.prerelease().c_str());
}
// if we're coming from 3.4.4 or 3.5.0b14 which had no version stored then we need to apply new settings // if we're coming from 3.4.4 or 3.5.0b14 which had no version stored then we need to apply new settings
if (missing_version) { if (missing_version) {
LOG_INFO("Upgrade: Setting MQTT Entity ID format to older v3.4 format"); LOG_INFO("Upgrade: Setting MQTT Entity ID format to older v3.4 format (0)");
EMSESP::esp8266React.getMqttSettingsService()->update([&](MqttSettings & mqttSettings) { EMSESP::esp8266React.getMqttSettingsService()->update([&](MqttSettings & mqttSettings) {
mqttSettings.entity_format = Mqtt::entityFormat::SINGLE_LONG; // use old Entity ID format from v3.4 mqttSettings.entity_format = Mqtt::entityFormat::SINGLE_LONG; // use old Entity ID format from v3.4
return StateUpdateResult::CHANGED; return StateUpdateResult::CHANGED;
}); });
} else if (settings_version.major() == 3 && settings_version.minor() <= 6) { } else if (settings_version.major() == 3 && settings_version.minor() <= 6) {
LOG_INFO("Upgrade: Setting MQTT Entity ID format to v3.6 format");
EMSESP::esp8266React.getMqttSettingsService()->update([&](MqttSettings & mqttSettings) { EMSESP::esp8266React.getMqttSettingsService()->update([&](MqttSettings & mqttSettings) {
if (mqttSettings.entity_format == 1) { if (mqttSettings.entity_format == 1) {
mqttSettings.entity_format = Mqtt::entityFormat::SINGLE_OLD; // use old Entity ID format from v3.6 mqttSettings.entity_format = Mqtt::entityFormat::SINGLE_OLD; // use old Entity ID format from v3.6
LOG_INFO("Upgrade: Setting MQTT Entity ID format to v3.6 format (3)");
return StateUpdateResult::CHANGED; return StateUpdateResult::CHANGED;
} else if (mqttSettings.entity_format == 2) { } else if (mqttSettings.entity_format == 2) {
mqttSettings.entity_format = Mqtt::entityFormat::MULTI_OLD; // use old Entity ID format from v3.6 mqttSettings.entity_format = Mqtt::entityFormat::MULTI_OLD; // use old Entity ID format from v3.6
LOG_INFO("Upgrade: Setting MQTT Entity ID format to v3.6 format (4)");
return StateUpdateResult::CHANGED; return StateUpdateResult::CHANGED;
} }
return StateUpdateResult::UNCHANGED; return StateUpdateResult::UNCHANGED;
}); });
} }
// force WiFi sleep to off (was default on < 3.7.0-dev-33) // changes to Network
EMSESP::esp8266React.getNetworkSettingsService()->update([&](NetworkSettings & networkSettings) {
networkSettings.nosleep = true;
return StateUpdateResult::CHANGED;
});
// Network Settings Wifi tx_power is now using the value * 4.
EMSESP::esp8266React.getNetworkSettingsService()->update([&](NetworkSettings & networkSettings) { EMSESP::esp8266React.getNetworkSettingsService()->update([&](NetworkSettings & networkSettings) {
// Network Settings Wifi tx_power is now using the value * 4.
if (networkSettings.tx_power == 20) { if (networkSettings.tx_power == 20) {
networkSettings.tx_power = WIFI_POWER_19_5dBm; // use 19.5 as we don't have 20 anymore networkSettings.tx_power = WIFI_POWER_19_5dBm; // use 19.5 as we don't have 20 anymore
LOG_INFO("Upgrade: Setting WiFi TX Power to Auto"); LOG_INFO("Upgrade: Setting WiFi TX Power to Auto");
}
// force WiFi sleep to off (was default on < 3.7.0-dev-33)
networkSettings.nosleep = true;
LOG_INFO("Upgrade: Disabling WiFi nosleep");
return StateUpdateResult::CHANGED;
});
// changes to application settings
EMSESP::webSettingsService.update([&](WebSettings & settings) {
// force web buffer to 25 for those boards without psram
if (EMSESP::system_.PSram() == 0) {
settings.weblog_buffer = 25;
return StateUpdateResult::CHANGED; return StateUpdateResult::CHANGED;
} }
return StateUpdateResult::UNCHANGED; return StateUpdateResult::UNCHANGED;
}); });
} else if (this_version < settings_version) { } else if (this_version < settings_version) {
// need downgrade // need downgrade
LOG_NOTICE("Downgrading to version %d.%d.%d-%s", this_version.major(), this_version.minor(), this_version.patch(), this_version.prerelease().c_str()); LOG_NOTICE("Downgrading to version %d.%d.%d-%s", this_version.major(), this_version.minor(), this_version.patch(), this_version.prerelease().c_str());
@@ -1267,7 +1287,7 @@ bool System::check_upgrade(bool factory_settings) {
settings.version = EMSESP_APP_VERSION; settings.version = EMSESP_APP_VERSION;
return StateUpdateResult::CHANGED; return StateUpdateResult::CHANGED;
}); });
LOG_INFO("Upgrade: Setting version to %s", EMSESP_APP_VERSION); // LOG_INFO("Upgrade: Setting version to %s", EMSESP_APP_VERSION);
return true; // need reboot return true; // need reboot
} }
@@ -1300,7 +1320,7 @@ bool System::saveSettings(const char * filename, const char * section, JsonObjec
if (section_json) { if (section_json) {
File section_file = LittleFS.open(filename, "w"); File section_file = LittleFS.open(filename, "w");
if (section_file) { if (section_file) {
LOG_INFO("Applying new %s", section); LOG_INFO("Applying new uploaded %s data", section);
serializeJson(section_json, section_file); serializeJson(section_json, section_file);
section_file.close(); section_file.close();
return true; // reboot required return true; // reboot required
@@ -1438,7 +1458,7 @@ bool System::command_info(const char * value, const int8_t id, JsonObject output
#endif #endif
node["resetReason"] = EMSESP::system_.reset_reason(0) + " / " + EMSESP::system_.reset_reason(1); node["resetReason"] = EMSESP::system_.reset_reason(0) + " / " + EMSESP::system_.reset_reason(1);
#ifndef EMSESP_STANDALONE #ifndef EMSESP_STANDALONE
node["psram"] = (EMSESP::system_.PSram() > 0); // boolean node["psram"] = (EMSESP::system_.PSram() > 0); // make boolean
if (EMSESP::system_.PSram()) { if (EMSESP::system_.PSram()) {
node["psramSize"] = EMSESP::system_.PSram(); node["psramSize"] = EMSESP::system_.PSram();
node["freePsram"] = ESP.getFreePsram() / 1024; node["freePsram"] = ESP.getFreePsram() / 1024;
@@ -1756,10 +1776,11 @@ bool System::load_board_profile(std::vector<int8_t> & data, const std::string &
(int8_t)EMSESP::system_.eth_phy_addr_, (int8_t)EMSESP::system_.eth_phy_addr_,
(int8_t)EMSESP::system_.eth_clock_mode_}; (int8_t)EMSESP::system_.eth_clock_mode_};
} else { } else {
// unknown, return false LOG_DEBUG("Couldn't identify board profile %s", board_profile.c_str());
return false; return false; // unknown, return false
} }
// LOG_DEBUG("Found data for board profile %s", board_profile.c_str());
return true; return true;
} }

View File

@@ -217,6 +217,10 @@ class System {
has_ipv6_ = b; has_ipv6_ = b;
} }
bool has_ipv6() {
return has_ipv6_;
}
void ntp_connected(bool b); void ntp_connected(bool b);
bool ntp_connected(); bool ntp_connected();

View File

@@ -1 +1 @@
#define EMSESP_APP_VERSION "3.7.0-dev.34" #define EMSESP_APP_VERSION "3.7.0-dev.35"

View File

@@ -18,6 +18,8 @@
#include "emsesp.h" #include "emsesp.h"
using ::uuid::console::Shell;
namespace emsesp { namespace emsesp {
WebLogService::WebLogService(AsyncWebServer * server, SecurityManager * securityManager) WebLogService::WebLogService(AsyncWebServer * server, SecurityManager * securityManager)
@@ -75,12 +77,15 @@ size_t WebLogService::maximum_log_messages() const {
void WebLogService::maximum_log_messages(size_t count) { void WebLogService::maximum_log_messages(size_t count) {
maximum_log_messages_ = std::max((size_t)1, count); maximum_log_messages_ = std::max((size_t)1, count);
if (limit_log_messages_ > maximum_log_messages_) { if (limit_log_messages_ > maximum_log_messages_) {
limit_log_messages_ = maximum_log_messages_; limit_log_messages_ = maximum_log_messages_;
} }
while (log_messages_.size() > maximum_log_messages_) { while (log_messages_.size() > maximum_log_messages_) {
log_messages_.pop_front(); log_messages_.pop_front();
} }
EMSESP::webSettingsService.update([&](WebSettings & settings) { EMSESP::webSettingsService.update([&](WebSettings & settings) {
settings.weblog_buffer = count; settings.weblog_buffer = count;
return StateUpdateResult::CHANGED; return StateUpdateResult::CHANGED;
@@ -132,6 +137,42 @@ void WebLogService::operator<<(std::shared_ptr<uuid::log::Message> message) {
}); });
} }
// dumps out the contents of log buffer to shell console
void WebLogService::show(Shell & shell) {
if (log_messages_.empty()) {
return;
}
shell.println();
shell.printfln("Last Log (filtered by WebLog's level %s & buffer %d):", format_level_uppercase(log_level()), maximum_log_messages());
shell.println();
for (const auto & message : log_messages_) {
log_message_id_tail_ = message.id_;
shell.print(uuid::log::format_timestamp_ms(message.content_->uptime_ms, 3));
shell.printf(" %c %lu: [%s] ", uuid::log::format_level_char(message.content_->level), message.id_, message.content_->name);
if ((message.content_->level == uuid::log::Level::ERR) || (message.content_->level == uuid::log::Level::WARNING)) {
shell.print(COLOR_RED);
shell.println(message.content_->text);
shell.print(COLOR_RESET);
} else if (message.content_->level == uuid::log::Level::INFO) {
shell.print(COLOR_YELLOW);
shell.println(message.content_->text);
shell.print(COLOR_RESET);
} else if (message.content_->level == uuid::log::Level::DEBUG) {
shell.print(COLOR_CYAN);
shell.println(message.content_->text);
shell.print(COLOR_RESET);
} else {
shell.println(message.content_->text);
}
}
shell.println();
}
void WebLogService::loop() { void WebLogService::loop() {
if (!events_.count() || log_messages_.empty()) { if (!events_.count() || log_messages_.empty()) {
return; return;
@@ -200,7 +241,7 @@ void WebLogService::fetchLog(AsyncWebServerRequest * request) {
request->send(200); request->send(200);
} }
// sets the values like level after a POST // sets the values after a POST
void WebLogService::getSetValues(AsyncWebServerRequest * request, JsonVariant json) { void WebLogService::getSetValues(AsyncWebServerRequest * request, JsonVariant json) {
if ((request->method() == HTTP_GET) || (!json.is<JsonObject>())) { if ((request->method() == HTTP_GET) || (!json.is<JsonObject>())) {
// GET - return the values // GET - return the values
@@ -209,12 +250,13 @@ void WebLogService::getSetValues(AsyncWebServerRequest * request, JsonVariant js
root["level"] = log_level(); root["level"] = log_level();
root["max_messages"] = maximum_log_messages(); root["max_messages"] = maximum_log_messages();
root["compact"] = compact(); root["compact"] = compact();
root["psram"] = (EMSESP::system_.PSram() > 0);
response->setLength(); response->setLength();
request->send(response); request->send(response);
return; return;
} }
// POST - write the settings
auto && body = json.as<JsonObject>(); auto && body = json.as<JsonObject>();
uuid::log::Level level = body["level"]; uuid::log::Level level = body["level"];

View File

@@ -23,6 +23,8 @@
#define EMSESP_FETCH_LOG_PATH "/rest/fetchLog" #define EMSESP_FETCH_LOG_PATH "/rest/fetchLog"
#define EMSESP_LOG_SETTINGS_PATH "/rest/logSettings" #define EMSESP_LOG_SETTINGS_PATH "/rest/logSettings"
using ::uuid::console::Shell;
namespace emsesp { namespace emsesp {
class WebLogService : public uuid::log::Handler { class WebLogService : public uuid::log::Handler {
@@ -42,6 +44,7 @@ class WebLogService : public uuid::log::Handler {
bool compact() const; bool compact() const;
void compact(bool compact); void compact(bool compact);
void loop(); void loop();
void show(Shell & shell);
virtual void operator<<(std::shared_ptr<uuid::log::Message> message); virtual void operator<<(std::shared_ptr<uuid::log::Message> message);

View File

@@ -28,15 +28,16 @@ WebSettingsService::WebSettingsService(AsyncWebServer * server, FS * fs, Securit
server->on(EMSESP_BOARD_PROFILE_SERVICE_PATH, server->on(EMSESP_BOARD_PROFILE_SERVICE_PATH,
HTTP_GET, HTTP_GET,
securityManager->wrapRequest([this](AsyncWebServerRequest * request) { board_profile(request); }, AuthenticationPredicates::IS_AUTHENTICATED)); securityManager->wrapRequest([this](AsyncWebServerRequest * request) { board_profile(request); }, AuthenticationPredicates::IS_AUTHENTICATED));
addUpdateHandler([this] { onUpdate(); }, false);
server->on(EMSESP_GET_SETTINGS_PATH, server->on(EMSESP_GET_SETTINGS_PATH,
HTTP_GET, HTTP_GET,
securityManager->wrapRequest([this](AsyncWebServerRequest * request) { getSettings(request); }, AuthenticationPredicates::IS_ADMIN)); securityManager->wrapRequest([this](AsyncWebServerRequest * request) { getSettings(request); }, AuthenticationPredicates::IS_ADMIN));
addUpdateHandler([this] { onUpdate(); }, false);
} }
void WebSettings::read(WebSettings & settings, JsonObject root) { void WebSettings::read(WebSettings & settings, JsonObject root) {
root["version"] = settings.version; root["version"] = settings.version;
root["board_profile"] = settings.board_profile;
root["platform"] = EMSESP_PLATFORM;
root["locale"] = settings.locale; root["locale"] = settings.locale;
root["tx_mode"] = settings.tx_mode; root["tx_mode"] = settings.tx_mode;
root["ems_bus_id"] = settings.ems_bus_id; root["ems_bus_id"] = settings.ems_bus_id;
@@ -67,7 +68,6 @@ void WebSettings::read(WebSettings & settings, JsonObject root) {
root["analog_enabled"] = settings.analog_enabled; root["analog_enabled"] = settings.analog_enabled;
root["pbutton_gpio"] = settings.pbutton_gpio; root["pbutton_gpio"] = settings.pbutton_gpio;
root["solar_maxflow"] = settings.solar_maxflow; root["solar_maxflow"] = settings.solar_maxflow;
root["board_profile"] = settings.board_profile;
root["fahrenheit"] = settings.fahrenheit; root["fahrenheit"] = settings.fahrenheit;
root["bool_format"] = settings.bool_format; root["bool_format"] = settings.bool_format;
root["bool_dashboard"] = settings.bool_dashboard; root["bool_dashboard"] = settings.bool_dashboard;
@@ -79,7 +79,6 @@ void WebSettings::read(WebSettings & settings, JsonObject root) {
root["eth_power"] = settings.eth_power; root["eth_power"] = settings.eth_power;
root["eth_phy_addr"] = settings.eth_phy_addr; root["eth_phy_addr"] = settings.eth_phy_addr;
root["eth_clock_mode"] = settings.eth_clock_mode; root["eth_clock_mode"] = settings.eth_clock_mode;
root["platform"] = EMSESP_PLATFORM;
root["modbus_enabled"] = settings.modbus_enabled; root["modbus_enabled"] = settings.modbus_enabled;
root["modbus_port"] = settings.modbus_port; root["modbus_port"] = settings.modbus_port;
root["modbus_max_clients"] = settings.modbus_max_clients; root["modbus_max_clients"] = settings.modbus_max_clients;
@@ -88,90 +87,116 @@ void WebSettings::read(WebSettings & settings, JsonObject root) {
// call on initialization and also when settings are updated via web or console // call on initialization and also when settings are updated via web or console
StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) { StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) {
// load the version of the settings // load the version from the settings config. This can be blank and later used in System::check_upgrade()
// will be picked up in System::check_upgrade()
settings.version = root["version"] | EMSESP_DEFAULT_VERSION; settings.version = root["version"] | EMSESP_DEFAULT_VERSION;
// load default GPIO configuration based on board profile
std::vector<int8_t> data; // // led, dallas, rx, tx, button, phy_type, eth_power, eth_phy_addr, eth_clock_mode
settings.board_profile = root["board_profile"] | EMSESP_DEFAULT_BOARD_PROFILE;
// for -D compile setting store it in NVS
if ((String)EMSESP_DEFAULT_BOARD_PROFILE != "default" && EMSESP::nvs_.getString("boot") == "") {
EMSESP::nvs_.putString("boot", (const char *)EMSESP_DEFAULT_BOARD_PROFILE);
}
#ifndef EMSESP_STANDALONE #ifndef EMSESP_STANDALONE
bool psram = ESP.getPsramSize() > 0; // System::PSram() is initialized later bool psram = ESP.getPsramSize() > 0; // System::PSram() is initialized later
#else #else
bool psram = false; bool psram = false;
#endif #endif
if (System::load_board_profile(data, settings.board_profile.c_str())) { #ifdef EMSESP_DEBUG
if (settings.board_profile == "CUSTOM") { //read pins, fallback to S32 EMSESP::logger().debug("NVS boot value=[%s], board profile=[%s], EMSESP_DEFAULT_BOARD_PROFILE=[%s]",
data = {(int8_t)(root["led_gpio"] | 2), EMSESP::nvs_.getString("boot").c_str(),
(int8_t)(root["dallas_gpio"] | 18), root["board_profile"] | "",
(int8_t)(root["rx_gpio"] | 23), EMSESP_DEFAULT_BOARD_PROFILE);
(int8_t)(root["tx_gpio"] | 5), #endif
(int8_t)(root["pbutton_gpio"] | 0),
(int8_t)(root["phy_type"] | PHY_type::PHY_TYPE_NONE), // get the current board profile saved in the settings file
(int8_t)(root["eth_power"] | 0), settings.board_profile = root["board_profile"] | EMSESP_DEFAULT_BOARD_PROFILE; // this is set at compile time in platformio.ini, other it's "default"
(int8_t)(root["eth_phy_addr"] | 0), String old_board_profile = settings.board_profile;
(int8_t)(root["eth_clock_mode"] | 0)};
// The optional NVS boot value has priority and overrides any board_profile setting.
// We only do this for BBQKees boards
// Note 1: we never set the NVS boot value in the code - this is done on initial pre-loading
// Note 2: The board profile is dynamically changed for the session, but the value in the settings file on the FS remains untouched
if (!EMSESP::system_.getBBQKeesGatewayDetails().isEmpty()) {
String nvs_boot = EMSESP::nvs_.getString("boot");
if (!nvs_boot.isEmpty()) {
#ifdef EMSESP_DEBUG
EMSESP::logger().debug("Overriding board profile with NVS boot value %s");
#endif
settings.board_profile = nvs_boot;
} }
// check valid pins in this board profile
if (!System::is_valid_gpio(data[0], psram) || !System::is_valid_gpio(data[1], psram) || !System::is_valid_gpio(data[2], psram)
|| !System::is_valid_gpio(data[3], psram) || !System::is_valid_gpio(data[4], psram) || !System::is_valid_gpio(data[6], psram)) {
settings.board_profile = ""; // reset to factory default
}
} else {
settings.board_profile = ""; // reset to factory default
} }
if (settings.board_profile == "") {
// unknown, check for NVS or scan for ethernet, use default E32/E32V2/S32 // load the board profile from the settings, if it's not "default"
settings.board_profile = EMSESP::nvs_.getString("boot"); std::vector<int8_t> data; // // led, dallas, rx, tx, button, phy_type, eth_power, eth_phy_addr, eth_clock_mode
if (!System::load_board_profile(data, settings.board_profile.c_str())) { if (settings.board_profile != "default") {
#if defined(EMSESP_STANDALONE) if (System::load_board_profile(data, settings.board_profile.c_str())) {
settings.board_profile = "S32"; if (settings.board_profile == "CUSTOM") { // read pins, fallback to S32 values
#elif CONFIG_IDF_TARGET_ESP32 data = {(int8_t)(root["led_gpio"] | 2),
if (settings.board_profile == "" && !psram) { // empty: new test for E32 (int8_t)(root["dallas_gpio"] | 18),
#if ESP_ARDUINO_VERSION_MAJOR < 3 (int8_t)(root["rx_gpio"] | 23),
if (ETH.begin(1, 16, 23, 18, ETH_PHY_LAN8720, ETH_CLOCK_GPIO0_IN)) { (int8_t)(root["tx_gpio"] | 5),
#else (int8_t)(root["pbutton_gpio"] | 0),
if (ETH.begin(ETH_PHY_LAN8720, 1, 23, 18, 16, ETH_CLOCK_GPIO0_IN)) { (int8_t)(root["phy_type"] | PHY_type::PHY_TYPE_NONE),
#endif (int8_t)(root["eth_power"] | 0),
EMSESP::nvs_.putString("boot", "E32"); (int8_t)(root["eth_phy_addr"] | 0),
} else { (int8_t)(root["eth_clock_mode"] | 0)};
EMSESP::nvs_.putString("boot", "Test");
}
} else if (settings.board_profile == "Test" || psram) { // test E32V2
#if ESP_ARDUINO_VERSION_MAJOR < 3
if (ETH.begin(0, 15, 23, 18, ETH_PHY_LAN8720, ETH_CLOCK_GPIO0_OUT)) {
#else
if (ETH.begin(ETH_PHY_LAN8720, 0, 23, 18, 15, ETH_CLOCK_GPIO0_OUT)) {
#endif
EMSESP::nvs_.putString("boot", "E32V2");
} else {
EMSESP::nvs_.putString("boot", "S32");
}
} else {
EMSESP::nvs_.putString("boot", "S32");
} }
// ESP.restart(); // check valid pins in this board profile
EMSESP::system_.restart_requested(true); if (!System::is_valid_gpio(data[0], psram) || !System::is_valid_gpio(data[1], psram) || !System::is_valid_gpio(data[2], psram)
#elif CONFIG_IDF_TARGET_ESP32C3 || !System::is_valid_gpio(data[3], psram) || !System::is_valid_gpio(data[4], psram) || !System::is_valid_gpio(data[6], psram)) {
settings.board_profile = "C3MINI"; settings.board_profile = "default"; // reset to factory default
#elif CONFIG_IDF_TARGET_ESP32S2 }
settings.board_profile = "S2MINI"; } else {
#elif CONFIG_IDF_TARGET_ESP32S3 settings.board_profile = "default"; // can't find profile, use "default"
settings.board_profile = "S32S3"; // BBQKees Gateway S3
#else
settings.board_profile = "S32";
#endif
System::load_board_profile(data, settings.board_profile.c_str());
} }
EMSESP::logger().info("No board profile found. Re-setting to %s", settings.board_profile.c_str()); }
// still don't have a valid board profile. Let's see if we can determine one
if (settings.board_profile == "default") {
#ifdef EMSESP_DEBUG
EMSESP::logger().debug("Trying to detect board and set board profile...");
#endif
#if defined(EMSESP_STANDALONE)
settings.board_profile = "S32";
#elif CONFIG_IDF_TARGET_ESP32
// check for no PSRAM, could be a E32 or S32
if (!psram) {
#if ESP_ARDUINO_VERSION_MAJOR < 3
if (ETH.begin(1, 16, 23, 18, ETH_PHY_LAN8720, ETH_CLOCK_GPIO0_IN)) {
#else
if (ETH.begin(ETH_PHY_LAN8720, 1, 23, 18, 16, ETH_CLOCK_GPIO0_IN)) {
#endif
settings.board_profile = "E32"; // Ethernet without PSRAM
} else {
settings.board_profile = "S32"; // ESP32 standard WiFi without PSRAM
}
} else {
// check for boards with PSRAM, could be a E32V2 otherwise default back to the S32
#if ESP_ARDUINO_VERSION_MAJOR < 3
if (ETH.begin(0, 15, 23, 18, ETH_PHY_LAN8720, ETH_CLOCK_GPIO0_OUT)) {
#else
if (ETH.begin(ETH_PHY_LAN8720, 0, 23, 18, 15, ETH_CLOCK_GPIO0_OUT)) {
#endif
settings.board_profile = "E32V2"; // Ethernet and PSRAM
} else {
settings.board_profile = "S32"; // ESP32 standard WiFi with PSRAM
}
}
// override if we know the target from the build config like C3, S2, S3 etc..
#elif CONFIG_IDF_TARGET_ESP32C3
settings.board_profile = "C3MINI";
#elif CONFIG_IDF_TARGET_ESP32S2
settings.board_profile = "S2MINI";
#elif CONFIG_IDF_TARGET_ESP32S3
settings.board_profile = "S32S3"; // BBQKees Gateway S3
#endif
// apply the new board profile setting
System::load_board_profile(data, settings.board_profile.c_str());
}
if (old_board_profile != settings.board_profile) {
// see if need to override the set board profile (e.g. forced by NVS boot string)
EMSESP::logger().info("Setting new Board profile %s (was %s)", settings.board_profile.c_str(), old_board_profile.c_str());
} else { } else {
EMSESP::logger().info("Loading board profile %s", settings.board_profile.c_str()); EMSESP::logger().info("Board profile set to %s", settings.board_profile.c_str());
} }
int prev; int prev;
@@ -233,7 +258,7 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) {
} }
#endif #endif
// temperaturesensor // temperature sensor
prev = settings.dallas_parasite; prev = settings.dallas_parasite;
settings.dallas_parasite = root["dallas_parasite"] | EMSESP_DEFAULT_DALLAS_PARASITE; settings.dallas_parasite = root["dallas_parasite"] | EMSESP_DEFAULT_DALLAS_PARASITE;
check_flag(prev, settings.dallas_parasite, ChangeFlags::SENSOR); check_flag(prev, settings.dallas_parasite, ChangeFlags::SENSOR);
@@ -343,13 +368,20 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) {
EMSESP::system_.bool_dashboard(settings.bool_dashboard); EMSESP::system_.bool_dashboard(settings.bool_dashboard);
settings.weblog_level = root["weblog_level"] | EMSESP_DEFAULT_WEBLOG_LEVEL; settings.weblog_level = root["weblog_level"] | EMSESP_DEFAULT_WEBLOG_LEVEL;
settings.weblog_buffer = root["weblog_buffer"] | EMSESP_DEFAULT_WEBLOG_BUFFER;
settings.weblog_compact = root["weblog_compact"] | EMSESP_DEFAULT_WEBLOG_COMPACT; settings.weblog_compact = root["weblog_compact"] | EMSESP_DEFAULT_WEBLOG_COMPACT;
// if no psram limit weblog buffer to 25 messages
if (EMSESP::system_.PSram() > 0) {
settings.weblog_buffer = root["weblog_buffer"] | EMSESP_DEFAULT_WEBLOG_BUFFER;
} else {
settings.weblog_buffer = root["weblog_buffer"] | 25;
}
// save the settings // save the settings
if (flags_ == WebSettings::ChangeFlags::RESTART) { if (get_flags() == WebSettings::ChangeFlags::RESTART) {
return StateUpdateResult::CHANGED_RESTART; // tell WebUI that a restart is needed return StateUpdateResult::CHANGED_RESTART; // tell WebUI that a restart is needed
} }
return StateUpdateResult::CHANGED; return StateUpdateResult::CHANGED;
} }
@@ -377,11 +409,11 @@ void WebSettingsService::onUpdate() {
} }
if (WebSettings::has_flags(WebSettings::ChangeFlags::BUTTON)) { if (WebSettings::has_flags(WebSettings::ChangeFlags::BUTTON)) {
EMSESP::system_.button_init(true); // reload settings EMSESP::system_.button_init(true);
} }
if (WebSettings::has_flags(WebSettings::ChangeFlags::LED)) { if (WebSettings::has_flags(WebSettings::ChangeFlags::LED)) {
EMSESP::system_.led_init(true); // reload settings EMSESP::system_.led_init(true);
} }
if (WebSettings::has_flags(WebSettings::ChangeFlags::MQTT)) { if (WebSettings::has_flags(WebSettings::ChangeFlags::MQTT)) {
@@ -393,6 +425,7 @@ void WebSettingsService::onUpdate() {
void WebSettingsService::begin() { void WebSettingsService::begin() {
_fsPersistence.readFromFS(); _fsPersistence.readFromFS();
WebSettings::reset_flags(); WebSettings::reset_flags();
} }

View File

@@ -3,7 +3,7 @@
// Compile with -DEMSESP_UNITY_CREATE to generate the test functions // Compile with -DEMSESP_UNITY_CREATE to generate the test functions
// and copy the output and paste below. // and copy the output and paste below.
// //
// TODO: convert output to JSON and compare, showing differences // TODO convert output to JSON and compare, showing differences
// //
// You can also manually compare the differences using https://www.diffchecker.com/text-compare/ // You can also manually compare the differences using https://www.diffchecker.com/text-compare/
// //