AWS Lambda: 1関数で複数台のobnizを管理する

定期的な実行のときにサーバーレスは便利ですが、obnizとの接続など、ネットワークの応答待ち時間があり、金額的にもったいない部分があります。

それを解消するために、複数のobnizを1回のlambda関数で管理しましょう。

前提の条件は1台のときと同じです

  • 起動がかぶらないようにする
  • 制限時間を考慮する
  • 接続できない場合を考慮する

詳細はAWS Lambda: 1関数で1台のobnizを管理する を見てください

プログラムの書き方が少々変わります。

1つのobnizに対する命令関数をoneTaskとして作成し、その関数内で処理が完結するようにしています。それをobnizの数分だけ実行し、 Promise.all ですべての処理が終わるまで待機します。

const Obniz = require("obniz");

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"},
];

// 1つのobnizに対する
async function oneTask(targetObniz) {
  const obniz = new Obniz(targetObniz.obnizId, {auto_connect: false, access_token: targetObniz.accessToken});

  try {
    const connected = await obniz.connectWait({timeout: 3});
    if (!connected) {
      return new Error("obniz " + targetObniz.obnizId + " is not online");
    }

    const tempSensor = obniz.wired("LM35DZ", {gnd: 0, output: 1, vcc: 2});
    const temp = await tempSensor.getWait();
    obniz.close();
  } catch (e) {
    return e;
  }
  return null;

}

exports.handler = async (event) => {

  let tasks = [];
  for (const targetObniz of obnizIdList) {
    tasks.push(oneTask(targetObniz));
  }

  let results = await Promise.all(tasks);

  for (const result of results) {
    if (result) {
      const response = {
        statusCode: 500,
        body: JSON.stringify({status: "error", error: result}),
      };
    }

  }
  const response = {
    statusCode: 200,
    body: JSON.stringify({status: "success"}),
  };

  return response;
};