-- 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)