Commit Graph

71 Commits

Author SHA1 Message Date
ericwyuan
5915cf4be3 fix: 分块大小减至5MB + Edge端chunk_size变更自动清理 + 断点续传防护
NAS dispatcher:
- CHUNK_SIZE 10MB→5MB(~1Mbps上行带宽下可靠传输)
- chunk上传timeout (30,120)→(60,180)(增加连接和读取余量)
- _query_uploaded_chunks 返回 (set, edge_total) 元组
- expected_total != edge_total 时跳过断点续传(防止chunk_size变更导致文件损坏)

Edge api_gateway:
- upload_chunk 检测 total_chunks 变更,自动清理旧分块
- 防止不同chunk_size的旧分块与新分块混合导致assemble后文件损坏
2026-08-20 14:18:29 +08:00
ericwyuan
b6c13a9047 feat: 分块断点续传上传 — 20MB/块 + 分块级重试 + 断点查询
Edge 端新增 3 个端点:
- POST /api/edge/video/chunk: 接收单块,保存到 task_{id}/chunk_{index:04d}
- GET /api/edge/video/chunks: 查询已上传分块(断点续传)
- POST /api/edge/video/assemble: 合并全部分块入队

NAS Dispatcher 重写:
- 大文件(>50MB)自动分块上传(20MB/块)
- 每块最多重试 3 次(分块级重试,非整文件级)
- 上传前查询已上传分块,跳过已有的(断点续传)
- 全部上传后调 /assemble 合并入队
- 小文件(<=50MB)走直接上传路径
- max_retries 3→5(文件级重试次数)
- scheduler 切回生产目录

解决: 360MB 视频跨公网单次上传超时/断连问题
2026-08-20 12:27:30 +08:00
ericwyuan
02da23ef42 feat: 异步任务队列架构 - SQLite队列 + 速率限制 + NAS Poller
Edge端:
- 新增 SQLite 异步任务队列 (queue_manager + consumer)
- 新增 TokenBucket 速率限制器 (Gemini 1000 RPM, NVIDIA 40 RPM, burst 2x)
- 新增 /api/edge/video/enqueue + /api/edge/results 端点
- 消费者线程从队列消费任务,按速率限制调用AI模型
- orchestrator 集成 rate_limiter,Gemini优先→NVIDIA兜底

NAS端:
- Dispatcher 重构为 enqueue 模式(上传后立即返回,不等结果)
- 新增 Poller 线程(定期从Edge拉取结果写 MariaDB)
- app.py 启动 Poller,config.yaml 新增 poller 配置
- db_layer 更新 valid_stages 添加 'process'
2026-08-20 12:07:09 +08:00
ericwyuan
853cb21542 fix: NVIDIA single-frame JSON parsing + Gemini timeout/circuit breaker tuning
NVIDIA fix:
- Replace parse_vlm_json (requires full schema: global_summary/entities_json/
  frame_details/compute_provider) with lightweight _parse_single_frame_json
  that only extracts per-frame fields (person/action/clothing/etc)
- Root cause: NVIDIA adapter does per-frame analysis returning single-frame
  JSON, but parse_vlm_json rejected it for missing full-schema fields
- Verified: task 297 → 6/6 frames parsed successfully, first SUCCESS

Gemini + circuit breaker tuning:
- Gemini timeout: 30s → 90s (multi-image vision analysis needs more time)
- NVIDIA timeout: 20s → 30s (per-frame API call)
- Circuit breaker threshold: 3 → 5 (less aggressive tripping)
- Circuit breaker cooldown: 600s → 300s (faster recovery)
2026-08-20 11:02:26 +08:00
ericwyuan
babf5b09a9 [架构重构] 移除本地Ollama融合,云端直出JSON直存DB,Q&A三模型降级
1. 视频摘要链路:云端VLM直出结构化JSON → Edge format_cloud_result格式化校验 → 直存NAS DB(移除run_text_fusion本地融合)
2. 智能问答链路:Gemini→NVIDIA→Ollama降级,新增chat()纯文本问答方法
3. 适配器重构:base/gemini/nvidia/ollama adapter新增chat();gemini多图单请求结构化JSON;nvidia逐帧调用聚合
4. 端点变更:/api/edge/chat → /api/edge/chat/ask,调orchestrator.run_qa()
5. chat_handler改经Edge Q&A编排,不再直连Ollama
6. 配置更新:ollama_url → qa_url,Ollama role注释改为Q&A兜底
7. README同步更新架构描述、拓扑图、时序图、模块表
2026-08-20 10:21:09 +08:00
ericwyuan
486eee4feb fix(db): frame_timestamp ISO8601 归一化 + perf(edge): ollama num_predict 1024→512
- db_layer._dt_or_none 支持 ISO 8601(带 T/Z/时区偏移) 归一化为 MariaDB DATETIME 标准格式, 修复 1292 Incorrect datetime value
- edge config ollama num_predict 512: qwen2.5:7b 在 ARM 上 1024 token 融合需 200s, 降到 512 加速且输出足够
2026-08-20 09:26:42 +08:00
ericwyuan
d2fd01f134 perf(config): Gemini 视觉单帧 timeout 15→30s
实测 gemini-flash-latest 视觉推理免费层排队需 15~30s,15s 频繁超时触发熔断;
调到 30s 后单测通过(返回有效描述)。NVIDIA NIM 仍 20s 稳定可用
2026-08-20 09:14:53 +08:00
ericwyuan
a46da5db81 feat(orchestrator): 视觉 fallback 降级 + 文本融合角色化
- run_visual_analysis 仅 vision 角色参与, fallback 顺序降级(Gemini→NVIDIA NIM)首个成功即采用
- run_text_fusion 固定用 role=text 的 Ollama(qwen2.5:7b) 融合, 支持 num_predict
- config 改为多模型池(gemini/nvidia vision + ollama text)
2026-08-20 09:11:44 +08:00
ericwyuan
99d75a4bda feat(adapter): 云端视觉适配器 + role 角色区分
- base_adapter 增加 role 字段(vision/text)与 get_role()
- gemini_adapter 修复 v1beta 下模型名 404(gemini-1.5-flash→gemini-flash-latest), 改逐帧调用
- 新增 nvidia_adapter(openai SDK, 规避 NIM 单次限 1 图逐帧), 注册 adapter_factory
- 视觉分析仅 vision 角色参与, 文本融合交给 role=text 模型
2026-08-20 09:11:44 +08:00
ericwyuan
7ce8aff67c perf: use FFmpeg fast seek instead of fps filter for frame extraction
- Replace single `ffmpeg -vf fps=1/interval` call (full video decode) with
  per-frame `ffmpeg -ss <ts> -frames:v 1` calls (keyframe seek)
- 6-8x faster on ARM: 180s+ → 33s for 60 frames from 30min video
- Per-frame timeout 30s (was 120s single call), failed seeks logged and skipped
- Verified end-to-end: 30min 360MB video → 60 candidates → 12 keyframes in 39s
2026-08-20 02:30:17 +08:00
ericwyuan
6a9d1626fb fix(event-time): event_end_time/frame_timestamp NOT NULL 列兜底
- Edge push 模式: event_end_time 未提供时用 start+视频时长推算
- fam-core db_layer: insert_event 空值兜底(end→start→NOW)
- insert_event_detail: frame_timestamp 空值兜底 NOW
解决 1048 Column cannot be null 落库失败
2026-08-20 02:20:01 +08:00
ericwyuan
be30b5f875 fix(config): Ollama 超时与 num_predict 按 ARM 实测调整
- 实测 1024px 帧视觉编码 ~36s/帧 + ~5 tok/s 生成
- num_predict 500→60: 500 会单帧跑数分钟必触发 240s 超时
- vlm_visual/model timeout 240→600, vlm_fusion 120→300, overall 600→1800
2026-08-20 01:54:32 +08:00
ericwyuan
727642d38b feat: adaptive keyframe count based on video duration
- Replace fixed 5-8 keyframe limit with duration-based adaptive sizing
- Candidate frames: clamp(duration_min × 2, 30, 120)
- Keyframe cap: clamp(duration / 150s, 8, 30)
- 30min video → 12 keyframes (was 8), 60min → 24, 120min → 30
- Short videos (<12min) still get floor of 8 keyframes
- Add Ollama keep-alive config doc to PROGRESS.md (OLLAMA_KEEP_ALIVE=-1)
- Update config.yaml and config.yaml.example with new video params
2026-08-20 01:29:14 +08:00
ericwyuan
40944428d1 feat: video analysis switched to push mode (upload whole video, sync response)
Rationale: Oracle cannot reach NAS (Tailscale userspace mode on NAS, no TUN),
the old pull+webhook design requires Edge to download video from NAS and
callback to NAS - both blocked. New design is one-way NAS -> Oracle:

