Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- dashboard.lua
- -- Zentraler "Server", holt Daten von allen Reactor-Clients per rednet,
- -- zeigt sie grafisch an und steuert per "KI" die Rod-Level, um
- -- möglichst hohen Output bei minimalem Verbrauch zu erzielen.
- ---------------------------------------------
- -- 1) KONFIG
- ---------------------------------------------
- local monSide = "top" -- dein Monitor
- local modemSide = "bottom" -- Wo dein Modem (Wireless/Wired)
- local batterySide = nil -- Falls du zusätzlich eine Battery am Dashboard hast? (optional)
- local refreshInterval = 5 -- alle X Sekunden aktualisieren
- -- Reaktorliste: "id" = Computer-ID, "name" = Anzeige, "auto" = KI an/aus
- local reactors = {
- {
- id = 9, -- ID deines Reaktor-Computers
- name = "Reactor 1",
- auto = true,
- rodLevel = 0,
- lastRF = 0,
- fuelPct = 0,
- temp = 0
- },
- {
- id = 6,
- name = "Reactor 2",
- auto = false,
- rodLevel = 0,
- lastRF = 0,
- fuelPct = 0,
- temp = 0
- },
- -- bel. mehr ...
- }
- ---------------------------------------------
- -- 2) PERIPHERIE
- ---------------------------------------------
- local mon = peripheral.wrap(monSide)
- if not mon then error("Monitor an '"..monSide.."' nicht gefunden!") end
- mon.setTextScale(0.5)
- local w,h = mon.getSize()
- local modem = peripheral.wrap(modemSide)
- if not modem then error("Modem an '"..modemSide.."' nicht gefunden!") end
- rednet.open(modemSide)
- -- Falls du eine separate Battery an diesem Computer hast:
- local battery = nil
- if batterySide then
- battery = peripheral.wrap(batterySide)
- end
- ---------------------------------------------
- -- 3) GLOBALE VARIABLEN
- ---------------------------------------------
- local currentScreen = "main"
- local currentDetail = 1 -- Index in 'reactors'
- local batteryPercent = 0
- -- Um Fuel/Effizienz zu optimieren, speichern wir (pro Reaktor) "bestRodLevel" etc.
- -- Hier kann man später "KI" historical data anlegen.
- ---------------------------------------------
- -- 4) HILFSMETHODEN
- ---------------------------------------------
- local function clear()
- mon.setBackgroundColor(colors.black)
- mon.clear()
- mon.setCursorPos(1,1)
- end
- local function centerText(y,text,col)
- col = col or colors.white
- mon.setTextColor(col)
- local x = math.floor((w-#text)/2)
- mon.setCursorPos(x+1,y)
- mon.write(text)
- end
- -- Reaktordaten abholen
- local function getReactorData(clientID)
- rednet.send(clientID, {cmd="GET_DATA"}, "REACTOR_PROTO")
- local sender, resp = rednet.receive("REACTOR_PROTO", 3)
- if sender == clientID and type(resp)=="table" then
- return resp
- end
- return nil
- end
- local function setReactorActive(clientID, active)
- rednet.send(clientID, {cmd="SET_ACTIVE", active=active}, "REACTOR_PROTO")
- -- Wir ignorieren die Antwort hier, du könntest sie abwarten.
- end
- local function setReactorRodLevel(clientID, level)
- rednet.send(clientID, {cmd="SET_ROD_LEVEL", level=level}, "REACTOR_PROTO")
- end
- -- Optionaler Batteriestand, falls du eine am Dashboard hast
- local function getBatteryPercent()
- if not battery then return 100 end
- local stored = battery.getEnergyStored()
- local cap = battery.getMaxEnergyStored()
- if cap<=0 then return 100 end
- return math.floor((stored/cap)*100)
- end
- ---------------------------------------------
- -- 5) KI-LOGIK (erweitert)
- ---------------------------------------------
- -- Idee: Wir wollen "maximale" Leistung - ABER minimalen Fuel-Verbrauch.
- -- - Wenn Reaktor "auto" = true, wir machen Feintuning:
- -- 1) Wenn Battery < 50% => Reaktor an, rods senken (0% => max Output).
- -- 2) Wenn Battery > 95% => Reaktor aus (Rod 100% => minimal Verbrauch).
- -- 3) Wenn Reaktor an, wir gucken "fuelConsumed" vs "energyProduced" => Effizienz
- -- 4) Kleines "Delta-Testing": wir probieren rod +5, checken ob Battery stable.
- -- Wenn stable => Beibehalten, so sparst du Fuel.
- -- Wenn Battery sinkt => rod -5.
- -- Wir brauchen also "alt-Batterie" + "alt-Fuel" => statische Ansätze
- local oldBattery = 100
- local function autoLogic()
- batteryPercent = getBatteryPercent()
- local deltaB = batteryPercent - oldBattery
- oldBattery = batteryPercent
- for _, r in ipairs(reactors) do
- if r.auto then
- -- Not-Aus? Battery < 50 => Reaktor an, rods => 0 (mehr Power)
- if batteryPercent < 50 then
- setReactorActive(r.id, true)
- r.isOnline = true
- local newRod = 0
- setReactorRodLevel(r.id, newRod)
- r.rodLevel = newRod
- end
- -- Battery > 95 => Reaktor aus
- if batteryPercent > 95 then
- setReactorActive(r.id, false)
- r.isOnline = false
- end
- -- Feinsteuerung, wenn Reaktor online
- if r.isOnline then
- -- Haben wir "energyProduced" und "fuelConsumed"? -> in r eingetragen
- if r.energyProduced and r.fuelConsumed then
- -- "Effizienz" = energyProduced / fuelConsumed (units ???)
- -- Pseudocode:
- -- Falls battery stable (deltaB ~ 0) => rods + 1 => test
- -- Falls battery sinkt => rods - 2 ...
- if math.abs(deltaB) < 1 then
- -- annähern
- local newRod = math.min(100, r.rodLevel + 1)
- setReactorRodLevel(r.id, newRod)
- r.rodLevel = newRod
- elseif deltaB < 0 then
- -- wir verlieren Energie => rods -1
- local newRod = math.max(0, r.rodLevel - 1)
- setReactorRodLevel(r.id, newRod)
- r.rodLevel = newRod
- elseif deltaB > 3 then
- -- wir laden stark => rods +1
- local newRod = math.min(100, r.rodLevel + 1)
- setReactorRodLevel(r.id, newRod)
- r.rodLevel = newRod
- end
- end
- end
- end
- end
- end
- ---------------------------------------------
- -- 6) GRAFIK: HAUPTMENÜ
- ---------------------------------------------
- local function drawMain()
- clear()
- centerText(1, "Multi Reactor Dashboard", colors.cyan)
- mon.setTextColor(colors.white)
- mon.setCursorPos(2,2)
- mon.write("Battery: "..batteryPercent.."%")
- local colCount=2
- local boxW, boxH=24,5
- local startY=3
- local i=1
- for row=0,10 do
- for col=0,colCount-1 do
- local rr = reactors[i]
- if not rr then return end
- local x=col*(boxW+1)+2
- local y=row*(boxH+1)+startY
- -- Box
- mon.setTextColor(colors.white)
- mon.setCursorPos(x,y)
- mon.write("+"..string.rep("-",boxW-2).."+")
- for rrow=1, boxH-2 do
- mon.setCursorPos(x, y+rrow)
- mon.write("|"..string.rep(" ", boxW-2).."|")
- end
- mon.setCursorPos(x, y+boxH-1)
- mon.write("+"..string.rep("-",boxW-2).."+")
- -- Name
- mon.setCursorPos(x+2,y+1)
- mon.write(rr.name)
- -- Online
- mon.setCursorPos(x+2,y+2)
- if rr.isOnline then
- mon.setTextColor(colors.lime)
- mon.write("Online")
- else
- mon.setTextColor(colors.red)
- mon.write("Offline")
- end
- -- Auto
- mon.setCursorPos(x+2,y+3)
- mon.setTextColor(rr.auto and colors.lime or colors.gray)
- mon.write("[Auto:"..tostring(rr.auto).."]")
- i=i+1
- if i>#reactors then return end
- end
- end
- end
- ---------------------------------------------
- -- 7) GRAFIK: DETAIL
- ---------------------------------------------
- local function drawDetail(idx)
- local r = reactors[idx]
- if not r then return end
- clear()
- centerText(1, r.name.." Detail", colors.cyan)
- mon.setCursorPos(2,3)
- mon.setTextColor(r.isOnline and colors.lime or colors.red)
- mon.write("Status: "..(r.isOnline and "Online" or "Offline"))
- -- Fuel %
- local fPct = 0
- if (r.fuelAmountMax or 0)>0 then
- fPct = math.floor(r.fuelAmount / r.fuelAmountMax *100)
- end
- mon.setCursorPos(2,4)
- mon.setTextColor(colors.white)
- mon.write(("Fuel: %d%%"):format(fPct))
- mon.setCursorPos(2,5)
- mon.write(("Rod: %d%%"):format(r.rodLevel or 0))
- mon.setCursorPos(2,6)
- mon.write(("RF/t: %.1f"):format(r.energyProduced or 0))
- mon.setCursorPos(2,7)
- mon.write(("FuelC/t: %.4f"):format(r.fuelConsumed or 0))
- mon.setCursorPos(2,8)
- mon.write(("Temp: %.1fC (Casing: %.1fC)"):format(r.fuelTemp or 0, r.casingTemp or 0))
- mon.setCursorPos(2,9)
- mon.write(("Reactivity: %.1f%%"):format(r.reactivity or 0))
- mon.setCursorPos(2,11)
- mon.setTextColor(colors.gray)
- mon.write("[ Toggle ON/OFF ]")
- mon.setCursorPos(2,12)
- mon.write("[Auto Mode: "..(r.auto and "On" or "Off").."]")
- mon.setCursorPos(2,h)
- mon.setTextColor(colors.yellow)
- mon.write("[ Zurueck ]")
- end
- ---------------------------------------------
- -- 8) TOUCH-HANDLER
- ---------------------------------------------
- local function clickMain(x,y)
- local colCount=2
- local boxW,boxH=24,5
- local startY=3
- local i=1
- for row=0,10 do
- for col=0,colCount-1 do
- local rx = col*(boxW+1)+2
- local ry = row*(boxH+1)+startY
- if x>=rx and x<=rx+boxW-1 and y>=ry and y<=ry+boxH-1 then
- if reactors[i] then
- currentDetail=i
- currentScreen="detail"
- drawDetail(i)
- end
- return
- end
- i=i+1
- if i>#reactors then return end
- end
- end
- end
- local function clickDetail(x,y)
- local r = reactors[currentDetail]
- if not r then return end
- if y==h then
- -- [Zurueck]
- currentScreen="main"
- drawMain()
- return
- end
- if x>=2 and x<=17 and y==11 then
- -- Toggle On/Off
- local newState = not r.isOnline
- setReactorActive(r.id, newState)
- r.isOnline = newState
- drawDetail(currentDetail)
- return
- end
- if x>=2 and x<=17 and y==12 then
- r.auto=not r.auto
- drawDetail(currentDetail)
- return
- end
- end
- ---------------------------------------------
- -- 9) UPDATE-LOOP
- ---------------------------------------------
- local function updateAll()
- -- Batteriestand
- batteryPercent = getBatteryPercent()
- -- Hol Daten vom Client
- for _,rx in ipairs(reactors) do
- local data = getReactorData(rx.id)
- if data then
- rx.isOnline = data.active
- rx.energyProduced = data.energyProduced or 0
- rx.fuelAmount = data.fuelAmount or 0
- rx.fuelAmountMax = data.fuelAmountMax or 1
- rx.fuelConsumed = data.fuelConsumed or 0
- rx.reactivity = data.reactivity or 0
- rx.fuelTemp = data.fuelTemp or 0
- rx.casingTemp = data.casingTemp or 0
- rx.rodLevel = data.rodLevel or 0
- rx.energyStored = data.energyStored or 0
- rx.energyCapacity = data.energyCapacity or 1
- else
- rx.isOnline = false
- end
- end
- -- KI
- autoLogic()
- end
- local function mainLoop()
- updateAll()
- drawMain()
- local timerID = os.startTimer(refreshInterval)
- while true do
- local e, p1, p2, p3 = os.pullEvent()
- if e=="timer" and p1==timerID then
- updateAll()
- if currentScreen=="main" then
- drawMain()
- else
- drawDetail(currentDetail)
- end
- timerID = os.startTimer(refreshInterval)
- elseif e=="monitor_touch" then
- local x,y = p2,p3
- if currentScreen=="main" then
- clickMain(x,y)
- else
- clickDetail(x,y)
- end
- end
- end
- end
- mainLoop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement