• 回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

【你购物我买单】基于 Wio Terminal 的智能家居终端

Wio Terminal 是 Seeed 推出的一块掌心大小的 Arduino/CircuitPython 兼容开发板,自带 2.4" LCD、Wi-Fi/BLE、加速度计、麦克风、USB-C、锂电池管理、Grove 与 40-Pin 树莓派扩展口,无线网络使用了 Realtek 的 RTL8720DN,支持 2.4GHz & 5GHz Wi-Fi 和蓝牙 5.0。插上即可采集-显示-联网,还可以跑 TinyML 玩边缘 AI,零焊接就能从传感器到云端实现物联网开发。

本项目使用 Wio Terminal 制作了智能家居终端,具备两大核心功能:一是通过 MQTT 获取室内环境数据,二是通过无线网络获取实时天气数据。
环境监测功能使用自制的数据采集器(ESP32 主控,AHT20 温湿度传感器、BMT 280 气压传感器),配合 Wio Terminal 板载光照传感器,可采集温度、湿度、大气压强和光强数据。温湿度、大气压强数据使用 MQTT 发送到 Wio Terminal;获取光照强度则直接使用 analogRead(WIO_LIGHT) 获得采集到的 ADC 值。采集到的数据可显示在 LCD 屏上。要在 Arduino IDE 使用 MQTT,只需安装 PubSubClient 库即可。

天气数据获取功能通过 Wi-Fi 接入互联网获取实时天气数据。使用的天气数据 API 为腾讯天气,免费且可查询多种数据,weather_type 参数传入要查询的数据即可,可选的类型有:当前天气(observe)、未来 48 小时预报(forecast_1h)、未来七日预报(forecast_24h)、生活指数(index)、预警(alarm)、提示(tips)、日出日落时间(rise)、空气质量数据(air),多参数查询使用"|"分割。这里为了方便开发,在 PC 上运行了一个服务端转发从天气 API 获取的数据,在局域网内访问 PC 的 5000 端口即可获得天气 API 返回的数据,避免了 Wio Terminal 直接访问天气 API 需要进行 SSL 认证的问题。如果不想在 PC 上运行中间层,直接在 Wio Terminal 上请求 HTTPS 网站也很简单,只需要使用下面的命令获得指定网站的根证书(需安装 openssl),在 Wio Terminal 网络请求程序前使用 client.setCACert(root_ca) 设置证书即可。
openssl s_client -showcerts -verify 5 -connect www.example.com:443 < /dev/null

另外,Seeed 官方的 LCD 屏幕库存在 BUG,所以这里使用了 LovyanGFX 库,相比官方库支持更多高级用法。同时,利用 Wio Terminal 的按键实现翻页效果,可循环显示环境数据、天气数据等不同页面。为了高效处理网络请求和屏幕绘图,使用了 FreeRTOS,由于官方 Wi-Fi 库底层已使用 FreeRTOS,所以在使用 Wi-Fi 库时无需手动引入,直接使用 xTaskCreate() 创建任务即可。
天气 API 的 Python 服务端代码:
from flask import Flask, Response
import requests
import json

app = Flask(__name__)

WEATHER_URL = (
    "https://wis.qq.com/weather/common"
    "?source=pc"
    "&weather_type=observe"
    "&province=辽宁"
    "&city=沈阳"
    "&county=沈河"
)


@app.route("/weather", methods=["GET"])
def weather():
    try:
        r = requests.get(WEATHER_URL, timeout=5)
        r.raise_for_status()
        compact = json.dumps(r.json(), separators=(",", ":"), ensure_ascii=False)
        return Response(compact, mimetype="application/json")
    except requests.RequestException as e:
        error_json = json.dumps({"error": str(e)}, separators=(",", ":"))
        return Response(error_json, status=502, mimetype="application/json")


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000, debug=True)
自制的数据采集器原理图:

全部回复(0)
正序查看
倒序查看
现在还没有回复呢,说说你的想法