diff options
| author | Josh Rahm <joshuarahm@gmail.com> | 2025-12-07 13:04:02 -0700 |
|---|---|---|
| committer | Josh Rahm <joshuarahm@gmail.com> | 2025-12-07 13:04:02 -0700 |
| commit | 42f4c42676d42619d530db27e7a2a0b76fbf9253 (patch) | |
| tree | 01ebd66f55aeb9a7c2113ebde3508a2cb1f01f5a /main/param | |
| parent | 3f8b6e6f34275bdba501e3b1cddab43331b6f569 (diff) | |
| download | esp32-ws2812b-42f4c42676d42619d530db27e7a2a0b76fbf9253.tar.gz esp32-ws2812b-42f4c42676d42619d530db27e7a2a0b76fbf9253.tar.bz2 esp32-ws2812b-42f4c42676d42619d530db27e7a2a0b76fbf9253.zip | |
Clean up how parameters work.
Formalize a poor-man's Parameter "typeclass" and create "instances".
This makes things way less ad-hoc.
Diffstat (limited to 'main/param')
| -rw-r--r-- | main/param/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | main/param/bool.c | 81 | ||||
| -rw-r--r-- | main/param/color_int.c | 96 | ||||
| -rw-r--r-- | main/param/int.c | 99 | ||||
| -rw-r--r-- | main/param/uint32_t.c | 43 | ||||
| -rw-r--r-- | main/param/uint8_t.c | 42 |
6 files changed, 363 insertions, 0 deletions
diff --git a/main/param/CMakeLists.txt b/main/param/CMakeLists.txt new file mode 100644 index 0000000..614a7e3 --- /dev/null +++ b/main/param/CMakeLists.txt @@ -0,0 +1,2 @@ +file(GLOB PARAM_SRCS "${CMAKE_CURRENT_LIST_DIR}/*.c") +set(PARAM_SRCS ${PARAM_SRCS} PARENT_SCOPE) diff --git a/main/param/bool.c b/main/param/bool.c new file mode 100644 index 0000000..46b6ebb --- /dev/null +++ b/main/param/bool.c @@ -0,0 +1,81 @@ +#include "param.h" +#include "http_server.h" + +void cmd_handle(bool)(const char* attr, sockbuf_t* sockbuf, bool* ptr) +{ + char buf_[32]; + char* op = read_token(sockbuf, buf_, sizeof(buf_)); + + bool curval = *ptr; + if (!strcmp(op, "on")) { + curval = 1; + } else if (!strcmp(op, "off")) { + curval = 0; + } else if (!strcmp(op, "toggle")) { + curval = !curval; + } else { + sockbuf_write(sockbuf, "Invalid value: '"); + sockbuf_write(sockbuf, op); + sockbuf_write(sockbuf, "'\n"); + return; + } + + *ptr = curval; + snprintf(buf_, sizeof(buf_), "%s = %s\n", attr, curval ? "on" : "off"); + sockbuf_write(sockbuf, buf_); +} + +size_t serialize_to_json(bool)( + char** out, size_t len, const char* attr, const char* dn, bool value) +{ + size_t newlen = snprintf( + *out, + len, + "\"%s\":{\"type\":\"bool\",\"value\":\"%s\",\"disp\":\"%s\"}", + attr, + value ? "on" : "off", + dn); + *out += newlen; + return len - newlen; +} + +#define TAG "serialize" +void http_handle(bool)(httpd_req_t* req, bool* val) +{ + char buf[128]; + int buf_len = httpd_req_get_url_query_len(req) + 1; + + if (buf_len > 1) { + if (buf_len > sizeof(buf)) { + ESP_LOGI(TAG, "Invalid request. Query string too long."); + httpd_resp_set_status(req, HTTPD_400); + return; + } + + if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) { + char param[32]; + if (httpd_query_key_value(buf, "set", param, sizeof(param)) == ESP_OK) { + if (!strcmp(param, "on")) { + *val = true; + } else if (!strcmp(param, "off")) { + *val = false; + } else if (!strcmp(param, "toggle")) { + *val = !*val; + } else { + ESP_LOGI(TAG, "Invalid request. Invalid param value."); + httpd_resp_set_status(req, HTTPD_400); + return; + } + } + } + } + + httpd_resp_set_status(req, HTTPD_204); +} + +void print(bool)(sockbuf_t* sockbuf, const char* attr, bool val) +{ + char buf[128]; + snprintf(buf, sizeof(buf), "%s: %s :: bool\n", attr, val ? "on" : "off"); + sockbuf_write(sockbuf, buf); +} diff --git a/main/param/color_int.c b/main/param/color_int.c new file mode 100644 index 0000000..0b8b002 --- /dev/null +++ b/main/param/color_int.c @@ -0,0 +1,96 @@ +#include "param.h" +#include "http_server.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> + +void cmd_handle(color_int_t)( + const char* attr, sockbuf_t* sockbuf, color_int_t* ptr) +{ + char buf_[32]; + char* value = read_token(sockbuf, buf_, sizeof(buf_)); + + if (!value) { + sockbuf_write(sockbuf, "Missing color value\n"); + return; + } + + char* p = value; + if (*p == '#') { + p++; + } else if (!strncasecmp(p, "0x", 2)) { + p += 2; + } + + char* end = NULL; + unsigned long parsed = strtoul(p, &end, 16); + if (end == p || *end != '\0' || parsed > 0xFFFFFFUL) { + sockbuf_write(sockbuf, "Invalid color; expected hex like RRGGBB\n"); + return; + } + + *ptr = (color_int_t)parsed; + snprintf(buf_, sizeof(buf_), "%s = 0x%06lx\n", attr, parsed); + sockbuf_write(sockbuf, buf_); +} + +size_t serialize_to_json(color_int_t)( + char** out, size_t len, const char* attr, const char* dn, color_int_t value) +{ + size_t newlen = snprintf( + *out, + len, + "\"%s\":{\"type\":\"color\",\"value\":\"#%06lx\",\"disp\":\"%s\"}", + attr, + (unsigned long)(value & 0xFFFFFF), + dn); + *out += newlen; + return len - newlen; +} + +#define TAG "param_color" +void http_handle(color_int_t)(httpd_req_t* req, color_int_t* val) +{ + char buf[128]; + int buf_len = httpd_req_get_url_query_len(req) + 1; + + if (buf_len > 1) { + if (buf_len > sizeof(buf)) { + ESP_LOGI(TAG, "Invalid request. Query string too long."); + httpd_resp_set_status(req, HTTPD_400); + return; + } + + if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) { + char param[32]; + if (httpd_query_key_value(buf, "set", param, sizeof(param)) == ESP_OK) { + char* p = param; + if (*p == '#') { + p++; + } else if (!strncasecmp(p, "0x", 2)) { + p += 2; + } + char* end = NULL; + unsigned long parsed = strtoul(p, &end, 16); + if (end == p || *end != '\0' || parsed > 0xFFFFFFUL) { + ESP_LOGI(TAG, "Invalid request. Invalid color value."); + httpd_resp_set_status(req, HTTPD_400); + return; + } + *val = (color_int_t)parsed; + } + } + } + + httpd_resp_set_status(req, HTTPD_204); +} + +void print(color_int_t)( + sockbuf_t* sockbuf, const char* attr, color_int_t val) +{ + char buf[128]; + snprintf(buf, sizeof(buf), "%s: 0x%06lx :: color\n", attr, (unsigned long)val); + sockbuf_write(sockbuf, buf); +} diff --git a/main/param/int.c b/main/param/int.c new file mode 100644 index 0000000..758180a --- /dev/null +++ b/main/param/int.c @@ -0,0 +1,99 @@ +#include "param.h" +#include "http_server.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +void cmd_handle(int)(const char* attr, sockbuf_t* sockbuf, int* ptr) +{ + char op_[8]; + char buf_[32]; + + char* op = read_token(sockbuf, op_, sizeof(op_)); + char* value = read_token(sockbuf, buf_, sizeof(buf_)); + + int curval = *ptr; + int ivalue = value ? atoi(value) : 0; + if (!strcmp(op, "+=")) { + curval += ivalue; + } else if (!strcmp(op, "-=")) { + curval -= ivalue; + } else if (!strcmp(op, "=")) { + curval = ivalue; + } else { + sockbuf_write(sockbuf, "Unknown operation: '"); + sockbuf_write(sockbuf, op); + sockbuf_write(sockbuf, "'\n"); + return; + } + + snprintf(buf_, sizeof(buf_), "%s = %d\n", attr, curval); + *ptr = curval; + sockbuf_write(sockbuf, buf_); +} + +size_t serialize_to_json(int)( + char** out, size_t len, const char* attr, const char* dn, int value) +{ + size_t newlen = snprintf( + *out, + len, + "\"%s\":{\"type\":\"int\",\"value\":\"%d\",\"disp\":\"%s\"}", + attr, + value, + dn); + *out += newlen; + return len - newlen; +} + +#define TAG "param_int" +void http_handle(int)(httpd_req_t* req, int* val) +{ + char buf[128]; + int buf_len = httpd_req_get_url_query_len(req) + 1; + esp_err_t err; + + if (buf_len > 1) { + if (buf_len > sizeof(buf)) { + ESP_LOGI(TAG, "Invalid request. Query string too long."); + httpd_resp_set_status(req, HTTPD_400); + return; + } + + if ((err = httpd_req_get_url_query_str(req, buf, buf_len)) == ESP_OK) { + char param[32]; + if (httpd_query_key_value(buf, "add", param, sizeof(param)) == ESP_OK) { + *val += atoi(param); + } else if ( + httpd_query_key_value(buf, "set", param, sizeof(param)) == ESP_OK) { + *val = atoi(param); + } else if ( + httpd_query_key_value(buf, "sub", param, sizeof(param)) == ESP_OK) { + *val -= atoi(param); + } else { + ESP_LOGI(TAG, "No valid parameters."); + httpd_resp_set_status(req, HTTPD_400); + return; + } + } else { + ESP_LOGI(TAG, "Unable to get URL query string. [%d]", err); + httpd_resp_set_status(req, HTTPD_500); + return; + } + } else { + ESP_LOGI(TAG, "No query string provided?"); + httpd_resp_set_status(req, HTTPD_400); + return; + } + + ESP_LOGI(TAG, "Now equals %d", *val); + httpd_resp_set_status(req, HTTPD_204); +} + +void print(int)(sockbuf_t* sockbuf, const char* attr, int val) +{ + char buf[128]; + snprintf(buf, sizeof(buf), "%s: %d :: int\n", attr, val); + sockbuf_write(sockbuf, buf); +} diff --git a/main/param/uint32_t.c b/main/param/uint32_t.c new file mode 100644 index 0000000..2c256c1 --- /dev/null +++ b/main/param/uint32_t.c @@ -0,0 +1,43 @@ +#include "param.h" +#include "http_server.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +void cmd_handle(uint32_t)( + const char* attr, sockbuf_t* sockbuf, uint32_t* ptr) +{ + int tmp = (int)(*ptr); + cmd_handle(int)(attr, sockbuf, &tmp); + *ptr = (uint32_t)tmp; +} + +size_t serialize_to_json(uint32_t)( + char** out, size_t len, const char* attr, const char* dn, uint32_t value) +{ + size_t newlen = snprintf( + *out, + len, + "\"%s\":{\"type\":\"uint32_t\",\"value\":\"%u\",\"disp\":\"%s\"}", + attr, + (unsigned int)value, + dn); + *out += newlen; + return len - newlen; +} + +#define TAG "param_u32" +void http_handle(uint32_t)(httpd_req_t* req, uint32_t* val) +{ + int tmp = (int)(*val); + http_handle(int)(req, &tmp); + *val = (uint32_t)tmp; +} + +void print(uint32_t)(sockbuf_t* sockbuf, const char* attr, uint32_t val) +{ + char buf[128]; + snprintf(buf, sizeof(buf), "%s: %lu :: uint32_t\n", attr, (unsigned long)val); + sockbuf_write(sockbuf, buf); +} diff --git a/main/param/uint8_t.c b/main/param/uint8_t.c new file mode 100644 index 0000000..6d8e01a --- /dev/null +++ b/main/param/uint8_t.c @@ -0,0 +1,42 @@ +#include "param.h" +#include "http_server.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +void cmd_handle(uint8_t)(const char* attr, sockbuf_t* sockbuf, uint8_t* ptr) +{ + int tmp = (int)(*ptr); + cmd_handle(int)(attr, sockbuf, &tmp); + *ptr = (uint8_t)tmp; +} + +size_t serialize_to_json(uint8_t)( + char** out, size_t len, const char* attr, const char* dn, uint8_t value) +{ + size_t newlen = snprintf( + *out, + len, + "\"%s\":{\"type\":\"uint8_t\",\"value\":\"%u\",\"disp\":\"%s\"}", + attr, + (unsigned int)value, + dn); + *out += newlen; + return len - newlen; +} + +#define TAG "param_u8" +void http_handle(uint8_t)(httpd_req_t* req, uint8_t* val) +{ + int tmp = (int)(*val); + http_handle(int)(req, &tmp); + *val = (uint8_t)tmp; +} + +void print(uint8_t)(sockbuf_t* sockbuf, const char* attr, uint8_t val) +{ + char buf[128]; + snprintf(buf, sizeof(buf), "%s: %u :: uint8_t\n", attr, (unsigned int)val); + sockbuf_write(sockbuf, buf); +} |