View difference between Paste ID: we4y9Lz8 and JxLqMr2g
SHOW: | | - or go back to the newest paste.
1
--
2
-- Control passive cooled Big Reactor (http://big-reactors.com/).
3
--
4
-- Author: kla_sch
5
-- post: http://www.computercraft.info/forums2/index.php?/topic/18515-control-passive-cooled-big-reactors/
6
--
7
-- History:
8
--	  v0.1, 2014-05-05:
9
--			first version
10
--
11
-- Remarks:
12
--	  Reactor API: http://big-reactors.com/cc_api.html
13
--
14
15
-- -------------------------------
16
-- Constant values (configuration)
17
--
18
-- Critical energy mark: give us the maximum power.
19
critEnergy=3000000
20
-- Low energy mark: turn reactor on to get more energy
21
lowEnergy=7000000
22
-- Heigh energy mark: we have enough, so turn the reactor off.
23
highEnergy=9000000
24
-- Refresh delay (seconds)
25
delay=5
26
-- Peripheriques
27
pList = peripheral.getNames()
28
29
30
--
31
-- Calculate the control rod level (in %) by stored energy of internal
32
-- recator cell.
33
--
34
-- * If cellEnergy <= critEnergy, the calculation results in maximum
35
--	energy generation (control rod level = 0%).
36
-- * If cellEnergy >= highEnergy, the calculation results in 10% energy
37
--	generation (control rod level = 90%).
38
--
39
-- Parameters:
40
--	  cellEnergy - stored energy of internal cell in RF
41
--
42
-- Return:
43
--	  New control rod level in %.
44
--
45
function calcRodLevel(cellEnergy)
46
	-- Delta between critical and heigh energy mark
47
	local deltaEnergy = highEnergy - critEnergy 
48
49
	-- Calculated maximum delta energy (not the real maximum), so that
50
	-- the high energy mark results into a control rod level of 90%
51
	local deltaEnergy100 = deltaEnergy * 100 / 90
52
53
	-- Energy for calculation: value between 0 and 'deltaEnergy'
54
	local calcEnergy = cellEnergy - critEnergy
55
56
	if calcEnergy < 0 then
57
		calcEnergy = 0
58
	elseif calcEnergy > deltaEnergy then
59
		calcEnergy = deltaEnergy
60
	end
61
62
	-- Calculate control rod level and round the result (math.floor + 0.5)
63
	return math.floor(calcEnergy * 100 / deltaEnergy100 + 0.5)
64
end
65
66
67
--
68
-- Write text with colors, if possible (advance monitor)
69
--
70
-- Parameters:
71
--	  mon	- handle of monitor
72
--	  color - text color
73
--	  text  - text to write
74
--
75
function writeColor(mon, color, text, bgcolor)
76
 bgcolor = bgcolor == nil and colors.black or bgcolor
77
	if (mon.isColor()) then
78
		mon.setTextColor(color)
79
		mon.setBackgroundColor(bgcolor)
80
	end
81
	mon.write(text)
82
	if (mon.isColor()) then
83
		mon.setTextColor(colors.white)
84
		mon.setBackgroundColor(colors.black)
85
	end
86
end
87
function resetColor(mon)
88
	mon.setTextColor(1)
89
	mon.setBackgroundColor(colors.black)
90
end
91
function clearSquare(mon, x, y, w, h)
92
	resetColor(mon)
93
	for _h=1,h do
94
		mon.setCursorPos(x,y+_h-1)
95
		mon.write(string.rep(" ",w))
96
	end
97
end
98
99
--
100-
	mon.clear()
100+
101
--
102
-- Parameters:
103
--	  mon		  - handle of monitor.
104
--	  state		- state of reactor (on/off)
105
--	  rodLvl	  - Level of control rods in %
106
--	  cellEnergy - stored energy of internal cell (in RF)
107
--
108
function displayStatusToMonitor(mon, state, rodLvl, cellEnergy)
109
	clearSquare(mon, 1, 3, 15, 3)
110
111
	-- First get the monitor size and try to scale, if the feature ist
112
	-- available.
113
	if mon.setTextScale ~= nil then
114
		-- reset text scale
115
		mon.setTextScale(1)
116
	end
117
118
	local width, height = mon.getSize()
119
	if width < 15 or height < 5 then
120
		-- too small: try to scale down.
121
		if mon.setTextScale ~= nil then
122
			mon.setTextScale(0.5)
123
		else
124
			return -- too small und no text scale available
125
		end
126
127
		width, height = mon.getSize()
128
		if width < 15 or height < 5 then
129
			return -- still too small
130
		end
131
	else
132
		-- Huge monitors? Try to scale up, if possible (max scale=5).
133
		local scale = math.min(width / 16, height / 5, 5)
134
		scale = math.floor(scale * 2) / 2 -- multiple of 0.5 
135
136
		if scale > 1 and mon.setTextScale ~= nil then
137
			mon.setTextScale(scale)
138
			width, height = mon.getSize()
139
		end
140
	end
141
142
143
	--
144
	-- Output the data
145
	--
146
	mon.setCursorPos(1,1)
147
	mon.write("Reactor")
148
149
	mon.setCursorPos(1,3)
150
	mon.write("Status ")
151
152
	if state then
153
		writeColor(mon, colors.green, "ON")
154
	else
155
		writeColor(mon, colors.red, "OFF")
156
	end
157
158
	mon.setCursorPos(1,4)
159
	mon.write("Rod Level: " .. rodLvl .. "%")
160
161
	mon.setCursorPos(1,5)
162
	if width < 16 then
163
		mon.write("Cell: ") -- One block monitor (15x5 with scale 0.5)
164
	else
165
		mon.write("Energy: ")
166
	end
167
168
	local c
169
	if cellEnergy < critEnergy then
170
		c = colors.red -- Red: We use too much energy
171
	elseif cellEnergy > lowEnergy then
172
		c = colors.green -- Green: More energy then low water mark
173
	else
174
		c = colors.orange -- Orange: Less energy the low water mark, but OK
175
	end
176
	writeColor(mon, c, string.format("%d", math.floor(cellEnergy/1000 + 0.5)))
177
	mon.write(" kRF")
178
end
179
180
181
--
182
-- Display reactor status to any connected monitor and also to console.
183
--
184
-- Parameters:
185
--	  state		- state of reactor (on/off)
186-
	local pList = peripheral.getNames()
186+
187
--	  cellEnergy - stored energy of internal energy cell in RF
188
--
189
function displayStatus(state, rodLvl, cellEnergy)
190
	displayStatusToMonitor(term, state, rodLvl, cellEnergy) -- console
191
	term.setCursorPos(1,17)
192
	writeColor(term, colors.lightGray, "* Hold Crtl-T to terminate program")
193
	term.setCursorPos(1,8)
194
195
	local i, name
196
	for i, name in pairs(pList) do
197
		if peripheral.getType(name) == "monitor" then
198
			-- found monitor as peripheral
199
			displayStatusToMonitor(peripheral.wrap(name), state, rodLvl, cellEnergy)
200
		end
201
	end
202
end
203
204
205
--
206-
	local pList = peripheral.getNames()
206+
207
--
208
-- If no reactor was found this function terminate the program.
209
--
210
-- Return:
211
--	  Handle of first connected reactor found.
212
--
213
function getReactorHandle()
214
	local i, name
215
	for i, name in pairs(pList) do
216
		if peripheral.getType(name) == "BigReactors-Reactor" then
217
			return peripheral.wrap(name)
218
		end
219
	end
220
221
	error("No big reactor connected: Exit program")
222
	exit()
223
end
224
225
function main()
226
	reactor = getReactorHandle()
227
228
	--
229
	-- Endless loop: Recalculate rod level, set rod level, display result
230
	-- and wait for 5 secounds.
231
	--
232
	while true do
233
		cellEnergy = reactor.getEnergyStored()
234
		if cellEnergy < lowEnergy then
235
			-- Low energy: switch reactor ON and calculate control rods by
236
			-- energy cell level.
237
			reactor.setActive(true)
238
			rodLvl=calcRodLevel(cellEnergy)
239
		elseif cellEnergy > highEnergy then
240
			-- High energy: switch reactor OFF and set control rod level to 100
241
			reactor.setActive(false)
242
			rodLvl=100
243
		elseif cellEnergy > lowEnergy then
244
			-- Enough energy: do not change state of reactor. Only recalculate
245
			-- control rod level.
246
			--
247
			-- * If the reactor ist switched off, we will wait until energy
248
			--	fall below low energy mark.
249
			--
250
			-- * If it is turned on, we generate more energy until the
251
			--	energy level exeeds the high energy mark.
252
			rodLvl=calcRodLevel(cellEnergy)
253
		end
254
255
		reactor.setAllControlRodLevels(rodLvl)
256
257
		displayStatus(reactor.getActive(), rodLvl, cellEnergy)
258
259
		os.sleep(delay) -- Wait for 5s
260
	end	
261
end
262
263
function tickToMonitor(mon,frame)
264
	local len = string.len(delay.."/"..delay)
265
	local cx,cy = mon.getCursorPos()
266
	mon.setCursorPos(16-len,1)
267
	mon.write(string.rep(" ",len))
268
	mon.setCursorPos(16-string.len(frame.."/"..delay),1)
269
	writeColor(mon, colors.lightGray, frame.."/"..delay)
270
	mon.setCursorPos(cx,cy)
271-
		local pList = peripheral.getNames()
271+
272
273
function tick()
274
	local t=0
275
	while true do
276
		local f=t%delay+1
277
		tickToMonitor(term,f)
278
		local i, name
279
		for i, name in pairs(pList) do
280
			if peripheral.getType(name) == "monitor" then
281
				-- found monitor as peripheral
282
				tickToMonitor(peripheral.wrap(name),f)
283
			end
284
		end
285
		sleep(1)
286
		t=t+1
287
	end
288
end
289
290
function shortcutToMonitor(mon)
291
	local cx,cy = mon.getCursorPos()
292
	mon.setCursorPos(13,2)
293
	writeColor(mon, colors.black, "T", colors.orange)
294
	writeColor(mon, colors.black, "R", colors.blue)
295
	writeColor(mon, colors.black, "S", colors.red)
296
	resetColor(mon)
297-
		local pList = peripheral.getNames()
297+
298
end
299
300
function shortcut()
301
	while true do
302
		shortcutToMonitor(term)
303
		local i, name
304
		for i, name in pairs(pList) do
305
			if peripheral.getType(name) == "monitor" then
306
				-- found monitor as peripheral
307
				shortcutToMonitor(peripheral.wrap(name))
308
			end
309
		end
310
		event, side, xPos, yPos = os.pullEvent()
311
		if ((event == "mouse_click" and side == 1) or event == "monitor_touch")
312
			and yPos == 2 then
313
			if xPos == 13 then --T
314
				return
315
			elseif xPos == 14 then --R
316
				os.reboot()
317
			elseif xPos == 15 then --S
318
				os.shutdown()
319
			end
320-
r = parallel.waitForAny(main, shortcut, tick)
320+
321-
if r == 2 then
321+
322
	end
323-
	local pList = peripheral.getNames()
323+
324
325
term.clear()
326
for i, name in pairs(pList) do
327
	if peripheral.getType(name) == "monitor" then
328-
   mon = peripheral.wrap(name)
328+
		-- found monitor as peripheral
329-
   mon.setCursorPos(1,6)
329+
		mon = peripheral.wrap(name)
330
		mon.clear()
331
	end
332
end
333
r = parallel.waitForAny(shortcut, tick, main)
334
if r == 1 then
335
	writeColor(term, colors.red, "Terminated", colors.black)
336
	local i, name
337
	for i, name in pairs(pList) do
338
		if peripheral.getType(name) == "monitor" then
339
			-- found monitor as peripheral
340
			mon = peripheral.wrap(name)
341
			mon.setCursorPos(1,6)
342
			writeColor(mon, colors.red, "Terminated", colors.black)
343
		end
344
	end
345
	print("")
346
end
347
--
348
-- EOF
349
--