diff --git a/ESPlant-Firmware/main/configuration_mode_server.c b/ESPlant-Firmware/main/configuration_mode_server.c index 036f62e..89a0acd 100644 --- a/ESPlant-Firmware/main/configuration_mode_server.c +++ b/ESPlant-Firmware/main/configuration_mode_server.c @@ -354,6 +354,35 @@ esp_err_t post_api_timeouts_configurationMode_handler(httpd_req_t *req) return ESP_OK; } +esp_err_t get_api_timeouts_wdt_handler(httpd_req_t *req) +{ + uint64_t timeout = DEFAULT_WATCHDOG_TIMEOUT_MS; + plantstore_getWatchdogTimeoutMs(&timeout); + + char resp[15]; + sprintf(resp, "%llu", timeout); + httpd_resp_send(req, resp, HTTPD_RESP_USE_STRLEN); + return ESP_OK; +} + +esp_err_t post_api_timeouts_wdt_handler(httpd_req_t *req) +{ + char timoutString[10]; + if (!get_single_value(req, timoutString) || !is_number(timoutString)) + { + return ESP_FAIL; + } + + uint64_t timeout; + sscanf(timoutString, "%llu", &timeout); + + plantstore_setWatchdogTimeoutMs(timeout); + + const char resp[] = "OK"; + httpd_resp_send(req, resp, HTTPD_RESP_USE_STRLEN); + return ESP_OK; +} + esp_err_t get_api_update_percentage_handler(httpd_req_t *req) { char resp[10]; @@ -615,6 +644,18 @@ httpd_uri_t post_api_timeouts_configurationMode = { .handler = post_api_timeouts_configurationMode_handler, .user_ctx = NULL}; +httpd_uri_t get_api_timeouts_wdt = { + .uri = "/api/timeouts/wdt", + .method = HTTP_GET, + .handler = get_api_timeouts_wdt_handler, + .user_ctx = NULL}; + +httpd_uri_t post_api_timeouts_wdt = { + .uri = "/api/timeouts/wdt", + .method = HTTP_POST, + .handler = post_api_timeouts_wdt_handler, + .user_ctx = NULL}; + httpd_uri_t post_api_update_firmware = { .uri = "/api/update/firmware", .method = HTTP_POST, @@ -661,6 +702,8 @@ httpd_handle_t start_webserver(void) httpd_register_uri_handler(server, &get_api_timeouts_sleep); httpd_register_uri_handler(server, &get_api_timeouts_configurationMode); httpd_register_uri_handler(server, &post_api_timeouts_configurationMode); + httpd_register_uri_handler(server, &get_api_timeouts_wdt); + httpd_register_uri_handler(server, &post_api_timeouts_wdt); httpd_register_uri_handler(server, &get_api_update_percentage); httpd_register_uri_handler(server, &get_api_connectedNetwork); httpd_register_uri_handler(server, &get_api_sensorData); diff --git a/ESPlant-Firmware/main/defaults.h b/ESPlant-Firmware/main/defaults.h index 8791029..ddd9ddd 100644 --- a/ESPlant-Firmware/main/defaults.h +++ b/ESPlant-Firmware/main/defaults.h @@ -2,7 +2,10 @@ #define DEFAULT_SENSOR_TIMEOUT_SLEEP_MS 1000 * 60 * 60 // 60 minutes #define DEFAULT_CONFIGURATION_MODE_TIMEOUT_MS 60000 +#define DEFAULT_WATCHDOG_TIMEOUT_MS 1000 * 20 // 20 seconds #define DEFAULT_SSID_MAX_LENGTH 33 #define DEFAULT_PASSWORD_MAX_LENGTH 65 -#define DEFAULT_API_URL "http://esplant.hoppingadventure.com/api/v2/data" \ No newline at end of file +#define DEFAULT_API_URL "http://esplant.hoppingadventure.com/api/v2/data" + +// #define BLUMY_DEBUG \ No newline at end of file diff --git a/ESPlant-Firmware/main/main.c b/ESPlant-Firmware/main/main.c index f70e6d1..f9a9c2a 100644 --- a/ESPlant-Firmware/main/main.c +++ b/ESPlant-Firmware/main/main.c @@ -25,6 +25,16 @@ void sendSensorData(sensors_full_data_t *sensors_data, int8_t rssi) char bearer[60]; sprintf(bearer, "Bearer %s", token); +#ifdef BLUMY_DEBUG + uint8_t debug_wdt_reached = 1; + plantstore_debugGetWdtReached(&debug_wdt_reached); + if (debug_wdt_reached) + { + rssi = 127; // debug value that is easy to spot + plantstore_debugSetWdtReached(0); + } +#endif + sprintf(data, "{\"light\":%2.2f,\"voltage\":%.2f,\"temperature\":%.2f,\"humidity\":%.2f,\"isUsbConnected\":%s,\"moisture\":%d,\"moistureStabilizationTime\":%lu,\"isMoistureMeasurementSuccessful\":%s,\"humidityRaw\":%lu,\"temperatureRaw\":%lu,\"rssi\":%d,\"duration\":%lld}", sensors_data->light, sensors_data->voltage, @@ -55,7 +65,6 @@ void sendSensorData(sensors_full_data_t *sensors_data, int8_t rssi) ESP_ERROR_CHECK(esp_http_client_set_header(client, "Authorization", bearer)); ESP_ERROR_CHECK(esp_http_client_perform(client)); - ESP_LOGI("Data", "%s", data); int status_code = esp_http_client_get_status_code(client); ESP_LOGI("HTTP", "Status Code: %d", status_code); @@ -106,9 +115,41 @@ void configuration_mode(bool isConfigured) start_deep_sleep(); } +void watchdog_callback(void *arg) +{ + ESP_LOGE("Watchdog", "Watchdog timeout reached, going to sleep"); +#ifdef BLUMY_DEBUG + uint8_t debug_wdt_reached = 1; + plantstore_debugGetWdtReached(&debug_wdt_reached); + if (!debug_wdt_reached) + { + plantstore_debugSetWdtReached(1); + } +#endif + start_deep_sleep(); +} + +esp_timer_handle_t init_watchdog() +{ + esp_timer_create_args_t watchdog_args = { + .callback = &watchdog_callback, + .name = "watchdog", + }; + esp_timer_handle_t watchdog_timer; + ESP_ERROR_CHECK(esp_timer_create(&watchdog_args, &watchdog_timer)); + uint64_t watchdog_timeout = DEFAULT_WATCHDOG_TIMEOUT_MS; + plantstore_getWatchdogTimeoutMs(&watchdog_timeout); + + ESP_LOGI("Watchdog", "Starting watchdog with timeout %llu ms", watchdog_timeout); + ESP_ERROR_CHECK(esp_timer_start_once(watchdog_timer, watchdog_timeout * 1000)); + + return watchdog_timer; +} + void sensor_mode() { ESP_LOGI("MODE", "Starting sensor mode"); + esp_timer_handle_t watchdog_timer = init_watchdog(); plantfi_initWifiStaOnly(); plantfi_configureStaFromPlantstore(); sensors_initSensors(); @@ -126,6 +167,7 @@ void sensor_mode() ESP_LOGE("WIFI", "Failed to connect to wifi"); } sensors_deinitSensors(); // optional + ESP_ERROR_CHECK(esp_timer_stop(watchdog_timer)); start_deep_sleep(); } diff --git a/ESPlant-Firmware/main/plantstore.c b/ESPlant-Firmware/main/plantstore.c index 4c7429f..80329a6 100644 --- a/ESPlant-Firmware/main/plantstore.c +++ b/ESPlant-Firmware/main/plantstore.c @@ -168,6 +168,23 @@ void plantstore_setConfigurationModeTimeoutMs(int32_t timeoutMs) nvs_close(nvs_handle); } +bool plantstore_getWatchdogTimeoutMs(uint64_t *timeoutMs) +{ + nvs_handle_t nvs_handle = plantstore_openNvsReadOnly(); + esp_err_t timeout_err = nvs_get_u64(nvs_handle, WATCHDOG_TIMEOUT_KEY, timeoutMs); + nvs_close(nvs_handle); + + return timeout_err == ESP_OK; +} + +void plantstore_setWatchdogTimeoutMs(uint64_t timeoutMs) +{ + nvs_handle_t nvs_handle = plantstore_openNvsReadWrite(); + ESP_ERROR_CHECK(nvs_set_u64(nvs_handle, WATCHDOG_TIMEOUT_KEY, timeoutMs)); + ESP_ERROR_CHECK(nvs_commit(nvs_handle)); + nvs_close(nvs_handle); +} + void plantstore_setFirmwareUpdateUrl(char *url) { nvs_handle_t nvs_handle = plantstore_openNvsReadWrite(); @@ -200,4 +217,24 @@ void plantstore_hardReset() ESP_ERROR_CHECK(nvs_erase_all(nvs_handle)); ESP_ERROR_CHECK(nvs_commit(nvs_handle)); nvs_close(nvs_handle); -} \ No newline at end of file +} + + +#ifdef BLUMY_DEBUG +bool plantstore_debugGetWdtReached(uint8_t *reached) +{ + nvs_handle_t nvs_handle = plantstore_openNvsReadOnly(); + esp_err_t reached_err = nvs_get_u8(nvs_handle, DEBUG_WDT_REACHED_KEY, reached); + nvs_close(nvs_handle); + + return reached_err == ESP_OK; +} + +void plantstore_debugSetWdtReached(uint8_t reached) +{ + nvs_handle_t nvs_handle = plantstore_openNvsReadWrite(); + ESP_ERROR_CHECK(nvs_set_u8(nvs_handle, DEBUG_WDT_REACHED_KEY, reached)); + ESP_ERROR_CHECK(nvs_commit(nvs_handle)); + nvs_close(nvs_handle); +} +#endif \ No newline at end of file diff --git a/ESPlant-Firmware/main/plantstore.h b/ESPlant-Firmware/main/plantstore.h index 0f70b32..aca8f7e 100644 --- a/ESPlant-Firmware/main/plantstore.h +++ b/ESPlant-Firmware/main/plantstore.h @@ -2,6 +2,7 @@ #include "nvs_flash.h" #include "esp_log.h" +#include "defaults.h" #define CREDENTIALS_SSID_KEY "cred_ssid" #define CREDENTIALS_PASSWORD_KEY "cred_password" @@ -18,8 +19,13 @@ #define BLUMY_TOKEN_KEY "blumy_token" #define SENSOR_TIMEOUT_SLEEP_KEY "timeout_sleep" #define SENSOR_TIMEOUT_CONFIG_KEY "timeout_config" +#define WATCHDOG_TIMEOUT_KEY "timeout_wdt" #define FIRMWARE_UPDATE_URL_KEY "update_url" +#ifdef BLUMY_DEBUG +#define DEBUG_WDT_REACHED_KEY "debug_wdt" +#endif + bool plantstore_getWifiCredentials(char *ssid, char *password, size_t ssid_size, size_t password_size); void plantstore_setWifiCredentials(char *ssid, char *password); bool plantstore_getCloudConfigurationHttp(char *sensorId, char *url, char *auth, size_t sensorId_size, size_t url_size, size_t auth_size); @@ -32,6 +38,8 @@ bool plantstore_getSensorTimeoutSleepMs(uint64_t *timeoutMs); void plantstore_setSensorTimeoutSleepMs(uint64_t timeoutMs); bool plantstore_getConfigurationModeTimeoutMs(int32_t *timeoutMs); void plantstore_setConfigurationModeTimeoutMs(int32_t timeoutMs); +bool plantstore_getWatchdogTimeoutMs(uint64_t *timeoutMs); +void plantstore_setWatchdogTimeoutMs(uint64_t timeoutMs); void plantstore_setFirmwareUpdateUrl(char *url); bool plantstore_getFirmwareUpdateUrl(char *url, size_t url_size); /** @@ -39,4 +47,9 @@ bool plantstore_getFirmwareUpdateUrl(char *url, size_t url_size); * The plantstore is marked as configured, if the wifi credentials are set and at least one of the cloud configurations is set. */ bool plantstore_isConfigured(); -void plantstore_hardReset(); \ No newline at end of file +void plantstore_hardReset(); + +#ifdef BLUMY_DEBUG +bool plantstore_debugGetWdtReached(uint8_t *reached); +void plantstore_debugSetWdtReached(uint8_t reached); +#endif \ No newline at end of file