OC-Copper/oc/app/iot-mgr.lua

132 lines
3.5 KiB
Lua

-- I, 20kdc, release this into the public domain.
-- No warranty is provided, implied or otherwise.
-- Controller for objects following the 'IoT protocol'
-- (see <soontobe> provided microcontroller source)
local occure = require("occure")
local event = require("event")
local args = {...}
local cmdinfo = {
["help"] = {"Lists the commands"},
["discover"] = {"Sends a packet on the discovery port to a given address", "target"},
["get"] = {"Gets a value", "target", "index"},
["set"] = {"Sets a value", "target", "index", "data"},
["invoke"] = {"Runs an action", "target", "index", "data"}
}
local function packet(tp, idx, data)
return string.char(idx + (tp * 64)) .. data
end
local didGet = false
local getTarg = 0
local function getHelper(tp, tfrom, tto, p, d, u)
if tp ~= "copper_packet" then return end
if p == 4 then
if tto == occure.getHostname() then
if d:sub(1, 1) == packet(3, getTarg, "") then
print(d)
didGet = true
end
end
end
end
local function displayDisc(d)
local types = {
[0] = "void",
[0x40] = "void=",
[0x80] = "action(void)",
[1] = "string",
[0x41] = "string=",
[0x81] = "action(string)",
[2] = "boolean",
[0x42] = "boolean=",
[0x82] = "action(boolean)",
[3] = "float",
[0x43] = "float=",
[0x83] = "action(float)",
[4] = "descriptor",
[0x44] = "descriptor=",
[0x84] = "action(descriptor)",
}
while #d > 7 do
local tp = d:byte()
local n = types[tp] or ("unknown " .. tp)
print(" " .. d:sub(2, 8) .. ": " .. n)
d = d:sub(9)
end
end
local function discHelper(tp, tfrom, tto, p, d, u)
if tp ~= "copper_packet" then return end
if p == 4 then
if tto == occure.getHostname() then
if d:byte() == 0xC0 then
-- Discovery response.
print("\"" .. tfrom .. "\"")
displayDisc(d:sub(2))
end
end
end
end
local commands = {
["help"] = function ()
for k, v in pairs(cmdinfo) do
print(k .. ": " .. v[1])
for i = 2, #v do
print(" " .. v[i])
end
end
end,
["discover"] = function (target)
occure.output(target, 1, "", true)
event.listen("copper_packet", discHelper)
pcall(os.sleep, 10)
event.ignore("copper_packet", discHelper)
end,
["get"] = function (target, index)
index = tonumber(index)
local ack = false
getTarg = index
didGet = false
occure.output(target, 4, packet(0, index, ""), false, function() ack = true end)
event.listen("copper_packet", getHelper)
local safety = 0
while (not didGet) and (safety < 30) do
os.sleep(1)
safety = safety + 1
end
event.ignore("copper_packet", getHelper)
if not didGet then
if ack then
print("ACK'd but no response - bad parameters likely.")
else
print("Didn't get any response, not even an ACK.")
end
end
end,
["set"] = function (target, index, data)
index = tonumber(index)
local complete = nil
occure.output(target, 4, packet(1, index, data), false, function() complete = "acknowledged!" end, function() complete = "unacknowledged :(" end)
while not complete do
os.sleep(1)
end
print(complete)
end,
["invoke"] = function (target, index, data)
index = tonumber(index)
local complete = nil
occure.output(target, 4, packet(2, index, data), false, function() complete = "acknowledged!" end, function() complete = "unacknowledged :(" end)
while not complete do
os.sleep(1)
end
print(complete)
end
}
if not commands[args[1]] then error("No such command - try 'iot-mgr help'") end
if #args ~= #cmdinfo[args[1]] then error("Parameter count mismatch.") end
commands[args[1]](select(2, table.unpack(args)))