mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2026-10-28 11:14:58 +00:00
Compare commits
23
Commits
960a7a554e
...
af3c05247c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af3c05247c | ||
|
|
6fa08808dd | ||
|
|
613e3c87ae | ||
|
|
f8e7dd9244 | ||
|
|
1375f87163 | ||
|
|
4b3f6015ee | ||
|
|
ca79e2e09b | ||
|
|
b51d153dc5 | ||
|
|
79c2e5e8a1 | ||
|
|
597939c896 | ||
|
|
eb4232d6c8 | ||
|
|
3ea25eba43 | ||
|
|
61eaee2ffa | ||
|
|
3666f21d41 | ||
|
|
e4f9d4a96d | ||
|
|
635daa8ab8 | ||
|
|
52b24d5641 | ||
|
|
619fe46a4e | ||
|
|
115f5281f4 | ||
|
|
333e2d83d7 | ||
|
|
3befcb638d | ||
|
|
8a48eb75d2 | ||
|
|
74ff39b22e |
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
+920
-900
File diff suppressed because it is too large
Load Diff
+914
-900
File diff suppressed because it is too large
Load Diff
@@ -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,
|
||||
|
||||
|
@@ -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"
|
||||
}
|
||||
|
||||
Generated
+339
-345
File diff suppressed because it is too large
Load Diff
@@ -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 {
|
||||
|
||||
@@ -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))}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
Generated
+65
-65
@@ -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
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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 @@
|
||||
#define EMSESP_APP_VERSION "3.9.0-dev.15"
|
||||
#define EMSESP_APP_VERSION "3.9.0-dev.16"
|
||||
|
||||
+2
-1
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user