使用物联网构建植物监控工具:初学者友好教程

导航至

本文最初发表于 The New Stack,并经许可在此处转载。

创建一个物联网 (IoT) 应用程序来监控室内植物是学习随时间变化的数据的实用起点。这对于任何喜欢室内园艺但经常忘记检查植物的人都很有用。

这个项目对所有人开放,从从事科学展览项目的学生到监控外来植物苗圃的植物学家。有很多方法可以监控室内植物,但这是高科技的方式——使用传感器和先进的软件系统。

对于这个项目,我们将使用 InfluxDB,这是一个时间序列平台,专门用于存储随时间出现的顺序数据。这在比较数据、为特定阈值创建警报以及监控物理世界和虚拟世界中的事件时非常有用。

mmonitoring a plant

如果您想亲自学习或迫切需要让室内植物存活,可以从我的 git 存储库 中获取完整的物料清单、面包板(带有您选择的微控制器)的原理图以及源代码。

架构

the architecture

物联网传感器以定时间隔跟踪我植物的健康指标。我们将它收集的数据归类为时间序列数据,因为它包含一个时间戳,该时间戳作为存储中的第一列出现。物联网传感器生成关于植物健康的数据。然后我使用 Telegraf,一个开源收集代理,以及 Python 客户端库 来收集这些数据并将其发送到存储层 InfluxDB。Plotly 图形库提供数据可视化。我用 Python 编写了这个项目,它使用 Flask 库进行路由。

开始入门

工具

  • 要监控的植物
  • Particle Boron 或 类似的微控制器
  • 至少一个用于您植物的物联网传感器
  • 面包板
  • 跳线

我使用四个传感器来生成以下五个数据点

  • 空气温度
  • 湿度
  • 光照
  • 土壤温度
  • 土壤湿度

schematics and sensors

微控制器

我使用 Boron 微控制器,并通过公司网站设置设备。为了从微控制器本身接收数据,我通过 USB 电缆将其连接到我的笔记本电脑。微控制器的设置取决于您选择使用的微控制器。您的微控制器可能提供其他连接选项,包括蓝牙或通过 TCP/IP 的小型服务器访问。

按照微控制器制造商提供的说明进行操作,直到您收到来自传感器的输入。您无需理解数据;只需确保您的微控制器正在发送原始数据。

InfluxDB

登录 InfluxDB。创建一个存储桶,InfluxDB 在其中存储数据。我们将通过 API 连接到 InfluxDB。下一步是[创建所需的凭据和令牌](https://docs.influxdb.org.cn/influxdb/v2.7/security/tokens/。

代码

将数据写入 InfluxDB 非常简单,从客户端库开始。我为这个项目使用了 InfluxDB 的 Python 客户端库。下面的代码示例说明了如何编写代码以将来自微控制器传感器的原始数据发送到 InfluxDB。

def write_to_influx(self,data):
	p = (influxdb_client.Point("sensor_data")
                    	.tag("user",data["user"])
                    	.tag("device_id",data["device"])                     
                    	.field(data["sensor_name"], int(data["value"])
                    	))
	self.write_api.write(bucket=self.cloud_bucket, org=self.cloud_org, record=p)
	print(p, flush=True)

标签

Measurements(测量) 是 InfluxDB 中相当于关系数据库中表的概念。我的代码很好地利用了标签。标签不是必需的,但它们很方便,因为它们是元数据,使数据更易于理解和使用。在本例中,它们可以指定不同的植物、设备或其他内容,具体取决于您想要实现的复杂程度。

查询数据

quering data

查询返回类似于下表的表格。

在我可以查询我的数据之前,我需要初始化 Flight SQL 客户端。

from flightsql import FlightSQLClient

接下来是

# This is our flight client setup, it’s how we will query from IOX
    	# we need to remove the Https:// from our host
    	host = host.split("://")[1]
    	self.flight_client = FlightSQLClient(host=host,
                     	token=token,
                     	metadata= {'bucket-name': bucket}
        	             )

    	self.cloud_bucket = bucket
    	self.cloud_org = org

下面是从 InfluxDB 检索数据的基本 SQL 查询。

SELECT {sensor_name}, time FROM sensor_data WHERE time > (NOW() - INTERVAL '2 HOURS') AND device_id='{deviceID}'

在我们检索和读取数据之前,我们必须将其转换为 Pyarrow 格式。下面的代码是一个函数,其中包括查询和与 Flight SQL 的连接以检索数据。

def querydata(self, sensor_name, deviceID) -> DataFrame:   	

        query = self.flight_client.execute(f"SELECT {sensor_name}, time FROM sensor_data WHERE time > (NOW() - INTERVAL '2 HOURS') AND device_id='{deviceID}'")

        # Create reader to consume result
    	reader = self.flight_client.do_get(query.endpoints[0].ticket)

    	# Read all data into a pyarrow.Table
    	Table = reader.read_all()
    	print(Table)

   	# Convert to Pandas DataFrame
    	df = Table.to_pandas()
    	df = df.sort_values(by="time")
    	print(df)
    	return df

您可以调用之前的查询,并为您选择的内容(包括存储桶、传感器和设备)替换变量。返回的结果允许您绘制传入数据的图表。return df 方法以数据帧格式提取我们的数据。

数据帧

Pandas DataFrames 是二维数据结构,可以快速进行数据分析和处理。我们将数据转换为 DataFrame,以便在 Python 中更轻松地使用。如果您喜欢不同的样式,还可以选择其他几种数据输出选项。

@app.callback(Output("store", "data"), [Input("button", "n_clicks")])
def generate_graphs(n):
# Generate graphs based upon pandas data frame. 
    df = influx.querydata( "soil_temperature", graph_default["deviceID"] )
    soil_temp_graph = px.line(df, x="time", y="soil_temperature", title="Soil Temperature")

    df = influx.querydata( "air_temperature", graph_default["deviceID"] )
    air_temp_graph= px.line(df, x="time", y="air_temperature", title="Air Temperature")

    df = influx.querydata( "humidity", graph_default["deviceID"] )
    humidity_graph= px.line(df, x="time", y="humidity", title="humidity")

    df = influx.querydata( "soil_moisture", graph_default["deviceID"] )
    soil_moisture= px.line(df, x="time", y="soil_moisture", title="Soil Moisture")

    df = influx.querydata( "light", graph_default["deviceID"] )
    light_graph= px.line(df, x="time", y="light", title="light")

图形库期望您返回一个数据帧以进行可视化。这是查询数据点的最终结果。下面的图像是硬编码的图表,说明了数据点。不同的选项卡显示不同的图表并跟踪单独的指标。这只是项目功能的一小部分。

Plant-Buddy-Dashboard

结论

查看我的演示文稿,该演示文稿以 Plant Buddy 为中心,更深入地讨论了这个项目和整个 InfluxDB 生态系统。我们的社区页面还有其他精彩项目的示例。现在开始使用 InfluxDB,构建一些很酷的东西吧!