前言

本文将介绍如何使用Arduino和ESP2866微控制器,结合Zabbix API进行二次开发,以获取并显示主机的CPU占用率、可用内存、SWAP使用情况以及启动时间等关键硬件信息。我们将编写一系列函数,通过与Zabbix服务器建立连接、发送HTTP请求并解析返回的JSON数据,从中提取所需的信息,并使用OLED屏幕进行可视化展示。

通过阅读本文,示范如何结合Arduino和ESP2866,以及与Zabbix API进行交互,实现在物理设备上实时显示主机的硬件信息。提供一种简单而有效的方式,以更直观的方式监测和分析系统的性能,从而更好地管理和优化IT基础设施。

效果图:

事前准备

材料 数量
ESP8266 开发板 1块
SSD1306 OLED 屏幕 1个
  • 开发板引脚接线:
本文用的ESP8266 VCC GND GPIO 14 GPIO 2
D1 Mini VCC GND GPIO D1 GPIO D2
NodeMCU VCC GND D1 D2
SSD1306 OLED 屏幕 VCC GND SCL SDA

本文所使用的开发板接线

d1_mini dependencies...
Platform espressif8266 @ 4.2.0 (required: espressif8266)
├── framework-arduinoespressif8266 @ 3.30102.0 (required: platformio/framework-arduinoespressif8266 @ ~3.30102.0)
├── tool-esptool @ 1.413.0 (required: platformio/tool-esptool @ <2)
├── tool-esptoolpy @ 1.30000.201119 (required: platformio/tool-esptoolpy @ ~1.30000.0)
├── tool-mklittlefs @ 1.203.210628 (required: platformio/tool-mklittlefs @ ~1.203.0)
├── tool-mkspiffs @ 1.200.0 (required: platformio/tool-mkspiffs @ ~1.200.0)
└── toolchain-xtensa @ 2.100300.220621 (required: platformio/toolchain-xtensa @ ~2.100300.0)

Libraries
└── ESP8266 and ESP32 OLED driver for SSD1306 displays @ 4.4.0 (required: thingpulse/ESP8266 and ESP32 OLED driver for SSD1306 displays @ ^4.3.0)

程序逻辑

基于ESP8266和SSD1306 OLED屏幕的程序,用于显示主机的硬件信息。程序通过与Zabbix服务器进行通信,获取CPU占用率、可用内存、SWAP使用情况和启动时间等信息,并将其显示在OLED屏幕上。

程序的主要逻辑如下:

  1. 引入所需的库文件,包括ESP8266WiFi、WiFiClient、Wire和SSD1306Wire。
  2. 初始化OLED屏幕对象,并设置相关参数。
  3. 定义Wi-Fi网络的SSID和密码,以及Zabbix服务器的地址、端口、API路径和API令牌等信息。
  4. 定义各个API请求的字符串变量,用于向Zabbix服务器发送请求并获取数据。
  5. setup()函数中,初始化串口通信和OLED屏幕,并连接到Wi-Fi网络。然后调用各个打印函数,获取并显示CPU占用率、可用内存、SWAP使用情况和启动时间等信息。
  6. loop()函数中,循环调用各个打印函数,以实现周期性更新屏幕上的信息。
  7. printCPUUsage()函数用于获取并显示CPU占用率。
  8. printMemoryUsage()函数用于获取并显示可用内存。
  9. printSWAPUsage()函数用于获取并显示SWAP使用情况。
  10. printBootTime()函数用于获取并显示启动时间。

通过与Zabbix服务器的交互,程序能够获取主机的硬件信息,并利用OLED屏幕进行实时显示。用户可以根据需要对程序进行扩展,添加其他硬件信息的获取和显示功能。

程序解读

