1. 项目概述与核心需求
这个智能看护系统的核心目标是通过现有硬件设备(萤石云摄像头+Mac mini)实现零成本的家庭监控自动化。作为一名长期关注智能家居的技术从业者,我发现市面上大多数智能监控方案要么需要额外购买专用设备,要么依赖云端服务产生持续费用。而实际上,很多家庭已经拥有支持开放API的网络摄像头和闲置的计算设备,完全可以通过技术整合实现类似功能。
我选择萤石云摄像头作为硬件基础有几个关键考量:首先,它的开放平台API文档完善,支持设备控制、视频流获取等核心功能;其次,相比其他品牌(如TP-LINK)完全不开放API的做法,萤石云提供了合规的接入方式;最后,我家已经有两台萤石云设备(客厅CP1云台版和阳台C2C固定版),可以直接复用现有硬件。
系统需要解决的核心技术挑战包括:
- 如何高效稳定地接入摄像头API
- 如何在不依赖云端服务的情况下实现智能画面分析
- 如何设计合理的监控策略平衡实时性和资源消耗
- 如何将分析结果以最友好的方式推送给家庭成员
2. 萤石云API对接与工程实践
2.1 API能力调研与设备差异处理
萤石云开放平台提供了相当完善的API文档,涵盖了设备管理、视频流获取、云台控制等核心功能。经过详细调研,我确认以下几个关键接口对本项目至关重要:
- 设备列表查询(/api/lapp/device/list)
- 设备抓拍(/api/lapp/device/capture)
- 云台控制(/api/lapp/ptz/start)
- 预置点管理(/api/lapp/preset/list)
- 直播流地址获取(/api/lapp/live/address/get)
值得注意的是,不同型号的摄像头功能存在差异。我家两台设备中,CP1支持云台控制和预置点,而C2C仅支持基础抓拍功能。这意味着代码中必须实现设备能力检测和路由逻辑:
python复制def get_device_capabilities(device_serial):
if device_serial.startswith('CP1'):
return {'ptz': True, 'preset': True}
elif device_serial.startswith('C2C'):
return {'ptz': False, 'preset': False}
else:
raise ValueError('Unknown device type')
2.2 Token管理的最佳实践
萤石云的AccessToken有效期只有7天,这是系统可靠性的关键挑战。经过多次测试,我确定了最稳健的Token管理方案:
- 实现Token自动续期机制
- 在API调用层做错误码嗅探
- 采用懒加载+缓存策略
具体实现如下:
python复制_token = None
_token_expire = 0
def get_token():
global _token, _token_expire
if not _token or time.time() > _token_expire:
resp = requests.post('https://open.ys7.com/api/lapp/token/get', data={
'appKey': APP_KEY,
'appSecret': APP_SECRET
}).json()
if resp['code'] == '200':
_token = resp['data']['accessToken']
_token_expire = time.time() + 6*24*3600 # 提前1天刷新
return _token
这种设计确保了无论系统运行多久、何时重启,Token都会在需要时自动刷新,无需人工干预。
2.3 云台控制的工程细节
云台摄像头的预置点功能是本项目的重要特性,但实际实现中遇到了几个关键问题:
- 物理延迟问题:云台转动需要时间,立即抓拍会导致图像模糊
- 预置点精度问题:不同环境光照下云台停靠位置可能有偏差
- API频率限制:连续控制指令需要适当间隔
针对这些问题,我开发了一个交互式调试工具preset_wizard.py,允许通过键盘实时控制云台并保存预置点。核心控制逻辑如下:
python复制def move_ptz(device_serial, direction, speed=50):
"""控制云台转动
:param direction: 0-上,1-下,2-左,3-右,4-左上,5-左下,6-右上,7-右下
:param speed: 速度值(1-100)
"""
api('/api/lapp/ptz/start', {
'deviceSerial': device_serial,
'channelNo': 1,
'direction': direction,
'speed': speed
})
time.sleep(0.2) # 最小控制间隔
api('/api/lapp/ptz/stop', {
'deviceSerial': device_serial,
'channelNo': 1
})
实际测试表明,云台从当前位置转到预置点平均需要4-6秒,因此代码中设置了可配置的等待时间:
python复制def move_to_preset(device_serial, preset_index):
api('/api/lapp/preset/move', {
'deviceSerial': device_serial,
'channelNo': 1,
'index': preset_index
})
time.sleep(os.getenv('MOVE_WAIT', '5')) # 可配置的等待时间
3. 视觉分析架构设计
3.1 级联检测模型选型
视觉分析采用了两级级联架构,这是经过多次迭代后的最优方案:
第一级:YOLOv8s目标检测
- 模型大小:21MB
- 推理速度:~36ms/帧(Mac M4)
- 功能:快速判断画面中是否有人/猫
- 优势:极低计算成本过滤空画面
第二级:MiniCPM-V多模态模型
- 模型大小:5.5GB(量化后)
- 推理速度:~5.5s/帧
- 功能:详细分析画面内容
- 优势:理解复杂场景和语义
这种架构的效能对比非常明显:
| 场景 | YOLO处理 | MiniCPM-V处理 | 总处理时间 |
|---|---|---|---|
| 空房间 | 36ms | 不触发 | 36ms |
| 有人出现 | 36ms | 5.5s | ~5.5s |
| 猫咪出现 | 36ms | 5.5s | ~5.5s |
实测数据显示,级联架构将大模型调用次数减少了约90%,大大降低了系统负载。
3.2 YOLOv8的优化实践
在YOLO模型选择上,我对比了不同版本的性能:
| 模型 | 参数量 | 推理速度 | 准确率 |
|---|---|---|---|
| YOLOv8n | 3.2M | ~12ms | 78% |
| YOLOv8s | 11.4M | ~36ms | 86% |
| YOLOv8m | 25.9M | ~74ms | 89% |
| YOLOv8l | 43.7M | ~130ms | 90% |
最终选择YOLOv8s是因为它在准确率和速度之间取得了最佳平衡。对于家居监控场景,86%的准确率已经足够,因为后续还有大模型做二次验证。
实现细节上,我使用了OpenCV的DNN模块加载YOLO模型:
python复制net = cv2.dnn.readNetFromONNX('yolov8s.onnx')
def detect_objects(image):
blob = cv2.dnn.blobFromImage(image, 1/255.0, (640,640), swapRB=True)
net.setInput(blob)
outputs = net.forward(net.getUnconnectedOutLayersNames())
# 后处理逻辑...
return detections
3.3 MiniCPM-V的本地部署
MiniCPM-V是面壁智能推出的开源多模态模型,特别适合端侧部署。在Mac mini(M4,16GB)上的部署步骤如下:
- 安装Ollama:
bash复制curl -fsSL https://ollama.com/install.sh | sh
- 拉取MiniCPM-V模型:
bash复制ollama pull minicpm-v
- 创建模型运行脚本:
python复制def query_visual_model(image_path, prompt):
import ollama
response = ollama.generate(
model='minicpm-v',
prompt=prompt,
images=[image_path],
options={'temperature': 0.1}
)
return response['response']
模型支持的中文Prompt示例:
code复制请分析这张图片:
1. 画面中有几个人?他们的年龄阶段是?
2. 他们在做什么?
3. 是否有需要关注的异常情况?
请用JSON格式回答。
4. 实时性与工程优化
4.1 抓拍即录机制
早期版本存在关键画面丢失的问题,原因是分析流水线延迟导致录制开始时目标已离开画面。经过多次优化,最终实现的抓拍即录机制流程如下:
-
定时任务触发时立即启动两个并行线程:
- 线程A:执行API抓拍
- 线程B:开始建立RTSP流连接
-
YOLO分析抓拍结果:
- 如果无目标:终止录制线程
- 如果有目标:允许录制继续
-
大模型分析期间:
- 录制线程持续保存视频流
- 分析完成后取相关时段视频生成GIF
这种设计确保了即使大模型分析需要5-6秒,录制的视频也能包含事件发生时的关键画面。
技术实现上使用了Python的多线程和ffmpeg:
python复制def start_recording(device_serial):
stream_url = get_stream_url(device_serial)
cmd = [
'ffmpeg',
'-i', stream_url,
'-t', '10', # 录制10秒
'-vf', 'fps=5,scale=480:-1',
'-c:v', 'gif',
'-f', 'gif',
'temp.gif'
]
process = subprocess.Popen(cmd)
return process
# 在检测到目标后
recording_process = start_recording(device_serial)
analysis_result = analyze_image(captured_image)
if analysis_result['has_target']:
recording_process.wait() # 等待录制完成
send_gif('temp.gif')
else:
recording_process.terminate() # 终止录制
4.2 性能优化技巧
通过以下优化手段将系统资源占用降至最低:
- 模型预热:通过定时任务保持Ollama模型常驻内存,避免冷启动延迟
- 智能调度:错开不同摄像头的分析时间点,避免CPU峰值负载
- 缓存利用:重复使用已加载的模型和资源,减少IO开销
- 自适应频率:夜间降低检测频率,白天根据活动程度动态调整
资源监控数据显示优化后的系统负载:
- CPU平均使用率:15-20%
- 内存占用:约8GB(包含Ollama模型)
- 网络流量:每月约10GB
5. 系统集成与日常使用
5.1 OpenClaw Skill封装
将整套功能封装为OpenClaw Skill的主要结构:
code复制ezviz-monitor/
├── SKILL.md # 技能描述文档
├── monitor.py # 主逻辑脚本(600+行)
├── requirements.txt # 依赖列表
└── .env.example # 环境变量模板
SKILL.md中明确定义了技能能力:
markdown复制# 萤石云监控技能
## 能力概述
- 客厅宝宝监控:每2分钟自动巡视,检测到宝宝活动时推送通知
- 阳台猫咪监控:每2分钟自动巡视,记录猫咪进食/如厕情况
- 手动查询:支持通过指令实时查看任一摄像头画面
## 指令示例
- "看看客厅现在什么情况"
- "八月今天吃了几次饭"(八月是猫的名字)
- "停止监控":将摄像头转向天花板停止拍摄
5.2 飞书集成方案
飞书机器人通知的实现要点:
- 申请企业自建应用,获取app_id和app_secret
- 配置事件订阅和消息权限
- 实现GIF上传和富文本消息发送
核心通知代码:
python复制def send_lark_notification(image_path, message):
# 上传图片获取key
upload_url = 'https://open.feishu.cn/open-apis/im/v1/images'
headers = {'Authorization': f'Bearer {get_lark_token()}'}
with open(image_path, 'rb') as f:
r = requests.post(upload_url, headers=headers, files={'image': f})
image_key = r.json()['data']['image_key']
# 发送消息
msg_url = 'https://open.feishu.cn/open-apis/im/v1/messages'
payload = {
"receive_id": CHAT_ID,
"msg_type": "post",
"content": json.dumps({
"post": {
"zh_cn": {
"title": "监控通知",
"content": [
[{"tag": "text", "text": message}],
[{"tag": "img", "image_key": image_key}]
]
}
}
})
}
requests.post(msg_url, headers=headers, json=payload)
5.3 定时任务配置
通过OpenClaw的Cron系统设置三个核心任务:
- 宝宝巡视(每2分钟):
python复制0 */2 * * * python /skills/ezviz-monitor/monitor.py --mode baby-check
- 猫咪巡视(每2分钟):
python复制1 */2 * * * python /skills/ezviz-monitor/monitor.py --mode cat-check
- 家庭日报(每天18:00):
python复制0 18 * * * python /skills/ezviz-monitor/monitor.py --mode daily-report
定时任务采用了错峰调度策略,避免两个摄像头同时触发造成资源争用。
6. 扩展应用与工程思考
6.1 模式的可迁移性
这套架构可以轻松迁移到其他监控场景,只需调整检测目标和分析逻辑:
-
独居老人看护:
- 检测目标:老人活动状态
- 异常情况:长时间静止、跌倒
- 通知策略:紧急情况即时报警,日常活动日报
-
商铺安防监控:
- 检测目标:非营业时间人员出入
- 分析重点:是否为本店员工
- 通知渠道:店主手机推送
-
工厂安全监管:
- 检测目标:安全装备佩戴
- 规则配置:危险区域、防护装备要求
- 响应机制:实时语音提醒+管理端报警
6.2 工程实践心得
在项目实施过程中积累了几个关键经验:
-
硬件API的可靠性设计:
- 所有硬件操作都需要考虑物理延迟
- API调用必须实现自动重试和错误恢复
- 频率限制和配额管理不能忽视
-
模型选型的平衡艺术:
- 小模型负责确定性高的任务
- 大模型处理需要语义理解的场景
- 级联架构能显著降低计算成本
-
实时性优化的关键:
- 采用投机式预执行弥补分析延迟
- 并行化独立任务流程
- 合理设置超时和回退机制
-
用户体验的细节打磨:
- 通知频率需要智能调控
- 交互设计要符合自然语言习惯
- 隐私控制必须直观可靠
6.3 资源与后续计划
项目相关资源:
- 完整代码库:包含在OpenClaw Skills集合中
- 模型文件:YOLOv8s.onnx和MiniCPM-V的Ollama配置
- 部署指南:详细的环境配置和API申请教程
未来改进方向:
- 支持更多摄像头品牌和型号
- 增加更精细的行为分析能力
- 优化模型量化方案进一步降低资源占用
- 开发移动端应用提供更友好的交互界面
这套方案最令我满意的不是某个技术点,而是它展示的"用现有资源创造智能体验"的可能性。通过合理组合成熟技术和创新思路,完全可以在不增加硬件投入的情况下,打造出实用、可靠的智能家居解决方案。这种技术整合的思路,或许比单纯追求算法精度更有普适意义。
