Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- Nuclear Reactor Control - by meigrafd @ 12.08.2015
- This Script is used to automatically control a Nuclear-Reactor with a Robot.
- The Robot checks the Reactor-Inventory, push Coolant Cells into and replaces depleted Uran.
- It also monitores Reactor heat and drops Uran if it still heats up after shutdown to prevent explosion.
- Requires:
- OpenComputers >=1.5
- Setup Reactor like:
- https://app.box.com/s/fu5sqhgd19cf3vt6qu3j15r9lx7efjty
- Robot must be placed so the Reactor is in front of it!
- Bundled Cable ends to Robot.
- First Thermal Sensor turns Reactor off. Set this to max 1500.
- Second Thermal Sensor tells Robot to drop Uran Cells to prevent explosion. Set this to max 2500.
- (when Reactor was on it will still heat up after shutdown)
- For a little bit better Cooling and Blastprotection you also should add Water above the complete Reactor.
- As Robot you should use a Creative one because it doesnt use Power and you have enough space for Addons.
- Craft the Robot minimum with:
- - Inventory Controller Upgrade
- - Inventory Upgrade
- - Redstone Card (tier 2)
- - Chunkloader Upgrade
- - Geolyzer Block
- - Wireless Network Card
- - Hard Disk Drive
- Setup Reactor Inventory as (you only need to place all the Reactor Heat Vent. Robot does the rest):
- http://s2.postimage.org/5r41iiq15/Reactor_Setup.jpg
- (biggest Setup with 1120 EU/t)
- Install the Scripts as 'autorun.lua'
- Scroll down to: CONFIG - START
- --]]
- --[[ Internal values - DONT change! ]]
- local color = require("colors") -- http://ocdoc.cil.li/api:colors
- local component = require("component") -- http://ocdoc.cil.li/api:component
- local event = require("event") -- http://ocdoc.cil.li/api:event
- local robot = require("robot") -- http://ocdoc.cil.li/api:robot
- local side = require("sides") -- http://ocdoc.cil.li/api:sides
- local serial = require("serialization")
- local term = require("term") -- http://ocdoc.cil.li/api:term
- local ic = component.inventory_controller -- http://ocdoc.cil.li/component:inventory_controller
- local geo = component.geolyzer -- http://ocdoc.cil.li/component:geolyzer
- local gpu = component.gpu -- http://ocdoc.cil.li/component:gpu
- local rs = component.redstone
- local wlan = component.modem
- local wlanPort = 100
- local version = 0.1
- reactorState = 'off'
- uranDropped = false
- thermalTriggered = false
- commandsexecdCount=1
- w,h = gpu.getResolution()
- ---[[ CONFIG - START ]]
- -- Chest Inventory Sides for which Items. Only valid sides: left, right, back, up, down
- -- NOTE: Only use one Chest for one Type of Item!
- -- Fastest for Coolant will be "up" or "down"
- -- Put a Chest below the Robot as Trash, where it drops all it takes out of Reactor.
- chestCoolant = "up"
- chestUran = "left"
- chestTrash = "down"
- chestReactor = "front"
- -- Wire Colors. Available Colors with Bundled Cable: http://computercraft.info/wiki/Colors_(API)#Colors
- wireReactor = color.green -- To turn Reactor on/off
- wireThermal1 = color.blue -- If Reactor Temperature gets >1500
- wireThermal2 = color.red -- If Reactor Temperature gets >2500
- -- Bundled Cable Side. Only valid sides: back, left, right
- wireSide = side.back
- local CheckEvery = 1 -- sec. Dont set too high! (but also not lower 0.5)
- -- Wireless Modem channel to optional Monitor-Computer.
- local wlanChannel = 111
- local UseReactorSetup = 1
- --[[ Set to 1 or 2.
- 1 = Biggest with five Quad-Fuel-Rods in a row, twice.
- 2 = three Quad-Fuel-Rods in a row, twice.
- --]]
- ---[[ CONFIG - END ]]
- --[[
- Required Reactor Inventory setup Table.
- first row from left to right, then the second row from left to right, etc.
- one row = 9 columns.
- NOTE: Not the exact Item-Name is used, just a match of e.g. *Coolant* so 10k or 60k Coolant Cells can be used,
- but better use 60k Coolant Cells instead of 10k.
- --]]
- if UseReactorSetup == 1 then
- -- 5 Quad-Fuel-Rods in a row, twice.
- RequiredReactorInventory = {
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Coolant Cell",
- "Coolant Cell",
- "Coolant Cell",
- "Coolant Cell",
- "Coolant Cell",
- "Coolant Cell",
- "Coolant Cell",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Coolant Cell",
- "Uran",
- "Uran",
- "Uran",
- "Uran",
- "Uran",
- "Coolant Cell",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Coolant Cell",
- "Uran",
- "Uran",
- "Uran",
- "Uran",
- "Uran",
- "Coolant Cell",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Coolant Cell",
- "Coolant Cell",
- "Coolant Cell",
- "Coolant Cell",
- "Coolant Cell",
- "Coolant Cell",
- "Coolant Cell",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent"
- }
- else
- -- only 3 Quad-Fuel-Rods in a row, twice
- RequiredReactorInventory = {
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Coolant Cell",
- "Coolant Cell",
- "Coolant Cell",
- "Coolant Cell",
- "Coolant Cell",
- "Coolant Cell",
- "Coolant Cell",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Coolant Cell",
- "Coolant Cell",
- "Uran",
- "Uran",
- "Uran",
- "Coolant Cell",
- "Coolant Cell",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Coolant Cell",
- "Coolant Cell",
- "Uran",
- "Uran",
- "Uran",
- "Coolant Cell",
- "Coolant Cell",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Coolant Cell",
- "Coolant Cell",
- "Coolant Cell",
- "Coolant Cell",
- "Coolant Cell",
- "Coolant Cell",
- "Coolant Cell",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent",
- "Reactor Heat Vent"
- }
- end
- ---[[ functions ]]
- -- RGB hexadecimal Color codes needed for GPU.
- local rgb = {
- black = 0x000000,
- white = 0xFFFFFF,
- orange = 0xFFCC33,
- magenta = 0xCC66CC,
- lightBlue = 0x6699FF,
- yellow = 0xFFFF33,
- lime = 0x33CC33,
- pink = 0xFF6699,
- gray = 0x333333,
- lightGray = 0xCCCCCC,
- cyan = 0x336699,
- purple = 0x9933CC,
- blue = 0x333399,
- brown = 0x663300,
- green = 0x336600,
- red = 0xFF3333,
- }
- -- display text on terminal screen
- function draw_text_term(x, y, text)
- -- term.setCursor(x, y)
- -- term.clearLine()
- term.setCursor(x, y)
- term.write(text)
- end
- -- This function can be useful for sending/receiving messages via network.
- function encode(data)
- return serial.serialize(data)
- end
- function decode(data)
- status, result = pcall(serial.unserialize, data)
- return status, result
- end
- -- http://stackoverflow.com/questions/1426954/split-string-in-lua
- function split(pString, pPattern)
- local Table = {} -- NOTE: use {n = 0} in Lua-5.0
- local fpat = "(.-)" .. pPattern
- local last_end = 1
- local s, e, cap = pString:find(fpat, 1)
- while s do
- if s ~= 1 or cap ~= "" then
- table.insert(Table, cap)
- end
- last_end = e+1
- s, e, cap = pString:find(fpat, last_end)
- end
- if last_end <= #pString then
- cap = pString:sub(last_end)
- table.insert(Table, cap)
- end
- return Table
- end
- function stringMatch(text, find)
- if string.find(string.lower(text), string.lower(find)) then
- return true
- else
- return false
- end
- end
- function lappend(list, delimiter, value)
- if list == '' then
- local list = value
- else
- local list = list..delimiter..value
- end
- return list
- end
- function turn(side)
- if side == "left" then
- robot.turnLeft()
- elseif side == "right" then
- robot.turnRight()
- elseif side == "front" then
- robot.turnRight()
- robot.turnRight()
- elseif side == "back" then
- robot.turnLeft()
- robot.turnLeft()
- end
- end
- -- drop item in current robots slot to Trash
- function drop()
- if chestTrash == "down" then
- success = robot.dropDown()
- elseif chestTrash == "up" then
- success = robot.dropUp()
- elseif chestTrash == "left" then
- turn('left')
- success = robot.drop()
- turn('right')
- elseif chestTrash == "right" then
- turn('right')
- success = robot.drop()
- turn('left')
- end
- end
- function suck(side)
- local success = true
- if side == "up" then
- if not robot.suckUp(1) then
- success = false
- end
- elseif side == "down" then
- if not robot.suckDown(1) then
- success = false
- end
- elseif side == "left" then
- turn('left')
- if not robot.suck(1) then
- success = false
- end
- turn('right')
- elseif side == "right" then
- turn('right')
- if not robot.suck(1) then
- success = false
- end
- turn('left')
- end
- return success
- end
- -- verify reactor in front
- function verifyReactor()
- local data = geo.analyze(side.front)
- if stringMatch(data.name, "ReactorChamber") then
- return true
- else
- return false
- end
- end
- -- get coolant from chest and put into reactors toSlot
- function Coolant(toSlot)
- while (robot.count() > 0) do
- drop()
- end
- -- get coolant from chest
- local success = suck(chestCoolant)
- if success == false then
- print("WARNING: can't pick up Coolant!")
- changeReactorState('off', 'Coolant')
- else
- -- verify reactor in front
- while verifyReactor() == false do
- turn('left')
- end
- -- put coolant into reactors toSlot
- success, reason = ic.dropIntoSlot(side.front, toSlot)
- commandsexecdCount = commandsexecdCount + 1
- end
- end
- -- get uran from chest and put into reactors toSlot
- function Uran(toSlot)
- while (robot.count() > 0) do
- drop()
- end
- -- get uran from chest
- local success = suck(chestUran)
- if success == false then
- print("WARNING: can't pick up Uran!")
- changeReactorState('off', 'Uran')
- else
- -- verify reactor in front
- while verifyReactor() == false do
- turn('left')
- end
- -- put uran into reactors toSlot
- success, reason = ic.dropIntoSlot(side.front, toSlot)
- commandsexecdCount = commandsexecdCount + 1
- end
- end
- function Depleted_Uran(fromSlot, replace)
- success = ic.suckFromSlot(side.front, fromSlot)
- while (robot.count() > 0) do
- drop()
- end
- -- only drop Uran from Reactor to Trash or replace it too?
- if replace == true then
- Uran(fromSlot)
- end
- commandsexecdCount = commandsexecdCount + 1
- end
- function checkInventory()
- linecount = 1
- draw_text_term(1, 1, "Checking Reactor Inventory..")
- allFine = true
- for i=1, #RequiredReactorInventory do
- local Slot = i
- local Item = RequiredReactorInventory[Slot]
- found = false
- depleted_uran = false
- slotDetails = ic.getStackInSlot(side.front, Slot)
- if slotDetails ~= nil then
- if (stringMatch(slotDetails.label, Item) == true) then
- --draw_text_term(1, linecount, 'Slot#'..Slot..': '..Item)
- if (stringMatch(slotDetails.label, "depleted") == true) then
- depleted_uran = true
- else
- found = true
- end
- end
- end
- if depleted_uran == true then
- allFine = false
- linecount = linecount + 1
- -- does not meet the requirements. replace it!
- draw_text_term(1, linecount, 'Slot#'..Slot..': "Depleted Uran". Replacing it!')
- -- Replace Depleted Uran.
- Depleted_Uran(Slot, true)
- elseif found == false then
- allFine = false
- linecount = linecount + 1
- -- does not meet the requirements. replace it!
- draw_text_term(1, linecount, 'Slot#'..i..': "'..Item..'" not found!')
- -- Replace Item.
- if (stringMatch(Item, "Coolant") == true) then
- Coolant(Slot)
- elseif (stringMatch(Item, "Uran") == true) then
- Uran(Slot)
- end
- end
- end
- if allFine == true then
- draw_text_term(1, 2, "Nothing to do.")
- -- change Reactor back on?
- if reactorState == 'off' then
- changeReactorState('on')
- end
- end
- end
- -- http://ocdoc.cil.li/component:redstone
- function changeReactorState(state, reason)
- reason = reason or ''
- if reason ~= '' then
- msg = "Changing Reactor State to: "..state.." coz: "..reason
- else
- msg = "Changing Reactor State to: "..state
- end
- draw_text_term(1, h-1, msg)
- if state == "on" then
- if uranDropped == true then
- uranDropped = false
- end
- rs.setBundledOutput(wireSide, wireReactor, 255)
- else
- rs.setBundledOutput(wireSide, wireReactor, 0)
- end
- reactorState = state
- end
- --[[ End functions ]]
- --[[ Main Script ]]
- term.clear()
- local linecount = 3
- draw_text_term(1, linecount, "Checking peripherals...")
- os.sleep(0.2)
- -- detect Robot
- local linecount = linecount + 2
- draw_text_term(2, linecount, "Checking Robot...")
- os.sleep(0.2)
- if not component.isAvailable("robot") then
- draw_text_term(2, (linecount + 1), "Error:", rgb.red, rgb.black)
- draw_text_term(2, (linecount + 2), "Can only run on robots")
- return
- else
- draw_text_term(30, linecount, "success")
- os.sleep(0.2)
- end
- -- detect Inventory Controller
- local linecount = linecount + 1
- draw_text_term(2, linecount, "Checking Inventory Controller...")
- os.sleep(0.2)
- if not component.isAvailable("inventory_controller") then
- draw_text_term(2, (linecount + 1), "Error:")
- draw_text_term(2, (linecount + 2), "Could find Inventory Controller")
- return
- else
- draw_text_term(30, linecount, "success")
- os.sleep(0.2)
- end
- draw_text_term(1, (linecount + 2), "Setup Complete!")
- os.sleep(1)
- draw_text_term(1, (linecount + 3), "Starting")
- robot.select(1)
- -- all seems fine, start main loop
- -- http://ocdoc.cil.li/component:signals
- while true do
- term.clear()
- -- check State of Thermal1
- if (rs.getBundledInput(wireSide, wireThermal1) > 0) then
- -- turn Reactor off
- changeReactorState('off', 'Thermal1 triggered')
- thermalTriggered = true
- end
- -- check State of Thermal2
- if (rs.getBundledInput(wireSide, wireThermal2) > 0) then
- -- turn Reactor off
- changeReactorState('off', 'Thermal2 triggered')
- thermalTriggered = true
- -- tell Robot to drop all Uran Cells to prevent explosion
- if uranDropped == false then
- draw_text_term(1, linecount+1, 'Dropping all Uran Cells to prevent explosion..')
- for i=1, #RequiredReactorInventory do
- if stringMatch(RequiredReactorInventory[i], "Uran") == true then
- Depleted_Uran(i, false)
- end
- end
- -- after drop cmd was exec make sure to not exec it again
- uranDropped = true
- end
- end
- if (thermalTriggered == true
- and rs.getBundledInput(wireSide, wireThermal1) == 0
- and rs.getBundledInput(wireSide, wireThermal2) == 0) then
- thermalTriggered = false
- changeReactorState('on')
- end
- -- only check inventory when we didnt told robot to remove uran to prevent explosion..
- if uranDropped == false then
- checkInventory()
- end
- os.sleep(CheckEvery)
- end
- --
- -- EOF
- --
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement