Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- print("Plasma turbine monitor v.0.3")
- local event = require("event")
- local cmp = require("component")
- local sides = require("sides")
- local computer = require("computer")
- local durability = 1536000
- local durabilityMin = 13180
- local rotorTime = 0
- local nominalOut = 28643
- local exitPending = false
- local eu = 0
- local plasma = 0
- local rotor_start_time = 0
- local eu_min = 10000000
- local eu_max = 3600000000
- local plasma_min = 8
- local plasma_max = 16
- local durabilityPeriod = 75
- local slow_timer = -1
- local warm_timer = -1
- local dur_timer = -1
- local tank = cmp.tank_controller
- local trans = cmp.transposer
- local bat = cmp.gt_batterybuffer
- local red = cmp.redstone
- --load cells
- local function readConfig()
- local f = io.open("ptm.cfg", "r")
- if f then
- line = f:read() if line ~= nil then durability = tonumber(line) end
- line = f:read() if line ~= nil then durabilityMin = tonumber(line) end
- line = f:read() if line ~= nil then rotorTime = tonumber(line) end
- line = f:read() if line ~= nil then nominalOut = tonumber(line) end
- f:close()
- end
- end
- local function saveConfig()
- local f = io.open("ptm.cfg", "w")
- if f then
- f:write(durability.."\n")
- f:write(durabilityMin.."\n")
- f:write(rotorTime.."\n")
- f:write(nominalOut.."\n")
- f:close()
- end
- end
- local function hysteresisOFF(state, value, vmin, vmax)
- local r = state
- if (not state) then
- if (value < vmin) then r = true end
- else
- if (value > vmax) then r = false end
- end
- return r
- end
- local function hysteresisON(state, value, vmin, vmax)
- local r = state
- if (state) then
- if (value < vmin) then r = false end
- else
- if (value > vmax) then r = true end
- end
- return r
- end
- local function getEUStored()
- local eu = bat.getEUStored() + bat.getBatteryCharge(1)
- return eu
- end
- local function getPlasmaStored()
- local sns = tank.getSensorInformation()
- local value = tonumber(string.sub(sns[4],1,-2))
- return value
- end
- -- State machine definitions
- local stStandBy = 1
- local stWarmingUp = 2
- local stRun = 3
- local stSlowingDown = 4
- local stShutDown = 5
- local m_state = stStandBy
- local m_state_pending = stStandBy
- local m_entry = {}
- local m_in_state = {}
- local m_exit = {}
- local function state2str(value)
- local s = "undef"
- if value == stStandBy then
- s = "stStandBy"
- end
- if value == stWarmingUp then
- s = "stWarmingUp"
- end
- if value == stRun then
- s = "stRun"
- end
- if value == stSlowingDown then
- s = "stSlowingDown"
- end
- if value == stShutDown then
- s = "stShutDown"
- end
- return s.."("..value..")"
- end
- local function assignState(value, on_entry, in_state, on_exit)
- m_entry[value] = on_entry
- m_in_state[value] = in_state
- m_exit[value] = on_exit
- end
- local function switchState()
- if m_exit[m_state] ~= nul then
- print("exit from "..state2str(m_state))
- m_exit[m_state]()
- end
- print("assign "..state2str(m_state_pending))
- m_state = m_state_pending
- if m_entry[m_state] ~= nul then
- print("enter in "..state2str(m_state))
- m_entry[m_state]()
- end
- end
- local function s_standby()
- if exitPending then
- m_state_pending = stShutDown
- else
- if eu < eu_min and plasma > plasma_min then
- local r = trans.transferFluid(sides.west, sides.up, 1000)
- print("fluid: ", r)
- if r then
- m_state_pending = stWarmingUp
- else
- print("# Cannot load plasma cells")
- end
- end
- end
- end
- local function sin_warming()
- warm_timer = event.timer(51, handle_warming_timer, 1)
- end
- function handle_warming_timer()
- warm_timer = -1
- print("handle_warming_timer()")
- m_state_pending = stRun
- end
- local function s_warming()
- if exitPending then
- m_state_pending = stShutDown
- end
- end
- local function sout_warming()
- if warm_timer ~= -1 then
- event.cancel(warm_timer)
- end
- end
- local function sin_run()
- print("Enable main plasma flow ...")
- red.setOutput(sides.west, 255) -- enable main plasma flow
- dur_timer = event.timer(durabilityPeriod, handle_dur_timer, math.huge)
- rotor_start_time = computer.uptime()
- end
- local function s_run()
- if exitPending or eu > eu_max or plasma < plasma_min or durability <= durabilityMin then
- m_state_pending = stSlowingDown
- end
- end
- function handle_dur_timer()
- durability = durability - math.floor(math.pow(nominalOut, 0.7) + 0.5)
- print("Calculate durability ... "..durability)
- end
- local function sin_slowing()
- print("Disable main plasma flow ...")
- red.setOutput(sides.west, 0) -- disable main plasma flow
- slow_timer = event.timer(60, handle_slowing_timer, 1)
- end
- function handle_slowing_timer()
- print("handle_slowing_timer()")
- if exitPending or durability <= durabilityMin then
- m_state_pending = stShutDown
- else
- m_state_pending = stStandBy
- end
- end
- function sout_slowing()
- rotorTime = rotorTime + (computer.uptime() - rotor_start_time)
- print("Rotor time: "..rotorTime)
- event.cancel(dur_timer)
- dur_timer = -1
- end
- function sin_shutdown()
- if durability <= durabilityMin then
- print("# Replace rotor !!! Durability is too low: "..durability)
- end
- end
- assignState(stStandBy, nul, s_standby, nul)
- assignState(stWarmingUp, sin_warming, s_warming, sout_warming)
- assignState(stRun, sin_run, s_run, nul)
- assignState(stSlowingDown, sin_slowing, nul, sout_slowing)
- assignState(stShutDown, sin_shutdown, nul, nul)
- -- Main
- function handleKeyDown(A, keybAddr, ch, code, pName)
- if (ch == 32) then
- print("Exit pending ...")
- exitPending = true
- return
- end
- --print(A, keybAddr, ch, code, pName)
- end
- local function Main()
- local cnt = 0
- local s = ""
- local t = 0
- local eu_old = 0
- local de = 0
- while m_state ~= stShutDown do
- cnt = cnt + 1
- if cnt > 0 then
- cnt = 0
- eu = getEUStored()
- plasma = tank.getTankLevel(sides.south)
- if m_in_state[m_state] ~= nul then m_in_state[m_state]() end
- t = computer.uptime()
- de = eu - eu_old
- eu_old = eu
- s = plasma < plasma_min and "LOW" or ""
- print("t: "..t,"st: "..m_state,"eu: "..eu,"de: "..de,"pls: "..plasma..s.." dur: "..durability)
- end
- if m_state ~= m_state_pending then switchState() end
- os.sleep(2)
- --event.debug_tick()
- end
- end
- red.setOutput(sides.west, 0)
- readConfig()
- if durability > durabilityMin then
- event.listen("key_down", handleKeyDown)
- Main()
- event.ignore("key_down", handleKeyDown)
- if dur_timer ~= -1 then
- event.cancel(dur_timer)
- end
- red.setOutput(sides.west, 0) -- disable main flow
- saveConfig()
- else
- sin_repair()
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement