Why do you only discover bugs _after_ you've committed?
[slh] / hddtemp.el
1 ;; hddtemp.el --- Display hard disc temperatures   -*- Emacs-Lisp -*-
2
3 ;; Copyright (C) 2008 Steve Youngs
4
5 ;; Author:     Steve Youngs <steve@sxemacs.org>
6 ;; Maintainer: Steve Youngs <steve@sxemacs.org>
7 ;; Created:    <2008-08-13>
8 ;; Time-stamp: <Wednesday Aug 13, 2008 16:39:01 steve>
9 ;; Homepage:   
10 ;; Keywords:   sensor
11
12 ;; This file is part of hddtemp.
13
14 ;; Redistribution and use in source and binary forms, with or without
15 ;; modification, are permitted provided that the following conditions
16 ;; are met:
17 ;;
18 ;; 1. Redistributions of source code must retain the above copyright
19 ;;    notice, this list of conditions and the following disclaimer.
20 ;;
21 ;; 2. Redistributions in binary form must reproduce the above copyright
22 ;;    notice, this list of conditions and the following disclaimer in the
23 ;;    documentation and/or other materials provided with the distribution.
24 ;;
25 ;; 3. Neither the name of the author nor the names of any contributors
26 ;;    may be used to endorse or promote products derived from this
27 ;;    software without specific prior written permission.
28 ;;
29 ;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
30 ;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31 ;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
32 ;; DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33 ;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34 ;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 ;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
36 ;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
37 ;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
38 ;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
39 ;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40
41 ;;; Commentary:
42 ;; 
43 ;;    Just a bit of fun hacking to display hard disc temperatures.  This
44 ;;    requires a util called "hddtemp" to be running in daemon mode.  You
45 ;;    can get it from <http://savannah.nongnu.org/projects/hddtemp/>.
46
47 ;;; Todo:
48 ;;
49 ;;     o Clean up the butt-ugly let form in #'hddtemp
50
51 ;;; Code:
52 (require 'cl-loop)
53 (put 'cl:dotimes 'lisp-indent-function 'defun)
54
55 (defvar hddtemp-hash (make-hash-table :test #'equal :size 4)
56   "A hash-table to hold the temp values.")
57
58 (defun hddtemp-filt (proc string)
59   "Process the output from `hddtemp-proc'."
60   (let* ((data (remove "" (split-string-by-char string ?|)))
61          (iterations (/ (length data) 4)))
62     (cl:dotimes (i (declare-boundp iterations))
63       (setq i (number-to-string i))
64       (puthash (concat "dev-" i) (car data) hddtemp-hash)
65       (puthash (concat "mod-" i) (cadr data) hddtemp-hash)
66       (puthash (concat "tmp-" i) (caddr data) hddtemp-hash)
67       (puthash (concat "c/f-" i) (cadddr data) hddtemp-hash)
68       (setq data (cddddr data)))))
69
70 (defun hddtemp-proc ()
71   "Connect to the hddtemp daemon."
72   (let ((proc (open-network-stream "hdt" nil "localhost" 7634)))
73     (set-process-filter proc #'hddtemp-filt)))
74
75 (defun hddtemp-init ()
76   "Initialise an itimer to perodically grab hd temps."
77   (let ((htimer (get-itimer "hddtemp")))
78     (and htimer (delete-itimer htimer))
79     (start-itimer "hddtemp" #'hddtemp-proc 60 60)))
80
81 (defun hddtemp (&optional disc)
82   "Display the current temperature of DISC.
83
84 Argument DISC is a numeric prefix arg, if omitted the first hard disc
85 temp is displayed.  Counting begins at zero."
86   (interactive "p")
87   (let* ((disc (if (interactive-p)
88                    (or (and (eq disc 1) (null current-prefix-arg)
89                             "0")
90                        (and current-prefix-arg
91                             (number-to-string current-prefix-arg)))
92                  (if disc
93                      (number-to-string disc)
94                    "0")))
95          (dev (concat "dev-" disc))
96          (mod (concat "mod-" disc))
97          (tmp (concat "tmp-" disc))
98          (c/f (concat "c/f-" disc))
99          (msg (format "%s (%s): %s°%s"
100                       (gethash dev hddtemp-hash)
101                       (gethash mod hddtemp-hash)
102                       (gethash tmp hddtemp-hash)
103                       (gethash c/f hddtemp-hash))))
104     (unless (gethash dev hddtemp-hash)
105       (error 'invalid-argument (format "No such disc: %s" disc)))
106     (if (interactive-p)
107         (message msg)
108       (list (gethash dev hddtemp-hash)
109             (gethash mod hddtemp-hash)
110             (gethash tmp hddtemp-hash)
111             (gethash c/f hddtemp-hash)))))
112
113
114 (provide 'hddtemp)
115
116 ;; On-load actions
117 (hddtemp-proc)
118 (hddtemp-init)
119
120 ;;; hddtemp.el ends here