forked from xiaozhi/xiaozhi-esp32
feat: add state change events and callbacks (#798)
This commit is contained in:
@@ -23,6 +23,7 @@ set(SOURCES "audio_codecs/audio_codec.cc"
|
|||||||
"ota.cc"
|
"ota.cc"
|
||||||
"settings.cc"
|
"settings.cc"
|
||||||
"background_task.cc"
|
"background_task.cc"
|
||||||
|
"device_state_event.cc"
|
||||||
"main.cc"
|
"main.cc"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -990,6 +990,9 @@ void Application::SetDeviceState(DeviceState state) {
|
|||||||
// The state is changed, wait for all background tasks to finish
|
// The state is changed, wait for all background tasks to finish
|
||||||
background_task_->WaitForCompletion();
|
background_task_->WaitForCompletion();
|
||||||
|
|
||||||
|
// Send the state change event
|
||||||
|
DeviceStateEventManager::GetInstance().PostStateChangeEvent(previous_state, state);
|
||||||
|
|
||||||
auto& board = Board::GetInstance();
|
auto& board = Board::GetInstance();
|
||||||
auto display = board.GetDisplay();
|
auto display = board.GetDisplay();
|
||||||
auto led = board.GetLed();
|
auto led = board.GetLed();
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "audio_processor.h"
|
#include "audio_processor.h"
|
||||||
#include "wake_word.h"
|
#include "wake_word.h"
|
||||||
#include "audio_debugger.h"
|
#include "audio_debugger.h"
|
||||||
|
#include "device_state_event.h"
|
||||||
|
|
||||||
#define SCHEDULE_EVENT (1 << 0)
|
#define SCHEDULE_EVENT (1 << 0)
|
||||||
#define SEND_AUDIO_EVENT (1 << 1)
|
#define SEND_AUDIO_EVENT (1 << 1)
|
||||||
@@ -34,20 +35,6 @@ enum AecMode {
|
|||||||
kAecOnServerSide,
|
kAecOnServerSide,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DeviceState {
|
|
||||||
kDeviceStateUnknown,
|
|
||||||
kDeviceStateStarting,
|
|
||||||
kDeviceStateWifiConfiguring,
|
|
||||||
kDeviceStateIdle,
|
|
||||||
kDeviceStateConnecting,
|
|
||||||
kDeviceStateListening,
|
|
||||||
kDeviceStateSpeaking,
|
|
||||||
kDeviceStateUpgrading,
|
|
||||||
kDeviceStateActivating,
|
|
||||||
kDeviceStateAudioTesting,
|
|
||||||
kDeviceStateFatalError
|
|
||||||
};
|
|
||||||
|
|
||||||
#define OPUS_FRAME_DURATION_MS 60
|
#define OPUS_FRAME_DURATION_MS 60
|
||||||
#define MAX_AUDIO_PACKETS_IN_QUEUE (2400 / OPUS_FRAME_DURATION_MS)
|
#define MAX_AUDIO_PACKETS_IN_QUEUE (2400 / OPUS_FRAME_DURATION_MS)
|
||||||
#define AUDIO_TESTING_MAX_DURATION_MS 10000
|
#define AUDIO_TESTING_MAX_DURATION_MS 10000
|
||||||
|
|||||||
18
main/device_state.h
Normal file
18
main/device_state.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#ifndef _DEVICE_STATE_H_
|
||||||
|
#define _DEVICE_STATE_H_
|
||||||
|
|
||||||
|
enum DeviceState {
|
||||||
|
kDeviceStateUnknown,
|
||||||
|
kDeviceStateStarting,
|
||||||
|
kDeviceStateWifiConfiguring,
|
||||||
|
kDeviceStateIdle,
|
||||||
|
kDeviceStateConnecting,
|
||||||
|
kDeviceStateListening,
|
||||||
|
kDeviceStateSpeaking,
|
||||||
|
kDeviceStateUpgrading,
|
||||||
|
kDeviceStateActivating,
|
||||||
|
kDeviceStateAudioTesting,
|
||||||
|
kDeviceStateFatalError
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _DEVICE_STATE_H_
|
||||||
46
main/device_state_event.cc
Normal file
46
main/device_state_event.cc
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#include "device_state_event.h"
|
||||||
|
|
||||||
|
ESP_EVENT_DEFINE_BASE(XIAOZHI_STATE_EVENTS);
|
||||||
|
|
||||||
|
DeviceStateEventManager& DeviceStateEventManager::GetInstance() {
|
||||||
|
static DeviceStateEventManager instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceStateEventManager::RegisterStateChangeCallback(std::function<void(DeviceState, DeviceState)> callback) {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
callbacks_.push_back(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceStateEventManager::PostStateChangeEvent(DeviceState previous_state, DeviceState current_state) {
|
||||||
|
device_state_event_data_t event_data = {
|
||||||
|
.previous_state = previous_state,
|
||||||
|
.current_state = current_state
|
||||||
|
};
|
||||||
|
esp_event_post(XIAOZHI_STATE_EVENTS, XIAOZHI_STATE_CHANGED_EVENT, &event_data, sizeof(event_data), portMAX_DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::function<void(DeviceState, DeviceState)>> DeviceStateEventManager::GetCallbacks() {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
return callbacks_;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceStateEventManager::DeviceStateEventManager() {
|
||||||
|
esp_err_t err = esp_event_loop_create_default();
|
||||||
|
if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) {
|
||||||
|
ESP_ERROR_CHECK(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_register(XIAOZHI_STATE_EVENTS, XIAOZHI_STATE_CHANGED_EVENT,
|
||||||
|
[](void* handler_args, esp_event_base_t base, int32_t id, void* event_data) {
|
||||||
|
auto* data = static_cast<device_state_event_data_t*>(event_data);
|
||||||
|
auto& manager = DeviceStateEventManager::GetInstance();
|
||||||
|
for (const auto& callback : manager.GetCallbacks()) {
|
||||||
|
callback(data->previous_state, data->current_state);
|
||||||
|
}
|
||||||
|
}, nullptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceStateEventManager::~DeviceStateEventManager() {
|
||||||
|
esp_event_handler_unregister(XIAOZHI_STATE_EVENTS, XIAOZHI_STATE_CHANGED_EVENT, nullptr);
|
||||||
|
}
|
||||||
39
main/device_state_event.h
Normal file
39
main/device_state_event.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#ifndef _DEVICE_STATE_EVENT_H_
|
||||||
|
#define _DEVICE_STATE_EVENT_H_
|
||||||
|
|
||||||
|
#include <esp_event.h>
|
||||||
|
#include <functional>
|
||||||
|
#include <vector>
|
||||||
|
#include <mutex>
|
||||||
|
#include "device_state.h"
|
||||||
|
|
||||||
|
ESP_EVENT_DECLARE_BASE(XIAOZHI_STATE_EVENTS);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
XIAOZHI_STATE_CHANGED_EVENT,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct device_state_event_data_t {
|
||||||
|
DeviceState previous_state;
|
||||||
|
DeviceState current_state;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DeviceStateEventManager {
|
||||||
|
public:
|
||||||
|
static DeviceStateEventManager& GetInstance();
|
||||||
|
DeviceStateEventManager(const DeviceStateEventManager&) = delete;
|
||||||
|
DeviceStateEventManager& operator=(const DeviceStateEventManager&) = delete;
|
||||||
|
|
||||||
|
void RegisterStateChangeCallback(std::function<void(DeviceState, DeviceState)> callback);
|
||||||
|
void PostStateChangeEvent(DeviceState previous_state, DeviceState current_state);
|
||||||
|
std::vector<std::function<void(DeviceState, DeviceState)>> GetCallbacks();
|
||||||
|
|
||||||
|
private:
|
||||||
|
DeviceStateEventManager();
|
||||||
|
~DeviceStateEventManager();
|
||||||
|
|
||||||
|
std::vector<std::function<void(DeviceState, DeviceState)>> callbacks_;
|
||||||
|
std::mutex mutex_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _DEVICE_STATE_EVENT_H_
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "gpio_led.h"
|
#include "gpio_led.h"
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
|
#include "device_state.h"
|
||||||
#include <esp_log.h>
|
#include <esp_log.h>
|
||||||
|
|
||||||
#define TAG "GpioLed"
|
#define TAG "GpioLed"
|
||||||
|
|||||||
Reference in New Issue
Block a user