mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-08 00:39:50 +03:00
Merge branch 'v2' of https://github.com/proddy/EMS-ESP into v2
This commit is contained in:
@@ -344,7 +344,7 @@ void Boiler::show_values(uuid::console::Shell & shell) {
|
||||
}
|
||||
|
||||
print_value(shell, 2, F("Warm Water activated"), Helpers::render_value(buffer, wWActivated_, EMS_VALUE_BOOL));
|
||||
print_value(shell, 2, F("Warm Water charging type"), wWCircPumpType_ ? "3-way valve" : "charge pump");
|
||||
print_value(shell, 2, F("Warm Water charging type"), wWCircPumpType_ ? "3-way valve" : "charge pump");
|
||||
print_value(shell, 2, F("Warm Water circulation pump available"), Helpers::render_value(buffer, wWCircPump_, EMS_VALUE_BOOL));
|
||||
if (wWCircPumpMode_ == 7) {
|
||||
print_value(shell, 2, F("Warm Water circulation pump freq"), "continuous");
|
||||
|
||||
@@ -110,22 +110,22 @@ void EMSESP::trace_watch_id(uint16_t trace_watch_id) {
|
||||
}
|
||||
}
|
||||
|
||||
// show the Rx and Tx queues
|
||||
// show the EMS bus status plus both Rx and Tx queues
|
||||
void EMSESP::show_emsbus(uuid::console::Shell & shell) {
|
||||
// EMS bus specific
|
||||
// EMS bus information
|
||||
if (rxservice_.bus_connected()) {
|
||||
uint8_t success_rate = 0;
|
||||
if (rxservice_.telegram_error_count()) {
|
||||
success_rate = ((float)rxservice_.telegram_error_count() / (float)rxservice_.telegram_count()) * 100;
|
||||
}
|
||||
|
||||
shell.printfln(F("EMS Bus protocol: %s, #telegrams received: %d, #Read requests sent: %d, #Write requests sent: %d, #CRC errors: %d (%d%%)"),
|
||||
EMSbus::is_ht3() ? F("HT3") : F("Buderus"),
|
||||
rxservice_.telegram_count(),
|
||||
txservice_.telegram_read_count(),
|
||||
txservice_.telegram_write_count(),
|
||||
rxservice_.telegram_error_count(),
|
||||
success_rate);
|
||||
shell.printfln(F("EMS Bus info:"));
|
||||
shell.printfln(F(" Bus protocol: %s"), EMSbus::is_ht3() ? F("HT3") : F("Buderus"));
|
||||
shell.printfln(F(" #telegrams received: %d"), rxservice_.telegram_count());
|
||||
shell.printfln(F(" #read requests sent: %d"), txservice_.telegram_read_count());
|
||||
shell.printfln(F(" #write requests sent: %d"), txservice_.telegram_write_count());
|
||||
shell.printfln(F(" #CRC errors: %d (%d%%)"), rxservice_.telegram_error_count(), success_rate);
|
||||
shell.printfln(F(" #Tx fails: %d"), txservice_.telegram_fail_count());
|
||||
} else {
|
||||
shell.printfln(F("EMS Bus is disconnected"));
|
||||
}
|
||||
@@ -570,21 +570,21 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) {
|
||||
}
|
||||
|
||||
// are we waiting for a response from a recent Tx Read or Write?
|
||||
bool tx_successful = false;
|
||||
if (EMSbus::tx_waiting()) {
|
||||
// if it's a single byte 1 or 4 then its maybe a response from the last write action
|
||||
EMSbus::tx_waiting(false); // reset Tx wait state
|
||||
|
||||
// if it's a single byte 1 or 4 then its maybe a response from the last write action
|
||||
if (length == 1) {
|
||||
if (first_value == TxService::TX_WRITE_SUCCESS) {
|
||||
LOG_DEBUG(F("Last Tx write successful. Sending read request."));
|
||||
txservice_.increment_telegram_write_count(); // last tx/write was confirmed ok
|
||||
txservice_.send_poll(); // close the bus
|
||||
txservice_.post_send_query(); // send type_id to last destination
|
||||
txservice_.post_send_query(); // follow up with any post-read
|
||||
tx_successful = true;
|
||||
} else if (first_value == TxService::TX_WRITE_FAIL) {
|
||||
LOG_ERROR(F("Last Tx write rejected by host"));
|
||||
txservice_.send_poll(); // close the bus
|
||||
} else {
|
||||
// ignore it, it's probably a poll and we can wait for the next one
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// got a telegram with data in it. See if the src/dest matches that from the last one we sent
|
||||
@@ -594,18 +594,24 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) {
|
||||
if (txservice_.is_last_tx(src, dest)) {
|
||||
LOG_DEBUG(F("Last Tx read successful"));
|
||||
txservice_.increment_telegram_read_count();
|
||||
txservice_.send_poll();
|
||||
} else {
|
||||
// the telegram we got wasn't what we had requested
|
||||
// So re-send the last Tx and increment retry count
|
||||
uint8_t retries = txservice_.retry_tx(); // returns 0 if exceeded count
|
||||
if (retries) {
|
||||
LOG_ERROR(F("Last Tx read failed. Retrying #%d..."), retries);
|
||||
} else {
|
||||
LOG_ERROR(F("Last Tx read failed after %d retries"), txservice_.MAXIMUM_TX_RETRIES);
|
||||
}
|
||||
txservice_.send_poll(); // close the bus
|
||||
tx_successful = true;
|
||||
}
|
||||
}
|
||||
|
||||
// if Tx wasn't successful, retry
|
||||
if (!tx_successful) {
|
||||
// the telegram we got wasn't what we had requested
|
||||
// So re-send the last Tx and increment retry count
|
||||
uint8_t retries = txservice_.retry_tx(); // returns 0 if exceeded count
|
||||
if (retries) {
|
||||
LOG_ERROR(F("Last Tx operation failed. Retrying #%d..."), retries);
|
||||
} else {
|
||||
LOG_ERROR(F("Last Tx operation failed after %d retries. Ignoring request."), txservice_.MAXIMUM_TX_RETRIES);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// check for poll
|
||||
@@ -825,7 +831,6 @@ void EMSESP::loop() {
|
||||
shower_.loop(); // check for shower on/off
|
||||
sensors_.loop(); // this will also send out via MQTT
|
||||
console_.loop(); // telnet/serial console
|
||||
delay(ESP_DELAY); // some time to WiFi and everything else to catch up, calls yield, and also prevent overheating
|
||||
|
||||
// force a query on the EMS devices to fetch latest data at a set interval (1 min)
|
||||
if ((uuid::get_uptime() - last_fetch_ > EMS_FETCH_FREQUENCY)) {
|
||||
@@ -833,7 +838,7 @@ void EMSESP::loop() {
|
||||
fetch_device_values();
|
||||
}
|
||||
|
||||
// helps ease wifi outages
|
||||
// helps ease wifi dropouts effecting MQTT and Telnet services
|
||||
// https://github.com/esp8266/Arduino/blob/e721089e601985e633641ab7323f81a84ea0cd1b/cores/esp8266/core_esp8266_wiring.cpp#L41-L57
|
||||
delay(1);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,6 @@
|
||||
#include "roomcontrol.h"
|
||||
|
||||
#define LOG_TRACE_WATCH_NONE 0 // no watch set
|
||||
#define ESP_DELAY 1
|
||||
|
||||
namespace emsesp {
|
||||
|
||||
|
||||
@@ -24,5 +24,4 @@ void setup() {
|
||||
|
||||
void loop() {
|
||||
emsesp::EMSESP::loop();
|
||||
yield();
|
||||
}
|
||||
|
||||
@@ -369,7 +369,7 @@ void Mqtt::show_topic_handlers(uuid::console::Shell & shell, const uint8_t devic
|
||||
return;
|
||||
}
|
||||
|
||||
shell.print(F(" These MQTT topics are registered: "));
|
||||
shell.print(F(" Subscribed MQTT topics: "));
|
||||
for (const auto & mqtt_function : mqtt_functions_) {
|
||||
if (mqtt_function.device_id_ == device_id) {
|
||||
shell.printf(F("%s "), mqtt_function.topic_.c_str());
|
||||
|
||||
@@ -69,7 +69,7 @@ class Sensors {
|
||||
#ifdef WEMOS_D1_32
|
||||
static constexpr uint8_t SENSOR_GPIO = 18; // Wemos D1-32 for compatibility D5
|
||||
#else
|
||||
static constexpr uint8_t SENSOR_GPIO = 14;
|
||||
static constexpr uint8_t SENSOR_GPIO = 14; // D5 is LED on wemos lolin D32, so use GPIO14
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ void System::start() {
|
||||
// register MQTT system commands
|
||||
Mqtt::subscribe("cmd", std::bind(&System::mqtt_commands, this, _1));
|
||||
|
||||
// RTC state variables - onky for ESP8266
|
||||
// RTC state variables - only for ESP8266
|
||||
#if defined(ESP8266)
|
||||
state_.registerVar(&reset_counter_); // we send a pointer to each of our variables
|
||||
state_.registerVar(&safe_mode_);
|
||||
|
||||
@@ -388,10 +388,9 @@ void TxService::send() {
|
||||
return;
|
||||
}
|
||||
|
||||
// if there's nothing in the queue to send
|
||||
// optionally, send back a poll and quit
|
||||
// if there's nothing in the queue to transmit, send back a poll and quit
|
||||
if (tx_telegrams_.empty()) {
|
||||
// send_poll(); // TODO commented out poll for now. should add back when stable.
|
||||
send_poll();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -409,7 +408,7 @@ void TxService::send_telegram(const QueuedTxTelegram & tx_telegram) {
|
||||
// build the header
|
||||
auto telegram = tx_telegram.telegram_;
|
||||
|
||||
// src - set MSB if its Junkers/HT3
|
||||
// src - set MSB if it's Junkers/HT3
|
||||
uint8_t src = telegram->src;
|
||||
if (ems_mask() != EMS_MASK_UNSET) {
|
||||
src ^= ems_mask();
|
||||
@@ -484,7 +483,10 @@ void TxService::send_telegram(const QueuedTxTelegram & tx_telegram) {
|
||||
|
||||
// send the telegram to the UART Tx
|
||||
EMSUART_STATUS status = EMSuart::transmit(telegram_raw, length);
|
||||
//LOG_TRACE(F("Tx: %s"), Helpers::data_to_hex(telegram_raw, length).c_str());
|
||||
#ifdef EMSESP_DEBUG
|
||||
LOG_TRACE(F("Tx: %s"), Helpers::data_to_hex(telegram_raw, length).c_str());
|
||||
#endif
|
||||
|
||||
if (status != EMS_TX_STATUS_OK) {
|
||||
LOG_ERROR(F("Failed to transmit Tx via UART. Error: %s"), status == EMS_TX_WTD_TIMEOUT ? F("Timeout") : F("BRK"));
|
||||
}
|
||||
@@ -609,10 +611,13 @@ void TxService::remember_tx(const uint8_t * data, const uint8_t length) {
|
||||
// returns retry count, or 0 if all done
|
||||
uint8_t TxService::retry_tx() {
|
||||
if (++retry_count_ == MAXIMUM_TX_RETRIES) {
|
||||
reset_retry_count(); // give up
|
||||
} else {
|
||||
add(telegram_last_, telegram_last_length_); // add the last Tx telegram to the tx queue, at the top
|
||||
reset_retry_count(); // give up
|
||||
increment_telegram_fail_count(); // another Tx fail
|
||||
return 0;
|
||||
}
|
||||
|
||||
add(telegram_last_, telegram_last_length_); // add the last Tx telegram to the tx queue, at the top
|
||||
|
||||
return retry_count_;
|
||||
}
|
||||
|
||||
|
||||
@@ -270,6 +270,14 @@ class TxService : public EMSbus {
|
||||
telegram_read_count_++;
|
||||
}
|
||||
|
||||
uint16_t telegram_fail_count() const {
|
||||
return telegram_fail_count_;
|
||||
}
|
||||
|
||||
void increment_telegram_fail_count() {
|
||||
telegram_fail_count_++;
|
||||
}
|
||||
|
||||
uint16_t telegram_write_count() const {
|
||||
return telegram_write_count_;
|
||||
}
|
||||
@@ -312,6 +320,7 @@ class TxService : public EMSbus {
|
||||
const std::shared_ptr<const Telegram> telegram_last; // copy of last telegram
|
||||
uint16_t telegram_read_count_ = 0; // # Tx successful reads
|
||||
uint16_t telegram_write_count_ = 0; // # Tx successful writes
|
||||
uint16_t telegram_fail_count_ = 0; // # Tx unsuccessful transmits
|
||||
|
||||
uint8_t retry_count_ = 0; // count for # Tx retries
|
||||
|
||||
|
||||
@@ -1527,15 +1527,14 @@ void Thermostat::console_commands(Shell & shell, unsigned int context) {
|
||||
EMSESPShell::commands->add_command(ShellContext::THERMOSTAT,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(change), F_(temp)},
|
||||
flash_string_vector{F_(degrees_mandatory), F_(hc_optional),F_(mode_optional)},
|
||||
flash_string_vector{F_(degrees_mandatory), F_(hc_optional), F_(mode_optional)},
|
||||
[=](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments) {
|
||||
uint8_t hc = (arguments.size() >= 2) ? arguments[1].at(0) - '0' : DEFAULT_HEATING_CIRCUIT;
|
||||
if ((arguments.size() == 3)) {
|
||||
set_temperature(atof(arguments.front().c_str()), arguments.back().c_str(), hc);
|
||||
} else {
|
||||
set_temperature(atof(arguments.front().c_str()), HeatingCircuit::Mode::AUTO, hc);
|
||||
}
|
||||
|
||||
uint8_t hc = (arguments.size() >= 2) ? arguments[1].at(0) - '0' : DEFAULT_HEATING_CIRCUIT;
|
||||
if ((arguments.size() == 3)) {
|
||||
set_temperature(atof(arguments.front().c_str()), arguments.back().c_str(), hc);
|
||||
} else {
|
||||
set_temperature(atof(arguments.front().c_str()), HeatingCircuit::Mode::AUTO, hc);
|
||||
}
|
||||
});
|
||||
|
||||
EMSESPShell::commands->add_command(
|
||||
@@ -1544,7 +1543,7 @@ void Thermostat::console_commands(Shell & shell, unsigned int context) {
|
||||
flash_string_vector{F_(change), F_(mode)},
|
||||
flash_string_vector{F_(mode_mandatory), F_(hc_optional)},
|
||||
[=](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments) {
|
||||
uint8_t hc = (arguments.size() == 2) ? arguments[1].at(0) - '0' : DEFAULT_HEATING_CIRCUIT;
|
||||
uint8_t hc = (arguments.size() == 2) ? arguments[1].at(0) - '0' : DEFAULT_HEATING_CIRCUIT;
|
||||
set_mode(arguments.front(), hc);
|
||||
},
|
||||
[](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments __attribute__((unused))) -> const std::vector<std::string> {
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define EMSESP_APP_VERSION "2.0.0a12"
|
||||
#define EMSESP_APP_VERSION "2.0.0a13"
|
||||
|
||||
Reference in New Issue
Block a user