Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local os = require("os")
- local event = require("event")
- local sides = require("sides")
- local component = require("component")
- local math = require("math")
- local bit32 = require("bit32")
- local string = require("string")
- local gpu = component.gpu
- local width, height = gpu.getResolution()
- function clear()
- gpu.setBackground(0x000000)
- local width, height = gpu.getResolution()
- gpu.fill(1, 1, width, height, " ")
- end
- function singleBorderBox(x, y, w, h)
- gpu.fill(x, y, w, 1, "█")
- gpu.fill(x, y + h - 1, w, 1, "█")
- gpu.fill(x, y + 1, 1, h - 1, "█")
- gpu.fill(x + w - 1, y + 1, 1, h - 1, "█")
- end
- function doubleBorderBox(x, y, w, h)
- singleBorderBox(x, y, w, h)
- singleBorderBox(x + 2, y + 2, w - 4, h - 4)
- end
- function horizontalProgressBar(x, y, w, h, progress, color, showPercent)
- -- 0 >= progress <= 1
- singleBorderBox(x,y,w,h)
- local oldFG = gpu.getForeground()
- gpu.setForeground(color)
- gpu.fill(x + 2, y + 2, math.floor(((w - 4) * progress) + 0.5), h - 4, "█")
- if showPercent then
- -- Figure out placement of the percent label
- local percent = string.format("%.2f", progress * 100) .. "%"
- local len = string.len(percent)
- local labelX = math.floor((((w - 2) / 2) - (len / 2)) + 0.5) + x + 1
- local labelY = math.floor(((h - 2) / 2) + 0.5) + y
- -- Display the label with appropriate coloring.
- for i = 1, len do
- local c, fg, bg, _, _ = gpu.get(labelX + i - 1, labelY)
- if c == "█" then
- gpu.setForeground(bg)
- gpu.setBackground(fg)
- gpu.set(labelX + i - 1, labelY, string.sub(percent, i, i))
- gpu.setBackground(bg)
- gpu.setForeground(fg)
- else
- gpu.set(labelX + i - 1, labelY, string.sub(percent, i, i))
- end
- end
- end
- gpu.setForeground(oldFG)
- end
- function adjustShade(color, factor)
- local red = bit32.band(16711680, color)
- local green = bit32.band(65280, color)
- local blue = bit32.band(255, color)
- red = red * factor
- green = green * factor
- blue = blue * factor
- local result = bit32.bor(blue, 0)
- result = bit32.bor(green, result)
- result = bit32.bor(red, result)
- return result
- end
- function maxAndMinFromArray(data)
- local max = data[1]
- local min = data[1]
- if #data > 1 then
- for i=2, #data do
- if data[i] > max then
- max = data[i]
- end
- if data[i] < min then
- min = data[i]
- end
- end
- end
- return max, min
- end
- function verticalBarChart(x, y, w, h, data, color)
- -- Draw the axies
- gpu.fill(x, y, 1, h, "█")
- gpu.fill(x + 1, y + h - 1, w - 1, 1, "█")
- local max, min = maxAndMinFromArray(data)
- local oldFG = gpu.getForeground()
- gpu.setForeground(color)
- -- Draw the bars
- local numberOfBars = math.min(#data, math.floor((w - 2) / 2))
- for i=1, numberOfBars do
- if i >= 2 then
- gpu.setForeground(adjustShade(color, .75))
- end
- local heightOfBar = math.floor(((((h - 2) * .95) / max) * data[i]) +0.5)
- gpu.fill(x + w - (2 * i), (h - 2) - heightOfBar + y, 2, heightOfBar, "█")
- end
- gpu.setForeground(oldFG)
- end
- function format_int(number)
- -- stolen from here: https://stackoverflow.com/questions/10989788/lua-format-integer
- local i, j, minus, int, fraction = tostring(number):find('([-]?)(%d+)([.]?%d*)')
- -- reverse the int-string and append a comma to all blocks of 3 digits
- int = int:reverse():gsub("(%d%d%d)", "%1,")
- -- reverse the int-string back remove an optional comma and put the
- -- optional minus and fractional part back
- return minus .. int:reverse():gsub("^,", "") .. fraction
- end
- function condenseInt(number)
- if number >= 1000000000 then
- return string.format("%.2f", number / 1000000000) .. "B"
- elseif number >=1000000 then
- return string.format("%.2f", number / 1000000) .. "M"
- elseif number >= 1000 then
- return string.format("%.2f", number / 1000) .. "K"
- else
- return number
- end
- end
- function updateScreen(currentRF, RFStorage, supplyData, demandData)
- clear()
- gpu.setBackground(0x000000)
- gpu.setForeground(0x696969)
- doubleBorderBox(1, 1, width, height)
- gpu.setForeground(0xD2D2D2)
- horizontalProgressBar(6, 6, width - 10, 9, currentRF/RFStorage, 0xCC0000, true)
- verticalBarChart(23, 19, 46, 23, supplyData, 0x00DB00)
- verticalBarChart(91, 19, 46, 23, demandData, 0xCC0000)
- gpu.setForeground(0xFFFFFF)
- local rf = "Redstone Flux: " .. format_int(currentRF) .. " / " .. format_int(RFStorage)
- gpu.set(math.floor(((width - #rf) / 2) + 0.5), 5, rf)
- local supplyTitle = "RF Supply"
- gpu.set(math.floor(((46 - #supplyTitle) / 2) + 0.5 + 23), 18, supplyTitle)
- local demandTitle = "RF Demand"
- gpu.set(math.floor(((46 - #demandTitle) / 2) + 0.5 + 91), 18, demandTitle)
- local currentSupply = supplyData[1]
- local maxSupply, minSupply = maxAndMinFromArray(supplyData)
- gpu.set(27, 43, "Current Supply: " .. condenseInt(currentSupply) .. " RF/t")
- gpu.set(27, 44, "Max Supply (last 10 min): " .. condenseInt(maxSupply) .. " RF/t")
- gpu.set(27, 45, "Min Supply (last 10 min): " .. condenseInt(minSupply) .. " RF/t")
- local currentDemand = demandData[1]
- local maxDemand, minDemand = maxAndMinFromArray(demandData)
- gpu.set(96, 43, "Current Demand: " .. condenseInt(currentDemand) .. " RF/t")
- gpu.set(96, 44, "Max Demand (last 10 min): " .. condenseInt(maxDemand) .. " RF/t")
- gpu.set(96, 45, "Min Demand (last 10 min): " .. condenseInt(minDemand) .. " RF/t")
- end
- function interruptHandler()
- print("Interrupted. Setting gates back to manual")
- for addr, type in component.list("flux_gate", true) do
- local gate = component.proxy(addr)
- gate.setOverrideEnabled(false)
- end
- print("Exiting")
- end
- -- Main
- local pylon = component.draconic_rf_storage
- local redstone = component.redstone
- local gates = {}
- local i = 0
- for addr, type in component.list("flux_gate", true) do
- gates[i] = addr
- i = i + 1
- end
- print("Found " .. i .. " flux gate(s)")
- if i == 2 then
- print("Figuring out which is which")
- local gate1 = component.proxy(gates[0])
- local gate2 = component.proxy(gates[1])
- -- Computer control and set the flow high.
- gate1.setOverrideEnabled(true)
- gate1.setFlowOverride(100000000)
- gate2.setOverrideEnabled(true)
- gate2.setFlowOverride(100000000)
- -- Close one gate and see if we get a negative transfer in the storage.
- -- This only works if there is a draw on the system. We assume there is something...
- gate1.setFlowOverride(0)
- os.sleep(2)
- if pylon.getTransferPerTick() < 0 then
- inGate = gate1
- outGate = gate2
- else
- inGate = gate2
- outGate = gate1
- end
- gate1.setFlowOverride(100000000)
- print("Figured it out")
- print("Running tests...")
- local supplyData = {}
- local demandData = {}
- local runFlag = true
- while(runFlag) do
- local currentRF = pylon.getEnergyStored()
- local storageRF = pylon.getMaxEnergyStored()
- -- Test: Determine total in/out.
- inGate.setFlowOverride(0)
- os.sleep(2)
- local newDemandData = { math.abs(pylon.getTransferPerTick()) }
- for i = 1, math.min(#demandData, 22) do
- newDemandData[i + 1] = demandData[i]
- end
- demandData = newDemandData
- if (pylon.getMaxEnergyStored() - pylon.getEnergyStored()) < 20000000 then
- -- Storage is almost full. Trash enough that we can get a read on incoming RF
- redstone.setOutput(sides.south, 15)
- os.sleep(2)
- redstone.setOutput(sides.south, 0)
- end
- outGate.setFlowOverride(0)
- inGate.setFlowOverride(100000000)
- os.sleep(2)
- local RFIn = pylon.getTransferPerTick()
- outGate.setFlowOverride(100000000)
- -- Maybe nothing is coming in.
- if RFIn < 1 then
- RFIn = 0
- end
- local newSupplyData = { math.abs(RFIn) }
- for i = 1, math.min(#supplyData, 22) do
- newSupplyData[i + 1] = supplyData[i]
- end
- supplyData = newSupplyData
- -- Update the screen
- updateScreen(currentRF, storageRF, supplyData, demandData)
- local name, _ = event.pull(30, "interrupted")
- if name == "interrupted" then
- interruptHandler()
- runFlag = false
- end
- end
- else
- print("Found more or less than 2 flux gates. Exiting...")
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement