Advertisement
DuckStrom

Computercraft Extractor Controller 2

Oct 29th, 2016
215
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --EyeDeck's extractor controller program
  2. f = fs.open("buttonAPI","r")
  3. if f == nil then
  4.   print("Attempting to fetch ButtonAPI...")
  5.   bapi = http.get("http://idek.chir.uno/mc/buttonAPI.lua")
  6.   if (bapi) then
  7.     f = fs.open("buttonAPI","w")
  8.     f.write(bapi.readAll())
  9.     f.close()
  10.     print("...complete, ButtonAPI has been downloaded.")
  11.   else
  12.     print("...failed, ButtonAPI could not be downloaded. Re-run this program to retry, or supply ButtonAPI manually.")
  13.     error("ButtonAPI download failed")
  14.   end
  15. else
  16.   f.close()
  17. end
  18. os.loadAPI("buttonAPI")
  19.  
  20. ex, cvt, coil, mon = nil, nil, nil, nil
  21.  
  22. warning = {}
  23. print("Checking peripherals...")
  24. while ex == nil or cvt == nil or coil == nil or mon == nil do
  25.   ex = peripheral.find("Extractor")
  26.   adv1,adv2 = peripheral.find("AdvancedGear")
  27.   mon = peripheral.find("monitor")
  28.  
  29.   if adv1.getName() == "CVT Unit" then
  30.     cvt = adv1
  31.     coil = adv2
  32.   else
  33.     cvt = adv2
  34.     coil = adv1
  35.   end
  36.  
  37.   if ex == nil then
  38.     if warning.ex == nil then
  39.       print("Extractor missing!")
  40.       warning.ex = true
  41.     end
  42.      sleep(2)
  43.   elseif cvt == nil then
  44.     if warning.cvt == nil then
  45.       print("CVT missing!")
  46.       warning.cvt = true
  47.     end
  48.     sleep(2)
  49.   elseif coil == nil then
  50.     if warning.coil == nil then
  51.       print("Coil missing!")
  52.       warning.coil = true
  53.     end
  54.     sleep(2)
  55.   elseif mon == nil then
  56.     if warning.mon == nil then
  57.       print("Monitor missing!")
  58.       warning.mon = true
  59.     end
  60.     sleep(2)
  61.   else
  62.     break
  63.   end
  64. end
  65. print("All peripherals present.")
  66.  
  67. peripherals = 0
  68.  
  69. --Returns right-most item in extractor, else if empty returns false
  70. function notEmpty()
  71.   item = {}
  72.   for i = 4,1,-1 do
  73.     item = getStackInSlot(ex,i)
  74.     if item ~= nil then
  75.       return item
  76.     end
  77.   end
  78.  
  79.   return false
  80. end
  81.  
  82. function getStackInSlot(p,slot)
  83.   sanityCheck()
  84.   item = {}
  85.   item.raw_name, item.dmg, item.qty, item.display_name = p.getSlot(slot-1)
  86.  
  87.   -- 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
  88.   if item.qty ~= nil then
  89.     return item
  90.   else
  91.     return nil
  92.   end
  93. end
  94.  
  95. -- A huge hack to prevent a crash when a peripheral is disconnected
  96. function sanityCheck()
  97.   if peripherals < 0 then
  98.     print("A peripheral has been detached!\nWaiting for reattachment...")
  99.     while peripherals < 0 do
  100.       sleep(2)
  101.     end
  102.     print("Resuming.")
  103.   end
  104. end
  105.  
  106. function writeState(state,val)
  107.   if val == true then val = "1" else val = "0" end
  108.  
  109.   local file = fs.open(state,"w")
  110.   file.write(val)
  111.   file.close()
  112. end
  113.  
  114. function readState(state)
  115.   local file = fs.open(state,"r")
  116.   local val
  117.  
  118.   if file == nil then
  119.     val = false
  120.   else
  121.     val = file.readAll()
  122.     if val == "1" then val = true else val = false end
  123.     file.close()
  124.   end
  125.  
  126.   return val
  127. end
  128.  
  129. function updateDisplay(name)
  130.   sanityCheck()
  131.   local old_disp = term.redirect(mon)
  132.   local power_in_hours = math.floor(coil.getEnergy() / 37507786621 * 100)*.01
  133.  
  134.   if name == nil then -- prevent a crash just in case
  135.     name = "nil"
  136.   end
  137.  
  138.   term.setCursorPos(2,10)
  139.   term.setTextColor(colors.white)
  140.   -- extra spaces are a hack to clear the last item if necessary ("Ammonium Chloride Solution" is long)
  141.   write("Extracting: ".. name .."                     \n                       ")
  142.   term.setCursorPos(2,12)
  143.   write("Power remaining: ".. power_in_hours .."h         ")
  144.   term.redirect(old_disp)
  145. end
  146.  
  147. function exLoop()
  148.   while true do
  149.     if isOn then
  150.       print("Beginning extraction...")
  151.       jammed = false
  152.      
  153.       while isOn do
  154.         local currentItem = notEmpty()
  155.        
  156.         if currentItem ~= false and jammed == false then
  157.           updateDisplay(currentItem.display_name)
  158.           coil.setSpeed(4096)
  159.          
  160.           sanityCheck()
  161.           cvt.setRatio(1)
  162.           coil.setTorque(4096)
  163.           sleep(0.75) --sleep(4.2)
  164.          
  165.           sanityCheck()
  166.           cvt.setRatio(32)
  167.           coil.setTorque(256)
  168.           sleep(0.5) --sleep(2.85)
  169.         else
  170.           if jammed == true then
  171.             updateDisplay("Jammed (check output)")
  172.           else
  173.             updateDisplay("Idle")
  174.           end
  175.          
  176.           if autoOn then
  177.             sanityCheck()
  178.             coil.setTorque(0)
  179.             sleep(8)
  180.           else
  181.             isOn = false
  182.             buttonAPI.drawButton(mon,2,2,16,7,colors.black,colors.lime,"Start")
  183.           end
  184.         end
  185.       end
  186.    
  187.     sanityCheck()
  188.     coil.setTorque(0)
  189.     print("Ceasing extraction.")
  190.  
  191.     else -- isOn == false
  192.       sleep(2)
  193.     end
  194.   end
  195. end
  196.  
  197. function uiLoop()
  198.   while true do
  199.     sanityCheck()
  200.     event, _, x, y = os.pullEvent("monitor_touch")
  201.     local button_name = buttonAPI.getButton(x,y)
  202.     --print(button_name .. " pressed at " .. x .. "," .. y)
  203.    
  204.     if button_name == "startstop" then
  205.       if isOn == false then
  206.         buttonAPI.drawButton(mon,2,2,16,7,colors.black,colors.red,"Stop")
  207.         isOn = true
  208.       else
  209.         buttonAPI.drawButton(mon,2,2,16,7,colors.black,colors.lime,"Start")
  210.         isOn = false
  211.       end
  212.       writeState("isOn",isOn)
  213.     elseif button_name == "manualauto" then
  214.       if autoOn == false then
  215.         buttonAPI.drawButton(mon,20,2,16,7,colors.black,colors.yellow,"Automatic")
  216.         autoOn = true
  217.       else
  218.         buttonAPI.drawButton(mon,20,2,16,7,colors.black,colors.blue,"Manual")
  219.         autoOn = false
  220.       end
  221.       writeState("autoOn",autoOn)
  222.     end
  223.   end  
  224. end
  225.  
  226. --[[
  227.   While main function is active, if the item in the output slot remains
  228.   unchanged for ~12 seconds or longer, assume the machine has jammed
  229.   and set a variable to stop the main loop.
  230. --]]
  231. function jamLoop()
  232.   local jamCount = 0
  233.   local lastItem = {}
  234.   local item = nil
  235.  
  236.   while true do
  237.     if isOn then
  238.       item = getStackInSlot(ex,9)
  239.       if item == nil then
  240.         item = getStackInSlot(ex,8)
  241.       end
  242.  
  243.       if item == nil then
  244.         lastItem = {}
  245.         jammed = false
  246.         jamCount = 0
  247.       else
  248.         -- comparing the item object directly doesn't work anymore, test count and name instead
  249.         if lastItem.display_name == item.display_name and lastItem.qty == item.qty then
  250.           jamCount = jamCount + 1
  251.         else
  252.           jamCount = 0
  253.         end
  254.        
  255.         lastItem = item
  256.        
  257.         if jamCount >= 3 then
  258.           if jammed == false then
  259.             jammed = true
  260.             print("Extractor jammed!")
  261.           end
  262.         else
  263.           jammed = false
  264.         end
  265.       end
  266.     end
  267.    
  268.     sleep(4)
  269.   end
  270. end
  271.  
  272. function peripheralLoop()  
  273.   while true do
  274.     local event = os.pullEvent()
  275.     if event == "peripheral" then
  276.       peripherals = peripherals + 1
  277.       print("A peripheral has been detached!")
  278.     end
  279.     if event == "peripheral_detach" then
  280.       peripherals = peripherals - 1
  281.       print("A peripheral has been reattached!")
  282.     end
  283.   end
  284. end
  285.  
  286. mon.setTextScale(0.5)
  287. mon.setBackgroundColor(colors.black)
  288. mon.setTextColor(colors.white)
  289. mon.clear()
  290.  
  291. coil.setSpeed(4096)
  292. coil.setTorque(0)
  293.  
  294. isOn = readState("isOn")
  295. autoOn = readState("autoOn")
  296.  
  297. buttonAPI.drawButton(mon,2,2,16,7,colors.black,isOn and colors.red or colors.lime,isOn and "Stop" or "Start","startstop")
  298. buttonAPI.drawButton(mon,20,2,16,7,colors.black,autoOn and colors.yellow or colors.blue,autoOn and "Automatic" or "Manual","manualauto")
  299.  
  300. if (notEmpty() ~= false) then
  301.   updateDisplay(notEmpty().display_name)
  302. else
  303.   updateDisplay("Idle")
  304. end
  305.  
  306. parallel.waitForAll(uiLoop, exLoop, jamLoop, peripheralLoop)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement