Files
vision-record/scheduler.py
T

223 lines
6.8 KiB
Python
Raw Normal View History

"""
定时任务调度模块
"""
import threading
import time
import datetime
from camera import CameraCapture
from analyzer import ImageAnalyzer
from database import db
from config import CAPTURE_INTERVAL
class VisionScheduler:
"""视觉记录调度器"""
def __init__(self):
self.camera = CameraCapture()
self.analyzer = ImageAnalyzer()
self.running = False
self.interval = CAPTURE_INTERVAL
self.timer = None
self.auto_analyze = True # 自动分析
# 统计
self.capture_count = 0
self.last_capture_time = None
self.last_analyze_time = None
self.errors = []
def start(self, interval=None, auto_analyze=None):
"""启动定时拍照
Args:
interval: 拍照间隔(秒)
auto_analyze: 是否自动分析
"""
if self.running:
return {'success': False, 'error': '已在运行中'}
if interval:
self.interval = interval
if auto_analyze is not None:
self.auto_analyze = auto_analyze
self.running = True
self._schedule_next()
return {
'success': True,
'interval': self.interval,
'auto_analyze': self.auto_analyze
}
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
self.timer = threading.Timer(self.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'])
self.capture_count += 1
self.last_capture_time = datetime.datetime.now().isoformat()
# 自动分析
if self.auto_analyze:
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'])
self.capture_count += 1
self.last_capture_time = datetime.datetime.now().isoformat()
# 如果自动分析开启,立即分析
if self.auto_analyze:
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']
}
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': self.interval,
'auto_analyze': self.auto_analyze,
'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):
"""设置拍照间隔"""
self.interval = interval
if self.running:
# 重启定时器
self.stop()
self.start()
return {'success': True, 'interval': interval}
# 全局实例
scheduler = VisionScheduler()