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