Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --tankmon tppi fix
- -- Edited by bot190 to support CC 1.73 and OpenPeripheralCore 0.5.0
- -- Tank monitoring program edited by Morphik08
- -- Original program by Forgotten_Boy
- -- Hardware detector program by Sharidan
- -- Requires OpenPeripherals (OP). Tested with version 3.0.
- -- Supports iron & steel Railcraft tanks, Open Block tanks, Ender Tanks, AE ExtraCells tanks,
- -- TConstruct tanks, Extra Utilities Drums, Mekanism Dynamic Tanks.
- -- Also supports multiple tanks, and tanks attached with modems.
- -- If I missed any tanks, let me know. I will add it to the list.
- --[[
- Setup:
- - Place an Advanced Computer with wireless modem and with tankmon on it adjacent to a tank. Run "tankmon".
- - Setup another Advanced Computer with wireless modem and with tankmon on it adjacent to an advanced monitor and/or terminal glass bridge. Run "tankmon".
- - Your monitor should now show the contents of the tank. Add as many tanks as you like and the server will simply add them to the display.
- - The size of the monitor or locations of the modems don't matter, place them anywhere on the computer. The monitor can be resized while tankmon is running.
- Optional Setup:
- - Place an Advanced Computer with wired and wireless modems with lan cables connecting all tanks with lan modems attached to tanks and to computer. Run "tankmon".
- - Setup another Advanced Computer with wireless modem and with tankmon on it adjacent to an advanced monitor and/or terminal glass bridge. Run "tankmon".
- - Your monitor should now show the contents of the tanks. Add as many tanks as you like and the server will simply add them to the display.
- - The size of the monitor or locations of the modems don't matter, place them anywhere on the computer. The monitor can be resized while tankmon is running.
- Advanced usage:
- - On the client, you can use tankmon to trigger a redstone signal when the tank reaches a certain threshold (specified as 0 to 100, a percentage). For example:
- tankmon 100 left
- tankmon 0 top
- The first example will send redstone output on the left when the tank is full. The second example will send redstone output on the top when the tank is empty.
- --]]
- -- Variable definitions
- local valve, monitor, screenw, screenh
- local serverID = nil
- local clients = {}
- local args = {...}
- local redLimit, redside, on
- local sides = {"left", "right", "top", "bottom", "front", "back"};
- local tankTypes = {"tile.basicblock.dynamic_valve_name", "rcirontankvalvetile", "rcsteeltankvalvetile", "openblocks_tank", "drum", "ender_tank", "cofh_thermalexpansion_tank", "net_minecraft_src_buildcraft_factory_tiletank", "tileentitycertustank", "tconstruct_lavatank"};
- local scale = .5 --Scale for monitor text
- local skipEmpty = true --Skip showing empty tanks
- local count = 0 --Counter for tanks
- ----------------------------------------------------
- -- Terminal Bridge Glasses Variable definitions
- ----------------------------------------------------
- local bridge = {}
- bridge["TankText"] = {}
- bridge["TankBackground"] = {}
- bridge["TankTexture"] = {}
- -------------------------------------------------------
- -- Terminal Bridge Glasses display variable definitions
- -- Feel free to alter these to your liking
- -------------------------------------------------------
- bridge["BackgroundColor"] = 0x000000 --Background Bar color
- bridge["TextColor"] = 0x33B5E5 --Text color
- bridge["TextScale"] = 1 --Text Scale
- bridge["ExtendBackground"] = true --Extend Black background behind text
- bridge["BarWidth"] = 25 --Tank bar width
- bridge["BarHeight"] = 50 --Tank bar height
- bridge["XOffset"] = 5 --X Offset for displaying info
- bridge["YOffset"] = 50 --Y Offset for displaying info
- bridge["XSpacing"] = 5 --Space between columns
- bridge["YSpacing"] = 5 --Space between rows
- bridge["Alpha"] = 1 --Alpha value of bar background
- bridge["LinesAmt"] = 3 --Number of text lines after tank bar
- bridge["MaxCols"] = 3 --Max Number of cols to display per page
- bridge["MaxRows"] = 3 --Max Number of rows to display per page
- -------------------------------------------------------
- -- Which row to start with. This will be changed to
- -- automatically change based on user input in chat
- -- command box.
- -------------------------------------------------------
- bridge["StartRow"] = 0 --Min Row to display
- -------------------------------------------------------
- -- Altering these does nothing
- -------------------------------------------------------
- bridge["CurrentRow"] = 1 --Current Row
- bridge["CurrentCol"] = 1 --Current Col
- ----------------------------------------------------
- -- Function definitions
- ----------------------------------------------------
- local liquidNameColors = {
- {"water", colors.blue, "Water" },
- {"lava", colors.orange, "Lava" },
- {"liquidforce", colors.yellow, "Liquid Force" },
- {"turpentine", colors.brown, "Turpentine" },
- {"poison", colors.purple, "Poison" },
- {"latex", colors.white, "Latex" },
- {"ardite.molten", colors.orange, "Molten Ardite" },
- {"gold.molten", colors.yellow, "Molten Gold" },
- {"blood", colors.orange, "Blood" },
- {"copper.molten", colors.orange, "Molten Copper" },
- {"obsidian.molten", colors.gray, "Molten Obsidian" },
- {"bop.honey", colors.yellow, "Honey" },
- {"sap", colors.brown, "Sap" },
- {"liquidnitrogen", colors.cyan, "Liquid Nitrogen" },
- {"iron.molten", colors.gray, "Molten Iron" },
- {"bop.liquidpoison", colors.purple, "Liquid Poison" },
- {"alumite.molten", colors.orange, "Molten Ardite" },
- {"cobalt.molten", colors.cyan, "Molten Cobalt" },
- {"bop.springwater", colors.blue, "Spring Water" },
- {"glowstone", colors.yellow, "Energized Glowstone" },
- {"resin", colors.brown, "Resin" },
- {"emerald.liquid", colors.lime, "Liquified Emerald" },
- {"pinkslime", colors.pink, "Pink Slime" },
- {"redstone", colors.red, "Redstone" },
- {"xpjuice", colors.lime, "Liquid XP" },
- {"oil", colors.gray, "Oil" },
- {"aluminum.molten", colors.lightGray, "Molten Aluminum" },
- {"manyullyn.molten", colors.purple, "Molten Manyullyn" },
- {"stone.seared", colors.gray, "Seared Stone" },
- {"creosote", colors.green, "Creosote Oil" },
- {"sludge", colors.brown, "Sludge" },
- {"bioethanol", colors.lime, "Ethanol" },
- {"acid", colors.lime, "Acid" },
- {"biomass", colors.lime, "Biomass" },
- {"immibis.liquidxp", colors.lime, "Liquid XP" },
- {"electrum.molten", colors.yellow, "Molten Electrum" },
- {"sewage", colors.brown, "Sewage" },
- {"slime.blue", colors.cyan, "Liquid Blueslime" },
- {"tin.molten", colors.lightGray, "Molten Tin" },
- {"aluminumbrass.molten", colors.orange, "Molten Aluminum Brass" },
- {"milk", colors.white, "Milk" },
- {"fuel", colors.lime, "Fuel" },
- {"biofuel", colors.green, "Biofuel" },
- {"chocolatemilk", colors.brown, "Chocolate Milk" },
- {"glass.molten", colors.lightGray, "Molten Glass" },
- {"cryotheum", colors.cyan, "Gelid Cryotheum" },
- {"pyrotheum", colors.orange, "Blazing Pyrotheum" },
- {"pinkslime", colors.pink, "Pink Slime" },
- {"platinum.molten", colors.cyan, "Molten Platinum" },
- {"coal", colors.gray, "Liquifacted Coal" },
- {"lead.molten", colors.gray, "Molten Lead" },
- {"mushroomsoup", colors.brown, "Mushroom Soup" },
- {"silver.molten", colors.lightGray, "Molten Silver" },
- {"nickel.molten", colors.cyan, "Molten Nickel" },
- {"ender", colors.green, "Resonant Ender" },
- {"invar.molten", colors.lightGray, "Molten Invar" },
- {"glue", colors.white, "Glue" },
- {"meat", colors.pink, "Meat" },
- {"steel.molten", colors.gray, "Molten Steel" },
- {"bronze.molten", colors.brown, "Molten Bronze" }
- }
- function cls()
- term.clear()
- term.setCursorPos(1,1)
- term.setCursorBlink(false)
- end
- function clm()
- if monitor then
- monitor.setBackgroundColor(colors.black)
- monitor.setTextScale(scale)
- monitor.clear()
- monitor.setCursorPos(1,1)
- monitor.setCursorBlink(false)
- end
- end
- function clb()
- if bridge["peripheral"] then
- bridge["peripheral"].clear()
- end
- end
- function table.merge(tbl1, tbl2)
- for k,v in ipairs(tbl2) do
- table.insert(tbl1, v)
- end
- return tbl1
- end
- function split(str, wordNum)
- local splitString = {}
- for tmp in str:gmatch("%w+") do
- table.insert(splitString, tmp)
- end
- return splitString[wordNum] or ""
- end
- local function getLiquidColor(liquid)
- for c, color in pairs (liquidNameColors) do
- if (liquid == color[1]) or (liquid == color[3]) then
- return color[2]
- end
- end
- return colors.white;
- end
- local function getDeviceSide(deviceType)
- for i,side in pairs(sides) do
- if (peripheral.isPresent(side)) then
- if (peripheral.getType(side)) == string.lower(deviceType) then
- return side;
- end
- end
- end
- end
- function hardwareDetector(...)
- local self = {}
- -- Initialize internal hardware list
- self._devList = {}
- -- Internal worker function
- -- Checks a boolean value and returns the
- -- corresponding supplied value
- local function iif(bool, resultTrue, resultFalse)
- if (bool) then
- return resultTrue;
- else
- return resultFalse;
- end
- end
- local function split(str, pat)
- local t = {}
- local fpat = "(.-)" .. pat
- local last_end = 1
- local s, e, cap = str:find(fpat, 1)
- while s do
- if s ~= 1 or cap ~= "" then
- table.insert(t,cap)
- end
- last_end = e+1
- s, e, cap = str:find(fpat, last_end)
- end -- while
- if last_end <= #str then
- cap = str:sub(last_end)
- table.insert(t, cap)
- end
- return t
- end
- local function splitType(str)
- local typ, adv = str, nil
- local r = split(str, ":")
- if (#r == 2) then
- typ = r[1]
- adv = r[2]
- end
- return typ, adv;
- end
- local function wrapID(value)
- if (value == nil) then
- return "offline"
- else
- return tostring(value)
- end
- end
- local function addDevice(label, devType, remote)
- local lcdt = string.lower(devType)
- local adv = "n/a";
- local pCall = function() end;
- if (remote) then
- pCall = function(label, method)
- return remote.callRemote(label, method)
- end;
- else
- pCall = function(label, method)
- return peripheral.call(label, method)
- end;
- end
- if (lcdt == "modem") then
- adv = iif(pCall(label, "isWireless"), "wireless", "cable")
- elseif (lcdt == "monitor") then
- adv = iif(pCall(label, "isColor"), "advanced", "normal")
- elseif (lcdt == "computer" or lcdt == "turtle") then
- adv = tostring(wrapID(pCall(label, "getID")))
- elseif (lcdt == "drive") then
- if (disk.isPresent(label)) then
- if (disk.hasData(label)) then
- adv = "floppy";
- elseif (disk.hasAudio(label)) then
- adv = "music";
- else
- adv = "unknown";
- end
- else
- adv = "empty"
- end
- end
- table.insert(self._devList, {label, devType, adv});
- if (lcdt == "modem" and string.lower(adv) == "cable") then
- return true;
- end
- end
- -- Detects all connected peripherals
- function self.detect()
- self._devList = {};
- local sides = rs.getSides();
- local remoteSide = {};
- for i, side in pairs(sides) do
- local devType = peripheral.getType(side);
- if (devType) then
- if (addDevice(side, devType)) then
- table.insert(remoteSide, side);
- end
- end -- if
- end -- for-do
- if (#remoteSide > 0) then
- -- There was a cable modem attached, so we need to loop through all remote peripherals too
- for r = 1, #remoteSide do
- local rp = peripheral.wrap(remoteSide[r]);
- local lst = rp.getNamesRemote()
- for r = 1, #lst do
- local name = lst[r]
- local devType = rp.getTypeRemote(name);
- if (devType) then
- addDevice(name, devType, rp);
- end
- end
- end -- for r
- end
- end
- -- Returns a tuple of the first matching peripheral
- function self.find(...)
- local args={...}
- if (#args > 0) then
- local idx = 0;
- for i, sideType in pairs(self._devList) do
- for a = 1, #args do
- local findType = args[a];
- if (type(findType) == "string") then
- local typ, adv = splitType(findType);
- if (string.lower(typ) == string.lower(self._devList[i][2])) then
- if (adv) then
- if (string.lower(adv) == string.lower(self._devList[i][3])) then
- -- We found a device of this type
- idx = i;
- end
- else
- -- We found a device of this type
- idx = i;
- end
- if (idx > 0) then
- return tostring(self._devList[idx][1]), tostring(self._devList[idx][2]), tostring(self._devList[idx][3])
- end
- end
- end
- end
- end
- return nil;
- else
- error("No device type specified.", 0)
- end
- end
- -- Returns a complete list of peripherals
- function self.getAll()
- return self._devList;
- end
- -- Returns a list of all matching peripherals
- function self.getList(...)
- local args={...}
- local results = {}
- if (#args > 0) then
- for i, sideType in pairs(self._devList) do
- for a = 1, #args do
- local findType = args[a];
- if (type(findType) == "string") then
- if (string.lower(findType) == string.lower(self._devList[i][2])) then
- -- We found a device of this type
- table.insert(results, {tostring(self._devList[i][1]), tostring(self._devList[i][2]), tostring(self._devList[i][3])})
- end
- elseif (type(findType) == "table") then
- for i2, entry in pairs(findType) do
- if (type(entry) == "string") then
- if (string.lower(entry) == string.lower(self._devList[i][2])) then
- -- We found a device of this type
- table.insert(results, {tostring(self._devList[i][1]), tostring(self._devList[i][2]), tostring(self._devList[i][3])})
- end
- end
- end
- end
- end
- end
- return results;
- else
- error("No device type specified.", 0);
- end
- end
- -- Determines if the device is remote or not
- function self.isRemote(dev)
- if (type(dev) == "string") then
- local sides = rs.getSides();
- for i, s in pairs(sides) do
- if (string.lower(dev) == string.lower(s)) then
- return nil;
- end
- end
- return true;
- else
- error("Device connect string expected.", 0);
- end
- end
- -- Internal calls, don't mess with these
- self.detect()
- local args = {...};
- if (#args > 0) then
- return self.find(...);
- else
- -- If no parameters were passed,
- -- return the hardware object
- return self;
- end
- end
- local function showLevel(count,total,filled,color,label,rawLabel, amt, threshold, signal)
- if (monitor) then
- local screenw, screenh = monitor.getSize()
- --total = total + 1
- if (not screenw) then
- return nil;
- -- monitor has been broken
- end
- local starty = screenh - math.floor((screenh * filled))
- local width = math.ceil(screenw / total)
- local offset = math.ceil((screenw / total) * (count-1))
- local amtw = string.len(amt)
- local thresholdy = (threshold and ( screenh - ((threshold / 100) * screenh)))
- if (count == total) then
- -- the final column should use up the remaining space. A hack!
- width = screenw - offset
- end
- if (thresholdy and thresholdy < 1) then
- thresholdy = 1
- else
- if (thresholdy and thresholdy > screenh) then
- thresholdy = screenh
- end
- end
- restoreTo = term.current()
- term.redirect(monitor)
- for c=starty, screenh + 1, 1 do
- for line=0, width, 1 do
- paintutils.drawPixel(line + offset, c, color)
- end
- end
- if (thresholdy) then
- local thresholdColor = color
- for line=0, width, 1 do
- thresholdColor = color
- if (signal) then
- thresholdColor = colors.red
- else
- -- makes a dotted line when there is no redstone signal
- if (line % 2 == 0) then
- thresholdColor = colors.red
- else
- thresholdColor = color
- end
- end
- paintutils.drawPixel(line + offset, thresholdy, thresholdColor)
- end
- end
- --truncate the label to the width of the bar.
- monLabel = string.sub(rawLabel, 1, math.max((width - 1), 0))
- monitor.setBackgroundColor(color)
- if (color == colors.white) then
- monitor.setTextColor(colors.black)
- end
- labely = math.min((starty + 1), screenh - 1)
- monitor.setCursorPos(offset + 1, labely)
- monitor.setTextScale(scale)
- write(monLabel)
- if (amtw <= width) then
- amty = math.min(labely + 1, screenh)
- monitor.setCursorPos(offset + 1, amty)
- write(amt)
- end
- monitor.setTextColor(colors.white)
- term.redirect(restoreTo)
- end
- if (bridge["peripheral"]) then
- --Maximum length string can be
- local cutoffPoint = math.ceil(bridge["BarWidth"] / (8*bridge["TextScale"]))
- bridge["CurrentRow"] = math.floor((count+bridge["MaxCols"]-1)/bridge["MaxCols"])
- bridge["CurrentCol"] = ((count+bridge["MaxCols"]-1) - bridge["CurrentRow"]*bridge["MaxCols"]) + 1
- if (bridge["CurrentRow"] > bridge["StartRow"]) and (bridge["CurrentRow"] <= (bridge["StartRow"] + bridge["MaxRows"])) then
- --Heigth including extra lines below tank display
- local fullHeight = bridge["BarHeight"]+((8*bridge["TextScale"])*(bridge["LinesAmt"]))
- --X and Y coords for tank displays
- local x = bridge["XOffset"] + ((bridge["BarWidth"] + bridge["XSpacing"]) * (bridge["CurrentCol"]-1))
- local y = bridge["YOffset"] + ((fullHeight+bridge["YSpacing"])*(bridge["CurrentRow"]-bridge["StartRow"]-1))
- --Draw tank background using liquid texture
- if bridge["ExtendBackground"] then
- bridge["TankBackground"][count] = bridge["peripheral"].addBox(x,y,bridge["BarWidth"],fullHeight,bridge["BackgroundColor"],bridge["Alpha"])
- else
- bridge["TankBackground"][count] = bridge["peripheral"].addBox(x,y,bridge["BarWidth"],bridge["BarHeight"],bridge["BackgroundColor"],bridge["Alpha"])
- end
- bridge["TankTexture"][count] = bridge["peripheral"].addLiquid(x+1,y+1+math.ceil(bridge["BarHeight"]-(bridge["BarHeight"] * filled)),bridge["BarWidth"]-2,(bridge["BarHeight"] * filled)-2,label)
- --Display info to bridge
- bridge["TankText"][count] = bridge["TankText"][count] or {}
- for i=0,(bridge["LinesAmt"]-1) do
- bridge["TankText"][count][i] = bridge["peripheral"].addText((x+2), (bridge["BarHeight"]+y+((8*bridge["TextScale"])*i)),"",bridge["TextColor"])
- bridge["TankText"][count][i].setScale(scale)
- end
- bridge["TankText"][count][0].setText(string.sub(split(rawLabel,1), 1, cutoffPoint))
- bridge["TankText"][count][1].setText(string.sub(split(rawLabel,2), 1, cutoffPoint))
- bridge["TankText"][count][2].setText(string.sub(tostring(math.floor(filled*100)).."%", 1, cutoffPoint))
- end
- end
- end
- local function tankStats(tank)
- if(tank) then
- local name = tank["contents"]["name"] or nil
- local rawName = tank["contents"]["rawName"] or nil
- local amt = tank["contents"]["amount"]
- local size = tank["capacity"]
- local filled = (amt and 1 / (size / amt)) or 0
- local threshold = tank["contents"]["redLimit"] or -1
- local signalOn = tank["contents"]["on"] or false
- return name, rawName, amt, size, filled, threshold, signalOn
- else
- return nil;
- end
- end
- local function tableCount(t)
- local total=0
- for k,v in pairs (t) do
- total = total + 1
- end
- return total
- end
- function printTable(tt, indent)
- print(tableToString(tt, indent))
- end
- function tableToString (tt, indent, done)
- done = done or {}
- indent = indent or 0
- if type(tt) == "table" then
- local sb = {}
- for key, value in pairs (tt) do
- table.insert(sb, string.rep (" ", indent)) -- indent it
- if type (value) == "table" and not done [value] then
- done [value] = true
- table.insert(sb, "{\n");
- table.insert(sb, tableToString (value, indent + 2, done))
- table.insert(sb, string.rep (" ", indent)) -- indent it
- table.insert(sb, "}\n");
- elseif "number" == type(key) then
- table.insert(sb, string.format("\"%s\"\n", tostring(value)))
- else
- table.insert(sb, string.format("%s = \"%s\"\n", tostring (key), tostring(value)))
- end
- end
- return table.concat(sb)
- else
- return tt .. "\n"
- end
- end
- function table.contains(tbl, element)
- for _, value in pairs(tbl) do
- if value == element then
- return true
- end
- end
- return false
- end
- local function findTank(tbl)
- if type(tbl) == "table" then
- for index,value in pairs(tbl) do
- if type(value) == "table" then
- if value["capacity"] then
- return tbl
- else
- return findTank(value)
- end
- end
- end
- else
- return nil
- end
- end
- local function findTanks(tbl)
- local tblTemp = {}
- if type(tbl) == "table" then
- for index,value in pairs(tbl) do
- if type(value) == "table" then
- if value["capacity"] then
- table.insert(tblTemp, value)
- else
- table.insert(tblTemp, findTank(value))
- end
- end
- end
- end
- return tblTemp
- end
- local function updateDisplay()
- --printTable(findTanks(clients))
- --end
- --local function tmp()
- local count = 1
- local lstTanks = {}
- local total = 0
- clm()
- clb()
- if tableCount(clients) > 0 then
- local i = 1
- for ix,client in pairs (clients) do
- local tanks = findTanks(client)
- table.merge(lstTanks, tanks)
- if (i <= 15) then
- term.setCursorPos(1,6+i)
- term.clearLine()
- print("Client "..i.." # of Tanks: "..tostring(#tanks))
- end
- i = i + 1
- end
- total = #lstTanks
- term.setCursorPos(1,6)
- term.clearLine()
- print("Total # of Tanks: "..tostring(total))
- for _,tankInfo in pairs (lstTanks) do
- local name, rawName, amt, size, filled, threshold, signalOn = tankStats(tankInfo)
- local color = getLiquidColor(rawName)
- local unit = ""
- local amount = math.max(amt or 0, 0)
- --print("Name: "..tostring(name))
- --print("Raw Name: "..tostring(rawName))
- --print("color: "..tostring(color))
- --print("amt: "..tostring(amt))
- --print("size: "..tostring(size))
- --print("filled: "..tostring(filled))
- if not (name) and (skipEmpty) then total = total - 1 end
- if name or (not (name) and not (skipEmpty)) then
- if (amount > 1000000) then
- unit="M"
- amount=string.format("%.2f", math.floor(amt / 1000) / 1000)
- --unit="K Buckets"
- --amount=string.format("%i", math.floor(amt / 1000) / 1000)
- else
- if(amount > 0) then
- unit="K"
- amount=string.format("%.2f", amt / 1000)
- --unit=" Buckets"
- --amount=string.format("%i", amt / 1000)
- else
- amount = ""
- end
- end
- amount = amount..unit
- showLevel(count, total, filled, color, name or "Empty", rawName or "Empty", amount, threshold, signalOn)
- count = count + 1
- --end
- end
- end
- end
- return nil;
- end
- local function broadcast ()
- cls()
- print("_____________ tankmon Server started __________")
- print("Broadcasting that tank display is available...")
- print("Hold Ctrl+T to Terminate.")
- while true do
- rednet.broadcast(os.getComputerID())
- term.setCursorPos(1, 5)
- term.clearLine()
- write("Connected tankmon clients: " .. tableCount(clients))
- sleep(7)
- end
- end
- local function receive()
- while true do
- local senderID, message, distance = rednet.receive()
- if (message) then
- local data = textutils.unserialize(message)
- clients[senderID] = data
- end
- end
- end
- local function display()
- while true do
- updateDisplay()
- sleep(1.5)
- end
- end
- local function connect()
- cls()
- print("Looking for a tankmon server in range...")
- while true do
- local senderID, message, distance = rednet.receive()
- serverID = senderID
- print()
- print("Connected to server " ..tostring(serverID)..".")
- sleep(3)
- end
- end
- local function publishTank()
- while true do
- if (serverID) then
- local hw = hardwareDetector()
- lstTanks = hw.getList(tankTypes)
- if (type(lstTanks) == "table") then
- if (#lstTanks > 0) then
- local info = {}
- for i, tank in pairs(lstTanks) do
- if not tank[1]["capacity"] then
- lstTanks[i][1] = peripheral.wrap(lstTanks[i][1]).getTankInfo("unknown")[1]
- end
- end
- cls()
- print("** Sending out tank information **")
- print("Number of tanks: "..#lstTanks)
- for i, tank in pairs(lstTanks) do
- if tank[1]["contents"] then
- -- establish whether redstone signal should be sent
- local name, rawName, amt, size, filled, threshold, signalOn = tankStats(tank[1])
- on = false
- pctFilled = filled * 100
- if (filled and redLimit and redLimit==0 and filled==0) then
- on = true
- else
- if(filled and redLimit and filled <= redLimit) then
- on=true
- end
- end
- if(redside) then
- rs.setOutput(redside, on)
- end
- -- use rednet to update the server with this tank's info.
- tank[1]["redLimit"] = redLimit
- tank[1]["on"] = on
- table.insert(info, tank[1])
- if (redLimit and redside) then
- print("Redstone signal on: " .. tostring(on))
- end
- if (i <= 12) then
- term.setCursorPos(1,3 + i)
- term.clearLine()
- if tank[1]["contents"]["amount"] then
- write("** Tank "..i.." contains: " .. tostring(tank[1]["contents"]["amount"]).."mB of "..tostring(tank[1]["name"]))
- else
- write("** Tank "..i.." is empty.")
- end
- end
- end
- end
- if (redLimit and redside) then
- print("Redstone threshold: " .. tostring(redLimit))
- print("Redstone output side: " .. tostring(redside))
- end
- rednet.send(serverID, textutils.serialize(info), false)
- end
- end
- end
- sleep(math.random(1,5))
- end
- end
- -------------------------------------------------------
- -- Hardware setup and detection
- -------------------------------------------------------
- local hw = hardwareDetector()
- local screenSide, _, _ = hw.find("monitor:advanced");
- local bridgeSide, _, _ = hw.find("openperipheral_glassesbridge");
- local modemSide, _, _ = hardwareDetector("modem:wireless")
- lstTanks = hw.getList(tankTypes)
- if (modemSide) then
- local modem = peripheral.wrap(modemSide)
- else
- error("A wireless modem must be attached to this computer.")
- end
- if (#lstTanks > 0) and (bridgeSide or screenSide) then
- error("Either a screen or a tank valve can be connected, not both.")
- end
- if (screenSide) then
- monitor = peripheral.wrap(screenSide)
- if(not monitor.isColor()) then
- error("The attached monitor must be Advanced. Get some gold!")
- end
- screenw, screenh = monitor.getSize()
- clm()
- end
- if (bridgeSide) then
- bridge["peripheral"] = peripheral.wrap(bridgeSide)
- clb()
- end
- ---------------------------------------
- --the Main
- ---------------------------------------
- rednet.open(modemSide)
- if (#lstTanks > 0) then
- -- client mode
- redLimit = args[1]
- redside = args[2]
- if (redLimit and not redside) then
- print("A threshold and redstone side must both be present.")
- print("e.g. tankmon 100 top")
- error()
- end
- if (redLimit) then
- redLimit = tonumber(redLimit)
- print("")
- print("Tank will send redstone signal at or below " .. tostring(redLimit) .. "% on side " .. redside)
- end
- -- clear outstanding redstone signals.
- for i,side in pairs(sides) do
- rs.setOutput(side, false)
- end
- parallel.waitForAll(connect, publishTank)
- else
- -- server mode
- parallel.waitForAll(broadcast, receive, display)
- end
- rednet.close(modemSide)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement