import cv2 import time import requests import numpy as np from datetime import datetime import os import json import logging import argparse class CameraMonitor: def __init__(self, config, logger): self.config = config self.logger = logger def initialize_camera(self): """ Initialize the camera and return the VideoCapture object. """ cap = cv2.VideoCapture(self.config['camera_address']) if not cap.isOpened(): raise Exception(f"Failed to open camera at {self.config['camera_address']}") return cap def log_scene_change(self): """ Log a scene change notification to the Scenesense server. """ current_time = int(time.time()) human_readable_time = datetime.utcfromtimestamp(current_time).strftime('%Y-%m-%d %H:%M:%S') description = f'Scene change detected at {human_readable_time}' payload = {'timestamp': current_time, 'description': description} try: response = requests.post(self.config['api_url'], json=payload) response.raise_for_status() self.logger.info(f'Scene change logged: {description}') except requests.exceptions.RequestException as e: self.logger.error(f'Error connecting to Scenesense server: {e}') except requests.exceptions.HTTPError as e: self.logger.error(f'HTTP error: {e}') def detect_scene_change(self, previous_frame, current_frame): """ Detect scene change based on frame differences. """ frame_diff = cv2.absdiff(previous_frame, current_frame) mean_diff = np.mean(frame_diff) return mean_diff > self.config['sensitivity_threshold'] def run(self): try: with self.initialize_camera() as cap: previous_frame = None while True: ret, current_frame = cap.read() if not ret: raise Exception("Failed to read frame") if previous_frame is not None: if self.detect_scene_change(previous_frame, current_frame): self.log_scene_change() previous_frame = current_frame except KeyboardInterrupt: self.logger.info("Camera monitoring stopped by user.") except Exception as e: self.logger.error(f"An error occurred: {e}") def parse_command_line_args(): parser = argparse.ArgumentParser(description='Camera Monitor for Scenesense') parser.add_argument('--config', type=str, default='config.json', help='Path to configuration file') return parser.parse_args() def load_config(config_path): try: with open(config_path, 'r') as config_file: return json.load(config_file) except FileNotFoundError: raise Exception(f"Config file not found: {config_path}") except json.JSONDecodeError: raise Exception(f"Invalid JSON format in config file: {config_path}") def setup_logging(): logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') return logging.getLogger('CameraMonitor') def main(): args = parse_command_line_args() config = load_config(args.config) logger = setup_logging() monitor = CameraMonitor(config, logger) monitor.run() if __name__ == "__main__": main()