src.nth.io/

summaryrefslogtreecommitdiff
path: root/scrypted/README.md
AgeCommit message (Collapse)AuthorFilesLines
4 daysdocs: sync README + TESTING + scrypted README with v1.4.0 realityLuke Hoersten1-16/+16
Drift accumulated across the review-fix, mDNS-discovery, and tooling work: - Discovery: the design-era "use a Node mDNS library" flow is replaced with what shipped — the sandbox has no such libraries; the script does a dependency-free legacy-unicast dgram browse (no :5353 bind), host dropdowns, blank-name inheritance, and auto-heal on register failure (matched by the new mac TXT record) instead of periodic re-browsing. - /state example: add mac, ota_state, panel dims, tear_guard_engaged, temp_c, and the stream stats object; correct `configured` semantics (scrypted URL only) and the never-null MAC-derived name in /config. - /config: document the 54-char name cap (mDNS label limit). - scrypted/README: add-device + settings tables gain the discovered-host dropdown, Wake triggers on create, and the canonical "Viewport name" rename field (the Scrypted pencil doesn't propagate — by design); trigger-scoped subscriptions; device-wake immediate-204 semantics; idle=0 no longer force-slept by the safety timer; "manual IP" dropped from limitations; discovery section reframed with the diagnostic.ts probe and bridge-networking caveat. - Source map: dedupe the doubled touch.{h,c} row, add stream_server / ota / chip_temp rows, fix nvs_config + endpoint-count drift. - Build/TESTING: point iteration at `make ota` (USB stays for first flash); TXT expectations include mac; DHCP-renumber failure mode now documents the verified auto-heal path.
2026-06-30docs: bring scrypted/README.md in line with current streaming behaviorLuke Hoersten1-16/+22
The v1 README still described the old snapshot-poll path. Update to match the shipped script: live MJPEG over a TCP data socket (port 81, ~24fps) via ffmpeg, not ~1fps snapshots. Fixes: - intro + v1 limitations: MJPEG streaming is done, not a v2 "POST /stream" TODO - Settings: replace the removed "Frame push interval" with the real Display fields (JPEG quality, Max Scrypted-side buffer, Stream prebuffer); add the Actions group; correct brightness default (100, was 80) - Wake triggers default is person+doorbell (was "all three"), doorbell only for doorbell-capable cameras - drop the stale snapshot-source / snapshot-interval / POST /frame 409 mentions - host field: no mDNS auto-resolve (was contradictory) - smoke test: Loading -> live video, not "snapshots flowing"
2026-06-30docs: document required Medium-stream prebuffer for fast wakeLuke Hoersten1-0/+11
Wake-to-live is ~0.7s only when the streamed substream keeps a rebroadcast prebuffer. Add a "Fast wake — camera prebuffer (required)" section to scrypted/README.md: enable Prebuffer on the STREAM: MEDIUM tab (default only prebuffers High), keep duration >= the detected keyframe interval (~5s), leave the viewport's Stream prebuffer (ms) at 6000, and how to verify via the log.
2026-06-14scrypted: per-viewport frame interval + trigger picker + live status; drop ↵Luke Hoersten1-16/+24
mDNS auto-resolve - Move "frame push interval" from the parent's global setting to a per-viewport child setting (different cameras want different rates). Clamped to ≥33 ms (~30 fps max). Default still 1000 ms (1 fps). - New "Wake triggers" multi-select on each viewport: doorbell, motion, person. Default = all three. Clear all of them for tap-only mode. handleCameraEvent now gates by this set; clearing it cleanly turns a viewport into a tap-only display with no auto-wake. - Add a "Status (live)" group at the bottom of each viewport's Settings page that fetches /state + /config in parallel (1.5 s timeout) and surfaces every field — name, mac, ip, awake/asleep, configured, uptime, frame + error counters, resolution, free heap/psram, firmware version, registered scrypted URL. Offline devices say so cleanly. - Drop mDNS auto-resolve: no more lookupMdns / refreshHostFromMdns, no per-viewport "auto-resolve via mDNS" toggle, no `dns` require. The host field is just an operator-set string now. The README documents the manual lookup commands (dns-sd, avahi-resolve) so finding the device IP stays a one-liner. - Parent's Settings page is now informational-only (viewport count + callback base URL); per-viewport tuning lives on each child.
2026-06-14scrypted/README: drop stale BOOT-factory-reset + IP-screen refsLuke Hoersten1-2/+2
2026-06-14scrypted/script: auto-populate viewport host via mDNSLuke Hoersten1-1/+12
The host field is now optional in "+ Add Device". The script tries dns.promises.lookup("viewport-<name>.local") via the OS resolver (Bonjour on macOS, nss-mdns on Linux, host networking on Docker) on: - every registerViewport call (plugin start, child instantiation, settings change, periodic 5-min refresh), - right after createDevice so a fresh viewport's host field is populated by the time the operator opens its settings page. On a successful lookup that differs from the stored host, the resolved IP is written back to the child's storage. POST /config and POST /frame then use the resolved value. Falls back gracefully to the operator-entered host (with a one-line warning if both are empty). A per-viewport "Auto-resolve via mDNS" toggle (default on) opts out — useful for cross-VLAN setups or hosts where mDNS doesn't reach. scrypted/README.md adds a "How mDNS auto-resolve works" section covering the per-OS resolver requirements and the Docker host- networking note.
2026-06-14Path B: per-viewport Scrypted devices with UI-driven settingsLuke Hoersten1-54/+67
Convert the Scripts-plugin script from a hardcoded BINDINGS constant into a DeviceProvider + DeviceCreator + HttpRequestHandler. Each viewport is now a child Scrypted device under the parent script with its own Settings page; operators add, edit, and delete viewports entirely through the Scrypted UI. Parent (ScryptedViewportProvider): - DeviceProvider: getDevice(nativeId) instantiates a Viewport, attaches its camera event listener, and posts /config. releaseDevice tears down stream + listener + child storage entry. - DeviceCreator: "+ Add Device" on the parent's page shows a small form (name / host / camera picker filtered to Camera interfaces / orientation choice). createDevice() pre-populates the child's storage via deviceManager.getDeviceStorage(nativeId) and registers it under the parent. - Tracks known child nativeIds in its own storage as a JSON array so it can eagerly instantiate every child on plugin start (each registration + camera subscription happens at load time, not lazily). - 5-min re-register loop catches devices that rebooted or got new DHCP leases. - HttpRequestHandler routes POST <base>/state on the parent's endpoint; body {viewport, state} is matched against child names. Honors the spec race rules: every callback cancels any prior stream + safety timer for that viewport before applying the new state, and a /frame 409 stops the stream without echoing sleep back. - Global tuning (frame_interval_ms) lives on the parent's Settings. Child (Viewport): - Settings: host (string), camera (type=device with deviceFilter for the Camera interface — the UX win), orientation (choices), idle timeout, brightness. All persisted via this.storage. - putSetting fires onBindingChanged() on the parent so re-register + re-subscribe happen immediately when any field changes. scrypted/README.md rewritten for the UI-driven flow — install + add device + edit + remove + global tuning + smoke test — no more "edit BINDINGS and re-save." scrypted/package.json + tsconfig.json: optional `npm install` so editors can resolve @scrypted/sdk types. Nothing here ships — install remains "paste into Scripts plugin." node_modules ignored.
2026-06-14M9-precursor: v1 Scrypted Script (snapshot-rate end-to-end)Luke Hoersten1-0/+83
scrypted/scrypted-viewport.ts — single-file TypeScript script for Scrypted's Scripts plugin. Binds N viewports to N Scrypted cameras and implements the full Scrypted side of the protocol: Outbound (Scrypted -> device): - POST /config on script load + every 5 min (re-syncs after device reboot or DHCP renumber). - POST /state {wake} when a bound camera fires an event or when the device's own POST /state {wake} arrives (operator tap). - POST /frame at FRAME_INTERVAL_MS (1 fps default) via camera.takePicture({picture:{width,height}}). - POST /state {sleep} when the Scrypted-side per-stream timer expires. Inbound (device -> Scrypted POST <base>/state): - {state:wake} -> startStream() (cancels pending sleep timer + any prior interval, then begins pushing frames). - {state:sleep} -> stopStream(sendSleep=false) (no echo back). - Unknown viewport -> 404. Bad body -> 400. Race rules from the spec are honored: - Every callback cancels prior pending state for that viewport before applying the new state (cancelPendingSleep semantics). - startStream / stopStream are idempotent — re-entering is safe. - On /frame returning 409, stream stops immediately without echoing /state {sleep} back (the device already slept). Configuration is a single BINDINGS array at the top of the file — edit name/host/cameraId/orientation per viewport and save in the Scrypted UI. No package install. Tuning constants (IDLE_TIMEOUT_MS, FRAME_INTERVAL_MS, REREGISTER_INTERVAL_MS, etc.) are right above the class. scrypted/README.md walks through Scripts-plugin install, the BINDINGS schema, what each constant controls, an event-by-event description of the script's behavior, the v1 limitations (snapshot-rate, manual IP, camera must respect picture dims), and an end-to-end smoke test. Top-level README's Scrypted Integration section now links the script file and the install README directly.