Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions firmware/main/apps/app_avatar/app_avatar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,24 @@ void AppAvatar::onOpen()
}
});

GetHAL().onWsDeviceControl.connect([&](const WsDeviceControl_t& control) {
LvglLockGuard lvgl_lock;

switch (control.action) {
case WsDeviceControlAction::Sleep:
GetHAL().enterRemoteSleepMode();
break;
case WsDeviceControlAction::Wake:
GetHAL().exitRemoteSleepMode();
break;
case WsDeviceControlAction::PowerOff:
GetHAL().remotePowerOff();
break;
default:
break;
}
});

GetHAL().onWsDanceData.connect([&](std::string_view data) {
LvglLockGuard lvgl_lock;
auto sequence = stackchan::animation::parse_sequence_from_json(data.data());
Expand Down Expand Up @@ -324,6 +342,7 @@ void AppAvatar::onClose()
GetHAL().onWsCallRequest.clear();
GetHAL().onWsCallEnd.clear();
GetHAL().onWsTextMessage.clear();
GetHAL().onWsDeviceControl.clear();
GetHAL().onWsDanceData.clear();

_ws_call_view_id = -1;
Expand Down
2 changes: 1 addition & 1 deletion firmware/main/apps/app_avatar/view/ws_display_card.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ WsDisplayCardView::WsDisplayCardView(lv_obj_t* parent, std::string title, const
_title->align(LV_ALIGN_TOP_LEFT, 0, 0);
_title->setWidth(260);
_title->setText(title.empty() ? "STATUS" : title);
_title->setTextFont(&lv_font_montserrat_18);
_title->setTextFont(&lv_font_montserrat_20);
_title->setTextColor(lv_color_hex(0x47330A));

_content = std::make_unique<uitk::lvgl_cpp::Label>(_card->get());
Expand Down
2 changes: 2 additions & 0 deletions firmware/main/hal/board/hal_bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ void board_set_backlight_brightness(uint8_t brightness, bool permanent = false);
uint8_t board_get_backlight_brightness();
void board_set_speaker_volume(uint8_t volume, bool permanent = false);
uint8_t board_get_speaker_volume();
void board_set_power_save_mode(bool enabled);
void board_power_off();

void app_play_sound(const std::string_view& sound);

Expand Down
32 changes: 32 additions & 0 deletions firmware/main/hal/board/stackchan.cc
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,26 @@ class M5StackCoreS3Board : public WifiBoard {
return &backlight;
}

void SetManualPowerSaveMode(bool enabled)
{
if (enabled) {
GetDisplay()->SetPowerSaveMode(true);
GetBacklight()->SetBrightness(10);
return;
}

GetDisplay()->SetPowerSaveMode(false);
GetBacklight()->RestoreBrightness();
if (power_save_timer_ != nullptr) {
power_save_timer_->WakeUp();
}
}

void PowerOffNow()
{
pmic_->PowerOff();
}

i2c_master_bus_handle_t GetI2cBus()
{
return i2c_bus_;
Expand Down Expand Up @@ -650,6 +670,18 @@ uint8_t hal_bridge::board_get_speaker_volume()
return volume;
}

void hal_bridge::board_set_power_save_mode(bool enabled)
{
auto& board = (M5StackCoreS3Board&)Board::GetInstance();
board.SetManualPowerSaveMode(enabled);
}

void hal_bridge::board_power_off()
{
auto& board = (M5StackCoreS3Board&)Board::GetInstance();
board.PowerOffNow();
}

void hal_bridge::toggle_xiaozhi_chat_state()
{
auto& app = Application::GetInstance();
Expand Down
16 changes: 16 additions & 0 deletions firmware/main/hal/hal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* SPDX-License-Identifier: MIT
*/
#include "hal.h"
#include "board/hal_bridge.h"
#include <memory>
#include <mooncake_log.h>
#include <nvs_flash.h>
Expand Down Expand Up @@ -87,6 +88,21 @@ void Hal::reboot()
esp_restart();
}

void Hal::enterRemoteSleepMode()
{
hal_bridge::board_set_power_save_mode(true);
}

void Hal::exitRemoteSleepMode()
{
hal_bridge::board_set_power_save_mode(false);
}

void Hal::remotePowerOff()
{
hal_bridge::board_power_off();
}

static void _confirm_ota_image_if_stable()
{
constexpr uint32_t ota_confirm_delay_ms = 20000;
Expand Down
14 changes: 14 additions & 0 deletions firmware/main/hal/hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ enum class WsTextMessageMode {
DisplayCard,
};

enum class WsDeviceControlAction {
Sleep = 0,
Wake,
PowerOff,
};

/**
* @brief
*
Expand All @@ -51,6 +57,10 @@ struct WsTextMessage_t {
uint32_t durationMs = 4000;
};

struct WsDeviceControl_t {
WsDeviceControlAction action = WsDeviceControlAction::Sleep;
};

/**
* @brief
*
Expand Down Expand Up @@ -199,6 +209,9 @@ class Hal {
std::array<uint8_t, 6> getFactoryMac();
std::string getFactoryMacString(std::string divider = "");
void reboot();
void enterRemoteSleepMode();
void exitRemoteSleepMode();
void remotePowerOff();
void updateHeapStatusLog();
uint8_t getBatteryLevel();
bool isBatteryCharging();
Expand Down Expand Up @@ -256,6 +269,7 @@ class Hal {
uitk::Signal<bool> onWsCallResponse;
uitk::Signal<WsSignalSource> onWsCallEnd;
uitk::Signal<const WsTextMessage_t&> onWsTextMessage;
uitk::Signal<const WsDeviceControl_t&> onWsDeviceControl;
uitk::Signal<bool> onWsVideoModeChange;
uitk::Signal<std::shared_ptr<LvglImage>> onWsVideoFrame;
uitk::Signal<std::string_view> onWsDanceData;
Expand Down
22 changes: 22 additions & 0 deletions firmware/main/hal/hal_ws_avatar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,28 @@ class WebSocketAvatar {
auto type = doc["type"].as<std::string>();
if (type == "displayCard" || type == "display_card") {
text_msg.mode = WsTextMessageMode::DisplayCard;
} else if (type == "deviceControl" || type == "device_control") {
WsDeviceControl_t control_msg;

if (!doc["action"].is<std::string>()) {
ESP_LOGE(_tag.c_str(), "deviceControl action missing");
return;
}

auto action = doc["action"].as<std::string>();
if (action == "sleep") {
control_msg.action = WsDeviceControlAction::Sleep;
} else if (action == "wake") {
control_msg.action = WsDeviceControlAction::Wake;
} else if (action == "powerOff" || action == "power_off" || action == "shutdown") {
control_msg.action = WsDeviceControlAction::PowerOff;
} else {
ESP_LOGE(_tag.c_str(), "unknown deviceControl action: %s", action.c_str());
return;
}

GetHAL().onWsDeviceControl.emit(control_msg);
return;
}
}

Expand Down