View difference between Paste ID: E4Fn29VJ and DJWnFyes
SHOW: | | - or go back to the newest paste.
1
-- Mendenbarr's Big Reactor control script, adapted from http://pastebin.com/FHnfkprx, courtesy of Lyqyd. 
2
-- Tries to add in support for a large reactor with many turbines, turning the reactor off and on as needed to support the number of turbines connected. 
3
4
local modemSide, reactorSide
5
6
for _, side in ipairs(rs.getSides()) do
7
	if peripheral.getType(side) == "modem" then
8
		local wirelessMethod = false
9
		for i, method in ipairs(peripheral.getMethods(side)) do
10
			if method == "isWireless" then
11
				wirelessMethod = true
12
				if peripheral.call(side, "isWireless") then
13
					modemSide = side
14
				end
15
				break
16
			end
17
		end
18
		if not wirelessMethod then
19
			modemSide = side
20
		end
21
	elseif peripheral.getType(side) == "BigReactors-Reactor" then
22
		reactorSide = side
23
	end
24
	if modemSide and reactorSide then break end
25
end
26
27
local modem, reactor
28
29
if modemSide then
30
	rednet.open(modemSide)
31
	modem = peripheral.wrap(modemSide)
32
end
33
if reactorSide then
34
	reactor = peripheral.wrap(reactorSide)
35
else
36
	error("No Reactor Found")
37
end
38
39
local function sendUpdate(id, message)
40
	if modemSide then
41
		rednet.send(id, message)
42
	end
43
end
44
45
local function average(tab)
46
	local average = 0
47
	for i = 1, #tab do
48
		average = average + tab[i]
49
	end
50
	return average / #tab
51
end
52
53
local function pollInformation(reactor)
54
	local information = {}
55
	information.reactor = {}
56
	information.fuel = {}
57
	information.rods = {}
58
	information.cooling = {}
59
	information.power = {}
60
	do
61
		information.reactor.active = reactor.getActive()
62
		information.reactor.activeCooling = reactor.isActivelyCooled()
63
		information.reactor.temperature = reactor.getCasingTemperature()
64
	end
65
	do
66
		information.fuel.fuelAmount = reactor.getFuelAmount()
67
		information.fuel.wasteAmount = reactor.getWasteAmount()
68
		information.fuel.max = reactor.getFuelAmountMax()
69
		information.fuel.reactivity = reactor.getFuelReactivity()
70
		information.fuel.consumption = reactor.getFuelConsumedLastTick()
71
		information.fuel.temperature = reactor.getFuelTemperature()
72
	end
73
	do
74
		information.rods.count = reactor.getNumberOfControlRods()
75
		information.rods.levels = {}
76
		for i = 1, information.rods.count do
77
			information.rods.levels[i] = reactor.getControlRodLevel(i - 1)
78
		end
79
		information.rods.average = average(information.rods.levels)
80
	end
81
	if information.reactor.activeCooling then
82
		information.cooling.coldType = reactor.getCoolantType()
83
		information.cooling.coldAmount = reactor.getCoolantAmount()
84
		information.cooling.hotType = reactor.getHotFluidType()
85
		information.cooling.hotAmount = reactor.getHotFluidAmount()
86
		information.cooling.hotProduced = reactor.getHotFluidProducedLastTick()
87
	end
88
	if not information.reactor.activeCooling then
89
		information.power.produced = reactor.getEnergyProducedLastTick()
90
		information.power.stored = reactor.getEnergyStored()
91
		information.power.percentage = math.floor(information.power.stored / 100000)
92
	end
93
	return information
94
end
95
96
local settings = {
97
	rods = {
98
		setpoint = 0,
99
		maximum = 100,
100
		minimum = 0,
101
		mode = "auto",
102
		--values are auto, operator, startup.
103
	},
104
	reactor = {
105
		active = true,
106
	},
107
	general = {
108
		slowStartTickDelayCount = 4,
109
		slowStartSteamTickDelayCount = 20,
110
	},
111
	turbines = {
112
		count = 3,
113
	}
114
}
115
116
local startupCount = 0
117
local lastRodsSetting
118
119
local function printCenter(text)
120
	text = tostring(text)
121
	local x, y = term.getSize()
122
	local xCur, yCur = term.getCursorPos()
