CCCPaste

eb1afd36fe94e

-- reactor_sender.lua
-- Läuft an dem Computer, der direkt am Reaktor / Energiespeicher hängt.
-- Starten: speichern unter reactor_sender.lua und ausführen.
-- Öffne das Modem an der jeweiligen Seite, z.B. rednet.open("right")

local modemSide = "right" -- falls dein Modem woanders ist, anpassen
local serviceName = "POWAH_REACTOR" -- Broadcast/Service-Name

local function safeOpenModem()
  if peripheral.getType(modemSide) == "modem" or peripheral.getType(modemSide) == "wireless_modem" then
    rednet.open(modemSide)
    return true
  end
  -- falls es nicht als modem erkannt wird, versuchen trotzdem
  local ok, _ = pcall(rednet.open, modemSide)
  return ok
end

local function findReactorPeripheral()
  -- Versucht, ein angeschlossenes Peripherie-Gerät zu finden, das Energie-Methoden hat.
  -- Prüft alle Peripherie-Namen am Computer.
  for _, name in ipairs(peripheral.getNames()) do
    local methods = peripheral.getMethods(name)
    local mset = {}
    for _, m in ipairs(methods) do mset[m] = true end
    -- gängige Methoden-Names prüfen
    if mset["getEnergyStored"] or mset["getMaxEnergyStored"]
      or mset["getEnergy"] or mset["getMaxEnergy"]
      or mset["getStored"] or mset["getCapacity"]
      or mset["getEnergyStoredForge"] then
      return name
    end
  end
  return nil
end

-- Flexible Abruf-Funktionen: versucht mehrere mögliche Methoden
local function callIfExists(peri, ...)
  for i = 1, select("#", ...) do
    local m = select(i, ...)
    if peripheral.call(peri, m) ~= nil then
      -- return value (could be false/nil though); to be safe wrap pcall
      local ok, res = pcall(peripheral.call, peri, m)
      if ok then return res end
    end
  end
  return nil
end

local function pollReactor(peri)
  -- Gibt eine Tabelle zurück: {stored=number, capacity=number, producedPerTick=number}
  if not peri then return nil end
  local result = {}

  -- gespeicherte Energie
  local stored = nil
  stored = callIfExists(peri,
    "getEnergyStored",
    "getEnergy",
    "getStored",
    "getCurrentEnergy"
  )
  -- Kapazität
  local capacity = nil
  capacity = callIfExists(peri,
    "getMaxEnergyStored",
    "getMaxEnergy",
    "getCapacity",
    "getMaxEnergy"
  )

  -- Produktion (RF/t oder FE/t)
  local produced = nil
  produced = callIfExists(peri,
    "getEnergyGenerated", -- hypothetisch
    "getEnergyPerTick",
    "getRfPerTick",
    "getGenerationRate",
    "getPower"
  )

  -- Manche Peripheries liefern ein Table mit feldern
  if type(stored) == "table" then
    if stored.stored then stored = stored.stored end
    if stored.energy then stored = stored.energy end
  end

  result.stored = tonumber(stored) or 0
  result.capacity = tonumber(capacity) or 0
  result.produced = tonumber(produced) or 0
  return result
end

-- Hauptloop: wartet auf Anfragen per rednet und antwortet mit Status
local function main()
  if not safeOpenModem() then
    print("Fehler: Konnte Modem nicht öffnen an Seite:", modemSide)
    return
  end
  print("Reactor sender gestartet. Suche nach Peripherie...")
  local peri = findReactorPeripheral()
  if not peri then
    print("Warnung: Keine passende Peripherie automatisch gefunden.")
    print("Peripherie-Liste:")
    for _,n in ipairs(peripheral.getNames()) do print("-", n) end
  else
    print("Gefundene Peripherie:", peri)
  end

  while true do
    -- wartet auf Anfrage (serviceName)
    local senderId, msg = nil, nil
    senderId, msg = rednet.receive(5) -- 5s timeout, damit wir sporadisch die Peripherien neu erkennen
    if msg == serviceName or (type(msg) == "table" and msg.request == "status") then
      -- erneutes Erkennen der Peripherie (falls z.B. Block neu gesetzt)
      peri = findReactorPeripheral() or peri
      local status = pollReactor(peri)
      rednet.send(senderId, status, serviceName)
    else
      -- timeout oder anderes: peridi neu suchen
      peri = findReactorPeripheral() or peri
    end
  end
end

main()