メインコンテンツへスキップ
三田工場 技術サイト
実践:Raspberry Piで設備監視システムを作る

実践:Raspberry Piで設備監視システムを作る

HowTo11分で読めます

このシリーズ: 全5回

  1. 第1回: MQTTとは?IoT時代の「伝言板」を初心者向けに解説
  2. 第2回: Pub/Subモデルとトピックの仕組み
  3. 第3回: 実践:Raspberry Piで設備監視システムを作る ← 今ここ
  4. 第4回: 複数のRaspberry Piを中継機で束ねてOracle DBにデータを送る
  5. 第5回: MQTTで双方向通信!Oracleのデータを子機に配信する

はじめに

前回までの記事で、MQTTとPub/Subモデルの概念を理解しました。

今回は実際にRaspberry Piを使って、 工場の設備監視システムを構築してみましょう。


完成イメージ

text
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│     【工場フロア】                                           │
│                                                             │
│   ┌─────────┐   ┌─────────┐   ┌─────────┐                 │
│   │📷 カメラ1│   │📷 カメラ2│   │📷 カメラ3│                 │
│   │  設備A   │   │  設備B   │   │  設備C   │                 │
│   │  🟢稼働  │   │  🔴停止  │   │  🟡異常  │                 │
│   └────┬────┘   └────┬────┘   └────┬────┘                 │
│        │             │             │                       │
│        │   Wi-Fi     │             │                       │
│        └─────────────┼─────────────┘                       │
│                      │                                     │
│                      ▼                                     │
│   ┌──────────────────────────────────┐                    │
│   │  🖥️ 中継機(このRaspberry Pi)    │                    │
│   │                                  │                    │
│   │  ・MQTTブローカー (Mosquitto)     │                    │
│   │  ・Oracle連携ブリッジ             │                    │
│   └──────────────────┬───────────────┘                    │
│                      │                                     │
│                      │ インターネット                       │
│                      ▼                                     │
│   ┌──────────────────────────────────┐                    │
│   │  ☁️ Oracle Cloud Database        │                    │
│   │     データ蓄積・分析              │                    │
│   └──────────────────────────────────┘                    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

システム構成の解説

なぜこの構成が良いの?

text
❌ 悪い例:各カメラから直接クラウドへ
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

┌─────────┐      インターネット      ┌─────────┐
│ カメラ1  │ ─────────────────────→ │  Cloud  │
└─────────┘                         └─────────┘
┌─────────┐                         ┌─────────┐
│ カメラ2  │ ─────────────────────→ │  Cloud  │
└─────────┘                         └─────────┘
┌─────────┐                         ┌─────────┐
│ カメラ3  │ ─────────────────────→ │  Cloud  │
└─────────┘                         └─────────┘

問題点:
・各カメラにクラウドの認証情報が必要(セキュリティリスク)
・インターネット障害で全停止
・カメラが増えるたびにクラウド設定が必要


✅ 良い例:中継機を経由
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

┌─────────┐
│ カメラ1  │ ─┐
└─────────┘   │
              │  ローカル    ┌─────────┐  インターネット  ┌─────────┐
┌─────────┐   │  ネットワーク │  中継機  │ ───────────→  │  Cloud  │
│ カメラ2  │ ──┼────────────→│         │                └─────────┘
└─────────┘   │              └─────────┘

┌─────────┐   │
│ カメラ3  │ ─┘
└─────────┘

メリット:
・クラウド認証情報は中継機だけ(セキュリティ向上)
・ローカルで一時保存可能(障害耐性)
・カメラ追加が簡単(中継機を見るだけ)

中継機の役割

text
┌────────────────────────────────────────────────────────────┐
│                    中継機の内部構造                         │
├────────────────────────────────────────────────────────────┤
│                                                            │
│   入口(受信)                                              │
│   ┌────────────────────────────────────────┐              │
│   │         Mosquitto (MQTTブローカー)      │              │
│   │                                        │              │
│   │  ポート1883で待ち受け                   │              │
│   │  equipment/status/# を受信            │              │
│   └────────────────────┬───────────────────┘              │
│                        │                                  │
│                        │ メッセージ配信                    │
│                        ▼                                  │
│   処理(変換・保存)                                        │
│   ┌────────────────────────────────────────┐              │
│   │      MQTT-Oracle ブリッジ               │              │
│   │                                        │              │
│   │  ① MQTTメッセージを受信                 │              │
│   │  ② JSONデータを解析                    │              │
│   │  ③ Oracleに保存                        │              │
│   │  ④ 重複チェック(同一秒はスキップ)      │              │
│   └────────────────────┬───────────────────┘              │
│                        │                                  │
│                        ▼                                  │
│   出口(送信)                                              │
│   ┌────────────────────────────────────────┐              │
│   │         Oracle Cloud Database          │              │
│   │                                        │              │
│   │  テーブル: EQUIPMENT_STATUS            │              │
│   │  カラム: MK_DATE, STA_NO1-3, T1_STATUS │              │
│   └────────────────────────────────────────┘              │
│                                                            │
└────────────────────────────────────────────────────────────┘

データの流れ(詳細)

Step 1: カメラが色を検知

text
┌────────────────────────────────────────────────────────────┐
│                    カメラ側の処理                           │
├────────────────────────────────────────────────────────────┤
│                                                            │
│   ┌──────────────────┐                                    │
│   │    📷 カメラ      │                                    │
│   │                  │                                    │
│   │  ┌────────────┐  │                                    │
│   │  │ 🟢 緑の領域 │  │  ← 設備のランプを監視              │
│   │  └────────────┘  │                                    │
│   └────────┬─────────┘                                    │
│            │                                              │
│            ▼                                              │
│   ┌──────────────────┐                                    │
│   │   色検知プログラム  │                                    │
│   │                  │                                    │
│   │  緑 → status: 1  │  (稼働中)                        │
│   │  赤 → status: 2  │  (停止)                          │
│   │  黄 → status: 3  │  (異常)                          │
│   └────────┬─────────┘                                    │
│            │                                              │
│            ▼                                              │
│   JSONデータを生成:                                        │
│   {                                                       │
│     "mk_date": "20260205120000",                          │
│     "sta_no1": "FACTORY01",                               │
│     "sta_no2": "LINE01",                                  │
│     "sta_no3": "EQ001",                                   │
│     "t1_status": 1                                        │
│   }                                                       │
│                                                            │
└────────────────────────────────────────────────────────────┘

Step 2: MQTTで送信

text
┌────────────────────────────────────────────────────────────┐
│                    MQTT送信                                │
├────────────────────────────────────────────────────────────┤
│                                                            │
│   カメラ側                                                  │
│   ┌──────────────────────────────────────┐                │
│   │  import paho.mqtt.client as mqtt     │                │
│   │                                      │                │
│   │  client = mqtt.Client()              │                │
│   │  client.connect("192.168.32.213")    │ ← 中継機のIP  │
│   │                                      │                │
│   │  client.publish(                     │                │
│   │    "equipment/status/EQ001",         │ ← トピック     │
│   │    json.dumps(data)                  │ ← データ       │
│   │  )                                   │                │
│   └──────────────────────────────────────┘                │
│                                                            │
│                         │                                  │
│                         │ Wi-Fi / LAN                      │
│                         ▼                                  │
│                                                            │
│   中継機側                                                  │
│   ┌──────────────────────────────────────┐                │
│   │           Mosquitto                  │                │
│   │                                      │                │
│   │  "equipment/status/EQ001" に         │                │
│   │  メッセージが到着!                   │                │
│   │                                      │                │
│   │  → 購読者(ブリッジ)に配信           │                │
│   └──────────────────────────────────────┘                │
│                                                            │
└────────────────────────────────────────────────────────────┘

Step 3: ブリッジがOracleに保存

text
┌────────────────────────────────────────────────────────────┐
│                    Oracle保存                              │
├────────────────────────────────────────────────────────────┤
│                                                            │
│   ブリッジ                                                  │
│   ┌──────────────────────────────────────┐                │
│   │  def on_message(client, userdata, msg):               │
│   │                                      │                │
│   │    # JSONを解析                       │                │
│   │    data = json.loads(msg.payload)    │                │
│   │                                      │                │
│   │    # Oracleに保存                     │                │
│   │    cursor.execute("""                │                │
│   │      INSERT INTO EQUIPMENT_STATUS    │                │
│   │      (MK_DATE, STA_NO1, STA_NO2,     │                │
│   │       STA_NO3, T1_STATUS)            │                │
│   │      VALUES (:1, :2, :3, :4, :5)     │                │
│   │    """, [...])                       │                │
│   └──────────────────────────────────────┘                │
│                                                            │
│                         │                                  │
│                         │ インターネット (HTTPS)           │
│                         ▼                                  │
│                                                            │
│   Oracle Cloud                                             │
│   ┌──────────────────────────────────────┐                │
│   │  EQUIPMENT_STATUS テーブル            │                │
│   │                                      │                │
│   │  MK_DATE        | STA_NO3 | STATUS   │                │
│   │  ─────────────────────────────────── │                │
│   │  20260205120000 | EQ001   | 1        │                │
│   │  20260205120001 | EQ002   | 2        │                │
│   │  20260205120002 | EQ001   | 1        │                │
│   └──────────────────────────────────────┘                │
│                                                            │
└────────────────────────────────────────────────────────────┘

複数カメラの場合

