我如何用 CircuitPython 和开源工具监控温室
创始人
2024-03-02 07:34:53
0

使用微控制器、传感器、Python 以及 MQTT 持续追踪温室的温度、湿度以及环境光。

种有西红柿的温室花园

CircuitPython 提供了一种和微控制器板进行交互的革命性方式。这篇文章介绍了如何使用 CircuitPython 来监测温室的温度、湿度以及环境光,并且使用 CircuitPython MQTT 客户端将结果发布到一个 MQTT 中介 broker 。你可以在若干个程序中订阅 MQTT 队列并进一步处理信息。

这个项目使用一个简单的 Python 程序来运行 Web 服务器,它发布一个 Prometheus 格式的采集端点,拉取监控指标到 Prometheus 进行不间断的监控。

关于 CircuitPython

CircuitPython 是一个由 Adafruit 创建的开源 Python 发行版,用于运行在低成本微控制器开发板上。CircuitPython 为与 兼容的开发板 的交互提供了简单的开发体验。你可以在连接你的开发板时挂载的 CIRCUITPYTHON 根驱动器上创建一个 code.py 文件来启动你的程序。CircuitPython 还为开发板提供了一个串行连接,包含一个交互式解释器(REPL)会话,你可以使用 Python 代码实时和开发板进行交互。

Adafruit 的网站提供了大量的文档,可以帮助你开始使用 CircuitPython。首先,参考下《欢迎来到 CircuitPython》指南。这份指南能够帮助你开始使用 CircuitPython 在开发板上运行代码以及和 REPL 交互。它还记录了如何安装 Adafruit 的 CircuitPython 库合集和范例,可以用在它出售的许多开发板和传感器上。接下来,阅读《CircuitPython 基础》指南来学习更多关于其功能的信息,里面还有链接指向在特定及兼容的开发板上使用 CircuitPython 的相关信息。最后,就如所有开源软件一样,你可以深入 CircuitPython 的源码,发布议题,以及做出贡献。

微控制器设置

微控制器系统非常简单。要完成这个示例项目,你会需要:

  • 树莓派 4:你需要一台电脑来给微控制器系统编程,我用的是树莓派 4。
  • CircuitPython 兼容的微控制器:我用的是 Adafruit Feather S2,带有内置 WiFi,环境光传感器,Qwiic 线缆输入。
  • 微控制器 WiFi:Feather S2 内置了 WiFi。如果你的微控制器没有,你需要给开发板找个 WiFi 扩展板。
  • 传感器:Feather S2 有个内置的环境光传感器,所以我还需要一个温湿度传感器。有很多不同厂商的产品可以选择,包括 Adafruit、SparkFun、亚马逊。我用的是一个 Adafruit 传感器,带有 Feather S2 输入兼容的 Qwiic 线缆。尽管多数 SparkFun 传感器可以在 Adafruit 库下工作,但如果你不是从 Adafruit 购买的传感器,你可能还是需要自己去找到它兼容 CircuitPython 的 Python 库。
  • 跳线和线缆:为了避免使用面包板或焊接,我使用 Adafruit Qwiic 线缆。SparkFun 销售的包含不同长度的线缆套装中也有它。

在将微控制器连接到你的电脑之前,将传感器连接到微控制器上。

将传感器连接到微控制器上

现在你可以将微控制器用 USB 数据线连接到你的电脑。

MQTT 中介

你可以使用 这份说明 来在树莓派的系统上安装 Mosquitto MQTT 中介 和 Mosquitto 客户端。如果你想把树莓派做为长期服务器使用,在你的网络上给树莓派 4 设置一个静态 IP 地址。Mosquitto 中介运行起来之后,创建一份 用户名/密码文件,设置客户端向中介发布和订阅消息时用的认证信息。

你可以用树莓派上的 Mosquitto 客户端来测试 MQTT 中介。打开两个终端(如果你是无界面运行的话打开两个 SSH 会话):

在终端一输入:

mosquitto_sub -h localhost -u $user -P $pass -t "mqtt/test"

这条命令会启动一个持续运行的进程,监听发布到 mqtt/test 队列的消息。

在终端二输入:

