Skip to content

Fall back to FILE_FIND when cmd 272 VOD search returns 405 - #185

Open
florian-bailly wants to merge 1 commit into
starkillerOG:mainfrom
florian-bailly:fix-search-vod-type-405-filefind
Open

Fall back to FILE_FIND when cmd 272 VOD search returns 405#185
florian-bailly wants to merge 1 commit into
starkillerOG:mainfrom
florian-bailly:fix-search-vod-type-405-filefind

Conversation

@florian-bailly

@florian-bailly florian-bailly commented Jul 26, 2026

Copy link
Copy Markdown

Summary

search_vod_type uses the Baichuan cmd 272 VOD search, which the Reolink E1 Pro and Argus battery cameras do not implement — they reject it with status 405, so the call raises ApiError and no recordings can be listed (#150).

This catches the 405 on the first request and falls back to the generic FILE_FIND search (cmd 14 open / 15 list / 16 close), which returns the same SD-card recordings. The public API and return type of search_vod_type are unchanged, so existing callers keep working and now also succeed on these models.

How it works

  • 405 fallback — cmd 272 raising ApiError(rspCode=405) on the first request switches to FILE_FIND; any other ApiError still propagates.
  • Per-day iteration — the firmware searches a single calendar day per FILE_FIND open: a multi-day window returns only the start day. So the search iterates day-by-day over [start.date(), end.date()] (_filefind_day) and merges the results, de-duplicating clips by name across days (a clip straddling midnight is returned by both days' searches).
  • Paging — each day pages through cmd 15 until no new files come back, then closes the handle with cmd 16 (close failures are tolerated).
  • Shared trigger classification — the <recordType>/alarmType → VOD_trigger mapping already existed inline in the cmd 272 path. Both paths now share a single VOD_TRIGGER_TOKENS table + _classify_vod_triggers helper, so they classify identically and FILE_FIND gets the full trigger set (motion / io / person / face / vehicle / animal / doorbell / package / crying / crossline / intrusion / linger / forgotten- & taken-item).

The commented-out FILE_FIND sketch previously left in search_vod_type is replaced by this working implementation.

Warning

Known smell — paging termination is coupled to de-dup. In _filefind_day, a single new_files flag decides both "did this page add clips?" and "should paging continue?". A page that is entirely already-seen clips, or entirely malformed, breaks the loop early even if later pages still hold new clips.

With a sequential per-day handle this should not happen in practice, which is why it is shipped as-is — but it is a real coupling. If preferred, I can split termination from de-dup (break only on a genuinely empty <FileInfo> set). Say the word and I'll adjust.

Test plan

tests/test_baichuan_filefind_fallback.py (10 tests / 16 subtests):

  • cmd 272 → 405 triggers the FILE_FIND chain (14/15/16) with correctly-classified clips;
  • a non-405 ApiError still propagates (no accidental swallowing);
  • per-day iteration over a multi-day window (one open/list/close per day);
  • multi-page paging within a single day accumulates across pages;
  • cross-day de-dup — a midnight-straddling clip is counted once;
  • a day with no recordings (no handle) is skipped and the search continues;
  • the full trigger table — every recordType token maps to its VOD_trigger;
  • malformed entries (missing name / unparseable time) are skipped, valid siblings kept;
  • 64-bit sizessizeL + (sizeH << 32);
  • close-failure tolerance — a cmd 16 failure does not drop results.

Verified on real hardware — Argus PT Ultra (fw v3.0.0.3911): a 12-day window returned 123 clips across 11 days (MOTION/PERSON/ANIMAL) instead of raising.

black --check, isort, pylint (10.00/10) and mypy pass on the changed module.

Closes #150.

Note: #164 also adds Baichuan SD listing, but via new get_recordings_for_day / search_recordings_for_day_bc methods. This PR is complementary — it keeps the existing search_vod_type API working on 405 firmwares instead of adding a parallel API.

🤖 Generated with Claude Code

Some firmwares (Reolink E1 Pro, Argus battery cameras) do not implement the
cmd 272 VOD search and answer it with HTTP 405. Fall back to the Baichuan
FILE_FIND protocol (cmd 14 open / 15 list / 16 close) to enumerate the SD-card
recordings on those devices. Closes starkillerOG#150.

The firmware searches a single calendar day per FILE_FIND open (a multi-day
window returns only the start day), so the search iterates day-by-day and
merges the results, de-duplicating clips by name across days.

The recordType/alarmType -> VOD_trigger classification is factored into a
shared VOD_TRIGGER_TOKENS table and _classify_vod_triggers helper, used by both
the cmd 272 and FILE_FIND paths so they classify identically (this also gives
FILE_FIND the full trigger set, incl. cry/crossline/intrusion/...).

Live-verified on an Argus PT Ultra (fw v3.0.0.3911): a 12-day window now returns
123 clips across 11 days. Tests cover the 405 fallback, per-day iteration,
multi-page paging, cross-day de-dup, days without recordings, the full trigger
table, malformed entries, 64-bit sizes, and close-failure tolerance.
@florian-bailly
florian-bailly force-pushed the fix-search-vod-type-405-filefind branch from 4e9c367 to baddcb4 Compare July 26, 2026 14:49
@florian-bailly

florian-bailly commented Aug 6, 2026

Copy link
Copy Markdown
Author

hello @starkillerOG

This is a small PR to fix the listing cmd not supported on (some?) camera batteries.

It's targeted on the 405 return for the cmd 272, so regressions are quite unlikely on other models.

It ran successfully on my Argus PT Ultra.

This issue was also reported by #150

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reolink E1 Pro -> search_vod_type throws status code 405 from cmd_id 272

1 participant