4.1. LoRaScript
LoRaScriptはJavaScriptおよびNode.jsベースの独自プラグイン機構です。LoRaScriptを使って機能を追加(アドオン)することができます。
LoRaScriptではNode.js APIの一部とサードパーティAPIを使用できます。
(APIのリストは「4.1.1. LoRaScript API」にあります。)
図4-1 LoRaScript
図4-1はLoRaScriptコンソールです。
[Core Status]パネルの内、[Proc]はプラグインプロセスID、[Stat]はプロセスステータス(実行中または停止)、[Vmem]はメモリ使用量を表します。
[Packet Info]パネルではLoRaScriptで受信したパケット数を確認できます。[Plugin File]パネルはプラグインマネージャーによって読み込まれる現在のファイルを表示します。
[Plugin Editor]パネルはオンラインスクリプトエディターです。
プラグインマネージャーがスクリプトを正しく読み込むために、onInit()
とonLoRaRx(data)
の2つの関数の定義が必要です。
onInit()
はプラグインの初期化時に呼び出されます。パケットを受信する毎にonLoRaRx(data)
が呼び出されます。
onLoRaRx(data)
関数の第一引数は仕様[3]のrxpkコンポーネントに準拠するJSONオブジェクトです。
[Plugin Log]パネルはプラグインのログを表示します。(debug_print()
関数を使用)
プラグインでパケットを送信するにはsend_pkt(data)
を呼び出します。data引数も仕様[3]のtxpkコンポーネントに準拠する必要があります。
表4-1はユーザーが使用できるコールバック関数とメソッドの一覧です。表4-2と表4-3はそれぞれANNWS.01.2.1.W.SYS rxpkおよびtxpkコンポーネントを示します。
表4-1 LoRaScriptコールバックとメソッド
名前 | タイプ | 使用方法 |
---|---|---|
onInit() | Callback | プラグイン初期化メソッド。プラグインはこのコールバックで初期化手続きを設定できます。 |
onLoRaRx(data) | Callback | 着信パケットの受信時に呼び出されます。dataは[3]に準拠するJSONオブジェクトです。 |
send_pkt(data) | Method | 送信パケットの送信に使用されます。dataはJSONオブジェクトで[3]に準拠する必要があります。 |
debug_print(message) | Method | [Plugin Log]パネルでのメッセージを表示用です。 |
表4-2 ANNWS.01.2.1.W.SYSのrxpk JSONコンポーネント
フィールド | データ型 | コメント |
---|---|---|
time | string(任意) | LoRa®フレームの受信のTC時間。 精度は1マイクロ秒です。形式はISO 8601「コンパクト」形式です。 |
tmst | unsigned integer(必須) | LoRa®フレームが受信された瞬間のゲートウェイ内部時間カウンターの値(マイクロ秒単位) |
freq | unsigned float(Hz精度、必須) | MHz単位の受信信号の中心周波数。 |
chan | unsigned integer(必須) | フレームが受信されたコンセントレータ「IF」チャネル。 |
rfch | unsigned integer(必須) | フレームが受信されたコンセントレーター無線周波数チェーン。 |
stat | signed integer(必須) | フレームに対するゲートウェイのCRCテストの結果。 |
modu | string(必須) | 使用される変調技術:LoRa®変調を表す「LORA」、FSK変調を表す「FSK」 |
datr | string(必須) | データレート識別子。 「modu」が「LORA」に等しい場合、「datr」は「SFnBWm」を含みます。 |
codr | string(「modu」が「LoRa」と等しい場合に必須) | ECCコードレート。「codr」は文字「k / n」で構成されます。 |
rssi | signed integer(必須) | 測定された受信信号強度(dBm単位) |
lsnr | signed float(必須) | 測定された受信信号対雑音比(dB単位) |
size | unsigned integer(任意) | 受信したフレームのオクテット数。 |
data | string(必須) | Base64にエンコードされたフレームペイロード。 |
表4-3 ANNWS.01.2.1.W.SYSのtxpk JSONコンポーネント
フィールド | データ型 | コメント |
---|---|---|
imme | boolean(任意) | trueの場合、ゲートウェイはすぐにフレームを送信するように指示されます。 |
tmst | unsigned integer(任意) | 「imme」がtrueではなく「tmst」が存在する場合、ゲートウェイはその内部タイムスタンプカウンタが「tmst」の値と等しいときにフレームを送信するように命令されます。 |
time | string(必須) | UTC時刻。 精度は1マイクロ秒です。形式はISO 8601「コンパクト」形式です。 |
freq | unsigned float(Hz精度、必須) | フレームをMHz単位で送信するときの中心周波数。 |
rfch | unsigned integer(必須) | ゲートウェイがフレームを送信するように指示されるアンテナ。 |
powe | signed integer(任意) | ゲートウェイがフレームを送信するように指示される出力電力。 |
modu | string(任意) | 使用される変調技術:LoRa変調を表す「LORA」、FSK変調を表す「FSK」 |
datr | string(任意) | データレート識別子。「modu」が「LORA」に等しい場合、「datr」は「SFnBWm」を含みます。 |
codr | string (「modu」が「LoRa」と等しい場合に必須) | ECCコードレート。「codr」は文字「k / n」で構成されます。 |
ipol | boolean(必須) | trueの場合、ゲートウェイに送信ビットの極性を反転するように指示します。 |
size | unsigned integer(任意) | 受信したフレームのオクテット数。 |
data | string(任意) | Base64にエンコードされたフレームペイロード。 Base64パディング文字は追加されません。 |
ncrc | bool(任意) | falseでない場合、トランスミッタによる物理層CRC生成を無効にします。 |
リスト4-1 rxpkの例
{ "time":"2013-03-31T16:21:17.528002Z", "tmst":3512348611, "chan":2, "rfch":0, "freq":866.349812, "stat":1, "modu":"LORA", "datr":"SF7BW125", "codr":"4/6", "rssi":-35, "lsnr":5.1, "size":32, "data":"-DS4CGaDCdG+48eJNM3Vai-zDpsR71Pn9CPA9uCON84" }
リスト4-2 txpkの例
{ "imme":true, "freq":864.123456, "rfch":0, "powe":14, "modu":"LORA", "datr":"SF11BW125", "codr":"4/6", "ipol":false, "size":32, "data":"H3P3N2i9qc4yt7rK7ldqoeCVJGBybzPY5h1Dd7P7p8v" }
Base64をrxpkからASCII文字列に変換するLoRaScriptサンプルコードをリスト4-3に示し、Base64エンコーディングでtxpkパケットを送信するためのリスト4-4に示します。
リスト4-3 LoRaScriptでのBase64からASCIIへのrxpkデータ
function onLoRaRx(data) { //convert base64 to ascii encoding var asciiStr = new Buffer(data, 'base64').toString('ascii'); debug_print("receive " + asciiStr); }
リスト4-4 LoRaScriptでtxパケットを作成して送信する
function onInit() { setInterval(period_send, 1000); // send a txpk in every 1 second } function period_send () { var msg = 'Hello World'; var msg_size = Buffer.byteLength(msg, 'asci'); var base64str = new Buffer(msg).toString('base64'); var json_obj = { imme:true, freq:915.5, rfch:0, powe:14, modu:"LORA", datr:"SF7BW125", codr:"4/6", ipol:false, size:msg_size, data:base64str }; send_pkt(JSON.stringify(json_obj)); }
var lora_packet = require('lora-packet'); function onInit() { debug_print("on init"); } function onLoRaRx (data) { debug_print("on Recv data"); var raw = JSON.parse(data); var lorawan_packet = new Buffer(raw.data, 'base64'); if(lorawan_packet.length>12){ var device = new Buffer(4); for (var i=0; i<4; i++) { device[i] = lorawan_packet[4-i]; } var packet = lora_packet.fromWire(lorawan_packet); var NwkSKey = new Buffer("2b7e151628aed2a6abf7158809cf4f3c", 'hex'); if(lora_packet.verifyMIC(packet, NwkSKey)){ var AppSKey = new Buffer("2b7e151628aed2a6abf7158809cf4f3c", 'hex'); var dec = lora_packet.decrypt(packet, AppSKey, NwkSKey).toString('hex'); var msg = { devaddr: device.toString('hex'), data: dec, fport: packet.getFPort(), counter: packet.getFCnt(), freq: raw.freq, datr: raw.datr }; debug_print(JSON.stringify(msg)); } } }