ものづくり

GASで作ったAPIにM5StackからPOSTする方法

thumbnail
n-mukineer

M5Stack君の仕事を減らしてあげよう

前回まででできたシステム

前の記事
【簡単IoT】AmbientでM5Stackから送信したCO2濃度をグラフ化する
【簡単IoT】AmbientでM5Stackから送信したCO2濃度をグラフ化する

前回まででできたシステムの概略図を描いてみました。

前回まででできたシステム

今後機能を拡張していくことを考えると、この構成だと若干扱いづらい点があります。

それは、M5Stack君にとって通信相手が二人いることです(よくエンジニア業界ではモノやサービスを擬人化したりするので敬称をつけてみました笑)。

もちろん、通信相手が二人いたとしても動作としては問題はないのですが、今後3つ目、4つ目と通信相手が増えていったときに、M5Stack君を毎回アップデートしていかなければなりません。

M5Stack君は今一人しかいませんが、今後複数のM5Stack君を用意して各部屋に設置した場合、通信相手を増やすたびに全M5Stack君のファームウェアをアップデートする必要が出てきます。

これでは結構面倒くさいですよね…

ということで、M5Stack君の仕事量を減らしてあげたいと思います!(よっ、有能管理職!)

目指すシステム

今回の記事で目指すシステムはこちらのようになります。

M5Stack君はGAS(Google Apps Script)先輩にCO2濃度(と温度)をひたすら投げ続けます。

GAS先輩は受け取ったデータを、決められた手順に従って各通信相手に転送します。

こうすることで、M5Stack君はデータをGAS先輩に送信するという作業に集中できるようになります

よって、今後通信相手を増やしたとしてもGAS先輩の仕事になりますので、M5Stack君のアップデートは不要!

GAS先輩コード一つ書き換えれば、システム全体に反映することができるようになります

  • ハードウェア(M5Stack)にはできるだけ複雑な処理をさせない!
  • ソフトウェア(GAS)に複雑な処理を集約しておき、修正しやすくしておく!

GASプロジェクトをWebアプリとしてデプロイする

GASのプロジェクト作成方法は以下の記事で紹介していますので、その手順に従ってプロジェクトを作成しておきましょう。

あわせて読みたい
【無料】GASを使い始めるための3ステップ【簡単】
【無料】GASを使い始めるための3ステップ【簡単】

POST用のAPIを作成する

POST用のAPIを立てるのはめちゃめちゃ簡単です。

「エディタ」画面に行き、「doPost」という関数を作成します。これはM5Stackからデータを飛ばす際に使用するAPIとなります。

ちなみに、GASはJavaScriptをベースとしています。

function doPost(e) {
  const body = JSON.parse(e.postData.contents);
  const co2 = body.co2;
  const temp = body.temp;
  console.log(`CO2濃度: ${co2}ppm`);
  console.log(`温度:${temp}℃`);
}

デプロイする(本番環境に反映する)

「デプロイ」ボタンを押し、「新しいデプロイ」を選択します。

デプロイタイプは「ウェブアプリ」とします。

説明文を適当に入力、「次のユーザーとして実行」は「自分」、「アクセスできるユーザー」は「全員」とします。

「デプロイ」ボタンを押します。

ウェブアプリのURLが表示されるので必ず「コピー」しておきましょう。

えぬ
えぬ

これでAPIが公開されました!

今回はAPIキーなど何もかけていないのでリンクを知っている人であればだれでもアクセスできるようになっています。むやみにURLは公開しないようにしましょう!

ちなみに、2回目以降のデプロイの場合は少し手順が異なります。以下の記事を参照ください。

あわせて読みたい
GASからLINE Notifyを使ってLINE通知する方法
GASからLINE Notifyを使ってLINE通知する方法

M5StackからPOSTしてみる

今回は「ArduinoJson.h」というライブラリを追加します。

今回のプログラムのポイントは下記です。これまでのLINE NotifyやAmbientにデータを送る部分はGAS側に移行するため削除してあります。

  1. 「GAS_API_URL」という変数にコピーしておいたAPIのURLを設定する
  2. 「post_co2」という関数を作る
  3. CO2濃度を測定した直後に「post_co2」を実行する
#include <M5Stack.h>
#include <MHZ19_uart.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>


#define ARDUINO_ARCH_ESP32
#define PERIOD 60
#define THPPM 1000

WiFiClient client;
const char* ssid = "WiFiのSSID";
const char* password = "WiFiのパスワード";
const char* GAS_API_URL = "GASのAPI URLを入力(デプロイ時に表示されたもの)";

const int rx_pin = 16;	//Serial rx pin no
const int tx_pin = 17;	//Serial tx pin no

MHZ19_uart mhz19;

/*----------------------------------------------------------
    MH-Z19 CO2 sensor  setup
  ----------------------------------------------------------*/
