Advertisement
DuckStrom

Computercraft Extractor Controller 3

Feb 9th, 2020
400
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.75 KB | None | 0 0
  1. --[[
  2. EyeDeck's RoC extractor controller
  3.  
  4. Recommended setup:
  5. _ M M M
  6. E C P P
  7. B G V I
  8.  
  9. M = CC Modem/cable
  10. E = Extractor
  11. C = Computer
  12. P = Peripheral Proxy (pointed down)
  13. B = Bevel gears (^<)
  14. G = 16:1 Bedrock Gearbox, speed mode
  15. V = CVT, w/lube and 31 belts
  16. I = Industrial Coil w/ external Redstone
  17.  
  18. Next, attach a 2x2 of advanced monitors,
  19. either to the computer, or via network cable.
  20.  
  21. Finally, to load, enter:
  22.   pastebin get 2varmnk0 wget
  23.   wget http://idek.chir.uno/mc/extractor.lua startup
  24.   startup
  25. --]]
  26.  
  27. coil_speed = 4096 -- constant
  28. stages = {
  29.   {ratio=-2, coil=4096, t=0.4}, -- 16MW: -2x CVT, 4096Nm coil, 0.4s, 32768 @ 512Nm  #1/t
  30.   -- 3/t? only 3rd stage matters here anyway
  31.   {ratio=32, coil=512,  t=0.6},  -- 2MW: 32x CVT, 512Nm coil, 0.6s, = 2097152 @ 1Nm; #2/t  x1.5  12
  32.   {ratio=1,  coil=4096, t=0.7}   -- 16MW, 1x CVT, 4096Nm coil 0.9s, = 65536 @ 256    #2/t  x1.5  18
  33. }
  34.  
  35. w_per_cycle = 0
  36. total_time = 0
  37. for _,stage in pairs(stages) do
  38.   w_per_cycle = w_per_cycle + (coil_speed * stage.coil * stage.t)
  39.   total_time = total_time + stage.t
  40. end
  41. avg_w = w_per_cycle / total_time
  42.  
  43. pwr_remaining_mult = avg_w * 60 * 60
  44.  
  45. f = fs.open("buttonAPI","r")
  46. if f == nil then
  47.   print("Attempting to fetch ButtonAPI...")
  48.   bapi = http.get("http://idek.chir.uno/mc/buttonAPI.lua")
  49.   if (bapi) then
  50.     f = fs.open("buttonAPI","w")
  51.     f.write(bapi.readAll())
  52.     f.close()
  53.     print("...complete, ButtonAPI has been downloaded.")
  54.   else
  55.     print("...failed, ButtonAPI could not be downloaded. Re-run this program to retry, or supply ButtonAPI manually.")
  56.     error("ButtonAPI download failed")
  57.   end
  58. else
  59.   f.close()
  60. end
  61. os.loadAPI("buttonAPI")
  62. ex, cvt, coil, mon = nil, nil, nil, nil
  63. warning = {}
  64. print("Checking peripherals...")
  65. while ex == nil or cvt == nil or coil == nil or mon == nil do
  66.   ex = peripheral.find("Extractor")
  67.   adv1,adv2 = peripheral.find("AdvancedGear")
  68.   mon = peripheral.find("monitor")
  69.   if adv1.getName() == "CVT Unit" then
  70.     cvt = adv1
  71.     coil = adv2
  72.   else
  73.     cvt = adv2
  74.     coil = adv1
  75.   end
  76.  
  77.   if ex == nil then
  78.     if warning.ex == nil then
  79.       print("Extractor missing!")
  80.       warning.ex = true
  81.     end
  82.      sleep(2)
  83.   elseif cvt == nil then
  84.     if warning.cvt == nil then
  85.       print("CVT missing!")
  86.       warning.cvt = true
  87.     end
  88.     sleep(2)
  89.   elseif coil == nil then
  90.     if warning.coil == nil then
  91.       print("Coil missing!")
  92.       warning.coil = true
  93.     end
  94.     sleep(2)
  95.   elseif mon == nil then
  96.     if warning.mon == nil then
  97.       print("Monitor missing!")
  98.       warning.mon = true
  99.     end
  100.     sleep(2)
  101.   else
  102.     break
  103.   end
  104. end
  105. print("All peripherals present.")
  106. peripherals = 0
  107. --Returns right-most item in extractor, else if empty returns false
  108. function notEmpty()
  109.   local item = {}
  110.   for i = 4,1,-1 do
  111.     item = getStackInSlot(ex,i)
  112.     if item ~= nil then
  113.       return item
  114.     end
  115.   end
  116.  
  117.   return false
  118. end
  119. function getItemNameList(p)
  120.   local items = {}
  121.   for i = 1,4,1 do
  122.     item = getStackInSlot(p,i)
  123.     if item == nil then
  124.       items[i] = " "
  125.     else
  126.       items[i] = string.format("%02d", item["qty"]) .. " x " .. item["display_name"]
  127.     end
  128.   end
  129.   return items
  130. end
  131. function getStackInSlot(p,slot)
  132.   sanityCheck()
  133.   local item = {}
  134.   item.raw_name, item.dmg, item.qty, item.display_name = p.getSlot(slot-1)
  135.  
  136.   -- make sure that nil is returned instead of a useless object if there is no item or the script will break in 12 different places
  137.   if item.qty ~= nil then
  138.     return item
  139.   else
  140.     return nil
  141.   end
  142. end
  143. -- A huge hack to prevent a crash when a peripheral is disconnected
  144. function sanityCheck()
  145.   if peripherals < 0 then
  146.     print("A peripheral has been detached!\nWaiting for reattachment...")
  147.     while peripherals < 0 do
  148.       sleep(2)
  149.     end
  150.     print("Resuming.")
  151.   end
  152. end
  153. function writeState(state,val)
  154.   if val == true then val = "1" else val = "0" end
  155.  
  156.   local file = fs.open("state_"..state,"w")
  157.   file.write(val)
  158.   file.close()
  159. end
  160. function readState(state)
  161.   local file = fs.open("state_"..state,"r")
  162.   local val
  163.  
  164.   if file == nil then
  165.     val = false
  166.   else
  167.     val = file.readAll()
  168.     if val == "1" then val = true else val = false end
  169.     file.close()
  170.   end
  171.  
  172.   return val
  173. end
  174.  
  175. function updateDisplay(state, items)
  176.   sanityCheck()
  177.   local old_disp = term.redirect(mon)
  178.   local power_in_hours = math.floor(coil.getEnergy() / pwr_remaining_mult * 100)*.01
  179.   local cx, cy = 2, 10
  180.  
  181.   -- term.setCursorPos(cx,cy)
  182.   if state == "ex" then
  183.     term.setTextColor(colors.lime)
  184.     writeCentered(term, cy, "-- Extracting --")
  185.   elseif state == "jam" then
  186.     term.setTextColor(colors.red)
  187.     writeCentered(term, cy, "-- Jammed! Check output -- ")
  188.   elseif state == "idle" then
  189.     term.setTextColor(colors.yellow)
  190.     writeCentered(term, cy, "-- Idle --")
  191.   end
  192.  
  193.   term.setTextColor(colors.white)
  194.   cx = cx + 2
  195.   for k,v in ipairs(items) do
  196.     cy = cy + 1
  197.     term.setCursorPos(cx,cy)
  198.     term.clearLine()
  199.     term.write(k .. ": " .. v)
  200.   end
  201.   cx = 2
  202.   cy = 23
  203.   term.setCursorPos(cx,cy - 2)
  204.   term.write("Current jam ct: ".. jam_count .."  ")
  205.  
  206.   term.setCursorPos(cx,cy)
  207.   term.clearLine()
  208.   term.write("Power remaining: ".. power_in_hours .."h")
  209.  
  210.   term.redirect(old_disp)
  211. end
  212. function writeCentered(p,y,txt)
  213.   p.setCursorPos(math.floor(mon_w / 2) - math.floor(#txt / 2), y)
  214.   p.clearLine()
  215.   p.write(txt)
  216. end
  217.  
  218. function exLoop()
  219.   while true do
  220.     if is_on then
  221.       print("Beginning extraction...")
  222.       jammed = false
  223.      
  224.       while is_on do
  225.         local current_item = notEmpty()
  226.        
  227.         items = getItemNameList(ex)
  228.         if current_item ~= false and jammed == false then
  229.           updateDisplay("ex", items)
  230.          
  231.           for _,stage in pairs(stages) do
  232.             sanityCheck()
  233.             cvt.setRatio(stage.ratio)
  234.             coil.setTorque(stage.coil)
  235.             sleep(stage.t)
  236.           end
  237.         else
  238.           if jammed == true then
  239.             updateDisplay("jam", items)
  240.           else
  241.             updateDisplay("idle", items)
  242.           end
  243.          
  244.           if auto_on then
  245.             sanityCheck()
  246.             coil.setTorque(0)
  247.             sleep(8)
  248.           else
  249.             is_on = false
  250.             buttonAPI.drawButton(mon,2,2,16,7,colors.black,colors.lime,"Start")
  251.           end
  252.         end
  253.       end
  254.    
  255.     sanityCheck()
  256.     coil.setTorque(0)
  257.     print("Ceasing extraction.")
  258.  
  259.     else -- is_on == false
  260.       sleep(2)
  261.     end
  262.   end
  263. end
  264.  
  265. function uiLoop()
  266.   while true do
  267.     sanityCheck()
  268.     local event, _, x, y = os.pullEvent("monitor_touch")
  269.     local button_name = buttonAPI.getButton(x,y)
  270.     --print(button_name .. " pressed at " .. x .. "," .. y)
  271.    
  272.     if button_name == "startstop" then
  273.       if is_on == false then
  274.         buttonAPI.drawButton(mon,2,2,16,7,colors.black,colors.red,"Stop")
  275.         is_on = true
  276.       else
  277.         buttonAPI.drawButton(mon,2,2,16,7,colors.black,colors.lime,"Start")
  278.         is_on = false
  279.       end
  280.       writeState("is_on",is_on)
  281.     elseif button_name == "manualauto" then
  282.       if auto_on == false then
  283.         buttonAPI.drawButton(mon,20,2,16,7,colors.black,colors.yellow,"Automatic")
  284.         auto_on = true
  285.       else
  286.         buttonAPI.drawButton(mon,20,2,16,7,colors.black,colors.blue,"Manual")
  287.         auto_on = false
  288.       end
  289.       writeState("auto_on",auto_on)
  290.     end
  291.   end  
  292. end
  293.  
  294. --[[
  295.   While main function is active, if the item in the output slot remains
  296.   unchanged for ~12 seconds or longer, assume the machine has jammed
  297.   and set a variable to stop the main loop.
  298. --]]
  299. function jamLoop()
  300.   -- local jam_count = 0 -- moved to global
  301.   local last_item = {}
  302.   local item = nil
  303.   local sleep_time = (len_torque + len_speed) * 1.333
  304.  
  305.   while true do
  306.     if is_on then
  307.       item = getStackInSlot(ex,9)
  308.       if item == nil then
  309.         item = notEmpty() -- get right-most item other than extra output
  310.         if item == false then
  311.           item = nil
  312.         end
  313.       end
  314.  
  315.       if item == nil then
  316.         last_item = {}
  317.         jammed = false
  318.         jam_count = 0
  319.       else
  320.         -- comparing the item object directly doesn't work, test count and name instead
  321.         if last_item.display_name == item.display_name and last_item.qty == item.qty then
  322.           jam_count = jam_count + 1
  323.         else
  324.           jam_count = 0
  325.         end
  326.        
  327.         last_item = item
  328.        
  329.         if jam_count >= 6 then
  330.           if jammed == false then
  331.             jammed = true
  332.             print("Extractor jammed!")
  333.           end
  334.         else
  335.           jammed = false
  336.         end
  337.       end
  338.     end
  339.    
  340.     sleep(sleep_time)
  341.   end
  342. end
  343. function peripheralLoop()
  344.   while true do
  345.     local event = os.pullEvent()
  346.     if event == "peripheral" then
  347.       peripherals = peripherals + 1
  348.       print("A peripheral has been detached!")
  349.     end
  350.     if event == "peripheral_detach" then
  351.       peripherals = peripherals - 1
  352.       print("A peripheral has been reattached!")
  353.     end
  354.   end
  355. end
  356. mon.setTextScale(0.5)
  357. mon.setBackgroundColor(colors.black)
  358. mon.setTextColor(colors.white)
  359. mon.clear()
  360. mon_w, mon_h = mon.getSize()
  361. -- write(mon_w)
  362.  
  363. coil.setSpeed(4096)
  364. coil.setTorque(0)
  365. is_on = readState("is_on")
  366. auto_on = readState("auto_on")
  367. buttonAPI.drawButton(mon,2,2,16,7,colors.black,is_on and colors.red or colors.lime,is_on and "Stop" or "Start","startstop")
  368. buttonAPI.drawButton(mon,20,2,16,7,colors.black,auto_on and colors.yellow or colors.blue,auto_on and "Automatic" or "Manual","manualauto")
  369. jam_count = 0
  370.  
  371. items = getItemNameList(ex)
  372. if (notEmpty() ~= false) then
  373.   updateDisplay("ex", items)
  374. else
  375.   updateDisplay("idle", items)
  376. end
  377.  
  378. parallel.waitForAll(uiLoop, exLoop, jamLoop, peripheralLoop)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement