""" 定时任务调度模块 """ import threading import time import datetime from camera import CameraCapture from analyzer import ImageAnalyzer from database import db from config import config_mgr class VisionScheduler: """视觉记录调度器""" def __init__(self): self.camera = CameraCapture() self.analyzer = ImageAnalyzer() self.running = False self.timer = None # 统计 self.capture_count = 0 self.last_capture_time = None self.last_analyze_time = None self.errors = [] def start(self): """启动定时拍照""" if self.running: return {'success': False, 'error': '已在运行中'} self.running = True interval = config_mgr.get('capture_interval', 60) self._schedule_next() return { 'success': True, 'interval': interval, 'auto_analyze': config_mgr.get('auto_analyze', True) } def stop(self): """停止定时拍照""" self.running = False if self.timer: self.timer.cancel() self.timer = None self.camera.close() return {'success': True} def _schedule_next(self): """安排下一次拍照""" if not self.running: return interval = config_mgr.get('capture_interval', 60) self.timer = threading.Timer(interval, self._capture_task) self.timer.start() def _capture_task(self): """拍照任务""" if not self.running: return try: # 拍照 result = self.camera.capture() if result['success']: # 记录到数据库 image_id = db.add_image( result['path'], date_folder=result.get('date_folder') ) self.capture_count += 1 self.last_capture_time = datetime.datetime.now().isoformat() # 自动分析 if config_mgr.get('auto_analyze', True): self._analyze_task(image_id, result['path']) else: self.errors.append({ 'time': datetime.datetime.now().isoformat(), 'error': result['error'] }) except Exception as e: self.errors.append({ 'time': datetime.datetime.now().isoformat(), 'error': str(e) }) # 安排下一次 self._schedule_next() def _analyze_task(self, image_id, image_path): """分析任务""" try: result = self.analyzer.analyze(image_path) if result['success']: # 记录事件 for event in result['events']: db.add_event( image_id, event['event_type'], event['description'], event['confidence'] ) # 标记已分析 db.mark_image_analyzed(image_id) self.last_analyze_time = datetime.datetime.now().isoformat() else: self.errors.append({ 'time': datetime.datetime.now().isoformat(), 'error': f"分析失败: {result['error']}" }) except Exception as e: self.errors.append({ 'time': datetime.datetime.now().isoformat(), 'error': str(e) }) def capture_now(self): """立即拍照""" result = self.camera.capture() if result['success']: image_id = db.add_image( result['path'], date_folder=result.get('date_folder') ) self.capture_count += 1 self.last_capture_time = datetime.datetime.now().isoformat() # 如果自动分析开启,立即分析 if config_mgr.get('auto_analyze', True): threading.Thread( target=self._analyze_task, args=(image_id, result['path']) ).start() return { 'success': True, 'image_id': image_id, 'path': result['path'], 'timestamp': result['timestamp'], 'date_folder': result.get('date_folder') } return result def analyze_now(self, image_id): """立即分析指定图片""" image = db.get_image_by_id(image_id) if not image: return {'success': False, 'error': '图片不存在'} result = self.analyzer.analyze(image['path']) if result['success']: for event in result['events']: db.add_event( image_id, event['event_type'], event['description'], event['confidence'] ) db.mark_image_analyzed(image_id) self.last_analyze_time = datetime.datetime.now().isoformat() return result def analyze_unanalyzed(self): """分析所有未分析的图片""" images = db.get_unanalyzed_images(limit=10) results = [] for image in images: result = self.analyzer.analyze(image['path']) if result['success']: for event in result['events']: db.add_event( image['id'], event['event_type'], event['description'], event['confidence'] ) db.mark_image_analyzed(image['id']) results.append({'image_id': image['id'], 'success': True}) else: results.append({'image_id': image['id'], 'success': False, 'error': result['error']}) return results def get_status(self): """获取调度器状态""" return { 'running': self.running, 'interval': config_mgr.get('capture_interval', 60), 'auto_analyze': config_mgr.get('auto_analyze', True), 'capture_count': self.capture_count, 'last_capture_time': self.last_capture_time, 'last_analyze_time': self.last_analyze_time, 'recent_errors': self.errors[-5:] if self.errors else [] } def set_interval(self, interval): """设置拍照间隔""" config_mgr.set('capture_interval', interval) if self.running: # 重启定时器 self.stop() self.start() return {'success': True, 'interval': interval} # 全局实例 scheduler = VisionScheduler()