基本逻辑流程原理

  1. setup()函数中,首先通过WiFi.begin(ssid, password)建立与Wi-Fi网络的连接。
  2. 接着,调用四个系统信息函数,分别是printCPUUsageprintMemoryUsageprintSWAPUsageprintBootTime
  3. 在每个系统信息函数中,通过WiFiClient client创建一个与服务器的TCP连接。
  4. 使用client.connect(server, port)连接到Zabbix服务器。
  5. 如果连接成功,就发送一个HTTP POST请求到指定的API路径,同时在请求头中包含API令牌和主机名。
  6. 通过client.available()检查服务器是否有可用数据。
  7. 如果有数据可读取,使用client.readString()读取服务器的响应。
  8. 将服务器响应解析为JSON格式,并提取出所需的系统信息。
  9. 使用Serial.println()将系统信息打印到串行监视器。
  10. 关闭TCP连接,使用client.stop()断开与服务器的连接。

一些变量和字符串,用于与 Zabbix API 进行通信的含义:

  1. const char *ssid = "";:这是 Wi-Fi 网络的 SSID,用于连接 ESP8266 模块到 Wi-Fi 网络。
  2. const char *password = "";:这是 Wi-Fi 网络的密码,用于连接 ESP8266 模块到 Wi-Fi 网络。
  3. const char *server = "";:这是 Zabbix 服务器的地址,指定将要与之通信的服务器。
  4. const int port = ;:这是 Zabbix 服务器的端口号,通常是 80(HTTP)或 443(HTTPS)。
  5. const char *apiPath = "/zabbix/api_jsonrpc.php";:这是 Zabbix API 的路径,指定 API 的入口点。
  6. const char *apiToken = "";:这是用于身份验证的 API 令牌,用于在 API 请求中进行身份验证。
  7. const char *hostname = "zabbix-1";:这是 Zabbix 服务器的主机名或主机标识符,用于指定要获取数据的主机。

接下来,代码定义了用于 API 请求的字符串变量,包括 apiRequest_bootTimeapiRequest_swapapiRequest_cpuapiRequest_men。这些字符串包含了用于与 Zabbix API 进行通信的 JSON 请求的详细信息,每个字符串对应不同的 API 请求。

这些 JSON 请求中包含了以下参数:

  • jsonrpc:指定 JSON-RPC 的版本号。
  • method:指定要调用的 API 方法。
  • params:包含方法的参数,例如输出字段、搜索条件等。
  • auth:用于身份验证的 API 令牌。
  • id:请求的唯一标识符。

自定义函数解读

printCPUUsage()

这个函数用于打印CPU占用率。

  1. 创建一个WiFiClient对象client用于与服务器进行通信。
  2. 如果成功连接到服务器:
    • 构建HTTP POST请求,包括请求头和请求体。请求头中包括服务器主机地址、内容类型和内容长度等信息。
    • 发送请求到服务器。
    • 设置一个超时计时器,并等待服务器响应。
    • 如果在超时时间内收到了服务器的响应:
      • 跳过响应头部,找到分隔响应头部和响应体的空行。
      • 读取并解析服务器返回的JSON数据。
      • 从JSON数据中提取CPU占用率的值。
      • 打印CPU占用率。
      • 关闭与服务器的连接。
    • 否则,打印错误信息,关闭与服务器的连接。
  3. 如果无法连接到服务器,打印错误信息。

printMemoryUsage()

这个函数用于打印可用内存。

  1. 创建一个WiFiClient对象client用于与服务器进行通信。
  2. 如果成功连接到服务器:
    • 构建HTTP POST请求,包括请求头和请求体。请求头中包括服务器主机地址、内容类型和内容长度等信息。
    • 发送请求到服务器。
    • 设置一个超时计时器,并等待服务器响应。
    • 如果在超时时间内收到了服务器的响应:
      • 跳过响应头部,找到分隔响应头部和响应体的空行。
      • 读取并解析服务器返回的JSON数据。
      • 从JSON数据中提取可用内存的值。
      • 将字节数转换为GB单位。
      • 打印可用内存值。
      • 关闭与服务器的连接。
    • 否则,打印错误信息,关闭与服务器的连接。
  3. 如果无法连接到服务器,打印错误信息。

