Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- pocket_startup.lua
- -- Pocket controller for CC:Tweaked. REPL to drive miners via the base controller.
- -- Requires: pocket with Ender (wireless) modem upgrade.
- -- Protocols (match your controller)
- local PROTOCOL = "minesys:v1" -- miner heartbeats (read-only here)
- local CTL_PROTO = "minesys:ctl" -- controller RPC (goto, clear, face, fwd, up, dn)
- -- ---- init ----
- local modem = peripheral.find("modem", function(_,p) return p.isWireless() end)
- if not modem then error("No wireless modem on pocket") end
- rednet.open(peripheral.getName(modem))
- pcall(function() rednet.host("minesys:pocket", "pocket_"..(os.getComputerLabel() or os.getComputerID())) end)
- -- ---- state ----
- local function now() return os.epoch("utc") end
- local turtles = {} -- by label or id: {id,label,pos,fuel,freePct,status,seen}
- local function upsertStatus(m)
- local key = m.label or m.id
- if not key then return end
- local t = turtles[key] or {}
- t.id = m.id or t.id
- t.label = m.label or t.label or ("t"..tostring(m.id or ""))
- t.pos = m.pos or t.pos
- t.fuel = m.fuel or t.fuel
- t.status = m.status or t.status
- if m.extra and m.extra.inv then t.freePct = m.extra.inv.freePct end
- t.seen = now()
- turtles[key] = t
- end
- -- ---- UI helpers ----
- local function listTurtles()
- term.clear(); term.setCursorPos(1,1)
- print("Turtles (label fuel free% x,y,z status):")
- for _,t in pairs(turtles) do
- local pos = t.pos and (t.pos.x..","..t.pos.y..","..t.pos.z) or "?, ?, ?"
- local free = t.freePct and string.format("%d", math.floor(t.freePct+0.5)) or "--"
- print(string.format("%-14s %-6s %-4s %s [%s]",
- t.label or "?", tostring(t.fuel or "?"), free, pos, t.status or "?"))
- end
- end
- local function help()
- print("list")
- print("fac <label> <N|E|S|W>")
- print("fwd <label> <n>")
- print("up <label> <n>")
- print("dn <label> <n>")
- print("clear <label> <L> <W> <H> <N|E|S|W>")
- print("goto <label> <x> <y> <z> [order yxz|xyz|...]\n")
- end
- -- ---- controller RPC ----
- local function ctlReq(payload)
- payload.op = "req"
- payload.ref = math.random(1,1e9)
- rednet.broadcast(payload, CTL_PROTO)
- local tm = os.startTimer(4)
- while true do
- local ev,a,b,c = os.pullEvent()
- if ev=="rednet_message" then
- local sid,msg,proto = a,b,c
- if proto==CTL_PROTO and type(msg)=="table" and msg.op=="resp" and msg.ref==payload.ref then
- return msg.ok, msg.err
- end
- elseif ev=="timer" and a==tm then
- return false, "timeout"
- end
- end
- end
- -- ---- REPL command wrappers ----
- local function cmd_face(lab, dir)
- if dir=="" then print("need dir"); return end
- local ok,err = ctlReq({act="face", label=lab, dir=dir})
- print(ok and "ok" or ("err: "..tostring(err)))
- end
- local function cmd_fwd(lab, n)
- local ok,err = ctlReq({act="fwd", label=lab, n=tonumber(n) or 1})
- print(ok and "ok" or ("err: "..tostring(err)))
- end
- local function cmd_up(lab, n)
- local ok,err = ctlReq({act="up", label=lab, n=tonumber(n) or 1})
- print(ok and "ok" or ("err: "..tostring(err)))
- end
- local function cmd_dn(lab, n)
- local ok,err = ctlReq({act="dn", label=lab, n=tonumber(n) or 1})
- print(ok and "ok" or ("err: "..tostring(err)))
- end
- local function cmd_clear(lab, L, W, H, dir)
- local ok,err = ctlReq({
- act="clear", label=lab,
- L=tonumber(L), W=tonumber(W), H=tonumber(H), dir=dir
- })
- print(ok and "ok" or ("err: "..tostring(err)))
- end
- local function parseOrder(ord)
- if ord and #ord==3 then return {ord:sub(1,1), ord:sub(2,2), ord:sub(3,3)} end
- return nil
- end
- local function cmd_goto(lab,x,y,z,ord)
- local function parseOrder(o) return (o and #o==3) and {o:sub(1,1),o:sub(2,2),o:sub(3,3)} or nil end
- local ok,err = ctlReq({act="goto", label=lab, x=tonumber(x), y=tonumber(y), z=tonumber(z), order=parseOrder(ord)})
- print(ok and "ok" or ("err: "..tostring(err)))
- end
- -- ---- threads ----
- local function inputThread()
- term.clear(); term.setCursorPos(1,1)
- print("Pocket miner controller. type 'help'.")
- while true do
- io.write("> ")
- local line = read()
- local a,b,c,d,e,f = line:match("^(%S+)%s*(%S*)%s*(%S*)%s*(%S*)%s*(%S*)%s*(%S*)")
- if a=="help" then help()
- elseif a=="list" then listTurtles()
- elseif a=="fac" then cmd_face(b,c)
- elseif a=="fwd" then cmd_fwd(b,c)
- elseif a=="up" then cmd_up(b,c)
- elseif a=="dn" then cmd_dn(b,c)
- elseif a=="clear" then cmd_clear(b,c,d,e,f)
- elseif a=="goto" then cmd_goto(b,c,d,e,f)
- elseif a=="" then
- else print("unknown") end
- end
- end
- local function netThread()
- while true do
- local id,msg,proto = rednet.receive(PROTOCOL, 5)
- if id and proto==PROTOCOL and type(msg)=="table" and msg.op=="status" then
- upsertStatus(msg)
- end
- end
- end
- parallel.waitForAny(inputThread, netThread)
Advertisement
Add Comment
Please, Sign In to add comment