SHOW:
|
|
- or go back to the newest paste.
| 1 | - | --[[ |
| 1 | + | |
| 2 | - | Program name: Lolmer's EZ-NUKE reactor control system |
| 2 | + | local progVer = "" |
| 3 | - | Version: v0.3.17 |
| 3 | + | local progName = "Mt. Weather" |
| 4 | - | Programmer: Lolmer |
| 4 | + | |
| 5 | - | With reat assistance from @echaet and @thetaphi |
| 5 | + | |
| 6 | - | Last update: 2015-04-08 |
| 6 | + | |
| 7 | - | Pastebin: http://pastebin.com/fguScPBQ |
| 7 | + | |
| 8 | - | GitHub: https://github.com/sandalle/minecraft_bigreactor_control |
| 8 | + | |
| 9 | -- End multi-reactor cleanup section | |
| 10 | - | Description: |
| 10 | + | |
| 11 | - | This program controls a Big Reactors nuclear reactor in Minecraft with a Computercraft computer, using Computercraft's own wired modem connected to the reactors computer control port. |
| 11 | + | |
| 12 | local monitorList = {} -- Empty monitor array
| |
| 13 | - | This program was designed to work with the mods and versions installed on Never Stop Toasting (NST) Diet http://www.technicpack.net/modpack/details/never-stop-toasting-diet.254882 Endeavour: Never Stop Toasting: Diet official Minecraft server http://forums.somethingawful.com/showthread.php?threadid=3603757 |
| 13 | + | |
| 14 | local reactorList = {} -- Empty reactor array
| |
| 15 | - | To simplify the code and guesswork, I assume the following monitor layout, where each "monitor" listed below is a collection of three wide by two high Advanced Monitors: |
| 15 | + | |
| 16 | - | 1) One Advanced Monitor for overall status display plus |
| 16 | + | |
| 17 | - | one or more Reactors plus |
| 17 | + | |
| 18 | - | none or more Turbines. |
| 18 | + | local turbineMonitorOffset = 0 -- Turbines are assigned monitors after reactors |
| 19 | - | 2) One Advanced Monitor for overall status display plus (furthest monitor from computer by cable length) |
| 19 | + | |
| 20 | - | one Advanced Monitor for each connected Reactor plus (subsequent found monitors) |
| 20 | + | |
| 21 | - | one Advanced Monitor for each connected Turbine (last group of monitors found). |
| 21 | + | |
| 22 | - | If you enable debug mode, add one additional Advanced Monitor for #1 or #2. |
| 22 | + | |
| 23 | write("Initializing program...\n")
| |
| 24 | - | Notes |
| 24 | + | |
| 25 | - | ---------------------------- |
| 25 | + | |
| 26 | - | - Only one reactor and one, two, and three turbines have been tested with the above, but IN THEORY any number is supported. |
| 26 | + | |
| 27 | - | - Devices are found in the reverse order they are plugged in, so monitor_10 will be found before monitor_9. |
| 27 | + | |
| 28 | local logFile = fs.open("reactorcontrol.log", "w")
| |
| 29 | - | When using actively cooled reactors with turbines, keep the following in mind: |
| 29 | + | |
| 30 | - | - 1 mB steam carries up to 10RF of potential energy to extract in a turbine. |
| 30 | + | |
| 31 | - | - Actively cooled reactors produce steam, not power. |
| 31 | + | |
| 32 | - | - You will need about 10 mB of water for each 1 mB of steam that you want to create in a 7^3 reactor. |
| 32 | + | |
| 33 | - | - Two 15x15x14 Turbines can output 260K RF/t by just one 7^3 (four rods) reactor putting out 4k mB steam. |
| 33 | + | |
| 34 | end | |
| 35 | - | Features |
| 35 | + | |
| 36 | - | ---------------------------- |
| 36 | + | |
| 37 | - | - Configurable min/max energy buffer and min/max temperature via ReactorOptions file. |
| 37 | + | |
| 38 | - | - Disengages coils and minimizes flow for turbines over max energy buffer. |
| 38 | + | |
| 39 | - | - ReactorOptions is read on start and then current values are saved every program cycle. |
| 39 | + | |
| 40 | - | - Rod Control value in ReactorOptions is only useful for initial start, after that the program saves the current Rod Control average over all Fuel Rods for next boot. |
| 40 | + | local ccVersion = nil |
| 41 | - | - Auto-adjusts control rods per reactor to maintain temperature. |
| 41 | + | ccVersion = os.version() |
| 42 | - | - Will display reactor data to all attached monitors of correct dimensions. |
| 42 | + | |
| 43 | - | - For multiple monitors, the first monitor (often last plugged in) is the overall status monitor. |
| 43 | + | if ccVersion == "CraftOS 1.6" then |
| 44 | - | - For multiple monitors, the first monitor (often last plugged in) is the overall status monitor. |
| 44 | + | term.native() |
| 45 | - | - A new cruise mode from mechaet, ONLINE will be "blue" when active, to keep your actively cooled reactors running smoothly. |
| 45 | + | |
| 46 | term.restore() | |
| 47 | - | GUI Usage |
| 47 | + | |
| 48 | - | ---------------------------- |
| 48 | + | |
| 49 | - | - Right-clicking between "< * >" of the last row of a monitor alternates the device selection between Reactor, Turbine, and Status output. |
| 49 | + | |
| 50 | - | - Right-clicking "<" and ">" switches between connected devices, starting with the currently selected type, but not limited to them. |
| 50 | + | |
| 51 | - | - The other "<" and ">" buttons, when right-clicked with the mouse, will decrease and increase, respectively, the values assigned to the monitor: |
| 51 | + | |
| 52 | - | - "Rod (%)" will lower/raise the Reactor Control Rods for that Reactor |
| 52 | + | |
| 53 | - | - "mB/t" will lower/raise the Turbine Flow Rate maximum for that Turbine |
| 53 | + | local function printLog(printStr) |
| 54 | - | - "RPM" will lower/raise the target Turbine RPM for that Turbine |
| 54 | + | if debugMode then |
| 55 | - | - Right-clicking between the "<" and ">" (not on them) will disable auto-adjust of that value for attached device. |
| 55 | + | -- If multiple monitors, use the last monitor for debugging if debug is enabled |
| 56 | - | - Right-clicking on the "Enabled" or "Disabled" text for auto-adjust will do the same. |
| 56 | + | if #monitorList > 1 then |
| 57 | - | - Right-clicking on "ONLINE" or "OFFLINE" at the top-right will toggle the state of attached device. |
| 57 | + | term.redirect(monitorList[#monitorList]) -- Redirect to last monitor for debugging |
| 58 | monitorList[#monitorList].setTextScale(0.5) -- Fit more logs on screen | |
| 59 | - | Default values |
| 59 | + | write(printStr.."\n") -- May need to use term.scroll(x) if we output too much, not sure |
| 60 | - | ---------------------------- |
| 60 | + | termRestore() |
| 61 | - | - Rod Control: 90% (Let's start off safe and then power up as we can) |
| 61 | + | end -- if #monitorList > 1 then |
| 62 | - | - Minimum Energy Buffer: 15% (will power on below this value) |
| 62 | + | |
| 63 | - | - Maximum Energy Buffer: 85% (will power off above this value) |
| 63 | + | |
| 64 | - | - Minimum Passive Cooling Temperature: 950^C (will raise control rods below this value) |
| 64 | + | |
| 65 | - | - Maximum Passive Cooling Temperature: 1,400^C (will lower control rods above this value) |
| 65 | + | |
| 66 | - | - Minimum Active Cooling Temperature: 300^C (will raise the control rods below this value) |
| 66 | + | |
| 67 | - | - Maximum Active Cooling Temperature: 420^C (will lower control rods above this value) |
| 67 | + | |
| 68 | - | - Optimal Turbine RPM: 900, 1,800, or 2,700 (divisible by 900) |
| 68 | + | |
| 69 | - | - New user-controlled option for target speed of turbines, defaults to 2726RPM, which is high-optimal. |
| 69 | + | |
| 70 | end -- if debugMode then | |
| 71 | - | Requirements |
| 71 | + | |
| 72 | - | ---------------------------- |
| 72 | + | |
| 73 | - | - Advanced Monitor size is X: 29, Y: 12 with a 3x2 size |
| 73 | + | |
| 74 | - | - Computer or Advanced Computer |
| 74 | + | |
| 75 | - | - Modems (not wireless) connecting each of the Computer to both the Advanced Monitor and Reactor Computer Port. |
| 75 | + | |
| 76 | - | - Big Reactors (http://www.big-reactors.com/) 0.3.2A+ |
| 76 | + | |
| 77 | - | - Computercraft (http://computercraft.info/) 1.58, 1.63+, or 1.73+ |
| 77 | + | |
| 78 | - | - Reset the computer any time number of connected devices change. |
| 78 | + | |
| 79 | config = {}
| |
| 80 | - | Resources |
| 80 | + | |
| 81 | - | ---------------------------- |
| 81 | + | |
| 82 | - | - This script is available from: |
| 82 | + | |
| 83 | - | - http://pastebin.com/fguScPBQ |
| 83 | + | |
| 84 | - | - https://github.com/sandalle/minecraft_bigreactor_control |
| 84 | + | |
| 85 | printLog("Save function called for config for "..path.." EOL")
| |
| 86 | - | - Start-up script is available from: |
| 86 | + | |
| 87 | - | - http://pastebin.com/ZTMzRLez |
| 87 | + | |
| 88 | - | - https://github.com/sandalle/minecraft_bigreactor_control |
| 88 | + | |
| 89 | - | - Other reactor control program which I based my program on: |
| 89 | + | |
| 90 | - | - http://pastebin.com/aMAu4X5J (ScatmanJohn) |
| 90 | + | |
| 91 | - | - http://pastebin.com/HjUVNDau (version ScatmanJohn based his on) |
| 91 | + | |
| 92 | - | - A simpler Big Reactor control program is available from: |
| 92 | + | |
| 93 | - | - http://pastebin.com/7S5xCvgL (IronClaymore only for passively cooled reactors) |
| 93 | + | |
| 94 | - | - Reactor Computer Port API: http://wiki.technicpack.net/Reactor_Computer_Port |
| 94 | + | |
| 95 | - | - Computercraft API: http://computercraft.info/wiki/Category:APIs |
| 95 | + | |
| 96 | - | - Big Reactors Efficiency, Speculation and Questions! http://www.reddit.com/r/feedthebeast/comments/1vzds0/big_reactors_efficiency_speculation_and_questions/ |
| 96 | + | |
| 97 | - | - Big Reactors API code: https://github.com/erogenousbeef/BigReactors/blob/master/erogenousbeef/bigreactors/common/multiblock/tileentity/TileEntityReactorComputerPort.java |
| 97 | + | |
| 98 | - | - Big Reactors API: http://big-reactors.com/cc_api.html |
| 98 | + | |
| 99 | - | - Big Reactor Simulator from http://reddit.com/r/feedthebeast : http://br.sidoh.org/ |
| 99 | + | |
| 100 | - | - A tutorial from FTB's rhn : http://forum.feed-the-beast.com/threads/rhns-continued-adventures-a-build-journal-guide-collection-etc.42664/page-10#post-657819 |
| 100 | + | |
| 101 | value2 = tostring(value2) | |
| 102 | - | ChangeLog |
| 102 | + | |
| 103 | - | ============================ |
| 103 | + | |
| 104 | - | - 0.3.17 |
| 104 | + | |
| 105 | - | - Display how much steam (in mB/t) a Turbine is receiving on that Turbine's monitor. |
| 105 | + | |
| 106 | - | - Set monitor scale before checking size fixing Issue #50. |
| 106 | + | |
| 107 | - | - Having a monitor is now optional, closing Issue #46. |
| 107 | + | |
| 108 | - | - Incorporate steam supply and demand in reactor control thanks to @thetaphi (Nicolas Kratz). |
| 108 | + | |
| 109 | - | - Added turbine coil auto dis-/engage (Issue #51 and #55) thanks to @thetaphi (Nicolas Kratz). |
| 109 | + | |
| 110 | - | - Stop overzealous controlRodAdjustAmount adjustment amount adjustment Issue #56 thanks to @thetaphi (Nicolas Kratz). |
| 110 | + | |
| 111 | - | - Monitors can be reconfigured via GUI fixes Issue #34 thanks to @thetaphi (Nicolas Kratz). |
| 111 | + | |
| 112 | end --config.save = function(path, tab) | |
| 113 | - | Prior ChangeLogs are posted at https://github.com/sandalle/minecraft_bigreactor_control/releases |
| 113 | + | |
| 114 | -- Load a config file | |
| 115 | - | TODO |
| 115 | + | |
| 116 | - | ============================ |
| 116 | + | |
| 117 | - | See https://github.com/sandalle/minecraft_bigreactor_control/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement :) |
| 117 | + | |
| 118 | assert(path ~= nil, "Path can't be nil") | |
| 119 | - | ]]-- |
| 119 | + | |
| 120 | if f ~= nil then | |
| 121 | local tab = {}
| |
| 122 | local line = "" | |
| 123 | - | local progVer = "0.3.17" |
| 123 | + | |
| 124 | - | local progName = "EZ-NUKE" |
| 124 | + | |
| 125 | local currentTag = nil | |
| 126 | local found = false | |
| 127 | local pos = 0 | |
| 128 | while line ~= nil do | |
| 129 | found = false | |
| 130 | line = line:gsub("\\;", "#_!36!_#") -- to keep \;
| |
| 131 | line = line:gsub("\\=", "#_!71!_#") -- to keep \=
| |
| 132 | if line ~= "" then | |
| 133 | -- Delete comments | |
| 134 | newLine = line | |
| 135 | line = "" | |
| 136 | for i=1, string.len(newLine) do | |
| 137 | if string.sub(newLine, i, i) ~= ";" then | |
| 138 | line = line..newLine:sub(i, i) | |
| 139 | - | local monitorAssignments = {} -- Empty array of monitor - "what to display" assignments
|
| 139 | + | |
| 140 | - | local monitorOptionFileName = "monitors.options" -- File for saving the monitor assignments |
| 140 | + | |
| 141 | end | |
| 142 | - | local steamRequested = 0 -- Sum of Turbine Flow Rate in mB |
| 142 | + | |
| 143 | - | local steamDelivered = 0 -- Sum of Active Reactor steam output in mB |
| 143 | + | |
| 144 | -- Find tag | |
| 145 | - | -- Log levels |
| 145 | + | |
| 146 | - | local FATAL = 16 |
| 146 | + | |
| 147 | - | local ERROR = 8 |
| 147 | + | |
| 148 | - | local WARN = 4 |
| 148 | + | |
| 149 | - | local INFO = 2 |
| 149 | + | |
| 150 | - | local DEBUG = 1 |
| 150 | + | |
| 151 | if not found and line ~= "" then | |
| 152 | pos = line:find("=")
| |
| 153 | if pos == nil then | |
| 154 | error("Bad INI file structure")
| |
| 155 | end | |
| 156 | line = line:gsub("#_!36!_#", ";")
| |
| 157 | line = line:gsub("#_!71!_#", "=")
| |
| 158 | tab[currentTag][stringTrim(line:sub(1, pos-1))] = stringTrim(line:sub(pos+1, line:len())) | |
| 159 | found = true | |
| 160 | end | |
| 161 | end | |
| 162 | line = f.readLine() | |
| 163 | end | |
| 164 | ||
| 165 | f:close() | |
| 166 | ||
| 167 | return tab | |
| 168 | else | |
| 169 | return nil | |
| 170 | end | |
| 171 | - | local ccVersion = nil |
| 171 | + | |
| 172 | - | ccVersion = os.version() |
| 172 | + | |
| 173 | ||
| 174 | - | if ccVersion == "CraftOS 1.6" or "CraftOS 1.7" then |
| 174 | + | |
| 175 | - | term.redirect(term.native()) |
| 175 | + | |
| 176 | local function round(num, places) | |
| 177 | local mult = 10^places | |
| 178 | local addon = nil | |
| 179 | if ((num * mult) < 0) then | |
| 180 | addon = -.5 | |
| 181 | else | |
| 182 | addon = .5 | |
| 183 | end | |
| 184 | - | local function printLog(printStr, logLevel) |
| 184 | + | |
| 185 | - | logLevel = logLevel or INFO |
| 185 | + | |
| 186 | - | -- No, I'm not going to write full syslog style levels. But this makes it a little easier filtering and finding stuff in the logfile. |
| 186 | + | |
| 187 | - | -- Since you're already looking at it, you can adjust your preferred log level right here. |
| 187 | + | |
| 188 | - | if debugMode and (logLevel >= WARN) then |
| 188 | + | |
| 189 | - | -- If multiple monitors, print to all of them |
| 189 | + | |
| 190 | - | for monitorName, deviceData in pairs(monitorAssignments) do |
| 190 | + | |
| 191 | - | if deviceData.type == "Debug" then |
| 191 | + | |
| 192 | - | debugMonitor = monitorList[deviceData.index] |
| 192 | + | |
| 193 | - | if(not debugMonitor) or (not debugMonitor.getSize()) then |
| 193 | + | |
| 194 | - | term.write("printLog(): debug monitor "..monitorName.." failed")
|
| 194 | + | |
| 195 | local printString, xPos, yPos, monitorIndex = | |
| 196 | - | term.redirect(debugMonitor) -- Redirect to selected monitor |
| 196 | + | |
| 197 | - | debugMonitor.setTextScale(0.5) -- Fit more logs on screen |
| 197 | + | |
| 198 | - | local color = colors.lightGray |
| 198 | + | |
| 199 | - | if (logLevel == WARN) then |
| 199 | + | |
| 200 | - | color = colors.white |
| 200 | + | |
| 201 | - | elseif (logLevel == ERROR) then |
| 201 | + | |
| 202 | - | color = colors.red |
| 202 | + | |
| 203 | - | elseif (logLevel == FATAL) then |
| 203 | + | |
| 204 | - | color = colors.black |
| 204 | + | |
| 205 | - | debugMonitor.setBackgroundColor(colors.red) |
| 205 | + | |
| 206 | return -- Invalid monitorIndex | |
| 207 | - | debugMonitor.setTextColor(color) |
| 207 | + | |
| 208 | - | write(printStr.."\n") -- May need to use term.scroll(x) if we output too much, not sure |
| 208 | + | |
| 209 | - | debugMonitor.setBackgroundColor(colors.black) |
| 209 | + | |
| 210 | monitor.write(printString) | |
| 211 | end -- function print(printParams) | |
| 212 | ||
| 213 | - | end -- for |
| 213 | + | |
| 214 | -- Replaces the one from FC_API (http://pastebin.com/A9hcbZWe) and adding multi-monitor support | |
| 215 | local function printCentered(printString, yPos, monitorIndex) | |
| 216 | local monitor = nil | |
| 217 | monitor = monitorList[monitorIndex] | |
| 218 | ||
| 219 | if not monitor then | |
| 220 | printLog("monitor["..monitorIndex.."] in printCentered() is NOT a valid monitor.")
| |
| 221 | return -- Invalid monitorIndex | |
| 222 | end | |
| 223 | ||
| 224 | local width, height = monitor.getSize() | |
| 225 | local monitorNameLength = 0 | |
| 226 | ||
| 227 | -- Special changes for title bar | |
| 228 | if yPos == 1 then | |
| 229 | -- Add monitor name to first line | |
| 230 | monitorNameLength = monitorNames[monitorIndex]:len() | |
| 231 | - | -- Format number with [k,M,G,T,P,E] postfix or exponent, depending on how large it is |
| 231 | + | |
| 232 | - | local function formatReadableSIUnit(num) |
| 232 | + | |
| 233 | - | printLog("formatReadableSIUnit("..num..")", DEBUG)
|
| 233 | + | if (#monitorList ~= 1) and (monitorIndex ~= 1) then |
| 234 | - | num = tonumber(num) |
| 234 | + | |
| 235 | - | if(num < 1000) then return tostring(num) end |
| 235 | + | |
| 236 | - | local sizes = {"", "k", "M", "G", "T", "P", "E"}
|
| 236 | + | |
| 237 | - | local exponent = math.floor(math.log10(num)) |
| 237 | + | |
| 238 | - | local group = math.floor(exponent / 3) |
| 238 | + | monitor.setCursorPos(math.floor(width/2) - math.ceil(printString:len()/2) + monitorNameLength/2, yPos) |
| 239 | - | if group > #sizes then |
| 239 | + | monitor.clearLine() |
| 240 | - | return string.format("%e", num)
|
| 240 | + | |
| 241 | ||
| 242 | - | local divisor = math.pow(10, (group - 1) * 3) |
| 242 | + | |
| 243 | - | return string.format("%i%s", num / divisor, sizes[group])
|
| 243 | + | -- print{monitorNames[monitorIndex], 1, 1, monitorIndex} -- Print monitor name
|
| 244 | ||
| 245 | - | end -- local function formatReadableSIUnit(num) |
| 245 | + | |
| 246 | end -- function printCentered(printString, yPos, monitorIndex) | |
| 247 | - | -- pretty printLog() a table |
| 247 | + | |
| 248 | - | local function tprint (tbl, loglevel, indent) |
| 248 | + | |
| 249 | - | if not loglevel then loglevel = DEBUG end |
| 249 | + | |
| 250 | - | if not indent then indent = 0 end |
| 250 | + | |
| 251 | - | for k, v in pairs(tbl) do |
| 251 | + | |
| 252 | - | formatting = string.rep(" ", indent) .. k .. ": "
|
| 252 | + | |
| 253 | - | if type(v) == "table" then |
| 253 | + | |
| 254 | - | printLog(formatting, loglevel) |
| 254 | + | |
| 255 | - | tprint(v, loglevel, indent+1) |
| 255 | + | |
| 256 | - | elseif type(v) == 'boolean' or type(v) == "function" then |
| 256 | + | printLog("monitor["..monitorIndex.."] in printLeft() is NOT a valid monitor.")
|
| 257 | - | printLog(formatting .. tostring(v), loglevel) |
| 257 | + | |
| 258 | end | |
| 259 | - | printLog(formatting .. v, loglevel) |
| 259 | + | |
| 260 | local gap = 1 | |
| 261 | local width = monitor.getSize() | |
| 262 | - | end -- function tprint() |
| 262 | + | |
| 263 | -- Clear left-half of the monitor | |
| 264 | ||
| 265 | for curXPos = 1, (width / 2) do | |
| 266 | monitor.setCursorPos(curXPos, yPos) | |
| 267 | monitor.write(" ")
| |
| 268 | end | |
| 269 | ||
| 270 | -- Write our string left-aligned | |
| 271 | monitor.setCursorPos(1+gap, yPos) | |
| 272 | monitor.write(printString) | |
| 273 | end | |
| 274 | ||
| 275 | ||
| 276 | -- Print text padded from the right side | |
| 277 | -- Clear the right side of the screen | |
| 278 | local function printRight(printString, yPos, monitorIndex) | |
| 279 | local monitor = nil | |
| 280 | monitor = monitorList[monitorIndex] | |
| 281 | ||
| 282 | if not monitor then | |
| 283 | printLog("monitor["..monitorIndex.."] in printRight() is NOT a valid monitor.")
| |
| 284 | return -- Invalid monitorIndex | |
| 285 | end | |
| 286 | ||
| 287 | -- Make sure printString is a string | |
| 288 | printString = tostring(printString) | |
| 289 | ||
| 290 | local gap = 1 | |
| 291 | local width = monitor.getSize() | |
| 292 | ||
| 293 | -- Clear right-half of the monitor | |
| 294 | for curXPos = (width/2), width do | |
| 295 | monitor.setCursorPos(curXPos, yPos) | |
| 296 | monitor.write(" ")
| |
| 297 | end | |
| 298 | ||
| 299 | -- Write our string right-aligned | |
| 300 | monitor.setCursorPos(math.floor(width) - math.ceil(printString:len()+gap), yPos) | |
| 301 | monitor.write(printString) | |
| 302 | end | |
| 303 | ||
| 304 | ||
| 305 | -- Replaces the one from FC_API (http://pastebin.com/A9hcbZWe) and adding multi-monitor support | |
| 306 | - | printLog("Successfully opened "..path.." for reading EOL")
|
| 306 | + | |
| 307 | local monitor = nil | |
| 308 | monitor = monitorList[monitorIndex] | |
| 309 | ||
| 310 | printLog("Called as clearMonitor(printString="..printString..",monitorIndex="..monitorIndex..").")
| |
| 311 | ||
| 312 | if not monitor then | |
| 313 | printLog("monitor["..monitorIndex.."] in clearMonitor(printString="..printString..",monitorIndex="..monitorIndex..") is NOT a valid monitor.")
| |
| 314 | return -- Invalid monitorIndex | |
| 315 | end | |
| 316 | ||
| 317 | local gap = 2 | |
| 318 | monitor.clear() | |
| 319 | local width, height = monitor.getSize() | |
| 320 | monitor.setTextScale(1.0) -- Make sure scale is correct | |
| 321 | ||
| 322 | printCentered(printString, 1, monitorIndex) | |
| 323 | monitor.setTextColor(colors.blue) | |
| 324 | print{monitorNames[monitorIndex], 1, 1, monitorIndex}
| |
| 325 | monitor.setTextColor(colors.white) | |
| 326 | ||
| 327 | for i=1, width do | |
| 328 | monitor.setCursorPos(i, gap) | |
| 329 | monitor.write("-")
| |
| 330 | end | |
| 331 | ||
| 332 | monitor.setCursorPos(1, gap+1) | |
| 333 | end -- function clearMonitor(printString, monitorIndex) | |
| 334 | ||
| 335 | ||
| 336 | -- Return a list of all connected (including via wired modems) devices of "deviceType" | |
| 337 | local function getDevices(deviceType) | |
| 338 | printLog("Called as getDevices(deviceType="..deviceType..")")
| |
| 339 | ||
| 340 | local deviceName = nil | |
| 341 | local deviceIndex = 1 | |
| 342 | local deviceList, deviceNames = {}, {} -- Empty array, which grows as we need
| |
| 343 | local peripheralList = peripheral.getNames() -- Get table of connected peripherals | |
| 344 | ||
| 345 | deviceType = deviceType:lower() -- Make sure we're matching case here | |
| 346 | ||
| 347 | for peripheralIndex = 1, #peripheralList do | |
| 348 | -- Log every device found | |
| 349 | -- printLog("Found "..peripheral.getType(peripheralList[peripheralIndex]).."["..peripheralIndex.."] attached as \""..peripheralList[peripheralIndex].."\".")
| |
| 350 | if (string.lower(peripheral.getType(peripheralList[peripheralIndex])) == deviceType) then | |
| 351 | -- Log devices found which match deviceType and which device index we give them | |
| 352 | printLog("Found "..peripheral.getType(peripheralList[peripheralIndex]).."["..peripheralIndex.."] as index \"["..deviceIndex.."]\" attached as \""..peripheralList[peripheralIndex].."\".")
| |
| 353 | write("Found "..peripheral.getType(peripheralList[peripheralIndex]).."["..peripheralIndex.."] as index \"["..deviceIndex.."]\" attached as \""..peripheralList[peripheralIndex].."\".\n")
| |
| 354 | deviceNames[deviceIndex] = peripheralList[peripheralIndex] | |
| 355 | - | printLog("Could NOT opened "..path.." for reading! EOL")
|
| 355 | + | |
| 356 | deviceIndex = deviceIndex + 1 | |
| 357 | end | |
| 358 | end -- for peripheralIndex = 1, #peripheralList do | |
| 359 | ||
| 360 | return deviceList, deviceNames | |
| 361 | end -- function getDevices(deviceType) | |
| 362 | ||
| 363 | -- Draw a line across the entire x-axis | |
| 364 | local function drawLine(yPos, monitorIndex) | |
| 365 | local monitor = nil | |
| 366 | monitor = monitorList[monitorIndex] | |
| 367 | ||
| 368 | if not monitor then | |
| 369 | printLog("monitor["..monitorIndex.."] in drawLine() is NOT a valid monitor.")
| |
| 370 | return -- Invalid monitorIndex | |
| 371 | end | |
| 372 | ||
| 373 | local width, height = monitor.getSize() | |
| 374 | ||
| 375 | for i=1, width do | |
| 376 | monitor.setCursorPos(i, yPos) | |
| 377 | monitor.write("-")
| |
| 378 | end | |
| 379 | end -- function drawLine(yPos,monitorIndex) | |
| 380 | ||
| 381 | ||
| 382 | -- Display a solid bar of specified color | |
| 383 | local function drawBar(startXPos, startYPos, endXPos, endYPos, color, monitorIndex) | |
| 384 | local monitor = nil | |
| 385 | monitor = monitorList[monitorIndex] | |
| 386 | ||
| 387 | if not monitor then | |
| 388 | printLog("monitor["..monitorIndex.."] in drawBar() is NOT a valid monitor.")
| |
| 389 | return -- Invalid monitorIndex | |
| 390 | end | |
| 391 | ||
| 392 | -- PaintUtils only outputs to term., not monitor. | |
| 393 | -- See http://www.computercraft.info/forums2/index.php?/topic/15540-paintutils-on-a-monitor/ | |
| 394 | term.redirect(monitor) | |
| 395 | paintutils.drawLine(startXPos, startYPos, endXPos, endYPos, color) | |
| 396 | monitor.setBackgroundColor(colors.black) -- PaintUtils doesn't restore the color | |
| 397 | termRestore() | |
| 398 | end -- function drawBar(startXPos, startYPos,endXPos,endYPos,color,monitorIndex) | |
| 399 | ||
| 400 | ||
| 401 | -- Display single pixel color | |
| 402 | local function drawPixel(xPos, yPos, color, monitorIndex) | |
| 403 | local monitor = nil | |
| 404 | monitor = monitorList[monitorIndex] | |
| 405 | ||
| 406 | if not monitor then | |
| 407 | - | printLog("monitor["..monitorIndex.."] in printCentered() is NOT a valid monitor.", ERROR)
|
| 407 | + | |
| 408 | return -- Invalid monitorIndex | |
| 409 | end | |
| 410 | ||
| 411 | -- PaintUtils only outputs to term., not monitor. | |
| 412 | -- See http://www.computercraft.info/forums2/index.php?/topic/15540-paintutils-on-a-monitor/ | |
| 413 | term.redirect(monitor) | |
| 414 | paintutils.drawPixel(xPos, yPos, color) | |
| 415 | monitor.setBackgroundColor(colors.black) -- PaintUtils doesn't restore the color | |
| 416 | termRestore() | |
| 417 | end -- function drawPixel(xPos, yPos, color, monitorIndex) | |
| 418 | - | width = width - monitorNameLength -- add a space |
| 418 | + | |
| 419 | ||
| 420 | -- End helper functions | |
| 421 | - | if monitorAssignments[monitorNames[monitorIndex]].type ~= "Status" then |
| 421 | + | |
| 422 | ||
| 423 | -- Then initialize the monitors | |
| 424 | local function findMonitors() | |
| 425 | -- Empty out old list of monitors | |
| 426 | - | monitor.setCursorPos(monitorNameLength + math.ceil((1 + width - printString:len())/2), yPos) |
| 426 | + | |
| 427 | ||
| 428 | printLog("Finding monitors...")
| |
| 429 | monitorList, monitorNames = getDevices("monitor")
| |
| 430 | ||
| 431 | if #monitorList == 0 then | |
| 432 | printLog("No monitors found!")
| |
| 433 | error("Can't find any monitors!")
| |
| 434 | else | |
| 435 | for monitorIndex = 1, #monitorList do | |
| 436 | local monitor, monitorX, monitorY = nil, nil, nil | |
| 437 | monitor = monitorList[monitorIndex] | |
| 438 | - | printLog("monitor["..monitorIndex.."] in printLeft() is NOT a valid monitor.", ERROR)
|
| 438 | + | |
| 439 | if not monitor then | |
| 440 | printLog("monitorList["..monitorIndex.."] in findMonitors() is NOT a valid monitor.")
| |
| 441 | ||
| 442 | table.remove(monitorList, monitorIndex) -- Remove invalid monitor from list | |
| 443 | if monitorIndex ~= #monitorList then -- If we're not at the end, clean up | |
| 444 | monitorIndex = monitorIndex - 1 -- We just removed an element | |
| 445 | end -- if monitorIndex == #monitorList then | |
| 446 | break -- Invalid monitorIndex | |
| 447 | else -- valid monitor | |
| 448 | monitorX, monitorY = monitor.getSize() | |
| 449 | if (monitorX == nil) or (monitorY == nil) then -- somehow a valid monitor, but non-existent sizes? Maybe fixes Issue #3 | |
| 450 | printLog("monitorList["..monitorIndex.."] in findMonitors() is NOT a valid sized monitor.")
| |
| 451 | ||
| 452 | table.remove(monitorList, monitorIndex) -- Remove invalid monitor from list | |
| 453 | if monitorIndex ~= #monitorList then -- If we're not at the end, clean up | |
| 454 | monitorIndex = monitorIndex - 1 -- We just removed an element | |
| 455 | end -- if monitorIndex == #monitorList then | |
| 456 | break -- Invalid monitorIndex | |
| 457 | ||
| 458 | -- Check for minimum size to allow for monitor.setTextScale(0.5) to work for 3x2 debugging monitor, changes getSize() | |
| 459 | elseif monitorX < 29 or monitorY < 12 then | |
| 460 | term.redirect(monitor) | |
| 461 | monitor.clear() | |
| 462 | printLog("Removing monitor "..monitorIndex.." for being too small.")
| |
| 463 | monitor.setCursorPos(1,2) | |
| 464 | write("Monitor is the wrong size!\n")
| |
| 465 | - | printLog("monitor["..monitorIndex.."] in printRight() is NOT a valid monitor.", ERROR)
|
| 465 | + | |
| 466 | termRestore() | |
| 467 | ||
| 468 | table.remove(monitorList, monitorIndex) -- Remove invalid monitor from list | |
| 469 | if monitorIndex == #monitorList then -- If we're at the end already, break from loop | |
| 470 | break | |
| 471 | else | |
| 472 | monitorIndex = monitorIndex - 1 -- We just removed an element | |
| 473 | end -- if monitorIndex == #monitorList then | |
| 474 | ||
| 475 | end -- if monitorX < 29 or monitorY < 12 then | |
| 476 | end -- if not monitor then | |
| 477 | ||
| 478 | printLog("Monitor["..monitorIndex.."] named \""..monitorNames[monitorIndex].."\" is a valid monitor of size x:"..monitorX.." by y:"..monitorY..".")
| |
| 479 | end -- for monitorIndex = 1, #monitorList do | |
| 480 | end -- if #monitorList == 0 then | |
| 481 | ||
| 482 | printLog("Found "..#monitorList.." monitor(s) in findMonitors().")
| |
| 483 | end -- local function findMonitors() | |
| 484 | ||
| 485 | ||
| 486 | -- Initialize all Big Reactors - Reactors | |
| 487 | local function findReactors() | |
| 488 | -- Empty out old list of reactors | |
| 489 | newReactorList = {}
| |
| 490 | printLog("Finding reactors...")
| |
| 491 | newReactorList, reactorNames = getDevices("BigReactors-Reactor")
| |
| 492 | ||
| 493 | if #newReactorList == 0 then | |
| 494 | printLog("No reactors found!")
| |
| 495 | - | printLog("monitor["..monitorIndex.."] in clearMonitor(printString="..printString..",monitorIndex="..monitorIndex..") is NOT a valid monitor.", ERROR)
|
| 495 | + | |
| 496 | else -- Placeholder | |
| 497 | for reactorIndex = 1, #newReactorList do | |
| 498 | local reactor = nil | |
| 499 | reactor = newReactorList[reactorIndex] | |
| 500 | ||
| 501 | if not reactor then | |
| 502 | printLog("reactorList["..reactorIndex.."] in findReactors() is NOT a valid Big Reactor.")
| |
| 503 | ||
| 504 | table.remove(newReactorList, reactorIndex) -- Remove invalid reactor from list | |
| 505 | if reactorIndex ~= #newReactorList then -- If we're not at the end, clean up | |
| 506 | reactorIndex = reactorIndex - 1 -- We just removed an element | |
| 507 | end -- reactorIndex ~= #newReactorList then | |
| 508 | return -- Invalid reactorIndex | |
| 509 | else | |
| 510 | printLog("reactor["..reactorIndex.."] in findReactors() is a valid Big Reactor.")
| |
| 511 | --initialize the default table | |
| 512 | _G[reactorNames[reactorIndex]] = {}
| |
| 513 | _G[reactorNames[reactorIndex]]["ReactorOptions"] = {}
| |
| 514 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["baseControlRodLevel"] = 80 | |
| 515 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["lastTempPoll"] = 0 | |
| 516 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["autoStart"] = true | |
| 517 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["activeCooled"] = true | |
| 518 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorMaxTemp"] = 1400 --set for passive-cooled, the active-cooled subroutine will correct it | |
| 519 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorMinTemp"] = 1000 | |
| 520 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["rodOverride"] = false | |
| 521 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorName"] = reactorNames[reactorIndex] | |
| 522 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorCruising"] = false | |
| 523 | if reactor.getConnected() then | |
| 524 | printLog("reactor["..reactorIndex.."] in findReactors() is connected.")
| |
| 525 | else | |
| 526 | printLog("reactor["..reactorIndex.."] in findReactors() is NOT connected.")
| |
| 527 | return -- Disconnected reactor | |
| 528 | end | |
| 529 | end | |
| 530 | ||
| 531 | --failsafe | |
| 532 | local tempTable = _G[reactorNames[reactorIndex]] | |
| 533 | ||
| 534 | --check to make sure we get a valid config | |
| 535 | if (config.load(reactorNames[reactorIndex]..".options")) ~= nil then | |
| 536 | tempTable = config.load(reactorNames[reactorIndex]..".options") | |
| 537 | else | |
| 538 | --if we don't have a valid config from disk, make a valid config | |
| 539 | config.save(reactorNames[reactorIndex]..".options", _G[reactorNames[reactorIndex]]) | |
| 540 | end | |
| 541 | ||
| 542 | --load values from tempTable, checking for nil values along the way | |
| 543 | if tempTable["ReactorOptions"]["baseControlRodLevel"] ~= nil then | |
| 544 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["baseControlRodLevel"] = tempTable["ReactorOptions"]["baseControlRodLevel"] | |
| 545 | end | |
| 546 | ||
| 547 | if tempTable["ReactorOptions"]["lastTempPoll"] ~= nil then | |
| 548 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["lastTempPoll"] = tempTable["ReactorOptions"]["lastTempPoll"] | |
| 549 | end | |
| 550 | ||
| 551 | if tempTable["ReactorOptions"]["autoStart"] ~= nil then | |
| 552 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["autoStart"] = tempTable["ReactorOptions"]["autoStart"] | |
| 553 | end | |
| 554 | ||
| 555 | if tempTable["ReactorOptions"]["activeCooled"] ~= nil then | |
| 556 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["activeCooled"] = tempTable["ReactorOptions"]["activeCooled"] | |
| 557 | end | |
| 558 | ||
| 559 | if tempTable["ReactorOptions"]["reactorMaxTemp"] ~= nil then | |
| 560 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorMaxTemp"] = tempTable["ReactorOptions"]["reactorMaxTemp"] | |
| 561 | end | |
| 562 | ||
| 563 | if tempTable["ReactorOptions"]["reactorMinTemp"] ~= nil then | |
| 564 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorMinTemp"] = tempTable["ReactorOptions"]["reactorMinTemp"] | |
| 565 | end | |
| 566 | ||
| 567 | if tempTable["ReactorOptions"]["rodOverride"] ~= nil then | |
| 568 | printLog("Got value from config file for Rod Override, the value is: "..tostring(tempTable["ReactorOptions"]["rodOverride"]).." EOL")
| |
| 569 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["rodOverride"] = tempTable["ReactorOptions"]["rodOverride"] | |
| 570 | end | |
| 571 | ||
| 572 | if tempTable["ReactorOptions"]["reactorName"] ~= nil then | |
| 573 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorName"] = tempTable["ReactorOptions"]["reactorName"] | |
| 574 | end | |
| 575 | ||
| 576 | if tempTable["ReactorOptions"]["reactorCruising"] ~= nil then | |
| 577 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorCruising"] = tempTable["ReactorOptions"]["reactorCruising"] | |
| 578 | end | |
| 579 | ||
| 580 | --stricter typing, let's set these puppies up with the right type of value. | |
| 581 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["baseControlRodLevel"] = tonumber(_G[reactorNames[reactorIndex]]["ReactorOptions"]["baseControlRodLevel"]) | |
| 582 | ||
| 583 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["lastTempPoll"] = tonumber(_G[reactorNames[reactorIndex]]["ReactorOptions"]["lastTempPoll"]) | |
| 584 | ||
| 585 | if (tostring(_G[reactorNames[reactorIndex]]["ReactorOptions"]["autoStart"]) == "true") then | |
| 586 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["autoStart"] = true | |
| 587 | else | |
| 588 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["autoStart"] = false | |
| 589 | end | |
| 590 | ||
| 591 | if (tostring(_G[reactorNames[reactorIndex]]["ReactorOptions"]["activeCooled"]) == "true") then | |
| 592 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["activeCooled"] = true | |
| 593 | else | |
| 594 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["activeCooled"] = false | |
| 595 | end | |
| 596 | ||
| 597 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorMaxTemp"] = tonumber(_G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorMaxTemp"]) | |
| 598 | ||
| 599 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorMinTemp"] = tonumber(_G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorMinTemp"]) | |
| 600 | - | local function saveMonitorAssignments() |
| 600 | + | |
| 601 | - | local assignments = {}
|
| 601 | + | |
| 602 | - | for monitor, data in pairs(monitorAssignments) do |
| 602 | + | |
| 603 | - | local name = nil |
| 603 | + | |
| 604 | - | if (data.type == "Reactor") then |
| 604 | + | |
| 605 | - | name = data.reactorName |
| 605 | + | |
| 606 | - | elseif (data.type == "Turbine") then |
| 606 | + | |
| 607 | - | name = data.turbineName |
| 607 | + | |
| 608 | ||
| 609 | - | name = data.type |
| 609 | + | |
| 610 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorCruising"] = true | |
| 611 | - | assignments[monitor] = name |
| 611 | + | |
| 612 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorCruising"] = false | |
| 613 | - | config.save(monitorOptionFileName, {Monitors = assignments})
|
| 613 | + | |
| 614 | ||
| 615 | --save one more time, in case we didn't have a complete config file before | |
| 616 | - | UI = {
|
| 616 | + | |
| 617 | - | monitorIndex = 1, |
| 617 | + | |
| 618 | - | reactorIndex = 1, |
| 618 | + | |
| 619 | - | turbineIndex = 1 |
| 619 | + | |
| 620 | - | } |
| 620 | + | |
| 621 | reactorList = newReactorList | |
| 622 | - | UI.handlePossibleClick = function(self) |
| 622 | + | |
| 623 | - | local monitorData = monitorAssignments[sideClick] |
| 623 | + | -- Start turbine monitor offset after reactors get monitors |
| 624 | - | if monitorData == nil then |
| 624 | + | -- This assumes that there is a monitor for each turbine and reactor, plus the overall monitor display |
| 625 | - | printLog("UI.handlePossibleClick(): "..sideClick.." is unassigned, can't handle click", WARN)
|
| 625 | + | turbineMonitorOffset = #reactorList + 1 -- #turbineList will start at "1" if turbines found and move us just beyond #reactorList and status monitor range |
| 626 | - | return |
| 626 | + | |
| 627 | printLog("Found "..#reactorList.." reactor(s) in findReactors().")
| |
| 628 | printLog("Set turbineMonitorOffset to "..turbineMonitorOffset.." in findReactors().")
| |
| 629 | - | self.monitorIndex = monitorData.index |
| 629 | + | |
| 630 | - | local width, height = monitorList[self.monitorIndex].getSize() |
| 630 | + | |
| 631 | - | -- All the last line are belong to us |
| 631 | + | |
| 632 | - | if (yClick == height) then |
| 632 | + | |
| 633 | - | if (monitorData.type == "Reactor") then |
| 633 | + | |
| 634 | - | if (xClick == 1) then |
| 634 | + | |
| 635 | - | self:selectPrevReactor() |
| 635 | + | |
| 636 | - | elseif (xClick == width) then |
| 636 | + | |
| 637 | - | self:selectNextReactor() |
| 637 | + | |
| 638 | - | elseif (3 <= xClick and xClick <= width - 2) then |
| 638 | + | |
| 639 | - | self:selectTurbine() |
| 639 | + | |
| 640 | if #newTurbineList == 0 then | |
| 641 | - | elseif (monitorData.type == "Turbine") then |
| 641 | + | |
| 642 | - | if (xClick == 1) then |
| 642 | + | |
| 643 | - | self:selectPrevTurbine() |
| 643 | + | |
| 644 | - | elseif (xClick == width) then |
| 644 | + | |
| 645 | - | self:selectNextTurbine() |
| 645 | + | |
| 646 | - | elseif (3 <= xClick and xClick <= width - 2) then |
| 646 | + | |
| 647 | - | self:selectStatus() |
| 647 | + | |
| 648 | printLog("turbineList["..turbineIndex.."] in findTurbines() is NOT a valid Big Reactors Turbine.")
| |
| 649 | - | elseif (monitorData.type == "Status") then |
| 649 | + | |
| 650 | - | if (xClick == 1) then |
| 650 | + | |
| 651 | - | self.turbineIndex = #turbineList |
| 651 | + | |
| 652 | - | self:selectTurbine() |
| 652 | + | |
| 653 | - | elseif (xClick == width) then |
| 653 | + | |
| 654 | - | self.reactorIndex = 1 |
| 654 | + | |
| 655 | - | self:selectReactor() |
| 655 | + | |
| 656 | - | elseif (3 <= xClick and xClick <= width - 2) then |
| 656 | + | |
| 657 | - | self:selectReactor() |
| 657 | + | |
| 658 | _G[turbineNames[turbineIndex]] = {}
| |
| 659 | _G[turbineNames[turbineIndex]]["TurbineOptions"] = {}
| |
| 660 | - | self:selectStatus() |
| 660 | + | |
| 661 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["BaseSpeed"] = 2726 | |
| 662 | - | -- Yes, that means we're skipping Debug. I figure everyone who wants that is |
| 662 | + | |
| 663 | - | -- bound to use the console key commands anyway, and that way we don't have |
| 663 | + | |
| 664 | - | -- it interfere with regular use. |
| 664 | + | |
| 665 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["turbineName"] = turbineNames[turbineIndex] | |
| 666 | printLog("turbineList["..turbineIndex.."] in findTurbines() is a valid Big Reactors Turbine.")
| |
| 667 | if turbine.getConnected() then | |
| 668 | - | if (monitorData.type == "Turbine") then |
| 668 | + | |
| 669 | - | self:handleTurbineMonitorClick(monitorData.turbineIndex, monitorData.index) |
| 669 | + | |
| 670 | - | elseif (monitorData.type == "Reactor") then |
| 670 | + | |
| 671 | - | self:handleReactorMonitorClick(monitorData.reactorIndex, monitorData.index) |
| 671 | + | |
| 672 | end | |
| 673 | end | |
| 674 | - | end -- UI.handlePossibleClick() |
| 674 | + | |
| 675 | --failsafe | |
| 676 | - | UI.logChange = function(self, messageText) |
| 676 | + | |
| 677 | - | printLog("UI: "..messageText)
|
| 677 | + | |
| 678 | --check to make sure we get a valid config | |
| 679 | - | write(messageText.."\n") |
| 679 | + | |
| 680 | tempTable = config.load(turbineNames[turbineIndex]..".options") | |
| 681 | else | |
| 682 | - | UI.selectNextMonitor = function(self) |
| 682 | + | |
| 683 | - | self.monitorIndex = self.monitorIndex + 1 |
| 683 | + | |
| 684 | - | if self.monitorIndex > #monitorList then |
| 684 | + | |
| 685 | - | self.monitorIndex = 1 |
| 685 | + | |
| 686 | --load values from tempTable, checking for nil values along the way | |
| 687 | - | local messageText = "Selected monitor "..monitorNames[self.monitorIndex] |
| 687 | + | |
| 688 | - | self:logChange(messageText) |
| 688 | + | |
| 689 | - | end -- UI.selectNextMonitor() |
| 689 | + | |
| 690 | ||
| 691 | if tempTable["TurbineOptions"]["BaseSpeed"] ~= nil then | |
| 692 | - | UI.selectReactor = function(self) |
| 692 | + | |
| 693 | - | monitorAssignments[monitorNames[self.monitorIndex]] = {type="Reactor", index=self.monitorIndex, reactorName=reactorNames[self.reactorIndex], reactorIndex=self.reactorIndex}
|
| 693 | + | |
| 694 | - | saveMonitorAssignments() |
| 694 | + | |
| 695 | - | local messageText = "Selected reactor "..reactorNames[self.reactorIndex].." for display on "..monitorNames[self.monitorIndex] |
| 695 | + | |
| 696 | - | self:logChange(messageText) |
| 696 | + | |
| 697 | - | end -- UI.selectReactor() |
| 697 | + | |
| 698 | ||
| 699 | - | UI.selectPrevReactor = function(self) |
| 699 | + | |
| 700 | - | if self.reactorIndex <= 1 then |
| 700 | + | |
| 701 | - | self.reactorIndex = #reactorList |
| 701 | + | |
| 702 | - | self:selectStatus() |
| 702 | + | |
| 703 | if tempTable["TurbineOptions"]["flowOverride"] ~= nil then | |
| 704 | - | self.reactorIndex = self.reactorIndex - 1 |
| 704 | + | |
| 705 | - | self:selectReactor() |
| 705 | + | |
| 706 | ||
| 707 | - | end -- UI.selectPrevReactor() |
| 707 | + | |
| 708 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["turbineName"] = tempTable["TurbineOptions"]["turbineName"] | |
| 709 | - | UI.selectNextReactor = function(self) |
| 709 | + | |
| 710 | - | if self.reactorIndex >= #reactorList then |
| 710 | + | |
| 711 | - | self.reactorIndex = 1 |
| 711 | + | |
| 712 | - | self.turbineIndex = 1 |
| 712 | + | |
| 713 | - | self:selectTurbine() |
| 713 | + | |
| 714 | ||
| 715 | - | self.reactorIndex = self.reactorIndex + 1 |
| 715 | + | |
| 716 | - | self:selectReactor() |
| 716 | + | |
| 717 | end -- if #newTurbineList == 0 then | |
| 718 | - | end -- UI.selectNextReactor() |
| 718 | + | |
| 719 | printLog("Found "..#turbineList.." turbine(s) in findTurbines().")
| |
| 720 | end -- function findTurbines() | |
| 721 | - | UI.selectTurbine = function(self) |
| 721 | + | |
| 722 | - | monitorAssignments[monitorNames[self.monitorIndex]] = {type="Turbine", index=self.monitorIndex, turbineName=turbineNames[self.turbineIndex], turbineIndex=self.turbineIndex}
|
| 722 | + | |
| 723 | - | saveMonitorAssignments() |
| 723 | + | |
| 724 | - | local messageText = "Selected turbine "..turbineNames[self.turbineIndex].." for display on "..monitorNames[self.monitorIndex] |
| 724 | + | |
| 725 | - | self:logChange(messageText) |
| 725 | + | |
| 726 | - | end -- UI.selectTurbine() |
| 726 | + | |
| 727 | if not reactor then | |
| 728 | - | UI.selectPrevTurbine = function(self) |
| 728 | + | |
| 729 | - | if self.turbineIndex <= 1 then |
| 729 | + | |
| 730 | - | self.turbineIndex = #turbineList |
| 730 | + | |
| 731 | - | self.reactorIndex = #reactorList |
| 731 | + | |
| 732 | - | self:selectReactor() |
| 732 | + | |
| 733 | ||
| 734 | - | self.turbineIndex = self.turbineIndex - 1 |
| 734 | + | |
| 735 | - | self:selectTurbine() |
| 735 | + | |
| 736 | end -- function getReactorStoredEnergyBufferPercent(reactor) | |
| 737 | - | end -- UI.selectPrevTurbine() |
| 737 | + | |
| 738 | ||
| 739 | - | UI.selectNextTurbine = function(self) |
| 739 | + | |
| 740 | - | if self.turbineIndex >= #turbineList then |
| 740 | + | |
| 741 | - | self.turbineIndex = 1 |
| 741 | + | |
| 742 | - | self:selectStatus() |
| 742 | + | |
| 743 | if not turbine then | |
| 744 | - | self.turbineIndex = self.turbineIndex + 1 |
| 744 | + | |
| 745 | - | self:selectTurbine() |
| 745 | + | |
| 746 | else | |
| 747 | - | end -- UI.selectNextTurbine() |
| 747 | + | |
| 748 | end | |
| 749 | ||
| 750 | - | UI.selectStatus = function(self) |
| 750 | + | |
| 751 | - | monitorAssignments[monitorNames[self.monitorIndex]] = {type="Status", index=self.monitorIndex}
|
| 751 | + | |
| 752 | - | saveMonitorAssignments() |
| 752 | + | |
| 753 | - | local messageText = "Selected status summary for display on "..monitorNames[self.monitorIndex] |
| 753 | + | |
| 754 | - | self:logChange(messageText) |
| 754 | + | |
| 755 | - | end -- UI.selectStatus() |
| 755 | + | |
| 756 | ||
| 757 | - | UI.selectDebug = function(self) |
| 757 | + | |
| 758 | - | monitorAssignments[monitorNames[self.monitorIndex]] = {type="Debug", index=self.monitorIndex}
|
| 758 | + | |
| 759 | - | saveMonitorAssignments() |
| 759 | + | |
| 760 | - | monitorList[self.monitorIndex].clear() |
| 760 | + | |
| 761 | - | local messageText = "Selected debug output for display on "..monitorNames[self.monitorIndex] |
| 761 | + | |
| 762 | - | self:logChange(messageText) |
| 762 | + | |
| 763 | - | end -- UI.selectDebug() |
| 763 | + | |
| 764 | reactor = reactorList[reactorIndex] | |
| 765 | - | -- Allow controlling Reactor Control Rod Level from GUI |
| 765 | + | |
| 766 | - | UI.handleReactorMonitorClick = function(self, reactorIndex, monitorIndex) |
| 766 | + | |
| 767 | return -- Invalid reactorIndex | |
| 768 | else | |
| 769 | printLog("reactor["..reactorIndex.."] in reactorCruise(cruiseMaxTemp="..cruiseMaxTemp..",cruiseMinTemp="..cruiseMinTemp..",lastPolledTemp="..lastPolledTemp..",reactorIndex="..reactorIndex..") is a valid Big Reactor.")
| |
| 770 | if reactor.getConnected() then | |
| 771 | printLog("reactor["..reactorIndex.."] in reactorCruise(cruiseMaxTemp="..cruiseMaxTemp..",cruiseMinTemp="..cruiseMinTemp..",lastPolledTemp="..lastPolledTemp..",reactorIndex="..reactorIndex..") is connected.")
| |
| 772 | else | |
| 773 | printLog("reactor["..reactorIndex.."] in reactorCruise(cruiseMaxTemp="..cruiseMaxTemp..",cruiseMinTemp="..cruiseMinTemp..",lastPolledTemp="..lastPolledTemp..",reactorIndex="..reactorIndex..") is NOT connected.")
| |
| 774 | return -- Disconnected reactor | |
| 775 | end -- if reactor.getConnected() then | |
| 776 | end -- if not reactor then | |
| 777 | ||
| 778 | local rodPercentage = math.ceil(reactor.getControlRodLevel(0)) | |
| 779 | local reactorTemp = math.ceil(reactor.getFuelTemperature()) | |
| 780 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["baseControlRodLevel"] = rodPercentage | |
| 781 | ||
| 782 | if ((reactorTemp < cruiseMaxTemp) and (reactorTemp > cruiseMinTemp)) then | |
| 783 | - | printLog("reactor["..reactorIndex.."] in handleReactorMonitorClick(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is NOT a valid Big Reactor.")
|
| 783 | + | |
| 784 | rodPercentage = (rodPercentage - 1) | |
| 785 | --Boundary check | |
| 786 | - | printLog("reactor["..reactorIndex.."] in handleReactorMonitorClick(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is a valid Big Reactor.")
|
| 786 | + | |
| 787 | reactor.setAllControlRodLevels(0) | |
| 788 | - | printLog("reactor["..reactorIndex.."] in handleReactorMonitorClick(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is connected.")
|
| 788 | + | |
| 789 | reactor.setAllControlRodLevels(rodPercentage) | |
| 790 | - | printLog("reactor["..reactorIndex.."] in handleReactorMonitorClick(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is NOT connected.")
|
| 790 | + | |
| 791 | else | |
| 792 | rodPercentage = (rodPercentage + 1) | |
| 793 | --Boundary check | |
| 794 | if rodPercentage > 99 then | |
| 795 | - | local reactorStatus = _G[reactorNames[reactorIndex]]["ReactorOptions"]["Status"] |
| 795 | + | |
| 796 | else | |
| 797 | reactor.setAllControlRodLevels(rodPercentage) | |
| 798 | - | if xClick >= (width - string.len(reactorStatus) - 1) and xClick <= (width-1) and (sideClick == monitorNames[monitorIndex]) then |
| 798 | + | |
| 799 | - | if yClick == 1 then |
| 799 | + | |
| 800 | - | reactor.setActive(not reactor.getActive()) -- Toggle reactor status |
| 800 | + | |
| 801 | - | _G[reactorNames[reactorIndex]]["ReactorOptions"]["autoStart"] = reactor.getActive() |
| 801 | + | |
| 802 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorCruising"] = false | |
| 803 | end -- if ((reactorTemp < cruiseMaxTemp) and (reactorTemp > cruiseMinTemp)) then | |
| 804 | else | |
| 805 | - | -- If someone offlines the reactor (offline after a status click was detected), then disable autoStart |
| 805 | + | |
| 806 | - | if not reactor.getActive() then |
| 806 | + | |
| 807 | end -- if ((lastPolledTemp < cruiseMaxTemp) and (lastPolledTemp > cruiseMinTemp)) then | |
| 808 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["lastTempPoll"] = reactorTemp | |
| 809 | - | end -- if yClick == 1 then |
| 809 | + | |
| 810 | - | end -- if (xClick >= (width - string.len(reactorStatus) - 1) and xClick <= (width-1)) and (sideClick == monitorNames[monitorIndex]) then |
| 810 | + | |
| 811 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorMinTemp"] = cruiseMinTemp | |
| 812 | - | -- Allow disabling rod level auto-adjust and only manual rod level control |
| 812 | + | |
| 813 | - | if ((xClick > 23 and xClick < 28 and yClick == 4) |
| 813 | + | |
| 814 | - | or (xClick > 20 and xClick < 27 and yClick == 9)) |
| 814 | + | |
| 815 | - | and (sideClick == monitorNames[monitorIndex]) then |
| 815 | + | |
| 816 | - | _G[reactorNames[reactorIndex]]["ReactorOptions"]["rodOverride"] = not _G[reactorNames[reactorIndex]]["ReactorOptions"]["rodOverride"] |
| 816 | + | |
| 817 | local function temperatureControl(reactorIndex) | |
| 818 | - | sideClick, xClick, yClick = 0, 0, 0 -- Reset click after we register it |
| 818 | + | |
| 819 | - | end -- if (xClick > 23) and (xClick < 28) and (yClick == 4) and (sideClick == monitorNames[monitorIndex]) then |
| 819 | + | |
| 820 | local reactor = nil | |
| 821 | reactor = reactorList[reactorIndex] | |
| 822 | - | local newRodPercentage = rodPercentage |
| 822 | + | |
| 823 | printLog("reactor["..reactorIndex.."] in temperatureControl(reactorIndex="..reactorIndex..") is NOT a valid Big Reactor.")
| |
| 824 | - | printLog("Decreasing Rod Levels in handleReactorMonitorClick(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").")
|
| 824 | + | |
| 825 | else | |
| 826 | printLog("reactor["..reactorIndex.."] in temperatureControl(reactorIndex="..reactorIndex..") is a valid Big Reactor.")
| |
| 827 | ||
| 828 | if reactor.getConnected() then | |
| 829 | printLog("reactor["..reactorIndex.."] in temperatureControl(reactorIndex="..reactorIndex..") is connected.")
| |
| 830 | else | |
| 831 | printLog("reactor["..reactorIndex.."] in temperatureControl(reactorIndex="..reactorIndex..") is NOT connected.")
| |
| 832 | - | printLog("Setting reactor["..reactorIndex.."] Rod Levels to "..newRodPercentage.."% in handleReactorMonitorClick(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").")
|
| 832 | + | |
| 833 | end -- if reactor.getConnected() then | |
| 834 | end | |
| 835 | ||
| 836 | local reactorNum = reactorIndex | |
| 837 | local rodPercentage = math.ceil(reactor.getControlRodLevel(0)) | |
| 838 | local reactorTemp = math.ceil(reactor.getFuelTemperature()) | |
| 839 | local localMinReactorTemp, localMaxReactorTemp = _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorMinTemp"], _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorMaxTemp"] | |
| 840 | - | printLog("Increasing Rod Levels in handleReactorMonitorClick(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").")
|
| 840 | + | |
| 841 | --bypass if the reactor itself is set to not be auto-controlled | |
| 842 | if ((not _G[reactorNames[reactorIndex]]["ReactorOptions"]["rodOverride"]) or (_G[reactorNames[reactorIndex]]["ReactorOptions"]["rodOverride"] == "false")) then | |
| 843 | -- No point modifying control rod levels for temperature if the reactor is offline | |
| 844 | if reactor.getActive() then | |
| 845 | -- Actively cooled reactors should range between 0^C-300^C | |
| 846 | -- Actually, active-cooled reactors should range between 300 and 420C (Mechaet) | |
| 847 | -- Accordingly I changed the below lines | |
| 848 | - | printLog("Setting reactor["..reactorIndex.."] Rod Levels to "..newRodPercentage.."% in handleReactorMonitorClick(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").")
|
| 848 | + | |
| 849 | -- below was 0 | |
| 850 | localMinReactorTemp = 300 | |
| 851 | -- below was 300 | |
| 852 | localMaxReactorTemp = 420 | |
| 853 | else | |
| 854 | localMinReactorTemp = _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorMinTemp"] | |
| 855 | localMaxReactorTemp = _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorMaxTemp"] | |
| 856 | - | printLog("No change to Rod Levels requested by "..progName.." GUI in handleReactorMonitorClick(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").")
|
| 856 | + | |
| 857 | local lastTempPoll = _G[reactorNames[reactorIndex]]["ReactorOptions"]["lastTempPoll"] | |
| 858 | - | end -- UI.handleReactorMonitorClick = function(self, reactorIndex, monitorIndex) |
| 858 | + | |
| 859 | --let's bypass all this math and hit the much-more-subtle cruise feature | |
| 860 | - | -- Allow controlling Turbine Flow Rate from GUI |
| 860 | + | |
| 861 | - | UI.handleTurbineMonitorClick = function(self, turbineIndex, monitorIndex) |
| 861 | + | |
| 862 | else | |
| 863 | -- Don't bring us to 100, that's effectively a shutdown | |
| 864 | if (reactorTemp > localMaxReactorTemp) and (rodPercentage ~= 99) then | |
| 865 | --increase the rods, but by how much? | |
| 866 | if (reactorTemp > lastTempPoll) then | |
| 867 | --we're climbing, we need to get this to decrease | |
| 868 | if ((reactorTemp - lastTempPoll) > 100) then | |
| 869 | --we're climbing really fast, arrest it | |
| 870 | if (rodPercentage + (10 * controlRodAdjustAmount)) > 99 then | |
| 871 | reactor.setAllControlRodLevels(99) | |
| 872 | else | |
| 873 | reactor.setAllControlRodLevels(rodPercentage + (10 * controlRodAdjustAmount)) | |
| 874 | end | |
| 875 | else | |
| 876 | --we're not climbing by leaps and bounds, let's give it a rod adjustment based on temperature increase | |
| 877 | local diffAmount = reactorTemp - lastTempPoll | |
| 878 | - | printLog("turbine["..turbineIndex.."] in handleTurbineMonitorClick(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..") is NOT a valid Big Turbine.")
|
| 878 | + | |
| 879 | controlRodAdjustAmount = diffAmount | |
| 880 | if (rodPercentage + controlRodAdjustAmount) > 99 then | |
| 881 | - | printLog("turbine["..turbineIndex.."] in handleTurbineMonitorClick(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..") is a valid Big Turbine.")
|
| 881 | + | |
| 882 | else | |
| 883 | - | printLog("turbine["..turbineIndex.."] in handleTurbineMonitorClick(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..") is connected.")
|
| 883 | + | reactor.setAllControlRodLevels(rodPercentage + controlRodAdjustAmount) |
| 884 | end | |
| 885 | - | printLog("turbine["..turbineIndex.."] in handleTurbineMonitorClick(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..") is NOT connected.")
|
| 885 | + | |
| 886 | elseif (reactorTemp == lastTempPoll) then | |
| 887 | --temperature has stagnated, kick it very lightly | |
| 888 | local controlRodAdjustment = 1 | |
| 889 | if (rodPercentage + controlRodAdjustment) > 99 then | |
| 890 | reactor.setAllControlRodLevels(99) | |
| 891 | else | |
| 892 | - | local turbineStatus = _G[turbineNames[turbineIndex]]["TurbineOptions"]["Status"] |
| 892 | + | |
| 893 | end | |
| 894 | end --if (reactorTemp > lastTempPoll) then | |
| 895 | - | if (xClick >= (width - string.len(turbineStatus) - 1)) and (xClick <= (width-1)) and (sideClick == monitorNames[monitorIndex]) then |
| 895 | + | |
| 896 | - | if yClick == 1 then |
| 896 | + | |
| 897 | - | turbine.setActive(not turbine.getActive()) -- Toggle turbine status |
| 897 | + | elseif (reactorTemp < localMinReactorTemp) and (rodPercentage ~=0) then |
| 898 | - | _G[turbineNames[turbineIndex]]["TurbineOptions"]["autoStart"] = turbine.getActive() |
| 898 | + | |
| 899 | if (reactorTemp < lastTempPoll) then | |
| 900 | --we're descending, let's stop that. | |
| 901 | if ((lastTempPoll - reactorTemp) > 100) then | |
| 902 | - | end -- if yClick == 1 then |
| 902 | + | |
| 903 | - | end -- if (xClick >= (width - string.len(turbineStatus) - 1)) and (xClick <= (width-1)) and (sideClick == monitorNames[monitorIndex]) then |
| 903 | + | if (rodPercentage - (10 * controlRodAdjustAmount)) < 0 then |
| 904 | reactor.setAllControlRodLevels(0) | |
| 905 | - | -- Allow disabling/enabling flow rate auto-adjust |
| 905 | + | |
| 906 | - | if (xClick > 23 and xClick < 28 and yClick == 4) and (sideClick == monitorNames[monitorIndex]) then |
| 906 | + | reactor.setAllControlRodLevels(rodPercentage - (10 * controlRodAdjustAmount)) |
| 907 | - | _G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"] = true |
| 907 | + | |
| 908 | - | sideClick, xClick, yClick = 0, 0, 0 -- Reset click after we register it |
| 908 | + | |
| 909 | - | elseif (xClick > 20 and xClick < 27 and yClick == 10) and (sideClick == monitorNames[monitorIndex]) then |
| 909 | + | |
| 910 | local diffAmount = lastTempPoll - reactorTemp | |
| 911 | - | if ((_G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"]) or (_G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"] == "true")) then |
| 911 | + | |
| 912 | - | _G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"] = false |
| 912 | + | controlRodAdjustAmount = diffAmount |
| 913 | if (rodPercentage - controlRodAdjustAmount) < 0 then | |
| 914 | reactor.setAllControlRodLevels(0) | |
| 915 | else | |
| 916 | - | sideClick, xClick, yClick = 0, 0, 0 -- Reset click after we register it |
| 916 | + | reactor.setAllControlRodLevels(rodPercentage - controlRodAdjustAmount) |
| 917 | end | |
| 918 | end --if ((lastTempPoll - reactorTemp) > 100) then | |
| 919 | elseif (reactorTemp == lastTempPoll) then | |
| 920 | --temperature has stagnated, kick it very lightly | |
| 921 | - | printLog("Decrease to Flow Rate requested by "..progName.." GUI in handleTurbineMonitorClick(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").")
|
| 921 | + | |
| 922 | if (rodPercentage - controlRodAdjustment) < 0 then | |
| 923 | reactor.setAllControlRodLevels(0) | |
| 924 | else | |
| 925 | reactor.setAllControlRodLevels(rodPercentage - controlRodAdjustment) | |
| 926 | end --if (rodPercentage - controlRodAdjustment) < 0 then | |
| 927 | ||
| 928 | end --if (reactorTemp < lastTempPoll) then | |
| 929 | --if we're below temp but increasing, do nothing and let it continue to rise. | |
| 930 | end --if (reactorTemp > localMaxReactorTemp) and (rodPercentage ~= 99) then | |
| 931 | ||
| 932 | if ((reactorTemp > localMinReactorTemp) and (reactorTemp < localMaxReactorTemp)) then | |
| 933 | --engage cruise mode | |
| 934 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorCruising"] = true | |
| 935 | end -- if ((reactorTemp > localMinReactorTemp) and (reactorTemp < localMaxReactorTemp)) then | |
| 936 | end -- if reactorCruising then | |
| 937 | --always set this number | |
| 938 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["lastTempPoll"] = reactorTemp | |
| 939 | config.save(reactorNames[reactorIndex]..".options", _G[reactorNames[reactorIndex]]) | |
| 940 | end -- if reactor.getActive() then | |
| 941 | else | |
| 942 | - | printLog("Increase to Flow Rate requested by "..progName.." GUI in handleTurbineMonitorClick(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").")
|
| 942 | + | |
| 943 | end -- if not _G[reactorNames[reactorIndex]]["ReactorOptions"]["rodOverride"] then | |
| 944 | end -- function temperatureControl(reactorIndex) | |
| 945 | ||
| 946 | -- Load saved reactor parameters if ReactorOptions file exists | |
| 947 | local function loadReactorOptions() | |
| 948 | local reactorOptions = fs.open("ReactorOptions", "r") -- See http://computercraft.info/wiki/Fs.open
| |
| 949 | ||
| 950 | if reactorOptions then | |
| 951 | -- The following values were added by Lolmer | |
| 952 | minStoredEnergyPercent = reactorOptions.readLine() | |
| 953 | maxStoredEnergyPercent = reactorOptions.readLine() | |
| 954 | --added by Mechaet | |
| 955 | -- If we succeeded in reading a string, convert it to a number | |
| 956 | ||
| 957 | if minStoredEnergyPercent ~= nil then | |
| 958 | minStoredEnergyPercent = tonumber(minStoredEnergyPercent) | |
| 959 | end | |
| 960 | ||
| 961 | if maxStoredEnergyPercent ~= nil then | |
| 962 | maxStoredEnergyPercent = tonumber(maxStoredEnergyPercent) | |
| 963 | end | |
| 964 | - | printLog("No change to Flow Rate requested by "..progName.." GUI in handleTurbineMonitorClick(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").")
|
| 964 | + | |
| 965 | reactorOptions.close() | |
| 966 | end -- if reactorOptions then | |
| 967 | ||
| 968 | - | printLog("Decrease to Turbine RPM requested by "..progName.." GUI in handleTurbineMonitorClick(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").")
|
| 968 | + | |
| 969 | if minStoredEnergyPercent == nil then | |
| 970 | minStoredEnergyPercent = 15 | |
| 971 | end | |
| 972 | ||
| 973 | if maxStoredEnergyPercent == nil then | |
| 974 | maxStoredEnergyPercent = 85 | |
| 975 | end | |
| 976 | ||
| 977 | end -- function loadReactorOptions() | |
| 978 | - | printLog("Increase to Turbine RPM requested by "..progName.." GUI in handleTurbineMonitorClick(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").")
|
| 978 | + | |
| 979 | ||
| 980 | -- Save our reactor parameters | |
| 981 | local function saveReactorOptions() | |
| 982 | local reactorOptions = fs.open("ReactorOptions", "w") -- See http://computercraft.info/wiki/Fs.open
| |
| 983 | ||
| 984 | -- If we can save the files, save them | |
| 985 | if reactorOptions then | |
| 986 | local reactorIndex = 1 | |
| 987 | -- The following values were added by Lolmer | |
| 988 | - | printLog("No change to Turbine RPM requested by "..progName.." GUI in handleTurbineMonitorClick(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").")
|
| 988 | + | |
| 989 | reactorOptions.writeLine(maxStoredEnergyPercent) | |
| 990 | - | end -- function handleTurbineMonitorClick(turbineIndex, monitorIndex) |
| 990 | + | |
| 991 | else | |
| 992 | printLog("Failed to open file ReactorOptions for writing!")
| |
| 993 | end -- if reactorOptions then | |
| 994 | end -- function saveReactorOptions() | |
| 995 | ||
| 996 | ||
| 997 | local function displayReactorBars(barParams) | |
| 998 | -- Default to first reactor and first monitor | |
| 999 | setmetatable(barParams,{__index={reactorIndex=1, monitorIndex=1}})
| |
| 1000 | local reactorIndex, monitorIndex = | |
| 1001 | barParams[1] or barParams.reactorIndex, | |
| 1002 | barParams[2] or barParams.monitorIndex | |
| 1003 | ||
| 1004 | printLog("Called as displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").")
| |
| 1005 | - | printLog("No monitors found, continuing headless")
|
| 1005 | + | |
| 1006 | -- Grab current monitor | |
| 1007 | local monitor = nil | |
| 1008 | monitor = monitorList[monitorIndex] | |
| 1009 | if not monitor then | |
| 1010 | printLog("monitor["..monitorIndex.."] in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is NOT a valid monitor.")
| |
| 1011 | return -- Invalid monitorIndex | |
| 1012 | end | |
| 1013 | ||
| 1014 | -- Grab current reactor | |
| 1015 | local reactor = nil | |
| 1016 | reactor = reactorList[reactorIndex] | |
| 1017 | if not reactor then | |
| 1018 | printLog("reactor["..reactorIndex.."] in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is NOT a valid Big Reactor.")
| |
| 1019 | return -- Invalid reactorIndex | |
| 1020 | - | monitor.setTextScale(1.0) -- Make sure scale is correct |
| 1020 | + | |
| 1021 | printLog("reactor["..reactorIndex.."] in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is a valid Big Reactor.")
| |
| 1022 | if reactor.getConnected() then | |
| 1023 | printLog("reactor["..reactorIndex.."] in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is connected.")
| |
| 1024 | else | |
| 1025 | printLog("reactor["..reactorIndex.."] in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is NOT connected.")
| |
| 1026 | return -- Disconnected reactor | |
| 1027 | end -- if reactor.getConnected() then | |
| 1028 | end -- if not reactor then | |
| 1029 | ||
| 1030 | -- Draw border lines | |
| 1031 | local width, height = monitor.getSize() | |
| 1032 | printLog("Size of monitor is "..width.."w x"..height.."h in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..")")
| |
| 1033 | ||
| 1034 | for i=3, 5 do | |
| 1035 | monitor.setCursorPos(22, i) | |
| 1036 | monitor.write("|")
| |
| 1037 | end | |
| 1038 | ||
| 1039 | drawLine(2, monitorIndex) | |
| 1040 | drawLine(6, monitorIndex) | |
| 1041 | ||
| 1042 | -- Draw some text | |
| 1043 | local fuelString = "Fuel: " | |
| 1044 | local tempString = "Temp: " | |
| 1045 | local energyBufferString = "" | |
| 1046 | ||
| 1047 | if reactor.isActivelyCooled() then | |
| 1048 | energyBufferString = "Steam: " | |
| 1049 | else | |
| 1050 | energyBufferString = "Energy: " | |
| 1051 | end | |
| 1052 | ||
| 1053 | local padding = math.max(string.len(fuelString), string.len(tempString), string.len(energyBufferString)) | |
| 1054 | ||
| 1055 | local fuelPercentage = round(reactor.getFuelAmount()/reactor.getFuelAmountMax()*100,1) | |
| 1056 | print{fuelString,2,3,monitorIndex}
| |
| 1057 | print{fuelPercentage.." %",padding+2,3,monitorIndex}
| |
| 1058 | ||
| 1059 | local reactorTemp = math.ceil(reactor.getFuelTemperature()) | |
| 1060 | print{tempString,2,5,monitorIndex}
| |
| 1061 | print{reactorTemp.." C",padding+2,5,monitorIndex}
| |
| 1062 | ||
| 1063 | local rodPercentage = math.ceil(reactor.getControlRodLevel(0)) | |
| 1064 | printLog("Current Rod Percentage for reactor["..reactorIndex.."] is "..rodPercentage.."% in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").")
| |
| 1065 | -- Allow controlling Reactor Control Rod Level from GUI | |
| 1066 | -- Decrease rod button: 23X, 4Y | |
| 1067 | -- Increase rod button: 28X, 4Y | |
| 1068 | if (xClick == 23) and (yClick == 4) and (sideClick == monitorNames[monitorIndex]) then | |
| 1069 | printLog("Decreasing Rod Levels in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").")
| |
| 1070 | --Decrease rod level by amount | |
| 1071 | newRodPercentage = rodPercentage - (5 * controlRodAdjustAmount) | |
| 1072 | if newRodPercentage < 0 then | |
| 1073 | newRodPercentage = 0 | |
| 1074 | end | |
| 1075 | sideClick, xClick, yClick = 0, 0, 0 | |
| 1076 | ||
| 1077 | printLog("Setting reactor["..reactorIndex.."] Rod Levels to "..newRodPercentage.."% in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").")
| |
| 1078 | reactor.setAllControlRodLevels(newRodPercentage) | |
| 1079 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["baseControlRodLevel"] = newRodPercentage | |
| 1080 | ||
| 1081 | -- Save updated rod percentage | |
| 1082 | config.save(reactorNames[reactorIndex]..".options", _G[reactorNames[reactorIndex]]) | |
| 1083 | rodPercentage = newRodPercentage | |
| 1084 | elseif (xClick == 29) and (yClick == 4) and (sideClick == monitorNames[monitorIndex]) then | |
| 1085 | printLog("Increasing Rod Levels in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").")
| |
| 1086 | --Increase rod level by amount | |
| 1087 | newRodPercentage = rodPercentage + (5 * controlRodAdjustAmount) | |
| 1088 | if newRodPercentage > 100 then | |
| 1089 | newRodPercentage = 100 | |
| 1090 | end | |
| 1091 | sideClick, xClick, yClick = 0, 0, 0 | |
| 1092 | ||
| 1093 | printLog("Setting reactor["..reactorIndex.."] Rod Levels to "..newRodPercentage.."% in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").")
| |
| 1094 | reactor.setAllControlRodLevels(newRodPercentage) | |
| 1095 | - | _G[reactorNames[reactorIndex]]["ReactorOptions"]["controlRodAdjustAmount"] = controlRodAdjustAmount |
| 1095 | + | |
| 1096 | ||
| 1097 | -- Save updated rod percentage | |
| 1098 | config.save(reactorNames[reactorIndex]..".options", _G[reactorNames[reactorIndex]]) | |
| 1099 | rodPercentage = round(newRodPercentage,0) | |
| 1100 | else | |
| 1101 | printLog("No change to Rod Levels requested by "..progName.." GUI in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").")
| |
| 1102 | end -- if (xClick == 29) and (yClick == 4) and (sideClick == monitorNames[monitorIndex]) then | |
| 1103 | ||
| 1104 | print{"Rod (%)",23,3,monitorIndex}
| |
| 1105 | print{"< >",23,4,monitorIndex}
| |
| 1106 | print{stringTrim(rodPercentage),25,4,monitorIndex}
| |
| 1107 | ||
| 1108 | ||
| 1109 | -- getEnergyProducedLastTick() is used for both RF/t (passively cooled) and mB/t (actively cooled) | |
| 1110 | local energyBuffer = reactor.getEnergyProducedLastTick() | |
| 1111 | if reactor.isActivelyCooled() then | |
| 1112 | printLog("reactor["..reactorIndex.."] produced "..energyBuffer.." mB last tick in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").")
| |
| 1113 | else | |
| 1114 | printLog("reactor["..reactorIndex.."] produced "..energyBuffer.." RF last tick in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").")
| |
| 1115 | end | |
| 1116 | ||
| 1117 | print{energyBufferString,2,4,monitorIndex}
| |
| 1118 | ||
| 1119 | -- Actively cooled reactors do not produce energy, only hot fluid mB/t to be used in a turbine | |
| 1120 | -- still uses getEnergyProducedLastTick for mB/t of hot fluid generated | |
| 1121 | if not reactor.isActivelyCooled() then | |
| 1122 | printLog("reactor["..reactorIndex.."] in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is NOT an actively cooled reactor.")
| |
| 1123 | ||
| 1124 | -- Draw stored energy buffer bar | |
| 1125 | drawBar(2,8,28,8,colors.gray,monitorIndex) | |
| 1126 | ||
| 1127 | local curStoredEnergyPercent = getReactorStoredEnergyBufferPercent(reactor) | |
| 1128 | if curStoredEnergyPercent > 4 then | |
| 1129 | drawBar(2, 8, math.floor(26*curStoredEnergyPercent/100)+2, 8, colors.yellow, monitorIndex) | |
| 1130 | elseif curStoredEnergyPercent > 0 then | |
| 1131 | drawPixel(2, 8, colors.yellow, monitorIndex) | |
| 1132 | end -- if curStoredEnergyPercent > 4 then | |
| 1133 | ||
| 1134 | print{"Energy Buffer",2,7,monitorIndex}
| |
| 1135 | print{curStoredEnergyPercent, width-(string.len(curStoredEnergyPercent)+2),7,monitorIndex}
| |
| 1136 | print{"%",28,7,monitorIndex}
| |
| 1137 | ||
| 1138 | print{math.ceil(energyBuffer).." RF/t",padding+2,4,monitorIndex}
| |
| 1139 | else | |
| 1140 | printLog("reactor["..reactorIndex.."] in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is an actively cooled reactor.")
| |
| 1141 | print{math.ceil(energyBuffer).." mB/t",padding+2,4,monitorIndex}
| |
| 1142 | end -- if not reactor.isActivelyCooled() then | |
| 1143 | ||
| 1144 | -- Print rod override status | |
| 1145 | local reactorRodOverrideStatus = "" | |
| 1146 | ||
| 1147 | - | if tempTable["ReactorOptions"]["controlRodAdjustAmount"] ~= nil then |
| 1147 | + | |
| 1148 | - | _G[reactorNames[reactorIndex]]["ReactorOptions"]["controlRodAdjustAmount"] = tempTable["ReactorOptions"]["controlRodAdjustAmount"] |
| 1148 | + | |
| 1149 | if not _G[reactorNames[reactorIndex]]["ReactorOptions"]["rodOverride"] then | |
| 1150 | printLog("Reactor Rod Override status is: "..tostring(_G[reactorNames[reactorIndex]]["ReactorOptions"]["rodOverride"]).." EOL")
| |
| 1151 | reactorRodOverrideStatus = "Enabled" | |
| 1152 | monitor.setTextColor(colors.green) | |
| 1153 | else | |
| 1154 | printLog("Reactor Rod Override status is: "..tostring(_G[reactorNames[reactorIndex]]["ReactorOptions"]["rodOverride"]).." EOL")
| |
| 1155 | reactorRodOverrideStatus = "Disabled" | |
| 1156 | monitor.setTextColor(colors.red) | |
| 1157 | end -- if not reactorRodOverride then | |
| 1158 | printLog("reactorRodOverrideStatus is \""..reactorRodOverrideStatus.."\" in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").")
| |
| 1159 | ||
| 1160 | print{reactorRodOverrideStatus, width - string.len(reactorRodOverrideStatus) - 1, 9, monitorIndex}
| |
| 1161 | monitor.setTextColor(colors.white) | |
| 1162 | ||
| 1163 | print{"Reactivity: "..math.ceil(reactor.getFuelReactivity()).." %", 2, 10, monitorIndex}
| |
| 1164 | print{"Fuel: "..round(reactor.getFuelConsumedLastTick(),3).." mB/t", 2, 11, monitorIndex}
| |
| 1165 | print{"Waste: "..reactor.getWasteAmount().." mB", width-(string.len(reactor.getWasteAmount())+10), 11, monitorIndex}
| |
| 1166 | ||
| 1167 | monitor.setTextColor(colors.blue) | |
| 1168 | printCentered(_G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorName"],12,monitorIndex) | |
| 1169 | monitor.setTextColor(colors.white) | |
| 1170 | end -- function displayReactorBars(barParams) | |
| 1171 | ||
| 1172 | ||
| 1173 | local function reactorStatus(statusParams) | |
| 1174 | -- Default to first reactor and first monitor | |
| 1175 | setmetatable(statusParams,{__index={reactorIndex=1, monitorIndex=1}})
| |
| 1176 | local reactorIndex, monitorIndex = | |
| 1177 | statusParams[1] or statusParams.reactorIndex, | |
| 1178 | statusParams[2] or statusParams.monitorIndex | |
| 1179 | printLog("Called as reactorStatus(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..")")
| |
| 1180 | ||
| 1181 | -- Grab current monitor | |
| 1182 | local monitor = nil | |
| 1183 | monitor = monitorList[monitorIndex] | |
| 1184 | if not monitor then | |
| 1185 | printLog("monitor["..monitorIndex.."] in reactorStatus(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is NOT a valid monitor.")
| |
| 1186 | return -- Invalid monitorIndex | |
| 1187 | end | |
| 1188 | - | _G[reactorNames[reactorIndex]]["ReactorOptions"]["controlRodAdjustAmount"] = tonumber(_G[reactorNames[reactorIndex]]["ReactorOptions"]["controlRodAdjustAmount"]) |
| 1188 | + | |
| 1189 | -- Grab current reactor | |
| 1190 | local reactor = nil | |
| 1191 | reactor = reactorList[reactorIndex] | |
| 1192 | if not reactor then | |
| 1193 | printLog("reactor["..reactorIndex.."] in reactorStatus(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is NOT a valid Big Reactor.")
| |
| 1194 | return -- Invalid reactorIndex | |
| 1195 | else | |
| 1196 | printLog("reactor["..reactorIndex.."] in reactorStatus(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is a valid Big Reactor.")
| |
| 1197 | end | |
| 1198 | ||
| 1199 | local width, height = monitor.getSize() | |
| 1200 | local reactorStatus = "" | |
| 1201 | ||
| 1202 | if reactor.getConnected() then | |
| 1203 | printLog("reactor["..reactorIndex.."] in reactorStatus(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is connected.")
| |
| 1204 | ||
| 1205 | if reactor.getActive() then | |
| 1206 | reactorStatus = "ONLINE" | |
| 1207 | ||
| 1208 | -- Set "ONLINE" to blue if the actively cooled reactor is both in cruise mode and online | |
| 1209 | if _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorCruising"] and reactor.isActivelyCooled() then | |
| 1210 | monitor.setTextColor(colors.blue) | |
| 1211 | else | |
| 1212 | monitor.setTextColor(colors.green) | |
| 1213 | end -- if reactorCruising and reactor.isActivelyCooled() then | |
| 1214 | else | |
| 1215 | reactorStatus = "OFFLINE" | |
| 1216 | monitor.setTextColor(colors.red) | |
| 1217 | end -- if reactor.getActive() then | |
| 1218 | ||
| 1219 | if xClick >= (width - string.len(reactorStatus) - 1) and xClick <= (width-1) and (sideClick == monitorNames[monitorIndex]) then | |
| 1220 | if yClick == 1 then | |
| 1221 | reactor.setActive(not reactor.getActive()) -- Toggle reactor status | |
| 1222 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["autoStart"] = reactor.getActive() | |
| 1223 | config.save(reactorNames[reactorIndex]..".options", _G[reactorNames[reactorIndex]]) | |
| 1224 | sideClick, xClick, yClick = 0, 0, 0 -- Reset click after we register it | |
| 1225 | ||
| 1226 | -- If someone offlines the reactor (offline after a status click was detected), then disable autoStart | |
| 1227 | if not reactor.getActive() then | |
| 1228 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["autoStart"] = false | |
| 1229 | end | |
| 1230 | end -- if yClick == 1 then | |
| 1231 | end -- if (xClick >= (width - string.len(reactorStatus) - 1) and xClick <= (width-1)) and (sideClick == monitorNames[monitorIndex]) then | |
| 1232 | ||
| 1233 | -- Allow disabling rod level auto-adjust and only manual rod level control | |
| 1234 | if ((xClick > 23 and xClick < 28 and yClick == 4) | |
| 1235 | or (xClick > 20 and xClick < 27 and yClick == 9)) | |
| 1236 | and (sideClick == monitorNames[monitorIndex]) then | |
| 1237 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["rodOverride"] = not _G[reactorNames[reactorIndex]]["ReactorOptions"]["rodOverride"] | |
| 1238 | config.save(reactorNames[reactorIndex]..".options", _G[reactorNames[reactorIndex]]) | |
| 1239 | sideClick, xClick, yClick = 0, 0, 0 -- Reset click after we register it | |
| 1240 | end -- if (xClick > 23) and (xClick < 28) and (yClick == 4) and (sideClick == monitorNames[monitorIndex]) then | |
| 1241 | ||
| 1242 | else | |
| 1243 | printLog("reactor["..reactorIndex.."] in reactorStatus(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is NOT connected.")
| |
| 1244 | reactorStatus = "DISCONNECTED" | |
| 1245 | monitor.setTextColor(colors.red) | |
| 1246 | end -- if reactor.getConnected() then | |
| 1247 | ||
| 1248 | print{reactorStatus, width - string.len(reactorStatus) - 1, 1, monitorIndex}
| |
| 1249 | monitor.setTextColor(colors.white) | |
| 1250 | end -- function reactorStatus(statusParams) | |
| 1251 | ||
| 1252 | ||
| 1253 | -- Display all found reactors' status to monitor 1 | |
| 1254 | -- This is only called if multiple reactors and/or a reactor plus at least one turbine are found | |
| 1255 | local function displayAllStatus() | |
| 1256 | local reactor, turbine = nil, nil | |
| 1257 | local onlineReactor, onlineTurbine = 0, 0 | |
| 1258 | local totalReactorRF, totalReactorSteam, totalTurbineRF = 0, 0, 0 | |
| 1259 | local totalReactorFuelConsumed = 0 | |
| 1260 | local totalCoolantStored, totalSteamStored, totalEnergy, totalMaxEnergyStored = 0, 0, 0, 0 -- Total turbine and reactor energy buffer and overall capacity | |
| 1261 | local maxSteamStored = (2000*#turbineList)+(5000*#reactorList) | |
| 1262 | local maxCoolantStored = (2000*#turbineList)+(5000*#reactorList) | |
| 1263 | ||
| 1264 | local monitor, monitorIndex = nil, 1 | |
| 1265 | monitor = monitorList[monitorIndex] | |
| 1266 | if not monitor then | |
| 1267 | printLog("monitor["..monitorIndex.."] in displayAllStatus() is NOT a valid monitor.")
| |
| 1268 | return -- Invalid monitorIndex | |
| 1269 | end | |
| 1270 | ||
| 1271 | for reactorIndex = 1, #reactorList do | |
| 1272 | reactor = reactorList[reactorIndex] | |
| 1273 | if not reactor then | |
| 1274 | printLog("reactor["..reactorIndex.."] in displayAllStatus() is NOT a valid Big Reactor.")
| |
| 1275 | break -- Invalid reactorIndex | |
| 1276 | else | |
| 1277 | printLog("reactor["..reactorIndex.."] in displayAllStatus() is a valid Big Reactor.")
| |
| 1278 | end -- if not reactor then | |
| 1279 | ||
| 1280 | if reactor.getConnected() then | |
| 1281 | printLog("reactor["..reactorIndex.."] in displayAllStatus() is connected.")
| |
| 1282 | if reactor.getActive() then | |
| 1283 | onlineReactor = onlineReactor + 1 | |
| 1284 | totalReactorFuelConsumed = totalReactorFuelConsumed + reactor.getFuelConsumedLastTick() | |
| 1285 | end -- reactor.getActive() then | |
| 1286 | ||
| 1287 | -- Actively cooled reactors do not produce or store energy | |
| 1288 | if not reactor.isActivelyCooled() then | |
| 1289 | totalMaxEnergyStored = totalMaxEnergyStored + 10000000 -- Reactors store 10M RF | |
| 1290 | totalEnergy = totalEnergy + reactor.getEnergyStored() | |
| 1291 | totalReactorRF = totalReactorRF + reactor.getEnergyProducedLastTick() | |
| 1292 | else | |
| 1293 | totalReactorSteam = totalReactorSteam + reactor.getEnergyProducedLastTick() | |
| 1294 | totalSteamStored = totalSteamStored + reactor.getHotFluidAmount() | |
| 1295 | totalCoolantStored = totalCoolantStored + reactor.getCoolantAmount() | |
| 1296 | end -- if not reactor.isActivelyCooled() then | |
| 1297 | else | |
| 1298 | - | -- Assign status, reactors, turbines and debug output to the monitors that shall display them |
| 1298 | + | |
| 1299 | - | -- Depends on the [monitor,reactor,turbine]Lists being populated already |
| 1299 | + | |
| 1300 | - | local function assignMonitors() |
| 1300 | + | |
| 1301 | ||
| 1302 | - | local monitors = {}
|
| 1302 | + | |
| 1303 | - | monitorAssignments = {}
|
| 1303 | + | |
| 1304 | if not turbine then | |
| 1305 | - | printLog("Assigning monitors...")
|
| 1305 | + | |
| 1306 | break -- Invalid turbineIndex | |
| 1307 | - | local m = config.load(monitorOptionFileName) |
| 1307 | + | |
| 1308 | - | if (m ~= nil) then |
| 1308 | + | |
| 1309 | - | -- first, merge the detected and the configured monitor lists |
| 1309 | + | |
| 1310 | - | -- this is to ensure we pick up new additions to the network |
| 1310 | + | |
| 1311 | - | for monitorIndex, monitorName in ipairs(monitorNames) do |
| 1311 | + | |
| 1312 | - | monitors[monitorName] = m.Monitors[monitorName] or "" |
| 1312 | + | |
| 1313 | if turbine.getActive() then | |
| 1314 | - | -- then, go through all of it again to build our runtime data structure |
| 1314 | + | |
| 1315 | - | for monitorName, assignedName in pairs(monitors) do |
| 1315 | + | |
| 1316 | - | printLog("Looking for monitor and device named "..monitorName.." and "..assignedName)
|
| 1316 | + | |
| 1317 | - | for monitorIndex = 1, #monitorNames do |
| 1317 | + | |
| 1318 | - | printLog("if "..monitorName.." == "..monitorNames[monitorIndex].." then", DEBUG)
|
| 1318 | + | |
| 1319 | - | |
| 1319 | + | |
| 1320 | - | if monitorName == monitorNames[monitorIndex] then |
| 1320 | + | |
| 1321 | - | printLog("Found "..monitorName.." at index "..monitorIndex, DEBUG)
|
| 1321 | + | |
| 1322 | - | if assignedName == "Status" then |
| 1322 | + | |
| 1323 | - | monitorAssignments[monitorName] = {type="Status", index=monitorIndex}
|
| 1323 | + | |
| 1324 | - | elseif assignedName == "Debug" then |
| 1324 | + | |
| 1325 | - | monitorAssignments[monitorName] = {type="Debug", index=monitorIndex}
|
| 1325 | + | |
| 1326 | ||
| 1327 | - | local maxListLen = math.max(#reactorNames, #turbineNames) |
| 1327 | + | |
| 1328 | - | for i = 1, maxListLen do |
| 1328 | + | |
| 1329 | - | if assignedName == reactorNames[i] then |
| 1329 | + | |
| 1330 | - | monitorAssignments[monitorName] = {type="Reactor", index=monitorIndex, reactorName=reactorNames[i], reactorIndex=i}
|
| 1330 | + | |
| 1331 | - | break |
| 1331 | + | |
| 1332 | - | elseif assignedName == turbineNames[i] then |
| 1332 | + | |
| 1333 | - | monitorAssignments[monitorName] = {type="Turbine", index=monitorIndex, turbineName=turbineNames[i], turbineIndex=i}
|
| 1333 | + | |
| 1334 | - | break |
| 1334 | + | |
| 1335 | - | elseif i == maxListLen then |
| 1335 | + | |
| 1336 | - | printLog("assignMonitors(): Monitor "..monitorName.." was configured to display nonexistant device "..assignedName..". Setting inactive.", WARN)
|
| 1336 | + | |
| 1337 | - | monitorAssignments[monitorName] = {type="Inactive", index=monitorIndex}
|
| 1337 | + | |
| 1338 | -- Display liquids | |
| 1339 | monitor.setTextColor(colors.blue) | |
| 1340 | printLeft("Steam (mB)", 6, monitorIndex)
| |
| 1341 | - | break |
| 1341 | + | |
| 1342 | - | elseif monitorIndex == #monitorNames then |
| 1342 | + | |
| 1343 | - | printLog("assignMonitors(): Monitor "..monitorName.." not found. It was configured to display device "..assignedName..". Discarding.", WARN)
|
| 1343 | + | |
| 1344 | monitor.setTextColor(colors.blue) | |
| 1345 | printRight("Coolant (mB)", 6, monitorIndex)
| |
| 1346 | monitor.setTextColor(colors.white) | |
| 1347 | printRight(math.ceil(totalCoolantStored).."/"..maxCoolantStored, 7, monitorIndex) | |
| 1348 | - | printLog("No valid monitor configuration found, generating...")
|
| 1348 | + | |
| 1349 | monitor.setTextColor(colors.blue) | |
| 1350 | - | -- create assignments that reflect the setup before 0.3.17 |
| 1350 | + | |
| 1351 | monitor.setTextColor(colors.white) | |
| 1352 | - | monitorAssignments[monitorNames[1]] = {type="Status", index=1}
|
| 1352 | + | |
| 1353 | - | monitorIndex = monitorIndex + 1 |
| 1353 | + | |
| 1354 | ||
| 1355 | - | if monitorIndex > #monitorList then |
| 1355 | + | |
| 1356 | - | break |
| 1356 | + | print{"Buffer: "..math.ceil(totalEnergy,3).."/"..totalMaxEnergyStored.." RF", 2, 12, monitorIndex}
|
| 1357 | end -- function displayAllStatus() | |
| 1358 | - | monitorAssignments[monitorNames[monitorIndex]] = {type="Reactor", index=monitorIndex, reactorName=reactorNames[reactorIndex], reactorIndex=reactorIndex}
|
| 1358 | + | |
| 1359 | - | printLog(monitorNames[monitorIndex].." -> "..reactorNames[reactorIndex]) |
| 1359 | + | |
| 1360 | -- Get turbine status | |
| 1361 | - | monitorIndex = monitorIndex + 1 |
| 1361 | + | |
| 1362 | printLog("Called as displayTurbineBars(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").")
| |
| 1363 | ||
| 1364 | - | if monitorIndex > #monitorList then |
| 1364 | + | |
| 1365 | - | break |
| 1365 | + | |
| 1366 | monitor = monitorList[monitorIndex] | |
| 1367 | - | monitorAssignments[monitorNames[monitorIndex]] = {type="Turbine", index=monitorIndex, turbineName=turbineNames[turbineIndex], turbineIndex=turbineIndex}
|
| 1367 | + | |
| 1368 | - | printLog(monitorNames[monitorIndex].." -> "..turbineNames[turbineIndex]) |
| 1368 | + | |
| 1369 | return -- Invalid monitorIndex | |
| 1370 | - | monitorIndex = monitorIndex + 1 |
| 1370 | + | |
| 1371 | ||
| 1372 | - | if monitorIndex <= #monitorList then |
| 1372 | + | |
| 1373 | - | monitorAssignments[monitorNames[#monitorList]] = {type="Debug", index=#monitorList}
|
| 1373 | + | |
| 1374 | turbine = turbineList[turbineIndex] | |
| 1375 | if not turbine then | |
| 1376 | printLog("turbine["..turbineIndex.."] in displayTurbineBars(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..") is NOT a valid Big Turbine.")
| |
| 1377 | - | tprint(monitorAssignments) |
| 1377 | + | |
| 1378 | else | |
| 1379 | - | saveMonitorAssignments() |
| 1379 | + | |
| 1380 | if turbine.getConnected() then | |
| 1381 | - | end -- function assignMonitors() |
| 1381 | + | |
| 1382 | else | |
| 1383 | - | local eventHandler |
| 1383 | + | |
| 1384 | - | -- Replacement for sleep, which passes on events instead of dropping themo |
| 1384 | + | |
| 1385 | - | -- Straight from http://computercraft.info/wiki/Os.sleep |
| 1385 | + | |
| 1386 | - | local function wait(time) |
| 1386 | + | |
| 1387 | - | local timer = os.startTimer(time) |
| 1387 | + | |
| 1388 | --local variable to match the view on the monitor | |
| 1389 | - | while true do |
| 1389 | + | |
| 1390 | - | local event = {os.pullEvent()}
|
| 1390 | + | |
| 1391 | -- Draw border lines | |
| 1392 | - | if (event[1] == "timer" and event[2] == timer) then |
| 1392 | + | |
| 1393 | - | break |
| 1393 | + | |
| 1394 | for i=3, 6 do | |
| 1395 | - | eventHandler(event[1], event[2], event[3], event[4]) |
| 1395 | + | |
| 1396 | monitor.write("|")
| |
| 1397 | end | |
| 1398 | ||
| 1399 | drawLine(2,monitorIndex) | |
| 1400 | drawLine(7,monitorIndex) | |
| 1401 | ||
| 1402 | -- Allow controlling Turbine Flow Rate from GUI | |
| 1403 | -- Decrease flow rate button: 22X, 4Y | |
| 1404 | -- Increase flow rate button: 28X, 4Y | |
| 1405 | local turbineFlowRate = tonumber(_G[turbineNames[turbineIndex]]["TurbineOptions"]["LastFlow"]) | |
| 1406 | if (xClick == 22) and (yClick == 4) and (sideClick == monitorNames[monitorIndex]) then | |
| 1407 | printLog("Decrease to Flow Rate requested by "..progName.." GUI in displayTurbineBars(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").")
| |
| 1408 | --Decrease rod level by amount | |
| 1409 | newTurbineFlowRate = turbineFlowRate - flowRateAdjustAmount | |
| 1410 | if newTurbineFlowRate < 0 then | |
| 1411 | newTurbineFlowRate = 0 | |
| 1412 | end | |
| 1413 | sideClick, xClick, yClick = 0, 0, 0 | |
| 1414 | ||
| 1415 | -- Check bounds [0,2000] | |
| 1416 | if newTurbineFlowRate > 2000 then | |
| 1417 | newTurbineFlowRate = 2000 | |
| 1418 | elseif newTurbineFlowRate < 0 then | |
| 1419 | newTurbineFlowRate = 25 -- Don't go to zero, might as well power off | |
| 1420 | end | |
| 1421 | ||
| 1422 | turbine.setFluidFlowRateMax(newTurbineFlowRate) | |
| 1423 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["LastFlow"] = newTurbineFlowRate | |
| 1424 | -- Save updated Turbine Flow Rate | |
| 1425 | turbineFlowRate = newTurbineFlowRate | |
| 1426 | config.save(turbineNames[turbineIndex]..".options", _G[turbineNames[turbineIndex]]) | |
| 1427 | elseif (xClick == 29) and (yClick == 4) and (sideClick == monitorNames[monitorIndex]) then | |
| 1428 | printLog("Increase to Flow Rate requested by "..progName.." GUI in displayTurbineBars(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").")
| |
| 1429 | --Increase rod level by amount | |
| 1430 | newTurbineFlowRate = turbineFlowRate + flowRateAdjustAmount | |
| 1431 | if newTurbineFlowRate > 2000 then | |
| 1432 | newTurbineFlowRate = 2000 | |
| 1433 | end | |
| 1434 | sideClick, xClick, yClick = 0, 0, 0 | |
| 1435 | ||
| 1436 | -- Check bounds [0,2000] | |
| 1437 | if newTurbineFlowRate > 2000 then | |
| 1438 | newTurbineFlowRate = 2000 | |
| 1439 | elseif newTurbineFlowRate < 0 then | |
| 1440 | newTurbineFlowRate = 25 -- Don't go to zero, might as well power off | |
| 1441 | end | |
| 1442 | ||
| 1443 | turbine.setFluidFlowRateMax(newTurbineFlowRate) | |
| 1444 | ||
| 1445 | -- Save updated Turbine Flow Rate | |
| 1446 | turbineFlowRate = math.ceil(newTurbineFlowRate) | |
| 1447 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["LastFlow"] = turbineFlowRate | |
| 1448 | config.save(turbineNames[turbineIndex]..".options", _G[turbineNames[turbineIndex]]) | |
| 1449 | else | |
| 1450 | printLog("No change to Flow Rate requested by "..progName.." GUI in displayTurbineBars(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").")
| |
| 1451 | end -- if (xClick == 29) and (yClick == 4) and (sideClick == monitorNames[monitorIndex]) then | |
| 1452 | ||
| 1453 | if (xClick == 22) and (yClick == 6) and (sideClick == monitorNames[monitorIndex]) then | |
| 1454 | printLog("Decrease to Turbine RPM requested by "..progName.." GUI in displayTurbineBars(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").")
| |
| 1455 | rpmRateAdjustment = 909 | |
| 1456 | newTurbineBaseSpeed = turbineBaseSpeed - rpmRateAdjustment | |
| 1457 | if newTurbineBaseSpeed < 908 then | |
| 1458 | newTurbineBaseSpeed = 908 | |
| 1459 | end | |
| 1460 | sideClick, xClick, yClick = 0, 0, 0 | |
| 1461 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["BaseSpeed"] = newTurbineBaseSpeed | |
| 1462 | config.save(turbineNames[turbineIndex]..".options", _G[turbineNames[turbineIndex]]) | |
| 1463 | elseif (xClick == 29) and (yClick == 6) and (sideClick == monitorNames[monitorIndex]) then | |
| 1464 | printLog("Increase to Turbine RPM requested by "..progName.." GUI in displayTurbineBars(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").")
| |
| 1465 | rpmRateAdjustment = 909 | |
| 1466 | newTurbineBaseSpeed = turbineBaseSpeed + rpmRateAdjustment | |
| 1467 | if newTurbineBaseSpeed > 2726 then | |
| 1468 | newTurbineBaseSpeed = 2726 | |
| 1469 | end | |
| 1470 | sideClick, xClick, yClick = 0, 0, 0 | |
| 1471 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["BaseSpeed"] = newTurbineBaseSpeed | |
| 1472 | config.save(turbineNames[turbineIndex]..".options", _G[turbineNames[turbineIndex]]) | |
| 1473 | else | |
| 1474 | printLog("No change to Turbine RPM requested by "..progName.." GUI in displayTurbineBars(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").")
| |
| 1475 | end -- if (xClick == 29) and (yClick == 4) and (sideClick == monitorNames[monitorIndex]) then | |
| 1476 | print{" mB/t",22,3,monitorIndex}
| |
| 1477 | print{"< >",22,4,monitorIndex}
| |
| 1478 | print{stringTrim(turbineFlowRate),24,4,monitorIndex}
| |
| 1479 | print{" RPM",22,5,monitorIndex}
| |
| 1480 | print{"< >",22,6,monitorIndex}
| |
| 1481 | print{stringTrim(tonumber(_G[turbineNames[turbineIndex]]["TurbineOptions"]["BaseSpeed"])),24,6,monitorIndex}
| |
| 1482 | local rotorSpeedString = "Speed: " | |
| 1483 | local energyBufferString = "Energy: " | |
| 1484 | local padding = math.max(string.len(rotorSpeedString), string.len(energyBufferString)) | |
| 1485 | ||
| 1486 | local energyBuffer = turbine.getEnergyProducedLastTick() | |
| 1487 | print{energyBufferString,1,4,monitorIndex}
| |
| 1488 | print{math.ceil(energyBuffer).." RF/t",padding+1,4,monitorIndex}
| |
| 1489 | ||
| 1490 | local rotorSpeed = math.ceil(turbine.getRotorSpeed()) | |
| 1491 | print{rotorSpeedString,1,5,monitorIndex}
| |
| 1492 | print{rotorSpeed.." RPM",padding+1,5,monitorIndex}
| |
| 1493 | ||
| 1494 | -- PaintUtils only outputs to term., not monitor. | |
| 1495 | -- See http://www.computercraft.info/forums2/index.php?/topic/15540-paintutils-on-a-monitor/ | |
| 1496 | ||
| 1497 | -- Draw stored energy buffer bar | |
| 1498 | drawBar(1,9,28,9,colors.gray,monitorIndex) | |
| 1499 | ||
| 1500 | local curStoredEnergyPercent = getTurbineStoredEnergyBufferPercent(turbine) | |
| 1501 | if curStoredEnergyPercent > 4 then | |
| 1502 | drawBar(1, 9, math.floor(26*curStoredEnergyPercent/100)+2, 9, colors.yellow,monitorIndex) | |
| 1503 | elseif curStoredEnergyPercent > 0 then | |
| 1504 | drawPixel(1, 9, colors.yellow, monitorIndex) | |
| 1505 | end -- if curStoredEnergyPercent > 4 then | |
| 1506 | ||
| 1507 | print{"Energy Buffer",1,8,monitorIndex}
| |
| 1508 | print{curStoredEnergyPercent, width-(string.len(curStoredEnergyPercent)+2),8,monitorIndex}
| |
| 1509 | print{"%",28,8,monitorIndex}
| |
| 1510 | ||
| 1511 | -- Print rod override status | |
| 1512 | local turbineFlowRateOverrideStatus = "" | |
| 1513 | ||
| 1514 | print{"Flow Auto-adjust:",2,10,monitorIndex}
| |
| 1515 | ||
| 1516 | if ((not _G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"]) or (_G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"] == "false")) then | |
| 1517 | turbineFlowRateOverrideStatus = "Enabled" | |
| 1518 | monitor.setTextColor(colors.green) | |
| 1519 | else | |
| 1520 | turbineFlowRateOverrideStatus = "Disabled" | |
| 1521 | monitor.setTextColor(colors.red) | |
| 1522 | end -- if not reactorRodOverride then | |
| 1523 | ||
| 1524 | print{turbineFlowRateOverrideStatus, width - string.len(turbineFlowRateOverrideStatus) - 1, 10, monitorIndex}
| |
| 1525 | monitor.setTextColor(colors.white) | |
| 1526 | ||
| 1527 | monitor.setTextColor(colors.blue) | |
| 1528 | printCentered(_G[turbineNames[turbineIndex]]["TurbineOptions"]["turbineName"],12,monitorIndex) | |
| 1529 | monitor.setTextColor(colors.white) | |
| 1530 | ||
| 1531 | -- Need equation to figure out rotor efficiency and display | |
| 1532 | end -- function displayTurbineBars(statusParams) | |
| 1533 | ||
| 1534 | ||
| 1535 | -- Display turbine status | |
| 1536 | local function turbineStatus(turbineIndex, monitorIndex) | |
| 1537 | -- Grab current monitor | |
| 1538 | local monitor = nil | |
| 1539 | ||
| 1540 | printLog("Called as turbineStatus(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").")
| |
| 1541 | - | local localControlRodAdjustAmount = _G[reactorNames[reactorIndex]]["ReactorOptions"]["controlRodAdjustAmount"] |
| 1541 | + | |
| 1542 | monitor = monitorList[monitorIndex] | |
| 1543 | if not monitor then | |
| 1544 | printLog("monitor["..monitorIndex.."] in turbineStatus(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..") is NOT a valid monitor.")
| |
| 1545 | return -- Invalid monitorIndex | |
| 1546 | end | |
| 1547 | ||
| 1548 | -- Grab current turbine | |
| 1549 | - | if (rodPercentage + (10 * localControlRodAdjustAmount)) > 99 then |
| 1549 | + | |
| 1550 | turbine = turbineList[turbineIndex] | |
| 1551 | if not turbine then | |
| 1552 | - | reactor.setAllControlRodLevels(rodPercentage + (10 * localControlRodAdjustAmount)) |
| 1552 | + | |
| 1553 | return -- Invalid turbineIndex | |
| 1554 | else | |
| 1555 | printLog("turbine["..turbineIndex.."] in turbineStatus(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..") is a valid Big Turbine.")
| |
| 1556 | end | |
| 1557 | ||
| 1558 | - | _G[reactorNames[reactorIndex]]["ReactorOptions"]["controlRodAdjustAmount"] = diffAmount |
| 1558 | + | |
| 1559 | - | if (rodPercentage + diffAmount) > 99 then |
| 1559 | + | |
| 1560 | ||
| 1561 | if turbine.getConnected() then | |
| 1562 | - | reactor.setAllControlRodLevels(rodPercentage + diffAmount) |
| 1562 | + | |
| 1563 | if turbine.getActive() then | |
| 1564 | turbineStatus = "ONLINE" | |
| 1565 | - | elseif ((lastTempPoll - reactorTemp) < (reactorTemp * 0.005)) then |
| 1565 | + | |
| 1566 | else | |
| 1567 | turbineStatus = "OFFLINE" | |
| 1568 | monitor.setTextColor(colors.red) | |
| 1569 | end -- if turbine.getActive() then | |
| 1570 | ||
| 1571 | if (xClick >= (width - string.len(turbineStatus) - 1)) and (xClick <= (width-1)) and (sideClick == monitorNames[monitorIndex]) then | |
| 1572 | if yClick == 1 then | |
| 1573 | turbine.setActive(not turbine.getActive()) -- Toggle turbine status | |
| 1574 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["autoStart"] = turbine.getActive() | |
| 1575 | config.save(turbineNames[turbineIndex]..".options", _G[turbineNames[turbineIndex]]) | |
| 1576 | - | elseif ((reactorTemp < localMinReactorTemp) and (rodPercentage ~=0)) or (steamRequested - steamDelivered > 0) then |
| 1576 | + | sideClick, xClick, yClick = 0, 0, 0 -- Reset click after we register it |
| 1577 | end -- if yClick == 1 then | |
| 1578 | - | if (steamRequested > (steamDelivered*2)) then |
| 1578 | + | end -- if (xClick >= (width - string.len(turbineStatus) - 1)) and (xClick <= (width-1)) and (sideClick == monitorNames[monitorIndex]) then |
| 1579 | - | -- Bridge to machine room: Full steam ahead! |
| 1579 | + | |
| 1580 | - | reactor.setAllControlRodLevels(0) |
| 1580 | + | -- Allow disabling/enabling flow rate auto-adjust |
| 1581 | - | elseif (reactorTemp < lastTempPoll) then |
| 1581 | + | if (xClick > 23 and xClick < 28 and yClick == 4) and (sideClick == monitorNames[monitorIndex]) then |
| 1582 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"] = true | |
| 1583 | sideClick, xClick, yClick = 0, 0, 0 -- Reset click after we register it | |
| 1584 | elseif (xClick > 20 and xClick < 27 and yClick == 10) and (sideClick == monitorNames[monitorIndex]) then | |
| 1585 | - | if (rodPercentage - (10 * localControlRodAdjustAmount)) < 0 then |
| 1585 | + | |
| 1586 | if ((_G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"]) or (_G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"] == "true")) then | |
| 1587 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"] = false | |
| 1588 | - | reactor.setAllControlRodLevels(rodPercentage - (10 * localControlRodAdjustAmount)) |
| 1588 | + | |
| 1589 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"] = true | |
| 1590 | end | |
| 1591 | sideClick, xClick, yClick = 0, 0, 0 -- Reset click after we register it | |
| 1592 | end | |
| 1593 | config.save(turbineNames[turbineIndex]..".options", _G[turbineNames[turbineIndex]]) | |
| 1594 | - | _G[reactorNames[reactorIndex]]["ReactorOptions"]["controlRodAdjustAmount"] = diffAmount |
| 1594 | + | |
| 1595 | - | if (rodPercentage - diffAmount) < 0 then |
| 1595 | + | |
| 1596 | printLog("turbine["..turbineIndex.."] in turbineStatus(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..") is NOT connected.")
| |
| 1597 | turbineStatus = "DISCONNECTED" | |
| 1598 | - | reactor.setAllControlRodLevels(rodPercentage - diffAmount) |
| 1598 | + | |
| 1599 | end -- if turbine.getConnected() then | |
| 1600 | ||
| 1601 | print{turbineStatus, width - string.len(turbineStatus) - 1, 1, monitorIndex}
| |
| 1602 | monitor.setTextColor(colors.white) | |
| 1603 | end -- function function turbineStatus(turbineIndex, monitorIndex) | |
| 1604 | ||
| 1605 | ||
| 1606 | -- Maintain Turbine flow rate at 900 or 1,800 RPM | |
| 1607 | local function flowRateControl(turbineIndex) | |
| 1608 | if ((not _G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"]) or (_G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"] == "false")) then | |
| 1609 | ||
| 1610 | printLog("Called as flowRateControl(turbineIndex="..turbineIndex..").")
| |
| 1611 | ||
| 1612 | -- Grab current turbine | |
| 1613 | local turbine = nil | |
| 1614 | - | if ((reactorTemp > localMinReactorTemp) and (reactorTemp < localMaxReactorTemp)) and not (steamRequested - steamDelivered > 0) then |
| 1614 | + | |
| 1615 | ||
| 1616 | -- assign for the duration of this run | |
| 1617 | local lastTurbineSpeed = tonumber(_G[turbineNames[turbineIndex]]["TurbineOptions"]["LastSpeed"]) | |
| 1618 | local turbineBaseSpeed = tonumber(_G[turbineNames[turbineIndex]]["TurbineOptions"]["BaseSpeed"]) | |
| 1619 | ||
| 1620 | if not turbine then | |
| 1621 | printLog("turbine["..turbineIndex.."] in flowRateControl(turbineIndex="..turbineIndex..") is NOT a valid Big Turbine.")
| |
| 1622 | return -- Invalid turbineIndex | |
| 1623 | else | |
| 1624 | printLog("turbine["..turbineIndex.."] in flowRateControl(turbineIndex="..turbineIndex..") is a valid Big Turbine.")
| |
| 1625 | ||
| 1626 | if turbine.getConnected() then | |
| 1627 | printLog("turbine["..turbineIndex.."] in flowRateControl(turbineIndex="..turbineIndex..") is connected.")
| |
| 1628 | else | |
| 1629 | printLog("turbine["..turbineIndex.."] in flowRateControl(turbineIndex="..turbineIndex..") is NOT connected.")
| |
| 1630 | end -- if turbine.getConnected() then | |
| 1631 | end -- if not turbine then | |
| 1632 | ||
| 1633 | -- No point modifying control rod levels for temperature if the turbine is offline | |
| 1634 | if turbine.getActive() then | |
| 1635 | printLog("turbine["..turbineIndex.."] in flowRateControl(turbineIndex="..turbineIndex..") is active.")
| |
| 1636 | ||
| 1637 | local flowRate = tonumber(_G[turbineNames[turbineIndex]]["TurbineOptions"]["LastFlow"]) | |
| 1638 | local flowRateUserMax = math.ceil(turbine.getFluidFlowRateMax()) | |
| 1639 | local rotorSpeed = math.ceil(turbine.getRotorSpeed()) | |
| 1640 | local newFlowRate = 0 | |
| 1641 | ||
| 1642 | -- Going to control the turbine based on target RPM since changing the target flow rate bypasses this function | |
| 1643 | if (rotorSpeed < turbineBaseSpeed) then | |
| 1644 | printLog("BELOW COMMANDED SPEED")
| |
| 1645 | if (rotorSpeed > lastTurbineSpeed) then | |
| 1646 | --we're still increasing, let's let it level off | |
| 1647 | --also lets the first control pass go by on startup | |
| 1648 | elseif (rotorSpeed < lastTurbineSpeed) then | |
| 1649 | --we're decreasing where we should be increasing, do something | |
| 1650 | if ((lastTurbineSpeed - rotorSpeed) > 100) then | |
| 1651 | --kick it harder | |
| 1652 | newFlowRate = 2000 | |
| 1653 | printLog("HARD KICK")
| |
| 1654 | else | |
| 1655 | --let's adjust based on proximity | |
| 1656 | flowAdjustment = (turbineBaseSpeed - rotorSpeed)/5 | |
| 1657 | newFlowRate = flowRate + flowAdjustment | |
| 1658 | printLog("Light Kick: new flow rate is "..newFlowRate.." mB/t and flowAdjustment was "..flowAdjustment.." EOL")
| |
| 1659 | end | |
| 1660 | else | |
| 1661 | --we've stagnated, kick it. | |
| 1662 | flowAdjustment = (turbineBaseSpeed - lastTurbineSpeed) | |
| 1663 | newFlowRate = flowRate + flowAdjustment | |
| 1664 | printLog("Stagnated: new flow rate is "..newFlowRate.." mB/t and flowAdjustment was "..flowAdjustment.." EOL")
| |
| 1665 | end --if (rotorSpeed > lastTurbineSpeed) then | |
| 1666 | else | |
| 1667 | --we're above commanded turbine speed | |
| 1668 | printLog("ABOVE COMMANDED SPEED")
| |
| 1669 | if (rotorSpeed < lastTurbineSpeed) then | |
| 1670 | --we're decreasing, let it level off | |
| 1671 | --also bypasses first control pass on startup | |
| 1672 | elseif (rotorSpeed > lastTurbineSpeed) then | |
| 1673 | --we're above and ascending. | |
| 1674 | if ((rotorSpeed - lastTurbineSpeed) > 100) then | |
| 1675 | --halt | |
| 1676 | newFlowRate = 25 | |
| 1677 | else | |
| 1678 | --let's adjust based on proximity | |
| 1679 | flowAdjustment = (rotorSpeed - turbineBaseSpeed)/5 | |
| 1680 | newFlowRate = flowRate - flowAdjustment | |
| 1681 | printLog("Light Kick: new flow rate is "..newFlowRate.." mB/t and flowAdjustment was "..flowAdjustment.." EOL")
| |
| 1682 | end | |
| 1683 | else | |
| 1684 | --we've stagnated, kick it. | |
| 1685 | flowAdjustment = (lastTurbineSpeed - turbineBaseSpeed) | |
| 1686 | newFlowRate = flowRate - flowAdjustment | |
| 1687 | printLog("Stagnated: new flow rate is "..newFlowRate.." mB/t and flowAdjustment was "..flowAdjustment.." EOL")
| |
| 1688 | end --if (rotorSpeed < lastTurbineSpeed) then | |
| 1689 | end --if (rotorSpeed < turbineBaseSpeed) | |
| 1690 | ||
| 1691 | --check to make sure an adjustment was made | |
| 1692 | if (newFlowRate == 0) then | |
| 1693 | --do nothing, we didn't ask for anything this pass | |
| 1694 | else | |
| 1695 | --boundary check | |
| 1696 | if newFlowRate > 2000 then | |
| 1697 | newFlowRate = 2000 | |
| 1698 | elseif newFlowRate < 25 then | |
| 1699 | newFlowRate = 25 -- Don't go to zero, might as well power off | |
| 1700 | end -- if newFlowRate > 2000 then | |
| 1701 | --no sense running an adjustment if it's not necessary | |
| 1702 | if ((newFlowRate < flowRate) or (newFlowRate > flowRate)) then | |
| 1703 | printLog("turbine["..turbineIndex.."] in flowRateControl(turbineIndex="..turbineIndex..") is being commanded to "..newFlowRate.." mB/t flow")
| |
| 1704 | newFlowRate = round(newFlowRate, 0) | |
| 1705 | turbine.setFluidFlowRateMax(newFlowRate) | |
| 1706 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["LastFlow"] = newFlowRate | |
| 1707 | config.save(turbineNames[turbineIndex]..".options", _G[turbineNames[turbineIndex]]) | |
| 1708 | end | |
| 1709 | end | |
| 1710 | --always set this | |
| 1711 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["LastSpeed"] = rotorSpeed | |
| 1712 | config.save(turbineNames[turbineIndex]..".options", _G[turbineNames[turbineIndex]]) | |
| 1713 | else | |
| 1714 | printLog("turbine["..turbineIndex.."] in flowRateControl(turbineIndex="..turbineIndex..") is NOT active.")
| |
| 1715 | end -- if turbine.getActive() then | |
| 1716 | else | |
| 1717 | printLog("turbine["..turbineIndex.."] has flow override set to "..tostring(_G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"])..", bypassing flow control.")
| |
| 1718 | end -- if not _G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"] then | |
| 1719 | end -- function flowRateControl(turbineIndex) | |
| 1720 | ||
| 1721 | ||
| 1722 | - | monitor.setCursorPos(1, height) |
| 1722 | + | |
| 1723 | - | monitor.write("< ")
|
| 1723 | + | |
| 1724 | - | monitor.setCursorPos(width-1, height) |
| 1724 | + | |
| 1725 | - | monitor.write(" >")
|
| 1725 | + | |
| 1726 | -- Get our initial list of connected monitors and reactors | |
| 1727 | -- and initialize every cycle in case the connected devices change | |
| 1728 | findMonitors() | |
| 1729 | findReactors() | |
| 1730 | findTurbines() | |
| 1731 | ||
| 1732 | while not finished do | |
| 1733 | local reactor = nil | |
| 1734 | local monitorIndex = 1 | |
| 1735 | ||
| 1736 | -- For multiple reactors/monitors, monitor #1 is reserved for overall status | |
| 1737 | -- or for multiple reactors/turbines and only one monitor | |
| 1738 | if ( ( ((#reactorList + #turbineList) > 1) and (#monitorList >= 1) ) or | |
| 1739 | ( ((#reactorList + #turbineList) >=1) and (#monitorList > 1) ) ) then | |
| 1740 | local monitor = nil | |
| 1741 | monitor = monitorList[monitorIndex] | |
| 1742 | if not monitor then | |
| 1743 | printLog("monitor["..monitorIndex.."] in main() is NOT a valid monitor.")
| |
| 1744 | return -- Invalid monitorIndex | |
| 1745 | end | |
| 1746 | ||
| 1747 | clearMonitor(progName.." "..progVer, monitorIndex) -- Clear monitor and draw borders | |
| 1748 | printCentered(progName.." "..progVer, 1, monitorIndex) | |
| 1749 | displayAllStatus() | |
| 1750 | monitorIndex = 2 -- Next monitor, #1 is reserved for overall status | |
| 1751 | end | |
| 1752 | ||
| 1753 | -- Iterate through reactors, continue to run even if not enough monitors are connected | |
| 1754 | for reactorIndex = 1, #reactorList do | |
| 1755 | local monitor = nil | |
| 1756 | local reactorMonitorIndex = monitorIndex + reactorIndex - 1 -- reactorIndex starts at 1 | |
| 1757 | ||
| 1758 | printLog("Attempting to display reactor["..reactorIndex.."] on monitor["..reactorMonitorIndex.."]...")
| |
| 1759 | ||
| 1760 | reactor = reactorList[reactorIndex] | |
| 1761 | if not reactor then | |
| 1762 | printLog("reactor["..reactorIndex.."] in main() is NOT a valid Big Reactor.")
| |
| 1763 | break -- Invalid reactorIndex | |
| 1764 | else | |
| 1765 | printLog("reactor["..reactorIndex.."] in main() is a valid Big Reactor.")
| |
| 1766 | end -- if not reactor then | |
| 1767 | ||
| 1768 | -- Only attempt to assign a monitor if we have a monitor for this reactor | |
| 1769 | if (reactorMonitorIndex <= #monitorList) then | |
| 1770 | printLog("Displaying reactor["..reactorIndex.."] on monitor["..reactorMonitorIndex.."].")
| |
| 1771 | monitor = monitorList[reactorMonitorIndex] | |
| 1772 | ||
| 1773 | if not monitor then | |
| 1774 | printLog("monitor["..reactorMonitorIndex.."] in main() is NOT a valid monitor.")
| |
| 1775 | else | |
| 1776 | clearMonitor(progName, reactorMonitorIndex) -- Clear monitor and draw borders | |
| 1777 | printCentered(progName, 1, reactorMonitorIndex) | |
| 1778 | ||
| 1779 | -- Display reactor status, includes "Disconnected" but found reactors | |
| 1780 | reactorStatus{reactorIndex, reactorMonitorIndex}
| |
| 1781 | ||
| 1782 | -- Draw the borders and bars for the current reactor on the current monitor | |
| 1783 | displayReactorBars{reactorIndex, reactorMonitorIndex}
| |
| 1784 | end -- if not monitor | |
| 1785 | else | |
| 1786 | printLog("You may want "..(#reactorList + #turbineList + 1).." monitors for your "..#reactorList.." connected reactors and "..#turbineList.." connected turbines.")
| |
| 1787 | end -- if (#monitorList ~= 1) and (reactorMonitorIndex < #monitorList) then | |
| 1788 | ||
| 1789 | if reactor.getConnected() then | |
| 1790 | printLog("reactor["..reactorIndex.."] is connected.")
| |
| 1791 | local curStoredEnergyPercent = getReactorStoredEnergyBufferPercent(reactor) | |
| 1792 | ||
| 1793 | -- Shutdown reactor if current stored energy % is >= desired level, otherwise activate | |
| 1794 | -- First pass will have curStoredEnergyPercent=0 until displayBars() is run once | |
| 1795 | if curStoredEnergyPercent >= maxStoredEnergyPercent then | |
| 1796 | reactor.setActive(false) | |
| 1797 | -- Do not auto-start the reactor if it was manually powered off (autoStart=false) | |
| 1798 | elseif (curStoredEnergyPercent <= minStoredEnergyPercent) and (_G[reactorNames[reactorIndex]]["ReactorOptions"]["autoStart"] == true) then | |
| 1799 | reactor.setActive(true) | |
| 1800 | end -- if curStoredEnergyPercent >= maxStoredEnergyPercent then | |
| 1801 | ||
| 1802 | -- Don't try to auto-adjust control rods if manual control is requested | |
| 1803 | if not _G[reactorNames[reactorIndex]]["ReactorOptions"]["rodOverride"] then | |
| 1804 | temperatureControl(reactorIndex) | |
| 1805 | end -- if not reactorRodOverride then | |
| 1806 | else | |
| 1807 | printLog("reactor["..reactorIndex.."] is NOT connected.")
| |
| 1808 | end -- if reactor.getConnected() then | |
| 1809 | end -- for reactorIndex = 1, #reactorList do | |
| 1810 | ||
| 1811 | -- Monitors for turbines start after turbineMonitorOffset | |
| 1812 | for turbineIndex = 1, #turbineList do | |
| 1813 | local monitor = nil | |
| 1814 | local turbineMonitorIndex = turbineIndex + turbineMonitorOffset | |
| 1815 | ||
| 1816 | printLog("Attempting to display turbine["..turbineIndex.."] on monitor["..turbineMonitorIndex.."]...")
| |
| 1817 | - | -- monitor switch controls |
| 1817 | + | |
| 1818 | - | monitor.setCursorPos(1, height) |
| 1818 | + | -- Only attempt to assign a monitor if we found a monitor for this turbine |
| 1819 | - | monitor.write("<")
|
| 1819 | + | if (turbineMonitorIndex <= #monitorList) then |
| 1820 | - | monitor.setCursorPos(width, height) |
| 1820 | + | printLog("Displaying turbine["..turbineIndex.."] on monitor["..turbineMonitorIndex.."].")
|
| 1821 | - | monitor.write(">")
|
| 1821 | + | monitor = monitorList[turbineMonitorIndex] |
| 1822 | if not monitor then | |
| 1823 | printLog("monitor["..turbineMonitorIndex.."] in main() is NOT a valid monitor.")
| |
| 1824 | else | |
| 1825 | clearMonitor(progName, turbineMonitorIndex) -- Clear monitor and draw borders | |
| 1826 | printCentered(progName, 1, turbineMonitorIndex) | |
| 1827 | ||
| 1828 | -- Display turbine status, includes "Disconnected" but found turbines | |
| 1829 | turbineStatus(turbineIndex, turbineMonitorIndex) | |
| 1830 | ||
| 1831 | -- Draw the borders and bars for the current turbine on the current monitor | |
| 1832 | displayTurbineBars(turbineIndex, turbineMonitorIndex) | |
| 1833 | end -- if not monitor | |
| 1834 | else | |
| 1835 | printLog("You may want "..(#reactorList + #turbineList + 1).." monitors for your "..#reactorList.." connected reactors and "..#turbineList.." connected turbines.")
| |
| 1836 | end -- if (#monitorList ~= 1) and (turbineMonitorIndex < #monitorList) then | |
| 1837 | ||
| 1838 | turbine = turbineList[turbineIndex] | |
| 1839 | if not turbine then | |
| 1840 | printLog("turbine["..turbineIndex.."] in main() is NOT a valid Big Turbine.")
| |
| 1841 | break -- Invalid turbineIndex | |
| 1842 | else | |
| 1843 | printLog("turbine["..turbineIndex.."] in main() is a valid Big Turbine.")
| |
| 1844 | end -- if not turbine then | |
| 1845 | ||
| 1846 | if turbine.getConnected() then | |
| 1847 | printLog("turbine["..turbineIndex.."] is connected.")
| |
| 1848 | ||
| 1849 | if not _G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"] then | |
| 1850 | flowRateControl(turbineIndex) | |
| 1851 | end -- if not turbineFlowRateOverride[turbineIndex] then | |
| 1852 | else | |
| 1853 | printLog("turbine["..turbineIndex.."] is NOT connected.")
| |
| 1854 | end -- if turbine.getConnected() then | |
| 1855 | end -- for reactorIndex = 1, #reactorList do | |
| 1856 | ||
| 1857 | sleep(loopTime) -- Sleep | |
| 1858 | saveReactorOptions() | |
| 1859 | end -- while not finished do | |
| 1860 | end -- main() | |
| 1861 | ||
| 1862 | ||
| 1863 | local function eventHandler() | |
| 1864 | while not finished do | |
| 1865 | -- http://computercraft.info/wiki/Os.pullEvent | |
| 1866 | -- http://www.computercraft.info/forums2/index.php?/topic/1516-ospullevent-what-is-it-and-how-is-it-useful/ | |
| 1867 | event, arg1, arg2, arg3 = os.pullEvent() | |
| 1868 | ||
| 1869 | if event == "monitor_touch" then | |
| 1870 | sideClick, xClick, yClick = arg1, math.floor(arg2), math.floor(arg3) | |
| 1871 | printLog("Side: "..arg1.." Monitor touch X: "..xClick.." Y: "..yClick)
| |
| 1872 | elseif event == "char" and not inManualMode then | |
| 1873 | local ch = string.lower(arg1) | |
| 1874 | if ch == "q" then | |
| 1875 | finished = true | |
| 1876 | elseif ch == "r" then | |
| 1877 | - | _G[reactorNames[reactorIndex]]["ReactorOptions"]["Status"] = reactorStatus |
| 1877 | + | |
| 1878 | os.reboot() | |
| 1879 | end -- if ch == "q" then | |
| 1880 | end -- if event == "monitor_touch" then | |
| 1881 | end -- while not finished do | |
| 1882 | end -- function eventHandler() | |
| 1883 | ||
| 1884 | - | -- Display all found reactors' status to selected monitor |
| 1884 | + | |
| 1885 | while not finished do | |
| 1886 | - | local function displayAllStatus(monitorIndex) |
| 1886 | + | parallel.waitForAny(eventHandler, main) |
| 1887 | sleep(loopTime) | |
| 1888 | end -- while not finished do | |
| 1889 | ||
| 1890 | ||
| 1891 | -- Clear up after an exit | |
| 1892 | term.clear() | |
| 1893 | term.setCursorPos(1,1) |