Advertisement
DanFrmSpace

solar_monitor_computer

Jun 10th, 2025 (edited)
982
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 15.26 KB | None | 0 0
  1. -- Monitor Computer Script for CC: Tweaked + Mekanism
  2. -- Receives solar farm data and manages 6 energy cubes with 3x3 monitor display
  3.  
  4. local CHANNEL = 100
  5. local MONITOR_WIDTH = 3
  6. local MONITOR_HEIGHT = 3
  7. local UPDATE_INTERVAL = 2 -- seconds
  8.  
  9. -- Peripheral setup
  10. local wiredModem = peripheral.wrap("right")
  11. local enderModem = peripheral.find("modem", function(name, modem)
  12.     return modem.isWireless()
  13. end)
  14. local monitor = peripheral.find("monitor")
  15.  
  16. -- Data storage
  17. local solarFarmData = nil
  18. local lastSolarUpdate = 0
  19.  
  20. -- Initialize peripherals
  21. local function initializePeripherals()
  22.     if not wiredModem then
  23.         error("Wired modem not found on right side")
  24.     end
  25.    
  26.     if not enderModem then
  27.         error("Ender modem not found on left side")
  28.     end
  29.    
  30.     if not monitor then
  31.         error("Monitor not found")
  32.     end
  33.    
  34.     enderModem.open(CHANNEL)
  35.    
  36.     -- Setup monitor
  37.     monitor.setTextScale(0.5)
  38.     monitor.clear()
  39.    
  40.     print("Peripherals initialized successfully")
  41. end
  42.  
  43. -- Get all connected energy cubes
  44. local function getEnergyCubes()
  45.     local cubes = {}
  46.     local connectedPeripherals = wiredModem.getNamesRemote()
  47.    
  48.     for _, name in ipairs(connectedPeripherals) do
  49.         if string.find(name, "basicEnergyCube_") then
  50.             cubes[#cubes + 1] = name
  51.         end
  52.     end
  53.    
  54.     table.sort(cubes)
  55.     print("Found " .. #cubes .. " energy cubes")
  56.     return cubes
  57. end
  58.  
  59. -- Collect data from a single energy cube
  60. local function collectCubeData(cubeName)
  61.     local success, data = pcall(function()
  62.         local cubeProxy = peripheral.wrap(cubeName)
  63.         if not cubeProxy then
  64.             return nil
  65.         end
  66.        
  67.         -- Use the correct Mekanism Energy Cube API methods
  68.         local energy = cubeProxy.getEnergy()
  69.         local maxEnergy = cubeProxy.getMaxEnergy()
  70.         local energyPercentage = maxEnergy > 0 and (energy / maxEnergy) * 100 or 0
  71.         local energyNeeded = cubeProxy.getEnergyNeeded()
  72.        
  73.         -- Try additional methods that should exist for energy cubes
  74.         local chargeItem = nil
  75.         local dischargeItem = nil
  76.        
  77.         pcall(function() chargeItem = cubeProxy.getChargeItem() end)
  78.         pcall(function() dischargeItem = cubeProxy.getDischargeItem() end)
  79.        
  80.         return {
  81.             name = cubeName,
  82.             energy = energy,
  83.             maxEnergy = maxEnergy,
  84.             energyPercentage = energyPercentage,
  85.             energyNeeded = energyNeeded,
  86.             chargeItem = chargeItem,
  87.             dischargeItem = dischargeItem
  88.         }
  89.     end)
  90.    
  91.     if not success then
  92.         print("Error collecting data from " .. cubeName .. ": " .. tostring(data))
  93.         return nil
  94.     end
  95.    
  96.     return data
  97. end
  98.  
  99. -- Collect data from all energy cubes
  100. local function collectAllCubeData(cubes)
  101.     local allData = {
  102.         timestamp = os.epoch("utc"),
  103.         totalCubes = #cubes,
  104.         cubes = {},
  105.         summary = {
  106.             totalEnergy = 0,
  107.             totalMaxEnergy = 0,
  108.             totalEnergyNeeded = 0,
  109.             averagePercentage = 0,
  110.             cubesActive = 0
  111.         }
  112.     }
  113.    
  114.     local validCubes = 0
  115.    
  116.     for _, cubeName in ipairs(cubes) do
  117.         local cubeData = collectCubeData(cubeName)
  118.         if cubeData then
  119.             allData.cubes[#allData.cubes + 1] = cubeData
  120.            
  121.             -- Update summary
  122.             allData.summary.totalEnergy = allData.summary.totalEnergy + cubeData.energy
  123.             allData.summary.totalMaxEnergy = allData.summary.totalMaxEnergy + cubeData.maxEnergy
  124.             allData.summary.totalEnergyNeeded = allData.summary.totalEnergyNeeded + cubeData.energyNeeded
  125.            
  126.             if cubeData.energy > 0 then
  127.                 allData.summary.cubesActive = allData.summary.cubesActive + 1
  128.             end
  129.            
  130.             validCubes = validCubes + 1
  131.         end
  132.     end
  133.    
  134.     -- Calculate average percentage
  135.     if validCubes > 0 and allData.summary.totalMaxEnergy > 0 then
  136.         allData.summary.averagePercentage = (allData.summary.totalEnergy / allData.summary.totalMaxEnergy) * 100
  137.     end
  138.    
  139.     allData.summary.validCubes = validCubes
  140.     return allData
  141. end
  142.  
  143. -- Listen for solar farm data
  144. local function listenForSolarData()
  145.     local event, side, channel, replyChannel, message, distance = os.pullEvent("modem_message")
  146.    
  147.     if channel == CHANNEL and type(message) == "table" and message.type == "solar_farm_data" then
  148.         solarFarmData = message.data
  149.         lastSolarUpdate = os.epoch("utc")
  150.         return true
  151.     end
  152.    
  153.     return false
  154. end
  155.  
  156. -- Format energy values for display
  157. local function formatEnergy(energy)
  158.     if energy >= 1000000 then
  159.         return string.format("%.1fM", energy / 1000000)
  160.     elseif energy >= 1000 then
  161.         return string.format("%.1fK", energy / 1000)
  162.     else
  163.         return string.format("%.0f", energy)
  164.     end
  165. end
  166.  
  167. -- Format percentage for display
  168. local function formatPercentage(percentage)
  169.     return string.format("%.1f%%", percentage)
  170. end
  171.  
  172. -- Get color based on percentage
  173. local function getPercentageColor(percentage)
  174.     if percentage >= 80 then
  175.         return colors.lime
  176.     elseif percentage >= 50 then
  177.         return colors.yellow
  178.     elseif percentage >= 25 then
  179.         return colors.orange
  180.     else
  181.         return colors.red
  182.     end
  183. end
  184.  
  185. -- Draw a progress bar
  186. local function drawProgressBar(monitor, x, y, width, percentage, color)
  187.     monitor.setCursorPos(x, y)
  188.     monitor.setBackgroundColor(colors.gray)
  189.    
  190.     local filled = math.floor((percentage / 100) * width)
  191.    
  192.     for i = 1, width do
  193.         if i <= filled then
  194.             monitor.setBackgroundColor(color)
  195.         else
  196.             monitor.setBackgroundColor(colors.gray)
  197.         end
  198.         monitor.write(" ")
  199.     end
  200.    
  201.     monitor.setBackgroundColor(colors.black)
  202. end
  203.  
  204. -- Display data on monitor
  205. local function displayOnMonitor(cubeData)
  206.     monitor.clear()
  207.     monitor.setCursorPos(1, 1)
  208.     monitor.setTextColor(colors.white)
  209.     monitor.setBackgroundColor(colors.black)
  210.    
  211.     local monitorWidth, monitorHeight = monitor.getSize()
  212.    
  213.     -- Header
  214.     monitor.setCursorPos(1, 1)
  215.     monitor.setTextColor(colors.lightBlue)
  216.     monitor.write("=== ENERGY MANAGEMENT SYSTEM ===")
  217.    
  218.     monitor.setCursorPos(monitorWidth - 19, 1)
  219.     monitor.setTextColor(colors.white)
  220.     monitor.write("Time: " .. os.date("%H:%M:%S"))
  221.    
  222.     -- Solar Farm Section (Left Column)
  223.     local leftCol = 1
  224.     local rightCol = math.floor(monitorWidth * 0.6) + 1
  225.     local currentLine = 3
  226.    
  227.     monitor.setCursorPos(leftCol, currentLine)
  228.     monitor.setTextColor(colors.yellow)
  229.     monitor.write("SOLAR FARM")
  230.     monitor.setCursorPos(leftCol + 11, currentLine)
  231.     monitor.setTextColor(colors.gray)
  232.     monitor.write(string.rep("-", 25))
  233.     currentLine = currentLine + 1
  234.    
  235.     if solarFarmData and (os.epoch("utc") - lastSolarUpdate) < 30000 then
  236.         -- Solar status
  237.         monitor.setCursorPos(leftCol, currentLine)
  238.         monitor.setTextColor(colors.white)
  239.         monitor.write("Status: ")
  240.         monitor.setTextColor(colors.green)
  241.         monitor.write("ONLINE")
  242.         currentLine = currentLine + 1
  243.        
  244.         monitor.setCursorPos(leftCol, currentLine)
  245.         monitor.setTextColor(colors.white)
  246.         monitor.write("Panels: " .. solarFarmData.summary.validPanels .. "/" .. solarFarmData.totalPanels)
  247.         monitor.write("  Sun: ")
  248.         if solarFarmData.summary.panelsSeeSun == solarFarmData.summary.validPanels then
  249.             monitor.setTextColor(colors.green)
  250.         else
  251.             monitor.setTextColor(colors.orange)
  252.         end
  253.         monitor.write(solarFarmData.summary.panelsSeeSun)
  254.         currentLine = currentLine + 1
  255.        
  256.         monitor.setCursorPos(leftCol, currentLine)
  257.         monitor.setTextColor(colors.white)
  258.         monitor.write("Energy: " .. formatEnergy(solarFarmData.summary.totalEnergy))
  259.         currentLine = currentLine + 1
  260.        
  261.         monitor.setCursorPos(leftCol, currentLine)
  262.         monitor.write("Capacity: " .. formatEnergy(solarFarmData.summary.totalMaxEnergy))
  263.         currentLine = currentLine + 1
  264.        
  265.         monitor.setCursorPos(leftCol, currentLine)
  266.         monitor.write("Production: " .. formatEnergy(solarFarmData.summary.totalProductionRate) .. "/t")
  267.         currentLine = currentLine + 1
  268.        
  269.         -- Solar progress bar
  270.         monitor.setCursorPos(leftCol, currentLine)
  271.         monitor.write("Fill: " .. formatPercentage(solarFarmData.summary.averagePercentage))
  272.         currentLine = currentLine + 1
  273.         drawProgressBar(monitor, leftCol, currentLine, 35, solarFarmData.summary.averagePercentage,
  274.                        getPercentageColor(solarFarmData.summary.averagePercentage))
  275.         currentLine = currentLine + 2
  276.     else
  277.         monitor.setCursorPos(leftCol, currentLine)
  278.         monitor.setTextColor(colors.red)
  279.         monitor.write("Status: OFFLINE")
  280.         currentLine = currentLine + 1
  281.        
  282.         monitor.setCursorPos(leftCol, currentLine)
  283.         monitor.setTextColor(colors.gray)
  284.         monitor.write("No solar data available")
  285.         currentLine = currentLine + 4
  286.     end
  287.    
  288.     -- Energy Storage Section (Right Column)
  289.     currentLine = 3
  290.     monitor.setCursorPos(rightCol, currentLine)
  291.     monitor.setTextColor(colors.cyan)
  292.     monitor.write("ENERGY STORAGE")
  293.     monitor.setCursorPos(rightCol + 15, currentLine)
  294.     monitor.setTextColor(colors.gray)
  295.     monitor.write(string.rep("-", 20))
  296.     currentLine = currentLine + 1
  297.    
  298.     monitor.setCursorPos(rightCol, currentLine)
  299.     monitor.setTextColor(colors.white)
  300.     monitor.write("Cubes: " .. cubeData.summary.validCubes .. "/" .. cubeData.totalCubes)
  301.     monitor.write("  Active: " .. cubeData.summary.cubesActive)
  302.     currentLine = currentLine + 1
  303.    
  304.     monitor.setCursorPos(rightCol, currentLine)
  305.     monitor.write("Stored: " .. formatEnergy(cubeData.summary.totalEnergy))
  306.     currentLine = currentLine + 1
  307.    
  308.     monitor.setCursorPos(rightCol, currentLine)
  309.     monitor.write("Capacity: " .. formatEnergy(cubeData.summary.totalMaxEnergy))
  310.     currentLine = currentLine + 1
  311.    
  312.     monitor.setCursorPos(rightCol, currentLine)
  313.     monitor.write("Available: " .. formatEnergy(cubeData.summary.totalEnergyNeeded))
  314.     currentLine = currentLine + 1
  315.    
  316.     -- Storage progress bar
  317.     monitor.setCursorPos(rightCol, currentLine)
  318.     monitor.write("Fill: " .. formatPercentage(cubeData.summary.averagePercentage))
  319.     currentLine = currentLine + 1
  320.     drawProgressBar(monitor, rightCol, currentLine, 35, cubeData.summary.averagePercentage,
  321.                    getPercentageColor(cubeData.summary.averagePercentage))
  322.     currentLine = currentLine + 2
  323.    
  324.     -- Individual cube status (Full width at bottom)
  325.     currentLine = math.max(currentLine, 12)
  326.     monitor.setCursorPos(1, currentLine)
  327.     monitor.setTextColor(colors.lightGray)
  328.     monitor.write("INDIVIDUAL CUBE STATUS")
  329.     monitor.setCursorPos(23, currentLine)
  330.     monitor.write(string.rep("-", monitorWidth - 22))
  331.     currentLine = currentLine + 1
  332.    
  333.     -- Create a grid layout for cubes (2 columns)
  334.     local cubesPerRow = 2
  335.     local colWidth = math.floor(monitorWidth / cubesPerRow)
  336.    
  337.     for i, cube in ipairs(cubeData.cubes) do
  338.         if currentLine < monitorHeight - 2 then
  339.             local col = ((i - 1) % cubesPerRow) + 1
  340.             local xPos = (col - 1) * colWidth + 1
  341.            
  342.             if col == 1 then
  343.                 -- Starting a new row
  344.                 if i > 1 then
  345.                     currentLine = currentLine + 1
  346.                 end
  347.             end
  348.            
  349.             monitor.setCursorPos(xPos, currentLine)
  350.             monitor.setTextColor(colors.white)
  351.            
  352.             local cubeId = string.match(cube.name, "basicEnergyCube_(%d+)")
  353.             local status = cube.energy > 0 and "ACTIVE" or "EMPTY"
  354.             local statusColor = cube.energy > 0 and colors.green or colors.gray
  355.            
  356.             monitor.write("Cube " .. cubeId .. ": ")
  357.             monitor.setTextColor(getPercentageColor(cube.energyPercentage))
  358.             monitor.write(formatPercentage(cube.energyPercentage))
  359.            
  360.             monitor.setCursorPos(xPos + 15, currentLine)
  361.             monitor.setTextColor(statusColor)
  362.             monitor.write(status)
  363.            
  364.             monitor.setCursorPos(xPos + 22, currentLine)
  365.             monitor.setTextColor(colors.white)
  366.             monitor.write(formatEnergy(cube.energy))
  367.         end
  368.     end
  369.    
  370.     -- System status at bottom
  371.     monitor.setCursorPos(1, monitorHeight)
  372.     monitor.setTextColor(colors.green)
  373.     monitor.write("SYSTEM ONLINE")
  374.    
  375.     monitor.setCursorPos(monitorWidth - 15, monitorHeight)
  376.     monitor.setTextColor(colors.gray)
  377.     monitor.write("Ch: " .. CHANNEL)
  378.    
  379.     -- Connection indicator
  380.     monitor.setCursorPos(monitorWidth - 8, monitorHeight)
  381.     if solarFarmData and (os.epoch("utc") - lastSolarUpdate) < 15000 then
  382.         monitor.setTextColor(colors.green)
  383.         monitor.write("LINKED")
  384.     else
  385.         monitor.setTextColor(colors.red)
  386.         monitor.write("UNLINK")
  387.     end
  388. end
  389.  
  390. -- Main execution function
  391. local function main()
  392.     print("Starting Monitor Computer...")
  393.    
  394.     initializePeripherals()
  395.     local cubes = getEnergyCubes()
  396.    
  397.     if #cubes == 0 then
  398.         error("No energy cubes found!")
  399.     end
  400.    
  401.     print("Starting monitoring loop...")
  402.    
  403.     -- Start listening for solar data in parallel
  404.     parallel.waitForAll(
  405.         function()
  406.             while true do
  407.                 listenForSolarData()
  408.             end
  409.         end,
  410.         function()
  411.             while true do
  412.                 local cubeData = collectAllCubeData(cubes)
  413.                 displayOnMonitor(cubeData)
  414.                
  415.                 -- Display summary on terminal
  416.                 term.clear()
  417.                 term.setCursorPos(1, 1)
  418.                 print("=== MONITOR COMPUTER ===")
  419.                 print("Time: " .. os.date("%H:%M:%S"))
  420.                 print("Energy Cubes: " .. cubeData.summary.validCubes .. "/" .. cubeData.totalCubes)
  421.                 print("Total Storage: " .. formatEnergy(cubeData.summary.totalEnergy) .. " FE")
  422.                 print("Storage Fill: " .. formatPercentage(cubeData.summary.averagePercentage))
  423.                
  424.                 if solarFarmData then
  425.                     local age = (os.epoch("utc") - lastSolarUpdate) / 1000
  426.                     print("Solar Data: " .. string.format("%.1fs old", age))
  427.                     print("Solar Production: " .. formatEnergy(solarFarmData.summary.totalProductionRate) .. " FE/t")
  428.                 else
  429.                     print("Solar Data: Not available")
  430.                 end
  431.                
  432.                 print("Monitor Updated: " .. os.date("%H:%M:%S"))
  433.                
  434.                 sleep(UPDATE_INTERVAL)
  435.             end
  436.         end
  437.     )
  438. end
  439.  
  440. -- Error handling wrapper
  441. local function runWithErrorHandling()
  442.     local success, err = pcall(main)
  443.     if not success then
  444.         print("Fatal error: " .. tostring(err))
  445.         print("Restarting in 10 seconds...")
  446.         sleep(10)
  447.         os.reboot()
  448.     end
  449. end
  450.  
  451. -- Start the program
  452. runWithErrorHandling()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement