X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/06e21633a4a9de1e8013376cf92d912817df28cd..8725b746408685833dec0ee09f1a4fc680786c9a:/lisp/battery.el diff --git a/lisp/battery.el b/lisp/battery.el index 3b245ed644..98ba7d1b63 100644 --- a/lisp/battery.el +++ b/lisp/battery.el @@ -1,6 +1,6 @@ ;;; battery.el --- display battery status information -*- coding: iso-8859-1 -*- -;; Copyright (C) 1997-1998, 2000-2011 Free Software Foundation, Inc. +;; Copyright (C) 1997-1998, 2000-2013 Free Software Foundation, Inc. ;; Author: Ralph Schleicher ;; Keywords: hardware @@ -31,14 +31,16 @@ ;;; Code: (require 'timer) -(eval-when-compile (require 'cl)) - +(eval-when-compile (require 'cl-lib)) (defgroup battery nil "Display battery status information." :prefix "battery-" :group 'hardware) +;; Either BATn or yeeloong-bat, basically. +(defconst battery--linux-sysfs-regexp "[bB][aA][tT][0-9]?$") + (defcustom battery-status-function (cond ((and (eq system-type 'gnu/linux) (file-readable-p "/proc/apm")) @@ -48,8 +50,12 @@ 'battery-linux-proc-acpi) ((and (eq system-type 'gnu/linux) (file-directory-p "/sys/class/power_supply/") - (directory-files "/sys/class/power_supply/" nil "BAT[0-9]$")) + (directory-files "/sys/class/power_supply/" nil + battery--linux-sysfs-regexp)) 'battery-linux-sysfs) + ((and (eq system-type 'berkeley-unix) + (file-executable-p "/usr/sbin/apm")) + 'battery-bsd-apm) ((and (eq system-type 'darwin) (condition-case nil (with-temp-buffer @@ -57,7 +63,7 @@ (> (buffer-size) 0))) (error nil))) 'battery-pmset) - ((eq system-type 'windows-nt) + ((fboundp 'w32-battery-status) 'w32-battery-status)) "Function for getting battery status information. The function has to return an alist of conversion definitions. @@ -74,7 +80,7 @@ introduced by a `%' character in a control string." (cond ((eq battery-status-function 'battery-linux-proc-acpi) "Power %L, battery %B at %r (%p%% load, remaining time %t)") ((eq battery-status-function 'battery-linux-sysfs) - "Power %L, battery %B (%p%% load)") + "Power %L, battery %B (%p%% load, remaining time %t)") ((eq battery-status-function 'battery-pmset) "%L power, battery %B (%p%% load, remaining time %t)") (battery-status-function @@ -104,6 +110,7 @@ string are substituted as defined by the current value of the variable (defcustom battery-mode-line-limit 100 "Percentage of full battery load below which display battery status" + :version "24.1" :type 'integer :group 'battery) @@ -226,7 +233,7 @@ seconds." "Regular expression matching contents of `/proc/apm'.") (defun battery-linux-proc-apm () - "Get APM status information from Linux kernel. + "Get APM status information from Linux (the kernel). This function works only with the new `/proc/apm' format introduced in Linux version 1.3.58. @@ -297,7 +304,7 @@ The following %-sequences are provided: ;;; `/proc/acpi/' interface for Linux. (defun battery-linux-proc-acpi () - "Get ACPI status information from Linux kernel. + "Get ACPI status information from Linux (the kernel). This function works only with the `/proc/acpi/' format introduced in Linux version 2.4.20 and 2.6.0. @@ -337,14 +344,15 @@ The following %-sequences are provided: (setq charging-state (match-string 1))) (when (re-search-forward "present rate: +\\([0-9]+\\) \\(m[AW]\\)$" nil t) - (setq rate (+ (or rate 0) (string-to-number (match-string 1))) - rate-type (or (and rate-type + (setq rate (+ (or rate 0) (string-to-number (match-string 1)))) + (when (> rate 0) + (setq rate-type (or (and rate-type (if (string= rate-type (match-string 2)) rate-type (error "Inconsistent rate types (%s vs. %s)" rate-type (match-string 2)))) - (match-string 2)))) + (match-string 2))))) (when (re-search-forward "remaining capacity: +\\([0-9]+\\) m[AW]h$" nil t) (setq capacity @@ -354,16 +362,16 @@ The following %-sequences are provided: (when (re-search-forward "present: +yes$" nil t) (when (re-search-forward "design capacity: +\\([0-9]+\\) m[AW]h$" nil t) - (incf design-capacity (string-to-number (match-string 1)))) + (cl-incf design-capacity (string-to-number (match-string 1)))) (when (re-search-forward "last full capacity: +\\([0-9]+\\) m[AW]h$" nil t) - (incf last-full-capacity (string-to-number (match-string 1)))) + (cl-incf last-full-capacity (string-to-number (match-string 1)))) (when (re-search-forward "design capacity warning: +\\([0-9]+\\) m[AW]h$" nil t) - (incf warn (string-to-number (match-string 1)))) + (cl-incf warn (string-to-number (match-string 1)))) (when (re-search-forward "design capacity low: +\\([0-9]+\\) m[AW]h$" nil t) - (incf low (string-to-number (match-string 1))))))) + (cl-incf low (string-to-number (match-string 1))))))) (setq full-capacity (if (> last-full-capacity 0) last-full-capacity design-capacity)) (and capacity rate @@ -421,10 +429,15 @@ format introduced in Linux version 2.4.25. The following %-sequences are provided: %c Current capacity (mAh or mWh) +%r Current rate %B Battery status (verbose) +%d Temperature (in degrees Celsius) %p Battery load percentage -%L AC line status (verbose)" - (let (charging-state +%L AC line status (verbose) +%m Remaining time (to charge or discharge) in minutes +%h Remaining time (to charge or discharge) in hours +%t Remaining time (to charge or discharge) in the form `h:min'" + (let (charging-state rate temperature hours (charge-full 0.0) (charge-now 0.0) (energy-full 0.0) @@ -435,7 +448,8 @@ The following %-sequences are provided: (with-temp-buffer (dolist (dir (ignore-errors (directory-files - "/sys/class/power_supply/" t "BAT[0-9]$"))) + "/sys/class/power_supply/" t + battery--linux-sysfs-regexp))) (erase-buffer) (ignore-errors (insert-file-contents (expand-file-name "uevent" dir))) @@ -444,6 +458,12 @@ The following %-sequences are provided: (and (re-search-forward "POWER_SUPPLY_STATUS=\\(.*\\)$" nil t) (member charging-state '("Unknown" "Full" nil)) (setq charging-state (match-string 1))) + (when (re-search-forward + "POWER_SUPPLY_\\(CURRENT\\|POWER\\)_NOW=\\([0-9]*\\)$" + nil t) + (setq rate (float (string-to-number (match-string 2))))) + (when (re-search-forward "POWER_SUPPLY_TEMP=\\([0-9]*\\)$" nil t) + (setq temperature (match-string 1))) (let (full-string now-string) ;; Sysfs may list either charge (mAh) or energy (mWh). ;; Keep track of both, and choose which to report later. @@ -466,14 +486,32 @@ The following %-sequences are provided: (setq energy-full (+ energy-full (string-to-number full-string)) energy-now (+ energy-now - (string-to-number now-string))))))))) + (string-to-number now-string)))))) + (goto-char (point-min)) + (when (and energy-now rate (not (zerop rate)) + (re-search-forward + "POWER_SUPPLY_VOLTAGE_NOW=\\([0-9]*\\)$" nil t)) + (let ((remaining (if (string= charging-state "Discharging") + energy-now + (- energy-full energy-now)))) + (setq hours (/ (/ (* remaining (string-to-number + (match-string 1))) + rate) + 10000000.0))))))) (list (cons ?c (cond ((or (> charge-full 0) (> charge-now 0)) (number-to-string charge-now)) ((or (> energy-full 0) (> energy-now 0)) (number-to-string energy-now)) (t "N/A"))) + (cons ?r (if rate (format "%.1f" (/ rate 1000000.0)) "N/A")) + (cons ?m (if hours (format "%d" (* hours 60)) "N/A")) + (cons ?h (if hours (format "%d" hours) "N/A")) + (cons ?t (if hours + (format "%d:%02d" hours (* (- hours (floor hours)) 60)) + "N/A")) + (cons ?d (or temperature "N/A")) (cons ?B (or charging-state "N/A")) - (cons ?p (cond ((> charge-full 0) + (cons ?p (cond ((and (> charge-full 0) (> charge-now 0)) (format "%.1f" (/ (* 100 charge-now) charge-full))) ((> energy-full 0) @@ -489,6 +527,73 @@ The following %-sequences are provided: "BAT") "N/A"))))) + +;;; `apm' interface for BSD. +(defun battery-bsd-apm () + "Get APM status information from BSD apm binary. +The following %-sequences are provided: +%L AC line status (verbose) +%B Battery status (verbose) +%b Battery status, empty means high, `-' means low, + `!' means critical, and `+' means charging +%P Advanced power saving mode state (verbose) +%p Battery charge percentage +%s Remaining battery charge time in seconds +%m Remaining battery charge time in minutes +%h Remaining battery charge time in hours +%t Remaining battery charge time in the form `h:min'" + (let* ((os-name (car (split-string + (shell-command-to-string "/usr/bin/uname")))) + (apm-flag (if (equal os-name "OpenBSD") "P" "s")) + (apm-cmd (concat "/usr/sbin/apm -ablm" apm-flag)) + (apm-output (split-string (shell-command-to-string apm-cmd))) + ;; Battery status + (battery-status + (let ((stat (string-to-number (nth 0 apm-output)))) + (cond ((eq stat 0) '("high" . "")) + ((eq stat 1) '("low" . "-")) + ((eq stat 2) '("critical" . "!")) + ((eq stat 3) '("charging" . "+")) + ((eq stat 4) '("absent" . nil))))) + ;; Battery percentage + (battery-percentage (nth 1 apm-output)) + ;; Battery life + (battery-life (nth 2 apm-output)) + ;; AC status + (line-status + (let ((ac (string-to-number (nth 3 apm-output)))) + (cond ((eq ac 0) "disconnected") + ((eq ac 1) "connected") + ((eq ac 2) "backup power")))) + ;; Advanced power savings mode + (apm-mode + (let ((apm (string-to-number (nth 4 apm-output)))) + (if (string= os-name "OpenBSD") + (cond ((eq apm 0) "manual") + ((eq apm 1) "automatic") + ((eq apm 2) "cool running")) + (if (eq apm 1) "on" "off")))) + seconds minutes hours remaining-time) + (unless (member battery-life '("unknown" "-1")) + (if (member os-name '("OpenBSD" "NetBSD")) + (setq minutes (string-to-number battery-life) + seconds (* 60 minutes)) + (setq seconds (string-to-number battery-life) + minutes (truncate (/ seconds 60)))) + (setq hours (truncate (/ minutes 60)) + remaining-time (format "%d:%02d" hours + (- minutes (* 60 hours))))) + (list (cons ?L (or line-status "N/A")) + (cons ?B (or (car battery-status) "N/A")) + (cons ?b (or (cdr battery-status) "N/A")) + (cons ?p (if (string= battery-percentage "255") + "N/A" + battery-percentage)) + (cons ?P (or apm-mode "N/A")) + (cons ?s (or (and seconds (number-to-string seconds)) "N/A")) + (cons ?m (or (and minutes (number-to-string minutes)) "N/A")) + (cons ?h (or (and hours (number-to-string hours)) "N/A")) + (cons ?t (or remaining-time "N/A"))))) ;;; `pmset' interface for Darwin (OS X).