如何用LineBot控制家電

有了LineBot,要控制家電用品,實現智慧家庭都可以,而且手機不用寫任何APP,只要手機有Line,並且有一個能連上網的開發板,但問題是開發板要挑哪一種。聯發科的7688及7697都可以連網,所以是個不錯的選擇,由LineBot去改變MCS的雲端資料,再由7688及7697去讀取MCS的資料,就可以控制開發板。但是,需要在三個地方做設定,一個是在LineBot伺服器上寫程式,第二步在MCS上設定各種資料通道,第三步就是在7688或7697上寫碼,看起來又複雜了點,如果能在LineBot伺服器直接可寫碼控制開發板就省事多了,於是我用了Webduino Smart。Webduino能夠讓我直接在LineBot上寫碼控制Webduino,最主要是因為Webduino支援了javascript,可以用網頁控制,即然可以用javascript,那就代表在node.js環境的伺服器上寫碼也能控制webduino,所以,這一篇主要是以LineBot控制Webduino為主要結構。

相關的LineBot申請、heroku網站空間旳申請以及程式上傳,就請參閱前面幾篇文章,在此不贅述。

LineBot控制Websuino Smart

繼電器Data腳位請接Webduino Smart的五號腳位

Line可以控制任何地方的Webduino

除了能控制家電,它也能回應數學算式,計算結果

這個程式除了控制家電外,還包含了一個能幫我計算數學式的回應,例如,能計算3*2,或是sin(30),或是(234+365)*567,所以程式完成後也可以測驗一下讓LineBot算數學。

在上傳程式前,有幾個packge要先安裝,mathjs是計算數學式的相關函式,webduino-js以及webduino-blockly則是要控制webduino需要用到的package。安裝的指令如下:

  • d:
  • cd bottest (以上指令請視自己程式的工作資料夾來更改)
  • npm install webduino-js --save
  • npm install webduino-blockly --save
  • npm install mathjs --save

利用LineBot控制家電的詳細程式index.js,其中LineBot的channelId、channelSecret及AccessToken請自行修改,另外,找到myBoardVars這個變數,要把device參數改成自己的webduino的deviceId。

require('webduino-js');
require('webduino-blockly');

var linebot = require('linebot');
var express = require('express');
var math = require('mathjs');

var bot = linebot({
  channelId: '請輸入LineBot的channelId',
  channelSecret: '請輸入LineBot的channelSecret',
  channelAccessToken: '請輸入LineBot的channelAccessToken'
});
//以下的Webduino的device,請輸入自己webduino的DeviceID
var myBoardVars={board: 'Smart', device: '這裡請輸入webduino的Device ID,前後引號不能去掉', transport: 'mqtt'};

//注意:上面為連結Webduino Smart的連結語法,如果你的板子是webduino馬克一號或是Fly,請將上面的語法刪掉,並改成以下的連結語法。var myBoardVars={device: '這裡請輸入webduino的Device ID,前後引號不能去掉'};

var rgbled;
var relay;
var myBoard;
   
bot.on('message', function(event) {
   var myReply='';
   if (event.message.type === 'text') {
      myReply=processText(event.message.text);
   }
   if (event.message.type === 'sticker') {
      myReply='你太幽默了!';
   console.log('sticker');
   }
   if (event.message.type === 'image') {
      myReply='這照片好帥!';
   }
   event.reply(myReply).then(function(data) {
      // success 
      console.log(myReply);
   }).catch(function(error) {
      // error 
      console.log('error');
   });
});

function processText(myMsg){
   var myResult='';
   if (myMsg==='你好' || myMsg==='早安' || myMsg==='午安' || myMsg==='晚安')
      myResult=myMsg; 
   else if (myMsg==='我很帥')
      myResult='我也這麼覺得';
   else if (myMsg==='繼電器')
      myResult='5號腳位';
   else if (myMsg==='再見')
      myResult='這麼快就要離開我了!';
   else if (myMsg==='led開' || myMsg==='LED開'){
      if (!deviceIsConnected())
         myResult='裝置未連接!';
      else{
         myResult='LED已打開!';
         rgbled.setColor('#FFFFFF');
      }
   }
   else if (myMsg==='led關' || myMsg==='LED關'){
      if (!deviceIsConnected())
         myResult='裝置未連接!';
      else{
         myResult='LED已關閉!';
         rgbled.setColor('#000000');
      }
   }
   else if (myMsg==='電燈開'){
      if (!deviceIsConnected())
         myResult='裝置未連接!';
      else{
         myResult='電燈已打開!';
         relay.on();
      }
   }
   else if (myMsg==='電燈關'){
      if (!deviceIsConnected())
         myResult='裝置未連接!';
      else{
         myResult='電燈已關閉!';
         relay.off();
      }
   }
   else{
      myResult='';
      try{
         myResult='答案是'+math.eval(myMsg.toLowerCase()).toString();
      }catch(err){
         myResult='';
      }
      if (myResult==='')
         myResult='抱歉,我不懂這句話的意思!';
   }
   return myResult;
}

boardReady(myBoardVars, true, function (board) {
   myBoard=board;
   board.systemReset();
   board.samplingInterval = 50;
   rgbled = getRGBLedCathode(board, 15, 12, 13);
   relay = getRelay(board, 5);
   rgbled.setColor('#000000');
   relay.off();
});

//以下為檢查webduino是否已連線成功的函式
function deviceIsConnected(){
   if (myBoard===undefined)
      return false;
   else if (myBoard.isConnected===undefined)
      return false;
   else
      return myBoard.isConnected;
}


const app = express();
const linebotParser = bot.parser();
app.post('/', linebotParser);

//因為 express 預設走 port 3000,而 heroku 上預設卻不是,要透過下列程式轉換
var server = app.listen(process.env.PORT || 8080, function() {
  var port = server.address().port;
  console.log("App now running on port", port);
});

上傳完程式到heroku後,Webduino Smart板子上的LED燈點亮及關閉的指令是「LED開」及「LED關」,電燈繼電器開關的指令為「電燈開」及「電燈關」。


PS.上面boardReady這個函式,就是在處理LineBot和Webduino Smart的連結,短短幾行程式就可以搞定連結的方式。所以,不寫程式在開發板上的板子,好像也有它的好處。原先不能燒程式在板子上的問題也讓我對webduino 不是很滿意, 然後來我覺得這樣子反而更有彈性,因為燒在板子上你就沒辦法更改程式了。 而現在webduino, 只要知道Device ID 你就可以在全世界任何一台電腦都可以對它進行程式控制。 當然你如果覺得某一台電腦要一直開著且瀏覽器必須一直打開的這種狀況很困擾, 也可以用像本文所介紹的,用node.js寫伺服器端的程式,反正伺服器得24小時開機不是嗎?