CCCPaste

EnanReactorAutoConfig_ForEEPROM

local function proxy(name)
    return component.proxy(component.list("gpu")())
end

local gpu = proxy("gpu")
local w, h = gpu.getResolution()

local TARGET_INSTABILITY = 2
local STABILIZER_ENERGY  = 10000
local OUTPUT_RATE        = 60000

local SLEEP_TIME = 3.0
local ERROR_SLEEP_TIME = 8.0

local CORE_TYPE = "warpdriveEnanReactorCore"

local function pairsByKeys(t, f)
    local a = {}
    for n in pairs(t) do table.insert(a, n) end
    table.sort(a, f)
    local i = 0
    local iter = function ()
        i = i + 1
        if a[i] == nil then return nil
            else return a[i], t[a[i]]
        end
    end
    return iter
end

local function configureRelease(core)
    local energy, capacity = core.energy()
    local pct = energy / capacity
    if pct > 0.9 then
        core.releaseRate(OUTPUT_RATE)
    else
        core.release(false)
    end
end

local function initialConfig(core)
    core.stabilizerEnergy(STABILIZER_ENERGY)
    core.instabilityTarget(100 - TARGET_INSTABILITY)
    configureRelease(core)
    core.enable(true)
end

local cursorY = 1
local function print(...)
    local resStr = ""
    for _, v in ipairs({...}) do
        resStr = resStr .. tostring(v) .. "    "
    end
    if gpu.set(1, cursorY, resStr) then
        cursorY = cursorY + 1
    end
end

local function clear()
    gpu.fill(1, 1, w, h, ' ')
    cursorY = 1
end

local function drawState(cores)
    clear()
    print("Состояние ядер:")

    for addr, core in pairsByKeys(cores) do
        pcall(function()
            local instabil = {core.instability()}
            instabil = 100.0 - (instabil[1] + instabil[2] + instabil[3] + instabil[4]) / 4.0
            local rmode = core.releaseRate()
            if rmode == "at_rate" then rmode = "rate" else rmode = "hold" end
            print(addr, "Energy: " .. tostring(core.energy()), "Stability: " .. tostring(instabil), "Release mode: " .. rmode)
        end)
    end
end

local function main()
    local cores = {}
    for addr, _ in pairs(component.list(CORE_TYPE)) do
        cores[addr] = component.proxy(addr)
        initialConfig(cores[addr])
    end

    drawState(cores)

    local lastDrawedTime = computer.uptime()
    while true do
        -- Get event
        e = {computer.pullSignal(SLEEP_TIME)}

        if e[1] == "component_added" then
            local addr, ctype = e[2], e[3]
            if ctype == CORE_TYPE then
                cores[addr] = component.proxy(addr)
                initialConfig(cores[addr])
            end
        elseif e[1] == "component_removed" then
            local addr, ctype = e[2], e[3]
            if ctype == CORE_TYPE then
                cores[addr] = nil
            end
        end

        local currentTime = computer.uptime()
        if currentTime > (lastDrawedTime + SLEEP_TIME) then
            for _, core in pairs(cores) do
                pcall(configureRelease, core)
            end
            drawState(cores)
            lastDrawedTime = currentTime
        end
    end
end

local s, e = xpcall(main(), function(err) return err .. "\n" .. debug.traceback(); end)

if not s then
    clear()
    gpu.setForeground(0xFF0000)
    print(e)
    gpu.setForeground(0xFFFFFF)

    local startTime = computer.uptime()
    repeat
        computer.pullSignal(ERROR_SLEEP_TIME)
    until computer.uptime() > (startTime + ERROR_SLEEP_TIME)
end