Zabbix はネットワーク管理ソフトウェア。様々なものを取得、DBにデータを格納し、Webで可視化できる。
Zabbix はポーリングで取得する方法と、監視対象からデータをプッシュするやり方がある。
データをプッシュするには snmp や、zabbix sender という CLI プログラムを使う方法がある。
zabbix sender は Zabbix agents パッケージに含まれていて、 Unix 系や Windows 系が提供されている。
今回は ESP32 上で zabbix sender と同じように使用することのできる方法を試してみます。
環境
- Arduino 1.8.19
- ポータブル化済
- esp32 by Espressif Systems version 2.0.4
- Ubuntu Linux 22.04
- Zabbix サーバ
以下でインストールしたもの
「Zabbix を Raspberry Pi にインストール」
https://qiita.com/nanbuwks/items/42a3c7e740e721bffbf7
用語
-
エージェント
監視対象。snmp の知識があると、snmp ではデータ収集するところがエージェントというのでエージェントの言葉の意味が逆になるので注意。 -
サーバ
監視対象のデータを収集し、DBに格納し、Webサーバでビューする役目を持つ。フロントエンドはLAMP環境などで動くPHPプログラム。
ライブラリ
https://github.com/leruetkins/ESP32ZabbixSender
を試してみます。
ライブラリ導入
ポータブル化しているので、ポータブル環境ディレクトリから以下のようにして作業します。
$ cd porable/sketchbook/libraries
$ git clone https://github.com/leruetkins/ESP32ZabbixSender.git
$ ls -alh
.
.
.
drwxrwxr-x 4 nanbuwks nanbuwks 4.0K 3月 23 00:52 ESP32ZabbixSender
.
.
.
これだけだとダメで、以下の作業が必要でした。
$ cd ESP32ZabbixSender/
$ ls
ESP8266ZabbixSender.cpp ESP8266ZabbixSender.h README.md sample_ESP32ZabbixSender
$ mv ESP8266ZabbixSender.h ESP32ZabbixSender.h
$ mv ESP8266ZabbixSender.cpp ESP32ZabbixSender.cpp
サンプルプログラム
まずは、センサーとか何もつけずに Zabbix との通信のみを実現しt見ます。
sample_ESP32ZabbixSender
#include <ESP32ZabbixSender.h>
ESP32ZabbixSender zSender;
/* WiFi settings */
String ssid = "AP_SSID";
String pass = "AP_PASSWD";
/* Zabbix server setting */
#define SERVERADDR 192, 168, 35, 14 // Zabbix server Address
#define ZABBIXPORT 10051 // Zabbix erver Port
#define ZABBIXAGHOST "IOTBOARD_00" // Zabbix item's host name
boolean checkConnection();
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(100);
WiFi.begin(ssid.c_str(), pass.c_str());
while (!checkConnection()) {
}
zSender.Init(IPAddress(SERVERADDR), ZABBIXPORT, ZABBIXAGHOST); // Init zabbix server information
}
void loop() {
static int counter1 = 1;
static int counter2 = 1;
checkConnection(); // Check wifi connection
zSender.ClearItem(); // Clear ZabbixSender's item list
zSender.AddItem("counter1", (float)counter1); // Exmaple value of zabbix trapper item
zSender.AddItem("counter2", (float)counter2); // Exmaple value of zabbix trapper item
if (zSender.Send() == EXIT_SUCCESS) { // Send zabbix items
Serial.println("ZABBIX SEND: OK");
} else {
Serial.println("ZABBIX SEND: NG");
}
counter1 += 1;
counter2 *= 2;
delay(1000); // wait 1sec
}
boolean checkConnection() {
int count = 0;
Serial.print("Waiting for Wi-Fi connection");
while (count < 300) {
if (WiFi.status() == WL_CONNECTED) {
Serial.println();
Serial.println("Connected!");
return (true);
}
delay(500);
Serial.print(".");
count++;
}
Serial.println("Timed out.");
return false;
}
適宜書き換えます。
- wifi-settings をネットワーク環境にあわせて書き直し
- zabbix サーバに対して書き直し
#define SERVERADDR 192, 168, 42, 65
#define ZABBIXPORT 10051
#define ZABBIXAGHOST "PLANT_01" // Zabbix item's host name
- loop を以下のように書き直し
void loop() {
static int i = 0;
static int counter1 = 1;
static int counter2 = 1;
static int counter3 = 1;
checkConnection(); // Check wifi connection
zSender.ClearItem(); // Clear ZabbixSender's item list
zSender.AddItem("tempW", (float)counter1);
zSender.AddItem("tempB", (float)counter2);
zSender.AddItem("tempA", (float)counter3);
if (zSender.Send() == EXIT_SUCCESS) { // Send zabbix items
Serial.println("ZABBIX SEND: OK");
} else {
Serial.println("ZABBIX SEND: NG");
}
counter1 = sin((float)i/100)*100;
counter2 = cos((float)i/100)*120;
counter3 = i % 200 - 100;
i++;
delay(1000); // wait 1sec
}
Zabbix サーバの設定
作成した PLANT_01 の「アイテム」を押して
「監視データ」-「最新データ」で監視対象にチェックをつけて「グラフ表示」
以下のように表示できます
実際のセンサー値を表示
「サーミスタを使って安く温度を測定する」
https://qiita.com/nanbuwks/items/faebeac190b02a9fb716
の値を表示してみました。
#include <ESP32ZabbixSender.h>
ESP32ZabbixSender zSender;
String ssid = "openforce4";
String pass = "10101000";
#define SERVERADDR 192, 168, 42, 65
#define ZABBIXPORT 10051
#define ZABBIXAGHOST "PLANT_01" // Zabbix item's host name
boolean checkConnection();
const int BW=3100,BB=3950,BA=3950;
int thermistor_r;
int readW,readB,readA,readF;
float tempW,tempB,tempA;
float termistorRtoTemp(float T, float R, float B){
float t1 = log( R / T ) ;
float t2 = log(R/T);
//Serial.printf("T:%f R:%f B:%f logRT:%f ", T,R,B,R/T);
//Serial.printf("%f\n", t2);
float Temp = ((298*B) / ( B + ( 298 * t1 ))) - 273 ;
return(Temp);
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.disconnect();
pinMode(25,OUTPUT);
delay(100);
WiFi.begin(ssid.c_str(), pass.c_str());
while (!checkConnection()) {
}
zSender.Init(IPAddress(SERVERADDR), ZABBIXPORT, ZABBIXAGHOST); // Init zabbix server information
}
void loop() {
static int i = 0;
digitalWrite(25,HIGH);
readW = analogReadMilliVolts(34)+5;
readB = analogReadMilliVolts(32)+5;
readA = analogReadMilliVolts(33)+5;
readF = analogReadMilliVolts(35)+5;
digitalWrite(25,LOW);
Serial.printf("%d %d %d %d ",readW,readB,readA,readF);
// Serial.printf("%d %d %d ",readW,readB,readA);
thermistor_r = ( 1000 * readW )/ (readF - readA );
tempW = termistorRtoTemp(1000,thermistor_r,3100);
thermistor_r = ( 10000 * readB )/ (readF - readB );
tempB = termistorRtoTemp(10000,thermistor_r,3950);
thermistor_r = ( 10000 * readA )/ (readF - readA );
tempA = termistorRtoTemp(10000,thermistor_r,3950);
Serial.printf("%f %f %f \n",tempW,tempB,tempA);
checkConnection();
zSender.ClearItem();
zSender.AddItem("tempW", tempW);
zSender.AddItem("tempB", tempB);
zSender.AddItem("tempA", tempA);
if (zSender.Send() == EXIT_SUCCESS) {
Serial.println("ZABBIX SEND: OK");
} else {
Serial.println("ZABBIX SEND: NG");
}
i++;
delay(1000);
}
boolean checkConnection() {
int count = 0;
Serial.print("Waiting for Wi-Fi connection");
while (count < 300) {
if (WiFi.status() == WL_CONNECTED) {
Serial.println();
Serial.println("Connected!");
return (true);
}
delay(500);
Serial.print(".");
count++;
}
Serial.println("Timed out.");
return false;
}
これは青色の水温をモニターして、植物育成の値から外れているかどうかをチェックしているところです。