Merge remote-tracking branch 'upstream/dev' into dev

This commit is contained in:
hpanther
2020-11-05 14:47:18 +01:00
21 changed files with 191 additions and 1331 deletions

View File

@@ -1202,7 +1202,7 @@ bool Boiler::set_pump_delay(const char * value, const int8_t id) {
// on a RC35 it's by EMSESP::send_write_request(0x37, 0x10, 2, &set, 1, 0); (set is 1,2,3) 1=hot, 2=eco, 3=intelligent
bool Boiler::set_warmwater_mode(const char * value, const int8_t id) {
uint8_t set;
if (!Helpers::value2enum(value, set, {"hot", "eco", "intelligent"})) {
if (!Helpers::value2enum(value, set, {F("hot"), F("eco"), F("intelligent")})) {
LOG_WARNING(F("Set boiler warm water mode: Invalid value"));
return false;
}

View File

@@ -224,7 +224,7 @@ bool Mixer::export_values(JsonObject & json) {
// returns false if empty
bool Mixer::export_values_format(uint8_t mqtt_format, JsonObject & json) {
// check if there is data for the mixer unit
if (!Helpers::hasValue(status_)) {
if (this->type() == Type::NONE) {
return 0;
}
@@ -249,7 +249,7 @@ bool Mixer::export_values_format(uint8_t mqtt_format, JsonObject & json) {
json_hc["flowSetTemp"] = flowSetTemp_;
}
if (Helpers::hasValue(pumpStatus_)) {
char s[5];
char s[7];
json_hc["pumpStatus"] = Helpers::render_value(s, pumpStatus_, EMS_VALUE_BOOL);
}
if (Helpers::hasValue(status_)) {
@@ -274,7 +274,7 @@ bool Mixer::export_values_format(uint8_t mqtt_format, JsonObject & json) {
json_hc["wwTemp"] = (float)flowTemp_ / 10;
}
if (Helpers::hasValue(pumpStatus_)) {
char s[5];
char s[7];
json_hc["pumpStatus"] = Helpers::render_value(s, pumpStatus_, EMS_VALUE_BOOL);
}
if (Helpers::hasValue(status_)) {
@@ -316,7 +316,7 @@ void Mixer::process_IPMStatusMessage(std::shared_ptr<const Telegram> telegram) {
// check if circuit is active, 0-off, 1-unmixed, 2-mixed
uint8_t ismixed = 0;
changed_ |= telegram->read_value(ismixed, 0);
telegram->read_value(ismixed, 0);
if (ismixed == 0) {
return;
}

View File

@@ -419,7 +419,7 @@ bool Thermostat::export_values_main(JsonObject & rootThermostat) {
// Floordry
if (Helpers::hasValue(floordrystatus_) && Helpers::hasValue(floordrytemp_) && (floordrytemp_ > 0)) {
char s[10];
rootThermostat["floordry"] = Helpers::render_enum(s, {"off", "start", "heat", "hold", "cool", "end"}, floordrystatus_);
rootThermostat["floordry"] = Helpers::render_enum(s, {F("off"), F("start"), F("heat"), F("hold"), F("cool"), F("end")}, floordrystatus_);
rootThermostat["floordrytemp"] = floordrytemp_;
}
@@ -447,9 +447,9 @@ bool Thermostat::export_values_main(JsonObject & rootThermostat) {
if (Helpers::hasValue(ibaBuildingType_)) {
char s[10];
if (model == EMS_DEVICE_FLAG_RC300 || model == EMS_DEVICE_FLAG_RC100) {
rootThermostat["building"] = Helpers::render_enum(s, {"light", "medium", "heavy"}, ibaBuildingType_ - 1);
rootThermostat["building"] = Helpers::render_enum(s, {F("light"), F("medium"), F("heavy")}, ibaBuildingType_ - 1);
} else {
rootThermostat["building"] = Helpers::render_enum(s, {"light", "medium", "heavy"}, ibaBuildingType_);
rootThermostat["building"] = Helpers::render_enum(s, {F("light"), F("medium"), F("heavy")}, ibaBuildingType_);
}
}
@@ -457,9 +457,9 @@ bool Thermostat::export_values_main(JsonObject & rootThermostat) {
if (Helpers::hasValue(wwMode_)) {
char s[10];
if (model == EMS_DEVICE_FLAG_RC300 || model == EMS_DEVICE_FLAG_RC100) {
rootThermostat["wwmode"] = Helpers::render_enum(s, {"off", "low", "high", "auto", "own_prog"}, wwMode_);
rootThermostat["wwmode"] = Helpers::render_enum(s, {F("off"), F("low"), F("high"), F("auto"), F("own_prog")}, wwMode_);
} else {
rootThermostat["wwmode"] = Helpers::render_enum(s, {"off", "on", "auto"}, wwMode_);
rootThermostat["wwmode"] = Helpers::render_enum(s, {F("off"), F("on"), F("auto")}, wwMode_);
}
}
@@ -476,7 +476,7 @@ bool Thermostat::export_values_main(JsonObject & rootThermostat) {
// Warm Water circulation mode
if (Helpers::hasValue(wwCircMode_)) {
char s[7];
rootThermostat["wwcircmode"] = Helpers::render_enum(s, {"off", "on", "auto"}, wwCircMode_);
rootThermostat["wwcircmode"] = Helpers::render_enum(s, {F("off"), F("on"), F("auto")}, wwCircMode_);
}
return (rootThermostat.size());
@@ -608,7 +608,7 @@ bool Thermostat::export_values_hc(uint8_t mqtt_format, JsonObject & rootThermost
// Summer mode
if (Helpers::hasValue(hc->summer_setmode)) {
char s[7];
dataThermostat["summermode"] = Helpers::render_enum(s, {"summer", "auto", "winter"}, hc->summer_setmode);
dataThermostat["summermode"] = Helpers::render_enum(s, {F("summer"), F("auto"), F("winter")}, hc->summer_setmode);
}
// mode - always force showing this when in HA so not to break HA's climate component
@@ -1514,7 +1514,7 @@ bool Thermostat::set_remotetemp(const char * value, const int8_t id) {
// 0xA5 - Set the building settings
bool Thermostat::set_building(const char * value, const int8_t id) {
uint8_t bd = 0;
if (!Helpers::value2enum(value, bd, {"light", "medium", "heavy"})) {
if (!Helpers::value2enum(value, bd, {F("light"), F("medium"), F("heavy")})) {
LOG_WARNING(F("Set building: Invalid value"));
return false;
}
@@ -1533,7 +1533,7 @@ bool Thermostat::set_building(const char * value, const int8_t id) {
// 0xA5 Set the language settings
bool Thermostat::set_language(const char * value, const int8_t id) {
uint8_t lg = 0;
if (!Helpers::value2enum(value, lg, {"german", "dutch", "french", "italian"})) {
if (!Helpers::value2enum(value, lg, {F("german"), F("dutch"), F("french"), F("italian")})) {
LOG_WARNING(F("Set language: Invalid value"));
return false;
}
@@ -1586,14 +1586,14 @@ bool Thermostat::set_roominfluence(const char * value, const int8_t id) {
bool Thermostat::set_wwmode(const char * value, const int8_t id) {
uint8_t set = 0xFF;
if ((this->model() == EMS_DEVICE_FLAG_RC300) || (this->model() == EMS_DEVICE_FLAG_RC100)) {
if (!Helpers::value2enum(value, set, {"off", "low", "high", "auto", "own"})) {
if (!Helpers::value2enum(value, set, {F("off"), F("low"), F("high"), F("auto"), F("own")})) {
LOG_WARNING(F("Set warm water mode: Invalid mode"));
return false;
}
LOG_INFO(F("Setting warm water mode to %s"), value);
write_command(0x02F5, 2, set, 0x02F5);
} else {
if (!Helpers::value2enum(value, set, {"off", "on", "auto"})) {
if (!Helpers::value2enum(value, set, {F("off"), F("on"), F("auto")})) {
LOG_WARNING(F("Set warm water mode: Invalid mode"));
return false;
}
@@ -1631,7 +1631,7 @@ bool Thermostat::set_wwtemplow(const char * value, const int8_t id) {
// sets the thermostat ww circulation working mode, where mode is a string
bool Thermostat::set_wwcircmode(const char * value, const int8_t id) {
uint8_t set = 0xFF;
if (!Helpers::value2enum(value, set, {"off", "on", "auto"})) {
if (!Helpers::value2enum(value, set, {F("off"), F("on"), F("auto")})) {
LOG_WARNING(F("Set warm water circulation mode: Invalid mode"));
return false;
}
@@ -1909,7 +1909,7 @@ bool Thermostat::set_summermode(const char * value, const int8_t id) {
return false;
}
uint8_t set = 0xFF;
if (!Helpers::value2enum(value, set, {"summer", "auto", "winter"})) {
if (!Helpers::value2enum(value, set, {F("summer"), F("auto"), F("winter")})) {
LOG_WARNING(F("Setting summer mode: Invalid mode"));
return false;
}

View File

@@ -133,7 +133,7 @@ class Thermostat : public EMSdevice {
std::vector<uint16_t> summer_typeids;
std::string datetime_; // date and time stamp
std::string errorCode_; // code as string i.e. "A22(816)"
std::string errorCode_; // code from 0xA2 as string i.e. "A22(816)"
bool changed_ = false;
bool ha_registered_ = false;

View File

@@ -917,7 +917,7 @@ void EMSESP::start() {
emsdevices.reserve(5); // reserve space for initially 5 devices to avoid mem
LOG_INFO("EMS Device library loaded with %d records", device_library_.size());
LOG_INFO(F("EMS Device library loaded with %d records"), device_library_.size());
#if defined(EMSESP_STANDALONE)
mqtt_.on_connect(); // simulate an MQTT connection

View File

@@ -136,21 +136,18 @@ char * Helpers::render_boolean(char * result, bool value) {
}
// depending on format render a number or a string
char * Helpers::render_enum(char * result, const std::vector<std::string> & value, const uint8_t no) {
char * Helpers::render_enum(char * result, const std::vector<const __FlashStringHelper *> value, const uint8_t no) {
if (no >= value.size()) {
return nullptr; // out of bounds
}
if (bool_format() == BOOL_FORMAT_ONOFF) {
strcpy(result, value[no].c_str());
} else if (bool_format() == BOOL_FORMAT_TRUEFALSE) {
if (no == 0 && value[0] == "off") {
strcpy(result, uuid::read_flash_string(value[no]).c_str());
if (bool_format() == BOOL_FORMAT_TRUEFALSE) {
if (no == 0 && uuid::read_flash_string(value[0]) == "off") {
strlcpy(result, "false", 7);
} else if (no == 1 && value[1] == "on") {
} else if (no == 1 && uuid::read_flash_string(value[1]) == "on") {
strlcpy(result, "true", 6);
} else {
strcpy(result, value[no].c_str());
}
} else {
} else if (bool_format() == BOOL_FORMAT_NUMBERS) {
itoa(result, no);
}
return result;
@@ -462,13 +459,14 @@ bool Helpers::value2bool(const char * v, bool & value) {
}
// checks to see if a string is member of a vector and return the index, also allow true/false for on/off
bool Helpers::value2enum(const char * v, uint8_t & value, const std::vector<std::string> & strs) {
bool Helpers::value2enum(const char * v, uint8_t & value, const std::vector<const __FlashStringHelper *> strs) {
if ((v == nullptr) || (strlen(v) == 0)) {
return false;
}
std::string str = toLower(v);
for (value = 0; value < strs.size(); value++) {
if ((strs[value] == "off" && str == "false") || (strs[value] == "on" && str == "true") || (str == strs[value]) || (v[0] == '0' + value)) {
std::string str1 = uuid::read_flash_string(strs[value]);
if ((str1 == "off" && str == "false") || (str1 == "on" && str == "true") || (str == str1) || (v[0] == '0' + value)) {
return true;
}
}

View File

@@ -26,6 +26,7 @@
#define BOOL_FORMAT_ONOFF 1
#define BOOL_FORMAT_TRUEFALSE 2
#define BOOL_FORMAT_NUMBERS 3
namespace emsesp {
@@ -39,7 +40,7 @@ class Helpers {
static char * render_value(char * result, const int16_t value, const uint8_t format);
static char * render_value(char * result, const char * value, uint8_t format);
static char * render_boolean(char * result, bool value);
static char * render_enum(char * result, const std::vector<std::string> & value, const uint8_t no);
static char * render_enum(char * result, const std::vector<const __FlashStringHelper *> value, const uint8_t no);
static char * hextoa(char * result, const uint8_t value);
static std::string data_to_hex(const uint8_t * data, const uint8_t length);
@@ -62,7 +63,7 @@ class Helpers {
static bool value2float(const char * v, float & value);
static bool value2bool(const char * v, bool & value);
static bool value2string(const char * v, std::string & value);
static bool value2enum(const char * v, uint8_t & value, const std::vector<std::string> & strs);
static bool value2enum(const char * v, uint8_t & value, const std::vector<const __FlashStringHelper *> strs);
static void bool_format(uint8_t bool_format) {
bool_format_ = bool_format;

View File

@@ -486,7 +486,7 @@ void Mqtt::on_connect() {
// homeassistant/sensor/ems-esp/status/config
// all the values from the heartbeat payload will be added as attributes to the entity state
void Mqtt::ha_status() {
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_MEDIUM> doc;
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_SMALL> doc;
doc["name"] = F("EMS-ESP status");
doc["uniq_id"] = F("status");
@@ -697,7 +697,9 @@ void Mqtt::register_mqtt_ha_binary_sensor(const __FlashStringHelper * name, cons
return;
}
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_MEDIUM> doc;
return; // TODO
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_SMALL> doc;
doc["name"] = name;
doc["uniq_id"] = entity;
@@ -729,9 +731,9 @@ void Mqtt::register_mqtt_ha_binary_sensor(const __FlashStringHelper * name, cons
snprintf_P(topic, sizeof(topic), PSTR("homeassistant/binary_sensor/ems-esp/%s/config"), entity);
// convert json to string and publish immediately with retain forced to true
std::string payload_text;
char payload_text[300];
serializeJson(doc, payload_text); // convert json to string
uint16_t packet_id = mqttClient_->publish(topic, 0, true, payload_text.c_str(), payload_text.size());
uint16_t packet_id = mqttClient_->publish(topic, 0, true, payload_text);
#if defined(EMSESP_STANDALONE)
LOG_DEBUG(F("Publishing topic %s"), topic);
#else
@@ -802,7 +804,7 @@ void Mqtt::register_mqtt_ha_sensor(const char * prefix,
}
new_name[0] = toupper(new_name[0]); // capitalize first letter
DynamicJsonDocument doc(EMSESP_MAX_JSON_SIZE_MEDIUM);
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_SMALL> doc;
doc["name"] = new_name;
doc["uniq_id"] = uniq;
if (uom != nullptr) {
@@ -818,21 +820,22 @@ void Mqtt::register_mqtt_ha_sensor(const char * prefix,
ids.add(ha_device);
// convert json to string and publish immediately with retain forced to true
doc.shrinkToFit();
std::string payload_text;
// std::string payload_text;
char payload_text[300];
serializeJson(doc, payload_text); // convert json to string
uint16_t packet_id = mqttClient_->publish(topic, 0, true, payload_text.c_str(), payload_text.size());
uint16_t packet_id = mqttClient_->publish(topic, 0, true, payload_text);
if (!packet_id) {
LOG_ERROR(F("Failed to publish topic %s"), topic);
} else {
#if defined(EMSESP_STANDALONE)
LOG_DEBUG(F("Publishing topic=%s, payload=%s"), topic, payload_text.c_str());
LOG_DEBUG(F("Publishing topic=%s, payload=%s"), topic, payload_text);
#else
LOG_DEBUG(F("Publishing topic %s"), topic);
#endif
}
delay(MQTT_PUBLISH_WAIT); // don't flood asynctcp
// delay(MQTT_PUBLISH_WAIT); // don't flood asynctcp
}
} // namespace emsesp

View File

@@ -61,7 +61,7 @@ bool System::command_send(const char * value, const int8_t id) {
// restart EMS-ESP
void System::restart() {
LOG_NOTICE("Restarting system...");
LOG_NOTICE(F("Restarting system..."));
Shell::loop_all();
delay(1000); // wait a second
#if defined(ESP8266)
@@ -73,7 +73,7 @@ void System::restart() {
// saves all settings
void System::wifi_reconnect() {
LOG_NOTICE("The wifi will reconnect...");
LOG_NOTICE(F("The wifi will reconnect..."));
Shell::loop_all();
delay(1000); // wait a second
EMSESP::webSettingsService.save(); // local settings

View File

@@ -1 +1 @@
#define EMSESP_APP_VERSION "2.1.1b0"
#define EMSESP_APP_VERSION "2.1.1b1"