Add persistent OLED UI settings and recovery

This commit is contained in:
2026-08-29 20:18:08 +02:00
parent 16c0c02389
commit 276559536b
14 changed files with 538 additions and 38 deletions
+202
View File
@@ -0,0 +1,202 @@
/* SPDX-License-Identifier: GPL-3.0-only */
/* UART0 administration commands for local UI aging settings. */
#include "local_ui_console.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "esp_console.h"
#include "local_display.h"
#include "local_status_ui.h"
#include "local_ui_config.h"
static void print_usage(void)
{
printf("Usage:\n");
printf(" display status\n");
printf(" display set <dim-seconds|off-seconds> <0..%u>\n",
LOCAL_UI_CONFIG_MAX_TIMEOUT_SECONDS);
printf(" display save|load|defaults|reset\n");
printf("Zero disables the selected inactivity transition.\n");
}
static void print_config(const local_ui_config_t *config)
{
printf("Local UI configuration v%u: dim-seconds=%u off-seconds=%u\n",
(unsigned int)config->version,
(unsigned int)config->dim_timeout_seconds,
(unsigned int)config->off_timeout_seconds);
}
static bool parse_timeout(const char *text, uint32_t *value)
{
if (text == NULL || *text == '\0') {
return false;
}
for (const char *character = text; *character != '\0'; ++character) {
if (*character < '0' || *character > '9') {
return false;
}
}
errno = 0;
char *end = NULL;
unsigned long parsed = strtoul(text, &end, 10);
if (errno != 0 || end == text || *end != '\0' ||
parsed > LOCAL_UI_CONFIG_MAX_TIMEOUT_SECONDS) {
return false;
}
*value = (uint32_t)parsed;
return true;
}
static int show_status(void)
{
local_ui_config_t config;
esp_err_t error = local_status_ui_get_config(&config);
if (error != ESP_OK) {
printf("Could not read local UI configuration: %s\n", esp_err_to_name(error));
return 1;
}
print_config(&config);
local_display_snapshot_t display;
error = local_display_get_snapshot(&display);
if (error != ESP_OK) {
printf("Display service unavailable: %s\n", esp_err_to_name(error));
return 1;
}
printf("OLED: bus=%s initialized=%s address=0x%02x contrast=%u last-error=%s\n",
display.bus_ready ? "ready" : "unavailable",
display.initialized ? "yes" : "no",
display.address_7bit,
(unsigned int)display.contrast,
esp_err_to_name(display.last_error));
return 0;
}
static int apply_parameter(const char *parameter, const char *text)
{
uint32_t value;
if (!parse_timeout(text, &value)) {
printf("Timeout must be 0..%u seconds.\n",
LOCAL_UI_CONFIG_MAX_TIMEOUT_SECONDS);
return 1;
}
local_ui_config_t config;
esp_err_t error = local_status_ui_get_config(&config);
if (error != ESP_OK) {
printf("Could not read local UI configuration: %s\n", esp_err_to_name(error));
return 1;
}
if (strcmp(parameter, "dim-seconds") == 0) {
config.dim_timeout_seconds = value;
} else if (strcmp(parameter, "off-seconds") == 0) {
config.off_timeout_seconds = value;
} else {
printf("Unknown display parameter '%s'.\n", parameter);
print_usage();
return 1;
}
error = local_status_ui_apply_config(&config);
if (error != ESP_OK) {
printf("Invalid display configuration: %s. When both timeouts are enabled, off must be later than dim.\n",
esp_err_to_name(error));
return 1;
}
print_config(&config);
printf("Applied in RAM; run 'display save' to persist it.\n");
return 0;
}
static int command_display(int argc, char **argv)
{
if (argc == 1 || (argc == 2 && strcmp(argv[1], "status") == 0)) {
return show_status();
}
if (argc == 4 && strcmp(argv[1], "set") == 0) {
return apply_parameter(argv[2], argv[3]);
}
if (argc == 2 && strcmp(argv[1], "save") == 0) {
local_ui_config_t config;
esp_err_t error = local_status_ui_get_config(&config);
if (error == ESP_OK) {
error = local_ui_config_save(&config);
}
if (error != ESP_OK) {
printf("Could not save display configuration: %s\n", esp_err_to_name(error));
return 1;
}
printf("Display configuration saved to NVS.\n");
return 0;
}
if (argc == 2 && strcmp(argv[1], "load") == 0) {
local_ui_config_t config;
bool used_stored_config;
esp_err_t error = local_ui_config_load(&config, &used_stored_config);
if (error == ESP_OK) {
error = local_status_ui_apply_config(&config);
}
if (error != ESP_OK) {
printf("Could not load display configuration: %s\n", esp_err_to_name(error));
return 1;
}
printf("Loaded %s display configuration.\n",
used_stored_config ? "stored" : "default");
print_config(&config);
return 0;
}
if (argc == 2 && strcmp(argv[1], "defaults") == 0) {
local_ui_config_t config;
local_ui_config_defaults(&config);
esp_err_t error = local_status_ui_apply_config(&config);
if (error != ESP_OK) {
printf("Could not apply display defaults: %s\n", esp_err_to_name(error));
return 1;
}
printf("Display defaults applied in RAM; run 'display save' to persist them.\n");
print_config(&config);
return 0;
}
if (argc == 2 && strcmp(argv[1], "reset") == 0) {
local_ui_config_t previous;
local_ui_config_t defaults;
local_ui_config_defaults(&defaults);
esp_err_t error = local_status_ui_get_config(&previous);
if (error == ESP_OK) {
error = local_status_ui_apply_config(&defaults);
}
if (error == ESP_OK) {
error = local_ui_config_reset_storage();
if (error != ESP_OK) {
(void)local_status_ui_apply_config(&previous);
}
}
if (error != ESP_OK) {
printf("Could not reset display configuration: %s\n", esp_err_to_name(error));
return 1;
}
printf("Display defaults applied and saved to NVS.\n");
print_config(&defaults);
return 0;
}
print_usage();
return 1;
}
esp_err_t local_ui_console_register_commands(void)
{
const esp_console_cmd_t command = {
.command = "display",
.help = "Configure persistent local OLED aging timeouts; use 'display' for status",
.hint = NULL,
.func = &command_display,
.argtable = NULL,
};
return esp_console_cmd_register(&command);
}