]> git.madduck.net Git - etc/awesome.git/blob - widget/net.lua

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

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