mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2026-01-29 01:59:08 +03:00
Merge branch 'v2_cmd' into v2
This commit is contained in:
@@ -18,65 +18,52 @@
|
||||
|
||||
#include "boiler.h"
|
||||
|
||||
MAKE_PSTR_WORD(boiler)
|
||||
MAKE_PSTR_WORD(wwtemp)
|
||||
MAKE_PSTR_WORD(flowtemp)
|
||||
MAKE_PSTR_WORD(wwactive)
|
||||
MAKE_PSTR_WORD(wwonetime)
|
||||
MAKE_PSTR_WORD(wwcirculation)
|
||||
MAKE_PSTR_WORD(comfort)
|
||||
MAKE_PSTR_WORD(eco)
|
||||
MAKE_PSTR_WORD(intelligent)
|
||||
MAKE_PSTR_WORD(hot)
|
||||
MAKE_PSTR_WORD(maxpower)
|
||||
MAKE_PSTR_WORD(minpower)
|
||||
|
||||
MAKE_PSTR(comfort_mandatory, "<hot | eco | intelligent>")
|
||||
|
||||
// shower
|
||||
MAKE_PSTR_WORD(shower)
|
||||
MAKE_PSTR_WORD(timer)
|
||||
MAKE_PSTR_WORD(alert)
|
||||
MAKE_PSTR(shower_timer_fmt, "Shower Timer is %s")
|
||||
MAKE_PSTR(shower_alert_fmt, "Shower Alert is %s")
|
||||
|
||||
namespace emsesp {
|
||||
|
||||
REGISTER_FACTORY(Boiler, EMSdevice::DeviceType::BOILER)
|
||||
MAKE_PSTR(logger_name, "boiler")
|
||||
uuid::log::Logger Boiler::logger_{F_(logger_name), uuid::log::Facility::CONSOLE};
|
||||
|
||||
uuid::log::Logger Boiler::logger_{F_(boiler), uuid::log::Facility::CONSOLE};
|
||||
|
||||
Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
LOG_DEBUG(F("Registering new Boiler with device ID 0x%02X"), device_id);
|
||||
this->reserve_mem(20); // reserve some space for the telegram registries, to avoid memory fragmentation
|
||||
|
||||
LOG_DEBUG(F("Adding new Boiler with device ID 0x%02X"), device_id);
|
||||
|
||||
// the telegram handlers...
|
||||
register_telegram_type(0x10, F("UBAErrorMessage1"), false, std::bind(&Boiler::process_UBAErrorMessage, this, _1));
|
||||
register_telegram_type(0x11, F("UBAErrorMessage2"), false, std::bind(&Boiler::process_UBAErrorMessage, this, _1));
|
||||
register_telegram_type(0x18, F("UBAMonitorFast"), false, std::bind(&Boiler::process_UBAMonitorFast, this, _1));
|
||||
register_telegram_type(0x19, F("UBAMonitorSlow"), true, std::bind(&Boiler::process_UBAMonitorSlow, this, _1));
|
||||
register_telegram_type(0x34, F("UBAMonitorWW"), false, std::bind(&Boiler::process_UBAMonitorWW, this, _1));
|
||||
register_telegram_type(0x1C, F("UBAMaintenanceStatus"), false, std::bind(&Boiler::process_UBAMaintenanceStatus, this, _1));
|
||||
register_telegram_type(0x2A, F("MC10Status"), false, std::bind(&Boiler::process_MC10Status, this, _1));
|
||||
register_telegram_type(0x33, F("UBAParameterWW"), true, std::bind(&Boiler::process_UBAParameterWW, this, _1));
|
||||
register_telegram_type(0x14, F("UBATotalUptime"), false, std::bind(&Boiler::process_UBATotalUptime, this, _1));
|
||||
register_telegram_type(0x35, F("UBAFlags"), false, std::bind(&Boiler::process_UBAFlags, this, _1));
|
||||
register_telegram_type(0x15, F("UBAMaintenanceData"), false, std::bind(&Boiler::process_UBAMaintenanceData, this, _1));
|
||||
register_telegram_type(0x16, F("UBAParameters"), true, std::bind(&Boiler::process_UBAParameters, this, _1));
|
||||
register_telegram_type(0x1A, F("UBASetPoints"), false, std::bind(&Boiler::process_UBASetPoints, this, _1));
|
||||
register_telegram_type(0xD1, F("UBAOutdoorTemp"), false, std::bind(&Boiler::process_UBAOutdoorTemp, this, _1));
|
||||
register_telegram_type(0xE3, F("UBAMonitorSlowPlus"), false, std::bind(&Boiler::process_UBAMonitorSlowPlus2, this, _1));
|
||||
register_telegram_type(0xE4, F("UBAMonitorFastPlus"), false, std::bind(&Boiler::process_UBAMonitorFastPlus, this, _1));
|
||||
register_telegram_type(0xE5, F("UBAMonitorSlowPlus"), false, std::bind(&Boiler::process_UBAMonitorSlowPlus, this, _1));
|
||||
register_telegram_type(0x10, F("UBAErrorMessage1"), false, [&](std::shared_ptr<const Telegram> t) { process_UBAErrorMessage(t); });
|
||||
register_telegram_type(0x11, F("UBAErrorMessage2"), false, [&](std::shared_ptr<const Telegram> t) { process_UBAErrorMessage(t); });
|
||||
register_telegram_type(0x18, F("UBAMonitorFast"), false, [&](std::shared_ptr<const Telegram> t) { process_UBAMonitorFast(t); });
|
||||
register_telegram_type(0x19, F("UBAMonitorSlow"), true, [&](std::shared_ptr<const Telegram> t) { process_UBAMonitorSlow(t); });
|
||||
register_telegram_type(0x34, F("UBAMonitorWW"), false, [&](std::shared_ptr<const Telegram> t) { process_UBAMonitorWW(t); });
|
||||
register_telegram_type(0x1C, F("UBAMaintenanceStatus"), false, [&](std::shared_ptr<const Telegram> t) { process_UBAMaintenanceStatus(t); });
|
||||
register_telegram_type(0x2A, F("MC10Status"), false, [&](std::shared_ptr<const Telegram> t) { process_MC10Status(t); });
|
||||
register_telegram_type(0x33, F("UBAParameterWW"), true, [&](std::shared_ptr<const Telegram> t) { process_UBAParameterWW(t); });
|
||||
register_telegram_type(0x14, F("UBATotalUptime"), false, [&](std::shared_ptr<const Telegram> t) { process_UBATotalUptime(t); });
|
||||
register_telegram_type(0x35, F("UBAFlags"), false, [&](std::shared_ptr<const Telegram> t) { process_UBAFlags(t); });
|
||||
register_telegram_type(0x15, F("UBAMaintenanceData"), false, [&](std::shared_ptr<const Telegram> t) { process_UBAMaintenanceData(t); });
|
||||
register_telegram_type(0x16, F("UBAParameters"), true, [&](std::shared_ptr<const Telegram> t) { process_UBAParameters(t); });
|
||||
register_telegram_type(0x1A, F("UBASetPoints"), false, [&](std::shared_ptr<const Telegram> t) { process_UBASetPoints(t); });
|
||||
register_telegram_type(0xD1, F("UBAOutdoorTemp"), false, [&](std::shared_ptr<const Telegram> t) { process_UBAOutdoorTemp(t); });
|
||||
register_telegram_type(0xE3, F("UBAMonitorSlowPlus"), false, [&](std::shared_ptr<const Telegram> t) { process_UBAMonitorSlowPlus2(t); });
|
||||
register_telegram_type(0xE4, F("UBAMonitorFastPlus"), false, [&](std::shared_ptr<const Telegram> t) { process_UBAMonitorFastPlus(t); });
|
||||
register_telegram_type(0xE5, F("UBAMonitorSlowPlus"), false, [&](std::shared_ptr<const Telegram> t) { process_UBAMonitorSlowPlus(t); });
|
||||
register_telegram_type(0xE9, F("UBADHWStatus"), false, [&](std::shared_ptr<const Telegram> t) { process_UBADHWStatus(t); });
|
||||
|
||||
register_telegram_type(0xE9, F("UBADHWStatus"), false, std::bind(&Boiler::process_UBADHWStatus, this, _1));
|
||||
|
||||
// MQTT callbacks
|
||||
register_mqtt_topic("boiler_cmd", std::bind(&Boiler::boiler_cmd, this, _1));
|
||||
register_mqtt_topic("boiler_cmd_wwactivated", std::bind(&Boiler::boiler_cmd_wwactivated, this, _1));
|
||||
register_mqtt_topic("boiler_cmd_wwonetime", std::bind(&Boiler::boiler_cmd_wwonetime, this, _1));
|
||||
register_mqtt_topic("boiler_cmd_wwcirculation", std::bind(&Boiler::boiler_cmd_wwcirculation, this, _1));
|
||||
register_mqtt_topic("boiler_cmd_wwtemp", std::bind(&Boiler::boiler_cmd_wwtemp, this, _1));
|
||||
// MQTT commands for boiler_cmd topic
|
||||
register_mqtt_cmd(F("comfort"), [&](const char * value, const int8_t id) { set_warmwater_mode(value, id); });
|
||||
register_mqtt_cmd(F("wwactivated"), [&](const char * value, const int8_t id) { set_warmwater_activated(value, id); });
|
||||
register_mqtt_cmd(F("wwtapactivated"), [&](const char * value, const int8_t id) { set_tapwarmwater_activated(value, id); });
|
||||
register_mqtt_cmd(F("wwonetime"), [&](const char * value, const int8_t id) { set_warmwater_onetime(value, id); });
|
||||
register_mqtt_cmd(F("wwcirculation"), [&](const char * value, const int8_t id) { set_warmwater_circulation(value, id); });
|
||||
register_mqtt_cmd(F("flowtemp"), [&](const char * value, const int8_t id) { set_flow_temp(value, id); });
|
||||
register_mqtt_cmd(F("wwtemp"), [&](const char * value, const int8_t id) { set_warmwater_temp(value, id); });
|
||||
register_mqtt_cmd(F("burnmaxpower"), [&](const char * value, const int8_t id) { set_max_power(value, id); });
|
||||
register_mqtt_cmd(F("burnminpower"), [&](const char * value, const int8_t id) { set_min_power(value, id); });
|
||||
register_mqtt_cmd(F("boilhyston"), [&](const char * value, const int8_t id) { set_hyst_on(value, id); });
|
||||
register_mqtt_cmd(F("boilhystoff"), [&](const char * value, const int8_t id) { set_hyst_off(value, id); });
|
||||
register_mqtt_cmd(F("burnperiod"), [&](const char * value, const int8_t id) { set_burn_period(value, id); });
|
||||
register_mqtt_cmd(F("pumpdelay"), [&](const char * value, const int8_t id) { set_pump_delay(value, id); });
|
||||
}
|
||||
|
||||
// add submenu context
|
||||
@@ -86,166 +73,24 @@ void Boiler::add_context_menu() {
|
||||
flash_string_vector{F_(boiler)},
|
||||
[&](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) {
|
||||
Boiler::console_commands(shell, ShellContext::BOILER);
|
||||
add_context_commands(ShellContext::BOILER);
|
||||
});
|
||||
}
|
||||
|
||||
// boiler_cmd topic
|
||||
void Boiler::boiler_cmd(const char * message) {
|
||||
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_SMALL> doc;
|
||||
DeserializationError error = deserializeJson(doc, message);
|
||||
if (error) {
|
||||
LOG_DEBUG(F("MQTT error: payload %s, error %s"), message, error.c_str());
|
||||
return;
|
||||
}
|
||||
if (nullptr != doc["flowtemp"]) {
|
||||
uint8_t t = doc["flowtemp"];
|
||||
set_flow_temp(t);
|
||||
}
|
||||
if (nullptr != doc["wwtemp"]) {
|
||||
uint8_t t = doc["wwtemp"];
|
||||
set_warmwater_temp(t);
|
||||
}
|
||||
if (nullptr != doc["boilhyston"]) {
|
||||
int8_t t = doc["boilhyston"];
|
||||
set_hyst_on(t);
|
||||
}
|
||||
if (nullptr != doc["boilhystoff"]) {
|
||||
uint8_t t = doc["boilhystoff"];
|
||||
set_hyst_off(t);
|
||||
}
|
||||
if (nullptr != doc["burnperiod"]) {
|
||||
uint8_t t = doc["burnperiod"];
|
||||
set_burn_period(t);
|
||||
}
|
||||
if (nullptr != doc["burnminpower"]) {
|
||||
uint8_t p = doc["burnminpower"];
|
||||
set_min_power(p);
|
||||
}
|
||||
if (nullptr != doc["burnmaxpower"]) {
|
||||
uint8_t p = doc["burnmaxpower"];
|
||||
set_max_power(p);
|
||||
}
|
||||
if (nullptr != doc["pumpdelay"]) {
|
||||
uint8_t t = doc["pumpdelay"];
|
||||
set_pump_delay(t);
|
||||
}
|
||||
|
||||
if (nullptr != doc["comfort"]) {
|
||||
const char * data = doc["comfort"];
|
||||
if (strcmp((char *)data, "hot") == 0) {
|
||||
set_warmwater_mode(1);
|
||||
} else if (strcmp((char *)data, "eco") == 0) {
|
||||
set_warmwater_mode(2);
|
||||
} else if (strcmp((char *)data, "intelligent") == 0) {
|
||||
set_warmwater_mode(3);
|
||||
}
|
||||
}
|
||||
|
||||
const char * command = doc["cmd"];
|
||||
if (command == nullptr || doc["data"] == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
// boiler ww comfort setting
|
||||
if (strcmp(command, "comfort") == 0) {
|
||||
const char * data = doc["data"];
|
||||
if (strcmp((char *)data, "hot") == 0) {
|
||||
set_warmwater_mode(1);
|
||||
} else if (strcmp((char *)data, "eco") == 0) {
|
||||
set_warmwater_mode(2);
|
||||
} else if (strcmp((char *)data, "intelligent") == 0) {
|
||||
set_warmwater_mode(3);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// boiler flowtemp setting
|
||||
if (strcmp(command, "flowtemp") == 0) {
|
||||
uint8_t t = doc["data"];
|
||||
set_flow_temp(t);
|
||||
return;
|
||||
}
|
||||
if (strcmp(command, "wwtemp") == 0) {
|
||||
uint8_t t = doc["data"];
|
||||
set_warmwater_temp(t);
|
||||
return;
|
||||
}
|
||||
// boiler max power setting
|
||||
if (strcmp(command, "burnmaxpower") == 0) {
|
||||
uint8_t p = doc["data"];
|
||||
set_max_power(p);
|
||||
return;
|
||||
}
|
||||
|
||||
// boiler min power setting
|
||||
if (strcmp(command, "burnminpower") == 0) {
|
||||
uint8_t p = doc["data"];
|
||||
set_min_power(p);
|
||||
return;
|
||||
}
|
||||
if (strcmp(command, "boilhyston") == 0) {
|
||||
int8_t t = doc["data"];
|
||||
set_hyst_on(t);
|
||||
return;
|
||||
}
|
||||
if (strcmp(command, "boilhystoff") == 0) {
|
||||
uint8_t t = doc["data"];
|
||||
set_hyst_off(t);
|
||||
return;
|
||||
}
|
||||
if (strcmp(command, "burnperiod") == 0) {
|
||||
uint8_t t = doc["data"];
|
||||
set_burn_period(t);
|
||||
return;
|
||||
}
|
||||
if (strcmp(command, "pumpdelay") == 0) {
|
||||
uint8_t t = doc["data"];
|
||||
set_pump_delay(t);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Boiler::boiler_cmd_wwactivated(const char * message) {
|
||||
if ((message[0] == '1' || strcmp(message, "on") == 0) || (strcmp(message, "auto") == 0)) {
|
||||
set_warmwater_activated(true);
|
||||
} else if (message[0] == '0' || strcmp(message, "off") == 0) {
|
||||
set_warmwater_activated(false);
|
||||
}
|
||||
}
|
||||
|
||||
void Boiler::boiler_cmd_wwonetime(const char * message) {
|
||||
if (message[0] == '1' || strcmp(message, "on") == 0) {
|
||||
set_warmwater_onetime(true);
|
||||
} else if (message[0] == '0' || strcmp(message, "off") == 0) {
|
||||
set_warmwater_onetime(false);
|
||||
}
|
||||
}
|
||||
|
||||
void Boiler::boiler_cmd_wwcirculation(const char * message) {
|
||||
if (message[0] == '1' || strcmp(message, "on") == 0) {
|
||||
set_warmwater_circulation(true);
|
||||
} else if (message[0] == '0' || strcmp(message, "off") == 0) {
|
||||
set_warmwater_circulation(false);
|
||||
}
|
||||
}
|
||||
|
||||
void Boiler::boiler_cmd_wwtemp(const char * message) {
|
||||
uint8_t t = atoi((char *)message);
|
||||
if (t) {
|
||||
set_warmwater_temp(t);
|
||||
}
|
||||
}
|
||||
|
||||
void Boiler::device_info(JsonArray & root) {
|
||||
JsonObject dataElement;
|
||||
|
||||
dataElement = root.createNestedObject();
|
||||
dataElement["name"] = F("Hot tap water");
|
||||
dataElement["value"] = tap_water_active_ ? F("running") : F("off");
|
||||
if (Helpers::hasValue(tap_water_active_, EMS_VALUE_BOOL)) {
|
||||
dataElement = root.createNestedObject();
|
||||
dataElement["name"] = F("Hot tap water");
|
||||
dataElement["value"] = tap_water_active_ ? F("running") : F("off");
|
||||
}
|
||||
|
||||
dataElement = root.createNestedObject();
|
||||
dataElement["name"] = F("Central heating");
|
||||
dataElement["value"] = heating_active_ ? F("active") : F("off");
|
||||
if (Helpers::hasValue(heating_active_, EMS_VALUE_BOOL)) {
|
||||
dataElement = root.createNestedObject();
|
||||
dataElement["name"] = F("Central heating");
|
||||
dataElement["value"] = heating_active_ ? F("active") : F("off");
|
||||
}
|
||||
|
||||
render_value_json(root, "", F("Selected flow temperature"), selFlowTemp_, F_(degrees));
|
||||
render_value_json(root, "", F("Current flow temperature"), curFlowTemp_, F_(degrees), 10);
|
||||
@@ -256,8 +101,9 @@ void Boiler::device_info(JsonArray & root) {
|
||||
|
||||
// publish values via MQTT
|
||||
void Boiler::publish_values() {
|
||||
const size_t capacity = JSON_OBJECT_SIZE(56); // must recalculate if more objects addded https://arduinojson.org/v6/assistant/
|
||||
DynamicJsonDocument doc(capacity);
|
||||
// const size_t capacity = JSON_OBJECT_SIZE(56); // must recalculate if more objects addded https://arduinojson.org/v6/assistant/
|
||||
// DynamicJsonDocument doc(capacity);
|
||||
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_LARGE> doc;
|
||||
|
||||
char s[10]; // for formatting strings
|
||||
|
||||
@@ -295,16 +141,16 @@ void Boiler::publish_values() {
|
||||
if (Helpers::hasValue(pumpMod2_)) {
|
||||
doc["pumpMod2"] = pumpMod2_;
|
||||
}
|
||||
if (Helpers::hasValue(wWCircPump_, VALUE_BOOL)) {
|
||||
if (Helpers::hasValue(wWCircPump_, EMS_VALUE_BOOL)) {
|
||||
doc["wWCircPump"] = Helpers::render_value(s, wWCircPump_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(wWCircPumpType_, VALUE_BOOL)) {
|
||||
if (Helpers::hasValue(wWCircPumpType_, EMS_VALUE_BOOL)) {
|
||||
doc["wWCiPuType"] = wWCircPumpType_ ? "valve" : "pump";
|
||||
}
|
||||
if (Helpers::hasValue(wWCircPumpMode_)) {
|
||||
doc["wWCiPuMode"] = wWCircPumpMode_;
|
||||
}
|
||||
if (Helpers::hasValue(wWCirc_, VALUE_BOOL)) {
|
||||
if (Helpers::hasValue(wWCirc_, EMS_VALUE_BOOL)) {
|
||||
doc["wWCirc"] = Helpers::render_value(s, wWCirc_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(extTemp_)) {
|
||||
@@ -340,43 +186,43 @@ void Boiler::publish_values() {
|
||||
if (Helpers::hasValue(exhaustTemp_)) {
|
||||
doc["exhaustTemp"] = (float)exhaustTemp_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(wWActivated_, VALUE_BOOL)) {
|
||||
if (Helpers::hasValue(wWActivated_, EMS_VALUE_BOOL)) {
|
||||
doc["wWActivated"] = Helpers::render_value(s, wWActivated_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(wWOneTime_, VALUE_BOOL)) {
|
||||
if (Helpers::hasValue(wWOneTime_, EMS_VALUE_BOOL)) {
|
||||
doc["wWOnetime"] = Helpers::render_value(s, wWOneTime_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(wWDesinfecting_, VALUE_BOOL)) {
|
||||
if (Helpers::hasValue(wWDesinfecting_, EMS_VALUE_BOOL)) {
|
||||
doc["wWDesinfecting"] = Helpers::render_value(s, wWDesinfecting_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(wWReadiness_, VALUE_BOOL)) {
|
||||
if (Helpers::hasValue(wWReadiness_, EMS_VALUE_BOOL)) {
|
||||
doc["wWReady"] = Helpers::render_value(s, wWReadiness_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(wWRecharging_, VALUE_BOOL)) {
|
||||
if (Helpers::hasValue(wWRecharging_, EMS_VALUE_BOOL)) {
|
||||
doc["wWRecharge"] = Helpers::render_value(s, wWRecharging_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(wWTemperatureOK_, VALUE_BOOL)) {
|
||||
if (Helpers::hasValue(wWTemperatureOK_, EMS_VALUE_BOOL)) {
|
||||
doc["wWTempOK"] = Helpers::render_value(s, wWTemperatureOK_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(wWCirc_, VALUE_BOOL)) {
|
||||
if (Helpers::hasValue(wWCirc_, EMS_VALUE_BOOL)) {
|
||||
doc["wWCirc"] = Helpers::render_value(s, wWCirc_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(burnGas_, VALUE_BOOL)) {
|
||||
if (Helpers::hasValue(burnGas_, EMS_VALUE_BOOL)) {
|
||||
doc["burnGas"] = Helpers::render_value(s, burnGas_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(flameCurr_)) {
|
||||
doc["flameCurr"] = (float)(int16_t)flameCurr_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(heatPmp_, VALUE_BOOL)) {
|
||||
if (Helpers::hasValue(heatPmp_, EMS_VALUE_BOOL)) {
|
||||
doc["heatPump"] = Helpers::render_value(s, heatPmp_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(fanWork_, VALUE_BOOL)) {
|
||||
if (Helpers::hasValue(fanWork_, EMS_VALUE_BOOL)) {
|
||||
doc["fanWork"] = Helpers::render_value(s, fanWork_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(ignWork_, VALUE_BOOL)) {
|
||||
if (Helpers::hasValue(ignWork_, EMS_VALUE_BOOL)) {
|
||||
doc["ignWork"] = Helpers::render_value(s, ignWork_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(wWHeat_, VALUE_BOOL)) {
|
||||
if (Helpers::hasValue(wWHeat_, EMS_VALUE_BOOL)) {
|
||||
doc["wWHeat"] = Helpers::render_value(s, wWHeat_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(heating_temp_)) {
|
||||
@@ -450,16 +296,16 @@ bool Boiler::updated_values() {
|
||||
void Boiler::show_values(uuid::console::Shell & shell) {
|
||||
EMSdevice::show_values(shell); // for showing the header
|
||||
|
||||
if (Helpers::hasValue(tap_water_active_, VALUE_BOOL)) {
|
||||
if (Helpers::hasValue(tap_water_active_, EMS_VALUE_BOOL)) {
|
||||
print_value(shell, 2, F("Hot tap water"), tap_water_active_ ? F("running") : F("off"));
|
||||
}
|
||||
|
||||
if (Helpers::hasValue(heating_active_, VALUE_BOOL)) {
|
||||
if (Helpers::hasValue(heating_active_, EMS_VALUE_BOOL)) {
|
||||
print_value(shell, 2, F("Central heating"), heating_active_ ? F("active") : F("off"));
|
||||
}
|
||||
|
||||
print_value(shell, 2, F("Warm Water activated"), wWActivated_, nullptr, EMS_VALUE_BOOL);
|
||||
if (Helpers::hasValue(wWCircPumpType_, VALUE_BOOL)) {
|
||||
if (Helpers::hasValue(wWCircPumpType_, EMS_VALUE_BOOL)) {
|
||||
print_value(shell, 2, F("Warm Water charging type"), wWCircPumpType_ ? F("3-way valve") : F("charge pump"));
|
||||
}
|
||||
print_value(shell, 2, F("Warm Water circulation pump available"), wWCircPump_, nullptr, EMS_VALUE_BOOL);
|
||||
@@ -557,6 +403,8 @@ void Boiler::show_values(uuid::console::Shell & shell) {
|
||||
if (Helpers::hasValue(UBAuptime_)) {
|
||||
shell.printfln(F(" Total UBA working time: %d days %d hours %d minutes"), UBAuptime_ / 1440, (UBAuptime_ % 1440) / 60, UBAuptime_ % 60);
|
||||
}
|
||||
|
||||
shell.println();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -579,7 +427,7 @@ void Boiler::check_active() {
|
||||
|
||||
// see if the heating or hot tap water has changed, if so send
|
||||
// last_boilerActive stores heating in bit 1 and tap water in bit 2
|
||||
if (Helpers::hasValue(tap_water_active_, VALUE_BOOL) && Helpers::hasValue(heating_active_, VALUE_BOOL)) {
|
||||
if (Helpers::hasValue(tap_water_active_, EMS_VALUE_BOOL) && Helpers::hasValue(heating_active_, EMS_VALUE_BOOL)) {
|
||||
uint8_t latest_boilerState = (tap_water_active_ << 1) + heating_active_;
|
||||
if (latest_boilerState != last_boilerState) {
|
||||
last_boilerState = latest_boilerState;
|
||||
@@ -650,12 +498,12 @@ void Boiler::process_UBATotalUptime(std::shared_ptr<const Telegram> telegram) {
|
||||
*/
|
||||
void Boiler::process_UBAParameters(std::shared_ptr<const Telegram> telegram) {
|
||||
telegram->read_value(heating_temp_, 1);
|
||||
telegram->read_value(burnPowermax_,2);
|
||||
telegram->read_value(burnPowermin_,3);
|
||||
telegram->read_value(boilTemp_off_,4);
|
||||
telegram->read_value(boilTemp_on_,5);
|
||||
telegram->read_value(burnPeriod_,6);
|
||||
telegram->read_value(pumpDelay_,8);
|
||||
telegram->read_value(burnPowermax_, 2);
|
||||
telegram->read_value(burnPowermin_, 3);
|
||||
telegram->read_value(boilTemp_off_, 4);
|
||||
telegram->read_value(boilTemp_on_, 5);
|
||||
telegram->read_value(burnPeriod_, 6);
|
||||
telegram->read_value(pumpDelay_, 8);
|
||||
telegram->read_value(pump_mod_max_, 9);
|
||||
telegram->read_value(pump_mod_min_, 10);
|
||||
}
|
||||
@@ -804,7 +652,7 @@ void Boiler::process_UBAMaintenanceStatus(std::shared_ptr<const Telegram> telegr
|
||||
// 0x10, 0x11, 0x12
|
||||
// not yet implemented
|
||||
void Boiler::process_UBAErrorMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
// data: displaycode(2), errornumner(2), year, month, hour, day, minute, duration(2), src-addr
|
||||
// data: displaycode(2), errornumber(2), year, month, hour, day, minute, duration(2), src-addr
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
@@ -818,67 +666,113 @@ void Boiler::process_UBAMaintenanceData(std::shared_ptr<const Telegram> telegram
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Commands
|
||||
*/
|
||||
|
||||
|
||||
// Set the warm water temperature 0x33
|
||||
void Boiler::set_warmwater_temp(const uint8_t temperature) {
|
||||
LOG_INFO(F("Setting boiler warm water temperature to %d C"), temperature);
|
||||
write_command(EMS_TYPE_UBAParameterWW, 2, temperature);
|
||||
write_command(EMS_TYPE_UBAFlags, 3, temperature); // for i9000, see #397
|
||||
void Boiler::set_warmwater_temp(const char * value, const int8_t id) {
|
||||
int v = 0;
|
||||
if (!Helpers::value2number(value, v)) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO(F("Setting boiler warm water temperature to %d C"), v);
|
||||
write_command(EMS_TYPE_UBAParameterWW, 2, v);
|
||||
write_command(EMS_TYPE_UBAFlags, 3, v); // for i9000, see #397
|
||||
}
|
||||
|
||||
// flow temp
|
||||
void Boiler::set_flow_temp(const uint8_t temperature) {
|
||||
LOG_INFO(F("Setting boiler flow temperature to %d C"), temperature);
|
||||
write_command(EMS_TYPE_UBASetPoints, 0, temperature);
|
||||
void Boiler::set_flow_temp(const char * value, const int8_t id) {
|
||||
int v = 0;
|
||||
if (!Helpers::value2number(value, v)) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO(F("Setting boiler flow temperature to %d C"), v);
|
||||
write_command(EMS_TYPE_UBASetPoints, 0, v);
|
||||
}
|
||||
|
||||
// set min boiler output
|
||||
void Boiler::set_min_power(const uint8_t power) {
|
||||
LOG_INFO(F("Setting boiler min power to "), power);
|
||||
write_command(EMS_TYPE_UBAParameters, 3, power);
|
||||
void Boiler::set_min_power(const char * value, const int8_t id) {
|
||||
int v = 0;
|
||||
if (!Helpers::value2number(value, v)) {
|
||||
return;
|
||||
}
|
||||
LOG_INFO(F("Setting boiler min power to "), v);
|
||||
write_command(EMS_TYPE_UBAParameters, 3, v);
|
||||
}
|
||||
|
||||
// set max temp
|
||||
void Boiler::set_max_power(const uint8_t power) {
|
||||
LOG_INFO(F("Setting boiler max power to %d C"), power);
|
||||
write_command(EMS_TYPE_UBAParameters, 2, power);
|
||||
void Boiler::set_max_power(const char * value, const int8_t id) {
|
||||
int v = 0;
|
||||
if (!Helpers::value2number(value, v)) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO(F("Setting boiler max power to %d C"), v);
|
||||
write_command(EMS_TYPE_UBAParameters, 2, v);
|
||||
}
|
||||
|
||||
// set oiler on hysteresis
|
||||
void Boiler::set_hyst_on(const uint8_t temp) {
|
||||
LOG_INFO(F("Setting boiler hysteresis on to %d C"), temp);
|
||||
write_command(EMS_TYPE_UBAParameters, 5, temp);
|
||||
void Boiler::set_hyst_on(const char * value, const int8_t id) {
|
||||
int v = 0;
|
||||
if (!Helpers::value2number(value, v)) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO(F("Setting boiler hysteresis on to %d C"), v);
|
||||
write_command(EMS_TYPE_UBAParameters, 5, v);
|
||||
}
|
||||
|
||||
// set boiler off hysteresis
|
||||
void Boiler::set_hyst_off(const uint8_t temp) {
|
||||
LOG_INFO(F("Setting boiler hysteresis off to %d C"), temp);
|
||||
write_command(EMS_TYPE_UBAParameters, 4, temp);
|
||||
void Boiler::set_hyst_off(const char * value, const int8_t id) {
|
||||
int v = 0;
|
||||
if (!Helpers::value2number(value, v)) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO(F("Setting boiler hysteresis off to %d C"), v);
|
||||
write_command(EMS_TYPE_UBAParameters, 4, v);
|
||||
}
|
||||
|
||||
// set min burner period
|
||||
void Boiler::set_burn_period(const uint8_t t) {
|
||||
LOG_INFO(F("Setting burner min. period to %d min"), t);
|
||||
write_command(EMS_TYPE_UBAParameters, 6, t);
|
||||
void Boiler::set_burn_period(const char * value, const int8_t id) {
|
||||
int v = 0;
|
||||
if (!Helpers::value2number(value, v)) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO(F("Setting burner min. period to %d min"), v);
|
||||
write_command(EMS_TYPE_UBAParameters, 6, v);
|
||||
}
|
||||
|
||||
// set pump delay
|
||||
void Boiler::set_pump_delay(const uint8_t t) {
|
||||
LOG_INFO(F("Setting boiler pump delay to %d min"), t);
|
||||
write_command(EMS_TYPE_UBAParameters, 8, t);
|
||||
void Boiler::set_pump_delay(const char * value, const int8_t id) {
|
||||
int v = 0;
|
||||
if (!Helpers::value2number(value, v)) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO(F("Setting boiler pump delay to %d min"), v);
|
||||
write_command(EMS_TYPE_UBAParameters, 8, v);
|
||||
}
|
||||
|
||||
// 1=hot, 2=eco, 3=intelligent
|
||||
// note some boilers do not have this setting, than it's done by thermostat
|
||||
// on a RC35 it's by EMSESP::send_write_request(0x37, 0x10, 2, &set, 1, 0); (set is 1,2,3)
|
||||
void Boiler::set_warmwater_mode(const uint8_t comfort) {
|
||||
// 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
|
||||
void Boiler::set_warmwater_mode(const char * value, const int8_t id) {
|
||||
if (value == nullptr) {
|
||||
return;
|
||||
}
|
||||
uint8_t set;
|
||||
if (comfort == 1) {
|
||||
if (strcmp(value, "hot") == 0) {
|
||||
LOG_INFO(F("Setting boiler warm water to Hot"));
|
||||
set = 0x00;
|
||||
} else if (comfort == 2) {
|
||||
} else if (strcmp(value, "eco") == 0) {
|
||||
LOG_INFO(F("Setting boiler warm water to Eco"));
|
||||
set = 0xD8;
|
||||
} else if (comfort == 3) {
|
||||
} else if (strcmp(value, "intelligent") == 0) {
|
||||
LOG_INFO(F("Setting boiler warm water to Intelligent"));
|
||||
set = 0xEC;
|
||||
} else {
|
||||
@@ -888,24 +782,33 @@ void Boiler::set_warmwater_mode(const uint8_t comfort) {
|
||||
}
|
||||
|
||||
// turn on/off warm water
|
||||
void Boiler::set_warmwater_activated(const bool activated) {
|
||||
LOG_INFO(F("Setting boiler warm water %s"), activated ? "on" : "off");
|
||||
uint8_t value;
|
||||
void Boiler::set_warmwater_activated(const char * value, const int8_t id) {
|
||||
bool v = false;
|
||||
if (!Helpers::value2bool(value, v)) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO(F("Setting boiler warm water %s"), v ? "on" : "off");
|
||||
|
||||
// https://github.com/proddy/EMS-ESP/issues/268
|
||||
uint8_t n;
|
||||
if (EMSbus::is_ht3()) {
|
||||
value = (activated ? 0x08 : 0x00); // 0x08 is on, 0x00 is off
|
||||
n = (v ? 0x08 : 0x00); // 0x08 is on, 0x00 is off
|
||||
} else {
|
||||
value = (activated ? 0xFF : 0x00); // 0xFF is on, 0x00 is off
|
||||
n = (v ? 0xFF : 0x00); // 0xFF is on, 0x00 is off
|
||||
}
|
||||
write_command(EMS_TYPE_UBAParameterWW, 1, value);
|
||||
write_command(EMS_TYPE_UBAParameterWW, 1, n);
|
||||
}
|
||||
|
||||
// Activate / De-activate the Warm Tap Water
|
||||
// true = on, false = off
|
||||
// Note: Using the type 0x1D to put the boiler into Test mode. This may be shown on the boiler with a flashing 'T'
|
||||
void Boiler::set_tapwarmwater_activated(const bool activated) {
|
||||
LOG_INFO(F("Setting boiler warm tap water %s"), activated ? "on" : "off");
|
||||
void Boiler::set_tapwarmwater_activated(const char * value, const int8_t id) {
|
||||
bool v = false;
|
||||
if (!Helpers::value2bool(value, v)) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO(F("Setting tap warm tap water %s"), v ? "on" : "off");
|
||||
uint8_t message_data[EMS_MAX_TELEGRAM_MESSAGE_LENGTH];
|
||||
for (uint8_t i = 0; i < sizeof(message_data); i++) {
|
||||
message_data[i] = 0x00;
|
||||
@@ -914,7 +817,7 @@ void Boiler::set_tapwarmwater_activated(const bool activated) {
|
||||
// we use the special test mode 0x1D for this. Setting the first data to 5A puts the system into test mode and
|
||||
// a setting of 0x00 puts it back into normal operating mode
|
||||
// when in test mode we're able to mess around with the 3-way valve settings
|
||||
if (!activated) {
|
||||
if (!v) {
|
||||
// on
|
||||
message_data[0] = 0x5A; // test mode on
|
||||
message_data[1] = 0x00; // burner output 0%
|
||||
@@ -932,16 +835,26 @@ void Boiler::set_tapwarmwater_activated(const bool activated) {
|
||||
// Activate / De-activate One Time warm water 0x35
|
||||
// true = on, false = off
|
||||
// See also https://github.com/proddy/EMS-ESP/issues/341#issuecomment-596245458 for Junkers
|
||||
void Boiler::set_warmwater_onetime(const bool activated) {
|
||||
LOG_INFO(F("Setting boiler warm water OneTime loading %s"), activated ? "on" : "off");
|
||||
write_command(EMS_TYPE_UBAFlags, 0, (activated ? 0x22 : 0x02));
|
||||
void Boiler::set_warmwater_onetime(const char * value, const int8_t id) {
|
||||
bool v = false;
|
||||
if (!Helpers::value2bool(value, v)) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO(F("Setting boiler warm water OneTime loading %s"), v ? "on" : "off");
|
||||
write_command(EMS_TYPE_UBAFlags, 0, (v ? 0x22 : 0x02));
|
||||
}
|
||||
|
||||
// Activate / De-activate circulation of warm water 0x35
|
||||
// true = on, false = off
|
||||
void Boiler::set_warmwater_circulation(const bool activated) {
|
||||
LOG_INFO(F("Setting boiler warm water circulation %s"), activated ? "on" : "off");
|
||||
write_command(EMS_TYPE_UBAFlags, 1, (activated ? 0x22 : 0x02));
|
||||
void Boiler::set_warmwater_circulation(const char * value, const int8_t id) {
|
||||
bool v = false;
|
||||
if (!Helpers::value2bool(value, v)) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INFO(F("Setting boiler warm water circulation %s"), v ? "on" : "off");
|
||||
write_command(EMS_TYPE_UBAFlags, 1, (v ? 0x22 : 0x02));
|
||||
}
|
||||
|
||||
// add console commands
|
||||
@@ -952,118 +865,10 @@ void Boiler::console_commands(Shell & shell, unsigned int context) {
|
||||
flash_string_vector{F_(typeid_mandatory)},
|
||||
[=](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments) {
|
||||
uint16_t type_id = Helpers::hextoint(arguments.front().c_str());
|
||||
EMSESP::send_read_request(type_id, device_id());
|
||||
EMSESP::set_read_id(type_id);
|
||||
EMSESP::send_read_request(type_id, get_device_id());
|
||||
});
|
||||
|
||||
EMSESPShell::commands->add_command(ShellContext::BOILER,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(wwtemp)},
|
||||
flash_string_vector{F_(degrees_mandatory)},
|
||||
[=](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments) {
|
||||
set_warmwater_temp(Helpers::atoint(arguments.front().c_str()));
|
||||
});
|
||||
|
||||
EMSESPShell::commands->add_command(ShellContext::BOILER,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(flowtemp)},
|
||||
flash_string_vector{F_(degrees_mandatory)},
|
||||
[=](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments) {
|
||||
set_flow_temp(Helpers::atoint(arguments.front().c_str()));
|
||||
});
|
||||
|
||||
EMSESPShell::commands->add_command(ShellContext::BOILER,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(maxpower)},
|
||||
flash_string_vector{F_(n_mandatory)},
|
||||
[=](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments) {
|
||||
set_max_power(Helpers::atoint(arguments.front().c_str()));
|
||||
});
|
||||
|
||||
EMSESPShell::commands->add_command(ShellContext::BOILER,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(minpower)},
|
||||
flash_string_vector{F_(n_mandatory)},
|
||||
[=](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments) {
|
||||
set_min_power(Helpers::atoint(arguments.front().c_str()));
|
||||
});
|
||||
|
||||
EMSESPShell::commands->add_command(
|
||||
ShellContext::BOILER,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(wwactive)},
|
||||
flash_string_vector{F_(bool_mandatory)},
|
||||
[=](Shell & shell, const std::vector<std::string> & arguments) {
|
||||
if (arguments[0] == read_flash_string(F_(on))) {
|
||||
set_warmwater_activated(true);
|
||||
} else if (arguments[0] == read_flash_string(F_(off))) {
|
||||
set_warmwater_activated(false);
|
||||
} else {
|
||||
shell.println(F("Must be on or off"));
|
||||
return;
|
||||
}
|
||||
},
|
||||
[](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments __attribute__((unused))) -> const std::vector<std::string> {
|
||||
return std::vector<std::string>{read_flash_string(F_(on)), read_flash_string(F_(off))};
|
||||
});
|
||||
|
||||
EMSESPShell::commands->add_command(
|
||||
ShellContext::BOILER,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(wwonetime)},
|
||||
flash_string_vector{F_(bool_mandatory)},
|
||||
[=](Shell & shell, const std::vector<std::string> & arguments) {
|
||||
if (arguments[0] == read_flash_string(F_(on))) {
|
||||
set_warmwater_onetime(true);
|
||||
} else if (arguments[0] == read_flash_string(F_(off))) {
|
||||
set_warmwater_onetime(false);
|
||||
} else {
|
||||
shell.println(F("Must be on or off"));
|
||||
return;
|
||||
}
|
||||
},
|
||||
[](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments __attribute__((unused))) -> const std::vector<std::string> {
|
||||
return std::vector<std::string>{read_flash_string(F_(on)), read_flash_string(F_(off))};
|
||||
});
|
||||
|
||||
EMSESPShell::commands->add_command(
|
||||
ShellContext::BOILER,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(wwcirculation)},
|
||||
flash_string_vector{F_(bool_mandatory)},
|
||||
[=](Shell & shell, const std::vector<std::string> & arguments) {
|
||||
if (arguments[0] == read_flash_string(F_(on))) {
|
||||
set_warmwater_circulation(true);
|
||||
} else if (arguments[0] == read_flash_string(F_(off))) {
|
||||
set_warmwater_circulation(false);
|
||||
} else {
|
||||
shell.println(F("Must be on or off"));
|
||||
return;
|
||||
}
|
||||
},
|
||||
[](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments __attribute__((unused))) -> const std::vector<std::string> {
|
||||
return std::vector<std::string>{read_flash_string(F_(on)), read_flash_string(F_(off))};
|
||||
});
|
||||
|
||||
EMSESPShell::commands->add_command(
|
||||
ShellContext::BOILER,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(comfort)},
|
||||
flash_string_vector{F_(comfort_mandatory)},
|
||||
[=](Shell & shell, const std::vector<std::string> & arguments) {
|
||||
if (arguments[0] == read_flash_string(F_(hot))) {
|
||||
set_warmwater_mode(1);
|
||||
} else if (arguments[0] == read_flash_string(F_(eco))) {
|
||||
set_warmwater_mode(2);
|
||||
} else if (arguments[0] == read_flash_string(F_(intelligent))) {
|
||||
set_warmwater_mode(3);
|
||||
} else {
|
||||
shell.println(F("Invalid value. Must be hot, eco or intelligent"));
|
||||
}
|
||||
},
|
||||
[](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments __attribute__((unused))) -> const std::vector<std::string> {
|
||||
return std::vector<std::string>{read_flash_string(F_(hot)), read_flash_string(F_(eco)), read_flash_string(F_(intelligent))};
|
||||
});
|
||||
|
||||
EMSESPShell::commands->add_command(ShellContext::BOILER,
|
||||
CommandFlags::USER,
|
||||
flash_string_vector{F_(show)},
|
||||
|
||||
@@ -124,7 +124,7 @@ class Boiler : public EMSdevice {
|
||||
uint8_t burnPowermin_ = EMS_VALUE_UINT_NOTSET;
|
||||
uint8_t burnPowermax_ = EMS_VALUE_UINT_NOTSET;
|
||||
int8_t boilTemp_off_ = EMS_VALUE_INT_NOTSET;
|
||||
int8_t boilTemp_on_ = EMS_VALUE_UINT_NOTSET;
|
||||
int8_t boilTemp_on_ = EMS_VALUE_INT_NOTSET;
|
||||
uint8_t burnPeriod_ = EMS_VALUE_UINT_NOTSET;
|
||||
uint8_t pumpDelay_ = EMS_VALUE_UINT_NOTSET;
|
||||
|
||||
@@ -160,27 +160,20 @@ class Boiler : public EMSdevice {
|
||||
|
||||
void check_active();
|
||||
|
||||
void set_warmwater_temp(const uint8_t temperature);
|
||||
void set_flow_temp(const uint8_t temperature);
|
||||
void set_warmwater_mode(const uint8_t comfort);
|
||||
void set_warmwater_activated(const bool activated);
|
||||
void set_tapwarmwater_activated(const bool activated);
|
||||
void set_warmwater_onetime(const bool activated);
|
||||
void set_warmwater_circulation(const bool activated);
|
||||
void set_min_power(const uint8_t power);
|
||||
void set_max_power(const uint8_t power);
|
||||
void set_hyst_on(const uint8_t temp);
|
||||
void set_hyst_off(const uint8_t temp);
|
||||
void set_burn_period(const uint8_t t);
|
||||
void set_pump_delay(const uint8_t t);
|
||||
|
||||
|
||||
// mqtt callbacks
|
||||
void boiler_cmd(const char * message);
|
||||
void boiler_cmd_wwactivated(const char * message);
|
||||
void boiler_cmd_wwonetime(const char * message);
|
||||
void boiler_cmd_wwcirculation(const char * message);
|
||||
void boiler_cmd_wwtemp(const char * message);
|
||||
// commands - none of these use the additional id parameter
|
||||
void set_warmwater_mode(const char * value, const int8_t id);
|
||||
void set_warmwater_activated(const char * value, const int8_t id);
|
||||
void set_tapwarmwater_activated(const char * value, const int8_t id);
|
||||
void set_warmwater_onetime(const char * value, const int8_t id);
|
||||
void set_warmwater_circulation(const char * value, const int8_t id);
|
||||
void set_warmwater_temp(const char * value, const int8_t id);
|
||||
void set_flow_temp(const char * value, const int8_t id);
|
||||
void set_min_power(const char * value, const int8_t id);
|
||||
void set_max_power(const char * value, const int8_t id);
|
||||
void set_hyst_on(const char * value, const int8_t id);
|
||||
void set_hyst_off(const char * value, const int8_t id);
|
||||
void set_burn_period(const char * value, const int8_t id);
|
||||
void set_pump_delay(const char * value, const int8_t id);
|
||||
};
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
@@ -22,16 +22,10 @@ namespace emsesp {
|
||||
|
||||
REGISTER_FACTORY(Connect, EMSdevice::DeviceType::CONNECT);
|
||||
|
||||
MAKE_PSTR(logger_name, "connect")
|
||||
uuid::log::Logger Connect::logger_{F_(logger_name), uuid::log::Facility::CONSOLE};
|
||||
uuid::log::Logger Connect::logger_{F_(connect), uuid::log::Facility::CONSOLE};
|
||||
|
||||
Connect::Connect(uint8_t device_type, uint8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
// telegram handlers
|
||||
// register_telegram_type(EMS_TYPE_XX, "XX", false, std::bind(&Controller::process_XX, this, _1));
|
||||
|
||||
// MQTT callbacks
|
||||
// register_mqtt_topic("topic", std::bind(&Connect::cmd, this, _1));
|
||||
}
|
||||
|
||||
void Connect::device_info(JsonArray & root) {
|
||||
@@ -42,7 +36,7 @@ void Connect::add_context_menu() {
|
||||
|
||||
// display all values into the shell console
|
||||
void Connect::show_values(uuid::console::Shell & shell) {
|
||||
EMSdevice::show_values(shell); // always call this to show header
|
||||
// EMSdevice::show_values(shell); // always call this to show header
|
||||
}
|
||||
|
||||
// publish values via MQTT
|
||||
|
||||
@@ -18,22 +18,14 @@
|
||||
|
||||
#include "controller.h"
|
||||
|
||||
// MAKE_PSTR_WORD(controller)
|
||||
|
||||
namespace emsesp {
|
||||
|
||||
REGISTER_FACTORY(Controller, EMSdevice::DeviceType::CONTROLLER);
|
||||
|
||||
MAKE_PSTR(logger_name, "controller")
|
||||
uuid::log::Logger Controller::logger_{F_(logger_name), uuid::log::Facility::CONSOLE};
|
||||
uuid::log::Logger Controller::logger_{F_(controller), uuid::log::Facility::CONSOLE};
|
||||
|
||||
Controller::Controller(uint8_t device_type, uint8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
// telegram handlers
|
||||
// register_telegram_type(EMS_TYPE_XX, "XX", false, std::bind(&Controller::process_XX, this, _1));
|
||||
|
||||
// MQTT callbacks
|
||||
// register_mqtt_topic("topic", std::bind(&Controller::cmd, this, _1));
|
||||
}
|
||||
|
||||
void Controller::add_context_menu() {
|
||||
@@ -44,7 +36,7 @@ void Controller::device_info(JsonArray & root) {
|
||||
|
||||
// display all values into the shell console
|
||||
void Controller::show_values(uuid::console::Shell & shell) {
|
||||
EMSdevice::show_values(shell); // always call this to show header
|
||||
// EMSdevice::show_values(shell); // always call this to show header
|
||||
}
|
||||
|
||||
// publish values via MQTT
|
||||
|
||||
@@ -18,22 +18,14 @@
|
||||
|
||||
#include "gateway.h"
|
||||
|
||||
// MAKE_PSTR_WORD(gateway)
|
||||
|
||||
namespace emsesp {
|
||||
|
||||
REGISTER_FACTORY(Gateway, EMSdevice::DeviceType::GATEWAY);
|
||||
|
||||
MAKE_PSTR(logger_name, "gateway")
|
||||
uuid::log::Logger Gateway::logger_{F_(logger_name), uuid::log::Facility::CONSOLE};
|
||||
uuid::log::Logger Gateway::logger_{F_(gateway), uuid::log::Facility::CONSOLE};
|
||||
|
||||
Gateway::Gateway(uint8_t device_type, uint8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
// telegram handlers
|
||||
// register_telegram_type(EMS_TYPE_XX, "XX", false, std::bind(&Controller::process_XX, this, _1));
|
||||
|
||||
// MQTT callbacks
|
||||
// register_mqtt_topic("topic", std::bind(&Gateway::cmd, this, _1));
|
||||
}
|
||||
|
||||
void Gateway::add_context_menu() {
|
||||
|
||||
@@ -18,32 +18,19 @@
|
||||
|
||||
#include "heatpump.h"
|
||||
|
||||
// MAKE_PSTR_WORD(heatpump)
|
||||
|
||||
/*
|
||||
example telegrams 0x32B, 0x37B
|
||||
"38 10 FF 00 03 7B 08 24 00 4B",
|
||||
"38 10 FF 00 03 2B 00 C7 07 C3 01",
|
||||
"38 10 FF 00 03 2B 00 D1 08 2A 01",
|
||||
*/
|
||||
|
||||
namespace emsesp {
|
||||
|
||||
REGISTER_FACTORY(Heatpump, EMSdevice::DeviceType::HEATPUMP);
|
||||
|
||||
MAKE_PSTR(logger_name, "heatpump")
|
||||
uuid::log::Logger Heatpump::logger_{F_(logger_name), uuid::log::Facility::CONSOLE};
|
||||
uuid::log::Logger Heatpump::logger_{F_(heatpump), uuid::log::Facility::CONSOLE};
|
||||
|
||||
Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
LOG_DEBUG(F("Registering new Heat Pump module with device ID 0x%02X"), device_id);
|
||||
LOG_DEBUG(F("Adding new Heat Pump module with device ID 0x%02X"), device_id);
|
||||
|
||||
// telegram handlers
|
||||
register_telegram_type(0x047B, F("HP1"), true, std::bind(&Heatpump::process_HPMonitor1, this, _1));
|
||||
register_telegram_type(0x042B, F("HP2"), true, std::bind(&Heatpump::process_HPMonitor2, this, _1));
|
||||
|
||||
// MQTT callbacks
|
||||
// register_mqtt_topic("topic", std::bind(&Heatpump::cmd, this, _1));
|
||||
register_telegram_type(0x047B, F("HP1"), true, [&](std::shared_ptr<const Telegram> t) { process_HPMonitor1(t); });
|
||||
register_telegram_type(0x042B, F("HP2"), true, [&](std::shared_ptr<const Telegram> t) { process_HPMonitor2(t); });
|
||||
}
|
||||
|
||||
// context submenu
|
||||
@@ -55,7 +42,7 @@ void Heatpump::device_info(JsonArray & root) {
|
||||
|
||||
// display all values into the shell console
|
||||
void Heatpump::show_values(uuid::console::Shell & shell) {
|
||||
EMSdevice::show_values(shell); // always call this to show header
|
||||
// EMSdevice::show_values(shell); // always call this to show header
|
||||
}
|
||||
|
||||
// publish values via MQTT
|
||||
|
||||
@@ -22,35 +22,37 @@ namespace emsesp {
|
||||
|
||||
REGISTER_FACTORY(Mixing, EMSdevice::DeviceType::MIXING);
|
||||
|
||||
MAKE_PSTR(logger_name, "mixing")
|
||||
uuid::log::Logger Mixing::logger_{F_(logger_name), uuid::log::Facility::CONSOLE};
|
||||
uuid::log::Logger Mixing::logger_{F_(mixing), uuid::log::Facility::CONSOLE};
|
||||
|
||||
Mixing::Mixing(uint8_t device_type, uint8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
LOG_DEBUG(F("Registering new Mixing module with device ID 0x%02X"), device_id);
|
||||
LOG_DEBUG(F("Adding new Mixing module with device ID 0x%02X"), device_id);
|
||||
|
||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) {
|
||||
if (device_id <= 0x27) {
|
||||
// telegram handlers 0x20 - 0x27 for HC
|
||||
register_telegram_type(device_id - 0x20 + 0x02D7, F("MMPLUSStatusMessage_HC"), true, std::bind(&Mixing::process_MMPLUSStatusMessage_HC, this, _1));
|
||||
register_telegram_type(device_id - 0x20 + 0x02D7, F("MMPLUSStatusMessage_HC"), true, [&](std::shared_ptr<const Telegram> t) {
|
||||
process_MMPLUSStatusMessage_HC(t);
|
||||
});
|
||||
} else {
|
||||
// telegram handlers for warm water/DHW 0x28, 0x29
|
||||
register_telegram_type(device_id - 0x28 + 0x0331, F("MMPLUSStatusMessage_WWC"), true, std::bind(&Mixing::process_MMPLUSStatusMessage_WWC, this, _1));
|
||||
register_telegram_type(device_id - 0x28 + 0x0331, F("MMPLUSStatusMessage_WWC"), true, [&](std::shared_ptr<const Telegram> t) {
|
||||
process_MMPLUSStatusMessage_WWC(t);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// EMS 1.0
|
||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_MM10) {
|
||||
register_telegram_type(0x00AA, F("MMConfigMessage"), false, std::bind(&Mixing::process_MMConfigMessage, this, _1));
|
||||
register_telegram_type(0x00AB, F("MMStatusMessage"), true, std::bind(&Mixing::process_MMStatusMessage, this, _1));
|
||||
register_telegram_type(0x00AC, F("MMSetMessage"), false, std::bind(&Mixing::process_MMSetMessage, this, _1));
|
||||
}
|
||||
// HT3
|
||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_IPM) {
|
||||
register_telegram_type(0x010C, F("IPMSetMessage"), false, std::bind(&Mixing::process_IPMStatusMessage, this, _1));
|
||||
register_telegram_type(0x00AA, F("MMConfigMessage"), false, [&](std::shared_ptr<const Telegram> t) { process_MMConfigMessage(t); });
|
||||
register_telegram_type(0x00AB, F("MMStatusMessage"), true, [&](std::shared_ptr<const Telegram> t) { process_MMStatusMessage(t); });
|
||||
register_telegram_type(0x00AC, F("MMSetMessage"), false, [&](std::shared_ptr<const Telegram> t) { process_MMSetMessage(t); });
|
||||
}
|
||||
|
||||
// MQTT callbacks
|
||||
// register_mqtt_topic("topic", std::bind(&Mixing::cmd, this, _1));
|
||||
// HT3
|
||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_IPM) {
|
||||
register_telegram_type(0x010C, F("IPMSetMessage"), false, [&](std::shared_ptr<const Telegram> t) { process_IPMStatusMessage(t); });
|
||||
}
|
||||
}
|
||||
|
||||
// add context submenu
|
||||
@@ -68,11 +70,11 @@ void Mixing::device_info(JsonArray & root) {
|
||||
} else {
|
||||
render_value_json(root, "", F("Heating Circuit"), hc_, nullptr);
|
||||
}
|
||||
|
||||
render_value_json(root, "", F("Current flow temperature"), flowTemp_, F_(degrees), 10);
|
||||
render_value_json(root, "", F("Setpoint flow temperature"), flowSetTemp_, F_(degrees));
|
||||
render_value_json(root, "", F("Current pump modulation"), pumpMod_, F_(percent));
|
||||
render_value_json(root, "", F("Current valve status"), status_, nullptr);
|
||||
|
||||
}
|
||||
|
||||
// check to see if values have been updated
|
||||
@@ -97,16 +99,19 @@ void Mixing::show_values(uuid::console::Shell & shell) {
|
||||
} else {
|
||||
print_value(shell, 2, F("Heating Circuit"), hc_, nullptr);
|
||||
}
|
||||
|
||||
print_value(shell, 4, F("Current flow temperature"), flowTemp_, F_(degrees), 10);
|
||||
print_value(shell, 4, F("Setpoint flow temperature"), flowSetTemp_, F_(degrees));
|
||||
print_value(shell, 4, F("Current pump modulation"), pumpMod_, F_(percent));
|
||||
print_value(shell, 4, F("Current valve status"), status_, nullptr);
|
||||
|
||||
shell.println();
|
||||
}
|
||||
|
||||
// publish values via MQTT
|
||||
// ideally we should group up all the mixing units together into a nested JSON but for now we'll send them individually
|
||||
void Mixing::publish_values() {
|
||||
DynamicJsonDocument doc(EMSESP_MAX_JSON_SIZE_SMALL);
|
||||
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_SMALL> doc;
|
||||
|
||||
switch (type_) {
|
||||
case Type::HC:
|
||||
@@ -139,7 +144,7 @@ void Mixing::publish_values() {
|
||||
char topic[30];
|
||||
char s[3]; // for formatting strings
|
||||
strlcpy(topic, "mixing_data", 30);
|
||||
strlcat(topic, Helpers::itoa(s, device_id() - 0x20 + 1), 30); // append hc to topic
|
||||
strlcat(topic, Helpers::itoa(s, get_device_id() - 0x20 + 1), 30); // append hc to topic
|
||||
Mqtt::publish(topic, doc);
|
||||
}
|
||||
|
||||
@@ -171,7 +176,7 @@ void Mixing::process_MMPLUSStatusMessage_WWC(std::shared_ptr<const Telegram> tel
|
||||
// A1 00 FF 00 00 0C 02 04 00 01 1D 00 82
|
||||
void Mixing::process_IPMStatusMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
type_ = Type::HC;
|
||||
hc_ = device_id() - 0x20 + 1;
|
||||
hc_ = get_device_id() - 0x20 + 1;
|
||||
uint8_t ismixed = 0;
|
||||
telegram->read_value(ismixed, 0); // check if circuit is active, 0-off, 1-unmixed, 2-mixed
|
||||
if (ismixed == 0) {
|
||||
@@ -198,7 +203,7 @@ void Mixing::process_MMStatusMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
// the heating circuit is determine by which device_id it is, 0x20 - 0x23
|
||||
// 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;
|
||||
hc_ = get_device_id() - 0x20 + 1;
|
||||
telegram->read_value(flowTemp_, 1); // is * 10
|
||||
telegram->read_value(pumpMod_, 3);
|
||||
telegram->read_value(flowSetTemp_, 0);
|
||||
@@ -210,7 +215,7 @@ void Mixing::process_MMStatusMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
// Mixing on a MM10 - 0xAA
|
||||
// e.g. Thermostat -> Mixing Module, type 0xAA, telegram: 10 21 AA 00 FF 0C 0A 11 0A 32 xx
|
||||
void Mixing::process_MMConfigMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
hc_ = device_id() - 0x20 + 1;
|
||||
hc_ = get_device_id() - 0x20 + 1;
|
||||
// pos 0: active FF = on
|
||||
// pos 1: valve runtime 0C = 120 sec in units of 10 sec
|
||||
}
|
||||
@@ -218,7 +223,7 @@ void Mixing::process_MMConfigMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
// Mixing on a MM10 - 0xAC
|
||||
// e.g. Thermostat -> Mixing Module, type 0xAC, telegram: 10 21 AC 00 1E 64 01 AB
|
||||
void Mixing::process_MMSetMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
hc_ = device_id() - 0x20 + 1;
|
||||
hc_ = get_device_id() - 0x20 + 1;
|
||||
// pos 0: flowtemp setpoint 1E = 30°C
|
||||
// pos 1: position in %
|
||||
}
|
||||
|
||||
@@ -18,40 +18,35 @@
|
||||
|
||||
#include "solar.h"
|
||||
|
||||
MAKE_PSTR(kwh, "kWh")
|
||||
MAKE_PSTR(wh, "Wh")
|
||||
|
||||
namespace emsesp {
|
||||
|
||||
REGISTER_FACTORY(Solar, EMSdevice::DeviceType::SOLAR);
|
||||
|
||||
MAKE_PSTR(logger_name, "solar")
|
||||
uuid::log::Logger Solar::logger_{F_(logger_name), uuid::log::Facility::CONSOLE};
|
||||
uuid::log::Logger Solar::logger_{F_(solar), uuid::log::Facility::CONSOLE};
|
||||
|
||||
Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
LOG_DEBUG(F("Registering new Solar module with device ID 0x%02X"), device_id);
|
||||
LOG_DEBUG(F("Adding new Solar module with device ID 0x%02X"), device_id);
|
||||
|
||||
// telegram handlers
|
||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_SM10) {
|
||||
register_telegram_type(0x0097, F("SM10Monitor"), true, std::bind(&Solar::process_SM10Monitor, this, _1));
|
||||
register_telegram_type(0x0097, F("SM10Monitor"), true, [&](std::shared_ptr<const Telegram> t) { process_SM10Monitor(t); });
|
||||
}
|
||||
|
||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_SM100) {
|
||||
register_telegram_type(0x0362, F("SM100Monitor"), true, std::bind(&Solar::process_SM100Monitor, this, _1));
|
||||
register_telegram_type(0x0363, F("SM100Monitor2"), true, std::bind(&Solar::process_SM100Monitor2, this, _1));
|
||||
register_telegram_type(0x0366, F("SM100Config"), true, std::bind(&Solar::process_SM100Config, this, _1));
|
||||
register_telegram_type(0x0362, F("SM100Monitor"), true, [&](std::shared_ptr<const Telegram> t) { process_SM100Monitor(t); });
|
||||
register_telegram_type(0x0363, F("SM100Monitor2"), true, [&](std::shared_ptr<const Telegram> t) { process_SM100Monitor2(t); });
|
||||
register_telegram_type(0x0366, F("SM100Config"), true, [&](std::shared_ptr<const Telegram> t) { process_SM100Config(t); });
|
||||
|
||||
register_telegram_type(0x0364, F("SM100Status"), false, std::bind(&Solar::process_SM100Status, this, _1));
|
||||
register_telegram_type(0x036A, F("SM100Status2"), false, std::bind(&Solar::process_SM100Status2, this, _1));
|
||||
register_telegram_type(0x038E, F("SM100Energy"), true, std::bind(&Solar::process_SM100Energy, this, _1));
|
||||
register_telegram_type(0x0364, F("SM100Status"), false, [&](std::shared_ptr<const Telegram> t) { process_SM100Status(t); });
|
||||
register_telegram_type(0x036A, F("SM100Status2"), false, [&](std::shared_ptr<const Telegram> t) { process_SM100Status2(t); });
|
||||
register_telegram_type(0x038E, F("SM100Energy"), true, [&](std::shared_ptr<const Telegram> t) { process_SM100Energy(t); });
|
||||
}
|
||||
|
||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_ISM) {
|
||||
register_telegram_type(0x0103, F("ISM1StatusMessage"), true, std::bind(&Solar::process_ISM1StatusMessage, this, _1));
|
||||
register_telegram_type(0x0101, F("ISM1Set"), false, std::bind(&Solar::process_ISM1Set, this, _1));
|
||||
register_telegram_type(0x0103, F("ISM1StatusMessage"), true, [&](std::shared_ptr<const Telegram> t) { process_ISM1StatusMessage(t); });
|
||||
register_telegram_type(0x0101, F("ISM1Set"), false, [&](std::shared_ptr<const Telegram> t) { process_ISM1Set(t); });
|
||||
}
|
||||
|
||||
// MQTT callbacks
|
||||
// register_mqtt_topic("topic", std::bind(&Solar::cmd, this, _1));
|
||||
}
|
||||
|
||||
// context submenu
|
||||
@@ -113,7 +108,7 @@ void Solar::show_values(uuid::console::Shell & shell) {
|
||||
|
||||
// publish values via MQTT
|
||||
void Solar::publish_values() {
|
||||
DynamicJsonDocument doc(EMSESP_MAX_JSON_SIZE_MEDIUM);
|
||||
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_MEDIUM> doc;
|
||||
|
||||
char s[10]; // for formatting strings
|
||||
|
||||
@@ -141,11 +136,11 @@ void Solar::publish_values() {
|
||||
doc["cylinderPumpModulation"] = cylinderPumpModulation_;
|
||||
}
|
||||
|
||||
if (Helpers::hasValue(solarPump_, VALUE_BOOL)) {
|
||||
if (Helpers::hasValue(solarPump_, EMS_VALUE_BOOL)) {
|
||||
doc["solarPump"] = Helpers::render_value(s, solarPump_, EMS_VALUE_BOOL);
|
||||
}
|
||||
|
||||
if (Helpers::hasValue(valveStatus_, VALUE_BOOL)) {
|
||||
if (Helpers::hasValue(valveStatus_, EMS_VALUE_BOOL)) {
|
||||
doc["valveStatus"] = Helpers::render_value(s, valveStatus_, EMS_VALUE_BOOL);
|
||||
}
|
||||
|
||||
@@ -153,11 +148,11 @@ void Solar::publish_values() {
|
||||
doc["pumpWorkMin"] = (float)pumpWorkMin_;
|
||||
}
|
||||
|
||||
if (Helpers::hasValue(tankHeated_, VALUE_BOOL)) {
|
||||
if (Helpers::hasValue(tankHeated_, EMS_VALUE_BOOL)) {
|
||||
doc["tankHeated"] = Helpers::render_value(s, tankHeated_, EMS_VALUE_BOOL);
|
||||
}
|
||||
|
||||
if (Helpers::hasValue(collectorShutdown_, VALUE_BOOL)) {
|
||||
if (Helpers::hasValue(collectorShutdown_, EMS_VALUE_BOOL)) {
|
||||
doc["collectorShutdown"] = Helpers::render_value(s, collectorShutdown_, EMS_VALUE_BOOL);
|
||||
}
|
||||
|
||||
@@ -187,8 +182,8 @@ void Solar::console_commands() {
|
||||
|
||||
// SM10Monitor - type 0x97
|
||||
void Solar::process_SM10Monitor(std::shared_ptr<const Telegram> telegram) {
|
||||
telegram->read_value(collectorTemp_, 2); // collector temp from SM10, is *10
|
||||
telegram->read_value(tankBottomTemp_, 5); // bottom temp from SM10, is *10
|
||||
telegram->read_value(collectorTemp_, 2); // collector temp from SM10, is *10
|
||||
telegram->read_value(tankBottomTemp_, 5); // bottom temp from SM10, is *10
|
||||
telegram->read_value(solarPumpModulation_, 4); // modulation solar pump
|
||||
telegram->read_bitvalue(solarPump_, 7, 1);
|
||||
telegram->read_value(pumpWorkMin_, 8);
|
||||
@@ -196,7 +191,6 @@ void Solar::process_SM10Monitor(std::shared_ptr<const Telegram> telegram) {
|
||||
|
||||
/*
|
||||
* SM100Monitor - type 0x0362 EMS+ - for MS/SM100 and MS/SM200
|
||||
* e.g. B0 0B FF 00 02 62 00 44 02 7A 80 00 80 00 80 00 80 00 80 00 80 00 00 7C 80 00 80 00 80 00 80
|
||||
* e.g. B0 0B FF 00 02 62 00 77 01 D4 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00 00 F9 80 00 80 9E - for heat exchanger temp
|
||||
* e.g, 30 00 FF 00 02 62 01 AC
|
||||
* 30 00 FF 18 02 62 80 00
|
||||
@@ -237,21 +231,21 @@ void Solar::process_SM100Config(std::shared_ptr<const Telegram> telegram) {
|
||||
- PS1: Solar circuit pump for collector array 1
|
||||
- PS5: Cylinder primary pump when using an external heat exchanger
|
||||
* e.g. 30 00 FF 09 02 64 64 = 100%
|
||||
* 30 00 FF 09 02 64 1E = 30%
|
||||
*/
|
||||
void Solar::process_SM100Status(std::shared_ptr<const Telegram> telegram) {
|
||||
uint8_t solarpumpmod = solarPumpModulation_;
|
||||
uint8_t solarpumpmod = solarPumpModulation_;
|
||||
uint8_t cylinderpumpmod = cylinderPumpModulation_;
|
||||
telegram->read_value(cylinderPumpModulation_, 8);
|
||||
telegram->read_value(solarPumpModulation_, 9);
|
||||
|
||||
if (solarpumpmod == 0 && solarPumpModulation_ == 100) { // mask out boosts
|
||||
solarPumpModulation_ = 15; // set to minimum
|
||||
}
|
||||
|
||||
if (cylinderpumpmod == 0 && cylinderPumpModulation_ == 100) { // mask out boosts
|
||||
cylinderPumpModulation_ = 15; // set to minimum
|
||||
}
|
||||
|
||||
telegram->read_bitvalue(tankHeated_, 3, 1); // issue #422
|
||||
telegram->read_bitvalue(tankHeated_, 3, 1); // issue #422
|
||||
telegram->read_bitvalue(collectorShutdown_, 3, 0); // collector shutdown
|
||||
}
|
||||
|
||||
@@ -281,22 +275,23 @@ void Solar::process_SM100Energy(std::shared_ptr<const Telegram> telegram) {
|
||||
* e.g. B0 00 FF 00 00 03 32 00 00 00 00 13 00 D6 00 00 00 FB D0 F0
|
||||
*/
|
||||
void Solar::process_ISM1StatusMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
telegram->read_value(collectorTemp_, 4); // Collector Temperature
|
||||
telegram->read_value(tankBottomTemp_, 6); // Temperature Bottom of Solar Boiler
|
||||
telegram->read_value(collectorTemp_, 4); // Collector Temperature
|
||||
telegram->read_value(tankBottomTemp_, 6); // Temperature Bottom of Solar Boiler
|
||||
uint16_t Wh = 0xFFFF;
|
||||
telegram->read_value(Wh, 2); // Solar Energy produced in last hour only ushort, is not * 10
|
||||
|
||||
if (Wh != 0xFFFF) {
|
||||
energyLastHour_ = Wh * 10; // set to *10
|
||||
}
|
||||
telegram->read_bitvalue(solarPump_, 8, 0); // PS1 Solar pump on (1) or off (0)
|
||||
telegram->read_value(pumpWorkMin_, 10, 3); // force to 3 bytes
|
||||
telegram->read_bitvalue(collectorShutdown_, 9, 0); // collector shutdown on/off
|
||||
telegram->read_bitvalue(tankHeated_, 9, 2); // tank full
|
||||
|
||||
telegram->read_bitvalue(solarPump_, 8, 0); // PS1 Solar pump on (1) or off (0)
|
||||
telegram->read_value(pumpWorkMin_, 10, 3); // force to 3 bytes
|
||||
telegram->read_bitvalue(collectorShutdown_, 9, 0); // collector shutdown on/off
|
||||
telegram->read_bitvalue(tankHeated_, 9, 2); // tank full
|
||||
}
|
||||
|
||||
/*
|
||||
* Junkers ISM1 Solar Module - type 0x0101 EMS+ for setting values
|
||||
* e.g. 90 30 FF 06 00 01 50
|
||||
*/
|
||||
void Solar::process_ISM1Set(std::shared_ptr<const Telegram> telegram) {
|
||||
telegram->read_value(setpoint_maxBottomTemp_, 6);
|
||||
|
||||
@@ -18,22 +18,14 @@
|
||||
|
||||
#include "switch.h"
|
||||
|
||||
// MAKE_PSTR_WORD(switch)
|
||||
|
||||
namespace emsesp {
|
||||
|
||||
REGISTER_FACTORY(Switch, EMSdevice::DeviceType::SWITCH);
|
||||
|
||||
MAKE_PSTR(logger_name, "switch")
|
||||
uuid::log::Logger Switch::logger_{F_(logger_name), uuid::log::Facility::CONSOLE};
|
||||
uuid::log::Logger Switch::logger_{F_(switch), uuid::log::Facility::CONSOLE};
|
||||
|
||||
Switch::Switch(uint8_t device_type, uint8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
// telegram handlers
|
||||
// register_telegram_type(EMS_TYPE_XX, "XX", false, std::bind(&Controller::process_XX, this, _1));
|
||||
|
||||
// MQTT callbacks
|
||||
// register_mqtt_topic("topic", std::bind(&Switch::cmd, this, _1));
|
||||
}
|
||||
|
||||
void Switch::add_context_menu() {
|
||||
@@ -44,7 +36,7 @@ void Switch::device_info(JsonArray & root) {
|
||||
|
||||
// display all values into the shell console
|
||||
void Switch::show_values(uuid::console::Shell & shell) {
|
||||
EMSdevice::show_values(shell); // always call this to show header
|
||||
// EMSdevice::show_values(shell); // always call this to show header
|
||||
}
|
||||
|
||||
// publish values via MQTT
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -91,7 +91,7 @@ class Thermostat : public EMSdevice {
|
||||
uint16_t set_typeid_;
|
||||
};
|
||||
|
||||
std::string mode_tostring(uint8_t mode) const;
|
||||
static std::string mode_tostring(uint8_t mode);
|
||||
|
||||
virtual void show_values(uuid::console::Shell & shell);
|
||||
virtual void publish_values();
|
||||
@@ -99,21 +99,17 @@ class Thermostat : public EMSdevice {
|
||||
virtual bool updated_values();
|
||||
virtual void add_context_menu();
|
||||
|
||||
bool can_write() const {
|
||||
return ((flags() & EMSdevice::EMS_DEVICE_FLAG_NO_WRITE) == EMSdevice::EMS_DEVICE_FLAG_NO_WRITE);
|
||||
}
|
||||
private:
|
||||
static uuid::log::Logger logger_;
|
||||
|
||||
void console_commands(Shell & shell, unsigned int context);
|
||||
void add_commands();
|
||||
|
||||
// each thermostat has a list of heating controller type IDs for reading and writing
|
||||
std::vector<uint16_t> monitor_typeids;
|
||||
std::vector<uint16_t> set_typeids;
|
||||
std::vector<uint16_t> timer_typeids;
|
||||
|
||||
private:
|
||||
static uuid::log::Logger logger_;
|
||||
|
||||
void console_commands(Shell & shell, unsigned int context);
|
||||
void init_mqtt();
|
||||
|
||||
std::string datetime_; // date and time stamp
|
||||
|
||||
uint8_t mqtt_format_; // single, nested or ha
|
||||
@@ -210,6 +206,7 @@ class Thermostat : public EMSdevice {
|
||||
// Installation settings
|
||||
static constexpr uint8_t EMS_TYPE_IBASettings = 0xA5; // installation settings
|
||||
static constexpr uint8_t EMS_TYPE_wwSettings = 0x37; // ww settings
|
||||
static constexpr uint8_t EMS_TYPE_time = 0x06; // time
|
||||
|
||||
std::shared_ptr<Thermostat::HeatingCircuit> heating_circuit(std::shared_ptr<const Telegram> telegram);
|
||||
std::shared_ptr<Thermostat::HeatingCircuit> heating_circuit(const uint8_t hc_num);
|
||||
@@ -220,55 +217,65 @@ class Thermostat : public EMSdevice {
|
||||
void process_IBASettings(std::shared_ptr<const Telegram> telegram);
|
||||
void process_RCTime(std::shared_ptr<const Telegram> telegram);
|
||||
void process_RC35wwSettings(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
void process_RC35Monitor(std::shared_ptr<const Telegram> telegram);
|
||||
void process_RC35Set(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
void process_RC30Monitor(std::shared_ptr<const Telegram> telegram);
|
||||
void process_RC30Set(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
void process_RC20Monitor(std::shared_ptr<const Telegram> telegram);
|
||||
void process_RC20Set(std::shared_ptr<const Telegram> telegram);
|
||||
void process_RC20Remote(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
void process_RC20Monitor_2(std::shared_ptr<const Telegram> telegram);
|
||||
void process_RC20Set_2(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
void process_RC10Monitor(std::shared_ptr<const Telegram> telegram);
|
||||
void process_RC10Set(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
void process_RC300Monitor(std::shared_ptr<const Telegram> telegram);
|
||||
void process_RC300Set(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
void process_JunkersMonitor(std::shared_ptr<const Telegram> telegram);
|
||||
void process_JunkersSet(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
void process_JunkersSet2(std::shared_ptr<const Telegram> telegram);
|
||||
void process_EasyMonitor(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
void process_RC300WWmode(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
// set functions
|
||||
void set_settings_minexttemp(const int8_t mt);
|
||||
void set_settings_calinttemp(const int8_t ct);
|
||||
void set_settings_clockoffset(const int8_t co);
|
||||
void set_settings_display(const uint8_t ds);
|
||||
void set_settings_building(const uint8_t bg);
|
||||
void set_settings_language(const uint8_t lg);
|
||||
void set_control(const uint8_t ctrl, const uint8_t hc_num);
|
||||
void set_ww_mode(const std::string & mode);
|
||||
void set_holiday(const char * hd, const uint8_t hc_num);
|
||||
void set_datetime(const char * dt);
|
||||
void set_pause(const uint8_t hrs, const uint8_t hc_num);
|
||||
void set_party(const uint8_t hrs, const uint8_t hc_num);
|
||||
void set_mode(const uint8_t mode, const uint8_t hc_num);
|
||||
void set_mode(const std::string & mode, const uint8_t hc_num);
|
||||
// internal helper functions
|
||||
void set_mode_n(const uint8_t mode, const uint8_t hc_num);
|
||||
|
||||
void set_temperature_value(const char * value, const int8_t id, const uint8_t mode);
|
||||
void set_temperature(const float temperature, const std::string & mode, const uint8_t hc_num);
|
||||
void set_temperature(const float temperature, const uint8_t mode, const uint8_t hc_num);
|
||||
|
||||
// MQTT functions
|
||||
void thermostat_cmd(const char * message);
|
||||
// for HA specifically. MQTT functions.
|
||||
void thermostat_cmd_temp(const char * message);
|
||||
void thermostat_cmd_mode(const char * message);
|
||||
|
||||
// set functions - these use the id/hc
|
||||
void set_mode(const char * value, const int8_t id);
|
||||
void set_control(const char * value, const int8_t id);
|
||||
void set_holiday(const char * value, const int8_t id);
|
||||
void set_pause(const char * value, const int8_t id);
|
||||
void set_party(const char * value, const int8_t id);
|
||||
|
||||
void set_temp(const char * value, const int8_t id);
|
||||
void set_nighttemp(const char * value, const int8_t id);
|
||||
void set_daytemp(const char * value, const int8_t id);
|
||||
void set_nofrosttemp(const char * value, const int8_t id);
|
||||
void set_ecotemp(const char * value, const int8_t id);
|
||||
void set_heattemp(const char * value, const int8_t id);
|
||||
void set_summertemp(const char * value, const int8_t id);
|
||||
void set_designtemp(const char * value, const int8_t id);
|
||||
void set_offsettemp(const char * value, const int8_t id);
|
||||
void set_holidaytemp(const char * value, const int8_t id);
|
||||
|
||||
void set_remotetemp(const char * value, const int8_t id);
|
||||
|
||||
// set functions - these don't use the id/hc, the parameters are ignored
|
||||
void set_wwmode(const char * value, const int8_t id);
|
||||
void set_datetime(const char * value, const int8_t id);
|
||||
void set_minexttemp(const char * value, const int8_t id);
|
||||
void set_clockoffset(const char * value, const int8_t id);
|
||||
void set_calinttemp(const char * value, const int8_t id);
|
||||
void set_display(const char * value, const int8_t id);
|
||||
void set_building(const char * value, const int8_t id);
|
||||
void set_language(const char * value, const int8_t id);
|
||||
};
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
Reference in New Issue
Block a user