Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- flow_monitor.lua
- -- Measures fluid entering a tank peripheral each second.
- -- Compatible with Mekanism tanks, Create fluid tanks, etc.
- -- Usage: place a tank adjacent to the computer (or modem-connected)
- -- and optionally connect a monitor for a bigger display.
- local PERIPHERAL_SIDE = "right" -- change to the side/name of your tank
- local UPDATE_RATE = 1 -- seconds between samples
- local HISTORY_SIZE = 60 -- how many readings to keep for the average
- -- ─── Peripheral Setup ───────────────────────────────────────────────────────
- local tank = peripheral.wrap(PERIPHERAL_SIDE)
- if not tank then
- error("No peripheral found on side: " .. PERIPHERAL_SIDE, 0)
- end
- -- Try to grab an attached monitor; fall back to the terminal
- local display = peripheral.find("monitor") or term
- if display ~= term then
- display.setTextScale(0.5)
- end
- -- ─── Helpers ────────────────────────────────────────────────────────────────
- --- Returns the current fluid amount in mB, or 0 if the tank is empty.
- local function getFluidAmount()
- local data = tank.tanks()
- if not data or #data == 0 then return 0 end
- return data[1].amount or 0
- end
- --- Returns the max capacity in mB.
- local function getFluidCapacity()
- if tank.getFluidCapacity then return tank.getFluidCapacity() end
- if tank.getCapacity then return tank.getCapacity() end
- if tank.getTankCapacity then return tank.getTankCapacity(0) end
- return nil
- end
- --- Returns the name of the stored fluid, or "empty".
- local function getFluidName()
- local data = tank.tanks()
- if not data or #data == 0 then return "empty" end
- local name = data[1].name or "unknown"
- -- strip the mod prefix, e.g. "modernindustrialization:uu_matter" -> "uu_matter"
- return name:match(":(.+)$") or name
- end
- --- Format large numbers with commas, e.g. 1234567 → "1,234,567"
- local function commas(n)
- local s = tostring(math.abs(math.floor(n)))
- local result = ""
- local count = 0
- for i = #s, 1, -1 do
- if count > 0 and count % 3 == 0 then result = "," .. result end
- result = s:sub(i, i) .. result
- count = count + 1
- end
- if n < 0 then result = "-" .. result end
- return result
- end
- --- Colour-code the flow rate (positive = filling, negative = draining).
- local function flowColour(rate)
- if rate > 0 then return colours.lime end
- if rate < 0 then return colours.red end
- return colours.yellow
- end
- -- ─── Main Loop ──────────────────────────────────────────────────────────────
- local history = {} -- ring buffer of per-second deltas
- local prevAmount = getFluidAmount()
- local peakFlow = 0
- local lowestFlow = 0
- while true do
- os.sleep(UPDATE_RATE)
- local current = getFluidAmount()
- local delta = current - prevAmount -- mB gained this second
- prevAmount = current
- -- Update history ring buffer
- table.insert(history, delta)
- if #history > HISTORY_SIZE then table.remove(history, 1) end
- -- Rolling average
- local sum = 0
- for _, v in ipairs(history) do sum = sum + v end
- local avg = sum / #history
- -- Track extremes (ignore zero – tank is probably full or empty)
- if delta > peakFlow then peakFlow = delta end
- if delta < lowestFlow then lowestFlow = delta end
- -- ── Draw ─────────────────────────────────────────────────────────────────
- local w, h = display.getSize()
- display.setBackgroundColour(colours.black)
- display.clear()
- display.setCursorPos(1, 1)
- -- Header
- display.setTextColour(colours.cyan)
- display.setCursorPos(math.floor((w - 20) / 2) + 1, 1)
- display.write("=== FLUID FLOW MONITOR ===")
- -- Fluid name
- local name = getFluidName()
- display.setTextColour(colours.white)
- display.setCursorPos(1, 3)
- display.write(("Fluid : %s"):format(name))
- -- Current level / capacity
- local cap = getFluidCapacity()
- local fill = cap and (current / cap * 100) or nil
- display.setCursorPos(1, 4)
- display.write(("Level : %s mB"):format(commas(current)))
- if cap and fill then
- display.write((" / %s mB (%.1f%%)"):format(commas(cap), fill))
- end
- -- Current flow rate
- display.setCursorPos(1, 6)
- display.setTextColour(flowColour(delta))
- local sign = delta >= 0 and "+" or ""
- display.write(("Flow : %s%s mB/s"):format(sign, commas(delta)))
- -- Avg flow
- display.setCursorPos(1, 7)
- display.setTextColour(flowColour(avg))
- sign = avg >= 0 and "+" or ""
- display.write(("Avg : %s%.1f mB/s (last %ds)"):format(sign, avg, #history))
- -- Peak / low
- display.setTextColour(colours.orange)
- display.setCursorPos(1, 9)
- display.write(("Peak : +%s mB/s"):format(commas(peakFlow)))
- display.setTextColour(colours.red)
- display.setCursorPos(1, 10)
- display.write(("Low : %s mB/s"):format(commas(lowestFlow)))
- -- Simple bar graph (only if there's room)
- if h >= 14 and cap and cap > 0 then
- local barW = w - 10
- local filled = math.floor(barW * (current / cap))
- display.setTextColour(colours.white)
- display.setCursorPos(1, 12)
- display.write("Fill: [")
- display.setTextColour(colours.lime)
- display.write(string.rep("|", filled))
- display.setTextColour(colours.grey)
- display.write(string.rep("-", barW - filled))
- display.setTextColour(colours.white)
- display.write("]")
- end
- -- Timestamp
- display.setTextColour(colours.grey)
- display.setCursorPos(1, h)
- display.write(os.date and os.date("%H:%M:%S") or "")
- end
Advertisement
Add Comment
Please, Sign In to add comment