help-guix
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: A simple battery level alert mcron job for your Guix, v2


From: Maxim Cournoyer
Subject: Re: A simple battery level alert mcron job for your Guix, v2
Date: Thu, 01 Aug 2019 09:07:53 +0900
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux)

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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]