#include "device_status.hpp" #include #include #include extern WiFiManager wifiManager; // Version constants const char* FIRMWARE_VERSION = "1.0.0"; const char* HARDWARE_VERSION = "1.0"; DeviceStatus::DeviceStatus() { status = device_DeviceStatus_init_zero; } DeviceStatus::~DeviceStatus() { // Clean up if needed } void DeviceStatus::setInfo(const device_DeviceInfo& info) { status.has_info = true; status.info = info; } bool DeviceStatus::writeStreamCallback(pb_ostream_t *stream, const uint8_t *buf, size_t count) { StreamState* state = (StreamState*)stream->state; return state->stream->write(buf, count) == count; } const device_DeviceStatus& DeviceStatus::getStatus() { populate(); return status; } void DeviceStatus::populate() { // Populate device info from wifi manager status.has_info = true; wifiManager.getState(status.info); // Set device ID to MAC address String mac = WiFi.macAddress(); strncpy(status.info.device_id, mac.c_str(), sizeof(status.info.device_id) - 1); status.info.device_id[sizeof(status.info.device_id) - 1] = '\0'; // Set firmware version strncpy(status.info.firmware_version, FIRMWARE_VERSION, sizeof(status.info.firmware_version) - 1); status.info.firmware_version[sizeof(status.info.firmware_version) - 1] = '\0'; // Set hardware version strncpy(status.info.hardware_version, HARDWARE_VERSION, sizeof(status.info.hardware_version) - 1); status.info.hardware_version[sizeof(status.info.hardware_version) - 1] = '\0'; // Set uptime in seconds status.info.uptime_seconds = millis() / 1000; // Set up the logs callback to use the logger's logs status.logs.funcs.encode = [](pb_ostream_t *pb_stream, const pb_field_t *field, void * const *arg) -> bool { int count; const LogEntry* log_entries = logger.getLogs(count); for (int i = 0; i < count; ++i) { device_DeviceLogEntry log; log.timestamp = (int64_t)log_entries[i].timestamp * 1000; // Convert to milliseconds log.level = (device_DeviceLogLevel)log_entries[i].level; strncpy(log.message, log_entries[i].message, sizeof(log.message) - 1); log.message[sizeof(log.message) - 1] = '\0'; if (!pb_encode_tag_for_field(pb_stream, field) || !pb_encode_submessage(pb_stream, device_DeviceLogEntry_fields, &log)) { return false; } } return true; }; status.logs.arg = nullptr; // Not used } bool DeviceStatus::encode(Stream& stream) { populate(); // Create pb_ostream_t from Stream StreamState state = {&stream}; pb_ostream_t pb_stream = {&writeStreamCallback, &state, SIZE_MAX, 0}; // Encode the message return pb_encode(&pb_stream, device_DeviceStatus_fields, &status); }