net.lua 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. --[[
  2. Licensed under GNU General Public License v2
  3. * (c) 2013, Luca CPZ
  4. * (c) 2010-2012, Peter Hofmann
  5. --]]
  6. local helpers = require("lain.helpers")
  7. local naughty = require("naughty")
  8. local wibox = require("wibox")
  9. local string = string
  10. -- Network infos
  11. -- lain.widget.net
  12. local function factory(args)
  13. args = args or {}
  14. local net = { widget = args.widget or wibox.widget.textbox(), devices = {} }
  15. local timeout = args.timeout or 2
  16. local units = args.units or 1024 -- KB
  17. local notify = args.notify or "on"
  18. local wifi_state = args.wifi_state or "off"
  19. local eth_state = args.eth_state or "off"
  20. local screen = args.screen or 1
  21. local settings = args.settings or function() end
  22. -- Compatibility with old API where iface was a string corresponding to 1 interface
  23. net.iface = (args.iface and (type(args.iface) == "string" and {args.iface}) or
  24. (type(args.iface) == "table" and args.iface)) or {}
  25. function net.get_devices()
  26. net.iface = {} -- reset at every call
  27. helpers.line_callback("ip link", function(line)
  28. net.iface[#net.iface + 1] = not string.match(line, "LOOPBACK") and string.match(line, "(%w+): <") or nil
  29. end)
  30. end
  31. if #net.iface == 0 then net.get_devices() end
  32. function net.update()
  33. -- These are the totals over all specified interfaces
  34. net_now = {
  35. devices = {},
  36. -- Bytes since last iteration
  37. sent = 0,
  38. received = 0
  39. }
  40. for _, dev in ipairs(net.iface) do
  41. local dev_now = {}
  42. local dev_before = net.devices[dev] or { last_t = 0, last_r = 0 }
  43. local now_t = tonumber(helpers.first_line(string.format("/sys/class/net/%s/statistics/tx_bytes", dev)) or 0)
  44. local now_r = tonumber(helpers.first_line(string.format("/sys/class/net/%s/statistics/rx_bytes", dev)) or 0)
  45. dev_now.carrier = helpers.first_line(string.format("/sys/class/net/%s/carrier", dev)) or "0"
  46. dev_now.state = helpers.first_line(string.format("/sys/class/net/%s/operstate", dev)) or "down"
  47. dev_now.sent = (now_t - dev_before.last_t) / timeout / units
  48. dev_now.received = (now_r - dev_before.last_r) / timeout / units
  49. net_now.sent = net_now.sent + dev_now.sent
  50. net_now.received = net_now.received + dev_now.received
  51. dev_now.sent = string.format("%.1f", dev_now.sent)
  52. dev_now.received = string.format("%.1f", dev_now.received)
  53. dev_now.last_t = now_t
  54. dev_now.last_r = now_r
  55. if wifi_state == "on" and helpers.first_line(string.format("/sys/class/net/%s/uevent", dev)) == "DEVTYPE=wlan" then
  56. dev_now.wifi = true
  57. if string.match(dev_now.carrier, "1") then
  58. dev_now.signal = tonumber(string.match(helpers.lines_from("/proc/net/wireless")[3], "(%-%d+%.)")) or nil
  59. end
  60. else
  61. dev_now.wifi = false
  62. end
  63. if eth_state == "on" and helpers.first_line(string.format("/sys/class/net/%s/uevent", dev)) ~= "DEVTYPE=wlan" then
  64. dev_now.ethernet = true
  65. else
  66. dev_now.ethernet = false
  67. end
  68. net.devices[dev] = dev_now
  69. -- Notify only once when connection is lost
  70. if string.match(dev_now.carrier, "0") and notify == "on" and helpers.get_map(dev) then
  71. naughty.notify {
  72. title = dev,
  73. text = "No carrier",
  74. icon = helpers.icons_dir .. "no_net.png",
  75. screen = screen
  76. }
  77. helpers.set_map(dev, false)
  78. elseif string.match(dev_now.carrier, "1") then
  79. helpers.set_map(dev, true)
  80. end
  81. net_now.carrier = dev_now.carrier
  82. net_now.state = dev_now.state
  83. net_now.devices[dev] = dev_now
  84. -- net_now.sent and net_now.received will be
  85. -- the totals across all specified devices
  86. end
  87. net_now.sent = string.format("%.1f", net_now.sent)
  88. net_now.received = string.format("%.1f", net_now.received)
  89. widget = net.widget
  90. settings()
  91. end
  92. helpers.newtimer("network", timeout, net.update)
  93. return net
  94. end
  95. return factory