sync with dev

This commit is contained in:
proddy
2026-04-15 09:25:38 +02:00
parent 16c0370443
commit 4d3b31e5a1
67 changed files with 1747 additions and 1125 deletions

View File

@@ -83,20 +83,6 @@ void WebSettings::read(WebSettings & settings, JsonObject root) {
root["modbus_max_clients"] = settings.modbus_max_clients;
root["modbus_timeout"] = settings.modbus_timeout;
root["developer_mode"] = settings.developer_mode;
#ifndef NO_TLS_SUPPORT
root["email_enabled"] = settings.email_enabled;
#else
root["email_enabled"] = false;
#endif
root["email_ssl"] = settings.email_ssl;
root["email_starttls"] = settings.email_starttls;
root["email_server"] = settings.email_server;
root["email_port"] = settings.email_port;
root["email_login"] = settings.email_login;
root["email_pass"] = settings.email_pass;
root["email_sender"] = settings.email_sender;
root["email_recp"] = settings.email_recp;
root["email_subject"] = settings.email_subject;
}
// call on initialization and also when settings are updated/saved via web or console
@@ -257,9 +243,13 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) {
// Modbus settings
settings.modbus_enabled = root["modbus_enabled"] | EMSESP_DEFAULT_MODBUS_ENABLED;
check_flag(original_settings.modbus_enabled, settings.modbus_enabled, ChangeFlags::RESTART);
settings.modbus_port = root["modbus_port"] | EMSESP_DEFAULT_MODBUS_PORT;
check_flag(original_settings.modbus_port, settings.modbus_port, ChangeFlags::RESTART);
settings.modbus_max_clients = root["modbus_max_clients"] | EMSESP_DEFAULT_MODBUS_MAX_CLIENTS;
check_flag(original_settings.modbus_max_clients, settings.modbus_max_clients, ChangeFlags::RESTART);
settings.modbus_timeout = root["modbus_timeout"] | EMSESP_DEFAULT_MODBUS_TIMEOUT;
check_flag(original_settings.modbus_timeout, settings.modbus_timeout, ChangeFlags::RESTART);
//
// these may need mqtt restart to rebuild HA discovery topics
@@ -310,20 +300,6 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) {
settings.weblog_level = root["weblog_level"] | EMSESP_DEFAULT_WEBLOG_LEVEL;
settings.weblog_compact = root["weblog_compact"] | EMSESP_DEFAULT_WEBLOG_COMPACT;
settings.email_enabled = root["email_enabled"] | FACTORY_EMAIL_ENABLE;
settings.email_ssl = root["email_ssl"] | FACTORY_EMAIL_SSL;
settings.email_starttls = root["email_starttls"] | FACTORY_EMAIL_STARTTLS;
settings.email_server = root["email_server"] | FACTORY_EMAIL_SERVER;
settings.email_port = root["email_port"] | FACTORY_EMAIL_PORT;
settings.email_login = root["email_login"] | FACTORY_EMAIL_LOGIN;
settings.email_pass = root["email_pass"] | FACTORY_EMAIL_PASSWORD;
settings.email_sender = root["email_sender"] | FACTORY_EMAIL_FROM;
settings.email_recp = root["email_recp"] | FACTORY_EMAIL_TO;
settings.email_subject = root["email_subject"] | FACTORY_EMAIL_SUBJECT;
if (settings.email_ssl && settings.email_starttls) {
settings.email_ssl = false;
}
// if no psram limit weblog buffer to 25 messages
if (EMSESP::system_.PSram() > 0) {
settings.weblog_buffer = root["weblog_buffer"] | EMSESP_DEFAULT_WEBLOG_BUFFER;
@@ -482,14 +458,23 @@ void WebSettings::set_board_profile(WebSettings & settings) {
#if CONFIG_IDF_TARGET_ESP32
// check for no PSRAM, could be a E32 or S32?
if (!ESP.getPsramSize()) {
#if ESP_ARDUINO_VERSION_MAJOR < 3
if (ETH.begin(1, 16, 23, 18, ETH_PHY_LAN8720, ETH_CLOCK_GPIO0_IN)) {
#else
if (ETH.begin(ETH_PHY_LAN8720, 1, 23, 18, 16, ETH_CLOCK_GPIO0_IN)) {
#endif
settings.board_profile = "E32"; // Ethernet without PSRAM
} else {
settings.board_profile = "S32"; // ESP32 standard WiFi without PSRAM
}
} else {
// check for boards with PSRAM, could be a E32V2 otherwise default back to the S32
// check for boards with PSRAM, could be a E32V2 otherwise default back to the S32
#if ESP_ARDUINO_VERSION_MAJOR < 3
if (ETH.begin(0, 15, 23, 18, ETH_PHY_LAN8720, ETH_CLOCK_GPIO0_OUT)) {
#else
if (ETH.begin(ETH_PHY_LAN8720, 0, 23, 18, 15, ETH_CLOCK_GPIO0_OUT)) {
#endif
if (analogReadMilliVolts(39) > 700) { // core voltage > 2.6V
settings.board_profile = "E32V2_2"; // Ethernet, PSRAM, internal sensors
} else {
@@ -517,9 +502,9 @@ void WebSettings::set_board_profile(WebSettings & settings) {
#ifndef EMSESP_STANDALONE
uint32_t psram_size = ESP.getPsramSize() / 1024; // in KB
if (psram_size > 0) {
EMSESP::logger().info("Loaded board profile %s, PSRAM: %lu KB", settings.board_profile.c_str(), psram_size);
EMSESP::logger().info("Loaded board profile %s (PSRAM: %lu KB)", settings.board_profile.c_str(), psram_size);
} else {
EMSESP::logger().info("Loaded board profile %s, PSRAM: not available", settings.board_profile.c_str());
EMSESP::logger().info("Loaded board profile %s (PSRAM: not available)", settings.board_profile.c_str());
}
#endif

View File

@@ -216,6 +216,9 @@ void WebStatusService::action(AsyncWebServerRequest * request, JsonVariant json)
} else if (action == "resetMQTT" && is_admin) {
EMSESP::mqtt_.reset_mqtt();
ok = true;
} else if (action == "upgradeImportantMessages") {
root["upgradeImportantMessageType"] = upgradeImportantMessages(param);
ok = true;
}
#if defined(EMSESP_STANDALONE) && !defined(EMSESP_UNITY)
@@ -237,13 +240,75 @@ void WebStatusService::action(AsyncWebServerRequest * request, JsonVariant json)
request->send(response);
}
// action = upgradeImportantMessages
// returns the type of upgrade important message to display in the UI
// 0 = no message (if just a minor version upgrade)
// 1 = going from <= 3.8 to 3.9 (has new partition layout)
// 2 = major version upgrade
// version can be like 3.8.2 or a filename like EMS-ESP-3_8_2-dev_13-ESP32-16MB+.bin
uint8_t WebStatusService::upgradeImportantMessages(std::string & version) {
if (version.empty()) {
return 0;
}
// it's a filename with a .bin or .md extension, try and extract the version from it
// e.g. EMS-ESP-3_8_2-dev_13-ESP32-16MB+.bin -> major=3 minor=8 patch=2
version::Semver200_version latest_version;
if ((version.find(".bin") != std::string::npos) || (version.find(".md") != std::string::npos)) {
std::string filename = version;
auto pos = filename.find("EMS-ESP-");
if (pos == std::string::npos) {
EMSESP::logger().err("Invalid version string: %s", version.c_str());
return 0;
}
pos += 8; // skip past "EMS-ESP-"
auto underscore1 = filename.find('_', pos);
auto underscore2 = filename.find('_', underscore1 + 1);
auto dash = filename.find('-', underscore2 + 1);
if (underscore1 == std::string::npos || underscore2 == std::string::npos || dash == std::string::npos) {
EMSESP::logger().err("Invalid version string: %s", version.c_str());
return 0;
}
std::string major_version = filename.substr(pos, underscore1 - pos);
std::string minor_version = filename.substr(underscore1 + 1, underscore2 - underscore1 - 1);
std::string patch_version = filename.substr(underscore2 + 1, dash - underscore2 - 1);
latest_version = version::Semver200_version(major_version + "." + minor_version + "." + patch_version);
} else {
// if it's .json file exit
if (version.find(".json") != std::string::npos) {
return 0;
} else {
// treat it like a version string like "3.9.0"
latest_version = version::Semver200_version(version);
}
}
version::Semver200_version current_version(current_version_s); // get current version
if (latest_version > current_version && current_version.minor() < latest_version.minor()) {
return 0; // if it's just a minor version upgrade return 0
}
if ((current_version.major() <= 3 && current_version.minor() <= 8) && (latest_version.major() == 3 && latest_version.minor() == 9)) {
return 1; // if moving from below 3.8.x to 3.9.x return 1
}
if (latest_version > current_version && current_version.major() < latest_version.major()) {
return 2; // if it's a major version upgrade return 2
}
return 0; // if it's not a valid version upgrade return 0
}
// action = checkUpgrade
// versions holds the latest development version and stable version in one string, comma separated
bool WebStatusService::checkUpgrade(JsonObject root, std::string & versions) {
if (!versions.empty()) {
bool WebStatusService::checkUpgrade(JsonObject root, std::string & version) {
if (!version.empty()) {
version::Semver200_version current_version(current_version_s);
version::Semver200_version latest_dev_version(versions.substr(0, versions.find(',')));
version::Semver200_version latest_stable_version(versions.substr(versions.find(',') + 1));
version::Semver200_version latest_dev_version(version.substr(0, version.find(',')));
version::Semver200_version latest_stable_version(version.substr(version.find(',') + 1));
bool dev_upgradeable = latest_dev_version > current_version;
bool stable_upgradeable = latest_stable_version > current_version;
@@ -342,7 +407,7 @@ bool WebStatusService::getCustomSupport(JsonObject root) {
#if defined(EMSESP_STANDALONE)
// dummy test data for "test api3"
deserializeJson(doc, "{\"type\":\"customSupport\",\"Support\":{\"html\":[\"html code\",\"here\"], \"img_url\": \"https://emsesp.org/_media/images/designer.png\"}");
deserializeJson(doc, "{\"type\":\"customSupport\",\"Support\":{\"html\":[\"html code\",\"here\"], \"img_url\": \"https://emsesp.org/media/images/designer.png\"}");
#else
// check if we have custom support file uploaded
File file = LittleFS.open(EMSESP_CUSTOMSUPPORT_FILE, "r");

View File

@@ -30,12 +30,13 @@ class WebStatusService {
SecurityManager * _securityManager;
// actions
bool checkUpgrade(JsonObject root, std::string & latest_version);
bool exportData(JsonObject root, std::string & type);
bool getCustomSupport(JsonObject root);
bool uploadURL(const char * url);
bool setSystemStatus(const char * status);
void allvalues(JsonObject output);
bool checkUpgrade(JsonObject root, std::string & latest_version);
bool exportData(JsonObject root, std::string & type);
bool getCustomSupport(JsonObject root);
bool uploadURL(const char * url);
bool setSystemStatus(const char * status);
void allvalues(JsonObject output);
uint8_t upgradeImportantMessages(std::string & version);
std::string current_version_s = EMSESP_APP_VERSION;
};