LINE Things切断を検出してメッセージを送るナレッジ obniz編
ProtoOut LINE Things ハッカソンで挙がった技術ポイントのひとつ、LINE Things切断を検出してメッセージを送るナレッジ obniz編 をまとめました。
今回は、obnizでやってみます。
obnizのソースコードは変更しない
今回、obnizのソースは変更しません。LIFFのみで対応し切断を検出してLIFFからからチャットへメッセージを投げます。
Bluetooth切断のシチュエーション
LINE ThingsにおけるBluetooth切断のシチュエーションを想像してみましょう。Bluetooth切断が生じたときに、BluetoothデバイスでもスマートフォンのLINEアプリ側でも検出は可能です。
しかし、問題はそこからどうやって情報を伝えるかです。
- Bluetoothデバイスでも検出可能だが、インターネットに繋がっていないのでその状況をメッセージで外に出すのは難しい
- もちろんobnizの場合は、インターネット経由で動作させている前提で動いていますが、その仕組の部分は割愛
- obnizが何かしらのハードウェアと連携していて切断時に何かをするときには有効
- スマートフォンのLINEアプリ側もLIFFの仕組みで切断取得できる。
- こちらはスマホがオンラインで場合が多くLINEへメッセージを伝えることもできるケースが多い。
ということを考えると、スマートフォンのLINEアプリ側でLIFFを使うやり方のほうが、データを取り回す場合でも扱いやすいので、今回は採用します。
切断メッセージにメッセージ加える
切断イベント自体は、LIFFのサンプルにも既に書かれています。liffConnectToDeviceのところで、gattserverdisconnectedイベントが発生しています。
gattserverdisconnectedイベント
ここにメッセージを出すようにします。<a href="https://developers.line.biz/ja/reference/liff/#send-messages" target="_blank">liff.sendMessages</a>を使って、以下のように変更して、メッセージ接続時と切断時にメッセージを出すようにしています。
LIFFからその時写っているチャットにメッセージを打ち込むイメージです。
function liffConnectToDevice(device) {
device.gatt.connect().then(() => {
document.getElementById("device-name").innerText = device.name;
document.getElementById("device-id").innerText = device.id;
// Show status connected
uiToggleDeviceConnected(true);
// 接続時メッセージ
liff.sendMessages([
{
type:'text',
text:'LINE Thingsデバイスがつながりました!'
}
])
.then(() => {
console.log('message sent');
})
.catch((err) => {
console.log('error', err);
});
// Get service
device.gatt.getPrimaryService(USER_SERVICE_UUID).then(service => {
liffGetUserService(service);
}).catch(error => {
uiStatusError(makeErrorMsg(error), false);
});
device.gatt.getPrimaryService(PSDI_SERVICE_UUID).then(service => {
liffGetPSDIService(service);
}).catch(error => {
uiStatusError(makeErrorMsg(error), false);
});
// Device disconnect callback
// BLE切断イベント時でメッセージをLIFFから出す
// LIFFであればスマホがオンラインで場合が多くLINEへメッセージを伝えることもできるケースが多い。
const disconnectCallback = () => {
// Show status disconnected
uiToggleDeviceConnected(false);
// メッセージ
liff.sendMessages([
{
type:'text',
text:'LINE ThingsデバイスがBluetooth切断されました!'
}
])
.then(() => {
console.log('message sent');
})
.catch((err) => {
console.log('error', err);
});
// Remove disconnect callback
device.removeEventListener('gattserverdisconnected', disconnectCallback);
// Reset LED state
ledState = false;
// Reset UI elements
uiToggleLedButton(false);
uiToggleStateButton(false);
// Try to reconnect
initializeLiff();
};
device.addEventListener('gattserverdisconnected', disconnectCallback);
}).catch(error => {
uiStatusError(makeErrorMsg(error), false);
});
}
実際に動かしてみる
まず、メッセージを受け付けたいチャットでLIFFを開きたいので、LIFF URLをメモしておきます。
チャットにこのLIFF URLを送ります。
チャットでこのURLをクリックしてLIFFを出します。
LIFFが出ます。接続されます。
この時点でLIFFを閉じてみると接続時のメッセージが表示されてます。2つ出たのは一度閉じて2回目をつなげたからです。
遠くへ行ってBLE切断を再現します。
切断メッセージが送信されました!
ソースコード
動くソースコードはこちらにあります。
<a href="https://github.com/1ft-seabass/line-things-obniz-src/tree/master/liff-app-disconnect" target="_blank">line-things-obniz-src/liff-app-disconnect at master · 1ft-seabass/line-things-obniz-src</a>
余談:obniz側の切断検出
obniz側の切断検出はこちらです。
<a href="https://github.com/1ft-seabass/line-things-obniz-src/blob/master/liff-app-disconnect/obniz.js" target="_blank">line-things-obniz-src/obniz.js at master · 1ft-seabass/line-things-obniz-src</a>
obniz BLE側で切断は検出できます。obnizで動かすハードウェアのほうで、なにかしら切断に応じた操作をする場合には使えると思います。
// obniz BLE側で切断は検出できるが、問題はどう出すか。
// 閉じたBLEの状況では素直にやると他に伝えるすべがないので、検出のみ。
// obnizの特性を利用すれば、Wi-Fi経由でメッセージが出せなくもない。
obniz.ble.peripheral.onconnectionupdates = async function(data){
console.log("remote device ", data.address, data.status);
if (data.status === "connected") {
console.log("connected!!")
// 99で区別する
// await notifyCharacteristic.writeWait([99]);
// notifyCharacteristic.notify();
} else if (data.status === "disconnected") {
console.log("disconnected!!")
// 98で区別する
// await notifyCharacteristic.writeWait([98]);
// notifyCharacteristic.notify();
}
};
Discussion