168 lines
4.9 KiB
C
168 lines
4.9 KiB
C
#include <string.h>
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/semphr.h"
|
|
#include "esp_log.h"
|
|
|
|
#include "state_manager.h"
|
|
#include "audio_driver.h"
|
|
#include "wifi_connect.h"
|
|
#include "socket_client.h"
|
|
|
|
static const char *TAG = "state_manager";
|
|
|
|
// Centralized state container protected by a mutex
|
|
static device_state_t s_device_state;
|
|
static SemaphoreHandle_t s_state_mutex = NULL;
|
|
|
|
void state_manager_init(void)
|
|
{
|
|
s_state_mutex = xSemaphoreCreateMutex();
|
|
|
|
// Set initial boot default states
|
|
s_device_state.volume = 85;
|
|
s_device_state.led_state = LED_STATE_OFF;
|
|
s_device_state.led_brightness = 0.2f;
|
|
s_device_state.wifi_connected = false;
|
|
s_device_state.websocket_connected = false;
|
|
s_device_state.haptic_intensity = 0;
|
|
s_device_state.ambient_light = 0;
|
|
s_device_state.touch_active = 0;
|
|
|
|
ESP_LOGI(TAG, "State Manager initialized successfully.");
|
|
}
|
|
|
|
void state_get_current(device_state_t *out_state)
|
|
{
|
|
if (s_state_mutex == NULL) {
|
|
return;
|
|
}
|
|
if (xSemaphoreTake(s_state_mutex, portMAX_DELAY) == pdTRUE) {
|
|
memcpy(out_state, &s_device_state, sizeof(device_state_t));
|
|
xSemaphoreGive(s_state_mutex);
|
|
}
|
|
}
|
|
|
|
void state_set_volume(uint8_t volume)
|
|
{
|
|
if (volume > 100) volume = 100;
|
|
|
|
bool changed = false;
|
|
if (s_state_mutex != NULL && xSemaphoreTake(s_state_mutex, portMAX_DELAY) == pdTRUE) {
|
|
if (s_device_state.volume != volume) {
|
|
s_device_state.volume = volume;
|
|
changed = true;
|
|
}
|
|
xSemaphoreGive(s_state_mutex);
|
|
}
|
|
|
|
if (changed) {
|
|
ESP_LOGI(TAG, "Volume state changed to %d. Updating DAC codec driver...", volume);
|
|
Volume_Adjustment(volume);
|
|
trigger_telemetry_broadcast();
|
|
}
|
|
}
|
|
|
|
void state_set_led(led_state_t state)
|
|
{
|
|
bool changed = false;
|
|
if (s_state_mutex != NULL && xSemaphoreTake(s_state_mutex, portMAX_DELAY) == pdTRUE) {
|
|
if (s_device_state.led_state != state) {
|
|
s_device_state.led_state = state;
|
|
changed = true;
|
|
}
|
|
xSemaphoreGive(s_state_mutex);
|
|
}
|
|
|
|
if (changed) {
|
|
ESP_LOGI(TAG, "LED state changed to %d. Updating visual animation thread...", state);
|
|
set_led_state(state);
|
|
trigger_telemetry_broadcast();
|
|
}
|
|
}
|
|
|
|
void state_set_brightness(float brightness)
|
|
{
|
|
if (brightness < 0.0f) brightness = 0.0f;
|
|
if (brightness > 1.0f) brightness = 1.0f;
|
|
|
|
bool changed = false;
|
|
if (s_state_mutex != NULL && xSemaphoreTake(s_state_mutex, portMAX_DELAY) == pdTRUE) {
|
|
if (s_device_state.led_brightness != brightness) {
|
|
s_device_state.led_brightness = brightness;
|
|
changed = true;
|
|
}
|
|
xSemaphoreGive(s_state_mutex);
|
|
}
|
|
|
|
if (changed) {
|
|
ESP_LOGI(TAG, "LED brightness state changed to %f", brightness);
|
|
trigger_telemetry_broadcast();
|
|
}
|
|
}
|
|
|
|
void state_set_wifi_connected(bool connected)
|
|
{
|
|
bool changed = false;
|
|
if (s_state_mutex != NULL && xSemaphoreTake(s_state_mutex, portMAX_DELAY) == pdTRUE) {
|
|
if (s_device_state.wifi_connected != connected) {
|
|
s_device_state.wifi_connected = connected;
|
|
changed = true;
|
|
}
|
|
xSemaphoreGive(s_state_mutex);
|
|
}
|
|
|
|
if (changed) {
|
|
ESP_LOGI(TAG, "Wi-Fi connection state changed to: %s", connected ? "CONNECTED" : "DISCONNECTED");
|
|
trigger_telemetry_broadcast();
|
|
}
|
|
}
|
|
|
|
void state_set_websocket_connected(bool connected)
|
|
{
|
|
bool changed = false;
|
|
if (s_state_mutex != NULL && xSemaphoreTake(s_state_mutex, portMAX_DELAY) == pdTRUE) {
|
|
if (s_device_state.websocket_connected != connected) {
|
|
s_device_state.websocket_connected = connected;
|
|
changed = true;
|
|
}
|
|
xSemaphoreGive(s_state_mutex);
|
|
}
|
|
|
|
if (changed) {
|
|
ESP_LOGI(TAG, "WebSocket server state changed to: %s", connected ? "CONNECTED" : "DISCONNECTED");
|
|
trigger_telemetry_broadcast();
|
|
}
|
|
}
|
|
|
|
void state_set_haptic_intensity(uint8_t intensity)
|
|
{
|
|
if (intensity > 100) intensity = 100;
|
|
|
|
bool changed = false;
|
|
if (s_state_mutex != NULL && xSemaphoreTake(s_state_mutex, portMAX_DELAY) == pdTRUE) {
|
|
if (s_device_state.haptic_intensity != intensity) {
|
|
s_device_state.haptic_intensity = intensity;
|
|
changed = true;
|
|
}
|
|
xSemaphoreGive(s_state_mutex);
|
|
}
|
|
|
|
if (changed) {
|
|
ESP_LOGI(TAG, "Haptic intensity changed to %d", intensity);
|
|
#ifdef MODEL_PROTO_1
|
|
extern void proto1_haptics_set_intensity(uint8_t intensity);
|
|
proto1_haptics_set_intensity(intensity);
|
|
#endif
|
|
trigger_telemetry_broadcast();
|
|
}
|
|
}
|
|
|
|
void state_set_sensors(uint16_t ambient_light, uint8_t touch_active)
|
|
{
|
|
if (s_state_mutex != NULL && xSemaphoreTake(s_state_mutex, portMAX_DELAY) == pdTRUE) {
|
|
s_device_state.ambient_light = ambient_light;
|
|
s_device_state.touch_active = touch_active;
|
|
xSemaphoreGive(s_state_mutex);
|
|
}
|
|
}
|