さくらのVPS上にMQTTブローカーMosquittoと時系列データベースInfluxDBを構築し、M5ATOMS3とEnvIIIユニットで測定した環境データをGrafanaで可視化する手順について記録します。
1. システム構成
- デバイス: M5ATOMS3 + EnvIII Unit
- 通信プロトコル: MQTT
-
サーバー: さくらのVPS (Ubuntu 24.04 LTS)
- MQTT Broker: Mosquitto
- Data Collector: Telegraf
- Database: InfluxDB
- Dashboard: Grafana
2. さくらのVPSのセットアップ
- プラン選択: メモリ1GBプランにしました。
- OSインストール: Ubuntu 24.04 LTS にしました。
- IPアドレスの確認: コントロールパネルより割り当てられたIPアドレスを確認します。
3. ファイアウォールの設定
通信に必要なポートを開放するため、VPS側のパケットフィルタとOS側のファイアウォール(UFW)の両方を設定します。
3.1 さくらのVPS パケットフィルタ設定
VPSコントロールパネルの「パケットフィルタ」にて、以下のポートを許可設定(Inbound)に追加し、「設定反映」を行います。
- TCP 1883: MQTT通信用
- TCP 3000: Grafanaアクセス用
- TCP 22: SSH接続用 (デフォルトで許可されています)
3.2 OSファイアウォール (UFW) 設定
powershellで、SSHでサーバーに接続しssh ubuntu@<VPS_IP> 例ssh ubuntu@xxx.xxx.xxx.xxx、以下のコマンドを実行してポートを開放します。
sudo ufw allow 1883/tcp
sudo ufw allow 3000/tcp
sudo ufw reload
4. Mosquitto (MQTTブローカー) のインストール
データの送受信を行うMQTTブローカーを構築します。
sudo apt update
sudo apt install -y mosquitto mosquitto-clients
外部からの接続を許可するため、設定ファイルを作成します。
sudo nano /etc/mosquitto/conf.d/external.conf
listener 1883
allow_anonymous true
設定を反映させるため、サービスを再起動します。
sudo systemctl restart mosquitto
5. InfluxDB (時系列データベース) のインストール
センサーデータを保存するためのデータベースをインストールします。
# 必要なツールのインストール
sudo apt install -y curl gnupg2
# GPGキーの追加
wget -q https://repos.influxdata.com/influxdata-archive_compat.key
cat influxdata-archive_compat.key | gpg --dearmor | sudo tee /usr/share/keyrings/influxdata-archive_compat.gpg > /dev/null
# リポジトリの追加
echo 'deb [signed-by=/usr/share/keyrings/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main' | sudo tee /etc/apt/sources.list.d/influxdata.list
# インストール実行
sudo apt update
sudo apt install -y influxdb influxdb-client
# サービスの有効化と起動
sudo systemctl unmask influxdb
sudo systemctl enable influxdb
sudo systemctl start influxdb
6. Telegraf (データ収集エージェント) のインストールと設定
MQTTで受け取ったデータをJson形式として解析し、InfluxDBへ格納するための設定を行います。
パッケージは公式リポジトリからdebファイルを直接ダウンロードしてインストールします。
# インストーラーのダウンロードと実行 (バージョンは適宜最新のものを使用してください)
wget https://dl.influxdata.com/telegraf/releases/telegraf_1.29.5-1_amd64.deb
sudo dpkg -i telegraf_1.29.5-1_amd64.deb
※依存関係エラーが発生した場合は sudo apt-get install -f を実行してください。
設定ファイルの編集
/etc/telegraf/telegraf.conf を編集します。
sudo nano /etc/telegraf/telegraf.conf
以下の内容で上書き(または該当箇所を修正)します。
注意: tag_keys = ["device"] の設定により、Jsonデータ内の "device" フィールドをタグとして扱います。これによりGrafana等でのフィルタリングが可能になります。
[agent]
interval = "10s"
round_interval = true
metric_batch_size = 1000
metric_buffer_limit = 10000
collection_jitter = "0s"
flush_interval = "10s"
flush_jitter = "0s"
precision = ""
hostname = ""
omit_hostname = false
# MQTT input plugin
[[inputs.mqtt_consumer]]
servers = ["tcp://127.0.0.1:1883"]
topics = ["sensor/#"]
data_format = "json"
tag_keys = ["device"]
# InfluxDB output plugin
[[outputs.influxdb]]
urls = ["http://127.0.0.1:8086"]
database = "sensors"
設定反映のため再起動します。
sudo systemctl restart telegraf
7. Grafana (可視化ツール) のインストール
sudo apt-get install -y apt-transport-https software-properties-common wget
sudo mkdir -p /etc/apt/keyrings/
wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/grafana.gpg > /dev/null
echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | sudo tee /etc/apt/sources.list.d/grafana.list
sudo apt-get update
sudo apt-get install -y grafana
sudo systemctl enable grafana-server
sudo systemctl start grafana-server
8. M5ATOMS3 実装プログラム
Arduino IDEを使用し、以下のスケッチをデバイスに書き込みます。
必要なライブラリ: M5Unified, M5Unit-ENV, PubSubClient, ArduinoJson
#include <M5Unified.h>
#include <M5UnitENV.h> // M5Unit-ENVライブラリ
#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
// ========== 設定エリア ==========
const char* ssid = "YOUR_WIFI_SSID"; // WiFi名
const char* password = "YOUR_WIFI_PASSWORD"; // WiFiパスワード
const char* mqtt_server = "YOUR_VPS_IP"; // さくらのVPSのIPアドレス
const char* device_name = "AtomS3"; // デバイス名 (Grafanaの絞り込みに使用)
// MQTT設定
const int mqtt_port = 1883;
const char* mqtt_topic = "sensor/data";
// ===============================
SHT3X sht30;
QMP6988 qmp6988;
WiFiClient espClient;
PubSubClient client(espClient);
void setup_wifi() {
delay(10);
M5.Display.println();
M5.Display.print("Connecting to ");
M5.Display.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
M5.Display.print(".");
}
M5.Display.println("");
M5.Display.println("WiFi connected");
M5.Display.println("IP address: ");
M5.Display.println(WiFi.localIP());
}
void reconnect() {
while (!client.connected()) {
M5.Display.print("Attempting MQTT connection...");
String clientId = "M5AtomS3Client-";
clientId += String(random(0xffff), HEX);
if (client.connect(clientId.c_str())) {
M5.Display.println("connected");
} else {
M5.Display.print("failed, rc=");
M5.Display.print(client.state());
M5.Display.println(" try again in 5 seconds");
delay(5000);
}
}
}
void setup() {
auto cfg = M5.config();
M5.begin(cfg);
M5.Display.setTextSize(1.5);
Serial.begin(115200);
// AtomS3のGrove端子: G2(SDA), G1(SCL)
Wire.begin(2, 1);
if (!qmp6988.begin(&Wire, QMP6988_SLAVE_ADDRESS_L, 2, 1, 400000U)) {
M5.Display.println("QMP6988 not found");
}
if (!sht30.begin(&Wire, SHT3X_I2C_ADDR, 2, 1, 400000U)) {
M5.Display.println("SHT30 not found");
}
setup_wifi();
client.setServer(mqtt_server, mqtt_port);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
// 30秒ごとに送信
static unsigned long lastMsg = 0;
unsigned long now = millis();
if (now - lastMsg > 30000) {
lastMsg = now;
if (qmp6988.update() && sht30.update()) {
float temp = sht30.cTemp;
float hum = sht30.humidity;
float pressure = qmp6988.pressure / 100.0; // Pa -> hPa
// JSONデータの作成
StaticJsonDocument<200> doc;
doc["temperature"] = temp;
doc["humidity"] = hum;
doc["pressure"] = pressure;
doc["device"] = device_name;
char buffer[256];
serializeJson(doc, buffer);
// MQTT送信
M5.Display.fillScreen(BLACK);
M5.Display.setCursor(0,0);
M5.Display.printf("Temp: %.1f\nHum: %.1f\nPres: %.0f\n", temp, hum, pressure);
if (client.publish(mqtt_topic, buffer)) {
M5.Display.println("Sent!");
Serial.println(buffer);
} else {
M5.Display.println("Send failed");
}
}
}
}
9. データの確認とGrafanaの設定
9.1 データ着信確認
InfluxDBクライアントを使用して、データが正常に格納されているか確認します。
powershellで、SSHでサーバーに接続ssh ubuntu@<VPS_IP> 例ssh ubuntu@xxx.xxx.xxx.xxx
influx -precision rfc3339
> use sensors
> select * from mqtt_consumer order by time desc limit 5
9.2 Grafana設定
-
アクセス:
http://<VPS_IP>:3000(例:http://xxx.xxx.xxx.xxx:3000, 初期ID/PW: admin/admin, PW変更が求められる) -
Data Source: InfluxDBを追加 (URL:
http://localhost:8086, Database:sensors) -
Dashboard作成:
- 新規Dashboardを作成し、Panelを追加します。
- Data Sourceに先ほど追加した InfluxDB を選択します。
- Query設定 (Graphical Editor) にて:
-
FROM:
default(retention policy) /mqtt_consumer(measurement) を選択。 -
WHERE:
device=AtomS3を追加(デバイスごとの絞り込み)。 -
SELECT:
field(temperature)などを指定。
-
FROM:
- これでグラフが表示されます。
10. データ保持ポリシーの設定 (Data Retention)
ディスク容量の圧迫を防ぐため、古いデータを自動削除する設定を行います(例: 90日保存)。
influx
> use sensors
> ALTER RETENTION POLICY "autogen" ON "sensors" DURATION 90d
> SHOW RETENTION POLICIES
> exit
※ 表示される duration が 2160h0m0s (24時間 × 90日) となっていれば正しく設定されています。
※ もう一つの shardGroupDuration (例: 168h0m0s) は、InfluxDBが内部でデータを管理するファイル単位(この場合は1週間)を表すもので、保存期間とは異なりますのでそのままで問題ありません。
11. 可視化したグラフはこちら(Grafana)
以上でデータの可視化は完了です。

