IoTプロトコル

MQTT-SN

センサーネット向けの軽量MQTT(UDP対応)。

概要

MQTT-SN(MQTT for Sensor Networks)は、センサーネットワークや制約のある組み込みデバイス向けに設計された、MQTTプロトコルの軽量バリアントです。2013年にIBMのAndy Stanfordークラーク氏らによって仕様が策定され、もともとTCP/IPを前提としていたMQTTの思想を、UDPや非IP系の無線通信媒体にも適用できるよう拡張したものです。

通常のMQTTはTCPコネクションを張ることを前提としており、接続維持のためのオーバーヘッドがあります。一方MQTT-SNはUDPを基盤としているため、コネクションレスな通信が可能であり、電力消費の極端に厳しい超小型センサーデバイスや、ZigBee・BLE・LoRaのような非IP通信プロトコル上でも動作させることができます。

IoT機器の多様化が進む中、MQTT-SNはゲートウェイ(MQTT-SNゲートウェイ)を介してバックエンドのMQTTブローカーと連携することで、エッジからクラウドまでのシームレスなデータパイプラインを構成する重要な役割を担っています。


歴史・背景

MQTTは1999年にIBMとEurotech社が石油パイプライン監視向けに開発したプロトコルです。2014年にOASIS標準として正式採択され、IoTの普及とともに広まりましたが、その設計はTCPを前提としており、電池駆動の超小型センサーや非IP通信にはオーバーヘッドが大きい課題がありました。

MQTT-SNはこの課題を解決するため、以下の背景から生まれました。

  • ZigBeeやIEEE 802.15.4などの非IP無線網への対応需要:これらの通信規格ではIPスタック自体が省略されることが多く、TCPが使えない環境が存在していた。
  • バッテリー駆動センサーの普及:コイン電池や太陽電池で数年動作させる要件が増え、接続維持コストが問題になっていた。
  • 工場・農業・スマートシティ向けの大規模センサー展開:数千〜数万ノードのスケールでは、TCP接続ごとのサーバーリソース消費が無視できなかった。

MQTT-SN 1.2仕様は2013年に公開され、現在はOASISのMQTT技術委員会が管理しています。2023年頃にはMQTT-SN 2.0の草案議論も行われており、MQTT 5.0との整合性強化が進んでいます。


技術仕様

プロトコル構造

MQTT-SNはMQTTと同様のパブリッシュ/サブスクライブモデルを採用しますが、トランスポート層の違いに加え、いくつかの独自機能が定義されています。

項目MQTTMQTT-SN
トランスポートTCPUDP / ZigBee / BLE等
トピック表現文字列(可変長)2バイトのトピックID
接続モデル常時接続スリープ対応(断続接続)
QoSレベル0, 1, 20, 1, 2, -1(特殊)
ゲートウェイ不要(直接)必要(MQTT-SNゲートウェイ)

トピックID

通常のMQTTではトピックをsensors/room1/temperatureのような文字列で表現しますが、MQTT-SNでは2バイトのトピックIDに事前登録・マッピングすることでパケットサイズを大幅に削減します。

REGISTER  → クライアントがトピック文字列をブローカーに登録
REGACK    → ブローカーがトピックIDを割り当てて返す
PUBLISH   → 以降はトピックIDのみでPublishが可能

QoS -1(マイナス1)

MQTT-SNには通常のMQTTにない特殊なQoSレベルとしてQoS -1が存在します。これは接続確立なしに単発でPublishするモードであり、極限まで通信を減らしたい超省電力デバイスに向いています。確認応答なしの完全な「打ちっぱなし」送信です。

スリープ対応

MQTT-SNはデバイスのスリープ状態を明示的に扱うメッセージタイプを持っています。

DISCONNECT(duration指定あり) → スリープ開始通知
PINGREQ(ClientID付き)       → 起床通知 & バッファメッセージ取得

ゲートウェイはデバイスがスリープ中に届いたメッセージをバッファリングし、起床時にまとめて配信します。

ゲートウェイ構成

[センサーノード] ─── ZigBee/BLE/UDP ───> [MQTT-SNゲートウェイ]

                                              TCP/MQTT

                                          [MQTTブローカー]
                                          (Mosquitto, EMQX等)

ゲートウェイには2種類あります。

  • 透過型ゲートウェイ(Transparent Gateway):各センサーに1対1でMQTT接続を張る。スケールに難あり。
  • 集約型ゲートウェイ(Aggregating Gateway):複数センサーをまとめて1つのMQTT接続で処理。省リソース。

動作原理

接続シーケンス

Client                    MQTT-SN GW              MQTT Broker
  |                           |                       |
  |--- SEARCHGW ------------->|                       |
  |<-- GWINFO ----------------|                       |
  |--- CONNECT -------------->|--- CONNECT ---------->|
  |                           |<-- CONNACK -----------|
  |<-- CONNACK ----------------|                      |
  |--- REGISTER ------------->|                       |
  |<-- REGACK ----------------|  (topic "temp" → ID=1)|
  |--- PUBLISH(ID=1, val=25)->|--- PUBLISH("temp",25)->|
  |<-- PUBACK ----------------|<-- PUBACK ------------|

