Edited at

#linethings でバイクの盗難防止装置作ってみた

LINE Things anti-theft system

2019年4月にリリースされたLINE Things 自動通信機能を利用してバイクの盗難防止装置を作ってみました。本投稿では、その概要と開発手法を解説します。自動通信機能の詳しい解説を知りたい方は公式ブログをご確認下さい。


作ったもの


  • 帰宅後バイクのマフラーにセットし電源を入れると動作開始

  • マフラーの温度、加速度センサーの値をLINE App経由でサーバーに送信し続ける

  • 値が著しく変化すると盗難されそうになっていると判断し、LINEに通知する


開発


デバイス側

今回はセンサーが内蔵されているLINE Things development boardを利用します。


ファームウェアの書き込み

こちらを参考に、Arduino IDEのセットアップを完了させます。空のスケッチを書き込みエラーが出ないことを確認します。

次に、development board用のライブラリをインクルードします。スケッチ > ライブラリをインクルード > ライブラリを管理と進み、検索窓にキーワードを入力してフィルタリングし、以下を追加します。

検索キーワード
インストールするライブラリ

MMA8452Q
SparkFun MMA8452Q Accelerometer by SparkFun Electronics

Adafruit SSD1306
Adafruit SSD1306 by Adafruit

Adafruit GFX Library
Adafruit GFX Library by Adafruit

things_temp_libについては手動でインクルードする必要があります。以下のコマンドでzipに固め、スケッチ > ライブラリをインクルード > .ZIP形式のライブラリをインクルードからインクルードして下さい。

$ git clone https://github.com/line/line-things-dev-board.git

$ cd line-things-dev-board/library/
$ zip -r linethings_temp_lib.zip linethings_temp_lib/

新規ファイルを作成し、https://github.com/line/line-things-dev-board/blob/master/arduino/linethings-dev-default/linethings-dev-default.inoの中身をコピーして書き込み、エラーが出ないことを確認します。


Trial Productの作成

Developer CenterからMessaging APIのチャネルを作成し、アクセストークンを取得します。

また自動通信においてもLIFFの作成は必須のため、適当なURLでBLE featureをONにしたLIFFを作成し、app/のあとのIDを控えておいて下さい。

取得したアクセストークを利用し、ターミナル等から以下のコマンドを実行します。

$ curl -X POST https://api.line.me/things/v1/trial/products \

-H 'Authorization: Bearer {YOUR_CHANNEL_ACCESS_TOKEN}' \
-H 'Content-Type:application/json' \
-d '{
"name": "Devboard",
"liffId": "{LIFF_ID}"
}'

以下のような形で値が返却されるので、控えておいて下さい。

{

"id": 000000000000,
"name": "Sample Product",
"type": "BLE",
"channelId": 00000000,
"actionUri": "line://app/XXXXXXXX-XXXXXXXX",
"serviceUuid": "",
"psdiServiceUuid": "e625601e-9e55-4597-a598-76018a0d293d",
"psdiCharacteristicUuid": "26e2b12b-85f0-4f3f-9fdd-91d114270e6e"
}

戻ってきた値を控えておきます。ついでにMessaging APIチャネルのQRコードを撮影し友だち追加をし、アプリの設定画面からペアリングを完了させておきます。


ファームウェアのUUIDの値を書き換えて書き込み

define DEFAULT_ADVERTISE_UUID "f2b742dc-35e3-4e55-9def-0ce4a209c552"

.
.
define USER_SERVICE_UUID "f2b742dc-35e3-4e55-9def-0ce4a209c552"

の2行の値を、Trial Product作成APIを叩いた戻り値内のserviceUuidのものに置き換え、更に下部を以下の通り変更し、

// Notify Timing

// コメントアウト
// if (g_flag_notify && Bluefruit.connected()) {
int16_t sw1 = (sw1_value) ? 1 : 0;
int16_t sw2 = (sw2_value) ? 1 : 0;
int16_t tx_frame[6] = {
(int16_t) temperature * 100,
accel.cx * 1000,
accel.cy * 1000,
accel.cz * 1000,
sw1,
sw2
};
blesv_devboard_notify.notify((uint8_t*)tx_frame, sizeof(tx_frame));
g_flag_notify = 0;
// コメントアウト
//}
// delay(100);
delay(10000); // 変更

書き込みます。

キャッシュが残ってしまうことがあるので、連携解除、ペアリング解除、LINEアプリの再起動、Dev Boardの情報リセット(SW1を押しながら起動)等をお試し下さい。


シナリオセットの登録

最後にTrial Productにシナリオセットを登録し、development boardからの値を自動通信を利用してNotifyするよう設定しましょう。以下のコマンドを実行します。

