Lordeah18

stocker.lua

Nov 23rd, 2024
250
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.80 KB | None | 0 0
  1. if not fs.exists("json") then
  2.     shell.run("pastebin get 4nRg9CHU json")
  3. end
  4.  
  5. os.loadAPI("json")
  6.  
  7. local configFolder = "stock_config"
  8. local monitorPeripheral = "top"
  9.  
  10. -- Reads configuration files
  11. local function readConfigFiles(folder)
  12.     local configs = {}
  13.     if fs.exists(folder) and fs.isDir(folder) then
  14.         for _, file in ipairs(fs.list(folder)) do
  15.             local filePath = fs.combine(folder, file)
  16.             if fs.isDir(filePath) == false then
  17.                 local fileHandle = fs.open(filePath, "r")
  18.                 if fileHandle then
  19.                     local content = fileHandle.readAll()
  20.                     fileHandle.close()
  21.                     local parsed = json.decode(content)
  22.                     if parsed then
  23.                         table.insert(configs, parsed)
  24.                     end
  25.                 end
  26.             end
  27.         end
  28.     end
  29.     return configs
  30. end
  31.  
  32. -- Checks the stock level of a product
  33. local function checkStockLevel(itemName, destinationPeripheral)
  34.     local stockPeripheral = peripheral.wrap(destinationPeripheral)
  35.     if not stockPeripheral then
  36.         print("Error: Could not find destination peripheral.")
  37.         return 0
  38.     end
  39.  
  40.     local currentStock = 0
  41.     for _, item in pairs(stockPeripheral.list()) do
  42.         if item.name == itemName then
  43.             currentStock = currentStock + item.count
  44.         end
  45.     end
  46.     return currentStock
  47. end
  48.  
  49.  
  50. -- Checks for missing items in the source inventory
  51. local function checkMissingItems(itemConfig)
  52.     local missingItems = {}
  53.     local source = peripheral.wrap(itemConfig.source or defaultSourcePeripheral)
  54.     if not source then
  55.         print("Error: Could not find source peripheral.")
  56.         return missingItems, false
  57.     end
  58.  
  59.     for _, item in ipairs(itemConfig.items) do
  60.         local itemName = item.name
  61.         local requiredQuantity = item.quantity or 1
  62.         local availableQuantity = 0
  63.  
  64.         -- Check inventory for item and accumulate total countכא'
  65.         for slot, itemDetail in pairs(source.list()) do
  66.             if itemDetail.name == itemName then
  67.                 availableQuantity = availableQuantity + itemDetail.count
  68.             end
  69.         end
  70.  
  71.         -- Add to missing items if insufficient quantity
  72.         if availableQuantity < requiredQuantity then
  73.             table.insert(missingItems, {
  74.                 name = itemName,
  75.                 missing = requiredQuantity - availableQuantity
  76.             })
  77.         end
  78.     end
  79.  
  80.     return missingItems, #missingItems == 0
  81. end
  82.  
  83. -- Transfers ingredients to the processing input peripheral
  84. local function transferIngredients(ingredients, processingInput)
  85.     local inputPeripheral = peripheral.wrap(processingInput)
  86.     if not inputPeripheral then
  87.         print("Error: Could not find processing input peripheral.")
  88.         return false
  89.     end
  90.  
  91.     for _, ingredient in ipairs(ingredients) do
  92.         local ingredientName = ingredient.name
  93.         local quantity = ingredient.quantity or 1
  94.         local sourcePeripheral = peripheral.wrap(ingredient.source)
  95.  
  96.         if not sourcePeripheral then
  97.             print("Error: Could not find source peripheral for " .. ingredientName)
  98.             return false
  99.         end
  100.  
  101.         local transferred = 0
  102.         for slot, item in pairs(sourcePeripheral.list()) do
  103.             if item.name == ingredientName then
  104.                 local toTransfer = math.min(quantity - transferred, item.count)
  105.                 inputPeripheral.pullItems(peripheral.getName(sourcePeripheral), slot, toTransfer)
  106.                 transferred = transferred + toTransfer
  107.                 if transferred >= quantity then break end
  108.             end
  109.         end
  110.  
  111.         if transferred < quantity then
  112.             print("Error: Not enough " .. ingredientName .. " available.")
  113.             return false
  114.         end
  115.     end
  116.     return true
  117. end
  118.  
  119. local function waitForProduct(processingInput)
  120.     local inputPeripheral = peripheral.wrap(processingInput)
  121.     while #inputPeripheral.list() > 0 do
  122.         os.sleep(1)
  123.     end
  124. end
  125.  
  126. -- Transfers finished products to the stock destination peripheral
  127. local function transferProduct(productName, processingOutput, destination)
  128.     local outputPeripheral = peripheral.wrap(processingOutput)
  129.     local destinationPeripheral = peripheral.wrap(destination)
  130.  
  131.     if not outputPeripheral or not destinationPeripheral then
  132.         print("Error: Could not find processing output or destination peripheral.")
  133.         return
  134.     end
  135.  
  136.     for slot, item in pairs(outputPeripheral.list()) do
  137.         if item.name == productName then
  138.             outputPeripheral.pushItems(peripheral.getName(destinationPeripheral), slot)
  139.         end
  140.     end
  141. end
  142.  
  143. -- Displays status on the monitor
  144. local function displayStatus(config, currentStock, ingredientsReady)
  145.     local monitor = peripheral.wrap(monitorPeripheral)
  146.     if not monitor then
  147.         print("Error: Monitor not found.")
  148.         return
  149.     end
  150.  
  151.     monitor.clear()
  152.     monitor.setCursorPos(1, 1)
  153.     monitor.write("Stock Management:")
  154.     monitor.setCursorPos(1, 2)
  155.     monitor.write("- Product: " .. config.product)
  156.     monitor.setCursorPos(1, 3)
  157.     monitor.write("- Required Stock: " .. config.stock)
  158.     monitor.setCursorPos(1, 4)
  159.     monitor.write("- Current Stock: " .. currentStock)
  160.     monitor.setCursorPos(1, 5)
  161.     monitor.write("- Ingredients Ready: " .. (ingredientsReady and "Yes" or "No"))
  162. end
  163.  
  164. -- Main logic
  165. local function main()
  166.     local configFiles = readConfigFiles(configFolder)
  167.     for _, config in ipairs(configFiles) do
  168.         local productName = config.product
  169.         local requiredStock = config.stock
  170.         local destination = config.destination
  171.         local processingInput = config.processing_input
  172.         -- If output doesn't exist, assume it's the same block as the input
  173.         local processingOutput = config.processing_output or config.processing_input
  174.         local ingredients = config.ingredients
  175.         local batchSize = config.batch_size or 1
  176.         -- Check current stock level
  177.         local currentStock = checkStockLevel(productName, destination)
  178.         local ingredientsReady = false
  179.  
  180.         if currentStock < requiredStock then
  181.             local amountNeeded = math.ceil((requiredStock - currentStock) / batchSize)
  182.             print("Low stock for " .. productName .. ": Need " .. amountNeeded .. " batches")
  183.            
  184.             -- Adjust ingredient quantities based on amount needed
  185.             for _, ingredient in ipairs(ingredients) do
  186.                 -- If source is missing, assume the source is the same as the destination
  187.                 ingredient.source = ingredient.source or config.destination
  188.                 ingredient.quantity = ingredient.quantity * amountNeeded
  189.             end
  190.  
  191.             local missingItems, allAvailable = checkMissingItems(config)
  192.  
  193.             if not allAvailable then
  194.                 displayMissingResources(missingItems)
  195.                 goto continue
  196.             end
  197.             -- Transfer ingredients to processing input
  198.             ingredientsReady = transferIngredients(ingredients, processingInput)
  199.  
  200.             if ingredientsReady then
  201.                 print("Ingredients for " .. productName .. " placed in processing input.")
  202.             else
  203.                 print("Could not transfer ingredients for " .. productName .. ".")
  204.             end
  205.         end
  206.        
  207.         waitForProduct(processingInput)
  208.  
  209.         -- Transfer finished product to stock destination
  210.         transferProduct(productName, processingOutput, destination)
  211.  
  212.         -- Display status on the monitor
  213.         displayStatus(config, currentStock, ingredientsReady)
  214.        
  215.         ::continue::
  216.  
  217.     end
  218.     print("Stock management cycle complete.")
  219. end
  220.  
  221.  
  222. while true do
  223.     main()
  224.     os.sleep(10)
  225. end
  226.  
Advertisement
Add Comment
Please, Sign In to add comment