This commit is contained in:
MichaelDvP
2025-10-24 09:45:10 +02:00
25 changed files with 6732 additions and 6286 deletions

View File

@@ -18,17 +18,17 @@ jobs:
steps:
- name: Install python 3.13
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: '3.13'
- name: Install Node.js 22
uses: actions/setup-node@v4
- name: Install Node.js 24
uses: actions/setup-node@v6
with:
node-version: 22
node-version: 24
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Enable Corepack
run: corepack enable pnpm
@@ -45,20 +45,48 @@ jobs:
pip install -U platformio
python -m pip install intelhex
- name: Build the WebUI
- name: Build webUI
run: |
cd interface
pnpm install
pnpm typesafe-i18n --no-watch
sed -i "s/= 'pl'/= 'en'/" ./src/i18n/i18n-util.ts
pnpm build
pnpm webUI
platformio run -e build_webUI
- name: Build all PIO target environments
- name: Build modbus
run: |
platformio run -e build_modbus
- name: Build standalone
run: |
platformio run -e build_standalone
- name: Build all PIO target environments, from default_envs
run: |
platformio run
env:
NO_BUILD_WEBUI: true
- name: Commit the generated files
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "chore: update generated files"
- name: Configure Git
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
- name: Check for changes and commit
run: |
if [ -n "$(git status --porcelain)" ]; then
echo "Changes detected, committing..."
git add .
git commit -m "Auto-commit build artifacts and configuration updates
- Updated build configurations
- Generated build artifacts
- Version: ${{steps.build_info.outputs.VERSION}}"
echo "Pushing changes to repository..."
git push origin dev
else
echo "No changes to commit"
fi
- name: Create GitHub Release
id: 'automatic_releases'

View File

@@ -20,12 +20,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Install python 3.11
uses: actions/setup-python@v5
- name: Install python 3.13
uses: actions/setup-python@v6
with:
python-version: '3.11'
python-version: '3.13'
- name: Install PlatformIO
run: |

View File

@@ -17,7 +17,7 @@ jobs:
BUILD_WRAPPER_OUT_DIR: bw-output
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Install Build Wrapper

View File

@@ -16,17 +16,17 @@ jobs:
steps:
- name: Install python 3.13
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: '3.13'
- name: Install Node.js 22
uses: actions/setup-node@v4
- name: Install Node.js 24
uses: actions/setup-node@v6
with:
node-version: 22
node-version: 24
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Enable Corepack
run: corepack enable pnpm
@@ -37,20 +37,21 @@ jobs:
pip install -U platformio
python -m pip install intelhex
- name: Build the WebUI
- name: Build webUI
run: |
cd interface
pnpm install
pnpm typesafe-i18n --no-watch
sed -i "s/= 'pl'/= 'en'/" ./src/i18n/i18n-util.ts
pnpm build
pnpm webUI
platformio run -e build_webUI
- name: Build all PIO target environments
- name: Build modbus
run: |
platformio run -e build_modbus
- name: Build standalone
run: |
platformio run -e build_standalone
- name: Build all PIO target environments, from default_envs
run: |
platformio run
env:
NO_BUILD_WEBUI: true
- name: Create GitHub Release
uses: emsesp/action-automatic-releases@v1.0.0

View File

@@ -1,4 +1,8 @@
name: "Mark or close stale issues and PRs"
permissions:
contents: read
issues: write
pull-requests: write
on:
schedule:
@@ -8,7 +12,7 @@ jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
- uses: actions/stale@v10
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 30

View File

@@ -4,7 +4,7 @@ on:
workflow_dispatch:
push:
branches:
- 'dev2'
- 'test'
permissions:
contents: read
@@ -18,17 +18,17 @@ jobs:
steps:
- name: Install python 3.13
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: '3.13'
- name: Install Node.js 22
uses: actions/setup-node@v4
- name: Install Node.js 24
uses: actions/setup-node@v6
with:
node-version: 22
node-version: 24
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Enable Corepack
run: corepack enable pnpm
@@ -45,20 +45,21 @@ jobs:
pip install -U platformio
python -m pip install intelhex
- name: Build the WebUI
- name: Build webUI
run: |
cd interface
pnpm install
pnpm typesafe-i18n --no-watch
sed -i "s/= 'pl'/= 'en'/" ./src/i18n/i18n-util.ts
pnpm build
pnpm webUI
platformio run -e build_webUI
- name: Build all target environments
- name: Build modbus
run: |
platformio run -e build_modbus
- name: Build standalone
run: |
platformio run -e build_standalone
- name: Build all PIO target environments, from default_envs
run: |
platformio run
env:
NO_BUILD_WEBUI: true
- name: Create GitHub Release
id: 'automatic_releases'

2
.gitignore vendored
View File

