OS7以降
プラグインを利用することで、端末上で直接プログラムを動かすことができます。
これによりobnizの端末のみでオフライン時の動作や通信データの圧縮など高度な最適化が可能となります。

書き込みと実行
Luaはネットワーク接続と関係なく、OSの起動時からOSにより即座に実行が開始されます。
シリアルコンソールではなくobniz.jsからLuaを書き込むには以下のように文字列を送信し保存します。
obniz.storage.savePluginLua()を利用することで内部のフラッシュを上書きします。こちらは上書きするだけで実際の実行は再起動後となります。即座に適用するにはobniz.plugin.reloadLua()を呼び出します。
// Javascript Example
obniz.storage.savePluginLua(`
os.log("Hello World")
`);
obniz.plugin.reloadLua();
二重書き込みの阻止
接続ごとにPluginを書き換えると内部のフラッシュメモリの寿命に影響が出ます。
そこで、期待するLuaが入っていたら書き込まないような処理が必要です。obnizOSは起動したときに読み出したLuaの名称を送信するため、これを比較することで防ぐことができます。obniz.plugin_nameには起動時に利用されたpluginの名前が入ります。pluginの名前はLuaの中でplugin_name()関数の返り値として指定できます。
// Javascript Example
if (obniz.plugin_name !== 'my_plugin') {
console.log("Must Load Plugin");
obniz.storage.savePluginLua(`
function plugin_name()
return "my_plugin" -- max 30 chars
end
`);
obniz.plugin!.reloadLua();
obniz.reboot(); // Not necessary on every case.
} else {
console.log("No Need to Load Plugin");
}
随時実行
Luaスクリプトは本体に保存せずともSDK経由で随時実行することが可能です。
// Javascript Example
obniz.plugin!.execLua(`
x=1;
x=x+2;
os.log(x.."\\n")
`); // will print "3" on obnizOS console(need console enabled)
obniz.plugin!.execLua(`os.log(os.getTick().."\\n")`);
obniz.plugin!.execLua(`os.log(os.getTick().."\\n")`);
この機能を利用することで、端末を再起動することなく必要な関数・変数を随時更新することができます。
これによりダウンタイムを発生させることなく高速に端末の挙動を最適化し、通信量を最大限圧縮することが可能となります。
通信頻度を値によってクラウドから変更する例
// Javascript Example
if (temperature > 26) {
obniz.plugin!.execLua(`
interval = 1;
`);
} else {
obniz.plugin!.execLua(`
interval = 60;
`);
}
送信されるデータの種類をモードによって切り替える例
if (mode == 'temperature') {
obniz.plugin!.execLua(`
function filter(data)
if data.temperature == nil then
return nil
end
return data
end
`);
} else {
obniz.plugin!.execLua(`
function filter(data)
return data
end
`);
}
対応している全Lua向けのobniz関数
-- System Event Handler
function on_event(event)
if event == "power_on" then
elseif event == "setting_mode" then
elseif event == "connecting_to_network" then
elseif event == "connecting_to_cloud" then
elseif event == "online" then
end
end
-- func(int), module(int), data(string(uint8 array))
function on_upstream(func, module, data)
if necessary then
return 1;
elseif rightnow then
return 2;
elseif mustDrop then
cloud.upstreamEnqueue(1, 2, str); -- change to differenct command
cloud.upstreamFlush(); -- optional
return 0;
end
end
-- received from obnis.js
function on_command(command)
cloud.pluginSend("123");
end
-- called while online every around 1msec
function on_online_loop()
-- os.log(\"online_loop\");
end
-- called while offline every around 1msec
-- You should care about communication because this function will be called
-- different thread.
function on_offline_loop()
-- os.log(\"offline_loop\");
end
function on_self_check()
os.log(" - self check ok");
end
function plugin_name() -- will be get by obniz.plugin_name
return "my_plugin"
end
-- Available Functions
-- OS
os.getTick(); -- system tick in msec
os.getUnixTime(); -- get seconds from 1970/1/1. you must adjust time by calling pingWait();
os.log("hello world");
os.wait(1000); -- 1,000msec wait
os.reboot();
os.resetOnDisconnect(false); -- It will never reset after disconnection. And queued data never lost when offline.
os.sleep(5 * 1000, 0); -- deep sleep + external module sleep.
os.sleep(5 * 1000, 1); -- deep sleep + without external module sleep.
os.sleep(5 * 1000, 2); -- light sleep + external module sleep.
os.sleep(5 * 1000, 3); -- light sleep + without external module
os.getVersion();
os.getHW();
-- storage file
storage.fileOpen("text.txt")
storage.fileWrite("ABC");
storage.fileAppend("abcdefg");
length = storage.fileGetSize();
data = storage.fileRead(0, length);
storage.fileClose();
-- storage kvs
error = storage.kvsSave({ name = "Yuki", attr = { engineer = true } })
data = storage.kvsLoad();
-- Cloud
cloud.connect();
cloud.disconnect();
cloud.upstreamEnqueue(0, 1, data) -- module func data
cloud.pluginSend(data);
cloud.pluginSendFrameStart(frame_id, length); -- framing
cloud.pluginSendFrameEnd(); -- framing
cloud.enqueueTimestampByTick(os.getTick()-1000); -- it will enqueue unix timestamp
-- io
io.retain(1, true);
io.output(1, true);
local val = io.input(1);
-- ad
local val = ad.get(1); -- 0.0v~3.3v
-- uart
uart.start(1, 2, 9600) -- tx:io1 rx:io2 baud:9600
uart.send("hello");
local data = uart.recv() -- uart.recv(1) limit to 1byte max
if #data > 1 then
os.log(data); -- received
end
-- spi
local err = spi.start(20, 21, 19, 8, 100 * 1000); -- MOSI, MISO, CLK, CS(could be null for non shared SPI), baudrate
if err > 0 then
os.log("SPI Error: " .. err);
return
end
let result = spi.write(string.char(0x40, 0x00, 0xC0)); -- result must be 3bytes if success.
-- wifi
wifi.on();
wifi.off();
wifi.sniffStart(callback);
wifi.sniffSetChannel(2);
wifi.sniffStop();
-- ble
ble.on();
ble.off();
ble.scanStart(onFind, { -- default option values
active=true,
interval=16,
window=16,
phy1m=true,
phyCoded=true,
duplicate=true
});