View difference between Paste ID: XCq5cNxd and 8Arm47SX
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
19
-- Critical energy mark: give us the maximum power.
20
critEnergy=3000000
21
22
-- Low energy mark: turn reactor on to get more energy
23
lowEnergy=7000000
24
25
-- Heigh energy mark: we have enough, so turn the reactor off.
26
highEnergy=9000000
27
28
29
--
30
-- Calculate the control rod level (in %) by stored energy of internal
31
-- recator cell.
32
--
33
-- * If cellEnergy <= critEnergy, the calculation results in maximum
34
--   energy generation (control rod level = 0%).
35
-- * If cellEnergy >= highEnergy, the calculation results in 10% energy
36
--   generation (control rod level = 90%).
37
--
38
-- Parameters:
39
--     cellEnergy - stored energy of internal cell in RF
40
--
41
-- Return:
42
--     New control rod level in %.
43
--
44
function calcRodLevel(cellEnergy)
45
   -- Delta between critical and heigh energy mark
46
   local deltaEnergy = highEnergy - critEnergy 
47
48
   -- Calculated maximum delta energy (not the real maximum), so that
49
   -- the high energy mark results into a control rod level of 90%
50
   local deltaEnergy100 = deltaEnergy * 100 / 90
51
52
   -- Energy for calculation: value between 0 and 'deltaEnergy'
53
   local calcEnergy = cellEnergy - critEnergy
54
55
   if calcEnergy < 0 then
56
      calcEnergy = 0
57
   elseif calcEnergy > deltaEnergy then
58
      calcEnergy = deltaEnergy
59
   end
60
61
   -- Calculate control rod level and round the result (math.floor + 0.5)
62
   return math.floor(calcEnergy * 100 / deltaEnergy100 + 0.5)
63
end
64
65
66
--
67
-- Write text with colors, if possible (advance monitor)
68
--
69
-- Parameters:
70
--     mon   - handle of monitor
71
--     color - text color
72
--     text  - text to write
73
--
74
function writeColor(mon, color, text)
75
   if (mon.isColor()) then
76
      mon.setTextColor(color)
77
   end
78
   mon.write(text)
79
   if (mon.isColor()) then
80
      mon.setTextColor(colors.white)
81
   end
82
end
83
84
85
--
86
-- Display reactor status to a monitor.
87
--
88
-- Parameters:
89
--     mon        - handle of monitor.
90
--     state      - state of reactor (on/off)
91
--     rodLvl     - Level of control rods in %
92
--     cellEnergy - stored energy of internal cell (in RF)
93
--
94
function displayStatusToMonitor(mon, state, rodLvl, cellEnergy)
95
   mon.clear()
96
97
   -- First get the monitor size and try to scale, if the feature ist
98
   -- available.
99
   if mon.setTextScale ~= nil then
100
      -- reset text scale
101
      mon.setTextScale(1)
102
   end
103
104
   local width, height = mon.getSize()
105
   if width < 15 or height < 5 then
106
      -- too small: try to scale down.
107
      if mon.setTextScale ~= nil then
108
         mon.setTextScale(0.5)
109
      else
110
         return -- too small und no text scale available
111
      end
112
113
      width, height = mon.getSize()
114
      if width < 15 or height < 5 then
115
         return -- still too small
116
      end
117
   else
118
      -- Huge monitors? Try to scale up, if possible (max scale=5).
119
      local scale = math.min(width / 16, height / 5, 5)
120
      scale = math.floor(scale * 2) / 2 -- multiple of 0.5 
121
122
      if scale > 1 and mon.setTextScale ~= nil then
123
         mon.setTextScale(scale)
124
         width, height = mon.getSize()
125
      end
126
   end
127
128
129
   --
130
   -- Output the data
131
   --
132
133
   mon.setCursorPos(1,1)
134
   mon.write("Reactor")
135
136
   mon.setCursorPos(1,3)
137
   mon.write("Status ")
138
139
   if state then
140
      writeColor(mon, colors.green, "ON")
141
   else
142
      writeColor(mon, colors.red, "OFF")
143
   end
144
145
   mon.setCursorPos(1,4)
146
   mon.write("Rod Level: " .. rodLvl .. "%")
147
148
   mon.setCursorPos(1,5)
149
   if width < 16 then
150
      mon.write("Cell: ") -- One block monitor (15x5 with scale 0.5)
151
   else
152
      mon.write("Energy: ")
153
   end
154
155
   local c
156
   if cellEnergy < critEnergy then
157
      c = colors.red -- Red: We use too much energy
158
   elseif cellEnergy > lowEnergy then
159
      c = colors.green -- Green: More energy then low water mark
160
   else
161
      c = colors.orange -- Orange: Less energy the low water mark, but OK
162
   end
163
   writeColor(mon, c, string.format("%d", math.floor(cellEnergy/1000 + 0.5)))
164
   mon.write(" kRF")
165
end
166
167
168
--
169
-- Display reactor status to any connected monitor and also to console.
170
--
171
-- Parameters:
172
--     state      - state of reactor (on/off)
173
--     rodLvl     - Level of control rods in %
174
--     cellEnergy - stored energy of internal energy cell in RF
175
--
176
function displayStatus(state, rodLvl, cellEnergy)
177
   displayStatusToMonitor(term, state, rodLvl, cellEnergy) -- console
178
   term.setCursorPos(1,7)
179
   term.write("* Hold Crtl-T to terminate program")
180
   term.setCursorPos(1,8)
181
182
   local pList = peripheral.getNames()
183
   local i, name
184
   for i, name in pairs(pList) do
185
      if peripheral.getType(name) == "monitor" then
186
         -- found monitor as peripheral
187
         displayStatusToMonitor(peripheral.wrap(name),
188
                                state, rodLvl, cellEnergy)
189
      end
190
   end
191
end
192
193
194
--
195
-- Find the first connected big reactor and return the wraped handle.
196
--
197
-- If no reactor was found this function terminate the program.
198
--
199
-- Return:
200
--     Handle of first connected reactor found.
201
--
202
function getReactorHandle()
203
   local pList = peripheral.getNames()
204
   local i, name
205
   for i, name in pairs(pList) do
206
      if peripheral.getType(name) == "BigReactors-Reactor" then
207
         return peripheral.wrap(name)
208
      end
209
   end
210
211
   error("No big reactor connected: Exit program")
212
   exit()
213
end
214
215
216
reactor = getReactorHandle()
217
218
--
219
-- Endless loop: Recalculate rod level, set rod level, display result
220
-- and wait for 5 secounds.
221
--
222
while true do
223
   cellEnergy = reactor.getEnergyStored()
224
   if cellEnergy < lowEnergy then
225
      -- Low energy: switch reactor ON and calculate control rods by
226
      -- energy cell level.
227
      reactor.setActive(true)
228
      rodLvl=calcRodLevel(cellEnergy)
229
   elseif cellEnergy > highEnergy then
230
      -- High energy: switch reactor OFF and set control rod level to 100
231
      reactor.setActive(false)
232
      rodLvl=100
233
   elseif cellEnergy > lowEnergy then
234
      -- Enough energy: do not change state of reactor. Only recalculate
235
      -- control rod level.
236
      --
237
      -- * If the reactor ist switched off, we will wait until energy
238
      --   fall below low energy mark.
239
      --
240
      -- * If it is turned on, we generate more energy until the
241
      --   energy level exeeds the high energy mark.
242
      rodLvl=calcRodLevel(cellEnergy)
243
   end
244
245
   reactor.setAllControlRodLevels(rodLvl)
246
247
   displayStatus(reactor.getActive(), rodLvl, cellEnergy)
248
249
   os.sleep(5) -- Wait for 5s
250
end
251
252
--
253
-- EOF
254
--