Advertisement
toastonrye

ae2monitor

Jul 10th, 2025 (edited)
407
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.16 KB | None | 0 0
  1. -- AE2 System Monitor for CC: Tweaked with Advanced Peripherals
  2. -- This was tested in ATM10 v3.2 modpack
  3.  
  4. -- IMPORTANT: Older/Newer versions of Advanced Peripherals have different functions!
  5. -- This script will likely not work unless you are using Advanced Peripherals 0.7.49a
  6.  
  7. local MONITOR_SIDE = "left"
  8. local AE2_BRIDGE_SIDE = "right"
  9. local REFRESH_RATE = 1
  10.  
  11. local colors = colors
  12. local WHITE, BLACK = colors.white, colors.black
  13. local BLUE, GREEN, RED = colors.blue, colors.green, colors.red
  14. local YELLOW, GRAY, DARK_GRAY = colors.yellow, colors.lightGray, colors.gray
  15.  
  16. local monitor, ae2_bridge = nil, nil
  17. local currentTab = 1
  18. local tabNames = { "Power", "Usage", "Bytes", "Types" }
  19.  
  20. -- Cached values to prevent flickering
  21. local cache = {
  22.   energy = { stored = nil, max = nil },
  23.   usage = nil,
  24.   bytes = { used = nil, max = nil },
  25.   types = { used = nil, max = nil },
  26. }
  27.  
  28. local function initPeripherals()
  29.   monitor = peripheral.wrap(MONITOR_SIDE)
  30.   if not monitor or not monitor.isColor then error("No valid Advanced Monitor at " .. MONITOR_SIDE) end
  31.   ae2_bridge = peripheral.wrap(AE2_BRIDGE_SIDE)
  32.   if not ae2_bridge then error("No AE2 ME Bridge at " .. AE2_BRIDGE_SIDE) end
  33.   monitor.setTextScale(1)
  34. end
  35.  
  36. local function clearMain()
  37.   local width, height = monitor.getSize()
  38.   monitor.setBackgroundColor(BLACK)
  39.   monitor.setTextColor(WHITE)
  40.   for y = 1, height - 3 do
  41.     monitor.setCursorPos(1, y)
  42.     monitor.write(string.rep(" ", width))
  43.   end
  44. end
  45.  
  46. local function formatNumber(n)
  47.   if n >= 1e12 then return string.format("%.2fT", n/1e12)
  48.   elseif n >= 1e9 then return string.format("%.2fG", n/1e9)
  49.   elseif n >= 1e6 then return string.format("%.2fM", n/1e6)
  50.   elseif n >= 1e3 then return string.format("%.2fK", n/1e3)
  51.   else return tostring(math.floor(n)) end
  52. end
  53.  
  54. local function drawBar(x, y, width, progress, max, fg, bg)
  55.   local filled = math.floor(width * (progress / max))
  56.   monitor.setCursorPos(x, y)
  57.   monitor.setBackgroundColor(fg)
  58.   monitor.write(string.rep(" ", filled))
  59.   monitor.setBackgroundColor(bg)
  60.   monitor.write(string.rep(" ", width - filled))
  61. end
  62.  
  63. local function centerText(y, text, color)
  64.   local width = monitor.getSize()
  65.   monitor.setCursorPos(math.floor((width - #text) / 2), y)
  66.   monitor.setTextColor(color or WHITE)
  67.   monitor.write(text)
  68. end
  69.  
  70. local function drawPowerTab()
  71.   local ok1, stored = pcall(ae2_bridge.getEnergyStorage)
  72.   local ok2, max = pcall(ae2_bridge.getMaxEnergyStorage)
  73.   if not (ok1 and ok2 and stored and max) then
  74.     if cache.energy.stored ~= "error" then
  75.       clearMain()
  76.       centerText(1, tabNames[1])
  77.       centerText(3, "Error: Failed to read AE2 energy.", YELLOW)
  78.       cache.energy.stored = "error"
  79.     end
  80.     return
  81.   end
  82.   if stored == cache.energy.stored and max == cache.energy.max then return end
  83.   cache.energy.stored, cache.energy.max = stored, max
  84.  
  85.   clearMain()
  86.   centerText(1, tabNames[1])
  87.   local pct = (stored / max) * 100
  88.   local color = pct < 25 and RED or pct < 50 and YELLOW or GREEN
  89.   centerText(3, string.format("Stored: %s AE / %s AE", formatNumber(stored), formatNumber(max)))
  90.   centerText(4, string.format("Percentage: %.2f%%", pct))
  91.   local w = math.floor(monitor.getSize() * 0.8)
  92.   drawBar(math.floor((monitor.getSize() - w)/2), 6, w, stored, max, color, GRAY)
  93. end
  94.  
  95. local function drawUsageTab()
  96.   local ok, usage = pcall(ae2_bridge.getEnergyUsage)
  97.   if not ok or not usage then
  98.     if cache.usage ~= "error" then
  99.       clearMain()
  100.       centerText(1, tabNames[2])
  101.       centerText(3, "Error: Failed to read AE2 usage.", YELLOW)
  102.       cache.usage = "error"
  103.     end
  104.     return
  105.   end
  106.   if usage == cache.usage then return end
  107.   cache.usage = usage
  108.  
  109.   clearMain()
  110.   centerText(1, tabNames[2])
  111.   centerText(3, string.format("Current Usage: %s AE/t", formatNumber(usage)))
  112.   centerText(5, "This is an instantaneous reading.")
  113.   centerText(6, "Actual usage fluctuates with activity.")
  114. end
  115.  
  116. local function drawBytesTab()
  117.   local ok1, used = pcall(ae2_bridge.getUsedItemStorage)
  118.   local ok2, max = pcall(ae2_bridge.getTotalItemStorage)
  119.   if not (ok1 and ok2 and used and max) then
  120.     if cache.bytes.used ~= "error" then
  121.       clearMain()
  122.       centerText(1, tabNames[3])
  123.       centerText(3, "Error: Failed to read AE2 bytes.", YELLOW)
  124.       cache.bytes.used = "error"
  125.     end
  126.     return
  127.   end
  128.   if used == cache.bytes.used and max == cache.bytes.max then return end
  129.   cache.bytes.used, cache.bytes.max = used, max
  130.  
  131.   clearMain()
  132.   centerText(1, tabNames[3])
  133.   local pct = (used / max) * 100
  134.   local color = pct > 75 and RED or pct > 50 and YELLOW or GREEN
  135.   centerText(3, string.format("Used: %s B / %s B", formatNumber(used), formatNumber(max)))
  136.   centerText(4, string.format("Percentage: %.2f%%", pct))
  137.   local w = math.floor(monitor.getSize() * 0.8)
  138.   drawBar(math.floor((monitor.getSize() - w)/2), 6, w, used, max, color, GRAY)
  139. end
  140.  
  141. local function drawTypesTab()
  142.   local ok, items = pcall(ae2_bridge.listItems)
  143.   if not ok or not items then
  144.     if cache.types.used ~= "error" then
  145.       clearMain()
  146.       centerText(1, tabNames[4])
  147.       centerText(3, "Error: Failed to list items.", YELLOW)
  148.       cache.types.used = "error"
  149.     end
  150.     return
  151.   end
  152.  
  153.   local types = {}
  154.   for _, item in ipairs(items) do
  155.     if item and item.fingerprint then
  156.         types[item.fingerprint] = true
  157.     end
  158.     end
  159.  
  160.   local used = 0
  161.     for _ in pairs(types) do
  162.         used = used + 1
  163.     end
  164.  
  165.   --[[
  166.   local ok1, used = pcall(ae2_bridge.getItemTypes)
  167.   local ok2, max = pcall(ae2_bridge.getMaxItemTypes)
  168.   if not (ok1 and ok2) then
  169.     if cache.types.used ~= "error" then
  170.       clearMain()
  171.       centerText(1, tabNames[4])
  172.       centerText(3, "Error: Failed to get types.", YELLOW)
  173.       cache.types.used = "error"
  174.     end
  175.     return
  176.   end
  177.   --]]
  178.  
  179.   clearMain()
  180.   centerText(1, tabNames[4])
  181.   --local pct = (used / max) * 100
  182.   --local color = pct > 75 and RED or pct > 50 and YELLOW or GREEN
  183.   --centerText(3, string.format("Used: %s Types / %s Types", formatNumber(used), formatNumber(max)))
  184.   centerText(2, string.format("Unique fingerprints or types: %d", used))
  185.   --centerText(4, string.format("Percentage: %.2f%%", pct))
  186.   --local w = math.floor(monitor.getSize() * 0.8)
  187.   --drawBar(math.floor((monitor.getSize() - w)/2), 6, w, used, max, color, GRAY)
  188. end
  189.  
  190. local function drawNavigation()
  191.   local width, height = monitor.getSize()
  192.   local tabY, spacing = height - 2, 1
  193.   local totalWidth = 0
  194.   for _, name in ipairs(tabNames) do totalWidth = totalWidth + #name + 2 + spacing end
  195.   local x = math.floor((width - totalWidth) / 2)
  196.   for i, name in ipairs(tabNames) do
  197.     local w = #name + 2
  198.     monitor.setCursorPos(x, tabY)
  199.     monitor.setBackgroundColor(i == currentTab and BLUE or DARK_GRAY)
  200.     monitor.setTextColor(i == currentTab and YELLOW or WHITE)
  201.     monitor.write(" " .. name .. " ")
  202.     x = x + w + spacing
  203.   end
  204. end
  205.  
  206. local function handleTouch(x, y)
  207.   local width, height = monitor.getSize()
  208.   local tabY = height - 2
  209.   if y ~= tabY then return end
  210.  
  211.   local spacing = 1
  212.   local totalWidth = 0
  213.   for _, name in ipairs(tabNames) do totalWidth = totalWidth + #name + 2 + spacing end
  214.   local xPos = math.floor((width - totalWidth) / 2)
  215.   for i, name in ipairs(tabNames) do
  216.     local w = #name + 2
  217.     if x >= xPos and x <= xPos + w - 1 then
  218.       if currentTab ~= i then
  219.         currentTab = i
  220.         drawUI()
  221.         drawNavigation()
  222.       end
  223.       return
  224.     end
  225.     xPos = xPos + w + spacing
  226.   end
  227. end
  228.  
  229. function drawUI()
  230.   if currentTab == 1 then drawPowerTab()
  231.   elseif currentTab == 2 then drawUsageTab()
  232.   elseif currentTab == 3 then drawBytesTab()
  233.   elseif currentTab == 4 then drawTypesTab() end
  234. end
  235.  
  236. local function main()
  237.   initPeripherals()
  238.   drawUI()
  239.   drawNavigation()
  240.   local lastTouch = 0
  241.   local timer = os.startTimer(REFRESH_RATE)
  242.  
  243.   while true do
  244.     local e, p1, p2, p3 = os.pullEvent()
  245.     if e == "monitor_touch" and p1 == MONITOR_SIDE then
  246.       local now = os.clock()
  247.       if now - lastTouch > 0.25 then
  248.         handleTouch(p2, p3)
  249.         lastTouch = now
  250.       end
  251.     elseif e == "timer" and p1 == timer then
  252.       drawUI()
  253.       drawNavigation()
  254.       timer = os.startTimer(REFRESH_RATE)
  255.     end
  256.   end
  257. end
  258.  
  259. main()
  260.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement