standardise interface to metrics
call as follows: (let [m (metricname.new)] (m:read) (m:read) ... )
This commit is contained in:
parent
b6a8048c8b
commit
463c1eea03
@ -17,9 +17,9 @@ Not quite dogfood-ready yet, but fast approaching.
|
||||
* blinkenlicht.fnl is the module that parses `bar` and `indicator`
|
||||
forms and does all the UI
|
||||
|
||||
* metric.fnl is a collection of functions that read metrics (load
|
||||
average, battery status etc) from the system, for indicators to
|
||||
display.
|
||||
* metric/*.fnl is a collection of modules that read metrics (load
|
||||
average, connectivity, battery status etc) from the system, for
|
||||
indicators to display.
|
||||
|
||||
Use the `default.nix` for guidance as to libraries and other setup
|
||||
required - or just use it, of course.
|
||||
@ -43,10 +43,10 @@ Gtk will find it anyway. Magic.
|
||||
* [X] add some mechanism for indicators that wait for events instead of polling
|
||||
* [X] set indicator background colour (use css for this?)
|
||||
* [ ] update image/label widget instead of destroying
|
||||
* [ ] allow height customisation
|
||||
* [ ] allow image height customisation
|
||||
* [X] set poll interval based on indicators' requested intervals
|
||||
* [X] allow indicator to change styles based on status
|
||||
* [ ] add metrics for
|
||||
- wireless connected/strength
|
||||
- [X] wireless connected/strength
|
||||
- wwan connected/type (hspa, lte, etc)/signal
|
||||
- cpu %
|
||||
|
@ -3,10 +3,12 @@
|
||||
(local {: view} (require :fennel))
|
||||
|
||||
(local iostream (require :iostream))
|
||||
(local metric (require :metric))
|
||||
(local uplink (require :uplink))
|
||||
(local modem (require :modem))
|
||||
|
||||
(local uplink (require :metric.uplink))
|
||||
(local battery (require :metric.battery))
|
||||
(local cpustat (require :metric.cpustat))
|
||||
|
||||
(stylesheet "licht.css")
|
||||
|
||||
(fn battery-icon-codepoint [status percent]
|
||||
@ -40,26 +42,27 @@
|
||||
(indicator {
|
||||
:wait-for { :interval (* 1 500) }
|
||||
:refresh
|
||||
#(let [current (. (metric.cpustat) :iowait)
|
||||
delta (- current previous)
|
||||
v (if (> delta 4) "" " ")]
|
||||
(set previous current)
|
||||
{:text v})
|
||||
(let [stat (cpustat.new)]
|
||||
#(let [current (. (stat:read) :iowait)
|
||||
delta (- current previous)
|
||||
v (if (> delta 4) "" " ")]
|
||||
(set previous current)
|
||||
{:text v}))
|
||||
}))
|
||||
|
||||
(let [modem (modem.new)]
|
||||
(indicator {
|
||||
:wait-for {
|
||||
(indicator {
|
||||
:wait-for {
|
||||
:interval (* 4 1000)
|
||||
}
|
||||
:refresh
|
||||
}
|
||||
:refresh
|
||||
(let [modem (modem.new)]
|
||||
#(let [{:m3gpp-operator-name operator
|
||||
:signal-quality quality} (modem:value)]
|
||||
:signal-quality quality} (modem:read)]
|
||||
{:text (.. operator
|
||||
;" " (. quality 1) "dBm"
|
||||
;;" " (. quality 1) "dBm"
|
||||
)
|
||||
})
|
||||
}))
|
||||
}))
|
||||
})
|
||||
|
||||
(let [uplink (uplink.new)
|
||||
input (iostream.from-descriptor uplink.fd)]
|
||||
@ -68,7 +71,7 @@
|
||||
:input [input]
|
||||
}
|
||||
:refresh
|
||||
#(let [status (uplink:status)]
|
||||
#(let [status (uplink:read)]
|
||||
(if status
|
||||
{:text (.. (or status.ssid status.name "?")
|
||||
" "
|
||||
@ -85,15 +88,17 @@
|
||||
(indicator {
|
||||
:wait-for { :interval (* 1000 10) }
|
||||
:refresh
|
||||
#(let [{:power-supply-capacity percent
|
||||
:power-supply-status status}
|
||||
(metric.battery "axp20x-battery")
|
||||
icon-code (battery-icon-codepoint
|
||||
status (tonumber percent))]
|
||||
{:text
|
||||
(string.format "%s %d%%" (utf8.char icon-code) percent)
|
||||
:classes ["battery" (if (< (tonumber percent) 20) "low" "ok")]
|
||||
})
|
||||
(let [battery (battery.new (or (os.getenv "BLINKEN_BATTERY")
|
||||
"axp20x-battery"))]
|
||||
#(let [{:power-supply-capacity percent
|
||||
:power-supply-status status}
|
||||
(battery.read)
|
||||
icon-code (battery-icon-codepoint
|
||||
status (tonumber percent))]
|
||||
{:text
|
||||
(string.format "%s %d%%" (utf8.char icon-code) percent)
|
||||
:classes ["battery" (if (< (tonumber percent) 20) "low" "ok")]
|
||||
}))
|
||||
})
|
||||
(indicator {
|
||||
:wait-for { :interval 4000 }
|
||||
|
@ -1,42 +0,0 @@
|
||||
(local {: view} (require :fennel))
|
||||
|
||||
(fn loadavg []
|
||||
(with-open [f (io.open "/proc/loadavg" :r)]
|
||||
(let [line (f:read "*a")
|
||||
(one five fifteen) (line:match "([%d.]+) +([%d.]+) +([%d.]+)")]
|
||||
(values (tonumber one) (tonumber five) (tonumber fifteen)))))
|
||||
|
||||
(fn battery [name]
|
||||
(let [name (.. "/sys/class/power_supply/" name "/uevent")]
|
||||
(with-open [f (io.open name :r)]
|
||||
(let [fields {}]
|
||||
(each [line #(f:read "*l")]
|
||||
(let [(name value) (line:match "([^=]+)=(.+)")]
|
||||
(tset fields (: (name:gsub "_" "-") :lower) value)))
|
||||
fields))))
|
||||
|
||||
(fn parse-cpu-stat-line [line]
|
||||
(let [labels [:user :nice :system :idle :iowait
|
||||
:irq :softirq :steal :guest :guest_nice]
|
||||
vals (icollect [field (line:gmatch "([%d.]+)")]
|
||||
(tonumber field))]
|
||||
(collect [i label (ipairs labels)]
|
||||
label (. vals i))))
|
||||
|
||||
(var proc-stat-handle nil)
|
||||
|
||||
(fn cpustat [path]
|
||||
(if proc-stat-handle
|
||||
(proc-stat-handle:seek :set 0)
|
||||
(set proc-stat-handle (io.open "/proc/stat" :r)))
|
||||
(let [f proc-stat-handle]
|
||||
(accumulate [ret nil
|
||||
line #(f:read "*l") ]
|
||||
(if (= (string.sub line 1 (# "cpu ")) "cpu ")
|
||||
(parse-cpu-stat-line line)
|
||||
ret))))
|
||||
|
||||
{: loadavg
|
||||
: battery
|
||||
: cpustat
|
||||
}
|
15
blinkenlicht/metric/battery.fnl
Normal file
15
blinkenlicht/metric/battery.fnl
Normal file
@ -0,0 +1,15 @@
|
||||
(fn battery [name]
|
||||
(let [name (.. "/sys/class/power_supply/" name "/uevent")]
|
||||
(with-open [f (io.open name :r)]
|
||||
(let [fields {}]
|
||||
(each [line #(f:read "*l")]
|
||||
(let [(name value) (line:match "([^=]+)=(.+)")]
|
||||
(tset fields (: (name:gsub "_" "-") :lower) value)))
|
||||
fields))))
|
||||
|
||||
{ :new
|
||||
(fn [name]
|
||||
{
|
||||
:read #(battery name)
|
||||
})
|
||||
}
|
24
blinkenlicht/metric/cpustat.fnl
Normal file
24
blinkenlicht/metric/cpustat.fnl
Normal file
@ -0,0 +1,24 @@
|
||||
(fn parse-cpu-stat-line [line]
|
||||
(let [labels [:user :nice :system :idle :iowait
|
||||
:irq :softirq :steal :guest :guest_nice]
|
||||
vals (icollect [field (line:gmatch "([%d.]+)")]
|
||||
(tonumber field))]
|
||||
(collect [i label (ipairs labels)]
|
||||
label (. vals i))))
|
||||
|
||||
(fn cpustat [proc-stat-handle]
|
||||
(let [f proc-stat-handle]
|
||||
(f:seek :set 0)
|
||||
(accumulate [ret nil
|
||||
line #(f:read "*l")
|
||||
:until ret]
|
||||
(if (= (string.sub line 1 (# "cpu ")) "cpu ")
|
||||
(parse-cpu-stat-line line)
|
||||
ret))))
|
||||
{
|
||||
:new
|
||||
#(let [handle (io.open "/proc/stat" :r)]
|
||||
{
|
||||
:read #(cpustat handle)
|
||||
})
|
||||
}
|
9
blinkenlicht/metric/loadavg.fnl
Normal file
9
blinkenlicht/metric/loadavg.fnl
Normal file
@ -0,0 +1,9 @@
|
||||
(fn loadavg []
|
||||
(with-open [f (io.open "/proc/loadavg" :r)]
|
||||
(let [line (f:read "*a")
|
||||
(one five fifteen) (line:match "([%d.]+) +([%d.]+) +([%d.]+)")]
|
||||
(values (tonumber one) (tonumber five) (tonumber fifteen)))))
|
||||
|
||||
{:new #{
|
||||
:read #(loadavg)
|
||||
})
|
@ -90,13 +90,13 @@
|
||||
:refresh #(each [_ event (ipairs (sock:event))]
|
||||
(handle-event event))
|
||||
:fd (sock:fd)
|
||||
:status (fn [self]
|
||||
(self:refresh)
|
||||
(let [defaultroute routes.default
|
||||
interface (and defaultroute
|
||||
(. links defaultroute.index))]
|
||||
(and interface (= interface.running "yes")
|
||||
(get-network-info interface))))
|
||||
:read (fn [self]
|
||||
(self:refresh)
|
||||
(let [defaultroute routes.default
|
||||
interface (and defaultroute
|
||||
(. links defaultroute.index))]
|
||||
(and interface (= interface.running "yes")
|
||||
(get-network-info interface))))
|
||||
:wait #(sock:poll 1000)
|
||||
:interface (fn [self ifnum]
|
||||
(. links ifnum))
|
@ -5,25 +5,22 @@
|
||||
(local variant dbus.variant)
|
||||
|
||||
;; https://www.freedesktop.org/software/ModemManager/api/latest/ref-dbus.html
|
||||
(var the-modem-manager nil)
|
||||
|
||||
(fn modem-manager []
|
||||
(when (not the-modem-manager)
|
||||
(set the-modem-manager
|
||||
(dbus.Proxy:new
|
||||
{
|
||||
:bus dbus.Bus.SYSTEM
|
||||
:name "org.freedesktop.ModemManager1"
|
||||
:interface "org.freedesktop.DBus.ObjectManager"
|
||||
:path "/org/freedesktop/ModemManager1"
|
||||
})))
|
||||
the-modem-manager)
|
||||
(dbus.Proxy:new
|
||||
{
|
||||
:bus dbus.Bus.SYSTEM
|
||||
:name "org.freedesktop.ModemManager1"
|
||||
:interface "org.freedesktop.DBus.ObjectManager"
|
||||
:path "/org/freedesktop/ModemManager1"
|
||||
}))
|
||||
|
||||
;; this is a function because the path to the modem may change
|
||||
;; (e.g. due to suspend/resume cycles causing services to be stopped
|
||||
;; and started)
|
||||
|
||||
(fn modem-interface []
|
||||
(let [modem-path (next (: (assert (modem-manager)) :GetManagedObjects))]
|
||||
(fn modem-interface [manager]
|
||||
(let [modem-path (next (: (assert manager) :GetManagedObjects))]
|
||||
(dbus.Proxy:new
|
||||
{
|
||||
:bus dbus.Bus.SYSTEM
|
||||
@ -33,10 +30,11 @@
|
||||
})))
|
||||
|
||||
(fn new-modem-status []
|
||||
{
|
||||
:value #(let [m (modem-interface)]
|
||||
(variant.strip (m:GetStatus)))
|
||||
})
|
||||
(let [manager (modem-manager)]
|
||||
{
|
||||
:read #(let [m (modem-interface manager)]
|
||||
(variant.strip (m:GetStatus)))
|
||||
}))
|
||||
|
||||
(comment
|
||||
(let [ctx (: (GLib.MainLoop) :get_context)
|
||||
|
Loading…
Reference in New Issue
Block a user