123
	term.setCursorPos((x - #text) / 2 + 1, yCur)
124
	term.write(text)
125
end
126
127
local function displayScreen(info)
128
	local x, y = term.getSize()
129
	local column = math.ceil(x / 2)
130
	term.setBackgroundColor(term.isColor() and colors.gray or colors.black)
131
	term.setTextColor(colors.white)
132
	term.clear()
133
	do
134
		term.setCursorPos(2, 3)
135
		term.write("Temperature:")
136
		term.setCursorPos(2, 4)
137
		term.write("Core: "..info.fuel.temperature)
138
		term.setCursorPos(2, 5)
139
		term.write("Case: "..info.reactor.temperature)
140
	end
141
	do
142
		term.setCursorPos(2, 7)
143
		term.write("Fuel:")
144
		term.setCursorPos(2, 8)
145
		term.write("Fuel Level: "..tostring(info.fuel.fuelAmount).." mB")
146
		term.setCursorPos(2, 9)
147
		term.write("Waste Level: "..tostring(info.fuel.wasteAmount).." mB")
148
		term.setCursorPos(2, 10)
149
		term.write("Total: "..tostring(info.fuel.fuelAmount + info.fuel.wasteAmount).." mB")
150
		term.setCursorPos(2, 11)
151
		term.write("Capacity: "..tostring(info.fuel.max).." mB")
152
		term.setCursorPos(2, 12)
153
		term.write("Consumed: "..string.match(string.format("%f", info.fuel.consumption).."0000", "(%d+%.%d%d%d%d)").." mB/t")
154
		term.setCursorPos(2, 13)
155
		term.write("Reactivity: "..string.match(string.format("%f", info.fuel.reactivity).."00", "(%d+%.%d%d)").."%")
156
	end
157
	do
158
		term.setCursorPos(column, 3)
159
		term.write("Control Rods:")
160
		term.setCursorPos(column, 4)
161
		term.write("Actual: "..tostring(info.rods.average).."%")
162
		term.setCursorPos(column, 5)
163
		term.write("Setpoint: "..tostring(settings.rods.setpoint).."%")
164
		do
165
			if term.isColor() then term.setBackgroundColor(colors.red) end
166
			term.setCursorPos(column, 6)
167
			term.write("--")
168
			term.setCursorPos(column + 3, 6)
169
			term.write("-")
170
			if term.isColor() then term.setBackgroundColor(colors.yellow) end
171
			term.setCursorPos(column + 5, 6)
172
			term.write("=")
173
			if term.isColor() then term.setBackgroundColor(colors.lime) end
174
			term.setCursorPos(column + 7, 6)
175
			term.write("+")
176
			term.setCursorPos(column + 9, 6)
177
			term.write("++")
178
			if term.isColor() then term.setBackgroundColor(colors.blue) end
179
			term.setCursorPos(column + 12, 6)
180
			term.write("A")
181
			if term.isColor() then term.setBackgroundColor(colors.gray) end
182
		end
183
	end
184
	if info.reactor.activeCooling then
185
		--active cooling set
186
		term.setCursorPos(column, 8)
187
		term.write("Cooling:")
188
		term.setCursorPos(column, 9)
189
		term.write("Steam Output: "..tostring(info.cooling.hotProduced).." mB/t")
190
		term.setCursorPos(column, 10)
191
		term.write("Steam Level: "..tostring(info.cooling.hotAmount).." mB")
192
		term.setCursorPos(column, 11)
193
		term.write("Water Level: "..tostring(info.cooling.coldAmount).." mB")
194
	else
195
		--passive cooling set
196
		term.setCursorPos(column, 8)
197
		term.write("Power:")
198
		term.setCursorPos(column, 9)
199
		term.write("RF Output: "..tostring(math.floor(info.power.produced)).." RF/t")
200
		term.setCursorPos(column, 10)
201
		term.write("RF Stored: "..tostring(info.power.stored).." RF")
202
		term.setCursorPos(column, 11)
203
		term.write("RF % Full: "..tostring(info.power.percentage).."%")
204
	end
205
end
206
207
local function handleScreen(event)
208
	if event[1] == "mouse_click" then
209
		local x, y = term.getSize()
210
		local column = math.ceil(x / 2)
211
		if event[4] == 6 then
212
			if event[3] == column or event[3] == column + 1 then
213
				if event[2] == 1 then
214
					settings.rods.setpoint = math.max(0, settings.rods.setpoint - 10)
215
					settings.rods.mode = "operator"
216
				elseif event[2] == 2 then
217
					settings.rods.setpoint = 0
218
					settings.rods.mode = "operator"
219
				end
220
			elseif event[3] == column + 3 then
221
				settings.rods.setpoint = math.max(0, settings.rods.setpoint - 1)
222
				settings.rods.mode = "operator"
223
			elseif event[3] == column + 5 then
224
				settings.rods.setpoint = lastRodsSetting
225
				settings.rods.mode = "operator"
226
			elseif event[3] == column + 7 then
227
				settings.rods.setpoint = math.min(100, settings.rods.setpoint + 1)
228
				settings.rods.mode = "operator"
229
			elseif event[3] == column + 9 or event[3] == column + 10 then
230
				if event[2] == 1 then
231
					settings.rods.setpoint = math.min(100, settings.rods.setpoint + 10)
232
					settings.rods.mode = "operator"
233
				elseif event[2] == 2 then
234
					settings.rods.setpoint = 100
235
					settings.rods.mode = "operator"
236
				end
237
			elseif event[3] == column + 12 then
238
				settings.rods.mode = "auto"
239
			end
240
		end
241
	elseif event[1] == "char" then
242
		if event[2] == "-" then
243
			settings.rods.setpoint = math.max(0, settings.rods.setpoint - 1)
244
			settings.rods.mode = "operator"
245
		elseif event[2] == "=" then
246
			settings.rods.setpoint = lastRodsSetting
247
			settings.rods.mode = "operator"
248
		elseif event[2] == "+" then
249
			settings.rods.setpoint = math.min(100, settings.rods.setpoint + 1)
250
			settings.rods.mode = "operator"
251
		elseif string.lower(event[2]) == "a" then
252
			settings.rods.mode = "auto"
253
		end
254
	end
255
end
256
257
local function setRods(setpoint)
258
	if setpoint ~= lastRodsSetting then
259
		reactor.setAllControlRodLevels(math.max(settings.rods.minimum, math.min(settings.rods.maximum, setpoint)))
260
		sendUpdate(masterControl, "rods.actual:"..tostring(setpoint))
261
		lastRodsSetting = setpoint
262
	end
263
end
264
265
local tickRods = {
266
	operator = function(info)
267
		setRods(settings.rods.setpoint)
268
	end,
269
	startup = function(info)
270
		startupCount = startupCount + 1
271
		if info.power.percentage < info.rods.average then
272
			if startupCount >= settings.general.slowStartTickDelayCount then
273
				setRods(info.rods.average - 1)
274
				startupCount = 0
275
			end
276
		else
277-
			if information.reactor.activeCooling == false then
277+
278-
				setRods(info.power.percentage)
278+
279-
			else
279+
280-
				setActive(information.cooling.hotProduced < settings.turbines.count * 2000)
280+
281
	end,
282
	auto = function(info)
283
		setActive(information.cooling.hotProduced < settings.turbines.count * 2000)
284
	end,
285
	steamStartup = function(info)
286
		--
287-
		if information.reactor.activeCooling == false then
287+
288-
			setRods(info.power.percentage)
288+
289
290
if fs.exists("reactorsettings") then
291
	dofile("reactorsettings")
292-
		
292+
293
294
local reactorTick = os.startTimer(0.5)
295
print("Reactor Control Started")
296
297
while true do
298
	local info = pollInformation(reactor)
299
	displayScreen(info)
300
	local event = {os.pullEvent()}
301
	if event[1] == "rednet_message" then
302
		if event[2] == masterControl then
303
			if event[3] == "stop" then
304
				print("Received STOP command")
305
				settings.reactor.active = false
306
				sendUpdate(masterControl, "reactor.active:false")
307
				reactor.setActive(false)
308
			elseif event[3] == "start" then
309
				print("Received START command")
310
				settings.reactor.active = true
311
				sendUpdate(masterControl, "reactor.active:true")
312
				reactor.setActive(true)
313
				reactor.setAllControlRodLevels(99)
314
				settings.rods.mode = "startup"
315
				sendUpdate(masterControl, "rods.mode:startup")
316
				print("Reactor in STARTUP mode")
317
				startupCount = 0
318
				reactorTick = os.startTimer(0.5)
319
			end
320
		end
321
	elseif event[1] == "timer" then
322
		if event[2] == reactorTick then
323
			if tickRods[settings.rods.mode] then
324
				tickRods[settings.rods.mode](info)
325
			end
326
			reactorTick = os.startTimer(0.5)
327
		end
328
	else
329
		handleScreen(event)
330
	end
331
end