Merge remote-tracking branch 'emsesp/dev' into dev

This commit is contained in:
MichaelDvP
2026-10-09 11:59:08 +02:00
23 changed files with 507 additions and 302 deletions
+3 -1
View File
@@ -37,12 +37,14 @@ This release is based on the latest Espressif/Arduino core version 3. It brings
- HA Discovery warning on Uptime after EMS-ESP boot due to NTP not ready
- hc/control setting for UI800 thermostats [#3181](https://github.com/emsesp/EMS-ESP32/discussions/3181)
- solar module switches [#3223](https://github.com/emsesp/EMS-ESP32/issues/3223)
- UI800/HMI800.2 thermostats without telegram 0x470 reported `summertemp` as 0 and lost the per-hc heat/cool delays. `summermode` is now also shown for UI800 heatpumps [#3257](https://github.com/emsesp/EMS-ESP32/issues/3257)
- 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
- 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
- add 0kW to heat limits [#3262](https://github.com/emsesp/EMS-ESP32/issues/3262), [#3265](https://github.com/emsesp/EMS-ESP32/issues/3265)
- show temperature value for sensor 0x40 [#3272](https://github.com/emsesp/EMS-ESP32/issues/3272)
- no EMS bus on custom boards whose interface relies on a pull-up on the Rx line. The newer ESP-IDF no longer enables the internal pull-up on the UART Rx pin, so it is now set explicitly as it was in 3.8 [#3258](https://github.com/emsesp/EMS-ESP32/discussions/3258)
## Changed
@@ -60,4 +62,4 @@ This release is based on the latest Espressif/Arduino core version 3. It brings
- TLS buffers (~17KB per HTTPS request) are taken from PSRAM on boards that have it, instead of fragmenting the internal heap
- failed versions.json fetches back off from 5 up to 160 minutes instead of retrying every 5 minutes, as each attempt blocks the main loop for as long as the DNS, connect and read timeouts allow
- optimized the LED library to support WS2812B V5 and the newer V6 RGB LEDs
- hold Tx while a K30RF/KM200 gateway is syncing [#3094](https://github.com/emsesp/EMS-ESP32/issues/3094)
+12
View File
@@ -6583,6 +6583,18 @@ uint8
| hc1.control | control device | enum | | true | HC | 44 | 1 | 1 |
| hc1.remotetemp | room temperature from remote | cmd | C | true | HC | 45 | 1 | 1/10 |
| hc1.remotehum | room humidity from remote | cmd | % | true | HC | 46 | 1 | 1 |
uint8
| hc1.heatondelay | heat-on delay | uint8 (>=1<=48) | hours | true | HC | 47 | 1 | 1 |
uint8
| hc1.heatoffdelay | heat-off delay | uint8 (>=1<=48) | hours | true | HC | 48 | 1 | 1 |
uint8
| hc1.coolondelay | cooling on delay | uint8 (>=1<=48) | hours | true | HC | 49 | 1 | 1 |
uint8
| hc1.cooloffdelay | cooling off delay | uint8 (>=1<=48) | hours | true | HC | 50 | 1 | 1 |
uint8
| hc1.instantstart | instant start | uint8 (>=1<=10) | K | true | HC | 51 | 1 | 1 |
uint8
| hc1.coolstart | cooling starttemp | uint8 (>=20<=35) | C | true | HC | 52 | 1 | 1 |
| hc1.boost | boost mode | boolean | | true | HC | 53 | 1 | 1 |
uint8
| hc1.boosttime | boost time | uint8 (>=0<=0) | hours | true | HC | 54 | 1 | 1 |
+6
View File
@@ -4836,6 +4836,12 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
"Rego 3000, UI800, Logamatic BC400",thermostat,253,hc1.control,control device,enum [off\|-\|CR10\|CR10H\|-\|CR20RF\|RT800\|single] (>=0<=0), ,true,select.thermostat_hc1_control_device,select.thermostat_hc1_control,7,1,1,44,1
"Rego 3000, UI800, Logamatic BC400",thermostat,253,hc1.remotetemp,room temperature from remote,cmd [] (>=-1<=101),C,true,sensor.thermostat_hc1_room_temperature_from_remote,sensor.thermostat_hc1_remotetemp,7,1,1/10,45,1
"Rego 3000, UI800, Logamatic BC400",thermostat,253,hc1.remotehum,room humidity from remote,cmd [] (>=-1<=101),%,true,sensor.thermostat_hc1_room_humidity_from_remote,sensor.thermostat_hc1_remotehum,7,1,1,46,1
"Rego 3000, UI800, Logamatic BC400",thermostat,253,hc1.heatondelay,heat-on delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_heat-on_delay,number.thermostat_hc1_heatondelay,7,1,1,47,1
"Rego 3000, UI800, Logamatic BC400",thermostat,253,hc1.heatoffdelay,heat-off delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_heat-off_delay,number.thermostat_hc1_heatoffdelay,7,1,1,48,1
"Rego 3000, UI800, Logamatic BC400",thermostat,253,hc1.coolondelay,cooling on delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_on_delay,number.thermostat_hc1_coolondelay,7,1,1,49,1
"Rego 3000, UI800, Logamatic BC400",thermostat,253,hc1.cooloffdelay,cooling off delay,uint8 (>=1<=48),hours,true,number.thermostat_hc1_cooling_off_delay,number.thermostat_hc1_cooloffdelay,7,1,1,50,1
"Rego 3000, UI800, Logamatic BC400",thermostat,253,hc1.instantstart,instant start,uint8 (>=1<=10),K,true,number.thermostat_hc1_instant_start,number.thermostat_hc1_instantstart,7,1,1,51,1
"Rego 3000, UI800, Logamatic BC400",thermostat,253,hc1.coolstart,cooling starttemp,uint8 (>=20<=35),C,true,number.thermostat_hc1_cooling_starttemp,number.thermostat_hc1_coolstart,7,1,1,52,1
"Rego 3000, UI800, Logamatic BC400",thermostat,253,hc1.boost,boost mode,boolean (>=0<=0), ,true,switch.thermostat_hc1_boost_mode,switch.thermostat_hc1_boost,7,1,1,53,1
"Rego 3000, UI800, Logamatic BC400",thermostat,253,hc1.boosttime,boost time,uint8 (>=0<=0),hours,true,number.thermostat_hc1_boost_time,number.thermostat_hc1_boosttime,7,1,1,54,1
"Rego 3000, UI800, Logamatic BC400",thermostat,253,hc1.switchprogmode,switch program mode,enum [level\|absolute] (>=0<=0), ,true,select.thermostat_hc1_switch_program_mode,select.thermostat_hc1_switchprogmode,7,1,1,55,1
Can't render this file because it is too large.
+4 -4
View File
@@ -29,7 +29,7 @@ telegram_type_id,name,is_fetched
0x3B,Energy,
0x3D,RC35Set,
0x3E,RC35Monitor,
0x3F,RC35Timer,
0x3F,RC30Timer,
0x40,RC30Temp,
0x41,RC30Monitor,
0x42,RC35Timer2,
@@ -77,7 +77,7 @@ telegram_type_id,name,is_fetched
0x0103,ISM1StatusMessage,fetched
0x0104,ISM2StatusMessage,
0x010C,IPMStatusMessage,
0x011E,IPMTempMessage,
0x011E,JunkersDisp,fetched
0x012E,HPEnergy1,
0x013B,HPEnergy2,
0x0165,JunkersSet,
@@ -112,7 +112,7 @@ telegram_type_id,name,is_fetched
0x02A0,RC300Curves,
0x02A1,RC300Curves,
0x02A2,RC300Curves,
0x02A5,EasyMonitor,
0x02A5,CRFMonitor,
0x02A6,RC300Monitor,
0x02A7,RC300Monitor,
0x02A8,RC300Monitor,
@@ -200,7 +200,7 @@ telegram_type_id,name,is_fetched
0x04A2,HpInput,fetched
0x04A5,HPFan,fetched
0x04A7,HPPowerLimit,fetched
0x04AA,HPPower,
0x04AA,HPPower2,fetched
0x04AE,HPEnergy,fetched
0x04AF,HPMeters,fetched
0x055C,VentilationSet,fetched
1 telegram_type_id name is_fetched
29 0x3B Energy
30 0x3D RC35Set
31 0x3E RC35Monitor
32 0x3F RC35Timer RC30Timer
33 0x40 RC30Temp
34 0x41 RC30Monitor
35 0x42 RC35Timer2
77 0x0103 ISM1StatusMessage fetched
78 0x0104 ISM2StatusMessage
79 0x010C IPMStatusMessage
80 0x011E IPMTempMessage JunkersDisp fetched
81 0x012E HPEnergy1
82 0x013B HPEnergy2
83 0x0165 JunkersSet
112 0x02A0 RC300Curves
113 0x02A1 RC300Curves
114 0x02A2 RC300Curves
115 0x02A5 EasyMonitor CRFMonitor
116 0x02A6 RC300Monitor
117 0x02A7 RC300Monitor
118 0x02A8 RC300Monitor
200 0x04A2 HpInput fetched
201 0x04A5 HPFan fetched
202 0x04A7 HPPowerLimit fetched
203 0x04AA HPPower HPPower2 fetched
204 0x04AE HPEnergy fetched
205 0x04AF HPMeters fetched
206 0x055C VentilationSet fetched
+2 -2
View File
@@ -31,7 +31,7 @@
"@table-library/react-table-library": "4.1.15",
"alova": "^3.5.5",
"jwt-decode": "^4.0.0",
"preact": "^10.29.8",
"preact": "^11.0.0",
"react": "^19.3.0",
"react-dom": "^19.3.0",
"react-icons": "^5.7.0",
@@ -58,5 +58,5 @@
"vite": "^8.3.3",
"vite-plugin-imagemin": "^0.6.1"
},
"packageManager": "pnpm@12.9.1"
"packageManager": "pnpm@12.10.1"
}
+182 -182
View File
@@ -7,153 +7,153 @@ importers:
configDependencies: {}
packageManagerDependencies:
pnpm:
specifier: 12.9.1
version: 12.9.1
specifier: 12.10.1
version: 12.10.1
packages:
'@pnpm/exe.android-arm64@12.9.1':
resolution: {integrity: sha512-Hgm1XdqMTfBC8PdGLL+NjZWv4xyi7D6XNrN9fb24XGYlyTBmUtdCefKnCLmHujShRD8BEO1zqM30SNcKBDLysw==}
'@pnpm/exe.android-arm64@12.10.1':
resolution: {integrity: sha512-CVTlHPwNvadQCJD9bGSMzWIhFX8QpjtqC2c27dhdnn/9iKzEjZ3qL62o3gHpKbIuo6qn4WxTKRoaokgNdReBig==}
cpu: [arm64]
os: [android]
'@pnpm/exe.android-x64@12.9.1':
resolution: {integrity: sha512-WDGCe6jZRVZP3RC/q6hOkZylkPkIQIi1/GcrR/d/YzbihhAHXCczrk+UYnV5TgbsEnAYO7Cx+2rX3nfhHvy24w==}
'@pnpm/exe.android-x64@12.10.1':
resolution: {integrity: sha512-NFiYLIaodY7da0XIebwcU3JoP7IK/lzF7zgKSSP+9H+QcFnQ1GDfBkuBKCYJzZ+Xu0WH54neIPLBBCaOjaaauA==}
cpu: [x64]
os: [android]
'@pnpm/exe.darwin-arm64@12.9.1':
resolution: {integrity: sha512-+7iiEEBgYN9szPWUnAuN6eOVMTI6Hrki5bcuC9n9xl9tTnT53Tpxpo45Hml+W4IrAU0d+Tmd0sPnVIbX59PD6w==}
'@pnpm/exe.darwin-arm64@12.10.1':
resolution: {integrity: sha512-0O8tdQ8ijlPJudXspLMTcitMkdBEz6uUflazL5uQE0WMs85oQIp0U+5hfEktMFB64QqEhjqlvvujTwbzdr9oMg==}
cpu: [arm64]
os: [darwin]
'@pnpm/exe.darwin-x64@12.9.1':
resolution: {integrity: sha512-SK7TxJiR12GbJZGffRFHItkc+Mx+99v6xMMJ9/X//8NwWV1wo17a2bwfGI8qZpl17YwsrmPEFOOqhzE1GIlrtQ==}
'@pnpm/exe.darwin-x64@12.10.1':
resolution: {integrity: sha512-ud+1/uZOKEo8P/AsPynOJc/LNwfI0j6WwCElibj71rU9l4nIBnsSn+wWTIPZPkZ4BBSH5+82azSnAARMyJ1lNA==}
cpu: [x64]
os: [darwin]
'@pnpm/exe.freebsd-x64@12.9.1':
resolution: {integrity: sha512-4AjLk6uvTs2iO6wMit2hcxJ2M32xb7OV5SNFk+w6G8/NzcjcMB7ENEpyeXyLiP0kcnp8uaCGUct2NfrLCJ35eQ==}
'@pnpm/exe.freebsd-x64@12.10.1':
resolution: {integrity: sha512-mj9PE5rf8uAfQQ2K66HSATMSut+lNiB4eSqFd5+azFVCMnxNSy/32xpZQJT21PhnN3Y4qbK+iKHe5nWAxSuRhw==}
cpu: [x64]
os: [freebsd]
'@pnpm/exe.linux-arm64-musl@12.9.1':
resolution: {integrity: sha512-dZL2ES1ckDWM9v+EtxoOklZ0WNdtayooi9iLiDUubopudX3zXPNR2mlrxBRgjbDgECOndQen2SmyxL5eZiBuKw==}
'@pnpm/exe.linux-arm64-musl@12.10.1':
resolution: {integrity: sha512-xba+00wZJ8Um6rBJJjWl88uJj0tydB8dtomvjlCLvi0uL32vpa9CRP8Vv26FIXvbiZ1bo2RCzYt/eChxJVV52w==}
cpu: [arm64]
os: [linux]
libc: [musl]
'@pnpm/exe.linux-arm64@12.9.1':
resolution: {integrity: sha512-cx+uF6xqwEtm7B8NV+1ve0xBg9gcuzQZ5R+0WgOWvKG/h978UljS6BgWs1ipIGuGgUdeVhm3PKmBltXIcczLXA==}
'@pnpm/exe.linux-arm64@12.10.1':
resolution: {integrity: sha512-oBdMp69ScC9UnniG4qZAQVr2fBDSXjm4yk/72vkEVyrlwS23yMxcRQl7Qdo3sgXPAygY6TWnPRKm4rXzjoyW7w==}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@pnpm/exe.linux-ppc64@12.9.1':
resolution: {integrity: sha512-MpjPsy4XR17zAtLziQZfsN+wveWa/bUJggZtwfo3+SuyRmXnSvVkFD4+v8/3RTWyYaM6mwLUTjZDJ+g3urL+ew==}
'@pnpm/exe.linux-ppc64@12.10.1':
resolution: {integrity: sha512-Yyb3wu09h3c7mLme270uHFiVaAIUHC411Ru9LIU2BKUIstrGlXa9OqqVWoXaRgYRdFdOFknkwG7GNn6ygwLbnw==}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@pnpm/exe.linux-riscv64@12.9.1':
resolution: {integrity: sha512-Oo67TKqqH+Bno+L6X7Xyorwp1QG82zKIkL0vbo1x2kcPTDiyPbdM+d6lIs4+hzeB1KHT5FDoGzZj2dad7Ft+eg==}
'@pnpm/exe.linux-riscv64@12.10.1':
resolution: {integrity: sha512-PdkeUFFkybknnGkWP0H22eMpIiS4OZXL5BcQzF4lh+vmrW3IaC2HOkbANKgot/PKO0Kl77pzA/6PKFxgbgfXIQ==}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@pnpm/exe.linux-s390x@12.9.1':
resolution: {integrity: sha512-QAD5FRCdW36HfD58BV7DoDm6z8yv+GgSqcUV1+ERwYjpVQuG6ZTpf5o0x3KDas8eTLIW7MLYVdDdlAurWeArEg==}
'@pnpm/exe.linux-s390x@12.10.1':
resolution: {integrity: sha512-1okKuHKJwJPAbofDxfhZWAUxEWtee4ZSf7Pah8kcvocaJkf2WxFJ5KVTiNIvDml5GLidDQsgf7Pcf/WHbCak7Q==}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@pnpm/exe.linux-x64-musl@12.9.1':
resolution: {integrity: sha512-mQDhBsGqcTkrLQM4q5igmRFcr6EAl4UM/FGawY+0CWGcqPpUmYUvDy9LHy80xxkHIWVJ886gvvso2XOjfav1Jw==}
'@pnpm/exe.linux-x64-musl@12.10.1':
resolution: {integrity: sha512-e6IqzVNkPa7srFKJKnY23uWJ+qz0LaRWiTUo/sHfFXRRMRzB5uNOr6qWWip/jqhdGwU91n9J7LrEYZ6e0tRczw==}
cpu: [x64]
os: [linux]
libc: [musl]
'@pnpm/exe.linux-x64@12.9.1':
resolution: {integrity: sha512-+M5N74hM4fc87AAckxx/UIW+dUnWf2eko+HchJs/NZUxehLhekNyMI/GNaNXlvd+kWR+97XXBD51XRkkNiUtrA==}
'@pnpm/exe.linux-x64@12.10.1':
resolution: {integrity: sha512-ZByV0DRgWzGaDSjT5ddRBASdwz+r/qPMYh7o6RGmPQjtRGNFbSl94xY2DcAM8mqCOZJUUDtAXQ+wpBXcdpKlkg==}
cpu: [x64]
os: [linux]
libc: [glibc]
'@pnpm/exe.win32-arm64@12.9.1':
resolution: {integrity: sha512-mI28C2wxobrDi6x1OYhBRyG10hnDq/4sEIyy5RzoX6LB4kLuv6K/d25HOpMwlW20cuM4M72k9NZpOdcmUxMbEA==}
'@pnpm/exe.win32-arm64@12.10.1':
resolution: {integrity: sha512-I7QZHcjioG7orFeCRUFUHByJ1G0zFPnAlaGGyrUvb6MGkv5oeNwNPl7t+Gp+7zHfnMcgLGJ1a+Wfim0IDw3lOw==}
cpu: [arm64]
os: [win32]
'@pnpm/exe.win32-x64@12.9.1':
resolution: {integrity: sha512-SWoDMT0oD7NrDSIoPpkKD09D9fAQKNjwFZ3lezlCUhAfXxMv70zsfrNT2/P+GoCK2kefXF9OysUZkH1l5vvvfA==}
'@pnpm/exe.win32-x64@12.10.1':
resolution: {integrity: sha512-4WJFdp58EKlCj0zLobrXU0vpszSZIr4X/3y/uNbAQqGW0zE+VdruZB0gFc3L2kzsUzVwTYbaCn+XEhnCYSAlTg==}
cpu: [x64]
os: [win32]
pnpm@12.9.1:
resolution: {integrity: sha512-BrBV//XNINwSeB3hc87TMQzglRvy7GICEaFgRdVETVyTpmMhB2TvKaZTphBFm6A2jw50+E2AxUcjz5Wq57wNbQ==}
pnpm@12.10.1:
resolution: {integrity: sha512-ukCjfrGjcNYP6oxM8dNkwTvMzvUY6YrSvO6VT1OdONo3RY5YJho/pV4GUjRQ6g//+fSXsTW+QfLBXBZCusrObA==}
engines: {node: '>=18.*'}
hasBin: true
snapshots:
'@pnpm/exe.android-arm64@12.9.1':
'@pnpm/exe.android-arm64@12.10.1':
optional: true
'@pnpm/exe.android-x64@12.9.1':
'@pnpm/exe.android-x64@12.10.1':
optional: true
'@pnpm/exe.darwin-arm64@12.9.1':
'@pnpm/exe.darwin-arm64@12.10.1':
optional: true
'@pnpm/exe.darwin-x64@12.9.1':
'@pnpm/exe.darwin-x64@12.10.1':
optional: true
'@pnpm/exe.freebsd-x64@12.9.1':
'@pnpm/exe.freebsd-x64@12.10.1':
optional: true
'@pnpm/exe.linux-arm64-musl@12.9.1':
'@pnpm/exe.linux-arm64-musl@12.10.1':
optional: true
'@pnpm/exe.linux-arm64@12.9.1':
'@pnpm/exe.linux-arm64@12.10.1':
optional: true
'@pnpm/exe.linux-ppc64@12.9.1':
'@pnpm/exe.linux-ppc64@12.10.1':
optional: true
'@pnpm/exe.linux-riscv64@12.9.1':
'@pnpm/exe.linux-riscv64@12.10.1':
optional: true
'@pnpm/exe.linux-s390x@12.9.1':
'@pnpm/exe.linux-s390x@12.10.1':
optional: true
'@pnpm/exe.linux-x64-musl@12.9.1':
'@pnpm/exe.linux-x64-musl@12.10.1':
optional: true
'@pnpm/exe.linux-x64@12.9.1':
'@pnpm/exe.linux-x64@12.10.1':
optional: true
'@pnpm/exe.win32-arm64@12.9.1':
'@pnpm/exe.win32-arm64@12.10.1':
optional: true
'@pnpm/exe.win32-x64@12.9.1':
'@pnpm/exe.win32-x64@12.10.1':
optional: true
pnpm@12.9.1:
pnpm@12.10.1:
optionalDependencies:
'@pnpm/exe.android-arm64': 12.9.1
'@pnpm/exe.android-x64': 12.9.1
'@pnpm/exe.darwin-arm64': 12.9.1
'@pnpm/exe.darwin-x64': 12.9.1
'@pnpm/exe.freebsd-x64': 12.9.1
'@pnpm/exe.linux-arm64': 12.9.1
'@pnpm/exe.linux-arm64-musl': 12.9.1
'@pnpm/exe.linux-ppc64': 12.9.1
'@pnpm/exe.linux-riscv64': 12.9.1
'@pnpm/exe.linux-s390x': 12.9.1
'@pnpm/exe.linux-x64': 12.9.1
'@pnpm/exe.linux-x64-musl': 12.9.1
'@pnpm/exe.win32-arm64': 12.9.1
'@pnpm/exe.win32-x64': 12.9.1
'@pnpm/exe.android-arm64': 12.10.1
'@pnpm/exe.android-x64': 12.10.1
'@pnpm/exe.darwin-arm64': 12.10.1
'@pnpm/exe.darwin-x64': 12.10.1
'@pnpm/exe.freebsd-x64': 12.10.1
'@pnpm/exe.linux-arm64': 12.10.1
'@pnpm/exe.linux-arm64-musl': 12.10.1
'@pnpm/exe.linux-ppc64': 12.10.1
'@pnpm/exe.linux-riscv64': 12.10.1
'@pnpm/exe.linux-s390x': 12.10.1
'@pnpm/exe.linux-x64': 12.10.1
'@pnpm/exe.linux-x64-musl': 12.10.1
'@pnpm/exe.win32-arm64': 12.10.1
'@pnpm/exe.win32-x64': 12.10.1
---
lockfileVersion: '9.0'
@@ -191,8 +191,8 @@ importers:
specifier: ^4.0.0
version: 4.0.0
preact:
specifier: ^10.29.8
version: 10.29.8
specifier: ^11.0.0
version: 11.0.0
react:
specifier: ^19.3.0
version: 19.3.0
@@ -214,7 +214,7 @@ importers:
version: 10.0.1(eslint@10.12.0(supports-color@10.2.2))
'@preact/preset-vite':
specifier: ^2.10.6
version: 2.10.6(@babel/core@7.29.7(supports-color@10.2.2))(preact@10.29.8)(supports-color@10.2.2)(vite@8.3.3(@types/node@26.6.4)(terser@5.51.2))
version: 2.10.6(@babel/core@7.29.7(supports-color@10.2.2))(preact@11.0.0)(supports-color@10.2.2)(vite@8.3.3(@types/node@26.6.4)(terser@5.51.2))
'@trivago/prettier-plugin-sort-imports':
specifier: ^6.0.2
version: 6.0.2(prettier@3.9.9)(supports-color@10.2.2)
@@ -247,7 +247,7 @@ importers:
version: 3.9.9
rollup-plugin-visualizer:
specifier: ^7.1.1
version: 7.1.1(rolldown@1.2.12)
version: 7.1.1(rolldown@1.2.13)
terser:
specifier: ^5.51.2
version: 5.51.2
@@ -328,8 +328,8 @@ packages:
resolution: {integrity: sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==}
engines: {node: '>=6.9.0'}
'@babel/helpers@7.29.7':
resolution: {integrity: sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==}
'@babel/helpers@7.29.10':
resolution: {integrity: sha512-EMCx3AGZ3WfAl6ht7AyQoPm2Lh+BGYEMdc4Q6Hf7uSCDOZFuLq44qNwL+iaim8VlyYhRAo4X43+weadK8ZB4Yg==}
engines: {node: '>=6.9.0'}
'@babel/parser@7.29.9':
@@ -355,16 +355,16 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0-0
'@babel/runtime@7.29.7':
resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==}
'@babel/runtime@7.29.10':
resolution: {integrity: sha512-NpugTzbKgGrNe45Ui32cN8vCFFMxVtP/9rtfwv0nP5FRDAjvYBxJcLVpYA9mr1jxP6cnIT7x9LUzuDTbWYYNRA==}
engines: {node: '>=6.9.0'}
'@babel/template@7.29.7':
resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==}
engines: {node: '>=6.9.0'}
'@babel/traverse@7.29.8':
resolution: {integrity: sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==}
'@babel/traverse@7.29.10':
resolution: {integrity: sha512-B3lYAs2nkKskbgQ1nfy8Ma9ao9Q1rntTAQHrzzyDuj+TSO+X3le6PfWwqDvodsb+OumE10eMFfuMCTQSQ5iuIQ==}
engines: {node: '>=6.9.0'}
'@babel/types@7.29.8':
@@ -627,8 +627,8 @@ packages:
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
engines: {node: '>= 8'}
'@oxc-project/types@0.152.0':
resolution: {integrity: sha512-oM/5rLBm2tPkg0iBgkH/FOeR3PCDpY19GTgAZjMFM8h9WI9VW7cLgzp6nwtarYKmovavIQZ+Fe/RKX/8C8O/Rw==}
'@oxc-project/types@0.153.0':
resolution: {integrity: sha512-jSNrRIyvPVLL5E1z/tS5zLAprosGz/FuI1PWwEOz59j3E4TTTzSpqKb/RDGqJhhW0QHYISGXxq582wGx6T11Tw==}
'@popperjs/core@2.11.8':
resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
@@ -661,98 +661,98 @@ packages:
'@remix-run/route-pattern@0.22.1':
resolution: {integrity: sha512-czdGJWh09Lapvcqt7Vb09KlrU2PhRJ8xQaI+AItTuD9aDJ5MAgxnS38lnys6Ll+6RJEqPiaUqTwIQhVLwFvv+w==}
'@rolldown/binding-android-arm-eabi@1.2.12':
resolution: {integrity: sha512-dB/a1214qKfHMXCpgqR4OZT+jS4kTyEXbQGJPqzobt5EwH5rX080pxE37alt3RzvR1bf1Yz/yGqRfrYAxuPw0A==}
'@rolldown/binding-android-arm-eabi@1.2.13':
resolution: {integrity: sha512-Vu/NICrgdRvUOeaJZIyB2FP63s6fO/4ud5l8dXmxDx9yDyn+mN0y+gsvsVviSli+T361Aqo0h46EuMoobrwawA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [android]
'@rolldown/binding-android-arm64@1.2.12':
resolution: {integrity: sha512-7KHFgQ5VJxIHcLlrwrc3Xbds7oTNQT7Pgi9gQCJKrd2VGab/UksIOYp6VD8MzCstGxOKMgNamPwUCfxPdP1OHg==}
'@rolldown/binding-android-arm64@1.2.13':
resolution: {integrity: sha512-6LEoIrGy5vvCd2boNnv2soPSUZj/PRvhp8R/t9KlX+mIZxThIE/ZqxrGXxmuNX0FuvQFvLdZr7S4HrYpYBVhEQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [android]
'@rolldown/binding-darwin-arm64@1.2.12':
resolution: {integrity: sha512-3YIhqHD96nA5SaYNRBR16HnGv4oavZvXfD/ayHM+oYZ0WD/8lBAtf6zQua4kEyAvpqrluKXl0lnOBoiNby7x9w==}
'@rolldown/binding-darwin-arm64@1.2.13':
resolution: {integrity: sha512-CaJSRzlQ6Q+zkDMVA9OkVxBjVoPRCDEE3v0FSJ9kIQBgRjFApA3Si4ijhbNVUji7ZJt+PfO0e46qy4nPInHUPA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [darwin]
'@rolldown/binding-darwin-x64@1.2.12':
resolution: {integrity: sha512-UuuJ35MFw4gmFOrE9pEqIV+K3syIKveph+Qc1/ljHZVdoDW4pz/JHR/eMVom+TZGl/5OOvGJOWaOCVt3ZfqhxA==}
'@rolldown/binding-darwin-x64@1.2.13':
resolution: {integrity: sha512-e4r340I5hxSzJkD3YJBxgzq/rJ3wwxwdLLb2FPt1Zpyem20nrQPT11DDEEkazwxaHumH8wpglsp/Ozgj/wT6mw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [darwin]
'@rolldown/binding-freebsd-x64@1.2.12':
resolution: {integrity: sha512-uMvssit0a4W+/7D8CbHUvG719mH3R2jwXAlh/XcPvuHTE0g++LymF88DCGNX0HM2rBOn0xrzgXktIB6fLSJBTQ==}
'@rolldown/binding-freebsd-x64@1.2.13':
resolution: {integrity: sha512-hoBWDZ4/K/mJKVMbsgUd1jfpA2DiOrJ54mpegObU9TBHBBrtX4FLIXJJQRDPZ/2Dn91GvPob+Z2hwKJzf4E5SQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [freebsd]
'@rolldown/binding-linux-arm-gnueabihf@1.2.12':
resolution: {integrity: sha512-XcFu0R0xWnwzSf4IQgFH1rJIckPN1pLy2R+4r9IDB7Yfu/ys9cVqfa4pBrMHj7a3gl8mIR4nRNPg0e5IvEVs6g==}
'@rolldown/binding-linux-arm-gnueabihf@1.2.13':
resolution: {integrity: sha512-oF9fZu3vTWnTiVAkDFxU9PJLt1nh20K9RRpuHsR7ZnE2L7XookBbDBVLojCVSLGbvtSlxeUNnjAj6DbNsKyzbg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@rolldown/binding-linux-arm64-gnu@1.2.12':
resolution: {integrity: sha512-260UrKgn8tz39ak+SMDOirKzr7V04M9dWPw5llW00SwBivCZoWcRBKV1d8cXnRkUmSZA3BdiUmBHWk7734Ulpw==}
'@rolldown/binding-linux-arm64-gnu@1.2.13':
resolution: {integrity: sha512-DTpb/+jMiqWMPgphn4ksW1zW+XLJ6dJJ9FMvnIk9I291LhCctMPhMYJrP5t9p6C9qa3KXadDdUEZHBaPh3kNxQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@rolldown/binding-linux-arm64-musl@1.2.12':
resolution: {integrity: sha512-5YK1I9SqDkbPgc1IA8BgDl34suqUS2q0KWnBrirm0E51YjOs6eo6dV6jbQfNE/argHRSvd0QUGgtpIoYx+WWpw==}
'@rolldown/binding-linux-arm64-musl@1.2.13':
resolution: {integrity: sha512-xU+Kvv9N2A3SY35zFh1FWWNjxbadE/BKeqnkXe7vScU4GZsw757BlVmDLITZEq8DPpk6m7uoDYkK7P+x/uU5Ow==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [musl]
'@rolldown/binding-linux-ppc64-gnu@1.2.12':
resolution: {integrity: sha512-Rkcrmp7eFRg74yL5fXEU91JEWbdEPLevWwGtXpmhbjlD1StScbWTmO94Bhly+Mo+ketKYkdmM1vNUKeWSlx8cQ==}
'@rolldown/binding-linux-ppc64-gnu@1.2.13':
resolution: {integrity: sha512-XMk/hnhh25oQ756Lclb1Q11h4ll0xC0Esa5w4Vzp+mAE2S3AGJgeM0SonrIgY8fHhjarb6hcoTuwoFG0VVP2ig==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@rolldown/binding-linux-s390x-gnu@1.2.12':
resolution: {integrity: sha512-qvK4DuAsQc2BSjlx+Xr+IzOIvvxbGZqxFwdWfG6F518Erj0GGISyQbJ6pIappnOxlNPzNHvo/L0BwB30GZ+zVw==}
'@rolldown/binding-linux-s390x-gnu@1.2.13':
resolution: {integrity: sha512-U1BoTHYmlywE2n3HUWjzZ+8EQsKr+OwpxYuDWaubx42tUL8QSL7nOqRz/NVHanibbFP3M1Rxuprz/wNcbMKjqw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@rolldown/binding-linux-x64-gnu@1.2.12':
resolution: {integrity: sha512-Q9uLBO53Xd4QIq1WOycVQyPP1O4HhraEV2qqb3uTrnVw6QZih9duY4vNXOivL1xoUS1/z+W8eF4NMfl2a8Sdjw==}
'@rolldown/binding-linux-x64-gnu@1.2.13':
resolution: {integrity: sha512-J4cm80Pc6wEwV5AZ42o62sIQgDk+Y7R2s646jIwuvO+4V46QB58N4vVuMPWCBaNgursXLpmUWJV//WQAkPvHBQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [glibc]
'@rolldown/binding-linux-x64-musl@1.2.12':
resolution: {integrity: sha512-3IBxWFMjbOZskDPKv8Lf9BCnahlKuHthWkYnyIxOH/QcJrFcS4EmcenthApkwr/5+nEqZlLzeYbxeMaX7A5u4g==}
'@rolldown/binding-linux-x64-musl@1.2.13':
resolution: {integrity: sha512-W0euZS40U4V6JkmEnVCIX9mcsL6cbXQ4X8c2w+MMOIjFg68TXUW+u3RT+2e1t1pv9mg/EP3pDtK3POXdQ7Rxyw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [musl]
'@rolldown/binding-openharmony-arm64@1.2.12':
resolution: {integrity: sha512-xtX61xg4LKPkPWilZU1ynKClz5Gj4bf74LML4r3eVLWumKnGjoEr1OSHQhMdbBDoYTi+yjrujvpZe2pUnqCrrA==}
'@rolldown/binding-openharmony-arm64@1.2.13':
resolution: {integrity: sha512-do/AF/4n9MRshia3a5aXoy8xM2c6mgfT6D7H/dY6my5z+hfCIR4ab7mk4IRj++nsEQpKy39kd0DQnDq+r692tw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [openharmony]
'@rolldown/binding-win32-arm64-msvc@1.2.12':
resolution: {integrity: sha512-At7fPB6PCaIjzgIhEZFxuT+BBFqiQibJDT4d3PhiR3f4E7bbMZF4aKblbFfEM3sETRDd1YiQx/+U/g/B/ou5Ew==}
'@rolldown/binding-win32-arm64-msvc@1.2.13':
resolution: {integrity: sha512-6FtUf2cJZobutJdxnGYX8z0vtbgqU0b2v8vfBhkXb9wp2MppMFtkunE+IaOntyi01rkIQoPW2GHABtfzsC0BRQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [win32]
'@rolldown/binding-win32-x64-msvc@1.2.12':
resolution: {integrity: sha512-WIw2haVKwjuYdXkHaoC0mF8Le71TuCBxjrdKqLbJGctbBABj+ClfmNvtbOnzpq3RokNo5+V1qhtSzJyXorsklQ==}
'@rolldown/binding-win32-x64-msvc@1.2.13':
resolution: {integrity: sha512-UKhFaZTeTcbKrb3iU82m17jVcPEAoqDkCN5MBqgPyZSwp/cQmib21crTS0DdH7T1B7wZRWEI89YQAOJMet5yhg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [win32]
@@ -1106,8 +1106,8 @@ packages:
resolution: {integrity: sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==}
engines: {node: '>=0.10.0'}
caniuse-lite@1.0.30001814:
resolution: {integrity: sha512-/Uaf1lAzr59XcMpW0o96WoEfr+VXK2OX4U9AgFoiSHsVJ4HppnIFUjtYzsyDH2+tgANaQb2/oxYGwCPapN1FpA==}
caniuse-lite@1.0.30001815:
resolution: {integrity: sha512-uDybUEyfgbyJJ93J1vikTylBX31AkdVYeVPeffMQpf8XN7hSfr0oZOn4VFOIMNvtU5+rHvC5Udg2TgtJKHm23Q==}
caw@2.0.1:
resolution: {integrity: sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==}
@@ -1338,8 +1338,8 @@ packages:
duplexer3@0.1.5:
resolution: {integrity: sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==}
electron-to-chromium@1.5.448:
resolution: {integrity: sha512-c3DEaf2iJbLz7XvmYGZQrzaxy6Azt2/NcWAV1r3GkibEyRNkVer6t3JevvwAQ6gW2JBGGY2N/MGMS/QV+77Ldw==}
electron-to-chromium@1.5.449:
resolution: {integrity: sha512-dKeYk/3SFQz+nXi5whp3OuJzeWABEG4zCtkWJ9+Vby1E1iFM2y0gElRtQvNXRPJTsj8WAF4HMP7hvP790QtJ9g==}
emoji-regex@10.6.0:
resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==}
@@ -2531,10 +2531,10 @@ packages:
resolution: {integrity: sha512-C+y9x90UElAddDZmV4qOx9W53B61PO7cIqWz2dQsWlwswuq4mr8NEwytdGKboYbQlGZ3awrkTeNvcZiZNHnQ8A==}
engines: {node: '>=20'}
preact@10.29.8:
resolution: {integrity: sha512-ej2aVZ+vZ8WO7tvlQWRM9N63A0KzF9q4mWJfDUHgYaIofWY9hu74QdnQrjoPMmZi2/nZ5gN0bJCQF49xQqx09Q==}
preact@11.0.0:
resolution: {integrity: sha512-LRTLKuSe6VYPhvBDjwFaX+nuZnpsw6IN2GSboisAvhGsncylBmrbDCERhgKDn6yP2mAwbGvsB5OVyTe33M8gBg==}
peerDependencies:
preact-render-to-string: '>=5'
preact-render-to-string: '>=6.7.0'
peerDependenciesMeta:
preact-render-to-string:
optional: true
@@ -2682,8 +2682,8 @@ packages:
deprecated: Rimraf versions prior to v4 are no longer supported
hasBin: true
rolldown@1.2.12:
resolution: {integrity: sha512-8wafseiaG80xmXSfqidUNqZcylTlhmPZZt+za2m+js2sFZ8dTNlhIOV2WcbIPx2hgwPBJpEUGFAMZ9bgBBLTSQ==}
rolldown@1.2.13:
resolution: {integrity: sha512-/5apOkwWxtACcQtZ5WlrAsKS4JwXVThQPJZ3RqIruRY9UG9M8e0VlXN068xum/JRKA4aIUoJ13ghe/kGCvidiQ==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
@@ -3191,10 +3191,10 @@ snapshots:
'@babel/generator': 7.29.8
'@babel/helper-compilation-targets': 7.29.7
'@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2)
'@babel/helpers': 7.29.7
'@babel/helpers': 7.29.10
'@babel/parser': 7.29.9
'@babel/template': 7.29.7
'@babel/traverse': 7.29.8(supports-color@10.2.2)
'@babel/traverse': 7.29.10(supports-color@10.2.2)
'@babel/types': 7.29.8
'@jridgewell/remapping': 2.3.5
convert-source-map: 2.0.0
@@ -3229,7 +3229,7 @@ snapshots:
'@babel/helper-module-imports@7.29.7(supports-color@10.2.2)':
dependencies:
'@babel/traverse': 7.29.8(supports-color@10.2.2)
'@babel/traverse': 7.29.10(supports-color@10.2.2)
'@babel/types': 7.29.8
transitivePeerDependencies:
- supports-color
@@ -3239,7 +3239,7 @@ snapshots:
'@babel/core': 7.29.7(supports-color@10.2.2)
'@babel/helper-module-imports': 7.29.7(supports-color@10.2.2)
'@babel/helper-validator-identifier': 7.29.7
'@babel/traverse': 7.29.8(supports-color@10.2.2)
'@babel/traverse': 7.29.10(supports-color@10.2.2)
transitivePeerDependencies:
- supports-color
@@ -3251,7 +3251,7 @@ snapshots:
'@babel/helper-validator-option@7.29.7': {}
'@babel/helpers@7.29.7':
'@babel/helpers@7.29.10':
dependencies:
'@babel/template': 7.29.7
'@babel/types': 7.29.8
@@ -3283,7 +3283,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@babel/runtime@7.29.7': {}
'@babel/runtime@7.29.10': {}
'@babel/template@7.29.7':
dependencies:
@@ -3291,7 +3291,7 @@ snapshots:
'@babel/parser': 7.29.9
'@babel/types': 7.29.8
'@babel/traverse@7.29.8(supports-color@10.2.2)':
'@babel/traverse@7.29.10(supports-color@10.2.2)':
dependencies:
'@babel/code-frame': 7.29.7
'@babel/generator': 7.29.8
@@ -3323,7 +3323,7 @@ snapshots:
'@emotion/babel-plugin@11.13.5(supports-color@10.2.2)':
dependencies:
'@babel/helper-module-imports': 7.29.7(supports-color@10.2.2)
'@babel/runtime': 7.29.7
'@babel/runtime': 7.29.10
'@emotion/hash': 0.9.2
'@emotion/memoize': 0.9.0
'@emotion/serialize': 1.3.3
@@ -3354,7 +3354,7 @@ snapshots:
'@emotion/react@11.14.0(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2)':
dependencies:
'@babel/runtime': 7.29.7
'@babel/runtime': 7.29.10
'@emotion/babel-plugin': 11.13.5(supports-color@10.2.2)
'@emotion/cache': 11.14.0
'@emotion/serialize': 1.3.3
@@ -3380,7 +3380,7 @@ snapshots:
'@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2)':
dependencies:
'@babel/runtime': 7.29.7
'@babel/runtime': 7.29.10
'@emotion/babel-plugin': 11.13.5(supports-color@10.2.2)
'@emotion/is-prop-valid': 1.4.0
'@emotion/react': 11.14.0(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2)
@@ -3492,7 +3492,7 @@ snapshots:
'@mui/icons-material@9.4.0(@mui/material@9.4.0(@emotion/react@11.14.0(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(@types/react@19.3.0)(react@19.3.0)':
dependencies:
'@babel/runtime': 7.29.7
'@babel/runtime': 7.29.10
'@mui/material': 9.4.0(@emotion/react@11.14.0(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)
react: 19.3.0
optionalDependencies:
@@ -3500,7 +3500,7 @@ snapshots:
'@mui/material@9.4.0(@emotion/react@11.14.0(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(@types/react@19.3.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)':
dependencies:
'@babel/runtime': 7.29.7
'@babel/runtime': 7.29.10
'@mui/core-downloads-tracker': 9.4.0
'@mui/system': 9.4.0(@emotion/react@11.14.0(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(@types/react@19.3.0)(react@19.3.0)
'@mui/types': 9.4.0(@types/react@19.3.0)
@@ -3521,7 +3521,7 @@ snapshots:
'@mui/private-theming@9.4.0(@types/react@19.3.0)(react@19.3.0)':
dependencies:
'@babel/runtime': 7.29.7
'@babel/runtime': 7.29.10
'@mui/utils': 9.4.0(@types/react@19.3.0)(react@19.3.0)
prop-types: 15.8.1
react: 19.3.0
@@ -3530,7 +3530,7 @@ snapshots:
'@mui/styled-engine@9.4.0(@emotion/react@11.14.0(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(react@19.3.0)':
dependencies:
'@babel/runtime': 7.29.7
'@babel/runtime': 7.29.10
'@emotion/cache': 11.14.0
'@emotion/serialize': 1.3.3
'@emotion/sheet': 1.4.0
@@ -3543,7 +3543,7 @@ snapshots:
'@mui/system@9.4.0(@emotion/react@11.14.0(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(@types/react@19.3.0)(react@19.3.0)':
dependencies:
'@babel/runtime': 7.29.7
'@babel/runtime': 7.29.10
'@mui/private-theming': 9.4.0(@types/react@19.3.0)(react@19.3.0)
'@mui/styled-engine': 9.4.0(@emotion/react@11.14.0(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(react@19.3.0)
'@mui/types': 9.4.0(@types/react@19.3.0)
@@ -3559,13 +3559,13 @@ snapshots:
'@mui/types@9.4.0(@types/react@19.3.0)':
dependencies:
'@babel/runtime': 7.29.7
'@babel/runtime': 7.29.10
optionalDependencies:
'@types/react': 19.3.0
'@mui/utils@9.4.0(@types/react@19.3.0)(react@19.3.0)':
dependencies:
'@babel/runtime': 7.29.7
'@babel/runtime': 7.29.10
'@mui/types': 9.4.0(@types/react@19.3.0)
'@types/prop-types': 15.7.15
clsx: 2.1.1
@@ -3587,16 +3587,16 @@ snapshots:
'@nodelib/fs.scandir': 2.1.5
fastq: 1.20.3
'@oxc-project/types@0.152.0': {}
'@oxc-project/types@0.153.0': {}
'@popperjs/core@2.11.8': {}
'@preact/preset-vite@2.10.6(@babel/core@7.29.7(supports-color@10.2.2))(preact@10.29.8)(supports-color@10.2.2)(vite@8.3.3(@types/node@26.6.4)(terser@5.51.2))':
'@preact/preset-vite@2.10.6(@babel/core@7.29.7(supports-color@10.2.2))(preact@11.0.0)(supports-color@10.2.2)(vite@8.3.3(@types/node@26.6.4)(terser@5.51.2))':
dependencies:
'@babel/core': 7.29.7(supports-color@10.2.2)
'@babel/plugin-transform-react-jsx': 7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2)
'@babel/plugin-transform-react-jsx-development': 7.29.7(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2)
'@prefresh/vite': 2.4.12(preact@10.29.8)(supports-color@10.2.2)(vite@8.3.3(@types/node@26.6.4)(terser@5.51.2))
'@prefresh/vite': 2.4.12(preact@11.0.0)(supports-color@10.2.2)(vite@8.3.3(@types/node@26.6.4)(terser@5.51.2))
'@rollup/pluginutils': 5.4.0
babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.29.7(supports-color@10.2.2))
debug: 4.4.3(supports-color@10.2.2)
@@ -3614,69 +3614,69 @@ snapshots:
dependencies:
'@babel/core': 7.29.7(supports-color@10.2.2)
'@prefresh/core@1.5.11(preact@10.29.8)':
'@prefresh/core@1.5.11(preact@11.0.0)':
dependencies:
preact: 10.29.8
preact: 11.0.0
'@prefresh/utils@1.2.1': {}
'@prefresh/vite@2.4.12(preact@10.29.8)(supports-color@10.2.2)(vite@8.3.3(@types/node@26.6.4)(terser@5.51.2))':
'@prefresh/vite@2.4.12(preact@11.0.0)(supports-color@10.2.2)(vite@8.3.3(@types/node@26.6.4)(terser@5.51.2))':
dependencies:
'@babel/core': 7.29.7(supports-color@10.2.2)
'@prefresh/babel-plugin': 0.5.4(@babel/core@7.29.7(supports-color@10.2.2))
'@prefresh/core': 1.5.11(preact@10.29.8)
'@prefresh/core': 1.5.11(preact@11.0.0)
'@prefresh/utils': 1.2.1
'@rollup/pluginutils': 4.2.1
preact: 10.29.8
preact: 11.0.0
vite: 8.3.3(@types/node@26.6.4)(terser@5.51.2)
transitivePeerDependencies:
- supports-color
'@remix-run/route-pattern@0.22.1': {}
'@rolldown/binding-android-arm-eabi@1.2.12':
'@rolldown/binding-android-arm-eabi@1.2.13':
optional: true
'@rolldown/binding-android-arm64@1.2.12':
'@rolldown/binding-android-arm64@1.2.13':
optional: true
'@rolldown/binding-darwin-arm64@1.2.12':
'@rolldown/binding-darwin-arm64@1.2.13':
optional: true
'@rolldown/binding-darwin-x64@1.2.12':
'@rolldown/binding-darwin-x64@1.2.13':
optional: true
'@rolldown/binding-freebsd-x64@1.2.12':
'@rolldown/binding-freebsd-x64@1.2.13':
optional: true
'@rolldown/binding-linux-arm-gnueabihf@1.2.12':
'@rolldown/binding-linux-arm-gnueabihf@1.2.13':
optional: true
'@rolldown/binding-linux-arm64-gnu@1.2.12':
'@rolldown/binding-linux-arm64-gnu@1.2.13':
optional: true
'@rolldown/binding-linux-arm64-musl@1.2.12':
'@rolldown/binding-linux-arm64-musl@1.2.13':
optional: true
'@rolldown/binding-linux-ppc64-gnu@1.2.12':
'@rolldown/binding-linux-ppc64-gnu@1.2.13':
optional: true
'@rolldown/binding-linux-s390x-gnu@1.2.12':
'@rolldown/binding-linux-s390x-gnu@1.2.13':
optional: true
'@rolldown/binding-linux-x64-gnu@1.2.12':
'@rolldown/binding-linux-x64-gnu@1.2.13':
optional: true
'@rolldown/binding-linux-x64-musl@1.2.12':
'@rolldown/binding-linux-x64-musl@1.2.13':
optional: true
'@rolldown/binding-openharmony-arm64@1.2.12':
'@rolldown/binding-openharmony-arm64@1.2.13':
optional: true
'@rolldown/binding-win32-arm64-msvc@1.2.12':
'@rolldown/binding-win32-arm64-msvc@1.2.13':
optional: true
'@rolldown/binding-win32-x64-msvc@1.2.12':
'@rolldown/binding-win32-x64-msvc@1.2.13':
optional: true
'@rolldown/pluginutils@1.0.1': {}
@@ -3707,7 +3707,7 @@ snapshots:
dependencies:
'@babel/generator': 7.29.8
'@babel/parser': 7.29.9
'@babel/traverse': 7.29.8(supports-color@10.2.2)
'@babel/traverse': 7.29.10(supports-color@10.2.2)
'@babel/types': 7.29.8
javascript-natural-sort: 0.7.1
lodash-es: 4.18.1
@@ -3928,7 +3928,7 @@ snapshots:
babel-plugin-macros@3.1.0:
dependencies:
'@babel/runtime': 7.29.7
'@babel/runtime': 7.29.10
cosmiconfig: 7.1.0
resolve: 1.22.13
@@ -4004,8 +4004,8 @@ snapshots:
browserslist@4.29.3:
dependencies:
baseline-browser-mapping: 2.11.27
caniuse-lite: 1.0.30001814
electron-to-chromium: 1.5.448
caniuse-lite: 1.0.30001815
electron-to-chromium: 1.5.449
node-releases: 2.0.57
update-browserslist-db: 1.3.3(browserslist@4.29.3)
@@ -4075,7 +4075,7 @@ snapshots:
camelcase@2.1.1: {}
caniuse-lite@1.0.30001814: {}
caniuse-lite@1.0.30001815: {}
caw@2.0.1:
dependencies:
@@ -4296,7 +4296,7 @@ snapshots:
dom-helpers@5.2.1:
dependencies:
'@babel/runtime': 7.29.7
'@babel/runtime': 7.29.10
csstype: 3.2.3
dom-serializer@1.4.1:
@@ -4370,7 +4370,7 @@ snapshots:
duplexer3@0.1.5: {}
electron-to-chromium@1.5.448: {}
electron-to-chromium@1.5.449: {}
emoji-regex@10.6.0: {}
@@ -5501,7 +5501,7 @@ snapshots:
powershell-utils@0.2.1: {}
preact@10.29.8: {}
preact@11.0.0: {}
prelude-ls@1.2.1: {}
@@ -5567,7 +5567,7 @@ snapshots:
react-transition-group@4.4.5(react-dom@19.3.0(react@19.3.0))(react@19.3.0):
dependencies:
'@babel/runtime': 7.29.7
'@babel/runtime': 7.29.10
dom-helpers: 5.2.1
loose-envify: 1.4.0
prop-types: 15.8.1
@@ -5581,7 +5581,7 @@ snapshots:
react-window@1.8.11(react-dom@19.3.0(react@19.3.0))(react@19.3.0):
dependencies:
'@babel/runtime': 7.29.7
'@babel/runtime': 7.29.10
memoize-one: 5.2.1
react: 19.3.0
react-dom: 19.3.0(react@19.3.0)
@@ -5639,35 +5639,35 @@ snapshots:
dependencies:
glob: 7.2.3
rolldown@1.2.12:
rolldown@1.2.13:
dependencies:
'@oxc-project/types': 0.152.0
'@oxc-project/types': 0.153.0
'@rolldown/pluginutils': 1.0.1
optionalDependencies:
'@rolldown/binding-android-arm-eabi': 1.2.12
'@rolldown/binding-android-arm64': 1.2.12
'@rolldown/binding-darwin-arm64': 1.2.12
'@rolldown/binding-darwin-x64': 1.2.12
'@rolldown/binding-freebsd-x64': 1.2.12
'@rolldown/binding-linux-arm-gnueabihf': 1.2.12
'@rolldown/binding-linux-arm64-gnu': 1.2.12
'@rolldown/binding-linux-arm64-musl': 1.2.12
'@rolldown/binding-linux-ppc64-gnu': 1.2.12
'@rolldown/binding-linux-s390x-gnu': 1.2.12
'@rolldown/binding-linux-x64-gnu': 1.2.12
'@rolldown/binding-linux-x64-musl': 1.2.12
'@rolldown/binding-openharmony-arm64': 1.2.12
'@rolldown/binding-win32-arm64-msvc': 1.2.12
'@rolldown/binding-win32-x64-msvc': 1.2.12
'@rolldown/binding-android-arm-eabi': 1.2.13
'@rolldown/binding-android-arm64': 1.2.13
'@rolldown/binding-darwin-arm64': 1.2.13
'@rolldown/binding-darwin-x64': 1.2.13
'@rolldown/binding-freebsd-x64': 1.2.13
'@rolldown/binding-linux-arm-gnueabihf': 1.2.13
'@rolldown/binding-linux-arm64-gnu': 1.2.13
'@rolldown/binding-linux-arm64-musl': 1.2.13
'@rolldown/binding-linux-ppc64-gnu': 1.2.13
'@rolldown/binding-linux-s390x-gnu': 1.2.13
'@rolldown/binding-linux-x64-gnu': 1.2.13
'@rolldown/binding-linux-x64-musl': 1.2.13
'@rolldown/binding-openharmony-arm64': 1.2.13
'@rolldown/binding-win32-arm64-msvc': 1.2.13
'@rolldown/binding-win32-x64-msvc': 1.2.13
rollup-plugin-visualizer@7.1.1(rolldown@1.2.12):
rollup-plugin-visualizer@7.1.1(rolldown@1.2.13):
dependencies:
open: 11.0.4
picomatch: 4.0.7
source-map: 0.8.0
yargs: 18.2.0
optionalDependencies:
rolldown: 1.2.12
rolldown: 1.2.13
run-applescript@7.1.0: {}
@@ -6026,7 +6026,7 @@ snapshots:
lightningcss: 1.33.0
picomatch: 4.0.7
postcss: 8.5.29
rolldown: 1.2.12
rolldown: 1.2.13
tinyglobby: 0.2.17
optionalDependencies:
'@types/node': 26.6.4
+1 -1
View File
@@ -174,7 +174,7 @@ const Devices = memo(() => {
}
`,
Table: `
--data-table-library_grid-template-columns: repeat(1, minmax(0, 1fr)) 130px;
--data-table-library_grid-template-columns: repeat(1, minmax(0, 1fr)) 170px;
`,
HeaderRow: `
.th {
-12
View File
@@ -1,5 +1,3 @@
import { useContext } from 'react';
import AccessTimeIcon from '@mui/icons-material/AccessTime';
import DeviceHubIcon from '@mui/icons-material/DeviceHub';
import DirectionsBusIcon from '@mui/icons-material/DirectionsBus';
@@ -24,7 +22,6 @@ import { useRequest } from 'alova/client';
import { busConnectionStatus } from 'app/main/types';
import { FormLoader, SectionContent, useLayoutTitle } from 'components';
import ListMenuItem from 'components/layout/ListMenuItem';
import { AuthenticatedContext } from 'contexts/authentication';
import { useI18nContext } from 'i18n/i18n-react';
import { NTPSyncStatus, NetworkConnectionStatus, SystemStatusCodes } from 'types';
import { useInterval } from 'utils';
@@ -56,8 +53,6 @@ const SystemStatus = () => {
useLayoutTitle(LL.STATUS_OF(''));
const { me } = useContext(AuthenticatedContext);
const { data, send: loadData, error } = useRequest(readSystemStatus);
useInterval(() => {
@@ -211,7 +206,6 @@ const SystemStatus = () => {
</ListItem>
<ListMenuItem
disabled={!me.admin}
icon={MemoryIcon}
bgcolor="#68374d"
label={LL.HARDWARE()}
@@ -220,7 +214,6 @@ const SystemStatus = () => {
/>
<ListMenuItem
disabled={!me.admin}
icon={DirectionsBusIcon}
bgcolor={busStatusHighlight}
label={LL.DATA_TRAFFIC()}
@@ -229,7 +222,6 @@ const SystemStatus = () => {
/>
<ListMenuItem
disabled={!me.admin}
icon={
data.network_status === NetworkConnectionStatus.WIFI_STATUS_CONNECTED
? WifiIcon
@@ -242,7 +234,6 @@ const SystemStatus = () => {
/>
<ListMenuItem
disabled={!me.admin}
icon={DeviceHubIcon}
bgcolor={activeHighlight(data.mqtt_status)}
label="MQTT"
@@ -251,7 +242,6 @@ const SystemStatus = () => {
/>
<ListMenuItem
disabled={!me.admin}
icon={AccessTimeIcon}
bgcolor={ntpStatusHighlight}
label="NTP"
@@ -260,7 +250,6 @@ const SystemStatus = () => {
/>
<ListMenuItem
disabled={!me.admin}
icon={SettingsInputAntennaIcon}
bgcolor={activeHighlight(data.ap_status)}
label={LL.ACCESS_POINT(0)}
@@ -269,7 +258,6 @@ const SystemStatus = () => {
/>
<ListMenuItem
disabled={!me.admin}
icon={LogoDevIcon}
bgcolor="#40828f"
label={LL.LOG_OF(LL.SYSTEM(0))}
+9
View File
@@ -20,6 +20,8 @@
#include <Arduino.h>
#include <sys/time.h>
namespace uuid {
static uint64_t now_millis = 0;
@@ -41,4 +43,11 @@ uint32_t get_uptime() {
return (uint32_t)now_millis;
}
// both clocks are read live and subtracted in us, rounding each to ms or s first makes the offset jitter
int64_t get_wall_offset_ms() {
struct timeval tv;
gettimeofday(&tv, nullptr);
return ((int64_t)tv.tv_sec * 1000000 + tv.tv_usec - esp_timer_get_time()) / 1000;
}
} // namespace uuid
+3
View File
@@ -105,6 +105,9 @@ uint64_t get_uptime_ms();
uint32_t get_uptime();
uint32_t get_uptime_sec();
// milliseconds to add to an uptime in ms to get the wall clock time in ms since the epoch
int64_t get_wall_offset_ms();
void set_uptime();
} // namespace uuid
+6 -5
View File
@@ -106,14 +106,15 @@ void Shell::output_logs() {
}
while (1) {
time_t offset = time(nullptr) - uuid::get_uptime_sec();
if (offset < 1500000000L) {
int64_t offset_ms = uuid::get_wall_offset_ms();
if (offset_ms < 1500000000000LL) {
print(uuid::log::format_timestamp_ms(message.content_->uptime_ms, 3));
} else {
time_t t1 = offset + (time_t)(message.content_->uptime_ms / 1000);
char timestr[25];
int64_t wall_ms = offset_ms + (int64_t)message.content_->uptime_ms;
time_t t1 = (time_t)(wall_ms / 1000);
char timestr[25];
strftime(timestr, 25, "%FT%T", localtime(&t1));
printf("%s.%03d", timestr, (uint16_t)(message.content_->uptime_ms % 1000));
printf("%s.%03d", timestr, (int)(wall_ms % 1000));
}
printf(" %c %lu: [%s] ", uuid::log::format_level_char(message.content_->level), message.id_, message.content_->name);
+1 -1
View File
@@ -17,5 +17,5 @@
"@trivago/prettier-plugin-sort-imports": "^6.0.2",
"prettier": "^3.9.9"
},
"packageManager": "pnpm@12.6.0"
"packageManager": "pnpm@12.10.1"
}
+65 -65
View File
@@ -7,153 +7,153 @@ importers:
configDependencies: {}
packageManagerDependencies:
pnpm:
specifier: 12.6.0
version: 12.6.0
specifier: 12.10.1
version: 12.10.1
packages:
'@pnpm/exe.android-arm64@12.6.0':
resolution: {integrity: sha512-kviIHft9h02q+7N2In7tSL9T/HRUSGwYmU74YPtsWU5ee7vgqPyC0JT6RRX6miW+NxX1CvHgQxg69qq1qTLJYQ==}
'@pnpm/exe.android-arm64@12.10.1':
resolution: {integrity: sha512-CVTlHPwNvadQCJD9bGSMzWIhFX8QpjtqC2c27dhdnn/9iKzEjZ3qL62o3gHpKbIuo6qn4WxTKRoaokgNdReBig==}
cpu: [arm64]
os: [android]
'@pnpm/exe.android-x64@12.6.0':
resolution: {integrity: sha512-CT8aJKLq2mtZFE71pr4E5Z2xHL8uGnRGr+NclDqsXlVF4SVcQ2QAs14mWi0C8gjT4hbmi+Q0lJRRIkMAWfjjng==}
'@pnpm/exe.android-x64@12.10.1':
resolution: {integrity: sha512-NFiYLIaodY7da0XIebwcU3JoP7IK/lzF7zgKSSP+9H+QcFnQ1GDfBkuBKCYJzZ+Xu0WH54neIPLBBCaOjaaauA==}
cpu: [x64]
os: [android]
'@pnpm/exe.darwin-arm64@12.6.0':
resolution: {integrity: sha512-rafpVkjzugKBMxSvGQd5wK1x5eOTkD/+lcJIFHeQhvd+BJ8kDisOOvwhQDrpGd4vd2Fx+hhW0P2Ptt638OlhFg==}
'@pnpm/exe.darwin-arm64@12.10.1':
resolution: {integrity: sha512-0O8tdQ8ijlPJudXspLMTcitMkdBEz6uUflazL5uQE0WMs85oQIp0U+5hfEktMFB64QqEhjqlvvujTwbzdr9oMg==}
cpu: [arm64]
os: [darwin]
'@pnpm/exe.darwin-x64@12.6.0':
resolution: {integrity: sha512-72Jpuv1m24gI8zUNcaylYpBWEhBzz1VPhnDIU2GYM2eRP+KsOqVLwV78i+JrihI39zY2NNXmaN4eAKX1inpaDQ==}
'@pnpm/exe.darwin-x64@12.10.1':
resolution: {integrity: sha512-ud+1/uZOKEo8P/AsPynOJc/LNwfI0j6WwCElibj71rU9l4nIBnsSn+wWTIPZPkZ4BBSH5+82azSnAARMyJ1lNA==}
cpu: [x64]
os: [darwin]
'@pnpm/exe.freebsd-x64@12.6.0':
resolution: {integrity: sha512-LON4QgNy1w/XF4uySZIyC/5hEB0oGdelXsY9tSKqstER+2j2X2oHz67skD11RRd/HWFRtMr64shQZ4I9ZoZ0zg==}
'@pnpm/exe.freebsd-x64@12.10.1':
resolution: {integrity: sha512-mj9PE5rf8uAfQQ2K66HSATMSut+lNiB4eSqFd5+azFVCMnxNSy/32xpZQJT21PhnN3Y4qbK+iKHe5nWAxSuRhw==}
cpu: [x64]
os: [freebsd]
'@pnpm/exe.linux-arm64-musl@12.6.0':
resolution: {integrity: sha512-BdDpX+DeaMUc5x6WNcE6FkmFy36NwrBbBvwsZU737Zt3u1fTY+iKFPchjEQNCM4rT6q6xvF2oN3ZwExGsJCkxQ==}
'@pnpm/exe.linux-arm64-musl@12.10.1':
resolution: {integrity: sha512-xba+00wZJ8Um6rBJJjWl88uJj0tydB8dtomvjlCLvi0uL32vpa9CRP8Vv26FIXvbiZ1bo2RCzYt/eChxJVV52w==}
cpu: [arm64]
os: [linux]
libc: [musl]
'@pnpm/exe.linux-arm64@12.6.0':
resolution: {integrity: sha512-8h2sNoIhHDpHDYqZZCh9PXr6krqW10btb0GHVGuw710muDHlFAHMtUG2ogmaHge6zJG1xgY4Y7mwX5g/LWvrYg==}
'@pnpm/exe.linux-arm64@12.10.1':
resolution: {integrity: sha512-oBdMp69ScC9UnniG4qZAQVr2fBDSXjm4yk/72vkEVyrlwS23yMxcRQl7Qdo3sgXPAygY6TWnPRKm4rXzjoyW7w==}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@pnpm/exe.linux-ppc64@12.6.0':
resolution: {integrity: sha512-ld6xgcEhFCFrsVsJhbmdmR714PnsEspO/Ij8w0/D7OSiz2hYGu3fZd5tKRxOI5m6H6Gl0/RRFAPncTHbsgXVjQ==}
'@pnpm/exe.linux-ppc64@12.10.1':
resolution: {integrity: sha512-Yyb3wu09h3c7mLme270uHFiVaAIUHC411Ru9LIU2BKUIstrGlXa9OqqVWoXaRgYRdFdOFknkwG7GNn6ygwLbnw==}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@pnpm/exe.linux-riscv64@12.6.0':
resolution: {integrity: sha512-HIbImydoC3J8NFt+8MXfhTCf5rO6NjCMyinSAHac0VmV8uCHw+kbQkyAzxV84rzz9ZOzmBOnj0b1N461UIYGsw==}
'@pnpm/exe.linux-riscv64@12.10.1':
resolution: {integrity: sha512-PdkeUFFkybknnGkWP0H22eMpIiS4OZXL5BcQzF4lh+vmrW3IaC2HOkbANKgot/PKO0Kl77pzA/6PKFxgbgfXIQ==}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@pnpm/exe.linux-s390x@12.6.0':
resolution: {integrity: sha512-DjSqT7+BZ/lWcDHwNMuzsRVfyxUimh+D54Xw4tSWbdVVQhtWtNMUyI93LVnwCmsoEpar2gC3SFeAgywx37svKQ==}
'@pnpm/exe.linux-s390x@12.10.1':
resolution: {integrity: sha512-1okKuHKJwJPAbofDxfhZWAUxEWtee4ZSf7Pah8kcvocaJkf2WxFJ5KVTiNIvDml5GLidDQsgf7Pcf/WHbCak7Q==}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@pnpm/exe.linux-x64-musl@12.6.0':
resolution: {integrity: sha512-31lKeGPmRE6xfV6I3VjaEGVFRei14pl/zgoFDK4w+UkbJqOuNl2Ht3O1GuqNIg3Gl14qTEb4kZRAYFHXifDx9A==}
'@pnpm/exe.linux-x64-musl@12.10.1':
resolution: {integrity: sha512-e6IqzVNkPa7srFKJKnY23uWJ+qz0LaRWiTUo/sHfFXRRMRzB5uNOr6qWWip/jqhdGwU91n9J7LrEYZ6e0tRczw==}
cpu: [x64]
os: [linux]
libc: [musl]
'@pnpm/exe.linux-x64@12.6.0':
resolution: {integrity: sha512-qFWBneHJAJ73W4whtbaFOL1M/7DBC6ILHXuxc7ZPtEhfPuT1zeZiGrmKHoMAfJA+mcm6xhOFljqVTUS+00Jabw==}
'@pnpm/exe.linux-x64@12.10.1':
resolution: {integrity: sha512-ZByV0DRgWzGaDSjT5ddRBASdwz+r/qPMYh7o6RGmPQjtRGNFbSl94xY2DcAM8mqCOZJUUDtAXQ+wpBXcdpKlkg==}
cpu: [x64]
os: [linux]
libc: [glibc]
'@pnpm/exe.win32-arm64@12.6.0':
resolution: {integrity: sha512-OhfefXEEykZlslSUhR8PPRe6MVPV3Oink/dVfIecE5velpc7j80cZYsHlaDrtRDcm3TPwQHkaRW1SJ1efX9oFg==}
'@pnpm/exe.win32-arm64@12.10.1':
resolution: {integrity: sha512-I7QZHcjioG7orFeCRUFUHByJ1G0zFPnAlaGGyrUvb6MGkv5oeNwNPl7t+Gp+7zHfnMcgLGJ1a+Wfim0IDw3lOw==}
cpu: [arm64]
os: [win32]
'@pnpm/exe.win32-x64@12.6.0':
resolution: {integrity: sha512-L2tuyrD2+Imgxs3VK/ST/2L3xD6vDP0ktJQxM0TaGw7TbAQEMq+RMc8iK6Ew7Id579uzjJe8jSfJID2ZGsOHCA==}
'@pnpm/exe.win32-x64@12.10.1':
resolution: {integrity: sha512-4WJFdp58EKlCj0zLobrXU0vpszSZIr4X/3y/uNbAQqGW0zE+VdruZB0gFc3L2kzsUzVwTYbaCn+XEhnCYSAlTg==}
cpu: [x64]
os: [win32]
pnpm@12.6.0:
resolution: {integrity: sha512-PvaPlRyxEawgS0paFvCy3fDaVqluBBPoHYVdnwtV75JnFHCQKOHNAMQFwsX7e56OxNxGd3yAXQNzwvL/AP0g7A==}
pnpm@12.10.1:
resolution: {integrity: sha512-ukCjfrGjcNYP6oxM8dNkwTvMzvUY6YrSvO6VT1OdONo3RY5YJho/pV4GUjRQ6g//+fSXsTW+QfLBXBZCusrObA==}
engines: {node: '>=18.*'}
hasBin: true
snapshots:
'@pnpm/exe.android-arm64@12.6.0':
'@pnpm/exe.android-arm64@12.10.1':
optional: true
'@pnpm/exe.android-x64@12.6.0':
'@pnpm/exe.android-x64@12.10.1':
optional: true
'@pnpm/exe.darwin-arm64@12.6.0':
'@pnpm/exe.darwin-arm64@12.10.1':
optional: true
'@pnpm/exe.darwin-x64@12.6.0':
'@pnpm/exe.darwin-x64@12.10.1':
optional: true
'@pnpm/exe.freebsd-x64@12.6.0':
'@pnpm/exe.freebsd-x64@12.10.1':
optional: true
'@pnpm/exe.linux-arm64-musl@12.6.0':
'@pnpm/exe.linux-arm64-musl@12.10.1':
optional: true
'@pnpm/exe.linux-arm64@12.6.0':
'@pnpm/exe.linux-arm64@12.10.1':
optional: true
'@pnpm/exe.linux-ppc64@12.6.0':
'@pnpm/exe.linux-ppc64@12.10.1':
optional: true
'@pnpm/exe.linux-riscv64@12.6.0':
'@pnpm/exe.linux-riscv64@12.10.1':
optional: true
'@pnpm/exe.linux-s390x@12.6.0':
'@pnpm/exe.linux-s390x@12.10.1':
optional: true
'@pnpm/exe.linux-x64-musl@12.6.0':
'@pnpm/exe.linux-x64-musl@12.10.1':
optional: true
'@pnpm/exe.linux-x64@12.6.0':
'@pnpm/exe.linux-x64@12.10.1':
optional: true
'@pnpm/exe.win32-arm64@12.6.0':
'@pnpm/exe.win32-arm64@12.10.1':
optional: true
'@pnpm/exe.win32-x64@12.6.0':
'@pnpm/exe.win32-x64@12.10.1':
optional: true
pnpm@12.6.0:
pnpm@12.10.1:
optionalDependencies:
'@pnpm/exe.android-arm64': 12.6.0
'@pnpm/exe.android-x64': 12.6.0
'@pnpm/exe.darwin-arm64': 12.6.0
'@pnpm/exe.darwin-x64': 12.6.0
'@pnpm/exe.freebsd-x64': 12.6.0
'@pnpm/exe.linux-arm64': 12.6.0
'@pnpm/exe.linux-arm64-musl': 12.6.0
'@pnpm/exe.linux-ppc64': 12.6.0
'@pnpm/exe.linux-riscv64': 12.6.0
'@pnpm/exe.linux-s390x': 12.6.0
'@pnpm/exe.linux-x64': 12.6.0
'@pnpm/exe.linux-x64-musl': 12.6.0
'@pnpm/exe.win32-arm64': 12.6.0
'@pnpm/exe.win32-x64': 12.6.0
'@pnpm/exe.android-arm64': 12.10.1
'@pnpm/exe.android-x64': 12.10.1
'@pnpm/exe.darwin-arm64': 12.10.1
'@pnpm/exe.darwin-x64': 12.10.1
'@pnpm/exe.freebsd-x64': 12.10.1
'@pnpm/exe.linux-arm64': 12.10.1
'@pnpm/exe.linux-arm64-musl': 12.10.1
'@pnpm/exe.linux-ppc64': 12.10.1
'@pnpm/exe.linux-riscv64': 12.10.1
'@pnpm/exe.linux-s390x': 12.10.1
'@pnpm/exe.linux-x64': 12.10.1
'@pnpm/exe.linux-x64-musl': 12.10.1
'@pnpm/exe.win32-arm64': 12.10.1
'@pnpm/exe.win32-x64': 12.10.1
---
lockfileVersion: '9.0'
@@ -211,8 +211,8 @@ packages:
resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==}
engines: {node: '>=6.9.0'}
'@babel/traverse@7.29.8':
resolution: {integrity: sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==}
'@babel/traverse@7.29.10':
resolution: {integrity: sha512-B3lYAs2nkKskbgQ1nfy8Ma9ao9Q1rntTAQHrzzyDuj+TSO+X3le6PfWwqDvodsb+OumE10eMFfuMCTQSQ5iuIQ==}
engines: {node: '>=6.9.0'}
'@babel/types@7.29.8':
@@ -340,7 +340,7 @@ snapshots:
'@babel/parser': 7.29.9
'@babel/types': 7.29.8
'@babel/traverse@7.29.8':
'@babel/traverse@7.29.10':
dependencies:
'@babel/code-frame': 7.29.7
'@babel/generator': 7.29.8
@@ -377,7 +377,7 @@ snapshots:
dependencies:
'@babel/generator': 7.29.8
'@babel/parser': 7.29.9
'@babel/traverse': 7.29.8
'@babel/traverse': 7.29.10
'@babel/types': 7.29.8
javascript-natural-sort: 0.7.1
lodash-es: 4.18.1
+2
View File
@@ -50,6 +50,8 @@ build_flags =
; -D EMSESP_MQTT_STACKSIZE=5120 ; default
-D EMSESP_UART_RUNNING_CORE=1 ; default any core
; -D EMSESP_UART_STACKSIZE=2560 ; default
; -D EMSESP_GATEWAY_TX_HOLD ; hold Tx while a K30RF/KM200 gateway is syncing, see issue #3094
; -D EMSESP_TX_PRE_DELAY=1000 ; wait this many us before each Tx so we don't overlap the master's break, see issue #3094
unbuild_flags =
${common.core_unbuild_flags}
+127
View File
@@ -49,6 +49,18 @@ uint16_t EMSESP::wait_validate_ = 0;
bool EMSESP::wait_km_ = false;
uint32_t EMSESP::last_fetch_ = 0;
#ifdef EMSESP_GATEWAY_TX_HOLD
uint32_t EMSESP::gateway_hold_until_ = 0;
uint32_t EMSESP::gateway_hold_start_ = 0;
uint32_t EMSESP::gateway_cooldown_until_ = 0;
uint32_t EMSESP::gateway_window_start_ = 0;
uint8_t EMSESP::gateway_window_count_ = 0;
uint32_t EMSESP::gateway_fast_start_ = 0;
uint8_t EMSESP::gateway_fast_count_ = 0;
uint8_t EMSESP::last_version_request_src_ = 0;
uint32_t EMSESP::last_version_request_time_ = 0;
#endif
uint32_t EMSESP::last_entity_change_ = 0;
bool EMSESP::entity_compaction_pending_ = false;
@@ -1130,9 +1142,26 @@ void EMSESP::process_version(const std::shared_ptr<const Telegram> & telegram) {
brand = EMSdevice::Brand::NO_BRAND; // unknown
}
#ifdef EMSESP_GATEWAY_TX_HOLD
// skip the name request if we already know this device and its name
bool known = false;
for (const auto & emsdevice : emsdevices) {
if (emsdevice && emsdevice->is_device_id(device_id) && emsdevice->product_id() == product_id && !emsdevice->model().empty()) {
known = true;
break;
}
}
#endif
// add it - will be overwritten if device already exists
(void)add_device(device_id, product_id, version, brand);
#ifdef EMSESP_GATEWAY_TX_HOLD
if (known) {
return;
}
#endif
// request the deviceName from telegram 0x01
send_read_request(EMSdevice::EMS_TYPE_NAME, device_id, 27);
}
@@ -1249,7 +1278,16 @@ bool EMSESP::process_telegram(const std::shared_ptr<const Telegram> & telegram)
LOG_NOTICE("%s", pretty_telegram(telegram).c_str());
}
if (!wait_km_ && !found_device && (telegram->src != EMSbus::ems_bus_id()) && (telegram->message_length > 0)) {
#ifdef EMSESP_GATEWAY_TX_HOLD
// a new device often sends several broadcasts before its version reply is processed, only ask once
if (telegram->src != last_version_request_src_ || uuid::get_uptime() - last_version_request_time_ > 5000) {
last_version_request_src_ = telegram->src;
last_version_request_time_ = uuid::get_uptime();
send_read_request(EMSdevice::EMS_TYPE_VERSION, telegram->src);
}
#else
send_read_request(EMSdevice::EMS_TYPE_VERSION, telegram->src);
#endif
}
}
}
@@ -1511,6 +1549,13 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const
// Print to LOG showing we've added a new device
LOG_INFO("Detected EMS device: %s (0x%02X)", EMSdevice::device_type_2_device_name(device_type), device_id);
#ifdef EMSESP_GATEWAY_TX_HOLD
// a gateway appearing while we're running is most likely starting up and about to sync
if (device_id == EMSdevice::EMS_DEVICE_ID_GATEWAY1) {
gateway_tx_hold_start();
}
#endif
// register the MQTT subscribe topic for this device
// except for controller and gateway
if ((device_type == DeviceType::CONTROLLER) || (device_type == DeviceType::GATEWAY)) {
@@ -1656,6 +1701,13 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) {
}
#endif
// check for poll to us, if so send top message from Tx queue immediately and quit
#ifdef EMSESP_GATEWAY_TX_HOLD
if (poll_id == EMSbus::ems_bus_id() && gateway_tx_hold()) {
// still ack the poll, otherwise the master drops us from 0x07 and the gateway sees the device list change
txservice_.send_poll();
return;
}
#endif
if (poll_id == txservice_.get_send_id()) {
txservice_.send();
} else {
@@ -1670,6 +1722,10 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) {
#endif
Roomctrl::check(data[1], data, length); // check if there is a message for the roomcontroller
#ifdef EMSESP_GATEWAY_TX_HOLD
gateway_rx_check(data, length);
#endif
rxservice_.add(data, length); // add to RxQueue
}
}
@@ -1677,6 +1733,11 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) {
// fetch devices one by one
void EMSESP::scheduled_fetch_values() {
static uint8_t no = 0;
#ifdef EMSESP_GATEWAY_TX_HOLD
if (gateway_tx_hold()) {
return;
}
#endif
if (no || (uuid::get_uptime() - last_fetch_ > EMS_FETCH_FREQUENCY)) {
if (!no) {
last_fetch_ = uuid::get_uptime();
@@ -1698,6 +1759,72 @@ void EMSESP::scheduled_fetch_values() {
}
}
#ifdef EMSESP_GATEWAY_TX_HOLD
// count read requests from the gateway to other devices, a high rate means it's doing its startup sync
void EMSESP::gateway_rx_check(const uint8_t * data, const uint8_t length) {
if (length < 4 || (data[0] & 0x7F) != EMSdevice::EMS_DEVICE_ID_GATEWAY1 || !(data[1] & 0x80)) {
return;
}
uint8_t dest = data[1] & 0x7F;
if (dest == 0 || dest == EMSbus::ems_bus_id()) {
return;
}
uint32_t now = uuid::get_uptime();
if (now - gateway_window_start_ > GATEWAY_BURST_WINDOW) {
gateway_window_start_ = now;
gateway_window_count_ = 0;
}
if (now - gateway_fast_start_ > GATEWAY_FAST_WINDOW) {
gateway_fast_start_ = now;
gateway_fast_count_ = 0;
}
++gateway_window_count_;
++gateway_fast_count_;
if (gateway_window_count_ >= GATEWAY_BURST_THRESHOLD || gateway_fast_count_ >= GATEWAY_FAST_THRESHOLD) {
gateway_window_start_ = now;
gateway_window_count_ = 0;
gateway_fast_start_ = now;
gateway_fast_count_ = 0;
gateway_tx_hold_start();
}
}
void EMSESP::gateway_tx_hold_start() {
uint32_t now = uuid::get_uptime();
if (gateway_cooldown_until_) {
if ((int32_t)(now - gateway_cooldown_until_) < 0) {
return;
}
gateway_cooldown_until_ = 0;
}
if (!gateway_hold_until_) {
gateway_hold_start_ = now;
LOG_INFO("Gateway 0x%02X is busy, holding Tx", EMSdevice::EMS_DEVICE_ID_GATEWAY1);
}
gateway_hold_until_ = (now + GATEWAY_HOLD_TIME) | 1; // 0 means no hold
}
bool EMSESP::gateway_tx_hold() {
if (!gateway_hold_until_) {
return false;
}
uint32_t now = uuid::get_uptime();
if (now - gateway_hold_start_ > GATEWAY_HOLD_MAX) {
gateway_hold_until_ = 0;
gateway_cooldown_until_ = (now + GATEWAY_HOLD_COOLDOWN) | 1;
LOG_WARNING("Gateway 0x%02X still busy after %lu s, resuming Tx", EMSdevice::EMS_DEVICE_ID_GATEWAY1, (unsigned long)(GATEWAY_HOLD_MAX / 1000));
return false;
}
if ((int32_t)(now - gateway_hold_until_) >= 0) {
gateway_hold_until_ = 0;
LOG_INFO("Gateway 0x%02X is quiet, resuming Tx after %lu s", EMSdevice::EMS_DEVICE_ID_GATEWAY1, (unsigned long)((now - gateway_hold_start_) / 1000));
return false;
}
return true;
}
#endif
// EMSESP main class
EMSESP::EMSESP()
#ifndef EMSESP_STANDALONE
+26
View File
@@ -291,6 +291,32 @@ class EMSESP {
static constexpr uint32_t EMS_FETCH_FREQUENCY = 60000; // check every minute
static constexpr uint8_t EMS_WAIT_KM_TIMEOUT = 60; // wait one minute
#ifdef EMSESP_GATEWAY_TX_HOLD
// hold our Tx while a gateway (K30RF/KM200 on 0x48) is doing its startup sync, see issue #3094
// a startup sync is 55-250 read requests/min to other devices, normal operation is <10/min
static void gateway_rx_check(const uint8_t * data, const uint8_t length);
static bool gateway_tx_hold();
static void gateway_tx_hold_start();
static constexpr uint32_t GATEWAY_BURST_WINDOW = 30000; // ms window for counting gateway read requests
static constexpr uint8_t GATEWAY_BURST_THRESHOLD = 15; // read requests within window to treat gateway as busy
static constexpr uint32_t GATEWAY_FAST_WINDOW = 5000; // short window to catch the start of a burst quickly
static constexpr uint8_t GATEWAY_FAST_THRESHOLD = 8; // normal polling is ~1 read per 2s, a sync starts at >10/s
static constexpr uint32_t GATEWAY_HOLD_TIME = 60000; // keep holding Tx this long after the last busy window
static constexpr uint32_t GATEWAY_HOLD_MAX = 600000; // never hold longer than 10 minutes in one go
static constexpr uint32_t GATEWAY_HOLD_COOLDOWN = 600000; // after hitting the max, don't hold again for 10 minutes
static uint32_t gateway_hold_until_;
static uint32_t gateway_hold_start_;
static uint32_t gateway_cooldown_until_;
static uint32_t gateway_window_start_;
static uint8_t gateway_window_count_;
static uint32_t gateway_fast_start_;
static uint8_t gateway_fast_count_;
static uint8_t last_version_request_src_;
static uint32_t last_version_request_time_;
#endif
static constexpr uint32_t SYSTEM_STATUS_RESET_TIMEOUT = 300000; // return a non-normal system status to normal after this (in ms) - 5 minutes
struct Device_record {
+3 -2
View File
@@ -1318,8 +1318,9 @@ void Mqtt::add_ha_classes(JsonObject doc, const uint8_t device_type, const uint8
break;
case DeviceValueUOM::MV:
case DeviceValueUOM::VOLTS:
doc[sc_ha] = sc_ha_measurement;
doc[dc_ha] = "voltage";
doc[sc_ha] = sc_ha_measurement;
doc[dc_ha] = "voltage";
doc["sug_dsp_prc"] = 2; // round to 2 decimal places
break;
case DeviceValueUOM::MBAR:
doc[sc_ha] = sc_ha_measurement;
+10
View File
@@ -558,6 +558,16 @@ void TxService::add(uint8_t operation, const uint8_t * data, const uint8_t lengt
// send a Tx telegram to request data from an EMS device
void TxService::read_request(const uint16_t type_id, const uint8_t dest, const uint8_t offset, const uint8_t length, const bool front) {
#ifdef EMSESP_GATEWAY_TX_HOLD
// while Tx is held the queue isn't drained, so periodic triggers (e.g. UBADevices) would stack up identical reads
for (const auto & queued : tx_telegrams_) {
const auto & t = queued.telegram_;
if (t->operation == Telegram::Operation::TX_READ && t->dest == dest && t->type_id == type_id && t->offset == offset) {
LOG_DEBUG("Tx read request to deviceID 0x%02X for typeID 0x%02X already queued", dest, type_id);
return;
}
}
#endif
LOG_DEBUG("Tx read request to deviceID 0x%02X for typeID 0x%02X", dest, type_id);
uint8_t message_data = 0xFF;
+27 -21
View File
@@ -182,9 +182,7 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
register_telegram_type(set_typeids[i], "RC300Set", false, MAKE_PF_CB(process_RC300Set), 29);
register_telegram_type(summer_typeids[i], "RC300Summer", false, MAKE_PF_CB(process_RC300Summer), 14);
register_telegram_type(curve_typeids[i], "RC300Curves", false, MAKE_PF_CB(process_RC300Curve), 9);
if (model != EMSdevice::EMS_DEVICE_FLAG_UI800) {
register_telegram_type(summer2_typeids[i], "RC300Summer2", false, MAKE_PF_CB(process_RC300Summer2), 8);
}
register_telegram_type(summer2_typeids[i], "RC300Summer2", false, MAKE_PF_CB(process_RC300Summer2), 8);
}
const size_t set2_size = set2_typeids.size();
for (uint8_t i = 0; i < set2_size; i++) {
@@ -1183,7 +1181,12 @@ void Thermostat::process_RC300Monitor(const std::shared_ptr<const Telegram> & te
has_update(hc->hpoperatingstate, EMS_VALUE_UINT8_NOTSET);
} else {
has_enumupdate(telegram, hc->hpoperatingstate, 20, 1); // 1:heating, 2:off, 3:cooling
has_update(hc->summermode, EMS_VALUE_UINT8_NOTSET);
// UI800 heatpumps report a valid summer bit, older RC300 heatpumps don't, #3257
if (model() == EMSdevice::EMS_DEVICE_FLAG_UI800) {
has_update(hc->summermode, hc->statusbyte & 0x50 ? 1 : 0);
} else {
has_update(hc->summermode, EMS_VALUE_UINT8_NOTSET);
}
}
has_update(telegram, hc->targetflowtemp, 4);
has_update(telegram, hc->curroominfl, 27);
@@ -1257,7 +1260,7 @@ void Thermostat::process_RC300Summer(const std::shared_ptr<const Telegram> & tel
has_update(telegram, hc->roominfl_factor, 1); // is * 10
has_update(telegram, hc->offsettemp, 2);
has_update(telegram, hc->solarInfl, 3);
if (!is_received(summer2_typeids[hc->hc()])) {
if (!is_received(summer2_typeids[hc->hc()]) && !has_summer3()) {
has_update(telegram, hc->summertemp, 6);
has_update(telegram, hc->summersetmode, 7);
}
@@ -1275,6 +1278,11 @@ void Thermostat::process_RC300Summer(const std::shared_ptr<const Telegram> & tel
has_update(telegram, hc->comfortPointTemp, 12);
}
// some UI800 (e.g. HMI800.2) don't send 0x470 and use the per-hc 0x471 ff instead, #3257
bool Thermostat::has_summer3() const {
return model() == EMSdevice::EMS_DEVICE_FLAG_UI800 && is_received(0x470);
}
// type 0x470, only BC400/UI800
// (0x470), data: 01 0E 01 01 02 17 04 48
void Thermostat::process_RC300Summer3(const std::shared_ptr<const Telegram> & telegram) {
@@ -2655,7 +2663,7 @@ bool Thermostat::set_coolondelay(const char * value, const int8_t id) {
if (!Helpers::value2float(value, f)) {
return false;
}
if (model() == EMSdevice::EMS_DEVICE_FLAG_UI800) {
if (has_summer3()) {
write_command(0x470, 6, (uint8_t)(f * 4), 0x470);
return true;
}
@@ -2672,7 +2680,7 @@ bool Thermostat::set_cooloffdelay(const char * value, const int8_t id) {
if (!Helpers::value2float(value, f)) {
return false;
}
if (model() == EMSdevice::EMS_DEVICE_FLAG_UI800) {
if (has_summer3()) {
write_command(0x470, 7, (uint8_t)(f * 4), 0x470);
return true;
}
@@ -3439,7 +3447,7 @@ bool Thermostat::set_mode_n(const uint8_t mode, const int8_t id) {
// sets the thermostat summermode for RC300
bool Thermostat::set_summermode(const char * value, const int8_t id) {
uint8_t set;
if (model() == EMSdevice::EMS_DEVICE_FLAG_UI800) {
if (has_summer3()) {
if (Helpers::value2enum(value, set, FL_(enum_summermode))) {
write_command(0x470, 0, set, 0x470);
return true;
@@ -3600,7 +3608,7 @@ bool Thermostat::set_heatondelay(const char * value, const int8_t id) {
if (!Helpers::value2float(value, f)) {
return false;
}
if (model() == EMSdevice::EMS_DEVICE_FLAG_UI800) {
if (has_summer3()) {
write_command(0x470, 2, (uint8_t)(f * 4), 0x470);
return true;
}
@@ -3617,7 +3625,7 @@ bool Thermostat::set_heatoffdelay(const char * value, const int8_t id) {
if (!Helpers::value2float(value, f)) {
return false;
}
if (model() == EMSdevice::EMS_DEVICE_FLAG_UI800) {
if (has_summer3()) {
write_command(0x470, 3, (uint8_t)(f * 4), 0x470);
return true;
}
@@ -3634,7 +3642,7 @@ bool Thermostat::set_instantstart(const char * value, const int8_t id) {
if (!Helpers::value2number(value, v)) {
return false;
}
if (model() == EMSdevice::EMS_DEVICE_FLAG_UI800) {
if (has_summer3()) {
write_command(0x470, 4, (uint8_t)v, 0x470);
return true;
}
@@ -4164,7 +4172,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co
validate_typeid = set_typeids[hc->hc()];
switch (mode) {
case HeatingCircuit::Mode::SUMMER:
if (model == EMSdevice::EMS_DEVICE_FLAG_UI800) {
if (has_summer3()) {
write_command(0x470, 1, temperature, 0x470);
return true;
}
@@ -4179,7 +4187,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co
factor = 1;
break;
case HeatingCircuit::Mode::COOLSTART:
if (model == EMSdevice::EMS_DEVICE_FLAG_UI800) {
if (has_summer3()) {
write_command(0x470, 5, temperature, 0x470);
return true;
}
@@ -5207,14 +5215,12 @@ void Thermostat::register_device_values_hc(std::shared_ptr<Thermostat::HeatingCi
101);
register_device_value(tag, &hc->remotehum, DeviceValueType::CMD, FL_(remotehum), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_remotehum), -1, 101);
}
if (model != EMSdevice::EMS_DEVICE_FLAG_UI800) {
register_device_value(tag, &hc->heatondelay, DeviceValueType::UINT8, FL_(heatondelay), DeviceValueUOM::HOURS, MAKE_CF_CB(set_heatondelay), 1, 48);
register_device_value(tag, &hc->heatoffdelay, DeviceValueType::UINT8, FL_(heatoffdelay), DeviceValueUOM::HOURS, MAKE_CF_CB(set_heatoffdelay), 1, 48);
register_device_value(tag, &hc->coolondelay, DeviceValueType::UINT8, FL_(coolondelay), DeviceValueUOM::HOURS, MAKE_CF_CB(set_coolondelay), 1, 48);
register_device_value(tag, &hc->cooloffdelay, DeviceValueType::UINT8, FL_(cooloffdelay), DeviceValueUOM::HOURS, MAKE_CF_CB(set_cooloffdelay), 1, 48);
register_device_value(tag, &hc->instantstart, DeviceValueType::UINT8, FL_(instantstart), DeviceValueUOM::K, MAKE_CF_CB(set_instantstart), 1, 10);
register_device_value(tag, &hc->coolstart, DeviceValueType::UINT8, FL_(coolstart), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_coolstart), 20, 35);
}
register_device_value(tag, &hc->heatondelay, DeviceValueType::UINT8, FL_(heatondelay), DeviceValueUOM::HOURS, MAKE_CF_CB(set_heatondelay), 1, 48);
register_device_value(tag, &hc->heatoffdelay, DeviceValueType::UINT8, FL_(heatoffdelay), DeviceValueUOM::HOURS, MAKE_CF_CB(set_heatoffdelay), 1, 48);
register_device_value(tag, &hc->coolondelay, DeviceValueType::UINT8, FL_(coolondelay), DeviceValueUOM::HOURS, MAKE_CF_CB(set_coolondelay), 1, 48);
register_device_value(tag, &hc->cooloffdelay, DeviceValueType::UINT8, FL_(cooloffdelay), DeviceValueUOM::HOURS, MAKE_CF_CB(set_cooloffdelay), 1, 48);
register_device_value(tag, &hc->instantstart, DeviceValueType::UINT8, FL_(instantstart), DeviceValueUOM::K, MAKE_CF_CB(set_instantstart), 1, 10);
register_device_value(tag, &hc->coolstart, DeviceValueType::UINT8, FL_(coolstart), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_coolstart), 20, 35);
register_device_value(tag, &hc->boost, DeviceValueType::BOOL, FL_(boost), DeviceValueUOM::NONE, MAKE_CF_CB(set_boost));
register_device_value(tag, &hc->boosttime, DeviceValueType::UINT8, FL_(boosttime), DeviceValueUOM::HOURS, MAKE_CF_CB(set_boosttime));
register_device_value(tag,
+3
View File
@@ -459,9 +459,12 @@ class Thermostat : public EMSdevice {
void process_RC300Monitor(const std::shared_ptr<const Telegram> & telegram);
void process_RC300Set(const std::shared_ptr<const Telegram> & telegram);
void process_RC300Set2(const std::shared_ptr<const Telegram> & telegram);
void process_RC300Summer(const std::shared_ptr<const Telegram> & telegram);
void process_RC300Summer2(const std::shared_ptr<const Telegram> & telegram);
void process_RC300Summer3(const std::shared_ptr<const Telegram> & telegram);
bool has_summer3() const;
void process_RC300WWmode(const std::shared_ptr<const Telegram> & telegram);
void process_RC300WWmode2(const std::shared_ptr<const Telegram> & telegram);
void process_RC300WWtemp(const std::shared_ptr<const Telegram> & telegram);
+1 -1
View File
@@ -1 +1 @@
#define EMSESP_APP_VERSION "3.9.0-dev.15"
#define EMSESP_APP_VERSION "3.9.0-dev.16"
+8
View File
@@ -24,6 +24,7 @@
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "soc/uart_reg.h"
#include "uart/emsuart_esp32.h"
#include "emsesp.h"
@@ -91,6 +92,7 @@ void EMSuart::start(const uint8_t tx_mode, const uint8_t rx_gpio, const uint8_t
#endif
uart_param_config(EMSUART_NUM, &uart_config);
uart_set_pin(EMSUART_NUM, tx_gpio, rx_gpio, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
gpio_pullup_en((gpio_num_t)rx_gpio); // IDF 5 no longer enables the Rx pull-up, some custom interfaces rely on it
uart_set_line_inverse(EMSUART_NUM, inverse_mask);
uart_driver_install(EMSUART_NUM,
UART_HW_FIFO_LEN(EMSUART_NUM) + 1,
@@ -109,6 +111,7 @@ void EMSuart::start(const uint8_t tx_mode, const uint8_t rx_gpio, const uint8_t
#endif
} else {
uart_set_pin(EMSUART_NUM, tx_gpio, rx_gpio, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
gpio_pullup_en((gpio_num_t)rx_gpio);
vTaskResume(xHandle);
}
tx_mode_ = tx_mode;
@@ -153,6 +156,11 @@ uint8_t EMSuart::transmit(const uint8_t * buf, const uint8_t len) {
last_tx_src_ = len < 4 ? 0 : buf[0]; // update last tx source
#ifdef EMSESP_TX_PRE_DELAY
// the BRK event fires after one character time of low, while the master break may still be running
delayMicroseconds(EMSESP_TX_PRE_DELAY);
#endif
// TXMODE is hardware controlled mode
if (tx_mode_ == EMS_TXMODE_HW) {
uart_write_bytes_with_break(EMSUART_NUM, buf, len, 10);
+6 -5
View File
@@ -156,14 +156,15 @@ void WebLogService::loop() {
// convert time to real offset
char * WebLogService::messagetime(char * out, const uint64_t t, const size_t bufsize) {
time_t offset = time(nullptr) - uuid::get_uptime_sec();
if (offset < 1500000000L) {
int64_t offset_ms = uuid::get_wall_offset_ms();
if (offset_ms < 1500000000000LL) {
strlcpy(out, uuid::log::format_timestamp_ms(t, 3).c_str(), bufsize);
} else {
time_t t1 = offset + (time_t)(t / 1000);
char timestr[25];
int64_t wall_ms = offset_ms + (int64_t)t;
time_t t1 = (time_t)(wall_ms / 1000);
char timestr[25];
strftime(timestr, 25, "%FT%T", localtime(&t1));
snprintf(out, bufsize, "%s.%03d", timestr, (uint16_t)(t % 1000));
snprintf(out, bufsize, "%s.%03d", timestr, (int)(wall_ms % 1000));
}
return out;
}