Advertisement
meigrafd

OpenComputers: Nuclear Reactor Control (v0.1)

Aug 11th, 2015
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.72 KB | None | 0 0
  1. --[[
  2.  
  3.  Nuclear Reactor Control - by meigrafd @ 12.08.2015
  4.  
  5.  This Script is used to automatically control a Nuclear-Reactor with a Robot.
  6.  The Robot checks the Reactor-Inventory, push Coolant Cells into and replaces depleted Uran.
  7.  It also monitores Reactor heat and drops Uran if it still heats up after shutdown to prevent explosion.
  8.  
  9.  Requires:
  10.    OpenComputers >=1.5
  11.  
  12.  Setup Reactor like:
  13.   https://app.box.com/s/fu5sqhgd19cf3vt6qu3j15r9lx7efjty
  14.  Robot must be placed so the Reactor is in front of it!
  15.  Bundled Cable ends to Robot.
  16.  First Thermal Sensor turns Reactor off. Set this to max 1500.
  17.  Second Thermal Sensor tells Robot to drop Uran Cells to prevent explosion. Set this to max 2500.
  18.   (when Reactor was on it will still heat up after shutdown)
  19.  For a little bit better Cooling and Blastprotection you also should add Water above the complete Reactor.
  20.  
  21.  As Robot you should use a Creative one because it doesnt use Power and you have enough space for Addons.
  22.  
  23.  Craft the Robot minimum with:
  24.  - Inventory Controller Upgrade
  25.  - Inventory Upgrade
  26.  - Redstone Card (tier 2)
  27.  - Chunkloader Upgrade
  28.  - Geolyzer Block
  29.  - Wireless Network Card
  30.  - Hard Disk Drive
  31.  
  32.  Setup Reactor Inventory as (you only need to place all the Reactor Heat Vent. Robot does the rest):
  33.    http://s2.postimage.org/5r41iiq15/Reactor_Setup.jpg
  34.  (biggest Setup with 1120 EU/t)
  35.  
  36.  Install the Scripts as 'autorun.lua'
  37.  
  38.  Scroll down to: CONFIG - START
  39.  
  40.  
  41. --]]
  42.  
  43.  
  44. --[[ Internal values - DONT change! ]]
  45.  
  46. local color = require("colors")  -- http://ocdoc.cil.li/api:colors
  47. local component = require("component")  -- http://ocdoc.cil.li/api:component
  48. local event = require("event")  -- http://ocdoc.cil.li/api:event
  49. local robot = require("robot")  -- http://ocdoc.cil.li/api:robot
  50. local side = require("sides")  -- http://ocdoc.cil.li/api:sides
  51. local serial = require("serialization")
  52. local term = require("term")  -- http://ocdoc.cil.li/api:term
  53. local ic = component.inventory_controller  -- http://ocdoc.cil.li/component:inventory_controller
  54. local geo = component.geolyzer  -- http://ocdoc.cil.li/component:geolyzer
  55. local gpu = component.gpu  -- http://ocdoc.cil.li/component:gpu
  56. local rs = component.redstone
  57. local wlan = component.modem
  58. local wlanPort = 100
  59.  
  60. local version = 0.1
  61. reactorState = 'off'
  62. uranDropped = false
  63. thermalTriggered = false
  64. commandsexecdCount=1
  65. w,h = gpu.getResolution()
  66.  
  67. ---[[ CONFIG - START ]]
  68.  
  69.  
  70. -- Chest Inventory Sides for which Items. Only valid sides: left, right, back, up, down
  71. -- NOTE: Only use one Chest for one Type of Item!
  72. -- Fastest for Coolant will be "up" or "down"
  73. -- Put a Chest below the Robot as Trash, where it drops all it takes out of Reactor.
  74. chestCoolant = "up"
  75. chestUran = "left"
  76. chestTrash = "down"
  77. chestReactor = "front"
  78.  
  79. -- Wire Colors. Available Colors with Bundled Cable: http://computercraft.info/wiki/Colors_(API)#Colors
  80. wireReactor = color.green -- To turn Reactor on/off
  81. wireThermal1 = color.blue -- If Reactor Temperature gets >1500
  82. wireThermal2 = color.red -- If Reactor Temperature gets >2500
  83.  
  84. -- Bundled Cable Side. Only valid sides: back, left, right
  85. wireSide = side.back
  86.  
  87. local CheckEvery = 1 -- sec. Dont set too high! (but also not lower 0.5)
  88.  
  89. -- Wireless Modem channel to optional Monitor-Computer.
  90. local wlanChannel = 111
  91.  
  92. local UseReactorSetup = 1
  93. --[[ Set to 1 or 2.
  94. 1 = Biggest with five Quad-Fuel-Rods in a row, twice.
  95. 2 = three Quad-Fuel-Rods in a row, twice.
  96. --]]
  97.  
  98.  
  99. ---[[ CONFIG - END ]]
  100.  
  101.  
  102.  
  103. --[[
  104.  
  105.   Required Reactor Inventory setup Table.
  106.   first row from left to right, then the second row from left to right, etc.
  107.   one row = 9 columns.
  108.   NOTE: Not the exact Item-Name is used, just a match of e.g. *Coolant* so 10k or 60k Coolant Cells can be used,
  109.         but better use 60k Coolant Cells instead of 10k.
  110. --]]
  111.  
  112. if UseReactorSetup == 1 then
  113.     -- 5 Quad-Fuel-Rods in a row, twice.
  114.     RequiredReactorInventory = {
  115.         "Reactor Heat Vent",
  116.         "Reactor Heat Vent",
  117.         "Reactor Heat Vent",
  118.         "Reactor Heat Vent",
  119.         "Reactor Heat Vent",
  120.         "Reactor Heat Vent",
  121.         "Reactor Heat Vent",
  122.         "Reactor Heat Vent",
  123.         "Reactor Heat Vent",
  124.    
  125.         "Reactor Heat Vent",
  126.         "Coolant Cell",
  127.         "Coolant Cell",
  128.         "Coolant Cell",
  129.         "Coolant Cell",
  130.         "Coolant Cell",
  131.         "Coolant Cell",
  132.         "Coolant Cell",
  133.         "Reactor Heat Vent",
  134.    
  135.         "Reactor Heat Vent",
  136.         "Coolant Cell",
  137.         "Uran",
  138.         "Uran",
  139.         "Uran",
  140.         "Uran",
  141.         "Uran",
  142.         "Coolant Cell",
  143.         "Reactor Heat Vent",
  144.    
  145.         "Reactor Heat Vent",
  146.         "Coolant Cell",
  147.         "Uran",
  148.         "Uran",
  149.         "Uran",
  150.         "Uran",
  151.         "Uran",
  152.         "Coolant Cell",
  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.         "Reactor Heat Vent",
  167.         "Reactor Heat Vent",
  168.         "Reactor Heat Vent",
  169.         "Reactor Heat Vent",
  170.         "Reactor Heat Vent",
  171.         "Reactor Heat Vent",
  172.         "Reactor Heat Vent",
  173.         "Reactor Heat Vent"
  174.     }
  175. else
  176.     -- only 3 Quad-Fuel-Rods in a row, twice
  177.     RequiredReactorInventory = {
  178.         "Reactor Heat Vent",
  179.         "Reactor Heat Vent",
  180.         "Reactor Heat Vent",
  181.         "Reactor Heat Vent",
  182.         "Reactor Heat Vent",
  183.         "Reactor Heat Vent",
  184.         "Reactor Heat Vent",
  185.         "Reactor Heat Vent",
  186.         "Reactor Heat Vent",
  187.    
  188.         "Reactor Heat Vent",
  189.         "Coolant Cell",
  190.         "Coolant Cell",
  191.         "Coolant Cell",
  192.         "Coolant Cell",
  193.         "Coolant Cell",
  194.         "Coolant Cell",
  195.         "Coolant Cell",
  196.         "Reactor Heat Vent",
  197.    
  198.         "Reactor Heat Vent",
  199.         "Coolant Cell",
  200.         "Coolant Cell",
  201.         "Uran",
  202.         "Uran",
  203.         "Uran",
  204.         "Coolant Cell",
  205.         "Coolant Cell",
  206.         "Reactor Heat Vent",
  207.    
  208.         "Reactor Heat Vent",
  209.         "Coolant Cell",
  210.         "Coolant Cell",
  211.         "Uran",
  212.         "Uran",
  213.         "Uran",
  214.         "Coolant Cell",
  215.         "Coolant Cell",
  216.         "Reactor Heat Vent",
  217.    
  218.         "Reactor Heat Vent",
  219.         "Coolant Cell",
  220.         "Coolant Cell",
  221.         "Coolant Cell",
  222.         "Coolant Cell",
  223.         "Coolant Cell",
  224.         "Coolant Cell",
  225.         "Coolant Cell",
  226.         "Reactor Heat Vent",
  227.    
  228.         "Reactor Heat Vent",
  229.         "Reactor Heat Vent",
  230.         "Reactor Heat Vent",
  231.         "Reactor Heat Vent",
  232.         "Reactor Heat Vent",
  233.         "Reactor Heat Vent",
  234.         "Reactor Heat Vent",
  235.         "Reactor Heat Vent",
  236.         "Reactor Heat Vent"
  237.     }
  238. end
  239.  
  240.  
  241. ---[[ functions ]]
  242.  
  243.  
  244. -- RGB hexadecimal Color codes needed for GPU.
  245. local rgb = {
  246.     black = 0x000000,
  247.     white = 0xFFFFFF,
  248.     orange = 0xFFCC33,
  249.     magenta = 0xCC66CC,
  250.     lightBlue = 0x6699FF,
  251.     yellow = 0xFFFF33,
  252.     lime = 0x33CC33,
  253.     pink = 0xFF6699,
  254.     gray = 0x333333,
  255.     lightGray = 0xCCCCCC,
  256.     cyan = 0x336699,
  257.     purple = 0x9933CC,
  258.     blue = 0x333399,
  259.     brown = 0x663300,
  260.     green = 0x336600,
  261.     red = 0xFF3333,
  262. }
  263.  
  264. -- display text on terminal screen
  265. function draw_text_term(x, y, text)
  266. --  term.setCursor(x, y)
  267. --  term.clearLine()
  268.   term.setCursor(x, y)
  269.   term.write(text)
  270. end
  271.  
  272.  
  273. -- This function can be useful for sending/receiving messages via network.
  274. function encode(data)
  275.     return serial.serialize(data)
  276. end
  277. function decode(data)
  278.     status, result = pcall(serial.unserialize, data)
  279.     return status, result
  280. end
  281.  
  282.  
  283. -- http://stackoverflow.com/questions/1426954/split-string-in-lua
  284. function split(pString, pPattern)
  285.     local Table = {}  -- NOTE: use {n = 0} in Lua-5.0
  286.     local fpat = "(.-)" .. pPattern
  287.     local last_end = 1
  288.     local s, e, cap = pString:find(fpat, 1)
  289.     while s do
  290.         if s ~= 1 or cap ~= "" then
  291.             table.insert(Table, cap)
  292.         end
  293.         last_end = e+1
  294.         s, e, cap = pString:find(fpat, last_end)
  295.     end
  296.     if last_end <= #pString then
  297.         cap = pString:sub(last_end)
  298.         table.insert(Table, cap)
  299.     end
  300.     return Table
  301. end
  302.  
  303. function stringMatch(text, find)
  304.     if string.find(string.lower(text), string.lower(find)) then
  305.         return true
  306.     else
  307.         return false
  308.     end
  309. end
  310.  
  311. function lappend(list, delimiter, value)
  312.     if list == '' then
  313.         local list = value
  314.     else
  315.         local list = list..delimiter..value
  316.     end
  317.     return list
  318. end
  319.  
  320.  
  321.  
  322. function turn(side)
  323.     if side == "left" then
  324.         robot.turnLeft()
  325.     elseif side == "right" then
  326.         robot.turnRight()
  327.     elseif side == "front" then
  328.         robot.turnRight()
  329.         robot.turnRight()
  330.     elseif side == "back" then
  331.         robot.turnLeft()
  332.         robot.turnLeft()
  333.     end
  334. end
  335.  
  336. -- drop item in current robots slot to Trash
  337. function drop()
  338.     if chestTrash == "down" then
  339.         success = robot.dropDown()
  340.     elseif chestTrash == "up" then
  341.         success = robot.dropUp()
  342.     elseif chestTrash == "left" then
  343.         turn('left')
  344.         success = robot.drop()
  345.         turn('right')
  346.     elseif chestTrash == "right" then
  347.         turn('right')
  348.         success = robot.drop()
  349.         turn('left')
  350.     end
  351. end
  352.  
  353. function suck(side)
  354.     local success = true
  355.     if side == "up" then
  356.         if not robot.suckUp(1) then
  357.             success = false
  358.         end
  359.     elseif side == "down" then
  360.         if not robot.suckDown(1) then
  361.             success = false
  362.         end
  363.     elseif side == "left" then
  364.         turn('left')
  365.         if not robot.suck(1) then
  366.             success = false
  367.         end
  368.         turn('right')
  369.     elseif side == "right" then
  370.         turn('right')
  371.         if not robot.suck(1) then
  372.             success = false
  373.         end
  374.         turn('left')
  375.     end
  376.     return success
  377. end
  378.  
  379. -- verify reactor in front
  380. function verifyReactor()
  381.     local data = geo.analyze(side.front)
  382.     if stringMatch(data.name, "ReactorChamber") then
  383.         return true
  384.     else
  385.         return false
  386.     end
  387. end
  388.  
  389.  
  390. -- get coolant from chest and put into reactors toSlot
  391. function Coolant(toSlot)
  392.     while (robot.count() > 0) do
  393.         drop()
  394.     end
  395.     -- get coolant from chest
  396.     local success = suck(chestCoolant)
  397.     if success == false then
  398.         print("WARNING: can't pick up Coolant!")
  399.         changeReactorState('off', 'Coolant')
  400.     else
  401.         -- verify reactor in front
  402.         while verifyReactor() == false do
  403.             turn('left')
  404.         end
  405.         -- put coolant into reactors toSlot
  406.         success, reason = ic.dropIntoSlot(side.front, toSlot)
  407.         commandsexecdCount = commandsexecdCount + 1
  408.     end
  409. end
  410.  
  411. -- get uran from chest and put into reactors toSlot
  412. function Uran(toSlot)
  413.     while (robot.count() > 0) do
  414.         drop()
  415.     end
  416.     -- get uran from chest
  417.     local success = suck(chestUran)
  418.     if success == false then
  419.         print("WARNING: can't pick up Uran!")
  420.         changeReactorState('off', 'Uran')
  421.     else
  422.         -- verify reactor in front
  423.         while verifyReactor() == false do
  424.             turn('left')
  425.         end
  426.         -- put uran into reactors toSlot
  427.         success, reason = ic.dropIntoSlot(side.front, toSlot)
  428.         commandsexecdCount = commandsexecdCount + 1
  429.     end
  430. end
  431.  
  432. function Depleted_Uran(fromSlot, replace)
  433.     success = ic.suckFromSlot(side.front, fromSlot)
  434.     while (robot.count() > 0) do
  435.         drop()
  436.     end
  437.     -- only drop Uran from Reactor to Trash or replace it too?
  438.     if replace == true then
  439.         Uran(fromSlot)
  440.     end
  441.     commandsexecdCount = commandsexecdCount + 1
  442. end
  443.  
  444.  
  445. function checkInventory()
  446.     linecount = 1
  447.     draw_text_term(1, 1, "Checking Reactor Inventory..")
  448.     allFine = true
  449.     for i=1, #RequiredReactorInventory do
  450.         local Slot = i
  451.         local Item = RequiredReactorInventory[Slot]
  452.         found = false
  453.         depleted_uran = false
  454.         slotDetails = ic.getStackInSlot(side.front, Slot)
  455.         if slotDetails ~= nil then
  456.             if (stringMatch(slotDetails.label, Item) == true) then
  457.                 --draw_text_term(1, linecount, 'Slot#'..Slot..': '..Item)
  458.                 if (stringMatch(slotDetails.label, "depleted") == true) then
  459.                     depleted_uran = true
  460.                 else
  461.                     found = true
  462.                 end
  463.             end
  464.         end
  465.         if depleted_uran == true then
  466.             allFine = false
  467.             linecount = linecount + 1
  468.             -- does not meet the requirements. replace it!
  469.             draw_text_term(1, linecount, 'Slot#'..Slot..': "Depleted Uran". Replacing it!')
  470.             -- Replace Depleted Uran.
  471.             Depleted_Uran(Slot, true)
  472.         elseif found == false then
  473.             allFine = false
  474.             linecount = linecount + 1
  475.             -- does not meet the requirements. replace it!
  476.             draw_text_term(1, linecount, 'Slot#'..i..': "'..Item..'" not found!')
  477.             -- Replace Item.
  478.             if (stringMatch(Item, "Coolant") == true) then
  479.                 Coolant(Slot)
  480.             elseif (stringMatch(Item, "Uran") == true) then
  481.                 Uran(Slot)
  482.             end
  483.         end
  484.     end
  485.     if allFine == true then
  486.         draw_text_term(1, 2, "Nothing to do.")
  487.         -- change Reactor back on?
  488.         if reactorState == 'off' then
  489.             changeReactorState('on')
  490.         end
  491.     end
  492. end
  493.  
  494. -- http://ocdoc.cil.li/component:redstone
  495. function changeReactorState(state, reason)
  496.     reason = reason or ''
  497.     if reason ~= '' then
  498.         msg = "Changing Reactor State to: "..state.." coz: "..reason
  499.     else
  500.         msg = "Changing Reactor State to: "..state
  501.     end
  502.     draw_text_term(1, h-1, msg)
  503.     if state == "on" then
  504.         if uranDropped == true then
  505.             uranDropped = false
  506.         end
  507.         rs.setBundledOutput(wireSide, wireReactor, 255)
  508.     else
  509.         rs.setBundledOutput(wireSide, wireReactor, 0)
  510.     end
  511.     reactorState = state
  512. end
  513.  
  514.  
  515. --[[ End functions ]]
  516.  
  517.  
  518. --[[ Main Script ]]
  519.  
  520.  
  521. term.clear()
  522.  
  523. local linecount = 3
  524. draw_text_term(1, linecount, "Checking peripherals...")
  525. os.sleep(0.2)
  526.  
  527. -- detect Robot
  528. local linecount = linecount + 2
  529. draw_text_term(2, linecount, "Checking Robot...")
  530. os.sleep(0.2)
  531. if not component.isAvailable("robot") then
  532.     draw_text_term(2, (linecount + 1), "Error:", rgb.red, rgb.black)
  533.     draw_text_term(2, (linecount + 2), "Can only run on robots")
  534.     return
  535. else
  536.     draw_text_term(30, linecount, "success")
  537.     os.sleep(0.2)
  538. end
  539.  
  540. -- detect Inventory Controller
  541. local linecount = linecount + 1
  542. draw_text_term(2, linecount, "Checking Inventory Controller...")
  543. os.sleep(0.2)
  544. if not component.isAvailable("inventory_controller") then
  545.     draw_text_term(2, (linecount + 1), "Error:")
  546.     draw_text_term(2, (linecount + 2), "Could find Inventory Controller")
  547.     return
  548. else
  549.     draw_text_term(30, linecount, "success")
  550.     os.sleep(0.2)
  551. end
  552.  
  553. draw_text_term(1, (linecount + 2), "Setup Complete!")
  554. os.sleep(1)
  555. draw_text_term(1, (linecount + 3), "Starting")
  556. robot.select(1)
  557.  
  558.  
  559. -- all seems fine, start main loop
  560. -- http://ocdoc.cil.li/component:signals
  561.  
  562.  
  563. while true do
  564.     term.clear()
  565.     -- check State of Thermal1
  566.     if (rs.getBundledInput(wireSide, wireThermal1) > 0) then
  567.         -- turn Reactor off
  568.         changeReactorState('off', 'Thermal1 triggered')
  569.         thermalTriggered = true
  570.     end
  571.     -- check State of Thermal2
  572.     if (rs.getBundledInput(wireSide, wireThermal2) > 0) then
  573.         -- turn Reactor off
  574.         changeReactorState('off', 'Thermal2 triggered')
  575.         thermalTriggered = true
  576.         -- tell Robot to drop all Uran Cells to prevent explosion
  577.         if uranDropped == false then
  578.             draw_text_term(1, linecount+1, 'Dropping all Uran Cells to prevent explosion..')
  579.             for i=1, #RequiredReactorInventory do
  580.                 if stringMatch(RequiredReactorInventory[i], "Uran") == true then
  581.                     Depleted_Uran(i, false)
  582.                 end
  583.             end
  584.             -- after drop cmd was exec make sure to not exec it again
  585.             uranDropped = true
  586.         end
  587.     end
  588.     if (thermalTriggered == true
  589.             and rs.getBundledInput(wireSide, wireThermal1) == 0
  590.             and rs.getBundledInput(wireSide, wireThermal2) == 0) then
  591.                 thermalTriggered = false
  592.                 changeReactorState('on')
  593.     end
  594.  
  595.     -- only check inventory when we didnt told robot to remove uran to prevent explosion..
  596.     if uranDropped == false then
  597.         checkInventory()
  598.     end
  599.  
  600.     os.sleep(CheckEvery)
  601. end
  602.  
  603.  
  604. --
  605. -- EOF
  606. --
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement