Activity Functions
Activity functions perform the actual I/O work of the orchestration โ communicating with cameras, storing images, and updating external systems. They run as isolated units so that failures in one activity don't crash the parent orchestration.
Image Capture Activitiesโ
RequestSingleImageFromDeviceโ
Captures a single image from a camera.
Routing logic:
- SimCam (simulated) โ HTTP GET to Mock Camera API
- RealCam (production) โ
IVAPIXClient.GetAWFImageAsync()with standard image fallback
After capture:
SingleImageStorageService.StoreImageAsync()saves the image to Blob Storage- A thumbnail is generated (aspect-ratio preserved)
- Metadata is written to Table Storage
- Image metadata is broadcast via SignalR
RequestPanoFromDeviceโ
Captures a panoramic image from multiple PTZ positions.
Internal panorama flow:
- Move camera to each pan position (typically 6 positions for 360ยฐ)
- Capture an image at each position
- Stitch all images horizontally using
System.Drawing(JPEG quality 50) - Save component images as a ZIP archive via
PreStitchedImageStorageService - Save the stitched panorama via
PanoImageStorageService
External panorama flow (UCSD):
- Fetch the panorama from the UCSD Alert CA API
- Re-stitch with corrected orientation
- Save to Blob Storage
Camera Movement Activitiesโ
Eight activity functions handle camera control, all located in CameraMovementFunctions.cs:
| Activity | Method | Purpose |
|---|---|---|
PanTiltZoomCamera | IVAPIXClient.PTZ() | Move camera to specific pan/tilt/zoom position |
MoveCameraHome | IVAPIXClient.GoHome() | Return camera to preset home position |
GetCameraPosition | IVAPIXClient.GetPosition() | Query current PTZ coordinates |
FocusCamera | IVAPIXClient.SetFocus() | Adjust camera focus |
SetCameraBrightness | IVAPIXClient.SetBrightness() | Adjust camera brightness |
ShouldToggleGuardTourInOrchestration | Conditional check | Validates if guard tour should be enabled before attempting toggle |
GuardTourToggleInOrchestration | IVAPIXClient.ToggleGuardTour() | Enable/disable automated patrol |
CameraStatus | IVAPIXClient.GetStatusAsync() | Full status query |
Guard Tour Toggle Logicโ
ShouldToggleGuardTourInOrchestration is triggered when the orchestration requests to enable guard tour mode:
- Checks if the enable flag is true in the trigger
- Retrieves the camera's current operational state from the repository
- Only calls
GuardTourToggleInOrchestrationif:- The operational state exists in records
- The camera is currently marked as patrol-enabled (
IsPatrolEnabled)
- This prevents unnecessary camera API calls if patrol mode should remain deactivated
GuardTourToggleInOrchestration is directly invoked by the conditional check and performs the actual camera operation:
- Verifies the camera is ready for communication
- Confirms the camera has guard tour capability
- Sends the toggle request to the camera via VAPIX
- Updates the camera's
IsPatrolEnabledflag in the operational repository on success
All camera movement activities:
- Decrypt credentials via
IEncryptionServicebefore communicating with the camera - Log results to Application Insights telemetry
- Return results to the orchestration for state updates
Status Reporting Activitiesโ
SubmitOnlineStatusToESRI / SubmitOfflineStatusToESRIโ
When the orchestration detects a camera's online/offline status has changed:
- Calls the ESRI feature layer API to update the camera's status on the map
- This ensures the frontend map always reflects current camera health
DurableDataStoreFunctionsโ
Syncs the current CameraState entity state to Table Storage:
- Creates a record with acquisition rates per mode
- Used by the Admin API dashboard for aggregated monitoring
- Also broadcasts current config to SignalR for real-time frontend updates
Error Handlingโ
Activity functions use the Durable Functions retry policy:
- If an activity fails (e.g., camera unreachable, storage timeout), the orchestration captures the failure
- The orchestration loop continues to the next iteration via
ContinueAsNew() - Failed captures are logged to Application Insights with error kind dimensions
- Telemetry tracks SUCCESS (metric value 10) vs. FAIL (metric value 1) per capture attempt