mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2026-01-26 16:49:11 +03:00
Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev
This commit is contained in:
@@ -58,12 +58,12 @@ enum APNetworkStatus { ACTIVE = 0, INACTIVE, LINGERING };
|
||||
|
||||
class APSettings {
|
||||
public:
|
||||
uint8_t provisionMode; // 0 = on, 2 = off
|
||||
String ssid;
|
||||
String password;
|
||||
uint8_t channel;
|
||||
bool ssidHidden;
|
||||
uint8_t maxClients;
|
||||
uint8_t provisionMode = FACTORY_AP_PROVISION_MODE; // 0 = on, 2 = off
|
||||
String ssid = FACTORY_AP_SSID;
|
||||
String password = FACTORY_AP_PASSWORD;
|
||||
uint8_t channel = FACTORY_AP_CHANNEL;
|
||||
bool ssidHidden = FACTORY_AP_SSID_HIDDEN;
|
||||
uint8_t maxClients = FACTORY_AP_MAX_CLIENTS;
|
||||
|
||||
IPAddress localIP;
|
||||
IPAddress gatewayIP;
|
||||
|
||||
@@ -70,6 +70,10 @@ class FSPersistence {
|
||||
|
||||
// failed to open file, return false
|
||||
if (!settingsFile || !jsonObject.size()) {
|
||||
#if defined(EMSESP_DEBUG)
|
||||
Serial.printf("Failed to write file %s", _filePath);
|
||||
Serial.println();
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <espMqttClient.h>
|
||||
|
||||
#include <uuid/common.h>
|
||||
#include <default_settings.h>
|
||||
|
||||
#define MQTT_RECONNECTION_DELAY 2000 // 2 seconds
|
||||
|
||||
@@ -65,37 +66,37 @@
|
||||
|
||||
class MqttSettings {
|
||||
public:
|
||||
bool enabled;
|
||||
String host;
|
||||
uint16_t port;
|
||||
String rootCA;
|
||||
bool enableTLS;
|
||||
String username;
|
||||
String password;
|
||||
bool enabled = FACTORY_MQTT_ENABLED;
|
||||
String host = FACTORY_MQTT_HOST;
|
||||
uint16_t port = FACTORY_MQTT_PORT;
|
||||
String rootCA = "";
|
||||
bool enableTLS = false;
|
||||
String username = FACTORY_MQTT_USERNAME;
|
||||
String password = FACTORY_MQTT_PASSWORD;
|
||||
String clientId;
|
||||
uint16_t keepAlive;
|
||||
bool cleanSession;
|
||||
uint16_t keepAlive = FACTORY_MQTT_KEEP_ALIVE;
|
||||
bool cleanSession = FACTORY_MQTT_CLEAN_SESSION;
|
||||
|
||||
// EMS-ESP specific
|
||||
String base;
|
||||
uint16_t publish_time_boiler;
|
||||
uint16_t publish_time_thermostat;
|
||||
uint16_t publish_time_solar;
|
||||
uint16_t publish_time_mixer;
|
||||
uint16_t publish_time_water;
|
||||
uint16_t publish_time_other;
|
||||
uint16_t publish_time_sensor;
|
||||
uint16_t publish_time_heartbeat;
|
||||
uint8_t mqtt_qos;
|
||||
bool mqtt_retain;
|
||||
bool ha_enabled;
|
||||
uint8_t nested_format;
|
||||
String discovery_prefix;
|
||||
uint8_t discovery_type;
|
||||
bool publish_single;
|
||||
bool publish_single2cmd;
|
||||
bool send_response;
|
||||
uint8_t entity_format;
|
||||
String base = FACTORY_MQTT_BASE;
|
||||
uint16_t publish_time_boiler = EMSESP_DEFAULT_PUBLISH_TIME;
|
||||
uint16_t publish_time_thermostat = EMSESP_DEFAULT_PUBLISH_TIME;
|
||||
uint16_t publish_time_solar = EMSESP_DEFAULT_PUBLISH_TIME;
|
||||
uint16_t publish_time_mixer = EMSESP_DEFAULT_PUBLISH_TIME;
|
||||
uint16_t publish_time_water = EMSESP_DEFAULT_PUBLISH_TIME;
|
||||
uint16_t publish_time_other = EMSESP_DEFAULT_PUBLISH_TIME_OTHER;
|
||||
uint16_t publish_time_sensor = EMSESP_DEFAULT_PUBLISH_TIME;
|
||||
uint16_t publish_time_heartbeat = EMSESP_DEFAULT_PUBLISH_HEARTBEAT;
|
||||
uint8_t mqtt_qos = EMSESP_DEFAULT_MQTT_QOS;
|
||||
bool mqtt_retain = EMSESP_DEFAULT_MQTT_RETAIN;
|
||||
bool ha_enabled = EMSESP_DEFAULT_HA_ENABLED;
|
||||
uint8_t nested_format = EMSESP_DEFAULT_NESTED_FORMAT;
|
||||
String discovery_prefix = EMSESP_DEFAULT_DISCOVERY_PREFIX;
|
||||
uint8_t discovery_type = EMSESP_DEFAULT_DISCOVERY_TYPE;
|
||||
bool publish_single = EMSESP_DEFAULT_PUBLISH_SINGLE;
|
||||
bool publish_single2cmd = EMSESP_DEFAULT_PUBLISH_SINGLE2CMD;
|
||||
bool send_response = EMSESP_DEFAULT_SEND_RESPONSE;
|
||||
uint8_t entity_format = EMSESP_DEFAULT_ENTITY_FORMAT;
|
||||
|
||||
static void read(MqttSettings & settings, JsonObject root);
|
||||
static StateUpdateResult update(JsonObject root, MqttSettings & settings);
|
||||
|
||||
@@ -30,10 +30,10 @@
|
||||
|
||||
class NTPSettings {
|
||||
public:
|
||||
bool enabled;
|
||||
String tzLabel;
|
||||
String tzFormat;
|
||||
String server;
|
||||
bool enabled = FACTORY_NTP_ENABLED;
|
||||
String tzLabel = FACTORY_NTP_TIME_ZONE_LABEL;
|
||||
String tzFormat = FACTORY_NTP_TIME_ZONE_FORMAT;
|
||||
String server = FACTORY_NTP_SERVER;
|
||||
|
||||
static void read(NTPSettings & settings, JsonObject root);
|
||||
static StateUpdateResult update(JsonObject root, NTPSettings & settings);
|
||||
|
||||
@@ -64,17 +64,17 @@
|
||||
class NetworkSettings {
|
||||
public:
|
||||
// core wifi configuration
|
||||
String ssid;
|
||||
String bssid;
|
||||
String password;
|
||||
String hostname;
|
||||
bool staticIPConfig;
|
||||
bool bandwidth20;
|
||||
uint8_t tx_power;
|
||||
bool nosleep;
|
||||
bool enableMDNS;
|
||||
bool enableCORS;
|
||||
String CORSOrigin;
|
||||
String ssid = FACTORY_WIFI_SSID;
|
||||
String bssid = "";
|
||||
String password = FACTORY_WIFI_PASSWORD;
|
||||
String hostname = FACTORY_WIFI_HOSTNAME;
|
||||
bool staticIPConfig = false;
|
||||
bool bandwidth20 = false;
|
||||
uint8_t tx_power = 0;
|
||||
bool nosleep = true;
|
||||
bool enableMDNS = true;
|
||||
bool enableCORS = false;
|
||||
String CORSOrigin = "*";
|
||||
|
||||
// optional configuration for static IP address
|
||||
IPAddress localIP;
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <list>
|
||||
|
||||
#define ACCESS_TOKEN_PARAMATER "access_token"
|
||||
|
||||
#define AUTHORIZATION_HEADER "Authorization"
|
||||
#define AUTHORIZATION_HEADER_PREFIX "Bearer "
|
||||
#define AUTHORIZATION_HEADER_PREFIX_LEN 7
|
||||
|
||||
@@ -172,7 +172,7 @@ void UploadFileService::handleError(AsyncWebServerRequest * request, int code) {
|
||||
// check for invalid extension and immediately kill the connection, which will throw an error
|
||||
// that is caught by the web code. Unfortunately the http error code is not sent to the client on fast network connections
|
||||
if (code == 406) {
|
||||
request->client()->close(true);
|
||||
request->client()->close();
|
||||
_is_firmware = false;
|
||||
Update.abort();
|
||||
}
|
||||
|
||||
@@ -576,7 +576,7 @@ bool AnalogSensor::update(uint8_t gpio, const char * org_name, double offset, do
|
||||
newSensor.is_system = is_system;
|
||||
settings.analogCustomizations.push_back(newSensor);
|
||||
// check the gpio again and add to used list
|
||||
if (EMSESP::system_.add_gpio(gpio, "Analog Sensor")) {
|
||||
if (EMSESP::system_.add_gpio(gpio, name)) {
|
||||
LOG_DEBUG("Adding customization for analog sensor GPIO %02d", gpio);
|
||||
return StateUpdateResult::CHANGED; // persist the change
|
||||
} else {
|
||||
|
||||
@@ -25,10 +25,6 @@
|
||||
#define EMSESP_DEFAULT_LOCALE EMSESP_LOCALE_EN // English
|
||||
#endif
|
||||
|
||||
#ifndef EMSESP_DEFAULT_VERSION
|
||||
#define EMSESP_DEFAULT_VERSION ""
|
||||
#endif
|
||||
|
||||
#ifndef EMSESP_DEFAULT_TX_MODE
|
||||
#define EMSESP_DEFAULT_TX_MODE 1 // EMS1.0
|
||||
#endif
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#ifndef EMSESP_STANDALONE
|
||||
#include "esp_ota_ops.h"
|
||||
#include "rom/rtc.h"
|
||||
#endif
|
||||
|
||||
static_assert(uuid::thread_safe, "uuid-common must be thread-safe");
|
||||
@@ -1721,15 +1722,31 @@ void EMSESP::start() {
|
||||
LOG_INFO("EMS-ESP version %s", EMSESP_APP_VERSION);
|
||||
#endif
|
||||
|
||||
// check if the firmware is fresh
|
||||
LOG_DEBUG("System is running in Debug mode");
|
||||
|
||||
// check if the firmware is fresh, i.e. a new install or a new version has been uploaded
|
||||
// this is set in UploadFileService::uploadComplete()
|
||||
// and reset in System::set_partition_install_date()
|
||||
if (!EMSESP::nvs_.getBool(EMSESP_NVS_BOOT_NEW_FIRMWARE)) {
|
||||
LOG_DEBUG("Firmware is fresh");
|
||||
if (EMSESP::nvs_.getBool(EMSESP_NVS_BOOT_NEW_FIRMWARE)) {
|
||||
LOG_DEBUG("Firmware is a new install");
|
||||
} else {
|
||||
// check if the firmware has been uploaded via Serial/USB
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||
if (rtc_get_reset_reason(0) == 11) { // ESP_RST_USB (Reset by USB peripheral, on CPU 0 only
|
||||
#else
|
||||
if ((rtc_get_reset_reason(0) == 14 || rtc_get_reset_reason(1) == 14)) { // APP CPU reset by PRO CPU, can be either CPUs
|
||||
#endif
|
||||
LOG_DEBUG("Firmware is a new install, uploaded via Serial/USB");
|
||||
EMSESP::nvs_.putBool(emsesp::EMSESP_NVS_BOOT_NEW_FIRMWARE, true); // set flag so it's picked up later to set the install date
|
||||
}
|
||||
}
|
||||
|
||||
LOG_DEBUG("System is running in Debug mode");
|
||||
// S2 are C3 are both single core
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||
LOG_INFO("Last system reset reason Core0: %s", system_.reset_reason(0).c_str());
|
||||
#else
|
||||
LOG_INFO("Last system reset reason Core0: %s, Core1: %s", system_.reset_reason(0).c_str(), system_.reset_reason(1).c_str());
|
||||
#endif
|
||||
|
||||
// see if we're restoring a settings file
|
||||
#ifndef EMSESP_STANDALONE
|
||||
@@ -1837,7 +1854,7 @@ void EMSESP::loop() {
|
||||
if (EMSESP::system_.systemStatus() == SYSTEM_STATUS::SYSTEM_STATUS_INVALID_GPIO) {
|
||||
static bool only_once = false;
|
||||
if (!only_once) {
|
||||
LOG_ERROR("Invalid GPIOs used. Please check your settings and log");
|
||||
LOG_ERROR("Invalid GPIOs used. Please check your settings and the system log");
|
||||
only_once = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -562,8 +562,8 @@ void Mqtt::ha_status() {
|
||||
// Note we don't use camelCase as it would change the HA entity_id and impact historic data
|
||||
#ifndef EMSESP_STANDALONE
|
||||
if (!EMSESP::system_.ethernet_connected() || WiFi.isConnected()) {
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT8, "WiFi RSSI", "rssi", DeviceValueUOM::DBM);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT8, "WiFi strength", "wifistrength", DeviceValueUOM::PERCENT);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT8, "RSSI", "rssi", DeviceValueUOM::DBM);
|
||||
publish_system_ha_sensor_config(DeviceValueType::INT8, "Signal", "wifistrength", DeviceValueUOM::PERCENT);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1628,4 +1628,4 @@ void Mqtt::add_value_bool(JsonObject doc, const char * name, bool value) {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace emsesp
|
||||
} // namespace emsesp
|
||||
|
||||
@@ -105,8 +105,8 @@ uint32_t System::led_flash_duration_ = 0;
|
||||
bool System::led_flash_timer_ = false;
|
||||
|
||||
// GPIOs
|
||||
std::vector<uint8_t, AllocatorPSRAM<uint8_t>> System::valid_system_gpios_;
|
||||
std::vector<uint8_t, AllocatorPSRAM<uint8_t>> System::used_gpios_;
|
||||
std::vector<uint8_t, AllocatorPSRAM<uint8_t>> System::valid_system_gpios_;
|
||||
std::vector<System::GpioUsage, AllocatorPSRAM<System::GpioUsage>> System::used_gpios_;
|
||||
|
||||
// find the index of the language
|
||||
// 0 = EN, 1 = DE, etc...
|
||||
@@ -316,11 +316,9 @@ void System::get_partition_info() {
|
||||
|
||||
auto current_partition = (const char *)esp_ota_get_running_partition()->label;
|
||||
|
||||
// update the current version and partition name in NVS if not already set (saves on flash wearing)
|
||||
if (EMSESP::nvs_.getString(current_partition) != EMSESP_APP_VERSION || emsesp::EMSESP::nvs_.getBool(emsesp::EMSESP_NVS_BOOT_NEW_FIRMWARE, false)) {
|
||||
if (EMSESP::nvs_.getBool(emsesp::EMSESP_NVS_BOOT_NEW_FIRMWARE, false)) {
|
||||
EMSESP::nvs_.putBool(emsesp::EMSESP_NVS_BOOT_NEW_FIRMWARE, false);
|
||||
}
|
||||
// update the current version and partition name in NVS if not already set
|
||||
if (EMSESP::nvs_.getString(current_partition) != EMSESP_APP_VERSION || emsesp::EMSESP::nvs_.getBool(emsesp::EMSESP_NVS_BOOT_NEW_FIRMWARE, true)) {
|
||||
EMSESP::nvs_.putBool(emsesp::EMSESP_NVS_BOOT_NEW_FIRMWARE, false);
|
||||
EMSESP::nvs_.putString(current_partition, EMSESP_APP_VERSION);
|
||||
char c[20];
|
||||
snprintf(c, sizeof(c), "d_%s", current_partition);
|
||||
@@ -1216,16 +1214,16 @@ void System::show_system(uuid::console::Shell & shell) {
|
||||
// GPIOs
|
||||
shell.println(" GPIOs:");
|
||||
shell.printf(" in use:");
|
||||
for (const auto & gpio : used_gpios_) {
|
||||
shell.printf(" %d", gpio);
|
||||
for (const auto & usage : used_gpios_) {
|
||||
shell.printf(" %d(%s)", usage.pin, usage.source.c_str());
|
||||
}
|
||||
shell.printfln(" (total %d)", used_gpios_.size());
|
||||
shell.printfln(" [total %d]", used_gpios_.size());
|
||||
auto available = available_gpios();
|
||||
shell.printf(" available:");
|
||||
for (const auto & gpio : available) {
|
||||
shell.printf(" %d", gpio);
|
||||
}
|
||||
shell.printfln(" (total %d)", available.size());
|
||||
shell.printfln(" [total %d]", available.size());
|
||||
// List all partitions and their version info
|
||||
shell.println(" Partitions:");
|
||||
for (const auto & partition : partition_info_) {
|
||||
@@ -1410,7 +1408,7 @@ bool System::check_upgrade() {
|
||||
// see if we're missing a version, will be < 3.5.0b13 from Dec 23 2022
|
||||
missing_version = (settingsVersion.empty() || (settingsVersion.length() < 5));
|
||||
if (missing_version) {
|
||||
LOG_WARNING("No version information found");
|
||||
LOG_WARNING("No version information found. Assuming version 3.5.0");
|
||||
settingsVersion = "3.5.0"; // this was the last stable version without version info
|
||||
}
|
||||
|
||||
@@ -1422,7 +1420,7 @@ bool System::check_upgrade() {
|
||||
bool save_version = true;
|
||||
bool reboot_required = false;
|
||||
|
||||
LOG_DEBUG("Checking for version upgrades (settings file is v%d.%d.%d%s)",
|
||||
LOG_DEBUG("Checking for version upgrades from v%d.%d.%d%s",
|
||||
settings_version.major(),
|
||||
settings_version.minor(),
|
||||
settings_version.patch(),
|
||||
@@ -1432,7 +1430,7 @@ bool System::check_upgrade() {
|
||||
if (this_version > settings_version) {
|
||||
// we need to do an upgrade
|
||||
if (missing_version) {
|
||||
LOG_NOTICE("Upgrading to version %d.%d.%d%s", this_version.major(), this_version.minor(), this_version.patch(), this_version_type);
|
||||
LOG_NOTICE("Upgrading to version %d.%d.%d%s", this_version.major(), this_version.minor(), this_version.patch(), this_version_type.c_str());
|
||||
} else {
|
||||
LOG_NOTICE("Upgrading from version %d.%d.%d%s to %d.%d.%d%s",
|
||||
settings_version.major(),
|
||||
@@ -1499,7 +1497,15 @@ bool System::check_upgrade() {
|
||||
});
|
||||
} else if (this_version < settings_version) {
|
||||
// downgrading
|
||||
LOG_NOTICE("Downgrading to version %d.%d.%d%s", this_version.major(), this_version.minor(), this_version.patch(), this_version_type.c_str());
|
||||
LOG_NOTICE("Downgrading from version %d.%d.%d%s to version %d.%d.%d%s",
|
||||
settings_version.major(),
|
||||
settings_version.minor(),
|
||||
settings_version.patch(),
|
||||
settings_version_type.c_str(),
|
||||
this_version.major(),
|
||||
this_version.minor(),
|
||||
this_version.patch(),
|
||||
this_version_type.c_str());
|
||||
} else {
|
||||
save_version = false; // same version, do nothing
|
||||
}
|
||||
@@ -2031,8 +2037,9 @@ bool System::command_info(const char * value, const int8_t id, JsonObject output
|
||||
#else
|
||||
node["version"] = EMSESP_APP_VERSION;
|
||||
#endif
|
||||
node["uptime"] = uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3);
|
||||
node["uptimeSec"] = uuid::get_uptime_sec();
|
||||
node["uptime"] = uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3);
|
||||
node["uptimeSec"] = uuid::get_uptime_sec();
|
||||
node["resetReason"] = EMSESP::system_.reset_reason(0) + " / " + EMSESP::system_.reset_reason(1);
|
||||
#ifndef EMSESP_STANDALONE
|
||||
node["platform"] = EMSESP_PLATFORM;
|
||||
node["cpuType"] = ESP.getChipModel();
|
||||
@@ -2045,10 +2052,7 @@ bool System::command_info(const char * value, const int8_t id, JsonObject output
|
||||
node["freeApp"] = EMSESP::system_.appFree(); // kilobytes
|
||||
node["partition"] = (const char *)esp_ota_get_running_partition()->label; // active partition
|
||||
node["flash_chip_size"] = ESP.getFlashChipSize() / 1024; // kilobytes
|
||||
#endif
|
||||
node["resetReason"] = EMSESP::system_.reset_reason(0) + " / " + EMSESP::system_.reset_reason(1);
|
||||
#ifndef EMSESP_STANDALONE
|
||||
node["psram"] = (EMSESP::system_.PSram() > 0); // make boolean
|
||||
node["psram"] = (EMSESP::system_.PSram() > 0); // make boolean
|
||||
if (EMSESP::system_.PSram()) {
|
||||
node["psramSize"] = EMSESP::system_.PSram();
|
||||
node["freePsram"] = ESP.getFreePsram() / 1024;
|
||||
@@ -2057,9 +2061,27 @@ bool System::command_info(const char * value, const int8_t id, JsonObject output
|
||||
#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S2
|
||||
node["temperature"] = EMSESP::system_.temperature();
|
||||
#endif
|
||||
|
||||
node["txpause"] = EMSbus::tx_mode() == EMS_TXMODE_OFF;
|
||||
#endif
|
||||
node["txpause"] = EMSbus::tx_mode() == EMS_TXMODE_OFF;
|
||||
|
||||
// GPIO information
|
||||
std::string gpios_in_use_str;
|
||||
for (const auto & usage : EMSESP::system_.used_gpios_) {
|
||||
if (!gpios_in_use_str.empty()) {
|
||||
gpios_in_use_str += ", ";
|
||||
}
|
||||
gpios_in_use_str += Helpers::itoa(usage.pin);
|
||||
}
|
||||
node["gpios_in_use"] = gpios_in_use_str;
|
||||
|
||||
std::string gpios_available_str;
|
||||
for (const auto & gpio : EMSESP::system_.available_gpios()) {
|
||||
if (!gpios_available_str.empty()) {
|
||||
gpios_available_str += ", ";
|
||||
}
|
||||
gpios_available_str += Helpers::itoa(gpio);
|
||||
}
|
||||
node["gpios_available"] = gpios_available_str;
|
||||
|
||||
// Network Status
|
||||
node = output["network"].to<JsonObject>();
|
||||
@@ -2448,15 +2470,15 @@ bool System::command_txpause(const char * value, const int8_t id) {
|
||||
|
||||
// format command - factory reset, removing all config files
|
||||
bool System::command_format(const char * value, const int8_t id) {
|
||||
#if !defined(EMSESP_STANDALONE) && !defined(EMSESP_DEBUG)
|
||||
// don't really format the filesystem in debug or standalone mode
|
||||
#if !defined(EMSESP_STANDALONE) && !defined(EMSESP_TEST)
|
||||
// don't really format the filesystem in test or standalone mode
|
||||
if (LittleFS.format()) {
|
||||
LOG_INFO("Filesystem formatted successfully. All config files removed.");
|
||||
} else {
|
||||
LOG_ERROR("Format failed");
|
||||
}
|
||||
#else
|
||||
LOG_INFO("Format command not available in standalone or debug mode");
|
||||
LOG_ERROR("Format command not available in standalone or test mode");
|
||||
#endif
|
||||
|
||||
// restart will be handled by the main loop
|
||||
@@ -2553,21 +2575,6 @@ bool System::ntp_connected() {
|
||||
// see if its a BBQKees Gateway by checking the nvs values
|
||||
String System::getBBQKeesGatewayDetails(uint8_t detail) {
|
||||
#ifndef EMSESP_STANDALONE
|
||||
/*
|
||||
if (!EMSESP::nvs_.isKey("mfg")) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// mfg can be either "BBQKees" or "BBQKees Electronics"
|
||||
auto mfg = EMSESP::nvs_.getString("mfg");
|
||||
if (mfg) {
|
||||
if (!mfg.startsWith("BBQKees")) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
return "BBQKees Gateway Model " + EMSESP::nvs_.getString("model") + " v" + EMSESP::nvs_.getString("hwrevision") + "/" + EMSESP::nvs_.getString("batch");
|
||||
*/
|
||||
union {
|
||||
struct {
|
||||
uint32_t no : 4;
|
||||
@@ -2580,14 +2587,17 @@ String System::getBBQKeesGatewayDetails(uint8_t detail) {
|
||||
};
|
||||
uint32_t reg;
|
||||
} gw;
|
||||
|
||||
for (uint8_t reg = 0; reg < 8; reg++) {
|
||||
gw.reg = esp_efuse_read_reg(EFUSE_BLK3, reg);
|
||||
if (reg == 7 || esp_efuse_read_reg(EFUSE_BLK3, reg + 1) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
const char * mfg[] = {"unknown", "BBQKees Electronics", "", "", "", "", "", ""};
|
||||
const char * model[] = {"unknown", "S3", "E32V2", "E32V2.2", "S32", "E32", "", "", ""};
|
||||
const char * board[] = {"CUSTOM", "S32S3", "E32V2", "E32V2_2", "S32", "E32", "", "", ""};
|
||||
|
||||
switch (detail) {
|
||||
case FUSE_VALUE::MFG:
|
||||
return gw.mfg < 2 ? String(mfg[gw.mfg]) : "unknown";
|
||||
@@ -2605,9 +2615,11 @@ String System::getBBQKeesGatewayDetails(uint8_t detail) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!gw.reg || gw.mfg > 1 || gw.model > 5) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return String(mfg[gw.mfg]) + " " + String(model[gw.model]) + " rev." + String(gw.rev_major) + "." + String(gw.rev_minor) + "/" + String(2000 + gw.year)
|
||||
+ (gw.month < 10 ? "0" : "") + String(gw.month) + String(gw.no);
|
||||
#else
|
||||
@@ -2684,6 +2696,9 @@ bool System::uploadFirmwareURL(const char * url) {
|
||||
// we're about to start the upload, set the status so the Web System Monitor spots it
|
||||
EMSESP::system_.systemStatus(SYSTEM_STATUS::SYSTEM_STATUS_UPLOADING);
|
||||
|
||||
// set a callback so we can monitor progress in the WebUI
|
||||
Update.onProgress([](size_t progress, size_t total) { EMSESP::system_.systemStatus(SYSTEM_STATUS::SYSTEM_STATUS_UPLOADING + (progress * 100 / total)); });
|
||||
|
||||
// get tcp stream and send it to Updater
|
||||
WiFiClient * stream = http.getStreamPtr();
|
||||
if (Update.writeStream(*stream) != firmware_size) {
|
||||
@@ -2772,10 +2787,15 @@ bool System::command_read(const char * value, const int8_t id) {
|
||||
}
|
||||
|
||||
// set the system status code - SYSTEM_STATUS in system.h
|
||||
// this is also used in the SystemMonitor.tsx WebUI to show the progress of the firmware upload, start at 100
|
||||
void System::systemStatus(uint8_t status_code) {
|
||||
if (systemStatus_ != status_code) {
|
||||
systemStatus_ = status_code;
|
||||
LOG_DEBUG("Setting System status code %d", status_code);
|
||||
#ifdef EMSESP_DEBUG
|
||||
if (status_code < SYSTEM_STATUS::SYSTEM_STATUS_UPLOADING) {
|
||||
LOG_DEBUG("Setting System status code %d", status_code);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2783,8 +2803,11 @@ uint8_t System::systemStatus() {
|
||||
return systemStatus_;
|
||||
}
|
||||
|
||||
// takes a string range like "6-11, 1, 23, 24-48" which has optional ranges and single values and converts to a vector of ints
|
||||
std::vector<uint8_t, AllocatorPSRAM<uint8_t>> System::string_range_to_vector(const std::string & range) {
|
||||
// takes two arguments:
|
||||
// the first is the full range of pins to consider
|
||||
// the second is a string range of GPIOs to exclude, like "6-11, 1, 23, 24-48"
|
||||
// returns a vector array of GPIOs that are valid for use
|
||||
std::vector<uint8_t, AllocatorPSRAM<uint8_t>> System::string_range_to_vector(const std::string & range, const std::string & exclude) {
|
||||
std::vector<uint8_t, AllocatorPSRAM<uint8_t>> gpios;
|
||||
std::string::size_type pos = 0;
|
||||
std::string::size_type prev = 0;
|
||||
@@ -2816,41 +2839,122 @@ std::vector<uint8_t, AllocatorPSRAM<uint8_t>> System::string_range_to_vector(con
|
||||
// handle the last part
|
||||
process_part(range.substr(prev));
|
||||
|
||||
// if exclude list is provided, parse it and remove excluded GPIOs
|
||||
if (!exclude.empty()) {
|
||||
std::vector<uint8_t, AllocatorPSRAM<uint8_t>> exclude_gpios;
|
||||
pos = 0;
|
||||
prev = 0;
|
||||
|
||||
auto process_exclude = [&exclude_gpios](std::string part) {
|
||||
// trim whitespace
|
||||
part.erase(0, part.find_first_not_of(" \t"));
|
||||
part.erase(part.find_last_not_of(" \t") + 1);
|
||||
|
||||
// check if it's a range (contains '-')
|
||||
std::string::size_type dash_pos = part.find('-');
|
||||
if (dash_pos != std::string::npos) {
|
||||
// it's a range like "6-11"
|
||||
int start = std::stoi(part.substr(0, dash_pos));
|
||||
int end = std::stoi(part.substr(dash_pos + 1));
|
||||
for (int i = start; i <= end; i++) {
|
||||
exclude_gpios.push_back(static_cast<uint8_t>(i));
|
||||
}
|
||||
} else {
|
||||
exclude_gpios.push_back(static_cast<uint8_t>(std::stoi(part)));
|
||||
}
|
||||
};
|
||||
|
||||
while ((pos = exclude.find(',', prev)) != std::string::npos) {
|
||||
process_exclude(exclude.substr(prev, pos - prev));
|
||||
prev = pos + 1;
|
||||
}
|
||||
|
||||
// handle the last part
|
||||
process_exclude(exclude.substr(prev));
|
||||
|
||||
// remove excluded GPIOs from the main list
|
||||
gpios.erase(std::remove_if(gpios.begin(),
|
||||
gpios.end(),
|
||||
[&exclude_gpios](uint8_t gpio) { return std::find(exclude_gpios.begin(), exclude_gpios.end(), gpio) != exclude_gpios.end(); }),
|
||||
gpios.end());
|
||||
}
|
||||
|
||||
return gpios;
|
||||
}
|
||||
|
||||
// initialize a list of valid GPIOs based on the ESP32 board
|
||||
// note: we always allow 0, which is used to indicate Dallas or LED is disabled
|
||||
// string_to_vector() take two strings, the first is the range of GPIOs to use, the second is a list of GPIOs to exclude
|
||||
// notes:
|
||||
// we always allow 0 (which is usually a strapping pin), because it's used to indicate whether EMS-ESP Dallas or the LED is disabled
|
||||
// we allow UART0, 1 and 2 as they are configurable
|
||||
// strapping pins are disabled as they can affect boot behaviour
|
||||
// we accept GPIOs that are fixed on BBQKees boards
|
||||
//
|
||||
void System::set_valid_system_gpios() {
|
||||
valid_system_gpios_.clear(); // reset system list
|
||||
used_gpios_.clear(); // reset used list
|
||||
|
||||
// get free gpios based on board/platform type
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
// https://www.wemos.cc/en/latest/c3/c3_mini.html
|
||||
valid_system_gpios_ = string_range_to_vector("0-10"); // UART0=20,21
|
||||
// https://docs.espressif.com/projects/esp-idf/en/stable/esp32c3/api-reference/peripherals/gpio.html
|
||||
// excluded:
|
||||
// GPIO2, GPIO8 - GPIO9 = strapping pins
|
||||
// GPIO12 - GPIO17 = used for SPI flash and PSRAM
|
||||
// GPIO18 - GPIO19 = USB-JTAG
|
||||
//
|
||||
// notes on what is allowed:
|
||||
// GPIO10 = button on BOARD_C3_MINI_V1
|
||||
valid_system_gpios_ = string_range_to_vector("0-21", "2, 8-9, 12-17, 18-19");
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
// 43 and 44 are UART0 pins
|
||||
// 38 and 39 are strapping pins, input only
|
||||
valid_system_gpios_ = string_range_to_vector("0-14, 19, 20, 21, 33-37, 45, 46");
|
||||
// https://docs.espressif.com/projects/esp-idf/en/stable/esp32s2/api-reference/peripherals/gpio.html
|
||||
// excluded:
|
||||
// GPIO26 - GPIO32 = SPI flash and PSRAM
|
||||
// GPIO45 - GPIO46 = strapping pins
|
||||
// GPIO39 - GPIO42 = USB-JTAG
|
||||
// GPIO22 - GPIO25 = don't exist
|
||||
//
|
||||
// notes on what is allowed:
|
||||
valid_system_gpios_ = string_range_to_vector("0-46", "26-32, 45-46, 39-42, 22-25");
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
// 43 and 44 are UART0 pins
|
||||
// 33-37 for Octal SPI (SPIIO4 through SPIIO7 and SPIDQS)
|
||||
// 38 and 39 are input only
|
||||
// 45 and 36 are strapping pins, input only
|
||||
// 47 and 48 are valid on a Wemos S3 (https://github.com/emsesp/EMS-ESP32/issues/2874)
|
||||
valid_system_gpios_ = string_range_to_vector("0-14, 17, 18, 21, 33-39, 45-48");
|
||||
// https://docs.espressif.com/projects/esp-idf/en/stable/esp32s3/api-reference/peripherals/gpio.html
|
||||
// excluded:
|
||||
// GPIO3, GPIO45 - GPIO46 = strapping pins
|
||||
// GPIO26 - GPIO32 = SPI flash and PSRAM and not recommended
|
||||
// GPIO33 - GPIO37 = Octal flash/PSRAM
|
||||
// GPIO19 - GPIO20 = USB-JTAG
|
||||
// GPIO22 - GPIO25 = don't exist
|
||||
//
|
||||
// notes on what is allowed:
|
||||
// GPIO11 - GPIO19 = ADC analog input only pins
|
||||
// GPIO47 - GPIO48 = valid on a Wemos S3
|
||||
// GPIO8 = used by Liligo S3 board profile for Rx
|
||||
valid_system_gpios_ = string_range_to_vector("0-48", "3, 45-46, 26-32, 33-37, 19-20, 22-25");
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32
|
||||
// 1 and 3 are UART0 pins, but used for some eth-boards (BBQKees-E32, OlimexPOE)
|
||||
// 32-39 is ADC1, input only
|
||||
// https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/peripherals/gpio.html
|
||||
// excluded:
|
||||
// GPIO6 - GPIO11, GPIO16 - GPIO17 = used for SPI flash and PSRAM
|
||||
// GPIO12 - GPIO15 = USB-JTAG (but we allow GPIO14 for BBQKees) and GPIO12 & GPIO13 also reserved for BBQKees E32V2.2
|
||||
// GPIO20, GPIO24, GPIO28 - GPIO31 = don't exist
|
||||
//
|
||||
// notes on what is allowed:
|
||||
// GPIO34, GPIO35, GPIO37 = input only
|
||||
// GPIO2, GPIO4, GPIO5, GPIO14 = used on BBQKees boards for either LED, Dallas or Rx
|
||||
// GPIO23 and GPIO18 are used by Ethernet
|
||||
// GPIO25 - GPIO37 = ADC2
|
||||
// GPIO32 - GPIO39 = ADC1
|
||||
// GPIO36 = used on BBQKees boards for supply_voltage (E32V2.2) (note may conflict with WiFI on other boards)
|
||||
// GPIO39 = used on BBQKees boards for core_voltage (E32V2.2) (note may conflict with WiFI on other boards)
|
||||
if (ESP.getPsramSize() > 0) {
|
||||
// if psram is enabled remove pins 16 and 17 from the list
|
||||
valid_system_gpios_ = string_range_to_vector("0-5, 12-15, 18-19, 23, 25-27, 32-39");
|
||||
// remove SPI0/1 PSRAM pins GPIO16 (CS) and GPIO17 (CLK) from the list
|
||||
valid_system_gpios_ = string_range_to_vector("0-39", "6-11, 12, 13, 15, 16, 17, 20, 24, 28-31");
|
||||
} else {
|
||||
valid_system_gpios_ = string_range_to_vector("0-5, 12-19, 23, 25-27, 32-39");
|
||||
valid_system_gpios_ = string_range_to_vector("0-39", "6-11, 12, 13, 15, 20, 24, 28-31");
|
||||
}
|
||||
#elif defined(EMSESP_STANDALONE)
|
||||
valid_system_gpios_ = string_range_to_vector("0-5, 12-19, 23, 25-27, 32-39");
|
||||
valid_system_gpios_ = string_range_to_vector("0-39");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2860,8 +2964,9 @@ bool System::add_gpio(uint8_t pin, const char * source_name) {
|
||||
// check if this is a valid user GPIO
|
||||
if (std::find(valid_system_gpios_.begin(), valid_system_gpios_.end(), pin) != valid_system_gpios_.end()) {
|
||||
// It's valid now check if it's already in the used list
|
||||
if (std::find(used_gpios_.begin(), used_gpios_.end(), pin) != used_gpios_.end()) {
|
||||
LOG_WARNING("GPIO %d for %s is already in use", pin, source_name);
|
||||
auto it = std::find_if(used_gpios_.begin(), used_gpios_.end(), [pin](const GpioUsage & usage) { return usage.pin == pin; });
|
||||
if (it != used_gpios_.end()) {
|
||||
LOG_WARNING("GPIO %d for %s is already in use by %s", pin, source_name, it->source.c_str());
|
||||
return false; // Pin is already used
|
||||
}
|
||||
} else {
|
||||
@@ -2874,24 +2979,24 @@ bool System::add_gpio(uint8_t pin, const char * source_name) {
|
||||
remove_gpio(pin);
|
||||
|
||||
LOG_DEBUG("Adding GPIO %d for %s to used gpio list", pin, source_name);
|
||||
used_gpios_.push_back(pin); // add to used list
|
||||
used_gpios_.push_back({pin, source_name}); // add to used list
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// remove a gpio from both valid and used lists
|
||||
void System::remove_gpio(uint8_t pin, bool also_system) {
|
||||
auto it = std::find(used_gpios_.begin(), used_gpios_.end(), pin);
|
||||
auto it = std::find_if(used_gpios_.begin(), used_gpios_.end(), [pin](const GpioUsage & usage) { return usage.pin == pin; });
|
||||
if (it != used_gpios_.end()) {
|
||||
LOG_DEBUG("GPIO %d removed from used gpio list", pin);
|
||||
used_gpios_.erase(it);
|
||||
}
|
||||
|
||||
if (also_system) {
|
||||
it = std::find(valid_system_gpios_.begin(), valid_system_gpios_.end(), pin);
|
||||
if (it != valid_system_gpios_.end()) {
|
||||
auto it_sys = std::find(valid_system_gpios_.begin(), valid_system_gpios_.end(), pin);
|
||||
if (it_sys != valid_system_gpios_.end()) {
|
||||
LOG_DEBUG("GPIO %d removed from valid gpio list", pin);
|
||||
valid_system_gpios_.erase(it);
|
||||
valid_system_gpios_.erase(it_sys);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2900,7 +3005,7 @@ void System::remove_gpio(uint8_t pin, bool also_system) {
|
||||
std::vector<uint8_t> System::available_gpios() {
|
||||
std::vector<uint8_t> gpios;
|
||||
for (const auto & gpio : valid_system_gpios_) {
|
||||
if (std::find(used_gpios_.begin(), used_gpios_.end(), gpio) == used_gpios_.end()) {
|
||||
if (std::find_if(used_gpios_.begin(), used_gpios_.end(), [gpio](const GpioUsage & usage) { return usage.pin == gpio; }) == used_gpios_.end()) {
|
||||
gpios.push_back(gpio); // didn't find it in used_gpios_, so it's available
|
||||
}
|
||||
}
|
||||
@@ -2909,8 +3014,8 @@ std::vector<uint8_t> System::available_gpios() {
|
||||
|
||||
// make a snapshot of the current GPIOs
|
||||
void System::make_snapshot_gpios(std::vector<int8_t> & u_gpios, std::vector<int8_t> & s_gpios) {
|
||||
for (const auto & gpio : used_gpios_) {
|
||||
u_gpios.push_back(gpio);
|
||||
for (const auto & usage : used_gpios_) {
|
||||
u_gpios.push_back(usage.pin);
|
||||
}
|
||||
for (const auto & gpio : valid_system_gpios_) {
|
||||
s_gpios.push_back(gpio);
|
||||
@@ -2921,7 +3026,7 @@ void System::make_snapshot_gpios(std::vector<int8_t> & u_gpios, std::vector<int8
|
||||
void System::restore_snapshot_gpios(std::vector<int8_t> & u_gpios, std::vector<int8_t> & s_gpios) {
|
||||
used_gpios_.clear();
|
||||
for (const auto & gpio : u_gpios) {
|
||||
used_gpios_.push_back(gpio);
|
||||
used_gpios_.push_back({static_cast<uint8_t>(gpio), "restored"});
|
||||
}
|
||||
|
||||
valid_system_gpios_.clear();
|
||||
|
||||
@@ -159,7 +159,6 @@ class System {
|
||||
static void extractSettings(const char * filename, const char * section, JsonObject output);
|
||||
static bool saveSettings(const char * filename, const char * section, JsonObject input);
|
||||
|
||||
// GPIOs
|
||||
static bool add_gpio(uint8_t pin, const char * source_name);
|
||||
static std::vector<uint8_t> available_gpios();
|
||||
static bool load_board_profile(std::vector<int8_t> & data, const std::string & board_profile);
|
||||
@@ -434,11 +433,15 @@ class System {
|
||||
void led_monitor();
|
||||
void system_check();
|
||||
|
||||
static std::vector<uint8_t, AllocatorPSRAM<uint8_t>> string_range_to_vector(const std::string & range);
|
||||
static std::vector<uint8_t, AllocatorPSRAM<uint8_t>> string_range_to_vector(const std::string & range, const std::string & exclude = "");
|
||||
|
||||
// GPIOs
|
||||
static std::vector<uint8_t, AllocatorPSRAM<uint8_t>> valid_system_gpios_; // list of valid GPIOs for the ESP32 board that can be used
|
||||
static std::vector<uint8_t, AllocatorPSRAM<uint8_t>> used_gpios_; // list of GPIOs used by the application
|
||||
struct GpioUsage {
|
||||
uint8_t pin;
|
||||
std::string source;
|
||||
};
|
||||
static std::vector<uint8_t, AllocatorPSRAM<uint8_t>> valid_system_gpios_; // list of valid GPIOs for the ESP32 board that can be used
|
||||
static std::vector<GpioUsage, AllocatorPSRAM<GpioUsage>> used_gpios_; // list of GPIOs used by the application
|
||||
|
||||
int8_t wifi_quality(int8_t dBm);
|
||||
|
||||
|
||||
@@ -221,14 +221,14 @@ void RxService::add(uint8_t * data, uint8_t length) {
|
||||
LOG_TRACE("Rx: %s", Helpers::data_to_hex(data, length).c_str());
|
||||
}
|
||||
|
||||
LOG_DEBUG("New Rx telegram, message length %d", message_length);
|
||||
|
||||
// if we don't have a type_id exit,
|
||||
// do not exit on empty message, it is checked for toggle fetch
|
||||
// if we don't have a type_id exit
|
||||
// do not exit on empty message, it is checked later for toggle fetch
|
||||
if (type_id == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_DEBUG("New Rx telegram, message length %d", message_length);
|
||||
|
||||
// create the telegram
|
||||
auto telegram = std::make_shared<Telegram>(operation, src, dest, type_id, offset, message_data, message_length);
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define EMSESP_APP_VERSION "3.8.1-dev.3"
|
||||
#define EMSESP_APP_VERSION "3.8.1-dev.4"
|
||||
|
||||
@@ -120,10 +120,11 @@ StateUpdateResult WebCustomization::update(JsonObject root, WebCustomization & c
|
||||
for (const JsonObject analogJson : analogJsons) {
|
||||
// create each of the sensor, overwriting any previous settings
|
||||
// if the gpio is invalid skip the sensor
|
||||
if (!EMSESP::system_.add_gpio(analogJson["gpio"].as<uint8_t>(), "Analog Sensor")) {
|
||||
auto analog_sensor_name = analogJson["name"].as<const char *>();
|
||||
if (!EMSESP::system_.add_gpio(analogJson["gpio"].as<uint8_t>(), analog_sensor_name)) {
|
||||
EMSESP::logger().warning("Analog sensor: Invalid GPIO %d for %s. Skipping.",
|
||||
analogJson["gpio"].as<uint8_t>(),
|
||||
analogJson["name"].as<const char *>());
|
||||
analog_sensor_name);
|
||||
continue;
|
||||
}
|
||||
auto analog = AnalogCustomization();
|
||||
|
||||
@@ -97,7 +97,7 @@ void WebLogService::show(Shell & shell) {
|
||||
}
|
||||
|
||||
shell.println();
|
||||
shell.printfln("Recent Log (level %s, max %d messages):", uuid::log::format_level_uppercase(level_), maximum_log_messages_);
|
||||
shell.printfln("Recent Log:");
|
||||
shell.println();
|
||||
|
||||
for (const auto & message : log_messages_) {
|
||||
|
||||
@@ -96,9 +96,7 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) {
|
||||
std::vector<int8_t> system_gpios;
|
||||
EMSESP::system_.make_snapshot_gpios(used_gpios, system_gpios);
|
||||
|
||||
reset_flags();
|
||||
|
||||
settings.version = root["version"] | EMSESP_DEFAULT_VERSION; // save the version, we use it later in System::check_upgrade()
|
||||
settings.version = root["version"] | EMSESP_APP_VERSION; // save the version, we use it later in System::check_upgrade()
|
||||
settings.board_profile = root["board_profile"] | EMSESP_DEFAULT_BOARD_PROFILE;
|
||||
|
||||
// get current values that are related to the board profile
|
||||
@@ -113,10 +111,13 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) {
|
||||
settings.eth_clock_mode = root["eth_clock_mode"];
|
||||
settings.led_type = root["led_type"]; // 1 = RGB-LED
|
||||
|
||||
reset_flags();
|
||||
|
||||
// see if the user has changed the board profile
|
||||
// this will set: led_gpio, dallas_gpio, rx_gpio, tx_gpio, pbutton_gpio, phy_type, eth_power, eth_phy_addr, eth_clock_mode, led_type
|
||||
// this will always run when EMS-ESP starts since original_settings{} is empty
|
||||
if (original_settings.board_profile != settings.board_profile) {
|
||||
if (original_settings.board_profile != settings.board_profile || original_settings.board_profile == "default"
|
||||
|| original_settings.board_profile.length() == 0) {
|
||||
set_board_profile(settings);
|
||||
add_flags(ChangeFlags::RESTART);
|
||||
}
|
||||
@@ -306,10 +307,10 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) {
|
||||
|
||||
// save the settings if changed from the webUI
|
||||
// if we encountered an invalid GPIO, rollback changes and don't save settings, and report the error to WebUI
|
||||
// without a restart
|
||||
if (!have_valid_gpios) {
|
||||
// replace settings with original settings
|
||||
settings = original_settings; // the original settings are still valid
|
||||
// restore the GPIOs from the snapshot
|
||||
settings = original_settings;
|
||||
EMSESP::system_.restore_snapshot_gpios(used_gpios, system_gpios);
|
||||
|
||||
// report the error to WebUI
|
||||
@@ -320,7 +321,8 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) {
|
||||
// save the setting internally, for reference later
|
||||
EMSESP::system_.store_settings(settings);
|
||||
|
||||
if (has_flags(WebSettings::ChangeFlags::RESTART)) {
|
||||
// and finally always write to the settings file
|
||||
if (has_flags(ChangeFlags::RESTART)) {
|
||||
return StateUpdateResult::CHANGED_RESTART;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace emsesp {
|
||||
|
||||
class WebSettings {
|
||||
public:
|
||||
String version;
|
||||
String version = EMSESP_APP_VERSION;
|
||||
String locale;
|
||||
uint8_t tx_mode;
|
||||
uint8_t ems_bus_id;
|
||||
|
||||
Reference in New Issue
Block a user