2019年12月22日日曜日

SPRESENSEからLINEに通知を送ろう




はじめに

SPRESENSEに待望のLPWA通信ボード発売されました
そこで早速手に入れてIoT通信してみました
ただサンプル通り実行するだけでは面白くないと思いますから、このボードからLINEに通知を送るところまでの方法について紹介させていただきます

1.SPRESENSE LTE拡張ボードについて

ソニーがSPRESENSE向けに販売するLPWA通信ボードです
LTE-M規格でインターネットに接続することができます


1-1.どこで買えるの?

スイッチサイエンスさんのオンラインショップからすぐ買えます
https://www.switch-science.com/catalog/5999/

SPRESENSE本体もスイッチサイエンスさんで販売されていますので購入の際はお忘れずに
https://www.switch-science.com/catalog/3900/

1-2.インターネット契約は?

この通信ボードには通信契約は付いていませんので別途契約してください
IIJとSORACOMから対応SIMと一緒に契約することができます

今回はIIJmioのIoTサービスを使ってみました
https://www.iijmio.jp/mit/
実はIIJさんのIoT SIMはなんと3Gから4G,LPWAまで使えてしまうという懐の広さ!
いちねんプランならば年払い2400円で月100メガバイトまで通信できます

SORACOMさんはLPWA直結クラウドサービスがとっても魅力!
近日中にこちらも紹介したいと思います

2.開発環境を準備しましょう

SPRESENSEはリアルタイムOSのNuttXもしくはArduinoで開発することができます
今回はお手軽な方法を紹介したいのでArudinoで進めていきます

2-1.ArduinoIDE

公式サイトがとても親切です
https://developer.sony.com/develop/spresense/docs/arduino_set_up_ja.html

まずメインボードだけで次の作業を行っておきましょう
・Arduino IDE のインストール
・USB ドライバのインストール
・Spresense Arduino board package のインストール
・Spresense ブートローダーのインストール
・LED のスケッチを動かしてみる

2-2.ハードウェアの組み立て

写真みたいにLTEボードの上にメインボードを載せます
LTEボードに固定用のピンが添付されていますのでこれを使って固定します

3.LINE通知の登録をしましょう

今回はクラウド代わりにLINE通知を利用させていただきました
お手軽にスマホ通知でデータが送れるのが便利です

3-1.LINE通知登録

次の手順で通知の登録を行います
スマホでLINEにログインした状態でブラウザを開きLINE Notifyを検索します
検索結果のうち以下のリンクを開きましょう

ブラウザでLINE通知のページが開きますのでログインします

スマホサイトには開発者向けの機能がありませんのでPCサイトに切り替えます

アクセストークン発行ボタンを押します

今回はトークン名としてSPRESENCE IoTを登録しました
個人向けなのでお好きな名称がつけてください
通知先は自分自身のみですので1:1を選択します

最後に発行ボタンを押します


発行に成功するとアクセストークンが発行されます
コピーしてメール等でアプリ開発しているパソコンに送信しておきましょう

これでLINE側の設定は完了です

3-2.ルート証明書の取得

SPRESENSEのHTTPSライブラリは接続先のルート証明書を必要とします
次のURLを参考にルート証明書を取得します
必要となるサイトは"https://notify-api.line.me"ですのでURLを置き換えて取得してください

https://developer.sony.com/develop/spresense/docs/arduino_tutorials_ja.html#lte_howtoexport_cert

取得したルート証明書(line-me.pem)はmicroSDカードにCERTSフォルダを作り書き込みます
CERTS/line-me.pem

4.Arudinoスケッチ

今回作ったスケッチを張り付けました
スイッチ入力があるとLINE通知を行うというシンプルなコードです

#include <ArduinoHttpClient.h>
#include <SDHCI.h>
#include <LTE.h>

// APN data
#define LTE_APN       "iijmio.jp" // replace your APN
#define LTE_USER_NAME "mio@iij"   // replace with your username
#define LTE_PASSWORD  "iij"       // replace with your password

// LINE Token
char notify_token[] = "your token";  // Personal Access Token

// URL, path & port (for example: httpbin.org)
char server[] = "notify-api.line.me";
char postPath[] = "/api/notify";
int port = 443; // port 443 is the default for HTTPS

#define ROOTCA_FILE "CERTS/line-me.pem"   // https://notify-api.line.meから取得したPEMファイルを配置

// initialize the library instance
LTE lteAccess;
LTETLSClient tlsClient;
HttpClient client = HttpClient(tlsClient, server, port);
SDClass theSD;

int prevSW;

void setup()
{
  // 初期化
  Serial.begin(115200);
//  while (!Serial) {
//      ; // wait for serial port to connect. Needed for native USB port only
//  }

  Serial.println("Starting App");
  pinMode(LED0, OUTPUT);
  pinMode(PIN_PWM_3, INPUT);
  int prevSW = digitalRead(PIN_PWM_3);

  /* Initialize SD */
  while (!theSD.begin()) {
    ; /* wait until SD card is mounted. */
  }

  // SDカードから証明書ファイルを読み込む
  File rootCertsFile = theSD.open(ROOTCA_FILE, FILE_READ);
  tlsClient.setCACert(rootCertsFile, rootCertsFile.available());
  rootCertsFile.close();
}

void send_line_notify(String message){
  Serial.println("sending Notify");

  // LTE接続開始
  while (true) {
    if (lteAccess.begin() == LTE_SEARCHING) {
      if (lteAccess.attach(LTE_APN, LTE_USER_NAME, LTE_PASSWORD) == LTE_READY) {
        Serial.println("attach succeeded.");
        break;
      }
      Serial.println("An error occurred, shutdown and try again.");
      lteAccess.shutdown();
      sleep(1);
    }
  }

  // 送信データ準備
  String contentType = "application/x-www-form-urlencoded\nAuthorization: Bearer " + String(notify_token);
  String postData = "message="+String(message);

  // HTTPS POST送信
  client.post(postPath, contentType, postData);

  // 応答コードを表示
  int statusCode = client.responseStatusCode();
  String response = client.responseBody();
  Serial.print("Status code: ");
  Serial.println(statusCode);
  Serial.print("Response: ");
  Serial.println(response);

  // LTE接続停止
  Serial.println();
  Serial.println("disconnecting.");
  client.stop();
  lteAccess.shutdown();
}

void loop()
{
  int curSW = digitalRead(PIN_PWM_3);
  if (curSW != prevSW) {
    if (curSW == 1) {
      digitalWrite(LED0, HIGH);
      String message="ドアが開いたよ";
      send_line_notify(message);
      digitalWrite(LED0, LOW);
    }
    prevSW = curSW;
  }
  
  sleep(1);
}

4-1.スケッチの修正

配布コードにはLINEへのアクセストークンがセットされていません
3-1項で手に入れたアクセストークンを次の場所にセットしてください

// LINE Token
char notify_token[] = "your token";  // Personal Access Token

またIIJmio以外のSIMをお使いの方はAPNも変更しておいてください

// APN data
#define LTE_APN       "iijmio.jp" // replace your APN
#define LTE_USER_NAME "mio@iij"   // replace with your username
#define LTE_PASSWORD  "iij"       // replace with your password


5.動作させてみましょう

5-1.ハードウェアの準備

ボード背面にSIMカードとルート証明書の入ったSDカードを装着します

ボード上のピンヘッダに磁力スイッチを接続します
ドア防犯センサーとして売られていたものを付けています
スイッチならば何でもOKです

5-2.プログラムの実行

メインボードとPCを接続しArudinoIDEからスケッチを書き込みます
その後磁力スイッチを引き離すと通知が行われます


Arduinoのシリアルモニターには次のようなログが残っているかと思います
Starting App
sending Notify
attach succeeded.
Status code: 200
Response: {"status":200,"message":"ok"}
disconnecting.

6.まとめ

いかがでしたでしょうか
LPWAのIoTボードもこんなに簡単に使えるようになりました
次回はセンサー入力はSORACOMクラウドについても紹介していきたいと思います


0 件のコメント:

コメントを投稿