-- TurbineMonitor
-- Made By: MrKMG <mrkmg.com>
--
-- This program will keep your turbines up to speed
-- and turn the coil on and off as needed.
--
-- To Use:
--
-- Attach as many Turbines and Monitors as you
-- would like via wired modems. Monitors will all
-- display the same information for each turbine:
-- Current Speed
-- Current Power Generation,
-- Coil On/Off
-- Flow On/Off
--
-- Monitors can be of any size
--
--Edit these to fit your turbines
-- Speed to keep rotors between. Recommend putting
-- just above the best your turbine can do.
minSpeed = 1800
maxSpeed = 1820
-- Range of RF to keep in turbine. Recommend to
-- keep low to avoid waste.
minEnergy = 1
maxEnergy = 200000
-- Colors for the monitor
uiColors = {}
uiColors["background"] = colors.gray
uiColors["border"] = colors.black
uiColors["headerBackground"] = colors.blue
uiColors["headerText"] = colors.black
uiColors["currentSpeedBackground"] = colors.black
uiColors["currentSpeedText"] = colors.white
uiColors["currentPowerGenBackground"] = colors.black
uiColors["currentPowerGenText"] = colors.white
uiColors["coilOnBackground"] = colors.green
uiColors["coilOnText"] = colors.white
uiColors["coilOffBackground"] = colors.red
uiColors["coilOffText"] = colors.white
uiColors["flowOnBackground"] = colors.green
uiColors["flowOnText"] = colors.white
uiColors["flowOffBackground"] = colors.red
uiColors["flowOffText"] = colors.white
-- Text for the monitor.
uiText = {}
uiText["name"] = "Turbine "
uiText["rpm"] = " rpm"
uiText["rft"] = " RF/t"
uiText["rfs"] = " RF/s"
uiText["/"] = " / "
uiText["flowOn"] = "Flow: On"
uiText["flowOff"] = "Flow: Off"
uiText["coilsOn"] = "Coils: On"
uiText["coilsOff"] = "Coils: Off"
uiText["title"] = "Turbine Monitor"
-- Edit below at your your own risk
-- !#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#
function drawPixel(x, y, col)
mon.setTextColor(uiColors["coilOnText"])
mon.setCursorPos(x, y)
mon.setBackgroundColor(col)
mon.write(" ")
end
function drawLine(x, y, length, col)
for i = 0, length - 1 do
drawPixel(x + i, y, col)
end
end
-- Center Text
local function printCenter(mon, y, txt)
local w, h = mon.getSize()
local x = math.floor((w / 2) - (#txt / 2))
mon.setBackgroundColor(uiColors["flowOffBackground"])
mon.setTextColor(uiColors["coilOnText"])
mon.setCursorPos(x, y)
mon.write(txt)
end
-- Global Variables
mon = peripheral.wrap("right")
t = {} -- Holds turbines
m = {} -- Holds monitor
w = {} -- Holds windows
-- Other Functions
function round(num)
return math.floor(num + 0.5)
end
-- Program Functions
-- Finds all devices. Puts turbines in `t` table
-- and monitors in `m` table
function getDevices()
for _, name in pairs(peripheral.getNames()) do
if peripheral.getType(name) == "BigReactors-Turbine" then
table.insert(t, peripheral.wrap(name))
end
if peripheral.getType(name) == "monitor" then
table.insert(m, peripheral.wrap(name))
end
end
end
-- Determines if the coil should be turned on
function needCoilOn(i)
if t[i].getEnergyStored() < minEnergy then
return true
else
return false
end
end
-- Determines if the coil should be turned off
function needCoilOff(i)
if t[i].getEnergyStored() > maxEnergy then
return true
else
return false
end
end
-- Turns coil on
function coilOn(i)
t[i].setInductorEngaged(true)
end
-- Tuns coil off
function coilOff(i)
t[i].setInductorEngaged(false)
end
-- Checks if coil in on or off
function isCoilOn(i)
return t[i].getInductorEngaged()
end
-- Determines if flow should turn on
function needFlowOn(i)
if t[i].getRotorSpeed() < minSpeed then
return true
else
return false
end
end
-- Determines if flow should turn off
function needFlowOff(i)
if t[i].getRotorSpeed() > maxSpeed then
return true
else
return false
end
end
-- Turns flow on
-- (Sets flow to MAX)
function flowOn(i)
t[i].setFluidFlowRateMax(t[i].getFluidFlowRateMaxMax())
end
-- Turns flow off
-- (Sets flow to 0)
function flowOff(i)
t[i].setFluidFlowRateMax(0)
end
-- Checks if flow is on or off
-- (Assumes MAX is on, other is off)
function isFlowOn(i)
return t[i].getFluidFlowRateMax() == t[i].getFluidFlowRateMaxMax()
end
-- Get Rotor Speed
function getRotorSpeed(i)
return math.floor(t[i].getRotorSpeed())
end
-- Get Power Generation
function getPowerGeneration(i)
return math.floor(t[i].getEnergyProducedLastTick())
end
-- Get Sum Power Generation
function getSumPowerGeneration()
local sum = 0
for i = 1, #t ,1 do
sum = sum + getPowerGeneration(i)
end
return sum
end
function getSumPowerGeneration20()
local sum = 0
for i = 1, #t ,1 do
sum = getSumPowerGeneration() * 20
end
return sum
end
-- Returns text scale for best fit
-- TODO Figure out if there is a better way than
-- brute forcing
function getScaleForBox(baseWidth, baseHeight, fitWidth, fitHeight, count)
local best = 0.5
for i = best, 5, 0.5 do
local cWidth = baseWidth / i
local cHeight = baseHeight / i
local cPerRow = math.floor(cWidth / fitWidth)
local cPerCol = math.floor(cHeight / fitHeight)
if cPerRow * cPerCol >= count then
best = i
else
break
end
end
return best
end
-- Determins offset to center the windows in the
-- monitor.
function getOffsetForWindow(monitorWidth, monitorHeight, desiredWidth, desiredHeight, count)
local columnsNeeded = math.min(math.floor(monitorWidth / desiredWidth), count)
local rowsNeeded = math.ceil(count / columnsNeeded)
local widthUsed = desiredWidth * columnsNeeded
local heightUsed = desiredHeight * rowsNeeded
local offsetLeft = math.ceil((monitorWidth - widthUsed) / 2)
local offsetRight = math.ceil((monitorHeight - heightUsed) / 2)
return offsetLeft, offsetRight
end
-- Clears each connected monitor
function clearMonitors()
for i = 1, #m do
m[i].setBackgroundColor(uiColors["border"])
m[i].clear()
end
end
-- Setup each monitor
-- (Put a window in each monitor for each turbine)
function setupMonitors()
if #t > 0 then
local monitorWidth
local monitorHeight
local desiredW = 14
local desiredH = 8
local currentX
local currentY
for i = 1, #m do
print("Setting Up " .. i)
table.insert(w, {})
m[i].setTextScale(1)
monitorWidth, monitorHeight = m[i].getSize()
print("Initial Size: " .. monitorWidth .. " " .. monitorHeight)
scale = getScaleForBox(monitorWidth, monitorHeight, desiredW, desiredH, #t)
print("Scale: " .. scale)
m[i].setTextScale(scale)
monitorWidth, monitorHeight = m[i].getSize()
offsetX, offsetY = getOffsetForWindow(monitorWidth, monitorHeight, desiredW, desiredH, #t)
print("Offset: " .. offsetX .. " " .. offsetY)
currentX = offsetX
currentY = offsetY
for ii = 1, #t do
print(currentX .. " " .. currentY .. " " .. desiredW .. " " .. desiredH)
table.insert(w[i], window.create(m[i], currentX, currentY, desiredW, desiredH))
currentX = currentX + desiredW
if (currentX + desiredW > monitorWidth) then
currentX = offsetX
currentY = currentY + desiredH
end
end
end
end
end
-- Write status of turn to window
function writeStatus(turbine, screen)
screen.setBackgroundColor(uiColors["border"])
screen.clear()
-- Write Title
screen.setBackgroundColor(uiColors["headerBackground"])
screen.setTextColor(uiColors["headerText"])
screen.setCursorPos(2, 2)
screen.clearLine()
screen.write(uiText["name"] .. turbine)
--Filler
screen.setBackgroundColor(uiColors["background"])
screen.setCursorPos(1, 3)
screen.clearLine()
-- Write Rotor Speed
screen.setBackgroundColor(uiColors["currentSpeedBackground"])
screen.setTextColor(uiColors["currentSpeedText"])
screen.setCursorPos(2, 4)
screen.clearLine()
screen.write(getRotorSpeed(turbine) .. uiText["rpm"])
-- Write Power Generation
screen.setBackgroundColor(uiColors["currentPowerGenBackground"])
screen.setTextColor(uiColors["currentPowerGenText"])
screen.setCursorPos(2, 5)
screen.clearLine()
screen.write(getPowerGeneration(turbine) .. uiText["rft"])
--Filler
screen.setBackgroundColor(uiColors["background"])
screen.setCursorPos(1, 6)
screen.clearLine()
-- Write Coil Status
if isCoilOn(turbine) then
screen.setBackgroundColor(uiColors["coilOnBackground"])
screen.setTextColor(uiColors["coilOnText"])
screen.setCursorPos(2, 7)
screen.clearLine()
screen.write(uiText["coilsOn"])
else
screen.setBackgroundColor(uiColors["coilOffBackground"])
screen.setTextColor(uiColors["coilOffText"])
screen.setCursorPos(2, 7)
screen.clearLine()
screen.write(uiText["coilsOff"])
end
-- Write Flow Status
if isFlowOn(turbine) then
screen.setBackgroundColor(uiColors["flowOnBackground"])
screen.setTextColor(uiColors["flowOnText"])
screen.setCursorPos(2, 8)
screen.clearLine()
screen.write(uiText["flowOn"])
else
screen.setBackgroundColor(uiColors["flowOffBackground"])
screen.setTextColor(uiColors["flowOffText"])
screen.setCursorPos(2, 8)
screen.clearLine()
screen.write(uiText["flowOff"])
end
-- Draw Right Border
screen.setBackgroundColor(uiColors["border"])
for i = 1, 8 do
screen.setCursorPos(14, i)
screen.write(" ")
end
end
-- Write status of each turbine to appropiate windows
function writeStatuses()
for i = 1, #m do
for ii = 1, #t do
writeStatus(ii, w[i][ii])
end
end
end
-- Setup
function setup()
w = {}
m = {}
t = {}
getDevices()
if (#t == 0) then
error("No Turbines. You did something wrong")
end
if (#m > 0) then
clearMonitors()
setupMonitors()
end
end
-- Main Loop
function main()
for i = 1, #t do
if isCoilOn(i) then
if needCoilOff(i) then
print("turning off " .. i)
coilOff(i)
end
else
if needCoilOn(i) then
print("turning on " .. i)
coilOn(i)
end
end
if isFlowOn(i) then
if needFlowOff(i) then
print("stopping flow " .. i)
flowOff(i)
end
else
if needFlowOn(i) then
print("starting flow " .. i)
flowOn(i)
end
end
end
writeStatuses()
end
-- Program Run
setup()
while true do
main()
drawLine(1, 2, 4, colors.black)
drawLine(5, 2, 69, colors.red)
drawLine(74, 2, 6, colors.black)
drawLine(1, 3, 4, colors.black)
drawLine(5, 3, 69, colors.red)
printCenter(mon, 3, uiText["title"])
drawLine(74, 3, 6, colors.black)
drawLine(1, 4, 4, colors.black)
drawLine(5, 4, 69, colors.red)
drawLine(74, 4, 6, colors.black)
drawLine(1, 48, 4, colors.black)
drawLine(5, 48, 69, colors.red)
drawLine(74, 48, 6, colors.black)
drawLine(1, 49, 4, colors.black)
drawLine(5, 49, 69, colors.red)
printCenter(mon, 49, getSumPowerGeneration() .. uiText["rft"] .. uiText["/"] .. getSumPowerGeneration20() .. uiText["rfs"])
drawLine(74, 49, 6, colors.black)
drawLine(1, 50, 4, colors.black)
drawLine(5, 50, 69, colors.red)
drawLine(74, 50, 6, colors.black)
os.sleep(1)
end
Comments