From d15fbe7801f9afc4f4f8ebdbd4a8c5c6f401b0d5 Mon Sep 17 00:00:00 2001 From: pswid <78219494+pswid@users.noreply.github.com> Date: Tue, 10 Jan 2023 11:50:02 +0100 Subject: [PATCH 1/6] added dhw alternating operation --- src/device_library.h | 2 +- src/devices/boiler.cpp | 57 ++++++++++++++++++++++++++++++++++++--- src/devices/boiler.h | 13 ++++++++- src/locale_translations.h | 3 +++ 4 files changed, 69 insertions(+), 6 deletions(-) diff --git a/src/device_library.h b/src/device_library.h index 85f493489..88beb343d 100644 --- a/src/device_library.h +++ b/src/device_library.h @@ -40,7 +40,7 @@ {167, DeviceType::BOILER, "Cerapur Aero", DeviceFlags::EMS_DEVICE_FLAG_NONE}, {168, DeviceType::BOILER, "Hybrid Heatpump", DeviceFlags::EMS_DEVICE_FLAG_HYBRID}, {170, DeviceType::BOILER, "Logano GB212", DeviceFlags::EMS_DEVICE_FLAG_NONE}, -{172, DeviceType::BOILER, "Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i", DeviceFlags::EMS_DEVICE_FLAG_HEATPUMP}, +{172, DeviceType::BOILER, "Enviline/Compress 6000AW/Hybrid 3000-7000iAW/SupraEco/Geo 5xx/WLW196i/WSW196i", DeviceFlags::EMS_DEVICE_FLAG_HEATPUMP}, {173, DeviceType::BOILER, "Geo 5xx", DeviceFlags::EMS_DEVICE_FLAG_HEATPUMP}, {195, DeviceType::BOILER, "Condens 5000i/Greenstar 8000/GC9800IW", DeviceFlags::EMS_DEVICE_FLAG_NONE}, {203, DeviceType::BOILER, "Logamax U122/Cerapur", DeviceFlags::EMS_DEVICE_FLAG_NONE}, diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 1614b7824..2361ada94 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -102,8 +102,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, &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, &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, &heatingPump2Mod_, DeviceValueType::UINT, FL_(heatingPump2Mod), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, @@ -182,6 +180,8 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const DeviceValueTAG::TAG_DEVICE_DATA, &boil2HystOff_, DeviceValueType::INT, FL_(boil2HystOff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst2_off), 0, 20); 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, &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, &burnStarts_, DeviceValueType::ULONG, FL_(burnStarts), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnWorkMin_, DeviceValueType::TIME, FL_(burnWorkMin), DeviceValueUOM::MINUTES); @@ -443,8 +443,6 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const FL_(maxHeatHeat), DeviceValueUOM::NONE, 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, &maxHeatDhw_, DeviceValueType::ENUM, @@ -452,6 +450,8 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const FL_(maxHeatDhw), DeviceValueUOM::NONE, 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, &auxHeaterOnly_, DeviceValueType::BOOL, @@ -556,6 +556,28 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const 3, 10); // 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, &wwComfOffTemp_, DeviceValueType::UINT, @@ -1058,6 +1080,7 @@ void Boiler::process_UBAParameterWWPlus(std::shared_ptr telegram has_update(telegram, wwCircPump_, 10); // 0x01 means yes has_enumupdate(telegram, wwCircMode_, 11, 1); // 1=1x3min... 6=6x3min, 7=continuous 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, wwSelTempLow_, 18); has_update(telegram, wwMaxTemp_, 20); @@ -1408,6 +1431,8 @@ void Boiler::process_UBAMaintenanceData(std::shared_ptr 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: 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 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, minTempSilent_, 11); has_update(telegram, hpHystHeat_, 37); // is / 5 @@ -2350,4 +2375,28 @@ bool Boiler::set_hpCircPumpWw(const char * value, const int8_t id) { 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; + } + // if (is_fetch(EMS_TYPE_UBAParameterWWPlus)) { // do we need/want this? + write_command(EMS_TYPE_UBAParameterWWPlus, 14, v ? 1 : 0, EMS_TYPE_UBAParameterWWPlus); + // } else { + // write_command(EMS_TYPE_UBAParameterWW, 14, v ? 0xFF : 0, EMS_TYPE_UBAParameterWW); + // } + 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 diff --git a/src/devices/boiler.h b/src/devices/boiler.h index 9a3451ef0..3de6a9459 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -64,7 +64,7 @@ class Boiler : public EMSdevice { uint8_t wwChargeOptimization_; // DHW charge optimization uint8_t wwDisinfectionTemp_; // DHW disinfection temperature to prevent infection 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 wwCurTemp2_; // DHW current temperature storage 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 wwCylMiddleTemp_; // Cyl middle temperature (TS3) 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 uint8_t reset_; // for reset command @@ -395,6 +398,14 @@ class Boiler : public EMSdevice { inline bool set_wwEcoPlusOffTemp(const char * value, const int8_t id) { return set_wwOffTemp(value, 5); } + 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_switchOverTemp(const char * value, const int8_t id); diff --git a/src/locale_translations.h b/src/locale_translations.h index 324d8f1fd..05c2a4c7e 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -405,6 +405,9 @@ MAKE_PSTR_LIST(auxMaxTemp, "auxmaxtemp", "aux heater max temperature", "Zusatzhe MAKE_PSTR_LIST(manDefrost, "mandefrost", "manual defrost", "Manuelle Enteisung", "", "", "", "", "") // TODO translate MAKE_PSTR_LIST(pvCooling, "pvcooling", "Cooling only with PV", "Kühlen nur mit PV", "", "", "", "", "") // TODO translate MAKE_PSTR_LIST(hpCircPumpWw, "hpcircpumpww", "circulation pump available during dhw", "", "", "", "", "", "") // 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 MAKE_PSTR_LIST(hybridStrategy, "hybridstrategy", "hybrid control strategy", "Hybrid Strategie", "Hybride strategie", "Hybrid kontrollstrategi", "strategia sterowania hybrydowego", "hybrid kontrollstrategi", "stratégie contrôle hybride") From d72d2b33bd396a803782583d4b8ed50492eae30d Mon Sep 17 00:00:00 2001 From: pswid <78219494+pswid@users.noreply.github.com> Date: Tue, 10 Jan 2023 12:04:27 +0100 Subject: [PATCH 2/6] =?UTF-8?q?fix=20Polish=20boolean=20option=20"w=C5=82.?= =?UTF-8?q?/wy=C5=82."=20not=20working?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Because of compiler error, in Polish translation, we don't use uppercase boolean option "WŁĄCZONO/WYŁĄCZONO" but "wł./wył." instead. --- src/helpers.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/helpers.cpp b/src/helpers.cpp index f027df312..5242ec5d5 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -596,14 +596,16 @@ bool Helpers::value2bool(const char * value, bool & value_b) { return false; } - std::string bool_str = toLower(value); // convert to lower case + std::string bool_str = 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 == std::string(Helpers::translated_word(FL_(ON)))) + || (bool_str == "on") || (bool_str == "1") || (bool_str == "true")) { value_b = true; 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 == std::string(Helpers::translated_word(FL_(OFF)))) + || (bool_str == "off") || (bool_str == "0") || (bool_str == "false")) { value_b = false; return true; // is a bool } From bbbeb155f091f3dbbfaea1e26b4120c85ffe08ec Mon Sep 17 00:00:00 2001 From: pswid <78219494+pswid@users.noreply.github.com> Date: Fri, 13 Jan 2023 21:45:29 +0100 Subject: [PATCH 3/6] tags in entity IDs (long format) always in English now in mqtt discovery topics you can see e.g: "uniq_id": "thermostat_OG1_mode_type" (for Polish lang.) but should be: "uniq_id": "thermostat_hc1_mode_type", --- src/mqtt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mqtt.cpp b/src/mqtt.cpp index d9d5cb456..80749352b 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -1003,7 +1003,7 @@ void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev if (EMSdevice::tag_to_string(tag).empty()) { snprintf(uniq_id, sizeof(uniq_id), "%s_%s", device_name, Helpers::toLower(uniq_s).c_str()); } 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()); } } From 4f05ddab93d4321c236e7489b63a9716b45fda54 Mon Sep 17 00:00:00 2001 From: pswid <78219494+pswid@users.noreply.github.com> Date: Sun, 15 Jan 2023 13:00:22 +0100 Subject: [PATCH 4/6] =?UTF-8?q?fix=20for=20d72d2b3=20(Polish=20boolean=20o?= =?UTF-8?q?ption=20"w=C5=82./wy=C5=82.")?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Because of compiler error, in Polish translation, we don't use uppercase boolean option "WŁĄCZONO/WYŁĄCZONO" but "wł./wył." instead. --- src/helpers.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/helpers.cpp b/src/helpers.cpp index 5242ec5d5..020e8119a 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -596,15 +596,15 @@ bool Helpers::value2bool(const char * value, bool & value_b) { return false; } - std::string bool_str = value; + std::string bool_str = toLower(value); - if ((bool_str == std::string(Helpers::translated_word(FL_(on)))) || (bool_str == std::string(Helpers::translated_word(FL_(ON)))) + 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; return true; // is a bool } - if ((bool_str == std::string(Helpers::translated_word(FL_(off)))) || (bool_str == std::string(Helpers::translated_word(FL_(OFF)))) + 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; return true; // is a bool From 7e174a1b7d5ac6fd6d2153c1e17b3a382d5a92fe Mon Sep 17 00:00:00 2001 From: pswid <78219494+pswid@users.noreply.github.com> Date: Wed, 18 Jan 2023 21:43:29 +0100 Subject: [PATCH 5/6] Fix first letter not capitalized in Polish --- src/helpers.cpp | 35 +++++++++++++++++++++++++++++++++++ src/helpers.h | 1 + src/mqtt.cpp | 4 ++-- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/helpers.cpp b/src/helpers.cpp index 020e8119a..47531e8af 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -678,6 +678,41 @@ std::string Helpers::toUpper(std::string const & s) { return lc; } +// capitalizes one UTF-8 character in char array +// works with Latin1 (1 byte) and Polish (2 bytes) characters +// TODO add special characters that occur in other supported languages +void Helpers::CharToUpperUTF8(char * c) { + switch (*c) { + case 0xC3: + if (*(c + 1) == 0xB3) //ó (0xC3,0xB3) -> Ó (0xC3,0x93) + *(c + 1) = 0x93; + 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) = *(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) = *(c + 1) - 1; + break; + } + break; + default: + *c = toupper(*c); //works on Latin1 letters + break; + } +} + // replace char in char string void Helpers::replace_char(char * str, char find, char replace) { if (str == nullptr) { diff --git a/src/helpers.h b/src/helpers.h index e4505643c..67b633227 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -55,6 +55,7 @@ class Helpers { static std::string toLower(std::string const & s); static std::string toUpper(std::string const & s); static std::string toLower(const char * s); + static void CharToUpperUTF8(char * c); static void replace_char(char * str, char find, char replace); diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 80749352b..d2fe4b174 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -907,7 +907,7 @@ void Mqtt::publish_ha_sensor_config(DeviceValue & dv, const std::string & model, if (create_device_config) { 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["mf"] = brand; dev_json["mdl"] = model; @@ -1132,7 +1132,7 @@ void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev // friendly name = char ha_name[70]; 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()) { snprintf(ha_name, sizeof(ha_name), "%s", F_name); // no tag } else { From 5e41481e279f12f6f2cdde54ec0157f98469cd57 Mon Sep 17 00:00:00 2001 From: pswid <78219494+pswid@users.noreply.github.com> Date: Sat, 21 Jan 2023 12:09:17 +0100 Subject: [PATCH 6/6] capitalize more special chcaracters --- src/helpers.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/helpers.cpp b/src/helpers.cpp index 47531e8af..7928d7cc5 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -679,20 +679,22 @@ std::string Helpers::toUpper(std::string const & s) { } // capitalizes one UTF-8 character in char array -// works with Latin1 (1 byte) and Polish (2 bytes) characters +// 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: - if (*(c + 1) == 0xB3) //ó (0xC3,0xB3) -> Ó (0xC3,0x93) - *(c + 1) = 0x93; + // 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) = *(c + 1) - 1; + *(c + 1) -= 1; break; } break; @@ -703,7 +705,7 @@ void Helpers::CharToUpperUTF8(char * c) { case 0x9B: //ś (0xC5,0x9B) -> Ś (0xC5,0x9A) case 0xBA: //ź (0xC5,0xBA) -> Ź (0xC5,0xB9) case 0xBC: //ż (0xC5,0xBC) -> Ż (0xC5,0xBB) - *(c + 1) = *(c + 1) - 1; + *(c + 1) -= 1; break; } break;