Help us understand the problem. What is going on with this article?

[3分クッキング♪] 余っていたM5StickCでLINE Beacon化してみた!

この投稿は IoTLT Advent Calendar 2019の11日目の投稿です。

こんにちは!もちゃんと申します!
LINE ThingsやLINE Beaconが好きです。

この夏、LINE Thingsのアワードが開催され、私もたくさんの作品を応募し大盛況のうちに幕を閉じました。
image.png

作品を応募するにあたり、多くのセンサーやデバイスを購入していたのですがM5StickCに関しては安かった(1,000円ぐらい)のもあり気が付いたら余るレベルの数を購入しておりました...

image.png

下記はLINE対応ビーコンですが何かM5StickCと形似てませんか?もうM5StickCがビーコンにしか見えなくなりました。少なくとも私はそう思います。(余ってるし)こいつをビーコン化してやろうと...(2019年秋)

image.png

はじめに

前置きが長くなりました。。
今回はオープンなLINE Beaconデバイスの仕様である、「LINE Simple Beacon」の仕組みを使ってLINE Beacon化していきます。

LINE Simple Beaconとは

LINE Simple Beaconとは、LINE Bot開発者向けのビーコンデバイス仕様です。 LINE Simple BeaconはBluetooth Low Energy (以下、「BLE」という)の仕様にもとづいており、 汎用のデバイスでLINE Beaconのサービスを利用することを可能とします。

https://github.com/line/line-simple-beacon/blob/master/README.ja.md

さっそくBeacon化してみる

必要なもの

  • 余ったM5StickC
  • LINE Bot
  • LINE Beacon化したいと思うお気持ち

事前準備

事前にLINE Botが必要になります。
ここでは簡単にですが、下記にLINE Botの準備手順を記載します。

◆ まずMessaging APIのチャネルを作成します。

下記URLからチャネルを作成します。
https://developers.line.me/ja/services/messaging-api/
作成後、Messaging API設定タブに移動し、QRコードでBotと友だちになっておきましょう。
スクリーンショット 2019-12-12 0.49.20.png

◆ そしてwebhookの設定

webhook URLを入力し、webhookの利用をONにします。
スクリーンショット 2019-12-12 0.07.18.png

◆ 応答メッセージの無効

応答メッセージを利用しないので編集ボタンからLINE公式アカウント画面で無効にしましょう。
スクリーンショット 2019-12-12 1.01.16.png

◆ LINE Bot のコードは下記のような感じです

'use strict';

const line = require('@line/bot-sdk');

const config = {
    channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN,
    channelSecret: process.env.CHANNEL_SECRET
};

const client = new line.Client(config);

module.exports = async( req, res ) => {
  Promise
    .all(req.body.events.map(await handleEvent))
    .then((result) => res.json(result))
    .catch((err) => {
      console.error(err);
      res.status(200).end();
    });
};

// event handler
async function handleEvent(event, session) {
  console.log(event);
  let echo = [];
  // 参考:https://developers.line.biz/ja/reference/messaging-api/#beacon-event
  if (event.type === 'beacon') {
    if (event.beacon.type === 'enter') {
      // LINE Botと友だちになっている方がLINE Beaconの近くにきたら、その人の情報を送る
      await client.pushMessage(process.env.USER_ID, [
        { 'type': 'text', 'text': event.source.userId + 'さんが来店しました。' }
      ]);
    }
    return;
  } else if (event.type === 'follow') {
    return;
  } else {
    echo = { 'type': 'text', 'text': '申し訳ありませんが、お返事できません。' }; 
  }

  // use reply API
  return client.replyMessage(event.replyToken, echo);
}

※ 上記ではプッシュメッセージ機能を使ってLINE Botにメッセージを送信しています。1か月あたり1,000通までの制限はありますが無料でも利用できます。
https://engineering.linecorp.com/ja/blog/line-developer-trial-migration/

LINE Beacon化の作業

