Add greenhouse drawer inventory diagnostic
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
-- ATM10 Greenhouse inventory diagnostic
|
||||
-- Read-only: detects a connected drawer/storage controller and writes its contents.
|
||||
|
||||
local OUTPUT_FILE = "greenhouse_inventory_debug.txt"
|
||||
local requestedName = ({ ... })[1]
|
||||
|
||||
local function containsMethod(methods, wanted)
|
||||
for _, method in ipairs(methods or {}) do
|
||||
if method == wanted then return true end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function allTypes(name)
|
||||
local types = { peripheral.getType(name) }
|
||||
local result = {}
|
||||
for _, value in ipairs(types) do
|
||||
if type(value) == "string" then result[#result + 1] = value end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
local function joinedTypes(name)
|
||||
return table.concat(allTypes(name), ", ")
|
||||
end
|
||||
|
||||
local function isInventory(name)
|
||||
if peripheral.hasType and peripheral.hasType(name, "inventory") then return true end
|
||||
local methods = peripheral.getMethods(name) or {}
|
||||
return containsMethod(methods, "list") and containsMethod(methods, "size")
|
||||
end
|
||||
|
||||
local function safeCall(name, method, ...)
|
||||
local result = table.pack(pcall(peripheral.call, name, method, ...))
|
||||
if not result[1] then return false, tostring(result[2]) end
|
||||
return true, table.unpack(result, 2, result.n)
|
||||
end
|
||||
|
||||
local function itemCount(contents)
|
||||
local total, occupied = 0, 0
|
||||
for _, item in pairs(contents or {}) do
|
||||
if type(item) == "table" and item.name then
|
||||
total = total + (tonumber(item.count) or 0)
|
||||
occupied = occupied + 1
|
||||
end
|
||||
end
|
||||
return total, occupied
|
||||
end
|
||||
|
||||
local function scoreCandidate(candidate)
|
||||
local text = (candidate.name .. " " .. candidate.types):lower()
|
||||
local score = candidate.occupied
|
||||
if text:find("functionalstorage", 1, true) then score = score + 10000 end
|
||||
if text:find("storage_controller", 1, true) then score = score + 5000 end
|
||||
if text:find("controller", 1, true) then score = score + 2000 end
|
||||
if text:find("drawer", 1, true) then score = score + 1000 end
|
||||
return score
|
||||
end
|
||||
|
||||
local candidates = {}
|
||||
for _, name in ipairs(peripheral.getNames()) do
|
||||
if isInventory(name) then
|
||||
local okList, contents = safeCall(name, "list")
|
||||
if okList and type(contents) == "table" then
|
||||
local total, occupied = itemCount(contents)
|
||||
local okSize, size = safeCall(name, "size")
|
||||
candidates[#candidates + 1] = {
|
||||
name = name,
|
||||
types = joinedTypes(name),
|
||||
contents = contents,
|
||||
total = total,
|
||||
occupied = occupied,
|
||||
size = okSize and tonumber(size) or 0,
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
table.sort(candidates, function(left, right)
|
||||
local leftScore, rightScore = scoreCandidate(left), scoreCandidate(right)
|
||||
if leftScore == rightScore then return left.name < right.name end
|
||||
return leftScore > rightScore
|
||||
end)
|
||||
|
||||
local selected
|
||||
if requestedName then
|
||||
for _, candidate in ipairs(candidates) do
|
||||
if candidate.name == requestedName then selected = candidate break end
|
||||
end
|
||||
if not selected then error("Inventar-Peripheral nicht gefunden: " .. requestedName, 0) end
|
||||
else
|
||||
selected = candidates[1]
|
||||
end
|
||||
|
||||
if not selected then
|
||||
error("Kein verbundenes Inventar gefunden. Wired Modem am Drawer Controller pruefen.", 0)
|
||||
end
|
||||
|
||||
local aggregate = {}
|
||||
for slot, item in pairs(selected.contents) do
|
||||
if type(item) == "table" and item.name then
|
||||
local entry = aggregate[item.name]
|
||||
if not entry then
|
||||
entry = { name = item.name, displayName = item.displayName, count = 0, slots = {} }
|
||||
aggregate[item.name] = entry
|
||||
end
|
||||
entry.count = entry.count + (tonumber(item.count) or 0)
|
||||
entry.slots[#entry.slots + 1] = tonumber(slot) or slot
|
||||
end
|
||||
end
|
||||
|
||||
local items = {}
|
||||
for _, item in pairs(aggregate) do items[#items + 1] = item end
|
||||
table.sort(items, function(left, right) return left.name < right.name end)
|
||||
|
||||
local function isEssence(item)
|
||||
return item.name:find("_essence", 1, true) ~= nil
|
||||
end
|
||||
|
||||
local function isSeed(item)
|
||||
return item.name:find("_seeds", 1, true) ~= nil or item.name:find("_seed", 1, true) ~= nil
|
||||
end
|
||||
|
||||
local file = fs.open(OUTPUT_FILE, "w")
|
||||
if not file then error("Kann " .. OUTPUT_FILE .. " nicht schreiben", 0) end
|
||||
|
||||
local function line(text)
|
||||
file.writeLine(tostring(text or ""))
|
||||
end
|
||||
|
||||
line("ATM10 GREENHOUSE INVENTORY DEBUG")
|
||||
line("Computer ID: " .. os.getComputerID())
|
||||
line("Selected peripheral: " .. selected.name)
|
||||
line("Types: " .. selected.types)
|
||||
line("Slots reported: " .. tostring(selected.size))
|
||||
line("Occupied entries: " .. selected.occupied)
|
||||
line("Total items: " .. selected.total)
|
||||
line("")
|
||||
line("INVENTORY CANDIDATES")
|
||||
for index, candidate in ipairs(candidates) do
|
||||
line(string.format("%d. %s | %s | slots=%d occupied=%d items=%d%s",
|
||||
index, candidate.name, candidate.types, candidate.size, candidate.occupied,
|
||||
candidate.total, candidate == selected and " | SELECTED" or ""))
|
||||
end
|
||||
|
||||
line("")
|
||||
line("ESSENCES")
|
||||
local essenceCount = 0
|
||||
for _, item in ipairs(items) do
|
||||
if isEssence(item) then
|
||||
essenceCount = essenceCount + 1
|
||||
line(string.format("%s | count=%d | slots=%s",
|
||||
item.name, item.count, table.concat(item.slots, ",")))
|
||||
end
|
||||
end
|
||||
line("Essence types: " .. essenceCount)
|
||||
|
||||
line("")
|
||||
line("SEEDS")
|
||||
local seedCount = 0
|
||||
for _, item in ipairs(items) do
|
||||
if isSeed(item) then
|
||||
seedCount = seedCount + 1
|
||||
line(string.format("%s | count=%d | slots=%s",
|
||||
item.name, item.count, table.concat(item.slots, ",")))
|
||||
end
|
||||
end
|
||||
line("Seed types: " .. seedCount)
|
||||
|
||||
line("")
|
||||
line("ALL ITEMS")
|
||||
for _, item in ipairs(items) do
|
||||
line(string.format("%s | count=%d | slots=%s",
|
||||
item.name, item.count, table.concat(item.slots, ",")))
|
||||
end
|
||||
line("Unique item types: " .. #items)
|
||||
file.close()
|
||||
|
||||
print("Greenhouse-Dump erstellt:")
|
||||
print(OUTPUT_FILE)
|
||||
print("Controller: " .. selected.name)
|
||||
print("Items: " .. #items .. " | Essenzen: " .. essenceCount .. " | Seeds: " .. seedCount)
|
||||
print("Falls der falsche Controller gewaehlt wurde:")
|
||||
print("greenhouse_inventory_debug <peripheral_name>")
|
||||
Reference in New Issue
Block a user