データ送受信

OS上で動作するLuaプラグインとjavascriptSDKの間でデータのやり取りを行うことができます。

obniz.plugin.send()

obniz.js側からプラグインへバイナリ列を送信します。

// Javascript Example
obniz.plugin.send("obniz.js send data get device?")
obniz.plugin.send([0x00, 0x01, 0x02])

Luaプラグインではon_command()で受信します

function on_command(command)
  os.log(command)
end

obniz.plugin.onreceive

プラグイン側から送信されたバイナリ列を受け取ります。

// Javascript Example
obniz.plugin.onreceive = (data) => {
  console.log(data);
};

Luaプラグインではcloud.pluginSend()で送信します。

cloud.pluginSend("123");

obniz.plugin.onFrameStart / onFrameEnd

プラグイン側からフレーム情報が送られたときに呼び出されます。

大きなデータを送信する際にデータの区切りを示すのに便利です。
onFrameStartではプラグイン側から送信されたframe_idとデータの長さを受け取ることができ、その後大きなデータであれば何度かonreceiveでデータを受信することになります。そしてすべてのデータの受信が完了するとonFrameEndが呼び出されます。

// Javascript Example
  obniz.plugin!.onFrameStart = (frame_id, length) => {
    console.log(`frame start id=${frame_id} length=${length}`);
  }
  obniz.plugin!.onFrameEnd = () => {
    console.log(`frame ended`);
  }
  obniz.plugin!.onreceive = (data) => {
    console.log(`received=${Buffer.from(data).toString()}`);
  };

Luaプラグインでは以下のコマンドでの送信となります。

cloud.pluginSendFrameStart(frame_id, length); -- framing 
cloud.pluginSend("123");
cloud.pluginSend("456");
cloud.pluginSend("789");
cloud.pluginSendFrameEnd(); -- framing 

obniz.plugin.callWait()

OS7.1.0以降

端末でLuaスクリプトを実行し、その返り値を待ちます。execLua()がスクリプトを送って結果を待たないのに対し、callWait()はスクリプトがreturnした値を受け取ります。

スクリプトは端末のコルーチンの中で実行されます。そのため、実行中にLua側からcloud.transactionWait()(後述)を呼べます。

obniz.plugin.callWait(lua_script, timeout)
  • lua_script (string): 実行するLuaスクリプトです。返り値を文字列として受け取ります。
  • timeout (number, 任意): 結果を待つ時間(ミリ秒)です。既定値は30000です。

スクリプトがエラーを起こすと、返されるPromiseはそのエラーメッセージで拒否されます。

// Javascript Example

// Luaを実行し、返り値を待つ
const result = await obniz.plugin.callWait(`return "hello from lua"`);
console.log(result); // "hello from lua"

// Luaで計算した値を返せる
const sum = await obniz.plugin.callWait(`
  local x = 0
  for i = 1, 10 do x = x + i end
  return tostring(x)
`);
console.log(sum); // "55"

// Luaで起きたエラーはPromiseを拒否する
try {
  await obniz.plugin.callWait(`MUST FAILED`);
} catch (e) {
  console.log("lua error:", e.message);
}

cloud.transactionWait() / obniz.plugin.onCloudTransaction

OS7.1.0以降

データを一方向に送るだけのcloud.pluginSend()とは異なり、cloud.transactionWait()はobniz.jsへデータを送り、応答を待ちます。これにより、プラグインからクラウドへ問い合わせを行い、答えを受け取ってから処理を続けられます。

Luaプラグイン側

cloud.transactionWait()はデータを送信し、obniz.jsが応答するまで処理を中断したうえで、その結果を返します。処理を中断するため、この関数はLuaのコルーチンの中で実行してください。obniz.js側のobniz.plugin.callWait()は、スクリプトをコルーチンの中で実行します。

cloud.transactionWait(data, callback, timeout_ms)
  • data (string): obniz.jsへ送るデータです。
  • callback (function, 任意): 応答が届いたときにcallback(success, result)の形で呼ばれます。
  • timeout_ms (number, 任意): 応答を待つ時間(ミリ秒)です。既定値は30000です。

返り値はsuccess (boolean)とresult (stringまたはnil)の2つです。

os.log("start");

-- クラウドへ問い合わせ、応答を待つ(タイムアウト5000ms)
local success, result = cloud.transactionWait("ping", 5000)
if success then
  return result
else
  return "transaction failed"
end

Javascript Example

プラグインからの問い合わせはobniz.plugin.onCloudTransactionで受け取ります。このハンドラが返した値は、success = trueとともに、待機中のLuaのコルーチンへ渡されます。エラーをthrowすると、プラグインへsuccess = falseを返します。

// プラグインが cloud.transactionWait(data) を実行すると呼ばれる。
obniz.plugin.onCloudTransaction = async (data, str) => {
  console.log("lua asked cloud:", str);
  // 例えばここで外部APIを呼び、その応答を返す。
  return `echo:${str}`;
};

// callWait はスクリプトをコルーチンの中で実行するため、transactionWait が待機できる。
const result = await obniz.plugin.callWait(`
  local success, result = cloud.transactionWait("ping", 5000)
  if success then
    return result
  else
    return "transaction failed"
  end
`);
console.log("lua got back:", result); // "echo:ping"