From 5bdb070173ece537d089b8a1567778b240d71ec1 Mon Sep 17 00:00:00 2001 From: salirezav Date: Tue, 2 Sep 2025 15:31:47 -0400 Subject: [PATCH] Enhance camera management features: add debug endpoint for camera manager state, implement live camera routes without authentication, and improve logging for camera initialization and status checks. Update Docker configuration to include environment variables for the web app. --- .../usda_vision_system/api/server.py | 23 ++ .../usda_vision_system/camera/manager.py | 8 + .../usda_vision_system/camera/monitor.py | 35 ++- .../usda_vision_system/core/state_manager.py | 1 + docker-compose.yml | 2 + management-dashboard-web-app/.env.example | 0 management-dashboard-web-app/.gitignore | 0 .../.vscode/extensions.json | 0 .../docs/AI_AGENT_VIDEO_INTEGRATION_GUIDE.md | 0 .../docs/API_CHANGES_SUMMARY.md | 0 .../docs/API_DOCUMENTATION.md | 0 .../docs/API_QUICK_REFERENCE.md | 0 .../docs/CURRENT_CONFIGURATION.md | 0 .../docs/MP4_FORMAT_UPDATE.md | 0 .../docs/PROJECT_COMPLETE.md | 0 .../docs/REACT_INTEGRATION_GUIDE.md | 0 .../API Documentations/docs/README.md | 0 .../docs/VIDEO_STREAMING.md | 0 .../docs/WEB_AI_AGENT_VIDEO_INTEGRATION.md | 0 .../docs/api/CAMERA_CONFIG_API.md | 0 .../docs/camera/BLOWER_CAMERA_CONFIG.md | 0 .../docs/camera/CONVEYOR_CAMERA_CONFIG.md | 0 .../docs/camera/PREVIEW_ENHANCEMENT.md | 0 .../features/AUTO_RECORDING_FEATURE_GUIDE.md | 0 .../docs/guides/CAMERA_RECOVERY_GUIDE.md | 0 .../docs/guides/MQTT_LOGGING_GUIDE.md | 0 .../docs/guides/STREAMING_GUIDE.md | 0 .../docs/legacy/01README.md | 0 .../docs/legacy/IMPLEMENTATION_SUMMARY.md | 0 .../API Documentations/docs/legacy/README.md | 0 .../docs/legacy/README_SYSTEM.md | 0 .../docs/legacy/TIMEZONE_SETUP_SUMMARY.md | 0 .../docs/legacy/VIDEO_RECORDER_README.md | 0 .../CAMERA_ROUTE_IMPLEMENTATION.md | 210 ++++++++++++++++++ management-dashboard-web-app/README.md | 0 .../VISION_SYSTEM_README.md | 0 .../api-endpoints.http | 0 .../docs/AUTO_RECORDING_SETUP.md | 0 .../docs/MODULAR_ARCHITECTURE_GUIDE.md | 0 .../MP4_FRONTEND_IMPLEMENTATION_STATUS.md | 0 .../docs/VIDEO_STREAMING_INTEGRATION.md | 0 .../VIDEO_STREAMING_INTEGRATION_COMPLETE.md | 0 management-dashboard-web-app/eslint.config.js | 0 management-dashboard-web-app/index.html | 0 .../package-lock.json | 75 ++++++- management-dashboard-web-app/package.json | 8 +- .../phase_2_experimental_run_sheet.csv | 0 .../public/camera-test.html | 119 ++++++++++ management-dashboard-web-app/public/vite.svg | 0 management-dashboard-web-app/src/App.css | 0 management-dashboard-web-app/src/App.tsx | 21 ++ .../src/assets/react.svg | 0 .../src/components/AutoRecordingStatus.tsx | 0 .../src/components/AutoRecordingTest.tsx | 0 .../src/components/CameraConfigModal.tsx | 0 .../src/components/CameraPreviewModal.tsx | 0 .../src/components/CameraRoute.tsx | 25 +++ .../src/components/CreateUserModal.tsx | 0 .../src/components/Dashboard.tsx | 0 .../src/components/DashboardHome.tsx | 0 .../src/components/DashboardLayout.tsx | 0 .../src/components/DataEntry.tsx | 0 .../src/components/DataEntryInterface.tsx | 0 .../src/components/DraftManager.tsx | 0 .../src/components/ExperimentForm.tsx | 0 .../src/components/ExperimentModal.tsx | 0 .../src/components/Experiments.tsx | 0 .../src/components/LiveCameraView.tsx | 134 +++++++++++ .../src/components/Login.tsx | 0 .../src/components/PhaseDataEntry.tsx | 0 .../src/components/PhaseDraftManager.tsx | 0 .../src/components/PhaseSelector.tsx | 0 .../RepetitionDataEntryInterface.tsx | 0 .../src/components/RepetitionLockManager.tsx | 0 .../components/RepetitionPhaseSelector.tsx | 0 .../components/RepetitionScheduleModal.tsx | 0 .../src/components/ScheduleModal.tsx | 0 .../src/components/Sidebar.tsx | 0 .../src/components/TopNavbar.tsx | 0 .../src/components/UserManagement.tsx | 0 .../src/components/VisionSystem.tsx | 27 ++- .../video-streaming/VideoStreamingPage.tsx | 0 .../components/ApiStatusIndicator.tsx | 0 .../video-streaming/components/Pagination.tsx | 0 .../components/PerformanceDashboard.tsx | 0 .../video-streaming/components/VideoCard.tsx | 0 .../components/VideoDebugger.tsx | 0 .../components/VideoErrorBoundary.tsx | 0 .../video-streaming/components/VideoList.tsx | 0 .../video-streaming/components/VideoModal.tsx | 0 .../components/VideoPlayer.tsx | 0 .../components/VideoThumbnail.tsx | 0 .../video-streaming/components/index.ts | 0 .../features/video-streaming/hooks/index.ts | 0 .../video-streaming/hooks/useVideoInfo.ts | 0 .../video-streaming/hooks/useVideoList.ts | 0 .../video-streaming/hooks/useVideoPlayer.ts | 0 .../src/features/video-streaming/index.ts | 0 .../video-streaming/services/videoApi.ts | 0 .../features/video-streaming/types/index.ts | 0 .../features/video-streaming/utils/index.ts | 0 .../utils/performanceMonitor.ts | 0 .../video-streaming/utils/thumbnailCache.ts | 0 .../video-streaming/utils/videoUtils.ts | 0 .../src/hooks/useAuth.ts | 0 .../src/hooks/useAutoRecording.ts | 0 management-dashboard-web-app/src/index.css | 0 .../src/lib/autoRecordingManager.ts | 0 .../src/lib/supabase.ts | 0 .../src/lib/visionApi.ts | 0 management-dashboard-web-app/src/main.tsx | 0 .../src/test/videoStreamingTest.ts | 0 .../src/test/visionApi.test.ts | 0 .../src/utils/videoFileUtils.ts | 0 .../src/vite-env.d.ts | 0 .../supabase/.gitignore | 0 .../supabase/.temp/cli-latest | 2 +- .../supabase/config.toml | 0 .../migrations/20250719000001_rbac_schema.sql | 0 .../20250719000002_rls_policies.sql | 0 .../20250719000003_seed_admin_user.sql | 0 .../20250720000001_multiple_roles_support.sql | 0 .../20250720000002_fix_role_id_constraint.sql | 0 .../20250720000003_experiments_table.sql | 0 .../20250721000001_add_scheduled_date.sql | 0 ...24000001_experiment_repetitions_system.sql | 0 ...725000001_experiment_data_entry_system.sql | 0 .../20250725000003_fix_draft_constraints.sql | 0 ...50728000001_fix_repetitions_visibility.sql | 0 .../supabase/seed.sql | 0 .../tailwind.config.js | 0 management-dashboard-web-app/test-api-fix.js | 0 .../test-camera-config.html | 0 .../test-stop-streaming.html | 0 .../tsconfig.app.json | 0 management-dashboard-web-app/tsconfig.json | 0 .../tsconfig.node.json | 0 management-dashboard-web-app/vite.config.ts | 0 138 files changed, 672 insertions(+), 18 deletions(-) mode change 100644 => 100755 management-dashboard-web-app/.env.example mode change 100644 => 100755 management-dashboard-web-app/.gitignore mode change 100644 => 100755 management-dashboard-web-app/.vscode/extensions.json mode change 100644 => 100755 management-dashboard-web-app/API Documentations/docs/AI_AGENT_VIDEO_INTEGRATION_GUIDE.md mode change 100644 => 100755 management-dashboard-web-app/API Documentations/docs/API_CHANGES_SUMMARY.md mode change 100644 => 100755 management-dashboard-web-app/API Documentations/docs/API_DOCUMENTATION.md mode change 100644 => 100755 management-dashboard-web-app/API Documentations/docs/API_QUICK_REFERENCE.md mode change 100644 => 100755 management-dashboard-web-app/API Documentations/docs/CURRENT_CONFIGURATION.md mode change 100644 => 100755 management-dashboard-web-app/API Documentations/docs/MP4_FORMAT_UPDATE.md mode change 100644 => 100755 management-dashboard-web-app/API Documentations/docs/PROJECT_COMPLETE.md mode change 100644 => 100755 management-dashboard-web-app/API Documentations/docs/REACT_INTEGRATION_GUIDE.md mode change 100644 => 100755 management-dashboard-web-app/API Documentations/docs/README.md mode change 100644 => 100755 management-dashboard-web-app/API Documentations/docs/VIDEO_STREAMING.md mode change 100644 => 100755 management-dashboard-web-app/API Documentations/docs/WEB_AI_AGENT_VIDEO_INTEGRATION.md mode change 100644 => 100755 management-dashboard-web-app/API Documentations/docs/api/CAMERA_CONFIG_API.md mode change 100644 => 100755 management-dashboard-web-app/API Documentations/docs/camera/BLOWER_CAMERA_CONFIG.md mode change 100644 => 100755 management-dashboard-web-app/API Documentations/docs/camera/CONVEYOR_CAMERA_CONFIG.md mode change 100644 => 100755 management-dashboard-web-app/API Documentations/docs/camera/PREVIEW_ENHANCEMENT.md mode change 100644 => 100755 management-dashboard-web-app/API Documentations/docs/features/AUTO_RECORDING_FEATURE_GUIDE.md mode change 100644 => 100755 management-dashboard-web-app/API Documentations/docs/guides/CAMERA_RECOVERY_GUIDE.md mode change 100644 => 100755 management-dashboard-web-app/API Documentations/docs/guides/MQTT_LOGGING_GUIDE.md mode change 100644 => 100755 management-dashboard-web-app/API Documentations/docs/guides/STREAMING_GUIDE.md mode change 100644 => 100755 management-dashboard-web-app/API Documentations/docs/legacy/01README.md mode change 100644 => 100755 management-dashboard-web-app/API Documentations/docs/legacy/IMPLEMENTATION_SUMMARY.md mode change 100644 => 100755 management-dashboard-web-app/API Documentations/docs/legacy/README.md mode change 100644 => 100755 management-dashboard-web-app/API Documentations/docs/legacy/README_SYSTEM.md mode change 100644 => 100755 management-dashboard-web-app/API Documentations/docs/legacy/TIMEZONE_SETUP_SUMMARY.md mode change 100644 => 100755 management-dashboard-web-app/API Documentations/docs/legacy/VIDEO_RECORDER_README.md create mode 100755 management-dashboard-web-app/CAMERA_ROUTE_IMPLEMENTATION.md mode change 100644 => 100755 management-dashboard-web-app/README.md mode change 100644 => 100755 management-dashboard-web-app/VISION_SYSTEM_README.md mode change 100644 => 100755 management-dashboard-web-app/api-endpoints.http mode change 100644 => 100755 management-dashboard-web-app/docs/AUTO_RECORDING_SETUP.md mode change 100644 => 100755 management-dashboard-web-app/docs/MODULAR_ARCHITECTURE_GUIDE.md mode change 100644 => 100755 management-dashboard-web-app/docs/MP4_FRONTEND_IMPLEMENTATION_STATUS.md mode change 100644 => 100755 management-dashboard-web-app/docs/VIDEO_STREAMING_INTEGRATION.md mode change 100644 => 100755 management-dashboard-web-app/docs/VIDEO_STREAMING_INTEGRATION_COMPLETE.md mode change 100644 => 100755 management-dashboard-web-app/eslint.config.js mode change 100644 => 100755 management-dashboard-web-app/index.html mode change 100644 => 100755 management-dashboard-web-app/package-lock.json mode change 100644 => 100755 management-dashboard-web-app/package.json mode change 100644 => 100755 management-dashboard-web-app/phase_2_experimental_run_sheet.csv create mode 100755 management-dashboard-web-app/public/camera-test.html mode change 100644 => 100755 management-dashboard-web-app/public/vite.svg mode change 100644 => 100755 management-dashboard-web-app/src/App.css mode change 100644 => 100755 management-dashboard-web-app/src/App.tsx mode change 100644 => 100755 management-dashboard-web-app/src/assets/react.svg mode change 100644 => 100755 management-dashboard-web-app/src/components/AutoRecordingStatus.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/AutoRecordingTest.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/CameraConfigModal.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/CameraPreviewModal.tsx create mode 100755 management-dashboard-web-app/src/components/CameraRoute.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/CreateUserModal.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/Dashboard.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/DashboardHome.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/DashboardLayout.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/DataEntry.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/DataEntryInterface.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/DraftManager.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/ExperimentForm.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/ExperimentModal.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/Experiments.tsx create mode 100755 management-dashboard-web-app/src/components/LiveCameraView.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/Login.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/PhaseDataEntry.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/PhaseDraftManager.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/PhaseSelector.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/RepetitionDataEntryInterface.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/RepetitionLockManager.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/RepetitionPhaseSelector.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/RepetitionScheduleModal.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/ScheduleModal.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/Sidebar.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/TopNavbar.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/UserManagement.tsx mode change 100644 => 100755 management-dashboard-web-app/src/components/VisionSystem.tsx mode change 100644 => 100755 management-dashboard-web-app/src/features/video-streaming/VideoStreamingPage.tsx mode change 100644 => 100755 management-dashboard-web-app/src/features/video-streaming/components/ApiStatusIndicator.tsx mode change 100644 => 100755 management-dashboard-web-app/src/features/video-streaming/components/Pagination.tsx mode change 100644 => 100755 management-dashboard-web-app/src/features/video-streaming/components/PerformanceDashboard.tsx mode change 100644 => 100755 management-dashboard-web-app/src/features/video-streaming/components/VideoCard.tsx mode change 100644 => 100755 management-dashboard-web-app/src/features/video-streaming/components/VideoDebugger.tsx mode change 100644 => 100755 management-dashboard-web-app/src/features/video-streaming/components/VideoErrorBoundary.tsx mode change 100644 => 100755 management-dashboard-web-app/src/features/video-streaming/components/VideoList.tsx mode change 100644 => 100755 management-dashboard-web-app/src/features/video-streaming/components/VideoModal.tsx mode change 100644 => 100755 management-dashboard-web-app/src/features/video-streaming/components/VideoPlayer.tsx mode change 100644 => 100755 management-dashboard-web-app/src/features/video-streaming/components/VideoThumbnail.tsx mode change 100644 => 100755 management-dashboard-web-app/src/features/video-streaming/components/index.ts mode change 100644 => 100755 management-dashboard-web-app/src/features/video-streaming/hooks/index.ts mode change 100644 => 100755 management-dashboard-web-app/src/features/video-streaming/hooks/useVideoInfo.ts mode change 100644 => 100755 management-dashboard-web-app/src/features/video-streaming/hooks/useVideoList.ts mode change 100644 => 100755 management-dashboard-web-app/src/features/video-streaming/hooks/useVideoPlayer.ts mode change 100644 => 100755 management-dashboard-web-app/src/features/video-streaming/index.ts mode change 100644 => 100755 management-dashboard-web-app/src/features/video-streaming/services/videoApi.ts mode change 100644 => 100755 management-dashboard-web-app/src/features/video-streaming/types/index.ts mode change 100644 => 100755 management-dashboard-web-app/src/features/video-streaming/utils/index.ts mode change 100644 => 100755 management-dashboard-web-app/src/features/video-streaming/utils/performanceMonitor.ts mode change 100644 => 100755 management-dashboard-web-app/src/features/video-streaming/utils/thumbnailCache.ts mode change 100644 => 100755 management-dashboard-web-app/src/features/video-streaming/utils/videoUtils.ts mode change 100644 => 100755 management-dashboard-web-app/src/hooks/useAuth.ts mode change 100644 => 100755 management-dashboard-web-app/src/hooks/useAutoRecording.ts mode change 100644 => 100755 management-dashboard-web-app/src/index.css mode change 100644 => 100755 management-dashboard-web-app/src/lib/autoRecordingManager.ts mode change 100644 => 100755 management-dashboard-web-app/src/lib/supabase.ts mode change 100644 => 100755 management-dashboard-web-app/src/lib/visionApi.ts mode change 100644 => 100755 management-dashboard-web-app/src/main.tsx mode change 100644 => 100755 management-dashboard-web-app/src/test/videoStreamingTest.ts mode change 100644 => 100755 management-dashboard-web-app/src/test/visionApi.test.ts mode change 100644 => 100755 management-dashboard-web-app/src/utils/videoFileUtils.ts mode change 100644 => 100755 management-dashboard-web-app/src/vite-env.d.ts mode change 100644 => 100755 management-dashboard-web-app/supabase/.gitignore mode change 100644 => 100755 management-dashboard-web-app/supabase/.temp/cli-latest mode change 100644 => 100755 management-dashboard-web-app/supabase/config.toml mode change 100644 => 100755 management-dashboard-web-app/supabase/migrations/20250719000001_rbac_schema.sql mode change 100644 => 100755 management-dashboard-web-app/supabase/migrations/20250719000002_rls_policies.sql mode change 100644 => 100755 management-dashboard-web-app/supabase/migrations/20250719000003_seed_admin_user.sql mode change 100644 => 100755 management-dashboard-web-app/supabase/migrations/20250720000001_multiple_roles_support.sql mode change 100644 => 100755 management-dashboard-web-app/supabase/migrations/20250720000002_fix_role_id_constraint.sql mode change 100644 => 100755 management-dashboard-web-app/supabase/migrations/20250720000003_experiments_table.sql mode change 100644 => 100755 management-dashboard-web-app/supabase/migrations/20250721000001_add_scheduled_date.sql mode change 100644 => 100755 management-dashboard-web-app/supabase/migrations/20250724000001_experiment_repetitions_system.sql mode change 100644 => 100755 management-dashboard-web-app/supabase/migrations/20250725000001_experiment_data_entry_system.sql mode change 100644 => 100755 management-dashboard-web-app/supabase/migrations/20250725000003_fix_draft_constraints.sql mode change 100644 => 100755 management-dashboard-web-app/supabase/migrations/20250728000001_fix_repetitions_visibility.sql mode change 100644 => 100755 management-dashboard-web-app/supabase/seed.sql mode change 100644 => 100755 management-dashboard-web-app/tailwind.config.js mode change 100644 => 100755 management-dashboard-web-app/test-api-fix.js mode change 100644 => 100755 management-dashboard-web-app/test-camera-config.html mode change 100644 => 100755 management-dashboard-web-app/test-stop-streaming.html mode change 100644 => 100755 management-dashboard-web-app/tsconfig.app.json mode change 100644 => 100755 management-dashboard-web-app/tsconfig.json mode change 100644 => 100755 management-dashboard-web-app/tsconfig.node.json mode change 100644 => 100755 management-dashboard-web-app/vite.config.ts diff --git a/camera-management-api/usda_vision_system/api/server.py b/camera-management-api/usda_vision_system/api/server.py index d9d25df..7adcc26 100644 --- a/camera-management-api/usda_vision_system/api/server.py +++ b/camera-management-api/usda_vision_system/api/server.py @@ -688,6 +688,29 @@ class APIServer: except Exception as e: self.logger.error(f"Failed to add video routes: {e}") + @self.app.get("/debug/camera-manager") + async def debug_camera_manager(): + """Debug endpoint to check camera manager state""" + try: + if not self.camera_manager: + return {"error": "Camera manager not available"} + + return { + "available_cameras": len(self.camera_manager.available_cameras), + "camera_recorders": list(self.camera_manager.camera_recorders.keys()), + "camera_streamers": list(self.camera_manager.camera_streamers.keys()), + "streamer_states": { + name: { + "exists": streamer is not None, + "is_streaming": streamer.is_streaming() if streamer else False, + "streaming": getattr(streamer, 'streaming', False) if streamer else False + } + for name, streamer in self.camera_manager.camera_streamers.items() + } + } + except Exception as e: + return {"error": str(e)} + def _setup_event_subscriptions(self): """Setup event subscriptions for WebSocket broadcasting""" diff --git a/camera-management-api/usda_vision_system/camera/manager.py b/camera-management-api/usda_vision_system/camera/manager.py index fac36ef..8886493 100644 --- a/camera-management-api/usda_vision_system/camera/manager.py +++ b/camera-management-api/usda_vision_system/camera/manager.py @@ -460,12 +460,16 @@ class CameraManager: def _initialize_streamers(self) -> None: """Initialize camera streamers for configured cameras""" + self.logger.info("Starting camera streamer initialization...") with self._lock: for camera_config in self.config.cameras: if not camera_config.enabled: + self.logger.debug(f"Skipping disabled camera: {camera_config.name}") continue try: + self.logger.info(f"Initializing streamer for camera: {camera_config.name}") + # Find matching physical camera device_info = self._find_camera_device(camera_config.name) if device_info is None: @@ -481,6 +485,10 @@ class CameraManager: except Exception as e: self.logger.error(f"Error initializing streamer for {camera_config.name}: {e}") + import traceback + self.logger.error(f"Traceback: {traceback.format_exc()}") + + self.logger.info(f"Camera streamer initialization complete. Created {len(self.camera_streamers)} streamers: {list(self.camera_streamers.keys())}") def get_camera_streamer(self, camera_name: str) -> Optional[CameraStreamer]: """Get camera streamer for a specific camera""" diff --git a/camera-management-api/usda_vision_system/camera/monitor.py b/camera-management-api/usda_vision_system/camera/monitor.py index 71fac9f..9107537 100644 --- a/camera-management-api/usda_vision_system/camera/monitor.py +++ b/camera-management-api/usda_vision_system/camera/monitor.py @@ -172,14 +172,37 @@ class CameraMonitor: if not device_info: return "disconnected", "Camera device not found", None + # ALWAYS check our streamer state first, before doing any camera availability tests + streamer = self.camera_manager.camera_streamers.get(camera_name) + self.logger.info(f"Checking streamer for {camera_name}: {streamer}") + if streamer and streamer.is_streaming(): + self.logger.info(f"Camera {camera_name} is streaming - setting status to streaming") + return "streaming", "Camera streaming (live preview)", self._get_device_info_dict(device_info) + + # Also check if our recorder is active + recorder = self.camera_manager.camera_recorders.get(camera_name) + if recorder and recorder.hCamera and recorder.recording: + self.logger.info(f"Camera {camera_name} is recording - setting status to available") + return "available", "Camera recording (in use by system)", self._get_device_info_dict(device_info) + # Check if camera is already opened by another process - if mvsdk.CameraIsOpened(device_info): - # Camera is opened - check if it's our recorder that's currently recording - recorder = self.camera_manager.camera_recorders.get(camera_name) - if recorder and recorder.hCamera and recorder.recording: - return "available", "Camera recording (in use by system)", self._get_device_info_dict(device_info) - else: + try: + self.logger.info(f"Checking if camera {camera_name} is opened...") + is_opened = mvsdk.CameraIsOpened(device_info) + self.logger.info(f"CameraIsOpened result for {camera_name}: {is_opened}") + + if is_opened: + self.logger.info(f"Camera {camera_name} is opened by another process - setting status to busy") return "busy", "Camera opened by another process", self._get_device_info_dict(device_info) + else: + self.logger.info(f"Camera {camera_name} is not opened, will try initialization") + # Camera is not opened, so we can try to initialize it + pass + + except Exception as e: + self.logger.warning(f"CameraIsOpened failed for {camera_name}: {e}") + # If we can't determine the status, try to initialize to see what happens + self.logger.info(f"CameraIsOpened failed for {camera_name}, will try initialization: {e}") # Try to initialize camera briefly to test availability try: diff --git a/camera-management-api/usda_vision_system/core/state_manager.py b/camera-management-api/usda_vision_system/core/state_manager.py index 5683d22..9482d05 100644 --- a/camera-management-api/usda_vision_system/core/state_manager.py +++ b/camera-management-api/usda_vision_system/core/state_manager.py @@ -28,6 +28,7 @@ class CameraStatus(Enum): UNKNOWN = "unknown" AVAILABLE = "available" BUSY = "busy" + STREAMING = "streaming" # New status for when camera is streaming ERROR = "error" DISCONNECTED = "disconnected" diff --git a/docker-compose.yml b/docker-compose.yml index 6cee373..c11aae9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -45,6 +45,8 @@ services: web: image: node:20-alpine working_dir: /app + env_file: + - ./management-dashboard-web-app/.env volumes: - ./management-dashboard-web-app:/app environment: diff --git a/management-dashboard-web-app/.env.example b/management-dashboard-web-app/.env.example old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/.gitignore b/management-dashboard-web-app/.gitignore old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/.vscode/extensions.json b/management-dashboard-web-app/.vscode/extensions.json old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/API Documentations/docs/AI_AGENT_VIDEO_INTEGRATION_GUIDE.md b/management-dashboard-web-app/API Documentations/docs/AI_AGENT_VIDEO_INTEGRATION_GUIDE.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/API Documentations/docs/API_CHANGES_SUMMARY.md b/management-dashboard-web-app/API Documentations/docs/API_CHANGES_SUMMARY.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/API Documentations/docs/API_DOCUMENTATION.md b/management-dashboard-web-app/API Documentations/docs/API_DOCUMENTATION.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/API Documentations/docs/API_QUICK_REFERENCE.md b/management-dashboard-web-app/API Documentations/docs/API_QUICK_REFERENCE.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/API Documentations/docs/CURRENT_CONFIGURATION.md b/management-dashboard-web-app/API Documentations/docs/CURRENT_CONFIGURATION.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/API Documentations/docs/MP4_FORMAT_UPDATE.md b/management-dashboard-web-app/API Documentations/docs/MP4_FORMAT_UPDATE.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/API Documentations/docs/PROJECT_COMPLETE.md b/management-dashboard-web-app/API Documentations/docs/PROJECT_COMPLETE.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/API Documentations/docs/REACT_INTEGRATION_GUIDE.md b/management-dashboard-web-app/API Documentations/docs/REACT_INTEGRATION_GUIDE.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/API Documentations/docs/README.md b/management-dashboard-web-app/API Documentations/docs/README.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/API Documentations/docs/VIDEO_STREAMING.md b/management-dashboard-web-app/API Documentations/docs/VIDEO_STREAMING.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/API Documentations/docs/WEB_AI_AGENT_VIDEO_INTEGRATION.md b/management-dashboard-web-app/API Documentations/docs/WEB_AI_AGENT_VIDEO_INTEGRATION.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/API Documentations/docs/api/CAMERA_CONFIG_API.md b/management-dashboard-web-app/API Documentations/docs/api/CAMERA_CONFIG_API.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/API Documentations/docs/camera/BLOWER_CAMERA_CONFIG.md b/management-dashboard-web-app/API Documentations/docs/camera/BLOWER_CAMERA_CONFIG.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/API Documentations/docs/camera/CONVEYOR_CAMERA_CONFIG.md b/management-dashboard-web-app/API Documentations/docs/camera/CONVEYOR_CAMERA_CONFIG.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/API Documentations/docs/camera/PREVIEW_ENHANCEMENT.md b/management-dashboard-web-app/API Documentations/docs/camera/PREVIEW_ENHANCEMENT.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/API Documentations/docs/features/AUTO_RECORDING_FEATURE_GUIDE.md b/management-dashboard-web-app/API Documentations/docs/features/AUTO_RECORDING_FEATURE_GUIDE.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/API Documentations/docs/guides/CAMERA_RECOVERY_GUIDE.md b/management-dashboard-web-app/API Documentations/docs/guides/CAMERA_RECOVERY_GUIDE.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/API Documentations/docs/guides/MQTT_LOGGING_GUIDE.md b/management-dashboard-web-app/API Documentations/docs/guides/MQTT_LOGGING_GUIDE.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/API Documentations/docs/guides/STREAMING_GUIDE.md b/management-dashboard-web-app/API Documentations/docs/guides/STREAMING_GUIDE.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/API Documentations/docs/legacy/01README.md b/management-dashboard-web-app/API Documentations/docs/legacy/01README.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/API Documentations/docs/legacy/IMPLEMENTATION_SUMMARY.md b/management-dashboard-web-app/API Documentations/docs/legacy/IMPLEMENTATION_SUMMARY.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/API Documentations/docs/legacy/README.md b/management-dashboard-web-app/API Documentations/docs/legacy/README.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/API Documentations/docs/legacy/README_SYSTEM.md b/management-dashboard-web-app/API Documentations/docs/legacy/README_SYSTEM.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/API Documentations/docs/legacy/TIMEZONE_SETUP_SUMMARY.md b/management-dashboard-web-app/API Documentations/docs/legacy/TIMEZONE_SETUP_SUMMARY.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/API Documentations/docs/legacy/VIDEO_RECORDER_README.md b/management-dashboard-web-app/API Documentations/docs/legacy/VIDEO_RECORDER_README.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/CAMERA_ROUTE_IMPLEMENTATION.md b/management-dashboard-web-app/CAMERA_ROUTE_IMPLEMENTATION.md new file mode 100755 index 0000000..4859e11 --- /dev/null +++ b/management-dashboard-web-app/CAMERA_ROUTE_IMPLEMENTATION.md @@ -0,0 +1,210 @@ +# ๐ŸŽฅ Camera Route Implementation Guide + +This document explains the implementation of the new public camera live view routes (`/camera#/live`) that don't require authentication. + +## ๐Ÿš€ What Was Implemented + +### 1. **LiveCameraView Component** (`src/components/LiveCameraView.tsx`) +- Displays live camera feed without authentication requirements +- Handles streaming start/stop automatically +- Provides error handling and loading states +- Full-screen live view with camera label and status indicator + +### 2. **CameraRoute Component** (`src/components/CameraRoute.tsx`) +- Validates camera route parameters +- Ensures only valid camera numbers (camera1, camera2, etc.) are accepted +- Renders the LiveCameraView for valid routes + +### 3. **Updated App.tsx** +- Added route pattern matching for `/camera#/live` +- Integrated camera routes into existing authentication flow +- Maintains backward compatibility with existing functionality + +### 4. **Test Page** (`public/camera-test.html`) +- Simple HTML page to test camera routes +- Provides links to test different camera numbers +- Explains expected behavior + +## ๐Ÿ“‹ Required Dependencies + +The following packages need to be installed to complete the implementation: + +```bash +# Install React Router +npm install react-router-dom + +# Install TypeScript types +npm install --save-dev @types/react-router-dom +``` + +**Note:** Due to permission issues, these packages couldn't be installed automatically. You'll need to resolve the permissions or install them manually. + +## ๐Ÿ”ง How to Complete the Setup + +### Option 1: Fix Permissions and Install +```bash +# Fix node_modules permissions +sudo chown -R $USER:$USER node_modules +sudo chmod -R 755 node_modules + +# Install dependencies +npm install +``` + +### Option 2: Manual Installation +```bash +# Remove problematic node_modules +rm -rf node_modules + +# Reinstall everything +npm install +``` + +### Option 3: Use Yarn Instead +```bash +# Install yarn if not available +npm install -g yarn + +# Install dependencies with yarn +yarn install +``` + +## ๐Ÿงช Testing the Implementation + +### 1. **Start the Development Server** +```bash +npm run dev +``` + +### 2. **Test Camera Routes** +Open these URLs in your browser: +- `http://localhost:5173/camera1/live` - Live view of camera1 +- `http://localhost:5173/camera2/live` - Live view of camera2 +- `http://localhost:5173/camera3/live` - Live view of camera3 + +### 3. **Use the Test Page** +Open `http://localhost:5173/camera-test.html` to access the test interface. + +### 4. **Expected Behavior** +- โœ… **Valid routes** should show live camera feed +- โŒ **Invalid routes** should show error message +- ๐Ÿ”’ **Protected routes** should redirect to login + +## ๐Ÿ—๏ธ Architecture Details + +### Route Pattern +``` +/camera{number}/live +``` +- `{number}` must be a positive integer +- Examples: `/camera1/live`, `/camera2/live`, `/camera10/live` +- Invalid: `/camera/live`, `/camera0/live`, `/camera-1/live` + +### Component Flow +``` +App.tsx โ†’ Route Detection โ†’ CameraRoute โ†’ LiveCameraView +``` + +### API Integration +The LiveCameraView component integrates with existing camera API endpoints: +- `POST /cameras/{camera_name}/start-stream` - Start streaming +- `GET /cameras/{camera_name}/stream` - Get MJPEG stream +- `POST /cameras/{camera_name}/stop-stream` - Stop streaming + +## ๐ŸŽฏ Key Features + +### โœ… **Public Access** +- No authentication required +- Anyone can view live camera feeds +- Perfect for monitoring displays + +### โœ… **Non-Blocking Streaming** +- Uses existing CameraStreamer infrastructure +- Separate camera connections for streaming vs. recording +- Doesn't interfere with recording operations + +### โœ… **Real-time Video** +- MJPEG format for low latency +- Automatic stream management +- Error handling and retry functionality + +### โœ… **Responsive Design** +- Full-screen live view +- Camera identification labels +- Live status indicators + +## ๐Ÿ” Troubleshooting + +### Common Issues + +#### 1. **Permission Errors During Installation** +```bash +# Fix ownership +sudo chown -R $USER:$USER . + +# Fix permissions +sudo chmod -R 755 . +``` + +#### 2. **Camera Stream Not Loading** +- Check if camera API is running (`http://localhost:8000`) +- Verify camera configuration in `config.compose.json` +- Check browser console for errors + +#### 3. **Route Not Working** +- Ensure React app is running +- Check browser console for routing errors +- Verify component imports are correct + +#### 4. **TypeScript Errors** +- Install missing type definitions +- Check import paths +- Verify component interfaces + +### Debug Steps +1. Check browser console for errors +2. Verify API endpoints are accessible +3. Test camera streaming directly via API +4. Check component rendering in React DevTools + +## ๐Ÿš€ Next Steps + +### Immediate +1. Install required dependencies +2. Test basic functionality +3. Verify camera streaming works + +### Future Enhancements +1. **Add React Router** for better routing +2. **Implement URL-based navigation** between cameras +3. **Add camera selection interface** +4. **Implement stream quality controls** +5. **Add recording controls** (if needed) + +### Production Considerations +1. **Security**: Consider adding rate limiting +2. **Performance**: Optimize for multiple concurrent viewers +3. **Monitoring**: Add analytics and usage tracking +4. **Access Control**: Implement optional authentication if needed + +## ๐Ÿ“š Related Documentation + +- [Camera API Documentation](../camera-management-api/docs/API_DOCUMENTATION.md) +- [Streaming Guide](../camera-management-api/docs/guides/STREAMING_GUIDE.md) +- [Vision System README](VISION_SYSTEM_README.md) + +## ๐Ÿค Support + +If you encounter issues: +1. Check the troubleshooting section above +2. Review browser console for error messages +3. Verify camera API is running and accessible +4. Test API endpoints directly with curl or Postman + +--- + +**Implementation Status**: โœ… Components Created | โš ๏ธ Dependencies Pending | ๏ฟฝ๏ฟฝ Ready for Testing + + + + diff --git a/management-dashboard-web-app/README.md b/management-dashboard-web-app/README.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/VISION_SYSTEM_README.md b/management-dashboard-web-app/VISION_SYSTEM_README.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/api-endpoints.http b/management-dashboard-web-app/api-endpoints.http old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/docs/AUTO_RECORDING_SETUP.md b/management-dashboard-web-app/docs/AUTO_RECORDING_SETUP.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/docs/MODULAR_ARCHITECTURE_GUIDE.md b/management-dashboard-web-app/docs/MODULAR_ARCHITECTURE_GUIDE.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/docs/MP4_FRONTEND_IMPLEMENTATION_STATUS.md b/management-dashboard-web-app/docs/MP4_FRONTEND_IMPLEMENTATION_STATUS.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/docs/VIDEO_STREAMING_INTEGRATION.md b/management-dashboard-web-app/docs/VIDEO_STREAMING_INTEGRATION.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/docs/VIDEO_STREAMING_INTEGRATION_COMPLETE.md b/management-dashboard-web-app/docs/VIDEO_STREAMING_INTEGRATION_COMPLETE.md old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/eslint.config.js b/management-dashboard-web-app/eslint.config.js old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/index.html b/management-dashboard-web-app/index.html old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/package-lock.json b/management-dashboard-web-app/package-lock.json old mode 100644 new mode 100755 index b41d8d3..d20e905 --- a/management-dashboard-web-app/package-lock.json +++ b/management-dashboard-web-app/package-lock.json @@ -13,19 +13,21 @@ "@tailwindcss/vite": "^4.1.11", "react": "^19.1.0", "react-dom": "^19.1.0", + "react-router-dom": "^6.28.0", "tailwindcss": "^4.1.11" }, "devDependencies": { "@eslint/js": "^9.30.1", "@types/react": "^19.1.8", "@types/react-dom": "^19.1.6", + "@types/react-router-dom": "^5.3.3", "@vitejs/plugin-react": "^4.6.0", "eslint": "^9.30.1", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.20", "globals": "^16.3.0", "typescript": "~5.8.3", - "typescript-eslint": "^8.35.1", + "typescript-eslint": "^8.28.1", "vite": "^7.0.4" } }, @@ -1054,6 +1056,15 @@ "node": ">= 8" } }, + "node_modules/@remix-run/router": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.0.tgz", + "integrity": "sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-beta.19", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.19.tgz", @@ -1709,6 +1720,13 @@ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "license": "MIT" }, + "node_modules/@types/history": { + "version": "4.7.11", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", + "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -1751,6 +1769,29 @@ "@types/react": "^19.0.0" } }, + "node_modules/@types/react-router": { + "version": "5.1.20", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", + "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*" + } + }, + "node_modules/@types/react-router-dom": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", + "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "*" + } + }, "node_modules/@types/ws": { "version": "8.18.1", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", @@ -3562,6 +3603,38 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.30.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.1.tgz", + "integrity": "sha512-X1m21aEmxGXqENEPG3T6u0Th7g0aS4ZmoNynhbs+Cn+q+QGTLt+d5IQ2bHAXKzKcxGJjxACpVbnYQSCRcfxHlQ==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.23.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.30.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.1.tgz", + "integrity": "sha512-llKsgOkZdbPU1Eg3zK8lCn+sjD9wMRZZPuzmdWWX5SUs8OFkN5HnFVC0u5KMeMaC9aoancFI/KoLuKPqN+hxHw==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.23.0", + "react-router": "6.30.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", diff --git a/management-dashboard-web-app/package.json b/management-dashboard-web-app/package.json old mode 100644 new mode 100755 index 2110d3d..fb0ccb7 --- a/management-dashboard-web-app/package.json +++ b/management-dashboard-web-app/package.json @@ -6,7 +6,7 @@ "scripts": { "dev": "vite", "build": "tsc -b && vite build", - "lint": "eslint .", + "lint": "eslint", "preview": "vite preview" }, "dependencies": { @@ -15,19 +15,21 @@ "@tailwindcss/vite": "^4.1.11", "react": "^19.1.0", "react-dom": "^19.1.0", + "react-router-dom": "^6.28.0", "tailwindcss": "^4.1.11" }, "devDependencies": { "@eslint/js": "^9.30.1", "@types/react": "^19.1.8", "@types/react-dom": "^19.1.6", + "@types/react-router-dom": "^5.3.3", "@vitejs/plugin-react": "^4.6.0", "eslint": "^9.30.1", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.20", "globals": "^16.3.0", "typescript": "~5.8.3", - "typescript-eslint": "^8.35.1", + "typescript-eslint": "^8.28.1", "vite": "^7.0.4" } -} +} \ No newline at end of file diff --git a/management-dashboard-web-app/phase_2_experimental_run_sheet.csv b/management-dashboard-web-app/phase_2_experimental_run_sheet.csv old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/public/camera-test.html b/management-dashboard-web-app/public/camera-test.html new file mode 100755 index 0000000..faaf55a --- /dev/null +++ b/management-dashboard-web-app/public/camera-test.html @@ -0,0 +1,119 @@ + + + + + + + Camera Route Test + + + + +

