如果您曾经想知道您的树莓派的性能,那么您可能需要一个用于您的 Pi 的仪表板。在本文中,我演示了如何快速构建一个按需监控仪表板,用于您的树莓派,以便您可以实时查看您的 CPU 性能、内存和磁盘使用情况,并在以后根据需要添加更多视图和操作。
如果您已经在使用 Appsmith,您也可以直接导入示例应用并开始使用。
Appsmith
Appsmith 是一个开源的低代码应用构建器,可帮助开发人员轻松快速地构建内部应用,如仪表板和管理面板。对于您的仪表板来说,这是一个绝佳的选择,并减少了传统编码方法的时间和复杂性。
对于此示例中的仪表板,我显示了以下使用统计数据:
- CPU
- 使用率百分比
- 频率或时钟速度
- 计数
- 温度
- 内存
- 使用率百分比
- 可用内存百分比
- 总内存
- 可用内存
- 磁盘
- 磁盘使用率百分比
- 已用磁盘空间
- 可用磁盘空间
- 总磁盘空间
创建端点
您需要一种方法从您的树莓派 (RPi) 获取这些数据并将其导入 Appsmith。psutils Python 库对于监控和性能分析非常有用,而 Flask-RESTful Flask 扩展创建了一个 REST API。
Appsmith 每隔几秒钟调用 REST API 以自动刷新数据,并获得一个 JSON 对象作为响应,其中包含所有所需的统计数据,如下所示:
{ "cpu_count": 4,
"cpu_freq": [
600.0,
600.0,
1200.0 ],
"cpu_mem_avail": 463953920,
"cpu_mem_free": 115789824,
"cpu_mem_total": 971063296,
"cpu_mem_used": 436252672,
"cpu_percent": 1.8,
"disk_usage_free": 24678121472,
"disk_usage_percent": 17.7,
"disk_usage_total": 31307206656,
"disk_usage_used": 5292728320,
"sensor_temperatures": 52.616 }
1. 设置 REST API
如果您的树莓派上还没有 Python,请在您的 Pi 上打开一个终端并运行此安装命令:
$ sudo apt install python3
现在为您的开发设置一个 Python 虚拟环境:
$ python -m venv PiData
接下来,激活环境。您必须在重启您的 Pi 后执行此操作。
$ source PiData/bin/activate
$ cd PiData
要安装 Flask 和 Flask-RESTful 以及稍后您需要的依赖项,请在您的 Python 虚拟环境中创建一个名为 requirements.txt
的文件,并将以下行添加到其中:
flask
flask-restful
gunicorn
保存文件,然后使用 pip
一次性安装所有这些。您必须在重启您的 Pi 后执行此操作。
(PyData)$ python -m pip install -r requirements.txt
接下来,创建一个名为 pi_stats.py
的文件,以存放使用 psutils
检索 RPi 系统统计数据的逻辑。将此代码粘贴到您的 pi_stat.py
文件中:
from flask import Flask
from flask_restful import Resource, Api
import psutil
app = Flask(__name__)
api = Api(app)
class PiData(Resource):
def get(self):
return "RPI Stat dashboard"
api.add_resource(PiData, '/get-stats')
if __name__ == '__main__':
app.run(debug=True)
以下是代码的作用:
- 使用 app = Flask(name) 定义嵌套 API 对象的应用。
- 使用 Flask-RESTful 的 API 方法 定义 API 对象。
- 将 PiData 定义为 Flask-RESTful 中的具体 Resource 类,以公开每个受支持的 HTTP 方法的方法。
- 使用
api.add_resource(PiData, '/get-stats')
将资源PiData
附加到 API 对象api
。 - 每当您访问 URL
/get-stats
时,PiData
将作为响应返回。
2. 使用 psutils 读取统计数据
要从您的 Pi 获取统计数据,您可以使用 psutils
中的这些内置函数:
cpu_percentage
、cpu_count
、cpu_freq
和sensors_temperatures
函数分别用于 CPU 的使用率百分比、计数、时钟速度和温度。sensors_temperatures
报告连接到 RPi 的所有设备的温度。要仅获取 CPU 的温度,请使用键cpu-thermal
。virtual_memory
用于获取总内存、可用内存、已用内存和可用内存统计数据(以字节为单位)。disk_usage
返回总磁盘空间、已用磁盘空间和可用磁盘空间统计数据(以字节为单位)。
将所有函数组合在一个 Python 字典中,如下所示:
system_info_data = {
'cpu_percent': psutil.cpu_percent(1),
'cpu_count': psutil.cpu_count(),
'cpu_freq': psutil.cpu_freq(),
'cpu_mem_total': memory.total,
'cpu_mem_avail': memory.available,
'cpu_mem_used': memory.used,
'cpu_mem_free': memory.free,
'disk_usage_total': disk.total,
'disk_usage_used': disk.used,
'disk_usage_free': disk.free,
'disk_usage_percent': disk.percent,
'sensor_temperatures': psutil.sensors_temperatures()\['cpu-thermal'
][0].current, }
下一节将使用此字典。
3. 从 Flask-RESTful API 获取数据
要在 API 响应中查看来自您的 Pi 的数据,请更新 pi_stats.py
以在类 PiData
中包含字典 system_info_data
:
from flask import Flask
from flask_restful import Resource, Api
import psutil
app = Flask(__name__)
api = Api(app)
class PiData(Resource):
def get(self):
memory = psutil.virtual_memory()
disk = psutil.disk_usage('/')
system_info_data = {
'cpu_percent': psutil.cpu_percent(1),
'cpu_count': psutil.cpu_count(),
'cpu_freq': psutil.cpu_freq(),
'cpu_mem_total': memory.total,
'cpu_mem_avail': memory.available,
'cpu_mem_used': memory.used,
'cpu_mem_free': memory.free,
'disk_usage_total': disk.total,
'disk_usage_used': disk.used,
'disk_usage_free': disk.free,
'disk_usage_percent': disk.percent,
'sensor_temperatures': psutil.sensors_temperatures()['cpu-thermal'][0].current, }
return system_info_data
api.add_resource(PiData, '/get-stats')
if __name__ == '__main__':
app.run(debug=True)
您的脚本已准备就绪。运行 PiData.py
脚本:
$ python PyData.py
* Serving Flask app "PiData" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not run this in a production environment.
* Debug mode: on
* Running on http://127.0.0.1:5000 (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
您有了一个可用的 API!
4. 使 API 可在 Internet 上访问
您可以在您的本地网络上与您的 API 交互。但是,要通过 Internet 访问它,您必须在您的防火墙中打开一个端口,并将传入的流量转发到 Flask 提供的端口。但是,正如您的测试输出所建议的那样,从 Flask 运行 Flask 应用仅用于开发,不用于生产。为了安全地使您的 API 可在 Internet 上访问,您可以使用 gunicorn
生产服务器,您在项目设置阶段已安装了它。
现在您可以启动您的 Flask API。您必须在每次重启您的 Pi 后执行此操作。
$ gunicorn -w 4 'PyData:app'
Serving on http://0.0.0.0:8000
要从外部世界访问您的 Pi,请在您的网络防火墙中打开一个端口,并将传入的流量定向到您的 PI 的 IP 地址,端口为 8000。
首先,获取您的 Pi 的内部 IP 地址:
$ ip addr show | grep inet
内部 IP 地址以 10 或 192 或 172 开头。
接下来,您必须配置您的防火墙。通常在您从互联网服务提供商 (ISP) 处获得的路由器中嵌入了防火墙。通常,您可以通过 Web 浏览器访问您的家庭路由器。您的路由器的地址有时印在路由器的底部,它以 192.168 或 10 开头。但是,每台设备都不同,所以我无法准确地告诉您需要单击什么来调整您的设置。有关如何配置防火墙的完整说明,请阅读 Seth Kenlon 的文章打开端口并通过防火墙路由流量。
或者,您可以使用 localtunnel 来使用动态端口转发服务。
一旦您的流量到达您的 Pi,您就可以查询您的 API:
$ curl https://example.com/get-stats
{
"cpu_count": 4,
"cpu_freq": [
600.0,
600.0,
1200.0 ],
"cpu_mem_avail": 386273280,
...
如果您已走到这一步,那么最困难的部分已经结束。
5. 重复
如果您重启您的 Pi,您必须按照以下步骤操作:
- 使用
source
重新激活您的 Python 环境。 - 使用
pip
刷新应用程序依赖项。 - 使用
gunicorn
启动 Flask 应用程序。
您的防火墙设置是持久的,但是如果您使用 localtunnel,那么您还必须在重启后启动一个新的隧道。
如果您愿意,您可以自动化这些任务,但这完全是另一个教程。本教程的最后一节是在 Appsmith 上使用拖放式小部件和一点 Javascript 构建 UI,以将您的 RPi 数据绑定到 UI。相信我,从这里开始就很容易了!
在 Appsmith 上构建仪表板。

(Keyur Paralkar, CC BY-SA 4.0)
要获得像这样的仪表板,您需要将公开的 API 端点连接到 Appsmith,使用 Appsmith 的小部件库构建 UI,并将 API 的响应绑定到您的小部件。如果您已经在使用 Appsmith,您可以直接导入示例应用并开始使用。
如果您尚未这样做,请注册一个免费的 Appsmith 帐户。或者,您可以自托管 Appsmith。
将 API 连接为 Appsmith 数据源
登录到您的 Appsmith 帐户。
- 在左侧导航栏中找到并单击 QUERIES/JS 旁边的 + 按钮。
- 单击 创建空白 API。
- 在页面顶部,将您的项目命名为 PiData。
- 获取您的 API 的 URL。如果您使用 localtunnel,那么它是一个
localtunnel.me
地址,并且始终在末尾附加/get-stats
以获取统计数据。将其粘贴到页面上的第一个空白字段中,然后单击 RUN 按钮。
确认您在 Response 窗格中看到成功响应。

(Keyur Paralkar, CC BY-SA 4.0)
构建 UI
AppSmith 的界面非常直观,但是如果您感到迷茫,我建议您浏览 在 Appsmith 上构建您的第一个应用程序 教程。
对于标题,将文本、图像和分隔线小部件拖放到画布上。像这样排列它们:

(Keyur Paralkar, CC BY-SA 4.0)
文本小部件包含您页面的实际标题。输入一些比“树莓派统计信息”更酷的东西。
图像小部件容纳仪表板的独特徽标。您可以使用任何您想要的东西。
使用开关小部件来切换实时数据模式。在 Property 面板中配置它以从您构建的 API 获取数据。
对于正文,使用左侧小部件库中的以下小部件,为 CPU 统计信息创建一个容器小部件:
- 进度条
- 统计框
- 图表
对内存和磁盘统计信息部分执行相同的操作。您不需要磁盘统计信息的图表,但是如果可以找到它的用途,请不要阻止您使用它。
您的小部件的最终排列应如下所示:

(Keyur Paralkar, CC BY-SA 4.0)
最后一步是将来自 API 的数据绑定到您拥有的 UI 小部件。
将数据绑定到小部件
返回画布并在三个类别的部分中找到您的小部件。首先设置 CPU 统计信息。
要将数据绑定到进度条小部件:
- 单击进度条小部件以在右侧查看属性面板。
- 查找 Progress 属性。
- 单击 JS 按钮以激活 Javascript。
- 在 Progress 的字段中粘贴
{{PiData.data.cpu_percent ?? 0}}
。该代码引用了来自您的名为PiData
的 API 的数据流。Appsmith 将响应数据缓存在PiData
的.data
运算符中。键cpu_percent
包含 Appsmith 用于显示百分比的数据,在本例中为 CPU 使用率。 - 在进度条小部件下方添加一个文本小部件作为标签。

(Keyur Paralkar, CC BY-SA 4.0)
CPU 部分中有三个统计框小部件。将数据绑定到每个小部件与绑定到进度条小部件完全相同,不同之处在于您从 .data
运算符绑定不同的数据属性。按照相同的步骤进行,但有以下例外:
{{${PiData.data.cpu_freq[0]} ?? 0 }}
以显示时钟速度。{{${PiData.data.cpu_count} ?? 0 }}
用于 CPU 计数。{{${(PiData.data.sensor_temperatures).toPrecision(3)} ?? 0 }}
用于 CPU 温度数据。
假设一切按计划进行,您最终会得到像这样的漂亮仪表板:

(Keyur Paralkar, CC BY-SA 4.0)
CPU 使用率趋势
您可以使用图表小部件将 CPU 使用率显示为趋势线,并使其随时间自动更新。
首先,单击小部件,在右侧找到 Chart Type 属性,并将其更改为 LINE CHART。要查看趋势线,请将 cpu_percent
存储在数据点数组中。您的 API 当前将其作为时间上的单个数据点返回,因此请使用 Appsmith 的 storeValue
函数(浏览器 setItem
方法的 Appsmith 原生实现)来获取数组。
单击 QUERIES/JS 旁边的 + 按钮,并将它命名为 utils。
将此 Javascript 代码粘贴到 Code 字段中:
export default {
getLiveData: () => {
//When switch is on:
if (Switch1.isSwitchedOn) {
setInterval(() => {
let utilData = appsmith.store.cpu_util_data;
PiData.run()
storeValue("cpu_util_data", [...utilData, {
x: PiData.data.cpu_percent,
y: PiData.data.cpu_percent
}]);
}, 1500, 'timerId')
} else {
clearInterval('timerId');
}
},
initialOnPageLoad: () => {
storeValue("cpu_util_data", []);
}
}
要初始化 Store
,您在名为 initialOnPageLoad
的对象中创建了一个 JavaScript 函数,并且您已将 storeValue
函数包含在其中。
您使用 storeValue("cpu_util_data", []);
将来自 cpu_util_data
的值存储到 storeValue
函数中。此函数在页面加载时运行。
到目前为止,代码每次刷新页面时都会将来自 cpu_util_data
的一个数据点存储在 Store
中。要存储数组,您可以使用下标变量 x
和 y
,它们都存储来自 cpu_percent
数据属性的值。
您还希望通过存储值之间的设定间隔自动存储此数据。当 setInterval 函数执行时:
- 将获取存储在
cpu_util_data
中的值。 - 将调用 API
PiData
。 cpu_util_data
将更新为x
和y
变量,其中包含返回的最新cpu_percent
数据。cpu_util_data
的值将存储在键utilData
中。- 步骤 1 到 4 将重复执行,当且仅当该函数设置为自动执行时。您可以使用开关小部件将其设置为自动执行,这解释了为什么存在
getLiveData
父函数。
导航到 Settings 选项卡以查找对象中的所有父函数,并在 RUN ON PAGE LOAD 选项中将 initialOnPageLoad
设置为 Yes。

(Keyur Paralkar, CC BY-SA 4.0)
现在刷新页面以进行确认。
返回画布。单击图表小部件并找到 Chart Data 属性。粘贴绑定 {{ appsmith.store.disk_util_data }}
到其中。如果您自己运行对象 utils
几次,这将获得您的图表。要自动运行此操作:
- 在仪表板的标题中找到并单击 Live Data Switch 小部件。
- 查找
onChange
事件。 - 将其绑定到
{{ utils.getLiveData() }}
。Javascript 对象是utils
,而getLiveData
是在您切换开关时激活的函数,它从您的树莓派获取实时数据。但是还有其他实时数据,因此相同的开关也适用于它们。继续阅读以了解如何操作。
绑定所有数据
将数据绑定到内存和磁盘部分中的小部件与您对 CPU 统计信息部分执行的操作类似。
对于内存,绑定更改为:
{{( PiData.data.cpu_mem_avail/1000000000).toPrecision(2) \* 100 ?? 0 }}
用于进度条。{{ \${(PiData.data.cpu_mem_used/1000000000).toPrecision(2)} ?? 0 }} GB
、{{ \${(PiData.data.cpu_mem_free/1000000000).toPrecision(2)} ?? 0}} GB
和{{ \${(PiData.data.cpu_mem_total/1000000000).toPrecision(2)} ?? 0 }} GB
用于三个统计框小部件。
对于磁盘,进度条和统计框小部件上的绑定分别更改为:
{{ PiData.data.disk_usage_percent ?? 0 }}
{{ \${(PiData.data.disk_usage_used/1000000000).toPrecision(2)} ?? 0 }} GB
{{ \${(PiData.data.disk_usage_free/1000000000).toPrecision(2)} ?? 0 }} GB
和{{ \${(PiData.data.disk_usage_total/1000000000).toPrecision(2)} ?? 0 }} GB
用于三个统计框小部件。
此处的图表需要更新您为 CPU 统计信息创建的 utils
对象,其中名为 disk_util_data
的 storeValue
键嵌套在 getLiveData
下,其逻辑与 cpu_util_data
相同。对于磁盘使用率图表,我们存储 disk_util_data,其逻辑与 CPU 使用率趋势图表的逻辑相同。
export default {
getLiveData: () => {
//When switch is on:
if (Switch1.isSwitchedOn) {
setInterval(() => {
const cpuUtilData = appsmith.store.cpu_util_data;
const diskUtilData = appsmith.store.disk_util_data;
PiData.run();
storeValue("cpu_util_data", [...cpuUtilData, { x: PiData.data.cpu_percent,y: PiData.data.cpu_percent }]);
storeValue("disk_util_data", [...diskUtilData, { x: PiData.data.disk_usage_percent,y: PiData.data.disk_usage_percent }]);
}, 1500, 'timerId')
} else {
clearInterval('timerId');
}
},
initialOnPageLoad: () => {
storeValue("cpu_util_data", []);
storeValue("disk_util_data", []);
}
}
可视化由开关切换实时数据开启和关闭以及 utils
Javascript 对象触发的数据流,如下所示:

(Keyur Paralkar, CC BY-SA 4.0)
切换开启后,图表会像这样变化:

(Keyur Paralkar, CC BY-SA 4.0)
美观、简约且非常实用。
尽情享用
随着您越来越熟悉 psutils
、Javascript 和 Appsmith,我认为您会发现您可以轻松且无休止地调整您的仪表板,以完成非常酷的事情,例如:
- 查看来自前一周、前一个月、前一季度、前一年或您的 RPi 数据允许的任何自定义范围的趋势
- 为任何统计信息的阈值突破构建警报机器人
- 监控连接到您的树莓派的其他设备
- 将
psutils
扩展到安装了 Python 的另一台计算机 - 使用另一个库监控您的家庭或办公室网络
- 监控您的花园
- 跟踪您自己的生活习惯
直到下一个精彩的构建,祝您黑客愉快!
评论已关闭。