src.nth.io/

summaryrefslogtreecommitdiff
path: root/main/app_main.c
diff options
context:
space:
mode:
authorLuke Hoersten <[email protected]>2026-06-13 22:42:14 -0500
committerLuke Hoersten <[email protected]>2026-06-13 22:42:14 -0500
commite7feac61e5ea275f303574fedd942ebed8fc8e73 (patch)
tree26bbb23c8faf16294325b27c254df6dd6fbdf1e8 /main/app_main.c
parente91ed43dee0f2715362fed9f52fa684e655de7be (diff)
M4: NVS-backed /config with partial updates + validation
nvs_config.{h,c} — persist the runtime config (viewport, scrypted, idle_timeout_ms, orientation, brightness) under a single NVS namespace. nvs_config_load() applies persisted values over the in-RAM defaults on boot and flips state from UNCONFIGURED to ASLEEP once both name and Scrypted URL are present. nvs_config_save() commits the whole record atomically. http_api.c — add GET /config and POST /config: - GET serializes viewport_state to the spec's JSON shape, with null for unset string fields and defaults filled in for the rest. - POST is partial: each field is optional; only present fields are validated and applied. Validation runs on a staged copy and errors short-circuit with 400 + reason before any state mutation, so a rejected request leaves the device untouched. - Validation rules: viewport non-empty <64 chars; scrypted starts with http:// and <256 chars; idle_timeout_ms 0 or >=5000; orientation in {portrait,landscape}; brightness 0..100. - Side-effects fire after the lock + save: brightness change pushes PWM to the panel MCU; viewport/orientation change reapplies mDNS hostname + TXT. - 204 on success; 400 with a single-line reason on validation error. app_main calls nvs_config_load() right after viewport_state_init(), so mdns_service_start() and display_init() see the persisted hostname, orientation, and brightness from the first packet/PWM. Build clean against ESP-IDF 5.4 (binary ~620 KB). TESTING.md M3 now documents the Hosyond jumper wiring (5V/GND/SDA=GPIO7/ SCL=GPIO8 from board to panel header; DSI FPC carries only the high- speed lanes). M4 entry expands the validation matrix and side-effects to verify.
Diffstat (limited to 'main/app_main.c')
-rw-r--r--main/app_main.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/main/app_main.c b/main/app_main.c
index c3c12c0..316f702 100644
--- a/main/app_main.c
+++ b/main/app_main.c
@@ -2,6 +2,7 @@
#include "http_api.h"
#include "mdns_service.h"
#include "net_eth.h"
+#include "nvs_config.h"
#include "viewport_state.h"
#include "esp_event.h"
@@ -18,6 +19,7 @@ void app_main(void)
ESP_ERROR_CHECK(esp_event_loop_create_default());
viewport_state_init();
+ nvs_config_load(); // apply persisted config over defaults (best-effort)
ESP_LOGI(TAG, "Scrypted Viewport boot (v%s)", VIEWPORT_VERSION);
ESP_ERROR_CHECK(net_eth_init());
@@ -30,8 +32,8 @@ void app_main(void)
ESP_ERROR_CHECK(mdns_service_start());
ESP_ERROR_CHECK(http_api_start());
- // Display is best-effort during bring-up: a missing/miswired panel must
- // not kill networking + /state. M3 acceptance: show a test pattern.
+ // Display is best-effort — a missing/miswired panel must not kill
+ // networking + /state. M3 acceptance: show a test pattern.
if (display_init() == ESP_OK) {
display_test_pattern();
ESP_LOGI(TAG, "display up — test pattern on screen");
@@ -39,7 +41,6 @@ void app_main(void)
ESP_LOGW(TAG, "display init failed — continuing without panel");
}
- // TODO M4: /config persistence (NVS) + GET /config + POST /config
// TODO M5: /frame JPEG decode -> framebuffer
// TODO M6: POST /state + idle timer
// TODO M7: Capacitive touch -> outbound /state POST