ここからがLINE Beacon化の作業です。
下記の手順に従えば3分ぐらいでいけると思います!

◆ 環境構築

Arduino IDEはお手持ちのPCに入っている前提で

ESP32のボード開発用のライブラリをインストールしていきます。
メニューバーの「Arduino」->「Preference(環境設定)」を開きましょう。
スクリーンショット 2019-12-12 8.46.33.png

https://dl.espressif.com/dl/package_esp32_index.json
上記をコピーして、赤枠に入力して、「OK」ボタンを押しましょう。
スクリーンショット 2019-12-12 8.49.09.png

次にメニューバーの「ツール」->「ボード」->「ボードマネージャー」を開きましょう。
スクリーンショット 2019-12-12 8.49.56.png

上の入力欄にESP32を検索して表示されたたものをインストールしていきます。
スクリーンショット 2019-12-12 8.52.20.png

次にM5StickCのライブラリをインストールします。「ツール」->「ライブラリを管理」を開きましょう。
スクリーンショット 2019-12-12 8.54.05.png

同様に入力欄にM5StickCで検索し赤枠をインストールしましょう。
スクリーンショット 2019-12-12 8.55.21.png

M5StickCをPCと接続して、メニューバーの「ツール」から下記のように設定をします。他はデフォルトのままでOKです。
スクリーンショット 2019-12-12 8.57.01.png

上記のインストールを進めながら、下記のLINE Simple BeaconのハードウェアIDの設定も実施します。

◆ LINE Simple BeaconのハードウェアID

下記URLから [LINE Simple BeaconのハードウェアIDを発行]ボタンを押します。
https://manager.line.biz/beacon/register
スクリーンショット 2019-12-12 1.25.34.png

アカウントリストから、上記で作成したチャネルの選択ボタンを押して、ハードウェアIDを発行します。
スクリーンショット 2019-12-12 0.56.24.png

スクリーンショット 2019-12-12 1.03.40.png

発行したハードウェアIDをM5StickCのコードの「YOUR_HWID」に書き換えます。
スクリーンショット 2019-12-12 0.56.36.png

◆ M5StickCのコードは下記のような感じです

下記がM5StickCをLINE Simple Beaconとして動作させるコードになります。Arduino IDEを使って書き込みます。

#include <M5StickC.h>
#include <string>
#include "BLEDevice.h"
#include "BLEAdvertising.h"

/**
 * Bluetooth TX power level(index), it's just a index corresponding to power(dbm).
 * * ESP_PWR_LVL_N12 (-12 dbm)
 * * ESP_PWR_LVL_N9  (-9 dbm)
 * * ESP_PWR_LVL_N6  (-6 dbm)
 * * ESP_PWR_LVL_N3  (-3 dbm)
 * * ESP_PWR_LVL_N0  ( 0 dbm)
 * * ESP_PWR_LVL_P3  (+3 dbm)
 * * ESP_PWR_LVL_P6  (+6 dbm)
 * * ESP_PWR_LVL_P9  (+9 dbm)
 */
#define POWER_LEVEL ESP_PWR_LVL_P9

// 発行したハードウェアIDを書き換える
#define HWID "YOUR_HWID"
bool beaconFlg = false;

BLEAdvertising *pAdvertising;

std::string hexEncode(std::string raw) {
  const char *hexMap = "0123456789abcdef";
  std::string hex = "";
  for(int i=0; i<raw.size(); i++) {
    hex += hexMap[(raw[i] >> 4) & 0x0F];
    hex += hexMap[raw[i] & 0x0F];
  }
  return hex;
}

int htoi (unsigned char c)
{
  if ('0' <= c && c <= '9') return c - '0';
  if ('A' <= c && c <= 'F') return c - 'A' + 10;
  if ('a' <= c && c <= 'f') return c - 'a' + 10;
  return 0;
}

