Merge branch 'dev' into dev

This commit is contained in:
Proddy
2025-11-03 18:02:43 +01:00
committed by GitHub
20 changed files with 1499 additions and 1444 deletions

View File

@@ -0,0 +1,27 @@
{
"name": "EMS-ESP Devcontainer",
"image": "mcr.microsoft.com/devcontainers/typescript-node:1-22-bookworm",
"features": {
"ghcr.io/devcontainers/features/node:1": {},
"ghcr.io/devcontainers-extra/features/pnpm:2": {},
"ghcr.io/devcontainers/features/python:1": {},
"ghcr.io/shyim/devcontainers-features/bun:0": {}
},
"forwardPorts": [
3000,
3080
],
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "cd mock-api && pnpm install && cd .. && cd interface && pnpm install",
// Configure tool-specific properties.
"customizations": {
"vscode": {
"extensions": [
"platformio.platformio-ide"
]
}
}
}

View File

@@ -48,6 +48,7 @@ For more details go to [docs.emsesp.org](https://docs.emsesp.org/).
- fix wwMaxPower on Junkers ZBS14 [#2609](https://github.com/emsesp/EMS-ESP32/issues/2609)
- ventilation bypass state from telegram 0x55C [#1197](https://github.com/emsesp/EMS-ESP32/issues/1197)
- set selflowtemp for ems+ boilers [#2641](https://github.com/emsesp/EMS-ESP32/discussions/2641)
- syslog timestamp [#2704](https://github.com/emsesp/EMS-ESP32/issues/2704)
## Changed

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -19,7 +19,8 @@
"typesafe-i18n": "typesafe-i18n --no-watch",
"webUI": "vite build && node progmem-generator.js",
"format": "prettier -l -w '**/*.{ts,tsx,js,css,json,md}'",
"lint": "eslint . --fix"
"lint": "eslint . --fix",
"standalone-devcontainer": "concurrently -c \"auto\" \"typesafe-i18n\" \"pnpm:mock-rest\" \"vite --host\""
},
"dependencies": {
"@alova/adapter-xhr": "2.2.1",
@@ -48,6 +49,7 @@
"devDependencies": {
"@babel/core": "^7.28.5",
"@eslint/js": "^9.39.0",
"@preact/compat": "^18.3.1",
"@preact/preset-vite": "^2.10.2",
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
"@types/node": "^24.10.0",
@@ -64,5 +66,5 @@
"vite-plugin-imagemin": "^0.6.1",
"vite-tsconfig-paths": "^5.1.4"
},
"packageManager": "pnpm@10.20.0+sha512.cf9998222162dd85864d0a8102e7892e7ba4ceadebbf5a31f9c2fce48dfce317a9c53b9f6464d1ef9042cba2e02ae02a9f7c143a2b438cd93c91840f0192b9dd"
"packageManager": "pnpm@10.20.0"
}

View File

@@ -81,6 +81,9 @@ importers:
'@eslint/js':
specifier: ^9.39.0
version: 9.39.0
'@preact/compat':
specifier: ^18.3.1
version: 18.3.1(preact@10.27.2)
'@preact/preset-vite':
specifier: ^2.10.2
version: 2.10.2(@babel/core@7.28.5)(preact@10.27.2)(vite@7.1.12(@types/node@24.10.0)(terser@5.44.0))

View File

@@ -17,6 +17,7 @@
*/
#include "uuid/syslog.h"
#include "../../src/core/emsesp.h"
#ifndef UUID_SYSLOG_HAVE_GETTIMEOFDAY
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
@@ -230,8 +231,7 @@ SyslogService::QueuedLogMessage::QueuedLogMessage(unsigned long id, std::shared_
: id_(id)
, content_(std::move(content)) {
// Added for EMS-ESP
// if (time_good_ || emsesp::EMSESP::system_.network_connected()) {
if (time_good_) {
if (time_good_ || emsesp::EMSESP::system_.network_connected()) {
#if UUID_SYSLOG_HAVE_GETTIMEOFDAY
if (gettimeofday(&time_, nullptr) != 0) {
time_.tv_sec = (time_t)-1;
@@ -523,7 +523,7 @@ bool SyslogService::transmit(const QueuedLogMessage & message) {
// (unsigned long)message.time_.tv_usec);
// added for EMS-ESP
udp_.printf("%04u-%02u-%02uT%02u:%02u:%02u.%06lu%+02d:%02d",
udp_.printf("%04u-%02u-%02uT%02u:%02u:%02u.%06lu%+03d:%02d",
tm.tm_year + 1900,
tm.tm_mon + 1,
tm.tm_mday,
@@ -537,7 +537,7 @@ bool SyslogService::transmit(const QueuedLogMessage & message) {
udp_.print('-');
}
udp_.printf(" %s %s - - - ", hostname_.c_str(), message.content_->name);
udp_.printf(" %s %s - - - ", hostname_.c_str(), message.content_->name ? message.content_->name : "emsesp");
char id_c_str[15];
snprintf(id_c_str, sizeof(id_c_str), " %lu: ", message.id_);

View File

@@ -40,7 +40,7 @@ build_flags =
-D CONFIG_ASYNC_TCP_PRIORITY=10 ; default
-D CONFIG_ASYNC_TCP_QUEUE_SIZE=64 ; default
-D CONFIG_ASYNC_TCP_RUNNING_CORE=1 ; force async_tcp task to be on same core as Arduino app (default is any core)
-D CONFIG_ASYNC_TCP_STACK_SIZE=8192 ; stack usage measured: ESP32: ~2.3K, ESP32S3: ~3.5k - (was 6KB/6144, default is 16KB/8192*2)
-D CONFIG_ASYNC_TCP_STACK_SIZE=6144 ; default is 16KB/8192*2
; ESPAsyncWebServer
; -D WS_MAX_QUEUED_MESSAGES=0 ; not used, default 8
; -D SSE_MAX_QUEUED_MESSAGES=1 ; for log messages, default 32

View File

@@ -990,11 +990,11 @@ void EMSdevice::generate_values_web(JsonObject output, const bool is_dashboard)
} else if ((dv.type == DeviceValueType::UINT16) && Helpers::hasValue(*(uint16_t *)(dv.value_p))) {
obj["v"] = Helpers::transformNumFloat(*(uint16_t *)(dv.value_p), dv.numeric_operator, fahrenheit);
} else if ((dv.type == DeviceValueType::UINT24) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) {
obj["v"] = dv.numeric_operator > 0 ? *(uint32_t *)(dv.value_p) / dv.numeric_operator : *(uint32_t *)(dv.value_p);
obj["v"] = dv.numeric_operator > 0 ? Helpers::transformNumFloat(*(uint32_t *)(dv.value_p), dv.numeric_operator) : *(uint32_t *)(dv.value_p);
} else if ((dv.type == DeviceValueType::TIME) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) {
obj["v"] = dv.numeric_operator > 0 ? *(uint32_t *)(dv.value_p) / dv.numeric_operator : *(uint32_t *)(dv.value_p);
} else if ((dv.type == DeviceValueType::UINT32) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) {
obj["v"] = dv.numeric_operator > 0 ? *(uint32_t *)(dv.value_p) / dv.numeric_operator : *(uint32_t *)(dv.value_p);
obj["v"] = dv.numeric_operator > 0 ? Helpers::transformNumFloat(*(uint32_t *)(dv.value_p), dv.numeric_operator) : *(uint32_t *)(dv.value_p);
} else {
obj["v"] = ""; // must have a value for sorting to work
}
@@ -1100,7 +1100,7 @@ void EMSdevice::generate_values_web_customization(JsonArray output) {
} else if (dv.type == DeviceValueType::UINT16) {
obj["v"] = Helpers::transformNumFloat(*(uint16_t *)(dv.value_p), dv.numeric_operator, fahrenheit);
} else if (dv.type == DeviceValueType::UINT24 || dv.type == DeviceValueType::UINT32) {
obj["v"] = dv.numeric_operator > 0 ? *(uint32_t *)(dv.value_p) / dv.numeric_operator : *(uint32_t *)(dv.value_p);
obj["v"] = dv.numeric_operator > 0 ? Helpers::transformNumFloat(*(uint32_t *)(dv.value_p), dv.numeric_operator) : *(uint32_t *)(dv.value_p);
} else if (dv.type == DeviceValueType::TIME) {
obj["v"] = dv.numeric_operator > 0 ? *(uint32_t *)(dv.value_p) / dv.numeric_operator : *(uint32_t *)(dv.value_p);
}

View File

@@ -38,7 +38,7 @@
#endif
#ifndef EMSESP_STANDALONE
#include "ESP32React/ESP32React.h"
#include "../ESP32React/ESP32React.h"
#else
#include "../lib_standalone/ESP32React.h"
#endif

View File

@@ -547,6 +547,7 @@ MAKE_TRANSLATION(heatondelay, "heatondelay", "heat-on delay", "Einschaltverzöge
MAKE_TRANSLATION(heatoffdelay, "heatoffdelay", "heat-off delay", "Ausschaltverzögerung Heizen", "", "Frånkopplingsfördröjning värme", "opóźnienie włączania ogrzewania", "", "", "", "", "Oneskorenie vypnutia kúrenia", "zpoždění vypnutí topení") // TODO translate
MAKE_TRANSLATION(hpSetDiffPress, "hpsetdiffpress", "set differential pressure", "Pumpensolldruck", "", "VP Tryckskillnad", "różnica ciśnień", "", "", "", "", "nastaviť diferenčný tlak", "nastavení rozdílového tlaku") // TODO translate
MAKE_TRANSLATION(hpFan, "fan", "fan", "Lüfter", "", "Fläkt", "wentylator", "", "", "", "", "ventilátor", "ventilátor") // TODO translate
MAKE_TRANSLATION(fanSpd, "fanspd", "fan speed", "Lüfter Geschw.", "", "Fläkt", "wentylator", "", "", "", "", "ventilátor", "ventilátor") // TODO translate
MAKE_TRANSLATION(hpShutdown, "shutdown", "shutdown", "Abschalten", "", "Stäng av", "wyłączenie", "", "", "", "", "vypnutie", "vypnutí") // TODO translate
MAKE_TRANSLATION(pc0Flow, "pc0flow", "Flow PC0", "Durchfluss PC0", "", "Flöde värmebärarpump", "", "", "", "", "", "prietok PC0", "průtok PC0") // TODO translate
MAKE_TRANSLATION(pc1Flow, "pc1flow", "Flow PC1", "Durchfluss PC1", "", "Flöde cirkulationspump", "", "", "", "", "", "prietok PC1", "průtok PC1") // TODO translate

View File

@@ -163,39 +163,40 @@ const std::initializer_list<Modbus::EntityModbusInfo> Modbus::modbus_register_ma
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpEA0), 241, 1), // hpea0
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPumpMode), 242, 1), // hppumpmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpFan), 243, 1), // fan
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpShutdown), 244, 1), // shutdown
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpCurrPower), 245, 1), // hpcurrpower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPowerLimit), 246, 1), // hppowerlimit
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(exhaustTemp), 247, 1), // exhausttemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnGas), 248, 1), // burngas
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnGas2), 249, 1), // burngas2
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(flameCurr), 250, 1), // flamecurr
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(fanWork), 251, 1), // fanwork
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(ignWork), 252, 1), // ignwork
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(oilPreHeat), 253, 1), // oilpreheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMinPower), 254, 1), // burnminpower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMaxPower), 255, 1), // burnmaxpower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMinPeriod), 256, 1), // burnminperiod
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(absBurnPow), 257, 1), // absburnpow
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatblock), 258, 1), // heatblock
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boilHystOn), 259, 1), // boilhyston
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boilHystOff), 260, 1), // boilhystoff
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boil2HystOn), 261, 1), // boil2hyston
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boil2HystOff), 262, 1), // boil2hystoff
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveOn), 263, 1), // curveon
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveBase), 264, 1), // curvebase
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveEnd), 265, 1), // curveend
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(summertemp), 266, 1), // summertemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nofrostmode), 267, 1), // nofrostmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nofrosttemp), 268, 1), // nofrosttemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(gasMeterHeat), 269, 2), // gasmeterheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nrgHeat2), 271, 2), // nrgheat2
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nomPower), 273, 1), // nompower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(netFlowTemp), 274, 1), // netflowtemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatValve), 275, 1), // heatvalve
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(keepWarmTemp), 276, 1), // keepwarmtemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(setReturnTemp), 277, 1), // setreturntemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatingOn), 278, 1), // heating
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(fanSpd), 244, 1), // fanspd
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpShutdown), 245, 1), // shutdown
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpCurrPower), 246, 1), // hpcurrpower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(hpPowerLimit), 247, 1), // hppowerlimit
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(exhaustTemp), 248, 1), // exhausttemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnGas), 249, 1), // burngas
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnGas2), 250, 1), // burngas2
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(flameCurr), 251, 1), // flamecurr
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(fanWork), 252, 1), // fanwork
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(ignWork), 253, 1), // ignwork
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(oilPreHeat), 254, 1), // oilpreheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMinPower), 255, 1), // burnminpower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMaxPower), 256, 1), // burnmaxpower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(burnMinPeriod), 257, 1), // burnminperiod
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(absBurnPow), 258, 1), // absburnpow
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatblock), 259, 1), // heatblock
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boilHystOn), 260, 1), // boilhyston
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boilHystOff), 261, 1), // boilhystoff
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boil2HystOn), 262, 1), // boil2hyston
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(boil2HystOff), 263, 1), // boil2hystoff
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveOn), 264, 1), // curveon
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveBase), 265, 1), // curvebase
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(curveEnd), 266, 1), // curveend
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(summertemp), 267, 1), // summertemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nofrostmode), 268, 1), // nofrostmode
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nofrosttemp), 269, 1), // nofrosttemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(gasMeterHeat), 270, 2), // gasmeterheat
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nrgHeat2), 272, 2), // nrgheat2
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(nomPower), 274, 1), // nompower
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(netFlowTemp), 275, 1), // netflowtemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatValve), 276, 1), // heatvalve
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(keepWarmTemp), 277, 1), // keepwarmtemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(setReturnTemp), 278, 1), // setreturntemp
REGISTER_MAPPING(dt::BOILER, TAG_TYPE_DEVICE_DATA, FL_(heatingOn), 279, 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

View File

@@ -212,16 +212,20 @@ bool System::command_message(const char * value, const int8_t id, JsonObject out
return false; // must have a string value
}
auto computed_value = compute(value); // process the message via Shunting Yard
EMSESP::webSchedulerService.computed_value.clear();
EMSESP::webSchedulerService.raw_value = value;
for (uint8_t wait = 0; wait < 2000 && !EMSESP::webSchedulerService.raw_value.empty(); wait++) {
delay(1);
}
if (computed_value.length() == 0) {
if (EMSESP::webSchedulerService.computed_value.empty()) {
LOG_WARNING("Message result is empty");
return false;
}
LOG_INFO("Message: %s", computed_value.c_str()); // send to log
Mqtt::queue_publish(F_(message), computed_value); // send to MQTT if enabled
output["api_data"] = computed_value; // send to API
LOG_INFO("Message: %s", EMSESP::webSchedulerService.computed_value.c_str()); // send to log
Mqtt::queue_publish(F_(message), EMSESP::webSchedulerService.computed_value); // send to MQTT if enabled
output["api_data"] = EMSESP::webSchedulerService.computed_value; // send to API
return true;
}

View File

@@ -25,7 +25,7 @@
// UART drivers
#if defined(ESP32)
#include "uart/emsuart_esp32.h"
#include "../uart/emsuart_esp32.h"
#elif defined(EMSESP_STANDALONE)
#include "emsuart_standalone.h"
#endif

View File

@@ -887,6 +887,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
DeviceValueUOM::NONE,
MAKE_CF_CB(set_hpPumpMode));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &fan_, DeviceValueType::UINT8, FL_(hpFan), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_fan), 20, 100);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &fanspd_, DeviceValueType::UINT8, FL_(fanSpd), DeviceValueUOM::PERCENT);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&hpshutdown_,
DeviceValueType::CMD,
@@ -1215,10 +1216,9 @@ void Boiler::check_active() {
if (has_telegram_id(0xE4)) {
uint8_t data[] = {1, 0, 0, 1, 1};
write_command(EMS_TYPE_UBASetPoints2, 0, data, sizeof(data), 0);
} else {
uint8_t data[] = {0, 0, 0, 0};
write_command(EMS_TYPE_UBASetPoints, 0, data, sizeof(data), 0);
}
uint8_t data[] = {0, 0, 0, 0};
write_command(EMS_TYPE_UBASetPoints, 0, data, sizeof(data), 0);
}
// calculate energy for boiler 0x08 from stored modulation an time in units of 0.01 Wh
@@ -1733,6 +1733,7 @@ void Boiler::process_HpPower(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, hpTargetSpd_, 22);
has_update(telegram, receiverValveVr0_, 15);
has_update(telegram, expansionValveVr1_, 16);
has_update(telegram, fanspd_, 19);
// has_update(hpHeatingOn_, hpActivity_ == 1 ? 0xFF : 0);
// has_update(hpCoolingOn_, hpActivity_ == 2 ? 0xFF : 0);
@@ -2476,6 +2477,7 @@ bool Boiler::set_burn_power(const char * value, const int8_t id) {
if (has_telegram_id(0xE4)) {
write_command(EMS_TYPE_UBASetPoints2, 2, v);
write_command(EMS_TYPE_UBASetPoints, 1, v);
} else {
write_command(EMS_TYPE_UBASetPoints, 1, v);
}
@@ -3459,13 +3461,12 @@ bool Boiler::set_forceHeatingOff(const char * value, const int8_t id) {
if (has_telegram_id(0xE4)) {
uint8_t data[] = {1, heatingTemp_, (Helpers::hasValue(burnMaxPower_) ? burnMaxPower_ : (uint8_t)100), 1, 1};
write_command(EMS_TYPE_UBASetPoints2, 0, data, sizeof(data), 0);
} else {
uint8_t data[] = {heatingTemp_,
(Helpers::hasValue(burnMaxPower_) ? burnMaxPower_ : (uint8_t)100),
(Helpers::hasValue(pumpModMax_) ? pumpModMax_ : (uint8_t)100),
0};
write_command(EMS_TYPE_UBASetPoints, 0, data, sizeof(data), 0);
}
uint8_t data[] = {heatingTemp_,
(Helpers::hasValue(burnMaxPower_) ? burnMaxPower_ : (uint8_t)100),
(Helpers::hasValue(pumpModMax_) ? pumpModMax_ : (uint8_t)100),
0};
write_command(EMS_TYPE_UBASetPoints, 0, data, sizeof(data), 0);
}
has_update(forceHeatingOff_, v);
return true;

View File

@@ -245,6 +245,7 @@ class Boiler : public EMSdevice {
uint8_t hpPumpMode_;
uint8_t hpSetDiffPress_;
uint8_t fan_;
uint8_t fanspd_;
uint8_t hpshutdown_;
uint8_t receiverValveVr0_;
uint8_t expansionValveVr1_;

View File

@@ -1145,7 +1145,7 @@ void Thermostat::process_RC300Monitor(std::shared_ptr<const Telegram> telegram)
has_update(telegram, hc->targetflowtemp, 4);
has_update(telegram, hc->curroominfl, 27);
has_update(telegram, hc->currSolarInfl, 29);
has_update(telegram, hc->coolingon, 32);
has_bitupdate(telegram, hc->coolingon, 32, 0);
has_update(telegram, hc->vacationmode, 18);
add_ha_climate(hc);
@@ -1266,7 +1266,7 @@ void Thermostat::process_RC300Curve(std::shared_ptr<const Telegram> telegram) {
has_enumupdate(telegram, hc->nofrostmode, 5, 1); // 1-room, 2-outdoor, 3- room & outdoor
has_update(telegram, hc->nofrosttemp, 6);
if (hc->heatingtype < 2) {
if (hc->heatingtype < 3) {
has_update(telegram, hc->maxflowtemp, 8);
} else {
has_update(telegram, hc->maxflowtemp, 7);

View File

@@ -1 +1 @@
#define EMSESP_APP_VERSION "3.7.3-dev.23"
#define EMSESP_APP_VERSION "3.7.3-dev.24"

View File

@@ -459,6 +459,11 @@ void WebSchedulerService::loop() {
static uint32_t last_uptime_min = 0;
static uint32_t last_uptime_sec = 0;
if (!raw_value.empty()) { // process a value from system/message command
computed_value = compute(raw_value);
raw_value.clear();
}
// get list of scheduler events and exit if it's empty
if (scheduleItems_->empty()) {
return;

View File

@@ -86,6 +86,9 @@ class WebSchedulerService : public StatefulService<WebScheduler> {
uint8_t count_entities(bool cmd_only = false);
bool onChange(const char * cmd);
std::string raw_value;
std::string computed_value;
#if defined(EMSESP_TEST)
void load_test_data();
#endif