curl -v -X PUT https://api.line.me/things/v1/products/<TRIAL 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": "e90b4b4e-f18a-44f0-8691-b041c7fe57f2"
},
"actions": [
]
}
]
}'

これでペアリングが終わっている端末がBluetoothの範囲にいる間でかつLIFFを開いていない時には、スケッチに記述の通り、10秒おきに以下のようなJSONがWebhookとしてBotのWebhook URLに飛ぶようになります。

{

"events": [
{
"type": "things",
"replyToken": "",
"source": {
"userId": "",
"type": "user"
},
"timestamp": 1557027988663,
"things": {
"deviceId": "",
"result": {
"scenarioId": "01D99MDBF1HFTV16FFD0YMX8G0",
"revision": 2,
"startTime": 1557027978,
"endTime": 1557027988,
"resultCode": "success",
"bleNotificationPayload": "jArd/wIA9gMAAAAA/+nVpQ==",
"actionResults": []
},
"type": "scenarioResult"
}
}
],
"destination": ""
}


サーバー側


監視サーバーの開発

監視サーバーはdevelopment board上のセンサーの値を前項記載のフォーマットでWebhookを通じて定期的に値を受け取り、以下の条件が発生するとLINEアプリに通知します。


  • 加速度センサーのx,y,z合計値の前回との差分が0.15以上

  • 温度センサーの値が前回との差分が10度以上

Heroku用のプロジェクトをこちらで公開しているのでgit cloneして/static/liff-starter.jsUSER_SERVICE_UUIDの値を前項と同じものに書き換え、Herokuにデプロイします。データベースにRedisを利用しておりますので、Add onから有効化して下さい。

値の読み取りの部分だけ特有の形になりますので貼っておきます。

    # Read value end decode

decoded = base64.b64decode(
event["things"]["result"]["bleNotificationPayload"])

temperature = float(numpy.frombuffer(
buffer=decoded, dtype='int16', count=1, offset=0)[0] / 100.0)

acx = float(numpy.frombuffer(buffer=decoded,
dtype='int16', count=1, offset=2)[0] / 1000.0)
acy = float(numpy.frombuffer(buffer=decoded,
dtype='int16', count=1, offset=4)[0] / 1000.0)
acz = float(numpy.frombuffer(buffer=decoded,
dtype='int16', count=1, offset=6)[0] / 1000.0)
accelerometer = acx + acy + acz

デプロイが完了したら、LIFFのエンドポイントURLをhttps://<your app name>.herokuapp.com/に、Messaging APIのWebhookを利用するをONにしWebhook URLをhttps://<your app name>.herokuapp.com/callbackに設定します。

注意点として、LIFFはキャッシュされることがあります。その際はtemplates/index.html下部のliff-starter.js読み込み部の?id=XXXXを置き換えると再度読み込まれます。


デモ

自分のバイクで試してみたのですが、急激に温度が上がるところがなく温度検知の部分はデモできず。

傾き検知 → LINEで通知は以下のようになります。見えにくいですがサイドスタンドで駐車中のバイクを真っ直ぐにすると通知が来ていることが分かります。

なおUSBからの給電になっていますが、はんだ付けすれば電池駆動も可能です。

@ufoo68さんの記事「LINE Thingsでパトランプを回してみた」と組み合わせてパトランプが回るようにしたりするのも面白いかもしれませんね。


もっと詳しく知りたい方は

公式ドキュメント

https://developers.line.biz/ja/docs/line-things/about-auto-communication/

公式ブログ

https://engineering.linecorp.com/ja/blog/line-things-automatic-communication/

また現在のところ、以下のイベントが予定されています。両方共既に満員ですがキャンセルも出ると思いますので是非お申し込み下さい。

LINE Things 自動通信機能のハンズオン(LINE Things開発者によるハンズオン)

https://code4osaka.connpass.com/event/129124/

デジットハッカソン令和(LINE Things開発者がメンターとして参加)

https://digithack.jp/


他LINE Things関連記事

M5StickCでLINE Thingsの自動通信機能を試してみた

LINE Thingsでウェアラブルデバイスつくってみた

[LINE Things とM5Stack で子どもの帰宅/外出を通知できる仕組みを作ってみた]

https://qiita.com/sumihiro3/items/965998815a0b975a465a


まとめ

これまではLIFFを経由した通信のみでしたが、自動通信機能が追加され出来ることが大幅に増えました。また、開発も簡単でLINEを利用することでユーザーにとって格段にIoT機器の導入の障壁が下がることが予想されます。

皆様も是非何か作ってみて下さい。

既に製品化やリリース済み製品への導入をお考えの方はLINE Things Partnership Formからお問い合わせ頂くとスムーズです。