M5StackでLINE Beaconを作成する手順を久々にまとめてみる 2020年9月版


最近LINE Beaconを触ってみているので久々に少しまとめてみます。

調べると出てくる記事はもう結構古いと思うので改めて自分用にも。

必要なソフトウェアなどは省略せずに書いてるつもりですが、完全初心者向けハンズオン記事とかではないのでご留意下さい。

何よりも登録のこのURLをいつも忘れるので記録です。(後述)

> https://manager.line.biz/beacon/register

## LINE Beaconとは

LINEが提供するLINEと連携できるビーコンの仕組みです。詳細は参考記事へ。

> 参考: [LINE ThingsやLINE Beaconの立ち位置おさらいなど #linedc #linethings](https://qiita.com/n0bisuke/items/1f552f3508fe8cf22759)

選択肢として公式デバイスもありますが、今回はLINE Simple Beaconを利用します。

## M5Stack

M5Atom Liteが安いかつコンパクトかつケース個人的にオススメです。1000円で買えます。

> https://www.switch-science.com/catalog/6262/ 

## 必要な要素

ざっくり言うとサーバーサイド実装+マイコンボード実装が必要です。

* STEP0. [下準備] LINE BOT作成
	* LINE BeaconはLINE BOTに紐づく仕組みです。LINE BOT開発が必要になります。
	* サーバーサイドの言語ならなんでもOKですが、ここではNode.jsで進めます。
* STEP1. マイコンボードのLINE Beacon化
	* LINE Simple Beaconを利用してESP32などのマイコンボードに書き込みます。
* STEP2. LINE BOT開発
	* 作成したLINE BOTをLINE Beaconのイベントに対応させます

ちなみに筆者環境は、macOS Catalina / Arduino IDE 1.8.12 / Node.js v14.10.1です

## 実際に作ってみる

### STEP0. [下準備] LINE BOTを作成

Node.jsでLINE BOTを作成します。Node.jsのインストールなどは事前に済ませておきましょう。

[1時間でLINE BOTを作るハンズオン](https://qiita.com/n0bisuke/items/ceaa09ef8898bee8369d)を元にLINE BOTを作成しましょう。

### STEP1. マイコンボードのLINE Beacon化

この記事では[M5Atom Lite](https://www.switch-science.com/catalog/6262/)を利用しますが、M5Atom MatrixやM5Stack Basic、M5Core2などでも試せました。

#### 1.1 マイコンボードへの書き込みまで

* Arduino IDEの準備

Arduino IDEで開発をしていきます。準備しましょう。

https://www.arduino.cc

* Arduino IDEにESP32ボードライブラリの追加

Arduino IDEでESP32系のボードの書き込みが出来るようにします。

Arduino IDEの設定から、追加のボードマネージャのURLに以下のURLを追加

```
https://dl.espressif.com/dl/package_esp32_index.json
```

`ボードマネージャ`でESP32と検索し,[espressif/arduino-esp32](https://github.com/espressif/arduino-esp32)をインストール

> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/f9498995-30c5-05e6-4b2b-57d6705af55d.png" width="400px">

* Arduino IDEにLINE Beacon用ライブラリのGreen Beaconを追加

`ライブラリマネージャ（ライブラリを管理）`でGreen Beaconと検索し[green-beacon-esp32](https://github.com/ukkz/green-beacon-esp32)をインストール

* シンプルなコードを書き込む

PCとマイコンボードをケーブルで接続して書き込みを行います。

```hello.ino
void setup() {
  Serial.begin(115200);
  Serial.println("start");
}

void loop() {
}
```

書き込み時の設定はこんな感じ。

> ![スクリーンショット 2020-09-16 11.00.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/d6e4e852-390d-9c99-ecf6-858372ecaa60.png "スクリーンショット 2020-09-16 11.00.31.png")

M5Atom系の場合、ボードはESP32 Pico Kitを選択、Upload Speedを115200に変更しましょう。

Upload Speedをそのままにすると`A fatal error occurred: Timed out waiting for packet header`というエラーになります。

...ちなみに同じエラーでもこんな事象(↓)が発生することもあるので気をつけましょう。

> こんな事象: [M5Stack Core2にArudino IDEで書き込みと発生したまさかのエラー #iotlt](https://qiita.com/n0bisuke/items/f0910445d1563bc88214)


#### 1.2 LINE Simple BeaconのID発行

LINE Simple BeaconのID発行のページへ行きます。このページのURLがいつもどこにあるか分からなくなる......

> https://manager.line.biz/beacon/register

`line simple BeaconのハードウェアIDを発行`を選択 -> 利用するLINE Botのアカウントを選択 -> ハードウェアIDを発行

と進んでIDを発行します。

> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/6f8e8703-a0d3-544f-ea56-3da113a4d3bc.png" width="400px">

`123456abcz`のような10桁のIDが発行されると思います。

#### 1.3 マイコンボードへ書き込む

以下のようなコードで実装できます。

```beacon.ino
#include "GreenBeacon.h"

void setup() {
  GreenBeacon beacon = GreenBeacon("123456abcz"); // 取得したIDを指定
  beacon.start("Hello!");
}

void loop() {}
```

これを書き込みます。

無事に書き込まれたらマイコンボードがLINE Beacon化してビーコン電波を発信してくれます。

### STEP2. LINE BOT開発

[1時間でLINE BOTを作るハンズオン](https://qiita.com/n0bisuke/items/ceaa09ef8898bee8369d)の記事を元に作ったコードのhandleEventの関数を差し替えます。

```js
//省略

async function handleEvent(event) {
  //BOTが生きてるか確認用のおうむ返し
  if (event.type === 'message' && event.message.type === 'text') {
    return client.replyMessage(event.replyToken, {
      type: 'text',
      text: event.message.text //実際に返信の言葉を入れる箇所
    });
  }

  //ビーコン反応
  else if(event.type === 'beacon') {
    console.log(`beacon enter`);
    // ここに処理を書いていく
    
    return Promise.resolve(null);
  }
}

//省略
```

実際に試すと、LINE Beaconの反応があった際にターミナルに`beacon enter`と表示されます。

あとは`// ここに処理を書いていく`とコメントした箇所を中心に処理を書いていきましょう。

#### 動かない場合

* 基本
	* LINE BOTと友達になっているか確認
	* スマートフォンでBluetoothがオンになっているか確認
	* LINEアプリでLINE Beaconがオンになってるか確認
	* Arduino IDEで書き込みエラーは出てないか確認
* それでもダメなら
	* おうむ返しが帰ってくるか確認
	* LINEアプリを一度落としてから再起動
	* LINE BOTを一度友達削除してから再度友達に

こんな手順で確認しましょう。

### おまけ: マイコンボードからビーコンでメッセージを送る

LINE Simple BeaconではDMというパラメータでマイコンボードからLINE BOT側にメッセージを送ることができます。

**センサーデータをLINE BOT経由でユーザーに送ったり、その値によってLINE BOTがユーザーに話しかける内容を変えたり**出来ます。

```bash
beacon: { hwid: '000000000', dm: '48656c6c6f', type: 'enter' }
```

* Arduino側のコード

```beacon.ino
#include "GreenBeacon.h"

const String hwid = "xxxxxxxxx";

GreenBeacon beacon; // Require in case using globally

void setup() {
  beacon = GreenBeacon(hwid, "MyBeacon"); // "MyBeacon" is optional
  beacon.start(); // start advertising
}

void loop() {
//  String mes = String(millis());
  String mes = "Hello";
  log_i("setMessage(%s)", mes.c_str());
  beacon.setMessage(mes);
  delay(1000);
}
```

* Node.js側のコード

マイコンボードからのメッセージが`event.beacon.dm`に格納されています。

このままだと16進数の文字列で送信されてくるので変換してあげましょう。

```js
const dmHexStr = event.beacon.dm; //16進数文字列
const dmStr = Buffer.from(dmHexStr, 'hex').toString('utf-8');
console.log(dmStr); //マイコンボードからのメッセージ
```

> 参考: [Node.jsで16進数文字列を文字列に変換メモ](https://qiita.com/n0bisuke/items/1872b3217c3bb9aba507)


以下、handleEventの関数をまるっと置き換えられるようにしてます。

```js
//省略

async function handleEvent(event) {
  //おうむ返し
  if (event.type === 'message' && event.message.type === 'text') {
    return client.replyMessage(event.replyToken, {
      type: 'text',
      text: event.message.text //実際に返信の言葉を入れる箇所
    });
  }

  //ビーコン反応
  else if(event.type === 'beacon') {
    console.log(`beacon enter`);
    // ここに処理
    const dmHexStr = event.beacon.dm; //16進数文字列
    const dmStr = Buffer.from(dmHexStr, 'hex').toString('utf-8');
    console.log(dmStr); //マイコンボードからのメッセージ

    return client.replyMessage(event.replyToken, {
      type: 'text',
      text: `マイコンボードからのメッセージ: ` + dmStr //実際に返信の言葉を入れる箇所
    });
  }
}
```

> ![スクリーンショット 2020-09-16 17.09.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/f29f3ceb-0d03-36bc-7e32-f1e1d0d03188.png "スクリーンショット 2020-09-16 17.09.32.png")


## まとめ

一旦一通り使えるようにまとめてみました。

何よりもこのビーコンのID払い出しURLがいつも忘れてしまう問題がデカいのでこの記事にまた戻ってこれるようにしたい。

> https://manager.line.biz/beacon/register

ドキュメントやBOT管理画面からの導線がいつも分からないんだよなぁ......