mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-08 16:59:50 +03:00
Merge a30, fix summer/holidaymode, ww_mode in thermostat
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)) {
|
||||
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)) {
|
||||
} else if (Helpers::hasValue(hc->holiday_mode) && hc->holiday_mode) {
|
||||
shell.printfln(F(" Program is set to Holiday mode"));
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define EMSESP_APP_VERSION "2.0.0a29"
|
||||
#define EMSESP_APP_VERSION "2.0.0a30"
|
||||
|
||||
Reference in New Issue
Block a user