meigrafd

Computer Reactor Master (0.7)

Jul 9th, 2015
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 15.79 KB | None | 0 0
  1. --[[ (comment block)
  2.  
  3.  by meigrafd @ 09.07.2015
  4.  
  5.  Version History:
  6.  - Computer
  7.   http://pastebin.com/ewb0tM52
  8.   http://pastebin.com/EJxbbxyN
  9.  - Turtle
  10.   http://pastebin.com/YUfiniV9
  11.   http://pastebin.com/6BSDQzEm
  12.  
  13.  
  14.  Requires:
  15.    ComputerCraft >=1.5
  16.    OpenCCsensors >=1.7.5
  17.    OpenPeripheral
  18.  
  19.  Setup Reactor like:
  20.  
  21.  Bundled Cable ends to Computer.
  22.  First Thermal Sensor turns Reactor off. Set this to max 1000.
  23.  Second Thermal Sensor tells Turtle to drop Uran Cells to prevent explosion. Set this to max 2500.
  24.   (when Reactor was on it will still head up also after shutdown)
  25.  For a little bit better Cooling and Blastprotection you also should add Water above the complete Reactor.
  26.  
  27.  Setup Reactor Inventory as:
  28.    http://s2.postimage.org/5r41iiq15/Reactor_Setup.jpg
  29.  (biggest Setup with 1120 EU/t)
  30.  
  31.  Use a Wireless Turtle (modem always on the left side) and add a Wireless Modem to your Computer.
  32.  Place a OpenCCsensor to any side of your Computer and add an 'Inventory Sensor Card'.
  33.  Install the Scripts as 'startup'.
  34.  First start Script on Computer and only then on Turtle.
  35.  
  36.  Optional:
  37.  Execute once in Terminal of Cumputer near Reactor: label set reacomp
  38.  and on the Turtle: label set reatur
  39.  
  40. --]]
  41.  
  42.  
  43. ---[[ CONFIG - START ]]
  44.  
  45.  
  46. local UseReactorSetup = 2
  47. --[[ Set to 1 or 2.
  48. 1 = Biggest with five Quad-Fuel-Rods in a row, twice.
  49. 2 = three Quad-Fuel-Rods in a row, twice.
  50. --]]
  51.  
  52. local CheckEvery = 1 -- sec. Dont set too high! (but also not lower 0.5)
  53.  
  54. -- Modem channel. Must be same as Turtle uses
  55. local ModemChannel = 32768 -- Broadcast channel.
  56.  
  57. -- Wire Colors. Available Colors with Bundled Cable: http://computercraft.info/wiki/Colors_(API)#Colors
  58. wireReactor = colors.green -- To turn Reactor on/off
  59. wireThermal1 = colors.blue -- If Reactor Temperature gets >1000
  60. wireThermal2 = colors.red -- If Reactor Temperature gets >2000
  61.  
  62. -- Bundled Cable Side on Computer. Only valid sides: bottom, top, back, front, right, left
  63. wireSide = "bottom"
  64. --sometimes "right" doesnt work..
  65.  
  66.  
  67. ---[[ CONFIG - END ]]
  68.  
  69.  
  70.  
  71. --[[
  72.   Required Reactor Inventory setup Table.
  73.   first row from left to right, then the second row from left to right, etc.
  74.   one row = 9 columns.
  75.   NOTE: Not the exact Item-Name is used, just a match of e.g. *Coolant* so 10k or 60k Coolant Cells can be used,
  76.         but better use 60k Coolant Cells instead of 10k.
  77. --]]
  78.  
  79. if UseReactorSetup == 1 then
  80.     -- 5 Quad-Fuel-Rods in a row, twice.
  81.     RequiredReactorInventory = {
  82.         "Reactor Heat Vent",
  83.         "Reactor Heat Vent",
  84.         "Reactor Heat Vent",
  85.         "Reactor Heat Vent",
  86.         "Reactor Heat Vent",
  87.         "Reactor Heat Vent",
  88.         "Reactor Heat Vent",
  89.         "Reactor Heat Vent",
  90.         "Reactor Heat Vent",
  91.    
  92.         "Reactor Heat Vent",
  93.         "Coolant Cell",
  94.         "Coolant Cell",
  95.         "Coolant Cell",
  96.         "Coolant Cell",
  97.         "Coolant Cell",
  98.         "Coolant Cell",
  99.         "Coolant Cell",
  100.         "Reactor Heat Vent",
  101.    
  102.         "Reactor Heat Vent",
  103.         "Coolant Cell",
  104.         "Uran",
  105.         "Uran",
  106.         "Uran",
  107.         "Uran",
  108.         "Uran",
  109.         "Coolant Cell",
  110.         "Reactor Heat Vent",
  111.    
  112.         "Reactor Heat Vent",
  113.         "Coolant Cell",
  114.         "Uran",
  115.         "Uran",
  116.         "Uran",
  117.         "Uran",
  118.         "Uran",
  119.         "Coolant Cell",
  120.         "Reactor Heat Vent",
  121.    
  122.         "Reactor Heat Vent",
  123.         "Coolant Cell",
  124.         "Coolant Cell",
  125.         "Coolant Cell",
  126.         "Coolant Cell",
  127.         "Coolant Cell",
  128.         "Coolant Cell",
  129.         "Coolant Cell",
  130.         "Reactor Heat Vent",
  131.    
  132.         "Reactor Heat Vent",
  133.         "Reactor Heat Vent",
  134.         "Reactor Heat Vent",
  135.         "Reactor Heat Vent",
  136.         "Reactor Heat Vent",
  137.         "Reactor Heat Vent",
  138.         "Reactor Heat Vent",
  139.         "Reactor Heat Vent",
  140.         "Reactor Heat Vent"
  141.     }
  142. else
  143.     -- only 3 Quad-Fuel-Rods in a row, twice
  144.     RequiredReactorInventory = {
  145.         "Reactor Heat Vent",
  146.         "Reactor Heat Vent",
  147.         "Reactor Heat Vent",
  148.         "Reactor Heat Vent",
  149.         "Reactor Heat Vent",
  150.         "Reactor Heat Vent",
  151.         "Reactor Heat Vent",
  152.         "Reactor Heat Vent",
  153.         "Reactor Heat Vent",
  154.    
  155.         "Reactor Heat Vent",
  156.         "Coolant Cell",
  157.         "Coolant Cell",
  158.         "Coolant Cell",
  159.         "Coolant Cell",
  160.         "Coolant Cell",
  161.         "Coolant Cell",
  162.         "Coolant Cell",
  163.         "Reactor Heat Vent",
  164.    
  165.         "Reactor Heat Vent",
  166.         "Coolant Cell",
  167.         "Coolant Cell",
  168.         "Uran",
  169.         "Uran",
  170.         "Uran",
  171.         "Coolant Cell",
  172.         "Coolant Cell",
  173.         "Reactor Heat Vent",
  174.    
  175.         "Reactor Heat Vent",
  176.         "Coolant Cell",
  177.         "Coolant Cell",
  178.         "Uran",
  179.         "Uran",
  180.         "Uran",
  181.         "Coolant Cell",
  182.         "Coolant Cell",
  183.         "Reactor Heat Vent",
  184.    
  185.         "Reactor Heat Vent",
  186.         "Coolant Cell",
  187.         "Coolant Cell",
  188.         "Coolant Cell",
  189.         "Coolant Cell",
  190.         "Coolant Cell",
  191.         "Coolant Cell",
  192.         "Coolant Cell",
  193.         "Reactor Heat Vent",
  194.    
  195.         "Reactor Heat Vent",
  196.         "Reactor Heat Vent",
  197.         "Reactor Heat Vent",
  198.         "Reactor Heat Vent",
  199.         "Reactor Heat Vent",
  200.         "Reactor Heat Vent",
  201.         "Reactor Heat Vent",
  202.         "Reactor Heat Vent",
  203.         "Reactor Heat Vent"
  204.     }
  205. end
  206.  
  207.  
  208. ---[[ functions ]]
  209.  
  210.  
  211. -- source: http://pastebin.com/RCPEHmxs
  212. function clear()
  213.   myMonitor.setBackgroundColor(colors.black)
  214.   myMonitor.clear()
  215.   myMonitor.setCursorPos(1,1)
  216. end
  217.  
  218. --display text on computer's terminal screen
  219. function draw_text_term(x, y, text, text_color, bg_color)
  220.   term.setTextColor(text_color)
  221.   term.setBackgroundColor(bg_color)
  222.   term.setCursorPos(x,y)
  223.   write(text)
  224. end
  225.  
  226. --display text on monitor, "myMonitor" peripheral
  227. function draw_text(x, y, text, text_color, bg_color)
  228.   myMonitor.setBackgroundColor(bg_color)
  229.   myMonitor.setTextColor(text_color)
  230.   myMonitor.setCursorPos(x,y)
  231.   myMonitor.write(text)
  232. end
  233.  
  234. --draw line on computer nonitor
  235. function draw_line(x, y, length, color)
  236.     myMonitor.setBackgroundColor(color)
  237.     myMonitor.setCursorPos(x,y)
  238.     myMonitor.write(string.rep(" ", length))
  239. end
  240.  
  241. --draw line on computer terminal
  242. function draw_line_term(x, y, length, color)
  243.     term.setBackgroundColor(color)
  244.     term.setCursorPos(x,y)
  245.     term.write(string.rep(" ", length))
  246. end
  247.  
  248. --create progress bar
  249. --draws two overlapping lines
  250. --background line of bg_color
  251. --main line of bar_color as a percentage of minVal/maxVal
  252. function progress_bar(x, y, length, minVal, maxVal, bar_color, bg_color)
  253.   draw_line(x, y, length, bg_color) --backgoround bar
  254.   local barSize = math.floor((minVal/maxVal) * length)
  255.   draw_line(x, y, barSize, bar_color) --progress so far
  256. end
  257.  
  258. --same as above but on the computer terminal
  259. function progress_bar_term(x, y, length, minVal, maxVal, bar_color, bg_color)
  260.   draw_line_term(x, y, length, bg_color) --backgoround bar
  261.   local barSize = math.floor((minVal/maxVal) * length)
  262.   draw_line_term(x, y, barSize, bar_color)  --progress so far
  263. end
  264.  
  265. --create button on monitor
  266. function button(x, y, length, text, txt_color, bg_color)
  267.   draw_line(x, y, length, bg_color)
  268.   draw_text((x+2), y, text, txt_color, bg_color)
  269. end
  270.  
  271. -- http://stackoverflow.com/questions/1426954/split-string-in-lua
  272. function split(pString, pPattern)
  273.     local Table = {}  -- NOTE: use {n = 0} in Lua-5.0
  274.     local fpat = "(.-)" .. pPattern
  275.     local last_end = 1
  276.     local s, e, cap = pString:find(fpat, 1)
  277.     while s do
  278.         if s ~= 1 or cap ~= "" then
  279.             table.insert(Table, cap)
  280.         end
  281.         last_end = e+1
  282.         s, e, cap = pString:find(fpat, last_end)
  283.     end
  284.     if last_end <= #pString then
  285.         cap = pString:sub(last_end)
  286.         table.insert(Table, cap)
  287.     end
  288.     return Table
  289. end
  290.  
  291.  
  292. function stringMatch(text, find)
  293.     if string.find(string.lower(text), string.lower(find)) then
  294.         return true
  295.     else
  296.         return false
  297.     end
  298. end
  299.  
  300. function getDeviceSide(deviceType)
  301.     -- loop through all the sides
  302.     for i,side in pairs(rs.getSides()) do
  303.         if (peripheral.isPresent(side)) then
  304.             -- Yup, there is something on this side
  305.             if (peripheral.getType(side) == string.lower(deviceType)) then
  306.                 -- Yes, this is the device type we need, so return the side
  307.                 return side;
  308.             end
  309.         end
  310.     end
  311.     --nothing found, return nil
  312.     return nil;
  313. end
  314.  
  315. function findReactorInventory()
  316.     local targets = mySensor.getTargets()
  317.     for pos,info in pairs(targets) do
  318.         if stringMatch(info.Name, "reactor") then
  319.             myReactor = pos
  320.             foundReactor = true
  321.             break -- stop after first found coz all are one..
  322.         end
  323.     end
  324. end
  325.  
  326. function checkInventory()
  327.     draw_text_term(1, 1, "Checking Reactor Inventory..", colors.white, colors.black)
  328.     details = mySensor.getTargetDetails(myReactor)
  329.     allFine = true
  330.     sleep(0.1)
  331.  
  332.     linecount = 1
  333.     for i=1, #RequiredReactorInventory do
  334.         found = false
  335.         depleted_uran = false
  336.         for slot,info in pairs(details.Slots) do
  337.             if slot == i and (stringMatch(info.Name, RequiredReactorInventory[i]) == true) then
  338.                 if stringMatch(info.Name, "Depleted") == true then
  339.                     depleted_uran = true
  340.                     break
  341.                 else
  342.                     found = true
  343.                     break
  344.                 end
  345.             end
  346.         end
  347.         if depleted_uran == true then
  348.             allFine = false
  349.             linecount = linecount + 1
  350.             local Slot = i
  351.             local Item = "Depleted Uran"
  352.             -- does not meet the requirements. replace it!
  353.             draw_text_term(1, linecount, 'Slot#'..Slot..': "'..Item..'" replacing it!', colors.red, colors.black)
  354.             -- tell Turtle to replace Item. Format -> Slot:Item
  355.             myModem.transmit(ModemChannel, ModemChannel, Slot..':depleted')
  356.         elseif found == false then
  357.             allFine = false
  358.             linecount = linecount + 1
  359.             local Slot = i
  360.             local Item = RequiredReactorInventory[Slot]
  361.             -- does not meet the requirements. replace it!
  362.             draw_text_term(1, linecount, 'Slot#'..Slot..': "'..Item..'" not found!', colors.red, colors.black)
  363.             -- tell Turtle to replace Item. Format -> Slot:Item
  364.             myModem.transmit(ModemChannel, ModemChannel, Slot..':'..Item)
  365.         end
  366.     end
  367.  
  368.     if allFine == true then
  369.         draw_text_term(1, 2, "Nothing to do.", colors.lime, colors.black)
  370.     end
  371. end
  372.  
  373. -- http://computercraft.info/wiki/Usage_of_the_bundled_cable_using_the_Redstone_API
  374. -- http://computercraft.info/wiki/Redstone_(API)
  375. function changeReactorState(state, reason)
  376.     if reason ~= '' then
  377.         msg = "Changing Reactor State to: "..state.." coz: "..reason
  378.     else
  379.         msg = "Changing Reactor State to: "..state
  380.     end
  381.     draw_text_term(1, h-1, msg, colors.red, colors.black)
  382.     if state == "on" then
  383.         if uranDropped == true then
  384.             uranDropped = false
  385.         end
  386.         rs.setBundledOutput(wireSide, wireReactor)
  387.     else
  388.         rs.setBundledOutput(wireSide, 0)
  389.     end
  390.     reactorState = state
  391. end
  392.  
  393. function printInv(from, list)
  394.     print(from, " Inventory:")
  395.     -- list format received: slot#=name|slot#=name|slot#=name
  396.     local t1 = split(list, "|")
  397.     for _,n in pairs(t1) do
  398.         local t2 = split(n, "=")
  399.         print("slot#"..t2[1]..": "..t2[2])
  400.     end
  401. end
  402.  
  403.  
  404. --[[ End functions ]]
  405.  
  406.  
  407. --[[ Internal values ]]
  408.  
  409. local version = 0.7
  410. foundModem = false
  411. foundSensor = false
  412. foundReactor = false
  413. foundMonitor = false
  414. w,h = term.getSize()
  415. reactorState = 'off'
  416. uranDropped = false
  417. thermalTriggered = false
  418.  
  419.  
  420. --[[ Main Script ]]
  421.  
  422.  
  423. term.clear()
  424.  
  425. if fs.exists("ocs/apis/sensor") then
  426.     os.loadAPI("ocs/apis/sensor")
  427. else
  428.     error('Missing OCS mod api')
  429. end
  430.  
  431.  
  432. draw_text_term(1, 3, "Searching for peripherals...", colors.white, colors.black)
  433. sleep(0.5)
  434.  
  435.  
  436. -- detect Modem
  437. draw_text_term(2, 5, "Connecting to modem...", colors.white, colors.black)
  438. sleep(0.5)
  439. side = getDeviceSide("modem")
  440. if side == nil then
  441.     draw_text_term(1, 8, "Error:", colors.red, colors.black)
  442.     draw_text_term(1, 9, "Could not connect to Modem", colors.red, colors.black)
  443.     os.exit()
  444. else
  445.     myModem = peripheral.wrap(side)
  446.     myModem.open(ModemChannel)
  447.     foundModem = true
  448.     if myModem.isWireless() then
  449.         draw_text_term(27, 5, "success", colors.lime, colors.black)
  450.         draw_text_term(35, 5, "(wireless)", colors.white, colors.black)
  451.     else
  452.         draw_text_term(27, 5, "success", colors.lime, colors.black)
  453.         draw_text_term(35, 5, "(wired)", colors.white, colors.black)
  454.     end
  455.     sleep(0.5)
  456. end
  457.  
  458. -- detect Sensor
  459. draw_text_term(2, 6, "Connecting to sensor...", colors.white, colors.black)
  460. sleep(0.5)
  461. side = getDeviceSide("sensor")
  462. if side == nil then
  463.     draw_text_term(1, 7, "Error:", colors.red, colors.black)
  464.     draw_text_term(1, 8, "Could not connect to Sensor", colors.red, colors.black)
  465.     os.exit()
  466. else
  467.     mySensor = peripheral.wrap(side)
  468.     foundSensor = true
  469.     draw_text_term(27, 6, "success", colors.lime, colors.black)
  470.     sleep(0.5)
  471. end
  472.  
  473. -- detect Reactor
  474. draw_text_term(2, 7, "Connecting to Reactor...", colors.white, colors.black)
  475. sleep(0.5)
  476. findReactorInventory()
  477. if foundReactor == false then
  478.     draw_text_term(1, 8, "Error:", colors.red, colors.black)
  479.     draw_text_term(1, 9, "no Reactor found! Check adjacency of sensors and type of card", colors.red, colors.black)
  480.     error()
  481. else
  482.     draw_text_term(27, 7, "success", colors.lime, colors.black)
  483.     sleep(0.5)
  484. end
  485.  
  486. -- detect (optional) Monitor
  487. side = getDeviceSide("monitor")
  488. if side == nil then
  489.     draw_text_term(2, 8, "Could not connect to optional Monitor", colors.white, colors.black)
  490. else
  491.     myMonitor = peripheral.wrap(side)
  492.     foundMonitor = true
  493.     mw,mh = myMonitor.getSize()
  494.     draw_text_term(2, 8, "Detected optional Monitor", colors.white, colors.black)
  495.     -- check if monitor can colors (advanced monitor)
  496.     if not myMonitor.isColor() then
  497.         draw_text_term(2, 9, "Please use an Advanced Monitor for Colors!", colors.white, colors.black)
  498.     end
  499. end
  500.  
  501. draw_text_term(1, 11, "Setup Complete!", colors.lime, colors.black)
  502. sleep(3)
  503. draw_text_term(1, 12, "Starting", colors.white, colors.black)
  504.  
  505.  
  506. -- all seems fine, start main loop
  507. while true do
  508.     term.clear()
  509.     -- only check inventory when we didnt told turtle to remove uran to prevent explosion..
  510.     if uranDropped == false then
  511.         checkInventory()
  512.     end
  513.  
  514.     -- check State of Thermal1
  515.     if (colors.test(rs.getBundledInput(wireSide), wireThermal1)) == true then
  516.         -- turn Reactor off
  517.         changeReactorState('off', 'Thermal1 triggered')
  518.         thermalTriggered = true
  519.     end
  520.     -- check State of Thermal2
  521.     if (colors.test(rs.getBundledInput(wireSide), wireThermal2)) == true then
  522.         -- turn Reactor off
  523.         changeReactorState('off', 'Thermal2 triggered')
  524.         thermalTriggered = true
  525.         -- tell Turtle to drop all Uran Cells to prevent explosion
  526.         if uranDropped == false then
  527.             draw_text_term(1, linecount+1, 'Telling Turtle to drop all Uran Cells', colors.red, colors.black)
  528.             dropList = ""
  529.             for i=1, #RequiredReactorInventory do
  530.                 if stringMatch(RequiredReactorInventory[i], "Uran") == true then
  531.                     if dropList == '' then
  532.                         dropList = i
  533.                     else
  534.                         dropList = dropList..','..i
  535.                     end
  536.                 end
  537.             end
  538.             myModem.transmit(ModemChannel, ModemChannel, 'DropUranSlots:'..dropList)
  539.             -- after drop cmd was send make sure to not send it again
  540.             uranDropped = true
  541.         end
  542.     end
  543.     if (thermalTriggered == true
  544.             and colors.test(rs.getBundledInput(wireSide), wireThermal1) == false
  545.             and colors.test(rs.getBundledInput(wireSide), wireThermal2) == false) then
  546.                 changeReactorState('on', '')
  547.                 thermalTriggered = false
  548.     end
  549.  
  550.     -- Receive messages Event loop
  551.     timerID = os.startTimer(0.5) -- Wait for ... secounds before rise a timer event.
  552.     repeat
  553.         local event, modemSide, senderChannel, replyChannel, message, senderDistance = os.pullEvent()
  554.         if event == "modem_message" then
  555.             -- Determine if message contains ':'
  556.             if string.find(message, "\:") then
  557.                 -- split message e.g. slot:item into a table
  558.                 msgTable = split(message,"\:")
  559.                 if msgTable[1] == "CoolantInv" then
  560.                     printInv("Coolant", msgTable[2])
  561.                 elseif msgTable[1] == "UranInv" then
  562.                     printInv("Uran", msgTable[2])
  563.                 elseif msgTable[1] == "TrashInv" then
  564.                     printInv("Trash", msgTable[2])
  565.                 elseif msgTable[1] == "ReactorInv" then
  566.                     printInv("Reactor", msgTable[2])
  567.  
  568.                 elseif msgTable[1] == "STOP" then
  569.                     -- Turtle registered a Problem so turn Reactor off. Reason = msgTable[2]
  570.                     changeReactorState('off', msgTable[2])
  571.                 end
  572.             -- message doesnt contain ':'
  573.             else
  574.                 if message == "READY" then
  575.                     -- Turtle is ready so turn Reactor on
  576.                     changeReactorState('on', '')
  577.                 else
  578.                     draw_text_term(1, h-1, "ERROR: Received unknown message: "..message, colors.red, colors.black)
  579.                 end
  580.             end
  581.         end
  582.     -- exit repeat loop on timer event
  583.     until (event == "timer" and modemSide == timerID)
  584.  
  585.     sleep(CheckEvery)
  586. end
  587.  
  588.  
  589. --
  590. -- EOF
  591. --
Add Comment
Please, Sign In to add comment