実装詳細とアーキテクチャ要件
Role Aが担当する「AI推論&エッジ連携モジュール」は、システムの「目と脳」を担う最も負荷の高いコンポーネントです。単にライブラリを繋ぎ合わせるだけでは、「VPNのネットワーク瞬断によるプロセス停止」や「AI推論・API通信のI/O待ちによるカメラ映像の遅延(バッファ詰まり)」といった致命的な障害が必ず発生します。
また、Role AはIAM管理者権限を保有しているため、EC2のプロビジョニングから必要な権限(IAMロール)の付与までを自律的に行い、他ロールとの依存関係を最小化します。
目的: アプリケーション実行基盤を構築し、AWSリソースへのアクセスを可能にする。
aws configure コマンドを実行し、手順1で取得したアクセスキーとシークレットキーを設定する。
【重要】技術的課題と根本解決:
プログラムからAWSリソース(IoT Core等)にアクセスするにはアクセスキーが必須です。しかし、ソースコード内にキーを直接書き込む(ハードコードする)ことは厳禁です。必ず aws configure を用いて ~/.aws/credentials に安全に保存し、AWS SDK (boto3等) に自動で読み込ませるセキュアな実装を徹底してください。
目的: EC2からローカルネットワーク内のカメラ映像をリアルタイムに取得する。
cv2.VideoCapture) を用いてRTSPストリームを取得する。
【重要】技術的課題と根本解決:
VPN経由ではパケット遅延が発生しやすく、標準の読み込みでは古いフレームがバッファに溜まり、推論が数秒〜数十秒遅延します。これを防ぐため、「カメラ読み込み専用のバックグラウンドスレッド」を作成し、常に最新の1フレームのみを保持し、古いフレームは即座に破棄(ドロップ)する設計を必ず実装してください。
目的: 映像から子供の危険状態を判定する。ディスク容量最適化のため、軽量なYOLOv8 Poseモデル1つで全判定を完結させる。
yolov8n-pose.pt を用い、「人物のバウンディングボックスの縦横比(体が横倒しになっていないか)」「キーポイントの座標比較(頭部と足首のY座標逆転)」「顔のキーポイント消失(うつ伏せ)」を数学的に判定する。
【重要】技術的課題と根本解決:
EC2(CPU環境)では推論に時間がかかる場合があります。毎フレーム推論すると処理が追いつかないため、「Nフレームに1回だけ推論を実行する(フレームスキップ)」ロジックを組み込み、FPSの低下を防いでください。
目的: センサーデータの取得と、危険検知時のリアルタイムアラート送信を行う。
【重要】技術的課題と根本解決:
VPNの鍵更新などでネットワークが瞬断すると、MQTTクライアントがクラッシュします。必ずSDKの「非同期イベントループ」と「自動再接続機能」を利用し、オフライン時はメッセージをキューイング(QoS 1)する堅牢な接続クラスを設計してください。
目的: 危険検知時の状況を、画像付きで保護者のWebexに通知する。
requests ライブラリを用いて、Webex Messaging APIへマルチパートデータとしてPOST送信する。
【重要】技術的課題と根本解決:
ディスクへの画像保存(cv2.imwrite等)は絶対に禁止します。 EC2のEBSボリュームへの書き込みはI/O待ちを発生させ、システム全体が数秒間フリーズ(バッファ詰まり)する致命的な原因となります。
必ず「メモリ上で直接JPEGエンコード(cv2.imencode('.jpg', frame))」し、そのバイナリデータを「別スレッド(ThreadPoolExecutor等)」で送信して、メインの推論ループを絶対にブロックしない非同期送信を実装してください。
目的: 蓄積されたデータから、普段行かない場所へのアクセスなど潜在的リスクを抽出する。
boto3 を用いて、Role Bが構築したDynamoDBから過去の滞在座標と時間帯データを定期的に(例: 1日1回)取得する。scikit-learn の IsolationForest を用いてデータをクラスタリングし、異常スコアを算出する。boto3 を用いてDynamoDBへ直接書き込み(保存し)、Role Bの履歴取得API経由でRole Cのダッシュボードにサジェストする(WebSocketによるリアルタイム通知は不要)。
【重要】技術的課題と根本解決:
リアルタイムのAI推論ループと同じスレッドで機械学習のバッチ処理を実行すると、カメラ映像の処理が完全に停止します。必ず cron 等を用いた別プロセス、または完全に独立した非同期タスクとして実行し、メインの監視システムに一切の負荷をかけない設計にしてください。
【重要】AWS IoT Coreへ送信するJSONスキーマが以下に確定しました。 Merakiの生データやYOLOの配列をそのまま送るのではなく、必ずEC2上で以下の形式に整形(パース)してからPublishしてください。
// パターン1: AI推論アラート
{
"device_id": "mv_camera_01", "room_id": "living_room", "timestamp": 1723307400000, "event_type": "ai_hazard",
"details": { "hazard_type": "fall", "x": 640, "y": 480, "confidence": 0.85 }
}
// パターン2: Merakiセンサーアラート
{
"device_id": "mt20_door_01", "room_id": "living_room", "timestamp": 1723307405000, "event_type": "sensor_alert",
"details": { "sensor_type": "door", "status": "open", "battery_level": 95 }
}
// パターン3: 複合アラート
{
"device_id": "system_logic_01", "room_id": "living_room", "timestamp": 1723307410000, "event_type": "complex_alert",
"details": { "alert_type": "night_wandering", "trigger_device": "mt20_door_01", "lux": 5 }
}
// パターン4: 行動パターン解析結果
{
"device_id": "system_logic_01", "room_id": "living_room", "timestamp": 1723307420000, "event_type": "risk_suggestion",
"details": { "risk_level": "high", "suggested_area": { "x": 100, "y": 200, "radius": 50 }, "reason": "unusual_access_time" }
}