void setup() {
  M5.begin();
  delay(100);
  Serial.println("Hello");
  mhz19.begin(rx_pin, tx_pin);
  mhz19.setAutoCalibration(false);

  int  i = 500;
  WiFi.begin(ssid, password);  //  Wi-Fi APに接続
  while (WiFi.status() != WL_CONNECTED) {  //  Wi-Fi AP接続待ち
      M5.Lcd.setTextSize(3);
      M5.Lcd.setCursor(20,120);
      M5.Lcd.printf("Connecting...");
      i--;
      if(i<0){
        delay(250);
        M5.Power.reset();
      }
  }

  M5.Lcd.setTextSize(3);
  M5.Lcd.setCursor(20,120);
  M5.Lcd.printf("Connected!\n");
  M5.Lcd.clear();
  M5.Lcd.setBrightness(50);
}

/*----------------------------------------------------------
    MH-Z19 CO2 sensor  loop
  ----------------------------------------------------------*/
void loop() {
  unsigned long startt = millis(); // loopの開始時刻を記録
  int co2ppm = mhz19.getPPM();
  int temp = mhz19.getTemperature();
  Serial.print("co2: "); Serial.println(co2ppm);
  Serial.print("temp: "); Serial.println(temp);
  M5.Lcd.clear();
  M5.Lcd.setTextSize(10);
  M5.Lcd.setCursor(20,120);
  M5.Lcd.printf("%dppm\n", (int)co2ppm);
  M5.Lcd.setTextSize(2);
  M5.Lcd.setCursor(20,0);
  M5.Lcd.printf("RSSI:%d dBm", WiFi.RSSI());
  post_co2(String(co2ppm), String(temp));
  delay(PERIOD*1000);
  wifi_lan_check();
}

/*
 * GASにPOSTする
 *
 */
void post_co2(String co2, String temp) {
  StaticJsonDocument<200> doc;
  doc["co2"] = co2;
  doc["temp"] = temp;
  char json_string[255];
  serializeJson(doc, json_string, sizeof(json_string));
  Serial.printf(json_string);

  HTTPClient http;
  http.begin(GAS_API_URL);
  http.addHeader("Content-Type", "application/json");
  int status_code = http.POST((uint8_t *)json_string, strlen(json_string));
  if (status_code == 200) {
    Serial.printf("[POST] end to server");
  } else {
    Serial.printf("[POST]failed to send to server");
  }
}

/*
 * void wifi_lan_check()
 *   WiFi Lan の監視をします。
 *   WiFi.status() で判断するよりも、ping で応答をチェックした方が、早いかも。
 */
void wifi_lan_check(){
  int i;
  if(WiFi.status() != WL_CONNECTED){
    M5.Lcd.clear();
    M5.Lcd.setTextSize(3);
    M5.Lcd.setCursor(20,120);
    M5.Lcd.printf("Connecting...");
    WiFi.disconnect();
    delay(50);
    WiFi.begin(ssid, password);
    i=50;
    while (WiFi.status() != WL_CONNECTED) {
      delay(250);
      i--;
      if(i<0){
        delay(250);
        M5.Power.reset();
      }
    }
  }
}

動作確認

M5Stackに書き込んで、GCPのログを見てみましょう。

GCPのロギングページにアクセスします。

ログエクスプローラという画面が開くので確認します

CO2と温度が受信できています!やったね!

えぬ
えぬ

これでGAS側でデータを受け取ることができることを確認できました!

このデータを受信できていれば、「1000ppmを超えていたらLINE Notifyに通知」したり、「Ambientにデータを転送」したりすることも自由にできるので、次回はそのあたりをやっていきます!

GASを始めて使う方はこちらもお読みください
【無料】GASを使い始めるための3ステップ【簡単】
【無料】GASを使い始めるための3ステップ【簡単】

まとめ

GASからLINE NotifyやAmbientにデータを飛ばす部分は次回にしようと思います。

今回のまとめ

  • Google Apps Scriptを使って簡単にWebアプリケーションが作れる。
  • M5Stackから自作のWebアプリケーションにPOSTすることができる。
  • M5Stackの仕事を減らし、Webアプリケーション側に複雑な処理を任せるようにすることで拡張しやすくなる。
次の記事
GASからLINE Notifyを使ってLINE通知する方法
GASからLINE Notifyを使ってLINE通知する方法
前の記事
【簡単IoT】AmbientでM5Stackから送信したCO2濃度をグラフ化する
【簡単IoT】AmbientでM5Stackから送信したCO2濃度をグラフ化する
シリーズを最初から読む
【超簡単電子工作】M5StackとCO2センサで自室のCO2濃度を測定してみた!
【超簡単電子工作】M5StackとCO2センサで自室のCO2濃度を測定してみた!

このブログを書いている人
えぬ
えぬ
N日後にムキムキになるエンジニア
WebアプリエンジニアとしてIoTシステムを開発中。30代折り返し。 趣味(モノづくり、プログラミング、筋トレ)や子育てのことを主に記事にします。 TOEIC: 900点/第一級陸上無線技術士/第3種電気主任技術者/技術士一次試験合格/基本情報技術者/第2種電気工事士/デジタル技術検定2級(情報・制御)
記事URLをコピーしました