LoRaWANで実現する監視カメラの死活監視

LoRaWANで実現する監視カメラの死活監視

LoRaWANで実現する監視カメラの死活監視

はじめに

街中で見かける監視カメラ。防犯や記録のために重要な役割を果たしていますが、古い機種の多くはネットワークに常時接続されておらず、正常に動作しているかどうかの確認が課題となっています。本記事では、LoRaWAN を活用して既設の監視カメラの死活監視を実現する方法をご紹介します。

背景

監視カメラシステムにおいて、カメラの正常動作の確認は極めて重要です。しかし、以下のような課題が存在します:

  • 古い機種は遠隔監視機能を持っていない
  • 定期的な現地確認が必要
  • 異常が発生してから発見されるまでのタイムラグ
  • カメラが停止していた場合、重要な映像が記録されていない可能性

実際に、市町村などから業務委託を受けた運用事業者から、人手不足もあり定期的な現地確認は非現実的であるという声を聞きます。

システム構成

今回は以下の機器を使用して、LoRaWAN ベースの死活監視システムを構築します:

使用機器

  • Arduino MKR WAN 1310(LoRaWAN 通信モジュール搭載)
  • MKR WAN ETH HAT(有線 LAN インターフェース)
  • オフィス内ルータ(既設の監視カメラを想定、有線 LAN 接続のみ対応という前提)

MKRWAN1310とHAT

アーキテクチャ概要

  1. Arduino + ETH HAT を監視カメラに有線 LAN 接続
  2. 定期的に TCP 接続による死活監視を実施(多くの監視カメラは HTTP ポート 80 が開いています)
  3. 監視結果を LoRaWAN 経由でサーバーに送信
  4. 異常検知時にアラート通知(今回は、ここは割愛)

実装詳細

1. ハードウェア接続

[ルータ] ←有線LAN→ [MKR WAN ETH HAT] ←内部接続→ [MKR WAN 1310] ←LoRaWAN→ [ゲートウェイ]

2. Arduino 実装コード

#include <MKRWAN.h>
#include <Ethernet.h>
#include <SPI.h>

LoRaModem modem;

// LoRaWAN設定
const char *appEui = "YOUR_APP_EUI";
const char *appKey = "YOUR_APP_KEY";

// カメラのIPアドレスとポート
IPAddress cameraIP(192, 168, xxx, xxx);
int cameraPort = 80;  // 多くのカメラはHTTPポート80を使用

// Ethernet設定
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
EthernetClient client;

void setup() {
  Serial.begin(115200);
  while (!Serial) {
    ; // シリアルポートの準備待ち
  }

  // LoRaWANの初期化
  if (!modem.begin(AS923)) {
    Serial.println("LoRaWAN初期化失敗");
    while (1) {}
  }

  // ネットワークへの接続
  int connected = modem.joinOTAA(appEui, appKey);
  if (!connected) {
    Serial.println("LoRaWAN接続失敗");
    while (1) {}
  }

  // Ethernetの初期化
  Ethernet.begin(mac);
  delay(1000); // ネットワーク安定化待ち
}

bool checkCamera() {
  // カメラへのTCP接続を試行
  if (client.connect(cameraIP, cameraPort)) {
    // 接続成功
    client.stop();
    return true;
  }
  return false;
}

void sendStatus(bool isActive) {
  // ステータスパケットの作成
  uint8_t payload[3];
  payload[0] = isActive ? 1 : 0;  // カメラの状態
  payload[1] = Ethernet.linkStatus(); // Ethernet接続状態
  payload[2] = isActive ? 200 : 500;  // ステータスコード

  // LoRaWANでデータ送信
  modem.beginPacket();
  modem.write(payload, sizeof(payload));
  int err = modem.endPacket(true);  // true = confirmed uplink

  if (err > 0) {
    Serial.println("送信成功");
  } else {
    Serial.println("送信失敗");
  }
}

void loop() {
  bool cameraActive = checkCamera();
  Serial.print("カメラ状態: ");
  Serial.println(cameraActive ? "Active" : "Inactive");

  sendStatus(cameraActive);

  // 30分待機
  delay(1800000);
}

3. 死活監視ロジック

監視カメラの状態確認は以下のステップで実行されます:

  1. 30 分ごとに TCP 接続による疎通確認
  2. 接続結果の状態をチェック
    • 成功:カメラが正常に動作中
    • 失敗:カメラに問題発生の可能性
  3. 結果を LoRaWAN 経由で送信
    • 1 バイト目:カメラの状態(0=異常、1=正常)
    • 2 バイト目:Ethernet 接続状態
    • 3 バイト目:ステータスコード

4. The Things Stack でのデコード関数

function Decoder(bytes, port) {
  let ethStatus;
  switch (bytes[1]) {
    case 0:
      ethStatus = "Unknown";
      break;
    case 1:
      ethStatus = "LinkON";
      break;
    case 2:
      ethStatus = "LinkOFF";
      break;
    default:
      ethStatus = "Error";
  }

  return {
    camera_status: bytes[0] === 1 ? "ACTIVE" : "INACTIVE",
    ethernet_status: ethStatus,
    status_code: bytes[2],
    timestamp: new Date().toISOString(),
  };
}

無事に、TTS 上に Uplink が届き、デコードされています。

TTS上でのデコード結果


運用時の注意点

1. 電源の確保

  • Arduino 用の電源はカメラの電源系統から供給
  • 停電対策として UPS との連携も検討

2. ネットワーク設定

  • カメラと Arduino は同一セグメントに配置
  • DHCP ではなく固定 IP を推奨
  • カメラの HTTP ポートアクセス許可の確認

3. アラート設定

  • 2 回連続で異常を検知した場合にアラート
  • アラートは上位アプリで実装し、メール、Slack 等で通知
  • 現地確認が必要な場合の連絡フロー整備

4. 改善ポイント

  • カメラ機種ごとの最適なポート番号の選定
  • 複数のポートでの死活監視
  • HTTP レスポンスの内容確認による詳細な状態把握

実運用での効果

本システムを導入することで、以下のような効果が得られます:

  1. 監視カメラの異常の早期発見
  2. 定期的な現地確認の工数削減
  3. 記録漏れリスクの低減
  4. 保守運用コストの最適化

まとめ

TCP 接続による死活監視を実装することで、より実用的なシステムを構築することができました。この方式には以下のような利点があります:

  • 多くのファイアウォールでも TCP 80 番ポートは許可されている
  • カメラの Web 管理インターフェースの存在確認も兼ねられる
  • より詳細な状態確認の拡張が容易

また、本実装は以下のような機器の監視にも応用可能です:

  • デジタルサイネージ
  • 自動販売機
  • 工場設備
  • 屋外設置センサー

参考情報

  1. Arduino MKR WAN 1310 公式ドキュメント
  2. The Things Network の AS923 情報
  3. Arduino Ethernet ライブラリ

担当紹介

  • ブログ全体の構成と執筆・コーディング担当: Claude 3.5 Sonnet
  • ネタ提供、動作確認・コード修正、文書の最終微調整&文責: 私