robathome icon

RoboMiner_remote

robathome | PRO | 10/18/25 08:04:39 PM UTC (Edited) | 0 ⭐ | 584 👁️ | Never ⏰ | []
text |

4.78 KB

|

None

|

0 👍

/

0 👎

-- 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)
 

Comments