Last active
January 23, 2020 06:02
-
-
Save InternetUnexplorer/0819ed1cf71886f8b40ae2571bcef0cd to your computer and use it in GitHub Desktop.
OpenComputers script to drain items from an ME network based on a set of item limits
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local component = require "component" | |
local term = require "term" | |
-- Get ME and database components | |
-- The interface is needed to access the common network API, see | |
-- https://github.com/MightyPirates/OpenComputers/issues/3055 | |
local meInterface = component.me_interface | |
local meExportbus = component.me_exportbus | |
local database = component.database | |
local function loadConfiguration() | |
local exportSide, itemLimits = dofile "config.lua" | |
-- Assert that exportSide is an integer between 0 and 5 (inclusive) | |
assert(math.floor(exportSide) == exportSide) | |
assert(exportSide >= 0 and exportSide <= 5) | |
-- Assert that itemLimits is a table, then check k/v pairs | |
assert(type(itemLimits) == "table") | |
for label, limit in pairs(itemLimits) do | |
-- Assert that all keys are strings | |
assert(type(label) == "string") | |
-- Assert that all values are nonnegative integers | |
assert(math.floor(limit) == limit) | |
assert(limit >= 0) | |
end | |
-- Once sanity checks have been passed, return values | |
return exportSide, itemLimits | |
end | |
local function printItemLimits(itemLimits) | |
-- Print a horizontal separator | |
local function printSep() | |
print(string.rep("-", 32)) | |
end | |
-- Print a right-padded row with two columns | |
local function printRow(left, right) | |
print(string.format("%-24s %-7s", left, right)) | |
end | |
-- Print header and separator | |
printRow("Item Name", "Maximum") | |
printSep() | |
-- Print a row for each item limit | |
for label, limit in pairs(itemLimits) do | |
printRow(label, limit) | |
end | |
-- Print ending separator | |
printSep() | |
end | |
-- Clear line and print a status message without wrapping | |
local function printStatus(status) | |
term.clearLine() | |
term.write(status, false) | |
end | |
-- Get item info from the interface, filtered by item label | |
local function getItemInfo(label) | |
local filter = { ["label"] = label } | |
return meInterface.getItemsInNetwork(filter)[1] | |
end | |
-- Get item count from the interface, filtered by item label | |
local function getItemCount(label) | |
local info = getItemInfo(label) | |
return info and info.size or 0 | |
end | |
-- Set the export bus item configuration | |
-- Passing nil as the label clears the export configuration | |
-- This function modifies the first database slot | |
local function setDrainItem(label, exportSide) | |
-- Clear the first item in the database, as store() doesn't seem to want to | |
-- override it for some reason | |
database.clear(1) | |
-- If an item label was provided, update the database slot | |
-- Otherwise, it will be left blank, which will clear the configuration | |
if label then | |
local info = getItemInfo(label) | |
meInterface.store(info, database.address) | |
end | |
-- Set the export configuration to match the first database slot | |
meExportbus.setExportConfiguration(exportSide, 1, database.address, 1) | |
end | |
-- Drain an item until the count is below the limit | |
-- Will return early if item count remains the same after an export | |
local function drainItem(label, limit, exportSide) | |
-- Configure export bus to export the item | |
printStatus("Setting export configuration") | |
setDrainItem(label, exportSide) | |
-- Get the current count before draining | |
local count = getItemCount(label) | |
-- Drain until item no longer over limit | |
while count > limit do | |
-- Show drain status | |
printStatus(string.format("Draining %s (%d > %d)", | |
label, count, limit)) | |
-- Trigger an export on the bus | |
meExportbus.exportIntoSlot(exportSide, 1) | |
-- Get the updated item count | |
local newCount = getItemCount(label) | |
-- Sanity check, if item count has changed then update count and | |
-- continue, otherwise break as something may have gone wrong | |
if newCount ~= count then | |
count = newCount | |
else | |
break | |
end | |
-- Yield as loop can take a while to complete | |
os.sleep(0) | |
end | |
-- Clear the export bus configuration when done | |
printStatus("Clearing export configuration") | |
setDrainItem(nil, exportSide) | |
end | |
-- Load configuration from file and print list of limits | |
local exportSide, itemLimits = loadConfiguration() | |
printItemLimits(itemLimits) | |
-- Clear export configuration before starting | |
printStatus("Clearing export configuration") | |
setDrainItem(nil, exportSide) | |
while true do | |
-- Check each item in succession and drain if over limit | |
for label, limit in pairs(itemLimits) do | |
printStatus(string.format("Idle (checking %s)", label)) | |
if getItemCount(label) > limit then | |
drainItem(label, limit, exportSide) | |
end | |
end | |
-- Wait a bit before checking again | |
printStatus("Idle") | |
os.sleep(10) | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- autodrain.lua configuration file | |
local sides = require "sides" | |
local exportSide = sides.right | |
local itemLimits = { | |
["Solidified Experience"] = 250000, | |
} | |
return exportSide, itemLimits |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment