]> 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:

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