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