M5Stack に LINE Beacon で書き込み Node-RED で作った LINE BOT とやり取りするメモ

M5Stack に LINE Beacon で書き込み Node-RED で作った LINE BOT とやり取りするメモです。

M5StackでLINE Beaconを作成する手順を久々にまとめてみる 2020年9月版

こちらの記事を参考に書いてみました。

という対応をします。

image

LINE Simple BeaconのハードウェアIDを発行はこんな感じです。

M5Stack に LINE Beacon を書き込む

beacon = GreenBeacon("Hardware ID"); のところを Hardware ID のところを先ほどのハードウェアIDに書き換えてプログラムを書き込みます。

#include "GreenBeacon.h"
#include <M5Stack.h>

GreenBeacon beacon;

int wait_msec = 20000;  // 20000 msec = 20 sec

void setup() {

  // Initialize the M5Stack object
  M5.begin();

  // START
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setCursor(0, 10);
  M5.Lcd.setTextColor(WHITE);
  M5.Lcd.setTextSize(3);
  M5.Lcd.println("[LINE Beacon]");
  M5.Lcd.print("wait_msec : ");
  M5.Lcd.println(wait_msec);
  // 
  beacon = GreenBeacon("   ID   "); // 取得したハードウェアIDを指定
}

void beacon_execute(String message){
  beacon.start(message);
  
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setCursor(0, 10);
  M5.Lcd.println("> beacon.start");
  M5.Lcd.print("mode : ");
  M5.Lcd.println(message.c_str());
  // wait_msec だけ待つ
  int startTime = millis();
  while(millis() - startTime < wait_msec){
    M5.Lcd.print(".");
    delay(1000);
  }
  M5.Lcd.println(".");

  beacon.stop();
  M5.Lcd.println("> beacon.stop");
}

void loop() {
  
  if(M5.BtnA.wasPressed()) {
    String mes = "enter";
    beacon_execute(mes);
  }

  if(M5.BtnB.wasPressed()) {
    String mes = "exit";
    beacon_execute(mes);
  }

  if(M5.BtnC.wasPressed()) {
    String mes = "close";
    M5.Lcd.fillScreen(BLACK);
    M5.Lcd.setCursor(0, 10);
    M5.Lcd.println("> beacon.stop");
    M5.Lcd.println(mes.c_str());
    beacon.stop();
  }
  
  M5.update();
  
}

Messaging APIリファレンスの Beacon を見ると leave イベントは廃止されるようなので、ユーザーがビーコンの受信圏から出るという反応をさせずM5Stack 側から一定時間ビーコンを発信するとOFFにする形にしています。子のプログラムでは 20 秒で設定しています。

image

このように動きます。

Node-RED で作った LINE BOT のフロー

image

先ほどの M5Stack で動く LINE Beacon から受信する LINE BOT は、 Node-RED で作っています。

image

Node-RED で LINE BOT はこのように実装されています。以下が、インポートして使えるフローの JSON です。

[{"id":"9ed44f76.ba43e","type":"http in","z":"1e78849d.7b126b","name":"","url":"/line/webhook","method":"post","upload":false,"swaggerDoc":"","x":430,"y":480,"wires":[["4111667b.c124e8","7bcc5845.d6b358"]]},{"id":"e2440c56.4dc1","type":"ReplyMessage","z":"1e78849d.7b126b","name":"","channelSecret":"","channelAccessToken":"","replyMessage":"","x":1370,"y":480,"wires":[]},{"id":"4111667b.c124e8","type":"switch","z":"1e78849d.7b126b","name":"type beacon 判定","property":"payload.events.0.type","propertyType":"msg","rules":[{"t":"eq","v":"beacon","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":740,"y":480,"wires":[["d41bcba8.4e4bb8"],["e2440c56.4dc1"]]},{"id":"22a3eb04.cafd34","type":"change","z":"1e78849d.7b126b","name":"メッセージ作成","rules":[{"t":"set","p":"payload.events.0.message","pt":"msg","to":"{}","tot":"json"},{"t":"set","p":"payload.events.0.message","pt":"msg","to":"{\t   \"type\":\"text\",\t   \"text\":\"Node-REDにLINEビーコンきたよ:\" & payload.dmStr\t}","tot":"jsonata"},{"t":"set","p":"payload.events.0.type","pt":"msg","to":"message","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1170,"y":440,"wires":[["e2440c56.4dc1"]]},{"id":"7bc6a031.6c729","type":"comment","z":"1e78849d.7b126b","name":"Beacon →","info":"","x":930,"y":400,"wires":[]},{"id":"7bcc5845.d6b358","type":"debug","z":"1e78849d.7b126b","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":720,"y":440,"wires":[]},{"id":"d41bcba8.4e4bb8","type":"function","z":"1e78849d.7b126b","name":"dm 値を文字列に変更","func":"const dmHexStr = msg.payload.events[0].beacon.dm; //16進数文字列\nconst dmStr = Buffer.from(dmHexStr, 'hex').toString('utf-8');\n\nmsg.payload.dmStr = dmStr;\n\nreturn msg;","outputs":1,"noerr":0,"x":970,"y":440,"wires":[["22a3eb04.cafd34"]]},{"id":"7000bdc0.3ef254","type":"comment","z":"1e78849d.7b126b","name":"そのほかはオウム返し →","info":"","x":980,"y":520,"wires":[]}]

type が beacon のときだけ処理を行って、他のメッセージタイプは同じメッセージをそのまま返事しています。Node-REDにLINEビーコンきたよ: という文字列に、 LINE Beacon 側から添えられた dm 値を加えているので、enter か exit が M5Stack でボタンが押されるたびに返ってきます。

反応が以前の最終の状態と、今回の状態で 2 連続で来るケースもあるので、このあたりはもう少し検証してみます。