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));
}
}
}