Files
SceneSense/camera-client/camera_monitor.py
Muhamad H. Asadi 2e70b3419d changed logging module to lg for smaller code base
Changes to be committed:
	modified:   camera-client/camera_monitor.py
2023-09-21 22:26:32 +03:30

121 lines
4.1 KiB
Python

import cv2
import time
import requests
import numpy as np
from datetime import datetime
import os
import json
import logging as lg
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(log_file='logs/camera_monitor.log'):
# logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# return logging.getLogger('CameraMonitor')
# Configure the logger
logger = lg.getLogger('CameraMonitor')
logger.setLevel(lg.INFO)
# Create a TimedRotatingFileHandler for log rotation
file_handler = lg.handlers.TimedRotatingFileHandler(
log_file, when='midnight', backupCount=7
) # Keeps logs for 7 days
file_handler.suffix = '%Y-%m-%d' # Append date to log file names
# Define the log message format
formatter = lg.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
file_handler.setFormatter(formatter)
# Add the file handler to the logger
logger.addHandler(file_handler)
return logger
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()