阿库娅很不错,要整一个吗?


能养成的智能家居系统?好诶!不是虚拟美少女?!!但是但是,大厂生态哪有亲手养大的安心?

(可惜是个智障.webp

我又不是智障

网关部分

食材

项目大体分为两个阶段。第一阶段,改造现有设备然后接入树莓派 4B,通过 Web 应用实现远程控制,调研中转到 Google Home 的方法(到此为止了)。第二阶段,加持先进的 ML (Magic Learning) 技术,实现 AI (Artificial Idiot) 中枢,彻底替换 Google Home。主要技术指标如下。

  • 远程控制继电器
  • 跨平台用户界面
  • 断网也能使用
  • 接入 Google Home
  • 开源(但不一定安全)
  • 美少女皮 + 自定义唤醒词

先不管有生之年的技术指标,第一阶段用到的软件如下。

  • 后端
    • Raspbian Buster (arm64)
    • Flask
    • OpenCV 4.2
    • MariaDB 10.4
    • Nginx
  • 前端
    • Jinja2
    • Bootstrap 4

推荐的开发工具。

  • 宇宙第一 VS Code
  • 宇宙第二 PyCharm
  • 不入流 Keil C51

为避免消化不良,还需掌握如下技巧。

  • 对硬件一知半解
  • 擅长使用 Google

应用架构

网关硬件就用树莓派,主要提供 REST API,配合 Web 界面进行交互,实现远程控制设备。也可接入第三方服务,比如 Google home(嘤语学习好助手)。

为了快速上线,后端咱就用了 Python。框架采用 Flask,是一个采用模块化设计理念的 Web 应用框架,也被称为微框架。Flask 没太多默认配置,可以通过 Flask-extension 引入如 MySQL ORM,模板引擎,表单和身份验证等插件。程序使用 MVC 分层架构,便于协作开发和后续扩展,同样为了加速,暂时使用 Jinja2 模板生成器糊出来的前端。

数据库

MariaDB 是 MySQL 在 MySQL 的基础上改进的关系型数据库,在提升性能的同时保持与 MySQL 的完全兼容,仅需简单卸载 MySQL 并安装 MariaDB 即可。

参见 E-R 图,config 表保存传感器节点的状态,包括传感器类型,环境数据最大值和最小值,传感器或执行器状态,上次动作源等。sensor 表保存传感器历史数据,外键连接 config 表。camera 表保存连续运动的发生时间和截图路径。user 表储存用户信息,包括登录名称,用户邮箱,密码等数据。

运动检测

OpenCV 已经实现了多种常见的检测算法。MOG 算法是一个背景分割算法,以混合高斯模型为基础。此算法使用多个高斯分布混合计算对背景像素建模,指定权重为像素点 RGB 值在整个序列中的持续时间。若一个 RGB 值属于背景像素点,那么它的持续时间相对于运动像素长,相应的权重也更高。

MOG2 是 MOG 算法的改进。它为每一个像素点单独计算高斯分布,这样能更好的适应由于亮度,噪点等外部参数发生变化而引起的场景变化。

GMG 算法结合了贝叶斯分割法和静态背景估算法,使用图像序列的一些帧建立背景模型,然后通过贝叶斯估计 (Bayesian Estimation) 识别前景。这是一种自适应算法,更新出现的图像帧具有更高的权重,从而适应光照变化。此外,还可以利用开闭运算等形态学算法,除去噪音。

运动检测流程如上图所示。

节点部分

目前初号机只提供温度检测,运动检测,远程监控,自动控制,远程控制等功能。不过第一版只是试验品,咱就先来介绍下当前的硬件施工进度,以及软硬件联合测试的方法。

施工标准

标准实现至少需要准备如下硬件,更敷衍的实现只需一个带摄像头的电脑。大部分模块网上有成品,没有的也能用面包板凑合下。

  • Raspberry Pi 4B ×1
  • PI Camera ×1
  • 8051 MCU ×1
  • 1-Wire temp sensor DS18B20 ×1
  • ZigBee CC2530 SoC ×3

MCU

节点 MCU 有 8051/AVR ATmega8/STM32 可选,8051 本来是不会选的,不过手边有几片 8051,就直接回收利用了,用于运行控制程序,处理和保存数据。

其他还有 ZigBee,传感器模块。ZigBee 负责与其他节点或网关通信,传感器负责感知环境参数。

温度传感器

DS18B20 温度传感器使用 1-Wire 总线协议通信,每个传感器都有唯一的 64 位地址,MCU 通过该地址识别和寻址总线上的设备。

DS18B20 温度传感器定义了读写指令,响应指令和复位指令。除响应指令外,同步信号均由 MCU 产生。为了确保可靠的数据传输,同一时间只能有一个信号存在于 1-Wire 总线上。数据的传输符合单总线协议,按照初始化配置、ROM 指令、工作指令的顺序进行操作,其所有的指令和数据都是从低位开始发送到高位。

ZigBee

传感器节点的 ZigBee 模块使用网状路由,即单播发送。数据包通过 Mesh 路由发送,发送方知道接收方是否收到完整数据。网状路由最多可以经过 30 个节点来传输数据。

咱这里用的是成品模块(DL-LN3X),支持串口通信,只需指定节点的地址和数据,即可发送到目的节点,中间的过程由 CC2530 自带的程序处理。

温度采集

控制温度节点的程序运行在 8051 MCU 上,使用 C 语音开发。如下图,功能是每隔 1s 上传一次温度信息,或者在上位机请求时立即上传温度信息。

PCB

PCB 板形尺寸确定在 50mm*50mm 以内,完成总体布局后,开始放置组件。组件位置是否合理,将直接关系到电路是否可靠。

在 PCB 布局中,先按照功能模块划分区域,然后考虑各模块的相对位置。任何高频模拟信号或高精度数字信号都应该尽可能保持距离,原则上所有敏感区域利用 GND 相互隔离,信号路径尽可能短。

测试

运行环境

树莓派安装 Raspbian Buster 系统,使用 virtualenv 创建一个 Python 3 虚拟环境,执行 pip 命令安装所有依赖包。

$ pip install -r requirements.txt

运动捕捉相关功能使用 OpenCV 实现,PyPi 预编译的 OpenCV 4 可能缺少部分功能(目前够用了),如果需要完整功能,下面是编译安装的方法。

下载 opencv 和扩展库 opencv_contrib 源码到本地,进入 Python 3 虚拟环境,安装 numpy 和编译工具,使用 CMake 来构建编译配置。

$ cmake -D CMAKE_BUILD_TYPE=RELEASE \    -D CMAKE_INSTALL_PREFIX=/usr/local \    -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules \    -D ENABLE_NEON=ON \    -D ENABLE_VFPV3=ON \    -D BUILD_TESTS=OFF \    -D OPENCV_ENABLE_NONFREE=ON \    -D INSTALL_PYTHON_EXAMPLES=OFF \    -D BUILD_EXAMPLES=OFF ..

确认配置无误,开始编译。

# 4个核心,Raspberry Pi 4B 大约需要 1 小时make -j4make install

编译的 OpenCV 默认安装在全局的 site-packages 目录。

数据库

安装 MariaDB,使用 flask-migrate 创建数据库。

$ python manage.py db init$ python manage.py db migrate$ python manage.py db upgrade

开动吧

根目录下的 gate.py 是网关程序的入口文件。在生产环境部署时,还需使用 Nginx 反向代理,以提高系统的稳定性和安全性。

$ which python/home/xxx/umr-dive/venv/bin/python$ export Env=Dev$ sudo -E /home/xxx/umr-dive/venv/bin/python gate.py -i 0.0.0.0 -o 80

现在咱有了个能用的智能家居,别的再慢慢扩展,但愿不会成为有生之年系列吧。

Reference

项目源码

OpenCV – Stream video to web browser/HTML page

Install OpenCV 4 on Raspberry Pi 4 and Raspbian Buster

未完待续。