Files
yggdrasil/thermo_sensor/main/ygg_http_req.c
T

213 lines
5.9 KiB
C
Raw Normal View History

2026-09-13 18:14:19 +02:00
#include <stdio.h>
#include <string.h>
#include "cJSON.h"
#include "esp_log.h"
#include "esp_http_client.h"
#include "ygg_http_req.h"
#define GET_RESP_MAX_SIZE 4096
2026-09-15 13:38:55 +02:00
#define POST_RESP_MAX_SIZE 4096
2026-09-13 18:14:19 +02:00
static const char *TAG = "YGG_HTTP_REQ";
static char GET_RESP[GET_RESP_MAX_SIZE];
2026-09-15 13:38:55 +02:00
static char POST_RESP[POST_RESP_MAX_SIZE];
2026-09-13 18:14:19 +02:00
esp_err_t _http_event_handler(esp_http_client_event_t *evt) {
return ESP_OK;
}
char* ygg_send_get(const char *url) {
size_t total = 0;
esp_http_client_config_t config = {
.url = url,
2026-09-25 16:46:30 +02:00
.timeout_ms = 3000,
2026-09-13 18:14:19 +02:00
};
esp_http_client_handle_t client = esp_http_client_init(&config);
esp_err_t err = esp_http_client_open(client, 0);
if (err != ESP_OK) {
ESP_LOGE(TAG, "HTTP open error: %s", esp_err_to_name(err));
esp_http_client_cleanup(client);
return NULL;
}
esp_http_client_fetch_headers(client);
while (total < GET_RESP_MAX_SIZE - 1) {
int len = esp_http_client_read(
client,
GET_RESP + total,
GET_RESP_MAX_SIZE - 1 - total
);
if (len <= 0) {
break;
}
total += len;
}
GET_RESP[total] = '\0';
ESP_LOGI(TAG, "Status HTTP = %d",
esp_http_client_get_status_code(client));
ESP_LOGI(TAG, "Response: %s", GET_RESP);
esp_http_client_close(client);
esp_http_client_cleanup(client);
return GET_RESP;
}
2026-09-15 13:38:55 +02:00
char* ygg_send_post(const char *url, char *post_data) {
memset(POST_RESP, 0, POST_RESP_MAX_SIZE);
2026-09-13 18:14:19 +02:00
esp_http_client_config_t config = {
.url = url,
2026-09-25 16:46:30 +02:00
.timeout_ms = 3000,
2026-09-13 18:14:19 +02:00
};
2026-09-15 13:38:55 +02:00
2026-09-13 18:14:19 +02:00
esp_http_client_handle_t client = esp_http_client_init(&config);
2026-09-15 13:38:55 +02:00
if (client == NULL) {
ESP_LOGE(TAG, "Failed to initialize HTTP client");
return NULL;
}
int post_len = strlen(post_data);
2026-09-13 18:14:19 +02:00
esp_http_client_set_method(client, HTTP_METHOD_POST);
esp_http_client_set_header(client, "Content-Type", "application/json");
2026-09-15 13:38:55 +02:00
esp_err_t err = esp_http_client_open(client, post_len);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err));
esp_http_client_cleanup(client);
return NULL;
}
2026-09-13 18:14:19 +02:00
2026-09-15 13:38:55 +02:00
int wlen = esp_http_client_write(client, post_data, post_len);
if (wlen < 0) {
ESP_LOGE(TAG, "Failed to write post data");
esp_http_client_cleanup(client);
return NULL;
2026-09-13 18:14:19 +02:00
}
2026-09-15 13:38:55 +02:00
esp_http_client_fetch_headers(client);
int rlen = esp_http_client_read(client, POST_RESP, POST_RESP_MAX_SIZE - 1);
2026-09-13 18:14:19 +02:00
esp_http_client_cleanup(client);
2026-09-15 13:38:55 +02:00
if (rlen < 0) {
ESP_LOGE(TAG, "Error reading HTTP response");
return NULL;
}
POST_RESP[rlen] = '\0';
return POST_RESP;
2026-09-13 18:14:19 +02:00
}
int ygg_get_sensor_id(const char *sensor_name,
const char *url);
2026-09-20 21:07:10 +02:00
void ygg_send_sensor_readouts(const char *base_url,
const char *sensor_name,
2026-09-15 20:51:07 +02:00
ygg_sensor_readout readout) {
2026-09-13 18:14:19 +02:00
char post_data[64];
2026-09-20 21:07:10 +02:00
int sensor_id = ygg_get_sensor_id(sensor_name, base_url);
2026-09-15 13:38:55 +02:00
char url[128];
snprintf(url, sizeof(url),
2026-09-20 21:07:10 +02:00
"%s/api/sensors/%d/readouts", base_url, sensor_id);
2026-09-13 18:14:19 +02:00
snprintf(post_data, sizeof(post_data),
2026-09-15 20:51:07 +02:00
"{\"type\":\"temperature\", \"value\":%.2f}", readout.temperature);
2026-09-13 18:14:19 +02:00
ygg_send_post(url, post_data);
snprintf(post_data, sizeof(post_data),
2026-09-15 20:51:07 +02:00
"{\"type\":\"pressure\", \"value\":%.2f}", readout.pressure);
2026-09-13 18:14:19 +02:00
ygg_send_post(url, post_data);
snprintf(post_data, sizeof(post_data),
2026-09-15 20:51:07 +02:00
"{\"type\":\"humidity\", \"value\":%.2f}", readout.humidity);
2026-09-13 18:14:19 +02:00
ygg_send_post(url, post_data);
}
char* ygg_get_sensors(const char *base_url) {
char url[128];
snprintf(url, sizeof(url),
"%s/api/sensors", base_url);
char *sensors = ygg_send_get(url);
return sensors;
}
2026-09-15 13:38:55 +02:00
int ygg_json_find_sensor_id(char *json_sensors, const char *sensor_name) {
if (json_sensors == NULL || sensor_name == NULL) {
return -1;
}
cJSON *root = cJSON_Parse(json_sensors);
if (root == NULL) {
return -1;
}
int result_id = -1;
2026-09-13 18:14:19 +02:00
2026-09-15 13:38:55 +02:00
// CASE 1: JSON is single object { "id": 3, "name": "..." }
if (cJSON_IsObject(root)) {
cJSON *id = cJSON_GetObjectItem(root, "id");
cJSON *item_name = cJSON_GetObjectItem(root, "name");
2026-09-13 18:14:19 +02:00
if (cJSON_IsNumber(id) &&
cJSON_IsString(item_name) &&
strcmp(item_name->valuestring, sensor_name) == 0) {
2026-09-15 13:38:55 +02:00
result_id = id->valueint;
2026-09-13 18:14:19 +02:00
}
}
2026-09-15 13:38:55 +02:00
// CASE 2: JSON is array [ { "id": 3, "name": "..." }, ... ]
else if (cJSON_IsArray(root)) {
cJSON *item = NULL;
cJSON_ArrayForEach(item, root) {
cJSON *id = cJSON_GetObjectItem(item, "id");
cJSON *item_name = cJSON_GetObjectItem(item, "name");
if (cJSON_IsNumber(id) &&
cJSON_IsString(item_name) &&
strcmp(item_name->valuestring, sensor_name) == 0) {
result_id = id->valueint;
break;
}
}
}
2026-09-13 18:14:19 +02:00
cJSON_Delete(root);
2026-09-15 13:38:55 +02:00
return result_id;
}
int ygg_add_sensor(const char *base_url, const char *sensor_name) {
char url[128];
char post_data[128];
snprintf(url, sizeof(url),
"%s/api/sensors", base_url);
snprintf(post_data, sizeof(post_data),
"{\"name\":\"%s\"}", sensor_name);
char *resp = ygg_send_post(url, post_data);
ESP_LOGI(TAG, "POST new sensor, resp: %s", resp);
int id = ygg_json_find_sensor_id(resp, sensor_name);
return id;
2026-09-13 18:14:19 +02:00
}
int ygg_get_sensor_id(const char *sensor_name,
2026-09-15 13:38:55 +02:00
const char *base_url) {
char *sensors = ygg_get_sensors(base_url);
int id = ygg_json_find_sensor_id(sensors, sensor_name);
if (id == -1) {
id = ygg_add_sensor(base_url, sensor_name);
ESP_LOGI(TAG, "Added sensor ID to DB: %d", id);
}
else
ESP_LOGI(TAG, "Found sensor ID in DB: %d", id);
return id;
2026-09-13 18:14:19 +02:00
}