ericwyuan
7adc32486a
[重构] 运动监测恢复轮询主路径(简单稳定) - poll_enabled 默认开启;修复3隐患: 推送失败批次不前进游标(下轮重试不丢事件)、重启优先续用DB游标(停机期间事件补推)、fetch limit 提到1000;Webhook降级为可选补充
2026-08-22 12:00:03 +08:00
ericwyuan
ca6d425b19
[重构] 运动监测改为 Webhook 驱动(去轮询) - 关闭 MotionNotifier 轮询,NAS 端合成稳定 event_id、摄像头名映射 camera_id、EVENT_TIME 解析为 epoch,SS Webhook 直接推送甲骨文
2026-08-22 10:53:03 +08:00
ericwyuan
01bbb39750
[新增] NAS 运动监测通知服务 MotionNotifier - 轮询/接收 SS 事件后主动 POST 推送到甲骨文 /api/ss/motion(单向 NAS->Oracle):新增 motion_notifier 子包、/api/ss/webhook 实时转发蓝图、db_layer 运动游标、app.py 接线与 config 块
2026-08-22 10:26:03 +08:00
ericwyuan
e56d362d73
refactor(fam-core): 重构第二阶段 - img_proxy 收尾 + 稳定性小修 + 工程质量
...
img_proxy 收尾: 提交此前未提交的图片代理蓝图(app.py 注册),改为复用 oracle_sync
已解析好的 base_url/token/timeout,不再独立读一份配置(避免配置改动时两处不同步)。
稳定性/正确性: chat_handler 问答失败时不再把 Oracle 内部 HTTP 状态码等细节透传给
客户端,改为通用错误信息(详细原因仍记服务端日志); 删除 logger.py 里旧任务架构
遗留的死函数 log_task; 更新 config.yaml.example 到当前 v2 架构(原文件还是重构前
的 scheduler/dispatcher/video_server 旧结构,当前代码完全不读这些字段)。
工程质量: 新增 fam-core/tests(9 个单元测试,覆盖 _format_events 上下文格式化和
config_loader 的 ${ENV_VAR} 解析)。
部署时发现并修复一个和这次改动无关的运维问题: NAS .env 文件缺 export 关键字,
plain source 只在当前 shell 生效不会被子进程(gunicorn)继承,导致 Oracle-Sync
token 校验失败;用 set -a/set +a 强制导出重启,非代码改动。
已部署 NAS 并验证:/health、/api/status、/api/proxy/frame、/api/proxy/avatar
全部通过;浏览器实测事件时间轴、人物管理页正常渲染。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com >
2026-08-22 00:50:49 +08:00
ericwyuan
44026b65ea
[阶段3] FAM-Core 瘦身为管理后台+Oracle-Sync 同步引擎,FAM-UI 改读同步镜像 - 删除 scheduler/dispatcher/poller/event_receiver/video_server,新增 oracle_sync 每30分钟拉增量写 sync_* 镜像表;member_manager/chat_handler 改走同步数据;UI 移除帧图改为事件时间线;DDL 新增 sync_videos/events/people/cursor
2026-08-21 10:38:26 +08:00
ericwyuan
0d5173f442
feat: UI 时间轴重构 + 关键帧图片全链路持久化
...
界面重做(深色监控面板主题):
- 事件时间轴页: 左侧事件列表卡片 + 右侧关键帧时间轴
(时间点 + 视频帧 + 人物/动作/衣着摘要 + 关注标记)
- 全局 CSS: 深色主题、卡片化按钮、统计卡、对话气泡、成员卡片
- 侧边栏任务队列状态徽章; 历史帧无图时优雅降级占位
关键帧持久化链路:
- Edge orchestrator: process_push_task 成功后把 keyframes
base64 注入 frame_details[i].frame_image (位置对齐视觉输入帧)
- NAS event_receiver: 落库前 base64 解码写盘到
fam-ui/static/frames/event_{id}/frame_{idx}.jpg
- payload 增量 ~300KB/事件 (6帧 jpeg q80), 队列/拉取均无压力
配置: fam-core/fam-ui 新增 storage.frame_image_dir
2026-08-20 19:50:36 +08:00
ericwyuan
203b076783
feat: NAS端FFmpeg预压缩 — 根治360MB视频跨境上传超时
...
根因诊断(网络问题,非代码逻辑):
- NAS(中国移动) → Oracle(美国Phoenix) 跨境上行带宽实测仅 0.5-0.9MB/s 且波动大
- 下载方向 3.0MB/s(非对称,典型国际出口拥塞)
- Tailscale P2P: ping 可通(224ms)但持续数据流被阻断(0 B/s, 127s超时)
- 360MB 原始视频上传需 10-20min,任何大分块都会超时
NAS dispatcher:
- 新增 _compress_video: 480p/CRF28/veryfast,静态监控场景实测 ~36x 压缩比
(360MB → ~12MB,上传时间 20min → ~30s)
- ffmpeg 自动探测: CodecPack ffmpeg41(带libx264) > /usr/local/bin > PATH
(Synology 系统 ffmpeg 被裁剪,无 h264 编解码)
- scale 两级滤镜: force_original_aspect_ratio=decrease + trunc(iw/2)*2
(h264 要求偶数尺寸,853x480 会报错)
- 压缩缓存 /tmp/fam_compressed/task_{id}/,源文件未变则重试复用,TTL 24h
- 压缩完成后重置 PROCESSING 状态(重置 stale 回收计时基准)
- 压缩失败回退原始文件分块上传
- _query_uploaded_chunks 失败时记录日志(原静默失败导致全量重传无感知)
Edge api_gateway:
- fix: total_chunks 变更清理旧分块后同步重写 meta.json
(原 bug: meta.json 不更新导致每块上传都触发清理,删除同批新分块死循环)
config:
- stale_timeout 600→1800(覆盖压缩+上传+Edge队列积压总时长)
- 新增 ffmpeg_path / compress_timeout 配置项
2026-08-20 14:59:50 +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
4f0f19bccd
fix: dispatcher/poller 超时改为分离模式,stale_timeout 缩短到 10 分钟
...
- dispatcher 上传 timeout 从 300s 改为 (10s connect, 60s read)
避免大文件上传无限阻塞 dispatcher 线程
- poller 拉取 timeout 从 30s 改为 (10s connect, 15s read)
- stale_timeout 从 3600s 缩短到 600s(10 分钟)
更快回收卡死的 PROCESSING 任务
2026-08-20 12:12:19 +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
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
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
da6b1c8d39
[2.1-2.5] FAM-Core 六个子模块 - Scheduler/Dispatcher/Event-Receiver/Chat-Handler/Member-Manager/Video-Server + DB层 + 配置
2026-08-19 22:21:31 +08:00