SHOW:
|
|
- or go back to the newest paste.
1 | --[[ | |
2 | Program name: Lolmer's EZ-NUKE reactor control system | |
3 | - | Version: v0.3.17 |
3 | + | Version: v0.3.13 |
4 | Programmer: Lolmer | |
5 | - | With reat assistance from @echaet and @thetaphi |
5 | + | Great assistance by Mechaet |
6 | - | Last update: 2015-04-08 |
6 | + | Last update: 2014-09-24 |
7 | Pastebin: http://pastebin.com/fguScPBQ | |
8 | - | GitHub: https://github.com/sandalle/minecraft_bigreactor_control |
8 | + | |
9 | Description: | |
10 | 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 | 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 | To simplify the code and guesswork, I assume the following monitor layout, where each "monitor" listed below is a collection of 3 wide by two high Advanced Monitors: | |
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 | one or more Reactors plus | |
17 | none or more Turbines. | |
18 | 2) One Advanced Monitor for overall status display plus (furthest monitor from computer by cable length) | |
19 | one Advanced Monitor for each connected Reactor plus (subsequent found monitors) | |
20 | one Advanced Monitor for each connected Turbine (last group of monitors found). | |
21 | If you enable debug mode, add one additional Advanced Monitor for #1 or #2. | |
22 | ||
23 | Notes: | |
24 | - | Notes |
24 | + | Only one reactor and one, two, and three turbines have been tested with the above, but IN THEORY any number is supported. |
25 | - | ---------------------------- |
25 | + | Devices are found in the reverse order they are plugged in, so monitor_10 will be found before monitor_9. |
26 | - | - Only one reactor and one, two, and three turbines have been tested with the above, but IN THEORY any number is supported. |
26 | + | Two 15x15x14 Turbines can output 260K RF/t by just one 7^3 (four rods) reactor putting out 4k mB steam. |
27 | - | - Devices are found in the reverse order they are plugged in, so monitor_10 will be found before monitor_9. |
27 | + | |
28 | When using actively cooled reactors with turbines, keep the following in mind: | |
29 | - 1 mB steam carries up to 10RF of potential energy to extract in a turbine. | |
30 | - | - 1 mB steam carries up to 10RF of potential energy to extract in a turbine. |
30 | + | - Actively cooled reactors produce steam, not power. |
31 | - | - Actively cooled reactors produce steam, not power. |
31 | + | - 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 | - | - 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 | + | Features: |
34 | Configurable min/max energy buffer and min/max temperature via ReactorOptions file. | |
35 | - | Features |
35 | + | ReactorOptions is read on start and then current values are saved every program cycle. |
36 | - | ---------------------------- |
36 | + | 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. |
37 | - | - Configurable min/max energy buffer and min/max temperature via ReactorOptions file. |
37 | + | Auto-adjusts control rods per reactor to maintain temperature. |
38 | - | - Disengages coils and minimizes flow for turbines over max energy buffer. |
38 | + | Will display reactor data to all attached monitors of correct dimensions. |
39 | - | - ReactorOptions is read on start and then current values are saved every program cycle. |
39 | + | For multiple monitors, the first monitor (often last plugged in) is the overall status monitor. |
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 | + | For multiple monitors, the first monitor (often last plugged in) is the overall status monitor. |
41 | - | - Auto-adjusts control rods per reactor to maintain temperature. |
41 | + | A new cruise mode from mechaet, ONLINE will be "blue" when active, to keep your actively cooled reactors running smoothly. |
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 | + | GUI Usage: |
44 | - | - For multiple monitors, the first monitor (often last plugged in) is the overall status monitor. |
44 | + | The "<" and ">" buttons, when right-clicked with the mouse, will decrease and increase, respectively, the values assigned to the monitor: |
45 | - | - A new cruise mode from mechaet, ONLINE will be "blue" when active, to keep your actively cooled reactors running smoothly. |
45 | + | "Rod (%)" will lower/raise the Reactor Control Rods for that Reactor |
46 | "mB/t" will lower/raise the Turbine Flow Rate maximum for that Turbine | |
47 | - | GUI Usage |
47 | + | "RPM" will lower/raise the target Turbine RPM for that Turbine |
48 | - | ---------------------------- |
48 | + | Right-clicking between the "<" and ">" (not on them) will disable auto-adjust of that value for attached device. |
49 | - | - Right-clicking between "< * >" of the last row of a monitor alternates the device selection between Reactor, Turbine, and Status output. |
49 | + | Right-clicking on the "Enabled" or "Disabled" text for auto-adjust will do the same. |
50 | - | - Right-clicking "<" and ">" switches between connected devices, starting with the currently selected type, but not limited to them. |
50 | + | Right-clicking on "ONLINE" or "OFFLINE" at the top-right will toggle the state of attached device. |
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 | + | Default values: |
53 | - | - "mB/t" will lower/raise the Turbine Flow Rate maximum for that Turbine |
53 | + | Rod Control: 90% (Let's start off safe and then power up as we can) |
54 | - | - "RPM" will lower/raise the target Turbine RPM for that Turbine |
54 | + | Minimum Energy Buffer: 15% (will power on below this value) |
55 | - | - Right-clicking between the "<" and ">" (not on them) will disable auto-adjust of that value for attached device. |
55 | + | Maximum Energy Buffer: 85% (will power off above this value) |
56 | - | - Right-clicking on the "Enabled" or "Disabled" text for auto-adjust will do the same. |
56 | + | Minimum Passive Cooling Temperature: 950^C (will raise control rods below this value) |
57 | - | - Right-clicking on "ONLINE" or "OFFLINE" at the top-right will toggle the state of attached device. |
57 | + | Maximum Passive Cooling Temperature: 1,400^C (will lower control rods above this value) |
58 | Minimum Active Cooling Temperature: 300^C (will raise the control rods below this value) | |
59 | - | Default values |
59 | + | Maximum Active Cooling Temperature: 420^C (will lower control rods above this value) |
60 | - | ---------------------------- |
60 | + | Optimal Turbine RPM: 900, 1,800, or 2,700 (divisible by 900) |
61 | - | - Rod Control: 90% (Let's start off safe and then power up as we can) |
61 | + | New user-controlled option for target speed of turbines, defaults to 2726RPM, which is high-optimal. |
62 | - | - Minimum Energy Buffer: 15% (will power on below this value) |
62 | + | |
63 | - | - Maximum Energy Buffer: 85% (will power off above this value) |
63 | + | Requirements: |
64 | - | - Minimum Passive Cooling Temperature: 950^C (will raise control rods below this value) |
64 | + | Advanced Monitor size is X: 29, Y: 12 with a 3x2 size |
65 | - | - Maximum Passive Cooling Temperature: 1,400^C (will lower control rods above this value) |
65 | + | Computer or Advanced Computer |
66 | - | - Minimum Active Cooling Temperature: 300^C (will raise the control rods below this value) |
66 | + | Modems (not wireless) connecting each of the Computer to both the Advanced Monitor and Reactor Computer Port. |
67 | - | - Maximum Active Cooling Temperature: 420^C (will lower control rods above this value) |
67 | + | Big Reactors (http://www.big-reactors.com/) 0.3.2A+ |
68 | - | - Optimal Turbine RPM: 900, 1,800, or 2,700 (divisible by 900) |
68 | + | Computercraft (http://computercraft.info/) 1.63+ |
69 | - | - New user-controlled option for target speed of turbines, defaults to 2726RPM, which is high-optimal. |
69 | + | Reset the computer any time number of connected devices change. |
70 | ||
71 | - | Requirements |
71 | + | Resources: |
72 | - | ---------------------------- |
72 | + | This script is available from: |
73 | - | - Advanced Monitor size is X: 29, Y: 12 with a 3x2 size |
73 | + | http://pastebin.com/fguScPBQ |
74 | - | - Computer or Advanced Computer |
74 | + | https://github.com/sandalle/minecraft_bigreactor_control |
75 | - | - Modems (not wireless) connecting each of the Computer to both the Advanced Monitor and Reactor Computer Port. |
75 | + | Start-up script is available from: |
76 | - | - Big Reactors (http://www.big-reactors.com/) 0.3.2A+ |
76 | + | http://pastebin.com/ZTMzRLez |
77 | - | - Computercraft (http://computercraft.info/) 1.58, 1.63+, or 1.73+ |
77 | + | https://github.com/sandalle/minecraft_bigreactor_control |
78 | - | - Reset the computer any time number of connected devices change. |
78 | + | Other reactor control program which I based my program on: |
79 | http://pastebin.com/aMAu4X5J (ScatmanJohn) | |
80 | - | Resources |
80 | + | http://pastebin.com/HjUVNDau (version ScatmanJohn based his on) |
81 | - | ---------------------------- |
81 | + | A simpler Big Reactor control program is available from: |
82 | - | - This script is available from: |
82 | + | http://pastebin.com/7S5xCvgL (IronClaymore only for passively cooled reactors) |
83 | - | - http://pastebin.com/fguScPBQ |
83 | + | |
84 | - | - https://github.com/sandalle/minecraft_bigreactor_control |
84 | + | Reactor Computer Port API: http://wiki.technicpack.net/Reactor_Computer_Port |
85 | Computercraft API: http://computercraft.info/wiki/Category:APIs | |
86 | - | - Start-up script is available from: |
86 | + | Big Reactors Efficiency, Speculation and Questions! http://www.reddit.com/r/feedthebeast/comments/1vzds0/big_reactors_efficiency_speculation_and_questions/ |
87 | - | - http://pastebin.com/ZTMzRLez |
87 | + | Big Reactors API code: https://github.com/erogenousbeef/BigReactors/blob/master/erogenousbeef/bigreactors/common/multiblock/tileentity/TileEntityReactorComputerPort.java |
88 | - | - https://github.com/sandalle/minecraft_bigreactor_control |
88 | + | Big Reactors API: http://big-reactors.com/cc_api.html |
89 | - | - Other reactor control program which I based my program on: |
89 | + | |
90 | - | - http://pastebin.com/aMAu4X5J (ScatmanJohn) |
90 | + | ChangeLog: |
91 | - | - http://pastebin.com/HjUVNDau (version ScatmanJohn based his on) |
91 | + | - 0.3.13 |
92 | - | - A simpler Big Reactor control program is available from: |
92 | + | - Fix one reactor and one monitor incorrectly using status display instead of control display (Issue #35) |
93 | - | - http://pastebin.com/7S5xCvgL (IronClaymore only for passively cooled reactors) |
93 | + | - Fix concatenating a string and boolean, see http://stackoverflow.com/questions/6615572/how-to-format-a-lua-string-with-a-boolean-variable |
94 | - | - Reactor Computer Port API: http://wiki.technicpack.net/Reactor_Computer_Port |
94 | + | - Hopefully fix concatenating string and nul in printLog (Issue #3) |
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 | + | - 0.3.12 |
97 | - | - Big Reactors API code: https://github.com/erogenousbeef/BigReactors/blob/master/erogenousbeef/bigreactors/common/multiblock/tileentity/TileEntityReactorComputerPort.java |
97 | + | - Mechaet's changes: |
98 | - | - Big Reactors API: http://big-reactors.com/cc_api.html |
98 | + | - Redid some typing to correct a bug where the reactors always started with rod control disabled. |
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 | + | - 0.3.11 |
101 | - Mechaet's changes: | |
102 | - | ChangeLog |
102 | + | - Cleaned up global variables list |
103 | - | ============================ |
103 | + | - Added in per-device naming (displays a friendly name on the bottom of the monitor if configured in the device options file) |
104 | - | - 0.3.17 |
104 | + | - Bigger bypasses of control routines when the control has been overridden |
105 | - | - Display how much steam (in mB/t) a Turbine is receiving on that Turbine's monitor. |
105 | + | - Individual config files for turbines and reactors. Persistent between reboots, remembers your last saved settings. |
106 | - | - Set monitor scale before checking size fixing Issue #50. |
106 | + | - Cruise mode override bypass |
107 | - | - Having a monitor is now optional, closing Issue #46. |
107 | + | - Changing flow rate no longer toggles flow rate override on and off. Changing the flow rate clearly indicates intent, so we put the override flag on and leave it there. |
108 | - | - Incorporate steam supply and demand in reactor control thanks to @thetaphi (Nicolas Kratz). |
108 | + | - Changed the rate at which the regular algorithm adjusts reactor rod control rates. Instead of being 1:1 we now move at 1:5 speed because there is a wide loophole where big adjustments can cause a swinging pendulum effect continually missing the target. |
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 | + | - 0.3.10 |
111 | - | - Monitors can be reconfigured via GUI fixes Issue #34 thanks to @thetaphi (Nicolas Kratz). |
111 | + | - Turbine algorithm pass by Mechaet. |
112 | - Updated turbine GUI. | |
113 | - | Prior ChangeLogs are posted at https://github.com/sandalle/minecraft_bigreactor_control/releases |
113 | + | - Fix single monitor (again) for Issue #22. |
114 | ||
115 | - | TODO |
115 | + | - 0.3.9 |
116 | - | ============================ |
116 | + | - Reactor algorithm pass by Mechaet. |
117 | - | See https://github.com/sandalle/minecraft_bigreactor_control/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement :) |
117 | + | - Additional user config options by Mechaet. |
118 | - Fix multiple reactors and none or more turbines with only one status monitor. | |
119 | - Fix monitor scaling after one was used as debug (or in case of other modifications). | |
120 | - Cruise mode implemented, defaults off but is saved between boots. | |
121 | - Fix energy/% displays to match Big Reactors' GUI (Issue #9). | |
122 | - Always write out found devices on computer terminal. | |
123 | - | local progVer = "0.3.17" |
123 | + | - Much improved round() function from mechaet (Issue #14). |
124 | - Refactoring pass/algorithm change on the reactor temperature control. Should now adjust in increments to achieve the desired temperature range quicker and more accurately. | |
125 | - Optimal passive-cooled reactor temperature range changed from 850-900 to 950-1400. | |
126 | - Fix display Issue #15. | |
127 | ||
128 | - 0.3.8 | |
129 | - Update to ComputerCraft 1.6 API (only term.restore() -> term.native() required :)). | |
130 | ||
131 | - 0.3.7 | |
132 | - Fix typo when initializing TurbineNames array. | |
133 | - Fix Issue #1, turbine display is using the Reactor buffer size (10M RF) instead of the Turbine buffer size (1M RF). | |
134 | ||
135 | - 0.3.6 | |
136 | - Fix multi-reactors displaying on the correct monitors (thanks HybridFusion). | |
137 | - Fix rod auto-adjust text position. | |
138 | - Reactors store 10M RF and Turbines store 1M RF in their buffer. | |
139 | - | local monitorAssignments = {} -- Empty array of monitor - "what to display" assignments |
139 | + | - Add more colour to displayAllStatus(). |
140 | - | local monitorOptionFileName = "monitors.options" -- File for saving the monitor assignments |
140 | + | - Sleep for only two seconds instead of five. |
141 | - | local knowlinglyOverride = false -- Issue #39 Allow the user to override safe values, currently only enabled for actively cooled reactor min/max temperature |
141 | + | - Fix getDeviceStoredEnergyBufferPercent() for Reactors storing 10M RF in buffer. |
142 | - | local steamRequested = 0 -- Sum of Turbine Flow Rate in mB |
142 | + | - Keep actively cooled reactors between 0-300^C (non-configurable for now). |
143 | - | local steamDelivered = 0 -- Sum of Active Reactor steam output in mB |
143 | + | |
144 | - 0.3.5 | |
145 | - | -- Log levels |
145 | + | - Do not discover connected devices every loop - nicer on servers. Reset computer anytime number of connected devices change. |
146 | - | local FATAL = 16 |
146 | + | - Fix multi-reactor setups to display the additional reactors on monitors, rather than the last one found. |
147 | - | local ERROR = 8 |
147 | + | - Fix passive reactor display having auto-adjust and energy buffer overwrite each other (removes rod count). |
148 | - | local WARN = 4 |
148 | + | |
149 | - | local INFO = 2 |
149 | + | - 0.3.4 |
150 | - | local DEBUG = 1 |
150 | + | - Fix arithmetic for checking if we have enough monitors for the number of reactors. |
151 | - Turbines are optimal at 900, 1800, *and* 2700 RPM | |
152 | - Increase loop timer from 1 to 5 to be nicer to servers | |
153 | ||
154 | - 0.3.3 | |
155 | - Add Big Reactors Turbine support. | |
156 | - First found monitor (appears to be last connected monitor) is used to display status of all found devices (if more than one valid monitor is found) | |
157 | - Display monitor number on top left of each monitor as "M#" to help find which monitor is which. | |
158 | - Enabling debug will use the last monitor found, if more than one, to print out debug info (also written to file) | |
159 | - Only clear monitors when we're about to use them (e.g. turbine monitors no longer clear, then wait for all reactors to update) | |
160 | - Fix getDeviceStoredEnergyBufferPercent(), was off by a decimal place | |
161 | - Just use first Control Rod level for entire reactor, they are no longer treated individually in BR 0.3 | |
162 | - Allow for one monitor for n number of reactors and m number of turbines | |
163 | - Auto-adjust turbine flow rate by 25 mB to keep rotor speed at 900 or 1,800 RPM. | |
164 | - Clicks on monitors relate to what the monitor is showing (e.g. clicking on reactor 1's display won't modify turbine 1's nor reactor 2's values) | |
165 | - Print monitor name and device (reactor|turbine) name in blue to monitor associated for easier design by users. | |
166 | - Remove version number from monitors to free up space for monitor names. | |
167 | - Add option of right-clicking on "Enabled"/"Disabled" of auto-adjust to toggle it. | |
168 | ||
169 | - 0.3.2 | |
170 | - | local function termRestore() |
170 | + | - Allow for rod control to override (disable) auto-adjust via UI (Rhonyn) |
171 | - | local ccVersion = nil |
171 | + | |
172 | - | ccVersion = os.version() |
172 | + | - 0.3.1 |
173 | - Add fuel consumption per tick to display | |
174 | - | if ccVersion == "CraftOS 1.6" or "CraftOS 1.7" then |
174 | + | |
175 | - | term.redirect(term.native()) |
175 | + | - 0.3.0 |
176 | - | elseif ccVersion == "CraftOS 1.5" then |
176 | + | - Add multi-monitor support! Sends one reactor's data to all monitors. |
177 | - | term.restore() |
177 | + | - print function now takes table to support optional specified monitor |
178 | - | else -- Default to older term.restore |
178 | + | - Set "numRods" every cycle for some people (mechaet) |
179 | - | printLog("Unsupported CraftOS found. Reported version is \""..ccVersion.."\".") |
179 | + | - Don't redirect terminal output with multiple monitor support |
180 | - | term.restore() |
180 | + | - Log troubleshooting data to reactorcontrol.log |
181 | - | end -- if ccVersion |
181 | + | - FC_API no longer used (copied and modified what I needed) |
182 | - | end -- function termRestore() |
182 | + | - Multi-reactor support is theoretically implemented, but it is UNTESTED! |
183 | - Updated for Big Reactor 0.3 (no longer works with 0.2) | |
184 | - | local function printLog(printStr, logLevel) |
184 | + | - BR getFuelTemperature() now returns many significant digits, just use math.ceil() |
185 | - | logLevel = logLevel or INFO |
185 | + | - BR 0.3 removed individual rod temperatures, now it's only reactor-level temperature |
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 | + | - 0.2.4 |
188 | - | if debugMode and (logLevel >= WARN) then |
188 | + | - Simplify math, don't divide by a simple large number and then multiply by 100 (#/10000000*100) |
189 | - | -- If multiple monitors, print to all of them |
189 | + | - Fix direct-connected (no modem) devices. getDeviceSide -> FC_API.getDeviceSide (simple as that :)) |
190 | - | for monitorName, deviceData in pairs(monitorAssignments) do |
190 | + | |
191 | - | if deviceData.type == "Debug" then |
191 | + | - 0.2.3 |
192 | - | debugMonitor = monitorList[deviceData.index] |
192 | + | - Check bounds on reactor.setRodControlLevel(#,#), Big Reactor doesn't check for us. |
193 | - | if(not debugMonitor) or (not debugMonitor.getSize()) then |
193 | + | |
194 | - | term.write("printLog(): debug monitor "..monitorName.." failed") |
194 | + | - 0.2.2 |
195 | - Do not auto-start the reactor if it was manually powered off (autoStart=false) | |
196 | - | term.redirect(debugMonitor) -- Redirect to selected monitor |
196 | + | |
197 | - | debugMonitor.setTextScale(0.5) -- Fit more logs on screen |
197 | + | - 0.2.1 |
198 | - | local color = colors.lightGray |
198 | + | - Lower/raise only the hottest/coldest Control Rod while trying to control the reactor temperature. |
199 | - | if (logLevel == WARN) then |
199 | + | - "<" Rod Control buttons was off by one (to the left) |
200 | - | color = colors.white |
200 | + | |
201 | - | elseif (logLevel == ERROR) then |
201 | + | - 0.2.0 - Lolmer Edition :) |
202 | - | color = colors.red |
202 | + | - Add min/max stored energy percentage (default is 15%/85%), configurable via ReactorOptions file. |
203 | - | elseif (logLevel == FATAL) then |
203 | + | - No reason to keep burning fuel if our power output is going nowhere. :) |
204 | - | color = colors.black |
204 | + | - Use variables variable for the title and version. |
205 | - | debugMonitor.setBackgroundColor(colors.red) |
205 | + | - Try to keep the temperature between configured values (default is 850^C-950^C) |
206 | - Add Waste and number of Control/Fuel Rods to displayBards() | |
207 | - | debugMonitor.setTextColor(color) |
207 | + | |
208 | - | write(printStr.."\n") -- May need to use term.scroll(x) if we output too much, not sure |
208 | + | TODO: |
209 | - | debugMonitor.setBackgroundColor(colors.black) |
209 | + | - Save parameters per reactor instead of one global set for all reactors. |
210 | - | termRestore() |
210 | + | - Add min/max RF/t output and have it override temperature concerns (maybe?). |
211 | - Add support for wireless modems, see http://computercraft.info/wiki/Modem_%28API%29, will not be secure (anyone can send/listen to your channels)! | |
212 | - Add support for any sized monitor (minimum 3x3), dynamic allocation/alignment. | |
213 | - | end -- for |
213 | + | - Lookup using pcall for better error handling http://www.computercraft.info/forums2/index.php?/topic/10992-using-pcall/ . |
214 | - Update cruise mode to work independently for each actively-cooled reactor. | |
215 | ||
216 | ]]-- | |
217 | ||
218 | ||
219 | -- Some global variables | |
220 | local progVer = "0.3.13" | |
221 | local progName = "EZ-NUKE" | |
222 | local sideClick, xClick, yClick = nil, 0, 0 | |
223 | local loopTime = 2 | |
224 | local controlRodAdjustAmount = 1 -- Default Reactor Rod Control % adjustment amount | |
225 | local flowRateAdjustAmount = 25 -- Default Turbine Flow Rate in mB adjustment amount | |
226 | local debugMode = false | |
227 | -- End multi-reactor cleanup section | |
228 | local minStoredEnergyPercent = nil -- Max energy % to store before activate | |
229 | local maxStoredEnergyPercent = nil -- Max energy % to store before shutdown | |
230 | local monitorList = {} -- Empty monitor array | |
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 | + | |
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 | + | local turbineMonitorOffset = 0 -- Turbines are assigned monitors after reactors |
237 | - | local exponent = math.floor(math.log10(num)) |
237 | + | |
238 | - | local group = math.floor(exponent / 3) |
238 | + | |
239 | - | if group > #sizes then |
239 | + | |
240 | - | return string.format("%e", num) |
240 | + | |
241 | write("Initializing program...\n") | |
242 | - | local divisor = math.pow(10, (group - 1) * 3) |
242 | + | |
243 | - | return string.format("%i%s", num / divisor, sizes[group]) |
243 | + | |
244 | -- File needs to exist for append "a" later and zero it out if it already exists | |
245 | - | end -- local function formatReadableSIUnit(num) |
245 | + | |
246 | local logFile = fs.open("reactorcontrol.log", "w") | |
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 | + | |
257 | - | printLog(formatting .. tostring(v), loglevel) |
257 | + | |
258 | local function printLog(printStr) | |
259 | - | printLog(formatting .. v, loglevel) |
259 | + | if debugMode then |
260 | -- If multiple monitors, use the last monitor for debugging if debug is enabled | |
261 | if #monitorList > 1 then | |
262 | - | end -- function tprint() |
262 | + | term.redirect(monitorList[#monitorList]) -- Redirect to last monitor for debugging |
263 | monitorList[#monitorList].setTextScale(0.5) -- Fit more logs on screen | |
264 | write(printStr.."\n") -- May need to use term.scroll(x) if we output too much, not sure | |
265 | term.native() | |
266 | end -- if #monitorList > 1 then | |
267 | ||
268 | local logFile = fs.open("reactorcontrol.log", "a") -- See http://computercraft.info/wiki/Fs.open | |
269 | if logFile then | |
270 | logFile.writeLine(printStr) | |
271 | logFile.close() | |
272 | else | |
273 | error("Cannot open file reactorcontrol.log for appending!") | |
274 | end -- if logFile then | |
275 | end -- if debugMode then | |
276 | end -- function printLog(printStr) | |
277 | ||
278 | -- Trim a string | |
279 | function stringTrim(s) | |
280 | assert(s ~= nil, "String can't be nil") | |
281 | return(string.gsub(s, "^%s*(.-)%s*$", "%1")) | |
282 | end | |
283 | ||
284 | config = {} | |
285 | ||
286 | -- Save a table into a config file | |
287 | -- path: path of the file to write | |
288 | -- tab: table to save | |
289 | config.save = function(path, tab) | |
290 | printLog("Save function called for config for "..path.." EOL") | |
291 | assert(path ~= nil, "Path can't be nil") | |
292 | assert(type(tab) == "table", "Second parameter must be a table") | |
293 | local f = io.open(path, "w") | |
294 | local i = 0 | |
295 | for key, value in pairs(tab) do | |
296 | if i ~= 0 then | |
297 | f:write("\n") | |
298 | end | |
299 | f:write("["..key.."]".."\n") | |
300 | for key2, value2 in pairs(tab[key]) do | |
301 | key2 = stringTrim(key2) | |
302 | --doesn't like boolean values | |
303 | if (type(value2) ~= "boolean") then | |
304 | value2 = stringTrim(value2) | |
305 | else | |
306 | - | printLog("Successfully opened "..path.." for reading EOL") |
306 | + | |
307 | end | |
308 | key2 = key2:gsub(";", "\\;") | |
309 | key2 = key2:gsub("=", "\\=") | |
310 | value2 = value2:gsub(";", "\\;") | |
311 | value2 = value2:gsub("=", "\\=") | |
312 | f:write(key2.."="..value2.."\n") | |
313 | end | |
314 | i = i + 1 | |
315 | end | |
316 | f:close() | |
317 | end --config.save = function(path, tab) | |
318 | ||
319 | -- Load a config file | |
320 | -- path: path of the file to read | |
321 | config.load = function(path) | |
322 | printLog("Load function called for config for "..path.." EOL") | |
323 | assert(path ~= nil, "Path can't be nil") | |
324 | local f = fs.open(path, "r") | |
325 | if f ~= nil then | |
326 | local tab = {} | |
327 | local line = "" | |
328 | local newLine | |
329 | local i | |
330 | local currentTag = nil | |
331 | local found = false | |
332 | local pos = 0 | |
333 | while line ~= nil do | |
334 | found = false | |
335 | line = line:gsub("\\;", "#_!36!_#") -- to keep \; | |
336 | line = line:gsub("\\=", "#_!71!_#") -- to keep \= | |
337 | if line ~= "" then | |
338 | -- Delete comments | |
339 | newLine = line | |
340 | line = "" | |
341 | for i=1, string.len(newLine) do | |
342 | if string.sub(newLine, i, i) ~= ";" then | |
343 | line = line..newLine:sub(i, i) | |
344 | else | |
345 | break | |
346 | end | |
347 | end | |
348 | line = stringTrim(line) | |
349 | -- Find tag | |
350 | if line:sub(1, 1) == "[" and line:sub(line:len(), line:len()) == "]" then | |
351 | currentTag = stringTrim(line:sub(2, line:len()-1)) | |
352 | tab[currentTag] = {} | |
353 | found = true | |
354 | end | |
355 | - | printLog("Could NOT opened "..path.." for reading! EOL") |
355 | + | |
356 | if not found and line ~= "" then | |
357 | pos = line:find("=") | |
358 | if pos == nil then | |
359 | error("Bad INI file structure") | |
360 | end | |
361 | line = line:gsub("#_!36!_#", ";") | |
362 | line = line:gsub("#_!71!_#", "=") | |
363 | tab[currentTag][stringTrim(line:sub(1, pos-1))] = stringTrim(line:sub(pos+1, line:len())) | |
364 | found = true | |
365 | end | |
366 | end | |
367 | line = f.readLine() | |
368 | end | |
369 | ||
370 | f:close() | |
371 | ||
372 | return tab | |
373 | else | |
374 | return nil | |
375 | end | |
376 | end --config.load = function(path) | |
377 | ||
378 | ||
379 | ||
380 | -- round() function from mechaet | |
381 | local function round(num, places) | |
382 | local mult = 10^places | |
383 | local addon = nil | |
384 | if ((num * mult) < 0) then | |
385 | addon = -.5 | |
386 | else | |
387 | addon = .5 | |
388 | end | |
389 | ||
390 | local integer, decimal = math.modf(num*mult+addon) | |
391 | newNum = integer/mult | |
392 | printLog("Called round(num="..num..",places="..places..") returns \""..newNum.."\".") | |
393 | return newNum | |
394 | end -- function round(num, places) | |
395 | ||
396 | ||
397 | local function print(printParams) | |
398 | -- Default to xPos=1, yPos=1, and first monitor | |
399 | setmetatable(printParams,{__index={xPos=1, yPos=1, monitorIndex=1}}) | |
400 | local printString, xPos, yPos, monitorIndex = | |
401 | printParams[1], -- Required parameter | |
402 | printParams[2] or printParams.xPos, | |
403 | printParams[3] or printParams.yPos, | |
404 | printParams[4] or printParams.monitorIndex | |
405 | ||
406 | local monitor = nil | |
407 | - | printLog("monitor["..monitorIndex.."] in printCentered() is NOT a valid monitor.", ERROR) |
407 | + | |
408 | ||
409 | if not monitor then | |
410 | printLog("monitor["..monitorIndex.."] in print() is NOT a valid monitor.") | |
411 | return -- Invalid monitorIndex | |
412 | end | |
413 | ||
414 | monitor.setCursorPos(xPos, yPos) | |
415 | monitor.write(printString) | |
416 | end -- function print(printParams) | |
417 | ||
418 | - | width = width - monitorNameLength -- add a space |
418 | + | |
419 | -- Replaces the one from FC_API (http://pastebin.com/A9hcbZWe) and adding multi-monitor support | |
420 | local function printCentered(printString, yPos, monitorIndex) | |
421 | - | if monitorAssignments[monitorNames[monitorIndex]].type ~= "Status" then |
421 | + | |
422 | monitor = monitorList[monitorIndex] | |
423 | ||
424 | if not monitor then | |
425 | printLog("monitor["..monitorIndex.."] in printCentered() is NOT a valid monitor.") | |
426 | - | monitor.setCursorPos(monitorNameLength + math.ceil((1 + width - printString:len())/2), yPos) |
426 | + | |
427 | end | |
428 | ||
429 | local width, height = monitor.getSize() | |
430 | local monitorNameLength = 0 | |
431 | ||
432 | -- Special changes for title bar | |
433 | if yPos == 1 then | |
434 | -- Add monitor name to first line | |
435 | monitorNameLength = monitorNames[monitorIndex]:len() | |
436 | ||
437 | -- Leave room for "offline" and "online" on the right except for overall status display | |
438 | - | printLog("monitor["..monitorIndex.."] in printLeft() is NOT a valid monitor.", ERROR) |
438 | + | if (#monitorList ~= 1) and (monitorIndex ~= 1) then |
439 | width = width - 7 | |
440 | end | |
441 | end | |
442 | ||
443 | monitor.setCursorPos(math.floor(width/2) - math.ceil(printString:len()/2) + monitorNameLength/2, yPos) | |
444 | monitor.clearLine() | |
445 | monitor.write(printString) | |
446 | ||
447 | monitor.setTextColor(colors.blue) | |
448 | print{monitorNames[monitorIndex], 1, 1, monitorIndex} | |
449 | monitor.setTextColor(colors.white) | |
450 | end -- function printCentered(printString, yPos, monitorIndex) | |
451 | ||
452 | ||
453 | -- Print text padded from the left side | |
454 | -- Clear the left side of the screen | |
455 | local function printLeft(printString, yPos, monitorIndex) | |
456 | local monitor = nil | |
457 | monitor = monitorList[monitorIndex] | |
458 | ||
459 | if not monitor then | |
460 | printLog("monitor["..monitorIndex.."] in printLeft() is NOT a valid monitor.") | |
461 | return -- Invalid monitorIndex | |
462 | end | |
463 | ||
464 | local gap = 1 | |
465 | - | printLog("monitor["..monitorIndex.."] in printRight() is NOT a valid monitor.", ERROR) |
465 | + | |
466 | ||
467 | -- Clear left-half of the monitor | |
468 | ||
469 | for curXPos = 1, (width / 2) do | |
470 | monitor.setCursorPos(curXPos, yPos) | |
471 | monitor.write(" ") | |
472 | end | |
473 | ||
474 | -- Write our string left-aligned | |
475 | monitor.setCursorPos(1+gap, yPos) | |
476 | monitor.write(printString) | |
477 | end | |
478 | ||
479 | ||
480 | -- Print text padded from the right side | |
481 | -- Clear the right side of the screen | |
482 | local function printRight(printString, yPos, monitorIndex) | |
483 | local monitor = nil | |
484 | monitor = monitorList[monitorIndex] | |
485 | ||
486 | if not monitor then | |
487 | printLog("monitor["..monitorIndex.."] in printRight() is NOT a valid monitor.") | |
488 | return -- Invalid monitorIndex | |
489 | end | |
490 | ||
491 | -- Make sure printString is a string | |
492 | printString = tostring(printString) | |
493 | ||
494 | local gap = 1 | |
495 | - | printLog("monitor["..monitorIndex.."] in clearMonitor(printString="..printString..",monitorIndex="..monitorIndex..") is NOT a valid monitor.", ERROR) |
495 | + | |
496 | ||
497 | -- Clear right-half of the monitor | |
498 | for curXPos = (width/2), width do | |
499 | monitor.setCursorPos(curXPos, yPos) | |
500 | monitor.write(" ") | |
501 | end | |
502 | ||
503 | -- Write our string right-aligned | |
504 | monitor.setCursorPos(math.floor(width) - math.ceil(printString:len()+gap), yPos) | |
505 | monitor.write(printString) | |
506 | end | |
507 | ||
508 | ||
509 | -- Replaces the one from FC_API (http://pastebin.com/A9hcbZWe) and adding multi-monitor support | |
510 | local function clearMonitor(printString, monitorIndex) | |
511 | local monitor = nil | |
512 | monitor = monitorList[monitorIndex] | |
513 | ||
514 | printLog("Called as clearMonitor(printString="..printString..",monitorIndex="..monitorIndex..").") | |
515 | ||
516 | if not monitor then | |
517 | printLog("monitor["..monitorIndex.."] in clearMonitor(printString="..printString..",monitorIndex="..monitorIndex..") is NOT a valid monitor.") | |
518 | return -- Invalid monitorIndex | |
519 | end | |
520 | ||
521 | local gap = 2 | |
522 | monitor.clear() | |
523 | local width, height = monitor.getSize() | |
524 | monitor.setTextScale(1.0) -- Make sure scale is correct | |
525 | ||
526 | printCentered(printString, 1, monitorIndex) | |
527 | monitor.setTextColor(colors.blue) | |
528 | print{monitorNames[monitorIndex], 1, 1, monitorIndex} | |
529 | monitor.setTextColor(colors.white) | |
530 | ||
531 | for i=1, width do | |
532 | monitor.setCursorPos(i, gap) | |
533 | monitor.write("-") | |
534 | end | |
535 | ||
536 | monitor.setCursorPos(1, gap+1) | |
537 | end -- function clearMonitor(printString, monitorIndex) | |
538 | ||
539 | ||
540 | -- Return a list of all connected (including via wired modems) devices of "deviceType" | |
541 | local function getDevices(deviceType) | |
542 | printLog("Called as getDevices(deviceType="..deviceType..")") | |
543 | ||
544 | local deviceName = nil | |
545 | local deviceIndex = 1 | |
546 | local deviceList, deviceNames = {}, {} -- Empty array, which grows as we need | |
547 | local peripheralList = peripheral.getNames() -- Get table of connected peripherals | |
548 | ||
549 | deviceType = deviceType:lower() -- Make sure we're matching case here | |
550 | ||
551 | for peripheralIndex = 1, #peripheralList do | |
552 | -- Log every device found | |
553 | -- printLog("Found "..peripheral.getType(peripheralList[peripheralIndex]).."["..peripheralIndex.."] attached as \""..peripheralList[peripheralIndex].."\".") | |
554 | if (string.lower(peripheral.getType(peripheralList[peripheralIndex])) == deviceType) then | |
555 | -- Log devices found which match deviceType and which device index we give them | |
556 | printLog("Found "..peripheral.getType(peripheralList[peripheralIndex]).."["..peripheralIndex.."] as index \"["..deviceIndex.."]\" attached as \""..peripheralList[peripheralIndex].."\".") | |
557 | write("Found "..peripheral.getType(peripheralList[peripheralIndex]).."["..peripheralIndex.."] as index \"["..deviceIndex.."]\" attached as \""..peripheralList[peripheralIndex].."\".\n") | |
558 | deviceNames[deviceIndex] = peripheralList[peripheralIndex] | |
559 | deviceList[deviceIndex] = peripheral.wrap(peripheralList[peripheralIndex]) | |
560 | deviceIndex = deviceIndex + 1 | |
561 | end | |
562 | end -- for peripheralIndex = 1, #peripheralList do | |
563 | ||
564 | return deviceList, deviceNames | |
565 | end -- function getDevices(deviceType) | |
566 | ||
567 | -- Draw a line across the entire x-axis | |
568 | local function drawLine(yPos, monitorIndex) | |
569 | local monitor = nil | |
570 | monitor = monitorList[monitorIndex] | |
571 | ||
572 | if not monitor then | |
573 | printLog("monitor["..monitorIndex.."] in drawLine() is NOT a valid monitor.") | |
574 | return -- Invalid monitorIndex | |
575 | end | |
576 | ||
577 | local width, height = monitor.getSize() | |
578 | - | termRestore() |
578 | + | |
579 | for i=1, width do | |
580 | monitor.setCursorPos(i, yPos) | |
581 | monitor.write("-") | |
582 | end | |
583 | end -- function drawLine(yPos,monitorIndex) | |
584 | ||
585 | ||
586 | -- Display a solid bar of specified color | |
587 | local function drawBar(startXPos, startYPos, endXPos, endYPos, color, monitorIndex) | |
588 | local monitor = nil | |
589 | monitor = monitorList[monitorIndex] | |
590 | ||
591 | if not monitor then | |
592 | printLog("monitor["..monitorIndex.."] in drawBar() is NOT a valid monitor.") | |
593 | return -- Invalid monitorIndex | |
594 | end | |
595 | ||
596 | -- PaintUtils only outputs to term., not monitor. | |
597 | - | termRestore() |
597 | + | |
598 | term.redirect(monitor) | |
599 | paintutils.drawLine(startXPos, startYPos, endXPos, endYPos, color) | |
600 | - | local function saveMonitorAssignments() |
600 | + | |
601 | - | local assignments = {} |
601 | + | term.native() |
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 | monitor = monitorList[monitorIndex] | |
609 | - | name = data.type |
609 | + | |
610 | if not monitor then | |
611 | - | assignments[monitor] = name |
611 | + | |
612 | return -- Invalid monitorIndex | |
613 | - | config.save(monitorOptionFileName, {Monitors = assignments}) |
613 | + | |
614 | ||
615 | -- PaintUtils only outputs to term., not monitor. | |
616 | - | UI = { |
616 | + | |
617 | - | monitorIndex = 1, |
617 | + | |
618 | - | reactorIndex = 1, |
618 | + | |
619 | - | turbineIndex = 1 |
619 | + | |
620 | - | } |
620 | + | term.native() |
621 | end -- function drawPixel(xPos, yPos, color, monitorIndex) | |
622 | - | UI.handlePossibleClick = function(self) |
622 | + | |
623 | - | local monitorData = monitorAssignments[sideClick] |
623 | + | |
624 | - | if monitorData == nil then |
624 | + | |
625 | - | printLog("UI.handlePossibleClick(): "..sideClick.." is unassigned, can't handle click", WARN) |
625 | + | |
626 | - | return |
626 | + | |
627 | -- Then initialize the monitors | |
628 | local function findMonitors() | |
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 | + | printLog("No monitors found!") |
637 | - | self:selectNextReactor() |
637 | + | error("Can't find any monitors!") |
638 | - | elseif (3 <= xClick and xClick <= width - 2) then |
638 | + | |
639 | - | self:selectTurbine() |
639 | + | |
640 | local monitor, monitorX, monitorY = nil, nil, nil | |
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 | monitorIndex = monitorIndex - 1 -- We just removed an element | |
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 | monitorIndex = monitorIndex - 1 -- We just removed an element | |
659 | end -- if monitorIndex == #monitorList then | |
660 | - | self:selectStatus() |
660 | + | |
661 | ||
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 | monitor.clear() | |
666 | printLog("Removing monitor "..monitorIndex.." for being too small.") | |
667 | monitor.setCursorPos(1,2) | |
668 | - | if (monitorData.type == "Turbine") then |
668 | + | |
669 | - | self:handleTurbineMonitorClick(monitorData.turbineIndex, monitorData.index) |
669 | + | |
670 | - | elseif (monitorData.type == "Reactor") then |
670 | + | term.native() |
671 | - | self:handleReactorMonitorClick(monitorData.reactorIndex, monitorData.index) |
671 | + | |
672 | table.remove(monitorList, monitorIndex) -- Remove invalid monitor from list | |
673 | if monitorIndex == #monitorList then -- If we're at the end already, break from loop | |
674 | - | end -- UI.handlePossibleClick() |
674 | + | |
675 | else | |
676 | - | UI.logChange = function(self, messageText) |
676 | + | |
677 | - | printLog("UI: "..messageText) |
677 | + | |
678 | - | termRestore() |
678 | + | |
679 | - | write(messageText.."\n") |
679 | + | |
680 | end -- if not monitor then | |
681 | ||
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 | printLog("Found "..#monitorList.." monitor(s) in findMonitors().") | |
687 | - | local messageText = "Selected monitor "..monitorNames[self.monitorIndex] |
687 | + | |
688 | - | self:logChange(messageText) |
688 | + | |
689 | - | end -- UI.selectNextMonitor() |
689 | + | |
690 | -- Initialize all Big Reactors - Reactors | |
691 | local function findReactors() | |
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 | printLog("No reactors found!") | |
699 | - | UI.selectPrevReactor = function(self) |
699 | + | |
700 | - | if self.reactorIndex <= 1 then |
700 | + | |
701 | - | self.reactorIndex = #reactorList |
701 | + | |
702 | - | self:selectStatus() |
702 | + | |
703 | reactor = newReactorList[reactorIndex] | |
704 | - | self.reactorIndex = self.reactorIndex - 1 |
704 | + | |
705 | - | self:selectReactor() |
705 | + | |
706 | printLog("reactorList["..reactorIndex.."] in findReactors() is NOT a valid Big Reactor.") | |
707 | - | end -- UI.selectPrevReactor() |
707 | + | |
708 | table.remove(newReactorList, reactorIndex) -- Remove invalid reactor from list | |
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 | printLog("reactor["..reactorIndex.."] in findReactors() is a valid Big Reactor.") | |
715 | - | self.reactorIndex = self.reactorIndex + 1 |
715 | + | |
716 | - | self:selectReactor() |
716 | + | |
717 | _G[reactorNames[reactorIndex]]["ReactorOptions"] = {} | |
718 | - | end -- UI.selectNextReactor() |
718 | + | |
719 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["lastTempPoll"] = 0 | |
720 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["autoStart"] = true | |
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 reactor.getConnected() 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 | end | |
734 | - | self.turbineIndex = self.turbineIndex - 1 |
734 | + | |
735 | - | self:selectTurbine() |
735 | + | |
736 | local tempTable = _G[reactorNames[reactorIndex]] | |
737 | - | end -- UI.selectPrevTurbine() |
737 | + | |
738 | --check to make sure we get a valid config | |
739 | - | UI.selectNextTurbine = function(self) |
739 | + | |
740 | - | if self.turbineIndex >= #turbineList then |
740 | + | |
741 | - | self.turbineIndex = 1 |
741 | + | |
742 | - | self:selectStatus() |
742 | + | |
743 | config.save(reactorNames[reactorIndex]..".options", _G[reactorNames[reactorIndex]]) | |
744 | - | self.turbineIndex = self.turbineIndex + 1 |
744 | + | |
745 | - | self:selectTurbine() |
745 | + | |
746 | --load values from tempTable, checking for nil values along the way | |
747 | - | end -- UI.selectNextTurbine() |
747 | + | |
748 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["baseControlRodLevel"] = tempTable["ReactorOptions"]["baseControlRodLevel"] | |
749 | end | |
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 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["autoStart"] = tempTable["ReactorOptions"]["autoStart"] | |
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 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorMaxTemp"] = tempTable["ReactorOptions"]["reactorMaxTemp"] | |
765 | - | -- Allow controlling Reactor Control Rod Level from GUI |
765 | + | |
766 | - | UI.handleReactorMonitorClick = function(self, reactorIndex, monitorIndex) |
766 | + | |
767 | if tempTable["ReactorOptions"]["reactorMinTemp"] ~= nil then | |
768 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorMinTemp"] = tempTable["ReactorOptions"]["reactorMinTemp"] | |
769 | end | |
770 | ||
771 | if tempTable["ReactorOptions"]["rodOverride"] ~= nil then | |
772 | printLog("Got value from config file for Rod Override, the value is: "..tostring(tempTable["ReactorOptions"]["rodOverride"]).." EOL") | |
773 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["rodOverride"] = tempTable["ReactorOptions"]["rodOverride"] | |
774 | end | |
775 | ||
776 | if tempTable["ReactorOptions"]["reactorName"] ~= nil then | |
777 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorName"] = tempTable["ReactorOptions"]["reactorName"] | |
778 | end | |
779 | ||
780 | if tempTable["ReactorOptions"]["reactorCruising"] ~= nil then | |
781 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorCruising"] = tempTable["ReactorOptions"]["reactorCruising"] | |
782 | end | |
783 | - | printLog("reactor["..reactorIndex.."] in handleReactorMonitorClick(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is NOT a valid Big Reactor.") |
783 | + | |
784 | --stricter typing, let's set these puppies up with the right type of value. | |
785 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["baseControlRodLevel"] = tonumber(_G[reactorNames[reactorIndex]]["ReactorOptions"]["baseControlRodLevel"]) | |
786 | - | printLog("reactor["..reactorIndex.."] in handleReactorMonitorClick(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is a valid Big Reactor.") |
786 | + | |
787 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["lastTempPoll"] = tonumber(_G[reactorNames[reactorIndex]]["ReactorOptions"]["lastTempPoll"]) | |
788 | - | printLog("reactor["..reactorIndex.."] in handleReactorMonitorClick(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is connected.") |
788 | + | |
789 | if (tostring(_G[reactorNames[reactorIndex]]["ReactorOptions"]["autoStart"]) == "true") then | |
790 | - | printLog("reactor["..reactorIndex.."] in handleReactorMonitorClick(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is NOT connected.") |
790 | + | |
791 | else | |
792 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["autoStart"] = false | |
793 | end | |
794 | ||
795 | - | local reactorStatus = _G[reactorNames[reactorIndex]]["ReactorOptions"]["Status"] |
795 | + | |
796 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["activeCooled"] = true | |
797 | else | |
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 | ||
803 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorMinTemp"] = tonumber(_G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorMinTemp"]) | |
804 | ||
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 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["rodOverride"] = true | |
808 | else | |
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 | end | |
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 | end | |
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 | config.save(reactorNames[reactorIndex]..".options", _G[reactorNames[reactorIndex]]) | |
821 | end -- for reactorIndex = 1, #newReactorList do | |
822 | - | local newRodPercentage = rodPercentage |
822 | + | |
823 | ||
824 | - | printLog("Decreasing Rod Levels in handleReactorMonitorClick(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").") |
824 | + | |
825 | reactorList = newReactorList | |
826 | ||
827 | -- Start turbine monitor offset after reactors get monitors | |
828 | -- This assumes that there is a monitor for each turbine and reactor, plus the overall monitor display | |
829 | turbineMonitorOffset = #reactorList + 1 -- #turbineList will start at "1" if turbines found and move us just beyond #reactorList and status monitor range | |
830 | ||
831 | printLog("Found "..#reactorList.." reactor(s) in findReactors().") | |
832 | - | printLog("Setting reactor["..reactorIndex.."] Rod Levels to "..newRodPercentage.."% in handleReactorMonitorClick(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").") |
832 | + | printLog("Set turbineMonitorOffset to "..turbineMonitorOffset.." in findReactors().") |
833 | end -- function findReactors() | |
834 | ||
835 | ||
836 | -- Initialize all Big Reactors - Turbines | |
837 | local function findTurbines() | |
838 | -- Empty out old list of turbines | |
839 | newTurbineList = {} | |
840 | - | printLog("Increasing Rod Levels in handleReactorMonitorClick(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").") |
840 | + | |
841 | printLog("Finding turbines...") | |
842 | newTurbineList, turbineNames = getDevices("BigReactors-Turbine") | |
843 | ||
844 | if #newTurbineList == 0 then | |
845 | printLog("No turbines found") -- Not an error | |
846 | else | |
847 | for turbineIndex = 1, #newTurbineList do | |
848 | - | printLog("Setting reactor["..reactorIndex.."] Rod Levels to "..newRodPercentage.."% in handleReactorMonitorClick(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").") |
848 | + | |
849 | turbine = newTurbineList[turbineIndex] | |
850 | ||
851 | if not turbine then | |
852 | printLog("turbineList["..turbineIndex.."] in findTurbines() is NOT a valid Big Reactors Turbine.") | |
853 | ||
854 | table.remove(newTurbineList, turbineIndex) -- Remove invalid turbine from list | |
855 | if turbineIndex ~= #newTurbineList then -- If we're not at the end, clean up | |
856 | - | printLog("No change to Rod Levels requested by "..progName.." GUI in handleReactorMonitorClick(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").") |
856 | + | |
857 | end -- turbineIndex ~= #newTurbineList then | |
858 | - | end -- UI.handleReactorMonitorClick = function(self, reactorIndex, monitorIndex) |
858 | + | |
859 | return -- Invalid turbineIndex | |
860 | - | -- Allow controlling Turbine Flow Rate from GUI |
860 | + | |
861 | - | UI.handleTurbineMonitorClick = function(self, turbineIndex, monitorIndex) |
861 | + | |
862 | _G[turbineNames[turbineIndex]] = {} | |
863 | _G[turbineNames[turbineIndex]]["TurbineOptions"] = {} | |
864 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["LastSpeed"] = 0 | |
865 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["BaseSpeed"] = 2726 | |
866 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["autoStart"] = true | |
867 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["LastFlow"] = 2000 --open up with all the steam wide open | |
868 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"] = false | |
869 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["turbineName"] = turbineNames[turbineIndex] | |
870 | printLog("turbineList["..turbineIndex.."] in findTurbines() is a valid Big Reactors Turbine.") | |
871 | if turbine.getConnected() then | |
872 | printLog("turbine["..turbineIndex.."] in findTurbines() is connected.") | |
873 | else | |
874 | printLog("turbine["..turbineIndex.."] in findTurbines() is NOT connected.") | |
875 | return -- Disconnected turbine | |
876 | end | |
877 | end | |
878 | - | printLog("turbine["..turbineIndex.."] in handleTurbineMonitorClick(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..") is NOT a valid Big Turbine.") |
878 | + | |
879 | --failsafe | |
880 | local tempTable = _G[turbineNames[turbineIndex]] | |
881 | - | printLog("turbine["..turbineIndex.."] in handleTurbineMonitorClick(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..") is a valid Big Turbine.") |
881 | + | |
882 | --check to make sure we get a valid config | |
883 | - | printLog("turbine["..turbineIndex.."] in handleTurbineMonitorClick(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..") is connected.") |
883 | + | |
884 | tempTable = config.load(turbineNames[turbineIndex]..".options") | |
885 | - | printLog("turbine["..turbineIndex.."] in handleTurbineMonitorClick(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..") is NOT connected.") |
885 | + | |
886 | --if we don't have a valid config from disk, make a valid config | |
887 | config.save(turbineNames[turbineIndex]..".options", _G[turbineNames[turbineIndex]]) | |
888 | end | |
889 | ||
890 | --load values from tempTable, checking for nil values along the way | |
891 | if tempTable["TurbineOptions"]["LastSpeed"] ~= nil then | |
892 | - | local turbineStatus = _G[turbineNames[turbineIndex]]["TurbineOptions"]["Status"] |
892 | + | |
893 | end | |
894 | ||
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 | + | |
898 | - | _G[turbineNames[turbineIndex]]["TurbineOptions"]["autoStart"] = turbine.getActive() |
898 | + | |
899 | if tempTable["TurbineOptions"]["autoStart"] ~= nil then | |
900 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["autoStart"] = tempTable["TurbineOptions"]["autoStart"] | |
901 | end | |
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 | + | |
904 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["LastFlow"] = tempTable["TurbineOptions"]["LastFlow"] | |
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 | + | |
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 | ||
911 | - | if ((_G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"]) or (_G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"] == "true")) then |
911 | + | |
912 | - | _G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"] = false |
912 | + | |
913 | end | |
914 | ||
915 | --save once more just to make sure we got it | |
916 | - | sideClick, xClick, yClick = 0, 0, 0 -- Reset click after we register it |
916 | + | |
917 | end -- for turbineIndex = 1, #newTurbineList do | |
918 | ||
919 | -- Overwrite old turbine list with the now updated list | |
920 | turbineList = newTurbineList | |
921 | - | printLog("Decrease to Flow Rate requested by "..progName.." GUI in handleTurbineMonitorClick(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").") |
921 | + | |
922 | ||
923 | printLog("Found "..#turbineList.." turbine(s) in findTurbines().") | |
924 | end -- function findTurbines() | |
925 | ||
926 | ||
927 | -- Return current energy buffer in a specific reactor by % | |
928 | local function getReactorStoredEnergyBufferPercent(reactor) | |
929 | printLog("Called as getReactorStoredEnergyBufferPercent(reactor).") | |
930 | ||
931 | if not reactor then | |
932 | printLog("getReactorStoredEnergyBufferPercent() did NOT receive a valid Big Reactor Reactor.") | |
933 | return -- Invalid reactorIndex | |
934 | else | |
935 | printLog("getReactorStoredEnergyBufferPercent() did receive a valid Big Reactor Reactor.") | |
936 | end | |
937 | ||
938 | local energyBufferStorage = reactor.getEnergyStored() | |
939 | return round(energyBufferStorage/100000, 1) -- (buffer/10000000 RF)*100% | |
940 | end -- function getReactorStoredEnergyBufferPercent(reactor) | |
941 | ||
942 | - | printLog("Increase to Flow Rate requested by "..progName.." GUI in handleTurbineMonitorClick(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").") |
942 | + | |
943 | -- Return current energy buffer in a specific Turbine by % | |
944 | local function getTurbineStoredEnergyBufferPercent(turbine) | |
945 | printLog("Called as getTurbineStoredEnergyBufferPercent(turbine)") | |
946 | ||
947 | if not turbine then | |
948 | printLog("getTurbineStoredEnergyBufferPercent() did NOT receive a valid Big Reactor Turbine.") | |
949 | return -- Invalid reactorIndex | |
950 | else | |
951 | printLog("getTurbineStoredEnergyBufferPercent() did receive a valid Big Reactor Turbine.") | |
952 | end | |
953 | ||
954 | local energyBufferStorage = turbine.getEnergyStored() | |
955 | return round(energyBufferStorage/10000, 1) -- (buffer/1000000 RF)*100% | |
956 | end -- function getTurbineStoredEnergyBufferPercent(turbine) | |
957 | ||
958 | local function reactorCruise(cruiseMaxTemp, cruiseMinTemp, reactorIndex) | |
959 | printLog("Called as reactorCruise(cruiseMaxTemp="..cruiseMaxTemp..",cruiseMinTemp="..cruiseMinTemp..",lastPolledTemp=".._G[reactorNames[reactorIndex]]["ReactorOptions"]["lastTempPoll"]..",reactorIndex="..reactorIndex..").") | |
960 | ||
961 | --sanitization | |
962 | local lastPolledTemp = tonumber(_G[reactorNames[reactorIndex]]["ReactorOptions"]["lastTempPoll"]) | |
963 | cruiseMaxTemp = tonumber(cruiseMaxTemp) | |
964 | - | printLog("No change to Flow Rate requested by "..progName.." GUI in handleTurbineMonitorClick(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").") |
964 | + | |
965 | ||
966 | if ((lastPolledTemp < cruiseMaxTemp) and (lastPolledTemp > cruiseMinTemp)) then | |
967 | local reactor = nil | |
968 | - | printLog("Decrease to Turbine RPM requested by "..progName.." GUI in handleTurbineMonitorClick(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").") |
968 | + | |
969 | if not reactor then | |
970 | printLog("reactor["..reactorIndex.."] in reactorCruise(cruiseMaxTemp="..cruiseMaxTemp..",cruiseMinTemp="..cruiseMinTemp..",lastPolledTemp="..lastPolledTemp..",reactorIndex="..reactorIndex..") is NOT a valid Big Reactor.") | |
971 | return -- Invalid reactorIndex | |
972 | else | |
973 | printLog("reactor["..reactorIndex.."] in reactorCruise(cruiseMaxTemp="..cruiseMaxTemp..",cruiseMinTemp="..cruiseMinTemp..",lastPolledTemp="..lastPolledTemp..",reactorIndex="..reactorIndex..") is a valid Big Reactor.") | |
974 | if reactor.getConnected() then | |
975 | printLog("reactor["..reactorIndex.."] in reactorCruise(cruiseMaxTemp="..cruiseMaxTemp..",cruiseMinTemp="..cruiseMinTemp..",lastPolledTemp="..lastPolledTemp..",reactorIndex="..reactorIndex..") is connected.") | |
976 | else | |
977 | printLog("reactor["..reactorIndex.."] in reactorCruise(cruiseMaxTemp="..cruiseMaxTemp..",cruiseMinTemp="..cruiseMinTemp..",lastPolledTemp="..lastPolledTemp..",reactorIndex="..reactorIndex..") is NOT connected.") | |
978 | - | printLog("Increase to Turbine RPM requested by "..progName.." GUI in handleTurbineMonitorClick(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").") |
978 | + | |
979 | end -- if reactor.getConnected() then | |
980 | end -- if not reactor then | |
981 | ||
982 | local rodPercentage = math.ceil(reactor.getControlRodLevel(0)) | |
983 | local reactorTemp = math.ceil(reactor.getFuelTemperature()) | |
984 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["baseControlRodLevel"] = rodPercentage | |
985 | ||
986 | if ((reactorTemp < cruiseMaxTemp) and (reactorTemp > cruiseMinTemp)) then | |
987 | if (reactorTemp < lastPolledTemp) then | |
988 | - | printLog("No change to Turbine RPM requested by "..progName.." GUI in handleTurbineMonitorClick(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").") |
988 | + | |
989 | --Boundary check | |
990 | - | end -- function handleTurbineMonitorClick(turbineIndex, monitorIndex) |
990 | + | |
991 | reactor.setAllControlRodLevels(0) | |
992 | else | |
993 | reactor.setAllControlRodLevels(rodPercentage) | |
994 | end | |
995 | else | |
996 | rodPercentage = (rodPercentage + 1) | |
997 | --Boundary check | |
998 | if rodPercentage > 99 then | |
999 | reactor.setAllControlRodLevels(99) | |
1000 | else | |
1001 | reactor.setAllControlRodLevels(rodPercentage) | |
1002 | end | |
1003 | end -- if (reactorTemp > lastPolledTemp) then | |
1004 | else | |
1005 | - | printLog("No monitors found, continuing headless") |
1005 | + | |
1006 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorCruising"] = false | |
1007 | end -- if ((reactorTemp < cruiseMaxTemp) and (reactorTemp > cruiseMinTemp)) then | |
1008 | else | |
1009 | --I don't know how we'd get here, but let's turn the cruise mode off | |
1010 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorCruising"] = false | |
1011 | end -- if ((lastPolledTemp < cruiseMaxTemp) and (lastPolledTemp > cruiseMinTemp)) then | |
1012 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["lastTempPoll"] = reactorTemp | |
1013 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["activeCooled"] = true | |
1014 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorMaxTemp"] = cruiseMaxTemp | |
1015 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorMinTemp"] = cruiseMinTemp | |
1016 | config.save(reactorNames[reactorIndex]..".options", _G[reactorNames[reactorIndex]]) | |
1017 | end -- function reactorCruise(cruiseMaxTemp, cruiseMinTemp, lastPolledTemp, reactorIndex) | |
1018 | ||
1019 | -- Modify reactor control rod levels to keep temperature with defined parameters, but | |
1020 | - | monitor.setTextScale(1.0) -- Make sure scale is correct |
1020 | + | |
1021 | local function temperatureControl(reactorIndex) | |
1022 | printLog("Called as temperatureControl(reactorIndex="..reactorIndex..")") | |
1023 | ||
1024 | local reactor = nil | |
1025 | reactor = reactorList[reactorIndex] | |
1026 | if not reactor then | |
1027 | printLog("reactor["..reactorIndex.."] in temperatureControl(reactorIndex="..reactorIndex..") is NOT a valid Big Reactor.") | |
1028 | return -- Invalid reactorIndex | |
1029 | else | |
1030 | printLog("reactor["..reactorIndex.."] in temperatureControl(reactorIndex="..reactorIndex..") is a valid Big Reactor.") | |
1031 | ||
1032 | if reactor.getConnected() then | |
1033 | printLog("reactor["..reactorIndex.."] in temperatureControl(reactorIndex="..reactorIndex..") is connected.") | |
1034 | else | |
1035 | printLog("reactor["..reactorIndex.."] in temperatureControl(reactorIndex="..reactorIndex..") is NOT connected.") | |
1036 | return -- Disconnected reactor | |
1037 | end -- if reactor.getConnected() then | |
1038 | end | |
1039 | ||
1040 | - | termRestore() |
1040 | + | |
1041 | local rodPercentage = math.ceil(reactor.getControlRodLevel(0)) | |
1042 | local reactorTemp = math.ceil(reactor.getFuelTemperature()) | |
1043 | local localMinReactorTemp, localMaxReactorTemp = _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorMinTemp"], _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorMaxTemp"] | |
1044 | ||
1045 | --bypass if the reactor itself is set to not be auto-controlled | |
1046 | if ((not _G[reactorNames[reactorIndex]]["ReactorOptions"]["rodOverride"]) or (_G[reactorNames[reactorIndex]]["ReactorOptions"]["rodOverride"] == "false")) then | |
1047 | -- No point modifying control rod levels for temperature if the reactor is offline | |
1048 | if reactor.getActive() then | |
1049 | -- Actively cooled reactors should range between 0^C-300^C | |
1050 | -- Actually, active-cooled reactors should range between 300 and 420C (Mechaet) | |
1051 | -- Accordingly I changed the below lines | |
1052 | if reactor.isActivelyCooled() then | |
1053 | -- below was 0 | |
1054 | localMinReactorTemp = 300 | |
1055 | -- below was 300 | |
1056 | localMaxReactorTemp = 420 | |
1057 | else | |
1058 | localMinReactorTemp = _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorMinTemp"] | |
1059 | localMaxReactorTemp = _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorMaxTemp"] | |
1060 | end | |
1061 | local lastTempPoll = _G[reactorNames[reactorIndex]]["ReactorOptions"]["lastTempPoll"] | |
1062 | if _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorCruising"] then | |
1063 | --let's bypass all this math and hit the much-more-subtle cruise feature | |
1064 | --printLog("min: "..localMinReactorTemp..", max: "..localMaxReactorTemp..", lasttemp: "..lastTempPoll..", ri: "..reactorIndex.." EOL") | |
1065 | reactorCruise(localMaxReactorTemp, localMinReactorTemp, reactorIndex) | |
1066 | else | |
1067 | -- Don't bring us to 100, that's effectively a shutdown | |
1068 | if (reactorTemp > localMaxReactorTemp) and (rodPercentage ~= 99) then | |
1069 | --increase the rods, but by how much? | |
1070 | if (reactorTemp > lastTempPoll) then | |
1071 | --we're climbing, we need to get this to decrease | |
1072 | if ((reactorTemp - lastTempPoll) > 100) then | |
1073 | --we're climbing really fast, arrest it | |
1074 | if (rodPercentage + (10 * controlRodAdjustAmount)) > 99 then | |
1075 | reactor.setAllControlRodLevels(99) | |
1076 | else | |
1077 | reactor.setAllControlRodLevels(rodPercentage + (10 * controlRodAdjustAmount)) | |
1078 | end | |
1079 | else | |
1080 | --we're not climbing by leaps and bounds, let's give it a rod adjustment based on temperature increase | |
1081 | local diffAmount = reactorTemp - lastTempPoll | |
1082 | diffAmount = (round(diffAmount/10, 0))/5 | |
1083 | controlRodAdjustAmount = diffAmount | |
1084 | if (rodPercentage + controlRodAdjustAmount) > 99 then | |
1085 | reactor.setAllControlRodLevels(99) | |
1086 | else | |
1087 | reactor.setAllControlRodLevels(rodPercentage + controlRodAdjustAmount) | |
1088 | end | |
1089 | end --if ((reactorTemp - lastTempPoll) > 100) then | |
1090 | elseif (reactorTemp == lastTempPoll) then | |
1091 | --temperature has stagnated, kick it very lightly | |
1092 | local controlRodAdjustment = 1 | |
1093 | if (rodPercentage + controlRodAdjustment) > 99 then | |
1094 | reactor.setAllControlRodLevels(99) | |
1095 | - | _G[reactorNames[reactorIndex]]["ReactorOptions"]["controlRodAdjustAmount"] = controlRodAdjustAmount |
1095 | + | |
1096 | reactor.setAllControlRodLevels(rodPercentage + controlRodAdjustment) | |
1097 | end | |
1098 | end --if (reactorTemp > lastTempPoll) then | |
1099 | --worth noting that if we're above temp but decreasing, we do nothing. let it continue decreasing. | |
1100 | ||
1101 | elseif (reactorTemp < localMinReactorTemp) and (rodPercentage ~=0) then | |
1102 | --we're too cold. time to warm up, but by how much? | |
1103 | if (reactorTemp < lastTempPoll) then | |
1104 | --we're descending, let's stop that. | |
1105 | if ((lastTempPoll - reactorTemp) > 100) then | |
1106 | --we're headed for a new ice age, bring the heat | |
1107 | if (rodPercentage - (10 * controlRodAdjustAmount)) < 0 then | |
1108 | reactor.setAllControlRodLevels(0) | |
1109 | else | |
1110 | reactor.setAllControlRodLevels(rodPercentage - (10 * controlRodAdjustAmount)) | |
1111 | end | |
1112 | else | |
1113 | --we're not descending quickly, let's bump it based on descent rate | |
1114 | local diffAmount = lastTempPoll - reactorTemp | |
1115 | diffAmount = (round(diffAmount/10, 0))/5 | |
1116 | controlRodAdjustAmount = diffAmount | |
1117 | if (rodPercentage - controlRodAdjustAmount) < 0 then | |
1118 | reactor.setAllControlRodLevels(0) | |
1119 | else | |
1120 | reactor.setAllControlRodLevels(rodPercentage - controlRodAdjustAmount) | |
1121 | end | |
1122 | end --if ((lastTempPoll - reactorTemp) > 100) then | |
1123 | elseif (reactorTemp == lastTempPoll) then | |
1124 | --temperature has stagnated, kick it very lightly | |
1125 | local controlRodAdjustment = 1 | |
1126 | if (rodPercentage - controlRodAdjustment) < 0 then | |
1127 | reactor.setAllControlRodLevels(0) | |
1128 | else | |
1129 | reactor.setAllControlRodLevels(rodPercentage - controlRodAdjustment) | |
1130 | end --if (rodPercentage - controlRodAdjustment) < 0 then | |
1131 | ||
1132 | end --if (reactorTemp < lastTempPoll) then | |
1133 | --if we're below temp but increasing, do nothing and let it continue to rise. | |
1134 | end --if (reactorTemp > localMaxReactorTemp) and (rodPercentage ~= 99) then | |
1135 | ||
1136 | if ((reactorTemp > localMinReactorTemp) and (reactorTemp < localMaxReactorTemp)) then | |
1137 | --engage cruise mode | |
1138 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorCruising"] = true | |
1139 | end -- if ((reactorTemp > localMinReactorTemp) and (reactorTemp < localMaxReactorTemp)) then | |
1140 | end -- if reactorCruising then | |
1141 | --always set this number | |
1142 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["lastTempPoll"] = reactorTemp | |
1143 | config.save(reactorNames[reactorIndex]..".options", _G[reactorNames[reactorIndex]]) | |
1144 | end -- if reactor.getActive() then | |
1145 | else | |
1146 | printLog("Bypassed temperature control due to rodOverride being "..tostring(_G[reactorNames[reactorIndex]]["ReactorOptions"]["rodOverride"]).." EOL") | |
1147 | - | if tempTable["ReactorOptions"]["controlRodAdjustAmount"] ~= nil then |
1147 | + | |
1148 | - | _G[reactorNames[reactorIndex]]["ReactorOptions"]["controlRodAdjustAmount"] = tempTable["ReactorOptions"]["controlRodAdjustAmount"] |
1148 | + | |
1149 | ||
1150 | -- Load saved reactor parameters if ReactorOptions file exists | |
1151 | local function loadReactorOptions() | |
1152 | local reactorOptions = fs.open("ReactorOptions", "r") -- See http://computercraft.info/wiki/Fs.open | |
1153 | ||
1154 | if reactorOptions then | |
1155 | -- The following values were added by Lolmer | |
1156 | minStoredEnergyPercent = reactorOptions.readLine() | |
1157 | maxStoredEnergyPercent = reactorOptions.readLine() | |
1158 | --added by Mechaet | |
1159 | -- If we succeeded in reading a string, convert it to a number | |
1160 | ||
1161 | if minStoredEnergyPercent ~= nil then | |
1162 | minStoredEnergyPercent = tonumber(minStoredEnergyPercent) | |
1163 | end | |
1164 | ||
1165 | if maxStoredEnergyPercent ~= nil then | |
1166 | maxStoredEnergyPercent = tonumber(maxStoredEnergyPercent) | |
1167 | end | |
1168 | ||
1169 | reactorOptions.close() | |
1170 | end -- if reactorOptions then | |
1171 | ||
1172 | -- Set default values if we failed to read any of the above | |
1173 | if minStoredEnergyPercent == nil then | |
1174 | minStoredEnergyPercent = 15 | |
1175 | end | |
1176 | ||
1177 | if maxStoredEnergyPercent == nil then | |
1178 | maxStoredEnergyPercent = 85 | |
1179 | end | |
1180 | ||
1181 | end -- function loadReactorOptions() | |
1182 | ||
1183 | ||
1184 | -- Save our reactor parameters | |
1185 | local function saveReactorOptions() | |
1186 | local reactorOptions = fs.open("ReactorOptions", "w") -- See http://computercraft.info/wiki/Fs.open | |
1187 | ||
1188 | - | _G[reactorNames[reactorIndex]]["ReactorOptions"]["controlRodAdjustAmount"] = tonumber(_G[reactorNames[reactorIndex]]["ReactorOptions"]["controlRodAdjustAmount"]) |
1188 | + | |
1189 | if reactorOptions then | |
1190 | local reactorIndex = 1 | |
1191 | -- The following values were added by Lolmer | |
1192 | reactorOptions.writeLine(minStoredEnergyPercent) | |
1193 | reactorOptions.writeLine(maxStoredEnergyPercent) | |
1194 | reactorOptions.close() | |
1195 | else | |
1196 | printLog("Failed to open file ReactorOptions for writing!") | |
1197 | end -- if reactorOptions then | |
1198 | end -- function saveReactorOptions() | |
1199 | ||
1200 | ||
1201 | local function displayReactorBars(barParams) | |
1202 | -- Default to first reactor and first monitor | |
1203 | setmetatable(barParams,{__index={reactorIndex=1, monitorIndex=1}}) | |
1204 | local reactorIndex, monitorIndex = | |
1205 | barParams[1] or barParams.reactorIndex, | |
1206 | barParams[2] or barParams.monitorIndex | |
1207 | ||
1208 | printLog("Called as displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").") | |
1209 | ||
1210 | -- Grab current monitor | |
1211 | local monitor = nil | |
1212 | monitor = monitorList[monitorIndex] | |
1213 | if not monitor then | |
1214 | printLog("monitor["..monitorIndex.."] in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is NOT a valid monitor.") | |
1215 | return -- Invalid monitorIndex | |
1216 | end | |
1217 | ||
1218 | -- Grab current reactor | |
1219 | local reactor = nil | |
1220 | reactor = reactorList[reactorIndex] | |
1221 | if not reactor then | |
1222 | printLog("reactor["..reactorIndex.."] in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is NOT a valid Big Reactor.") | |
1223 | return -- Invalid reactorIndex | |
1224 | else | |
1225 | printLog("reactor["..reactorIndex.."] in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is a valid Big Reactor.") | |
1226 | if reactor.getConnected() then | |
1227 | printLog("reactor["..reactorIndex.."] in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is connected.") | |
1228 | else | |
1229 | printLog("reactor["..reactorIndex.."] in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is NOT connected.") | |
1230 | return -- Disconnected reactor | |
1231 | end -- if reactor.getConnected() then | |
1232 | end -- if not reactor then | |
1233 | ||
1234 | -- Draw border lines | |
1235 | local width, height = monitor.getSize() | |
1236 | printLog("Size of monitor is "..width.."w x"..height.."h in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..")") | |
1237 | ||
1238 | for i=3, 5 do | |
1239 | monitor.setCursorPos(22, i) | |
1240 | monitor.write("|") | |
1241 | end | |
1242 | ||
1243 | drawLine(2, monitorIndex) | |
1244 | drawLine(6, monitorIndex) | |
1245 | ||
1246 | -- Draw some text | |
1247 | local fuelString = "Fuel: " | |
1248 | local tempString = "Temp: " | |
1249 | local energyBufferString = "" | |
1250 | ||
1251 | if reactor.isActivelyCooled() then | |
1252 | energyBufferString = "Steam: " | |
1253 | else | |
1254 | energyBufferString = "Energy: " | |
1255 | end | |
1256 | ||
1257 | local padding = math.max(string.len(fuelString), string.len(tempString), string.len(energyBufferString)) | |
1258 | ||
1259 | local fuelPercentage = round(reactor.getFuelAmount()/reactor.getFuelAmountMax()*100,1) | |
1260 | print{fuelString,2,3,monitorIndex} | |
1261 | print{fuelPercentage.." %",padding+2,3,monitorIndex} | |
1262 | ||
1263 | local reactorTemp = math.ceil(reactor.getFuelTemperature()) | |
1264 | print{tempString,2,5,monitorIndex} | |
1265 | print{reactorTemp.." C",padding+2,5,monitorIndex} | |
1266 | ||
1267 | local rodPercentage = math.ceil(reactor.getControlRodLevel(0)) | |
1268 | printLog("Current Rod Percentage for reactor["..reactorIndex.."] is "..rodPercentage.."% in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").") | |
1269 | -- Allow controlling Reactor Control Rod Level from GUI | |
1270 | -- Decrease rod button: 23X, 4Y | |
1271 | -- Increase rod button: 28X, 4Y | |
1272 | if (xClick == 23) and (yClick == 4) and (sideClick == monitorNames[monitorIndex]) then | |
1273 | printLog("Decreasing Rod Levels in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").") | |
1274 | --Decrease rod level by amount | |
1275 | newRodPercentage = rodPercentage - (5 * controlRodAdjustAmount) | |
1276 | if newRodPercentage < 0 then | |
1277 | newRodPercentage = 0 | |
1278 | end | |
1279 | sideClick, xClick, yClick = 0, 0, 0 | |
1280 | ||
1281 | printLog("Setting reactor["..reactorIndex.."] Rod Levels to "..newRodPercentage.."% in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").") | |
1282 | reactor.setAllControlRodLevels(newRodPercentage) | |
1283 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["baseControlRodLevel"] = newRodPercentage | |
1284 | ||
1285 | -- Save updated rod percentage | |
1286 | config.save(reactorNames[reactorIndex]..".options", _G[reactorNames[reactorIndex]]) | |
1287 | rodPercentage = newRodPercentage | |
1288 | elseif (xClick == 29) and (yClick == 4) and (sideClick == monitorNames[monitorIndex]) then | |
1289 | printLog("Increasing Rod Levels in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").") | |
1290 | --Increase rod level by amount | |
1291 | newRodPercentage = rodPercentage + (5 * controlRodAdjustAmount) | |
1292 | if newRodPercentage > 100 then | |
1293 | newRodPercentage = 100 | |
1294 | end | |
1295 | sideClick, xClick, yClick = 0, 0, 0 | |
1296 | ||
1297 | printLog("Setting reactor["..reactorIndex.."] Rod Levels to "..newRodPercentage.."% in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").") | |
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 | -- Save updated rod percentage | |
1302 | - | local monitors = {} |
1302 | + | |
1303 | - | monitorAssignments = {} |
1303 | + | |
1304 | else | |
1305 | - | printLog("Assigning monitors...") |
1305 | + | printLog("No change to Rod Levels requested by "..progName.." GUI in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").") |
1306 | end -- if (xClick == 29) and (yClick == 4) and (sideClick == monitorNames[monitorIndex]) then | |
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 | -- getEnergyProducedLastTick() is used for both RF/t (passively cooled) and mB/t (actively cooled) | |
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 | printLog("reactor["..reactorIndex.."] in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is NOT an actively cooled reactor.") | |
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 | print{"Energy Buffer",2,7,monitorIndex} | |
1339 | print{curStoredEnergyPercent, width-(string.len(curStoredEnergyPercent)+2),7,monitorIndex} | |
1340 | print{"%",28,7,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 | printLog("reactor["..reactorIndex.."] in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is an actively cooled reactor.") | |
1345 | print{math.ceil(energyBuffer).." mB/t",padding+2,4,monitorIndex} | |
1346 | end -- if not reactor.isActivelyCooled() then | |
1347 | ||
1348 | - | printLog("No valid monitor configuration found, generating...") |
1348 | + | |
1349 | local reactorRodOverrideStatus = "" | |
1350 | - | -- create assignments that reflect the setup before 0.3.17 |
1350 | + | |
1351 | print{"Rod Auto-adjust:",2,9,monitorIndex} | |
1352 | - | monitorAssignments[monitorNames[1]] = {type="Status", index=1} |
1352 | + | |
1353 | - | monitorIndex = monitorIndex + 1 |
1353 | + | |
1354 | printLog("Reactor Rod Override status is: "..tostring(_G[reactorNames[reactorIndex]]["ReactorOptions"]["rodOverride"]).." EOL") | |
1355 | - | if monitorIndex > #monitorList then |
1355 | + | |
1356 | - | break |
1356 | + | |
1357 | else | |
1358 | - | monitorAssignments[monitorNames[monitorIndex]] = {type="Reactor", index=monitorIndex, reactorName=reactorNames[reactorIndex], reactorIndex=reactorIndex} |
1358 | + | |
1359 | - | printLog(monitorNames[monitorIndex].." -> "..reactorNames[reactorIndex]) |
1359 | + | |
1360 | monitor.setTextColor(colors.red) | |
1361 | - | monitorIndex = monitorIndex + 1 |
1361 | + | |
1362 | printLog("reactorRodOverrideStatus is \""..reactorRodOverrideStatus.."\" in displayReactorBars(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..").") | |
1363 | ||
1364 | - | if monitorIndex > #monitorList then |
1364 | + | |
1365 | - | break |
1365 | + | |
1366 | ||
1367 | - | monitorAssignments[monitorNames[monitorIndex]] = {type="Turbine", index=monitorIndex, turbineName=turbineNames[turbineIndex], turbineIndex=turbineIndex} |
1367 | + | |
1368 | - | printLog(monitorNames[monitorIndex].." -> "..turbineNames[turbineIndex]) |
1368 | + | |
1369 | print{"Waste: "..reactor.getWasteAmount().." mB", width-(string.len(reactor.getWasteAmount())+10), 11, monitorIndex} | |
1370 | - | monitorIndex = monitorIndex + 1 |
1370 | + | |
1371 | monitor.setTextColor(colors.blue) | |
1372 | - | if monitorIndex <= #monitorList then |
1372 | + | |
1373 | - | monitorAssignments[monitorNames[#monitorList]] = {type="Debug", index=#monitorList} |
1373 | + | |
1374 | end -- function displayReactorBars(barParams) | |
1375 | ||
1376 | ||
1377 | - | tprint(monitorAssignments) |
1377 | + | |
1378 | -- Default to first reactor and first monitor | |
1379 | - | saveMonitorAssignments() |
1379 | + | |
1380 | local reactorIndex, monitorIndex = | |
1381 | - | end -- function assignMonitors() |
1381 | + | |
1382 | statusParams[2] or statusParams.monitorIndex | |
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 | if not monitor then | |
1389 | - | while true do |
1389 | + | |
1390 | - | local event = {os.pullEvent()} |
1390 | + | |
1391 | end | |
1392 | - | if (event[1] == "timer" and event[2] == timer) then |
1392 | + | |
1393 | - | break |
1393 | + | |
1394 | local reactor = nil | |
1395 | - | eventHandler(event[1], event[2], event[3], event[4]) |
1395 | + | |
1396 | if not reactor then | |
1397 | printLog("reactor["..reactorIndex.."] in reactorStatus(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is NOT a valid Big Reactor.") | |
1398 | return -- Invalid reactorIndex | |
1399 | else | |
1400 | printLog("reactor["..reactorIndex.."] in reactorStatus(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is a valid Big Reactor.") | |
1401 | end | |
1402 | ||
1403 | local width, height = monitor.getSize() | |
1404 | local reactorStatus = "" | |
1405 | ||
1406 | if reactor.getConnected() then | |
1407 | printLog("reactor["..reactorIndex.."] in reactorStatus(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is connected.") | |
1408 | ||
1409 | if reactor.getActive() then | |
1410 | reactorStatus = "ONLINE" | |
1411 | ||
1412 | -- Set "ONLINE" to blue if the actively cooled reactor is both in cruise mode and online | |
1413 | if _G[reactorNames[reactorIndex]]["ReactorOptions"]["reactorCruising"] and reactor.isActivelyCooled() then | |
1414 | monitor.setTextColor(colors.blue) | |
1415 | else | |
1416 | monitor.setTextColor(colors.green) | |
1417 | end -- if reactorCruising and reactor.isActivelyCooled() then | |
1418 | else | |
1419 | reactorStatus = "OFFLINE" | |
1420 | monitor.setTextColor(colors.red) | |
1421 | end -- if reactor.getActive() then | |
1422 | ||
1423 | if xClick >= (width - string.len(reactorStatus) - 1) and xClick <= (width-1) and (sideClick == monitorNames[monitorIndex]) then | |
1424 | if yClick == 1 then | |
1425 | reactor.setActive(not reactor.getActive()) -- Toggle reactor status | |
1426 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["autoStart"] = reactor.getActive() | |
1427 | config.save(reactorNames[reactorIndex]..".options", _G[reactorNames[reactorIndex]]) | |
1428 | sideClick, xClick, yClick = 0, 0, 0 -- Reset click after we register it | |
1429 | ||
1430 | -- If someone offlines the reactor (offline after a status click was detected), then disable autoStart | |
1431 | if not reactor.getActive() then | |
1432 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["autoStart"] = false | |
1433 | end | |
1434 | end -- if yClick == 1 then | |
1435 | end -- if (xClick >= (width - string.len(reactorStatus) - 1) and xClick <= (width-1)) and (sideClick == monitorNames[monitorIndex]) then | |
1436 | ||
1437 | -- Allow disabling rod level auto-adjust and only manual rod level control | |
1438 | if ((xClick > 23 and xClick < 28 and yClick == 4) | |
1439 | or (xClick > 20 and xClick < 27 and yClick == 9)) | |
1440 | and (sideClick == monitorNames[monitorIndex]) then | |
1441 | _G[reactorNames[reactorIndex]]["ReactorOptions"]["rodOverride"] = not _G[reactorNames[reactorIndex]]["ReactorOptions"]["rodOverride"] | |
1442 | config.save(reactorNames[reactorIndex]..".options", _G[reactorNames[reactorIndex]]) | |
1443 | sideClick, xClick, yClick = 0, 0, 0 -- Reset click after we register it | |
1444 | end -- if (xClick > 23) and (xClick < 28) and (yClick == 4) and (sideClick == monitorNames[monitorIndex]) then | |
1445 | ||
1446 | else | |
1447 | printLog("reactor["..reactorIndex.."] in reactorStatus(reactorIndex="..reactorIndex..",monitorIndex="..monitorIndex..") is NOT connected.") | |
1448 | reactorStatus = "DISCONNECTED" | |
1449 | monitor.setTextColor(colors.red) | |
1450 | end -- if reactor.getConnected() then | |
1451 | ||
1452 | print{reactorStatus, width - string.len(reactorStatus) - 1, 1, monitorIndex} | |
1453 | monitor.setTextColor(colors.white) | |
1454 | end -- function reactorStatus(statusParams) | |
1455 | ||
1456 | ||
1457 | -- Display all found reactors' status to monitor 1 | |
1458 | -- This is only called if multiple reactors and/or a reactor plus at least one turbine are found | |
1459 | local function displayAllStatus() | |
1460 | local reactor, turbine = nil, nil | |
1461 | local onlineReactor, onlineTurbine = 0, 0 | |
1462 | local totalReactorRF, totalReactorSteam, totalTurbineRF = 0, 0, 0 | |
1463 | local totalReactorFuelConsumed = 0 | |
1464 | local totalCoolantStored, totalSteamStored, totalEnergy, totalMaxEnergyStored = 0, 0, 0, 0 -- Total turbine and reactor energy buffer and overall capacity | |
1465 | local maxSteamStored = (2000*#turbineList)+(5000*#reactorList) | |
1466 | local maxCoolantStored = (2000*#turbineList)+(5000*#reactorList) | |
1467 | ||
1468 | local monitor, monitorIndex = nil, 1 | |
1469 | monitor = monitorList[monitorIndex] | |
1470 | if not monitor then | |
1471 | printLog("monitor["..monitorIndex.."] in displayAllStatus() is NOT a valid monitor.") | |
1472 | return -- Invalid monitorIndex | |
1473 | end | |
1474 | ||
1475 | for reactorIndex = 1, #reactorList do | |
1476 | reactor = reactorList[reactorIndex] | |
1477 | if not reactor then | |
1478 | printLog("reactor["..reactorIndex.."] in displayAllStatus() is NOT a valid Big Reactor.") | |
1479 | break -- Invalid reactorIndex | |
1480 | else | |
1481 | printLog("reactor["..reactorIndex.."] in displayAllStatus() is a valid Big Reactor.") | |
1482 | end -- if not reactor then | |
1483 | ||
1484 | if reactor.getConnected() then | |
1485 | printLog("reactor["..reactorIndex.."] in displayAllStatus() is connected.") | |
1486 | if reactor.getActive() then | |
1487 | onlineReactor = onlineReactor + 1 | |
1488 | totalReactorFuelConsumed = totalReactorFuelConsumed + reactor.getFuelConsumedLastTick() | |
1489 | end -- reactor.getActive() then | |
1490 | ||
1491 | -- Actively cooled reactors do not produce or store energy | |
1492 | if not reactor.isActivelyCooled() then | |
1493 | totalMaxEnergyStored = totalMaxEnergyStored + 10000000 -- Reactors store 10M RF | |
1494 | totalEnergy = totalEnergy + reactor.getEnergyStored() | |
1495 | totalReactorRF = totalReactorRF + reactor.getEnergyProducedLastTick() | |
1496 | else | |
1497 | totalReactorSteam = totalReactorSteam + reactor.getEnergyProducedLastTick() | |
1498 | totalSteamStored = totalSteamStored + reactor.getHotFluidAmount() | |
1499 | totalCoolantStored = totalCoolantStored + reactor.getCoolantAmount() | |
1500 | end -- if not reactor.isActivelyCooled() then | |
1501 | else | |
1502 | printLog("reactor["..reactorIndex.."] in displayAllStatus() is NOT connected.") | |
1503 | end -- if reactor.getConnected() then | |
1504 | end -- for reactorIndex = 1, #reactorList do | |
1505 | ||
1506 | for turbineIndex = 1, #turbineList do | |
1507 | turbine = turbineList[turbineIndex] | |
1508 | if not turbine then | |
1509 | printLog("turbine["..turbineIndex.."] in displayAllStatus() is NOT a valid Turbine.") | |
1510 | break -- Invalid turbineIndex | |
1511 | else | |
1512 | printLog("turbine["..turbineIndex.."] in displayAllStatus() is a valid Turbine.") | |
1513 | end -- if not turbine then | |
1514 | ||
1515 | if turbine.getConnected() then | |
1516 | printLog("turbine["..turbineIndex.."] in displayAllStatus() is connected.") | |
1517 | if turbine.getActive() then | |
1518 | onlineTurbine = onlineTurbine + 1 | |
1519 | end | |
1520 | ||
1521 | totalMaxEnergyStored = totalMaxEnergyStored + 1000000 -- Turbines store 1M RF | |
1522 | totalEnergy = totalEnergy + turbine.getEnergyStored() | |
1523 | totalTurbineRF = totalTurbineRF + turbine.getEnergyProducedLastTick() | |
1524 | totalSteamStored = totalSteamStored + turbine.getInputAmount() | |
1525 | totalCoolantStored = totalCoolantStored + turbine.getOutputAmount() | |
1526 | - | if reactor.isActivelyCooled() and not knowlinglyOverride then |
1526 | + | |
1527 | printLog("turbine["..turbineIndex.."] in displayAllStatus() is NOT connected.") | |
1528 | end -- if turbine.getConnected() then | |
1529 | end -- for turbineIndex = 1, #turbineList do | |
1530 | ||
1531 | print{"Reactors online/found: "..onlineReactor.."/"..#reactorList, 2, 3, monitorIndex} | |
1532 | print{"Turbines online/found: "..onlineTurbine.."/"..#turbineList, 2, 4, monitorIndex} | |
1533 | ||
1534 | if totalReactorRF ~= 0 then | |
1535 | monitor.setTextColor(colors.blue) | |
1536 | printRight("Reactor", 9, monitorIndex) | |
1537 | monitor.setTextColor(colors.white) | |
1538 | printRight(math.ceil(totalReactorRF).." (RF/t)", 10, monitorIndex) | |
1539 | end | |
1540 | ||
1541 | - | local localControlRodAdjustAmount = _G[reactorNames[reactorIndex]]["ReactorOptions"]["controlRodAdjustAmount"] |
1541 | + | |
1542 | -- Display liquids | |
1543 | monitor.setTextColor(colors.blue) | |
1544 | printLeft("Steam (mB)", 6, monitorIndex) | |
1545 | monitor.setTextColor(colors.white) | |
1546 | printLeft(math.ceil(totalSteamStored).."/"..maxSteamStored, 7, monitorIndex) | |
1547 | printLeft(math.ceil(totalReactorSteam).." mB/t", 8, monitorIndex) | |
1548 | monitor.setTextColor(colors.blue) | |
1549 | - | if (rodPercentage + (10 * localControlRodAdjustAmount)) > 99 then |
1549 | + | |
1550 | monitor.setTextColor(colors.white) | |
1551 | printRight(math.ceil(totalCoolantStored).."/"..maxCoolantStored, 7, monitorIndex) | |
1552 | - | reactor.setAllControlRodLevels(rodPercentage + (10 * localControlRodAdjustAmount)) |
1552 | + | |
1553 | monitor.setTextColor(colors.blue) | |
1554 | printLeft("Turbine", 9, monitorIndex) | |
1555 | monitor.setTextColor(colors.white) | |
1556 | printLeft(math.ceil(totalTurbineRF).." RF/t", 10, monitorIndex) | |
1557 | end -- if #turbineList then | |
1558 | - | _G[reactorNames[reactorIndex]]["ReactorOptions"]["controlRodAdjustAmount"] = diffAmount |
1558 | + | |
1559 | - | if (rodPercentage + diffAmount) > 99 then |
1559 | + | |
1560 | print{"Buffer: "..math.ceil(totalEnergy,3).."/"..totalMaxEnergyStored.." RF", 2, 12, monitorIndex} | |
1561 | end -- function displayAllStatus() | |
1562 | - | reactor.setAllControlRodLevels(rodPercentage + diffAmount) |
1562 | + | |
1563 | ||
1564 | -- Get turbine status | |
1565 | - | elseif ((lastTempPoll - reactorTemp) < (reactorTemp * 0.005)) then |
1565 | + | |
1566 | printLog("Called as displayTurbineBars(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").") | |
1567 | ||
1568 | -- Grab current monitor | |
1569 | local monitor = nil | |
1570 | monitor = monitorList[monitorIndex] | |
1571 | if not monitor then | |
1572 | printLog("monitor["..monitorIndex.."] in displayTurbineBars(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..") is NOT a valid monitor.") | |
1573 | return -- Invalid monitorIndex | |
1574 | end | |
1575 | ||
1576 | - | elseif ((reactorTemp < localMinReactorTemp) and (rodPercentage ~=0)) or (steamRequested - steamDelivered > 0) then |
1576 | + | |
1577 | local turbine = nil | |
1578 | - | if (steamRequested > (steamDelivered*2)) then |
1578 | + | |
1579 | - | -- Bridge to machine room: Full steam ahead! |
1579 | + | |
1580 | - | reactor.setAllControlRodLevels(0) |
1580 | + | |
1581 | - | elseif (reactorTemp < lastTempPoll) then |
1581 | + | |
1582 | else | |
1583 | printLog("turbine["..turbineIndex.."] in displayTurbineBars(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..") is a valid Big Turbine.") | |
1584 | if turbine.getConnected() then | |
1585 | - | if (rodPercentage - (10 * localControlRodAdjustAmount)) < 0 then |
1585 | + | |
1586 | else | |
1587 | printLog("turbine["..turbineIndex.."] in displayTurbineBars(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..") is NOT connected.") | |
1588 | - | reactor.setAllControlRodLevels(rodPercentage - (10 * localControlRodAdjustAmount)) |
1588 | + | |
1589 | end -- if turbine.getConnected() then | |
1590 | end -- if not turbine then | |
1591 | ||
1592 | --local variable to match the view on the monitor | |
1593 | local turbineBaseSpeed = tonumber(_G[turbineNames[turbineIndex]]["TurbineOptions"]["BaseSpeed"]) | |
1594 | - | _G[reactorNames[reactorIndex]]["ReactorOptions"]["controlRodAdjustAmount"] = diffAmount |
1594 | + | |
1595 | - | if (rodPercentage - diffAmount) < 0 then |
1595 | + | |
1596 | local width, height = monitor.getSize() | |
1597 | ||
1598 | - | reactor.setAllControlRodLevels(rodPercentage - diffAmount) |
1598 | + | |
1599 | monitor.setCursorPos(21, i) | |
1600 | monitor.write("|") | |
1601 | end | |
1602 | ||
1603 | drawLine(2,monitorIndex) | |
1604 | drawLine(7,monitorIndex) | |
1605 | ||
1606 | -- Allow controlling Turbine Flow Rate from GUI | |
1607 | -- Decrease flow rate button: 22X, 4Y | |
1608 | -- Increase flow rate button: 28X, 4Y | |
1609 | local turbineFlowRate = tonumber(_G[turbineNames[turbineIndex]]["TurbineOptions"]["LastFlow"]) | |
1610 | if (xClick == 22) and (yClick == 4) and (sideClick == monitorNames[monitorIndex]) then | |
1611 | printLog("Decrease to Flow Rate requested by "..progName.." GUI in displayTurbineBars(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").") | |
1612 | --Decrease rod level by amount | |
1613 | newTurbineFlowRate = turbineFlowRate - flowRateAdjustAmount | |
1614 | - | if ((reactorTemp > localMinReactorTemp) and (reactorTemp < localMaxReactorTemp)) and not (steamRequested - steamDelivered > 0) then |
1614 | + | |
1615 | newTurbineFlowRate = 0 | |
1616 | end | |
1617 | sideClick, xClick, yClick = 0, 0, 0 | |
1618 | ||
1619 | -- Check bounds [0,2000] | |
1620 | if newTurbineFlowRate > 2000 then | |
1621 | newTurbineFlowRate = 2000 | |
1622 | elseif newTurbineFlowRate < 0 then | |
1623 | newTurbineFlowRate = 25 -- Don't go to zero, might as well power off | |
1624 | end | |
1625 | ||
1626 | turbine.setFluidFlowRateMax(newTurbineFlowRate) | |
1627 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["LastFlow"] = newTurbineFlowRate | |
1628 | -- Save updated Turbine Flow Rate | |
1629 | turbineFlowRate = newTurbineFlowRate | |
1630 | config.save(turbineNames[turbineIndex]..".options", _G[turbineNames[turbineIndex]]) | |
1631 | elseif (xClick == 29) and (yClick == 4) and (sideClick == monitorNames[monitorIndex]) then | |
1632 | printLog("Increase to Flow Rate requested by "..progName.." GUI in displayTurbineBars(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").") | |
1633 | --Increase rod level by amount | |
1634 | newTurbineFlowRate = turbineFlowRate + flowRateAdjustAmount | |
1635 | if newTurbineFlowRate > 2000 then | |
1636 | newTurbineFlowRate = 2000 | |
1637 | end | |
1638 | sideClick, xClick, yClick = 0, 0, 0 | |
1639 | ||
1640 | -- Check bounds [0,2000] | |
1641 | if newTurbineFlowRate > 2000 then | |
1642 | newTurbineFlowRate = 2000 | |
1643 | elseif newTurbineFlowRate < 0 then | |
1644 | newTurbineFlowRate = 25 -- Don't go to zero, might as well power off | |
1645 | end | |
1646 | ||
1647 | turbine.setFluidFlowRateMax(newTurbineFlowRate) | |
1648 | ||
1649 | -- Save updated Turbine Flow Rate | |
1650 | turbineFlowRate = math.ceil(newTurbineFlowRate) | |
1651 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["LastFlow"] = turbineFlowRate | |
1652 | config.save(turbineNames[turbineIndex]..".options", _G[turbineNames[turbineIndex]]) | |
1653 | else | |
1654 | printLog("No change to Flow Rate requested by "..progName.." GUI in displayTurbineBars(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").") | |
1655 | end -- if (xClick == 29) and (yClick == 4) and (sideClick == monitorNames[monitorIndex]) then | |
1656 | ||
1657 | if (xClick == 22) and (yClick == 6) and (sideClick == monitorNames[monitorIndex]) then | |
1658 | printLog("Decrease to Turbine RPM requested by "..progName.." GUI in displayTurbineBars(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").") | |
1659 | rpmRateAdjustment = 909 | |
1660 | newTurbineBaseSpeed = turbineBaseSpeed - rpmRateAdjustment | |
1661 | if newTurbineBaseSpeed < 908 then | |
1662 | newTurbineBaseSpeed = 908 | |
1663 | end | |
1664 | sideClick, xClick, yClick = 0, 0, 0 | |
1665 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["BaseSpeed"] = newTurbineBaseSpeed | |
1666 | config.save(turbineNames[turbineIndex]..".options", _G[turbineNames[turbineIndex]]) | |
1667 | elseif (xClick == 29) and (yClick == 6) and (sideClick == monitorNames[monitorIndex]) then | |
1668 | printLog("Increase to Turbine RPM requested by "..progName.." GUI in displayTurbineBars(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").") | |
1669 | rpmRateAdjustment = 909 | |
1670 | newTurbineBaseSpeed = turbineBaseSpeed + rpmRateAdjustment | |
1671 | if newTurbineBaseSpeed > 2726 then | |
1672 | newTurbineBaseSpeed = 2726 | |
1673 | end | |
1674 | sideClick, xClick, yClick = 0, 0, 0 | |
1675 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["BaseSpeed"] = newTurbineBaseSpeed | |
1676 | config.save(turbineNames[turbineIndex]..".options", _G[turbineNames[turbineIndex]]) | |
1677 | else | |
1678 | printLog("No change to Turbine RPM requested by "..progName.." GUI in displayTurbineBars(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").") | |
1679 | end -- if (xClick == 29) and (yClick == 4) and (sideClick == monitorNames[monitorIndex]) then | |
1680 | print{" mB/t",22,3,monitorIndex} | |
1681 | print{"< >",22,4,monitorIndex} | |
1682 | print{stringTrim(turbineFlowRate),24,4,monitorIndex} | |
1683 | print{" RPM",22,5,monitorIndex} | |
1684 | print{"< >",22,6,monitorIndex} | |
1685 | print{stringTrim(tonumber(_G[turbineNames[turbineIndex]]["TurbineOptions"]["BaseSpeed"])),24,6,monitorIndex} | |
1686 | local rotorSpeedString = "Speed: " | |
1687 | local energyBufferString = "Energy: " | |
1688 | local padding = math.max(string.len(rotorSpeedString), string.len(energyBufferString)) | |
1689 | ||
1690 | local energyBuffer = turbine.getEnergyProducedLastTick() | |
1691 | print{energyBufferString,1,4,monitorIndex} | |
1692 | print{math.ceil(energyBuffer).." RF/t",padding+1,4,monitorIndex} | |
1693 | ||
1694 | local rotorSpeed = math.ceil(turbine.getRotorSpeed()) | |
1695 | print{rotorSpeedString,1,5,monitorIndex} | |
1696 | print{rotorSpeed.." RPM",padding+1,5,monitorIndex} | |
1697 | ||
1698 | -- PaintUtils only outputs to term., not monitor. | |
1699 | -- See http://www.computercraft.info/forums2/index.php?/topic/15540-paintutils-on-a-monitor/ | |
1700 | ||
1701 | -- Draw stored energy buffer bar | |
1702 | drawBar(1,9,28,9,colors.gray,monitorIndex) | |
1703 | ||
1704 | local curStoredEnergyPercent = getTurbineStoredEnergyBufferPercent(turbine) | |
1705 | if curStoredEnergyPercent > 4 then | |
1706 | drawBar(1, 9, math.floor(26*curStoredEnergyPercent/100)+2, 9, colors.yellow,monitorIndex) | |
1707 | elseif curStoredEnergyPercent > 0 then | |
1708 | drawPixel(1, 9, colors.yellow, monitorIndex) | |
1709 | end -- if curStoredEnergyPercent > 4 then | |
1710 | ||
1711 | print{"Energy Buffer",1,8,monitorIndex} | |
1712 | print{curStoredEnergyPercent, width-(string.len(curStoredEnergyPercent)+2),8,monitorIndex} | |
1713 | print{"%",28,8,monitorIndex} | |
1714 | ||
1715 | -- Print rod override status | |
1716 | local turbineFlowRateOverrideStatus = "" | |
1717 | ||
1718 | print{"Flow Auto-adjust:",2,10,monitorIndex} | |
1719 | ||
1720 | if ((not _G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"]) or (_G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"] == "false")) then | |
1721 | turbineFlowRateOverrideStatus = "Enabled" | |
1722 | - | monitor.setCursorPos(1, height) |
1722 | + | |
1723 | - | monitor.write("< ") |
1723 | + | |
1724 | - | monitor.setCursorPos(width-1, height) |
1724 | + | |
1725 | - | monitor.write(" >") |
1725 | + | |
1726 | end -- if not reactorRodOverride then | |
1727 | ||
1728 | print{turbineFlowRateOverrideStatus, width - string.len(turbineFlowRateOverrideStatus) - 1, 10, monitorIndex} | |
1729 | monitor.setTextColor(colors.white) | |
1730 | ||
1731 | monitor.setTextColor(colors.blue) | |
1732 | printCentered(_G[turbineNames[turbineIndex]]["TurbineOptions"]["turbineName"],12,monitorIndex) | |
1733 | monitor.setTextColor(colors.white) | |
1734 | ||
1735 | -- Need equation to figure out rotor efficiency and display | |
1736 | end -- function displayTurbineBars(statusParams) | |
1737 | ||
1738 | ||
1739 | -- Display turbine status | |
1740 | local function turbineStatus(turbineIndex, monitorIndex) | |
1741 | -- Grab current monitor | |
1742 | local monitor = nil | |
1743 | ||
1744 | printLog("Called as turbineStatus(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..").") | |
1745 | ||
1746 | monitor = monitorList[monitorIndex] | |
1747 | if not monitor then | |
1748 | printLog("monitor["..monitorIndex.."] in turbineStatus(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..") is NOT a valid monitor.") | |
1749 | return -- Invalid monitorIndex | |
1750 | end | |
1751 | ||
1752 | -- Grab current turbine | |
1753 | local turbine = nil | |
1754 | turbine = turbineList[turbineIndex] | |
1755 | if not turbine then | |
1756 | printLog("turbine["..turbineIndex.."] in turbineStatus(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..") is NOT a valid Big Turbine.") | |
1757 | return -- Invalid turbineIndex | |
1758 | else | |
1759 | printLog("turbine["..turbineIndex.."] in turbineStatus(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..") is a valid Big Turbine.") | |
1760 | end | |
1761 | ||
1762 | local width, height = monitor.getSize() | |
1763 | local turbineStatus = "" | |
1764 | ||
1765 | if turbine.getConnected() then | |
1766 | printLog("turbine["..turbineIndex.."] in turbineStatus(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..") is connected.") | |
1767 | if turbine.getActive() then | |
1768 | turbineStatus = "ONLINE" | |
1769 | monitor.setTextColor(colors.green) | |
1770 | else | |
1771 | turbineStatus = "OFFLINE" | |
1772 | monitor.setTextColor(colors.red) | |
1773 | end -- if turbine.getActive() then | |
1774 | ||
1775 | if (xClick >= (width - string.len(turbineStatus) - 1)) and (xClick <= (width-1)) and (sideClick == monitorNames[monitorIndex]) then | |
1776 | if yClick == 1 then | |
1777 | turbine.setActive(not turbine.getActive()) -- Toggle turbine status | |
1778 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["autoStart"] = turbine.getActive() | |
1779 | config.save(turbineNames[turbineIndex]..".options", _G[turbineNames[turbineIndex]]) | |
1780 | sideClick, xClick, yClick = 0, 0, 0 -- Reset click after we register it | |
1781 | end -- if yClick == 1 then | |
1782 | end -- if (xClick >= (width - string.len(turbineStatus) - 1)) and (xClick <= (width-1)) and (sideClick == monitorNames[monitorIndex]) then | |
1783 | ||
1784 | -- Allow disabling/enabling flow rate auto-adjust | |
1785 | if (xClick > 23 and xClick < 28 and yClick == 4) and (sideClick == monitorNames[monitorIndex]) then | |
1786 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"] = true | |
1787 | sideClick, xClick, yClick = 0, 0, 0 -- Reset click after we register it | |
1788 | elseif (xClick > 20 and xClick < 27 and yClick == 10) and (sideClick == monitorNames[monitorIndex]) then | |
1789 | ||
1790 | if ((_G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"]) or (_G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"] == "true")) then | |
1791 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"] = false | |
1792 | else | |
1793 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"] = true | |
1794 | end | |
1795 | sideClick, xClick, yClick = 0, 0, 0 -- Reset click after we register it | |
1796 | end | |
1797 | config.save(turbineNames[turbineIndex]..".options", _G[turbineNames[turbineIndex]]) | |
1798 | ||
1799 | else | |
1800 | printLog("turbine["..turbineIndex.."] in turbineStatus(turbineIndex="..turbineIndex..",monitorIndex="..monitorIndex..") is NOT connected.") | |
1801 | turbineStatus = "DISCONNECTED" | |
1802 | monitor.setTextColor(colors.red) | |
1803 | end -- if turbine.getConnected() then | |
1804 | ||
1805 | print{turbineStatus, width - string.len(turbineStatus) - 1, 1, monitorIndex} | |
1806 | monitor.setTextColor(colors.white) | |
1807 | end -- function function turbineStatus(turbineIndex, monitorIndex) | |
1808 | ||
1809 | ||
1810 | -- Maintain Turbine flow rate at 900 or 1,800 RPM | |
1811 | local function flowRateControl(turbineIndex) | |
1812 | if ((not _G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"]) or (_G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"] == "false")) then | |
1813 | ||
1814 | printLog("Called as flowRateControl(turbineIndex="..turbineIndex..").") | |
1815 | ||
1816 | -- Grab current turbine | |
1817 | - | -- monitor switch controls |
1817 | + | |
1818 | - | monitor.setCursorPos(1, height) |
1818 | + | |
1819 | - | monitor.write("<") |
1819 | + | |
1820 | - | monitor.setCursorPos(width, height) |
1820 | + | |
1821 | - | monitor.write(">") |
1821 | + | |
1822 | local turbineBaseSpeed = tonumber(_G[turbineNames[turbineIndex]]["TurbineOptions"]["BaseSpeed"]) | |
1823 | ||
1824 | if not turbine then | |
1825 | printLog("turbine["..turbineIndex.."] in flowRateControl(turbineIndex="..turbineIndex..") is NOT a valid Big Turbine.") | |
1826 | return -- Invalid turbineIndex | |
1827 | else | |
1828 | printLog("turbine["..turbineIndex.."] in flowRateControl(turbineIndex="..turbineIndex..") is a valid Big Turbine.") | |
1829 | ||
1830 | if turbine.getConnected() then | |
1831 | printLog("turbine["..turbineIndex.."] in flowRateControl(turbineIndex="..turbineIndex..") is connected.") | |
1832 | else | |
1833 | printLog("turbine["..turbineIndex.."] in flowRateControl(turbineIndex="..turbineIndex..") is NOT connected.") | |
1834 | end -- if turbine.getConnected() then | |
1835 | end -- if not turbine then | |
1836 | ||
1837 | -- No point modifying control rod levels for temperature if the turbine is offline | |
1838 | if turbine.getActive() then | |
1839 | printLog("turbine["..turbineIndex.."] in flowRateControl(turbineIndex="..turbineIndex..") is active.") | |
1840 | ||
1841 | local flowRate = tonumber(_G[turbineNames[turbineIndex]]["TurbineOptions"]["LastFlow"]) | |
1842 | local flowRateUserMax = math.ceil(turbine.getFluidFlowRateMax()) | |
1843 | local rotorSpeed = math.ceil(turbine.getRotorSpeed()) | |
1844 | local newFlowRate = 0 | |
1845 | ||
1846 | -- Going to control the turbine based on target RPM since changing the target flow rate bypasses this function | |
1847 | if (rotorSpeed < turbineBaseSpeed) then | |
1848 | printLog("BELOW COMMANDED SPEED") | |
1849 | if (rotorSpeed > lastTurbineSpeed) then | |
1850 | --we're still increasing, let's let it level off | |
1851 | --also lets the first control pass go by on startup | |
1852 | elseif (rotorSpeed < lastTurbineSpeed) then | |
1853 | --we're decreasing where we should be increasing, do something | |
1854 | if ((lastTurbineSpeed - rotorSpeed) > 100) then | |
1855 | --kick it harder | |
1856 | newFlowRate = 2000 | |
1857 | printLog("HARD KICK") | |
1858 | else | |
1859 | --let's adjust based on proximity | |
1860 | flowAdjustment = (turbineBaseSpeed - rotorSpeed)/5 | |
1861 | newFlowRate = flowRate + flowAdjustment | |
1862 | printLog("Light Kick: new flow rate is "..newFlowRate.." mB/t and flowAdjustment was "..flowAdjustment.." EOL") | |
1863 | end | |
1864 | else | |
1865 | --we've stagnated, kick it. | |
1866 | flowAdjustment = (turbineBaseSpeed - lastTurbineSpeed) | |
1867 | newFlowRate = flowRate + flowAdjustment | |
1868 | printLog("Stagnated: new flow rate is "..newFlowRate.." mB/t and flowAdjustment was "..flowAdjustment.." EOL") | |
1869 | end --if (rotorSpeed > lastTurbineSpeed) then | |
1870 | else | |
1871 | --we're above commanded turbine speed | |
1872 | printLog("ABOVE COMMANDED SPEED") | |
1873 | if (rotorSpeed < lastTurbineSpeed) then | |
1874 | --we're decreasing, let it level off | |
1875 | --also bypasses first control pass on startup | |
1876 | elseif (rotorSpeed > lastTurbineSpeed) then | |
1877 | - | _G[reactorNames[reactorIndex]]["ReactorOptions"]["Status"] = reactorStatus |
1877 | + | |
1878 | if ((rotorSpeed - lastTurbineSpeed) > 100) then | |
1879 | --halt | |
1880 | newFlowRate = 25 | |
1881 | else | |
1882 | --let's adjust based on proximity | |
1883 | flowAdjustment = (rotorSpeed - turbineBaseSpeed)/5 | |
1884 | - | -- Display all found reactors' status to selected monitor |
1884 | + | |
1885 | printLog("Light Kick: new flow rate is "..newFlowRate.." mB/t and flowAdjustment was "..flowAdjustment.." EOL") | |
1886 | - | local function displayAllStatus(monitorIndex) |
1886 | + | |
1887 | else | |
1888 | --we've stagnated, kick it. | |
1889 | flowAdjustment = (lastTurbineSpeed - turbineBaseSpeed) | |
1890 | newFlowRate = flowRate - flowAdjustment | |
1891 | printLog("Stagnated: new flow rate is "..newFlowRate.." mB/t and flowAdjustment was "..flowAdjustment.." EOL") | |
1892 | end --if (rotorSpeed < lastTurbineSpeed) then | |
1893 | end --if (rotorSpeed < turbineBaseSpeed) | |
1894 | ||
1895 | - | local monitor = monitorList[monitorIndex] |
1895 | + | |
1896 | if (newFlowRate == 0) then | |
1897 | --do nothing, we didn't ask for anything this pass | |
1898 | else | |
1899 | --boundary check | |
1900 | if newFlowRate > 2000 then | |
1901 | newFlowRate = 2000 | |
1902 | elseif newFlowRate < 25 then | |
1903 | newFlowRate = 25 -- Don't go to zero, might as well power off | |
1904 | end -- if newFlowRate > 2000 then | |
1905 | --no sense running an adjustment if it's not necessary | |
1906 | if ((newFlowRate < flowRate) or (newFlowRate > flowRate)) then | |
1907 | printLog("turbine["..turbineIndex.."] in flowRateControl(turbineIndex="..turbineIndex..") is being commanded to "..newFlowRate.." mB/t flow") | |
1908 | newFlowRate = round(newFlowRate, 0) | |
1909 | turbine.setFluidFlowRateMax(newFlowRate) | |
1910 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["LastFlow"] = newFlowRate | |
1911 | config.save(turbineNames[turbineIndex]..".options", _G[turbineNames[turbineIndex]]) | |
1912 | end | |
1913 | end | |
1914 | --always set this | |
1915 | _G[turbineNames[turbineIndex]]["TurbineOptions"]["LastSpeed"] = rotorSpeed | |
1916 | config.save(turbineNames[turbineIndex]..".options", _G[turbineNames[turbineIndex]]) | |
1917 | else | |
1918 | printLog("turbine["..turbineIndex.."] in flowRateControl(turbineIndex="..turbineIndex..") is NOT active.") | |
1919 | end -- if turbine.getActive() then | |
1920 | else | |
1921 | printLog("turbine["..turbineIndex.."] has flow override set to "..tostring(_G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"])..", bypassing flow control.") | |
1922 | end -- if not _G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"] then | |
1923 | end -- function flowRateControl(turbineIndex) | |
1924 | ||
1925 | ||
1926 | function main() | |
1927 | -- Load reactor parameters and initialize systems | |
1928 | loadReactorOptions() | |
1929 | ||
1930 | -- Get our initial list of connected monitors and reactors | |
1931 | -- and initialize every cycle in case the connected devices change | |
1932 | findMonitors() | |
1933 | findReactors() | |
1934 | findTurbines() | |
1935 | ||
1936 | while not finished do | |
1937 | local reactor = nil | |
1938 | local monitorIndex = 1 | |
1939 | ||
1940 | -- For multiple reactors/monitors, monitor #1 is reserved for overall status | |
1941 | -- or for multiple reactors/turbines and only one monitor | |
1942 | if ( ( ((#reactorList + #turbineList) > 1) and (#monitorList >= 1) ) or | |
1943 | ( ((#reactorList + #turbineList) >=1) and (#monitorList > 1) ) ) then | |
1944 | local monitor = nil | |
1945 | monitor = monitorList[monitorIndex] | |
1946 | if not monitor then | |
1947 | printLog("monitor["..monitorIndex.."] in main() is NOT a valid monitor.") | |
1948 | return -- Invalid monitorIndex | |
1949 | end | |
1950 | ||
1951 | clearMonitor(progName.." "..progVer, monitorIndex) -- Clear monitor and draw borders | |
1952 | printCentered(progName.." "..progVer, 1, monitorIndex) | |
1953 | displayAllStatus() | |
1954 | monitorIndex = 2 -- Next monitor, #1 is reserved for overall status | |
1955 | end | |
1956 | ||
1957 | -- Iterate through reactors, continue to run even if not enough monitors are connected | |
1958 | for reactorIndex = 1, #reactorList do | |
1959 | local monitor = nil | |
1960 | local reactorMonitorIndex = monitorIndex + reactorIndex - 1 -- reactorIndex starts at 1 | |
1961 | ||
1962 | printLog("Attempting to display reactor["..reactorIndex.."] on monitor["..reactorMonitorIndex.."]...") | |
1963 | ||
1964 | reactor = reactorList[reactorIndex] | |
1965 | if not reactor then | |
1966 | printLog("reactor["..reactorIndex.."] in main() is NOT a valid Big Reactor.") | |
1967 | break -- Invalid reactorIndex | |
1968 | else | |
1969 | printLog("reactor["..reactorIndex.."] in main() is a valid Big Reactor.") | |
1970 | end -- if not reactor then | |
1971 | ||
1972 | -- Only attempt to assign a monitor if we have a monitor for this reactor | |
1973 | if (reactorMonitorIndex <= #monitorList) then | |
1974 | printLog("Displaying reactor["..reactorIndex.."] on monitor["..reactorMonitorIndex.."].") | |
1975 | monitor = monitorList[reactorMonitorIndex] | |
1976 | ||
1977 | if not monitor then | |
1978 | printLog("monitor["..reactorMonitorIndex.."] in main() is NOT a valid monitor.") | |
1979 | else | |
1980 | clearMonitor(progName, reactorMonitorIndex) -- Clear monitor and draw borders | |
1981 | printCentered(progName, 1, reactorMonitorIndex) | |
1982 | ||
1983 | -- Display reactor status, includes "Disconnected" but found reactors | |
1984 | reactorStatus{reactorIndex, reactorMonitorIndex} | |
1985 | ||
1986 | - | printCentered("Buffer: "..formatReadableSIUnit(math.ceil(totalEnergy)).."/"..formatReadableSIUnit(totalMaxEnergyStored).." RF", 12, monitorIndex) |
1986 | + | -- Draw the borders and bars for the current reactor on the current monitor |
1987 | displayReactorBars{reactorIndex, reactorMonitorIndex} | |
1988 | - | -- monitor switch controls |
1988 | + | end -- if not monitor |
1989 | else | |
1990 | - | monitor.setCursorPos(1, height) |
1990 | + | printLog("You may want "..(#reactorList + #turbineList + 1).." monitors for your "..#reactorList.." connected reactors and "..#turbineList.." connected turbines.") |
1991 | - | monitor.write("<") |
1991 | + | end -- if (#monitorList ~= 1) and (reactorMonitorIndex < #monitorList) then |
1992 | - | monitor.setCursorPos(width, height) |
1992 | + | |
1993 | - | monitor.write(">") |
1993 | + | |
1994 | printLog("reactor["..reactorIndex.."] is connected.") | |
1995 | local curStoredEnergyPercent = getReactorStoredEnergyBufferPercent(reactor) | |
1996 | ||
1997 | -- Shutdown reactor if current stored energy % is >= desired level, otherwise activate | |
1998 | -- First pass will have curStoredEnergyPercent=0 until displayBars() is run once | |
1999 | if curStoredEnergyPercent >= maxStoredEnergyPercent then | |
2000 | reactor.setActive(false) | |
2001 | -- Do not auto-start the reactor if it was manually powered off (autoStart=false) | |
2002 | elseif (curStoredEnergyPercent <= minStoredEnergyPercent) and (_G[reactorNames[reactorIndex]]["ReactorOptions"]["autoStart"] == true) then | |
2003 | reactor.setActive(true) | |
2004 | end -- if curStoredEnergyPercent >= maxStoredEnergyPercent then | |
2005 | ||
2006 | -- Don't try to auto-adjust control rods if manual control is requested | |
2007 | if not _G[reactorNames[reactorIndex]]["ReactorOptions"]["rodOverride"] then | |
2008 | temperatureControl(reactorIndex) | |
2009 | end -- if not reactorRodOverride then | |
2010 | else | |
2011 | printLog("reactor["..reactorIndex.."] is NOT connected.") | |
2012 | end -- if reactor.getConnected() then | |
2013 | end -- for reactorIndex = 1, #reactorList do | |
2014 | ||
2015 | -- Monitors for turbines start after turbineMonitorOffset | |
2016 | for turbineIndex = 1, #turbineList do | |
2017 | local monitor = nil | |
2018 | local turbineMonitorIndex = turbineIndex + turbineMonitorOffset | |
2019 | ||
2020 | printLog("Attempting to display turbine["..turbineIndex.."] on monitor["..turbineMonitorIndex.."]...") | |
2021 | ||
2022 | -- Only attempt to assign a monitor if we found a monitor for this turbine | |
2023 | if (turbineMonitorIndex <= #monitorList) then | |
2024 | printLog("Displaying turbine["..turbineIndex.."] on monitor["..turbineMonitorIndex.."].") | |
2025 | monitor = monitorList[turbineMonitorIndex] | |
2026 | if not monitor then | |
2027 | printLog("monitor["..turbineMonitorIndex.."] in main() is NOT a valid monitor.") | |
2028 | else | |
2029 | clearMonitor(progName, turbineMonitorIndex) -- Clear monitor and draw borders | |
2030 | printCentered(progName, 1, turbineMonitorIndex) | |
2031 | ||
2032 | -- Display turbine status, includes "Disconnected" but found turbines | |
2033 | turbineStatus(turbineIndex, turbineMonitorIndex) | |
2034 | ||
2035 | -- Draw the borders and bars for the current turbine on the current monitor | |
2036 | displayTurbineBars(turbineIndex, turbineMonitorIndex) | |
2037 | end -- if not monitor | |
2038 | - | monitor.setCursorPos(1, height) |
2038 | + | |
2039 | - | monitor.write("< ") |
2039 | + | printLog("You may want "..(#reactorList + #turbineList + 1).." monitors for your "..#reactorList.." connected reactors and "..#turbineList.." connected turbines.") |
2040 | - | monitor.setCursorPos(width-1, height) |
2040 | + | end -- if (#monitorList ~= 1) and (turbineMonitorIndex < #monitorList) then |
2041 | - | monitor.write(" >") |
2041 | + | |
2042 | turbine = turbineList[turbineIndex] | |
2043 | if not turbine then | |
2044 | printLog("turbine["..turbineIndex.."] in main() is NOT a valid Big Turbine.") | |
2045 | break -- Invalid turbineIndex | |
2046 | else | |
2047 | printLog("turbine["..turbineIndex.."] in main() is a valid Big Turbine.") | |
2048 | end -- if not turbine then | |
2049 | ||
2050 | if turbine.getConnected() then | |
2051 | printLog("turbine["..turbineIndex.."] is connected.") | |
2052 | - | local steamBufferString = "Steam: " |
2052 | + | |
2053 | - | local padding = math.max(string.len(rotorSpeedString), string.len(energyBufferString), string.len(steamBufferString)) |
2053 | + | if not _G[turbineNames[turbineIndex]]["TurbineOptions"]["flowOverride"] then |
2054 | flowRateControl(turbineIndex) | |
2055 | end -- if not turbineFlowRateOverride[turbineIndex] then | |
2056 | else | |
2057 | printLog("turbine["..turbineIndex.."] is NOT connected.") | |
2058 | end -- if turbine.getConnected() then | |
2059 | end -- for reactorIndex = 1, #reactorList do | |
2060 | ||
2061 | sleep(loopTime) -- Sleep | |
2062 | saveReactorOptions() | |
2063 | - | local steamBuffer = turbine.getFluidFlowRate() |
2063 | + | |
2064 | - | print{steamBufferString,1,6,monitorIndex} |
2064 | + | |
2065 | - | print{steamBuffer.." mB/t",padding+1,6,monitorIndex} |
2065 | + | |
2066 | ||
2067 | local function eventHandler() | |
2068 | while not finished do | |
2069 | -- http://computercraft.info/wiki/Os.pullEvent | |
2070 | -- http://www.computercraft.info/forums2/index.php?/topic/1516-ospullevent-what-is-it-and-how-is-it-useful/ | |
2071 | event, arg1, arg2, arg3 = os.pullEvent() | |
2072 | ||
2073 | if event == "monitor_touch" then | |
2074 | sideClick, xClick, yClick = arg1, math.floor(arg2), math.floor(arg3) | |
2075 | printLog("Side: "..arg1.." Monitor touch X: "..xClick.." Y: "..yClick) | |
2076 | elseif event == "char" and not inManualMode then | |
2077 | local ch = string.lower(arg1) | |
2078 | if ch == "q" then | |
2079 | finished = true | |
2080 | elseif ch == "r" then | |
2081 | finished = true | |
2082 | os.reboot() | |
2083 | end -- if ch == "q" then | |
2084 | end -- if event == "monitor_touch" then | |
2085 | end -- while not finished do | |
2086 | end -- function eventHandler() | |
2087 | ||
2088 | ||
2089 | while not finished do | |
2090 | parallel.waitForAny(eventHandler, main) | |
2091 | sleep(loopTime) | |
2092 | end -- while not finished do | |
2093 | ||
2094 | ||
2095 | -- Clear up after an exit | |
2096 | term.clear() | |
2097 | term.setCursorPos(1,1) |