diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 10dca72..ce0ecee 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -153,6 +153,7 @@ jobs: uses: softprops/action-gh-release@v2 with: body: ${{steps.github_release.outputs.changelog}} + append_body: true make_latest: true draft: false prerelease: false diff --git a/README.md b/README.md index 5627df7..935baba 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ - [Powering with the internal 3.7V battery](#powering-with-the-internal-37v-battery) - [Powering with USB-C power bank](#powering-with-usb-c-power-bank) - [Powering with USB-C Solar Panel](#powering-with-usb-c-solar-panel) + - [Beelance consumption](#beelance-consumption) - [Firmware flash (first time)](#firmware-flash-first-time) - [Device Configuration](#device-configuration) - [Important information about the Modem](#important-information-about-the-modem) @@ -198,7 +199,25 @@ Beelance works with a SIM card, so you need to select your carrier: The JSON payload sent from Beelance is more or less **250 bytes**. ```json -{"ts":1731147105,"bh":"beelance-73fadc","temp":24.56,"wt":0,"lat":0,"long":0,"alt":0,"sim":"8944501905220523406f","op":"Orange F","dev":"73FADC","boot":36,"ver":"main_9203b08_modified","up":103,"pow":"ext","bat":0,"volt":4.23,"eco":false} +{ + "ts": 1731147105, + "bh": "beelance-73fadc", + "temp": 24.56, + "wt": 0, + "lat": 0, + "long": 0, + "alt": 0, + "sim": "8944501905220523406f", + "op": "Orange F", + "dev": "73FADC", + "boot": 36, + "ver": "main_9203b08_modified", + "up": 103, + "pow": "ext", + "bat": 0, + "volt": 4.23, + "eco": false +} ``` You also need to add the HTTP/HTTPS headers overhead, which can easily be at least **100 bytes**. @@ -340,6 +359,35 @@ Never power the device with both the on-board solar connector and a usb-c solar **This option is not working very well with the LILYGO T-A7670G** because this board does not have a Power Management Unit (PMU) like the `T-SIM7080G-S3`. So when the solar panel is not able to produce enough current, the device will simply not start, until the solar panel voltage becomes 0 and then the device will switch on the battery. +### Beelance consumption + +Here is the power consumption of the device in 2 modes: + +1. **Active mode** (above / left): from when the device starts or wakes up until when it sends the data and goes to deep sleep +2. **Deep sleep mode** (below / right): when the device is in deep sleep + +| [![](https://raw.githubusercontent.com/mathieucarbou/Beelance/main/docs/assets/images/power-wakeup.png)](https://raw.githubusercontent.com/mathieucarbou/Beelance/main/docs/assets/images/power-wakeup.png) | [![](https://raw.githubusercontent.com/mathieucarbou/Beelance/main/docs/assets/images/power-deepsleep.png)](https://raw.githubusercontent.com/mathieucarbou/Beelance/main/docs/assets/images/power-deepsleep.png) | + +The device consumption in active mode is on average less than 200mA. +So a charged battery having a capacity of more than 3000 mAh (3200-3600 mAh) should last about 15 hours if kept in active mode + +The device consumption in deep sleep mode is less than 500 uA. +So a charged battery having a capacity of more than 3000 mAh (3200-3600 mAh) should last about 8 months. + +By default, the device will wake up every hour between 5 am to 11 pm, send the data and go back to sleep. +We will suppose that the device takes 3 minutes to register on the network. get a GPS point and send the data. (which, in reality, is much less). + +The device will be in active mode for 3 minutes 16 times a day, which is 48 minutes per day. +The device will be in deep sleep for 23 hours and 12 minutes per day. + +**So the consumption of the device per day should be no more than 220 mAh, which means about 2 weeks of autonomy with a 3000mAh battery.** + +**All these numbers are quite theoretical and the real consumption will be different because the heat and cold will affect the battery capacity.** + +But coupled with a solar panel, the device should be able to last indefinitely. + +Note: the testing was done with the temperature probe attached. + ## Firmware flash (first time) First time, flash the entire firmware which includes the partition table and all partitions. diff --git a/docs/assets/images/power-deepsleep.png b/docs/assets/images/power-deepsleep.png new file mode 100644 index 0000000..0d553e2 Binary files /dev/null and b/docs/assets/images/power-deepsleep.png differ diff --git a/docs/assets/images/power-wakeup.png b/docs/assets/images/power-wakeup.png new file mode 100644 index 0000000..cf65b8b Binary files /dev/null and b/docs/assets/images/power-wakeup.png differ diff --git a/docs/index.md b/docs/index.md index 5627df7..935baba 100644 --- a/docs/index.md +++ b/docs/index.md @@ -26,6 +26,7 @@ - [Powering with the internal 3.7V battery](#powering-with-the-internal-37v-battery) - [Powering with USB-C power bank](#powering-with-usb-c-power-bank) - [Powering with USB-C Solar Panel](#powering-with-usb-c-solar-panel) + - [Beelance consumption](#beelance-consumption) - [Firmware flash (first time)](#firmware-flash-first-time) - [Device Configuration](#device-configuration) - [Important information about the Modem](#important-information-about-the-modem) @@ -198,7 +199,25 @@ Beelance works with a SIM card, so you need to select your carrier: The JSON payload sent from Beelance is more or less **250 bytes**. ```json -{"ts":1731147105,"bh":"beelance-73fadc","temp":24.56,"wt":0,"lat":0,"long":0,"alt":0,"sim":"8944501905220523406f","op":"Orange F","dev":"73FADC","boot":36,"ver":"main_9203b08_modified","up":103,"pow":"ext","bat":0,"volt":4.23,"eco":false} +{ + "ts": 1731147105, + "bh": "beelance-73fadc", + "temp": 24.56, + "wt": 0, + "lat": 0, + "long": 0, + "alt": 0, + "sim": "8944501905220523406f", + "op": "Orange F", + "dev": "73FADC", + "boot": 36, + "ver": "main_9203b08_modified", + "up": 103, + "pow": "ext", + "bat": 0, + "volt": 4.23, + "eco": false +} ``` You also need to add the HTTP/HTTPS headers overhead, which can easily be at least **100 bytes**. @@ -340,6 +359,35 @@ Never power the device with both the on-board solar connector and a usb-c solar **This option is not working very well with the LILYGO T-A7670G** because this board does not have a Power Management Unit (PMU) like the `T-SIM7080G-S3`. So when the solar panel is not able to produce enough current, the device will simply not start, until the solar panel voltage becomes 0 and then the device will switch on the battery. +### Beelance consumption + +Here is the power consumption of the device in 2 modes: + +1. **Active mode** (above / left): from when the device starts or wakes up until when it sends the data and goes to deep sleep +2. **Deep sleep mode** (below / right): when the device is in deep sleep + +| [![](https://raw.githubusercontent.com/mathieucarbou/Beelance/main/docs/assets/images/power-wakeup.png)](https://raw.githubusercontent.com/mathieucarbou/Beelance/main/docs/assets/images/power-wakeup.png) | [![](https://raw.githubusercontent.com/mathieucarbou/Beelance/main/docs/assets/images/power-deepsleep.png)](https://raw.githubusercontent.com/mathieucarbou/Beelance/main/docs/assets/images/power-deepsleep.png) | + +The device consumption in active mode is on average less than 200mA. +So a charged battery having a capacity of more than 3000 mAh (3200-3600 mAh) should last about 15 hours if kept in active mode + +The device consumption in deep sleep mode is less than 500 uA. +So a charged battery having a capacity of more than 3000 mAh (3200-3600 mAh) should last about 8 months. + +By default, the device will wake up every hour between 5 am to 11 pm, send the data and go back to sleep. +We will suppose that the device takes 3 minutes to register on the network. get a GPS point and send the data. (which, in reality, is much less). + +The device will be in active mode for 3 minutes 16 times a day, which is 48 minutes per day. +The device will be in deep sleep for 23 hours and 12 minutes per day. + +**So the consumption of the device per day should be no more than 220 mAh, which means about 2 weeks of autonomy with a 3000mAh battery.** + +**All these numbers are quite theoretical and the real consumption will be different because the heat and cold will affect the battery capacity.** + +But coupled with a solar panel, the device should be able to last indefinitely. + +Note: the testing was done with the temperature probe attached. + ## Firmware flash (first time) First time, flash the entire firmware which includes the partition table and all partitions. diff --git a/include/Beelance.h b/include/Beelance.h index 5baefee..4bf253b 100644 --- a/include/Beelance.h +++ b/include/Beelance.h @@ -4,7 +4,6 @@ */ #pragma once -#include #include #include @@ -20,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/include/BeelanceClass.h b/include/BeelanceClass.h index 9ffba22..a3147be 100644 --- a/include/BeelanceClass.h +++ b/include/BeelanceClass.h @@ -7,11 +7,12 @@ #include #include +#include #include namespace Beelance { typedef struct { - String time; + std::string time; float temperature; int32_t weight; } Measurement; diff --git a/include/BeelanceMacros.h b/include/BeelanceMacros.h index ba13c33..f060298 100644 --- a/include/BeelanceMacros.h +++ b/include/BeelanceMacros.h @@ -52,14 +52,6 @@ #define BEELANCE_TEMPERATURE_PIN 12 #endif -#ifndef BEELANCE_MODEM_TASK_STACK_SIZE - #define BEELANCE_MODEM_TASK_STACK_SIZE 256 * 21 -#endif - -#ifndef BEELANCE_HX711_TASK_STACK_SIZE - #define BEELANCE_HX711_TASK_STACK_SIZE 256 * 12 -#endif - #ifndef BEELANCE_MIN_SEND_DELAY #define BEELANCE_MIN_SEND_DELAY 1800 #endif diff --git a/include/BeelanceWebsite.h b/include/BeelanceWebsite.h index c548890..95338f5 100644 --- a/include/BeelanceWebsite.h +++ b/include/BeelanceWebsite.h @@ -6,6 +6,8 @@ #include +#include + namespace Beelance { class WebsiteClass { public: @@ -97,15 +99,15 @@ namespace Beelance { Chart _chartHourlyTemp = Chart(&dashboard, BAR_CHART, "Temperature (C) - Hourly Max"); Chart _chartDailyTemp = Chart(&dashboard, BAR_CHART, "Temperature (C) - Daily Max"); - String _chartLatestX[BEELANCE_MAX_HISTORY_SIZE]; + std::string _chartLatestX[BEELANCE_MAX_HISTORY_SIZE]; float _chartLatestWeightY[BEELANCE_MAX_HISTORY_SIZE]; float _chartLatestTempY[BEELANCE_MAX_HISTORY_SIZE]; - String _chartHourlyX[BEELANCE_MAX_HISTORY_SIZE]; + std::string _chartHourlyX[BEELANCE_MAX_HISTORY_SIZE]; float _chartHourlyWeightY[BEELANCE_MAX_HISTORY_SIZE]; float _chartHourlyTempY[BEELANCE_MAX_HISTORY_SIZE]; - String _chartDailyX[BEELANCE_MAX_HISTORY_SIZE]; + std::string _chartDailyX[BEELANCE_MAX_HISTORY_SIZE]; float _chartDailyWeightY[BEELANCE_MAX_HISTORY_SIZE]; float _chartDailyTempY[BEELANCE_MAX_HISTORY_SIZE]; diff --git a/lib/MycilaAppInfo/MycilaAppInfo.cpp b/lib/MycilaAppInfo/MycilaAppInfo.cpp index 6c51bf9..85351df 100644 --- a/lib/MycilaAppInfo/MycilaAppInfo.cpp +++ b/lib/MycilaAppInfo/MycilaAppInfo.cpp @@ -7,6 +7,8 @@ #include #include +#include + #ifndef APP_NAME #define APP_NAME "Beelance" #endif @@ -40,15 +42,15 @@ Mycila::AppInfoClass::AppInfoClass() : id(Mycila::System::getChipIDStr()), nameModel(name + " " + model), nameModelVersion(name + " " + model + " " + version), manufacturer(APP_MANUFACTURER), - firmware(String(APP_NAME) + (isdigit(version.charAt(0)) ? "-v" : "-") + (version.indexOf("_") >= 0 ? version.substring(0, version.indexOf("_")) : version) + "-" + __COMPILED_BUILD_NAME__ + ".bin"), + firmware(std::string(APP_NAME) + (std::isdigit(version[0]) ? "-v" : "-") + version.substr(0, version.find("_")) + "-" + __COMPILED_BUILD_NAME__ + ".bin"), buildBranch(__COMPILED_BUILD_BRANCH__), buildHash(__COMPILED_BUILD_HASH__), buildDate(__COMPILED_BUILD_TIMESTAMP__), - defaultHostname(Mycila::Str::lowerCaseCopy(name + "-" + id)), - defaultMqttClientId(Mycila::Str::lowerCaseCopy(name + "_" + id)), + defaultHostname(Mycila::string::toLowerCase(name + "-" + id)), + defaultMqttClientId(Mycila::string::toLowerCase(name + "_" + id)), defaultSSID(name + "-" + id), - debug(firmware.indexOf("debug") >= 0), - trial(firmware.indexOf("trial") >= 0) {} + debug(firmware.find("debug") != std::string::npos), + trial(firmware.find("trial") != std::string::npos) {} void Mycila::AppInfoClass::toJson(const JsonObject& root) const { root["build_date"] = buildDate; diff --git a/lib/MycilaAppInfo/MycilaAppInfo.h b/lib/MycilaAppInfo/MycilaAppInfo.h index 0e8500c..05903fc 100644 --- a/lib/MycilaAppInfo/MycilaAppInfo.h +++ b/lib/MycilaAppInfo/MycilaAppInfo.h @@ -5,7 +5,8 @@ #pragma once #include -#include + +#include namespace Mycila { class AppInfoClass { @@ -15,20 +16,20 @@ namespace Mycila { void toJson(const JsonObject& root) const; public: - const String id; - const String name; - const String model; - const String version; - const String nameModel; - const String nameModelVersion; - const String manufacturer; - const String firmware; - const String buildBranch; - const String buildHash; - const String buildDate; - const String defaultHostname; - const String defaultMqttClientId; - const String defaultSSID; + const std::string id; + const std::string name; + const std::string model; + const std::string version; + const std::string nameModel; + const std::string nameModelVersion; + const std::string manufacturer; + const std::string firmware; + const std::string buildBranch; + const std::string buildHash; + const std::string buildDate; + const std::string defaultHostname; + const std::string defaultMqttClientId; + const std::string defaultSSID; const bool debug; const bool trial; }; diff --git a/lib/MycilaModem/MycilaModem.cpp b/lib/MycilaModem/MycilaModem.cpp index 769c681..bd3cb1e 100644 --- a/lib/MycilaModem/MycilaModem.cpp +++ b/lib/MycilaModem/MycilaModem.cpp @@ -6,11 +6,15 @@ #include #include +#include #include +#include +#include + #if defined(TINY_GSM_MODEM_A7670) && defined(MYCILA_GPS_RX_PIN) && defined(MYCILA_GPS_TX_PIN) -#define TINY_GSM_MODEM_A7670G 1 -#include + #define TINY_GSM_MODEM_A7670G 1 + #include TinyGPSPlus tinyGPS; #endif @@ -56,31 +60,31 @@ void Mycila::ModemClass::loop() { if (_modem.init(_pin.c_str())) { logger.info(TAG, "SIM Ready!"); - _error = emptyString; + _error = std::string(); #ifdef TINY_GSM_MODEM_SIM7080 // 2 Automatic _modem.setNetworkMode(2); // NB-IoT bands - String nbiotBands = "+CBANDCFG=\"NB-IOT\","; - nbiotBands.concat(_bands[MODEM_MODE_NB_IOT]); + std::string nbiotBands = "+CBANDCFG=\"NB-IOT\","; + nbiotBands += _bands[MODEM_MODE_NB_IOT]; _modem.sendAT(nbiotBands.c_str()); _modem.waitResponse(); // LTE-M bands - String ltemBands = "+CBANDCFG=\"CAT-M\","; - ltemBands.concat(_bands[MODEM_MODE_LTE_M]); + std::string ltemBands = "+CBANDCFG=\"CAT-M\","; + ltemBands += _bands[MODEM_MODE_LTE_M]; _modem.sendAT(ltemBands.c_str()); _modem.waitResponse(); // APN - _modem.sendAT("+CNCFG=0,1,\"", _apn, "\""); + _modem.sendAT("+CNCFG=0,1,\"", _apn.c_str(), "\""); _modem.waitResponse(); #endif // APN - _modem.sendAT("+CGDCONT=1,\"IP\",\"", _apn, "\""); + _modem.sendAT("+CGDCONT=1,\"IP\",\"", _apn.c_str(), "\""); _modem.waitResponse(); // go to registration @@ -170,7 +174,7 @@ void Mycila::ModemClass::loop() { // de-register _modem.sendAT("+COPS=2"); _modem.waitResponse(); - _operator = emptyString; + _operator = std::string(); // https://help.onomondo.com/en/how-to-clear-the-fplmn-list // Query state: AT+CRSM=176,28539,0,0,12AT+CRSM=176,28539,0,0,12 @@ -191,17 +195,15 @@ void Mycila::ModemClass::loop() { ModemOperatorSearchResult op; op.state = static_cast(_spy.parseInt()); _spy.readStringUntil('"'); - op.name = _spy.readStringUntil('"'); - op.name.trim(); + op.name = Mycila::string::trim(_spy.readStringUntil('"').c_str()); _spy.readStringUntil('"'); _spy.readStringUntil('"'); _spy.readStringUntil('"'); - op.code = _spy.readStringUntil('"'); - op.code.trim(); + op.code = Mycila::string::trim(_spy.readStringUntil('"').c_str()); _spy.readStringUntil(','); op.mode = _spy.parseInt(); - if (!op.name.isEmpty()) { + if (!op.name.empty()) { if (op.state == MODEM_OPERATOR_FORBIDDEN) { logger.warn(TAG, "Skipping forbidden operator %s (%d)", op.name.c_str(), op.mode); } else { @@ -296,25 +298,25 @@ void Mycila::ModemClass::setDebug(bool debug) { if (debug) { _readBuffer.reserve(512); _writeBuffer.reserve(512); - _readBuffer.concat("<< "); - _writeBuffer.concat(">> "); + _readBuffer += "<< "; + _writeBuffer += ">> "; _spy.onRead(std::bind(&Mycila::ModemClass::_onRead, this, std::placeholders::_1, std::placeholders::_2)); _spy.onWrite(std::bind(&Mycila::ModemClass::_onWrite, this, std::placeholders::_1, std::placeholders::_2)); } else { _spy.onRead(nullptr); _spy.onWrite(nullptr); - _readBuffer = emptyString; - _writeBuffer = emptyString; + _readBuffer = std::string(); + _writeBuffer = std::string(); } } -int Mycila::ModemClass::sendTCP(const String& host, uint16_t port, const String& payload, const uint16_t connectTimeoutSec) { +int Mycila::ModemClass::sendTCP(const std::string& host, uint16_t port, const std::string& payload, const uint16_t connectTimeoutSec) { TinyGsmClient client(_modem); client.setTimeout(connectTimeoutSec * 1000); int code = ESP_ERR_TIMEOUT; if (client.connect(host.c_str(), port, connectTimeoutSec)) { - client.print(payload); + client.print(payload.c_str()); client.flush(); client.stop(); code = ESP_OK; @@ -323,8 +325,8 @@ int Mycila::ModemClass::sendTCP(const String& host, uint16_t port, const String& } #ifdef TINY_GSM_MODEM_A7670 -int Mycila::ModemClass::httpPOST(const String& url, const String& payload, const uint16_t connectTimeoutSec) { - if (url.isEmpty() || payload.isEmpty()) +int Mycila::ModemClass::httpPOST(const std::string& url, const std::string& payload, const uint16_t connectTimeoutSec) { + if (url.empty() || payload.empty()) return ESP_ERR_INVALID_ARG; if (!_modem.https_begin()) @@ -334,7 +336,7 @@ int Mycila::ModemClass::httpPOST(const String& url, const String& payload, const return ESP_ERR_INVALID_ARG; _modem.https_set_timeout(connectTimeoutSec); - _modem.https_set_user_agent(_model); + _modem.https_set_user_agent(_model.c_str()); _modem.https_set_content_type("application/json"); if (_modem.https_post(payload.c_str()) == -1) return ESP_ERR_INVALID_STATE; @@ -344,8 +346,8 @@ int Mycila::ModemClass::httpPOST(const String& url, const String& payload, const #endif #ifdef TINY_GSM_MODEM_SIM7080 -int Mycila::ModemClass::httpPOST(const String& url, const String& payload, const uint16_t connectTimeoutSec) { - if (url.isEmpty() || payload.isEmpty()) +int Mycila::ModemClass::httpPOST(const std::string& url, const std::string& payload, const uint16_t connectTimeoutSec) { + if (url.empty() || payload.empty()) return ESP_ERR_INVALID_ARG; if (!_modem.isNetworkConnected()) @@ -356,10 +358,10 @@ int Mycila::ModemClass::httpPOST(const String& url, const String& payload, const HOST, PORT, PATH } state = PROTOCOL; - String protocol; - String host; - String port; - String path = "/"; + std::string protocol; + std::string host; + std::string port; + std::string path = "/"; for (int i = 0; i < url.length(); i++) { switch (state) { @@ -367,12 +369,12 @@ int Mycila::ModemClass::httpPOST(const String& url, const String& payload, const if (url[i] == ':') state = URLParseState::SEPERATOR; else - protocol.concat(url[i]); + protocol += url[i]; break; case URLParseState::SEPERATOR: if (url[i] != '/') { state = HOST; - host.concat(url[i]); + host += url[i]; } break; case URLParseState::HOST: @@ -381,16 +383,16 @@ int Mycila::ModemClass::httpPOST(const String& url, const String& payload, const else if (url[i] == '/') state = PATH; else - host.concat(url[i]); + host += url[i]; break; case URLParseState::PORT: if (url[i] == '/') state = PATH; else - port.concat(url[i]); + port += url[i]; break; case URLParseState::PATH: - path.concat(url[i]); + path += url[i]; break; default: assert(false); @@ -398,34 +400,34 @@ int Mycila::ModemClass::httpPOST(const String& url, const String& payload, const } } - protocol.toLowerCase(); + std::transform(protocol.begin(), protocol.end(), protocol.begin(), ::tolower); - if (host.isEmpty() || (protocol != "http" && protocol != "https")) + if (host.empty() || (protocol != "http" && protocol != "https")) return ESP_ERR_INVALID_ARG; int ret = HTTP_SUCCESS; if (protocol == "https") { - const uint16_t httpsPort = port.isEmpty() ? 443 : port.toInt(); + const uint16_t httpsPort = port.empty() ? 443 : std::stol(port); TinyGsmClientSecure client(_modem); client.setTimeout(connectTimeoutSec * 1000); if (client.connect(host.c_str(), httpsPort, connectTimeoutSec)) { - HttpClient http(client, host, httpsPort); + HttpClient http(client, host.c_str(), httpsPort); http.setTimeout(connectTimeoutSec * 1000); - ret = http.post(path, "application/json", payload); + ret = http.post(path.c_str(), "application/json", payload.c_str()); http.stop(); } else { ret = HTTP_ERROR_CONNECTION_FAILED; } } else if (protocol == "http") { - const uint16_t httpPort = port.isEmpty() ? 80 : port.toInt(); + const uint16_t httpPort = port.empty() ? 80 : std::stol(port); TinyGsmClient client(_modem); client.setTimeout(connectTimeoutSec * 1000); if (client.connect(host.c_str(), httpPort, connectTimeoutSec)) { - HttpClient http(client, host, httpPort); + HttpClient http(client, host.c_str(), httpPort); http.setTimeout(connectTimeoutSec * 1000); - ret = http.post(path, "application/json", payload); + ret = http.post(path.c_str(), "application/json", payload.c_str()); http.stop(); } else { ret = HTTP_ERROR_CONNECTION_FAILED; @@ -453,24 +455,24 @@ int Mycila::ModemClass::httpPOST(const String& url, const String& payload, const void Mycila::ModemClass::_onRead(const uint8_t* buffer, size_t size) { if (size) { - _readBuffer.concat((const char*)buffer, size); - if (_readBuffer.endsWith("\n")) { - size = _readBuffer.endsWith("\r\n") ? _readBuffer.length() - 2 : _readBuffer.length() - 1; + _readBuffer.append((const char*)buffer, size); + if (Mycila::string::endsWith(_readBuffer, "\n")) { + size = Mycila::string::endsWith(_readBuffer, "\r\n") ? _readBuffer.length() - 2 : _readBuffer.length() - 1; logger.debug(TAG, "%.*s", size, _readBuffer.c_str()); _readBuffer.clear(); - _readBuffer.concat("<< "); + _readBuffer += "<< "; } } } void Mycila::ModemClass::_onWrite(const uint8_t* buffer, size_t size) { if (size) { - _writeBuffer.concat((const char*)buffer, size); - if (_writeBuffer.endsWith("\n")) { - size = _writeBuffer.endsWith("\r\n") ? _writeBuffer.length() - 2 : _writeBuffer.length() - 1; + _writeBuffer.append((const char*)buffer, size); + if (Mycila::string::endsWith(_writeBuffer, "\n")) { + size = Mycila::string::endsWith(_writeBuffer, "\r\n") ? _writeBuffer.length() - 2 : _writeBuffer.length() - 1; logger.debug(TAG, "%.*s", size, _writeBuffer.c_str()); _writeBuffer.clear(); - _writeBuffer.concat(">> "); + _writeBuffer += ">> "; } } } @@ -562,8 +564,8 @@ bool Mycila::ModemClass::_syncTime() { setenv("TZ", _timeZoneInfo.c_str(), 1); tzset(); - String time = Mycila::Time::getLocalStr(); - if (!time.isEmpty()) { + std::string time = Mycila::Time::getLocalStr(); + if (!time.empty()) { logger.info(TAG, "Time synced from GPS: %s", time.c_str()); return true; } @@ -586,8 +588,8 @@ bool Mycila::ModemClass::_syncTime() { setenv("TZ", _timeZoneInfo.c_str(), 1); tzset(); - String time = Mycila::Time::getLocalStr(); - if (!time.isEmpty()) { + std::string time = Mycila::Time::getLocalStr(); + if (!time.empty()) { logger.info(TAG, "Time synced from cellular network: %s", time.c_str()); return true; } @@ -602,12 +604,12 @@ void Mycila::ModemClass::_syncInfo() { _signal = sq >= 0 && sq <= 31 ? map(sq, 0, 31, 0, 100) : 0; // misc info - _iccid = _modem.getSimCCID(); - _imei = _modem.getIMEI(); - _imsi = _modem.getIMSI(); - _localIP = _modem.getLocalIP(); - _model = _modem.getModemName(); - _operator = _modem.getOperator(); + _iccid = _modem.getSimCCID().c_str(); + _imei = _modem.getIMEI().c_str(); + _imsi = _modem.getIMSI().c_str(); + _localIP = _modem.getLocalIP().c_str(); + _model = _modem.getModemName().c_str(); + _operator = _modem.getOperator().c_str(); } void Mycila::ModemClass::_sync() { @@ -629,8 +631,8 @@ void Mycila::ModemClass::_dequeueATCommands() { if (_commands.size()) { for (size_t i = 0; i < _commands.size(); i++) { logger.info(TAG, "Execute command: %s", _commands[i].c_str()); - if (_commands[i].startsWith("AT+")) - _modem.sendAT(_commands[i].substring(2).c_str()); + if (Mycila::string::startsWith(_commands[i], "AT+")) + _modem.sendAT(_commands[i].substr(2).c_str()); else _modem.sendAT(_commands[i].c_str()); delay(5000); diff --git a/lib/MycilaModem/MycilaModem.h b/lib/MycilaModem/MycilaModem.h index 1018c67..488cad3 100644 --- a/lib/MycilaModem/MycilaModem.h +++ b/lib/MycilaModem/MycilaModem.h @@ -8,6 +8,7 @@ #include #include +#include #include #ifndef MYCILA_MODEM_SERIAL @@ -75,8 +76,8 @@ namespace Mycila { typedef struct { ModemOperatorState state; - String name; // operator name - String code; // operator code + std::string name; // operator name + std::string code; // operator code uint8_t mode; // technology access mode } ModemOperatorSearchResult; @@ -110,40 +111,40 @@ namespace Mycila { ModemGPSState getGPSState() const { return _gpsState; } std::vector getDiscoveredOperators() const { return _operators; } - String getAPN() const { return _apn; } - String getTimeZoneInfo() const { return _timeZoneInfo; } - String getBands(ModemMode mode) { return mode == MODEM_MODE_AUTO ? "" : _bands[mode]; } - String getError() const { return _error; } - String getICCID() const { return _iccid; } - String getIMEI() const { return _imei; } - String getIMSI() const { return _imsi; } - String getLocalIP() const { return _localIP; } - String getModel() const { return _model; } - String getOperator() const { return _operator; } - String getPIN() const { return _pin; } + const std::string& getAPN() const { return _apn; } + const std::string& getTimeZoneInfo() const { return _timeZoneInfo; } + std::string getBands(ModemMode mode) { return mode == MODEM_MODE_AUTO ? "" : _bands[mode]; } + const std::string& getError() const { return _error; } + const std::string& getICCID() const { return _iccid; } + const std::string& getIMEI() const { return _imei; } + const std::string& getIMSI() const { return _imsi; } + const std::string& getLocalIP() const { return _localIP; } + const std::string& getModel() const { return _model; } + const std::string& getOperator() const { return _operator; } + const std::string& getPIN() const { return _pin; } // 0-100% uint8_t getSignalQuality() const { return _signal; } - void setAPN(const String& apn) { _apn = apn; } - void setTimeZoneInfo(const String& timeZoneInfo) { _timeZoneInfo = timeZoneInfo; } - void setBands(ModemMode mode, const String& bands) { _bands[mode] = bands; } + void setAPN(const std::string& apn) { _apn = apn; } + void setTimeZoneInfo(const std::string& timeZoneInfo) { _timeZoneInfo = timeZoneInfo; } + void setBands(ModemMode mode, const std::string& bands) { _bands[mode] = bands; } void setDebug(bool debug); - void setPIN(const String& pin) { _pin = pin; } + void setPIN(const std::string& pin) { _pin = pin; } void setPreferredMode(ModemMode mode) { _mode = mode; } void setGpsSyncTimeout(uint32_t timeoutSec) { _gpsSyncTimeout = timeoutSec; } void setCallback(ModemStateChangeCallback callback) { _callback = callback; } - void enqueueAT(const String& cmd) { _commands.push_back(cmd); } + void enqueueAT(const char* cmd) { _commands.push_back(cmd); } void scanForOperators() { _state = MODEM_SEARCHING; } void powerOff(); bool activateData(); void activateGPS(); // Returns ESP_OK or ESP_ERR_TIMEOUT if connection times out - int sendTCP(const String& host, uint16_t port, const String& payload, const uint16_t connectTimeoutSec = MYCILA_MODEM_CONNECT_TIMEOUT); + int sendTCP(const std::string& host, uint16_t port, const std::string& payload, const uint16_t connectTimeoutSec = MYCILA_MODEM_CONNECT_TIMEOUT); // Returns ESP_OK or ESP_ERR_TIMEOUT if connection times out - int httpPOST(const String& url, const String& payload, const uint16_t connectTimeoutSec = MYCILA_MODEM_CONNECT_TIMEOUT); + int httpPOST(const std::string& url, const std::string& payload, const uint16_t connectTimeoutSec = MYCILA_MODEM_CONNECT_TIMEOUT); private: // model and streams @@ -152,8 +153,8 @@ namespace Mycila { private: // debug - String _readBuffer; - String _writeBuffer; + std::string _readBuffer; + std::string _writeBuffer; private: // GPS and Time @@ -161,25 +162,25 @@ namespace Mycila { ModemGPSState _gpsState = MODEM_GPS_OFF; uint32_t _gpsSyncStartTime = 0; ModemGPSData _gpsData; - String _timeZoneInfo = "UTC0"; + std::string _timeZoneInfo = "UTC0"; private: // Modem info - String _iccid; - String _imei; - String _imsi; - String _localIP; - String _model; - String _operator; + std::string _iccid; + std::string _imei; + std::string _imsi; + std::string _localIP; + std::string _model; + std::string _operator; uint8_t _signal; private: // Modem settings ModemMode _mode = MODEM_MODE_AUTO; - String _apn; - String _pin; + std::string _apn; + std::string _pin; uint32_t _gpsSyncTimeout = MYCILA_MODEM_GPS_SYNC_TIMEOUT; - std::map _bands = { + std::map _bands = { {MODEM_MODE_LTE_M, "1,2,3,4,5,8,12,13,14,18,19,20,25,26,2 7,28,66,85"}, {MODEM_MODE_NB_IOT, "1,2,3,4,5,8,12,13,18,19,20,25,26,28,6 6,71,85"}, }; @@ -196,9 +197,9 @@ namespace Mycila { // state machine ModemState _state = MODEM_OFF; ModemStateChangeCallback _callback = nullptr; - String _error; + std::string _error; uint32_t _lastRefreshTime = 0; - std::vector _commands; + std::vector _commands; private: // utilities diff --git a/platformio.ini b/platformio.ini index e191470..e714a26 100644 --- a/platformio.ini +++ b/platformio.ini @@ -15,7 +15,7 @@ default_envs = lilygo_t_a7670g, lilygo_t_sim7080g [env] framework = arduino -platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc2/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc3/platform-espressif32.zip monitor_filters = esp32_exception_decoder, log2file monitor_speed = 115200 @@ -45,21 +45,22 @@ lib_compat_mode = strict lib_ldf_mode = chain lib_deps = https://github.com/mathieucarbou/arduino-libraries-ArduinoHttpClient#dev - bblanchon/ArduinoJson @ 7.2.0 - mathieucarbou/AsyncTCP @ 3.2.12 + bblanchon/ArduinoJson @ 7.2.1 + mathieucarbou/AsyncTCP @ 3.2.14 mathieucarbou/ESPAsyncWebServer @ 3.3.22 - mathieucarbou/MycilaConfig @ 3.1.0 - mathieucarbou/MycilaDS18 @ 4.1.0 - mathieucarbou/MycilaESPConnect @ 6.1.0 - mathieucarbou/MycilaLogger @ 3.2.0 - mathieucarbou/MycilaSystem @ 3.1.0 - mathieucarbou/MycilaTaskManager @ 3.1.2 - mathieucarbou/MycilaTaskMonitor @ 3.0.1 - mathieucarbou/MycilaUtilities @ 2.0.0 - mathieucarbou/MycilaWebSerial @ 6.4.1 - mathieucarbou/StreamDebugger @ 2.1.0 + mathieucarbou/MycilaConfig @ 7.0.3 + mathieucarbou/MycilaDS18 @ 4.1.1 + mathieucarbou/MycilaESPConnect @ 7.0.0 + mathieucarbou/MycilaLogger @ 3.2.1 + mathieucarbou/MycilaSystem @ 4.0.0 + mathieucarbou/MycilaTaskManager @ 3.1.3 + mathieucarbou/MycilaTaskMonitor @ 3.0.2 + mathieucarbou/MycilaUtilities @ 3.1.1 + mathieucarbou/MycilaWebSerial @ 7.0.1 + mathieucarbou/StreamDebugger @ 2.1.2 https://github.com/mathieucarbou/lewisxhe-TinyGSM#dev - ayushsharma82/ESP-DASH @ 4.0.8 + ; ayushsharma82/ESP-DASH @ 4.0.8 + https://github.com/mathieucarbou/ayushsharma82-ESP-DASH#dev robtillaart/HX711 @ 0.5.0 build_flags = @@ -73,6 +74,8 @@ build_flags = -D CONFIG_ASYNC_TCP_STACK_SIZE=5120 ; ESPAsyncWebServer -D WS_MAX_QUEUED_MESSAGES=64 + ; ESP-DASH with STL string + -D DASH_USE_STL_STRING=1 ; Mycila -D MYCILA_JSON_SUPPORT -D MYCILA_LOGGER_SUPPORT diff --git a/src/BeelanceClass.cpp b/src/BeelanceClass.cpp index 2f91cf1..17d4ed9 100644 --- a/src/BeelanceClass.cpp +++ b/src/BeelanceClass.cpp @@ -8,6 +8,7 @@ #include #include +#include #define TAG "BEELANCE" @@ -37,12 +38,12 @@ bool Beelance::BeelanceClass::isNightModeActive() const { return false; } - const int inRange = Mycila::Time::timeInRange(timeInfo, config.get(KEY_NIGHT_START_TIME).c_str(), config.get(KEY_NIGHT_STOP_TIME).c_str()); + const int inRange = Mycila::Time::timeInRange(timeInfo, config.get(KEY_NIGHT_START_TIME), config.get(KEY_NIGHT_STOP_TIME)); return inRange != -1 && inRange; } uint32_t Beelance::BeelanceClass::getDelayUntilNextSend() const { - const int itvl = config.get(KEY_SEND_INTERVAL).toInt() < BEELANCE_MIN_SEND_DELAY ? BEELANCE_MIN_SEND_DELAY : config.get(KEY_SEND_INTERVAL).toInt(); + const int itvl = config.getLong(KEY_SEND_INTERVAL) < BEELANCE_MIN_SEND_DELAY ? BEELANCE_MIN_SEND_DELAY : config.getLong(KEY_SEND_INTERVAL); if (!Mycila::Modem.isTimeSynced()) { // modem time not synced @@ -63,7 +64,7 @@ uint32_t Beelance::BeelanceClass::getDelayUntilNextSend() const { total += itvl; time_t unixTime = now + total; localtime_r(&unixTime, &timeInfo); - } while (Mycila::Time::timeInRange(timeInfo, config.get(KEY_NIGHT_START_TIME).c_str(), config.get(KEY_NIGHT_STOP_TIME).c_str()) == 1); + } while (Mycila::Time::timeInRange(timeInfo, config.get(KEY_NIGHT_START_TIME), config.get(KEY_NIGHT_STOP_TIME)) == 1); if (total == itvl) { // the next send time is not within the night time range @@ -73,7 +74,7 @@ uint32_t Beelance::BeelanceClass::getDelayUntilNextSend() const { // total is after the night time range // total - itvl is still within the night time range - const int stopTimeMins = Mycila::Time::toMinutes(config.get(KEY_NIGHT_STOP_TIME).c_str()); + const int stopTimeMins = Mycila::Time::toMinutes(config.get(KEY_NIGHT_STOP_TIME)); const time_t unixTime = now + total - itvl; struct tm timeInfo; @@ -108,14 +109,13 @@ bool Beelance::BeelanceClass::sendMeasurements() { return false; } - // if (config.get(KEY_SEND_URL).isEmpty() && Mycila::Modem.getAPN() != "onomondo") { - if (config.get(KEY_SEND_URL).isEmpty()) { + if (config.isEmpty(KEY_SEND_URL)) { logger.error(TAG, "Unable to send measurements: no URL defined"); return false; } JsonDocument doc; - String payload; + std::string payload; payload.reserve(512); toJson(doc.to()); serializeJson(doc, payload); @@ -123,8 +123,8 @@ bool Beelance::BeelanceClass::sendMeasurements() { _recordMeasurement(doc["ts"].as(), doc["temp"].as(), doc["wt"].as()); _saveHistory(); - if (!config.get(KEY_SEND_URL).isEmpty()) { - const String url = config.get(KEY_SEND_URL); + if (!config.isEmpty(KEY_SEND_URL)) { + const std::string& url = config.getString(KEY_SEND_URL); logger.info(TAG, "Sending measurements to %s...", url.c_str()); switch (Mycila::Modem.httpPOST(url, payload)) { case ESP_OK: @@ -244,10 +244,10 @@ bool Beelance::BeelanceClass::mustSleep() const { void Beelance::BeelanceClass::_recordMeasurement(const time_t timestamp, const float temperature, const int32_t weight) { logger.info(TAG, "Record measurement: temperature = %.2f C, weight = %d g", temperature, weight); - const String dt = Mycila::Time::toLocalStr(timestamp); // 2024-04-12 15:02:17 - const String hhmm = dt.substring(11, 16); // 15:02 - const String hour = dt.substring(11, 13) + ":00"; // 15:00 - const String day = dt.substring(5, 10); // 2024-04-12 + const std::string dt = Mycila::Time::toLocalStr(timestamp); // 2024-04-12 15:02:17 + const std::string hhmm = dt.substr(11, 16); // 15:02 + const std::string hour = dt.substr(11, 13) + ":00"; // 15:00 + const std::string day = dt.substr(5, 10); // 2024-04-12 bool found = false; for (auto& entry : latestHistory) { @@ -309,32 +309,32 @@ void Beelance::BeelanceClass::_loadHistory() { logger.info(TAG, "Load history..."); JsonDocument doc; - JsonObject root = doc.to(); if (LittleFS.exists(FILE_HISTORY)) { File file = LittleFS.open(FILE_HISTORY, "r"); if (file) { - deserializeJson(root, file); + deserializeJson(doc, file); file.close(); + JsonObject root = doc.as(); // latestHistory latestHistory.clear(); JsonArray latest = root["latest"].as(); for (int len = latest.size(), i = max(0, len - BEELANCE_MAX_HISTORY_SIZE); i < len; i++) - latestHistory.push_back({latest[i]["time"].as(), latest[i]["temp"].as(), latest[i]["wt"].as()}); + latestHistory.push_back({latest[i]["time"].as(), latest[i]["temp"].as(), latest[i]["wt"].as()}); // hourlyHistory hourlyHistory.clear(); JsonArray hourly = root["hourly"].as(); for (int len = hourly.size(), i = max(0, len - BEELANCE_MAX_HISTORY_SIZE); i < len; i++) - hourlyHistory.push_back({hourly[i]["time"].as(), hourly[i]["temp"].as(), hourly[i]["wt"].as()}); + hourlyHistory.push_back({hourly[i]["time"].as(), hourly[i]["temp"].as(), hourly[i]["wt"].as()}); // dailyHistory dailyHistory.clear(); JsonArray daily = root["daily"].as(); for (int len = daily.size(), i = max(0, len - BEELANCE_MAX_HISTORY_SIZE); i < len; i++) - dailyHistory.push_back({daily[i]["time"].as(), daily[i]["temp"].as(), daily[i]["wt"].as()}); + dailyHistory.push_back({daily[i]["time"].as(), daily[i]["temp"].as(), daily[i]["wt"].as()}); } else { logger.error(TAG, "Unable to open file: " FILE_HISTORY); diff --git a/src/Beelance_API_REST.cpp b/src/Beelance_API_REST.cpp index 684a94b..47b557d 100644 --- a/src/Beelance_API_REST.cpp +++ b/src/Beelance_API_REST.cpp @@ -6,7 +6,10 @@ #include #include +#include + #include +#include #define TAG "BEELANCE" @@ -25,7 +28,7 @@ void Beelance::BeelanceClass::_initREST() { webServer .on("/api/config/backup", HTTP_GET, [](AsyncWebServerRequest* request) { - String body; + StreamString body; body.reserve(4096); config.backup(body); AsyncWebServerResponse* response = request->beginResponse(200, "text/plain", body); @@ -42,7 +45,7 @@ void Beelance::BeelanceClass::_initREST() { return request->send(400, "text/plain", "No config file uploaded"); } StreamString* buffer = reinterpret_cast(request->_tempObject); - config.restore(*buffer); + config.restore((*buffer).c_str()); delete buffer; request->_tempObject = nullptr; request->send(200, "text/plain", "OK"); @@ -63,12 +66,12 @@ void Beelance::BeelanceClass::_initREST() { webServer .on("/api/config", HTTP_POST, [](AsyncWebServerRequest* request) { - std::map settings; + std::map settings; for (size_t i = 0, max = request->params(); i < max; i++) { const AsyncWebParameter* p = request->getParam(i); if (p->isPost() && !p->isFile()) { const char* keyRef = config.keyRef(p->name().c_str()); - settings[keyRef] = p->value(); + settings[keyRef] = p->value().c_str(); } } request->send(200); diff --git a/src/Beelance_Config.cpp b/src/Beelance_Config.cpp index 72f101f..428f663 100644 --- a/src/Beelance_Config.cpp +++ b/src/Beelance_Config.cpp @@ -6,25 +6,27 @@ #include +#include + #define TAG "BEELANCE" void Beelance::BeelanceClass::_initConfig() { logger.info(TAG, "Initializing Config System..."); - config.begin(28); + config.begin("BEELANCE"); config.configure(KEY_ADMIN_PASSWORD); config.configure(KEY_AP_MODE_ENABLE, "true"); config.configure(KEY_BEEHIVE_NAME, Mycila::AppInfo.defaultHostname); config.configure(KEY_DEBUG_ENABLE, "false"); - config.configure(KEY_HX711_CLOCK_PIN, String(BEELANCE_HX711_CLOCK_PIN)); - config.configure(KEY_HX711_DATA_PIN, String(BEELANCE_HX711_DATA_PIN)); + config.configure(KEY_HX711_CLOCK_PIN, std::to_string(BEELANCE_HX711_CLOCK_PIN)); + config.configure(KEY_HX711_DATA_PIN, std::to_string(BEELANCE_HX711_DATA_PIN)); config.configure(KEY_HX711_OFFSET, "0"); config.configure(KEY_HX711_SCALE, "1"); config.configure(KEY_MODEM_APN); config.configure(KEY_MODEM_BANDS_LTE_M, "1,3,8,20,28"); config.configure(KEY_MODEM_BANDS_NB_IOT, "3,8,20"); - config.configure(KEY_MODEM_GPS_SYNC_TIMEOUT, String(MYCILA_MODEM_GPS_SYNC_TIMEOUT)); + config.configure(KEY_MODEM_GPS_SYNC_TIMEOUT, std::to_string(MYCILA_MODEM_GPS_SYNC_TIMEOUT)); config.configure(KEY_MODEM_MODE, "AUTO"); config.configure(KEY_MODEM_PIN); config.configure(KEY_NIGHT_START_TIME, "23:00"); @@ -33,7 +35,7 @@ void Beelance::BeelanceClass::_initConfig() { config.configure(KEY_PMU_CHARGING_CURRENT, "500"); config.configure(KEY_SEND_INTERVAL, "3600"); config.configure(KEY_SEND_URL); - config.configure(KEY_TEMPERATURE_PIN, String(BEELANCE_TEMPERATURE_PIN)); + config.configure(KEY_TEMPERATURE_PIN, std::to_string(BEELANCE_TEMPERATURE_PIN)); config.configure(KEY_TIMEZONE_INFO, "CET-1CEST,M3.5.0,M10.5.0/3"); config.configure(KEY_WIFI_PASSWORD); config.configure(KEY_WIFI_SSID); diff --git a/src/Beelance_EventHandlers.cpp b/src/Beelance_EventHandlers.cpp index 66a794a..f6e7b63 100644 --- a/src/Beelance_EventHandlers.cpp +++ b/src/Beelance_EventHandlers.cpp @@ -6,6 +6,8 @@ #include #include +#include + #define TAG "EVENTS" void refresh() { @@ -72,8 +74,10 @@ void Beelance::BeelanceClass::_initEventHandlers() { } }); - config.listen([this](const String& key, const String& oldValue, const String& newValue) { - logger.info(TAG, "Set %s: '%s' => '%s'", key.c_str(), oldValue.c_str(), newValue.c_str()); + config.listen([this](const char* k, const std::string& newValue) { + logger.info(TAG, "'%s' => '%s'", k, newValue.c_str()); + const std::string key = k; + if (key == KEY_AP_MODE_ENABLE && (espConnect.getState() == Mycila::ESPConnect::State::AP_STARTED || espConnect.getState() == Mycila::ESPConnect::State::NETWORK_CONNECTING || espConnect.getState() == Mycila::ESPConnect::State::NETWORK_CONNECTED || espConnect.getState() == Mycila::ESPConnect::State::NETWORK_TIMEOUT || espConnect.getState() == Mycila::ESPConnect::State::NETWORK_DISCONNECTED || espConnect.getState() == Mycila::ESPConnect::State::NETWORK_RECONNECTING)) { restartTask.resume(); @@ -82,19 +86,19 @@ void Beelance::BeelanceClass::_initEventHandlers() { esp_log_level_set("*", static_cast(logger.getLevel())); } else if (key == KEY_MODEM_APN) { - Mycila::Modem.setAPN(config.get(KEY_MODEM_APN)); + Mycila::Modem.setAPN(config.getString(KEY_MODEM_APN)); } else if (key == KEY_MODEM_PIN) { - Mycila::Modem.setPIN(config.get(KEY_MODEM_PIN)); + Mycila::Modem.setPIN(config.getString(KEY_MODEM_PIN)); } else if (key == KEY_MODEM_BANDS_LTE_M) { - Mycila::Modem.setBands(Mycila::ModemMode::MODEM_MODE_LTE_M, config.get(KEY_MODEM_BANDS_LTE_M)); + Mycila::Modem.setBands(Mycila::ModemMode::MODEM_MODE_LTE_M, config.getString(KEY_MODEM_BANDS_LTE_M)); } else if (key == KEY_MODEM_BANDS_NB_IOT) { - Mycila::Modem.setBands(Mycila::ModemMode::MODEM_MODE_NB_IOT, config.get(KEY_MODEM_BANDS_NB_IOT)); + Mycila::Modem.setBands(Mycila::ModemMode::MODEM_MODE_NB_IOT, config.getString(KEY_MODEM_BANDS_NB_IOT)); } else if (key == KEY_MODEM_MODE) { - String tech = config.get(KEY_MODEM_MODE); + const std::string& tech = config.getString(KEY_MODEM_MODE); if (tech == "LTE-M") { Mycila::Modem.setPreferredMode(Mycila::ModemMode::MODEM_MODE_LTE_M); } else if (tech == "NB-IoT") { @@ -104,25 +108,25 @@ void Beelance::BeelanceClass::_initEventHandlers() { } } else if (key == KEY_MODEM_GPS_SYNC_TIMEOUT) { - Mycila::Modem.setGpsSyncTimeout(config.get(KEY_MODEM_GPS_SYNC_TIMEOUT).toInt()); + Mycila::Modem.setGpsSyncTimeout(config.getLong(KEY_MODEM_GPS_SYNC_TIMEOUT)); } else if (key == KEY_TIMEZONE_INFO) { - logger.info(TAG, "Setting timezone to %s", config.get(KEY_TIMEZONE_INFO).c_str()); - Mycila::Modem.setTimeZoneInfo(config.get(KEY_TIMEZONE_INFO)); - setenv("TZ", config.get(KEY_TIMEZONE_INFO).c_str(), 1); + logger.info(TAG, "Setting timezone to %s", config.get(KEY_TIMEZONE_INFO)); + Mycila::Modem.setTimeZoneInfo(config.getString(KEY_TIMEZONE_INFO)); + setenv("TZ", config.get(KEY_TIMEZONE_INFO), 1); tzset(); } else if (key == KEY_HX711_OFFSET) { - logger.info(TAG, "Setting HX711 offset to %d", config.get(KEY_HX711_OFFSET).toInt()); - hx711.setOffset(config.get(KEY_HX711_OFFSET).toInt()); + logger.info(TAG, "Setting HX711 offset to %d", config.getLong(KEY_HX711_OFFSET)); + hx711.setOffset(config.getLong(KEY_HX711_OFFSET)); } else if (key == KEY_HX711_SCALE) { - logger.info(TAG, "Setting HX711 scale to %f", config.get(KEY_HX711_SCALE).toFloat()); - hx711.setScale(config.get(KEY_HX711_SCALE).toFloat()); + logger.info(TAG, "Setting HX711 scale to %f", config.getFloat(KEY_HX711_SCALE)); + hx711.setScale(config.getFloat(KEY_HX711_SCALE)); } else if (key == KEY_PMU_CHARGING_CURRENT) { - logger.info(TAG, "Setting charging current to %d mA", config.get(KEY_PMU_CHARGING_CURRENT).toInt()); - Mycila::PMU.setChargingCurrent(config.get(KEY_PMU_CHARGING_CURRENT).toInt()); + logger.info(TAG, "Setting charging current to %d mA", config.getLong(KEY_PMU_CHARGING_CURRENT)); + Mycila::PMU.setChargingCurrent(config.getLong(KEY_PMU_CHARGING_CURRENT)); } }); diff --git a/src/Beelance_Tasks.cpp b/src/Beelance_Tasks.cpp index 2be06b4..ad4f66f 100644 --- a/src/Beelance_Tasks.cpp +++ b/src/Beelance_Tasks.cpp @@ -4,6 +4,8 @@ */ #include +#include + #define TAG "BEELANCE" static const Mycila::TaskPredicate DEBUG_ENABLED = []() { @@ -20,12 +22,12 @@ Mycila::Task modemLoopTask("Modem.loop()", [](void* params) { Mycila::Modem.loop Mycila::Task serialDebugATTask("serialDebugAT", [](void* params) { if (Serial.available()) { - String msg; + std::string msg; msg.reserve(128); while (Serial.available()) - msg.concat(static_cast(Serial.read())); - if (msg.startsWith("AT+")) { - Mycila::Modem.enqueueAT(msg); + msg += Serial.read(); + if (Mycila::string::startsWith(msg, "AT+")) { + Mycila::Modem.enqueueAT(msg.c_str()); } } }); @@ -38,12 +40,12 @@ Mycila::Task hx711Task("hx711.read()", [](void* params) { hx711.read(); }); Mycila::Task hx711TareTask("hx711.tare()", Mycila::TaskType::ONCE, [](void* params) { hx711.tare(); - config.set(KEY_HX711_OFFSET, String(hx711.getOffset())); - config.set(KEY_HX711_SCALE, String(hx711.getScale())); + config.set(KEY_HX711_OFFSET, std::to_string(hx711.getOffset())); + config.set(KEY_HX711_SCALE, std::to_string(hx711.getScale())); }); Mycila::Task hx711ScaleTask("hx711.calibrate()", Mycila::TaskType::ONCE, [](void* params) { - config.set(KEY_HX711_SCALE, String(hx711.calibrate(calibrationWeight), 6)); + config.set(KEY_HX711_SCALE, Mycila::string::to_string(hx711.calibrate(calibrationWeight), 6)); calibrationWeight = 0; }); @@ -70,12 +72,12 @@ Mycila::Task resetTask("resetTask", Mycila::TaskType::ONCE, [](void* params) { }); Mycila::Task startModemTask("startModemTask", Mycila::TaskType::ONCE, [](void* params) { - Mycila::Modem.setPIN(config.get(KEY_MODEM_PIN)); - Mycila::Modem.setAPN(config.get(KEY_MODEM_APN)); - Mycila::Modem.setTimeZoneInfo(config.get(KEY_TIMEZONE_INFO)); - Mycila::Modem.setGpsSyncTimeout(config.get(KEY_MODEM_GPS_SYNC_TIMEOUT).toInt()); + Mycila::Modem.setPIN(config.getString(KEY_MODEM_PIN)); + Mycila::Modem.setAPN(config.getString(KEY_MODEM_APN)); + Mycila::Modem.setTimeZoneInfo(config.getString(KEY_TIMEZONE_INFO)); + Mycila::Modem.setGpsSyncTimeout(config.getLong(KEY_MODEM_GPS_SYNC_TIMEOUT)); // mode - String tech = config.get(KEY_MODEM_MODE); + const std::string& tech = config.getString(KEY_MODEM_MODE); if (tech == "LTE-M") { Mycila::Modem.setPreferredMode(Mycila::ModemMode::MODEM_MODE_LTE_M); } else if (tech == "NB-IoT") { @@ -84,8 +86,8 @@ Mycila::Task startModemTask("startModemTask", Mycila::TaskType::ONCE, [](void* p Mycila::Modem.setPreferredMode(Mycila::ModemMode::MODEM_MODE_AUTO); } // bands - Mycila::Modem.setBands(Mycila::ModemMode::MODEM_MODE_LTE_M, config.get(KEY_MODEM_BANDS_LTE_M)); - Mycila::Modem.setBands(Mycila::ModemMode::MODEM_MODE_NB_IOT, config.get(KEY_MODEM_BANDS_NB_IOT)); + Mycila::Modem.setBands(Mycila::ModemMode::MODEM_MODE_LTE_M, config.getString(KEY_MODEM_BANDS_LTE_M)); + Mycila::Modem.setBands(Mycila::ModemMode::MODEM_MODE_NB_IOT, config.getString(KEY_MODEM_BANDS_NB_IOT)); // start modem if (Mycila::Modem.getState() == Mycila::ModemState::MODEM_OFF) { logger.info(TAG, "Enable Modem..."); diff --git a/src/Beelance_Website_Init.cpp b/src/Beelance_Website_Init.cpp index 037c080..3c9a69e 100644 --- a/src/Beelance_Website_Init.cpp +++ b/src/Beelance_Website_Init.cpp @@ -6,6 +6,8 @@ #include +#include + #define TAG "WEBSITE" extern const uint8_t logo_jpeg_gz_start[] asm("_binary__pio_data_logo_jpeg_gz_start"); @@ -17,7 +19,7 @@ void Beelance::WebsiteClass::init() { authMiddleware.setAuthType(AsyncAuthType::AUTH_DIGEST); authMiddleware.setRealm("YaSolR"); authMiddleware.setUsername(BEELANCE_ADMIN_USERNAME); - authMiddleware.setPassword(config.get(KEY_ADMIN_PASSWORD).c_str()); + authMiddleware.setPassword(config.get(KEY_ADMIN_PASSWORD)); authMiddleware.generateHash(); webServer.addMiddleware(&authMiddleware); @@ -52,32 +54,32 @@ void Beelance::WebsiteClass::init() { // web console WebSerial.begin(&webServer, "/console"); - WebSerial.onMessage([](const String& msg) { - if (msg.startsWith("AT+")) { + WebSerial.onMessage([](const std::string& msg) { + if (Mycila::string::startsWith(msg, "AT+")) { logger.info(TAG, "Enqueue AT Command: %s...", msg.c_str()); - Mycila::Modem.enqueueAT(msg); + Mycila::Modem.enqueueAT(msg.c_str()); } }); logger.forwardTo(&WebSerial); // app stats - _firmName.set((Mycila::AppInfo.name.c_str())); - _firmVersionStat.set(Mycila::AppInfo.version.c_str()); - _firmManufacturerStat.set(Mycila::AppInfo.manufacturer.c_str()); + _firmName.set(Mycila::AppInfo.name); + _firmVersionStat.set(Mycila::AppInfo.version); + _firmManufacturerStat.set(Mycila::AppInfo.manufacturer); - _firmFilenameStat.set(Mycila::AppInfo.firmware.c_str()); - _firmHashStat.set(Mycila::AppInfo.buildHash.c_str()); - _firmTimeStat.set(Mycila::AppInfo.buildDate.c_str()); + _firmFilenameStat.set(Mycila::AppInfo.firmware); + _firmHashStat.set(Mycila::AppInfo.buildHash); + _firmTimeStat.set(Mycila::AppInfo.buildDate); - _deviceIdStat.set(Mycila::System::getChipIDStr().c_str()); + _deviceIdStat.set(Mycila::System::getChipIDStr()); _cpuModelStat.set(ESP.getChipModel()); - _cpuCoresStat.set(String(ESP.getChipCores()).c_str()); - _bootCountStat.set(String(Mycila::System::getBootCount()).c_str()); + _cpuCoresStat.set(std::to_string(ESP.getChipCores())); + _bootCountStat.set(std::to_string(Mycila::System::getBootCount())); _bootReasonStat.set(Mycila::System::getLastRebootReason()); - _heapMemoryTotalStat.set((String(ESP.getHeapSize()) + " bytes").c_str()); + _heapMemoryTotalStat.set(std::to_string(ESP.getHeapSize()) + " bytes"); - _hostnameStat.set(Mycila::AppInfo.defaultHostname.c_str()); + _hostnameStat.set(Mycila::AppInfo.defaultHostname); // home callbacks diff --git a/src/Beelance_Website_Update.cpp b/src/Beelance_Website_Update.cpp index 5f1016a..179385f 100644 --- a/src/Beelance_Website_Update.cpp +++ b/src/Beelance_Website_Update.cpp @@ -4,6 +4,8 @@ */ #include +#include + #define TAG "WEBSITE" void Beelance::WebsiteClass::_update(bool skipWebSocketPush) { @@ -15,13 +17,13 @@ void Beelance::WebsiteClass::_update(bool skipWebSocketPush) { Mycila::System::Memory memory; Mycila::System::getMemory(memory); - _heapMemoryUsageStat.set((String(memory.usage) + " %").c_str()); - _heapMemoryUsedStat.set((String(memory.used) + " bytes").c_str()); + _heapMemoryUsageStat.set((Mycila::string::to_string(memory.usage, 2) + " %")); + _heapMemoryUsedStat.set(std::to_string(memory.used) + " bytes"); - _modemModelStat.set(Mycila::Modem.getModel().c_str()); - _modemICCIDStat.set(Mycila::Modem.getICCID().c_str()); - _modemIMEIStat.set(Mycila::Modem.getIMEI().c_str()); - _modemIMSIStat.set(Mycila::Modem.getIMSI().c_str()); + _modemModelStat.set(Mycila::Modem.getModel()); + _modemICCIDStat.set(Mycila::Modem.getICCID()); + _modemIMEIStat.set(Mycila::Modem.getIMEI()); + _modemIMSIStat.set(Mycila::Modem.getIMSI()); switch (Mycila::Modem.getMode()) { case ::Mycila::ModemMode::MODEM_MODE_LTE_M: _modemModePrefStat.set("LTE-M"); @@ -33,27 +35,27 @@ void Beelance::WebsiteClass::_update(bool skipWebSocketPush) { _modemModePrefStat.set("Auto"); break; } - _modemLTEMBandsStat.set(Mycila::Modem.getBands(Mycila::ModemMode::MODEM_MODE_LTE_M).c_str()); - _modemNBIoTBandsStat.set(Mycila::Modem.getBands(Mycila::ModemMode::MODEM_MODE_NB_IOT).c_str()); - _modemIpStat.set(Mycila::Modem.getLocalIP().c_str()); + _modemLTEMBandsStat.set(Mycila::Modem.getBands(Mycila::ModemMode::MODEM_MODE_LTE_M)); + _modemNBIoTBandsStat.set(Mycila::Modem.getBands(Mycila::ModemMode::MODEM_MODE_NB_IOT)); + _modemIpStat.set(Mycila::Modem.getLocalIP()); _apIPStat.set(espConnect.getIPAddress(Mycila::ESPConnect::Mode::AP).toString().c_str()); - _apMACStat.set(espConnect.getMACAddress(Mycila::ESPConnect::Mode::AP).c_str()); + _apMACStat.set(espConnect.getMACAddress(Mycila::ESPConnect::Mode::AP)); _wifiIPStat.set(espConnect.getIPAddress(Mycila::ESPConnect::Mode::STA).toString().c_str()); - _wifiMACStat.set(espConnect.getMACAddress(Mycila::ESPConnect::Mode::STA).c_str()); - _wifiSSIDStat.set(espConnect.getWiFiSSID().c_str()); - _wifiRSSIStat.set((String(espConnect.getWiFiRSSI()) + " dBm").c_str()); - _wifiSignalStat.set((String(espConnect.getWiFiSignalQuality()) + " %").c_str()); - _hx711WeightStat.set((String(hx711.getWeight(), 0) + " g").c_str()); - _hx711TareStat.set((String(hx711.getTare(), 0) + " g").c_str()); - _hx711OffsetStat.set(String(hx711.getOffset()).c_str()); - _hx711ScaleStat.set(String(hx711.getScale(), 6).c_str()); + _wifiMACStat.set(espConnect.getMACAddress(Mycila::ESPConnect::Mode::STA)); + _wifiSSIDStat.set(espConnect.getWiFiSSID()); + _wifiRSSIStat.set(std::to_string(espConnect.getWiFiRSSI()) + " dBm"); + _wifiSignalStat.set(std::to_string(espConnect.getWiFiSignalQuality()) + " %"); + _hx711WeightStat.set(std::to_string(static_cast(hx711.getWeight())) + " g"); + _hx711TareStat.set(std::to_string(static_cast(hx711.getTare())) + " g"); + _hx711OffsetStat.set(std::to_string(hx711.getOffset())); + _hx711ScaleStat.set(Mycila::string::to_string(hx711.getScale(), 6)); - _pmuLowBatShutThreshold.set((String(Mycila::PMU.readLowBatteryShutdownThreshold()) + " %").c_str()); + _pmuLowBatShutThreshold.set(std::to_string(Mycila::PMU.readLowBatteryShutdownThreshold()) + " %"); // home - _bhName.update(config.get(KEY_BEEHIVE_NAME).c_str()); + _bhName.update(config.get(KEY_BEEHIVE_NAME)); // weight if (!hx711.isEnabled()) { @@ -91,8 +93,11 @@ void Beelance::WebsiteClass::_update(bool skipWebSocketPush) { _time.update("Syncing...", DASH_STATUS_WARNING); break; case Mycila::ModemTimeState::MODEM_TIME_SYNCED: { - String time = Mycila::Time::getLocalStr(); - _time.update(time.isEmpty() ? "Syncing..." : time.c_str(), time.isEmpty() ? DASH_STATUS_WARNING : DASH_STATUS_SUCCESS); + std::string time = Mycila::Time::getLocalStr(); + if (time.empty()) + _time.update("Syncing...", DASH_STATUS_WARNING); + else + _time.update(time, DASH_STATUS_SUCCESS); break; } default: @@ -113,9 +118,9 @@ void Beelance::WebsiteClass::_update(bool skipWebSocketPush) { _altitude.update("Syncing...", DASH_STATUS_WARNING); break; case Mycila::ModemGPSState::MODEM_GPS_SYNCED: - _latitude.update(String(Mycila::Modem.getGPSData().latitude, 6).c_str(), DASH_STATUS_SUCCESS); - _longitude.update(String(Mycila::Modem.getGPSData().longitude, 6).c_str(), DASH_STATUS_SUCCESS); - _altitude.update((String(Mycila::Modem.getGPSData().altitude) + " m").c_str(), DASH_STATUS_SUCCESS); + _latitude.update(Mycila::string::to_string(Mycila::Modem.getGPSData().latitude, 6), DASH_STATUS_SUCCESS); + _longitude.update(Mycila::string::to_string(Mycila::Modem.getGPSData().longitude, 6), DASH_STATUS_SUCCESS); + _altitude.update(std::to_string(Mycila::Modem.getGPSData().altitude) + " m", DASH_STATUS_SUCCESS); break; case Mycila::ModemGPSState::MODEM_GPS_TIMEOUT: _latitude.update("Timeout!", DASH_STATUS_DANGER); @@ -151,14 +156,14 @@ void Beelance::WebsiteClass::_update(bool skipWebSocketPush) { _modemState.update("Ready", DASH_STATUS_SUCCESS); break; case Mycila::ModemState::MODEM_ERROR: - _modemState.update(Mycila::Modem.getError().c_str(), DASH_STATUS_DANGER); + _modemState.update(Mycila::Modem.getError(), DASH_STATUS_DANGER); break; default: assert(false); break; } - _modemAPN.update(Mycila::Modem.getAPN().c_str(), Mycila::Modem.getAPN().isEmpty() ? DASH_STATUS_DANGER : DASH_STATUS_SUCCESS); + _modemAPN.update(Mycila::Modem.getAPN(), Mycila::Modem.getAPN().empty() ? DASH_STATUS_DANGER : DASH_STATUS_SUCCESS); // operator switch (Mycila::Modem.getState()) { @@ -169,18 +174,18 @@ void Beelance::WebsiteClass::_update(bool skipWebSocketPush) { case Mycila::ModemState::MODEM_WAIT_REGISTRATION: case Mycila::ModemState::MODEM_SEARCHING: { const Mycila::ModemOperatorSearchResult* candidate = Mycila::Modem.getCandidate(); - _modemOperator.update(candidate ? (candidate->name + " (" + candidate->mode + ") ?").c_str() : "", candidate ? DASH_STATUS_WARNING : DASH_STATUS_IDLE); + _modemOperator.update(candidate ? candidate->name + " (" + std::to_string(candidate->mode) + ") ?" : std::string(), candidate ? DASH_STATUS_WARNING : DASH_STATUS_IDLE); break; } case Mycila::ModemState::MODEM_GPS: case Mycila::ModemState::MODEM_CONNECTING: - if (Mycila::Modem.getOperator().isEmpty()) + if (Mycila::Modem.getOperator().empty()) _modemOperator.update("", DASH_STATUS_WARNING); else - _modemOperator.update(Mycila::Modem.getOperator().c_str(), DASH_STATUS_SUCCESS); + _modemOperator.update(Mycila::Modem.getOperator(), DASH_STATUS_SUCCESS); break; case Mycila::ModemState::MODEM_READY: - _modemOperator.update(Mycila::Modem.getOperator().c_str(), DASH_STATUS_SUCCESS); + _modemOperator.update(Mycila::Modem.getOperator(), DASH_STATUS_SUCCESS); break; case Mycila::ModemState::MODEM_ERROR: _modemOperator.update("", DASH_STATUS_IDLE); @@ -195,14 +200,14 @@ void Beelance::WebsiteClass::_update(bool skipWebSocketPush) { if (Mycila::PMU.isBatteryCharging()) { float level = Mycila::PMU.getBatteryLevel(); if (level > 0) { - _power.update((String("Bat. charging: ") + static_cast(floor(level))).c_str(), "%"); + _power.update(std::string("Bat. charging: ") + Mycila::string::to_string(floor(level), 2), "%"); } else { _power.update("Bat. charging...", ""); } } else if (Mycila::PMU.isBatteryDischarging()) { float level = Mycila::PMU.getBatteryLevel(); if (level > 0) { - _power.update((String("Bat. discharging: ") + static_cast(floor(level))).c_str(), "%"); + _power.update(std::string("Bat. discharging: ") + Mycila::string::to_string(floor(level), 2), "%"); } else { _power.update("Bat. discharging...", ""); } @@ -211,7 +216,7 @@ void Beelance::WebsiteClass::_update(bool skipWebSocketPush) { } _volt.update(Mycila::PMU.getBatteryVoltage()); - _uptime.update(Mycila::Time::toDHHMMSS(Mycila::System::getUptime()).c_str()); + _uptime.update(Mycila::Time::toDHHMMSS(Mycila::System::getUptime())); _restart.update(!restartTask.isPaused()); _sendNow.update(sendTask.isRunning() || (sendTask.isEnabled() && !sendTask.isPaused() && sendTask.isEarlyRunRequested())); @@ -223,15 +228,15 @@ void Beelance::WebsiteClass::_update(bool skipWebSocketPush) { int idx = 0; while (idx < BEELANCE_MAX_HISTORY_SIZE) { - _chartLatestX[idx] = emptyString; + _chartLatestX[idx] = std::string(); _chartLatestTempY[idx] = 0; _chartLatestWeightY[idx] = 0; - _chartHourlyX[idx] = emptyString; + _chartHourlyX[idx] = std::string(); _chartHourlyTempY[idx] = 0; _chartHourlyWeightY[idx] = 0; - _chartDailyX[idx] = emptyString; + _chartDailyX[idx] = std::string(); _chartDailyTempY[idx] = 0; _chartDailyWeightY[idx] = 0; diff --git a/src/main.cpp b/src/main.cpp index a440a2f..7949236 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,8 +16,8 @@ Mycila::Logger logger; Mycila::Config config; Mycila::TaskManager hx711TaskManager("hx711"); -Mycila::TaskManager loopTaskManager("loopTask"); -Mycila::TaskManager modemTaskManager("modemTask"); +Mycila::TaskManager loopTaskManager("beelance"); +Mycila::TaskManager modemTaskManager("modem"); Mycila::HX711 hx711; Mycila::DS18 temperatureSensor; @@ -52,30 +52,30 @@ void setup() { Mycila::PMU.begin(); Mycila::PMU.enableDCPins(); Mycila::PMU.setChargingLedMode(XPOWERS_CHG_LED_ON); - Mycila::PMU.setChargingCurrent(config.get(KEY_PMU_CHARGING_CURRENT).toInt()); + Mycila::PMU.setChargingCurrent(config.getLong(KEY_PMU_CHARGING_CURRENT)); logger.info(TAG, "Powering Modem..."); Mycila::PMU.enableModem(); logger.info(TAG, "Powering GPS..."); Mycila::PMU.enableGPS(); // Temperature - temperatureSensor.begin(config.get(KEY_TEMPERATURE_PIN).toInt()); + temperatureSensor.begin(config.getLong(KEY_TEMPERATURE_PIN)); if (!temperatureSensor.isEnabled()) { Beelance::Website.disableTemperature(); } // HX711 logger.info(TAG, "Configure HX711..."); - hx711.setOffset(config.get(KEY_HX711_OFFSET).toInt()); - hx711.setScale(config.get(KEY_HX711_SCALE).toFloat()); + hx711.setOffset(config.getLong(KEY_HX711_OFFSET)); + hx711.setScale(config.getFloat(KEY_HX711_SCALE)); hx711.setExpirationDelay(10); - hx711.begin(config.get(KEY_HX711_DATA_PIN).toInt(), config.get(KEY_HX711_CLOCK_PIN).toInt()); + hx711.begin(config.getLong(KEY_HX711_DATA_PIN), config.getLong(KEY_HX711_CLOCK_PIN)); // stack monitor Mycila::TaskMonitor.begin(5); Mycila::TaskMonitor.addTask("async_tcp"); // ESPAsyncTCP - Mycila::TaskMonitor.addTask("loopTask"); // Arduino - Mycila::TaskMonitor.addTask("modemTask"); // Modem + Mycila::TaskMonitor.addTask("beelance"); // Beelance + Mycila::TaskMonitor.addTask("modem"); // Modem Mycila::TaskMonitor.addTask("hx711"); // HX711 // network @@ -83,15 +83,16 @@ void setup() { espConnect.end(); espConnect.setAutoRestart(true); espConnect.setBlocking(false); - espConnect.begin(Mycila::AppInfo.defaultHostname.c_str(), Mycila::AppInfo.defaultSSID.c_str(), config.get(KEY_ADMIN_PASSWORD).c_str(), {config.get(KEY_WIFI_SSID).c_str(), config.get(KEY_WIFI_PASSWORD).c_str(), config.getBool(KEY_AP_MODE_ENABLE)}); + espConnect.begin(Mycila::AppInfo.defaultHostname.c_str(), Mycila::AppInfo.defaultSSID.c_str(), config.get(KEY_ADMIN_PASSWORD), {config.get(KEY_WIFI_SSID), config.get(KEY_WIFI_PASSWORD), config.getBool(KEY_AP_MODE_ENABLE)}); - assert(modemTaskManager.asyncStart(BEELANCE_MODEM_TASK_STACK_SIZE, uxTaskPriorityGet(NULL), xPortGetCoreID())); - assert(hx711TaskManager.asyncStart(BEELANCE_HX711_TASK_STACK_SIZE, uxTaskPriorityGet(NULL), xPortGetCoreID())); + assert(loopTaskManager.asyncStart(512 * 19, uxTaskPriorityGet(NULL), xPortGetCoreID())); + assert(modemTaskManager.asyncStart(512 * 11, uxTaskPriorityGet(NULL), xPortGetCoreID())); + assert(hx711TaskManager.asyncStart(512 * 6, uxTaskPriorityGet(NULL), xPortGetCoreID())); // STARTUP READY! logger.info(TAG, "Started %s", Mycila::AppInfo.nameModelVersion.c_str()); } void loop() { - loopTaskManager.loop(); + vTaskDelete(NULL); }