#include "protocol.h" #include "ws.h" #include #include #include #include "esp_wifi.h" #include "esp_netif.h" #define PROTOCOL_VERSION 1 static uint32_t msg_id = 1; static inline int append(char* buf, size_t size, int pos, const char* fmt, ...) { if ((size_t)pos >= size) return -1; va_list args; va_start(args, fmt); int written = vsnprintf(buf + pos, size - pos, fmt, args); va_end(args); if (written < 0 || (size_t)(pos + written) >= size) { return -1; } return pos + written; } int build_telemetry( char* buf, size_t buf_size, int64_t ts, uint32_t device_id, const char* metric, const char* source, const char* unit, const int* values, size_t count ) { int pos = 0; // --- header --- pos = append(buf, buf_size, pos, "{\"v\":1,\"t\":\"t\",\"id\":%lu,\"ts\":%lld,\"d\":%lu,\"p\":{", (unsigned long)protocol_next_id(), (long long)ts, (unsigned long)device_id ); if (pos < 0) return -1; // --- payload meta --- pos = append(buf, buf_size, pos, "\"m\":\"%s\",\"s\":\"%s\",\"u\":\"%s\",\"v\":[", metric, source, unit ); if (pos < 0) return -1; // --- values --- for (size_t i = 0; i < count ; i ++) { pos = append(buf, buf_size, pos, "[%u,%d]%s", values[i*2 + 0], // delta time values[i*2 + 1], (i < count - 1) ? "," : "" ); if (pos < 0) return -1; } // --- close --- pos = append(buf, buf_size, pos, "]}}"); if (pos < 0) return -1; return pos; } __attribute__((deprecated)) // --- TELEMETRY (single measurement) --- int build_telemetry_single( char* buf, size_t buf_size, const char* id, const char* device_id, int64_t ts_ms, const char* metric, double value, const char* unit, const char* source, int64_t m_ts_ms ) { int pos = 0; // header pos = append(buf, buf_size, pos, "{\"v\":%d,\"id\":\"%s\",\"type\":\"telemetry\",\"ts\":%lld," "\"deviceId\":\"%s\",\"payload\":{\"measurements\":[", PROTOCOL_VERSION, id, (long long)ts_ms, device_id ); if (pos < 0) return -1; // measurement start pos = append(buf, buf_size, pos, "{\"metric\":\"%s\",\"value\":%.3f", metric, value ); if (pos < 0) return -1; // optional if (unit) { pos = append(buf, buf_size, pos, ",\"unit\":\"%s\"", unit); if (pos < 0) return -1; } if (source) { pos = append(buf, buf_size, pos, ",\"source\":\"%s\"", source); if (pos < 0) return -1; } if (m_ts_ms > 0) { pos = append(buf, buf_size, pos, ",\"ts\":%lld", (long long)m_ts_ms); if (pos < 0) return -1; } // close measurement + payload pos = append(buf, buf_size, pos, "}]}}"); if (pos < 0) return -1; return pos; } __attribute__((deprecated)) // --- EVENT --- int build_event( char* buf, size_t buf_size, const char* id, const char* device_id, int64_t ts_ms, const char* name, const char* severity, const char* message ) { int pos = 0; // header pos = append(buf, buf_size, pos, "{\"v\":%d,\"id\":\"%s\",\"type\":\"event\",\"ts\":%lld," "\"deviceId\":\"%s\",\"payload\":{", PROTOCOL_VERSION, id, (long long)ts_ms, device_id ); if (pos < 0) return -1; // required pos = append(buf, buf_size, pos, "\"name\":\"%s\"", name); if (pos < 0) return -1; // optional if (severity) { pos = append(buf, buf_size, pos, ",\"severity\":\"%s\"", severity); if (pos < 0) return -1; } if (message) { pos = append(buf, buf_size, pos, ",\"message\":\"%s\"", message); if (pos < 0) return -1; } // close pos = append(buf, buf_size, pos, "}}"); if (pos < 0) return -1; return pos; } uint32_t protocol_next_id() { return msg_id++; }; void protocol_send_event_hb(int64_t ts) { char buf[256]; wifi_ap_record_t ap; esp_wifi_sta_get_ap_info(&ap); int rssi = ap.rssi; const char *ssid = (const char *)ap.ssid; esp_netif_ip_info_t ip_info; esp_netif_t *netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); esp_netif_get_ip_info(netif, &ip_info); uint32_t ip = ip_info.ip.addr; size_t heap_free = heap_caps_get_free_size(MALLOC_CAP_DEFAULT); size_t heap_largest = heap_caps_get_largest_free_block(MALLOC_CAP_DEFAULT); uint32_t id = protocol_next_id(); snprintf(buf, sizeof(buf), "{\"v\":1,\"id\":%" PRIu32 ",\"t\":\"e\",\"ts\":%" PRIu64 ",\"d\":%u," "\"p\":{" "\"t\":\"hb\"," "\"v\":%u," "\"hp\":%u," "\"hl\":%u," "\"rs\":%d," "\"ip\":%" PRIu32 "," "\"si\":\"%s\"" "}}", id, ts, CONFIG_DEVICE_ID, FW_VERSION, heap_free, heap_largest, rssi, ip, ssid ); ws_send(buf); } bool protocol_is_connected() { return ws_is_connected(); }