๐ŸŽฅ Camera Route Test

+ +
+

Test the New Camera Routes

+

This page helps you test the new camera live view routes that don't require authentication.

+

Note: Make sure the React app is running and the camera API is accessible.

+
+ + + +
+

Expected Behavior

+ +
+ +
+

API Endpoints

+

The camera routes use these backend API endpoints:

+ +
+ + + + + + + + diff --git a/management-dashboard-web-app/public/vite.svg b/management-dashboard-web-app/public/vite.svg old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/App.css b/management-dashboard-web-app/src/App.css old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/App.tsx b/management-dashboard-web-app/src/App.tsx old mode 100644 new mode 100755 index e8cf843..457fbf5 --- a/management-dashboard-web-app/src/App.tsx +++ b/management-dashboard-web-app/src/App.tsx @@ -2,6 +2,7 @@ import { useState, useEffect } from 'react' import { supabase } from './lib/supabase' import { Login } from './components/Login' import { Dashboard } from './components/Dashboard' +import { CameraRoute } from './components/CameraRoute' function App() { const [isAuthenticated, setIsAuthenticated] = useState(null) @@ -84,6 +85,18 @@ function App() { } } + // Check if current route is a camera live route + const isCameraLiveRoute = (route: string) => { + const cameraRoutePattern = /^\/camera(\d+)\/live$/ + return cameraRoutePattern.test(route) + } + + // Extract camera number from route + const getCameraNumber = (route: string) => { + const match = route.match(/^\/camera(\d+)\/live$/) + return match ? `camera${match[1]}` : null + } + if (loading) { return (
@@ -107,6 +120,14 @@ function App() { ) } + // Handle camera live routes (no authentication required) + if (isCameraLiveRoute(currentRoute)) { + const cameraNumber = getCameraNumber(currentRoute) + if (cameraNumber) { + return + } + } + return ( <> {isAuthenticated ? ( diff --git a/management-dashboard-web-app/src/assets/react.svg b/management-dashboard-web-app/src/assets/react.svg old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/AutoRecordingStatus.tsx b/management-dashboard-web-app/src/components/AutoRecordingStatus.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/AutoRecordingTest.tsx b/management-dashboard-web-app/src/components/AutoRecordingTest.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/CameraConfigModal.tsx b/management-dashboard-web-app/src/components/CameraConfigModal.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/CameraPreviewModal.tsx b/management-dashboard-web-app/src/components/CameraPreviewModal.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/CameraRoute.tsx b/management-dashboard-web-app/src/components/CameraRoute.tsx new file mode 100755 index 0000000..b4fba33 --- /dev/null +++ b/management-dashboard-web-app/src/components/CameraRoute.tsx @@ -0,0 +1,25 @@ +import { LiveCameraView } from './LiveCameraView' + +interface CameraRouteProps { + cameraNumber: string +} + +export function CameraRoute({ cameraNumber }: CameraRouteProps) { + // Validate camera number (only allow camera1, camera2, etc.) + if (!cameraNumber || !/^camera\d+$/.test(cameraNumber)) { + return ( +
+
+

