Guest User

Untitled

a guest
May 22nd, 2015
219
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 / 4
  79.         screenh = screenh / 4
  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.                         -- establish whether redstone signal should be sent
  252.                         local amt,size,pctFilled = tankStats(tank)
  253.                         on = false
  254.                         local filled = pctFilled * 100
  255.                         if (filled and redlimit and redlimit==0 and filled==0) then
  256.                                 on = true
  257.                         else
  258.                                 if(filled and redlimit and filled <= redlimit) then
  259.                                         on=true
  260.                                 end
  261.                         end
  262.                         if(redside) then
  263.                                 rs.setOutput(redside, on)
  264.                         end
  265.                         -- use rednet to update the server with this tank's info.
  266.                         local info = {tank, redlimit, on}
  267.                         if (redlimit and redside) then
  268.                                 print("Redstone threshold: " .. tostring(redlimit))
  269.                                 print("Redstone output side: " .. redside)
  270.                                 print("Redstone signal on: " .. tostring(on))
  271.                                 print("")
  272.                         end
  273.                         term.clearLine()
  274.                         write("** Tank contains: " .. tostring(amt))
  275.             rednet.send(serverID, textutils.serialize(info), false)            
  276.                 end
  277.                 sleep(math.random(1,5))
  278.     end
  279. end
  280.  
  281. ---------------------------------------
  282. --the Main
  283. ---------------------------------------
  284. local modemSide = getDeviceSide("modem");
  285.  
  286. if (modemSide) then
  287.       local modem = peripheral.wrap(modemSide)
  288. else
  289.       error("A wireless modem must be attached to this computer.")
  290. end
  291.  
  292. local tankSide = getDeviceSide("iron_tank_valve");
  293. local tankSide2 = getDeviceSide("steel_tank_valve");
  294. local tankSide3 = getDeviceSide("rcsteeltankvalvetile");
  295. local tankSide4 = getDeviceSide("rcirontankvalvetile");
  296. local finalside = tankSide or tankSide2 or tankSide3 or tankSide4
  297. local screenSide = getDeviceSide("monitor");
  298.  
  299. if (finalside and screenSide) then
  300.       error("Either a screen or a tank valve can be connected, not both.")
  301. end
  302.  
  303. if finalside  then
  304.       valve = peripheral.wrap(finalside )
  305. end
  306.  
  307. if (screenSide) then
  308.       monitor = peripheral.wrap(screenSide)
  309.         if(not monitor.isColor()) then
  310.                 error("The attached monitor must be Advanced.  Get some gold!")
  311.         end
  312.     screenw, screenh = monitor.getSize()
  313.     monitor.clear()
  314. end
  315.  
  316. rednet.open(modemSide)
  317. if (valve) then
  318.       -- client mode
  319.         redlimit = args[1]
  320.         redside = args[2]
  321.         if (redlimit and not redside) then
  322.                 print("A threshold and redstone side must both be present.")
  323.                 print("e.g. tankmon 100 top")
  324.                 error()
  325.         end
  326.         if (redlimit) then
  327.                 redlimit = tonumber(redlimit)
  328.                 print("")
  329.                 print("Tank will send redstone signal at or below " .. tostring(redlimit) .. "% on side " .. redside)
  330.         end
  331.         -- clear outstanding redstone signals.
  332.         for i,side in pairs(sides) do
  333.                 rs.setOutput(side, false)
  334.         end
  335.     parallel.waitForAll(connect, publishTank)
  336. else
  337.       -- server mode
  338.       parallel.waitForAll(broadcast, receive, display)
  339. end
  340. rednet.close(modemSide)
Advertisement
Add Comment
Please, Sign In to add comment