Skip to main content

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:

  1. SingleImageStorageService.StoreImageAsync() saves the image to Blob Storage
  2. A thumbnail is generated (aspect-ratio preserved)
  3. Metadata is written to Table Storage
  4. Image metadata is broadcast via SignalR

RequestPanoFromDeviceโ€‹

Captures a panoramic image from multiple PTZ positions.

Internal panorama flow:

  1. Move camera to each pan position (typically 6 positions for 360ยฐ)
  2. Capture an image at each position
  3. Stitch all images horizontally using System.Drawing (JPEG quality 50)
  4. Save component images as a ZIP archive via PreStitchedImageStorageService
  5. Save the stitched panorama via PanoImageStorageService

External panorama flow (UCSD):

  1. Fetch the panorama from the UCSD Alert CA API
  2. Re-stitch with corrected orientation
  3. Save to Blob Storage

Camera Movement Activitiesโ€‹

Eight activity functions handle camera control, all located in CameraMovementFunctions.cs:

ActivityMethodPurpose
PanTiltZoomCameraIVAPIXClient.PTZ()Move camera to specific pan/tilt/zoom position
MoveCameraHomeIVAPIXClient.GoHome()Return camera to preset home position
GetCameraPositionIVAPIXClient.GetPosition()Query current PTZ coordinates
FocusCameraIVAPIXClient.SetFocus()Adjust camera focus
SetCameraBrightnessIVAPIXClient.SetBrightness()Adjust camera brightness
ShouldToggleGuardTourInOrchestrationConditional checkValidates if guard tour should be enabled before attempting toggle
GuardTourToggleInOrchestrationIVAPIXClient.ToggleGuardTour()Enable/disable automated patrol
CameraStatusIVAPIXClient.GetStatusAsync()Full status query

Guard Tour Toggle Logicโ€‹

ShouldToggleGuardTourInOrchestration is triggered when the orchestration requests to enable guard tour mode:

  1. Checks if the enable flag is true in the trigger
  2. Retrieves the camera's current operational state from the repository
  3. Only calls GuardTourToggleInOrchestration if:
    • The operational state exists in records
    • The camera is currently marked as patrol-enabled (IsPatrolEnabled)
  4. 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:

  1. Verifies the camera is ready for communication
  2. Confirms the camera has guard tour capability
  3. Sends the toggle request to the camera via VAPIX
  4. Updates the camera's IsPatrolEnabled flag in the operational repository on success

All camera movement activities:

  • Decrypt credentials via IEncryptionService before 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:

  1. Calls the ESRI feature layer API to update the camera's status on the map
  2. 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