Invalid Camera

+

Camera number must be in format: camera1, camera2, etc.

+
+
+ ) + } + + return +} + + + + diff --git a/management-dashboard-web-app/src/components/CreateUserModal.tsx b/management-dashboard-web-app/src/components/CreateUserModal.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/Dashboard.tsx b/management-dashboard-web-app/src/components/Dashboard.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/DashboardHome.tsx b/management-dashboard-web-app/src/components/DashboardHome.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/DashboardLayout.tsx b/management-dashboard-web-app/src/components/DashboardLayout.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/DataEntry.tsx b/management-dashboard-web-app/src/components/DataEntry.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/DataEntryInterface.tsx b/management-dashboard-web-app/src/components/DataEntryInterface.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/DraftManager.tsx b/management-dashboard-web-app/src/components/DraftManager.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/ExperimentForm.tsx b/management-dashboard-web-app/src/components/ExperimentForm.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/ExperimentModal.tsx b/management-dashboard-web-app/src/components/ExperimentModal.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/Experiments.tsx b/management-dashboard-web-app/src/components/Experiments.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/LiveCameraView.tsx b/management-dashboard-web-app/src/components/LiveCameraView.tsx new file mode 100755 index 0000000..2a8038e --- /dev/null +++ b/management-dashboard-web-app/src/components/LiveCameraView.tsx @@ -0,0 +1,134 @@ +import { useState, useEffect, useRef } from 'react' + +interface LiveCameraViewProps { + cameraName: string +} + +export function LiveCameraView({ cameraName }: LiveCameraViewProps) { + const [isStreaming, setIsStreaming] = useState(false) + const [error, setError] = useState(null) + const [loading, setLoading] = useState(true) + const imgRef = useRef(null) + + const API_BASE = import.meta.env.VITE_VISION_API_URL || 'http://localhost:8000' + + useEffect(() => { + startStreaming() + return () => stopStreaming() + }, [cameraName]) + + const startStreaming = async () => { + try { + setLoading(true) + setError(null) + + // Start the stream + const response = await fetch(`${API_BASE}/cameras/${cameraName}/start-stream`, { + method: 'POST' + }) + + if (response.ok) { + setIsStreaming(true) + // Set the stream source with timestamp to prevent caching + if (imgRef.current) { + imgRef.current.src = `${API_BASE}/cameras/${cameraName}/stream?t=${Date.now()}` + } + } else { + throw new Error(`Failed to start stream: ${response.statusText}`) + } + } catch (err) { + const errorMessage = err instanceof Error ? err.message : 'Failed to start stream' + setError(errorMessage) + } finally { + setLoading(false) + } + } + + const stopStreaming = async () => { + try { + if (isStreaming) { + await fetch(`${API_BASE}/cameras/${cameraName}/stop-stream`, { + method: 'POST' + }) + setIsStreaming(false) + } + } catch (err) { + console.error('Error stopping stream:', err) + } + } + + const handleImageError = () => { + setError('Failed to load camera stream') + } + + const handleImageLoad = () => { + setError(null) + } + + if (loading) { + return ( +
+
+
+

Starting camera stream...

+
+
+ ) + } + + if (error) { + return ( +
+
+
+ + + +
+

Stream Error

+

{error}

+ +
+
+ ) + } + + return ( +
+
+ {/* Camera Label */} +
+
+ {cameraName} - Live View +
+
+ + {/* Live Stream */} + {`Live + + {/* Status Indicator */} +
+
+
+ LIVE +
+
+
+
+ ) +} + + + + diff --git a/management-dashboard-web-app/src/components/Login.tsx b/management-dashboard-web-app/src/components/Login.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/PhaseDataEntry.tsx b/management-dashboard-web-app/src/components/PhaseDataEntry.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/PhaseDraftManager.tsx b/management-dashboard-web-app/src/components/PhaseDraftManager.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/PhaseSelector.tsx b/management-dashboard-web-app/src/components/PhaseSelector.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/RepetitionDataEntryInterface.tsx b/management-dashboard-web-app/src/components/RepetitionDataEntryInterface.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/RepetitionLockManager.tsx b/management-dashboard-web-app/src/components/RepetitionLockManager.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/RepetitionPhaseSelector.tsx b/management-dashboard-web-app/src/components/RepetitionPhaseSelector.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/RepetitionScheduleModal.tsx b/management-dashboard-web-app/src/components/RepetitionScheduleModal.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/ScheduleModal.tsx b/management-dashboard-web-app/src/components/ScheduleModal.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/Sidebar.tsx b/management-dashboard-web-app/src/components/Sidebar.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/TopNavbar.tsx b/management-dashboard-web-app/src/components/TopNavbar.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/UserManagement.tsx b/management-dashboard-web-app/src/components/UserManagement.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/components/VisionSystem.tsx b/management-dashboard-web-app/src/components/VisionSystem.tsx old mode 100644 new mode 100755 index eb000ab..393f5a0 --- a/management-dashboard-web-app/src/components/VisionSystem.tsx +++ b/management-dashboard-web-app/src/components/VisionSystem.tsx @@ -196,9 +196,10 @@ const CamerasStatus = memo(({ const hasSerial = !!camera.device_info?.serial_number // Determine if camera is connected based on status - const isConnected = camera.status === 'available' || camera.status === 'connected' + const isConnected = camera.status === 'available' || camera.status === 'connected' || camera.status === 'streaming' const hasError = camera.status === 'error' const statusText = camera.status || 'unknown' + const isStreaming = camera.status === 'streaming' return (
@@ -209,11 +210,12 @@ const CamerasStatus = memo(({ ({cameraName}) )} -
- {isConnected ? 'Connected' : hasError ? 'Error' : 'Disconnected'} + {isStreaming ? 'Streaming' : isConnected ? 'Connected' : hasError ? 'Error' : 'Disconnected'}
@@ -224,7 +226,8 @@ const CamerasStatus = memo(({ hasError ? 'text-yellow-600' : 'text-red-600' }`}> - {statusText.charAt(0).toUpperCase() + statusText.slice(1)} + {isStreaming ? 'Streaming' : + statusText.charAt(0).toUpperCase() + statusText.slice(1)}
@@ -238,6 +241,16 @@ const CamerasStatus = memo(({ )} + {isStreaming && ( +
+ Streaming: + +
+ Live +
+
+ )} + {hasDeviceInfo && ( <> {camera.device_info.model && ( @@ -923,7 +936,7 @@ export function VisionSystem() { {/* Notification */} {notification && ( -
diff --git a/management-dashboard-web-app/src/features/video-streaming/VideoStreamingPage.tsx b/management-dashboard-web-app/src/features/video-streaming/VideoStreamingPage.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/features/video-streaming/components/ApiStatusIndicator.tsx b/management-dashboard-web-app/src/features/video-streaming/components/ApiStatusIndicator.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/features/video-streaming/components/Pagination.tsx b/management-dashboard-web-app/src/features/video-streaming/components/Pagination.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/features/video-streaming/components/PerformanceDashboard.tsx b/management-dashboard-web-app/src/features/video-streaming/components/PerformanceDashboard.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/features/video-streaming/components/VideoCard.tsx b/management-dashboard-web-app/src/features/video-streaming/components/VideoCard.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/features/video-streaming/components/VideoDebugger.tsx b/management-dashboard-web-app/src/features/video-streaming/components/VideoDebugger.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/features/video-streaming/components/VideoErrorBoundary.tsx b/management-dashboard-web-app/src/features/video-streaming/components/VideoErrorBoundary.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/features/video-streaming/components/VideoList.tsx b/management-dashboard-web-app/src/features/video-streaming/components/VideoList.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/features/video-streaming/components/VideoModal.tsx b/management-dashboard-web-app/src/features/video-streaming/components/VideoModal.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/features/video-streaming/components/VideoPlayer.tsx b/management-dashboard-web-app/src/features/video-streaming/components/VideoPlayer.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/features/video-streaming/components/VideoThumbnail.tsx b/management-dashboard-web-app/src/features/video-streaming/components/VideoThumbnail.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/features/video-streaming/components/index.ts b/management-dashboard-web-app/src/features/video-streaming/components/index.ts old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/features/video-streaming/hooks/index.ts b/management-dashboard-web-app/src/features/video-streaming/hooks/index.ts old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/features/video-streaming/hooks/useVideoInfo.ts b/management-dashboard-web-app/src/features/video-streaming/hooks/useVideoInfo.ts old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/features/video-streaming/hooks/useVideoList.ts b/management-dashboard-web-app/src/features/video-streaming/hooks/useVideoList.ts old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/features/video-streaming/hooks/useVideoPlayer.ts b/management-dashboard-web-app/src/features/video-streaming/hooks/useVideoPlayer.ts old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/features/video-streaming/index.ts b/management-dashboard-web-app/src/features/video-streaming/index.ts old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/features/video-streaming/services/videoApi.ts b/management-dashboard-web-app/src/features/video-streaming/services/videoApi.ts old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/features/video-streaming/types/index.ts b/management-dashboard-web-app/src/features/video-streaming/types/index.ts old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/features/video-streaming/utils/index.ts b/management-dashboard-web-app/src/features/video-streaming/utils/index.ts old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/features/video-streaming/utils/performanceMonitor.ts b/management-dashboard-web-app/src/features/video-streaming/utils/performanceMonitor.ts old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/features/video-streaming/utils/thumbnailCache.ts b/management-dashboard-web-app/src/features/video-streaming/utils/thumbnailCache.ts old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/features/video-streaming/utils/videoUtils.ts b/management-dashboard-web-app/src/features/video-streaming/utils/videoUtils.ts old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/hooks/useAuth.ts b/management-dashboard-web-app/src/hooks/useAuth.ts old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/hooks/useAutoRecording.ts b/management-dashboard-web-app/src/hooks/useAutoRecording.ts old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/index.css b/management-dashboard-web-app/src/index.css old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/lib/autoRecordingManager.ts b/management-dashboard-web-app/src/lib/autoRecordingManager.ts old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/lib/supabase.ts b/management-dashboard-web-app/src/lib/supabase.ts old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/lib/visionApi.ts b/management-dashboard-web-app/src/lib/visionApi.ts old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/main.tsx b/management-dashboard-web-app/src/main.tsx old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/test/videoStreamingTest.ts b/management-dashboard-web-app/src/test/videoStreamingTest.ts old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/test/visionApi.test.ts b/management-dashboard-web-app/src/test/visionApi.test.ts old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/utils/videoFileUtils.ts b/management-dashboard-web-app/src/utils/videoFileUtils.ts old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/src/vite-env.d.ts b/management-dashboard-web-app/src/vite-env.d.ts old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/supabase/.gitignore b/management-dashboard-web-app/supabase/.gitignore old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/supabase/.temp/cli-latest b/management-dashboard-web-app/supabase/.temp/cli-latest old mode 100644 new mode 100755 index 8e00c6d..322987f --- a/management-dashboard-web-app/supabase/.temp/cli-latest +++ b/management-dashboard-web-app/supabase/.temp/cli-latest @@ -1 +1 @@ -v2.33.9 \ No newline at end of file +v2.34.3 \ No newline at end of file diff --git a/management-dashboard-web-app/supabase/config.toml b/management-dashboard-web-app/supabase/config.toml old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/supabase/migrations/20250719000001_rbac_schema.sql b/management-dashboard-web-app/supabase/migrations/20250719000001_rbac_schema.sql old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/supabase/migrations/20250719000002_rls_policies.sql b/management-dashboard-web-app/supabase/migrations/20250719000002_rls_policies.sql old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/supabase/migrations/20250719000003_seed_admin_user.sql b/management-dashboard-web-app/supabase/migrations/20250719000003_seed_admin_user.sql old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/supabase/migrations/20250720000001_multiple_roles_support.sql b/management-dashboard-web-app/supabase/migrations/20250720000001_multiple_roles_support.sql old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/supabase/migrations/20250720000002_fix_role_id_constraint.sql b/management-dashboard-web-app/supabase/migrations/20250720000002_fix_role_id_constraint.sql old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/supabase/migrations/20250720000003_experiments_table.sql b/management-dashboard-web-app/supabase/migrations/20250720000003_experiments_table.sql old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/supabase/migrations/20250721000001_add_scheduled_date.sql b/management-dashboard-web-app/supabase/migrations/20250721000001_add_scheduled_date.sql old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/supabase/migrations/20250724000001_experiment_repetitions_system.sql b/management-dashboard-web-app/supabase/migrations/20250724000001_experiment_repetitions_system.sql old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/supabase/migrations/20250725000001_experiment_data_entry_system.sql b/management-dashboard-web-app/supabase/migrations/20250725000001_experiment_data_entry_system.sql old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/supabase/migrations/20250725000003_fix_draft_constraints.sql b/management-dashboard-web-app/supabase/migrations/20250725000003_fix_draft_constraints.sql old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/supabase/migrations/20250728000001_fix_repetitions_visibility.sql b/management-dashboard-web-app/supabase/migrations/20250728000001_fix_repetitions_visibility.sql old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/supabase/seed.sql b/management-dashboard-web-app/supabase/seed.sql old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/tailwind.config.js b/management-dashboard-web-app/tailwind.config.js old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/test-api-fix.js b/management-dashboard-web-app/test-api-fix.js old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/test-camera-config.html b/management-dashboard-web-app/test-camera-config.html old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/test-stop-streaming.html b/management-dashboard-web-app/test-stop-streaming.html old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/tsconfig.app.json b/management-dashboard-web-app/tsconfig.app.json old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/tsconfig.json b/management-dashboard-web-app/tsconfig.json old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/tsconfig.node.json b/management-dashboard-web-app/tsconfig.node.json old mode 100644 new mode 100755 diff --git a/management-dashboard-web-app/vite.config.ts b/management-dashboard-web-app/vite.config.ts old mode 100644 new mode 100755