printSWAPUsage()

这个函数用于打印SWAP(交换空间)的使用情况。

  1. 创建一个WiFiClient对象client用于与服务器进行通信。
  2. 如果成功连接到服务器:
    • 构建HTTP POST请求,包括请求头和请求体。请求头中包括服务器主机地址、内容类型和内容长度等信息。
    • 发送请求到服务器。
    • 设置一个超时计时器,并等待服务器响应。
    • 如果在超时时间内收到了服务器的响应:
      • 跳过响应头部,找到分隔响应头部和响应体的空行。
      • 读取并解析服务器返回的JSON数据。
      • 从JSON数据中提取SWAP使用率的值。
      • 将SWAP使用率从百分比转换为GB单位。
      • 打印SWAP使用情况。
      • 关闭与服务器的连接。
    • 否则,打印错误信息,关闭与服务器的连接。
  3. 如果无法连接到服务器,打印错误信息。

printBootTime()

这个函数用于打印系统启动时间。

  1. 创建一个WiFiClient对象client用于与服务器进行通信。
  2. 如果成功连接到服务器:
    • 构建HTTP POST请求,包括请求头和请求体。请求头中包括服务器主机地址、内容类型和内容长度等信息。
    • 发送请求到服务器。
    • 设置一个超时计时器,并等待服务器响应。
    • 如果在超时时间内收到了服务器的响应:
      • 跳过响应头部,找到分隔响应头部和响应体的空行。
      • 读取并解析服务器返回的JSON数据。
      • 从JSON数据中提取启动时间的值。
      • 将启动时间从UNIX时间戳转换为可读格式。
      • 打印启动时间。
      • 关闭与服务器的连接。
    • 否则,打印错误信息,关闭与服务器的连接。
  3. 如果无法连接到服务器,打印错误信息。

这些函数使用了HTTP协议与服务器进行通信,通过发送POST请求并解析服务器返回的JSON数据,从中提取所需的信息,并打印在串口终端上。函数中的代码负责处理网络通信和数据解析的细节,使用户能够轻松获取和打印所需的系统信息。

对应成Linux命令

# API 请求字符串变量 - apiRequest_bootTime
curl -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "method": "item.get",
  "params": {
    "output": ["lastvalue"],
    "search": {
      "key_": "system.boottime"
    },
    "host": "主机名"
  },
  "auth": "你的zabbix auth token",
  "id": 1
}' http://你的zabbix服务器路径/zabbix/api_jsonrpc.php

# API 请求字符串变量 - apiRequest_swap
curl -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "method": "item.get",
  "params": {
    "output": ["lastvalue"],
    "search": {
      "key_": "system.swap.size[,pfree]"
    },
    "host": "主机名"
  },
  "auth": "你的zabbix auth token",
  "id": 1
}' http://你的zabbix服务器路径/zabbix/api_jsonrpc.php

# API 请求字符串变量 - apiRequest_cpu
curl -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "method": "item.get",
  "params": {
    "output": ["lastvalue"],
    "host": "主机名",
    "search": {
      "key_": "system.cpu.load[all,avg1]"
    },
    "sortfield": "name"
  },
  "auth": "你的zabbix auth token",
  "id": 1
}' http://你的zabbix服务器路径/zabbix/api_jsonrpc.php

# API 请求字符串变量 - apiRequest_men
curl -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "method": "item.get",
  "params": {
    "output": ["lastvalue"],
    "host": "主机名",
    "search": {
      "key_": "vm.memory.size[available]"
    },
    "sortfield": "name"
  },
  "auth": "你的zabbix auth token",
  "id": 1
}' http://你的zabbix服务器路径/zabbix/api_jsonrpc.php

参考文章


一沙一世界,一花一天堂。君掌盛无边,刹那成永恒。