dot Redis 8 已发布,且为开源版本

了解更多

如何在 Redis 中管理实时 IoT 传感器数据

想象您是一家向消费者销售数百万台智能空调的空调制造公司。您正在构建一个集中式的智能气候控制系统,该系统收集关于房屋温度、压力和湿度的传感器数据,并将其发送到中心位置进行效率分析,以帮助终端用户削减电费支出。

这篇博文将展示此类用例的简化版本,以演示其工作原理,让您了解如何在 Redis 中管理各种实时 IoT 传感器数据。

以下是我们使用的:

  1. 一个BME680 环境传感器,用于模拟智能空调并将数据发送到 Redis
  2. RedisTimeSeries 模块,用于为 Redis 添加时间序列功能并以时间序列格式存储数据
  3. 带有 Redis 数据源的 Grafana,用于创建图表进行使用情况分析

硬件要求

软件要求

准备 Jetson Nano 进行操作系统安装

按照这 10 个步骤查看其工作原理

步骤 1:获取您的传感器

市场上有各种各样的传感器,但本次演示使用的是 Pimoroni BME680 分线板。BME680 是一款集成环境传感器,专为对尺寸和低功耗有关键要求的移动应用和可穿戴设备开发。它可以测量温度、压力、湿度和室内空气质量,并与 Raspberry Pi 和 Arduino 兼容。

步骤 2:设置您的 IoT 开发板

在本次演示中,我们使用 NVIDIA Jetson Nano 开发板,这是一款小型而功能强大的计算机,供开发者学习、探索和构建边缘设备的 AI 应用程序。它售价 59 美元,基本上是一个开发者套件,包含一个 2GB 内存的 Jetson Nano 模块,提供 472 GFLOPS 的计算能力。本次演示也适用于其他流行的 IoT 设备,例如 Raspberry Pi、Arduino、Banana Pi 等。

步骤 3:接线

BME680 可以直接插入 Jetson Nano 开发板,无需任何连接线。

步骤 4:使传感器工作

接好传感器后,我们建议使用 i2cdetect 运行 I2C 检测,以验证您是否看到设备:在我们的示例中,它显示 76。请注意,传感器使用 I2C 或 SPI 通信协议与微控制器通信。

$ i2cdetect -r -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- 76 --

步骤 5:准备好使用 Redis

您需要在本地笔记本电脑或云端运行一个 Redis 服务器,并且 Redis 服务器必须编译有 RedisTimeSeries 模块。在本次演示中,我们使用 Redis Enterprise Cloud,这是一项完全托管的云数据库服务,已经内置并集成了 RedisTimeSeries 模块。

步骤 6:设置 Redis Enterprise Cloud

如果您是 RedisTimeSeries 的新手,请查看我们的 RedisTimeSeries 快速入门教程。它解释了如何开始使用 Redis Enterprise Cloud 以及如何启用 RedisTimeSeries。本次实现需要以下几个详细信息:

  • Redis 数据库名称
  • Redis 数据库端点
  • 端口号
  • 默认用户密码

步骤 7:克隆项目仓库

$ git clone https://github.com/redis-developer/redis-datasets
$ cd redis-datasets/redistimeseries/realtime-sensor-jetson

从 BME680 读取传感器值相当直接,但需要您设置一些配置值。您还可以通过两种不同的“模式”运行传感器——带或不带气体读数。仅测量温度、压力和湿度可以让您更快地采样数据。

首先,让我们看一下库导入和配置设置。打开终端窗口,创建一个文件,然后输入以下内容:

import bme680
import time
import datetime
import csv
import argparse
import redis

第一个模块 bme680 允许您轻松编写 Python 代码来读取传感器的湿度、温度和压力。同样,还有其他 Python 模块,例如处理时间相关任务的 time,导入 Redis Python 模块的 redis 等。我们使用 time 库在每次读取传感器之间引入一个小的延迟,以帮助确保结果一致。

print("""read-sensor.py - Displays temperature, pressure, humidity, and gas.
Press Ctrl+C to exit!
""")

try:
    sensor = bme680.BME680(bme680.I2C_ADDR_PRIMARY)
except IOError:
    sensor = bme680.BME680(bme680.I2C_ADDR_SECONDARY)

# These calibration data can safely be commented
# out, if desired.

print('Calibration data:')
for name in dir(sensor.calibration_data):

    if not name.startswith('_'):
        value = getattr(sensor.calibration_data, name)

        if isinstance(value, int):
            print('{}: {}'.format(name, value))

# These oversampling settings can be tweaked to
# change the balance between accuracy and noise in
# the data.

sensor.set_humidity_oversample(bme680.OS_2X)
sensor.set_pressure_oversample(bme680.OS_4X)
sensor.set_temperature_oversample(bme680.OS_8X)
sensor.set_filter(bme680.FILTER_SIZE_3)
sensor.set_gas_status(bme680.ENABLE_GAS_MEAS)

命令 sensor = bme680.BME680() 创建传感器实例,我们将用它来配置设置并获取传感器的读数。我们为湿度、压力和温度测量建立的 _oversample 设置旨在在准确读数和最小化噪声之间取得平衡。过采样越高,噪声降低越大,尽管精度也会降低。

_filter 用于保护传感器读数免受瞬时条件变化的影响,例如关门可能导致压力瞬间变化,而 IIR 滤波器则可以去除这些瞬时尖峰值。

如下方代码所示,气体测量有一些可以调整的设置。可以使用 set_gas_status 启用或禁用它。如上所述,禁用它可以使其他读数更快地获取。热板的温度及其保持该温度的时长也可以更改,但如果您的气体电阻读数看起来正常,我们建议不要更改这些设置。

print('\n\nInitial reading:')
for name in dir(sensor.data):
    value = getattr(sensor.data, name)

    if not name.startswith('_'):
        print('{}: {}'.format(name, value))

sensor.set_gas_heater_temperature(320)
sensor.set_gas_heater_duration(150)
sensor.select_gas_heater_profile(0)

# Up to 10 heater profiles can be configured, each
# with their own temperature and duration.
# sensor.set_gas_heater_profile(200, 150, nb_profile=1)
# sensor.select_gas_heater_profile(1)


parser = argparse.ArgumentParser()
parser.add_argument("--port", type=int, help="redis instance port", default=6379)
parser.add_argument(
    "--password", type=int, help="redis instance password", default=None
)
parser.add_argument("--verbose", help="enable verbose output", action="store_true")
parser.add_argument("--host", type=str, help="redis instance host", default="127.0.0.1")


args = parser.parse_args()

接下来,我们定义 Redis 连接器,其中指定 Redis 实例的主机、端口和密码。如下所示,以下代码定义了各种 RedisTimeSeries 键,例如温度键(TS:TEMPERATURE)、压力键(TS:PRESSURE)和湿度键(TS:HUMIDITY)。

# redis setup
redis_obj = redis.Redis(host=args.host, port=args.port, password=args.password)
temperature_key = "ts:temperature"
pressure_key = "ts:pressure"
humidity_key = "ts:humidity"

sensor.get_sensor_data() 指令从传感器获取数据,并用温度、湿度和压力填充这三个变量。

接下来,通过在 Redis 连接上调用无参数的 .pipeline() 方法构建一个“事务性管道”。在底层,管道收集所有传递的命令,直到调用 .execute() 方法。如您所见,我们使用了 RedisTimeSeries 的 TS.ADD 命令来填充传感器数据结构。您可以通过此 GitHub 仓库访问完整的代码。

步骤 8:执行脚本

在执行脚本之前,您需要导入 bme680 和 smbus Python 模块,如下所示:

$ pip3 install bme680
$ pip3 install smbus

确保您提供了正确的 Redis Enterprise Cloud 数据库端点、用户名和密码

$ python3 sensorloader.py --host <Redis Enterprise Cloud host> --port <port>  --password <password> 

您可以运行 monitor 命令来验证传感器数据是否正在填充,如下所示:

$ redis-cli -h redis-12929.c212.ap-south-1-1.ec2.cloud.redislabs.com -p 12929
redis-12929.c212.ap-south-1-1.ec2.cloud.redislabs.com:12929> auth <password>
OK
redis-12929.c212.ap-south-1-1.ec2.cloud.redislabs.com:12929> monitor
OK
1611046300.446452 [0 122.179.79.106:53715] "info" "server"
1611046300.450452 [0 122.179.79.106:53717] "info" "stats"
1611046300.450452 [0 122.179.79.106:53716] "info" "clients"
1611046300.486452 [0 122.179.79.106:53714] "info" "memory"
1611046300.486452 [0 122.179.79.106:53713] "info" "server"
1611046300.494452 [0 122.179.79.106:53715] "info" "memory"
1611046300.498452 [0 122.179.79.106:53717] "info" "commandstats"
1611046300.522452 [0 122.179.79.106:53716] "dbsize"
1611046301.498452 [0 122.179.79.106:53714] "info" "memory"
1611046301.498452 [0 122.179.79.106:53713] "info" "server"
1611046301.498452 [0 122.179.79.106:53715] "info" "server"
1611046301.498452 [0 122.179.79.106:53716] "info" "clients"
1611046301.498452 [0 122.179.79.106:53717] "info" "stats"
1611046301.554452 [0 122.179.79.106:53714] "info" "memory"
1611046301.562452 [0 122.179.79.106:53717] "info" "commandstats"

步骤 9:部署 Grafana

在 Grafana 中绘制传感器数据图非常令人兴奋。要实现这一点,请运行以下命令:

$ docker run -d -e "GF_INSTALL_PLUGINS=redis-app" -p 3000:3000 grafana/grafana

确保您的系统上正在运行 Docker Engine,无论是在您的桌面系统还是在云端。本次演示中,我已在 Docker Desktop for Mac 上进行了测试。

将您的浏览器指向 https://<IP_ADDRESS>:3000。使用“admin”作为用户名和密码登录 Grafana 控制面板。

单击 Grafana 控制面板左侧的“Data Sources”选项,添加数据源。

Add data source 选项下,搜索 Redis,然后 Redis 数据源将如下所示出现:

输入名称、Redis Enterprise Cloud 数据库端点和密码,然后点击 Save & Test

点击 Dashboards 以导入 Redis 和 Redis Streaming。对这两个选项都点击 Import

点击 Redis 查看一个精美的 Grafana 控制面板,其中显示 Redis 数据库信息。

步骤 10:在 Grafana 中绘制 RedisTimeSeries 传感器数据图

最后,让我们创建一个显示温度、压力和湿度的传感器控制面板。首先从温度开始,先点击左侧导航窗口中的 +。在 Create 选项下,选择 Dashboard 并点击 Add new panel 按钮。

将打开一个新窗口,显示 Query 部分。从下拉菜单中选择 SensorT,选择 RedisTimeSeries 作为类型,选择 TS.GET 作为命令,选择 ts”temperature 作为键。

选择 TS.GET 作为命令。

输入 ts”temperature 作为键。

点击 Run,然后点击 Save,如下所示:

现在您可以以您喜欢的名称保存控制面板。

点击 Save。这将打开一个传感器控制面板。您可以点击 Panel Title 并选择 Edit

输入 Temperature,并在 Visualization 下选择 Gauge

点击 Apply,您应该能看到如下所示的温度控制面板:

对压力(ts:pressure)和湿度(ts:humidity)遵循相同的过程,并将它们添加到控制面板。您应该能够看到完整的温度、湿度和压力控制面板读数。看起来很棒,不是吗?

下一步

此演示展示了 RedisTimeSeries 如何结合 Redis 和专门构建的时间序列数据库的优势。这种组合让您能够通过有效地存储和管理 RedisTimeSeries 数据来轻松跟踪环境因素。最后,通过将 Grafana 与 RedisTimeSeries 集成,您可以创建一个实用、信息丰富的控制面板,让您能够实时放大和缩小图表。

此示例应用只是您可以使用 RedisTimeSeries 完成的许多出色事情之一。要了解更多想法,请查看以下有趣的用例:

在 RedisTimeSeries 上构建您的金融应用

使用适用于 Grafana 的 Redis 数据源构建的 3 个实际应用

使用 Redis 和 Grafana 实现实时可观测性