Advertisement
downwind

Multiple Turbine Display

May 28th, 2015
280
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.42 KB | None | 0 0
  1. os.loadAPI("button")
  2.  
  3. --Based on the PID Controller first posted by Copper280z on Reddit:
  4. --http://www.reddit.com/r/feedthebeast/comments/2pxwzo/big_reactors_like_br_turbines_but_dont_like/
  5. --Heavily Modified by LezChap for use with Multiple Turbines and Turbine Control
  6. --Turbine Graphic Code used from Direwolf20's Reactor Controler (youtube.com/watch?v=l7ZwSFVYITU)
  7. --Button API modified from Direwolf20 (youtube link above)
  8.  
  9. --Based on the above modifications ^ posted at:
  10. --http://www.reddit.com/r/feedthebeast/comments/2tgea8/dw20_103_reactor_pid_and_turbine_controller/
  11. --Modified by LiLRichy to remove reactor and turbine controls and automation and only display values.5/28/2015
  12.  
  13. --  ***  Requires Button API found at: http://pastebin.com/BqVQJgFM  ***
  14.  
  15. local turbines = {peripheral.find("BigReactors-Turbine")}
  16. local mon = peripheral.find("monitor")
  17. local totalTurbines = #turbines
  18.  
  19. --Change number below for your setup
  20. rednet.open("bottom") --modem connected to Capacitor Relay Computer
  21. local goalRPM = 1800
  22.  
  23. --Tweak these numbers if needed, as per Copper280z's post on Reddit (linked in header)
  24. local P = .4
  25. local I = .000001
  26. local D = 12
  27.  
  28. --initiating variables
  29. local integral = 0
  30. local derivative = 0
  31. local error = 0
  32. local prevError = 0
  33. local table = {}
  34. local needEngaged = false
  35. local needShutdown = false
  36. local turbineSpeed = 0
  37.  
  38. local slowdown = {}
  39. for k,v in ipairs(turbines) do
  40.   slowdown[k] = false
  41. end
  42.  
  43. local CRchange = 0
  44. local newCR = 0
  45. local turbinePage = 0
  46. local lastPage = 1
  47. local pages = math.ceil(totalTurbines / 4)
  48. mon.clear()
  49.  
  50. local turbineSpeed = 0
  51. local countTurbines = 0
  52. local timerCounter = 0
  53.  
  54. function PID()
  55.   turbineSpeed = 0
  56.   local turbineNeedSteam = false
  57.   for k,v in pairs(turbines) do
  58.     local tempSpeed = v.getRotorSpeed()
  59.     turbineSpeed = turbineSpeed + tempSpeed
  60.     --if one turbine is too low, make sure steam is produced
  61.     if tempSpeed < (goalRPM - 6) then
  62.       turbineNeedSteam = true
  63.     end
  64.   end
  65.   turbineSpeed = turbineSpeed / totalTurbines
  66.   error = goalRPM - turbineSpeed
  67.  
  68.   integral = integral + error
  69.   derivative = error - prevError
  70.  
  71.   if integral > 1000 then
  72.     integral = 1000
  73.   end
  74.  
  75.   if integral < -1000 then
  76.     integral = -1000
  77.   end
  78.  
  79.   countTurbines = 0
  80.   for k,v in ipairs(slowdown) do
  81.     if not v then
  82.       countTurbines = countTurbines + 1
  83.     end
  84.   end
  85.  end
  86.  
  87. function doTurbineLogic()
  88.   for k,v in ipairs(turbines) do
  89.     local turbSpeed = v.getRotorSpeed()
  90.     local flowRate = v.getFluidFlowRateMax()
  91.     local maxFlowRate = v.getFluidFlowRateMaxMax()
  92.     local safeShutdown = false
  93.     local tooSlow = false
  94.     local coils = v.getInductorEngaged()
  95.  
  96.     if turbSpeed > goalRPM + 50 then
  97.       safeShutdown = false
  98.     elseif turbSpeed < goalRPM - 10 then
  99.       tooSlow = true
  100.     else
  101.       tooSlow = false
  102.       safeShutdown = true
  103.     end
  104.     needEngaged = false
  105.     needShutdown = false
  106.      
  107.     if turbSpeed > goalRPM + 5 then
  108.       slowdown[k] = true
  109.     end
  110.     if turbSpeed < goalRPM then
  111.       slowdown[k] = false
  112.     end
  113.     --does the system need power, or have too much?
  114.     if table.monitor and table.currPower < 10000000 then
  115.       needEngaged = true
  116.       needShutdown = false
  117.     elseif not table.montitor and table.currPower > shutdownPower then
  118.       needEngaged = false
  119.       needShutdown = true
  120.     end
  121.   end
  122. end
  123.  
  124. function toint(num)  --removes decimals from strings
  125.   return string.format("%d", tostring(num))
  126. end  
  127.  
  128. function commaformat(num)  --puts a comma every 3 digits in a number (From Direwolf20)
  129.   local formatted = num
  130.   local neg = false
  131.   if formatted < 0 then
  132.     formatted = math.abs(formatted)
  133.     neg = true
  134.   end
  135.   while true do
  136.     formatted, k = string.gsub(formatted, "^(%d+)(%d%d%d)", '%1,%2')
  137.     if k == 0 then
  138.       break
  139.     end
  140.   end
  141.   if neg then
  142.     formatted = "-"..formatted
  143.   end
  144.  
  145.   return formatted
  146. end
  147.  
  148. function displayHeader()
  149.   mon.setTextScale(1)
  150.   mon.setBackgroundColor(colors.black)
  151.   mon.setTextColor(colors.white)
  152.   mon.setCursorPos(1,1)
  153.   mon.clearLine()
  154.  
  155.   --Start First Line of Header
  156.   mon.write("Average RPM: ")
  157.   if error > 4 or error < -4 then
  158.     mon.setTextColor(colors.red)
  159.   else
  160.     mon.setTextColor(colors.green)
  161.   end
  162.   mon.write(toint(turbineSpeed))
  163.  
  164.   local x, y = mon.getSize()
  165.   local middle = (x/2) + 3
  166.  
  167.   mon.setTextColor(colors.white)
  168.   mon.setCursorPos(middle, 1)
  169.   mon.write("Turbines Active: ")
  170.   mon.write(toint(countTurbines).." of "..totalTurbines)
  171.  
  172.   --start second line of Header
  173.   mon.setTextColor(colors.white)
  174.   mon.setCursorPos(1,2)
  175.   mon.clearLine()
  176.   mon.write("Goal RPM: "..goalRPM)
  177.  
  178.   mon.setCursorPos(middle, 2)
  179.   mon.write("Power Produced: ")
  180.   local totalEnergyProduced = 0
  181.   for k,v in ipairs(turbines) do
  182.     totalEnergyProduced = totalEnergyProduced + v.getEnergyProducedLastTick()
  183.   end
  184.   if totalEnergyProduced > (23500 * totalTurbines) then
  185.     mon.setTextColor(colors.green)
  186.   else
  187.     mon.setTextColor(colors.red)
  188.   end
  189.   totalEnergyProduced = toint(totalEnergyProduced)
  190.   totalEnergyProduced = tonumber(totalEnergyProduced)
  191.   mon.write(commaformat(totalEnergyProduced).."RF/t")
  192. end
  193.  
  194.   --start third line of Header "not used but left incase it is needed later on"
  195.   --mon.setTextColor(colors.white)
  196.   --mon.setCursorPos(1,3)
  197.   --mon.clearLine()
  198.  
  199.   --start fourth line of Header "not used but left incase it is needed later on"
  200.   --mon.setTextColor(colors.white)
  201.   --mon.setCursorPos(1,4)
  202.   --mon.clearLine()
  203.  
  204. function displayTurbines(page)
  205.   local turbineStartNum = (page * 4) + 1
  206.   local turbinesOnPage = totalTurbines - turbineStartNum + 1
  207.   if turbinesOnPage > 4 then
  208.     turbinesOnPage = 4
  209.   end
  210.   if turbinesOnPage < 1 then
  211.     turbinesOnPage = 1
  212.   end
  213.   local x,y = mon.getSize()
  214.   local xInterval = math.floor(x/(turbinesOnPage + 1))
  215.   local turbinePagePeriph = {}
  216.   local temp = 1
  217.   for i = turbineStartNum, (turbineStartNum + turbinesOnPage - 1) do
  218.     turbinePagePeriph[temp] = turbines[i]
  219.     --print(i.." "..turbines[i])
  220.     temp = temp + 1
  221.   end
  222.   --clear text variables of Turbines
  223.   --mon.setCursorPos(1,5)
  224.   --mon.clearLine()
  225.   mon.setCursorPos(1,18)
  226.   mon.clearLine()
  227.   mon.setCursorPos(1,19)
  228.   mon.clearLine()
  229.  
  230.   for k,v in ipairs(turbinePagePeriph) do
  231.     --display Turbine info on Monitor
  232.     local xCenter = (k * xInterval)
  233.  
  234.     --display Turbine Title (Turbine #)
  235.     local turbineTitle = "Turbine "..tostring(k + turbineStartNum - 1)
  236.     local titleXStart = xCenter - math.floor(string.len(turbineTitle) / 2)
  237.     mon.setTextColor(colors.lightBlue)
  238.     mon.setCursorPos(titleXStart, 5)
  239.     mon.write(turbineTitle)
  240.  
  241.     --display individual turbine RPMs
  242.     local turbineRPM = toint(v.getRotorSpeed())
  243.     local RPMXStart = xCenter - math.floor(string.len("RPM"..tostring(turbineRPM)) / 2)
  244.     mon.setCursorPos(RPMXStart, 18)
  245.    
  246.     if goalRPM - turbineRPM > 4 or goalRPM - turbineRPM < -4 then
  247.       mon.setTextColor(colors.red)
  248.     else
  249.       mon.setTextColor(colors.green)
  250.     end
  251.     mon.write(turbineRPM.."RPM")
  252.  
  253.     --display individual turbine power outputs
  254.     local powerMade = v.getEnergyProducedLastTick()
  255.     if powerMade > 0 then
  256.       mon.setTextColor(colors.green)
  257.     else
  258.       mon.setTextColor(colors.red)
  259.     end
  260.     powerMade = toint(powerMade)
  261.     powerMade = tonumber(powerMade)
  262.     powerMade = commaformat(powerMade).."RF"
  263.     local powerXStart = xCenter - math.floor(string.len(powerMade) / 2)
  264.     mon.setCursorPos(powerXStart, 19)
  265.     mon.write(powerMade)
  266.   end
  267.  
  268.   --display turbine graphics/coils
  269.   for k,v in ipairs(turbinePagePeriph) do
  270.     local xCenter = (k * xInterval)
  271.     local turbineXStart = xCenter - 3
  272.     local coilColor
  273.     if v.getInductorEngaged() then
  274.       coilColor = colors.red
  275.     else
  276.       coilColor = colors.blue
  277.     end
  278.     mon.setBackgroundColor(colors.gray)
  279.     mon.setCursorPos(turbineXStart, 6)
  280.     mon.write("       ")
  281.     for i=7,13 do
  282.       mon.setCursorPos(turbineXStart, i)
  283.       mon.setBackgroundColor(colors.gray)
  284.       mon.write(" ")
  285.       mon.setBackgroundColor(colors.lightGray)
  286.       mon.write(" ")
  287.       if i % 2 == 0 then
  288.         mon.setBackgroundColor(colors.gray)
  289.       end
  290.       mon.write(" ")
  291.       mon.setBackgroundColor(colors.gray)
  292.       mon.write(" ")
  293.       if i % 2 ~= 0 then
  294.         mon.setBackgroundColor(colors.lightGray)
  295.       end
  296.       mon.write(" ")
  297.       mon.setBackgroundColor(colors.lightGray)
  298.       mon.write(" ")
  299.       mon.setBackgroundColor(colors.gray)
  300.       mon.write(" ")
  301.     end
  302.     for i=14,16 do
  303.       mon.setCursorPos(turbineXStart, i)
  304.       mon.setBackgroundColor(colors.gray)
  305.       mon.write(" ")
  306.       mon.setBackgroundColor(colors.lightGray)
  307.       mon.write(" ")
  308.       mon.setBackgroundColor(coilColor)
  309.       mon.write(" ")
  310.       mon.setBackgroundColor(colors.gray)
  311.       mon.write(" ")
  312.       mon.setBackgroundColor(coilColor)
  313.       mon.write(" ")
  314.       mon.setBackgroundColor(colors.lightGray)
  315.       mon.write(" ")
  316.       mon.setBackgroundColor(colors.gray)
  317.       mon.write(" ")
  318.     end
  319.   mon.setCursorPos(turbineXStart, 17)
  320.   mon.write("       ")
  321.   mon.setBackgroundColor(colors.black)
  322.   end
  323. end
  324.  
  325. --change Turbine page
  326. function turnPage(num)
  327.   turbinePage = num
  328.   mon.clear()
  329.   displayScreen()
  330. end
  331.  
  332. --show buttons to change pages
  333. function displayPageButtons(page)
  334.   button.clearTable()
  335.   mon.setTextColor(colors.black)
  336.   if page > 0 then
  337.     local param = page - 1
  338.     button.setTable("<<", turnPage, param, 1, 3, 10, 12)
  339.   end
  340.   if page < (pages-1) then
  341.     local param = page + 1
  342.     button.setTable(">>", turnPage, param, 48, 50, 10, 12)
  343.   end
  344.   button.screen()
  345. end
  346.  
  347. function displayScreen()
  348.   displayHeader()
  349.   displayTurbines(turbinePage)
  350.   if pages > 1 and lastPage ~= turbinePage then  --only refresh buttons if page changes
  351.     displayPageButtons(turbinePage)
  352.     lastPage = turbinePage
  353.   end
  354. end
  355.  
  356. displayScreen()
  357. os.startTimer(.1)
  358.  
  359. while true do
  360.   local event, param1, param2, param3 = os.pullEvent()
  361.  
  362.   --do timed events, restart timer
  363.   if event == "timer" then
  364.     os.startTimer(.1)
  365.     PID()
  366.     if not (table.monitor == nil) then
  367.       doTurbineLogic()
  368.     end
  369.     timerCounter = timerCounter + 1
  370.     --update display every half second
  371.     if timerCounter % 5 == 0 then
  372.       timerCounter = 0
  373.       displayScreen()
  374.     end
  375.   end
  376.  
  377.   --parse monitor clicks to API
  378.   if event == "monitor_touch" then
  379.     button.checkxy(param2, param3)
  380.   end
  381. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement