(use srfi-1) (add-load-path "/home/hip/src/lisp/x11") (use x11) (define (rounded-number->string x . digits-of-precision) (if (null? digits-of-precision) (number->string (inexact->exact (round x))) (let* ((digits (car digits-of-precision)) (factor (expt 10.0 digits)) (n (abs (inexact->exact (round (* x factor))))) (s (number->string n)) (l (string-length s)) (rs (if (< n factor) (string-append "0." (make-string (- digits l) #\0) s) (string-append (substring s 0 (- l digits)) "." (substring s (- l digits) l))))) (if (< x 0) (string-append "-" rs) rs)))) (define (read-log) (call-with-input-file "/home/hip/lib/smart/hddtemp.log" (lambda (p) (port->string-list p)))) (define (get-temperature-from-logline line) "Fri Dec 19 18:40:03 CET 2003 /dev/hda: WDC WD800BB-00DKA0: 29 C" (string->number (car (list-tail (string-split line " ") 9)))) (define (temperatures) (filter number? (map get-temperature-from-logline (read-log)))) ;; todo: statistical analysis, averages, std deviations ;; monitoring of actual temperatures to stay within 2x stddev (define (average ls) (let loop ((l ls) (total 0)) (cond ((null? l) (/ total (length ls))) (else (loop (cdr l) (+ (car l) total)))))) (define screen-width 512) (define screen-height 512) (define (transform-y y) (- screen-height ; put origin a bottom-left (* 5 y))) ; scale up 5 times (define (transform-to-screen temperatures) (let ((samples-per-pixel (round (/ (length temperatures) screen-width)))) (let loop ((ts temperatures) (result ())) 'xxx))) (define (expose) (let* ((ts (temperatures)) (ts-len (length ts)) (ts-avg (rounded-number->string (average ts) 2))) (draw-string 10 20 #`",ts-len samples, average ,ts-avg C") (for-each (lambda (coord) (draw-point (car coord) (transform-y (cadr coord)))) (zip (iota screen-width) (take-right ts screen-width))))) (make-window expose)