std::string hexDecode(std::string hex) {
  if (hex.size() % 2) return "";
  std::string raw = "";
  for(int i=0; i<hex.size(); i+=2) {
    raw += (char) ( htoi(hex[i]) * 16 + htoi(hex[i+1]) );
  }
  return raw;
}

bool setLINEBeacon (std::string hwid, std::string msg) {
  // check hwid
  if (hwid.size() != 5 || msg.size() > 13) return false;

  BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
  BLEAdvertisementData oScanResponseData = BLEAdvertisementData();
  BLEUUID line_uuid("FE6F");

  // flag
  // LE General Discoverable Mode (2)
  // BR/EDR Not Supported (4)
  oAdvertisementData.setFlags(0x06);

  // LINE Corp UUID
  oAdvertisementData.setCompleteServices(line_uuid);

  // Service Data
  std::string payload = "";
  payload += (char) 0x02; // Frame Type of the LINE Simple Beacon Frame
  payload += hwid; // HWID of LINE Simple Beacon
  payload += 0x7F; // Measured TxPower of the LINE Simple Beacon Frame
  payload += msg; // Device message of LINE Simple Beacon Frame
  oAdvertisementData.setServiceData(line_uuid, payload);

  pAdvertising->setAdvertisementData(oAdvertisementData);
  pAdvertising->setScanResponseData(oScanResponseData);
  return true;
}

void setup() {
  M5.begin();
  BLEDevice::init("");
  esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_ADV, POWER_LEVEL);
  pAdvertising = BLEDevice::getAdvertising();

  M5.Lcd.setCursor(0, 30);
  M5.Lcd.print("Ready");
}

void loop()
{
  // The underlying framework will advertise periodically.
  // we simply wait here.
  if (digitalRead(M5_BUTTON_HOME) == LOW) {
    if (!beaconFlg) {
      // LINE BeaconをONにする
      setLINEBeacon(hexDecode(HWID), hexEncode(std::string((const char*) BLEDevice::getAddress().getNative(), 6)));
      pAdvertising->start();
      M5.Lcd.fillScreen(BLACK);
      M5.Lcd.setCursor(0, 30);
      M5.Lcd.print("line beacon! ON");
      beaconFlg = true;
    } else {
      // LINE BeaconをOFFにする
      //// LINE Beaconをストップする機能は現在動作しないようです。下記URLを参考にしてください。
      //// https://github.com/nkolban/esp32-snippets/issues/797
      pAdvertising = BLEDevice::getAdvertising();
      pAdvertising->stop();
      M5.Lcd.fillScreen(BLACK);
      M5.Lcd.setCursor(0, 30);
      M5.Lcd.print("line beacon! OFF");
      beaconFlg = false;
    }
    while(digitalRead(M5_BUTTON_HOME) == LOW);
  }
}

これでLINE Beacon化完了です!

活用アイディア

ジャストアイディアですが、お得意さんが来店された時に名前思い出せないッ!...みたいな時にもLINE BeaconとLINE Botで来店時にお客様のuserIdからお名前をそっと教えてくれる仕組みとか色々できそうではないでしょうか!(LINEのuserIdと顧客情報を紐づける仕組みは別途必要)

その他、LINE Beacon活用事例など

  • LINE DEVELOPER DAY 2019でもLINE Beaconを活用した可視化の取り組みがあったようです!

image.png

https://speakerdeck.com/line_devday2019/the-iot-technology-inside-line-developer-day-2019?slide=11

  • 出退勤をLINE Beaconで自動化

image.png

https://www.slideshare.net/linecorp/line-beacon-assists-employees-who-forget-to-clockin-and-out-124004111

他にも様々な場面でLINE Beaconは活用されています。

まとめ

LINE Botと友達になるだけでLINE Beaconと連携できる手軽さが良いですよね。
既存のBotにも活用できると思いますので、新しい展望が出てくる可能性もあるのではないでしょうか。
年末年始でお時間ある方も是非試してみてください。

参考情報

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした