Posted 20 November 2016 - 08:01 PM
Hi guys,
im trying to make a BigReactors CC script, to monitor reactor and Turbines and control the Rpm and things.
Now i encountered a problem with events, i use a timer to update the Interface and now try to use other events like "char" or "mouse_click". If any other event than "timer" happens, the computer crashes and restarts itself and i can't find any mistake in this code. I looked at others, how they do it and its similar to them.
This is the whole script, and this is the important part for my problem i think, the Main loop:
I tried to google this problem, but couldnt find any solution. Perhaps im to dump to "name" this problem, but what ever.
If anyone sees the problem pls tell me.
Thanks in advance!
im trying to make a BigReactors CC script, to monitor reactor and Turbines and control the Rpm and things.
Now i encountered a problem with events, i use a timer to update the Interface and now try to use other events like "char" or "mouse_click". If any other event than "timer" happens, the computer crashes and restarts itself and i can't find any mistake in this code. I looked at others, how they do it and its similar to them.
Spoiler
modem = peripheral.wrap("back")
--
-- settings
-- filename: name of the file where the settings will be saved
-- color_background: color of the background of the monitor
-- color_txt: font color
-- color_border: color of the border of the whole monitor
-- color_panel: color of the panels where the text will be
-- color_header: color of the header line of panels
-- targetSpeed: RPM that the reactor should aim for
-- rodLevel: insertionlevel of fuelrods
-- updateTime: time in Sec, how fast to update the GUI
settings = {
filename = "settings.dat";
color_background = colors.blue;
color_txt = colors.white;
color_border = colors.black;
color_panel = colors.lightBlue;
color_header = colors.gray;
targetSpeed = 1820;
rodLevel = 999;
updateTime = 2;
}
-- table of tables of (list-matrix) monitors, turbines, reactors and chests
local p = {
mon = { };
turb = { };
reactor = { };
chest = { };
}
-- gets all peripherals that the modem receives
local peripherals = modem.getNamesRemote()
-- Temp variable, to save updateTime
--local oldUpdateTime = 0
local statusCalibrateRpm
--
-- go through all
-- monitors, BigReactors-Turbines,
-- BigReactors-Reactors, diamond-chests REVIEW COMMENT
-- and put them in the according list in the next available slot
-- @param peripherals table of peripherals available
--
for index, connection in pairs(peripherals) do
if peripheral.getType(connection) == "monitor" then
p.mon[#p.mon + 1] = peripheral.wrap(connection)
elseif peripheral.getType(connection) == "BigReactors-Turbine" then
p.turb[#p.turb + 1] = peripheral.wrap(connection)
elseif peripheral.getType(connection) == "BigReactors-Reactor" then
p.reactor[#p.reactor + 1] = peripheral.wrap(connection)
elseif peripheral.getType(connection) == "diamond" then
p.chest[#p.chest + 1] = peripheral.wrap(connection)
else
print(peripheral.getType(connection))
print("Was not added!")
end
end
--
-- print out number of
-- monitors, turbines, reactors and chests
--
print("New connections:")
print("Monitors: " .. #p.mon)
print("Turbines: " .. #p.turb)
print("Reactors: " .. #p.reactor)
print("Chests: " .. #p.chest)
--
-- save a table under a given name
-- @param table table of parameters
-- @param name name of the file
--
function save(table, name)
local file = fs.open(name, "w")
file.write(textutils.serialize(table))
file.close()
end
--
-- load a table with a given name
-- @param name name of the file that will be loaded
--
function load(name)
local file = fs.open(name, "r")
local data = file.readAll()
file.close()
return textutils.unserialize(data)
end
------------------------------------------------------------------------------------------------------------
----------------------------Style functions-----------------------------------------------------------------
------------------------------------------------------------------------------------------------------------
-- max x, y coordinate of Mon[1]
monX, monY = p.mon[1].getSize()
--
-- clear monitor and reset cursorPosition
--
function clear()
p.mon[1].setBackgroundColor(settings.color_background)
p.mon[1].clear()
p.mon[1].setCursorPos(1, 1)
end
--
-- get Text onto the screen
-- @param x x-Position
-- @param y y-Position
-- @param text text that will be put onto the screen
-- @param color_txt font color
-- @param color_background background color
--
function drawText(x, y, text, color_txt, color_background)
p.mon[1].setBackgroundColor(color_background)
p.mon[1].setTextColor(color_txt)
p.mon[1].setCursorPos(x, y)
p.mon[1].write(text)
end
--
-- draws a line out of char or spaces if !char (rectangle)
-- @param x x-Position
-- @param y y-Position
-- @param length length in x-axis
-- @param size size of the line (y-axis)
-- @param color_bar background color
-- @param char line made of specific char
--
function drawLine(x, y, length, size, color_bar, char)
for yPos = y, y + size - 1 do
p.mon[1].setBackgroundColor(color_bar)
p.mon[1].setCursorPos(x, yPos)
if char then
p.mon[1].write(string.rep(char, length))
else
p.mon[1].write(string.rep(" ", length))
end
end
end
--
-- draws a progressbar
-- @param x x-Position
-- @param y y-Position
-- @param name
-- @param length length in x-axis
-- @param size size in y-axis
-- @param minVal min Value
-- @param maxVal max Value
-- @param color_bar color of the actual bar
-- @param color_background background color
--
function drawProg(x, y, name, length, size, minVal, maxVal, color_bar, color_background)
drawLine(x, y, length, size, color_background)
local barSize = math.floor((minVal / maxVal) * length)
drawLine(x, y, barSize, size, color_bar)
local text = name .. " " .. math.floor((minVal / maxVal) * 100) .. "%"
local backgroundcolor = color_bar
local x_Position, y_Position
if barSize > monX / 2 + #text / 2 then
-- drawText(monX / 2 - #text / 2 + 2, y + size / 2, text, settings.color_txt, color_bar)
x_Position = monX / 2 - #text / 2 + 2
y_Position = y + size / 2
elseif barSize > #text then
-- drawText((x + barSize) - #text, y + size / 2, text, settings.color_txt, color_bar)
x_Position =(x + barSize) - #text
y_Position = y + size / 2
else
-- drawText(monX / 2 - #text / 2 + 2, y + size / 2, text, settings.color_txt, color_background)
backgroundcolor = color_background
x_Position = monX / 2 - #text / 2 + 2
y_Position = y + size / 2
end
drawText(x_Position, y_Position, text, settings.color_txt, backgroundcolor)
end
--
-- draws text in the center (y-axis)
-- @param y y-Position
-- @param text text that will be centered
-- @param color_txt font color
-- @param color_background background color
--
function centerText(y, text, color_txt, color_background)
drawText(monX / 2 - #text / 2 + 2, y, text, color_txt, color_background)
end
--
-- draws turbine panel with information of all trubines:
-- number, Active, RPM, RF/t, Engaged
-- @param x x-Position
-- @param y y-Position
--
function displayTurbine_bottom(x, y)
local turbActive, coilsEngaged, font_color
for i = 1, #p.turb do
drawText(x, y + i, "#" .. i, settings.color_txt, settings.color_panel)
if (p.turb[i].getActive()) then
turbActive = "True"
font_color = colors.green
else
turbActive = "False"
font_color = colors.red
end
drawText(10 + x, y + i, turbActive, font_color, settings.color_panel)
drawText(18 + x, y + i, tostring(math.floor(p.turb[i].getRotorSpeed())), settings.color_txt, settings.color_panel)
drawText(24 + x, y + i, tostring(math.floor(p.turb[i].getEnergyProducedLastTick())), settings.color_txt, settings.color_panel)
if (p.turb[i].getInductorEngaged()) then
coilsEngaged = "True"
font_color = colors.green
else
coilsEngaged = "False"
font_color = colors.red
end
drawText(31 + x, y + i, coilsEngaged, font_color, settings.color_panel)
end
end
--
-- draw routine for displayTurbine
--
function displayTurbine(x, y)
drawPanel(x - 1, x + 38, y - 1, y + 1 + #p.turb, settings.color_panel)
drawText(x, y, "Turbine", settings.color_header, settings.color_panel)
drawText(x + 10, y, "Active", settings.color_header, settings.color_panel)
drawText(x + 18, y, "RPM", settings.color_header, settings.color_panel)
drawText(x + 24, y, "RF/t ", settings.color_header, settings.color_panel)
drawText(x + 31, y, "Engaged", settings.color_header, settings.color_panel)
if (#p.turb ~= 0) then
displayTurbine_bottom(x,y)
end
end
--
-- draws Reactoroverview-panel which displays overall information:
-- Active, Heat, Fuel, Cost, Steam, React, #Rods REVIEW, Rodlvl
-- @param x x-Position
-- @param y y-Position
--
function displayReactor(x, y)
drawPanel(x - 1, x + 18, y - 1, y + 11, settings.color_panel)
drawText(x, y, "Reactoroverview", settings.color_header, settings.color_panel)
if (#p.reactor ~= 0) then
displayReactor_bottom(x, y)
end
end
--
-- helper function for displayReactor
-- displays everything below "Heat:"-line
--
function displayReactor_bottom(x, y)
drawText(x + 1, y + 3, "Fuel: ", settings.color_txt, settings.color_panel)
local fuelMax = p.reactor[1].getFuelAmountMax()
local fuelAmount = p.reactor[1].getFuelAmount()
local fuelPerc =(fuelAmount / fuelMax) * 100
local reactorActive, reactorheat, font_color
drawText(x + 1, y + 1, "Active: ", settings.color_txt, settings.color_panel)
if (p.reactor[1].getActive()) then
reactorActive = "True"
font_color = colors.green
else
reactorActive = "False"
font_color = colors.red
end
drawText(x + 9, y + 1, reactorActive, font_color, settings.color_panel)
drawText(x + 1, y + 2, "Heat: ", settings.color_txt, settings.color_panel)
if (p.reactor[1].getFuelTemperature() > 2000) then
font_color = colors.red
elseif (p.reactor[1].getFuelTemperature() > 1000) then
font_color = colors.purple
else
font_color = colors.white
end
drawText(x + 9, y + 2, tostring(math.floor(p.reactor[1].getFuelTemperature())) .. " C", font_color, settings.color_panel)
drawText(x + 9, y + 3, round(fuelPerc, 1) .. " %", settings.color_txt, settings.color_panel)
drawText(x + 1, y + 4, "Cost: ", settings.color_txt, settings.color_panel)
temp = round(p.reactor[1].getFuelConsumedLastTick(), 2)
drawText(x + 9, y + 4, temp .. " mb/t", settings.color_txt, settings.color_panel)
drawText(x + 1, y + 5, "Steam: ", settings.color_txt, settings.color_panel)
drawText(x + 9, y + 5, p.reactor[1].getHotFluidProducedLastTick() .. " mb/t", settings.color_txt, settings.color_panel)
drawText(x + 1, y + 6, "React: ", settings.color_txt, settings.color_panel)
drawText(x + 9, y + 6, tostring(math.floor(p.reactor[1].getFuelReactivity())) .. " %", settings.color_txt, settings.color_panel)
drawText(x + 1, y + 7, "Rods#: ", settings.color_txt, settings.color_panel)
drawText(x + 9, y + 7, tostring(math.floor(p.reactor[1].getNumberOfControlRods())), settings.color_txt, settings.color_panel)
drawText(x + 1, y + 8, "Rodlvl: ", settings.color_txt, settings.color_panel)
drawText(x + 9, y + 8, tostring(math.floor(p.reactor[1].getControlRodLevel(0))), settings.color_txt, settings.color_panel)
drawText(x , y + 9, "Estimated Runtime", settings.color_header, settings.color_panel)
drawText(x + 1, y + 10, calculateFuelTime(), settings.color_txt, settings.color_panel)
end
--
-- draw a panel
-- @param xStart Starting point x-Position
-- @param xEnd End point x-Position
-- @param yStart Starting point y-Position
-- @param yEnd End point y-Position
-- @param color color of the panel
--
function drawPanel(xStart, xEnd, yStart, yEnd, color)
p.mon[1].setBackgroundColor(color)
for j = yStart, yEnd do
for i = xStart, xEnd do
p.mon[1].setCursorPos(i, j)
p.mon[1].write(" ")
end
end
end
function showInfo()
term.clear()
term.setCursorPos(1,1)
print("--Peripherals connected--")
print("Monitors: " .. #p.mon)
print("Turbines: " .. #p.turb)
print("Reactors: " .. #p.reactor)
print("Chests: " .. #p.chest)
print("-------------------------")
print("press R for reboot")
end
------------------------------------------------------------------------------------------------------------
----------------------------Functionality-------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------
--
-- rounds the given number
-- @param number given number to be rounded
-- @param decimal rounding accuracy
--
function round(number, decimal)
local multiplier = 10 ^(decimal or 0)
return math.floor(number * multiplier + 0.5) / multiplier
end
--
-- test if a file exists
-- @param name name of the file
--
function file_exists(name)
local file = io.open(name, "r")
if file ~= nil then io.close(file) return true else return false end
end
--
-- calibrates RPM of all turbines by disengaging if speed is to low
-- and engaging if speed is less or equal than targeted speed
--
function calibrateRpm()
if oldUpdateTime == 0 then
oldUpdateTime = settings.updateTime -- save the Actual update time
end
for i = 1, #p.turb do
if (p.turb[i].getRotorSpeed() < settings.targetSpeed - 10) then
if (p.turb[i].getInductorEngaged() == true) then
p.turb[i].setInductorEngaged(false)
statusCalibrateRpm = true
end
elseif(p.turb[i].getRotorSpeed() >= settings.targetSpeed) then
p.turb[i].setInductorEngaged(true)
--settings.updateTime = oldUpdateTime -- reset update time to actual value
--oldUpdateTime = 0 -- reset value
statusCalibrateRpm = false
end
end
end
--
-- calculates the remaining time the reactor could run
-- based on the remaining fuel
--
function calculateFuelTime()
if (#p.reactor ~= 0) then
local cost = p.reactor[1].getFuelConsumedLastTick()
local fuelAmount = 0
local runtimeHrs, runtimeMin, runtimeSec, time
for i = 1, p.chest[1].getInventorySize() do
if (p.chest[1].getStackInSlot(i)) ~= nil then
item_name = p.chest[1].getStackInSlot(i)
if (item_name.display_name == "Yellorium Ingot" or item_name.display_name == "Blutonium Ingot") then
fuelAmount = fuelAmount + item_name.qty
end
end
end
fuelAmount =(fuelAmount * 1000) + p.reactor[1].getFuelAmount()
--print("Fuelamount: " .. fuelAmount .. " mb")
--print("Cost: " .. cost .. " mb/t")
runtimeSec = fuelAmount / cost / 20
runtimeMin = runtimeSec / 60
runtimeHrs = runtimeMin / 60
-- todo: return String mit Stunden, Minuten, Sekunden
time = tostring(math.floor(runtimeHrs)) .. "h" .. tostring(math.floor(runtimeMin % 60)) .. "m" .. tostring(math.floor(runtimeSec % 60)).."s"
return time
else
return "no Reactor"
end
end
--
-- sets the most efficient Rodlevel inside of the reactor
-- could be inaccurate if the fuel level is below 100%
--
function setRodLevelForSteam()
if (#p.turb ~= 0) and (#p.reactor ~= 0) then
if (settings.rodLevel == 999) then
centerText(monY/2, "Setting up the fuelrods, please wait...", settings.color_txt, settings.color_background)
while (p.reactor[1].getFuelTemperature() > 100) do
p.reactor[1].setAllControlRodLevels(100)
p.reactor[1].setActive(false)
print("Temperatur is to high to messure. Please Wait till " .. math.floor(p.reactor[1].getFuelTemperature()) .. "<100 C")
sleep(2)
end
--
print("Setting up the Rodlevel for the amount of Turbines connected...")
sleep(1)
local turbs = #p.turb
local steamNeeded = turbs * 2000
local actualSteam = 0
settings.rodLevel = 100
--
if (p.reactor[1].getFuelAmount() <(p.reactor[1].getFuelAmountMax() -1000)) then
term.setTextColor(colors.red)
print("Fuel Level below 100%, calculation of Rodlevel may be wrong")
term.setTextColor(colors.white)
sleep(0.5)
end
--
p.reactor[1].setActive(true)
while (steamNeeded > actualSteam) do
print("Steam needed: " .. steamNeeded .. " Output: " .. p.reactor[1].getHotFluidProducedLastTick() .. " Rodlevel: " .. p.reactor[1].getControlRodLevel(0))
settings.rodLevel = settings.rodLevel - 1
p.reactor[1].setAllControlRodLevels(settings.rodLevel)
sleep(2)
actualSteam = p.reactor[1].getHotFluidProducedLastTick()
end
--
print("Perfect Rodlevel: " .. settings.rodLevel)
save(settings, settings.filename)
print("Settings saved")
end
print("Setting Rodlevels")
p.reactor[1].setAllControlRodLevels(settings.rodLevel)
else
print("GO CRAFT A FUCKING REACTOR YOU LAZY BASTERD, or a Turbine")
end
end
--
-- updates the GUI
--
function update()
clear()
displayTurbine(3, 3)
displayReactor(60, 3)
calibrateRpm()
showInfo()
end
--
-- initializes the reactor setup
--
function init()
if (file_exists(settings.filename)) then
settings = load(settings.filename)
end
clear()
setRodLevelForSteam()
sleep(0.5)
print("Activating Turbines")
sleep(0.5)
for i = 1, #p.turb do
p.turb[i].setActive(true)
end
print("Setup Ready and running!")
end
init()
------------------------------------------------------------------------------------------------------------
----------------------------Main loop-----------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------
while true do
update()
save(settings, settings.filename)
if(statusCalibrateRpm == false) then
tID = os.startTimer(settings.updateTime) --start updateTimer
else
tID = os.startTimer(0.5) --start calibrate timer
end
local evt, p1, p2, p3 = os.pullEvent()
repeat
if (evt == "char") then
print("event!")
if (p1 == "r") then
print("REBOOT")
os.reboot()
end
end
until (evt == "timer" and p1 == tID)
--sleep(settings.updateTime)
end
This is the whole script, and this is the important part for my problem i think, the Main loop:
Spoiler
while true do
update()
save(settings, settings.filename)
if(statusCalibrateRpm == false) then
tID = os.startTimer(settings.updateTime) --start updateTimer
else
tID = os.startTimer(0.5) --start calibrate timer
end
local evt, p1, p2, p3 = os.pullEvent()
repeat
if (evt == "char") then
print("event!")
if (p1 == "r") then
print("REBOOT")
os.reboot()
end
end
until (evt == "timer" and p1 == tID)
--sleep(settings.updateTime)
end
I tried to google this problem, but couldnt find any solution. Perhaps im to dump to "name" this problem, but what ever.
If anyone sees the problem pls tell me.
Thanks in advance!
Edited on 20 November 2016 - 10:12 PM