Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[ Tank Monitor 2 ]]--
- --[[ by Dog ]]--
- --[[ aka HydrantHunter ]]--
- --[[ based on an AaP ]]--
- --[[ thread started by ]]--
- --[[ Zatilla7 ]]--
- --[[ pastebin iuKauV9d ]]--
- --[[
- - Requires:
- - Computer (standard or advanced)
- - 3-wide advanced monitor array (2 tall or better recommended)
- - Tanks to monitor
- - Tanks and monitor array can be connected directly or via modem/network cable
- - MC 1.6.4 or 1.7.10 ... maybe 1.8.9 and beyond (not tested)
- - ComputerCraft 1.58 (untested) -> 1.63+
- ]]--
- --# predeclarations
- local tArgs = { ... } --# declare, localize, and capture any command line arguments with this variable
- local mon --# declare and localize our monitor wrapping variable
- local tankList = { } --# declare, localize, and set our tank list wrapping variable with an empty table
- local validTanks = { --# declare ,localize, and set the table of tanks we are looking for
- ender_tank = true, --# Ender tank
- drum = true, --# Extra Utilities drum - untested
- tileentitycertustank = true, --# Extra Cells certus tank - untested
- tconstruct_lavatank = true, --# Tinkerer's Construct lava tank - untested
- openblocks_tank = true, --# OpenBlocks tank
- factory2_1 = true, --# Forestry Raintank
- water_tank = true, --# Railcraft water tank
- rcirontankvalvetile = true, --# Railcraft iron tank valve
- rcsteeltankvalvetile = true, --# Railcraft steel tank valve
- rcboilertanklowtile = true, --# Railcraft low pressure boiler tank - untested
- rcboilertankhightile = true, --# Railcraft high pressure boiler tank - untested
- cofh_thermalexpansion_tank = true, --# Thermal Expansion portable tank
- net_minecraft_src_buildcraft_factory_tiletank = true, --# Buildcraft tank
- }
- --# look for monitors and tanks (both directly connected and connected via network cable)
- for _, side in pairs(rs.getSides()) do --# this generic loop calls redstone.getSides() to look at each side of the computer
- if peripheral.isPresent(side) then --# if we find a perhiperal...
- if validTanks[peripheral.getType(side)] then --# we check it against the list of tanks and if we find one...
- tankList[#tankList + 1] = peripheral.wrap(side) --# ...we wrap it while simultaneously incrementing our tankList index number
- elseif peripheral.getType(side) == "monitor" then --# if we find a monitor...
- mon = peripheral.wrap(side) --# ...we wrap it
- elseif peripheral.getType(side) == "modem" then --# if we find a modem, we...
- if not peripheral.call(side,"isWireless") then --# ...eliminate wireless modems and...
- for _, device in pairs(peripheral.call(side, "getNamesRemote")) do --# ...look for network attached peripherals using another generic loop
- for tank in pairs(validTanks) do --# we start yet another generic loop that allows us to compare a :sub of our validTanks against the discovered peripheral
- if validTanks[device:sub(1, #tostring(tank))] then --# we check the peripheral against the list of tanks and if we find one...
- tankList[#tankList + 1] = peripheral.wrap(device) --# ...we wrap it while simultaneously incrementing our tankList index number then...
- break --# ...break out of this loop to continue the 'outter loop'
- end
- end
- if peripheral.getType(device) == "monitor" then --# if we find a monitor...
- mon = peripheral.wrap(device) --# ...we wrap it
- end
- end
- end
- end
- end
- end
- term.clear() --# clear the terminal screen...
- term.setCursorPos(2, 2) --# ...and set the cursor position for any terminal output
- --# exit if no tanks are found
- if not tankList[1] then
- term.write("No known tanks found.")
- term.setCursorPos(2, 4)
- term.write("Tank Monitor is OFFLINE")
- term.setCursorPos(2, 6)
- end
- --# prepare display (and exit if no monitor is found)
- if not mon then --# if we don't find a monitor...
- term.write("No monitor found.") --# ...inform the user then...
- term.setCursorPos(2, 3)
- term.write("A monitor is required.")
- term.setCursorPos(2, 5)
- term.write("Tank Monitor is OFFLINE")
- term.setCursorPos(1, 7) --# ...set cursor position for post-exit and...
- return --# ...quit and exit the program
- end
- mon.setTextScale(1) --# valid text scales are 0.5 to 5 in increments of 0.5
- mon.clear() --# clear the monitor
- local monX, monY = mon.getSize() --# delcare, localize, and set our variables to store monitor width and height
- --# Color Definitions
- local white = colors.white --# declare, localize, and set variables for the colors we'll use
- local black = colors.black --# (so they're easier to type and redefine for b&w)
- local silver = colors.lightGray
- local orange = colors.orange
- local yellow = colors.yellow
- local red = colors.red
- local green = colors.green
- local sky = colors.lightBlue
- if not mon.isColor() then --# if the monitor is not color...
- silver = colors.white --# ...we set all our not-black colors to white
- orange = colors.white
- yellow = colors.white
- red = colors.white
- green = colors.white
- sky = colors.white
- end
- --# declare and localize function to gather and display tank info
- local function monitorTanks()
- while true do
- local yPos = 0 --# declare, localize, and set cursor Y position variable to 0
- for tankNum = 1, #tankList do --# start parsing our list of tanks (1, 2, 3, ...)
- local tankInfo = tankList[tankNum].getTankInfo("unknown") --# get tank's info
- local tankStats = tankInfo[1] --# take just the table of info we want from the info returned by the tank
- yPos = yPos + 1 --# increment cursor Y position variable
- mon.setCursorPos(1, yPos) --# set the cursor position
- mon.setTextColor(silver) --# set the color for tank #
- mon.write("Tank " .. tostring(tankNum) .. ": ") --# display the tank number (1, 2, 3, ...)
- mon.setTextColor(white) --# set the color for tank contents rawName or EMPTY
- if tankStats.rawName or tankStats.contents.rawName then --# if we have actual tank data (the tank isn't empty) then ...
- mon.write((tankStats.rawName and tankStats.rawName or tankStats.contents.rawName) .. string.rep(" ", monX)) --# ...display rawName of tank contents (this is the 'descriptive' name)
- yPos = yPos + 1 --# increment cursor Y position variable
- mon.setCursorPos(1, yPos) --# set the cursor position
- local tankPercent = ((tankStats.amount and tankStats.amount or tankStats.contents.amount) / tankStats.capacity) * 100 --# declare, localize, and set the variable to hold the tank's fill percentage
- if tankPercent < 10 then --# if our tank is less than 10% full...
- tankPercent = tonumber(tostring(tankPercent):sub(1, 4)) --# ...we take the first 4 digits
- else --# ...otherwise...
- tankPercent = tonumber(tostring(tankPercent):sub(1, 5)) --# ...we take the first 5 digits
- end
- if tankPercent > 74 then --# if the tank is more than 74% full...
- mon.setTextColor(green) --# ...set the color to green
- elseif tankPercent > 49 and tankPercent < 75 then --# if the tank is between 50%-74% full...
- mon.setTextColor(sky) --# ...set the color to light blue
- elseif tankPercent > 24 and tankPercent < 50 then --# if the tank is between 25%-49% full...
- mon.setTextColor(yellow) --# ...set the color to yellow
- elseif tankPercent < 25 then --# if the tank is less than 25% full...
- mon.setTextColor(orange) --# ...set the color to orange
- end
- mon.write((tankStats.amount and tankStats.amount or tankStats.contents.amount) .. " of " .. tankStats.capacity .. " (" .. tankPercent .. "%)" .. string.rep(" ", monX)) --# display stored amount and total capacity
- else --# if the tank has no contents...
- mon.write("EMPTY") --# ...display 'EMPTY'
- yPos = yPos + 1 --# increment cursor Y position variable
- mon.setCursorPos(1, yPos) --# set the cursor position
- mon.setTextColor(red) --# set the color for an empty tank
- mon.write("0 of " .. tankStats.capacity .. " (0%)" .. string.rep(monX)) --# display empty amount and total capacity
- end
- yPos = yPos + 1 --# increment cursor Y position variable
- end
- sleep(1) --# sleep for 1 second before refreshing the tank info
- end
- end
- --# declare and localize function to capture character input
- local function keyPress()
- while true do --# start an infinite loop
- local _, char = os.pullEvent("char") --# declare, localize, and capture the data returned from a "char" event
- if string.lower(char) == "q" then --# if 'q' is pressed then...
- return --# ...exit this loop, which will result in the program quitting and exiting
- end
- end
- end
- --# declare and localize function to run another program or the CC shell in tandem
- local function foregroundShell()
- local tUnpack = unpack or table.unpack --# determine which table unpack routine is available to use
- term.clear()
- term.setCursorPos(1, 1)
- if fs.exists(tArgs[1]) then --# if the file specified by tArgs[1] exists...
- shell.run(tUnpack(tArgs)) --# ...run it...
- else --# ...otherwise...
- shell.run("shell") --# ...run the standard shell
- end
- end
- --# start the program
- if tArgs[1] then --# if we are set to run in the background (by command line argument)...
- parallel.waitForAny(monitorTanks, foregroundShell) --# ...use the parallel api to wait for activity from either function (monitorTanks() or foregroundShell())
- else --# otherwise...
- term.write("Monitoring tanks...") --# ...display something on the terminal so the user knows the program is running then...
- term.setCursorPos(2, 4)
- term.write("press 'q' to quit")
- parallel.waitForAny(monitorTanks, keyPress) --# ...use the parallel api to wait for activity from either function (monitorTanks() or keyPress())
- end
- --# do this if the program gracefully exits from a running state
- mon.clear() --# if the shell or program is exited, clear the monitor...
- term.clear() --# ...clear the screen...
- term.setCursorPos(1, 1)
- term.write("Tank Monitor is OFFLINE") --# ...inform the user and...
- term.setCursorPos(1, 3) --# ...set the cursor position for post-exit
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement