研究生 / 科研工作者桌面作息追踪与工作量分析系统
实时监控 · 数据分析 · 作息追踪 · 摄像头抓拍 · 隐私安全
DailyRoutine Monitoring 是一款运行在 Windows 桌面的轻量级作息追踪与工作量分析工具。程序以后台服务形式运行,通过监控鼠标、键盘、窗口和系统活动,自动生成忙碌指数、工作达成率、专注度等多维度分析报告,并通过美观的 Web 界面可视化呈现。同时支持定时摄像头抓拍,自动记录工作场景。
适用场景:
- 📚 研究生 / 科研工作者追踪每日实验室坐班时长
- 💼 自由职业者量化工作投入
- 🧠 任何希望了解自己"时间都去哪了"的人
核心原则:所有数据仅存储于本地 SQLite 数据库,不上传任何服务器。
- 🔧 开机自启动:支持 Windows 开机静默启动,无感知后台运行
- 🖱️ 鼠标追踪:实时记录移动距离、点击次数、移动频率
- ⌨️ 键盘追踪:记录按键频率(不记录按键内容)
- 🪟 窗口追踪:记录窗口切换次数和活动窗口标题
- 💻 系统监控:CPU / 内存使用率采集
- 📊 忙碌指数 (0-100):加权融合鼠标、键盘、窗口、系统四维指标
- 🎯 工作达成率:当日实际活动时长 vs 自定义标准工时
- 🔥 工作强度:综合时长 × 忙碌度的投入评估
- 🧘 专注度评分:基于窗口切换频率,越高代表越专注
- ⚡ 效率指数:单位时间内的操作活跃度
- 📅 作息规律性:基于每日开机时间标准差
- 📈 忙碌度曲线:精确到分钟的全天活动曲线(含次日凌晨 2 点前数据)
- 🗓️ 活动日历:月度日历热力图,一目了然查看每日工作量
- 📉 趋势图表:任意时间段的活动时长和忙碌指数趋势
- 📋 周报 / 月报:自动统计工作天数、日均时长、综合指标
- 🔍 自定义分析:自由选择任意时间段进行深入分析
- 📥 CSV 导出:原始数据,方便 Python / Excel 进一步分析
- 📥 Excel 导出:含每日明细 + 汇总统计双工作表
- 🎥 时间段抓拍:配置多个每日时间段,按指定间隔(如每 60 秒)自动拍照
- 📌 固定时间抓拍:在每天特定时间点(如 08:50、14:50、19:50)永久拍照
- 📸 手动立即抓拍:Web 界面一键拍照,可即时验证摄像头设备并按需抓拍
- 🎞️ GIF 动图:每个时间段结束时自动将临时照片合成为 GIF 动图
- 🏷️ 时间戳水印:每张照片自动叠加拍摄时间
- 🧹 自动清理:过期临时照片自动删除,GIF 和永久照片长期保存
- 🖥️ Web 查看:在 Web 界面中浏览临时抓拍、永久抓拍和 GIF 动图
- 🔒 隐私安全:摄像头按需初始化、空闲自动释放,照片仅存本地
- 🔒 所有数据存储于本地
data/activity.db(SQLite) - 🔒 不记录键盘输入内容,仅统计按键次数
- 🔒 不截屏、不录音、不联网上传
- 🔒 摄像头照片仅存储于本地,可通过配置禁用抓拍功能
- 🔒 支持自定义数据保留天数,过期自动清理
点击展开 Web 界面截图描述
- 六宫格数据卡片:活动时长、工作达成率、鼠标点击、键盘按键、鼠标移动距离、平均忙碌指数
- 忙碌度曲线图:0-26 小时全时段,红色标注空闲时段
- 统计周期概览:总天数、有效工作天数、排除天数说明
- 综合指标:日均活动时长、鼠标移动距离、工作强度、专注度、效率指数、作息规律性
- 双子图趋势:活动时长 + 忙碌指数,含平均值线和标准工时参考线
- 月度日历热力图:每个日期格子显示活动时长和工作达成率
- 统计汇总表格
- 自由选择起止日期
- 趋势图 + 完整统计报表
- CSV / Excel 双格式支持
- Excel 包含"每日统计"和"汇总统计"两个工作表
- 服务状态卡片:抓拍服务状态、摄像头设备状态(待机/正在拍摄/未启用)、活跃线程数
- 摄像头说明提示:解释按需启用机制,避免误判设备故障
- 立即抓拍按钮:一键拍照即时验证设备
- 图片网格:浏览临时抓拍、永久抓拍和 GIF 动图
- 点击图片可查看大图
| 项目 | 要求 |
|---|---|
| 操作系统 | Windows 10 / 11 |
| Python | 3.8 或更高版本 |
| 磁盘空间 | ≥ 100 MB |
# 克隆仓库
git clone https://github.com/Kecoya/DailyRoutine-Monitoring.git
cd DailyRoutine-Monitoring
# 安装依赖
pip install -r requirements.txtpython main.py启动后打开浏览器访问 http://127.0.0.1:5000 即可查看 Web 界面。
python setup_autostart.py选择选项 1 即可在 Windows 启动文件夹中创建快捷方式,下次开机自动静默运行。
📖 更详细的安装和配置指南请参考 INSTALL.md
DailyRoutine-Monitoring/
├── main.py # 程序入口(含单实例检测、stdio 修复)
├── config.py # 全局配置文件
├── monitor_service.py # 核心监控服务(双缓冲计数器,pynput 零阻塞回调)
├── camera_service.py # 摄像头抓拍服务(时间段抓拍 + 固定时间抓拍 + GIF 生成)
├── database.py # 数据库访问层(SQLite WAL 模式)
├── analyzer.py # 数据分析模块(统计 + 图表生成)
├── web_app.py # Flask Web 服务器
├── silent_launcher.py # 静默启动器(用于开机自启,无窗口)
├── setup_autostart.py # 自启动配置工具
├── requirements.txt # Python 依赖列表
├── restart.bat # 安全重启脚本
├── 启动监控.bat # 一键启动(双击运行)
├── 安装依赖.bat # 一键安装依赖
├── templates/
│ └── index.html # Web 前端页面
├── static/ # 运行时生成的图表(自动清理)
├── data/ # 数据库文件(.gitignore 排除)
│ └── captures/ # 摄像头抓拍数据(.gitignore 排除)
└── logs/ # 日志文件(.gitignore 排除)
所有配置项集中在 config.py 中,可根据个人需求自由调整:
# ===== 监控配置 =====
MONITOR_INTERVAL = 60 # 数据保存间隔(秒),越小精度越高,数据量越大
IDLE_THRESHOLD = 600 # 空闲判定阈值(秒),10 分钟无活动视为空闲
NAP_TIME_START = 13 # 午休开始时间(小时)
NAP_TIME_END = 14.5 # 午休结束时间(小时)
# ===== Web 服务 =====
WEB_HOST = '127.0.0.1' # 绑定地址(默认仅本机访问)
WEB_PORT = 5000 # 端口号
# ===== 忙碌度计算权重 =====
BUSY_WEIGHTS = {
'mouse_activity': 0.30, # 鼠标活动权重
'keyboard_activity': 0.30, # 键盘活动权重
'window_switches': 0.20, # 窗口切换权重
'system_usage': 0.20 # 系统资源权重
}
# ===== 个人化设置 =====
LAB_WORK_HOURS = 8.5 # 每日标准工作时长(小时),用于计算工作达成率
PIXELS_PER_METER = 5200 # 鼠标距离换算系数,根据显示器调整
DATA_RETENTION_DAYS = 365 # 数据保留天数
# ===== 摄像头抓拍配置 =====
CAPTURE_ENABLED = True # 是否启用摄像头抓拍(设为 False 可完全禁用)
CAPTURE_CAMERA_ID = 0 # 摄像头设备 ID
CAPTURE_TIME_RANGES = [ # 时间段抓拍(保存为临时文件,结束时生成 GIF)
{"start": "11:30", "end": "14:30", "interval": 60},
{"start": "17:30", "end": "18:30", "interval": 60},
{"start": "21:30", "end": "23:59", "interval": 60},
]
CAPTURE_FIXED_TIMES = [ # 固定时间点抓拍(永久保存)
{"time": "08:50", "description": "morning"},
{"time": "14:50", "description": "noon"},
{"time": "19:50", "description": "night"},
]
CAPTURE_GIF_FPS = 24 # GIF 帧率
CAPTURE_CLEANUP_DAYS = 7 # 临时照片保留天数
CAPTURE_TIMESTAMP_ENABLED = True # 是否在照片上添加时间戳水印| 间隔 | 日数据量 | 年数据量 | 适用场景 |
|---|---|---|---|
| 5 秒 | ~3.4 MB | ~1.2 GB | 高精度分析 |
| 30 秒 | ~570 KB | ~200 MB | 均衡 |
| 60 秒 | ~280 KB | ~100 MB | 推荐默认 |
| 120 秒 | ~140 KB | ~50 MB | 低配设备 |
活动指标的计算已自动适配不同间隔(
interval_factor),无需手动调整其他参数。
基于典型显示器物理尺寸的经验换算值:
| 显示器 | 分辨率 | 参考值 |
|---|---|---|
| 24 寸 FHD | 1920×1080 | ~3600 |
| 27 寸 FHD | 1920×1080 | ~3200 |
| 27 寸 2K | 2560×1440 | ~4300 |
| 32 寸 4K | 3840×2160 | ~5500 |
可根据实际显示器测量值调整,计算方法:水平分辨率 ÷ (屏幕宽度cm ÷ 100)。
忙碌指数通过四维指标加权计算,范围 0-100:
BusyIndex = mouse_score × 0.30 + keyboard_score × 0.30
+ window_score × 0.20 + system_score × 0.20
每个子指标的归一化参考值(每分钟基准):
- 鼠标移动:5000 px → 50 分,点击:50 次 → 30 分,移动次数:500 → 20 分
- 键盘按键:300 次 → 100 分
- 窗口切换:10 次 → 100 分
- 系统占用:(CPU% + Memory%) / 2
当用户空闲时间超过阈值(默认 10 分钟)时,忙碌指数强制归零。
| 指标 | 公式 | 含义 |
|---|---|---|
| 工作强度 | (活动时长 × 忙碌指数) / 平均活动时长 | 综合投入程度 |
| 专注度 | 100 - (窗口切换次数 / 活动小时数) | 分数越高越专注 |
| 效率指数 | (鼠标点击 + 键盘按键) / 活动分钟数 | 操作活跃度 |
| 规律性 | max(0, 100 - 开机时间标准差 × 10) | 作息稳定程度 |
| 达成率 | 实际活动时长 / 标准工时 × 100% | 当日目标完成度 |
工作日的统计范围定义为 当天 00:00 ~ 次日 02:00,凌晨 0-2 点的活动自动归入前一天的统计,确保加班到凌晨的工作量不会丢失。
本系统在设计上最大程度保护用户隐私:
| 维度 | 说明 |
|---|---|
| 数据存储 | 仅使用本地 SQLite,无网络连接 |
| 键盘监控 | 仅记录按键次数,不记录按键内容 |
| 鼠标监控 | 仅记录移动距离和点击次数,不记录屏幕坐标 |
| 窗口标题 | 记录活动窗口标题用于分析,可选择性禁用 |
| 摄像头抓拍 | 摄像头按需初始化、空闲自动释放,照片仅存本地,可配置禁用 |
| 数据清理 | 支持自定义保留天数,过期数据自动清除 |
| 数据导出 | 所有数据可导出为 CSV/Excel,用户完全掌控 |
| 类别 | 技术 |
|---|---|
| 语言 | Python 3.8+ |
| Web 框架 | Flask |
| 数据库 | SQLite (WAL 模式) |
| 系统监控 | psutil, pynput, pywin32 (win32gui) |
| 摄像头抓拍 | opencv-python, schedule, Pillow |
| 数据分析 | pandas, numpy |
| 可视化 | matplotlib, seaborn |
| 数据导出 | openpyxl |
| 前端 | 原生 HTML/CSS/JS(无框架依赖) |
Flask # Web 服务器
psutil # 系统资源监控
pynput # 鼠标/键盘事件监听
pywin32 # Windows API(窗口管理、快捷方式)
matplotlib # 图表生成
pandas # 数据分析
numpy # 数值计算
seaborn # 统计可视化
openpyxl # Excel 导出
opencv-python # 摄像头抓拍
schedule # 定时任务调度
Pillow # GIF 动图生成
程序提示"已在运行中"怎么办?
这是内置的单实例检测机制,说明已有监控进程在后台运行。如果需要重启,请使用 restart.bat 或手动结束进程后重新启动。
Web 界面打不开?
- 确认程序正在运行(检查任务管理器中的 python/pythonw 进程)
- 尝试访问
http://127.0.0.1:5000(不是 localhost) - 检查端口 5000 是否被其他程序占用
- 查看日志文件
logs/monitor.log获取错误信息
开机自启动不生效?
- 运行
python setup_autostart.py选择选项3检查状态 - 按
Win+R输入shell:startup确认快捷方式是否存在 - 查看
logs/silent_launcher.log确认启动是否成功
鼠标移动距离不准?
PIXELS_PER_METER 的默认值基于 24 寸 1920×1080 显示器。如果你的显示器规格不同,请根据实际物理尺寸调整此值。计算方法见 配置说明 章节。
如何彻底卸载?
- 运行
python setup_autostart.py→ 选择2移除自启动 - 关闭正在运行的程序(Ctrl+C 或任务管理器结束进程)
- 删除项目文件夹
摄像头显示"待机(按需启用)"是不是设备故障?
不是故障。摄像头为按需启用设计:仅在配置的抓拍时间段或固定时间点自动打开,其余时间释放以供其他程序(会议、直播等)使用。因此"待机"是正常的空闲状态。
要验证摄像头是否可用,点击 Web 界面摄像头抓拍页的 "📸 立即抓拍" 按钮即可即时拍照。若按钮报错"摄像头无法打开",可能是设备被其他程序(如正在进行的视频会议)占用,关闭占用程序后重试。
为什么时间段抓拍后看不到新照片?
若项目路径中包含中文等非 ASCII 字符,早期版本因 OpenCV 文件 I/O 限制会导致抓拍静默失败。v1.3.1 已修复此问题(改用 imencode/imdecode + numpy 文件读写绕过)。若仍异常,请查看 logs/monitor.log 中的摄像头相关日志,或用"立即抓拍"按钮定位问题。
- 实时监控(鼠标/键盘/窗口/系统)
- Web 可视化界面
- 忙碌度曲线图 + 日历热力图 + 趋势图
- 周报/月报/自定义分析
- CSV/Excel 数据导出
- 开机自启动(静默运行)
- 单实例检测(防止多开)
- 线程安全(双缓冲计数器 + 图表生成锁)
- 摄像头定时抓拍(时间段抓拍 + 固定时间抓拍 + GIF 生成)
- 应用程序使用时长统计
- 系统托盘图标 + 右键菜单
- 多显示器支持
- 自定义忙碌度计算规则
- 移动端响应式适配
- 数据备份与恢复功能
欢迎提交 Issue 和 Pull Request!
- Fork 本仓库
- 创建特性分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 提交 Pull Request
本项目基于 MIT License 开源。
Made with ❤️ for researchers who want to track their daily routines.