CCCPaste

regulate_turbine_energy

-- energy_redstone_control.lua
-- Enciende redstone por  cuando la energía >= highThreshold (porcentaje)
-- y apaga cuando la energía <= lowThreshold.
-- Uso:
--   shell.run("energy_redstone_control", , , , , )
-- Ejemplo:
--   shell.run("energy_redstone_control", "back", "left", "0.9", "0.5", "1")

local args = {...}
local energySide  = args[1] or "back"   -- lado donde está el bloque que almacena energía
local redstoneSide = args[2] or "left" -- lado por donde emitir la señal de redstone
local highPct     = tonumber(args[3]) or 0.90  -- umbral ON (90% por defecto)
local lowPct      = tonumber(args[4]) or 0.50  -- umbral OFF (50% por defecto)
local pollInterval = tonumber(args[5]) or 1    -- segundos entre comprobaciones

-- función segura para llamar a métodos del periférico
local function tryCall(side, method, ...)
  local ok, res = pcall(peripheral.call, side, method, ...)
  if not ok then return nil, res end
  return res
end

-- intenta obtener energía y capacidad usando varios nombres comunes
local function getEnergy(side)
  local tries = {
    {"getEnergyStored", "getMaxEnergyStored"},
    {"getEnergyStored", "getEnergyCapacity"},
    {"getEnergy", "getMaxEnergy"},
    {"getEnergy", "getEnergyCapacity"},
    {"getEnergyStats"} -- puede devolver tabla {energy=.., capacity=..} o {energy, capacity}
  }

  for _, pair in ipairs(tries) do
    local curMeth, capMeth = pair[1], pair[2]
    if capMeth then
      local ok1, cur = pcall(peripheral.call, side, curMeth)
      local ok2, cap = pcall(peripheral.call, side, capMeth)
      if ok1 and ok2 and type(cur) == "number" and type(cap) == "number" then
        return cur, cap
      end
      -- algunos mods devuelven tabla en una llamada
      if ok1 and type(cur) == "table" and (cur.energy or cur.energyStored or cur.capacity or cur.maxEnergy) then
        local c = cur.energy or cur.energyStored or cur.energy or cur.amount
        local capv = cur.capacity or cur.maxEnergy or cur.max or cur.energyCapacity
        if type(c) == "number" and type(capv) == "number" then
          return c, capv
        end
      end
    else
      -- caso de getEnergyStats()
      local ok, res = pcall(peripheral.call, side, curMeth)
      if ok and type(res) == "table" then
        -- intentar distintos formatos
        if type(res.energy) == "number" and type(res.capacity) == "number" then
          return res.energy, res.capacity
        elseif type(res[1]) == "number" and type(res[2]) == "number" then
          return res[1], res[2]
        end
      end
    end
  end

  return nil, nil
end

-- set redstone safely (no pcall necesario; setOutput no falla si lado inválido, pero por seguridad usamos pcall)
local function setRedstone(side, state)
  pcall(redstone.setOutput, side, state)
end

-- Helper visual
local function fmt(n)
  if not n then return "nil" end
  return tostring(math.floor(n + 0.5))
end

-- Comprobaciones iniciales
print(("Control de energía -> energySide=%s, redstoneSide=%s, ON>=%.0f%%, OFF<=%.0f%%, poll=%.1fs")
      :format(energySide, redstoneSide, highPct*100, lowPct*100, pollInterval))

local outputOn = false

while true do
  if not peripheral.isPresent(energySide) then
    print("No hay periférico detectado en: " .. tostring(energySide))
    -- no bloque; dejar salida en off y esperar
    if outputOn then
      setRedstone(redstoneSide, false)
      outputOn = false
      print("Salida redstone DESACTIVADA (no hay periférico).")
    end
    sleep(pollInterval)
  else
    local energy, capacity = getEnergy(energySide)