View difference between Paste ID: zP9AR3gV and XH6h8wfX
SHOW: | | - or go back to the newest paste.
1
-- keeps reactor working efficiently at all times; increases power load when necessary, goes idle at 90% power until below 10%
2
 
3
-- updated to Bigger Reactors; see earlier versions for the big reactors versions (they exist)
4-
  local reactor,terminal --also searches for a terminal glasses terminal
4+
5-
  for k,v in pairs(rs.getSides()) do
5+
timer=nil
6-
    if (peripheral.getType(v) == "BigReactors-Reactor") then
6+
7
local timeOperationTable={
8
  __sub=function(a,b)
9-
      break
9+
    if not a or not b then return false end
10
    if b[2]>a[2] then
11
          return setmetatable({(a[1]-1)-b[1],(a[2]-b[2])%24},timeOperationTable)
12-
      print('terminal found!')
12+
        else
13
          return setmetatable({a[1]-b[1],a[2]-b[2]},timeOperationTable)
14
        end
15-
  return reactor, terminal
15+
  end,
16
  __tostring=function(t)
17
    return t[1]..' in-game days, ' .. math.floor(t[2]) ..' hours'
18
  end
19-
local reactor,terminal=findPeripherals()
19+
}
20
 
21-
local curPower,oldPower,controlRodLevel,powerMode,secondsWorked=0,0,100,0,0
21+
22
  local reactor,terminal,monitor
23
  for k,v in pairs(peripheral.getNames()) do
24
    local t = peripheral.getType(v)
25-
powerMode = reactor.getEnergyStored()<9000000
25+
    if (t == "BiggerReactors_Reactor") then
26
      reactor = peripheral.wrap(v)
27
      print('reactor found!')
28
    elseif (peripheral.getType(v) == "openperipheral_glassesbridge") and (not terminal) then
29-
  secondsWorked=secondsWorked+1
29+
30-
  print('Yes, I am working. Total time: ' .. secondsWorked .. ' steps.')
30+
      print('terminal glasses terminal found!')
31-
  oldPower=curPower
31+
    elseif (peripheral.getType(v) == 'monitor') then
32-
  curPower=reactor.getEnergyStored()
32+
      monitor=peripheral.wrap(v)
33-
  if oldPower==0 then
33+
      local x,y=monitor.getSize()
34-
    oldPower=curPower+(target*interval)
34+
      monitor.setTextScale(math.min(5,math.max(x/60,0.5)))
35
      print('monitor found!')
36-
  if curPower>9000000 then
36+
37
  end
38-
  elseif curPower<1000000 then
38+
  return reactor, terminal, monitor
39
end
40
 
41
 
42-
    oldDeltaPower=deltaPower or 0
42+
local reactor,terminal,monitor=findPeripherals()
43-
    deltaPower = curPower-oldPower
43+
44-
    local curError = deltaPower-(target*interval)
44+
local controlRodLevel,powerMode,tickCount,showAdvancedSettings=0,50,0,0,false
45-
    integral=integral+curError
45+
46-
    print('Error: ' .. curError)
46+
local upTicks=0
47-
    print('Integral: ' .. integral)
47+
48-
    local deltaControlRodLevel=(Kp*curError)+(Ki*integral)
48+
49-
	if deltaControlRodLevel>50 or deltaControlRodLevel<-50 then
49+
50-
	 if curError<target*10 and curError>-target*10 then
50+
local function powerPerc()
51-
	  Kp=Kp/2
51+
    return reactor.battery().stored()/reactor.battery().capacity()
52-
	 end
52+
53-
	 if integral>100000 or integral<100000 then
53+
54-
	  integral=0
54+
local function reactivity()
55-
	 end
55+
    return reactor.fuelTank().fuelReactivity()
56-
	end
56+
57-
	if deltaControlRodLevel>-1 and deltaControlRodLevel<1 then
57+
58-
	 if curError>target*10 then
58+
tempGuess = 1000
59-
      Kp=Kp*1.5
59+
60-
	 end
60+
tempGuessChange = 2
61-
	end
61+
62-
	deltaControlRodLevel=deltaControlRodLevel<0 and math.ceil(deltaControlRodLevel) or deltaControlRodLevel>0 and math.floor(deltaControlRodLevel) or 0
62+
reactivities = {}
63-
    print('Control rod level change: ' .. deltaControlRodLevel)
63+
64
lastReactivity = 1
65-
    if controlRodLevel>100 or controlRodLevel<0 then 
65+
66
bestFound = false
67
68
powerMode = powerPerc() < 0.1
69-
    if curPower<10000 then
69+
70-
     controlRodLevel=0
70+
71
  term.clear()
72
  tickCount=tickCount+1
73-
    print('Current control rod level: ' .. controlRodLevel)
73+
  if powerMode and powerPerc()>0.99 then
74
    powerMode=false
75
    timeStarted={os.day(),os.time()} --I keep repeating this because not doing it (using a function) makes setmetatable apparently completely and utterly fail to work and gives me a bunch of other stupid crap
76-
    reactor.setAllControlRodLevels(100)
76+
    setmetatable(timeStarted,timeOperationTable)
77-
    print("Reactor's nearly full.")
77+
  elseif not powerMode and powerPerc()<0.1 then
78-
    print("Current status: off.")
78+
79
    timeStarted={os.day(),os.time()}
80
    setmetatable(timeStarted,timeOperationTable)
81
  elseif powerPerc() < 0.001 then
82
    reactor.setActive(true)
83
    reactor.setAllControlRodLevels(0)
84-
  local wastePercent=reactor.getWasteAmount()/reactor.getFuelAmountMax()
84+
85-
  local fuelPercent=(reactor.getWasteAmount()+reactor.getFuelAmount())/reactor.getFuelAmountMax()
85+
86
    upTicks=upTicks+1
87-
  terminal.addBox(5,5,math.floor(curPower/100000),10,0x00cc00,0.8)
87+
    reactor.setActive(true)
88
    local temperature = reactor.fuelTemperature()
89
    oldError=curError or 0
90
    curError = temperature - tempGuess or 0
91
    integral=integral+curError or 0
92
    derivative = tickCount>1 and curError - oldError or 0
93
    term.setCursorPos(1,1)
94
    term.write('Error: ' .. curError)
95
    term.setCursorPos(1,2)
96-
args = {...}
96+
    term.write('Integral: ' .. integral)
97
    term.setCursorPos(1,3)
98-
interval = args[1] or 2
98+
    term.write('Derivative: ' .. derivative)
99-
target = args[2] or 100
99+
    term.setCursorPos(1,4)
100-
Kp=0.001
100+
    Kp=Kp or 0.1*interval
101-
Ki=0.0001
101+
    Ki=Ki or 0.001*interval
102
    Kd=Kd or 0.001*interval
103
    local deltaControlRodLevel=(Kp*curError)+(Ki*integral)+(Kd*derivative)
104-
target=tonumber(target)
104+
    term.write('Control rod level change: ' .. deltaControlRodLevel)
105
    controlRodLevel = controlRodLevel+deltaControlRodLevel
106
    if controlRodLevel>100 or controlRodLevel<0 then
107
     integral=0
108
    end
109
    controlRodLevel = controlRodLevel>100 and 100 or controlRodLevel<0 and 0 or controlRodLevel
110-
while reactor.getConnected() do
110+
    term.setCursorPos(1,5)
111-
  if interval then os.startTimer(interval) end
111+
    term.write('Current control rod level: ' .. controlRodLevel)
112
        term.setCursorPos(1,6)
113-
  if event[1]=='timer' then
113+
        term.write('Uptime: ' .. timeOperationTable.__tostring(setmetatable({os.day(),os.time()},timeOperationTable)-timeStarted)) --wow the normal tostring should really work here
114-
   reactorActivities()
114+
        term.setCursorPos(1,7)
115
    term.write('Uptime percentage: ' ..(upTicks*100)/tickCount..'%')
116-
    terminalActivities()
116+
    if term.isColor() then
117
      term.setCursorPos(1,8)
118
      term.write('Error weight: ' .. Kp)
119
      term.setCursorPos(1,9)
120
      term.write('Integral weight: ' .. Ki)
121
      term.setCursorPos(1,10)
122
      term.write('Derivative weight: ' .. Kd)
123
      term.setCursorPos(1,11)
124
      term.write('Target temp: ' .. tempGuess)
125
      for i=8,11,1 do
126
        term.setCursorPos(30,i)
127
        term.write('+-')
128
      end
129
    end
130
    reactor.setAllControlRodLevels(controlRodLevel)
131
  else
132
    term.setCursorPos(1,1)
133
    term.write("Reactor's nearly full.")
134
    term.setCursorPos(1,2)
135
    term.write("Current status: off.")
136
    reactor.setActive(false)
137
  end
138
end
139
 
140
local function terminalActivities()
141
  terminal.clear()
142
  local fuel = reactor.fuelTank()
143
  local wastePercent=fuel.waste()/fuel.capacity()
144
  local fuelPercent=(fuel.waste()+fuel.fuel())/fuel.capacity()
145
  terminal.addBox(5,5,100,10,0xcc0000,0.8)
146
  terminal.addBox(5,5,math.floor(powerPerc()),10,0x00cc00,0.8)
147
  terminal.addBox(105,5,10,100,0xcccccc,0.8)
148
  terminal.addBox(105,5,10,controlRodLevel,0x303030,0.8)
149
  terminal.addBox(5,20,100,10,0x303030,0.8)
150
  terminal.addBox(5,20,math.min(math.floor(100*fuelPercent),100),10,0xcccc00,0.8)
151
  terminal.addBox(5,20,math.min(math.floor(100*wastePercent),100),10,0x00cccc,0.8)
152
end
153
 
154
local function monitorActivities()
155
  monitor.clear()
156
  monitor.setTextColor(colors.white)
157
  monitor.setCursorPos(1,1)
158
  monitor.write('Power mode: ')
159
  if powerMode then
160
   monitor.setTextColor(colors.green)
161
   monitor.write('On')
162
   monitor.setTextColor(colors.white)
163
   monitor.setCursorPos(1,4)
164
   monitor.write('Reactor working at ' .. 100-controlRodLevel .. '% capacity.')
165
   monitor.setCursorPos(1,5)
166
   monitor.write('Uptime: ' .. timeOperationTable.__tostring(setmetatable({os.day(),os.time()},timeOperationTable)-timeStarted))
167
  else
168
   monitor.setTextColor(colors.red)
169
   monitor.write('Off')
170
   monitor.setTextColor(colors.white)
171
   monitor.setCursorPos(1,4)
172
   monitor.write("Reactor's off.")
173
   monitor.setCursorPos(1,5)
174
   monitor.write('Downtime: ' .. timeOperationTable.__tostring(setmetatable({os.day(),os.time()},timeOperationTable)-timeStarted))
175
  end
176
  monitor.setCursorPos(1,2)
177
  monitor.write('Current temperature: ')
178
  monitor.setTextColor(curError>100 and colors.red or curError>10 and colors.orange or curError>-10 and colors.green or curError>-100 and colors.lightBlue or colors.cyan)
179
  monitor.write(reactor.fuelTemperature())
180
  monitor.setCursorPos(1,3)
181
  monitor.setTextColor(colors.white)
182
  monitor.write('Current energy storage: ' .. reactor.battery().stored())
183
  monitor.setCursorPos(1,6)
184
  monitor.write('Uptime percentage: ' ..(upTicks*100)/tickCount..'%')
185
  if monitor.isColor() then
186
    if showAdvancedSettings then
