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) |