Advertisement
mlard811

ReactorControlv2

Apr 7th, 2014
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.44 KB | None | 0 0
  1. --[[
  2. I found this program for controlling a reactor, however it was outdated.  I fixed it and this version does currently work in the latest version of Tekkit.  I did not write the original, my coding skills are pretty basic.  Other than my fix, everything below remains the same as the original.
  3.  
  4. Big Reactors controller script
  5. Uses wired modems to connect to computer control port on reactor
  6. Prefers monitor connection (also via wired modem) for local display and potentially control
  7. Uses wireless modem channel to send status and accept control commands from central system
  8. If present, wireless modem must be on top of the computer
  9. Note: Do not connect more than one reactor to the same controlling computer
  10. ]]--
  11.  
  12. -- Global settings
  13. -- This reactor ID
  14. reactorID = 2
  15.  
  16. -- Wireless channels
  17. wcStatus = 100
  18. wcCtl = 110
  19.  
  20. -- Minimum control rod setting - This is to prevent longer 'hunt' times to optimize temperature
  21. -- Note: This setting will be adjusted automatically as the reactor runs, but is not saved through restarts
  22. crmin = 0
  23.  
  24. -- Start pushing in control rods when temperature climbs above this temp
  25. tempmax = 995
  26. tempmin = 940
  27.  
  28. -- Start pushing in control rods when stored energy climbs above this percent
  29. -- Control rods will scale from crmin to 100%, starting from this %
  30. storpct = 30
  31.  
  32. -- There should be no need to edit code below this line
  33.  
  34.  
  35.  
  36. -- Utility function - return a wrapped variable for a specific peripheral
  37. function wrapThis(thing)
  38. local wrapped, i = nil, 0
  39. while wrapped == nil and i <= 100 do
  40. wrapped = peripheral.wrap(thing.."_"..i)
  41. i = i + 1
  42. end
  43. if wrapped == nil then
  44. return nil
  45. else
  46. return wrapped
  47. end
  48. end
  49.  
  50. -- Collect statistics for Local display and remote send
  51. function getStats()
  52. local curTemp = r.getFuelTemperature()
  53. local curFuel = r.getFuelAmount()
  54. local maxFuel = r.getFuelAmountMax()
  55. local curRF = r.getEnergyStored()
  56. local ctlRod = r.getControlRodLevel(0)
  57. local curFuelPct = curFuel/maxFuel*100
  58. local curRFPct = curRF/100000
  59. local curRFGen = r.getEnergyProducedLastTick()
  60. local active = r.getActive()
  61.  
  62. -- Round values
  63. curRFPct = math.floor((curRFPct*10))/10
  64. curFuelPct = math.floor((curFuelPct*10))/10
  65. curRFGen = math.floor(curRFGen)
  66.  
  67. return curTemp, curFuelPct, curRFPct, curRFGen, ctlRod, active
  68. end
  69.  
  70. -- Local status display
  71. function displayStatus()
  72. if mon == nil then
  73. return
  74. end
  75. local curTemp, curFuelPct, curRFPct, curRFGen, ctlRod, active = getStats()
  76. mon.clear()
  77. mon.setCursorPos(1,1)
  78. mon.write("Temp: "..curTemp)
  79. mon.setCursorPos(1,2)
  80. mon.write("Fuel: "..curFuelPct.."%")
  81. mon.setCursorPos(1,3)
  82. mon.write("Energy: "..curRFPct.."%")
  83. mon.setCursorPos(1,4)
  84. mon.write("RF Gen: "..curRFGen)
  85. mon.setCursorPos(1,5)
  86. mon.write("Control Rod: "..ctlRod.."%")
  87. mon.setCursorPos(1,6)
  88. mon.write("Min Control Rod: "..crmin.."%")
  89. mon.setCursorPos(1,7)
  90. if active then
  91. mon.write("Active")
  92. else
  93. mon.write("Shutdown")
  94. end
  95. end
  96.  
  97. -- Transmit current system stats on wireless channel
  98. function txStatus()
  99. if modem == nil then
  100. return
  101. end
  102. local curTemp, curFuelPct, curRFPct, curRFGen, ctlRod, active = getStats()
  103. local updateStr = "R:"..reactorID.." T:"..curTemp.." F:"..curFuelPct.." E:"..curRFPct.." G:"..curRFGen.." C:"..ctlRod.." S:"..crmin
  104. if active then
  105. updateStr = updateStr.." A:true"
  106. else
  107. updateStr = updateStr.." A:false"
  108. end
  109. modem.transmit(wcStatus, wcCtl, updateStr)
  110. end
  111.  
  112.  
  113. function main()
  114. print("Initializing reactor control...")
  115. print("Max Temp: "..tempmax)
  116. print("Control rod minimum: "..crmin.."%")
  117. print("Target Energy level: "..storpct.."%")
  118. -- Initialize connections to peripherals
  119. if initConnections() == false then
  120. return false
  121. end
  122.  
  123. -- Start the reactor
  124. startup()
  125.  
  126. -- Start our monitoring and control loop
  127. running = true
  128. local loopCount = 1
  129. os.startTimer(1)
  130. while running do
  131. local e, p1, p2, p3, p4, p5 = os.pullEvent()
  132.  
  133. if e == "key" then
  134. if p1 == 16 then -- 'q' key
  135. running = false
  136. elseif p1 == 13 then -- '=/+' key
  137. crmin = crmin + 10
  138. elseif p1 == 12 then -- '-' key
  139. crmin = crmin - 10
  140. elseif p1 == 18 then -- 'e'
  141. r.setActive(false)
  142. elseif p1 == 19 then -- 'r'
  143. r.setActive(true)
  144. end
  145. elseif e == "modem_message" and p2 == wcCtl then
  146. local rid, cmd = string.gmatch(p4, "%S+")
  147. if rid == reactorID then
  148. if cmd == 'stop' then
  149. r.setActive(false)
  150. elseif cmd == 'start' then
  151. r.setActive(true)
  152. elseif cmd == 'crminup' then
  153. crmin = crmin + 10
  154. elseif cmd == 'crmindown' then
  155. crmin = crmin - 10
  156. end
  157. end
  158. elseif e == "timer" then
  159. os.startTimer(1)
  160. end
  161.  
  162. -- Constrain the control rod settings
  163. if crmin < 0 then
  164. crmin = 0
  165. elseif crmin > 100 then
  166. crmin = 100
  167. end
  168.  
  169. -- Run reactor controls every 10 cycles - this allows for some time for things to stabilize after each adjustment
  170. if loopCount > 10 then
  171. manageReactor()
  172. loopCount = 1
  173. end
  174.  
  175. -- Update the displays after every loop
  176. displayStatus()
  177. txStatus()
  178. loopCount = loopCount + 1
  179. end
  180. cleanup()
  181. return true
  182. end
  183.  
  184. -- Initialize connections to peripherals. Only return false if we can't talk to the reactor
  185. function initConnections()
  186. -- Connect to reactor
  187. r = wrapThis("BigReactors-Reactor")
  188. if r == nil then
  189. print("No reactor found")
  190. return false
  191. end
  192.  
  193. -- Check to see if we have a valid reactor
  194. if r.getConnected() == false then
  195. print("Reactor not connected")
  196. return false
  197. end
  198.  
  199. -- Connect monitor
  200. mon = wrapThis("monitor")
  201. if mon == nil then
  202. print("No monitor found, full status display disabled")
  203. else
  204. -- Start things off with current status
  205. displayStatus()
  206. end
  207.  
  208. -- Connect wireless network - wireless modem needs to be on top
  209. modem = peripheral.wrap("top")
  210. if modem == nil then
  211. print("No wireless modem found. No remote status/control enabled")
  212. else
  213. txStatus()
  214. -- Open control channel
  215. modem.open(wcCtl)
  216. end
  217. return true
  218. end
  219.  
  220. -- Configure initial control rod settings and activate reactor
  221. function startup()
  222. -- Verify initial control rod state and activate reactor (if needed)
  223. local curTemp, curFuelPct, curRFPct, curRFGen, ctlRod, active = getStats()
  224. if ctlRod < crmin then
  225. r.setAllControlRodLevels(crmin)
  226. end
  227. if active == false then
  228. r.setActive(true)
  229. end
  230. end
  231.  
  232. -- Cleanup reactor before exiting
  233. -- Note: This will shutdown the reactor to avoid having the reactor run without supervision
  234. function cleanup()
  235. r.setActive(false)
  236. end
  237.  
  238. -- Adjust reactor status based on temperature, energy level and control rod settings
  239. function manageReactor()
  240.  
  241. local cRT = r.getControlRodLevel(0)
  242.  
  243. -- First, if the control rods are lower than our minimum setting, just bump it up
  244. if cRT < crmin then
  245. r.setAllControlRodLevels(crmin)
  246. end
  247.  
  248.  
  249. local curTemp, curFuelPct, curRFPct, curRFGen, ctlRod, active = getStats()
  250. ctlSet = ctlRod
  251. ctTargR = 0
  252.  
  253. -- If the reactor stored energy is above the target, start pushing the control rods in - scale from crmin to 100
  254. -- Better to run the reactor at 50% stable than turn it full on/off to maintain energy reserve?
  255. -- Scale insertion speed based on how far above the target we are? - similar to temp adjustments
  256. -- Figure out the target control rod setting based on energy storage
  257. if curRFPct > storpct then
  258. ctScale = 100 - crmin
  259. esScale = 100 - storpct
  260. esLvl = curRFPct - storpct
  261. esMult = esLvl / esScale
  262. ctTargR = ctScale * esMult + crmin
  263. ctTargR = math.floor(ctTargR)
  264. end
  265.  
  266. -- Look for control rod insertion, adjust and return if matched
  267.  
  268. -- If the reactor temp is too high, start pushing the control rods in - continue if matched
  269. if curTemp > tempmax then
  270. local dT = curTemp - tempmax
  271. if dT > 100 then
  272. dR = 15
  273. elseif dT > 30 then
  274. dR = 10
  275. elseif dT > 20 then
  276. dR = 5
  277. elseif dT > 10 then
  278. dR = 2
  279. elseif dT > 5 then
  280. dR = 1
  281. end
  282. ctlSet = ctlRod + dR
  283. end
  284.  
  285. -- Apply energy load adjustment
  286. if ctTargR > ctlSet then
  287. ctlSet = ctTargR
  288. end
  289.  
  290. -- If we are pushing the control rods in, then we need to do that here and then return - Note - a hot and charged reactor will scale control rods very quickly
  291. if ctlSet > 100 then
  292. ctlSet = 100
  293. end
  294. if ctlSet > ctlRod then
  295. r.setAllControlRodLevels(ctlSet)
  296. return
  297. end
  298.  
  299. -- If the reactor temp is too low, retract control rods
  300. if curTemp < tempmin then
  301. local dT = tempmin - curTemp
  302. if dT > 100 then
  303. dR = 15
  304. elseif dT > 70 then
  305. dR = 10
  306. elseif dT > 40 then
  307. dR = 5
  308. elseif dT > 20 then
  309. dR = 2
  310. elseif dT > 10 then
  311. dR = 1
  312. end
  313. ctlSet = ctlSet - dR
  314. end
  315.  
  316. -- Apply energy load adjustment
  317. if ctTargR > ctlSet then
  318. ctlSet = ctTargR
  319. end
  320.  
  321. -- Retract control rods
  322. if ctlSet < crmin then
  323. ctlSet = crmin
  324. end
  325. if ctlSet <= ctlRod then
  326. r.setAllControlRodLevels(ctlSet)
  327. end
  328. end
  329.  
  330. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement