Advertisement
Guest User

ptm.lua

a guest
Dec 16th, 2017
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.40 KB | None | 0 0
  1. print("Plasma turbine monitor v.0.3")
  2.  
  3. local event = require("event")
  4. local cmp = require("component")
  5. local sides = require("sides")
  6. local computer = require("computer")
  7.  
  8. local durability = 1536000
  9. local durabilityMin = 13180
  10. local rotorTime = 0
  11. local nominalOut = 28643
  12.  
  13. local exitPending = false
  14. local eu = 0
  15. local plasma = 0
  16. local rotor_start_time = 0
  17.  
  18. local eu_min = 10000000
  19. local eu_max = 3600000000
  20. local plasma_min = 8
  21. local plasma_max = 16
  22. local durabilityPeriod = 75
  23.  
  24. local slow_timer = -1
  25. local warm_timer = -1
  26. local dur_timer = -1
  27.  
  28. local tank = cmp.tank_controller
  29. local trans = cmp.transposer
  30. local bat = cmp.gt_batterybuffer
  31. local red = cmp.redstone
  32.  
  33. --load cells
  34.  
  35. local function readConfig()
  36.   local f = io.open("ptm.cfg", "r")
  37.   if f then
  38.     line = f:read() if line ~= nil then durability = tonumber(line) end
  39.     line = f:read() if line ~= nil then durabilityMin = tonumber(line) end
  40.     line = f:read() if line ~= nil then rotorTime = tonumber(line) end
  41.     line = f:read() if line ~= nil then nominalOut = tonumber(line) end
  42.     f:close()
  43.   end
  44. end
  45.  
  46. local function saveConfig()
  47.   local f = io.open("ptm.cfg", "w")
  48.   if f then
  49.     f:write(durability.."\n")
  50.     f:write(durabilityMin.."\n")
  51.     f:write(rotorTime.."\n")
  52.     f:write(nominalOut.."\n")
  53.     f:close()
  54.   end
  55. end
  56.  
  57. local function hysteresisOFF(state, value, vmin, vmax)
  58.   local r = state
  59.   if (not state) then
  60.     if (value < vmin) then r = true end
  61.   else
  62.     if (value > vmax) then r = false end
  63.   end
  64.   return r
  65. end
  66.  
  67. local function hysteresisON(state, value, vmin, vmax)
  68.   local r = state
  69.   if (state) then
  70.     if (value < vmin) then r = false end
  71.   else
  72.     if (value > vmax) then r = true end
  73.   end
  74.   return r
  75. end
  76.  
  77. local function getEUStored()
  78.   local eu = bat.getEUStored() + bat.getBatteryCharge(1)
  79.   return eu
  80. end
  81.  
  82. local function getPlasmaStored()
  83.   local sns = tank.getSensorInformation()
  84.   local value = tonumber(string.sub(sns[4],1,-2))
  85.   return value
  86. end
  87.  
  88. -- State machine definitions
  89.  
  90. local stStandBy = 1
  91. local stWarmingUp = 2
  92. local stRun = 3
  93. local stSlowingDown = 4
  94. local stShutDown = 5
  95.  
  96. local m_state = stStandBy
  97. local m_state_pending = stStandBy
  98. local m_entry = {}
  99. local m_in_state = {}
  100. local m_exit = {}
  101.  
  102. local function state2str(value)
  103.   local s = "undef"
  104.   if value == stStandBy then
  105.     s = "stStandBy"
  106.   end
  107.   if value == stWarmingUp then
  108.     s = "stWarmingUp"
  109.   end
  110.   if value == stRun then
  111.     s = "stRun"
  112.   end
  113.   if value == stSlowingDown then
  114.     s = "stSlowingDown"
  115.   end
  116.   if value == stShutDown then
  117.     s = "stShutDown"
  118.   end
  119.   return s.."("..value..")"
  120. end
  121.  
  122. local function assignState(value, on_entry, in_state, on_exit)
  123.   m_entry[value] = on_entry
  124.   m_in_state[value] = in_state
  125.   m_exit[value] = on_exit
  126. end
  127.  
  128. local function switchState()
  129.   if m_exit[m_state] ~= nul then
  130.     print("exit from "..state2str(m_state))
  131.     m_exit[m_state]()
  132.   end
  133.  
  134.   print("assign "..state2str(m_state_pending))
  135.   m_state = m_state_pending
  136.  
  137.   if m_entry[m_state] ~= nul then
  138.     print("enter in "..state2str(m_state))
  139.     m_entry[m_state]()
  140.   end
  141. end
  142.  
  143. local function s_standby()
  144.   if exitPending then
  145.     m_state_pending = stShutDown
  146.   else
  147.     if eu < eu_min and plasma > plasma_min then
  148.       local r = trans.transferFluid(sides.west, sides.up, 1000)
  149.       print("fluid: ", r)
  150.       if r then
  151.          m_state_pending = stWarmingUp
  152.       else
  153.         print("# Cannot load plasma cells")
  154.       end
  155.     end
  156.   end
  157. end
  158.  
  159. local function sin_warming()
  160.   warm_timer = event.timer(51, handle_warming_timer, 1)
  161. end
  162.  
  163. function handle_warming_timer()
  164.   warm_timer = -1
  165.   print("handle_warming_timer()")
  166.   m_state_pending = stRun
  167. end
  168.  
  169. local function s_warming()
  170.   if exitPending then
  171.     m_state_pending = stShutDown
  172.   end
  173. end
  174.  
  175. local function sout_warming()
  176.   if warm_timer ~= -1 then
  177.     event.cancel(warm_timer)
  178.   end
  179. end
  180.  
  181. local function sin_run()
  182.   print("Enable main plasma flow ...")
  183.   red.setOutput(sides.west, 255) -- enable main plasma flow
  184.   dur_timer = event.timer(durabilityPeriod, handle_dur_timer, math.huge)
  185.   rotor_start_time = computer.uptime()
  186. end
  187.  
  188. local function s_run()
  189.   if exitPending or eu > eu_max or plasma < plasma_min or durability <= durabilityMin then
  190.     m_state_pending = stSlowingDown
  191.   end
  192. end
  193.  
  194. function handle_dur_timer()
  195.   durability = durability - math.floor(math.pow(nominalOut, 0.7) + 0.5)
  196.   print("Calculate durability ... "..durability)
  197. end
  198.  
  199. local function sin_slowing()
  200.   print("Disable main plasma flow ...")
  201.   red.setOutput(sides.west, 0) -- disable main plasma flow
  202.   slow_timer = event.timer(60, handle_slowing_timer, 1)
  203. end
  204.  
  205. function handle_slowing_timer()
  206.   print("handle_slowing_timer()")
  207.   if exitPending or durability <= durabilityMin then
  208.     m_state_pending = stShutDown
  209.   else
  210.     m_state_pending = stStandBy
  211.   end
  212. end
  213.  
  214. function sout_slowing()
  215.   rotorTime = rotorTime + (computer.uptime() - rotor_start_time)
  216.   print("Rotor time: "..rotorTime)
  217.   event.cancel(dur_timer)
  218.   dur_timer = -1
  219. end
  220.  
  221. function sin_shutdown()
  222.   if durability <= durabilityMin then
  223.     print("# Replace rotor !!! Durability is too low: "..durability)
  224.   end
  225. end
  226.  
  227. assignState(stStandBy,     nul,          s_standby, nul)
  228. assignState(stWarmingUp,   sin_warming,  s_warming, sout_warming)
  229. assignState(stRun,         sin_run,      s_run,     nul)
  230. assignState(stSlowingDown, sin_slowing,  nul,       sout_slowing)
  231. assignState(stShutDown,    sin_shutdown, nul,       nul)
  232.  
  233. -- Main
  234.  
  235. function handleKeyDown(A, keybAddr, ch, code, pName)
  236.   if (ch == 32) then
  237.     print("Exit pending ...")
  238.     exitPending = true
  239.     return
  240.   end
  241.   --print(A, keybAddr, ch, code, pName)
  242. end
  243.  
  244. local function Main()
  245.   local cnt = 0
  246.   local s = ""
  247.   local t = 0
  248.   local eu_old = 0
  249.   local de = 0
  250.   while m_state ~= stShutDown do
  251.     cnt = cnt + 1
  252.     if cnt > 0 then
  253.       cnt = 0
  254.       eu = getEUStored()
  255.       plasma = tank.getTankLevel(sides.south)
  256.       if m_in_state[m_state] ~= nul then m_in_state[m_state]() end
  257.      
  258.       t = computer.uptime()
  259.       de = eu - eu_old
  260.       eu_old = eu
  261.  
  262.       s = plasma < plasma_min and "LOW" or ""
  263.       print("t: "..t,"st: "..m_state,"eu: "..eu,"de: "..de,"pls: "..plasma..s.."  dur: "..durability)
  264.     end
  265.     if m_state ~= m_state_pending then switchState() end
  266.  
  267.     os.sleep(2)
  268.     --event.debug_tick()
  269.   end
  270. end
  271.  
  272. red.setOutput(sides.west, 0)
  273. readConfig()
  274. if durability > durabilityMin then
  275.   event.listen("key_down", handleKeyDown)
  276.   Main()
  277.   event.ignore("key_down", handleKeyDown)
  278.   if dur_timer ~= -1 then
  279.     event.cancel(dur_timer)
  280.   end
  281.   red.setOutput(sides.west, 0) -- disable main flow
  282.   saveConfig()
  283. else
  284.   sin_repair()
  285. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement