Simulated Cameras
You can't develop against 1,400 cameras bolted to mountaintops. You need something that
answers "give me an image" and "where are you pointing" the way a real camera would, but runs
on your laptop. That's Alert.CA.ImageAcquisition.MockCameraAPI — a standalone web API that
impersonates a camera's image endpoints so the whole acquisition pipeline can run end to end
with no hardware.
The one idea to hold on to
A simulated camera is just a config swap: when a device has a mock URL configured, the
engine calls the mock API instead of IVAPIXClient. The activity function branches on it:
GET_IMAGE_URL = _config["MockGetImageUrl"] ?? "";
// …
getImageResponse = await GetImageFromMockCameraAPI(instanceId); // simulated device
// vs.
response = await _vapixClient.GetImageAsync(new GetImageRequest(...)); // real camera
Everything upstream — the orchestration, the modes, the queue, the storage pipeline — is identical. Only the leaf call changes. That's what makes the mock useful: you're exercising the real engine, not a stubbed copy of it.
What the mock serves
ImageController has two endpoints, both returning canned assets bundled with the project:
GET api/Image/GetLatestImage— returns a random JPG fromStaticImages/plus a fabricatedCameraPosition, shaped as the sameGetImageResponsea real camera returns.GET api/Image/GetPanoImage?deviceId=...— returns that device's pano tiles from a per-site dictionary (named sites like Lyons_Peak, Otay_Mtn, UCSD_TDLLN), or a random pano if the device isn't mapped.
Because GetLatestImage generates a random CameraPosition, a simulated camera's "PTZ" isn't
real: sending a move updates the entity's stored position, but the next mock image comes back
with an unrelated fabricated position. The mock is for exercising the pipeline (capture,
store, broadcast, mode transitions), not for verifying that a physical camera actually pointed
where you told it. For real PTZ behavior you need a real camera.
Wrapping up
The mock camera API is a hardware stand-in that serves canned images and pano tiles behind the same response shapes a real camera uses, and the engine routes to it purely by configuration — so the entire acquisition pipeline runs locally against the real orchestration. Just remember it fabricates positions: it proves the pipeline works, not that a camera moved.
Next, where camera inventory and configuration actually come from: Where Cameras Come From.