187
     monitor.setCursorPos(1,7)
188
         derweight='Derivative weight: ' .. Kd
189
     monitor.write('Error weight: ' .. Kp)
190
     monitor.setCursorPos(1,8)
191
     monitor.write('Integral weight: ' .. Ki)
192
     monitor.setCursorPos(1,9)
193
     monitor.write(derweight)
194
     monitor.setCursorPos(1,10)
195
     monitor.write("Target temp:" .. tempGuess)
196
     for i=7,10,1 do
197
       monitor.setCursorPos(string.len(derweight)+2,i)
198
       monitor.write('+-')
199
     end
200
     monitor.setCursorPos(1,11)--hate hardcoding hate hardcoding
201
         monitor.setTextColor(colors.yellow)
202
     monitor.write('Hide advanced settings')
203
    else
204
     monitor.setCursorPos(1,7)
205
     monitor.setTextColor(colors.yellow)
206
     monitor.write('Show advanced settings')
207
    end
208
  end
209
end
210
 
211
function monitorTouch(x,y)
212
  if showAdvancedSettings then -- all these global variables are going to make me sick
213
    if x==(string.len(derweight)>23 and string.len(derweight)+3 or string.len(derweight)+2) then
214
      if y==5 then
215
        Kp=Kp+0.05
216
      elseif y==6 then
217
        Ki=Ki+(0.005*interval)
218
      elseif y==7 then
219
        Kd=Kd+0.01
220
      elseif y==8 then
221
        tempGuess = tempGuess + 10
222
      end
223
    elseif x==((string.len(derweight)>22) and string.len(derweight)+4 or string.len(derweight)+3) then --in case you're wondering, I have no idea either, but it's necessary
224
      if y==5 then
225
        Kp=Kp-0.05
226
      elseif y==6 then
227
        Ki=Ki-(0.005*interval)
228
      elseif y==7 then
229
        Kd=Kd-0.01
230
      elseif y==8 then
231
        tempGuess = tempGuess - 10
232
        elseif y==9 then
233
          showAdvancedSettings=false
234
        end
235
    end
236
  else
237
    if y==5 then
238
      showAdvancedSettings=true
239
    end
240
  end
241
end
242
 
243
local args = {...}
244
 
245
interval = args[1] or 0.5
246
 
247
interval=tonumber(interval)
248
 
249
if interval<0.5 then
250
    interval=0.5
251
end
252
 
253
local timeStarted={os.day(),os.time()}
254
 
255
setmetatable(timeStarted,timeOperationTable)
256
 
257
while reactor.connected() do
258
  if not timer then timer=os.startTimer(interval) end
259
  local event = {os.pullEvent()}
260
  if event[1]=='timer' and event[2]==timer then
261
   timer=nil
262
   pcall(reactorActivities)
263
   if terminal then
264
    pcall(terminalActivities)
265
   end
266
   if monitor then
267
    pcall(monitorActivities)
268
   end
269
  elseif event[1]=='mouse_click' then
270
    if event[2]=='1' then
271
     if event[3]==49 then
272
      if event[4]==5 then
273
       Kp=Kp+0.05
274
      elseif event[4]==6 then
275
       Ki=Ki+(0.005*interval)
276
      elseif event[4]==7 then
277
       Kd=Kd+0.01
278
      elseif event[4]==8 then
279
       tempGuess=tempGuess+10
280
      end
281
     elseif event[3]==50 then
282
      if event[4]==5 then
283
       Kp=Kp-0.05
284
      elseif event[4]==6 then
285
       Ki=Ki-(0.005*interval)
286
      elseif event[4]==7 then
287
       Kd=Kd-0.01
288
      elseif event[4]==8 then
289
        tempGuess=tempGuess-10
290
      end
291
     end
292
    end
293
  elseif event[1]=='monitor_touch' then
294
   pcall(monitorTouch,event[3],event[4])
295
   pcall(monitorActivities)
296
  end
297
end