Advertisement
Guest User

tankmon for CC 1.57

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