hbspbar

[WIP] bspwm status bar
git clone https://hhvn.uk/hbspbar
git clone git://hhvn.uk/hbspbar
Log | Files | Refs

commit 1c46de9342a93cf8284d2bd4ed58f524cda60b29
parent a7e98ba0835c8c7278f298f34fecf6749432fc25
Author: hhvn <dev@hhvn.uk>
Date:   Sun, 19 Nov 2023 13:31:42 +0000

CPU usage & temp

Diffstat:
Astatus/02-cpu.go | 152+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 152 insertions(+), 0 deletions(-)

diff --git a/status/02-cpu.go b/status/02-cpu.go @@ -0,0 +1,152 @@ +package status // import "hhvn.uk/hbspbar/status" + +import ( + "fmt" + "errors" + "strings" + + "hhvn.uk/hbspbar/drw" + "hhvn.uk/hbspbar/config" + "hhvn.uk/hbspbar/common" +) + +func getcpus(c chan [][]string, e chan error) { + var ret [][]string + + lines, err := common.FileAsLines("/proc/stat") + if err != nil { + c <- nil + e <- err + return + } + + for _, l := range lines { + var tok []string + + tokempty := strings.Split(l, " ") + + if !strings.HasPrefix(tokempty[0], "cpu") || + strings.HasSuffix(tokempty[0], "u") { + continue + } + + for _, t := range tokempty { + if t != "" { tok = append(tok, t) } + } + + ret = append(ret, tok) + } + + c <- ret + + // This is only used if ret == nil + e <- errors.New("apparently this computer has no cores") +} + +func cpu(name string) error { + u := newUpdate(name) + + cpus := [2]chan [][]string{ + make(chan [][]string), + make(chan [][]string) } + + cpuerr := [2]chan error{ + make(chan error), + make(chan error) } + + go getcpus(cpus[0], cpuerr[0]) + sleep(1) + go getcpus(cpus[1], cpuerr[1]) + + start := <- cpus[0] + if start == nil { return <- cpuerr[0] } + + end := <- cpus[1] + if end == nil { return <- cpuerr[1] } + + if len(start) != len(end) { + return errors.New("somehow we lost/gained some cores") + } + + ncores := len(start) + + total := make([]int, ncores) + idle := make([]int, ncores) + + for i, c := range start { + for j, v := range c { + if j == 0 { continue } + n, err := common.Intify(v) + if err != nil { return err } + total[i] += n + } + + n, err := common.Intify(c[4]) + if err != nil { return err } + idle[i] = n + } + + cx := 0 + + for i, c := range end { + ltotal := 0 + + for j, v := range c { + if j == 0 { continue } + n, err := common.Intify(v) + if err != nil { return err } + ltotal += n + } + + n, err := common.Intify(c[4]) + if err != nil { return err } + lidle := n - idle[i] + ltotal = ltotal - total[i] + used := int((100 * (ltotal - lidle)) / ltotal) + + tbpad := 3 + th := int(config.H) - tbpad * 2 + 1 + h := int(th * used / 100) + fg := blendGYR(used) + bg := drw.Blend(fg, config.Status, 75) + + u.drawRect(cx, tbpad - 1, 3, th, bg, true) + u.drawRect(cx, tbpad + th - h - 1, 3, h, fg, true) + cx += 5 + } + + temps := 0 + + for i := 0; i < ncores; i ++ { + file := fmt.Sprintf("/sys/class/thermal/thermal_zone%d/temp", i) + content, err := common.FileAsLines(file) + if err != nil { return err } + + n, err := common.Intify(content[0]) + if err != nil { return err } + + temps += n / 1000 + } + + // <=40: green. >=80: red. + cp := float64(temps/ncores - 40) + cp /= 40 + cp *= 100 + if cp > 100 { cp = 100 } + + u.drawText(cx, blendGYR(int(cp)), fmt.Sprintf("%d°C", temps / ncores)) + + updates <- u + return nil +} + +func init() { + name := "cpu" + register(name) + + go func(){ + for { + checkError(name, cpu(name)) + } + }() +}