SHOW:
|
|
- or go back to the newest paste.
1 | -- TODO: actually make graph? | |
2 | ||
3 | local monitor = peripheral.find "monitor" | |
4 | - | local storage = peripheral.find(settings.get "storage_type" or "draconic_rf_storage") |
4 | + | local storage = peripheral.find "draconic_rf_storage" |
5 | local re_in_gate = peripheral.wrap "flux_gate_3" | |
6 | local re_out_gate = peripheral.wrap "flux_gate_6" | |
7 | local dist_gate = peripheral.wrap "flux_gate_7" | |
8 | local reactor = peripheral.find "draconic_reactor" | |
9 | local capacity = (storage.getMaxEnergyStored or storage.getEnergyCapacity)() | |
10 | local delay = 0.1 | |
11 | local ticks_delay = 0.1 / 0.05 | |
12 | local threshold = 1e9 | |
13 | local tx_out = 1e8 | |
14 | local target_field = 0.4 | |
15 | local target_saturation = 0.3 | |
16 | ||
17 | local function read_energy() | |
18 | return storage.getEnergyStored() | |
19 | end | |
20 | ||
21 | monitor.setTextScale(1) | |
22 | monitor.setBackgroundColor(colors.black) | |
23 | monitor.setTextColor(colors.white) | |
24 | local data = {} | |
25 | ||
26 | local prefixes = {"", "k", "M", "G", "T", "P", "E", "Z", "Y", "R", "Q"} | |
27 | local function SI_prefix(value, unit) | |
28 | local i = 1 | |
29 | local x = value | |
30 | while x > 1000 or x < -1000 do | |
31 | x = x / 1000 | |
32 | i = i + 1 | |
33 | end | |
34 | return ("%.3f%s%s"):format(x, prefixes[i], unit) | |
35 | end | |
36 | ||
37 | local function display(data) | |
38 | monitor.clear() | |
39 | local longest_label = 0 | |
40 | for _, val in pairs(data) do | |
41 | if #val[1] > longest_label then longest_label = #val[1] end | |
42 | end | |
43 | local i = 1 | |
44 | for _, val in pairs(data) do | |
45 | monitor.setCursorPos(1, i) | |
46 | monitor.setTextColor(val[3] or colors.white) | |
47 | monitor.write(val[1] .. ":" .. (" "):rep(longest_label - #val[1] + 2) .. val[2]) | |
48 | i = i + 1 | |
49 | end | |
50 | end | |
51 | ||
52 | re_in_gate.setOverrideEnabled(true) | |
53 | re_out_gate.setOverrideEnabled(true) | |
54 | dist_gate.setOverrideEnabled(true) | |
55 | local past_RF_per_tick = {} | |
56 | local history_length = 1200 / ticks_delay | |
57 | local function display_stats() | |
58 | local previous | |
59 | - | { "Time", ("%s.%03d"):format(os.date "!%X", os.epoch "utc" % 1000) }, |
59 | + | |
60 | - | { "Stored", SI_prefix(energy, "RF") }, |
60 | + | |
61 | local reactor_state = reactor.getReactorInfo() | |
62 | if previous then | |
63 | local diff = energy - previous | |
64 | local RF_per_tick = diff / ticks_delay | |
65 | table.insert(past_RF_per_tick, RF_per_tick) | |
66 | if #past_RF_per_tick > history_length then table.remove(past_RF_per_tick, 1) end | |
67 | local total = 0 | |
68 | for _, h in pairs(past_RF_per_tick) do total = total + h end | |
69 | local average = total / #past_RF_per_tick | |
70 | ||
71 | local status = "OK" | |
72 | local status_col = colors.green | |
73 | if energy < threshold then | |
74 | status = "Storage Low" | |
75 | status_col = colors.yellow | |
76 | end | |
77 | if reactor_state.status == "warming_up" then | |
78 | status = "Reactor Precharge" | |
79 | status_col = colors.blue | |
80 | elseif reactor_state.status ~= "cold" and (reactor_state.status == "stopping" or reactor_state.temperature > 8000 or reactor_state.fieldStrength / reactor_state.maxFieldStrength < 0.2 or reactor_state.fuelConversion / reactor_state.maxFuelConversion > 0.83) then | |
81 | status = "Emergency Shutdown" | |
82 | status_col = colors.orange | |
83 | reactor.stopReactor() | |
84 | re_out_gate.setFlowOverride(0) | |
85 | re_in_gate.setFlowOverride(1e7) | |
86 | elseif reactor_state.status == "cold" then | |
87 | status = "Reactor Off" | |
88 | status_col = colors.pink | |
89 | end | |
90 | if reactor_state.temperature > 9000 then | |
91 | status = "Imminent Death" | |
92 | status_col = colors.red | |
93 | end | |
94 | if status == "OK" or status == "Storage Low" then | |
95 | re_in_gate.setFlowOverride(reactor_state.fieldDrainRate / (1 - target_field)) | |
96 | local base_max_rft = reactor_state.maxEnergySaturation / 1000 * 1.5 | |
97 | local conv_level = (reactor_state.fuelConversion / reactor_state.maxFuelConversion) * 1.3 - 0.3 | |
98 | local max_rft = base_max_rft * (1 + conv_level * 2) | |
99 | re_out_gate.setFlowOverride(math.min(max_rft * 0.7, 5 * reactor_state.fieldDrainRate / (1 - target_field))) | |
100 | end | |
101 | dist_gate.setFlowOverride(energy > threshold and tx_out or 0) | |
102 | ||
103 | display { | |
104 | { "Status", status, status_col }, | |
105 | { "Time", os.date "!%X" }, | |
106 | { "Stored", SI_prefix(energy, "RF"), energy < threshold and colors.yellow }, | |
107 | { "Capacity", SI_prefix(capacity, "RF") }, | |
108 | { "% filled", ("%.4f%%"):format(energy / capacity * 100) }, | |
109 | { "Inst I/O", SI_prefix(RF_per_tick, "RF/t") }, | |
110 | { "60s I/O" , SI_prefix(average, "RF/t") }, | |
111 | { "Fuel Consumed", ("%.4f%%"):format(100 * reactor_state.fuelConversion / reactor_state.maxFuelConversion) }, | |
112 | { "Saturation", ("%.4f%%"):format(100 * reactor_state.energySaturation / reactor_state.maxEnergySaturation) }, | |
113 | { "Field Strength", ("%.4f%%"):format(100 * reactor_state.fieldStrength / reactor_state.maxFieldStrength) }, | |
114 | { "Field Input", SI_prefix(re_in_gate.getFlow(), "RF/t") }, | |
115 | { "Generation Rate", SI_prefix(reactor_state.generationRate, "RF/t") }, | |
116 | { "Temperature", reactor_state.temperature } | |
117 | } | |
118 | end | |
119 | previous = energy | |
120 | sleep(delay) | |
121 | end | |
122 | end | |
123 | ||
124 | display_stats() |