]> 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 branch 'master' of github.com:copycat-killer/lain
[etc/awesome.git] / widget / net.lua
1
2 --[[
3                                                   
4      Licensed under GNU General Public License v2 
5       * (c) 2013,      Luke Bonham                
6       * (c) 2010-2012, Peter Hofmann              
7                                                   
8 --]]
9
10 local helpers = require("lain.helpers")
11 local naughty = require("naughty")
12 local wibox   = require("wibox")
13 local string  = { format = string.format,
14                   match  = string.match }
15
16 -- Network infos
17 -- lain.widget.net
18
19 local function factory(args)
20     local net = { widget = wibox.widget.textbox() }
21     net.last_t = 0
22     net.last_r = 0
23     net.devices = {}
24
25     local args       = args or {}
26     local timeout    = args.timeout or 2
27     local units      = args.units or 1024 --kb
28     local notify     = args.notify or "on"
29     local screen     = args.screen or 1
30     local settings   = args.settings or function() end
31
32     -- Compatibility with old API where iface was a string corresponding to 1 interface
33     net.iface = (args.iface and (type(args.iface) == "string" and {args.iface}) or
34                 (type(args.iface) == "table" and args.iface)) or {}
35
36     function net.get_device()
37         helpers.async(string.format("ip link show", device_cmd), function(ws)
38             ws = ws:match("(%w+): <BROADCAST,MULTICAST,.-UP,LOWER_UP>")
39             net.iface = ws and { ws } or {}
40         end)
41     end
42
43     if #net.iface == 0 then net.get_device() end
44
45     function update()
46         -- These are the totals over all specified interfaces
47         net_now = {
48             -- New api - Current state of requested devices
49             devices  = {},
50             -- Bytes since last iteration
51             sent     = 0,
52             received = 0
53         }
54
55         -- Total bytes transfered
56         local total_t = 0
57         local total_r = 0
58
59         for i, dev in ipairs(net.iface) do
60             local dev_now    = {}
61             local dev_before = net.devices[dev] or { last_t = 0, last_r = 0 }
62             local now_t      = tonumber(helpers.first_line(string.format("/sys/class/net/%s/statistics/tx_bytes", dev)) or 0)
63             local now_r      = tonumber(helpers.first_line(string.format("/sys/class/net/%s/statistics/rx_bytes", dev)) or 0)
64
65             dev_now.carrier  = helpers.first_line(string.format("/sys/class/net/%s/carrier", dev)) or "0"
66             dev_now.state    = helpers.first_line(string.format("/sys/class/net/%s/operstate", dev)) or "down"
67
68             dev_now.sent     = (now_t - dev_before.last_t) / timeout / units
69             dev_now.received = (now_r - dev_before.last_r) / timeout / units
70
71             net_now.sent     = net_now.sent     + dev_now.sent
72             net_now.received = net_now.received + dev_now.received
73
74             dev_now.sent     = string.format('%.1f', dev_now.sent)
75             dev_now.received = string.format('%.1f', dev_now.received)
76
77             dev_now.last_t   = now_t
78             dev_now.last_r   = now_r
79
80             -- This will become dev_before in the next update/iteration
81             net.devices[dev] = dev_now
82
83             total_t  = total_t + now_t
84             total_r  = total_r + now_r
85
86             -- Notify only once when connection is loss
87             if string.match(dev_now.carrier, "0") and notify == "on" and helpers.get_map(dev) then
88                 naughty.notify({
89                     title    = dev,
90                     text     = "no carrier",
91                     icon     = helpers.icons_dir .. "no_net.png",
92                     screen   = screen
93                 })
94                 helpers.set_map(dev, false)
95             elseif string.match(dev_now.carrier, "1") then
96                 helpers.set_map(dev, true)
97             end
98
99             net_now.carrier      = dev_now.carrier
100             net_now.state        = dev_now.state
101             net_now.devices[dev] = dev_now
102             -- new_now.sent and net_now.received will be the
103             -- totals across all specified devices
104         end
105
106         if total_t ~= net.last_t or total_r ~= net.last_r then
107             net_now.sent     = string.format('%.1f', net_now.sent)
108             net_now.received = string.format('%.1f', net_now.received)
109             net.last_t       = total_t
110             net.last_r       = total_r
111         end
112
113         widget = net.widget
114         settings()
115     end
116
117     helpers.newtimer("network", timeout, update)
118
119     return net
120 end
121
122 return factory