forked from xiaozhi/xiaozhi-esp32
sending part of IoT states
This commit is contained in:
@@ -383,10 +383,12 @@ void Application::Start() {
|
|||||||
protocol_->server_sample_rate(), codec->output_sample_rate());
|
protocol_->server_sample_rate(), codec->output_sample_rate());
|
||||||
}
|
}
|
||||||
SetDecodeSampleRate(protocol_->server_sample_rate());
|
SetDecodeSampleRate(protocol_->server_sample_rate());
|
||||||
// IoT device descriptors
|
|
||||||
last_iot_states_.clear();
|
|
||||||
auto& thing_manager = iot::ThingManager::GetInstance();
|
auto& thing_manager = iot::ThingManager::GetInstance();
|
||||||
protocol_->SendIotDescriptors(thing_manager.GetDescriptorsJson());
|
protocol_->SendIotDescriptors(thing_manager.GetDescriptorsJson());
|
||||||
|
std::string states;
|
||||||
|
if (thing_manager.GetStatesJson(states, false)) {
|
||||||
|
protocol_->SendIotStates(states);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
protocol_->OnAudioChannelClosed([this, &board]() {
|
protocol_->OnAudioChannelClosed([this, &board]() {
|
||||||
board.SetPowerSaveMode(true);
|
board.SetPowerSaveMode(true);
|
||||||
@@ -789,9 +791,8 @@ void Application::SetDecodeSampleRate(int sample_rate) {
|
|||||||
|
|
||||||
void Application::UpdateIotStates() {
|
void Application::UpdateIotStates() {
|
||||||
auto& thing_manager = iot::ThingManager::GetInstance();
|
auto& thing_manager = iot::ThingManager::GetInstance();
|
||||||
auto states = thing_manager.GetStatesJson();
|
std::string states;
|
||||||
if (states != last_iot_states_) {
|
if (thing_manager.GetStatesJson(states, true)) {
|
||||||
last_iot_states_ = states;
|
|
||||||
protocol_->SendIotStates(states);
|
protocol_->SendIotStates(states);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,7 +91,6 @@ private:
|
|||||||
bool keep_listening_ = false;
|
bool keep_listening_ = false;
|
||||||
bool aborted_ = false;
|
bool aborted_ = false;
|
||||||
bool voice_detected_ = false;
|
bool voice_detected_ = false;
|
||||||
std::string last_iot_states_;
|
|
||||||
int clock_ticks_ = 0;
|
int clock_ticks_ = 0;
|
||||||
|
|
||||||
// Audio encode / decode
|
// Audio encode / decode
|
||||||
|
|||||||
@@ -22,16 +22,32 @@ std::string ThingManager::GetDescriptorsJson() {
|
|||||||
return json_str;
|
return json_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ThingManager::GetStatesJson() {
|
bool ThingManager::GetStatesJson(std::string& json, bool delta) {
|
||||||
std::string json_str = "[";
|
if (!delta) {
|
||||||
|
last_states_.clear();
|
||||||
|
}
|
||||||
|
bool changed = false;
|
||||||
|
json = "[";
|
||||||
|
// 枚举thing,获取每个thing的state,如果发生变化,则更新,保存到last_states_
|
||||||
|
// 如果delta为true,则只返回变化的部分
|
||||||
for (auto& thing : things_) {
|
for (auto& thing : things_) {
|
||||||
json_str += thing->GetStateJson() + ",";
|
std::string state = thing->GetStateJson();
|
||||||
|
if (delta) {
|
||||||
|
// 如果delta为true,则只返回变化的部分
|
||||||
|
auto it = last_states_.find(thing->name());
|
||||||
|
if (it != last_states_.end() && it->second == state) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
changed = true;
|
||||||
|
last_states_[thing->name()] = state;
|
||||||
|
}
|
||||||
|
json += state + ",";
|
||||||
}
|
}
|
||||||
if (json_str.back() == ',') {
|
if (json.back() == ',') {
|
||||||
json_str.pop_back();
|
json.pop_back();
|
||||||
}
|
}
|
||||||
json_str += "]";
|
json += "]";
|
||||||
return json_str;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThingManager::Invoke(const cJSON* command) {
|
void ThingManager::Invoke(const cJSON* command) {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ public:
|
|||||||
void AddThing(Thing* thing);
|
void AddThing(Thing* thing);
|
||||||
|
|
||||||
std::string GetDescriptorsJson();
|
std::string GetDescriptorsJson();
|
||||||
std::string GetStatesJson();
|
bool GetStatesJson(std::string& json, bool delta = false);
|
||||||
void Invoke(const cJSON* command);
|
void Invoke(const cJSON* command);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -33,6 +33,7 @@ private:
|
|||||||
~ThingManager() = default;
|
~ThingManager() = default;
|
||||||
|
|
||||||
std::vector<Thing*> things_;
|
std::vector<Thing*> things_;
|
||||||
|
std::map<std::string, std::string> last_states_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ void Protocol::SendIotDescriptors(const std::string& descriptors) {
|
|||||||
cJSON_AddItemToArray(descriptorArray, cJSON_Duplicate(descriptor, 1));
|
cJSON_AddItemToArray(descriptorArray, cJSON_Duplicate(descriptor, 1));
|
||||||
cJSON_AddItemToObject(messageRoot, "descriptors", descriptorArray);
|
cJSON_AddItemToObject(messageRoot, "descriptors", descriptorArray);
|
||||||
|
|
||||||
char* message = cJSON_Print(messageRoot);
|
char* message = cJSON_PrintUnformatted(messageRoot);
|
||||||
if (message == nullptr) {
|
if (message == nullptr) {
|
||||||
ESP_LOGE(TAG, "Failed to print JSON message for IoT descriptor at index %d", i);
|
ESP_LOGE(TAG, "Failed to print JSON message for IoT descriptor at index %d", i);
|
||||||
cJSON_Delete(messageRoot);
|
cJSON_Delete(messageRoot);
|
||||||
@@ -111,7 +111,7 @@ void Protocol::SendIotDescriptors(const std::string& descriptors) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Protocol::SendIotStates(const std::string& states) {
|
void Protocol::SendIotStates(const std::string& states) {
|
||||||
std::string message = "{\"session_id\":\"" + session_id_ + "\",\"type\":\"iot\",\"states\":" + states + "}";
|
std::string message = "{\"session_id\":\"" + session_id_ + "\",\"type\":\"iot\",\"update\":true,\"states\":" + states + "}";
|
||||||
SendText(message);
|
SendText(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user