mosquitto_pub -h localhost -u $user -P $pass -t "mqtt/test" -m hello`

这条命令会向 mqtt/test 队列发布一条消息,它应该会显示在终端一的输出里。

现在你可以中止终端一运行的 sub 命令了。

Mosquitto 中介允许客户端发布消息到任何队列,甚至没有任何订阅的队列也可以。这些消息会永久丢失,但这不会阻止客户端继续发布消息。

打开第三个终端,订阅下列队列(你的控制器会发布消息到这些队列上):

  • greenhouse/temperature
  • greenhouse/light
  • greenhouse/humidity

给微控制器编码

现在你已经准备好给微控制器编码,发布它的监测指标到树莓派 4 上运行的 MQTT 中介上了。

Adafruit 有 出色的文档,指导你使用 CircuitPython 库合集 的库来将你的微控制器连接到 WiFi 路由器,并发布监测指标到 MQTT 中介上。

安装下列库到 CIRCUITPYTHON/lib 目录,温室监控会用到它们。这些库在 Adafruit 的 CircuitPython 库合集中都有提供:

  • adafruit_bus_device:一个带有多个 .mpy 文件的 Python 包文件夹(.mpy 是经过压缩的 Python 文件,用以节省空间)
  • adafruit_requests:单个 .mpy 文件
  • adafruit_register:一个包文件夹
  • adafruit_minimqtt:一个包文件夹
  • adafruit_si7021:单个 .mpy 文件,用来支持温湿度传感器

库装好了之后,将以下代码写入 CIRCUITPYTHON 文件夹的 code.py 文件中:

import time
import ssl
import socketpool
import wifi
import adafruit_minimqtt.adafruit_minimqtt as MQTT
import board
from digitalio import DigitalInOut, Direction, Pull
from analogio import AnalogIn
import adafruit_si7021
 
# Add a secrets.py to your filesystem that has a dictionary called secrets with "ssid" and
# "password" keys with your WiFi credentials. DO NOT share that file or commit it into Git or other
# source control.
# pylint: disable=no-name-in-module,wrong-import-order
try:
        from secrets import secrets
except ImportError:
        print("WiFi secrets are kept in secrets.py, please add them there!")
        raise
 
print("Connecting to %s" % secrets["ssid"])
wifi.radio.connect(secrets["ssid"], secrets["password"])
print("Connected to %s!" % secrets["ssid"])
### Feeds ###
light_feed = "greenhouse/light"
temp_feed = "greenhouse/temperature"
humidity_feed = "greenhouse/humidity"
 
# Define callback methods which are called when events occur
# pylint: disable=unused-argument, redefined-outer-name
def connected(client, userdata, flags, rc):
        # This function will be called when the client is connected
        # successfully to the broker.
        print("Connected to MQTT!")
 
def disconnected(client, userdata, rc):
        # This method is called when the client is disconnected
        print("Disconnected from MQTT!")
 
 
def get_voltage(pin):
        return (pin.value * 3.3) / 65536
 
# Create a socket pool
pool = socketpool.SocketPool(wifi.radio)
 
# Set up a MiniMQTT Client
mqtt_client = MQTT.MQTT(
        broker=secrets["broker"],
        port=secrets["port"],
        username=secrets["aio_username"],
        password=secrets["aio_key"],
        socket_pool=pool,
        ssl_context=ssl.create_default_context(),
)
 
# Setup the callback methods above
mqtt_client.on_connect = connected
mqtt_client.on_disconnect = disconnected
 
# Connect the client to the MQTT broker.
print("Connecting to MQTT...")
mqtt_client.connect()
 
# Create library object using our Bus I2C port
sensor = adafruit_si7021.SI7021(board.I2C())
light_pin = AnalogIn(board.IO4)
 
while True:
        # Poll the message queue
        mqtt_client.loop()
 
        # get the current temperature
        light_val = get_voltage(light_pin)
        temp_val = ((sensor.temperature * 9)/5) + 32
        humidity_val = sensor.relative_humidity
 
        # Send a new messages
        mqtt_client.publish(light_feed, light_val)
        mqtt_client.publish(temp_feed, temp_val)
        mqtt_client.publish(humidity_feed, humidity_val)
        time.sleep(0.5)

保存你的代码。然后连接到串行监视器,看程序连接到你的 MQTT 中介。你还可以将树莓派 4 上的终端切换到订阅了它的发布队列的终端来查看输出。

处理监测指标

像 MQTT 这样的发布/订阅工作流给微控制器系统提供了诸多好处。你可以有多个微控制器 + 传感器来回报同一个系统的不同指标或并行回报相同指标的若干读数。你还可以有多个不同进程订阅各个队列,并行地对这些消息进行回应。甚至还可以有多个进程订阅相同的队列,对消息做出不同的动作,比如数值过高时发送通知邮件或将消息发送到另一个 MQTT 队列上去。

另一个选项是让一个微控制器订阅一个外部队列,可以发送信号告诉微控制器做出动作,比如关闭或开始一个新会话。最后,发布/订阅工作流对低功耗微控制器系统更佳(比如那些使用电池或太阳能的系统),因为这些设备可以在更长的延迟周期后批量发布监测指标,并在回报的间隔期间关闭大量消耗电量的 WiFi 广播。

要处理这些监测指标,我创建了一个 Python 客户端,使用 Paho Python MQTT 客户端 订阅监测指标队列。我还使用官方的 Prometheus Python 客户端 创建了一个 Web 服务器,它产生一个符合 Prometheus 标准的采集端点,使用这些监测指标作为面板信息。Prometheus 服务器和 Mosquitto MQTT 中介我都是运行在同一个树莓派 4 上的。

from prometheus_client import start_http_server, Gauge
import random
import time
import paho.mqtt.client as mqtt

gauge = {
  "greenhouse/light": Gauge('light','light in lumens'),
  "greenhouse/temperature": Gauge('temperature', 'temperature in fahrenheit'),
  "greenhouse/humidity": Gauge('humidity','relative % humidity')
}

try:
        from mqtt_secrets import mqtt_secrets
except ImportError:
        print("WiFi secrets are kept in secrets.py, please add them there!")
        raise

def on_connect(client, userdata, flags, rc):
        print("Connected with result code "+str(rc))
        # Subscribing in on_connect() means that if we lose the connection and
        # reconnect then subscriptions will be renewed.
        client.subscribe("greenhouse/light")
        client.subscribe('greenhouse/temperature')
        client.subscribe('greenhouse/humidity')

def on_message(client, userdata, msg):
        topic = msg.topic
        payload = msg.payload
        gauge[topic].set(payload)

client = mqtt.Client()
client.username_pw_set(mqtt_secrets["mqtt_user"],mqtt_secrets['mqtt_password'])
client.on_connect = on_connect
client.on_message = on_message
client.connect('localhost',1883,60)

if __name__ == '__main__':
        # Start up the server to expose the metrics.

        client = mqtt.Client()
        client.username_pw_set('london','abc123')
        client.on_connect = on_connect
        client.on_message = on_message
        client.connect('localhost',1883,60)

        start_http_server(8000)
        client.loop_forever()

然后我配置 Prometheus 服务器采集端点数据到 localhost:8000

你可以在 Github 上访问 温室 MQTT 微控制器 这个项目的代码,项目采用 MIT 许可证授权。


via: https://opensource.com/article/21/5/monitor-greenhouse-open-source

作者:Darin London 选题:lujun9972 译者:alim0x 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

相关内容

事关《哪吒2》票房,上海开...
今年年初 《哪吒之魔童闹海》(简称《哪吒2》) 掀起票房狂潮,至今...
2025-04-27 08:46:36
原创 ...
京津冀融媒体中心消息:近日,全球网总编辑、京津冀融媒体中心主任、保...
2025-04-18 09:44:58
在CentOS系统上高效搭...
在CentOS系统上部署Apache HTTP服务器的高效指南 A...
2025-04-17 06:17:20
在CentOS系统上部署Z...
高效搭建Zabbix监控系统在CentOS上的部署教程 在IT运维...
2025-03-14 09:42:31
打开“智眼”~延庆野鸭湖鸟...
“又飞来一只鸟,快看看是什么鸟。”区自然保护地管理处工作人员张标指...
2025-03-07 14:54:27
如何在CentOS上安装并...
CentOS Sysstat工具:系统监控与性能分析的利器 在Li...
2025-03-05 06:38:05

热门资讯

使用 KRAWL 扫描 Kub... 用 KRAWL 脚本来识别 Kubernetes Pod 和容器中的错误。当你使用 Kubernet...
Helix:高级 Linux ... 说到 基于终端的文本编辑器,通常 Vim、Emacs 和 Nano 受到了关注。这并不意味着没有其他...
通过 SaltStack 管理... 我在搜索Puppet的替代品时,偶然间碰到了Salt。我喜欢puppet,但是我又爱上Salt了:)...
Epic 游戏商店现在可在 S... 现在可以在 Steam Deck 上运行 Epic 游戏商店了,几乎无懈可击! 但是,它是非官方的。...
如何在 Github 上创建一... 学习如何复刻一个仓库,进行更改,并要求维护人员审查并合并它。你知道如何使用 git 了,你有一个 G...
2024 开年,LLUG 和你... Hi,Linuxer,2024 新年伊始,不知道你是否已经准备好迎接新的一年~ 2024 年,Lin...
什么是 KDE Connect... 什么是 KDE Connect?它的主要特性是什么?它应该如何安装?本文提供了基本的使用指南。科技日...
JStock:Linux 上不... 如果你在股票市场做投资,那么你可能非常清楚投资组合管理计划有多重要。管理投资组合的目标是依据你能承受...
Opera 浏览器内置的 VP... 昨天我们报道过 Opera 浏览器内置了 VPN 服务,用户打开它可以防止他们的在线活动被窥视。不过...
Bazzite:专为 Stea... 为 Linux 桌面或者 Steam Deck 做好游戏准备,听起来都很刺激!对于一个专为 Linu...