M5Core2 + ENVⅢ + Nostr で作る環境データ可視化システム
M5Core2 + ENVⅢ + Nostr で作る環境データ可視化システム
はじめに
データベースサーバーを使わずに、Nostrプロトコルを活用した環境データ収集・可視化システムを作りました。M5 Core2に温湿度気圧センサーを接続し、1時間ごとに取得したデータをNostrに投稿。そのデータを読み取って、直近一週間の環境データをグラフで表示するWebアプリケーションも併せて開発しました。
成果物
- 環境データBot: まいへやBot
- データ可視化サイト: まいへやデータビューア
M5 | Bot |
---|---|
![]() |
![]() |
使用機材・技術
ハードウェア
ソフトウェア
- M5側: Arduino IDE、C++
- Web側: Svelte、TypeScript
- プロトコル: Nostr
システム構成
このシステムは大きく2つの部分から構成されています。
- データ収集部: M5 Core2でセンサーデータを取得し、Nostrに投稿
- データ表示部: Nostrからデータを取得し、Webブラウザでグラフ表示
実装詳細
1. センサーデータの収集・投稿(M5側)
主要なライブラリ
- M5Core2標準ライブラリ、WiFi関連
- arduino-nostr 0.2.0
- uBitcoin 0.2.0
投稿データ形式
センサーから取得したデータは以下の形式でNostrに投稿されます:
🌡️ 温度: 25.0°C
💧 湿度: 62.6%
📊 気圧: 999.7hPa
ソースコード
実装の詳細は以下のリポジトリで公開しています:
2. データ可視化(Web側)
主要なライブラリ
- rx-nostr @rx-nostr/crypto - Nostrクライアント
- Chart.js + chartjs-adapter-date-fns - グラフ描画
データ取得フィルター
過去7日間のデータを取得するため、以下のフィルターを使用:
const since = Math.floor((Date.now() - 7 * 24 * 60 * 60 * 1000) / 1000);
const filter = {
authors: [PUBKEY_HEX],
kinds: [1],
since: since,
limit: 500
};
データ抽出処理
投稿されたテキストから各環境データを正規表現で抽出:
// 温度の抽出 (🌡️ 温度: 22.7°C や おんど: 23.0℃)
const tempMatch = content.match(/(?:🌡️\s*)?(?:温度|おんど)[::]?\s*([0-9.]+)\s*(?:°C|℃)/i);
// 湿度の抽出 (💧 湿度: 74.8% や しつど: 49%)
const humidityMatch = content.match(/(?:💧\s*)?(?:湿度|しつど)[::]?\s*([0-9.]+)\s*%/i);
// 気圧の抽出 (📊 気圧: 996.4hPa や きあつ: 1010hPa)
const pressureMatch = content.match(/(?:📊\s*)?(?:気圧|きあつ)[::]?\s*([0-9.]+)\s*hPa/i);
実装リポジトリ
Webアプリケーションの実装詳細:
GitHub - app ディレクトリ
工夫したポイント
データベース不要の設計
従来のIoTシステムでは専用のデータベースサーバーが必要ですが、このシステムではNostrプロトコルを活用することで、分散型のデータ保存を実現しました。これにより、サーバー運用コストを削減し、システムの可用性を向上させています。
リレー選択
Botの投稿を受け入れてくれるNostrリレーを「雰囲気で」選択しているのも特徴の一つです。Nostrの分散型特性を活かし、複数のリレーに投稿することで、データの冗長性を確保できます。
柔軟なデータ抽出
投稿形式の変更に対応できるよう、正規表現パターンを工夫しました。これにより、システムの運用中にデータ形式を調整した場合でも、過去データを含めて正しく処理できます。
まとめ
NostrプロトコルとM5Stackを組み合わせることで、シンプルながら実用的な環境データ監視システムを構築できました。データベースサーバーが不要で、分散型の特性を活かしたIoTシステムの新しい形として、今後も発展の可能性を感じています。
グラフに表示されているデータの欠落部分は、コード改造中でNostrへの投稿が停止していた期間によるものです。継続的な運用により、より安定したデータ収集が期待できます。
Discussion