all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* A simple battery level alert mcron job for your Guix
@ 2019-07-22 10:10 Maxim Cournoyer
  2019-08-01  0:07 ` A simple battery level alert mcron job for your Guix, v2 Maxim Cournoyer
  0 siblings, 1 reply; 3+ messages in thread
From: Maxim Cournoyer @ 2019-07-22 10:10 UTC (permalink / raw)
  To: help-guix

If like me, you are using a minimalist WM, you might miss on basic
features such as a battery level gauge.  Having a laptop silently die on
us due to forgetting to plug the AC charger can be frustrating...

So here's a small hack that should at least beep the PC speaker when the
battery goes below 20%.  It relies on "acpi" to get the battery level
and "beep" to make use of the PC speaker.

--8<---------------cut here---------------start------------->8---
(use-service-module
 ...
 base
 mcron
 ...)

(use-package-modules
 ...
 linux
 terminals                      ; for "beep"
 ...)

;;; Allow the use of the PC speaker (beep) for any active user.
(define %pcspeaker-beep-rule
  (udev-rule
   "70-pcspkr-beep.rules"
   (string-append "ACTION==\"add\", SUBSYSTEM==\"input\", "
		  "ATTRS{name}==\"PC Speaker\", ENV{DEVNAME}!=\"\", "
		  "TAG+=\"uaccess\"")))

(define %battery-alert-job
  #~(job '(next-minute (range 0 60 1))
	 "(( $(acpi | cut -d',' -f2 | tr -d ' %') < 20 )) && beep -r5"))

(operating-system
 ...
 (packages (cons* ...
             	  acpi beep		;for the battery alert mcron job
                  %base-packages))

 (services
  (cons*
   (service mcron-service-type
            (mcron-configuration (jobs (list %battery-alert-job))))
            ...
   (modify-services %desktop-services
    (udev-service-type config =>
		       (udev-configuration
		        (inherit config)
			(rules (cons* %pcspeaker-beep-rule
				      (udev-configuration-rules config)))))))))
--8<---------------cut here---------------end--------------->8---

One caveat: on my laptop at least, the mute button silences even the PC
speaker, leaving some room for more surprise shutdowns.

Have fun,

Maxim

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: A simple battery level alert mcron job for your Guix, v2
  2019-08-01  0:07 ` A simple battery level alert mcron job for your Guix, v2 Maxim Cournoyer
@ 2019-07-31 15:23   ` Ricardo Wurmus
  0 siblings, 0 replies; 3+ messages in thread
From: Ricardo Wurmus @ 2019-07-31 15:23 UTC (permalink / raw)
  To: Maxim Cournoyer; +Cc: help-guix


Maxim Cournoyer <maxim.cournoyer@gmail.com> writes:

> The following mcron job accomplish this.  I've implemented it in Guile
> Scheme this time around and was puzzled that I had to use program-file
> to make it work, otherwise srfi-26's cut would error on undefined symbol
> '<>'.
>
> The problem was that passing the code as a lambda would have the syntax
> imported not a the top level, which is the only valid place to
> define/import syntax definitions, per the Guile manual.  Using
> `program-file' works around that, by placing the logic at the top level
> of a standalone script, while allowing you to define everything at the
> level of your Guix config file.

Ah, thanks for investigating this.  When you first asked about this I
was really quite puzzled.

> 	 (let* ((input-pipe (open-pipe* OPEN_READ
> 					#$(file-append acpi "/bin/acpi")))
> 		(output (get-string-all input-pipe))
> 		(m (string-match "Discharging, ([0-9]+)%" output))
> 		(level (and=> m (compose string->number
> 					 (cut match:substring <> 1)))))
> 	   (when (and=> level (cut <= <> %min-level))
> 	     (format #t "warning: Battery level is low (~a%)~%" level)
> 	     (invoke #$(file-append beep "/bin/beep") "-r5")))))))

Perhaps and-let* (SRFI 2) would be of interest here.

-- 
Ricardo

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: A simple battery level alert mcron job for your Guix, v2
  2019-07-22 10:10 A simple battery level alert mcron job for your Guix Maxim Cournoyer
@ 2019-08-01  0:07 ` Maxim Cournoyer
  2019-07-31 15:23   ` Ricardo Wurmus
  0 siblings, 1 reply; 3+ messages in thread
From: Maxim Cournoyer @ 2019-08-01  0:07 UTC (permalink / raw)
  To: help-guix

Hello again,

The previously posted battery level alert job had a very annoying
limitation: it would keep beeping until the level of the battery would
have recovered above the defined limit.

We can do much better by stopping the noise as soon as the AC cable has
been plugged in.

The following mcron job accomplish this.  I've implemented it in Guile
Scheme this time around and was puzzled that I had to use program-file
to make it work, otherwise srfi-26's cut would error on undefined symbol
'<>'.

The problem was that passing the code as a lambda would have the syntax
imported not a the top level, which is the only valid place to
define/import syntax definitions, per the Guile manual.  Using
`program-file' works around that, by placing the logic at the top level
of a standalone script, while allowing you to define everything at the
level of your Guix config file.

Here's the new job definition, including an easy way to test it:

#+BEGIN_SRC scheme
(use-modules (gnu packages linux)
	     (gnu packages terminals)
	     (guix build utils)
	     (guix derivations)
	     (guix gexp)
	     (guix modules)
	     (guix store)
	     (guix ui))

;;; Helper to build a derivation easily.
(define (build-drv drv)
  (with-store store
    (let* ((drv (run-with-store store drv))
	   (success? (build-derivations store (list drv))))
      (when (not success?)
	(error "Build failed."))
      (derivation->output-path drv))))

(define %battery-alert-job
  ;; Beep the system when the battery reaches %MIN-LEVEL or less
  ;; battery percent.
  (program-file
   "battery-alert.scm"
   (with-imported-modules (source-module-closure
			   '((guix build utils)))
     #~(begin
	 (define %min-level 20)
	 (use-modules (guix build utils)
		      (ice-9 popen)
		      (ice-9 regex)
		      (ice-9 textual-ports)
		      (srfi srfi-26))
	 (setenv "LC_ALL" "C")
	 (let* ((input-pipe (open-pipe* OPEN_READ
					#$(file-append acpi "/bin/acpi")))
		(output (get-string-all input-pipe))
		(m (string-match "Discharging, ([0-9]+)%" output))
		(level (and=> m (compose string->number
					 (cut match:substring <> 1)))))
	   (when (and=> level (cut <= <> %min-level))
	     (format #t "warning: Battery level is low (~a%)~%" level)
	     (invoke #$(file-append beep "/bin/beep") "-r5")))))))

;;; Test job
(invoke (build-drv (lower-object %battery-alert-job)))
#+END_SRC

I'll send a patch to document the use of program-file for this use case,
along with this example.

Maxim

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-07-31 15:23 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-22 10:10 A simple battery level alert mcron job for your Guix Maxim Cournoyer
2019-08-01  0:07 ` A simple battery level alert mcron job for your Guix, v2 Maxim Cournoyer
2019-07-31 15:23   ` Ricardo Wurmus

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/guix.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.