-- http://cdn.clearbackblast.com/dcs/cc/fusion_reactor_monitor.lua local basalt = require("basalt") -- local mon = peripheral.find('monitor') -- mon.setTextScale(0.5) local bundle_side = 'top' local bundle_laser = colors.red local bundle_primer = colors.yellow local bundle_fuel = colors.purple local bundle_fuel_state = colors.green local reactor_start_level = 30 local reactor_stop_level = 90 local reactor_autostart = false local battery = peripheral.find('inductionPort') local laser = peripheral.find('laserAmplifier') local reactor = peripheral.find('fusionReactorLogicAdapter') local term_width, term_height = term.getSize() local reactor_starting = false local reactor_stopping = false local last_stored = 0 function pulseBundle(color) current = redstone.getBundledOutput(bundle_side) redstone.setBundledOutput(bundle_side, colors.combine(current, color)) sleep(0.1) current = redstone.getBundledOutput(bundle_side) redstone.setBundledOutput(bundle_side, colors.subtract(current, color)) end function setBundle(color, value) fnc = value and colors.combine or colors.subtract current = redstone.getBundledOutput(bundle_side) redstone.setBundledOutput(bundle_side, fnc(current, color)) end function checkBundle(color) return redstone.testBundledInput(bundle_side, color) end function rnd(val, dec) local X = math.pow(10, dec or 1) return math.floor(val * X) / X end function pwr(value) return mekanismEnergyHelper.joulesToFE(value) end function pwrString(value) local val = value local pre = '' local suf = '' if val < 0 then pre = '-' val = -val end val = pwr(val) if val > 1000 then suf = 'k' val = val / 1000 end if val > 1000 then suf = 'M' val = val / 1000 end if val > 1000 then suf = 'B' val = val / 1000 end if val > 1000 then suf = 'T' val = val / 1000 end return string.format('%s%s%s', pre, rnd(val, 1), suf) end function human_time(secs) if secs == math.huge then return '> 1 year' end -- Prepare value local secs = math.floor(secs) -- Days local weeks = math.floor(secs / 604800) secs = secs - (604800 * weeks) -- Days local days = math.floor(secs / 86400) secs = secs - (86400 * days) -- Hours local hours = math.floor(secs / 3600) secs = secs - (3600 * hours) -- Minutes local mins = math.floor(secs / 60) secs = secs - (60 * mins) -- If we have more than 72h worth of storage, switch to week, day, hour format if weeks > 0 then return string.format('%dwk %dd %dh', weeks, days, hours) elseif days >= 3 then return string.format('%dd %dh', days, hours) end return string.format('%dh %dm', hours, mins) end function laserReady() local laser_energy = laser.getEnergy() return pwr(laser_energy) > 1000000000 end function primerReady() return reactor.getHohlraum().count > 0 end function hasFuel() return reactor.getDTFuel().amount > 0 end function isHot() return reactor.getPlasmaTemperature() >= reactor.getIgnitionTemperature(false) end function isRunning() return isHot() and hasFuel() end local main = basalt.getMainFrame() :setBackground(colors.black) local layout = main:addFlexbox() :setBackground(colors.black) :setPosition(2, 2) :setSize("{parent.width - 2}", "{parent.height - 2}") local charge_progress = layout:addProgressBar() :setDirection("up") :setProgress(50) :setSize('{parent.width / 3}', "{parent.height}") :setProgressColor(colors.lime) :setShowPercentage(true) local status_frame = layout:addFrame() :setBackground(colors.black) :setSize('{(parent.width / 3) * 2}', "{parent.height}") local label_output = status_frame:addLabel() :setForeground(colors.white) :setText('Output:') local label_output_width, _ = label_output:getSize() local current_output = status_frame:addLabel() :setForeground(colors.red) :setPosition(label_output_width+2, 1) local label_input = status_frame:addLabel() :setForeground(colors.white) :setPosition(1, 2) :setText('Input:') local label_input_width, _ = label_input:getSize() local current_input = status_frame:addLabel() :setForeground(colors.green) :setPosition(label_input_width+2, 2) local label_fuel = status_frame:addLabel() :setForeground(colors.white) :setPosition(1, 3) :setText('Fuel Flow:') local label_fuel_width, _ = label_fuel:getSize() local current_fuel = status_frame:addLabel() :setPosition(label_fuel_width+2, 3) local label_laser = status_frame:addLabel() :setForeground(colors.white) :setPosition(1, 4) :setText('Laser:') local label_laser_width, _ = label_laser:getSize() local current_laser = status_frame:addLabel() :setPosition(label_laser_width+2, 4) local label_reactor = status_frame:addLabel() :setForeground(colors.white) :setPosition(1, 5) :setText('Reactor:') local label_reactor_width, _ = label_reactor:getSize() local current_reactor = status_frame:addLabel() :setPosition(label_reactor_width+2, 5) local current_state = status_frame:addLabel() :setPosition(1, 7) local label_rate = status_frame:addLabel() :setForeground(colors.white) :setPosition(1, 8) :setText('Rate:') local label_rate_width, _ = label_rate:getSize() local current_rate = status_frame:addLabel() :setPosition(label_rate_width+2, 8) local current_time_until = status_frame:addLabel() :setForeground(colors.white) :setPosition(1, 9) :setText('') local current_action = status_frame:addLabel() :setForeground(colors.white) :setPosition(1, '{parent.height - 3}') :setText('') function reactorStart() if reactor_starting or isRunning() then return end reactor_starting = true current_action:setText('Fueling...') if not checkBundle(bundle_fuel_state) then pulseBundle(bundle_fuel) end while not hasFuel() do sleep(1) end current_action:setText('Priming...') setBundle(bundle_primer, true) while not primerReady() do sleep(1) end setBundle(bundle_primer, false) if not isHot() then current_action:setText('Igniting...') while not laserReady() do current_action:setText('Waiting for laser...') sleep(10) end pulseBundle(bundle_laser) end while not isHot() do sleep(1) end reactor_starting = false current_action:setText('') end function reactorStop() if reactor_stopping then return end reactor_stopping = true current_action:setText('Halting...') if checkBundle(bundle_fuel_state) then pulseBundle(bundle_fuel) end while hasFuel() do sleep(1) end reactor_stopping = false current_action:setText('') end function displayState(change) local text = change == 0 and 'Idle' or change > 0 and 'Charging' or 'Discharging' local text_color = change == 0 and colors.white or change > 0 and colors.green or colors.red current_state:setText(text):setForeground(text_color) current_rate:setText(pwrString(change)..'/s'):setForeground(text_color) if change == 0 then current_time_until:setText('') return end if change < 0 then -- Discharging local amount_to_discharge = pwr(battery.getEnergy()) current_time_until:setText(human_time(amount_to_discharge / pwr(change))) else -- Charging local amount_to_charge = pwr(battery.getMaxEnergy() - battery.getEnergy()) current_time_until:setText(human_time(amount_to_charge / pwr(change))) end end local doStart = status_frame:addButton() :setBackground(colors.green) :setPosition(1, '{parent.height - 1}') :setSize('{parent.width / 2}', 1) :setText('Start') :onClick(function() basalt.schedule(reactorStart) end) local doStop = status_frame:addButton() :setBackground(colors.red) :setPosition('{parent.width / 2}', '{parent.height - 1}') :setSize('{parent.width / 2}', 1) :setText('Stop') :onClick(function() basalt.schedule(reactorStop) end) local toggleAuto = status_frame:addButton() :setBackground(colors.red) :setPosition(1, '{parent.height}') :setSize('{parent.width}', 1) :setText('Toggle Auto') :setBackground(reactor_autostart and colors.green or colors.red) :onClick(function(self) reactor_autostart = not reactor_autostart self:setBackground(reactor_autostart and colors.green or colors.red) end) basalt.schedule(function() while true do local batt_percent = rnd((battery.getEnergy() / battery.getMaxEnergy()) * 100) current_output:setText(pwrString(battery.getLastOutput())) current_input:setText(pwrString(battery.getLastInput())) local fuel_state = checkBundle(colors.green) current_fuel:setText(fuel_state and not hasFuel() and 'Flow Fail' or fuel_state and 'Open' or 'Closed') :setForeground(fuel_state and not hasFuel() and colors.orange or fuel_state and colors.green or colors.red) local laser_energy = laser.getEnergy() local laser_ready = pwr(laser_energy) > 1000000000 current_laser:setText(laser_ready and 'Ready' or pwrString(laser_energy)) :setForeground(laser_ready and colors.green or colors.red) current_reactor:setText(hasFuel() and isHot() and 'Online' or isHot() and 'Cooldown' or 'Offline') :setForeground(hasFuel() and isHot() and colors.green or isHot() and colors.orange or colors.red) charge_progress:setProgress(batt_percent) end end) basalt.schedule(function() while true do local stored = battery.getEnergy() local change = stored - last_stored displayState(change) last_stored = stored sleep(1) end end) basalt.schedule(function() while true do if reactor_autostart then local batt_percent = rnd((battery.getEnergy() / battery.getMaxEnergy()) * 100) if isRunning() and batt_percent > reactor_stop_level then reactorStop() end if not isRunning() and batt_percent < reactor_start_level then reactorStart() end end sleep(5) end end) basalt.run()