Advertisement
Guest User

Untitled

a guest
May 22nd, 2015
206
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.     max = max + 1
  78.     if (not screenw) then
  79.         return nil;
  80.         -- monitor has been broken
  81.     end
  82.        
  83.     local starty = screenh -  math.floor((screenh * filled))
  84.     local width  = math.ceil(screenw / max + .5)
  85.     local offset = math.ceil(width * (count - 1))
  86.     local amtw = string.len(amt)
  87.     local thresholdy = (threshold and ( screenh - ((threshold / 100) * screenh)))
  88.  
  89.     if (count == max) then
  90.     --  the final column should use up the remaining space.  A hack!
  91.         width = screenw - offset
  92.     end
  93.     --truncate the label to the width of the bar.
  94.     label = string.sub(label, 1, math.max((width - 1), 0))
  95.  
  96.     if (thresholdy and thresholdy < 1) then
  97.         thresholdy = 1
  98.     else
  99.         if (thresholdy and thresholdy > screenh) then
  100.             thresholdy = screenh
  101.         end
  102.     end
  103.  
  104.     term.redirect(monitor)
  105.     for c=starty, screenh + 1, 1 do
  106.         for line=0, width, 1 do
  107.             paintutils.drawPixel(line + offset, c, color)
  108.         end
  109.     end
  110.     if (thresholdy) then
  111.         local thresholdColor = color
  112.         for line=0, width, 1 do
  113.             thresholdColor = color
  114.             if (signal) then
  115.                 thresholdColor = colors.red
  116.             else
  117.                 -- makes a dotted line when there is no redstone signal
  118.                 if (line % 2 == 0) then
  119.                     thresholdColor = colors.red
  120.                 end
  121.             end
  122.             paintutils.drawPixel(line + offset, thresholdy, thresholdColor)
  123.         end
  124.     end
  125.  
  126.     monitor.setBackgroundColor(color)
  127.     if (color == colors.white) then
  128.         monitor.setTextColor(colors.black)
  129.     end
  130.  
  131.     labely = math.min((starty + 1), screenh - 1)
  132.     monitor.setCursorPos(offset + 1, labely)
  133.     write(label)
  134.  
  135.     if (amtw <= width) then
  136.         amty = math.min(labely + 1, screenh)
  137.         monitor.setCursorPos(offset + 1, amty)
  138.         write(amt)
  139.     end
  140.     monitor.setTextColor(colors.white)
  141.     -- term.restore()
  142. end
  143.  
  144. local function tankStats(tank)
  145.     if(tank) then
  146.         local amt = tank["amount"]
  147.         local size = tank["capacity"]
  148.         local filled = (amt and 1 / (size / amt)) or 0
  149.         return amt, size, filled
  150.     else
  151.         return nil;
  152.     end
  153. end
  154.  
  155. local function tableCount(t)
  156.     local total=0
  157.     for k,v in pairs (t) do
  158.         total = total + 1
  159.     end
  160.     return total
  161. end
  162.  
  163. local function updateDisplay()
  164.     local total = tableCount(clients)
  165.     local count = 1
  166.  
  167.     monitor.setBackgroundColor(colors.black)
  168.     monitor.setTextScale(.5)
  169.     monitor.clear()
  170.  
  171.     for ix,client in pairs (clients) do
  172.         local tank = client[1]
  173.         local threshold = client[2]
  174.         local signalOn = client[3]
  175.         local amt,size,filled = tankStats(tank)
  176.         local kind = tank["name"]
  177.         local color,name = getLiquidColor(kind)
  178.         local unit = ""
  179.         local amount = math.max(amt or 0, 0)
  180.  
  181.         if (amount > 1000000) then
  182.             unit="M"
  183.             amount=string.format("%.2f", math.floor(amt / 1000) / 1000)
  184.         else
  185.             if (amount > 0) then
  186.                 unit="K"
  187.                 amount=string.format("%.2f", amt / 1000)
  188.             else
  189.                 amount = ""
  190.             end
  191.         end
  192.         amount = amount..unit
  193.         showLevel(count, total, filled, color, name or "Empty", amount, threshold, signalOn)
  194.         count = count + 1    
  195.     end
  196.     return nil;
  197. end
  198.  
  199. local function broadcast ()
  200.     term.clear()
  201.     term.setCursorPos(1,1)
  202.     print("_____________ tankmon Server started __________")
  203.     print("Broadcasting that tank display is available...")
  204.     print("Hold Ctrl+T to Terminate.")
  205.     while true do
  206.         rednet.broadcast(os.getComputerID())
  207.         -- term.setCursorPos(1, 5)
  208.         -- term.clearLine()
  209.         -- write("Connected tankmon clients: " .. tostring(tableCount(clients)))
  210.         sleep(7)
  211.     end
  212. end
  213.  
  214. local function receive()
  215.     while true do
  216.         local senderID, message, distance = rednet.receive()
  217.         if (message) then
  218.             local data = textutils.unserialize(message)
  219.             clients[senderID] = data
  220.         end
  221.     end
  222. end
  223.  
  224. local function display()
  225.     while true do
  226.         updateDisplay()
  227.         sleep(1.5)
  228.     end
  229. end
  230.  
  231. local function connect()
  232.     print("Looking for a tankmon server in wireless Rednet range...")
  233.     while true do
  234.         local senderID, message, distance = rednet.receive()
  235.         serverID = senderID
  236.         print("Connected to server " .. tostring(serverID))
  237.         sleep(3)
  238.     end
  239. end
  240.  
  241. local function publishTank()
  242.     while true do
  243.         if serverID then
  244.             term.clear()
  245.             term.setCursorPos(1,1)
  246.             print("** Sending out tank information **")
  247.             local tank = valve.getTankInfo("unknown")[1]
  248.  
  249.             -- establish whether redstone signal should be sent
  250.             local amt,size,pctFilled = tankStats(tank)
  251.             on = false
  252.             local filled = pctFilled * 100
  253.             if (filled and redlimit and redlimit==0 and filled==0) then
  254.                 on = true
  255.             else
  256.                 if (filled and redlimit and filled <= redlimit) then
  257.                     on=true
  258.                 end
  259.             end
  260.             if (redside) then
  261.                 rs.setOutput(redside, on)
  262.             end
  263.  
  264.             -- use rednet to update the server with this tank's info.
  265.             local info = {tank, redlimit, on}
  266.             if (redlimit and redside) then
  267.                 print("Redstone threshold: " .. tostring(redlimit))
  268.                 print("Redstone output side: " .. redside)
  269.                 print("Redstone signal on: " .. tostring(on))
  270.                 print("")
  271.             end
  272.             term.clearLine()
  273.             write("** Tank contains: " .. tostring(amt))
  274.             rednet.send(serverID, textutils.serialize(info), false)            
  275.         end
  276.         sleep(math.random(1,5))
  277.     end
  278. end
  279.  
  280. ---------------------------------------
  281. -- Main
  282. ---------------------------------------
  283. local modemSide = getDeviceSide("modem");
  284.  
  285. if (modemSide) then
  286.     local modem = peripheral.wrap(modemSide)
  287. else
  288.     error ("A wireless modem must be attached to this computer.")
  289. end
  290.  
  291. local tankSide = getDeviceSide("iron_tank_valve");
  292. local tankSide2 = getDeviceSide("steel_tank_valve");
  293. local tankSide3 = getDeviceSide("rcsteeltankvalvetile");
  294. local tankSide4 = getDeviceSide("rcirontankvalvetile");
  295. local finalside = tankSide or tankSide2 or tankSide3 or tankSide4
  296. local screenSide = getDeviceSide("monitor");
  297.  
  298. if (finalside and screenSide) then
  299.       error("Either a screen or a tank valve can be connected, not both.")
  300. end
  301.  
  302. if finalside  then
  303.     valve = peripheral.wrap(finalside )
  304. end
  305.  
  306. if (screenSide) then
  307.     monitor = peripheral.wrap(screenSide)
  308.     local screenw, screenh = monitor.getSize()
  309.     screenw = screenw / 2
  310.     screenh = screenh / 2
  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.     if (screenh and screenw) then
  340.         paintutils.drawLine(screenw, 0, screenw, 2 * screenh)
  341.         paintutils.drawLine(0, screenh, 2 * screenw, screenh)
  342.     end
  343.  
  344.     parallel.waitForAll(broadcast, receive, display)
  345. end
  346. rednet.close(modemSide)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement