Add greenhouse drawer inventory diagnostic
This commit is contained in:
@@ -61,6 +61,26 @@ stehen alle verbundenen Peripherien, Methoden, Frogport-Adressen sowie abrufbare
|
|||||||
Paket-, Inventar- und Stock-Ticker-Daten. Das Programm versendet keine Pakete und
|
Paket-, Inventar- und Stock-Ticker-Daten. Das Programm versendet keine Pakete und
|
||||||
veraendert keine Redstone-Ausgaenge.
|
veraendert keine Redstone-Ausgaenge.
|
||||||
|
|
||||||
|
## Greenhouse-Inventar erfassen
|
||||||
|
|
||||||
|
`greenhouse_inventory_debug.lua` erkennt einen per Wired Modem verbundenen
|
||||||
|
Drawer-/Storage-Controller und schreibt dessen Inhalt rein lesend nach
|
||||||
|
`greenhouse_inventory_debug.txt`. Essenzen, Seeds und die vollstaendige
|
||||||
|
Itemliste werden mit Registry-ID, Menge und Slot ausgegeben.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
delete greenhouse_inventory_debug.lua
|
||||||
|
wget https://git.peli-server.de/Dystroyer8/ATM10_CC_Codes/raw/branch/main/greenhouse_inventory_debug.lua greenhouse_inventory_debug.lua
|
||||||
|
greenhouse_inventory_debug
|
||||||
|
```
|
||||||
|
|
||||||
|
Falls mehrere Controller verbunden sind, kann der im Dump angezeigte
|
||||||
|
Peripheral-Name gezielt uebergeben werden:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
greenhouse_inventory_debug <peripheral_name>
|
||||||
|
```
|
||||||
|
|
||||||
### Erster Logistik-Funktionstest
|
### Erster Logistik-Funktionstest
|
||||||
|
|
||||||
Nach erfolgreicher Erkennung kann der Monitor-Testcontroller installiert werden:
|
Nach erfolgreicher Erkennung kann der Monitor-Testcontroller installiert werden:
|
||||||
|
|||||||
@@ -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