forked from xiaozhi/xiaozhi-esp32
sensecap watcher manufacture (#469)
* feat: add shutdown and battery cmd. * fix: fixed the issue that the LCD does not light up when some devices are turned on. * fix: fix task sys_evt stack overflow. * feat: Optimize UI display for circles; add Added factory reset function. * feat: "low_battery_label_" obj configurable * feat: add read_mac cmd * fix: fix "low_battery_label_" obj redefine * style: modify Google C++ Style. * Update sensecap_watcher.cc Remove extra spaces --------- Co-authored-by: Xiaoxia <terrence@tenclass.com>
This commit is contained in:
@@ -98,4 +98,9 @@
|
|||||||
|
|
||||||
#define CONFIG_BSP_LCD_SPI_DMA_SIZE_DIV 16
|
#define CONFIG_BSP_LCD_SPI_DMA_SIZE_DIV 16
|
||||||
|
|
||||||
|
/* ADC */
|
||||||
|
#define BSP_BAT_ADC_CHAN (ADC_CHANNEL_2) // GPIO3
|
||||||
|
#define BSP_BAT_ADC_ATTEN (ADC_ATTEN_DB_2_5) // 0 ~ 1100 mV
|
||||||
|
#define BSP_BAT_VOL_RATIO ((62 + 20) / 20)
|
||||||
|
|
||||||
#endif // _BOARD_CONFIG_H_
|
#endif // _BOARD_CONFIG_H_
|
||||||
|
|||||||
@@ -25,12 +25,64 @@
|
|||||||
#include <iot_knob.h>
|
#include <iot_knob.h>
|
||||||
#include <esp_io_expander_tca95xx_16bit.h>
|
#include <esp_io_expander_tca95xx_16bit.h>
|
||||||
#include <esp_sleep.h>
|
#include <esp_sleep.h>
|
||||||
|
#include "esp_console.h"
|
||||||
|
#include "esp_mac.h"
|
||||||
|
#include "nvs_flash.h"
|
||||||
|
|
||||||
|
#include "assets/lang_config.h"
|
||||||
|
|
||||||
#define TAG "sensecap_watcher"
|
#define TAG "sensecap_watcher"
|
||||||
|
|
||||||
|
|
||||||
LV_FONT_DECLARE(font_puhui_30_4);
|
LV_FONT_DECLARE(font_puhui_30_4);
|
||||||
LV_FONT_DECLARE(font_awesome_30_4);
|
LV_FONT_DECLARE(font_awesome_20_4);
|
||||||
|
|
||||||
|
class CustomLcdDisplay : public SpiLcdDisplay {
|
||||||
|
public:
|
||||||
|
CustomLcdDisplay(esp_lcd_panel_io_handle_t io_handle,
|
||||||
|
esp_lcd_panel_handle_t panel_handle,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
int offset_x,
|
||||||
|
int offset_y,
|
||||||
|
bool mirror_x,
|
||||||
|
bool mirror_y,
|
||||||
|
bool swap_xy)
|
||||||
|
: SpiLcdDisplay(io_handle, panel_handle, width, height, offset_x, offset_y, mirror_x, mirror_y, swap_xy,
|
||||||
|
{
|
||||||
|
.text_font = &font_puhui_30_4,
|
||||||
|
.icon_font = &font_awesome_20_4,
|
||||||
|
.emoji_font = font_emoji_64_init(),
|
||||||
|
}) {
|
||||||
|
|
||||||
|
DisplayLockGuard lock(this);
|
||||||
|
lv_obj_set_size(status_bar_, LV_HOR_RES, fonts_.text_font->line_height * 2 + 10);
|
||||||
|
lv_obj_set_style_layout(status_bar_, LV_LAYOUT_NONE, 0);
|
||||||
|
lv_obj_set_style_pad_top(status_bar_, 10, 0);
|
||||||
|
lv_obj_set_style_pad_bottom(status_bar_, 1, 0);
|
||||||
|
|
||||||
|
// 针对圆形屏幕调整位置
|
||||||
|
// network battery mute //
|
||||||
|
// status //
|
||||||
|
lv_obj_align(battery_label_, LV_ALIGN_TOP_MID, -2.5*fonts_.icon_font->line_height, 0);
|
||||||
|
lv_obj_align(network_label_, LV_ALIGN_TOP_MID, -0.5*fonts_.icon_font->line_height, 0);
|
||||||
|
lv_obj_align(mute_label_, LV_ALIGN_TOP_MID, 1.5*fonts_.icon_font->line_height, 0);
|
||||||
|
|
||||||
|
lv_obj_align(status_label_, LV_ALIGN_BOTTOM_MID, 0, 0);
|
||||||
|
lv_obj_set_flex_grow(status_label_, 0);
|
||||||
|
lv_obj_set_width(status_label_, LV_HOR_RES * 0.75);
|
||||||
|
lv_label_set_long_mode(status_label_, LV_LABEL_LONG_SCROLL_CIRCULAR);
|
||||||
|
|
||||||
|
lv_obj_align(notification_label_, LV_ALIGN_BOTTOM_MID, 0, 0);
|
||||||
|
lv_obj_set_width(notification_label_, LV_HOR_RES * 0.75);
|
||||||
|
lv_label_set_long_mode(notification_label_, LV_LABEL_LONG_SCROLL_CIRCULAR);
|
||||||
|
|
||||||
|
lv_obj_align(low_battery_popup_, LV_ALIGN_BOTTOM_MID, 0, -20);
|
||||||
|
lv_obj_set_style_bg_color(low_battery_popup_, lv_color_hex(0xFF0000), 0);
|
||||||
|
lv_obj_set_width(low_battery_label_, LV_HOR_RES * 0.75);
|
||||||
|
lv_label_set_long_mode(low_battery_label_, LV_LABEL_LONG_SCROLL_CIRCULAR);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class SensecapWatcher : public WifiBoard {
|
class SensecapWatcher : public WifiBoard {
|
||||||
private:
|
private:
|
||||||
@@ -42,7 +94,7 @@ private:
|
|||||||
PowerSaveTimer* power_save_timer_;
|
PowerSaveTimer* power_save_timer_;
|
||||||
esp_lcd_panel_io_handle_t panel_io_ = nullptr;
|
esp_lcd_panel_io_handle_t panel_io_ = nullptr;
|
||||||
esp_lcd_panel_handle_t panel_ = nullptr;
|
esp_lcd_panel_handle_t panel_ = nullptr;
|
||||||
|
uint32_t long_press_cnt_;
|
||||||
void InitializePowerSaveTimer() {
|
void InitializePowerSaveTimer() {
|
||||||
power_save_timer_ = new PowerSaveTimer(-1, 60, 300);
|
power_save_timer_ = new PowerSaveTimer(-1, 60, 300);
|
||||||
power_save_timer_->OnEnterSleepMode([this]() {
|
power_save_timer_->OnEnterSleepMode([this]() {
|
||||||
@@ -144,7 +196,7 @@ private:
|
|||||||
void OnKnobRotate(bool clockwise) {
|
void OnKnobRotate(bool clockwise) {
|
||||||
auto codec = GetAudioCodec();
|
auto codec = GetAudioCodec();
|
||||||
int current_volume = codec->output_volume();
|
int current_volume = codec->output_volume();
|
||||||
int new_volume = current_volume + (clockwise ? 5 : -5);
|
int new_volume = current_volume + (clockwise ? -5 : 5);
|
||||||
|
|
||||||
// 确保音量在有效范围内
|
// 确保音量在有效范围内
|
||||||
if (new_volume > 100) {
|
if (new_volume > 100) {
|
||||||
@@ -163,7 +215,7 @@ private:
|
|||||||
ESP_LOGE(TAG, "Failed to set volume! Expected:%d Actual:%d",
|
ESP_LOGE(TAG, "Failed to set volume! Expected:%d Actual:%d",
|
||||||
new_volume, codec->output_volume());
|
new_volume, codec->output_volume());
|
||||||
}
|
}
|
||||||
GetDisplay()->ShowNotification("音量: " + std::to_string(codec->output_volume()));
|
GetDisplay()->ShowNotification(std::string(Lang::Strings::VOLUME) + ": "+std::to_string(codec->output_volume()));
|
||||||
power_save_timer_->WakeUp();
|
power_save_timer_->WakeUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,7 +245,7 @@ private:
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
//watcher 是通过长按滚轮进行开机的, 需要等待滚轮释放, 否则用户开机松手时可能会误触成单击
|
// watcher 是通过长按滚轮进行开机的, 需要等待滚轮释放, 否则用户开机松手时可能会误触成单击
|
||||||
ESP_LOGI(TAG, "waiting for knob button release");
|
ESP_LOGI(TAG, "waiting for knob button release");
|
||||||
while(IoExpanderGetLevel(BSP_KNOB_BTN) == 0) {
|
while(IoExpanderGetLevel(BSP_KNOB_BTN) == 0) {
|
||||||
vTaskDelay(50 / portTICK_PERIOD_MS);
|
vTaskDelay(50 / portTICK_PERIOD_MS);
|
||||||
@@ -212,6 +264,7 @@ private:
|
|||||||
iot_button_register_cb(btns, BUTTON_LONG_PRESS_START, [](void* button_handle, void* usr_data) {
|
iot_button_register_cb(btns, BUTTON_LONG_PRESS_START, [](void* button_handle, void* usr_data) {
|
||||||
auto self = static_cast<SensecapWatcher*>(usr_data);
|
auto self = static_cast<SensecapWatcher*>(usr_data);
|
||||||
bool is_charging = (self->IoExpanderGetLevel(BSP_PWR_VBUS_IN_DET) == 0);
|
bool is_charging = (self->IoExpanderGetLevel(BSP_PWR_VBUS_IN_DET) == 0);
|
||||||
|
self->long_press_cnt_ = 0;
|
||||||
if (is_charging) {
|
if (is_charging) {
|
||||||
ESP_LOGI(TAG, "charging");
|
ESP_LOGI(TAG, "charging");
|
||||||
} else {
|
} else {
|
||||||
@@ -219,6 +272,18 @@ private:
|
|||||||
self->IoExpanderSetLevel(BSP_PWR_SYSTEM, 0);
|
self->IoExpanderSetLevel(BSP_PWR_SYSTEM, 0);
|
||||||
}
|
}
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
|
iot_button_register_cb(btns, BUTTON_LONG_PRESS_HOLD, [](void* button_handle, void* usr_data) {
|
||||||
|
auto self = static_cast<SensecapWatcher*>(usr_data);
|
||||||
|
self->long_press_cnt_++; // 每隔20ms加一
|
||||||
|
// 长按10s 恢复出厂设置: 2+0.02*400 = 10
|
||||||
|
if (self->long_press_cnt_ > 400) {
|
||||||
|
ESP_LOGI(TAG, "Factory reset");
|
||||||
|
nvs_flash_erase();
|
||||||
|
esp_restart();
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeSpi() {
|
void InitializeSpi() {
|
||||||
@@ -270,23 +335,18 @@ private:
|
|||||||
esp_lcd_panel_mirror(panel_, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y);
|
esp_lcd_panel_mirror(panel_, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y);
|
||||||
esp_lcd_panel_disp_on_off(panel_, true);
|
esp_lcd_panel_disp_on_off(panel_, true);
|
||||||
|
|
||||||
display_ = new SpiLcdDisplay(panel_io_, panel_,
|
display_ = new CustomLcdDisplay(panel_io_, panel_,
|
||||||
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY,
|
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY);
|
||||||
{
|
|
||||||
.text_font = &font_puhui_30_4,
|
|
||||||
.icon_font = &font_awesome_30_4,
|
|
||||||
.emoji_font = font_emoji_64_init(),
|
|
||||||
});
|
|
||||||
|
|
||||||
// 使每次刷新的起始列数索引是4的倍数且列数总数是4的倍数,以满足SPD2010的要求
|
// 使每次刷新的起始列数索引是4的倍数且列数总数是4的倍数,以满足SPD2010的要求
|
||||||
lv_display_add_event_cb(lv_display_get_default(), [](lv_event_t *e) {
|
lv_display_add_event_cb(lv_display_get_default(), [](lv_event_t *e) {
|
||||||
lv_area_t *area = (lv_area_t *)lv_event_get_param(e);
|
lv_area_t *area = (lv_area_t *)lv_event_get_param(e);
|
||||||
uint16_t x1 = area->x1;
|
uint16_t x1 = area->x1;
|
||||||
uint16_t x2 = area->x2;
|
uint16_t x2 = area->x2;
|
||||||
// round the start of area down to the nearest 4N number
|
// round the start of area down to the nearest 4N number
|
||||||
area->x1 = (x1 >> 2) << 2;
|
area->x1 = (x1 >> 2) << 2;
|
||||||
// round the end of area up to the nearest 4M+3 number
|
// round the end of area up to the nearest 4M+3 number
|
||||||
area->x2 = ((x2 >> 2) << 2) + 3;
|
area->x2 = ((x2 >> 2) << 2) + 3;
|
||||||
}, LV_EVENT_INVALIDATE_AREA, NULL);
|
}, LV_EVENT_INVALIDATE_AREA, NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -296,15 +356,159 @@ private:
|
|||||||
auto& thing_manager = iot::ThingManager::GetInstance();
|
auto& thing_manager = iot::ThingManager::GetInstance();
|
||||||
thing_manager.AddThing(iot::CreateThing("Speaker"));
|
thing_manager.AddThing(iot::CreateThing("Speaker"));
|
||||||
thing_manager.AddThing(iot::CreateThing("Screen"));
|
thing_manager.AddThing(iot::CreateThing("Screen"));
|
||||||
|
thing_manager.AddThing(iot::CreateThing("Battery"));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t BatterygetVoltage(void) {
|
||||||
|
static bool initialized = false;
|
||||||
|
static adc_oneshot_unit_handle_t adc_handle;
|
||||||
|
static adc_cali_handle_t cali_handle = NULL;
|
||||||
|
if (!initialized) {
|
||||||
|
adc_oneshot_unit_init_cfg_t init_config = {
|
||||||
|
.unit_id = ADC_UNIT_1,
|
||||||
|
};
|
||||||
|
adc_oneshot_new_unit(&init_config, &adc_handle);
|
||||||
|
|
||||||
|
adc_oneshot_chan_cfg_t ch_config = {
|
||||||
|
.atten = BSP_BAT_ADC_ATTEN,
|
||||||
|
.bitwidth = ADC_BITWIDTH_DEFAULT,
|
||||||
|
};
|
||||||
|
adc_oneshot_config_channel(adc_handle, BSP_BAT_ADC_CHAN, &ch_config);
|
||||||
|
|
||||||
|
adc_cali_curve_fitting_config_t cali_config = {
|
||||||
|
.unit_id = ADC_UNIT_1,
|
||||||
|
.chan = BSP_BAT_ADC_CHAN,
|
||||||
|
.atten = BSP_BAT_ADC_ATTEN,
|
||||||
|
.bitwidth = ADC_BITWIDTH_DEFAULT,
|
||||||
|
};
|
||||||
|
if (adc_cali_create_scheme_curve_fitting(&cali_config, &cali_handle) == ESP_OK) {
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (initialized) {
|
||||||
|
int raw_value = 0;
|
||||||
|
int voltage = 0; // mV
|
||||||
|
adc_oneshot_read(adc_handle, BSP_BAT_ADC_CHAN, &raw_value);
|
||||||
|
adc_cali_raw_to_voltage(cali_handle, raw_value, &voltage);
|
||||||
|
voltage = voltage * 82 / 20;
|
||||||
|
// ESP_LOGI(TAG, "voltage: %dmV", voltage);
|
||||||
|
return (uint16_t)voltage;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t BatterygetPercent(bool print = false) {
|
||||||
|
int voltage = 0;
|
||||||
|
for (uint8_t i = 0; i < 10; i++) {
|
||||||
|
voltage += BatterygetVoltage();
|
||||||
|
}
|
||||||
|
voltage /= 10;
|
||||||
|
int percent = (-1 * voltage * voltage + 9016 * voltage - 19189000) / 10000;
|
||||||
|
percent = (percent > 100) ? 100 : (percent < 0) ? 0 : percent;
|
||||||
|
if (print) {
|
||||||
|
printf("voltage: %dmV, percentage: %d%%\r\n", voltage, percent);
|
||||||
|
}
|
||||||
|
return (uint8_t)percent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeCmd() {
|
||||||
|
esp_console_repl_t *repl = NULL;
|
||||||
|
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
||||||
|
repl_config.max_cmdline_length = 1024;
|
||||||
|
repl_config.prompt = "SenseCAP>";
|
||||||
|
|
||||||
|
const esp_console_cmd_t cmd1 = {
|
||||||
|
.command = "reboot",
|
||||||
|
.help = "reboot the device",
|
||||||
|
.hint = nullptr,
|
||||||
|
.func = [](int argc, char** argv) -> int {
|
||||||
|
esp_restart();
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
.argtable = nullptr
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd1));
|
||||||
|
|
||||||
|
const esp_console_cmd_t cmd2 = {
|
||||||
|
.command = "shutdown",
|
||||||
|
.help = "shutdown the device",
|
||||||
|
.hint = nullptr,
|
||||||
|
.func = NULL,
|
||||||
|
.argtable = NULL,
|
||||||
|
.func_w_context = [](void *context,int argc, char** argv) -> int {
|
||||||
|
auto self = static_cast<SensecapWatcher*>(context);
|
||||||
|
self->GetBacklight()->SetBrightness(0);
|
||||||
|
self->IoExpanderSetLevel(BSP_PWR_SYSTEM, 0);
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
.context =this
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd2));
|
||||||
|
|
||||||
|
const esp_console_cmd_t cmd3 = {
|
||||||
|
.command = "battery",
|
||||||
|
.help = "get battery percent",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = NULL,
|
||||||
|
.argtable = NULL,
|
||||||
|
.func_w_context = [](void *context,int argc, char** argv) -> int {
|
||||||
|
auto self = static_cast<SensecapWatcher*>(context);
|
||||||
|
self->BatterygetPercent(true);
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
.context =this
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd3));
|
||||||
|
|
||||||
|
const esp_console_cmd_t cmd4 = {
|
||||||
|
.command = "factory_reset",
|
||||||
|
.help = "factory reset and reboot the device",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = NULL,
|
||||||
|
.argtable = NULL,
|
||||||
|
.func_w_context = [](void *context,int argc, char** argv) -> int {
|
||||||
|
auto self = static_cast<SensecapWatcher*>(context);
|
||||||
|
nvs_flash_erase();
|
||||||
|
esp_restart();
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
.context =this
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd4));
|
||||||
|
|
||||||
|
const esp_console_cmd_t cmd5 = {
|
||||||
|
.command = "read_mac",
|
||||||
|
.help = "Read mac address",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = NULL,
|
||||||
|
.argtable = NULL,
|
||||||
|
.func_w_context = [](void *context,int argc, char** argv) -> int {
|
||||||
|
uint8_t mac[6];
|
||||||
|
esp_read_mac(mac, ESP_MAC_WIFI_STA);
|
||||||
|
printf("wifi_sta_mac: " MACSTR "\n", MAC2STR(mac));
|
||||||
|
esp_read_mac(mac, ESP_MAC_WIFI_SOFTAP);
|
||||||
|
printf("wifi_softap_mac: " MACSTR "\n", MAC2STR(mac));
|
||||||
|
esp_read_mac(mac, ESP_MAC_BT);
|
||||||
|
printf("bt_mac: " MACSTR "\n", MAC2STR(mac));
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
.context =this
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd5));
|
||||||
|
|
||||||
|
esp_console_dev_uart_config_t hw_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
|
||||||
|
ESP_ERROR_CHECK(esp_console_new_repl_uart(&hw_config, &repl_config, &repl));
|
||||||
|
ESP_ERROR_CHECK(esp_console_start_repl(repl));
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SensecapWatcher(){
|
SensecapWatcher() {
|
||||||
ESP_LOGI(TAG, "Initialize Sensecap Watcher");
|
ESP_LOGI(TAG, "Initialize Sensecap Watcher");
|
||||||
InitializePowerSaveTimer();
|
InitializePowerSaveTimer();
|
||||||
InitializeI2c();
|
InitializeI2c();
|
||||||
InitializeSpi();
|
InitializeSpi();
|
||||||
InitializeExpander();
|
InitializeExpander();
|
||||||
|
InitializeCmd(); //工厂生产测试使用
|
||||||
InitializeButton();
|
InitializeButton();
|
||||||
InitializeKnob();
|
InitializeKnob();
|
||||||
Initializespd2010Display();
|
Initializespd2010Display();
|
||||||
@@ -352,6 +556,23 @@ public:
|
|||||||
}
|
}
|
||||||
WifiBoard::SetPowerSaveMode(enabled);
|
WifiBoard::SetPowerSaveMode(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool GetBatteryLevel(int &level, bool& charging, bool& discharging) override {
|
||||||
|
static bool last_discharging = false;
|
||||||
|
charging = (IoExpanderGetLevel(BSP_PWR_VBUS_IN_DET) == 0);
|
||||||
|
discharging = !charging;
|
||||||
|
level = (int)BatterygetPercent(false);
|
||||||
|
|
||||||
|
if (discharging != last_discharging) {
|
||||||
|
power_save_timer_->SetEnabled(discharging);
|
||||||
|
last_discharging = discharging;
|
||||||
|
}
|
||||||
|
if (level <= 1 && discharging) {
|
||||||
|
ESP_LOGI(TAG, "Battery level is low, shutting down");
|
||||||
|
IoExpanderSetLevel(BSP_PWR_SYSTEM, 0);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
DECLARE_BOARD(SensecapWatcher);
|
DECLARE_BOARD(SensecapWatcher);
|
||||||
|
|||||||
@@ -75,7 +75,9 @@ Display::~Display() {
|
|||||||
lv_obj_del(battery_label_);
|
lv_obj_del(battery_label_);
|
||||||
lv_obj_del(emotion_label_);
|
lv_obj_del(emotion_label_);
|
||||||
}
|
}
|
||||||
|
if( low_battery_popup_ != nullptr ) {
|
||||||
|
lv_obj_del(low_battery_popup_);
|
||||||
|
}
|
||||||
if (pm_lock_ != nullptr) {
|
if (pm_lock_ != nullptr) {
|
||||||
esp_pm_lock_delete(pm_lock_);
|
esp_pm_lock_delete(pm_lock_);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ protected:
|
|||||||
lv_obj_t *battery_label_ = nullptr;
|
lv_obj_t *battery_label_ = nullptr;
|
||||||
lv_obj_t* chat_message_label_ = nullptr;
|
lv_obj_t* chat_message_label_ = nullptr;
|
||||||
lv_obj_t* low_battery_popup_ = nullptr;
|
lv_obj_t* low_battery_popup_ = nullptr;
|
||||||
|
lv_obj_t* low_battery_label_ = nullptr;
|
||||||
|
|
||||||
const char* battery_icon_ = nullptr;
|
const char* battery_icon_ = nullptr;
|
||||||
const char* network_icon_ = nullptr;
|
const char* network_icon_ = nullptr;
|
||||||
bool muted_ = false;
|
bool muted_ = false;
|
||||||
|
|||||||
@@ -363,10 +363,10 @@ void LcdDisplay::SetupUI() {
|
|||||||
lv_obj_align(low_battery_popup_, LV_ALIGN_BOTTOM_MID, 0, 0);
|
lv_obj_align(low_battery_popup_, LV_ALIGN_BOTTOM_MID, 0, 0);
|
||||||
lv_obj_set_style_bg_color(low_battery_popup_, current_theme.low_battery, 0);
|
lv_obj_set_style_bg_color(low_battery_popup_, current_theme.low_battery, 0);
|
||||||
lv_obj_set_style_radius(low_battery_popup_, 10, 0);
|
lv_obj_set_style_radius(low_battery_popup_, 10, 0);
|
||||||
lv_obj_t* low_battery_label = lv_label_create(low_battery_popup_);
|
low_battery_label_ = lv_label_create(low_battery_popup_);
|
||||||
lv_label_set_text(low_battery_label, Lang::Strings::BATTERY_NEED_CHARGE);
|
lv_label_set_text(low_battery_label_, Lang::Strings::BATTERY_NEED_CHARGE);
|
||||||
lv_obj_set_style_text_color(low_battery_label, lv_color_white(), 0);
|
lv_obj_set_style_text_color(low_battery_label_, lv_color_white(), 0);
|
||||||
lv_obj_center(low_battery_label);
|
lv_obj_center(low_battery_label_);
|
||||||
lv_obj_add_flag(low_battery_popup_, LV_OBJ_FLAG_HIDDEN);
|
lv_obj_add_flag(low_battery_popup_, LV_OBJ_FLAG_HIDDEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -628,10 +628,10 @@ void LcdDisplay::SetupUI() {
|
|||||||
lv_obj_align(low_battery_popup_, LV_ALIGN_BOTTOM_MID, 0, 0);
|
lv_obj_align(low_battery_popup_, LV_ALIGN_BOTTOM_MID, 0, 0);
|
||||||
lv_obj_set_style_bg_color(low_battery_popup_, current_theme.low_battery, 0);
|
lv_obj_set_style_bg_color(low_battery_popup_, current_theme.low_battery, 0);
|
||||||
lv_obj_set_style_radius(low_battery_popup_, 10, 0);
|
lv_obj_set_style_radius(low_battery_popup_, 10, 0);
|
||||||
lv_obj_t* low_battery_label = lv_label_create(low_battery_popup_);
|
low_battery_label_ = lv_label_create(low_battery_popup_);
|
||||||
lv_label_set_text(low_battery_label, Lang::Strings::BATTERY_NEED_CHARGE);
|
lv_label_set_text(low_battery_label_, Lang::Strings::BATTERY_NEED_CHARGE);
|
||||||
lv_obj_set_style_text_color(low_battery_label, lv_color_white(), 0);
|
lv_obj_set_style_text_color(low_battery_label_, lv_color_white(), 0);
|
||||||
lv_obj_center(low_battery_label);
|
lv_obj_center(low_battery_label_);
|
||||||
lv_obj_add_flag(low_battery_popup_, LV_OBJ_FLAG_HIDDEN);
|
lv_obj_add_flag(low_battery_popup_, LV_OBJ_FLAG_HIDDEN);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -218,10 +218,10 @@ void OledDisplay::SetupUI_128x64() {
|
|||||||
lv_obj_align(low_battery_popup_, LV_ALIGN_BOTTOM_MID, 0, 0);
|
lv_obj_align(low_battery_popup_, LV_ALIGN_BOTTOM_MID, 0, 0);
|
||||||
lv_obj_set_style_bg_color(low_battery_popup_, lv_color_black(), 0);
|
lv_obj_set_style_bg_color(low_battery_popup_, lv_color_black(), 0);
|
||||||
lv_obj_set_style_radius(low_battery_popup_, 10, 0);
|
lv_obj_set_style_radius(low_battery_popup_, 10, 0);
|
||||||
lv_obj_t* low_battery_label = lv_label_create(low_battery_popup_);
|
low_battery_label_ = lv_label_create(low_battery_popup_);
|
||||||
lv_label_set_text(low_battery_label, Lang::Strings::BATTERY_NEED_CHARGE);
|
lv_label_set_text(low_battery_label_, Lang::Strings::BATTERY_NEED_CHARGE);
|
||||||
lv_obj_set_style_text_color(low_battery_label, lv_color_white(), 0);
|
lv_obj_set_style_text_color(low_battery_label_, lv_color_white(), 0);
|
||||||
lv_obj_center(low_battery_label);
|
lv_obj_center(low_battery_label_);
|
||||||
lv_obj_add_flag(low_battery_popup_, LV_OBJ_FLAG_HIDDEN);
|
lv_obj_add_flag(low_battery_popup_, LV_OBJ_FLAG_HIDDEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user