This commit is contained in:
MichaelDvP
2023-01-22 10:48:37 +01:00
6 changed files with 112 additions and 13 deletions

View File

@@ -104,8 +104,6 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingActive_, DeviceValueType::BOOL, FL_(heatingActive), DeviceValueUOM::NONE); 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, &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)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &selFlowTemp_, DeviceValueType::UINT, FL_(selFlowTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flow_temp));
register_device_value(
DeviceValueTAG::TAG_DEVICE_DATA, &selBurnPow_, DeviceValueType::UINT, FL_(selBurnPow), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_burn_power), 0, 254);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingPumpMod_, DeviceValueType::UINT, FL_(heatingPumpMod), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingPumpMod_, DeviceValueType::UINT, FL_(heatingPumpMod), DeviceValueUOM::PERCENT);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&outdoorTemp_, &outdoorTemp_,
@@ -184,6 +182,8 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setFlowTemp_, DeviceValueType::UINT, FL_(setFlowTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setFlowTemp_, DeviceValueType::UINT, FL_(setFlowTemp), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setBurnPow_, DeviceValueType::UINT, FL_(setBurnPow), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setBurnPow_, DeviceValueType::UINT, FL_(setBurnPow), DeviceValueUOM::PERCENT);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &absBurnPow_, DeviceValueType::UINT, FL_(absBurnPow), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &absBurnPow_, DeviceValueType::UINT, FL_(absBurnPow), DeviceValueUOM::PERCENT);
register_device_value(
DeviceValueTAG::TAG_DEVICE_DATA, &selBurnPow_, DeviceValueType::UINT, FL_(selBurnPow), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_burn_power), 0, 254);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &curBurnPow_, DeviceValueType::UINT, FL_(curBurnPow), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &curBurnPow_, DeviceValueType::UINT, FL_(curBurnPow), DeviceValueUOM::PERCENT);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnStarts_, DeviceValueType::ULONG, FL_(burnStarts), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnStarts_, DeviceValueType::ULONG, FL_(burnStarts), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnWorkMin_, DeviceValueType::TIME, FL_(burnWorkMin), DeviceValueUOM::MINUTES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnWorkMin_, DeviceValueType::TIME, FL_(burnWorkMin), DeviceValueUOM::MINUTES);
@@ -445,8 +445,6 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
FL_(maxHeatHeat), FL_(maxHeatHeat),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_maxHeatHeat)); MAKE_CF_CB(set_maxHeatHeat));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &manDefrost_, DeviceValueType::BOOL, FL_(manDefrost), DeviceValueUOM::NONE, MAKE_CF_CB(set_manDefrost));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &pvCooling_, DeviceValueType::BOOL, FL_(pvCooling), DeviceValueUOM::NONE, MAKE_CF_CB(set_pvCooling));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&maxHeatDhw_, &maxHeatDhw_,
DeviceValueType::ENUM, DeviceValueType::ENUM,
@@ -454,6 +452,8 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
FL_(maxHeatDhw), FL_(maxHeatDhw),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_maxHeatDhw)); MAKE_CF_CB(set_maxHeatDhw));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &manDefrost_, DeviceValueType::BOOL, FL_(manDefrost), DeviceValueUOM::NONE, MAKE_CF_CB(set_manDefrost));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &pvCooling_, DeviceValueType::BOOL, FL_(pvCooling), DeviceValueUOM::NONE, MAKE_CF_CB(set_pvCooling));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&auxHeaterOnly_, &auxHeaterOnly_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
@@ -615,6 +615,28 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_elHeatStep3)); MAKE_CF_CB(set_elHeatStep3));
// heatpump DHW settings // heatpump DHW settings
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
&wwAlternatingOper_,
DeviceValueType::BOOL,
FL_(wwAlternatingOper),
DeviceValueUOM::NONE,
MAKE_CF_CB(set_wwAlternatingOper));
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
&wwAltOpPrioHeat_,
DeviceValueType::UINT,
FL_(wwAltOpPrioHeat),
DeviceValueUOM::MINUTES,
MAKE_CF_CB(set_wwAltOpPrioHeat),
20,
120);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
&wwAltOpPrioWw_,
DeviceValueType::UINT,
FL_(wwAltOpPrioWw),
DeviceValueUOM::MINUTES,
MAKE_CF_CB(set_wwAltOpPrioWw),
30,
120);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
&wwComfOffTemp_, &wwComfOffTemp_,
DeviceValueType::UINT, DeviceValueType::UINT,
@@ -1119,6 +1141,7 @@ void Boiler::process_UBAParameterWWPlus(std::shared_ptr<const Telegram> telegram
has_update(telegram, wwCircPump_, 10); // 0x01 means yes has_update(telegram, wwCircPump_, 10); // 0x01 means yes
has_update(telegram, wwCircMode_, 11); // 0=off, 1=1x3min... 6=6x3min, 7=continuous has_update(telegram, wwCircMode_, 11); // 0=off, 1=1x3min... 6=6x3min, 7=continuous
has_update(telegram, wwDisinfectionTemp_, 12); // setting here, status in E9 has_update(telegram, wwDisinfectionTemp_, 12); // setting here, status in E9
has_update(telegram, wwAlternatingOper_, 14); // 0x01 means enabled
has_update(telegram, wwSelTempSingle_, 16); has_update(telegram, wwSelTempSingle_, 16);
has_update(telegram, wwSelTempLow_, 18); has_update(telegram, wwSelTempLow_, 18);
has_update(telegram, wwMaxTemp_, 20); has_update(telegram, wwMaxTemp_, 20);
@@ -1470,6 +1493,8 @@ void Boiler::process_UBAMaintenanceData(std::shared_ptr<const Telegram> telegram
// Boiler(0x08) -> All(0x00), ?(0x0484), data: 00 00 14 28 0D 50 00 00 00 02 02 07 28 01 00 02 05 19 0A 0A 03 0D 07 00 0A // Boiler(0x08) -> All(0x00), ?(0x0484), data: 00 00 14 28 0D 50 00 00 00 02 02 07 28 01 00 02 05 19 0A 0A 03 0D 07 00 0A
// Boiler(0x08) -> All(0x00), ?(0x0484), data: 01 90 00 F6 28 14 64 00 00 E1 00 1E 00 1E 01 64 01 64 54 20 00 00 (offset 25) // Boiler(0x08) -> All(0x00), ?(0x0484), data: 01 90 00 F6 28 14 64 00 00 E1 00 1E 00 1E 01 64 01 64 54 20 00 00 (offset 25)
void Boiler::process_HpSilentMode(std::shared_ptr<const Telegram> telegram) { void Boiler::process_HpSilentMode(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, wwAltOpPrioHeat_, 2); // range 20-120 minutes on Buderus WSW196i
has_update(telegram, wwAltOpPrioWw_, 3); // range 30-120 minutes on Buderus WSW196i
has_update(telegram, silentMode_, 10); // enum off-auto-on has_update(telegram, silentMode_, 10); // enum off-auto-on
has_update(telegram, minTempSilent_, 11); has_update(telegram, minTempSilent_, 11);
has_update(telegram, hpHystHeat_, 37); // is / 5 has_update(telegram, hpHystHeat_, 37); // is / 5
@@ -2517,4 +2542,24 @@ bool Boiler::set_elHeatStep(const char * value, const int8_t id) {
return false; return false;
} }
// dhw alternating operation, turn on/off; heatpumps only?
bool Boiler::set_wwAlternatingOper(const char * value, const int8_t id) {
bool v;
if (!Helpers::value2bool(value, v)) {
return false;
}
write_command(EMS_TYPE_UBAParameterWWPlus, 14, v ? 1 : 0, EMS_TYPE_UBAParameterWWPlus);
return true;
}
// dhw alternating operation, set prioitise heating (id=2) or dhw (id=3) time; heatpumps only?
bool Boiler::set_wwAltOpPrio(const char * value, const int8_t id) {
int v;
if (Helpers::value2number(value, v)) {
write_command(0x484, id, v, 0x484);
return true;
}
return false;
}
} // namespace emsesp } // namespace emsesp

View File

@@ -64,7 +64,7 @@ class Boiler : public EMSdevice {
uint8_t wwChargeOptimization_; // DHW charge optimization uint8_t wwChargeOptimization_; // DHW charge optimization
uint8_t wwDisinfectionTemp_; // DHW disinfection temperature to prevent infection uint8_t wwDisinfectionTemp_; // DHW disinfection temperature to prevent infection
uint8_t wwCircMode_; // DHW circulation pump mode uint8_t wwCircMode_; // DHW circulation pump mode
uint8_t wwCirc_; // Circulation on/off uint8_t wwCirc_; // DHW circulation on/off
uint16_t wwCurTemp_; // DHW current temperature uint16_t wwCurTemp_; // DHW current temperature
uint16_t wwCurTemp2_; // DHW current temperature storage uint16_t wwCurTemp2_; // DHW current temperature storage
uint8_t wwCurFlow_; // DHW current flow temp in l/min uint8_t wwCurFlow_; // DHW current flow temp in l/min
@@ -91,6 +91,9 @@ class Boiler : public EMSdevice {
uint16_t wwMixerTemp_; // mixing temperature uint16_t wwMixerTemp_; // mixing temperature
uint16_t wwCylMiddleTemp_; // Cyl middle temperature (TS3) uint16_t wwCylMiddleTemp_; // Cyl middle temperature (TS3)
uint16_t wwSolarTemp_; uint16_t wwSolarTemp_;
uint8_t wwAlternatingOper_; // alternating operation on/off
uint8_t wwAltOpPrioHeat_; // alternating operation, prioritise heat time
uint8_t wwAltOpPrioWw_; // alternating operation, prioritise dhw time
// main // main
uint8_t reset_; // for reset command uint8_t reset_; // for reset command
@@ -434,6 +437,14 @@ class Boiler : public EMSdevice {
inline bool set_elHeatStep3(const char * value, const int8_t id) { inline bool set_elHeatStep3(const char * value, const int8_t id) {
return set_elHeatStep(value, 3); return set_elHeatStep(value, 3);
} }
bool set_wwAlternatingOper(const char * value, const int8_t id);
bool set_wwAltOpPrio(const char * value, const int8_t id);
inline bool set_wwAltOpPrioHeat(const char * value, const int8_t id) {
return set_wwAltOpPrio(value, 2);
}
inline bool set_wwAltOpPrioWw(const char * value, const int8_t id) {
return set_wwAltOpPrio(value, 3);
}
/* /*
bool set_hybridStrategy(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); bool set_switchOverTemp(const char * value, const int8_t id);

View File

@@ -597,14 +597,16 @@ bool Helpers::value2bool(const char * value, bool & value_b) {
return false; return false;
} }
std::string bool_str = toLower(value); // convert to lower case std::string bool_str = toLower(value);
if ((bool_str == std::string(Helpers::translated_word(FL_(on)))) || (bool_str == "on") || (bool_str == "1") || (bool_str == "true")) { if ((bool_str == std::string(Helpers::translated_word(FL_(on)))) || (bool_str == toLower(Helpers::translated_word(FL_(ON)))) || (bool_str == "on")
|| (bool_str == "1") || (bool_str == "true")) {
value_b = true; value_b = true;
return true; // is a bool return true; // is a bool
} }
if ((bool_str == std::string(Helpers::translated_word(FL_(off)))) || (bool_str == "off") || (bool_str == "0") || (bool_str == "false")) { if ((bool_str == std::string(Helpers::translated_word(FL_(off)))) || (bool_str == toLower(Helpers::translated_word(FL_(OFF)))) || (bool_str == "off")
|| (bool_str == "0") || (bool_str == "false")) {
value_b = false; value_b = false;
return true; // is a bool return true; // is a bool
} }
@@ -677,6 +679,43 @@ std::string Helpers::toUpper(std::string const & s) {
return lc; return lc;
} }
// capitalizes one UTF-8 character in char array
// works with Latin1 (1 byte), Polish amd some other (2 bytes) characters
// TODO add special characters that occur in other supported languages
void Helpers::CharToUpperUTF8(char * c) {
switch (*c) {
case 0xC3:
// grave, acute, circumflex, diaeresis, etc.
if ((*(c + 1) >= 0xA0) && (*(c + 1) <= 0xBE)) {
*(c + 1) -= 0x20;
}
break;
case 0xC4:
switch (*(c + 1)) {
case 0x85: //ą (0xC4,0x85) -> Ą (0xC4,0x84)
case 0x87: //ć (0xC4,0x87) -> Ć (0xC4,0x86)
case 0x99: //ę (0xC4,0x99) -> Ę (0xC4,0x98)
*(c + 1) -= 1;
break;
}
break;
case 0xC5:
switch (*(c + 1)) {
case 0x82: //ł (0xC5,0x82) -> Ł (0xC5,0x81)
case 0x84: //ń (0xC5,0x84) -> Ń (0xC5,0x83)
case 0x9B: //ś (0xC5,0x9B) -> Ś (0xC5,0x9A)
case 0xBA: //ź (0xC5,0xBA) -> Ź (0xC5,0xB9)
case 0xBC: //ż (0xC5,0xBC) -> Ż (0xC5,0xBB)
*(c + 1) -= 1;
break;
}
break;
default:
*c = toupper(*c); //works on Latin1 letters
break;
}
}
// replace char in char string // replace char in char string
void Helpers::replace_char(char * str, char find, char replace) { void Helpers::replace_char(char * str, char find, char replace) {
if (str == nullptr) { if (str == nullptr) {

View File

@@ -55,6 +55,7 @@ class Helpers {
static std::string toLower(std::string const & s); static std::string toLower(std::string const & s);
static std::string toUpper(std::string const & s); static std::string toUpper(std::string const & s);
static std::string toLower(const char * s); static std::string toLower(const char * s);
static void CharToUpperUTF8(char * c);
static void replace_char(char * str, char find, char replace); static void replace_char(char * str, char find, char replace);

View File

@@ -416,6 +416,9 @@ MAKE_PSTR_LIST(hp3wayValve, "hp3way", "3-way valve") // TODO translate
MAKE_PSTR_LIST(elHeatStep1, "elheatstep1", "el. heater step 1") // TODO translate MAKE_PSTR_LIST(elHeatStep1, "elheatstep1", "el. heater step 1") // TODO translate
MAKE_PSTR_LIST(elHeatStep2, "elheatstep2", "el. heater step 2") // TODO translate MAKE_PSTR_LIST(elHeatStep2, "elheatstep2", "el. heater step 2") // TODO translate
MAKE_PSTR_LIST(elHeatStep3, "elheatstep3", "el. heater step 3") // TODO translate MAKE_PSTR_LIST(elHeatStep3, "elheatstep3", "el. heater step 3") // TODO translate
MAKE_PSTR_LIST(wwAlternatingOper, "wwalternatingop", "alternating operation", "", "", "", "praca naprzemienna", "", "") // TODO translate
MAKE_PSTR_LIST(wwAltOpPrioHeat, "wwaltopprioheat", "prioritise heating during dhw", "", "", "", "czas na ogrzewanie w trakcie c.w.u", "", "") // TODO translate
MAKE_PSTR_LIST(wwAltOpPrioWw, "wwaltopprioww", "prioritise dhw during heating", "", "", "", "czas na c.w.u w trakcie ogrzewania", "", "") // TODO translate
// hybrid heatpump // hybrid heatpump
MAKE_PSTR_LIST(hybridStrategy, "hybridstrategy", "hybrid control strategy", "Hybrid Strategie", "Hybride strategie", "Hybrid kontrollstrategi", "strategia sterowania hybrydowego", "hybrid kontrollstrategi", "stratégie contrôle hybride") MAKE_PSTR_LIST(hybridStrategy, "hybridstrategy", "hybrid control strategy", "Hybrid Strategie", "Hybride strategie", "Hybrid kontrollstrategi", "strategia sterowania hybrydowego", "hybrid kontrollstrategi", "stratégie contrôle hybride")

View File

@@ -907,7 +907,7 @@ void Mqtt::publish_ha_sensor_config(DeviceValue & dv, const std::string & model,
if (create_device_config) { if (create_device_config) {
auto cap_name = strdup(device_type_name); auto cap_name = strdup(device_type_name);
cap_name[0] = toupper(cap_name[0]); // capitalize Helpers::CharToUpperUTF8(cap_name); // capitalize first letter
dev_json["name"] = std::string("EMS-ESP ") + cap_name; dev_json["name"] = std::string("EMS-ESP ") + cap_name;
dev_json["mf"] = brand; dev_json["mf"] = brand;
dev_json["mdl"] = model; dev_json["mdl"] = model;
@@ -1003,7 +1003,7 @@ void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
if (EMSdevice::tag_to_string(tag).empty()) { if (EMSdevice::tag_to_string(tag).empty()) {
snprintf(uniq_id, sizeof(uniq_id), "%s_%s", device_name, Helpers::toLower(uniq_s).c_str()); snprintf(uniq_id, sizeof(uniq_id), "%s_%s", device_name, Helpers::toLower(uniq_s).c_str());
} else { } else {
snprintf(uniq_id, sizeof(uniq_id), "%s_%s_%s", device_name, EMSdevice::tag_to_string(tag).c_str(), Helpers::toLower(uniq_s).c_str()); snprintf(uniq_id, sizeof(uniq_id), "%s_%s_%s", device_name, EMSdevice::tag_to_string(tag, false).c_str(), Helpers::toLower(uniq_s).c_str());
} }
} }
@@ -1132,7 +1132,7 @@ void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
// friendly name = <tag> <name> // friendly name = <tag> <name>
char ha_name[70]; char ha_name[70];
char * F_name = strdup(fullname); char * F_name = strdup(fullname);
F_name[0] = toupper(F_name[0]); // capitalize first letter Helpers::CharToUpperUTF8(F_name); // capitalize first letter
if (EMSdevice::tag_to_string(tag).empty()) { if (EMSdevice::tag_to_string(tag).empty()) {
snprintf(ha_name, sizeof(ha_name), "%s", F_name); // no tag snprintf(ha_name, sizeof(ha_name), "%s", F_name); // no tag
} else { } else {