SHOW:
|
|
- or go back to the newest paste.
1 | -- modified to work with draconic rf storage (trying to determine actual 'gain' from reactor) | |
2 | --Rev 20210701 wtp | |
3 | - | --Rev. 20210619 wtp |
3 | + | --Moved extraneous notes and documentation into https://pastebin.com/FcZRymGb |
4 | - | --As my previous paste could be my 'first', this one will become my 1.1 release. |
4 | + | --author: wparish@wparish.com |
5 | -- rev 1.2 import borrowed functions | |
6 | - | --Developed for use on 1.7 Infinity with Draconic Evolution 1.7.10-1.0.2h (Mym.li normal mode) |
6 | + | -- ============================== -- |
7 | -- functions (borrowed from knPtJCjb) | |
8 | - | --I've got the main parts I wanted, the setup and considerations are detailed below: |
8 | + | |
9 | -- logging functions | |
10 | - | --Advanced computer with a Draconic Reactor stabilizer on it's right side. |
10 | + | local function getTime() |
11 | - | --Red cage lamp on top (to come on when either containment field or saturation <51%) |
11 | + | |
12 | - | -- Note: neither light will light nor flash at 51%, if the last iteration left the red light illuminated it will stay |
12 | + | contentSite = http.get("http://worldtimeapi.org/api/timezone/GMT").readAll() |
13 | - | -- illuminated until either it drops below 51% or rises up or beyond 52% (I call this the 'transition period') |
13 | + | |
14 | - | --Green cage lamb on back (to come on with both containment field and saturation >51%) |
14 | + | if string.find(contentSite, "datetime") ~= nil then -- and string.find(contentSite, "localDate") == 3 then |
15 | - | --A wired modem is on the left side with a cable running up to the Tier-7 Draconic Energy Core Energy Pylon |
15 | + | content = contentSite |
16 | - | --advanced monitors 5 wide, three tall stacked below the computer facing the stabilizer I have the flux gate on. |
16 | + | |
17 | - | --The Draconic Reactor is connected directly with cryotheum ducts from the stabilizer to the T7 energy 'input' |
17 | + | content = "00:00:00.00000','utcDate" |
18 | - | --then the T7 energy output goes to the reactor injector. |
18 | + | |
19 | - | -- The reactor injector flux gate has a redstone signal high at 262,000RF/t and connects back to the injector in |
19 | + | timePos = string.find(content,"datetime")+22 |
20 | - | -- reverse containment field mode (three repeaters and a piece of redstone) using 139,700K for my mostly used reactor |
20 | + | time = string.sub(content, timePos, timePos+13) |
21 | - | -- The stabilizer flux gate to the T7 energy core is currently set at 2,010,000 though of course that took weeks and starts |
21 | + | -- if string.sub(content, timePos, timePos+1) == "PM" then |
22 | - | -- out much lower. |
22 | + | -- timePM = tostring(tonumber(string.sub(time,1,2))+12)..string.sub(time,3) |
23 | - | -- Since the T7 fills up and the reactor essentially shuts down, I have a third flux gate 'drain' between the T7 |
23 | + | -- return timePM |
24 | - | -- energy core and the injector flux gate which is also connected to a modem and wired back to the computer. |
24 | + | -- else |
25 | - | -- The idea is to allow both my use and public use to draw on the reactor up to the amount the reactor creates, |
25 | + | return time |
26 | - | -- but to limit the flux gate if that drain gets too high as I've found connecting a new t7 to any of those tessearcts |
26 | + | -- I don't care if the time is 24H |
27 | - | -- on that flux gate would run out the buffer for the reactor and it would ultimately fail (I lost at least one core this way) |
27 | + | -- end |
28 | end | |
29 | - | -- Its worth acknowledging that the mym.li servers disable the explosion, so while losing the chaos shards hurts, |
29 | + | |
30 | - | -- at least you don't lose the rest of the infrastructure. |
30 | + | -- numeric functions |
31 | local function round(num, idp) | |
32 | - | -- Changes for the 19th. |
32 | + | local mult = 10^(idp or 0) |
33 | - | -- Mostly cosmetic, I'm going to start by converting my print redirect output to specific monitor coordinates |
33 | + | return math.floor(num * mult + 0.5) / multi |
34 | - | -- also better color management, so if the saturation is gaining during the transition period I want that green |
34 | + | |
35 | - | -- but the draining warning should be yellow |
35 | + | |
36 | - | -- the fluxgate flow override when it kicks in should be red |
36 | + | -- file functions |
37 | - | -- the normal flux gate flow set to the generation power-field drain should be green |
37 | + | -- write table to file 'path' |
38 | - | -- I may also suppress the maxFieldStrength and maxEnergySaturation as it's static and you sort of get that from the |
38 | + | local function fileWrite(path, text) |
39 | - | -- current values and their respective percentages |
39 | + | local file = io.open(path, "w") |
40 | - | -- I'm also going to shuffle around and try to put the variable definitions together in a block rather than |
40 | + | file:write(text) |
41 | - | -- having code intermixed in the variable initialization block |
41 | + | file:close() |
42 | end | |
43 | ||
44 | -- get table from 'path' | |
45 | local function fileGetTable(path) | |
46 | - | local fluxgate = peripheral.wrap("flux_gate_308") -- dump energy |
46 | + | if fs.exists(path) then |
47 | - | local fluxgate_out = peripheral.wrap("flux_gate_309") -- from reactor |
47 | + | local file = io.open(path, "r") |
48 | local lines = {} | |
49 | local i = 1 | |
50 | local line = file:read("*l") | |
51 | while line ~= nil do | |
52 | lines[i] = line | |
53 | line = file:read("*l") | |
54 | i = i +1 | |
55 | end | |
56 | file:close() | |
57 | return lines | |
58 | end | |
59 | return {} | |
60 | end | |
61 | ||
62 | -- update line in file 'path' (n is line number) | |
63 | local function fileReplaceLine(path, n, text) | |
64 | local lines = fileGetTable(path) | |
65 | lines[n] = text | |
66 | fileWriteFromTable(path, lines) | |
67 | end | |
68 | ||
69 | -- append line of text to path | |
70 | local function fileAppend(path, text) | |
71 | local file = io.open(path, "a") | |
72 | file:write(text.."\n") | |
73 | file:close() | |
74 | end | |
75 | ||
76 | -- get file length for path | |
77 | local function fileGetLength(path) | |
78 | local file = io.open(path, "r") | |
79 | local i = 0 | |
80 | while file:read("*l") ~= nil do | |
81 | i = i +1 | |
82 | end | |
83 | file:close() | |
84 | return I | |
85 | end | |
86 | ||
87 | -- return array of lines | |
88 | local function fileGetLines(path, startN, endN) | |
89 | local lines = fileGetTable(path) | |
90 | local linesOut = {} | |
91 | local x = 1 | |
92 | for i = startN, endN, 1 do | |
93 | linesOut[x] = lines[i] | |
94 | x = x + 1 | |
95 | end | |
96 | return linesOut | |
97 | end | |
98 | ||
99 | local function getLogs(path, xPos, yPos) | |
100 | local Logs = fileGetLines(path, fileGetLength(path)-5, fileGetLength(path)) | |
101 | for i = 1, 6, 1 do | |
102 | mon.setCursorPos(xPos+2,yPos+1+i) | |
103 | mon.write(Logs[i]) | |
104 | end | |
105 | end | |
106 | ||
107 | local function addLog(path, time, text) | |
108 | fileAppend(path, "["..time.."]") | |
109 | fileAppend(path, text) | |
110 | end | |
111 | ||
112 | -- end borrowed functions-- | |
113 | -- ===================== -- | |
114 | ||
115 | -- Each instance will have unique values for the flux gates. I'm going to store those as: | |
116 | -- Mym.li (values.cfg) | |
117 | -- local values = { | |
118 | -- "fluxgate".."flux_gate_308", | |
119 | -- "fluxgate_out".."flux_gate_309", | |
120 | -- slack API codes (to decrease odds I'll post those to pastebin again) | |
121 | -- } | |
122 | -- meh whatever just put the values line 1 = fluxgate, line 2 = fluxgate_out (values only), line 3 = slack API codes | |
123 | -- Dirtcraft fluxgate flux_gate_67 and fluxgate_out flux_gate_68 | |
124 | -- local values = {} | |
125 | ||
126 | local storage = peripheral.find("draconic_rf_storage") | |
127 | local monitor = peripheral.wrap("bottom") | |
128 | local core = peripheral.wrap("right") | |
129 | --local fluxgate = peripheral.wrap("flux_gate_308") -- dump energy | |
130 | --local fluxgate_out = peripheral.wrap("flux_gate_309") -- from reactor | |
131 | local powerstate = 0 | |
132 | local x=0 | |
133 | local y=0 | |
134 | local x1=0 | |
135 | local msg="empty" | |
136 | local fieldStrengthPercent=0 | |
137 | local lastFieldStrengthPercent | |
138 | local energySaturationPercent=0 | |
139 | local lastEnergySaturationPercent=0 -- last energy saturation | |
140 | local ecrft=0 -- energy core rf per tick | |
141 | local adjtimeout=0 | |
142 | local coretemp=0 | |
143 | local history="50 field saturation gain/loss @ 2 sec intervals" | |
144 | ||
145 | -- initialize log | |
146 | if fs.exists("logs.txt") then | |
147 | else | |
148 | file = io.open("logs.txt", "w") | |
149 | file:write("") | |
150 | file:close() | |
151 | end | |
152 | ||
153 | local values=fileGetTable("values.cfg") | |
154 | addLog("logs.txt",getTime(),"Values") | |
155 | ||
156 | for i,value in pairs(values) do | |
157 | addLog("logs.txt",getTime(),i..": "..value) | |
158 | end | |
159 | -- print(textutils.serialix(values)) | |
160 | local fluxgate = peripheral.wrap(values[1]) -- dump energy | |
161 | local fluxgate_out = peripheral.wrap(values[2]) -- from reactor | |
162 | local slack_api = peripheral.wrap(values[3]) -- authentication URL code | |
163 | ||
164 | term.redirect(monitor) | |
165 | term.setBackgroundColor(colors.gray) | |
166 | fluxgate.setOverrideEnabled(true) -- required for direct computer control of flux gate flow rate | |
167 | ||
168 | while true do | |
169 | ||
170 | local stab = core.getReactorInfo() | |
171 | ||
172 | y=x | |
173 | x=storage.getEnergyStored() | |
174 | powerstate=stab.status | |
175 | ||
176 | monitor.clear() | |
177 | ||
178 | monitor.setTextColor(colors.yellow) | |
179 | monitor.setCursorPos(32,1) | |
180 | print(getTime().." GMT") | |
181 | ||
182 | monitor.setTextColor(colors.white) | |
183 | monitor.setCursorPos(15,1) | |
184 | print("status:") | |
185 | if powerstate=="online" then | |
186 | monitor.setTextColor(colors.green) | |
187 | else | |
188 | monitor.setTextColor(colors.red) | |
189 | end | |
190 | monitor.setCursorPos(23,1) | |
191 | print(powerstate) | |
192 | ||
193 | monitor.setTextColor(colors.white) | |
194 | monitor.setCursorPos(7,2) | |
195 | print("generationRate: "..stab.generationRate.." RF/t") | |
196 | ||
197 | monitor.setCursorPos(10,3) | |
198 | coretemp=stab.temperature | |
199 | monitor.setTextColor(colors.green) | |
200 | if (coretemp>7000) then | |
201 | monitor.setTextColor(colors.orange) | |
202 | end | |
203 | if (coretemp>8000) then | |
204 | monitor.setTextColor(colors.purple) | |
205 | end | |
206 | print("temperature: "..coretemp) | |
207 | monitor.setTextColor(colors.white) | |
208 | ||
209 | monitor.setCursorPos(8,4) | |
210 | print("fieldStrength: "..stab.fieldStrength) | |
211 | ||
212 | -- these two max values are static and don't really tell us anything | |
213 | --monitor.setCursorPos(5,5) | |
214 | --print("maxFieldStrength: "..stab.maxFieldStrength) | |
215 | ||
216 | monitor.setCursorPos(7,6) | |
217 | print("fieldDrainRate: "..stab.fieldDrainRate) | |
218 | ||
219 | monitor.setCursorPos(1,7) | |
220 | print("Fuel Conversion Rate: "..stab.fuelConversionRate.." nb/t") | |
221 | ||
222 | --monitor.setCursorPos(4,8) | |
223 | --print("maxFuelConversion: "..stab.maxFuelConversion) | |
224 | ||
225 | local fuelConversionPercent=stab.fuelConversion*100/stab.maxFuelConversion | |
226 | monitor.setCursorPos(7,9) | |
227 | print("fuelConversion: "..stab.fuelConversion.."("..math.floor(fuelConversionPercent).."%)") | |
228 | ||
229 | lastEnergySaturationPercent=energySaturationPercent | |
230 | energySaturationPercent=stab.energySaturation*100/stab.maxEnergySaturation | |
231 | monitor.setCursorPos(5,10) | |
232 | print("energySaturation: "..stab.energySaturation.."("..math.floor(energySaturationPercent).."%) "..tonumber(string.format("%.3f",energySaturationPercent-lastEnergySaturationPercent))) | |
233 | --if energySaturationPercent==50 then | |
234 | -- stab.setGenerationRate=stab.generationRate+10000 | |
235 | -- sleep(5) | |
236 | -- end | |
237 | ||
238 | --monitor.setCursorPos(2,11) | |
239 | --print("maxEnergySaturation: "..stab.maxEnergySaturation) | |
240 | ||
241 | monitor.setCursorPos(8,12) | |
242 | print("fluxgate flow: "..fluxgate.getFlow()) | |
243 | ||
244 | lastFieldStrengthPercent=fieldStrengthPercent | |
245 | fieldStrengthPercent=stab.fieldStrength*100/stab.maxFieldStrength | |
246 | monitor.setCursorPos(2,13) | |
247 | print("Cont. fieldStrength: "..tonumber(string.format("%.3f",(fieldStrengthPercent))).."%".." ("..fieldStrengthPercent-lastFieldStrengthPercent..")") | |
248 | ||
249 | monitor.setCursorPos(2,15) | |
250 | print("Energy Core Storage: "..tonumber(string.format("%.3f",x))) | |
251 | ecrft=((((x-y)/1000/1000)/2)/20) -- there are 20 ticks in a second so you /20 not multiple dufus | |
252 | ||
253 | monitor.setCursorPos(5,16) | |
254 | ||
255 | x1=ecrft | |
256 | if (x1>999999999) then | |
257 | -- leave x1 alone for millions | |
258 | msg="MRF/t" | |
259 | end | |
260 | ||
261 | if (x1<10000000000) then | |
262 | x1=x1*1000 | |
263 | msg="KRF/t" | |
264 | end | |
265 | ||
266 | if (x1<1000000) then | |
267 | x1=x1*1000 | |
268 | msg="RF/t" | |
269 | end | |
270 | ||
271 | print("Energy Core RF/t: "..x1..msg..", "..math.floor(x*100/2140000000000).."%") | |
272 | if (fieldStrengthPercent>51 and energySaturationPercent>51) then | |
273 | -- monitor.setCursorPos(15,14) | |
274 | redstone.setOutput("top",false) | |
275 | end | |
276 | ||
277 | if (adjtimeout>0) then | |
278 | adjtimeout=adjtimeout-1 | |
279 | monitor.setCursorPos(18,14) | |
280 | monitor.setTextColor(colors.cyan) | |
281 | print("Adjtimeout="..adjtimeout) | |
282 | end | |
283 | if (coretemp<7000 and adjtimeout==0 and energySaturationPercent>51) then | |
284 | -- coretemp temp set to 'save' 7k | |
285 | monitor.setCursorPos(18,14) | |
286 | monitor.setTextColor(colors.pink) | |
287 | print("experimental: adding~10k") | |
288 | addLog("logs.txt",getTime(),"adding 10k to "..fluxgate_out.getSignalLowFlow()) | |
289 | fluxgate_out.setSignalLowFlow(fluxgate_out.getSignalLowFlow()+10000) | |
290 | adjtimeout=120 -- no faster than 1 adj. per 2 min | |
291 | end | |
292 | ||
293 | --end | |
294 | ||
295 | if (fieldStrengthPercent<51 or energySaturationPercent<51) then | |
296 | monitor.setCursorPos(1,14) | |
297 | if (lastEnergySaturationPercent<energySaturationPercent) then | |
298 | monitor.setTextColor(colors.green) | |
299 | print("++++ Correcting") | |
300 | history=history.."+" | |
301 | elseif (lastEnergySaturationPercent>energySaturationPercent) then | |
302 | monitor.setTextColor(colors.yellow) | |
303 | print("!!!! Degrading") | |
304 | history=history.."-" | |
305 | end | |
306 | if string.len(history)>50 then | |
307 | history=string.sub(history,2,50) | |
308 | end | |
309 | monitor.setCursorPos(1,18) | |
310 | monitor.setTextColor(colors.lightBlue) | |
311 | print(history) | |
312 | ||
313 | redstone.setOutput("top", not redstone.getOutput("top")) | |
314 | redstone.setOutput("back",false) | |
315 | -- or temp over?? 8800? | |
316 | if (fieldStrengthPercent<45 or energySaturationPercent<45) then | |
317 | redstone.setOutput("top",true) | |
318 | core.stopReactor() | |
319 | monitor.setCursorPos(20,14) | |
320 | monitor.setTextColor(colors.red) | |
321 | print("*** REACTOR SCRAM ***") | |
322 | addLog("logs.txt",getTime(),"SCRAM: fs-"..fieldStrengthPercent..", es-"..energySaturationPercent) | |
323 | term.setBackgroundColor(colors.yellow) | |
324 | end | |
325 | end | |
326 | ||
327 | monitor.setTextColor(colors.white) | |
328 | ||
329 | if (fieldStrengthPercent>51 and energySaturationPercent>51) then | |
330 | redstone.setOutput("top",false) | |
331 | redstone.setOutput("back",true) | |
332 | -- redstone.setOutput("back",true) -- redstone.getOutput("top")) | |
333 | end | |
334 | -- Energy dump, if core<50% then | |
335 | -- set fluxgate low flow to core net gain (presuming you're generating at least 500k) | |
336 | ||
337 | if (x*100/2141200000000)>50 then -- per above now I'm only setting the output when over 70% | |
338 | ||
339 | -- seems to work more predictably just allowing the generation rate, using the change kept allow massive drops | |
340 | -- and recover time was poor (even with the 70% safety margin) an empty T7 is really a RF vacuum. | |
341 | -- fluxgate.setFlowOverride(ecrft*4000) | |
342 | fluxgate.setFlowOverride((stab.generationRate-(stab.fieldDrainRate*2))-20500) -- *2 to dump extra above generation range | |
343 | -- end | |
344 | else | |
345 | -- Want to let a little through since I rely on this energy to keep my AE2 system operational | |
346 | fluxgate.setFlowOverride(500000) | |
347 | end | |
348 | ||
349 | sleep(2) | |
350 | end |