前回できたこと
- LINEのReplyAPIを利用したおうむ返しBot
- ラズパイ、DHT11を利用し温湿度データをBotで返信
前回記事を参照
RaspberryPi3を使ってLINE BOTに部屋の温度を教えてもらう 【node.js】
前提条件
- LINE Messaging APIのDeveloper Trialのアカウント(またはビジネスプラン)を利用
フリープランだとPushAPIは使えないようです
MessagingAPIで利用できる料金プラン
今回の作業内容
- PUSH通知してみる
- 温湿度を通知してみる
- 温湿度を常に監視するため、プログラムを繰り返し実行させる(node-cronのインストール)
node-cronは定時通知(月曜日に通知、毎日朝7時に通知など)にも使えるよ!
【所要時間 30分】
クロン / クーロン / クローン
cron 【 crond 】 crontab
cronとは、UNIX系システムの常駐プログラム(デーモン)の一種で、ユーザの設定したスケジュールに基づいて指定したコマンドやシェルスクリプトなどを自動実行してくれるプログラム。
実行スケジュールは毎時、毎日、毎週、毎月をはじめ細かく指定でき、「crontab」というファイルに記述・保存しておく。crond(cron daemon)というプロセスがcrontabの内容に従って、決められた日時にコマンドなどを実行してくれる。 -- IT用語辞典より
1. PUSH通知してみる
作業ディレクトリ構成はこうなる予定です(詳細は前回参照)
workspace/mylinebot $ ls
cron.js dht.js node_modules package-lock.json package.json plugins server.js
送り先の確認
ID、グループを指定できます。今回は自分のIDに送ります。
LINE Developersのコンソール画面より自分のIDを確認
https://developers.line.me/
Botのチャンネル設定の一番下、Uから始まる文字列が自分のIDです
server.jsの編集
line-bot-sdk-nodejsを利用するので簡単!
client.pushMessage()を利用します
client.pushMessage('user_or_group_or_room_id', {
type: 'text',
text: 'hello, world',
})
const express = require('express');
const line = require('@line/bot-sdk');
const PORT = process.env.PORT || 3000;
const config = {
channelAccessToken: '',
channelSecret: ''
};
const app = express();
app.post('/webhook', line.middleware(config), (req, res) => {
console.log(req.body.events);
Promise
.all(req.body.events.map(handleEvent))
.then((result) => res.json(result));
});
const client = new line.Client(config);
client.pushMessage('送信先ID', {
type: 'text',
text: 'hello, world',
})
// 以下省略
nodeで実行してみる
$ node server.js
2. 温湿度を通知してみる
ログ出力のためmoment-timezoneをインストールしました
$ npm install moment-timezone
server.jsの編集
const express = require('express');
const line = require('@line/bot-sdk');
const PORT = process.env.PORT || 3000;
const moment = require('moment-timezone');
const config = {
channelAccessToken: '',
channelSecret: ''
};
const app = express();
app.post('/webhook', line.middleware(config), (req, res) => {
console.log(req.body.events);
Promise
.all(req.body.events.map(handleEvent))
.then((result) => res.json(result));
});
const client = new line.Client(config);
// pushMessageを送る処理
function sendPushMessage(mes) {
client.pushMessage('送信先ID', {
type: 'text',
text: mes,
})
console.log(moment().tz("Asia/Tokyo").format() + ' 送信完了:push message');
}
const readout = dht.getData();
console.log(readout);
const mes = '室内の温度は'+readout.temperature.toFixed(1)+'℃、'+'湿度は'+readout.humidity.toFixed(1)+'%です。'
sendPushMessage(mes);
// replyMessageを送る処理
function handleEvent(event) {
if (event.type !== 'message' || event.message.type !== 'text') {
return Promise.resolve(null);
}
var mes = '';
mes = event.message.text;
if(event.message.text === 'いまなんど') {
// mes = dht.getData();
const readout = dht.getData();
mes = '室内の温度は'+readout.temperature.toFixed(1)+'℃、'+'湿度は'+readout.humidity.toFixed(1)+'%です。'
} else {
mes = event.message.text;
}
return client.replyMessage(event.replyToken, {
type: 'text',
text: mes
});
}
dht.jsの変更
前回はメッセージを返していましたが、データをそのまま返すように変更しました
const sensorLib = require('node-dht-sensor');
const sensor = {
sensors: [ {
name: "DHT11",
type: 11,
pin: 4
} ],
read: function() {
// 前回はメッセージを返していましたが、データをそのまま返すように変更
const readout = sensorLib.read(this.sensors[0].type, this.sensors[0].pin);
// return '室内の温度は'+readout.temperature.toFixed(1)+'℃、'+'湿度は'+readout.humidity.toFixed(1)+'%です。';
return readout;
}
}
exports.getData = function() {
try {
return sensor.read();
} catch (error) {
return '不明です';
}
}
nodeで実行してみる
$ node server.js
3. 温湿度を常に監視するため、繰り返し実行させる(node-cronのインストール)
node-cronのインストール
$ npm install node-cron
node-cron https://www.npmjs.com/package/node-cron
cron.jsを作成
$ nano cron.js
var mycron = require('cron').CronJob;
var task = new mycron({
cronTime: '* * * * * *', //毎秒実行
onTick: function() {
console.log('毎秒実行');
}
},
start: true, // newした後即時実行するかどうか
});
task.start();
参照記事:http://chkkchy.hatenablog.com/entry/2014/08/07/201314
cron.jsを実行
$ node cron.js
cron.jsの編集(実際の処理)
var mycron = require('cron').CronJob;
const server = require('./server');
const dht = require('./dht');
var task = new mycron({
cronTime: '*/10 * * * * *', //毎10秒実行
onTick: function() {
const readout = dht.getData();
console.log(readout);
// 一定温度を超えていたらアラート通知
if ((readout.temperature > 25) || (readout.temperature < 19)){
const mes = '室内の温度は'+readout.temperature.toFixed(1)+'℃、'+'湿度は'+readout.humidity.toFixed(1)+'%です。'
server.sendPushMessage(mes);
}
},
start: true,
});
task.start();
// 追記
const cron = require('./cron');
// ...省略
const client = new line.Client(config);
// pushMessageを送る処理
function sendPushMessage(mes) {
client.pushMessage('送信先ID', {
type: 'text',
text: mes,
})
console.log(moment().tz("Asia/Tokyo").format() + ' 送信完了:push message');
}
// replyMessageを送る処理
function handleEvent(event) {
if (event.type !== 'message' || event.message.type !== 'text') {
return Promise.resolve(null);
}
var mes = '';
mes = event.message.text;
if(event.message.text === 'いまなんど') {
// mes = dht.getData();
const readout = dht.getData();
mes = '室内の温度は'+readout.temperature.toFixed(1)+'℃、'+'湿度は'+readout.humidity.toFixed(1)+'%です。'
} else {
mes = event.message.text;
}
return client.replyMessage(event.replyToken, {
type: 'text',
text: mes
});
}
server.jsを実行
$ node server.js
LINEにメッセージがたくさん届くよ!(毎10秒。上記コードだと室温が20~25度だと届きません。)
ちなみに
毎10秒 cronTime: '*/10 * * * * *'
毎2分 cronTime: '*/2 * * * *'
毎日朝7時に通知など、node-cronは定時通知にも使えます
詳しくはライブラリのREAD MEを参照してください
もしnpmのインストールで怒られたら
$ sudo npm install --unsafe-perm
--unsafe-perm
を追加するとうまくいくかも!
参照記事 https://github.com/nodejs/node-gyp/issues/454
次回への課題
- ラズパイにSSH接続しているMacがスリープすると、プログラムが終了する
- →ラズパイ内で自動実行の永続化が必要
- ラズパイのセキュリティ