- FAM-Edge: new POST /api/edge/video/push endpoint accepts multipart video
  upload, reuses existing OpenCV scene-change keyframe selection, analyzes
  synchronously and returns the result payload directly in the HTTP response
  (no webhook callback). Old /api/edge/video/analyze kept for compatibility.
- FAM-Edge: VideoPreprocessor.save_upload() saves the uploaded file
- FAM-Edge: AIOrchestrator.process_push_task() runs the full pipeline
  (health check -> extract -> select -> compress -> VLM -> fusion) and
  returns callback-style payload dict
- FAM-Core: Dispatcher rewritten to push mode - reads local video file,
  uploads with task metadata (camera_name, event_start_time from file mtime,
  known_members_context), applies the result to DB via shared
  event_receiver.apply_success_event()
- FAM-Core: event_receiver success logic extracted into reusable
  apply_success_event() (used by both webhook route and dispatcher)
- config: edge_url -> /api/edge/video/push, push_timeout 1800s, gunicorn
  Edge timeout raised to 1800s for long synchronous analysis
2026-08-20 01:03:48 +08:00
ericwyuan
94a8805045 feat: FAM-Edge chat proxy + PyMySQL migration for FAM-UI + config update
- FAM-Edge: add /api/edge/chat proxy endpoint forwarding to local Ollama
  (Ollama port 11434 not exposed externally, FAM-Edge acts as reverse proxy)
- FAM-Core config: edge_url and ollama_url switched from Tailscale IP to
  Oracle public IP (Tailscale firewall blocking between NAS and Oracle)
- FAM-UI: migrate mysql.connector to PyMySQL (same as FAM-Core)
- FAM-UI: cursor(dictionary=True) replaced with cursorclass=DictCursor
- End-to-end chat verified: FAM-Core -> FAM-Edge proxy -> Ollama -> response
  Answer: 今天没有观察到张三 (no events in DB yet, expected)
2026-08-19 23:59:28 +08:00
ericwyuan
47658fa068 [deploy] PyMySQL 替换 + Tailscale 组网 + config.yaml + 路径修复
- db_layer.py: mysql-connector-python(19MB) → PyMySQL(45KB), 去掉连接池
- config_loader.py: 修复路径解析 (2级→3级 dirname), FAM-Core + FAM-Edge 均修复
- Tailscale 组网完成: Oracle=100.74.137.126, NAS=100.70.234.39, 互通验证通过
- NAS Python 依赖: flask/gunicorn/pymysql/PyYAML 全部安装成功
- NAS 代码部署: /volume1/web/sentinel-home-ai/, FAM-Core 7 模块导入 PASS
- NAS DB 连接验证: PyMySQL → MariaDB 10.11.11, 6 张表可见, PASS
- config.yaml 创建: FAM-Core + FAM-Edge + FAM-UI (Tailscale IP + 密码)
- requirements.txt: mysql-connector-python → PyMySQL
2026-08-19 23:27:28 +08:00
ericwyuan
50d83539f6 [deploy] Oracle 环境部署 + 模型基准测试 + OllamaAdapter 优化
- Oracle 依赖安装: flask/gunicorn/requests/PyYAML/opencv/numpy 全部成功
- FAM-Edge 全部 8 个模块导入验证 PASS
- llava-phi3 基准测试: 冷启动 109s, 预热无限制 13.35s, 预热+num_predict=30 仅 4.34s PASS
- OllamaAdapter 新增 num_predict 可配置参数 (默认 500)
- config.yaml.example 新增 num_predict 配置项
- 创建 PROGRESS.md 进度追踪文档
2026-08-19 23:01:21 +08:00
ericwyuan
c1bfac59df fix(requirements): 移除 google-generativeai/openai 硬依赖 - 代码用 requests 直接调 REST API,兼容 Python 3.8 2026-08-19 22:50:30 +08:00
ericwyuan
c45464c3e2 [补全] 各模块 __init__.py 导出 - 确保import链路完整 2026-08-19 22:37:47 +08:00
ericwyuan
5e4587bdc2 [3.5补充] Storage-Cleaner - finally清理逻辑 + 超期残留目录清理 2026-08-19 22:35:50 +08:00
ericwyuan
cdd1f21d4c [3.1-3.5] FAM-Edge 全链路 - API-Gateway/Video-Preprocessor/AI-Orchestrator/模型适配器(基类+Ollama+Gemini)/熔断器/JSON解析容错 + 配置 2026-08-19 22:25:38 +08:00