This document describes how to exchange data between a Lua plugin running on the obniz OS and the obniz JavaScript SDK.
Overview
You can facilitate communication between a Lua plugin operating on the device OS and the JavaScript SDK. This allows for bidirectional data transfer and efficient handling of large data sets.
obniz.plugin.send()
Sends a binary data sequence from the obniz.js side to the Lua plugin.
Javascript Example
// Send string data
obniz.plugin.send("obniz.js send data get device?");
// Send byte array
obniz.plugin.send([0x00, 0x01, 0x02]);
Lua Plugin Side
On the Lua side, use the on_command() function to receive the data.
function on_command(command)
-- 'command' contains the data sent from JS
os.log(command)
end
obniz.plugin.onreceive
This event handler receives a binary data sequence sent from the Lua plugin to the obniz.js side.
Javascript Example
obniz.plugin.onreceive = (data) => {
console.log(data);
};
Lua Plugin Side
Use cloud.pluginSend() to send data to the JavaScript SDK.
cloud.pluginSend("123");
obniz.plugin.onFrameStart / onFrameEnd
These handlers are triggered when frame information is sent from the plugin side.
These functions are particularly useful for segmenting and managing large data transfers.
onFrameStart: Receives theframe_idand the totallengthof the data.onreceive: For large payloads, the data will be received in multiple chunks through this handler.onFrameEnd: Called once all data defined in the frame has been completely received.
Javascript Example
// Handle the start of a frame
obniz.plugin.onFrameStart = (frame_id, length) => {
console.log(`Frame start: ID=${frame_id}, Total Length=${length}`);
};
// Handle the end of a frame
obniz.plugin.onFrameEnd = () => {
console.log("Frame reception completed");
};
// Receive chunks of data
obniz.plugin.onreceive = (data) => {
console.log(`Received chunk: ${Buffer.from(data).toString()}`);
};
Lua Plugin Side
To use framing in a Lua plugin, use the following commands:
local frame_id = 1
local total_length = 9
cloud.pluginSendFrameStart(frame_id, total_length); -- Start framing
cloud.pluginSend("123");
cloud.pluginSend("456");
cloud.pluginSend("789");
cloud.pluginSendFrameEnd(); -- End framing
obniz.plugin.callWait()
Available for OS7.1.0 and later
Runs a Lua script on the device and waits for its return value. While execLua() simply fires a script and forgets it, callWait() resolves with whatever the script returns.
The script runs inside a coroutine on the device, which lets the Lua side call cloud.transactionWait() (see below) while it runs.
obniz.plugin.callWait(lua_script, timeout)
lua_script(string): The Lua script to run. Its return value is resolved as a string.timeout(number, optional): The time to wait for a result, in milliseconds. Defaults to30000.
If the script raises an error, the returned Promise is rejected with that error message.
// Javascript Example
// Run Lua and wait for its return value
const result = await obniz.plugin.callWait(`return "hello from lua"`);
console.log(result); // "hello from lua"
// Lua can compute and return a value
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"
// An error raised in Lua rejects the Promise
try {
await obniz.plugin.callWait(`MUST FAILED`);
} catch (e) {
console.log("lua error:", e.message);
}
cloud.transactionWait() / obniz.plugin.onCloudTransaction
Available for OS7.1.0 and later
Unlike cloud.pluginSend(), which only sends data one way, cloud.transactionWait() sends data to obniz.js and waits for a reply. The plugin can therefore ask the cloud a question and continue once the answer arrives.
Lua Plugin Side
cloud.transactionWait() sends data and suspends until obniz.js responds, then returns the result. Because it suspends, it must run inside a Lua coroutine. The obniz.plugin.callWait() method on the obniz.js side runs the script within a coroutine for you.
cloud.transactionWait(data, callback, timeout_ms)
data(string): The data to send to obniz.js.callback(function, optional): Called ascallback(success, result)when the reply arrives.timeout_ms(number, optional): The time to wait for a reply, in milliseconds. Defaults to30000.
It returns two values: success (boolean) and result (string or nil).
os.log("start");
-- Ask the cloud and wait for the reply (timeout 5000ms)
local success, result = cloud.transactionWait("ping", 5000)
if success then
return result
else
return "transaction failed"
end
Javascript Example
Handle the request from the plugin with obniz.plugin.onCloudTransaction. Whatever the handler returns is passed back to the waiting Lua coroutine with success = true. Throwing an error reports success = false to the plugin.
// Called when the plugin runs cloud.transactionWait(data).
obniz.plugin.onCloudTransaction = async (data, str) => {
console.log("lua asked cloud:", str);
// For example, call an external API here and return its response.
return `echo:${str}`;
};
// callWait runs the script inside a coroutine so transactionWait can wait.
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"