AWS EC2: 1マシンで複数台(2~100台)のデバイスを管理する

obnizはうまくシステムを作ることで、1つのプログラムで100台程度のobnizを管理することができます。

たとえば、AWS上のデータベースに、センサの値を記録していくアプリを検討します。すべてのデバイスは等価で、どのデバイスにも同じ用にセンサが接続され、どのデバイスでも同じ挙動をさせたいとします。

この場合のシステム構成は、obniz1台を扱うときと同じです。

この場合、obniz↔EC2間の接続はEC2からobniz側にアクセスしますので、ポートを開けたりして外部からEC2にアクセスできるようにする必要はありません。

クローズドなEC2から、セキュアに保ったまま、obnizと連携を行うことができます。

プログラムの書き方や実行方法でも注意する点があります。

  • アクセストークンを発行する
  • 切断時、再接続時の挙動をきちんと明確にする
  • プロセスが死んだら再起動するようにしましょう

詳細はセキュアでトラブルの少ないプログラムの書き方のページを参照してください。

今回のプログラムではぞれぞれのセンサの値を独立した状態で動かしますので、単純に1台で使うときのプログラムが複数動いていれば良いとなります。1プロセス1obnizにして複数プロセスを起動する方法もありますが、過剰なリソースを費やしてしまうことになりますので、1プロセスですべてのobnizを管理します。100台程度までであれば1プロセス内で管理するのが簡易で管理しやすくなります。

上記を踏まえたサンプルプログラムがこちらです。

const Obniz = require("obniz");
initDb();

const obnizIdList = [
  {obnizId:"obniz_id_1", accessToken: "access_token_1" },
  {obnizId:"obniz_id_2", accessToken: "access_token_2" },
  {obnizId:"obniz_id_3", accessToken: "access_token_3" },
   ...
  {obnizId:"obniz_id_99", accessToken: "access_token_99" },
];

for(const targetObniz of obnizIdList){
  const obnizId = targetObniz.obnizId;
  const accessToken = targetObniz.accessToken;

    // access_tokenを設定します。
    const obniz = new Obniz(obnizId, { access_token: accessToken })
    
    obniz.onconnect = async ()=>{
      // 接続時処理(初期設定など)
      await saveObnizStatusToDb(obnizId, "connected");
      
      const tempSensor = obniz.wired("LM35DZ", { gnd:0 , output:1, vcc:2});
    
        obniz.onloop = async ()=>{
         //繰り返し処理
    
             const temp = await tempSensor.getWait();
             console.log(obnizId, temp);
         await saveTempToDb(obnizId, temp);
      };
    }
    
    
    obniz.onclose = async ()=>{
      // 切断時処理(コールバックのリセットなど)
      await saveObnizStatusToDb(obnizId, "disconnected");
    }

}

function initDb(){

}

async function saveTempToDb(obnizId, temp){

}

async function saveObnizStatusToDb(obnizId, status){

}

実行時は、pm2を使用して下記のように実行します。

npm install pm2 -g
pm2 start ./app.js --name app

永続化していますので、停止もpm2を通じて停止します。

pm2 stop app