@@ -72,3 +72,5 @@ CMakeLists.txt
logs/*
sdkconfig.*
sdkconfig_tasmota_esp32
pnpm-lock.yaml
package.json

File diff suppressed because it is too large Load Diff

View File

@@ -1,231 +1,231 @@
telegram_type_id,name,is_fetched
0x04,UBAFactory,fetched
0x06,RCTime,
0x0A,EasyMonitor,fetched
0x10,UBAErrorMessage1,
0x11,UBAErrorMessage2,
0x12,RCErrorMessage,
0x13,RCErrorMessage2,
0x14,UBATotalUptime,fetched
0x15,UBAMaintenanceData,
0x16,UBAParameters,fetched
0x18,UBAMonitorFast,
0x19,UBAMonitorSlow,
0x1A,UBASetPoints,
0x1C,UBAMaintenanceStatus,
0x1E,HydrTemp,
0x23,JunkersSetMixer,fetched
0x27,UBASettingsWW,fetched
0x28,WeatherComp,fetched
0x2A,MC110Status,
0x2E,Meters,
0x33,UBAParameterWW,fetched
0x34,UBAMonitorWW,
0x35,UBAFlags,
0x37,WWSettings,fetched
0x38,WWTimer,fetched
0x39,WWCircTimer,fetched
0x3A,RC30WWSettings,fetched
0x3B,Energy,
0x3D,RC35Set,
0x3E,RC35Monitor,
0x3F,RC35Timer,
0x40,RC30Temp,
0x41,RC30Monitor,
0x42,RC35Timer2,
0x47,RC35Set,
0x48,RC35Monitor,
0x49,RC35Timer,
0x4C,RC35Timer2,
0x51,RC35Set,
0x52,RC35Monitor,
0x53,RC35Timer,
0x56,RC35Timer2,
0x5B,RC35Set,
0x5C,RC35Monitor,
0x5D,RC35Timer,
0x60,RC35Timer2,
0x96,SM10Config,fetched
0x97,SM10Monitor,
0x9C,WM10MonitorMessage,
0x9D,WM10SetMessage,
0xA2,RCError,
0xA3,RCOutdoorTemp,
0xA5,IBASettings,fetched
0xA7,RC30Set,
0xA9,RC30Vacation,fetched
0xAA,MMConfigMessage,fetched
0xAB,MMStatusMessage,
0xAC,MMSetMessage,
0xAF,RC20Remote,
0xB0,RC10Set,
0xB1,RC10Monitor,
0xBB,HybridSettings,fetched
0xBF,ErrorMessage,
0xC0,RCErrorMessage,
0xC2,UBAErrorMessage3,
0xC6,UBAErrorMessage3,
0xD1,UBAOutdoorTemp,
0xE3,UBAMonitorSlowPlus2,
0xE4,UBAMonitorFastPlus,
0xE5,UBAMonitorSlowPlus,
0xE6,UBAParametersPlus,fetched
0xE9,UBAMonitorWWPlus,
0xEA,UBAParameterWWPlus,fetched
0x0101,ISM1Set,fetched
0x0103,ISM1StatusMessage,fetched
0x0104,ISM2StatusMessage,
0x010C,IPMStatusMessage,
0x011E,JunkersDisp,fetched
0x012E,HPEnergy1,
0x013B,HPEnergy2,
0x0165,JunkersSet,
0x0166,JunkersSet,
0x0167,JunkersSet,
0x0168,JunkersSet,
0x016E,Absent,fetched
0x016F,JunkersMonitor,
0x0170,JunkersMonitor,
0x0171,JunkersMonitor,
0x0172,JunkersMonitor,
0x0179,JunkersSet,
0x017A,JunkersSet,
0x017B,JunkersSet,
0x017C,JunkersSet,
0x01D3,JunkersDhw,fetched
0x023A,RC300OutdoorTemp,fetched
0x023E,PVSettings,fetched
0x0240,RC300Settings,fetched
0x0241,RC300Settings,fetched
0x0267,RC300Floordry,
0x0269,RC300Holiday,fetched
0x0291,HPMode,fetched
0x0292,HPMode,fetched
0x0293,HPMode,fetched
0x0294,HPMode,fetched
0x029B,RC300Curves,
0x029C,RC300Curves,
0x029D,RC300Curves,
0x029E,RC300Curves,
0x029F,RC300Curves,
0x02A0,RC300Curves,
0x02A1,RC300Curves,
0x02A2,RC300Curves,
0x02A5,RC300Monitor,
0x02A6,RC300Monitor,
0x02A7,RC300Monitor,
0x02A8,RC300Monitor,
0x02A9,RC300Monitor,
0x02AA,RC300Monitor,
0x02AB,RC300Monitor,
0x02AC,RC300Monitor,
0x02AF,RC300Summer,
0x02B0,RC300Summer,
0x02B1,RC300Summer,
0x02B2,RC300Summer,
0x02B3,RC300Summer,
0x02B4,RC300Summer,
0x02B5,RC300Summer,
0x02B6,RC300Summer,
0x02B9,RC300Set,
0x02BA,RC300Set,
0x02BB,RC300Set,
0x02BC,RC300Set,
0x02BD,RC300Set,
0x02BE,RC300Set,
0x02BF,RC300Set,
0x02C0,RC300Set,
0x02CC,HPPressure,fetched
0x02CD,MMPLUSConfigMessage,fetched
0x02CE,RC300Set2,
0x02D0,RC300Set2,
0x02D2,RC300Set2,
0x02D6,HPPump2,fetched
0x02D7,MMPLUSStatusMessage,
0x02E0,UBASetPoints,
0x02F5,RC300WWmode,fetched
0x02F6,RC300WW2mode,fetched
0x0313,MMPLUSConfigMessage_WWC,fetched
0x031B,RC300WWtemp,fetched
0x031D,RC300WWmode2,
0x031E,RC300WWmode2,
0x0331,MMPLUSStatusMessage_WWC,
0x0358,SM100SystemConfig,fetched
0x035A,SM100CircuitConfig,fetched
0x035C,SM100HeatAssist,fetched
0x035D,SM100Circuit2Config,fetched
0x035F,SM100Config1,fetched
0x0361,SM100Differential,fetched
0x0362,SM100Monitor,
0x0363,SM100Monitor2,
0x0364,SM100Status,
0x0366,SM100Config,
0x036A,SM100Status2,
0x0380,SM100CollectorConfig,fetched
0x038E,SM100Energy,fetched
0x0391,SM100Time,fetched
0x043F,CRHolidays,fetched
0x0467,HPSet,
0x0468,HPSet,
0x0469,HPSet,
0x046A,HPSet,
0x0471,RC300Summer2,
0x0472,RC300Summer2,
0x0473,RC300Summer2,
0x0474,RC300Summer2,
0x0475,RC300Summer2,
0x0476,RC300Summer2,
0x0477,RC300Summer2,
0x0478,RC300Summer2,
0x047B,HP2,
0x0484,HPSilentMode,fetched
0x0485,HpCooling,fetched
0x0486,HpInConfig,fetched
0x0488,HPValve,fetched
0x048A,HpPool,fetched
0x048B,HPPumps,fetched
0x048D,HpPower,fetched
0x048F,HpTemperatures,
0x0491,HPAdditionalHeater,fetched
0x0492,HpHeaterConfig,fetched
0x0494,UBAEnergySupplied,
0x0495,UBAInformation,
0x0499,HPDhwSettings,fetched
0x049C,HPSettings2,fetched
0x049D,HPSettings3,fetched
0x04A2,HpInput,fetched
0x04A5,HPFan,fetched
0x04A7,HPPowerLimit,fetched
0x04AA,HPPower2,fetched
0x04AE,HPEnergy,fetched
0x04AF,HPMeters,fetched
0x055C,VentilationSet,fetched
0x056B,VentilationMode,fetched
0x0583,VentilationMonitor,
0x0585,Blowerspeed,
0x0587,Bypass,
0x05BA,HpPoolStatus,fetched
0x05D9,Airquality,
0x0772,HIUSettings,
0x0779,HIUMonitor,
0x07A5,SM100wwCirc,fetched
0x07A6,SM100wwParam,fetched
0x07AA,SM100wwStatus,
0x07AB,SM100wwCommand,
0x07AC,SM100wwParam1,
0x07AD,SM100ValveStatus,
0x07AE,SM100wwKeepWarm,fetched
0x07D6,SM100wwTemperature,
0x07E0,SM100wwStatus2,fetched
0x0935,EM100SetMessage,fetched
0x0936,EM100OutMessage,
0x0937,EM100TempMessage,
0x0938,EM100InputMessage,
0x0939,EM100MonitorMessage,
0x093A,EM100ConfigMessage,
0x0998,HPSettings,fetched
0x0999,HPFunctionTest,fetched
0x099A,HPStarts,
0x099B,HPFlowTemp,
0x099C,HPComp,
0x09A0,HPTemperature,
telegram_type_id,name,is_fetched
0x04,UBAFactory,fetched
0x06,RCTime,
0x0A,EasyMonitor,fetched
0x10,UBAErrorMessage1,
0x11,UBAErrorMessage2,
0x12,RCErrorMessage,
0x13,RCErrorMessage2,
0x14,UBATotalUptime,fetched
0x15,UBAMaintenanceData,
0x16,UBAParameters,fetched
0x18,UBAMonitorFast,
0x19,UBAMonitorSlow,
0x1A,UBASetPoints,
0x1C,UBAMaintenanceStatus,
0x1E,HydrTemp,
0x23,JunkersSetMixer,fetched
0x27,UBASettingsWW,fetched
0x28,WeatherComp,fetched
0x2A,MC110Status,
0x2E,Meters,
0x33,UBAParameterWW,fetched
0x34,UBAMonitorWW,
0x35,UBAFlags,
0x37,WWSettings,fetched
0x38,WWTimer,fetched
0x39,WWCircTimer,fetched
0x3A,RC30WWSettings,fetched
0x3B,Energy,
0x3D,RC35Set,
0x3E,RC35Monitor,
0x3F,RC35Timer,
0x40,RC30Temp,
0x41,RC30Monitor,
0x42,RC35Timer2,
0x47,RC35Set,
0x48,RC35Monitor,
0x49,RC35Timer,
0x4C,RC35Timer2,
0x51,RC35Set,
0x52,RC35Monitor,
0x53,RC35Timer,
0x56,RC35Timer2,
0x5B,RC35Set,
0x5C,RC35Monitor,
0x5D,RC35Timer,
0x60,RC35Timer2,
0x96,SM10Config,fetched
0x97,SM10Monitor,
0x9C,WM10MonitorMessage,
0x9D,WM10SetMessage,
0xA2,RCError,
0xA3,RCOutdoorTemp,
0xA5,IBASettings,fetched
0xA7,RC30Set,
0xA9,RC30Vacation,fetched
0xAA,MMConfigMessage,fetched
0xAB,MMStatusMessage,
0xAC,MMSetMessage,
0xAF,RC20Remote,
0xB0,RC10Set,
0xB1,RC10Monitor,
0xBB,HybridSettings,fetched
0xBF,ErrorMessage,
0xC0,RCErrorMessage,
0xC2,UBAErrorMessage3,
0xC6,UBAErrorMessage3,
0xD1,UBAOutdoorTemp,
0xE3,UBAMonitorSlowPlus2,
0xE4,UBAMonitorFastPlus,
0xE5,UBAMonitorSlowPlus,
0xE6,UBAParametersPlus,fetched
0xE9,UBAMonitorWWPlus,
0xEA,UBAParameterWWPlus,fetched
0x0101,ISM1Set,fetched
0x0103,ISM1StatusMessage,fetched
0x0104,ISM2StatusMessage,
0x010C,IPMStatusMessage,
0x011E,JunkersDisp,fetched
0x012E,HPEnergy1,
0x013B,HPEnergy2,
0x0165,JunkersSet,
0x0166,JunkersSet,
0x0167,JunkersSet,
0x0168,JunkersSet,
0x016E,Absent,fetched
0x016F,JunkersMonitor,
0x0170,JunkersMonitor,
0x0171,JunkersMonitor,
0x0172,JunkersMonitor,
0x0179,JunkersSet,
0x017A,JunkersSet,
0x017B,JunkersSet,
0x017C,JunkersSet,
0x01D3,JunkersDhw,fetched
0x023A,RC300OutdoorTemp,fetched
0x023E,PVSettings,fetched
0x0240,RC300Settings,fetched
0x0241,RC300Settings,fetched
0x0267,RC300Floordry,
0x0269,RC300Holiday,fetched
0x0291,HPMode,fetched
0x0292,HPMode,fetched
0x0293,HPMode,fetched
0x0294,HPMode,fetched
0x029B,RC300Curves,
0x029C,RC300Curves,
0x029D,RC300Curves,
0x029E,RC300Curves,
0x029F,RC300Curves,
0x02A0,RC300Curves,
0x02A1,RC300Curves,
0x02A2,RC300Curves,
0x02A5,RC300Monitor,
0x02A6,RC300Monitor,
0x02A7,RC300Monitor,
0x02A8,RC300Monitor,
0x02A9,RC300Monitor,
0x02AA,RC300Monitor,
0x02AB,RC300Monitor,
0x02AC,RC300Monitor,
0x02AF,RC300Summer,
0x02B0,RC300Summer,
0x02B1,RC300Summer,
0x02B2,RC300Summer,
0x02B3,RC300Summer,
0x02B4,RC300Summer,
0x02B5,RC300Summer,
0x02B6,RC300Summer,
0x02B9,RC300Set,
0x02BA,RC300Set,
0x02BB,RC300Set,
0x02BC,RC300Set,
0x02BD,RC300Set,
0x02BE,RC300Set,
0x02BF,RC300Set,
0x02C0,RC300Set,
0x02CC,HPPressure,fetched
0x02CD,MMPLUSConfigMessage,fetched
0x02CE,RC300Set2,
0x02D0,RC300Set2,
0x02D2,RC300Set2,
0x02D6,HPPump2,fetched
0x02D7,MMPLUSStatusMessage,
0x02E0,UBASetPoints,
0x02F5,RC300WWmode,fetched
0x02F6,RC300WW2mode,fetched
0x0313,MMPLUSConfigMessage_WWC,fetched
0x031B,RC300WWtemp,fetched
0x031D,RC300WWmode2,
0x031E,RC300WWmode2,
0x0331,MMPLUSStatusMessage_WWC,
0x0358,SM100SystemConfig,fetched
0x035A,SM100CircuitConfig,fetched
0x035C,SM100HeatAssist,fetched
0x035D,SM100Circuit2Config,fetched
0x035F,SM100Config1,fetched
0x0361,SM100Differential,fetched
0x0362,SM100Monitor,
0x0363,SM100Monitor2,
0x0364,SM100Status,
0x0366,SM100Config,
0x036A,SM100Status2,
0x0380,SM100CollectorConfig,fetched
0x038E,SM100Energy,fetched
0x0391,SM100Time,fetched
0x043F,CRHolidays,fetched
0x0467,HPSet,
0x0468,HPSet,
0x0469,HPSet,
0x046A,HPSet,
0x0471,RC300Summer2,
0x0472,RC300Summer2,
0x0473,RC300Summer2,
0x0474,RC300Summer2,
0x0475,RC300Summer2,
0x0476,RC300Summer2,
0x0477,RC300Summer2,
0x0478,RC300Summer2,
0x047B,HP2,
0x0484,HPSilentMode,fetched
0x0485,HpCooling,fetched
0x0486,HpInConfig,fetched
0x0488,HPValve,fetched
0x048A,HpPool,fetched
0x048B,HPPumps,fetched
0x048D,HpPower,fetched
0x048F,HpTemperatures,
0x0491,HPAdditionalHeater,fetched
0x0492,HpHeaterConfig,fetched
0x0494,UBAEnergySupplied,
0x0495,UBAInformation,
0x0499,HPDhwSettings,fetched
0x049C,HPSettings2,fetched
0x049D,HPSettings3,fetched
0x04A2,HpInput,fetched
0x04A5,HPFan,fetched
0x04A7,HPPowerLimit,fetched
0x04AA,HPPower2,fetched
0x04AE,HPEnergy,fetched
0x04AF,HPMeters,fetched
0x055C,VentilationSet,fetched
0x056B,VentilationMode,fetched
0x0583,VentilationMonitor,
0x0585,Blowerspeed,
0x0587,Bypass,
0x05BA,HpPoolStatus,fetched
0x05D9,Airquality,
0x0772,HIUSettings,
0x0779,HIUMonitor,
0x07A5,SM100wwCirc,fetched
0x07A6,SM100wwParam,fetched
0x07AA,SM100wwStatus,
0x07AB,SM100wwCommand,
0x07AC,SM100wwParam1,
0x07AD,SM100ValveStatus,
0x07AE,SM100wwKeepWarm,fetched
0x07D6,SM100wwTemperature,
0x07E0,SM100wwStatus2,fetched
0x0935,EM100SetMessage,fetched
0x0936,EM100OutMessage,
0x0937,EM100TempMessage,
0x0938,EM100InputMessage,
0x0939,EM100MonitorMessage,
0x093A,EM100ConfigMessage,
0x0998,HPSettings,fetched
0x0999,HPFunctionTest,fetched
0x099A,HPStarts,
0x099B,HPFlowTemp,
0x099C,HPComp,
0x09A0,HPTemperature,
1 telegram_type_id name is_fetched
2 0x04 UBAFactory fetched
3 0x06 RCTime
4 0x0A EasyMonitor fetched
5 0x10 UBAErrorMessage1
6 0x11 UBAErrorMessage2
7 0x12 RCErrorMessage
8 0x13 RCErrorMessage2
9 0x14 UBATotalUptime fetched
10 0x15 UBAMaintenanceData
11 0x16 UBAParameters fetched
12 0x18 UBAMonitorFast
13 0x19 UBAMonitorSlow
14 0x1A UBASetPoints
15 0x1C UBAMaintenanceStatus
16 0x1E HydrTemp
17 0x23 JunkersSetMixer fetched
18 0x27 UBASettingsWW fetched
19 0x28 WeatherComp fetched
20 0x2A MC110Status
21 0x2E Meters
22 0x33 UBAParameterWW fetched
23 0x34 UBAMonitorWW
24 0x35 UBAFlags
25 0x37 WWSettings fetched
26 0x38 WWTimer fetched
27 0x39 WWCircTimer fetched
28 0x3A RC30WWSettings fetched
29 0x3B Energy
30 0x3D RC35Set
31 0x3E RC35Monitor
32 0x3F RC35Timer
33 0x40 RC30Temp
34 0x41 RC30Monitor
35 0x42 RC35Timer2
36 0x47 RC35Set
37 0x48 RC35Monitor
38 0x49 RC35Timer
39 0x4C RC35Timer2
40 0x51 RC35Set
41 0x52 RC35Monitor
42 0x53 RC35Timer
43 0x56 RC35Timer2
44 0x5B RC35Set
45 0x5C RC35Monitor
46 0x5D RC35Timer
47 0x60 RC35Timer2
48 0x96 SM10Config fetched
49 0x97 SM10Monitor
50 0x9C WM10MonitorMessage
51 0x9D WM10SetMessage
52 0xA2 RCError
53 0xA3 RCOutdoorTemp
54 0xA5 IBASettings fetched
55 0xA7 RC30Set
56 0xA9 RC30Vacation fetched
57 0xAA MMConfigMessage fetched
58 0xAB MMStatusMessage
59 0xAC MMSetMessage
60 0xAF RC20Remote
61 0xB0 RC10Set
62 0xB1 RC10Monitor
63 0xBB HybridSettings fetched
64 0xBF ErrorMessage
65 0xC0 RCErrorMessage
66 0xC2 UBAErrorMessage3
67 0xC6 UBAErrorMessage3
68 0xD1 UBAOutdoorTemp
69 0xE3 UBAMonitorSlowPlus2
70 0xE4 UBAMonitorFastPlus
71 0xE5 UBAMonitorSlowPlus
72 0xE6 UBAParametersPlus fetched
73 0xE9 UBAMonitorWWPlus
74 0xEA UBAParameterWWPlus fetched
75 0x0101 ISM1Set fetched
76 0x0103 ISM1StatusMessage fetched
77 0x0104 ISM2StatusMessage
78 0x010C IPMStatusMessage
79 0x011E JunkersDisp fetched
80 0x012E HPEnergy1
81 0x013B HPEnergy2
82 0x0165 JunkersSet
83 0x0166 JunkersSet
84 0x0167 JunkersSet
85 0x0168 JunkersSet
86 0x016E Absent fetched
87 0x016F JunkersMonitor
88 0x0170 JunkersMonitor
89 0x0171 JunkersMonitor
90 0x0172 JunkersMonitor
91 0x0179 JunkersSet
92 0x017A JunkersSet
93 0x017B JunkersSet
94 0x017C JunkersSet
95 0x01D3 JunkersDhw fetched
96 0x023A RC300OutdoorTemp fetched
97 0x023E PVSettings fetched
98 0x0240 RC300Settings fetched
99 0x0241 RC300Settings fetched
100 0x0267 RC300Floordry
101 0x0269 RC300Holiday fetched
102 0x0291 HPMode fetched
103 0x0292 HPMode fetched
104 0x0293 HPMode fetched
105 0x0294 HPMode fetched
106 0x029B RC300Curves
107 0x029C RC300Curves
108 0x029D RC300Curves
109 0x029E RC300Curves
110 0x029F RC300Curves
111 0x02A0 RC300Curves
112 0x02A1 RC300Curves
113 0x02A2 RC300Curves
114 0x02A5 RC300Monitor
115 0x02A6 RC300Monitor
116 0x02A7 RC300Monitor
117 0x02A8 RC300Monitor
118 0x02A9 RC300Monitor
119 0x02AA RC300Monitor
120 0x02AB RC300Monitor
121 0x02AC RC300Monitor
122 0x02AF RC300Summer
123 0x02B0 RC300Summer
124 0x02B1 RC300Summer
125 0x02B2 RC300Summer
126 0x02B3 RC300Summer
127 0x02B4 RC300Summer
128 0x02B5 RC300Summer
129 0x02B6 RC300Summer
130 0x02B9 RC300Set
131 0x02BA RC300Set
132 0x02BB RC300Set
133 0x02BC RC300Set
134 0x02BD RC300Set
135 0x02BE RC300Set
136 0x02BF RC300Set
137 0x02C0 RC300Set
138 0x02CC HPPressure fetched
139 0x02CD MMPLUSConfigMessage fetched
140 0x02CE RC300Set2
141 0x02D0 RC300Set2
142 0x02D2 RC300Set2
143 0x02D6 HPPump2 fetched
144 0x02D7 MMPLUSStatusMessage
145 0x02E0 UBASetPoints
146 0x02F5 RC300WWmode fetched
147 0x02F6 RC300WW2mode fetched
148 0x0313 MMPLUSConfigMessage_WWC fetched
149 0x031B RC300WWtemp fetched
150 0x031D RC300WWmode2
151 0x031E RC300WWmode2
152 0x0331 MMPLUSStatusMessage_WWC
153 0x0358 SM100SystemConfig fetched
154 0x035A SM100CircuitConfig fetched
155 0x035C SM100HeatAssist fetched
156 0x035D SM100Circuit2Config fetched
157 0x035F SM100Config1 fetched
158 0x0361 SM100Differential fetched
159 0x0362 SM100Monitor
160 0x0363 SM100Monitor2
161 0x0364 SM100Status
162 0x0366 SM100Config
163 0x036A SM100Status2
164 0x0380 SM100CollectorConfig fetched
165 0x038E SM100Energy fetched
166 0x0391 SM100Time fetched
167 0x043F CRHolidays fetched
168 0x0467 HPSet
169 0x0468 HPSet
170 0x0469 HPSet
171 0x046A HPSet
172 0x0471 RC300Summer2
173 0x0472 RC300Summer2
174 0x0473 RC300Summer2
175 0x0474 RC300Summer2
176 0x0475 RC300Summer2
177 0x0476 RC300Summer2
178 0x0477 RC300Summer2
179 0x0478 RC300Summer2
180 0x047B HP2
181 0x0484 HPSilentMode fetched
182 0x0485 HpCooling fetched
183 0x0486 HpInConfig fetched
184 0x0488 HPValve fetched
185 0x048A HpPool fetched
186 0x048B HPPumps fetched
187 0x048D HpPower fetched
188 0x048F HpTemperatures
189 0x0491 HPAdditionalHeater fetched
190 0x0492 HpHeaterConfig fetched
191 0x0494 UBAEnergySupplied
192 0x0495 UBAInformation
193 0x0499 HPDhwSettings fetched
194 0x049C HPSettings2 fetched
195 0x049D HPSettings3 fetched
196 0x04A2 HpInput fetched
197 0x04A5 HPFan fetched
198 0x04A7 HPPowerLimit fetched
199 0x04AA HPPower2 fetched
200 0x04AE HPEnergy fetched
201 0x04AF HPMeters fetched
202 0x055C VentilationSet fetched
203 0x056B VentilationMode fetched
204 0x0583 VentilationMonitor
205 0x0585 Blowerspeed
206 0x0587 Bypass
207 0x05BA HpPoolStatus fetched
208 0x05D9 Airquality
209 0x0772 HIUSettings
210 0x0779 HIUMonitor
211 0x07A5 SM100wwCirc fetched
212 0x07A6 SM100wwParam fetched
213 0x07AA SM100wwStatus
214 0x07AB SM100wwCommand
215 0x07AC SM100wwParam1
216 0x07AD SM100ValveStatus
217 0x07AE SM100wwKeepWarm fetched
218 0x07D6 SM100wwTemperature
219 0x07E0 SM100wwStatus2 fetched
220 0x0935 EM100SetMessage fetched
221 0x0936 EM100OutMessage
222 0x0937 EM100TempMessage
223 0x0938 EM100InputMessage
224 0x0939 EM100MonitorMessage
225 0x093A EM100ConfigMessage
226 0x0998 HPSettings fetched
227 0x0999 HPFunctionTest fetched
228 0x099A HPStarts
229 0x099B HPFlowTemp
230 0x099C HPComp
231 0x09A0 HPTemperature

View File

@@ -44,7 +44,7 @@
"typescript": "^5.9.3"
},
"devDependencies": {
"@babel/core": "^7.28.4",
"@babel/core": "^7.28.5",
"@eslint/js": "^9.38.0",
"@preact/compat": "^18.3.1",
"@preact/preset-vite": "^2.10.2",
@@ -59,7 +59,7 @@
"rollup-plugin-visualizer": "^6.0.5",
"terser": "^5.44.0",
"typescript-eslint": "^8.46.2",
"vite": "^7.1.11",
"vite": "^7.1.12",
"vite-plugin-imagemin": "^0.6.1",
"vite-tsconfig-paths": "^5.1.4"
},

182
interface/pnpm-lock.yaml generated
View File

@@ -70,8 +70,8 @@ importers:
version: 5.9.3
devDependencies:
'@babel/core':
specifier: ^7.28.4
version: 7.28.4
specifier: ^7.28.5
version: 7.28.5
'@eslint/js':
specifier: ^9.38.0
version: 9.38.0
@@ -80,7 +80,7 @@ importers:
version: 18.3.1(preact@10.27.2)
'@preact/preset-vite':
specifier: ^2.10.2
version: 2.10.2(@babel/core@7.28.4)(preact@10.27.2)(vite@7.1.11(@types/node@24.9.1)(terser@5.44.0))
version: 2.10.2(@babel/core@7.28.5)(preact@10.27.2)(vite@7.1.12(@types/node@24.9.1)(terser@5.44.0))
'@trivago/prettier-plugin-sort-imports':
specifier: ^5.2.2
version: 5.2.2(prettier@3.6.2)
@@ -115,14 +115,14 @@ importers:
specifier: ^8.46.2
version: 8.46.2(eslint@9.38.0)(typescript@5.9.3)
vite:
specifier: ^7.1.11
version: 7.1.11(@types/node@24.9.1)(terser@5.44.0)
specifier: ^7.1.12
version: 7.1.12(@types/node@24.9.1)(terser@5.44.0)
vite-plugin-imagemin:
specifier: ^0.6.1
version: 0.6.1(vite@7.1.11(@types/node@24.9.1)(terser@5.44.0))
version: 0.6.1(vite@7.1.12(@types/node@24.9.1)(terser@5.44.0))
vite-tsconfig-paths:
specifier: ^5.1.4
version: 5.1.4(typescript@5.9.3)(vite@7.1.11(@types/node@24.9.1)(terser@5.44.0))
version: 5.1.4(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.1)(terser@5.44.0))
packages:
@@ -138,16 +138,16 @@ packages:
resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==}
engines: {node: '>=6.9.0'}
'@babel/compat-data@7.28.4':
resolution: {integrity: sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==}
'@babel/compat-data@7.28.5':
resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==}
engines: {node: '>=6.9.0'}
'@babel/core@7.28.4':
resolution: {integrity: sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==}
'@babel/core@7.28.5':
resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==}
engines: {node: '>=6.9.0'}
'@babel/generator@7.28.3':
resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==}
'@babel/generator@7.28.5':
resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==}
engines: {node: '>=6.9.0'}
'@babel/helper-annotate-as-pure@7.27.3':
@@ -180,8 +180,8 @@ packages:
resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
engines: {node: '>=6.9.0'}
'@babel/helper-validator-identifier@7.27.1':
resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==}
'@babel/helper-validator-identifier@7.28.5':
resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
engines: {node: '>=6.9.0'}
'@babel/helper-validator-option@7.27.1':
@@ -192,8 +192,8 @@ packages:
resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==}
engines: {node: '>=6.9.0'}
'@babel/parser@7.28.4':
resolution: {integrity: sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==}
'@babel/parser@7.28.5':
resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==}
engines: {node: '>=6.0.0'}
hasBin: true
@@ -223,12 +223,12 @@ packages:
resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==}
engines: {node: '>=6.9.0'}
'@babel/traverse@7.28.4':
resolution: {integrity: sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==}
'@babel/traverse@7.28.5':
resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==}
engines: {node: '>=6.9.0'}
'@babel/types@7.28.4':
resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==}
'@babel/types@7.28.5':
resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==}
engines: {node: '>=6.9.0'}
'@emotion/babel-plugin@11.13.5':
@@ -1014,8 +1014,8 @@ packages:
base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
baseline-browser-mapping@2.8.19:
resolution: {integrity: sha512-zoKGUdu6vb2jd3YOq0nnhEDQVbPcHhco3UImJrv5dSkvxTc2pl2WjOPsjZXDwPDSl5eghIMuY3R6J9NDKF3KcQ==}
baseline-browser-mapping@2.8.20:
resolution: {integrity: sha512-JMWsdF+O8Orq3EMukbUN1QfbLK9mX2CkUmQBcW2T0s8OmdAUL5LLM/6wFwSrqXzlXB13yhyK9gTKS1rIizOduQ==}
hasBin: true
bin-build@3.0.0:
@@ -2976,8 +2976,8 @@ packages:
vite:
optional: true
vite@7.1.11:
resolution: {integrity: sha512-uzcxnSDVjAopEUjljkWh8EIrg6tlzrjFUfMcR1EVsRDGwf/ccef0qQPRyOrROwhrTDaApueq+ja+KLPlzR/zdg==}
vite@7.1.12:
resolution: {integrity: sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
peerDependencies:
@@ -3084,23 +3084,23 @@ snapshots:
'@babel/code-frame@7.27.1':
dependencies:
'@babel/helper-validator-identifier': 7.27.1
'@babel/helper-validator-identifier': 7.28.5
js-tokens: 4.0.0
picocolors: 1.1.1
'@babel/compat-data@7.28.4': {}
'@babel/compat-data@7.28.5': {}
'@babel/core@7.28.4':
'@babel/core@7.28.5':
dependencies:
'@babel/code-frame': 7.27.1
'@babel/generator': 7.28.3
'@babel/generator': 7.28.5
'@babel/helper-compilation-targets': 7.27.2
'@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4)
'@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5)
'@babel/helpers': 7.28.4
'@babel/parser': 7.28.4
'@babel/parser': 7.28.5
'@babel/template': 7.27.2
'@babel/traverse': 7.28.4
'@babel/types': 7.28.4
'@babel/traverse': 7.28.5
'@babel/types': 7.28.5
'@jridgewell/remapping': 2.3.5
convert-source-map: 2.0.0
debug: 4.4.3
@@ -3110,21 +3110,21 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@babel/generator@7.28.3':
'@babel/generator@7.28.5':
dependencies:
'@babel/parser': 7.28.4
'@babel/types': 7.28.4
'@babel/parser': 7.28.5
'@babel/types': 7.28.5
'@jridgewell/gen-mapping': 0.3.13
'@jridgewell/trace-mapping': 0.3.31
jsesc: 3.1.0
'@babel/helper-annotate-as-pure@7.27.3':
dependencies:
'@babel/types': 7.28.4
'@babel/types': 7.28.5
'@babel/helper-compilation-targets@7.27.2':
dependencies:
'@babel/compat-data': 7.28.4
'@babel/compat-data': 7.28.5
'@babel/helper-validator-option': 7.27.1
browserslist: 4.27.0
lru-cache: 5.1.1
@@ -3134,17 +3134,17 @@ snapshots:
'@babel/helper-module-imports@7.27.1':
dependencies:
'@babel/traverse': 7.28.4
'@babel/types': 7.28.4
'@babel/traverse': 7.28.5
'@babel/types': 7.28.5
transitivePeerDependencies:
- supports-color
'@babel/helper-module-transforms@7.28.3(@babel/core@7.28.4)':
'@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)':
dependencies:
'@babel/core': 7.28.4
'@babel/core': 7.28.5
'@babel/helper-module-imports': 7.27.1
'@babel/helper-validator-identifier': 7.27.1
'@babel/traverse': 7.28.4
'@babel/helper-validator-identifier': 7.28.5
'@babel/traverse': 7.28.5
transitivePeerDependencies:
- supports-color
@@ -3152,39 +3152,39 @@ snapshots:
'@babel/helper-string-parser@7.27.1': {}
'@babel/helper-validator-identifier@7.27.1': {}
'@babel/helper-validator-identifier@7.28.5': {}
'@babel/helper-validator-option@7.27.1': {}
'@babel/helpers@7.28.4':
dependencies:
'@babel/template': 7.27.2
'@babel/types': 7.28.4
'@babel/types': 7.28.5
'@babel/parser@7.28.4':
'@babel/parser@7.28.5':
dependencies:
'@babel/types': 7.28.4
'@babel/types': 7.28.5
'@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.4)':
'@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.5)':
dependencies:
'@babel/core': 7.28.4
'@babel/core': 7.28.5
'@babel/helper-plugin-utils': 7.27.1
'@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.28.4)':
'@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.28.5)':
dependencies:
'@babel/core': 7.28.4
'@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.4)
'@babel/core': 7.28.5
'@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.5)
transitivePeerDependencies:
- supports-color
'@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.4)':
'@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.5)':
dependencies:
'@babel/core': 7.28.4
'@babel/core': 7.28.5
'@babel/helper-annotate-as-pure': 7.27.3
'@babel/helper-module-imports': 7.27.1
'@babel/helper-plugin-utils': 7.27.1
'@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.4)
'@babel/types': 7.28.4
'@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5)
'@babel/types': 7.28.5
transitivePeerDependencies:
- supports-color
@@ -3193,25 +3193,25 @@ snapshots:
'@babel/template@7.27.2':
dependencies:
'@babel/code-frame': 7.27.1
'@babel/parser': 7.28.4
'@babel/types': 7.28.4
'@babel/parser': 7.28.5
'@babel/types': 7.28.5
'@babel/traverse@7.28.4':
'@babel/traverse@7.28.5':
dependencies:
'@babel/code-frame': 7.27.1
'@babel/generator': 7.28.3
'@babel/generator': 7.28.5
'@babel/helper-globals': 7.28.0
'@babel/parser': 7.28.4
'@babel/parser': 7.28.5
'@babel/template': 7.27.2
'@babel/types': 7.28.4
'@babel/types': 7.28.5
debug: 4.4.3
transitivePeerDependencies:
- supports-color
'@babel/types@7.28.4':
'@babel/types@7.28.5':
dependencies:
'@babel/helper-string-parser': 7.27.1
'@babel/helper-validator-identifier': 7.27.1
'@babel/helper-validator-identifier': 7.28.5
'@emotion/babel-plugin@11.13.5':
dependencies:
@@ -3575,18 +3575,18 @@ snapshots:
dependencies:
preact: 10.27.2
'@preact/preset-vite@2.10.2(@babel/core@7.28.4)(preact@10.27.2)(vite@7.1.11(@types/node@24.9.1)(terser@5.44.0))':
'@preact/preset-vite@2.10.2(@babel/core@7.28.5)(preact@10.27.2)(vite@7.1.12(@types/node@24.9.1)(terser@5.44.0))':
dependencies:
'@babel/core': 7.28.4
'@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.4)
'@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.4)
'@prefresh/vite': 2.4.10(preact@10.27.2)(vite@7.1.11(@types/node@24.9.1)(terser@5.44.0))
'@babel/core': 7.28.5
'@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.5)
'@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.5)
'@prefresh/vite': 2.4.10(preact@10.27.2)(vite@7.1.12(@types/node@24.9.1)(terser@5.44.0))
'@rollup/pluginutils': 4.2.1
babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.28.4)
babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.28.5)
debug: 4.4.3
picocolors: 1.1.1
vite: 7.1.11(@types/node@24.9.1)(terser@5.44.0)
vite-prerender-plugin: 0.5.12(vite@7.1.11(@types/node@24.9.1)(terser@5.44.0))
vite: 7.1.12(@types/node@24.9.1)(terser@5.44.0)
vite-prerender-plugin: 0.5.12(vite@7.1.12(@types/node@24.9.1)(terser@5.44.0))
transitivePeerDependencies:
- preact
- supports-color
@@ -3599,15 +3599,15 @@ snapshots:
'@prefresh/utils@1.2.1': {}
'@prefresh/vite@2.4.10(preact@10.27.2)(vite@7.1.11(@types/node@24.9.1)(terser@5.44.0))':
'@prefresh/vite@2.4.10(preact@10.27.2)(vite@7.1.12(@types/node@24.9.1)(terser@5.44.0))':
dependencies:
'@babel/core': 7.28.4
'@babel/core': 7.28.5
'@prefresh/babel-plugin': 0.5.2
'@prefresh/core': 1.5.8(preact@10.27.2)
'@prefresh/utils': 1.2.1
'@rollup/pluginutils': 4.2.1
preact: 10.27.2
vite: 7.1.11(@types/node@24.9.1)(terser@5.44.0)
vite: 7.1.12(@types/node@24.9.1)(terser@5.44.0)
transitivePeerDependencies:
- supports-color
@@ -3695,10 +3695,10 @@ snapshots:
'@trivago/prettier-plugin-sort-imports@5.2.2(prettier@3.6.2)':
dependencies:
'@babel/generator': 7.28.3
'@babel/parser': 7.28.4
'@babel/traverse': 7.28.4
'@babel/types': 7.28.4
'@babel/generator': 7.28.5
'@babel/parser': 7.28.5
'@babel/traverse': 7.28.5
'@babel/types': 7.28.5
javascript-natural-sort: 0.7.1
lodash: 4.17.21
prettier: 3.6.2
@@ -3928,15 +3928,15 @@ snapshots:
cosmiconfig: 7.1.0
resolve: 1.22.11
babel-plugin-transform-hook-names@1.0.2(@babel/core@7.28.4):
babel-plugin-transform-hook-names@1.0.2(@babel/core@7.28.5):
dependencies:
'@babel/core': 7.28.4
'@babel/core': 7.28.5
balanced-match@1.0.2: {}
base64-js@1.5.1: {}
baseline-browser-mapping@2.8.19: {}
baseline-browser-mapping@2.8.20: {}
bin-build@3.0.0:
dependencies:
@@ -3993,7 +3993,7 @@ snapshots:
browserslist@4.27.0:
dependencies:
baseline-browser-mapping: 2.8.19
baseline-browser-mapping: 2.8.20
caniuse-lite: 1.0.30001751
electron-to-chromium: 1.5.239
node-releases: 2.0.26
@@ -5935,7 +5935,7 @@ snapshots:
spdx-correct: 3.2.0
spdx-expression-parse: 3.0.1
vite-plugin-imagemin@0.6.1(vite@7.1.11(@types/node@24.9.1)(terser@5.44.0)):
vite-plugin-imagemin@0.6.1(vite@7.1.12(@types/node@24.9.1)(terser@5.44.0)):
dependencies:
'@types/imagemin': 7.0.1
'@types/imagemin-gifsicle': 7.0.4
@@ -5960,11 +5960,11 @@ snapshots:
imagemin-webp: 6.1.0
jpegtran-bin: 6.0.1
pathe: 0.2.0
vite: 7.1.11(@types/node@24.9.1)(terser@5.44.0)
vite: 7.1.12(@types/node@24.9.1)(terser@5.44.0)
transitivePeerDependencies:
- supports-color
vite-prerender-plugin@0.5.12(vite@7.1.11(@types/node@24.9.1)(terser@5.44.0)):
vite-prerender-plugin@0.5.12(vite@7.1.12(@types/node@24.9.1)(terser@5.44.0)):
dependencies:
kolorist: 1.8.0
magic-string: 0.30.19
@@ -5972,20 +5972,20 @@ snapshots:
simple-code-frame: 1.3.0
source-map: 0.7.6
stack-trace: 1.0.0-pre2
vite: 7.1.11(@types/node@24.9.1)(terser@5.44.0)
vite: 7.1.12(@types/node@24.9.1)(terser@5.44.0)
vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.1.11(@types/node@24.9.1)(terser@5.44.0)):
vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.1)(terser@5.44.0)):
dependencies:
debug: 4.4.3
globrex: 0.1.2
tsconfck: 3.1.6(typescript@5.9.3)
optionalDependencies:
vite: 7.1.11(@types/node@24.9.1)(terser@5.44.0)
vite: 7.1.12(@types/node@24.9.1)(terser@5.44.0)
transitivePeerDependencies:
- supports-color
- typescript
vite@7.1.11(@types/node@24.9.1)(terser@5.44.0):
vite@7.1.12(@types/node@24.9.1)(terser@5.44.0):
dependencies:
esbuild: 0.25.11
fdir: 6.5.0(picomatch@4.0.3)

View File

@@ -30,8 +30,8 @@ packages:
resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==}
engines: {node: '>=6.9.0'}
'@babel/generator@7.28.3':
resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==}
'@babel/generator@7.28.5':
resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==}
engines: {node: '>=6.9.0'}
'@babel/helper-globals@7.28.0':
@@ -42,12 +42,12 @@ packages:
resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
engines: {node: '>=6.9.0'}
'@babel/helper-validator-identifier@7.27.1':
resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==}
'@babel/helper-validator-identifier@7.28.5':
resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
engines: {node: '>=6.9.0'}
'@babel/parser@7.28.4':
resolution: {integrity: sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==}
'@babel/parser@7.28.5':
resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==}
engines: {node: '>=6.0.0'}
hasBin: true
@@ -55,12 +55,12 @@ packages:
resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==}
engines: {node: '>=6.9.0'}
'@babel/traverse@7.28.4':
resolution: {integrity: sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==}
'@babel/traverse@7.28.5':
resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==}
engines: {node: '>=6.9.0'}
'@babel/types@7.28.4':
resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==}
'@babel/types@7.28.5':
resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==}
engines: {node: '>=6.9.0'}
'@jridgewell/gen-mapping@0.3.13':
@@ -160,14 +160,14 @@ snapshots:
'@babel/code-frame@7.27.1':
dependencies:
'@babel/helper-validator-identifier': 7.27.1
'@babel/helper-validator-identifier': 7.28.5
js-tokens: 4.0.0
picocolors: 1.1.1
'@babel/generator@7.28.3':
'@babel/generator@7.28.5':
dependencies:
'@babel/parser': 7.28.4
'@babel/types': 7.28.4
'@babel/parser': 7.28.5
'@babel/types': 7.28.5
'@jridgewell/gen-mapping': 0.3.13
'@jridgewell/trace-mapping': 0.3.31
jsesc: 3.1.0
@@ -176,34 +176,34 @@ snapshots:
'@babel/helper-string-parser@7.27.1': {}
'@babel/helper-validator-identifier@7.27.1': {}
'@babel/helper-validator-identifier@7.28.5': {}
'@babel/parser@7.28.4':
'@babel/parser@7.28.5':
dependencies:
'@babel/types': 7.28.4
'@babel/types': 7.28.5
'@babel/template@7.27.2':
dependencies:
'@babel/code-frame': 7.27.1
'@babel/parser': 7.28.4
'@babel/types': 7.28.4
'@babel/parser': 7.28.5
'@babel/types': 7.28.5
'@babel/traverse@7.28.4':
'@babel/traverse@7.28.5':
dependencies:
'@babel/code-frame': 7.27.1
'@babel/generator': 7.28.3
'@babel/generator': 7.28.5
'@babel/helper-globals': 7.28.0
'@babel/parser': 7.28.4
'@babel/parser': 7.28.5
'@babel/template': 7.27.2
'@babel/types': 7.28.4
'@babel/types': 7.28.5
debug: 4.4.3
transitivePeerDependencies:
- supports-color
'@babel/types@7.28.4':
'@babel/types@7.28.5':
dependencies:
'@babel/helper-string-parser': 7.27.1
'@babel/helper-validator-identifier': 7.27.1
'@babel/helper-validator-identifier': 7.28.5
'@jridgewell/gen-mapping@0.3.13':
dependencies:
@@ -229,10 +229,10 @@ snapshots:
'@trivago/prettier-plugin-sort-imports@5.2.2(prettier@3.6.2)':
dependencies:
'@babel/generator': 7.28.3
'@babel/parser': 7.28.4
'@babel/traverse': 7.28.4
'@babel/types': 7.28.4
'@babel/generator': 7.28.5
'@babel/parser': 7.28.5
'@babel/traverse': 7.28.5
'@babel/types': 7.28.5
javascript-natural-sort: 0.7.1
lodash: 4.17.21
prettier: 3.6.2

View File

@@ -30,7 +30,7 @@ default_envs = debug
; uncomment if you want to upload the firmware via OTA (must have upload_protocol = custom)
extra_scripts =
pre:scripts/build_interface.py ; builds the WebUI (unless NO_BUILD_WEBUI is set) - comment out if you don't want to build each time
pre:scripts/build_interface.py ; builds the WebUI - comment out if you don't want to build each time
scripts/rename_fw.py ; renames the firmware .bin file - comment out if not needed
scripts/upload.py ; optionally upload the firmware via OTA (must have upload_protocol = custom)

View File

@@ -98,9 +98,9 @@ build_flags =
build_unflags =
${common.unbuild_flags}
extra_scripts =
pre:scripts/build_interface.py ; builds the WebUI (unless NO_BUILD_WEBUI is set)
; pre:scripts/build_interface.py ; builds the WebUI
scripts/rename_fw.py ; renames the firmware .bin file
scripts/upload.py ; optionally upload the firmware via OTA (if upload_protocol = custom)
; scripts/upload.py ; optionally upload the firmware via OTA (if upload_protocol = custom)
monitor_speed = 115200
monitor_filters = direct
build_type = release
@@ -111,11 +111,16 @@ lib_deps =
ESP32Async/ESPAsyncWebServer @ 3.8.1
https://github.com/emsesp/EMS-ESP-Modules.git @ 1.0.8
; builds the web interface only, not the firmware
[env:build_webUI]
platform = native
targets = build
extra_scripts = post:scripts/build_interface.py
;
; Builds for different board types
; We use Tasmota for boards without PSRAM as this framework has mbedtls removed to save memory.
;
; Note, if the system environment variable (windows or linux) "NO_BUILD_WEBUI" is set, the WebUI will not be built.
; If you're building for a single target environment, we recommend creating a pio_local.ini (see example file)
;
@@ -175,6 +180,7 @@ board = seeed_xiao_esp32c6
build_flags =
${common.build_flags}
-DBOARD_C6
;
; Building and testing natively, standalone without an ESP32.
; See https://docs.platformio.org/en/latest/platforms/native.html
@@ -193,15 +199,12 @@ build_flags =
;
[env:native]
platform = native
extra_scripts =
build_flags =
build_type = debug
build_src_flags =
-DARDUINOJSON_ENABLE_ARDUINO_STRING=1
-DEMSESP_STANDALONE -DEMSESP_TEST
-DEMSESP_DEFAULT_LOCALE=\"en\" -DEMSESP_DEFAULT_TX_MODE=8 -DEMSESP_DEFAULT_VERSION=\"3.7.3-dev.0\" -DEMSESP_DEFAULT_BOARD_PROFILE=\"S32\"
-std=gnu++17 -Og -ggdb
build_unflags = -std=gnu++11 -std=gnu++14
build_type = debug
build_src_flags =
-Wall -Wextra
-Wno-unused-parameter -Wno-sign-compare -Wno-missing-braces
-I./src/core
@@ -232,7 +235,6 @@ lib_deps =
; then re-run and capture the output between "START - CUT HERE" and "END - CUT HERE" into the test_api.h file
[env:native-test]
platform = native
extra_scripts =
test_build_src = true
build_flags =
; -DEMSESP_UNITY_CREATE
@@ -271,3 +273,30 @@ lib_ldf_mode = off
lib_deps = Unity
test_testing_command =
${platformio.build_dir}/${this.__env__}/program
# builds the modbus_entity_parameters.hpp header file
# pio run -e build_modbus -t build
[env:build_modbus]
extends = env:native
targets = build
extra_scripts =
pre:scripts/build_modbus_entity_parameters_pre.py
post:scripts/build_run_test.py
build_flags = -DEMSESP_MODBUS
custom_test_command = entity_dump
custom_output_file = dump_entities.csv
custom_post_script = scripts/build_modbus_entity_parameters_post.py
; builds the real dump_entities.csv and dump_telegrams.csv files
; and the Modbus-Entity-Registers.md file
; to be run after build_modbus with: pio run -e build_standalone -t clean -t build
[env:build_standalone]
extends = env:native
targets = build
extra_scripts =
post:scripts/build_run_test.py
build_flags = -DEMSESP_STANDALONE
custom_test_command = entity_dump
custom_output_file = dump_entities.csv
custom_post_script = scripts/build_modbus_generate_doc_post.py

View File

@@ -1,29 +1,120 @@
from pathlib import Path
import os
import subprocess
import shutil
Import("env")
def buildWeb():
os.chdir("interface")
print("Building web interface...")
def get_pnpm_executable():
"""Get the appropriate pnpm executable for the current platform."""
# Try different pnpm executable names
pnpm_names = ['pnpm', 'pnpm.cmd', 'pnpm.exe']
for name in pnpm_names:
if shutil.which(name):
return name
# Fallback to pnpm if not found
return 'pnpm'
def run_command_in_directory(command, directory):
"""Run a command in a specific directory."""
try:
env.Execute("pnpm install")
env.Execute("pnpm typesafe-i18n")
with open("./src/i18n/i18n-util.ts") as r:
text = r.read().replace("Locales = 'pl'", "Locales = 'en'")
with open("./src/i18n/i18n-util.ts", "w") as w:
w.write(text)
print("Setting WebUI locale to 'en'")
env.Execute("pnpm build")
env.Execute("pnpm webUI")
finally:
os.chdir("..")
result = subprocess.run(
command,
shell=True,
cwd=directory,
check=True,
capture_output=True,
text=True
)
if result.stdout:
print(result.stdout)
if result.stderr:
print(result.stderr)
return True
except subprocess.CalledProcessError as e:
print(f"Command failed: {command}")
print(f"Error: {e}")
if e.stdout:
print(f"Output: {e.stdout}")
if e.stderr:
print(f"Error output: {e.stderr}")
return False
except Exception as e:
print(f"Unexpected error running command '{command}': {e}")
return False
# Don't buuld webUI if called from GitHub Actions
if "NO_BUILD_WEBUI" in os.environ:
print("!! Skipping the build of the web interface !!")
else:
if not (env.IsCleanTarget()):
buildWeb()
def buildWeb():
interface_dir = Path("interface")
pnpm_exe = get_pnpm_executable()
# Set CI environment variable to make pnpm use silent mode
os.environ['CI'] = 'true'
print("Building web interface...")
# Check if interface directory exists
if not interface_dir.exists():
print(f"Error: Interface directory '{interface_dir}' not found!")
return False
# Check if pnpm is available
if not shutil.which(pnpm_exe):
print(f"Error: '{pnpm_exe}' not found in PATH!")
return False
try:
# Run pnpm commands in the interface directory
commands = [
f"{pnpm_exe} install",
f"{pnpm_exe} typesafe-i18n",
f"{pnpm_exe} build",
f"{pnpm_exe} webUI"
]
for command in commands:
print(f"Running: {command}")
if not run_command_in_directory(command, interface_dir):
return False
# Modify i18n-util.ts file
i18n_file = interface_dir / "src" / "i18n" / "i18n-util.ts"
if i18n_file.exists():
with open(i18n_file, 'r') as r:
text = r.read().replace("Locales = 'pl'", "Locales = 'en'")
with open(i18n_file, 'w') as w:
w.write(text)
print("Setting WebUI locale to 'en'")
else:
print(f"Warning: {i18n_file} not found, skipping locale modification")
print("Web interface build completed successfully!")
return True
except Exception as e:
print(f"Error building web interface: {e}")
return False
def build_webUI(*args, **kwargs):
success = buildWeb()
if not success:
print("Web interface build failed!")
env.Exit(1)
env.Exit(0)
# Create custom target that only runs the script
env.AddCustomTarget(
name="build",
dependencies=None,
actions=[build_webUI],
title="build web interface",
description="installs pnpm packages, updates libraries and builds web UI"
)

View File

@@ -0,0 +1,52 @@
import subprocess
import os
import sys
import shutil
from pathlib import Path
def get_python_executable():
"""Get the appropriate Python executable for the current platform."""
# Try different Python executable names
python_names = ['python3', 'python', 'py']
for name in python_names:
if shutil.which(name):
return name
# Fallback to sys.executable if available
return sys.executable
def csv_to_header(csv_file_path, header_file_path, script_path):
# Ensure the output directory exists
Path(header_file_path).parent.mkdir(parents=True, exist_ok=True)
# delete the output file if it exists
if os.path.exists(header_file_path):
os.remove(header_file_path)
# Read CSV file and pipe to Python script to generate header
python_exe = get_python_executable()
with open(csv_file_path, 'r') as csv_file:
with open(header_file_path, 'w') as header_file:
subprocess.run(
[python_exe, script_path],
stdin=csv_file,
stdout=header_file,
check=True
)
print(f"Generated header file: {header_file_path} ({os.path.getsize(header_file_path)} bytes)")
def main():
csv_file = os.path.join("docs", "dump_entities.csv")
header_file = os.path.join("src", "core", "modbus_entity_parameters.hpp")
script_file = os.path.join("scripts", "update_modbus_registers.py")
csv_to_header(csv_file, header_file, script_file)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,40 @@
from pathlib import Path
import os
Import("env")
def create_dummy_modbus_header():
"""Create a dummy modbus_entity_parameters.hpp so the first pass compiles."""
header_content = '''#include "modbus.h"
#include "emsdevice.h"
/*
* This file is auto-generated. Do not modify.
*/
// clang-format off
namespace emsesp {
using dt = EMSdevice::DeviceType;
#define REGISTER_MAPPING(device_type, device_value_tag_type, long_name, modbus_register_offset, modbus_register_count) \\
{ device_type, device_value_tag_type, long_name[0], modbus_register_offset, modbus_register_count }
// IMPORTANT: This list MUST be ordered by keys "device_type", "device_value_tag_type" and "modbus_register_offset" in this order.
const std::initializer_list<Modbus::EntityModbusInfo> Modbus::modbus_register_mappings = {};
} // namespace emsesp
// clang-format on
'''
header_path = Path("src") / "core" / "modbus_entity_parameters.hpp"
header_path.parent.mkdir(parents=True, exist_ok=True)
with open(header_path, 'w') as f:
f.write(header_content)
print(f"Created dummy header file: {header_path} ({os.path.getsize(header_path)} bytes)")
if not (env.IsCleanTarget()):
create_dummy_modbus_header()

View File

@@ -0,0 +1,64 @@
import subprocess
import os
import sys
import shutil
from pathlib import Path
# Import the streaming function from the separate module
from run_executable import run_with_streaming_input
def get_python_executable():
"""Get the appropriate Python executable for the current platform."""
# Try different Python executable names
python_names = ['python3', 'python', 'py']
for name in python_names:
if shutil.which(name):
return name
# Fallback to sys.executable if available
return sys.executable
def csv_to_md(csv_file_path, output_file_path, script_path):
# Ensure the output directory exists
Path(output_file_path).parent.mkdir(parents=True, exist_ok=True)
# delete the output file if it exists
if os.path.exists(output_file_path):
os.remove(output_file_path)
# Read CSV file and pipe to Python script to generate header
python_exe = get_python_executable()
with open(csv_file_path, 'r') as csv_file:
with open(output_file_path, 'w') as output_file:
subprocess.run(
[python_exe, script_path],
stdin=csv_file,
stdout=output_file,
check=True
)
print(f"Generated MD file: {output_file_path} ({os.path.getsize(output_file_path)} bytes)")
def main(program_path="./emsesp"):
csv_file = os.path.join("docs", "dump_entities.csv")
output_file = os.path.join("docs", "Modbus-Entity-Registers.md")
script_file = os.path.join("scripts", "generate-modbus-register-doc.py")
# generate the MD file
csv_to_md(csv_file, output_file, script_file)
# run the test command and generate the dump_telegrams.csv file
test_command = "test telegram_dump"
telegram_output_file = os.path.join("docs", "dump_telegrams.csv")
print(f"Running test command: telegram_dump > {telegram_output_file}")
run_with_streaming_input(program_path, test_command, telegram_output_file)
if __name__ == "__main__":
# Get program path from command line argument or use default
program_path = sys.argv[1] if len(sys.argv) > 1 else "./emsesp"
main(program_path)

46
scripts/build_run_test.py Executable file
View File

@@ -0,0 +1,46 @@
import os
import shutil
import subprocess
import sys
Import("env")
# Import the streaming function from the separate module
from run_executable import run_with_streaming_input
def get_python_executable():
"""Get the appropriate Python executable for the current platform."""
# Try different Python executable names
python_names = ['python3', 'python', 'py']
for name in python_names:
if shutil.which(name):
return name
# Fallback to sys.executable if available
return sys.executable
def build_run_test(source, target, env):
# Get the executable path
program_path = source[0].get_abspath()
# Get output file and test command from environment variable or use defaults
output_file = os.path.join("docs", env.GetProjectOption("custom_output_file", "dump_default_output.txt"))
test_command = env.GetProjectOption("custom_test_command", "test entity_dump")
# run the test command and save the output to the output file
run_with_streaming_input(program_path, test_command, output_file)
# if we have a post command defined run it
post_script = env.GetProjectOption("custom_post_script", None)
if post_script:
print(f"Running post script: {post_script}")
python_exe = get_python_executable()
subprocess.run([python_exe, post_script, program_path], check=True)
env.AddCustomTarget(
"build",
"$BUILD_DIR/${PROGNAME}$PROGSUFFIX",
build_run_test
)

14
scripts/force_clean.py Normal file
View File

@@ -0,0 +1,14 @@
Import("env")
import os
import shutil
def force_clean(source, target, env):
"""Remove build directory before building"""
build_dir = env.subst("$BUILD_DIR")
if os.path.exists(build_dir):
print(f"Force cleaning: {build_dir}")
shutil.rmtree(build_dir)
# Register the callback to run before building
env.AddPreAction("$BUILD_DIR/${PROGNAME}$PROGSUFFIX", force_clean)

View File

@@ -1,59 +0,0 @@
#!/bin/sh
#
# Builds the dump_*.csv files, modbus headers and modbus documentation.
# Run as `sh scripts/generate_csv_and_headers.sh` from the root of the repository.
# create a dummy modbus_entity_parameters.hpp so the first pass compiles
cat >./src/core/modbus_entity_parameters.hpp <<EOL
#include "modbus.h"
#include "emsdevice.h"
/*
* This file is auto-generated. Do not modify.
*/
// clang-format off
namespace emsesp {
using dt = EMSdevice::DeviceType;
#define REGISTER_MAPPING(device_type, device_value_tag_type, long_name, modbus_register_offset, modbus_register_count) \\
{ device_type, device_value_tag_type, long_name[0], modbus_register_offset, modbus_register_count }
// IMPORTANT: This list MUST be ordered by keys "device_type", "device_value_tag_type" and "modbus_register_offset" in this order.
const std::initializer_list<Modbus::EntityModbusInfo> Modbus::modbus_register_mappings = {};
} // namespace emsesp
// clang-format on
EOL
# First generate Modbus entity parameters
# build the modbus_entity_parameters.hpp header file
make clean
make -s ARGS=-DEMSESP_MODBUS
rm -f ./src/core/modbus_entity_parameters.hpp ./docs/dump_entities.csv
echo "test entity_dump" | ./emsesp | python3 ./scripts/strip_csv.py > ./docs/dump_entities.csv
cat ./docs/dump_entities.csv | python3 ./scripts/update_modbus_registers.py > ./src/core/modbus_entity_parameters.hpp
# regenerate dump_entities.csv but without the Modbus entity parameters
make clean
make -s ARGS=-DEMSESP_STANDALONE
rm -f ./docs/dump_entities.csv
echo "test entity_dump" | ./emsesp | python3 ./scripts/strip_csv.py > ./docs/dump_entities.csv
# generate Modbus doc - Modbus-Entity-Registers.md used in the emsesp.org documentation
rm -f ./docs/Modbus-Entity-Registers.md
cat ./docs/dump_entities.csv | python3 ./scripts/generate-modbus-register-doc.py > ./docs/Modbus-Entity-Registers.md
# dump_telegrams.csv
rm -f ./docs/dump_telegrams.csv
echo "test telegram_dump" | ./emsesp | python3 ./scripts/strip_csv.py > ./docs/dump_telegrams.csv
ls -al ./src/core/modbus_entity_parameters.hpp
ls -al ./docs/Modbus-Entity-Registers.md
ls -al ./docs/dump_entities.csv
ls -al ./docs/dump_telegrams.csv

135
scripts/run_executable.py Executable file
View File

@@ -0,0 +1,135 @@
#!/usr/bin/env python3
"""
Utility functions for running executables with streaming input and CSV output extraction.
"""
import subprocess
import sys
import os
from pathlib import Path
def run_with_streaming_input(program_path, test_command, output_file=None):
"""
Run the executable and stream text input to it.
Args:
program_path (str): Path to the executable to run
test_command (str): Command to send to the executable
output_file (str, optional): Path to save CSV output. If None, no file is saved.
Returns:
int: Return code of the executed process
"""
try:
# Start the process with pipes for stdin, stdout, and stderr
process = subprocess.Popen(
[str(program_path)],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
bufsize=1 # Line buffered
)
# add "test " to test_command if it doesn't already start with "test "
if not test_command.startswith("test "):
test_command = "test " + test_command
# Stream input line by line
for line in test_command.strip().split('\n'):
process.stdin.write(line + '\n')
process.stdin.flush()
# Close stdin to signal end of input
process.stdin.close()
# Read and collect output between CSV START and CSV END, then export to file
in_cvs_section = False
csv_output = []
for line in process.stdout:
if "---- CSV START ----" in line:
in_cvs_section = True
continue
elif "---- CSV END ----" in line:
in_cvs_section = False
continue
elif in_cvs_section:
csv_output.append(line)
# print(line, end='')
# Export CSV output to file if output_file is specified
if output_file:
# Ensure the output directory exists
Path(output_file).parent.mkdir(parents=True, exist_ok=True)
# delete the output file if it exists
if os.path.exists(output_file):
os.remove(output_file)
# Export CSV output to file
with open(output_file, 'w') as f:
f.writelines(csv_output)
print(f"CSV file created: {output_file} ({os.path.getsize(output_file)} bytes)")
# Wait for process to complete
return_code = process.wait()
# Print any errors
stderr_output = process.stderr.read()
if stderr_output:
print("\nErrors:", file=sys.stderr)
print(stderr_output, file=sys.stderr)
return return_code
except Exception as e:
print(f"Error running executable: {e}", file=sys.stderr)
return 1
def run_executable_with_command(program_path, command, output_file=None):
"""
Simplified interface to run an executable with a command and optionally save output.
Args:
program_path (str): Path to the executable to run
command (str): Command to send to the executable
output_file (str, optional): Path to save CSV output. If None, no file is saved.
Returns:
int: Return code of the executed process
"""
return run_with_streaming_input(program_path, command, output_file)
def main():
"""Command-line interface for running executables with streaming input."""
if len(sys.argv) < 3:
print("Usage: python3 run_executable.py <program_path> <command> [output_file]")
print("Example: python3 run_executable.py ./emsesp entity_dump ./output.csv")
sys.exit(1)
program_path = sys.argv[1]
command = sys.argv[2]
output_file = sys.argv[3] if len(sys.argv) > 3 else None
print(f"Running: {program_path}")
print(f"Command: {command}")
if output_file:
print(f"Output file: {output_file}")
return_code = run_with_streaming_input(program_path, command, output_file)
if return_code == 0:
print("Execution completed successfully!")
else:
print(f"Execution failed with return code: {return_code}")
sys.exit(return_code)
if __name__ == "__main__":
main()

View File

@@ -26,4 +26,3 @@ pnpm webUI
cd ..
npx cspell "**"
sh ./scripts/generate_csv_and_headers.sh

View File

@@ -228,10 +228,12 @@ void RxService::add(uint8_t * data, uint8_t length) {
// create the telegram
auto telegram = std::make_shared<Telegram>(operation, src, dest, type_id, offset, message_data, message_length);
// check if queue is full, if so remove top item to make space
// check if queue is full, if so remove top item to make space, except if we're in standalone mode
#ifndef EMSESP_STANDALONE
if (rx_telegrams_.size() >= MAX_RX_TELEGRAMS) {
rx_telegrams_.pop_front();
}
#endif
rx_telegrams_.emplace_back(rx_telegram_id_++, std::move(telegram)); // add to queue
}
@@ -239,7 +241,7 @@ void RxService::add(uint8_t * data, uint8_t length) {
// add empty telegram to rx-queue
void RxService::add_empty(const uint8_t src, const uint8_t dest, const uint16_t type_id, uint8_t offset) {
auto telegram = std::make_shared<Telegram>(Telegram::Operation::RX, src, dest, type_id, offset, nullptr, 0);
// only if queue is not full
// only if queue is not full
if (rx_telegrams_.size() < MAX_RX_TELEGRAMS) {
rx_telegrams_.emplace_back(rx_telegram_id_++, std::move(telegram)); // add to queue
}
@@ -442,6 +444,7 @@ void TxService::add(const uint8_t operation,
LOG_DEBUG("New Tx [#%d] telegram, length %d", tx_telegram_id_, message_length);
#ifndef EMSESP_STANDALONE
// if the queue is full, make room by removing the last one
if (tx_telegrams_.size() >= MAX_TX_TELEGRAMS) {
LOG_WARNING("Tx queue overflow, skip one message");
@@ -452,6 +455,7 @@ void TxService::add(const uint8_t operation,
}
tx_telegrams_.pop_front();
}
#endif
if (front) {
tx_telegrams_.emplace_front(tx_telegram_id_++, std::move(telegram), false, validateid); // add to front of queue

View File

@@ -32,13 +32,8 @@
#include "helpers.h"
#if defined(EMSESP_STANDALONE)
#define MAX_RX_TELEGRAMS 100 // size of Rx queue
#define MAX_TX_TELEGRAMS 200 // size of Tx queue
#else
#define MAX_RX_TELEGRAMS 10 // size of Rx queue
#define MAX_TX_TELEGRAMS 160 // size of Tx queue
#endif
// default values for null values
static constexpr uint8_t EMS_VALUE_BOOL = 0xFF; // used to mark that something is a boolean