Merge a30, fix summer/holidaymode, ww_mode in thermostat

This commit is contained in:
MichaelDvP
2020-06-28 07:08:41 +02:00
7 changed files with 125 additions and 44 deletions

View File

@@ -95,6 +95,15 @@ void Boiler::boiler_cmd(const char * message) {
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);
}
const char * command = doc["cmd"];
if (command == nullptr) {
return;
@@ -695,25 +704,23 @@ void Boiler::set_flow_temp(const uint8_t temperature) {
}
// 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) {
uint8_t set;
if (comfort == 1) {
LOG_INFO(F("Setting boiler warm water to hot"));
set = 0;
LOG_INFO(F("Setting boiler warm water to Hot"));
set = 0x00;
} else if (comfort == 2) {
LOG_INFO(F("Setting boiler warm water to eco"));
LOG_INFO(F("Setting boiler warm water to Eco"));
set = 0xD8;
} else if (comfort == 3) {
LOG_INFO(F("Setting boiler warm water to intelligent"));
LOG_INFO(F("Setting boiler warm water to Intelligent"));
set = 0xEC;
} else {
return; // do nothing
}
write_command(EMS_TYPE_UBAParameterWW, 9, set);
// some boilers do not have this setting, than it's done by thermostat
// Test for RC35, but not a good way, we are here in boiler context.
// EMSESP::send_write_request(0x37, 0x10, 2, &set, 1, 0); // for RC35, maybe work also on RC300
}
// turn on/off warm water

View File

