remove mqtt custom, add thermostat wwtemps, mixing mqtt formats and api output

This commit is contained in:
MichaelDvP
2020-10-08 10:37:21 +02:00
parent 7d5a654f52
commit bddf377b59
9 changed files with 93 additions and 77 deletions

View File

@@ -69,22 +69,22 @@ void Mixing::device_info_web(JsonArray & root) {
// fetch the values into a JSON document
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_MEDIUM> doc;
JsonObject output = doc.to<JsonObject>();
if (!export_values(output)) {
if (!export_values(Mqtt::Format::SINGLE, output)) {
return; // empty
}
char prefix_str[10];
if (type() == Type::WWC) {
snprintf_P(prefix_str, sizeof(prefix_str), PSTR("(wwc %d) "), hc_);
print_value_json(root, F("wwTemp"), FPSTR(prefix_str), F_(wwTemp), F_(degrees), output);
print_value_json(root, F("pumpStatus"), FPSTR(prefix_str), F_(pumpStatus), nullptr, output);
print_value_json(root, F("tempStatus"), FPSTR(prefix_str), F_(tempStatus), nullptr, output);
} else {
if (type() == Type::HC) {
snprintf_P(prefix_str, sizeof(prefix_str), PSTR("(hc %d) "), hc_);
print_value_json(root, F("flowTemp"), FPSTR(prefix_str), F_(flowTemp), F_(degrees), output);
print_value_json(root, F("flowSetTemp"), FPSTR(prefix_str), F_(flowSetTemp), F_(degrees), output);
print_value_json(root, F("pumpStatus"), FPSTR(prefix_str), F_(pumpStatus), nullptr, output);
print_value_json(root, F("valveStatus"), FPSTR(prefix_str), F_(valveStatus), F_(percent), output);
} else {
snprintf_P(prefix_str, sizeof(prefix_str), PSTR("(wwc %d) "), hc_);
print_value_json(root, F("wwTemp"), FPSTR(prefix_str), F_(wwTemp), F_(degrees), output);
print_value_json(root, F("pumpStatus"), FPSTR(prefix_str), F_(pumpStatus), nullptr, output);
print_value_json(root, F("tempStatus"), FPSTR(prefix_str), F_(tempStatus), nullptr, output);
}
}
@@ -108,28 +108,32 @@ void Mixing::show_values(uuid::console::Shell & shell) {
// fetch the values into a JSON document
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_MEDIUM> doc;
JsonObject output = doc.to<JsonObject>();
if (!export_values(output)) {
if (!export_values(Mqtt::Format::SINGLE, output)) {
return; // empty
}
if (type() == Type::WWC) {
shell.println(F_(ww_hc));
print_value_json(shell, F("wwTemp"), nullptr, F_(wwTemp), F_(degrees), output);
print_value_json(shell, F("pumpStatus"), nullptr, F_(pumpStatus), nullptr, output);
print_value_json(shell, F("tempStatus"), nullptr, F_(tempStatus), nullptr, output);
if (type() == Type::HC) {
shell.printfln(F_(hc), hc_);
print_value_json(shell, F("flowTemp"), F(" "), F_(flowTemp), F_(degrees), output);
print_value_json(shell, F("flowSetTemp"), F(" "), F_(flowSetTemp), F_(degrees), output);
print_value_json(shell, F("pumpStatus"), F(" "), F_(pumpStatus), nullptr, output);
print_value_json(shell, F("valveStatus"), F(" "), F_(valveStatus), F_(percent), output);
} else {
shell.println(F_(hc));
print_value_json(shell, F("flowTemp"), nullptr, F_(flowTemp), F_(degrees), output);
print_value_json(shell, F("flowSetTemp"), nullptr, F_(flowSetTemp), F_(degrees), output);
print_value_json(shell, F("pumpStatus"), nullptr, F_(pumpStatus), nullptr, output);
print_value_json(shell, F("valveStatus"), nullptr, F_(valveStatus), F_(percent), output);
shell.printfln(F_(ww_hc), hc_);
print_value_json(shell, F("wwTemp"), F(" "), F_(wwTemp), F_(degrees), output);
print_value_json(shell, F("pumpStatus"), F(" "), F_(pumpStatus), nullptr, output);
print_value_json(shell, F("tempStatus"), F(" "), F_(tempStatus), nullptr, output);
}
shell.println();
}
// export all valuet to info command
bool Mixing::command_info(const char * value, const int8_t id, JsonObject & output) {
return (export_values(output));
if (id != (device_id() - 0x20 + 1) && id > 0) { // defaults to first hc if no id
return false;
}
return (export_values(Mqtt::Format::NESTED, output));
}
// publish values via MQTT
@@ -137,7 +141,7 @@ bool Mixing::command_info(const char * value, const int8_t id, JsonObject & outp
void Mixing::publish_values() {
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_SMALL> doc;
JsonObject output = doc.to<JsonObject>();
if (export_values(output)) {
if (export_values(Mqtt::mqtt_format(), output)) {
char topic[30];
char s[5];
strlcpy(topic, "mixing_data", 30);
@@ -189,43 +193,49 @@ void Mixing::register_mqtt_ha_config(const char * topic) {
// creates JSON doc from values
// returns false if empty
bool Mixing::export_values(JsonObject & output) {
switch (this->type()) {
case Type::HC:
output["type"] = "hc";
bool Mixing::export_values(uint8_t mqtt_format, JsonObject & output) {
JsonObject output_hc;
char hc_name[10]; // hc{1-4}
if (this->type() == Type::HC) {
snprintf_P(hc_name, sizeof(hc_name), PSTR("hc%d"), hc_);
if ((mqtt_format == Mqtt::Format::NESTED)) {
output_hc = output.createNestedObject(hc_name);
} else {
output_hc = output;
output["type"] = "hc";
}
if (Helpers::hasValue(flowTemp_)) {
output["flowTemp"] = (float)flowTemp_ / 10;
output_hc["flowTemp"] = (float)flowTemp_ / 10;
}
if (Helpers::hasValue(flowSetTemp_)) {
output["flowSetTemp"] = flowSetTemp_;
output_hc["flowSetTemp"] = flowSetTemp_;
}
if (Helpers::hasValue(pumpStatus_)) {
char s[5]; // for formatting strings
output["pumpStatus"] = Helpers::render_value(s, pumpStatus_, EMS_VALUE_BOOL);
output_hc["pumpStatus"] = Helpers::render_value(s, pumpStatus_, EMS_VALUE_BOOL);
}
if (Helpers::hasValue(status_)) {
output["valveStatus"] = status_;
output_hc["valveStatus"] = status_;
}
} else {
snprintf_P(hc_name, sizeof(hc_name), PSTR("wwc%d"), hc_);
if ((mqtt_format == Mqtt::Format::NESTED)) {
output_hc = output.createNestedObject(hc_name);
} else {
output_hc = output;
output["type"] = "wwc";
}
break;
case Type::WWC:
output["type"] = "wwc";
if (Helpers::hasValue(flowTemp_)) {
output["wwTemp"] = (float)flowTemp_ / 10;
output_hc["wwTemp"] = (float)flowTemp_ / 10;
}
if (Helpers::hasValue(pumpStatus_)) {
char s[5]; // for formatting strings
output["pumpStatus"] = Helpers::render_value(s, pumpStatus_, EMS_VALUE_BOOL);
output_hc["pumpStatus"] = Helpers::render_value(s, pumpStatus_, EMS_VALUE_BOOL);
}
if (Helpers::hasValue(status_)) {
output["tempStatus"] = status_;
output_hc["tempStatus"] = status_;
}
break;
case Type::NONE:
default:
return false;
break;
}
return output.size();
@@ -285,8 +295,8 @@ void Mixing::process_MMStatusMessage(std::shared_ptr<const Telegram> telegram) {
// 0x21 is position 2. 0x20 is typically reserved for the WM10 switch module
// see https://github.com/proddy/EMS-ESP/issues/270 and https://github.com/proddy/EMS-ESP/issues/386#issuecomment-629610918
hc_ = device_id() - 0x20 + 1;
changed_ |= telegram->read_value(flowTemp_, 1); // is * 10
changed_ |= telegram->read_bitvalue(pumpStatus_, 3, 0);
changed_ |= telegram->read_value(flowTemp_, 1); // is * 10
changed_ |= telegram->read_bitvalue(pumpStatus_, 3, 2); // is 0 or 0x64 (100%), check only bit 2
changed_ |= telegram->read_value(flowSetTemp_, 0);
changed_ |= telegram->read_value(status_, 4); // valve status -100 to 100
}

View File

@@ -44,7 +44,7 @@ class Mixing : public EMSdevice {
private:
static uuid::log::Logger logger_;
bool export_values(JsonObject & doc);
bool export_values(uint8_t mqtt_format, JsonObject & doc);
void register_mqtt_ha_config(const char * topic);
bool command_info(const char * value, const int8_t id, JsonObject & output);

View File

@@ -182,6 +182,8 @@ void Thermostat::device_info_web(JsonArray & root) {
print_value_json(root, F("minexttemp"), nullptr, F_(minexttemp), F_(degrees), output_main);
print_value_json(root, F("building"), nullptr, F_(building), nullptr, output_main);
print_value_json(root, F("wwmode"), nullptr, F_(wwmode), nullptr, output_main);
print_value_json(root, F("wwtemp"), nullptr, F_(wwtemp), nullptr, output_main);
print_value_json(root, F("wwtemplow"), nullptr, F_(wwtemplow), nullptr, output_main);
print_value_json(root, F("wwcircmode"), nullptr, F_(wwcircmode), nullptr, output_main);
}
@@ -192,13 +194,10 @@ void Thermostat::device_info_web(JsonArray & root) {
for (const auto & hc : heating_circuits_) {
if (hc->is_active()) {
char prefix_str[10];
snprintf_P(prefix_str, sizeof(prefix_str), PSTR("(hc %d) "), hc->hc_num());
snprintf_P(prefix_str, sizeof(prefix_str), PSTR("hc%d"), hc->hc_num());
JsonObject output = output_hc[prefix_str];
char hc_name[10]; // hc{1-4}
strlcpy(hc_name, "hc", 10);
char s[3];
strlcat(hc_name, Helpers::itoa(s, hc->hc_num()), 10);
JsonObject output = output_hc[hc_name];
snprintf_P(prefix_str, sizeof(prefix_str), PSTR("(hc %d) "), hc->hc_num());
print_value_json(root, F("seltemp"), FPSTR(prefix_str), F_(seltemp), F_(degrees), output);
print_value_json(root, F("currtemp"), FPSTR(prefix_str), F_(currtemp), F_(degrees), output);
@@ -263,6 +262,8 @@ void Thermostat::show_values(uuid::console::Shell & shell) {
print_value_json(shell, F("minexttemp"), nullptr, F_(minexttemp), F_(degrees), output_main);
print_value_json(shell, F("building"), nullptr, F_(building), nullptr, output_main);
print_value_json(shell, F("wwmode"), nullptr, F_(wwmode), nullptr, output_main);
print_value_json(shell, F("wwtemp"), nullptr, F_(wwtemp), nullptr, output_main);
print_value_json(shell, F("wwtemplow"), nullptr, F_(wwtemplow), nullptr, output_main);
print_value_json(shell, F("wwcircmode"), nullptr, F_(wwcircmode), nullptr, output_main);
}
@@ -274,12 +275,10 @@ void Thermostat::show_values(uuid::console::Shell & shell) {
// display for each active heating circuit
for (const auto & hc : heating_circuits_) {
if (hc->is_active()) {
shell.printfln(" Heating Circuit %d:", hc->hc_num());
shell.printfln(F_(hc), hc->hc_num());
char hc_name[10]; // hc{1-4}
strlcpy(hc_name, "hc", 10);
char s[3];
strlcat(hc_name, Helpers::itoa(s, hc->hc_num()), 10);
snprintf_P(hc_name, sizeof(hc_name), PSTR("hc%d"), hc->hc_num());
JsonObject output = output_hc[hc_name];
print_value_json(shell, F("seltemp"), F(" "), F_(seltemp), F_(degrees), output);
@@ -423,6 +422,16 @@ bool Thermostat::export_values_main(JsonObject & rootThermostat) {
}
}
// Warm water temp
if (Helpers::hasValue(wwTemp_)) {
rootThermostat["wwtemp"] = wwTemp_;
}
// Warm water low temp
if (Helpers::hasValue(wwTempLow_)) {
rootThermostat["wwtemplow"] = wwTempLow_;
}
// Warm Water circulation mode
if (Helpers::hasValue(wwCircMode_)) {
char s[7];
@@ -546,7 +555,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, {"off", "auto", "on"}, hc->summer_setmode);
dataThermostat["summermode"] = Helpers::render_enum(s, {"summer", "auto", "winter"}, hc->summer_setmode);
}
// mode - always force showing this when in HA so not to break HA's climate component
@@ -1710,7 +1719,7 @@ bool Thermostat::set_summermode(const char * value, const int8_t id) {
return false;
}
uint8_t set = 0xFF;
if (!Helpers::value2enum(value, set, {"off", "auto", "on"})) {
if (!Helpers::value2enum(value, set, {"summer", "auto", "winter"})) {
LOG_WARNING(F("Setting summer mode: Invalid mode"));
return false;
}