Advertisement
Guest User

Untitled

a guest
May 22nd, 2015
205
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- Variable definitions
  2. local valve, monitor, screenw, screenh
  3. local serverID = nil
  4. local clients = {}
  5. local args = {...}
  6. local redlimit, redside, on
  7. local sides = {"left", "right", "top", "bottom", "front", "back"};
  8.  
  9. ----------------------------------------------------
  10. -- Function definitions
  11. ----------------------------------------------------
  12. local liquidColors = {{"Water", colors.blue },
  13.                         {"tile.oilStill", colors.gray, "Oil"},
  14.                         {"Creosote Oil", colors.brown},
  15.                         {"Essence", colors.lime},
  16.                         {"Steam", colors.lightGray},
  17.                         {"Honey", colors.yellow},
  18.                         {"Ethanol", colors.orange},
  19.                         {"Lava", colors.orange},
  20.                         {"item.fuel", colors.yellow, "Fuel"},
  21.                         {"Biomass", colors.green},
  22.                         {"Fortron", colors.lightBlue},
  23.                         {"Sludge", colors.black},
  24.                         {"Liquid DNA", colors.magenta},
  25.                         {"Fruit Juice", colors.green},
  26.                         {"Seed Oil", colors.yellow},
  27.                         {"Liquid Force", colors.yellow},
  28.                         {"Oil", colors.black, "Oil"},
  29.                         {"Fuel", colors.yellow, "Fuel"},
  30.                         {"uumatter", colors.purple, "UUMatter"},
  31.                         {"vegetable", colors.magenta, "Veg"},
  32.                         {"deuterium", colors.lightBlue, "Deuterium"},
  33. --liquid names for OpenPeripherals 0.2.1 by AmigaLink
  34.                         {"creosote", colors.brown, "Creosote Oil"},
  35.                         {"essence", colors.lime, "Essence"},
  36.                         {"steam", colors.lightGray, "Steam"},
  37.                         {"honey", colors.yellow, "Honey"},
  38.                         {"bioethanol", colors.orange, "Ethanol"},
  39.                         {"lava", colors.orange, "Lava"},
  40.                         {"biomass", colors.green, "Biomass"},
  41.                         {"fortron", colors.lightBlue, "Fortron"},
  42.                         {"sludge", colors.black, "Sludge"},
  43.                         {"liquiddna", colors.magenta, "Liquid DNA"},
  44.                         {"fruitjuice", colors.green, "Fruit Juice"},
  45.                         {"seedoil", colors.yellow, "Seed Oil"},
  46.                         {"xpjuice", colors.lime, "XP Juice"},
  47.                         {"liquidforce", colors.yellow, "Liquid Force"},
  48.                         {"oil", colors.gray, "Oil"},
  49.                         {"fuel", colors.yellow, "Fuel"},
  50.                         {"milk", colors.white, "Milk"},
  51. -- Life Essence suggested by Fyrhtu
  52.                         {"life essence", colors.red, "Life Essence"},
  53. -- My liquids
  54.                         {"nitrofuel", colors.green, "Nitrofuel"}
  55.                     }
  56.  
  57. local function getLiquidColor(liquid)
  58.     for c, color in pairs (liquidColors) do
  59.         if (liquid == color[1]) then
  60.             return color[2],color[3] or liquid
  61.         end
  62.     end
  63.     return colors.white, liquid;
  64. end
  65.  
  66. local function getDeviceSide(deviceType)
  67.     for i, side in pairs(sides) do
  68.         if (peripheral.isPresent(side)) then
  69.             if (peripheral.getType(side)) == string.lower(deviceType) then
  70.                 return side;
  71.             end
  72.         end
  73.     end
  74. end
  75.  
  76. local function showLevel(count, max, filled, color, label, amt, threshold, signal)
  77.     local screenw, screenh = monitor.getSize()
  78.     screenw = screenw / 2
  79.     screenh = screenh / 2
  80.     max = max + 1
  81.     if (not screenw) then
  82.         return nil;
  83.         -- monitor has been broken
  84.     end
  85.        
  86.     local starty = screenh -  math.floor((screenh * filled))
  87.     local width  = math.ceil(screenw / max + .5)
  88.     local offset = math.ceil(width * (count - 1))
  89.     local amtw = string.len(amt)
  90.     local thresholdy = (threshold and ( screenh - ((threshold / 100) * screenh)))
  91.  
  92.     if (count == max) then
  93.     --  the final column should use up the remaining space.  A hack!
  94.         width = screenw - offset
  95.     end
  96.     --truncate the label to the width of the bar.
  97.     label = string.sub(label, 1, math.max((width - 1), 0))
  98.  
  99.     if (thresholdy and thresholdy < 1) then
  100.         thresholdy = 1
  101.     else
  102.         if (thresholdy and thresholdy > screenh) then
  103.             thresholdy = screenh
  104.         end
  105.     end
  106.  
  107.     term.redirect(monitor)
  108.     for c=starty, screenh + 1, 1 do
  109.         for line=0, width, 1 do
  110.             paintutils.drawPixel(line + offset, c, color)
  111.         end
  112.     end
  113.     if (thresholdy) then
  114.         local thresholdColor = color
  115.         for line=0, width, 1 do
  116.             thresholdColor = color
  117.             if (signal) then
  118.                 thresholdColor = colors.red
  119.             else
  120.                 -- makes a dotted line when there is no redstone signal
  121.                 if (line % 2 == 0) then
  122.                     thresholdColor = colors.red
  123.                 end
  124.             end
  125.             paintutils.drawPixel(line + offset, thresholdy, thresholdColor)
  126.         end
  127.     end
  128.  
  129.     monitor.setBackgroundColor(color)
  130.     if (color == colors.white) then
  131.         monitor.setTextColor(colors.black)
  132.     end
  133.  
  134.     labely = math.min((starty + 1), screenh - 1)
  135.     monitor.setCursorPos(offset + 1, labely)
  136.     write(label)
  137.  
  138.     if (amtw <= width) then
  139.         amty = math.min(labely + 1, screenh)
  140.         monitor.setCursorPos(offset + 1, amty)
  141.         write(amt)
  142.     end
  143.     monitor.setTextColor(colors.white)
  144.     -- term.restore()
  145. end
  146.  
  147. local function tankStats(tank)
  148.     if(tank) then
  149.         local amt = tank["amount"]
  150.         local size = tank["capacity"]
  151.         local filled = (amt and 1 / (size / amt)) or 0
  152.         return amt, size, filled
  153.     else
  154.         return nil;
  155.     end
  156. end
  157.  
  158. local function tableCount(t)
  159.     local total=0
  160.     for k,v in pairs (t) do
  161.         total = total + 1
  162.     end
  163.     return total
  164. end
  165.  
  166. local function updateDisplay()
  167.     local total = tableCount(clients)
  168.     local count = 1
  169.  
  170.     monitor.setBackgroundColor(colors.black)
  171.     monitor.setTextScale(.5)
  172.     monitor.clear()
  173.  
  174.     for ix,client in pairs (clients) do
  175.         local tank = client[1]
  176.         local threshold = client[2]
  177.         local signalOn = client[3]
  178.         local amt,size,filled = tankStats(tank)
  179.         local kind = tank["name"]
  180.         local color,name = getLiquidColor(kind)
  181.         local unit = ""
  182.         local amount = math.max(amt or 0, 0)
  183.  
  184.         if (amount > 1000000) then
  185.             unit="M"
  186.             amount=string.format("%.2f", math.floor(amt / 1000) / 1000)
  187.         else
  188.             if (amount > 0) then
  189.                 unit="K"
  190.                 amount=string.format("%.2f", amt / 1000)
  191.             else
  192.                 amount = ""
  193.             end
  194.         end
  195.         amount = amount..unit
  196.         showLevel(count, total, filled, color, name or "Empty", amount, threshold, signalOn)
  197.         count = count + 1    
  198.     end
  199.     return nil;
  200. end
  201.  
  202. local function broadcast ()
  203.     term.clear()
  204.     term.setCursorPos(1,1)
  205.     print("_____________ tankmon Server started __________")
  206.     print("Broadcasting that tank display is available...")
  207.     print("Hold Ctrl+T to Terminate.")
  208.     while true do
  209.         rednet.broadcast(os.getComputerID())
  210.         -- term.setCursorPos(1, 5)
  211.         -- term.clearLine()
  212.         -- write("Connected tankmon clients: " .. tostring(tableCount(clients)))
  213.         sleep(7)
  214.     end
  215. end
  216.  
  217. local function receive()
  218.     while true do
  219.         local senderID, message, distance = rednet.receive()
  220.         if (message) then
  221.             local data = textutils.unserialize(message)
  222.             clients[senderID] = data
  223.         end
  224.     end
  225. end
  226.  
  227. local function display()
  228.     while true do
  229.         updateDisplay()
  230.         sleep(1.5)
  231.     end
  232. end
  233.  
  234. local function connect()
  235.     print("Looking for a tankmon server in wireless Rednet range...")
  236.     while true do
  237.         local senderID, message, distance = rednet.receive()
  238.         serverID = senderID
  239.         print("Connected to server " .. tostring(serverID))
  240.         sleep(3)
  241.     end
  242. end
  243.  
  244. local function publishTank()
  245.     while true do
  246.         if serverID then
  247.             term.clear()
  248.             term.setCursorPos(1,1)
  249.             print("** Sending out tank information **")
  250.             local tank = valve.getTankInfo("unknown")[1]
  251.  
  252.             -- establish whether redstone signal should be sent
  253.             local amt,size,pctFilled = tankStats(tank)
  254.             on = false
  255.             local filled = pctFilled * 100
  256.             if (filled and redlimit and redlimit==0 and filled==0) then
  257.                 on = true
  258.             else
  259.                 if (filled and redlimit and filled <= redlimit) then
  260.                     on=true
  261.                 end
  262.             end
  263.             if (redside) then
  264.                 rs.setOutput(redside, on)
  265.             end
  266.  
  267.             -- use rednet to update the server with this tank's info.
  268.             local info = {tank, redlimit, on}
  269.             if (redlimit and redside) then
  270.                 print("Redstone threshold: " .. tostring(redlimit))
  271.                 print("Redstone output side: " .. redside)
  272.                 print("Redstone signal on: " .. tostring(on))
  273.                 print("")
  274.             end
  275.             term.clearLine()
  276.             write("** Tank contains: " .. tostring(amt))
  277.             rednet.send(serverID, textutils.serialize(info), false)            
  278.         end
  279.         sleep(math.random(1,5))
  280.     end
  281. end
  282.  
  283. ---------------------------------------
  284. -- Main
  285. ---------------------------------------
  286. local modemSide = getDeviceSide("modem");
  287.  
  288. if (modemSide) then
  289.     local modem = peripheral.wrap(modemSide)
  290. else
  291.     error ("A wireless modem must be attached to this computer.")
  292. end
  293.  
  294. local tankSide = getDeviceSide("iron_tank_valve");
  295. local tankSide2 = getDeviceSide("steel_tank_valve");
  296. local tankSide3 = getDeviceSide("rcsteeltankvalvetile");
  297. local tankSide4 = getDeviceSide("rcirontankvalvetile");
  298. local finalside = tankSide or tankSide2 or tankSide3 or tankSide4
  299. local screenSide = getDeviceSide("monitor");
  300.  
  301. if (finalside and screenSide) then
  302.       error("Either a screen or a tank valve can be connected, not both.")
  303. end
  304.  
  305. if finalside  then
  306.     valve = peripheral.wrap(finalside )
  307. end
  308.  
  309. if (screenSide) then
  310.     monitor = peripheral.wrap(screenSide)
  311.     if (not monitor.isColor()) then
  312.         error("The attached monitor must be Advanced. Get some gold!")
  313.     end
  314.     monitor.clear()
  315. end
  316.  
  317. rednet.open(modemSide)
  318. if (valve) then
  319.     -- client mode
  320.     redlimit = args[1]
  321.     redside = args[2]
  322.     if (redlimit and not redside) then
  323.         print ("A threshold and redstone side must both be present.")
  324.         print ("e.g. tankmon 100 top")
  325.         error ()
  326.     end
  327.     if (redlimit) then
  328.         redlimit = tonumber(redlimit)
  329.         print("")
  330.         print("Tank will send redstone signal at or below " .. tostring(redlimit) .. "% on side " .. redside)
  331.     end
  332.     -- clear outstanding redstone signals.
  333.     for i,side in pairs(sides) do
  334.         rs.setOutput(side, false)
  335.     end
  336.     parallel.waitForAll(connect, publishTank)
  337. else
  338.     -- server mode
  339.     parallel.waitForAll(broadcast, receive, display)
  340. end
  341. rednet.close(modemSide)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement