Compare commits

...
13 Commits
Author SHA1 Message Date
Proddy b333b2871c Merge pull request #3244 from proddy/dev
bump version for testing
2026-09-18 15:19:15 +02:00
proddy c92f928143 bump version 2026-09-18 15:18:40 +02:00
proddy 4b430bc7fd auto-formatting 2026-09-18 15:18:20 +02:00
proddy 95da61cc6e update 2026-09-18 15:18:15 +02:00
Proddy e33b91f5a2 Merge pull request #3241 from HeatMind/fix/weblog-buffer-zero
Guard against a stored weblog_buffer of 0 (pop_front on an empty deque)
2026-09-18 15:08:39 +02:00
Proddy eed008707c Merge pull request #3242 from Jaano/fix/maxheat-enum-12-15kw
fix: add 12 kW and 15 kW steps to enum_maxHeat
2026-09-18 15:08:11 +02:00
Proddy c7f696a9dd Merge branch 'dev' into fix/maxheat-enum-12-15kw 2026-09-18 15:08:00 +02:00
Proddy a4c8263bb7 Merge pull request #3243 from proddy/dev
auto release notes on dev changes
2026-09-18 15:06:16 +02:00
Proddy c5cdd94bd7 Merge branch 'emsesp:dev' into dev 2026-09-18 15:05:41 +02:00
proddy 755dc17b0d show diffs in dev releases 2026-09-18 14:43:51 +02:00
proddy 8bc2aaa9c1 package update 2026-09-18 14:43:38 +02:00
Jaano RosinandClaude Opus 5 5cc45b97bc fix: add 12 kW and 15 kW steps to enum_maxHeat
The heat limit registers on heat pumps using EMS_DEVICE_FLAG_HEATPUMP
(product 172/173) are bytes 2/3/4 of telegram 0x0492, read as a direct
index into enum_maxHeat. That table has only six entries, so any unit
whose auxiliary electric heater goes above 9 kW reports an index the
table cannot resolve.

Nothing bounds-checks the raw byte on the way in, and every render path
guards on `value < options_size`, so an out-of-range index is dropped
silently: no value is published to MQTT, the API omits the field, Home
Assistant shows `unknown`, and nothing appears in the log. Helpers::
value2enum stops at the same boundary, so the value cannot be written
back from EMS-ESP either, leaving the entity permanently stuck.

Measured on a Bosch Compress 7000i AW (CS7000iAW 13 OR-T, product 172)
with a 15 kW auxiliary heater, by setting each limit from the unit's own
display and reading telegram 0x0492 back:

    display 12 / 9 / 6 kW  ->  0x0492 data: 03 00 06 05 04

    raw  kW   note
      0   0   agrees with the existing table
      1   2   not offered by this heater
      2   3   not offered by this heater
      3   4   not offered by this heater
      4   6   agrees with the existing table
      5   9   agrees with the existing table
      6  12   new
      7  15   new

Indices 0, 4 and 5 match what EMS-ESP already decodes, which confirms the
existing entries and their ordering; the table was correct, just short.
The 2 kW and 4 kW entries belong to the 4-stufig (2/4/6/9 kW) heater
variant described in the HPC 410 service manual section 4.2.2, so a
3 kW-stepped heater simply skips them and walks 0, 3, 6, 9, 12, 15 kW,
i.e. raw 0, 2, 4, 5, 6, 7. The same sparse pattern is already encoded for
CS6800 devices in Boiler::process_HpHeaterConfig, which maps raw
{0, 2, 4, 5} onto {0, 3, 6, 9} kW.

Only devices carrying EMS_DEVICE_FLAG_HEATPUMP are affected; CS6800
devices use enum_maxHeat1/enum_maxHeat2 and are unchanged. Verified with
the standalone build: `test entity_dump` differs from the committed
docs/dump_entities.csv in exactly the six maxheat rows of products 172
and 173, and nowhere else.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 13:17:37 +03:00
HeatMind b2b98ef660 fix(weblog): guard against a weblog_buffer of 0 (pop_front on empty deque)
WebLogService::operator<< trims with `log_messages_.size() >= limit_log_messages_`.
size() is unsigned, so with limit_log_messages_ == 0 the condition holds even for an
empty deque and pop_front() runs on it - undefined behaviour, in practice heap
corruption. On a PSRAM board the stored value survives a reboot, so the device crashes
again as soon as the first log message is written.

Nothing clamps the value on the way in: start() copies settings.weblog_buffer with no
lower bound, the PSRAM branch of operator<< passes it straight into
limit_log_messages_, and ArduinoJson's | in WebSettings::update() only substitutes the
default for a missing or type-incompatible key - a stored 0 is a valid uint16_t.

- operator<<: skip the trim loop on an empty deque
- start(): keep the existing default when the stored value is 0
- getSetValues(): a missing or zero max_messages keeps the current size instead of
  storing 0
- WebSettings::update(): repair a stored 0, and derive the psram/no-psram default once
  instead of twice

Refs #3237
2026-09-15 09:13:24 +02:00
14 changed files with 444 additions and 324 deletions
+25
View File
@@ -29,6 +29,8 @@ jobs:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v6 uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Install pnpm - name: Install pnpm
run: npm install -g pnpm run: npm install -g pnpm
@@ -39,6 +41,13 @@ jobs:
version=`grep -E '^#define EMSESP_APP_VERSION' ./src/emsesp_version.h | awk -F'"' '{print $2}'` version=`grep -E '^#define EMSESP_APP_VERSION' ./src/emsesp_version.h | awk -F'"' '{print $2}'`
echo "VERSION=$version" >> $GITHUB_OUTPUT echo "VERSION=$version" >> $GITHUB_OUTPUT
# must run before the release moves the 'latest' tag to this build
- name: Find the previous dev release
id: previous
run: |
prev=`git rev-parse -q --verify 'refs/tags/latest^{commit}' || git describe --tags --abbrev=0 --match 'v*'`
echo "REF=$prev" >> $GITHUB_OUTPUT
- name: Install PlatformIO - name: Install PlatformIO
run: | run: |
python -m pip install --upgrade pip python -m pip install --upgrade pip
@@ -66,12 +75,28 @@ jobs:
with: with:
commit_message: "chore: update generated files for v${{steps.build_info.outputs.VERSION}}" commit_message: "chore: update generated files for v${{steps.build_info.outputs.VERSION}}"
# an empty body falls back to the commit list generated by the release action
- name: Build the release notes
id: notes
env:
PREV_REF: ${{ steps.previous.outputs.REF }}
VERSION: ${{ steps.build_info.outputs.VERSION }}
run: |
./scripts/release_notes.sh "$PREV_REF" "$VERSION" > release_notes.md || :
cat release_notes.md
{
echo 'BODY<<__RELEASE_NOTES_EOF__'
cat release_notes.md
echo '__RELEASE_NOTES_EOF__'
} >> $GITHUB_OUTPUT
- name: Create GitHub Release - name: Create GitHub Release
id: 'automatic_releases' id: 'automatic_releases'
uses: emsesp/action-automatic-releases@v1.0.1 uses: emsesp/action-automatic-releases@v1.0.1
with: with:
repo_token: '${{ secrets.GITHUB_TOKEN }}' repo_token: '${{ secrets.GITHUB_TOKEN }}'
title: Development Build v${{steps.build_info.outputs.VERSION}} title: Development Build v${{steps.build_info.outputs.VERSION}}
body: ${{ steps.notes.outputs.BODY }}
automatic_release_tag: 'latest' automatic_release_tag: 'latest'
prerelease: true prerelease: true
files: | files: |
+1
View File
@@ -33,6 +33,7 @@ This release is based on the latest Espressif/Arduino core version 3. It brings
- possible crash when the WebUI asked for version information while the versions.json refresh was rewriting the cache from the main loop task - possible crash when the WebUI asked for version information while the versions.json refresh was rewriting the cache from the main loop task
- HTTP client could write past a fixed 64 byte buffer when a URL had a hostname of 64 characters or more, could busy-spin for the whole read budget if the socket reported bytes it wouldn't return, and buffered responses without any size limit - HTTP client could write past a fixed 64 byte buffer when a URL had a hostname of 64 characters or more, could busy-spin for the whole read budget if the socket reported bytes it wouldn't return, and buffered responses without any size limit
- the "Ethernet clock mode (GPIO16/17) conflicts with PSRAM" error was never logged because Ethernet had already been skipped by the time the check ran - the "Ethernet clock mode (GPIO16/17) conflicts with PSRAM" error was never logged because Ethernet had already been skipped by the time the check ran
- heat limit entities (`maxheatcomp`, `maxheatheat`, `dhw.maxheat`) read as unknown on heat pumps with an auxiliary heater larger than 9 kW - `enum_maxHeat` was missing the 12 kW and 15 kW steps
## Changed ## Changed
+6 -6
View File
@@ -2763,9 +2763,9 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
"Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,hpin3opt,input 3 options,string (>=0<=0), ,true,sensor.boiler_input_3_options,sensor.boiler_hpin3opt,6,0,1,198,8 "Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,hpin3opt,input 3 options,string (>=0<=0), ,true,sensor.boiler_input_3_options,sensor.boiler_hpin3opt,6,0,1,198,8
"Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,hpin4,input 4 state,boolean, ,false,binary_sensor.boiler_input_4_state,binary_sensor.boiler_hpin4,6,0,1,206,1 "Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,hpin4,input 4 state,boolean, ,false,binary_sensor.boiler_input_4_state,binary_sensor.boiler_hpin4,6,0,1,206,1
"Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,hpin4opt,input 4 options,string (>=0<=0), ,true,sensor.boiler_input_4_options,sensor.boiler_hpin4opt,6,0,1,207,8 "Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,hpin4opt,input 4 options,string (>=0<=0), ,true,sensor.boiler_input_4_options,sensor.boiler_hpin4opt,6,0,1,207,8
"Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,maxheatcomp,heat limit compressor,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW] (>=0<=0), ,true,select.boiler_heat_limit_compressor,select.boiler_maxheatcomp,6,0,1,215,1 "Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,maxheatcomp,heat limit compressor,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW\|12 kW\|15 kW] (>=0<=0), ,true,select.boiler_heat_limit_compressor,select.boiler_maxheatcomp,6,0,1,215,1
"Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,maxheatheat,heat limit heating,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW] (>=0<=0), ,true,select.boiler_heat_limit_heating,select.boiler_maxheatheat,6,0,1,216,1 "Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,maxheatheat,heat limit heating,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW\|12 kW\|15 kW] (>=0<=0), ,true,select.boiler_heat_limit_heating,select.boiler_maxheatheat,6,0,1,216,1
"Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,dhw.maxheat,heat limit,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW] (>=0<=0), ,true,select.boiler_dhw_heat_limit,select.boiler_dhw_maxheat,6,9,1,14,1 "Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,dhw.maxheat,heat limit,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW\|12 kW\|15 kW] (>=0<=0), ,true,select.boiler_dhw_heat_limit,select.boiler_dhw_maxheat,6,9,1,14,1
"Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,auxheatersource,aux heater source,enum [not installed\|electric heater\|exclusive\|parallel\|hybrid] (>=0<=0), ,true,select.boiler_aux_heater_source,select.boiler_auxheatersource,6,0,1,217,1 "Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,auxheatersource,aux heater source,enum [not installed\|electric heater\|exclusive\|parallel\|hybrid] (>=0<=0), ,true,select.boiler_aux_heater_source,select.boiler_auxheatersource,6,0,1,217,1
"Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,pvcooling,cooling only with PV,boolean (>=0<=0), ,true,switch.boiler_cooling_only_with_PV,switch.boiler_pvcooling,6,0,1,218,1 "Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,pvcooling,cooling only with PV,boolean (>=0<=0), ,true,switch.boiler_cooling_only_with_PV,switch.boiler_pvcooling,6,0,1,218,1
"Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,auxheateronly,aux heater only,boolean (>=0<=0), ,true,switch.boiler_aux_heater_only,switch.boiler_auxheateronly,6,0,1,219,1 "Enviline, Compress 6000AW, Hybrid 3000-7000iAW, SupraEco/Geo 5xx, WLW196i/WSW196i",boiler,172,auxheateronly,aux heater only,boolean (>=0<=0), ,true,switch.boiler_aux_heater_only,switch.boiler_auxheateronly,6,0,1,219,1
@@ -2982,9 +2982,9 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
"Geo 5xx",boiler,173,hpin3opt,input 3 options,string (>=0<=0), ,true,sensor.boiler_input_3_options,sensor.boiler_hpin3opt,6,0,1,198,8 "Geo 5xx",boiler,173,hpin3opt,input 3 options,string (>=0<=0), ,true,sensor.boiler_input_3_options,sensor.boiler_hpin3opt,6,0,1,198,8
"Geo 5xx",boiler,173,hpin4,input 4 state,boolean, ,false,binary_sensor.boiler_input_4_state,binary_sensor.boiler_hpin4,6,0,1,206,1 "Geo 5xx",boiler,173,hpin4,input 4 state,boolean, ,false,binary_sensor.boiler_input_4_state,binary_sensor.boiler_hpin4,6,0,1,206,1
"Geo 5xx",boiler,173,hpin4opt,input 4 options,string (>=0<=0), ,true,sensor.boiler_input_4_options,sensor.boiler_hpin4opt,6,0,1,207,8 "Geo 5xx",boiler,173,hpin4opt,input 4 options,string (>=0<=0), ,true,sensor.boiler_input_4_options,sensor.boiler_hpin4opt,6,0,1,207,8
"Geo 5xx",boiler,173,maxheatcomp,heat limit compressor,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW] (>=0<=0), ,true,select.boiler_heat_limit_compressor,select.boiler_maxheatcomp,6,0,1,215,1 "Geo 5xx",boiler,173,maxheatcomp,heat limit compressor,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW\|12 kW\|15 kW] (>=0<=0), ,true,select.boiler_heat_limit_compressor,select.boiler_maxheatcomp,6,0,1,215,1
"Geo 5xx",boiler,173,maxheatheat,heat limit heating,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW] (>=0<=0), ,true,select.boiler_heat_limit_heating,select.boiler_maxheatheat,6,0,1,216,1 "Geo 5xx",boiler,173,maxheatheat,heat limit heating,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW\|12 kW\|15 kW] (>=0<=0), ,true,select.boiler_heat_limit_heating,select.boiler_maxheatheat,6,0,1,216,1
"Geo 5xx",boiler,173,dhw.maxheat,heat limit,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW] (>=0<=0), ,true,select.boiler_dhw_heat_limit,select.boiler_dhw_maxheat,6,9,1,14,1 "Geo 5xx",boiler,173,dhw.maxheat,heat limit,enum [0 kW\|2 kW\|3 kW\|4 kW\|6 kW\|9 kW\|12 kW\|15 kW] (>=0<=0), ,true,select.boiler_dhw_heat_limit,select.boiler_dhw_maxheat,6,9,1,14,1
"Geo 5xx",boiler,173,auxheatersource,aux heater source,enum [not installed\|electric heater\|exclusive\|parallel\|hybrid] (>=0<=0), ,true,select.boiler_aux_heater_source,select.boiler_auxheatersource,6,0,1,217,1 "Geo 5xx",boiler,173,auxheatersource,aux heater source,enum [not installed\|electric heater\|exclusive\|parallel\|hybrid] (>=0<=0), ,true,select.boiler_aux_heater_source,select.boiler_auxheatersource,6,0,1,217,1
"Geo 5xx",boiler,173,pvcooling,cooling only with PV,boolean (>=0<=0), ,true,switch.boiler_cooling_only_with_PV,switch.boiler_pvcooling,6,0,1,218,1 "Geo 5xx",boiler,173,pvcooling,cooling only with PV,boolean (>=0<=0), ,true,switch.boiler_cooling_only_with_PV,switch.boiler_pvcooling,6,0,1,218,1
"Geo 5xx",boiler,173,auxheateronly,aux heater only,boolean (>=0<=0), ,true,switch.boiler_aux_heater_only,switch.boiler_auxheateronly,6,0,1,219,1 "Geo 5xx",boiler,173,auxheateronly,aux heater only,boolean (>=0<=0), ,true,switch.boiler_aux_heater_only,switch.boiler_auxheateronly,6,0,1,219,1
Can't render this file because it is too large.
+4 -4
View File
@@ -35,14 +35,14 @@
"react": "^19.3.0", "react": "^19.3.0",
"react-dom": "^19.3.0", "react-dom": "^19.3.0",
"react-icons": "^5.7.0", "react-icons": "^5.7.0",
"react-router": "^8.3.1", "react-router": "^8.4.0",
"typesafe-i18n": "^5.27.1" "typesafe-i18n": "^5.27.1"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^10.0.1", "@eslint/js": "^10.0.1",
"@preact/preset-vite": "^2.10.6", "@preact/preset-vite": "^2.10.6",
"@trivago/prettier-plugin-sort-imports": "^6.0.2", "@trivago/prettier-plugin-sort-imports": "^6.0.2",
"@types/node": "^26.5.1", "@types/node": "^26.6.1",
"@types/react": "^19.3.0", "@types/react": "^19.3.0",
"@types/react-dom": "^19.3.0", "@types/react-dom": "^19.3.0",
"concurrently": "^10.0.5", "concurrently": "^10.0.5",
@@ -50,7 +50,7 @@
"eslint-config-prettier": "^10.1.8", "eslint-config-prettier": "^10.1.8",
"etag": "^1.8.1", "etag": "^1.8.1",
"mime-types": "^3.0.2", "mime-types": "^3.0.2",
"prettier": "^3.9.6", "prettier": "^3.9.7",
"rollup-plugin-visualizer": "^7.1.1", "rollup-plugin-visualizer": "^7.1.1",
"terser": "^5.51.2", "terser": "^5.51.2",
"typescript": "^6.0.3", "typescript": "^6.0.3",
@@ -58,5 +58,5 @@
"vite": "^8.3.0", "vite": "^8.3.0",
"vite-plugin-imagemin": "^0.6.1" "vite-plugin-imagemin": "^0.6.1"
}, },
"packageManager": "pnpm@12.4.1" "packageManager": "pnpm@12.4.2"
} }
+229 -223
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -15,7 +15,7 @@
}, },
"devDependencies": { "devDependencies": {
"@trivago/prettier-plugin-sort-imports": "^6.0.2", "@trivago/prettier-plugin-sort-imports": "^6.0.2",
"prettier": "^3.9.6" "prettier": "^3.9.7"
}, },
"packageManager": "pnpm@12.4.1" "packageManager": "pnpm@12.4.2"
} }
+73 -73
View File
@@ -7,153 +7,153 @@ importers:
configDependencies: {} configDependencies: {}
packageManagerDependencies: packageManagerDependencies:
pnpm: pnpm:
specifier: 12.4.1 specifier: 12.4.2
version: 12.4.1 version: 12.4.2
packages: packages:
'@pnpm/exe.android-arm64@12.4.1': '@pnpm/exe.android-arm64@12.4.2':
resolution: {integrity: sha512-/HwsqXMSmlOfgtV9+O0ratzjV6Vd/8n1hh4rGHpCGmDURvt52MwZxdbhyxP4K03ZfvgSDvotFPr8O+RzE5Eu8A==} resolution: {integrity: sha512-E255MbcQ0V1577M2BV0ajWuP7KmTPYA0jqZnk3rK6Lq3kTvZWulMMb7iqRmnLsQbyWTkMEB2CfyM70loVDA8xg==}
cpu: [arm64] cpu: [arm64]
os: [android] os: [android]
'@pnpm/exe.android-x64@12.4.1': '@pnpm/exe.android-x64@12.4.2':
resolution: {integrity: sha512-+l74Qb4c2YjOzNKHXJLg+1wr8xHM1ckkUhnU5KRUK9TJqiiczt6yeTZqqzHIlJ8i6pAoj5V0OJevDRwnQKLgrQ==} resolution: {integrity: sha512-J1pSeCUwuKxMG70ZzpWn8JzElxiEa8NN/3N0SlZRtU2xbztChaJCKF3HaBNIj9yPfeofWzJo/lwNvDDjraQuZw==}
cpu: [x64] cpu: [x64]
os: [android] os: [android]
'@pnpm/exe.darwin-arm64@12.4.1': '@pnpm/exe.darwin-arm64@12.4.2':
resolution: {integrity: sha512-6rkZkT3iGfaxknUdGHraqSWFvTa6N0ajAHluv9Ax0GRWs0sIcGNiFhDopv6xSZCsJZmG483aNS/b6UEDy3blfw==} resolution: {integrity: sha512-A0WDo8iErfZBXgrLseQxw8i8Y9ctUpOEl/Uu+cubnTzpD8tT9ykIB548L8YTM2WD4OS+ZOHSxy8aGZcvKq8PaQ==}
cpu: [arm64] cpu: [arm64]
os: [darwin] os: [darwin]
'@pnpm/exe.darwin-x64@12.4.1': '@pnpm/exe.darwin-x64@12.4.2':
resolution: {integrity: sha512-Vb1CHlR88HghC1qUxjxjs82zQSXnXacPD+btG2CmG8Q/hBU7Q0/b2YWJKSQqZXicunV5khFtfTlAwJddV9RkYA==} resolution: {integrity: sha512-MSgJdovBWHcb5DEOvfPH9yNi/T5O1Xa4ess+E1ESGo/5yuty7S4JoiIjami+fsNXfnoQMlwsMUqYU4zAvBcNCw==}
cpu: [x64] cpu: [x64]
os: [darwin] os: [darwin]
'@pnpm/exe.freebsd-x64@12.4.1': '@pnpm/exe.freebsd-x64@12.4.2':
resolution: {integrity: sha512-iT3iHz3Nl0Sxxj7UPOtZ/aQ81AFsQhjoeWMAlPkSRO04gsgDGAXv3UYxOFaesMWsfNxaGn0A+CITbuCHFF66FA==} resolution: {integrity: sha512-h2YumlQSNvgbRPv+RXwABohX65f9bOBZn+jMIt7bFDISZPCzQ+Nvpt6Awbp4ip5PwQgYxbu5iREJ1fHE39Fm8A==}
cpu: [x64] cpu: [x64]
os: [freebsd] os: [freebsd]
'@pnpm/exe.linux-arm64-musl@12.4.1': '@pnpm/exe.linux-arm64-musl@12.4.2':
resolution: {integrity: sha512-aBooZfNXM5f+OGUgCAMFWpE/kAhsWfvmqIyMtHy6zl3aNxyInWrcY/Saln/UElzo7lZWMC0Yktroxd/2J26lNQ==} resolution: {integrity: sha512-LwSEtSEDTv6S51YLs3YvSkPyun/QmfMic1UGICUkPWFu6ByP43RdMlkKvmVkfGhAYCpnxO057vrmyJqtfZrPCA==}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [musl] libc: [musl]
'@pnpm/exe.linux-arm64@12.4.1': '@pnpm/exe.linux-arm64@12.4.2':
resolution: {integrity: sha512-TlOdacTTP09BgcMvwWBFRsu8VAjfwqwnslBj+XSq1JFM3ck4f3k+1O/747EuctxZxs3/o785b6Q3s7Pd92Ptsg==} resolution: {integrity: sha512-2dSiDXyhx+RTHsewxex8f/jVjqQXWJ2oow4kCVHEWdZKeBpgMxvZ6fHkTAUBJXgqhbKIDHvuNlZBP7gJfUWL5A==}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [glibc] libc: [glibc]
'@pnpm/exe.linux-ppc64@12.4.1': '@pnpm/exe.linux-ppc64@12.4.2':
resolution: {integrity: sha512-r/ab/MlIBo75oizUP5ITiziCCrnXz4SJwfErLQ+603AshB+Yq7xTMCoMtzTSCAMu6aaymIKkAFtZvd2J75Wq0w==} resolution: {integrity: sha512-8Itc+jQk+MTz04LS9D1RcH+VctAWmzM4l1cJQ+Sx7pAJNo7EKHdRMbC0Tok1jyQ7eEHNJZD5EleYneZqWfZM+g==}
cpu: [ppc64] cpu: [ppc64]
os: [linux] os: [linux]
libc: [glibc] libc: [glibc]
'@pnpm/exe.linux-riscv64@12.4.1': '@pnpm/exe.linux-riscv64@12.4.2':
resolution: {integrity: sha512-C/D1QWdKMiB8+wv/spl1rGITFUuqC+aI/fb6h8NB5sqxsOaGXeYc/g891oCuzggHn6SODk9p+I09hI76x/cMNw==} resolution: {integrity: sha512-hleOeqhTVpH+z9RVMGnxvU4ZnrkBUClWjCbHD9u6kwyqhGSpevoU1wTGish+CBRhmIgMAy9pAfFpqhbAKOKNfw==}
cpu: [riscv64] cpu: [riscv64]
os: [linux] os: [linux]
libc: [glibc] libc: [glibc]
'@pnpm/exe.linux-s390x@12.4.1': '@pnpm/exe.linux-s390x@12.4.2':
resolution: {integrity: sha512-nxz5zD4yXt94uzbStDk0QTPKW+aE92hH1b5tFXK9ctB1HE9Xcq1vjTiA2LsZMFC6p4gdu5OwQeFqYNAVGa6QlA==} resolution: {integrity: sha512-LAsQRRdP9aToENR6dtcIJ9l+e1zMYOX0tQcLGpRyLPVBQcYRLlvAPcmDshsiIHQjp05SDa9FI0czX1ZQ1a7a/A==}
cpu: [s390x] cpu: [s390x]
os: [linux] os: [linux]
libc: [glibc] libc: [glibc]
'@pnpm/exe.linux-x64-musl@12.4.1': '@pnpm/exe.linux-x64-musl@12.4.2':
resolution: {integrity: sha512-5AwgFdGhVUg2kIweYGfxzSLEHiIG77PQhZAkXC3TwofQHsu1Wr+TrV5/rNX2PopFnHRzuE581zoB8F6Wle32yg==} resolution: {integrity: sha512-kzfzH2/0BWdTABK14Yj5a1xsdkTEQUp2eXEPNakaD9jKL025lq3hyaKHIz/gIZaPDMe/1bFFK/En4ztFlbBJxw==}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [musl] libc: [musl]
'@pnpm/exe.linux-x64@12.4.1': '@pnpm/exe.linux-x64@12.4.2':
resolution: {integrity: sha512-FJOZuuuQMhp0oLzBtcKkLXknBI92hfkmSnlKc47vfin4HrmfID5khY2lGekL9tCzk1cpR+HShEw/meFl+nHtzQ==} resolution: {integrity: sha512-/pbt0UVTa8NMDhzOWLQRfZ6G9ROKXlJPZtx845BqyWfc7hCrWXhTLBd70yO2y8+E+IWN3oHM1s/JsIQNGk1yvg==}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [glibc] libc: [glibc]
'@pnpm/exe.win32-arm64@12.4.1': '@pnpm/exe.win32-arm64@12.4.2':
resolution: {integrity: sha512-OO7eKBL9S+xk5hRy+JUUZSNJknGuGe3GEUffsrlC2LbqKF02g+VX1anGIzSbJDvkkdnpJhSlxF5AUz2JzJu2Jw==} resolution: {integrity: sha512-PsW19e4dAUNpZ0cS9flaxFuAmpt2dKlH/Vvi8TZ4qyJjjQzue/CEsWm+6wKVP4CJ7IT8RdL4qh+soOPWIgF2Zw==}
cpu: [arm64] cpu: [arm64]
os: [win32] os: [win32]
'@pnpm/exe.win32-x64@12.4.1': '@pnpm/exe.win32-x64@12.4.2':
resolution: {integrity: sha512-x7gJHZgHo6hp354xCYA2NvoFzYJkHwovt2kVsUBK5EmXULLcP51JGMq09CX+5FRFJUZFKoXjLu3mZWmfP7o6PQ==} resolution: {integrity: sha512-+xGoeE0g55ztWvl8i5QqdmNfW3nIrTVcoQrNshEOwxthm9Ag48oXton3uxOA3/SANyz5AXexEjj2KO20NnOrEw==}
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
pnpm@12.4.1: pnpm@12.4.2:
resolution: {integrity: sha512-LoHjmdc/6DkNqyXgaqeIq3pZCCSNL1o3D4K0gRR6ano2e/gEj5pv22Rg8hpm8FQt7bi5TKLIcjWWdBkgsWVtTA==} resolution: {integrity: sha512-CK3GYTGAJ1x8ntraOdzwjJxhrU5+rzMKTzRh8QKw+QdCNFTRF/mOctR/7wYWBwZE17/8lzpqV/UJCm18NosHyQ==}
engines: {node: '>=18.*'} engines: {node: '>=18.*'}
hasBin: true hasBin: true
snapshots: snapshots:
'@pnpm/exe.android-arm64@12.4.1': '@pnpm/exe.android-arm64@12.4.2':
optional: true optional: true
'@pnpm/exe.android-x64@12.4.1': '@pnpm/exe.android-x64@12.4.2':
optional: true optional: true
'@pnpm/exe.darwin-arm64@12.4.1': '@pnpm/exe.darwin-arm64@12.4.2':
optional: true optional: true
'@pnpm/exe.darwin-x64@12.4.1': '@pnpm/exe.darwin-x64@12.4.2':
optional: true optional: true
'@pnpm/exe.freebsd-x64@12.4.1': '@pnpm/exe.freebsd-x64@12.4.2':
optional: true optional: true
'@pnpm/exe.linux-arm64-musl@12.4.1': '@pnpm/exe.linux-arm64-musl@12.4.2':
optional: true optional: true
'@pnpm/exe.linux-arm64@12.4.1': '@pnpm/exe.linux-arm64@12.4.2':
optional: true optional: true
'@pnpm/exe.linux-ppc64@12.4.1': '@pnpm/exe.linux-ppc64@12.4.2':
optional: true optional: true
'@pnpm/exe.linux-riscv64@12.4.1': '@pnpm/exe.linux-riscv64@12.4.2':
optional: true optional: true
'@pnpm/exe.linux-s390x@12.4.1': '@pnpm/exe.linux-s390x@12.4.2':
optional: true optional: true
'@pnpm/exe.linux-x64-musl@12.4.1': '@pnpm/exe.linux-x64-musl@12.4.2':
optional: true optional: true
'@pnpm/exe.linux-x64@12.4.1': '@pnpm/exe.linux-x64@12.4.2':
optional: true optional: true
'@pnpm/exe.win32-arm64@12.4.1': '@pnpm/exe.win32-arm64@12.4.2':
optional: true optional: true
'@pnpm/exe.win32-x64@12.4.1': '@pnpm/exe.win32-x64@12.4.2':
optional: true optional: true
pnpm@12.4.1: pnpm@12.4.2:
optionalDependencies: optionalDependencies:
'@pnpm/exe.android-arm64': 12.4.1 '@pnpm/exe.android-arm64': 12.4.2
'@pnpm/exe.android-x64': 12.4.1 '@pnpm/exe.android-x64': 12.4.2
'@pnpm/exe.darwin-arm64': 12.4.1 '@pnpm/exe.darwin-arm64': 12.4.2
'@pnpm/exe.darwin-x64': 12.4.1 '@pnpm/exe.darwin-x64': 12.4.2
'@pnpm/exe.freebsd-x64': 12.4.1 '@pnpm/exe.freebsd-x64': 12.4.2
'@pnpm/exe.linux-arm64': 12.4.1 '@pnpm/exe.linux-arm64': 12.4.2
'@pnpm/exe.linux-arm64-musl': 12.4.1 '@pnpm/exe.linux-arm64-musl': 12.4.2
'@pnpm/exe.linux-ppc64': 12.4.1 '@pnpm/exe.linux-ppc64': 12.4.2
'@pnpm/exe.linux-riscv64': 12.4.1 '@pnpm/exe.linux-riscv64': 12.4.2
'@pnpm/exe.linux-s390x': 12.4.1 '@pnpm/exe.linux-s390x': 12.4.2
'@pnpm/exe.linux-x64': 12.4.1 '@pnpm/exe.linux-x64': 12.4.2
'@pnpm/exe.linux-x64-musl': 12.4.1 '@pnpm/exe.linux-x64-musl': 12.4.2
'@pnpm/exe.win32-arm64': 12.4.1 '@pnpm/exe.win32-arm64': 12.4.2
'@pnpm/exe.win32-x64': 12.4.1 '@pnpm/exe.win32-x64': 12.4.2
--- ---
lockfileVersion: '9.0' lockfileVersion: '9.0'
@@ -175,10 +175,10 @@ importers:
devDependencies: devDependencies:
'@trivago/prettier-plugin-sort-imports': '@trivago/prettier-plugin-sort-imports':
specifier: ^6.0.2 specifier: ^6.0.2
version: 6.0.2(prettier@3.9.6) version: 6.0.2(prettier@3.9.7)
prettier: prettier:
specifier: ^3.9.6 specifier: ^3.9.7
version: 3.9.6 version: 3.9.7
packages: packages:
@@ -258,8 +258,8 @@ packages:
balanced-match@1.0.2: balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
brace-expansion@2.1.4: brace-expansion@2.1.7:
resolution: {integrity: sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==} resolution: {integrity: sha512-uZbew1NqdmPDTMJ8ah1y+b+9QEJrfkXFk3RcTQw3X0jW/xRUvFKsg1CfQdSYGdTbXZWExtU3J3ccxtnfw1Fi0g==}
debug@4.4.3: debug@4.4.3:
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
@@ -303,8 +303,8 @@ packages:
picocolors@1.1.1: picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
prettier@3.9.6: prettier@3.9.7:
resolution: {integrity: sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==} resolution: {integrity: sha512-T3mF5P7HFzZVLDQuCUNtJj6WK1pcpLMweMNUVwGb01bLNkH9AkKxtZvmInw8K6bnn2O3d6/5RHl6zSHiBAD0Og==}
engines: {node: '>=14'} engines: {node: '>=14'}
hasBin: true hasBin: true
@@ -373,7 +373,7 @@ snapshots:
'@msgpack/msgpack@3.1.3': {} '@msgpack/msgpack@3.1.3': {}
'@trivago/prettier-plugin-sort-imports@6.0.2(prettier@3.9.6)': '@trivago/prettier-plugin-sort-imports@6.0.2(prettier@3.9.7)':
dependencies: dependencies:
'@babel/generator': 7.29.8 '@babel/generator': 7.29.8
'@babel/parser': 7.29.8 '@babel/parser': 7.29.8
@@ -383,13 +383,13 @@ snapshots:
lodash-es: 4.18.1 lodash-es: 4.18.1
minimatch: 9.0.9 minimatch: 9.0.9
parse-imports-exports: 0.2.4 parse-imports-exports: 0.2.4
prettier: 3.9.6 prettier: 3.9.7
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
balanced-match@1.0.2: {} balanced-match@1.0.2: {}
brace-expansion@2.1.4: brace-expansion@2.1.7:
dependencies: dependencies:
balanced-match: 1.0.2 balanced-match: 1.0.2
@@ -409,7 +409,7 @@ snapshots:
minimatch@9.0.9: minimatch@9.0.9:
dependencies: dependencies:
brace-expansion: 2.1.4 brace-expansion: 2.1.7
ms@2.1.3: {} ms@2.1.3: {}
@@ -421,4 +421,4 @@ snapshots:
picocolors@1.1.1: {} picocolors@1.1.1: {}
prettier@3.9.6: {} prettier@3.9.7: {}
+72
View File
@@ -0,0 +1,72 @@
#!/usr/bin/env bash
#
# Builds the release body for a dev build and writes it to stdout.
#
# scripts/release_notes.sh <previous release ref> <version>
#
# The summary is the set of CHANGELOG_LATEST.md lines added since the previous
# dev release, kept under their own headings. The full changelog and the commit
# list follow, both collapsed.
set -euo pipefail
PREV_REF=${1:?usage: release_notes.sh <previous release ref> <version>}
VERSION=${2:?usage: release_notes.sh <previous release ref> <version>}
CHANGELOG=CHANGELOG_LATEST.md
REPO_URL="https://github.com/${GITHUB_REPOSITORY:-emsesp/EMS-ESP32}"
MAX_COMMITS=250
prev_version=$(git show "${PREV_REF}:src/emsesp_version.h" 2>/dev/null |
awk -F'"' '/EMSESP_APP_VERSION/ { print $2 }')
added=$(mktemp)
trap 'rm -f "${added}"' EXIT
git diff -U0 "${PREV_REF}..HEAD" -- "${CHANGELOG}" |
sed -n 's/^+\([^+].*\)/\1/p' >"${added}"
# walk the changelog so the added lines keep the order and headings they have there
summary=$(awk '
NR == FNR { if (NF) wanted[$0] = 1; next }
/^#+ / { sub(/^#+ /, ""); heading = $0; next }
$0 in wanted && !seen[$0]++ {
if (heading != shown) { printf "\n### %s\n\n", heading; shown = heading }
print
}
' "${added}" "${CHANGELOG}")
echo "Development build of EMS-ESP v${VERSION}."
echo
if [ -n "${summary}" ]; then
echo "## Changes since ${prev_version:-the previous dev build}"
echo "${summary}"
echo
elif [ -n "${prev_version}" ]; then
echo "No changelog entries were added since ${prev_version}, see the commits below."
echo
fi
echo "<details>"
echo "<summary>Full v${VERSION%%-*} changelog so far</summary>"
echo
sed '1,/^For more details go to/d' "${CHANGELOG}" | awk 'NF || seen { print; seen = 1 }'
echo
echo "</details>"
echo
count=$(git rev-list --no-merges --count "${PREV_REF}..HEAD")
echo "<details>"
echo "<summary>Commits (${count})</summary>"
echo
git log --no-merges --max-count="${MAX_COMMITS}" \
--pretty=format:"- [\`%h\`](${REPO_URL}/commit/%H) %s (%an)" "${PREV_REF}..HEAD"
echo
if [ "${count}" -gt "${MAX_COMMITS}" ]; then
echo
echo "... and $((count - MAX_COMMITS)) more."
fi
echo
echo "</details>"
echo
echo "[Compare all changes](${REPO_URL}/compare/${PREV_REF}...$(git rev-parse HEAD))"
+3 -1
View File
@@ -224,6 +224,8 @@ MAKE_NOTRANSLATION(3kW, "3 kW")
MAKE_NOTRANSLATION(4kW, "4 kW") MAKE_NOTRANSLATION(4kW, "4 kW")
MAKE_NOTRANSLATION(6kW, "6 kW") MAKE_NOTRANSLATION(6kW, "6 kW")
MAKE_NOTRANSLATION(9kW, "9 kW") MAKE_NOTRANSLATION(9kW, "9 kW")
MAKE_NOTRANSLATION(12kW, "12 kW")
MAKE_NOTRANSLATION(15kW, "15 kW")
MAKE_NOTRANSLATION(L1, "L1") MAKE_NOTRANSLATION(L1, "L1")
MAKE_NOTRANSLATION(L2, "L2") MAKE_NOTRANSLATION(L2, "L2")
MAKE_NOTRANSLATION(L3, "L3") MAKE_NOTRANSLATION(L3, "L3")
@@ -312,7 +314,7 @@ MAKE_ENUM(enum_comfort1, FL_(high_comfort), FL_(eco))
MAKE_ENUM(enum_comfort2, FL_(eco), FL_(high_comfort)) MAKE_ENUM(enum_comfort2, FL_(eco), FL_(high_comfort))
MAKE_ENUM(enum_flow, FL_(off), FL_(flow), FL_(bufferedflow), FL_(buffer), FL_(layeredbuffer)) MAKE_ENUM(enum_flow, FL_(off), FL_(flow), FL_(bufferedflow), FL_(buffer), FL_(layeredbuffer))
MAKE_ENUM(enum_reset, FL_(dash), FL_(maintenance), FL_(error), FL_(history), FL_(message), FL_(hp_error), FL_(burn_starts), FL_(factory)) MAKE_ENUM(enum_reset, FL_(dash), FL_(maintenance), FL_(error), FL_(history), FL_(message), FL_(hp_error), FL_(burn_starts), FL_(factory))
MAKE_ENUM(enum_maxHeat, FL_(0kW), FL_(2kW), FL_(3kW), FL_(4kW), FL_(6kW), FL_(9kW)) MAKE_ENUM(enum_maxHeat, FL_(0kW), FL_(2kW), FL_(3kW), FL_(4kW), FL_(6kW), FL_(9kW), FL_(12kW), FL_(15kW))
MAKE_ENUM(enum_maxHeat1, FL_(0kW), FL_(3kW), FL_(6kW), FL_(9kW)) MAKE_ENUM(enum_maxHeat1, FL_(0kW), FL_(3kW), FL_(6kW), FL_(9kW))
MAKE_ENUM(enum_maxHeat2, FL_(3kW), FL_(6kW), FL_(9kW)) MAKE_ENUM(enum_maxHeat2, FL_(3kW), FL_(6kW), FL_(9kW))
MAKE_ENUM(enum_pumpMode, FL_(proportional), FL_(deltaP1), FL_(deltaP2), FL_(deltaP3), FL_(deltaP4)) MAKE_ENUM(enum_pumpMode, FL_(proportional), FL_(deltaP1), FL_(deltaP2), FL_(deltaP3), FL_(deltaP4))
+3 -1
View File
@@ -1131,7 +1131,9 @@ void System::show_system(uuid::console::Shell & shell) {
// client and all the JSON work on this task, and a TLS handshake alone can want several KB // client and all the JSON work on this task, and a TLS handshake alone can want several KB
TaskHandle_t loop_task = xTaskGetHandle("loopTask"); TaskHandle_t loop_task = xTaskGetHandle("loopTask");
if (loop_task != nullptr) { if (loop_task != nullptr) {
shell.printfln(" Loop task stack min free/total: %u / %u bytes", (unsigned)uxTaskGetStackHighWaterMark(loop_task), (unsigned)getArduinoLoopTaskStackSize()); shell.printfln(" Loop task stack min free/total: %u / %u bytes",
(unsigned)uxTaskGetStackHighWaterMark(loop_task),
(unsigned)getArduinoLoopTaskStackSize());
} }
#endif #endif
shell.printfln(" App used/free: %lu KB / %lu KB", appUsed(), appFree()); shell.printfln(" App used/free: %lu KB / %lu KB", appUsed(), appFree());
+1 -1
View File
@@ -337,7 +337,7 @@ class Boiler : public EMSdevice {
double nrgWwF_; // double calculate for nrgWw double nrgWwF_; // double calculate for nrgWw
uint8_t nomPower_; uint8_t nomPower_;
int16_t tk1_; int16_t tk1_;
/* /*
// Hybrid heatpump with telegram 0xBB is readable and writeable in boiler and thermostat // Hybrid heatpump with telegram 0xBB is readable and writeable in boiler and thermostat
+1 -1
View File
@@ -1 +1 @@
#define EMSESP_APP_VERSION "3.9.0-dev.10" #define EMSESP_APP_VERSION "3.9.0-dev.11"
+18 -8
View File
@@ -44,10 +44,13 @@ void WebLogService::begin() {
// apply the user settings // apply the user settings
void WebLogService::start() { void WebLogService::start() {
EMSESP::webSettingsService.read([&](WebSettings & settings) { EMSESP::webSettingsService.read([&](WebSettings & settings) {
maximum_log_messages_ = settings.weblog_buffer; // a stored value of 0 would make limit_log_messages_ 0, see the guard in operator<<
limit_log_messages_ = maximum_log_messages_; if (settings.weblog_buffer) {
compact_ = settings.weblog_compact; maximum_log_messages_ = settings.weblog_buffer;
level_ = (uuid::log::Level)settings.weblog_level; }
limit_log_messages_ = maximum_log_messages_;
compact_ = settings.weblog_compact;
level_ = (uuid::log::Level)settings.weblog_level;
}); });
uuid::log::Logger::register_handler(this, level_); uuid::log::Logger::register_handler(this, level_);
if (level_ == uuid::log::Level::OFF) { if (level_ == uuid::log::Level::OFF) {
@@ -80,7 +83,9 @@ void WebLogService::operator<<(std::shared_ptr<uuid::log::Message> message) {
} }
} }
#endif #endif
while (log_messages_.size() >= limit_log_messages_) { // size() is unsigned, so with limit_log_messages_ == 0 this condition is always true
// and pop_front() would run on an empty deque (undefined behaviour)
while (!log_messages_.empty() && log_messages_.size() >= limit_log_messages_) {
log_messages_.pop_front(); log_messages_.pop_front();
} }
@@ -210,9 +215,14 @@ void WebLogService::getSetValues(AsyncWebServerRequest * request, JsonVariant js
} }
// POST - write the settings // POST - write the settings
level_ = json["level"]; level_ = json["level"];
maximum_log_messages_ = json["max_messages"]; // keep the current size if the key is missing or 0 - a 0 would be stored and make
compact_ = json["compact"]; // limit_log_messages_ 0 on the next boot
const size_t max_messages = json["max_messages"] | maximum_log_messages_;
if (max_messages) {
maximum_log_messages_ = max_messages;
}
compact_ = json["compact"];
uuid::log::Logger::register_handler(this, level_); uuid::log::Logger::register_handler(this, level_);
if (level_ == uuid::log::Level::OFF) { if (level_ == uuid::log::Level::OFF) {
+6 -4
View File
@@ -335,10 +335,12 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) {
settings.email_subject = root["email_subject"] | FACTORY_EMAIL_SUBJECT; settings.email_subject = root["email_subject"] | FACTORY_EMAIL_SUBJECT;
// if no psram limit weblog buffer to 25 messages // if no psram limit weblog buffer to 25 messages
if (EMSESP::system_.PSram() > 0) { const uint16_t weblog_buffer_default = (EMSESP::system_.PSram() > 0) ? EMSESP_DEFAULT_WEBLOG_BUFFER : 25;
settings.weblog_buffer = root["weblog_buffer"] | EMSESP_DEFAULT_WEBLOG_BUFFER; settings.weblog_buffer = root["weblog_buffer"] | weblog_buffer_default;
} else { // a stored 0 is a valid uint16 and passes the | default above, but would make
settings.weblog_buffer = root["weblog_buffer"] | 25; // limit to 25 messages if no psram // limit_log_messages_ 0 in WebLogService
if (settings.weblog_buffer == 0) {
settings.weblog_buffer = weblog_buffer_default;
} }
// save the settings if changed from the webUI // save the settings if changed from the webUI