Skip to content

feat: fake Reolink camera driven by scenarios - #65

Open
MateoLostanlen wants to merge 20 commits into
mainfrom
feat/fake-reolink-camera
Open

MateoLostanlen wants to merge 20 commits into
mainfrom
feat/fake-reolink-camera

Conversation

@MateoLostanlen

@MateoLostanlen MateoLostanlen commented Oct 22, 2026 •

Copy link
Copy Markdown
Member
  • Add a fake Reolink camera (stdlib HTTPS server) so the real pyro_camera_api and engine run unchanged against it: Snap, PTZ presets, zoom, focus, reboot. Closes Fake Reolink camera driven by scenarios #29.
  • Scenarios are a folder of frames per camera, with three published ones: smoke then clear, never smoke, and false positives from the pyro-dataset val set (YOLO fires, the temporal model rejects them). Each preset moves to its next frame on its next patrol visit (first Snap after a ToPos), so the engine sees every frame once per preset whatever its timing, and autofocus snaps do not advance the scenario. Images come from the scenarios release, scripts/make_scenario.py builds them from a replayed alert.
  • engine and pyro_camera_api move to the compose network, the camera API waits for init_script, and init_script tolerates being re-run (completion marker). The camera API runs with ENABLE_STUCK_DETECTOR=false (every preset serves the same frames) and can reach a MediaMTX on the host (host.docker.internal).
  • A workflow publishes pyronear/fake-camera (latest on main, X.Y.Z on a fake-camera-vX.Y.Z tag) with the default scenario embedded; it needs the DOCKERHUB_LOGIN / DOCKERHUB_PW secrets.
  • The compose workflow now creates .env, starts the engine profile and fails when a service is unhealthy or the engine is not running. It is disabled on the repo and has to be enabled again.
  • Not covered yet: one image sequence per preset, RTSP stream (Playwright test: start a live check (levée de doute) #62).

A stdlib HTTPS server answering the Reolink CGI API (Snap, PtzCtrl,
GetPtzPreset, SetPtzPreset, zoom, focus, reboot) from a folder of frames,
one per interval from the first Snap, last frame held. Three scenario
definitions and a script to build frames from a replayed alert.
engine and pyro_camera_api move from host networking to the compose
network so the fake cameras are reachable by name. The camera API waits
for init_script to write the camera tokens. The stuck detector is off
since every preset serves the same frames. Poses of the two scenario
cameras take the production presets and azimuths.
docker compose up restarts the exited init container, which failed on the
duplicate organizations and blocked the services that wait for it.
A database initialized before this branch has the organizations but no
token for the new fake cameras: do not exit early in that case.
Also state in the scenario descriptions that every preset serves the
same frames for now.
The fake camera only serves frames, so for the engine a false positive is
the same as a wildfire. Keep fire and no fire.
fetch-scenario downloads unless every camera of the scenario has frames.
init_script skips a re-run only when a marker written at the end of a
successful run exists, so a partial init is not mistaken for a complete
one.
The previous commit only changed fetch-scenario; this is the init_script
part: a re-run exits early only when data/.init_done exists, so a partial
init is not mistaken for a complete one.
latest on main, X.Y.Z on a fake-camera-vX.Y.Z tag, build only on pull
requests. The default scenario is fetched from the release and embedded.
So the published image runs alone, e.g. on a test station; a volume on
/scenarios still overrides it. The build takes data/scenarios as a named
context, which the image workflow already passes.
A restored credentials.json with blank tokens must not be skipped, and a
full init starts by dropping the marker.
@MateoLostanlen
MateoLostanlen requested a review from fe51 October 26, 2026 17:34
…lock

With a clock, the camera API patrol and the scenario drifted apart: a preset could get the same frame twice or skip one, and the autofocus snaps advanced the scenario too. Now the first Snap after a ToPos takes the next frame of that preset, snaps in place keep it, and a static camera moves on every Snap. The scenario interval is gone.
YOLO fires on both cameras while the temporal model rejects the sequences, so no alert is expected with temporal validation. It caught repeated frames being scored on the engine (pyronear/pyro-engine#415). Images are in the scenarios release (false-positive.zip).
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.

Fake Reolink camera driven by scenarios

1 participant