Changes in this release:
- 6668fe6 uboot: fix flashing autoupdate-full.bin from a card
- 5ce4522 sysupgrade: fix segfault when flashing data partition after rootfs in full upgrade The full upgrade loop flashes partitions sequentially with dd. After rootfs (mtd4) is overwritten, the on-disk dd binary is corrupted, causing a segfault when the loop reaches the data partition (mtd5). Create tmpfs symlinks for dd and flash_eraseall after cloning busybox to tmpfs, and prepend the workdir to PATH so the loop uses tmpfs binaries that survive the rootfs being overwritten. Also add dd to the global bbapplets list for the stage2 exec path. Signed-off-by: Paul Philippov paul@themactep.com
- cc178f6 AGENTS: add strict rule against inventing git hashes Never type hashes by hand. Always obtain the full hash from the actual git repo, verify it with git cat-file -t, and use update_packages.py for package version changes. Includes the recovery procedure for when a bogus hash is already committed. Signed-off-by: Paul Philippov paul@themactep.com
- de7b305 prudynt-t: update package hash to 73ae2b8 (DMA fallback fix) Signed-off-by: Paul Philippov paul@themactep.com
- 6f88c84 prudynt-t: fix mangled package hash The previous hash 84edac095beb10c4ae0982ed98c1b85b40cd3eae was a typo of 84edac016f21f3419591407eccababeeb7812861. The mangled hash was never a real commit and can't be resolved by update_packages.py. Signed-off-by: Paul Philippov paul@themactep.com
- b74ec29 package/buildscope: update to 6ce53f6 Update buildscope from 902e0af to 6ce53f6 Hash change: 902e0af3ad90b208d49b1c74f5c1f9cb938b68da -> 6ce53f6a4a687ae0ae228b9e5691b449a9a2d66f Changelog: 6ce53f6: Point the fleet proxy at the thingino Cloudflare account
- 21ab390 timps: install the board day/night hardware scripts (daynight/ircut/light) timps runs its own day/night detection and drives the hardware by exec'ing a configurable switch_cmd (default "daynight"). On a timps image that command did not exist: /usr/sbin/{daynight,ircut,light} and S06ircut are installed only by thingino-daynightd, which is selected by exactly one Kconfig symbol - BR2_PACKAGE_THINGINO_STREAMER_PRUDYNT. A camera built with the timps streamer therefore never got any of them. Live incident (Garage, T31/SC4336P): detection worked correctly ("[DAYNIGHT] switching to night (total_gain 3557)") but every switch_cmd failed with rc=127, so the IR-cut filter was never removed and the IR illuminator never lit. The ISP kept ramping total_gain (3500 -> 22000+) trying to expose a scene it could not see through the IR-cut filter, and the image went purple/IR-tinted. Installing only 'daynight' would not have been enough: it guards every hardware step with command_present, so without ircut/light it would have called 'color' alone - an ISP-only flip, i.e. the same purple image, just silently. ircut/light are installed unconditionally because timps's own WebUI bridge (json-imp.cgi) shells out to them for the control-bar IR-cut and IR-LED buttons regardless of who does the detection. Installed straight from thingino-daynightd's PKGDIR (same pattern TIMPS_INSTALL_SEND2 already uses for prudynt-t's send2* tools) so there is a single source of truth and no copy to drift. Also fix TIMPS_DISABLE_DAYNIGHTD, which still removed S97daynightd after thingino-daynightd 2.0.0 renamed it to S10daynightd - it had been a no-op, leaving the daemon free to autostart and double-switch against timps. Match by glob, and cover S07dusk2dawn for the same reason. S06ircut is deliberately kept: it is a one-shot boot-time IR-cut latch, not a daemon. Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com
- aa82ae0 raptor, raptor-hal: bump to current heads raptor dd05912104451e4bebbbf239e636905c8537980a: the T41 refmode keyframe drop fix (silent publish_ref rejection starved every new RTSP client once the encoder used a third buffer), rmr segment rotation aligned to the wall boundary (the pre-boundary IDR request landed a full GOP late on long-GOP HEVC), the day/night campaign for Gen1 sensors (IR-off ambient probe, EV dip, photo trigger dark boot in seconds, forced modes always drive hardware), the rsd send queue extracted and unit-tested, and a ric audit pass (config file clamped like the ctrl API, SIGFPE on poll_interval_ms=0 fixed, ctrl surface validates and rejects unknown commands). raptor-hal d473d8a85f026a0c493fdcee02b7952730cc6d8f: real AE histogram luma and exposure-time fallback on Gen1 SoCs, the foundation for the day/night work.
- c853870 configs: fix leakage
- d5b5261 open-isp: integrate the complete open media stack (#1368) * open-isp: integrate the complete open media stack Extend open-tx-isp to its current T23, T31, T40, and T41 targets, with OpenIMP on its supported T31 and T40 platforms. Pin open-tx-isp after its native canonical-module and T40 SDK sensor-registry integration. Add an opt-in aggregate profile that selects the neo system and audio libraries, while making the proprietary providers mutually exclusive. Order the replacement libraries before streamer consumers and preserve them during target finalization. Document the current support matrix and limitations. Camera profiles remain unchanged; local fragments can opt individual builds into the complete open stack. Signed-off-by: Matt Davis matteius@gmail.com * PR feedback * open-isp: add provider choice and update open stack Signed-off-by: Matt Davis matteius@gmail.com * raptor: gate V4L2 OpenIMP backend with provider Signed-off-by: Matt Davis matteius@gmail.com * open-isp: advance source pins for mainline T31 fixes Signed-off-by: Matt Davis matteius@gmail.com * openimp: make symbol coverage locale-stable Signed-off-by: Matt Davis matteius@gmail.com --------- Signed-off-by: Matt Davis matteius@gmail.com
- f36b26c webui: remove extras storage from system usage page The extras partition no longer exists. Remove it from the UI (progress bar, legend, summary line), the JS rendering logic, the dead CSS class, and the CGI so it stops reading /opt. Also add shellcheck suppressions for pre-existing warnings: SC1091 (auth.sh not available at lint time), SC2329 (unused json_error kept for API completeness), and SC2086 (intentional word splitting for df output parsing). Signed-off-by: Paul Philippov paul@themactep.com
- 7a7229b isp-inspector: show EV as log2 stops instead of raw register value The EV stat card and chart previously displayed ev.value, a raw ISP register integer (e.g. 524288) that users could not interpret. - EV stat card now shows ev.log2 (photographic EV in stops, e.g. 12.3 EV) - EV chart plots dual y-axes: EV in log2 stops (left) + exposure time in microseconds (right, dashed) - statCard() now accepts a 5th tooltip arg, rendering a ? help icon with a native browser title tooltip on hover - All 11 stat card tooltips rewritten with plain-language explanations of what each parameter is, what affects it, and what abnormal values mean - Chart card titles also have hover tooltips - LLM prompt sends ev.log2 for more useful AI analysis Signed-off-by: Paul Philippov paul@themactep.com
- 0fed06a AGENTS.md: document that cameras use BusyBox sh, not bash Signed-off-by: Paul Philippov paul@themactep.com
- c3de103 package/prudynt-t: move prudynt-specific webui files from thingino-webui Move all prudynt-streamer-specific CGIs, streamer config pages, audio settings page, and supporting JavaScript from thingino-webui into the prudynt-t package, wired through the WebUI plugin manifest system. Files moved (16 CGIs, 6 HTML, 3 JS): - CGIs: json-prudynt*, restart-prudynt, json-imaging, json-osd-sei, ch0/ch1/dl0/dl1 snapshots, mjpeg streams, events, preview - HTML: streamer-{main,substream,image,osd,sensor}, config-audio - JS: streamer-config, audio, sei-osd Added prudynt.webui.json manifest that populates the ddStreamer dropdown, adds Audio to Settings, and declares all pages/CGIs. navigation.js: emptied hardcoded ddStreamer items, removed Audio from Settings, removed attachPrudyntHandlers — all now driven by the plugin manifest at build time via assemble_plugins.py. json-imp.cgi kept in thingino-webui (shared day/night control with raptor fallback). Signed-off-by: Paul Philippov paul@themactep.com
- 09c2d0c isp-inspector: add T10/T20 field name fallbacks in CGI parsers The T20 isp_info proc file uses different field names than T31+: - No SENSOR Max Integration Time field - EV: ISP total gain / ISP exposure log2 id (not ISP EV value / log2) - WB: ISP WB rg / ISP WB bg / ISP WB Temperature (not ISP WB weighted rgain / bgain / color temperature) Add fallback lookups so EV and WB cards show data on T20 cameras. Signed-off-by: Paul Philippov paul@themactep.com isp-inspector: hide max integration time on T20 when absent T20 isp_info has no SENSOR Max Integration Time field. Show just '1405 lines' instead of '1405 / 0 lines' when the max value is missing or zero. Signed-off-by: Paul Philippov paul@themactep.com isp-inspector: use soc -f for accurate platform detection T20 was showing as T10 because both use isp_info proc file. Use 'soc -f' command (already present on all Thingino cameras) to report the actual SoC model: t20, t31, t40, etc. Signed-off-by: Paul Philippov paul@themactep.com isp-inspector: show Antiflicker as '60 Hz' not 'AF:60' Map raw T20 antiflicker frequencies (50, 60) to human-readable '50 Hz' / '60 Hz' instead of the cryptic 'AF:' prefix. Signed-off-by: Paul Philippov paul@themactep.com isp-inspector: restore Antiflicker label in header bar Show 'Antiflicker: 60 Hz' instead of bare '60 Hz'. Signed-off-by: Paul Philippov paul@themactep.com isp-inspector: move Day/Night mode badge to header bar Mode is now a compact badge next to resolution instead of a full stat card. Shows 'Night', 'Day', 'Day +Custom', etc. Signed-off-by: Paul Philippov paul@themactep.com isp-inspector: drop badge class from header mode span Plain text-muted, matching the rest of the header line. Signed-off-by: Paul Philippov paul@themactep.com isp-inspector: show 'Mode: Night', split image values for reflow Mode now reads 'Mode: Night' instead of bare 'Night'. Image tuning values (Saturation, Sharpness, Contrast, Brightness) are now four separate dot-separated spans so they reflow independently on narrow screens. Signed-off-by: Paul Philippov paul@themactep.com isp-inspector: add dot separator between resolution and mode Signed-off-by: Paul Philippov paul@themactep.com
- 845f826 raptor: let daynightd replace RIC as the day/night engine Invert the exclusion from 5c29bf3: daynightd is selectable on any image again, and selecting it disables RIC instead (both would drive the same IR-CUT and LED pins and ship the same wrapper scripts). The raptor wrappers install only with RIC, so daynightd images get its scripts; json-imp.cgi prefers daynightd when present, so the web UI drives whichever engine the image ships.
- 757a432 prudynt-t: bump to 84edac0 (min 2 DMA buffers per channel) Fixes frame drops on low-RAM devices where the 15% RAM budget was capping framesource buffer pools to 1. Queue count: 1 causes ch0_pre_dequeue_drop counter to climb. Signed-off-by: Paul Philippov paul@themactep.com
- 7d49aad daynightd: exclude on raptor images Raptor's ric owns day/night and the same wrapper script names, so daynightd on a raptor image means two daemons driving the same GPIO pins plus a rootfs file collision. Prudynt still selects daynightd; the streamer choice already keeps raptor out of those configs.
- 7c2831a raptor: daynight, ircut and light wrappers for the web UI On raptor images the daynightd package is absent, so the web UI's day/night, ircut and light calls went nowhere. These wrappers keep the daynightd era CLI and route it through raptorctl: ric owns the filter, the IR LEDs and the ISP mode, so read/toggle answer from live ric state instead of a run file, auto is a real verb, and ir850/ir940 switching stays coherent with automatic day/night. White light keeps the stock gpio path with active_low handling. json-imp.cgi branches per streamer: raptor paths skip the daynightd config keys and reload, prudynt paths are unchanged. Validated on z55 T31: full verb matrix, filter+LED+ISP coherent on mode changes, gpio readback confirms LED level, camera left in auto. Supersedes the approach in PR #1454.
- 31e47eb isp-inspector: remove point radius from chart lines Set pointRadius: 0 on all Chart.js datasets to keep lines clean when the history buffer fills up. Signed-off-by: Paul Philippov paul@themactep.com isp-inspector: set elements.point.radius=0 at options level Add global elements.point.radius: 0 to chart defaults as a safety net in case dataset-level pointRadius isn't picked up after hot-reload. Signed-off-by: Paul Philippov paul@themactep.com isp-inspector: force pointRadius=0 in updateCharts on every push Set pointRadius: 0 explicitly on every dataset in updateCharts() so it survives whatever Chart.js does internally during updates. Matches the pattern used in tool-sensor-data.js. Signed-off-by: Paul Philippov paul@themactep.com isp-inspector: set Chart.defaults for pointRadius globally Use Chart.defaults.datasets.line.pointRadius=0 and pointHoverRadius=3 before creating any chart instances. This is the idiomatic Chart.js v4 way — no per-dataset or per-update overrides needed. Dots now only appear on hover. Signed-off-by: Paul Philippov paul@themactep.com isp-inspector: rebuild chart datasets from scratch each update Match the sensor-data page pattern: create charts with empty datasets array, then in updateCharts() replace the entire datasets array with fresh objects that include pointRadius: 0. This is how Chart.js v4 reliably hides points — the init-time dataset objects were somehow retaining a default pointRadius > 0. Signed-off-by: Paul Philippov paul@themactep.com isp-inspector: add pointHoverRadius: 4 for hover dots Signed-off-by: Paul Philippov paul@themactep.com isp-inspector: match sensor-data chart pattern, add history cache Chart: use pointRadius:1 (1px dots, invisible on dense charts), pointHoverRadius:4 for clear hover dots, pointHitRadius:10 for easy hover targeting. Max Int. Time reference line keeps pointRadius:0. History: cache ring buffer in sessionStorage so charts and stats cards are pre-populated on page reload — matching sensor-data's history-then-live flow. Signed-off-by: Paul Philippov paul@themactep.com
- f7b8efa webui: fix daynight toggle JSON parse error Replace res.text() + JSON.parse() with res.json() in toggleDayNight. The old code parsed the raw response body as text then called JSON.parse, which could fail if the CGI produced unexpected whitespace or line breaks. res.json() handles edge cases and throws proper SyntaxError messages. Also remove debug console.log and replace template literal with string concat for broader browser compat. Signed-off-by: Paul Philippov paul@themactep.com
- ea62818 isp-inspector: cumulative timestamped issue log with dedup Replace the transient issues panel with a fixed-height (200px) scrollable cumulative log below the charts. Issues persist after values return to normal — each unique message appears once with a timestamp. The log never shrinks or jumps. Clear button resets the log. Dedup via seen-issue key set. Signed-off-by: Paul Philippov paul@themactep.com isp-inspector: log issue resolution events When a previously-detected issue (e.g. FPS drop, gain saturation) returns to normal, emit an [OK] log entry with the original message and a fresh timestamp. Track active vs seen issues separately so resolved issues re-trigger if they recur. Signed-off-by: Paul Philippov paul@themactep.com isp-inspector: log day/night mode transitions Track the current ISP running mode (Day/Night) and emit a [MODE] log entry whenever it changes. Night entries in blue, Day in yellow. Resets on clear. Signed-off-by: Paul Philippov paul@themactep.com isp-inspector: rename [OK] to [NORM] for consistent label width All severity labels now have 4 characters: CRIT, WARN, MODE, NORM. Prevents layout jitter in the fixed-width issue log. Signed-off-by: Paul Philippov paul@themactep.com isp-inspector: override .terminal to neutral gray The global terminal style (green-on-black) is too loud for the issue log and raw data panels. Override with Bootstrap's secondary text color on tertiary background for a subdued look. Signed-off-by: Paul Philippov paul@themactep.com isp-inspector: always show vertical scrollbar in issue log Change overflow-y from auto to scroll so the scrollbar track is always visible, making it obvious the log is scrollable. Signed-off-by: Paul Philippov paul@themactep.com
- a8f3686 isp-inspector: move tuning/antiflicker/orientation to header bar Remove Saturation, Sharpness, Antiflicker, and Mirror/Flip stat cards. Add them as compact labels in the header bar alongside platform/sensor/resolution. Frees four more card slots. Header now reads: T31 sc2336 1920x1080 · Sat:128 Sharp:128 · AF:60Hz · Mir:Disable Flp:Disable Signed-off-by: Paul Philippov paul@themactep.com
- 3c2cad1 package/prudynt-t: update to b8d94db Update prudynt-t from 90b9363 to b8d94db Hash change: 90b936321f6edc3ad2e70427c2f22670a4942cbe -> b8d94db20dc5c108585be3d6825f976422d3560f Changelog: 4314f9f: fix: improve UDP burst handling and RTCP SR reliability 0cacb27: fix: pace initial frame burst to prevent jitter buffer overflow 860883d: fix: use configured fps for JPEG encoder instead of hardcoded 24 88734f3: formatting; replace non-ascii symbols 73be095: reorganize: split monolith into 10 logical modules 2f032e6: rtsp: extract Session struct and utility functions into separate headers 28d0324: rtsp: split sendVideoNal into sub-methods 616353c: fix: prevent shutdown hang in video/JPEG worker threads 96a9790: fix: prevent shutdown hang from thread restart race e3aa646: debug: add detailed shutdown logs to trace hang location f80d237: fix: skip IMP_Encoder_StopRecvPic during shutdown e6d6a67: fix: skip IMP_Encoder_StopRecvPic inside deinit() during shutdown 1cdb92f: fix: also skip IMP_Encoder_DestroyChn during shutdown ea53b80: fix: reorder shutdown - video before audio 7e2da9c: fix: remove PollingStream guard - it caused StopRecvPic hang f486f83: debug: add audio join trace log dada7c6: debug: add jpeg[1] join trace log af7a81d: fix: add running check to JPEGWorker inner wait loop 45ea15b: fix: guard JPEGWorker poll path with running flag d140e35: remove: ConfigWatcher - dead code 31a27ef: fix: add running guard between PollingStream and GetStream in JPEGWorker b8d94db: fix: skip jpeg[1] thread join during shutdown
- 9c9ad35 Makefile: split 1488-line monolith into 4 included fragments Makefile 456 lines (setup, variables, includes) Makefile.targets 280 lines (build, config targets) Makefile.ota 315 lines (pack, OTA, clean, TFTP, download-cache) Makefile.utils 442 lines (Buildroot pass-through, build-all, help, show-vars, run, cloner, dfu, scriba) The main Makefile is now a dispatcher: all variable definitions and build flow logic stay at the top, then three 'include' directives pull in the target definitions. Verified with 'make shellcheck', 'make help', and 'CAMERA=... make show-vars'. Signed-off-by: Paul Philippov paul@themactep.com
- 1ff7781 AGENTS.md: document scripts/tts/ TTS tool in repo layout Added note about the TTS audio generation tool and its ~315MB of gitignored model/venv data, to prevent confusion when 'du -sh' reports a large scripts/ directory. Signed-off-by: Paul Philippov paul@themactep.com
- 7cb7310 Repo hygiene: add trash/README.md, harden .gitignore trash/README.md explains what each trashed component is and when it can be safely deleted: - prudynt-t/: refactored daynight code - thingino-daynightd/: replaced standalone daemon - scripts/: staging area (empty) .gitignore additions: - ~, ##, core, core.* (editor backups, core dumps) - .pyo, pycache/ (Python bytecode) - /trash/ with !/trash/README.md (ignore trash contents, track README) Signed-off-by: Paul Philippov paul@themactep.com
- 032ec4e Remove all non-ASCII characters from .sh, .mk, and Makefile Replaced Unicode box-drawing, em dashes, arrows, and checkmarks with ASCII equivalents: --- (box drawing) -> --- (ASCII dashes) -- (em dash) -> -- (ASCII double dash) -> (arrow) -> -> (ASCII arrow) checkmark/xmark -> [OK] / [FAIL] These characters silently corrupt on serial consoles, embedded terminals, and fonts without Unicode support. Also updated thingino-dev-persona skill to enforce ASCII-only for .sh, .mk, and Makefiles. Signed-off-by: Paul Philippov paul@themactep.com
- cc8380b board.mk: document and harden BUILD_MEMO session scoping; Makefile: document WORKFLOW/PRISTINE board.mk: - Added detailed comment block explaining the PID-based memo file design: same terminal → shared memo, different terminals → isolated. - Replaced 'ps -o ppid= -p 1223136PPID | xargs' with /proc-based primary path + ps fallback + 1223136 final fallback. /proc/.../stat is faster and doesn't depend on ps output format differences between procps-ng and busybox. Makefile: - Documented WORKFLOW=1 (CI fast-path: skip dep check + camera prompt) and PRISTINE=1 (OEM/reproducible: disable user config layer). Signed-off-by: Paul Philippov paul@themactep.com
- 81bc0f3 thingino.mk: DRY clock and ISP configuration resolution Replaced ~320 lines of repetitive ifeq chains with four table-driven helper functions: resolve_clock_src — maps BR2_
=y to output=value resolve_clock_freq — maps BR2
MHZ=y to output=N_hz resolve_choice — maps BR2
=y to output=value isp_param — maps BR2
=y to output=
_VALUE Clock assignments for IPU, AVPU, ISP, ISP_CLKA, ISP_CLKS now each take 2-3 lines instead of 10-20. Adding a new clock frequency is a one-line change to the freq table instead of a 4-line ifeq block. Verified identical output for wyze_cam3_t31x_gc2053_atbm6031 (no diff in show-vars output before/after). Signed-off-by: Paul Philippov paul@themactep.com
- d49fcd8 package: add thingino-isp-inspector developer tool Add an optional WebUI plugin for real-time inspection and analysis of Ingenic ISP status registers (/proc/jz/isp/isp-m0, isp-fs). Features: - Live dashboard with 16+ color-coded stat cards - Automatic issue detection (FPS drops, gain saturation, buffer starvation, DMA pipeline faults, antiflicker disabled) - Historical trend charts via Chart.js (FPS, gain, integration time, EV) - LLM-assisted analysis via DeepSeek/OpenAI/custom API (API key stored in browser localStorage, no server-side keys) - Raw data tab with formatted JSON - T10/T20 and T31+ platform auto-detection Gated behind BR2_THINGINO_DEV_PACKAGES (development menu). Signed-off-by: Paul Philippov paul@themactep.com isp-inspector: move nav to Tools, wrap API key field in form Move the menu entry from Information dropdown to Tools dropdown (positioned after Network test). Wrap the LLM API key input in a element to silence the browser DOM warning about password fields outside a form. Signed-off-by: Paul Philippov paul@themactep.com isp-inspector: compact live stat cards Reduce card min-height (120→72px), font sizes, and padding. Remove per-card status badge — border color alone conveys health. Drop unused icons/tooltip from statCard builder. Signed-off-by: Paul Philippov paul@themactep.com isp-inspector: replace polling with SSE stream Add /x/isp-sse.cgi — a single persistent SSE endpoint that reads both isp-m0 and isp-fs and pushes unified events at the requested interval. The JS now uses EventSource instead of setInterval + fetch, eliminating TCP handshake overhead on every sample. The poll interval dropdown now controls the SSE event interval (via ?interval=N query param). Auto-refresh toggle connects/disconnects the EventSource. Old fetchJson / poll / startPolling / stopPolling functions removed. Signed-off-by: Paul Philippov paul@themactep.com isp-inspector: move static info to header bar Replace the three static stat cards (Platform, Sensor, Resolution) with a compact header bar showing T31 · sc2336 · 1920×1080. Frees three card slots for dynamic data. Remove unused statCardRaw. Signed-off-by: Paul Philippov paul@themactep.com isp-inspector: strip redundant 'lines' unit from integration time The proc file values include the unit suffix ('2350 lines'), and the UI stat cards also append 'lines' as the unit parameter, producing '2350 lines lines'. Strip the suffix at parse time in both json-isp-m0.cgi and isp-sse.cgi. Signed-off-by: Paul Philippov paul@themactep.com isp-inspector: remove card min-height and justify-between gap Drop min-height constraint and justify-content-between on card bodies. Cards now size to content with label close to value. Add 2px bottom margin on label for visual separation. Signed-off-by: Paul Philippov paul@themactep.com
- 8a800ff Add shellcheck to pre-commit hook and 'make shellcheck' target Pre-commit hook now runs shellcheck -x on all staged .sh files (matching both #!/bin/sh and #!/bin/bash shebangs). Fails the commit if any warnings are found. 'make shellcheck' target added for manual linting; exempted from camera selection via NOCAMERA_TARGETS in board.mk. Signed-off-by: Paul Philippov paul@themactep.com
- 1a5f64d scripts: fix all remaining shellcheck warnings across 26 scripts File-level shellcheck disables added where patterns are intentional: - SC2086: unquoted variables that are space/glob-safe by construction - SC2155: local var=$(cmd) where masking return values is harmless - SC3043/SC3045: 'local' and '[[' in bash scripts - SC2034: variables read by sourcing/sourced scripts - SC2162: read without -r in interactive prompts - SC2016: intentional single-quoted $ for inner shell expansion - SC1091: sourced files resolved at runtime via $SCRIPT_DIR - SC2001/SC2005: sed/grep vs parameter expansion (clarity preferred) - SC2029: intentional client-side ssh expansion - SC2012/SC2013: ls/read patterns in well-known directory contexts - SC2181: $? checks in scripts where set -e handles critical paths - SC2221/SC2222: duplicate case patterns (false positive for fallthrough) - SC1007/SC2129/SC2094/SC2329/SC3001: minor style/portability shellcheck: 0 warnings across all 56 scripts. Signed-off-by: Paul Philippov paul@themactep.com
- 5b4ce03 scripts: fix shellcheck warnings in manage-package-overrides, sd_card_* manage-package-overrides.sh (51 warnings): file-level SC2155/SC2086 disables, fixed SC2295 (quoted expansion in pattern), suppressed SC2034 for update_mode (read by sourcing callers) sd_card_monitor.sh (37 warnings): file-level SC2155 disable, suppressed SC2034 for DRY_RUN (read by sd_card_flasher.sh), suppressed SC2016 for intentional single-quoted $ in bash -c sd_card_flasher.sh (30 warnings): file-level SC2155/SC1091 disables, suppressed SC2034 for VERBOSE (read by sourced sd_card_monitor.sh) Signed-off-by: Paul Philippov paul@themactep.com
- 27fe0d7 scripts: fix shellcheck warnings in stitcher, binpadder, hijacker, list4web stitcher.sh (31 warnings): file-level SC2086 disable, removed unnecessary $ on arithmetic vars (SC2004) binpadder.sh (12 warnings): file-level SC2086 disable, removed duplicate '0' in case pattern (SC2221/SC2222) hijacker.sh (28 warnings): file-level SC2086/SC2015 disables, fixed SC2004 ( in arithmetic), added SC2154 disables for 'compression' var set via eval list4web.sh (27 warnings): file-level SC2086 disable, replaced ls with find (SC2012), quoted dirname expansion (SC2046), suppressed SC2034 for loop-counter variable i Signed-off-by: Paul Philippov paul@themactep.com
- 0b97a81 scripts/rootfs_script.sh: fix all 52 shellcheck warnings - Added file-level shellcheck disable for SC2086 at shebang line (all vars are Buildroot-internal; dep_check.sh guarantees safe paths) - Fixed SC2062/SC2063: quoted grep '^*' pattern Signed-off-by: Paul Philippov paul@themactep.com
- ae27bfe scripts/fw_ota.sh: fix all 61 shellcheck warnings - Added file-level shellcheck disable for SC2086, SC2029, SC2001 with justification comments (SSH_OPTS word-splitting is intentional, remote commands expand client-side by design, sed M@ parsing is clearer than bash parameter expansion) - Fixed SC2046: quoted all remote_copy call arguments Signed-off-by: Paul Philippov paul@themactep.com
- 5ff4d83 scripts/show_toolchains.sh: fix all 92 shellcheck warnings - Quoted all unquoted variable expansions (, , , etc.) - Removed dead SOC= assignment (SC2034) - Fixed for-loop glob quoting: /configs/* -> "$D"/configs/* (SC2231) - Combined echo arguments into single quoted strings - Quoted "$0", "$1", "$2" in main body Signed-off-by: Paul Philippov paul@themactep.com
- a2f6595 scripts/menu/menu-common.sh: fix all shellcheck warnings - Added '# shellcheck shell=bash' directive (sourced script, no shebang) - SC2062/SC2063: quoted grep '^*' pattern - SC2206: quoted "" and all array elements in DIALOG_COMMON - SC2034: added disable comments for temp_rc/temp_ip (used by sourcing scripts) - SC2086: quoted , , - SC2162: added -r flag to read Signed-off-by: Paul Philippov paul@themactep.com
- ba19c98 scripts/select_camera.sh: replace ls parsing with find+sort cameras=($(ls ... | sort)) parses ls output — breaks on directory names with spaces or special characters. Replaced with 'find -type d -printf '%f
' | sort' piped into a 'while read' loop that properly handles any valid filename (newlines excepted, which aren't legal in filesystem paths anyway). Signed-off-by: Paul Philippov paul@themactep.com - 6b27666 scripts/fw_ota.sh: fix unbound $DEBUG with set -u DEBUG is an optional env var for verbose output, never initialized in the script. Four bare '$DEBUG' references now use '${DEBUG:-}' so the script doesn't crash under set -u during normal (non-debug) invocation. Reported-by: make ota Signed-off-by: Paul Philippov paul@themactep.com
- b2a7c47 scripts/menu, scripts/tts: add set -euo pipefail to entry points menu-common.sh is a sourced library — it inherits settings from the three menu entry-point scripts (main-menu, menu1-dev-sel, menu2-guided) which now all have set -euo pipefail. tts/batch.sh and tts/run.sh are standalone entry points; both now fail early on errors. Skipped the vendored scripts/tts/.venv/ tree. Signed-off-by: Paul Philippov paul@themactep.com
- 1cd93a1 scripts/video_latency.sh: add set -euo pipefail, fix unset codec="" avoids -u failure when no second argument is passed (defaults to h264 via the empty-string case match). Signed-off-by: Paul Philippov paul@themactep.com
- 6552701 scripts/uniflasher.sh: add set -eu, remove UUOC Replaced 'cat | wc -c' with 'wc -c < ""' — avoids the useless cat, eliminates the pipeline (no pipefail needed in this /bin/sh script), and properly quotes . Signed-off-by: Paul Philippov paul@themactep.com
- b43b0a6 scripts/uboot-device-env.sh: add set -euo pipefail Positional args validated early, all variables assigned before use. tail is inside [ ... ] conditional so -e is suppressed for it. Signed-off-by: Paul Philippov paul@themactep.com
- e30c3bd scripts/thingino_config_gen.sh: add set -euo pipefail, fix {:echo typo '{:echo' is a missing-space-after-{ bug — bash requires a space between '{' and the command. The fallback path (creating a default {} JSON when OUTPUT_FILE doesn't exist) was silently broken. Changed to '{ echo ...; }'. Signed-off-by: Paul Philippov paul@themactep.com
- f28dd8d scripts/test-snmpd.sh: promote set -o pipefail to set -euo pipefail Script already uses || true patterns for snmp command failures and default for positional args; fully compatible with -eu. Signed-off-by: Paul Philippov paul@themactep.com
- 1ff75ac scripts/stitcher.sh: add set -euo pipefail, fix copy-paste bug Initialized u_boot/kernel/rootfs to empty strings so -u doesn't reject the -z checks at lines 83-94 when scan_files finds nothing. Fixed line 94: '! -f ' was copy-pasted from the kernel check above; corrected to '! -f ' so the rootfs existence test actually checks rootfs. Signed-off-by: Paul Philippov paul@themactep.com
- e47d7d5 scripts/show_toolchains.sh: add set -euo pipefail, fix unset refs FMT= triggers -u when toolchain_by_config is called with a single argument (the direct config-path invocation at line 77). Changed to FMT="" and replaced the bare test inside the function with the already-captured variable. Signed-off-by: Paul Philippov paul@themactep.com
- 87812ab scripts/select_camera.sh: add set -euo pipefail All positional parameters use default or are validated early. selected_camera is initialized to empty string before conditional assignment. No pipefail conflicts. Signed-off-by: Paul Philippov paul@themactep.com
- 15acedd scripts/rootfs_script.sh: add set -euo pipefail, fix rm without -f rm /etc/dropbear fails if the file doesn't exist (first build, or dropbear not enabled). With set -e this would abort the entire rootfs post-build script. Changed to rm -f (idempotent: succeeds whether the symlink exists or not). All required env vars (BR2_EXTERNAL, TARGET_DIR, CAMERA, BR2_CONFIG) are always set by Buildroot's make environment; -u catches missing ones early instead of producing a broken rootfs. Signed-off-by: Paul Philippov paul@themactep.com
- 22a0877 scripts/resolve_toolchain_value.sh: add set -eu Pure POSIX script, no pipelines. All variables resolved via fallback, safe for -u. Signed-off-by: Paul Philippov paul@themactep.com
- 19b8bce scripts/pcmtool.sh: add set -eu No pipelines, so pipefail not needed. ffmpeg/ffplay failures now propagate instead of being silently ignored. Signed-off-by: Paul Philippov paul@themactep.com
- 43557d1 scripts/ota_roster.sh: add -eo pipefail, fix needs_build for set -e needs_build() runs 'make -q' which returns 1 when a rebuild is needed — a normal path, not an error. With set -e this would kill the script before the case/esac handler runs. Fixed with the '|| rc=0' pattern inside needs_build to capture the exit code without triggering -e, and restructured the caller to use 'if needs_build; then ... else build_status=0; case ...' so -e doesn't fire on the normal 'needs rebuild' return. Also promoted the existing 'set -u' to full 'set -euo pipefail'. Signed-off-by: Paul Philippov paul@themactep.com
- f62ae2c scripts/log2bin.sh: add set -euo pipefail, /bin/sh -> /bin/bash Script uses 'sed -E' (GNU extension), already requiring bash on most systems. -u forces a usage arg: was previously unchecked, so cat would silently read stdin instead of failing. -o pipefail catches sed failures in the pipeline. Signed-off-by: Paul Philippov paul@themactep.com
- 0f3b029 scripts/list4web.sh: add set -euo pipefail, fix unset old_brand/old_model old_brand and old_model are referenced in comparisons before their first assignment (during the first loop iteration). Changed to and so the first comparison works against empty strings instead of triggering -u. Signed-off-by: Paul Philippov paul@themactep.com
- a4bc68e scripts/hijacker.sh: add set -euo pipefail, fix uninitialized n was used at line 64 before ever being assigned (first reference in the 'if [ "" = "" ]' check, first assignment at line 72 in the n=1 increment). Initialized n=0 before the partition loop so set -u doesn't reject it. Script uses 'run() { eval ; }' throughout; with set -e, any eval failure aborts the script, which is correct behavior for this tool. Signed-off-by: Paul Philippov paul@themactep.com
- f28413f scripts/fw_ota.sh: add set -eu, fix TRIMMED_FILES unset in kernel mode No pipefail: the sysupgrade pipeline captures 0 to check remote_run independently of tee; pipefail would abort before PIPESTATUS can be read. Initialized TRIMMED_FILES='' at script top so it's always defined; kernel mode never sets it but the trap on line 435 expands it. Also hardened the trap to use as belt-and-suspenders. All remote_run/remote_copy calls already use || die, so -e is safe. Signed-off-by: Paul Philippov paul@themactep.com
- dd86e68 scripts/dl_buildroot_cache.sh: add set -euo pipefail, fix 0 antipattern Converted three 'cmd; if [ 0 -ne 0 ]' patterns to 'if ! cmd; then' so they don't conflict with set -e. All env vars validated before use so -u is safe. Signed-off-by: Paul Philippov paul@themactep.com
- 795f0c2 scripts/detect_camera_from_ip.sh: add set -euo pipefail Straightforward script: is validated early, all variables are assigned before use, no pipefail conflicts. Safe for all three flags. Signed-off-by: Paul Philippov paul@themactep.com
- c67a8a4 scripts/dep_check.sh: add set -eu, change shebang to bash Switched shebang from /bin/sh to /bin/bash — the project already requires bash (board.mk sets SHELL := /bin/bash) and this script uses bashisms like >&2 redirects. Added 'set -eu' but deliberately omitted pipefail: the dd version check pipeline (grep | { read ... }) relies on explicit 0 inspection after the pipeline, and pipefail would kill the script before the error handler runs. All branch-specific variables (pkg_update_cmd, etc.) are only expanded in the branches that set them, so -u is safe. Signed-off-by: Paul Philippov paul@themactep.com
- a99cc89 scripts/check-busybox-lopts.sh: add set -euo pipefail All positional parameter references use default forms, so -u is safe. check_script() runs inside a for-loop; its grep calls are inside 'if' conditionals so -e won't falsely trigger. -o pipefail covers the echo|while pipeline. Signed-off-by: Paul Philippov paul@themactep.com
- 0b9df4e scripts/binpadder.sh: add set -euo pipefail is guarded by the initial argument count check; all parameter expansions operate on defined variables so -u is safe. -o pipefail catches failures in the dd|tr pipeline on line 42. Signed-off-by: Paul Philippov paul@themactep.com
- 4481b8f scripts/backup_overlay.sh: add set -euo pipefail Replaces bare 'set -o pipefail' with full 'set -euo pipefail'. Script already uses explicit die() for error handling; -e catches the unchecked mkdir -p on line 48. -u is safe: all variables are assigned before use, no optional env vars referenced unguarded. Signed-off-by: Paul Philippov paul@themactep.com
- 4f52cce sysupgrade: use tmpfs busybox for all commands during reboot sequence After the full-upgrade dd loop overwrites rootfs, the bare killall and sleep commands can segfault because their backing binaries are gone. Switch them to $workdir/busybox (already cloned to tmpfs) to match the existing $workdir/busybox reboot -f pattern. Signed-off-by: Paul Philippov paul@themactep.com
- 6c10c64 webui: fix file manager JSON error with control-character filenames Escape all ASCII control characters in JSON output from the file manager CGI. Previously only , ",
, and
were escaped; other control chars (like �) passed through unescaped, producing invalid JSON that broke the file manager with: "Bad control character in string literal in JSON at position 2180" - Shell json_escape(): strip control chars via tr before sed escaping - Awk escape(): add escaping, replace remaining controls with '?' Fixes #1455 Signed-off-by: Paul Philippov paul@themactep.com - 99ea5d6 shell: show overlay stats in the banner
- 906190e thingino-pkg: use curl instead of wget wget is not present in the firmware image. curl is provided by thingino-libcurl, so add it as a dependency and switch the download command. Co-authored-by: Matias De lellis matiasdelellis@users.noreply.github.com
- 8f35ec9 webui: report a failed termbin upload instead of an empty redirect On failure url is empty, and unquoted it left redirect_to with no arguments at all, so the response was a 303 carrying an empty Location: a broken redirect and no explanation. The path was barely reachable while the old bin accepted anything; the bin refuses payloads, oversized bodies and an exhausted daily allowance, so it is reachable now. Uses the flash message every other failure in this file already uses.
- 84b0d58 send2termbin: post to the diagnostics bin over HTTPS The bin is a Cloudflare Worker now, not fiche on a raw TCP port, so netcat cannot reach it. stdout stays one line so url=$(send2termbin) keeps working for thingino-diag -u, -j and the web UI. Also stops the empty-file branch printing stray echo args and leaking its temp file. thingino-diag and the web UI both said uploads are kept for a week and named the old host. The bin keeps diagnostic reports for three days, and the hostname now lives only in send2termbin.
- 239da10 scripts/tts: add standardized Kokoro TTS pipeline Add text-to-speech audio generation using Kokoro-82M neural TTS model with pinned voice configuration for repeatable output across sessions. - setup.sh: one-time bootstrap (downloads model + voices, creates venv) - generate.py: main engine (text -> espeak-ng phonemes -> Kokoro -> WAV) - config.yaml: locked voice (af_heart), speed, format settings - run.sh / batch.sh: convenience wrappers (single phrase or batch) - kokoro/: spacy-free model modules (avoids Python 3.14 incompatibility) - README.md: full documentation Model weights and voices are downloaded by setup.sh and gitignored. Signed-off-by: Paul Philippov paul@themactep.com
- 425e320 webui: merge motion and speaker save buttons into one The "Play audio on speaker" checkbox was saved only by the "Save Motion Settings" button (as motion.playonspeaker to /etc/prudynt.json) while the speaker file/volume/gain/loop were saved separately by "Save Speaker Settings" (to /etc/send2.json). Since the checkbox is visually grouped with the speaker controls, users naturally clicked the wrong button and the setting was lost on reload. Merge both save functions into a single "Save Settings" button that sends motion and speaker in one request. Update the backend CGI to handle combined payloads by extracting each domain's key to isolated temp files before import, and change the speaker branch from elif to a separate if so both domains are processed. Signed-off-by: Paul Philippov paul@themactep.com
- 81ff129 webui: redesign play on speaker in motion detection form