Compare commits

...
23 Commits
Author SHA1 Message Date
Proddy af3c05247c Merge pull request #3270 from proddy/dev
A few changes for 3094, 3258, 3257
2026-10-08 18:08:26 +02:00
proddy 6fa08808dd update dev-16 2026-10-08 18:03:46 +02:00
proddy 613e3c87ae pkg update 2026-10-08 18:03:38 +02:00
proddy f8e7dd9244 Ack polls during gateway Tx hold (#3094) 2026-10-06 21:42:51 +02:00
proddy 1375f87163 add precision to voltage in HA 2026-10-04 14:29:17 +02:00
proddy 4b3f6015ee tests for gateway speeds 2026-10-04 14:28:53 +02:00
proddy ca79e2e09b skip duplicate reads 2026-10-04 14:28:25 +02:00
proddy b51d153dc5 show status in guest mode 2026-10-04 14:28:12 +02:00
proddy 79c2e5e8a1 formatting type column 2026-10-04 14:28:02 +02:00
Proddy 597939c896 Merge branch 'emsesp:dev' into dev 2026-10-04 10:18:48 +02:00
Proddy eb4232d6c8 Merge pull request #3261 from RaHehl/fix/de-heatpump-sensor-names
fix: German names of heat pump sensors TC0, TC1, TC3 and TA4
2026-10-04 10:08:31 +02:00
proddy 3ea25eba43 EMSESP_TX_PRE_DELAY 2026-10-04 09:56:34 +02:00
proddy 61eaee2ffa enable internal pull-up on the UART Rx 2026-10-04 09:22:40 +02:00
Raphael Hehl 3666f21d41 fix: German names of heat pump sensors TC0, TC1, TC3 and TA4
The English names of TC0, TC1 and TA4 are correct, the German
translations were not. Use the terms from the Bosch manuals.
2026-10-03 00:18:51 +02:00
proddy e4f9d4a96d #3257 summermode back and a test for #3094 2026-10-01 17:52:52 +02:00
proddy 635daa8ab8 chore: update generated files for v3.9.0-dev.16 2026-09-30 16:22:18 +00:00
proddy 52b24d5641 #3257 2026-09-30 18:04:34 +02:00
Proddy 619fe46a4e Merge pull request #3255 from proddy/dev
update GH actions
2026-09-27 15:31:48 +02:00
Proddy 115f5281f4 Merge branch 'emsesp:dev' into dev 2026-09-27 15:17:42 +02:00
proddy 333e2d83d7 update 2026-09-27 15:10:45 +02:00
proddy 3befcb638d update github actions 2026-09-27 14:02:09 +02:00
proddy 8a48eb75d2 formatting 2026-09-27 10:34:55 +02:00
proddy 74ff39b22e chore: update generated files for v3.9.0-dev.15 2026-09-27 08:05:03 +00:00
35 changed files with 2616 additions and 2395 deletions
+4 -3
View File
@@ -14,21 +14,22 @@ permissions:
jobs:
pre-release:
name: 'Build Dev Release'
if: github.event_name == 'workflow_dispatch' || github.repository == 'emsesp/EMS-ESP32'
runs-on: ubuntu-latest
steps:
- name: Install python 3.13
uses: actions/setup-python@v6
uses: actions/setup-python@v7
with:
python-version: '3.13'
- name: Install Node.js 26
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version: 26
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
with:
fetch-depth: 0
@@ -11,10 +11,10 @@ jobs:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: GitHub Releases To Discord
uses: SethCohen/github-releases-to-discord@v1.13.1
uses: SethCohen/github-releases-to-discord@v1.20.0
with:
webhook_url: ${{ secrets.WEBHOOK_URL }}
color: '2105893'
+2 -2
View File
@@ -15,10 +15,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Install python 3.13
uses: actions/setup-python@v6
uses: actions/setup-python@v7
with:
python-version: '3.13'
+3 -3
View File
@@ -19,15 +19,15 @@ jobs:
BUILD_WRAPPER_OUT_DIR: bw-output
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Install Build Wrapper
uses: SonarSource/sonarqube-scan-action/install-build-wrapper@master
uses: SonarSource/sonarqube-scan-action/install-build-wrapper@v8.2.2
- name: Run Build Wrapper
run: build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} make all
- name: SonarQube Scan
uses: SonarSource/sonarqube-scan-action@master
uses: SonarSource/sonarqube-scan-action@v8.2.2
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
+3 -3
View File
@@ -16,17 +16,17 @@ jobs:
steps:
- name: Install python 3.13
uses: actions/setup-python@v6
uses: actions/setup-python@v7
with:
python-version: '3.13'
- name: Install Node.js 26
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version: 26
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Install pnpm
run: npm install -g pnpm
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v10
- uses: actions/stale@v11
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 30
+3 -3
View File
@@ -18,17 +18,17 @@ jobs:
steps:
- name: Install python 3.13
uses: actions/setup-python@v6
uses: actions/setup-python@v7
with:
python-version: '3.13'
- name: Install Node.js 26
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version: 26
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Install pnpm
run: npm install -g pnpm
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Get and Send EMS-ESP version to Cloudflare
env:
+4 -2
View File
@@ -4,7 +4,7 @@ For more details go to [emsesp.org](https://emsesp.org/).
## [3.9.0]
This release is based on the latest Espressif/Arduino core version 3. It brings in many memory and performance optimizations. Note it does require the user to manually migrate settings from 3.8.x to 3.9.0.
This release is based on the latest Espressif/Arduino core version 3. It brings in many memory and performance optimizations.
## Added
@@ -37,10 +37,12 @@ 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
- 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
@@ -58,4 +60,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)
File diff suppressed because it is too large Load Diff
+914 -900
View File
File diff suppressed because it is too large Load Diff
+4 -3
View File
@@ -112,10 +112,10 @@ telegram_type_id,name,is_fetched
0x02A0,RC300Curves,
0x02A1,RC300Curves,
0x02A2,RC300Curves,
0x02A5,EasyMonitor,
0x02A5,CRFMonitor,
0x02A6,RC300Monitor,
0x02A7,RC300Monitor,
0x02A8,CRFMonitor,
0x02A8,RC300Monitor,
0x02A9,RC300Monitor,
0x02AA,RC300Monitor,
0x02AB,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
@@ -209,6 +209,7 @@ telegram_type_id,name,is_fetched
0x0585,Blowerspeed,
0x0587,Bypass,
0x05BA,HpPoolStatus,fetched
0x05C4,HpPoolShunt,
0x05D9,Airquality,
0x0772,HIUSettings,
0x0779,HIUMonitor,
1 telegram_type_id name is_fetched
112 0x02A0 RC300Curves
113 0x02A1 RC300Curves
114 0x02A2 RC300Curves
115 0x02A5 EasyMonitor CRFMonitor
116 0x02A6 RC300Monitor
117 0x02A7 RC300Monitor
118 0x02A8 CRFMonitor RC300Monitor
119 0x02A9 RC300Monitor
120 0x02AA RC300Monitor
121 0x02AB 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
209 0x0585 Blowerspeed
210 0x0587 Bypass
211 0x05BA HpPoolStatus fetched
212 0x05C4 HpPoolShunt
213 0x05D9 Airquality
214 0x0772 HIUSettings
215 0x0779 HIUMonitor
+6 -6
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",
@@ -42,11 +42,11 @@
"@eslint/js": "^10.0.1",
"@preact/preset-vite": "^2.10.6",
"@trivago/prettier-plugin-sort-imports": "^6.0.2",
"@types/node": "^26.6.3",
"@types/node": "^26.6.4",
"@types/react": "^19.3.0",
"@types/react-dom": "^19.3.0",
"concurrently": "^10.0.5",
"eslint": "^10.11.0",
"eslint": "^10.12.0",
"eslint-config-prettier": "^10.1.8",
"etag": "^1.8.1",
"mime-types": "^3.0.2",
@@ -54,9 +54,9 @@
"rollup-plugin-visualizer": "^7.1.1",
"terser": "^5.51.2",
"typescript": "^6.0.3",
"typescript-eslint": "^8.70.1",
"vite": "^8.3.1",
"typescript-eslint": "^8.71.1",
"vite": "^8.3.3",
"vite-plugin-imagemin": "^0.6.1"
},
"packageManager": "pnpm@12.6.0"
"packageManager": "pnpm@12.10.1"
}
+339 -345
View File
File diff suppressed because it is too large Load Diff
+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}
+2 -1
View File
@@ -406,7 +406,8 @@ void AnalogSensor::measure() {
sensor.sum_ = (sensor.sum_ * 15 + a * 16) / 16;
sensor.analog_ = sensor.sum_ / 16;
}
if (sensor.analog_ > 0 && sensor.analog_ < NTC_VREF_MV && (sensor.last_reading_ + 1 < sensor.analog_ || sensor.last_reading_ > sensor.analog_ + 1)) {
if (sensor.analog_ > 0 && sensor.analog_ < NTC_VREF_MV
&& (sensor.last_reading_ + 1 < sensor.analog_ || sensor.last_reading_ > sensor.analog_ + 1)) {
sensor.set_value(sensor.offset() + 1 / (1 / T25 + log((double)sensor.analog_ / (NTC_VREF_MV - sensor.analog_) * (Rt / R0)) / Beta)
- T0); // Temperature in Celsius
sensor.last_reading_ = sensor.analog_;
+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 {
+4 -4
View File
@@ -484,9 +484,9 @@ MAKE_TRANSLATION(expansionValveVr1, "expvalve", "expansion valve VR1", "Ausdehnu
MAKE_TRANSLATION(hpMaxPower, "hpmaxpower", "compressor max power", "max. Kompressorleistung", "", "Max. Kompressoreffekt", "maksymalna wydajność sprężarki", "", "", "", "", "max výkon kompresora", "maximální výkon kompresoru")
MAKE_TRANSLATION(pvMaxComp, "pvmaxcomp", "pv compressor max power", "PV max. Kompressorleistung", "", "PV Max. Kompressoreffekt", "maksymalna wydajność sprężarki", "", "", "", "", "pv max výkon kompresora", "maximální výkon PV kompresoru")
MAKE_TRANSLATION(hpPower, "hppower", "compressor power output", "Kompressorleistung", "Compressorvermogen", "Kompressoreffekt", "moc wyjściowa sprężarki", "kompressoreffekt", "puissance de sortie compresseur", "ısı pompası güç çıkışı", "potenza uscita compressore", "výkon kompresora", "výstupní výkon kompresoru")
MAKE_TRANSLATION(hpTc0, "hptc0", "heat carrier return (TC0)", "Kältemittelrücklauf (TC0)", "Koudemiddel retour (TC0)", "Värmebärare Retur (TC0)", "temperatura nośnika ciepła na powrocie (TC0)", "kjølemiddel retur (TC0)", "retour caloporteur (TC0)", "sıcak su dönüşü (TC0)", "ritorno del refrigerante (TC0)", "návrat nosiča tepla (TC0)", "návrat teplonosné látky (TC0)")
MAKE_TRANSLATION(hpTc1, "hptc1", "heat carrier forward (TC1)", "Kältemittelvorlauf (TC1)", "Koudemiddel aanvoer (TC1)", "Värmebärare Framledning (TC1)", "temperatura nośnika ciepła pierwotna (TC1)", "kjølemiddel tur (TC1)", "avance caloporteur (TC1)", "sıcak su çıkışı (TC1)", "flusso di refrigerante (TC1)", "nosič tepla vpred (TC1)", "předání teplonosné látky (TC1)")
MAKE_TRANSLATION(hpTc3, "hptc3", "condenser temperature (TC3)", "Kondensatortemperatur (TC3)", "Condensortemperatuur (TC3)", "Kondensortemperatur (TC3)", "temperatura skraplacza/na wyjściu sprężarki (TC3)", "kondensortemperatur (TC3)", "température condensateur (TC3)", "kondenser sıcaklığı (TC3)", "temperatura condensatore (TC3)", "teplota kondenzátora (TC3)", "teplota kondenzátoru (TC3)")
MAKE_TRANSLATION(hpTc0, "hptc0", "heat carrier return (TC0)", "Wärmeträgerrücklauf (TC0)", "Koudemiddel retour (TC0)", "Värmebärare Retur (TC0)", "temperatura nośnika ciepła na powrocie (TC0)", "kjølemiddel retur (TC0)", "retour caloporteur (TC0)", "sıcak su dönüşü (TC0)", "ritorno del refrigerante (TC0)", "návrat nosiča tepla (TC0)", "návrat teplonosné látky (TC0)")
MAKE_TRANSLATION(hpTc1, "hptc1", "heat carrier forward (TC1)", "Wärmeträgervorlauf (TC1)", "Koudemiddel aanvoer (TC1)", "Värmebärare Framledning (TC1)", "temperatura nośnika ciepła pierwotna (TC1)", "kjølemiddel tur (TC1)", "avance caloporteur (TC1)", "sıcak su çıkışı (TC1)", "flusso di refrigerante (TC1)", "nosič tepla vpred (TC1)", "předání teplonosné látky (TC1)")
MAKE_TRANSLATION(hpTc3, "hptc3", "condenser temperature (TC3)", "Wärmeträgerausgang (TC3)", "Condensortemperatuur (TC3)", "Kondensortemperatur (TC3)", "temperatura skraplacza/na wyjściu sprężarki (TC3)", "kondensortemperatur (TC3)", "température condensateur (TC3)", "kondenser sıcaklığı (TC3)", "temperatura condensatore (TC3)", "teplota kondenzátora (TC3)", "teplota kondenzátoru (TC3)")
MAKE_TRANSLATION(hpTr1, "hptr1", "compressor temperature (TR1)", "Kompressortemperatur (TR1)", "Compressor temperatuur (TR1)", "Kompressor temp (TR1)", "temperatura sprężarki (TR1)", "kompressor temperatur (TR1)", "température compresseur (TR1)", "ısı pompası sıcaklığı (TR1)", "temperatura compressore (TR1)", "teplota kompresora (TR1)", "teplota kompresoru (TR1)")
MAKE_TRANSLATION(hpTr3, "hptr3", "refrigerant temperature liquid side (condenser output) (TR3)", "Kältemittel (flüssig) (TR3)", "Temperatuur koudemiddel vloeibare zijde (TR3)", "Köldmedium temperatur (kondensorutlopp) (TR3)", "temperatura skraplacza ogrzew. (TR3)", "kjølemiddeltemperatur på væskesiden (TR3)", "température réfrigérant côté liquide (sortie condensateur) (TR3)", "ısı pompası çıkışı (TR3)", "temperatura refrigerante lato liquido (uscita condensatore) (TR3)", "teplota chladiva na strane kvapaliny (výstup kondenzátora) (TR3)", "teplota chladiva na kapalné straně (výstup kondenzátoru) (TR3)")
MAKE_TRANSLATION(hpTr4, "hptr4", "evaporator inlet temperature (TR4)", "Verdampfereingang (TR4)", "Verdamper ingangstemperatuur (TR4)", "Förångare inloppstemp (TR4)", "temperatura na wejściu parownika (TR4)", "innløpstemperatur for fordamperen (TR4)", "température entrée évaporateur (TR4)", "evaporatör giriş sıcaklığı (TR4)", "temperatura di ingresso dell'evaporatore (TR4)", "Vstupná teplota výparníka (TR4)", "teplota vstupu do evaporátoru (TR4)")
@@ -496,7 +496,7 @@ MAKE_TRANSLATION(hpTr7, "hptr7", "refrigerant temperature gas side (condenser in
MAKE_TRANSLATION(hpTl2, "hptl2", "air inlet temperature (TL2)", "Außenlufteintrittstemperatur (TL2)", "Temperatuur luchtinlaat (TL2)", "Luftintagstemperatur (TL2)", "temperatura wlotu powietrza (TL2)", "luftinntakstemperatur (TL2)", "température entrée air (TL2)", "hava giriş sıcaklığı (TL2)", "temperatura ingresso aria (TL2)", "teplota prívodu vzduchu (TL2)", "teplota vzduchu na vstupu (TL2)")
MAKE_TRANSLATION(hpPl1, "hppl1", "low pressure side temperature (PL1)", "Niederdrucktemperatur (PL1)", "Temperatuur lage drukzijde (PL1)", "Temperatur Lågtryckssidan (PL1)", "temperatura po stronie niskiego ciśnienia (PL1)", "temperatur lavtrykksiden (PL1)", "température côté basse pression (PL1)", "düşük basınç tarafı sıcaklığı (PL1)", "temperatura lato bassa pressione (PL1)", "teplota na strane nízkeho tlaku (PL1)", "teplota na nízkotlaké straně (PL1)")
MAKE_TRANSLATION(hpPh1, "hpph1", "high pressure side temperature (PH1)", "Hochdrucktemperatur (PH1)", "Temperatuur hoge drukzijde (PH1)", "Temperatur Högtryckssidan (PH1)", "temperatura po stronie wysokiego ciśnienia (PH1)", "Temperatur Høytrykksiden (PH1)", "température côté bhauteasse pression (PH1)", "yüksek basınç tarafı sıcaklığı (PH1)", "temperatura lato alta pressione (PH1)", "teplota na strane vysokého tlaku (PH1)", "teplota na vysokotlaké straně (PH1)")
MAKE_TRANSLATION(hpTa4, "hpta4", "drain pan temp (TA4)", "Kondensatorwanne (TA4)", "Temperatuur condensorafvoerbak (TA4)", " (TA4)", "temperatura ociekacza (TA4)", "kondenstråg temperatur (TA4)", " (TA4)", "tahliye sıcaklığı (TA4)", "temperatura condensatore (TA4)", "teplota vypúšťacej misky (TA4)", "teplota odvodňovací vany (TA4)")
MAKE_TRANSLATION(hpTa4, "hpta4", "drain pan temp (TA4)", "Auffangwanne (TA4)", "Temperatuur condensorafvoerbak (TA4)", " (TA4)", "temperatura ociekacza (TA4)", "kondenstråg temperatur (TA4)", " (TA4)", "tahliye sıcaklığı (TA4)", "temperatura condensatore (TA4)", "teplota vypúšťacej misky (TA4)", "teplota odvodňovací vany (TA4)")
MAKE_TRANSLATION(hpTw1, "hptw1", "reservoir temp (TW1)", "DHW Reservoir (TW1)", "(TW1)", "Varmvattentank Temperatur (TW1)", "temperatura zbiornika (TW1)", "(TW1)", "(TW1)", "(TW1)", "(TW1)", "teplota zásobníka (TW1)", "teplota v nádrži (TW1)")
MAKE_TRANSLATION(hpInput1, "hpin1", "input 1 state", "Status Eingang 1", "Status input 1", "Status Ingång 1", "stan wejścia 1", "status inggang 1", "état entrée 1", "giriş 1 durumu", "stato ingresso 1", "stav vstupu 1", "stav vstupu 1")
MAKE_TRANSLATION(hpInput2, "hpin2", "input 2 state", "Status Eingang 2", "Status input 2", "Status Ingång 2", "stan wejścia 2", "status inggang 2", "état entrée 2", "giriş 2 durumu", "stato ingresso 2", "stav vstupu 2", "stav vstupu 2")
+104 -102
View File
@@ -101,108 +101,110 @@ const std::initializer_list<Modbus::EntityModbusInfo> Modbus::modbus_register_ma
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpSetDiffPress), 151, 1), // hpsetdiffpress
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpCompOn), 152, 1), // hpcompon
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpActivity), 153, 1), // hpactivity
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpBrinePumpSpd), 154, 1), // hpbrinepumpspd
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpSwitchValve), 155, 1), // hpswitchvalve
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpCompSpd), 156, 1), // hpcompspd
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTargetSpd), 157, 1), // hptargetspd
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpCircSpd), 158, 1), // hpcircspd
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(receiverValveVr0), 159, 1), // recvalve
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(expansionValveVr1), 160, 1), // expvalve
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpBrineIn), 161, 1), // hpbrinein
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpBrineOut), 162, 1), // hpbrineout
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTc0), 163, 1), // hptc0
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTc1), 164, 1), // hptc1
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTc3), 165, 1), // hptc3
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTr1), 166, 1), // hptr1
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTr3), 167, 1), // hptr3
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTr4), 168, 1), // hptr4
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTr5), 169, 1), // hptr5
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTr6), 170, 1), // hptr6
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTr7), 171, 1), // hptr7
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTl2), 172, 1), // hptl2
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPl1), 173, 1), // hppl1
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPh1), 174, 1), // hpph1
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTa4), 175, 1), // hpta4
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTw1), 176, 1), // hptw1
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(poolSetTemp), 177, 1), // poolsettemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hp4wayValve), 178, 1), // hp4way
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpInput1), 179, 1), // hpin1
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpIn1Opt), 180, 8), // hpin1opt
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpInput2), 188, 1), // hpin2
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpIn2Opt), 189, 8), // hpin2opt
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpInput3), 197, 1), // hpin3
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpIn3Opt), 198, 8), // hpin3opt
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpInput4), 206, 1), // hpin4
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpIn4Opt), 207, 8), // hpin4opt
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(maxHeatComp), 215, 1), // maxheatcomp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(maxHeatHeat), 216, 1), // maxheatheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterSource), 217, 1), // auxheatersource
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pvCooling), 218, 1), // pvcooling
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterOnly), 219, 1), // auxheateronly
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterOff), 220, 1), // auxheateroff
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterStatus), 221, 1), // auxheaterstatus
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterLevel), 222, 1), // auxheaterlevel
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterDelay), 223, 1), // auxheaterdelay
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxMaxLimit), 224, 1), // auxmaxlimit
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxLimitStart), 225, 1), // auxlimitstart
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeatMode), 226, 1), // auxheatrmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpHystHeat), 227, 1), // hphystheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpHystCool), 228, 1), // hphystcool
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpHystPool), 229, 1), // hphystpool
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(silentMode), 230, 1), // silentmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(silentFrom), 231, 1), // silentfrom
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(silentTo), 232, 1), // silentto
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(minTempSilent), 233, 1), // mintempsilent
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(tempParMode), 234, 1), // tempparmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeatMixValve), 235, 1), // auxheatmix
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(tempDiffHeat), 236, 1), // tempdiffheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(tempDiffCool), 237, 1), // tempdiffcool
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(vp_cooling), 238, 1), // vpcooling
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatCable), 239, 1), // heatcable
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(VC0valve), 240, 1), // vc0valve
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(primePump), 241, 1), // primepump
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(primePumpMod), 242, 1), // primepumpmod
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hp3wayValve), 243, 1), // hp3way
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(elHeatStep1), 244, 1), // elheatstep1
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(elHeatStep2), 245, 1), // elheatstep2
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(elHeatStep3), 246, 1), // elheatstep3
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpEA0), 247, 1), // hpea0
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPumpMode), 248, 1), // hppumpmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpFan), 249, 1), // fan
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(fanSpd), 250, 1), // fanspd
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpShutdown), 251, 1), // shutdown
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpCurrPower), 252, 1), // hpcurrpower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPowerLimit), 253, 1), // hppowerlimit
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(exhaustTemp), 254, 1), // exhausttemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnGas), 255, 1), // burngas
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnGas2), 256, 1), // burngas2
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(flameCurr), 257, 1), // flamecurr
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(fanWork), 258, 1), // fanwork
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(ignWork), 259, 1), // ignwork
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(oilPreHeat), 260, 1), // oilpreheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMinPower), 261, 1), // burnminpower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMaxPower), 262, 1), // burnmaxpower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMinPeriod), 263, 1), // burnminperiod
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(absBurnPow), 264, 1), // absburnpow
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatblock), 265, 1), // heatblock
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boilHystOn), 266, 1), // boilhyston
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boilHystOff), 267, 1), // boilhystoff
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boil2HystOn), 268, 1), // boil2hyston
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boil2HystOff), 269, 1), // boil2hystoff
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveOn), 270, 1), // curveon
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveBase), 271, 1), // curvebase
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveEnd), 272, 1), // curveend
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(summertemp), 273, 1), // summertemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nofrostmode), 274, 1), // nofrostmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nofrosttemp), 275, 1), // nofrosttemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(gasMeterHeat), 276, 2), // gasmeterheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nrgHeat2), 278, 2), // nrgheat2
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nomPower), 280, 1), // nompower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(netFlowTemp), 281, 1), // netflowtemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatValve), 282, 1), // heatvalve
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(keepWarmTemp), 283, 1), // keepwarmtemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(setReturnTemp), 284, 1), // setreturntemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatingOn), 285, 1), // heating
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPoolOn), 154, 1), // hppoolon
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpBrinePumpSpd), 155, 1), // hpbrinepumpspd
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpSwitchValve), 156, 1), // hpswitchvalve
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpCompSpd), 157, 1), // hpcompspd
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTargetSpd), 158, 1), // hptargetspd
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpCircSpd), 159, 1), // hpcircspd
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(receiverValveVr0), 160, 1), // recvalve
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(expansionValveVr1), 161, 1), // expvalve
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpBrineIn), 162, 1), // hpbrinein
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpBrineOut), 163, 1), // hpbrineout
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTc0), 164, 1), // hptc0
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTc1), 165, 1), // hptc1
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTc3), 166, 1), // hptc3
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTr1), 167, 1), // hptr1
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTr3), 168, 1), // hptr3
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTr4), 169, 1), // hptr4
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTr5), 170, 1), // hptr5
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTr6), 171, 1), // hptr6
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTr7), 172, 1), // hptr7
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTl2), 173, 1), // hptl2
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPl1), 174, 1), // hppl1
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPh1), 175, 1), // hpph1
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTa4), 176, 1), // hpta4
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpTw1), 177, 1), // hptw1
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(poolOn), 178, 1), // poolon
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(poolSetTemp), 179, 1), // poolsettemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hp4wayValve), 180, 1), // hp4way
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpInput1), 181, 1), // hpin1
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpIn1Opt), 182, 8), // hpin1opt
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpInput2), 190, 1), // hpin2
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpIn2Opt), 191, 8), // hpin2opt
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpInput3), 199, 1), // hpin3
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpIn3Opt), 200, 8), // hpin3opt
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpInput4), 208, 1), // hpin4
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpIn4Opt), 209, 8), // hpin4opt
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(maxHeatComp), 217, 1), // maxheatcomp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(maxHeatHeat), 218, 1), // maxheatheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterSource), 219, 1), // auxheatersource
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(pvCooling), 220, 1), // pvcooling
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterOnly), 221, 1), // auxheateronly
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterOff), 222, 1), // auxheateroff
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterStatus), 223, 1), // auxheaterstatus
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterLevel), 224, 1), // auxheaterlevel
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeaterDelay), 225, 1), // auxheaterdelay
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxMaxLimit), 226, 1), // auxmaxlimit
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxLimitStart), 227, 1), // auxlimitstart
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeatMode), 228, 1), // auxheatrmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpHystHeat), 229, 1), // hphystheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpHystCool), 230, 1), // hphystcool
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpHystPool), 231, 1), // hphystpool
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(silentMode), 232, 1), // silentmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(silentFrom), 233, 1), // silentfrom
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(silentTo), 234, 1), // silentto
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(minTempSilent), 235, 1), // mintempsilent
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(tempParMode), 236, 1), // tempparmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(auxHeatMixValve), 237, 1), // auxheatmix
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(tempDiffHeat), 238, 1), // tempdiffheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(tempDiffCool), 239, 1), // tempdiffcool
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(vp_cooling), 240, 1), // vpcooling
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatCable), 241, 1), // heatcable
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(VC0valve), 242, 1), // vc0valve
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(primePump), 243, 1), // primepump
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(primePumpMod), 244, 1), // primepumpmod
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hp3wayValve), 245, 1), // hp3way
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(elHeatStep1), 246, 1), // elheatstep1
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(elHeatStep2), 247, 1), // elheatstep2
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(elHeatStep3), 248, 1), // elheatstep3
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpEA0), 249, 1), // hpea0
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPumpMode), 250, 1), // hppumpmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpFan), 251, 1), // fan
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(fanSpd), 252, 1), // fanspd
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpShutdown), 253, 1), // shutdown
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpCurrPower), 254, 1), // hpcurrpower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPowerLimit), 255, 1), // hppowerlimit
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(exhaustTemp), 256, 1), // exhausttemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnGas), 257, 1), // burngas
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnGas2), 258, 1), // burngas2
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(flameCurr), 259, 1), // flamecurr
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(fanWork), 260, 1), // fanwork
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(ignWork), 261, 1), // ignwork
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(oilPreHeat), 262, 1), // oilpreheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMinPower), 263, 1), // burnminpower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMaxPower), 264, 1), // burnmaxpower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMinPeriod), 265, 1), // burnminperiod
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(absBurnPow), 266, 1), // absburnpow
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatblock), 267, 1), // heatblock
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boilHystOn), 268, 1), // boilhyston
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boilHystOff), 269, 1), // boilhystoff
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boil2HystOn), 270, 1), // boil2hyston
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boil2HystOff), 271, 1), // boil2hystoff
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveOn), 272, 1), // curveon
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveBase), 273, 1), // curvebase
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveEnd), 274, 1), // curveend
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(summertemp), 275, 1), // summertemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nofrostmode), 276, 1), // nofrostmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nofrosttemp), 277, 1), // nofrosttemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(gasMeterHeat), 278, 2), // gasmeterheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nrgHeat2), 280, 2), // nrgheat2
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nomPower), 282, 1), // nompower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(netFlowTemp), 283, 1), // netflowtemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatValve), 284, 1), // heatvalve
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(keepWarmTemp), 285, 1), // keepwarmtemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(setReturnTemp), 286, 1), // setreturntemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatingOn), 287, 1), // heating
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(nrgWw), 0, 2), // nrg
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(meterWw), 2, 2), // meter
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DHW, FL_(upTimeCompWw), 4, 2), // uptimecomp
+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
@@ -181,9 +181,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++) {
@@ -1182,7 +1180,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);
@@ -1256,7 +1259,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);
}
@@ -1274,6 +1277,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) {
@@ -2654,7 +2662,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;
}
@@ -2671,7 +2679,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;
}
@@ -3438,7 +3446,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;
@@ -3599,7 +3607,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;
}
@@ -3616,7 +3624,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;
}
@@ -3633,7 +3641,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;
}
@@ -4163,7 +4171,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;
}
@@ -4178,7 +4186,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;
}
@@ -5206,14 +5214,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"
+2 -1
View File
@@ -967,7 +967,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
uart_telegram({0x10, 0x08, 0xFF, 0x00, 0x03, 0x8A, 0x01});
uart_telegram({0x08, 0x00, 0xFF, 0x00, 0x03, 0x8A, 0x01, 0x50, 0x01, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x1E, 0x00, 0x00, 0x01, 0x00, 0x04});
// HPValve, byte 0 bit 6 = pool heating active
uart_telegram({0x08, 0x00, 0xFF, 0x00, 0x03, 0x88, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00});
uart_telegram({0x08, 0x00, 0xFF, 0x00, 0x03, 0x88, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x00, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00});
// heatpump -> MP100 shunt setpoint 0%
uart_telegram({0x08, 0x11, 0xFF, 0x00, 0x04, 0xC4, 0x00});
// MP100 -> heatpump: 32.5 C, shunt 45%, pool request active
+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;
}