diff options
| author | Josh Rahm <joshuarahm@gmail.com> | 2025-12-07 16:02:20 -0700 |
|---|---|---|
| committer | Josh Rahm <joshuarahm@gmail.com> | 2025-12-07 16:02:20 -0700 |
| commit | 44c7f7a675d2cdb0281322f38be3227ef4fb1df2 (patch) | |
| tree | 4da919b59129c1447fa9aec45e6cd51bf70dc071 | |
| parent | c9efee6f3ffcf19e139d72d946aa4d837bbcbb9e (diff) | |
| download | esp32-ws2812b-44c7f7a675d2cdb0281322f38be3227ef4fb1df2.tar.gz esp32-ws2812b-44c7f7a675d2cdb0281322f38be3227ef4fb1df2.tar.bz2 esp32-ws2812b-44c7f7a675d2cdb0281322f38be3227ef4fb1df2.zip | |
Add a "reset defaults" button and handler.
| -rw-r--r-- | controller_webpage/index.html | 13 | ||||
| -rw-r--r-- | main/http_server.c | 33 | ||||
| -rw-r--r-- | main/main.c | 18 | ||||
| -rw-r--r-- | main/pattern/twinkle.c | 16 | ||||
| -rw-r--r-- | main/tcp_server.c | 9 |
5 files changed, 74 insertions, 15 deletions
diff --git a/controller_webpage/index.html b/controller_webpage/index.html index bfa6461..1a308eb 100644 --- a/controller_webpage/index.html +++ b/controller_webpage/index.html @@ -166,6 +166,7 @@ <header> <h1>Tree Lights Controller</h1> <div class="toolbar"> + <button class="secondary" onclick="resetDefaults()">Reset defaults</button> <button class="secondary" onclick="refreshValues()">Reload</button> </div> </header> @@ -341,6 +342,18 @@ } } + async function resetDefaults() { + setStatus("Resetting…"); + try { + await fetch(`${BASE_URL}/reset`, { method: "POST" }); + await refreshValues(); + setStatus("Reset to defaults"); + } catch (err) { + setStatus("Reset failed"); + console.error(err); + } + } + refreshValues(); </script> </body> diff --git a/main/http_server.c b/main/http_server.c index 745bfa6..16a7256 100644 --- a/main/http_server.c +++ b/main/http_server.c @@ -15,14 +15,16 @@ ESP_LOGI(TAG, "Handling [%s] (%s)", #attr, req->uri); \ ws_params_t* params = (ws_params_t*)req->user_ctx; \ httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); \ + ws_state_t snapshot; \ if (xSemaphoreTake(params->state_lock, portMAX_DELAY) != pdTRUE) { \ httpd_resp_send_err( \ req, HTTPD_500_INTERNAL_SERVER_ERROR, "lock failed"); \ return ESP_FAIL; \ } \ http_handle(typ)(req, ¶ms->state.attr); \ - ws_state_save(¶ms->state); \ + snapshot = params->state; \ xSemaphoreGive(params->state_lock); \ + ws_state_save(&snapshot); \ httpd_resp_send(req, NULL, 0); \ return ESP_OK; \ } \ @@ -92,17 +94,44 @@ static httpd_uri_t http_params_get_handler = { .handler = handle_get_params, .user_ctx = NULL}; +static esp_err_t handle_reset(httpd_req_t* req) +{ + httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); + + ws_params_t* params = (ws_params_t*)req->user_ctx; + ws_state_t snapshot; + reset_parameters(params); + if (xSemaphoreTake(params->state_lock, portMAX_DELAY) != pdTRUE) { + httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "lock failed"); + return ESP_FAIL; + } + snapshot = params->state; + xSemaphoreGive(params->state_lock); + + ws_state_save(&snapshot); + httpd_resp_send(req, NULL, 0); + return ESP_OK; +} + +static httpd_uri_t http_reset_handler = { + .uri = "/reset", + .method = HTTP_POST, + .handler = handle_reset, + .user_ctx = NULL}; + httpd_handle_t start_webserver(ws_params_t* params) { httpd_handle_t server = NULL; httpd_config_t config = HTTPD_DEFAULT_CONFIG(); config.lru_purge_enable = true; - config.max_uri_handlers = NUMBER_PARAMS + 1; + config.max_uri_handlers = NUMBER_PARAMS + 2; ESP_LOGI(TAG, "Starting httpd server on port: '%d'", config.server_port); if (httpd_start(&server, &config) == ESP_OK) { http_params_get_handler.user_ctx = params; + http_reset_handler.user_ctx = params; httpd_register_uri_handler(server, &http_params_get_handler); + httpd_register_uri_handler(server, &http_reset_handler); #define STATE_PARAM(typ, attr, ...) \ ESP_LOGI(TAG, "Registering URI handler [%s]", #attr); \ diff --git a/main/main.c b/main/main.c index 3248b93..5f8055d 100644 --- a/main/main.c +++ b/main/main.c @@ -94,15 +94,15 @@ void app_main(void) wifi_init_station("Wort", "JoshIsBau5"); ESP_LOGI("main", "Complete!"); - // if (xSemaphoreTake(ws_params.state_lock, portMAX_DELAY) == pdTRUE) { - // esp_err_t load_err = ws_state_load(&ws_params.state); - // if (load_err == ESP_OK) { - // ESP_LOGI("main", "Restored state from NVS"); - // } else { - // ESP_LOGI("main", "No saved state (%d); using defaults", load_err); - // } - // xSemaphoreGive(ws_params.state_lock); - // } + if (xSemaphoreTake(ws_params.state_lock, portMAX_DELAY) == pdTRUE) { + esp_err_t load_err = ws_state_load(&ws_params.state); + if (load_err == ESP_OK) { + ESP_LOGI("main", "Restored state from NVS"); + } else { + ESP_LOGI("main", "No saved state (%d); using defaults", load_err); + } + xSemaphoreGive(ws_params.state_lock); + } /* Pin the LED writer to core 1 to avoid preemption by Wi-Fi/IDF tasks. */ xTaskCreatePinnedToCore( diff --git a/main/pattern/twinkle.c b/main/pattern/twinkle.c index d23b111..450cda6 100644 --- a/main/pattern/twinkle.c +++ b/main/pattern/twinkle.c @@ -1,8 +1,8 @@ +#include "pattern/twinkle.h" + #include <stdint.h> #include <stdlib.h> -#include "pattern/twinkle.h" - // The shape of a "spike" uint8_t w_arr[91] = {1, 2, 4, 7, 11, 17, 24, 33, 44, 56, 70, 85, 101, 117, 134, 151, 167, 183, 197, 210, 222, 232, 240, 247, @@ -36,7 +36,7 @@ static uint8_t pseudo_random(uint8_t x) } /* Produces a randomize "twinkle" effect. */ -uint8_t twinkle(uint32_t time, size_t x, uint8_t amt) +static uint8_t twinkle_raw(uint32_t time, size_t x, uint8_t amt) { uint8_t time_offset = pseudo_random(x); @@ -51,3 +51,13 @@ uint8_t twinkle(uint32_t time, size_t x, uint8_t amt) return 0; } } + +uint8_t twinkle(uint32_t time, size_t x, uint8_t amt) +{ + if (time % 2 == 0) { + return twinkle_raw(time / 2, x, amt); + } else { + return (twinkle_raw(time / 2, x, amt) + twinkle_raw(time / 2 + 1, x, amt)) / + 2; + } +} diff --git a/main/tcp_server.c b/main/tcp_server.c index 5899a36..81b97b6 100644 --- a/main/tcp_server.c +++ b/main/tcp_server.c @@ -25,6 +25,8 @@ static int strcmp_(const char* s1, const char* s2) static void handle_set_cmd( sockbuf_t* sockbuf, ws_params_t* ws_params, const char* key) { + ws_state_t snapshot; + bool should_save = false; if (xSemaphoreTake(ws_params->state_lock, portMAX_DELAY) != pdTRUE) { sockbuf_write(sockbuf, "Failed to lock state\n"); return; @@ -47,10 +49,15 @@ static void handle_set_cmd( sockbuf_write(sockbuf, key); sockbuf_write(sockbuf, "'\n"); } else { - ws_state_save(&ws_params->state); + snapshot = ws_params->state; + should_save = true; } xSemaphoreGive(ws_params->state_lock); + + if (should_save) { + ws_state_save(&snapshot); + } } static void handle_print_cmd(sockbuf_t* sockbuf, ws_params_t* ws_params) |