Nessiesson

[Claude] ComputerCraft Fluid Flow Rate Calculator

Apr 22nd, 2026 (edited)
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.93 KB | None | 0 0
  1. -- flow_monitor.lua
  2. -- Measures fluid entering a tank peripheral each second.
  3. -- Compatible with Mekanism tanks, Create fluid tanks, etc.
  4. -- Usage: place a tank adjacent to the computer (or modem-connected)
  5. --        and optionally connect a monitor for a bigger display.
  6.  
  7. local PERIPHERAL_SIDE = "right"   -- change to the side/name of your tank
  8. local UPDATE_RATE      = 1         -- seconds between samples
  9. local HISTORY_SIZE     = 60        -- how many readings to keep for the average
  10.  
  11. -- ─── Peripheral Setup ───────────────────────────────────────────────────────
  12.  
  13. local tank = peripheral.wrap(PERIPHERAL_SIDE)
  14. if not tank then
  15.   error("No peripheral found on side: " .. PERIPHERAL_SIDE, 0)
  16. end
  17.  
  18. -- Try to grab an attached monitor; fall back to the terminal
  19. local display = peripheral.find("monitor") or term
  20. if display ~= term then
  21.   display.setTextScale(0.5)
  22. end
  23.  
  24. -- ─── Helpers ────────────────────────────────────────────────────────────────
  25.  
  26. --- Returns the current fluid amount in mB, or 0 if the tank is empty.
  27. local function getFluidAmount()
  28.   local data = tank.tanks()
  29.   if not data or #data == 0 then return 0 end
  30.   return data[1].amount or 0
  31. end
  32.  
  33. --- Returns the max capacity in mB.
  34. local function getFluidCapacity()
  35.   if tank.getFluidCapacity    then return tank.getFluidCapacity()    end
  36.   if tank.getCapacity         then return tank.getCapacity()          end
  37.   if tank.getTankCapacity     then return tank.getTankCapacity(0)     end
  38.   return nil
  39. end
  40.  
  41. --- Returns the name of the stored fluid, or "empty".
  42. local function getFluidName()
  43.   local data = tank.tanks()
  44.   if not data or #data == 0 then return "empty" end
  45.   local name = data[1].name or "unknown"
  46.   -- strip the mod prefix, e.g. "modernindustrialization:uu_matter" -> "uu_matter"
  47.   return name:match(":(.+)$") or name
  48. end
  49.  
  50. --- Format large numbers with commas, e.g. 1234567 → "1,234,567"
  51. local function commas(n)
  52.   local s = tostring(math.abs(math.floor(n)))
  53.   local result = ""
  54.   local count = 0
  55.   for i = #s, 1, -1 do
  56.     if count > 0 and count % 3 == 0 then result = "," .. result end
  57.     result = s:sub(i, i) .. result
  58.     count = count + 1
  59.   end
  60.   if n < 0 then result = "-" .. result end
  61.   return result
  62. end
  63.  
  64. --- Colour-code the flow rate (positive = filling, negative = draining).
  65. local function flowColour(rate)
  66.   if rate > 0  then return colours.lime    end
  67.   if rate < 0  then return colours.red     end
  68.   return colours.yellow
  69. end
  70.  
  71. -- ─── Main Loop ──────────────────────────────────────────────────────────────
  72.  
  73. local history     = {}   -- ring buffer of per-second deltas
  74. local prevAmount  = getFluidAmount()
  75. local peakFlow    = 0
  76. local lowestFlow  = 0
  77.  
  78. while true do
  79.   os.sleep(UPDATE_RATE)
  80.  
  81.   local current   = getFluidAmount()
  82.   local delta     = current - prevAmount   -- mB gained this second
  83.   prevAmount      = current
  84.  
  85.   -- Update history ring buffer
  86.   table.insert(history, delta)
  87.   if #history > HISTORY_SIZE then table.remove(history, 1) end
  88.  
  89.   -- Rolling average
  90.   local sum = 0
  91.   for _, v in ipairs(history) do sum = sum + v end
  92.   local avg = sum / #history
  93.  
  94.   -- Track extremes (ignore zero – tank is probably full or empty)
  95.   if delta > peakFlow  then peakFlow  = delta end
  96.   if delta < lowestFlow then lowestFlow = delta end
  97.  
  98.   -- ── Draw ─────────────────────────────────────────────────────────────────
  99.   local w, h = display.getSize()
  100.   display.setBackgroundColour(colours.black)
  101.   display.clear()
  102.   display.setCursorPos(1, 1)
  103.  
  104.   -- Header
  105.   display.setTextColour(colours.cyan)
  106.   display.setCursorPos(math.floor((w - 20) / 2) + 1, 1)
  107.   display.write("=== FLUID FLOW MONITOR ===")
  108.  
  109.   -- Fluid name
  110.   local name = getFluidName()
  111.   display.setTextColour(colours.white)
  112.   display.setCursorPos(1, 3)
  113.   display.write(("Fluid : %s"):format(name))
  114.  
  115.   -- Current level / capacity
  116.   local cap  = getFluidCapacity()
  117.   local fill = cap and (current / cap * 100) or nil
  118.   display.setCursorPos(1, 4)
  119.   display.write(("Level : %s mB"):format(commas(current)))
  120.   if cap and fill then
  121.     display.write(("  /  %s mB  (%.1f%%)"):format(commas(cap), fill))
  122.   end
  123.  
  124.   -- Current flow rate
  125.   display.setCursorPos(1, 6)
  126.   display.setTextColour(flowColour(delta))
  127.   local sign = delta >= 0 and "+" or ""
  128.   display.write(("Flow  : %s%s mB/s"):format(sign, commas(delta)))
  129.  
  130.   -- Avg flow
  131.   display.setCursorPos(1, 7)
  132.   display.setTextColour(flowColour(avg))
  133.   sign = avg >= 0 and "+" or ""
  134.   display.write(("Avg   : %s%.1f mB/s  (last %ds)"):format(sign, avg, #history))
  135.  
  136.   -- Peak / low
  137.   display.setTextColour(colours.orange)
  138.   display.setCursorPos(1, 9)
  139.   display.write(("Peak  : +%s mB/s"):format(commas(peakFlow)))
  140.   display.setTextColour(colours.red)
  141.   display.setCursorPos(1, 10)
  142.   display.write(("Low   : %s mB/s"):format(commas(lowestFlow)))
  143.  
  144.   -- Simple bar graph (only if there's room)
  145.   if h >= 14 and cap and cap > 0 then
  146.     local barW   = w - 10
  147.     local filled = math.floor(barW * (current / cap))
  148.     display.setTextColour(colours.white)
  149.     display.setCursorPos(1, 12)
  150.     display.write("Fill: [")
  151.     display.setTextColour(colours.lime)
  152.     display.write(string.rep("|", filled))
  153.     display.setTextColour(colours.grey)
  154.     display.write(string.rep("-", barW - filled))
  155.     display.setTextColour(colours.white)
  156.     display.write("]")
  157.   end
  158.  
  159.   -- Timestamp
  160.   display.setTextColour(colours.grey)
  161.   display.setCursorPos(1, h)
  162.   display.write(os.date and os.date("%H:%M:%S") or "")
  163. end
Advertisement
Add Comment
Please, Sign In to add comment