LINE Things 自動通信機能 ハンズオン

# LINE Things 自動通信機能 ハンズオン

<img src="https://qiita-image-store.s3.amazonaws.com/0/29906/993235a9-b521-5bb3-b203-49cfca6829fd.png" width="480">

LINE Things 自動通信機能を対象としたハンズオンです。各地で開催予定。

- [【デジットハッカソン2019 Special Day】LINE Thingsハンズオン](https://code4osaka.connpass.com/event/129124/)
- [LINE Thingsと可視化サービスの研究会](https://line.connpass.com/event/137271/)

**このハンズオンでは、[LINE Things development board](https://github.com/line/line-things-dev-board) を利用します。**
[おまけ](#おまけ-line-things-自動通信機能を体験しよう---line-things-starter-利用) には、[LINE Things Starter](https://github.com/line/line-things-starter/) 向けの章も用意していますので、ボードが手に入らない方は [LINE Things Developer Trial ハンズオン](https://qiita.com/hktechno/items/bb83cc898c75819b2664) とあわせてご覧ください。

説明をスキップして、ハンズオンを始めたい方は[こちら](#step-1---line-things-を使うための準備をしよう)から。

## 今日の流れ

- LINE Things のコンセプト・概要の説明
  - LINE Things とは
  - LINE Things の自動通信についての説明
  - LINE Things で自動通信をしてみたデバイスの紹介 (体重計、呼び出しボタン)
- ハンズオン
  - [Step 1 - LINE Things を使うための準備をしよう](#step-1---line-things-を使うための準備をしよう)
  - [Step 2 - LINE Things dev board を LINE Things と連携させよう](#step-2---line-things-dev-board-を-line-things-と連携させよう)
  - [Step 3 - LINE Things 自動通信機能を体験しよう](#step-3---line-things-自動通信機能を体験しよう)
  - [Step 4 - LINE Bot サーバーの設定](#step-4---line-bot-サーバーの設定)
- 時間が余った人は、応用編に挑戦したり、工夫してみたり
- その他、LINE Things を利用したちょっとしたガジェットの作例紹介
- 懇親・質問タイムなど

### 目標

LINE Things Starter または LINE Things development board を利用して、自動通信のためのシナリオを実行し Webhook を受け取り Bot で返信できるようになる。

### 必要なもの

- [LINE Things development board](https://github.com/line/line-things-dev-board)
- LINE の最新版 (>= 9.6) をインストール済の Android か iPhone
 - iPhone 4S 以下では iOS および LINE アプリ最新版が対応しておらず、利用不可能です
- Micro-USB to USB ケーブル
- USB が使える PC (Windows / Mac)

### 心得

わからないことがあったら積極的にスタッフを呼んで聞いてください。
限られたハンズオンの時間なので、自分で悩んで考えるより手を動かすことに時間を使ってください！

### ハッシュタグ

[\#linethings](https://twitter.com/search?q=%23linethings&src=typd)

本日の内容は、自由に Twitter へ投稿してもらって構いません。
完成したデバイスの写真や、困ったこと、ご意見等お待ちしております！

---

## LINE Things とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29906/1ed3fb5e-a31c-453a-1f4c-5da4ebd2b6b5.png)

[LINE Things](https://developers.line.biz/ja/services/line-things/) は LINE 上から利用できる、新しい IoT プラットフォームです。Bluetooth LE を利用して、IoT デバイスに接続し、LIFF や LINE Bot からコミュニケーションができるようになります。
基本的には、**LIFF も LINE Things も LINE Bot 機能の延長線** として開発されているので、Bot やメッセージングと連携する IoT デバイスの実現を目的としています。
もっと詳しく知りたい方は、以下のドキュメントやブログ、発表資料をご覧ください。

- [LINE Thingsとは何か？ / What is LINE Things?](https://speakerdeck.com/line_developers/what-is-line-things)
- [LINE Things - LINE Developers](https://developers.line.biz/ja/docs/line-things/)
- [LINE の IoT プラットフォーム LINE Things の Developer Trial を試してみる](https://engineering.linecorp.com/ja/blog/line-things-developer-trial/)
- [LINE Things 自動通信機能がリリースされました & 使い方紹介](https://engineering.linecorp.com/ja/blog/line-things-automatic-communication/)
- [Looking Toward the World Connected and Expanded through Things LINE&#x27;s Effort in IoT and its Future](https//www.slideshare.net/linecorp/looking-toward-the-world-connected-and-expanded-through-things-lines-effort-in-iot-and-its-future-123994663)


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29906/a1d5163c-ecf9-5080-0381-db81203f7592.png" width="640">


LINE Things の全般的な説明と、LINE Things Starter を用いた LIFF 上の JavaScript API を体験するハンズオンは、以下の Developer Trial ハンズオン資料をご覧ください。
(今回は、LINE Things development board を使用します)

- [LINE Things Developer Trial ハンズオン](https://qiita.com/hktechno/items/bb83cc898c75819b2664)

---

### LINE Things でできること3つ

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29906/9c8fc04a-9dbc-4f00-2c8f-e68a590aaa81.png" width="640">


- LINE アプリ上で Bluetooth LE 接続可能な LINE Things 対応デバイスを登録する
  - 詳しくは [LINE Things Developer Trial ハンズオン](https://qiita.com/hktechno/items/bb83cc898c75819b2664)
- LIFF 上から JavaScript API を経由して LINE Things 対応デバイスを操作する
  - 詳しくは [LINE Things Developer Trial ハンズオン](https://qiita.com/hktechno/items/bb83cc898c75819b2664)
- **LINE アプリがデバイスに対して自動で通信を行い、LINE Bot に情報を送信する** ← LINE Things 自動通信機能
  - **新機能**: LINE アプリのバージョン 9.6.0 以降で利用可能 

今回のハンズオンは、主に **LINE Things の自動通信機能**  を体験して頂くハンズオンとなります。

---

## LINE Things の自動通信機能について

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29906/fb5856d6-416c-8e67-dc73-5a7eeb1c2a39.png)

LINE Things の自動通信とは、エンドユーザーがアプリの操作をしなくても、開発者があらかじめ登録した通信手順で、デバイスとLINEの間で自動的に通信を行う機能です。
つまり、スマホの画面が点いていなくても、(限られた状況では) バックグラウンドで Bluetooth LE 通信できるようになります。

自動通信機能を利用することで、家電などのデバイスが、まるで自発的にコミュニケーションを行うような UX が実現できます。
例えば、以下のような例です。

- LINE Bot からユーザーにメッセージを送信してお知らせする
  - 例: 定期的にバッテリー残量を通知する
  - 例: 体重計に乗った時に体重を取得してお知らせする
- LINE Bot にデータを溜め込んで定期的に変化を通知する
  - 例: 運動量計からの情報を取得して運動量を測定する
- LINE Bot が行った処理の結果をメッセージで送信する
  - 例: デバイスがピクセルデータを読み取って送信し、画像としてメッセージをユーザーに返す

自動通信に加えて、ユーザーとボットとの会話をや、LIFFを利用することで、IoTデバイスとLINEを活用した新しいユーザ体験を提供できます。

### 自動通信を利用した例: 呼び出しボタン

<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">自動通信を使った呼び出しボタンの例 <a href="https://t.co/xyTpEZ8BjR">https://t.co/xyTpEZ8BjR</a></p>&mdash; Hirotaka Kawata (@hktechno) <a href="https://twitter.com/hktechno/status/1128283207978250241?ref_src=twsrc%5Etfw">2019年5月14日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

### 自動通信を利用した例: 体重計

<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">自動通信を使った体重計の例 <a href="https://t.co/NYB0EuynBi">https://t.co/NYB0EuynBi</a></p>&mdash; Hirotaka Kawata (@hktechno) <a href="https://twitter.com/hktechno/status/1128283206690660353?ref_src=twsrc%5Etfw">2019年5月14日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

LIFF の BLE 機能を使えば、以下のように HTML と JavaScript を使った UI も　LINE アプリ内で実現できます。
自動通信と、LIFF をうまく組み合わせて利用したいところです。

<img src="https://qiita-image-store.s3.amazonaws.com/0/29906/9eb66e58-366e-9a01-6e5b-ecb5efeefd31.jpeg" width="480">

### LINE Things の自動通信機能を使ったデバイスの作例

- [#linethings でバイクの盗難防止装置作ってみた](https://qiita.com/stachibana/items/dac5968255f375792fae)
- [M5StickCとLINE Thingsで冷蔵庫の開閉時間をBotに通知させるデモ　](https://twitter.com/gaomar/status/1128181447435534338)
- [LINE Thingsでウェアラブルデバイスを作ってみた](https://qiita.com/K_M95/items/a1d461334441147df652)
- [LINE Things とM5Stack で子どもの帰宅／外出を通知できる仕組みを作ってみた](https://qiita.com/sumihiro3/items/965998815a0b975a465a)

### 自動通信に必要なものは？

#### ハードウェア (デバイス)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29906/0de01ec2-9114-f597-5e0c-5af0f3d8a16d.jpeg" width="480">

Bluetooth LE に対応したハードウェアが必要になります。
LINE Things 対応デバイスとして LIFF 上から操作できるものであれば、基本的に自動通信をそのまま利用できます。
特に新しく、対応しなければいけない点はありません。

つまり、[GATT Service の Read, Write, Notify](https://qiita.com/hktechno/items/bb83cc898c75819b2664#gatt-service-characteristic) のいずれかを用いて通信できるものであれば、自動通信からもその Characteristic を利用することができます。

#### LINE Bot

<img src="https://qiita-image-store.s3.amazonaws.com/0/29906/981d82c0-e7db-c990-e807-27c778f80264.png" width="240">

自動通信の実行結果や、やり取りされたデータは、全て Messaging API のチャネル (== LINE Bot) への Webhook 送信先に、通常のメッセージと同じような形式のイベントとして送信されます。
そのため、LINE Bot として Webhook を受け取ることができる Web サーバーが必要になります。

- [Webhookイベントオブジェクト - LINE Thingsシナリオ実行イベント](https://developers.line.biz/ja/reference/messaging-api/#scenario-result-event)

ユーザーに通信した内容を元にしたメッセージを送信するためには、自動通信のイベントに対して[応答メッセージ](https://developers.line.biz/ja/reference/messaging-api/#send-reply-message)を送信したり、[プッシュメッセージ](https://developers.line.biz/ja/reference/messaging-api/#send-push-message)機能を使ってメッセージを送信することになります。

#### 料金

LINE Things Developer Trial の範囲であれば、無料で利用できます。
自動通信を利用するために、追加の料金は必要ありません。

### 自動通信に必要な準備

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29906/7e2e3574-66f0-fc14-a11a-e04d51852cc8.png" width="640">

自動通信を行うためには、大きく2つの準備と設定が必要です。

- LINE のサーバーに API を通じてどのような手順・設定で LINE アプリがデバイスと通信を行うかを定義した "シナリオセット" を登録
- シナリオセットを元に通信した結果を Messaging API のチャネル (LINE Bot) を経由して Webhook により受け取るためのサーバーの準備

上記は、実際にデバイスと LINE アプリ、LINE プラットフォームのサーバー、そして Messaging API の一連の流れを表した図になります。
この先で、1つ1つ説明していきます。

### シナリオセット - 自動通信を行う手順の登録

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29906/bfa29ccd-4cd6-76ec-2d14-a2b40d435ed4.png" width="640">

LINE Things の自動通信では、LINE アプリは LINE Things プラットフォームのサーバーに保存されたプロダクト固有のシナリオセットをもとに、デバイスと通信を行います。
シナリオセットは、JSON 形式で定義して [自動通信向けシナリオ管理API](https://developers.line.biz/ja/reference/line-things/#auto-communication-scenario-management-api) を通じて LINE Things プラットフォームのサーバーへ登録できます。

シナリオセットの特徴は以下のとおりです。

- LINE Things に登録したプロダクトに、シナリオセット1つが登録可能
- シナリオセットは、複数の "シナリオ" の集合体
- シナリオは、指定された "トリガ" を起点として "アクション" の集合を順番に実行する
- 実行結果は、シナリオの実行ごとにイベントが送信される

詳しくは、公式ドキュメントの [自動通信の準備をする](https://developers.line.biz/ja/docs/line-things/prepare-auto-communication/) を参照してください。
ここでは、簡単に概念と使い方を説明します。

#### シナリオ

シナリオは、トリガとアクションから構成されています。

##### トリガ

トリガーには、現在2つの種類があり、いずれかを指定します。

- `IMMEDIATE`：デバイスとLINEが接続されると、すぐにアクションを実行する
- `BLE_NOTIFICATION`：指定したGATT Characteristicの通知を受けたときに、アクションを実行する
  - Notify のペイロードは、アクション実行結果とあわせてLINEに送信されます。

##### アクション

トリガによって開始されたシナリオ内で、どのような手順で通信を実行するかを指定します。
以下のような3種類のアクションを複数個リストとして指定可能で、順番に実行されます。
もし、トリガに `BLE_NOTIFICATION` を指定した場合など、そのペイロードのみが必要であれば、アクションを空することも可能です。

- `GATT_READ`：指定したGATT Characteristicからデータを取得する
  - 読み取ったデータは、シナリオ実行結果と共に送信されます
- `GATT_WRITE`：指定したGATT Characteristicにデータを書き込む
- `SLEEP`：指定された時間待つ

#### シナリオセット

シナリオセットは、複数のシナリオの集合で、リストとして登録できます。
複数のトリガが `IMMEDAITE` のシナリオの実行は、ここで順番に実行されます。

また、シナリオセットには以下のパラメーターが指定でき、デバイスとの接続の切断・再接続に関する設定を行います。

- `autoClose`
  - `true` を指定すると、シナリオセット内のすべての実行中シナリオを実行後に、デバイスとの接続を切断する
    - トリガが　`BLE_NOTIFICATION` のシナリオが Notify を待っている状況は、実行中とは判断されません 
  - `false` の場合、デバイスとの接続を維持する（常時接続）
- `suppressionInterval`
  - `autoClose = true` の場合、接続を切断したあと再接続を抑制する時間を指定する
  - [**重要**] 再接続は、必ずここで指定した時間で行われるとは限らない。あくまで、再接続を抑制する時間です。
  - `autoClose = false` の場合には `0` 固定

これらのパラメーターは、一部 OS の制限などにより動作に注意点があります。
詳しくは、[自動通信を利用する際の注意点について](https://developers.line.biz/ja/docs/line-things/notes-on-using-auto-communication/) を参照してください。

**おすすめの設定は、`autoClose = false` かつ `suppressionInterval = 0` (常時接続) の状態で利用することです。**

#### シナリオセットの例

ここで、実際に JSON で記述したシナリオセットの例を少し見てみましょう。

常時接続で、ある GATT Characteristicからの　Notify を待つ例から。
ほぼ、Service UUID と Characteristic UUID を見るだけなので、簡単ですね。

```json
{
  "autoClose": false,
  "suppressionInterval": 0,
  "scenarios": [
    {
      "trigger": {
        "type": "BLE_NOTIFICATION",
        "serviceUuid": "91E4E176-D0B9-464D-9FE4-52EE3E9F1552",
        "characteristicUuid": "62FBD229-6EDD-4D1A-B554-5C4E1BB29169"
      },
      "actions": [
      ]
    }
  ]
}
```

次に、前回接続から1時間以上経過後、デバイスに接続し、すぐにアクション　(GATT へのアクセス) を実行し、接続を切断する例。
少し複雑ですが、GATT 操作を list で並べて書くことで、いろいろ情報を抜いたり、コマンド操作的なことができるようになるのがわかると思います。

```json
{
  "autoClose": true, 
  "suppressionInterval": 3600000,  
  "scenarios": [
    {
      "trigger": {
        "type": "IMMEDIATE"        
      },                                                      
      "actions": [                                                  
        {
          "type": "GATT_READ",
          "serviceUuid": "7B3D6B30-8F8C-4549-A4F5-66B1F435FA8F",
          "characteristicUuid": "90EC53BA-1DBE-4AE2-B762-7C1FEA00F380"
        },
        {
          "type": "SLEEP",
          "sleepMillis": 5000
        },
        {
          "type": "GATT_WRITE",
          "serviceUuid": "7B3D6B30-8F8C-4549-A4F5-66B1F435FA8F",
          "characteristicUuid": "5486C1A0-0EC2-4073-9C38-755D21EFE090",
          "data": "6AMAAA=="
        }
      ]
    }
  ]
}

```

### Messaging API - LINE Things シナリオ実行イベントの受け取り 

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29906/c0b45b82-aff5-d46b-6ebd-96425c474a21.png" width="640">

では、実際にシナリオセットを登録したあと、どうやってその結果を受け取るのでしょうか？
上記は、実際にデバイスと LINE アプリ、LINE プラットフォームのサーバー、そして Messaging API の一連の流れを表した図になります。

何度か説明してきたように、Messaging API のチャネル (LINE Bot) の Webhook 登録先に、ボットにメッセージが送信されたときと同じような形式で送信されます。
つまり、[LINE Bot として](https://developers.line.biz/ja/docs/messaging-api/building-bot/)メッセージを受信できるようなサーバーを作れば、ほぼそのまま LINE Things 自動通信にも対応できます。

通常のメッセージと違う点は、イベントの `type` が `things` として送信され、テキストメッセージとは異なるパラメーターを持っている点です。
詳しくは、[LINE Thingsシナリオ実行イベント](https://developers.line.biz/ja/reference/messaging-api/#scenario-result-event) に記載されています。

通常のメッセージイベントと同様の形で Messaging API へ送信されるため、`replyToken` も利用可能です。
つまり、デバイスと自動通信した結果をもとに、ユーザーへメッセージを "[返信](https://developers.line.biz/ja/reference/messaging-api/#send-reply-message)" することができます。
プッシュメッセージではないので、`replyToken` を使った返信は、メッセージ単位で課金される事はありません。

#### LINE Thingsシナリオ実行イベント Webhook の例

実際に、Webhook として受け取れるシナリオ実行イベントの例は以下のようなものになります。

シナリオ実行イベントは、"シナリオ" 単位のイベントとして発行されます。(シナリオセットではない)
どのシナリオが実行されたかは、`scenarioId` で判断してください。`scenarioId` は、シナリオセット登録時に、自動で採番されレスポンスに格納されています。
シナリオ実行中に LINE アプリ内でエラーが発生した場合にも送信され、`resultCode` が `success` ではないイベントとして送信されます。

実行結果に含まれるバイナリは、すべて BASE64 でエンコードされます。
トリガを `BLE_NOTIFICATION` に指定した場合の Notify のペイロードは、`bleNotificationPayload` に格納されています。
また、アクションの実行結果は `actionResults` に、シナリオでアクションを指定した順番で格納されます。

```json
{
    "type": "things",
    "timestamp": 1552375572973,
    "replyToken": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "source": {
        "type": "user",
        "userId": "u1234567890abcdef1234567890abcdef"
    },
    "things": {
        "type": "scenarioResult",
        "deviceId": "tfedcba9876543210fedcba9876543210",
        "result": {
            "scenarioId": "DUMMY_SCENARIO_ID",
            "revision": 0,
            "resultCode": "success",
            "startTime": 1552375571097,
            "endTime": 1552375571098,
            "bleNotificationPayload": "AAAAAA==",
            "actionResults": [
                {
                    "data": "mIcIAA==",
                    "type": "binary"
                },
                {
                    "type": "void"
                },
                {
                    "type": "void"
                }
            ]
        }
    }
}
```

---

# LINE Things 自動通信機能を体験しよう

## Step 1 - LINE Things を使うための準備をしよう

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29906/be5a64db-1d24-0417-da9f-b3833ea3c88e.jpeg" width="640">

**[LINE Things development board](https://github.com/line/line-things-dev-board) を利用する例になります。**

このハンズオンでは、**Arduino からのファームウェア書き換えは必要ありません**。
ただし、LINE Things development board のファームウェアは最新版 (Ver.2 以上) である必要があります。(最新版でない場合は、連携時にメッセージが届きます)

### Messaging API のチャネル (LINE Bot) の作成

<img width="480" src="https://qiita-image-store.s3.amazonaws.com/0/29906/114ad991-e24c-ada1-4eb8-6127d19a47ef.png">

以下の手順を参考に、Messaging API のチャネルを作成してください。このチャネル (Bot) をもとに、LIFF や LINE Things プロダクトの情報が結びつきます。
LINE Developers コンソールにログインして開発者情報を登録と、LINE の Bot を作るためのプロバイダーの作成が必要です。

- [Messaging APIを利用するには](https://developers.line.biz/ja/docs/messaging-api/getting-started/)
  - "次のステップ" へ進む必要はありません

***⚠注意*** チャネルの名前に "***LINE***" を含めることが出来ません。原因不明のエラーになるので、LINE という文字列を指定しないでください。

ここで、必ず自分の LINE アカウントで、**作成した LINE Bot と友だちになっておきましょう**。LINE Things Developer Trial では、プロダクトが結び付けられているチャネルの Bot と友達のユーザーにのみ、そのプロダクトが連携画面に表示されるようになります。


### LIFF アプリのデプロイと作成

次に、LIFF (LINE Front-end Framework) アプリの準備を行います。

通常、LIFF アプリを作成するには、そのエンドポイントを提供する Web サーバーが必要になります。今回使用しているデモの　LIFF は、静的な HTML と JS を提供するだけでよいので、 GitHub Pages を利用します。

#### GitHub Pages のデプロイ

<img width="775" alt="0760b7ec886f16877173b98a12ba7db2.png" src="https://qiita-image-store.s3.amazonaws.com/0/354978/4eec5948-d396-57bd-c9ef-d3012193db5e.png">

自分の GitHub アカウントで [LINE Things dev board](https://github.com/line/line-things-dev-board) を Fork して、GitHub Pages にデプロイします。

LINE Things dev board のリポジトリ を GitHub で Fork した後、Settingsタブを開き、GitHub Pages の Source を master branch に変更してください。

その後、"Your site is published at {URL}" と表示されるはずで、この URL をコピーしてください。URL に **`liff-app/linethings-dev-default/` を末尾につけたもの** が LIFF のエンドポイント URL になります。

#### LIFF アプリの作成と BLE feature の付与

<img width="1431" alt="e0e95baf8668729908ed721e438f404c.png" src="https://qiita-image-store.s3.amazonaws.com/0/354978/7b83f7bf-5f32-bc1e-3497-0a19658bfe70.png">

その後、デプロイされた URL をエンドポイント URL として LIFF を作成します。
LINE Things 向けの LIFF を作成する際には、 **BLE feature を ON** に設定する必要があります。
この設定がないと、LIFF の Bluetooth LE プラグインが有効にならず、その LIFF 上では LINE Things の機能を動作させることが出来ません。

まず、LIFF を作成したいチャンネルを選択して、"LIFF" のタブを開いてください。
上記のような画面が表示されるので、⊕追加 ボタンを押します。

<img width="1091" alt="fde95d08c74cba73f5978362f9bf1df9.png" src="https://qiita-image-store.s3.amazonaws.com/0/354978/b2f3e018-26e5-3914-7a8d-5cc03bc53cb0.png">

LIFF の追加ポップアップが現れます。
まずは、BLE feature を ON にしましょう。こうすることで、LIFF 内で LINE Things 向けの BLE 通信機能が使えるようになります。

LIFF の名前は、何でも良いので適当に入力してください。
サイズは、Full を押すと全画面で LIFF が表示されるので、まずはこれをおすすめします。
エンドポイント URL には、先ほど作成した GitHub Pages の URL を入力してください。
最後に保存するを押してください。

<img width="563" alt="365cb0b88231a90018371a73b82c7643.png" src="https://qiita-image-store.s3.amazonaws.com/0/354978/dd508fee-5a63-d027-bccd-701f2aa0ea89.png">

**[注意] 必ずURLの一番最後に "/" をつけてください。**

```
OK : liff-app/linethings-dev-default/
NG : liff-app/linethings-dev-default
```

作成が完了すると、上のように LIFF URL という項目が表示されます。(**line://app/** から始まる URL)
この URL をメモしておきましょう。プロダクトの作成のために利用します。


### LINE Things プロダクトの作成

LIFF の作成が完了したら、この情報をもとに LINE Things の新しいプロダクトを作成します。
LINE Things Developer Trial 専用の API を利用して、新しい LINE Things プロダクトを作成します。

その前に、まずお使いの PC に `curl` コマンドが入っているかどうか確認してほしいです。
(残念ながら、現在こちらは Web UI は提供されていませんので、REST API のみとなります...)

- **Windows をお使いの方**: PowerShell を開いて `curl.exe --help` と入力して、ヘルプが表示されれば問題ありません。最近の Windows 10 では標準でインストールされていることが多いです。`curl` (.exe なし) は、ここで扱う `curl` と違うコマンドにエイリアスされているので使用しないでください。
  - **無事 `curl.exe` の存在が確認された方**: PowerShell では、改行に使っているバックスラッシュ `\` を認識できません。削除して1行につなげてコマンドを入力してください。また、JSON の `"` を `\` でエスケープする必要があります。
  - **`curl.exe` が見つからない方**: `Invoke-WebRequest` やその他 POST できるツールを使って API を実行してください。
- **Mac/Linux をお使いの方**: おそらく、最初からインストールされています。`curl --help` と入力して、ヘルプが表示されていれば問題ありません。

curl が使えることがわかった方は、以下の公式ドキュメントを参考に　LINE Things Developer Trial 専用 API を利用してプロダクトを作成します。

- [デバイスを作成する - プロダクト情報を登録する](https://developers.line.biz/ja/docs/line-things/create-devices/#register-product-information)
- [LINE Things APIリファレンス - トライアルプロダクト情報を作成する](https://developers.line.biz/ja/reference/line-things/#post-trial-products)

以下がプロダクト作成 API を curl コマンドを利用して実行してみた例です。

**Mac の方はこちら**

```shell
$ curl -X POST https://api.line.me/things/v1/trial/products \
-H 'Authorization: Bearer <channel access token>' \
-H 'Content-Type:application/json' \
-d '{
  "name": "<trial product name>",
  "liffId": "<LIFF APP ID>"
}'
```

**Windows の方はこちら**

```shell
> curl.exe -X POST https://api.line.me/things/v1/trial/products `
-H 'Authorization: Bearer <channel access token>' `
-H 'Content-Type:application/json' `
-d @'
{
  \"name\": \"<trial product name>\",
  \"liffId\": \"<LIFF APP ID>\"
}
'@
```

`name` には、好きなプロダクト名を登録することが出来ます。自分の Product だと分かる名前を設定しましょう。"LINE Things dev board" などありきたりな名前を入れると、同じようなプロダクトを何種類か登録したりしたときに、どのプロダクトと連携したのかがわかりにくくなってしまいます。
`liffId` には、上記で作成した LIFF アプリの ID (LIFF URL の line://app/ 以降の文字列) を指定してください。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29906/5acb3bbb-4757-ffa7-f9f6-6dd711dff5ce.png" width="480">

`channel access token` は、LINE の Channel API を叩くためのアクセストークンで、[LINE Developers](https://developers.line.biz/) コンソールのチャネル基本設定から取得することができます。
チャンネル (Bot) ごとに違う値となっています。表示されていない場合には、再発行を押して、この値をコピーして使ってください。

上記のプロダクト作成 API を叩くと、以下のような結果が帰ってきます。
LINE Things の Developer Trial 向けプロダクトでは、プロダクトを作成すると専用の Bluetooth LE の GATT Service UUID が発行されます。上記の結果に含まれる serviceUuid が、発行された UUID となります。


```
{
  "id": "{productId}",
  "name": "{trial product name}",
  "actionUri": "{LIFF APP URL}",
  "channelId": {channelId},
  "type": "BLE",
  "serviceUuid": "{serviceUuid}",
  "psdiServiceUuid": "{psdiServiceUuid}",
  "psdiCharacteristicUuid": "{psdiCharacteristicUuid}"
}
```

ここで発行された情報は、このあと使用しますので**必ずコピー**しておいてください。

## Step 2 - LINE Things dev board を LINE Things と連携させよう

ここから、実際に LINE Things デバイスへ接続して、LIFF を開きボードを自分の UUID に書き換える作業を始めます。

### LINE から LINE Things デバイスを接続してみよう

まずはデフォルトファームウェアのまま、初期状態の Service UUID を使用して LINE App から LINE Things dev board に接続してみようと思います。

LINE Things を利用するために、まずお使いの LINE をインストールしたスマートフォン上で、以下の QR コードを読み取って規約に同意していただき、LINE Things の機能を有効化してください。なお、すでにLINE Thingsを利用したことがある方はこの作業は不要です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/354978/cc42d152-c717-74f9-0cef-851597c46dfa.png)

その後、以下のようなデバイス連携画面が見えるはずです。一度有効化したら、次回からは `設定` → `LINE Things` からデバイス連携画面を開くことが出来ます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29906/b9de3e52-1cd4-692d-00aa-8d0b9022fe59.png" width="320">

LINE Things dev board にUSBケーブルを差し、ディスプレイに表示がされていることを確認します。 **デバイスとLINEがインストールされたスマートフォンを近づけて** "連携可能なデバイス" に **LINE Things dev board** が表示されていることを確認して、タップして LIFF を開きます。

**このデバイスは、まだ初期状態の Public なプロダクトで、まだ皆さんが作ったチャネルとは連携されていない状態です。**

もしデバイスがいくつか出ている場合は、とりあえず一番上のデバイスを選択して接続してみます。

- USBケーブルを差したけど動かない方
    - 左上にあるジャンパーピン (Power Select) で、上と真ん中が接続されていることを確認してください。

<img src="https://qiita-image-store.s3.amazonaws.com/0/354978/68727d80-9037-94b0-5bde-19ef87efeea3.jpeg" width="480">

- LEDは光っているけどデバイスが動かない方
    - 故障の可能性があるので、スタッフにを呼んでください。

**連携しました！今すぐ利用してみましょう** の画面が出たら *[今すぐ利用]* ボタンを押して、LIFFを開きます。

デフォルトのLIFFでは、一度に複数デバイスと接続できるように作られているため、この画面では近くにある全ての LINE Things dev board が表示されているかと思います。

デフォルトファームウェアでは、すべての LINE Things dev board が同じ Service UUID でアドバタイズしているため、 **電波の届く限り、すべての LINE Things dev board に接続可能** になっています。

この状態では、デバイスとスマホを近づけ、 **一番電界強度が高いデバイス** と接続します。
よくわかりにくかったら、スマホをデバイスから近づけたり離したりすることで、 **電界強度の強弱から自分のデバイスを見つける** ことができます。

<img src="https://qiita-image-store.s3.amazonaws.com/0/354978/53d0efcd-6c76-6b32-1b3f-6848372393cf.png" width="320">

上の写真の例では一番上のデバイスが最も強い電波を発しています。

### LINE Things dev board に自分のプロダクトの Service UUID を設定

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29906/cee6c6aa-e01f-0b9d-59d2-185cac0b2af3.png" width="320">

少し前のステップで自分のプロダクトの Service UUID を取得していました。ここではその取得したUUIDを自分のデバイスに設定してみましょう。この Service UUID をデバイスに設定することで、Advertising のときに自分のデバイスのみが表示され、接続できるようになります。
本当はデバイスのファームウェアを書き換えて行う必要があるのですが、このボードのデフォルトサンプルファームウェアは UUID を LIFF 上から書き換えることができます。

行う手順は次のとおりです。

1. Write advertising packet書き換えタブを開く
2. 取得したService UUIDをテキストボックスに入れて書き換えボタンを押す

これで LINE Things dev board のディスプレイに「BLE advertising uuid changed from LIFF....」 と表示されていれば成功です。

フォーマットの正しくない UUID を書き込んでしまった場合はエラーメッセージが出るので正しい UUID を再度書き込みましょう。

<img src="https://qiita-image-store.s3.amazonaws.com/0/354978/a6be5e29-4048-6c1c-5d1b-1571a33ee9c5.jpeg" width="480">

**LINE AppのLINE Thingsを閉じて**、LINE Things dev board の **リセットボタンを押して** ください。

書き込んだ Advatising UUID を初期状態に戻したい場合は、マザーボードの SW1 を押しながらリセットボタンを押すと、初期状態に戻ります。

### 自分のプロダクト情報を書き込んだ LINE Things dev board に接続してみよう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29906/5ffe1739-2653-3c83-4202-d7397601ad68.png)

ここまでの手順で、自分独自のデバイスをLINE Thingsとして利用できる準備が整いました。

まずは、先程、デフォルトの UUID のプロダクトで LINE Things から接続してしまったので、そのデバイス情報を消しましょう。
スマートフォンの OS の Bluetooth デバイス連携画面からデバイス登録を解除し、その後 LINE App上の LINE Things のデバイス連携画面からも解除を行います。 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29906/d546f2d3-bd72-689e-80aa-916cb79ef17f.png)

これで自分で設定した UUID の LINE Things dev board に接続できる準備ができました。
新しく、先程 **自分で設定したプロダクトの名前** が "連携可能なデバイス" に表示されます。

Notify タブの Notify ボタンを押してみましょう。LINE Things dev boardには加速度センサ、温度センサ、スイッチが搭載されています。
ボードを傾けるとX, Y, Zの値が変化し、温度センサを触ると取得される温度が変化することを確認します。同様に、スイッチの状態も取れていることを確認してください。

次に、Writeタブを開きます。LED2 ~ 5のチェックボックスにを ON/OFFしてボード上のLEDが変化することと、Buzzerが反応することを確認してください。

## Step 3 - LINE Things 自動通信機能の準備をしよう

これまでの章で、LINE Things の基本的な準備が整いました。
この先が、本題の自動通信を体験してみるハンズオンになります。

**[LINE Things development board](https://github.com/line/line-things-dev-board) を利用する例になります。**
[LINE Things Starter](https://github.com/line/line-things-starter) を利用する場合には、おまけの章を参照してください。

### LINE Things dev board でボタンの変化を受け取るには？

LINE Things development board には、GPIO ポート (ボタンを含む) の状態の変化を Notify する GATT Characteristic が用意されています。
初期状態では、`0` や `1` など、ボタンの状態と SW1 か SW2 どちらが押されたかが、状態が変化する度に Notify されるようになっています。
詳しい仕様は、LINE Things dev board の[デフォルトファームウェアについて](https://github.com/techno/line-things-dev-board/blob/cpulabs/docs/default-firmware.md)を参照してください。

この Characteristic を利用して、ボタンが押された通知を自動通信で受け取ってみましょう。
LINE Things development board は、Advertising する Service UUID はプロダクトごとに変化しますが、実際に操作をおこなう GATT Service は別に設定されていて、固定です。
独自の Advertising Service UUID を設定しても、上記の Service UUID は変化しませんので、このまま使います。

```
USER_SERVICE_UUID "f2b742dc-35e3-4e55-9def-0ce4a209c552"
NOTIFY_SW_CHARACTERISTIC_UUID "a11bd5c0-e7da-4015-869b-d5c0087d3cc4"
```

### シナリオセットの登録

次に、実際にシナリオセットを構築して登録してみましょう。
詳しい仕様は、[自動通信向けシナリオ管理API](https://developers.line.biz/ja/reference/line-things/#auto-communication-scenario-management-api) を参考にしてください。

#### ボタンの変化を受け取るシナリオセットを考える

まず、IO 変化の Notify を受け取るための**シナリオ**は、以下のような設定になります。
トリガを `BLE_NOTIFICATION` に設定して、Service UUID と Characteristic UUID を指定します。
Notify を受け取ったあと、ただそのペイロードを受け取れればよいだけなので、アクションは空に設定します。

```json
{
    "trigger": {
        "type": "BLE_NOTIFICATION",
        "serviceUuid": "f2b742dc-35e3-4e55-9def-0ce4a209c552",
        "characteristicUuid": "a11bd5c0-e7da-4015-869b-d5c0087d3cc4"
    },
    "actions": [
    ]
}
```

このシナリオをもとに、今回は以下のような**シナリオセット**を登録します。
`autoClose` は `false` に設定して、常時接続しずっと Notify を待ち受けるような設定とします。

```json
{
    "autoClose": false, 
    "suppressionInterval": 0,  
    "scenarios": [
        {
            "trigger": {
                "type": "BLE_NOTIFICATION",
                "serviceUuid": "f2b742dc-35e3-4e55-9def-0ce4a209c552",
                "characteristicUuid": "a11bd5c0-e7da-4015-869b-d5c0087d3cc4"
            },
            "actions": [
            ]
        }
    ]
}

```

#### シナリオ管理 API を使ってシナリオセットを登録

シナリオセットが完成したところで、実際にこのシナリオセットを API で LINE Things プラットフォームに登録してみましょう。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29906/5acb3bbb-4757-ffa7-f9f6-6dd711dff5ce.png" width="640">

API を利用するには、チャネルのアクセストークンが必要になります。[LINE Developers コンソール](https://developers.line.biz/) から取得してください。
また、シナリオセットを登録する LINE Things のプロダクトのプロダクト ID が必要になります。プロダクト登録 API のレスポンスに含まれていますが、忘れてしまった方は、以下のような API をリクエストして取得してください。

```shell
## Mac
$ curl -X GET https://api.line.me/things/v1/trial/products -H 'Authorization: Bearer <YOUR CHANNEL ACCESS TOKEN>'
## Windows
> curl.exe -X GET https://api.line.me/things/v1/trial/products -H 'Authorization: Bearer <YOUR CHANNEL ACCESS TOKEN>'
```

アクセストークンとプロダクト ID が取得できたら、`curl` コマンドで以下のように API をリクエストします。
`<YOUR PRODUCT ID>` と `<YOUR CHANNEL ACCESS TOKEN>` にそれぞれ、プロダクト ID とアクセストークンを入れてください。

**Mac や Linux の方はこちら**

```shell
$ curl -X PUT https://api.line.me/things/v1/products/<YOUR PRODUCT ID>/scenario-set \
-H 'Authorization: Bearer <YOUR CHANNEL ACCESS TOKEN>' \
-H 'Content-Type:application/json' \
-d '
{
    "autoClose": false, 
    "suppressionInterval": 0,  
    "scenarios": [
        {
            "trigger": {
                "type": "BLE_NOTIFICATION",
                "serviceUuid": "f2b742dc-35e3-4e55-9def-0ce4a209c552",
                "characteristicUuid": "a11bd5c0-e7da-4015-869b-d5c0087d3cc4"
            },
            "actions": [
            ]
        }
    ]
}'
```

**Windows の方はこちら**

```shell
> curl.exe -X PUT https://api.line.me/things/v1/products/<YOUR PRODUCT ID>/scenario-set `
-H 'Authorization: Bearer <YOUR CHANNEL ACCESS TOKEN>' `
-H 'Content-Type:application/json' `
-d @'
{
    \"autoClose\": false, 
    \"suppressionInterval\": 0,  
    \"scenarios\": [
        {
            \"trigger\": {
                \"type\": \"BLE_NOTIFICATION\",
                \"serviceUuid\": \"f2b742dc-35e3-4e55-9def-0ce4a209c552\",
                \"characteristicUuid\": \"a11bd5c0-e7da-4015-869b-d5c0087d3cc4\"
            },
            \"actions\": [
            ]
        }
    ]
}
'@
```

エラーがなく正しくシナリオセットを登録できたら、[LINE Things のデバイス連携画面](https://line.me/R/nv/things/deviceLink) を開いてみましょう。
この画面を開くことで、連携済みのプロダクトのシナリオセットを更新することができます。(前回取得から24時間以上経過でも、自動更新されます)

正しく自動通信が動作している場合、LIFF を開いていなくても LINE Things dev board の OLED に `[BLE]` と表示されます。
`[BLE]` が表示されている場合には、ボードが接続されている状態ということです。

Android の場合には、以下のような自動通信を実行中であるという通知が表示されます。(iOS の場合には特に表示がありません)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29906/a332e6d2-4f2f-1d3e-3be5-fb47ecb22d6f.png" width="320">

## Step 4 - LINE Bot サーバーの設定

ここまでの手順で、LINE のサーバーへシナリオセットで指定された手順をもとに、通信内容を送信することができるようになりました。
次に、送信された通信内容を Messaging API の Webhook として LINE のサーバーから受け取り、メッセージを返信しましょう。

通常、LINE のサーバーから Webhook を受け取るには HTTPS に対応した Web サーバーが必要になるのですが、ちゃんと準備するには少々面倒な作業です。
そのため、今回は [ngrok](https://ngrok.com/) を利用して、ローカル環境で動かしたサーバーへリクエストをプロキシして手軽に Messaging API を体験したいと思います。
ここでは、Python 3 + Flask を利用した簡単な Messaging API を利用して Messaging API の Webhook を受け取り、メッセージを返答するような

### Webhook を受け取る Python + Flask サーバーを動かす

Webhook を受けとってメッセージを返信するために、以下のようなコードををローカルで動かします。
このコードは、Python 3 で書かれていて、Flask フレームワークを利用しています。
以下のコードを、`app.py` としてわかりやすい場所に保存してください。

#### サンプルコード

```python
from flask import Flask, request, abort
import json
import base64

from linebot import (
    LineBotApi, WebhookParser
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)

app = Flask(__name__)

ACCESS_TOKEN = "<YOUR_ACCESS_TOKEN>"
CHANNEL_SECRET = "<YOUR_CHANNEL_SECRET>"
line_bot_api = LineBotApi(ACCESS_TOKEN)
parser = WebhookParser(CHANNEL_SECRET)

@app.route("/")
def healthcheck():
    return 'OK'

@app.route("/callback", methods=['POST'])
def callback():
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    try:
        for event in parser.parse(body, signature):
            if event.type == "things":
                handle_things_event(event)
            else:
                handle_message(event)
    except InvalidSignatureError:
        print("Invalid signature. Please check your channel access token/channel secret.")
        abort(400)

    return 'OK'

def handle_things_event(event):
    if event.things.type != "scenarioResult":
        return
    if event.things.result.result_code != "success":
        app.logger.warn("Error result: %s", event)
        return

    if event.things.result.ble_notification_payload:
        button_state = base64.b64decode(event.things.result.ble_notification_payload)
        line_bot_api.reply_message(event.reply_token, TextSendMessage(text="ボタンが押されたよ %s" % (button_state)))

def handle_message(event):
    if event.type == "message" and event.message.type == "text":
        line_bot_api.reply_message(event.reply_token, TextSendMessage(text=event.message.text))

if __name__ == "__main__":
    app.run(debug=True)
```

次に、`app.py` の以下の部分を、[LINE Developers コンソール](https://developers.line.biz/)から取得した "アクセストークン" と "Channel Secret" に書き換えてください。

```python
ACCESS_TOKEN = "<YOUR_ACCESS_TOKEN>"
CHANNEL_SECRET = "<YOUR_CHANNEL_SECRET>"
```

### Python 3 と Flask のインストール

以下のような手順で Python 3 と Flask を準備することができます。
また、ここでは [line-bot-sdk-python](https://github.com/line/line-bot-sdk-python) を利用するので、そちらもインストールします。

#### Mac の方はこちら

[Homebrew](https://brew.sh/index_ja) と [pip](https://www.python.jp/install/windows/pip.html) を利用してインストールします。
以下のコマンドを実行するだけです。

```
$ brew install python3
$ pip3 install flask line-bot-sdk
```

#### Windows の方はこちら

以下の手順に従って、Python 3 をインストールしてください。
**必ず、"Add Python 3.x to PATH" にチェックを入れてください。**
[Python3のインストール - python.jp](https://www.python.jp/install/windows/install_py3.html)

その後、PowerShell またはコマンドプロンプトを開いて、以下のコマンドを実行します。

```shell
> pip install flask line-bot-sdk
```

### LINE Bot アプリケーションサーバーの起動

Python を利用してアプリケーション・サーバーを起動するためには、以下のコマンドを実行します。
Flask は標準で、5000 番ポートを利用します。

```shell
## Mac
$ python3 app.py
## Windows
> python app.py
```

起動できたら、http://localhost:5000/ を開いてみましょう。
"OK" が表示されたら問題ありません。

### ngrok を利用したプロキシ

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29906/b2e04367-6a99-b7ac-faca-f78f78e0ec94.png" width="480">

[ngrok](https://ngrok.com/) は、ローカルの HTTP ポートをインターネット上へプロキシしてくれる便利なツールです。
一時的にローカルの PC で Messaging API の動作検証やデバッグしたい場合には、ngrok を使うことでとてもお手軽になります。
しかし、一歩間違えるとセキュリティ上のリスクもあるので、慎重に利用してください。

[ngrok の Download page](https://ngrok.com/download) から、ngrok のバイナリをダウンロードし、展開します。
今回は Flask の 5000 番ポートを HTTP でプロキシするので、以下のように `ngrok` コマンドを実行します。

```shell
## Mac
$ ./ngrok http 5000
## Windows
> .¥ngrok.exe http 5000

ngrok by @inconshreveable                                                                                                                                                                      (Ctrl+C to quit)
                                                                                                                                                                                                               
Session Status                online                                                                                                                                                                           
Account                       Hirotaka Kawata (Plan: Free)                                                                                                                                                     
Update                        update available (version 2.3.28, Ctrl-U to update)                                                                                                                              
Version                       2.3.25                                                                                                                                                                           
Region                        United States (us)                                                                                                                                                               
Web Interface                 http://127.0.0.1:4040                                                                                                                                                            
Forwarding                    http://7750a774.ngrok.io -> http://localhost:5000                                                                                                                                
Forwarding                    https://7750a774.ngrok.io -> http://localhost:5000                                                                                                                               
                                                                                                                                                                                                               
Connections                   ttl     opn     rt1     rt5     p50     p90                                                                                                                                      
                              0       0       0.00    0.00    0.00    0.00   
```

表示された画面に
`Forwarding                    https://7750a774.ngrok.io -> http://localhost:5000`
と表示されている部分が、プロキシされた URL になります。

### Webhook 送信先の設定

[LINE Developers コンソール](https://developers.line.biz/) を開いて、LINE Things プロダクトを登録したチャネルの Webhook 送信を以下のように設定してください。

- Webhook送信: **利用する**
- Webhook URL: **上記で取得した ngrok の URL + `/callback`**
  - 例) `https://7750a774.ngrok.io/callback`

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29906/f1f88022-c280-45d7-546f-30241b6d9a49.png" width="480">

これで、LINE サーバーが受信した自動通信の実行結果を、Webhook URL に送信する準備ができました。

### 動作確認

Webhook の設定が完了したら、自動通信の動作確認をしてみましょう。
ボード上のボタンを押して、以下のようにメッセージが送信されたら成功です。

メッセージに表示される異ペイロードは以下の通りです。

- LINE Things dev board の場合
  - 1byte 目がボタンの番号、2byte 目がボタンの状態です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29906/d8d0e75c-275b-d378-4312-4faca80573f0.png" width="320">

LINE Things の自動通信機能は楽しんでいただけたでしょうか？
以上で、基本編は終了です。**おつかれさまでした！**

## 応用編 - LINE Things development board 利用

時間が余った方は、以下の応用編に挑戦してみてください。

### 押すボタンによってメッセージを変えてみる

`SW1` と `SW2` どちらのボタンを押したかによって、メッセージを出し分けてみましょう。
受け取った `bleNotificationPayload` の 1byte 目の情報を元に判断しましょう。

BASE64 のでコード部分を以下のように変更すると、`button` と `state` の2つの変数に、ボタンの番号と状態をそれぞれ入れることができます。
あとは、`button` の情報をもとにどちらのボタンであるかを判断することができます。

```python
button, state = base64.b64decode(event.things.result.ble_notification_payload)
```

### 温度センサーを利用してみる

次に、温度センサーの値を使って、変化を通知してみましょう。
ここからは、少々レベルが上がります。

#### LINE Things dev board で温度センサーの情報を受け取るには？

LINE Things development board には、温度センサーから取得した温度を Notify する GATT Characteristic が用意されています。
この Characteristic を利用して、現在の温度を自動通信で受け取ってみましょう。
詳しい仕様は、LINE Things dev board の[デフォルトファームウェアについて](https://github.com/techno/line-things-dev-board/blob/cpulabs/docs/default-firmware.md)を参照してください。

```
USER_SERVICE_UUID "f2b742dc-35e3-4e55-9def-0ce4a209c552"
NOTIFY_TEMP_CHARACTERISTIC_UUID "fe9b11a8-5f98-40d6-ae82-bea94816277f"
```

初期状態では、10秒間隔でセルシウス度(℃)を100倍した値が2byteで、送信されるようになっています。
そのまま10秒間隔でも良いのですが、LINE Things dev board のデフォルトファームウェアでは、Notify の間隔を変更する事ができるようになっています。
今回は、少し複雑なシナリオを構成するために、あえて Notify 間隔をもっとはやめの1秒に設定してみましょう。

この設定は、下記の Characteristic に以下のような形式で、18byte のデータを書き込む必要があります。
0 がたくさん並んでいるのは、他の設定と Characteristic を共有してて、固定長だからです。

```c
USER_SERVICE_UUID "f2b742dc-35e3-4e55-9def-0ce4a209c552"
COMMAND_WRITE_CHARACTERISTIC_UUID "5136e866-d081-47d3-aabc-a2c9518bacd4"
```
```js
// source: 0 - OFF, 1 - ON
// interval: 0 - 65535 in milliseconds
[18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, source, interval >> 8, interval & 0xff]
```

つまり、温度センサーの情報を1秒間隔で Notify を受け取りたい場合には以下のような手順が必要です。

- 温度センサーの値を Notify により受け取る設定をする
  - Service UUID: `f2b742dc-35e3-4e55-9def-0ce4a209c552`
  - Characteristic UUID: `fe9b11a8-5f98-40d6-ae82-bea94816277f`
- 温度センサーの Notify 間隔を設定するコマンドを Write する
  - `source`: 1 (ON), `interval`: 1000ms
  - Service UUID: `f2b742dc-35e3-4e55-9def-0ce4a209c552`
  - Characteristic UUID: `5136e866-d081-47d3-aabc-a2c9518bacd4`
  - Write data: `[18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 232]` => `0x1200000000000000000000000000000103e8`

#### 温度センサーの値を受け取るシナリオセットの登録

まず、温度センサーの値の Notify を受け取るための**シナリオ**は、以下のような設定になります。
トリガを `BLE_NOTIFICATION` に設定して、Service UUID と Characteristic UUID を指定します。
Notify を受け取ったあと、ただそのペイロードを受け取れればよいだけなので、アクションは空に設定します。

```json
{
    "trigger": {
        "type": "BLE_NOTIFICATION",
        "serviceUuid": "f2b742dc-35e3-4e55-9def-0ce4a209c552",
        "characteristicUuid": "fe9b11a8-5f98-40d6-ae82-bea94816277f"
    },
    "actions": [
    ]
}
```

次に、接続した直後に温度センサーの Notify 間隔を行う設定を Write する**シナリオ**は、以下のような設定になります。
Service UUID と Characteristic UUID, そして書き込みする `data` を指定します。

```json
{
    "trigger": {
        "type": "IMMEDIATE"
    },
    "actions": [
        {
            "type": "GATT_WRITE",
            "serviceUuid": "f2b742dc-35e3-4e55-9def-0ce4a209c552",
            "characteristicUuid": "5136e866-d081-47d3-aabc-a2c9518bacd4",
            "data": "EgAAAAAAAAAAAAAAAAAAAQPo"
        }
    ]
}
```

`data` には BASE64 形式のバイナリデータを指定する必要があります。
今回は、`0x1200000000000000000000000000000103e8` を送信したいので `EgAAAAAAAAAAAAAAAAAAAQPo` となります。
Mac や Linux では、以下のようなコマンドラインでバイナリから BASE64 へ変換できます。
または、[Binary to base64](https://cryptii.com/pipes/binary-to-base64) ツールがインターネット上に多数あるので、これを利用してもよいでしょう。

```shell
$ echo -n "\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x03\xe8" | base64
EgAAAAAAAAAAAAAAAAAAAQPo
```

これらの2つのシナリオをもとに、今回は以下のような**シナリオセット**を登録します。
`autoClose` は `false` に設定して、常時接続しずっと Notify を待ち受けるような設定とします。

**Mac のコマンド例**

```shell
$ curl -X PUT https://api.line.me/things/v1/products/<YOUR PRODUCT ID>/scenario-set \
-H 'Authorization: Bearer <YOUR CHANNEL ACCESS TOKEN>' \
-H 'Content-Type:application/json' \
-d '
{
    "autoClose": false, 
    "suppressionInterval": 0,  
    "scenarios": [
        {
            "trigger": {
                "type": "BLE_NOTIFICATION",
                "serviceUuid": "f2b742dc-35e3-4e55-9def-0ce4a209c552",
                "characteristicUuid": "fe9b11a8-5f98-40d6-ae82-bea94816277f"
            },
            "actions": [
            ]
        },
        {
            "trigger": {
                "type": "IMMEDIATE"
            },
            "actions": [
                {
                    "type": "GATT_WRITE",
                    "serviceUuid": "f2b742dc-35e3-4e55-9def-0ce4a209c552",
                    "characteristicUuid": "5136e866-d081-47d3-aabc-a2c9518bacd4",
                    "data": "EgAAAAAAAAAAAAAAAAAAAQPo"
                }
            ]
        }
    ]
}'
```

**Windows のコマンド例**

```shell
> curl.exe -X PUT https://api.line.me/things/v1/products/<YOUR PRODUCT ID>/scenario-set `
-H 'Authorization: Bearer <YOUR CHANNEL ACCESS TOKEN>' `
-H 'Content-Type:application/json' `
-d @'
{
    "autoClose": false, 
    "suppressionInterval": 0,  
    "scenarios": [
        {
            "trigger": {
                "type": "BLE_NOTIFICATION",
                "serviceUuid": "f2b742dc-35e3-4e55-9def-0ce4a209c552",
                "characteristicUuid": "fe9b11a8-5f98-40d6-ae82-bea94816277f"
            },
            "actions": [
            ]
        },
        {
            "trigger": {
                "type": "IMMEDIATE"
            },
            "actions": [
                {
                    "type": "GATT_WRITE",
                    "serviceUuid": "f2b742dc-35e3-4e55-9def-0ce4a209c552",
                    "characteristicUuid": "5136e866-d081-47d3-aabc-a2c9518bacd4",
                    "data": "EgAAAAAAAAAAAAAAAAAAAQPo"
                }
            ]
        }
    ]
}
'@
```

### Bot の変更

Bot の `bleNotificationPayload` 受け取る部分を以下のように変更しましょう。
温度の値は、100倍された値が 2byte で送られて来るので、まず int に変換したあと、100で割っています。
(通常、BLE のペイロードはリトルエンディアンが利用されますが、LINE Things dev board はすべてビッグエンディアンです)

```python
    if event.things.result.ble_notification_payload:
        payload = base64.b64decode(event.things.result.ble_notification_payload)
        temperature = int.from_bytes(payload, 'big') / 100.0
        line_bot_api.reply_message(event.reply_token, TextSendMessage(text="温度は %s" % (temperature)))
```

1秒毎に温度を通知するメッセージが送られてきたら成功です。
実際には、LINE Things dev board は内部で様々な処理をしている (センサーの値をディスプレイに表示したり) ので、Notify の間隔は多少遅延する場合があります。

温度が一定以上の数値になったらメッセージを送信したり、急激な温度変化を検知したりしてみましょう。

## [おまけ] LINE Things 自動通信機能を体験しよう - LINE Things Starter 利用

<img src="https://qiita-image-store.s3.amazonaws.com/0/29906/0bb157a3-e360-22eb-e702-bfdf7b26c835.jpeg" width="480">

**[LINE Things Developer Trial ハンズオン](https://qiita.com/hktechno/items/bb83cc898c75819b2664) の続きの内容になります**

**[LINE Things Starter](https://github.com/line/line-things-starter) を利用利用してハンズ・オンしたい方向けの章です**
**[LINE Things development board](https://github.com/line/line-things-dev-board) を利用する場合には、[こちら](#line-things-自動通信機能を体験しよう)を参照してください**

### LINE Things Starter でボタンの変化を受け取るには？

LINE Things Starter には、ボタンの状態を Notify する GATT Characteristic が用意されています。
ボタンの状態が変化するたびに、`0` や `1` など、ボタンの状態が Notify されるようになっています。
この Characteristic を利用して、ボタンが押された通知を自動通信で受け取ってみましょう。

```cpp
#define USER_SERVICE_UUID "<YOUR_SERVICE_UUID>"
#define NOTIFY_CHARACTERISTIC_UUID "62FBD229-6EDD-4D1A-B554-5C4E1BB29169"
```

### シナリオセットの登録

実際に上記の設定をもとに、シナリオセットを構築して登録してみましょう。
詳しい仕様は、[自動通信向けシナリオ管理API](https://developers.line.biz/ja/reference/line-things/#auto-communication-scenario-management-api) を参考にしてください。

#### ボタンの変化を受け取るシナリオセットを考える

まず、IO 変化の Notify を受け取るための**シナリオ**は、以下のような設定になります。
トリガを `BLE_NOTIFICATION` に設定して、Service UUID と Characteristic UUID を指定します。
Notify を受け取ったあと、ただそのペイロードを受け取れればよいだけなので、アクションは空に設定します。

```json
{
    "trigger": {
        "type": "BLE_NOTIFICATION",
        "serviceUuid": "<YOUR_SERVICE_UUID>",
        "characteristicUuid": "62FBD229-6EDD-4D1A-B554-5C4E1BB29169"
    },
    "actions": [
    ]
}
```

このシナリオをもとに、今回は以下のような**シナリオセット**を登録します。
今回は、シナリオは1つしかないので、そのままの内容を設定します。
`autoClose` は `false` に設定して、常時接続しずっと Notify を待ち受けるような設定とします。

```json
{
    "autoClose": false, 
    "suppressionInterval": 0,  
    "scenarios": [
        {
            "trigger": {
                "type": "BLE_NOTIFICATION",
                "serviceUuid": "<YOUR_SERVICE_UUID>",
                "characteristicUuid": "62FBD229-6EDD-4D1A-B554-5C4E1BB29169"
            },
            "actions": [
            ]
        }
    ]
}

```

#### 自動通信向けシナリオ管理 API を使ってシナリオセットを登録

シナリオセットが完成したところで、実際にこのシナリオセットを API で LINE Things プラットフォームに登録してみましょう。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29906/5acb3bbb-4757-ffa7-f9f6-6dd711dff5ce.png" width="640">

API を利用するには、チャネルのアクセストークンが必要になります。[LINE Developers コンソール](https://developers.line.biz/) から取得してください。
また、シナリオセットを登録する LINE Things のプロダクトのプロダクト ID が必要になります。プロダクト登録 API のレスポンスに含まれていますが、忘れてしまった方は、以下のような API をリクエストして取得してください。

```shell
## Mac
$ curl -X GET https://api.line.me/things/v1/trial/products -H 'Authorization: Bearer <YOUR CHANNEL ACCESS TOKEN>'
## Windows
> curl.exe -X GET https://api.line.me/things/v1/trial/products -H 'Authorization: Bearer <YOUR CHANNEL ACCESS TOKEN>'
```

アクセストークンとプロダクト ID が取得できたら、`curl` コマンドで以下のように API をリクエストします。
Windows をお使いの方は、必ず **PowerShell** を使ってください。通常のコマンドプロンプトには対応していません。
`<YOUR PRODUCT ID>` と `<YOUR CHANNEL ACCESS TOKEN>` にそれぞれ、プロダクト ID とアクセストークンを入れてください。

**Mac や Linux の方はこちら**

```shell
$ curl -X PUT https://api.line.me/things/v1/products/<YOUR PRODUCT ID>/scenario-set \
-H "Authorization: Bearer <YOUR CHANNEL ACCESS TOKEN>" \
-H 'Content-Type:application/json' \
-d '
{
    "autoClose": false, 
    "suppressionInterval": 0,  
    "scenarios": [
        {
            "trigger": {
                "type": "BLE_NOTIFICATION",
                "serviceUuid": "<YOUR_SERVICE_UUID>",
                "characteristicUuid": "62FBD229-6EDD-4D1A-B554-5C4E1BB29169"
            },
            "actions": [
            ]
        }
    ]
}'
```

**Windows の方はこちら**

```shell
> curl.exe -X PUT https://api.line.me/things/v1/products/<YOUR PRODUCT ID>/scenario-set `
-H 'Authorization: Bearer <YOUR CHANNEL ACCESS TOKEN>' `
-H 'Content-Type:application/json' `
-d @'
{
    \"autoClose\": false, 
    \"suppressionInterval\": 0,  
    \"scenarios\": [
        {
            \"trigger\": {
                \"type\": \"BLE_NOTIFICATION\",
                \"serviceUuid\": \"<YOUR_SERVICE_UUID>\",
                \"characteristicUuid\": \"62FBD229-6EDD-4D1A-B554-5C4E1BB29169\"
            },
            \"actions\": [
            ]
        }
    ]
}
'@
```

エラーがなく正しくシナリオセットを登録できたら、[LINE Things のデバイス連携画面](https://line.me/R/nv/things/deviceLink) を開いてみましょう。
この画面を開くことで、連携済みのプロダクトのシナリオセットを更新することができます。(前回取得から24時間以上経過でも、自動更新されます)

Android の場合には、以下のような自動通信を実行中であるという通知が表示されます。(iOS の場合には特に表示がありません)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29906/a332e6d2-4f2f-1d3e-3be5-fb47ecb22d6f.png" width="320">

[Step 4 - LINE Bot サーバーの設定](#step-4---line-bot-サーバーの設定)に進んでください。


## 開発のコツとトラブルシューティング

基本的な点については、[LINE Things Developer Trial ハンズオン - 開発のコツとトラブルシューティング](https://qiita.com/hktechno/items/bb83cc898c75819b2664#%E9%96%8B%E7%99%BA%E3%81%AE%E3%82%B3%E3%83%84%E3%81%A8%E3%83%88%E3%83%A9%E3%83%96%E3%83%AB%E3%82%B7%E3%83%A5%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0) を参照してください。

### 配布済みのシナリオセットはいつ更新されるの？

LINE Things のデバイス連携画面を開くと、シナリオセットが更新されます。
また、前回更新から24時間以上経過後に再度自動で取得します。

### LIFF 上の通信と自動通信を共存させることはできる？

できます。
BLE feature が有効な LIFF が開かれると、自動通信が停止するようになっています。
現状、iOS と Android で多少挙動が異なりますが、LIFF で通信している間に自動通信が行われることはありません。

### シナリオが思った通りに動いてくれない

まず、[自動通信を利用する際の注意点について](https://developers.line.biz/ja/docs/line-things/notes-on-using-auto-communication/) を確認してください。

それでも正しく動かない場合、端末によっては Bluetooth LE の接続が不安定である場合があります。(特に Android の場合)