src.nth.io/

summaryrefslogtreecommitdiff
path: root/main/state_client.h
diff options
context:
space:
mode:
authorLuke Hoersten <[email protected]>2026-06-13 23:01:23 -0500
committerLuke Hoersten <[email protected]>2026-06-13 23:01:23 -0500
commit1d6cbb222ced226fcb482c0b19130774d181c8f8 (patch)
tree768d964dc962e111c8c596e10e2da95748bc738a /main/state_client.h
parent57c93fd2978ed5b5e64f4620803b7a2cd7767ed2 (diff)
M7: touch + outbound /state POST to Scrypted
state_client.{h,c}: - Worker task drains a depth-1 queue (xQueueOverwrite gives the replace-on-full semantics from the spec — in-flight POST is never cancelled; the next queued entry is overwritten by newer state). - esp_http_client POST to <scrypted>/state with Content-Type application/ json, User-Agent ScryptedViewport/<version>, Connection: close, 1s timeout. Body: {"viewport":"<name>","state":"wake"|"sleep"}. - Any non-2xx or transport error increments state_post_failures and is otherwise ignored. Silently drops if no Scrypted URL is configured. touch.{h,c}: - FT5426 capacitive touch on the shared I2C bus at 0x38. - 30ms polling task; tracks down/up transitions, detects taps as down-then-up within 500ms with a 150ms debounce. - On tap, toggles wake/sleep via state_machine_set_local(), which drives the local transition AND fires state_client_post() at Scrypted. state_machine adds state_machine_set_local(): runs the same transition as state_machine_set() then enqueues an outbound POST. Idle-timer expiry now uses this path so Scrypted sees idle-driven sleeps too (the spec's "tighten the race with /frame 409" path stays in place as the fallback). display.h exposes display_i2c_bus(); touch.c uses it instead of re-initializing the same I2C port. app_main starts state_client right after the state machine and starts touch after display init (touch is skipped if display isn't up since they share the bus). CMakeLists.txt: add esp_http_client to REQUIRES. Build clean against ESP-IDF 5.4 (binary ~860 KB; jumped ~210 KB from M6 because esp_http_client + cJSON path pulls in tcp_transport, mbedtls, http_parser). TESTING.md M7: flask-based test receiver, tap dispatch verification, failure-path check (kill receiver, confirm counter increments), queue-coalescing behavior, no-POST-on-Scrypted-initiated, no-POST- when-unconfigured.
Diffstat (limited to 'main/state_client.h')
-rw-r--r--main/state_client.h18
1 files changed, 18 insertions, 0 deletions
diff --git a/main/state_client.h b/main/state_client.h
new file mode 100644
index 0000000..bf7e1c6
--- /dev/null
+++ b/main/state_client.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include "esp_err.h"
+#include "viewport_state.h"
+
+esp_err_t state_client_init(void);
+
+// Queue a state-change POST to <scrypted>/state.
+//
+// Concurrency model (per spec):
+// - At most one HTTP POST in flight; a dedicated worker task drives it.
+// - Depth-1 queue. If a POST is already queued, replace it with the newer
+// one — the in-flight POST is never cancelled.
+// - Fire-and-forget from the caller's perspective. Local state change
+// proceeds immediately regardless of POST outcome.
+//
+// Silently dropped if the device has no Scrypted URL configured.
+void state_client_post(viewport_run_state_t state);