2
0

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 1 year has passed since last update.

はじめに

LINE Beaconが気になりつつも触れていなかったので、opnizというIoTフレームワークでコントールできるか試してみました。

opnizでコントロールできるとどんなことができるかというと、ビーコンのstartやstopをNode.jsから任意のタイミングで切り替えたり、device messageというビーコンから送れる任意のメッセージを動的に変更できたりします。

それができることで何がうれしいかというと今のところパッと浮かばないのですが、何かできそうなポテンシャルはそこはかとなく感じているので、選択肢のひとつとして頭の片隅においておくといいことがあるかもしれません。

LINE Beacon実装にあたり参考にした記事

LINE Beaconの実装は上記の記事を参考にGreen BeaconというLINE Simple BeaconのArduinoライブラリを使用させていただきました。
少ないコードでLINE Beaconが実装できてとても便利です!作者さまありがとうございます!

環境情報

ソースコード

Node.js(opniz & LINE Bot)

Node.jsのコードはopniz Node.js SDKをGreenBeacon用に拡張して制御するコードと、LINE BeaconからのWebhookを受けるBotサーバー用のコードの2つがあります。
Botサーバーのコードはopniz Node.js SDKのコードでimportして同時に動かしています。

package.json
{
	"name": "opniz-line-beacon",
	"version": "0.0.1",
	"main": "index.mjs",
	"type": "module",
	"dependencies": {
		"@line/bot-sdk": "^7.5.2",
		"express": "^4.18.2",
		"opniz": "^0.2.4"
	}
}
index.mjs
import { Opniz } from "opniz"
import { LINEBot } from "./linebot.mjs"


const config = {
	channelAccessToken: "<Channel Access Token>", // 書き換える
	channelSecret: "<Channel Secret>", // 書き換える
}
const botPort = 3000 // 任意のポート番号でOK
const opnizPort = 3001 // 任意のポート番号でOK

const lineBot = new LINEBot({ config, port: botPort })



// GreenBeacon用opniz拡張クラス
class GreenBeacon extends Opniz.Esp32 {
	async startBeacon(message = "") {
		return Boolean(await this.exec("startBeacon", message))
	}
	async stopBeacon() {
		return Boolean(await this.exec("stopBeacon"))
	}
	async setMessage(message = "") {
		return Boolean(await this.exec("setMessage", message))
	}
}

const opniz = new GreenBeacon({ port: opnizPort })



const main = async () => {
	while (!(await opniz.connectWait({ timeout: 5000 }))) { console.log("connect..."); await opniz.sleep(100) }
	console.log("[connected]")
	
	try {
		await opniz.startBeacon("test!") // LINE Beacon開始
		// await opniz.stopBeacon() // LINE Beacon停止
		
		// 動作テストとして1秒おきにデバイスのヒープメモリサイズを取得
		for (;;) {
			console.log(await opniz.getFreeHeap())
			await opniz.sleep(1000)
		}
		
	} catch(e) {
		console.log("[error]", e.message)
		await main()
	}
}
main()
linebot.mjs
// LINE BeaconからのWebhookを受けるBotサーバー
import express from "express"
import { Client, middleware } from "@line/bot-sdk"

export class LINEBot {
	#bot
	#app
	
	constructor({ config, port }) {
		this.#bot = new Client(config)
		
		this.#app = express()
		this.#app.post("/", middleware(config), this.#handleWebhook)
		this.#app.listen(port)
	}
	
	#handleWebhook = (req, res) => {
		const events = req.body.events
		console.log(events)
		
		events.forEach(this.handleEvent)
		res.status(200).send("OK")
	}
	
	handleEvent = (event) => {
		switch (event.type) {
			case "message": this.handleMessage(event); break
			case "beacon": this.handleBeacon(event); break
		}
	}
	
	handleMessage = (event) => {
		this.#bot.replyMessage(event.replyToken, {
			type: "text",
			text: event.message.text,
		})
	}
	
	handleBeacon = (event) => {
		const message = Buffer.from(event.beacon.dm, "hex").toString("utf-8")
		this.#bot.replyMessage(event.replyToken, {
			type: "text",
			text: message,
		})
	}
}

M5Stamp Pico(PlatformIO)

ライブラリ個別インストール(PlatformIOプロジェクトルートディレクトリで実行)
$ cd lib
$ git clone https://github.com/miso-develop/opniz-arduino-esp32
$ git clone https://github.com/ukkz/green-beacon-esp32
platformio.ini
[env:m5stack-atom]
platform = espressif32
board = m5stack-atom
framework = arduino
lib_deps = 
	links2004/WebSockets@^2.3.7
	bblanchon/ArduinoJson@^6.19.4
monitor_speed = 115200
board_build.partitions = huge_app.csv
main.cpp
#include <OpnizEsp32.h>
#include <lib/WiFiConnector.h>

const char* ssid = "<Wi-Fi SSID>"; // 書き換える
const char* password = "<Wi-Fi Password>"; // 書き換える

const char* address = "<IP Address>"; // Node.js SDKを実行するマシンのIPアドレスへ書き換える
const uint16_t port = 3001; // 任意のポート番号でOK(Node.js SDKと合わせる)

const String hwid = "<Hardware ID>"; // LINE Official Account Managerのビーコンページで取得したハードウェアIDに書き換える

WiFiConnector wifiConnector(ssid, password);
Opniz::Esp32* opniz = new Opniz::Esp32(address, port);



#include "GreenBeacon.h"
GreenBeacon beacon;

// GreenBeacon関数用ハンドラ定義
class startBeaconHandler : public BaseHandler {
public:
    String name() override { return "startBeacon"; };
    String procedure(JsonArray params) override {
        Serial.println("startBeacon");
        String message = params[0];
        Serial.println(message);
        beacon.start(message);
        return "true";
    }
};
class stopBeaconHandler : public BaseHandler {
public:
    String name() override { return "stopBeacon"; };
    String procedure(JsonArray params) override {
        Serial.println("stopBeacon");
        beacon.stop();
        return "true";
    }
};
class setMessageHandler : public BaseHandler {
public:
    String name() override { return "setMessage"; };
    String procedure(JsonArray params) override {
        Serial.println("setMessage");
        String message = params[0];
        Serial.println(message);
        beacon.setMessage(message);
        return "true";
    }
};



void setup() {
    Serial.begin(115200);
    
    wifiConnector.connect();
    
    beacon = GreenBeacon(hwid);
    
    opniz->addHandler({
        new startBeaconHandler,
        new stopBeaconHandler,
        new setMessageHandler,
    });
    opniz->connect();
}

void loop() {
    opniz->loop();
    wifiConnector.watch();
}

ハマったポイントと解決策

PlatformIOでGreenBeaconをインストールしたらバージョンが古かった

書き込みサイズオーバー

image

  • コンパイル後、書き込みしようとしたらサイズオーバーでエラー

メモリ不足

  • 当初M5ATOM Liteで実装していたのですがパニックで再起動を繰り返す状況に

おわりに

ROM不足にRAM不足と普段なかなか経験しないようなマイコンならではのエラーに悩まされて楽しかったです。

無事opnizからLINE Beaconをコントロールできるようになったので、何かいい感じに使えたらまた記事にしてみたいと思います。

2
0
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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?