#include "param.h" #include "http_server.h" #include #include #include #include static inline uint8_t clamp_u8(int v) { if (v < 0) return 0; if (v > 255) return 255; return (uint8_t)v; } static int parse_fraction(const char* s, fraction_t* out) { if (!s) return -1; char* end = NULL; float f = strtof(s, &end); if (end == s) { return -1; } *out = clamp_u8((int)lroundf(f * 255.0f)); return 0; } void cmd_handle(fraction_t)(const char* attr, sockbuf_t* sockbuf, fraction_t* ptr) { char op_[8]; char buf_[32]; char* op = read_token(sockbuf, op_, sizeof(op_)); char* value = read_token(sockbuf, buf_, sizeof(buf_)); fraction_t curval = *ptr; fraction_t parsed = 0; if (!strcmp(op, "+=") || !strcmp(op, "-=") || !strcmp(op, "=")) { if (parse_fraction(value, &parsed) != 0) { sockbuf_write(sockbuf, "Invalid value\n"); return; } if (!strcmp(op, "+=")) { curval = clamp_u8((int)curval + (int)parsed); } else if (!strcmp(op, "-=")) { curval = clamp_u8((int)curval - (int)parsed); } else { curval = parsed; } } else { sockbuf_write(sockbuf, "Unknown operation: '"); sockbuf_write(sockbuf, op); sockbuf_write(sockbuf, "'\n"); return; } *ptr = curval; snprintf(buf_, sizeof(buf_), "%s = %.3f\n", attr, curval / 255.0f); sockbuf_write(sockbuf, buf_); } size_t serialize_to_json(fraction_t)( char** out, size_t len, const char* attr, const char* dn, fraction_t value) { float fval = value / 255.0f; size_t newlen = snprintf( *out, len, "\"%s\":{\"type\":\"fraction\",\"value\":\"%.4f\",\"disp\":\"%s\"}", attr, fval, dn); *out += newlen; return len - newlen; } #define TAG "param_fraction" void http_handle(fraction_t)(httpd_req_t* req, fraction_t* 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]; fraction_t parsed; if (httpd_query_key_value(buf, "add", param, sizeof(param)) == ESP_OK) { if (parse_fraction(param, &parsed) != 0) { httpd_resp_set_status(req, HTTPD_400); return; } *val = clamp_u8((int)(*val) + (int)parsed); } else if ( httpd_query_key_value(buf, "set", param, sizeof(param)) == ESP_OK) { if (parse_fraction(param, &parsed) != 0) { httpd_resp_set_status(req, HTTPD_400); return; } *val = parsed; } else if ( httpd_query_key_value(buf, "sub", param, sizeof(param)) == ESP_OK) { if (parse_fraction(param, &parsed) != 0) { httpd_resp_set_status(req, HTTPD_400); return; } *val = clamp_u8((int)(*val) - (int)parsed); } 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; } httpd_resp_set_status(req, HTTPD_204); } void print(fraction_t)(sockbuf_t* sockbuf, const char* attr, fraction_t val) { char buf[128]; snprintf(buf, sizeof(buf), "%s: %.3f :: fraction\n", attr, val / 255.0f); sockbuf_write(sockbuf, buf); }