# LubanHome **Repository Path**: hhxcaz/LubanHome ## Basic Information - **Project Name**: LubanHome - **Description**: 家庭物联网/智能家居开源平台:内置MQTT Broker + 数据采集网关 + 报警规则引擎 + 定时调度 + Vue3实时大屏,支持ESP8266/ESP32接入与OTA固件升级 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-18 - **Last Updated**: 2026-09-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # LubanHome 家庭物联网 / 智能家居系统 > 一套**开箱即用的家庭物联网 / 智能家居平台**:内置 MQTT Broker + 数据采集网关 + 报警规则引擎 + 定时调度 + Vue3 实时大屏,支持 ESP8266 / ESP32 真机接入与 OTA 固件升级。 ``` ESP8266/ESP32 设备 ──MQTT──► 内置Broker ──► Gateway(采集/入库/规则/报警) │ SQLite data.db │ API Server(:3000 REST + Web大屏 + SSE实时推送) ``` --- ## 目录 - [系统界面预览](#系统界面预览) - [一、功能全景](#一功能全景) - [二、系统架构](#二系统架构) - [三、技术栈](#三技术栈) - [四、目录结构](#四目录结构) - [五、快速开始(本地运行)](#五快速开始本地运行) - [六、详细配置说明](#六详细配置说明) - [七、固件开发指南(编译/烧录/接线/OTA)](#七固件开发指南) - [八、Web 使用说明](#八web-使用说明) - [九、REST API 汇总](#九rest-api-汇总) - [十、MQTT 协议](#十mqtt-协议) - [十一、用户权限系统](#十一用户权限系统) - [十二、报警与规则引擎](#十二报警与规则引擎) - [十三、定时任务](#十三定时任务) - [十四、数据可视化](#十四数据可视化) - [十五、测试](#十五测试) - [十六、部署(路由器 / 内网穿透)](#十六部署) - [十七、运维保障(备份/回滚/健康检查)](#十七运维保障) - [十八、开源说明](#十八开源说明) --- ## 系统界面预览 **PC 端** | 设备总览(实时数据大屏) | 远程控制 | |---|---| | ![PC 端设备总览](screenshots/pc-overview.png) | ![PC 端远程控制](screenshots/pc-control.png) | | 数据曲线 | 事件日志 | 用户权限设置 | |---|---|---| | ![PC 端数据曲线](screenshots/pc-charts.png) | ![PC 端事件日志](screenshots/pc-events.png) | ![PC 端设置](screenshots/pc-settings.png) | **移动端(响应式自适应布局)** | 设备总览 | 远程控制 | 用户权限设置 | |---|---|---| | ![移动端设备总览](screenshots/mobile-overview.png) | ![移动端远程控制](screenshots/mobile-control.png) | ![移动端设置](screenshots/mobile-settings.png) | > 深色科技风统一风格:PC 端左侧导航栏 + 移动端底部 Tab 栏;全部图表基于 ECharts 5(本地 vendor,无 CDN),PC / 移动端自适应。 --- ## 一、功能全景 ### 1.1 设备接入与远程控制 | 功能 | 说明 | |---|---| | 设备自动注册 | 设备首次上报能力(capabilities)即自动注册,无需手动添加 | | 设备 ID 自动生成 | 固件 `DEVICE_ID` 留空时,首次开机自动生成芯片唯一 ID(`esp8266-xxxxxxxx` / `esp32-xxxxxxxx`),零配置上线 | | 芯片型号自动识别 | `DEVICE_TYPE` 留空时按编译目标芯片自动识别(esp8266 / esp32 / esp32-cam) | | 远程控制 | 任意在线设备下发命令(开关/浇花/加热/抓拍/报警测试…),1 秒内回执 | | 设备实时状态 | 开关类状态(开/关)、长时任务(浇水中·剩余秒数)实时显示,SSE 推送 | | 命令回执确认 | 下发 → 设备 ACK → 入库回显全链路,超时自动标记 timeout,不永久挂起 | | 一机多用 | 同一固件烧录后,配网页可改设备类型/引脚/周期,无需重新烧录 | | OTA 远程升级 | 单台/批量推送固件,支持 MD5 校验、容量监控、失败回滚(双分区 A/B) | | 定时任务 | cron 五字段定时下发命令(定时开关、定时抓拍),Web 可视化配置 | ### 1.2 监控与报警 | 功能 | 说明 | |---|---| | 实时数据大屏 | 设备总数/在线率/报警数/累计读数 KPI + 设备状态卡 + SSE 实时推送 | | 数据曲线 | 原始/小时/天/月多粒度折线图(平均/最大/最小) | | 数据分析 | 在线率仪表盘、设备/事件/命令分布饼图、24h×星期热力图、每日活动柱状图 | | 开关统计 | 开关次数分布、响应速度分布、最近命令记录 | | 报警规则引擎 | 数值阈值报警(可设死区回差、连续确认防误报、冷却、自动恢复) | | 自定义预警值 | 不同设备/分组/分类单独设置阈值(设备级、组级、类级) | | 报警闭环 | 触发 → 确认 → 忽略 → 归档,报警历史报表 | | 事件日志 | 设备上下线、报警、命令、规则触发全记录 | | 摄像头抓拍 | ESP32-CAM 定时/远程抓拍,图片管理(查看/删除/清除) | ### 1.3 权限与多用户 | 功能 | 说明 | |---|---| | 角色权限 | admin(管理员)/ operator(操作员)/ viewer(访客)三内置角色 | | 自定义权限点 | 7 个权限点任意组合(设备查看/控制/管理、定时、规则、用户、设置) | | 设备范围控制 | 每个用户可限定可见/可控设备(all 或指定设备列表) | | 数据权限联动 | 总览、数据分析、事件日志、统计接口全部按设备范围过滤,数字一致 | | 登录安全 | 失败 5 次锁定 15 分钟、密码强度校验 | ### 1.4 数据与运维 | 功能 | 说明 | |---|---| | 数据库自动备份 | 启动备份 + 每日定时备份(可设保留份数),Web 一键下载/删除 | | 一键回滚 | `rollback.py` 自动停服务 → 安全备份 → 恢复 → 重启 | | 健康检查/守护 | `healthcheck.py` + `watchdog.py` 自动拉起故障服务 | | 读数自动归档 | 保留最近 7 天原始读数,更早自动聚合到小时/天统计,防数据库无限膨胀 | | 日志清除 | 按 7/14/30/365 天前清除事件/命令日志,或清空全部 | | 数据导出 | 读数 CSV 导出 | | Windows 开机自启 | 计划任务 + 常驻守护 | --- ## 二、系统架构 ``` ┌──────────────────────────────────────────────┐ │ start_all.py 单进程 │ │ │ ESP8266/ESP32 ──────► │ ① 内置 MQTT Broker (:1883) │ (MQTT 3.1.1) │ │ │ │ ▼ │ │ ② gateway.py 订阅 dev/# │ │ · 数据/事件/ACK/状态/媒体入库 │ │ · 心跳检测 → 在线/离线 │ │ · 规则引擎 → 报警/联动/邮件 │ │ │ │ │ ▼ │ │ SQLite data.db(七张表 + 聚合表) │ │ ▲ │ │ ③ api_server.py REST (:3000) │ │ · 用户鉴权 / 设备/命令/日志/设置 API │ │ · 静态页面(Vue3 SPA)+ SSE 实时推送 │ │ · MQTT 发布器(命令下发) │ │ ④ scheduler.py 定时任务(cron → 下发命令) │ │ ⑤ 读数归档线程(每小时聚合 7 天前原始数据) │ │ ⑥ 自动备份线程(每日 03:30,保留 N 份) │ └──────────────────────────────────────────────┘ ▲ │ SSE (EventSource) Web 前端(浏览器) ``` **模块职责**: | 模块 | 职责 | |---|---| | `broker.py` | 内置 MQTT 3.1.1 Broker(设备接入点,支持账号鉴权;端口被占用时自动让位给外部 mosquitto) | | `gateway.py` | 采集网关:订阅 `dev/#`,主题分派(data/event/ack/status/capabilities/media);高优先级队列保证命令回执即时;心跳超时判离线 | | `api_server.py` | REST API + Vue 静态页面 + SSE 实时推送 + 用户鉴权 + MQTT 命令发布器 | | `db.py` | SQLite 访问层(设备/读数/事件/命令/媒体/用户/定时任务/阈值/分组分类/固件/设置),WAL 模式 | | `rules.py` | 规则引擎:数值/事件触发 → 报警/联动命令,防误报确认、死区回差、冷却、自动恢复 | | `auth.py` | 用户认证(pbkdf2 密码哈希、token 会话、登录锁定)+ 角色权限矩阵 + 设备范围 | | `scheduler.py` | cron 五字段解析,到点经 MQTT 下发命令(命令来源 `cron`) | | `notifier.py` | 报警通知(邮件/日志,可扩展) | | `backup.py` | SQLite WAL 在线备份 + 保留份数清理 | | `rollback.py` | 一键回滚到指定备份 | | `healthcheck.py` / `watchdog.py` | 健康检查 / 自动拉起 | | `simulator.py` | 模拟设备(13 台虚拟设备、多场景、--fast 加速) | | `web/` | Vue3 前端(本地 vendor,无 CDN,兼容 PC / 移动端) | | `luban_firmware/` | ESP8266/ESP32 统一固件骨架 + 12 类设备驱动 | --- ## 三、技术栈 | 层 | 技术 | |---|---| | 后端 | Python 3(标准库 + paho-mqtt **1.x / 2.x 兼容**,零框架零重量依赖) | | 数据库 | SQLite(WAL 模式,单文件,免安装) | | MQTT | 内置 Broker(MQTT 3.1.1),兼容 mosquitto 2.x | | 前端 | Vue 3(本地 vendor 文件,**无 CDN**)+ ECharts 5 + 原生 hash 路由 | | 实时 | SSE(EventSource)全量快照 + 增量推送,断线自动降级轮询 | | 固件 | Arduino 框架(ESP8266/ESP32),统一骨架 + 12 类驱动,OTA 双分区升级 | --- ## 四、目录结构 ``` LubanHome/ ├── 物联网系统设计文档.md # 系统设计背景与方案 ├── 物联网开发环境清单.md # 开发环境 / 工具链清单 ├── 系统功能清单与测试记录.md # 功能清单与迭代测试记录 ├── README.md # 本文件 └── iot/ ├── start_all.py # 一键启动(broker+gateway+api+调度+归档+备份) ├── config.py # 全局配置(环境变量覆盖) ├── broker.py # 内置 MQTT Broker ├── gateway.py # 采集网关(消息双队列 + 高优先级 ACK) ├── api_server.py # REST API + 静态页面 + SSE ├── db.py # SQLite 访问层 ├── auth.py # 用户/权限 ├── rules.py / rules.json # 规则引擎 / 规则配置(可编辑) ├── scheduler.py # 定时任务 ├── backup.py / rollback.py # 备份 / 回滚 ├── healthcheck.py / watchdog.py / install_service.ps1 # 运维 ├── simulator.py # 模拟设备 ├── capabilities.json # 设备能力声明(自动生成界面依据) ├── requirements.txt # 唯一依赖 paho-mqtt ├── tests/ # 单元 + 端到端测试 ├── scripts/ # 辅助脚本(清理等) ├── web/ # Vue3 前端(vendor 本地化) ├── luban_firmware/ # ESP8266/ESP32 固件(统一骨架 + 驱动) ├── media/ # 摄像头抓拍 / 固件文件(运行时生成) ├── backup/ # 数据库备份(运行时生成) └── data.db # 数据库(运行时生成) ``` --- ## 五、快速开始(本地运行) ### 5.1 环境要求 - Python 3.8+ - 一台可上网的电脑(Windows / Linux / macOS 均可) ### 5.2 安装与启动 ```bash # 1. 进入 iot 目录 cd iot # 2. 安装依赖(唯一外部依赖 paho-mqtt) pip install -r requirements.txt # 3. 终端 1:一键启动(内置 broker + gateway + API + 调度器 + 备份 + 归档) python start_all.py # 4. 终端 2:启动模拟设备(--fast 10 = 10 倍速模拟真实设备) python simulator.py --fast 10 # 5. 打开浏览器 # http://127.0.0.1:3000 # 默认管理员:admin / admin123 (首次登录后请在「设置→用户管理」修改密码) ``` 启动成功后控制台会显示: ``` 家庭物联网系统已启动 ─ Web 界面: http://127.0.0.1:3000 (admin / admin123) ─ MQTT: 127.0.0.1:1883 ─ 数据库: ...\data.db ─ 备份目录: ...\backup(每日 03:30 自动备份,保留 5 份) ``` ### 5.3 模拟器用法 ```bash python simulator.py --fast 10 # 默认场景,13 台虚拟设备,10 倍速 python simulator.py --fast 10 --scenario all # 多场景并行(烟雾/燃气/漏水/高温/干旱/雾霾) python simulator.py --fast 10 --scenario fire # 仅烟雾报警场景 python simulator.py --fast 10 --devices temp_living,sw1 # 只模拟指定设备 python simulator.py --fast 3 # 3 倍速(低负载,命令回执更快) ``` > 提示:`--fast` 越大数据上报越密,对后端压力越大。日常测试推荐 `--fast 3`,做报警演示可用 `--fast 10`。 --- ## 六、详细配置说明 ### 6.1 后端环境变量(config.py) 所有配置均可用环境变量覆盖,前缀 `IOT_`: | 环境变量 | 默认值 | 说明 | |---|---|---| | `IOT_DB_PATH` | `./data.db` | SQLite 数据库文件路径 | | `IOT_MEDIA_DIR` | `./media` | 摄像头抓拍 / 固件文件存储目录 | | `IOT_WEB_DIR` | `./web` | 前端静态页面目录 | | `IOT_RULES_FILE` | `./rules.json` | 规则引擎配置文件 | | `IOT_CAP_FILE` | `./capabilities.json` | 设备能力声明文件 | | `IOT_MQTT_HOST` | `127.0.0.1` | MQTT Broker 地址(部署到路由器时改为路由器 IP) | | `IOT_MQTT_PORT` | `1883` | MQTT 端口 | | `IOT_MQTT_USER` | `""` | MQTT 账号(留空=匿名) | | `IOT_MQTT_PASS` | `""` | MQTT 密码 | | `IOT_API_HOST` | `0.0.0.0` | API 监听地址 | | `IOT_API_PORT` | `3000` | Web/API 端口 | | `IOT_OTA_HOST` | 自动探测局域网 IP | OTA 固件下载地址(板子需能访问,内网穿透时填公网域名) | | `IOT_AUTH_MODE` | `user` | 鉴权模式:`user`=完整用户系统(默认);`off`=免登录(仅本地调试) | | `IOT_WEB_TOKEN` | `""` | 兼容旧配置:token 模式下写操作需该 Bearer token | | `IOT_OFFLINE_TIMEOUT` | `120` | 设备离线判定秒数(3 个心跳周期) | | `IOT_HB_CHECK` | `10` | 心跳检查间隔秒数 | | `IOT_ALERT_CONFIRM` | `3` | 安全设备报警连续确认次数(防误报) | | `IOT_EMAIL_ENABLED` | `0` | 邮件通知开关(`1` 开启) | | `IOT_EMAIL_CMD` | `""` | 邮件发送命令模板(如 msmtp) | | `IOT_EMAIL_TO` / `IOT_EMAIL_FROM` | `""` | 收件人 / 发件人 | | `IOT_BACKUP_DIR` | `./backup` | 备份文件目录 | | `IOT_BACKUP_KEEP` | `5` | 备份保留份数(Web 设置页可改 1~60) | | `IOT_BACKUP_HOUR` / `IOT_BACKUP_MIN` | `3` / `30` | 每日自动备份时间 | ### 6.2 Web 设置页可配置项(运行时生效,无需重启) | 配置 | 位置 | 说明 | |---|---|---| | 用户/角色/权限点/设备范围 | 设置→用户管理 | 多用户管理 | | 定时任务 | 设置→定时任务 | cron 表达式增删改/启停 | | 阈值预警 | 设置→报警阈值 | 设备/分组/分类级数值阈值 | | 设备分类与分组 | 设置→设备分类分组 | 归类管理(可重命名/删除) | | MQTT 鉴权 | 设置→MQTT 设置 | 启用共享账号 + 用户名/密码(网关/模拟器自动同步) | | 邮件通知 | 设置→邮件通知 | 报警邮件(测试发送) | | 固件管理 | 设置→固件升级 | 上传 .bin,单台/批量推送 | | 数据维护 | 设置→数据维护 | 备份(立即备份/保留份数/下载/删除)、日志清除、数据库压缩 | ### 6.3 固件配置(luban_config.h) 固件所有出厂默认配置集中在 `iot/luban_firmware/luban_config.h`,首次开机写入 EEPROM,之后均可在**配网页**(热点 `LubanHome-XXXX` → `192.168.4.1`)修改并保存,**无需重新烧录**: | 配置项 | 说明 | |---|---| | `DEVICE_ID` | 设备唯一 ID(英文数字下划线);**留空 `""` 则首次开机自动生成芯片唯一 ID**,零配置上线 | | `DEVICE_NAME` | 显示名称(UTF-8,配网页可改) | | `DEVICE_TYPE` | 芯片型号;**留空=编译时自动识别**(esp8266 / esp32 / esp32-cam),也可手动填 | | `DEVICE_LOCATION` | 安装位置(配网页可改) | | `FW_VERSION` | 固件版本号(显示在设备状态,OTA 依据) | | `WIFI_SSID` / `WIFI_PASS` | WiFi 账号密码(**烧录后可在配网页修改,支持换 WiFi**) | | `MQTT_HOST` / `MQTT_PORT` | 服务器地址(运行 start_all.py 的主机 IP)与端口 | | `MQTT_USER` / `MQTT_PASS` | MQTT 鉴权凭据(留空=无鉴权;与 Web 设置页 MQTT 鉴权账号对应) | | `MQTT_KEEPALIVE` | 心跳保活秒数 | | `DEVICE_KIND` | **出厂默认设备类型(1~12)**:决定这台板子当什么用(开关/浇花/温湿度/烟雾…);配网页可改,一机多用 | | `SWITCH_CMDS` | 开关命令集:0=relay_on/off(开关),1=water_start/stop(水泵) | | `TASK_DURATION` | 长时任务时长(秒):浇花水泵浇 N 秒自动停;0=手动停不自动关 | | `PIN_RELAY` / `PIN_RELAY2` | 继电器引脚(开关/水泵/加热/加湿/除湿) | | `PIN_DHT` / `DHT_TYPE` | DHT 温湿度引脚与型号(DHT11/DHT22) | | `PIN_ADC` | 模拟采样引脚(土壤/烟雾/燃气/漏水) | | `SOIL_DRY_VAL` / `SOIL_WET_VAL` | 土壤干/湿 ADC 标定值 | | `PIN_DIGITAL` | 数字输入引脚(门窗磁干簧管 / 人体感应 PIR) | | `PIN_PMS_*` / `PIN_MHZ_*` | 空气质量站串口引脚(PMS5003 / MH-Z19,编译期固定) | | `PIN_DS18B20` / `WATER_LEVEL_PIN` / `FEED_PIN` | 鱼缸:水温传感器/水位/投喂引脚 | | `REPORT_INTERVAL` | 周期上报读数间隔(秒) | | `API_TOKEN` | 摄像头抓拍上传用的设备账号 token(鉴权模式必填,可选) | **12 种设备类型**(配网页下拉与系统 capabilities 对齐): | 值 | 类型 | 典型设备 | 主要硬件 | |---|---|---|---| | 1 | `DT_SWITCH` 继电器开关 | 客厅开关 sw1 | 继电器 | | 2 | `DT_DHT` 温湿度计 | 客厅温度计 temp_living | DHT11/22 | | 3 | `DT_HUMID` 湿度联动站 | hum_station | DHT + 加湿/除湿继电器 | | 4 | `DT_AIR` 空气质量站 | air_quality | PMS5003 + MH-Z19 | | 5 | `DT_SOIL` 土壤湿度 | soil_garden | 土壤传感器(ADC) | | 6 | `DT_SMOKE` 烟雾报警 | smoke_kitchen | MQ-2 | | 7 | `DT_GAS` 燃气报警 | gas_kitchen | MQ-5 | | 8 | `DT_LEAK` 漏水检测 | leak_bathroom | 漏水探针(ADC) | | 9 | `DT_DOOR` 门窗磁 | door_front | 干簧管 | | 10 | `DT_MOTION` 人体感应 | motion_hall | PIR | | 11 | `DT_AQUARIUM` 鱼缸温控 | aquarium | DS18B20 + 加热/投喂 | | 12 | `DT_CAM` 摄像头 | cam1 | ESP32-CAM(仅 ESP32-CAM) | > 浇花水泵是 `DT_SWITCH` + `SWITCH_CMDS=1` + `TASK_DURATION=30` 的组合(water_start 浇 30s 自动停)。 ### 6.4 数据库表结构(data.db) | 表 | 说明 | |---|---| | `devices` | 设备元信息(ID/名称/位置/类型/分类/分组/在线状态/固件版本) | | `readings` | 原始读数(device_id + metric + value + ts),7 天后自动聚合归档 | | `readings_agg` | 聚合读数(hour/day/month) | | `events` | 事件日志(上线/离线/报警/命令/规则/媒体…) | | `commands` | 命令记录(下发/ACK/耗时/结果/来源) | | `media` | 媒体索引(摄像头抓拍) | | `users` / `user_perms` | 用户 / 额外权限点 | | `roles` / `role_perms` | 角色 / 角色权限 | | `schedules` | 定时任务 | | `thresholds` | 报警阈值(设备/分组/分类级) | | `groups` / `categories` | 设备分组 / 分类 | | `firmware` | 固件版本库 | | `settings` | KV 设置(MQTT 鉴权、备份保留、邮件…) | --- ## 七、固件开发指南 ### 7.1 硬件接线(摘要,完整版见 `iot/luban_firmware/硬件接线指南.md`) | 设备类型 | 接线 | |---|---| | 开关/水泵 | 继电器 IN → `GPIO4`,板子 3V3 → 继电器 VCC,GND → GND | | 温湿度 DHT | DHT 数据 → `GPIO2`,VCC → 3V3,GND → GND(DHT22 需 4.7kΩ 上拉) | | 土壤/烟雾/燃气/漏水 | 传感器 AO → `A0`(ESP8266 唯一 ADC;ESP32 任意 ADC 引脚) | | 门窗磁/人体感应 | 干簧管/PIR OUT → `GPIO12`,VCC → 3V3,GND → GND | | 空气质量站 | PMS5003 TX→`GPIO16`/RX→`GPIO17`;MH-Z19 TX→`GPIO18`/RX→`GPIO19` | | 鱼缸温控 | DS18B20 数据 → `GPIO14`(4.7kΩ 上拉),水位 → `GPIO13`,投喂电机 → `GPIO15` | | 摄像头 | ESP32-CAM 用板上默认引脚,无需配置 | ### 7.2 编译与烧录(Arduino) ```bash # 方式一:Arduino IDE # 1. 打开 iot/luban_firmware/luban_firmware.ino # 2. 按需修改 luban_config.h(WiFi / 服务器 IP / 设备类型) # 3. 工具→开发板:ESP8266 选 "NodeMCU 1.0 (ESP-12E)",ESP32 选对应型号 # 4. 项目→导出编译的二进制文件(OTA 用 .bin) # 5. 上传(选串口,如 COM4) # 方式二:arduino-cli(命令行) arduino-cli compile --fqbn esp8266:esp8266:nodemcuv2 luban_firmware arduino-cli upload -p COM4 --fqbn esp8266:esp8266:nodemcuv2 luban_firmware ``` **内存注意**:ESP8266 有 1MB/4MB 闪存版本之分,编译时按板子实际容量选择 Flash Size(4MB 板子若选了 1MB 配置会烧录失败)。OTA 双分区升级要求固件体积 < 闪存一半。 ### 7.3 配网(首次开机 / 换 WiFi) 1. 板子连不上 WiFi 时自动开热点 `LubanHome-XXXX` 2. 手机连接该热点 → 打开 `192.168.4.1` 3. 配置页填写:WiFi 账号密码、设备 ID/名称/位置、设备类型、引脚、上报周期(19 个字段) 4. 保存后板子自动重启接入系统 ### 7.4 OTA 远程升级 - 系统「设置→固件升级」上传编译好的 `.bin` - 勾选设备 → 推送(可**全选/反选**批量升级,也可单台升级) - 固件下载后校验 MD5,**失败自动回滚**到另一分区,不砖 - 设备端支持双分区 A/B 方案,容量不足(1MB 板)时自动拒绝 ### 7.5 远程恢复出厂(reset_cfg) 设备已接入时,向 `dev//cmd` 发布 `{"id":"...","command":"reset_cfg","params":{}}`: - EEPROM 恢复为编译期默认值(WiFi / 服务器 / 设备 ID / 名称 / 类型) - 自动重启,按新配置重新上线(设备 ID 留空则重新自动生成) **典型用途**:切换服务器 IP、换 WiFi、一机多用改设备类型——免拆机、免重烧,远端一键完成。 --- ## 八、Web 使用说明 | 页面 | 路由 | 功能 | |---|---|---| | 登录 | `#/login` | 账号登录(失败 5 次锁 15 分钟) | | 设备总览(首页) | `#/overview` | 实时数据大屏:KPI 大数字 + 设备状态卡 + 分组筛选 + 报警横幅;点设备卡开详情抽屉 | | 控制面板 | `#/control` | 按设备下发命令、查看状态、添加定时任务 | | 数据曲线 | `#/charts` | 多设备多指标折线图(原始/小时/天/月) | | 数据分析 | `#/analysis` | 在线率仪表盘 + 分布饼图 + 热力图 + 柱状图(默认近 7 天,可筛选) | | 开关统计 | `#/switches` | 开关次数分布、响应速度分布、最近命令记录 | | 事件日志 | `#/events` | 全量事件(类型筛选/搜索/CSV 导出) | | 摄像头 | `#/camera` | 抓拍图片查看/删除/清除 | | 设置 | `#/settings` | 用户权限、定时任务、阈值、分类分组、MQTT/邮件、固件、数据维护 | **设备详情抽屉**(任意页面点设备卡打开): - 当前状态(开/关芯片、运行中·已运行秒数、浇水中·剩余秒数) - 实时数据(温度/湿度等最新读数) - 控制命令(按能力自动生成按钮) - 最近事件 / 报警详情 - 编辑设备(名称/位置/分类/分组) --- ## 九、REST API 汇总 鉴权:除 `/api/login` 外全部需 `Authorization: Bearer `。 | 方法 | 路径 | 说明 | |---|---|---| | POST | `/api/login` / `/api/logout` | 登录 / 登出 | | GET | `/api/me` | 当前用户 + 权限点 | | GET/POST | `/api/users` | 用户列表 / 新增 | | PUT/DELETE | `/api/users/` | 修改 / 删除用户 | | GET | `/api/devices` | 设备列表 + 状态 + 最新读数 + 能力 | | PUT | `/api/devices/` | 改名称/位置/分类/分组 | | POST | `/api/devices/batch` | 批量操作(分组/分类) | | GET | `/api/summary` | 首页总览数据 | | GET | `/api/readings?device=&metric=&from=&to=&interval=` | 读数查询(raw/hour/day/month) | | GET | `/api/events?device=&type=&from=&to=` | 事件日志 | | POST | `/api/events/clear` | 清除事件日志 `{days}`(0=全部) | | GET | `/api/commands?device=&agg=` | 命令记录 / 统计(count/avg_latency/distribution) | | POST | `/api/commands/clear` | 清除命令日志 `{days}` | | GET | `/api/media` / PUT `/api/media/upload` | 媒体索引 / 上传 | | POST | `/api/media/clear` | 清除媒体 `{days}` | | GET | `/api/export?device=&metric=` | 读数 CSV 导出 | | GET | `/api/alerts` | 活动报警 | | POST | `/api/alerts/ack` / `/api/alerts/ignore` | 确认 / 忽略报警 | | GET | `/api/capabilities` | 设备能力声明 | | GET | `/api/stats/*` | 可视化数据源(overview/heatmap/daily/compare/metric_rank/event_types/command_results) | | POST | `/api/command` | 下发命令 `{"device":"sw1","command":"relay_on"}` | | POST | `/api/command/status` | 查询命令状态 `{"id":"c..."}` | | GET/POST | `/api/schedules` | 定时任务列表 / 新增 | | PUT/DELETE | `/api/schedules/` | 修改 / 删除 | | POST | `/api/schedules//toggle` | 启用 / 停用 | | GET/POST | `/api/thresholds` | 报警阈值列表 / 新增 | | PUT/DELETE | `/api/thresholds/` | 修改 / 删除阈值 | | GET/POST | `/api/roles` | 角色列表 / 新增自定义角色 | | PUT/DELETE | `/api/roles/` | 角色权限修改 / 删除 | | GET/POST | `/api/groups` | 分组分类列表 / 新增 | | POST | `/api/groups/rename` | 分组重命名(同步设备) | | DELETE | `/api/groups/` | 删除分组(设备回归未分组) | | GET/POST | `/api/settings/mqtt` | MQTT 鉴权配置 | | GET/PUT | `/api/settings/mail` | 邮件通知配置 | | POST | `/api/settings/mail/test` | 测试邮件 | | GET/POST | `/api/backups` / `/api/backup` | 备份列表 / 立即备份 | | GET | `/api/backups/download?name=` | 下载备份 | | POST | `/api/backups/delete` | 删除备份 | | GET/PUT | `/api/settings/backup` | 备份保留设置 | | POST | `/api/db/vacuum` | 压缩数据库 | | GET/POST | `/api/firmware` | 固件列表 / 上传 | | POST | `/api/firmware/push` | 推送升级 `{firmware_id, device_ids}` | | GET | `/api/stream?token=` | SSE 实时推送(EventSource) | | GET | `/api/capabilities?device=` | 单设备能力 | | GET | `/api/rules` / `/api/rules/` | 规则列表 / 详情 | --- ## 十、MQTT 协议 ``` dev//capabilities 设备→系统 能力声明(自动注册 + 生成界面) dev//data 设备→系统 {"temperature":26.5,"humidity":58}(key 即 metric) dev//event 设备→系统 {"type":"motion_detect","detail":{}} dev//cmd 系统→设备 {"id":"c...","command":"relay_on","params":{}}(reset_cfg=远程恢复出厂) dev//ack 设备→系统 {"id":"c...","result":"ok","latency_ms":85} dev//media 设备→系统 {"type":"image","path":"...","size":45210} dev//status 设备→系统 {"status":"online","battery":92,"fw_version":"1.2.0"} ``` **内置命令**:`relay_on` / `relay_off`(开关)、`water_start` / `water_stop`(水泵)、`ota`(固件升级)、`reset_cfg`(远程恢复出厂)、`capture`(摄像头抓拍)、`alarm_test`(报警测试)。 **命令闭环**:Web 下发 → broker → 设备执行 → ACK 回传 → gateway 高优先级队列入库 → 前端 SSE/轮询回显。全链路 1 秒内,设备掉线/超时自动标记 timeout。 --- ## 十一、用户权限系统 **内置角色**: | 角色 | 设备查看 | 设备控制 | 定时任务 | 联动规则 | 用户管理 | 系统设置 | |---|---|---|---|---|---|---| | admin 管理员 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | operator 操作员 | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ | | viewer 访客 | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | **7 个权限点**:`device.view` 查看、`device.control` 控制、`device.manage` 管理、`schedule.manage` 定时、`rule.manage` 规则、`user.manage` 用户、`settings.manage` 设置。 **设备范围**:每个用户可限定 `all` 或指定设备列表(如 `sw1,cam1`),范围外数据返回 403;统计接口与事件日志按范围过滤,保证各页数字一致。 --- ## 十二、报警与规则引擎 规则配置在 `iot/rules.json`(可编辑,不硬编码): ```json { "when": {"device": "smoke_kitchen", "metric": "smoke_level", "op": ">", "value": 60}, "then": [{"action": "raise_alert", "level": "critical", "title": "烟雾报警"}, {"device": "relay_power", "command": "relay_off"}], "confirm_count": 3, "cooldown": 60, "recover": {"op": "<", "value": 30} } ``` - 数值触发:`metric op value`;事件触发:`{"device":"door_front","event":"door_open"}` - 动作:`raise_alert`(报警)/ `command`(联动下发)/ `notify`(通知) - `confirm_count` 连续 N 次采样确认防误报;`cooldown` 冷却防刷屏;`recover` 自动恢复条件 - 阈值预警(Web 设置页):设备级 / 分组级 / 分类级单独设置,不同场景不同数值 --- ## 十三、定时任务 cron 五字段:`分(0-59) 时(0-23) 日(1-31) 月(1-12) 周(0-6, 0=周日)` - 支持 `*`、`1,3`、`2-6`、`*/10`,如每天 8:30 = `30 8 * * *` - 到点自动经 MQTT 下发命令,下次执行时间自动刷新 - 「控制面板」可为当前设备快捷添加,「设置」统一管理 --- ## 十四、数据可视化 - **设备总览**:深色实时大屏,KPI + 设备状态卡 + 分组筛选 + LIVE 时钟 - **数据曲线**:多粒度折线图(原始/小时/天/月 × 平均/最大/最小) - **数据分析**:在线率仪表盘、设备/事件/命令分布饼图、24h×星期热力图、每日活动柱状图 - **开关统计**:开关次数分布、响应速度分布、最近命令记录 - 全部图表基于 ECharts 5(本地 vendor,无 CDN),深色主题统一风格 --- ## 十五、测试 ```bash # 单元测试(数据库 + 规则引擎 + 用户/权限点/分组/调度/统计) cd iot python -m unittest tests.test_db -v # 端到端测试(broker+gateway+api+模拟器全链路,含权限/调度/统计/范围过滤/分组管理) python tests/e2e_test.py ``` --- ## 十六、部署 ### 16.1 路由器部署(OpenWrt) 已实测:OpenWrt 25.x(x86 / ARM 均可),Python 3.13 + paho-mqtt **1.6.1** 直接运行——后端已做 paho 1.x/2.x 兼容,无需升级依赖。 ```bash # 1. 上传代码到路由器(dropbear 无 sftp 时用 scp,或 tar 管道传输) scp -r iot root@192.168.1.1:/root/lubanhome # 2. 释放 1883 端口(若装了系统自带 mosquitto) service mosquitto stop && service mosquitto disable # 3. 创建 procd 服务(开机自启 + 崩溃自动拉起) cat > /etc/init.d/lubanhome <<'EOF' #!/bin/sh /etc/rc.common START=99 STOP=10 USE_PROCD=1 start_service() { procd_open_instance procd_set_param command /usr/bin/python3 -u /root/lubanhome/start_all.py procd_set_param working_directory /root/lubanhome procd_set_param stdout 1 procd_set_param stderr 1 procd_set_param respawn 3600 5 5 procd_close_instance } EOF chmod +x /etc/init.d/lubanhome /etc/init.d/lubanhome enable && /etc/init.d/lubanhome start # 4. 验证(两个端口都监听即成功) netstat -tln | grep -E '1883|3000' ``` > ⚠️ **不要用 `python3 ... &` 直接后台**:busybox 无 `nohup`,SSH 断开后进程会被 SIGHUP 杀掉。务必用 procd / init.d 托管。 > > 固件侧的 `MQTT_HOST` 改为路由器 IP(如 `192.168.1.1`),重新烧录或用 `reset_cfg` 远程恢复出厂即可切换,**无需改后端任何配置**。 ### 16.2 内网穿透(公网访问) - 系统**不写死任何 host**:OTA 地址用 `IOT_OTA_HOST` 覆盖,MQTT 地址用 `IOT_MQTT_HOST` 覆盖 - 内网穿透时填公网域名:`export IOT_MQTT_HOST=your.domain.com`、`export IOT_OTA_HOST=your.domain.com` - 公网暴露前**务必**:启用 `IOT_AUTH_MODE=user`、修改默认管理员密码、开启 MQTT 密码鉴权 --- ## 十七、运维保障 ```bash python backup.py # 手动备份一次 python backup.py --list # 查看备份 python rollback.py list # 列出备份 python rollback.py 2 # 回滚到第 2 份(自动停服务→安全备份→恢复) python healthcheck.py # 检查 Web+MQTT+API 健康状态 python watchdog.py --once # 单次检查,异常自动重启 python watchdog.py --daemon # 常驻守护(每 30s 检查,连续 3 次失败重启) # Windows 开机自启(管理员 PowerShell) powershell -ExecutionPolicy Bypass -File install_service.ps1 ``` **数据维护(Web 设置页)**:自动备份(每日 03:30,保留 N 份,可下载/删除)、日志清除(7/14/30/365 天前或全部)、数据库压缩、读数自动归档(保留 7 天原始,更早聚合)。 --- ## 十八、开源说明 - 本项目为个人家庭物联网项目开源,欢迎 Fork / Star / Issue - 代码结构清晰、注释完整,可自由修改用于学习与家庭部署 - **安全提示**:默认管理员 `admin/admin123` 与默认 MQTT 凭据仅限内网测试;公网部署前请务必修改所有默认凭据 - 固件默认配置(`luban_config.h`)为占位符,编译前请填写你自己的 WiFi / 服务器信息 **相关文档**:`物联网系统设计文档.md`(设计方案)、`物联网开发环境清单.md`(环境搭建)、`系统功能清单与测试记录.md`(功能与迭代记录)。