##obniz「今から帰るね!」とLINEでメッセージ送ると、奥さんの好きな曲が流れ、LEDランプで自宅の到着時間を教えてくれる仕組み!
仕事が終わって携帯を見ると、いつも奥さんから「何時に帰ってくる?」「何時の電車に乗る?」といったLINEメッセージが来ている。これが気になる理由は、夕食の準備やお風呂を沸かす準備があるからだ!
「今から帰るね!」とLINEメッセージを送ると自宅のobnizに連携させたスピーカーから、奥さんの好きな音楽が流れ、時間の経過とともに。LEDランプの色が変化する仕組みを制作したいと思いました。
(例)自宅到着1時間前:赤色ランプ 30分前:黄色ランプ 10分前:青色など
##作成した仕組み(未完成)
Visual Studio Codeを使い、LINEBot×obniz(スピーカーとLEDを連携させた仕組み)制作
まだ、制作途中段階で、好きな音楽も制作出来ていない状況です。
音階周波数で制作したいと思っております)
##開発環境
・LINEBot公式アカウント解説
・Visual Studio Code基本操作
・LINEBot参考ページ
・obniz公式ドキュメント(起動とWi-Fi設定)
・obniz公式ドキュメント(Speaker)
##準備
機材を準備
・LEDは、obniz0~5番繋ぐ。
・スピーカーを10番~11番に繋ぐ。
・Visual Studio Codeで、LINEBotとobnizを連携させる。
・LINEBot準備
Botアカウントの準備は、前回と同様に、こちらの記事
##共通テンプレート
テンプレートをもとに作成しました!
サンプルコード **(クリックで表示)**
'use strict';
// ########################################
// 初期設定など
// ########################################
// パッケージを使用します
const express = require('express');
const line = require('@line/bot-sdk');
const axios = require('axios');
// ローカル(自分のPC)でサーバーを公開するときのポート番号です
const PORT = process.env.PORT || 3000;
// Messaging APIで利用するクレデンシャル(秘匿情報)です。
const config = {
channelSecret: '作成したBotのチャネルシークレット',
channelAccessToken: '作成したBotのチャネルアクセストークン'
};
// ########## ▼▼▼ サンプル関数 ▼▼▼ ##########
(この行をサンプル関数丸ごと全部と置き換えてね)
// ########## ▲▲▲ サンプル関数 ▲▲▲ ##########
// ########################################
// LINEサーバーからのWebhookデータを処理する部分
// ########################################
// LINE SDKを初期化します
const client = new line.Client(config);
// LINEサーバーからWebhookがあると「サーバー部分」から以下の "handleEvent" という関数が呼び出されます
async function handleEvent(event) {
// 受信したWebhookが「テキストメッセージ以外」であればnullを返すことで無視します
if (event.type !== 'message' || event.message.type !== 'text') {
return Promise.resolve(null);
}
// サンプル関数を実行します
return sampleFunction(event);
}
// ########################################
// Expressによるサーバー部分
// ########################################
// expressを初期化します
const app = express();
// HTTP POSTによって '/webhook' のパスにアクセスがあったら、POSTされた内容に応じて様々な処理をします
app.post('/webhook', line.middleware(config), (req, res) => {
// 検証ボタンをクリックしたときに飛んできたWebhookを受信したときのみ以下のif文内を実行
if (req.body.events.length === 0) {
res.send('Hello LINE BOT! (HTTP POST)'); // LINEサーバーに返答します(なくてもよい)
console.log('検証イベントを受信しました!'); // ターミナルに表示します
return; // これより下は実行されません
} else {
// 通常のメッセージなど … Webhookの中身を確認用にターミナルに表示します
console.log('受信しました:', req.body.events);
}
// あらかじめ宣言しておいた "handleEvent" 関数にWebhookの中身を渡して処理してもらい、
// 関数から戻ってきたデータをそのままLINEサーバーに「レスポンス」として返します
Promise.all(req.body.events.map(handleEvent)).then((result) => res.json(result));
});
// 最初に決めたポート番号でサーバーをPC内だけに公開します
// (環境によってはローカルネットワーク内にも公開されます)
app.listen(PORT);
console.log(`ポート${PORT}番でExpressサーバーを実行中です…`);
ソースコード **(クリックで表示)**
const Obniz = require('obniz');
const { exit } = require('process');
const obniz = new Obniz('obniz_ID'); // Obniz_IDに自分のIDを入れます。今回は、消してます。
// 任意の秒数待つことができる関数
// 参考: https://qiita.com/suin/items/99aa8641d06b5f819656
const sleep = (msec) => new Promise(res => setTimeout(res, msec));
// obnizが接続済み
obniz.onconnect = async function () {
var led = obniz.wired("LED", {anode:0, cathode:1});
led.blink(); // 100msec
var led = obniz.wired("LED", {anode:2, cathode:3});
led.blink(); // 200msec
var led = obniz.wired("LED", {anode:4, cathode:5});
led.on();
// スピーカーを利用
const speaker = obniz.wired('Speaker', { signal: 10, gnd: 11 });
// ポッ↓
speaker.play(500); await sleep(300); speaker.stop(); await sleep(700);
// ポッ↓
speaker.play(500); await sleep(300); speaker.stop(); await sleep(700);
// ポッ↓
speaker.play(500); await sleep(300); speaker.stop(); await sleep(700);
// ポ~~~ン↑
speaker.play(1000); await sleep(1000); speaker.stop();
// Ctrl+C を打たなくても自動で終了します
exit();
}
ソースコード **(クリックで表示)**
const Obniz = require('obniz');
const { exit } = require('process');
const obniz = new Obniz('obniz_ID'); // Obniz_IDに自分のIDを入れます
const express = require('express');
const line = require('@line/bot-sdk');
const PORT = process.env.PORT || 3000;
// Messaging APIで利用するクレデンシャル(秘匿情報)です。
const config = {
channelSecret: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
channelAccessToken: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
};
const app = express();
const app = express();
// HTTP POSTによって '/webhook' のパスにアクセスがあったら、POSTされた内容に応じて様々な処理をします
app.post('/webhook', line.middleware(config), (req, res) => {
// 検証ボタンをクリックしたときに飛んできたWebhookを受信したときのみ以下のif文内を実行
if (req.body.events.length === 0) {
res.send('Hello LINE BOT! (HTTP POST)'); // LINEサーバーに返答します(なくてもよい)
console.log('検証イベントを受信しました!'); // ターミナルに表示します
return; // これより下は実行されません
} else {
// 通常のメッセージなど … Webhookの中身を確認用にターミナルに表示します
console.log('受信しました:', req.body.events);
}
// あらかじめ宣言しておいた "handleEvent" 関数にWebhookの中身を渡して処理してもらい、
// 関数から戻ってきたデータをそのままLINEサーバーに「レスポンス」として返します
Promise.all(req.body.events.map(handleEvent)).then((result) => res.json(result));
});
const client = new line.Client(config);
// obniz接続
obniz.onconnect = async function () {
obniz.display.clear();
obniz.display.print("obniz meets LINE Bot!");
}
function handleEvent(event) {
if (event.type !== 'message' || event.message.type !== 'text') {
return Promise.resolve(null);
}
let mes = ''
if(event.message.text === '帰るね!'){
mes = 'すこしまってね'; //メッセージだけ先に処理
getAskObnizSpeaker(event.source.userId); //スクレイピング処理が終わったらプッシュメッセージ
}else{
mes = event.message.text;
}
return client.replyMessage(event.replyToken, {
type: 'text',
text: mes
});
}
const getAskObnizSpeaker = async (userId) => {
// スピーカーを呼び出す
const speaker = obniz.wired("Speaker", {signal:0, gnd:1});
console.log("Speaker")
await client.pushMessage(userId, {
type: 'text',
text: "了解!気を付けて!",
});
// 任意の秒数待つことができる関数
// 参考: https://qiita.com/suin/items/99aa8641d06b5f819656
const sleep = (msec) => new Promise(res => setTimeout(res, msec));
// obnizが接続済み
obniz.onconnect = async function () {
var led = obniz.wired("LED", {anode:0, cathode:1});
led.blink(); // 100msec
var led = obniz.wired("LED", {anode:2, cathode:3});
led.blink(); // 200msec
var led = obniz.wired("LED", {anode:4, cathode:5});
led.on();
// スピーカーを利用
const speaker = obniz.wired('Speaker', { signal: 10, gnd: 11 });
// ポッ↓
speaker.play(500); await sleep(300); speaker.stop(); await sleep(700);
// ポッ↓
speaker.play(500); await sleep(300); speaker.stop(); await sleep(700);
// ポッ↓
speaker.play(500); await sleep(300); speaker.stop(); await sleep(700);
// ポ~~~ン↑
speaker.play(1000); await sleep(1000); speaker.stop();
// Ctrl+C を打たなくても自動で終了します
exit();
}
##稼働状況
https://twitter.com/EgashiraYosuke/status/1450791166673178625
##詰まっているところ
・LINE通知を検知し、LEDランプと音を連携させるところ。(うまく連携出来ていない)
・自宅到着1時間前:赤色ランプ 30分前:黄色ランプ 10分前:青色など
フルカラーLEDでも良いかと考えております。
##フィードバック
奥さんからは、「曲を毎回変えて欲しい」「LINEを送付したら、乗換案内で自動検索し、何時着が自動通知してくれる」「車の場合は、エンジンをかけた瞬間、計算してくれ通知してくれるなど」GPSみたいと笑ってました。社内からは、「outlookとIoT連携した施策」、「全く別物だが、温度センサーを使い、冷凍・冷蔵温度異常がでた際に、社員スマホ、LINEに通知がくるシステムがあると便利。夏場温度異常が多く、緊急対応が多いため」という声がありました。
##今後チャレンジしたいこと
今後、赤外線距離センサー赤外線距離センサーを活用し、自宅のポストに投函されたら、LINEの通知が来るようなシステムも制作していきたい思っております。
奥さんも喜んでくれると思うので、汗
これも奥さん、友達にフィードバックもらったところ、「毎回通知される仕組みでなく、せめて1日1回にして欲しい」
「一人暮らしで毎回見るの面倒だから、一定の量を超えたら通知して欲しい」という声がありましたので、次回制作していく中で、この意見を取り入れながら進めていきたいと思います。
##今後取り組みたい課題
https://note.com/dsvvpxgc/n/ne90690aa950b