]> git.madduck.net Git - etc/awesome.git/blob - widgets/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:

lain is now as asynchronous as possible
[etc/awesome.git] / widgets / 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 local setmetatable = setmetatable
16
17 -- Network infos
18 -- lain.widgets.net
19
20 local function worker(args)
21     local net = helpers.make_widget_textbox()
22     net.last_t = 0
23     net.last_r = 0
24     net.devices = {}
25
26     local args       = args or {}
27     local timeout    = args.timeout or 2
28     local units      = args.units or 1024 --kb
29     local notify     = args.notify or "on"
30     local screen     = args.screen or 1
31     local settings   = args.settings or function() end
32
33     -- Compatibility with old API where iface was a string corresponding to 1 interface
34     net.iface = (args.iface and type(args.iface) == "string" 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             -- Old api compatibility
100             net_now.carrier      = dev_now.carrier
101             net_now.state        = dev_now.state
102             -- And new api
103             net_now.devices[dev] = dev_now
104             -- With the new api new_now.sent and net_now.received will be the
105             -- totals across all specified devices
106         end
107
108         if total_t ~= net.last_t or total_r ~= net.last_r then
109             net_now.sent     = string.format('%.1f', net_now.sent)
110             net_now.received = string.format('%.1f', net_now.received)
111             net.last_t       = total_t
112             net.last_r       = total_r
113         end
114
115         widget = net.widget
116         settings()
117     end
118
119     helpers.newtimer(net.iface, timeout, update)
120
121     return net
122 end
123
124 return setmetatable({}, { __call = function(_, ...) return worker(...) end })