Skip to content

Commit 5c87070

Browse files
authored
feat: add state change events and callbacks (78#798)
1 parent c68c959 commit 5c87070

File tree

7 files changed

+109
-14
lines changed

7 files changed

+109
-14
lines changed

main/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ set(SOURCES "audio_codecs/audio_codec.cc"
2323
"ota.cc"
2424
"settings.cc"
2525
"background_task.cc"
26+
"device_state_event.cc"
2627
"main.cc"
2728
)
2829

main/application.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -990,6 +990,9 @@ void Application::SetDeviceState(DeviceState state) {
990990
// The state is changed, wait for all background tasks to finish
991991
background_task_->WaitForCompletion();
992992

993+
// Send the state change event
994+
DeviceStateEventManager::GetInstance().PostStateChangeEvent(previous_state, state);
995+
993996
auto& board = Board::GetInstance();
994997
auto display = board.GetDisplay();
995998
auto led = board.GetLed();

main/application.h

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "audio_processor.h"
2424
#include "wake_word.h"
2525
#include "audio_debugger.h"
26+
#include "device_state_event.h"
2627

2728
#define SCHEDULE_EVENT (1 << 0)
2829
#define SEND_AUDIO_EVENT (1 << 1)
@@ -34,20 +35,6 @@ enum AecMode {
3435
kAecOnServerSide,
3536
};
3637

37-
enum DeviceState {
38-
kDeviceStateUnknown,
39-
kDeviceStateStarting,
40-
kDeviceStateWifiConfiguring,
41-
kDeviceStateIdle,
42-
kDeviceStateConnecting,
43-
kDeviceStateListening,
44-
kDeviceStateSpeaking,
45-
kDeviceStateUpgrading,
46-
kDeviceStateActivating,
47-
kDeviceStateAudioTesting,
48-
kDeviceStateFatalError
49-
};
50-
5138
#define OPUS_FRAME_DURATION_MS 60
5239
#define MAX_AUDIO_PACKETS_IN_QUEUE (2400 / OPUS_FRAME_DURATION_MS)
5340
#define AUDIO_TESTING_MAX_DURATION_MS 10000

main/device_state.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#ifndef _DEVICE_STATE_H_
2+
#define _DEVICE_STATE_H_
3+
4+
enum DeviceState {
5+
kDeviceStateUnknown,
6+
kDeviceStateStarting,
7+
kDeviceStateWifiConfiguring,
8+
kDeviceStateIdle,
9+
kDeviceStateConnecting,
10+
kDeviceStateListening,
11+
kDeviceStateSpeaking,
12+
kDeviceStateUpgrading,
13+
kDeviceStateActivating,
14+
kDeviceStateAudioTesting,
15+
kDeviceStateFatalError
16+
};
17+
18+
#endif // _DEVICE_STATE_H_

main/device_state_event.cc

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#include "device_state_event.h"
2+
3+
ESP_EVENT_DEFINE_BASE(XIAOZHI_STATE_EVENTS);
4+
5+
DeviceStateEventManager& DeviceStateEventManager::GetInstance() {
6+
static DeviceStateEventManager instance;
7+
return instance;
8+
}
9+
10+
void DeviceStateEventManager::RegisterStateChangeCallback(std::function<void(DeviceState, DeviceState)> callback) {
11+
std::lock_guard<std::mutex> lock(mutex_);
12+
callbacks_.push_back(callback);
13+
}
14+
15+
void DeviceStateEventManager::PostStateChangeEvent(DeviceState previous_state, DeviceState current_state) {
16+
device_state_event_data_t event_data = {
17+
.previous_state = previous_state,
18+
.current_state = current_state
19+
};
20+
esp_event_post(XIAOZHI_STATE_EVENTS, XIAOZHI_STATE_CHANGED_EVENT, &event_data, sizeof(event_data), portMAX_DELAY);
21+
}
22+
23+
std::vector<std::function<void(DeviceState, DeviceState)>> DeviceStateEventManager::GetCallbacks() {
24+
std::lock_guard<std::mutex> lock(mutex_);
25+
return callbacks_;
26+
}
27+
28+
DeviceStateEventManager::DeviceStateEventManager() {
29+
esp_err_t err = esp_event_loop_create_default();
30+
if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) {
31+
ESP_ERROR_CHECK(err);
32+
}
33+
34+
ESP_ERROR_CHECK(esp_event_handler_register(XIAOZHI_STATE_EVENTS, XIAOZHI_STATE_CHANGED_EVENT,
35+
[](void* handler_args, esp_event_base_t base, int32_t id, void* event_data) {
36+
auto* data = static_cast<device_state_event_data_t*>(event_data);
37+
auto& manager = DeviceStateEventManager::GetInstance();
38+
for (const auto& callback : manager.GetCallbacks()) {
39+
callback(data->previous_state, data->current_state);
40+
}
41+
}, nullptr));
42+
}
43+
44+
DeviceStateEventManager::~DeviceStateEventManager() {
45+
esp_event_handler_unregister(XIAOZHI_STATE_EVENTS, XIAOZHI_STATE_CHANGED_EVENT, nullptr);
46+
}

main/device_state_event.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#ifndef _DEVICE_STATE_EVENT_H_
2+
#define _DEVICE_STATE_EVENT_H_
3+
4+
#include <esp_event.h>
5+
#include <functional>
6+
#include <vector>
7+
#include <mutex>
8+
#include "device_state.h"
9+
10+
ESP_EVENT_DECLARE_BASE(XIAOZHI_STATE_EVENTS);
11+
12+
enum {
13+
XIAOZHI_STATE_CHANGED_EVENT,
14+
};
15+
16+
struct device_state_event_data_t {
17+
DeviceState previous_state;
18+
DeviceState current_state;
19+
};
20+
21+
class DeviceStateEventManager {
22+
public:
23+
static DeviceStateEventManager& GetInstance();
24+
DeviceStateEventManager(const DeviceStateEventManager&) = delete;
25+
DeviceStateEventManager& operator=(const DeviceStateEventManager&) = delete;
26+
27+
void RegisterStateChangeCallback(std::function<void(DeviceState, DeviceState)> callback);
28+
void PostStateChangeEvent(DeviceState previous_state, DeviceState current_state);
29+
std::vector<std::function<void(DeviceState, DeviceState)>> GetCallbacks();
30+
31+
private:
32+
DeviceStateEventManager();
33+
~DeviceStateEventManager();
34+
35+
std::vector<std::function<void(DeviceState, DeviceState)>> callbacks_;
36+
std::mutex mutex_;
37+
};
38+
39+
#endif // _DEVICE_STATE_EVENT_H_

main/led/gpio_led.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "gpio_led.h"
22
#include "application.h"
3+
#include "device_state.h"
34
#include <esp_log.h>
45

56
#define TAG "GpioLed"

0 commit comments

Comments
 (0)