ディスカバリ

MQTT-SNはUDPブロードキャストを使ったゲートウェイ自動発見機能(SEARCHGW / GWINFO)を持っており、センサーデバイスが事前にゲートウェイアドレスを知らなくても動作できます。これはZigBeeネットワーク上での動的構成に特に有用です。

Will機能

通常のMQTTと同様に、接続確立時にWill(遺言)メッセージを登録できます。接続が突然切断された場合に自動的にPublishされます。センサーの障害検知に使われます。


用途・ユースケース

農業IoT(スマート農業)

広大な農地に設置された土壌センサー、温湿度センサーなどがZigBee網でゲートウェイに集約し、MQTT-SNでデータ送信します。コイン電池で年単位の動作が求められる環境では、スリープ対応のMQTT-SNが不可欠です。

// 疑似コード: 30分ごとに起床してPublishする例
void sensor_main_loop(void) {
    mqtt_sn_connect(gateway_addr, "soil_sensor_01");
    
    uint16_t topic_id = mqtt_sn_register("farm/field1/soil_moisture");
    
    float moisture = read_soil_sensor();
    char payload[16];
    snprintf(payload, sizeof(payload), "%.1f", moisture);
    
    mqtt_sn_publish(topic_id, payload, QOS_1);
    
    // 30分スリープ
    mqtt_sn_disconnect(1800);  // duration = 1800秒
    enter_deep_sleep(1800);
}

工場設備監視

生産ラインの各設備にMQTT-SNクライアントを実装し、振動センサー・電流センサーのデータをリアルタイム収集します。ZigBee等を使えば既存設備に電線を引き回す必要がなく、後付けでの展開が容易です。

スマートメーター

電力・ガス・水道のスマートメーターは、UDP上のMQTT-SNでデータを収集センターに送信する実装事例があります。計量データは1日数回程度の送信でよく、QoS 1での確認応答で信頼性を担保します。

ビル管理(BAS: Building Automation System)

複数フロアにまたがる環境センサー網をMQTT-SNで構成し、中央のBASサーバーがデータ収集・制御を行います。BLEメッシュ上でMQTT-SNを動かす実装も増えています。


実装・開発のポイント

主要実装ライブラリ

ライブラリ言語特徴
Eclipse Paho MQTT-SNC組み込み向け、軽量
mqtt-sn-toolsCコマンドラインツール付き
Mosquitto MQTT-SN GWC++ゲートウェイとしても機能
RSMBCIBMの参照実装

Mosquittoとの連携

# mqtt-sn-pubコマンドでテスト送信
mqtt-sn-pub -h 192.168.1.10 -p 1884 \
  -t "sensors/temp" -m "25.3" -q 1

# Mosquitto側でブリッジ設定(mosquitto.conf)
listener 1884
protocol mqtt

ゲートウェイ実装の注意点

// トピックIDマッピングテーブル管理
typedef struct {
    char topic_str[64];
    uint16_t topic_id;
    uint16_t client_id;
} TopicMapping;

// ゲートウェイはクライアントごとにマッピングを管理する必要がある
// メモリ制約のある環境では、LRUキャッシュが有効

UDP通信の信頼性確保

UDPはパケットロスの可能性があります。QoS 1/2を使い、タイムアウトと再送を実装します。

#define MQTT_SN_RETRANSMIT_TIMEOUT_MS  3000
#define MQTT_SN_MAX_RETRIES            3

int mqtt_sn_publish_with_retry(uint16_t topic_id, 
                                const char *payload, 
                                uint8_t qos) {
    for (int i = 0; i < MQTT_SN_MAX_RETRIES; i++) {
        if (send_publish(topic_id, payload, qos) == 0) {
            if (wait_puback(MQTT_SN_RETRANSMIT_TIMEOUT_MS) == 0) {
                return 0;  // 成功
            }
        }
    }
    return -1;  // 失敗
}

セキュリティの考慮

MQTT-SN自体は暗号化機能を持たないため、以下の対策が必要です。

  • DTLSを使ったUDP通信の暗号化
  • ゲートウェイでのデバイス認証
  • MQTTブローカー側でのTLS終端

他技術との比較

項目MQTT-SNMQTTCoAPZigbee直接
トランスポートUDPTCPUDP独自
最小パケット2バイト2バイト4バイト
Pub/Sub△(拡張)
スリープ対応○(ネイティブ)△(Keep Alive)
ゲートウェイ要否必要不要不要必要
普及度

CoAPはREST的なアクセスモデルを持ち、リクエスト/レスポンス型の用途に向いています。MQTT-SNはPub/Subモデルを維持しているため、既存のMQTTエコシステムとの統合が容易です。

MQTTとの移行も容易で、ゲートウェイを設けるだけでデバイス側のコードをほぼ変えずにバックエンドをそのまま流用できる点が大きなアドバンテージです。LoRaWANLPWAとの組み合わせでも使われており、さまざまなレイヤーで活用されています。

関連用語

参考リンク