add forceheatingoff

This commit is contained in:
MichaelDvP
2023-10-07 15:19:04 +02:00
parent 5e53689a81
commit ac4eba5b72
20 changed files with 98 additions and 32 deletions

View File

@@ -9,6 +9,7 @@
- humidity for ventilation devices
- telegrams for RC100H, hc2 (seen on discord)
- names for BC400, GB192i, read temperatures for low loss header and heatblock [#1317](https://github.com/emsesp/EMS-ESP32/discussions/1317)
- option for `forceheatingoff` [#1262](https://github.com/emsesp/EMS-ESP32/issues/1262)
## Fixed

View File

@@ -26,9 +26,9 @@
"@mui/material": "^5.14.12",
"@table-library/react-table-library": "4.1.7",
"@types/lodash-es": "^4.17.9",
"@types/node": "^20.8.2",
"@types/node": "^20.8.3",
"@types/react": "^18.2.25",
"@types/react-dom": "^18.2.10",
"@types/react-dom": "^18.2.11",
"@types/react-router-dom": "^5.3.3",
"alova": "^2.13.1",
"async-validator": "^4.2.5",
@@ -53,7 +53,7 @@
"@types/babel__core": "^7",
"@typescript-eslint/eslint-plugin": "^6.7.4",
"@typescript-eslint/parser": "^6.7.4",
"eslint": "^8.50.0",
"eslint": "^8.51.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-airbnb-typescript": "^17.1.0",
"eslint-config-prettier": "^9.0.0",

View File

@@ -126,6 +126,7 @@ const de: Translation = {
BYPASS_TOKEN: 'Zugriffstoken-Autorisierung bei API-Aufrufen umgehen',
READONLY: 'Nur-Lese-Modus aktivieren (blockiert alle ausgehenden EMS Tx Write-Befehle)',
UNDERCLOCK_CPU: 'CPU-Geschwindigkeit untertakten',
HEATINGOFF: 'Heizen ausschalten beim EMS-ESP Start',
ENABLE_SHOWER_TIMER: 'Duschtimer aktivieren',
ENABLE_SHOWER_ALERT: 'Duschalarm aktivieren',
TRIGGER_TIME: 'Auslösezeit',

View File

@@ -126,6 +126,7 @@ const en: Translation = {
BYPASS_TOKEN: 'Bypass Access Token authorization on API calls',
READONLY: 'Enable read-only mode (blocks all outgoing EMS Tx Write commands)',
UNDERCLOCK_CPU: 'Underclock CPU speed',
HEATINGOFF: 'Start boiler with forced heating off',
ENABLE_SHOWER_TIMER: 'Enable Shower Timer',
ENABLE_SHOWER_ALERT: 'Enable Shower Alert',
TRIGGER_TIME: 'Trigger Time',

View File

@@ -126,6 +126,7 @@ const fr: Translation = {
BYPASS_TOKEN: 'Contourner l\'autorisation du jeton d\'accès sur les appels API',
READONLY: 'Activer le mode lecture uniquement (bloque toutes les commandes EMS sortantes en écriture Tx)',
UNDERCLOCK_CPU: 'Underclock du CPU',
HEATINGOFF: 'Start boiler with forced heating off', // TODO translate
ENABLE_SHOWER_TIMER: 'Activer la minuterie de la douche',
ENABLE_SHOWER_ALERT: 'Activer les alertes de durée de douche',
TRIGGER_TIME: 'Durée avant déclenchement',

View File

@@ -128,6 +128,7 @@ const it: Translation = {
BYPASS_TOKEN: 'Ignora autorizzazione del token di accesso sulle chiamate API',
READONLY: 'Abilita modalità sola-lettura (blocca tutti i comandi di scrittura EMS Tx in uscita)',
UNDERCLOCK_CPU: 'Abbassa velocità della CPU',
HEATINGOFF: 'Avviamento caldaia con riscaldamento forzato spento',
ENABLE_SHOWER_TIMER: 'Abilita timer doccia',
ENABLE_SHOWER_ALERT: 'Abilita avviso doccia',
TRIGGER_TIME: 'Tempo di avvio',

View File

@@ -126,6 +126,7 @@ const nl: Translation = {
BYPASS_TOKEN: 'API Access Token authenticatie uitschakelen',
READONLY: 'Activeer read-only modus (blokkeert alle outgaande EMS Tx schrijf commandos)',
UNDERCLOCK_CPU: 'Underclock CPU snelheid',
HEATINGOFF: 'Start boiler with forced heating off', // TODO translate
ENABLE_SHOWER_TIMER: 'Activeer Douche Timer (tijdmeting)',
ENABLE_SHOWER_ALERT: 'Activeer Douchemelding',
TRIGGER_TIME: 'Trigger tijd',

View File

@@ -126,6 +126,7 @@ const no: Translation = {
BYPASS_TOKEN: 'Utelat Aksess Token authorisering av API kall',
READONLY: 'Aktiver read-only modus (blokker all EMS Tx Skriving)',
UNDERCLOCK_CPU: 'Underklokking av prosessorhastighet',
HEATINGOFF: 'Start boiler with forced heating off', // TODO translate
ENABLE_SHOWER_TIMER: 'Aktiver Dusjtimer',
ENABLE_SHOWER_ALERT: 'Aktiver Dusj-varsling',
TRIGGER_TIME: 'Aktiveringstid',

View File

@@ -126,6 +126,7 @@ const pl: BaseTranslation = {
BYPASS_TOKEN: 'Pomiń autoryzację tokenem w wywołaniach API',
READONLY: 'Tryb pracy "tylko do odczytu" (blokuje wszystkie komendy zapisu na magistralę EMS)',
UNDERCLOCK_CPU: 'Obniż taktowanie CPU',
HEATINGOFF: 'Start boiler with forced heating off', // TODO translate
ENABLE_SHOWER_TIMER: 'Aktywuj minutnik prysznica',
ENABLE_SHOWER_ALERT: 'Aktywuj alarm prysznica',
TRIGGER_TIME: 'Wyzwalaj po czasie',

View File

@@ -126,6 +126,7 @@ const sv: Translation = {
BYPASS_TOKEN: 'Inaktivera Token-autensiering för API-anrop',
READONLY: 'Aktivera read-only (blockerar alla utgående skrivkommandon mot EMS-bussen)',
UNDERCLOCK_CPU: 'Nedklocka Processorhastighet',
HEATINGOFF: 'Start boiler with forced heating off', // TODO translate
ENABLE_SHOWER_TIMER: 'Aktivera Dusch-timer',
ENABLE_SHOWER_ALERT: 'Aktivera Dusch-varning',
TRIGGER_TIME: 'Aktiveringstid',

View File

@@ -126,6 +126,7 @@ const tr: Translation = {
BYPASS_TOKEN: 'API bağlantılarında Erişim Jeton onaylamasını geç',
READONLY: 'Salt okunur modu devreye al (bütün giden EMS Tx Yazma komutlarını engeller)',
UNDERCLOCK_CPU: 'İşlemci hızını düşür',
HEATINGOFF: 'Start boiler with forced heating off', // TODO translate
ENABLE_SHOWER_TIMER: 'Duş Sayacını Devreye Al',
ENABLE_SHOWER_ALERT: 'Duş Alarmını Devreye Al',
TRIGGER_TIME: 'Tetikleme Zamanı',

View File

@@ -425,6 +425,11 @@ const SettingsApplication: FC = () => {
label={LL.UNDERCLOCK_CPU()}
disabled={saving}
/>
<BlockFormControlLabel
control={<Checkbox checked={data.boiler_heatingoff} onChange={updateFormValue} name="boiler_heatingoff" />}
label={LL.HEATINGOFF()}
disabled={saving}
/>
<Grid container spacing={0} direction="row" justifyContent="flex-start" alignItems="flex-start">
<BlockFormControlLabel
control={<Checkbox checked={data.shower_timer} onChange={updateFormValue} name="shower_timer" />}

View File

@@ -7,6 +7,7 @@ export interface Settings {
syslog_mark_interval: number;
syslog_host: string;
syslog_port: number;
boiler_heatingoff: boolean;
shower_timer: boolean;
shower_alert: boolean;
shower_alert_coldshot: number;

View File

@@ -769,10 +769,10 @@ __metadata:
languageName: node
linkType: hard
"@eslint/js@npm:8.50.0":
version: 8.50.0
resolution: "@eslint/js@npm:8.50.0"
checksum: 92cb0a823869e85f287bd172f14a6a20d7d65c3f4db886a0356a9efebfe8fe519e9ead84a5687bd18f45eca417bdcce96e3b83fe3feae8baf0f8f44d14073bae
"@eslint/js@npm:8.51.0":
version: 8.51.0
resolution: "@eslint/js@npm:8.51.0"
checksum: c126d15213d938c72062b8f04388c084ba778771f2409ce508aa4b78152bf57e442b4c7996f632577b642101da5b41df101aece775fcc213a3159f55bcc4bdee
languageName: node
linkType: hard
@@ -1477,10 +1477,10 @@ __metadata:
languageName: node
linkType: hard
"@types/node@npm:^20.8.2":
version: 20.8.2
resolution: "@types/node@npm:20.8.2"
checksum: e9952db222dd3e1cca1107d1b2aaec4e93b4af8b4fc32b42dd4fac3719f98c14edb8c591829c972d2f6e2b527bbb34af53608f6a7973f4a7dbd1d3bc929bbe8d
"@types/node@npm:^20.8.3":
version: 20.8.3
resolution: "@types/node@npm:20.8.3"
checksum: 83511d7c310100f3fddbbf3a28f0049d60da6ffc4255231845b2e2189d7ff104727647d2b05d2a29b0af2ad61b529a4897056b3798e0cba027c629f3b13d7e82
languageName: node
linkType: hard
@@ -1505,12 +1505,12 @@ __metadata:
languageName: node
linkType: hard
"@types/react-dom@npm:^18.2.10":
version: 18.2.10
resolution: "@types/react-dom@npm:18.2.10"
"@types/react-dom@npm:^18.2.11":
version: 18.2.11
resolution: "@types/react-dom@npm:18.2.11"
dependencies:
"@types/react": "*"
checksum: ac4056c3b8ba5461a58a7933e1f98d772e877f275a1b4169a936391900aec8f3c8e6125ccbbda530842cd9d108a2be8c994c7f48bfd801f89702e2de9064d834
checksum: 3ba42df0dc1e8a26baed9668b9e2b5aea7c8e28289cf5baa656c1a07c6f83cd3c3360a374e00f96c01ce914950105d14d3ecd59be75cf215b8d3657b0b5d7785
languageName: node
linkType: hard
@@ -1717,15 +1717,15 @@ __metadata:
"@table-library/react-table-library": 4.1.7
"@types/babel__core": ^7
"@types/lodash-es": ^4.17.9
"@types/node": ^20.8.2
"@types/node": ^20.8.3
"@types/react": ^18.2.25
"@types/react-dom": ^18.2.10
"@types/react-dom": ^18.2.11
"@types/react-router-dom": ^5.3.3
"@typescript-eslint/eslint-plugin": ^6.7.4
"@typescript-eslint/parser": ^6.7.4
alova: ^2.13.1
async-validator: ^4.2.5
eslint: ^8.50.0
eslint: ^8.51.0
eslint-config-airbnb: ^19.0.4
eslint-config-airbnb-typescript: ^17.1.0
eslint-config-prettier: ^9.0.0
@@ -3088,14 +3088,14 @@ eslint-plugin-prettier@alpha:
languageName: node
linkType: hard
"eslint@npm:^8.50.0":
version: 8.50.0
resolution: "eslint@npm:8.50.0"
"eslint@npm:^8.51.0":
version: 8.51.0
resolution: "eslint@npm:8.51.0"
dependencies:
"@eslint-community/eslint-utils": ^4.2.0
"@eslint-community/regexpp": ^4.6.1
"@eslint/eslintrc": ^2.1.2
"@eslint/js": 8.50.0
"@eslint/js": 8.51.0
"@humanwhocodes/config-array": ^0.11.11
"@humanwhocodes/module-importer": ^1.0.1
"@nodelib/fs.walk": ^1.2.8
@@ -3131,7 +3131,7 @@ eslint-plugin-prettier@alpha:
text-table: ^0.2.0
bin:
eslint: bin/eslint.js
checksum: 91629528cb240bc61b25480574d35cd54ed444cb61a70fa76f7d5ab26af2b637b94bf8fba94403c9052c1baa944a169b6ab9cc8070496e925f7eeef730ff9038
checksum: b534962c60cb2ad219d20a33f93c80e8ea5dd89f390f7bab44c80df32134db0a87e73e7ccd2928d87498c0595128ee29b4dba8a1f1abbbb3da9c3fb0418ecdcc
languageName: node
linkType: hard

View File

@@ -61,6 +61,10 @@
#define EMSESP_DEFAULT_TRACELOG_RAW false
#endif
#ifndef EMSESP_DEFAULT_BOILER_HEATINGOFF
#define EMSESP_DEFAULT_BOILER_HEATINGOFF false
#endif
#ifndef EMSESP_DEFAULT_SHOWER_TIMER
#define EMSESP_DEFAULT_SHOWER_TIMER false
#endif

View File

@@ -119,7 +119,12 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
// reset is a command uses a dummy variable which is always zero, shown as blank, but provides command enum options
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &reset_, DeviceValueType::CMD, FL_(enum_reset), FL_(reset), DeviceValueUOM::NONE, MAKE_CF_CB(set_reset));
has_update(reset_, 0);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&forceHeatingOff_,
DeviceValueType::BOOL,
FL_(forceHeatingOff),
DeviceValueUOM::NONE,
MAKE_CF_CB(set_forceHeatingOff));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingActive_, DeviceValueType::BOOL, FL_(heatingActive), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &tapwaterActive_, DeviceValueType::BOOL, FL_(tapwaterActive), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &selFlowTemp_, DeviceValueType::UINT, FL_(selFlowTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flow_temp));
@@ -963,6 +968,11 @@ void Boiler::check_active() {
EMSESP::tap_water_active(b); // let EMS-ESP know, used in the Shower class
}
if (!Helpers::hasValue(forceHeatingOff_, EMS_VALUE_BOOL)) {
EMSESP::webSettingsService.read([&](WebSettings & settings) { forceHeatingOff_ = (settings.boiler_heatingoff || selFlowTemp_ == 0) ? 1 : 0; });
has_update(&forceHeatingOff_);
}
// calculate energy for boiler 0x08 from stored modulation an time in units of 0.01 Wh
if (model() != EMS_DEVICE_FLAG_HEATPUMP) {
// remember values from last call
@@ -1220,6 +1230,11 @@ void Boiler::process_UBAMonitorSlow(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, burn2WorkMin_, 16, 3); // force to 3 bytes
has_update(telegram, heatWorkMin_, 19, 3); // force to 3 bytes
has_update(telegram, heatStarts_, 22, 3); // force to 3 bytes
if (forceHeatingOff_ == EMS_VALUE_BOOL_ON && telegram->dest == 0) {
uint8_t data[] = {0, 0, 0, 0};
write_command(EMS_TYPE_UBASetPoints, 0, data, sizeof(data), 0);
}
}
/*
@@ -1250,6 +1265,11 @@ void Boiler::process_UBAMonitorSlowPlus(std::shared_ptr<const Telegram> telegram
has_update(telegram, heatStarts_, 22, 3); // force to 3 bytes
has_update(telegram, heatingPumpMod_, 25);
// temperature measurements at 4, see #620
if (forceHeatingOff_ == EMS_VALUE_BOOL_ON && telegram->dest == 0) {
uint8_t data[] = {0, 0, 0, 0};
write_command(EMS_TYPE_UBASetPoints, 0, data, sizeof(data), 0);
}
}
/*
@@ -1499,6 +1519,12 @@ void Boiler::process_UBASetPoints(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, setFlowTemp_, 0); // boiler set temp from thermostat
has_update(telegram, setBurnPow_, 1); // max burner power in %
has_update(telegram, wwSetPumpPower_, 2); // ww pump speed/power?
// overwrite other settings on receive?
if (forceHeatingOff_ == EMS_VALUE_BOOL_ON && telegram->dest == 0x08) {
uint8_t data[] = {0, 0, 0, 0};
write_command(EMS_TYPE_UBASetPoints, 0, data, sizeof(data), 0);
}
}
#pragma GCC diagnostic push
@@ -2049,9 +2075,6 @@ bool Boiler::set_ww_chargeOptimization(const char * value, const int8_t id) {
return true;
}
// set dhw max power
bool Boiler::set_ww_maxpower(const char * value, const int8_t id) {
int v;
@@ -2360,12 +2383,10 @@ bool Boiler::set_reset(const char * value, const int8_t id) {
} else if (num == 1) {
// LOG_INFO("Reset boiler maintenance message");
write_command(0x05, 0x08, 0xFF, 0x1C);
has_update(&reset_);
return true;
} else if (num == 2) {
// LOG_INFO("Reset boiler error message");
write_command(0x05, 0x00, 0x5A); // error reset
has_update(&reset_);
return true;
}
return false;
@@ -2768,6 +2789,22 @@ bool Boiler::set_wwAltOpPrio(const char * value, const int8_t id) {
return false;
}
bool Boiler::set_forceHeatingOff(const char * value, const int8_t id) {
bool v;
if (Helpers::value2bool(value, v)) {
has_update(forceHeatingOff_, v);
if (!v && Helpers::hasValue(heatingTemp_)) {
uint8_t data[] = {heatingTemp_,
(Helpers::hasValue(burnMaxPower_) ? burnMaxPower_ : (uint8_t)100),
(Helpers::hasValue(pumpModMax_) ? pumpModMax_ : (uint8_t)0),
0};
write_command(EMS_TYPE_UBASetPoints, 0, data, sizeof(data), 0);
}
return true;
}
return false;
}
// energy counters. Setting an invalid value does not update, but trigger a store.
bool Boiler::set_nrgHeat(const char * value, const int8_t id) {
float v;

View File

@@ -88,7 +88,6 @@ class Boiler : public EMSdevice {
uint32_t wwWorkM_; // DHW minutes
int8_t wwHystOn_;
int8_t wwHystOff_;
uint8_t wwTapActivated_; // maintenance-mode to switch DHW off
uint16_t wwMixerTemp_; // mixing temperature
uint16_t wwCylMiddleTemp_; // Cyl middle temperature (TS3)
uint16_t wwSolarTemp_;
@@ -96,6 +95,10 @@ class Boiler : public EMSdevice {
uint8_t wwAltOpPrioHeat_; // alternating operation, prioritize heat time
uint8_t wwAltOpPrioWw_; // alternating operation, prioritize dhw time
// special function
uint8_t forceHeatingOff_;
uint8_t wwTapActivated_; // maintenance-mode to switch DHW off
// main
uint8_t reset_; // for reset command
uint8_t heatingActive_; // Central heating is on/off
@@ -470,6 +473,8 @@ class Boiler : public EMSdevice {
inline bool set_wwAltOpPrioWw(const char * value, const int8_t id) {
return set_wwAltOpPrio(value, 3);
}
bool set_forceHeatingOff(const char * value, const int8_t id);
/*
bool set_hybridStrategy(const char * value, const int8_t id);
bool set_switchOverTemp(const char * value, const int8_t id);

View File

@@ -283,6 +283,7 @@ MAKE_TRANSLATION(haclimate, "haclimate", "Discovery current room temperature", "
// Entity translations: tag, mqtt, en, de, nl, sv, pl, no, fr, tr, it
// Boiler
MAKE_TRANSLATION(forceHeatingOff, "heatingoff", "force heating off", "Heizen abschalten", "", "", "", "", "", "", "") // TODO translate
MAKE_TRANSLATION(wwtapactivated, "wwtapactivated", "turn on/off", "Durchlauferhitzer aktiv", "zet aan/uit", "på/av", "system przygotowywania", "Varmtvann active", "ecs activée", "aç/kapa", "commuta on/off")
MAKE_TRANSLATION(reset, "reset", "reset", "Reset", "Reset", "Nollställ", "kasowanie komunikatu", "nullstill", "reset", "Sıfırla", "Reset")
MAKE_TRANSLATION(oilPreHeat, "oilpreheat", "oil preheating", "Ölvorwärmung", "Olie voorverwarming", "Förvärmning olja", "podgrzewanie oleju", "oljeforvarming", "préchauffage de l'huile", "Yakıt Ön ısıtma devrede", "preriscaldamento olio")

View File

@@ -46,6 +46,7 @@ void WebSettings::read(WebSettings & settings, JsonObject & root) {
root["syslog_mark_interval"] = settings.syslog_mark_interval;
root["syslog_host"] = settings.syslog_host;
root["syslog_port"] = settings.syslog_port;
root["boiler_heatingoff"] = settings.boiler_heatingoff;
root["shower_timer"] = settings.shower_timer;
root["shower_alert"] = settings.shower_alert;
root["shower_alert_coldshot"] = settings.shower_alert_coldshot;
@@ -275,6 +276,7 @@ StateUpdateResult WebSettings::update(JsonObject & root, WebSettings & settings)
settings.notoken_api = root["notoken_api"] | EMSESP_DEFAULT_NOTOKEN_API;
settings.solar_maxflow = root["solar_maxflow"] | EMSESP_DEFAULT_SOLAR_MAXFLOW;
settings.boiler_heatingoff = root["boiler_heatingoff"] | EMSESP_DEFAULT_BOILER_HEATINGOFF;
settings.fahrenheit = root["fahrenheit"];
EMSESP::system_.fahrenheit(settings.fahrenheit);

View File

@@ -33,6 +33,7 @@ class WebSettings {
String locale;
uint8_t tx_mode;
uint8_t ems_bus_id;
bool boiler_heatingoff;
bool shower_timer;
bool shower_alert;
uint8_t shower_alert_trigger;