1 |
;;; battery.el --- display battery status information |
;;; battery.el --- display battery status information |
2 |
|
|
3 |
;; Copyright (C) 1997, 1998, 2000, 2001, 2003 Free Software Foundation, Inc. |
;; Copyright (C) 1997, 1998, 2000, 2001, 2003, 2004 |
4 |
|
;; Free Software Foundation, Inc. |
5 |
|
|
6 |
;; Author: Ralph Schleicher <rs@nunatak.allgaeu.org> |
;; Author: Ralph Schleicher <rs@nunatak.allgaeu.org> |
7 |
;; Keywords: hardware |
;; Keywords: hardware |
32 |
;;; Code: |
;;; Code: |
33 |
|
|
34 |
(require 'timer) |
(require 'timer) |
35 |
|
(eval-when-compile (require 'cl)) |
36 |
|
|
37 |
|
|
|
|
|
38 |
(defgroup battery nil |
(defgroup battery nil |
39 |
"Display battery status information." |
"Display battery status information." |
40 |
:prefix "battery-" |
:prefix "battery-" |
183 |
(re-search-forward battery-linux-proc-apm-regexp) |
(re-search-forward battery-linux-proc-apm-regexp) |
184 |
(setq driver-version (match-string 1)) |
(setq driver-version (match-string 1)) |
185 |
(setq bios-version (match-string 2)) |
(setq bios-version (match-string 2)) |
186 |
(setq tem (battery-hex-to-int-2 (match-string 3))) |
(setq tem (string-to-number (match-string 3) 16)) |
187 |
(if (not (logand tem 2)) |
(if (not (logand tem 2)) |
188 |
(setq bios-interface "not supported") |
(setq bios-interface "not supported") |
189 |
(setq bios-interface "enabled") |
(setq bios-interface "enabled") |
190 |
(cond ((logand tem 16) (setq bios-interface "disabled")) |
(cond ((logand tem 16) (setq bios-interface "disabled")) |
191 |
((logand tem 32) (setq bios-interface "disengaged"))) |
((logand tem 32) (setq bios-interface "disengaged"))) |
192 |
(setq tem (battery-hex-to-int-2 (match-string 4))) |
(setq tem (string-to-number (match-string 4) 16)) |
193 |
(cond ((= tem 0) (setq line-status "off-line")) |
(cond ((= tem 0) (setq line-status "off-line")) |
194 |
((= tem 1) (setq line-status "on-line")) |
((= tem 1) (setq line-status "on-line")) |
195 |
((= tem 2) (setq line-status "on backup"))) |
((= tem 2) (setq line-status "on backup"))) |
196 |
(setq tem (battery-hex-to-int-2 (match-string 6))) |
(setq tem (string-to-number (match-string 6) 16)) |
197 |
(if (= tem 255) |
(if (= tem 255) |
198 |
(setq battery-status "N/A") |
(setq battery-status "N/A") |
199 |
(setq tem (battery-hex-to-int-2 (match-string 5))) |
(setq tem (string-to-number (match-string 5) 16)) |
200 |
(cond ((= tem 0) (setq battery-status "high" |
(cond ((= tem 0) (setq battery-status "high" |
201 |
battery-status-symbol "")) |
battery-status-symbol "")) |
202 |
((= tem 1) (setq battery-status "low" |
((= tem 1) (setq battery-status "low" |
244 |
%m Remaining time in minutes |
%m Remaining time in minutes |
245 |
%h Remaining time in hours |
%h Remaining time in hours |
246 |
%t Remaining time in the form `h:min'" |
%t Remaining time in the form `h:min'" |
247 |
(let (capacity design-capacity rate rate-type charging-state warn low |
(let ((design-capacity 0) |
248 |
minutes hours) |
(warn 0) |
249 |
(when (file-directory-p "/proc/acpi/battery/") |
(low 0) |
250 |
;; ACPI provides information about each battery present in the system in |
capacity rate rate-type charging-state minutes hours) |
251 |
;; a separate subdirectory. We are going to merge the available |
;; ACPI provides information about each battery present in the system in |
252 |
;; information together since displaying for a variable amount of |
;; a separate subdirectory. We are going to merge the available |
253 |
;; batteries seems overkill for format-strings. |
;; information together since displaying for a variable amount of |
254 |
(mapc |
;; batteries seems overkill for format-strings. |
255 |
(lambda (dir) |
(with-temp-buffer |
256 |
(with-temp-buffer |
(dolist (dir (ignore-errors (directory-files "/proc/acpi/battery/" |
257 |
(insert-file-contents (expand-file-name "state" dir)) |
t "\\`[^.]"))) |
258 |
(when (re-search-forward "present: +yes$" nil t) |
(erase-buffer) |
259 |
(and (re-search-forward "charging state: +\\(.*\\)$" nil t) |
(ignore-errors (insert-file-contents (expand-file-name "state" dir))) |
260 |
(or (null charging-state) (string= charging-state |
(when (re-search-forward "present: +yes$" nil t) |
261 |
"unknown")) |
(and (re-search-forward "charging state: +\\(.*\\)$" nil t) |
262 |
;; On most multi-battery systems, most of the time only one |
(member charging-state '("unknown" nil)) |
263 |
;; battery is "charging"/"discharging", the others are |
;; On most multi-battery systems, most of the time only one |
264 |
;; "unknown". |
;; battery is "charging"/"discharging", the others are |
265 |
(setq charging-state (match-string 1))) |
;; "unknown". |
266 |
(when (re-search-forward "present rate: +\\([0-9]+\\) \\(m[AW]\\)$" |
(setq charging-state (match-string 1))) |
267 |
nil t) |
(when (re-search-forward "present rate: +\\([0-9]+\\) \\(m[AW]\\)$" |
268 |
(setq rate (+ (or rate 0) (string-to-int (match-string 1))) |
nil t) |
269 |
rate-type (or (and rate-type |
(setq rate (+ (or rate 0) (string-to-number (match-string 1))) |
270 |
(if (string= rate-type (match-string 2)) |
rate-type (or (and rate-type |
271 |
rate-type |
(if (string= rate-type (match-string 2)) |
272 |
(error |
rate-type |
273 |
"Inconsistent rate types (%s vs. %s)" |
(error |
274 |
rate-type (match-string 2)))) |
"Inconsistent rate types (%s vs. %s)" |
275 |
(match-string 2)))) |
rate-type (match-string 2)))) |
276 |
(when (re-search-forward "remaining capacity: +\\([0-9]+\\) m[AW]h$" |
(match-string 2)))) |
277 |
nil t) |
(when (re-search-forward "remaining capacity: +\\([0-9]+\\) m[AW]h$" |
278 |
(setq capacity |
nil t) |
279 |
(+ (or capacity 0) (string-to-int (match-string 1)))))) |
(setq capacity |
280 |
(goto-char (point-max)) |
(+ (or capacity 0) (string-to-number (match-string 1)))))) |
281 |
(insert-file-contents (expand-file-name "info" dir)) |
(goto-char (point-max)) |
282 |
(when (re-search-forward "present: +yes$" nil t) |
(ignore-errors (insert-file-contents (expand-file-name "info" dir))) |
283 |
(when (re-search-forward "design capacity: +\\([0-9]+\\) m[AW]h$" |
(when (re-search-forward "present: +yes$" nil t) |
284 |
nil t) |
(when (re-search-forward "design capacity: +\\([0-9]+\\) m[AW]h$" |
285 |
(setq design-capacity (+ (or design-capacity 0) |
nil t) |
286 |
(string-to-int (match-string 1))))) |
(incf design-capacity (string-to-number (match-string 1)))) |
287 |
(when (re-search-forward "design capacity warning: +\\([0-9]+\\) m[AW]h$" |
(when (re-search-forward |
288 |
nil t) |
"design capacity warning: +\\([0-9]+\\) m[AW]h$" nil t) |
289 |
(setq warn (+ (or warn 0) (string-to-int (match-string 1))))) |
(incf warn (string-to-number (match-string 1)))) |
290 |
(when (re-search-forward "design capacity low: +\\([0-9]+\\) m[AW]h$" |
(when (re-search-forward "design capacity low: +\\([0-9]+\\) m[AW]h$" |
291 |
nil t) |
nil t) |
292 |
(setq low (+ (or low 0) |
(incf low (string-to-number (match-string 1))))))) |
|
(string-to-int (match-string 1)))))))) |
|
|
(directory-files "/proc/acpi/battery/" t "\\(BAT\\|CMB\\)"))) |
|
293 |
(and capacity rate |
(and capacity rate |
294 |
(setq minutes (if (zerop rate) 0 |
(setq minutes (if (zerop rate) 0 |
295 |
(floor (* (/ (float (if (string= charging-state |
(floor (* (/ (float (if (string= charging-state |
326 |
rate-type)) "N/A")) |
rate-type)) "N/A")) |
327 |
(cons ?B (or charging-state "N/A")) |
(cons ?B (or charging-state "N/A")) |
328 |
(cons ?b (or (and (string= charging-state "charging") "+") |
(cons ?b (or (and (string= charging-state "charging") "+") |
329 |
(and low (< capacity low) "!") |
(and (< capacity low) "!") |
330 |
(and warn (< capacity warn) "-") |
(and (< capacity warn) "-") |
331 |
"")) |
"")) |
332 |
(cons ?h (or (and hours (number-to-string hours)) "N/A")) |
(cons ?h (or (and hours (number-to-string hours)) "N/A")) |
333 |
(cons ?m (or (and minutes (number-to-string minutes)) "N/A")) |
(cons ?m (or (and minutes (number-to-string minutes)) "N/A")) |
345 |
|
|
346 |
(defun battery-format (format alist) |
(defun battery-format (format alist) |
347 |
"Substitute %-sequences in FORMAT." |
"Substitute %-sequences in FORMAT." |
348 |
(let ((index 0) |
(replace-regexp-in-string |
349 |
(length (length format)) |
"%." |
350 |
(result "") |
(lambda (str) |
351 |
char flag elem) |
(let ((char (aref str 1))) |
352 |
(while (< index length) |
(if (eq char ?%) "%" |
353 |
(setq char (aref format index)) |
(or (cdr (assoc char alist)) "")))) |
354 |
(if (not flag) |
format t t)) |
|
(if (char-equal char ?%) |
|
|
(setq flag t) |
|
|
(setq result (concat result (char-to-string char)))) |
|
|
(cond ((char-equal char ?%) |
|
|
(setq result (concat result "%"))) |
|
|
((setq elem (assoc char alist)) |
|
|
(setq result (concat result (cdr elem))))) |
|
|
(setq flag nil)) |
|
|
(setq index (1+ index))) |
|
|
(or (null flag) |
|
|
(setq result (concat result "%"))) |
|
|
result)) |
|
|
|
|
|
(defconst battery-hex-map '((?0 . 0) (?1 . 1) (?2 . 2) (?3 . 3) |
|
|
(?4 . 4) (?5 . 5) (?6 . 6) (?7 . 7) |
|
|
(?8 . 8) (?9 . 9) (?a . 10) (?b . 11) |
|
|
(?c . 12) (?d . 13) (?e . 14) (?f . 15))) |
|
|
|
|
|
(defun battery-hex-to-int (string) |
|
|
"Convert a hexadecimal number (a string) into a number." |
|
|
(save-match-data |
|
|
(and (string-match "^[ \t]+" string) |
|
|
(setq string (substring string (match-end 0)))) |
|
|
(and (string-match "^0[xX]" string) |
|
|
(setq string (substring string (match-end 0))))) |
|
|
(battery-hex-to-int-2 string)) |
|
|
|
|
|
(defun battery-hex-to-int-2 (string) |
|
|
(let ((index 0) |
|
|
(length (length string)) |
|
|
(value 0) |
|
|
(elem nil)) |
|
|
(while (and (< index length) |
|
|
(setq elem (assoc (downcase (aref string index)) |
|
|
battery-hex-map))) |
|
|
(setq value (+ (* 16 value) (cdr elem)) |
|
|
index (1+ index))) |
|
|
value)) |
|
355 |
|
|
356 |
|
|
357 |
(provide 'battery) |
(provide 'battery) |
358 |
|
|
359 |
;;; arch-tag: 65916f50-4754-4b6b-ac21-0b510f545a37 |
;; arch-tag: 65916f50-4754-4b6b-ac21-0b510f545a37 |
360 |
;;; battery.el ends here |
;;; battery.el ends here |