Skip to content

Commit ff25e08

Browse files
committed
Add power information menu
1 parent 1ef4920 commit ff25e08

4 files changed

Lines changed: 188 additions & 0 deletions

File tree

main/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ idf_component_register(
3636
"menu/menu_repository_client.c"
3737
"menu/menu_repository_client_project.c"
3838
"menu/menu_wifi_info.c"
39+
"menu/menu_power_information.c"
3940

4041
# Fonts
4142
"chakrapetchmedium.c"

main/menu/menu_power_information.c

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
#include "menu_power_information.h"
2+
#include <string.h>
3+
#include "bsp/input.h"
4+
#include "bsp/power.h"
5+
#include "common/display.h"
6+
#include "common/theme.h"
7+
#include "driver/temperature_sensor.h"
8+
#include "gui_style.h"
9+
#include "icons.h"
10+
#include "menu/message_dialog.h"
11+
#include "pax_gfx.h"
12+
#include "pax_matrix.h"
13+
#include "pax_text.h"
14+
#include "pax_types.h"
15+
16+
#if defined(CONFIG_BSP_TARGET_TANMATSU) || defined(CONFIG_BSP_TARGET_KONSOOL) || \
17+
defined(CONFIG_BSP_TARGET_HACKERHOTEL_2026)
18+
#define FOOTER_LEFT ((gui_element_icontext_t[]){{get_icon(ICON_ESC), "/"}, {get_icon(ICON_F1), "Back"}}), 2
19+
#define FOOTER_RIGHT NULL, 0
20+
#define TEXT_FONT pax_font_sky_mono
21+
#define TEXT_SIZE 18
22+
#elif defined(CONFIG_BSP_TARGET_MCH2022)
23+
#define FOOTER_LEFT ((gui_element_icontext_t[]){{NULL, "🅱 Back"}}), 1
24+
#define FOOTER_RIGHT NULL, 0
25+
#define TEXT_FONT pax_font_sky_mono
26+
#define TEXT_SIZE 9
27+
#else
28+
#define FOOTER_LEFT NULL, 0
29+
#define FOOTER_RIGHT NULL, 0
30+
#define TEXT_FONT pax_font_sky_mono
31+
#define TEXT_SIZE 9
32+
#endif
33+
34+
static temperature_sensor_handle_t temp_handle = NULL;
35+
36+
static void render(void) {
37+
pax_buf_t* buffer = display_get_buffer();
38+
gui_theme_t* theme = get_theme();
39+
40+
int header_height = theme->header.height + (theme->header.vertical_margin * 2);
41+
int footer_height = theme->footer.height + (theme->footer.vertical_margin * 2);
42+
pax_vec2_t position = {
43+
.x0 = theme->menu.horizontal_margin + theme->menu.horizontal_padding,
44+
.y0 = header_height + theme->menu.vertical_margin + theme->menu.vertical_padding,
45+
.x1 = pax_buf_get_width(buffer) - theme->menu.horizontal_margin - theme->menu.horizontal_padding,
46+
.y1 = pax_buf_get_height(buffer) - footer_height - theme->menu.vertical_margin - theme->menu.vertical_padding,
47+
};
48+
49+
render_base_screen_statusbar(buffer, theme, true, true, true,
50+
((gui_element_icontext_t[]){{get_icon(ICON_DEVICE_INFO), "Power information"}}), 1,
51+
FOOTER_LEFT, FOOTER_RIGHT);
52+
char text_buffer[256];
53+
int line = 0;
54+
55+
bsp_power_battery_information_t information = {0};
56+
57+
esp_err_t res = bsp_power_get_battery_information(&information);
58+
59+
if (res != ESP_OK) {
60+
snprintf(text_buffer, sizeof(text_buffer), "Unavailable (%s)", esp_err_to_name(res));
61+
pax_draw_text(buffer, theme->palette.color_foreground, TEXT_FONT, TEXT_SIZE, position.x0,
62+
position.y0 + (TEXT_SIZE + 2) * (line++), text_buffer);
63+
display_blit_buffer(buffer);
64+
return;
65+
}
66+
67+
if (information.battery_available) {
68+
snprintf(text_buffer, sizeof(text_buffer), "Battery type: %s",
69+
information.type ? information.type : "Unknown");
70+
pax_draw_text(buffer, theme->palette.color_foreground, TEXT_FONT, TEXT_SIZE, position.x0,
71+
position.y0 + (TEXT_SIZE + 2) * (line++), text_buffer);
72+
snprintf(text_buffer, sizeof(text_buffer), "Charging disabled: %s",
73+
information.charging_disabled ? "Yes" : "No");
74+
pax_draw_text(buffer, theme->palette.color_foreground, TEXT_FONT, TEXT_SIZE, position.x0,
75+
position.y0 + (TEXT_SIZE + 2) * (line++), text_buffer);
76+
snprintf(text_buffer, sizeof(text_buffer), "Battery charging: %s",
77+
information.battery_charging ? "Yes" : "No");
78+
pax_draw_text(buffer, theme->palette.color_foreground, TEXT_FONT, TEXT_SIZE, position.x0,
79+
position.y0 + (TEXT_SIZE + 2) * (line++), text_buffer);
80+
snprintf(text_buffer, sizeof(text_buffer), "Max charging current: %" PRIu16 " mA",
81+
information.maximum_charging_current);
82+
pax_draw_text(buffer, theme->palette.color_foreground, TEXT_FONT, TEXT_SIZE, position.x0,
83+
position.y0 + (TEXT_SIZE + 2) * (line++), text_buffer);
84+
snprintf(text_buffer, sizeof(text_buffer), "Current charging current: %" PRIu16 " mA",
85+
information.current_charging_current);
86+
pax_draw_text(buffer, theme->palette.color_foreground, TEXT_FONT, TEXT_SIZE, position.x0,
87+
position.y0 + (TEXT_SIZE + 2) * (line++), text_buffer);
88+
snprintf(text_buffer, sizeof(text_buffer), "Battery voltage: %" PRIu16 " mV", information.voltage);
89+
pax_draw_text(buffer, theme->palette.color_foreground, TEXT_FONT, TEXT_SIZE, position.x0,
90+
position.y0 + (TEXT_SIZE + 2) * (line++), text_buffer);
91+
snprintf(text_buffer, sizeof(text_buffer), "Charging target voltage: %" PRIu16 " mV",
92+
information.charging_target_voltage);
93+
pax_draw_text(buffer, theme->palette.color_foreground, TEXT_FONT, TEXT_SIZE, position.x0,
94+
position.y0 + (TEXT_SIZE + 2) * (line++), text_buffer);
95+
snprintf(text_buffer, sizeof(text_buffer), "Remaining charge: %.2f%%",
96+
information.remaining_percentage);
97+
pax_draw_text(buffer, theme->palette.color_foreground, TEXT_FONT, TEXT_SIZE, position.x0,
98+
position.y0 + (TEXT_SIZE + 2) * (line++), text_buffer);
99+
} else {
100+
snprintf(text_buffer, sizeof(text_buffer), "No battery detected");
101+
pax_draw_text(buffer, theme->palette.color_foreground, TEXT_FONT, TEXT_SIZE, position.x0,
102+
position.y0 + (TEXT_SIZE + 2) * (line++), text_buffer);
103+
}
104+
105+
line++;
106+
snprintf(text_buffer, sizeof(text_buffer), "Power supply detected: %s",
107+
information.power_supply_available ? "Yes" : "No");
108+
pax_draw_text(buffer, theme->palette.color_foreground, TEXT_FONT, TEXT_SIZE, position.x0,
109+
position.y0 + (TEXT_SIZE + 2) * (line++), text_buffer);
110+
111+
uint16_t system_voltage = 0;
112+
esp_err_t res_sys = bsp_power_get_system_voltage(&system_voltage);
113+
if (res_sys == ESP_OK) {
114+
snprintf(text_buffer, sizeof(text_buffer), "System voltage: %" PRIu16 " mV", system_voltage);
115+
pax_draw_text(buffer, theme->palette.color_foreground, TEXT_FONT, TEXT_SIZE, position.x0,
116+
position.y0 + (TEXT_SIZE + 2) * (line++), text_buffer);
117+
}
118+
119+
uint16_t input_voltage = 0;
120+
esp_err_t res_input = bsp_power_get_input_voltage(&input_voltage);
121+
if (res_input == ESP_OK) {
122+
snprintf(text_buffer, sizeof(text_buffer), "Input voltage: %" PRIu16 " mV", input_voltage);
123+
pax_draw_text(buffer, theme->palette.color_foreground, TEXT_FONT, TEXT_SIZE, position.x0,
124+
position.y0 + (TEXT_SIZE + 2) * (line++), text_buffer);
125+
}
126+
127+
res = temperature_sensor_enable(temp_handle);
128+
if (res == ESP_OK) {
129+
float tsens_out;
130+
res = temperature_sensor_get_celsius(temp_handle, &tsens_out);
131+
if (res == ESP_OK) {
132+
line++;
133+
snprintf(text_buffer, sizeof(text_buffer), "SoC temperature: ~%.2f *C", tsens_out);
134+
pax_draw_text(buffer, theme->palette.color_foreground, TEXT_FONT, TEXT_SIZE, position.x0,
135+
position.y0 + (TEXT_SIZE + 2) * (line++), text_buffer);
136+
};
137+
temperature_sensor_disable(temp_handle);
138+
}
139+
140+
display_blit_buffer(buffer);
141+
}
142+
143+
void menu_power_information(void) {
144+
QueueHandle_t input_event_queue = NULL;
145+
ESP_ERROR_CHECK(bsp_input_get_queue(&input_event_queue));
146+
147+
if (temp_handle == NULL) {
148+
temperature_sensor_config_t temp_sensor_config = TEMPERATURE_SENSOR_CONFIG_DEFAULT(20, 50);
149+
ESP_ERROR_CHECK(temperature_sensor_install(&temp_sensor_config, &temp_handle));
150+
}
151+
152+
render();
153+
while (1) {
154+
bsp_input_event_t event;
155+
if (xQueueReceive(input_event_queue, &event, pdMS_TO_TICKS(1000)) == pdTRUE) {
156+
switch (event.type) {
157+
case INPUT_EVENT_TYPE_NAVIGATION: {
158+
if (event.args_navigation.state) {
159+
switch (event.args_navigation.key) {
160+
case BSP_INPUT_NAVIGATION_KEY_ESC:
161+
case BSP_INPUT_NAVIGATION_KEY_F1:
162+
case BSP_INPUT_NAVIGATION_KEY_GAMEPAD_B:
163+
return;
164+
default:
165+
break;
166+
}
167+
}
168+
break;
169+
}
170+
default:
171+
break;
172+
}
173+
} else {
174+
render();
175+
}
176+
}
177+
}

main/menu/menu_power_information.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#pragma once
2+
3+
void menu_power_information(void);

main/menu/settings.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "gui_style.h"
1010
#include "icons.h"
1111
#include "menu/about.h"
12+
#include "menu/menu_power_information.h"
1213
#include "menu/message_dialog.h"
1314
#include "menu/wifi.h"
1415
#include "pax_gfx.h"
@@ -29,6 +30,7 @@ typedef enum {
2930
ACTION_ABOUT,
3031
ACTION_LAST,
3132
ACTION_RADIO_UPDATE,
33+
ACTION_POWER_INFORMATION,
3234
} menu_home_action_t;
3335

3436
static void execute_action(pax_buf_t* fb, menu_home_action_t action, gui_theme_t* theme) {
@@ -51,6 +53,9 @@ static void execute_action(pax_buf_t* fb, menu_home_action_t action, gui_theme_t
5153
case ACTION_RADIO_UPDATE:
5254
radio_update(fb, theme, "/sd/firmware/radio/esp-hosted.zz", true, 1093760);
5355
break;
56+
case ACTION_POWER_INFORMATION:
57+
menu_power_information();
58+
break;
5459
default:
5560
break;
5661
}
@@ -79,6 +84,8 @@ void menu_settings(pax_buf_t* buffer, gui_theme_t* theme) {
7984
menu_insert_item_icon(&menu, "Firmware update", NULL, (void*)ACTION_FIRMWARE_UPDATE, -1,
8085
get_icon(ICON_SYSTEM_UPDATE));
8186
menu_insert_item_icon(&menu, "Device information", NULL, (void*)ACTION_DEVICE_INFO, -1, get_icon(ICON_DEVICE_INFO));
87+
menu_insert_item_icon(&menu, "Power information", NULL, (void*)ACTION_POWER_INFORMATION, -1,
88+
get_icon(ICON_BATTERY_UNKNOWN));
8289
menu_insert_item_icon(&menu, "About", NULL, (void*)ACTION_ABOUT, -1, get_icon(ICON_INFO));
8390
/*#if defined(CONFIG_BSP_TARGET_TANMATSU) || defined(CONFIG_BSP_TARGET_KONSOOL) || \
8491
defined(CONFIG_BSP_TARGET_HACKERHOTEL_2026)

0 commit comments

Comments
 (0)