#include "cmd_led_ring.h" #include "esp_log.h" #include "led_ring.h" #include "uart_cmd.h" static const char *TAG = "[LED_RING_CMD]"; #define LED_RING_MODE_CLEAR 0 #define LED_RING_MODE_PROGRESS 1 #define LED_RING_MODE_DIGIT 2 #define LED_RING_MODE_BLINK 3 #define LED_RING_MODE_FIND_ME 4 static uint8_t clamp_u8(uint32_t v) { if (v > 255) { return 255; } return (uint8_t)v; } static uint8_t clamp_progress(uint32_t v) { if (v > 100) { return 100; } return (uint8_t)v; } static uint8_t resolve_intensity(uint32_t intensity) { if (intensity == 0) { return LED_RING_DEFAULT_INTENSITY; } return clamp_u8(intensity); } static void reply(bool success, uint32_t mode, uint32_t progress, uint32_t digit) { alox_UartMessage response; uart_cmd_init_response(&response, alox_MessageType_LED_RING, alox_UartMessage_led_ring_progress_response_tag); response.payload.led_ring_progress_response.success = success; response.payload.led_ring_progress_response.mode = mode; response.payload.led_ring_progress_response.progress = progress; response.payload.led_ring_progress_response.digit = digit; uart_cmd_send(&response, TAG); } static void handle_led_ring(const uint8_t *data, size_t len) { alox_UartMessage uart_msg; alox_LedRingProgressRequest req = alox_LedRingProgressRequest_init_zero; if (uart_cmd_decode(data, len, &uart_msg) != ESP_OK) { ESP_LOGW(TAG, "decode failed"); reply(false, 0, 0, 0); return; } const alox_LedRingProgressRequest *req_ptr = UART_CMD_REQ( &uart_msg, alox_UartMessage_led_ring_progress_request_tag, led_ring_progress_request); if (req_ptr != NULL) { req = *req_ptr; } uint32_t mode = req.mode; uint8_t r = clamp_u8(req.r); uint8_t g = clamp_u8(req.g); uint8_t b = clamp_u8(req.b); uint8_t intensity = resolve_intensity(req.intensity); led_command_t cmd = {0}; switch (mode) { case LED_RING_MODE_CLEAR: cmd.mode = LED_CMD_CLEAR; led_ring_send_command(&cmd); ESP_LOGI(TAG, "clear"); reply(true, mode, 0, 0); return; case LED_RING_MODE_PROGRESS: { uint8_t progress = clamp_progress(req.progress); cmd.mode = LED_CMD_PROGRESS; cmd.progress = progress; cmd.r = r; cmd.g = g; cmd.b = b; cmd.intensity = intensity; led_ring_send_command(&cmd); ESP_LOGI(TAG, "progress %u%% rgb=%u,%u,%u", (unsigned)progress, (unsigned)r, (unsigned)g, (unsigned)b); reply(true, mode, progress, 0); return; } case LED_RING_MODE_DIGIT: { if (req.digit > 10) { ESP_LOGW(TAG, "digit %lu out of range", (unsigned long)req.digit); reply(false, mode, 0, req.digit); return; } cmd.mode = LED_CMD_SET_DIGIT; cmd.value = (uint8_t)req.digit; cmd.r = r; cmd.g = g; cmd.b = b; cmd.intensity = intensity; led_ring_send_command(&cmd); ESP_LOGI(TAG, "digit %u rgb=%u,%u,%u", (unsigned)cmd.value, (unsigned)r, (unsigned)g, (unsigned)b); reply(true, mode, 0, req.digit); return; } case LED_RING_MODE_FIND_ME: led_ring_find_me(); ESP_LOGI(TAG, "find-me"); reply(true, mode, 0, 0); return; case LED_RING_MODE_BLINK: { cmd.mode = LED_CMD_BLINK; cmd.r = r; cmd.g = g; cmd.b = b; cmd.intensity = intensity; cmd.blink_ms = (uint16_t)(req.blink_ms > 0 ? req.blink_ms : 350); cmd.blink_count = req.blink_count > 0 ? (uint8_t)req.blink_count : 1; if (cmd.blink_count == 0) { cmd.blink_count = 1; } led_ring_send_command(&cmd); ESP_LOGI(TAG, "blink x%u %u ms rgb=%u,%u,%u", (unsigned)cmd.blink_count, (unsigned)cmd.blink_ms, (unsigned)r, (unsigned)g, (unsigned)b); reply(true, mode, 0, 0); return; } default: ESP_LOGW(TAG, "unknown mode %lu", (unsigned long)mode); reply(false, mode, 0, 0); return; } } void cmd_led_ring_register(void) { uart_cmd_register(alox_MessageType_LED_RING, handle_led_ring); }