diff --git a/interface/src/project/EMSESPSettingsController.tsx b/interface/src/project/EMSESPSettingsController.tsx
index b633ff984..11533b0d1 100644
--- a/interface/src/project/EMSESPSettingsController.tsx
+++ b/interface/src/project/EMSESPSettingsController.tsx
@@ -247,6 +247,21 @@ function EMSESPSettingsControllerForm(props: EMSESPSettingsControllerFormProps)
onChange={handleValueChange('syslog_mark_interval')}
margin="normal"
/>
+
+
+ Analog input
+
+
+ }
+ label="Enable ADC"
+ />
+
} variant="contained" color="primary" type="submit">
Save
diff --git a/interface/src/project/EMSESPtypes.ts b/interface/src/project/EMSESPtypes.ts
index f3d58086c..39b1fcae4 100644
--- a/interface/src/project/EMSESPtypes.ts
+++ b/interface/src/project/EMSESPtypes.ts
@@ -15,6 +15,7 @@ export interface EMSESPSettings {
hide_led: boolean;
api_enabled: boolean;
bool_format: number;
+ analog_enabled: boolean;
}
export enum busConnectionStatus {
diff --git a/src/EMSESPSettingsService.cpp b/src/EMSESPSettingsService.cpp
index ae6ed3248..3441b4f11 100644
--- a/src/EMSESPSettingsService.cpp
+++ b/src/EMSESPSettingsService.cpp
@@ -44,6 +44,7 @@ void EMSESPSettings::read(EMSESPSettings & settings, JsonObject & root) {
root["hide_led"] = settings.hide_led;
root["api_enabled"] = settings.api_enabled;
root["bool_format"] = settings.bool_format;
+ root["analog_enabled"] = settings.analog_enabled;
}
StateUpdateResult EMSESPSettings::update(JsonObject & root, EMSESPSettings & settings) {
@@ -63,6 +64,7 @@ StateUpdateResult EMSESPSettings::update(JsonObject & root, EMSESPSettings & set
settings.hide_led = root["hide_led"] | EMSESP_DEFAULT_HIDE_LED;
settings.api_enabled = root["api_enabled"] | EMSESP_DEFAULT_API_ENABLED;
settings.bool_format = root["bool_format"] | EMSESP_DEFAULT_BOOL_FORMAT;
+ settings.analog_enabled = root["analog_enabled"] | EMSESP_DEFAULT_ANALOG_ENABLED;
return StateUpdateResult::CHANGED;
}
diff --git a/src/EMSESPSettingsService.h b/src/EMSESPSettingsService.h
index 6e200260e..4fd819903 100644
--- a/src/EMSESPSettingsService.h
+++ b/src/EMSESPSettingsService.h
@@ -37,6 +37,7 @@
#define EMSESP_DEFAULT_DALLAS_PARASITE false
#define EMSESP_DEFAULT_API_ENABLED true
#define EMSESP_DEFAULT_BOOL_FORMAT 1 // on/off
+#define EMSESP_DEFAULT_ANALOG_ENABLED false
// Default GPIO PIN definitions
#if defined(ESP8266)
@@ -77,6 +78,7 @@ class EMSESPSettings {
bool hide_led;
bool api_enabled;
uint8_t bool_format;
+ bool analog_enabled;
static void read(EMSESPSettings & settings, JsonObject & root);
static StateUpdateResult update(JsonObject & root, EMSESPSettings & settings);
diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp
index ae42ade1d..ea513c0e9 100644
--- a/src/devices/boiler.cpp
+++ b/src/devices/boiler.cpp
@@ -33,17 +33,17 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
// the telegram handlers...
register_telegram_type(0x10, F("UBAErrorMessage1"), false, [&](std::shared_ptr t) { process_UBAErrorMessage(t); });
register_telegram_type(0x11, F("UBAErrorMessage2"), false, [&](std::shared_ptr t) { process_UBAErrorMessage(t); });
+ register_telegram_type(0x14, F("UBATotalUptime"), true, [&](std::shared_ptr t) { process_UBATotalUptime(t); });
+ register_telegram_type(0x15, F("UBAMaintenanceData"), false, [&](std::shared_ptr t) { process_UBAMaintenanceData(t); });
+ register_telegram_type(0x16, F("UBAParameters"), true, [&](std::shared_ptr t) { process_UBAParameters(t); });
register_telegram_type(0x18, F("UBAMonitorFast"), false, [&](std::shared_ptr t) { process_UBAMonitorFast(t); });
register_telegram_type(0x19, F("UBAMonitorSlow"), true, [&](std::shared_ptr t) { process_UBAMonitorSlow(t); });
- register_telegram_type(0x34, F("UBAMonitorWW"), false, [&](std::shared_ptr t) { process_UBAMonitorWW(t); });
+ register_telegram_type(0x1A, F("UBASetPoints"), false, [&](std::shared_ptr t) { process_UBASetPoints(t); });
register_telegram_type(0x1C, F("UBAMaintenanceStatus"), false, [&](std::shared_ptr t) { process_UBAMaintenanceStatus(t); });
register_telegram_type(0x2A, F("MC10Status"), false, [&](std::shared_ptr t) { process_MC10Status(t); });
register_telegram_type(0x33, F("UBAParameterWW"), true, [&](std::shared_ptr t) { process_UBAParameterWW(t); });
- register_telegram_type(0x14, F("UBATotalUptime"), true, [&](std::shared_ptr t) { process_UBATotalUptime(t); });
+ register_telegram_type(0x34, F("UBAMonitorWW"), false, [&](std::shared_ptr t) { process_UBAMonitorWW(t); });
register_telegram_type(0x35, F("UBAFlags"), false, [&](std::shared_ptr t) { process_UBAFlags(t); });
- register_telegram_type(0x15, F("UBAMaintenanceData"), false, [&](std::shared_ptr t) { process_UBAMaintenanceData(t); });
- register_telegram_type(0x16, F("UBAParameters"), true, [&](std::shared_ptr t) { process_UBAParameters(t); });
- register_telegram_type(0x1A, F("UBASetPoints"), false, [&](std::shared_ptr t) { process_UBASetPoints(t); });
register_telegram_type(0xD1, F("UBAOutdoorTemp"), false, [&](std::shared_ptr t) { process_UBAOutdoorTemp(t); });
register_telegram_type(0xE3, F("UBAMonitorSlowPlus"), false, [&](std::shared_ptr t) { process_UBAMonitorSlowPlus2(t); });
register_telegram_type(0xE4, F("UBAMonitorFastPlus"), false, [&](std::shared_ptr t) { process_UBAMonitorFastPlus(t); });
@@ -57,7 +57,9 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
register_mqtt_cmd(F("wwactivated"), [&](const char * value, const int8_t id) { return set_warmwater_activated(value, id); });
register_mqtt_cmd(F("wwtapactivated"), [&](const char * value, const int8_t id) { return set_tapwarmwater_activated(value, id); });
register_mqtt_cmd(F("wwonetime"), [&](const char * value, const int8_t id) { return set_warmwater_onetime(value, id); });
+ register_mqtt_cmd(F("wwcircpump"), [&](const char * value, const int8_t id) { return set_warmwater_circulation_pump(value, id); });
register_mqtt_cmd(F("wwcirculation"), [&](const char * value, const int8_t id) { return set_warmwater_circulation(value, id); });
+ register_mqtt_cmd(F("wwcircmode"), [&](const char * value, const int8_t id) { return set_warmwater_circulation_mode(value, id); });
register_mqtt_cmd(F("flowtemp"), [&](const char * value, const int8_t id) { return set_flow_temp(value, id); });
register_mqtt_cmd(F("wwtemp"), [&](const char * value, const int8_t id) { return set_warmwater_temp(value, id); });
register_mqtt_cmd(F("heatingactivated"), [&](const char * value, const int8_t id) { return set_heating_activated(value, id); });
@@ -237,8 +239,8 @@ bool Boiler::export_values(JsonObject & output) {
if (Helpers::hasValue(wWDisinfecting_, EMS_VALUE_BOOL)) {
output["wWDisinfecting"] = Helpers::render_value(s, wWDisinfecting_, EMS_VALUE_BOOL);
}
- if (Helpers::hasValue(wWReadiness_, EMS_VALUE_BOOL)) {
- output["wWReady"] = Helpers::render_value(s, wWReadiness_, EMS_VALUE_BOOL);
+ if (Helpers::hasValue(wWCharging_, EMS_VALUE_BOOL)) {
+ output["wWCharge"] = Helpers::render_value(s, wWCharging_, EMS_VALUE_BOOL);
}
if (Helpers::hasValue(wWRecharging_, EMS_VALUE_BOOL)) {
output["wWRecharge"] = Helpers::render_value(s, wWRecharging_, EMS_VALUE_BOOL);
@@ -246,8 +248,8 @@ bool Boiler::export_values(JsonObject & output) {
if (Helpers::hasValue(wWTemperatureOK_, EMS_VALUE_BOOL)) {
output["wWTempOK"] = Helpers::render_value(s, wWTemperatureOK_, EMS_VALUE_BOOL);
}
- if (Helpers::hasValue(wWCirc_, EMS_VALUE_BOOL)) {
- output["wWCirc"] = Helpers::render_value(s, wWCirc_, EMS_VALUE_BOOL);
+ if (Helpers::hasValue(wWActive_, EMS_VALUE_BOOL)) {
+ output["wWActive"] = Helpers::render_value(s, wWActive_, EMS_VALUE_BOOL);
}
if (Helpers::hasValue(burnGas_, EMS_VALUE_BOOL)) {
output["burnGas"] = Helpers::render_value(s, burnGas_, EMS_VALUE_BOOL);
@@ -480,14 +482,14 @@ void Boiler::show_values(uuid::console::Shell & shell) {
*/
void Boiler::check_active() {
if ((boilerState_ & 0x09) != (last_boilerState & 0x09)) {
- char s[5];
+ char s[7];
bool b = ((boilerState_ & 0x09) == 0x09);
Mqtt::publish(F("heating_active"), Helpers::render_boolean(s, b));
heating_active_ = b ? EMS_VALUE_BOOL_ON : EMS_VALUE_BOOL_OFF;
}
if ((boilerState_ & 0x0A) != (last_boilerState & 0x0A)) {
- char s[5];
+ char s[7];
bool b = ((boilerState_ & 0x0A) == 0x0A);
Mqtt::publish(F("tapwater_active"), Helpers::render_boolean(s, b));
tap_water_active_ = b ? EMS_VALUE_BOOL_ON : EMS_VALUE_BOOL_OFF;
@@ -497,7 +499,6 @@ void Boiler::check_active() {
last_boilerState = boilerState_;
/*
-
// hot tap water, using flow to check instead of the burner power
// send these values back to the main EMSESP, so other classes (e.g. Shower) can use it
if (Helpers::hasValue(wWCurFlow_) && Helpers::hasValue(burnGas_) && (wWType_ > 0) && (wWType_ < 3)) {
@@ -613,9 +614,10 @@ void Boiler::process_UBAMonitorWW(std::shared_ptr telegram) {
changed_ |= telegram->read_bitvalue(wWOneTime_, 5, 1);
changed_ |= telegram->read_bitvalue(wWDisinfecting_, 5, 2);
- changed_ |= telegram->read_bitvalue(wWReadiness_, 5, 3);
+ changed_ |= telegram->read_bitvalue(wWCharging_, 5, 3);
changed_ |= telegram->read_bitvalue(wWRecharging_, 5, 4);
changed_ |= telegram->read_bitvalue(wWTemperatureOK_, 5, 5);
+ changed_ |= telegram->read_bitvalue(wWActive_, 5, 6);
}
/*
@@ -715,7 +717,7 @@ void Boiler::process_UBADHWStatus(std::shared_ptr telegram) {
changed_ |= telegram->read_bitvalue(wWOneTime_, 12, 2);
changed_ |= telegram->read_bitvalue(wWDisinfecting_, 12, 3);
- changed_ |= telegram->read_bitvalue(wWReadiness_, 12, 4);
+ changed_ |= telegram->read_bitvalue(wWCharging_, 12, 4);
changed_ |= telegram->read_bitvalue(wWRecharging_, 13, 4);
changed_ |= telegram->read_bitvalue(wWTemperatureOK_, 13, 5);
changed_ |= telegram->read_bitvalue(wWCircPump_, 13, 2);
@@ -816,7 +818,7 @@ bool Boiler::set_heating_activated(const char * value, const int8_t id) {
return false;
}
- LOG_INFO(F("Setting boiler heating "), v ? "on" : "off");
+ LOG_INFO(F("Setting boiler heating %s"), v ? "on" : "off");
if (get_toggle_fetch(EMS_TYPE_UBAParametersPlus)) {
write_command(EMS_TYPE_UBAParametersPlus, 0, v ? 0x01 : 0, EMS_TYPE_UBAParametersPlus);
} else {
@@ -992,7 +994,7 @@ bool Boiler::set_warmwater_activated(const char * value, const int8_t id) {
if (get_toggle_fetch(EMS_TYPE_UBAParameterWWPlus)) {
write_command(EMS_TYPE_UBAParameterWWPlus, 1, v ? 1 : 0, EMS_TYPE_UBAParameterWWPlus);
} else {
- write_command(EMS_TYPE_UBAParameterWW, 1, n, EMS_TYPE_UBAParameterWW);
+ write_command(EMS_TYPE_UBAParameterWW, 1, n, 0x34);
}
return true;
@@ -1024,7 +1026,6 @@ bool Boiler::set_tapwarmwater_activated(const char * value, const int8_t id) {
} else {
// get out of test mode. Send all zeros.
// telegram: 0B 08 1D 00 00
- message_data[4] = 0x00; // test mode off
}
write_command(EMS_TYPE_UBAFunctionTest, 0, message_data, sizeof(message_data), 0);
@@ -1069,4 +1070,42 @@ bool Boiler::set_warmwater_circulation(const char * value, const int8_t id) {
return true;
}
+// configuration of warm water circulation pump
+bool Boiler::set_warmwater_circulation_pump(const char * value, const int8_t id) {
+ bool v = false;
+ if (!Helpers::value2bool(value, v)) {
+ return false;
+ }
+
+ LOG_INFO(F("Setting boiler warm water circulation %s"), v ? "on" : "off");
+
+ if (get_toggle_fetch(EMS_TYPE_UBAParameterWWPlus)) {
+ write_command(EMS_TYPE_UBAParameterWWPlus, 10, v ? 0x01 : 0x00, EMS_TYPE_UBAParameterWWPlus);
+ } else {
+ write_command(EMS_TYPE_UBAParameterWW, 6, v ? 0xFF : 0x00, EMS_TYPE_UBAParameterWW);
+ }
+
+ return true;
+}
+
+// Set the mode of circulation, 1x3min, ... 6x3min, continous
+// true = on, false = off
+bool Boiler::set_warmwater_circulation_mode(const char * value, const int8_t id) {
+ int v = 0;
+ if (!Helpers::value2number(value, v)) {
+ return false;
+ }
+
+ if (get_toggle_fetch(EMS_TYPE_UBAParameterWW)) {
+ if (v < 7) {
+ LOG_INFO(F("Setting circulation mode %dx3min"), v);
+ } else {
+ LOG_INFO(F("Setting circulation mode continous"));
+ }
+ write_command(EMS_TYPE_UBAParameterWW, 6, v, EMS_TYPE_UBAParameterWW);
+ }
+
+ return true;
+}
+
} // namespace emsesp
diff --git a/src/devices/boiler.h b/src/devices/boiler.h
index 931e6ac1d..377667843 100644
--- a/src/devices/boiler.h
+++ b/src/devices/boiler.h
@@ -116,11 +116,12 @@ class Boiler : public EMSdevice {
uint32_t wWWorkM_ = EMS_VALUE_ULONG_NOTSET; // Warm Water # minutes
uint8_t wWOneTime_ = EMS_VALUE_BOOL_NOTSET; // Warm Water one time function on/off
uint8_t wWDisinfecting_ = EMS_VALUE_BOOL_NOTSET; // Warm Water disinfection on/off
- uint8_t wWReadiness_ = EMS_VALUE_BOOL_NOTSET; // Warm Water readiness on/off
+ uint8_t wWCharging_ = EMS_VALUE_BOOL_NOTSET; // Warm Water charging on/off
uint8_t wWRecharging_ = EMS_VALUE_BOOL_NOTSET; // Warm Water recharge on/off
uint8_t wWTemperatureOK_ = EMS_VALUE_BOOL_NOTSET; // Warm Water temperature ok on/off
uint8_t wWCurFlow_ = EMS_VALUE_UINT_NOTSET; // Warm Water current flow temp in l/min
uint8_t wWType_ = EMS_VALUE_UINT_NOTSET; // 0-off, 1-flow, 2-flowbuffer, 3-buffer, 4-layered buffer
+ uint8_t wWActive_ = EMS_VALUE_BOOL_NOTSET;
// UBATotalUptime
uint32_t UBAuptime_ = EMS_VALUE_ULONG_NOTSET; // Total UBA working hours
@@ -175,6 +176,8 @@ class Boiler : public EMSdevice {
bool set_tapwarmwater_activated(const char * value, const int8_t id);
bool set_warmwater_onetime(const char * value, const int8_t id);
bool set_warmwater_circulation(const char * value, const int8_t id);
+ bool set_warmwater_circulation_pump(const char * value, const int8_t id);
+ bool set_warmwater_circulation_mode(const char * value, const int8_t id);
bool set_warmwater_temp(const char * value, const int8_t id);
bool set_flow_temp(const char * value, const int8_t id);
bool set_heating_activated(const char * value, const int8_t id);
diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp
index ac59f5288..3e8c966ae 100644
--- a/src/devices/thermostat.cpp
+++ b/src/devices/thermostat.cpp
@@ -112,9 +112,11 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
} else if ((model == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model == EMSdevice::EMS_DEVICE_FLAG_RC100)) {
monitor_typeids = {0x02A5, 0x02A6, 0x02A7, 0x02A8};
set_typeids = {0x02B9, 0x02BA, 0x02BB, 0x02BC};
+ summer_typeids = {0x02AF, 0x02B0, 0x02B1, 0x02B2};
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
register_telegram_type(monitor_typeids[i], F("RC300Monitor"), false, [&](std::shared_ptr t) { process_RC300Monitor(t); });
register_telegram_type(set_typeids[i], F("RC300Set"), false, [&](std::shared_ptr t) { process_RC300Set(t); });
+ register_telegram_type(summer_typeids[i], F("RC300Summer"), false, [&](std::shared_ptr t) { process_RC300Summer(t); });
}
register_telegram_type(0x31D, F("RC300WWmode"), false, [&](std::shared_ptr t) { process_RC300WWmode(t); });
register_telegram_type(0x31E, F("RC300WWmode"), false, [&](std::shared_ptr t) { process_RC300WWmode(t); });
@@ -288,12 +290,20 @@ bool Thermostat::export_values(uint8_t mqtt_format, JsonObject & rootThermostat)
}
}
if (Helpers::hasValue(wwMode_)) {
- if (wwMode_ == 0) {
- rootThermostat["wwmode"] = "off";
- } else if (wwMode_ == 1) {
- rootThermostat["wwmode"] = "on";
- } else if (wwMode_ == 2) {
+ if (wwMode_ == 2) {
rootThermostat["wwmode"] = "auto";
+ } else {
+ char s[7];
+ rootThermostat["wwmode"] = Helpers::render_boolean(s, (wwMode_ == 1));
+ }
+ }
+
+ if (Helpers::hasValue(wwCircMode_)) {
+ if (wwCircMode_ == 2) {
+ rootThermostat["wwcircmode"] = "auto";
+ } else {
+ char s[7];
+ rootThermostat["wwcircmode"] = Helpers::render_boolean(s, (wwCircMode_ == 1));
}
}
@@ -388,10 +398,20 @@ bool Thermostat::export_values(uint8_t mqtt_format, JsonObject & rootThermostat)
if (Helpers::hasValue(hc->designtemp)) {
dataThermostat["designtemp"] = hc->designtemp;
}
+
if (Helpers::hasValue(hc->summertemp)) {
dataThermostat["summertemp"] = hc->summertemp;
}
+ if (Helpers::hasValue(hc->summer_setmode)) {
+ if (hc->summer_setmode == 1) {
+ dataThermostat["summermode"] = "auto";
+ } else {
+ char s[7];
+ rootThermostat["summermode"] = Helpers::render_boolean(s, (hc->summer_setmode == 0));
+ }
+ }
+
// mode - always force showing this when in HA so not to break HA's climate component
if ((Helpers::hasValue(hc->mode)) || (mqtt_format == Mqtt::Format::HA)) {
uint8_t hc_mode = hc->get_mode(flags);
@@ -744,20 +764,29 @@ void Thermostat::show_values(uuid::console::Shell & shell) {
print_value(shell, 2, F("Offset clock"), ibaClockOffset_, nullptr); // offset (in sec) to clock, 0xff = -1 s, 0x02 = 2 s
}
}
+
if (Helpers::hasValue(wwMode_)) {
- if (wwMode_ == 0) {
- shell.printfln(F(" Warm Water mode: off"));
- } else if (wwMode_ == 1) {
- shell.printfln(F(" Warm Water mode: on"));
- } else if (wwMode_ == 2) {
- shell.printfln(F(" Warm Water mode: auto"));
+ if (wwMode_ == 2) {
+ print_value(shell, 2, F("Warm Water mode"), F("auto"));
+ } else {
+ print_value(shell, 2, F("Warm Water mode"), wwMode_, nullptr, EMS_VALUE_BOOL);
}
}
+
+ if (Helpers::hasValue(wwCircMode_)) {
+ if (wwCircMode_ == 2) {
+ print_value(shell, 2, F("Warm Water circulation mode"), F("auto"));
+ } else {
+ print_value(shell, 2, F("Warm Water circulation mode"), wwCircMode_, nullptr, EMS_VALUE_BOOL);
+ }
+ }
+
if (flags == EMS_DEVICE_FLAG_RC35) {
print_value(shell, 2, F("Damped Outdoor temperature"), dampedoutdoortemp_, F_(degrees));
print_value(shell, 2, F("Temp sensor 1"), tempsensor1_, F_(degrees), 10);
print_value(shell, 2, F("Temp sensor 2"), tempsensor2_, F_(degrees), 10);
}
+
if (flags == EMS_DEVICE_FLAG_RC30_1) {
// settings parameters
if (Helpers::hasValue(ibaMainDisplay_)) {
@@ -794,6 +823,7 @@ void Thermostat::show_values(uuid::console::Shell & shell) {
}
}
}
+
if (flags == EMS_DEVICE_FLAG_RC35 || flags == EMS_DEVICE_FLAG_RC30_1) {
if (Helpers::hasValue(ibaCalIntTemperature_)) {
print_value(shell, 2, F("Offset int. temperature"), ibaCalIntTemperature_, F_(degrees), 2);
@@ -887,6 +917,14 @@ void Thermostat::show_values(uuid::console::Shell & shell) {
if (Helpers::hasValue(hc->summertemp)) {
print_value(shell, 4, F("Summer temperature"), hc->summertemp, F_(degrees));
}
+ if (Helpers::hasValue(hc->summer_setmode)) {
+ if (hc->summer_setmode == 1) {
+ print_value(shell, 4, F("Summer mode"), F("auto"));
+ } else {
+ char s[7];
+ print_value(shell, 4, F("Summer mode"), Helpers::render_boolean(s, (hc->summer_setmode == 0)));
+ }
+ }
if (Helpers::hasValue(hc->targetflowtemp)) {
print_value(shell, 4, F("Target flow temperature"), hc->targetflowtemp, F_(degrees));
}
@@ -995,7 +1033,8 @@ void Thermostat::process_IBASettings(std::shared_ptr telegram) {
// Settings WW 0x37 - RC35
void Thermostat::process_RC35wwSettings(std::shared_ptr telegram) {
- changed_ |= telegram->read_value(wwMode_, 2); // 0 off, 1-on, 2-auto
+ changed_ |= telegram->read_value(wwMode_, 2); // 0 off, 1-on, 2-auto
+ changed_ |= telegram->read_value(wwCircMode_, 3); // 0 off, 1-on, 2-auto
}
// type 0x6F - FR10/FR50/FR100 Junkers
@@ -1055,6 +1094,13 @@ void Thermostat::process_RC300Set(std::shared_ptr telegram) {
changed_ |= telegram->read_value(hc->manualtemp, 10); // is * 2
}
+// types 0x2AF ff
+void Thermostat::process_RC300Summer(std::shared_ptr telegram) {
+ std::shared_ptr hc = heating_circuit(telegram);
+ changed_ |= telegram->read_value(hc->summertemp, 6);
+ changed_ |= telegram->read_value(hc->summer_setmode, 7);
+}
+
// types 0x31D and 0x31E
void Thermostat::process_RC300WWmode(std::shared_ptr telegram) {
// 0x31D for WW system 1, 0x31E for WW system 2
@@ -1301,11 +1347,11 @@ bool Thermostat::set_wwmode(const char * value, const int8_t id) {
}
uint8_t set = 0xFF; // some dummy value
- if (v == "off") {
+ if (v == "off" || v == "0" || v == "false") {
set = 0;
- } else if (v == "on") {
+ } else if (v == "on" || v == "1" || v == "true") {
set = 1;
- } else if (v == "auto") {
+ } else if (v == "auto" || v == "2") {
set = 2;
}
@@ -1319,6 +1365,32 @@ bool Thermostat::set_wwmode(const char * value, const int8_t id) {
return true;
}
+// sets the thermostat ww circulation working mode, where mode is a string
+bool Thermostat::set_wwcircmode(const char * value, const int8_t id) {
+ std::string v(10, '\0');
+ if (!Helpers::value2string(value, v)) {
+ return false;
+ }
+
+ uint8_t set = 0xFF; // some dummy value
+ if (v == "off" || v == "0" || v == "false") {
+ set = 0;
+ } else if (v == "on" || v == "1" || v == "true") {
+ set = 1;
+ } else if (v == "auto" || v == "2") {
+ set = 2;
+ }
+
+ if (set != 0xFF) {
+ LOG_INFO(F("Setting thermostat warm water circulation mode to %s"), v.c_str());
+ write_command(EMS_TYPE_wwSettings, 3, set, EMS_TYPE_wwSettings);
+ } else {
+ LOG_WARNING(F("Set thermostat warm water circulation mode: Invalid mode: %s"), v.c_str());
+ }
+
+ return true;
+}
+
// set the holiday as string dd.mm.yyyy-dd.mm.yyyy
bool Thermostat::set_holiday(const char * value, const int8_t id) {
std::string hd(30, '\0');
@@ -1569,6 +1641,32 @@ bool Thermostat::set_mode_n(const uint8_t mode, const uint8_t hc_num) {
return true;
}
+bool Thermostat::set_summermode(const char * value, const int8_t id) {
+ uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id;
+ std::shared_ptr hc = heating_circuit(hc_num);
+ std::string v(10, '\0');
+ if (!Helpers::value2string(value, v)) {
+ return false;
+ }
+
+ uint8_t set = 0xFF; // some dummy value
+ if (v == "on" || v == "1" || v == "true") {
+ LOG_INFO(F("Setting summer mode to always on for heating circuit %d"), hc->hc_num());
+ set = 0;
+ } else if (v == "auto" || v == "2") {
+ LOG_INFO(F("Setting summer mode to auto for heating circuit %d"), hc->hc_num());
+ set = 1;
+ } else if (v == "off" || v == "0" || v == "false") {
+ LOG_INFO(F("Setting summer mode to always off for heating circuit %d"), hc->hc_num());
+ set = 2;
+ } else {
+ return false;
+ }
+ write_command(summer_typeids[hc->hc_num() - 1], 7, set, summer_typeids[hc->hc_num() - 1]);
+ return true;
+}
+
+
// sets the thermostat temp, where mode is a string
bool Thermostat::set_temperature(const float temperature, const std::string & mode, const uint8_t hc_num) {
if (mode_tostring(HeatingCircuit::Mode::MANUAL) == mode) {
@@ -1626,6 +1724,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co
int8_t offset = -1; // we use -1 to check if there is a value
uint8_t factor = 2; // some temperatures only use 1
uint16_t validate_typeid = monitor_typeids[hc->hc_num() - 1];
+ uint16_t set_typeid = set_typeids[hc->hc_num() - 1];
if (model == EMS_DEVICE_FLAG_RC10) {
offset = EMS_OFFSET_RC10Set_temp;
@@ -1639,6 +1738,11 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co
} else if ((model == EMS_DEVICE_FLAG_RC300) || (model == EMS_DEVICE_FLAG_RC100)) {
validate_typeid = set_typeids[hc->hc_num() - 1];
switch (mode) {
+ case HeatingCircuit::Mode::SUMMER:
+ offset = 0x06;
+ set_typeid = summer_typeids[hc->hc_num() - 1];
+ validate_typeid = set_typeid;
+ break;
case HeatingCircuit::Mode::MANUAL:
offset = 0x0A; // manual offset
break;
@@ -1790,7 +1894,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co
// add the write command to the Tx queue. value is *2
// post validate is the corresponding monitor or set type IDs as they can differ per model
- write_command(set_typeids[hc->hc_num() - 1], offset, (uint8_t)((float)temperature * (float)factor), validate_typeid);
+ write_command(set_typeid, offset, (uint8_t)((float)temperature * (float)factor), validate_typeid);
return true;
}
@@ -1868,7 +1972,6 @@ void Thermostat::add_commands() {
}
// common to all thermostats
- register_mqtt_cmd(F("wwmode"), [&](const char * value, const int8_t id) { return set_wwmode(value, id); });
register_mqtt_cmd(F("temp"), [&](const char * value, const int8_t id) { return set_temp(value, id); });
register_mqtt_cmd(F("mode"), [=](const char * value, const int8_t id) {
if (!set_mode(value, id)) {
@@ -1885,6 +1988,8 @@ void Thermostat::add_commands() {
register_mqtt_cmd(F("manualtemp"), [&](const char * value, const int8_t id) { return set_manualtemp(value, id); });
register_mqtt_cmd(F("ecotemp"), [&](const char * value, const int8_t id) { return set_ecotemp(value, id); });
register_mqtt_cmd(F("comforttemp"), [&](const char * value, const int8_t id) { return set_comforttemp(value, id); });
+ register_mqtt_cmd(F("summermode"), [&](const char * value, const int8_t id) { return set_summermode(value, id); });
+ register_mqtt_cmd(F("summertemp"), [&](const char * value, const int8_t id) { return set_summertemp(value, id); });
break;
case EMS_DEVICE_FLAG_RC20_2:
register_mqtt_cmd(F("nighttemp"), [&](const char * value, const int8_t id) { return set_nighttemp(value, id); });
@@ -1911,6 +2016,8 @@ void Thermostat::add_commands() {
register_mqtt_cmd(F("designtemp"), [&](const char * value, const int8_t id) { return set_designtemp(value, id); });
register_mqtt_cmd(F("offsettemp"), [&](const char * value, const int8_t id) { return set_offsettemp(value, id); });
register_mqtt_cmd(F("holidaytemp"), [&](const char * value, const int8_t id) { return set_holidaytemp(value, id); });
+ register_mqtt_cmd(F("wwmode"), [&](const char * value, const int8_t id) { return set_wwmode(value, id); });
+ register_mqtt_cmd(F("wwcircmode"), [&](const char * value, const int8_t id) { return set_wwcircmode(value, id); });
break;
case EMS_DEVICE_FLAG_JUNKERS:
register_mqtt_cmd(F("nofrosttemp"), [&](const char * value, const int8_t id) { return set_nofrosttemp(value, id); });
diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h
index 7f2a604e3..2dd3c170f 100644
--- a/src/devices/thermostat.h
+++ b/src/devices/thermostat.h
@@ -62,6 +62,7 @@ class Thermostat : public EMSdevice {
uint8_t designtemp = EMS_VALUE_UINT_NOTSET; // heating curve design temp at MinExtTemp
int8_t offsettemp = EMS_VALUE_INT_NOTSET; // heating curve offest temp at roomtemp signed!
uint8_t manualtemp = EMS_VALUE_UINT_NOTSET;
+ uint8_t summer_setmode = EMS_VALUE_UINT_NOTSET;
uint8_t hc_num() const {
return hc_num_;
@@ -117,6 +118,7 @@ class Thermostat : public EMSdevice {
std::vector monitor_typeids;
std::vector set_typeids;
std::vector timer_typeids;
+ std::vector summer_typeids;
std::string datetime_; // date and time stamp
@@ -135,9 +137,10 @@ class Thermostat : public EMSdevice {
uint16_t tempsensor1_ = EMS_VALUE_USHORT_NOTSET;
uint16_t tempsensor2_ = EMS_VALUE_USHORT_NOTSET;
- uint8_t wwSystem_ = EMS_VALUE_UINT_NOTSET;
- uint8_t wwExtra_ = EMS_VALUE_UINT_NOTSET;
- uint8_t wwMode_ = EMS_VALUE_UINT_NOTSET;
+ uint8_t wwSystem_ = EMS_VALUE_UINT_NOTSET;
+ uint8_t wwExtra_ = EMS_VALUE_UINT_NOTSET;
+ uint8_t wwMode_ = EMS_VALUE_UINT_NOTSET;
+ uint8_t wwCircMode_ = EMS_VALUE_UINT_NOTSET;
std::vector> heating_circuits_; // each thermostat can have multiple heating circuits
@@ -240,11 +243,12 @@ class Thermostat : public EMSdevice {
void process_RC10Set(std::shared_ptr telegram);
void process_RC300Monitor(std::shared_ptr telegram);
void process_RC300Set(std::shared_ptr telegram);
+ void process_RC300Summer(std::shared_ptr telegram);
+ void process_RC300WWmode(std::shared_ptr telegram);
void process_JunkersMonitor(std::shared_ptr telegram);
void process_JunkersSet(std::shared_ptr telegram);
void process_JunkersSet2(std::shared_ptr telegram);
void process_EasyMonitor(std::shared_ptr telegram);
- void process_RC300WWmode(std::shared_ptr telegram);
// internal helper functions
bool set_mode_n(const uint8_t mode, const uint8_t hc_num);
@@ -259,6 +263,7 @@ class Thermostat : public EMSdevice {
bool set_holiday(const char * value, const int8_t id);
bool set_pause(const char * value, const int8_t id);
bool set_party(const char * value, const int8_t id);
+ bool set_summermode(const char * value, const int8_t id);
bool set_temp(const char * value, const int8_t id);
bool set_nighttemp(const char * value, const int8_t id);
@@ -276,6 +281,7 @@ class Thermostat : public EMSdevice {
// set functions - these don't use the id/hc, the parameters are ignored
bool set_wwmode(const char * value, const int8_t id);
+ bool set_wwcircmode(const char * value, const int8_t id);
bool set_datetime(const char * value, const int8_t id);
bool set_minexttemp(const char * value, const int8_t id);
bool set_clockoffset(const char * value, const int8_t id);
diff --git a/src/emsdevice.h b/src/emsdevice.h
index d50772921..f3d416226 100644
--- a/src/emsdevice.h
+++ b/src/emsdevice.h
@@ -192,7 +192,7 @@ class EMSdevice {
Value & value,
const __FlashStringHelper * suffix,
const uint8_t format = 0) {
-
+
// create the value as a string using the render_value function
char buffer[15];
if (Helpers::render_value(buffer, value, format) == nullptr) {
diff --git a/src/helpers.h b/src/helpers.h
index b84f4f699..034ddbe36 100644
--- a/src/helpers.h
+++ b/src/helpers.h
@@ -41,7 +41,7 @@ class Helpers {
static char * render_value(char * result, const uint32_t value, const uint8_t format);
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 * smallitoa(char * result, const uint8_t value);
diff --git a/src/system.cpp b/src/system.cpp
index 942c1dfef..cfdada737 100644
--- a/src/system.cpp
+++ b/src/system.cpp
@@ -30,12 +30,13 @@ uuid::syslog::SyslogService System::syslog_;
#endif
// init statics
-uint32_t System::heap_start_ = 0;
-int System::reset_counter_ = 0;
-bool System::upload_status_ = false;
-bool System::hide_led_ = false;
-uint8_t System::led_gpio_ = 0;
-uint16_t System::analog_ = 0;
+uint32_t System::heap_start_ = 0;
+int System::reset_counter_ = 0;
+bool System::upload_status_ = false;
+bool System::hide_led_ = false;
+uint8_t System::led_gpio_ = 0;
+uint16_t System::analog_ = 0;
+bool System::analog_enabled_ = false;
// send on/off to a gpio pin
// value: true = HIGH, false = LOW
@@ -162,7 +163,10 @@ void System::init() {
set_led(); // init LED
// set the boolean format used for rendering booleans
- EMSESP::emsespSettingsService.read([&](EMSESPSettings & settings) { Helpers::bool_format(settings.bool_format); });
+ EMSESP::emsespSettingsService.read([&](EMSESPSettings & settings) {
+ Helpers::bool_format(settings.bool_format);
+ analog_enabled_ = settings.analog_enabled;
+ });
EMSESP::init_tx(); // start UART
}
@@ -203,7 +207,9 @@ void System::loop() {
#endif
led_monitor(); // check status and report back using the LED
system_check(); // check system health
- measure_analog();
+ if (analog_enabled_) {
+ measure_analog();
+ }
// send out heartbeat
uint32_t currentMillis = uuid::get_uptime();
@@ -257,7 +263,9 @@ void System::send_heartbeat() {
doc["mqttpublishfails"] = Mqtt::publish_fails();
doc["txfails"] = EMSESP::txservice_.telegram_fail_count();
doc["rxfails"] = EMSESP::rxservice_.telegram_error_count();
- doc["adc"] = analog_; //analogRead(A0);
+ if (analog_enabled_) {
+ doc["adc"] = analog_;
+ }
Mqtt::publish_retain(F("heartbeat"), doc.as(), false); // send to MQTT with retain off. This will add to MQTT queue.
}
@@ -279,10 +287,10 @@ void System::measure_analog() {
if (!analog_) { // init first time
analog_ = a;
- sum_ = a * 256;
+ sum_ = a * 512;
} else { // simple moving average filter
- sum_ = sum_ * 255 / 256 + a;
- analog_ = sum_ / 256;
+ sum_ = (sum_ * 511) / 512 + a;
+ analog_ = sum_ / 512;
}
}
}
@@ -789,6 +797,7 @@ bool System::check_upgrade() {
settings.dallas_gpio = custom_settings["dallas_gpio"] | EMSESP_DEFAULT_DALLAS_GPIO;
settings.dallas_parasite = custom_settings["dallas_parasite"] | EMSESP_DEFAULT_DALLAS_PARASITE;
settings.led_gpio = custom_settings["led_gpio"] | EMSESP_DEFAULT_LED_GPIO;
+ settings.analog_enabled = EMSESP_DEFAULT_ANALOG_ENABLED;
return StateUpdateResult::CHANGED;
},
@@ -912,6 +921,7 @@ bool System::command_info(const char * value, const int8_t id, JsonObject & outp
node["hide_led"] = Helpers::render_boolean(s, settings.hide_led);
node["api_enabled"] = Helpers::render_boolean(s, settings.api_enabled);
node["bool_format"] = settings.bool_format;
+ node["analog_enabled"] = settings.analog_enabled;
});
#endif
diff --git a/src/system.h b/src/system.h
index 28059ed98..4b5e38336 100644
--- a/src/system.h
+++ b/src/system.h
@@ -74,7 +74,7 @@ class System {
static constexpr uint32_t LED_WARNING_BLINK = 1000; // pulse to show no connection, 1 sec
static constexpr uint32_t LED_WARNING_BLINK_FAST = 100; // flash quickly for boot up sequence
static constexpr uint32_t SYSTEM_HEARTBEAT_INTERVAL = 60000; // in milliseconds, how often the MQTT heartbeat is sent (1 min)
- static constexpr uint32_t SYSTEM_MEASURE_ANALOG_INTERVAL = 1100;
+ static constexpr uint32_t SYSTEM_MEASURE_ANALOG_INTERVAL = 500;
// internal LED
static constexpr uint8_t LED_ON = LOW;
@@ -103,6 +103,7 @@ class System {
uint32_t syslog_mark_interval_;
String syslog_host_;
static uint8_t led_gpio_;
+ static bool analog_enabled_;
};
} // namespace emsesp