text
┌────────────────────────────────────────────────────────────┐
│                 複数カメラの運用                            │
├────────────────────────────────────────────────────────────┤
│                                                            │
│   Raspberry Pi #1 (192.168.32.100)                        │
│   ┌─────────────────────┐                                 │
│   │  カメラ: 設備A監視    │                                 │
│   │  STA_NO3: EQ001     │ ──┐                             │
│   └─────────────────────┘   │                             │
│                             │                             │
│   Raspberry Pi #2 (192.168.32.101)                        │
│   ┌─────────────────────┐   │                             │
│   │  カメラ: 設備B監視    │   │  すべて同じトピック          │
│   │  STA_NO3: EQ002     │ ──┼─ equipment/status/XXX       │
│   └─────────────────────┘   │                             │
│                             │                             │
│   Raspberry Pi #3 (192.168.32.102)                        │
│   ┌─────────────────────┐   │                             │
│   │  カメラ: 設備C監視    │   │                             │
│   │  STA_NO3: EQ003     │ ──┘                             │
│   └─────────────────────┘                                 │
│                             │                             │
│                             ▼                             │
│   中継機 (192.168.32.213)                                  │
│   ┌─────────────────────────────────────────────┐        │
│   │                                             │        │
│   │  Mosquitto: equipment/status/# を受信       │        │
│   │                                             │        │
│   │  → EQ001のデータ来た!→ Oracle保存          │        │
│   │  → EQ002のデータ来た!→ Oracle保存          │        │
│   │  → EQ003のデータ来た!→ Oracle保存          │        │
│   │                                             │        │
│   └─────────────────────────────────────────────┘        │
│                                                            │
│   ポイント:                                                │
│   ・各カメラは自分のSTA_NO3だけ変えればOK                   │
│   ・中継機の設定変更は不要                                  │
│   ・カメラを追加しても中継機はそのまま動く                   │
│                                                            │
└────────────────────────────────────────────────────────────┘

障害に強い理由

ケース1: インターネット障害

text
┌────────────────────────────────────────────────────────────┐
│              インターネットが切れた場合                      │
├────────────────────────────────────────────────────────────┤
│                                                            │
│   カメラ → 中継機: ✅ 動作継続                              │
│   (ローカルネットワークは生きている)                        │
│                                                            │
│   中継機 → Oracle: ❌ 一時停止                             │
│   (インターネットが切れている)                             │
│                                                            │
│   対策オプション:                                           │
│   ┌─────────────────────────────────────────────┐        │
│   │  ・中継機にローカルDBを追加                   │        │
│   │  ・ファイルにバッファリング                   │        │
│   │  ・復旧後に再送信                            │        │
│   └─────────────────────────────────────────────┘        │
│                                                            │
└────────────────────────────────────────────────────────────┘

ケース2: カメラ1台が故障

text
┌────────────────────────────────────────────────────────────┐
│               カメラ1台が故障した場合                        │
├────────────────────────────────────────────────────────────┤
│                                                            │
│   カメラ1: ❌ 故障                                         │
│   カメラ2: ✅ 正常動作                                      │
│   カメラ3: ✅ 正常動作                                      │
│   中継機:  ✅ 正常動作                                      │
│   Oracle:  ✅ 正常動作                                      │
│                                                            │
│   → 他のカメラは影響なし!                                  │
│   → 疎結合のメリット                                        │
│                                                            │
└────────────────────────────────────────────────────────────┘

コスト比較

text
┌────────────────────────────────────────────────────────────┐
│                    コスト比較                              │
├────────────────────────────────────────────────────────────┤
│                                                            │
│   ┌─────────────────────────────────────────────┐        │
│   │           オープンソース(今回の構成)        │        │
│   ├─────────────────────────────────────────────┤        │
│   │  Mosquitto        : 無料                    │        │
│   │  Python           : 無料                    │        │
│   │  paho-mqtt        : 無料                    │        │
│   │  Oracle Always Free: 無料                   │        │
│   │  ─────────────────────────────────          │        │
│   │  合計: 0円/月                               │        │
│   └─────────────────────────────────────────────┘        │
│                                                            │
│   ┌─────────────────────────────────────────────┐        │
│   │           商用IoTプラットフォーム            │        │
│   ├─────────────────────────────────────────────┤        │
│   │  AWS IoT Core     : $1.00/100万メッセージ   │        │
│   │  Azure IoT Hub    : $25~/月〜               │        │
│   │  Google Cloud IoT : $0.0045/MB              │        │
│   │  ─────────────────────────────────          │        │
│   │  合計: 数千円〜数万円/月                     │        │
│   └─────────────────────────────────────────────┘        │
│                                                            │
│   ※ 商用サービスは管理機能・セキュリティが充実              │
│   ※ 小規模なら自前構築、大規模なら商用サービスを検討        │
│                                                            │
└────────────────────────────────────────────────────────────┘

まとめ

今回作ったシステム

text
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│  📷 カメラ(複数) ─→ 🖥️ 中継機 ─→ ☁️ Oracle Cloud          │
│                                                             │
│  ・カメラ: 色を検知してMQTT送信                              │
│  ・中継機: Mosquitto + ブリッジ                              │
│  ・クラウド: データ蓄積・分析                                │
│                                                             │
└─────────────────────────────────────────────────────────────┘

MQTTを使うメリット(まとめ)

メリット 説明
軽量 電池駆動のセンサーでも使える
リアルタイム 変化があれば即座に通知
スケーラブル 機器を追加しても設定変更が少ない
疎結合 1台壊れても他に影響しない
無料 Mosquittoはオープンソース

関連記事

関連記事