Advertisement
PlatinKinggg

orchestrator.lua

May 29th, 2025 (edited)
689
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 12.46 KB | Gaming | 0 0
  1. -- Datei: orchestrator.lua
  2. -- Hauptsteuerung für mehrere Turbinen (standardisierte API für alle Modvarianten)
  3.  
  4.  
  5. -- Laden aller benötigten Programmdateien
  6. -- Loading of all neccessary programfiles
  7. local turbine = require("turbine")
  8. local state = require("state")
  9. local gui = require("gui")
  10. local language = require("language")
  11. local settings = state.settings
  12. local langKey = state.langKey
  13.  
  14. local rebootRequested = false
  15.  
  16. state.turbines = turbine.getTurbines()
  17.  
  18. for id, t in ipairs(state.turbines) do
  19.     state.turbineInfos[id] = turbine.getTurbineInfo(t)
  20.     state.lastRotorSpeed[id] = state.turbineInfos[id].rotorSpeed
  21.     print(state.turbineInfos[id].rotorSpeed)
  22.     state.bladeEfficiencyFlow[id] = state.turbineInfos[id].numberOfBlades * settings.mBPerBlade
  23.     state.turbineDiagnosis[id] = { coilFault = false, lastFaultTime = 0, multiBlockFault = false, energyLimitReached = false }
  24.     state.rpmDelta[id] = state.turbineInfos[id].rotorSpeed - state.lastRotorSpeed[id]
  25. end
  26.  
  27. -- ==== LOGIKFUNKTION ZUR TURBINENBEWERTUNG ==================================
  28.  
  29. local function evaluate(id)
  30.     local action = {
  31.         shouldActivate = state.turbineInfos[id].active,
  32.         inductorStatus = state.turbineInfos[id].inductorEngaged,
  33.         flowRate = state.turbineInfos[id].fluidFlowRateMax,
  34.     }
  35.    
  36.     local turbine = state.turbineInfos[id]
  37.     local turbineDiagnosis = state.turbineDiagnosis[id]
  38.  
  39.     local rpmIsFalling = state.rpmDelta[id] < 0.7
  40.     local rpmIsRising = state.rpmDelta[id] > 0.7
  41.     local rotorInertia = math.min(math.max(1.0, turbine.rotorMass / settings.referenceMass), 4.0)
  42.  
  43.     local rotorThresholdInduction = (settings.referenceRPMThreshold1 / rotorInertia) * (1800 / settings.rotorMaxSpeed)
  44.     local rotorThresholdFar = (settings.referenceRPMThreshold2 / rotorInertia) * (1800 / settings.rotorMaxSpeed)
  45.     local rotorThresholdClose = (settings.referenceRPMThreshold3 / rotorInertia) * (1800 / settings.rotorMaxSpeed)
  46.  
  47.     -- Rekonfiguration bei unvollständigem Multiblock
  48.     if not turbine.assembled then
  49.         action.shouldActivate = false
  50.         action.inductorStatus = false
  51.         action.flowRate = 0
  52.     end
  53.  
  54.     -- Diagnose: Zu viele Coils? Volle Flowrate, trotzdem keine RPM-Zielerreichung?
  55.     if turbine.rotorSpeed < settings.rotorMaxSpeed - rotorThresholdInduction and turbine.inductorEngaged then
  56.         turbineDiagnosis.lastFaultTime = state.unixTime
  57.         turbineDiagnosis.coilFault = true
  58.     elseif not turbine.assembled then
  59.         turbineDiagnosis.lastFaultTime = state.unixTime
  60.         turbineDiagnosis.multiBlockFault = true
  61.     elseif turbine.energyStored >= turbine.energyCapacity * settings.energyStopThreshold then
  62.         turbineDiagnosis.lastFaultTime = state.unixTime
  63.         turbineDiagnosis.energyLimitReached = true
  64.     elseif state.unixTime - turbineDiagnosis.lastFaultTime ~= 0 and state.unixTime - turbineDiagnosis.lastFaultTime > settings.errorResetTime then
  65.         turbineDiagnosis.lastFaultTime = 0
  66.         turbineDiagnosis.coilFault = false
  67.         turbineDiagnosis.multiBlockFault = false
  68.         turbineDiagnosis.energyLimitReached = false
  69.     end
  70.  
  71.     if turbine.energyStored >= turbine.energyCapacity * settings.energyStopThreshold and settings.energyForceStop then
  72.         action.shouldActivate = false
  73.         action.inductorStatus = false
  74.     elseif turbine.energyStored <= turbine.energyCapacity * settings.energyStartThreshold and settings.energyForceStart then
  75.         action.shouldActivate = true   
  76.     end
  77.  
  78.     if turbine.active and action.shouldActivate then
  79.         if action.inductorStatus and turbine.rotorSpeed < settings.rotorMaxSpeed - rotorThresholdInduction then
  80.             action.inductorStatus = false
  81.         elseif not action.inductorStatus and turbine.rotorSpeed > settings.rotorMaxSpeed - rotorThresholdInduction then
  82.             action.inductorStatus = true
  83.         end
  84.     end
  85.  
  86.     if turbine.active then
  87.         if turbine.rotorSpeed == 0 then
  88.             action.flowRate = state.bladeEfficiencyFlow[id]
  89.         elseif turbine.rotorSpeed <= settings.rotorMaxSpeed - rotorThresholdFar then
  90.             if rpmIsRising then
  91.                 if state.rpmDelta[id] > 48 / rotorInertia then
  92.                     action.flowRate = turbine.fluidFlowRate - 25
  93.                 elseif state.rpmDelta[id] < 16 / rotorInertia then
  94.                     if action.flowRate < state.bladeEfficiencyFlow[id] then
  95.                         action.flowRate = math.min(turbine.fluidFlowRate + (25 * rotorInertia), state.bladeEfficiencyFlow[id])
  96.                     elseif not settings.flowEfficiencyLimit then
  97.                         action.flowRate = turbine.fluidFlowRate + (25 * rotorInertia)
  98.                     end
  99.                 end
  100.             elseif rpmIsFalling then
  101.                 if action.flowRate < state.bladeEfficiencyFlow[id] then
  102.                     action.flowRate = math.min(turbine.fluidFlowRate + 100, state.bladeEfficiencyFlow[id])
  103.                 elseif not settings.flowEfficiencyLimit then
  104.                     action.flowRate = turbine.fluidFlowRate + 100
  105.                 end
  106.             elseif action.flowRate < state.bladeEfficiencyFlow[id] then
  107.                 action.flowRate = math.min(turbine.fluidFlowRate + 25, state.bladeEfficiencyFlow[id])
  108.             elseif not settings.flowEfficiencyLimit then
  109.                 action.flowRate = turbine.fluidFlowRate + 25
  110.             end
  111.        
  112.         --
  113.         elseif turbine.rotorSpeed <= settings.rotorMaxSpeed - rotorThresholdClose then
  114.             if rpmIsRising then
  115.                 if state.rpmDelta[id] > 12 / rotorInertia then
  116.                     action.flowRate = turbine.fluidFlowRate - 10
  117.                 elseif state.rpmDelta[id] < 4 / rotorInertia then
  118.                     if action.flowRate < state.bladeEfficiencyFlow[id] then
  119.                         action.flowRate = math.min(turbine.fluidFlowRate + 10, state.bladeEfficiencyFlow[id])
  120.                     elseif not settings.flowEfficiencyLimit then
  121.                         action.flowRate = turbine.fluidFlowRate + 10
  122.                     end
  123.                    
  124.                 end
  125.             elseif rpmIsFalling then
  126.                 if action.flowRate < state.bladeEfficiencyFlow[id] then
  127.                     action.flowRate = math.min(turbine.fluidFlowRate + 50, state.bladeEfficiencyFlow[id])
  128.                 elseif not settings.flowEfficiencyLimit then
  129.                     action.flowRate = turbine.fluidFlowRate + 50
  130.                 end
  131.             elseif action.flowRate < state.bladeEfficiencyFlow[id] then
  132.                 action.flowRate = math.min(turbine.fluidFlowRate + 25, state.bladeEfficiencyFlow[id])
  133.             elseif not settings.flowEfficiencyLimit then
  134.                 action.flowRate = turbine.fluidFlowRate + 25
  135.             end
  136.        
  137.         --
  138.         elseif turbine.rotorSpeed > settings.rotorMaxSpeed - rotorThresholdClose and turbine.rotorSpeed < settings.rotorMaxSpeed + rotorThresholdClose then
  139.             if rpmIsRising and state.rpmDelta[id] >= 2 / rotorInertia then
  140.                 action.flowRate = turbine.fluidFlowRate - 5
  141.             elseif rpmIsFalling and state.rpmDelta[id] >= 2 / rotorInertia then
  142.                 if action.flowRate < state.bladeEfficiencyFlow[id] then
  143.                      action.flowRate = math.min(turbine.fluidFlowRate + 5, state.bladeEfficiencyFlow[id])
  144.                 elseif not settings.flowEfficiencyLimit then
  145.                     action.flowRate = turbine.fluidFlowRate + 5
  146.                 end
  147.             end
  148.         elseif turbine.rotorSpeed >= settings.rotorMaxSpeed + rotorThresholdClose and turbine.rotorSpeed < 2000 then
  149.             if rpmIsRising then
  150.                 action.flowRate = turbine.fluidFlowRate - 50
  151.             else
  152.                 action.flowRate = turbine.fluidFlowRate - 10
  153.             end
  154.         elseif turbine.rotorSpeed >= 2000 then
  155.             action.flowRate = 0
  156.         end
  157.     end
  158.  
  159.     return action
  160. end
  161.  
  162. -- ==== TURBINENSTEUERUNG ====================================================
  163.  
  164. local function turbineControlLoop()
  165.     while true do
  166.         if rebootRequested then return end
  167.         state.unixTime = os.time(os.date("*t"))
  168.         if state.turbineEvaluateCount >= 1 then
  169.             state.turbineEvaluateCount = 0
  170.             gui.initTerminal()
  171.             for id, t in ipairs(state.turbines) do
  172.                 local info = turbine.getTurbineInfo(t)
  173.  
  174.                 -- Aktualisierung der Turbinen Infowerte / Update turbine info values
  175.                 state.turbineInfos[id] = turbine.getTurbineInfo(t)
  176.                 state.rpmDelta[id] = state.turbineInfos[id].rotorSpeed - state.lastRotorSpeed[id]
  177.                
  178.                 -- Funktionsaufruf zur Berechnung aktueller Turbinenaktionen / Evaluate turbine actions
  179.                 local action = evaluate(id)
  180.                
  181.                 -- Speicherung der Turbinengeschwindigkeit als Referenzwert / Save rotor speed
  182.                 state.lastRotorSpeed[id] = state.turbineInfos[id].rotorSpeed
  183.  
  184.                 -- Ausführung der Turbinen Steueraktionen / Execute turbine control
  185.                 turbine.setActive(t, action.shouldActivate)
  186.                 turbine.setInductorEngaged(t, action.inductorStatus)
  187.                 turbine.setFluidFlowRateMax(t, action.flowRate)
  188.             end
  189.         else
  190.             state.turbineEvaluateCount = state.turbineEvaluateCount + settings.updateInterval
  191.         end
  192.        
  193.         -- Aktuelle Zeit und RF-Produktion seit letztem Update / Current time and RF production
  194.         local rfSum = 0
  195.         local steamSum = 0
  196.  
  197.         for _, t in ipairs(state.turbines) do
  198.             rfSum = rfSum + (t.getEnergyProducedLastTick() or 0)
  199.             steamSum = steamSum + (t.getFluidFlowRate() or 0)
  200.         end
  201.  
  202.         -- RF/tick * 20 = RF/s bei normalem Takt / RF per second
  203.         local interval = settings.updateInterval or 1
  204.         local rfEstimated = math.floor(rfSum * 20)
  205.         local steamEstimated = math.floor(steamSum * 20)
  206.  
  207.         -- In Verlauf einfügen / Insert into history
  208.         table.insert(state.rfProduction.history, 1, {
  209.             time = state.unixTime,
  210.             rf = rfEstimated,
  211.             steam = steamEstimated
  212.         })
  213.  
  214.         -- Verlauf auf 1 Stunde begrenzen / Limit to 1 hour
  215.         local cutoff = state.unixTime - 3600
  216.         while #state.rfProduction.history > 0 and state.rfProduction.history[#state.rfProduction.history].time < cutoff do
  217.             table.remove(state.rfProduction.history)
  218.         end
  219.        
  220.         gui.renderPage()
  221.         os.sleep(settings.updateInterval)
  222.     end
  223. end
  224.  
  225.  
  226. -- Tastatur-Reset, Monitor-Touch und Resize-Handler bleiben unverändert --
  227.  
  228. local function keyListenerLoop()
  229.     while true do
  230.         local event, key = os.pullEvent("key")
  231.         if key == 211 then
  232.             rebootRequested = true
  233.             return
  234.         end
  235.     end
  236. end
  237.  
  238. local function handleTouchInput()
  239.     while true do
  240.         if rebootRequested then return end
  241.         local event, side, x, y = os.pullEvent("monitor_touch")
  242.         local width, height = gui.getMonitorSize()
  243.  
  244.         if settings.debugTouch == 1 or settings.debug == 1 then
  245.             print("x=" .. x .. " and y=" .. y)
  246.         end
  247.  
  248.         if x < 7 and y < 6 then
  249.             gui.setSpecialPage("options")
  250.         elseif x >= 2 and x <= 6 and y >= height - 3 then
  251.             gui.setPage(gui.currentPage - 1)
  252.         elseif x >= width - 5 and x <= width - 1 and y >= height - 3 then
  253.             gui.setPage(gui.currentPage + 1)
  254.         elseif x >= 8 and x <= math.floor(width / 2) - 1 and y >= height - 3 then
  255.             gui.setPage(1)
  256.         elseif x >= math.ceil(width / 2) + 2 and x <= width - 6 and y >= height - 3 then
  257.             gui.setSpecialPage("system")
  258.         end
  259.     end
  260. end
  261.  
  262. local function handleMonitorResize()
  263.     while true do
  264.         if rebootRequested then return end
  265.         local event, side = os.pullEvent("monitor_resize")
  266.         if side == peripheral.getName(peripheral.find("monitor")) then
  267.             gui.debugPrint("Monitorgröße geändert – GUI wird neu initialisiert.")
  268.             gui.initMonitor()
  269.             gui.initSystemWindows()
  270.             gui.initInfoWindows()
  271.             gui.renderPage()
  272.         end
  273.     end
  274. end
  275.  
  276. -- ==== Programm Start ================================================================
  277.  
  278. gui.initMonitor()
  279. gui.initTerminal()
  280. gui.initSystemWindows()
  281. gui.initInfoWindows()
  282. gui.initInfoWindowsMaxLength()
  283.  
  284. parallel.waitForAny(
  285.     turbineControlLoop,
  286.     keyListenerLoop,
  287.     handleTouchInput,
  288.     handleMonitorResize
  289. )
  290.  
  291. if rebootRequested then
  292.     print(language.data[langKey].orchestrator.restartInfo)
  293.     gui.rebootScreen(language.data[langKey].orchestrator.restartInfo)
  294.     os.sleep(1)
  295.     os.reboot()
  296. end
  297.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement