Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Monitor Computer Script for CC: Tweaked + Mekanism
- -- Receives solar farm data and manages 6 energy cubes with 3x3 monitor display
- local CHANNEL = 100
- local MONITOR_WIDTH = 3
- local MONITOR_HEIGHT = 3
- local UPDATE_INTERVAL = 2 -- seconds
- -- Peripheral setup
- local wiredModem = peripheral.wrap("right")
- local enderModem = peripheral.find("modem", function(name, modem)
- return modem.isWireless()
- end)
- local monitor = peripheral.find("monitor")
- -- Data storage
- local solarFarmData = nil
- local lastSolarUpdate = 0
- -- Initialize peripherals
- local function initializePeripherals()
- if not wiredModem then
- error("Wired modem not found on right side")
- end
- if not enderModem then
- error("Ender modem not found on left side")
- end
- if not monitor then
- error("Monitor not found")
- end
- enderModem.open(CHANNEL)
- -- Setup monitor
- monitor.setTextScale(0.5)
- monitor.clear()
- print("Peripherals initialized successfully")
- end
- -- Get all connected energy cubes
- local function getEnergyCubes()
- local cubes = {}
- local connectedPeripherals = wiredModem.getNamesRemote()
- for _, name in ipairs(connectedPeripherals) do
- if string.find(name, "basicEnergyCube_") then
- cubes[#cubes + 1] = name
- end
- end
- table.sort(cubes)
- print("Found " .. #cubes .. " energy cubes")
- return cubes
- end
- -- Collect data from a single energy cube
- local function collectCubeData(cubeName)
- local success, data = pcall(function()
- local cubeProxy = peripheral.wrap(cubeName)
- if not cubeProxy then
- return nil
- end
- -- Use the correct Mekanism Energy Cube API methods
- local energy = cubeProxy.getEnergy()
- local maxEnergy = cubeProxy.getMaxEnergy()
- local energyPercentage = maxEnergy > 0 and (energy / maxEnergy) * 100 or 0
- local energyNeeded = cubeProxy.getEnergyNeeded()
- -- Try additional methods that should exist for energy cubes
- local chargeItem = nil
- local dischargeItem = nil
- pcall(function() chargeItem = cubeProxy.getChargeItem() end)
- pcall(function() dischargeItem = cubeProxy.getDischargeItem() end)
- return {
- name = cubeName,
- energy = energy,
- maxEnergy = maxEnergy,
- energyPercentage = energyPercentage,
- energyNeeded = energyNeeded,
- chargeItem = chargeItem,
- dischargeItem = dischargeItem
- }
- end)
- if not success then
- print("Error collecting data from " .. cubeName .. ": " .. tostring(data))
- return nil
- end
- return data
- end
- -- Collect data from all energy cubes
- local function collectAllCubeData(cubes)
- local allData = {
- timestamp = os.epoch("utc"),
- totalCubes = #cubes,
- cubes = {},
- summary = {
- totalEnergy = 0,
- totalMaxEnergy = 0,
- totalEnergyNeeded = 0,
- averagePercentage = 0,
- cubesActive = 0
- }
- }
- local validCubes = 0
- for _, cubeName in ipairs(cubes) do
- local cubeData = collectCubeData(cubeName)
- if cubeData then
- allData.cubes[#allData.cubes + 1] = cubeData
- -- Update summary
- allData.summary.totalEnergy = allData.summary.totalEnergy + cubeData.energy
- allData.summary.totalMaxEnergy = allData.summary.totalMaxEnergy + cubeData.maxEnergy
- allData.summary.totalEnergyNeeded = allData.summary.totalEnergyNeeded + cubeData.energyNeeded
- if cubeData.energy > 0 then
- allData.summary.cubesActive = allData.summary.cubesActive + 1
- end
- validCubes = validCubes + 1
- end
- end
- -- Calculate average percentage
- if validCubes > 0 and allData.summary.totalMaxEnergy > 0 then
- allData.summary.averagePercentage = (allData.summary.totalEnergy / allData.summary.totalMaxEnergy) * 100
- end
- allData.summary.validCubes = validCubes
- return allData
- end
- -- Listen for solar farm data
- local function listenForSolarData()
- local event, side, channel, replyChannel, message, distance = os.pullEvent("modem_message")
- if channel == CHANNEL and type(message) == "table" and message.type == "solar_farm_data" then
- solarFarmData = message.data
- lastSolarUpdate = os.epoch("utc")
- return true
- end
- return false
- end
- -- Format energy values for display
- local function formatEnergy(energy)
- if energy >= 1000000 then
- return string.format("%.1fM", energy / 1000000)
- elseif energy >= 1000 then
- return string.format("%.1fK", energy / 1000)
- else
- return string.format("%.0f", energy)
- end
- end
- -- Format percentage for display
- local function formatPercentage(percentage)
- return string.format("%.1f%%", percentage)
- end
- -- Get color based on percentage
- local function getPercentageColor(percentage)
- if percentage >= 80 then
- return colors.lime
- elseif percentage >= 50 then
- return colors.yellow
- elseif percentage >= 25 then
- return colors.orange
- else
- return colors.red
- end
- end
- -- Draw a progress bar
- local function drawProgressBar(monitor, x, y, width, percentage, color)
- monitor.setCursorPos(x, y)
- monitor.setBackgroundColor(colors.gray)
- local filled = math.floor((percentage / 100) * width)
- for i = 1, width do
- if i <= filled then
- monitor.setBackgroundColor(color)
- else
- monitor.setBackgroundColor(colors.gray)
- end
- monitor.write(" ")
- end
- monitor.setBackgroundColor(colors.black)
- end
- -- Display data on monitor
- local function displayOnMonitor(cubeData)
- monitor.clear()
- monitor.setCursorPos(1, 1)
- monitor.setTextColor(colors.white)
- monitor.setBackgroundColor(colors.black)
- local monitorWidth, monitorHeight = monitor.getSize()
- -- Header
- monitor.setCursorPos(1, 1)
- monitor.setTextColor(colors.lightBlue)
- monitor.write("=== ENERGY MANAGEMENT SYSTEM ===")
- monitor.setCursorPos(monitorWidth - 19, 1)
- monitor.setTextColor(colors.white)
- monitor.write("Time: " .. os.date("%H:%M:%S"))
- -- Solar Farm Section (Left Column)
- local leftCol = 1
- local rightCol = math.floor(monitorWidth * 0.6) + 1
- local currentLine = 3
- monitor.setCursorPos(leftCol, currentLine)
- monitor.setTextColor(colors.yellow)
- monitor.write("SOLAR FARM")
- monitor.setCursorPos(leftCol + 11, currentLine)
- monitor.setTextColor(colors.gray)
- monitor.write(string.rep("-", 25))
- currentLine = currentLine + 1
- if solarFarmData and (os.epoch("utc") - lastSolarUpdate) < 30000 then
- -- Solar status
- monitor.setCursorPos(leftCol, currentLine)
- monitor.setTextColor(colors.white)
- monitor.write("Status: ")
- monitor.setTextColor(colors.green)
- monitor.write("ONLINE")
- currentLine = currentLine + 1
- monitor.setCursorPos(leftCol, currentLine)
- monitor.setTextColor(colors.white)
- monitor.write("Panels: " .. solarFarmData.summary.validPanels .. "/" .. solarFarmData.totalPanels)
- monitor.write(" Sun: ")
- if solarFarmData.summary.panelsSeeSun == solarFarmData.summary.validPanels then
- monitor.setTextColor(colors.green)
- else
- monitor.setTextColor(colors.orange)
- end
- monitor.write(solarFarmData.summary.panelsSeeSun)
- currentLine = currentLine + 1
- monitor.setCursorPos(leftCol, currentLine)
- monitor.setTextColor(colors.white)
- monitor.write("Energy: " .. formatEnergy(solarFarmData.summary.totalEnergy))
- currentLine = currentLine + 1
- monitor.setCursorPos(leftCol, currentLine)
- monitor.write("Capacity: " .. formatEnergy(solarFarmData.summary.totalMaxEnergy))
- currentLine = currentLine + 1
- monitor.setCursorPos(leftCol, currentLine)
- monitor.write("Production: " .. formatEnergy(solarFarmData.summary.totalProductionRate) .. "/t")
- currentLine = currentLine + 1
- -- Solar progress bar
- monitor.setCursorPos(leftCol, currentLine)
- monitor.write("Fill: " .. formatPercentage(solarFarmData.summary.averagePercentage))
- currentLine = currentLine + 1
- drawProgressBar(monitor, leftCol, currentLine, 35, solarFarmData.summary.averagePercentage,
- getPercentageColor(solarFarmData.summary.averagePercentage))
- currentLine = currentLine + 2
- else
- monitor.setCursorPos(leftCol, currentLine)
- monitor.setTextColor(colors.red)
- monitor.write("Status: OFFLINE")
- currentLine = currentLine + 1
- monitor.setCursorPos(leftCol, currentLine)
- monitor.setTextColor(colors.gray)
- monitor.write("No solar data available")
- currentLine = currentLine + 4
- end
- -- Energy Storage Section (Right Column)
- currentLine = 3
- monitor.setCursorPos(rightCol, currentLine)
- monitor.setTextColor(colors.cyan)
- monitor.write("ENERGY STORAGE")
- monitor.setCursorPos(rightCol + 15, currentLine)
- monitor.setTextColor(colors.gray)
- monitor.write(string.rep("-", 20))
- currentLine = currentLine + 1
- monitor.setCursorPos(rightCol, currentLine)
- monitor.setTextColor(colors.white)
- monitor.write("Cubes: " .. cubeData.summary.validCubes .. "/" .. cubeData.totalCubes)
- monitor.write(" Active: " .. cubeData.summary.cubesActive)
- currentLine = currentLine + 1
- monitor.setCursorPos(rightCol, currentLine)
- monitor.write("Stored: " .. formatEnergy(cubeData.summary.totalEnergy))
- currentLine = currentLine + 1
- monitor.setCursorPos(rightCol, currentLine)
- monitor.write("Capacity: " .. formatEnergy(cubeData.summary.totalMaxEnergy))
- currentLine = currentLine + 1
- monitor.setCursorPos(rightCol, currentLine)
- monitor.write("Available: " .. formatEnergy(cubeData.summary.totalEnergyNeeded))
- currentLine = currentLine + 1
- -- Storage progress bar
- monitor.setCursorPos(rightCol, currentLine)
- monitor.write("Fill: " .. formatPercentage(cubeData.summary.averagePercentage))
- currentLine = currentLine + 1
- drawProgressBar(monitor, rightCol, currentLine, 35, cubeData.summary.averagePercentage,
- getPercentageColor(cubeData.summary.averagePercentage))
- currentLine = currentLine + 2
- -- Individual cube status (Full width at bottom)
- currentLine = math.max(currentLine, 12)
- monitor.setCursorPos(1, currentLine)
- monitor.setTextColor(colors.lightGray)
- monitor.write("INDIVIDUAL CUBE STATUS")
- monitor.setCursorPos(23, currentLine)
- monitor.write(string.rep("-", monitorWidth - 22))
- currentLine = currentLine + 1
- -- Create a grid layout for cubes (2 columns)
- local cubesPerRow = 2
- local colWidth = math.floor(monitorWidth / cubesPerRow)
- for i, cube in ipairs(cubeData.cubes) do
- if currentLine < monitorHeight - 2 then
- local col = ((i - 1) % cubesPerRow) + 1
- local xPos = (col - 1) * colWidth + 1
- if col == 1 then
- -- Starting a new row
- if i > 1 then
- currentLine = currentLine + 1
- end
- end
- monitor.setCursorPos(xPos, currentLine)
- monitor.setTextColor(colors.white)
- local cubeId = string.match(cube.name, "basicEnergyCube_(%d+)")
- local status = cube.energy > 0 and "ACTIVE" or "EMPTY"
- local statusColor = cube.energy > 0 and colors.green or colors.gray
- monitor.write("Cube " .. cubeId .. ": ")
- monitor.setTextColor(getPercentageColor(cube.energyPercentage))
- monitor.write(formatPercentage(cube.energyPercentage))
- monitor.setCursorPos(xPos + 15, currentLine)
- monitor.setTextColor(statusColor)
- monitor.write(status)
- monitor.setCursorPos(xPos + 22, currentLine)
- monitor.setTextColor(colors.white)
- monitor.write(formatEnergy(cube.energy))
- end
- end
- -- System status at bottom
- monitor.setCursorPos(1, monitorHeight)
- monitor.setTextColor(colors.green)
- monitor.write("SYSTEM ONLINE")
- monitor.setCursorPos(monitorWidth - 15, monitorHeight)
- monitor.setTextColor(colors.gray)
- monitor.write("Ch: " .. CHANNEL)
- -- Connection indicator
- monitor.setCursorPos(monitorWidth - 8, monitorHeight)
- if solarFarmData and (os.epoch("utc") - lastSolarUpdate) < 15000 then
- monitor.setTextColor(colors.green)
- monitor.write("LINKED")
- else
- monitor.setTextColor(colors.red)
- monitor.write("UNLINK")
- end
- end
- -- Main execution function
- local function main()
- print("Starting Monitor Computer...")
- initializePeripherals()
- local cubes = getEnergyCubes()
- if #cubes == 0 then
- error("No energy cubes found!")
- end
- print("Starting monitoring loop...")
- -- Start listening for solar data in parallel
- parallel.waitForAll(
- function()
- while true do
- listenForSolarData()
- end
- end,
- function()
- while true do
- local cubeData = collectAllCubeData(cubes)
- displayOnMonitor(cubeData)
- -- Display summary on terminal
- term.clear()
- term.setCursorPos(1, 1)
- print("=== MONITOR COMPUTER ===")
- print("Time: " .. os.date("%H:%M:%S"))
- print("Energy Cubes: " .. cubeData.summary.validCubes .. "/" .. cubeData.totalCubes)
- print("Total Storage: " .. formatEnergy(cubeData.summary.totalEnergy) .. " FE")
- print("Storage Fill: " .. formatPercentage(cubeData.summary.averagePercentage))
- if solarFarmData then
- local age = (os.epoch("utc") - lastSolarUpdate) / 1000
- print("Solar Data: " .. string.format("%.1fs old", age))
- print("Solar Production: " .. formatEnergy(solarFarmData.summary.totalProductionRate) .. " FE/t")
- else
- print("Solar Data: Not available")
- end
- print("Monitor Updated: " .. os.date("%H:%M:%S"))
- sleep(UPDATE_INTERVAL)
- end
- end
- )
- end
- -- Error handling wrapper
- local function runWithErrorHandling()
- local success, err = pcall(main)
- if not success then
- print("Fatal error: " .. tostring(err))
- print("Restarting in 10 seconds...")
- sleep(10)
- os.reboot()
- end
- end
- -- Start the program
- runWithErrorHandling()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement