Arduino
zabbix
ESP8266
ESP-WROOM-02

ESP-WROOM-02からZabbixサーバーにZabbix senderプロトコルでデータを送信する

More than 1 year has passed since last update.


はじめに

zabbix_senderコマンドからサーバーへのデータの送信に使われているプロトコルは比較的シンプルな物で、ネットワークに接続できるマイコンであれば充分に実装できるものです。

このプロトコルをESP-WROOM-02なモジュールと組み合わせると各種センサーのデータをZabbixサーバーで収集するデバイスがお手軽に作れそうだったので、まずはZabbix senderプロトコルの仕組みでサーバーに値を登録できるところまで試してみました。

なお、本稿の例ではZabbix 3.0から実装された通信の暗号化には対応していません。

本稿の内容を実際に試す際には充分に信用のおけるネットワーク内で実行する事をお勧めします。


環境


ソースコード


ESP8266_zabbix-sender

#include <ESP8266WiFi.h>

#include <Ticker.h>
#include <ArduinoJson.h>

const char* ssid = "YourAccessPointName";
const char* password = "YourAccessPointPassword";
const char* zbx_server = "YourZabbixServerIPaddr";

Ticker ticker;
bool readyForTicker = false;

void setReadyForTicker() {
// A flag
readyForTicker = true;
}

int value = 0;
void doBlockingIO() {

uint64_t payloadsize ;

// dummy value increment
++value;

// create "zabbix sender format" json data for sending zabbix server
StaticJsonBuffer<200> jsonBuffer;
JsonObject& root = jsonBuffer.createObject();
root["request"] = "sender data";

JsonArray& data = root.createNestedArray("data");

JsonObject& item = jsonBuffer.createObject();
item["host"] = "Home Network";
item["key"] = "test";
item["value"] = value;
data.add(item);

/*
// zabbix sender can send more items at once
JsonObject& item2 = jsonBuffer.createObject();
item2["host"] = "Home Network";
item2["key"] = "test2";
item2["value"] = "hello";
data.add(item2);
*/

Serial.println();
Serial.println("== request ================");
root.printTo(Serial);

Serial.println("");
Serial.println("============================");
char buffer[256];
root.printTo(buffer, sizeof(buffer));
Serial.print("payload json size: ");
Serial.println(strlen(buffer));
Serial.println("============================");

//////////////////////////////
// connect to zabbix server
Serial.print("connecting to ");
Serial.println(zabbix_server);

// Use WiFiClient class to create TCP connections
WiFiClient client;
const int zabbixPort = 10051 ;
if (!client.connect(zabbix_server, zabbixPort)) {
Serial.println("connection failed");
return;
}

//////////////////////////////
// send the zabbix_sender's format data to server

// send fixed header to zabbix server
client.print(String("ZBXD") );
client.write(0x01);

// send json size to zabbix server
payloadsize = strlen(buffer);
for (int i = 0; i < 64; i += 8) {
client.write(lowByte(payloadsize >> i));
}

// send json to zabbix server
client.print(buffer);
//////////////////////////////

unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) {
Serial.println(">>> Client Timeout !");
client.stop();
return;
}
}

// Read all the lines of the reply from server and print them to Serial
while (client.available()) {
String line = client.readStringUntil('\r');
Serial.println("== response ================");
Serial.print(line);
Serial.println("");
Serial.println("============================");
}

Serial.println();
Serial.println("closing connection");

// Drop the flag
readyForTicker = false;
}

void setup() {
Serial.begin(115200);
delay(10);

// We start by connecting to a WiFi network

Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}

Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());

// call setReadyForTicker() every 60 seconds
ticker.attach(60, setReadyForTicker);
}

void loop() {
if (readyForTicker) {
doBlockingIO();
}
}



サーバー側の設定


  • ZabbixサーバーのWeb UI上で"Home Network"という名前のホストを作成

  • Zabbixトラッパー型のtestというキーのアイテムを作成

※ホスト名、アイテムキーはソースコード内で設定しているものに揃える

item.png


実際にやってみた様子

インクリメントされる数値が1分おきにサーバーに登録されるところまで出来ました。

kekka.png


おわりに

さきほどI2C接続のセンサーをいくつかポチったので、それらが届き次第上述の内容と組み合わせてみたいと思います。


参考