Skip to content

Instantly share code, notes, and snippets.

@bot190
Last active August 29, 2015 14:17
Show Gist options
  • Save bot190/4583b9a8eb906b9fb80d to your computer and use it in GitHub Desktop.
Save bot190/4583b9a8eb906b9fb80d to your computer and use it in GitHub Desktop.
Updating tankmon to work with CC 1.73, Openperipherals 0.5.0
--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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment