数据记录可以用于各种原因。在之前的文章中,我写了关于如何监控我家用电量。 树莓派平台非常适合此类应用,因为它允许与多种模拟和数字传感器通信。 本文展示了如何记录树莓派的 CPU 温度,并按需创建基于电子表格的报告。 记录 CPU 温度不需要任何额外的板或传感器。
即使没有树莓派,您也可以按照此处描述的步骤进行操作,只需替换代码的特定部分。
设置
该代码基于 Pythonic,一个图形化的 Python 编程前端。开始使用 Pythonic 最简单的方法是下载并刷写树莓派镜像。 如果你没有树莓派,请使用 GitHub 页面上提到的其他安装方法之一(例如,Docker 或 Pip)。
安装完成后,将树莓派连接到本地网络。 接下来,通过导航到 http://pythonicrpi:7000/,在浏览器中打开基于 Web 的 GUI。
现在您应该看到以下屏幕

(Stephan Avenwedde, CC BY-SA 4.0)
下载并解压缩 GitHub 上提供的示例。 该存档包含多种文件类型。
使用绿色标记的按钮上传current_config.json
,使用黄色标记的按钮上传 XLSX 文件和其余的 *.py
文件。

(Stephan Avenwedde, CC BY-SA 4.0)
上传文件后,您应该看到这样的配置

(Stephan Avenwedde, CC BY-SA 4.0)
实现
该应用程序可以分为两个逻辑部分:日志记录和报告生成。 这两部分彼此独立运行。
日志记录
配置的顶部可以概括为日志记录设置

(Stephan Avenwedde, CC BY-SA 4.0)
涉及的元素
- ManualScheduler - 0x0412dbdc:在启动时(或手动)触发连接的元素。
- CreateTable - 0x6ce104a4:组装一个 SQL 查询,该查询创建工作表(如果尚不存在)。
- Scheduler - 0x557616c2:每 5 秒触发后续元素。
- DataAcquisition - 0x0e7b8360:在这里,我们收集 CPU 温度并组装一个 SQL 查询。
- SQLite - 0x196f9a6e: 表示一个 SQLite 数据库,接受 SQL 查询。
我将仔细研究 *DataAcquisition - 0x0e7b8360*。通过导航到 http://pythonicrpi:8000/ 打开内置的 Web 编辑器 (code-server)。 您可以在左侧窗格中看到所有与元素相关的 *.py
文件。 DataAcquisition 元素基于 Generic Pipe 类型。 打开具有相关 ID 的文件
generic_pipe_0x0e7b8360.py

(Stephan Avenwedde, CC BY-SA 4.0)
在此元素中,负责读取 CPU 温度,您可以根据您是否在树莓派上运行它来取消注释代码行。
上面的代码生成一个 SQL 查询,该查询在表 *my_table* 中插入一行,其中包含 Unix 时间戳(以秒为单位)和实际 CPU 温度(或随机数)。 代码由之前的元素 (Scheduler - 0x557616c2) 每 5 秒触发一次。 SQL 查询字符串被转发到连接的 SQLite - 0x196f9a6e 元素,该元素将查询应用于文件系统上的相关 SQLite 数据库。 该过程以每秒 1/5 个样本的采样率将 CPU 温度记录在数据库中。
报告生成
底部网络按需生成报告

(Stephan Avenwedde, CC BY-SA 4.0)
涉及的元素
- ManualScheduler - 0x7c840ba9:在启动时(或手动)激活连接的 Telegram 机器人。
- Telegram - 0x2e4148e2:Telegram 机器人,提供请求和提供报告的界面。
- GenericPipe- 0x2f78d74c:组装一个包含报告数据的 SQL 查询。
- SQLite - 0x5617d487:
- ReportGenerator- 0x13ad992a:基于数据创建基于 XLSX 的报告。
示例代码包含一个电子表格模板 (report_template.xlsx),它也属于此配置。
注意:要使 Telegram 机器人运行,请提供一个 Telegram 机器人令牌以与服务器通信。 core.telegram.org 描述了创建机器人令牌的过程。
当用户请求报告时,Telegram 元素将请求作为 Python 字符串输出。 接收到请求的 GenericPipe- 0x2f78d74c 元素组装一个 SQL 查询,该查询被转发到 SQLite - 0x5617d487 元素。 现在,基于 SQL 查询读取的实际数据被发送到 ReportGenerator- 0x13ad992a,我将对此进行更仔细的观察
generic_pipe_13ad992a.py
def execute(self):
path = Path.home() / 'Pythonic' / 'executables' / 'report_template.xlsx'
try:
wb = load_workbook(path)
except FileNotFoundError as e:
recordDone = Record(PythonicError(e), 'Template not found')
self.return_queue.put(recordDone)
con.close()
return
except Exception as e:
recordDone = Record(PythonicError(e), 'Open log for details')
self.return_queue.put(recordDone)
con.close()
return
datasheet = wb['Data']
# create an iterator over the rows in the datasheet
rows = datasheet.iter_rows(min_row=2, max_row=999, min_col=0, max_col=2)
在第一部分中,我使用 load_workbook() of the openpyxl 库来加载电子表格模板。 如果加载成功,我会在 datasheet 变量中获取对实际工作表的引用。 之后,我在 datasheet 中创建一个关于行的迭代器,该迭代器存储在变量 rows 中。
# Convert unix time [s] back into a datetime object, returns an iterator
reportdata_dt = map(lambda rec: (datetime.datetime.fromtimestamp(rec[0]), rec[1]), self.inputData)
# iterate till the first iterator is exhausted
for (dt, val), (row_dt, row_val) in zip(reportdata_dt, rows):
row_dt.value = dt
row_val.value = val
reportDate = datetime.datetime.now().strftime('%d_%b_%Y_%H_%M_%S')
filename = 'report_{}.xlsx'.format(reportDate)
filepath = Path.home() / 'Pythonic' / 'log' / filename
wb.save(filepath)
wb.close()
recordDone = Record(filepath, 'Report saved under: {}'.format(filename))
self.return_queue.put(recordDone)
最后一部分以变量 reportdata_dt 开头:该变量保存一个迭代器,当使用时,将来自 SQLite 数据库 (self.inputdata) 的输入数据的原始 Unix 时间戳转换回 Python datetime 对象。 接下来,我使用先前创建的 rows 迭代器 zip reportdata_dt 迭代器,并迭代直到其中第一个耗尽,这应该是 reportdata_dt。 在迭代期间,我用时间戳和值填充每行的列。 在最后一步中,我使用由实际日期和时间组成的文件名保存电子表格,并将文件名转发到 Telegram - 0x2e4148e2 元素。
然后,Telegram - 0x2e4148e2 从磁盘将文件加载回内存,并将其发送给请求报告的用户。 此视频显示了整个过程
用户收到的报告如下所示

(Stephan Avenwedde, CC BY-SA 4.0)
总结
本文展示了如何轻松地将树莓派转换为数据记录器。 树莓派平台允许您与任何类型的传感器交互,使您能够监控物理值以及计算值。 使用电子表格作为报告的基础可以为您提供很大的灵活性,并使这些报告非常可定制。 openpyxl 库与 Pythonic 结合使用,可以简化此过程。
评论已关闭。