View difference between Paste ID: DJWnFyes and FHnfkprx
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-
		setRods(info.power.percentage)
277+
			if information.reactor.activeCooling == false then
278
				setRods(info.power.percentage)
279
			else
280
				setActive(information.cooling.hotProduced < settings.turbines.count * 2000)
281
			end
282
			settings.rods.mode = "auto"
283
			print("Reactor in AUTO mode")
284
		end
285
	end,
286
	auto = function(info)
287
		if information.reactor.activeCooling == false then
288
			setRods(info.power.percentage)
289
		else
290
			setActive(information.cooling.hotProduced < settings.turbines.count * 2000)
291
		end
292
		
293
	end,
294
	steamStartup = function(info)
295
		--
296
	end,
297
}
298
299
if fs.exists("reactorsettings") then
300
	dofile("reactorsettings")
301
end
302
303
local reactorTick = os.startTimer(0.5)
304
print("Reactor Control Started")
305
306
while true do
307
	local info = pollInformation(reactor)
308
	displayScreen(info)
309
	local event = {os.pullEvent()}
310
	if event[1] == "rednet_message" then
311
		if event[2] == masterControl then
312
			if event[3] == "stop" then
313
				print("Received STOP command")
314
				settings.reactor.active = false
315
				sendUpdate(masterControl, "reactor.active:false")
316
				reactor.setActive(false)
317
			elseif event[3] == "start" then
318
				print("Received START command")
319
				settings.reactor.active = true
320
				sendUpdate(masterControl, "reactor.active:true")
321
				reactor.setActive(true)
322
				reactor.setAllControlRodLevels(99)
323
				settings.rods.mode = "startup"
324
				sendUpdate(masterControl, "rods.mode:startup")
325
				print("Reactor in STARTUP mode")
326
				startupCount = 0
327
				reactorTick = os.startTimer(0.5)
328
			end
329
		end
330
	elseif event[1] == "timer" then
331
		if event[2] == reactorTick then
332
			if tickRods[settings.rods.mode] then
333
				tickRods[settings.rods.mode](info)
334
			end
335
			reactorTick = os.startTimer(0.5)
336
		end
337
	else
338
		handleScreen(event)
339
	end
340
end