@@ -22,6 +22,7 @@ MAKE_PSTR_WORD(thermostat)
MAKE_PSTR_WORD(master)
MAKE_PSTR_WORD(temp)
MAKE_PSTR_WORD(mode)
MAKE_PSTR_WORD(wwmode)
MAKE_PSTR(hc_optional, "[heating circuit]")
MAKE_PSTR(mode_mandatory, "<mode>")
@@ -238,6 +239,7 @@ void Thermostat::thermostat_cmd(const char * message) {
return;
}
// check for nested commands like {"hc2":{"temp":21}}
for (const auto & hc : heating_circuits_) {
char hc_name[6], s[3]; // hc{1-4}
strlcpy(hc_name, "hc", 6);
@@ -295,7 +297,15 @@ void Thermostat::thermostat_cmd(const char * message) {
set_settings_minexttemp(mt);
}
if (nullptr != doc["building"]) {
std::string bds = doc["building"];
uint8_t bd = doc["building"];
if (strcmp(bds.c_str(), "light") == 0) {
bd = 0;
} else if (strcmp(bds.c_str(), "medium") == 0) {
bd = 1;
} else if (strcmp(bds.c_str(), "heavy") == 0) {
bd = 2;
}
set_settings_building(bd);
}
if (nullptr != doc["language"]) {
@@ -311,20 +321,62 @@ void Thermostat::thermostat_cmd(const char * message) {
set_settings_clockoffset(co);
}
// get heating circuit if it exists
uint8_t hc_num = doc["hc"] | AUTO_HEATING_CIRCUIT;
// check for unnested commands like {"temp":21} or {"hc":2,"temp":21,"mode":"auto"}
if (nullptr != doc["mode"]) {
std::string mode = doc["mode"]; // first check mode
set_mode(mode, hc_num);
}
if (float f = doc["temp"]) {
set_temperature(f, HeatingCircuit::Mode::AUTO, hc_num);
}
if (float f = doc["nighttemp"]) {
set_temperature(f, HeatingCircuit::Mode::NIGHT, hc_num);
}
if (float f = doc["daytemp"]) {
set_temperature(f, HeatingCircuit::Mode::DAY, hc_num);
}
if (float f = doc["nofrosttemp"]) {
set_temperature(f, HeatingCircuit::Mode::NOFROST, hc_num);
}
if (float f = doc["summertemp"]) {
set_temperature(f, HeatingCircuit::Mode::SUMMER, hc_num);
}
if (float f = doc["designtemp"]) {
set_temperature(f, HeatingCircuit::Mode::DESIGN, hc_num);
}
if (float f = doc["offsettemp"]) {
set_temperature(f, HeatingCircuit::Mode::OFFSET, hc_num);
}
if (float f = doc["holidaytemp"]) { //
set_temperature(f, HeatingCircuit::Mode::HOLIDAY, hc_num);
}
if (float f = doc["remotetemp"]) {
if (f > 100 || f < 0) {
Roomctrl::set_remotetemp(hc_num - 1, EMS_VALUE_SHORT_NOTSET);
} else {
Roomctrl::set_remotetemp(hc_num - 1, (int16_t)(f * 10));
}
}
if (nullptr != doc["control"]) {
uint8_t ctrl = doc["control"];
set_control(ctrl, hc_num);
}
// check for commands like {"hc":2,"cmd":"temp","data":21}
const char * command = doc["cmd"];
if (command == nullptr) {
return;
}
// get heating circuit if it exists
uint8_t hc_num = doc["hc"] | AUTO_HEATING_CIRCUIT;
if (strcmp(command, "temp") == 0) {
float f = doc["data"];
if (f) {
set_temperature(f, HeatingCircuit::Mode::AUTO, hc_num);
return;
}
return;
}
// thermostat mode changes
@@ -341,8 +393,8 @@ void Thermostat::thermostat_cmd(const char * message) {
float f = doc["data"];
if (f) {
set_temperature(f, HeatingCircuit::Mode::NIGHT, hc_num);
return;
}
return;
}
if (strcmp(command, "daytemp") == 0) {
@@ -597,9 +649,9 @@ void Thermostat::publish_values() {
// special handling of mode type, for the RC35 replace with summer/holiday if set
// https://github.com/proddy/EMS-ESP/issues/373#issuecomment-619810209
if (Helpers::hasValue(hc->summer_mode)) {
if (Helpers::hasValue(hc->summer_mode) && hc->summer_mode) {
dataThermostat["modetype"] = F("summer");
} else if (Helpers::hasValue(hc->holiday_mode)) {
} else if (Helpers::hasValue(hc->holiday_mode) && hc->holiday_mode) {
dataThermostat["modetype"] = F("holiday");
} else if (Helpers::hasValue(hc->mode_type)) {
dataThermostat["modetype"] = mode_tostring(hc->get_mode_type(flags));
@@ -839,7 +891,15 @@ 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 (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);
@@ -935,9 +995,9 @@ void Thermostat::show_values(uuid::console::Shell & shell) {
print_value(shell, 4, F("Mode Type"), mode_tostring(hc->get_mode_type(flags)).c_str());
}
if (Helpers::hasValue(hc->summer_mode)) {
shell.printfln(F(" Program is set to Summer mode"));
} else if (Helpers::hasValue(hc->holiday_mode)) {
if (Helpers::hasValue(hc->summer_mode) && hc->summer_mode) {
shell.printfln(F(" Program is set to Summer mode"));
} else if (Helpers::hasValue(hc->holiday_mode) && hc->holiday_mode) {
shell.printfln(F(" Program is set to Holiday mode"));
}
@@ -1079,7 +1139,7 @@ void Thermostat::process_RC300Monitor(std::shared_ptr<const Telegram> telegram)
std::shared_ptr<Thermostat::HeatingCircuit> hc = heating_circuit(telegram);
telegram->read_value(hc->curr_roomTemp, 0); // is * 10
telegram->read_bitvalue(hc->mode_type, 10, 1);
telegram->read_bitvalue(hc->mode, 10, 0); // bit 1, mode (auto=1 or manual=0)
@@ -1274,29 +1334,23 @@ void Thermostat::set_control(const uint8_t ctrl, const uint8_t hc_num) {
LOG_INFO(F("Setting circuit-control for hc%d to %d"), hc_num, ctrl);
write_command(set_typeids[hc->hc_num() - 1], 26, ctrl);
} else {
LOG_INFO(F("Setting circuit-control not possible"));
LOG_INFO(F("set circuit-control not supported"));
}
}
// Set the WW mode in 0x37, 0-off, 1-on, 2-auto
void Thermostat::set_ww_mode(const uint8_t mode) {
if (mode > 2) {
LOG_WARNING(F("set wWMode: Invalid control mode: %d"), mode);
return;
}
if ((flags() & 0x0F) == EMS_DEVICE_FLAG_RC35 || (flags() & 0x0F) == EMS_DEVICE_FLAG_RC30_1) {
LOG_INFO(F("Setting wWMode to %d"), mode);
write_command(0x37, 2, mode);
}
}
// sets the thermostat ww working mode, where mode is a string
void Thermostat::set_ww_mode(const std::string & mode) {
if (strcasecmp("off",mode.c_str()) == 0) {
set_ww_mode(0);
} if (strcasecmp("on",mode.c_str()) == 0) {
set_ww_mode(1);
LOG_INFO(F("Setting thermostat warm water mode to %s"), mode.c_str());
write_command(EMS_TYPE_wwSettings, 2, 0);
} else if (strcasecmp("on",mode.c_str()) == 0) {
LOG_INFO(F("Setting thermostat warm water mode to %s"), mode.c_str());
write_command(EMS_TYPE_wwSettings, 2, 1);
} else if (strcasecmp("auto",mode.c_str()) == 0) {
set_ww_mode(2);
LOG_INFO(F("Setting thermostat warm water mode to %s"), mode.c_str());
write_command(EMS_TYPE_wwSettings, 2, 2);
} else {
LOG_WARNING(F("set thermostat warm water mode: Invalid mode: %s"), mode.c_str());
}
}
@@ -1633,6 +1687,8 @@ void Thermostat::console_commands(Shell & shell, unsigned int context) {
uint8_t hc = (arguments.size() >= 2) ? arguments[1].at(0) - '0' : AUTO_HEATING_CIRCUIT;
if ((arguments.size() == 3)) {
set_temperature(atof(arguments.front().c_str()), arguments.back().c_str(), hc);
} else if (arguments[1].at(0) >= 'A') {
set_temperature(atof(arguments.front().c_str()), arguments.back().c_str(), AUTO_HEATING_CIRCUIT);
} else {
set_temperature(atof(arguments.front().c_str()), HeatingCircuit::Mode::AUTO, hc);
}
@@ -1665,7 +1721,7 @@ void Thermostat::console_commands(Shell & shell, unsigned int context) {
EMSESPShell::commands->add_command(
ShellContext::THERMOSTAT,
CommandFlags::ADMIN,
flash_string_vector{F_(change), F_(mode)},
flash_string_vector{F_(change), F_(wwmode)},
flash_string_vector{F_(mode_mandatory)},
[=](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments) {
set_ww_mode(arguments.front());

View File

@@ -250,7 +250,6 @@ class Thermostat : public EMSdevice {
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 uint8_t mode);
void set_ww_mode(const std::string & mode);
void set_mode(const uint8_t mode, const uint8_t hc_num);
void set_mode(const std::string & mode, const uint8_t hc_num);

View File

@@ -249,7 +249,7 @@ bool EMSdevice::handle_telegram(std::shared_ptr<const Telegram> telegram) {
return false;
}
LOG_DEBUG(F("Processing %s..."), uuid::read_flash_string(tf.telegram_type_name_).c_str());
LOG_DEBUG(F("Decoding %s"), uuid::read_flash_string(tf.telegram_type_name_).c_str());
tf.process_function_(telegram);
return true;
}

View File

@@ -868,7 +868,7 @@ void EMSESP::console_commands(Shell & shell, unsigned int context) {
uint8_t watch = emsesp::EMSESP::watch();
if (watch == WATCH_OFF) {
shell.printfln(F("Watching telegrams is off"));
shell.printfln(F("Watch is off"));
return;
}

View File

@@ -60,7 +60,7 @@ void EMSuart::emsuart_recvTask(void * para) {
void IRAM_ATTR EMSuart::emsuart_rx_intr_handler(void * para) {
static uint8_t rxbuf[EMS_MAXBUFFERSIZE];
static uint8_t length;
UART_MUTEX_LOCK();
if (EMS_UART.int_st.rxfifo_full) {
EMS_UART.int_clr.rxfifo_full = 1;
emsTxBufIdx++;
@@ -93,6 +93,7 @@ void IRAM_ATTR EMSuart::emsuart_rx_intr_handler(void * para) {
xRingbufferSendFromISR(buf_handle, rxbuf, length - 1, &baseType);
}
drop_next_rx = false;
UART_MUTEX_UNLOCK();
}
}
@@ -101,16 +102,17 @@ void IRAM_ATTR EMSuart::emsuart_tx_timer_intr_handler() {
if (emsTxBufIdx > EMS_MAXBUFFERSIZE) {
return;
}
UART_MUTEX_LOCK();
emsTxBufIdx++;
if (emsTxBufIdx < emsTxBufLen) {
EMS_UART.fifo.rw_byte = emsTxBuf[emsTxBufIdx];
timerWrite(timer, 0);
timerAlarmWrite(timer, emsTxWait, false);
timerAlarmEnable(timer);
} else if (emsTxBufIdx == emsTxBufLen) {
EMS_UART.conf0.txd_brk = 1; // <brk> after send
}
UART_MUTEX_UNLOCK();
}
/*
@@ -124,6 +126,7 @@ void EMSuart::start(uint8_t tx_mode) {
return;
}
tx_mode_ = tx_mode;
UART_MUTEX_LOCK();
uart_config_t uart_config = {
.baud_rate = EMSUART_BAUD,
@@ -148,20 +151,24 @@ void EMSuart::start(uint8_t tx_mode) {
emsTxBufLen = 0;
timer = timerBegin(1, 80, true); // timer prescale to 1 µs, countup
timerAttachInterrupt(timer, &emsuart_tx_timer_intr_handler, true); // Timer with edge interrupt
UART_MUTEX_UNLOCK();
}
/*
* Stop, disables interrupt
*/
void EMSuart::stop() {
UART_MUTEX_LOCK();
EMS_UART.int_ena.val = 0; // disable all intr.
// timerAlarmDisable(timer);
UART_MUTEX_UNLOCK();
};
/*
* Restart Interrupt
*/
void EMSuart::restart() {
UART_MUTEX_LOCK();
if (EMS_UART.int_raw.brk_det) {
EMS_UART.int_clr.brk_det = 1; // clear flag
drop_next_rx = true; // and drop first frame
@@ -169,6 +176,7 @@ void EMSuart::restart() {
EMS_UART.int_ena.brk_det = 1; // activate only break
emsTxBufIdx = 0;
emsTxBufLen = 0;
UART_MUTEX_UNLOCK();
}
/*
@@ -176,10 +184,12 @@ void EMSuart::restart() {
*/
void EMSuart::send_poll(uint8_t data) {
// if (tx_mode_ >= 6 || tx_mode_ < 4) { // modes 1, 2, 3 also here
UART_MUTEX_LOCK();
if (tx_mode_ >= 5) {
EMS_UART.fifo.rw_byte = data;
emsTxBufIdx = 0;
emsTxBufLen = 1;
timerWrite(timer, 0);
timerAlarmWrite(timer, emsTxWait, false);
timerAlarmEnable(timer);
} else if (tx_mode_ == 5) {
@@ -212,6 +222,7 @@ void EMSuart::send_poll(uint8_t data) {
}
EMS_UART.conf0.txd_brk = 1; // <brk>
}
UART_MUTEX_UNLOCK();
}
/*
@@ -223,6 +234,7 @@ uint16_t EMSuart::transmit(uint8_t * buf, uint8_t len) {
if (len == 0 || len >= EMS_MAXBUFFERSIZE) {
return EMS_TX_STATUS_ERR;
}
UART_MUTEX_LOCK();
// if (tx_mode_ >= 6 || tx_mode_ < 4) { // timer controlled modes, also modes 1, 2, 3 because delays not working
if (tx_mode_ >= 5) { // timer controlled modes
@@ -232,8 +244,10 @@ uint16_t EMSuart::transmit(uint8_t * buf, uint8_t len) {
EMS_UART.fifo.rw_byte = buf[0];
emsTxBufIdx = 0;
emsTxBufLen = len;
timerWrite(timer, 0);
timerAlarmWrite(timer, emsTxWait, false);
timerAlarmEnable(timer);
UART_MUTEX_UNLOCK();
return EMS_TX_STATUS_OK;
}
@@ -246,6 +260,7 @@ uint16_t EMSuart::transmit(uint8_t * buf, uint8_t len) {
emsTxBufLen = len;
EMS_UART.conf1.rxfifo_full_thrhd = 1;
EMS_UART.int_ena.rxfifo_full = 1;
UART_MUTEX_UNLOCK();
return EMS_TX_STATUS_OK;
}
@@ -254,6 +269,7 @@ uint16_t EMSuart::transmit(uint8_t * buf, uint8_t len) {
EMS_UART.fifo.rw_byte = buf[i];
}
EMS_UART.conf0.txd_brk = 1; // <brk> after send
UART_MUTEX_UNLOCK();
return EMS_TX_STATUS_OK;
}
@@ -265,6 +281,7 @@ uint16_t EMSuart::transmit(uint8_t * buf, uint8_t len) {
EMS_UART.conf0.txd_brk = 1; // <brk> after send, cleard by hardware after send
// delayMicroseconds(EMSUART_TX_WAIT_BRK);
// EMS_UART.conf0.txd_brk = 0;
UART_MUTEX_UNLOCK();
return EMS_TX_STATUS_OK;
}
@@ -276,6 +293,7 @@ uint16_t EMSuart::transmit(uint8_t * buf, uint8_t len) {
EMS_UART.conf0.txd_brk = 1; // <brk> after send, cleard by hardware after send
// delayMicroseconds(EMSUART_TX_WAIT_BRK);
// EMS_UART.conf0.txd_brk = 0;
UART_MUTEX_UNLOCK();
return EMS_TX_STATUS_OK;
}
@@ -294,6 +312,7 @@ uint16_t EMSuart::transmit(uint8_t * buf, uint8_t len) {
EMS_UART.conf0.txd_brk = 1; // <brk> after send, cleard by hardware after send
// delayMicroseconds(EMSUART_TX_WAIT_BRK);
// EMS_UART.conf0.txd_brk = 0;
UART_MUTEX_UNLOCK();
return EMS_TX_STATUS_OK;
}

View File

@@ -1 +1 @@
#define EMSESP_APP_VERSION "2.0.0a29"
#define EMSESP_APP_VERSION "2.0.0a30"