diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/CurrentTransformerCard.cpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/CurrentTransformerCard.cpp index f5ce161..d9f230c 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/CurrentTransformerCard.cpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/CurrentTransformerCard.cpp @@ -84,6 +84,9 @@ void CurrentTransformerCard::saveEnergy(){ } void CurrentTransformerCard::loadEnergy(){ this->fram->read(this->framAddress, (uint8_t*)&this->energy, sizeof(this->energy)); + if (this->energy < 0 || isnan(this->energy)) { + this->energy = 0; + } } void CurrentTransformerCard::setEnergyAutoSave(bool autoSave){ diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.cpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.cpp index 86ad5a1..fc9f2cf 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.cpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.cpp @@ -3,8 +3,8 @@ /** * @brief Create a new Digital Input Card object with the specified address * @note If you are using the ESPMegaI/O board, you should use the dip switch constructor - * - * @param address_a The ESPMegaI/O address of bank A + * + * @param address_a The ESPMegaI/O address of bank A * @param address_b The ESPMegaI/O address of bank B */ DigitalInputCard::DigitalInputCard(uint8_t address_a, uint8_t address_b) : callbacks() @@ -16,11 +16,11 @@ DigitalInputCard::DigitalInputCard(uint8_t address_a, uint8_t address_b) : callb /** * @brief Create a new Digital Input Card object with the specified position on the dip switch - * + * * @note The bit 0 are at the left of the dip switch - * + * * @warning There are 6 switches on the dip switch, 3 for bank A and 3 for bank B, They should be unique for each bank accross all the cards - * + * * @param bit0 The position of the first switch on the dip switch * @param bit1 The position of the second switch on the dip switch * @param bit2 The position of the third switch on the dip switch @@ -50,19 +50,23 @@ DigitalInputCard::DigitalInputCard(bool bit0, bool bit1, bool bit2, bool bit3, b /** * @brief Initialize the Digital Input Card - * + * * @return True if the initialization is successful, false otherwise */ bool DigitalInputCard::begin() { this->inputBankA = PCF8574(this->address_a); this->inputBankB = PCF8574(this->address_b); - if (!this->inputBankA.begin()) { + if (!this->inputBankA.begin()) + { ESP_LOGE("DigitalInputCard", "Input Card ERROR: Failed to install input bank A"); + this->initOk = false; return false; } - if (!this->inputBankB.begin()) { + if (!this->inputBankB.begin()) + { ESP_LOGE("DigitalInputCard", "Input Card ERROR: Failed to install input bank B"); + this->initOk = false; return false; } // Set the debounce time for all pins to 50ms @@ -77,12 +81,13 @@ bool DigitalInputCard::begin() this->pinMap[i] = i; this->virtualPinMap[i] = i; } + this->initOk = true; return true; } /** * @brief Read the input from the specified pin, always refresh the input buffers - * + * * @param pin The pin to read from * @return True if the pin is HIGH, false if the pin is LOW */ @@ -93,13 +98,18 @@ bool DigitalInputCard::digitalRead(uint8_t pin) /** * @brief Read the input from the specified pin, also refresh the input buffers if refresh is true - * + * * @param pin The pin to read from * @param refresh If true, the input buffers will be refreshed before reading the pin * @return True if the pin is HIGH, false if the pin is LOW */ bool DigitalInputCard::digitalRead(uint8_t pin, bool refresh) { + if(!this->initOk) + { + ESP_LOGE("DigitalInputCard", "Input Card ERROR: Card not initialized"); + return false; + } pin = pinMap[pin]; // First check if the pin is in bank A or B if (pin >= 0 && pin <= 7) @@ -118,14 +128,14 @@ bool DigitalInputCard::digitalRead(uint8_t pin, bool refresh) // Extract the bit from the buffer return ((inputBufferB >> (15 - pin)) & 1); } - return 255; + return false; } /** * @brief Check if the specified pin changed since the last call to this function - * + * * @note This function compares the current input buffer with the previous input buffer to detect changes - * + * * @param pin The pin to check * @param currentBuffer The current input buffer * @param previousBuffer The previous input buffer @@ -134,33 +144,89 @@ void DigitalInputCard::handlePinChange(int pin, uint8_t ¤tBuffer, uint8_t { // Get the index of the pin in the pin map uint8_t virtualPin = virtualPinMap[pin]; - // Handle Bank A - if (((previousBuffer >> (7 - pin)) & 1) != ((currentBuffer >> (7 - pin)) & 1)) + if (pin < 8) { - if (millis() - lastDebounceTime[pin] > debounceTime[pin]) + // Handle Bank A + if (((previousBuffer >> (7 - pin)) & 1) != ((currentBuffer >> (7 - pin)) & 1)) { - lastDebounceTime[pin] = millis(); - previousBuffer ^= (-((currentBuffer >> (7 - pin)) & 1) ^ previousBuffer) & (1UL << (7 - pin)); - for(const auto& callback : callbacks) - callback.second(virtualPin, ((currentBuffer >> (7 - pin)) & 1)); + // When the pin first change, store the time + if (!pinChanged[virtualPin]) + { + ESP_LOGD("DigitalInputCard", "Pin %d changed", virtualPin); + pinChanged[virtualPin] = true; + lastDebounceTime[virtualPin] = millis(); + } + else + { + ESP_LOGD("DigitalInputCard", "Pin %d (%d>%d) debounce time: %d", virtualPin, ((previousBuffer >> (7 - pin)) & 1), ((currentBuffer >> (7 - pin)) & 1), millis() - lastDebounceTime[virtualPin]); + // If the pin was already changed, check if the debounce time has passed + if ((millis() - lastDebounceTime[virtualPin]) > debounceTime[virtualPin]) + { + ESP_LOGD("DigitalInputCard", "Pin %d triggered", virtualPin); + // Call the callback function + for (auto const &callback : callbacks) + { + callback.second(virtualPin, ((currentBuffer >> (7 - pin)) & 1)); + } + // Store the previous buffer at the specified pin (bitwise operation) + // new value : (currentBuffer >> (7 - pin)) & 1) + previousBuffer = (previousBuffer & ~(1 << (7 - pin))) | (((currentBuffer >> (7 - pin)) & 1) << (7 - pin)); + // Reset the pin changed flag + pinChanged[virtualPin] = false; + } + } + } + else + { + // Pin bounce back to previous state, reset the debounce time + lastDebounceTime[virtualPin] = millis(); + pinChanged[virtualPin] = false; } } - // Handle Bank B - if (((previousBuffer >> (15 - pin)) & 1) != ((currentBuffer >> (15 - pin)) & 1)) + else { - if (millis() - lastDebounceTime[pin] > debounceTime[pin]) + // Handle Bank B + if (((previousBuffer >> (15 - pin)) & 1) != ((currentBuffer >> (15 - pin)) & 1)) { - lastDebounceTime[pin] = millis(); - previousBuffer ^= (-((currentBuffer >> (15 - pin)) & 1) ^ previousBuffer) & (1UL << (15 - pin)); - for (const auto& callback : callbacks) - callback.second(virtualPin, ((currentBuffer >> (15 - pin)) & 1)); + // When the pin first change, store the time + if (!pinChanged[virtualPin]) + { + ESP_LOGD("DigitalInputCard", "Pin %d changed", virtualPin); + pinChanged[virtualPin] = true; + lastDebounceTime[virtualPin] = millis(); + } + else + { + ESP_LOGD("DigitalInputCard", "Pin %d (%d>%d) debounce time: %d", virtualPin, ((previousBuffer >> (15 - pin)) & 1), ((currentBuffer >> (15 - pin)) & 1), millis() - lastDebounceTime[virtualPin]); + // If the pin was already changed, check if the debounce time has passed + if ((millis() - lastDebounceTime[virtualPin]) > debounceTime[virtualPin]) + { + ESP_LOGD("DigitalInputCard", "Pin %d triggered", virtualPin); + // Call the callback function + for (auto const &callback : callbacks) + { + callback.second(virtualPin, ((currentBuffer >> (15 - pin)) & 1)); + } + // Store the previous buffer at the specified pin (bitwise operation) + // new value : (currentBuffer >> (15 - pin)) & 1) + previousBuffer = (previousBuffer & ~(1 << (15 - pin))) | (((currentBuffer >> (15 - pin)) & 1) << (15 - pin)); + // Reset the pin changed flag + pinChanged[virtualPin] = false; + } + } + } + else + { + // Pin bounce back to previous state, reset the debounce time + lastDebounceTime[virtualPin] = millis(); + pinChanged[virtualPin] = false; } } } /** - * @brief A loop to refresh the input buffers and check for pin changes - * + * @brief A loop to refresh the input buffers and check for pin changes + * * @note Although this function can be called in the main loop, it is recommended install the card in ESPMega to automatically manage the loop */ // Preform a loop to refresh the input buffers @@ -186,7 +252,7 @@ void DigitalInputCard::loop() /** * @brief Get the input buffer for bank A (the first 8 pins) - * + * * @return The input buffer for bank A where the first bit is the first pin and the last bit is the last pin */ uint8_t DigitalInputCard::getInputBufferA() @@ -202,7 +268,7 @@ uint8_t DigitalInputCard::getInputBufferA() /** * @brief Get the input buffer for bank B (the last 8 pins) - * + * * @return The input buffer for bank B where the first bit is the first pin and the last bit is the last pin */ uint8_t DigitalInputCard::getInputBufferB() @@ -218,7 +284,7 @@ uint8_t DigitalInputCard::getInputBufferB() /** * @brief Register a callback function to be called when a pin changes - * + * * @param callback The callback function to be called * @return The handler of the callback function */ @@ -233,6 +299,11 @@ uint8_t DigitalInputCard::registerCallback(std::function ca */ void DigitalInputCard::refreshInputBankA() { + if(!this->initOk) + { + ESP_LOGE("DigitalInputCard", "Input Card ERROR: Card not initialized"); + return; + } inputBufferA = inputBankA.read8(); } @@ -241,16 +312,21 @@ void DigitalInputCard::refreshInputBankA() */ void DigitalInputCard::refreshInputBankB() { + if(!this->initOk) + { + ESP_LOGE("DigitalInputCard", "Input Card ERROR: Card not initialized"); + return; + } inputBufferB = inputBankB.read8(); } /** * @brief Set the debounce time for the specified pin - * + * * Debounce is the time in milliseconds that the pin should be stable before the callback function is called * This is useful to prevent false triggers when the input is noisy * An example of this is when the input is connected to a mechanical switch - * + * * @param pin The pin to set the debounce time for * @param debounceTime The debounce time in milliseconds */ @@ -262,7 +338,7 @@ void DigitalInputCard::setDebounceTime(uint8_t pin, uint32_t debounceTime) /** * @brief Unregister a callback function - * + * * @param handler The handler of the callback function to unregister */ void DigitalInputCard::unregisterCallback(uint8_t handler) @@ -272,12 +348,12 @@ void DigitalInputCard::unregisterCallback(uint8_t handler) /** * @brief Load the pin map for the card - * + * * A pin map is an array of 16 elements that maps the physical pins to virtual pins * The virtual pins are the pins that are used in the callback functions and are used for all the functions in this class * The physical pins are the pins on the Input IC, This can be found on the schematic of the ESPMegaI/O board * This function is useful if you want to change the number identification of the pins to match your project needs - * + * * @param pinMap The pin map to load */ void DigitalInputCard::loadPinMap(uint8_t pinMap[16]) @@ -293,10 +369,33 @@ void DigitalInputCard::loadPinMap(uint8_t pinMap[16]) /** * @brief Get the type of the card - * + * * @return The type of the card */ uint8_t DigitalInputCard::getType() { return CARD_TYPE_DIGITAL_INPUT; +} + +/** + * @brief Preload the previous input buffer and the input buffer + * + * @note This function is useful if you want to preload the input buffers with a run-time value + */ +void DigitalInputCard::preloadInputBuffer() +{ + refreshInputBankA(); + refreshInputBankB(); + previousInputBufferA = inputBufferA; + previousInputBufferB = inputBufferB; +} + +/** + * @brief Get the status of the card + * + * @return True if the card is initialized, false otherwise + */ +bool DigitalInputCard::getStatus() +{ + return this->initOk; } \ No newline at end of file diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.hpp index a140029..d73f639 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.hpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputCard.hpp @@ -41,9 +41,14 @@ class DigitalInputCard : public ExpansionCard { void unregisterCallback(uint8_t handler); // Load a new pin map void loadPinMap(uint8_t pinMap[16]); + // Preload previousInputBuffer and inputBuffer + void preloadInputBuffer(); + // Status of card + bool getStatus(); // Get type of card uint8_t getType(); private: + bool initOk = false; PCF8574 inputBankA; PCF8574 inputBankB; uint8_t address_a; @@ -54,6 +59,7 @@ class DigitalInputCard : public ExpansionCard { uint8_t previousInputBufferB; uint32_t debounceTime[16]; uint32_t lastDebounceTime[16]; + bool pinChanged[16]; // A map of the physical pin to the virtual pin uint8_t pinMap[16]; // A map of the virtual pin to the physical pin diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputIoT.cpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputIoT.cpp index f138e52..ac1ba0c 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputIoT.cpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalInputIoT.cpp @@ -17,6 +17,9 @@ */ bool DigitalInputIoT::begin(uint8_t card_id, ExpansionCard *card, PubSubClient *mqtt, char *base_topic) { this->card = (DigitalInputCard *)card; + if(!this->card->getStatus()) { + return false; + } this->card_id = card_id; this->mqtt = mqtt; this->base_topic = base_topic; diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalOutputCard.cpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalOutputCard.cpp index cefa8e8..9735579 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalOutputCard.cpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalOutputCard.cpp @@ -32,7 +32,7 @@ DigitalOutputCard::DigitalOutputCard(uint8_t address) : change_callbacks(){ * @param bit4 The position of the fifth switch on the dip switch */ DigitalOutputCard::DigitalOutputCard(bool bit0, bool bit1, bool bit2, bool bit3, bool bit4) : - DigitalOutputCard(0x20+bit0+bit1*2+bit2*4+bit3*8+bit4*16) + DigitalOutputCard(0x40+bit0+bit1*2+bit2*4+bit3*8+bit4*16) { @@ -306,4 +306,13 @@ void DigitalOutputCard::saveStateToFRAM() { if(!framBinded) return; uint16_t packed = packStates(); this->fram->write16(framAddress, packed); +} + +/** + * @brief Toggle the state of the specified pin + * + * @param pin The pin to toggle + */ +void DigitalOutputCard::toggleState(uint8_t pin) { + this->setState(pin, !this->state_buffer[pin]); } \ No newline at end of file diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalOutputCard.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalOutputCard.hpp index a3ed97c..88ebbaa 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalOutputCard.hpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/DigitalOutputCard.hpp @@ -58,6 +58,8 @@ public: void setValue(uint8_t pin, uint16_t value); // Get the state of the specified pin bool getState(uint8_t pin); + // Toggle the state of the specified pin + void toggleState(uint8_t pin); // Get the pwm value of the specified pin uint16_t getValue(uint8_t pin); // Register a callback function that will be called when the state of a pin changes diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp index 59d64f4..de9233f 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaCommon.hpp @@ -1,3 +1,3 @@ #pragma once -#define SDK_VESRION "2.8.0" \ No newline at end of file +#define SDK_VESRION "2.10.0" \ No newline at end of file diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaIoT.cpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaIoT.cpp index 51ffd56..d0837f8 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaIoT.cpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaIoT.cpp @@ -144,6 +144,12 @@ void ESPMegaIoT::registerCard(uint8_t card_id) { return; } + // Check if the physical card is installed + if (cards[card_id] == NULL) + { + ESP_LOGE("ESPMegaIoT", "Registering card %d failed: Card not installed", card_id); + return; + } // Get the card type uint8_t card_type = cards[card_id]->getType(); // Create the respective IoT component @@ -625,6 +631,22 @@ void ESPMegaIoT::loadNetworkConfig() network_config.wifiUseAuth = fram->read8(IOT_FRAM_ADDRESS + 54); fram->read(IOT_FRAM_ADDRESS + 55, (uint8_t *)network_config.ssid, 32); fram->read(IOT_FRAM_ADDRESS + 87, (uint8_t *)network_config.password, 32); + + // If ip,gateway,subnet,dns1,dns2 is 0, the device is not configured + // set to default values + // ip: 192.168.0.99 + // gateway: 192.168.0.1 + // subnet: 255.255.255.0 + // dns1: 1.1.1.1 + // dns2: 9.9.9.9 + if ((uint32_t)network_config.ip == 0 && (uint32_t)network_config.gateway == 0 && (uint32_t)network_config.subnet == 0 && (uint32_t)network_config.dns1 == 0 && (uint32_t)network_config.dns2 == 0) + { + network_config.ip = IPAddress(192, 168, 0, 99); + network_config.gateway = IPAddress(192, 168, 0, 1); + network_config.subnet = IPAddress(255, 255, 255, 0); + network_config.dns1 = IPAddress(1, 1, 1, 1); + network_config.useStaticIp = true; + } } /** diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.cpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.cpp index 5db70e5..44b7f07 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.cpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.cpp @@ -1,4 +1,5 @@ #include +#include "esp_sntp.h" // Reserve FRAM address 0 - 1000 for ESPMegaPRO Internal Use // (34 Bytes) Address 0-33 for Built-in Digital Output Card @@ -11,6 +12,7 @@ */ ESPMegaPRO::ESPMegaPRO() { + } /** @@ -102,6 +104,13 @@ void ESPMegaPRO::loop() if (iotEnabled) { iot->loop(); + static int64_t lastNTPUpdate = (esp_timer_get_time() / 1000) - NTP_UPDATE_INTERVAL_MS + NTP_INITIAL_SYNC_DELAY_MS; + if ((esp_timer_get_time() / 1000) - lastNTPUpdate > NTP_UPDATE_INTERVAL_MS) + { + ESP_LOGV("ESPMegaPRO", "Updating time from NTP"); + lastNTPUpdate = esp_timer_get_time() / 1000; + this->updateTimeFromNTP(); + } } if (internalDisplayEnabled) { @@ -153,19 +162,35 @@ bool ESPMegaPRO::installCard(uint8_t slot, ExpansionCard *card) bool ESPMegaPRO::updateTimeFromNTP() { struct tm timeinfo; - if (getLocalTime(&timeinfo)) + uint32_t start = esp_timer_get_time() / 1000; + time_t now; + time(&now); + localtime_r(&now, &timeinfo); + if (!(timeinfo.tm_year > (2016 - 1900))) { - rtctime_t rtctime = this->getTime(); - if (rtctime.hours != timeinfo.tm_hour || rtctime.minutes != timeinfo.tm_min || - rtctime.seconds != timeinfo.tm_sec || rtctime.day != timeinfo.tm_mday || - rtctime.month != timeinfo.tm_mon + 1 || rtctime.year != timeinfo.tm_year + 1900) - { - this->setTime(timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec, - timeinfo.tm_mday, timeinfo.tm_mon + 1, timeinfo.tm_year + 1900); - } - return true; + ESP_LOGI("ESPMegaPRO", "NTP is not ready yet!"); + return false; } - return false; + rtctime_t rtctime = this->getTime(); + if (rtctime.hours != timeinfo.tm_hour || rtctime.minutes != timeinfo.tm_min || + rtctime.seconds != timeinfo.tm_sec || rtctime.day != timeinfo.tm_mday || + rtctime.month != timeinfo.tm_mon + 1 || rtctime.year != timeinfo.tm_year + 1900) + { + this->setTime(timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec, + timeinfo.tm_mday, timeinfo.tm_mon + 1, timeinfo.tm_year + 1900); + } + ESP_LOGV("ESPMegaPRO", "Time updated from NTP: %s", asctime(&timeinfo)); + return true; +} + +/** + * @brief Sets the timezone for the internal RTC. + * + * @note This function takes POSIX timezone strings (e.g. "EST5EDT,M3.2.0,M11.1.0"). +*/ +void ESPMegaPRO::setTimezone(const char* offset) +{ + setenv("TZ", offset, 1); } /** @@ -222,6 +247,10 @@ void ESPMegaPRO::enableIotModule() this->iot->bindFRAM(&fram); this->iot->intr_begin(cards); iotEnabled = true; + sntp_setoperatingmode(SNTP_OPMODE_POLL); + sntp_setservername(0, this->iot->getMqttConfig()->mqtt_server); + sntp_setservername(1, "pool.ntp.org"); + sntp_init(); } /** diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.hpp index 4b6bd14..f78bc86 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.hpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaProOS.hpp @@ -24,6 +24,11 @@ #define PWM_BANK_ADDRESS 0x5F #define RTC_ADDRESS 0x68 +// Constants +#define NTP_TIMEOUT_MS 5000 +#define NTP_UPDATE_INTERVAL_MS 60000 +#define NTP_INITIAL_SYNC_DELAY_MS 15000 + /** * @brief The ESPMegaPRO class is the main class for the ESPMegaPRO library. * @@ -47,6 +52,7 @@ class ESPMegaPRO { void enableIotModule(); void enableInternalDisplay(HardwareSerial *serial); void enableWebServer(uint16_t port); + void setTimezone(const char* offset); rtctime_t getTime(); void dumpFRAMtoSerial(uint16_t start, uint16_t end); void dumpFRAMtoSerialASCII(uint16_t start, uint16_t end); diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaWebServer.cpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaWebServer.cpp index d4791b7..00f6b31 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaWebServer.cpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/ESPMegaWebServer.cpp @@ -482,6 +482,7 @@ void ESPMegaWebServer::getDeviceInfoHandler(AsyncWebServerRequest *request) { doc["software_version"] = SW_VERSION; doc["sdk_version"] = SDK_VESRION; doc["idf_version"] = IDF_VER; + doc["uptime"] = esp_timer_get_time() / 1000000; // Uptime in seconds char buffer[512]; serializeJson(doc, buffer); request->send(200, "application/json", buffer); diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/html/ota.html b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/html/ota.html index 51fc30a..a9fc9da 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/html/ota.html +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/html/ota.html @@ -14,6 +14,10 @@ MAC Address Loading ...

+

+ Uptime + Loading ... +

Model Loading ... @@ -60,7 +64,7 @@ SIWAT SYSTEM 2023