20
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

LINE BOTでラズパイから部屋の温度を教えてもらう【Push API】【Node.js】

Last updated at Posted at 2018-05-20

前回できたこと

  • LINEのReplyAPIを利用したおうむ返しBot
  • ラズパイ、DHT11を利用し温湿度データをBotで返信

前回記事を参照
RaspberryPi3を使ってLINE BOTに部屋の温度を教えてもらう 【node.js】

前提条件

  • LINE Messaging APIのDeveloper Trialのアカウント(またはビジネスプラン)を利用

フリープランだとPushAPIは使えないようです
MessagingAPIで利用できる料金プラン

今回の作業内容

  1. PUSH通知してみる
  2. 温湿度を通知してみる
  3. 温湿度を常に監視するため、プログラムを繰り返し実行させる(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/
id.png

Botのチャンネル設定の一番下、Uから始まる文字列が自分のIDです
id2.png

server.jsの編集

line-bot-sdk-nodejsを利用するので簡単!
client.pushMessage()を利用します

client.pushMessage('user_or_group_or_room_id', {
  type: 'text',
  text: 'hello, world',
})

参照元: https://github.com/line/line-bot-sdk-nodejs/blob/master/docs/pages/api-reference/client.md#pushmessageto-string-messages-message--message-promiseany

server.js
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

LINEにメッセージが届いた!
IMG_6183.jpg

2. 温湿度を通知してみる

ログ出力のためmoment-timezoneをインストールしました

$ npm install moment-timezone

server.jsの編集

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の変更
前回はメッセージを返していましたが、データをそのまま返すように変更しました

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

LINEにメッセージが届いた!
スクリーンショット 2018-05-18 午後1.29.44.png

3. 温湿度を常に監視するため、繰り返し実行させる(node-cronのインストール)

node-cronのインストール

$ npm install node-cron

node-cron https://www.npmjs.com/package/node-cron

cron.jsを作成

$ nano cron.js
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

ログが毎秒出るのを確認!
ontick.png

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();
server.js
// 追記
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度だと届きません。)
IMG_6185.jpg

ちなみに
毎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がスリープすると、プログラムが終了する
    • →ラズパイ内で自動実行の永続化が必要
  • ラズパイのセキュリティ
20
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?